summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bfa')
-rw-r--r--drivers/scsi/bfa/Makefile2
-rw-r--r--drivers/scsi/bfa/bfa_cb_ioim_macros.h7
-rw-r--r--drivers/scsi/bfa/bfa_core.c3
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.c29
-rw-r--r--drivers/scsi/bfa/bfa_fcpim_priv.h6
-rw-r--r--drivers/scsi/bfa/bfa_fcport.c141
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c20
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c3
-rw-r--r--drivers/scsi/bfa/bfa_fcxp.c14
-rw-r--r--drivers/scsi/bfa/bfa_fwimg_priv.h25
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c7
-rw-r--r--drivers/scsi/bfa/bfa_hw_ct.c7
-rw-r--r--drivers/scsi/bfa/bfa_intr.c1
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c172
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h12
-rw-r--r--drivers/scsi/bfa/bfa_ioc_cb.c36
-rw-r--r--drivers/scsi/bfa/bfa_ioc_ct.c71
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.c107
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.h19
-rw-r--r--drivers/scsi/bfa/bfa_ioim.c65
-rw-r--r--drivers/scsi/bfa/bfa_log_module.c86
-rw-r--r--drivers/scsi/bfa/bfa_lps.c6
-rw-r--r--drivers/scsi/bfa/bfa_port.c31
-rw-r--r--drivers/scsi/bfa/bfa_port_priv.h7
-rw-r--r--drivers/scsi/bfa/bfa_priv.h3
-rw-r--r--drivers/scsi/bfa/bfa_rport.c5
-rw-r--r--drivers/scsi/bfa/bfa_sgpg.c5
-rw-r--r--drivers/scsi/bfa/bfa_uf.c10
-rw-r--r--drivers/scsi/bfa/bfad.c116
-rw-r--r--drivers/scsi/bfa/bfad_attr.c46
-rw-r--r--drivers/scsi/bfa/bfad_debugfs.c547
-rw-r--r--drivers/scsi/bfa/bfad_drv.h36
-rw-r--r--drivers/scsi/bfa/bfad_fwimg.c76
-rw-r--r--drivers/scsi/bfa/bfad_im.c37
-rw-r--r--drivers/scsi/bfa/bfad_im_compat.h13
-rw-r--r--drivers/scsi/bfa/bfad_intr.c8
-rw-r--r--drivers/scsi/bfa/fabric.c44
-rw-r--r--drivers/scsi/bfa/fcpim.c32
-rw-r--r--drivers/scsi/bfa/fcs_fabric.h5
-rw-r--r--drivers/scsi/bfa/fcs_rport.h3
-rw-r--r--drivers/scsi/bfa/fcs_vport.h1
-rw-r--r--drivers/scsi/bfa/fdmi.c6
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_ioc.h8
-rw-r--r--drivers/scsi/bfa/include/bfa.h4
-rw-r--r--drivers/scsi/bfa/include/bfa_fcpim.h20
-rw-r--r--drivers/scsi/bfa/include/bfa_svc.h1
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ctreg.h3
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ioc.h20
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_iocfc.h2
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_pbc.h62
-rw-r--r--drivers/scsi/bfa/include/cna/port/bfa_port.h1
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_debug.h3
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_adapter.h3
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_auth.h6
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_boot.h10
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_driver.h2
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_fcport.h26
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ioc.h7
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h12
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_itnim.h10
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_mfg.h41
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pci.h11
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_port.h14
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pport.h29
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_status.h46
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h3
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs.h4
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h1
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h1
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h4
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_linux.h6
-rw-r--r--drivers/scsi/bfa/include/protocol/fc.h1
-rw-r--r--drivers/scsi/bfa/include/protocol/fcp.h4
-rw-r--r--drivers/scsi/bfa/lport_api.c30
-rw-r--r--drivers/scsi/bfa/ms.c9
-rw-r--r--drivers/scsi/bfa/ns.c14
-rw-r--r--drivers/scsi/bfa/rport.c88
-rw-r--r--drivers/scsi/bfa/rport_api.c11
-rw-r--r--drivers/scsi/bfa/rport_ftrs.c14
-rw-r--r--drivers/scsi/bfa/scn.c2
-rw-r--r--drivers/scsi/bfa/vport.c56
81 files changed, 1913 insertions, 546 deletions
diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile
index 17e06cae71b..ac3fdf02d5f 100644
--- a/drivers/scsi/bfa/Makefile
+++ b/drivers/scsi/bfa/Makefile
@@ -1,7 +1,7 @@
obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
-
+bfa-y += bfad_debugfs.o
bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o
bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
diff --git a/drivers/scsi/bfa/bfa_cb_ioim_macros.h b/drivers/scsi/bfa/bfa_cb_ioim_macros.h
index 53a616f5f50..3906ed92696 100644
--- a/drivers/scsi/bfa/bfa_cb_ioim_macros.h
+++ b/drivers/scsi/bfa/bfa_cb_ioim_macros.h
@@ -171,6 +171,11 @@ bfa_cb_ioim_get_cdblen(struct bfad_ioim_s *dio)
return cmnd->cmd_len;
}
-
+/**
+ * Assign queue to be used for the I/O request. This value depends on whether
+ * the driver wants to use the queues via any specific algorithm. Currently,
+ * this is not supported.
+ */
+#define bfa_cb_ioim_get_reqq(__dio) BFA_FALSE
#endif /* __BFA_HCB_IOIM_MACROS_H__ */
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 3a7b3f88932..76fa5c5b40d 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -333,9 +333,10 @@ bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P},
{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P},
{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT},
+ {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT_FC},
};
- *npciids = sizeof(__pciids) / sizeof(__pciids[0]);
+ *npciids = ARRAY_SIZE(__pciids);
*pciids = __pciids;
}
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
index 790c945aeae..8c703d8dc94 100644
--- a/drivers/scsi/bfa/bfa_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -80,11 +80,6 @@ bfa_fcpim_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
}
static void
-bfa_fcpim_initdone(struct bfa_s *bfa)
-{
-}
-
-static void
bfa_fcpim_detach(struct bfa_s *bfa)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
@@ -172,4 +167,28 @@ bfa_fcpim_qdepth_get(struct bfa_s *bfa)
return fcpim->q_depth;
}
+void
+bfa_fcpim_update_ioredirect(struct bfa_s *bfa)
+{
+ bfa_boolean_t ioredirect;
+
+ /*
+ * IO redirection is turned off when QoS is enabled and vice versa
+ */
+ ioredirect = bfa_fcport_is_qos_enabled(bfa) ? BFA_FALSE : BFA_TRUE;
+ /*
+ * Notify the bfad module of a possible state change in
+ * IO redirection capability, due to a QoS state change. bfad will
+ * check on the support for io redirection and update the
+ * fcpim's ioredirect state accordingly.
+ */
+ bfa_cb_ioredirect_state_change((void *)(bfa->bfad), ioredirect);
+}
+
+void
+bfa_fcpim_set_ioredirect(struct bfa_s *bfa, bfa_boolean_t state)
+{
+ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
+ fcpim->ioredirect = state;
+}
diff --git a/drivers/scsi/bfa/bfa_fcpim_priv.h b/drivers/scsi/bfa/bfa_fcpim_priv.h
index 5cf418460f7..762516cb5cb 100644
--- a/drivers/scsi/bfa/bfa_fcpim_priv.h
+++ b/drivers/scsi/bfa/bfa_fcpim_priv.h
@@ -49,7 +49,8 @@ struct bfa_fcpim_mod_s {
int num_tskim_reqs;
u32 path_tov;
u16 q_depth;
- u16 rsvd;
+ u8 reqq; /* Request queue to be used */
+ u8 rsvd;
struct list_head itnim_q; /* queue of active itnim */
struct list_head ioim_free_q; /* free IO resources */
struct list_head ioim_resfree_q; /* IOs waiting for f/w */
@@ -58,6 +59,7 @@ struct bfa_fcpim_mod_s {
u32 ios_active; /* current active IOs */
u32 delay_comp;
struct bfa_fcpim_stats_s stats;
+ bfa_boolean_t ioredirect;
};
struct bfa_ioim_s;
@@ -82,6 +84,7 @@ struct bfa_ioim_s {
struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
bfa_cb_cbfn_t io_cbfn; /* IO completion handler */
struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
+ u8 reqq; /* Request queue for I/O */
};
struct bfa_ioim_sp_s {
@@ -141,6 +144,7 @@ struct bfa_itnim_s {
struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
struct bfa_fcpim_mod_s *fcpim; /* fcpim module */
struct bfa_itnim_hal_stats_s stats;
+ struct bfa_itnim_latency_s io_latency;
};
#define bfa_itnim_is_online(_itnim) ((_itnim)->is_online)
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c
index c589488db0c..76867b5577f 100644
--- a/drivers/scsi/bfa/bfa_fcport.c
+++ b/drivers/scsi/bfa/bfa_fcport.c
@@ -18,6 +18,7 @@
#include <bfa.h>
#include <bfa_svc.h>
#include <bfi/bfi_pport.h>
+#include <bfi/bfi_pbc.h>
#include <cs/bfa_debug.h>
#include <aen/bfa_aen.h>
#include <cs/bfa_plog.h>
@@ -310,10 +311,12 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
- bfa_trc(fcport->bfa, pevent->link_state.fcf.fipenabled);
- bfa_trc(fcport->bfa, pevent->link_state.fcf.fipfailed);
+ bfa_trc(fcport->bfa,
+ pevent->link_state.vc_fcf.fcf.fipenabled);
+ bfa_trc(fcport->bfa,
+ pevent->link_state.vc_fcf.fcf.fipfailed);
- if (pevent->link_state.fcf.fipfailed)
+ if (pevent->link_state.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");
@@ -888,6 +891,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
struct bfa_pport_cfg_s *port_cfg = &fcport->cfg;
struct bfa_fcport_ln_s *ln = &fcport->ln;
+ struct bfa_timeval_s tv;
bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
fcport->bfa = bfa;
@@ -899,6 +903,12 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
/**
+ * initialize time stamp for stats reset
+ */
+ bfa_os_gettimeofday(&tv);
+ fcport->stats_reset_time = tv.tv_sec;
+
+ /**
* initialize and set default configuration
*/
port_cfg->topology = BFA_PPORT_TOPOLOGY_P2P;
@@ -912,25 +922,6 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
}
static void
-bfa_fcport_initdone(struct bfa_s *bfa)
-{
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
- /**
- * Initialize port attributes from IOC hardware data.
- */
- bfa_fcport_set_wwns(fcport);
- if (fcport->cfg.maxfrsize == 0)
- fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
- fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
- fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
-
- bfa_assert(fcport->cfg.maxfrsize);
- bfa_assert(fcport->cfg.rx_bbcredit);
- bfa_assert(fcport->speed_sup);
-}
-
-static void
bfa_fcport_detach(struct bfa_s *bfa)
{
}
@@ -971,14 +962,15 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
fcport->topology = pevent->link_state.topology;
if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP)
- fcport->myalpa =
- pevent->link_state.tl.loop_info.myalpa;
+ fcport->myalpa = 0;
/*
* QoS Details
*/
bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
- bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr);
+ bfa_os_assign(fcport->qos_vc_attr,
+ pevent->link_state.vc_fcf.qos_vc_attr);
+
bfa_trc(fcport->bfa, fcport->speed);
bfa_trc(fcport->bfa, fcport->topology);
@@ -1145,16 +1137,22 @@ __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
if (complete) {
if (fcport->stats_status == BFA_STATUS_OK) {
+ struct bfa_timeval_s tv;
/* Swap FC QoS or FCoE stats */
- if (bfa_ioc_get_fcmode(&fcport->bfa->ioc))
+ if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
bfa_fcport_qos_stats_swap(
&fcport->stats_ret->fcqos,
&fcport->stats->fcqos);
- else
+ } else {
bfa_fcport_fcoe_stats_swap(
&fcport->stats_ret->fcoe,
&fcport->stats->fcoe);
+
+ bfa_os_gettimeofday(&tv);
+ fcport->stats_ret->fcoe.secs_reset =
+ tv.tv_sec - fcport->stats_reset_time;
+ }
}
fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
} else {
@@ -1210,6 +1208,14 @@ __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
struct bfa_fcport_s *fcport = cbarg;
if (complete) {
+ struct bfa_timeval_s tv;
+
+ /**
+ * re-initialize time stamp for stats reset
+ */
+ bfa_os_gettimeofday(&tv);
+ fcport->stats_reset_time = tv.tv_sec;
+
fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
} else {
fcport->stats_busy = BFA_FALSE;
@@ -1263,6 +1269,29 @@ bfa_fcport_send_stats_clear(void *cbarg)
*/
/**
+ * Called to initialize port attributes
+ */
+void
+bfa_fcport_init(struct bfa_s *bfa)
+{
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+
+ /**
+ * Initialize port attributes from IOC hardware data.
+ */
+ bfa_fcport_set_wwns(fcport);
+ if (fcport->cfg.maxfrsize == 0)
+ fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
+ fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
+ fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
+
+ bfa_assert(fcport->cfg.maxfrsize);
+ bfa_assert(fcport->cfg.rx_bbcredit);
+ bfa_assert(fcport->speed_sup);
+}
+
+
+/**
* Firmware message handler.
*/
void
@@ -1281,7 +1310,7 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
break;
case BFI_FCPORT_I2H_DISABLE_RSP:
- if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+ if (fcport->msgtag == i2hmsg.pdisable_rsp->msgtag)
bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
break;
@@ -1355,6 +1384,17 @@ bfa_status_t
bfa_fcport_enable(struct bfa_s *bfa)
{
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+
+ /* if port is PBC disabled, return error */
+ if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
+ bfa_trc(bfa, fcport->pwwn);
+ return BFA_STATUS_PBC;
+ }
+
+ if (bfa_ioc_is_disabled(&bfa->ioc))
+ return BFA_STATUS_IOC_DISABLED;
if (fcport->diag_busy)
return BFA_STATUS_DIAG_BUSY;
@@ -1369,6 +1409,16 @@ bfa_fcport_enable(struct bfa_s *bfa)
bfa_status_t
bfa_fcport_disable(struct bfa_s *bfa)
{
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+
+ /* if port is PBC disabled, return error */
+ if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
+ bfa_trc(bfa, fcport->pwwn);
+ return BFA_STATUS_PBC;
+ }
+
bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
return BFA_STATUS_OK;
}
@@ -1559,12 +1609,17 @@ void
bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
{
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
attr->nwwn = fcport->nwwn;
attr->pwwn = fcport->pwwn;
+ attr->factorypwwn = bfa_ioc_get_mfg_pwwn(&bfa->ioc);
+ attr->factorynwwn = bfa_ioc_get_mfg_nwwn(&bfa->ioc);
+
bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
sizeof(struct bfa_pport_cfg_s));
/*
@@ -1590,11 +1645,18 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
- attr->port_state = bfa_sm_to_state(hal_pport_sm_table, fcport->sm);
- if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
- attr->port_state = BFA_PPORT_ST_IOCDIS;
- else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
- attr->port_state = BFA_PPORT_ST_FWMISMATCH;
+
+ /* PBC Disabled State */
+ if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED)
+ attr->port_state = BFA_PPORT_ST_PREBOOT_DISABLED;
+ else {
+ attr->port_state = bfa_sm_to_state(
+ hal_pport_sm_table, fcport->sm);
+ if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
+ attr->port_state = BFA_PPORT_ST_IOCDIS;
+ else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
+ attr->port_state = BFA_PPORT_ST_FWMISMATCH;
+ }
}
#define BFA_FCPORT_STATS_TOV 1000
@@ -1801,8 +1863,13 @@ bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
bfa_trc(bfa, ioc_type);
- if (ioc_type == BFA_IOC_TYPE_FC)
+ if (ioc_type == BFA_IOC_TYPE_FC) {
fcport->cfg.qos_enabled = on_off;
+ /**
+ * Notify fcpim of the change in QoS state
+ */
+ bfa_fcpim_update_ioredirect(bfa);
+ }
}
void
@@ -1886,4 +1953,10 @@ bfa_fcport_is_linkup(struct bfa_s *bfa)
return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup);
}
+bfa_boolean_t
+bfa_fcport_is_qos_enabled(struct bfa_s *bfa)
+{
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ return fcport->cfg.qos_enabled;
+}
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index 3516172c597..d1a99209bf5 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -86,7 +86,7 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
bfa_attach_fcs(bfa);
fcbuild_init();
- for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(fcs_modules); i++) {
mod = &fcs_modules[i];
if (mod->attach)
mod->attach(fcs);
@@ -99,14 +99,22 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
void
bfa_fcs_init(struct bfa_fcs_s *fcs)
{
- int i;
+ int i, npbc_vports;
struct bfa_fcs_mod_s *mod;
+ struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];
- for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(fcs_modules); i++) {
mod = &fcs_modules[i];
if (mod->modinit)
mod->modinit(fcs);
}
+ /* Initialize pbc vports */
+ if (!fcs->min_cfg) {
+ npbc_vports =
+ bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
+ for (i = 0; i < npbc_vports; i++)
+ bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
+ }
}
/**
@@ -163,13 +171,11 @@ void
bfa_fcs_exit(struct bfa_fcs_s *fcs)
{
struct bfa_fcs_mod_s *mod;
- int nmods, i;
+ int i;
bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
- nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
-
- for (i = 0; i < nmods; i++) {
+ for (i = 0; i < ARRAY_SIZE(fcs_modules); i++) {
mod = &fcs_modules[i];
if (mod->modexit) {
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index 7c1251c682d..35df20e68a5 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -135,6 +135,9 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
bfa_fcs_port_deleted(port);
break;
+ case BFA_FCS_PORT_SM_OFFLINE:
+ break;
+
default:
bfa_sm_fault(port->fcs, event);
}
diff --git a/drivers/scsi/bfa/bfa_fcxp.c b/drivers/scsi/bfa/bfa_fcxp.c
index cf0ad678268..8258f88bfee 100644
--- a/drivers/scsi/bfa/bfa_fcxp.c
+++ b/drivers/scsi/bfa/bfa_fcxp.c
@@ -149,11 +149,6 @@ bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
}
static void
-bfa_fcxp_initdone(struct bfa_s *bfa)
-{
-}
-
-static void
bfa_fcxp_detach(struct bfa_s *bfa)
{
}
@@ -225,7 +220,7 @@ bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
bfa_status_t req_status, u32 rsp_len,
u32 resid_len, struct fchs_s *rsp_fchs)
{
- /**discarded fcxp completion */
+ /* discarded fcxp completion */
}
static void
@@ -527,11 +522,8 @@ bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
if (nreq_sgles > BFI_SGE_INLINE) {
nreq_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
- if (bfa_sgpg_malloc
- (bfa, &fcxp->req_sgpg_q, nreq_sgpg)
+ if (bfa_sgpg_malloc(bfa, &fcxp->req_sgpg_q, nreq_sgpg)
!= BFA_STATUS_OK) {
- /* bfa_sgpg_wait(bfa, &fcxp->req_sgpg_wqe,
- nreq_sgpg); */
/*
* TODO
*/
@@ -685,7 +677,7 @@ bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
fcxp->send_cbarg = cbarg;
/**
- * If no room in CPE queue, wait for
+ * If no room in CPE queue, wait for space in request queue
*/
send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
if (!send_req) {
diff --git a/drivers/scsi/bfa/bfa_fwimg_priv.h b/drivers/scsi/bfa/bfa_fwimg_priv.h
index 1ec1355924d..d33e19e5439 100644
--- a/drivers/scsi/bfa/bfa_fwimg_priv.h
+++ b/drivers/scsi/bfa/bfa_fwimg_priv.h
@@ -21,11 +21,24 @@
#define BFI_FLASH_CHUNK_SZ 256 /* Flash chunk size */
#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32))
-extern u32 *bfi_image_ct_get_chunk(u32 off);
-extern u32 bfi_image_ct_size;
-extern u32 *bfi_image_cb_get_chunk(u32 off);
-extern u32 bfi_image_cb_size;
-extern u32 *bfi_image_cb;
-extern u32 *bfi_image_ct;
+/**
+ * BFI FW image type
+ */
+enum {
+ BFI_IMAGE_CB_FC,
+ BFI_IMAGE_CT_FC,
+ BFI_IMAGE_CT_CNA,
+ BFI_IMAGE_MAX,
+};
+
+extern u32 *bfi_image_get_chunk(int type, uint32_t off);
+extern u32 bfi_image_get_size(int type);
+extern u32 bfi_image_ct_fc_size;
+extern u32 bfi_image_ct_cna_size;
+extern u32 bfi_image_cb_fc_size;
+extern u32 *bfi_image_ct_fc;
+extern u32 *bfi_image_ct_cna;
+extern u32 *bfi_image_cb_fc;
+
#endif /* __BFA_FWIMG_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
index 871a4e28575..edfd729445c 100644
--- a/drivers/scsi/bfa/bfa_hw_cb.c
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -152,4 +152,9 @@ bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
}
-
+void
+bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end)
+{
+ *start = BFA_MSIX_RME_Q0;
+ *end = BFA_MSIX_RME_Q7;
+}
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c
index 76ceb9a4bf2..a357fb3066f 100644
--- a/drivers/scsi/bfa/bfa_hw_ct.c
+++ b/drivers/scsi/bfa/bfa_hw_ct.c
@@ -168,4 +168,9 @@ bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
bfa_ioc_isr_mode_set(&bfa->ioc, msix);
}
-
+void
+bfa_hwct_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end)
+{
+ *start = BFA_MSIX_RME_Q0;
+ *end = BFA_MSIX_RME_Q3;
+}
diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c
index 0eba3f930d5..493678889b2 100644
--- a/drivers/scsi/bfa/bfa_intr.c
+++ b/drivers/scsi/bfa/bfa_intr.c
@@ -134,6 +134,7 @@ bfa_isr_enable(struct bfa_s *bfa)
bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr_unmask);
bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, ~intr_unmask);
+ bfa->iocfc.intr_mask = ~intr_unmask;
bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0);
}
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index e038bc9769f..8e78f20110a 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -59,22 +59,18 @@ BFA_TRC_FILE(CNA, IOC);
((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
#define bfa_ioc_firmware_unlock(__ioc) \
((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
-#define bfa_ioc_fwimg_get_chunk(__ioc, __off) \
- ((__ioc)->ioc_hwif->ioc_fwimg_get_chunk(__ioc, __off))
-#define bfa_ioc_fwimg_get_size(__ioc) \
- ((__ioc)->ioc_hwif->ioc_fwimg_get_size(__ioc))
#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
#define bfa_ioc_notify_hbfail(__ioc) \
((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
+#define bfa_ioc_is_optrom(__ioc) \
+ (bfi_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ)
bfa_boolean_t bfa_auto_recover = BFA_TRUE;
/*
* forward declarations
*/
-static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
- enum bfa_ioc_aen_event event);
static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
@@ -88,6 +84,7 @@ static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
+static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc);
static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
@@ -433,6 +430,7 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
switch (event) {
case IOC_E_FWRSP_GETATTR:
bfa_ioc_timer_stop(ioc);
+ bfa_ioc_check_attr_wwns(ioc);
bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
break;
@@ -879,8 +877,8 @@ bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
struct bfi_ioc_image_hdr_s *drv_fwhdr;
int i;
- drv_fwhdr =
- (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
+ drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
+ bfi_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) {
@@ -907,12 +905,13 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
/**
* If bios/efi boot (flash based) -- return true
*/
- if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ if (bfa_ioc_is_optrom(ioc))
return BFA_TRUE;
bfa_ioc_fwver_get(ioc, &fwhdr);
- drv_fwhdr =
- (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
+ drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
+ bfi_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
+
if (fwhdr.signature != drv_fwhdr->signature) {
bfa_trc(ioc, fwhdr.signature);
@@ -980,8 +979,13 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
/**
* If IOC function is disabled and firmware version is same,
* just re-enable IOC.
+ *
+ * If option rom, IOC must not be in operational state. With
+ * convergence, IOC will be in operational state when 2nd driver
+ * is loaded.
*/
- if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
+ if (ioc_fwstate == BFI_IOC_DISABLED ||
+ (!bfa_ioc_is_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) {
bfa_trc(ioc, ioc_fwstate);
/**
@@ -1125,21 +1129,22 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
/**
* Flash based firmware boot
*/
- bfa_trc(ioc, bfa_ioc_fwimg_get_size(ioc));
- if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ bfa_trc(ioc, bfi_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)));
+ if (bfa_ioc_is_optrom(ioc))
boot_type = BFI_BOOT_TYPE_FLASH;
- fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
+ fwimg = bfi_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno);
+
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
pgoff = bfa_ioc_smem_pgoff(ioc, loff);
bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
- for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
+ for (i = 0; i < bfi_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) {
if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
- fwimg = bfa_ioc_fwimg_get_chunk(ioc,
+ fwimg = bfi_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc),
BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
}
@@ -1188,6 +1193,7 @@ bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
struct bfi_ioc_attr_s *attr = ioc->attr;
attr->adapter_prop = bfa_os_ntohl(attr->adapter_prop);
+ attr->card_type = bfa_os_ntohl(attr->card_type);
attr->maxfrsize = bfa_os_ntohs(attr->maxfrsize);
bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
@@ -1282,6 +1288,7 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param)
bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_INITING);
}
+ bfa_ioc_msgflush(ioc);
bfa_ioc_download_fw(ioc, boot_type, boot_param);
/**
@@ -1416,7 +1423,7 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
{
ioc->ioc_mc = mc;
ioc->pcidev = *pcidev;
- ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
+ ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id);
ioc->cna = ioc->ctdev && !ioc->fcmode;
/**
@@ -1607,6 +1614,13 @@ bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
bfa_fsm_send_event(ioc, IOC_E_HWERROR);
}
+void
+bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc)
+{
+ ioc->fcmode = BFA_TRUE;
+ ioc->port_id = bfa_ioc_pcifn(ioc);
+}
+
#ifndef BFA_BIOS_BUILD
/**
@@ -1696,6 +1710,9 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
/* For now, model descr uses same model string */
bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
+ ad_attr->card_type = ioc_attr->card_type;
+ ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type);
+
if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
ad_attr->prototype = 1;
else
@@ -1779,28 +1796,17 @@ void
bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
{
struct bfi_ioc_attr_s *ioc_attr;
- u8 nports;
- u8 max_speed;
bfa_assert(model);
bfa_os_memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
ioc_attr = ioc->attr;
- nports = bfa_ioc_get_nports(ioc);
- max_speed = bfa_ioc_speed_sup(ioc);
-
/**
* model name
*/
- if (max_speed == 10) {
- strcpy(model, "BR-10?0");
- model[5] = '0' + nports;
- } else {
- strcpy(model, "Brocade-??5");
- model[8] = '0' + max_speed;
- model[9] = '0' + nports;
- }
+ snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
+ BFA_MFG_NAME, ioc_attr->card_type);
}
enum bfa_ioc_state
@@ -1827,78 +1833,54 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
}
/**
- * hal_wwn_public
+ * bfa_wwn_public
*/
wwn_t
bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc)
{
- union {
- wwn_t wwn;
- u8 byte[sizeof(wwn_t)];
- }
- w;
-
- w.wwn = ioc->attr->mfg_wwn;
-
- if (bfa_ioc_portid(ioc) == 1)
- w.byte[7]++;
-
- return w.wwn;
+ return ioc->attr->pwwn;
}
wwn_t
bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc)
{
- union {
- wwn_t wwn;
- u8 byte[sizeof(wwn_t)];
- }
- w;
-
- w.wwn = ioc->attr->mfg_wwn;
-
- if (bfa_ioc_portid(ioc) == 1)
- w.byte[7]++;
+ return ioc->attr->nwwn;
+}
- w.byte[0] = 0x20;
+u64
+bfa_ioc_get_adid(struct bfa_ioc_s *ioc)
+{
+ return ioc->attr->mfg_pwwn;
+}
- return w.wwn;
+mac_t
+bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
+{
+ /*
+ * Currently mfg mac is used as FCoE enode mac (not configured by PBC)
+ */
+ if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE)
+ return bfa_ioc_get_mfg_mac(ioc);
+ else
+ return ioc->attr->mac;
}
wwn_t
-bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst)
+bfa_ioc_get_mfg_pwwn(struct bfa_ioc_s *ioc)
{
- union {
- wwn_t wwn;
- u8 byte[sizeof(wwn_t)];
- }
- w , w5;
-
- bfa_trc(ioc, inst);
-
- w.wwn = ioc->attr->mfg_wwn;
- w5.byte[0] = 0x50 | w.byte[2] >> 4;
- w5.byte[1] = w.byte[2] << 4 | w.byte[3] >> 4;
- w5.byte[2] = w.byte[3] << 4 | w.byte[4] >> 4;
- w5.byte[3] = w.byte[4] << 4 | w.byte[5] >> 4;
- w5.byte[4] = w.byte[5] << 4 | w.byte[6] >> 4;
- w5.byte[5] = w.byte[6] << 4 | w.byte[7] >> 4;
- w5.byte[6] = w.byte[7] << 4 | (inst & 0x0f00) >> 8;
- w5.byte[7] = (inst & 0xff);
-
- return w5.wwn;
+ return ioc->attr->mfg_pwwn;
}
-u64
-bfa_ioc_get_adid(struct bfa_ioc_s *ioc)
+wwn_t
+bfa_ioc_get_mfg_nwwn(struct bfa_ioc_s *ioc)
{
- return ioc->attr->mfg_wwn;
+ return ioc->attr->mfg_nwwn;
}
mac_t
-bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
+bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc)
{
- mac_t mac;
+ mac_t mac;
mac = ioc->attr->mfg_mac;
mac.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
@@ -1906,23 +1888,16 @@ bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
return mac;
}
-void
-bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc)
-{
- ioc->fcmode = BFA_TRUE;
- ioc->port_id = bfa_ioc_pcifn(ioc);
-}
-
bfa_boolean_t
bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
{
- return ioc->fcmode || (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT);
+ return ioc->fcmode || !bfa_asic_id_ct(ioc->pcidev.device_id);
}
/**
* Send AEN notification
*/
-static void
+void
bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
{
union bfa_aen_data_u aen_data;
@@ -2070,19 +2045,16 @@ bfa_ioc_recover(struct bfa_ioc_s *ioc)
bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
}
-#else
-
static void
-bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
+bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc)
{
-}
+ if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
+ return;
-static void
-bfa_ioc_recover(struct bfa_ioc_s *ioc)
-{
- bfa_assert(0);
+ if (ioc->attr->nwwn == 0)
+ bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_NWWN);
+ if (ioc->attr->pwwn == 0)
+ bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_PWWN);
}
#endif
-
-
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index d0804406ea1..cae05b251c9 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -186,9 +186,6 @@ struct bfa_ioc_hwif_s {
bfa_status_t (*ioc_pll_init) (struct bfa_ioc_s *ioc);
bfa_boolean_t (*ioc_firmware_lock) (struct bfa_ioc_s *ioc);
void (*ioc_firmware_unlock) (struct bfa_ioc_s *ioc);
- u32 * (*ioc_fwimg_get_chunk) (struct bfa_ioc_s *ioc,
- u32 off);
- u32 (*ioc_fwimg_get_size) (struct bfa_ioc_s *ioc);
void (*ioc_reg_init) (struct bfa_ioc_s *ioc);
void (*ioc_map_port) (struct bfa_ioc_s *ioc);
void (*ioc_isr_mode_set) (struct bfa_ioc_s *ioc,
@@ -214,6 +211,10 @@ struct bfa_ioc_hwif_s {
#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
+#define BFA_IOC_FWIMG_TYPE(__ioc) \
+ (((__ioc)->ctdev) ? \
+ (((__ioc)->fcmode) ? BFI_IMAGE_CT_FC : BFI_IMAGE_CT_CNA) : \
+ BFI_IMAGE_CB_FC)
#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
@@ -296,14 +297,17 @@ void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
struct bfi_ioc_image_hdr_s *fwhdr);
bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
struct bfi_ioc_image_hdr_s *fwhdr);
+void bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event);
/*
* bfa mfg wwn API functions
*/
wwn_t bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc);
wwn_t bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc);
-wwn_t bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst);
mac_t bfa_ioc_get_mac(struct bfa_ioc_s *ioc);
+wwn_t bfa_ioc_get_mfg_pwwn(struct bfa_ioc_s *ioc);
+wwn_t bfa_ioc_get_mfg_nwwn(struct bfa_ioc_s *ioc);
+mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc);
u64 bfa_ioc_get_adid(struct bfa_ioc_s *ioc);
#endif /* __BFA_IOC_H__ */
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c
index 3ce85319f73..324bdde7ea2 100644
--- a/drivers/scsi/bfa/bfa_ioc_cb.c
+++ b/drivers/scsi/bfa/bfa_ioc_cb.c
@@ -33,26 +33,13 @@ BFA_TRC_FILE(CNA, IOC_CB);
static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc);
static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
-static u32 *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off);
-static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
-struct bfa_ioc_hwif_s hwif_cb = {
- bfa_ioc_cb_pll_init,
- bfa_ioc_cb_firmware_lock,
- bfa_ioc_cb_firmware_unlock,
- bfa_ioc_cb_fwimg_get_chunk,
- bfa_ioc_cb_fwimg_get_size,
- bfa_ioc_cb_reg_init,
- bfa_ioc_cb_map_port,
- bfa_ioc_cb_isr_mode_set,
- bfa_ioc_cb_notify_hbfail,
- bfa_ioc_cb_ownership_reset,
-};
+struct bfa_ioc_hwif_s hwif_cb;
/**
* Called from bfa_ioc_attach() to map asic specific calls.
@@ -60,19 +47,16 @@ struct bfa_ioc_hwif_s hwif_cb = {
void
bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
{
- ioc->ioc_hwif = &hwif_cb;
-}
-
-static u32 *
-bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
-{
- return bfi_image_cb_get_chunk(off);
-}
+ hwif_cb.ioc_pll_init = bfa_ioc_cb_pll_init;
+ hwif_cb.ioc_firmware_lock = bfa_ioc_cb_firmware_lock;
+ hwif_cb.ioc_firmware_unlock = bfa_ioc_cb_firmware_unlock;
+ hwif_cb.ioc_reg_init = bfa_ioc_cb_reg_init;
+ hwif_cb.ioc_map_port = bfa_ioc_cb_map_port;
+ hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set;
+ hwif_cb.ioc_notify_hbfail = bfa_ioc_cb_notify_hbfail;
+ hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset;
-static u32
-bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc)
-{
- return bfi_image_cb_size;
+ ioc->ioc_hwif = &hwif_cb;
}
/**
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
index 20b58ad5f95..68f027da001 100644
--- a/drivers/scsi/bfa/bfa_ioc_ct.c
+++ b/drivers/scsi/bfa/bfa_ioc_ct.c
@@ -33,27 +33,13 @@ BFA_TRC_FILE(CNA, IOC_CT);
static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc);
static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
-static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
- u32 off);
-static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
-struct bfa_ioc_hwif_s hwif_ct = {
- bfa_ioc_ct_pll_init,
- bfa_ioc_ct_firmware_lock,
- bfa_ioc_ct_firmware_unlock,
- bfa_ioc_ct_fwimg_get_chunk,
- bfa_ioc_ct_fwimg_get_size,
- bfa_ioc_ct_reg_init,
- bfa_ioc_ct_map_port,
- bfa_ioc_ct_isr_mode_set,
- bfa_ioc_ct_notify_hbfail,
- bfa_ioc_ct_ownership_reset,
-};
+struct bfa_ioc_hwif_s hwif_ct;
/**
* Called from bfa_ioc_attach() to map asic specific calls.
@@ -61,19 +47,16 @@ struct bfa_ioc_hwif_s hwif_ct = {
void
bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
{
- ioc->ioc_hwif = &hwif_ct;
-}
+ hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init;
+ hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock;
+ hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock;
+ hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init;
+ hwif_ct.ioc_map_port = bfa_ioc_ct_map_port;
+ hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
+ hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail;
+ hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
-static u32*
-bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
-{
- return bfi_image_ct_get_chunk(off);
-}
-
-static u32
-bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc)
-{
- return bfi_image_ct_size;
+ ioc->ioc_hwif = &hwif_ct;
}
/**
@@ -95,7 +78,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
/**
* If bios boot (flash based) -- do not increment usage count
*/
- if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ if (bfi_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) < BFA_IOC_FWIMG_MINSZ)
return BFA_TRUE;
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
@@ -146,9 +129,14 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
/**
* Firmware lock is relevant only for CNA.
+ */
+ if (!ioc->cna)
+ return;
+
+ /**
* If bios boot (flash based) -- do not decrement usage count
*/
- if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ if (bfi_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) < BFA_IOC_FWIMG_MINSZ)
return;
/**
@@ -388,10 +376,35 @@ bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
__APP_PLL_425_ENABLE);
+ /**
+ * PSS memory reset is asserted at power-on-reset. Need to clear
+ * this before running EDRAM BISTR
+ */
+ if (ioc->cna) {
+ bfa_reg_write((rb + PMM_1T_RESET_REG_P0), __PMM_1T_RESET_P);
+ bfa_reg_write((rb + PMM_1T_RESET_REG_P1), __PMM_1T_RESET_P);
+ }
+
+ r32 = bfa_reg_read((rb + PSS_CTL_REG));
+ r32 &= ~__PSS_LMEM_RESET;
+ bfa_reg_write((rb + PSS_CTL_REG), r32);
+ bfa_os_udelay(1000);
+
+ if (ioc->cna) {
+ bfa_reg_write((rb + PMM_1T_RESET_REG_P0), 0);
+ bfa_reg_write((rb + PMM_1T_RESET_REG_P1), 0);
+ }
+
bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
bfa_os_udelay(1000);
r32 = bfa_reg_read((rb + MBIST_STAT_REG));
bfa_trc(ioc, r32);
+
+ /**
+ * Clear BISTR
+ */
+ bfa_reg_write((rb + MBIST_CTL_REG), 0);
+
/*
* release semaphore.
*/
diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c
index a76de2669bf..90820be9986 100644
--- a/drivers/scsi/bfa/bfa_iocfc.c
+++ b/drivers/scsi/bfa/bfa_iocfc.c
@@ -113,7 +113,6 @@ bfa_iocfc_send_cfg(void *bfa_arg)
bfa_assert(cfg->fwcfg.num_cqs <= BFI_IOC_MAX_CQS);
bfa_trc(bfa, cfg->fwcfg.num_cqs);
- iocfc->cfgdone = BFA_FALSE;
bfa_iocfc_reset_queues(bfa);
/**
@@ -145,6 +144,15 @@ bfa_iocfc_send_cfg(void *bfa_arg)
}
/**
+ * Enable interrupt coalescing if it is driver init path
+ * and not ioc disable/enable path.
+ */
+ if (!iocfc->cfgdone)
+ cfg_info->intr_attr.coalesce = BFA_TRUE;
+
+ iocfc->cfgdone = BFA_FALSE;
+
+ /**
* dma map IOC configuration itself
*/
bfi_h2i_set(cfg_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CFG_REQ,
@@ -170,7 +178,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
/**
* Initialize chip specific handlers.
*/
- if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
+ if (bfa_asic_id_ct(bfa_ioc_devid(&bfa->ioc))) {
iocfc->hwif.hw_reginit = bfa_hwct_reginit;
iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
@@ -179,6 +187,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall;
iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set;
iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
+ iocfc->hwif.hw_msix_get_rme_range = bfa_hwct_msix_get_rme_range;
} else {
iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
@@ -188,6 +197,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall;
iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set;
iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs;
+ iocfc->hwif.hw_msix_get_rme_range = bfa_hwcb_msix_get_rme_range;
}
iocfc->hwif.hw_reginit(bfa);
@@ -291,18 +301,6 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
}
/**
- * BFA submodules initialization completion notification.
- */
-static void
-bfa_iocfc_initdone_submod(struct bfa_s *bfa)
-{
- int i;
-
- for (i = 0; hal_mods[i]; i++)
- hal_mods[i]->initdone(bfa);
-}
-
-/**
* Start BFA submodules.
*/
static void
@@ -376,7 +374,6 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
struct bfa_iocfc_s *iocfc = &bfa->iocfc;
struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
struct bfa_iocfc_fwcfg_s *fwcfg = &cfgrsp->fwcfg;
- struct bfi_iocfc_cfg_s *cfginfo = iocfc->cfginfo;
fwcfg->num_cqs = fwcfg->num_cqs;
fwcfg->num_ioim_reqs = bfa_os_ntohs(fwcfg->num_ioim_reqs);
@@ -385,15 +382,13 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
fwcfg->num_uf_bufs = bfa_os_ntohs(fwcfg->num_uf_bufs);
fwcfg->num_rports = bfa_os_ntohs(fwcfg->num_rports);
- cfginfo->intr_attr.coalesce = cfgrsp->intr_attr.coalesce;
- cfginfo->intr_attr.delay = bfa_os_ntohs(cfgrsp->intr_attr.delay);
- cfginfo->intr_attr.latency = bfa_os_ntohs(cfgrsp->intr_attr.latency);
-
iocfc->cfgdone = BFA_TRUE;
/**
* Configuration is complete - initialize/start submodules
*/
+ bfa_fcport_init(bfa);
+
if (iocfc->action == BFA_IOCFC_ACT_INIT)
bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa);
else
@@ -531,7 +526,6 @@ bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
return;
}
- bfa_iocfc_initdone_submod(bfa);
bfa_iocfc_send_cfg(bfa);
}
@@ -625,9 +619,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa->trcmod, bfa->aen, bfa->logm);
/**
- * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
+ * Set FC mode for BFA_PCI_DEVICE_ID_CT_FC.
*/
- if (0)
+ if (pcidev->device_id == BFA_PCI_DEVICE_ID_CT_FC)
bfa_ioc_set_fcmode(&bfa->ioc);
bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
@@ -748,10 +742,20 @@ bfa_adapter_get_id(struct bfa_s *bfa)
void
bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr)
{
- struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+
+ attr->intr_attr.coalesce = iocfc->cfginfo->intr_attr.coalesce;
+
+ attr->intr_attr.delay = iocfc->cfginfo->intr_attr.delay ?
+ bfa_os_ntohs(iocfc->cfginfo->intr_attr.delay) :
+ bfa_os_ntohs(iocfc->cfgrsp->intr_attr.delay);
+
+ attr->intr_attr.latency = iocfc->cfginfo->intr_attr.latency ?
+ bfa_os_ntohs(iocfc->cfginfo->intr_attr.latency) :
+ bfa_os_ntohs(iocfc->cfgrsp->intr_attr.latency);
+
+ attr->config = iocfc->cfg;
- attr->intr_attr = iocfc->cfginfo->intr_attr;
- attr->config = iocfc->cfg;
}
bfa_status_t
@@ -760,7 +764,10 @@ bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)
struct bfa_iocfc_s *iocfc = &bfa->iocfc;
struct bfi_iocfc_set_intr_req_s *m;
- iocfc->cfginfo->intr_attr = *attr;
+ iocfc->cfginfo->intr_attr.coalesce = attr->coalesce;
+ iocfc->cfginfo->intr_attr.delay = bfa_os_htons(attr->delay);
+ iocfc->cfginfo->intr_attr.latency = bfa_os_htons(attr->latency);
+
if (!bfa_iocfc_is_operational(bfa))
return BFA_STATUS_OK;
@@ -770,9 +777,10 @@ bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)
bfi_h2i_set(m->mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_SET_INTR_REQ,
bfa_lpuid(bfa));
- m->coalesce = attr->coalesce;
- m->delay = bfa_os_htons(attr->delay);
- m->latency = bfa_os_htons(attr->latency);
+ m->coalesce = iocfc->cfginfo->intr_attr.coalesce;
+ m->delay = iocfc->cfginfo->intr_attr.delay;
+ m->latency = iocfc->cfginfo->intr_attr.latency;
+
bfa_trc(bfa, attr->delay);
bfa_trc(bfa, attr->latency);
@@ -872,15 +880,48 @@ bfa_iocfc_is_operational(struct bfa_s *bfa)
* Return boot target port wwns -- read from boot information in flash.
*/
void
-bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns)
+bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t *wwns)
{
- struct bfa_iocfc_s *iocfc = &bfa->iocfc;
- struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+ int i;
+
+ if (cfgrsp->pbc_cfg.boot_enabled && cfgrsp->pbc_cfg.nbluns) {
+ bfa_trc(bfa, cfgrsp->pbc_cfg.nbluns);
+ *nwwns = cfgrsp->pbc_cfg.nbluns;
+ for (i = 0; i < cfgrsp->pbc_cfg.nbluns; i++)
+ wwns[i] = cfgrsp->pbc_cfg.blun[i].tgt_pwwn;
+
+ return;
+ }
*nwwns = cfgrsp->bootwwns.nwwns;
- *wwns = cfgrsp->bootwwns.wwn;
+ memcpy(wwns, cfgrsp->bootwwns.wwn, sizeof(cfgrsp->bootwwns.wwn));
+}
+
+void
+bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa, struct bfa_boot_pbc_s *pbcfg)
+{
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+
+ pbcfg->enable = cfgrsp->pbc_cfg.boot_enabled;
+ pbcfg->nbluns = cfgrsp->pbc_cfg.nbluns;
+ pbcfg->speed = cfgrsp->pbc_cfg.port_speed;
+ memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun));
}
+int
+bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
+{
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+
+ memcpy(pbc_vport, cfgrsp->pbc_cfg.vport, sizeof(cfgrsp->pbc_cfg.vport));
+ return cfgrsp->pbc_cfg.nvports;
+}
+
+
#endif
diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h
index fbb4bdc9d60..74a6a048d1f 100644
--- a/drivers/scsi/bfa/bfa_iocfc.h
+++ b/drivers/scsi/bfa/bfa_iocfc.h
@@ -21,6 +21,7 @@
#include <bfa_ioc.h>
#include <bfa.h>
#include <bfi/bfi_iocfc.h>
+#include <bfi/bfi_pbc.h>
#include <bfa_callback_priv.h>
#define BFA_REQQ_NELEMS_MIN (4)
@@ -62,6 +63,8 @@ struct bfa_hwif_s {
void (*hw_isr_mode_set)(struct bfa_s *bfa, bfa_boolean_t msix);
void (*hw_msix_getvecs)(struct bfa_s *bfa, u32 *vecmap,
u32 *nvecs, u32 *maxvec);
+ void (*hw_msix_get_rme_range) (struct bfa_s *bfa, u32 *start,
+ u32 *end);
};
typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status);
@@ -103,7 +106,8 @@ struct bfa_iocfc_s {
struct bfa_hwif_s hwif;
bfa_cb_iocfc_t updateq_cbfn; /* bios callback function */
- void *updateq_cbarg; /* bios callback arg */
+ void *updateq_cbarg; /* bios callback arg */
+ u32 intr_mask;
};
#define bfa_lpuid(__bfa) bfa_ioc_portid(&(__bfa)->ioc)
@@ -116,7 +120,10 @@ struct bfa_iocfc_s {
#define bfa_isr_mode_set(__bfa, __msix) \
((__bfa)->iocfc.hwif.hw_isr_mode_set(__bfa, __msix))
#define bfa_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec) \
- (__bfa)->iocfc.hwif.hw_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec)
+ ((__bfa)->iocfc.hwif.hw_msix_getvecs(__bfa, __vecmap, \
+ __nvecs, __maxvec))
+#define bfa_msix_get_rme_range(__bfa, __start, __end) \
+ ((__bfa)->iocfc.hwif.hw_msix_get_rme_range(__bfa, __start, __end))
/*
* FC specific IOC functions.
@@ -152,6 +159,7 @@ void bfa_hwcb_msix_uninstall(struct bfa_s *bfa);
void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
u32 *nvecs, u32 *maxvec);
+void bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end);
void bfa_hwct_reginit(struct bfa_s *bfa);
void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
@@ -161,11 +169,16 @@ void bfa_hwct_msix_uninstall(struct bfa_s *bfa);
void bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
void bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
u32 *nvecs, u32 *maxvec);
+void bfa_hwct_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end);
void bfa_com_meminfo(bfa_boolean_t mincfg, u32 *dm_len);
void bfa_com_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi,
bfa_boolean_t mincfg);
-void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns);
+void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t *wwns);
+void bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa,
+ struct bfa_boot_pbc_s *pbcfg);
+int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa,
+ struct bfi_pbc_vport_s *pbc_vport);
#endif /* __BFA_IOCFC_H__ */
diff --git a/drivers/scsi/bfa/bfa_ioim.c b/drivers/scsi/bfa/bfa_ioim.c
index 687f3d6e252..bdfdc19915f 100644
--- a/drivers/scsi/bfa/bfa_ioim.c
+++ b/drivers/scsi/bfa/bfa_ioim.c
@@ -133,6 +133,8 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_IOTOV:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
__bfa_cb_ioim_pathtov, ioim);
break;
@@ -182,6 +184,8 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_ABORT:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
ioim);
break;
@@ -189,6 +193,8 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_HWFAIL:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
ioim);
break;
@@ -210,18 +216,24 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
switch (event) {
case BFA_IOIM_SM_COMP_GOOD:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
__bfa_cb_ioim_good_comp, ioim);
break;
case BFA_IOIM_SM_COMP:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
ioim);
break;
case BFA_IOIM_SM_DONE:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
ioim);
break;
@@ -234,8 +246,8 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
else {
bfa_sm_set_state(ioim, bfa_ioim_sm_abort_qfull);
- bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
- &ioim->iosp->reqq_wait);
+ bfa_reqq_wait(ioim->bfa, ioim->reqq,
+ &ioim->iosp->reqq_wait);
}
break;
@@ -247,13 +259,15 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
else {
bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
- bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
- &ioim->iosp->reqq_wait);
+ bfa_reqq_wait(ioim->bfa, ioim->reqq,
+ &ioim->iosp->reqq_wait);
}
break;
case BFA_IOIM_SM_HWFAIL:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
ioim);
break;
@@ -287,12 +301,16 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_ABORT_COMP:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
ioim);
break;
case BFA_IOIM_SM_COMP_UTAG:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
ioim);
break;
@@ -305,13 +323,15 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
else {
bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
- bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
+ bfa_reqq_wait(ioim->bfa, ioim->reqq,
&ioim->iosp->reqq_wait);
}
break;
case BFA_IOIM_SM_HWFAIL:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
ioim);
break;
@@ -365,6 +385,8 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_HWFAIL:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
ioim);
break;
@@ -399,6 +421,8 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_ABORT:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
ioim);
break;
@@ -414,6 +438,8 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_HWFAIL:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
ioim);
break;
@@ -448,6 +474,8 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_COMP:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
ioim);
break;
@@ -455,6 +483,8 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_DONE:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
ioim);
break;
@@ -462,6 +492,8 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_HWFAIL:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
ioim);
break;
@@ -488,7 +520,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_ABORT:
/**
- * IO is alraedy being cleaned up implicitly
+ * IO is already being cleaned up implicitly
*/
ioim->io_cbfn = __bfa_cb_ioim_abort;
break;
@@ -511,6 +543,8 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
case BFA_IOIM_SM_HWFAIL:
bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
+ list_del(&ioim->qe);
+ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
ioim);
break;
@@ -738,9 +772,9 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
/**
* check for room in queue to send request now
*/
- m = bfa_reqq_next(ioim->bfa, itnim->reqq);
+ m = bfa_reqq_next(ioim->bfa, ioim->reqq);
if (!m) {
- bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
+ bfa_reqq_wait(ioim->bfa, ioim->reqq,
&ioim->iosp->reqq_wait);
return BFA_FALSE;
}
@@ -832,7 +866,7 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
/**
* queue I/O message to firmware
*/
- bfa_reqq_produce(ioim->bfa, itnim->reqq);
+ bfa_reqq_produce(ioim->bfa, ioim->reqq);
return BFA_TRUE;
}
@@ -930,14 +964,13 @@ bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
static bfa_boolean_t
bfa_ioim_send_abort(struct bfa_ioim_s *ioim)
{
- struct bfa_itnim_s *itnim = ioim->itnim;
struct bfi_ioim_abort_req_s *m;
enum bfi_ioim_h2i msgop;
/**
* check for room in queue to send request now
*/
- m = bfa_reqq_next(ioim->bfa, itnim->reqq);
+ m = bfa_reqq_next(ioim->bfa, ioim->reqq);
if (!m)
return BFA_FALSE;
@@ -956,7 +989,7 @@ bfa_ioim_send_abort(struct bfa_ioim_s *ioim)
/**
* queue I/O message to firmware
*/
- bfa_reqq_produce(ioim->bfa, itnim->reqq);
+ bfa_reqq_produce(ioim->bfa, ioim->reqq);
return BFA_TRUE;
}
@@ -1306,6 +1339,14 @@ void
bfa_ioim_start(struct bfa_ioim_s *ioim)
{
bfa_trc_fp(ioim->bfa, ioim->iotag);
+
+ /**
+ * Obtain the queue over which this request has to be issued
+ */
+ ioim->reqq = bfa_fcpim_ioredirect_enabled(ioim->bfa) ?
+ bfa_cb_ioim_get_reqq(ioim->dio) :
+ bfa_itnim_get_reqq(ioim);
+
bfa_sm_send_event(ioim, BFA_IOIM_SM_START);
}
diff --git a/drivers/scsi/bfa/bfa_log_module.c b/drivers/scsi/bfa/bfa_log_module.c
index 5c154d341d6..cf577ef7cb9 100644
--- a/drivers/scsi/bfa/bfa_log_module.c
+++ b/drivers/scsi/bfa/bfa_log_module.c
@@ -110,6 +110,27 @@ struct bfa_log_msgdef_s bfa_log_msg_array[] = {
"Running firmware version is incompatible with the driver version.",
(0), 0},
+{BFA_AEN_IOC_FWCFG_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_CRITICAL, "BFA_AEN_IOC_FWCFG_ERROR",
+ "Link initialization failed due to firmware configuration read error:"
+ " WWN = %s.",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_AEN_IOC_INVALID_VENDOR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_ERROR, "BFA_AEN_IOC_INVALID_VENDOR",
+ "Unsupported switch vendor. Link initialization failed: WWN = %s.",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_AEN_IOC_INVALID_NWWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_ERROR, "BFA_AEN_IOC_INVALID_NWWN",
+ "Invalid NWWN. Link initialization failed: NWWN = 00:00:00:00:00:00:00:00.",
+ (0), 0},
+
+{BFA_AEN_IOC_INVALID_PWWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_ERROR, "BFA_AEN_IOC_INVALID_PWWN",
+ "Invalid PWWN. Link initialization failed: PWWN = 00:00:00:00:00:00:00:00.",
+ (0), 0},
+
@@ -347,6 +368,22 @@ struct bfa_log_msgdef_s bfa_log_msg_array[] = {
((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
(BFA_LOG_D << BFA_LOG_ARG2) | 0), 3},
+{BFA_LOG_HAL_DRIVER_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_INFO, "HAL_DRIVER_ERROR",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_LOG_HAL_DRIVER_CONFIG_ERROR,
+ BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
+ "HAL_DRIVER_CONFIG_ERROR",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_LOG_HAL_MBOX_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_INFO, "HAL_MBOX_ERROR",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
@@ -412,6 +449,55 @@ struct bfa_log_msgdef_s bfa_log_msg_array[] = {
((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_P << BFA_LOG_ARG1) |
(BFA_LOG_X << BFA_LOG_ARG2) | 0), 3},
+{BFA_LOG_LINUX_DRIVER_CONFIG_ERROR,
+ BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
+ "LINUX_DRIVER_CONFIG_ERROR",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_LOG_LINUX_BNA_STATE_MACHINE,
+ BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
+ "LINUX_BNA_STATE_MACHINE",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_LOG_LINUX_IOC_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_INFO, "LINUX_IOC_ERROR",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_LOG_LINUX_RESOURCE_ALLOC_ERROR,
+ BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
+ "LINUX_RESOURCE_ALLOC_ERROR",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_LOG_LINUX_RING_BUFFER_ERROR,
+ BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
+ "LINUX_RING_BUFFER_ERROR",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_LOG_LINUX_DRIVER_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_ERROR, "LINUX_DRIVER_ERROR",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_LOG_LINUX_DRIVER_INFO, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_INFO, "LINUX_DRIVER_INFO",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_LOG_LINUX_DRIVER_DIAG, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_INFO, "LINUX_DRIVER_DIAG",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
+{BFA_LOG_LINUX_DRIVER_AEN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
+ BFA_LOG_INFO, "LINUX_DRIVER_AEN",
+ "%s",
+ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
+
diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c
index ad06f618909..acabb44f092 100644
--- a/drivers/scsi/bfa/bfa_lps.c
+++ b/drivers/scsi/bfa/bfa_lps.c
@@ -41,7 +41,6 @@ static void bfa_lps_attach(struct bfa_s *bfa, void *bfad,
struct bfa_iocfc_cfg_s *cfg,
struct bfa_meminfo_s *meminfo,
struct bfa_pcidev_s *pcidev);
-static void bfa_lps_initdone(struct bfa_s *bfa);
static void bfa_lps_detach(struct bfa_s *bfa);
static void bfa_lps_start(struct bfa_s *bfa);
static void bfa_lps_stop(struct bfa_s *bfa);
@@ -347,11 +346,6 @@ bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
}
static void
-bfa_lps_initdone(struct bfa_s *bfa)
-{
-}
-
-static void
bfa_lps_detach(struct bfa_s *bfa)
{
}
diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c
index cab19028361..c7e69f1e56e 100644
--- a/drivers/scsi/bfa/bfa_port.c
+++ b/drivers/scsi/bfa/bfa_port.c
@@ -102,9 +102,14 @@ bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
port->stats_busy = BFA_FALSE;
if (status == BFA_STATUS_OK) {
+ struct bfa_timeval_s tv;
+
memcpy(port->stats, port->stats_dma.kva,
sizeof(union bfa_pport_stats_u));
bfa_port_stats_swap(port, port->stats);
+
+ bfa_os_gettimeofday(&tv);
+ port->stats->fc.secs_reset = tv.tv_sec - port->stats_reset_time;
}
if (port->stats_cbfn) {
@@ -125,9 +130,17 @@ bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
static void
bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
{
+ struct bfa_timeval_s tv;
+
port->stats_status = status;
port->stats_busy = BFA_FALSE;
+ /**
+ * re-initialize time stamp for stats reset
+ */
+ bfa_os_gettimeofday(&tv);
+ port->stats_reset_time = tv.tv_sec;
+
if (port->stats_cbfn) {
port->stats_cbfn(port->stats_cbarg, status);
port->stats_cbfn = NULL;
@@ -394,7 +407,7 @@ bfa_port_hbfail(void *arg)
*/
if (port->stats_busy) {
if (port->stats_cbfn)
- port->stats_cbfn(port->dev, BFA_STATUS_FAILED);
+ port->stats_cbfn(port->stats_cbarg, BFA_STATUS_FAILED);
port->stats_cbfn = NULL;
port->stats_busy = BFA_FALSE;
}
@@ -404,7 +417,7 @@ bfa_port_hbfail(void *arg)
*/
if (port->endis_pending) {
if (port->endis_cbfn)
- port->endis_cbfn(port->dev, BFA_STATUS_FAILED);
+ port->endis_cbfn(port->endis_cbarg, BFA_STATUS_FAILED);
port->endis_cbfn = NULL;
port->endis_pending = BFA_FALSE;
}
@@ -428,6 +441,8 @@ void
bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, void *dev,
struct bfa_trc_mod_s *trcmod, struct bfa_log_mod_s *logmod)
{
+ struct bfa_timeval_s tv;
+
bfa_assert(port);
port->dev = dev;
@@ -435,13 +450,21 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, void *dev,
port->trcmod = trcmod;
port->logmod = logmod;
- port->stats_busy = port->endis_pending = BFA_FALSE;
- port->stats_cbfn = port->endis_cbfn = NULL;
+ port->stats_busy = BFA_FALSE;
+ port->endis_pending = BFA_FALSE;
+ port->stats_cbfn = NULL;
+ port->endis_cbfn = NULL;
bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
bfa_ioc_hbfail_init(&port->hbfail, bfa_port_hbfail, port);
bfa_ioc_hbfail_register(port->ioc, &port->hbfail);
+ /**
+ * initialize time stamp for stats reset
+ */
+ bfa_os_gettimeofday(&tv);
+ port->stats_reset_time = tv.tv_sec;
+
bfa_trc(port, 0);
}
diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h
index 40e256ec67f..c9ebe0426fa 100644
--- a/drivers/scsi/bfa/bfa_port_priv.h
+++ b/drivers/scsi/bfa/bfa_port_priv.h
@@ -75,8 +75,9 @@ struct bfa_fcport_s {
bfa_status_t stats_status; /* stats/statsclr status */
bfa_boolean_t stats_busy; /* outstanding stats/statsclr */
bfa_boolean_t stats_qfull;
+ u32 stats_reset_time; /* stats reset time stamp */
bfa_cb_pport_t stats_cbfn; /* driver callback function */
- void *stats_cbarg; /* *!< user callback arg */
+ void *stats_cbarg; /* user callback arg */
bfa_boolean_t diag_busy; /* diag busy status */
bfa_boolean_t beacon; /* port beacon status */
bfa_boolean_t link_e2e_beacon; /* link beacon status */
@@ -87,5 +88,7 @@ struct bfa_fcport_s {
/*
* public functions
*/
-void bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
+void bfa_fcport_init(struct bfa_s *bfa);
+void bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
+
#endif /* __BFA_PORT_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_priv.h b/drivers/scsi/bfa/bfa_priv.h
index be80fc7e1b0..bf4939b1676 100644
--- a/drivers/scsi/bfa/bfa_priv.h
+++ b/drivers/scsi/bfa/bfa_priv.h
@@ -37,7 +37,6 @@
void *bfad, struct bfa_iocfc_cfg_s *cfg, \
struct bfa_meminfo_s *meminfo, \
struct bfa_pcidev_s *pcidev); \
- static void bfa_ ## __mod ## _initdone(struct bfa_s *bfa); \
static void bfa_ ## __mod ## _detach(struct bfa_s *bfa); \
static void bfa_ ## __mod ## _start(struct bfa_s *bfa); \
static void bfa_ ## __mod ## _stop(struct bfa_s *bfa); \
@@ -47,7 +46,6 @@
struct bfa_module_s hal_mod_ ## __mod = { \
bfa_ ## __mod ## _meminfo, \
bfa_ ## __mod ## _attach, \
- bfa_ ## __mod ## _initdone, \
bfa_ ## __mod ## _detach, \
bfa_ ## __mod ## _start, \
bfa_ ## __mod ## _stop, \
@@ -69,7 +67,6 @@ struct bfa_module_s {
struct bfa_iocfc_cfg_s *cfg,
struct bfa_meminfo_s *meminfo,
struct bfa_pcidev_s *pcidev);
- void (*initdone) (struct bfa_s *bfa);
void (*detach) (struct bfa_s *bfa);
void (*start) (struct bfa_s *bfa);
void (*stop) (struct bfa_s *bfa);
diff --git a/drivers/scsi/bfa/bfa_rport.c b/drivers/scsi/bfa/bfa_rport.c
index 7c509fa244e..ccd0680f6f1 100644
--- a/drivers/scsi/bfa/bfa_rport.c
+++ b/drivers/scsi/bfa/bfa_rport.c
@@ -636,11 +636,6 @@ bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
}
static void
-bfa_rport_initdone(struct bfa_s *bfa)
-{
-}
-
-static void
bfa_rport_detach(struct bfa_s *bfa)
{
}
diff --git a/drivers/scsi/bfa/bfa_sgpg.c b/drivers/scsi/bfa/bfa_sgpg.c
index 279d8f9b890..ae452c42e40 100644
--- a/drivers/scsi/bfa/bfa_sgpg.c
+++ b/drivers/scsi/bfa/bfa_sgpg.c
@@ -94,11 +94,6 @@ bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
}
static void
-bfa_sgpg_initdone(struct bfa_s *bfa)
-{
-}
-
-static void
bfa_sgpg_detach(struct bfa_s *bfa)
{
}
diff --git a/drivers/scsi/bfa/bfa_uf.c b/drivers/scsi/bfa/bfa_uf.c
index 4b3c2417d18..b9a9a686ef6 100644
--- a/drivers/scsi/bfa/bfa_uf.c
+++ b/drivers/scsi/bfa/bfa_uf.c
@@ -170,11 +170,6 @@ bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
}
static void
-bfa_uf_initdone(struct bfa_s *bfa)
-{
-}
-
-static void
bfa_uf_detach(struct bfa_s *bfa)
{
}
@@ -256,7 +251,10 @@ uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m)
(struct fchs_s *) buf, pld_w0);
}
- bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf);
+ if (bfa->fcs)
+ __bfa_cb_uf_recv(uf, BFA_TRUE);
+ else
+ bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf);
}
static void
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index d4fc4287ebd..ca04cc9d332 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -54,31 +54,62 @@ static int bfa_io_max_sge = BFAD_IO_MAX_SGE;
static int log_level = BFA_LOG_WARNING;
static int ioc_auto_recover = BFA_TRUE;
static int ipfc_enable = BFA_FALSE;
-static int ipfc_mtu = -1;
static int fdmi_enable = BFA_TRUE;
int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
int bfa_linkup_delay = -1;
+int bfa_debugfs_enable = 1;
module_param(os_name, charp, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(os_name, "OS name of the hba host machine");
module_param(os_patch, charp, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(os_patch, "OS patch level of the hba host machine");
module_param(host_name, charp, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(host_name, "Hostname of the hba host machine");
module_param(num_rports, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(num_rports, "Max number of rports supported per port"
+ " (physical/logical), default=1024");
module_param(num_ios, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(num_ios, "Max number of ioim requests, default=2000");
module_param(num_tms, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(num_tms, "Max number of task im requests, default=128");
module_param(num_fcxps, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(num_fcxps, "Max number of fcxp requests, default=64");
module_param(num_ufbufs, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(num_ufbufs, "Max number of unsolicited frame buffers,"
+ " default=64");
module_param(reqq_size, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(reqq_size, "Max number of request queue elements,"
+ " default=256");
module_param(rspq_size, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(rspq_size, "Max number of response queue elements,"
+ " default=64");
module_param(num_sgpgs, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(num_sgpgs, "Number of scatter/gather pages, default=2048");
module_param(rport_del_timeout, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(rport_del_timeout, "Rport delete timeout, default=90 secs,"
+ " Range[>0]");
module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32,"
+ " Range[>0]");
module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255");
module_param(log_level, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(log_level, "Driver log level, default=3,"
+ " Range[Critical:1|Error:2|Warning:3|Info:4]");
module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1,"
+ " Range[off:0|on:1]");
module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
-module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
-module_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ipfc_enable, "Enable IPoFC, default=0, Range[off:0|on:1]");
module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(bfa_linkup_delay, "Link up delay, default=30 secs for boot"
+ " port. Otherwise Range[>0]");
+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(bfa_debugfs_enable, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(bfa_debugfs_enable, "Enables debugfs feature, default=1,"
+ " Range[false:0|true:1]");
/*
* Stores the module parm num_sgpgs value;
@@ -322,7 +353,31 @@ ext:
return rc;
}
+/**
+ * @brief
+ * FCS PBC VPORT Create
+ */
+void
+bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport)
+{
+
+ struct bfad_pcfg_s *pcfg;
+ pcfg = kzalloc(sizeof(struct bfad_pcfg_s), GFP_ATOMIC);
+ if (!pcfg) {
+ bfa_trc(bfad, 0);
+ return;
+ }
+
+ pcfg->port_cfg.roles = BFA_PORT_ROLE_FCP_IM;
+ pcfg->port_cfg.pwwn = pbc_vport.vp_pwwn;
+ pcfg->port_cfg.nwwn = pbc_vport.vp_nwwn;
+ pcfg->port_cfg.preboot_vp = BFA_TRUE;
+
+ list_add_tail(&pcfg->list_entry, &bfad->pbc_pcfg_list);
+
+ return;
+}
void
bfad_hal_mem_release(struct bfad_s *bfad)
@@ -481,10 +536,10 @@ ext:
*/
bfa_status_t
bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
- struct bfa_port_cfg_s *port_cfg, struct device *dev)
+ struct bfa_port_cfg_s *port_cfg, struct device *dev)
{
struct bfad_vport_s *vport;
- int rc = BFA_STATUS_OK;
+ int rc = BFA_STATUS_OK;
unsigned long flags;
struct completion fcomp;
@@ -496,8 +551,12 @@ bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
vport->drv_port.bfad = bfad;
spin_lock_irqsave(&bfad->bfad_lock, flags);
- rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
- port_cfg, vport);
+ if (port_cfg->preboot_vp == BFA_TRUE)
+ rc = bfa_fcs_pbc_vport_create(&vport->fcs_vport,
+ &bfad->bfa_fcs, vf_id, port_cfg, vport);
+ else
+ rc = bfa_fcs_vport_create(&vport->fcs_vport,
+ &bfad->bfa_fcs, vf_id, port_cfg, vport);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (rc != BFA_STATUS_OK)
@@ -729,6 +788,7 @@ bfad_drv_init(struct bfad_s *bfad)
memset(&driver_info, 0, sizeof(driver_info));
strncpy(driver_info.version, BFAD_DRIVER_VERSION,
sizeof(driver_info.version) - 1);
+ __kernel_param_lock();
if (host_name)
strncpy(driver_info.host_machine_name, host_name,
sizeof(driver_info.host_machine_name) - 1);
@@ -738,6 +798,7 @@ bfad_drv_init(struct bfad_s *bfad)
if (os_patch)
strncpy(driver_info.host_os_patch, os_patch,
sizeof(driver_info.host_os_patch) - 1);
+ __kernel_param_unlock();
strncpy(driver_info.os_device_name, bfad->pci_name,
sizeof(driver_info.os_device_name - 1));
@@ -848,6 +909,10 @@ bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role)
bfad->pport.roles |= BFA_PORT_ROLE_FCP_IM;
}
+ /* Setup the debugfs node for this scsi_host */
+ if (bfa_debugfs_enable)
+ bfad_debugfs_init(&bfad->pport);
+
bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
out:
@@ -857,6 +922,10 @@ out:
void
bfad_uncfg_pport(struct bfad_s *bfad)
{
+ /* Remove the debugfs node for this scsi_host */
+ kfree(bfad->regdata);
+ bfad_debugfs_exit(&bfad->pport);
+
if ((bfad->pport.roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) {
bfad_ipfc_port_delete(bfad, &bfad->pport);
bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IPFC;
@@ -884,6 +953,7 @@ bfa_status_t
bfad_start_ops(struct bfad_s *bfad)
{
int retval;
+ struct bfad_pcfg_s *pcfg, *pcfg_new;
/* PPORT FCS config */
bfad_fcs_port_cfg(bfad);
@@ -901,6 +971,27 @@ bfad_start_ops(struct bfad_s *bfad)
bfad_drv_start(bfad);
+ /* pbc vport creation */
+ list_for_each_entry_safe(pcfg, pcfg_new, &bfad->pbc_pcfg_list,
+ list_entry) {
+ struct fc_vport_identifiers vid;
+ struct fc_vport *fc_vport;
+
+ memset(&vid, 0, sizeof(vid));
+ vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
+ vid.vport_type = FC_PORTTYPE_NPIV;
+ vid.disable = false;
+ vid.node_name = wwn_to_u64((u8 *)&pcfg->port_cfg.nwwn);
+ vid.port_name = wwn_to_u64((u8 *)&pcfg->port_cfg.pwwn);
+ fc_vport = fc_vport_create(bfad->pport.im_port->shost, 0, &vid);
+ if (!fc_vport)
+ printk(KERN_WARNING "bfad%d: failed to create pbc vport"
+ " %llx\n", bfad->inst_no, vid.port_name);
+ list_del(&pcfg->list_entry);
+ kfree(pcfg);
+
+ }
+
/*
* If bfa_linkup_delay is set to -1 default; try to retrive the
* value using the bfad_os_get_linkup_delay(); else use the
@@ -928,7 +1019,7 @@ out_cfg_pport_failure:
}
int
-bfad_worker (void *ptr)
+bfad_worker(void *ptr)
{
struct bfad_s *bfad;
unsigned long flags;
@@ -1031,6 +1122,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
bfad->ref_count = 0;
bfad->pport.bfad = bfad;
+ INIT_LIST_HEAD(&bfad->pbc_pcfg_list);
bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
"bfad_worker");
@@ -1172,6 +1264,14 @@ static struct pci_device_id bfad_id_table[] = {
.class = (PCI_CLASS_SERIAL_FIBER << 8),
.class_mask = ~0,
},
+ {
+ .vendor = BFA_PCI_VENDOR_ID_BROCADE,
+ .device = BFA_PCI_DEVICE_ID_CT_FC,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class = (PCI_CLASS_SERIAL_FIBER << 8),
+ .class_mask = ~0,
+ },
{0, 0},
};
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
index e477bfbfa7d..0818eb07ef8 100644
--- a/drivers/scsi/bfa/bfad_attr.c
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -373,47 +373,53 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
struct bfa_port_cfg_s port_cfg;
+ struct bfad_pcfg_s *pcfg;
int status = 0, rc;
unsigned long flags;
memset(&port_cfg, 0, sizeof(port_cfg));
-
- port_cfg.pwwn = wwn_to_u64((u8 *) &fc_vport->port_name);
- port_cfg.nwwn = wwn_to_u64((u8 *) &fc_vport->node_name);
-
+ u64_to_wwn(fc_vport->node_name, (u8 *)&port_cfg.nwwn);
+ u64_to_wwn(fc_vport->port_name, (u8 *)&port_cfg.pwwn);
if (strlen(vname) > 0)
strcpy((char *)&port_cfg.sym_name, vname);
-
port_cfg.roles = BFA_PORT_ROLE_FCP_IM;
- rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ list_for_each_entry(pcfg, &bfad->pbc_pcfg_list, list_entry) {
+ if (port_cfg.pwwn == pcfg->port_cfg.pwwn) {
+ port_cfg.preboot_vp = pcfg->port_cfg.preboot_vp;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev);
if (rc == BFA_STATUS_OK) {
- struct bfad_vport_s *vport;
+ struct bfad_vport_s *vport;
struct bfa_fcs_vport_s *fcs_vport;
struct Scsi_Host *vshost;
spin_lock_irqsave(&bfad->bfad_lock, flags);
fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0,
port_cfg.pwwn);
- if (fcs_vport == NULL) {
- spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ if (fcs_vport == NULL)
return VPCERR_BAD_WWN;
- }
fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
if (disable) {
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
bfa_fcs_vport_stop(fcs_vport);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
}
- spin_unlock_irqrestore(&bfad->bfad_lock, flags);
vport = fcs_vport->vport_drv;
vshost = vport->drv_port.im_port->shost;
- fc_host_node_name(vshost) = wwn_to_u64((u8 *) &port_cfg.nwwn);
- fc_host_port_name(vshost) = wwn_to_u64((u8 *) &port_cfg.pwwn);
+ fc_host_node_name(vshost) = wwn_to_u64((u8 *)&port_cfg.nwwn);
+ fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn);
fc_vport->dd_data = vport;
vport->drv_port.im_port->fc_vport = fc_vport;
-
} else if (rc == BFA_STATUS_INVALID_WWN)
return VPCERR_BAD_WWN;
else if (rc == BFA_STATUS_VPORT_EXISTS)
@@ -422,7 +428,7 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
return VPCERR_NO_FABRIC_SUPP;
else if (rc == BFA_STATUS_VPORT_WWN_BP)
return VPCERR_BAD_WWN;
- else
+ else
return FC_VPORT_FAILED;
return status;
@@ -449,7 +455,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
port = im_port->port;
vshost = vport->drv_port.im_port->shost;
- pwwn = wwn_to_u64((u8 *) &fc_host_port_name(vshost));
+ u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
spin_lock_irqsave(&bfad->bfad_lock, flags);
fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
@@ -467,6 +473,12 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
rc = bfa_fcs_vport_delete(&vport->fcs_vport);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ if (rc == BFA_STATUS_PBC) {
+ vport->drv_port.flags &= ~BFAD_PORT_DELETE;
+ vport->comp_del = NULL;
+ return -1;
+ }
+
wait_for_completion(vport->comp_del);
free_scsi_host:
@@ -490,7 +502,7 @@ bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable)
vport = (struct bfad_vport_s *)fc_vport->dd_data;
bfad = vport->drv_port.bfad;
vshost = vport->drv_port.im_port->shost;
- pwwn = wwn_to_u64((u8 *) &fc_vport->port_name);
+ u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
spin_lock_irqsave(&bfad->bfad_lock, flags);
fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c
new file mode 100644
index 00000000000..4b82f12aad6
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_debugfs.c
@@ -0,0 +1,547 @@
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/debugfs.h>
+
+#include <bfad_drv.h>
+#include <bfad_im.h>
+
+/*
+ * BFA debufs interface
+ *
+ * To access the interface, debugfs file system should be mounted
+ * if not already mounted using:
+ * mount -t debugfs none /sys/kernel/debug
+ *
+ * BFA Hierarchy:
+ * - bfa/host#
+ * where the host number corresponds to the one under /sys/class/scsi_host/host#
+ *
+ * Debugging service available per host:
+ * fwtrc: To collect current firmware trace.
+ * drvtrc: To collect current driver trace
+ * fwsave: To collect last saved fw trace as a result of firmware crash.
+ * regwr: To write one word to chip register
+ * regrd: To read one or more words from chip register.
+ */
+
+struct bfad_debug_info {
+ char *debug_buffer;
+ void *i_private;
+ int buffer_len;
+};
+
+static int
+bfad_debugfs_open_drvtrc(struct inode *inode, struct file *file)
+{
+ struct bfad_port_s *port = inode->i_private;
+ struct bfad_s *bfad = port->bfad;
+ struct bfad_debug_info *debug;
+
+ debug = kzalloc(sizeof(struct bfad_debug_info), GFP_KERNEL);
+ if (!debug)
+ return -ENOMEM;
+
+ debug->debug_buffer = (void *) bfad->trcmod;
+ debug->buffer_len = sizeof(struct bfa_trc_mod_s);
+
+ file->private_data = debug;
+
+ return 0;
+}
+
+static int
+bfad_debugfs_open_fwtrc(struct inode *inode, struct file *file)
+{
+ struct bfad_port_s *port = inode->i_private;
+ struct bfad_s *bfad = port->bfad;
+ struct bfad_debug_info *fw_debug;
+ unsigned long flags;
+ int rc;
+
+ fw_debug = kzalloc(sizeof(struct bfad_debug_info), GFP_KERNEL);
+ if (!fw_debug)
+ return -ENOMEM;
+
+ fw_debug->buffer_len = sizeof(struct bfa_trc_mod_s);
+
+ fw_debug->debug_buffer = vmalloc(fw_debug->buffer_len);
+ if (!fw_debug->debug_buffer) {
+ kfree(fw_debug);
+ printk(KERN_INFO "bfad[%d]: Failed to allocate fwtrc buffer\n",
+ bfad->inst_no);
+ return -ENOMEM;
+ }
+
+ memset(fw_debug->debug_buffer, 0, fw_debug->buffer_len);
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ rc = bfa_debug_fwtrc(&bfad->bfa,
+ fw_debug->debug_buffer,
+ &fw_debug->buffer_len);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ if (rc != BFA_STATUS_OK) {
+ vfree(fw_debug->debug_buffer);
+ fw_debug->debug_buffer = NULL;
+ kfree(fw_debug);
+ printk(KERN_INFO "bfad[%d]: Failed to collect fwtrc\n",
+ bfad->inst_no);
+ return -ENOMEM;
+ }
+
+ file->private_data = fw_debug;
+
+ return 0;
+}
+
+static int
+bfad_debugfs_open_fwsave(struct inode *inode, struct file *file)
+{
+ struct bfad_port_s *port = inode->i_private;
+ struct bfad_s *bfad = port->bfad;
+ struct bfad_debug_info *fw_debug;
+ unsigned long flags;
+ int rc;
+
+ fw_debug = kzalloc(sizeof(struct bfad_debug_info), GFP_KERNEL);
+ if (!fw_debug)
+ return -ENOMEM;
+
+ fw_debug->buffer_len = sizeof(struct bfa_trc_mod_s);
+
+ fw_debug->debug_buffer = vmalloc(fw_debug->buffer_len);
+ if (!fw_debug->debug_buffer) {
+ kfree(fw_debug);
+ printk(KERN_INFO "bfad[%d]: Failed to allocate fwsave buffer\n",
+ bfad->inst_no);
+ return -ENOMEM;
+ }
+
+ memset(fw_debug->debug_buffer, 0, fw_debug->buffer_len);
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ rc = bfa_debug_fwsave(&bfad->bfa,
+ fw_debug->debug_buffer,
+ &fw_debug->buffer_len);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ if (rc != BFA_STATUS_OK) {
+ vfree(fw_debug->debug_buffer);
+ fw_debug->debug_buffer = NULL;
+ kfree(fw_debug);
+ printk(KERN_INFO "bfad[%d]: Failed to collect fwsave\n",
+ bfad->inst_no);
+ return -ENOMEM;
+ }
+
+ file->private_data = fw_debug;
+
+ return 0;
+}
+
+static int
+bfad_debugfs_open_reg(struct inode *inode, struct file *file)
+{
+ struct bfad_debug_info *reg_debug;
+
+ reg_debug = kzalloc(sizeof(struct bfad_debug_info), GFP_KERNEL);
+ if (!reg_debug)
+ return -ENOMEM;
+
+ reg_debug->i_private = inode->i_private;
+
+ file->private_data = reg_debug;
+
+ return 0;
+}
+
+/* Changes the current file position */
+static loff_t
+bfad_debugfs_lseek(struct file *file, loff_t offset, int orig)
+{
+ struct bfad_debug_info *debug;
+ loff_t pos = file->f_pos;
+
+ debug = file->private_data;
+
+ switch (orig) {
+ case 0:
+ file->f_pos = offset;
+ break;
+ case 1:
+ file->f_pos += offset;
+ break;
+ case 2:
+ file->f_pos = debug->buffer_len - offset;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (file->f_pos < 0 || file->f_pos > debug->buffer_len) {
+ file->f_pos = pos;
+ return -EINVAL;
+ }
+
+ return file->f_pos;
+}
+
+static ssize_t
+bfad_debugfs_read(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *pos)
+{
+ struct bfad_debug_info *debug = file->private_data;
+
+ if (!debug || !debug->debug_buffer)
+ return 0;
+
+ return memory_read_from_buffer(buf, nbytes, pos,
+ debug->debug_buffer, debug->buffer_len);
+}
+
+#define BFA_REG_CT_ADDRSZ (0x40000)
+#define BFA_REG_CB_ADDRSZ (0x20000)
+#define BFA_REG_ADDRSZ(__bfa) \
+ ((bfa_ioc_devid(&(__bfa)->ioc) == BFA_PCI_DEVICE_ID_CT) ? \
+ BFA_REG_CT_ADDRSZ : BFA_REG_CB_ADDRSZ)
+#define BFA_REG_ADDRMSK(__bfa) ((uint32_t)(BFA_REG_ADDRSZ(__bfa) - 1))
+
+static bfa_status_t
+bfad_reg_offset_check(struct bfa_s *bfa, u32 offset, u32 len)
+{
+ u8 area;
+
+ /* check [16:15] */
+ area = (offset >> 15) & 0x7;
+ if (area == 0) {
+ /* PCIe core register */
+ if ((offset + (len<<2)) > 0x8000) /* 8k dwords or 32KB */
+ return BFA_STATUS_EINVAL;
+ } else if (area == 0x1) {
+ /* CB 32 KB memory page */
+ if ((offset + (len<<2)) > 0x10000) /* 8k dwords or 32KB */
+ return BFA_STATUS_EINVAL;
+ } else {
+ /* CB register space 64KB */
+ if ((offset + (len<<2)) > BFA_REG_ADDRMSK(bfa))
+ return BFA_STATUS_EINVAL;
+ }
+ return BFA_STATUS_OK;
+}
+
+static ssize_t
+bfad_debugfs_read_regrd(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *pos)
+{
+ struct bfad_debug_info *regrd_debug = file->private_data;
+ struct bfad_port_s *port = (struct bfad_port_s *)regrd_debug->i_private;
+ struct bfad_s *bfad = port->bfad;
+ ssize_t rc;
+
+ if (!bfad->regdata)
+ return 0;
+
+ rc = memory_read_from_buffer(buf, nbytes, pos,
+ bfad->regdata, bfad->reglen);
+
+ if ((*pos + nbytes) >= bfad->reglen) {
+ kfree(bfad->regdata);
+ bfad->regdata = NULL;
+ bfad->reglen = 0;
+ }
+
+ return rc;
+}
+
+static ssize_t
+bfad_debugfs_write_regrd(struct file *file, const char __user *buf,
+ size_t nbytes, loff_t *ppos)
+{
+ struct bfad_debug_info *regrd_debug = file->private_data;
+ struct bfad_port_s *port = (struct bfad_port_s *)regrd_debug->i_private;
+ struct bfad_s *bfad = port->bfad;
+ struct bfa_s *bfa = &bfad->bfa;
+ struct bfa_ioc_s *ioc = &bfa->ioc;
+ int addr, len, rc, i;
+ u32 *regbuf;
+ void __iomem *rb, *reg_addr;
+ unsigned long flags;
+
+ rc = sscanf(buf, "%x:%x", &addr, &len);
+ if (rc < 2) {
+ printk(KERN_INFO
+ "bfad[%d]: %s failed to read user buf\n",
+ bfad->inst_no, __func__);
+ return -EINVAL;
+ }
+
+ kfree(bfad->regdata);
+ bfad->regdata = NULL;
+ bfad->reglen = 0;
+
+ bfad->regdata = kzalloc(len << 2, GFP_KERNEL);
+ if (!bfad->regdata) {
+ printk(KERN_INFO "bfad[%d]: Failed to allocate regrd buffer\n",
+ bfad->inst_no);
+ return -ENOMEM;
+ }
+
+ bfad->reglen = len << 2;
+ rb = bfa_ioc_bar0(ioc);
+ addr &= BFA_REG_ADDRMSK(bfa);
+
+ /* offset and len sanity check */
+ rc = bfad_reg_offset_check(bfa, addr, len);
+ if (rc) {
+ printk(KERN_INFO "bfad[%d]: Failed reg offset check\n",
+ bfad->inst_no);
+ kfree(bfad->regdata);
+ bfad->regdata = NULL;
+ bfad->reglen = 0;
+ return -EINVAL;
+ }
+
+ reg_addr = rb + addr;
+ regbuf = (u32 *)bfad->regdata;
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ for (i = 0; i < len; i++) {
+ *regbuf = bfa_reg_read(reg_addr);
+ regbuf++;
+ reg_addr += sizeof(u32);
+ }
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ return nbytes;
+}
+
+static ssize_t
+bfad_debugfs_write_regwr(struct file *file, const char __user *buf,
+ size_t nbytes, loff_t *ppos)
+{
+ struct bfad_debug_info *debug = file->private_data;
+ struct bfad_port_s *port = (struct bfad_port_s *)debug->i_private;
+ struct bfad_s *bfad = port->bfad;
+ struct bfa_s *bfa = &bfad->bfa;
+ struct bfa_ioc_s *ioc = &bfa->ioc;
+ int addr, val, rc;
+ void __iomem *reg_addr;
+ unsigned long flags;
+
+ rc = sscanf(buf, "%x:%x", &addr, &val);
+ if (rc < 2) {
+ printk(KERN_INFO
+ "bfad[%d]: %s failed to read user buf\n",
+ bfad->inst_no, __func__);
+ return -EINVAL;
+ }
+
+ addr &= BFA_REG_ADDRMSK(bfa); /* offset only 17 bit and word align */
+
+ /* offset and len sanity check */
+ rc = bfad_reg_offset_check(bfa, addr, 1);
+ if (rc) {
+ printk(KERN_INFO
+ "bfad[%d]: Failed reg offset check\n",
+ bfad->inst_no);
+ return -EINVAL;
+ }
+
+ reg_addr = (uint32_t *) ((uint8_t *) bfa_ioc_bar0(ioc) + addr);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ bfa_reg_write(reg_addr, val);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ return nbytes;
+}
+
+static int
+bfad_debugfs_release(struct inode *inode, struct file *file)
+{
+ struct bfad_debug_info *debug = file->private_data;
+
+ if (!debug)
+ return 0;
+
+ file->private_data = NULL;
+ kfree(debug);
+ return 0;
+}
+
+static int
+bfad_debugfs_release_fwtrc(struct inode *inode, struct file *file)
+{
+ struct bfad_debug_info *fw_debug = file->private_data;
+
+ if (!fw_debug)
+ return 0;
+
+ if (fw_debug->debug_buffer)
+ vfree(fw_debug->debug_buffer);
+
+ file->private_data = NULL;
+ kfree(fw_debug);
+ return 0;
+}
+
+static const struct file_operations bfad_debugfs_op_drvtrc = {
+ .owner = THIS_MODULE,
+ .open = bfad_debugfs_open_drvtrc,
+ .llseek = bfad_debugfs_lseek,
+ .read = bfad_debugfs_read,
+ .release = bfad_debugfs_release,
+};
+
+static const struct file_operations bfad_debugfs_op_fwtrc = {
+ .owner = THIS_MODULE,
+ .open = bfad_debugfs_open_fwtrc,
+ .llseek = bfad_debugfs_lseek,
+ .read = bfad_debugfs_read,
+ .release = bfad_debugfs_release_fwtrc,
+};
+
+static const struct file_operations bfad_debugfs_op_fwsave = {
+ .owner = THIS_MODULE,
+ .open = bfad_debugfs_open_fwsave,
+ .llseek = bfad_debugfs_lseek,
+ .read = bfad_debugfs_read,
+ .release = bfad_debugfs_release_fwtrc,
+};
+
+static const struct file_operations bfad_debugfs_op_regrd = {
+ .owner = THIS_MODULE,
+ .open = bfad_debugfs_open_reg,
+ .llseek = bfad_debugfs_lseek,
+ .read = bfad_debugfs_read_regrd,
+ .write = bfad_debugfs_write_regrd,
+ .release = bfad_debugfs_release,
+};
+
+static const struct file_operations bfad_debugfs_op_regwr = {
+ .owner = THIS_MODULE,
+ .open = bfad_debugfs_open_reg,
+ .llseek = bfad_debugfs_lseek,
+ .write = bfad_debugfs_write_regwr,
+ .release = bfad_debugfs_release,
+};
+
+struct bfad_debugfs_entry {
+ const char *name;
+ mode_t mode;
+ const struct file_operations *fops;
+};
+
+static const struct bfad_debugfs_entry bfad_debugfs_files[] = {
+ { "drvtrc", S_IFREG|S_IRUGO, &bfad_debugfs_op_drvtrc, },
+ { "fwtrc", S_IFREG|S_IRUGO, &bfad_debugfs_op_fwtrc, },
+ { "fwsave", S_IFREG|S_IRUGO, &bfad_debugfs_op_fwsave, },
+ { "regrd", S_IFREG|S_IRUGO|S_IWUSR, &bfad_debugfs_op_regrd, },
+ { "regwr", S_IFREG|S_IWUSR, &bfad_debugfs_op_regwr, },
+};
+
+static struct dentry *bfa_debugfs_root;
+static atomic_t bfa_debugfs_port_count;
+
+inline void
+bfad_debugfs_init(struct bfad_port_s *port)
+{
+ struct bfad_im_port_s *im_port = port->im_port;
+ struct bfad_s *bfad = im_port->bfad;
+ struct Scsi_Host *shost = im_port->shost;
+ const struct bfad_debugfs_entry *file;
+ char name[16];
+ int i;
+
+ if (!bfa_debugfs_enable)
+ return;
+
+ /* Setup the BFA debugfs root directory*/
+ if (!bfa_debugfs_root) {
+ bfa_debugfs_root = debugfs_create_dir("bfa", NULL);
+ atomic_set(&bfa_debugfs_port_count, 0);
+ if (!bfa_debugfs_root) {
+ printk(KERN_WARNING
+ "BFA debugfs root dir creation failed\n");
+ goto err;
+ }
+ }
+
+ /*
+ * Setup the host# directory for the port,
+ * corresponds to the scsi_host num of this port.
+ */
+ snprintf(name, sizeof(name), "host%d", shost->host_no);
+ if (!port->port_debugfs_root) {
+ port->port_debugfs_root =
+ debugfs_create_dir(name, bfa_debugfs_root);
+ if (!port->port_debugfs_root) {
+ printk(KERN_WARNING
+ "BFA host root dir creation failed\n");
+ goto err;
+ }
+
+ atomic_inc(&bfa_debugfs_port_count);
+
+ for (i = 0; i < ARRAY_SIZE(bfad_debugfs_files); i++) {
+ file = &bfad_debugfs_files[i];
+ bfad->bfad_dentry_files[i] =
+ debugfs_create_file(file->name,
+ file->mode,
+ port->port_debugfs_root,
+ port,
+ file->fops);
+ if (!bfad->bfad_dentry_files[i]) {
+ printk(KERN_WARNING
+ "BFA host%d: create %s entry failed\n",
+ shost->host_no, file->name);
+ goto err;
+ }
+ }
+ }
+
+err:
+ return;
+}
+
+inline void
+bfad_debugfs_exit(struct bfad_port_s *port)
+{
+ struct bfad_im_port_s *im_port = port->im_port;
+ struct bfad_s *bfad = im_port->bfad;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bfad_debugfs_files); i++) {
+ if (bfad->bfad_dentry_files[i]) {
+ debugfs_remove(bfad->bfad_dentry_files[i]);
+ bfad->bfad_dentry_files[i] = NULL;
+ }
+ }
+
+ /*
+ * Remove the host# directory for the port,
+ * corresponds to the scsi_host num of this port.
+ */
+ if (port->port_debugfs_root) {
+ debugfs_remove(port->port_debugfs_root);
+ port->port_debugfs_root = NULL;
+ atomic_dec(&bfa_debugfs_port_count);
+ }
+
+ /* Remove the BFA debugfs root directory */
+ if (atomic_read(&bfa_debugfs_port_count) == 0) {
+ debugfs_remove(bfa_debugfs_root);
+ bfa_debugfs_root = NULL;
+ }
+}
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h
index 6c920c1b53a..465b8b86ec9 100644
--- a/drivers/scsi/bfa/bfad_drv.h
+++ b/drivers/scsi/bfa/bfad_drv.h
@@ -46,7 +46,7 @@
#ifdef BFA_DRIVER_VERSION
#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION
#else
-#define BFAD_DRIVER_VERSION "2.1.2.1"
+#define BFAD_DRIVER_VERSION "2.2.2.1"
#endif
@@ -111,6 +111,9 @@ struct bfad_port_s {
struct bfad_im_port_s *im_port; /* IM specific data */
struct bfad_tm_port_s *tm_port; /* TM specific data */
struct bfad_ipfc_port_s *ipfc_port; /* IPFC specific data */
+
+ /* port debugfs specific data */
+ struct dentry *port_debugfs_root;
};
/*
@@ -120,6 +123,8 @@ struct bfad_vport_s {
struct bfad_port_s drv_port;
struct bfa_fcs_vport_s fcs_vport;
struct completion *comp_del;
+ struct list_head list_entry;
+ struct bfa_port_cfg_s port_cfg;
};
/*
@@ -139,18 +144,6 @@ struct bfad_cfg_param_s {
u32 binding_method;
};
-union bfad_tmp_buf {
- /* From struct bfa_adapter_attr_s */
- char manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
- char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
- char model[BFA_ADAPTER_MODEL_NAME_LEN];
- char fw_ver[BFA_VERSION_LEN];
- char optrom_ver[BFA_VERSION_LEN];
-
- /* From struct bfa_ioc_pci_attr_s */
- u8 chip_rev[BFA_IOC_CHIP_REV_LEN]; /* chip revision */
-};
-
/*
* BFAD (PCI function) data structure
*/
@@ -193,8 +186,18 @@ struct bfad_s {
struct bfa_plog_s plog_buf;
int ref_count;
bfa_boolean_t ipfc_enabled;
- union bfad_tmp_buf tmp_buf;
struct fc_host_statistics link_stats;
+ struct list_head pbc_pcfg_list;
+ atomic_t wq_reqcnt;
+ /* debugfs specific data */
+ char *regdata;
+ u32 reglen;
+ struct dentry *bfad_dentry_files[5];
+};
+
+struct bfad_pcfg_s {
+ struct list_head list_entry;
+ struct bfa_port_cfg_s port_cfg;
};
/*
@@ -280,7 +283,9 @@ void bfad_drv_uninit(struct bfad_s *bfad);
void bfad_drv_log_level_set(struct bfad_s *bfad);
bfa_status_t bfad_fc4_module_init(void);
void bfad_fc4_module_exit(void);
-int bfad_worker (void *ptr);
+int bfad_worker(void *ptr);
+void bfad_debugfs_init(struct bfad_port_s *port);
+void bfad_debugfs_exit(struct bfad_port_s *port);
void bfad_pci_remove(struct pci_dev *pdev);
int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid);
@@ -293,6 +298,7 @@ extern struct list_head bfad_list;
extern int bfa_lun_queue_depth;
extern int bfad_supported_fc4s;
extern int bfa_linkup_delay;
+extern int bfa_debugfs_enable;
extern struct mutex bfad_mutex;
#endif /* __BFAD_DRV_H__ */
diff --git a/drivers/scsi/bfa/bfad_fwimg.c b/drivers/scsi/bfa/bfad_fwimg.c
index 2ad65f275a9..1baca1a1208 100644
--- a/drivers/scsi/bfa/bfad_fwimg.c
+++ b/drivers/scsi/bfa/bfad_fwimg.c
@@ -33,16 +33,20 @@
#include <bfa_fwimg_priv.h>
#include <bfa.h>
-u32 bfi_image_ct_size;
-u32 bfi_image_cb_size;
-u32 *bfi_image_ct;
-u32 *bfi_image_cb;
+u32 bfi_image_ct_fc_size;
+u32 bfi_image_ct_cna_size;
+u32 bfi_image_cb_fc_size;
+u32 *bfi_image_ct_fc;
+u32 *bfi_image_ct_cna;
+u32 *bfi_image_cb_fc;
-#define BFAD_FW_FILE_CT "ctfw.bin"
-#define BFAD_FW_FILE_CB "cbfw.bin"
-MODULE_FIRMWARE(BFAD_FW_FILE_CT);
-MODULE_FIRMWARE(BFAD_FW_FILE_CB);
+#define BFAD_FW_FILE_CT_FC "ctfw_fc.bin"
+#define BFAD_FW_FILE_CT_CNA "ctfw_cna.bin"
+#define BFAD_FW_FILE_CB_FC "cbfw_fc.bin"
+MODULE_FIRMWARE(BFAD_FW_FILE_CT_FC);
+MODULE_FIRMWARE(BFAD_FW_FILE_CT_CNA);
+MODULE_FIRMWARE(BFAD_FW_FILE_CB_FC);
u32 *
bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
@@ -74,24 +78,54 @@ error:
u32 *
bfad_get_firmware_buf(struct pci_dev *pdev)
{
- if (pdev->device == BFA_PCI_DEVICE_ID_CT) {
- if (bfi_image_ct_size == 0)
- bfad_read_firmware(pdev, &bfi_image_ct,
- &bfi_image_ct_size, BFAD_FW_FILE_CT);
- return bfi_image_ct;
+ if (pdev->device == BFA_PCI_DEVICE_ID_CT_FC) {
+ if (bfi_image_ct_fc_size == 0)
+ bfad_read_firmware(pdev, &bfi_image_ct_fc,
+ &bfi_image_ct_fc_size, BFAD_FW_FILE_CT_FC);
+ return bfi_image_ct_fc;
+ } else if (pdev->device == BFA_PCI_DEVICE_ID_CT) {
+ if (bfi_image_ct_cna_size == 0)
+ bfad_read_firmware(pdev, &bfi_image_ct_cna,
+ &bfi_image_ct_cna_size, BFAD_FW_FILE_CT_CNA);
+ return bfi_image_ct_cna;
} else {
- if (bfi_image_cb_size == 0)
- bfad_read_firmware(pdev, &bfi_image_cb,
- &bfi_image_cb_size, BFAD_FW_FILE_CB);
- return bfi_image_cb;
+ if (bfi_image_cb_fc_size == 0)
+ bfad_read_firmware(pdev, &bfi_image_cb_fc,
+ &bfi_image_cb_fc_size, BFAD_FW_FILE_CB_FC);
+ return bfi_image_cb_fc;
}
}
u32 *
-bfi_image_ct_get_chunk(u32 off)
-{ return (u32 *)(bfi_image_ct + off); }
+bfi_image_ct_fc_get_chunk(u32 off)
+{ return (u32 *)(bfi_image_ct_fc + off); }
u32 *
-bfi_image_cb_get_chunk(u32 off)
-{ return (u32 *)(bfi_image_cb + off); }
+bfi_image_ct_cna_get_chunk(u32 off)
+{ return (u32 *)(bfi_image_ct_cna + off); }
+u32 *
+bfi_image_cb_fc_get_chunk(u32 off)
+{ return (u32 *)(bfi_image_cb_fc + off); }
+
+uint32_t *
+bfi_image_get_chunk(int type, uint32_t off)
+{
+ switch (type) {
+ case BFI_IMAGE_CT_FC: return bfi_image_ct_fc_get_chunk(off); break;
+ case BFI_IMAGE_CT_CNA: return bfi_image_ct_cna_get_chunk(off); break;
+ case BFI_IMAGE_CB_FC: return bfi_image_cb_fc_get_chunk(off); break;
+ default: return 0; break;
+ }
+}
+
+uint32_t
+bfi_image_get_size(int type)
+{
+ switch (type) {
+ case BFI_IMAGE_CT_FC: return bfi_image_ct_fc_size; break;
+ case BFI_IMAGE_CT_CNA: return bfi_image_ct_cna_size; break;
+ case BFI_IMAGE_CB_FC: return bfi_image_cb_fc_size; break;
+ default: return 0; break;
+ }
+}
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 5b7cf539e50..6ef87f6fcdb 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -291,7 +291,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
struct bfa_tskim_s *tskim;
struct bfad_itnim_s *itnim;
struct bfa_itnim_s *bfa_itnim;
- DECLARE_WAIT_QUEUE_HEAD(wq);
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
int rc = SUCCESS;
unsigned long flags;
enum bfi_tskim_status task_status;
@@ -353,7 +353,7 @@ bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd)
struct bfad_itnim_s *itnim;
unsigned long flags;
u32 i, rc, err_cnt = 0;
- DECLARE_WAIT_QUEUE_HEAD(wq);
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
enum bfi_tskim_status task_status;
spin_lock_irqsave(&bfad->bfad_lock, flags);
@@ -554,7 +554,7 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
im_port->shost->transportt =
bfad_im_scsi_vport_transport_template;
- error = scsi_add_host(im_port->shost, dev);
+ error = scsi_add_host_with_dma(im_port->shost, dev, &bfad->pcidev->dev);
if (error) {
printk(KERN_WARNING "scsi_add_host failure %d\n", error);
goto out_fc_rel;
@@ -567,6 +567,7 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
out_fc_rel:
scsi_host_put(im_port->shost);
+ im_port->shost = NULL;
out_free_idr:
mutex_lock(&bfad_mutex);
idr_remove(&bfad_im_port_index, im_port->idr_id);
@@ -597,10 +598,12 @@ bfad_im_port_delete_handler(struct work_struct *work)
{
struct bfad_im_port_s *im_port =
container_of(work, struct bfad_im_port_s, port_delete_work);
+ struct bfad_s *bfad = im_port->bfad;
if (im_port->port->pvb_type != BFAD_PORT_PHYS_BASE) {
im_port->flags |= BFAD_PORT_DELETE;
fc_vport_terminate(im_port->fc_vport);
+ atomic_dec(&bfad->wq_reqcnt);
}
}
@@ -633,8 +636,11 @@ bfad_im_port_delete(struct bfad_s *bfad, struct bfad_port_s *port)
{
struct bfad_im_port_s *im_port = port->im_port;
- queue_work(bfad->im->drv_workq,
+ if (im_port->port->pvb_type != BFAD_PORT_PHYS_BASE) {
+ atomic_inc(&bfad->wq_reqcnt);
+ queue_work(bfad->im->drv_workq,
&im_port->port_delete_work);
+ }
}
void
@@ -695,12 +701,27 @@ void
bfad_im_probe_undo(struct bfad_s *bfad)
{
if (bfad->im) {
+ while (atomic_read(&bfad->wq_reqcnt)) {
+ printk(KERN_INFO "bfa %s: waiting workq processing,"
+ " wq_reqcnt:%x\n", bfad->pci_name,
+ atomic_read(&bfad->wq_reqcnt));
+ schedule_timeout_uninterruptible(HZ);
+ }
bfad_os_destroy_workq(bfad->im);
kfree(bfad->im);
bfad->im = NULL;
}
}
+/**
+ * Call back function to handle IO redirection state change
+ */
+void
+bfa_cb_ioredirect_state_change(void *hcb_bfad, bfa_boolean_t ioredirect)
+{
+ /* Do nothing */
+}
+
struct Scsi_Host *
bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
{
@@ -1204,9 +1225,9 @@ int
bfad_os_get_linkup_delay(struct bfad_s *bfad)
{
- u8 nwwns = 0;
- wwn_t *wwns;
- int ldelay;
+ u8 nwwns = 0;
+ wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX];
+ int ldelay;
/*
* Querying for the boot target port wwns
@@ -1215,7 +1236,7 @@ bfad_os_get_linkup_delay(struct bfad_s *bfad)
* else => local boot machine set bfa_linkup_delay = 10
*/
- bfa_iocfc_get_bootwwns(&bfad->bfa, &nwwns, &wwns);
+ bfa_iocfc_get_bootwwns(&bfad->bfa, &nwwns, wwns);
if (nwwns > 0) {
/* If boot over SAN; linkup_delay = 30sec */
diff --git a/drivers/scsi/bfa/bfad_im_compat.h b/drivers/scsi/bfa/bfad_im_compat.h
index b36be15044a..0a122abbbe8 100644
--- a/drivers/scsi/bfa/bfad_im_compat.h
+++ b/drivers/scsi/bfa/bfad_im_compat.h
@@ -18,9 +18,6 @@
#ifndef __BFAD_IM_COMPAT_H__
#define __BFAD_IM_COMPAT_H__
-extern u32 *bfi_image_buf;
-extern u32 bfi_image_size;
-
extern struct device_attribute *bfad_im_host_attrs[];
extern struct device_attribute *bfad_im_vport_attrs[];
@@ -37,10 +34,12 @@ bfad_load_fwimg(struct pci_dev *pdev)
static inline void
bfad_free_fwimg(void)
{
- if (bfi_image_ct_size && bfi_image_ct)
- vfree(bfi_image_ct);
- if (bfi_image_cb_size && bfi_image_cb)
- vfree(bfi_image_cb);
+ if (bfi_image_ct_fc_size && bfi_image_ct_fc)
+ vfree(bfi_image_ct_fc);
+ if (bfi_image_ct_cna_size && bfi_image_ct_cna)
+ vfree(bfi_image_ct_cna);
+ if (bfi_image_cb_fc_size && bfi_image_cb_fc)
+ vfree(bfi_image_cb_fc);
}
#endif
diff --git a/drivers/scsi/bfa/bfad_intr.c b/drivers/scsi/bfa/bfad_intr.c
index 2b7dbecbebc..56a351584f0 100644
--- a/drivers/scsi/bfa/bfad_intr.c
+++ b/drivers/scsi/bfa/bfad_intr.c
@@ -26,7 +26,11 @@ BFA_TRC_FILE(LDRV, INTR);
static int msix_disable_cb;
static int msix_disable_ct;
module_param(msix_disable_cb, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(msix_disable_cb, "Disable MSIX for Brocade-415/425/815/825"
+ " cards, default=0, Range[false:0|true:1]");
module_param(msix_disable_ct, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(msix_disable_ct, "Disable MSIX for Brocade-1010/1020/804"
+ " cards, default=0, Range[false:0|true:1]");
/**
* Line based interrupt handler.
*/
@@ -151,8 +155,8 @@ bfad_setup_intr(struct bfad_s *bfad)
/* Set up the msix entry table */
bfad_init_msix_entry(bfad, msix_entries, mask, max_bit);
- if ((pdev->device == BFA_PCI_DEVICE_ID_CT && !msix_disable_ct) ||
- (pdev->device != BFA_PCI_DEVICE_ID_CT && !msix_disable_cb)) {
+ if ((bfa_asic_id_ct(pdev->device) && !msix_disable_ct) ||
+ (!bfa_asic_id_ct(pdev->device) && !msix_disable_cb)) {
error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
if (error) {
diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c
index 8166e9745ec..ddd4ba9317e 100644
--- a/drivers/scsi/bfa/fabric.c
+++ b/drivers/scsi/bfa/fabric.c
@@ -789,7 +789,7 @@ bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
list_for_each_safe(qe, qen, &fabric->vport_q) {
vport = (struct bfa_fcs_vport_s *)qe;
- bfa_fcs_vport_delete(vport);
+ bfa_fcs_vport_fcs_delete(vport);
}
bfa_fcs_port_delete(&fabric->bport);
@@ -1027,6 +1027,32 @@ bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric)
return fabric->num_vports;
}
+/*
+ * Get OUI of the attached switch.
+ *
+ * Note : Use of this function should be avoided as much as possible.
+ * This function should be used only if there is any requirement
+ * to check for FOS version below 6.3.
+ * To check if the attached fabric is a brocade fabric, use
+ * bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
+ * or above only.
+ */
+
+u16
+bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
+{
+ wwn_t fab_nwwn;
+ u8 *tmp;
+ u16 oui;
+
+ fab_nwwn = bfa_lps_get_peer_nwwn(fabric->lps);
+
+ tmp = (uint8_t *)&fab_nwwn;
+ oui = (tmp[3] << 8) | tmp[4];
+
+ return oui;
+}
+
/**
* Unsolicited frame receive handling.
*/
@@ -1271,6 +1297,22 @@ bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
}
/**
+ *
+ * @param[in] fabric - fabric
+ * @param[in] node_symname -
+ * Caller allocated buffer to receive the symbolic name
+ *
+ * @return - none
+ */
+void
+bfa_fcs_get_sym_name(const struct bfa_fcs_s *fcs, char *node_symname)
+{
+ bfa_os_memcpy(node_symname,
+ fcs->fabric.bport.port_cfg.sym_name.symname,
+ BFA_SYMNAME_MAXLEN);
+}
+
+/**
* Not used by FCS.
*/
void
diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c
index 8ae4a2cfa85..6b8976ad22f 100644
--- a/drivers/scsi/bfa/fcpim.c
+++ b/drivers/scsi/bfa/fcpim.c
@@ -110,6 +110,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
switch (event) {
case BFA_FCS_ITNIM_SM_ONLINE:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
+ itnim->prli_retries = 0;
bfa_fcs_itnim_send_prli(itnim, NULL);
break;
@@ -174,8 +175,12 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
switch (event) {
case BFA_FCS_ITNIM_SM_RSP_OK:
- bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
- bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
+ if (itnim->rport->scsi_function == BFA_RPORT_INITIATOR) {
+ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
+ } else {
+ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
+ bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
+ }
break;
case BFA_FCS_ITNIM_SM_RSP_ERROR:
@@ -193,9 +198,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
case BFA_FCS_ITNIM_SM_INITIATOR:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
- /*
- * dont discard fcxp. accept will reach same state
- */
+ bfa_fcxp_discard(itnim->fcxp);
break;
case BFA_FCS_ITNIM_SM_DELETE:
@@ -218,8 +221,16 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
switch (event) {
case BFA_FCS_ITNIM_SM_TIMEOUT:
- bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
- bfa_fcs_itnim_send_prli(itnim, NULL);
+ if (itnim->prli_retries < BFA_FCS_RPORT_MAX_RETRIES) {
+ itnim->prli_retries++;
+ bfa_trc(itnim->fcs, itnim->prli_retries);
+ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
+ bfa_fcs_itnim_send_prli(itnim, NULL);
+ } else {
+ /* invoke target offline */
+ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
+ bfa_fcs_rport_logo_imp(itnim->rport);
+ }
break;
case BFA_FCS_ITNIM_SM_OFFLINE:
@@ -422,7 +433,7 @@ bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, port->lp_tag,
BFA_FALSE, FC_CLASS_3, len, &fchs,
bfa_fcs_itnim_prli_response, (void *)itnim, FC_MAX_PDUSZ,
- FC_RA_TOV);
+ FC_ELS_TOV);
itnim->stats.prli_sent++;
bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_FRMSENT);
@@ -467,7 +478,7 @@ bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
BFA_RPORT_INITIATOR;
itnim->stats.prli_rsp_acc++;
bfa_sm_send_event(itnim,
- BFA_FCS_ITNIM_SM_INITIATOR);
+ BFA_FCS_ITNIM_SM_RSP_OK);
return;
}
@@ -738,6 +749,7 @@ bfa_fcs_itnim_attr_get(struct bfa_fcs_port_s *port, wwn_t rpwwn,
attr->rec_support = itnim->rec_support;
attr->conf_comp = itnim->conf_comp;
attr->task_retry_id = itnim->task_retry_id;
+ bfa_os_memset(&attr->io_latency, 0, sizeof(struct bfa_itnim_latency_s));
return BFA_STATUS_OK;
}
@@ -793,7 +805,7 @@ bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs,
switch (els_cmd->els_code) {
case FC_ELS_PRLO:
- /* bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_PRLO); */
+ bfa_fcs_rport_prlo(itnim->rport, fchs->ox_id);
break;
default:
diff --git a/drivers/scsi/bfa/fcs_fabric.h b/drivers/scsi/bfa/fcs_fabric.h
index 244c3f00c50..432ab8ab8c3 100644
--- a/drivers/scsi/bfa/fcs_fabric.h
+++ b/drivers/scsi/bfa/fcs_fabric.h
@@ -26,6 +26,8 @@
#include <fcs/bfa_fcs_vport.h>
#include <fcs/bfa_fcs_lport.h>
+#define BFA_FCS_BRCD_SWITCH_OUI 0x051e
+
/*
* fcs friend functions: only between fcs modules
*/
@@ -60,4 +62,7 @@ void bfa_fcs_auth_finished(struct bfa_fcs_fabric_s *fabric,
void bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
wwn_t fabric_name);
+u16 bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric);
+void bfa_fcs_get_sym_name(const struct bfa_fcs_s *fcs, char *node_symname);
+
#endif /* __FCS_FABRIC_H__ */
diff --git a/drivers/scsi/bfa/fcs_rport.h b/drivers/scsi/bfa/fcs_rport.h
index 9c8d1d29238..e634fb7a69b 100644
--- a/drivers/scsi/bfa/fcs_rport.h
+++ b/drivers/scsi/bfa/fcs_rport.h
@@ -24,6 +24,8 @@
#include <fcs/bfa_fcs_rport.h>
+#define BFA_FCS_RPORT_MAX_RETRIES (5)
+
void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
u16 len);
void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport);
@@ -41,6 +43,7 @@ void bfa_fcs_rport_plogi_create(struct bfa_fcs_port_s *port,
void bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
struct fc_logi_s *plogi);
void bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport);
+void bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, uint16_t ox_id);
void bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport);
void bfa_fcs_rport_itntm_ack(struct bfa_fcs_rport_s *rport);
void bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport);
diff --git a/drivers/scsi/bfa/fcs_vport.h b/drivers/scsi/bfa/fcs_vport.h
index 13c32ebf946..bb647a4a5dd 100644
--- a/drivers/scsi/bfa/fcs_vport.h
+++ b/drivers/scsi/bfa/fcs_vport.h
@@ -26,6 +26,7 @@ void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport);
+void bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport);
#endif /* __FCS_VPORT_H__ */
diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c
index 8f17076d1a8..2b50eabf4b1 100644
--- a/drivers/scsi/bfa/fdmi.c
+++ b/drivers/scsi/bfa/fdmi.c
@@ -532,7 +532,7 @@ bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, (len + attr_len), &fchs,
bfa_fcs_port_fdmi_rhba_response, (void *)fdmi,
- FC_MAX_PDUSZ, FC_RA_TOV);
+ FC_MAX_PDUSZ, FC_FCCT_TOV);
bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
}
@@ -823,7 +823,7 @@ bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len + attr_len, &fchs,
bfa_fcs_port_fdmi_rprt_response, (void *)fdmi,
- FC_MAX_PDUSZ, FC_RA_TOV);
+ FC_MAX_PDUSZ, FC_FCCT_TOV);
bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
}
@@ -1043,7 +1043,7 @@ bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len + attr_len, &fchs,
bfa_fcs_port_fdmi_rpa_response, (void *)fdmi,
- FC_MAX_PDUSZ, FC_RA_TOV);
+ FC_MAX_PDUSZ, FC_FCCT_TOV);
bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
}
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h b/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h
index 71378b446b6..4daf96faa26 100644
--- a/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h
@@ -32,6 +32,14 @@
BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_DISABLE)
#define BFA_AEN_IOC_FWMISMATCH \
BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_FWMISMATCH)
+#define BFA_AEN_IOC_FWCFG_ERROR \
+ BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_FWCFG_ERROR)
+#define BFA_AEN_IOC_INVALID_VENDOR \
+ BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_INVALID_VENDOR)
+#define BFA_AEN_IOC_INVALID_NWWN \
+ BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_INVALID_NWWN)
+#define BFA_AEN_IOC_INVALID_PWWN \
+ BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_INVALID_PWWN)
#endif
diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h
index 1f5966cfbd1..d52b32f5695 100644
--- a/drivers/scsi/bfa/include/bfa.h
+++ b/drivers/scsi/bfa/include/bfa.h
@@ -126,6 +126,10 @@ struct bfa_sge_s {
bfa_ioc_get_type(&(__bfa)->ioc)
#define bfa_get_mac(__bfa) \
bfa_ioc_get_mac(&(__bfa)->ioc)
+#define bfa_get_mfg_mac(__bfa) \
+ bfa_ioc_get_mfg_mac(&(__bfa)->ioc)
+#define bfa_get_fw_clock_res(__bfa) \
+ ((__bfa)->iocfc.cfgrsp->fwcfg.fw_tick_res)
/*
* bfa API functions
diff --git a/drivers/scsi/bfa/include/bfa_fcpim.h b/drivers/scsi/bfa/include/bfa_fcpim.h
index 04789795fa5..4bc9453081d 100644
--- a/drivers/scsi/bfa/include/bfa_fcpim.h
+++ b/drivers/scsi/bfa/include/bfa_fcpim.h
@@ -42,6 +42,24 @@ u16 bfa_fcpim_qdepth_get(struct bfa_s *bfa);
bfa_status_t bfa_fcpim_get_modstats(struct bfa_s *bfa,
struct bfa_fcpim_stats_s *modstats);
bfa_status_t bfa_fcpim_clr_modstats(struct bfa_s *bfa);
+void bfa_fcpim_set_ioredirect(struct bfa_s *bfa, bfa_boolean_t state);
+void bfa_fcpim_update_ioredirect(struct bfa_s *bfa);
+void bfa_cb_ioredirect_state_change(void *hcb_bfad, bfa_boolean_t ioredirect);
+
+#define bfa_fcpim_ioredirect_enabled(__bfa) \
+ (((struct bfa_fcpim_mod_s *)(BFA_FCPIM_MOD(__bfa)))->ioredirect)
+
+#define bfa_fcpim_get_next_reqq(__bfa, __qid) \
+{ \
+ struct bfa_fcpim_mod_s *__fcpim = BFA_FCPIM_MOD(__bfa); \
+ __fcpim->reqq++; \
+ __fcpim->reqq &= (BFI_IOC_MAX_CQS - 1); \
+ *(__qid) = __fcpim->reqq; \
+}
+
+#define bfa_iocfc_map_msg_to_qid(__msg, __qid) \
+ *(__qid) = (u8)((__msg) & (BFI_IOC_MAX_CQS - 1));
+
/*
* bfa itnim API functions
@@ -56,6 +74,7 @@ void bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
struct bfa_itnim_hal_stats_s *stats);
void bfa_itnim_clear_stats(struct bfa_itnim_s *itnim);
+#define bfa_itnim_get_reqq(__ioim) (((struct bfa_ioim_s *)__ioim)->itnim->reqq)
/**
* BFA completion callback for bfa_itnim_online().
@@ -156,4 +175,3 @@ void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
enum bfi_tskim_status tsk_status);
#endif /* __BFA_FCPIM_H__ */
-
diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h
index 1349b99a3c6..7840943d73b 100644
--- a/drivers/scsi/bfa/include/bfa_svc.h
+++ b/drivers/scsi/bfa/include/bfa_svc.h
@@ -215,6 +215,7 @@ bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa,
bfa_cb_pport_t cbfn, void *cbarg);
bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
void *cbarg);
+bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa);
/*
* bfa rport API functions
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
index 57a8497105a..c0ef5a93b79 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
@@ -455,6 +455,9 @@ enum {
#define __PSS_LPU0_RAM_ERR 0x00000001
#define ERR_SET_REG 0x00018818
#define __PSS_ERR_STATUS_SET 0x003fffff
+#define PMM_1T_RESET_REG_P0 0x0002381c
+#define __PMM_1T_RESET_P 0x00000001
+#define PMM_1T_RESET_REG_P1 0x00023c1c
#define HQM_QSET0_RXQ_DRBL_P0 0x00038000
#define __RXQ0_ADD_VECTORS_P 0x80000000
#define __RXQ0_STOP_P 0x40000000
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ioc.h b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
index a0158aac002..450ded6e9bc 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_ioc.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
@@ -48,9 +48,14 @@ struct bfi_ioc_getattr_req_s {
};
struct bfi_ioc_attr_s {
- wwn_t mfg_wwn;
- mac_t mfg_mac;
- u16 rsvd_a;
+ wwn_t mfg_pwwn; /* Mfg port wwn */
+ wwn_t mfg_nwwn; /* Mfg node wwn */
+ mac_t mfg_mac; /* Mfg mac */
+ u16 rsvd_a;
+ wwn_t pwwn;
+ wwn_t nwwn;
+ mac_t mac; /* PBC or Mfg mac */
+ u16 rsvd_b;
char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)];
u8 pcie_gen;
u8 pcie_lanes_orig;
@@ -58,11 +63,12 @@ struct bfi_ioc_attr_s {
u8 rx_bbcredit; /* receive buffer credits */
u32 adapter_prop; /* adapter properties */
u16 maxfrsize; /* max receive frame size */
- char asic_rev;
- u8 rsvd_b;
- char fw_version[BFA_VERSION_LEN];
- char optrom_version[BFA_VERSION_LEN];
+ char asic_rev;
+ u8 rsvd_c;
+ char fw_version[BFA_VERSION_LEN];
+ char optrom_version[BFA_VERSION_LEN];
struct bfa_mfg_vpd_s vpd;
+ u32 card_type; /* card type */
};
/**
diff --git a/drivers/scsi/bfa/include/bfi/bfi_iocfc.h b/drivers/scsi/bfa/include/bfi/bfi_iocfc.h
index c3760df7257..ccdfcc5d7e0 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_iocfc.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_iocfc.h
@@ -19,6 +19,7 @@
#define __BFI_IOCFC_H__
#include "bfi.h"
+#include <bfi/bfi_pbc.h>
#include <defs/bfa_defs_ioc.h>
#include <defs/bfa_defs_iocfc.h>
#include <defs/bfa_defs_boot.h>
@@ -78,6 +79,7 @@ struct bfi_iocfc_cfgrsp_s {
struct bfa_iocfc_fwcfg_s fwcfg;
struct bfa_iocfc_intr_attr_s intr_attr;
struct bfi_iocfc_bootwwns bootwwns;
+ struct bfi_pbc_s pbc_cfg;
};
/**
diff --git a/drivers/scsi/bfa/include/bfi/bfi_pbc.h b/drivers/scsi/bfa/include/bfi/bfi_pbc.h
new file mode 100644
index 00000000000..88a4154c30c
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_pbc.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __BFI_PBC_H__
+#define __BFI_PBC_H__
+
+#pragma pack(1)
+
+#define BFI_PBC_MAX_BLUNS 8
+#define BFI_PBC_MAX_VPORTS 16
+
+#define BFI_PBC_PORT_DISABLED 2
+/**
+ * PBC boot lun configuration
+ */
+struct bfi_pbc_blun_s {
+ wwn_t tgt_pwwn;
+ lun_t tgt_lun;
+};
+
+/**
+ * PBC virtual port configuration
+ */
+struct bfi_pbc_vport_s {
+ wwn_t vp_pwwn;
+ wwn_t vp_nwwn;
+};
+
+/**
+ * BFI pre-boot configuration information
+ */
+struct bfi_pbc_s {
+ u8 port_enabled;
+ u8 boot_enabled;
+ u8 nbluns;
+ u8 nvports;
+ u8 port_speed;
+ u8 rsvd_a;
+ u16 hss;
+ wwn_t pbc_pwwn;
+ wwn_t pbc_nwwn;
+ struct bfi_pbc_blun_s blun[BFI_PBC_MAX_BLUNS];
+ struct bfi_pbc_vport_s vport[BFI_PBC_MAX_VPORTS];
+};
+
+#pragma pack()
+
+#endif /* __BFI_PBC_H__ */
diff --git a/drivers/scsi/bfa/include/cna/port/bfa_port.h b/drivers/scsi/bfa/include/cna/port/bfa_port.h
index 7cbf17d3141..d7babaf9784 100644
--- a/drivers/scsi/bfa/include/cna/port/bfa_port.h
+++ b/drivers/scsi/bfa/include/cna/port/bfa_port.h
@@ -37,6 +37,7 @@ struct bfa_port_s {
bfa_port_stats_cbfn_t stats_cbfn;
void *stats_cbarg;
bfa_status_t stats_status;
+ u32 stats_reset_time;
union bfa_pport_stats_u *stats;
struct bfa_dma_s stats_dma;
bfa_boolean_t endis_pending;
diff --git a/drivers/scsi/bfa/include/cs/bfa_debug.h b/drivers/scsi/bfa/include/cs/bfa_debug.h
index 441be86b1b0..75a911ea793 100644
--- a/drivers/scsi/bfa/include/cs/bfa_debug.h
+++ b/drivers/scsi/bfa/include/cs/bfa_debug.h
@@ -28,7 +28,8 @@
} while (0)
#define bfa_sm_fault(__mod, __event) do { \
- bfa_sm_panic((__mod)->logm, __LINE__, __FILE__, __event); \
+ bfa_trc(__mod, (((uint32_t)0xDEAD << 16) | __event)); \
+ bfa_sm_panic((__mod)->logm, __LINE__, __FILE__, __event); \
} while (0)
#ifndef BFA_PERF_BUILD
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h b/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h
index 8c208fc8e32..aea0360d67d 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h
@@ -39,7 +39,7 @@ enum {
struct bfa_adapter_attr_s {
char manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
- u32 rsvd1;
+ u32 card_type;
char model[BFA_ADAPTER_MODEL_NAME_LEN];
char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
wwn_t pwwn;
@@ -60,6 +60,7 @@ struct bfa_adapter_attr_s {
u8 pcie_lanes_orig;
u8 pcie_lanes;
u8 cna_capable;
+ u8 is_mezz;
};
/**
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
index 45df3282091..f56ed871bb9 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
@@ -125,10 +125,10 @@ struct bfa_auth_attr_s {
enum bfa_auth_status status;
enum bfa_auth_algo algo;
enum bfa_auth_group dh_grp;
- u16 rjt_code;
- u16 rjt_code_exp;
+ enum bfa_auth_rej_code rjt_code;
+ enum bfa_auth_rej_code_exp rjt_code_exp;
u8 secret_set;
- u8 resv[7];
+ u8 resv[3];
};
#endif /* __BFA_DEFS_AUTH_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_boot.h b/drivers/scsi/bfa/include/defs/bfa_defs_boot.h
index 6f4aa528354..0fca10b6ad1 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_boot.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_boot.h
@@ -24,6 +24,8 @@
enum {
BFA_BOOT_BOOTLUN_MAX = 4, /* maximum boot lun per IOC */
+ BFA_PREBOOT_BOOTLUN_MAX = 8, /* maximum preboot lun per IOC */
+
};
#define BOOT_CFG_REV1 1
@@ -67,5 +69,13 @@ struct bfa_boot_cfg_s {
struct bfa_boot_bootlun_s blun_disc[BFA_BOOT_BOOTLUN_MAX];
};
+struct bfa_boot_pbc_s {
+ u8 enable; /* enable/disable SAN boot */
+ u8 speed; /* boot speed settings */
+ u8 topology; /* boot topology setting */
+ u8 rsvd1;
+ u32 nbluns; /* number of boot luns */
+ struct bfa_boot_bootlun_s pblun[BFA_PREBOOT_BOOTLUN_MAX];
+};
#endif /* __BFA_DEFS_BOOT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
index 50382dd2ab4..7d00d00d396 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
@@ -29,7 +29,7 @@ struct bfa_driver_stats_s {
u16 tm_target_reset;
u16 tm_bus_reset;
u16 ioc_restart; /* IOC restart count */
- u16 io_pending; /* outstanding io count per-IOC */
+ u16 rsvd;
u64 control_req;
u64 input_req;
u64 output_req;
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h
index a07ef4a3cd7..af86a639643 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h
@@ -48,7 +48,7 @@ struct bfa_fcoe_stats_s {
u64 disc_fcf_unavail; /* Discovery FCF not avail */
u64 linksvc_unsupp; /* FIP link service req unsupp. */
u64 linksvc_err; /* FIP link service req errors */
- u64 logo_req; /* FIP logo */
+ u64 logo_req; /* FIP logos received */
u64 clrvlink_req; /* Clear virtual link requests */
u64 op_unsupp; /* FIP operation unsupp. */
u64 untagged; /* FIP untagged frames */
@@ -64,21 +64,15 @@ struct bfa_fcoe_stats_s {
u64 txf_timeout; /* Tx timeouts */
u64 txf_parity_errors; /* Transmit parity err */
u64 txf_fid_parity_errors; /* Transmit FID parity err */
- u64 tx_pause; /* Tx pause frames */
- u64 tx_zero_pause; /* Tx zero pause frames */
- u64 tx_first_pause; /* Tx first pause frames */
- u64 rx_pause; /* Rx pause frames */
- u64 rx_zero_pause; /* Rx zero pause frames */
- u64 rx_first_pause; /* Rx first pause frames */
- u64 rxf_ucast_octets; /* Rx unicast octets */
- u64 rxf_ucast; /* Rx unicast frames */
- u64 rxf_ucast_vlan; /* Rx unicast vlan frames */
- u64 rxf_mcast_octets; /* Rx multicast octets */
- u64 rxf_mcast; /* Rx multicast frames */
- u64 rxf_mcast_vlan; /* Rx multicast vlan frames */
- u64 rxf_bcast_octets; /* Rx broadcast octests */
- u64 rxf_bcast; /* Rx broadcast frames */
- u64 rxf_bcast_vlan; /* Rx broadcast vlan frames */
+ u64 rxf_ucast_octets; /* Rx FCoE unicast octets */
+ u64 rxf_ucast; /* Rx FCoE unicast frames */
+ u64 rxf_ucast_vlan; /* Rx FCoE unicast vlan frames */
+ u64 rxf_mcast_octets; /* Rx FCoE multicast octets */
+ u64 rxf_mcast; /* Rx FCoE multicast frames */
+ u64 rxf_mcast_vlan; /* Rx FCoE multicast vlan frames */
+ u64 rxf_bcast_octets; /* Rx FCoE broadcast octets */
+ u64 rxf_bcast; /* Rx FCoE broadcast frames */
+ u64 rxf_bcast_vlan; /* Rx FCoE broadcast vlan frames */
};
/**
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
index 8d8e6a96653..add0a05d941 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
@@ -126,7 +126,7 @@ struct bfa_ioc_attr_s {
struct bfa_ioc_driver_attr_s driver_attr; /* driver attr */
struct bfa_ioc_pci_attr_s pci_attr;
u8 port_id; /* port number */
- u8 rsvd[7]; /*!< 64bit align */
+ u8 rsvd[7]; /* 64bit align */
};
/**
@@ -138,6 +138,11 @@ enum bfa_ioc_aen_event {
BFA_IOC_AEN_ENABLE = 3, /* IOC enabled event */
BFA_IOC_AEN_DISABLE = 4, /* IOC disabled event */
BFA_IOC_AEN_FWMISMATCH = 5, /* IOC firmware mismatch */
+ BFA_IOC_AEN_FWCFG_ERROR = 6, /* IOC firmware config error */
+ BFA_IOC_AEN_INVALID_VENDOR = 7,
+ BFA_IOC_AEN_INVALID_NWWN = 8, /* Zero NWWN */
+ BFA_IOC_AEN_INVALID_PWWN = 9 /* Zero PWWN */
+
};
/**
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
index c290fb13d2d..31e728a631e 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
@@ -51,8 +51,10 @@ struct bfa_iocfc_fwcfg_s {
u16 num_tsktm_reqs; /* TM task management requests*/
u16 num_fcxp_reqs; /* unassisted FC exchanges */
u16 num_uf_bufs; /* unsolicited recv buffers */
- u8 num_cqs;
- u8 rsvd[5];
+ u8 num_cqs;
+ u8 fw_tick_res; /*!< FW clock resolution in ms */
+ u8 rsvd[4];
+
};
struct bfa_iocfc_drvcfg_s {
@@ -176,10 +178,10 @@ struct bfa_fw_port_fpg_stats_s {
u32 nos_rx;
u32 lip_rx;
u32 arbf0_rx;
+ u32 arb_rx;
u32 mrk_rx;
u32 const_mrk_rx;
u32 prim_unknown;
- u32 rsvd;
};
@@ -200,6 +202,8 @@ struct bfa_fw_port_lksm_stats_s {
u32 lrr_tx; /* No. of times LRR tx started */
u32 ols_tx; /* No. of times OLS tx started */
u32 nos_tx; /* No. of times NOS tx started */
+ u32 hwsm_lrr_rx; /* No. of times LRR rx-ed by HWSM */
+ u32 hwsm_lr_rx; /* No. of times LR rx-ed by HWSM */
};
@@ -239,7 +243,7 @@ struct bfa_fw_fip_stats_s {
u32 disc_fcf_unavail; /* Discovery FCF Not Avail. */
u32 linksvc_unsupp; /* Unsupported link service req */
u32 linksvc_err; /* Parse error in link service req */
- u32 logo_req; /* Number of FIP logos received */
+ u32 logo_req; /* FIP logos received */
u32 clrvlink_req; /* Clear virtual link req */
u32 op_unsupp; /* Unsupported FIP operation */
u32 untagged; /* Untagged frames (ignored) */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h b/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h
index 2ec769903d2..d77788b3999 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h
@@ -34,6 +34,15 @@ enum bfa_itnim_state {
BFA_ITNIM_INITIATIOR = 7, /* initiator */
};
+struct bfa_itnim_latency_s {
+ u32 min;
+ u32 max;
+ u32 count;
+ u32 clock_res;
+ u32 avg;
+ u32 rsvd;
+};
+
struct bfa_itnim_hal_stats_s {
u32 onlines; /* ITN nexus onlines (PRLI done) */
u32 offlines; /* ITN Nexus offlines */
@@ -91,6 +100,7 @@ struct bfa_itnim_attr_s {
u8 task_retry_id; /* task retry ident support */
u8 rec_support; /* REC supported */
u8 conf_comp; /* confirmed completion supp */
+ struct bfa_itnim_latency_s io_latency; /* IO latency */
};
/**
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
index c5bd9c36ad4..d22fb790964 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
@@ -45,26 +45,6 @@
#define BFA_MFG_CHKSUM_SIZE 16
/**
- * Manufacturing block encrypted version
- */
-#define BFA_MFG_ENC_VER 2
-
-/**
- * Manufacturing block version 1 length
- */
-#define BFA_MFG_VER1_LEN 128
-
-/**
- * Manufacturing block header length
- */
-#define BFA_MFG_HDR_LEN 4
-
-/**
- * Checksum size
- */
-#define BFA_MFG_CHKSUM_SIZE 16
-
-/**
* Manufacturing block format
*/
#define BFA_MFG_SERIALNUM_SIZE 11
@@ -86,6 +66,9 @@ enum {
BFA_MFG_TYPE_FC4P1 = 415, /* 4G 1port FC card */
BFA_MFG_TYPE_CNA10P2 = 1020, /* 10G 2port CNA card */
BFA_MFG_TYPE_CNA10P1 = 1010, /* 10G 1port CNA card */
+ BFA_MFG_TYPE_JAYHAWK = 804, /* Jayhawk mezz card */
+ BFA_MFG_TYPE_WANCHESE = 1007, /* Wanchese mezz card */
+ BFA_MFG_TYPE_INVALID = 0, /* Invalid card type */
};
#pragma pack(1)
@@ -95,6 +78,24 @@ enum {
*/
#define bfa_mfg_type2port_num(card_type) (((card_type) / 10) % 10)
+/**
+ * Check if Mezz card
+ */
+#define bfa_mfg_is_mezz(type) (( \
+ (type) == BFA_MFG_TYPE_JAYHAWK || \
+ (type) == BFA_MFG_TYPE_WANCHESE))
+
+/**
+ * Check if card type valid
+ */
+#define bfa_mfg_is_card_type_valid(type) (( \
+ (type) == BFA_MFG_TYPE_FC8P2 || \
+ (type) == BFA_MFG_TYPE_FC8P1 || \
+ (type) == BFA_MFG_TYPE_FC4P2 || \
+ (type) == BFA_MFG_TYPE_FC4P1 || \
+ (type) == BFA_MFG_TYPE_CNA10P2 || \
+ (type) == BFA_MFG_TYPE_CNA10P1 || \
+ bfa_mfg_is_mezz(type)))
/**
* All numerical fields are in big-endian format.
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pci.h b/drivers/scsi/bfa/include/defs/bfa_defs_pci.h
index c9b83321694..ea7d89bbc0b 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_pci.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pci.h
@@ -26,8 +26,13 @@ enum {
BFA_PCI_DEVICE_ID_FC_8G2P = 0x13,
BFA_PCI_DEVICE_ID_FC_8G1P = 0x17,
BFA_PCI_DEVICE_ID_CT = 0x14,
+ BFA_PCI_DEVICE_ID_CT_FC = 0x21,
};
+#define bfa_asic_id_ct(devid) \
+ ((devid) == BFA_PCI_DEVICE_ID_CT || \
+ (devid) == BFA_PCI_DEVICE_ID_CT_FC)
+
/**
* PCI sub-system device and vendor ID information
*/
@@ -35,7 +40,9 @@ enum {
BFA_PCI_FCOE_SSDEVICE_ID = 0x14,
};
-#define BFA_PCI_ACCESS_RANGES 1 /* Maximum number of device address ranges
- * mapped through different BAR(s). */
+/**
+ * Maximum number of device address ranges mapped through different BAR(s)
+ */
+#define BFA_PCI_ACCESS_RANGES 1
#endif /* __BFA_DEFS_PCI_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_port.h b/drivers/scsi/bfa/include/defs/bfa_defs_port.h
index 501bc9739d9..ebdf0d1731a 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_port.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_port.h
@@ -50,12 +50,12 @@ enum bfa_port_role {
* FCS port configuration.
*/
struct bfa_port_cfg_s {
- wwn_t pwwn; /* port wwn */
- wwn_t nwwn; /* node wwn */
- struct bfa_port_symname_s sym_name; /* vm port symbolic name */
- enum bfa_port_role roles; /* FCS port roles */
- u32 rsvd;
- u8 tag[16]; /* opaque tag from application */
+ wwn_t pwwn; /* port wwn */
+ wwn_t nwwn; /* node wwn */
+ struct bfa_port_symname_s sym_name; /* vm port symbolic name */
+ bfa_boolean_t preboot_vp; /* vport created from PBC */
+ enum bfa_port_role roles; /* FCS port roles */
+ u8 tag[16]; /* opaque tag from application */
};
/**
@@ -159,7 +159,7 @@ struct bfa_port_stats_s {
u32 ms_plogi_rsp_err;
u32 ms_plogi_acc_err;
u32 ms_plogi_accepts;
- u32 ms_rejects; /* NS command rejects */
+ u32 ms_rejects; /* MS command rejects */
u32 ms_plogi_unknown_rsp;
u32 ms_plogi_alloc_wait;
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
index 26e5cc78095..2de675839c2 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
@@ -38,6 +38,7 @@ enum bfa_pport_states {
BFA_PPORT_ST_IOCDOWN = 10,
BFA_PPORT_ST_IOCDIS = 11,
BFA_PPORT_ST_FWMISMATCH = 12,
+ BFA_PPORT_ST_PREBOOT_DISABLED = 13,
BFA_PPORT_ST_MAX_STATE,
};
@@ -203,6 +204,8 @@ struct bfa_pport_attr_s {
*/
wwn_t nwwn; /* node wwn */
wwn_t pwwn; /* port wwn */
+ wwn_t factorynwwn; /* factory node wwn */
+ wwn_t factorypwwn; /* factory port wwn */
enum fc_cos cos_supported; /* supported class of services */
u32 rsvd;
struct fc_symname_s port_symname; /* port symbolic name */
@@ -243,7 +246,7 @@ struct bfa_pport_fc_stats_s {
u64 secs_reset; /* Seconds since stats is reset */
u64 tx_frames; /* Tx frames */
u64 tx_words; /* Tx words */
- u64 tx_lip; /* TX LIP */
+ u64 tx_lip; /* Tx LIP */
u64 tx_nos; /* Tx NOS */
u64 tx_ols; /* Tx OLS */
u64 tx_lr; /* Tx LR */
@@ -309,7 +312,7 @@ struct bfa_pport_eth_stats_s {
u64 rx_zero_pause; /* Rx zero pause */
u64 tx_pause; /* Tx pause */
u64 tx_zero_pause; /* Tx zero pause */
- u64 rx_fcoe_pause; /* Rx fcoe pause */
+ u64 rx_fcoe_pause; /* Rx FCoE pause */
u64 rx_fcoe_zero_pause; /* Rx FCoE zero pause */
u64 tx_fcoe_pause; /* Tx FCoE pause */
u64 tx_fcoe_zero_pause; /* Tx FCoE zero pause */
@@ -381,26 +384,10 @@ struct bfa_pport_link_s {
u8 trunked; /* Trunked or not (1 or 0) */
u8 resvd[3];
struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
- struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
union {
- struct {
- u8 tmaster;/* Trunk Master or
- * not (1 or 0) */
- u8 tlinks; /* Trunk links bitmap
- * (linkup) */
- u8 resv1; /* Reserved */
- } trunk_info;
-
- struct {
- u8 myalpa; /* alpa claimed */
- u8 login_req; /* Login required or
- * not (1 or 0) */
- u8 alpabm_val;/* alpa bitmap valid
- * or not (1 or 0) */
- struct fc_alpabm_s alpabm; /* alpa bitmap */
- } loop_info;
- } tl;
- struct bfa_fcport_fcf_s fcf; /*!< FCF information (for FCoE) */
+ struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
+ struct bfa_fcport_fcf_s fcf; /* FCF information (for FCoE) */
+ } vc_fcf;
};
#endif /* __BFA_DEFS_PPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_status.h b/drivers/scsi/bfa/include/defs/bfa_defs_status.h
index ec78b4cb121..6eb4e62096f 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_status.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_status.h
@@ -84,8 +84,9 @@ enum bfa_status {
BFA_STATUS_BADFRMHDR = 48, /* Bad frame header */
BFA_STATUS_BADFRMSZ = 49, /* Bad frame size check and replace
* SFP/cable */
- BFA_STATUS_MISSINGFRM = 50, /* Missing frame check and replace
- * SFP/cable */
+ BFA_STATUS_MISSINGFRM = 50, /* Missing frame check and replace
+ * SFP/cable or for Mezz card check and
+ * replace pass through module */
BFA_STATUS_LINKTIMEOUT = 51, /* Link timeout check and replace
* SFP/cable */
BFA_STATUS_NO_FCPIM_NEXUS = 52, /* No FCP Nexus exists with the
@@ -173,7 +174,7 @@ enum bfa_status {
BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */
BFA_STATUS_CEE_NOT_DN = 110, /* eth port is not at down state, please
* bring down first */
- BFA_STATUS_10G_SPD = 111, /* Speed setting not valid for 10G HBA */
+ BFA_STATUS_10G_SPD = 111, /* Speed setting not valid for 10G CNA */
BFA_STATUS_IM_INV_TEAM_NAME = 112, /* Invalid team name */
BFA_STATUS_IM_DUP_TEAM_NAME = 113, /* Given team name already
* exists */
@@ -213,12 +214,13 @@ enum bfa_status {
* loaded */
BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */
BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */
- BFA_STATUS_NO_DRIVER = 133, /* Brocade adapter/driver not installed or loaded */
- BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */
+ BFA_STATUS_NO_DRIVER = 133, /* Brocade adapter/driver not installed
+ * or loaded */
+ BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */
BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */
BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */
- BFA_STATUS_IM_PVID_REMOVE = 137, /* Cannot remove port vlan (PVID) */
- BFA_STATUS_IM_PVID_EDIT = 138, /* Cannot edit port vlan (PVID) */
+ BFA_STATUS_IM_PVID_REMOVE = 137, /* Cannot remove port VLAN (PVID) */
+ BFA_STATUS_IM_PVID_EDIT = 138, /* Cannot edit port VLAN (PVID) */
BFA_STATUS_CNA_NO_BOOT = 139, /* Boot upload not allowed for CNA */
BFA_STATUS_IM_PVID_NON_ZERO = 140, /* Port VLAN ID (PVID) is Set to
* Non-Zero Value */
@@ -232,14 +234,15 @@ enum bfa_status {
BFA_STATUS_INSUFFICIENT_PERMS = 144, /* User doesn't have sufficient
* permissions to execute the BCU
* application */
- BFA_STATUS_IM_INV_VLAN_NAME = 145, /* Invalid/Reserved Vlan name
+ BFA_STATUS_IM_INV_VLAN_NAME = 145, /* Invalid/Reserved VLAN name
* string. The name is not allowed
- * for the normal Vlans */
+ * for the normal VLAN */
BFA_STATUS_CMD_NOTSUPP_CNA = 146, /* Command not supported for CNA */
- BFA_STATUS_IM_PASSTHRU_EDIT = 147, /* Can not edit passthru vlan id */
- BFA_STATUS_IM_BIND_FAILED = 148, /*! < IM Driver bind operation
+ BFA_STATUS_IM_PASSTHRU_EDIT = 147, /* Can not edit passthrough VLAN
+ * id */
+ BFA_STATUS_IM_BIND_FAILED = 148, /* IM Driver bind operation
* failed */
- BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation
+ BFA_STATUS_IM_UNBIND_FAILED = 149, /* IM Driver unbind operation
* failed */
BFA_STATUS_IM_PORT_IN_TEAM = 150, /* Port is already part of the
* team */
@@ -249,7 +252,24 @@ enum bfa_status {
BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, /* Given settings are not
* allowed for the current
* Teaming mode */
- BFA_STATUS_MAX_VAL /* Unknown error code */
+ BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot
+ * configuration */
+ BFA_STATUS_DEVID_MISSING = 155, /* Boot image is not for the adapter(s)
+ * installed */
+ BFA_STATUS_BAD_FWCFG = 156, /* Bad firmware configuration */
+ BFA_STATUS_CREATE_FILE = 157, /* Failed to create temporary file */
+ BFA_STATUS_INVALID_VENDOR = 158, /* Invalid switch vendor */
+ BFA_STATUS_SFP_NOT_READY = 159, /* SFP info is not ready. Retry */
+ BFA_STATUS_NO_TOPOLOGY_FOR_CNA = 160, /* Topology command not
+ * applicable to CNA */
+ BFA_STATUS_BOOT_CODE_UPDATED = 161, /* reboot -- -r is needed after
+ * boot code updated */
+ BFA_STATUS_BOOT_VERSION = 162, /* Boot code version not compatible with
+ * the driver installed */
+ BFA_STATUS_CARDTYPE_MISSING = 163, /* Boot image is not for the
+ * adapter(s) installed */
+ BFA_STATUS_INVALID_CARDTYPE = 164, /* Invalid card type provided */
+ BFA_STATUS_MAX_VAL /* Unknown error code */
};
#define bfa_status_t enum bfa_status
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h
index a39f474c2fc..cfd6ba7c47e 100644
--- a/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h
@@ -40,7 +40,8 @@ struct bfad_vport_s;
*
* @return None
*/
-void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv);
+void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv);
+void bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s);
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs.h b/drivers/scsi/bfa/include/fcs/bfa_fcs.h
index f2fd35fdee2..54e5b81ab2a 100644
--- a/drivers/scsi/bfa/include/fcs/bfa_fcs.h
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs.h
@@ -61,8 +61,8 @@ struct bfa_fcs_s {
/*
* bfa fcs API functions
*/
-void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
- bfa_boolean_t min_cfg);
+void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa,
+ struct bfad_s *bfad, bfa_boolean_t min_cfg);
void bfa_fcs_init(struct bfa_fcs_s *fcs);
void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
struct bfa_fcs_driver_info_s *driver_info);
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h
index e719f2c3eb3..9a35ecf5cdf 100644
--- a/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h
@@ -41,6 +41,7 @@ struct bfa_fcs_itnim_s {
struct bfa_fcs_s *fcs; /* fcs instance */
struct bfa_timer_s timer; /* timer functions */
struct bfa_itnim_s *bfa_itnim; /* BFA itnim struct */
+ u32 prli_retries; /* max prli retry attempts */
bfa_boolean_t seq_rec; /* seq recovery support */
bfa_boolean_t rec_support; /* REC supported */
bfa_boolean_t conf_comp; /* FCP_CONF support */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h
index 702b95b76c2..3027fc6c772 100644
--- a/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h
@@ -58,6 +58,7 @@ struct bfa_fcs_rport_s {
u16 reply_oxid; /* OX_ID of inbound requests */
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 */
wwn_t pwwn; /* port wwn of rport */
wwn_t nwwn; /* node wwn of rport */
struct bfa_rport_symname_s psym_name; /* port symbolic name */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h
index cd33f2cd5c3..0af26243086 100644
--- a/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h
@@ -49,6 +49,10 @@ bfa_status_t bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport,
struct bfa_fcs_s *fcs, u16 vf_id,
struct bfa_port_cfg_s *port_cfg,
struct bfad_vport_s *vport_drv);
+bfa_status_t bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport,
+ struct bfa_fcs_s *fcs, uint16_t vf_id,
+ struct bfa_port_cfg_s *port_cfg,
+ struct bfad_vport_s *vport_drv);
bfa_status_t bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport);
bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport);
bfa_status_t bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport);
diff --git a/drivers/scsi/bfa/include/log/bfa_log_linux.h b/drivers/scsi/bfa/include/log/bfa_log_linux.h
index bd451db4c30..44bc89768bd 100644
--- a/drivers/scsi/bfa/include/log/bfa_log_linux.h
+++ b/drivers/scsi/bfa/include/log/bfa_log_linux.h
@@ -53,8 +53,10 @@
(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 16)
#define BFA_LOG_LINUX_DRIVER_ERROR \
(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 17)
-#define BFA_LOG_LINUX_DRIVER_DIAG \
+#define BFA_LOG_LINUX_DRIVER_INFO \
(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 18)
-#define BFA_LOG_LINUX_DRIVER_AEN \
+#define BFA_LOG_LINUX_DRIVER_DIAG \
(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 19)
+#define BFA_LOG_LINUX_DRIVER_AEN \
+ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 20)
#endif
diff --git a/drivers/scsi/bfa/include/protocol/fc.h b/drivers/scsi/bfa/include/protocol/fc.h
index 8d1038035a7..436dd7c5643 100644
--- a/drivers/scsi/bfa/include/protocol/fc.h
+++ b/drivers/scsi/bfa/include/protocol/fc.h
@@ -1080,6 +1080,7 @@ struct fc_alpabm_s{
#define FC_REC_TOV (FC_ED_TOV + 1)
#define FC_RA_TOV 10
#define FC_ELS_TOV (2 * FC_RA_TOV)
+#define FC_FCCT_TOV (3 * FC_RA_TOV)
/*
* virtual fabric related defines
diff --git a/drivers/scsi/bfa/include/protocol/fcp.h b/drivers/scsi/bfa/include/protocol/fcp.h
index 9ade68ad285..74ea63ce84b 100644
--- a/drivers/scsi/bfa/include/protocol/fcp.h
+++ b/drivers/scsi/bfa/include/protocol/fcp.h
@@ -18,6 +18,7 @@
#ifndef __FCPPROTO_H__
#define __FCPPROTO_H__
+#include <linux/bitops.h>
#include <protocol/scsi.h>
#pragma pack(1)
@@ -102,9 +103,6 @@ enum {
/*
* Task management flags field - only one bit shall be set
*/
-#ifndef BIT
-#define BIT(_x) (1 << (_x))
-#endif
enum fcp_tm_cmnd{
FCP_TM_ABORT_TASK_SET = BIT(1),
FCP_TM_CLEAR_TASK_SET = BIT(2),
diff --git a/drivers/scsi/bfa/lport_api.c b/drivers/scsi/bfa/lport_api.c
index d3907d184e2..72b3f508d0e 100644
--- a/drivers/scsi/bfa/lport_api.c
+++ b/drivers/scsi/bfa/lport_api.c
@@ -137,6 +137,8 @@ bfa_fcs_port_get_rports(struct bfa_fcs_port_s *port, wwn_t rport_wwns[],
/*
* Iterate's through all the rport's in the given port to
* determine the maximum operating speed.
+ *
+ * To be used in TRL Functionality only
*/
enum bfa_pport_speed
bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port)
@@ -146,7 +148,8 @@ bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port)
struct bfa_fcs_s *fcs;
enum bfa_pport_speed max_speed = 0;
struct bfa_pport_attr_s pport_attr;
- enum bfa_pport_speed pport_speed;
+ enum bfa_pport_speed pport_speed, rport_speed;
+ bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa);
if (port == NULL)
return 0;
@@ -164,19 +167,28 @@ bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port)
qe = bfa_q_first(qh);
while (qe != qh) {
- rport = (struct bfa_fcs_rport_s *)qe;
- if ((bfa_os_ntoh3b(rport->pid) > 0xFFF000)
- || (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE)) {
+ rport = (struct bfa_fcs_rport_s *) qe;
+ if ((bfa_os_ntoh3b(rport->pid) > 0xFFF000) ||
+ (bfa_fcs_rport_get_state(rport) ==
+ BFA_RPORT_OFFLINE)) {
qe = bfa_q_next(qe);
continue;
}
- if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_8GBPS)
- || (rport->rpf.rpsc_speed > pport_speed)) {
- max_speed = rport->rpf.rpsc_speed;
+ rport_speed = rport->rpf.rpsc_speed;
+ if ((trl_enabled) && (rport_speed ==
+ BFA_PPORT_SPEED_UNKNOWN)) {
+ /* Use default ratelim speed setting */
+ rport_speed =
+ bfa_fcport_get_ratelim_speed(port->fcs->bfa);
+ }
+
+ if ((rport_speed == BFA_PPORT_SPEED_8GBPS) ||
+ (rport_speed > pport_speed)) {
+ max_speed = rport_speed;
break;
- } else if (rport->rpf.rpsc_speed > max_speed) {
- max_speed = rport->rpf.rpsc_speed;
+ } else if (rport_speed > max_speed) {
+ max_speed = rport_speed;
}
qe = bfa_q_next(qe);
diff --git a/drivers/scsi/bfa/ms.c b/drivers/scsi/bfa/ms.c
index 5e8c8dee6c9..1d579ef2612 100644
--- a/drivers/scsi/bfa/ms.c
+++ b/drivers/scsi/bfa/ms.c
@@ -157,6 +157,7 @@ bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
* Start timer for a delayed retry
*/
bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_retry);
+ ms->port->stats.ms_retries++;
bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), &ms->timer,
bfa_fcs_port_ms_timeout, ms,
BFA_FCS_RETRY_TIMEOUT);
@@ -279,6 +280,7 @@ bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
*/
if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_retry);
+ ms->port->stats.ms_retries++;
bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
&ms->timer, bfa_fcs_port_ms_timeout, ms,
BFA_FCS_RETRY_TIMEOUT);
@@ -359,7 +361,7 @@ bfa_fcs_port_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gmal_response,
- (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
+ (void *)ms, FC_MAX_PDUSZ, FC_FCCT_TOV);
bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
}
@@ -479,6 +481,7 @@ bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
*/
if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_retry);
+ ms->port->stats.ms_retries++;
bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
&ms->timer, bfa_fcs_port_ms_timeout, ms,
BFA_FCS_RETRY_TIMEOUT);
@@ -557,7 +560,7 @@ bfa_fcs_port_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gfn_response,
- (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
+ (void *)ms, FC_MAX_PDUSZ, FC_FCCT_TOV);
bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
}
@@ -637,7 +640,7 @@ bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response,
- (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
+ (void *)ms, FC_MAX_PDUSZ, FC_ELS_TOV);
port->stats.ms_plogi_sent++;
bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
diff --git a/drivers/scsi/bfa/ns.c b/drivers/scsi/bfa/ns.c
index d20dd7e1574..ae0edcc86ed 100644
--- a/drivers/scsi/bfa/ns.c
+++ b/drivers/scsi/bfa/ns.c
@@ -664,7 +664,7 @@ bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response,
- (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
+ (void *)ns, FC_MAX_PDUSZ, FC_ELS_TOV);
port->stats.ns_plogi_sent++;
bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
@@ -791,7 +791,7 @@ bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rspn_id_response,
- (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
+ (void *)ns, FC_MAX_PDUSZ, FC_FCCT_TOV);
port->stats.ns_rspnid_sent++;
@@ -865,7 +865,7 @@ bfa_fcs_port_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rft_id_response,
- (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
+ (void *)ns, FC_MAX_PDUSZ, FC_FCCT_TOV);
port->stats.ns_rftid_sent++;
bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
@@ -943,7 +943,7 @@ bfa_fcs_port_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rff_id_response,
- (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
+ (void *)ns, FC_MAX_PDUSZ, FC_FCCT_TOV);
port->stats.ns_rffid_sent++;
bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
@@ -1029,7 +1029,7 @@ bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_gid_ft_response,
(void *)ns, bfa_fcxp_get_maxrsp(port->fcs->bfa),
- FC_RA_TOV);
+ FC_FCCT_TOV);
port->stats.ns_gidft_sent++;
@@ -1228,10 +1228,10 @@ bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port)
struct bfa_fcs_rport_s *rport;
u8 nwwns;
- wwn_t *wwns;
+ wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX];
int ii;
- bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, &wwns);
+ bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns);
for (ii = 0; ii < nwwns; ++ii) {
rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c
index 7b096f2e383..9b4c2c9a644 100644
--- a/drivers/scsi/bfa/rport.c
+++ b/drivers/scsi/bfa/rport.c
@@ -36,8 +36,6 @@
BFA_TRC_FILE(FCS, RPORT);
-#define BFA_FCS_RPORT_MAX_RETRIES (5)
-
/* In millisecs */
static u32 bfa_fcs_rport_del_timeout =
BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
@@ -95,6 +93,7 @@ static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
u8 reason_code_expl);
static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
struct fchs_s *rx_fchs, u16 len);
+static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
/**
* fcs_rport_sm FCS rport state machine events
*/
@@ -115,7 +114,8 @@ enum rport_event {
RPSM_EVENT_HCB_OFFLINE = 13, /* BFA rport offline callback */
RPSM_EVENT_FC4_OFFLINE = 14, /* FC-4 offline complete */
RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */
- RPSM_EVENT_ADDRESS_DISC = 16 /* Need to Discover rport's PID */
+ RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */
+ RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */
};
static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
@@ -356,8 +356,8 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
*/
case RPSM_EVENT_TIMEOUT:
- rport->plogi_retries++;
if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
+ rport->plogi_retries++;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
bfa_fcs_rport_send_plogi(rport, NULL);
} else {
@@ -375,6 +375,7 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_free(rport);
break;
+ case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_LOGO_RCVD:
break;
@@ -430,6 +431,13 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
case RPSM_EVENT_LOGO_RCVD:
bfa_fcs_rport_send_logo_acc(rport);
+ /*
+ * !! fall through !!
+ */
+ case RPSM_EVENT_PRLO_RCVD:
+ if (rport->prlo == BFA_TRUE)
+ bfa_fcs_rport_send_prlo_acc(rport);
+
bfa_fcxp_discard(rport->fcxp);
/*
* !! fall through !!
@@ -504,6 +512,9 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_online_action(rport);
break;
+ case RPSM_EVENT_PRLO_RCVD:
+ break;
+
case RPSM_EVENT_LOGO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
bfa_rport_offline(rport->bfa_rport);
@@ -582,6 +593,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcs_rport_offline_action(rport);
break;
@@ -624,6 +636,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_offline_action(rport);
@@ -690,6 +703,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_discard(rport->fcxp);
bfa_fcs_rport_offline_action(rport);
@@ -740,6 +754,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_offline_action(rport);
@@ -811,6 +826,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_discard(rport->fcxp);
bfa_fcs_rport_offline_action(rport);
@@ -843,6 +859,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_ADDRESS_CHANGE:
break;
@@ -894,6 +911,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
case RPSM_EVENT_SCN:
case RPSM_EVENT_LOGO_IMP:
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_ADDRESS_CHANGE:
/**
* rport is already going offline.
@@ -953,6 +971,7 @@ 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:
/**
* Ignore, already offline.
*/
@@ -978,8 +997,11 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
switch (event) {
case RPSM_EVENT_HCB_OFFLINE:
case RPSM_EVENT_ADDRESS_CHANGE:
- if (rport->pid)
+ if (rport->pid && (rport->prlo == BFA_TRUE))
+ bfa_fcs_rport_send_prlo_acc(rport);
+ if (rport->pid && (rport->prlo == BFA_FALSE))
bfa_fcs_rport_send_logo_acc(rport);
+
/*
* If the lport is online and if the rport is not a well known
* address port, we try to re-discover the r-port.
@@ -1013,6 +1035,7 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
/**
* Ignore - already processing a LOGO.
*/
@@ -1042,6 +1065,7 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_ADDRESS_CHANGE:
break;
@@ -1075,6 +1099,7 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_free(rport);
@@ -1123,6 +1148,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_LOGO_IMP:
break;
@@ -1174,6 +1200,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
case RPSM_EVENT_SCN:
case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_PLOGI_SEND:
break;
@@ -1250,6 +1277,10 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_send_logo_acc(rport);
break;
+ case RPSM_EVENT_PRLO_RCVD:
+ bfa_fcs_rport_send_prlo_acc(rport);
+ break;
+
case RPSM_EVENT_PLOGI_COMP:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
bfa_timer_stop(&rport->timer);
@@ -1322,6 +1353,10 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_del_timeout);
break;
+ case RPSM_EVENT_PRLO_RCVD:
+ bfa_fcs_rport_send_prlo_acc(rport);
+ break;
+
case RPSM_EVENT_SCN:
/**
* ignore, wait for NS query response
@@ -1378,7 +1413,7 @@ bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
- (void *)rport, FC_MAX_PDUSZ, FC_RA_TOV);
+ (void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV);
rport->stats.plogis++;
bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
@@ -1519,7 +1554,7 @@ bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
- rport, FC_MAX_PDUSZ, FC_RA_TOV);
+ rport, FC_MAX_PDUSZ, FC_ELS_TOV);
rport->stats.adisc_sent++;
bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
@@ -1580,7 +1615,7 @@ bfa_fcs_rport_send_gidpn(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_rport_gidpn_response,
- (void *)rport, FC_MAX_PDUSZ, FC_RA_TOV);
+ (void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV);
bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
}
@@ -1692,7 +1727,7 @@ bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, NULL, rport, FC_MAX_PDUSZ,
- FC_ED_TOV);
+ FC_ELS_TOV);
rport->stats.logos++;
bfa_fcxp_discard(rport->fcxp);
@@ -2184,6 +2219,7 @@ bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
rport->reply_oxid = fchs->ox_id;
bfa_trc(rport->fcs, rport->reply_oxid);
+ rport->prlo = BFA_FALSE;
rport->stats.logo_rcvd++;
bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
}
@@ -2553,6 +2589,30 @@ bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
}
}
+/* Send best case acc to prlo */
+static void
+bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
+{
+ struct bfa_fcs_port_s *port = rport->port;
+ struct fchs_s fchs;
+ struct bfa_fcxp_s *fcxp;
+ int len;
+
+ bfa_trc(rport->fcs, rport->pid);
+
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ if (!fcxp)
+ return;
+
+ len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
+ rport->pid, bfa_fcs_port_get_fcid(port),
+ rport->reply_oxid, 0);
+
+ bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id,
+ port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs,
+ NULL, NULL, FC_MAX_PDUSZ, 0);
+}
+
/*
* Send a LS reject
*/
@@ -2604,3 +2664,13 @@ bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
if (rport_tmo > 0)
bfa_fcs_rport_del_timeout = rport_tmo * 1000;
}
+
+void
+bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, uint16_t ox_id)
+{
+ bfa_trc(rport->fcs, rport->pid);
+
+ rport->prlo = BFA_TRUE;
+ rport->reply_oxid = ox_id;
+ bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD);
+}
diff --git a/drivers/scsi/bfa/rport_api.c b/drivers/scsi/bfa/rport_api.c
index a441f41d2a6..15e0c470afd 100644
--- a/drivers/scsi/bfa/rport_api.c
+++ b/drivers/scsi/bfa/rport_api.c
@@ -83,6 +83,7 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
{
struct bfa_rport_qos_attr_s qos_attr;
struct bfa_fcs_port_s *port = rport->port;
+ enum bfa_pport_speed rport_speed = rport->rpf.rpsc_speed;
bfa_os_memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
@@ -102,10 +103,14 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
rport_attr->qos_attr = qos_attr;
rport_attr->trl_enforced = BFA_FALSE;
+
if (bfa_fcport_is_ratelim(port->fcs->bfa)) {
- if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) ||
- (rport->rpf.rpsc_speed <
- bfa_fcs_port_get_rport_max_speed(port)))
+ if (rport_speed == BFA_PPORT_SPEED_UNKNOWN) {
+ /* Use default ratelim speed setting */
+ rport_speed =
+ bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
+ }
+ if (rport_speed < bfa_fcs_port_get_rport_max_speed(port))
rport_attr->trl_enforced = BFA_TRUE;
}
diff --git a/drivers/scsi/bfa/rport_ftrs.c b/drivers/scsi/bfa/rport_ftrs.c
index ae7bba67ae2..f2a9361ce9a 100644
--- a/drivers/scsi/bfa/rport_ftrs.c
+++ b/drivers/scsi/bfa/rport_ftrs.c
@@ -73,6 +73,7 @@ static void
bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
{
struct bfa_fcs_rport_s *rport = rpf->rport;
+ struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric;
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
@@ -80,12 +81,16 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
switch (event) {
case RPFSM_EVENT_RPORT_ONLINE:
- if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
+ /* Send RPSC2 to a Brocade fabric only. */
+ if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
+ ((bfa_lps_is_brcd_fabric(rport->port->fabric->lps)) ||
+ (bfa_fcs_fabric_get_switch_oui(fabric) ==
+ BFA_FCS_BRCD_SWITCH_OUI))) {
bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
rpf->rpsc_retries = 0;
bfa_fcs_rpf_send_rpsc2(rpf, NULL);
- break;
- };
+ }
+ break;
case RPFSM_EVENT_RPORT_OFFLINE:
break;
@@ -269,6 +274,7 @@ void bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
if (__fcs_min_cfg(rport->port->fcs))
return;
+ rport->rpf.rpsc_speed = 0;
bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
}
@@ -307,7 +313,7 @@ bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
- rpf, FC_MAX_PDUSZ, FC_RA_TOV);
+ rpf, FC_MAX_PDUSZ, FC_ELS_TOV);
rport->stats.rpsc_sent++;
bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
diff --git a/drivers/scsi/bfa/scn.c b/drivers/scsi/bfa/scn.c
index 8fe09ba88a9..8a60129e630 100644
--- a/drivers/scsi/bfa/scn.c
+++ b/drivers/scsi/bfa/scn.c
@@ -218,7 +218,7 @@ bfa_fcs_port_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_scn_scr_response,
- (void *)scn, FC_MAX_PDUSZ, FC_RA_TOV);
+ (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV);
bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT);
}
diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c
index 27cd619a227..b378ec79d38 100644
--- a/drivers/scsi/bfa/vport.c
+++ b/drivers/scsi/bfa/vport.c
@@ -218,9 +218,9 @@ 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_logo);
+ bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
bfa_lps_discard(vport->lps);
- bfa_fcs_vport_do_logo(vport);
+ bfa_fcs_port_delete(&vport->lport);
break;
case BFA_FCS_VPORT_SM_OFFLINE:
@@ -357,8 +357,9 @@ bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
switch (event) {
case BFA_FCS_VPORT_SM_DELETE:
- bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
- bfa_fcs_vport_free(vport);
+ bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
+ bfa_fcs_port_delete(&vport->lport);
+
break;
default:
@@ -594,6 +595,15 @@ bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
}
/**
+ * delete notification from fabric SM. To be invoked from within FCS.
+ */
+void
+bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport)
+{
+ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
+}
+
+/**
* Delete completion callback from associated lport
*/
void
@@ -646,6 +656,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
return BFA_STATUS_VPORT_MAX;
vport->vport_drv = vport_drv;
+ vport_cfg->preboot_vp = BFA_FALSE;
bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
@@ -657,6 +668,36 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
}
/**
+ * Use this function to instantiate a new FCS PBC vport object. This
+ * function will not trigger any HW initialization process (which will be
+ * done in vport_start() call)
+ *
+ * param[in] vport - pointer to bfa_fcs_vport_t. This space
+ * needs to be allocated by the driver.
+ * param[in] fcs - FCS instance
+ * param[in] vport_cfg - vport configuration
+ * param[in] vf_id - VF_ID if vport is created within a VF.
+ * FC_VF_ID_NULL to specify base fabric.
+ * param[in] vport_drv - Opaque handle back to the driver's vport
+ * structure
+ *
+ * retval BFA_STATUS_OK - on success.
+ * retval BFA_STATUS_FAILED - on failure.
+ */
+bfa_status_t
+bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
+ uint16_t vf_id, struct bfa_port_cfg_s *vport_cfg,
+ struct bfad_vport_s *vport_drv)
+{
+ bfa_status_t rc;
+
+ rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv);
+ vport->lport.port_cfg.preboot_vp = BFA_TRUE;
+
+ return rc;
+}
+
+/**
* Use this function initialize the vport.
*
* @param[in] vport - pointer to bfa_fcs_vport_t.
@@ -692,6 +733,8 @@ bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
* Use this function to delete a vport object. Fabric object should
* be stopped before this function call.
*
+ * Donot invoke this from within FCS
+ *
* param[in] vport - pointer to bfa_fcs_vport_t.
*
* return None
@@ -699,6 +742,9 @@ bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
bfa_status_t
bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport)
{
+ if (vport->lport.port_cfg.preboot_vp)
+ return BFA_STATUS_PBC;
+
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
return BFA_STATUS_OK;
@@ -789,7 +835,7 @@ bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
switch (status) {
case BFA_STATUS_OK:
/*
- * Initialiaze the V-Port fields
+ * Initialize the V-Port fields
*/
__vport_fcid(vport) = bfa_lps_get_pid(vport->lps);
vport->vport_stats.fdisc_accepts++;