diff options
author | Jiri Kosina <jkosina@suse.cz> | 2011-09-15 09:08:05 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-09-15 09:08:18 -0400 |
commit | e060c38434b2caa78efe7cedaff4191040b65a15 (patch) | |
tree | 407361230bf6733f63d8e788e4b5e6566ee04818 /drivers/scsi/bfa | |
parent | 10e4ac572eeffe5317019bd7330b6058a400dfc2 (diff) | |
parent | cc39c6a9bbdebfcf1a7dee64d83bf302bc38d941 (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')
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 @@ | |||
27 | struct bfa_s; | 27 | struct bfa_s; |
28 | 28 | ||
29 | typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m); | 29 | typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m); |
30 | typedef 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 { | |||
177 | struct bfa_hwif_s { | 184 | struct 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); | |||
311 | void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); | 316 | void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); |
312 | 317 | ||
313 | void bfa_hwcb_reginit(struct bfa_s *bfa); | 318 | void bfa_hwcb_reginit(struct bfa_s *bfa); |
314 | void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); | 319 | void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci); |
315 | void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); | 320 | void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); |
316 | void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa); | 321 | void bfa_hwcb_msix_ctrl_install(struct bfa_s *bfa); |
317 | void bfa_hwcb_msix_queue_install(struct bfa_s *bfa); | 322 | void bfa_hwcb_msix_queue_install(struct bfa_s *bfa); |
@@ -324,7 +329,8 @@ void bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start, | |||
324 | void bfa_hwct_reginit(struct bfa_s *bfa); | 329 | void bfa_hwct_reginit(struct bfa_s *bfa); |
325 | void bfa_hwct2_reginit(struct bfa_s *bfa); | 330 | void bfa_hwct2_reginit(struct bfa_s *bfa); |
326 | void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq); | 331 | void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq); |
327 | void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); | 332 | void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci); |
333 | void bfa_hwct2_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci); | ||
328 | void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); | 334 | void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); |
329 | void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa); | 335 | void bfa_hwct_msix_ctrl_install(struct bfa_s *bfa); |
330 | void bfa_hwct_msix_queue_install(struct bfa_s *bfa); | 336 | void 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 | |||
379 | void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids); | 401 | void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids); |
380 | void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg); | 402 | void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg); |
381 | void bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg); | 403 | void bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg); |
@@ -406,7 +428,22 @@ bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa, | |||
406 | 428 | ||
407 | void bfa_iocfc_enable(struct bfa_s *bfa); | 429 | void bfa_iocfc_enable(struct bfa_s *bfa); |
408 | void bfa_iocfc_disable(struct bfa_s *bfa); | 430 | void bfa_iocfc_disable(struct bfa_s *bfa); |
431 | void 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 | ||
435 | struct 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 | ||
1213 | void | 1212 | void |
@@ -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 | ||
1570 | void | ||
1571 | bfa_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 | */ | ||
371 | enum 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 */ | ||
382 | enum 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 | |||
387 | struct 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 */ | ||
394 | enum 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 | |||
412 | enum 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 | |||
419 | struct 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 */ | ||
430 | enum 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 | |||
445 | struct 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 */ | ||
454 | enum 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 | |||
460 | struct 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 */ | ||
469 | enum 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 | |||
476 | struct bfa_audit_aen_data_s { | ||
477 | wwn_t pwwn; | ||
478 | int partition_inst; | ||
479 | int partition_type; | ||
480 | }; | ||
481 | |||
482 | /* BFA IOC level events */ | ||
483 | enum 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 | |||
495 | struct 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 | */ |
663 | struct 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 | |||
523 | struct bfa_boot_pbc_s { | 677 | struct 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 | ||
686 | struct 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 | |||
590 | enum bfa_defs_sfp_media_e { | 761 | enum 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 | ||
273 | struct bfa_fw_port_physm_stats_s { | 274 | struct bfa_fw_port_physm_stats_s { |
@@ -468,6 +469,7 @@ struct bfa_fw_stats_s { | |||
468 | * QoS states | 469 | * QoS states |
469 | */ | 470 | */ |
470 | enum bfa_qos_state { | 471 | enum 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 | */ | ||
805 | enum 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 | |||
811 | enum 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 | */ | ||
822 | struct 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 | ||
834 | struct 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 | */ |
792 | struct bfa_port_cfg_s { | 843 | struct 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 */ | ||
1289 | enum 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 | |||
1297 | struct 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 | |||
1308 | union 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 | |||
1320 | struct 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 | |||
80 | struct 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 | |||
86 | struct scsi_inquiry_vendor_s { | ||
87 | u8 vendor_id[8]; | ||
88 | }; | ||
89 | |||
90 | struct scsi_inquiry_prodid_s { | ||
91 | u8 product_id[16]; | ||
92 | }; | ||
93 | |||
94 | struct scsi_inquiry_prodrev_s { | ||
95 | u8 product_rev[4]; | ||
96 | }; | ||
97 | |||
98 | struct 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 | */ | ||
170 | struct 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 | */ |
26 | static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim); | 26 | static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim); |
27 | static bfa_boolean_t bfa_ioim_lm_proc_rpl_data(struct bfa_ioim_s *ioim); | ||
28 | static bfa_boolean_t bfa_ioim_lm_proc_inq_data(struct bfa_ioim_s *ioim); | ||
29 | static 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 | ||
80 | enum 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 | |||
87 | enum 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); | |||
219 | static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete); | 245 | static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete); |
220 | static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete); | 246 | static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete); |
221 | static bfa_boolean_t bfa_ioim_is_abortable(struct bfa_ioim_s *ioim); | 247 | static bfa_boolean_t bfa_ioim_is_abortable(struct bfa_ioim_s *ioim); |
248 | static void __bfa_cb_ioim_lm_lun_not_sup(void *cbarg, bfa_boolean_t complete); | ||
249 | static void __bfa_cb_ioim_lm_rpl_dc(void *cbarg, bfa_boolean_t complete); | ||
250 | static 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 | ||
421 | bfa_status_t | 456 | bfa_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 | ||
475 | void | ||
476 | bfa_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 | |||
492 | void | ||
493 | bfa_ioim_profile_start(struct bfa_ioim_s *ioim) | ||
494 | { | ||
495 | ioim->start_time = jiffies; | ||
496 | } | ||
497 | |||
498 | bfa_status_t | ||
499 | bfa_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 | |||
517 | bfa_status_t | ||
518 | bfa_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 | |||
440 | u16 | 528 | u16 |
441 | bfa_fcpim_qdepth_get(struct bfa_s *bfa) | 529 | bfa_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 | ||
1494 | bfa_status_t | ||
1495 | bfa_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 | |||
1404 | void | 1512 | void |
1405 | bfa_itnim_clear_stats(struct bfa_itnim_s *itnim) | 1513 | bfa_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 | */ | ||
2146 | static void | ||
2147 | bfa_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 | */ | ||
2166 | static enum bfa_ioim_lm_status | ||
2167 | bfa_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 | |||
2222 | static bfa_boolean_t | ||
2223 | bfa_ioim_lm_proc_rsp_data_dummy(struct bfa_ioim_s *ioim) | ||
2224 | { | ||
2225 | return BFA_TRUE; | ||
2226 | } | ||
2227 | |||
2228 | static void | ||
2229 | bfa_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 | |||
2254 | static int | ||
2255 | bfa_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 | |||
2338 | static bfa_boolean_t | ||
2339 | bfa_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 | |||
2352 | static bfa_boolean_t | ||
2353 | bfa_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 | ||
2013 | static void | 2400 | static 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 | ||
2070 | static void | 2457 | static 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 | |||
2482 | static 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 | |||
2508 | static 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 | |||
2534 | void | ||
2535 | bfa_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 | */ | ||
2559 | static void | ||
2560 | bfa_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 | |||
2573 | bfa_status_t | ||
2574 | bfa_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 | |||
2594 | bfa_status_t | ||
2595 | bfa_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 | |||
2617 | bfa_status_t | ||
2618 | bfa_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 | |||
2631 | bfa_status_t | ||
2632 | bfa_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 | |||
2692 | bfa_status_t | ||
2693 | bfa_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 | |||
2750 | static 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) | |||
2668 | void | 3364 | void |
2669 | bfa_ioim_start(struct bfa_ioim_s *ioim) | 3365 | bfa_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) | |||
3411 | static void | 4136 | static void |
3412 | bfa_fcp_start(struct bfa_s *bfa) | 4137 | bfa_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 | ||
3416 | static void | 4148 | static 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; | |||
102 | struct bfad_tskim_s; | 110 | struct bfad_tskim_s; |
103 | 111 | ||
104 | typedef void (*bfa_fcpim_profile_t) (struct bfa_ioim_s *ioim); | 112 | typedef void (*bfa_fcpim_profile_t) (struct bfa_ioim_s *ioim); |
113 | typedef bfa_boolean_t (*bfa_ioim_lm_proc_rsp_data_t) (struct bfa_ioim_s *ioim); | ||
105 | 114 | ||
106 | struct bfa_fcpim_s { | 115 | struct 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 | ||
176 | struct bfa_ioim_sp_s { | 187 | struct 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 | |||
253 | static inline bfa_boolean_t | 268 | static inline bfa_boolean_t |
254 | bfa_ioim_maxretry_reached(struct bfa_ioim_s *ioim) | 269 | bfa_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); |
298 | void bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *fcpim_stats, | 313 | void 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); |
315 | bfa_status_t bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time); | ||
316 | bfa_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, | |||
397 | void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk, | 414 | void 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 | ||
417 | void bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn, | ||
418 | wwn_t rp_wwn, u16 rp_tag, u8 lp_tag); | ||
419 | bfa_status_t bfa_fcpim_lunmask_update(struct bfa_s *bfa, u32 on_off); | ||
420 | bfa_status_t bfa_fcpim_lunmask_query(struct bfa_s *bfa, void *buf); | ||
421 | bfa_status_t bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id, | ||
422 | wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun); | ||
423 | bfa_status_t bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id, | ||
424 | wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun); | ||
425 | bfa_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 | */ | ||
1335 | static void | ||
1336 | bfa_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); |
40 | static 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 | ||
384 | static void | 390 | static void |
391 | bfa_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 | |||
417 | static void | ||
385 | bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced) | 418 | bfa_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 | */ | ||
306 | static void | ||
307 | bfa_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 | */ |
305 | static void | 331 | static 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 | */ | ||
5596 | static void | ||
5597 | bfa_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 | */ |
5564 | static void | 5621 | static 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 | ||
2043 | static void | 2044 | static void |
2045 | bfa_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 | |||
2073 | static void | ||
2044 | bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport) | 2074 | bfa_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 | ||
2072 | static void | 2104 | static 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 | */ | ||
45 | static void | 52 | static void |
46 | bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq) | 53 | bfa_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 | |||
66 | void | ||
67 | bfa_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 | ||
52 | void | 77 | void |
@@ -149,8 +174,13 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa) | |||
149 | void | 174 | void |
150 | bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) | 175 | bfa_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 | ||
156 | void | 186 | void |
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 | */ | ||
67 | void | 73 | void |
68 | bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) | 74 | bfa_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 | */ | ||
91 | void | ||
92 | bfa_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 | ||
76 | void | 99 | void |
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 | ||
463 | static void | 465 | static 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 | ||
1985 | bfa_status_t | 1990 | bfa_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 | */ | ||
2689 | void | ||
2690 | bfa_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 | */ |
2684 | bfa_status_t | 2726 | bfa_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 | */ | ||
3494 | static void | ||
3495 | bfa_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 | */ |
3448 | static void | 3542 | static 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 | */ | ||
3581 | static void | ||
3582 | bfa_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 | */ |
3487 | static void | 3625 | static 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 | ||
3840 | static void | 3978 | static void |
3979 | bfa_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 | |||
3998 | static void | ||
3841 | bfa_flash_cb(struct bfa_flash_s *flash) | 3999 | bfa_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 | |||
5596 | BFA_MODULE(dconf); | ||
5597 | |||
5598 | /* | ||
5599 | * DCONF state machine events | ||
5600 | */ | ||
5601 | enum 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 */ | ||
5611 | static void bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, | ||
5612 | enum bfa_dconf_event event); | ||
5613 | static void bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf, | ||
5614 | enum bfa_dconf_event event); | ||
5615 | static void bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, | ||
5616 | enum bfa_dconf_event event); | ||
5617 | static void bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf, | ||
5618 | enum bfa_dconf_event event); | ||
5619 | static void bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf, | ||
5620 | enum bfa_dconf_event event); | ||
5621 | static void bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf, | ||
5622 | enum bfa_dconf_event event); | ||
5623 | static void bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf, | ||
5624 | enum bfa_dconf_event event); | ||
5625 | |||
5626 | static void bfa_dconf_cbfn(void *dconf, bfa_status_t status); | ||
5627 | static void bfa_dconf_timer(void *cbarg); | ||
5628 | static bfa_status_t bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf); | ||
5629 | static 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 | */ | ||
5634 | static void | ||
5635 | bfa_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 | */ | ||
5674 | static void | ||
5675 | bfa_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 | */ | ||
5701 | static void | ||
5702 | bfa_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 | |||
5729 | static void | ||
5730 | bfa_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 | */ | ||
5765 | static void | ||
5766 | bfa_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 | |||
5786 | static void | ||
5787 | bfa_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 | |||
5813 | static void | ||
5814 | bfa_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 | */ | ||
5839 | static void | ||
5840 | bfa_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 | |||
5853 | static void | ||
5854 | bfa_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 | |||
5882 | static void | ||
5883 | bfa_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 | |||
5901 | void | ||
5902 | bfa_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 | } | ||
5907 | static void | ||
5908 | bfa_dconf_start(struct bfa_s *bfa) | ||
5909 | { | ||
5910 | } | ||
5911 | |||
5912 | static void | ||
5913 | bfa_dconf_stop(struct bfa_s *bfa) | ||
5914 | { | ||
5915 | } | ||
5916 | |||
5917 | static 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 | } | ||
5922 | static void | ||
5923 | bfa_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 | |||
5929 | static void | ||
5930 | bfa_dconf_detach(struct bfa_s *bfa) | ||
5931 | { | ||
5932 | } | ||
5933 | |||
5934 | static bfa_status_t | ||
5935 | bfa_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 | |||
5951 | bfa_status_t | ||
5952 | bfa_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 | |||
5968 | static void | ||
5969 | bfa_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 | |||
5976 | void | ||
5977 | bfa_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 | ||
332 | struct bfa_ioc_hwif_s { | 333 | struct 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, | |||
684 | void bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg); | 686 | void 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) | ||
695 | struct bfa_dconf_hdr_s { | ||
696 | u32 signature; | ||
697 | u32 version; | ||
698 | }; | ||
699 | |||
700 | struct bfa_dconf_s { | ||
701 | struct bfa_dconf_hdr_s hdr; | ||
702 | struct bfa_lunmask_cfg_s lun_mask; | ||
703 | }; | ||
704 | #pragma pack() | ||
705 | |||
706 | struct 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 | |||
727 | void bfa_dconf_modinit(struct bfa_s *bfa); | ||
728 | void bfa_dconf_modexit(struct bfa_s *bfa); | ||
729 | bfa_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); |
804 | bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, | 849 | bfa_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); |
851 | void bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event); | ||
806 | bfa_status_t bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats); | 852 | bfa_status_t bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats); |
807 | bfa_status_t bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc); | 853 | bfa_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 | ||
124 | extern bfa_boolean_t bfa_auto_recover; | 126 | extern bfa_boolean_t bfa_auto_recover; |
@@ -130,5 +132,6 @@ extern struct bfa_module_s hal_mod_lps; | |||
130 | extern struct bfa_module_s hal_mod_uf; | 132 | extern struct bfa_module_s hal_mod_uf; |
131 | extern struct bfa_module_s hal_mod_rport; | 133 | extern struct bfa_module_s hal_mod_rport; |
132 | extern struct bfa_module_s hal_mod_fcp; | 134 | extern struct bfa_module_s hal_mod_fcp; |
135 | extern 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 | ||
2011 | static void | ||
2012 | bfa_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, | |||
3102 | static void | 3146 | static 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 | ||
3150 | static void | 3201 | static void |
@@ -3174,7 +3225,9 @@ bfa_fcport_send_stats_get(void *cbarg) | |||
3174 | static void | 3225 | static 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 | ||
3212 | static void | 3269 | static 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 | */ |
3781 | bfa_status_t | 3841 | bfa_status_t |
3782 | bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, | 3842 | bfa_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 | */ |
3807 | bfa_status_t | 3867 | bfa_status_t |
3808 | bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg) | 3868 | bfa_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 */ | ||
4770 | void | ||
4771 | bfa_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 */ | ||
4786 | void | ||
4787 | bfa_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)) |
444 | typedef 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); |
553 | bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa); | 552 | bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa); |
554 | bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa, | 553 | bfa_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); | 555 | bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, |
557 | bfa_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); | ||
559 | bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa); | 557 | bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa); |
560 | bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa); | 558 | bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa); |
561 | bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa); | 559 | bfa_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 | ||
583 | void bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp); | ||
584 | void bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp); | ||
585 | bfa_boolean_t bfa_rport_lunmask_active(struct bfa_rport_s *rp); | ||
586 | wwn_t bfa_rport_get_pwwn(struct bfa_s *bfa, struct bfa_rport_s *rp); | ||
587 | struct bfa_rport_s *bfa_rport_get_by_wwn(struct bfa_s *bfa, u16 vf_id, | ||
588 | wwn_t *lpwwn, wwn_t rpwwn); | ||
589 | void *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 | */ |
583 | struct bfa_fcxp_s *bfa_fcxp_alloc(void *bfad_fcxp, struct bfa_s *bfa, | 594 | struct 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 | |||
1348 | bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) | 1348 | bfad_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 | ||
180 | int | 181 | int |
182 | bfad_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 | |||
199 | int | ||
200 | bfad_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 | |||
213 | int | ||
181 | bfad_iocmd_iocfc_get_attr(struct bfad_s *bfad, void *cmd) | 214 | bfad_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 | ||
342 | int | ||
343 | bfad_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 | |||
363 | int | ||
364 | bfad_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 | |||
383 | int | ||
384 | bfad_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 | |||
397 | int | ||
398 | bfad_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 | |||
309 | static int | 417 | static int |
310 | bfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd) | 418 | bfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd) |
311 | { | 419 | { |
@@ -354,6 +462,40 @@ out: | |||
354 | } | 462 | } |
355 | 463 | ||
356 | int | 464 | int |
465 | bfad_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; | ||
494 | out: | ||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | int | ||
357 | bfad_iocmd_lport_get_iostats(struct bfad_s *bfad, void *cmd) | 499 | bfad_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 | ||
684 | int | ||
685 | bfad_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; | ||
715 | out: | ||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | int | ||
720 | bfad_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; | ||
750 | out: | ||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | int | ||
755 | bfad_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; | ||
773 | out: | ||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | int | ||
778 | bfad_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; | ||
801 | out: | ||
802 | return 0; | ||
803 | } | ||
804 | |||
805 | int | ||
806 | bfad_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; | ||
826 | out: | ||
827 | return 0; | ||
828 | } | ||
829 | |||
542 | static int | 830 | static int |
543 | bfad_iocmd_fabric_get_lports(struct bfad_s *bfad, void *cmd, | 831 | bfad_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 | ||
584 | int | 872 | int |
873 | bfad_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 | |||
895 | int | ||
896 | bfad_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 | |||
919 | int | ||
920 | bfad_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 | |||
932 | int | ||
585 | bfad_iocmd_fcpim_get_modstats(struct bfad_s *bfad, void *cmd) | 933 | bfad_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 | ||
606 | int | 954 | int |
955 | bfad_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 | |||
976 | int | ||
607 | bfad_iocmd_fcpim_get_del_itn_stats(struct bfad_s *bfad, void *cmd) | 977 | bfad_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 | ||
672 | static int | 1042 | static int |
1043 | bfad_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 | |||
1071 | static int | ||
673 | bfad_iocmd_itnim_get_itnstats(struct bfad_s *bfad, void *cmd) | 1072 | bfad_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 */ | ||
1914 | int | ||
1915 | bfad_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); | ||
1941 | out: | ||
1942 | return 0; | ||
1943 | } | ||
1944 | |||
1945 | int | ||
1946 | bfad_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 | |||
1966 | int | ||
1967 | bfad_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 | |||
1980 | int | ||
1981 | bfad_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 | |||
1999 | static int | ||
2000 | bfad_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 | |||
2026 | int | ||
2027 | bfad_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; | ||
2047 | out: | ||
2048 | return 0; | ||
2049 | } | ||
2050 | |||
2051 | int | ||
2052 | bfad_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; | ||
2071 | out: | ||
2072 | return 0; | ||
2073 | } | ||
2074 | |||
2075 | int | ||
2076 | bfad_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; | ||
2093 | out: | ||
2094 | return 0; | ||
2095 | } | ||
2096 | |||
2097 | int | ||
2098 | bfad_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; | ||
2115 | out: | ||
2116 | return 0; | ||
2117 | } | ||
2118 | |||
2119 | int | ||
2120 | bfad_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 | |||
2138 | int | ||
2139 | bfad_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; | ||
2157 | out: | ||
2158 | return 0; | ||
2159 | } | ||
2160 | |||
2161 | int | ||
2162 | bfad_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; | ||
2180 | out: | ||
2181 | return 0; | ||
2182 | } | ||
2183 | |||
2184 | int | ||
2185 | bfad_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 | |||
2213 | int | ||
2214 | bfad_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 | |||
2231 | int | ||
2232 | bfad_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 | |||
2251 | int | ||
2252 | bfad_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 | |||
2267 | int | ||
2268 | bfad_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 | |||
2299 | int | ||
2300 | bfad_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; | ||
2322 | out: | ||
2323 | return 0; | ||
2324 | } | ||
2325 | |||
2326 | int | ||
2327 | bfad_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; | ||
2348 | out: | ||
2349 | return 0; | ||
2350 | } | ||
2351 | |||
2352 | int | ||
2353 | bfad_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; | ||
2371 | out: | ||
2372 | return 0; | ||
2373 | } | ||
2374 | |||
2375 | int | ||
2376 | bfad_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; | ||
2393 | out: | ||
2394 | return 0; | ||
2395 | } | ||
2396 | |||
2397 | int | ||
2398 | bfad_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 | |||
2414 | int | ||
2415 | bfad_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 | |||
2428 | int | ||
2429 | bfad_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 | |||
1514 | static int | 2447 | static int |
1515 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | 2448 | bfad_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 | ||
1712 | static int | 2784 | static 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 | ||
91 | struct bfa_bsg_gen_s { | 148 | struct bfa_bsg_gen_s { |
@@ -94,6 +151,43 @@ struct bfa_bsg_gen_s { | |||
94 | u16 rsvd; | 151 | u16 rsvd; |
95 | }; | 152 | }; |
96 | 153 | ||
154 | struct 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 | |||
162 | struct bfa_bsg_fcpim_profile_s { | ||
163 | bfa_status_t status; | ||
164 | u16 bfad_num; | ||
165 | u16 rsvd; | ||
166 | }; | ||
167 | |||
168 | struct 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 | |||
177 | struct 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 | |||
184 | struct 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 | |||
97 | struct bfa_bsg_ioc_info_s { | 191 | struct 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 | ||
261 | struct 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 | |||
269 | struct bfa_bsg_port_cfg_maxfrsize_s { | ||
270 | bfa_status_t status; | ||
271 | u16 bfad_num; | ||
272 | u16 maxfrsize; | ||
273 | }; | ||
274 | |||
167 | struct bfa_bsg_port_stats_s { | 275 | struct 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 | ||
348 | struct 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 | |||
356 | struct 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 | |||
366 | struct 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 | |||
374 | struct 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 | |||
382 | struct bfa_bsg_reset_stats_s { | ||
383 | bfa_status_t status; | ||
384 | u16 bfad_num; | ||
385 | u16 vf_id; | ||
386 | wwn_t vpwwn; | ||
387 | }; | ||
388 | |||
240 | struct bfa_bsg_fabric_get_lports_s { | 389 | struct 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 | ||
398 | struct 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 | |||
405 | struct bfa_bsg_fcpim_s { | ||
406 | bfa_status_t status; | ||
407 | u16 bfad_num; | ||
408 | u16 param; | ||
409 | }; | ||
410 | |||
249 | struct bfa_bsg_fcpim_modstats_s { | 411 | struct 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 | ||
423 | struct bfa_bsg_fcpim_modstatsclr_s { | ||
424 | bfa_status_t status; | ||
425 | u16 bfad_num; | ||
426 | }; | ||
427 | |||
261 | struct bfa_bsg_itnim_attr_s { | 428 | struct 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 | ||
655 | struct 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 | |||
662 | struct 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 | |||
669 | struct 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 | |||
676 | struct 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 | |||
683 | struct 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 | |||
690 | struct 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 | |||
697 | struct 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 | |||
704 | struct bfa_bsg_vf_reset_stats_s { | ||
705 | bfa_status_t status; | ||
706 | u16 bfad_num; | ||
707 | u16 vf_id; | ||
708 | }; | ||
709 | |||
710 | struct 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 | |||
716 | struct 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 | |||
488 | struct bfa_bsg_fcpt_s { | 725 | struct 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 | ||
659 | static 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 | |||
659 | bfa_status_t | 684 | bfa_status_t |
660 | bfad_im_probe(struct bfad_s *bfad) | 685 | bfad_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); | ||
679 | ext: | 705 | ext: |
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 | |||
120 | struct Scsi_Host *bfad_scsi_host_alloc(struct bfad_im_port_s *im_port, | 142 | struct Scsi_Host *bfad_scsi_host_alloc(struct bfad_im_port_s *im_port, |
121 | struct bfad_s *); | 143 | struct bfad_s *); |
122 | bfa_status_t bfad_thread_workq(struct bfad_s *bfad); | 144 | bfa_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 | */ | ||
789 | struct 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 | */ |
789 | enum bfa_sfp_stat_e { | 800 | enum 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 | */ | ||
942 | struct 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 | *---------------------------------------------------------------------- |