aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2011-09-15 09:08:05 -0400
committerJiri Kosina <jkosina@suse.cz>2011-09-15 09:08:18 -0400
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 @@
27struct bfa_s; 27struct bfa_s;
28 28
29typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m); 29typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m);
30typedef void (*bfa_cb_cbfn_status_t) (void *cbarg, bfa_status_t status);
30 31
31/* 32/*
32 * Interrupt message handlers 33 * Interrupt message handlers
@@ -121,6 +122,7 @@ bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg),
121#define bfa_cb_queue(__bfa, __hcb_qe, __cbfn, __cbarg) do { \ 122#define bfa_cb_queue(__bfa, __hcb_qe, __cbfn, __cbarg) do { \
122 (__hcb_qe)->cbfn = (__cbfn); \ 123 (__hcb_qe)->cbfn = (__cbfn); \
123 (__hcb_qe)->cbarg = (__cbarg); \ 124 (__hcb_qe)->cbarg = (__cbarg); \
125 (__hcb_qe)->pre_rmv = BFA_FALSE; \
124 list_add_tail(&(__hcb_qe)->qe, &(__bfa)->comp_q); \ 126 list_add_tail(&(__hcb_qe)->qe, &(__bfa)->comp_q); \
125 } while (0) 127 } while (0)
126 128
@@ -135,6 +137,11 @@ bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg),
135 } \ 137 } \
136 } while (0) 138 } while (0)
137 139
140#define bfa_cb_queue_status(__bfa, __hcb_qe, __status) do { \
141 (__hcb_qe)->fw_status = (__status); \
142 list_add_tail(&(__hcb_qe)->qe, &(__bfa)->comp_q); \
143} while (0)
144
138#define bfa_cb_queue_done(__hcb_qe) do { \ 145#define bfa_cb_queue_done(__hcb_qe) do { \
139 (__hcb_qe)->once = BFA_FALSE; \ 146 (__hcb_qe)->once = BFA_FALSE; \
140 } while (0) 147 } while (0)
@@ -177,7 +184,7 @@ struct bfa_msix_s {
177struct bfa_hwif_s { 184struct bfa_hwif_s {
178 void (*hw_reginit)(struct bfa_s *bfa); 185 void (*hw_reginit)(struct bfa_s *bfa);
179 void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq); 186 void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
180 void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq); 187 void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq, u32 ci);
181 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs); 188 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
182 void (*hw_msix_ctrl_install)(struct bfa_s *bfa); 189 void (*hw_msix_ctrl_install)(struct bfa_s *bfa);
183 void (*hw_msix_queue_install)(struct bfa_s *bfa); 190 void (*hw_msix_queue_install)(struct bfa_s *bfa);
@@ -268,10 +275,8 @@ struct bfa_iocfc_s {
268 ((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa)) 275 ((__bfa)->iocfc.hwif.hw_msix_queue_install(__bfa))
269#define bfa_msix_uninstall(__bfa) \ 276#define bfa_msix_uninstall(__bfa) \
270 ((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa)) 277 ((__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa))
271#define bfa_isr_rspq_ack(__bfa, __queue) do { \ 278#define bfa_isr_rspq_ack(__bfa, __queue, __ci) \
272 if ((__bfa)->iocfc.hwif.hw_rspq_ack) \ 279 ((__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue, __ci))
273 (__bfa)->iocfc.hwif.hw_rspq_ack(__bfa, __queue); \
274} while (0)
275#define bfa_isr_reqq_ack(__bfa, __queue) do { \ 280#define bfa_isr_reqq_ack(__bfa, __queue) do { \
276 if ((__bfa)->iocfc.hwif.hw_reqq_ack) \ 281 if ((__bfa)->iocfc.hwif.hw_reqq_ack) \
277 (__bfa)->iocfc.hwif.hw_reqq_ack(__bfa, __queue); \ 282 (__bfa)->iocfc.hwif.hw_reqq_ack(__bfa, __queue); \
@@ -311,7 +316,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec);
311void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); 316void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
312 317
313void bfa_hwcb_reginit(struct bfa_s *bfa); 318void bfa_hwcb_reginit(struct bfa_s *bfa);
314void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); 319void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
315void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); 320void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
316void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa); 321void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa);
317void bfa_hwcb_msix_queue_install(struct bfa_s *bfa); 322void 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,
324void bfa_hwct_reginit(struct bfa_s *bfa); 329void bfa_hwct_reginit(struct bfa_s *bfa);
325void bfa_hwct2_reginit(struct bfa_s *bfa); 330void bfa_hwct2_reginit(struct bfa_s *bfa);
326void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq); 331void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
327void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); 332void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
333void bfa_hwct2_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci);
328void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); 334void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
329void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa); 335void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa);
330void bfa_hwct_msix_queue_install(struct bfa_s *bfa); 336void bfa_hwct_msix_queue_install(struct bfa_s *bfa);
@@ -376,6 +382,22 @@ int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa,
376#define bfa_get_fw_clock_res(__bfa) \ 382#define bfa_get_fw_clock_res(__bfa) \
377 ((__bfa)->iocfc.cfgrsp->fwcfg.fw_tick_res) 383 ((__bfa)->iocfc.cfgrsp->fwcfg.fw_tick_res)
378 384
385/*
386 * lun mask macros return NULL when min cfg is enabled and there is
387 * no memory allocated for lunmask.
388 */
389#define bfa_get_lun_mask(__bfa) \
390 ((&(__bfa)->modules.dconf_mod)->min_cfg) ? NULL : \
391 (&(BFA_DCONF_MOD(__bfa)->dconf->lun_mask))
392
393#define bfa_get_lun_mask_list(_bfa) \
394 ((&(_bfa)->modules.dconf_mod)->min_cfg) ? NULL : \
395 (bfa_get_lun_mask(_bfa)->lun_list)
396
397#define bfa_get_lun_mask_status(_bfa) \
398 (((&(_bfa)->modules.dconf_mod)->min_cfg) \
399 ? BFA_LUNMASK_MINCFG : ((bfa_get_lun_mask(_bfa))->status))
400
379void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids); 401void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids);
380void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg); 402void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg);
381void bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg); 403void 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,
406 428
407void bfa_iocfc_enable(struct bfa_s *bfa); 429void bfa_iocfc_enable(struct bfa_s *bfa);
408void bfa_iocfc_disable(struct bfa_s *bfa); 430void bfa_iocfc_disable(struct bfa_s *bfa);
431void bfa_iocfc_cb_dconf_modinit(struct bfa_s *bfa, bfa_status_t status);
409#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \ 432#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \
410 bfa_timer_begin(&(_bfa)->timer_mod, _timer, _timercb, _arg, _timeout) 433 bfa_timer_begin(&(_bfa)->timer_mod, _timer, _timercb, _arg, _timeout)
411 434
435struct bfa_cb_pending_q_s {
436 struct bfa_cb_qe_s hcb_qe;
437 void *data; /* Driver buffer */
438};
439
440/* Common macros to operate on pending stats/attr apis */
441#define bfa_pending_q_init(__qe, __cbfn, __cbarg, __data) do { \
442 bfa_q_qe_init(&((__qe)->hcb_qe.qe)); \
443 (__qe)->hcb_qe.cbfn = (__cbfn); \
444 (__qe)->hcb_qe.cbarg = (__cbarg); \
445 (__qe)->hcb_qe.pre_rmv = BFA_TRUE; \
446 (__qe)->data = (__data); \
447} while (0)
448
412#endif /* __BFA_H__ */ 449#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[] = {
33 &hal_mod_uf, 33 &hal_mod_uf,
34 &hal_mod_rport, 34 &hal_mod_rport,
35 &hal_mod_fcp, 35 &hal_mod_fcp,
36 &hal_mod_dconf,
36 NULL 37 NULL
37}; 38};
38 39
@@ -237,8 +238,6 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
237 u32 pi, ci; 238 u32 pi, ci;
238 struct list_head *waitq; 239 struct list_head *waitq;
239 240
240 bfa_isr_rspq_ack(bfa, qid);
241
242 ci = bfa_rspq_ci(bfa, qid); 241 ci = bfa_rspq_ci(bfa, qid);
243 pi = bfa_rspq_pi(bfa, qid); 242 pi = bfa_rspq_pi(bfa, qid);
244 243
@@ -251,11 +250,9 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
251 } 250 }
252 251
253 /* 252 /*
254 * update CI 253 * acknowledge RME completions and update CI
255 */ 254 */
256 bfa_rspq_ci(bfa, qid) = pi; 255 bfa_isr_rspq_ack(bfa, qid, ci);
257 writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]);
258 mmiowb();
259 256
260 /* 257 /*
261 * Resume any pending requests in the corresponding reqq. 258 * Resume any pending requests in the corresponding reqq.
@@ -325,23 +322,19 @@ bfa_intx(struct bfa_s *bfa)
325 int queue; 322 int queue;
326 323
327 intr = readl(bfa->iocfc.bfa_regs.intr_status); 324 intr = readl(bfa->iocfc.bfa_regs.intr_status);
328 if (!intr)
329 return BFA_FALSE;
330 325
331 qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK); 326 qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK);
332 if (qintr) 327 if (qintr)
333 writel(qintr, bfa->iocfc.bfa_regs.intr_status); 328 writel(qintr, bfa->iocfc.bfa_regs.intr_status);
334 329
335 /* 330 /*
336 * RME completion queue interrupt 331 * Unconditional RME completion queue interrupt
337 */ 332 */
338 qintr = intr & __HFN_INT_RME_MASK; 333 if (bfa->queue_process) {
339 if (qintr && bfa->queue_process) {
340 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++) 334 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
341 bfa_isr_rspq(bfa, queue); 335 bfa_isr_rspq(bfa, queue);
342 } 336 }
343 337
344 intr &= ~qintr;
345 if (!intr) 338 if (!intr)
346 return BFA_TRUE; 339 return BFA_TRUE;
347 340
@@ -432,7 +425,8 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
432 __HFN_INT_MBOX_LPU1_CT2); 425 __HFN_INT_MBOX_LPU1_CT2);
433 intr &= __HFN_INT_ERR_MASK_CT2; 426 intr &= __HFN_INT_ERR_MASK_CT2;
434 } else { 427 } else {
435 halt_isr = intr & __HFN_INT_LL_HALT; 428 halt_isr = bfa_asic_id_ct(bfa->ioc.pcidev.device_id) ?
429 (intr & __HFN_INT_LL_HALT) : 0;
436 pss_isr = intr & __HFN_INT_ERR_PSS; 430 pss_isr = intr & __HFN_INT_ERR_PSS;
437 lpu_isr = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1); 431 lpu_isr = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1);
438 intr &= __HFN_INT_ERR_MASK; 432 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,
578 } else { 572 } else {
579 iocfc->hwif.hw_reginit = bfa_hwcb_reginit; 573 iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
580 iocfc->hwif.hw_reqq_ack = NULL; 574 iocfc->hwif.hw_reqq_ack = NULL;
581 iocfc->hwif.hw_rspq_ack = NULL; 575 iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
582 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; 576 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
583 iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install; 577 iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install;
584 iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install; 578 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,
595 if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) { 589 if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) {
596 iocfc->hwif.hw_reginit = bfa_hwct2_reginit; 590 iocfc->hwif.hw_reginit = bfa_hwct2_reginit;
597 iocfc->hwif.hw_isr_mode_set = NULL; 591 iocfc->hwif.hw_isr_mode_set = NULL;
598 iocfc->hwif.hw_rspq_ack = NULL; 592 iocfc->hwif.hw_rspq_ack = bfa_hwct2_rspq_ack;
599 } 593 }
600 594
601 iocfc->hwif.hw_reginit(bfa); 595 iocfc->hwif.hw_reginit(bfa);
@@ -685,7 +679,7 @@ bfa_iocfc_start_submod(struct bfa_s *bfa)
685 679
686 bfa->queue_process = BFA_TRUE; 680 bfa->queue_process = BFA_TRUE;
687 for (i = 0; i < BFI_IOC_MAX_CQS; i++) 681 for (i = 0; i < BFI_IOC_MAX_CQS; i++)
688 bfa_isr_rspq_ack(bfa, i); 682 bfa_isr_rspq_ack(bfa, i, bfa_rspq_ci(bfa, i));
689 683
690 for (i = 0; hal_mods[i]; i++) 684 for (i = 0; hal_mods[i]; i++)
691 hal_mods[i]->start(bfa); 685 hal_mods[i]->start(bfa);
@@ -709,7 +703,7 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
709 struct bfa_s *bfa = bfa_arg; 703 struct bfa_s *bfa = bfa_arg;
710 704
711 if (complete) { 705 if (complete) {
712 if (bfa->iocfc.cfgdone) 706 if (bfa->iocfc.cfgdone && BFA_DCONF_MOD(bfa)->flashdone)
713 bfa_cb_init(bfa->bfad, BFA_STATUS_OK); 707 bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
714 else 708 else
715 bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED); 709 bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
@@ -822,9 +816,11 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
822 */ 816 */
823 bfa_fcport_init(bfa); 817 bfa_fcport_init(bfa);
824 818
825 if (iocfc->action == BFA_IOCFC_ACT_INIT) 819 if (iocfc->action == BFA_IOCFC_ACT_INIT) {
826 bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa); 820 if (BFA_DCONF_MOD(bfa)->flashdone == BFA_TRUE)
827 else { 821 bfa_cb_queue(bfa, &iocfc->init_hcb_qe,
822 bfa_iocfc_init_cb, bfa);
823 } else {
828 if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE) 824 if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE)
829 bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe, 825 bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe,
830 bfa_iocfc_enable_cb, bfa); 826 bfa_iocfc_enable_cb, bfa);
@@ -1045,6 +1041,7 @@ bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
1045 } 1041 }
1046 1042
1047 bfa_iocfc_send_cfg(bfa); 1043 bfa_iocfc_send_cfg(bfa);
1044 bfa_dconf_modinit(bfa);
1048} 1045}
1049 1046
1050/* 1047/*
@@ -1207,7 +1204,9 @@ bfa_iocfc_stop(struct bfa_s *bfa)
1207 bfa->iocfc.action = BFA_IOCFC_ACT_STOP; 1204 bfa->iocfc.action = BFA_IOCFC_ACT_STOP;
1208 1205
1209 bfa->queue_process = BFA_FALSE; 1206 bfa->queue_process = BFA_FALSE;
1210 bfa_ioc_disable(&bfa->ioc); 1207 bfa_dconf_modexit(bfa);
1208 if (BFA_DCONF_MOD(bfa)->flashdone == BFA_TRUE)
1209 bfa_ioc_disable(&bfa->ioc);
1211} 1210}
1212 1211
1213void 1212void
@@ -1540,10 +1539,17 @@ bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
1540 struct list_head *qe; 1539 struct list_head *qe;
1541 struct list_head *qen; 1540 struct list_head *qen;
1542 struct bfa_cb_qe_s *hcb_qe; 1541 struct bfa_cb_qe_s *hcb_qe;
1542 bfa_cb_cbfn_status_t cbfn;
1543 1543
1544 list_for_each_safe(qe, qen, comp_q) { 1544 list_for_each_safe(qe, qen, comp_q) {
1545 hcb_qe = (struct bfa_cb_qe_s *) qe; 1545 hcb_qe = (struct bfa_cb_qe_s *) qe;
1546 hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE); 1546 if (hcb_qe->pre_rmv) {
1547 /* qe is invalid after return, dequeue before cbfn() */
1548 list_del(qe);
1549 cbfn = (bfa_cb_cbfn_status_t)(hcb_qe->cbfn);
1550 cbfn(hcb_qe->cbarg, hcb_qe->fw_status);
1551 } else
1552 hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
1547 } 1553 }
1548} 1554}
1549 1555
@@ -1556,10 +1562,20 @@ bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
1556 while (!list_empty(comp_q)) { 1562 while (!list_empty(comp_q)) {
1557 bfa_q_deq(comp_q, &qe); 1563 bfa_q_deq(comp_q, &qe);
1558 hcb_qe = (struct bfa_cb_qe_s *) qe; 1564 hcb_qe = (struct bfa_cb_qe_s *) qe;
1565 WARN_ON(hcb_qe->pre_rmv);
1559 hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE); 1566 hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE);
1560 } 1567 }
1561} 1568}
1562 1569
1570void
1571bfa_iocfc_cb_dconf_modinit(struct bfa_s *bfa, bfa_status_t status)
1572{
1573 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT) {
1574 if (bfa->iocfc.cfgdone == BFA_TRUE)
1575 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
1576 bfa_iocfc_init_cb, bfa);
1577 }
1578}
1563 1579
1564/* 1580/*
1565 * Return the list of PCI vendor/device id lists supported by this 1581 * 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 {
144 BFA_STATUS_INVLD_DFSZ = 24, /* Invalid Max data field size */ 144 BFA_STATUS_INVLD_DFSZ = 24, /* Invalid Max data field size */
145 BFA_STATUS_CMD_NOTSUPP = 26, /* Command/API not supported */ 145 BFA_STATUS_CMD_NOTSUPP = 26, /* Command/API not supported */
146 BFA_STATUS_FABRIC_RJT = 29, /* Reject from attached fabric */ 146 BFA_STATUS_FABRIC_RJT = 29, /* Reject from attached fabric */
147 BFA_STATUS_UNKNOWN_VWWN = 30, /* VPORT PWWN not found */
147 BFA_STATUS_PORT_OFFLINE = 34, /* Port is not online */ 148 BFA_STATUS_PORT_OFFLINE = 34, /* Port is not online */
148 BFA_STATUS_VPORT_WWN_BP = 46, /* WWN is same as base port's WWN */ 149 BFA_STATUS_VPORT_WWN_BP = 46, /* WWN is same as base port's WWN */
149 BFA_STATUS_PORT_NOT_DISABLED = 47, /* Port not disabled disable port */ 150 BFA_STATUS_PORT_NOT_DISABLED = 47, /* Port not disabled disable port */
@@ -164,6 +165,8 @@ enum bfa_status {
164 BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */ 165 BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */
165 BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot 166 BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot
166 * configuration */ 167 * configuration */
168 BFA_STATUS_BAD_FWCFG = 156, /* Bad firmware configuration */
169 BFA_STATUS_INVALID_VENDOR = 158, /* Invalid switch vendor */
167 BFA_STATUS_SFP_NOT_READY = 159, /* SFP info is not ready. Retry */ 170 BFA_STATUS_SFP_NOT_READY = 159, /* SFP info is not ready. Retry */
168 BFA_STATUS_TRUNK_ENABLED = 164, /* Trunk is already enabled on 171 BFA_STATUS_TRUNK_ENABLED = 164, /* Trunk is already enabled on
169 * this adapter */ 172 * this adapter */
@@ -172,11 +175,15 @@ enum bfa_status {
172 BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */ 175 BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */
173 BFA_STATUS_PHY_NOT_PRESENT = 183, /* PHY module not present */ 176 BFA_STATUS_PHY_NOT_PRESENT = 183, /* PHY module not present */
174 BFA_STATUS_FEATURE_NOT_SUPPORTED = 192, /* Feature not supported */ 177 BFA_STATUS_FEATURE_NOT_SUPPORTED = 192, /* Feature not supported */
178 BFA_STATUS_ENTRY_EXISTS = 193, /* Entry already exists */
179 BFA_STATUS_ENTRY_NOT_EXISTS = 194, /* Entry does not exist */
180 BFA_STATUS_NO_CHANGE = 195, /* Feature already in that state */
175 BFA_STATUS_FAA_ENABLED = 197, /* FAA is already enabled */ 181 BFA_STATUS_FAA_ENABLED = 197, /* FAA is already enabled */
176 BFA_STATUS_FAA_DISABLED = 198, /* FAA is already disabled */ 182 BFA_STATUS_FAA_DISABLED = 198, /* FAA is already disabled */
177 BFA_STATUS_FAA_ACQUIRED = 199, /* FAA is already acquired */ 183 BFA_STATUS_FAA_ACQUIRED = 199, /* FAA is already acquired */
178 BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */ 184 BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */
179 BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */ 185 BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */
186 BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */
180 BFA_STATUS_MAX_VAL /* Unknown error code */ 187 BFA_STATUS_MAX_VAL /* Unknown error code */
181}; 188};
182#define bfa_status_t enum bfa_status 189#define bfa_status_t enum bfa_status
@@ -359,6 +366,139 @@ struct bfa_ioc_attr_s {
359}; 366};
360 367
361/* 368/*
369 * AEN related definitions
370 */
371enum bfa_aen_category {
372 BFA_AEN_CAT_ADAPTER = 1,
373 BFA_AEN_CAT_PORT = 2,
374 BFA_AEN_CAT_LPORT = 3,
375 BFA_AEN_CAT_RPORT = 4,
376 BFA_AEN_CAT_ITNIM = 5,
377 BFA_AEN_CAT_AUDIT = 8,
378 BFA_AEN_CAT_IOC = 9,
379};
380
381/* BFA adapter level events */
382enum bfa_adapter_aen_event {
383 BFA_ADAPTER_AEN_ADD = 1, /* New Adapter found event */
384 BFA_ADAPTER_AEN_REMOVE = 2, /* Adapter removed event */
385};
386
387struct bfa_adapter_aen_data_s {
388 char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
389 u32 nports; /* Number of NPorts */
390 wwn_t pwwn; /* WWN of one of its physical port */
391};
392
393/* BFA physical port Level events */
394enum bfa_port_aen_event {
395 BFA_PORT_AEN_ONLINE = 1, /* Physical Port online event */
396 BFA_PORT_AEN_OFFLINE = 2, /* Physical Port offline event */
397 BFA_PORT_AEN_RLIR = 3, /* RLIR event, not supported */
398 BFA_PORT_AEN_SFP_INSERT = 4, /* SFP inserted event */
399 BFA_PORT_AEN_SFP_REMOVE = 5, /* SFP removed event */
400 BFA_PORT_AEN_SFP_POM = 6, /* SFP POM event */
401 BFA_PORT_AEN_ENABLE = 7, /* Physical Port enable event */
402 BFA_PORT_AEN_DISABLE = 8, /* Physical Port disable event */
403 BFA_PORT_AEN_AUTH_ON = 9, /* Physical Port auth success event */
404 BFA_PORT_AEN_AUTH_OFF = 10, /* Physical Port auth fail event */
405 BFA_PORT_AEN_DISCONNECT = 11, /* Physical Port disconnect event */
406 BFA_PORT_AEN_QOS_NEG = 12, /* Base Port QOS negotiation event */
407 BFA_PORT_AEN_FABRIC_NAME_CHANGE = 13, /* Fabric Name/WWN change */
408 BFA_PORT_AEN_SFP_ACCESS_ERROR = 14, /* SFP read error event */
409 BFA_PORT_AEN_SFP_UNSUPPORT = 15, /* Unsupported SFP event */
410};
411
412enum bfa_port_aen_sfp_pom {
413 BFA_PORT_AEN_SFP_POM_GREEN = 1, /* Normal */
414 BFA_PORT_AEN_SFP_POM_AMBER = 2, /* Warning */
415 BFA_PORT_AEN_SFP_POM_RED = 3, /* Critical */
416 BFA_PORT_AEN_SFP_POM_MAX = BFA_PORT_AEN_SFP_POM_RED
417};
418
419struct bfa_port_aen_data_s {
420 wwn_t pwwn; /* WWN of the physical port */
421 wwn_t fwwn; /* WWN of the fabric port */
422 u32 phy_port_num; /* For SFP related events */
423 u16 ioc_type;
424 u16 level; /* Only transitions will be informed */
425 mac_t mac; /* MAC address of the ethernet port */
426 u16 rsvd;
427};
428
429/* BFA AEN logical port events */
430enum bfa_lport_aen_event {
431 BFA_LPORT_AEN_NEW = 1, /* LPort created event */
432 BFA_LPORT_AEN_DELETE = 2, /* LPort deleted event */
433 BFA_LPORT_AEN_ONLINE = 3, /* LPort online event */
434 BFA_LPORT_AEN_OFFLINE = 4, /* LPort offline event */
435 BFA_LPORT_AEN_DISCONNECT = 5, /* LPort disconnect event */
436 BFA_LPORT_AEN_NEW_PROP = 6, /* VPort created event */
437 BFA_LPORT_AEN_DELETE_PROP = 7, /* VPort deleted event */
438 BFA_LPORT_AEN_NEW_STANDARD = 8, /* VPort created event */
439 BFA_LPORT_AEN_DELETE_STANDARD = 9, /* VPort deleted event */
440 BFA_LPORT_AEN_NPIV_DUP_WWN = 10, /* VPort with duplicate WWN */
441 BFA_LPORT_AEN_NPIV_FABRIC_MAX = 11, /* Max NPIV in fabric/fport */
442 BFA_LPORT_AEN_NPIV_UNKNOWN = 12, /* Unknown NPIV Error code */
443};
444
445struct bfa_lport_aen_data_s {
446 u16 vf_id; /* vf_id of this logical port */
447 u16 roles; /* Logical port mode,IM/TM/IP etc */
448 u32 rsvd;
449 wwn_t ppwwn; /* WWN of its physical port */
450 wwn_t lpwwn; /* WWN of this logical port */
451};
452
453/* BFA ITNIM events */
454enum bfa_itnim_aen_event {
455 BFA_ITNIM_AEN_ONLINE = 1, /* Target online */
456 BFA_ITNIM_AEN_OFFLINE = 2, /* Target offline */
457 BFA_ITNIM_AEN_DISCONNECT = 3, /* Target disconnected */
458};
459
460struct bfa_itnim_aen_data_s {
461 u16 vf_id; /* vf_id of the IT nexus */
462 u16 rsvd[3];
463 wwn_t ppwwn; /* WWN of its physical port */
464 wwn_t lpwwn; /* WWN of logical port */
465 wwn_t rpwwn; /* WWN of remote(target) port */
466};
467
468/* BFA audit events */
469enum bfa_audit_aen_event {
470 BFA_AUDIT_AEN_AUTH_ENABLE = 1,
471 BFA_AUDIT_AEN_AUTH_DISABLE = 2,
472 BFA_AUDIT_AEN_FLASH_ERASE = 3,
473 BFA_AUDIT_AEN_FLASH_UPDATE = 4,
474};
475
476struct bfa_audit_aen_data_s {
477 wwn_t pwwn;
478 int partition_inst;
479 int partition_type;
480};
481
482/* BFA IOC level events */
483enum bfa_ioc_aen_event {
484 BFA_IOC_AEN_HBGOOD = 1, /* Heart Beat restore event */
485 BFA_IOC_AEN_HBFAIL = 2, /* Heart Beat failure event */
486 BFA_IOC_AEN_ENABLE = 3, /* IOC enabled event */
487 BFA_IOC_AEN_DISABLE = 4, /* IOC disabled event */
488 BFA_IOC_AEN_FWMISMATCH = 5, /* IOC firmware mismatch */
489 BFA_IOC_AEN_FWCFG_ERROR = 6, /* IOC firmware config error */
490 BFA_IOC_AEN_INVALID_VENDOR = 7,
491 BFA_IOC_AEN_INVALID_NWWN = 8, /* Zero NWWN */
492 BFA_IOC_AEN_INVALID_PWWN = 9 /* Zero PWWN */
493};
494
495struct bfa_ioc_aen_data_s {
496 wwn_t pwwn;
497 u16 ioc_type;
498 mac_t mac;
499};
500
501/*
362 * ---------------------- mfg definitions ------------ 502 * ---------------------- mfg definitions ------------
363 */ 503 */
364 504
@@ -520,6 +660,20 @@ struct bfa_boot_bootlun_s {
520/* 660/*
521 * BOOT boot configuraton 661 * BOOT boot configuraton
522 */ 662 */
663struct bfa_boot_cfg_s {
664 u8 version;
665 u8 rsvd1;
666 u16 chksum;
667 u8 enable; /* enable/disable SAN boot */
668 u8 speed; /* boot speed settings */
669 u8 topology; /* boot topology setting */
670 u8 bootopt; /* bfa_boot_bootopt_t */
671 u32 nbluns; /* number of boot luns */
672 u32 rsvd2;
673 struct bfa_boot_bootlun_s blun[BFA_BOOT_BOOTLUN_MAX];
674 struct bfa_boot_bootlun_s blun_disc[BFA_BOOT_BOOTLUN_MAX];
675};
676
523struct bfa_boot_pbc_s { 677struct bfa_boot_pbc_s {
524 u8 enable; /* enable/disable SAN boot */ 678 u8 enable; /* enable/disable SAN boot */
525 u8 speed; /* boot speed settings */ 679 u8 speed; /* boot speed settings */
@@ -529,6 +683,15 @@ struct bfa_boot_pbc_s {
529 struct bfa_boot_bootlun_s pblun[BFA_PREBOOT_BOOTLUN_MAX]; 683 struct bfa_boot_bootlun_s pblun[BFA_PREBOOT_BOOTLUN_MAX];
530}; 684};
531 685
686struct bfa_ethboot_cfg_s {
687 u8 version;
688 u8 rsvd1;
689 u16 chksum;
690 u8 enable; /* enable/disable Eth/PXE boot */
691 u8 rsvd2;
692 u16 vlan;
693};
694
532/* 695/*
533 * ASIC block configuration related structures 696 * ASIC block configuration related structures
534 */ 697 */
@@ -587,6 +750,14 @@ struct bfa_ablk_cfg_s {
587 */ 750 */
588#define SFP_DIAGMON_SIZE 10 /* num bytes of diag monitor data */ 751#define SFP_DIAGMON_SIZE 10 /* num bytes of diag monitor data */
589 752
753/* SFP state change notification event */
754#define BFA_SFP_SCN_REMOVED 0
755#define BFA_SFP_SCN_INSERTED 1
756#define BFA_SFP_SCN_POM 2
757#define BFA_SFP_SCN_FAILED 3
758#define BFA_SFP_SCN_UNSUPPORT 4
759#define BFA_SFP_SCN_VALID 5
760
590enum bfa_defs_sfp_media_e { 761enum bfa_defs_sfp_media_e {
591 BFA_SFP_MEDIA_UNKNOWN = 0x00, 762 BFA_SFP_MEDIA_UNKNOWN = 0x00,
592 BFA_SFP_MEDIA_CU = 0x01, 763 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 {
268 u32 error_resets; /* error resets initiated by upsm */ 268 u32 error_resets; /* error resets initiated by upsm */
269 u32 sync_lost; /* Sync loss count */ 269 u32 sync_lost; /* Sync loss count */
270 u32 sig_lost; /* Signal loss count */ 270 u32 sig_lost; /* Signal loss count */
271 u32 asn8g_attempts; /* SNSM HWSM at 8Gbps attempts */
271}; 272};
272 273
273struct bfa_fw_port_physm_stats_s { 274struct bfa_fw_port_physm_stats_s {
@@ -468,6 +469,7 @@ struct bfa_fw_stats_s {
468 * QoS states 469 * QoS states
469 */ 470 */
470enum bfa_qos_state { 471enum bfa_qos_state {
472 BFA_QOS_DISABLED = 0, /* QoS is disabled */
471 BFA_QOS_ONLINE = 1, /* QoS is online */ 473 BFA_QOS_ONLINE = 1, /* QoS is online */
472 BFA_QOS_OFFLINE = 2, /* QoS is offline */ 474 BFA_QOS_OFFLINE = 2, /* QoS is offline */
473}; 475};
@@ -670,6 +672,12 @@ struct bfa_itnim_iostats_s {
670 u32 tm_iocdowns; /* TM cleaned-up due to IOC down */ 672 u32 tm_iocdowns; /* TM cleaned-up due to IOC down */
671 u32 tm_cleanups; /* TM cleanup requests */ 673 u32 tm_cleanups; /* TM cleanup requests */
672 u32 tm_cleanup_comps; /* TM cleanup completions */ 674 u32 tm_cleanup_comps; /* TM cleanup completions */
675 u32 lm_lun_across_sg; /* LM lun is across sg data buf */
676 u32 lm_lun_not_sup; /* LM lun not supported */
677 u32 lm_rpl_data_changed; /* LM report-lun data changed */
678 u32 lm_wire_residue_changed; /* LM report-lun rsp residue changed */
679 u32 lm_small_buf_addresidue; /* LM buf smaller than reported cnt */
680 u32 lm_lun_not_rdy; /* LM lun not ready */
673}; 681};
674 682
675/* Modify char* port_stt[] in bfal_port.c if a new state was added */ 683/* Modify char* port_stt[] in bfal_port.c if a new state was added */
@@ -785,8 +793,51 @@ enum bfa_port_linkstate_rsn {
785 CEE_ISCSI_PRI_PFC_OFF = 42, 793 CEE_ISCSI_PRI_PFC_OFF = 42,
786 CEE_ISCSI_PRI_OVERLAP_FCOE_PRI = 43 794 CEE_ISCSI_PRI_OVERLAP_FCOE_PRI = 43
787}; 795};
796
797#define MAX_LUN_MASK_CFG 16
798
799/*
800 * Initially flash content may be fff. On making LUN mask enable and disable
801 * state chnage. when report lun command is being processed it goes from
802 * BFA_LUN_MASK_ACTIVE to BFA_LUN_MASK_FETCH and comes back to
803 * BFA_LUN_MASK_ACTIVE.
804 */
805enum bfa_ioim_lun_mask_state_s {
806 BFA_IOIM_LUN_MASK_INACTIVE = 0,
807 BFA_IOIM_LUN_MASK_ACTIVE = 1,
808 BFA_IOIM_LUN_MASK_FETCHED = 2,
809};
810
811enum bfa_lunmask_state_s {
812 BFA_LUNMASK_DISABLED = 0x00,
813 BFA_LUNMASK_ENABLED = 0x01,
814 BFA_LUNMASK_MINCFG = 0x02,
815 BFA_LUNMASK_UNINITIALIZED = 0xff,
816};
817
788#pragma pack(1) 818#pragma pack(1)
789/* 819/*
820 * LUN mask configuration
821 */
822struct bfa_lun_mask_s {
823 wwn_t lp_wwn;
824 wwn_t rp_wwn;
825 struct scsi_lun lun;
826 u8 ua;
827 u8 rsvd[3];
828 u16 rp_tag;
829 u8 lp_tag;
830 u8 state;
831};
832
833#define MAX_LUN_MASK_CFG 16
834struct bfa_lunmask_cfg_s {
835 u32 status;
836 u32 rsvd;
837 struct bfa_lun_mask_s lun_list[MAX_LUN_MASK_CFG];
838};
839
840/*
790 * Physical port configuration 841 * Physical port configuration
791 */ 842 */
792struct bfa_port_cfg_s { 843struct bfa_port_cfg_s {
@@ -1228,4 +1279,52 @@ struct bfa_cee_stats_s {
1228 1279
1229#pragma pack() 1280#pragma pack()
1230 1281
1282/*
1283 * AEN related definitions
1284 */
1285#define BFAD_NL_VENDOR_ID (((u64)0x01 << SCSI_NL_VID_TYPE_SHIFT) \
1286 | BFA_PCI_VENDOR_ID_BROCADE)
1287
1288/* BFA remote port events */
1289enum bfa_rport_aen_event {
1290 BFA_RPORT_AEN_ONLINE = 1, /* RPort online event */
1291 BFA_RPORT_AEN_OFFLINE = 2, /* RPort offline event */
1292 BFA_RPORT_AEN_DISCONNECT = 3, /* RPort disconnect event */
1293 BFA_RPORT_AEN_QOS_PRIO = 4, /* QOS priority change event */
1294 BFA_RPORT_AEN_QOS_FLOWID = 5, /* QOS flow Id change event */
1295};
1296
1297struct bfa_rport_aen_data_s {
1298 u16 vf_id; /* vf_id of this logical port */
1299 u16 rsvd[3];
1300 wwn_t ppwwn; /* WWN of its physical port */
1301 wwn_t lpwwn; /* WWN of this logical port */
1302 wwn_t rpwwn; /* WWN of this remote port */
1303 union {
1304 struct bfa_rport_qos_attr_s qos;
1305 } priv;
1306};
1307
1308union bfa_aen_data_u {
1309 struct bfa_adapter_aen_data_s adapter;
1310 struct bfa_port_aen_data_s port;
1311 struct bfa_lport_aen_data_s lport;
1312 struct bfa_rport_aen_data_s rport;
1313 struct bfa_itnim_aen_data_s itnim;
1314 struct bfa_audit_aen_data_s audit;
1315 struct bfa_ioc_aen_data_s ioc;
1316};
1317
1318#define BFA_AEN_MAX_ENTRY 512
1319
1320struct bfa_aen_entry_s {
1321 struct list_head qe;
1322 enum bfa_aen_category aen_category;
1323 u32 aen_type;
1324 union bfa_aen_data_u aen_data;
1325 struct timeval aen_tv;
1326 u32 seq_num;
1327 u32 bfad_num;
1328};
1329
1231#endif /* __BFA_DEFS_SVC_H__ */ 1330#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 {
56 56
57#define SCSI_MAX_ALLOC_LEN 0xFF /* maximum allocarion length */ 57#define SCSI_MAX_ALLOC_LEN 0xFF /* maximum allocarion length */
58 58
59#define SCSI_SENSE_CUR_ERR 0x70
60#define SCSI_SENSE_DEF_ERR 0x71
61
62/*
63 * SCSI additional sense codes
64 */
65#define SCSI_ASC_LUN_NOT_READY 0x04
66#define SCSI_ASC_LUN_NOT_SUPPORTED 0x25
67#define SCSI_ASC_TOCC 0x3F
68
69/*
70 * SCSI additional sense code qualifiers
71 */
72#define SCSI_ASCQ_MAN_INTR_REQ 0x03 /* manual intervention req */
73#define SCSI_ASCQ_RL_DATA_CHANGED 0x0E /* report luns data changed */
74
75/*
76 * Methods of reporting informational exceptions
77 */
78#define SCSI_MP_IEC_UNIT_ATTN 0x2 /* generate unit attention */
79
80struct scsi_report_luns_data_s {
81 u32 lun_list_length; /* length of LUN list length */
82 u32 reserved;
83 struct scsi_lun lun[1]; /* first LUN in lun list */
84};
85
86struct scsi_inquiry_vendor_s {
87 u8 vendor_id[8];
88};
89
90struct scsi_inquiry_prodid_s {
91 u8 product_id[16];
92};
93
94struct scsi_inquiry_prodrev_s {
95 u8 product_rev[4];
96};
97
98struct scsi_inquiry_data_s {
99#ifdef __BIG_ENDIAN
100 u8 peripheral_qual:3; /* peripheral qualifier */
101 u8 device_type:5; /* peripheral device type */
102 u8 rmb:1; /* removable medium bit */
103 u8 device_type_mod:7; /* device type modifier */
104 u8 version;
105 u8 aenc:1; /* async evt notification capability */
106 u8 trm_iop:1; /* terminate I/O process */
107 u8 norm_aca:1; /* normal ACA supported */
108 u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
109 u8 rsp_data_format:4;
110 u8 additional_len;
111 u8 sccs:1;
112 u8 reserved1:7;
113 u8 reserved2:1;
114 u8 enc_serv:1; /* enclosure service component */
115 u8 reserved3:1;
116 u8 multi_port:1; /* multi-port device */
117 u8 m_chngr:1; /* device in medium transport element */
118 u8 ack_req_q:1; /* SIP specific bit */
119 u8 addr32:1; /* SIP specific bit */
120 u8 addr16:1; /* SIP specific bit */
121 u8 rel_adr:1; /* relative address */
122 u8 w_bus32:1;
123 u8 w_bus16:1;
124 u8 synchronous:1;
125 u8 linked_commands:1;
126 u8 trans_dis:1;
127 u8 cmd_queue:1; /* command queueing supported */
128 u8 soft_reset:1; /* soft reset alternative (VS) */
129#else
130 u8 device_type:5; /* peripheral device type */
131 u8 peripheral_qual:3; /* peripheral qualifier */
132 u8 device_type_mod:7; /* device type modifier */
133 u8 rmb:1; /* removable medium bit */
134 u8 version;
135 u8 rsp_data_format:4;
136 u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
137 u8 norm_aca:1; /* normal ACA supported */
138 u8 terminate_iop:1;/* terminate I/O process */
139 u8 aenc:1; /* async evt notification capability */
140 u8 additional_len;
141 u8 reserved1:7;
142 u8 sccs:1;
143 u8 addr16:1; /* SIP specific bit */
144 u8 addr32:1; /* SIP specific bit */
145 u8 ack_req_q:1; /* SIP specific bit */
146 u8 m_chngr:1; /* device in medium transport element */
147 u8 multi_port:1; /* multi-port device */
148 u8 reserved3:1; /* TBD - Vendor Specific */
149 u8 enc_serv:1; /* enclosure service component */
150 u8 reserved2:1;
151 u8 soft_seset:1; /* soft reset alternative (VS) */
152 u8 cmd_queue:1; /* command queueing supported */
153 u8 trans_dis:1;
154 u8 linked_commands:1;
155 u8 synchronous:1;
156 u8 w_bus16:1;
157 u8 w_bus32:1;
158 u8 rel_adr:1; /* relative address */
159#endif
160 struct scsi_inquiry_vendor_s vendor_id;
161 struct scsi_inquiry_prodid_s product_id;
162 struct scsi_inquiry_prodrev_s product_rev;
163 u8 vendor_specific[20];
164 u8 reserved4[40];
165};
166
167/*
168 * SCSI sense data format
169 */
170struct scsi_sense_s {
171#ifdef __BIG_ENDIAN
172 u8 valid:1;
173 u8 rsp_code:7;
174#else
175 u8 rsp_code:7;
176 u8 valid:1;
177#endif
178 u8 seg_num;
179#ifdef __BIG_ENDIAN
180 u8 file_mark:1;
181 u8 eom:1; /* end of media */
182 u8 ili:1; /* incorrect length indicator */
183 u8 reserved:1;
184 u8 sense_key:4;
185#else
186 u8 sense_key:4;
187 u8 reserved:1;
188 u8 ili:1; /* incorrect length indicator */
189 u8 eom:1; /* end of media */
190 u8 file_mark:1;
191#endif
192 u8 information[4]; /* device-type or cmd specific info */
193 u8 add_sense_length; /* additional sense length */
194 u8 command_info[4];/* command specific information */
195 u8 asc; /* additional sense code */
196 u8 ascq; /* additional sense code qualifier */
197 u8 fru_code; /* field replaceable unit code */
198#ifdef __BIG_ENDIAN
199 u8 sksv:1; /* sense key specific valid */
200 u8 c_d:1; /* command/data bit */
201 u8 res1:2;
202 u8 bpv:1; /* bit pointer valid */
203 u8 bpointer:3; /* bit pointer */
204#else
205 u8 bpointer:3; /* bit pointer */
206 u8 bpv:1; /* bit pointer valid */
207 u8 res1:2;
208 u8 c_d:1; /* command/data bit */
209 u8 sksv:1; /* sense key specific valid */
210#endif
211 u8 fpointer[2]; /* field pointer */
212};
213
59/* 214/*
60 * Fibre Channel Header Structure (FCHS) definition 215 * Fibre Channel Header Structure (FCHS) definition
61 */ 216 */
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);
24 * BFA ITNIM Related definitions 24 * BFA ITNIM Related definitions
25 */ 25 */
26static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim); 26static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
27static bfa_boolean_t bfa_ioim_lm_proc_rpl_data(struct bfa_ioim_s *ioim);
28static bfa_boolean_t bfa_ioim_lm_proc_inq_data(struct bfa_ioim_s *ioim);
29static void bfa_ioim_lm_init(struct bfa_s *bfa);
27 30
28#define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \ 31#define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \
29 (((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1)))) 32 (((_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);
57 } \ 60 } \
58} while (0) 61} while (0)
59 62
63#define bfa_ioim_rp_wwn(__ioim) \
64 (((struct bfa_fcs_rport_s *) \
65 (__ioim)->itnim->rport->rport_drv)->pwwn)
66
67#define bfa_ioim_lp_wwn(__ioim) \
68 ((BFA_LPS_FROM_TAG(BFA_LPS_MOD((__ioim)->bfa), \
69 (__ioim)->itnim->rport->rport_info.lp_tag))->pwwn) \
70
60#define bfa_itnim_sler_cb(__itnim) do { \ 71#define bfa_itnim_sler_cb(__itnim) do { \
61 if ((__itnim)->bfa->fcs) \ 72 if ((__itnim)->bfa->fcs) \
62 bfa_cb_itnim_sler((__itnim)->ditn); \ 73 bfa_cb_itnim_sler((__itnim)->ditn); \
@@ -66,6 +77,18 @@ static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
66 } \ 77 } \
67} while (0) 78} while (0)
68 79
80enum bfa_ioim_lm_status {
81 BFA_IOIM_LM_PRESENT = 1,
82 BFA_IOIM_LM_LUN_NOT_SUP = 2,
83 BFA_IOIM_LM_RPL_DATA_CHANGED = 3,
84 BFA_IOIM_LM_LUN_NOT_RDY = 4,
85};
86
87enum bfa_ioim_lm_ua_status {
88 BFA_IOIM_LM_UA_RESET = 0,
89 BFA_IOIM_LM_UA_SET = 1,
90};
91
69/* 92/*
70 * itnim state machine event 93 * itnim state machine event
71 */ 94 */
@@ -122,6 +145,9 @@ enum bfa_ioim_event {
122 BFA_IOIM_SM_TMDONE = 16, /* IO cleanup from tskim */ 145 BFA_IOIM_SM_TMDONE = 16, /* IO cleanup from tskim */
123 BFA_IOIM_SM_HWFAIL = 17, /* IOC h/w failure event */ 146 BFA_IOIM_SM_HWFAIL = 17, /* IOC h/w failure event */
124 BFA_IOIM_SM_IOTOV = 18, /* ITN offline TOV */ 147 BFA_IOIM_SM_IOTOV = 18, /* ITN offline TOV */
148 BFA_IOIM_SM_LM_LUN_NOT_SUP = 19,/* lunmask lun not supported */
149 BFA_IOIM_SM_LM_RPL_DC = 20, /* lunmask report-lun data changed */
150 BFA_IOIM_SM_LM_LUN_NOT_RDY = 21,/* lunmask lun not ready */
125}; 151};
126 152
127 153
@@ -219,6 +245,9 @@ static void __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete);
219static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete); 245static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete);
220static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete); 246static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete);
221static bfa_boolean_t bfa_ioim_is_abortable(struct bfa_ioim_s *ioim); 247static bfa_boolean_t bfa_ioim_is_abortable(struct bfa_ioim_s *ioim);
248static void __bfa_cb_ioim_lm_lun_not_sup(void *cbarg, bfa_boolean_t complete);
249static void __bfa_cb_ioim_lm_rpl_dc(void *cbarg, bfa_boolean_t complete);
250static void __bfa_cb_ioim_lm_lun_not_rdy(void *cbarg, bfa_boolean_t complete);
222 251
223/* 252/*
224 * forward declaration of BFA IO state machine 253 * forward declaration of BFA IO state machine
@@ -416,6 +445,12 @@ bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *lstats,
416 bfa_fcpim_add_iostats(lstats, rstats, output_reqs); 445 bfa_fcpim_add_iostats(lstats, rstats, output_reqs);
417 bfa_fcpim_add_iostats(lstats, rstats, rd_throughput); 446 bfa_fcpim_add_iostats(lstats, rstats, rd_throughput);
418 bfa_fcpim_add_iostats(lstats, rstats, wr_throughput); 447 bfa_fcpim_add_iostats(lstats, rstats, wr_throughput);
448 bfa_fcpim_add_iostats(lstats, rstats, lm_lun_across_sg);
449 bfa_fcpim_add_iostats(lstats, rstats, lm_lun_not_sup);
450 bfa_fcpim_add_iostats(lstats, rstats, lm_rpl_data_changed);
451 bfa_fcpim_add_iostats(lstats, rstats, lm_wire_residue_changed);
452 bfa_fcpim_add_iostats(lstats, rstats, lm_small_buf_addresidue);
453 bfa_fcpim_add_iostats(lstats, rstats, lm_lun_not_rdy);
419} 454}
420 455
421bfa_status_t 456bfa_status_t
@@ -437,6 +472,59 @@ bfa_fcpim_port_iostats(struct bfa_s *bfa,
437 return BFA_STATUS_OK; 472 return BFA_STATUS_OK;
438} 473}
439 474
475void
476bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
477{
478 struct bfa_itnim_latency_s *io_lat =
479 &(ioim->itnim->ioprofile.io_latency);
480 u32 val, idx;
481
482 val = (u32)(jiffies - ioim->start_time);
483 idx = bfa_ioim_get_index(scsi_bufflen((struct scsi_cmnd *)ioim->dio));
484 bfa_itnim_ioprofile_update(ioim->itnim, idx);
485
486 io_lat->count[idx]++;
487 io_lat->min[idx] = (io_lat->min[idx] < val) ? io_lat->min[idx] : val;
488 io_lat->max[idx] = (io_lat->max[idx] > val) ? io_lat->max[idx] : val;
489 io_lat->avg[idx] += val;
490}
491
492void
493bfa_ioim_profile_start(struct bfa_ioim_s *ioim)
494{
495 ioim->start_time = jiffies;
496}
497
498bfa_status_t
499bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time)
500{
501 struct bfa_itnim_s *itnim;
502 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
503 struct list_head *qe, *qen;
504
505 /* accumulate IO stats from itnim */
506 list_for_each_safe(qe, qen, &fcpim->itnim_q) {
507 itnim = (struct bfa_itnim_s *) qe;
508 bfa_itnim_clear_stats(itnim);
509 }
510 fcpim->io_profile = BFA_TRUE;
511 fcpim->io_profile_start_time = time;
512 fcpim->profile_comp = bfa_ioim_profile_comp;
513 fcpim->profile_start = bfa_ioim_profile_start;
514 return BFA_STATUS_OK;
515}
516
517bfa_status_t
518bfa_fcpim_profile_off(struct bfa_s *bfa)
519{
520 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
521 fcpim->io_profile = BFA_FALSE;
522 fcpim->io_profile_start_time = 0;
523 fcpim->profile_comp = NULL;
524 fcpim->profile_start = NULL;
525 return BFA_STATUS_OK;
526}
527
440u16 528u16
441bfa_fcpim_qdepth_get(struct bfa_s *bfa) 529bfa_fcpim_qdepth_get(struct bfa_s *bfa)
442{ 530{
@@ -1401,6 +1489,26 @@ bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
1401 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable)); 1489 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable));
1402} 1490}
1403 1491
1492#define bfa_io_lat_clock_res_div HZ
1493#define bfa_io_lat_clock_res_mul 1000
1494bfa_status_t
1495bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
1496 struct bfa_itnim_ioprofile_s *ioprofile)
1497{
1498 struct bfa_fcpim_s *fcpim = BFA_FCPIM(itnim->bfa);
1499 if (!fcpim->io_profile)
1500 return BFA_STATUS_IOPROFILE_OFF;
1501
1502 itnim->ioprofile.index = BFA_IOBUCKET_MAX;
1503 itnim->ioprofile.io_profile_start_time =
1504 bfa_io_profile_start_time(itnim->bfa);
1505 itnim->ioprofile.clock_res_mul = bfa_io_lat_clock_res_mul;
1506 itnim->ioprofile.clock_res_div = bfa_io_lat_clock_res_div;
1507 *ioprofile = itnim->ioprofile;
1508
1509 return BFA_STATUS_OK;
1510}
1511
1404void 1512void
1405bfa_itnim_clear_stats(struct bfa_itnim_s *itnim) 1513bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
1406{ 1514{
@@ -1469,7 +1577,28 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1469 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1577 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1470 WARN_ON(!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim)); 1578 WARN_ON(!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim));
1471 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, 1579 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1472 __bfa_cb_ioim_abort, ioim); 1580 __bfa_cb_ioim_abort, ioim);
1581 break;
1582
1583 case BFA_IOIM_SM_LM_LUN_NOT_SUP:
1584 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1585 bfa_ioim_move_to_comp_q(ioim);
1586 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1587 __bfa_cb_ioim_lm_lun_not_sup, ioim);
1588 break;
1589
1590 case BFA_IOIM_SM_LM_RPL_DC:
1591 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1592 bfa_ioim_move_to_comp_q(ioim);
1593 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1594 __bfa_cb_ioim_lm_rpl_dc, ioim);
1595 break;
1596
1597 case BFA_IOIM_SM_LM_LUN_NOT_RDY:
1598 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1599 bfa_ioim_move_to_comp_q(ioim);
1600 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1601 __bfa_cb_ioim_lm_lun_not_rdy, ioim);
1473 break; 1602 break;
1474 1603
1475 default: 1604 default:
@@ -2009,6 +2138,264 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2009 } 2138 }
2010} 2139}
2011 2140
2141/*
2142 * This is called from bfa_fcpim_start after the bfa_init() with flash read
2143 * is complete by driver. now invalidate the stale content of lun mask
2144 * like unit attention, rp tag and lp tag.
2145 */
2146static void
2147bfa_ioim_lm_init(struct bfa_s *bfa)
2148{
2149 struct bfa_lun_mask_s *lunm_list;
2150 int i;
2151
2152 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2153 return;
2154
2155 lunm_list = bfa_get_lun_mask_list(bfa);
2156 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2157 lunm_list[i].ua = BFA_IOIM_LM_UA_RESET;
2158 lunm_list[i].lp_tag = BFA_LP_TAG_INVALID;
2159 lunm_list[i].rp_tag = BFA_RPORT_TAG_INVALID;
2160 }
2161}
2162
2163/*
2164 * Validate LUN for LUN masking
2165 */
2166static enum bfa_ioim_lm_status
2167bfa_ioim_lm_check(struct bfa_ioim_s *ioim, struct bfa_lps_s *lps,
2168 struct bfa_rport_s *rp, struct scsi_lun lun)
2169{
2170 u8 i;
2171 struct bfa_lun_mask_s *lun_list = bfa_get_lun_mask_list(ioim->bfa);
2172 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)ioim->dio;
2173 struct scsi_cdb_s *cdb = (struct scsi_cdb_s *)cmnd->cmnd;
2174
2175 if ((cdb->scsi_cdb[0] == REPORT_LUNS) &&
2176 (scsilun_to_int((struct scsi_lun *)&lun) == 0)) {
2177 ioim->proc_rsp_data = bfa_ioim_lm_proc_rpl_data;
2178 return BFA_IOIM_LM_PRESENT;
2179 }
2180
2181 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2182
2183 if (lun_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
2184 continue;
2185
2186 if ((scsilun_to_int((struct scsi_lun *)&lun_list[i].lun) ==
2187 scsilun_to_int((struct scsi_lun *)&lun))
2188 && (rp->rport_tag == lun_list[i].rp_tag)
2189 && ((u8)ioim->itnim->rport->rport_info.lp_tag ==
2190 lun_list[i].lp_tag)) {
2191 bfa_trc(ioim->bfa, lun_list[i].rp_tag);
2192 bfa_trc(ioim->bfa, lun_list[i].lp_tag);
2193 bfa_trc(ioim->bfa, scsilun_to_int(
2194 (struct scsi_lun *)&lun_list[i].lun));
2195
2196 if ((lun_list[i].ua == BFA_IOIM_LM_UA_SET) &&
2197 ((cdb->scsi_cdb[0] != INQUIRY) ||
2198 (cdb->scsi_cdb[0] != REPORT_LUNS))) {
2199 lun_list[i].ua = BFA_IOIM_LM_UA_RESET;
2200 return BFA_IOIM_LM_RPL_DATA_CHANGED;
2201 }
2202
2203 if (cdb->scsi_cdb[0] == REPORT_LUNS)
2204 ioim->proc_rsp_data = bfa_ioim_lm_proc_rpl_data;
2205
2206 return BFA_IOIM_LM_PRESENT;
2207 }
2208 }
2209
2210 if ((cdb->scsi_cdb[0] == INQUIRY) &&
2211 (scsilun_to_int((struct scsi_lun *)&lun) == 0)) {
2212 ioim->proc_rsp_data = bfa_ioim_lm_proc_inq_data;
2213 return BFA_IOIM_LM_PRESENT;
2214 }
2215
2216 if (cdb->scsi_cdb[0] == TEST_UNIT_READY)
2217 return BFA_IOIM_LM_LUN_NOT_RDY;
2218
2219 return BFA_IOIM_LM_LUN_NOT_SUP;
2220}
2221
2222static bfa_boolean_t
2223bfa_ioim_lm_proc_rsp_data_dummy(struct bfa_ioim_s *ioim)
2224{
2225 return BFA_TRUE;
2226}
2227
2228static void
2229bfa_ioim_lm_fetch_lun(struct bfa_ioim_s *ioim, u8 *rl_data, int offset,
2230 int buf_lun_cnt)
2231{
2232 struct bfa_lun_mask_s *lun_list = bfa_get_lun_mask_list(ioim->bfa);
2233 struct scsi_lun *lun_data = (struct scsi_lun *)(rl_data + offset);
2234 struct scsi_lun lun;
2235 int i, j;
2236
2237 bfa_trc(ioim->bfa, buf_lun_cnt);
2238 for (j = 0; j < buf_lun_cnt; j++) {
2239 lun = *((struct scsi_lun *)(lun_data + j));
2240 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2241 if (lun_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
2242 continue;
2243 if ((lun_list[i].rp_wwn == bfa_ioim_rp_wwn(ioim)) &&
2244 (lun_list[i].lp_wwn == bfa_ioim_lp_wwn(ioim)) &&
2245 (scsilun_to_int((struct scsi_lun *)&lun_list[i].lun)
2246 == scsilun_to_int((struct scsi_lun *)&lun))) {
2247 lun_list[i].state = BFA_IOIM_LUN_MASK_FETCHED;
2248 break;
2249 }
2250 } /* next lun in mask DB */
2251 } /* next lun in buf */
2252}
2253
2254static int
2255bfa_ioim_lm_update_lun_sg(struct bfa_ioim_s *ioim, u32 *pgdlen,
2256 struct scsi_report_luns_data_s *rl)
2257{
2258 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)ioim->dio;
2259 struct scatterlist *sg = scsi_sglist(cmnd);
2260 struct bfa_lun_mask_s *lun_list = bfa_get_lun_mask_list(ioim->bfa);
2261 struct scsi_lun *prev_rl_data = NULL, *base_rl_data;
2262 int i, j, sgeid, lun_fetched_cnt = 0, prev_sg_len = 0, base_count;
2263 int lun_across_sg_bytes, bytes_from_next_buf;
2264 u64 last_lun, temp_last_lun;
2265
2266 /* fetch luns from the first sg element */
2267 bfa_ioim_lm_fetch_lun(ioim, (u8 *)(rl->lun), 0,
2268 (sg_dma_len(sg) / sizeof(struct scsi_lun)) - 1);
2269
2270 /* fetch luns from multiple sg elements */
2271 scsi_for_each_sg(cmnd, sg, scsi_sg_count(cmnd), sgeid) {
2272 if (sgeid == 0) {
2273 prev_sg_len = sg_dma_len(sg);
2274 prev_rl_data = (struct scsi_lun *)
2275 phys_to_virt(sg_dma_address(sg));
2276 continue;
2277 }
2278
2279 /* if the buf is having more data */
2280 lun_across_sg_bytes = prev_sg_len % sizeof(struct scsi_lun);
2281 if (lun_across_sg_bytes) {
2282 bfa_trc(ioim->bfa, lun_across_sg_bytes);
2283 bfa_stats(ioim->itnim, lm_lun_across_sg);
2284 bytes_from_next_buf = sizeof(struct scsi_lun) -
2285 lun_across_sg_bytes;
2286
2287 /* from next buf take higher bytes */
2288 temp_last_lun = *((u64 *)
2289 phys_to_virt(sg_dma_address(sg)));
2290 last_lun |= temp_last_lun >>
2291 (lun_across_sg_bytes * BITS_PER_BYTE);
2292
2293 /* from prev buf take higher bytes */
2294 temp_last_lun = *((u64 *)(prev_rl_data +
2295 (prev_sg_len - lun_across_sg_bytes)));
2296 temp_last_lun >>= bytes_from_next_buf * BITS_PER_BYTE;
2297 last_lun = last_lun | (temp_last_lun <<
2298 (bytes_from_next_buf * BITS_PER_BYTE));
2299
2300 bfa_ioim_lm_fetch_lun(ioim, (u8 *)&last_lun, 0, 1);
2301 } else
2302 bytes_from_next_buf = 0;
2303
2304 *pgdlen += sg_dma_len(sg);
2305 prev_sg_len = sg_dma_len(sg);
2306 prev_rl_data = (struct scsi_lun *)
2307 phys_to_virt(sg_dma_address(sg));
2308 bfa_ioim_lm_fetch_lun(ioim, (u8 *)prev_rl_data,
2309 bytes_from_next_buf,
2310 sg_dma_len(sg) / sizeof(struct scsi_lun));
2311 }
2312
2313 /* update the report luns data - based on fetched luns */
2314 sg = scsi_sglist(cmnd);
2315 base_rl_data = (struct scsi_lun *)rl->lun;
2316 base_count = (sg_dma_len(sg) / sizeof(struct scsi_lun)) - 1;
2317 for (i = 0, j = 0; i < MAX_LUN_MASK_CFG; i++) {
2318 if (lun_list[i].state == BFA_IOIM_LUN_MASK_FETCHED) {
2319 base_rl_data[j] = lun_list[i].lun;
2320 lun_list[i].state = BFA_IOIM_LUN_MASK_ACTIVE;
2321 j++;
2322 lun_fetched_cnt++;
2323 }
2324
2325 if (j > base_count) {
2326 j = 0;
2327 sg = sg_next(sg);
2328 base_rl_data = (struct scsi_lun *)
2329 phys_to_virt(sg_dma_address(sg));
2330 base_count = sg_dma_len(sg) / sizeof(struct scsi_lun);
2331 }
2332 }
2333
2334 bfa_trc(ioim->bfa, lun_fetched_cnt);
2335 return lun_fetched_cnt;
2336}
2337
2338static bfa_boolean_t
2339bfa_ioim_lm_proc_inq_data(struct bfa_ioim_s *ioim)
2340{
2341 struct scsi_inquiry_data_s *inq;
2342 struct scatterlist *sg = scsi_sglist((struct scsi_cmnd *)ioim->dio);
2343
2344 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2345 inq = (struct scsi_inquiry_data_s *)phys_to_virt(sg_dma_address(sg));
2346
2347 bfa_trc(ioim->bfa, inq->device_type);
2348 inq->peripheral_qual = SCSI_INQ_PQ_NOT_CON;
2349 return 0;
2350}
2351
2352static bfa_boolean_t
2353bfa_ioim_lm_proc_rpl_data(struct bfa_ioim_s *ioim)
2354{
2355 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)ioim->dio;
2356 struct scatterlist *sg = scsi_sglist(cmnd);
2357 struct bfi_ioim_rsp_s *m;
2358 struct scsi_report_luns_data_s *rl = NULL;
2359 int lun_count = 0, lun_fetched_cnt = 0;
2360 u32 residue, pgdlen = 0;
2361
2362 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2363 if (bfa_get_lun_mask_status(ioim->bfa) != BFA_LUNMASK_ENABLED)
2364 return BFA_TRUE;
2365
2366 m = (struct bfi_ioim_rsp_s *) &ioim->iosp->comp_rspmsg;
2367 if (m->scsi_status == SCSI_STATUS_CHECK_CONDITION)
2368 return BFA_TRUE;
2369
2370 pgdlen = sg_dma_len(sg);
2371 bfa_trc(ioim->bfa, pgdlen);
2372 rl = (struct scsi_report_luns_data_s *)phys_to_virt(sg_dma_address(sg));
2373 lun_count = cpu_to_be32(rl->lun_list_length) / sizeof(struct scsi_lun);
2374 lun_fetched_cnt = bfa_ioim_lm_update_lun_sg(ioim, &pgdlen, rl);
2375
2376 if (lun_count == lun_fetched_cnt)
2377 return BFA_TRUE;
2378
2379 bfa_trc(ioim->bfa, lun_count);
2380 bfa_trc(ioim->bfa, lun_fetched_cnt);
2381 bfa_trc(ioim->bfa, be32_to_cpu(rl->lun_list_length));
2382
2383 if (be32_to_cpu(rl->lun_list_length) <= pgdlen)
2384 rl->lun_list_length = be32_to_cpu(lun_fetched_cnt) *
2385 sizeof(struct scsi_lun);
2386 else
2387 bfa_stats(ioim->itnim, lm_small_buf_addresidue);
2388
2389 bfa_trc(ioim->bfa, be32_to_cpu(rl->lun_list_length));
2390 bfa_trc(ioim->bfa, be32_to_cpu(m->residue));
2391
2392 residue = be32_to_cpu(m->residue);
2393 residue += (lun_count - lun_fetched_cnt) * sizeof(struct scsi_lun);
2394 bfa_stats(ioim->itnim, lm_wire_residue_changed);
2395 m->residue = be32_to_cpu(residue);
2396 bfa_trc(ioim->bfa, ioim->nsges);
2397 return BFA_FALSE;
2398}
2012 2399
2013static void 2400static void
2014__bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete) 2401__bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete)
@@ -2068,6 +2455,299 @@ __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
2068} 2455}
2069 2456
2070static void 2457static void
2458__bfa_cb_ioim_lm_lun_not_sup(void *cbarg, bfa_boolean_t complete)
2459{
2460 struct bfa_ioim_s *ioim = cbarg;
2461 int sns_len = 0xD;
2462 u32 residue = scsi_bufflen((struct scsi_cmnd *)ioim->dio);
2463 struct scsi_sense_s *snsinfo;
2464
2465 if (!complete) {
2466 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2467 return;
2468 }
2469
2470 snsinfo = (struct scsi_sense_s *)BFA_SNSINFO_FROM_TAG(
2471 ioim->fcpim->fcp, ioim->iotag);
2472 snsinfo->rsp_code = SCSI_SENSE_CUR_ERR;
2473 snsinfo->add_sense_length = 0xa;
2474 snsinfo->asc = SCSI_ASC_LUN_NOT_SUPPORTED;
2475 snsinfo->sense_key = ILLEGAL_REQUEST;
2476 bfa_trc(ioim->bfa, residue);
2477 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_OK,
2478 SCSI_STATUS_CHECK_CONDITION, sns_len,
2479 (u8 *)snsinfo, residue);
2480}
2481
2482static void
2483__bfa_cb_ioim_lm_rpl_dc(void *cbarg, bfa_boolean_t complete)
2484{
2485 struct bfa_ioim_s *ioim = cbarg;
2486 int sns_len = 0xD;
2487 u32 residue = scsi_bufflen((struct scsi_cmnd *)ioim->dio);
2488 struct scsi_sense_s *snsinfo;
2489
2490 if (!complete) {
2491 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2492 return;
2493 }
2494
2495 snsinfo = (struct scsi_sense_s *)BFA_SNSINFO_FROM_TAG(ioim->fcpim->fcp,
2496 ioim->iotag);
2497 snsinfo->rsp_code = SCSI_SENSE_CUR_ERR;
2498 snsinfo->sense_key = SCSI_MP_IEC_UNIT_ATTN;
2499 snsinfo->asc = SCSI_ASC_TOCC;
2500 snsinfo->add_sense_length = 0x6;
2501 snsinfo->ascq = SCSI_ASCQ_RL_DATA_CHANGED;
2502 bfa_trc(ioim->bfa, residue);
2503 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_OK,
2504 SCSI_STATUS_CHECK_CONDITION, sns_len,
2505 (u8 *)snsinfo, residue);
2506}
2507
2508static void
2509__bfa_cb_ioim_lm_lun_not_rdy(void *cbarg, bfa_boolean_t complete)
2510{
2511 struct bfa_ioim_s *ioim = cbarg;
2512 int sns_len = 0xD;
2513 u32 residue = scsi_bufflen((struct scsi_cmnd *)ioim->dio);
2514 struct scsi_sense_s *snsinfo;
2515
2516 if (!complete) {
2517 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2518 return;
2519 }
2520
2521 snsinfo = (struct scsi_sense_s *)BFA_SNSINFO_FROM_TAG(
2522 ioim->fcpim->fcp, ioim->iotag);
2523 snsinfo->rsp_code = SCSI_SENSE_CUR_ERR;
2524 snsinfo->add_sense_length = 0xa;
2525 snsinfo->sense_key = NOT_READY;
2526 snsinfo->asc = SCSI_ASC_LUN_NOT_READY;
2527 snsinfo->ascq = SCSI_ASCQ_MAN_INTR_REQ;
2528 bfa_trc(ioim->bfa, residue);
2529 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_OK,
2530 SCSI_STATUS_CHECK_CONDITION, sns_len,
2531 (u8 *)snsinfo, residue);
2532}
2533
2534void
2535bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn, wwn_t rp_wwn,
2536 u16 rp_tag, u8 lp_tag)
2537{
2538 struct bfa_lun_mask_s *lun_list;
2539 u8 i;
2540
2541 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2542 return;
2543
2544 lun_list = bfa_get_lun_mask_list(bfa);
2545 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2546 if (lun_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE) {
2547 if ((lun_list[i].lp_wwn == lp_wwn) &&
2548 (lun_list[i].rp_wwn == rp_wwn)) {
2549 lun_list[i].rp_tag = rp_tag;
2550 lun_list[i].lp_tag = lp_tag;
2551 }
2552 }
2553 }
2554}
2555
2556/*
2557 * set UA for all active luns in LM DB
2558 */
2559static void
2560bfa_ioim_lm_set_ua(struct bfa_s *bfa)
2561{
2562 struct bfa_lun_mask_s *lunm_list;
2563 int i;
2564
2565 lunm_list = bfa_get_lun_mask_list(bfa);
2566 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2567 if (lunm_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
2568 continue;
2569 lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
2570 }
2571}
2572
2573bfa_status_t
2574bfa_fcpim_lunmask_update(struct bfa_s *bfa, u32 update)
2575{
2576 struct bfa_lunmask_cfg_s *lun_mask;
2577
2578 bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
2579 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2580 return BFA_STATUS_FAILED;
2581
2582 if (bfa_get_lun_mask_status(bfa) == update)
2583 return BFA_STATUS_NO_CHANGE;
2584
2585 lun_mask = bfa_get_lun_mask(bfa);
2586 lun_mask->status = update;
2587
2588 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_ENABLED)
2589 bfa_ioim_lm_set_ua(bfa);
2590
2591 return bfa_dconf_update(bfa);
2592}
2593
2594bfa_status_t
2595bfa_fcpim_lunmask_clear(struct bfa_s *bfa)
2596{
2597 int i;
2598 struct bfa_lun_mask_s *lunm_list;
2599
2600 bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
2601 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2602 return BFA_STATUS_FAILED;
2603
2604 lunm_list = bfa_get_lun_mask_list(bfa);
2605 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2606 if (lunm_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE) {
2607 if (lunm_list[i].rp_tag != BFA_RPORT_TAG_INVALID)
2608 bfa_rport_unset_lunmask(bfa,
2609 BFA_RPORT_FROM_TAG(bfa, lunm_list[i].rp_tag));
2610 }
2611 }
2612
2613 memset(lunm_list, 0, sizeof(struct bfa_lun_mask_s) * MAX_LUN_MASK_CFG);
2614 return bfa_dconf_update(bfa);
2615}
2616
2617bfa_status_t
2618bfa_fcpim_lunmask_query(struct bfa_s *bfa, void *buf)
2619{
2620 struct bfa_lunmask_cfg_s *lun_mask;
2621
2622 bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
2623 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2624 return BFA_STATUS_FAILED;
2625
2626 lun_mask = bfa_get_lun_mask(bfa);
2627 memcpy(buf, lun_mask, sizeof(struct bfa_lunmask_cfg_s));
2628 return BFA_STATUS_OK;
2629}
2630
2631bfa_status_t
2632bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id, wwn_t *pwwn,
2633 wwn_t rpwwn, struct scsi_lun lun)
2634{
2635 struct bfa_lun_mask_s *lunm_list;
2636 struct bfa_rport_s *rp = NULL;
2637 int i, free_index = MAX_LUN_MASK_CFG + 1;
2638 struct bfa_fcs_lport_s *port = NULL;
2639 struct bfa_fcs_rport_s *rp_fcs;
2640
2641 bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
2642 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2643 return BFA_STATUS_FAILED;
2644
2645 port = bfa_fcs_lookup_port(&((struct bfad_s *)bfa->bfad)->bfa_fcs,
2646 vf_id, *pwwn);
2647 if (port) {
2648 *pwwn = port->port_cfg.pwwn;
2649 rp_fcs = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
2650 rp = rp_fcs->bfa_rport;
2651 }
2652
2653 lunm_list = bfa_get_lun_mask_list(bfa);
2654 /* if entry exists */
2655 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2656 if (lunm_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
2657 free_index = i;
2658 if ((lunm_list[i].lp_wwn == *pwwn) &&
2659 (lunm_list[i].rp_wwn == rpwwn) &&
2660 (scsilun_to_int((struct scsi_lun *)&lunm_list[i].lun) ==
2661 scsilun_to_int((struct scsi_lun *)&lun)))
2662 return BFA_STATUS_ENTRY_EXISTS;
2663 }
2664
2665 if (free_index > MAX_LUN_MASK_CFG)
2666 return BFA_STATUS_MAX_ENTRY_REACHED;
2667
2668 if (rp) {
2669 lunm_list[free_index].lp_tag = bfa_lps_get_tag_from_pid(bfa,
2670 rp->rport_info.local_pid);
2671 lunm_list[free_index].rp_tag = rp->rport_tag;
2672 } else {
2673 lunm_list[free_index].lp_tag = BFA_LP_TAG_INVALID;
2674 lunm_list[free_index].rp_tag = BFA_RPORT_TAG_INVALID;
2675 }
2676
2677 lunm_list[free_index].lp_wwn = *pwwn;
2678 lunm_list[free_index].rp_wwn = rpwwn;
2679 lunm_list[free_index].lun = lun;
2680 lunm_list[free_index].state = BFA_IOIM_LUN_MASK_ACTIVE;
2681
2682 /* set for all luns in this rp */
2683 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2684 if ((lunm_list[i].lp_wwn == *pwwn) &&
2685 (lunm_list[i].rp_wwn == rpwwn))
2686 lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
2687 }
2688
2689 return bfa_dconf_update(bfa);
2690}
2691
2692bfa_status_t
2693bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id, wwn_t *pwwn,
2694 wwn_t rpwwn, struct scsi_lun lun)
2695{
2696 struct bfa_lun_mask_s *lunm_list;
2697 struct bfa_rport_s *rp = NULL;
2698 struct bfa_fcs_lport_s *port = NULL;
2699 struct bfa_fcs_rport_s *rp_fcs;
2700 int i;
2701
2702 /* in min cfg lunm_list could be NULL but no commands should run. */
2703 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2704 return BFA_STATUS_FAILED;
2705
2706 bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
2707 bfa_trc(bfa, *pwwn);
2708 bfa_trc(bfa, rpwwn);
2709 bfa_trc(bfa, scsilun_to_int((struct scsi_lun *)&lun));
2710
2711 if (*pwwn == 0) {
2712 port = bfa_fcs_lookup_port(
2713 &((struct bfad_s *)bfa->bfad)->bfa_fcs,
2714 vf_id, *pwwn);
2715 if (port) {
2716 *pwwn = port->port_cfg.pwwn;
2717 rp_fcs = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
2718 rp = rp_fcs->bfa_rport;
2719 }
2720 }
2721
2722 lunm_list = bfa_get_lun_mask_list(bfa);
2723 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2724 if ((lunm_list[i].lp_wwn == *pwwn) &&
2725 (lunm_list[i].rp_wwn == rpwwn) &&
2726 (scsilun_to_int((struct scsi_lun *)&lunm_list[i].lun) ==
2727 scsilun_to_int((struct scsi_lun *)&lun))) {
2728 lunm_list[i].lp_wwn = 0;
2729 lunm_list[i].rp_wwn = 0;
2730 int_to_scsilun(0, &lunm_list[i].lun);
2731 lunm_list[i].state = BFA_IOIM_LUN_MASK_INACTIVE;
2732 if (lunm_list[i].rp_tag != BFA_RPORT_TAG_INVALID) {
2733 lunm_list[i].rp_tag = BFA_RPORT_TAG_INVALID;
2734 lunm_list[i].lp_tag = BFA_LP_TAG_INVALID;
2735 }
2736 return bfa_dconf_update(bfa);
2737 }
2738 }
2739
2740 /* set for all luns in this rp */
2741 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2742 if ((lunm_list[i].lp_wwn == *pwwn) &&
2743 (lunm_list[i].rp_wwn == rpwwn))
2744 lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
2745 }
2746
2747 return BFA_STATUS_ENTRY_NOT_EXISTS;
2748}
2749
2750static void
2071__bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete) 2751__bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
2072{ 2752{
2073 struct bfa_ioim_s *ioim = cbarg; 2753 struct bfa_ioim_s *ioim = cbarg;
@@ -2077,6 +2757,7 @@ __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
2077 return; 2757 return;
2078 } 2758 }
2079 2759
2760 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2080 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED, 2761 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED,
2081 0, 0, NULL, 0); 2762 0, 0, NULL, 0);
2082} 2763}
@@ -2092,6 +2773,7 @@ __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete)
2092 return; 2773 return;
2093 } 2774 }
2094 2775
2776 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2095 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV, 2777 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV,
2096 0, 0, NULL, 0); 2778 0, 0, NULL, 0);
2097} 2779}
@@ -2106,6 +2788,7 @@ __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete)
2106 return; 2788 return;
2107 } 2789 }
2108 2790
2791 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2109 bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio); 2792 bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio);
2110} 2793}
2111 2794
@@ -2449,6 +3132,7 @@ bfa_ioim_attach(struct bfa_fcpim_s *fcpim)
2449 ioim->bfa = fcpim->bfa; 3132 ioim->bfa = fcpim->bfa;
2450 ioim->fcpim = fcpim; 3133 ioim->fcpim = fcpim;
2451 ioim->iosp = iosp; 3134 ioim->iosp = iosp;
3135 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2452 INIT_LIST_HEAD(&ioim->sgpg_q); 3136 INIT_LIST_HEAD(&ioim->sgpg_q);
2453 bfa_reqq_winit(&ioim->iosp->reqq_wait, 3137 bfa_reqq_winit(&ioim->iosp->reqq_wait,
2454 bfa_ioim_qresume, ioim); 3138 bfa_ioim_qresume, ioim);
@@ -2486,6 +3170,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2486 evt = BFA_IOIM_SM_DONE; 3170 evt = BFA_IOIM_SM_DONE;
2487 else 3171 else
2488 evt = BFA_IOIM_SM_COMP; 3172 evt = BFA_IOIM_SM_COMP;
3173 ioim->proc_rsp_data(ioim);
2489 break; 3174 break;
2490 3175
2491 case BFI_IOIM_STS_TIMEDOUT: 3176 case BFI_IOIM_STS_TIMEDOUT:
@@ -2521,6 +3206,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2521 if (rsp->abort_tag != ioim->abort_tag) { 3206 if (rsp->abort_tag != ioim->abort_tag) {
2522 bfa_trc(ioim->bfa, rsp->abort_tag); 3207 bfa_trc(ioim->bfa, rsp->abort_tag);
2523 bfa_trc(ioim->bfa, ioim->abort_tag); 3208 bfa_trc(ioim->bfa, ioim->abort_tag);
3209 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2524 return; 3210 return;
2525 } 3211 }
2526 3212
@@ -2539,6 +3225,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2539 WARN_ON(1); 3225 WARN_ON(1);
2540 } 3226 }
2541 3227
3228 ioim->proc_rsp_data = bfa_ioim_lm_proc_rsp_data_dummy;
2542 bfa_sm_send_event(ioim, evt); 3229 bfa_sm_send_event(ioim, evt);
2543} 3230}
2544 3231
@@ -2556,7 +3243,16 @@ bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2556 WARN_ON(BFA_IOIM_TAG_2_ID(ioim->iotag) != iotag); 3243 WARN_ON(BFA_IOIM_TAG_2_ID(ioim->iotag) != iotag);
2557 3244
2558 bfa_ioim_cb_profile_comp(fcpim, ioim); 3245 bfa_ioim_cb_profile_comp(fcpim, ioim);
2559 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD); 3246
3247 if (bfa_get_lun_mask_status(bfa) != BFA_LUNMASK_ENABLED) {
3248 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
3249 return;
3250 }
3251
3252 if (ioim->proc_rsp_data(ioim) == BFA_TRUE)
3253 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
3254 else
3255 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP);
2560} 3256}
2561 3257
2562/* 3258/*
@@ -2668,6 +3364,35 @@ bfa_ioim_free(struct bfa_ioim_s *ioim)
2668void 3364void
2669bfa_ioim_start(struct bfa_ioim_s *ioim) 3365bfa_ioim_start(struct bfa_ioim_s *ioim)
2670{ 3366{
3367 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)ioim->dio;
3368 struct bfa_lps_s *lps;
3369 enum bfa_ioim_lm_status status;
3370 struct scsi_lun scsilun;
3371
3372 if (bfa_get_lun_mask_status(ioim->bfa) == BFA_LUNMASK_ENABLED) {
3373 lps = BFA_IOIM_TO_LPS(ioim);
3374 int_to_scsilun(cmnd->device->lun, &scsilun);
3375 status = bfa_ioim_lm_check(ioim, lps,
3376 ioim->itnim->rport, scsilun);
3377 if (status == BFA_IOIM_LM_LUN_NOT_RDY) {
3378 bfa_sm_send_event(ioim, BFA_IOIM_SM_LM_LUN_NOT_RDY);
3379 bfa_stats(ioim->itnim, lm_lun_not_rdy);
3380 return;
3381 }
3382
3383 if (status == BFA_IOIM_LM_LUN_NOT_SUP) {
3384 bfa_sm_send_event(ioim, BFA_IOIM_SM_LM_LUN_NOT_SUP);
3385 bfa_stats(ioim->itnim, lm_lun_not_sup);
3386 return;
3387 }
3388
3389 if (status == BFA_IOIM_LM_RPL_DATA_CHANGED) {
3390 bfa_sm_send_event(ioim, BFA_IOIM_SM_LM_RPL_DC);
3391 bfa_stats(ioim->itnim, lm_rpl_data_changed);
3392 return;
3393 }
3394 }
3395
2671 bfa_ioim_cb_profile_start(ioim->fcpim, ioim); 3396 bfa_ioim_cb_profile_start(ioim->fcpim, ioim);
2672 3397
2673 /* 3398 /*
@@ -3411,6 +4136,13 @@ bfa_fcp_detach(struct bfa_s *bfa)
3411static void 4136static void
3412bfa_fcp_start(struct bfa_s *bfa) 4137bfa_fcp_start(struct bfa_s *bfa)
3413{ 4138{
4139 struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
4140
4141 /*
4142 * bfa_init() with flash read is complete. now invalidate the stale
4143 * content of lun mask like unit attention, rp tag and lp tag.
4144 */
4145 bfa_ioim_lm_init(fcp->bfa);
3414} 4146}
3415 4147
3416static void 4148static void
diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h
index 57b695ad4ee5..1080bcb81cb7 100644
--- a/drivers/scsi/bfa/bfa_fcpim.h
+++ b/drivers/scsi/bfa/bfa_fcpim.h
@@ -79,14 +79,22 @@ bfa_ioim_get_index(u32 n) {
79 if (n >= (1UL)<<22) 79 if (n >= (1UL)<<22)
80 return BFA_IOBUCKET_MAX - 1; 80 return BFA_IOBUCKET_MAX - 1;
81 n >>= 8; 81 n >>= 8;
82 if (n >= (1UL)<<16) 82 if (n >= (1UL)<<16) {
83 n >>= 16; pos += 16; 83 n >>= 16;
84 if (n >= 1 << 8) 84 pos += 16;
85 n >>= 8; pos += 8; 85 }
86 if (n >= 1 << 4) 86 if (n >= 1 << 8) {
87 n >>= 4; pos += 4; 87 n >>= 8;
88 if (n >= 1 << 2) 88 pos += 8;
89 n >>= 2; pos += 2; 89 }
90 if (n >= 1 << 4) {
91 n >>= 4;
92 pos += 4;
93 }
94 if (n >= 1 << 2) {
95 n >>= 2;
96 pos += 2;
97 }
90 if (n >= 1 << 1) 98 if (n >= 1 << 1)
91 pos += 1; 99 pos += 1;
92 100
@@ -102,6 +110,7 @@ struct bfad_ioim_s;
102struct bfad_tskim_s; 110struct bfad_tskim_s;
103 111
104typedef void (*bfa_fcpim_profile_t) (struct bfa_ioim_s *ioim); 112typedef void (*bfa_fcpim_profile_t) (struct bfa_ioim_s *ioim);
113typedef bfa_boolean_t (*bfa_ioim_lm_proc_rsp_data_t) (struct bfa_ioim_s *ioim);
105 114
106struct bfa_fcpim_s { 115struct bfa_fcpim_s {
107 struct bfa_s *bfa; 116 struct bfa_s *bfa;
@@ -115,7 +124,7 @@ struct bfa_fcpim_s {
115 u32 path_tov; 124 u32 path_tov;
116 u16 q_depth; 125 u16 q_depth;
117 u8 reqq; /* Request queue to be used */ 126 u8 reqq; /* Request queue to be used */
118 u8 rsvd; 127 u8 lun_masking_pending;
119 struct list_head itnim_q; /* queue of active itnim */ 128 struct list_head itnim_q; /* queue of active itnim */
120 struct list_head ioim_resfree_q; /* IOs waiting for f/w */ 129 struct list_head ioim_resfree_q; /* IOs waiting for f/w */
121 struct list_head ioim_comp_q; /* IO global comp Q */ 130 struct list_head ioim_comp_q; /* IO global comp Q */
@@ -170,7 +179,9 @@ struct bfa_ioim_s {
170 bfa_cb_cbfn_t io_cbfn; /* IO completion handler */ 179 bfa_cb_cbfn_t io_cbfn; /* IO completion handler */
171 struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */ 180 struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
172 u8 reqq; /* Request queue for I/O */ 181 u8 reqq; /* Request queue for I/O */
182 u8 mode; /* IO is passthrough or not */
173 u64 start_time; /* IO's Profile start val */ 183 u64 start_time; /* IO's Profile start val */
184 bfa_ioim_lm_proc_rsp_data_t proc_rsp_data; /* RSP data adjust */
174}; 185};
175 186
176struct bfa_ioim_sp_s { 187struct bfa_ioim_sp_s {
@@ -250,6 +261,10 @@ struct bfa_itnim_s {
250 (__ioim)->iotag |= k << BFA_IOIM_RETRY_TAG_OFFSET; \ 261 (__ioim)->iotag |= k << BFA_IOIM_RETRY_TAG_OFFSET; \
251} while (0) 262} while (0)
252 263
264#define BFA_IOIM_TO_LPS(__ioim) \
265 BFA_LPS_FROM_TAG(BFA_LPS_MOD(__ioim->bfa), \
266 __ioim->itnim->rport->rport_info.lp_tag)
267
253static inline bfa_boolean_t 268static inline bfa_boolean_t
254bfa_ioim_maxretry_reached(struct bfa_ioim_s *ioim) 269bfa_ioim_maxretry_reached(struct bfa_ioim_s *ioim)
255{ 270{
@@ -297,6 +312,8 @@ bfa_status_t bfa_fcpim_port_iostats(struct bfa_s *bfa,
297 struct bfa_itnim_iostats_s *stats, u8 lp_tag); 312 struct bfa_itnim_iostats_s *stats, u8 lp_tag);
298void bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *fcpim_stats, 313void bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *fcpim_stats,
299 struct bfa_itnim_iostats_s *itnim_stats); 314 struct bfa_itnim_iostats_s *itnim_stats);
315bfa_status_t bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time);
316bfa_status_t bfa_fcpim_profile_off(struct bfa_s *bfa);
300 317
301#define bfa_fcpim_ioredirect_enabled(__bfa) \ 318#define bfa_fcpim_ioredirect_enabled(__bfa) \
302 (((struct bfa_fcpim_s *)(BFA_FCPIM(__bfa)))->ioredirect) 319 (((struct bfa_fcpim_s *)(BFA_FCPIM(__bfa)))->ioredirect)
@@ -397,4 +414,14 @@ void bfa_tskim_start(struct bfa_tskim_s *tskim,
397void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk, 414void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
398 enum bfi_tskim_status tsk_status); 415 enum bfi_tskim_status tsk_status);
399 416
417void bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn,
418 wwn_t rp_wwn, u16 rp_tag, u8 lp_tag);
419bfa_status_t bfa_fcpim_lunmask_update(struct bfa_s *bfa, u32 on_off);
420bfa_status_t bfa_fcpim_lunmask_query(struct bfa_s *bfa, void *buf);
421bfa_status_t bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id,
422 wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun);
423bfa_status_t bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id,
424 wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun);
425bfa_status_t bfa_fcpim_lunmask_clear(struct bfa_s *bfa);
426
400#endif /* __BFA_FCPIM_H__ */ 427#endif /* __BFA_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index a9b22bc48bc3..eaac57e1ddec 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include "bfad_drv.h" 22#include "bfad_drv.h"
23#include "bfad_im.h"
23#include "bfa_fcs.h" 24#include "bfa_fcs.h"
24#include "bfa_fcbuild.h" 25#include "bfa_fcbuild.h"
25 26
@@ -1327,6 +1328,29 @@ bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1327 bfa_trc(fabric->fcs, status); 1328 bfa_trc(fabric->fcs, status);
1328} 1329}
1329 1330
1331
1332/*
1333 * Send AEN notification
1334 */
1335static void
1336bfa_fcs_fabric_aen_post(struct bfa_fcs_lport_s *port,
1337 enum bfa_port_aen_event event)
1338{
1339 struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
1340 struct bfa_aen_entry_s *aen_entry;
1341
1342 bfad_get_aen_entry(bfad, aen_entry);
1343 if (!aen_entry)
1344 return;
1345
1346 aen_entry->aen_data.port.pwwn = bfa_fcs_lport_get_pwwn(port);
1347 aen_entry->aen_data.port.fwwn = bfa_fcs_lport_get_fabric_name(port);
1348
1349 /* Send the AEN notification */
1350 bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
1351 BFA_AEN_CAT_PORT, event);
1352}
1353
1330/* 1354/*
1331 * 1355 *
1332 * @param[in] fabric - fabric 1356 * @param[in] fabric - fabric
@@ -1358,6 +1382,8 @@ bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1358 BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 1382 BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
1359 "Base port WWN = %s Fabric WWN = %s\n", 1383 "Base port WWN = %s Fabric WWN = %s\n",
1360 pwwn_ptr, fwwn_ptr); 1384 pwwn_ptr, fwwn_ptr);
1385 bfa_fcs_fabric_aen_post(&fabric->bport,
1386 BFA_PORT_AEN_FABRIC_NAME_CHANGE);
1361 } 1387 }
1362} 1388}
1363 1389
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h
index a5f1faf335a7..e75e07d25915 100644
--- a/drivers/scsi/bfa/bfa_fcs.h
+++ b/drivers/scsi/bfa/bfa_fcs.h
@@ -675,6 +675,7 @@ struct bfa_fcs_s {
675 struct bfa_fcs_fabric_s fabric; /* base fabric state machine */ 675 struct bfa_fcs_fabric_s fabric; /* base fabric state machine */
676 struct bfa_fcs_stats_s stats; /* FCS statistics */ 676 struct bfa_fcs_stats_s stats; /* FCS statistics */
677 struct bfa_wc_s wc; /* waiting counter */ 677 struct bfa_wc_s wc; /* waiting counter */
678 int fcs_aen_seq;
678}; 679};
679 680
680/* 681/*
diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c
index 29b4108be269..9272840a2409 100644
--- a/drivers/scsi/bfa/bfa_fcs_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c
@@ -37,6 +37,8 @@ static void bfa_fcs_itnim_prli_response(void *fcsarg,
37 struct bfa_fcxp_s *fcxp, void *cbarg, 37 struct bfa_fcxp_s *fcxp, void *cbarg,
38 bfa_status_t req_status, u32 rsp_len, 38 bfa_status_t req_status, u32 rsp_len,
39 u32 resid_len, struct fchs_s *rsp_fchs); 39 u32 resid_len, struct fchs_s *rsp_fchs);
40static void bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
41 enum bfa_itnim_aen_event event);
40 42
41/* 43/*
42 * fcs_itnim_sm FCS itnim state machine events 44 * fcs_itnim_sm FCS itnim state machine events
@@ -269,6 +271,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
269 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 271 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
270 "Target (WWN = %s) is online for initiator (WWN = %s)\n", 272 "Target (WWN = %s) is online for initiator (WWN = %s)\n",
271 rpwwn_buf, lpwwn_buf); 273 rpwwn_buf, lpwwn_buf);
274 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_ONLINE);
272 break; 275 break;
273 276
274 case BFA_FCS_ITNIM_SM_OFFLINE: 277 case BFA_FCS_ITNIM_SM_OFFLINE:
@@ -305,14 +308,17 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
305 bfa_itnim_offline(itnim->bfa_itnim); 308 bfa_itnim_offline(itnim->bfa_itnim);
306 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port)); 309 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
307 wwn2str(rpwwn_buf, itnim->rport->pwwn); 310 wwn2str(rpwwn_buf, itnim->rport->pwwn);
308 if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE) 311 if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE) {
309 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 312 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
310 "Target (WWN = %s) connectivity lost for " 313 "Target (WWN = %s) connectivity lost for "
311 "initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf); 314 "initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf);
312 else 315 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_DISCONNECT);
316 } else {
313 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 317 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
314 "Target (WWN = %s) offlined by initiator (WWN = %s)\n", 318 "Target (WWN = %s) offlined by initiator (WWN = %s)\n",
315 rpwwn_buf, lpwwn_buf); 319 rpwwn_buf, lpwwn_buf);
320 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_OFFLINE);
321 }
316 break; 322 break;
317 323
318 case BFA_FCS_ITNIM_SM_DELETE: 324 case BFA_FCS_ITNIM_SM_DELETE:
@@ -382,6 +388,33 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
382} 388}
383 389
384static void 390static void
391bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
392 enum bfa_itnim_aen_event event)
393{
394 struct bfa_fcs_rport_s *rport = itnim->rport;
395 struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
396 struct bfa_aen_entry_s *aen_entry;
397
398 /* Don't post events for well known addresses */
399 if (BFA_FCS_PID_IS_WKA(rport->pid))
400 return;
401
402 bfad_get_aen_entry(bfad, aen_entry);
403 if (!aen_entry)
404 return;
405
406 aen_entry->aen_data.itnim.vf_id = rport->port->fabric->vf_id;
407 aen_entry->aen_data.itnim.ppwwn = bfa_fcs_lport_get_pwwn(
408 bfa_fcs_get_base_port(itnim->fcs));
409 aen_entry->aen_data.itnim.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
410 aen_entry->aen_data.itnim.rpwwn = rport->pwwn;
411
412 /* Send the AEN notification */
413 bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
414 BFA_AEN_CAT_ITNIM, event);
415}
416
417static void
385bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced) 418bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced)
386{ 419{
387 struct bfa_fcs_itnim_s *itnim = itnim_cbarg; 420 struct bfa_fcs_itnim_s *itnim = itnim_cbarg;
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index f8251a91ba91..d4f951fe753e 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include "bfad_drv.h" 18#include "bfad_drv.h"
19#include "bfad_im.h"
19#include "bfa_fcs.h" 20#include "bfa_fcs.h"
20#include "bfa_fcbuild.h" 21#include "bfa_fcbuild.h"
21#include "bfa_fc.h" 22#include "bfa_fc.h"
@@ -300,6 +301,31 @@ bfa_fcs_lport_sm_deleting(
300 */ 301 */
301 302
302/* 303/*
304 * Send AEN notification
305 */
306static void
307bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port,
308 enum bfa_lport_aen_event event)
309{
310 struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
311 struct bfa_aen_entry_s *aen_entry;
312
313 bfad_get_aen_entry(bfad, aen_entry);
314 if (!aen_entry)
315 return;
316
317 aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
318 aen_entry->aen_data.lport.roles = port->port_cfg.roles;
319 aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
320 bfa_fcs_get_base_port(port->fcs));
321 aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
322
323 /* Send the AEN notification */
324 bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
325 BFA_AEN_CAT_LPORT, event);
326}
327
328/*
303 * Send a LS reject 329 * Send a LS reject
304 */ 330 */
305static void 331static void
@@ -593,6 +619,7 @@ bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
593 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 619 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
594 "Logical port online: WWN = %s Role = %s\n", 620 "Logical port online: WWN = %s Role = %s\n",
595 lpwwn_buf, "Initiator"); 621 lpwwn_buf, "Initiator");
622 bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE);
596 623
597 bfad->bfad_flags |= BFAD_PORT_ONLINE; 624 bfad->bfad_flags |= BFAD_PORT_ONLINE;
598} 625}
@@ -611,14 +638,17 @@ bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
611 638
612 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 639 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
613 if (bfa_sm_cmp_state(port->fabric, 640 if (bfa_sm_cmp_state(port->fabric,
614 bfa_fcs_fabric_sm_online) == BFA_TRUE) 641 bfa_fcs_fabric_sm_online) == BFA_TRUE) {
615 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 642 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
616 "Logical port lost fabric connectivity: WWN = %s Role = %s\n", 643 "Logical port lost fabric connectivity: WWN = %s Role = %s\n",
617 lpwwn_buf, "Initiator"); 644 lpwwn_buf, "Initiator");
618 else 645 bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
646 } else {
619 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 647 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
620 "Logical port taken offline: WWN = %s Role = %s\n", 648 "Logical port taken offline: WWN = %s Role = %s\n",
621 lpwwn_buf, "Initiator"); 649 lpwwn_buf, "Initiator");
650 bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE);
651 }
622 652
623 list_for_each_safe(qe, qen, &port->rport_q) { 653 list_for_each_safe(qe, qen, &port->rport_q) {
624 rport = (struct bfa_fcs_rport_s *) qe; 654 rport = (struct bfa_fcs_rport_s *) qe;
@@ -676,6 +706,7 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
676 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 706 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
677 "Logical port deleted: WWN = %s Role = %s\n", 707 "Logical port deleted: WWN = %s Role = %s\n",
678 lpwwn_buf, "Initiator"); 708 lpwwn_buf, "Initiator");
709 bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE);
679 710
680 /* Base port will be deleted by the OS driver */ 711 /* Base port will be deleted by the OS driver */
681 if (port->vport) { 712 if (port->vport) {
@@ -973,6 +1004,7 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
973 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 1004 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
974 "New logical port created: WWN = %s Role = %s\n", 1005 "New logical port created: WWN = %s Role = %s\n",
975 lpwwn_buf, "Initiator"); 1006 lpwwn_buf, "Initiator");
1007 bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW);
976 1008
977 bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit); 1009 bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit);
978 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); 1010 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
@@ -5559,6 +5591,31 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
5559 * fcs_vport_private FCS virtual port private functions 5591 * fcs_vport_private FCS virtual port private functions
5560 */ 5592 */
5561/* 5593/*
5594 * Send AEN notification
5595 */
5596static void
5597bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port,
5598 enum bfa_lport_aen_event event)
5599{
5600 struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
5601 struct bfa_aen_entry_s *aen_entry;
5602
5603 bfad_get_aen_entry(bfad, aen_entry);
5604 if (!aen_entry)
5605 return;
5606
5607 aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
5608 aen_entry->aen_data.lport.roles = port->port_cfg.roles;
5609 aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
5610 bfa_fcs_get_base_port(port->fcs));
5611 aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
5612
5613 /* Send the AEN notification */
5614 bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
5615 BFA_AEN_CAT_LPORT, event);
5616}
5617
5618/*
5562 * This routine will be called to send a FDISC command. 5619 * This routine will be called to send a FDISC command.
5563 */ 5620 */
5564static void 5621static void
@@ -5585,8 +5642,11 @@ bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
5585 case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */ 5642 case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
5586 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 5643 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
5587 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5644 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5588 else 5645 else {
5646 bfa_fcs_vport_aen_post(&vport->lport,
5647 BFA_LPORT_AEN_NPIV_DUP_WWN);
5589 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN); 5648 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN);
5649 }
5590 break; 5650 break;
5591 5651
5592 case FC_LS_RJT_EXP_INSUFF_RES: 5652 case FC_LS_RJT_EXP_INSUFF_RES:
@@ -5596,11 +5656,17 @@ bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
5596 */ 5656 */
5597 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 5657 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
5598 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5658 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5599 else 5659 else {
5660 bfa_fcs_vport_aen_post(&vport->lport,
5661 BFA_LPORT_AEN_NPIV_FABRIC_MAX);
5600 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); 5662 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
5663 }
5601 break; 5664 break;
5602 5665
5603 default: 5666 default:
5667 if (vport->fdisc_retries == 0)
5668 bfa_fcs_vport_aen_post(&vport->lport,
5669 BFA_LPORT_AEN_NPIV_UNKNOWN);
5604 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5670 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
5605 } 5671 }
5606} 5672}
diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c
index 2c514458a6b4..52628d5d3c9b 100644
--- a/drivers/scsi/bfa/bfa_fcs_rport.c
+++ b/drivers/scsi/bfa/bfa_fcs_rport.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include "bfad_drv.h" 22#include "bfad_drv.h"
23#include "bfad_im.h"
23#include "bfa_fcs.h" 24#include "bfa_fcs.h"
24#include "bfa_fcbuild.h" 25#include "bfa_fcbuild.h"
25 26
@@ -2041,6 +2042,35 @@ bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
2041} 2042}
2042 2043
2043static void 2044static void
2045bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
2046 enum bfa_rport_aen_event event,
2047 struct bfa_rport_aen_data_s *data)
2048{
2049 struct bfa_fcs_lport_s *port = rport->port;
2050 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2051 struct bfa_aen_entry_s *aen_entry;
2052
2053 bfad_get_aen_entry(bfad, aen_entry);
2054 if (!aen_entry)
2055 return;
2056
2057 if (event == BFA_RPORT_AEN_QOS_PRIO)
2058 aen_entry->aen_data.rport.priv.qos = data->priv.qos;
2059 else if (event == BFA_RPORT_AEN_QOS_FLOWID)
2060 aen_entry->aen_data.rport.priv.qos = data->priv.qos;
2061
2062 aen_entry->aen_data.rport.vf_id = rport->port->fabric->vf_id;
2063 aen_entry->aen_data.rport.ppwwn = bfa_fcs_lport_get_pwwn(
2064 bfa_fcs_get_base_port(rport->fcs));
2065 aen_entry->aen_data.rport.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
2066 aen_entry->aen_data.rport.rpwwn = rport->pwwn;
2067
2068 /* Send the AEN notification */
2069 bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
2070 BFA_AEN_CAT_RPORT, event);
2071}
2072
2073static void
2044bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport) 2074bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
2045{ 2075{
2046 struct bfa_fcs_lport_s *port = rport->port; 2076 struct bfa_fcs_lport_s *port = rport->port;
@@ -2063,10 +2093,12 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
2063 2093
2064 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 2094 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2065 wwn2str(rpwwn_buf, rport->pwwn); 2095 wwn2str(rpwwn_buf, rport->pwwn);
2066 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2096 if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2067 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2097 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2068 "Remote port (WWN = %s) online for logical port (WWN = %s)\n", 2098 "Remote port (WWN = %s) online for logical port (WWN = %s)\n",
2069 rpwwn_buf, lpwwn_buf); 2099 rpwwn_buf, lpwwn_buf);
2100 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
2101 }
2070} 2102}
2071 2103
2072static void 2104static void
@@ -2083,16 +2115,21 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
2083 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 2115 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2084 wwn2str(rpwwn_buf, rport->pwwn); 2116 wwn2str(rpwwn_buf, rport->pwwn);
2085 if (!BFA_FCS_PID_IS_WKA(rport->pid)) { 2117 if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2086 if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) 2118 if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) {
2087 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2119 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2088 "Remote port (WWN = %s) connectivity lost for " 2120 "Remote port (WWN = %s) connectivity lost for "
2089 "logical port (WWN = %s)\n", 2121 "logical port (WWN = %s)\n",
2090 rpwwn_buf, lpwwn_buf); 2122 rpwwn_buf, lpwwn_buf);
2091 else 2123 bfa_fcs_rport_aen_post(rport,
2124 BFA_RPORT_AEN_DISCONNECT, NULL);
2125 } else {
2092 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2126 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2093 "Remote port (WWN = %s) offlined by " 2127 "Remote port (WWN = %s) offlined by "
2094 "logical port (WWN = %s)\n", 2128 "logical port (WWN = %s)\n",
2095 rpwwn_buf, lpwwn_buf); 2129 rpwwn_buf, lpwwn_buf);
2130 bfa_fcs_rport_aen_post(rport,
2131 BFA_RPORT_AEN_OFFLINE, NULL);
2132 }
2096 } 2133 }
2097 2134
2098 if (bfa_fcs_lport_is_initiator(port)) { 2135 if (bfa_fcs_lport_is_initiator(port)) {
@@ -2366,8 +2403,11 @@ bfa_cb_rport_qos_scn_flowid(void *cbarg,
2366 struct bfa_rport_qos_attr_s new_qos_attr) 2403 struct bfa_rport_qos_attr_s new_qos_attr)
2367{ 2404{
2368 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2405 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2406 struct bfa_rport_aen_data_s aen_data;
2369 2407
2370 bfa_trc(rport->fcs, rport->pwwn); 2408 bfa_trc(rport->fcs, rport->pwwn);
2409 aen_data.priv.qos = new_qos_attr;
2410 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
2371} 2411}
2372 2412
2373/* 2413/*
@@ -2390,8 +2430,11 @@ bfa_cb_rport_qos_scn_prio(void *cbarg,
2390 struct bfa_rport_qos_attr_s new_qos_attr) 2430 struct bfa_rport_qos_attr_s new_qos_attr)
2391{ 2431{
2392 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2432 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2433 struct bfa_rport_aen_data_s aen_data;
2393 2434
2394 bfa_trc(rport->fcs, rport->pwwn); 2435 bfa_trc(rport->fcs, rport->pwwn);
2436 aen_data.priv.qos = new_qos_attr;
2437 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data);
2395} 2438}
2396 2439
2397/* 2440/*
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
index e7ffd8205dc7..ea24d4c6e67a 100644
--- a/drivers/scsi/bfa/bfa_hw_cb.c
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -42,11 +42,36 @@ bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
42 bfa->iocfc.bfa_regs.intr_status); 42 bfa->iocfc.bfa_regs.intr_status);
43} 43}
44 44
45/*
46 * Actions to respond RME Interrupt for Crossbow ASIC:
47 * - Write 1 to Interrupt Status register
48 * INTX - done in bfa_intx()
49 * MSIX - done in bfa_hwcb_rspq_ack_msix()
50 * - Update CI (only if new CI)
51 */
45static void 52static void
46bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq) 53bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq, u32 ci)
47{ 54{
48 writel(__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq), 55 writel(__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq),
49 bfa->iocfc.bfa_regs.intr_status); 56 bfa->iocfc.bfa_regs.intr_status);
57
58 if (bfa_rspq_ci(bfa, rspq) == ci)
59 return;
60
61 bfa_rspq_ci(bfa, rspq) = ci;
62 writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
63 mmiowb();
64}
65
66void
67bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
68{
69 if (bfa_rspq_ci(bfa, rspq) == ci)
70 return;
71
72 bfa_rspq_ci(bfa, rspq) = ci;
73 writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
74 mmiowb();
50} 75}
51 76
52void 77void
@@ -149,8 +174,13 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
149void 174void
150bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) 175bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
151{ 176{
152 bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix; 177 if (msix) {
153 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix; 178 bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
179 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
180 } else {
181 bfa->iocfc.hwif.hw_reqq_ack = NULL;
182 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
183 }
154} 184}
155 185
156void 186void
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c
index 989bbce9b296..637527f48b40 100644
--- a/drivers/scsi/bfa/bfa_hw_ct.c
+++ b/drivers/scsi/bfa/bfa_hw_ct.c
@@ -64,13 +64,36 @@ bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
64 writel(r32, bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]); 64 writel(r32, bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
65} 65}
66 66
67/*
68 * Actions to respond RME Interrupt for Catapult ASIC:
69 * - Write 1 to Interrupt Status register (INTx only - done in bfa_intx())
70 * - Acknowledge by writing to RME Queue Control register
71 * - Update CI
72 */
67void 73void
68bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) 74bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
69{ 75{
70 u32 r32; 76 u32 r32;
71 77
72 r32 = readl(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]); 78 r32 = readl(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
73 writel(r32, bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]); 79 writel(r32, bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
80
81 bfa_rspq_ci(bfa, rspq) = ci;
82 writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
83 mmiowb();
84}
85
86/*
87 * Actions to respond RME Interrupt for Catapult2 ASIC:
88 * - Write 1 to Interrupt Status register (INTx only - done in bfa_intx())
89 * - Update CI
90 */
91void
92bfa_hwct2_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
93{
94 bfa_rspq_ci(bfa, rspq) = ci;
95 writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
96 mmiowb();
74} 97}
75 98
76void 99void
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index d6c2bf3865d2..1ac5aecf25a6 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include "bfad_drv.h" 18#include "bfad_drv.h"
19#include "bfad_im.h"
19#include "bfa_ioc.h" 20#include "bfa_ioc.h"
20#include "bfi_reg.h" 21#include "bfi_reg.h"
21#include "bfa_defs.h" 22#include "bfa_defs.h"
@@ -458,6 +459,7 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
458 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); 459 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
459 bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED); 460 bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
460 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n"); 461 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
462 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE);
461} 463}
462 464
463static void 465static void
@@ -502,6 +504,7 @@ bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
502 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 504 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
503 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE); 505 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
504 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n"); 506 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n");
507 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_DISABLE);
505} 508}
506 509
507/* 510/*
@@ -1966,6 +1969,7 @@ bfa_ioc_fail_notify(struct bfa_ioc_s *ioc)
1966 1969
1967 BFA_LOG(KERN_CRIT, bfad, bfa_log_level, 1970 BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
1968 "Heart Beat of IOC has failed\n"); 1971 "Heart Beat of IOC has failed\n");
1972 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL);
1969 1973
1970} 1974}
1971 1975
@@ -1980,6 +1984,7 @@ bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
1980 BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 1984 BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
1981 "Running firmware version is incompatible " 1985 "Running firmware version is incompatible "
1982 "with the driver version\n"); 1986 "with the driver version\n");
1987 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH);
1983} 1988}
1984 1989
1985bfa_status_t 1990bfa_status_t
@@ -2679,6 +2684,43 @@ bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc)
2679} 2684}
2680 2685
2681/* 2686/*
2687 * Send AEN notification
2688 */
2689void
2690bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2691{
2692 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
2693 struct bfa_aen_entry_s *aen_entry;
2694 enum bfa_ioc_type_e ioc_type;
2695
2696 bfad_get_aen_entry(bfad, aen_entry);
2697 if (!aen_entry)
2698 return;
2699
2700 ioc_type = bfa_ioc_get_type(ioc);
2701 switch (ioc_type) {
2702 case BFA_IOC_TYPE_FC:
2703 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn;
2704 break;
2705 case BFA_IOC_TYPE_FCoE:
2706 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn;
2707 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2708 break;
2709 case BFA_IOC_TYPE_LL:
2710 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2711 break;
2712 default:
2713 WARN_ON(ioc_type != BFA_IOC_TYPE_FC);
2714 break;
2715 }
2716
2717 /* Send the AEN notification */
2718 aen_entry->aen_data.ioc.ioc_type = ioc_type;
2719 bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq,
2720 BFA_AEN_CAT_IOC, event);
2721}
2722
2723/*
2682 * Retrieve saved firmware trace from a prior IOC failure. 2724 * Retrieve saved firmware trace from a prior IOC failure.
2683 */ 2725 */
2684bfa_status_t 2726bfa_status_t
@@ -2879,6 +2921,10 @@ bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc)
2879{ 2921{
2880 if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL) 2922 if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
2881 return; 2923 return;
2924 if (ioc->attr->nwwn == 0)
2925 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_NWWN);
2926 if (ioc->attr->pwwn == 0)
2927 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_PWWN);
2882} 2928}
2883 2929
2884/* 2930/*
@@ -3443,6 +3489,54 @@ bfa_sfp_notify(void *sfp_arg, enum bfa_ioc_event_e event)
3443} 3489}
3444 3490
3445/* 3491/*
3492 * SFP's State Change Notification post to AEN
3493 */
3494static void
3495bfa_sfp_scn_aen_post(struct bfa_sfp_s *sfp, struct bfi_sfp_scn_s *rsp)
3496{
3497 struct bfad_s *bfad = (struct bfad_s *)sfp->ioc->bfa->bfad;
3498 struct bfa_aen_entry_s *aen_entry;
3499 enum bfa_port_aen_event aen_evt = 0;
3500
3501 bfa_trc(sfp, (((u64)rsp->pomlvl) << 16) | (((u64)rsp->sfpid) << 8) |
3502 ((u64)rsp->event));
3503
3504 bfad_get_aen_entry(bfad, aen_entry);
3505 if (!aen_entry)
3506 return;
3507
3508 aen_entry->aen_data.port.ioc_type = bfa_ioc_get_type(sfp->ioc);
3509 aen_entry->aen_data.port.pwwn = sfp->ioc->attr->pwwn;
3510 aen_entry->aen_data.port.mac = bfa_ioc_get_mac(sfp->ioc);
3511
3512 switch (rsp->event) {
3513 case BFA_SFP_SCN_INSERTED:
3514 aen_evt = BFA_PORT_AEN_SFP_INSERT;
3515 break;
3516 case BFA_SFP_SCN_REMOVED:
3517 aen_evt = BFA_PORT_AEN_SFP_REMOVE;
3518 break;
3519 case BFA_SFP_SCN_FAILED:
3520 aen_evt = BFA_PORT_AEN_SFP_ACCESS_ERROR;
3521 break;
3522 case BFA_SFP_SCN_UNSUPPORT:
3523 aen_evt = BFA_PORT_AEN_SFP_UNSUPPORT;
3524 break;
3525 case BFA_SFP_SCN_POM:
3526 aen_evt = BFA_PORT_AEN_SFP_POM;
3527 aen_entry->aen_data.port.level = rsp->pomlvl;
3528 break;
3529 default:
3530 bfa_trc(sfp, rsp->event);
3531 WARN_ON(1);
3532 }
3533
3534 /* Send the AEN notification */
3535 bfad_im_post_vendor_event(aen_entry, bfad, ++sfp->ioc->ioc_aen_seq,
3536 BFA_AEN_CAT_PORT, aen_evt);
3537}
3538
3539/*
3446 * SFP get data send 3540 * SFP get data send
3447 */ 3541 */
3448static void 3542static void
@@ -3482,6 +3576,50 @@ bfa_sfp_getdata(struct bfa_sfp_s *sfp, enum bfi_sfp_mem_e memtype)
3482} 3576}
3483 3577
3484/* 3578/*
3579 * SFP scn handler
3580 */
3581static void
3582bfa_sfp_scn(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg)
3583{
3584 struct bfi_sfp_scn_s *rsp = (struct bfi_sfp_scn_s *) msg;
3585
3586 switch (rsp->event) {
3587 case BFA_SFP_SCN_INSERTED:
3588 sfp->state = BFA_SFP_STATE_INSERTED;
3589 sfp->data_valid = 0;
3590 bfa_sfp_scn_aen_post(sfp, rsp);
3591 break;
3592 case BFA_SFP_SCN_REMOVED:
3593 sfp->state = BFA_SFP_STATE_REMOVED;
3594 sfp->data_valid = 0;
3595 bfa_sfp_scn_aen_post(sfp, rsp);
3596 break;
3597 case BFA_SFP_SCN_FAILED:
3598 sfp->state = BFA_SFP_STATE_FAILED;
3599 sfp->data_valid = 0;
3600 bfa_sfp_scn_aen_post(sfp, rsp);
3601 break;
3602 case BFA_SFP_SCN_UNSUPPORT:
3603 sfp->state = BFA_SFP_STATE_UNSUPPORT;
3604 bfa_sfp_scn_aen_post(sfp, rsp);
3605 if (!sfp->lock)
3606 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3607 break;
3608 case BFA_SFP_SCN_POM:
3609 bfa_sfp_scn_aen_post(sfp, rsp);
3610 break;
3611 case BFA_SFP_SCN_VALID:
3612 sfp->state = BFA_SFP_STATE_VALID;
3613 if (!sfp->lock)
3614 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3615 break;
3616 default:
3617 bfa_trc(sfp, rsp->event);
3618 WARN_ON(1);
3619 }
3620}
3621
3622/*
3485 * SFP show complete 3623 * SFP show complete
3486 */ 3624 */
3487static void 3625static void
@@ -3645,7 +3783,7 @@ bfa_sfp_intr(void *sfparg, struct bfi_mbmsg_s *msg)
3645 break; 3783 break;
3646 3784
3647 case BFI_SFP_I2H_SCN: 3785 case BFI_SFP_I2H_SCN:
3648 bfa_trc(sfp, msg->mh.msg_id); 3786 bfa_sfp_scn(sfp, msg);
3649 break; 3787 break;
3650 3788
3651 default: 3789 default:
@@ -3838,6 +3976,26 @@ bfa_sfp_speed(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed,
3838 BFA_ROUNDUP(0x010000 + sizeof(struct bfa_mfg_block_s), BFA_FLASH_SEG_SZ) 3976 BFA_ROUNDUP(0x010000 + sizeof(struct bfa_mfg_block_s), BFA_FLASH_SEG_SZ)
3839 3977
3840static void 3978static void
3979bfa_flash_aen_audit_post(struct bfa_ioc_s *ioc, enum bfa_audit_aen_event event,
3980 int inst, int type)
3981{
3982 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
3983 struct bfa_aen_entry_s *aen_entry;
3984
3985 bfad_get_aen_entry(bfad, aen_entry);
3986 if (!aen_entry)
3987 return;
3988
3989 aen_entry->aen_data.audit.pwwn = ioc->attr->pwwn;
3990 aen_entry->aen_data.audit.partition_inst = inst;
3991 aen_entry->aen_data.audit.partition_type = type;
3992
3993 /* Send the AEN notification */
3994 bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq,
3995 BFA_AEN_CAT_AUDIT, event);
3996}
3997
3998static void
3841bfa_flash_cb(struct bfa_flash_s *flash) 3999bfa_flash_cb(struct bfa_flash_s *flash)
3842{ 4000{
3843 flash->op_busy = 0; 4001 flash->op_busy = 0;
@@ -3978,6 +4136,7 @@ bfa_flash_intr(void *flasharg, struct bfi_mbmsg_s *msg)
3978 struct bfi_flash_erase_rsp_s *erase; 4136 struct bfi_flash_erase_rsp_s *erase;
3979 struct bfi_flash_write_rsp_s *write; 4137 struct bfi_flash_write_rsp_s *write;
3980 struct bfi_flash_read_rsp_s *read; 4138 struct bfi_flash_read_rsp_s *read;
4139 struct bfi_flash_event_s *event;
3981 struct bfi_mbmsg_s *msg; 4140 struct bfi_mbmsg_s *msg;
3982 } m; 4141 } m;
3983 4142
@@ -4061,8 +4220,19 @@ bfa_flash_intr(void *flasharg, struct bfi_mbmsg_s *msg)
4061 } 4220 }
4062 break; 4221 break;
4063 case BFI_FLASH_I2H_BOOT_VER_RSP: 4222 case BFI_FLASH_I2H_BOOT_VER_RSP:
4223 break;
4064 case BFI_FLASH_I2H_EVENT: 4224 case BFI_FLASH_I2H_EVENT:
4065 bfa_trc(flash, msg->mh.msg_id); 4225 status = be32_to_cpu(m.event->status);
4226 bfa_trc(flash, status);
4227 if (status == BFA_STATUS_BAD_FWCFG)
4228 bfa_ioc_aen_post(flash->ioc, BFA_IOC_AEN_FWCFG_ERROR);
4229 else if (status == BFA_STATUS_INVALID_VENDOR) {
4230 u32 param;
4231 param = be32_to_cpu(m.event->param);
4232 bfa_trc(flash, param);
4233 bfa_ioc_aen_post(flash->ioc,
4234 BFA_IOC_AEN_INVALID_VENDOR);
4235 }
4066 break; 4236 break;
4067 4237
4068 default: 4238 default:
@@ -4204,6 +4374,8 @@ bfa_flash_erase_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
4204 flash->instance = instance; 4374 flash->instance = instance;
4205 4375
4206 bfa_flash_erase_send(flash); 4376 bfa_flash_erase_send(flash);
4377 bfa_flash_aen_audit_post(flash->ioc, BFA_AUDIT_AEN_FLASH_ERASE,
4378 instance, type);
4207 return BFA_STATUS_OK; 4379 return BFA_STATUS_OK;
4208} 4380}
4209 4381
@@ -5416,3 +5588,396 @@ bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg)
5416 WARN_ON(1); 5588 WARN_ON(1);
5417 } 5589 }
5418} 5590}
5591
5592/*
5593 * DCONF module specific
5594 */
5595
5596BFA_MODULE(dconf);
5597
5598/*
5599 * DCONF state machine events
5600 */
5601enum bfa_dconf_event {
5602 BFA_DCONF_SM_INIT = 1, /* dconf Init */
5603 BFA_DCONF_SM_FLASH_COMP = 2, /* read/write to flash */
5604 BFA_DCONF_SM_WR = 3, /* binding change, map */
5605 BFA_DCONF_SM_TIMEOUT = 4, /* Start timer */
5606 BFA_DCONF_SM_EXIT = 5, /* exit dconf module */
5607 BFA_DCONF_SM_IOCDISABLE = 6, /* IOC disable event */
5608};
5609
5610/* forward declaration of DCONF state machine */
5611static void bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf,
5612 enum bfa_dconf_event event);
5613static void bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
5614 enum bfa_dconf_event event);
5615static void bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf,
5616 enum bfa_dconf_event event);
5617static void bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf,
5618 enum bfa_dconf_event event);
5619static void bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf,
5620 enum bfa_dconf_event event);
5621static void bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf,
5622 enum bfa_dconf_event event);
5623static void bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf,
5624 enum bfa_dconf_event event);
5625
5626static void bfa_dconf_cbfn(void *dconf, bfa_status_t status);
5627static void bfa_dconf_timer(void *cbarg);
5628static bfa_status_t bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf);
5629static void bfa_dconf_init_cb(void *arg, bfa_status_t status);
5630
5631/*
5632 * Begining state of dconf module. Waiting for an event to start.
5633 */
5634static void
5635bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5636{
5637 bfa_status_t bfa_status;
5638 bfa_trc(dconf->bfa, event);
5639
5640 switch (event) {
5641 case BFA_DCONF_SM_INIT:
5642 if (dconf->min_cfg) {
5643 bfa_trc(dconf->bfa, dconf->min_cfg);
5644 return;
5645 }
5646 bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read);
5647 dconf->flashdone = BFA_FALSE;
5648 bfa_trc(dconf->bfa, dconf->flashdone);
5649 bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa),
5650 BFA_FLASH_PART_DRV, dconf->instance,
5651 dconf->dconf,
5652 sizeof(struct bfa_dconf_s), 0,
5653 bfa_dconf_init_cb, dconf->bfa);
5654 if (bfa_status != BFA_STATUS_OK) {
5655 bfa_dconf_init_cb(dconf->bfa, BFA_STATUS_FAILED);
5656 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5657 return;
5658 }
5659 break;
5660 case BFA_DCONF_SM_EXIT:
5661 dconf->flashdone = BFA_TRUE;
5662 case BFA_DCONF_SM_IOCDISABLE:
5663 case BFA_DCONF_SM_WR:
5664 case BFA_DCONF_SM_FLASH_COMP:
5665 break;
5666 default:
5667 bfa_sm_fault(dconf->bfa, event);
5668 }
5669}
5670
5671/*
5672 * Read flash for dconf entries and make a call back to the driver once done.
5673 */
5674static void
5675bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
5676 enum bfa_dconf_event event)
5677{
5678 bfa_trc(dconf->bfa, event);
5679
5680 switch (event) {
5681 case BFA_DCONF_SM_FLASH_COMP:
5682 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5683 break;
5684 case BFA_DCONF_SM_TIMEOUT:
5685 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5686 break;
5687 case BFA_DCONF_SM_EXIT:
5688 dconf->flashdone = BFA_TRUE;
5689 bfa_trc(dconf->bfa, dconf->flashdone);
5690 case BFA_DCONF_SM_IOCDISABLE:
5691 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5692 break;
5693 default:
5694 bfa_sm_fault(dconf->bfa, event);
5695 }
5696}
5697
5698/*
5699 * DCONF Module is in ready state. Has completed the initialization.
5700 */
5701static void
5702bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5703{
5704 bfa_trc(dconf->bfa, event);
5705
5706 switch (event) {
5707 case BFA_DCONF_SM_WR:
5708 bfa_timer_start(dconf->bfa, &dconf->timer,
5709 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5710 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
5711 break;
5712 case BFA_DCONF_SM_EXIT:
5713 dconf->flashdone = BFA_TRUE;
5714 bfa_trc(dconf->bfa, dconf->flashdone);
5715 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5716 break;
5717 case BFA_DCONF_SM_INIT:
5718 case BFA_DCONF_SM_IOCDISABLE:
5719 break;
5720 default:
5721 bfa_sm_fault(dconf->bfa, event);
5722 }
5723}
5724
5725/*
5726 * entries are dirty, write back to the flash.
5727 */
5728
5729static void
5730bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5731{
5732 bfa_trc(dconf->bfa, event);
5733
5734 switch (event) {
5735 case BFA_DCONF_SM_TIMEOUT:
5736 bfa_sm_set_state(dconf, bfa_dconf_sm_sync);
5737 bfa_dconf_flash_write(dconf);
5738 break;
5739 case BFA_DCONF_SM_WR:
5740 bfa_timer_stop(&dconf->timer);
5741 bfa_timer_start(dconf->bfa, &dconf->timer,
5742 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5743 break;
5744 case BFA_DCONF_SM_EXIT:
5745 bfa_timer_stop(&dconf->timer);
5746 bfa_timer_start(dconf->bfa, &dconf->timer,
5747 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5748 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync);
5749 bfa_dconf_flash_write(dconf);
5750 break;
5751 case BFA_DCONF_SM_FLASH_COMP:
5752 break;
5753 case BFA_DCONF_SM_IOCDISABLE:
5754 bfa_timer_stop(&dconf->timer);
5755 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty);
5756 break;
5757 default:
5758 bfa_sm_fault(dconf->bfa, event);
5759 }
5760}
5761
5762/*
5763 * Sync the dconf entries to the flash.
5764 */
5765static void
5766bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf,
5767 enum bfa_dconf_event event)
5768{
5769 bfa_trc(dconf->bfa, event);
5770
5771 switch (event) {
5772 case BFA_DCONF_SM_IOCDISABLE:
5773 case BFA_DCONF_SM_FLASH_COMP:
5774 bfa_timer_stop(&dconf->timer);
5775 case BFA_DCONF_SM_TIMEOUT:
5776 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5777 dconf->flashdone = BFA_TRUE;
5778 bfa_trc(dconf->bfa, dconf->flashdone);
5779 bfa_ioc_disable(&dconf->bfa->ioc);
5780 break;
5781 default:
5782 bfa_sm_fault(dconf->bfa, event);
5783 }
5784}
5785
5786static void
5787bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5788{
5789 bfa_trc(dconf->bfa, event);
5790
5791 switch (event) {
5792 case BFA_DCONF_SM_FLASH_COMP:
5793 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5794 break;
5795 case BFA_DCONF_SM_WR:
5796 bfa_timer_start(dconf->bfa, &dconf->timer,
5797 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5798 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
5799 break;
5800 case BFA_DCONF_SM_EXIT:
5801 bfa_timer_start(dconf->bfa, &dconf->timer,
5802 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5803 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync);
5804 break;
5805 case BFA_DCONF_SM_IOCDISABLE:
5806 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty);
5807 break;
5808 default:
5809 bfa_sm_fault(dconf->bfa, event);
5810 }
5811}
5812
5813static void
5814bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf,
5815 enum bfa_dconf_event event)
5816{
5817 bfa_trc(dconf->bfa, event);
5818
5819 switch (event) {
5820 case BFA_DCONF_SM_INIT:
5821 bfa_timer_start(dconf->bfa, &dconf->timer,
5822 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5823 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
5824 break;
5825 case BFA_DCONF_SM_EXIT:
5826 dconf->flashdone = BFA_TRUE;
5827 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5828 break;
5829 case BFA_DCONF_SM_IOCDISABLE:
5830 break;
5831 default:
5832 bfa_sm_fault(dconf->bfa, event);
5833 }
5834}
5835
5836/*
5837 * Compute and return memory needed by DRV_CFG module.
5838 */
5839static void
5840bfa_dconf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
5841 struct bfa_s *bfa)
5842{
5843 struct bfa_mem_kva_s *dconf_kva = BFA_MEM_DCONF_KVA(bfa);
5844
5845 if (cfg->drvcfg.min_cfg)
5846 bfa_mem_kva_setup(meminfo, dconf_kva,
5847 sizeof(struct bfa_dconf_hdr_s));
5848 else
5849 bfa_mem_kva_setup(meminfo, dconf_kva,
5850 sizeof(struct bfa_dconf_s));
5851}
5852
5853static void
5854bfa_dconf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
5855 struct bfa_pcidev_s *pcidev)
5856{
5857 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
5858
5859 dconf->bfad = bfad;
5860 dconf->bfa = bfa;
5861 dconf->instance = bfa->ioc.port_id;
5862 bfa_trc(bfa, dconf->instance);
5863
5864 dconf->dconf = (struct bfa_dconf_s *) bfa_mem_kva_curp(dconf);
5865 if (cfg->drvcfg.min_cfg) {
5866 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_hdr_s);
5867 dconf->min_cfg = BFA_TRUE;
5868 /*
5869 * Set the flashdone flag to TRUE explicitly as no flash
5870 * write will happen in min_cfg mode.
5871 */
5872 dconf->flashdone = BFA_TRUE;
5873 } else {
5874 dconf->min_cfg = BFA_FALSE;
5875 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_s);
5876 }
5877
5878 bfa_dconf_read_data_valid(bfa) = BFA_FALSE;
5879 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5880}
5881
5882static void
5883bfa_dconf_init_cb(void *arg, bfa_status_t status)
5884{
5885 struct bfa_s *bfa = arg;
5886 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
5887
5888 dconf->flashdone = BFA_TRUE;
5889 bfa_trc(bfa, dconf->flashdone);
5890 bfa_iocfc_cb_dconf_modinit(bfa, status);
5891 if (status == BFA_STATUS_OK) {
5892 bfa_dconf_read_data_valid(bfa) = BFA_TRUE;
5893 if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE)
5894 dconf->dconf->hdr.signature = BFI_DCONF_SIGNATURE;
5895 if (dconf->dconf->hdr.version != BFI_DCONF_VERSION)
5896 dconf->dconf->hdr.version = BFI_DCONF_VERSION;
5897 }
5898 bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
5899}
5900
5901void
5902bfa_dconf_modinit(struct bfa_s *bfa)
5903{
5904 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
5905 bfa_sm_send_event(dconf, BFA_DCONF_SM_INIT);
5906}
5907static void
5908bfa_dconf_start(struct bfa_s *bfa)
5909{
5910}
5911
5912static void
5913bfa_dconf_stop(struct bfa_s *bfa)
5914{
5915}
5916
5917static void bfa_dconf_timer(void *cbarg)
5918{
5919 struct bfa_dconf_mod_s *dconf = cbarg;
5920 bfa_sm_send_event(dconf, BFA_DCONF_SM_TIMEOUT);
5921}
5922static void
5923bfa_dconf_iocdisable(struct bfa_s *bfa)
5924{
5925 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
5926 bfa_sm_send_event(dconf, BFA_DCONF_SM_IOCDISABLE);
5927}
5928
5929static void
5930bfa_dconf_detach(struct bfa_s *bfa)
5931{
5932}
5933
5934static bfa_status_t
5935bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf)
5936{
5937 bfa_status_t bfa_status;
5938 bfa_trc(dconf->bfa, 0);
5939
5940 bfa_status = bfa_flash_update_part(BFA_FLASH(dconf->bfa),
5941 BFA_FLASH_PART_DRV, dconf->instance,
5942 dconf->dconf, sizeof(struct bfa_dconf_s), 0,
5943 bfa_dconf_cbfn, dconf);
5944 if (bfa_status != BFA_STATUS_OK)
5945 WARN_ON(bfa_status);
5946 bfa_trc(dconf->bfa, bfa_status);
5947
5948 return bfa_status;
5949}
5950
5951bfa_status_t
5952bfa_dconf_update(struct bfa_s *bfa)
5953{
5954 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
5955 bfa_trc(dconf->bfa, 0);
5956 if (bfa_sm_cmp_state(dconf, bfa_dconf_sm_iocdown_dirty))
5957 return BFA_STATUS_FAILED;
5958
5959 if (dconf->min_cfg) {
5960 bfa_trc(dconf->bfa, dconf->min_cfg);
5961 return BFA_STATUS_FAILED;
5962 }
5963
5964 bfa_sm_send_event(dconf, BFA_DCONF_SM_WR);
5965 return BFA_STATUS_OK;
5966}
5967
5968static void
5969bfa_dconf_cbfn(void *arg, bfa_status_t status)
5970{
5971 struct bfa_dconf_mod_s *dconf = arg;
5972 WARN_ON(status);
5973 bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
5974}
5975
5976void
5977bfa_dconf_modexit(struct bfa_s *bfa)
5978{
5979 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
5980 BFA_DCONF_MOD(bfa)->flashdone = BFA_FALSE;
5981 bfa_trc(bfa, BFA_DCONF_MOD(bfa)->flashdone);
5982 bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT);
5983}
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index c5ecd2edc95d..546d46b37101 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -327,6 +327,7 @@ struct bfa_ioc_s {
327 enum bfa_mode_s port_mode; 327 enum bfa_mode_s port_mode;
328 u8 ad_cap_bm; /* adapter cap bit mask */ 328 u8 ad_cap_bm; /* adapter cap bit mask */
329 u8 port_mode_cfg; /* config port mode */ 329 u8 port_mode_cfg; /* config port mode */
330 int ioc_aen_seq;
330}; 331};
331 332
332struct bfa_ioc_hwif_s { 333struct bfa_ioc_hwif_s {
@@ -366,6 +367,8 @@ struct bfa_cb_qe_s {
366 struct list_head qe; 367 struct list_head qe;
367 bfa_cb_cbfn_t cbfn; 368 bfa_cb_cbfn_t cbfn;
368 bfa_boolean_t once; 369 bfa_boolean_t once;
370 bfa_boolean_t pre_rmv; /* set for stack based qe(s) */
371 bfa_status_t fw_status; /* to access fw status in comp proc */
369 void *cbarg; 372 void *cbarg;
370}; 373};
371 374
@@ -658,7 +661,6 @@ struct bfa_phy_s {
658 struct bfa_ioc_notify_s ioc_notify; /* ioc event notify */ 661 struct bfa_ioc_notify_s ioc_notify; /* ioc event notify */
659 struct bfa_mem_dma_s phy_dma; 662 struct bfa_mem_dma_s phy_dma;
660}; 663};
661
662#define BFA_PHY(__bfa) (&(__bfa)->modules.phy) 664#define BFA_PHY(__bfa) (&(__bfa)->modules.phy)
663#define BFA_MEM_PHY_DMA(__bfa) (&(BFA_PHY(__bfa)->phy_dma)) 665#define BFA_MEM_PHY_DMA(__bfa) (&(BFA_PHY(__bfa)->phy_dma))
664 666
@@ -684,6 +686,49 @@ void bfa_phy_memclaim(struct bfa_phy_s *phy,
684void bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg); 686void bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg);
685 687
686/* 688/*
689 * Driver Config( dconf) specific
690 */
691#define BFI_DCONF_SIGNATURE 0xabcdabcd
692#define BFI_DCONF_VERSION 1
693
694#pragma pack(1)
695struct bfa_dconf_hdr_s {
696 u32 signature;
697 u32 version;
698};
699
700struct bfa_dconf_s {
701 struct bfa_dconf_hdr_s hdr;
702 struct bfa_lunmask_cfg_s lun_mask;
703};
704#pragma pack()
705
706struct bfa_dconf_mod_s {
707 bfa_sm_t sm;
708 u8 instance;
709 bfa_boolean_t flashdone;
710 bfa_boolean_t read_data_valid;
711 bfa_boolean_t min_cfg;
712 struct bfa_timer_s timer;
713 struct bfa_s *bfa;
714 void *bfad;
715 void *trcmod;
716 struct bfa_dconf_s *dconf;
717 struct bfa_mem_kva_s kva_seg;
718};
719
720#define BFA_DCONF_MOD(__bfa) \
721 (&(__bfa)->modules.dconf_mod)
722#define BFA_MEM_DCONF_KVA(__bfa) (&(BFA_DCONF_MOD(__bfa)->kva_seg))
723#define bfa_dconf_read_data_valid(__bfa) \
724 (BFA_DCONF_MOD(__bfa)->read_data_valid)
725#define BFA_DCONF_UPDATE_TOV 5000 /* memtest timeout in msec */
726
727void bfa_dconf_modinit(struct bfa_s *bfa);
728void bfa_dconf_modexit(struct bfa_s *bfa);
729bfa_status_t bfa_dconf_update(struct bfa_s *bfa);
730
731/*
687 * IOC specfic macros 732 * IOC specfic macros
688 */ 733 */
689#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) 734#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
@@ -803,6 +848,7 @@ void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
803 struct bfi_ioc_image_hdr_s *fwhdr); 848 struct bfi_ioc_image_hdr_s *fwhdr);
804bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, 849bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
805 struct bfi_ioc_image_hdr_s *fwhdr); 850 struct bfi_ioc_image_hdr_s *fwhdr);
851void bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event);
806bfa_status_t bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats); 852bfa_status_t bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats);
807bfa_status_t bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc); 853bfa_status_t bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc);
808 854
diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h
index 1c6efd40a673..2d36e4823835 100644
--- a/drivers/scsi/bfa/bfa_modules.h
+++ b/drivers/scsi/bfa/bfa_modules.h
@@ -44,6 +44,7 @@ struct bfa_modules_s {
44 struct bfa_flash_s flash; /* flash module */ 44 struct bfa_flash_s flash; /* flash module */
45 struct bfa_diag_s diag_mod; /* diagnostics module */ 45 struct bfa_diag_s diag_mod; /* diagnostics module */
46 struct bfa_phy_s phy; /* phy module */ 46 struct bfa_phy_s phy; /* phy module */
47 struct bfa_dconf_mod_s dconf_mod; /* DCONF common module */
47}; 48};
48 49
49/* 50/*
@@ -119,6 +120,7 @@ struct bfa_s {
119 struct list_head reqq_waitq[BFI_IOC_MAX_CQS]; 120 struct list_head reqq_waitq[BFI_IOC_MAX_CQS];
120 bfa_boolean_t fcs; /* FCS is attached to BFA */ 121 bfa_boolean_t fcs; /* FCS is attached to BFA */
121 struct bfa_msix_s msix; 122 struct bfa_msix_s msix;
123 int bfa_aen_seq;
122}; 124};
123 125
124extern bfa_boolean_t bfa_auto_recover; 126extern bfa_boolean_t bfa_auto_recover;
@@ -130,5 +132,6 @@ extern struct bfa_module_s hal_mod_lps;
130extern struct bfa_module_s hal_mod_uf; 132extern struct bfa_module_s hal_mod_uf;
131extern struct bfa_module_s hal_mod_rport; 133extern struct bfa_module_s hal_mod_rport;
132extern struct bfa_module_s hal_mod_fcp; 134extern struct bfa_module_s hal_mod_fcp;
135extern struct bfa_module_s hal_mod_dconf;
133 136
134#endif /* __BFA_MODULES_H__ */ 137#endif /* __BFA_MODULES_H__ */
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index 21caaefce99f..aa8a0eaf91f9 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include "bfad_drv.h" 18#include "bfad_drv.h"
19#include "bfad_im.h"
19#include "bfa_plog.h" 20#include "bfa_plog.h"
20#include "bfa_cs.h" 21#include "bfa_cs.h"
21#include "bfa_modules.h" 22#include "bfa_modules.h"
@@ -2007,6 +2008,24 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2007 } 2008 }
2008} 2009}
2009 2010
2011static void
2012bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
2013{
2014 struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2015 struct bfa_aen_entry_s *aen_entry;
2016
2017 bfad_get_aen_entry(bfad, aen_entry);
2018 if (!aen_entry)
2019 return;
2020
2021 aen_entry->aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
2022 aen_entry->aen_data.port.pwwn = fcport->pwwn;
2023
2024 /* Send the AEN notification */
2025 bfad_im_post_vendor_event(aen_entry, bfad, ++fcport->bfa->bfa_aen_seq,
2026 BFA_AEN_CAT_PORT, event);
2027}
2028
2010/* 2029/*
2011 * FC PORT state machine functions 2030 * FC PORT state machine functions
2012 */ 2031 */
@@ -2095,6 +2114,7 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
2095 wwn2str(pwwn_buf, fcport->pwwn); 2114 wwn2str(pwwn_buf, fcport->pwwn);
2096 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2115 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2097 "Base port disabled: WWN = %s\n", pwwn_buf); 2116 "Base port disabled: WWN = %s\n", pwwn_buf);
2117 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
2098 break; 2118 break;
2099 2119
2100 case BFA_FCPORT_SM_LINKUP: 2120 case BFA_FCPORT_SM_LINKUP:
@@ -2155,6 +2175,7 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
2155 wwn2str(pwwn_buf, fcport->pwwn); 2175 wwn2str(pwwn_buf, fcport->pwwn);
2156 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2176 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2157 "Base port disabled: WWN = %s\n", pwwn_buf); 2177 "Base port disabled: WWN = %s\n", pwwn_buf);
2178 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
2158 break; 2179 break;
2159 2180
2160 case BFA_FCPORT_SM_STOP: 2181 case BFA_FCPORT_SM_STOP:
@@ -2208,6 +2229,12 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
2208 wwn2str(pwwn_buf, fcport->pwwn); 2229 wwn2str(pwwn_buf, fcport->pwwn);
2209 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2230 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2210 "Base port online: WWN = %s\n", pwwn_buf); 2231 "Base port online: WWN = %s\n", pwwn_buf);
2232 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
2233
2234 /* If QoS is enabled and it is not online, send AEN */
2235 if (fcport->cfg.qos_enabled &&
2236 fcport->qos_attr.state != BFA_QOS_ONLINE)
2237 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
2211 break; 2238 break;
2212 2239
2213 case BFA_FCPORT_SM_LINKDOWN: 2240 case BFA_FCPORT_SM_LINKDOWN:
@@ -2234,6 +2261,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
2234 wwn2str(pwwn_buf, fcport->pwwn); 2261 wwn2str(pwwn_buf, fcport->pwwn);
2235 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2262 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2236 "Base port disabled: WWN = %s\n", pwwn_buf); 2263 "Base port disabled: WWN = %s\n", pwwn_buf);
2264 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
2237 break; 2265 break;
2238 2266
2239 case BFA_FCPORT_SM_STOP: 2267 case BFA_FCPORT_SM_STOP:
@@ -2279,8 +2307,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
2279 wwn2str(pwwn_buf, fcport->pwwn); 2307 wwn2str(pwwn_buf, fcport->pwwn);
2280 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2308 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2281 "Base port offline: WWN = %s\n", pwwn_buf); 2309 "Base port offline: WWN = %s\n", pwwn_buf);
2310 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
2282 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2311 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2283 "Base port disabled: WWN = %s\n", pwwn_buf); 2312 "Base port disabled: WWN = %s\n", pwwn_buf);
2313 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
2284 break; 2314 break;
2285 2315
2286 case BFA_FCPORT_SM_LINKDOWN: 2316 case BFA_FCPORT_SM_LINKDOWN:
@@ -2290,26 +2320,32 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
2290 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2320 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2291 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); 2321 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
2292 wwn2str(pwwn_buf, fcport->pwwn); 2322 wwn2str(pwwn_buf, fcport->pwwn);
2293 if (BFA_PORT_IS_DISABLED(fcport->bfa)) 2323 if (BFA_PORT_IS_DISABLED(fcport->bfa)) {
2294 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2324 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2295 "Base port offline: WWN = %s\n", pwwn_buf); 2325 "Base port offline: WWN = %s\n", pwwn_buf);
2296 else 2326 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
2327 } else {
2297 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2328 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2298 "Base port (WWN = %s) " 2329 "Base port (WWN = %s) "
2299 "lost fabric connectivity\n", pwwn_buf); 2330 "lost fabric connectivity\n", pwwn_buf);
2331 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
2332 }
2300 break; 2333 break;
2301 2334
2302 case BFA_FCPORT_SM_STOP: 2335 case BFA_FCPORT_SM_STOP:
2303 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2336 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2304 bfa_fcport_reset_linkinfo(fcport); 2337 bfa_fcport_reset_linkinfo(fcport);
2305 wwn2str(pwwn_buf, fcport->pwwn); 2338 wwn2str(pwwn_buf, fcport->pwwn);
2306 if (BFA_PORT_IS_DISABLED(fcport->bfa)) 2339 if (BFA_PORT_IS_DISABLED(fcport->bfa)) {
2307 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2340 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2308 "Base port offline: WWN = %s\n", pwwn_buf); 2341 "Base port offline: WWN = %s\n", pwwn_buf);
2309 else 2342 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
2343 } else {
2310 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2344 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2311 "Base port (WWN = %s) " 2345 "Base port (WWN = %s) "
2312 "lost fabric connectivity\n", pwwn_buf); 2346 "lost fabric connectivity\n", pwwn_buf);
2347 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
2348 }
2313 break; 2349 break;
2314 2350
2315 case BFA_FCPORT_SM_HWFAIL: 2351 case BFA_FCPORT_SM_HWFAIL:
@@ -2317,13 +2353,16 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
2317 bfa_fcport_reset_linkinfo(fcport); 2353 bfa_fcport_reset_linkinfo(fcport);
2318 bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2354 bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
2319 wwn2str(pwwn_buf, fcport->pwwn); 2355 wwn2str(pwwn_buf, fcport->pwwn);
2320 if (BFA_PORT_IS_DISABLED(fcport->bfa)) 2356 if (BFA_PORT_IS_DISABLED(fcport->bfa)) {
2321 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2357 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2322 "Base port offline: WWN = %s\n", pwwn_buf); 2358 "Base port offline: WWN = %s\n", pwwn_buf);
2323 else 2359 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
2360 } else {
2324 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2361 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2325 "Base port (WWN = %s) " 2362 "Base port (WWN = %s) "
2326 "lost fabric connectivity\n", pwwn_buf); 2363 "lost fabric connectivity\n", pwwn_buf);
2364 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
2365 }
2327 break; 2366 break;
2328 2367
2329 default: 2368 default:
@@ -2454,6 +2493,7 @@ bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
2454 wwn2str(pwwn_buf, fcport->pwwn); 2493 wwn2str(pwwn_buf, fcport->pwwn);
2455 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2494 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2456 "Base port enabled: WWN = %s\n", pwwn_buf); 2495 "Base port enabled: WWN = %s\n", pwwn_buf);
2496 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
2457 break; 2497 break;
2458 2498
2459 case BFA_FCPORT_SM_STOP: 2499 case BFA_FCPORT_SM_STOP:
@@ -2508,6 +2548,7 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
2508 wwn2str(pwwn_buf, fcport->pwwn); 2548 wwn2str(pwwn_buf, fcport->pwwn);
2509 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2549 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2510 "Base port enabled: WWN = %s\n", pwwn_buf); 2550 "Base port enabled: WWN = %s\n", pwwn_buf);
2551 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
2511 break; 2552 break;
2512 2553
2513 case BFA_FCPORT_SM_DISABLE: 2554 case BFA_FCPORT_SM_DISABLE:
@@ -2874,6 +2915,9 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
2874 2915
2875 port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS; 2916 port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS;
2876 2917
2918 INIT_LIST_HEAD(&fcport->stats_pending_q);
2919 INIT_LIST_HEAD(&fcport->statsclr_pending_q);
2920
2877 bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport); 2921 bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
2878} 2922}
2879 2923
@@ -3102,30 +3146,38 @@ bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
3102static void 3146static void
3103__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete) 3147__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
3104{ 3148{
3105 struct bfa_fcport_s *fcport = cbarg; 3149 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg;
3150 struct bfa_cb_pending_q_s *cb;
3151 struct list_head *qe, *qen;
3152 union bfa_fcport_stats_u *ret;
3106 3153
3107 if (complete) { 3154 if (complete) {
3108 if (fcport->stats_status == BFA_STATUS_OK) { 3155 struct timeval tv;
3109 struct timeval tv; 3156 if (fcport->stats_status == BFA_STATUS_OK)
3110 3157 do_gettimeofday(&tv);
3111 /* Swap FC QoS or FCoE stats */ 3158
3112 if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { 3159 list_for_each_safe(qe, qen, &fcport->stats_pending_q) {
3113 bfa_fcport_qos_stats_swap( 3160 bfa_q_deq(&fcport->stats_pending_q, &qe);
3114 &fcport->stats_ret->fcqos, 3161 cb = (struct bfa_cb_pending_q_s *)qe;
3115 &fcport->stats->fcqos); 3162 if (fcport->stats_status == BFA_STATUS_OK) {
3116 } else { 3163 ret = (union bfa_fcport_stats_u *)cb->data;
3117 bfa_fcport_fcoe_stats_swap( 3164 /* Swap FC QoS or FCoE stats */
3118 &fcport->stats_ret->fcoe, 3165 if (bfa_ioc_get_fcmode(&fcport->bfa->ioc))
3119 &fcport->stats->fcoe); 3166 bfa_fcport_qos_stats_swap(&ret->fcqos,
3120 3167 &fcport->stats->fcqos);
3121 do_gettimeofday(&tv); 3168 else {
3122 fcport->stats_ret->fcoe.secs_reset = 3169 bfa_fcport_fcoe_stats_swap(&ret->fcoe,
3170 &fcport->stats->fcoe);
3171 ret->fcoe.secs_reset =
3123 tv.tv_sec - fcport->stats_reset_time; 3172 tv.tv_sec - fcport->stats_reset_time;
3173 }
3124 } 3174 }
3175 bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe,
3176 fcport->stats_status);
3125 } 3177 }
3126 fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); 3178 fcport->stats_status = BFA_STATUS_OK;
3127 } else { 3179 } else {
3128 fcport->stats_busy = BFA_FALSE; 3180 INIT_LIST_HEAD(&fcport->stats_pending_q);
3129 fcport->stats_status = BFA_STATUS_OK; 3181 fcport->stats_status = BFA_STATUS_OK;
3130 } 3182 }
3131} 3183}
@@ -3143,8 +3195,7 @@ bfa_fcport_stats_get_timeout(void *cbarg)
3143 } 3195 }
3144 3196
3145 fcport->stats_status = BFA_STATUS_ETIMER; 3197 fcport->stats_status = BFA_STATUS_ETIMER;
3146 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get, 3198 __bfa_cb_fcport_stats_get(fcport, BFA_TRUE);
3147 fcport);
3148} 3199}
3149 3200
3150static void 3201static void
@@ -3174,7 +3225,9 @@ bfa_fcport_send_stats_get(void *cbarg)
3174static void 3225static void
3175__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete) 3226__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
3176{ 3227{
3177 struct bfa_fcport_s *fcport = cbarg; 3228 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
3229 struct bfa_cb_pending_q_s *cb;
3230 struct list_head *qe, *qen;
3178 3231
3179 if (complete) { 3232 if (complete) {
3180 struct timeval tv; 3233 struct timeval tv;
@@ -3184,10 +3237,15 @@ __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
3184 */ 3237 */
3185 do_gettimeofday(&tv); 3238 do_gettimeofday(&tv);
3186 fcport->stats_reset_time = tv.tv_sec; 3239 fcport->stats_reset_time = tv.tv_sec;
3187 3240 list_for_each_safe(qe, qen, &fcport->statsclr_pending_q) {
3188 fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); 3241 bfa_q_deq(&fcport->statsclr_pending_q, &qe);
3242 cb = (struct bfa_cb_pending_q_s *)qe;
3243 bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe,
3244 fcport->stats_status);
3245 }
3246 fcport->stats_status = BFA_STATUS_OK;
3189 } else { 3247 } else {
3190 fcport->stats_busy = BFA_FALSE; 3248 INIT_LIST_HEAD(&fcport->statsclr_pending_q);
3191 fcport->stats_status = BFA_STATUS_OK; 3249 fcport->stats_status = BFA_STATUS_OK;
3192 } 3250 }
3193} 3251}
@@ -3205,8 +3263,7 @@ bfa_fcport_stats_clr_timeout(void *cbarg)
3205 } 3263 }
3206 3264
3207 fcport->stats_status = BFA_STATUS_ETIMER; 3265 fcport->stats_status = BFA_STATUS_ETIMER;
3208 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, 3266 __bfa_cb_fcport_stats_clr(fcport, BFA_TRUE);
3209 __bfa_cb_fcport_stats_clr, fcport);
3210} 3267}
3211 3268
3212static void 3269static void
@@ -3402,6 +3459,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
3402 fcport->use_flash_cfg = BFA_FALSE; 3459 fcport->use_flash_cfg = BFA_FALSE;
3403 } 3460 }
3404 3461
3462 if (fcport->cfg.qos_enabled)
3463 fcport->qos_attr.state = BFA_QOS_OFFLINE;
3464 else
3465 fcport->qos_attr.state = BFA_QOS_DISABLED;
3466
3405 bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); 3467 bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
3406 } 3468 }
3407 break; 3469 break;
@@ -3426,28 +3488,26 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
3426 /* 3488 /*
3427 * check for timer pop before processing the rsp 3489 * check for timer pop before processing the rsp
3428 */ 3490 */
3429 if (fcport->stats_busy == BFA_FALSE || 3491 if (list_empty(&fcport->stats_pending_q) ||
3430 fcport->stats_status == BFA_STATUS_ETIMER) 3492 (fcport->stats_status == BFA_STATUS_ETIMER))
3431 break; 3493 break;
3432 3494
3433 bfa_timer_stop(&fcport->timer); 3495 bfa_timer_stop(&fcport->timer);
3434 fcport->stats_status = i2hmsg.pstatsget_rsp->status; 3496 fcport->stats_status = i2hmsg.pstatsget_rsp->status;
3435 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, 3497 __bfa_cb_fcport_stats_get(fcport, BFA_TRUE);
3436 __bfa_cb_fcport_stats_get, fcport);
3437 break; 3498 break;
3438 3499
3439 case BFI_FCPORT_I2H_STATS_CLEAR_RSP: 3500 case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
3440 /* 3501 /*
3441 * check for timer pop before processing the rsp 3502 * check for timer pop before processing the rsp
3442 */ 3503 */
3443 if (fcport->stats_busy == BFA_FALSE || 3504 if (list_empty(&fcport->statsclr_pending_q) ||
3444 fcport->stats_status == BFA_STATUS_ETIMER) 3505 (fcport->stats_status == BFA_STATUS_ETIMER))
3445 break; 3506 break;
3446 3507
3447 bfa_timer_stop(&fcport->timer); 3508 bfa_timer_stop(&fcport->timer);
3448 fcport->stats_status = BFA_STATUS_OK; 3509 fcport->stats_status = BFA_STATUS_OK;
3449 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, 3510 __bfa_cb_fcport_stats_clr(fcport, BFA_TRUE);
3450 __bfa_cb_fcport_stats_clr, fcport);
3451 break; 3511 break;
3452 3512
3453 case BFI_FCPORT_I2H_ENABLE_AEN: 3513 case BFI_FCPORT_I2H_ENABLE_AEN:
@@ -3779,25 +3839,25 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
3779 * Fetch port statistics (FCQoS or FCoE). 3839 * Fetch port statistics (FCQoS or FCoE).
3780 */ 3840 */
3781bfa_status_t 3841bfa_status_t
3782bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, 3842bfa_fcport_get_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb)
3783 bfa_cb_port_t cbfn, void *cbarg)
3784{ 3843{
3785 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3844 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3786 3845
3787 if (fcport->stats_busy) { 3846 if (bfa_ioc_is_disabled(&bfa->ioc))
3788 bfa_trc(bfa, fcport->stats_busy); 3847 return BFA_STATUS_IOC_DISABLED;
3789 return BFA_STATUS_DEVBUSY;
3790 }
3791 3848
3792 fcport->stats_busy = BFA_TRUE; 3849 if (!list_empty(&fcport->statsclr_pending_q))
3793 fcport->stats_ret = stats; 3850 return BFA_STATUS_DEVBUSY;
3794 fcport->stats_cbfn = cbfn;
3795 fcport->stats_cbarg = cbarg;
3796 3851
3797 bfa_fcport_send_stats_get(fcport); 3852 if (list_empty(&fcport->stats_pending_q)) {
3853 list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q);
3854 bfa_fcport_send_stats_get(fcport);
3855 bfa_timer_start(bfa, &fcport->timer,
3856 bfa_fcport_stats_get_timeout,
3857 fcport, BFA_FCPORT_STATS_TOV);
3858 } else
3859 list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q);
3798 3860
3799 bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
3800 fcport, BFA_FCPORT_STATS_TOV);
3801 return BFA_STATUS_OK; 3861 return BFA_STATUS_OK;
3802} 3862}
3803 3863
@@ -3805,27 +3865,25 @@ bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
3805 * Reset port statistics (FCQoS or FCoE). 3865 * Reset port statistics (FCQoS or FCoE).
3806 */ 3866 */
3807bfa_status_t 3867bfa_status_t
3808bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg) 3868bfa_fcport_clear_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb)
3809{ 3869{
3810 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3870 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3811 3871
3812 if (fcport->stats_busy) { 3872 if (!list_empty(&fcport->stats_pending_q))
3813 bfa_trc(bfa, fcport->stats_busy);
3814 return BFA_STATUS_DEVBUSY; 3873 return BFA_STATUS_DEVBUSY;
3815 }
3816
3817 fcport->stats_busy = BFA_TRUE;
3818 fcport->stats_cbfn = cbfn;
3819 fcport->stats_cbarg = cbarg;
3820 3874
3821 bfa_fcport_send_stats_clear(fcport); 3875 if (list_empty(&fcport->statsclr_pending_q)) {
3876 list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q);
3877 bfa_fcport_send_stats_clear(fcport);
3878 bfa_timer_start(bfa, &fcport->timer,
3879 bfa_fcport_stats_clr_timeout,
3880 fcport, BFA_FCPORT_STATS_TOV);
3881 } else
3882 list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q);
3822 3883
3823 bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
3824 fcport, BFA_FCPORT_STATS_TOV);
3825 return BFA_STATUS_OK; 3884 return BFA_STATUS_OK;
3826} 3885}
3827 3886
3828
3829/* 3887/*
3830 * Fetch port attributes. 3888 * Fetch port attributes.
3831 */ 3889 */
@@ -4619,6 +4677,7 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
4619 rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle); 4677 rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle);
4620 rp->fw_handle = msg.create_rsp->fw_handle; 4678 rp->fw_handle = msg.create_rsp->fw_handle;
4621 rp->qos_attr = msg.create_rsp->qos_attr; 4679 rp->qos_attr = msg.create_rsp->qos_attr;
4680 bfa_rport_set_lunmask(bfa, rp);
4622 WARN_ON(msg.create_rsp->status != BFA_STATUS_OK); 4681 WARN_ON(msg.create_rsp->status != BFA_STATUS_OK);
4623 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 4682 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
4624 break; 4683 break;
@@ -4626,6 +4685,7 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
4626 case BFI_RPORT_I2H_DELETE_RSP: 4685 case BFI_RPORT_I2H_DELETE_RSP:
4627 rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle); 4686 rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle);
4628 WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK); 4687 WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK);
4688 bfa_rport_unset_lunmask(bfa, rp);
4629 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 4689 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
4630 break; 4690 break;
4631 4691
@@ -4706,6 +4766,37 @@ bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed)
4706 bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED); 4766 bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
4707} 4767}
4708 4768
4769/* Set Rport LUN Mask */
4770void
4771bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp)
4772{
4773 struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa);
4774 wwn_t lp_wwn, rp_wwn;
4775 u8 lp_tag = (u8)rp->rport_info.lp_tag;
4776
4777 rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn;
4778 lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn;
4779
4780 BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask =
4781 rp->lun_mask = BFA_TRUE;
4782 bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn, rp->rport_tag, lp_tag);
4783}
4784
4785/* Unset Rport LUN mask */
4786void
4787bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp)
4788{
4789 struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa);
4790 wwn_t lp_wwn, rp_wwn;
4791
4792 rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn;
4793 lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn;
4794
4795 BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask =
4796 rp->lun_mask = BFA_FALSE;
4797 bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn,
4798 BFA_RPORT_TAG_INVALID, BFA_LP_TAG_INVALID);
4799}
4709 4800
4710/* 4801/*
4711 * SGPG related functions 4802 * SGPG related functions
@@ -5517,11 +5608,29 @@ bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode,
5517 return BFA_STATUS_PORT_NOT_DISABLED; 5608 return BFA_STATUS_PORT_NOT_DISABLED;
5518 } 5609 }
5519 5610
5520 /* Check if the speed is supported */ 5611 /*
5521 bfa_fcport_get_attr(bfa, &attr); 5612 * Check if input speed is supported by the port mode
5522 bfa_trc(fcdiag, attr.speed_supported); 5613 */
5523 if (speed > attr.speed_supported) 5614 if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) {
5524 return BFA_STATUS_UNSUPP_SPEED; 5615 if (!(speed == BFA_PORT_SPEED_1GBPS ||
5616 speed == BFA_PORT_SPEED_2GBPS ||
5617 speed == BFA_PORT_SPEED_4GBPS ||
5618 speed == BFA_PORT_SPEED_8GBPS ||
5619 speed == BFA_PORT_SPEED_16GBPS ||
5620 speed == BFA_PORT_SPEED_AUTO)) {
5621 bfa_trc(fcdiag, speed);
5622 return BFA_STATUS_UNSUPP_SPEED;
5623 }
5624 bfa_fcport_get_attr(bfa, &attr);
5625 bfa_trc(fcdiag, attr.speed_supported);
5626 if (speed > attr.speed_supported)
5627 return BFA_STATUS_UNSUPP_SPEED;
5628 } else {
5629 if (speed != BFA_PORT_SPEED_10GBPS) {
5630 bfa_trc(fcdiag, speed);
5631 return BFA_STATUS_UNSUPP_SPEED;
5632 }
5633 }
5525 5634
5526 /* For Mezz card, port speed entered needs to be checked */ 5635 /* For Mezz card, port speed entered needs to be checked */
5527 if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { 5636 if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) {
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h
index fbe513a671b5..95adb86d3769 100644
--- a/drivers/scsi/bfa/bfa_svc.h
+++ b/drivers/scsi/bfa/bfa_svc.h
@@ -297,6 +297,7 @@ struct bfa_rport_s {
297 void *rport_drv; /* fcs/driver rport object */ 297 void *rport_drv; /* fcs/driver rport object */
298 u16 fw_handle; /* firmware rport handle */ 298 u16 fw_handle; /* firmware rport handle */
299 u16 rport_tag; /* BFA rport tag */ 299 u16 rport_tag; /* BFA rport tag */
300 u8 lun_mask; /* LUN mask flag */
300 struct bfa_rport_info_s rport_info; /* rport info from fcs/driver */ 301 struct bfa_rport_info_s rport_info; /* rport info from fcs/driver */
301 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ 302 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
302 struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */ 303 struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */
@@ -404,6 +405,7 @@ struct bfa_lps_s {
404 u8 bb_scn; /* local BB_SCN */ 405 u8 bb_scn; /* local BB_SCN */
405 u8 lsrjt_rsn; /* LSRJT reason */ 406 u8 lsrjt_rsn; /* LSRJT reason */
406 u8 lsrjt_expl; /* LSRJT explanation */ 407 u8 lsrjt_expl; /* LSRJT explanation */
408 u8 lun_mask; /* LUN mask flag */
407 wwn_t pwwn; /* port wwn of lport */ 409 wwn_t pwwn; /* port wwn of lport */
408 wwn_t nwwn; /* node wwn of lport */ 410 wwn_t nwwn; /* node wwn of lport */
409 wwn_t pr_pwwn; /* port wwn of lport peer */ 411 wwn_t pr_pwwn; /* port wwn of lport peer */
@@ -441,7 +443,6 @@ void bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
441 */ 443 */
442 444
443#define BFA_FCPORT(_bfa) (&((_bfa)->modules.port)) 445#define BFA_FCPORT(_bfa) (&((_bfa)->modules.port))
444typedef void (*bfa_cb_port_t) (void *cbarg, enum bfa_status status);
445 446
446/* 447/*
447 * Link notification data structure 448 * Link notification data structure
@@ -495,13 +496,11 @@ struct bfa_fcport_s {
495 u8 *stats_kva; 496 u8 *stats_kva;
496 u64 stats_pa; 497 u64 stats_pa;
497 union bfa_fcport_stats_u *stats; 498 union bfa_fcport_stats_u *stats;
498 union bfa_fcport_stats_u *stats_ret; /* driver stats location */
499 bfa_status_t stats_status; /* stats/statsclr status */ 499 bfa_status_t stats_status; /* stats/statsclr status */
500 bfa_boolean_t stats_busy; /* outstanding stats/statsclr */ 500 struct list_head stats_pending_q;
501 struct list_head statsclr_pending_q;
501 bfa_boolean_t stats_qfull; 502 bfa_boolean_t stats_qfull;
502 u32 stats_reset_time; /* stats reset time stamp */ 503 u32 stats_reset_time; /* stats reset time stamp */
503 bfa_cb_port_t stats_cbfn; /* driver callback function */
504 void *stats_cbarg; /* *!< user callback arg */
505 bfa_boolean_t diag_busy; /* diag busy status */ 504 bfa_boolean_t diag_busy; /* diag busy status */
506 bfa_boolean_t beacon; /* port beacon status */ 505 bfa_boolean_t beacon; /* port beacon status */
507 bfa_boolean_t link_e2e_beacon; /* link beacon status */ 506 bfa_boolean_t link_e2e_beacon; /* link beacon status */
@@ -552,10 +551,9 @@ void bfa_fcport_beacon(void *dev, bfa_boolean_t beacon,
552 bfa_boolean_t link_e2e_beacon); 551 bfa_boolean_t link_e2e_beacon);
553bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa); 552bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa);
554bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa, 553bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa,
555 union bfa_fcport_stats_u *stats, 554 struct bfa_cb_pending_q_s *cb);
556 bfa_cb_port_t cbfn, void *cbarg); 555bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa,
557bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, 556 struct bfa_cb_pending_q_s *cb);
558 void *cbarg);
559bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa); 557bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa);
560bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa); 558bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa);
561bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa); 559bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa);
@@ -578,6 +576,19 @@ void bfa_cb_rport_qos_scn_prio(void *rport,
578 struct bfa_rport_qos_attr_s new_qos_attr); 576 struct bfa_rport_qos_attr_s new_qos_attr);
579 577
580/* 578/*
579 * Rport LUN masking related
580 */
581#define BFA_RPORT_TAG_INVALID 0xffff
582#define BFA_LP_TAG_INVALID 0xff
583void bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp);
584void bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp);
585bfa_boolean_t bfa_rport_lunmask_active(struct bfa_rport_s *rp);
586wwn_t bfa_rport_get_pwwn(struct bfa_s *bfa, struct bfa_rport_s *rp);
587struct bfa_rport_s *bfa_rport_get_by_wwn(struct bfa_s *bfa, u16 vf_id,
588 wwn_t *lpwwn, wwn_t rpwwn);
589void *bfa_cb_get_rp_by_wwn(void *arg, u16 vf_id, wwn_t *lpwwn, wwn_t rpwwn);
590
591/*
581 * bfa fcxp API functions 592 * bfa fcxp API functions
582 */ 593 */
583struct bfa_fcxp_s *bfa_fcxp_alloc(void *bfad_fcxp, struct bfa_s *bfa, 594struct bfa_fcxp_s *bfa_fcxp_alloc(void *bfad_fcxp, struct bfa_s *bfa,
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index beb30a748ea5..66fb72531b34 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -1348,7 +1348,7 @@ int
1348bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) 1348bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
1349{ 1349{
1350 struct bfad_s *bfad; 1350 struct bfad_s *bfad;
1351 int error = -ENODEV, retval; 1351 int error = -ENODEV, retval, i;
1352 1352
1353 /* For single port cards - only claim function 0 */ 1353 /* For single port cards - only claim function 0 */
1354 if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P) && 1354 if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P) &&
@@ -1372,6 +1372,12 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
1372 bfa_trc_init(bfad->trcmod); 1372 bfa_trc_init(bfad->trcmod);
1373 bfa_trc(bfad, bfad_inst); 1373 bfa_trc(bfad, bfad_inst);
1374 1374
1375 /* AEN INIT */
1376 INIT_LIST_HEAD(&bfad->free_aen_q);
1377 INIT_LIST_HEAD(&bfad->active_aen_q);
1378 for (i = 0; i < BFA_AEN_MAX_ENTRY; i++)
1379 list_add_tail(&bfad->aen_list[i].qe, &bfad->free_aen_q);
1380
1375 if (!(bfad_load_fwimg(pdev))) { 1381 if (!(bfad_load_fwimg(pdev))) {
1376 kfree(bfad->trcmod); 1382 kfree(bfad->trcmod);
1377 goto out_alloc_trace_failure; 1383 goto out_alloc_trace_failure;
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 89f863ed2334..06fc00caeb41 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -56,7 +56,7 @@ bfad_iocmd_ioc_disable(struct bfad_s *bfad, void *cmd)
56 spin_lock_irqsave(&bfad->bfad_lock, flags); 56 spin_lock_irqsave(&bfad->bfad_lock, flags);
57 if (bfad->disable_active) { 57 if (bfad->disable_active) {
58 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 58 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
59 return EBUSY; 59 return -EBUSY;
60 } 60 }
61 61
62 bfad->disable_active = BFA_TRUE; 62 bfad->disable_active = BFA_TRUE;
@@ -90,6 +90,7 @@ bfad_iocmd_ioc_get_info(struct bfad_s *bfad, void *cmd)
90 bfa_get_adapter_serial_num(&bfad->bfa, iocmd->serialnum); 90 bfa_get_adapter_serial_num(&bfad->bfa, iocmd->serialnum);
91 iocmd->factorynwwn = pattr.factorynwwn; 91 iocmd->factorynwwn = pattr.factorynwwn;
92 iocmd->factorypwwn = pattr.factorypwwn; 92 iocmd->factorypwwn = pattr.factorypwwn;
93 iocmd->bfad_num = bfad->inst_no;
93 im_port = bfad->pport.im_port; 94 im_port = bfad->pport.im_port;
94 iocmd->host = im_port->shost->host_no; 95 iocmd->host = im_port->shost->host_no;
95 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 96 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -178,6 +179,38 @@ out:
178} 179}
179 180
180int 181int
182bfad_iocmd_ioc_reset_stats(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
183{
184 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
185 unsigned long flags;
186
187 if (v_cmd == IOCMD_IOC_RESET_STATS) {
188 bfa_ioc_clear_stats(&bfad->bfa);
189 iocmd->status = BFA_STATUS_OK;
190 } else if (v_cmd == IOCMD_IOC_RESET_FWSTATS) {
191 spin_lock_irqsave(&bfad->bfad_lock, flags);
192 iocmd->status = bfa_ioc_fw_stats_clear(&bfad->bfa.ioc);
193 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
194 }
195
196 return 0;
197}
198
199int
200bfad_iocmd_ioc_set_name(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
201{
202 struct bfa_bsg_ioc_name_s *iocmd = (struct bfa_bsg_ioc_name_s *) cmd;
203
204 if (v_cmd == IOCMD_IOC_SET_ADAPTER_NAME)
205 strcpy(bfad->adapter_name, iocmd->name);
206 else if (v_cmd == IOCMD_IOC_SET_PORT_NAME)
207 strcpy(bfad->port_name, iocmd->name);
208
209 iocmd->status = BFA_STATUS_OK;
210 return 0;
211}
212
213int
181bfad_iocmd_iocfc_get_attr(struct bfad_s *bfad, void *cmd) 214bfad_iocmd_iocfc_get_attr(struct bfad_s *bfad, void *cmd)
182{ 215{
183 struct bfa_bsg_iocfc_attr_s *iocmd = (struct bfa_bsg_iocfc_attr_s *)cmd; 216 struct bfa_bsg_iocfc_attr_s *iocmd = (struct bfa_bsg_iocfc_attr_s *)cmd;
@@ -306,6 +339,81 @@ out:
306 return 0; 339 return 0;
307} 340}
308 341
342int
343bfad_iocmd_port_reset_stats(struct bfad_s *bfad, void *cmd)
344{
345 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
346 struct bfad_hal_comp fcomp;
347 unsigned long flags;
348
349 init_completion(&fcomp.comp);
350 spin_lock_irqsave(&bfad->bfad_lock, flags);
351 iocmd->status = bfa_port_clear_stats(&bfad->bfa.modules.port,
352 bfad_hcb_comp, &fcomp);
353 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
354 if (iocmd->status != BFA_STATUS_OK) {
355 bfa_trc(bfad, iocmd->status);
356 return 0;
357 }
358 wait_for_completion(&fcomp.comp);
359 iocmd->status = fcomp.status;
360 return 0;
361}
362
363int
364bfad_iocmd_set_port_cfg(struct bfad_s *bfad, void *iocmd, unsigned int v_cmd)
365{
366 struct bfa_bsg_port_cfg_s *cmd = (struct bfa_bsg_port_cfg_s *)iocmd;
367 unsigned long flags;
368
369 spin_lock_irqsave(&bfad->bfad_lock, flags);
370 if (v_cmd == IOCMD_PORT_CFG_TOPO)
371 cmd->status = bfa_fcport_cfg_topology(&bfad->bfa, cmd->param);
372 else if (v_cmd == IOCMD_PORT_CFG_SPEED)
373 cmd->status = bfa_fcport_cfg_speed(&bfad->bfa, cmd->param);
374 else if (v_cmd == IOCMD_PORT_CFG_ALPA)
375 cmd->status = bfa_fcport_cfg_hardalpa(&bfad->bfa, cmd->param);
376 else if (v_cmd == IOCMD_PORT_CLR_ALPA)
377 cmd->status = bfa_fcport_clr_hardalpa(&bfad->bfa);
378 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
379
380 return 0;
381}
382
383int
384bfad_iocmd_port_cfg_maxfrsize(struct bfad_s *bfad, void *cmd)
385{
386 struct bfa_bsg_port_cfg_maxfrsize_s *iocmd =
387 (struct bfa_bsg_port_cfg_maxfrsize_s *)cmd;
388 unsigned long flags;
389
390 spin_lock_irqsave(&bfad->bfad_lock, flags);
391 iocmd->status = bfa_fcport_cfg_maxfrsize(&bfad->bfa, iocmd->maxfrsize);
392 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
393
394 return 0;
395}
396
397int
398bfad_iocmd_port_cfg_bbsc(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
399{
400 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
401 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
402 unsigned long flags;
403
404 spin_lock_irqsave(&bfad->bfad_lock, flags);
405 if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) {
406 if (v_cmd == IOCMD_PORT_BBSC_ENABLE)
407 fcport->cfg.bb_scn_state = BFA_TRUE;
408 else if (v_cmd == IOCMD_PORT_BBSC_DISABLE)
409 fcport->cfg.bb_scn_state = BFA_FALSE;
410 }
411 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
412
413 iocmd->status = BFA_STATUS_OK;
414 return 0;
415}
416
309static int 417static int
310bfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd) 418bfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd)
311{ 419{
@@ -354,6 +462,40 @@ out:
354} 462}
355 463
356int 464int
465bfad_iocmd_lport_reset_stats(struct bfad_s *bfad, void *cmd)
466{
467 struct bfa_fcs_lport_s *fcs_port;
468 struct bfa_bsg_reset_stats_s *iocmd =
469 (struct bfa_bsg_reset_stats_s *)cmd;
470 struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa);
471 struct list_head *qe, *qen;
472 struct bfa_itnim_s *itnim;
473 unsigned long flags;
474
475 spin_lock_irqsave(&bfad->bfad_lock, flags);
476 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
477 iocmd->vf_id, iocmd->vpwwn);
478 if (fcs_port == NULL) {
479 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
480 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
481 goto out;
482 }
483
484 bfa_fcs_lport_clear_stats(fcs_port);
485 /* clear IO stats from all active itnims */
486 list_for_each_safe(qe, qen, &fcpim->itnim_q) {
487 itnim = (struct bfa_itnim_s *) qe;
488 if (itnim->rport->rport_info.lp_tag != fcs_port->lp_tag)
489 continue;
490 bfa_itnim_clear_stats(itnim);
491 }
492 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
493 iocmd->status = BFA_STATUS_OK;
494out:
495 return 0;
496}
497
498int
357bfad_iocmd_lport_get_iostats(struct bfad_s *bfad, void *cmd) 499bfad_iocmd_lport_get_iostats(struct bfad_s *bfad, void *cmd)
358{ 500{
359 struct bfa_fcs_lport_s *fcs_port; 501 struct bfa_fcs_lport_s *fcs_port;
@@ -389,7 +531,7 @@ bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd,
389 void *iocmd_bufptr; 531 void *iocmd_bufptr;
390 532
391 if (iocmd->nrports == 0) 533 if (iocmd->nrports == 0)
392 return EINVAL; 534 return -EINVAL;
393 535
394 if (bfad_chk_iocmd_sz(payload_len, 536 if (bfad_chk_iocmd_sz(payload_len,
395 sizeof(struct bfa_bsg_lport_get_rports_s), 537 sizeof(struct bfa_bsg_lport_get_rports_s),
@@ -539,6 +681,152 @@ out:
539 return 0; 681 return 0;
540} 682}
541 683
684int
685bfad_iocmd_rport_clr_stats(struct bfad_s *bfad, void *cmd)
686{
687 struct bfa_bsg_rport_reset_stats_s *iocmd =
688 (struct bfa_bsg_rport_reset_stats_s *)cmd;
689 struct bfa_fcs_lport_s *fcs_port;
690 struct bfa_fcs_rport_s *fcs_rport;
691 struct bfa_rport_s *rport;
692 unsigned long flags;
693
694 spin_lock_irqsave(&bfad->bfad_lock, flags);
695 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
696 iocmd->vf_id, iocmd->pwwn);
697 if (fcs_port == NULL) {
698 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
699 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
700 goto out;
701 }
702
703 fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
704 if (fcs_rport == NULL) {
705 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
706 iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
707 goto out;
708 }
709
710 memset((char *)&fcs_rport->stats, 0, sizeof(struct bfa_rport_stats_s));
711 rport = bfa_fcs_rport_get_halrport(fcs_rport);
712 memset(&rport->stats, 0, sizeof(rport->stats));
713 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
714 iocmd->status = BFA_STATUS_OK;
715out:
716 return 0;
717}
718
719int
720bfad_iocmd_rport_set_speed(struct bfad_s *bfad, void *cmd)
721{
722 struct bfa_bsg_rport_set_speed_s *iocmd =
723 (struct bfa_bsg_rport_set_speed_s *)cmd;
724 struct bfa_fcs_lport_s *fcs_port;
725 struct bfa_fcs_rport_s *fcs_rport;
726 unsigned long flags;
727
728 spin_lock_irqsave(&bfad->bfad_lock, flags);
729 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
730 iocmd->vf_id, iocmd->pwwn);
731 if (fcs_port == NULL) {
732 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
733 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
734 goto out;
735 }
736
737 fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
738 if (fcs_rport == NULL) {
739 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
740 iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
741 goto out;
742 }
743
744 fcs_rport->rpf.assigned_speed = iocmd->speed;
745 /* Set this speed in f/w only if the RPSC speed is not available */
746 if (fcs_rport->rpf.rpsc_speed == BFA_PORT_SPEED_UNKNOWN)
747 bfa_rport_speed(fcs_rport->bfa_rport, iocmd->speed);
748 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
749 iocmd->status = BFA_STATUS_OK;
750out:
751 return 0;
752}
753
754int
755bfad_iocmd_vport_get_attr(struct bfad_s *bfad, void *cmd)
756{
757 struct bfa_fcs_vport_s *fcs_vport;
758 struct bfa_bsg_vport_attr_s *iocmd = (struct bfa_bsg_vport_attr_s *)cmd;
759 unsigned long flags;
760
761 spin_lock_irqsave(&bfad->bfad_lock, flags);
762 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs,
763 iocmd->vf_id, iocmd->vpwwn);
764 if (fcs_vport == NULL) {
765 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
766 iocmd->status = BFA_STATUS_UNKNOWN_VWWN;
767 goto out;
768 }
769
770 bfa_fcs_vport_get_attr(fcs_vport, &iocmd->vport_attr);
771 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
772 iocmd->status = BFA_STATUS_OK;
773out:
774 return 0;
775}
776
777int
778bfad_iocmd_vport_get_stats(struct bfad_s *bfad, void *cmd)
779{
780 struct bfa_fcs_vport_s *fcs_vport;
781 struct bfa_bsg_vport_stats_s *iocmd =
782 (struct bfa_bsg_vport_stats_s *)cmd;
783 unsigned long flags;
784
785 spin_lock_irqsave(&bfad->bfad_lock, flags);
786 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs,
787 iocmd->vf_id, iocmd->vpwwn);
788 if (fcs_vport == NULL) {
789 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
790 iocmd->status = BFA_STATUS_UNKNOWN_VWWN;
791 goto out;
792 }
793
794 memcpy((void *)&iocmd->vport_stats, (void *)&fcs_vport->vport_stats,
795 sizeof(struct bfa_vport_stats_s));
796 memcpy((void *)&iocmd->vport_stats.port_stats,
797 (void *)&fcs_vport->lport.stats,
798 sizeof(struct bfa_lport_stats_s));
799 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
800 iocmd->status = BFA_STATUS_OK;
801out:
802 return 0;
803}
804
805int
806bfad_iocmd_vport_clr_stats(struct bfad_s *bfad, void *cmd)
807{
808 struct bfa_fcs_vport_s *fcs_vport;
809 struct bfa_bsg_reset_stats_s *iocmd =
810 (struct bfa_bsg_reset_stats_s *)cmd;
811 unsigned long flags;
812
813 spin_lock_irqsave(&bfad->bfad_lock, flags);
814 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs,
815 iocmd->vf_id, iocmd->vpwwn);
816 if (fcs_vport == NULL) {
817 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
818 iocmd->status = BFA_STATUS_UNKNOWN_VWWN;
819 goto out;
820 }
821
822 memset(&fcs_vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s));
823 memset(&fcs_vport->lport.stats, 0, sizeof(struct bfa_lport_stats_s));
824 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
825 iocmd->status = BFA_STATUS_OK;
826out:
827 return 0;
828}
829
542static int 830static int
543bfad_iocmd_fabric_get_lports(struct bfad_s *bfad, void *cmd, 831bfad_iocmd_fabric_get_lports(struct bfad_s *bfad, void *cmd,
544 unsigned int payload_len) 832 unsigned int payload_len)
@@ -582,6 +870,66 @@ out:
582} 870}
583 871
584int 872int
873bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
874{
875 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
876 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
877 unsigned long flags;
878
879 spin_lock_irqsave(&bfad->bfad_lock, flags);
880
881 if (cmd == IOCMD_RATELIM_ENABLE)
882 fcport->cfg.ratelimit = BFA_TRUE;
883 else if (cmd == IOCMD_RATELIM_DISABLE)
884 fcport->cfg.ratelimit = BFA_FALSE;
885
886 if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN)
887 fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS;
888
889 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
890 iocmd->status = BFA_STATUS_OK;
891
892 return 0;
893}
894
895int
896bfad_iocmd_ratelim_speed(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
897{
898 struct bfa_bsg_trl_speed_s *iocmd = (struct bfa_bsg_trl_speed_s *)pcmd;
899 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
900 unsigned long flags;
901
902 spin_lock_irqsave(&bfad->bfad_lock, flags);
903
904 /* Auto and speeds greater than the supported speed, are invalid */
905 if ((iocmd->speed == BFA_PORT_SPEED_AUTO) ||
906 (iocmd->speed > fcport->speed_sup)) {
907 iocmd->status = BFA_STATUS_UNSUPP_SPEED;
908 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
909 return 0;
910 }
911
912 fcport->cfg.trl_def_speed = iocmd->speed;
913 iocmd->status = BFA_STATUS_OK;
914 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
915
916 return 0;
917}
918
919int
920bfad_iocmd_cfg_fcpim(struct bfad_s *bfad, void *cmd)
921{
922 struct bfa_bsg_fcpim_s *iocmd = (struct bfa_bsg_fcpim_s *)cmd;
923 unsigned long flags;
924
925 spin_lock_irqsave(&bfad->bfad_lock, flags);
926 bfa_fcpim_path_tov_set(&bfad->bfa, iocmd->param);
927 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
928 iocmd->status = BFA_STATUS_OK;
929 return 0;
930}
931
932int
585bfad_iocmd_fcpim_get_modstats(struct bfad_s *bfad, void *cmd) 933bfad_iocmd_fcpim_get_modstats(struct bfad_s *bfad, void *cmd)
586{ 934{
587 struct bfa_bsg_fcpim_modstats_s *iocmd = 935 struct bfa_bsg_fcpim_modstats_s *iocmd =
@@ -604,6 +952,28 @@ bfad_iocmd_fcpim_get_modstats(struct bfad_s *bfad, void *cmd)
604} 952}
605 953
606int 954int
955bfad_iocmd_fcpim_clr_modstats(struct bfad_s *bfad, void *cmd)
956{
957 struct bfa_bsg_fcpim_modstatsclr_s *iocmd =
958 (struct bfa_bsg_fcpim_modstatsclr_s *)cmd;
959 struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa);
960 struct list_head *qe, *qen;
961 struct bfa_itnim_s *itnim;
962 unsigned long flags;
963
964 spin_lock_irqsave(&bfad->bfad_lock, flags);
965 list_for_each_safe(qe, qen, &fcpim->itnim_q) {
966 itnim = (struct bfa_itnim_s *) qe;
967 bfa_itnim_clear_stats(itnim);
968 }
969 memset(&fcpim->del_itn_stats, 0,
970 sizeof(struct bfa_fcpim_del_itn_stats_s));
971 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
972 iocmd->status = BFA_STATUS_OK;
973 return 0;
974}
975
976int
607bfad_iocmd_fcpim_get_del_itn_stats(struct bfad_s *bfad, void *cmd) 977bfad_iocmd_fcpim_get_del_itn_stats(struct bfad_s *bfad, void *cmd)
608{ 978{
609 struct bfa_bsg_fcpim_del_itn_stats_s *iocmd = 979 struct bfa_bsg_fcpim_del_itn_stats_s *iocmd =
@@ -670,6 +1040,35 @@ bfad_iocmd_itnim_get_iostats(struct bfad_s *bfad, void *cmd)
670} 1040}
671 1041
672static int 1042static int
1043bfad_iocmd_itnim_reset_stats(struct bfad_s *bfad, void *cmd)
1044{
1045 struct bfa_bsg_rport_reset_stats_s *iocmd =
1046 (struct bfa_bsg_rport_reset_stats_s *)cmd;
1047 struct bfa_fcs_lport_s *fcs_port;
1048 struct bfa_fcs_itnim_s *itnim;
1049 unsigned long flags;
1050
1051 spin_lock_irqsave(&bfad->bfad_lock, flags);
1052 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
1053 iocmd->vf_id, iocmd->pwwn);
1054 if (!fcs_port)
1055 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
1056 else {
1057 itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn);
1058 if (itnim == NULL)
1059 iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
1060 else {
1061 iocmd->status = BFA_STATUS_OK;
1062 bfa_fcs_itnim_stats_clear(fcs_port, iocmd->rpwwn);
1063 bfa_itnim_clear_stats(bfa_fcs_itnim_get_halitn(itnim));
1064 }
1065 }
1066 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1067
1068 return 0;
1069}
1070
1071static int
673bfad_iocmd_itnim_get_itnstats(struct bfad_s *bfad, void *cmd) 1072bfad_iocmd_itnim_get_itnstats(struct bfad_s *bfad, void *cmd)
674{ 1073{
675 struct bfa_bsg_itnim_itnstats_s *iocmd = 1074 struct bfa_bsg_itnim_itnstats_s *iocmd =
@@ -1511,11 +1910,545 @@ out:
1511 return 0; 1910 return 0;
1512} 1911}
1513 1912
1913#define BFA_DEBUG_FW_CORE_CHUNK_SZ 0x4000U /* 16K chunks for FW dump */
1914int
1915bfad_iocmd_debug_fw_core(struct bfad_s *bfad, void *cmd,
1916 unsigned int payload_len)
1917{
1918 struct bfa_bsg_debug_s *iocmd = (struct bfa_bsg_debug_s *)cmd;
1919 void *iocmd_bufptr;
1920 unsigned long flags;
1921
1922 if (bfad_chk_iocmd_sz(payload_len, sizeof(struct bfa_bsg_debug_s),
1923 BFA_DEBUG_FW_CORE_CHUNK_SZ) != BFA_STATUS_OK) {
1924 iocmd->status = BFA_STATUS_VERSION_FAIL;
1925 return 0;
1926 }
1927
1928 if (iocmd->bufsz < BFA_DEBUG_FW_CORE_CHUNK_SZ ||
1929 !IS_ALIGNED(iocmd->bufsz, sizeof(u16)) ||
1930 !IS_ALIGNED(iocmd->offset, sizeof(u32))) {
1931 bfa_trc(bfad, BFA_DEBUG_FW_CORE_CHUNK_SZ);
1932 iocmd->status = BFA_STATUS_EINVAL;
1933 goto out;
1934 }
1935
1936 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_debug_s);
1937 spin_lock_irqsave(&bfad->bfad_lock, flags);
1938 iocmd->status = bfa_ioc_debug_fwcore(&bfad->bfa.ioc, iocmd_bufptr,
1939 (u32 *)&iocmd->offset, &iocmd->bufsz);
1940 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1941out:
1942 return 0;
1943}
1944
1945int
1946bfad_iocmd_debug_ctl(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
1947{
1948 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
1949 unsigned long flags;
1950
1951 if (v_cmd == IOCMD_DEBUG_FW_STATE_CLR) {
1952 spin_lock_irqsave(&bfad->bfad_lock, flags);
1953 bfad->bfa.ioc.dbg_fwsave_once = BFA_TRUE;
1954 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1955 } else if (v_cmd == IOCMD_DEBUG_PORTLOG_CLR)
1956 bfad->plog_buf.head = bfad->plog_buf.tail = 0;
1957 else if (v_cmd == IOCMD_DEBUG_START_DTRC)
1958 bfa_trc_init(bfad->trcmod);
1959 else if (v_cmd == IOCMD_DEBUG_STOP_DTRC)
1960 bfa_trc_stop(bfad->trcmod);
1961
1962 iocmd->status = BFA_STATUS_OK;
1963 return 0;
1964}
1965
1966int
1967bfad_iocmd_porglog_ctl(struct bfad_s *bfad, void *cmd)
1968{
1969 struct bfa_bsg_portlogctl_s *iocmd = (struct bfa_bsg_portlogctl_s *)cmd;
1970
1971 if (iocmd->ctl == BFA_TRUE)
1972 bfad->plog_buf.plog_enabled = 1;
1973 else
1974 bfad->plog_buf.plog_enabled = 0;
1975
1976 iocmd->status = BFA_STATUS_OK;
1977 return 0;
1978}
1979
1980int
1981bfad_iocmd_fcpim_cfg_profile(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
1982{
1983 struct bfa_bsg_fcpim_profile_s *iocmd =
1984 (struct bfa_bsg_fcpim_profile_s *)cmd;
1985 struct timeval tv;
1986 unsigned long flags;
1987
1988 do_gettimeofday(&tv);
1989 spin_lock_irqsave(&bfad->bfad_lock, flags);
1990 if (v_cmd == IOCMD_FCPIM_PROFILE_ON)
1991 iocmd->status = bfa_fcpim_profile_on(&bfad->bfa, tv.tv_sec);
1992 else if (v_cmd == IOCMD_FCPIM_PROFILE_OFF)
1993 iocmd->status = bfa_fcpim_profile_off(&bfad->bfa);
1994 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1995
1996 return 0;
1997}
1998
1999static int
2000bfad_iocmd_itnim_get_ioprofile(struct bfad_s *bfad, void *cmd)
2001{
2002 struct bfa_bsg_itnim_ioprofile_s *iocmd =
2003 (struct bfa_bsg_itnim_ioprofile_s *)cmd;
2004 struct bfa_fcs_lport_s *fcs_port;
2005 struct bfa_fcs_itnim_s *itnim;
2006 unsigned long flags;
2007
2008 spin_lock_irqsave(&bfad->bfad_lock, flags);
2009 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
2010 iocmd->vf_id, iocmd->lpwwn);
2011 if (!fcs_port)
2012 iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
2013 else {
2014 itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn);
2015 if (itnim == NULL)
2016 iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
2017 else
2018 iocmd->status = bfa_itnim_get_ioprofile(
2019 bfa_fcs_itnim_get_halitn(itnim),
2020 &iocmd->ioprofile);
2021 }
2022 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2023 return 0;
2024}
2025
2026int
2027bfad_iocmd_fcport_get_stats(struct bfad_s *bfad, void *cmd)
2028{
2029 struct bfa_bsg_fcport_stats_s *iocmd =
2030 (struct bfa_bsg_fcport_stats_s *)cmd;
2031 struct bfad_hal_comp fcomp;
2032 unsigned long flags;
2033 struct bfa_cb_pending_q_s cb_qe;
2034
2035 init_completion(&fcomp.comp);
2036 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
2037 &fcomp, &iocmd->stats);
2038 spin_lock_irqsave(&bfad->bfad_lock, flags);
2039 iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
2040 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2041 if (iocmd->status != BFA_STATUS_OK) {
2042 bfa_trc(bfad, iocmd->status);
2043 goto out;
2044 }
2045 wait_for_completion(&fcomp.comp);
2046 iocmd->status = fcomp.status;
2047out:
2048 return 0;
2049}
2050
2051int
2052bfad_iocmd_fcport_reset_stats(struct bfad_s *bfad, void *cmd)
2053{
2054 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
2055 struct bfad_hal_comp fcomp;
2056 unsigned long flags;
2057 struct bfa_cb_pending_q_s cb_qe;
2058
2059 init_completion(&fcomp.comp);
2060 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, &fcomp, NULL);
2061
2062 spin_lock_irqsave(&bfad->bfad_lock, flags);
2063 iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe);
2064 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2065 if (iocmd->status != BFA_STATUS_OK) {
2066 bfa_trc(bfad, iocmd->status);
2067 goto out;
2068 }
2069 wait_for_completion(&fcomp.comp);
2070 iocmd->status = fcomp.status;
2071out:
2072 return 0;
2073}
2074
2075int
2076bfad_iocmd_boot_cfg(struct bfad_s *bfad, void *cmd)
2077{
2078 struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd;
2079 struct bfad_hal_comp fcomp;
2080 unsigned long flags;
2081
2082 init_completion(&fcomp.comp);
2083 spin_lock_irqsave(&bfad->bfad_lock, flags);
2084 iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa),
2085 BFA_FLASH_PART_BOOT, PCI_FUNC(bfad->pcidev->devfn),
2086 &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0,
2087 bfad_hcb_comp, &fcomp);
2088 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2089 if (iocmd->status != BFA_STATUS_OK)
2090 goto out;
2091 wait_for_completion(&fcomp.comp);
2092 iocmd->status = fcomp.status;
2093out:
2094 return 0;
2095}
2096
2097int
2098bfad_iocmd_boot_query(struct bfad_s *bfad, void *cmd)
2099{
2100 struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd;
2101 struct bfad_hal_comp fcomp;
2102 unsigned long flags;
2103
2104 init_completion(&fcomp.comp);
2105 spin_lock_irqsave(&bfad->bfad_lock, flags);
2106 iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa),
2107 BFA_FLASH_PART_BOOT, PCI_FUNC(bfad->pcidev->devfn),
2108 &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0,
2109 bfad_hcb_comp, &fcomp);
2110 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2111 if (iocmd->status != BFA_STATUS_OK)
2112 goto out;
2113 wait_for_completion(&fcomp.comp);
2114 iocmd->status = fcomp.status;
2115out:
2116 return 0;
2117}
2118
2119int
2120bfad_iocmd_preboot_query(struct bfad_s *bfad, void *cmd)
2121{
2122 struct bfa_bsg_preboot_s *iocmd = (struct bfa_bsg_preboot_s *)cmd;
2123 struct bfi_iocfc_cfgrsp_s *cfgrsp = bfad->bfa.iocfc.cfgrsp;
2124 struct bfa_boot_pbc_s *pbcfg = &iocmd->cfg;
2125 unsigned long flags;
2126
2127 spin_lock_irqsave(&bfad->bfad_lock, flags);
2128 pbcfg->enable = cfgrsp->pbc_cfg.boot_enabled;
2129 pbcfg->nbluns = cfgrsp->pbc_cfg.nbluns;
2130 pbcfg->speed = cfgrsp->pbc_cfg.port_speed;
2131 memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun));
2132 iocmd->status = BFA_STATUS_OK;
2133 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2134
2135 return 0;
2136}
2137
2138int
2139bfad_iocmd_ethboot_cfg(struct bfad_s *bfad, void *cmd)
2140{
2141 struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd;
2142 struct bfad_hal_comp fcomp;
2143 unsigned long flags;
2144
2145 init_completion(&fcomp.comp);
2146 spin_lock_irqsave(&bfad->bfad_lock, flags);
2147 iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa),
2148 BFA_FLASH_PART_PXECFG,
2149 bfad->bfa.ioc.port_id, &iocmd->cfg,
2150 sizeof(struct bfa_ethboot_cfg_s), 0,
2151 bfad_hcb_comp, &fcomp);
2152 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2153 if (iocmd->status != BFA_STATUS_OK)
2154 goto out;
2155 wait_for_completion(&fcomp.comp);
2156 iocmd->status = fcomp.status;
2157out:
2158 return 0;
2159}
2160
2161int
2162bfad_iocmd_ethboot_query(struct bfad_s *bfad, void *cmd)
2163{
2164 struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd;
2165 struct bfad_hal_comp fcomp;
2166 unsigned long flags;
2167
2168 init_completion(&fcomp.comp);
2169 spin_lock_irqsave(&bfad->bfad_lock, flags);
2170 iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa),
2171 BFA_FLASH_PART_PXECFG,
2172 bfad->bfa.ioc.port_id, &iocmd->cfg,
2173 sizeof(struct bfa_ethboot_cfg_s), 0,
2174 bfad_hcb_comp, &fcomp);
2175 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2176 if (iocmd->status != BFA_STATUS_OK)
2177 goto out;
2178 wait_for_completion(&fcomp.comp);
2179 iocmd->status = fcomp.status;
2180out:
2181 return 0;
2182}
2183
2184int
2185bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
2186{
2187 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
2188 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
2189 struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
2190 unsigned long flags;
2191
2192 spin_lock_irqsave(&bfad->bfad_lock, flags);
2193
2194 if (v_cmd == IOCMD_TRUNK_ENABLE) {
2195 trunk->attr.state = BFA_TRUNK_OFFLINE;
2196 bfa_fcport_disable(&bfad->bfa);
2197 fcport->cfg.trunked = BFA_TRUE;
2198 } else if (v_cmd == IOCMD_TRUNK_DISABLE) {
2199 trunk->attr.state = BFA_TRUNK_DISABLED;
2200 bfa_fcport_disable(&bfad->bfa);
2201 fcport->cfg.trunked = BFA_FALSE;
2202 }
2203
2204 if (!bfa_fcport_is_disabled(&bfad->bfa))
2205 bfa_fcport_enable(&bfad->bfa);
2206
2207 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2208
2209 iocmd->status = BFA_STATUS_OK;
2210 return 0;
2211}
2212
2213int
2214bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd)
2215{
2216 struct bfa_bsg_trunk_attr_s *iocmd = (struct bfa_bsg_trunk_attr_s *)cmd;
2217 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
2218 struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
2219 unsigned long flags;
2220
2221 spin_lock_irqsave(&bfad->bfad_lock, flags);
2222 memcpy((void *)&iocmd->attr, (void *)&trunk->attr,
2223 sizeof(struct bfa_trunk_attr_s));
2224 iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa);
2225 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2226
2227 iocmd->status = BFA_STATUS_OK;
2228 return 0;
2229}
2230
2231int
2232bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
2233{
2234 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
2235 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
2236 unsigned long flags;
2237
2238 spin_lock_irqsave(&bfad->bfad_lock, flags);
2239 if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) {
2240 if (v_cmd == IOCMD_QOS_ENABLE)
2241 fcport->cfg.qos_enabled = BFA_TRUE;
2242 else if (v_cmd == IOCMD_QOS_DISABLE)
2243 fcport->cfg.qos_enabled = BFA_FALSE;
2244 }
2245 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2246
2247 iocmd->status = BFA_STATUS_OK;
2248 return 0;
2249}
2250
2251int
2252bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd)
2253{
2254 struct bfa_bsg_qos_attr_s *iocmd = (struct bfa_bsg_qos_attr_s *)cmd;
2255 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
2256 unsigned long flags;
2257
2258 spin_lock_irqsave(&bfad->bfad_lock, flags);
2259 iocmd->attr.state = fcport->qos_attr.state;
2260 iocmd->attr.total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr);
2261 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2262
2263 iocmd->status = BFA_STATUS_OK;
2264 return 0;
2265}
2266
2267int
2268bfad_iocmd_qos_get_vc_attr(struct bfad_s *bfad, void *cmd)
2269{
2270 struct bfa_bsg_qos_vc_attr_s *iocmd =
2271 (struct bfa_bsg_qos_vc_attr_s *)cmd;
2272 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
2273 struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
2274 unsigned long flags;
2275 u32 i = 0;
2276
2277 spin_lock_irqsave(&bfad->bfad_lock, flags);
2278 iocmd->attr.total_vc_count = be16_to_cpu(bfa_vc_attr->total_vc_count);
2279 iocmd->attr.shared_credit = be16_to_cpu(bfa_vc_attr->shared_credit);
2280 iocmd->attr.elp_opmode_flags =
2281 be32_to_cpu(bfa_vc_attr->elp_opmode_flags);
2282
2283 /* Individual VC info */
2284 while (i < iocmd->attr.total_vc_count) {
2285 iocmd->attr.vc_info[i].vc_credit =
2286 bfa_vc_attr->vc_info[i].vc_credit;
2287 iocmd->attr.vc_info[i].borrow_credit =
2288 bfa_vc_attr->vc_info[i].borrow_credit;
2289 iocmd->attr.vc_info[i].priority =
2290 bfa_vc_attr->vc_info[i].priority;
2291 i++;
2292 }
2293 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2294
2295 iocmd->status = BFA_STATUS_OK;
2296 return 0;
2297}
2298
2299int
2300bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
2301{
2302 struct bfa_bsg_fcport_stats_s *iocmd =
2303 (struct bfa_bsg_fcport_stats_s *)cmd;
2304 struct bfad_hal_comp fcomp;
2305 unsigned long flags;
2306 struct bfa_cb_pending_q_s cb_qe;
2307
2308 init_completion(&fcomp.comp);
2309 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
2310 &fcomp, &iocmd->stats);
2311
2312 spin_lock_irqsave(&bfad->bfad_lock, flags);
2313 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
2314 iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
2315 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2316 if (iocmd->status != BFA_STATUS_OK) {
2317 bfa_trc(bfad, iocmd->status);
2318 goto out;
2319 }
2320 wait_for_completion(&fcomp.comp);
2321 iocmd->status = fcomp.status;
2322out:
2323 return 0;
2324}
2325
2326int
2327bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
2328{
2329 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
2330 struct bfad_hal_comp fcomp;
2331 unsigned long flags;
2332 struct bfa_cb_pending_q_s cb_qe;
2333
2334 init_completion(&fcomp.comp);
2335 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
2336 &fcomp, NULL);
2337
2338 spin_lock_irqsave(&bfad->bfad_lock, flags);
2339 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
2340 iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe);
2341 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2342 if (iocmd->status != BFA_STATUS_OK) {
2343 bfa_trc(bfad, iocmd->status);
2344 goto out;
2345 }
2346 wait_for_completion(&fcomp.comp);
2347 iocmd->status = fcomp.status;
2348out:
2349 return 0;
2350}
2351
2352int
2353bfad_iocmd_vf_get_stats(struct bfad_s *bfad, void *cmd)
2354{
2355 struct bfa_bsg_vf_stats_s *iocmd =
2356 (struct bfa_bsg_vf_stats_s *)cmd;
2357 struct bfa_fcs_fabric_s *fcs_vf;
2358 unsigned long flags;
2359
2360 spin_lock_irqsave(&bfad->bfad_lock, flags);
2361 fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id);
2362 if (fcs_vf == NULL) {
2363 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2364 iocmd->status = BFA_STATUS_UNKNOWN_VFID;
2365 goto out;
2366 }
2367 memcpy((void *)&iocmd->stats, (void *)&fcs_vf->stats,
2368 sizeof(struct bfa_vf_stats_s));
2369 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2370 iocmd->status = BFA_STATUS_OK;
2371out:
2372 return 0;
2373}
2374
2375int
2376bfad_iocmd_vf_clr_stats(struct bfad_s *bfad, void *cmd)
2377{
2378 struct bfa_bsg_vf_reset_stats_s *iocmd =
2379 (struct bfa_bsg_vf_reset_stats_s *)cmd;
2380 struct bfa_fcs_fabric_s *fcs_vf;
2381 unsigned long flags;
2382
2383 spin_lock_irqsave(&bfad->bfad_lock, flags);
2384 fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id);
2385 if (fcs_vf == NULL) {
2386 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2387 iocmd->status = BFA_STATUS_UNKNOWN_VFID;
2388 goto out;
2389 }
2390 memset((void *)&fcs_vf->stats, 0, sizeof(struct bfa_vf_stats_s));
2391 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2392 iocmd->status = BFA_STATUS_OK;
2393out:
2394 return 0;
2395}
2396
2397int
2398bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd)
2399{
2400 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
2401 unsigned long flags;
2402
2403 spin_lock_irqsave(&bfad->bfad_lock, flags);
2404 if (v_cmd == IOCMD_FCPIM_LUNMASK_ENABLE)
2405 iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_TRUE);
2406 else if (v_cmd == IOCMD_FCPIM_LUNMASK_DISABLE)
2407 iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_FALSE);
2408 else if (v_cmd == IOCMD_FCPIM_LUNMASK_CLEAR)
2409 iocmd->status = bfa_fcpim_lunmask_clear(&bfad->bfa);
2410 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2411 return 0;
2412}
2413
2414int
2415bfad_iocmd_fcpim_lunmask_query(struct bfad_s *bfad, void *cmd)
2416{
2417 struct bfa_bsg_fcpim_lunmask_query_s *iocmd =
2418 (struct bfa_bsg_fcpim_lunmask_query_s *)cmd;
2419 struct bfa_lunmask_cfg_s *lun_mask = &iocmd->lun_mask;
2420 unsigned long flags;
2421
2422 spin_lock_irqsave(&bfad->bfad_lock, flags);
2423 iocmd->status = bfa_fcpim_lunmask_query(&bfad->bfa, lun_mask);
2424 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2425 return 0;
2426}
2427
2428int
2429bfad_iocmd_fcpim_cfg_lunmask(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
2430{
2431 struct bfa_bsg_fcpim_lunmask_s *iocmd =
2432 (struct bfa_bsg_fcpim_lunmask_s *)cmd;
2433 unsigned long flags;
2434
2435 spin_lock_irqsave(&bfad->bfad_lock, flags);
2436 if (v_cmd == IOCMD_FCPIM_LUNMASK_ADD)
2437 iocmd->status = bfa_fcpim_lunmask_add(&bfad->bfa, iocmd->vf_id,
2438 &iocmd->pwwn, iocmd->rpwwn, iocmd->lun);
2439 else if (v_cmd == IOCMD_FCPIM_LUNMASK_DELETE)
2440 iocmd->status = bfa_fcpim_lunmask_delete(&bfad->bfa,
2441 iocmd->vf_id, &iocmd->pwwn,
2442 iocmd->rpwwn, iocmd->lun);
2443 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2444 return 0;
2445}
2446
1514static int 2447static int
1515bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, 2448bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
1516 unsigned int payload_len) 2449 unsigned int payload_len)
1517{ 2450{
1518 int rc = EINVAL; 2451 int rc = -EINVAL;
1519 2452
1520 switch (cmd) { 2453 switch (cmd) {
1521 case IOCMD_IOC_ENABLE: 2454 case IOCMD_IOC_ENABLE:
@@ -1536,6 +2469,14 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
1536 case IOCMD_IOC_GET_FWSTATS: 2469 case IOCMD_IOC_GET_FWSTATS:
1537 rc = bfad_iocmd_ioc_get_fwstats(bfad, iocmd, payload_len); 2470 rc = bfad_iocmd_ioc_get_fwstats(bfad, iocmd, payload_len);
1538 break; 2471 break;
2472 case IOCMD_IOC_RESET_STATS:
2473 case IOCMD_IOC_RESET_FWSTATS:
2474 rc = bfad_iocmd_ioc_reset_stats(bfad, iocmd, cmd);
2475 break;
2476 case IOCMD_IOC_SET_ADAPTER_NAME:
2477 case IOCMD_IOC_SET_PORT_NAME:
2478 rc = bfad_iocmd_ioc_set_name(bfad, iocmd, cmd);
2479 break;
1539 case IOCMD_IOCFC_GET_ATTR: 2480 case IOCMD_IOCFC_GET_ATTR:
1540 rc = bfad_iocmd_iocfc_get_attr(bfad, iocmd); 2481 rc = bfad_iocmd_iocfc_get_attr(bfad, iocmd);
1541 break; 2482 break;
@@ -1554,12 +2495,31 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
1554 case IOCMD_PORT_GET_STATS: 2495 case IOCMD_PORT_GET_STATS:
1555 rc = bfad_iocmd_port_get_stats(bfad, iocmd, payload_len); 2496 rc = bfad_iocmd_port_get_stats(bfad, iocmd, payload_len);
1556 break; 2497 break;
2498 case IOCMD_PORT_RESET_STATS:
2499 rc = bfad_iocmd_port_reset_stats(bfad, iocmd);
2500 break;
2501 case IOCMD_PORT_CFG_TOPO:
2502 case IOCMD_PORT_CFG_SPEED:
2503 case IOCMD_PORT_CFG_ALPA:
2504 case IOCMD_PORT_CLR_ALPA:
2505 rc = bfad_iocmd_set_port_cfg(bfad, iocmd, cmd);
2506 break;
2507 case IOCMD_PORT_CFG_MAXFRSZ:
2508 rc = bfad_iocmd_port_cfg_maxfrsize(bfad, iocmd);
2509 break;
2510 case IOCMD_PORT_BBSC_ENABLE:
2511 case IOCMD_PORT_BBSC_DISABLE:
2512 rc = bfad_iocmd_port_cfg_bbsc(bfad, iocmd, cmd);
2513 break;
1557 case IOCMD_LPORT_GET_ATTR: 2514 case IOCMD_LPORT_GET_ATTR:
1558 rc = bfad_iocmd_lport_get_attr(bfad, iocmd); 2515 rc = bfad_iocmd_lport_get_attr(bfad, iocmd);
1559 break; 2516 break;
1560 case IOCMD_LPORT_GET_STATS: 2517 case IOCMD_LPORT_GET_STATS:
1561 rc = bfad_iocmd_lport_get_stats(bfad, iocmd); 2518 rc = bfad_iocmd_lport_get_stats(bfad, iocmd);
1562 break; 2519 break;
2520 case IOCMD_LPORT_RESET_STATS:
2521 rc = bfad_iocmd_lport_reset_stats(bfad, iocmd);
2522 break;
1563 case IOCMD_LPORT_GET_IOSTATS: 2523 case IOCMD_LPORT_GET_IOSTATS:
1564 rc = bfad_iocmd_lport_get_iostats(bfad, iocmd); 2524 rc = bfad_iocmd_lport_get_iostats(bfad, iocmd);
1565 break; 2525 break;
@@ -1575,12 +2535,40 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
1575 case IOCMD_RPORT_GET_STATS: 2535 case IOCMD_RPORT_GET_STATS:
1576 rc = bfad_iocmd_rport_get_stats(bfad, iocmd); 2536 rc = bfad_iocmd_rport_get_stats(bfad, iocmd);
1577 break; 2537 break;
2538 case IOCMD_RPORT_RESET_STATS:
2539 rc = bfad_iocmd_rport_clr_stats(bfad, iocmd);
2540 break;
2541 case IOCMD_RPORT_SET_SPEED:
2542 rc = bfad_iocmd_rport_set_speed(bfad, iocmd);
2543 break;
2544 case IOCMD_VPORT_GET_ATTR:
2545 rc = bfad_iocmd_vport_get_attr(bfad, iocmd);
2546 break;
2547 case IOCMD_VPORT_GET_STATS:
2548 rc = bfad_iocmd_vport_get_stats(bfad, iocmd);
2549 break;
2550 case IOCMD_VPORT_RESET_STATS:
2551 rc = bfad_iocmd_vport_clr_stats(bfad, iocmd);
2552 break;
1578 case IOCMD_FABRIC_GET_LPORTS: 2553 case IOCMD_FABRIC_GET_LPORTS:
1579 rc = bfad_iocmd_fabric_get_lports(bfad, iocmd, payload_len); 2554 rc = bfad_iocmd_fabric_get_lports(bfad, iocmd, payload_len);
1580 break; 2555 break;
2556 case IOCMD_RATELIM_ENABLE:
2557 case IOCMD_RATELIM_DISABLE:
2558 rc = bfad_iocmd_ratelim(bfad, cmd, iocmd);
2559 break;
2560 case IOCMD_RATELIM_DEF_SPEED:
2561 rc = bfad_iocmd_ratelim_speed(bfad, cmd, iocmd);
2562 break;
2563 case IOCMD_FCPIM_FAILOVER:
2564 rc = bfad_iocmd_cfg_fcpim(bfad, iocmd);
2565 break;
1581 case IOCMD_FCPIM_MODSTATS: 2566 case IOCMD_FCPIM_MODSTATS:
1582 rc = bfad_iocmd_fcpim_get_modstats(bfad, iocmd); 2567 rc = bfad_iocmd_fcpim_get_modstats(bfad, iocmd);
1583 break; 2568 break;
2569 case IOCMD_FCPIM_MODSTATSCLR:
2570 rc = bfad_iocmd_fcpim_clr_modstats(bfad, iocmd);
2571 break;
1584 case IOCMD_FCPIM_DEL_ITN_STATS: 2572 case IOCMD_FCPIM_DEL_ITN_STATS:
1585 rc = bfad_iocmd_fcpim_get_del_itn_stats(bfad, iocmd); 2573 rc = bfad_iocmd_fcpim_get_del_itn_stats(bfad, iocmd);
1586 break; 2574 break;
@@ -1590,6 +2578,9 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
1590 case IOCMD_ITNIM_GET_IOSTATS: 2578 case IOCMD_ITNIM_GET_IOSTATS:
1591 rc = bfad_iocmd_itnim_get_iostats(bfad, iocmd); 2579 rc = bfad_iocmd_itnim_get_iostats(bfad, iocmd);
1592 break; 2580 break;
2581 case IOCMD_ITNIM_RESET_STATS:
2582 rc = bfad_iocmd_itnim_reset_stats(bfad, iocmd);
2583 break;
1593 case IOCMD_ITNIM_GET_ITNSTATS: 2584 case IOCMD_ITNIM_GET_ITNSTATS:
1594 rc = bfad_iocmd_itnim_get_itnstats(bfad, iocmd); 2585 rc = bfad_iocmd_itnim_get_itnstats(bfad, iocmd);
1595 break; 2586 break;
@@ -1702,11 +2693,92 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
1702 case IOCMD_DEBUG_PORTLOG: 2693 case IOCMD_DEBUG_PORTLOG:
1703 rc = bfad_iocmd_porglog_get(bfad, iocmd); 2694 rc = bfad_iocmd_porglog_get(bfad, iocmd);
1704 break; 2695 break;
2696 case IOCMD_DEBUG_FW_CORE:
2697 rc = bfad_iocmd_debug_fw_core(bfad, iocmd, payload_len);
2698 break;
2699 case IOCMD_DEBUG_FW_STATE_CLR:
2700 case IOCMD_DEBUG_PORTLOG_CLR:
2701 case IOCMD_DEBUG_START_DTRC:
2702 case IOCMD_DEBUG_STOP_DTRC:
2703 rc = bfad_iocmd_debug_ctl(bfad, iocmd, cmd);
2704 break;
2705 case IOCMD_DEBUG_PORTLOG_CTL:
2706 rc = bfad_iocmd_porglog_ctl(bfad, iocmd);
2707 break;
2708 case IOCMD_FCPIM_PROFILE_ON:
2709 case IOCMD_FCPIM_PROFILE_OFF:
2710 rc = bfad_iocmd_fcpim_cfg_profile(bfad, iocmd, cmd);
2711 break;
2712 case IOCMD_ITNIM_GET_IOPROFILE:
2713 rc = bfad_iocmd_itnim_get_ioprofile(bfad, iocmd);
2714 break;
2715 case IOCMD_FCPORT_GET_STATS:
2716 rc = bfad_iocmd_fcport_get_stats(bfad, iocmd);
2717 break;
2718 case IOCMD_FCPORT_RESET_STATS:
2719 rc = bfad_iocmd_fcport_reset_stats(bfad, iocmd);
2720 break;
2721 case IOCMD_BOOT_CFG:
2722 rc = bfad_iocmd_boot_cfg(bfad, iocmd);
2723 break;
2724 case IOCMD_BOOT_QUERY:
2725 rc = bfad_iocmd_boot_query(bfad, iocmd);
2726 break;
2727 case IOCMD_PREBOOT_QUERY:
2728 rc = bfad_iocmd_preboot_query(bfad, iocmd);
2729 break;
2730 case IOCMD_ETHBOOT_CFG:
2731 rc = bfad_iocmd_ethboot_cfg(bfad, iocmd);
2732 break;
2733 case IOCMD_ETHBOOT_QUERY:
2734 rc = bfad_iocmd_ethboot_query(bfad, iocmd);
2735 break;
2736 case IOCMD_TRUNK_ENABLE:
2737 case IOCMD_TRUNK_DISABLE:
2738 rc = bfad_iocmd_cfg_trunk(bfad, iocmd, cmd);
2739 break;
2740 case IOCMD_TRUNK_GET_ATTR:
2741 rc = bfad_iocmd_trunk_get_attr(bfad, iocmd);
2742 break;
2743 case IOCMD_QOS_ENABLE:
2744 case IOCMD_QOS_DISABLE:
2745 rc = bfad_iocmd_qos(bfad, iocmd, cmd);
2746 break;
2747 case IOCMD_QOS_GET_ATTR:
2748 rc = bfad_iocmd_qos_get_attr(bfad, iocmd);
2749 break;
2750 case IOCMD_QOS_GET_VC_ATTR:
2751 rc = bfad_iocmd_qos_get_vc_attr(bfad, iocmd);
2752 break;
2753 case IOCMD_QOS_GET_STATS:
2754 rc = bfad_iocmd_qos_get_stats(bfad, iocmd);
2755 break;
2756 case IOCMD_QOS_RESET_STATS:
2757 rc = bfad_iocmd_qos_reset_stats(bfad, iocmd);
2758 break;
2759 case IOCMD_VF_GET_STATS:
2760 rc = bfad_iocmd_vf_get_stats(bfad, iocmd);
2761 break;
2762 case IOCMD_VF_RESET_STATS:
2763 rc = bfad_iocmd_vf_clr_stats(bfad, iocmd);
2764 break;
2765 case IOCMD_FCPIM_LUNMASK_ENABLE:
2766 case IOCMD_FCPIM_LUNMASK_DISABLE:
2767 case IOCMD_FCPIM_LUNMASK_CLEAR:
2768 rc = bfad_iocmd_lunmask(bfad, iocmd, cmd);
2769 break;
2770 case IOCMD_FCPIM_LUNMASK_QUERY:
2771 rc = bfad_iocmd_fcpim_lunmask_query(bfad, iocmd);
2772 break;
2773 case IOCMD_FCPIM_LUNMASK_ADD:
2774 case IOCMD_FCPIM_LUNMASK_DELETE:
2775 rc = bfad_iocmd_fcpim_cfg_lunmask(bfad, iocmd, cmd);
2776 break;
1705 default: 2777 default:
1706 rc = EINVAL; 2778 rc = -EINVAL;
1707 break; 2779 break;
1708 } 2780 }
1709 return -rc; 2781 return rc;
1710} 2782}
1711 2783
1712static int 2784static int
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h
index 99b0e8a70c89..e859adb9aa9e 100644
--- a/drivers/scsi/bfa/bfad_bsg.h
+++ b/drivers/scsi/bfa/bfad_bsg.h
@@ -30,24 +30,48 @@ enum {
30 IOCMD_IOC_GET_INFO, 30 IOCMD_IOC_GET_INFO,
31 IOCMD_IOC_GET_STATS, 31 IOCMD_IOC_GET_STATS,
32 IOCMD_IOC_GET_FWSTATS, 32 IOCMD_IOC_GET_FWSTATS,
33 IOCMD_IOC_RESET_STATS,
34 IOCMD_IOC_RESET_FWSTATS,
35 IOCMD_IOC_SET_ADAPTER_NAME,
36 IOCMD_IOC_SET_PORT_NAME,
33 IOCMD_IOCFC_GET_ATTR, 37 IOCMD_IOCFC_GET_ATTR,
34 IOCMD_IOCFC_SET_INTR, 38 IOCMD_IOCFC_SET_INTR,
35 IOCMD_PORT_ENABLE, 39 IOCMD_PORT_ENABLE,
36 IOCMD_PORT_DISABLE, 40 IOCMD_PORT_DISABLE,
37 IOCMD_PORT_GET_ATTR, 41 IOCMD_PORT_GET_ATTR,
38 IOCMD_PORT_GET_STATS, 42 IOCMD_PORT_GET_STATS,
43 IOCMD_PORT_RESET_STATS,
44 IOCMD_PORT_CFG_TOPO,
45 IOCMD_PORT_CFG_SPEED,
46 IOCMD_PORT_CFG_ALPA,
47 IOCMD_PORT_CFG_MAXFRSZ,
48 IOCMD_PORT_CLR_ALPA,
49 IOCMD_PORT_BBSC_ENABLE,
50 IOCMD_PORT_BBSC_DISABLE,
39 IOCMD_LPORT_GET_ATTR, 51 IOCMD_LPORT_GET_ATTR,
40 IOCMD_LPORT_GET_RPORTS, 52 IOCMD_LPORT_GET_RPORTS,
41 IOCMD_LPORT_GET_STATS, 53 IOCMD_LPORT_GET_STATS,
54 IOCMD_LPORT_RESET_STATS,
42 IOCMD_LPORT_GET_IOSTATS, 55 IOCMD_LPORT_GET_IOSTATS,
43 IOCMD_RPORT_GET_ATTR, 56 IOCMD_RPORT_GET_ATTR,
44 IOCMD_RPORT_GET_ADDR, 57 IOCMD_RPORT_GET_ADDR,
45 IOCMD_RPORT_GET_STATS, 58 IOCMD_RPORT_GET_STATS,
59 IOCMD_RPORT_RESET_STATS,
60 IOCMD_RPORT_SET_SPEED,
61 IOCMD_VPORT_GET_ATTR,
62 IOCMD_VPORT_GET_STATS,
63 IOCMD_VPORT_RESET_STATS,
46 IOCMD_FABRIC_GET_LPORTS, 64 IOCMD_FABRIC_GET_LPORTS,
65 IOCMD_RATELIM_ENABLE,
66 IOCMD_RATELIM_DISABLE,
67 IOCMD_RATELIM_DEF_SPEED,
68 IOCMD_FCPIM_FAILOVER,
47 IOCMD_FCPIM_MODSTATS, 69 IOCMD_FCPIM_MODSTATS,
70 IOCMD_FCPIM_MODSTATSCLR,
48 IOCMD_FCPIM_DEL_ITN_STATS, 71 IOCMD_FCPIM_DEL_ITN_STATS,
49 IOCMD_ITNIM_GET_ATTR, 72 IOCMD_ITNIM_GET_ATTR,
50 IOCMD_ITNIM_GET_IOSTATS, 73 IOCMD_ITNIM_GET_IOSTATS,
74 IOCMD_ITNIM_RESET_STATS,
51 IOCMD_ITNIM_GET_ITNSTATS, 75 IOCMD_ITNIM_GET_ITNSTATS,
52 IOCMD_IOC_PCIFN_CFG, 76 IOCMD_IOC_PCIFN_CFG,
53 IOCMD_FCPORT_ENABLE, 77 IOCMD_FCPORT_ENABLE,
@@ -86,6 +110,39 @@ enum {
86 IOCMD_PHY_READ_FW, 110 IOCMD_PHY_READ_FW,
87 IOCMD_VHBA_QUERY, 111 IOCMD_VHBA_QUERY,
88 IOCMD_DEBUG_PORTLOG, 112 IOCMD_DEBUG_PORTLOG,
113 IOCMD_DEBUG_FW_CORE,
114 IOCMD_DEBUG_FW_STATE_CLR,
115 IOCMD_DEBUG_PORTLOG_CLR,
116 IOCMD_DEBUG_START_DTRC,
117 IOCMD_DEBUG_STOP_DTRC,
118 IOCMD_DEBUG_PORTLOG_CTL,
119 IOCMD_FCPIM_PROFILE_ON,
120 IOCMD_FCPIM_PROFILE_OFF,
121 IOCMD_ITNIM_GET_IOPROFILE,
122 IOCMD_FCPORT_GET_STATS,
123 IOCMD_FCPORT_RESET_STATS,
124 IOCMD_BOOT_CFG,
125 IOCMD_BOOT_QUERY,
126 IOCMD_PREBOOT_QUERY,
127 IOCMD_ETHBOOT_CFG,
128 IOCMD_ETHBOOT_QUERY,
129 IOCMD_TRUNK_ENABLE,
130 IOCMD_TRUNK_DISABLE,
131 IOCMD_TRUNK_GET_ATTR,
132 IOCMD_QOS_ENABLE,
133 IOCMD_QOS_DISABLE,
134 IOCMD_QOS_GET_ATTR,
135 IOCMD_QOS_GET_VC_ATTR,
136 IOCMD_QOS_GET_STATS,
137 IOCMD_QOS_RESET_STATS,
138 IOCMD_VF_GET_STATS,
139 IOCMD_VF_RESET_STATS,
140 IOCMD_FCPIM_LUNMASK_ENABLE,
141 IOCMD_FCPIM_LUNMASK_DISABLE,
142 IOCMD_FCPIM_LUNMASK_CLEAR,
143 IOCMD_FCPIM_LUNMASK_QUERY,
144 IOCMD_FCPIM_LUNMASK_ADD,
145 IOCMD_FCPIM_LUNMASK_DELETE,
89}; 146};
90 147
91struct bfa_bsg_gen_s { 148struct bfa_bsg_gen_s {
@@ -94,6 +151,43 @@ struct bfa_bsg_gen_s {
94 u16 rsvd; 151 u16 rsvd;
95}; 152};
96 153
154struct bfa_bsg_portlogctl_s {
155 bfa_status_t status;
156 u16 bfad_num;
157 u16 rsvd;
158 bfa_boolean_t ctl;
159 int inst_no;
160};
161
162struct bfa_bsg_fcpim_profile_s {
163 bfa_status_t status;
164 u16 bfad_num;
165 u16 rsvd;
166};
167
168struct bfa_bsg_itnim_ioprofile_s {
169 bfa_status_t status;
170 u16 bfad_num;
171 u16 vf_id;
172 wwn_t lpwwn;
173 wwn_t rpwwn;
174 struct bfa_itnim_ioprofile_s ioprofile;
175};
176
177struct bfa_bsg_fcport_stats_s {
178 bfa_status_t status;
179 u16 bfad_num;
180 u16 rsvd;
181 union bfa_fcport_stats_u stats;
182};
183
184struct bfa_bsg_ioc_name_s {
185 bfa_status_t status;
186 u16 bfad_num;
187 u16 rsvd;
188 char name[BFA_ADAPTER_SYM_NAME_LEN];
189};
190
97struct bfa_bsg_ioc_info_s { 191struct bfa_bsg_ioc_info_s {
98 bfa_status_t status; 192 bfa_status_t status;
99 u16 bfad_num; 193 u16 bfad_num;
@@ -164,6 +258,20 @@ struct bfa_bsg_port_attr_s {
164 struct bfa_port_attr_s attr; 258 struct bfa_port_attr_s attr;
165}; 259};
166 260
261struct bfa_bsg_port_cfg_s {
262 bfa_status_t status;
263 u16 bfad_num;
264 u16 rsvd;
265 u32 param;
266 u32 rsvd1;
267};
268
269struct bfa_bsg_port_cfg_maxfrsize_s {
270 bfa_status_t status;
271 u16 bfad_num;
272 u16 maxfrsize;
273};
274
167struct bfa_bsg_port_stats_s { 275struct bfa_bsg_port_stats_s {
168 bfa_status_t status; 276 bfa_status_t status;
169 u16 bfad_num; 277 u16 bfad_num;
@@ -237,6 +345,47 @@ struct bfa_bsg_rport_scsi_addr_s {
237 u32 lun; 345 u32 lun;
238}; 346};
239 347
348struct bfa_bsg_rport_reset_stats_s {
349 bfa_status_t status;
350 u16 bfad_num;
351 u16 vf_id;
352 wwn_t pwwn;
353 wwn_t rpwwn;
354};
355
356struct bfa_bsg_rport_set_speed_s {
357 bfa_status_t status;
358 u16 bfad_num;
359 u16 vf_id;
360 enum bfa_port_speed speed;
361 u32 rsvd;
362 wwn_t pwwn;
363 wwn_t rpwwn;
364};
365
366struct bfa_bsg_vport_attr_s {
367 bfa_status_t status;
368 u16 bfad_num;
369 u16 vf_id;
370 wwn_t vpwwn;
371 struct bfa_vport_attr_s vport_attr;
372};
373
374struct bfa_bsg_vport_stats_s {
375 bfa_status_t status;
376 u16 bfad_num;
377 u16 vf_id;
378 wwn_t vpwwn;
379 struct bfa_vport_stats_s vport_stats;
380};
381
382struct bfa_bsg_reset_stats_s {
383 bfa_status_t status;
384 u16 bfad_num;
385 u16 vf_id;
386 wwn_t vpwwn;
387};
388
240struct bfa_bsg_fabric_get_lports_s { 389struct bfa_bsg_fabric_get_lports_s {
241 bfa_status_t status; 390 bfa_status_t status;
242 u16 bfad_num; 391 u16 bfad_num;
@@ -246,6 +395,19 @@ struct bfa_bsg_fabric_get_lports_s {
246 u32 rsvd; 395 u32 rsvd;
247}; 396};
248 397
398struct bfa_bsg_trl_speed_s {
399 bfa_status_t status;
400 u16 bfad_num;
401 u16 rsvd;
402 enum bfa_port_speed speed;
403};
404
405struct bfa_bsg_fcpim_s {
406 bfa_status_t status;
407 u16 bfad_num;
408 u16 param;
409};
410
249struct bfa_bsg_fcpim_modstats_s { 411struct bfa_bsg_fcpim_modstats_s {
250 bfa_status_t status; 412 bfa_status_t status;
251 u16 bfad_num; 413 u16 bfad_num;
@@ -258,6 +420,11 @@ struct bfa_bsg_fcpim_del_itn_stats_s {
258 struct bfa_fcpim_del_itn_stats_s modstats; 420 struct bfa_fcpim_del_itn_stats_s modstats;
259}; 421};
260 422
423struct bfa_bsg_fcpim_modstatsclr_s {
424 bfa_status_t status;
425 u16 bfad_num;
426};
427
261struct bfa_bsg_itnim_attr_s { 428struct bfa_bsg_itnim_attr_s {
262 bfa_status_t status; 429 bfa_status_t status;
263 u16 bfad_num; 430 u16 bfad_num;
@@ -485,6 +652,76 @@ struct bfa_bsg_vhba_attr_s {
485 struct bfa_vhba_attr_s attr; 652 struct bfa_vhba_attr_s attr;
486}; 653};
487 654
655struct bfa_bsg_boot_s {
656 bfa_status_t status;
657 u16 bfad_num;
658 u16 rsvd;
659 struct bfa_boot_cfg_s cfg;
660};
661
662struct bfa_bsg_preboot_s {
663 bfa_status_t status;
664 u16 bfad_num;
665 u16 rsvd;
666 struct bfa_boot_pbc_s cfg;
667};
668
669struct bfa_bsg_ethboot_s {
670 bfa_status_t status;
671 u16 bfad_num;
672 u16 rsvd;
673 struct bfa_ethboot_cfg_s cfg;
674};
675
676struct bfa_bsg_trunk_attr_s {
677 bfa_status_t status;
678 u16 bfad_num;
679 u16 rsvd;
680 struct bfa_trunk_attr_s attr;
681};
682
683struct bfa_bsg_qos_attr_s {
684 bfa_status_t status;
685 u16 bfad_num;
686 u16 rsvd;
687 struct bfa_qos_attr_s attr;
688};
689
690struct bfa_bsg_qos_vc_attr_s {
691 bfa_status_t status;
692 u16 bfad_num;
693 u16 rsvd;
694 struct bfa_qos_vc_attr_s attr;
695};
696
697struct bfa_bsg_vf_stats_s {
698 bfa_status_t status;
699 u16 bfad_num;
700 u16 vf_id;
701 struct bfa_vf_stats_s stats;
702};
703
704struct bfa_bsg_vf_reset_stats_s {
705 bfa_status_t status;
706 u16 bfad_num;
707 u16 vf_id;
708};
709
710struct bfa_bsg_fcpim_lunmask_query_s {
711 bfa_status_t status;
712 u16 bfad_num;
713 struct bfa_lunmask_cfg_s lun_mask;
714};
715
716struct bfa_bsg_fcpim_lunmask_s {
717 bfa_status_t status;
718 u16 bfad_num;
719 u16 vf_id;
720 wwn_t pwwn;
721 wwn_t rpwwn;
722 struct scsi_lun lun;
723};
724
488struct bfa_bsg_fcpt_s { 725struct bfa_bsg_fcpt_s {
489 bfa_status_t status; 726 bfa_status_t status;
490 u16 vf_id; 727 u16 vf_id;
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h
index 2f585f4159e1..5e19a5f820ec 100644
--- a/drivers/scsi/bfa/bfad_drv.h
+++ b/drivers/scsi/bfa/bfad_drv.h
@@ -55,7 +55,7 @@
55#ifdef BFA_DRIVER_VERSION 55#ifdef BFA_DRIVER_VERSION
56#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION 56#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION
57#else 57#else
58#define BFAD_DRIVER_VERSION "3.0.2.1" 58#define BFAD_DRIVER_VERSION "3.0.2.2"
59#endif 59#endif
60 60
61#define BFAD_PROTO_NAME FCPI_NAME 61#define BFAD_PROTO_NAME FCPI_NAME
@@ -223,6 +223,10 @@ struct bfad_s {
223 char *regdata; 223 char *regdata;
224 u32 reglen; 224 u32 reglen;
225 struct dentry *bfad_dentry_files[5]; 225 struct dentry *bfad_dentry_files[5];
226 struct list_head free_aen_q;
227 struct list_head active_aen_q;
228 struct bfa_aen_entry_s aen_list[BFA_AEN_MAX_ENTRY];
229 spinlock_t bfad_aen_spinlock;
226}; 230};
227 231
228/* BFAD state machine events */ 232/* BFAD state machine events */
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index f2bf81265ae5..01312381639f 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -656,6 +656,31 @@ bfad_im_port_clean(struct bfad_im_port_s *im_port)
656 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 656 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
657} 657}
658 658
659static void bfad_aen_im_notify_handler(struct work_struct *work)
660{
661 struct bfad_im_s *im =
662 container_of(work, struct bfad_im_s, aen_im_notify_work);
663 struct bfa_aen_entry_s *aen_entry;
664 struct bfad_s *bfad = im->bfad;
665 struct Scsi_Host *shost = bfad->pport.im_port->shost;
666 void *event_data;
667 unsigned long flags;
668
669 while (!list_empty(&bfad->active_aen_q)) {
670 spin_lock_irqsave(&bfad->bfad_aen_spinlock, flags);
671 bfa_q_deq(&bfad->active_aen_q, &aen_entry);
672 spin_unlock_irqrestore(&bfad->bfad_aen_spinlock, flags);
673 event_data = (char *)aen_entry + sizeof(struct list_head);
674 fc_host_post_vendor_event(shost, fc_get_event_number(),
675 sizeof(struct bfa_aen_entry_s) -
676 sizeof(struct list_head),
677 (char *)event_data, BFAD_NL_VENDOR_ID);
678 spin_lock_irqsave(&bfad->bfad_aen_spinlock, flags);
679 list_add_tail(&aen_entry->qe, &bfad->free_aen_q);
680 spin_unlock_irqrestore(&bfad->bfad_aen_spinlock, flags);
681 }
682}
683
659bfa_status_t 684bfa_status_t
660bfad_im_probe(struct bfad_s *bfad) 685bfad_im_probe(struct bfad_s *bfad)
661{ 686{
@@ -676,6 +701,7 @@ bfad_im_probe(struct bfad_s *bfad)
676 rc = BFA_STATUS_FAILED; 701 rc = BFA_STATUS_FAILED;
677 } 702 }
678 703
704 INIT_WORK(&im->aen_im_notify_work, bfad_aen_im_notify_handler);
679ext: 705ext:
680 return rc; 706 return rc;
681} 707}
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
index 4fe34d576b05..004b6cf848d9 100644
--- a/drivers/scsi/bfa/bfad_im.h
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -115,8 +115,30 @@ struct bfad_im_s {
115 struct bfad_s *bfad; 115 struct bfad_s *bfad;
116 struct workqueue_struct *drv_workq; 116 struct workqueue_struct *drv_workq;
117 char drv_workq_name[KOBJ_NAME_LEN]; 117 char drv_workq_name[KOBJ_NAME_LEN];
118 struct work_struct aen_im_notify_work;
118}; 119};
119 120
121#define bfad_get_aen_entry(_drv, _entry) do { \
122 unsigned long _flags; \
123 spin_lock_irqsave(&(_drv)->bfad_aen_spinlock, _flags); \
124 bfa_q_deq(&(_drv)->free_aen_q, &(_entry)); \
125 if (_entry) \
126 list_add_tail(&(_entry)->qe, &(_drv)->active_aen_q); \
127 spin_unlock_irqrestore(&(_drv)->bfad_aen_spinlock, _flags); \
128} while (0)
129
130/* post fc_host vendor event */
131#define bfad_im_post_vendor_event(_entry, _drv, _cnt, _cat, _evt) do { \
132 do_gettimeofday(&(_entry)->aen_tv); \
133 (_entry)->bfad_num = (_drv)->inst_no; \
134 (_entry)->seq_num = (_cnt); \
135 (_entry)->aen_category = (_cat); \
136 (_entry)->aen_type = (_evt); \
137 if ((_drv)->bfad_flags & BFAD_FC4_PROBE_DONE) \
138 queue_work((_drv)->im->drv_workq, \
139 &(_drv)->im->aen_im_notify_work); \
140} while (0)
141
120struct Scsi_Host *bfad_scsi_host_alloc(struct bfad_im_port_s *im_port, 142struct Scsi_Host *bfad_scsi_host_alloc(struct bfad_im_port_s *im_port,
121 struct bfad_s *); 143 struct bfad_s *);
122bfa_status_t bfad_thread_workq(struct bfad_s *bfad); 144bfa_status_t bfad_thread_workq(struct bfad_s *bfad);
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h
index 1e258d5f8aec..b2ba0b2e91b2 100644
--- a/drivers/scsi/bfa/bfi.h
+++ b/drivers/scsi/bfa/bfi.h
@@ -784,6 +784,17 @@ enum bfi_sfp_i2h_e {
784}; 784};
785 785
786/* 786/*
787 * SFP state change notification
788 */
789struct bfi_sfp_scn_s {
790 struct bfi_mhdr_s mhr; /* host msg header */
791 u8 event;
792 u8 sfpid;
793 u8 pomlvl; /* pom level: normal/warning/alarm */
794 u8 is_elb; /* e-loopback */
795};
796
797/*
787 * SFP state 798 * SFP state
788 */ 799 */
789enum bfa_sfp_stat_e { 800enum bfa_sfp_stat_e {
@@ -926,6 +937,15 @@ struct bfi_flash_erase_rsp_s {
926}; 937};
927 938
928/* 939/*
940 * Flash event notification
941 */
942struct bfi_flash_event_s {
943 struct bfi_mhdr_s mh; /* Common msg header */
944 bfa_status_t status;
945 u32 param;
946};
947
948/*
929 *---------------------------------------------------------------------- 949 *----------------------------------------------------------------------
930 * DIAG 950 * DIAG
931 *---------------------------------------------------------------------- 951 *----------------------------------------------------------------------