[SCSI] bfa: FCS bug fixes.
authorKrishna Gudipati <kgudipat@brocade.com>
Sat, 25 Jun 2011 03:24:52 +0000 (20:24 -0700)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 29 Jun 2011 22:12:11 +0000 (17:12 -0500)
- 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>
12 files changed:
drivers/scsi/bfa/bfa_defs_fcs.h
drivers/scsi/bfa/bfa_defs_svc.h
drivers/scsi/bfa/bfa_fcbuild.c
drivers/scsi/bfa/bfa_fcbuild.h
drivers/scsi/bfa/bfa_fcs.c
drivers/scsi/bfa/bfa_fcs.h
drivers/scsi/bfa/bfa_fcs_fcpim.c
drivers/scsi/bfa/bfa_fcs_lport.c
drivers/scsi/bfa/bfa_fcs_rport.c
drivers/scsi/bfa/bfa_svc.c
drivers/scsi/bfa/bfad.c
drivers/scsi/bfa/bfad_drv.h

index 191d34a..5e95976 100644 (file)
@@ -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,
 };
 
index d886187..7f35843 100644 (file)
@@ -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];
 };
 
 /*
index 08fba37..17b59b8 100644 (file)
@@ -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)
 {
index 9ba24c7..42cd9d4 100644 (file)
@@ -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);
 
index 5bbb76b..a9b22bc 100644 (file)
@@ -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;
index 5873d99..e32cb19 100644 (file)
@@ -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
index e7b49f4..29b4108 100644 (file)
@@ -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);
        }
 }
index 942443e..f8251a9 100644 (file)
@@ -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++;
 }
 
 /*
index 2ec5719..a42949d 100644 (file)
@@ -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);
 }
index 4dcf9b9..d7853e6 100644 (file)
@@ -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);
index 872c9df..0ed2608 100644 (file)
@@ -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);
 
index e5163c7..35bf0a6 100644 (file)
@@ -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;