diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-24 20:24:52 -0700 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 17:12:11 -0500 |
commit | d7be54cc5c5f6f9cb9ac67462aadda57813698b8 (patch) | |
tree | 2f77812fe06a7ed59172a51f11166aadd6a262d8 | |
parent | 4507025d01149aea8705e43508d0ef11e7010cfd (diff) | |
download | linux-d7be54cc5c5f6f9cb9ac67462aadda57813698b8.tar.bz2 |
[SCSI] bfa: FCS bug fixes.
- Added logic to initiate a PLOGI to the target, while processing a LOGO
from the same target in Direct attach mode.
- Added logic to generate a FCCT Reject indicating unsupported command,
upon receiving FCCT/FCGS requests.
- Added logic to set the fcpim in offline state and avoid any PRLI retries
if a PRLI response is a reject with a reason Command Not Supported.
- Updated the FDMI Supported/Current speeds.
- Added logic to wait for the response from the firmware before sending
ACC to PLOGI and transitioning to subsequent states - while processing an
Incoming PLOGI in online state.
- Added a wait state in the fcs_vport state machine - For case where
FDISC is in progress and we get a vport delete request we wait for
fdisc response and will transition to the appropriate state based on
rsp status, else its causing both driver/fw resources to be not
freed.
- Remove the fc_credit_recovery module param.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/bfa/bfa_defs_fcs.h | 25 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_defs_svc.h | 10 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcbuild.c | 31 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcbuild.h | 4 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs.c | 20 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs.h | 20 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs_fcpim.c | 10 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs_lport.c | 170 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs_rport.c | 45 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.c | 2 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad.c | 5 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_drv.h | 1 |
12 files changed, 288 insertions, 55 deletions
diff --git a/drivers/scsi/bfa/bfa_defs_fcs.h b/drivers/scsi/bfa/bfa_defs_fcs.h index 191d34a58b9c..5e95976d81b8 100644 --- a/drivers/scsi/bfa/bfa_defs_fcs.h +++ b/drivers/scsi/bfa/bfa_defs_fcs.h @@ -90,12 +90,12 @@ enum bfa_lport_role { * FCS port configuration. */ struct bfa_lport_cfg_s { - wwn_t pwwn; /* port wwn */ - wwn_t nwwn; /* node wwn */ - struct bfa_lport_symname_s sym_name; /* vm port symbolic name */ - bfa_boolean_t preboot_vp; /* vport created from PBC */ - enum bfa_lport_role roles; /* FCS port roles */ - u8 tag[16]; /* opaque tag from application */ + wwn_t pwwn; /* port wwn */ + wwn_t nwwn; /* node wwn */ + struct bfa_lport_symname_s sym_name; /* vm port symbolic name */ + bfa_boolean_t preboot_vp; /* vport created from PBC */ + enum bfa_lport_role roles; /* FCS port roles */ + u8 tag[16]; /* opaque tag from application */ }; /* @@ -249,12 +249,13 @@ enum bfa_vport_state { BFA_FCS_VPORT_FDISC_SEND = 2, BFA_FCS_VPORT_FDISC = 3, BFA_FCS_VPORT_FDISC_RETRY = 4, - BFA_FCS_VPORT_ONLINE = 5, - BFA_FCS_VPORT_DELETING = 6, - BFA_FCS_VPORT_CLEANUP = 6, - BFA_FCS_VPORT_LOGO_SEND = 7, - BFA_FCS_VPORT_LOGO = 8, - BFA_FCS_VPORT_ERROR = 9, + BFA_FCS_VPORT_FDISC_RSP_WAIT = 5, + BFA_FCS_VPORT_ONLINE = 6, + BFA_FCS_VPORT_DELETING = 7, + BFA_FCS_VPORT_CLEANUP = 8, + BFA_FCS_VPORT_LOGO_SEND = 9, + BFA_FCS_VPORT_LOGO = 10, + BFA_FCS_VPORT_ERROR = 11, BFA_FCS_VPORT_MAX_STATE, }; diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index d8861872ac70..7f3584380a42 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h @@ -748,9 +748,10 @@ struct bfa_port_cfg_s { u8 tx_bbcredit; /* transmit buffer credits */ u8 ratelimit; /* ratelimit enabled or not */ u8 trl_def_speed; /* ratelimit default speed */ - u8 bb_scn; + 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[2]; + u8 rsvd[1]; u16 path_tov; /* device path timeout */ u16 q_depth; /* SCSI Queue depth */ }; @@ -786,7 +787,6 @@ struct bfa_port_attr_s { enum bfa_port_topology topology; /* current topology */ bfa_boolean_t beacon; /* current beacon status */ bfa_boolean_t link_e2e_beacon; /* link beacon is on */ - bfa_boolean_t plog_enabled; /* portlog is enabled */ bfa_boolean_t bbsc_op_status; /* fc credit recovery oper state */ /* @@ -796,12 +796,10 @@ struct bfa_port_attr_s { enum bfa_port_type port_type; /* current topology */ u32 loopback; /* external loopback */ u32 authfail; /* auth fail state */ - bfa_boolean_t io_profile; /* get it from fcpim mod */ - u8 pad[4]; /* for 64-bit alignement */ /* FCoE specific */ u16 fcoe_vlan; - u8 rsvd1[6]; + u8 rsvd1[2]; }; /* diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c index 08fba370cf4f..17b59b8b5644 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.c +++ b/drivers/scsi/bfa/bfa_fcbuild.c @@ -155,6 +155,22 @@ fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id) */ } +static void +fc_gsresp_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) +{ + memset(fchs, 0, sizeof(struct fchs_s)); + + fchs->routing = FC_RTG_FC4_DEV_DATA; + fchs->cat_info = FC_CAT_SOLICIT_CTRL; + fchs->type = FC_TYPE_SERVICES; + fchs->f_ctl = + bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | + FCTL_END_SEQ | FCTL_SI_XFER); + fchs->d_id = d_id; + fchs->s_id = s_id; + fchs->ox_id = ox_id; +} + void fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) { @@ -1098,6 +1114,21 @@ fc_ct_rsp_parse(struct ct_hdr_s *cthdr) } u16 +fc_gs_rjt_build(struct fchs_s *fchs, struct ct_hdr_s *cthdr, + u32 d_id, u32 s_id, u16 ox_id, u8 reason_code, + u8 reason_code_expl) +{ + fc_gsresp_fchdr_build(fchs, d_id, s_id, ox_id); + + cthdr->cmd_rsp_code = cpu_to_be16(CT_RSP_REJECT); + cthdr->rev_id = CT_GS3_REVISION; + + cthdr->reason_code = reason_code; + cthdr->exp_code = reason_code_expl; + return sizeof(struct ct_hdr_s); +} + +u16 fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, u8 set_br_reg, u32 s_id, u16 ox_id) { diff --git a/drivers/scsi/bfa/bfa_fcbuild.h b/drivers/scsi/bfa/bfa_fcbuild.h index 9ba24c724f4c..42cd9d4da697 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.h +++ b/drivers/scsi/bfa/bfa_fcbuild.h @@ -183,6 +183,10 @@ u16 fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 fc_gpnid_build(struct fchs_s *fchs, void *pld, u32 s_id, u16 ox_id, u32 port_id); +u16 fc_gs_rjt_build(struct fchs_s *fchs, struct ct_hdr_s *cthdr, + u32 d_id, u32 s_id, u16 ox_id, + u8 reason_code, u8 reason_code_expl); + u16 fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, u8 set_br_reg, u32 s_id, u16 ox_id); diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 5bbb76b8e2ec..a9b22bc48bc3 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -192,11 +192,14 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs) #define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */ #define bfa_fcs_fabric_set_opertype(__fabric) do { \ - if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \ - == BFA_PORT_TOPOLOGY_P2P) \ + if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \ + == BFA_PORT_TOPOLOGY_P2P) { \ + if (fabric->fab_type == BFA_FCS_FABRIC_SWITCHED) \ (__fabric)->oper_type = BFA_PORT_TYPE_NPORT; \ else \ - (__fabric)->oper_type = BFA_PORT_TYPE_NLPORT; \ + (__fabric)->oper_type = BFA_PORT_TYPE_P2P; \ + } else \ + (__fabric)->oper_type = BFA_PORT_TYPE_NLPORT; \ } while (0) /* @@ -551,6 +554,9 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric, bfa_fcs_fabric_oper_bbscn(fabric)); break; + case BFA_FCS_FABRIC_SM_RETRY_OP: + break; + default: bfa_sm_fault(fabric->fcs, event); } @@ -827,6 +833,7 @@ bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status) */ fabric->bport.port_topo.pn2n.rem_port_wwn = fabric->lps->pr_pwwn; + fabric->fab_type = BFA_FCS_FABRIC_N2N; bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC); } @@ -917,8 +924,9 @@ static u8 bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric) { u8 pr_bbscn = fabric->lps->pr_bbscn; + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fabric->fcs->bfa); - if (!(fabric->fcs->bbscn_enabled && pr_bbscn)) + if (!(fcport->cfg.bb_scn_state && pr_bbscn)) return 0; /* return max of local/remote bb_scn values */ @@ -932,8 +940,10 @@ bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric) static bfa_boolean_t bfa_fcs_fabric_is_bbscn_enabled(struct bfa_fcs_fabric_s *fabric) { + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fabric->fcs->bfa); + if (bfa_ioc_get_fcmode(&fabric->fcs->bfa->ioc) && - fabric->fcs->bbscn_enabled && + fcport->cfg.bb_scn_state && !bfa_fcport_is_qos_enabled(fabric->fcs->bfa) && !bfa_fcport_is_trunk_enabled(fabric->fcs->bfa)) return BFA_TRUE; diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 5873d9942aa7..e32cb19e32c3 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -424,6 +424,7 @@ struct bfa_fcs_rport_s { enum fc_cos fc_cos; /* FC classes of service supp */ bfa_boolean_t cisc; /* CISC capable device */ bfa_boolean_t prlo; /* processing prlo or LOGO */ + bfa_boolean_t plogi_pending; /* Rx Plogi Pending */ wwn_t pwwn; /* port wwn of rport */ wwn_t nwwn; /* node wwn of rport */ struct bfa_rport_symname_s psym_name; /* port symbolic name */ @@ -595,10 +596,21 @@ void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim); void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs, u16 len); -#define BFA_FCS_FDMI_SUPORTED_SPEEDS (FDMI_TRANS_SPEED_1G | \ - FDMI_TRANS_SPEED_2G | \ - FDMI_TRANS_SPEED_4G | \ - FDMI_TRANS_SPEED_8G) +#define BFA_FCS_FDMI_SUPP_SPEEDS_4G (FDMI_TRANS_SPEED_1G | \ + FDMI_TRANS_SPEED_2G | \ + FDMI_TRANS_SPEED_4G) + +#define BFA_FCS_FDMI_SUPP_SPEEDS_8G (FDMI_TRANS_SPEED_1G | \ + FDMI_TRANS_SPEED_2G | \ + FDMI_TRANS_SPEED_4G | \ + FDMI_TRANS_SPEED_8G) + +#define BFA_FCS_FDMI_SUPP_SPEEDS_16G (FDMI_TRANS_SPEED_2G | \ + FDMI_TRANS_SPEED_4G | \ + FDMI_TRANS_SPEED_8G | \ + FDMI_TRANS_SPEED_16G) + +#define BFA_FCS_FDMI_SUPP_SPEEDS_10G FDMI_TRANS_SPEED_10G /* * HBA Attribute Block : BFA internal representation. Note : Some variable diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c index e7b49f4cb51f..29b4108be269 100644 --- a/drivers/scsi/bfa/bfa_fcs_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c @@ -54,6 +54,7 @@ enum bfa_fcs_itnim_event { BFA_FCS_ITNIM_SM_INITIATOR = 9, /* rport is initiator */ 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 */ }; static void bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim, @@ -178,6 +179,10 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim, BFA_FCS_RETRY_TIMEOUT); break; + case BFA_FCS_ITNIM_SM_RSP_NOT_SUPP: + bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); + break; + case BFA_FCS_ITNIM_SM_OFFLINE: bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); bfa_fcxp_discard(itnim->fcxp); @@ -447,6 +452,7 @@ bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, itnim->rport->scsi_function = BFA_RPORT_INITIATOR; itnim->stats.prli_rsp_acc++; + itnim->stats.initiator++; bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_OK); return; @@ -472,6 +478,10 @@ bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, bfa_trc(itnim->fcs, ls_rjt->reason_code_expl); itnim->stats.prli_rsp_rjt++; + if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) { + bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_NOT_SUPP); + return; + } bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR); } } diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 942443e711e5..f8251a91ba91 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -328,6 +328,40 @@ bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, } /* + * Send a FCCT Reject + */ +static void +bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port, + struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl) +{ + struct fchs_s fchs; + struct bfa_fcxp_s *fcxp; + struct bfa_rport_s *bfa_rport = NULL; + int len; + struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1); + struct ct_hdr_s *ct_hdr; + + bfa_trc(port->fcs, rx_fchs->d_id); + bfa_trc(port->fcs, rx_fchs->s_id); + + fcxp = bfa_fcs_fcxp_alloc(port->fcs); + if (!fcxp) + return; + + ct_hdr = bfa_fcxp_get_reqbuf(fcxp); + ct_hdr->gs_type = rx_cthdr->gs_type; + ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type; + + len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id, + bfa_fcs_lport_get_fcid(port), + rx_fchs->ox_id, reason_code, reason_code_expl); + + bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, + BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, + FC_MAX_PDUSZ, 0); +} + +/* * Process incoming plogi from a remote port. */ static void @@ -710,6 +744,16 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport, bfa_fcs_lport_abts_acc(lport, fchs); return; } + + if (fchs->type == FC_TYPE_SERVICES) { + /* + * Unhandled FC-GS frames. Send a FC-CT Reject + */ + bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP, + CT_NS_EXP_NOADDITIONAL); + return; + } + /* * look for a matching remote port ID */ @@ -1137,6 +1181,8 @@ static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, struct bfa_fcs_fdmi_hba_attr_s *hba_attr); static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, struct bfa_fcs_fdmi_port_attr_s *port_attr); +u32 bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed); + /* * fcs_fdmi_sm FCS FDMI state machine */ @@ -2223,12 +2269,36 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, /* * Supported Speeds */ - port_attr->supp_speed = cpu_to_be32(BFA_FCS_FDMI_SUPORTED_SPEEDS); + switch (pport_attr.speed_supported) { + case BFA_PORT_SPEED_16GBPS: + port_attr->supp_speed = + cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G); + break; + + case BFA_PORT_SPEED_10GBPS: + port_attr->supp_speed = + cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G); + break; + + case BFA_PORT_SPEED_8GBPS: + port_attr->supp_speed = + cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G); + break; + + case BFA_PORT_SPEED_4GBPS: + port_attr->supp_speed = + cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G); + break; + + default: + bfa_sm_fault(port->fcs, pport_attr.speed_supported); + } /* * Current Speed */ - port_attr->curr_speed = cpu_to_be32(pport_attr.speed); + port_attr->curr_speed = cpu_to_be32( + bfa_fcs_fdmi_convert_speed(pport_attr.speed)); /* * Max PDU Size. @@ -2249,6 +2319,41 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, } +/* + * Convert BFA speed to FDMI format. + */ +u32 +bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed) +{ + u32 ret; + + switch (pport_speed) { + case BFA_PORT_SPEED_1GBPS: + case BFA_PORT_SPEED_2GBPS: + ret = pport_speed; + break; + + case BFA_PORT_SPEED_4GBPS: + ret = FDMI_TRANS_SPEED_4G; + break; + + case BFA_PORT_SPEED_8GBPS: + ret = FDMI_TRANS_SPEED_8G; + break; + + case BFA_PORT_SPEED_10GBPS: + ret = FDMI_TRANS_SPEED_10G; + break; + + case BFA_PORT_SPEED_16GBPS: + ret = FDMI_TRANS_SPEED_16G; + break; + + default: + ret = FDMI_TRANS_SPEED_UNKNOWN; + } + return ret; +} void bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms) @@ -4827,8 +4932,8 @@ bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port) while (qe != qh) { rport = (struct bfa_fcs_rport_s *) qe; if ((bfa_ntoh3b(rport->pid) > 0xFFF000) || - (bfa_fcs_rport_get_state(rport) == - BFA_RPORT_OFFLINE)) { + (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) || + (rport->scsi_function != BFA_RPORT_TARGET)) { qe = bfa_q_next(qe); continue; } @@ -4841,17 +4946,15 @@ bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port) bfa_fcport_get_ratelim_speed(port->fcs->bfa); } - if ((rport_speed == BFA_PORT_SPEED_8GBPS) || - (rport_speed > port_speed)) { - max_speed = rport_speed; - break; - } else if (rport_speed > max_speed) { + if (rport_speed > max_speed) max_speed = rport_speed; - } qe = bfa_q_next(qe); } + if (max_speed > port_speed) + max_speed = port_speed; + bfa_trc(fcs, max_speed); return max_speed; } @@ -4996,6 +5099,8 @@ static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, enum bfa_fcs_vport_event event); static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, enum bfa_fcs_vport_event event); +static void bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, + enum bfa_fcs_vport_event event); static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, enum bfa_fcs_vport_event event); static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, @@ -5017,6 +5122,7 @@ static struct bfa_sm_table_s vport_sm_table[] = { {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE}, {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC}, {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY}, + {BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT}, {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE}, {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING}, {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP}, @@ -5145,9 +5251,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, switch (event) { case BFA_FCS_VPORT_SM_DELETE: - bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); - bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); - bfa_fcs_lport_delete(&vport->lport); + bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait); break; case BFA_FCS_VPORT_SM_OFFLINE: @@ -5215,6 +5319,41 @@ bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, } /* + * FDISC is in progress and we got a vport delete request - + * this is a wait state while we wait for fdisc response and + * we will transition to the appropriate state - on rsp status. + */ +static void +bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, + enum bfa_fcs_vport_event event) +{ + bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); + bfa_trc(__vport_fcs(vport), event); + + switch (event) { + case BFA_FCS_VPORT_SM_RSP_OK: + bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); + bfa_fcs_lport_delete(&vport->lport); + break; + + case BFA_FCS_VPORT_SM_DELETE: + break; + + case BFA_FCS_VPORT_SM_OFFLINE: + case BFA_FCS_VPORT_SM_RSP_ERROR: + case BFA_FCS_VPORT_SM_RSP_FAILED: + case BFA_FCS_VPORT_SM_RSP_DUP_WWN: + bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); + bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); + bfa_fcs_lport_delete(&vport->lport); + break; + + default: + bfa_sm_fault(__vport_fcs(vport), event); + } +} + +/* * Vport is online (FDISC is complete). */ static void @@ -5529,7 +5668,10 @@ void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport) { vport->vport_stats.fab_online++; - bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); + if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); + else + vport->vport_stats.fab_no_npiv++; } /* diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 2ec5719b654d..a42949d045eb 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c @@ -262,6 +262,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, break; case RPSM_EVENT_PLOGI_RCVD: + case RPSM_EVENT_PLOGI_COMP: case RPSM_EVENT_SCN: /* * Ignore, SCN is possibly online notification. @@ -470,6 +471,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, break; case RPSM_EVENT_PRLO_RCVD: + case RPSM_EVENT_PLOGI_COMP: break; case RPSM_EVENT_LOGO_RCVD: @@ -484,9 +486,9 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, break; case RPSM_EVENT_PLOGI_RCVD: - bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); + rport->plogi_pending = BFA_TRUE; + bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); - bfa_fcs_rport_send_plogiacc(rport, NULL); break; case RPSM_EVENT_DELETE: @@ -891,6 +893,18 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, switch (event) { case RPSM_EVENT_HCB_OFFLINE: + if (bfa_fcs_lport_is_online(rport->port) && + (rport->plogi_pending)) { + rport->plogi_pending = BFA_FALSE; + bfa_sm_set_state(rport, + bfa_fcs_rport_sm_plogiacc_sending); + bfa_fcs_rport_send_plogiacc(rport, NULL); + break; + } + /* + * !! fall through !! + */ + case RPSM_EVENT_ADDRESS_CHANGE: if (bfa_fcs_lport_is_online(rport->port)) { if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { @@ -921,6 +935,8 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, case RPSM_EVENT_SCN: case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD: + case RPSM_EVENT_PLOGI_RCVD: + case RPSM_EVENT_LOGO_IMP: /* * Ignore, already offline. */ @@ -957,10 +973,18 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, */ if (bfa_fcs_lport_is_online(rport->port) && (!BFA_FCS_PID_IS_WKA(rport->pid))) { - bfa_sm_set_state(rport, - bfa_fcs_rport_sm_nsdisc_sending); - rport->ns_retries = 0; - bfa_fcs_rport_send_nsdisc(rport, NULL); + if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { + bfa_sm_set_state(rport, + bfa_fcs_rport_sm_nsdisc_sending); + rport->ns_retries = 0; + bfa_fcs_rport_send_nsdisc(rport, NULL); + } else { + /* For N2N Direct Attach, try to re-login */ + bfa_sm_set_state(rport, + bfa_fcs_rport_sm_plogi_sending); + rport->plogi_retries = 0; + bfa_fcs_rport_send_plogi(rport, NULL); + } } else { /* * if it is not a well known address, reset the @@ -2026,6 +2050,11 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport) rport->stats.onlines++; + if ((!rport->pid) || (!rport->pwwn)) { + bfa_trc(rport->fcs, rport->pid); + bfa_sm_fault(rport->fcs, rport->pid); + } + if (bfa_fcs_lport_is_initiator(port)) { bfa_fcs_itnim_rport_online(rport->itnim); if (!BFA_FCS_PID_IS_WKA(rport->pid)) @@ -2049,6 +2078,7 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport) char rpwwn_buf[BFA_STRING_32]; rport->stats.offlines++; + rport->plogi_pending = BFA_FALSE; wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); wwn2str(rpwwn_buf, rport->pwwn); @@ -2252,6 +2282,9 @@ bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, rport->reply_oxid = rx_fchs->ox_id; bfa_trc(rport->fcs, rport->reply_oxid); + rport->pid = rx_fchs->s_id; + bfa_trc(rport->fcs, rport->pid); + rport->stats.plogi_rcvd++; bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); } diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 4dcf9b9a34d0..d7853e698d01 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -3750,8 +3750,6 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr) /* beacon attributes */ attr->beacon = fcport->beacon; attr->link_e2e_beacon = fcport->link_e2e_beacon; - attr->plog_enabled = (bfa_boolean_t)fcport->bfa->plog->plog_enabled; - attr->io_profile = bfa_fcpim_get_io_profile(fcport->bfa); attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 872c9df590b9..0ed260852159 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -53,7 +53,6 @@ int bfa_log_level = 3; /* WARNING log level */ int ioc_auto_recover = BFA_TRUE; int bfa_linkup_delay = -1; int fdmi_enable = BFA_TRUE; -int fc_credit_recovery = BFA_TRUE; int pcie_max_read_reqsz; int bfa_debugfs_enable = 1; int msix_disable_cb = 0, msix_disable_ct = 0; @@ -139,9 +138,6 @@ MODULE_PARM_DESC(msix_disable_ct, "Disable Message Signaled Interrupts " module_param(fdmi_enable, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(fdmi_enable, "Enables fdmi registration, default=1, " "Range[false:0|true:1]"); -module_param(fc_credit_recovery, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(fc_credit_recovery, "Enables FC Credit Recovery, default=1, " - "Range[false:0|true:1]"); module_param(pcie_max_read_reqsz, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(pcie_max_read_reqsz, "PCIe max read request size, default=0 " "(use system setting), Range[128|256|512|1024|2048|4096]"); @@ -877,7 +873,6 @@ bfad_drv_init(struct bfad_s *bfad) bfad->bfa_fcs.trcmod = bfad->trcmod; bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); bfad->bfa_fcs.fdmi_enabled = fdmi_enable; - bfad->bfa_fcs.bbscn_enabled = fc_credit_recovery; bfa_fcs_init(&bfad->bfa_fcs); spin_unlock_irqrestore(&bfad->bfad_lock, flags); diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index e5163c7d3958..35bf0a630a68 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -340,7 +340,6 @@ extern int bfa_linkup_delay; extern int msix_disable_cb; extern int msix_disable_ct; extern int fdmi_enable; -extern int fc_credit_recovery; extern int supported_fc4s; extern int pcie_max_read_reqsz; extern int bfa_debugfs_enable; |