提交 d7be54cc 编写于 作者: K Krishna Gudipati 提交者: James Bottomley

[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: NKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: NJames Bottomley <JBottomley@Parallels.com>
上级 4507025d
...@@ -249,12 +249,13 @@ enum bfa_vport_state { ...@@ -249,12 +249,13 @@ enum bfa_vport_state {
BFA_FCS_VPORT_FDISC_SEND = 2, BFA_FCS_VPORT_FDISC_SEND = 2,
BFA_FCS_VPORT_FDISC = 3, BFA_FCS_VPORT_FDISC = 3,
BFA_FCS_VPORT_FDISC_RETRY = 4, BFA_FCS_VPORT_FDISC_RETRY = 4,
BFA_FCS_VPORT_ONLINE = 5, BFA_FCS_VPORT_FDISC_RSP_WAIT = 5,
BFA_FCS_VPORT_DELETING = 6, BFA_FCS_VPORT_ONLINE = 6,
BFA_FCS_VPORT_CLEANUP = 6, BFA_FCS_VPORT_DELETING = 7,
BFA_FCS_VPORT_LOGO_SEND = 7, BFA_FCS_VPORT_CLEANUP = 8,
BFA_FCS_VPORT_LOGO = 8, BFA_FCS_VPORT_LOGO_SEND = 9,
BFA_FCS_VPORT_ERROR = 9, BFA_FCS_VPORT_LOGO = 10,
BFA_FCS_VPORT_ERROR = 11,
BFA_FCS_VPORT_MAX_STATE, BFA_FCS_VPORT_MAX_STATE,
}; };
......
...@@ -748,9 +748,10 @@ struct bfa_port_cfg_s { ...@@ -748,9 +748,10 @@ struct bfa_port_cfg_s {
u8 tx_bbcredit; /* transmit buffer credits */ u8 tx_bbcredit; /* transmit buffer credits */
u8 ratelimit; /* ratelimit enabled or not */ u8 ratelimit; /* ratelimit enabled or not */
u8 trl_def_speed; /* ratelimit default speed */ 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 faa_state; /* FAA enabled/disabled */
u8 rsvd[2]; u8 rsvd[1];
u16 path_tov; /* device path timeout */ u16 path_tov; /* device path timeout */
u16 q_depth; /* SCSI Queue depth */ u16 q_depth; /* SCSI Queue depth */
}; };
...@@ -786,7 +787,6 @@ struct bfa_port_attr_s { ...@@ -786,7 +787,6 @@ struct bfa_port_attr_s {
enum bfa_port_topology topology; /* current topology */ enum bfa_port_topology topology; /* current topology */
bfa_boolean_t beacon; /* current beacon status */ bfa_boolean_t beacon; /* current beacon status */
bfa_boolean_t link_e2e_beacon; /* link beacon is on */ 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 */ bfa_boolean_t bbsc_op_status; /* fc credit recovery oper state */
/* /*
...@@ -796,12 +796,10 @@ struct bfa_port_attr_s { ...@@ -796,12 +796,10 @@ struct bfa_port_attr_s {
enum bfa_port_type port_type; /* current topology */ enum bfa_port_type port_type; /* current topology */
u32 loopback; /* external loopback */ u32 loopback; /* external loopback */
u32 authfail; /* auth fail state */ u32 authfail; /* auth fail state */
bfa_boolean_t io_profile; /* get it from fcpim mod */
u8 pad[4]; /* for 64-bit alignement */
/* FCoE specific */ /* FCoE specific */
u16 fcoe_vlan; u16 fcoe_vlan;
u8 rsvd1[6]; u8 rsvd1[2];
}; };
/* /*
......
...@@ -155,6 +155,22 @@ fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id) ...@@ -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 void
fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
{ {
...@@ -1097,6 +1113,21 @@ fc_ct_rsp_parse(struct ct_hdr_s *cthdr) ...@@ -1097,6 +1113,21 @@ fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
return FC_PARSE_OK; return FC_PARSE_OK;
} }
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 u16
fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
u8 set_br_reg, u32 s_id, u16 ox_id) u8 set_br_reg, u32 s_id, u16 ox_id)
......
...@@ -183,6 +183,10 @@ u16 fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, ...@@ -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 fc_gpnid_build(struct fchs_s *fchs, void *pld, u32 s_id,
u16 ox_id, u32 port_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, u16 fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
u8 set_br_reg, u32 s_id, u16 ox_id); u8 set_br_reg, u32 s_id, u16 ox_id);
......
...@@ -193,9 +193,12 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs) ...@@ -193,9 +193,12 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
#define bfa_fcs_fabric_set_opertype(__fabric) do { \ #define bfa_fcs_fabric_set_opertype(__fabric) do { \
if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \ if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \
== BFA_PORT_TOPOLOGY_P2P) \ == BFA_PORT_TOPOLOGY_P2P) { \
if (fabric->fab_type == BFA_FCS_FABRIC_SWITCHED) \
(__fabric)->oper_type = BFA_PORT_TYPE_NPORT; \ (__fabric)->oper_type = BFA_PORT_TYPE_NPORT; \
else \ else \
(__fabric)->oper_type = BFA_PORT_TYPE_P2P; \
} else \
(__fabric)->oper_type = BFA_PORT_TYPE_NLPORT; \ (__fabric)->oper_type = BFA_PORT_TYPE_NLPORT; \
} while (0) } while (0)
...@@ -551,6 +554,9 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric, ...@@ -551,6 +554,9 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
bfa_fcs_fabric_oper_bbscn(fabric)); bfa_fcs_fabric_oper_bbscn(fabric));
break; break;
case BFA_FCS_FABRIC_SM_RETRY_OP:
break;
default: default:
bfa_sm_fault(fabric->fcs, event); bfa_sm_fault(fabric->fcs, event);
} }
...@@ -827,6 +833,7 @@ bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status) ...@@ -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->bport.port_topo.pn2n.rem_port_wwn =
fabric->lps->pr_pwwn; fabric->lps->pr_pwwn;
fabric->fab_type = BFA_FCS_FABRIC_N2N;
bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC); bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
} }
...@@ -917,8 +924,9 @@ static u8 ...@@ -917,8 +924,9 @@ static u8
bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric) bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric)
{ {
u8 pr_bbscn = fabric->lps->pr_bbscn; 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 0;
/* return max of local/remote bb_scn values */ /* return max of local/remote bb_scn values */
...@@ -932,8 +940,10 @@ bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric) ...@@ -932,8 +940,10 @@ bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric)
static bfa_boolean_t static bfa_boolean_t
bfa_fcs_fabric_is_bbscn_enabled(struct bfa_fcs_fabric_s *fabric) 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) && 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_qos_enabled(fabric->fcs->bfa) &&
!bfa_fcport_is_trunk_enabled(fabric->fcs->bfa)) !bfa_fcport_is_trunk_enabled(fabric->fcs->bfa))
return BFA_TRUE; return BFA_TRUE;
......
...@@ -424,6 +424,7 @@ struct bfa_fcs_rport_s { ...@@ -424,6 +424,7 @@ struct bfa_fcs_rport_s {
enum fc_cos fc_cos; /* FC classes of service supp */ enum fc_cos fc_cos; /* FC classes of service supp */
bfa_boolean_t cisc; /* CISC capable device */ bfa_boolean_t cisc; /* CISC capable device */
bfa_boolean_t prlo; /* processing prlo or LOGO */ 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 pwwn; /* port wwn of rport */
wwn_t nwwn; /* node wwn of rport */ wwn_t nwwn; /* node wwn of rport */
struct bfa_rport_symname_s psym_name; /* port symbolic name */ struct bfa_rport_symname_s psym_name; /* port symbolic name */
...@@ -595,11 +596,22 @@ void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim); ...@@ -595,11 +596,22 @@ void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim);
void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim,
struct fchs_s *fchs, u16 len); struct fchs_s *fchs, u16 len);
#define BFA_FCS_FDMI_SUPORTED_SPEEDS (FDMI_TRANS_SPEED_1G | \ #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_2G | \
FDMI_TRANS_SPEED_4G | \ FDMI_TRANS_SPEED_4G | \
FDMI_TRANS_SPEED_8G) 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 * HBA Attribute Block : BFA internal representation. Note : Some variable
* sizes have been trimmed to suit BFA For Ex : Model will be "Brocade". Based * sizes have been trimmed to suit BFA For Ex : Model will be "Brocade". Based
......
...@@ -54,6 +54,7 @@ enum bfa_fcs_itnim_event { ...@@ -54,6 +54,7 @@ enum bfa_fcs_itnim_event {
BFA_FCS_ITNIM_SM_INITIATOR = 9, /* rport is initiator */ BFA_FCS_ITNIM_SM_INITIATOR = 9, /* rport is initiator */
BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */ BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */
BFA_FCS_ITNIM_SM_PRLO = 11, /* 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, 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, ...@@ -178,6 +179,10 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
BFA_FCS_RETRY_TIMEOUT); BFA_FCS_RETRY_TIMEOUT);
break; 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: case BFA_FCS_ITNIM_SM_OFFLINE:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
bfa_fcxp_discard(itnim->fcxp); bfa_fcxp_discard(itnim->fcxp);
...@@ -447,6 +452,7 @@ bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, ...@@ -447,6 +452,7 @@ bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
itnim->rport->scsi_function = itnim->rport->scsi_function =
BFA_RPORT_INITIATOR; BFA_RPORT_INITIATOR;
itnim->stats.prli_rsp_acc++; itnim->stats.prli_rsp_acc++;
itnim->stats.initiator++;
bfa_sm_send_event(itnim, bfa_sm_send_event(itnim,
BFA_FCS_ITNIM_SM_RSP_OK); BFA_FCS_ITNIM_SM_RSP_OK);
return; return;
...@@ -472,6 +478,10 @@ bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, ...@@ -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); bfa_trc(itnim->fcs, ls_rjt->reason_code_expl);
itnim->stats.prli_rsp_rjt++; 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); bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR);
} }
} }
......
...@@ -327,6 +327,40 @@ bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, ...@@ -327,6 +327,40 @@ bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
FC_MAX_PDUSZ, 0); FC_MAX_PDUSZ, 0);
} }
/*
* 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. * Process incoming plogi from a remote port.
*/ */
...@@ -710,6 +744,16 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport, ...@@ -710,6 +744,16 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
bfa_fcs_lport_abts_acc(lport, fchs); bfa_fcs_lport_abts_acc(lport, fchs);
return; 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 * 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, ...@@ -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); struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
struct bfa_fcs_fdmi_port_attr_s *port_attr); 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 * fcs_fdmi_sm FCS FDMI state machine
*/ */
...@@ -2223,12 +2269,36 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, ...@@ -2223,12 +2269,36 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
/* /*
* Supported Speeds * 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 * 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. * Max PDU Size.
...@@ -2249,6 +2319,41 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, ...@@ -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 void
bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms) 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) ...@@ -4827,8 +4932,8 @@ bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port)
while (qe != qh) { while (qe != qh) {
rport = (struct bfa_fcs_rport_s *) qe; rport = (struct bfa_fcs_rport_s *) qe;
if ((bfa_ntoh3b(rport->pid) > 0xFFF000) || if ((bfa_ntoh3b(rport->pid) > 0xFFF000) ||
(bfa_fcs_rport_get_state(rport) == (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) ||
BFA_RPORT_OFFLINE)) { (rport->scsi_function != BFA_RPORT_TARGET)) {
qe = bfa_q_next(qe); qe = bfa_q_next(qe);
continue; continue;
} }
...@@ -4841,17 +4946,15 @@ bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port) ...@@ -4841,17 +4946,15 @@ bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port)
bfa_fcport_get_ratelim_speed(port->fcs->bfa); bfa_fcport_get_ratelim_speed(port->fcs->bfa);
} }
if ((rport_speed == BFA_PORT_SPEED_8GBPS) || if (rport_speed > max_speed)
(rport_speed > port_speed)) {
max_speed = rport_speed;
break;
} else if (rport_speed > max_speed) {
max_speed = rport_speed; max_speed = rport_speed;
}
qe = bfa_q_next(qe); qe = bfa_q_next(qe);
} }
if (max_speed > port_speed)
max_speed = port_speed;
bfa_trc(fcs, max_speed); bfa_trc(fcs, max_speed);
return max_speed; return max_speed;
} }
...@@ -4996,6 +5099,8 @@ static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, ...@@ -4996,6 +5099,8 @@ static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
enum bfa_fcs_vport_event event); enum bfa_fcs_vport_event event);
static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
enum bfa_fcs_vport_event event); 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, static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
enum bfa_fcs_vport_event event); enum bfa_fcs_vport_event event);
static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 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[] = { ...@@ -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_offline), BFA_FCS_VPORT_OFFLINE},
{BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC}, {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_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_online), BFA_FCS_VPORT_ONLINE},
{BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING}, {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING},
{BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP}, {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, ...@@ -5145,9 +5251,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
switch (event) { switch (event) {
case BFA_FCS_VPORT_SM_DELETE: case BFA_FCS_VPORT_SM_DELETE:
bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait);
bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
bfa_fcs_lport_delete(&vport->lport);
break; break;
case BFA_FCS_VPORT_SM_OFFLINE: case BFA_FCS_VPORT_SM_OFFLINE:
...@@ -5214,6 +5318,41 @@ bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, ...@@ -5214,6 +5318,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). * Vport is online (FDISC is complete).
*/ */
...@@ -5529,7 +5668,10 @@ void ...@@ -5529,7 +5668,10 @@ void
bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport) bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport)
{ {
vport->vport_stats.fab_online++; vport->vport_stats.fab_online++;
if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport)))
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
else
vport->vport_stats.fab_no_npiv++;
} }
/* /*
......
...@@ -262,6 +262,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, ...@@ -262,6 +262,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
break; break;
case RPSM_EVENT_PLOGI_RCVD: case RPSM_EVENT_PLOGI_RCVD:
case RPSM_EVENT_PLOGI_COMP:
case RPSM_EVENT_SCN: case RPSM_EVENT_SCN:
/* /*
* Ignore, SCN is possibly online notification. * Ignore, SCN is possibly online notification.
...@@ -470,6 +471,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, ...@@ -470,6 +471,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
break; break;
case RPSM_EVENT_PRLO_RCVD: case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_PLOGI_COMP:
break; break;
case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_LOGO_RCVD:
...@@ -484,9 +486,9 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, ...@@ -484,9 +486,9 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
break; break;
case RPSM_EVENT_PLOGI_RCVD: 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_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
bfa_fcs_rport_send_plogiacc(rport, NULL);
break; break;
case RPSM_EVENT_DELETE: case RPSM_EVENT_DELETE:
...@@ -891,6 +893,18 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, ...@@ -891,6 +893,18 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
switch (event) { switch (event) {
case RPSM_EVENT_HCB_OFFLINE: 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: case RPSM_EVENT_ADDRESS_CHANGE:
if (bfa_fcs_lport_is_online(rport->port)) { if (bfa_fcs_lport_is_online(rport->port)) {
if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { 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, ...@@ -921,6 +935,8 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
case RPSM_EVENT_SCN: case RPSM_EVENT_SCN:
case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_LOGO_RCVD:
case RPSM_EVENT_PRLO_RCVD: case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_PLOGI_RCVD:
case RPSM_EVENT_LOGO_IMP:
/* /*
* Ignore, already offline. * Ignore, already offline.
*/ */
...@@ -957,10 +973,18 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, ...@@ -957,10 +973,18 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
*/ */
if (bfa_fcs_lport_is_online(rport->port) && if (bfa_fcs_lport_is_online(rport->port) &&
(!BFA_FCS_PID_IS_WKA(rport->pid))) { (!BFA_FCS_PID_IS_WKA(rport->pid))) {
if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
bfa_sm_set_state(rport, bfa_sm_set_state(rport,
bfa_fcs_rport_sm_nsdisc_sending); bfa_fcs_rport_sm_nsdisc_sending);
rport->ns_retries = 0; rport->ns_retries = 0;
bfa_fcs_rport_send_nsdisc(rport, NULL); 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 { } else {
/* /*
* if it is not a well known address, reset the * 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) ...@@ -2026,6 +2050,11 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
rport->stats.onlines++; 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)) { if (bfa_fcs_lport_is_initiator(port)) {
bfa_fcs_itnim_rport_online(rport->itnim); bfa_fcs_itnim_rport_online(rport->itnim);
if (!BFA_FCS_PID_IS_WKA(rport->pid)) if (!BFA_FCS_PID_IS_WKA(rport->pid))
...@@ -2049,6 +2078,7 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport) ...@@ -2049,6 +2078,7 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
char rpwwn_buf[BFA_STRING_32]; char rpwwn_buf[BFA_STRING_32];
rport->stats.offlines++; rport->stats.offlines++;
rport->plogi_pending = BFA_FALSE;
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
wwn2str(rpwwn_buf, rport->pwwn); wwn2str(rpwwn_buf, rport->pwwn);
...@@ -2252,6 +2282,9 @@ bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, ...@@ -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; rport->reply_oxid = rx_fchs->ox_id;
bfa_trc(rport->fcs, rport->reply_oxid); bfa_trc(rport->fcs, rport->reply_oxid);
rport->pid = rx_fchs->s_id;
bfa_trc(rport->fcs, rport->pid);
rport->stats.plogi_rcvd++; rport->stats.plogi_rcvd++;
bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
} }
......
...@@ -3750,8 +3750,6 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr) ...@@ -3750,8 +3750,6 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
/* beacon attributes */ /* beacon attributes */
attr->beacon = fcport->beacon; attr->beacon = fcport->beacon;
attr->link_e2e_beacon = fcport->link_e2e_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.path_tov = bfa_fcpim_path_tov_get(bfa);
attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
......
...@@ -53,7 +53,6 @@ int bfa_log_level = 3; /* WARNING log level */ ...@@ -53,7 +53,6 @@ int bfa_log_level = 3; /* WARNING log level */
int ioc_auto_recover = BFA_TRUE; int ioc_auto_recover = BFA_TRUE;
int bfa_linkup_delay = -1; int bfa_linkup_delay = -1;
int fdmi_enable = BFA_TRUE; int fdmi_enable = BFA_TRUE;
int fc_credit_recovery = BFA_TRUE;
int pcie_max_read_reqsz; int pcie_max_read_reqsz;
int bfa_debugfs_enable = 1; int bfa_debugfs_enable = 1;
int msix_disable_cb = 0, msix_disable_ct = 0; int msix_disable_cb = 0, msix_disable_ct = 0;
...@@ -139,9 +138,6 @@ MODULE_PARM_DESC(msix_disable_ct, "Disable Message Signaled Interrupts " ...@@ -139,9 +138,6 @@ MODULE_PARM_DESC(msix_disable_ct, "Disable Message Signaled Interrupts "
module_param(fdmi_enable, int, S_IRUGO | S_IWUSR); module_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(fdmi_enable, "Enables fdmi registration, default=1, " MODULE_PARM_DESC(fdmi_enable, "Enables fdmi registration, default=1, "
"Range[false:0|true: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_param(pcie_max_read_reqsz, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(pcie_max_read_reqsz, "PCIe max read request size, default=0 " MODULE_PARM_DESC(pcie_max_read_reqsz, "PCIe max read request size, default=0 "
"(use system setting), Range[128|256|512|1024|2048|4096]"); "(use system setting), Range[128|256|512|1024|2048|4096]");
...@@ -877,7 +873,6 @@ bfad_drv_init(struct bfad_s *bfad) ...@@ -877,7 +873,6 @@ bfad_drv_init(struct bfad_s *bfad)
bfad->bfa_fcs.trcmod = bfad->trcmod; bfad->bfa_fcs.trcmod = bfad->trcmod;
bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
bfad->bfa_fcs.fdmi_enabled = fdmi_enable; bfad->bfa_fcs.fdmi_enabled = fdmi_enable;
bfad->bfa_fcs.bbscn_enabled = fc_credit_recovery;
bfa_fcs_init(&bfad->bfa_fcs); bfa_fcs_init(&bfad->bfa_fcs);
spin_unlock_irqrestore(&bfad->bfad_lock, flags); spin_unlock_irqrestore(&bfad->bfad_lock, flags);
......
...@@ -340,7 +340,6 @@ extern int bfa_linkup_delay; ...@@ -340,7 +340,6 @@ extern int bfa_linkup_delay;
extern int msix_disable_cb; extern int msix_disable_cb;
extern int msix_disable_ct; extern int msix_disable_ct;
extern int fdmi_enable; extern int fdmi_enable;
extern int fc_credit_recovery;
extern int supported_fc4s; extern int supported_fc4s;
extern int pcie_max_read_reqsz; extern int pcie_max_read_reqsz;
extern int bfa_debugfs_enable; extern int bfa_debugfs_enable;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册