summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2011-09-15 15:08:05 +0200
committerJiri Kosina <jkosina@suse.cz>2011-09-15 15:08:18 +0200
commite060c38434b2caa78efe7cedaff4191040b65a15 (patch)
tree407361230bf6733f63d8e788e4b5e6566ee04818 /drivers/scsi/bfa
parent10e4ac572eeffe5317019bd7330b6058a400dfc2 (diff)
parentcc39c6a9bbdebfcf1a7dee64d83bf302bc38d941 (diff)
Merge branch 'master' into for-next
Fast-forward merge with Linus to be able to merge patches based on more recent version of the tree.
Diffstat (limited to 'drivers/scsi/bfa')
-rw-r--r--drivers/scsi/bfa/bfa.h51
-rw-r--r--drivers/scsi/bfa/bfa_core.c60
-rw-r--r--drivers/scsi/bfa/bfa_defs.h171
-rw-r--r--drivers/scsi/bfa/bfa_defs_svc.h99
-rw-r--r--drivers/scsi/bfa/bfa_fc.h155
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.c736
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.h45
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c26
-rw-r--r--drivers/scsi/bfa/bfa_fcs.h1
-rw-r--r--drivers/scsi/bfa/bfa_fcs_fcpim.c37
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c74
-rw-r--r--drivers/scsi/bfa/bfa_fcs_rport.c49
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c38
-rw-r--r--drivers/scsi/bfa/bfa_hw_ct.c25
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c569
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h48
-rw-r--r--drivers/scsi/bfa/bfa_modules.h3
-rw-r--r--drivers/scsi/bfa/bfa_svc.c249
-rw-r--r--drivers/scsi/bfa/bfa_svc.h29
-rw-r--r--drivers/scsi/bfa/bfad.c8
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c1082
-rw-r--r--drivers/scsi/bfa/bfad_bsg.h237
-rw-r--r--drivers/scsi/bfa/bfad_drv.h6
-rw-r--r--drivers/scsi/bfa/bfad_im.c26
-rw-r--r--drivers/scsi/bfa/bfad_im.h22
-rw-r--r--drivers/scsi/bfa/bfi.h20
26 files changed, 3723 insertions, 143 deletions
diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h
index 3b0af1102bf4..a796de935054 100644
--- a/drivers/scsi/bfa/bfa.h
+++ b/drivers/scsi/bfa/bfa.h
@@ -27,6 +27,7 @@
struct bfa_s;
typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m);
+typedef void (*bfa_cb_cbfn_status_t) (void *cbarg, bfa_status_t status);
/*
* Interrupt message handlers
@@ -121,6 +122,7 @@ bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg),
#define bfa_cb_queue(__bfa, __hcb_qe, __cbfn, __cbarg) do { \
(__hcb_qe)->cbfn = (__cbfn); \
(__hcb_qe)->cbarg = (__cbarg); \
+ (__hcb_qe)->pre_rmv = BFA_FALSE; \
list_add_tail(&(__hcb_qe)->qe, &(__bfa)->comp_q); \
} while (0)
@@ -135,6 +137,11 @@ bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg),
} \
} while (0)
+#define bfa_cb_queue_status(__bfa, __hcb_qe, __status) do { \
+ (__hcb_qe)->fw_status = (__status); \
+ list_add_tail(&(__hcb_qe)->qe, &(__bfa)->comp_q); \
+} while (0)
+
#define bfa_cb_queue_done(__hcb_qe) do { \
(__hcb_qe)->once = BFA_FALSE; \
} while (0)
@@ -177,7 +184,7 @@ struct bfa_msix_s {
struct bfa_hwif_s {
void (*hw_reginit)(struct bfa_s *bfa);
void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
- void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
+ void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq, u32 ci);
void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
void (*hw_msix_ctrl_install)(struct bfa_s *bfa);
void (*hw_msix_queue_install)(struct bfa_s *bfa);
@@ -268,10 +275,8 @@ struct bfa_iocfc_s {
((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa))
#define bfa_msix_uninstall(__bfa) \
((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa))
-#define bfa_isr_rspq_ack(__bfa, __queue) do { \
- if ((__bfa)->iocfc.hwif.hw_rspq_ack) \
- (__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue); \
-} while (0)
+#define bfa_isr_rspq_ack(__bfa, __queue, __ci) \
+ ((__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue, __ci))
#define bfa_isr_reqq_ack(__bfa, __queue) do { \
if ((__bfa)->iocfc.hwif.hw_reqq_ack) \
(__bfa)->iocfc.hwif.hw_reqq_ack(__bfa, __queue); \
@@ -311,7 +316,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec);
void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
void bfa_hwcb_reginit(struct bfa_s *bfa);
-void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
+void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa);
void bfa_hwcb_msix_queue_install(struct bfa_s *bfa);
@@ -324,7 +329,8 @@ void bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start,
void bfa_hwct_reginit(struct bfa_s *bfa);
void bfa_hwct2_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);
+void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
+void bfa_hwct2_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa);
void bfa_hwct_msix_queue_install(struct bfa_s *bfa);
@@ -376,6 +382,22 @@ int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa,
#define bfa_get_fw_clock_res(__bfa) \
((__bfa)->iocfc.cfgrsp->fwcfg.fw_tick_res)
+/*
+ * lun mask macros return NULL when min cfg is enabled and there is
+ * no memory allocated for lunmask.
+ */
+#define bfa_get_lun_mask(__bfa) \
+ ((&(__bfa)->modules.dconf_mod)->min_cfg) ? NULL : \
+ (&(BFA_DCONF_MOD(__bfa)->dconf->lun_mask))
+
+#define bfa_get_lun_mask_list(_bfa) \
+ ((&(_bfa)->modules.dconf_mod)->min_cfg) ? NULL : \
+ (bfa_get_lun_mask(_bfa)->lun_list)
+
+#define bfa_get_lun_mask_status(_bfa) \
+ (((&(_bfa)->modules.dconf_mod)->min_cfg) \
+ ? BFA_LUNMASK_MINCFG : ((bfa_get_lun_mask(_bfa))->status))
+
void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids);
void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg);
void bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg);
@@ -406,7 +428,22 @@ bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa,
void bfa_iocfc_enable(struct bfa_s *bfa);
void bfa_iocfc_disable(struct bfa_s *bfa);
+void bfa_iocfc_cb_dconf_modinit(struct bfa_s *bfa, bfa_status_t status);
#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \
bfa_timer_begin(&(_bfa)->timer_mod, _timer, _timercb, _arg, _timeout)
+struct bfa_cb_pending_q_s {
+ struct bfa_cb_qe_s hcb_qe;
+ void *data; /* Driver buffer */
+};
+
+/* Common macros to operate on pending stats/attr apis */
+#define bfa_pending_q_init(__qe, __cbfn, __cbarg, __data) do { \
+ bfa_q_qe_init(&((__qe)->hcb_qe.qe)); \
+ (__qe)->hcb_qe.cbfn = (__cbfn); \
+ (__qe)->hcb_qe.cbarg = (__cbarg); \
+ (__qe)->hcb_qe.pre_rmv = BFA_TRUE; \
+ (__qe)->data = (__data); \
+} while (0)
+
#endif /* __BFA_H__ */
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index c38e589105a5..4bd546bcc240 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -33,6 +33,7 @@ static struct bfa_module_s *hal_mods[] = {
&hal_mod_uf,
&hal_mod_rport,
&hal_mod_fcp,
+ &hal_mod_dconf,
NULL
};
@@ -237,8 +238,6 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
u32 pi, ci;
struct list_head *waitq;
- bfa_isr_rspq_ack(bfa, qid);
-
ci = bfa_rspq_ci(bfa, qid);
pi = bfa_rspq_pi(bfa, qid);
@@ -251,11 +250,9 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
}
/*
- * update CI
+ * acknowledge RME completions and update CI
*/
- bfa_rspq_ci(bfa, qid) = pi;
- writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]);
- mmiowb();
+ bfa_isr_rspq_ack(bfa, qid, ci);
/*
* Resume any pending requests in the corresponding reqq.
@@ -325,23 +322,19 @@ bfa_intx(struct bfa_s *bfa)
int queue;
intr = readl(bfa->iocfc.bfa_regs.intr_status);
- if (!intr)
- return BFA_FALSE;
qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK);
if (qintr)
writel(qintr, bfa->iocfc.bfa_regs.intr_status);
/*
- * RME completion queue interrupt
+ * Unconditional RME completion queue interrupt
*/
- qintr = intr & __HFN_INT_RME_MASK;
- if (qintr && bfa->queue_process) {
+ if (bfa->queue_process) {
for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
bfa_isr_rspq(bfa, queue);
}
- intr &= ~qintr;
if (!intr)
return BFA_TRUE;
@@ -432,7 +425,8 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
__HFN_INT_MBOX_LPU1_CT2);
intr &= __HFN_INT_ERR_MASK_CT2;
} else {
- halt_isr = intr & __HFN_INT_LL_HALT;
+ halt_isr = bfa_asic_id_ct(bfa->ioc.pcidev.device_id) ?
+ (intr & __HFN_INT_LL_HALT) : 0;
pss_isr = intr & __HFN_INT_ERR_PSS;
lpu_isr = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1);
intr &= __HFN_INT_ERR_MASK;
@@ -578,7 +572,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
} else {
iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
iocfc->hwif.hw_reqq_ack = NULL;
- iocfc->hwif.hw_rspq_ack = NULL;
+ iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install;
iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install;
@@ -595,7 +589,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) {
iocfc->hwif.hw_reginit = bfa_hwct2_reginit;
iocfc->hwif.hw_isr_mode_set = NULL;
- iocfc->hwif.hw_rspq_ack = NULL;
+ iocfc->hwif.hw_rspq_ack = bfa_hwct2_rspq_ack;
}
iocfc->hwif.hw_reginit(bfa);
@@ -685,7 +679,7 @@ bfa_iocfc_start_submod(struct bfa_s *bfa)
bfa->queue_process = BFA_TRUE;
for (i = 0; i < BFI_IOC_MAX_CQS; i++)
- bfa_isr_rspq_ack(bfa, i);
+ bfa_isr_rspq_ack(bfa, i, bfa_rspq_ci(bfa, i));
for (i = 0; hal_mods[i]; i++)
hal_mods[i]->start(bfa);
@@ -709,7 +703,7 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
struct bfa_s *bfa = bfa_arg;
if (complete) {
- if (bfa->iocfc.cfgdone)
+ if (bfa->iocfc.cfgdone && BFA_DCONF_MOD(bfa)->flashdone)
bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
else
bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
@@ -822,9 +816,11 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
*/
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 {
+ if (iocfc->action == BFA_IOCFC_ACT_INIT) {
+ if (BFA_DCONF_MOD(bfa)->flashdone == BFA_TRUE)
+ bfa_cb_queue(bfa, &iocfc->init_hcb_qe,
+ bfa_iocfc_init_cb, bfa);
+ } else {
if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE)
bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe,
bfa_iocfc_enable_cb, bfa);
@@ -1045,6 +1041,7 @@ bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
}
bfa_iocfc_send_cfg(bfa);
+ bfa_dconf_modinit(bfa);
}
/*
@@ -1207,7 +1204,9 @@ bfa_iocfc_stop(struct bfa_s *bfa)
bfa->iocfc.action = BFA_IOCFC_ACT_STOP;
bfa->queue_process = BFA_FALSE;
- bfa_ioc_disable(&bfa->ioc);
+ bfa_dconf_modexit(bfa);
+ if (BFA_DCONF_MOD(bfa)->flashdone == BFA_TRUE)
+ bfa_ioc_disable(&bfa->ioc);
}
void
@@ -1540,10 +1539,17 @@ bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
struct list_head *qe;
struct list_head *qen;
struct bfa_cb_qe_s *hcb_qe;
+ bfa_cb_cbfn_status_t cbfn;
list_for_each_safe(qe, qen, comp_q) {
hcb_qe = (struct bfa_cb_qe_s *) qe;
- hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
+ if (hcb_qe->pre_rmv) {
+ /* qe is invalid after return, dequeue before cbfn() */
+ list_del(qe);
+ cbfn = (bfa_cb_cbfn_status_t)(hcb_qe->cbfn);
+ cbfn(hcb_qe->cbarg, hcb_qe->fw_status);
+ } else
+ hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
}
}
@@ -1556,10 +1562,20 @@ bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
while (!list_empty(comp_q)) {
bfa_q_deq(comp_q, &qe);
hcb_qe = (struct bfa_cb_qe_s *) qe;
+ WARN_ON(hcb_qe->pre_rmv);
hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE);
}
}
+void
+bfa_iocfc_cb_dconf_modinit(struct bfa_s *bfa, bfa_status_t status)
+{
+ if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT) {
+ if (bfa->iocfc.cfgdone == BFA_TRUE)
+ bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
+ bfa_iocfc_init_cb, bfa);
+ }
+}
/*
* Return the list of PCI vendor/device id lists supported by this
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h
index ed8d31b0188b..7b3d235d20b4 100644
--- a/drivers/scsi/bfa/bfa_defs.h
+++ b/drivers/scsi/bfa/bfa_defs.h
@@ -144,6 +144,7 @@ enum bfa_status {
BFA_STATUS_INVLD_DFSZ = 24, /* Invalid Max data field size */
BFA_STATUS_CMD_NOTSUPP = 26, /* Command/API not supported */
BFA_STATUS_FABRIC_RJT = 29, /* Reject from attached fabric */
+ BFA_STATUS_UNKNOWN_VWWN = 30, /* VPORT PWWN not found */
BFA_STATUS_PORT_OFFLINE = 34, /* Port is not online */
BFA_STATUS_VPORT_WWN_BP = 46, /* WWN is same as base port's WWN */
BFA_STATUS_PORT_NOT_DISABLED = 47, /* Port not disabled disable port */
@@ -164,6 +165,8 @@ enum bfa_status {
BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */
BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot
* configuration */
+ BFA_STATUS_BAD_FWCFG = 156, /* Bad firmware configuration */
+ BFA_STATUS_INVALID_VENDOR = 158, /* Invalid switch vendor */
BFA_STATUS_SFP_NOT_READY = 159, /* SFP info is not ready. Retry */
BFA_STATUS_TRUNK_ENABLED = 164, /* Trunk is already enabled on
* this adapter */
@@ -172,11 +175,15 @@ enum bfa_status {
BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */
BFA_STATUS_PHY_NOT_PRESENT = 183, /* PHY module not present */
BFA_STATUS_FEATURE_NOT_SUPPORTED = 192, /* Feature not supported */
+ BFA_STATUS_ENTRY_EXISTS = 193, /* Entry already exists */
+ BFA_STATUS_ENTRY_NOT_EXISTS = 194, /* Entry does not exist */
+ BFA_STATUS_NO_CHANGE = 195, /* Feature already in that state */
BFA_STATUS_FAA_ENABLED = 197, /* FAA is already enabled */
BFA_STATUS_FAA_DISABLED = 198, /* FAA is already disabled */
BFA_STATUS_FAA_ACQUIRED = 199, /* FAA is already acquired */
BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */
BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */
+ BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */
BFA_STATUS_MAX_VAL /* Unknown error code */
};
#define bfa_status_t enum bfa_status
@@ -359,6 +366,139 @@ struct bfa_ioc_attr_s {
};
/*
+ * AEN related definitions
+ */
+enum bfa_aen_category {
+ BFA_AEN_CAT_ADAPTER = 1,
+ BFA_AEN_CAT_PORT = 2,
+ BFA_AEN_CAT_LPORT = 3,
+ BFA_AEN_CAT_RPORT = 4,
+ BFA_AEN_CAT_ITNIM = 5,
+ BFA_AEN_CAT_AUDIT = 8,
+ BFA_AEN_CAT_IOC = 9,
+};
+
+/* BFA adapter level events */
+enum bfa_adapter_aen_event {
+ BFA_ADAPTER_AEN_ADD = 1, /* New Adapter found event */
+ BFA_ADAPTER_AEN_REMOVE = 2, /* Adapter removed event */
+};
+
+struct bfa_adapter_aen_data_s {
+ char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
+ u32 nports; /* Number of NPorts */
+ wwn_t pwwn; /* WWN of one of its physical port */
+};
+
+/* BFA physical port Level events */
+enum bfa_port_aen_event {
+ BFA_PORT_AEN_ONLINE = 1, /* Physical Port online event */
+ BFA_PORT_AEN_OFFLINE = 2, /* Physical Port offline event */
+ BFA_PORT_AEN_RLIR = 3, /* RLIR event, not supported */
+ BFA_PORT_AEN_SFP_INSERT = 4, /* SFP inserted event */
+ BFA_PORT_AEN_SFP_REMOVE = 5, /* SFP removed event */
+ BFA_PORT_AEN_SFP_POM = 6, /* SFP POM event */
+ BFA_PORT_AEN_ENABLE = 7, /* Physical Port enable event */
+ BFA_PORT_AEN_DISABLE = 8, /* Physical Port disable event */
+ BFA_PORT_AEN_AUTH_ON = 9, /* Physical Port auth success event */
+ BFA_PORT_AEN_AUTH_OFF = 10, /* Physical Port auth fail event */
+ BFA_PORT_AEN_DISCONNECT = 11, /* Physical Port disconnect event */
+ BFA_PORT_AEN_QOS_NEG = 12, /* Base Port QOS negotiation event */
+ BFA_PORT_AEN_FABRIC_NAME_CHANGE = 13, /* Fabric Name/WWN change */
+ BFA_PORT_AEN_SFP_ACCESS_ERROR = 14, /* SFP read error event */
+ BFA_PORT_AEN_SFP_UNSUPPORT = 15, /* Unsupported SFP event */
+};
+
+enum bfa_port_aen_sfp_pom {
+ BFA_PORT_AEN_SFP_POM_GREEN = 1, /* Normal */
+ BFA_PORT_AEN_SFP_POM_AMBER = 2, /* Warning */
+ BFA_PORT_AEN_SFP_POM_RED = 3, /* Critical */
+ BFA_PORT_AEN_SFP_POM_MAX = BFA_PORT_AEN_SFP_POM_RED
+};
+
+struct bfa_port_aen_data_s {
+ wwn_t pwwn; /* WWN of the physical port */
+ wwn_t fwwn; /* WWN of the fabric port */
+ u32 phy_port_num; /* For SFP related events */
+ u16 ioc_type;
+ u16 level; /* Only transitions will be informed */
+ mac_t mac; /* MAC address of the ethernet port */
+ u16 rsvd;
+};
+
+/* BFA AEN logical port events */
+enum bfa_lport_aen_event {
+ BFA_LPORT_AEN_NEW = 1, /* LPort created event */
+ BFA_LPORT_AEN_DELETE = 2, /* LPort deleted event */
+ BFA_LPORT_AEN_ONLINE = 3, /* LPort online event */
+ BFA_LPORT_AEN_OFFLINE = 4, /* LPort offline event */
+ BFA_LPORT_AEN_DISCONNECT = 5, /* LPort disconnect event */
+ BFA_LPORT_AEN_NEW_PROP = 6, /* VPort created event */
+ BFA_LPORT_AEN_DELETE_PROP = 7, /* VPort deleted event */
+ BFA_LPORT_AEN_NEW_STANDARD = 8, /* VPort created event */
+ BFA_LPORT_AEN_DELETE_STANDARD = 9, /* VPort deleted event */
+ BFA_LPORT_AEN_NPIV_DUP_WWN = 10, /* VPort with duplicate WWN */
+ BFA_LPORT_AEN_NPIV_FABRIC_MAX = 11, /* Max NPIV in fabric/fport */
+ BFA_LPORT_AEN_NPIV_UNKNOWN = 12, /* Unknown NPIV Error code */
+};
+
+struct bfa_lport_aen_data_s {
+ u16 vf_id; /* vf_id of this logical port */
+ u16 roles; /* Logical port mode,IM/TM/IP etc */
+ u32 rsvd;
+ wwn_t ppwwn; /* WWN of its physical port */
+ wwn_t lpwwn; /* WWN of this logical port */
+};
+
+/* BFA ITNIM events */
+enum bfa_itnim_aen_event {
+ BFA_ITNIM_AEN_ONLINE = 1, /* Target online */
+ BFA_ITNIM_AEN_OFFLINE = 2, /* Target offline */
+ BFA_ITNIM_AEN_DISCONNECT = 3, /* Target disconnected */
+};
+
+struct bfa_itnim_aen_data_s {
+ u16 vf_id; /* vf_id of the IT nexus */
+ u16 rsvd[3];
+ wwn_t ppwwn; /* WWN of its physical port */
+ wwn_t lpwwn; /* WWN of logical port */
+ wwn_t rpwwn; /* WWN of remote(target) port */
+};
+
+/* BFA audit events */
+enum bfa_audit_aen_event {
+ BFA_AUDIT_AEN_AUTH_ENABLE = 1,
+ BFA_AUDIT_AEN_AUTH_DISABLE = 2,
+ BFA_AUDIT_AEN_FLASH_ERASE = 3,
+ BFA_AUDIT_AEN_FLASH_UPDATE = 4,
+};
+
+struct bfa_audit_aen_data_s {
+ wwn_t pwwn;
+ int partition_inst;
+ int partition_type;
+};
+
+/* BFA IOC level events */
+enum bfa_ioc_aen_event {
+ BFA_IOC_AEN_HBGOOD = 1, /* Heart Beat restore event */
+ BFA_IOC_AEN_HBFAIL = 2, /* Heart Beat failure 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 */
+};
+
+struct bfa_ioc_aen_data_s {
+ wwn_t pwwn;
+ u16 ioc_type;
+ mac_t mac;
+};
+
+/*
* ---------------------- mfg definitions ------------
*/
@@ -520,6 +660,20 @@ struct bfa_boot_bootlun_s {
/*
* BOOT boot configuraton
*/
+struct bfa_boot_cfg_s {
+ u8 version;
+ u8 rsvd1;
+ u16 chksum;
+ u8 enable; /* enable/disable SAN boot */
+ u8 speed; /* boot speed settings */
+ u8 topology; /* boot topology setting */
+ u8 bootopt; /* bfa_boot_bootopt_t */
+ u32 nbluns; /* number of boot luns */
+ u32 rsvd2;
+ struct bfa_boot_bootlun_s blun[BFA_BOOT_BOOTLUN_MAX];
+ 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 */
@@ -529,6 +683,15 @@ struct bfa_boot_pbc_s {
struct bfa_boot_bootlun_s pblun[BFA_PREBOOT_BOOTLUN_MAX];
};
+struct bfa_ethboot_cfg_s {
+ u8 version;
+ u8 rsvd1;
+ u16 chksum;
+ u8 enable; /* enable/disable Eth/PXE boot */
+ u8 rsvd2;
+ u16 vlan;
+};
+
/*
* ASIC block configuration related structures
*/
@@ -587,6 +750,14 @@ struct bfa_ablk_cfg_s {
*/
#define SFP_DIAGMON_SIZE 10 /* num bytes of diag monitor data */
+/* SFP state change notification event */
+#define BFA_SFP_SCN_REMOVED 0
+#define BFA_SFP_SCN_INSERTED 1
+#define BFA_SFP_SCN_POM 2
+#define BFA_SFP_SCN_FAILED 3
+#define BFA_SFP_SCN_UNSUPPORT 4
+#define BFA_SFP_SCN_VALID 5
+
enum bfa_defs_sfp_media_e {
BFA_SFP_MEDIA_UNKNOWN = 0x00,
BFA_SFP_MEDIA_CU = 0x01,
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h
index 0b97525803fb..863c6ba7d5eb 100644
--- a/drivers/scsi/bfa/bfa_defs_svc.h
+++ b/drivers/scsi/bfa/bfa_defs_svc.h
@@ -268,6 +268,7 @@ struct bfa_fw_port_snsm_stats_s {
u32 error_resets; /* error resets initiated by upsm */
u32 sync_lost; /* Sync loss count */
u32 sig_lost; /* Signal loss count */
+ u32 asn8g_attempts; /* SNSM HWSM at 8Gbps attempts */
};
struct bfa_fw_port_physm_stats_s {
@@ -468,6 +469,7 @@ struct bfa_fw_stats_s {
* QoS states
*/
enum bfa_qos_state {
+ BFA_QOS_DISABLED = 0, /* QoS is disabled */
BFA_QOS_ONLINE = 1, /* QoS is online */
BFA_QOS_OFFLINE = 2, /* QoS is offline */
};
@@ -670,6 +672,12 @@ struct bfa_itnim_iostats_s {
u32 tm_iocdowns; /* TM cleaned-up due to IOC down */
u32 tm_cleanups; /* TM cleanup requests */
u32 tm_cleanup_comps; /* TM cleanup completions */
+ u32 lm_lun_across_sg; /* LM lun is across sg data buf */
+ u32 lm_lun_not_sup; /* LM lun not supported */
+ u32 lm_rpl_data_changed; /* LM report-lun data changed */
+ u32 lm_wire_residue_changed; /* LM report-lun rsp residue changed */
+ u32 lm_small_buf_addresidue; /* LM buf smaller than reported cnt */
+ u32 lm_lun_not_rdy; /* LM lun not ready */
};
/* Modify char* port_stt[] in bfal_port.c if a new state was added */
@@ -785,8 +793,51 @@ enum bfa_port_linkstate_rsn {
CEE_ISCSI_PRI_PFC_OFF = 42,
CEE_ISCSI_PRI_OVERLAP_FCOE_PRI = 43
};
+
+#define MAX_LUN_MASK_CFG 16
+
+/*
+ * Initially flash content may be fff. On making LUN mask enable and disable
+ * state chnage. when report lun command is being processed it goes from
+ * BFA_LUN_MASK_ACTIVE to BFA_LUN_MASK_FETCH and comes back to
+ * BFA_LUN_MASK_ACTIVE.
+ */
+enum bfa_ioim_lun_mask_state_s {
+ BFA_IOIM_LUN_MASK_INACTIVE = 0,
+ BFA_IOIM_LUN_MASK_ACTIVE = 1,
+ BFA_IOIM_LUN_MASK_FETCHED = 2,
+};
+
+enum bfa_lunmask_state_s {
+ BFA_LUNMASK_DISABLED = 0x00,
+ BFA_LUNMASK_ENABLED = 0x01,
+ BFA_LUNMASK_MINCFG = 0x02,
+ BFA_LUNMASK_UNINITIALIZED = 0xff,
+};
+
#pragma pack(1)
/*
+ * LUN mask configuration
+ */
+struct bfa_lun_mask_s {
+ wwn_t lp_wwn;
+ wwn_t rp_wwn;
+ struct scsi_lun lun;
+ u8 ua;
+ u8 rsvd[3];
+ u16 rp_tag;
+ u8 lp_tag;
+ u8 state;
+};
+
+#define MAX_LUN_MASK_CFG 16
+struct bfa_lunmask_cfg_s {
+ u32 status;
+ u32 rsvd;
+ struct bfa_lun_mask_s lun_list[MAX_LUN_MASK_CFG];
+};
+
+/*
* Physical port configuration
*/
struct bfa_port_cfg_s {
@@ -1228,4 +1279,52 @@ struct bfa_cee_stats_s {
#pragma pack()
+/*
+ * AEN related definitions
+ */
+#define BFAD_NL_VENDOR_ID (((u64)0x01 << SCSI_NL_VID_TYPE_SHIFT) \
+ | BFA_PCI_VENDOR_ID_BROCADE)
+
+/* BFA remote port events */
+enum bfa_rport_aen_event {
+ BFA_RPORT_AEN_ONLINE = 1, /* RPort online event */
+ BFA_RPORT_AEN_OFFLINE = 2, /* RPort offline event */
+ BFA_RPORT_AEN_DISCONNECT = 3, /* RPort disconnect event */
+ BFA_RPORT_AEN_QOS_PRIO = 4, /* QOS priority change event */
+ BFA_RPORT_AEN_QOS_FLOWID = 5, /* QOS flow Id change event */
+};
+
+struct bfa_rport_aen_data_s {
+ u16 vf_id; /* vf_id of this logical port */
+ u16 rsvd[3];
+ wwn_t ppwwn; /* WWN of its physical port */
+ wwn_t lpwwn; /* WWN of this logical port */
+ wwn_t rpwwn; /* WWN of this remote port */
+ union {
+ struct bfa_rport_qos_attr_s qos;
+ } priv;
+};
+
+union bfa_aen_data_u {
+ struct bfa_adapter_aen_data_s adapter;
+ struct bfa_port_aen_data_s port;
+ struct bfa_lport_aen_data_s lport;
+ struct bfa_rport_aen_data_s rport;
+ struct bfa_itnim_aen_data_s itnim;
+ struct bfa_audit_aen_data_s audit;
+ struct bfa_ioc_aen_data_s ioc;
+};
+
+#define BFA_AEN_MAX_ENTRY 512
+
+struct bfa_aen_entry_s {
+ struct list_head qe;
+ enum bfa_aen_category aen_category;
+ u32 aen_type;
+ union bfa_aen_data_u aen_data;
+ struct timeval aen_tv;
+ u32 seq_num;
+ u32 bfad_num;
+};
+
#endif /* __BFA_DEFS_SVC_H__ */
diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h
index 8d0b88f67a38..50b6a1c86195 100644
--- a/drivers/scsi/bfa/bfa_fc.h
+++ b/drivers/scsi/bfa/bfa_fc.h
@@ -56,6 +56,161 @@ struct scsi_cdb_s {
#define SCSI_MAX_ALLOC_LEN 0xFF /* maximum allocarion length */
+#define SCSI_SENSE_CUR_ERR 0x70
+#define SCSI_SENSE_DEF_ERR 0x71
+
+/*
+ * SCSI additional sense codes
+ */
+#define SCSI_ASC_LUN_NOT_READY 0x04
+#define SCSI_ASC_LUN_NOT_SUPPORTED 0x25
+#define SCSI_ASC_TOCC 0x3F
+
+/*
+ * SCSI additional sense code qualifiers
+ */
+#define SCSI_ASCQ_MAN_INTR_REQ 0x03 /* manual intervention req */
+#define SCSI_ASCQ_RL_DATA_CHANGED 0x0E /* report luns data changed */
+
+/*
+ * Methods of reporting informational exceptions
+ */
+#define SCSI_MP_IEC_UNIT_ATTN 0x2 /* generate unit attention */
+
+struct scsi_report_luns_data_s {
+ u32 lun_list_length; /* length of LUN list length */
+ u32 reserved;
+ struct scsi_lun lun[1]; /* first LUN in lun list */
+};
+
+struct scsi_inquiry_vendor_s {
+ u8 vendor_id[8];
+};
+
+struct scsi_inquiry_prodid_s {
+ u8 product_id[16];
+};
+
+struct scsi_inquiry_prodrev_s {
+ u8 product_rev[4];
+};
+
+struct scsi_inquiry_data_s {
+#ifdef __BIG_ENDIAN
+ u8 peripheral_qual:3; /* peripheral qualifier */
+ u8 device_type:5; /* peripheral device type */
+ u8 rmb:1; /* removable medium bit */
+ u8 device_type_mod:7; /* device type modifier */
+ u8 version;
+ u8 aenc:1; /* async evt notification capability */
+ u8 trm_iop:1; /* terminate I/O process */
+ u8 norm_aca:1; /* normal ACA supported */
+ u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
+ u8 rsp_data_format:4;
+ u8 additional_len;
+ u8 sccs:1;
+ u8 reserved1:7;
+ u8 reserved2:1;
+ u8 enc_serv:1; /* enclosure service component */
+ u8 reserved3:1;
+ u8 multi_port:1; /* multi-port device */
+ u8 m_chngr:1; /* device in medium transport element */
+ u8 ack_req_q:1; /* SIP specific bit */
+ u8 addr32:1; /* SIP specific bit */
+ u8 addr16:1; /* SIP specific bit */
+ u8 rel_adr:1; /* relative address */
+ u8 w_bus32:1;
+ u8 w_bus16:1;
+ u8 synchronous:1;
+ u8 linked_commands:1;
+ u8 trans_dis:1;
+ u8 cmd_queue:1; /* command queueing supported */
+ u8 soft_reset:1; /* soft reset alternative (VS) */
+#else
+ u8 device_type:5; /* peripheral device type */
+ u8 peripheral_qual:3; /* peripheral qualifier */
+ u8 device_type_mod:7; /* device type modifier */
+ u8 rmb:1; /* removable medium bit */
+ u8 version;
+ u8 rsp_data_format:4;
+ u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
+ u8 norm_aca:1; /* normal ACA supported */
+ u8 terminate_iop:1;/* terminate I/O process */
+ u8 aenc:1; /* async evt notification capability */
+ u8 additional_len;
+ u8 reserved1:7;
+ u8 sccs:1;
+ u8 addr16:1; /* SIP specific bit */
+ u8 addr32:1; /* SIP specific bit */
+ u8 ack_req_q:1; /* SIP specific bit */
+ u8 m_chngr:1; /* device in medium transport element */
+ u8 multi_port:1; /* multi-port device */
+ u8 reserved3:1; /* TBD - Vendor Specific */
+ u8 enc_serv:1; /* enclosure service component */
+ u8 reserved2:1;
+ u8 soft_seset:1; /* soft reset alternative (VS) */
+ u8 cmd_queue:1; /* command queueing supported */
+ u8 trans_dis:1;
+ u8 linked_commands:1;
+ u8 synchronous:1;
+ u8 w_bus16:1;
+ u8 w_bus32:1;
+ u8 rel_adr:1; /* relative address */
+#endif
+ struct scsi_inquiry_vendor_s vendor_id;
+ struct scsi_inquiry_prodid_s product_id;
+ struct scsi_inquiry_prodrev_s product_rev;
+ u8 vendor_specific[20];
+ u8 reserved4[40];
+};
+
+/*
+ * SCSI sense data format
+ */
+struct scsi_sense_s {
+#ifdef __BIG_ENDIAN
+ u8 valid:1;
+ u8 rsp_code:7;
+#else
+ u8 rsp_code:7;
+ u8 valid:1;
+#endif
+ u8 seg_num;
+#ifdef __BIG_ENDIAN
+ u8 file_mark:1;
+ u8 eom:1; /* end of media */
+ u8 ili:1; /* incorrect length indicator */
+ u8 reserved:1;
+ u8 sense_key:4;
+#else
+ u8 sense_key:4;
+ u8 reserved:1;
+ u8 ili:1; /* incorrect length indicator */
+ u8 eom:1; /* end of media */
+ u8 file_mark:1;
+#endif
+ u8 information[4]; /* device-type or cmd specific info */
+ u8 add_sense_length; /* additional sense length */
+ u8 command_info[4];/* command specific information */
+ u8 asc; /* additional sense code */
+ u8 ascq; /* additional sense code qualifier */
+ u8 fru_code; /* field replaceable unit code */
+#ifdef __BIG_ENDIAN
+ u8 sksv:1; /* sense key specific valid */
+ u8 c_d:1; /* command/data bit */
+ u8 res1:2;
+ u8 bpv:1; /* bit pointer valid */
+ u8 bpointer:3; /* bit pointer */
+#else
+ u8 bpointer:3; /* bit pointer */
+ u8 bpv:1; /* bit pointer valid */
+ u8 res1:2;
+ u8 c_d:1; /* command/data bit */
+ u8 sksv:1; /* sense key specific valid */
+#endif
+ u8 fpointer[2]; /* field pointer */
+};
+
/*
* Fibre Channel Header Structure (FCHS) definition
*/
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
index a4e7951c6063..e07bd4745d8b 100644
--- a/drivers/scsi/bfa/bfa_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -24,6 +24,9 @@ BFA_TRC_FILE(HAL, FCPIM);
* BFA ITNIM Related definitions
*/
static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
+static bfa_boolean_t bfa_ioim_lm_proc_rpl_data(struct bfa_ioim_s *ioim);
+static bfa_boolean_t bfa_ioim_lm_proc_inq_data(struct bfa_ioim_s *ioim);
+static void bfa_ioim_lm_init(struct bfa_s *bfa);
#define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \
(((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1))))
@@ -57,6 +60,14 @@ static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
} \
} while (0)
+#define bfa_ioim_rp_wwn(__ioim) \
+ (((str