/*
* Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
* All rights reserved
* www.brocade.com
*
* Linux driver for Brocade Fibre Channel Host Bus Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
/**
* fabric.c Fabric module implementation.
*/
#include "fcs_fabric.h"
#include "fcs_lport.h"
#include "fcs_vport.h"
#include "fcs_trcmod.h"
#include "fcs_fcxp.h"
#include "fcs_auth.h"
#include "fcs.h"
#include "fcbuild.h"
#include <log/bfa_log_fcs.h>
#include <aen/bfa_aen_port.h>
#include <bfa_svc.h>
BFA_TRC_FILE(FCS, FABRIC);
#define BFA_FCS_FABRIC_RETRY_DELAY (2000) /* Milliseconds */
#define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */
#define bfa_fcs_fabric_set_opertype(__fabric) do { \
if (bfa_pport_get_topology((__fabric)->fcs->bfa) \
== BFA_PPORT_TOPOLOGY_P2P) \
(__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \
else \
(__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT; \
} while (0)
/*
* forward declarations
*/
static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
static void bfa_fcs_fabric_delay(void *cbarg);
static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
static void bfa_fcs_fabric_delete_comp(void *cbarg);
static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
struct fchs_s *fchs, u16 len);
static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
struct fchs_s *fchs, u16 len);
static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
struct bfa_fcxp_s *fcxp,
void *cbarg, bfa_status_t status,
u32 rsp_len,
u32 resid_len,
struct fchs_s *rspfchs);
/**
* fcs_fabric_sm fabric state machine functions
*/
/**
* Fabric state machine events
*/
enum bfa_fcs_fabric_event {
BFA_FCS_FABRIC_SM_CREATE = 1, /* fabric create from driver */
BFA_FCS_FABRIC_SM_DELETE = 2, /* fabric delete from driver */
BFA_FCS_FABRIC_SM_LINK_DOWN = 3, /* link down from port */
BFA_FCS_FABRIC_SM_LINK_UP = 4, /* link up from port */
BFA_FCS_FABRIC_SM_CONT_OP = 5, /* continue op from flogi/auth */
BFA_FCS_FABRIC_SM_RETRY_OP = 6, /* continue op from flogi/auth */
BFA_FCS_FABRIC_SM_NO_FABRIC = 7, /* no fabric from flogi/auth
*/
BFA_FCS_FABRIC_SM_PERF_EVFP = 8, /* perform EVFP from
*flogi/auth */
BFA_FCS_FABRIC_SM_ISOLATE = 9, /* isolate from EVFP processing */
BFA_FCS_FABRIC_SM_NO_TAGGING = 10,/* no VFT tagging from EVFP */
BFA_FCS_FABRIC_SM_DELAYED = 11, /* timeout delay event */
BFA_FCS_FABRIC_SM_AUTH_FAILED = 12, /* authentication failed */
BFA_FCS_FABRIC_SM_AUTH_SUCCESS =