mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 13:11:40 +00:00
[SCSI] bfa: Add support for FC Arbitrated Loop topology.
- Add private loop topology support at 2G/4G/8G speeds with following limitations 1. No support for multiple initiators in the loop 2. No public loop support. If attached to a loop with an FL_Port, device continues to work as a private NL_Port in the loop 3. No auto topology detection. User has to manually set the configured topology to loop if attaching to loop. - When loop topology is configured, enabling FC port features QoS/Trunk/TRL are not allowed and vice versa. Signed-off-by: Vijaya Mohan Guvva <vmohan@brocade.com> Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
56d92aa5cf
commit
bc0e2c2a97
@ -159,6 +159,8 @@ enum bfa_status {
|
||||
BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */
|
||||
BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */
|
||||
BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */
|
||||
BFA_STATUS_ERROR_TRL_ENABLED = 87, /* TRL is enabled */
|
||||
BFA_STATUS_ERROR_QOS_ENABLED = 88, /* QoS is enabled */
|
||||
BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */
|
||||
BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */
|
||||
BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */
|
||||
@ -184,6 +186,9 @@ enum bfa_status {
|
||||
BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */
|
||||
BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */
|
||||
BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */
|
||||
BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */
|
||||
BFA_STATUS_LOOP_UNSUPP_MEZZ = 231, /* Loop topology is not supported
|
||||
* on mezz cards */
|
||||
BFA_STATUS_MAX_VAL /* Unknown error code */
|
||||
};
|
||||
#define bfa_status_t enum bfa_status
|
||||
|
@ -324,12 +324,46 @@ struct bfa_fw_fcoe_port_stats_s {
|
||||
struct bfa_fw_fip_stats_s fip_stats;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief LPSM statistics
|
||||
*/
|
||||
struct bfa_fw_lpsm_stats_s {
|
||||
u32 cls_rx; /* LPSM cls_rx */
|
||||
u32 cls_tx; /* LPSM cls_tx */
|
||||
u32 arbf0_rx; /* LPSM abrf0 rcvd */
|
||||
u32 arbf0_tx; /* LPSM abrf0 xmit */
|
||||
u32 init_rx; /* LPSM loop init start */
|
||||
u32 unexp_hwst; /* LPSM unknown hw state */
|
||||
u32 unexp_frame; /* LPSM unknown_frame */
|
||||
u32 unexp_prim; /* LPSM unexpected primitive */
|
||||
u32 prev_alpa_unavail; /* LPSM prev alpa unavailable */
|
||||
u32 alpa_unavail; /* LPSM alpa not available */
|
||||
u32 lip_rx; /* LPSM lip rcvd */
|
||||
u32 lip_f7f7_rx; /* LPSM lip f7f7 rcvd */
|
||||
u32 lip_f8_rx; /* LPSM lip f8 rcvd */
|
||||
u32 lip_f8f7_rx; /* LPSM lip f8f7 rcvd */
|
||||
u32 lip_other_rx; /* LPSM lip other rcvd */
|
||||
u32 lip_tx; /* LPSM lip xmit */
|
||||
u32 retry_tov; /* LPSM retry TOV */
|
||||
u32 lip_tov; /* LPSM LIP wait TOV */
|
||||
u32 idle_tov; /* LPSM idle wait TOV */
|
||||
u32 arbf0_tov; /* LPSM arbfo wait TOV */
|
||||
u32 stop_loop_tov; /* LPSM stop loop wait TOV */
|
||||
u32 lixa_tov; /* LPSM lisa wait TOV */
|
||||
u32 lixx_tov; /* LPSM lilp/lirp wait TOV */
|
||||
u32 cls_tov; /* LPSM cls wait TOV */
|
||||
u32 sler; /* LPSM SLER recvd */
|
||||
u32 failed; /* LPSM failed */
|
||||
u32 success; /* LPSM online */
|
||||
};
|
||||
|
||||
/*
|
||||
* IOC firmware FC uport stats
|
||||
*/
|
||||
struct bfa_fw_fc_uport_stats_s {
|
||||
struct bfa_fw_port_snsm_stats_s snsm_stats;
|
||||
struct bfa_fw_port_lksm_stats_s lksm_stats;
|
||||
struct bfa_fw_lpsm_stats_s lpsm_stats;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -357,11 +391,6 @@ struct bfa_fw_fcxchg_stats_s {
|
||||
u32 ua_state_inv;
|
||||
};
|
||||
|
||||
struct bfa_fw_lpsm_stats_s {
|
||||
u32 cls_rx;
|
||||
u32 cls_tx;
|
||||
};
|
||||
|
||||
/*
|
||||
* Trunk statistics
|
||||
*/
|
||||
@ -454,7 +483,6 @@ struct bfa_fw_stats_s {
|
||||
struct bfa_fw_io_stats_s io_stats;
|
||||
struct bfa_fw_port_stats_s port_stats;
|
||||
struct bfa_fw_fcxchg_stats_s fcxchg_stats;
|
||||
struct bfa_fw_lpsm_stats_s lpsm_stats;
|
||||
struct bfa_fw_lps_stats_s lps_stats;
|
||||
struct bfa_fw_trunk_stats_s trunk_stats;
|
||||
struct bfa_fw_advsm_stats_s advsm_stats;
|
||||
@ -498,9 +526,10 @@ enum bfa_qos_bw_alloc {
|
||||
* QoS attribute returned in QoS Query
|
||||
*/
|
||||
struct bfa_qos_attr_s {
|
||||
u8 state; /* QoS current state */
|
||||
u8 rsvd[3];
|
||||
u32 total_bb_cr; /* Total BB Credits */
|
||||
u8 state; /* QoS current state */
|
||||
u8 rsvd1[3];
|
||||
u32 total_bb_cr; /* Total BB Credits */
|
||||
u32 rsvd2[2];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -714,9 +743,11 @@ enum bfa_port_type {
|
||||
*/
|
||||
enum bfa_port_topology {
|
||||
BFA_PORT_TOPOLOGY_NONE = 0, /* No valid topology */
|
||||
BFA_PORT_TOPOLOGY_P2P = 1, /* P2P only */
|
||||
BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */
|
||||
BFA_PORT_TOPOLOGY_AUTO = 3, /* auto topology selection */
|
||||
BFA_PORT_TOPOLOGY_P2P_OLD_VER = 1, /* P2P def for older ver */
|
||||
BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */
|
||||
BFA_PORT_TOPOLOGY_AUTO_OLD_VER = 3, /* auto def for older ver */
|
||||
BFA_PORT_TOPOLOGY_AUTO = 4, /* auto topology selection */
|
||||
BFA_PORT_TOPOLOGY_P2P = 5, /* P2P only */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -851,9 +882,10 @@ struct bfa_port_cfg_s {
|
||||
u8 bb_scn; /* BB_SCN value from FLOGI Exchg */
|
||||
u8 bb_scn_state; /* Config state of BB_SCN */
|
||||
u8 faa_state; /* FAA enabled/disabled */
|
||||
u8 rsvd[1];
|
||||
u8 rsvd1;
|
||||
u16 path_tov; /* device path timeout */
|
||||
u16 q_depth; /* SCSI Queue depth */
|
||||
u32 rsvd2;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
@ -971,6 +1003,13 @@ struct bfa_trunk_vc_attr_s {
|
||||
u16 vc_credits[8];
|
||||
};
|
||||
|
||||
struct bfa_fcport_loop_info_s {
|
||||
u8 myalpa; /* alpa claimed */
|
||||
u8 alpabm_val; /* alpa bitmap valid or not (1 or 0) */
|
||||
u8 resvd[6];
|
||||
struct fc_alpabm_s alpabm; /* alpa bitmap */
|
||||
};
|
||||
|
||||
/*
|
||||
* Link state information
|
||||
*/
|
||||
@ -981,13 +1020,18 @@ struct bfa_port_link_s {
|
||||
u8 speed; /* Link speed (1/2/4/8 G) */
|
||||
u32 linkstate_opt; /* Linkstate optional data (debug) */
|
||||
u8 trunked; /* Trunked or not (1 or 0) */
|
||||
u8 resvd[3];
|
||||
u8 resvd[7];
|
||||
struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
|
||||
union {
|
||||
struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
|
||||
struct bfa_trunk_vc_attr_s trunk_vc_attr;
|
||||
struct bfa_fcport_fcf_s fcf; /* FCF information (for FCoE) */
|
||||
} vc_fcf;
|
||||
struct bfa_fcport_loop_info_s loop_info;
|
||||
union {
|
||||
struct bfa_qos_vc_attr_s qos_vc_attr;
|
||||
/* VC info from ELP */
|
||||
struct bfa_trunk_vc_attr_s trunk_vc_attr;
|
||||
struct bfa_fcport_fcf_s fcf;
|
||||
/* FCF information (for FCoE) */
|
||||
} vc_fcf;
|
||||
} attr;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
@ -1112,6 +1156,9 @@ struct bfa_port_fc_stats_s {
|
||||
u64 tx_frames; /* Tx frames */
|
||||
u64 tx_words; /* Tx words */
|
||||
u64 tx_lip; /* Tx LIP */
|
||||
u64 tx_lip_f7f7; /* Tx LIP_F7F7 */
|
||||
u64 tx_lip_f8f7; /* Tx LIP_F8F7 */
|
||||
u64 tx_arbf0; /* Tx ARB F0 */
|
||||
u64 tx_nos; /* Tx NOS */
|
||||
u64 tx_ols; /* Tx OLS */
|
||||
u64 tx_lr; /* Tx LR */
|
||||
@ -1119,6 +1166,9 @@ struct bfa_port_fc_stats_s {
|
||||
u64 rx_frames; /* Rx frames */
|
||||
u64 rx_words; /* Rx words */
|
||||
u64 lip_count; /* Rx LIP */
|
||||
u64 rx_lip_f7f7; /* Rx LIP_F7F7 */
|
||||
u64 rx_lip_f8f7; /* Rx LIP_F8F7 */
|
||||
u64 rx_arbf0; /* Rx ARB F0 */
|
||||
u64 nos_count; /* Rx NOS */
|
||||
u64 ols_count; /* Rx OLS */
|
||||
u64 lr_count; /* Rx LR */
|
||||
@ -1140,6 +1190,7 @@ struct bfa_port_fc_stats_s {
|
||||
u64 bbsc_frames_lost; /* Credit Recovery-Frames Lost */
|
||||
u64 bbsc_credits_lost; /* Credit Recovery-Credits Lost */
|
||||
u64 bbsc_link_resets; /* Credit Recovery-Link Resets */
|
||||
u64 loop_timeouts; /* Loop timeouts */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -24,6 +24,7 @@ typedef u64 wwn_t;
|
||||
|
||||
#define WWN_NULL (0)
|
||||
#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */
|
||||
#define FC_ALPA_MAX 128
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
@ -1015,6 +1016,10 @@ struct fc_symname_s {
|
||||
u8 symname[FC_SYMNAME_MAX];
|
||||
};
|
||||
|
||||
struct fc_alpabm_s {
|
||||
u8 alpa_bm[FC_ALPA_MAX / 8];
|
||||
};
|
||||
|
||||
/*
|
||||
* protocol default timeout values
|
||||
*/
|
||||
|
@ -228,6 +228,10 @@ fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
|
||||
|
||||
memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
|
||||
|
||||
/* For FC AL bb_cr is 0 and altbbcred is 1 */
|
||||
if (!bb_cr)
|
||||
plogi->csp.altbbcred = 1;
|
||||
|
||||
plogi->els_cmd.els_code = els_code;
|
||||
if (els_code == FC_ELS_PLOGI)
|
||||
fc_els_req_build(fchs, d_id, s_id, ox_id);
|
||||
|
@ -303,16 +303,30 @@ static void
|
||||
bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
|
||||
enum bfa_fcs_fabric_event event)
|
||||
{
|
||||
struct bfa_s *bfa = fabric->fcs->bfa;
|
||||
|
||||
bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
|
||||
bfa_trc(fabric->fcs, event);
|
||||
|
||||
switch (event) {
|
||||
case BFA_FCS_FABRIC_SM_START:
|
||||
if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
|
||||
if (!bfa_fcport_is_linkup(fabric->fcs->bfa)) {
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
|
||||
break;
|
||||
}
|
||||
if (bfa_fcport_get_topology(bfa) ==
|
||||
BFA_PORT_TOPOLOGY_LOOP) {
|
||||
fabric->fab_type = BFA_FCS_FABRIC_LOOP;
|
||||
fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
|
||||
fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
|
||||
bfa_sm_set_state(fabric,
|
||||
bfa_fcs_fabric_sm_online);
|
||||
bfa_fcs_fabric_set_opertype(fabric);
|
||||
bfa_fcs_lport_online(&fabric->bport);
|
||||
} else {
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
|
||||
bfa_fcs_fabric_login(fabric);
|
||||
} else
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
|
||||
}
|
||||
break;
|
||||
|
||||
case BFA_FCS_FABRIC_SM_LINK_UP:
|
||||
@ -337,16 +351,28 @@ static void
|
||||
bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
|
||||
enum bfa_fcs_fabric_event event)
|
||||
{
|
||||
struct bfa_s *bfa = fabric->fcs->bfa;
|
||||
|
||||
bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
|
||||
bfa_trc(fabric->fcs, event);
|
||||
|
||||
switch (event) {
|
||||
case BFA_FCS_FABRIC_SM_LINK_UP:
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
|
||||
bfa_fcs_fabric_login(fabric);
|
||||
if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) {
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
|
||||
bfa_fcs_fabric_login(fabric);
|
||||
break;
|
||||
}
|
||||
fabric->fab_type = BFA_FCS_FABRIC_LOOP;
|
||||
fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
|
||||
fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
|
||||
bfa_fcs_fabric_set_opertype(fabric);
|
||||
bfa_fcs_lport_online(&fabric->bport);
|
||||
break;
|
||||
|
||||
case BFA_FCS_FABRIC_SM_RETRY_OP:
|
||||
case BFA_FCS_FABRIC_SM_LOOPBACK:
|
||||
break;
|
||||
|
||||
case BFA_FCS_FABRIC_SM_DELETE:
|
||||
@ -595,14 +621,20 @@ void
|
||||
bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
|
||||
enum bfa_fcs_fabric_event event)
|
||||
{
|
||||
struct bfa_s *bfa = fabric->fcs->bfa;
|
||||
|
||||
bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
|
||||
bfa_trc(fabric->fcs, event);
|
||||
|
||||
switch (event) {
|
||||
case BFA_FCS_FABRIC_SM_LINK_DOWN:
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
|
||||
bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
|
||||
bfa_fcs_fabric_notify_offline(fabric);
|
||||
if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
|
||||
bfa_fcs_lport_offline(&fabric->bport);
|
||||
} else {
|
||||
bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
|
||||
bfa_fcs_fabric_notify_offline(fabric);
|
||||
}
|
||||
break;
|
||||
|
||||
case BFA_FCS_FABRIC_SM_DELETE:
|
||||
@ -719,20 +751,29 @@ static void
|
||||
bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric,
|
||||
enum bfa_fcs_fabric_event event)
|
||||
{
|
||||
struct bfa_s *bfa = fabric->fcs->bfa;
|
||||
|
||||
bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
|
||||
bfa_trc(fabric->fcs, event);
|
||||
|
||||
switch (event) {
|
||||
case BFA_FCS_FABRIC_SM_STOPCOMP:
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
|
||||
bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT);
|
||||
if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
|
||||
} else {
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
|
||||
bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT);
|
||||
}
|
||||
break;
|
||||
|
||||
case BFA_FCS_FABRIC_SM_LINK_UP:
|
||||
break;
|
||||
|
||||
case BFA_FCS_FABRIC_SM_LINK_DOWN:
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
|
||||
if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
|
||||
else
|
||||
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -975,9 +1016,6 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
|
||||
struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
|
||||
u8 alpa = 0, bb_scn = 0;
|
||||
|
||||
if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
|
||||
alpa = bfa_fcport_get_myalpa(bfa);
|
||||
|
||||
if (bfa_fcs_fabric_is_bbscn_enabled(fabric) &&
|
||||
(!fabric->fcs->bbscn_flogi_rjt))
|
||||
bb_scn = BFA_FCS_PORT_DEF_BB_SCN;
|
||||
|
@ -118,9 +118,9 @@ struct bfa_fcs_lport_fab_s {
|
||||
#define MAX_ALPA_COUNT 127
|
||||
|
||||
struct bfa_fcs_lport_loop_s {
|
||||
u8 num_alpa; /* Num of ALPA entries in the map */
|
||||
u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional
|
||||
*Map */
|
||||
u8 num_alpa; /* Num of ALPA entries in the map */
|
||||
u8 alpabm_valid; /* alpa bitmap valid or not (1 or 0) */
|
||||
u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional Map */
|
||||
struct bfa_fcs_lport_s *port; /* parent port */
|
||||
};
|
||||
|
||||
@ -175,6 +175,7 @@ enum bfa_fcs_fabric_type {
|
||||
BFA_FCS_FABRIC_UNKNOWN = 0,
|
||||
BFA_FCS_FABRIC_SWITCHED = 1,
|
||||
BFA_FCS_FABRIC_N2N = 2,
|
||||
BFA_FCS_FABRIC_LOOP = 3,
|
||||
};
|
||||
|
||||
|
||||
@ -350,9 +351,10 @@ void bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg,
|
||||
struct bfa_fcxp_s *fcxp_alloced);
|
||||
void bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *vport);
|
||||
void bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *vport);
|
||||
void bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *vport);
|
||||
void bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *vport);
|
||||
void bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
|
||||
struct fchs_s *rx_frame, u32 len);
|
||||
void bfa_fcs_lport_lip_scn_online(bfa_fcs_lport_t *port);
|
||||
|
||||
struct bfa_fcs_vport_s {
|
||||
struct list_head qe; /* queue elem */
|
||||
@ -453,6 +455,7 @@ struct bfa_fcs_rport_s {
|
||||
struct bfa_rport_stats_s stats; /* rport stats */
|
||||
enum bfa_rport_function scsi_function; /* Initiator/Target */
|
||||
struct bfa_fcs_rpf_s rpf; /* Rport features module */
|
||||
bfa_boolean_t scn_online; /* SCN online flag */
|
||||
};
|
||||
|
||||
static inline struct bfa_rport_s *
|
||||
@ -733,7 +736,7 @@ enum rport_event {
|
||||
RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */
|
||||
RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */
|
||||
RPSM_EVENT_DELETE = 7, /* RPORT delete request */
|
||||
RPSM_EVENT_SCN = 8, /* state change notification */
|
||||
RPSM_EVENT_FAB_SCN = 8, /* state change notification */
|
||||
RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */
|
||||
RPSM_EVENT_FAILED = 10, /* Request to rport failed. */
|
||||
RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */
|
||||
@ -744,7 +747,9 @@ enum rport_event {
|
||||
RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */
|
||||
RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */
|
||||
RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continuously */
|
||||
RPSM_EVENT_FC4_FCS_ONLINE = 19, /*!< FC-4 FCS online complete */
|
||||
RPSM_EVENT_SCN_OFFLINE = 19, /* loop scn offline */
|
||||
RPSM_EVENT_SCN_ONLINE = 20, /* loop scn online */
|
||||
RPSM_EVENT_FC4_FCS_ONLINE = 21, /* FC-4 FCS online complete */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -763,7 +768,7 @@ enum bfa_fcs_itnim_event {
|
||||
BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */
|
||||
BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */
|
||||
BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */
|
||||
BFA_FCS_ITNIM_SM_HAL_ONLINE = 13, /*!< bfa rport online event */
|
||||
BFA_FCS_ITNIM_SM_HAL_ONLINE = 13, /* bfa rport online event */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -23,6 +23,34 @@
|
||||
|
||||
BFA_TRC_FILE(FCS, PORT);
|
||||
|
||||
/*
|
||||
* ALPA to LIXA bitmap mapping
|
||||
*
|
||||
* ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31
|
||||
* is for L_bit (login required) and is filled as ALPA 0x00 here.
|
||||
*/
|
||||
static const u8 loop_alpa_map[] = {
|
||||
0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, /* Word 0 Bits 31..24 */
|
||||
0x17, 0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25, /* Word 0 Bits 23..16 */
|
||||
0x26, 0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, /* Word 0 Bits 15..08 */
|
||||
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, /* Word 0 Bits 07..00 */
|
||||
|
||||
0x3C, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, /* Word 1 Bits 31..24 */
|
||||
0x4C, 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, /* Word 1 Bits 23..16 */
|
||||
0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67, /* Word 1 Bits 15..08 */
|
||||
0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, /* Word 1 Bits 07..00 */
|
||||
|
||||
0x73, 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, /* Word 2 Bits 31..24 */
|
||||
0x81, 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, /* Word 2 Bits 23..16 */
|
||||
0x9B, 0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, /* Word 2 Bits 15..08 */
|
||||
0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, /* Word 2 Bits 07..00 */
|
||||
|
||||
0xB3, 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3, /* Word 3 Bits 31..24 */
|
||||
0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, /* Word 3 Bits 23..16 */
|
||||
0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, /* Word 3 Bits 15..08 */
|
||||
0xDA, 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF, /* Word 3 Bits 07..00 */
|
||||
};
|
||||
|
||||
static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port,
|
||||
struct fchs_s *rx_fchs, u8 reason_code,
|
||||
u8 reason_code_expl);
|
||||
@ -51,6 +79,10 @@ static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port);
|
||||
static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port);
|
||||
static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port);
|
||||
|
||||
static void bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port);
|
||||
static void bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port);
|
||||
static void bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port);
|
||||
|
||||
static struct {
|
||||
void (*init) (struct bfa_fcs_lport_s *port);
|
||||
void (*online) (struct bfa_fcs_lport_s *port);
|
||||
@ -62,7 +94,9 @@ static struct {
|
||||
bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online,
|
||||
bfa_fcs_lport_fab_offline}, {
|
||||
bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online,
|
||||
bfa_fcs_lport_n2n_offline},
|
||||
bfa_fcs_lport_n2n_offline}, {
|
||||
bfa_fcs_lport_loop_init, bfa_fcs_lport_loop_online,
|
||||
bfa_fcs_lport_loop_offline},
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1127,7 +1161,7 @@ static void
|
||||
bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
|
||||
{
|
||||
bfa_fcs_lport_ns_online(port);
|
||||
bfa_fcs_lport_scn_online(port);
|
||||
bfa_fcs_lport_fab_scn_online(port);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1221,6 +1255,98 @@ bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
|
||||
n2n_port->reply_oxid = 0;
|
||||
}
|
||||
|
||||
void
|
||||
bfa_fcport_get_loop_attr(struct bfa_fcs_lport_s *port)
|
||||
{
|
||||
int i = 0, j = 0, bit = 0, alpa_bit = 0;
|
||||
u8 k = 0;
|
||||
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(port->fcs->bfa);
|
||||
|
||||
port->port_topo.ploop.alpabm_valid = fcport->alpabm_valid;
|
||||
port->pid = fcport->myalpa;
|
||||
port->pid = bfa_hton3b(port->pid);
|
||||
|
||||
for (i = 0; i < (FC_ALPA_MAX / 8); i++) {
|
||||
for (j = 0, alpa_bit = 0; j < 8; j++, alpa_bit++) {
|
||||
bfa_trc(port->fcs->bfa, fcport->alpabm.alpa_bm[i]);
|
||||
bit = (fcport->alpabm.alpa_bm[i] & (1 << (7 - j)));
|
||||
if (bit) {
|
||||
port->port_topo.ploop.alpa_pos_map[k] =
|
||||
loop_alpa_map[(i * 8) + alpa_bit];
|
||||
k++;
|
||||
bfa_trc(port->fcs->bfa, k);
|
||||
bfa_trc(port->fcs->bfa,
|
||||
port->port_topo.ploop.alpa_pos_map[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
port->port_topo.ploop.num_alpa = k;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by fcs/port to initialize Loop topology.
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by fcs/port to notify transition to online state.
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port)
|
||||
{
|
||||
u8 num_alpa = 0, alpabm_valid = 0;
|
||||
struct bfa_fcs_rport_s *rport;
|
||||
u8 *alpa_map = NULL;
|
||||
int i = 0;
|
||||
u32 pid;
|
||||
|
||||
bfa_fcport_get_loop_attr(port);
|
||||
|
||||
num_alpa = port->port_topo.ploop.num_alpa;
|
||||
alpabm_valid = port->port_topo.ploop.alpabm_valid;
|
||||
alpa_map = port->port_topo.ploop.alpa_pos_map;
|
||||
|
||||
bfa_trc(port->fcs->bfa, port->pid);
|
||||
bfa_trc(port->fcs->bfa, num_alpa);
|
||||
if (alpabm_valid == 1) {
|
||||
for (i = 0; i < num_alpa; i++) {
|
||||
bfa_trc(port->fcs->bfa, alpa_map[i]);
|
||||
if (alpa_map[i] != bfa_hton3b(port->pid)) {
|
||||
pid = alpa_map[i];
|
||||
bfa_trc(port->fcs->bfa, pid);
|
||||
rport = bfa_fcs_lport_get_rport_by_pid(port,
|
||||
bfa_hton3b(pid));
|
||||
if (!rport)
|
||||
rport = bfa_fcs_rport_create(port,
|
||||
bfa_hton3b(pid));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < MAX_ALPA_COUNT; i++) {
|
||||
if (alpa_map[i] != port->pid) {
|
||||
pid = loop_alpa_map[i];
|
||||
bfa_trc(port->fcs->bfa, pid);
|
||||
rport = bfa_fcs_lport_get_rport_by_pid(port,
|
||||
bfa_hton3b(pid));
|
||||
if (!rport)
|
||||
rport = bfa_fcs_rport_create(port,
|
||||
bfa_hton3b(pid));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by fcs/port to notify transition to offline state.
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port)
|
||||
{
|
||||
}
|
||||
|
||||
#define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
|
||||
|
||||
/*
|
||||
@ -5199,7 +5325,7 @@ bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port)
|
||||
}
|
||||
|
||||
void
|
||||
bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port)
|
||||
bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *port)
|
||||
{
|
||||
struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
|
||||
|
||||
@ -5620,6 +5746,15 @@ bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port)
|
||||
memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s));
|
||||
}
|
||||
|
||||
/*
|
||||
* Let new loop map create missing rports
|
||||
*/
|
||||
void
|
||||
bfa_fcs_lport_lip_scn_online(struct bfa_fcs_lport_s *port)
|
||||
{
|
||||
bfa_fcs_lport_loop_online(port);
|
||||
}
|
||||
|
||||
/*
|
||||
* FCS virtual port state machine
|
||||
*/
|
||||
|
@ -106,9 +106,13 @@ static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
|
||||
enum rport_event event);
|
||||
static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
|
||||
enum rport_event event);
|
||||
static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
|
||||
enum rport_event event);
|
||||
static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport,
|
||||
static void bfa_fcs_rport_sm_adisc_online_sending(
|
||||
struct bfa_fcs_rport_s *rport, enum rport_event event);
|
||||
static void bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
|
||||
enum rport_event event);
|
||||
static void bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s
|
||||
*rport, enum rport_event event);
|
||||
static void bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
|
||||
enum rport_event event);
|
||||
static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
|
||||
enum rport_event event);
|
||||
@ -150,8 +154,10 @@ static struct bfa_sm_table_s rport_sm_table[] = {
|
||||
{BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
|
||||
{BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
|
||||
{BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
|
||||
{BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC},
|
||||
{BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC},
|
||||
{BFA_SM(bfa_fcs_rport_sm_adisc_online_sending), BFA_RPORT_ADISC},
|
||||
{BFA_SM(bfa_fcs_rport_sm_adisc_online), BFA_RPORT_ADISC},
|
||||
{BFA_SM(bfa_fcs_rport_sm_adisc_offline_sending), BFA_RPORT_ADISC},
|
||||
{BFA_SM(bfa_fcs_rport_sm_adisc_offline), BFA_RPORT_ADISC},
|
||||
{BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
|
||||
{BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
|
||||
{BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
|
||||
@ -231,10 +237,19 @@ bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_send_plogiacc(rport, NULL);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
|
||||
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
|
||||
bfa_timer_start(rport->fcs->bfa, &rport->timer,
|
||||
bfa_fcs_rport_timeout, rport,
|
||||
bfa_fcs_rport_del_timeout);
|
||||
break;
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
/* query the NS */
|
||||
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
|
||||
WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
|
||||
BFA_PORT_TOPOLOGY_LOOP));
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
|
||||
rport->ns_retries = 0;
|
||||
bfa_fcs_rport_send_nsdisc(rport, NULL);
|
||||
@ -280,12 +295,20 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
|
||||
|
||||
case RPSM_EVENT_PLOGI_RCVD:
|
||||
case RPSM_EVENT_PLOGI_COMP:
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
/*
|
||||
* Ignore, SCN is possibly online notification.
|
||||
*/
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
|
||||
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
|
||||
bfa_timer_start(rport->fcs->bfa, &rport->timer,
|
||||
bfa_fcs_rport_timeout, rport,
|
||||
bfa_fcs_rport_del_timeout);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
|
||||
@ -346,9 +369,19 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_send_plogiacc(rport, NULL);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
|
||||
bfa_timer_stop(&rport->timer);
|
||||
bfa_timer_start(rport->fcs->bfa, &rport->timer,
|
||||
bfa_fcs_rport_timeout, rport,
|
||||
bfa_fcs_rport_del_timeout);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
bfa_timer_stop(&rport->timer);
|
||||
WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
|
||||
BFA_PORT_TOPOLOGY_LOOP));
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
|
||||
rport->ns_retries = 0;
|
||||
bfa_fcs_rport_send_nsdisc(rport, NULL);
|
||||
@ -422,7 +455,18 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
}
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_PLOGI_RETRY:
|
||||
case RPSM_EVENT_SCN_ONLINE:
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
|
||||
bfa_fcxp_discard(rport->fcxp);
|
||||
bfa_timer_start(rport->fcs->bfa, &rport->timer,
|
||||
bfa_fcs_rport_timeout, rport,
|
||||
bfa_fcs_rport_del_timeout);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_PLOGI_RETRY:
|
||||
rport->plogi_retries = 0;
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
|
||||
bfa_timer_start(rport->fcs->bfa, &rport->timer,
|
||||
@ -440,8 +484,10 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
bfa_fcxp_discard(rport->fcxp);
|
||||
WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
|
||||
BFA_PORT_TOPOLOGY_LOOP));
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
|
||||
rport->ns_retries = 0;
|
||||
bfa_fcs_rport_send_nsdisc(rport, NULL);
|
||||
@ -512,7 +558,8 @@ bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
|
||||
case RPSM_EVENT_PLOGI_COMP:
|
||||
case RPSM_EVENT_LOGO_IMP:
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
|
||||
bfa_fcs_rport_fcs_offline_action(rport);
|
||||
break;
|
||||
@ -561,9 +608,10 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_fcs_offline_action(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
case RPSM_EVENT_LOGO_IMP:
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
|
||||
bfa_fcs_rport_fcs_offline_action(rport);
|
||||
break;
|
||||
@ -595,14 +643,15 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
bfa_trc(rport->fcs, event);
|
||||
|
||||
switch (event) {
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
|
||||
bfa_sm_set_state(rport,
|
||||
bfa_fcs_rport_sm_nsquery_sending);
|
||||
rport->ns_retries = 0;
|
||||
bfa_fcs_rport_send_nsdisc(rport, NULL);
|
||||
} else {
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
|
||||
bfa_sm_set_state(rport,
|
||||
bfa_fcs_rport_sm_adisc_online_sending);
|
||||
bfa_fcs_rport_send_adisc(rport, NULL);
|
||||
}
|
||||
break;
|
||||
@ -610,6 +659,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
case RPSM_EVENT_PLOGI_RCVD:
|
||||
case RPSM_EVENT_LOGO_IMP:
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
|
||||
bfa_fcs_rport_hal_offline_action(rport);
|
||||
break;
|
||||
@ -625,6 +675,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
bfa_fcs_rport_hal_offline_action(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN_ONLINE:
|
||||
case RPSM_EVENT_PLOGI_COMP:
|
||||
break;
|
||||
|
||||
@ -656,7 +707,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_hal_offline_action(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
/*
|
||||
* ignore SCN, wait for response to query itself
|
||||
*/
|
||||
@ -696,7 +747,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
|
||||
switch (event) {
|
||||
case RPSM_EVENT_ACCEPTED:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online_sending);
|
||||
bfa_fcs_rport_send_adisc(rport, NULL);
|
||||
break;
|
||||
|
||||
@ -718,7 +769,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
bfa_fcs_rport_hal_offline_action(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_LOGO_RCVD:
|
||||
@ -747,7 +798,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
* authenticating with rport. FC-4s are paused.
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s *rport,
|
||||
enum rport_event event)
|
||||
{
|
||||
bfa_trc(rport->fcs, rport->pwwn);
|
||||
@ -756,7 +807,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
|
||||
|
||||
switch (event) {
|
||||
case RPSM_EVENT_FCXP_SENT:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc);
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_DELETE:
|
||||
@ -779,7 +830,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_hal_offline_action(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_PLOGI_RCVD:
|
||||
@ -798,7 +849,8 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
|
||||
* FC-4s are paused.
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
|
||||
enum rport_event event)
|
||||
{
|
||||
bfa_trc(rport->fcs, rport->pwwn);
|
||||
bfa_trc(rport->fcs, rport->pid);
|
||||
@ -831,7 +883,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
bfa_fcs_rport_hal_offline_action(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
/*
|
||||
* already processing RSCN
|
||||
*/
|
||||
@ -856,7 +908,96 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
}
|
||||
|
||||
/*
|
||||
* Rport has sent LOGO. Awaiting FC-4 offline completion callback.
|
||||
* ADISC is being sent for authenticating with rport
|
||||
* Already did offline actions.
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s *rport,
|
||||
enum rport_event event)
|
||||
{
|
||||
bfa_trc(rport->fcs, rport->pwwn);
|
||||
bfa_trc(rport->fcs, rport->pid);
|
||||
bfa_trc(rport->fcs, event);
|
||||
|
||||
switch (event) {
|
||||
case RPSM_EVENT_FCXP_SENT:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_offline);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_DELETE:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
case RPSM_EVENT_LOGO_IMP:
|
||||
case RPSM_EVENT_LOGO_RCVD:
|
||||
case RPSM_EVENT_PRLO_RCVD:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
|
||||
bfa_fcxp_walloc_cancel(rport->fcs->bfa,
|
||||
&rport->fcxp_wqe);
|
||||
bfa_timer_start(rport->fcs->bfa, &rport->timer,
|
||||
bfa_fcs_rport_timeout, rport,
|
||||
bfa_fcs_rport_del_timeout);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_PLOGI_RCVD:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
|
||||
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
|
||||
bfa_fcs_rport_send_plogiacc(rport, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
bfa_sm_fault(rport->fcs, event);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ADISC to rport
|
||||
* Already did offline actions
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
|
||||
enum rport_event event)
|
||||
{
|
||||
bfa_trc(rport->fcs, rport->pwwn);
|
||||
bfa_trc(rport->fcs, rport->pid);
|
||||
bfa_trc(rport->fcs, event);
|
||||
|
||||
switch (event) {
|
||||
case RPSM_EVENT_ACCEPTED:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
|
||||
bfa_fcs_rport_hal_online(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_PLOGI_RCVD:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
|
||||
bfa_fcxp_discard(rport->fcxp);
|
||||
bfa_fcs_rport_send_plogiacc(rport, NULL);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_FAILED:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
|
||||
bfa_timer_start(rport->fcs->bfa, &rport->timer,
|
||||
bfa_fcs_rport_timeout, rport,
|
||||
bfa_fcs_rport_del_timeout);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_DELETE:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
case RPSM_EVENT_LOGO_IMP:
|
||||
case RPSM_EVENT_LOGO_RCVD:
|
||||
case RPSM_EVENT_PRLO_RCVD:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
|
||||
bfa_fcxp_discard(rport->fcxp);
|
||||
bfa_timer_start(rport->fcs->bfa, &rport->timer,
|
||||
bfa_fcs_rport_timeout, rport,
|
||||
bfa_fcs_rport_del_timeout);
|
||||
break;
|
||||
|
||||
default:
|
||||
bfa_sm_fault(rport->fcs, event);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Rport has sent LOGO. Awaiting FC-4 offline completion callback.
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
|
||||
@ -881,6 +1022,8 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN_ONLINE:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
case RPSM_EVENT_HCB_ONLINE:
|
||||
case RPSM_EVENT_LOGO_RCVD:
|
||||
case RPSM_EVENT_PRLO_RCVD:
|
||||
@ -945,6 +1088,8 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_hal_offline(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN_ONLINE:
|
||||
break;
|
||||
case RPSM_EVENT_LOGO_RCVD:
|
||||
/*
|
||||
* Rport is going offline. Just ack the logo
|
||||
@ -956,8 +1101,9 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_send_prlo_acc(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
case RPSM_EVENT_HCB_ONLINE:
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
case RPSM_EVENT_LOGO_IMP:
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
/*
|
||||
@ -1015,6 +1161,19 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_sm_nsdisc_sending);
|
||||
rport->ns_retries = 0;
|
||||
bfa_fcs_rport_send_nsdisc(rport, NULL);
|
||||
} else if (bfa_fcport_get_topology(rport->port->fcs->bfa) ==
|
||||
BFA_PORT_TOPOLOGY_LOOP) {
|
||||
if (rport->scn_online) {
|
||||
bfa_sm_set_state(rport,
|
||||
bfa_fcs_rport_sm_adisc_offline_sending);
|
||||
bfa_fcs_rport_send_adisc(rport, NULL);
|
||||
} else {
|
||||
bfa_sm_set_state(rport,
|
||||
bfa_fcs_rport_sm_offline);
|
||||
bfa_timer_start(rport->fcs->bfa, &rport->timer,
|
||||
bfa_fcs_rport_timeout, rport,
|
||||
bfa_fcs_rport_del_timeout);
|
||||
}
|
||||
} else {
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
|
||||
rport->plogi_retries = 0;
|
||||
@ -1027,7 +1186,9 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_free(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_SCN_ONLINE:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
case RPSM_EVENT_LOGO_RCVD:
|
||||
case RPSM_EVENT_PRLO_RCVD:
|
||||
case RPSM_EVENT_PLOGI_RCVD:
|
||||
@ -1106,6 +1267,8 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN_ONLINE:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
case RPSM_EVENT_LOGO_RCVD:
|
||||
case RPSM_EVENT_PRLO_RCVD:
|
||||
/*
|
||||
@ -1146,6 +1309,8 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN_ONLINE:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
break;
|
||||
|
||||
@ -1172,7 +1337,9 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_free(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_SCN_ONLINE:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
break;
|
||||
|
||||
@ -1209,10 +1376,12 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
bfa_fcs_rport_free(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
|
||||
bfa_timer_stop(&rport->timer);
|
||||
WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
|
||||
BFA_PORT_TOPOLOGY_LOOP));
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
|
||||
rport->ns_retries = 0;
|
||||
bfa_fcs_rport_send_nsdisc(rport, NULL);
|
||||
break;
|
||||
@ -1232,6 +1401,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
case RPSM_EVENT_LOGO_RCVD:
|
||||
case RPSM_EVENT_PRLO_RCVD:
|
||||
case RPSM_EVENT_LOGO_IMP:
|
||||
case RPSM_EVENT_SCN_OFFLINE:
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_PLOGI_COMP:
|
||||
@ -1240,6 +1410,12 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
|
||||
bfa_fcs_rport_fcs_online_action(rport);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN_ONLINE:
|
||||
bfa_timer_stop(&rport->timer);
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
|
||||
bfa_fcs_rport_send_plogi(rport, NULL);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_PLOGI_SEND:
|
||||
bfa_timer_stop(&rport->timer);
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
|
||||
@ -1280,7 +1456,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_send_plogiacc(rport, NULL);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
case RPSM_EVENT_LOGO_RCVD:
|
||||
case RPSM_EVENT_PRLO_RCVD:
|
||||
case RPSM_EVENT_PLOGI_SEND:
|
||||
@ -1326,7 +1502,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
|
||||
bfa_fcs_rport_send_nsdisc(rport, NULL);
|
||||
break;
|
||||
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
case RPSM_EVENT_ADDRESS_CHANGE:
|
||||
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
|
||||
bfa_timer_stop(&rport->timer);
|
||||
@ -1439,7 +1615,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
|
||||
case RPSM_EVENT_PRLO_RCVD:
|
||||
bfa_fcs_rport_send_prlo_acc(rport);
|
||||
break;
|
||||
case RPSM_EVENT_SCN:
|
||||
case RPSM_EVENT_FAB_SCN:
|
||||
/*
|
||||
* ignore, wait for NS query response
|
||||
*/
|
||||
@ -2546,7 +2722,7 @@ void
|
||||
bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
|
||||
{
|
||||
rport->stats.rscns++;
|
||||
bfa_sm_send_event(rport, RPSM_EVENT_SCN);
|
||||
bfa_sm_send_event(rport, RPSM_EVENT_FAB_SCN);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2621,6 +2797,48 @@ bfa_cb_rport_qos_scn_flowid(void *cbarg,
|
||||
bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
|
||||
}
|
||||
|
||||
void
|
||||
bfa_cb_rport_scn_online(struct bfa_s *bfa)
|
||||
{
|
||||
struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
|
||||
struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
|
||||
struct bfa_fcs_rport_s *rp;
|
||||
struct list_head *qe;
|
||||
|
||||
list_for_each(qe, &port->rport_q) {
|
||||
rp = (struct bfa_fcs_rport_s *) qe;
|
||||
bfa_sm_send_event(rp, RPSM_EVENT_SCN_ONLINE);
|
||||
rp->scn_online = BFA_TRUE;
|
||||
}
|
||||
|
||||
if (bfa_fcs_lport_is_online(port))
|
||||
bfa_fcs_lport_lip_scn_online(port);
|
||||
}
|
||||
|
||||
void
|
||||
bfa_cb_rport_scn_no_dev(void *rport)
|
||||
{
|
||||
struct bfa_fcs_rport_s *rp = rport;
|
||||
|
||||
bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
|
||||
rp->scn_online = BFA_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
bfa_cb_rport_scn_offline(struct bfa_s *bfa)
|
||||
{
|
||||
struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
|
||||
struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
|
||||
struct bfa_fcs_rport_s *rp;
|
||||
struct list_head *qe;
|
||||
|
||||
list_for_each(qe, &port->rport_q) {
|
||||
rp = (struct bfa_fcs_rport_s *) qe;
|
||||
bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
|
||||
rp->scn_online = BFA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* brief
|
||||
* This routine is a static BFA callback when there is a QoS priority
|
||||
|
@ -1244,6 +1244,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
|
||||
* Just ignore
|
||||
*/
|
||||
break;
|
||||
case BFA_LPS_SM_SET_N2N_PID:
|
||||
/*
|
||||
* When topology is set to loop, bfa_lps_set_n2n_pid() sends
|
||||
* this event. Ignore this event.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
bfa_sm_fault(lps->bfa, event);
|
||||
@ -1261,6 +1267,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
|
||||
|
||||
switch (event) {
|
||||
case BFA_LPS_SM_FWRSP:
|
||||
case BFA_LPS_SM_OFFLINE:
|
||||
if (lps->status == BFA_STATUS_OK) {
|
||||
bfa_sm_set_state(lps, bfa_lps_sm_online);
|
||||
if (lps->fdisc)
|
||||
@ -1289,7 +1296,6 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
|
||||
bfa_lps_login_comp(lps);
|
||||
break;
|
||||
|
||||
case BFA_LPS_SM_OFFLINE:
|
||||
case BFA_LPS_SM_DELETE:
|
||||
bfa_sm_set_state(lps, bfa_lps_sm_init);
|
||||
break;
|
||||
@ -2250,11 +2256,11 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
|
||||
if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
|
||||
|
||||
bfa_trc(fcport->bfa,
|
||||
pevent->link_state.vc_fcf.fcf.fipenabled);
|
||||
pevent->link_state.attr.vc_fcf.fcf.fipenabled);
|
||||
bfa_trc(fcport->bfa,
|
||||
pevent->link_state.vc_fcf.fcf.fipfailed);
|
||||
pevent->link_state.attr.vc_fcf.fcf.fipfailed);
|
||||
|
||||
if (pevent->link_state.vc_fcf.fcf.fipfailed)
|
||||
if (pevent->link_state.attr.vc_fcf.fcf.fipfailed)
|
||||
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
|
||||
BFA_PL_EID_FIP_FCF_DISC, 0,
|
||||
"FIP FCF Discovery Failed");
|
||||
@ -2996,6 +3002,21 @@ bfa_fcport_iocdisable(struct bfa_s *bfa)
|
||||
bfa_trunk_iocdisable(bfa);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update loop info in fcport for SCN online
|
||||
*/
|
||||
static void
|
||||
bfa_fcport_update_loop_info(struct bfa_fcport_s *fcport,
|
||||
struct bfa_fcport_loop_info_s *loop_info)
|
||||
{
|
||||
fcport->myalpa = loop_info->myalpa;
|
||||
fcport->alpabm_valid =
|
||||
loop_info->alpabm_val;
|
||||
memcpy(fcport->alpabm.alpa_bm,
|
||||
loop_info->alpabm.alpa_bm,
|
||||
sizeof(struct fc_alpabm_s));
|
||||
}
|
||||
|
||||
static void
|
||||
bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
|
||||
{
|
||||
@ -3005,12 +3026,15 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
|
||||
fcport->speed = pevent->link_state.speed;
|
||||
fcport->topology = pevent->link_state.topology;
|
||||
|
||||
if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)
|
||||
fcport->myalpa = 0;
|
||||
if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) {
|
||||
bfa_fcport_update_loop_info(fcport,
|
||||
&pevent->link_state.attr.loop_info);
|
||||
return;
|
||||
}
|
||||
|
||||
/* QoS Details */
|
||||
fcport->qos_attr = pevent->link_state.qos_attr;
|
||||
fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr;
|
||||
fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr;
|
||||
|
||||
/*
|
||||
* update trunk state if applicable
|
||||
@ -3019,7 +3043,8 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
|
||||
trunk->attr.state = BFA_TRUNK_DISABLED;
|
||||
|
||||
/* update FCoE specific */
|
||||
fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan);
|
||||
fcport->fcoe_vlan =
|
||||
be16_to_cpu(pevent->link_state.attr.vc_fcf.fcf.vlan);
|
||||
|
||||
bfa_trc(fcport->bfa, fcport->speed);
|
||||
bfa_trc(fcport->bfa, fcport->topology);
|
||||
@ -3609,6 +3634,9 @@ bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
|
||||
|
||||
if (fcport->cfg.trunked == BFA_TRUE)
|
||||
return BFA_STATUS_TRUNK_ENABLED;
|
||||
if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
|
||||
(speed == BFA_PORT_SPEED_16GBPS))
|
||||
return BFA_STATUS_UNSUPP_SPEED;
|
||||
if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
|
||||
bfa_trc(bfa, fcport->speed_sup);
|
||||
return BFA_STATUS_UNSUPP_SPEED;
|
||||
@ -3663,7 +3691,24 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology)
|
||||
|
||||
switch (topology) {
|
||||
case BFA_PORT_TOPOLOGY_P2P:
|
||||
break;
|
||||
|
||||
case BFA_PORT_TOPOLOGY_LOOP:
|
||||
if ((bfa_fcport_is_qos_enabled(bfa) != BFA_FALSE) ||
|
||||
(fcport->qos_attr.state != BFA_QOS_DISABLED))
|
||||
return BFA_STATUS_ERROR_QOS_ENABLED;
|
||||
if (fcport->cfg.ratelimit != BFA_FALSE)
|
||||
return BFA_STATUS_ERROR_TRL_ENABLED;
|
||||
if ((bfa_fcport_is_trunk_enabled(bfa) != BFA_FALSE) ||
|
||||
(fcport->trunk.attr.state != BFA_TRUNK_DISABLED))
|
||||
return BFA_STATUS_ERROR_TRUNK_ENABLED;
|
||||
if ((bfa_fcport_get_speed(bfa) == BFA_PORT_SPEED_16GBPS) ||
|
||||
(fcport->cfg.speed == BFA_PORT_SPEED_16GBPS))
|
||||
return BFA_STATUS_UNSUPP_SPEED;
|
||||
if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type))
|
||||
return BFA_STATUS_LOOP_UNSUPP_MEZZ;
|
||||
break;
|
||||
|
||||
case BFA_PORT_TOPOLOGY_AUTO:
|
||||
break;
|
||||
|
||||
@ -3686,6 +3731,17 @@ bfa_fcport_get_topology(struct bfa_s *bfa)
|
||||
return fcport->topology;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config topology.
|
||||
*/
|
||||
enum bfa_port_topology
|
||||
bfa_fcport_get_cfg_topology(struct bfa_s *bfa)
|
||||
{
|
||||
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
|
||||
|
||||
return fcport->cfg.topology;
|
||||
}
|
||||
|
||||
bfa_status_t
|
||||
bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
|
||||
{
|
||||
@ -3761,9 +3817,11 @@ bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
|
||||
u8
|
||||
bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
|
||||
{
|
||||
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
|
||||
if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP)
|
||||
return (BFA_FCPORT_MOD(bfa))->cfg.rx_bbcredit;
|
||||
|
||||
return fcport->cfg.rx_bbcredit;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -4707,6 +4765,21 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
|
||||
bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN);
|
||||
break;
|
||||
|
||||
case BFI_RPORT_I2H_LIP_SCN_ONLINE:
|
||||
bfa_fcport_update_loop_info(BFA_FCPORT_MOD(bfa),
|
||||
&msg.lip_scn->loop_info);
|
||||
bfa_cb_rport_scn_online(bfa);
|
||||
break;
|
||||
|
||||
case BFI_RPORT_I2H_LIP_SCN_OFFLINE:
|
||||
bfa_cb_rport_scn_offline(bfa);
|
||||
break;
|
||||
|
||||
case BFI_RPORT_I2H_NO_DEV:
|
||||
rp = BFA_RPORT_FROM_TAG(bfa, msg.lip_scn->bfa_handle);
|
||||
bfa_cb_rport_scn_no_dev(rp->rport_drv);
|
||||
break;
|
||||
|
||||
default:
|
||||
bfa_trc(bfa, m->mhdr.msg_id);
|
||||
WARN_ON(1);
|
||||
|
@ -474,8 +474,10 @@ struct bfa_fcport_s {
|
||||
/* supported speeds */
|
||||
enum bfa_port_speed speed; /* current speed */
|
||||
enum bfa_port_topology topology; /* current topology */
|
||||
u8 myalpa; /* my ALPA in LOOP topology */
|
||||
u8 rsvd[3];
|
||||
u8 myalpa; /* my ALPA in LOOP topology */
|
||||
u8 alpabm_valid; /* alpa bitmap valid or not */
|
||||
struct fc_alpabm_s alpabm; /* alpa bitmap */
|
||||
struct bfa_port_cfg_s cfg; /* current port configuration */
|
||||
bfa_boolean_t use_flash_cfg; /* get port cfg from flash */
|
||||
struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
|
||||
@ -534,6 +536,7 @@ enum bfa_port_speed bfa_fcport_get_speed(struct bfa_s *bfa);
|
||||
bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa,
|
||||
enum bfa_port_topology topo);
|
||||
enum bfa_port_topology bfa_fcport_get_topology(struct bfa_s *bfa);
|
||||
enum bfa_port_topology bfa_fcport_get_cfg_topology(struct bfa_s *bfa);
|
||||
bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
|
||||
bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
|
||||
u8 bfa_fcport_get_myalpa(struct bfa_s *bfa);
|
||||
@ -575,6 +578,9 @@ void bfa_cb_rport_offline(void *rport);
|
||||
void bfa_cb_rport_qos_scn_flowid(void *rport,
|
||||
struct bfa_rport_qos_attr_s old_qos_attr,
|
||||
struct bfa_rport_qos_attr_s new_qos_attr);
|
||||
void bfa_cb_rport_scn_online(struct bfa_s *bfa);
|
||||
void bfa_cb_rport_scn_offline(struct bfa_s *bfa);
|
||||
void bfa_cb_rport_scn_no_dev(void *rp);
|
||||
void bfa_cb_rport_qos_scn_prio(void *rport,
|
||||
struct bfa_rport_qos_attr_s old_qos_attr,
|
||||
struct bfa_rport_qos_attr_s new_qos_attr);
|
||||
|
@ -888,16 +888,22 @@ bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
|
||||
|
||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||
|
||||
if (cmd == IOCMD_RATELIM_ENABLE)
|
||||
fcport->cfg.ratelimit = BFA_TRUE;
|
||||
else if (cmd == IOCMD_RATELIM_DISABLE)
|
||||
fcport->cfg.ratelimit = BFA_FALSE;
|
||||
if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
|
||||
(fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
|
||||
iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
|
||||
else {
|
||||
if (cmd == IOCMD_RATELIM_ENABLE)
|
||||
fcport->cfg.ratelimit = BFA_TRUE;
|
||||
else if (cmd == IOCMD_RATELIM_DISABLE)
|
||||
fcport->cfg.ratelimit = BFA_FALSE;
|
||||
|
||||
if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN)
|
||||
fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS;
|
||||
if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN)
|
||||
fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS;
|
||||
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -919,8 +925,13 @@ bfad_iocmd_ratelim_speed(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fcport->cfg.trl_def_speed = iocmd->speed;
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
|
||||
(fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
|
||||
iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
|
||||
else {
|
||||
fcport->cfg.trl_def_speed = iocmd->speed;
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
}
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
|
||||
return 0;
|
||||
@ -2161,22 +2172,28 @@ bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
|
||||
|
||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||
|
||||
if (v_cmd == IOCMD_TRUNK_ENABLE) {
|
||||
trunk->attr.state = BFA_TRUNK_OFFLINE;
|
||||
bfa_fcport_disable(&bfad->bfa);
|
||||
fcport->cfg.trunked = BFA_TRUE;
|
||||
} else if (v_cmd == IOCMD_TRUNK_DISABLE) {
|
||||
trunk->attr.state = BFA_TRUNK_DISABLED;
|
||||
bfa_fcport_disable(&bfad->bfa);
|
||||
fcport->cfg.trunked = BFA_FALSE;
|
||||
}
|
||||
if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) ||
|
||||
(fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
|
||||
iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
|
||||
else {
|
||||
if (v_cmd == IOCMD_TRUNK_ENABLE) {
|
||||
trunk->attr.state = BFA_TRUNK_OFFLINE;
|
||||
bfa_fcport_disable(&bfad->bfa);
|
||||
fcport->cfg.trunked = BFA_TRUE;
|
||||
} else if (v_cmd == IOCMD_TRUNK_DISABLE) {
|
||||
trunk->attr.state = BFA_TRUNK_DISABLED;
|
||||
bfa_fcport_disable(&bfad->bfa);
|
||||
fcport->cfg.trunked = BFA_FALSE;
|
||||
}
|
||||
|
||||
if (!bfa_fcport_is_disabled(&bfad->bfa))
|
||||
bfa_fcport_enable(&bfad->bfa);
|
||||
if (!bfa_fcport_is_disabled(&bfad->bfa))
|
||||
bfa_fcport_enable(&bfad->bfa);
|
||||
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2189,12 +2206,17 @@ bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||
memcpy((void *)&iocmd->attr, (void *)&trunk->attr,
|
||||
sizeof(struct bfa_trunk_attr_s));
|
||||
iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa);
|
||||
if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) ||
|
||||
(fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
|
||||
iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
|
||||
else {
|
||||
memcpy((void *)&iocmd->attr, (void *)&trunk->attr,
|
||||
sizeof(struct bfa_trunk_attr_s));
|
||||
iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa);
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
}
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2207,14 +2229,18 @@ bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
|
||||
|
||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||
if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) {
|
||||
if (v_cmd == IOCMD_QOS_ENABLE)
|
||||
fcport->cfg.qos_enabled = BFA_TRUE;
|
||||
else if (v_cmd == IOCMD_QOS_DISABLE)
|
||||
fcport->cfg.qos_enabled = BFA_FALSE;
|
||||
if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
|
||||
(fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
|
||||
iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
|
||||
else {
|
||||
if (v_cmd == IOCMD_QOS_ENABLE)
|
||||
fcport->cfg.qos_enabled = BFA_TRUE;
|
||||
else if (v_cmd == IOCMD_QOS_DISABLE)
|
||||
fcport->cfg.qos_enabled = BFA_FALSE;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2226,11 +2252,17 @@ bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||
iocmd->attr.state = fcport->qos_attr.state;
|
||||
iocmd->attr.total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr);
|
||||
if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
|
||||
(fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
|
||||
iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
|
||||
else {
|
||||
iocmd->attr.state = fcport->qos_attr.state;
|
||||
iocmd->attr.total_bb_cr =
|
||||
be32_to_cpu(fcport->qos_attr.total_bb_cr);
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
}
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
|
||||
iocmd->status = BFA_STATUS_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2274,6 +2306,7 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
|
||||
struct bfad_hal_comp fcomp;
|
||||
unsigned long flags;
|
||||
struct bfa_cb_pending_q_s cb_qe;
|
||||
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
|
||||
|
||||
init_completion(&fcomp.comp);
|
||||
bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
|
||||
@ -2281,7 +2314,11 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
|
||||
|
||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||
WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
|
||||
iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
|
||||
if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
|
||||
(fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
|
||||
iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
|
||||
else
|
||||
iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
if (iocmd->status != BFA_STATUS_OK) {
|
||||
bfa_trc(bfad, iocmd->status);
|
||||
@ -2300,6 +2337,7 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
|
||||
struct bfad_hal_comp fcomp;
|
||||
unsigned long flags;
|
||||
struct bfa_cb_pending_q_s cb_qe;
|
||||
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
|
||||
|
||||
init_completion(&fcomp.comp);
|
||||
bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
|
||||
@ -2307,7 +2345,11 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
|
||||
|
||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||
WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
|
||||
iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe);
|
||||
if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
|
||||
(fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
|
||||
iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
|
||||
else
|
||||
iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe);
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
if (iocmd->status != BFA_STATUS_OK) {
|
||||
bfa_trc(bfad, iocmd->status);
|
||||
|
@ -499,6 +499,9 @@ enum bfi_rport_i2h_msgs {
|
||||
BFI_RPORT_I2H_CREATE_RSP = BFA_I2HM(1),
|
||||
BFI_RPORT_I2H_DELETE_RSP = BFA_I2HM(2),
|
||||
BFI_RPORT_I2H_QOS_SCN = BFA_I2HM(3),
|
||||
BFI_RPORT_I2H_LIP_SCN_ONLINE = BFA_I2HM(4),
|
||||
BFI_RPORT_I2H_LIP_SCN_OFFLINE = BFA_I2HM(5),
|
||||
BFI_RPORT_I2H_NO_DEV = BFA_I2HM(6),
|
||||
};
|
||||
|
||||
struct bfi_rport_create_req_s {
|
||||
@ -551,6 +554,14 @@ struct bfi_rport_qos_scn_s {
|
||||
struct bfa_rport_qos_attr_s new_qos_attr; /* New QoS Attributes */
|
||||
};
|
||||
|
||||
struct bfi_rport_lip_scn_s {
|
||||
struct bfi_mhdr_s mh; /*!< common msg header */
|
||||
u16 bfa_handle; /*!< host rport handle */
|
||||
u8 status; /*!< scn online status */
|
||||
u8 rsvd;
|
||||
struct bfa_fcport_loop_info_s loop_info;
|
||||
};
|
||||
|
||||
union bfi_rport_h2i_msg_u {
|
||||
struct bfi_msg_s *msg;
|
||||
struct bfi_rport_create_req_s *create_req;
|
||||
@ -563,6 +574,7 @@ union bfi_rport_i2h_msg_u {
|
||||
struct bfi_rport_create_rsp_s *create_rsp;
|
||||
struct bfi_rport_delete_rsp_s *delete_rsp;
|
||||
struct bfi_rport_qos_scn_s *qos_scn_evt;
|
||||
struct bfi_rport_lip_scn_s *lip_scn;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user