diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 21:57:01 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 21:57:01 -0400 |
| commit | 6a5a3d6a4adde0c66f3be29bbd7c0d6ffb7e1a40 (patch) | |
| tree | ae416ffa4458df755f984a05d65ee1c3e220c40b | |
| parent | 8bbbfa70549bd84f29ff331d0ac051897ccbbd72 (diff) | |
| parent | 5c1b10ab7f93d24f29b5630286e323d1c5802d5c (diff) | |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull misc SCSI updates from James Bottomley:
"This is an assorted set of stragglers into the merge window with
driver updates for megaraid_sas, lpfc, bfi and mvumi. It also
includes some fairly major fixes for virtio-scsi (scatterlist init),
scsi_debug (off by one error), storvsc (use after free) and qla2xxx
(potential deadlock).
Signed-off-by: James Bottomley <JBottomley@Parallels.com>"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (49 commits)
[SCSI] storvsc: Account for in-transit packets in the RESET path
[SCSI] qla2xxx: fix potential deadlock on ha->hardware_lock
[SCSI] scsi_debug: Fix off-by-one bug when unmapping region
[SCSI] Shorten the path length of scsi_cmd_to_driver()
[SCSI] virtio-scsi: support online resizing of disks
[SCSI] virtio-scsi: fix LUNs greater than 255
[SCSI] virtio-scsi: initialize scatterlist structure
[SCSI] megaraid_sas: Version, Changelog, Copyright update
[SCSI] megaraid_sas: Remove duplicate code
[SCSI] megaraid_sas: Add SystemPD FastPath support
[SCSI] megaraid_sas: Add array boundary check for SystemPD
[SCSI] megaraid_sas: Load io_request DataLength in bytes
[SCSI] megaraid_sas: Add module param for configurable MSI-X vector count
[SCSI] megaraid_sas: Remove un-needed completion_lock spinlock calls
[SCSI] lpfc 8.3.35: Update lpfc version for 8.3.35 driver release
[SCSI] lpfc 8.3.35: Fixed not reporting logical link speed to SCSI midlayer when QoS not on
[SCSI] lpfc 8.3.35: Fix error with fabric service parameters causing performance issues
[SCSI] lpfc 8.3.35: Fixed SCSI host create showing wrong link speed on SLI3 HBA ports
[SCSI] lpfc 8.3.35: Fixed not checking solicition in progress bit when verifying FCF record for use
[SCSI] lpfc 8.3.35: Fixed messages for misconfigured port errors
...
58 files changed, 4274 insertions, 747 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-fcoe b/Documentation/ABI/testing/sysfs-bus-fcoe index 469d09c02f6b..50e2a80ea28f 100644 --- a/Documentation/ABI/testing/sysfs-bus-fcoe +++ b/Documentation/ABI/testing/sysfs-bus-fcoe | |||
| @@ -9,19 +9,19 @@ Attributes: | |||
| 9 | this value will change the dev_loss_tmo for all | 9 | this value will change the dev_loss_tmo for all |
| 10 | FCFs discovered by this controller. | 10 | FCFs discovered by this controller. |
| 11 | 11 | ||
| 12 | lesb_link_fail: Link Error Status Block (LESB) link failure count. | 12 | lesb/link_fail: Link Error Status Block (LESB) link failure count. |
| 13 | 13 | ||
| 14 | lesb_vlink_fail: Link Error Status Block (LESB) virtual link | 14 | lesb/vlink_fail: Link Error Status Block (LESB) virtual link |
| 15 | failure count. | 15 | failure count. |
| 16 | 16 | ||
| 17 | lesb_miss_fka: Link Error Status Block (LESB) missed FCoE | 17 | lesb/miss_fka: Link Error Status Block (LESB) missed FCoE |
| 18 | Initialization Protocol (FIP) Keep-Alives (FKA). | 18 | Initialization Protocol (FIP) Keep-Alives (FKA). |
| 19 | 19 | ||
| 20 | lesb_symb_err: Link Error Status Block (LESB) symbolic error count. | 20 | lesb/symb_err: Link Error Status Block (LESB) symbolic error count. |
| 21 | 21 | ||
| 22 | lesb_err_block: Link Error Status Block (LESB) block error count. | 22 | lesb/err_block: Link Error Status Block (LESB) block error count. |
| 23 | 23 | ||
| 24 | lesb_fcs_error: Link Error Status Block (LESB) Fibre Channel | 24 | lesb/fcs_error: Link Error Status Block (LESB) Fibre Channel |
| 25 | Serivces error count. | 25 | Serivces error count. |
| 26 | 26 | ||
| 27 | Notes: ctlr_X (global increment starting at 0) | 27 | Notes: ctlr_X (global increment starting at 0) |
diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas index 3a3079411a3d..da03146c182a 100644 --- a/Documentation/scsi/ChangeLog.megaraid_sas +++ b/Documentation/scsi/ChangeLog.megaraid_sas | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | Release Date : Mon. Oct 1, 2012 17:00:00 PST 2012 - | ||
| 2 | (emaild-id:megaraidlinux@lsi.com) | ||
| 3 | Adam Radford | ||
| 4 | Current Version : 06.504.01.00-rc1 | ||
| 5 | Old Version : 00.00.06.18-rc1 | ||
| 6 | 1. Removed un-needed completion_lock spinlock calls. | ||
| 7 | 2. Add module param for configurable MSI-X vector count. | ||
| 8 | 3. Load io_request DataLength in bytes. | ||
| 9 | 4. Add array boundary check for SystemPD. | ||
| 10 | 5. Add SystemPD FastPath support. | ||
| 11 | 6. Remove duplicate code. | ||
| 12 | 7. Version, Changelog, Copyright update. | ||
| 13 | ------------------------------------------------------------------------------- | ||
| 1 | Release Date : Tue. Jun 17, 2012 17:00:00 PST 2012 - | 14 | Release Date : Tue. Jun 17, 2012 17:00:00 PST 2012 - |
| 2 | (emaild-id:megaraidlinux@lsi.com) | 15 | (emaild-id:megaraidlinux@lsi.com) |
| 3 | Adam Radford/Kashyap Desai | 16 | Adam Radford/Kashyap Desai |
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index b7c326f7a6d0..342d7d9c0997 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c | |||
| @@ -165,6 +165,16 @@ bfa_com_phy_attach(struct bfa_s *bfa, bfa_boolean_t mincfg) | |||
| 165 | bfa_phy_memclaim(phy, phy_dma->kva_curp, phy_dma->dma_curp, mincfg); | 165 | bfa_phy_memclaim(phy, phy_dma->kva_curp, phy_dma->dma_curp, mincfg); |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | static void | ||
| 169 | bfa_com_fru_attach(struct bfa_s *bfa, bfa_boolean_t mincfg) | ||
| 170 | { | ||
| 171 | struct bfa_fru_s *fru = BFA_FRU(bfa); | ||
| 172 | struct bfa_mem_dma_s *fru_dma = BFA_MEM_FRU_DMA(bfa); | ||
| 173 | |||
| 174 | bfa_fru_attach(fru, &bfa->ioc, bfa, bfa->trcmod, mincfg); | ||
| 175 | bfa_fru_memclaim(fru, fru_dma->kva_curp, fru_dma->dma_curp, mincfg); | ||
| 176 | } | ||
| 177 | |||
| 168 | /* | 178 | /* |
| 169 | * BFA IOC FC related definitions | 179 | * BFA IOC FC related definitions |
| 170 | */ | 180 | */ |
| @@ -274,6 +284,15 @@ bfa_iocfc_sm_initing(struct bfa_iocfc_s *iocfc, enum iocfc_event event) | |||
| 274 | case IOCFC_E_IOC_ENABLED: | 284 | case IOCFC_E_IOC_ENABLED: |
| 275 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_read); | 285 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_read); |
| 276 | break; | 286 | break; |
| 287 | |||
| 288 | case IOCFC_E_DISABLE: | ||
| 289 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling); | ||
| 290 | break; | ||
| 291 | |||
| 292 | case IOCFC_E_STOP: | ||
| 293 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping); | ||
| 294 | break; | ||
| 295 | |||
| 277 | case IOCFC_E_IOC_FAILED: | 296 | case IOCFC_E_IOC_FAILED: |
| 278 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed); | 297 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed); |
| 279 | break; | 298 | break; |
| @@ -298,6 +317,15 @@ bfa_iocfc_sm_dconf_read(struct bfa_iocfc_s *iocfc, enum iocfc_event event) | |||
| 298 | case IOCFC_E_DCONF_DONE: | 317 | case IOCFC_E_DCONF_DONE: |
| 299 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_wait); | 318 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_wait); |
| 300 | break; | 319 | break; |
| 320 | |||
| 321 | case IOCFC_E_DISABLE: | ||
| 322 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling); | ||
| 323 | break; | ||
| 324 | |||
| 325 | case IOCFC_E_STOP: | ||
| 326 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping); | ||
| 327 | break; | ||
| 328 | |||
| 301 | case IOCFC_E_IOC_FAILED: | 329 | case IOCFC_E_IOC_FAILED: |
| 302 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed); | 330 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed); |
| 303 | break; | 331 | break; |
| @@ -322,6 +350,15 @@ bfa_iocfc_sm_init_cfg_wait(struct bfa_iocfc_s *iocfc, enum iocfc_event event) | |||
| 322 | case IOCFC_E_CFG_DONE: | 350 | case IOCFC_E_CFG_DONE: |
| 323 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_done); | 351 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_done); |
| 324 | break; | 352 | break; |
| 353 | |||
| 354 | case IOCFC_E_DISABLE: | ||
| 355 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling); | ||
| 356 | break; | ||
| 357 | |||
| 358 | case IOCFC_E_STOP: | ||
| 359 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping); | ||
| 360 | break; | ||
| 361 | |||
| 325 | case IOCFC_E_IOC_FAILED: | 362 | case IOCFC_E_IOC_FAILED: |
| 326 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed); | 363 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed); |
| 327 | break; | 364 | break; |
| @@ -433,6 +470,12 @@ bfa_iocfc_sm_stopping(struct bfa_iocfc_s *iocfc, enum iocfc_event event) | |||
| 433 | bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.stop_hcb_qe, | 470 | bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.stop_hcb_qe, |
| 434 | bfa_iocfc_stop_cb, iocfc->bfa); | 471 | bfa_iocfc_stop_cb, iocfc->bfa); |
| 435 | break; | 472 | break; |
| 473 | |||
| 474 | case IOCFC_E_IOC_ENABLED: | ||
| 475 | case IOCFC_E_DCONF_DONE: | ||
| 476 | case IOCFC_E_CFG_DONE: | ||
| 477 | break; | ||
| 478 | |||
| 436 | default: | 479 | default: |
| 437 | bfa_sm_fault(iocfc->bfa, event); | 480 | bfa_sm_fault(iocfc->bfa, event); |
| 438 | break; | 481 | break; |
| @@ -454,6 +497,15 @@ bfa_iocfc_sm_enabling(struct bfa_iocfc_s *iocfc, enum iocfc_event event) | |||
| 454 | case IOCFC_E_IOC_ENABLED: | 497 | case IOCFC_E_IOC_ENABLED: |
| 455 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_cfg_wait); | 498 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_cfg_wait); |
| 456 | break; | 499 | break; |
| 500 | |||
| 501 | case IOCFC_E_DISABLE: | ||
| 502 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling); | ||
| 503 | break; | ||
| 504 | |||
| 505 | case IOCFC_E_STOP: | ||
| 506 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write); | ||
| 507 | break; | ||
| 508 | |||
| 457 | case IOCFC_E_IOC_FAILED: | 509 | case IOCFC_E_IOC_FAILED: |
| 458 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed); | 510 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed); |
| 459 | 511 | ||
| @@ -493,6 +545,13 @@ bfa_iocfc_sm_cfg_wait(struct bfa_iocfc_s *iocfc, enum iocfc_event event) | |||
| 493 | bfa_iocfc_enable_cb, iocfc->bfa); | 545 | bfa_iocfc_enable_cb, iocfc->bfa); |
| 494 | iocfc->bfa->iocfc.cb_reqd = BFA_FALSE; | 546 | iocfc->bfa->iocfc.cb_reqd = BFA_FALSE; |
| 495 | break; | 547 | break; |
| 548 | case IOCFC_E_DISABLE: | ||
| 549 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling); | ||
| 550 | break; | ||
| 551 | |||
| 552 | case IOCFC_E_STOP: | ||
| 553 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write); | ||
| 554 | break; | ||
| 496 | case IOCFC_E_IOC_FAILED: | 555 | case IOCFC_E_IOC_FAILED: |
| 497 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed); | 556 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed); |
| 498 | if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE) | 557 | if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE) |
| @@ -524,6 +583,10 @@ bfa_iocfc_sm_disabling(struct bfa_iocfc_s *iocfc, enum iocfc_event event) | |||
| 524 | case IOCFC_E_IOC_DISABLED: | 583 | case IOCFC_E_IOC_DISABLED: |
| 525 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabled); | 584 | bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabled); |
| 526 | break; | 585 | break; |
| 586 | case IOCFC_E_IOC_ENABLED: | ||
| 587 | case IOCFC_E_DCONF_DONE: | ||
| 588 | case IOCFC_E_CFG_DONE: | ||
| 589 | break; | ||
| 527 | default: | 590 | default: |
| 528 | bfa_sm_fault(iocfc->bfa, event); | 591 | bfa_sm_fault(iocfc->bfa, event); |
| 529 | break; | 592 | break; |
| @@ -785,19 +848,20 @@ void | |||
| 785 | bfa_isr_enable(struct bfa_s *bfa) | 848 | bfa_isr_enable(struct bfa_s *bfa) |
| 786 | { | 849 | { |
| 787 | u32 umsk; | 850 | u32 umsk; |
| 788 | int pci_func = bfa_ioc_pcifn(&bfa->ioc); | 851 | int port_id = bfa_ioc_portid(&bfa->ioc); |
| 789 | 852 | ||
| 790 | bfa_trc(bfa, pci_func); | 853 | bfa_trc(bfa, bfa_ioc_pcifn(&bfa->ioc)); |
| 854 | bfa_trc(bfa, port_id); | ||
| 791 | 855 | ||
| 792 | bfa_msix_ctrl_install(bfa); | 856 | bfa_msix_ctrl_install(bfa); |
| 793 | 857 | ||
| 794 | if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) { | 858 | if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) { |
| 795 | umsk = __HFN_INT_ERR_MASK_CT2; | 859 | umsk = __HFN_INT_ERR_MASK_CT2; |
| 796 | umsk |= pci_func == 0 ? | 860 | umsk |= port_id == 0 ? |
| 797 | __HFN_INT_FN0_MASK_CT2 : __HFN_INT_FN1_MASK_CT2; | 861 | __HFN_INT_FN0_MASK_CT2 : __HFN_INT_FN1_MASK_CT2; |
| 798 | } else { | 862 | } else { |
| 799 | umsk = __HFN_INT_ERR_MASK; | 863 | umsk = __HFN_INT_ERR_MASK; |
| 800 | umsk |= pci_func == 0 ? __HFN_INT_FN0_MASK : __HFN_INT_FN1_MASK; | 864 | umsk |= port_id == 0 ? __HFN_INT_FN0_MASK : __HFN_INT_FN1_MASK; |
| 801 | } | 865 | } |
| 802 | 866 | ||
| 803 | writel(umsk, bfa->iocfc.bfa_regs.intr_status); | 867 | writel(umsk, bfa->iocfc.bfa_regs.intr_status); |
| @@ -930,7 +994,8 @@ bfa_iocfc_send_cfg(void *bfa_arg) | |||
| 930 | cfg_info->single_msix_vec = 1; | 994 | cfg_info->single_msix_vec = 1; |
| 931 | cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG; | 995 | cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG; |
| 932 | cfg_info->num_cqs = cfg->fwcfg.num_cqs; | 996 | cfg_info->num_cqs = cfg->fwcfg.num_cqs; |
| 933 | cfg_info->num_ioim_reqs = cpu_to_be16(cfg->fwcfg.num_ioim_reqs); | 997 | cfg_info->num_ioim_reqs = cpu_to_be16(bfa_fcpim_get_throttle_cfg(bfa, |
| 998 | cfg->fwcfg.num_ioim_reqs)); | ||
| 934 | cfg_info->num_fwtio_reqs = cpu_to_be16(cfg->fwcfg.num_fwtio_reqs); | 999 | cfg_info->num_fwtio_reqs = cpu_to_be16(cfg->fwcfg.num_fwtio_reqs); |
| 935 | 1000 | ||
| 936 | bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa); | 1001 | bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa); |
| @@ -1192,10 +1257,14 @@ bfa_iocfc_qreg(struct bfa_s *bfa, struct bfi_iocfc_qreg_s *qreg) | |||
| 1192 | static void | 1257 | static void |
| 1193 | bfa_iocfc_res_recfg(struct bfa_s *bfa, struct bfa_iocfc_fwcfg_s *fwcfg) | 1258 | bfa_iocfc_res_recfg(struct bfa_s *bfa, struct bfa_iocfc_fwcfg_s *fwcfg) |
| 1194 | { | 1259 | { |
| 1260 | struct bfa_iocfc_s *iocfc = &bfa->iocfc; | ||
| 1261 | struct bfi_iocfc_cfg_s *cfg_info = iocfc->cfginfo; | ||
| 1262 | |||
| 1195 | bfa_fcxp_res_recfg(bfa, fwcfg->num_fcxp_reqs); | 1263 | bfa_fcxp_res_recfg(bfa, fwcfg->num_fcxp_reqs); |
| 1196 | bfa_uf_res_recfg(bfa, fwcfg->num_uf_bufs); | 1264 | bfa_uf_res_recfg(bfa, fwcfg->num_uf_bufs); |
| 1197 | bfa_rport_res_recfg(bfa, fwcfg->num_rports); | 1265 | bfa_rport_res_recfg(bfa, fwcfg->num_rports); |
| 1198 | bfa_fcp_res_recfg(bfa, fwcfg->num_ioim_reqs); | 1266 | bfa_fcp_res_recfg(bfa, cpu_to_be16(cfg_info->num_ioim_reqs), |
| 1267 | fwcfg->num_ioim_reqs); | ||
| 1199 | bfa_tskim_res_recfg(bfa, fwcfg->num_tskim_reqs); | 1268 | bfa_tskim_res_recfg(bfa, fwcfg->num_tskim_reqs); |
| 1200 | } | 1269 | } |
| 1201 | 1270 | ||
| @@ -1693,6 +1762,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, | |||
| 1693 | struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa); | 1762 | struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa); |
| 1694 | struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa); | 1763 | struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa); |
| 1695 | struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa); | 1764 | struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa); |
| 1765 | struct bfa_mem_dma_s *fru_dma = BFA_MEM_FRU_DMA(bfa); | ||
| 1696 | 1766 | ||
| 1697 | WARN_ON((cfg == NULL) || (meminfo == NULL)); | 1767 | WARN_ON((cfg == NULL) || (meminfo == NULL)); |
| 1698 | 1768 | ||
| @@ -1717,6 +1787,8 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, | |||
| 1717 | bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo()); | 1787 | bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo()); |
| 1718 | bfa_mem_dma_setup(meminfo, phy_dma, | 1788 | bfa_mem_dma_setup(meminfo, phy_dma, |
| 1719 | bfa_phy_meminfo(cfg->drvcfg.min_cfg)); | 1789 | bfa_phy_meminfo(cfg->drvcfg.min_cfg)); |
| 1790 | bfa_mem_dma_setup(meminfo, fru_dma, | ||
| 1791 | bfa_fru_meminfo(cfg->drvcfg.min_cfg)); | ||
| 1720 | } | 1792 | } |
| 1721 | 1793 | ||
| 1722 | /* | 1794 | /* |
| @@ -1789,6 +1861,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
| 1789 | bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg); | 1861 | bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg); |
| 1790 | bfa_com_diag_attach(bfa); | 1862 | bfa_com_diag_attach(bfa); |
| 1791 | bfa_com_phy_attach(bfa, cfg->drvcfg.min_cfg); | 1863 | bfa_com_phy_attach(bfa, cfg->drvcfg.min_cfg); |
| 1864 | bfa_com_fru_attach(bfa, cfg->drvcfg.min_cfg); | ||
| 1792 | } | 1865 | } |
| 1793 | 1866 | ||
| 1794 | /* | 1867 | /* |
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index b5a1595cc0a5..0efdf312b42c 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h | |||
| @@ -159,10 +159,13 @@ enum bfa_status { | |||
| 159 | BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */ | 159 | BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */ |
| 160 | BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */ | 160 | BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */ |
| 161 | BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */ | 161 | BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */ |
| 162 | BFA_STATUS_ERROR_TRL_ENABLED = 87, /* TRL is enabled */ | ||
| 163 | BFA_STATUS_ERROR_QOS_ENABLED = 88, /* QoS is enabled */ | ||
| 162 | BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */ | 164 | BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */ |
| 163 | BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */ | 165 | BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */ |
| 164 | BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */ | 166 | BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */ |
| 165 | BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */ | 167 | BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */ |
| 168 | BFA_STATUS_CMD_NOTSUPP_CNA = 146, /* Command not supported for CNA */ | ||
| 166 | BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot | 169 | BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot |
| 167 | * configuration */ | 170 | * configuration */ |
| 168 | BFA_STATUS_BAD_FWCFG = 156, /* Bad firmware configuration */ | 171 | BFA_STATUS_BAD_FWCFG = 156, /* Bad firmware configuration */ |
| @@ -184,6 +187,17 @@ enum bfa_status { | |||
| 184 | BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */ | 187 | BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */ |
| 185 | BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */ | 188 | BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */ |
| 186 | BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */ | 189 | BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */ |
| 190 | BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */ | ||
| 191 | BFA_STATUS_LOOP_UNSUPP_MEZZ = 231, /* Loop topology is not supported | ||
| 192 | * on mezz cards */ | ||
| 193 | BFA_STATUS_INVALID_BW = 233, /* Invalid bandwidth value */ | ||
| 194 | BFA_STATUS_QOS_BW_INVALID = 234, /* Invalid QOS bandwidth | ||
| 195 | * configuration */ | ||
| 196 | BFA_STATUS_DPORT_ENABLED = 235, /* D-port mode is already enabled */ | ||
| 197 | BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */ | ||
| 198 | BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */ | ||
| 199 | BFA_STATUS_FRU_NOT_PRESENT = 240, /* fru module not present */ | ||
| 200 | BFA_STATUS_DPORT_ERR = 245, /* D-port mode is enabled */ | ||
| 187 | BFA_STATUS_MAX_VAL /* Unknown error code */ | 201 | BFA_STATUS_MAX_VAL /* Unknown error code */ |
| 188 | }; | 202 | }; |
| 189 | #define bfa_status_t enum bfa_status | 203 | #define bfa_status_t enum bfa_status |
| @@ -249,6 +263,10 @@ struct bfa_adapter_attr_s { | |||
| 249 | 263 | ||
| 250 | u8 is_mezz; | 264 | u8 is_mezz; |
| 251 | u8 trunk_capable; | 265 | u8 trunk_capable; |
| 266 | u8 mfg_day; /* manufacturing day */ | ||
| 267 | u8 mfg_month; /* manufacturing month */ | ||
| 268 | u16 mfg_year; /* manufacturing year */ | ||
| 269 | u16 rsvd; | ||
| 252 | }; | 270 | }; |
| 253 | 271 | ||
| 254 | /* | 272 | /* |
| @@ -499,6 +517,17 @@ struct bfa_ioc_aen_data_s { | |||
| 499 | }; | 517 | }; |
| 500 | 518 | ||
| 501 | /* | 519 | /* |
| 520 | * D-port states | ||
| 521 | * | ||
| 522 | */ | ||
| 523 | enum bfa_dport_state { | ||
| 524 | BFA_DPORT_ST_DISABLED = 0, /* D-port is Disabled */ | ||
| 525 | BFA_DPORT_ST_DISABLING = 1, /* D-port is Disabling */ | ||
| 526 | BFA_DPORT_ST_ENABLING = 2, /* D-port is Enabling */ | ||
| 527 | BFA_DPORT_ST_ENABLED = 3, /* D-port is Enabled */ | ||
| 528 | }; | ||
| 529 | |||
| 530 | /* | ||
| 502 | * ---------------------- mfg definitions ------------ | 531 | * ---------------------- mfg definitions ------------ |
| 503 | */ | 532 | */ |
| 504 | 533 | ||
| @@ -722,7 +751,8 @@ struct bfa_ablk_cfg_pf_s { | |||
| 722 | u8 rsvd[1]; | 751 | u8 rsvd[1]; |
| 723 | u16 num_qpairs; | 752 | u16 num_qpairs; |
| 724 | u16 num_vectors; | 753 | u16 num_vectors; |
| 725 | u32 bw; | 754 | u16 bw_min; |
| 755 | u16 bw_max; | ||
| 726 | }; | 756 | }; |
| 727 | 757 | ||
| 728 | struct bfa_ablk_cfg_port_s { | 758 | struct bfa_ablk_cfg_port_s { |
| @@ -889,11 +919,40 @@ struct sfp_diag_ext_s { | |||
| 889 | u8 ext_status_ctl[2]; | 919 | u8 ext_status_ctl[2]; |
| 890 | }; | 920 | }; |
| 891 | 921 | ||
| 922 | /* | ||
| 923 | * Diagnostic: Data Fields -- Address A2h | ||
| 924 | * General Use Fields: User Writable Table - Features's Control Registers | ||
| 925 | * Total 32 bytes | ||
| 926 | */ | ||
| 927 | struct sfp_usr_eeprom_s { | ||
| 928 | u8 rsvd1[2]; /* 128-129 */ | ||
| 929 | u8 ewrap; /* 130 */ | ||
| 930 | u8 rsvd2[2]; /* */ | ||
| 931 | u8 owrap; /* 133 */ | ||
| 932 | u8 rsvd3[2]; /* */ | ||
| 933 | u8 prbs; /* 136: PRBS 7 generator */ | ||
| 934 | u8 rsvd4[2]; /* */ | ||
| 935 | u8 tx_eqz_16; /* 139: TX Equalizer (16xFC) */ | ||
| 936 | u8 tx_eqz_8; /* 140: TX Equalizer (8xFC) */ | ||
| 937 | u8 rsvd5[2]; /* */ | ||
| 938 | u8 rx_emp_16; /* 143: RX Emphasis (16xFC) */ | ||
| 939 | u8 rx_emp_8; /* 144: RX Emphasis (8xFC) */ | ||
| 940 | u8 rsvd6[2]; /* */ | ||
| 941 | u8 tx_eye_adj; /* 147: TX eye Threshold Adjust */ | ||
| 942 | u8 rsvd7[3]; /* */ | ||
| 943 | u8 tx_eye_qctl; /* 151: TX eye Quality Control */ | ||
| 944 | u8 tx_eye_qres; /* 152: TX eye Quality Result */ | ||
| 945 | u8 rsvd8[2]; /* */ | ||
| 946 | u8 poh[3]; /* 155-157: Power On Hours */ | ||
| 947 | u8 rsvd9[2]; /* */ | ||
| 948 | }; | ||
| 949 | |||
| 892 | struct sfp_mem_s { | 950 | struct sfp_mem_s { |
| 893 | struct sfp_srlid_base_s srlid_base; | 951 | struct sfp_srlid_base_s srlid_base; |
| 894 | struct sfp_srlid_ext_s srlid_ext; | 952 | struct sfp_srlid_ext_s srlid_ext; |
| 895 | struct sfp_diag_base_s diag_base; | 953 | struct sfp_diag_base_s diag_base; |
| 896 | struct sfp_diag_ext_s diag_ext; | 954 | struct sfp_diag_ext_s diag_ext; |
| 955 | struct sfp_usr_eeprom_s usr_eeprom; | ||
| 897 | }; | 956 | }; |
| 898 | 957 | ||
| 899 | /* | 958 | /* |
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index 36756ce0e58f..ec03c8cd8dac 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h | |||
| @@ -258,6 +258,7 @@ struct bfa_fw_port_lksm_stats_s { | |||
| 258 | u32 hwsm_lrr_rx; /* No. of times LRR rx-ed by HWSM */ | 258 | u32 hwsm_lrr_rx; /* No. of times LRR rx-ed by HWSM */ |
| 259 | u32 hwsm_lr_rx; /* No. of times LR rx-ed by HWSM */ | 259 | u32 hwsm_lr_rx; /* No. of times LR rx-ed by HWSM */ |
| 260 | u32 bbsc_lr; /* LKSM LR tx for credit recovery */ | 260 | u32 bbsc_lr; /* LKSM LR tx for credit recovery */ |
| 261 | u32 rsvd; | ||
| 261 | }; | 262 | }; |
| 262 | 263 | ||
| 263 | struct bfa_fw_port_snsm_stats_s { | 264 | struct bfa_fw_port_snsm_stats_s { |
| @@ -270,6 +271,9 @@ struct bfa_fw_port_snsm_stats_s { | |||
| 270 | u32 sync_lost; /* Sync loss count */ | 271 | u32 sync_lost; /* Sync loss count */ |
| 271 | u32 sig_lost; /* Signal loss count */ | 272 | u32 sig_lost; /* Signal loss count */ |
| 272 | u32 asn8g_attempts; /* SNSM HWSM at 8Gbps attempts */ | 273 | u32 asn8g_attempts; /* SNSM HWSM at 8Gbps attempts */ |
| 274 | u32 adapt_success; /* SNSM adaptation success */ | ||
| 275 | u32 adapt_fails; /* SNSM adaptation failures */ | ||
| 276 | u32 adapt_ign_fails; /* SNSM adaptation failures ignored */ | ||
| 273 | }; | 277 | }; |
| 274 | 278 | ||
| 275 | struct bfa_fw_port_physm_stats_s { | 279 | struct bfa_fw_port_physm_stats_s { |
| @@ -324,12 +328,46 @@ struct bfa_fw_fcoe_port_stats_s { | |||
| 324 | struct bfa_fw_fip_stats_s fip_stats; | 328 | struct bfa_fw_fip_stats_s fip_stats; |
| 325 | }; | 329 | }; |
| 326 | 330 | ||
| 331 | /** | ||
| 332 | * @brief LPSM statistics | ||
| 333 | */ | ||
| 334 | struct bfa_fw_lpsm_stats_s { | ||
| 335 | u32 cls_rx; /* LPSM cls_rx */ | ||
| 336 | u32 cls_tx; /* LPSM cls_tx */ | ||
| 337 | u32 arbf0_rx; /* LPSM abrf0 rcvd */ | ||
| 338 | u32 arbf0_tx; /* LPSM abrf0 xmit */ | ||
| 339 | u32 init_rx; /* LPSM loop init start */ | ||
| 340 | u32 unexp_hwst; /* LPSM unknown hw state */ | ||
| 341 | u32 unexp_frame; /* LPSM unknown_frame */ | ||
| 342 | u32 unexp_prim; /* LPSM unexpected primitive */ | ||
| 343 | u32 prev_alpa_unavail; /* LPSM prev alpa unavailable */ | ||
| 344 | u32 alpa_unavail; /* LPSM alpa not available */ | ||
| 345 | u32 lip_rx; /* LPSM lip rcvd */ | ||
| 346 | u32 lip_f7f7_rx; /* LPSM lip f7f7 rcvd */ | ||
| 347 | u32 lip_f8_rx; /* LPSM lip f8 rcvd */ | ||
| 348 | u32 lip_f8f7_rx; /* LPSM lip f8f7 rcvd */ | ||
| 349 | u32 lip_other_rx; /* LPSM lip other rcvd */ | ||
| 350 | u32 lip_tx; /* LPSM lip xmit */ | ||
| 351 | u32 retry_tov; /* LPSM retry TOV */ | ||
| 352 | u32 lip_tov; /* LPSM LIP wait TOV */ | ||
| 353 | u32 idle_tov; /* LPSM idle wait TOV */ | ||
| 354 | u32 arbf0_tov; /* LPSM arbfo wait TOV */ | ||
| 355 | u32 stop_loop_tov; /* LPSM stop loop wait TOV */ | ||
| 356 | u32 lixa_tov; /* LPSM lisa wait TOV */ | ||
| 357 | u32 lixx_tov; /* LPSM lilp/lirp wait TOV */ | ||
| 358 | u32 cls_tov; /* LPSM cls wait TOV */ | ||
| 359 | u32 sler; /* LPSM SLER recvd */ | ||
| 360 | u32 failed; /* LPSM failed */ | ||
| 361 | u32 success; /* LPSM online */ | ||
| 362 | }; | ||
| 363 | |||
| 327 | /* | 364 | /* |
| 328 | * IOC firmware FC uport stats | 365 | * IOC firmware FC uport stats |
| 329 | */ | 366 | */ |
| 330 | struct bfa_fw_fc_uport_stats_s { | 367 | struct bfa_fw_fc_uport_stats_s { |
| 331 | struct bfa_fw_port_snsm_stats_s snsm_stats; | 368 | struct bfa_fw_port_snsm_stats_s snsm_stats; |
| 332 | struct bfa_fw_port_lksm_stats_s lksm_stats; | 369 | struct bfa_fw_port_lksm_stats_s lksm_stats; |
| 370 | struct bfa_fw_lpsm_stats_s lpsm_stats; | ||
| 333 | }; | 371 | }; |
| 334 | 372 | ||
| 335 | /* | 373 | /* |
| @@ -357,11 +395,6 @@ struct bfa_fw_fcxchg_stats_s { | |||
| 357 | u32 ua_state_inv; | 395 | u32 ua_state_inv; |
| 358 | }; | 396 | }; |
| 359 | 397 | ||
| 360 | struct bfa_fw_lpsm_stats_s { | ||
| 361 | u32 cls_rx; | ||
| 362 | u32 cls_tx; | ||
| 363 | }; | ||
| 364 | |||
| 365 | /* | 398 | /* |
| 366 | * Trunk statistics | 399 | * Trunk statistics |
| 367 | */ | 400 | */ |
| @@ -454,7 +487,6 @@ struct bfa_fw_stats_s { | |||
| 454 | struct bfa_fw_io_stats_s io_stats; | 487 | struct bfa_fw_io_stats_s io_stats; |
| 455 | struct bfa_fw_port_stats_s port_stats; | 488 | struct bfa_fw_port_stats_s port_stats; |
| 456 | struct bfa_fw_fcxchg_stats_s fcxchg_stats; | 489 | struct bfa_fw_fcxchg_stats_s fcxchg_stats; |
| 457 | struct bfa_fw_lpsm_stats_s lpsm_stats; | ||
| 458 | struct bfa_fw_lps_stats_s lps_stats; | 490 | struct bfa_fw_lps_stats_s lps_stats; |
| 459 | struct bfa_fw_trunk_stats_s trunk_stats; | 491 | struct bfa_fw_trunk_stats_s trunk_stats; |
| 460 | struct bfa_fw_advsm_stats_s advsm_stats; | 492 | struct bfa_fw_advsm_stats_s advsm_stats; |
| @@ -494,13 +526,23 @@ enum bfa_qos_bw_alloc { | |||
| 494 | BFA_QOS_BW_LOW = 10, /* bandwidth allocation for Low */ | 526 | BFA_QOS_BW_LOW = 10, /* bandwidth allocation for Low */ |
| 495 | }; | 527 | }; |
| 496 | #pragma pack(1) | 528 | #pragma pack(1) |
| 529 | |||
| 530 | struct bfa_qos_bw_s { | ||
| 531 | u8 qos_bw_set; | ||
| 532 | u8 high; | ||
| 533 | u8 med; | ||
| 534 | u8 low; | ||
| 535 | }; | ||
| 536 | |||
| 497 | /* | 537 | /* |
| 498 | * QoS attribute returned in QoS Query | 538 | * QoS attribute returned in QoS Query |
| 499 | */ | 539 | */ |
| 500 | struct bfa_qos_attr_s { | 540 | struct bfa_qos_attr_s { |
| 501 | u8 state; /* QoS current state */ | 541 | u8 state; /* QoS current state */ |
| 502 | u8 rsvd[3]; | 542 | u8 rsvd1[3]; |
| 503 | u32 total_bb_cr; /* Total BB Credits */ | 543 | u32 total_bb_cr; /* Total BB Credits */ |
| 544 | struct bfa_qos_bw_s qos_bw; /* QOS bw cfg */ | ||
| 545 | struct bfa_qos_bw_s qos_bw_op; /* QOS bw operational */ | ||
| 504 | }; | 546 | }; |
| 505 | 547 | ||
| 506 | /* | 548 | /* |
| @@ -692,7 +734,8 @@ enum bfa_port_states { | |||
| 692 | BFA_PORT_ST_FWMISMATCH = 12, | 734 | BFA_PORT_ST_FWMISMATCH = 12, |
| 693 | BFA_PORT_ST_PREBOOT_DISABLED = 13, | 735 | BFA_PORT_ST_PREBOOT_DISABLED = 13, |
| 694 | BFA_PORT_ST_TOGGLING_QWAIT = 14, | 736 | BFA_PORT_ST_TOGGLING_QWAIT = 14, |
| 695 | BFA_PORT_ST_ACQ_ADDR = 15, | 737 | BFA_PORT_ST_FAA_MISCONFIG = 15, |
| 738 | BFA_PORT_ST_DPORT = 16, | ||
| 696 | BFA_PORT_ST_MAX_STATE, | 739 | BFA_PORT_ST_MAX_STATE, |
| 697 | }; | 740 | }; |
| 698 | 741 | ||
| @@ -714,9 +757,11 @@ enum bfa_port_type { | |||
| 714 | */ | 757 | */ |
| 715 | enum bfa_port_topology { | 758 | enum bfa_port_topology { |
| 716 | BFA_PORT_TOPOLOGY_NONE = 0, /* No valid topology */ | 759 | BFA_PORT_TOPOLOGY_NONE = 0, /* No valid topology */ |
| 717 | BFA_PORT_TOPOLOGY_P2P = 1, /* P2P only */ | 760 | BFA_PORT_TOPOLOGY_P2P_OLD_VER = 1, /* P2P def for older ver */ |
| 718 | BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */ | 761 | BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */ |
| 719 | BFA_PORT_TOPOLOGY_AUTO = 3, /* auto topology selection */ | 762 | BFA_PORT_TOPOLOGY_AUTO_OLD_VER = 3, /* auto def for older ver */ |
| 763 | BFA_PORT_TOPOLOGY_AUTO = 4, /* auto topology selection */ | ||
| 764 | BFA_PORT_TOPOLOGY_P2P = 5, /* P2P only */ | ||
| 720 | }; | 765 | }; |
| 721 | 766 | ||
| 722 | /* | 767 | /* |
| @@ -760,6 +805,7 @@ enum bfa_port_linkstate_rsn { | |||
| 760 | BFA_PORT_LINKSTATE_RSN_LOCAL_FAULT = 9, | 805 | BFA_PORT_LINKSTATE_RSN_LOCAL_FAULT = 9, |
| 761 | BFA_PORT_LINKSTATE_RSN_REMOTE_FAULT = 10, | 806 | BFA_PORT_LINKSTATE_RSN_REMOTE_FAULT = 10, |
| 762 | BFA_PORT_LINKSTATE_RSN_TIMEOUT = 11, | 807 | BFA_PORT_LINKSTATE_RSN_TIMEOUT = 11, |
| 808 | BFA_PORT_LINKSTATE_RSN_FAA_MISCONFIG = 12, | ||
| 763 | 809 | ||
| 764 | 810 | ||
| 765 | 811 | ||
| @@ -833,6 +879,19 @@ struct bfa_lunmask_cfg_s { | |||
| 833 | struct bfa_lun_mask_s lun_list[MAX_LUN_MASK_CFG]; | 879 | struct bfa_lun_mask_s lun_list[MAX_LUN_MASK_CFG]; |
| 834 | }; | 880 | }; |
| 835 | 881 | ||
| 882 | struct bfa_throttle_cfg_s { | ||
| 883 | u16 is_valid; | ||
| 884 | u16 value; | ||
| 885 | u32 rsvd; | ||
| 886 | }; | ||
| 887 | |||
| 888 | struct bfa_defs_fcpim_throttle_s { | ||
| 889 | u16 max_value; | ||
| 890 | u16 cur_value; | ||
| 891 | u16 cfg_value; | ||
| 892 | u16 rsvd; | ||
| 893 | }; | ||
| 894 | |||
| 836 | /* | 895 | /* |
| 837 | * Physical port configuration | 896 | * Physical port configuration |
| 838 | */ | 897 | */ |
| @@ -851,9 +910,10 @@ struct bfa_port_cfg_s { | |||
| 851 | u8 bb_scn; /* BB_SCN value from FLOGI Exchg */ | 910 | u8 bb_scn; /* BB_SCN value from FLOGI Exchg */ |
| 852 | u8 bb_scn_state; /* Config state of BB_SCN */ | 911 | u8 bb_scn_state; /* Config state of BB_SCN */ |
| 853 | u8 faa_state; /* FAA enabled/disabled */ | 912 | u8 faa_state; /* FAA enabled/disabled */ |
| 854 | u8 rsvd[1]; | 913 | u8 rsvd1; |
| 855 | u16 path_tov; /* device path timeout */ | 914 | u16 path_tov; /* device path timeout */ |
| 856 | u16 q_depth; /* SCSI Queue depth */ | 915 | u16 q_depth; /* SCSI Queue depth */ |
| 916 | struct bfa_qos_bw_s qos_bw; /* QOS bandwidth */ | ||
| 857 | }; | 917 | }; |
| 858 | #pragma pack() | 918 | #pragma pack() |
| 859 | 919 | ||
| @@ -901,7 +961,7 @@ struct bfa_port_attr_s { | |||
| 901 | 961 | ||
| 902 | /* FCoE specific */ | 962 | /* FCoE specific */ |
| 903 | u16 fcoe_vlan; | 963 | u16 fcoe_vlan; |
| 904 | u8 rsvd1[2]; | 964 | u8 rsvd1[6]; |
| 905 | }; | 965 | }; |
| 906 | 966 | ||
| 907 | /* | 967 | /* |
| @@ -971,6 +1031,13 @@ struct bfa_trunk_vc_attr_s { | |||
| 971 | u16 vc_credits[8]; | 1031 | u16 vc_credits[8]; |
| 972 | }; | 1032 | }; |
| 973 | 1033 | ||
| 1034 | struct bfa_fcport_loop_info_s { | ||
| 1035 | u8 myalpa; /* alpa claimed */ | ||
| 1036 | u8 alpabm_val; /* alpa bitmap valid or not (1 or 0) */ | ||
| 1037 | u8 resvd[6]; | ||
| 1038 | struct fc_alpabm_s alpabm; /* alpa bitmap */ | ||
| 1039 | }; | ||
| 1040 | |||
| 974 | /* | 1041 | /* |
| 975 | * Link state information | 1042 | * Link state information |
| 976 | */ | 1043 | */ |
| @@ -981,13 +1048,18 @@ struct bfa_port_link_s { | |||
| 981 | u8 speed; /* Link speed (1/2/4/8 G) */ | 1048 | u8 speed; /* Link speed (1/2/4/8 G) */ |
| 982 | u32 linkstate_opt; /* Linkstate optional data (debug) */ | 1049 | u32 linkstate_opt; /* Linkstate optional data (debug) */ |
| 983 | u8 trunked; /* Trunked or not (1 or 0) */ | 1050 | u8 trunked; /* Trunked or not (1 or 0) */ |
| 984 | u8 resvd[3]; | 1051 | u8 resvd[7]; |
| 985 | struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ | 1052 | struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ |
| 986 | union { | 1053 | union { |
| 987 | struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */ | 1054 | struct bfa_fcport_loop_info_s loop_info; |
| 988 | struct bfa_trunk_vc_attr_s trunk_vc_attr; | 1055 | union { |
| 989 | struct bfa_fcport_fcf_s fcf; /* FCF information (for FCoE) */ | 1056 | struct bfa_qos_vc_attr_s qos_vc_attr; |
| 990 | } vc_fcf; | 1057 | /* VC info from ELP */ |
| 1058 | struct bfa_trunk_vc_attr_s trunk_vc_attr; | ||
| 1059 | struct bfa_fcport_fcf_s fcf; | ||
| 1060 | /* FCF information (for FCoE) */ | ||
| 1061 | } vc_fcf; | ||
| 1062 | } attr; | ||
| 991 | }; | 1063 | }; |
| 992 | #pragma pack() | 1064 | #pragma pack() |
| 993 | 1065 | ||
| @@ -1112,6 +1184,9 @@ struct bfa_port_fc_stats_s { | |||
| 1112 | u64 tx_frames; /* Tx frames */ | 1184 | u64 tx_frames; /* Tx frames */ |
| 1113 | u64 tx_words; /* Tx words */ | 1185 | u64 tx_words; /* Tx words */ |
| 1114 | u64 tx_lip; /* Tx LIP */ | 1186 | u64 tx_lip; /* Tx LIP */ |
| 1187 | u64 tx_lip_f7f7; /* Tx LIP_F7F7 */ | ||
| 1188 | u64 tx_lip_f8f7; /* Tx LIP_F8F7 */ | ||
| 1189 | u64 tx_arbf0; /* Tx ARB F0 */ | ||
| 1115 | u64 tx_nos; /* Tx NOS */ | 1190 | u64 tx_nos; /* Tx NOS */ |
| 1116 | u64 tx_ols; /* Tx OLS */ | 1191 | u64 tx_ols; /* Tx OLS */ |
| 1117 | u64 tx_lr; /* Tx LR */ | 1192 | u64 tx_lr; /* Tx LR */ |
| @@ -1119,6 +1194,9 @@ struct bfa_port_fc_stats_s { | |||
| 1119 | u64 rx_frames; /* Rx frames */ | 1194 | u64 rx_frames; /* Rx frames */ |
| 1120 | u64 rx_words; /* Rx words */ | 1195 | u64 rx_words; /* Rx words */ |
| 1121 | u64 lip_count; /* Rx LIP */ | 1196 | u64 lip_count; /* Rx LIP */ |
| 1197 | u64 rx_lip_f7f7; /* Rx LIP_F7F7 */ | ||
| 1198 | u64 rx_lip_f8f7; /* Rx LIP_F8F7 */ | ||
| 1199 | u64 rx_arbf0; /* Rx ARB F0 */ | ||
| 1122 | u64 nos_count; /* Rx NOS */ | 1200 | u64 nos_count; /* Rx NOS */ |
| 1123 | u64 ols_count; /* Rx OLS */ | 1201 | u64 ols_count; /* Rx OLS */ |
| 1124 | u64 lr_count; /* Rx LR */ | 1202 | u64 lr_count; /* Rx LR */ |
| @@ -1140,6 +1218,7 @@ struct bfa_port_fc_stats_s { | |||
| 1140 | u64 bbsc_frames_lost; /* Credit Recovery-Frames Lost */ | 1218 | u64 bbsc_frames_lost; /* Credit Recovery-Frames Lost */ |
| 1141 | u64 bbsc_credits_lost; /* Credit Recovery-Credits Lost */ | 1219 | u64 bbsc_credits_lost; /* Credit Recovery-Credits Lost */ |
| 1142 | u64 bbsc_link_resets; /* Credit Recovery-Link Resets */ | 1220 | u64 bbsc_link_resets; /* Credit Recovery-Link Resets */ |
| 1221 | u64 loop_timeouts; /* Loop timeouts */ | ||
| 1143 | }; | 1222 | }; |
| 1144 | 1223 | ||
| 1145 | /* | 1224 | /* |
diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h index e0beb4d7e264..bea821b98030 100644 --- a/drivers/scsi/bfa/bfa_fc.h +++ b/drivers/scsi/bfa/bfa_fc.h | |||
| @@ -24,6 +24,7 @@ typedef u64 wwn_t; | |||
| 24 | 24 | ||
| 25 | #define WWN_NULL (0) | 25 | #define WWN_NULL (0) |
| 26 | #define FC_SYMNAME_MAX 256 /* max name server symbolic name size */ | 26 | #define FC_SYMNAME_MAX 256 /* max name server symbolic name size */ |
| 27 | #define FC_ALPA_MAX 128 | ||
| 27 | 28 | ||
| 28 | #pragma pack(1) | 29 | #pragma pack(1) |
| 29 | 30 | ||
| @@ -1015,6 +1016,10 @@ struct fc_symname_s { | |||
| 1015 | u8 symname[FC_SYMNAME_MAX]; | 1016 | u8 symname[FC_SYMNAME_MAX]; |
| 1016 | }; | 1017 | }; |
| 1017 | 1018 | ||
| 1019 | struct fc_alpabm_s { | ||
| 1020 | u8 alpa_bm[FC_ALPA_MAX / 8]; | ||
| 1021 | }; | ||
| 1022 | |||
| 1018 | /* | 1023 | /* |
| 1019 | * protocol default timeout values | 1024 | * protocol default timeout values |
| 1020 | */ | 1025 | */ |
diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c index 273cee90b3b4..dce787f6cca2 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.c +++ b/drivers/scsi/bfa/bfa_fcbuild.c | |||
| @@ -228,6 +228,10 @@ fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, | |||
| 228 | 228 | ||
| 229 | memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s)); | 229 | memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s)); |
| 230 | 230 | ||
| 231 | /* For FC AL bb_cr is 0 and altbbcred is 1 */ | ||
| 232 | if (!bb_cr) | ||
| 233 | plogi->csp.altbbcred = 1; | ||
| 234 | |||
| 231 | plogi->els_cmd.els_code = els_code; | 235 | plogi->els_cmd.els_code = els_code; |
| 232 | if (els_code == FC_ELS_PLOGI) | 236 | if (els_code == FC_ELS_PLOGI) |
| 233 | fc_els_req_build(fchs, d_id, s_id, ox_id); | 237 | fc_els_req_build(fchs, d_id, s_id, ox_id); |
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c index 1633963c66ca..27b560962357 100644 --- a/drivers/scsi/bfa/bfa_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcpim.c | |||
| @@ -158,6 +158,7 @@ enum bfa_tskim_event { | |||
| 158 | BFA_TSKIM_SM_IOS_DONE = 7, /* IO and sub TM completions */ | 158 | BFA_TSKIM_SM_IOS_DONE = 7, /* IO and sub TM completions */ |
| 159 | BFA_TSKIM_SM_CLEANUP = 8, /* TM cleanup on ITN offline */ | 159 | BFA_TSKIM_SM_CLEANUP = 8, /* TM cleanup on ITN offline */ |
| 160 | BFA_TSKIM_SM_CLEANUP_DONE = 9, /* TM abort completion */ | 160 | BFA_TSKIM_SM_CLEANUP_DONE = 9, /* TM abort completion */ |
| 161 | BFA_TSKIM_SM_UTAG = 10, /* TM completion unknown tag */ | ||
| 161 | }; | 162 | }; |
| 162 | 163 | ||
| 163 | /* | 164 | /* |
| @@ -3036,7 +3037,7 @@ bfa_ioim_abort(struct bfa_ioim_s *ioim) | |||
| 3036 | static void | 3037 | static void |
| 3037 | bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | 3038 | bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) |
| 3038 | { | 3039 | { |
| 3039 | bfa_trc(tskim->bfa, event); | 3040 | bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event); |
| 3040 | 3041 | ||
| 3041 | switch (event) { | 3042 | switch (event) { |
| 3042 | case BFA_TSKIM_SM_START: | 3043 | case BFA_TSKIM_SM_START: |
| @@ -3074,7 +3075,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
| 3074 | static void | 3075 | static void |
| 3075 | bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | 3076 | bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) |
| 3076 | { | 3077 | { |
| 3077 | bfa_trc(tskim->bfa, event); | 3078 | bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event); |
| 3078 | 3079 | ||
| 3079 | switch (event) { | 3080 | switch (event) { |
| 3080 | case BFA_TSKIM_SM_DONE: | 3081 | case BFA_TSKIM_SM_DONE: |
| @@ -3110,7 +3111,7 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
| 3110 | static void | 3111 | static void |
| 3111 | bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | 3112 | bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) |
| 3112 | { | 3113 | { |
| 3113 | bfa_trc(tskim->bfa, event); | 3114 | bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event); |
| 3114 | 3115 | ||
| 3115 | switch (event) { | 3116 | switch (event) { |
| 3116 | case BFA_TSKIM_SM_DONE: | 3117 | case BFA_TSKIM_SM_DONE: |
| @@ -3119,6 +3120,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
| 3119 | */ | 3120 | */ |
| 3120 | break; | 3121 | break; |
| 3121 | 3122 | ||
| 3123 | case BFA_TSKIM_SM_UTAG: | ||
| 3122 | case BFA_TSKIM_SM_CLEANUP_DONE: | 3124 | case BFA_TSKIM_SM_CLEANUP_DONE: |
| 3123 | bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup); | 3125 | bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup); |
| 3124 | bfa_tskim_cleanup_ios(tskim); | 3126 | bfa_tskim_cleanup_ios(tskim); |
| @@ -3138,7 +3140,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
| 3138 | static void | 3140 | static void |
| 3139 | bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | 3141 | bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) |
| 3140 | { | 3142 | { |
| 3141 | bfa_trc(tskim->bfa, event); | 3143 | bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event); |
| 3142 | 3144 | ||
| 3143 | switch (event) { | 3145 | switch (event) { |
| 3144 | case BFA_TSKIM_SM_IOS_DONE: | 3146 | case BFA_TSKIM_SM_IOS_DONE: |
| @@ -3170,7 +3172,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
| 3170 | static void | 3172 | static void |
| 3171 | bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | 3173 | bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) |
| 3172 | { | 3174 | { |
| 3173 | bfa_trc(tskim->bfa, event); | 3175 | bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event); |
| 3174 | 3176 | ||
| 3175 | switch (event) { | 3177 | switch (event) { |
| 3176 | case BFA_TSKIM_SM_QRESUME: | 3178 | case BFA_TSKIM_SM_QRESUME: |
| @@ -3207,7 +3209,7 @@ static void | |||
| 3207 | bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim, | 3209 | bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim, |
| 3208 | enum bfa_tskim_event event) | 3210 | enum bfa_tskim_event event) |
| 3209 | { | 3211 | { |
| 3210 | bfa_trc(tskim->bfa, event); | 3212 | bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event); |
| 3211 | 3213 | ||
| 3212 | switch (event) { | 3214 | switch (event) { |
| 3213 | case BFA_TSKIM_SM_DONE: | 3215 | case BFA_TSKIM_SM_DONE: |
| @@ -3238,7 +3240,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim, | |||
| 3238 | static void | 3240 | static void |
| 3239 | bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | 3241 | bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) |
| 3240 | { | 3242 | { |
| 3241 | bfa_trc(tskim->bfa, event); | 3243 | bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event); |
| 3242 | 3244 | ||
| 3243 | switch (event) { | 3245 | switch (event) { |
| 3244 | case BFA_TSKIM_SM_HCB: | 3246 | case BFA_TSKIM_SM_HCB: |
| @@ -3560,6 +3562,8 @@ bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) | |||
| 3560 | if (rsp->tsk_status == BFI_TSKIM_STS_ABORTED) { | 3562 | if (rsp->tsk_status == BFI_TSKIM_STS_ABORTED) { |
| 3561 | bfa_stats(tskim->itnim, tm_cleanup_comps); | 3563 | bfa_stats(tskim->itnim, tm_cleanup_comps); |
| 3562 | bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP_DONE); | 3564 | bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP_DONE); |
| 3565 | } else if (rsp->tsk_status == BFI_TSKIM_STS_UTAG) { | ||
| 3566 | bfa_sm_send_event(tskim, BFA_TSKIM_SM_UTAG); | ||
| 3563 | } else { | 3567 | } else { |
| 3564 | bfa_stats(tskim->itnim, tm_fw_rsps); | 3568 | bfa_stats(tskim->itnim, tm_fw_rsps); |
| 3565 | bfa_sm_send_event(tskim, BFA_TSKIM_SM_DONE); | 3569 | bfa_sm_send_event(tskim, BFA_TSKIM_SM_DONE); |
| @@ -3699,6 +3703,7 @@ bfa_fcp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
| 3699 | struct bfa_mem_dma_s *seg_ptr; | 3703 | struct bfa_mem_dma_s *seg_ptr; |
| 3700 | u16 idx, nsegs, num_io_req; | 3704 | u16 idx, nsegs, num_io_req; |
| 3701 | 3705 | ||
| 3706 | fcp->max_ioim_reqs = cfg->fwcfg.num_ioim_reqs; | ||
| 3702 | fcp->num_ioim_reqs = cfg->fwcfg.num_ioim_reqs; | 3707 | fcp->num_ioim_reqs = cfg->fwcfg.num_ioim_reqs; |
| 3703 | fcp->num_fwtio_reqs = cfg->fwcfg.num_fwtio_reqs; | 3708 | fcp->num_fwtio_reqs = cfg->fwcfg.num_fwtio_reqs; |
| 3704 | fcp->num_itns = cfg->fwcfg.num_rports; | 3709 | fcp->num_itns = cfg->fwcfg.num_rports; |
| @@ -3721,6 +3726,7 @@ bfa_fcp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
| 3721 | bfa_iocfc_set_snsbase(bfa, idx, fcp->snsbase[idx].pa); | 3726 | bfa_iocfc_set_snsbase(bfa, idx, fcp->snsbase[idx].pa); |
| 3722 | } | 3727 | } |
| 3723 | 3728 | ||
| 3729 | fcp->throttle_update_required = 1; | ||
| 3724 | bfa_fcpim_attach(fcp, bfad, cfg, pcidev); | 3730 | bfa_fcpim_attach(fcp, bfad, cfg, pcidev); |
| 3725 | 3731 | ||
| 3726 | bfa_iotag_attach(fcp); | 3732 | bfa_iotag_attach(fcp); |
| @@ -3759,23 +3765,33 @@ bfa_fcp_iocdisable(struct bfa_s *bfa) | |||
| 3759 | { | 3765 | { |
| 3760 | struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa); | 3766 | struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa); |
| 3761 | 3767 | ||
| 3762 | /* Enqueue unused ioim resources to free_q */ | ||
| 3763 | list_splice_tail_init(&fcp->iotag_unused_q, &fcp->iotag_ioim_free_q); | ||
| 3764 | |||
| 3765 | bfa_fcpim_iocdisable(fcp); | 3768 | bfa_fcpim_iocdisable(fcp); |
| 3766 | } | 3769 | } |
| 3767 | 3770 | ||
| 3768 | void | 3771 | void |
| 3769 | bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw) | 3772 | bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw, u16 max_ioim_fw) |
| 3770 | { | 3773 | { |
| 3771 | struct bfa_fcp_mod_s *mod = BFA_FCP_MOD(bfa); | 3774 | struct bfa_fcp_mod_s *mod = BFA_FCP_MOD(bfa); |
| 3772 | struct list_head *qe; | 3775 | struct list_head *qe; |
| 3773 | int i; | 3776 | int i; |
| 3774 | 3777 | ||
| 3778 | /* Update io throttle value only once during driver load time */ | ||
| 3779 | if (!mod->throttle_update_required) | ||
| 3780 | return; | ||
| 3781 | |||
| 3775 | for (i = 0; i < (mod->num_ioim_reqs - num_ioim_fw); i++) { | 3782 | for (i = 0; i < (mod->num_ioim_reqs - num_ioim_fw); i++) { |
| 3776 | bfa_q_deq_tail(&mod->iotag_ioim_free_q, &qe); | 3783 | bfa_q_deq_tail(&mod->iotag_ioim_free_q, &qe); |
| 3777 | list_add_tail(qe, &mod->iotag_unused_q); | 3784 | list_add_tail(qe, &mod->iotag_unused_q); |
| 3778 | } | 3785 | } |
| 3786 | |||
| 3787 | if (mod->num_ioim_reqs != num_ioim_fw) { | ||
| 3788 | bfa_trc(bfa, mod->num_ioim_reqs); | ||
| 3789 | bfa_trc(bfa, num_ioim_fw); | ||
| 3790 | } | ||
| 3791 | |||
| 3792 | mod->max_ioim_reqs = max_ioim_fw; | ||
| 3793 | mod->num_ioim_reqs = num_ioim_fw; | ||
| 3794 | mod->throttle_update_required = 0; | ||
| 3779 | } | 3795 | } |
| 3780 | 3796 | ||
| 3781 | void | 3797 | void |
| @@ -3833,3 +3849,88 @@ bfa_iotag_attach(struct bfa_fcp_mod_s *fcp) | |||
| 3833 | 3849 | ||
| 3834 | bfa_mem_kva_curp(fcp) = (u8 *) iotag; | 3850 | bfa_mem_kva_curp(fcp) = (u8 *) iotag; |
| 3835 | } | 3851 | } |
| 3852 | |||
| 3853 | |||
| 3854 | /** | ||
| 3855 | * To send config req, first try to use throttle value from flash | ||
| 3856 | * If 0, then use driver parameter | ||
| 3857 | * We need to use min(flash_val, drv_val) because | ||
| 3858 | * memory allocation was done based on this cfg'd value | ||
| 3859 | */ | ||
| 3860 | u16 | ||
| 3861 | bfa_fcpim_get_throttle_cfg(struct bfa_s *bfa, u16 drv_cfg_param) | ||
| 3862 | { | ||
| 3863 | u16 tmp; | ||
| 3864 | struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa); | ||
| 3865 | |||
| 3866 | /* | ||
| 3867 | * If throttle value from flash is already in effect after driver is | ||
| 3868 | * loaded then until next load, always return current value instead | ||
| 3869 | * of actual flash value | ||
| 3870 | */ | ||
| 3871 | if (!fcp->throttle_update_required) | ||
| 3872 | return (u16)fcp->num_ioim_reqs; | ||
| 3873 | |||
| 3874 | tmp = bfa_dconf_read_data_valid(bfa) ? bfa_fcpim_read_throttle(bfa) : 0; | ||
| 3875 | if (!tmp || (tmp > drv_cfg_param)) | ||
| 3876 | tmp = drv_cfg_param; | ||
| 3877 | |||
| 3878 | return tmp; | ||
| 3879 | } | ||
| 3880 | |||
| 3881 | bfa_status_t | ||
| 3882 | bfa_fcpim_write_throttle(struct bfa_s *bfa, u16 value) | ||
| 3883 | { | ||
| 3884 | if (!bfa_dconf_get_min_cfg(bfa)) { | ||
| 3885 | BFA_DCONF_MOD(bfa)->dconf->throttle_cfg.value = value; | ||
| 3886 | BFA_DCONF_MOD(bfa)->dconf->throttle_cfg.is_valid = 1; | ||
| 3887 | return BFA_STATUS_OK; | ||
| 3888 | } | ||
| 3889 | |||
| 3890 | return BFA_STATUS_FAILED; | ||
| 3891 | } | ||
| 3892 | |||
| 3893 | u16 | ||
| 3894 | bfa_fcpim_read_throttle(struct bfa_s *bfa) | ||
| 3895 | { | ||
| 3896 | struct bfa_throttle_cfg_s *throttle_cfg = | ||
| 3897 | &(BFA_DCONF_MOD(bfa)->dconf->throttle_cfg); | ||
| 3898 | |||
| 3899 | return ((!bfa_dconf_get_min_cfg(bfa)) ? | ||
| 3900 | ((throttle_cfg->is_valid == 1) ? (throttle_cfg->value) : 0) : 0); | ||
| 3901 | } | ||
| 3902 | |||
| 3903 | bfa_status_t | ||
| 3904 | bfa_fcpim_throttle_set(struct bfa_s *bfa, u16 value) | ||
| 3905 | { | ||
| 3906 | /* in min cfg no commands should run. */ | ||
| 3907 | if ((bfa_dconf_get_min_cfg(bfa) == BFA_TRUE) || | ||
| 3908 | (!bfa_dconf_read_data_valid(bfa))) | ||
| 3909 | return BFA_STATUS_FAILED; | ||
| 3910 | |||
| 3911 | bfa_fcpim_write_throttle(bfa, value); | ||
| 3912 | |||
| 3913 | return bfa_dconf_update(bfa); | ||
| 3914 | } | ||
| 3915 | |||
| 3916 | bfa_status_t | ||
| 3917 | bfa_fcpim_throttle_get(struct bfa_s *bfa, void *buf) | ||
| 3918 | { | ||
| 3919 | struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); | ||
| 3920 | struct bfa_defs_fcpim_throttle_s throttle; | ||
| 3921 | |||
| 3922 | if ((bfa_dconf_get_min_cfg(bfa) == BFA_TRUE) || | ||
| 3923 | (!bfa_dconf_read_data_valid(bfa))) | ||
| 3924 | return BFA_STATUS_FAILED; | ||
| 3925 | |||
| 3926 | memset(&throttle, 0, sizeof(struct bfa_defs_fcpim_throttle_s)); | ||
| 3927 | |||
| 3928 | throttle.cur_value = (u16)(fcpim->fcp->num_ioim_reqs); | ||
| 3929 | throttle.cfg_value = bfa_fcpim_read_throttle(bfa); | ||
| 3930 | if (!throttle.cfg_value) | ||
| 3931 | throttle.cfg_value = throttle.cur_value; | ||
| 3932 | throttle.max_value = (u16)(fcpim->fcp->max_ioim_reqs); | ||
| 3933 | memcpy(buf, &throttle, sizeof(struct bfa_defs_fcpim_throttle_s)); | ||
| 3934 | |||
| 3935 | return BFA_STATUS_OK; | ||
| 3936 | } | ||
diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h index 36f26da80f76..e693af6e5930 100644 --- a/drivers/scsi/bfa/bfa_fcpim.h +++ b/drivers/scsi/bfa/bfa_fcpim.h | |||
| @@ -42,7 +42,7 @@ void bfa_itn_create(struct bfa_s *bfa, struct bfa_rport_s *rport, | |||
| 42 | void (*isr)(struct bfa_s *bfa, struct bfi_msg_s *m)); | 42 | void (*isr)(struct bfa_s *bfa, struct bfi_msg_s *m)); |
| 43 | void bfa_itn_isr(struct bfa_s *bfa, struct bfi_msg_s *m); | 43 | void bfa_itn_isr(struct bfa_s *bfa, struct bfi_msg_s *m); |
| 44 | void bfa_iotag_attach(struct bfa_fcp_mod_s *fcp); | 44 | void bfa_iotag_attach(struct bfa_fcp_mod_s *fcp); |
| 45 | void bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw); | 45 | void bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw, u16 max_ioim_fw); |
| 46 | 46 | ||
| 47 | #define BFA_FCP_MOD(_hal) (&(_hal)->modules.fcp_mod) | 47 | #define BFA_FCP_MOD(_hal) (&(_hal)->modules.fcp_mod) |
| 48 | #define BFA_MEM_FCP_KVA(__bfa) (&(BFA_FCP_MOD(__bfa)->kva_seg)) | 48 | #define BFA_MEM_FCP_KVA(__bfa) (&(BFA_FCP_MOD(__bfa)->kva_seg)) |
| @@ -51,7 +51,9 @@ void bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw); | |||
| 51 | #define BFA_ITN_FROM_TAG(_fcp, _tag) \ | 51 | #define BFA_ITN_FROM_TAG(_fcp, _tag) \ |
| 52 | ((_fcp)->itn_arr + ((_tag) & ((_fcp)->num_itns - 1))) | 52 | ((_fcp)->itn_arr + ((_tag) & ((_fcp)->num_itns - 1))) |
| 53 | #define BFA_SNSINFO_FROM_TAG(_fcp, _tag) \ | 53 | #define BFA_SNSINFO_FROM_TAG(_fcp, _tag) \ |
| 54 | bfa_mem_get_dmabuf_kva(_fcp, _tag, BFI_IOIM_SNSLEN) | 54 | bfa_mem_get_dmabuf_kva(_fcp, (_tag & BFA_IOIM_IOTAG_MASK), \ |
| 55 | BFI_IOIM_SNSLEN) | ||
| 56 | |||
| 55 | 57 | ||
| 56 | #define BFA_ITNIM_MIN 32 | 58 | #define BFA_ITNIM_MIN 32 |
| 57 | #define BFA_ITNIM_MAX 1024 | 59 | #define BFA_ITNIM_MAX 1024 |
| @@ -148,6 +150,7 @@ struct bfa_fcp_mod_s { | |||
| 148 | struct list_head iotag_unused_q; /* unused IO resources*/ | 150 | struct list_head iotag_unused_q; /* unused IO resources*/ |
| 149 | struct bfa_iotag_s *iotag_arr; | 151 | struct bfa_iotag_s *iotag_arr; |
| 150 | struct bfa_itn_s *itn_arr; | 152 | struct bfa_itn_s *itn_arr; |
| 153 | int max_ioim_reqs; | ||
| 151 | int num_ioim_reqs; | 154 | int num_ioim_reqs; |
| 152 | int num_fwtio_reqs; | 155 | int num_fwtio_reqs; |
| 153 | int num_itns; | 156 | int num_itns; |
| @@ -155,6 +158,7 @@ struct bfa_fcp_mod_s { | |||
| 155 | struct bfa_fcpim_s fcpim; | 158 | struct bfa_fcpim_s fcpim; |
| 156 | struct bfa_mem_dma_s dma_seg[BFA_FCP_DMA_SEGS]; | 159 | struct bfa_mem_dma_s dma_seg[BFA_FCP_DMA_SEGS]; |
| 157 | struct bfa_mem_kva_s kva_seg; | 160 | struct bfa_mem_kva_s kva_seg; |
| 161 | int throttle_update_required; | ||
| 158 | }; | 162 | }; |
| 159 | 163 | ||
| 160 | /* | 164 | /* |
| @@ -416,5 +420,10 @@ bfa_status_t bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id, | |||
| 416 | bfa_status_t bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id, | 420 | bfa_status_t bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id, |
| 417 | wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun); | 421 | wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun); |
| 418 | bfa_status_t bfa_fcpim_lunmask_clear(struct bfa_s *bfa); | 422 | bfa_status_t bfa_fcpim_lunmask_clear(struct bfa_s *bfa); |
| 423 | u16 bfa_fcpim_read_throttle(struct bfa_s *bfa); | ||
| 424 | bfa_status_t bfa_fcpim_write_throttle(struct bfa_s *bfa, u16 value); | ||
| 425 | bfa_status_t bfa_fcpim_throttle_set(struct bfa_s *bfa, u16 value); | ||
| 426 | bfa_status_t bfa_fcpim_throttle_get(struct bfa_s *bfa, void *buf); | ||
| 427 | u16 bfa_fcpim_get_throttle_cfg(struct bfa_s *bfa, u16 drv_cfg_param); | ||
| 419 | 428 | ||
| 420 | #endif /* __BFA_FCPIM_H__ */ | 429 | #endif /* __BFA_FCPIM_H__ */ |
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index fd3e84d32bd2..d428808fb37e 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c | |||
| @@ -303,16 +303,30 @@ static void | |||
| 303 | bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric, | 303 | bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric, |
| 304 | enum bfa_fcs_fabric_event event) | 304 | enum bfa_fcs_fabric_event event) |
| 305 | { | 305 | { |
| 306 | struct bfa_s *bfa = fabric->fcs->bfa; | ||
| 307 | |||
| 306 | bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); | 308 | bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); |
| 307 | bfa_trc(fabric->fcs, event); | 309 | bfa_trc(fabric->fcs, event); |
| 308 | 310 | ||
| 309 | switch (event) { | 311 | switch (event) { |
| 310 | case BFA_FCS_FABRIC_SM_START: | 312 | case BFA_FCS_FABRIC_SM_START: |
| 311 | if (bfa_fcport_is_linkup(fabric->fcs->bfa)) { | 313 | if (!bfa_fcport_is_linkup(fabric->fcs->bfa)) { |
| 314 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); | ||
| 315 | break; | ||
| 316 | } | ||
| 317 | if (bfa_fcport_get_topology(bfa) == | ||
| 318 | BFA_PORT_TOPOLOGY_LOOP) { | ||
| 319 | fabric->fab_type = BFA_FCS_FABRIC_LOOP; | ||
| 320 | fabric->bport.pid = bfa_fcport_get_myalpa(bfa); | ||
| 321 | fabric->bport.pid = bfa_hton3b(fabric->bport.pid); | ||
| 322 | bfa_sm_set_state(fabric, | ||
| 323 | bfa_fcs_fabric_sm_online); | ||
| 324 | bfa_fcs_fabric_set_opertype(fabric); | ||
| 325 | bfa_fcs_lport_online(&fabric->bport); | ||
| 326 | } else { | ||
| 312 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); | 327 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); |
| 313 | bfa_fcs_fabric_login(fabric); | 328 | bfa_fcs_fabric_login(fabric); |
| 314 | } else | 329 | } |
| 315 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); | ||
| 316 | break; | 330 | break; |
| 317 | 331 | ||
| 318 | case BFA_FCS_FABRIC_SM_LINK_UP: | 332 | case BFA_FCS_FABRIC_SM_LINK_UP: |
| @@ -337,16 +351,28 @@ static void | |||
| 337 | bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric, | 351 | bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric, |
| 338 | enum bfa_fcs_fabric_event event) | 352 | enum bfa_fcs_fabric_event event) |
| 339 | { | 353 | { |
| 354 | struct bfa_s *bfa = fabric->fcs->bfa; | ||
| 355 | |||
| 340 | bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); | 356 | bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); |
| 341 | bfa_trc(fabric->fcs, event); | 357 | bfa_trc(fabric->fcs, event); |
| 342 | 358 | ||
| 343 | switch (event) { | 359 | switch (event) { |
| 344 | case BFA_FCS_FABRIC_SM_LINK_UP: | 360 | case BFA_FCS_FABRIC_SM_LINK_UP: |
| 345 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); | 361 | if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) { |
| 346 | bfa_fcs_fabric_login(fabric); | 362 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); |
| 363 | bfa_fcs_fabric_login(fabric); | ||
| 364 | break; | ||
| 365 | } | ||
| 366 | fabric->fab_type = BFA_FCS_FABRIC_LOOP; | ||
| 367 | fabric->bport.pid = bfa_fcport_get_myalpa(bfa); | ||
| 368 | fabric->bport.pid = bfa_hton3b(fabric->bport.pid); | ||
| 369 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online); | ||
| 370 | bfa_fcs_fabric_set_opertype(fabric); | ||
| 371 | bfa_fcs_lport_online(&fabric->bport); | ||
| 347 | break; | 372 | break; |
| 348 | 373 | ||
| 349 | case BFA_FCS_FABRIC_SM_RETRY_OP: | 374 | case BFA_FCS_FABRIC_SM_RETRY_OP: |
| 375 | case BFA_FCS_FABRIC_SM_LOOPBACK: | ||
| 350 | break; | 376 | break; |
| 351 | 377 | ||
| 352 | case BFA_FCS_FABRIC_SM_DELETE: | 378 | case BFA_FCS_FABRIC_SM_DELETE: |
| @@ -595,14 +621,20 @@ void | |||
| 595 | bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric, | 621 | bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric, |
| 596 | enum bfa_fcs_fabric_event event) | 622 | enum bfa_fcs_fabric_event event) |
| 597 | { | 623 | { |
| 624 | struct bfa_s *bfa = fabric->fcs->bfa; | ||
| 625 | |||
| 598 | bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); | 626 | bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); |
| 599 | bfa_trc(fabric->fcs, event); | 627 | bfa_trc(fabric->fcs, event); |
| 600 | 628 | ||
| 601 | switch (event) { | 629 | switch (event) { |
| 602 | case BFA_FCS_FABRIC_SM_LINK_DOWN: | 630 | case BFA_FCS_FABRIC_SM_LINK_DOWN: |
| 603 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); | 631 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); |
| 604 | bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE); | 632 | if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) { |
| 605 | bfa_fcs_fabric_notify_offline(fabric); | 633 | bfa_fcs_lport_offline(&fabric->bport); |
| 634 | } else { | ||
| 635 | bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE); | ||
| 636 | bfa_fcs_fabric_notify_offline(fabric); | ||
| 637 | } | ||
| 606 | break; | 638 | break; |
| 607 | 639 | ||
| 608 | case BFA_FCS_FABRIC_SM_DELETE: | 640 | case BFA_FCS_FABRIC_SM_DELETE: |
| @@ -719,20 +751,29 @@ static void | |||
| 719 | bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric, | 751 | bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric, |
| 720 | enum bfa_fcs_fabric_event event) | 752 | enum bfa_fcs_fabric_event event) |
| 721 | { | 753 | { |
| 754 | struct bfa_s *bfa = fabric->fcs->bfa; | ||
| 755 | |||
| 722 | bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); | 756 | bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); |
| 723 | bfa_trc(fabric->fcs, event); | 757 | bfa_trc(fabric->fcs, event); |
| 724 | 758 | ||
| 725 | switch (event) { | 759 | switch (event) { |
| 726 | case BFA_FCS_FABRIC_SM_STOPCOMP: | 760 | case BFA_FCS_FABRIC_SM_STOPCOMP: |
| 727 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup); | 761 | if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) { |
| 728 | bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT); | 762 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created); |
| 763 | } else { | ||
| 764 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup); | ||
| 765 | bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT); | ||
| 766 | } | ||
| 729 | break; | 767 | break; |
| 730 | 768 | ||
| 731 | case BFA_FCS_FABRIC_SM_LINK_UP: | 769 | case BFA_FCS_FABRIC_SM_LINK_UP: |
| 732 | break; | 770 | break; |
| 733 | 771 | ||
| 734 | case BFA_FCS_FABRIC_SM_LINK_DOWN: | 772 | case BFA_FCS_FABRIC_SM_LINK_DOWN: |
| 735 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup); | 773 | if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) |
| 774 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created); | ||
| 775 | else | ||
| 776 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup); | ||
| 736 | break; | 777 | break; |
| 737 | 778 | ||
| 738 | default: | 779 | default: |
| @@ -975,9 +1016,6 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric) | |||
| 975 | struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg; | 1016 | struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg; |
| 976 | u8 alpa = 0, bb_scn = 0; | 1017 | u8 alpa = 0, bb_scn = 0; |
| 977 | 1018 | ||
| 978 | if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) | ||
| 979 | alpa = bfa_fcport_get_myalpa(bfa); | ||
| 980 | |||
| 981 | if (bfa_fcs_fabric_is_bbscn_enabled(fabric) && | 1019 | if (bfa_fcs_fabric_is_bbscn_enabled(fabric) && |
| 982 | (!fabric->fcs->bbscn_flogi_rjt)) | 1020 | (!fabric->fcs->bbscn_flogi_rjt)) |
| 983 | bb_scn = BFA_FCS_PORT_DEF_BB_SCN; | 1021 | bb_scn = BFA_FCS_PORT_DEF_BB_SCN; |
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 6c4377cb287f..a449706c6bc0 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h | |||
| @@ -118,9 +118,9 @@ struct bfa_fcs_lport_fab_s { | |||
| 118 | #define MAX_ALPA_COUNT 127 | 118 | #define MAX_ALPA_COUNT 127 |
| 119 | 119 | ||
| 120 | struct bfa_fcs_lport_loop_s { | 120 | struct bfa_fcs_lport_loop_s { |
| 121 | u8 num_alpa; /* Num of ALPA entries in the map */ | 121 | u8 num_alpa; /* Num of ALPA entries in the map */ |
| 122 | u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional | 122 | u8 alpabm_valid; /* alpa bitmap valid or not (1 or 0) */ |
| 123 | *Map */ | 123 | u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional Map */ |
| 124 | struct bfa_fcs_lport_s *port; /* parent port */ | 124 | struct bfa_fcs_lport_s *port; /* parent port */ |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| @@ -175,6 +175,7 @@ enum bfa_fcs_fabric_type { | |||
| 175 | BFA_FCS_FABRIC_UNKNOWN = 0, | 175 | BFA_FCS_FABRIC_UNKNOWN = 0, |
| 176 | BFA_FCS_FABRIC_SWITCHED = 1, | 176 | BFA_FCS_FABRIC_SWITCHED = 1, |
| 177 | BFA_FCS_FABRIC_N2N = 2, | 177 | BFA_FCS_FABRIC_N2N = 2, |
| 178 | BFA_FCS_FABRIC_LOOP = 3, | ||
| 178 | }; | 179 | }; |
| 179 | 180 | ||
| 180 | 181 | ||
| @@ -350,9 +351,10 @@ void bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, | |||
| 350 | struct bfa_fcxp_s *fcxp_alloced); | 351 | struct bfa_fcxp_s *fcxp_alloced); |
| 351 | void bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *vport); | 352 | void bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *vport); |
| 352 | void bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *vport); | 353 | void bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *vport); |
| 353 | void bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *vport); | 354 | void bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *vport); |
| 354 | void bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port, | 355 | void bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port, |
| 355 | struct fchs_s *rx_frame, u32 len); | 356 | struct fchs_s *rx_frame, u32 len); |
| 357 | void bfa_fcs_lport_lip_scn_online(bfa_fcs_lport_t *port); | ||
| 356 | 358 | ||
| 357 | struct bfa_fcs_vport_s { | 359 | struct bfa_fcs_vport_s { |
| 358 | struct list_head qe; /* queue elem */ | 360 | struct list_head qe; /* queue elem */ |
| @@ -453,6 +455,7 @@ struct bfa_fcs_rport_s { | |||
| 453 | struct bfa_rport_stats_s stats; /* rport stats */ | 455 | struct bfa_rport_stats_s stats; /* rport stats */ |
| 454 | enum bfa_rport_function scsi_function; /* Initiator/Target */ | 456 | enum bfa_rport_function scsi_function; /* Initiator/Target */ |
| 455 | struct bfa_fcs_rpf_s rpf; /* Rport features module */ | 457 | struct bfa_fcs_rpf_s rpf; /* Rport features module */ |
| 458 | bfa_boolean_t scn_online; /* SCN online flag */ | ||
| 456 | }; | 459 | }; |
| 457 | 460 | ||
| 458 | static inline struct bfa_rport_s * | 461 | static inline struct bfa_rport_s * |
| @@ -639,9 +642,9 @@ struct bfa_fcs_fdmi_hba_attr_s { | |||
| 639 | u8 model[16]; | 642 | u8 model[16]; |
| 640 | u8 model_desc[256]; | 643 | u8 model_desc[256]; |
| 641 | u8 hw_version[8]; | 644 | u8 hw_version[8]; |
| 642 | u8 driver_version[8]; | 645 | u8 driver_version[BFA_VERSION_LEN]; |
| 643 | u8 option_rom_ver[BFA_VERSION_LEN]; | 646 | u8 option_rom_ver[BFA_VERSION_LEN]; |
| 644 | u8 fw_version[8]; | 647 | u8 fw_version[BFA_VERSION_LEN]; |
| 645 | u8 os_name[256]; | 648 | u8 os_name[256]; |
| 646 | __be32 max_ct_pyld; | 649 | __be32 max_ct_pyld; |
| 647 | }; | 650 | }; |
| @@ -733,7 +736,7 @@ enum rport_event { | |||
| 733 | RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */ | 736 | RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */ |
| 734 | RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */ | 737 | RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */ |
| 735 | RPSM_EVENT_DELETE = 7, /* RPORT delete request */ | 738 | RPSM_EVENT_DELETE = 7, /* RPORT delete request */ |
| 736 | RPSM_EVENT_SCN = 8, /* state change notification */ | 739 | RPSM_EVENT_FAB_SCN = 8, /* state change notification */ |
| 737 | RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */ | 740 | RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */ |
| 738 | RPSM_EVENT_FAILED = 10, /* Request to rport failed. */ | 741 | RPSM_EVENT_FAILED = 10, /* Request to rport failed. */ |
| 739 | RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */ | 742 | RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */ |
| @@ -744,7 +747,9 @@ enum rport_event { | |||
| 744 | RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */ | 747 | RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */ |
| 745 | RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */ | 748 | RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */ |
| 746 | RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continuously */ | 749 | RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continuously */ |
| 747 | RPSM_EVENT_FC4_FCS_ONLINE = 19, /*!< FC-4 FCS online complete */ | 750 | RPSM_EVENT_SCN_OFFLINE = 19, /* loop scn offline */ |
| 751 | RPSM_EVENT_SCN_ONLINE = 20, /* loop scn online */ | ||
| 752 | RPSM_EVENT_FC4_FCS_ONLINE = 21, /* FC-4 FCS online complete */ | ||
| 748 | }; | 753 | }; |
| 749 | 754 | ||
| 750 | /* | 755 | /* |
| @@ -763,7 +768,7 @@ enum bfa_fcs_itnim_event { | |||
| 763 | BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */ | 768 | BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */ |
| 764 | BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */ | 769 | BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */ |
| 765 | BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */ | 770 | BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */ |
| 766 | BFA_FCS_ITNIM_SM_HAL_ONLINE = 13, /*!< bfa rport online event */ | 771 | BFA_FCS_ITNIM_SM_HAL_ONLINE = 13, /* bfa rport online event */ |
| 767 | }; | 772 | }; |
| 768 | 773 | ||
| 769 | /* | 774 | /* |
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 3b75f6fb2de1..1224d0462a49 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c | |||
| @@ -23,6 +23,34 @@ | |||
| 23 | 23 | ||
| 24 | BFA_TRC_FILE(FCS, PORT); | 24 | BFA_TRC_FILE(FCS, PORT); |
| 25 | 25 | ||
| 26 | /* | ||
| 27 | * ALPA to LIXA bitmap mapping | ||
| 28 | * | ||
| 29 | * ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31 | ||
| 30 | * is for L_bit (login required) and is filled as ALPA 0x00 here. | ||
| 31 | */ | ||
| 32 | static const u8 loop_alpa_map[] = { | ||
| 33 | 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, /* Word 0 Bits 31..24 */ | ||
| 34 | 0x17, 0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25, /* Word 0 Bits 23..16 */ | ||
| 35 | 0x26, 0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, /* Word 0 Bits 15..08 */ | ||
| 36 | 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, /* Word 0 Bits 07..00 */ | ||
| 37 | |||
| 38 | 0x3C, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, /* Word 1 Bits 31..24 */ | ||
| 39 | 0x4C, 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, /* Word 1 Bits 23..16 */ | ||
| 40 | 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67, /* Word 1 Bits 15..08 */ | ||
| 41 | 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, /* Word 1 Bits 07..00 */ | ||
| 42 | |||
| 43 | 0x73, 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, /* Word 2 Bits 31..24 */ | ||
| 44 | 0x81, 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, /* Word 2 Bits 23..16 */ | ||
| 45 | 0x9B, 0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, /* Word 2 Bits 15..08 */ | ||
| 46 | 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, /* Word 2 Bits 07..00 */ | ||
| 47 | |||
| 48 | 0xB3, 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3, /* Word 3 Bits 31..24 */ | ||
| 49 | 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, /* Word 3 Bits 23..16 */ | ||
| 50 | 0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, /* Word 3 Bits 15..08 */ | ||
| 51 | 0xDA, 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF, /* Word 3 Bits 07..00 */ | ||
| 52 | }; | ||
| 53 | |||
| 26 | static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, | 54 | static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, |
| 27 | struct fchs_s *rx_fchs, u8 reason_code, | 55 | struct fchs_s *rx_fchs, u8 reason_code, |
| 28 | u8 reason_code_expl); | 56 | u8 reason_code_expl); |
| @@ -51,6 +79,10 @@ static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port); | |||
| 51 | static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port); | 79 | static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port); |
| 52 | static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port); | 80 | static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port); |
| 53 | 81 | ||
| 82 | static void bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port); | ||
| 83 | static void bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port); | ||
| 84 | static void bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port); | ||
| 85 | |||
| 54 | static struct { | 86 | static struct { |
| 55 | void (*init) (struct bfa_fcs_lport_s *port); | 87 | void (*init) (struct bfa_fcs_lport_s *port); |
| 56 | void (*online) (struct bfa_fcs_lport_s *port); | 88 | void (*online) (struct bfa_fcs_lport_s *port); |
| @@ -62,7 +94,9 @@ static struct { | |||
| 62 | bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online, | 94 | bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online, |
| 63 | bfa_fcs_lport_fab_offline}, { | 95 | bfa_fcs_lport_fab_offline}, { |
| 64 | bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online, | 96 | bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online, |
| 65 | bfa_fcs_lport_n2n_offline}, | 97 | bfa_fcs_lport_n2n_offline}, { |
| 98 | bfa_fcs_lport_loop_init, bfa_fcs_lport_loop_online, | ||
| 99 | bfa_fcs_lport_loop_offline}, | ||
| 66 | }; | 100 | }; |
| 67 | 101 | ||
| 68 | /* | 102 | /* |
| @@ -1127,7 +1161,7 @@ static void | |||
| 1127 | bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port) | 1161 | bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port) |
| 1128 | { | 1162 | { |
| 1129 | bfa_fcs_lport_ns_online(port); | 1163 | bfa_fcs_lport_ns_online(port); |
| 1130 | bfa_fcs_lport_scn_online(port); | 1164 | bfa_fcs_lport_fab_scn_online(port); |
| 1131 | } | 1165 | } |
| 1132 | 1166 | ||
| 1133 | /* | 1167 | /* |
| @@ -1221,6 +1255,98 @@ bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port) | |||
| 1221 | n2n_port->reply_oxid = 0; | 1255 | n2n_port->reply_oxid = 0; |
| 1222 | } | 1256 | } |
| 1223 | 1257 | ||
| 1258 | void | ||
| 1259 | bfa_fcport_get_loop_attr(struct bfa_fcs_lport_s *port) | ||
| 1260 | { | ||
| 1261 | int i = 0, j = 0, bit = 0, alpa_bit = 0; | ||
| 1262 | u8 k = 0; | ||
| 1263 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(port->fcs->bfa); | ||
| 1264 | |||
| 1265 | port->port_topo.ploop.alpabm_valid = fcport->alpabm_valid; | ||
| 1266 | port->pid = fcport->myalpa; | ||
| 1267 | port->pid = bfa_hton3b(port->pid); | ||
| 1268 | |||
| 1269 | for (i = 0; i < (FC_ALPA_MAX / 8); i++) { | ||
| 1270 | for (j = 0, alpa_bit = 0; j < 8; j++, alpa_bit++) { | ||
| 1271 | bfa_trc(port->fcs->bfa, fcport->alpabm.alpa_bm[i]); | ||
| 1272 | bit = (fcport->alpabm.alpa_bm[i] & (1 << (7 - j))); | ||
| 1273 | if (bit) { | ||
| 1274 | port->port_topo.ploop.alpa_pos_map[k] = | ||
| 1275 | loop_alpa_map[(i * 8) + alpa_bit]; | ||
| 1276 | k++; | ||
| 1277 | bfa_trc(port->fcs->bfa, k); | ||
| 1278 | bfa_trc(port->fcs->bfa, | ||
| 1279 | port->port_topo.ploop.alpa_pos_map[k]); | ||
| 1280 | } | ||
| 1281 | } | ||
| 1282 | } | ||
| 1283 | port->port_topo.ploop.num_alpa = k; | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | /* | ||
| 1287 | * Called by fcs/port to initialize Loop topology. | ||
| 1288 | */ | ||
| 1289 | static void | ||
| 1290 | bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port) | ||
| 1291 | { | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | /* | ||
| 1295 | * Called by fcs/port to notify transition to online state. | ||
| 1296 | */ | ||
| 1297 | static void | ||
| 1298 | bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port) | ||
| 1299 | { | ||
| 1300 | u8 num_alpa = 0, alpabm_valid = 0; | ||
| 1301 | struct bfa_fcs_rport_s *rport; | ||
| 1302 | u8 *alpa_map = NULL; | ||
| 1303 | int i = 0; | ||
| 1304 | u32 pid; | ||
| 1305 | |||
| 1306 | bfa_fcport_get_loop_attr(port); | ||
| 1307 | |||
| 1308 | num_alpa = port->port_topo.ploop.num_alpa; | ||
| 1309 | alpabm_valid = port->port_topo.ploop.alpabm_valid; | ||
| 1310 | alpa_map = port->port_topo.ploop.alpa_pos_map; | ||
| 1311 | |||
| 1312 | bfa_trc(port->fcs->bfa, port->pid); | ||
| 1313 | bfa_trc(port->fcs->bfa, num_alpa); | ||
| 1314 | if (alpabm_valid == 1) { | ||
| 1315 | for (i = 0; i < num_alpa; i++) { | ||
| 1316 | bfa_trc(port->fcs->bfa, alpa_map[i]); | ||
| 1317 | if (alpa_map[i] != bfa_hton3b(port->pid)) { | ||
| 1318 | pid = alpa_map[i]; | ||
| 1319 | bfa_trc(port->fcs->bfa, pid); | ||
| 1320 | rport = bfa_fcs_lport_get_rport_by_pid(port, | ||
| 1321 | bfa_hton3b(pid)); | ||
| 1322 | if (!rport) | ||
| 1323 | rport = bfa_fcs_rport_create(port, | ||
| 1324 | bfa_hton3b(pid)); | ||
| 1325 | } | ||
| 1326 | } | ||
| 1327 | } else { | ||
| 1328 | for (i = 0; i < MAX_ALPA_COUNT; i++) { | ||
| 1329 | if (alpa_map[i] != port->pid) { | ||
| 1330 | pid = loop_alpa_map[i]; | ||
| 1331 | bfa_trc(port->fcs->bfa, pid); | ||
| 1332 | rport = bfa_fcs_lport_get_rport_by_pid(port, | ||
| 1333 | bfa_hton3b(pid)); | ||
| 1334 | if (!rport) | ||
| 1335 | rport = bfa_fcs_rport_create(port, | ||
| 1336 | bfa_hton3b(pid)); | ||
| 1337 | } | ||
| 1338 | } | ||
| 1339 | } | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | /* | ||
| 1343 | * Called by fcs/port to notify transition to offline state. | ||
| 1344 | */ | ||
| 1345 | static void | ||
| 1346 | bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port) | ||
| 1347 | { | ||
| 1348 | } | ||
| 1349 | |||
| 1224 | #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 | 1350 | #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 |
| 1225 | 1351 | ||
| 1226 | /* | 1352 | /* |
| @@ -1888,13 +2014,10 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) | |||
| 1888 | sizeof(templen)); | 2014 | sizeof(templen)); |
| 1889 | } | 2015 | } |
| 1890 | 2016 | ||
| 1891 | /* | ||
| 1892 | * f/w Version = driver version | ||
| 1893 | */ | ||
| 1894 | attr = (struct fdmi_attr_s *) curr_ptr; | 2017 | attr = (struct fdmi_attr_s *) curr_ptr; |
| 1895 | attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION); | 2018 | attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION); |
| 1896 | templen = (u16) strlen(fcs_hba_attr->driver_version); | 2019 | templen = (u16) strlen(fcs_hba_attr->fw_version); |
| 1897 | memcpy(attr->value, fcs_hba_attr->driver_version, templen); | 2020 | memcpy(attr->value, fcs_hba_attr->fw_version, templen); |
| 1898 | templen = fc_roundup(templen, sizeof(u32)); | 2021 | templen = fc_roundup(templen, sizeof(u32)); |
| 1899 | curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; | 2022 | curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; |
| 1900 | len += templen; | 2023 | len += templen; |
| @@ -2296,6 +2419,7 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, | |||
| 2296 | { | 2419 | { |
| 2297 | struct bfa_fcs_lport_s *port = fdmi->ms->port; | 2420 | struct bfa_fcs_lport_s *port = fdmi->ms->port; |
| 2298 | struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; | 2421 | struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; |
| 2422 | struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; | ||
| 2299 | 2423 | ||
| 2300 | memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); | 2424 | memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); |
| 2301 | 2425 | ||
| @@ -2331,7 +2455,9 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, | |||
| 2331 | sizeof(driver_info->host_os_patch)); | 2455 | sizeof(driver_info->host_os_patch)); |
| 2332 | } | 2456 | } |
| 2333 | 2457 | ||
| 2334 | hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ); | 2458 | /* Retrieve the max frame size from the port attr */ |
| 2459 | bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); | ||
| 2460 | hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size; | ||
| 2335 | } | 2461 | } |
| 2336 | 2462 | ||
| 2337 | static void | 2463 | static void |
| @@ -2391,7 +2517,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, | |||
| 2391 | /* | 2517 | /* |
| 2392 | * Max PDU Size. | 2518 | * Max PDU Size. |
| 2393 | */ | 2519 | */ |
| 2394 | port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ); | 2520 | port_attr->max_frm_size = cpu_to_be32(pport_attr.pport_cfg.maxfrsize); |
| 2395 | 2521 | ||
| 2396 | /* | 2522 | /* |
| 2397 | * OS device Name | 2523 | * OS device Name |
| @@ -5199,7 +5325,7 @@ bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port) | |||
| 5199 | } | 5325 | } |
| 5200 | 5326 | ||
| 5201 | void | 5327 | void |
| 5202 | bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port) | 5328 | bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *port) |
| 5203 | { | 5329 | { |
| 5204 | struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); | 5330 | struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); |
| 5205 | 5331 | ||
| @@ -5621,6 +5747,15 @@ bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port) | |||
| 5621 | } | 5747 | } |
| 5622 | 5748 | ||
| 5623 | /* | 5749 | /* |
| 5750 | * Let new loop map create missing rports | ||
| 5751 | */ | ||
| 5752 | void | ||
| 5753 | bfa_fcs_lport_lip_scn_online(struct bfa_fcs_lport_s *port) | ||
| 5754 | { | ||
| 5755 | bfa_fcs_lport_loop_online(port); | ||
| 5756 | } | ||
| 5757 | |||
| 5758 | /* | ||
| 5624 | * FCS virtual port state machine | 5759 | * FCS virtual port state machine |
| 5625 | */ | 5760 | */ |
| 5626 | 5761 | ||
diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index cc43b2a58ce3..58ac643ba9f3 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c | |||
| @@ -106,9 +106,13 @@ static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, | |||
| 106 | enum rport_event event); | 106 | enum rport_event event); |
| 107 | static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, | 107 | static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, |
| 108 | enum rport_event event); | 108 | enum rport_event event); |
| 109 | static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, | 109 | static void bfa_fcs_rport_sm_adisc_online_sending( |
| 110 | enum rport_event event); | 110 | struct bfa_fcs_rport_s *rport, enum rport_event event); |
| 111 | static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, | 111 | static void bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport, |
| 112 | enum rport_event event); | ||
| 113 | static void bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s | ||
| 114 | *rport, enum rport_event event); | ||
| 115 | static void bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport, | ||
| 112 | enum rport_event event); | 116 | enum rport_event event); |
| 113 | static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, | 117 | static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, |
| 114 | enum rport_event event); | 118 | enum rport_event event); |
| @@ -150,8 +154,10 @@ static struct bfa_sm_table_s rport_sm_table[] = { | |||
| 150 | {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE}, | 154 | {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE}, |
| 151 | {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY}, | 155 | {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY}, |
| 152 | {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY}, | 156 | {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY}, |
| 153 | {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC}, | 157 | {BFA_SM(bfa_fcs_rport_sm_adisc_online_sending), BFA_RPORT_ADISC}, |
| 154 | {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC}, | 158 | {BFA_SM(bfa_fcs_rport_sm_adisc_online), BFA_RPORT_ADISC}, |
| 159 | {BFA_SM(bfa_fcs_rport_sm_adisc_offline_sending), BFA_RPORT_ADISC}, | ||
| 160 | {BFA_SM(bfa_fcs_rport_sm_adisc_offline), BFA_RPORT_ADISC}, | ||
| 155 | {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV}, | 161 | {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV}, |
| 156 | {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO}, | 162 | {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO}, |
| 157 | {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE}, | 163 | {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE}, |
| @@ -231,10 +237,19 @@ bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport, | |||
| 231 | bfa_fcs_rport_send_plogiacc(rport, NULL); | 237 | bfa_fcs_rport_send_plogiacc(rport, NULL); |
| 232 | break; | 238 | break; |
| 233 | 239 | ||
| 240 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 241 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); | ||
| 242 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); | ||
| 243 | bfa_timer_start(rport->fcs->bfa, &rport->timer, | ||
| 244 | bfa_fcs_rport_timeout, rport, | ||
| 245 | bfa_fcs_rport_del_timeout); | ||
| 246 | break; | ||
| 234 | case RPSM_EVENT_ADDRESS_CHANGE: | 247 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 235 | case RPSM_EVENT_SCN: | 248 | case RPSM_EVENT_FAB_SCN: |
| 236 | /* query the NS */ | 249 | /* query the NS */ |
| 237 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); | 250 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); |
| 251 | WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) != | ||
| 252 | BFA_PORT_TOPOLOGY_LOOP)); | ||
| 238 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); | 253 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); |
| 239 | rport->ns_retries = 0; | 254 | rport->ns_retries = 0; |
| 240 | bfa_fcs_rport_send_nsdisc(rport, NULL); | 255 | bfa_fcs_rport_send_nsdisc(rport, NULL); |
| @@ -280,12 +295,20 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, | |||
| 280 | 295 | ||
| 281 | case RPSM_EVENT_PLOGI_RCVD: | 296 | case RPSM_EVENT_PLOGI_RCVD: |
| 282 | case RPSM_EVENT_PLOGI_COMP: | 297 | case RPSM_EVENT_PLOGI_COMP: |
| 283 | case RPSM_EVENT_SCN: | 298 | case RPSM_EVENT_FAB_SCN: |
| 284 | /* | 299 | /* |
| 285 | * Ignore, SCN is possibly online notification. | 300 | * Ignore, SCN is possibly online notification. |
| 286 | */ | 301 | */ |
| 287 | break; | 302 | break; |
| 288 | 303 | ||
| 304 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 305 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); | ||
| 306 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); | ||
| 307 | bfa_timer_start(rport->fcs->bfa, &rport->timer, | ||
| 308 | bfa_fcs_rport_timeout, rport, | ||
| 309 | bfa_fcs_rport_del_timeout); | ||
| 310 | break; | ||
| 311 | |||
| 289 | case RPSM_EVENT_ADDRESS_CHANGE: | 312 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 290 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); | 313 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); |
| 291 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); | 314 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); |
| @@ -346,9 +369,19 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, | |||
| 346 | bfa_fcs_rport_send_plogiacc(rport, NULL); | 369 | bfa_fcs_rport_send_plogiacc(rport, NULL); |
| 347 | break; | 370 | break; |
| 348 | 371 | ||
| 372 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 373 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); | ||
| 374 | bfa_timer_stop(&rport->timer); | ||
| 375 | bfa_timer_start(rport->fcs->bfa, &rport->timer, | ||
| 376 | bfa_fcs_rport_timeout, rport, | ||
| 377 | bfa_fcs_rport_del_timeout); | ||
| 378 | break; | ||
| 379 | |||
| 349 | case RPSM_EVENT_ADDRESS_CHANGE: | 380 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 350 | case RPSM_EVENT_SCN: | 381 | case RPSM_EVENT_FAB_SCN: |
| 351 | bfa_timer_stop(&rport->timer); | 382 | bfa_timer_stop(&rport->timer); |
| 383 | WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) != | ||
| 384 | BFA_PORT_TOPOLOGY_LOOP)); | ||
| 352 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); | 385 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); |
| 353 | rport->ns_retries = 0; | 386 | rport->ns_retries = 0; |
| 354 | bfa_fcs_rport_send_nsdisc(rport, NULL); | 387 | bfa_fcs_rport_send_nsdisc(rport, NULL); |
| @@ -422,7 +455,18 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 422 | } | 455 | } |
| 423 | break; | 456 | break; |
| 424 | 457 | ||
| 425 | case RPSM_EVENT_PLOGI_RETRY: | 458 | case RPSM_EVENT_SCN_ONLINE: |
| 459 | break; | ||
| 460 | |||
| 461 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 462 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); | ||
| 463 | bfa_fcxp_discard(rport->fcxp); | ||
| 464 | bfa_timer_start(rport->fcs->bfa, &rport->timer, | ||
| 465 | bfa_fcs_rport_timeout, rport, | ||
| 466 | bfa_fcs_rport_del_timeout); | ||
| 467 | break; | ||
| 468 | |||
| 469 | case RPSM_EVENT_PLOGI_RETRY: | ||
| 426 | rport->plogi_retries = 0; | 470 | rport->plogi_retries = 0; |
| 427 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry); | 471 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry); |
| 428 | bfa_timer_start(rport->fcs->bfa, &rport->timer, | 472 | bfa_timer_start(rport->fcs->bfa, &rport->timer, |
| @@ -440,8 +484,10 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 440 | break; | 484 | break; |
| 441 | 485 | ||
| 442 | case RPSM_EVENT_ADDRESS_CHANGE: | 486 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 443 | case RPSM_EVENT_SCN: | 487 | case RPSM_EVENT_FAB_SCN: |
| 444 | bfa_fcxp_discard(rport->fcxp); | 488 | bfa_fcxp_discard(rport->fcxp); |
| 489 | WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) != | ||
| 490 | BFA_PORT_TOPOLOGY_LOOP)); | ||
| 445 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); | 491 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); |
| 446 | rport->ns_retries = 0; | 492 | rport->ns_retries = 0; |
| 447 | bfa_fcs_rport_send_nsdisc(rport, NULL); | 493 | bfa_fcs_rport_send_nsdisc(rport, NULL); |
| @@ -512,7 +558,8 @@ bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport, | |||
| 512 | case RPSM_EVENT_PLOGI_COMP: | 558 | case RPSM_EVENT_PLOGI_COMP: |
| 513 | case RPSM_EVENT_LOGO_IMP: | 559 | case RPSM_EVENT_LOGO_IMP: |
| 514 | case RPSM_EVENT_ADDRESS_CHANGE: | 560 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 515 | case RPSM_EVENT_SCN: | 561 | case RPSM_EVENT_FAB_SCN: |
| 562 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 516 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); | 563 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); |
| 517 | bfa_fcs_rport_fcs_offline_action(rport); | 564 | bfa_fcs_rport_fcs_offline_action(rport); |
| 518 | break; | 565 | break; |
| @@ -561,9 +608,10 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, | |||
| 561 | bfa_fcs_rport_fcs_offline_action(rport); | 608 | bfa_fcs_rport_fcs_offline_action(rport); |
| 562 | break; | 609 | break; |
| 563 | 610 | ||
| 564 | case RPSM_EVENT_SCN: | 611 | case RPSM_EVENT_FAB_SCN: |
| 565 | case RPSM_EVENT_LOGO_IMP: | 612 | case RPSM_EVENT_LOGO_IMP: |
| 566 | case RPSM_EVENT_ADDRESS_CHANGE: | 613 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 614 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 567 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); | 615 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); |
| 568 | bfa_fcs_rport_fcs_offline_action(rport); | 616 | bfa_fcs_rport_fcs_offline_action(rport); |
| 569 | break; | 617 | break; |
| @@ -595,14 +643,15 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 595 | bfa_trc(rport->fcs, event); | 643 | bfa_trc(rport->fcs, event); |
| 596 | 644 | ||
| 597 | switch (event) { | 645 | switch (event) { |
| 598 | case RPSM_EVENT_SCN: | 646 | case RPSM_EVENT_FAB_SCN: |
| 599 | if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { | 647 | if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { |
| 600 | bfa_sm_set_state(rport, | 648 | bfa_sm_set_state(rport, |
| 601 | bfa_fcs_rport_sm_nsquery_sending); | 649 | bfa_fcs_rport_sm_nsquery_sending); |
| 602 | rport->ns_retries = 0; | 650 | rport->ns_retries = 0; |
| 603 | bfa_fcs_rport_send_nsdisc(rport, NULL); | 651 | bfa_fcs_rport_send_nsdisc(rport, NULL); |
| 604 | } else { | 652 | } else { |
| 605 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); | 653 | bfa_sm_set_state(rport, |
| 654 | bfa_fcs_rport_sm_adisc_online_sending); | ||
| 606 | bfa_fcs_rport_send_adisc(rport, NULL); | 655 | bfa_fcs_rport_send_adisc(rport, NULL); |
| 607 | } | 656 | } |
| 608 | break; | 657 | break; |
| @@ -610,6 +659,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 610 | case RPSM_EVENT_PLOGI_RCVD: | 659 | case RPSM_EVENT_PLOGI_RCVD: |
| 611 | case RPSM_EVENT_LOGO_IMP: | 660 | case RPSM_EVENT_LOGO_IMP: |
| 612 | case RPSM_EVENT_ADDRESS_CHANGE: | 661 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 662 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 613 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); | 663 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); |
| 614 | bfa_fcs_rport_hal_offline_action(rport); | 664 | bfa_fcs_rport_hal_offline_action(rport); |
| 615 | break; | 665 | break; |
| @@ -625,6 +675,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 625 | bfa_fcs_rport_hal_offline_action(rport); | 675 | bfa_fcs_rport_hal_offline_action(rport); |
| 626 | break; | 676 | break; |
| 627 | 677 | ||
| 678 | case RPSM_EVENT_SCN_ONLINE: | ||
| 628 | case RPSM_EVENT_PLOGI_COMP: | 679 | case RPSM_EVENT_PLOGI_COMP: |
| 629 | break; | 680 | break; |
| 630 | 681 | ||
| @@ -656,7 +707,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, | |||
| 656 | bfa_fcs_rport_hal_offline_action(rport); | 707 | bfa_fcs_rport_hal_offline_action(rport); |
| 657 | break; | 708 | break; |
| 658 | 709 | ||
| 659 | case RPSM_EVENT_SCN: | 710 | case RPSM_EVENT_FAB_SCN: |
| 660 | /* | 711 | /* |
| 661 | * ignore SCN, wait for response to query itself | 712 | * ignore SCN, wait for response to query itself |
| 662 | */ | 713 | */ |
| @@ -696,7 +747,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 696 | 747 | ||
| 697 | switch (event) { | 748 | switch (event) { |
| 698 | case RPSM_EVENT_ACCEPTED: | 749 | case RPSM_EVENT_ACCEPTED: |
| 699 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); | 750 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online_sending); |
| 700 | bfa_fcs_rport_send_adisc(rport, NULL); | 751 | bfa_fcs_rport_send_adisc(rport, NULL); |
| 701 | break; | 752 | break; |
| 702 | 753 | ||
| @@ -718,7 +769,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 718 | bfa_fcs_rport_hal_offline_action(rport); | 769 | bfa_fcs_rport_hal_offline_action(rport); |
| 719 | break; | 770 | break; |
| 720 | 771 | ||
| 721 | case RPSM_EVENT_SCN: | 772 | case RPSM_EVENT_FAB_SCN: |
| 722 | break; | 773 | break; |
| 723 | 774 | ||
| 724 | case RPSM_EVENT_LOGO_RCVD: | 775 | case RPSM_EVENT_LOGO_RCVD: |
| @@ -747,7 +798,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 747 | * authenticating with rport. FC-4s are paused. | 798 | * authenticating with rport. FC-4s are paused. |
| 748 | */ | 799 | */ |
| 749 | static void | 800 | static void |
| 750 | bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, | 801 | bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s *rport, |
| 751 | enum rport_event event) | 802 | enum rport_event event) |
| 752 | { | 803 | { |
| 753 | bfa_trc(rport->fcs, rport->pwwn); | 804 | bfa_trc(rport->fcs, rport->pwwn); |
| @@ -756,7 +807,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, | |||
| 756 | 807 | ||
| 757 | switch (event) { | 808 | switch (event) { |
| 758 | case RPSM_EVENT_FCXP_SENT: | 809 | case RPSM_EVENT_FCXP_SENT: |
| 759 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc); | 810 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online); |
| 760 | break; | 811 | break; |
| 761 | 812 | ||
| 762 | case RPSM_EVENT_DELETE: | 813 | case RPSM_EVENT_DELETE: |
| @@ -779,7 +830,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, | |||
| 779 | bfa_fcs_rport_hal_offline_action(rport); | 830 | bfa_fcs_rport_hal_offline_action(rport); |
| 780 | break; | 831 | break; |
| 781 | 832 | ||
| 782 | case RPSM_EVENT_SCN: | 833 | case RPSM_EVENT_FAB_SCN: |
| 783 | break; | 834 | break; |
| 784 | 835 | ||
| 785 | case RPSM_EVENT_PLOGI_RCVD: | 836 | case RPSM_EVENT_PLOGI_RCVD: |
| @@ -798,7 +849,8 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, | |||
| 798 | * FC-4s are paused. | 849 | * FC-4s are paused. |
| 799 | */ | 850 | */ |
| 800 | static void | 851 | static void |
| 801 | bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) | 852 | bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport, |
| 853 | enum rport_event event) | ||
| 802 | { | 854 | { |
| 803 | bfa_trc(rport->fcs, rport->pwwn); | 855 | bfa_trc(rport->fcs, rport->pwwn); |
| 804 | bfa_trc(rport->fcs, rport->pid); | 856 | bfa_trc(rport->fcs, rport->pid); |
| @@ -831,7 +883,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 831 | bfa_fcs_rport_hal_offline_action(rport); | 883 | bfa_fcs_rport_hal_offline_action(rport); |
| 832 | break; | 884 | break; |
| 833 | 885 | ||
| 834 | case RPSM_EVENT_SCN: | 886 | case RPSM_EVENT_FAB_SCN: |
| 835 | /* | 887 | /* |
| 836 | * already processing RSCN | 888 | * already processing RSCN |
| 837 | */ | 889 | */ |
| @@ -856,7 +908,96 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 856 | } | 908 | } |
| 857 | 909 | ||
| 858 | /* | 910 | /* |
| 859 | * Rport has sent LOGO. Awaiting FC-4 offline completion callback. | 911 | * ADISC is being sent for authenticating with rport |
| 912 | * Already did offline actions. | ||
| 913 | */ | ||
| 914 | static void | ||
| 915 | bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s *rport, | ||
| 916 | enum rport_event event) | ||
| 917 | { | ||
| 918 | bfa_trc(rport->fcs, rport->pwwn); | ||
| 919 | bfa_trc(rport->fcs, rport->pid); | ||
| 920 | bfa_trc(rport->fcs, event); | ||
| 921 | |||
| 922 | switch (event) { | ||
| 923 | case RPSM_EVENT_FCXP_SENT: | ||
| 924 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_offline); | ||
| 925 | break; | ||
| 926 | |||
| 927 | case RPSM_EVENT_DELETE: | ||
| 928 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 929 | case RPSM_EVENT_LOGO_IMP: | ||
| 930 | case RPSM_EVENT_LOGO_RCVD: | ||
| 931 | case RPSM_EVENT_PRLO_RCVD: | ||
| 932 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); | ||
| 933 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, | ||
| 934 | &rport->fcxp_wqe); | ||
| 935 | bfa_timer_start(rport->fcs->bfa, &rport->timer, | ||
| 936 | bfa_fcs_rport_timeout, rport, | ||
| 937 | bfa_fcs_rport_del_timeout); | ||
| 938 | break; | ||
| 939 | |||
| 940 | case RPSM_EVENT_PLOGI_RCVD: | ||
| 941 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); | ||
| 942 | bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); | ||
| 943 | bfa_fcs_rport_send_plogiacc(rport, NULL); | ||
| 944 | break; | ||
| 945 | |||
| 946 | default: | ||
| 947 | bfa_sm_fault(rport->fcs, event); | ||
| 948 | } | ||
| 949 | } | ||
| 950 | |||
| 951 | /* | ||
| 952 | * ADISC to rport | ||
| 953 | * Already did offline actions | ||
| 954 | */ | ||
| 955 | static void | ||
| 956 | bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport, | ||
| 957 | enum rport_event event) | ||
| 958 | { | ||
| 959 | bfa_trc(rport->fcs, rport->pwwn); | ||
| 960 | bfa_trc(rport->fcs, rport->pid); | ||
| 961 | bfa_trc(rport->fcs, event); | ||
| 962 | |||
| 963 | switch (event) { | ||
| 964 | case RPSM_EVENT_ACCEPTED: | ||
| 965 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); | ||
| 966 | bfa_fcs_rport_hal_online(rport); | ||
| 967 | break; | ||
| 968 | |||
| 969 | case RPSM_EVENT_PLOGI_RCVD: | ||
| 970 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); | ||
| 971 | bfa_fcxp_discard(rport->fcxp); | ||
| 972 | bfa_fcs_rport_send_plogiacc(rport, NULL); | ||
| 973 | break; | ||
| 974 | |||
| 975 | case RPSM_EVENT_FAILED: | ||
| 976 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); | ||
| 977 | bfa_timer_start(rport->fcs->bfa, &rport->timer, | ||
| 978 | bfa_fcs_rport_timeout, rport, | ||
| 979 | bfa_fcs_rport_del_timeout); | ||
| 980 | break; | ||
| 981 | |||
| 982 | case RPSM_EVENT_DELETE: | ||
| 983 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 984 | case RPSM_EVENT_LOGO_IMP: | ||
| 985 | case RPSM_EVENT_LOGO_RCVD: | ||
| 986 | case RPSM_EVENT_PRLO_RCVD: | ||
| 987 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); | ||
| 988 | bfa_fcxp_discard(rport->fcxp); | ||
| 989 | bfa_timer_start(rport->fcs->bfa, &rport->timer, | ||
| 990 | bfa_fcs_rport_timeout, rport, | ||
| 991 | bfa_fcs_rport_del_timeout); | ||
| 992 | break; | ||
| 993 | |||
| 994 | default: | ||
| 995 | bfa_sm_fault(rport->fcs, event); | ||
| 996 | } | ||
| 997 | } | ||
| 998 | |||
| 999 | /* | ||
| 1000 | * Rport has sent LOGO. Awaiting FC-4 offline completion callback. | ||
| 860 | */ | 1001 | */ |
| 861 | static void | 1002 | static void |
| 862 | bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, | 1003 | bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, |
| @@ -881,6 +1022,8 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, | |||
| 881 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete); | 1022 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete); |
| 882 | break; | 1023 | break; |
| 883 | 1024 | ||
| 1025 | case RPSM_EVENT_SCN_ONLINE: | ||
| 1026 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 884 | case RPSM_EVENT_HCB_ONLINE: | 1027 | case RPSM_EVENT_HCB_ONLINE: |
| 885 | case RPSM_EVENT_LOGO_RCVD: | 1028 | case RPSM_EVENT_LOGO_RCVD: |
| 886 | case RPSM_EVENT_PRLO_RCVD: | 1029 | case RPSM_EVENT_PRLO_RCVD: |
| @@ -945,6 +1088,8 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, | |||
| 945 | bfa_fcs_rport_hal_offline(rport); | 1088 | bfa_fcs_rport_hal_offline(rport); |
| 946 | break; | 1089 | break; |
| 947 | 1090 | ||
| 1091 | case RPSM_EVENT_SCN_ONLINE: | ||
| 1092 | break; | ||
| 948 | case RPSM_EVENT_LOGO_RCVD: | 1093 | case RPSM_EVENT_LOGO_RCVD: |
| 949 | /* | 1094 | /* |
| 950 | * Rport is going offline. Just ack the logo | 1095 | * Rport is going offline. Just ack the logo |
| @@ -956,8 +1101,9 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, | |||
| 956 | bfa_fcs_rport_send_prlo_acc(rport); | 1101 | bfa_fcs_rport_send_prlo_acc(rport); |
| 957 | break; | 1102 | break; |
| 958 | 1103 | ||
| 1104 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 959 | case RPSM_EVENT_HCB_ONLINE: | 1105 | case RPSM_EVENT_HCB_ONLINE: |
| 960 | case RPSM_EVENT_SCN: | 1106 | case RPSM_EVENT_FAB_SCN: |
| 961 | case RPSM_EVENT_LOGO_IMP: | 1107 | case RPSM_EVENT_LOGO_IMP: |
| 962 | case RPSM_EVENT_ADDRESS_CHANGE: | 1108 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 963 | /* | 1109 | /* |
| @@ -1015,6 +1161,19 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, | |||
| 1015 | bfa_fcs_rport_sm_nsdisc_sending); | 1161 | bfa_fcs_rport_sm_nsdisc_sending); |
| 1016 | rport->ns_retries = 0; | 1162 | rport->ns_retries = 0; |
| 1017 | bfa_fcs_rport_send_nsdisc(rport, NULL); | 1163 | bfa_fcs_rport_send_nsdisc(rport, NULL); |
| 1164 | } else if (bfa_fcport_get_topology(rport->port->fcs->bfa) == | ||
| 1165 | BFA_PORT_TOPOLOGY_LOOP) { | ||
| 1166 | if (rport->scn_online) { | ||
| 1167 | bfa_sm_set_state(rport, | ||
| 1168 | bfa_fcs_rport_sm_adisc_offline_sending); | ||
| 1169 | bfa_fcs_rport_send_adisc(rport, NULL); | ||
| 1170 | } else { | ||
| 1171 | bfa_sm_set_state(rport, | ||
| 1172 | bfa_fcs_rport_sm_offline); | ||
| 1173 | bfa_timer_start(rport->fcs->bfa, &rport->timer, | ||
| 1174 | bfa_fcs_rport_timeout, rport, | ||
| 1175 | bfa_fcs_rport_del_timeout); | ||
| 1176 | } | ||
| 1018 | } else { | 1177 | } else { |
| 1019 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); | 1178 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); |
| 1020 | rport->plogi_retries = 0; | 1179 | rport->plogi_retries = 0; |
| @@ -1027,7 +1186,9 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, | |||
| 1027 | bfa_fcs_rport_free(rport); | 1186 | bfa_fcs_rport_free(rport); |
| 1028 | break; | 1187 | break; |
| 1029 | 1188 | ||
| 1030 | case RPSM_EVENT_SCN: | 1189 | case RPSM_EVENT_SCN_ONLINE: |
| 1190 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 1191 | case RPSM_EVENT_FAB_SCN: | ||
| 1031 | case RPSM_EVENT_LOGO_RCVD: | 1192 | case RPSM_EVENT_LOGO_RCVD: |
| 1032 | case RPSM_EVENT_PRLO_RCVD: | 1193 | case RPSM_EVENT_PRLO_RCVD: |
| 1033 | case RPSM_EVENT_PLOGI_RCVD: | 1194 | case RPSM_EVENT_PLOGI_RCVD: |
| @@ -1106,6 +1267,8 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, | |||
| 1106 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); | 1267 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); |
| 1107 | break; | 1268 | break; |
| 1108 | 1269 | ||
| 1270 | case RPSM_EVENT_SCN_ONLINE: | ||
| 1271 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 1109 | case RPSM_EVENT_LOGO_RCVD: | 1272 | case RPSM_EVENT_LOGO_RCVD: |
| 1110 | case RPSM_EVENT_PRLO_RCVD: | 1273 | case RPSM_EVENT_PRLO_RCVD: |
| 1111 | /* | 1274 | /* |
| @@ -1146,6 +1309,8 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, | |||
| 1146 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); | 1309 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); |
| 1147 | break; | 1310 | break; |
| 1148 | 1311 | ||
| 1312 | case RPSM_EVENT_SCN_ONLINE: | ||
| 1313 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 1149 | case RPSM_EVENT_ADDRESS_CHANGE: | 1314 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 1150 | break; | 1315 | break; |
| 1151 | 1316 | ||
| @@ -1172,7 +1337,9 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, | |||
| 1172 | bfa_fcs_rport_free(rport); | 1337 | bfa_fcs_rport_free(rport); |
| 1173 | break; | 1338 | break; |
| 1174 | 1339 | ||
| 1175 | case RPSM_EVENT_SCN: | 1340 | case RPSM_EVENT_SCN_ONLINE: |
| 1341 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 1342 | case RPSM_EVENT_FAB_SCN: | ||
| 1176 | case RPSM_EVENT_ADDRESS_CHANGE: | 1343 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 1177 | break; | 1344 | break; |
| 1178 | 1345 | ||
| @@ -1209,10 +1376,12 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 1209 | bfa_fcs_rport_free(rport); | 1376 | bfa_fcs_rport_free(rport); |
| 1210 | break; | 1377 | break; |
| 1211 | 1378 | ||
| 1212 | case RPSM_EVENT_SCN: | 1379 | case RPSM_EVENT_FAB_SCN: |
| 1213 | case RPSM_EVENT_ADDRESS_CHANGE: | 1380 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 1214 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); | ||
| 1215 | bfa_timer_stop(&rport->timer); | 1381 | bfa_timer_stop(&rport->timer); |
| 1382 | WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) != | ||
| 1383 | BFA_PORT_TOPOLOGY_LOOP)); | ||
| 1384 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); | ||
| 1216 | rport->ns_retries = 0; | 1385 | rport->ns_retries = 0; |
| 1217 | bfa_fcs_rport_send_nsdisc(rport, NULL); | 1386 | bfa_fcs_rport_send_nsdisc(rport, NULL); |
| 1218 | break; | 1387 | break; |
| @@ -1232,6 +1401,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 1232 | case RPSM_EVENT_LOGO_RCVD: | 1401 | case RPSM_EVENT_LOGO_RCVD: |
| 1233 | case RPSM_EVENT_PRLO_RCVD: | 1402 | case RPSM_EVENT_PRLO_RCVD: |
| 1234 | case RPSM_EVENT_LOGO_IMP: | 1403 | case RPSM_EVENT_LOGO_IMP: |
| 1404 | case RPSM_EVENT_SCN_OFFLINE: | ||
| 1235 | break; | 1405 | break; |
| 1236 | 1406 | ||
| 1237 | case RPSM_EVENT_PLOGI_COMP: | 1407 | case RPSM_EVENT_PLOGI_COMP: |
| @@ -1240,6 +1410,12 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
| 1240 | bfa_fcs_rport_fcs_online_action(rport); | 1410 | bfa_fcs_rport_fcs_online_action(rport); |
| 1241 | break; | 1411 | break; |
| 1242 | 1412 | ||
| 1413 | case RPSM_EVENT_SCN_ONLINE: | ||
| 1414 | bfa_timer_stop(&rport->timer); | ||
| 1415 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); | ||
| 1416 | bfa_fcs_rport_send_plogi(rport, NULL); | ||
| 1417 | break; | ||
| 1418 | |||
| 1243 | case RPSM_EVENT_PLOGI_SEND: | 1419 | case RPSM_EVENT_PLOGI_SEND: |
| 1244 | bfa_timer_stop(&rport->timer); | 1420 | bfa_timer_stop(&rport->timer); |
| 1245 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); | 1421 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); |
| @@ -1280,7 +1456,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport, | |||
| 1280 | bfa_fcs_rport_send_plogiacc(rport, NULL); | 1456 | bfa_fcs_rport_send_plogiacc(rport, NULL); |
| 1281 | break; | 1457 | break; |
| 1282 | 1458 | ||
| 1283 | case RPSM_EVENT_SCN: | 1459 | case RPSM_EVENT_FAB_SCN: |
| 1284 | case RPSM_EVENT_LOGO_RCVD: | 1460 | case RPSM_EVENT_LOGO_RCVD: |
| 1285 | case RPSM_EVENT_PRLO_RCVD: | 1461 | case RPSM_EVENT_PRLO_RCVD: |
| 1286 | case RPSM_EVENT_PLOGI_SEND: | 1462 | case RPSM_EVENT_PLOGI_SEND: |
| @@ -1326,7 +1502,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport, | |||
| 1326 | bfa_fcs_rport_send_nsdisc(rport, NULL); | 1502 | bfa_fcs_rport_send_nsdisc(rport, NULL); |
| 1327 | break; | 1503 | break; |
| 1328 | 1504 | ||
| 1329 | case RPSM_EVENT_SCN: | 1505 | case RPSM_EVENT_FAB_SCN: |
| 1330 | case RPSM_EVENT_ADDRESS_CHANGE: | 1506 | case RPSM_EVENT_ADDRESS_CHANGE: |
| 1331 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); | 1507 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); |
| 1332 | bfa_timer_stop(&rport->timer); | 1508 | bfa_timer_stop(&rport->timer); |
| @@ -1439,7 +1615,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, | |||
| 1439 | case RPSM_EVENT_PRLO_RCVD: | 1615 | case RPSM_EVENT_PRLO_RCVD: |
| 1440 | bfa_fcs_rport_send_prlo_acc(rport); | 1616 | bfa_fcs_rport_send_prlo_acc(rport); |
| 1441 | break; | 1617 | break; |
| 1442 | case RPSM_EVENT_SCN: | 1618 | case RPSM_EVENT_FAB_SCN: |
| 1443 | /* | 1619 | /* |
| 1444 | * ignore, wait for NS query response | 1620 | * ignore, wait for NS query response |
| 1445 | */ | 1621 | */ |
| @@ -2546,7 +2722,7 @@ void | |||
| 2546 | bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport) | 2722 | bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport) |
| 2547 | { | 2723 | { |
| 2548 | rport->stats.rscns++; | 2724 | rport->stats.rscns++; |
| 2549 | bfa_sm_send_event(rport, RPSM_EVENT_SCN); | 2725 | bfa_sm_send_event(rport, RPSM_EVENT_FAB_SCN); |
| 2550 | } | 2726 | } |
| 2551 | 2727 | ||
| 2552 | /* | 2728 | /* |
| @@ -2621,6 +2797,48 @@ bfa_cb_rport_qos_scn_flowid(void *cbarg, | |||
| 2621 | bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data); | 2797 | bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data); |
| 2622 | } | 2798 | } |
| 2623 | 2799 | ||
| 2800 | void | ||
| 2801 | bfa_cb_rport_scn_online(struct bfa_s *bfa) | ||
| 2802 | { | ||
| 2803 | struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs; | ||
| 2804 | struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs); | ||
| 2805 | struct bfa_fcs_rport_s *rp; | ||
| 2806 | struct list_head *qe; | ||
| 2807 | |||
| 2808 | list_for_each(qe, &port->rport_q) { | ||
| 2809 | rp = (struct bfa_fcs_rport_s *) qe; | ||
| 2810 | bfa_sm_send_event(rp, RPSM_EVENT_SCN_ONLINE); | ||
| 2811 | rp->scn_online = BFA_TRUE; | ||
| 2812 | } | ||
| 2813 | |||
| 2814 | if (bfa_fcs_lport_is_online(port)) | ||
| 2815 | bfa_fcs_lport_lip_scn_online(port); | ||
| 2816 | } | ||
| 2817 | |||
| 2818 | void | ||
| 2819 | bfa_cb_rport_scn_no_dev(void *rport) | ||
| 2820 | { | ||
| 2821 | struct bfa_fcs_rport_s *rp = rport; | ||
| 2822 | |||
| 2823 | bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE); | ||
| 2824 | rp->scn_online = BFA_FALSE; | ||
| 2825 | } | ||
| 2826 | |||
| 2827 | void | ||
| 2828 | bfa_cb_rport_scn_offline(struct bfa_s *bfa) | ||
| 2829 | { | ||
| 2830 | struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs; | ||
| 2831 | struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs); | ||
| 2832 | struct bfa_fcs_rport_s *rp; | ||
| 2833 | struct list_head *qe; | ||
| 2834 | |||
| 2835 | list_for_each(qe, &port->rport_q) { | ||
| 2836 | rp = (struct bfa_fcs_rport_s *) qe; | ||
| 2837 | bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE); | ||
| 2838 | rp->scn_online = BFA_FALSE; | ||
| 2839 | } | ||
| 2840 | } | ||
| 2841 | |||
| 2624 | /* | 2842 | /* |
| 2625 | * brief | 2843 | * brief |
| 2626 | * This routine is a static BFA callback when there is a QoS priority | 2844 | * This routine is a static BFA callback when there is a QoS priority |
| @@ -2808,6 +3026,9 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, | |||
| 2808 | struct bfa_rport_qos_attr_s qos_attr; | 3026 | struct bfa_rport_qos_attr_s qos_attr; |
| 2809 | struct bfa_fcs_lport_s *port = rport->port; | 3027 | struct bfa_fcs_lport_s *port = rport->port; |
| 2810 | bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed; | 3028 | bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed; |
| 3029 | struct bfa_port_attr_s port_attr; | ||
| 3030 | |||
| 3031 | bfa_fcport_get_attr(rport->fcs->bfa, &port_attr); | ||
| 2811 | 3032 | ||
| 2812 | memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s)); | 3033 | memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s)); |
| 2813 | memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s)); | 3034 | memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s)); |
| @@ -2838,7 +3059,8 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, | |||
| 2838 | rport_speed = | 3059 | rport_speed = |
| 2839 | bfa_fcport_get_ratelim_speed(rport->fcs->bfa); | 3060 | bfa_fcport_get_ratelim_speed(rport->fcs->bfa); |
| 2840 | 3061 | ||
| 2841 | if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port)) | 3062 | if ((bfa_fcs_lport_get_rport_max_speed(port) != |
| 3063 | BFA_PORT_SPEED_UNKNOWN) && (rport_speed < port_attr.speed)) | ||
| 2842 | rport_attr->trl_enforced = BFA_TRUE; | 3064 | rport_attr->trl_enforced = BFA_TRUE; |
| 2843 | } | 3065 | } |
| 2844 | } | 3066 | } |
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 75ca8752b9f4..0116c1032e25 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
| @@ -731,8 +731,7 @@ bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) | |||
| 731 | /* | 731 | /* |
| 732 | * Unlock the hw semaphore. Should be here only once per boot. | 732 | * Unlock the hw semaphore. Should be here only once per boot. |
| 733 | */ | 733 | */ |
| 734 | readl(iocpf->ioc->ioc_regs.ioc_sem_reg); | 734 | bfa_ioc_ownership_reset(iocpf->ioc); |
| 735 | writel(1, iocpf->ioc->ioc_regs.ioc_sem_reg); | ||
| 736 | 735 | ||
| 737 | /* | 736 | /* |
| 738 | * unlock init semaphore. | 737 | * unlock init semaphore. |
| @@ -1751,6 +1750,7 @@ bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc) | |||
| 1751 | attr->card_type = be32_to_cpu(attr->card_type); | 1750 | attr->card_type = be32_to_cpu(attr->card_type); |
| 1752 | attr->maxfrsize = be16_to_cpu(attr->maxfrsize); | 1751 | attr->maxfrsize = be16_to_cpu(attr->maxfrsize); |
| 1753 | ioc->fcmode = (attr->port_mode == BFI_PORT_MODE_FC); | 1752 | ioc->fcmode = (attr->port_mode == BFI_PORT_MODE_FC); |
| 1753 | attr->mfg_year = be16_to_cpu(attr->mfg_year); | ||
| 1754 | 1754 | ||
| 1755 | bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); | 1755 | bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); |
| 1756 | } | 1756 | } |
| @@ -2497,6 +2497,9 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, | |||
| 2497 | ad_attr->cna_capable = bfa_ioc_is_cna(ioc); | 2497 | ad_attr->cna_capable = bfa_ioc_is_cna(ioc); |
| 2498 | ad_attr->trunk_capable = (ad_attr->nports > 1) && | 2498 | ad_attr->trunk_capable = (ad_attr->nports > 1) && |
| 2499 | !bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz; | 2499 | !bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz; |
| 2500 | ad_attr->mfg_day = ioc_attr->mfg_day; | ||
| 2501 | ad_attr->mfg_month = ioc_attr->mfg_month; | ||
| 2502 | ad_attr->mfg_year = ioc_attr->mfg_year; | ||
| 2500 | } | 2503 | } |
| 2501 | 2504 | ||
| 2502 | enum bfa_ioc_type_e | 2505 | enum bfa_ioc_type_e |
| @@ -2923,7 +2926,7 @@ bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc) | |||
| 2923 | return; | 2926 | return; |
| 2924 | } | 2927 | } |
| 2925 | 2928 | ||
| 2926 | if (ioc->iocpf.poll_time >= BFA_IOC_TOV) | 2929 | if (ioc->iocpf.poll_time >= (3 * BFA_IOC_TOV)) |
| 2927 | bfa_iocpf_timeout(ioc); | 2930 | bfa_iocpf_timeout(ioc); |
| 2928 | else { | 2931 | else { |
| 2929 | ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; | 2932 | ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; |
| @@ -3016,7 +3019,6 @@ bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg) | |||
| 3016 | struct bfa_ablk_cfg_inst_s *cfg_inst; | 3019 | struct bfa_ablk_cfg_inst_s *cfg_inst; |
| 3017 | int i, j; | 3020 | int i, j; |
| 3018 | u16 be16; | 3021 | u16 be16; |
| 3019 | u32 be32; | ||
| 3020 | 3022 | ||
| 3021 | for (i = 0; i < BFA_ABLK_MAX; i++) { | 3023 | for (i = 0; i < BFA_ABLK_MAX; i++) { |
| 3022 | cfg_inst = &cfg->inst[i]; | 3024 | cfg_inst = &cfg->inst[i]; |
| @@ -3027,8 +3029,10 @@ bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg) | |||
| 3027 | cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16); | 3029 | cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16); |
| 3028 | be16 = cfg_inst->pf_cfg[j].num_vectors; | 3030 | be16 = cfg_inst->pf_cfg[j].num_vectors; |
| 3029 | cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16); | 3031 | cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16); |
| 3030 | be32 = cfg_inst->pf_cfg[j].bw; | 3032 | be16 = cfg_inst->pf_cfg[j].bw_min; |
| 3031 | cfg_inst->pf_cfg[j].bw = be16_to_cpu(be32); | 3033 | cfg_inst->pf_cfg[j].bw_min = be16_to_cpu(be16); |
| 3034 | be16 = cfg_inst->pf_cfg[j].bw_max; | ||
| 3035 | cfg_inst->pf_cfg[j].bw_max = be16_to_cpu(be16); | ||
| 3032 | } | 3036 | } |
| 3033 | } | 3037 | } |
| 3034 | } | 3038 | } |
| @@ -3170,7 +3174,8 @@ bfa_ablk_query(struct bfa_ablk_s *ablk, struct bfa_ablk_cfg_s *ablk_cfg, | |||
| 3170 | 3174 | ||
| 3171 | bfa_status_t | 3175 | bfa_status_t |
| 3172 | bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn, | 3176 | bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn, |
| 3173 | u8 port, enum bfi_pcifn_class personality, int bw, | 3177 | u8 port, enum bfi_pcifn_class personality, |
| 3178 | u16 bw_min, u16 bw_max, | ||
| 3174 | bfa_ablk_cbfn_t cbfn, void *cbarg) | 3179 | bfa_ablk_cbfn_t cbfn, void *cbarg) |
| 3175 | { | 3180 | { |
| 3176 | struct bfi_ablk_h2i_pf_req_s *m; | 3181 | struct bfi_ablk_h2i_pf_req_s *m; |
| @@ -3194,7 +3199,8 @@ bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn, | |||
| 3194 | bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE, | 3199 | bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE, |
| 3195 | bfa_ioc_portid(ablk->ioc)); | 3200 | bfa_ioc_portid(ablk->ioc)); |
| 3196 | m->pers = cpu_to_be16((u16)personality); | 3201 | m->pers = cpu_to_be16((u16)personality); |
| 3197 | m->bw = cpu_to_be32(bw); | 3202 | m->bw_min = cpu_to_be16(bw_min); |
| 3203 | m->bw_max = cpu_to_be16(bw_max); | ||
| 3198 | m->port = port; | 3204 | m->port = port; |
| 3199 | bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); | 3205 | bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); |
| 3200 | 3206 | ||
| @@ -3294,8 +3300,8 @@ bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port, enum bfa_mode_s mode, | |||
| 3294 | } | 3300 | } |
| 3295 | 3301 | ||
| 3296 | bfa_status_t | 3302 | bfa_status_t |
| 3297 | bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, int bw, | 3303 | bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, u16 bw_min, |
| 3298 | bfa_ablk_cbfn_t cbfn, void *cbarg) | 3304 | u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg) |
| 3299 | { | 3305 | { |
| 3300 | struct bfi_ablk_h2i_pf_req_s *m; | 3306 | struct bfi_ablk_h2i_pf_req_s *m; |
| 3301 | 3307 | ||
| @@ -3317,7 +3323,8 @@ bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, int bw, | |||
| 3317 | bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE, | 3323 | bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE, |
| 3318 | bfa_ioc_portid(ablk->ioc)); | 3324 | bfa_ioc_portid(ablk->ioc)); |
| 3319 | m->pcifn = (u8)pcifn; | 3325 | m->pcifn = (u8)pcifn; |
| 3320 | m->bw = cpu_to_be32(bw); | 3326 | m->bw_min = cpu_to_be16(bw_min); |
| 3327 | m->bw_max = cpu_to_be16(bw_max); | ||
| 3321 | bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); | 3328 | bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); |
| 3322 | 3329 | ||
| 3323 | return BFA_STATUS_OK; | 3330 | return BFA_STATUS_OK; |
| @@ -4680,22 +4687,25 @@ diag_tempsensor_comp(struct bfa_diag_s *diag, bfi_diag_ts_rsp_t *rsp) | |||
| 4680 | diag->tsensor.temp->temp = be16_to_cpu(rsp->temp); | 4687 | diag->tsensor.temp->temp = be16_to_cpu(rsp->temp); |
| 4681 | diag->tsensor.temp->ts_junc = rsp->ts_junc; | 4688 | diag->tsensor.temp->ts_junc = rsp->ts_junc; |
| 4682 | diag->tsensor.temp->ts_brd = rsp->ts_brd; | 4689 | diag->tsensor.temp->ts_brd = rsp->ts_brd; |
| 4683 | diag->tsensor.temp->status = BFA_STATUS_OK; | ||
| 4684 | 4690 | ||
| 4685 | if (rsp->ts_brd) { | 4691 | if (rsp->ts_brd) { |
| 4692 | /* tsensor.temp->status is brd_temp status */ | ||
| 4693 | diag->tsensor.temp->status = rsp->status; | ||
| 4686 | if (rsp->status == BFA_STATUS_OK) { | 4694 | if (rsp->status == BFA_STATUS_OK) { |
| 4687 | diag->tsensor.temp->brd_temp = | 4695 | diag->tsensor.temp->brd_temp = |
| 4688 | be16_to_cpu(rsp->brd_temp); | 4696 | be16_to_cpu(rsp->brd_temp); |
| 4689 | } else { | 4697 | } else |
| 4690 | bfa_trc(diag, rsp->status); | ||
| 4691 | diag->tsensor.temp->brd_temp = 0; | 4698 | diag->tsensor.temp->brd_temp = 0; |
| 4692 | diag->tsensor.temp->status = BFA_STATUS_DEVBUSY; | ||
| 4693 | } | ||
| 4694 | } | 4699 | } |
| 4700 | |||
| 4701 | bfa_trc(diag, rsp->status); | ||
| 4695 | bfa_trc(diag, rsp->ts_junc); | 4702 | bfa_trc(diag, rsp->ts_junc); |
| 4696 | bfa_trc(diag, rsp->temp); | 4703 | bfa_trc(diag, rsp->temp); |
| 4697 | bfa_trc(diag, rsp->ts_brd); | 4704 | bfa_trc(diag, rsp->ts_brd); |
| 4698 | bfa_trc(diag, rsp->brd_temp); | 4705 | bfa_trc(diag, rsp->brd_temp); |
| 4706 | |||
| 4707 | /* tsensor status is always good bcos we always have junction temp */ | ||
| 4708 | diag->tsensor.status = BFA_STATUS_OK; | ||
| 4699 | diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status); | 4709 | diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status); |
| 4700 | diag->tsensor.lock = 0; | 4710 | diag->tsensor.lock = 0; |
| 4701 | } | 4711 | } |
| @@ -4924,6 +4934,7 @@ bfa_diag_tsensor_query(struct bfa_diag_s *diag, | |||
| 4924 | diag->tsensor.temp = result; | 4934 | diag->tsensor.temp = result; |
| 4925 | diag->tsensor.cbfn = cbfn; | 4935 | diag->tsensor.cbfn = cbfn; |
| 4926 | diag->tsensor.cbarg = cbarg; | 4936 | diag->tsensor.cbarg = cbarg; |
| 4937 | diag->tsensor.status = BFA_STATUS_OK; | ||
| 4927 | 4938 | ||
| 4928 | /* Send msg to fw */ | 4939 | /* Send msg to fw */ |
| 4929 | diag_tempsensor_send(diag); | 4940 | diag_tempsensor_send(diag); |
| @@ -5615,7 +5626,7 @@ bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) | |||
| 5615 | } | 5626 | } |
| 5616 | bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read); | 5627 | bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read); |
| 5617 | bfa_timer_start(dconf->bfa, &dconf->timer, | 5628 | bfa_timer_start(dconf->bfa, &dconf->timer, |
| 5618 | bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); | 5629 | bfa_dconf_timer, dconf, 2 * BFA_DCONF_UPDATE_TOV); |
| 5619 | bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa), | 5630 | bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa), |
| 5620 | BFA_FLASH_PART_DRV, dconf->instance, | 5631 | BFA_FLASH_PART_DRV, dconf->instance, |
| 5621 | dconf->dconf, | 5632 | dconf->dconf, |
| @@ -5655,7 +5666,7 @@ bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf, | |||
| 5655 | break; | 5666 | break; |
| 5656 | case BFA_DCONF_SM_TIMEOUT: | 5667 | case BFA_DCONF_SM_TIMEOUT: |
| 5657 | bfa_sm_set_state(dconf, bfa_dconf_sm_ready); | 5668 | bfa_sm_set_state(dconf, bfa_dconf_sm_ready); |
| 5658 | bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_IOC_FAILED); | 5669 | bfa_ioc_suspend(&dconf->bfa->ioc); |
| 5659 | break; | 5670 | break; |
| 5660 | case BFA_DCONF_SM_EXIT: | 5671 | case BFA_DCONF_SM_EXIT: |
| 5661 | bfa_timer_stop(&dconf->timer); | 5672 | bfa_timer_stop(&dconf->timer); |
| @@ -5853,7 +5864,6 @@ bfa_dconf_init_cb(void *arg, bfa_status_t status) | |||
| 5853 | struct bfa_s *bfa = arg; | 5864 | struct bfa_s *bfa = arg; |
| 5854 | struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); | 5865 | struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); |
| 5855 | 5866 | ||
| 5856 | bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP); | ||
| 5857 | if (status == BFA_STATUS_OK) { | 5867 | if (status == BFA_STATUS_OK) { |
| 5858 | bfa_dconf_read_data_valid(bfa) = BFA_TRUE; | 5868 | bfa_dconf_read_data_valid(bfa) = BFA_TRUE; |
| 5859 | if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE) | 5869 | if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE) |
| @@ -5861,6 +5871,7 @@ bfa_dconf_init_cb(void *arg, bfa_status_t status) | |||
| 5861 | if (dconf->dconf->hdr.version != BFI_DCONF_VERSION) | 5871 | if (dconf->dconf->hdr.version != BFI_DCONF_VERSION) |
| 5862 | dconf->dconf->hdr.version = BFI_DCONF_VERSION; | 5872 | dconf->dconf->hdr.version = BFI_DCONF_VERSION; |
| 5863 | } | 5873 | } |
| 5874 | bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP); | ||
| 5864 | bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE); | 5875 | bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE); |
| 5865 | } | 5876 | } |
| 5866 | 5877 | ||
| @@ -5945,3 +5956,448 @@ bfa_dconf_modexit(struct bfa_s *bfa) | |||
| 5945 | struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); | 5956 | struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); |
| 5946 | bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT); | 5957 | bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT); |
| 5947 | } | 5958 | } |
| 5959 | |||
| 5960 | /* | ||
| 5961 | * FRU specific functions | ||
| 5962 | */ | ||
| 5963 | |||
| 5964 | #define BFA_FRU_DMA_BUF_SZ 0x02000 /* 8k dma buffer */ | ||
| 5965 | #define BFA_FRU_CHINOOK_MAX_SIZE 0x10000 | ||
| 5966 | #define BFA_FRU_LIGHTNING_MAX_SIZE 0x200 | ||
| 5967 | |||
| 5968 | static void | ||
| 5969 | bfa_fru_notify(void *cbarg, enum bfa_ioc_event_e event) | ||
| 5970 | { | ||
| 5971 | struct bfa_fru_s *fru = cbarg; | ||
| 5972 | |||
| 5973 | bfa_trc(fru, event); | ||
| 5974 | |||
| 5975 | switch (event) { | ||
| 5976 | case BFA_IOC_E_DISABLED: | ||
| 5977 | case BFA_IOC_E_FAILED: | ||
| 5978 | if (fru->op_busy) { | ||
| 5979 | fru->status = BFA_STATUS_IOC_FAILURE; | ||
| 5980 | fru->cbfn(fru->cbarg, fru->status); | ||
| 5981 | fru->op_busy = 0; | ||
| 5982 | } | ||
| 5983 | break; | ||
| 5984 | |||
| 5985 | default: | ||
| 5986 | break; | ||
| 5987 | } | ||
| 5988 | } | ||
| 5989 | |||
| 5990 | /* | ||
| 5991 | * Send fru write request. | ||
| 5992 | * | ||
| 5993 | * @param[in] cbarg - callback argument | ||
| 5994 | */ | ||
| 5995 | static void | ||
| 5996 | bfa_fru_write_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type) | ||
| 5997 | { | ||
| 5998 | struct bfa_fru_s *fru = cbarg; | ||
| 5999 | struct bfi_fru_write_req_s *msg = | ||
| 6000 | (struct bfi_fru_write_req_s *) fru->mb.msg; | ||
| 6001 | u32 len; | ||
| 6002 | |||
| 6003 | msg->offset = cpu_to_be32(fru->addr_off + fru->offset); | ||
| 6004 | len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ? | ||
| 6005 | fru->residue : BFA_FRU_DMA_BUF_SZ; | ||
| 6006 | msg->length = cpu_to_be32(len); | ||
| 6007 | |||
| 6008 | /* | ||
| 6009 | * indicate if it's the last msg of the whole write operation | ||
| 6010 | */ | ||
| 6011 | msg->last = (len == fru->residue) ? 1 : 0; | ||
| 6012 | |||
| 6013 | bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc)); | ||
| 6014 | bfa_alen_set(&msg->alen, len, fru->dbuf_pa); | ||
| 6015 | |||
| 6016 | memcpy(fru->dbuf_kva, fru->ubuf + fru->offset, len); | ||
| 6017 | bfa_ioc_mbox_queue(fru->ioc, &fru->mb); | ||
| 6018 | |||
| 6019 | fru->residue -= len; | ||
| 6020 | fru->offset += len; | ||
| 6021 | } | ||
| 6022 | |||
| 6023 | /* | ||
| 6024 | * Send fru read request. | ||
| 6025 | * | ||
| 6026 | * @param[in] cbarg - callback argument | ||
| 6027 | */ | ||
| 6028 | static void | ||
| 6029 | bfa_fru_read_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type) | ||
| 6030 | { | ||
| 6031 | struct bfa_fru_s *fru = cbarg; | ||
| 6032 | struct bfi_fru_read_req_s *msg = | ||
| 6033 | (struct bfi_fru_read_req_s *) fru->mb.msg; | ||
| 6034 | u32 len; | ||
| 6035 | |||
| 6036 | msg->offset = cpu_to_be32(fru->addr_off + fru->offset); | ||
| 6037 | len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ? | ||
| 6038 | fru->residue : BFA_FRU_DMA_BUF_SZ; | ||
| 6039 | msg->length = cpu_to_be32(len); | ||
| 6040 | bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc)); | ||
| 6041 | bfa_alen_set(&msg->alen, len, fru->dbuf_pa); | ||
| 6042 | bfa_ioc_mbox_queue(fru->ioc, &fru->mb); | ||
| 6043 | } | ||
| 6044 | |||
| 6045 | /* | ||
| 6046 | * Flash memory info API. | ||
| 6047 | * | ||
| 6048 | * @param[in] mincfg - minimal cfg variable | ||
| 6049 | */ | ||
| 6050 | u32 | ||
| 6051 | bfa_fru_meminfo(bfa_boolean_t mincfg) | ||
| 6052 | { | ||
| 6053 | /* min driver doesn't need fru */ | ||
| 6054 | if (mincfg) | ||
| 6055 | return 0; | ||
| 6056 | |||
| 6057 | return BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
| 6058 | } | ||
| 6059 | |||
| 6060 | /* | ||
| 6061 | * Flash attach API. | ||
| 6062 | * | ||
| 6063 | * @param[in] fru - fru structure | ||
| 6064 | * @param[in] ioc - ioc structure | ||
| 6065 | * @param[in] dev - device structure | ||
| 6066 | * @param[in] trcmod - trace module | ||
| 6067 | * @param[in] logmod - log module | ||
| 6068 | */ | ||
| 6069 | void | ||
| 6070 | bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, void *dev, | ||
| 6071 | struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg) | ||
| 6072 | { | ||
| 6073 | fru->ioc = ioc; | ||
| 6074 | fru->trcmod = trcmod; | ||
| 6075 | fru->cbfn = NULL; | ||
| 6076 | fru->cbarg = NULL; | ||
| 6077 | fru->op_busy = 0; | ||
| 6078 | |||
| 6079 | bfa_ioc_mbox_regisr(fru->ioc, BFI_MC_FRU, bfa_fru_intr, fru); | ||
| 6080 | bfa_q_qe_init(&fru->ioc_notify); | ||
| 6081 | bfa_ioc_notify_init(&fru->ioc_notify, bfa_fru_notify, fru); | ||
| 6082 | list_add_tail(&fru->ioc_notify.qe, &fru->ioc->notify_q); | ||
| 6083 | |||
| 6084 | /* min driver doesn't need fru */ | ||
| 6085 | if (mincfg) { | ||
| 6086 | fru->dbuf_kva = NULL; | ||
| 6087 | fru->dbuf_pa = 0; | ||
| 6088 | } | ||
| 6089 | } | ||
| 6090 | |||
| 6091 | /* | ||
| 6092 | * Claim memory for fru | ||
| 6093 | * | ||
| 6094 | * @param[in] fru - fru structure | ||
| 6095 | * @param[in] dm_kva - pointer to virtual memory address | ||
| 6096 | * @param[in] dm_pa - frusical memory address | ||
| 6097 | * @param[in] mincfg - minimal cfg variable | ||
| 6098 | */ | ||
| 6099 | void | ||
| 6100 | bfa_fru_memclaim(struct bfa_fru_s *fru, u8 *dm_kva, u64 dm_pa, | ||
| 6101 | bfa_boolean_t mincfg) | ||
| 6102 | { | ||
| 6103 | if (mincfg) | ||
| 6104 | return; | ||
| 6105 | |||
| 6106 | fru->dbuf_kva = dm_kva; | ||
| 6107 | fru->dbuf_pa = dm_pa; | ||
| 6108 | memset(fru->dbuf_kva, 0, BFA_FRU_DMA_BUF_SZ); | ||
| 6109 | dm_kva += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
| 6110 | dm_pa += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
| 6111 | } | ||
| 6112 | |||
| 6113 | /* | ||
| 6114 | * Update fru vpd image. | ||
| 6115 | * | ||
| 6116 | * @param[in] fru - fru structure | ||
| 6117 | * @param[in] buf - update data buffer | ||
| 6118 | * @param[in] len - data buffer length | ||
| 6119 | * @param[in] offset - offset relative to starting address | ||
| 6120 | * @param[in] cbfn - callback function | ||
| 6121 | * @param[in] cbarg - callback argument | ||
| 6122 | * | ||
| 6123 | * Return status. | ||
| 6124 | */ | ||
| 6125 | bfa_status_t | ||
| 6126 | bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, | ||
| 6127 | bfa_cb_fru_t cbfn, void *cbarg) | ||
| 6128 | { | ||
| 6129 | bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ); | ||
| 6130 | bfa_trc(fru, len); | ||
| 6131 | bfa_trc(fru, offset); | ||
| 6132 | |||
| 6133 | if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) | ||
| 6134 | return BFA_STATUS_FRU_NOT_PRESENT; | ||
| 6135 | |||
| 6136 | if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK) | ||
| 6137 | return BFA_STATUS_CMD_NOTSUPP; | ||
| 6138 | |||
| 6139 | if (!bfa_ioc_is_operational(fru->ioc)) | ||
| 6140 | return BFA_STATUS_IOC_NON_OP; | ||
| 6141 | |||
| 6142 | if (fru->op_busy) { | ||
| 6143 | bfa_trc(fru, fru->op_busy); | ||
| 6144 | return BFA_STATUS_DEVBUSY; | ||
| 6145 | } | ||
| 6146 | |||
| 6147 | fru->op_busy = 1; | ||
| 6148 | |||
| 6149 | fru->cbfn = cbfn; | ||
| 6150 | fru->cbarg = cbarg; | ||
| 6151 | fru->residue = len; | ||
| 6152 | fru->offset = 0; | ||
| 6153 | fru->addr_off = offset; | ||
| 6154 | fru->ubuf = buf; | ||
| 6155 | |||
| 6156 | bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ); | ||
| 6157 | |||
| 6158 | return BFA_STATUS_OK; | ||
| 6159 | } | ||
| 6160 | |||
| 6161 | /* | ||
| 6162 | * Read fru vpd image. | ||
| 6163 | * | ||
| 6164 | * @param[in] fru - fru structure | ||
| 6165 | * @param[in] buf - read data buffer | ||
| 6166 | * @param[in] len - data buffer length | ||
| 6167 | * @param[in] offset - offset relative to starting address | ||
| 6168 | * @param[in] cbfn - callback function | ||
| 6169 | * @param[in] cbarg - callback argument | ||
| 6170 | * | ||
| 6171 | * Return status. | ||
| 6172 | */ | ||
| 6173 | bfa_status_t | ||
| 6174 | bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, | ||
| 6175 | bfa_cb_fru_t cbfn, void *cbarg) | ||
| 6176 | { | ||
| 6177 | bfa_trc(fru, BFI_FRUVPD_H2I_READ_REQ); | ||
| 6178 | bfa_trc(fru, len); | ||
| 6179 | bfa_trc(fru, offset); | ||
| 6180 | |||
| 6181 | if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) | ||
| 6182 | return BFA_STATUS_FRU_NOT_PRESENT; | ||
| 6183 | |||
| 6184 | if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK) | ||
| 6185 | return BFA_STATUS_CMD_NOTSUPP; | ||
| 6186 | |||
| 6187 | if (!bfa_ioc_is_operational(fru->ioc)) | ||
| 6188 | return BFA_STATUS_IOC_NON_OP; | ||
| 6189 | |||
| 6190 | if (fru->op_busy) { | ||
| 6191 | bfa_trc(fru, fru->op_busy); | ||
| 6192 | return BFA_STATUS_DEVBUSY; | ||
| 6193 | } | ||
| 6194 | |||
| 6195 | fru->op_busy = 1; | ||
| 6196 | |||
| 6197 | fru->cbfn = cbfn; | ||
| 6198 | fru->cbarg = cbarg; | ||
| 6199 | fru->residue = len; | ||
| 6200 | fru->offset = 0; | ||
| 6201 | fru->addr_off = offset; | ||
| 6202 | fru->ubuf = buf; | ||
| 6203 | bfa_fru_read_send(fru, BFI_FRUVPD_H2I_READ_REQ); | ||
| 6204 | |||
| 6205 | return BFA_STATUS_OK; | ||
| 6206 | } | ||
| 6207 | |||
| 6208 | /* | ||
| 6209 | * Get maximum size fru vpd image. | ||
| 6210 | * | ||
| 6211 | * @param[in] fru - fru structure | ||
| 6212 | * @param[out] size - maximum size of fru vpd data | ||
| 6213 | * | ||
| 6214 | * Return status. | ||
| 6215 | */ | ||
| 6216 | bfa_status_t | ||
| 6217 | bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size) | ||
| 6218 | { | ||
| 6219 | if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) | ||
| 6220 | return BFA_STATUS_FRU_NOT_PRESENT; | ||
| 6221 | |||
| 6222 | if (!bfa_ioc_is_operational(fru->ioc)) | ||
| 6223 | return BFA_STATUS_IOC_NON_OP; | ||
| 6224 | |||
| 6225 | if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK) | ||
| 6226 | *max_size = BFA_FRU_CHINOOK_MAX_SIZE; | ||
| 6227 | else | ||
| 6228 | return BFA_STATUS_CMD_NOTSUPP; | ||
| 6229 | return BFA_STATUS_OK; | ||
| 6230 | } | ||
| 6231 | /* | ||
| 6232 | * tfru write. | ||
| 6233 | * | ||
| 6234 | * @param[in] fru - fru structure | ||
| 6235 | * @param[in] buf - update data buffer | ||
| 6236 | * @param[in] len - data buffer length | ||
| 6237 | * @param[in] offset - offset relative to starting address | ||
| 6238 | * @param[in] cbfn - callback function | ||
| 6239 | * @param[in] cbarg - callback argument | ||
| 6240 | * | ||
| 6241 | * Return status. | ||
| 6242 | */ | ||
| 6243 | bfa_status_t | ||
| 6244 | bfa_tfru_write(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, | ||
| 6245 | bfa_cb_fru_t cbfn, void *cbarg) | ||
| 6246 | { | ||
| 6247 | bfa_trc(fru, BFI_TFRU_H2I_WRITE_REQ); | ||
| 6248 | bfa_trc(fru, len); | ||
| 6249 | bfa_trc(fru, offset); | ||
| 6250 | bfa_trc(fru, *((u8 *) buf)); | ||
| 6251 | |||
| 6252 | if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) | ||
| 6253 | return BFA_STATUS_FRU_NOT_PRESENT; | ||
| 6254 | |||
| 6255 | if (!bfa_ioc_is_operational(fru->ioc)) | ||
| 6256 | return BFA_STATUS_IOC_NON_OP; | ||
| 6257 | |||
| 6258 | if (fru->op_busy) { | ||
| 6259 | bfa_trc(fru, fru->op_busy); | ||
| 6260 | return BFA_STATUS_DEVBUSY; | ||
| 6261 | } | ||
| 6262 | |||
| 6263 | fru->op_busy = 1; | ||
| 6264 | |||
| 6265 | fru->cbfn = cbfn; | ||
| 6266 | fru->cbarg = cbarg; | ||
| 6267 | fru->residue = len; | ||
| 6268 | fru->offset = 0; | ||
| 6269 | fru->addr_off = offset; | ||
| 6270 | fru->ubuf = buf; | ||
| 6271 | |||
| 6272 | bfa_fru_write_send(fru, BFI_TFRU_H2I_WRITE_REQ); | ||
| 6273 | |||
| 6274 | return BFA_STATUS_OK; | ||
| 6275 | } | ||
| 6276 | |||
| 6277 | /* | ||
| 6278 | * tfru read. | ||
| 6279 | * | ||
| 6280 | * @param[in] fru - fru structure | ||
| 6281 | * @param[in] buf - read data buffer | ||
| 6282 | * @param[in] len - data buffer length | ||
| 6283 | * @param[in] offset - offset relative to starting address | ||
| 6284 | * @param[in] cbfn - callback function | ||
| 6285 | * @param[in] cbarg - callback argument | ||
| 6286 | * | ||
| 6287 | * Return status. | ||
| 6288 | */ | ||
| 6289 | bfa_status_t | ||
| 6290 | bfa_tfru_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, | ||
| 6291 | bfa_cb_fru_t cbfn, void *cbarg) | ||
| 6292 | { | ||
| 6293 | bfa_trc(fru, BFI_TFRU_H2I_READ_REQ); | ||
| 6294 | bfa_trc(fru, len); | ||
| 6295 | bfa_trc(fru, offset); | ||
| 6296 | |||
| 6297 | if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) | ||
| 6298 | return BFA_STATUS_FRU_NOT_PRESENT; | ||
| 6299 | |||
| 6300 | if (!bfa_ioc_is_operational(fru->ioc)) | ||
| 6301 | return BFA_STATUS_IOC_NON_OP; | ||
| 6302 | |||
| 6303 | if (fru->op_busy) { | ||
| 6304 | bfa_trc(fru, fru->op_busy); | ||
| 6305 | return BFA_STATUS_DEVBUSY; | ||
| 6306 | } | ||
| 6307 | |||
| 6308 | fru->op_busy = 1; | ||
| 6309 | |||
| 6310 | fru->cbfn = cbfn; | ||
| 6311 | fru->cbarg = cbarg; | ||
| 6312 | fru->residue = len; | ||
| 6313 | fru->offset = 0; | ||
| 6314 | fru->addr_off = offset; | ||
| 6315 | fru->ubuf = buf; | ||
| 6316 | bfa_fru_read_send(fru, BFI_TFRU_H2I_READ_REQ); | ||
| 6317 | |||
| 6318 | return BFA_STATUS_OK; | ||
| 6319 | } | ||
| 6320 | |||
| 6321 | /* | ||
| 6322 | * Process fru response messages upon receiving interrupts. | ||
| 6323 | * | ||
| 6324 | * @param[in] fruarg - fru structure | ||
| 6325 | * @param[in] msg - message structure | ||
| 6326 | */ | ||
| 6327 | void | ||
| 6328 | bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg) | ||
| 6329 | { | ||
| 6330 | struct bfa_fru_s *fru = fruarg; | ||
| 6331 | struct bfi_fru_rsp_s *rsp = (struct bfi_fru_rsp_s *)msg; | ||
| 6332 | u32 status; | ||
| 6333 | |||
| 6334 | bfa_trc(fru, msg->mh.msg_id); | ||
| 6335 | |||
| 6336 | if (!fru->op_busy) { | ||
| 6337 | /* | ||
| 6338 | * receiving response after ioc failure | ||
| 6339 | */ | ||
| 6340 | bfa_trc(fru, 0x9999); | ||
| 6341 | return; | ||
| 6342 | } | ||
| 6343 | |||
| 6344 | switch (msg->mh.msg_id) { | ||
| 6345 | case BFI_FRUVPD_I2H_WRITE_RSP: | ||
| 6346 | case BFI_TFRU_I2H_WRITE_RSP: | ||
| 6347 | status = be32_to_cpu(rsp->status); | ||
| 6348 | bfa_trc(fru, status); | ||
| 6349 | |||
| 6350 | if (status != BFA_STATUS_OK || fru->residue == 0) { | ||
| 6351 | fru->status = status; | ||
| 6352 | fru->op_busy = 0; | ||
| 6353 | if (fru->cbfn) | ||
| 6354 | fru->cbfn(fru->cbarg, fru->status); | ||
| 6355 | } else { | ||
| 6356 | bfa_trc(fru, fru->offset); | ||
| 6357 | if (msg->mh.msg_id == BFI_FRUVPD_I2H_WRITE_RSP) | ||
| 6358 | bfa_fru_write_send(fru, | ||
| 6359 | BFI_FRUVPD_H2I_WRITE_REQ); | ||
| 6360 | else | ||
| 6361 | bfa_fru_write_send(fru, | ||
| 6362 | BFI_TFRU_H2I_WRITE_REQ); | ||
| 6363 | } | ||
| 6364 | break; | ||
| 6365 | case BFI_FRUVPD_I2H_READ_RSP: | ||
| 6366 | case BFI_TFRU_I2H_READ_RSP: | ||
| 6367 | status = be32_to_cpu(rsp->status); | ||
| 6368 | bfa_trc(fru, status); | ||
| 6369 | |||
| 6370 | if (status != BFA_STATUS_OK) { | ||
| 6371 | fru->status = status; | ||
| 6372 | fru->op_busy = 0; | ||
| 6373 | if (fru->cbfn) | ||
| 6374 | fru->cbfn(fru->cbarg, fru->status); | ||
| 6375 | } else { | ||
| 6376 | u32 len = be32_to_cpu(rsp->length); | ||
| 6377 | |||
| 6378 | bfa_trc(fru, fru->offset); | ||
| 6379 | bfa_trc(fru, len); | ||
| 6380 | |||
| 6381 | memcpy(fru->ubuf + fru->offset, fru->dbuf_kva, len); | ||
| 6382 | fru->residue -= len; | ||
| 6383 | fru->offset += len; | ||
| 6384 | |||
| 6385 | if (fru->residue == 0) { | ||
| 6386 | fru->status = status; | ||
| 6387 | fru->op_busy = 0; | ||
| 6388 | if (fru->cbfn) | ||
| 6389 | fru->cbfn(fru->cbarg, fru->status); | ||
| 6390 | } else { | ||
| 6391 | if (msg->mh.msg_id == BFI_FRUVPD_I2H_READ_RSP) | ||
| 6392 | bfa_fru_read_send(fru, | ||
| 6393 | BFI_FRUVPD_H2I_READ_REQ); | ||
| 6394 | else | ||
| 6395 | bfa_fru_read_send(fru, | ||
| 6396 | BFI_TFRU_H2I_READ_REQ); | ||
| 6397 | } | ||
| 6398 | } | ||
| 6399 | break; | ||
| 6400 | default: | ||
| 6401 | WARN_ON(1); | ||
| 6402 | } | ||
| 6403 | } | ||
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index b2856f96567c..23a90e7b7107 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h | |||
| @@ -702,6 +702,55 @@ void bfa_phy_memclaim(struct bfa_phy_s *phy, | |||
| 702 | void bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg); | 702 | void bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg); |
| 703 | 703 | ||
| 704 | /* | 704 | /* |
| 705 | * FRU module specific | ||
| 706 | */ | ||
| 707 | typedef void (*bfa_cb_fru_t) (void *cbarg, bfa_status_t status); | ||
| 708 | |||
| 709 | struct bfa_fru_s { | ||
| 710 | struct bfa_ioc_s *ioc; /* back pointer to ioc */ | ||
| 711 | struct bfa_trc_mod_s *trcmod; /* trace module */ | ||
| 712 | u8 op_busy; /* operation busy flag */ | ||
| 713 | u8 rsv[3]; | ||
| 714 | u32 residue; /* residual length */ | ||
| 715 | u32 offset; /* offset */ | ||
| 716 | bfa_status_t status; /* status */ | ||
| 717 | u8 *dbuf_kva; /* dma buf virtual address */ | ||
| 718 | u64 dbuf_pa; /* dma buf physical address */ | ||
| 719 | struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ | ||
| 720 | bfa_cb_fru_t cbfn; /* user callback function */ | ||
| 721 | void *cbarg; /* user callback arg */ | ||
| 722 | u8 *ubuf; /* user supplied buffer */ | ||
| 723 | struct bfa_cb_qe_s hcb_qe; /* comp: BFA callback qelem */ | ||
| 724 | u32 addr_off; /* fru address offset */ | ||
| 725 | struct bfa_mbox_cmd_s mb; /* mailbox */ | ||
| 726 | struct bfa_ioc_notify_s ioc_notify; /* ioc event notify */ | ||
| 727 | struct bfa_mem_dma_s fru_dma; | ||
| 728 | }; | ||
| 729 | |||
| 730 | #define BFA_FRU(__bfa) (&(__bfa)->modules.fru) | ||
| 731 | #define BFA_MEM_FRU_DMA(__bfa) (&(BFA_FRU(__bfa)->fru_dma)) | ||
| 732 | |||
| 733 | bfa_status_t bfa_fruvpd_update(struct bfa_fru_s *fru, | ||
| 734 | void *buf, u32 len, u32 offset, | ||
| 735 | bfa_cb_fru_t cbfn, void *cbarg); | ||
| 736 | bfa_status_t bfa_fruvpd_read(struct bfa_fru_s *fru, | ||
| 737 | void *buf, u32 len, u32 offset, | ||
| 738 | bfa_cb_fru_t cbfn, void *cbarg); | ||
| 739 | bfa_status_t bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size); | ||
| 740 | bfa_status_t bfa_tfru_write(struct bfa_fru_s *fru, | ||
| 741 | void *buf, u32 len, u32 offset, | ||
| 742 | bfa_cb_fru_t cbfn, void *cbarg); | ||
| 743 | bfa_status_t bfa_tfru_read(struct bfa_fru_s *fru, | ||
| 744 | void *buf, u32 len, u32 offset, | ||
| 745 | bfa_cb_fru_t cbfn, void *cbarg); | ||
| 746 | u32 bfa_fru_meminfo(bfa_boolean_t mincfg); | ||
| 747 | void bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, | ||
| 748 | void *dev, struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg); | ||
| 749 | void bfa_fru_memclaim(struct bfa_fru_s *fru, | ||
| 750 | u8 *dm_kva, u64 dm_pa, bfa_boolean_t mincfg); | ||
| 751 | void bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg); | ||
| 752 | |||
| 753 | /* | ||
| 705 | * Driver Config( dconf) specific | 754 | * Driver Config( dconf) specific |
| 706 | */ | 755 | */ |
| 707 | #define BFI_DCONF_SIGNATURE 0xabcdabcd | 756 | #define BFI_DCONF_SIGNATURE 0xabcdabcd |
| @@ -716,6 +765,7 @@ struct bfa_dconf_hdr_s { | |||
| 716 | struct bfa_dconf_s { | 765 | struct bfa_dconf_s { |
| 717 | struct bfa_dconf_hdr_s hdr; | 766 | struct bfa_dconf_hdr_s hdr; |
| 718 | struct bfa_lunmask_cfg_s lun_mask; | 767 | struct bfa_lunmask_cfg_s lun_mask; |
| 768 | struct bfa_throttle_cfg_s throttle_cfg; | ||
| 719 | }; | 769 | }; |
| 720 | #pragma pack() | 770 | #pragma pack() |
| 721 | 771 | ||
| @@ -738,6 +788,8 @@ struct bfa_dconf_mod_s { | |||
| 738 | #define bfa_dconf_read_data_valid(__bfa) \ | 788 | #define bfa_dconf_read_data_valid(__bfa) \ |
| 739 | (BFA_DCONF_MOD(__bfa)->read_data_valid) | 789 | (BFA_DCONF_MOD(__bfa)->read_data_valid) |
| 740 | #define BFA_DCONF_UPDATE_TOV 5000 /* memtest timeout in msec */ | 790 | #define BFA_DCONF_UPDATE_TOV 5000 /* memtest timeout in msec */ |
| 791 | #define bfa_dconf_get_min_cfg(__bfa) \ | ||
| 792 | (BFA_DCONF_MOD(__bfa)->min_cfg) | ||
| 741 | 793 | ||
| 742 | void bfa_dconf_modinit(struct bfa_s *bfa); | 794 | void bfa_dconf_modinit(struct bfa_s *bfa); |
| 743 | void bfa_dconf_modexit(struct bfa_s *bfa); | 795 | void bfa_dconf_modexit(struct bfa_s *bfa); |
| @@ -761,7 +813,8 @@ bfa_status_t bfa_dconf_update(struct bfa_s *bfa); | |||
| 761 | #define bfa_ioc_maxfrsize(__ioc) ((__ioc)->attr->maxfrsize) | 813 | #define bfa_ioc_maxfrsize(__ioc) ((__ioc)->attr->maxfrsize) |
| 762 | #define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit) | 814 | #define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit) |
| 763 | #define bfa_ioc_speed_sup(__ioc) \ | 815 | #define bfa_ioc_speed_sup(__ioc) \ |
| 764 | BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop) | 816 | ((bfa_ioc_is_cna(__ioc)) ? BFA_PORT_SPEED_10GBPS : \ |
| 817 | BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)) | ||
| 765 | #define bfa_ioc_get_nports(__ioc) \ | 818 | #define bfa_ioc_get_nports(__ioc) \ |
| 766 | BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop) | 819 | BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop) |
| 767 | 820 | ||
| @@ -885,12 +938,12 @@ bfa_status_t bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port, | |||
| 885 | enum bfa_mode_s mode, int max_pf, int max_vf, | 938 | enum bfa_mode_s mode, int max_pf, int max_vf, |
| 886 | bfa_ablk_cbfn_t cbfn, void *cbarg); | 939 | bfa_ablk_cbfn_t cbfn, void *cbarg); |
| 887 | bfa_status_t bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn, | 940 | bfa_status_t bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn, |
| 888 | u8 port, enum bfi_pcifn_class personality, int bw, | 941 | u8 port, enum bfi_pcifn_class personality, |
| 889 | bfa_ablk_cbfn_t cbfn, void *cbarg); | 942 | u16 bw_min, u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg); |
| 890 | bfa_status_t bfa_ablk_pf_delete(struct bfa_ablk_s *ablk, int pcifn, | 943 | bfa_status_t bfa_ablk_pf_delete(struct bfa_ablk_s *ablk, int pcifn, |
| 891 | bfa_ablk_cbfn_t cbfn, void *cbarg); | 944 | bfa_ablk_cbfn_t cbfn, void *cbarg); |
| 892 | bfa_status_t bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, int bw, | 945 | bfa_status_t bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, |
| 893 | bfa_ablk_cbfn_t cbfn, void *cbarg); | 946 | u16 bw_min, u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg); |
| 894 | bfa_status_t bfa_ablk_optrom_en(struct bfa_ablk_s *ablk, | 947 | bfa_status_t bfa_ablk_optrom_en(struct bfa_ablk_s *ablk, |
| 895 | bfa_ablk_cbfn_t cbfn, void *cbarg); | 948 | bfa_ablk_cbfn_t cbfn, void *cbarg); |
| 896 | bfa_status_t bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk, | 949 | bfa_status_t bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk, |
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 2eb0c6a2938d..de4e726a1263 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c | |||
| @@ -57,13 +57,6 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) | |||
| 57 | u32 usecnt; | 57 | u32 usecnt; |
| 58 | struct bfi_ioc_image_hdr_s fwhdr; | 58 | struct bfi_ioc_image_hdr_s fwhdr; |
| 59 | 59 | ||
| 60 | /* | ||
| 61 | * If bios boot (flash based) -- do not increment usage count | ||
| 62 | */ | ||
| 63 | if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) < | ||
| 64 | BFA_IOC_FWIMG_MINSZ) | ||
| 65 | return BFA_TRUE; | ||
| 66 | |||
| 67 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); | 60 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); |
| 68 | usecnt = readl(ioc->ioc_regs.ioc_usage_reg); | 61 | usecnt = readl(ioc->ioc_regs.ioc_usage_reg); |
| 69 | 62 | ||
| @@ -115,13 +108,6 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) | |||
| 115 | u32 usecnt; | 108 | u32 usecnt; |
| 116 | 109 | ||
| 117 | /* | 110 | /* |
| 118 | * If bios boot (flash based) -- do not decrement usage count | ||
| 119 | */ | ||
| 120 | if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) < | ||
| 121 | BFA_IOC_FWIMG_MINSZ) | ||
| 122 | return; | ||
| 123 | |||
| 124 | /* | ||
| 125 | * decrement usage count | 111 | * decrement usage count |
| 126 | */ | 112 | */ |
| 127 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); | 113 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); |
| @@ -400,13 +386,12 @@ static void | |||
| 400 | bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc) | 386 | bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc) |
| 401 | { | 387 | { |
| 402 | 388 | ||
| 403 | if (bfa_ioc_is_cna(ioc)) { | 389 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); |
| 404 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); | 390 | writel(0, ioc->ioc_regs.ioc_usage_reg); |
| 405 | writel(0, ioc->ioc_regs.ioc_usage_reg); | 391 | readl(ioc->ioc_regs.ioc_usage_sem_reg); |
| 406 | readl(ioc->ioc_regs.ioc_usage_sem_reg); | 392 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); |
| 407 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); | ||
| 408 | } | ||
| 409 | 393 | ||
| 394 | writel(0, ioc->ioc_regs.ioc_fail_sync); | ||
| 410 | /* | 395 | /* |
| 411 | * Read the hw sem reg to make sure that it is locked | 396 | * Read the hw sem reg to make sure that it is locked |
| 412 | * before we clear it. If it is not locked, writing 1 | 397 | * before we clear it. If it is not locked, writing 1 |
| @@ -759,25 +744,6 @@ bfa_ioc_ct2_mem_init(void __iomem *rb) | |||
| 759 | void | 744 | void |
| 760 | bfa_ioc_ct2_mac_reset(void __iomem *rb) | 745 | bfa_ioc_ct2_mac_reset(void __iomem *rb) |
| 761 | { | 746 | { |
| 762 | u32 r32; | ||
| 763 | |||
| 764 | bfa_ioc_ct2_sclk_init(rb); | ||
| 765 | bfa_ioc_ct2_lclk_init(rb); | ||
| 766 | |||
| 767 | /* | ||
| 768 | * release soft reset on s_clk & l_clk | ||
| 769 | */ | ||
| 770 | r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); | ||
| 771 | writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET, | ||
| 772 | (rb + CT2_APP_PLL_SCLK_CTL_REG)); | ||
| 773 | |||
| 774 | /* | ||
| 775 | * release soft reset on s_clk & l_clk | ||
| 776 | */ | ||
| 777 | r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
| 778 | writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET, | ||
| 779 | (rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
| 780 | |||
| 781 | /* put port0, port1 MAC & AHB in reset */ | 747 | /* put port0, port1 MAC & AHB in reset */ |
| 782 | writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET), | 748 | writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET), |
| 783 | rb + CT2_CSI_MAC_CONTROL_REG(0)); | 749 | rb + CT2_CSI_MAC_CONTROL_REG(0)); |
| @@ -785,8 +751,21 @@ bfa_ioc_ct2_mac_reset(void __iomem *rb) | |||
| 785 | rb + CT2_CSI_MAC_CONTROL_REG(1)); | 751 | rb + CT2_CSI_MAC_CONTROL_REG(1)); |
| 786 | } | 752 | } |
| 787 | 753 | ||
| 754 | static void | ||
| 755 | bfa_ioc_ct2_enable_flash(void __iomem *rb) | ||
| 756 | { | ||
| 757 | u32 r32; | ||
| 758 | |||
| 759 | r32 = readl((rb + PSS_GPIO_OUT_REG)); | ||
| 760 | writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG)); | ||
| 761 | r32 = readl((rb + PSS_GPIO_OE_REG)); | ||
| 762 | writel(r32 | 1, (rb + PSS_GPIO_OE_REG)); | ||
| 763 | } | ||
| 764 | |||
| 788 | #define CT2_NFC_MAX_DELAY 1000 | 765 | #define CT2_NFC_MAX_DELAY 1000 |
| 789 | #define CT2_NFC_VER_VALID 0x143 | 766 | #define CT2_NFC_PAUSE_MAX_DELAY 4000 |
| 767 | #define CT2_NFC_VER_VALID 0x147 | ||
| 768 | #define CT2_NFC_STATE_RUNNING 0x20000001 | ||
| 790 | #define BFA_IOC_PLL_POLL 1000000 | 769 | #define BFA_IOC_PLL_POLL 1000000 |
| 791 | 770 | ||
| 792 | static bfa_boolean_t | 771 | static bfa_boolean_t |
| @@ -802,6 +781,20 @@ bfa_ioc_ct2_nfc_halted(void __iomem *rb) | |||
| 802 | } | 781 | } |
| 803 | 782 | ||
| 804 | static void | 783 | static void |
| 784 | bfa_ioc_ct2_nfc_halt(void __iomem *rb) | ||
| 785 | { | ||
| 786 | int i; | ||
| 787 | |||
| 788 | writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG); | ||
| 789 | for (i = 0; i < CT2_NFC_MAX_DELAY; i++) { | ||
| 790 | if (bfa_ioc_ct2_nfc_halted(rb)) | ||
| 791 | break; | ||
| 792 | udelay(1000); | ||
| 793 | } | ||
| 794 | WARN_ON(!bfa_ioc_ct2_nfc_halted(rb)); | ||
| 795 | } | ||
| 796 | |||
| 797 | static void | ||
| 805 | bfa_ioc_ct2_nfc_resume(void __iomem *rb) | 798 | bfa_ioc_ct2_nfc_resume(void __iomem *rb) |
| 806 | { | 799 | { |
| 807 | u32 r32; | 800 | u32 r32; |
| @@ -817,105 +810,142 @@ bfa_ioc_ct2_nfc_resume(void __iomem *rb) | |||
| 817 | WARN_ON(1); | 810 | WARN_ON(1); |
| 818 | } | 811 | } |
| 819 | 812 | ||
| 820 | bfa_status_t | 813 | static void |
| 821 | bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) | 814 | bfa_ioc_ct2_clk_reset(void __iomem *rb) |
| 822 | { | 815 | { |
| 823 | u32 wgn, r32, nfc_ver, i; | 816 | u32 r32; |
| 824 | 817 | ||
| 825 | wgn = readl(rb + CT2_WGN_STATUS); | 818 | bfa_ioc_ct2_sclk_init(rb); |
| 826 | nfc_ver = readl(rb + CT2_RSC_GPR15_REG); | 819 | bfa_ioc_ct2_lclk_init(rb); |
| 827 | 820 | ||
| 828 | if ((wgn == (__A2T_AHB_LOAD | __WGN_READY)) && | 821 | /* |
| 829 | (nfc_ver >= CT2_NFC_VER_VALID)) { | 822 | * release soft reset on s_clk & l_clk |
| 830 | if (bfa_ioc_ct2_nfc_halted(rb)) | 823 | */ |
| 831 | bfa_ioc_ct2_nfc_resume(rb); | 824 | r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); |
| 825 | writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET, | ||
| 826 | (rb + CT2_APP_PLL_SCLK_CTL_REG)); | ||
| 832 | 827 | ||
| 833 | writel(__RESET_AND_START_SCLK_LCLK_PLLS, | 828 | r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); |
| 834 | rb + CT2_CSI_FW_CTL_SET_REG); | 829 | writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET, |
| 830 | (rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
| 835 | 831 | ||
| 836 | for (i = 0; i < BFA_IOC_PLL_POLL; i++) { | 832 | } |
| 837 | r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG); | ||
| 838 | if (r32 & __RESET_AND_START_SCLK_LCLK_PLLS) | ||
| 839 | break; | ||
| 840 | } | ||
| 841 | 833 | ||
| 842 | WARN_ON(!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS)); | 834 | static void |
| 835 | bfa_ioc_ct2_nfc_clk_reset(void __iomem *rb) | ||
| 836 | { | ||
| 837 | u32 r32, i; | ||
| 843 | 838 | ||
| 844 | for (i = 0; i < BFA_IOC_PLL_POLL; i++) { | 839 | r32 = readl((rb + PSS_CTL_REG)); |
| 845 | r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG); | 840 | r32 |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET); |
| 846 | if (!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS)) | 841 | writel(r32, (rb + PSS_CTL_REG)); |
| 847 | break; | 842 | |
| 848 | } | 843 | writel(__RESET_AND_START_SCLK_LCLK_PLLS, rb + CT2_CSI_FW_CTL_SET_REG); |
| 849 | 844 | ||
| 850 | WARN_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS); | 845 | for (i = 0; i < BFA_IOC_PLL_POLL; i++) { |
| 846 | r32 = readl(rb + CT2_NFC_FLASH_STS_REG); | ||
| 847 | |||
| 848 | if ((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)) | ||
| 849 | break; | ||
| 850 | } | ||
| 851 | WARN_ON(!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)); | ||
| 852 | |||
| 853 | for (i = 0; i < BFA_IOC_PLL_POLL; i++) { | ||
| 854 | r32 = readl(rb + CT2_NFC_FLASH_STS_REG); | ||
| 855 | |||
| 856 | if (!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)) | ||
| 857 | break; | ||
| 858 | } | ||
| 859 | WARN_ON((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)); | ||
| 860 | |||
| 861 | r32 = readl(rb + CT2_CSI_FW_CTL_REG); | ||
| 862 | WARN_ON((r32 & __RESET_AND_START_SCLK_LCLK_PLLS)); | ||
| 863 | } | ||
| 864 | |||
| 865 | static void | ||
| 866 | bfa_ioc_ct2_wait_till_nfc_running(void __iomem *rb) | ||
| 867 | { | ||
| 868 | u32 r32; | ||
| 869 | int i; | ||
| 870 | |||
| 871 | if (bfa_ioc_ct2_nfc_halted(rb)) | ||
| 872 | bfa_ioc_ct2_nfc_resume(rb); | ||
| 873 | for (i = 0; i < CT2_NFC_PAUSE_MAX_DELAY; i++) { | ||
| 874 | r32 = readl(rb + CT2_NFC_STS_REG); | ||
| 875 | if (r32 == CT2_NFC_STATE_RUNNING) | ||
| 876 | return; | ||
| 851 | udelay(1000); | 877 | udelay(1000); |
| 878 | } | ||
| 852 | 879 | ||
| 853 | r32 = readl(rb + CT2_CSI_FW_CTL_REG); | 880 | r32 = readl(rb + CT2_NFC_STS_REG); |
| 854 | WARN_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS); | 881 | WARN_ON(!(r32 == CT2_NFC_STATE_RUNNING)); |
| 855 | } else { | 882 | } |
| 856 | writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG); | ||
| 857 | for (i = 0; i < CT2_NFC_MAX_DELAY; i++) { | ||
| 858 | r32 = readl(rb + CT2_NFC_CSR_SET_REG); | ||
| 859 | if (r32 & __NFC_CONTROLLER_HALTED) | ||
| 860 | break; | ||
| 861 | udelay(1000); | ||
| 862 | } | ||
| 863 | 883 | ||
| 864 | bfa_ioc_ct2_mac_reset(rb); | 884 | bfa_status_t |
| 865 | bfa_ioc_ct2_sclk_init(rb); | 885 | bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) |
| 866 | bfa_ioc_ct2_lclk_init(rb); | 886 | { |
| 887 | u32 wgn, r32, nfc_ver; | ||
| 867 | 888 | ||
| 868 | /* | 889 | wgn = readl(rb + CT2_WGN_STATUS); |
| 869 | * release soft reset on s_clk & l_clk | ||
| 870 | */ | ||
| 871 | r32 = readl(rb + CT2_APP_PLL_SCLK_CTL_REG); | ||
| 872 | writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET, | ||
| 873 | (rb + CT2_APP_PLL_SCLK_CTL_REG)); | ||
| 874 | 890 | ||
| 891 | if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) { | ||
| 875 | /* | 892 | /* |
| 876 | * release soft reset on s_clk & l_clk | 893 | * If flash is corrupted, enable flash explicitly |
| 877 | */ | 894 | */ |
| 878 | r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG); | 895 | bfa_ioc_ct2_clk_reset(rb); |
| 879 | writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET, | 896 | bfa_ioc_ct2_enable_flash(rb); |
| 880 | (rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
| 881 | } | ||
| 882 | 897 | ||
| 883 | /* | 898 | bfa_ioc_ct2_mac_reset(rb); |
| 884 | * Announce flash device presence, if flash was corrupted. | 899 | |
| 885 | */ | 900 | bfa_ioc_ct2_clk_reset(rb); |
| 886 | if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) { | 901 | bfa_ioc_ct2_enable_flash(rb); |
| 887 | r32 = readl(rb + PSS_GPIO_OUT_REG); | 902 | |
| 888 | writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG)); | 903 | } else { |
| 889 | r32 = readl(rb + PSS_GPIO_OE_REG); | 904 | nfc_ver = readl(rb + CT2_RSC_GPR15_REG); |
| 890 | writel(r32 | 1, (rb + PSS_GPIO_OE_REG)); | 905 | |
| 906 | if ((nfc_ver >= CT2_NFC_VER_VALID) && | ||
| 907 | (wgn == (__A2T_AHB_LOAD | __WGN_READY))) { | ||
| 908 | |||
| 909 | bfa_ioc_ct2_wait_till_nfc_running(rb); | ||
| 910 | |||
| 911 | bfa_ioc_ct2_nfc_clk_reset(rb); | ||
| 912 | } else { | ||
| 913 | bfa_ioc_ct2_nfc_halt(rb); | ||
| 914 | |||
| 915 | bfa_ioc_ct2_clk_reset(rb); | ||
| 916 | bfa_ioc_ct2_mac_reset(rb); | ||
| 917 | bfa_ioc_ct2_clk_reset(rb); | ||
| 918 | |||
| 919 | } | ||
| 891 | } | 920 | } |
| 892 | 921 | ||
| 893 | /* | 922 | /* |
| 894 | * Mask the interrupts and clear any | 923 | * Mask the interrupts and clear any |
| 895 | * pending interrupts. | 924 | * pending interrupts left by BIOS/EFI |
| 896 | */ | 925 | */ |
| 926 | |||
| 897 | writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK)); | 927 | writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK)); |
| 898 | writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK)); | 928 | writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK)); |
| 899 | 929 | ||
| 900 | /* For first time initialization, no need to clear interrupts */ | 930 | /* For first time initialization, no need to clear interrupts */ |
| 901 | r32 = readl(rb + HOST_SEM5_REG); | 931 | r32 = readl(rb + HOST_SEM5_REG); |
| 902 | if (r32 & 0x1) { | 932 | if (r32 & 0x1) { |
| 903 | r32 = readl(rb + CT2_LPU0_HOSTFN_CMD_STAT); | 933 | r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); |
| 904 | if (r32 == 1) { | 934 | if (r32 == 1) { |
| 905 | writel(1, rb + CT2_LPU0_HOSTFN_CMD_STAT); | 935 | writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT)); |
| 906 | readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); | 936 | readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); |
| 907 | } | 937 | } |
| 908 | r32 = readl(rb + CT2_LPU1_HOSTFN_CMD_STAT); | 938 | r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT)); |
| 909 | if (r32 == 1) { | 939 | if (r32 == 1) { |
| 910 | writel(1, rb + CT2_LPU1_HOSTFN_CMD_STAT); | 940 | writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT)); |
| 911 | readl(rb + CT2_LPU1_HOSTFN_CMD_STAT); | 941 | readl((rb + CT2_LPU1_HOSTFN_CMD_STAT)); |
| 912 | } | 942 | } |
| 913 | } | 943 | } |
| 914 | 944 | ||
| 915 | bfa_ioc_ct2_mem_init(rb); | 945 | bfa_ioc_ct2_mem_init(rb); |
| 916 | 946 | ||
| 917 | writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC0_STATE_REG); | 947 | writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG)); |
| 918 | writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC1_STATE_REG); | 948 | writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG)); |
| 919 | 949 | ||
| 920 | return BFA_STATUS_OK; | 950 | return BFA_STATUS_OK; |
| 921 | } | 951 | } |
diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h index 189fff71e3c2..a14c784ff3fc 100644 --- a/drivers/scsi/bfa/bfa_modules.h +++ b/drivers/scsi/bfa/bfa_modules.h | |||
| @@ -45,6 +45,7 @@ struct bfa_modules_s { | |||
| 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 | struct bfa_dconf_mod_s dconf_mod; /* DCONF common module */ |
| 48 | struct bfa_fru_s fru; /* fru module */ | ||
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 50 | /* | 51 | /* |
diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c index 95e4ad8759ac..8ea7697deb9b 100644 --- a/drivers/scsi/bfa/bfa_port.c +++ b/drivers/scsi/bfa/bfa_port.c | |||
| @@ -250,6 +250,12 @@ bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn, | |||
| 250 | return BFA_STATUS_IOC_FAILURE; | 250 | return BFA_STATUS_IOC_FAILURE; |
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | /* if port is d-port enabled, return error */ | ||
| 254 | if (port->dport_enabled) { | ||
| 255 | bfa_trc(port, BFA_STATUS_DPORT_ERR); | ||
| 256 | return BFA_STATUS_DPORT_ERR; | ||
| 257 | } | ||
| 258 | |||
| 253 | if (port->endis_pending) { | 259 | if (port->endis_pending) { |
| 254 | bfa_trc(port, BFA_STATUS_DEVBUSY); | 260 | bfa_trc(port, BFA_STATUS_DEVBUSY); |
| 255 | return BFA_STATUS_DEVBUSY; | 261 | return BFA_STATUS_DEVBUSY; |
| @@ -300,6 +306,12 @@ bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn, | |||
| 300 | return BFA_STATUS_IOC_FAILURE; | 306 | return BFA_STATUS_IOC_FAILURE; |
| 301 | } | 307 | } |
| 302 | 308 | ||
| 309 | /* if port is d-port enabled, return error */ | ||
| 310 | if (port->dport_enabled) { | ||
| 311 | bfa_trc(port, BFA_STATUS_DPORT_ERR); | ||
| 312 | return BFA_STATUS_DPORT_ERR; | ||
| 313 | } | ||
| 314 | |||
| 303 | if (port->endis_pending) { | 315 | if (port->endis_pending) { |
| 304 | bfa_trc(port, BFA_STATUS_DEVBUSY); | 316 | bfa_trc(port, BFA_STATUS_DEVBUSY); |
| 305 | return BFA_STATUS_DEVBUSY; | 317 | return BFA_STATUS_DEVBUSY; |
| @@ -431,6 +443,10 @@ bfa_port_notify(void *arg, enum bfa_ioc_event_e event) | |||
| 431 | port->endis_cbfn = NULL; | 443 | port->endis_cbfn = NULL; |
| 432 | port->endis_pending = BFA_FALSE; | 444 | port->endis_pending = BFA_FALSE; |
| 433 | } | 445 | } |
| 446 | |||
| 447 | /* clear D-port mode */ | ||
| 448 | if (port->dport_enabled) | ||
| 449 | bfa_port_set_dportenabled(port, BFA_FALSE); | ||
| 434 | break; | 450 | break; |
| 435 | default: | 451 | default: |
| 436 | break; | 452 | break; |
| @@ -467,6 +483,7 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, | |||
| 467 | port->stats_cbfn = NULL; | 483 | port->stats_cbfn = NULL; |
| 468 | port->endis_cbfn = NULL; | 484 | port->endis_cbfn = NULL; |
| 469 | port->pbc_disabled = BFA_FALSE; | 485 | port->pbc_disabled = BFA_FALSE; |
| 486 | port->dport_enabled = BFA_FALSE; | ||
| 470 | 487 | ||
| 471 | bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port); | 488 | bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port); |
| 472 | bfa_q_qe_init(&port->ioc_notify); | 489 | bfa_q_qe_init(&port->ioc_notify); |
| @@ -483,6 +500,21 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, | |||
| 483 | } | 500 | } |
| 484 | 501 | ||
| 485 | /* | 502 | /* |
| 503 | * bfa_port_set_dportenabled(); | ||
| 504 | * | ||
| 505 | * Port module- set pbc disabled flag | ||
| 506 | * | ||
| 507 | * @param[in] port - Pointer to the Port module data structure | ||
| 508 | * | ||
| 509 | * @return void | ||
| 510 | */ | ||
| 511 | void | ||
| 512 | bfa_port_set_dportenabled(struct bfa_port_s *port, bfa_boolean_t enabled) | ||
| 513 | { | ||
| 514 | port->dport_enabled = enabled; | ||
| 515 | } | ||
| 516 | |||
| 517 | /* | ||
| 486 | * CEE module specific definitions | 518 | * CEE module specific definitions |
| 487 | */ | 519 | */ |
| 488 | 520 | ||
diff --git a/drivers/scsi/bfa/bfa_port.h b/drivers/scsi/bfa/bfa_port.h index 947f897328d6..2fcab6bc6280 100644 --- a/drivers/scsi/bfa/bfa_port.h +++ b/drivers/scsi/bfa/bfa_port.h | |||
| @@ -45,6 +45,7 @@ struct bfa_port_s { | |||
| 45 | bfa_status_t endis_status; | 45 | bfa_status_t endis_status; |
| 46 | struct bfa_ioc_notify_s ioc_notify; | 46 | struct bfa_ioc_notify_s ioc_notify; |
| 47 | bfa_boolean_t pbc_disabled; | 47 | bfa_boolean_t pbc_disabled; |
| 48 | bfa_boolean_t dport_enabled; | ||
| 48 | struct bfa_mem_dma_s port_dma; | 49 | struct bfa_mem_dma_s port_dma; |
| 49 | }; | 50 | }; |
| 50 | 51 | ||
| @@ -66,6 +67,8 @@ bfa_status_t bfa_port_disable(struct bfa_port_s *port, | |||
| 66 | u32 bfa_port_meminfo(void); | 67 | u32 bfa_port_meminfo(void); |
| 67 | void bfa_port_mem_claim(struct bfa_port_s *port, | 68 | void bfa_port_mem_claim(struct bfa_port_s *port, |
| 68 | u8 *dma_kva, u64 dma_pa); | 69 | u8 *dma_kva, u64 dma_pa); |
| 70 | void bfa_port_set_dportenabled(struct bfa_port_s *port, | ||
| 71 | bfa_boolean_t enabled); | ||
| 69 | 72 | ||
| 70 | /* | 73 | /* |
| 71 | * CEE declaration | 74 | * CEE declaration |
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index b2538d60db34..299c1c889b33 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c | |||
| @@ -67,6 +67,9 @@ enum bfa_fcport_sm_event { | |||
| 67 | BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ | 67 | BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ |
| 68 | BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ | 68 | BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ |
| 69 | BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ | 69 | BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ |
| 70 | BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */ | ||
| 71 | BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */ | ||
| 72 | BFA_FCPORT_SM_FAA_MISCONFIG = 12, /* FAA misconfiguratin */ | ||
| 70 | }; | 73 | }; |
| 71 | 74 | ||
| 72 | /* | 75 | /* |
| @@ -197,6 +200,10 @@ static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, | |||
| 197 | enum bfa_fcport_sm_event event); | 200 | enum bfa_fcport_sm_event event); |
| 198 | static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, | 201 | static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, |
| 199 | enum bfa_fcport_sm_event event); | 202 | enum bfa_fcport_sm_event event); |
| 203 | static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, | ||
| 204 | enum bfa_fcport_sm_event event); | ||
| 205 | static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, | ||
| 206 | enum bfa_fcport_sm_event event); | ||
| 200 | 207 | ||
| 201 | static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, | 208 | static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, |
| 202 | enum bfa_fcport_ln_sm_event event); | 209 | enum bfa_fcport_ln_sm_event event); |
| @@ -226,6 +233,8 @@ static struct bfa_sm_table_s hal_port_sm_table[] = { | |||
| 226 | {BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED}, | 233 | {BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED}, |
| 227 | {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, | 234 | {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, |
| 228 | {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, | 235 | {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, |
| 236 | {BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT}, | ||
| 237 | {BFA_SM(bfa_fcport_sm_faa_misconfig), BFA_PORT_ST_FAA_MISCONFIG}, | ||
| 229 | }; | 238 | }; |
| 230 | 239 | ||
| 231 | 240 | ||
| @@ -1244,6 +1253,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
| 1244 | * Just ignore | 1253 | * Just ignore |
| 1245 | */ | 1254 | */ |
| 1246 | break; | 1255 | break; |
| 1256 | case BFA_LPS_SM_SET_N2N_PID: | ||
| 1257 | /* | ||
| 1258 | * When topology is set to loop, bfa_lps_set_n2n_pid() sends | ||
| 1259 | * this event. Ignore this event. | ||
| 1260 | */ | ||
| 1261 | break; | ||
| 1247 | 1262 | ||
| 1248 | default: | 1263 | default: |
| 1249 | bfa_sm_fault(lps->bfa, event); | 1264 | bfa_sm_fault(lps->bfa, event); |
| @@ -1261,6 +1276,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
| 1261 | 1276 | ||
| 1262 | switch (event) { | 1277 | switch (event) { |
| 1263 | case BFA_LPS_SM_FWRSP: | 1278 | case BFA_LPS_SM_FWRSP: |
| 1279 | case BFA_LPS_SM_OFFLINE: | ||
| 1264 | if (lps->status == BFA_STATUS_OK) { | 1280 | if (lps->status == BFA_STATUS_OK) { |
| 1265 | bfa_sm_set_state(lps, bfa_lps_sm_online); | 1281 | bfa_sm_set_state(lps, bfa_lps_sm_online); |
| 1266 | if (lps->fdisc) | 1282 | if (lps->fdisc) |
| @@ -1289,7 +1305,6 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
| 1289 | bfa_lps_login_comp(lps); | 1305 | bfa_lps_login_comp(lps); |
| 1290 | break; | 1306 | break; |
| 1291 | 1307 | ||
| 1292 | case BFA_LPS_SM_OFFLINE: | ||
| 1293 | case BFA_LPS_SM_DELETE: | 1308 | case BFA_LPS_SM_DELETE: |
| 1294 | bfa_sm_set_state(lps, bfa_lps_sm_init); | 1309 | bfa_sm_set_state(lps, bfa_lps_sm_init); |
| 1295 | break; | 1310 | break; |
| @@ -2169,6 +2184,12 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, | |||
| 2169 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); | 2184 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
| 2170 | break; | 2185 | break; |
| 2171 | 2186 | ||
| 2187 | case BFA_FCPORT_SM_FAA_MISCONFIG: | ||
| 2188 | bfa_fcport_reset_linkinfo(fcport); | ||
| 2189 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); | ||
| 2190 | bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); | ||
| 2191 | break; | ||
| 2192 | |||
| 2172 | default: | 2193 | default: |
| 2173 | bfa_sm_fault(fcport->bfa, event); | 2194 | bfa_sm_fault(fcport->bfa, event); |
| 2174 | } | 2195 | } |
| @@ -2225,6 +2246,12 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, | |||
| 2225 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); | 2246 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
| 2226 | break; | 2247 | break; |
| 2227 | 2248 | ||
| 2249 | case BFA_FCPORT_SM_FAA_MISCONFIG: | ||
| 2250 | bfa_fcport_reset_linkinfo(fcport); | ||
| 2251 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); | ||
| 2252 | bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); | ||
| 2253 | break; | ||
| 2254 | |||
| 2228 | default: | 2255 | default: |
| 2229 | bfa_sm_fault(fcport->bfa, event); | 2256 | bfa_sm_fault(fcport->bfa, event); |
| 2230 | } | 2257 | } |
| @@ -2250,11 +2277,11 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, | |||
| 2250 | if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { | 2277 | if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { |
| 2251 | 2278 | ||
| 2252 | bfa_trc(fcport->bfa, | 2279 | bfa_trc(fcport->bfa, |
| 2253 | pevent->link_state.vc_fcf.fcf.fipenabled); | 2280 | pevent->link_state.attr.vc_fcf.fcf.fipenabled); |
| 2254 | bfa_trc(fcport->bfa, | 2281 | bfa_trc(fcport->bfa, |
| 2255 | pevent->link_state.vc_fcf.fcf.fipfailed); | 2282 | pevent->link_state.attr.vc_fcf.fcf.fipfailed); |
| 2256 | 2283 | ||
| 2257 | if (pevent->link_state.vc_fcf.fcf.fipfailed) | 2284 | if (pevent->link_state.attr.vc_fcf.fcf.fipfailed) |
| 2258 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | 2285 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
| 2259 | BFA_PL_EID_FIP_FCF_DISC, 0, | 2286 | BFA_PL_EID_FIP_FCF_DISC, 0, |
| 2260 | "FIP FCF Discovery Failed"); | 2287 | "FIP FCF Discovery Failed"); |
| @@ -2311,6 +2338,12 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, | |||
| 2311 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); | 2338 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
| 2312 | break; | 2339 | break; |
| 2313 | 2340 | ||
| 2341 | case BFA_FCPORT_SM_FAA_MISCONFIG: | ||
| 2342 | bfa_fcport_reset_linkinfo(fcport); | ||
| 2343 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); | ||
| 2344 | bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); | ||
| 2345 | break; | ||
| 2346 | |||
| 2314 | default: | 2347 | default: |
| 2315 | bfa_sm_fault(fcport->bfa, event); | 2348 | bfa_sm_fault(fcport->bfa, event); |
| 2316 | } | 2349 | } |
| @@ -2404,6 +2437,12 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, | |||
| 2404 | } | 2437 | } |
| 2405 | break; | 2438 | break; |
| 2406 | 2439 | ||
| 2440 | case BFA_FCPORT_SM_FAA_MISCONFIG: | ||
| 2441 | bfa_fcport_reset_linkinfo(fcport); | ||
| 2442 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); | ||
| 2443 | bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); | ||
| 2444 | break; | ||
| 2445 | |||
| 2407 | default: | 2446 | default: |
| 2408 | bfa_sm_fault(fcport->bfa, event); | 2447 | bfa_sm_fault(fcport->bfa, event); |
| 2409 | } | 2448 | } |
| @@ -2449,6 +2488,12 @@ bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, | |||
| 2449 | bfa_reqq_wcancel(&fcport->reqq_wait); | 2488 | bfa_reqq_wcancel(&fcport->reqq_wait); |
| 2450 | break; | 2489 | break; |
| 2451 | 2490 | ||
| 2491 | case BFA_FCPORT_SM_FAA_MISCONFIG: | ||
| 2492 | bfa_fcport_reset_linkinfo(fcport); | ||
| 2493 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); | ||
| 2494 | bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); | ||
| 2495 | break; | ||
| 2496 | |||
| 2452 | default: | 2497 | default: |
| 2453 | bfa_sm_fault(fcport->bfa, event); | 2498 | bfa_sm_fault(fcport->bfa, event); |
| 2454 | } | 2499 | } |
| @@ -2600,6 +2645,10 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, | |||
| 2600 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); | 2645 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); |
| 2601 | break; | 2646 | break; |
| 2602 | 2647 | ||
| 2648 | case BFA_FCPORT_SM_DPORTENABLE: | ||
| 2649 | bfa_sm_set_state(fcport, bfa_fcport_sm_dport); | ||
| 2650 | break; | ||
| 2651 | |||
| 2603 | default: | 2652 | default: |
| 2604 | bfa_sm_fault(fcport->bfa, event); | 2653 | bfa_sm_fault(fcport->bfa, event); |
| 2605 | } | 2654 | } |
| @@ -2680,6 +2729,81 @@ bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, | |||
| 2680 | } | 2729 | } |
| 2681 | } | 2730 | } |
| 2682 | 2731 | ||
| 2732 | static void | ||
| 2733 | bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event) | ||
| 2734 | { | ||
| 2735 | bfa_trc(fcport->bfa, event); | ||
| 2736 | |||
| 2737 | switch (event) { | ||
| 2738 | case BFA_FCPORT_SM_DPORTENABLE: | ||
| 2739 | case BFA_FCPORT_SM_DISABLE: | ||
| 2740 | case BFA_FCPORT_SM_ENABLE: | ||
| 2741 | case BFA_FCPORT_SM_START: | ||
| 2742 | /* | ||
| 2743 | * Ignore event for a port that is dport | ||
| 2744 | */ | ||
| 2745 | break; | ||
| 2746 | |||
| 2747 | case BFA_FCPORT_SM_STOP: | ||
| 2748 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); | ||
| 2749 | break; | ||
| 2750 | |||
| 2751 | case BFA_FCPORT_SM_HWFAIL: | ||
| 2752 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); | ||
| 2753 | break; | ||
| 2754 | |||
| 2755 | case BFA_FCPORT_SM_DPORTDISABLE: | ||
| 2756 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); | ||
| 2757 | break; | ||
| 2758 | |||
| 2759 | default: | ||
| 2760 | bfa_sm_fault(fcport->bfa, event); | ||
| 2761 | } | ||
| 2762 | } | ||
| 2763 | |||
| 2764 | static void | ||
| 2765 | bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, | ||
| 2766 | enum bfa_fcport_sm_event event) | ||
| 2767 | { | ||
| 2768 | bfa_trc(fcport->bfa, event); | ||
| 2769 | |||
| 2770 | switch (event) { | ||
| 2771 | case BFA_FCPORT_SM_DPORTENABLE: | ||
| 2772 | case BFA_FCPORT_SM_ENABLE: | ||
| 2773 | case BFA_FCPORT_SM_START: | ||
| 2774 | /* | ||
| 2775 | * Ignore event for a port as there is FAA misconfig | ||
| 2776 | */ | ||
| 2777 | break; | ||
| 2778 | |||
| 2779 | case BFA_FCPORT_SM_DISABLE: | ||
| 2780 | if (bfa_fcport_send_disable(fcport)) | ||
| 2781 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); | ||
| 2782 | else | ||
| 2783 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); | ||
| 2784 | |||
| 2785 | bfa_fcport_reset_linkinfo(fcport); | ||
| 2786 | bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); | ||
| 2787 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | ||
| 2788 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); | ||
| 2789 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); | ||
| 2790 | break; | ||
| 2791 | |||
| 2792 | case BFA_FCPORT_SM_STOP: | ||
| 2793 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); | ||
| 2794 | break; | ||
| 2795 | |||
| 2796 | case BFA_FCPORT_SM_HWFAIL: | ||
| 2797 | bfa_fcport_reset_linkinfo(fcport); | ||
| 2798 | bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); | ||
| 2799 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); | ||
| 2800 | break; | ||
| 2801 | |||
| 2802 | default: | ||
| 2803 | bfa_sm_fault(fcport->bfa, event); | ||
| 2804 | } | ||
| 2805 | } | ||
| 2806 | |||
| 2683 | /* | 2807 | /* |
| 2684 | * Link state is down | 2808 | * Link state is down |
| 2685 | */ | 2809 | */ |
| @@ -2943,6 +3067,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
| 2943 | */ | 3067 | */ |
| 2944 | do_gettimeofday(&tv); | 3068 | do_gettimeofday(&tv); |
| 2945 | fcport->stats_reset_time = tv.tv_sec; | 3069 | fcport->stats_reset_time = tv.tv_sec; |
| 3070 | fcport->stats_dma_ready = BFA_FALSE; | ||
| 2946 | 3071 | ||
| 2947 | /* | 3072 | /* |
| 2948 | * initialize and set default configuration | 3073 | * initialize and set default configuration |
| @@ -2953,6 +3078,9 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
| 2953 | port_cfg->maxfrsize = 0; | 3078 | port_cfg->maxfrsize = 0; |
| 2954 | 3079 | ||
| 2955 | port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS; | 3080 | port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS; |
| 3081 | port_cfg->qos_bw.high = BFA_QOS_BW_HIGH; | ||
| 3082 | port_cfg->qos_bw.med = BFA_QOS_BW_MED; | ||
| 3083 | port_cfg->qos_bw.low = BFA_QOS_BW_LOW; | ||
| 2956 | 3084 | ||
| 2957 | INIT_LIST_HEAD(&fcport->stats_pending_q); | 3085 | INIT_LIST_HEAD(&fcport->stats_pending_q); |
| 2958 | INIT_LIST_HEAD(&fcport->statsclr_pending_q); | 3086 | INIT_LIST_HEAD(&fcport->statsclr_pending_q); |
| @@ -2996,6 +3124,21 @@ bfa_fcport_iocdisable(struct bfa_s *bfa) | |||
| 2996 | bfa_trunk_iocdisable(bfa); | 3124 | bfa_trunk_iocdisable(bfa); |
| 2997 | } | 3125 | } |
| 2998 | 3126 | ||
| 3127 | /* | ||
| 3128 | * Update loop info in fcport for SCN online | ||
| 3129 | */ | ||
| 3130 | static void | ||
| 3131 | bfa_fcport_update_loop_info(struct bfa_fcport_s *fcport, | ||
| 3132 | struct bfa_fcport_loop_info_s *loop_info) | ||
| 3133 | { | ||
| 3134 | fcport->myalpa = loop_info->myalpa; | ||
| 3135 | fcport->alpabm_valid = | ||
| 3136 | loop_info->alpabm_val; | ||
| 3137 | memcpy(fcport->alpabm.alpa_bm, | ||
| 3138 | loop_info->alpabm.alpa_bm, | ||
| 3139 | sizeof(struct fc_alpabm_s)); | ||
| 3140 | } | ||
| 3141 | |||
| 2999 | static void | 3142 | static void |
| 3000 | bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) | 3143 | bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) |
| 3001 | { | 3144 | { |
| @@ -3005,12 +3148,15 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) | |||
| 3005 | fcport->speed = pevent->link_state.speed; | 3148 | fcport->speed = pevent->link_state.speed; |
| 3006 | fcport->topology = pevent->link_state.topology; | 3149 | fcport->topology = pevent->link_state.topology; |
| 3007 | 3150 | ||
| 3008 | if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) | 3151 | if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) { |
| 3009 | fcport->myalpa = 0; | 3152 | bfa_fcport_update_loop_info(fcport, |
| 3153 | &pevent->link_state.attr.loop_info); | ||
| 3154 | return; | ||
| 3155 | } | ||
| 3010 | 3156 | ||
| 3011 | /* QoS Details */ | 3157 | /* QoS Details */ |
| 3012 | fcport->qos_attr = pevent->link_state.qos_attr; | 3158 | fcport->qos_attr = pevent->link_state.qos_attr; |
| 3013 | fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr; | 3159 | fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr; |
| 3014 | 3160 | ||
| 3015 | /* | 3161 | /* |
| 3016 | * update trunk state if applicable | 3162 | * update trunk state if applicable |
| @@ -3019,7 +3165,8 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) | |||
| 3019 | trunk->attr.state = BFA_TRUNK_DISABLED; | 3165 | trunk->attr.state = BFA_TRUNK_DISABLED; |
| 3020 | 3166 | ||
| 3021 | /* update FCoE specific */ | 3167 | /* update FCoE specific */ |
| 3022 | fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan); | 3168 | fcport->fcoe_vlan = |
| 3169 | be16_to_cpu(pevent->link_state.attr.vc_fcf.fcf.vlan); | ||
| 3023 | 3170 | ||
| 3024 | bfa_trc(fcport->bfa, fcport->speed); | 3171 | bfa_trc(fcport->bfa, fcport->speed); |
| 3025 | bfa_trc(fcport->bfa, fcport->topology); | 3172 | bfa_trc(fcport->bfa, fcport->topology); |
| @@ -3453,6 +3600,7 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
| 3453 | case BFI_FCPORT_I2H_ENABLE_RSP: | 3600 | case BFI_FCPORT_I2H_ENABLE_RSP: |
| 3454 | if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) { | 3601 | if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) { |
| 3455 | 3602 | ||
| 3603 | fcport->stats_dma_ready = BFA_TRUE; | ||
| 3456 | if (fcport->use_flash_cfg) { | 3604 | if (fcport->use_flash_cfg) { |
| 3457 | fcport->cfg = i2hmsg.penable_rsp->port_cfg; | 3605 | fcport->cfg = i2hmsg.penable_rsp->port_cfg; |
| 3458 | fcport->cfg.maxfrsize = | 3606 | fcport->cfg.maxfrsize = |
| @@ -3468,6 +3616,8 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
| 3468 | else | 3616 | else |
| 3469 | fcport->trunk.attr.state = | 3617 | fcport->trunk.attr.state = |
| 3470 | BFA_TRUNK_DISABLED; | 3618 | BFA_TRUNK_DISABLED; |
| 3619 | fcport->qos_attr.qos_bw = | ||
| 3620 | i2hmsg.penable_rsp->port_cfg.qos_bw; | ||
| 3471 | fcport->use_flash_cfg = BFA_FALSE; | 3621 | fcport->use_flash_cfg = BFA_FALSE; |
| 3472 | } | 3622 | } |
| 3473 | 3623 | ||
| @@ -3476,6 +3626,9 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
| 3476 | else | 3626 | else |
| 3477 | fcport->qos_attr.state = BFA_QOS_DISABLED; | 3627 | fcport->qos_attr.state = BFA_QOS_DISABLED; |
| 3478 | 3628 | ||
| 3629 | fcport->qos_attr.qos_bw_op = | ||
| 3630 | i2hmsg.penable_rsp->port_cfg.qos_bw; | ||
| 3631 | |||
| 3479 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); | 3632 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); |
| 3480 | } | 3633 | } |
| 3481 | break; | 3634 | break; |
| @@ -3488,8 +3641,17 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
| 3488 | case BFI_FCPORT_I2H_EVENT: | 3641 | case BFI_FCPORT_I2H_EVENT: |
| 3489 | if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP) | 3642 | if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP) |
| 3490 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); | 3643 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); |
| 3491 | else | 3644 | else { |
| 3492 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN); | 3645 | if (i2hmsg.event->link_state.linkstate_rsn == |
| 3646 | BFA_PORT_LINKSTATE_RSN_FAA_MISCONFIG) | ||
| 3647 | bfa_sm_send_event(fcport, | ||
| 3648 | BFA_FCPORT_SM_FAA_MISCONFIG); | ||
| 3649 | else | ||
| 3650 | bfa_sm_send_event(fcport, | ||
| 3651 | BFA_FCPORT_SM_LINKDOWN); | ||
| 3652 | } | ||
| 3653 | fcport->qos_attr.qos_bw_op = | ||
| 3654 | i2hmsg.event->link_state.qos_attr.qos_bw_op; | ||
| 3493 | break; | 3655 | break; |
| 3494 | 3656 | ||
| 3495 | case BFI_FCPORT_I2H_TRUNK_SCN: | 3657 | case BFI_FCPORT_I2H_TRUNK_SCN: |
| @@ -3609,6 +3771,9 @@ bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed) | |||
| 3609 | 3771 | ||
| 3610 | if (fcport->cfg.trunked == BFA_TRUE) | 3772 | if (fcport->cfg.trunked == BFA_TRUE) |
| 3611 | return BFA_STATUS_TRUNK_ENABLED; | 3773 | return BFA_STATUS_TRUNK_ENABLED; |
| 3774 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && | ||
| 3775 | (speed == BFA_PORT_SPEED_16GBPS)) | ||
| 3776 | return BFA_STATUS_UNSUPP_SPEED; | ||
| 3612 | if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { | 3777 | if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { |
| 3613 | bfa_trc(bfa, fcport->speed_sup); | 3778 | bfa_trc(bfa, fcport->speed_sup); |
| 3614 | return BFA_STATUS_UNSUPP_SPEED; | 3779 | return BFA_STATUS_UNSUPP_SPEED; |
| @@ -3663,7 +3828,26 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology) | |||
| 3663 | 3828 | ||
| 3664 | switch (topology) { | 3829 | switch (topology) { |
| 3665 | case BFA_PORT_TOPOLOGY_P2P: | 3830 | case BFA_PORT_TOPOLOGY_P2P: |
| 3831 | break; | ||
| 3832 | |||
| 3666 | case BFA_PORT_TOPOLOGY_LOOP: | 3833 | case BFA_PORT_TOPOLOGY_LOOP: |
| 3834 | if ((bfa_fcport_is_qos_enabled(bfa) != BFA_FALSE) || | ||
| 3835 | (fcport->qos_attr.state != BFA_QOS_DISABLED)) | ||
| 3836 | return BFA_STATUS_ERROR_QOS_ENABLED; | ||
| 3837 | if (fcport->cfg.ratelimit != BFA_FALSE) | ||
| 3838 | return BFA_STATUS_ERROR_TRL_ENABLED; | ||
| 3839 | if ((bfa_fcport_is_trunk_enabled(bfa) != BFA_FALSE) || | ||
| 3840 | (fcport->trunk.attr.state != BFA_TRUNK_DISABLED)) | ||
| 3841 | return BFA_STATUS_ERROR_TRUNK_ENABLED; | ||
| 3842 | if ((bfa_fcport_get_speed(bfa) == BFA_PORT_SPEED_16GBPS) || | ||
| 3843 | (fcport->cfg.speed == BFA_PORT_SPEED_16GBPS)) | ||
| 3844 | return BFA_STATUS_UNSUPP_SPEED; | ||
| 3845 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) | ||
| 3846 | return BFA_STATUS_LOOP_UNSUPP_MEZZ; | ||
| 3847 | if (bfa_fcport_is_dport(bfa) != BFA_FALSE) | ||
| 3848 | return BFA_STATUS_DPORT_ERR; | ||
| 3849 | break; | ||
| 3850 | |||
| 3667 | case BFA_PORT_TOPOLOGY_AUTO: | 3851 | case BFA_PORT_TOPOLOGY_AUTO: |
| 3668 | break; | 3852 | break; |
| 3669 | 3853 | ||
| @@ -3686,6 +3870,17 @@ bfa_fcport_get_topology(struct bfa_s *bfa) | |||
| 3686 | return fcport->topology; | 3870 | return fcport->topology; |
| 3687 | } | 3871 | } |
| 3688 | 3872 | ||
| 3873 | /** | ||
| 3874 | * Get config topology. | ||
| 3875 | */ | ||
| 3876 | enum bfa_port_topology | ||
| 3877 | bfa_fcport_get_cfg_topology(struct bfa_s *bfa) | ||
| 3878 | { | ||
| 3879 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | ||
| 3880 | |||
| 3881 | return fcport->cfg.topology; | ||
| 3882 | } | ||
| 3883 | |||
| 3689 | bfa_status_t | 3884 | bfa_status_t |
| 3690 | bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) | 3885 | bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) |
| 3691 | { | 3886 | { |
| @@ -3761,9 +3956,11 @@ bfa_fcport_get_maxfrsize(struct bfa_s *bfa) | |||
| 3761 | u8 | 3956 | u8 |
| 3762 | bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) | 3957 | bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) |
| 3763 | { | 3958 | { |
| 3764 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | 3959 | if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) |
| 3960 | return (BFA_FCPORT_MOD(bfa))->cfg.rx_bbcredit; | ||
| 3765 | 3961 | ||
| 3766 | return fcport->cfg.rx_bbcredit; | 3962 | else |
| 3963 | return 0; | ||
| 3767 | } | 3964 | } |
| 3768 | 3965 | ||
| 3769 | void | 3966 | void |
| @@ -3850,8 +4047,9 @@ bfa_fcport_get_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb) | |||
| 3850 | { | 4047 | { |
| 3851 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | 4048 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
| 3852 | 4049 | ||
| 3853 | if (bfa_ioc_is_disabled(&bfa->ioc)) | 4050 | if (!bfa_iocfc_is_operational(bfa) || |
| 3854 | return BFA_STATUS_IOC_DISABLED; | 4051 | !fcport->stats_dma_ready) |
| 4052 | return BFA_STATUS_IOC_NON_OP; | ||
| 3855 | 4053 | ||
| 3856 | if (!list_empty(&fcport->statsclr_pending_q)) | 4054 | if (!list_empty(&fcport->statsclr_pending_q)) |
| 3857 | return BFA_STATUS_DEVBUSY; | 4055 | return BFA_STATUS_DEVBUSY; |
| @@ -3876,6 +4074,10 @@ bfa_fcport_clear_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb) | |||
| 3876 | { | 4074 | { |
| 3877 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | 4075 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
| 3878 | 4076 | ||
| 4077 | if (!bfa_iocfc_is_operational(bfa) || | ||
| 4078 | !fcport->stats_dma_ready) | ||
| 4079 | return BFA_STATUS_IOC_NON_OP; | ||
| 4080 | |||
| 3879 | if (!list_empty(&fcport->stats_pending_q)) | 4081 | if (!list_empty(&fcport->stats_pending_q)) |
| 3880 | return BFA_STATUS_DEVBUSY; | 4082 | return BFA_STATUS_DEVBUSY; |
| 3881 | 4083 | ||
| @@ -3905,6 +4107,40 @@ bfa_fcport_is_disabled(struct bfa_s *bfa) | |||
| 3905 | } | 4107 | } |
| 3906 | 4108 | ||
| 3907 | bfa_boolean_t | 4109 | bfa_boolean_t |
| 4110 | bfa_fcport_is_dport(struct bfa_s *bfa) | ||
| 4111 | { | ||
| 4112 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | ||
| 4113 | |||
| 4114 | return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) == | ||
| 4115 | BFA_PORT_ST_DPORT); | ||
| 4116 | } | ||
| 4117 | |||
| 4118 | bfa_status_t | ||
| 4119 | bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw) | ||
| 4120 | { | ||
| 4121 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | ||
| 4122 | enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa); | ||
| 4123 | |||
| 4124 | bfa_trc(bfa, ioc_type); | ||
| 4125 | |||
| 4126 | if ((qos_bw->high == 0) || (qos_bw->med == 0) || (qos_bw->low == 0)) | ||
| 4127 | return BFA_STATUS_QOS_BW_INVALID; | ||
| 4128 | |||
| 4129 | if ((qos_bw->high + qos_bw->med + qos_bw->low) != 100) | ||
| 4130 | return BFA_STATUS_QOS_BW_INVALID; | ||
| 4131 | |||
| 4132 | if ((qos_bw->med > qos_bw->high) || (qos_bw->low > qos_bw->med) || | ||
| 4133 | (qos_bw->low > qos_bw->high)) | ||
| 4134 | return BFA_STATUS_QOS_BW_INVALID; | ||
| 4135 | |||
| 4136 | if ((ioc_type == BFA_IOC_TYPE_FC) && | ||
| 4137 | (fcport->cfg.topology != BFA_PORT_TOPOLOGY_LOOP)) | ||
| 4138 | fcport->cfg.qos_bw = *qos_bw; | ||
| 4139 | |||
| 4140 | return BFA_STATUS_OK; | ||
| 4141 | } | ||
| 4142 | |||
| 4143 | bfa_boolean_t | ||
| 3908 | bfa_fcport_is_ratelim(struct bfa_s *bfa) | 4144 | bfa_fcport_is_ratelim(struct bfa_s *bfa) |
| 3909 | { | 4145 | { |
| 3910 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | 4146 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
| @@ -3981,6 +4217,26 @@ bfa_fcport_is_trunk_enabled(struct bfa_s *bfa) | |||
| 3981 | return fcport->cfg.trunked; | 4217 | return fcport->cfg.trunked; |
| 3982 | } | 4218 | } |
| 3983 | 4219 | ||
| 4220 | void | ||
| 4221 | bfa_fcport_dportenable(struct bfa_s *bfa) | ||
| 4222 | { | ||
| 4223 | /* | ||
| 4224 | * Assume caller check for port is in disable state | ||
| 4225 | */ | ||
| 4226 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTENABLE); | ||
| 4227 | bfa_port_set_dportenabled(&bfa->modules.port, BFA_TRUE); | ||
| 4228 | } | ||
| 4229 | |||
| 4230 | void | ||
| 4231 | bfa_fcport_dportdisable(struct bfa_s *bfa) | ||
| 4232 | { | ||
| 4233 | /* | ||
| 4234 | * Assume caller check for port is in disable state | ||
| 4235 | */ | ||
| 4236 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTDISABLE); | ||
| 4237 | bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE); | ||
| 4238 | } | ||
| 4239 | |||
| 3984 | /* | 4240 | /* |
| 3985 | * Rport State machine functions | 4241 | * Rport State machine functions |
| 3986 | */ | 4242 | */ |
| @@ -4707,6 +4963,21 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m) | |||
| 4707 | bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); | 4963 | bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); |
| 4708 | break; | 4964 | break; |
| 4709 | 4965 | ||
| 4966 | case BFI_RPORT_I2H_LIP_SCN_ONLINE: | ||
| 4967 | bfa_fcport_update_loop_info(BFA_FCPORT_MOD(bfa), | ||
| 4968 | &msg.lip_scn->loop_info); | ||
| 4969 | bfa_cb_rport_scn_online(bfa); | ||
| 4970 | break; | ||
| 4971 | |||
| 4972 | case BFI_RPORT_I2H_LIP_SCN_OFFLINE: | ||
| 4973 | bfa_cb_rport_scn_offline(bfa); | ||
| 4974 | break; | ||
| 4975 | |||
| 4976 | case BFI_RPORT_I2H_NO_DEV: | ||
| 4977 | rp = BFA_RPORT_FROM_TAG(bfa, msg.lip_scn->bfa_handle); | ||
| 4978 | bfa_cb_rport_scn_no_dev(rp->rport_drv); | ||
| 4979 | break; | ||
| 4980 | |||
| 4710 | default: | 4981 | default: |
| 4711 | bfa_trc(bfa, m->mhdr.msg_id); | 4982 | bfa_trc(bfa, m->mhdr.msg_id); |
| 4712 | WARN_ON(1); | 4983 | WARN_ON(1); |
| @@ -5348,6 +5619,37 @@ bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw) | |||
| 5348 | } | 5619 | } |
| 5349 | 5620 | ||
| 5350 | /* | 5621 | /* |
| 5622 | * Dport forward declaration | ||
| 5623 | */ | ||
| 5624 | |||
| 5625 | /* | ||
| 5626 | * BFA DPORT state machine events | ||
| 5627 | */ | ||
| 5628 | enum bfa_dport_sm_event { | ||
| 5629 | BFA_DPORT_SM_ENABLE = 1, /* dport enable event */ | ||
| 5630 | BFA_DPORT_SM_DISABLE = 2, /* dport disable event */ | ||
| 5631 | BFA_DPORT_SM_FWRSP = 3, /* fw enable/disable rsp */ | ||
| 5632 | BFA_DPORT_SM_QRESUME = 4, /* CQ space available */ | ||
| 5633 | BFA_DPORT_SM_HWFAIL = 5, /* IOC h/w failure */ | ||
| 5634 | }; | ||
| 5635 | |||
| 5636 | static void bfa_dport_sm_disabled(struct bfa_dport_s *dport, | ||
| 5637 | enum bfa_dport_sm_event event); | ||
| 5638 | static void bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport, | ||
| 5639 | enum bfa_dport_sm_event event); | ||
| 5640 | static void bfa_dport_sm_enabling(struct bfa_dport_s *dport, | ||
| 5641 | enum bfa_dport_sm_event event); | ||
| 5642 | static void bfa_dport_sm_enabled(struct bfa_dport_s *dport, | ||
| 5643 | enum bfa_dport_sm_event event); | ||
| 5644 | static void bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport, | ||
| 5645 | enum bfa_dport_sm_event event); | ||
| 5646 | static void bfa_dport_sm_disabling(struct bfa_dport_s *dport, | ||
| 5647 | enum bfa_dport_sm_event event); | ||
| 5648 | static void bfa_dport_qresume(void *cbarg); | ||
| 5649 | static void bfa_dport_req_comp(struct bfa_dport_s *dport, | ||
| 5650 | bfi_diag_dport_rsp_t *msg); | ||
| 5651 | |||
| 5652 | /* | ||
| 5351 | * BFA fcdiag module | 5653 | * BFA fcdiag module |
| 5352 | */ | 5654 | */ |
| 5353 | #define BFA_DIAG_QTEST_TOV 1000 /* msec */ | 5655 | #define BFA_DIAG_QTEST_TOV 1000 /* msec */ |
| @@ -5377,15 +5679,24 @@ bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
| 5377 | struct bfa_pcidev_s *pcidev) | 5679 | struct bfa_pcidev_s *pcidev) |
| 5378 | { | 5680 | { |
| 5379 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | 5681 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); |
| 5682 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
| 5683 | |||
| 5380 | fcdiag->bfa = bfa; | 5684 | fcdiag->bfa = bfa; |
| 5381 | fcdiag->trcmod = bfa->trcmod; | 5685 | fcdiag->trcmod = bfa->trcmod; |
| 5382 | /* The common DIAG attach bfa_diag_attach() will do all memory claim */ | 5686 | /* The common DIAG attach bfa_diag_attach() will do all memory claim */ |
| 5687 | dport->bfa = bfa; | ||
| 5688 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
| 5689 | bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport); | ||
| 5690 | dport->cbfn = NULL; | ||
| 5691 | dport->cbarg = NULL; | ||
| 5383 | } | 5692 | } |
| 5384 | 5693 | ||
| 5385 | static void | 5694 | static void |
| 5386 | bfa_fcdiag_iocdisable(struct bfa_s *bfa) | 5695 | bfa_fcdiag_iocdisable(struct bfa_s *bfa) |
| 5387 | { | 5696 | { |
| 5388 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | 5697 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); |
| 5698 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
| 5699 | |||
| 5389 | bfa_trc(fcdiag, fcdiag->lb.lock); | 5700 | bfa_trc(fcdiag, fcdiag->lb.lock); |
| 5390 | if (fcdiag->lb.lock) { | 5701 | if (fcdiag->lb.lock) { |
| 5391 | fcdiag->lb.status = BFA_STATUS_IOC_FAILURE; | 5702 | fcdiag->lb.status = BFA_STATUS_IOC_FAILURE; |
| @@ -5393,6 +5704,8 @@ bfa_fcdiag_iocdisable(struct bfa_s *bfa) | |||
| 5393 | fcdiag->lb.lock = 0; | 5704 | fcdiag->lb.lock = 0; |
| 5394 | bfa_fcdiag_set_busy_status(fcdiag); | 5705 | bfa_fcdiag_set_busy_status(fcdiag); |
| 5395 | } | 5706 | } |
| 5707 | |||
| 5708 | bfa_sm_send_event(dport, BFA_DPORT_SM_HWFAIL); | ||
| 5396 | } | 5709 | } |
| 5397 | 5710 | ||
| 5398 | static void | 5711 | static void |
| @@ -5577,6 +5890,9 @@ bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
| 5577 | case BFI_DIAG_I2H_QTEST: | 5890 | case BFI_DIAG_I2H_QTEST: |
| 5578 | bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); | 5891 | bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); |
| 5579 | break; | 5892 | break; |
| 5893 | case BFI_DIAG_I2H_DPORT: | ||
| 5894 | bfa_dport_req_comp(&fcdiag->dport, (bfi_diag_dport_rsp_t *)msg); | ||
| 5895 | break; | ||
| 5580 | default: | 5896 | default: |
| 5581 | bfa_trc(fcdiag, msg->mhdr.msg_id); | 5897 | bfa_trc(fcdiag, msg->mhdr.msg_id); |
| 5582 | WARN_ON(1); | 5898 | WARN_ON(1); |
| @@ -5646,12 +5962,18 @@ bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode, | |||
| 5646 | } | 5962 | } |
| 5647 | } | 5963 | } |
| 5648 | 5964 | ||
| 5965 | /* | ||
| 5966 | * For CT2, 1G is not supported | ||
| 5967 | */ | ||
| 5968 | if ((speed == BFA_PORT_SPEED_1GBPS) && | ||
| 5969 | (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) { | ||
| 5970 | bfa_trc(fcdiag, speed); | ||
| 5971 | return BFA_STATUS_UNSUPP_SPEED; | ||
| 5972 | } | ||
| 5973 | |||
| 5649 | /* For Mezz card, port speed entered needs to be checked */ | 5974 | /* For Mezz card, port speed entered needs to be checked */ |
| 5650 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { | 5975 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { |
| 5651 | if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { | 5976 | if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { |
| 5652 | if ((speed == BFA_PORT_SPEED_1GBPS) && | ||
| 5653 | (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) | ||
| 5654 | return BFA_STATUS_UNSUPP_SPEED; | ||
| 5655 | if (!(speed == BFA_PORT_SPEED_1GBPS || | 5977 | if (!(speed == BFA_PORT_SPEED_1GBPS || |
| 5656 | speed == BFA_PORT_SPEED_2GBPS || | 5978 | speed == BFA_PORT_SPEED_2GBPS || |
| 5657 | speed == BFA_PORT_SPEED_4GBPS || | 5979 | speed == BFA_PORT_SPEED_4GBPS || |
| @@ -5764,3 +6086,379 @@ bfa_fcdiag_lb_is_running(struct bfa_s *bfa) | |||
| 5764 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | 6086 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); |
| 5765 | return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK; | 6087 | return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK; |
| 5766 | } | 6088 | } |
| 6089 | |||
| 6090 | /* | ||
| 6091 | * D-port | ||
| 6092 | */ | ||
| 6093 | static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport, | ||
| 6094 | enum bfi_dport_req req); | ||
| 6095 | static void | ||
| 6096 | bfa_cb_fcdiag_dport(struct bfa_dport_s *dport, bfa_status_t bfa_status) | ||
| 6097 | { | ||
| 6098 | if (dport->cbfn != NULL) { | ||
| 6099 | dport->cbfn(dport->cbarg, bfa_status); | ||
| 6100 | dport->cbfn = NULL; | ||
| 6101 | dport->cbarg = NULL; | ||
| 6102 | } | ||
| 6103 | } | ||
| 6104 | |||
| 6105 | static void | ||
| 6106 | bfa_dport_sm_disabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
| 6107 | { | ||
| 6108 | bfa_trc(dport->bfa, event); | ||
| 6109 | |||
| 6110 | switch (event) { | ||
| 6111 | case BFA_DPORT_SM_ENABLE: | ||
| 6112 | bfa_fcport_dportenable(dport->bfa); | ||
| 6113 | if (bfa_dport_send_req(dport, BFI_DPORT_ENABLE)) | ||
| 6114 | bfa_sm_set_state(dport, bfa_dport_sm_enabling); | ||
| 6115 | else | ||
| 6116 | bfa_sm_set_state(dport, bfa_dport_sm_enabling_qwait); | ||
| 6117 | break; | ||
| 6118 | |||
| 6119 | case BFA_DPORT_SM_DISABLE: | ||
| 6120 | /* Already disabled */ | ||
| 6121 | break; | ||
| 6122 | |||
| 6123 | case BFA_DPORT_SM_HWFAIL: | ||
| 6124 | /* ignore */ | ||
| 6125 | break; | ||
| 6126 | |||
| 6127 | default: | ||
| 6128 | bfa_sm_fault(dport->bfa, event); | ||
| 6129 | } | ||
| 6130 | } | ||
| 6131 | |||
| 6132 | static void | ||
| 6133 | bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport, | ||
| 6134 | enum bfa_dport_sm_event event) | ||
| 6135 | { | ||
| 6136 | bfa_trc(dport->bfa, event); | ||
| 6137 | |||
| 6138 | switch (event) { | ||
| 6139 | case BFA_DPORT_SM_QRESUME: | ||
| 6140 | bfa_sm_set_state(dport, bfa_dport_sm_enabling); | ||
| 6141 | bfa_dport_send_req(dport, BFI_DPORT_ENABLE); | ||
| 6142 | break; | ||
| 6143 | |||
| 6144 | case BFA_DPORT_SM_HWFAIL: | ||
| 6145 | bfa_reqq_wcancel(&dport->reqq_wait); | ||
| 6146 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
| 6147 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); | ||
| 6148 | break; | ||
| 6149 | |||
| 6150 | default: | ||
| 6151 | bfa_sm_fault(dport->bfa, event); | ||
| 6152 | } | ||
| 6153 | } | ||
| 6154 | |||
| 6155 | static void | ||
| 6156 | bfa_dport_sm_enabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
| 6157 | { | ||
| 6158 | bfa_trc(dport->bfa, event); | ||
| 6159 | |||
| 6160 | switch (event) { | ||
| 6161 | case BFA_DPORT_SM_FWRSP: | ||
| 6162 | bfa_sm_set_state(dport, bfa_dport_sm_enabled); | ||
| 6163 | break; | ||
| 6164 | |||
| 6165 | case BFA_DPORT_SM_HWFAIL: | ||
| 6166 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
| 6167 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); | ||
| 6168 | break; | ||
| 6169 | |||
| 6170 | default: | ||
| 6171 | bfa_sm_fault(dport->bfa, event); | ||
| 6172 | } | ||
| 6173 | } | ||
| 6174 | |||
| 6175 | static void | ||
| 6176 | bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
| 6177 | { | ||
| 6178 | bfa_trc(dport->bfa, event); | ||
| 6179 | |||
| 6180 | switch (event) { | ||
| 6181 | case BFA_DPORT_SM_ENABLE: | ||
| 6182 | /* Already enabled */ | ||
| 6183 | break; | ||
| 6184 | |||
| 6185 | case BFA_DPORT_SM_DISABLE: | ||
| 6186 | bfa_fcport_dportdisable(dport->bfa); | ||
| 6187 | if (bfa_dport_send_req(dport, BFI_DPORT_DISABLE)) | ||
| 6188 | bfa_sm_set_state(dport, bfa_dport_sm_disabling); | ||
| 6189 | else | ||
| 6190 | bfa_sm_set_state(dport, bfa_dport_sm_disabling_qwait); | ||
| 6191 | break; | ||
| 6192 | |||
| 6193 | case BFA_DPORT_SM_HWFAIL: | ||
| 6194 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
| 6195 | break; | ||
| 6196 | |||
| 6197 | default: | ||
| 6198 | bfa_sm_fault(dport->bfa, event); | ||
| 6199 | } | ||
| 6200 | } | ||
| 6201 | |||
| 6202 | static void | ||
| 6203 | bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport, | ||
| 6204 | enum bfa_dport_sm_event event) | ||
| 6205 | { | ||
| 6206 | bfa_trc(dport->bfa, event); | ||
| 6207 | |||
| 6208 | switch (event) { | ||
| 6209 | case BFA_DPORT_SM_QRESUME: | ||
| 6210 | bfa_sm_set_state(dport, bfa_dport_sm_disabling); | ||
| 6211 | bfa_dport_send_req(dport, BFI_DPORT_DISABLE); | ||
| 6212 | break; | ||
| 6213 | |||
| 6214 | case BFA_DPORT_SM_HWFAIL: | ||
| 6215 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
| 6216 | bfa_reqq_wcancel(&dport->reqq_wait); | ||
| 6217 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); | ||
| 6218 | break; | ||
| 6219 | |||
| 6220 | default: | ||
| 6221 | bfa_sm_fault(dport->bfa, event); | ||
| 6222 | } | ||
| 6223 | } | ||
| 6224 | |||
| 6225 | static void | ||
| 6226 | bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
| 6227 | { | ||
| 6228 | bfa_trc(dport->bfa, event); | ||
| 6229 | |||
| 6230 | switch (event) { | ||
| 6231 | case BFA_DPORT_SM_FWRSP: | ||
| 6232 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
| 6233 | break; | ||
| 6234 | |||
| 6235 | case BFA_DPORT_SM_HWFAIL: | ||
| 6236 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
| 6237 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); | ||
| 6238 | break; | ||
| 6239 | |||
| 6240 | default: | ||
| 6241 | bfa_sm_fault(dport->bfa, event); | ||
| 6242 | } | ||
| 6243 | } | ||
| 6244 | |||
| 6245 | |||
| 6246 | static bfa_boolean_t | ||
| 6247 | bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req) | ||
| 6248 | { | ||
| 6249 | struct bfi_diag_dport_req_s *m; | ||
| 6250 | |||
| 6251 | /* | ||
| 6252 | * Increment message tag before queue check, so that responses to old | ||
| 6253 | * requests are discarded. | ||
| 6254 | */ | ||
| 6255 | dport->msgtag++; | ||
| 6256 | |||
| 6257 | /* | ||
| 6258 | * check for room in queue to send request now | ||
| 6259 | */ | ||
| 6260 | m = bfa_reqq_next(dport->bfa, BFA_REQQ_DIAG); | ||
| 6261 | if (!m) { | ||
| 6262 | bfa_reqq_wait(dport->bfa, BFA_REQQ_PORT, &dport->reqq_wait); | ||
| 6263 | return BFA_FALSE; | ||
| 6264 | } | ||
| 6265 | |||
| 6266 | bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT, | ||
| 6267 | bfa_fn_lpu(dport->bfa)); | ||
| 6268 | m->req = req; | ||
| 6269 | m->msgtag = dport->msgtag; | ||
| 6270 | |||
| 6271 | /* | ||
| 6272 | * queue I/O message to firmware | ||
| 6273 | */ | ||
| 6274 | bfa_reqq_produce(dport->bfa, BFA_REQQ_DIAG, m->mh); | ||
| 6275 | |||
| 6276 | return BFA_TRUE; | ||
| 6277 | } | ||
| 6278 | |||
| 6279 | static void | ||
| 6280 | bfa_dport_qresume(void *cbarg) | ||
| 6281 | { | ||
| 6282 | struct bfa_dport_s *dport = cbarg; | ||
| 6283 | |||
| 6284 | bfa_sm_send_event(dport, BFA_DPORT_SM_QRESUME); | ||
| 6285 | } | ||
| 6286 | |||
| 6287 | static void | ||
| 6288 | bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg) | ||
| 6289 | { | ||
| 6290 | bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP); | ||
| 6291 | bfa_cb_fcdiag_dport(dport, msg->status); | ||
| 6292 | } | ||
| 6293 | |||
| 6294 | /* | ||
| 6295 | * Dport enable | ||
| 6296 | * | ||
| 6297 | * @param[in] *bfa - bfa data struct | ||
| 6298 | */ | ||
| 6299 | bfa_status_t | ||
| 6300 | bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) | ||
| 6301 | { | ||
| 6302 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
| 6303 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
| 6304 | |||
| 6305 | /* | ||
| 6306 | * Dport is not support in MEZZ card | ||
| 6307 | */ | ||
| 6308 | if (bfa_mfg_is_mezz(dport->bfa->ioc.attr->card_type)) { | ||
| 6309 | bfa_trc(dport->bfa, BFA_STATUS_PBC); | ||
| 6310 | return BFA_STATUS_CMD_NOTSUPP_MEZZ; | ||
| 6311 | } | ||
| 6312 | |||
| 6313 | /* | ||
| 6314 | * Check to see if IOC is down | ||
| 6315 | */ | ||
| 6316 | if (!bfa_iocfc_is_operational(bfa)) | ||
| 6317 | return BFA_STATUS_IOC_NON_OP; | ||
| 6318 | |||
| 6319 | /* if port is PBC disabled, return error */ | ||
| 6320 | if (bfa_fcport_is_pbcdisabled(bfa)) { | ||
| 6321 | bfa_trc(dport->bfa, BFA_STATUS_PBC); | ||
| 6322 | return BFA_STATUS_PBC; | ||
| 6323 | } | ||
| 6324 | |||
| 6325 | /* | ||
| 6326 | * Check if port mode is FC port | ||
| 6327 | */ | ||
| 6328 | if (bfa_ioc_get_type(&bfa->ioc) != BFA_IOC_TYPE_FC) { | ||
| 6329 | bfa_trc(dport->bfa, bfa_ioc_get_type(&bfa->ioc)); | ||
| 6330 | return BFA_STATUS_CMD_NOTSUPP_CNA; | ||
| 6331 | } | ||
| 6332 | |||
| 6333 | /* | ||
| 6334 | * Check if port is in LOOP mode | ||
| 6335 | */ | ||
| 6336 | if ((bfa_fcport_get_cfg_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) || | ||
| 6337 | (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)) { | ||
| 6338 | bfa_trc(dport->bfa, 0); | ||
| 6339 | return BFA_STATUS_TOPOLOGY_LOOP; | ||
| 6340 | } | ||
| 6341 | |||
| 6342 | /* | ||
| 6343 | * Check if port is TRUNK mode | ||
| 6344 | */ | ||
| 6345 | if (bfa_fcport_is_trunk_enabled(bfa)) { | ||
| 6346 | bfa_trc(dport->bfa, 0); | ||
| 6347 | return BFA_STATUS_ERROR_TRUNK_ENABLED; | ||
| 6348 | } | ||
| 6349 | |||
| 6350 | /* | ||
| 6351 | * Check to see if port is disable or in dport state | ||
| 6352 | */ | ||
| 6353 | if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && | ||
| 6354 | (bfa_fcport_is_dport(bfa) == BFA_FALSE)) { | ||
| 6355 | bfa_trc(dport->bfa, 0); | ||
| 6356 | return BFA_STATUS_PORT_NOT_DISABLED; | ||
| 6357 | } | ||
| 6358 | |||
| 6359 | /* | ||
| 6360 | * Check if dport is busy | ||
| 6361 | */ | ||
| 6362 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || | ||
| 6363 | bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || | ||
| 6364 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || | ||
| 6365 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) { | ||
| 6366 | return BFA_STATUS_DEVBUSY; | ||
| 6367 | } | ||
| 6368 | |||
| 6369 | /* | ||
| 6370 | * Check if dport is already enabled | ||
| 6371 | */ | ||
| 6372 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) { | ||
| 6373 | bfa_trc(dport->bfa, 0); | ||
| 6374 | return BFA_STATUS_DPORT_ENABLED; | ||
| 6375 | } | ||
| 6376 | |||
| 6377 | dport->cbfn = cbfn; | ||
| 6378 | dport->cbarg = cbarg; | ||
| 6379 | |||
| 6380 | bfa_sm_send_event(dport, BFA_DPORT_SM_ENABLE); | ||
| 6381 | return BFA_STATUS_OK; | ||
| 6382 | } | ||
| 6383 | |||
| 6384 | /* | ||
| 6385 | * Dport disable | ||
| 6386 | * | ||
| 6387 | * @param[in] *bfa - bfa data struct | ||
| 6388 | */ | ||
| 6389 | bfa_status_t | ||
| 6390 | bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) | ||
| 6391 | { | ||
| 6392 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
| 6393 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
| 6394 | |||
| 6395 | if (bfa_ioc_is_disabled(&bfa->ioc)) | ||
| 6396 | return BFA_STATUS_IOC_DISABLED; | ||
| 6397 | |||
| 6398 | /* if port is PBC disabled, return error */ | ||
| 6399 | if (bfa_fcport_is_pbcdisabled(bfa)) { | ||
| 6400 | bfa_trc(dport->bfa, BFA_STATUS_PBC); | ||
| 6401 | return BFA_STATUS_PBC; | ||
| 6402 | } | ||
| 6403 | |||
| 6404 | /* | ||
| 6405 | * Check to see if port is disable or in dport state | ||
| 6406 | */ | ||
| 6407 | if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && | ||
| 6408 | (bfa_fcport_is_dport(bfa) == BFA_FALSE)) { | ||
| 6409 | bfa_trc(dport->bfa, 0); | ||
| 6410 | return BFA_STATUS_PORT_NOT_DISABLED; | ||
| 6411 | } | ||
| 6412 | |||
| 6413 | /* | ||
| 6414 | * Check if dport is busy | ||
| 6415 | */ | ||
| 6416 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || | ||
| 6417 | bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || | ||
| 6418 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || | ||
| 6419 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) | ||
| 6420 | return BFA_STATUS_DEVBUSY; | ||
| 6421 | |||
| 6422 | /* | ||
| 6423 | * Check if dport is already disabled | ||
| 6424 | */ | ||
| 6425 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) { | ||
| 6426 | bfa_trc(dport->bfa, 0); | ||
| 6427 | return BFA_STATUS_DPORT_DISABLED; | ||
| 6428 | } | ||
| 6429 | |||
| 6430 | dport->cbfn = cbfn; | ||
| 6431 | dport->cbarg = cbarg; | ||
| 6432 | |||
| 6433 | bfa_sm_send_event(dport, BFA_DPORT_SM_DISABLE); | ||
| 6434 | return BFA_STATUS_OK; | ||
| 6435 | } | ||
| 6436 | |||
| 6437 | /* | ||
| 6438 | * Get D-port state | ||
| 6439 | * | ||
| 6440 | * @param[in] *bfa - bfa data struct | ||
| 6441 | */ | ||
| 6442 | |||
| 6443 | bfa_status_t | ||
| 6444 | bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state) | ||
| 6445 | { | ||
| 6446 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
| 6447 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
| 6448 | |||
| 6449 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) | ||
| 6450 | *state = BFA_DPORT_ST_ENABLED; | ||
| 6451 | else if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || | ||
| 6452 | bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait)) | ||
| 6453 | *state = BFA_DPORT_ST_ENABLING; | ||
| 6454 | else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) | ||
| 6455 | *state = BFA_DPORT_ST_DISABLED; | ||
| 6456 | else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || | ||
| 6457 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) | ||
| 6458 | *state = BFA_DPORT_ST_DISABLING; | ||
| 6459 | else { | ||
| 6460 | bfa_trc(dport->bfa, BFA_STATUS_EINVAL); | ||
| 6461 | return BFA_STATUS_EINVAL; | ||
| 6462 | } | ||
| 6463 | return BFA_STATUS_OK; | ||
| 6464 | } | ||
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index 1abcf7c51661..8d7fbecfcb22 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h | |||
| @@ -474,8 +474,10 @@ struct bfa_fcport_s { | |||
| 474 | /* supported speeds */ | 474 | /* supported speeds */ |
| 475 | enum bfa_port_speed speed; /* current speed */ | 475 | enum bfa_port_speed speed; /* current speed */ |
| 476 | enum bfa_port_topology topology; /* current topology */ | 476 | enum bfa_port_topology topology; /* current topology */ |
| 477 | u8 myalpa; /* my ALPA in LOOP topology */ | ||
| 478 | u8 rsvd[3]; | 477 | u8 rsvd[3]; |
| 478 | u8 myalpa; /* my ALPA in LOOP topology */ | ||
| 479 | u8 alpabm_valid; /* alpa bitmap valid or not */ | ||
| 480 | struct fc_alpabm_s alpabm; /* alpa bitmap */ | ||
| 479 | struct bfa_port_cfg_s cfg; /* current port configuration */ | 481 | struct bfa_port_cfg_s cfg; /* current port configuration */ |
| 480 | bfa_boolean_t use_flash_cfg; /* get port cfg from flash */ | 482 | bfa_boolean_t use_flash_cfg; /* get port cfg from flash */ |
| 481 | struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ | 483 | struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ |
| @@ -512,6 +514,7 @@ struct bfa_fcport_s { | |||
| 512 | struct bfa_fcport_trunk_s trunk; | 514 | struct bfa_fcport_trunk_s trunk; |
| 513 | u16 fcoe_vlan; | 515 | u16 fcoe_vlan; |
| 514 | struct bfa_mem_dma_s fcport_dma; | 516 | struct bfa_mem_dma_s fcport_dma; |
| 517 | bfa_boolean_t stats_dma_ready; | ||
| 515 | }; | 518 | }; |
| 516 | 519 | ||
| 517 | #define BFA_FCPORT_MOD(__bfa) (&(__bfa)->modules.fcport) | 520 | #define BFA_FCPORT_MOD(__bfa) (&(__bfa)->modules.fcport) |
| @@ -534,6 +537,7 @@ enum bfa_port_speed bfa_fcport_get_speed(struct bfa_s *bfa); | |||
| 534 | bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa, | 537 | bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa, |
| 535 | enum bfa_port_topology topo); | 538 | enum bfa_port_topology topo); |
| 536 | enum bfa_port_topology bfa_fcport_get_topology(struct bfa_s *bfa); | 539 | enum bfa_port_topology bfa_fcport_get_topology(struct bfa_s *bfa); |
| 540 | enum bfa_port_topology bfa_fcport_get_cfg_topology(struct bfa_s *bfa); | ||
| 537 | bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa); | 541 | bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa); |
| 538 | bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa); | 542 | bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa); |
| 539 | u8 bfa_fcport_get_myalpa(struct bfa_s *bfa); | 543 | u8 bfa_fcport_get_myalpa(struct bfa_s *bfa); |
| @@ -547,6 +551,9 @@ void bfa_fcport_event_register(struct bfa_s *bfa, | |||
| 547 | void (*event_cbfn) (void *cbarg, | 551 | void (*event_cbfn) (void *cbarg, |
| 548 | enum bfa_port_linkstate event), void *event_cbarg); | 552 | enum bfa_port_linkstate event), void *event_cbarg); |
| 549 | bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); | 553 | bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); |
| 554 | bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa); | ||
| 555 | bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa, | ||
| 556 | struct bfa_qos_bw_s *qos_bw); | ||
| 550 | enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); | 557 | enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); |
| 551 | 558 | ||
| 552 | void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn); | 559 | void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn); |
| @@ -560,6 +567,8 @@ bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, | |||
| 560 | struct bfa_cb_pending_q_s *cb); | 567 | struct bfa_cb_pending_q_s *cb); |
| 561 | bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa); | 568 | bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa); |
| 562 | bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa); | 569 | bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa); |
| 570 | void bfa_fcport_dportenable(struct bfa_s *bfa); | ||
| 571 | void bfa_fcport_dportdisable(struct bfa_s *bfa); | ||
| 563 | bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa); | 572 | bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa); |
| 564 | void bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state); | 573 | void bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state); |
| 565 | 574 | ||
| @@ -575,6 +584,9 @@ void bfa_cb_rport_offline(void *rport); | |||
| 575 | void bfa_cb_rport_qos_scn_flowid(void *rport, | 584 | void bfa_cb_rport_qos_scn_flowid(void *rport, |
| 576 | struct bfa_rport_qos_attr_s old_qos_attr, | 585 | struct bfa_rport_qos_attr_s old_qos_attr, |
| 577 | struct bfa_rport_qos_attr_s new_qos_attr); | 586 | struct bfa_rport_qos_attr_s new_qos_attr); |
| 587 | void bfa_cb_rport_scn_online(struct bfa_s *bfa); | ||
| 588 | void bfa_cb_rport_scn_offline(struct bfa_s *bfa); | ||
| 589 | void bfa_cb_rport_scn_no_dev(void *rp); | ||
| 578 | void bfa_cb_rport_qos_scn_prio(void *rport, | 590 | void bfa_cb_rport_qos_scn_prio(void *rport, |
| 579 | struct bfa_rport_qos_attr_s old_qos_attr, | 591 | struct bfa_rport_qos_attr_s old_qos_attr, |
| 580 | struct bfa_rport_qos_attr_s new_qos_attr); | 592 | struct bfa_rport_qos_attr_s new_qos_attr); |
| @@ -697,11 +709,21 @@ struct bfa_fcdiag_lb_s { | |||
| 697 | u32 status; | 709 | u32 status; |
| 698 | }; | 710 | }; |
| 699 | 711 | ||
| 712 | struct bfa_dport_s { | ||
| 713 | struct bfa_s *bfa; /* Back pointer to BFA */ | ||
| 714 | bfa_sm_t sm; /* finite state machine */ | ||
| 715 | u32 msgtag; /* firmware msg tag for reply */ | ||
| 716 | struct bfa_reqq_wait_s reqq_wait; | ||
| 717 | bfa_cb_diag_t cbfn; | ||
| 718 | void *cbarg; | ||
| 719 | }; | ||
| 720 | |||
| 700 | struct bfa_fcdiag_s { | 721 | struct bfa_fcdiag_s { |
| 701 | struct bfa_s *bfa; /* Back pointer to BFA */ | 722 | struct bfa_s *bfa; /* Back pointer to BFA */ |
| 702 | struct bfa_trc_mod_s *trcmod; | 723 | struct bfa_trc_mod_s *trcmod; |
| 703 | struct bfa_fcdiag_lb_s lb; | 724 | struct bfa_fcdiag_lb_s lb; |
| 704 | struct bfa_fcdiag_qtest_s qtest; | 725 | struct bfa_fcdiag_qtest_s qtest; |
| 726 | struct bfa_dport_s dport; | ||
| 705 | }; | 727 | }; |
| 706 | 728 | ||
| 707 | #define BFA_FCDIAG_MOD(__bfa) (&(__bfa)->modules.fcdiag) | 729 | #define BFA_FCDIAG_MOD(__bfa) (&(__bfa)->modules.fcdiag) |
| @@ -717,5 +739,11 @@ bfa_status_t bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 ignore, | |||
| 717 | u32 queue, struct bfa_diag_qtest_result_s *result, | 739 | u32 queue, struct bfa_diag_qtest_result_s *result, |
| 718 | bfa_cb_diag_t cbfn, void *cbarg); | 740 | bfa_cb_diag_t cbfn, void *cbarg); |
| 719 | bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa); | 741 | bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa); |
| 742 | bfa_status_t bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, | ||
| 743 | void *cbarg); | ||
| 744 | bfa_status_t bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, | ||
| 745 | void *cbarg); | ||
| 746 | bfa_status_t bfa_dport_get_state(struct bfa_s *bfa, | ||
| 747 | enum bfa_dport_state *state); | ||
| 720 | 748 | ||
| 721 | #endif /* __BFA_SVC_H__ */ | 749 | #endif /* __BFA_SVC_H__ */ |
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index c37494916a1a..895b0e516e07 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c | |||
| @@ -63,9 +63,9 @@ int max_rport_logins = BFA_FCS_MAX_RPORT_LOGINS; | |||
| 63 | u32 bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size; | 63 | u32 bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size; |
| 64 | u32 *bfi_image_cb, *bfi_image_ct, *bfi_image_ct2; | 64 | u32 *bfi_image_cb, *bfi_image_ct, *bfi_image_ct2; |
| 65 | 65 | ||
| 66 | #define BFAD_FW_FILE_CB "cbfw.bin" | 66 | #define BFAD_FW_FILE_CB "cbfw-3.1.0.0.bin" |
| 67 | #define BFAD_FW_FILE_CT "ctfw.bin" | 67 | #define BFAD_FW_FILE_CT "ctfw-3.1.0.0.bin" |
| 68 | #define BFAD_FW_FILE_CT2 "ct2fw.bin" | 68 | #define BFAD_FW_FILE_CT2 "ct2fw-3.1.0.0.bin" |
| 69 | 69 | ||
| 70 | static u32 *bfad_load_fwimg(struct pci_dev *pdev); | 70 | static u32 *bfad_load_fwimg(struct pci_dev *pdev); |
| 71 | static void bfad_free_fwimg(void); | 71 | static void bfad_free_fwimg(void); |
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 0afa39076cef..555e7db94a1c 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c | |||
| @@ -33,7 +33,7 @@ bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd) | |||
| 33 | /* If IOC is not in disabled state - return */ | 33 | /* If IOC is not in disabled state - return */ |
| 34 | if (!bfa_ioc_is_disabled(&bfad->bfa.ioc)) { | 34 | if (!bfa_ioc_is_disabled(&bfad->bfa.ioc)) { |
| 35 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 35 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 36 | iocmd->status = BFA_STATUS_IOC_FAILURE; | 36 | iocmd->status = BFA_STATUS_OK; |
| 37 | return rc; | 37 | return rc; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| @@ -54,6 +54,12 @@ bfad_iocmd_ioc_disable(struct bfad_s *bfad, void *cmd) | |||
| 54 | unsigned long flags; | 54 | unsigned long flags; |
| 55 | 55 | ||
| 56 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 56 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 57 | if (bfa_ioc_is_disabled(&bfad->bfa.ioc)) { | ||
| 58 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 59 | iocmd->status = BFA_STATUS_OK; | ||
| 60 | return rc; | ||
| 61 | } | ||
| 62 | |||
| 57 | if (bfad->disable_active) { | 63 | if (bfad->disable_active) { |
| 58 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 64 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 59 | return -EBUSY; | 65 | return -EBUSY; |
| @@ -101,9 +107,10 @@ bfad_iocmd_ioc_get_info(struct bfad_s *bfad, void *cmd) | |||
| 101 | 107 | ||
| 102 | /* set adapter hw path */ | 108 | /* set adapter hw path */ |
| 103 | strcpy(iocmd->adapter_hwpath, bfad->pci_name); | 109 | strcpy(iocmd->adapter_hwpath, bfad->pci_name); |
| 104 | i = strlen(iocmd->adapter_hwpath) - 1; | 110 | for (i = 0; iocmd->adapter_hwpath[i] != ':' && i < BFA_STRING_32; i++) |
| 105 | while (iocmd->adapter_hwpath[i] != '.') | 111 | ; |
| 106 | i--; | 112 | for (; iocmd->adapter_hwpath[++i] != ':' && i < BFA_STRING_32; ) |
| 113 | ; | ||
| 107 | iocmd->adapter_hwpath[i] = '\0'; | 114 | iocmd->adapter_hwpath[i] = '\0'; |
| 108 | iocmd->status = BFA_STATUS_OK; | 115 | iocmd->status = BFA_STATUS_OK; |
| 109 | return 0; | 116 | return 0; |
| @@ -880,6 +887,19 @@ out: | |||
| 880 | } | 887 | } |
| 881 | 888 | ||
| 882 | int | 889 | int |
| 890 | bfad_iocmd_qos_set_bw(struct bfad_s *bfad, void *pcmd) | ||
| 891 | { | ||
| 892 | struct bfa_bsg_qos_bw_s *iocmd = (struct bfa_bsg_qos_bw_s *)pcmd; | ||
| 893 | unsigned long flags; | ||
| 894 | |||
| 895 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
| 896 | iocmd->status = bfa_fcport_set_qos_bw(&bfad->bfa, &iocmd->qos_bw); | ||
| 897 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 898 | |||
| 899 | return 0; | ||
| 900 | } | ||
| 901 | |||
| 902 | int | ||
| 883 | bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd) | 903 | bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd) |
| 884 | { | 904 | { |
| 885 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; | 905 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; |
| @@ -888,16 +908,22 @@ bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd) | |||
| 888 | 908 | ||
| 889 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 909 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 890 | 910 | ||
| 891 | if (cmd == IOCMD_RATELIM_ENABLE) | 911 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
| 892 | fcport->cfg.ratelimit = BFA_TRUE; | 912 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
| 893 | else if (cmd == IOCMD_RATELIM_DISABLE) | 913 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
| 894 | fcport->cfg.ratelimit = BFA_FALSE; | 914 | else { |
| 915 | if (cmd == IOCMD_RATELIM_ENABLE) | ||
| 916 | fcport->cfg.ratelimit = BFA_TRUE; | ||
| 917 | else if (cmd == IOCMD_RATELIM_DISABLE) | ||
| 918 | fcport->cfg.ratelimit = BFA_FALSE; | ||
| 895 | 919 | ||
| 896 | if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN) | 920 | if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN) |
| 897 | fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS; | 921 | fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS; |
| 922 | |||
| 923 | iocmd->status = BFA_STATUS_OK; | ||
| 924 | } | ||
| 898 | 925 | ||
| 899 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 926 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 900 | iocmd->status = BFA_STATUS_OK; | ||
| 901 | 927 | ||
| 902 | return 0; | 928 | return 0; |
| 903 | } | 929 | } |
| @@ -919,8 +945,13 @@ bfad_iocmd_ratelim_speed(struct bfad_s *bfad, unsigned int cmd, void *pcmd) | |||
| 919 | return 0; | 945 | return 0; |
| 920 | } | 946 | } |
| 921 | 947 | ||
| 922 | fcport->cfg.trl_def_speed = iocmd->speed; | 948 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
| 923 | iocmd->status = BFA_STATUS_OK; | 949 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
| 950 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | ||
| 951 | else { | ||
| 952 | fcport->cfg.trl_def_speed = iocmd->speed; | ||
| 953 | iocmd->status = BFA_STATUS_OK; | ||
| 954 | } | ||
| 924 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 955 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 925 | 956 | ||
| 926 | return 0; | 957 | return 0; |
| @@ -1167,8 +1198,8 @@ bfad_iocmd_pcifn_create(struct bfad_s *bfad, void *cmd) | |||
| 1167 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 1198 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 1168 | iocmd->status = bfa_ablk_pf_create(&bfad->bfa.modules.ablk, | 1199 | iocmd->status = bfa_ablk_pf_create(&bfad->bfa.modules.ablk, |
| 1169 | &iocmd->pcifn_id, iocmd->port, | 1200 | &iocmd->pcifn_id, iocmd->port, |
| 1170 | iocmd->pcifn_class, iocmd->bandwidth, | 1201 | iocmd->pcifn_class, iocmd->bw_min, |
| 1171 | bfad_hcb_comp, &fcomp); | 1202 | iocmd->bw_max, bfad_hcb_comp, &fcomp); |
| 1172 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 1203 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 1173 | if (iocmd->status != BFA_STATUS_OK) | 1204 | if (iocmd->status != BFA_STATUS_OK) |
| 1174 | goto out; | 1205 | goto out; |
| @@ -1211,8 +1242,8 @@ bfad_iocmd_pcifn_bw(struct bfad_s *bfad, void *cmd) | |||
| 1211 | init_completion(&fcomp.comp); | 1242 | init_completion(&fcomp.comp); |
| 1212 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 1243 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 1213 | iocmd->status = bfa_ablk_pf_update(&bfad->bfa.modules.ablk, | 1244 | iocmd->status = bfa_ablk_pf_update(&bfad->bfa.modules.ablk, |
| 1214 | iocmd->pcifn_id, iocmd->bandwidth, | 1245 | iocmd->pcifn_id, iocmd->bw_min, |
| 1215 | bfad_hcb_comp, &fcomp); | 1246 | iocmd->bw_max, bfad_hcb_comp, &fcomp); |
| 1216 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 1247 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 1217 | bfa_trc(bfad, iocmd->status); | 1248 | bfa_trc(bfad, iocmd->status); |
| 1218 | if (iocmd->status != BFA_STATUS_OK) | 1249 | if (iocmd->status != BFA_STATUS_OK) |
| @@ -1736,6 +1767,52 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) | |||
| 1736 | } | 1767 | } |
| 1737 | 1768 | ||
| 1738 | int | 1769 | int |
| 1770 | bfad_iocmd_diag_cfg_dport(struct bfad_s *bfad, unsigned int cmd, void *pcmd) | ||
| 1771 | { | ||
| 1772 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; | ||
| 1773 | unsigned long flags; | ||
| 1774 | struct bfad_hal_comp fcomp; | ||
| 1775 | |||
| 1776 | init_completion(&fcomp.comp); | ||
| 1777 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
| 1778 | if (cmd == IOCMD_DIAG_DPORT_ENABLE) | ||
| 1779 | iocmd->status = bfa_dport_enable(&bfad->bfa, | ||
| 1780 | bfad_hcb_comp, &fcomp); | ||
| 1781 | else if (cmd == IOCMD_DIAG_DPORT_DISABLE) | ||
| 1782 | iocmd->status = bfa_dport_disable(&bfad->bfa, | ||
| 1783 | bfad_hcb_comp, &fcomp); | ||
| 1784 | else { | ||
| 1785 | bfa_trc(bfad, 0); | ||
| 1786 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 1787 | return -EINVAL; | ||
| 1788 | } | ||
| 1789 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 1790 | |||
| 1791 | if (iocmd->status != BFA_STATUS_OK) | ||
| 1792 | bfa_trc(bfad, iocmd->status); | ||
| 1793 | else { | ||
| 1794 | wait_for_completion(&fcomp.comp); | ||
| 1795 | iocmd->status = fcomp.status; | ||
| 1796 | } | ||
| 1797 | |||
| 1798 | return 0; | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | int | ||
| 1802 | bfad_iocmd_diag_dport_get_state(struct bfad_s *bfad, void *pcmd) | ||
| 1803 | { | ||
| 1804 | struct bfa_bsg_diag_dport_get_state_s *iocmd = | ||
| 1805 | (struct bfa_bsg_diag_dport_get_state_s *)pcmd; | ||
| 1806 | unsigned long flags; | ||
| 1807 | |||
| 1808 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
| 1809 | iocmd->status = bfa_dport_get_state(&bfad->bfa, &iocmd->state); | ||
| 1810 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 1811 | |||
| 1812 | return 0; | ||
| 1813 | } | ||
| 1814 | |||
| 1815 | int | ||
| 1739 | bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) | 1816 | bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) |
| 1740 | { | 1817 | { |
| 1741 | struct bfa_bsg_phy_attr_s *iocmd = | 1818 | struct bfa_bsg_phy_attr_s *iocmd = |
| @@ -2052,7 +2129,7 @@ bfad_iocmd_boot_cfg(struct bfad_s *bfad, void *cmd) | |||
| 2052 | init_completion(&fcomp.comp); | 2129 | init_completion(&fcomp.comp); |
| 2053 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 2130 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 2054 | iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), | 2131 | iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), |
| 2055 | BFA_FLASH_PART_BOOT, PCI_FUNC(bfad->pcidev->devfn), | 2132 | BFA_FLASH_PART_BOOT, bfad->bfa.ioc.port_id, |
| 2056 | &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, | 2133 | &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, |
| 2057 | bfad_hcb_comp, &fcomp); | 2134 | bfad_hcb_comp, &fcomp); |
| 2058 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 2135 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| @@ -2074,7 +2151,7 @@ bfad_iocmd_boot_query(struct bfad_s *bfad, void *cmd) | |||
| 2074 | init_completion(&fcomp.comp); | 2151 | init_completion(&fcomp.comp); |
| 2075 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 2152 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 2076 | iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), | 2153 | iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), |
| 2077 | BFA_FLASH_PART_BOOT, PCI_FUNC(bfad->pcidev->devfn), | 2154 | BFA_FLASH_PART_BOOT, bfad->bfa.ioc.port_id, |
| 2078 | &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, | 2155 | &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, |
| 2079 | bfad_hcb_comp, &fcomp); | 2156 | bfad_hcb_comp, &fcomp); |
| 2080 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 2157 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| @@ -2161,22 +2238,31 @@ bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) | |||
| 2161 | 2238 | ||
| 2162 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 2239 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 2163 | 2240 | ||
| 2164 | if (v_cmd == IOCMD_TRUNK_ENABLE) { | 2241 | if (bfa_fcport_is_dport(&bfad->bfa)) |
| 2165 | trunk->attr.state = BFA_TRUNK_OFFLINE; | 2242 | return BFA_STATUS_DPORT_ERR; |
| 2166 | bfa_fcport_disable(&bfad->bfa); | ||
| 2167 | fcport->cfg.trunked = BFA_TRUE; | ||
| 2168 | } else if (v_cmd == IOCMD_TRUNK_DISABLE) { | ||
| 2169 | trunk->attr.state = BFA_TRUNK_DISABLED; | ||
| 2170 | bfa_fcport_disable(&bfad->bfa); | ||
| 2171 | fcport->cfg.trunked = BFA_FALSE; | ||
| 2172 | } | ||
| 2173 | 2243 | ||
| 2174 | if (!bfa_fcport_is_disabled(&bfad->bfa)) | 2244 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || |
| 2175 | bfa_fcport_enable(&bfad->bfa); | 2245 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
| 2246 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | ||
| 2247 | else { | ||
| 2248 | if (v_cmd == IOCMD_TRUNK_ENABLE) { | ||
| 2249 | trunk->attr.state = BFA_TRUNK_OFFLINE; | ||
| 2250 | bfa_fcport_disable(&bfad->bfa); | ||
| 2251 | fcport->cfg.trunked = BFA_TRUE; | ||
| 2252 | } else if (v_cmd == IOCMD_TRUNK_DISABLE) { | ||
| 2253 | trunk->attr.state = BFA_TRUNK_DISABLED; | ||
| 2254 | bfa_fcport_disable(&bfad->bfa); | ||
| 2255 | fcport->cfg.trunked = BFA_FALSE; | ||
| 2256 | } | ||
| 2257 | |||
| 2258 | if (!bfa_fcport_is_disabled(&bfad->bfa)) | ||
| 2259 | bfa_fcport_enable(&bfad->bfa); | ||
| 2260 | |||
| 2261 | iocmd->status = BFA_STATUS_OK; | ||
| 2262 | } | ||
| 2176 | 2263 | ||
| 2177 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 2264 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 2178 | 2265 | ||
| 2179 | iocmd->status = BFA_STATUS_OK; | ||
| 2180 | return 0; | 2266 | return 0; |
| 2181 | } | 2267 | } |
| 2182 | 2268 | ||
| @@ -2189,12 +2275,17 @@ bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd) | |||
| 2189 | unsigned long flags; | 2275 | unsigned long flags; |
| 2190 | 2276 | ||
| 2191 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 2277 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 2192 | memcpy((void *)&iocmd->attr, (void *)&trunk->attr, | 2278 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || |
| 2193 | sizeof(struct bfa_trunk_attr_s)); | 2279 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
| 2194 | iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa); | 2280 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
| 2281 | else { | ||
| 2282 | memcpy((void *)&iocmd->attr, (void *)&trunk->attr, | ||
| 2283 | sizeof(struct bfa_trunk_attr_s)); | ||
| 2284 | iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa); | ||
| 2285 | iocmd->status = BFA_STATUS_OK; | ||
| 2286 | } | ||
| 2195 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 2287 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 2196 | 2288 | ||
| 2197 | iocmd->status = BFA_STATUS_OK; | ||
| 2198 | return 0; | 2289 | return 0; |
| 2199 | } | 2290 | } |
| 2200 | 2291 | ||
| @@ -2207,14 +2298,22 @@ bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) | |||
| 2207 | 2298 | ||
| 2208 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 2299 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 2209 | if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) { | 2300 | if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) { |
| 2210 | if (v_cmd == IOCMD_QOS_ENABLE) | 2301 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
| 2211 | fcport->cfg.qos_enabled = BFA_TRUE; | 2302 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
| 2212 | else if (v_cmd == IOCMD_QOS_DISABLE) | 2303 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; |
| 2213 | fcport->cfg.qos_enabled = BFA_FALSE; | 2304 | else { |
| 2305 | if (v_cmd == IOCMD_QOS_ENABLE) | ||
| 2306 | fcport->cfg.qos_enabled = BFA_TRUE; | ||
| 2307 | else if (v_cmd == IOCMD_QOS_DISABLE) { | ||
| 2308 | fcport->cfg.qos_enabled = BFA_FALSE; | ||
| 2309 | fcport->cfg.qos_bw.high = BFA_QOS_BW_HIGH; | ||
| 2310 | fcport->cfg.qos_bw.med = BFA_QOS_BW_MED; | ||
| 2311 | fcport->cfg.qos_bw.low = BFA_QOS_BW_LOW; | ||
| 2312 | } | ||
| 2313 | } | ||
| 2214 | } | 2314 | } |
| 2215 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 2315 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 2216 | 2316 | ||
| 2217 | iocmd->status = BFA_STATUS_OK; | ||
| 2218 | return 0; | 2317 | return 0; |
| 2219 | } | 2318 | } |
| 2220 | 2319 | ||
| @@ -2226,11 +2325,21 @@ bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd) | |||
| 2226 | unsigned long flags; | 2325 | unsigned long flags; |
| 2227 | 2326 | ||
| 2228 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 2327 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 2229 | iocmd->attr.state = fcport->qos_attr.state; | 2328 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
| 2230 | iocmd->attr.total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr); | 2329 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) |
| 2330 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | ||
| 2331 | else { | ||
| 2332 | iocmd->attr.state = fcport->qos_attr.state; | ||
| 2333 | iocmd->attr.total_bb_cr = | ||
| 2334 | be32_to_cpu(fcport->qos_attr.total_bb_cr); | ||
| 2335 | iocmd->attr.qos_bw.high = fcport->cfg.qos_bw.high; | ||
| 2336 | iocmd->attr.qos_bw.med = fcport->cfg.qos_bw.med; | ||
| 2337 | iocmd->attr.qos_bw.low = fcport->cfg.qos_bw.low; | ||
| 2338 | iocmd->attr.qos_bw_op = fcport->qos_attr.qos_bw_op; | ||
| 2339 | iocmd->status = BFA_STATUS_OK; | ||
| 2340 | } | ||
| 2231 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 2341 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 2232 | 2342 | ||
| 2233 | iocmd->status = BFA_STATUS_OK; | ||
| 2234 | return 0; | 2343 | return 0; |
| 2235 | } | 2344 | } |
| 2236 | 2345 | ||
| @@ -2274,6 +2383,7 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd) | |||
| 2274 | struct bfad_hal_comp fcomp; | 2383 | struct bfad_hal_comp fcomp; |
| 2275 | unsigned long flags; | 2384 | unsigned long flags; |
| 2276 | struct bfa_cb_pending_q_s cb_qe; | 2385 | struct bfa_cb_pending_q_s cb_qe; |
| 2386 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); | ||
| 2277 | 2387 | ||
| 2278 | init_completion(&fcomp.comp); | 2388 | init_completion(&fcomp.comp); |
| 2279 | bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, | 2389 | bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, |
| @@ -2281,7 +2391,11 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd) | |||
| 2281 | 2391 | ||
| 2282 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 2392 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 2283 | WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); | 2393 | WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); |
| 2284 | iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); | 2394 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
| 2395 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) | ||
| 2396 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | ||
| 2397 | else | ||
| 2398 | iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); | ||
| 2285 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 2399 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 2286 | if (iocmd->status != BFA_STATUS_OK) { | 2400 | if (iocmd->status != BFA_STATUS_OK) { |
| 2287 | bfa_trc(bfad, iocmd->status); | 2401 | bfa_trc(bfad, iocmd->status); |
| @@ -2300,6 +2414,7 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd) | |||
| 2300 | struct bfad_hal_comp fcomp; | 2414 | struct bfad_hal_comp fcomp; |
| 2301 | unsigned long flags; | 2415 | unsigned long flags; |
| 2302 | struct bfa_cb_pending_q_s cb_qe; | 2416 | struct bfa_cb_pending_q_s cb_qe; |
| 2417 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); | ||
| 2303 | 2418 | ||
| 2304 | init_completion(&fcomp.comp); | 2419 | init_completion(&fcomp.comp); |
| 2305 | bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, | 2420 | bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, |
| @@ -2307,7 +2422,11 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd) | |||
| 2307 | 2422 | ||
| 2308 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 2423 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
| 2309 | WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); | 2424 | WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); |
| 2310 | iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); | 2425 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && |
| 2426 | (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) | ||
| 2427 | iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; | ||
| 2428 | else | ||
| 2429 | iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); | ||
| 2311 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 2430 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
| 2312 | if (iocmd->status != BFA_STATUS_OK) { | 2431 | if (iocmd->status != BFA_STATUS_OK) { |
| 2313 | bfa_trc(bfad, iocmd->status); | 2432 | bfa_trc(bfad, iocmd->status); |
| @@ -2435,6 +2554,139 @@ bfad_iocmd_fcpim_cfg_lunmask(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) | |||
| 2435 | return 0; | 2554 | return 0; |
| 2436 | } | 2555 | } |
| 2437 | 2556 | ||
| 2557 | int | ||
| 2558 | bfad_iocmd_fcpim_throttle_query(struct bfad_s *bfad, void *cmd) | ||
| 2559 | { | ||
| 2560 | struct bfa_bsg_fcpim_throttle_s *iocmd = | ||
| 2561 | (struct bfa_bsg_fcpim_throttle_s *)cmd; | ||
| 2562 | unsigned long flags; | ||
| 2563 | |||
| 2564 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
| 2565 | iocmd->status = bfa_fcpim_throttle_get(&bfad->bfa, | ||
| 2566 | (void *)&iocmd->throttle); | ||
| 2567 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 2568 | |||
| 2569 | return 0; | ||
| 2570 | } | ||
| 2571 | |||
| 2572 | int | ||
| 2573 | bfad_iocmd_fcpim_throttle_set(struct bfad_s *bfad, void *cmd) | ||
| 2574 | { | ||
| 2575 | struct bfa_bsg_fcpim_throttle_s *iocmd = | ||
| 2576 | (struct bfa_bsg_fcpim_throttle_s *)cmd; | ||
| 2577 | unsigned long flags; | ||
| 2578 | |||
| 2579 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
| 2580 | iocmd->status = bfa_fcpim_throttle_set(&bfad->bfa, | ||
| 2581 | iocmd->throttle.cfg_value); | ||
| 2582 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 2583 | |||
| 2584 | return 0; | ||
| 2585 | } | ||
| 2586 | |||
| 2587 | int | ||
| 2588 | bfad_iocmd_tfru_read(struct bfad_s *bfad, void *cmd) | ||
| 2589 | { | ||
| 2590 | struct bfa_bsg_tfru_s *iocmd = | ||
| 2591 | (struct bfa_bsg_tfru_s *)cmd; | ||
| 2592 | struct bfad_hal_comp fcomp; | ||
| 2593 | unsigned long flags = 0; | ||
| 2594 | |||
| 2595 | init_completion(&fcomp.comp); | ||
| 2596 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
| 2597 | iocmd->status = bfa_tfru_read(BFA_FRU(&bfad->bfa), | ||
| 2598 | &iocmd->data, iocmd->len, iocmd->offset, | ||
| 2599 | bfad_hcb_comp, &fcomp); | ||
| 2600 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 2601 | if (iocmd->status == BFA_STATUS_OK) { | ||
| 2602 | wait_for_completion(&fcomp.comp); | ||
| 2603 | iocmd->status = fcomp.status; | ||
| 2604 | } | ||
| 2605 | |||
| 2606 | return 0; | ||
| 2607 | } | ||
| 2608 | |||
| 2609 | int | ||
| 2610 | bfad_iocmd_tfru_write(struct bfad_s *bfad, void *cmd) | ||
| 2611 | { | ||
| 2612 | struct bfa_bsg_tfru_s *iocmd = | ||
| 2613 | (struct bfa_bsg_tfru_s *)cmd; | ||
| 2614 | struct bfad_hal_comp fcomp; | ||
| 2615 | unsigned long flags = 0; | ||
| 2616 | |||
| 2617 | init_completion(&fcomp.comp); | ||
| 2618 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
| 2619 | iocmd->status = bfa_tfru_write(BFA_FRU(&bfad->bfa), | ||
| 2620 | &iocmd->data, iocmd->len, iocmd->offset, | ||
| 2621 | bfad_hcb_comp, &fcomp); | ||
| 2622 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 2623 | if (iocmd->status == BFA_STATUS_OK) { | ||
| 2624 | wait_for_completion(&fcomp.comp); | ||
| 2625 | iocmd->status = fcomp.status; | ||
| 2626 | } | ||
| 2627 | |||
| 2628 | return 0; | ||
| 2629 | } | ||
| 2630 | |||
| 2631 | int | ||
| 2632 | bfad_iocmd_fruvpd_read(struct bfad_s *bfad, void *cmd) | ||
| 2633 | { | ||
| 2634 | struct bfa_bsg_fruvpd_s *iocmd = | ||
| 2635 | (struct bfa_bsg_fruvpd_s *)cmd; | ||
| 2636 | struct bfad_hal_comp fcomp; | ||
| 2637 | unsigned long flags = 0; | ||
| 2638 | |||
| 2639 | init_completion(&fcomp.comp); | ||
| 2640 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
| 2641 | iocmd->status = bfa_fruvpd_read(BFA_FRU(&bfad->bfa), | ||
| 2642 | &iocmd->data, iocmd->len, iocmd->offset, | ||
| 2643 | bfad_hcb_comp, &fcomp); | ||
| 2644 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 2645 | if (iocmd->status == BFA_STATUS_OK) { | ||
| 2646 | wait_for_completion(&fcomp.comp); | ||
| 2647 | iocmd->status = fcomp.status; | ||
| 2648 | } | ||
| 2649 | |||
| 2650 | return 0; | ||
| 2651 | } | ||
| 2652 | |||
| 2653 | int | ||
| 2654 | bfad_iocmd_fruvpd_update(struct bfad_s *bfad, void *cmd) | ||
| 2655 | { | ||
| 2656 | struct bfa_bsg_fruvpd_s *iocmd = | ||
| 2657 | (struct bfa_bsg_fruvpd_s *)cmd; | ||
| 2658 | struct bfad_hal_comp fcomp; | ||
| 2659 | unsigned long flags = 0; | ||
| 2660 | |||
| 2661 | init_completion(&fcomp.comp); | ||
| 2662 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
| 2663 | iocmd->status = bfa_fruvpd_update(BFA_FRU(&bfad->bfa), | ||
| 2664 | &iocmd->data, iocmd->len, iocmd->offset, | ||
| 2665 | bfad_hcb_comp, &fcomp); | ||
| 2666 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 2667 | if (iocmd->status == BFA_STATUS_OK) { | ||
| 2668 | wait_for_completion(&fcomp.comp); | ||
| 2669 | iocmd->status = fcomp.status; | ||
| 2670 | } | ||
| 2671 | |||
| 2672 | return 0; | ||
| 2673 | } | ||
| 2674 | |||
| 2675 | int | ||
| 2676 | bfad_iocmd_fruvpd_get_max_size(struct bfad_s *bfad, void *cmd) | ||
| 2677 | { | ||
| 2678 | struct bfa_bsg_fruvpd_max_size_s *iocmd = | ||
| 2679 | (struct bfa_bsg_fruvpd_max_size_s *)cmd; | ||
| 2680 | unsigned long flags = 0; | ||
| 2681 | |||
| 2682 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
| 2683 | iocmd->status = bfa_fruvpd_get_max_size(BFA_FRU(&bfad->bfa), | ||
| 2684 | &iocmd->max_size); | ||
| 2685 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
| 2686 | |||
| 2687 | return 0; | ||
| 2688 | } | ||
| 2689 | |||
| 2438 | static int | 2690 | static int |
| 2439 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | 2691 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, |
| 2440 | unsigned int payload_len) | 2692 | unsigned int payload_len) |
| @@ -2660,6 +2912,13 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | |||
| 2660 | case IOCMD_DIAG_LB_STAT: | 2912 | case IOCMD_DIAG_LB_STAT: |
| 2661 | rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); | 2913 | rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); |
| 2662 | break; | 2914 | break; |
| 2915 | case IOCMD_DIAG_DPORT_ENABLE: | ||
| 2916 | case IOCMD_DIAG_DPORT_DISABLE: | ||
| 2917 | rc = bfad_iocmd_diag_cfg_dport(bfad, cmd, iocmd); | ||
| 2918 | break; | ||
| 2919 | case IOCMD_DIAG_DPORT_GET_STATE: | ||
| 2920 | rc = bfad_iocmd_diag_dport_get_state(bfad, iocmd); | ||
| 2921 | break; | ||
| 2663 | case IOCMD_PHY_GET_ATTR: | 2922 | case IOCMD_PHY_GET_ATTR: |
| 2664 | rc = bfad_iocmd_phy_get_attr(bfad, iocmd); | 2923 | rc = bfad_iocmd_phy_get_attr(bfad, iocmd); |
| 2665 | break; | 2924 | break; |
| @@ -2741,6 +3000,9 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | |||
| 2741 | case IOCMD_QOS_RESET_STATS: | 3000 | case IOCMD_QOS_RESET_STATS: |
| 2742 | rc = bfad_iocmd_qos_reset_stats(bfad, iocmd); | 3001 | rc = bfad_iocmd_qos_reset_stats(bfad, iocmd); |
| 2743 | break; | 3002 | break; |
| 3003 | case IOCMD_QOS_SET_BW: | ||
| 3004 | rc = bfad_iocmd_qos_set_bw(bfad, iocmd); | ||
| 3005 | break; | ||
| 2744 | case IOCMD_VF_GET_STATS: | 3006 | case IOCMD_VF_GET_STATS: |
| 2745 | rc = bfad_iocmd_vf_get_stats(bfad, iocmd); | 3007 | rc = bfad_iocmd_vf_get_stats(bfad, iocmd); |
| 2746 | break; | 3008 | break; |
| @@ -2759,6 +3021,29 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | |||
| 2759 | case IOCMD_FCPIM_LUNMASK_DELETE: | 3021 | case IOCMD_FCPIM_LUNMASK_DELETE: |
| 2760 | rc = bfad_iocmd_fcpim_cfg_lunmask(bfad, iocmd, cmd); | 3022 | rc = bfad_iocmd_fcpim_cfg_lunmask(bfad, iocmd, cmd); |
| 2761 | break; | 3023 | break; |
| 3024 | case IOCMD_FCPIM_THROTTLE_QUERY: | ||
| 3025 | rc = bfad_iocmd_fcpim_throttle_query(bfad, iocmd); | ||
| 3026 | break; | ||
| 3027 | case IOCMD_FCPIM_THROTTLE_SET: | ||
| 3028 | rc = bfad_iocmd_fcpim_throttle_set(bfad, iocmd); | ||
| 3029 | break; | ||
| 3030 | /* TFRU */ | ||
| 3031 | case IOCMD_TFRU_READ: | ||
| 3032 | rc = bfad_iocmd_tfru_read(bfad, iocmd); | ||
| 3033 | break; | ||
| 3034 | case IOCMD_TFRU_WRITE: | ||
| 3035 | rc = bfad_iocmd_tfru_write(bfad, iocmd); | ||
| 3036 | break; | ||
| 3037 | /* FRU */ | ||
| 3038 | case IOCMD_FRUVPD_READ: | ||
| 3039 | rc = bfad_iocmd_fruvpd_read(bfad, iocmd); | ||
| 3040 | break; | ||
| 3041 | case IOCMD_FRUVPD_UPDATE: | ||
| 3042 | rc = bfad_iocmd_fruvpd_update(bfad, iocmd); | ||
| 3043 | break; | ||
| 3044 | case IOCMD_FRUVPD_GET_MAX_SIZE: | ||
| 3045 | rc = bfad_iocmd_fruvpd_get_max_size(bfad, iocmd); | ||
| 3046 | break; | ||
| 2762 | default: | 3047 | default: |
| 2763 | rc = -EINVAL; | 3048 | rc = -EINVAL; |
| 2764 | break; | 3049 | break; |
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 8c569ddb750d..15e1fc8e796b 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h | |||
| @@ -141,6 +141,17 @@ enum { | |||
| 141 | IOCMD_FCPIM_LUNMASK_QUERY, | 141 | IOCMD_FCPIM_LUNMASK_QUERY, |
| 142 | IOCMD_FCPIM_LUNMASK_ADD, | 142 | IOCMD_FCPIM_LUNMASK_ADD, |
| 143 | IOCMD_FCPIM_LUNMASK_DELETE, | 143 | IOCMD_FCPIM_LUNMASK_DELETE, |
| 144 | IOCMD_DIAG_DPORT_ENABLE, | ||
| 145 | IOCMD_DIAG_DPORT_DISABLE, | ||
| 146 | IOCMD_DIAG_DPORT_GET_STATE, | ||
| 147 | IOCMD_QOS_SET_BW, | ||
| 148 | IOCMD_FCPIM_THROTTLE_QUERY, | ||
| 149 | IOCMD_FCPIM_THROTTLE_SET, | ||
| 150 | IOCMD_TFRU_READ, | ||
| 151 | IOCMD_TFRU_WRITE, | ||
| 152 | IOCMD_FRUVPD_READ, | ||
| 153 | IOCMD_FRUVPD_UPDATE, | ||
| 154 | IOCMD_FRUVPD_GET_MAX_SIZE, | ||
| 144 | }; | 155 | }; |
| 145 | 156 | ||
| 146 | struct bfa_bsg_gen_s { | 157 | struct bfa_bsg_gen_s { |
| @@ -463,7 +474,8 @@ struct bfa_bsg_pcifn_s { | |||
| 463 | bfa_status_t status; | 474 | bfa_status_t status; |
| 464 | u16 bfad_num; | 475 | u16 bfad_num; |
| 465 | u16 pcifn_id; | 476 | u16 pcifn_id; |
| 466 | u32 bandwidth; | 477 | u16 bw_min; |
| 478 | u16 bw_max; | ||
| 467 | u8 port; | 479 | u8 port; |
| 468 | enum bfi_pcifn_class pcifn_class; | 480 | enum bfi_pcifn_class pcifn_class; |
| 469 | u8 rsvd[1]; | 481 | u8 rsvd[1]; |
| @@ -613,6 +625,13 @@ struct bfa_bsg_diag_lb_stat_s { | |||
| 613 | u16 rsvd; | 625 | u16 rsvd; |
| 614 | }; | 626 | }; |
| 615 | 627 | ||
| 628 | struct bfa_bsg_diag_dport_get_state_s { | ||
| 629 | bfa_status_t status; | ||
| 630 | u16 bfad_num; | ||
| 631 | u16 rsvd; | ||
| 632 | enum bfa_dport_state state; | ||
| 633 | }; | ||
| 634 | |||
| 616 | struct bfa_bsg_phy_attr_s { | 635 | struct bfa_bsg_phy_attr_s { |
| 617 | bfa_status_t status; | 636 | bfa_status_t status; |
| 618 | u16 bfad_num; | 637 | u16 bfad_num; |
| @@ -694,6 +713,13 @@ struct bfa_bsg_qos_vc_attr_s { | |||
| 694 | struct bfa_qos_vc_attr_s attr; | 713 | struct bfa_qos_vc_attr_s attr; |
| 695 | }; | 714 | }; |
| 696 | 715 | ||
| 716 | struct bfa_bsg_qos_bw_s { | ||
| 717 | bfa_status_t status; | ||
| 718 | u16 bfad_num; | ||
| 719 | u16 rsvd; | ||
| 720 | struct bfa_qos_bw_s qos_bw; | ||
| 721 | }; | ||
| 722 | |||
| 697 | struct bfa_bsg_vf_stats_s { | 723 | struct bfa_bsg_vf_stats_s { |
| 698 | bfa_status_t status; | 724 | bfa_status_t status; |
| 699 | u16 bfad_num; | 725 | u16 bfad_num; |
| @@ -722,6 +748,41 @@ struct bfa_bsg_fcpim_lunmask_s { | |||
| 722 | struct scsi_lun lun; | 748 | struct scsi_lun lun; |
| 723 | }; | 749 | }; |
| 724 | 750 | ||
| 751 | struct bfa_bsg_fcpim_throttle_s { | ||
| 752 | bfa_status_t status; | ||
| 753 | u16 bfad_num; | ||
| 754 | u16 vf_id; | ||
| 755 | struct bfa_defs_fcpim_throttle_s throttle; | ||
| 756 | }; | ||
| 757 | |||
| 758 | #define BFA_TFRU_DATA_SIZE 64 | ||
| 759 | #define BFA_MAX_FRUVPD_TRANSFER_SIZE 0x1000 | ||
| 760 | |||
| 761 | struct bfa_bsg_tfru_s { | ||
| 762 | bfa_status_t status; | ||
| 763 | u16 bfad_num; | ||
| 764 | u16 rsvd; | ||
| 765 | u32 offset; | ||
| 766 | u32 len; | ||
| 767 | u8 data[BFA_TFRU_DATA_SIZE]; | ||
| 768 | }; | ||
| 769 | |||
| 770 | struct bfa_bsg_fruvpd_s { | ||
| 771 | bfa_status_t status; | ||
| 772 | u16 bfad_num; | ||
| 773 | u16 rsvd; | ||
| 774 | u32 offset; | ||
| 775 | u32 len; | ||
| 776 | u8 data[BFA_MAX_FRUVPD_TRANSFER_SIZE]; | ||
| 777 | }; | ||
| 778 | |||
| 779 | struct bfa_bsg_fruvpd_max_size_s { | ||
| 780 | bfa_status_t status; | ||
| 781 | u16 bfad_num; | ||
| 782 | u16 rsvd; | ||
| 783 | u32 max_size; | ||
| 784 | }; | ||
| 785 | |||
| 725 | struct bfa_bsg_fcpt_s { | 786 | struct bfa_bsg_fcpt_s { |
| 726 | bfa_status_t status; | 787 | bfa_status_t status; |
| 727 | u16 vf_id; | 788 | u16 vf_id; |
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 1840651ce1d4..0c64a04f01fa 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h | |||
| @@ -57,7 +57,7 @@ | |||
| 57 | #ifdef BFA_DRIVER_VERSION | 57 | #ifdef BFA_DRIVER_VERSION |
| 58 | #define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION | 58 | #define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION |
| 59 | #else | 59 | #else |
| 60 | #define BFAD_DRIVER_VERSION "3.1.2.0" | 60 | #define BFAD_DRIVER_VERSION "3.1.2.1" |
| 61 | #endif | 61 | #endif |
| 62 | 62 | ||
| 63 | #define BFAD_PROTO_NAME FCPI_NAME | 63 | #define BFAD_PROTO_NAME FCPI_NAME |
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index b2ba0b2e91b2..57b146bca18c 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h | |||
| @@ -210,7 +210,8 @@ enum bfi_mclass { | |||
| 210 | BFI_MC_PORT = 21, /* Physical port */ | 210 | BFI_MC_PORT = 21, /* Physical port */ |
| 211 | BFI_MC_SFP = 22, /* SFP module */ | 211 | BFI_MC_SFP = 22, /* SFP module */ |
| 212 | BFI_MC_PHY = 25, /* External PHY message class */ | 212 | BFI_MC_PHY = 25, /* External PHY message class */ |
| 213 | BFI_MC_MAX = 32 | 213 | BFI_MC_FRU = 34, |
| 214 | BFI_MC_MAX = 35 | ||
| 214 | }; | 215 | }; |
| 215 | 216 | ||
| 216 | #define BFI_IOC_MAX_CQS 4 | 217 | #define BFI_IOC_MAX_CQS 4 |
| @@ -288,6 +289,9 @@ struct bfi_ioc_attr_s { | |||
| 288 | char optrom_version[BFA_VERSION_LEN]; | 289 | char optrom_version[BFA_VERSION_LEN]; |
| 289 | struct bfa_mfg_vpd_s vpd; | 290 | struct bfa_mfg_vpd_s vpd; |
| 290 | u32 card_type; /* card type */ | 291 | u32 card_type; /* card type */ |
| 292 | u8 mfg_day; /* manufacturing day */ | ||
| 293 | u8 mfg_month; /* manufacturing month */ | ||
| 294 | u16 mfg_year; /* manufacturing year */ | ||
| 291 | }; | 295 | }; |
| 292 | 296 | ||
| 293 | /* | 297 | /* |
| @@ -687,7 +691,8 @@ struct bfi_ablk_h2i_pf_req_s { | |||
| 687 | u8 pcifn; | 691 | u8 pcifn; |
| 688 | u8 port; | 692 | u8 port; |
| 689 | u16 pers; | 693 | u16 pers; |
| 690 | u32 bw; | 694 | u16 bw_min; /* percent BW @ max speed */ |
| 695 | u16 bw_max; /* percent BW @ max speed */ | ||
| 691 | }; | 696 | }; |
| 692 | 697 | ||
| 693 | /* BFI_ABLK_H2I_OPTROM_ENABLE, BFI_ABLK_H2I_OPTROM_DISABLE */ | 698 | /* BFI_ABLK_H2I_OPTROM_ENABLE, BFI_ABLK_H2I_OPTROM_DISABLE */ |
| @@ -957,6 +962,7 @@ enum bfi_diag_h2i { | |||
| 957 | BFI_DIAG_H2I_TEMPSENSOR = 4, | 962 | BFI_DIAG_H2I_TEMPSENSOR = 4, |
| 958 | BFI_DIAG_H2I_LEDTEST = 5, | 963 | BFI_DIAG_H2I_LEDTEST = 5, |
| 959 | BFI_DIAG_H2I_QTEST = 6, | 964 | BFI_DIAG_H2I_QTEST = 6, |
| 965 | BFI_DIAG_H2I_DPORT = 7, | ||
| 960 | }; | 966 | }; |
| 961 | 967 | ||
| 962 | enum bfi_diag_i2h { | 968 | enum bfi_diag_i2h { |
| @@ -966,6 +972,7 @@ enum bfi_diag_i2h { | |||
| 966 | BFI_DIAG_I2H_TEMPSENSOR = BFA_I2HM(BFI_DIAG_H2I_TEMPSENSOR), | 972 | BFI_DIAG_I2H_TEMPSENSOR = BFA_I2HM(BFI_DIAG_H2I_TEMPSENSOR), |
| 967 | BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST), | 973 | BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST), |
| 968 | BFI_DIAG_I2H_QTEST = BFA_I2HM(BFI_DIAG_H2I_QTEST), | 974 | BFI_DIAG_I2H_QTEST = BFA_I2HM(BFI_DIAG_H2I_QTEST), |
| 975 | BFI_DIAG_I2H_DPORT = BFA_I2HM(BFI_DIAG_H2I_DPORT), | ||
| 969 | }; | 976 | }; |
| 970 | 977 | ||
| 971 | #define BFI_DIAG_MAX_SGES 2 | 978 | #define BFI_DIAG_MAX_SGES 2 |
| @@ -1052,6 +1059,23 @@ struct bfi_diag_qtest_req_s { | |||
| 1052 | #define bfi_diag_qtest_rsp_t struct bfi_diag_qtest_req_s | 1059 | #define bfi_diag_qtest_rsp_t struct bfi_diag_qtest_req_s |
| 1053 | 1060 | ||
| 1054 | /* | 1061 | /* |
| 1062 | * D-port test | ||
| 1063 | */ | ||
| 1064 | enum bfi_dport_req { | ||
| 1065 | BFI_DPORT_DISABLE = 0, /* disable dport request */ | ||
| 1066 | BFI_DPORT_ENABLE = 1, /* enable dport request */ | ||
| 1067 | }; | ||
| 1068 | |||
| 1069 | struct bfi_diag_dport_req_s { | ||
| 1070 | struct bfi_mhdr_s mh; /* 4 bytes */ | ||
| 1071 | u8 req; /* request 1: enable 0: disable */ | ||
| 1072 | u8 status; /* reply status */ | ||
| 1073 | u8 rsvd[2]; | ||
| 1074 | u32 msgtag; /* msgtag for reply */ | ||
| 1075 | }; | ||
| 1076 | #define bfi_diag_dport_rsp_t struct bfi_diag_dport_req_s | ||
| 1077 | |||
| 1078 | /* | ||
| 1055 | * PHY module specific | 1079 | * PHY module specific |
| 1056 | */ | 1080 | */ |
| 1057 | enum bfi_phy_h2i_msgs_e { | 1081 | enum bfi_phy_h2i_msgs_e { |
| @@ -1147,6 +1171,50 @@ struct bfi_phy_write_rsp_s { | |||
| 1147 | u32 length; | 1171 | u32 length; |
| 1148 | }; | 1172 | }; |
| 1149 | 1173 | ||
| 1174 | enum bfi_fru_h2i_msgs { | ||
| 1175 | BFI_FRUVPD_H2I_WRITE_REQ = 1, | ||
| 1176 | BFI_FRUVPD_H2I_READ_REQ = 2, | ||
| 1177 | BFI_TFRU_H2I_WRITE_REQ = 3, | ||
| 1178 | BFI_TFRU_H2I_READ_REQ = 4, | ||
| 1179 | }; | ||
| 1180 | |||
| 1181 | enum bfi_fru_i2h_msgs { | ||
| 1182 | BFI_FRUVPD_I2H_WRITE_RSP = BFA_I2HM(1), | ||
| 1183 | BFI_FRUVPD_I2H_READ_RSP = BFA_I2HM(2), | ||
| 1184 | BFI_TFRU_I2H_WRITE_RSP = BFA_I2HM(3), | ||
| 1185 | BFI_TFRU_I2H_READ_RSP = BFA_I2HM(4), | ||
| 1186 | }; | ||
| 1187 | |||
| 1188 | /* | ||
| 1189 | * FRU write request | ||
| 1190 | */ | ||
| 1191 | struct bfi_fru_write_req_s { | ||
| 1192 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
| 1193 | u8 last; | ||
| 1194 | u8 rsv[3]; | ||
| 1195 | u32 offset; | ||
| 1196 | u32 length; | ||
| 1197 | struct bfi_alen_s alen; | ||
| 1198 | }; | ||
| 1199 | |||
| 1200 | /* | ||
| 1201 | * FRU read request | ||
| 1202 | */ | ||
| 1203 | struct bfi_fru_read_req_s { | ||
| 1204 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
| 1205 | u32 offset; | ||
| 1206 | u32 length; | ||
| 1207 | struct bfi_alen_s alen; | ||
| 1208 | }; | ||
| 1209 | |||
| 1210 | /* | ||
| 1211 | * FRU response | ||
| 1212 | */ | ||
| 1213 | struct bfi_fru_rsp_s { | ||
| 1214 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
| 1215 | u32 status; | ||
| 1216 | u32 length; | ||
| 1217 | }; | ||
| 1150 | #pragma pack() | 1218 | #pragma pack() |
| 1151 | 1219 | ||
| 1152 | #endif /* __BFI_H__ */ | 1220 | #endif /* __BFI_H__ */ |
diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h index d4220e13cafa..5ae2c167b2c8 100644 --- a/drivers/scsi/bfa/bfi_ms.h +++ b/drivers/scsi/bfa/bfi_ms.h | |||
| @@ -426,6 +426,7 @@ struct bfi_lps_login_req_s { | |||
| 426 | u8 auth_en; | 426 | u8 auth_en; |
| 427 | u8 lps_role; | 427 | u8 lps_role; |
| 428 | u8 bb_scn; | 428 | u8 bb_scn; |
| 429 | u32 vvl_flag; | ||
| 429 | }; | 430 | }; |
| 430 | 431 | ||
| 431 | struct bfi_lps_login_rsp_s { | 432 | struct bfi_lps_login_rsp_s { |
| @@ -499,6 +500,9 @@ enum bfi_rport_i2h_msgs { | |||
| 499 | BFI_RPORT_I2H_CREATE_RSP = BFA_I2HM(1), | 500 | BFI_RPORT_I2H_CREATE_RSP = BFA_I2HM(1), |
| 500 | BFI_RPORT_I2H_DELETE_RSP = BFA_I2HM(2), | 501 | BFI_RPORT_I2H_DELETE_RSP = BFA_I2HM(2), |
| 501 | BFI_RPORT_I2H_QOS_SCN = BFA_I2HM(3), | 502 | BFI_RPORT_I2H_QOS_SCN = BFA_I2HM(3), |
| 503 | BFI_RPORT_I2H_LIP_SCN_ONLINE = BFA_I2HM(4), | ||
| 504 | BFI_RPORT_I2H_LIP_SCN_OFFLINE = BFA_I2HM(5), | ||
| 505 | BFI_RPORT_I2H_NO_DEV = BFA_I2HM(6), | ||
| 502 | }; | 506 | }; |
| 503 | 507 | ||
| 504 | struct bfi_rport_create_req_s { | 508 | struct bfi_rport_create_req_s { |
| @@ -551,6 +555,14 @@ struct bfi_rport_qos_scn_s { | |||
| 551 | struct bfa_rport_qos_attr_s new_qos_attr; /* New QoS Attributes */ | 555 | struct bfa_rport_qos_attr_s new_qos_attr; /* New QoS Attributes */ |
| 552 | }; | 556 | }; |
| 553 | 557 | ||
| 558 | struct bfi_rport_lip_scn_s { | ||
| 559 | struct bfi_mhdr_s mh; /*!< common msg header */ | ||
| 560 | u16 bfa_handle; /*!< host rport handle */ | ||
| 561 | u8 status; /*!< scn online status */ | ||
| 562 | u8 rsvd; | ||
| 563 | struct bfa_fcport_loop_info_s loop_info; | ||
| 564 | }; | ||
| 565 | |||
| 554 | union bfi_rport_h2i_msg_u { | 566 | union bfi_rport_h2i_msg_u { |
| 555 | struct bfi_msg_s *msg; | 567 | struct bfi_msg_s *msg; |
| 556 | struct bfi_rport_create_req_s *create_req; | 568 | struct bfi_rport_create_req_s *create_req; |
| @@ -563,6 +575,7 @@ union bfi_rport_i2h_msg_u { | |||
| 563 | struct bfi_rport_create_rsp_s *create_rsp; | 575 | struct bfi_rport_create_rsp_s *create_rsp; |
| 564 | struct bfi_rport_delete_rsp_s *delete_rsp; | 576 | struct bfi_rport_delete_rsp_s *delete_rsp; |
| 565 | struct bfi_rport_qos_scn_s *qos_scn_evt; | 577 | struct bfi_rport_qos_scn_s *qos_scn_evt; |
| 578 | struct bfi_rport_lip_scn_s *lip_scn; | ||
| 566 | }; | 579 | }; |
| 567 | 580 | ||
| 568 | /* | 581 | /* |
| @@ -828,6 +841,7 @@ enum bfi_tskim_status { | |||
| 828 | */ | 841 | */ |
| 829 | BFI_TSKIM_STS_TIMEOUT = 10, /* TM request timedout */ | 842 | BFI_TSKIM_STS_TIMEOUT = 10, /* TM request timedout */ |
| 830 | BFI_TSKIM_STS_ABORTED = 11, /* Aborted on host request */ | 843 | BFI_TSKIM_STS_ABORTED = 11, /* Aborted on host request */ |
| 844 | BFI_TSKIM_STS_UTAG = 12, /* unknown tag for request */ | ||
| 831 | }; | 845 | }; |
| 832 | 846 | ||
| 833 | struct bfi_tskim_rsp_s { | 847 | struct bfi_tskim_rsp_s { |
diff --git a/drivers/scsi/bfa/bfi_reg.h b/drivers/scsi/bfa/bfi_reg.h index ed5f159e1867..99133bcf53f9 100644 --- a/drivers/scsi/bfa/bfi_reg.h +++ b/drivers/scsi/bfa/bfi_reg.h | |||
| @@ -338,6 +338,7 @@ enum { | |||
| 338 | #define __A2T_AHB_LOAD 0x00000800 | 338 | #define __A2T_AHB_LOAD 0x00000800 |
| 339 | #define __WGN_READY 0x00000400 | 339 | #define __WGN_READY 0x00000400 |
| 340 | #define __GLBL_PF_VF_CFG_RDY 0x00000200 | 340 | #define __GLBL_PF_VF_CFG_RDY 0x00000200 |
| 341 | #define CT2_NFC_STS_REG 0x00027410 | ||
| 341 | #define CT2_NFC_CSR_CLR_REG 0x00027420 | 342 | #define CT2_NFC_CSR_CLR_REG 0x00027420 |
| 342 | #define CT2_NFC_CSR_SET_REG 0x00027424 | 343 | #define CT2_NFC_CSR_SET_REG 0x00027424 |
| 343 | #define __HALT_NFC_CONTROLLER 0x00000002 | 344 | #define __HALT_NFC_CONTROLLER 0x00000002 |
| @@ -355,6 +356,8 @@ enum { | |||
| 355 | (CT2_CSI_MAC0_CONTROL_REG + \ | 356 | (CT2_CSI_MAC0_CONTROL_REG + \ |
| 356 | (__n) * (CT2_CSI_MAC1_CONTROL_REG - CT2_CSI_MAC0_CONTROL_REG)) | 357 | (__n) * (CT2_CSI_MAC1_CONTROL_REG - CT2_CSI_MAC0_CONTROL_REG)) |
| 357 | 358 | ||
| 359 | #define CT2_NFC_FLASH_STS_REG 0x00014834 | ||
| 360 | #define __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS 0x00000020 | ||
| 358 | /* | 361 | /* |
| 359 | * Name semaphore registers based on usage | 362 | * Name semaphore registers based on usage |
| 360 | */ | 363 | */ |
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 078d262ac7cc..666b7ac4475f 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
| @@ -1643,7 +1643,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
| 1643 | skb_reset_network_header(skb); | 1643 | skb_reset_network_header(skb); |
| 1644 | skb->mac_len = elen; | 1644 | skb->mac_len = elen; |
| 1645 | skb->protocol = htons(ETH_P_FCOE); | 1645 | skb->protocol = htons(ETH_P_FCOE); |
| 1646 | skb->priority = port->priority; | 1646 | skb->priority = fcoe->priority; |
| 1647 | 1647 | ||
| 1648 | if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN && | 1648 | if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN && |
| 1649 | fcoe->realdev->features & NETIF_F_HW_VLAN_TX) { | 1649 | fcoe->realdev->features & NETIF_F_HW_VLAN_TX) { |
| @@ -1917,7 +1917,6 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, | |||
| 1917 | struct fcoe_ctlr *ctlr; | 1917 | struct fcoe_ctlr *ctlr; |
| 1918 | struct fcoe_interface *fcoe; | 1918 | struct fcoe_interface *fcoe; |
| 1919 | struct net_device *netdev; | 1919 | struct net_device *netdev; |
| 1920 | struct fcoe_port *port; | ||
| 1921 | int prio; | 1920 | int prio; |
| 1922 | 1921 | ||
| 1923 | if (entry->app.selector != DCB_APP_IDTYPE_ETHTYPE) | 1922 | if (entry->app.selector != DCB_APP_IDTYPE_ETHTYPE) |
| @@ -1946,10 +1945,8 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, | |||
| 1946 | entry->app.protocol == ETH_P_FCOE) | 1945 | entry->app.protocol == ETH_P_FCOE) |
| 1947 | ctlr->priority = prio; | 1946 | ctlr->priority = prio; |
| 1948 | 1947 | ||
| 1949 | if (entry->app.protocol == ETH_P_FCOE) { | 1948 | if (entry->app.protocol == ETH_P_FCOE) |
| 1950 | port = lport_priv(ctlr->lp); | 1949 | fcoe->priority = prio; |
| 1951 | port->priority = prio; | ||
| 1952 | } | ||
| 1953 | 1950 | ||
| 1954 | return NOTIFY_OK; | 1951 | return NOTIFY_OK; |
| 1955 | } | 1952 | } |
| @@ -2180,7 +2177,6 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) | |||
| 2180 | u8 fup, up; | 2177 | u8 fup, up; |
| 2181 | struct net_device *netdev = fcoe->realdev; | 2178 | struct net_device *netdev = fcoe->realdev; |
| 2182 | struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); | 2179 | struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); |
| 2183 | struct fcoe_port *port = lport_priv(ctlr->lp); | ||
| 2184 | struct dcb_app app = { | 2180 | struct dcb_app app = { |
| 2185 | .priority = 0, | 2181 | .priority = 0, |
| 2186 | .protocol = ETH_P_FCOE | 2182 | .protocol = ETH_P_FCOE |
| @@ -2202,8 +2198,8 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) | |||
| 2202 | fup = dcb_getapp(netdev, &app); | 2198 | fup = dcb_getapp(netdev, &app); |
| 2203 | } | 2199 | } |
| 2204 | 2200 | ||
| 2205 | port->priority = ffs(up) ? ffs(up) - 1 : 0; | 2201 | fcoe->priority = ffs(up) ? ffs(up) - 1 : 0; |
| 2206 | ctlr->priority = ffs(fup) ? ffs(fup) - 1 : port->priority; | 2202 | ctlr->priority = ffs(fup) ? ffs(fup) - 1 : fcoe->priority; |
| 2207 | } | 2203 | } |
| 2208 | #endif | 2204 | #endif |
| 2209 | } | 2205 | } |
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h index a624add4f8ec..b42dc32cb5eb 100644 --- a/drivers/scsi/fcoe/fcoe.h +++ b/drivers/scsi/fcoe/fcoe.h | |||
| @@ -71,6 +71,7 @@ do { \ | |||
| 71 | * @oem: The offload exchange manager for all local port | 71 | * @oem: The offload exchange manager for all local port |
| 72 | * instances associated with this port | 72 | * instances associated with this port |
| 73 | * @removed: Indicates fcoe interface removed from net device | 73 | * @removed: Indicates fcoe interface removed from net device |
| 74 | * @priority: Priority for the FCoE packet (DCB) | ||
| 74 | * This structure is 1:1 with a net device. | 75 | * This structure is 1:1 with a net device. |
| 75 | */ | 76 | */ |
| 76 | struct fcoe_interface { | 77 | struct fcoe_interface { |
| @@ -81,6 +82,7 @@ struct fcoe_interface { | |||
| 81 | struct packet_type fip_packet_type; | 82 | struct packet_type fip_packet_type; |
| 82 | struct fc_exch_mgr *oem; | 83 | struct fc_exch_mgr *oem; |
| 83 | u8 removed; | 84 | u8 removed; |
| 85 | u8 priority; | ||
| 84 | }; | 86 | }; |
| 85 | 87 | ||
| 86 | #define fcoe_to_ctlr(x) \ | 88 | #define fcoe_to_ctlr(x) \ |
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 14243fa5f8e8..fcb9d0b20ee4 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
| @@ -851,7 +851,8 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) | |||
| 851 | fc_rp_info = (struct fcp_resp_rsp_info *)(rp_ex + 1); | 851 | fc_rp_info = (struct fcp_resp_rsp_info *)(rp_ex + 1); |
| 852 | if (flags & FCP_RSP_LEN_VAL) { | 852 | if (flags & FCP_RSP_LEN_VAL) { |
| 853 | respl = ntohl(rp_ex->fr_rsp_len); | 853 | respl = ntohl(rp_ex->fr_rsp_len); |
| 854 | if (respl != sizeof(*fc_rp_info)) | 854 | if ((respl != FCP_RESP_RSP_INFO_LEN4) && |
| 855 | (respl != FCP_RESP_RSP_INFO_LEN8)) | ||
| 855 | goto len_err; | 856 | goto len_err; |
| 856 | if (fsp->wait_for_comp) { | 857 | if (fsp->wait_for_comp) { |
| 857 | /* Abuse cdb_status for rsp code */ | 858 | /* Abuse cdb_status for rsp code */ |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index a184c2443a64..69b59935b53f 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | 27 | ||
| 28 | struct lpfc_sli2_slim; | 28 | struct lpfc_sli2_slim; |
| 29 | 29 | ||
| 30 | #define ELX_MODEL_NAME_SIZE 80 | ||
| 31 | |||
| 30 | #define LPFC_PCI_DEV_LP 0x1 | 32 | #define LPFC_PCI_DEV_LP 0x1 |
| 31 | #define LPFC_PCI_DEV_OC 0x2 | 33 | #define LPFC_PCI_DEV_OC 0x2 |
| 32 | 34 | ||
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b032562aa0d9..ad16e54ac383 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
| @@ -3935,6 +3935,12 @@ MODULE_PARM_DESC(lpfc_fcp_look_ahead, "Look ahead for completions"); | |||
| 3935 | # - Only meaningful if BG is turned on (lpfc_enable_bg=1). | 3935 | # - Only meaningful if BG is turned on (lpfc_enable_bg=1). |
| 3936 | # - Allows you to ultimately specify which profiles to use | 3936 | # - Allows you to ultimately specify which profiles to use |
| 3937 | # - Default will result in registering capabilities for all profiles. | 3937 | # - Default will result in registering capabilities for all profiles. |
| 3938 | # - SHOST_DIF_TYPE1_PROTECTION 1 | ||
| 3939 | # HBA supports T10 DIF Type 1: HBA to Target Type 1 Protection | ||
| 3940 | # - SHOST_DIX_TYPE0_PROTECTION 8 | ||
| 3941 | # HBA supports DIX Type 0: Host to HBA protection only | ||
| 3942 | # - SHOST_DIX_TYPE1_PROTECTION 16 | ||
| 3943 | # HBA supports DIX Type 1: Host to HBA Type 1 protection | ||
| 3938 | # | 3944 | # |
| 3939 | */ | 3945 | */ |
| 3940 | unsigned int lpfc_prot_mask = SHOST_DIF_TYPE1_PROTECTION | | 3946 | unsigned int lpfc_prot_mask = SHOST_DIF_TYPE1_PROTECTION | |
| @@ -3947,7 +3953,7 @@ MODULE_PARM_DESC(lpfc_prot_mask, "host protection mask"); | |||
| 3947 | /* | 3953 | /* |
| 3948 | # lpfc_prot_guard: i | 3954 | # lpfc_prot_guard: i |
| 3949 | # - Bit mask of protection guard types to register with the SCSI mid-layer | 3955 | # - Bit mask of protection guard types to register with the SCSI mid-layer |
| 3950 | # - Guard types are currently either 1) IP checksum 2) T10-DIF CRC | 3956 | # - Guard types are currently either 1) T10-DIF CRC 2) IP checksum |
| 3951 | # - Allows you to ultimately specify which profiles to use | 3957 | # - Allows you to ultimately specify which profiles to use |
| 3952 | # - Default will result in registering capabilities for all guard types | 3958 | # - Default will result in registering capabilities for all guard types |
| 3953 | # | 3959 | # |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index e470c489de07..4380a44000bc 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
| @@ -467,3 +467,4 @@ int lpfc_sli4_read_config(struct lpfc_hba *); | |||
| 467 | void lpfc_sli4_node_prep(struct lpfc_hba *); | 467 | void lpfc_sli4_node_prep(struct lpfc_hba *); |
| 468 | int lpfc_sli4_xri_sgl_update(struct lpfc_hba *); | 468 | int lpfc_sli4_xri_sgl_update(struct lpfc_hba *); |
| 469 | void lpfc_free_sgl_list(struct lpfc_hba *, struct list_head *); | 469 | void lpfc_free_sgl_list(struct lpfc_hba *, struct list_head *); |
| 470 | uint32_t lpfc_sli_port_speed_get(struct lpfc_hba *); | ||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index cfe533bc9790..f19e9b6f9f13 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
| @@ -809,6 +809,8 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
| 809 | phba->fc_ratov = FF_DEF_RATOV; | 809 | phba->fc_ratov = FF_DEF_RATOV; |
| 810 | rc = memcmp(&vport->fc_portname, &sp->portName, | 810 | rc = memcmp(&vport->fc_portname, &sp->portName, |
| 811 | sizeof(vport->fc_portname)); | 811 | sizeof(vport->fc_portname)); |
| 812 | memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); | ||
| 813 | |||
| 812 | if (rc >= 0) { | 814 | if (rc >= 0) { |
| 813 | /* This side will initiate the PLOGI */ | 815 | /* This side will initiate the PLOGI */ |
| 814 | spin_lock_irq(shost->host_lock); | 816 | spin_lock_irq(shost->host_lock); |
| @@ -3160,7 +3162,8 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
| 3160 | retry = 1; | 3162 | retry = 1; |
| 3161 | break; | 3163 | break; |
| 3162 | } | 3164 | } |
| 3163 | if (cmd == ELS_CMD_PLOGI) { | 3165 | if ((cmd == ELS_CMD_PLOGI) || |
| 3166 | (cmd == ELS_CMD_PRLI)) { | ||
| 3164 | delay = 1000; | 3167 | delay = 1000; |
| 3165 | maxretry = lpfc_max_els_tries + 1; | 3168 | maxretry = lpfc_max_els_tries + 1; |
| 3166 | retry = 1; | 3169 | retry = 1; |
| @@ -3305,7 +3308,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
| 3305 | ndlp->nlp_prev_state = ndlp->nlp_state; | 3308 | ndlp->nlp_prev_state = ndlp->nlp_state; |
| 3306 | if (cmd == ELS_CMD_PRLI) | 3309 | if (cmd == ELS_CMD_PRLI) |
| 3307 | lpfc_nlp_set_state(vport, ndlp, | 3310 | lpfc_nlp_set_state(vport, ndlp, |
| 3308 | NLP_STE_REG_LOGIN_ISSUE); | 3311 | NLP_STE_PRLI_ISSUE); |
| 3309 | else | 3312 | else |
| 3310 | lpfc_nlp_set_state(vport, ndlp, | 3313 | lpfc_nlp_set_state(vport, ndlp, |
| 3311 | NLP_STE_NPR_NODE); | 3314 | NLP_STE_NPR_NODE); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index e9845d2ecf10..d7096ad94d3f 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
| @@ -1506,9 +1506,10 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba, | |||
| 1506 | } | 1506 | } |
| 1507 | } | 1507 | } |
| 1508 | 1508 | ||
| 1509 | /* If FCF not available return 0 */ | 1509 | /* FCF not valid/available or solicitation in progress */ |
| 1510 | if (!bf_get(lpfc_fcf_record_fcf_avail, new_fcf_record) || | 1510 | if (!bf_get(lpfc_fcf_record_fcf_avail, new_fcf_record) || |
| 1511 | !bf_get(lpfc_fcf_record_fcf_valid, new_fcf_record)) | 1511 | !bf_get(lpfc_fcf_record_fcf_valid, new_fcf_record) || |
| 1512 | bf_get(lpfc_fcf_record_fcf_sol, new_fcf_record)) | ||
| 1512 | return 0; | 1513 | return 0; |
| 1513 | 1514 | ||
| 1514 | if (!(phba->hba_flag & HBA_FIP_SUPPORT)) { | 1515 | if (!(phba->hba_flag & HBA_FIP_SUPPORT)) { |
| @@ -1842,6 +1843,7 @@ lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba, | |||
| 1842 | "\tFCF_Index : x%x\n" | 1843 | "\tFCF_Index : x%x\n" |
| 1843 | "\tFCF_Avail : x%x\n" | 1844 | "\tFCF_Avail : x%x\n" |
| 1844 | "\tFCF_Valid : x%x\n" | 1845 | "\tFCF_Valid : x%x\n" |
| 1846 | "\tFCF_SOL : x%x\n" | ||
| 1845 | "\tFIP_Priority : x%x\n" | 1847 | "\tFIP_Priority : x%x\n" |
| 1846 | "\tMAC_Provider : x%x\n" | 1848 | "\tMAC_Provider : x%x\n" |
| 1847 | "\tLowest VLANID : x%x\n" | 1849 | "\tLowest VLANID : x%x\n" |
| @@ -1852,6 +1854,7 @@ lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba, | |||
| 1852 | bf_get(lpfc_fcf_record_fcf_index, fcf_record), | 1854 | bf_get(lpfc_fcf_record_fcf_index, fcf_record), |
| 1853 | bf_get(lpfc_fcf_record_fcf_avail, fcf_record), | 1855 | bf_get(lpfc_fcf_record_fcf_avail, fcf_record), |
| 1854 | bf_get(lpfc_fcf_record_fcf_valid, fcf_record), | 1856 | bf_get(lpfc_fcf_record_fcf_valid, fcf_record), |
| 1857 | bf_get(lpfc_fcf_record_fcf_sol, fcf_record), | ||
| 1855 | fcf_record->fip_priority, | 1858 | fcf_record->fip_priority, |
| 1856 | bf_get(lpfc_fcf_record_mac_addr_prov, fcf_record), | 1859 | bf_get(lpfc_fcf_record_mac_addr_prov, fcf_record), |
| 1857 | vlan_id, | 1860 | vlan_id, |
| @@ -2185,12 +2188,14 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 2185 | new_fcf_record)); | 2188 | new_fcf_record)); |
| 2186 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, | 2189 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, |
| 2187 | "2781 FCF (x%x) failed connection " | 2190 | "2781 FCF (x%x) failed connection " |
| 2188 | "list check: (x%x/x%x)\n", | 2191 | "list check: (x%x/x%x/%x)\n", |
| 2189 | bf_get(lpfc_fcf_record_fcf_index, | 2192 | bf_get(lpfc_fcf_record_fcf_index, |
| 2190 | new_fcf_record), | 2193 | new_fcf_record), |
| 2191 | bf_get(lpfc_fcf_record_fcf_avail, | 2194 | bf_get(lpfc_fcf_record_fcf_avail, |
| 2192 | new_fcf_record), | 2195 | new_fcf_record), |
| 2193 | bf_get(lpfc_fcf_record_fcf_valid, | 2196 | bf_get(lpfc_fcf_record_fcf_valid, |
| 2197 | new_fcf_record), | ||
| 2198 | bf_get(lpfc_fcf_record_fcf_sol, | ||
| 2194 | new_fcf_record)); | 2199 | new_fcf_record)); |
| 2195 | if ((phba->fcf.fcf_flag & FCF_IN_USE) && | 2200 | if ((phba->fcf.fcf_flag & FCF_IN_USE) && |
| 2196 | lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec, | 2201 | lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec, |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 834b699cac76..2cdeb5434fb7 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
| @@ -1305,6 +1305,11 @@ struct lpfc_mbx_mq_create_ext { | |||
| 1305 | #define lpfc_mbx_mq_create_ext_async_evt_link_SHIFT LPFC_TRAILER_CODE_LINK | 1305 | #define lpfc_mbx_mq_create_ext_async_evt_link_SHIFT LPFC_TRAILER_CODE_LINK |
| 1306 | #define lpfc_mbx_mq_create_ext_async_evt_link_MASK 0x00000001 | 1306 | #define lpfc_mbx_mq_create_ext_async_evt_link_MASK 0x00000001 |
| 1307 | #define lpfc_mbx_mq_create_ext_async_evt_link_WORD async_evt_bmap | 1307 | #define lpfc_mbx_mq_create_ext_async_evt_link_WORD async_evt_bmap |
| 1308 | #define LPFC_EVT_CODE_LINK_NO_LINK 0x0 | ||
| 1309 | #define LPFC_EVT_CODE_LINK_10_MBIT 0x1 | ||
| 1310 | #define LPFC_EVT_CODE_LINK_100_MBIT 0x2 | ||
| 1311 | #define LPFC_EVT_CODE_LINK_1_GBIT 0x3 | ||
| 1312 | #define LPFC_EVT_CODE_LINK_10_GBIT 0x4 | ||
| 1308 | #define lpfc_mbx_mq_create_ext_async_evt_fip_SHIFT LPFC_TRAILER_CODE_FCOE | 1313 | #define lpfc_mbx_mq_create_ext_async_evt_fip_SHIFT LPFC_TRAILER_CODE_FCOE |
| 1309 | #define lpfc_mbx_mq_create_ext_async_evt_fip_MASK 0x00000001 | 1314 | #define lpfc_mbx_mq_create_ext_async_evt_fip_MASK 0x00000001 |
| 1310 | #define lpfc_mbx_mq_create_ext_async_evt_fip_WORD async_evt_bmap | 1315 | #define lpfc_mbx_mq_create_ext_async_evt_fip_WORD async_evt_bmap |
| @@ -1314,6 +1319,13 @@ struct lpfc_mbx_mq_create_ext { | |||
| 1314 | #define lpfc_mbx_mq_create_ext_async_evt_fc_SHIFT LPFC_TRAILER_CODE_FC | 1319 | #define lpfc_mbx_mq_create_ext_async_evt_fc_SHIFT LPFC_TRAILER_CODE_FC |
| 1315 | #define lpfc_mbx_mq_create_ext_async_evt_fc_MASK 0x00000001 | 1320 | #define lpfc_mbx_mq_create_ext_async_evt_fc_MASK 0x00000001 |
| 1316 | #define lpfc_mbx_mq_create_ext_async_evt_fc_WORD async_evt_bmap | 1321 | #define lpfc_mbx_mq_create_ext_async_evt_fc_WORD async_evt_bmap |
| 1322 | #define LPFC_EVT_CODE_FC_NO_LINK 0x0 | ||
| 1323 | #define LPFC_EVT_CODE_FC_1_GBAUD 0x1 | ||
| 1324 | #define LPFC_EVT_CODE_FC_2_GBAUD 0x2 | ||
| 1325 | #define LPFC_EVT_CODE_FC_4_GBAUD 0x4 | ||
| 1326 | #define LPFC_EVT_CODE_FC_8_GBAUD 0x8 | ||
| 1327 | #define LPFC_EVT_CODE_FC_10_GBAUD 0xA | ||
| 1328 | #define LPFC_EVT_CODE_FC_16_GBAUD 0x10 | ||
| 1317 | #define lpfc_mbx_mq_create_ext_async_evt_sli_SHIFT LPFC_TRAILER_CODE_SLI | 1329 | #define lpfc_mbx_mq_create_ext_async_evt_sli_SHIFT LPFC_TRAILER_CODE_SLI |
| 1318 | #define lpfc_mbx_mq_create_ext_async_evt_sli_MASK 0x00000001 | 1330 | #define lpfc_mbx_mq_create_ext_async_evt_sli_MASK 0x00000001 |
| 1319 | #define lpfc_mbx_mq_create_ext_async_evt_sli_WORD async_evt_bmap | 1331 | #define lpfc_mbx_mq_create_ext_async_evt_sli_WORD async_evt_bmap |
| @@ -1695,8 +1707,14 @@ struct fcf_record { | |||
| 1695 | #define lpfc_fcf_record_fc_map_2_MASK 0x000000FF | 1707 | #define lpfc_fcf_record_fc_map_2_MASK 0x000000FF |
| 1696 | #define lpfc_fcf_record_fc_map_2_WORD word7 | 1708 | #define lpfc_fcf_record_fc_map_2_WORD word7 |
| 1697 | #define lpfc_fcf_record_fcf_valid_SHIFT 24 | 1709 | #define lpfc_fcf_record_fcf_valid_SHIFT 24 |
| 1698 | #define lpfc_fcf_record_fcf_valid_MASK 0x000000FF | 1710 | #define lpfc_fcf_record_fcf_valid_MASK 0x00000001 |
| 1699 | #define lpfc_fcf_record_fcf_valid_WORD word7 | 1711 | #define lpfc_fcf_record_fcf_valid_WORD word7 |
| 1712 | #define lpfc_fcf_record_fcf_fc_SHIFT 25 | ||
| 1713 | #define lpfc_fcf_record_fcf_fc_MASK 0x00000001 | ||
| 1714 | #define lpfc_fcf_record_fcf_fc_WORD word7 | ||
| 1715 | #define lpfc_fcf_record_fcf_sol_SHIFT 31 | ||
| 1716 | #define lpfc_fcf_record_fcf_sol_MASK 0x00000001 | ||
| 1717 | #define lpfc_fcf_record_fcf_sol_WORD word7 | ||
| 1700 | uint32_t word8; | 1718 | uint32_t word8; |
| 1701 | #define lpfc_fcf_record_fcf_index_SHIFT 0 | 1719 | #define lpfc_fcf_record_fcf_index_SHIFT 0 |
| 1702 | #define lpfc_fcf_record_fcf_index_MASK 0x0000FFFF | 1720 | #define lpfc_fcf_record_fcf_index_MASK 0x0000FFFF |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 8a55a586dd65..7dc4218d9c4c 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
| @@ -1892,8 +1892,10 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
| 1892 | max_speed = 4; | 1892 | max_speed = 4; |
| 1893 | else if (phba->lmt & LMT_2Gb) | 1893 | else if (phba->lmt & LMT_2Gb) |
| 1894 | max_speed = 2; | 1894 | max_speed = 2; |
| 1895 | else | 1895 | else if (phba->lmt & LMT_1Gb) |
| 1896 | max_speed = 1; | 1896 | max_speed = 1; |
| 1897 | else | ||
| 1898 | max_speed = 0; | ||
| 1897 | 1899 | ||
| 1898 | vp = &phba->vpd; | 1900 | vp = &phba->vpd; |
| 1899 | 1901 | ||
| @@ -2078,9 +2080,13 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
| 2078 | if (descp && descp[0] == '\0') { | 2080 | if (descp && descp[0] == '\0') { |
| 2079 | if (oneConnect) | 2081 | if (oneConnect) |
| 2080 | snprintf(descp, 255, | 2082 | snprintf(descp, 255, |
| 2081 | "Emulex OneConnect %s, %s Initiator, Port %s", | 2083 | "Emulex OneConnect %s, %s Initiator %s", |
| 2082 | m.name, m.function, | 2084 | m.name, m.function, |
| 2083 | phba->Port); | 2085 | phba->Port); |
| 2086 | else if (max_speed == 0) | ||
| 2087 | snprintf(descp, 255, | ||
| 2088 | "Emulex %s %s %s ", | ||
| 2089 | m.name, m.bus, m.function); | ||
| 2084 | else | 2090 | else |
| 2085 | snprintf(descp, 255, | 2091 | snprintf(descp, 255, |
| 2086 | "Emulex %s %d%s %s %s", | 2092 | "Emulex %s %d%s %s %s", |
| @@ -3502,6 +3508,119 @@ lpfc_sli4_parse_latt_link_speed(struct lpfc_hba *phba, | |||
| 3502 | } | 3508 | } |
| 3503 | 3509 | ||
| 3504 | /** | 3510 | /** |
| 3511 | * lpfc_sli_port_speed_get - Get sli3 link speed code to link speed | ||
| 3512 | * @phba: pointer to lpfc hba data structure. | ||
| 3513 | * | ||
| 3514 | * This routine is to get an SLI3 FC port's link speed in Mbps. | ||
| 3515 | * | ||
| 3516 | * Return: link speed in terms of Mbps. | ||
| 3517 | **/ | ||
| 3518 | uint32_t | ||
| 3519 | lpfc_sli_port_speed_get(struct lpfc_hba *phba) | ||
| 3520 | { | ||
| 3521 | uint32_t link_speed; | ||
| 3522 | |||
| 3523 | if (!lpfc_is_link_up(phba)) | ||
| 3524 | return 0; | ||
| 3525 | |||
| 3526 | switch (phba->fc_linkspeed) { | ||
| 3527 | case LPFC_LINK_SPEED_1GHZ: | ||
| 3528 | link_speed = 1000; | ||
| 3529 | break; | ||
| 3530 | case LPFC_LINK_SPEED_2GHZ: | ||
| 3531 | link_speed = 2000; | ||
| 3532 | break; | ||
| 3533 | case LPFC_LINK_SPEED_4GHZ: | ||
| 3534 | link_speed = 4000; | ||
| 3535 | break; | ||
| 3536 | case LPFC_LINK_SPEED_8GHZ: | ||
| 3537 | link_speed = 8000; | ||
| 3538 | break; | ||
| 3539 | case LPFC_LINK_SPEED_10GHZ: | ||
| 3540 | link_speed = 10000; | ||
| 3541 | break; | ||
| 3542 | case LPFC_LINK_SPEED_16GHZ: | ||
| 3543 | link_speed = 16000; | ||
| 3544 | break; | ||
| 3545 | default: | ||
| 3546 | link_speed = 0; | ||
| 3547 | } | ||
| 3548 | return link_speed; | ||
| 3549 | } | ||
| 3550 | |||
| 3551 | /** | ||
| 3552 | * lpfc_sli4_port_speed_parse - Parse async evt link speed code to link speed | ||
| 3553 | * @phba: pointer to lpfc hba data structure. | ||
| 3554 | * @evt_code: asynchronous event code. | ||
| 3555 | * @speed_code: asynchronous event link speed code. | ||
| 3556 | * | ||
| 3557 | * This routine is to parse the giving SLI4 async event link speed code into | ||
| 3558 | * value of Mbps for the link speed. | ||
| 3559 | * | ||
| 3560 | * Return: link speed in terms of Mbps. | ||
| 3561 | **/ | ||
| 3562 | static uint32_t | ||
| 3563 | lpfc_sli4_port_speed_parse(struct lpfc_hba *phba, uint32_t evt_code, | ||
| 3564 | uint8_t speed_code) | ||
| 3565 | { | ||
| 3566 | uint32_t port_speed; | ||
| 3567 | |||
| 3568 | switch (evt_code) { | ||
| 3569 | case LPFC_TRAILER_CODE_LINK: | ||
| 3570 | switch (speed_code) { | ||
| 3571 | case LPFC_EVT_CODE_LINK_NO_LINK: | ||
| 3572 | port_speed = 0; | ||
| 3573 | break; | ||
| 3574 | case LPFC_EVT_CODE_LINK_10_MBIT: | ||
| 3575 | port_speed = 10; | ||
| 3576 | break; | ||
| 3577 | case LPFC_EVT_CODE_LINK_100_MBIT: | ||
| 3578 | port_speed = 100; | ||
| 3579 | break; | ||
| 3580 | case LPFC_EVT_CODE_LINK_1_GBIT: | ||
| 3581 | port_speed = 1000; | ||
| 3582 | break; | ||
| 3583 | case LPFC_EVT_CODE_LINK_10_GBIT: | ||
| 3584 | port_speed = 10000; | ||
| 3585 | break; | ||
| 3586 | default: | ||
| 3587 | port_speed = 0; | ||
| 3588 | } | ||
| 3589 | break; | ||
| 3590 | case LPFC_TRAILER_CODE_FC: | ||
| 3591 | switch (speed_code) { | ||
| 3592 | case LPFC_EVT_CODE_FC_NO_LINK: | ||
| 3593 | port_speed = 0; | ||
| 3594 | break; | ||
| 3595 | case LPFC_EVT_CODE_FC_1_GBAUD: | ||
| 3596 | port_speed = 1000; | ||
| 3597 | break; | ||
| 3598 | case LPFC_EVT_CODE_FC_2_GBAUD: | ||
| 3599 | port_speed = 2000; | ||
| 3600 | break; | ||
| 3601 | case LPFC_EVT_CODE_FC_4_GBAUD: | ||
| 3602 | port_speed = 4000; | ||
| 3603 | break; | ||
| 3604 | case LPFC_EVT_CODE_FC_8_GBAUD: | ||
| 3605 | port_speed = 8000; | ||
| 3606 | break; | ||
| 3607 | case LPFC_EVT_CODE_FC_10_GBAUD: | ||
| 3608 | port_speed = 10000; | ||
| 3609 | break; | ||
| 3610 | case LPFC_EVT_CODE_FC_16_GBAUD: | ||
| 3611 | port_speed = 16000; | ||
| 3612 | break; | ||
| 3613 | default: | ||
| 3614 | port_speed = 0; | ||
| 3615 | } | ||
| 3616 | break; | ||
| 3617 | default: | ||
| 3618 | port_speed = 0; | ||
| 3619 | } | ||
| 3620 | return port_speed; | ||
| 3621 | } | ||
| 3622 | |||
| 3623 | /** | ||
| 3505 | * lpfc_sli4_async_link_evt - Process the asynchronous FCoE link event | 3624 | * lpfc_sli4_async_link_evt - Process the asynchronous FCoE link event |
| 3506 | * @phba: pointer to lpfc hba data structure. | 3625 | * @phba: pointer to lpfc hba data structure. |
| 3507 | * @acqe_link: pointer to the async link completion queue entry. | 3626 | * @acqe_link: pointer to the async link completion queue entry. |
| @@ -3558,7 +3677,8 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba, | |||
| 3558 | 3677 | ||
| 3559 | /* Keep the link status for extra SLI4 state machine reference */ | 3678 | /* Keep the link status for extra SLI4 state machine reference */ |
| 3560 | phba->sli4_hba.link_state.speed = | 3679 | phba->sli4_hba.link_state.speed = |
| 3561 | bf_get(lpfc_acqe_link_speed, acqe_link); | 3680 | lpfc_sli4_port_speed_parse(phba, LPFC_TRAILER_CODE_LINK, |
| 3681 | bf_get(lpfc_acqe_link_speed, acqe_link)); | ||
| 3562 | phba->sli4_hba.link_state.duplex = | 3682 | phba->sli4_hba.link_state.duplex = |
| 3563 | bf_get(lpfc_acqe_link_duplex, acqe_link); | 3683 | bf_get(lpfc_acqe_link_duplex, acqe_link); |
| 3564 | phba->sli4_hba.link_state.status = | 3684 | phba->sli4_hba.link_state.status = |
| @@ -3570,7 +3690,8 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba, | |||
| 3570 | phba->sli4_hba.link_state.fault = | 3690 | phba->sli4_hba.link_state.fault = |
| 3571 | bf_get(lpfc_acqe_link_fault, acqe_link); | 3691 | bf_get(lpfc_acqe_link_fault, acqe_link); |
| 3572 | phba->sli4_hba.link_state.logical_speed = | 3692 | phba->sli4_hba.link_state.logical_speed = |
| 3573 | bf_get(lpfc_acqe_logical_link_speed, acqe_link); | 3693 | bf_get(lpfc_acqe_logical_link_speed, acqe_link) * 10; |
| 3694 | |||
| 3574 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 3695 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
| 3575 | "2900 Async FC/FCoE Link event - Speed:%dGBit " | 3696 | "2900 Async FC/FCoE Link event - Speed:%dGBit " |
| 3576 | "duplex:x%x LA Type:x%x Port Type:%d Port Number:%d " | 3697 | "duplex:x%x LA Type:x%x Port Type:%d Port Number:%d " |
| @@ -3580,7 +3701,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba, | |||
| 3580 | phba->sli4_hba.link_state.status, | 3701 | phba->sli4_hba.link_state.status, |
| 3581 | phba->sli4_hba.link_state.type, | 3702 | phba->sli4_hba.link_state.type, |
| 3582 | phba->sli4_hba.link_state.number, | 3703 | phba->sli4_hba.link_state.number, |
| 3583 | phba->sli4_hba.link_state.logical_speed * 10, | 3704 | phba->sli4_hba.link_state.logical_speed, |
| 3584 | phba->sli4_hba.link_state.fault); | 3705 | phba->sli4_hba.link_state.fault); |
| 3585 | /* | 3706 | /* |
| 3586 | * For FC Mode: issue the READ_TOPOLOGY mailbox command to fetch | 3707 | * For FC Mode: issue the READ_TOPOLOGY mailbox command to fetch |
| @@ -3652,7 +3773,8 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc) | |||
| 3652 | } | 3773 | } |
| 3653 | /* Keep the link status for extra SLI4 state machine reference */ | 3774 | /* Keep the link status for extra SLI4 state machine reference */ |
| 3654 | phba->sli4_hba.link_state.speed = | 3775 | phba->sli4_hba.link_state.speed = |
| 3655 | bf_get(lpfc_acqe_fc_la_speed, acqe_fc); | 3776 | lpfc_sli4_port_speed_parse(phba, LPFC_TRAILER_CODE_FC, |
| 3777 | bf_get(lpfc_acqe_fc_la_speed, acqe_fc)); | ||
| 3656 | phba->sli4_hba.link_state.duplex = LPFC_ASYNC_LINK_DUPLEX_FULL; | 3778 | phba->sli4_hba.link_state.duplex = LPFC_ASYNC_LINK_DUPLEX_FULL; |
| 3657 | phba->sli4_hba.link_state.topology = | 3779 | phba->sli4_hba.link_state.topology = |
| 3658 | bf_get(lpfc_acqe_fc_la_topology, acqe_fc); | 3780 | bf_get(lpfc_acqe_fc_la_topology, acqe_fc); |
| @@ -3665,7 +3787,7 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc) | |||
| 3665 | phba->sli4_hba.link_state.fault = | 3787 | phba->sli4_hba.link_state.fault = |
| 3666 | bf_get(lpfc_acqe_link_fault, acqe_fc); | 3788 | bf_get(lpfc_acqe_link_fault, acqe_fc); |
| 3667 | phba->sli4_hba.link_state.logical_speed = | 3789 | phba->sli4_hba.link_state.logical_speed = |
| 3668 | bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc); | 3790 | bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc) * 10; |
| 3669 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 3791 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
| 3670 | "2896 Async FC event - Speed:%dGBaud Topology:x%x " | 3792 | "2896 Async FC event - Speed:%dGBaud Topology:x%x " |
| 3671 | "LA Type:x%x Port Type:%d Port Number:%d Logical speed:" | 3793 | "LA Type:x%x Port Type:%d Port Number:%d Logical speed:" |
| @@ -3675,7 +3797,7 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc) | |||
| 3675 | phba->sli4_hba.link_state.status, | 3797 | phba->sli4_hba.link_state.status, |
| 3676 | phba->sli4_hba.link_state.type, | 3798 | phba->sli4_hba.link_state.type, |
| 3677 | phba->sli4_hba.link_state.number, | 3799 | phba->sli4_hba.link_state.number, |
| 3678 | phba->sli4_hba.link_state.logical_speed * 10, | 3800 | phba->sli4_hba.link_state.logical_speed, |
| 3679 | phba->sli4_hba.link_state.fault); | 3801 | phba->sli4_hba.link_state.fault); |
| 3680 | pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 3802 | pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
| 3681 | if (!pmb) { | 3803 | if (!pmb) { |
| @@ -3783,14 +3905,18 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) | |||
| 3783 | case LPFC_SLI_EVENT_STATUS_VALID: | 3905 | case LPFC_SLI_EVENT_STATUS_VALID: |
| 3784 | return; /* no message if the sfp is okay */ | 3906 | return; /* no message if the sfp is okay */ |
| 3785 | case LPFC_SLI_EVENT_STATUS_NOT_PRESENT: | 3907 | case LPFC_SLI_EVENT_STATUS_NOT_PRESENT: |
| 3786 | sprintf(message, "Not installed"); | 3908 | sprintf(message, "Optics faulted/incorrectly installed/not " \ |
| 3909 | "installed - Reseat optics, if issue not " | ||
| 3910 | "resolved, replace."); | ||
| 3787 | break; | 3911 | break; |
| 3788 | case LPFC_SLI_EVENT_STATUS_WRONG_TYPE: | 3912 | case LPFC_SLI_EVENT_STATUS_WRONG_TYPE: |
| 3789 | sprintf(message, | 3913 | sprintf(message, |
| 3790 | "Optics of two types installed"); | 3914 | "Optics of two types installed - Remove one optic or " \ |
| 3915 | "install matching pair of optics."); | ||
| 3791 | break; | 3916 | break; |
| 3792 | case LPFC_SLI_EVENT_STATUS_UNSUPPORTED: | 3917 | case LPFC_SLI_EVENT_STATUS_UNSUPPORTED: |
| 3793 | sprintf(message, "Incompatible optics"); | 3918 | sprintf(message, "Incompatible optics - Replace with " \ |
| 3919 | "compatible optics for card to function."); | ||
| 3794 | break; | 3920 | break; |
| 3795 | default: | 3921 | default: |
| 3796 | /* firmware is reporting a status we don't know about */ | 3922 | /* firmware is reporting a status we don't know about */ |
| @@ -4161,11 +4287,11 @@ lpfc_sli4_async_grp5_evt(struct lpfc_hba *phba, | |||
| 4161 | phba->fcoe_eventtag = acqe_grp5->event_tag; | 4287 | phba->fcoe_eventtag = acqe_grp5->event_tag; |
| 4162 | prev_ll_spd = phba->sli4_hba.link_state.logical_speed; | 4288 | prev_ll_spd = phba->sli4_hba.link_state.logical_speed; |
| 4163 | phba->sli4_hba.link_state.logical_speed = | 4289 | phba->sli4_hba.link_state.logical_speed = |
| 4164 | (bf_get(lpfc_acqe_grp5_llink_spd, acqe_grp5)); | 4290 | (bf_get(lpfc_acqe_grp5_llink_spd, acqe_grp5)) * 10; |
| 4165 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 4291 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
| 4166 | "2789 GRP5 Async Event: Updating logical link speed " | 4292 | "2789 GRP5 Async Event: Updating logical link speed " |
| 4167 | "from %dMbps to %dMbps\n", (prev_ll_spd * 10), | 4293 | "from %dMbps to %dMbps\n", prev_ll_spd, |
| 4168 | (phba->sli4_hba.link_state.logical_speed*10)); | 4294 | phba->sli4_hba.link_state.logical_speed); |
| 4169 | } | 4295 | } |
| 4170 | 4296 | ||
| 4171 | /** | 4297 | /** |
| @@ -4947,7 +5073,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
| 4947 | } | 5073 | } |
| 4948 | 5074 | ||
| 4949 | phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) * | 5075 | phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) * |
| 4950 | phba->sli4_hba.cfg_eqn), GFP_KERNEL); | 5076 | phba->cfg_fcp_io_channel), GFP_KERNEL); |
| 4951 | if (!phba->sli4_hba.msix_entries) { | 5077 | if (!phba->sli4_hba.msix_entries) { |
| 4952 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 5078 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 4953 | "2573 Failed allocate memory for msi-x " | 5079 | "2573 Failed allocate memory for msi-x " |
| @@ -6559,7 +6685,8 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) | |||
| 6559 | i++; | 6685 | i++; |
| 6560 | } | 6686 | } |
| 6561 | if (i < cfg_fcp_io_channel) { | 6687 | if (i < cfg_fcp_io_channel) { |
| 6562 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | 6688 | lpfc_printf_log(phba, |
| 6689 | KERN_ERR, LOG_INIT, | ||
| 6563 | "3188 Reducing IO channels to match number of " | 6690 | "3188 Reducing IO channels to match number of " |
| 6564 | "CPUs: from %d to %d\n", cfg_fcp_io_channel, i); | 6691 | "CPUs: from %d to %d\n", cfg_fcp_io_channel, i); |
| 6565 | cfg_fcp_io_channel = i; | 6692 | cfg_fcp_io_channel = i; |
| @@ -6567,8 +6694,8 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) | |||
| 6567 | 6694 | ||
| 6568 | if (cfg_fcp_io_channel > | 6695 | if (cfg_fcp_io_channel > |
| 6569 | phba->sli4_hba.max_cfg_param.max_eq) { | 6696 | phba->sli4_hba.max_cfg_param.max_eq) { |
| 6570 | cfg_fcp_io_channel = phba->sli4_hba.max_cfg_param.max_eq; | 6697 | if (phba->sli4_hba.max_cfg_param.max_eq < |
| 6571 | if (cfg_fcp_io_channel < LPFC_FCP_IO_CHAN_MIN) { | 6698 | LPFC_FCP_IO_CHAN_MIN) { |
| 6572 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 6699 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 6573 | "2574 Not enough EQs (%d) from the " | 6700 | "2574 Not enough EQs (%d) from the " |
| 6574 | "pci function for supporting FCP " | 6701 | "pci function for supporting FCP " |
| @@ -6577,13 +6704,12 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) | |||
| 6577 | phba->cfg_fcp_io_channel); | 6704 | phba->cfg_fcp_io_channel); |
| 6578 | goto out_error; | 6705 | goto out_error; |
| 6579 | } | 6706 | } |
| 6580 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | 6707 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 6581 | "2575 Not enough EQs (%d) from the pci " | 6708 | "2575 Reducing IO channels to match number of " |
| 6582 | "function for supporting the requested " | 6709 | "available EQs: from %d to %d\n", |
| 6583 | "FCP EQs (%d), the actual FCP EQs can " | 6710 | cfg_fcp_io_channel, |
| 6584 | "be supported: %d\n", | 6711 | phba->sli4_hba.max_cfg_param.max_eq); |
| 6585 | phba->sli4_hba.max_cfg_param.max_eq, | 6712 | cfg_fcp_io_channel = phba->sli4_hba.max_cfg_param.max_eq; |
| 6586 | phba->cfg_fcp_io_channel, cfg_fcp_io_channel); | ||
| 6587 | } | 6713 | } |
| 6588 | 6714 | ||
| 6589 | /* Eventually cfg_fcp_eq_count / cfg_fcp_wq_count will be depricated */ | 6715 | /* Eventually cfg_fcp_eq_count / cfg_fcp_wq_count will be depricated */ |
| @@ -6592,7 +6718,6 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) | |||
| 6592 | phba->cfg_fcp_eq_count = cfg_fcp_io_channel; | 6718 | phba->cfg_fcp_eq_count = cfg_fcp_io_channel; |
| 6593 | phba->cfg_fcp_wq_count = cfg_fcp_io_channel; | 6719 | phba->cfg_fcp_wq_count = cfg_fcp_io_channel; |
| 6594 | phba->cfg_fcp_io_channel = cfg_fcp_io_channel; | 6720 | phba->cfg_fcp_io_channel = cfg_fcp_io_channel; |
| 6595 | phba->sli4_hba.cfg_eqn = cfg_fcp_io_channel; | ||
| 6596 | 6721 | ||
| 6597 | /* Get EQ depth from module parameter, fake the default for now */ | 6722 | /* Get EQ depth from module parameter, fake the default for now */ |
| 6598 | phba->sli4_hba.eq_esize = LPFC_EQE_SIZE_4B; | 6723 | phba->sli4_hba.eq_esize = LPFC_EQE_SIZE_4B; |
| @@ -8095,11 +8220,11 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) | |||
| 8095 | int vectors, rc, index; | 8220 | int vectors, rc, index; |
| 8096 | 8221 | ||
| 8097 | /* Set up MSI-X multi-message vectors */ | 8222 | /* Set up MSI-X multi-message vectors */ |
| 8098 | for (index = 0; index < phba->sli4_hba.cfg_eqn; index++) | 8223 | for (index = 0; index < phba->cfg_fcp_io_channel; index++) |
| 8099 | phba->sli4_hba.msix_entries[index].entry = index; | 8224 | phba->sli4_hba.msix_entries[index].entry = index; |
| 8100 | 8225 | ||
| 8101 | /* Configure MSI-X capability structure */ | 8226 | /* Configure MSI-X capability structure */ |
| 8102 | vectors = phba->sli4_hba.cfg_eqn; | 8227 | vectors = phba->cfg_fcp_io_channel; |
| 8103 | enable_msix_vectors: | 8228 | enable_msix_vectors: |
| 8104 | rc = pci_enable_msix(phba->pcidev, phba->sli4_hba.msix_entries, | 8229 | rc = pci_enable_msix(phba->pcidev, phba->sli4_hba.msix_entries, |
| 8105 | vectors); | 8230 | vectors); |
| @@ -8142,8 +8267,14 @@ enable_msix_vectors: | |||
| 8142 | goto cfg_fail_out; | 8267 | goto cfg_fail_out; |
| 8143 | } | 8268 | } |
| 8144 | } | 8269 | } |
| 8145 | phba->sli4_hba.msix_vec_nr = vectors; | ||
| 8146 | 8270 | ||
| 8271 | if (vectors != phba->cfg_fcp_io_channel) { | ||
| 8272 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 8273 | "3238 Reducing IO channels to match number of " | ||
| 8274 | "MSI-X vectors, requested %d got %d\n", | ||
| 8275 | phba->cfg_fcp_io_channel, vectors); | ||
| 8276 | phba->cfg_fcp_io_channel = vectors; | ||
| 8277 | } | ||
| 8147 | return rc; | 8278 | return rc; |
| 8148 | 8279 | ||
| 8149 | cfg_fail_out: | 8280 | cfg_fail_out: |
| @@ -8171,7 +8302,7 @@ lpfc_sli4_disable_msix(struct lpfc_hba *phba) | |||
| 8171 | int index; | 8302 | int index; |
| 8172 | 8303 | ||
| 8173 | /* Free up MSI-X multi-message vectors */ | 8304 | /* Free up MSI-X multi-message vectors */ |
| 8174 | for (index = 0; index < phba->sli4_hba.msix_vec_nr; index++) | 8305 | for (index = 0; index < phba->cfg_fcp_io_channel; index++) |
| 8175 | free_irq(phba->sli4_hba.msix_entries[index].vector, | 8306 | free_irq(phba->sli4_hba.msix_entries[index].vector, |
| 8176 | &phba->sli4_hba.fcp_eq_hdl[index]); | 8307 | &phba->sli4_hba.fcp_eq_hdl[index]); |
| 8177 | 8308 | ||
| @@ -9304,23 +9435,28 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba) | |||
| 9304 | 9435 | ||
| 9305 | /** | 9436 | /** |
| 9306 | * lpfc_write_firmware - attempt to write a firmware image to the port | 9437 | * lpfc_write_firmware - attempt to write a firmware image to the port |
| 9307 | * @phba: pointer to lpfc hba data structure. | ||
| 9308 | * @fw: pointer to firmware image returned from request_firmware. | 9438 | * @fw: pointer to firmware image returned from request_firmware. |
| 9439 | * @phba: pointer to lpfc hba data structure. | ||
| 9309 | * | 9440 | * |
| 9310 | * returns the number of bytes written if write is successful. | ||
| 9311 | * returns a negative error value if there were errors. | ||
| 9312 | * returns 0 if firmware matches currently active firmware on port. | ||
| 9313 | **/ | 9441 | **/ |
| 9314 | int | 9442 | static void |
| 9315 | lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | 9443 | lpfc_write_firmware(const struct firmware *fw, void *context) |
| 9316 | { | 9444 | { |
| 9445 | struct lpfc_hba *phba = (struct lpfc_hba *)context; | ||
| 9317 | char fwrev[FW_REV_STR_SIZE]; | 9446 | char fwrev[FW_REV_STR_SIZE]; |
| 9318 | struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data; | 9447 | struct lpfc_grp_hdr *image; |
| 9319 | struct list_head dma_buffer_list; | 9448 | struct list_head dma_buffer_list; |
| 9320 | int i, rc = 0; | 9449 | int i, rc = 0; |
| 9321 | struct lpfc_dmabuf *dmabuf, *next; | 9450 | struct lpfc_dmabuf *dmabuf, *next; |
| 9322 | uint32_t offset = 0, temp_offset = 0; | 9451 | uint32_t offset = 0, temp_offset = 0; |
| 9323 | 9452 | ||
| 9453 | /* It can be null, sanity check */ | ||
| 9454 | if (!fw) { | ||
| 9455 | rc = -ENXIO; | ||
| 9456 | goto out; | ||
| 9457 | } | ||
| 9458 | image = (struct lpfc_grp_hdr *)fw->data; | ||
| 9459 | |||
| 9324 | INIT_LIST_HEAD(&dma_buffer_list); | 9460 | INIT_LIST_HEAD(&dma_buffer_list); |
| 9325 | if ((be32_to_cpu(image->magic_number) != LPFC_GROUP_OJECT_MAGIC_NUM) || | 9461 | if ((be32_to_cpu(image->magic_number) != LPFC_GROUP_OJECT_MAGIC_NUM) || |
| 9326 | (bf_get_be32(lpfc_grp_hdr_file_type, image) != | 9462 | (bf_get_be32(lpfc_grp_hdr_file_type, image) != |
| @@ -9333,12 +9469,13 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | |||
| 9333 | be32_to_cpu(image->magic_number), | 9469 | be32_to_cpu(image->magic_number), |
| 9334 | bf_get_be32(lpfc_grp_hdr_file_type, image), | 9470 | bf_get_be32(lpfc_grp_hdr_file_type, image), |
| 9335 | bf_get_be32(lpfc_grp_hdr_id, image)); | 9471 | bf_get_be32(lpfc_grp_hdr_id, image)); |
| 9336 | return -EINVAL; | 9472 | rc = -EINVAL; |
| 9473 | goto release_out; | ||
| 9337 | } | 9474 | } |
| 9338 | lpfc_decode_firmware_rev(phba, fwrev, 1); | 9475 | lpfc_decode_firmware_rev(phba, fwrev, 1); |
| 9339 | if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) { | 9476 | if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) { |
| 9340 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9477 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 9341 | "3023 Updating Firmware. Current Version:%s " | 9478 | "3023 Updating Firmware, Current Version:%s " |
| 9342 | "New Version:%s\n", | 9479 | "New Version:%s\n", |
| 9343 | fwrev, image->revision); | 9480 | fwrev, image->revision); |
| 9344 | for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) { | 9481 | for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) { |
| @@ -9346,7 +9483,7 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | |||
| 9346 | GFP_KERNEL); | 9483 | GFP_KERNEL); |
| 9347 | if (!dmabuf) { | 9484 | if (!dmabuf) { |
| 9348 | rc = -ENOMEM; | 9485 | rc = -ENOMEM; |
| 9349 | goto out; | 9486 | goto release_out; |
| 9350 | } | 9487 | } |
| 9351 | dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev, | 9488 | dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev, |
| 9352 | SLI4_PAGE_SIZE, | 9489 | SLI4_PAGE_SIZE, |
| @@ -9355,7 +9492,7 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | |||
| 9355 | if (!dmabuf->virt) { | 9492 | if (!dmabuf->virt) { |
| 9356 | kfree(dmabuf); | 9493 | kfree(dmabuf); |
| 9357 | rc = -ENOMEM; | 9494 | rc = -ENOMEM; |
| 9358 | goto out; | 9495 | goto release_out; |
| 9359 | } | 9496 | } |
| 9360 | list_add_tail(&dmabuf->list, &dma_buffer_list); | 9497 | list_add_tail(&dmabuf->list, &dma_buffer_list); |
| 9361 | } | 9498 | } |
| @@ -9375,23 +9512,24 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | |||
| 9375 | } | 9512 | } |
| 9376 | rc = lpfc_wr_object(phba, &dma_buffer_list, | 9513 | rc = lpfc_wr_object(phba, &dma_buffer_list, |
| 9377 | (fw->size - offset), &offset); | 9514 | (fw->size - offset), &offset); |
| 9378 | if (rc) { | 9515 | if (rc) |
| 9379 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9516 | goto release_out; |
| 9380 | "3024 Firmware update failed. " | ||
| 9381 | "%d\n", rc); | ||
| 9382 | goto out; | ||
| 9383 | } | ||
| 9384 | } | 9517 | } |
| 9385 | rc = offset; | 9518 | rc = offset; |
| 9386 | } | 9519 | } |
| 9387 | out: | 9520 | |
| 9521 | release_out: | ||
| 9388 | list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) { | 9522 | list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) { |
| 9389 | list_del(&dmabuf->list); | 9523 | list_del(&dmabuf->list); |
| 9390 | dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE, | 9524 | dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE, |
| 9391 | dmabuf->virt, dmabuf->phys); | 9525 | dmabuf->virt, dmabuf->phys); |
| 9392 | kfree(dmabuf); | 9526 | kfree(dmabuf); |
| 9393 | } | 9527 | } |
| 9394 | return rc; | 9528 | release_firmware(fw); |
| 9529 | out: | ||
| 9530 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 9531 | "3024 Firmware update done: %d.", rc); | ||
| 9532 | return; | ||
| 9395 | } | 9533 | } |
| 9396 | 9534 | ||
| 9397 | /** | 9535 | /** |
| @@ -9418,12 +9556,11 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
| 9418 | struct lpfc_hba *phba; | 9556 | struct lpfc_hba *phba; |
| 9419 | struct lpfc_vport *vport = NULL; | 9557 | struct lpfc_vport *vport = NULL; |
| 9420 | struct Scsi_Host *shost = NULL; | 9558 | struct Scsi_Host *shost = NULL; |
| 9421 | int error; | 9559 | int error, ret; |
| 9422 | uint32_t cfg_mode, intr_mode; | 9560 | uint32_t cfg_mode, intr_mode; |
| 9423 | int mcnt; | 9561 | int mcnt; |
| 9424 | int adjusted_fcp_io_channel; | 9562 | int adjusted_fcp_io_channel; |
| 9425 | const struct firmware *fw; | 9563 | uint8_t file_name[ELX_MODEL_NAME_SIZE]; |
| 9426 | uint8_t file_name[16]; | ||
| 9427 | 9564 | ||
| 9428 | /* Allocate memory for HBA structure */ | 9565 | /* Allocate memory for HBA structure */ |
| 9429 | phba = lpfc_hba_alloc(pdev); | 9566 | phba = lpfc_hba_alloc(pdev); |
| @@ -9525,9 +9662,6 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
| 9525 | /* Default to single EQ for non-MSI-X */ | 9662 | /* Default to single EQ for non-MSI-X */ |
| 9526 | if (phba->intr_type != MSIX) | 9663 | if (phba->intr_type != MSIX) |
| 9527 | adjusted_fcp_io_channel = 1; | 9664 | adjusted_fcp_io_channel = 1; |
| 9528 | else if (phba->sli4_hba.msix_vec_nr < | ||
| 9529 | phba->cfg_fcp_io_channel) | ||
| 9530 | adjusted_fcp_io_channel = phba->sli4_hba.msix_vec_nr; | ||
| 9531 | else | 9665 | else |
| 9532 | adjusted_fcp_io_channel = phba->cfg_fcp_io_channel; | 9666 | adjusted_fcp_io_channel = phba->cfg_fcp_io_channel; |
| 9533 | phba->cfg_fcp_io_channel = adjusted_fcp_io_channel; | 9667 | phba->cfg_fcp_io_channel = adjusted_fcp_io_channel; |
| @@ -9572,12 +9706,12 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
| 9572 | /* check for firmware upgrade or downgrade (if_type 2 only) */ | 9706 | /* check for firmware upgrade or downgrade (if_type 2 only) */ |
| 9573 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == | 9707 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == |
| 9574 | LPFC_SLI_INTF_IF_TYPE_2) { | 9708 | LPFC_SLI_INTF_IF_TYPE_2) { |
| 9575 | snprintf(file_name, 16, "%s.grp", phba->ModelName); | 9709 | snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp", |
| 9576 | error = request_firmware(&fw, file_name, &phba->pcidev->dev); | 9710 | phba->ModelName); |
| 9577 | if (!error) { | 9711 | ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, |
| 9578 | lpfc_write_firmware(phba, fw); | 9712 | file_name, &phba->pcidev->dev, |
| 9579 | release_firmware(fw); | 9713 | GFP_KERNEL, (void *)phba, |
| 9580 | } | 9714 | lpfc_write_firmware); |
| 9581 | } | 9715 | } |
| 9582 | 9716 | ||
| 9583 | /* Check if there are static vports to be created. */ | 9717 | /* Check if there are static vports to be created. */ |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 64013f3097ad..7f45ac9964a9 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
| @@ -3829,9 +3829,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
| 3829 | cmd->scsi_done(cmd); | 3829 | cmd->scsi_done(cmd); |
| 3830 | 3830 | ||
| 3831 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 3831 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
| 3832 | spin_lock_irq(&phba->hbalock); | 3832 | spin_lock_irqsave(&phba->hbalock, flags); |
| 3833 | lpfc_cmd->pCmd = NULL; | 3833 | lpfc_cmd->pCmd = NULL; |
| 3834 | spin_unlock_irq(&phba->hbalock); | 3834 | spin_unlock_irqrestore(&phba->hbalock, flags); |
| 3835 | 3835 | ||
| 3836 | /* | 3836 | /* |
| 3837 | * If there is a thread waiting for command completion | 3837 | * If there is a thread waiting for command completion |
| @@ -3871,9 +3871,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
| 3871 | } | 3871 | } |
| 3872 | } | 3872 | } |
| 3873 | 3873 | ||
| 3874 | spin_lock_irq(&phba->hbalock); | 3874 | spin_lock_irqsave(&phba->hbalock, flags); |
| 3875 | lpfc_cmd->pCmd = NULL; | 3875 | lpfc_cmd->pCmd = NULL; |
| 3876 | spin_unlock_irq(&phba->hbalock); | 3876 | spin_unlock_irqrestore(&phba->hbalock, flags); |
| 3877 | 3877 | ||
| 3878 | /* | 3878 | /* |
| 3879 | * If there is a thread waiting for command completion | 3879 | * If there is a thread waiting for command completion |
| @@ -4163,7 +4163,7 @@ lpfc_info(struct Scsi_Host *host) | |||
| 4163 | { | 4163 | { |
| 4164 | struct lpfc_vport *vport = (struct lpfc_vport *) host->hostdata; | 4164 | struct lpfc_vport *vport = (struct lpfc_vport *) host->hostdata; |
| 4165 | struct lpfc_hba *phba = vport->phba; | 4165 | struct lpfc_hba *phba = vport->phba; |
| 4166 | int len; | 4166 | int len, link_speed = 0; |
| 4167 | static char lpfcinfobuf[384]; | 4167 | static char lpfcinfobuf[384]; |
| 4168 | 4168 | ||
| 4169 | memset(lpfcinfobuf,0,384); | 4169 | memset(lpfcinfobuf,0,384); |
| @@ -4184,12 +4184,18 @@ lpfc_info(struct Scsi_Host *host) | |||
| 4184 | phba->Port); | 4184 | phba->Port); |
| 4185 | } | 4185 | } |
| 4186 | len = strlen(lpfcinfobuf); | 4186 | len = strlen(lpfcinfobuf); |
| 4187 | if (phba->sli4_hba.link_state.logical_speed) { | 4187 | if (phba->sli_rev <= LPFC_SLI_REV3) { |
| 4188 | snprintf(lpfcinfobuf + len, | 4188 | link_speed = lpfc_sli_port_speed_get(phba); |
| 4189 | 384-len, | 4189 | } else { |
| 4190 | " Logical Link Speed: %d Mbps", | 4190 | if (phba->sli4_hba.link_state.logical_speed) |
| 4191 | phba->sli4_hba.link_state.logical_speed * 10); | 4191 | link_speed = |
| 4192 | phba->sli4_hba.link_state.logical_speed; | ||
| 4193 | else | ||
| 4194 | link_speed = phba->sli4_hba.link_state.speed; | ||
| 4192 | } | 4195 | } |
| 4196 | if (link_speed != 0) | ||
| 4197 | snprintf(lpfcinfobuf + len, 384-len, | ||
| 4198 | " Logical Link Speed: %d Mbps", link_speed); | ||
| 4193 | } | 4199 | } |
| 4194 | return lpfcinfobuf; | 4200 | return lpfcinfobuf; |
| 4195 | } | 4201 | } |
| @@ -4398,16 +4404,17 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
| 4398 | struct lpfc_scsi_buf *lpfc_cmd; | 4404 | struct lpfc_scsi_buf *lpfc_cmd; |
| 4399 | IOCB_t *cmd, *icmd; | 4405 | IOCB_t *cmd, *icmd; |
| 4400 | int ret = SUCCESS, status = 0; | 4406 | int ret = SUCCESS, status = 0; |
| 4407 | unsigned long flags; | ||
| 4401 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); | 4408 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); |
| 4402 | 4409 | ||
| 4403 | status = fc_block_scsi_eh(cmnd); | 4410 | status = fc_block_scsi_eh(cmnd); |
| 4404 | if (status != 0 && status != SUCCESS) | 4411 | if (status != 0 && status != SUCCESS) |
| 4405 | return status; | 4412 | return status; |
| 4406 | 4413 | ||
| 4407 | spin_lock_irq(&phba->hbalock); | 4414 | spin_lock_irqsave(&phba->hbalock, flags); |
| 4408 | /* driver queued commands are in process of being flushed */ | 4415 | /* driver queued commands are in process of being flushed */ |
| 4409 | if (phba->hba_flag & HBA_FCP_IOQ_FLUSH) { | 4416 | if (phba->hba_flag & HBA_FCP_IOQ_FLUSH) { |
| 4410 | spin_unlock_irq(&phba->hbalock); | 4417 | spin_unlock_irqrestore(&phba->hbalock, flags); |
| 4411 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, | 4418 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, |
| 4412 | "3168 SCSI Layer abort requested I/O has been " | 4419 | "3168 SCSI Layer abort requested I/O has been " |
| 4413 | "flushed by LLD.\n"); | 4420 | "flushed by LLD.\n"); |
| @@ -4416,7 +4423,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
| 4416 | 4423 | ||
| 4417 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; | 4424 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
| 4418 | if (!lpfc_cmd || !lpfc_cmd->pCmd) { | 4425 | if (!lpfc_cmd || !lpfc_cmd->pCmd) { |
| 4419 | spin_unlock_irq(&phba->hbalock); | 4426 | spin_unlock_irqrestore(&phba->hbalock, flags); |
| 4420 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, | 4427 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, |
| 4421 | "2873 SCSI Layer I/O Abort Request IO CMPL Status " | 4428 | "2873 SCSI Layer I/O Abort Request IO CMPL Status " |
| 4422 | "x%x ID %d LUN %d\n", | 4429 | "x%x ID %d LUN %d\n", |
| @@ -4427,7 +4434,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
| 4427 | iocb = &lpfc_cmd->cur_iocbq; | 4434 | iocb = &lpfc_cmd->cur_iocbq; |
| 4428 | /* the command is in process of being cancelled */ | 4435 | /* the command is in process of being cancelled */ |
| 4429 | if (!(iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ)) { | 4436 | if (!(iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ)) { |
| 4430 | spin_unlock_irq(&phba->hbalock); | 4437 | spin_unlock_irqrestore(&phba->hbalock, flags); |
| 4431 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, | 4438 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, |
| 4432 | "3169 SCSI Layer abort requested I/O has been " | 4439 | "3169 SCSI Layer abort requested I/O has been " |
| 4433 | "cancelled by LLD.\n"); | 4440 | "cancelled by LLD.\n"); |
| @@ -4484,7 +4491,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
| 4484 | abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; | 4491 | abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; |
| 4485 | abtsiocb->vport = vport; | 4492 | abtsiocb->vport = vport; |
| 4486 | /* no longer need the lock after this point */ | 4493 | /* no longer need the lock after this point */ |
| 4487 | spin_unlock_irq(&phba->hbalock); | 4494 | spin_unlock_irqrestore(&phba->hbalock, flags); |
| 4488 | 4495 | ||
| 4489 | if (lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, abtsiocb, 0) == | 4496 | if (lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, abtsiocb, 0) == |
| 4490 | IOCB_ERROR) { | 4497 | IOCB_ERROR) { |
| @@ -4516,7 +4523,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
| 4516 | goto out; | 4523 | goto out; |
| 4517 | 4524 | ||
| 4518 | out_unlock: | 4525 | out_unlock: |
| 4519 | spin_unlock_irq(&phba->hbalock); | 4526 | spin_unlock_irqrestore(&phba->hbalock, flags); |
| 4520 | out: | 4527 | out: |
| 4521 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, | 4528 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, |
| 4522 | "0749 SCSI Layer I/O Abort Request Status x%x ID %d " | 4529 | "0749 SCSI Layer I/O Abort Request Status x%x ID %d " |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 219bf534ef99..d7f3313ef886 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
| @@ -3964,9 +3964,9 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba) | |||
| 3964 | pci_write_config_word(phba->pcidev, PCI_COMMAND, (cfg_value & | 3964 | pci_write_config_word(phba->pcidev, PCI_COMMAND, (cfg_value & |
| 3965 | ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); | 3965 | ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); |
| 3966 | 3966 | ||
| 3967 | /* Perform FCoE PCI function reset */ | 3967 | /* Perform FCoE PCI function reset before freeing queue memory */ |
| 3968 | lpfc_sli4_queue_destroy(phba); | ||
| 3969 | rc = lpfc_pci_function_reset(phba); | 3968 | rc = lpfc_pci_function_reset(phba); |
| 3969 | lpfc_sli4_queue_destroy(phba); | ||
| 3970 | 3970 | ||
| 3971 | /* Restore PCI cmd register */ | 3971 | /* Restore PCI cmd register */ |
| 3972 | pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value); | 3972 | pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value); |
| @@ -7072,6 +7072,40 @@ lpfc_sli4_async_mbox_unblock(struct lpfc_hba *phba) | |||
| 7072 | } | 7072 | } |
| 7073 | 7073 | ||
| 7074 | /** | 7074 | /** |
| 7075 | * lpfc_sli4_wait_bmbx_ready - Wait for bootstrap mailbox register ready | ||
| 7076 | * @phba: Pointer to HBA context object. | ||
| 7077 | * @mboxq: Pointer to mailbox object. | ||
| 7078 | * | ||
| 7079 | * The function waits for the bootstrap mailbox register ready bit from | ||
| 7080 | * port for twice the regular mailbox command timeout value. | ||
| 7081 | * | ||
| 7082 | * 0 - no timeout on waiting for bootstrap mailbox register ready. | ||
| 7083 | * MBXERR_ERROR - wait for bootstrap mailbox register timed out. | ||
| 7084 | **/ | ||
| 7085 | static int | ||
| 7086 | lpfc_sli4_wait_bmbx_ready(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
| 7087 | { | ||
| 7088 | uint32_t db_ready; | ||
| 7089 | unsigned long timeout; | ||
| 7090 | struct lpfc_register bmbx_reg; | ||
| 7091 | |||
| 7092 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, mboxq) | ||
| 7093 | * 1000) + jiffies; | ||
| 7094 | |||
| 7095 | do { | ||
| 7096 | bmbx_reg.word0 = readl(phba->sli4_hba.BMBXregaddr); | ||
| 7097 | db_ready = bf_get(lpfc_bmbx_rdy, &bmbx_reg); | ||
| 7098 | if (!db_ready) | ||
| 7099 | msleep(2); | ||
| 7100 | |||
| 7101 | if (time_after(jiffies, timeout)) | ||
| 7102 | return MBXERR_ERROR; | ||
| 7103 | } while (!db_ready); | ||
| 7104 | |||
| 7105 | return 0; | ||
| 7106 | } | ||
| 7107 | |||
| 7108 | /** | ||
| 7075 | * lpfc_sli4_post_sync_mbox - Post an SLI4 mailbox to the bootstrap mailbox | 7109 | * lpfc_sli4_post_sync_mbox - Post an SLI4 mailbox to the bootstrap mailbox |
| 7076 | * @phba: Pointer to HBA context object. | 7110 | * @phba: Pointer to HBA context object. |
| 7077 | * @mboxq: Pointer to mailbox object. | 7111 | * @mboxq: Pointer to mailbox object. |
| @@ -7092,15 +7126,12 @@ lpfc_sli4_post_sync_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 7092 | { | 7126 | { |
| 7093 | int rc = MBX_SUCCESS; | 7127 | int rc = MBX_SUCCESS; |
| 7094 | unsigned long iflag; | 7128 | unsigned long iflag; |
| 7095 | uint32_t db_ready; | ||
| 7096 | uint32_t mcqe_status; | 7129 | uint32_t mcqe_status; |
| 7097 | uint32_t mbx_cmnd; | 7130 | uint32_t mbx_cmnd; |
| 7098 | unsigned long timeout; | ||
| 7099 | struct lpfc_sli *psli = &phba->sli; | 7131 | struct lpfc_sli *psli = &phba->sli; |
| 7100 | struct lpfc_mqe *mb = &mboxq->u.mqe; | 7132 | struct lpfc_mqe *mb = &mboxq->u.mqe; |
| 7101 | struct lpfc_bmbx_create *mbox_rgn; | 7133 | struct lpfc_bmbx_create *mbox_rgn; |
| 7102 | struct dma_address *dma_address; | 7134 | struct dma_address *dma_address; |
| 7103 | struct lpfc_register bmbx_reg; | ||
| 7104 | 7135 | ||
| 7105 | /* | 7136 | /* |
| 7106 | * Only one mailbox can be active to the bootstrap mailbox region | 7137 | * Only one mailbox can be active to the bootstrap mailbox region |
| @@ -7124,6 +7155,11 @@ lpfc_sli4_post_sync_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 7124 | phba->sli.mbox_active = mboxq; | 7155 | phba->sli.mbox_active = mboxq; |
| 7125 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 7156 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
| 7126 | 7157 | ||
| 7158 | /* wait for bootstrap mbox register for readyness */ | ||
| 7159 | rc = lpfc_sli4_wait_bmbx_ready(phba, mboxq); | ||
| 7160 | if (rc) | ||
| 7161 | goto exit; | ||
| 7162 | |||
| 7127 | /* | 7163 | /* |
| 7128 | * Initialize the bootstrap memory region to avoid stale data areas | 7164 | * Initialize the bootstrap memory region to avoid stale data areas |
| 7129 | * in the mailbox post. Then copy the caller's mailbox contents to | 7165 | * in the mailbox post. Then copy the caller's mailbox contents to |
| @@ -7138,35 +7174,18 @@ lpfc_sli4_post_sync_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 7138 | dma_address = &phba->sli4_hba.bmbx.dma_address; | 7174 | dma_address = &phba->sli4_hba.bmbx.dma_address; |
| 7139 | writel(dma_address->addr_hi, phba->sli4_hba.BMBXregaddr); | 7175 | writel(dma_address->addr_hi, phba->sli4_hba.BMBXregaddr); |
| 7140 | 7176 | ||
| 7141 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, mboxq) | 7177 | /* wait for bootstrap mbox register for hi-address write done */ |
| 7142 | * 1000) + jiffies; | 7178 | rc = lpfc_sli4_wait_bmbx_ready(phba, mboxq); |
| 7143 | do { | 7179 | if (rc) |
| 7144 | bmbx_reg.word0 = readl(phba->sli4_hba.BMBXregaddr); | 7180 | goto exit; |
| 7145 | db_ready = bf_get(lpfc_bmbx_rdy, &bmbx_reg); | ||
| 7146 | if (!db_ready) | ||
| 7147 | msleep(2); | ||
| 7148 | |||
| 7149 | if (time_after(jiffies, timeout)) { | ||
| 7150 | rc = MBXERR_ERROR; | ||
| 7151 | goto exit; | ||
| 7152 | } | ||
| 7153 | } while (!db_ready); | ||
| 7154 | 7181 | ||
| 7155 | /* Post the low mailbox dma address to the port. */ | 7182 | /* Post the low mailbox dma address to the port. */ |
| 7156 | writel(dma_address->addr_lo, phba->sli4_hba.BMBXregaddr); | 7183 | writel(dma_address->addr_lo, phba->sli4_hba.BMBXregaddr); |
| 7157 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, mboxq) | ||
| 7158 | * 1000) + jiffies; | ||
| 7159 | do { | ||
| 7160 | bmbx_reg.word0 = readl(phba->sli4_hba.BMBXregaddr); | ||
| 7161 | db_ready = bf_get(lpfc_bmbx_rdy, &bmbx_reg); | ||
| 7162 | if (!db_ready) | ||
| 7163 | msleep(2); | ||
| 7164 | 7184 | ||
| 7165 | if (time_after(jiffies, timeout)) { | 7185 | /* wait for bootstrap mbox register for low address write done */ |
| 7166 | rc = MBXERR_ERROR; | 7186 | rc = lpfc_sli4_wait_bmbx_ready(phba, mboxq); |
| 7167 | goto exit; | 7187 | if (rc) |
| 7168 | } | 7188 | goto exit; |
| 7169 | } while (!db_ready); | ||
| 7170 | 7189 | ||
| 7171 | /* | 7190 | /* |
| 7172 | * Read the CQ to ensure the mailbox has completed. | 7191 | * Read the CQ to ensure the mailbox has completed. |
| @@ -8090,6 +8109,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
| 8090 | bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com, | 8109 | bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com, |
| 8091 | LPFC_WQE_LENLOC_NONE); | 8110 | LPFC_WQE_LENLOC_NONE); |
| 8092 | bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0); | 8111 | bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0); |
| 8112 | bf_set(wqe_erp, &wqe->fcp_icmd.wqe_com, | ||
| 8113 | iocbq->iocb.ulpFCP2Rcvy); | ||
| 8093 | break; | 8114 | break; |
| 8094 | case CMD_GEN_REQUEST64_CR: | 8115 | case CMD_GEN_REQUEST64_CR: |
| 8095 | /* For this command calculate the xmit length of the | 8116 | /* For this command calculate the xmit length of the |
| @@ -12099,6 +12120,7 @@ lpfc_modify_fcp_eq_delay(struct lpfc_hba *phba, uint16_t startq) | |||
| 12099 | struct lpfc_queue *eq; | 12120 | struct lpfc_queue *eq; |
| 12100 | int cnt, rc, length, status = 0; | 12121 | int cnt, rc, length, status = 0; |
| 12101 | uint32_t shdr_status, shdr_add_status; | 12122 | uint32_t shdr_status, shdr_add_status; |
| 12123 | uint32_t result; | ||
| 12102 | int fcp_eqidx; | 12124 | int fcp_eqidx; |
| 12103 | union lpfc_sli4_cfg_shdr *shdr; | 12125 | union lpfc_sli4_cfg_shdr *shdr; |
| 12104 | uint16_t dmult; | 12126 | uint16_t dmult; |
| @@ -12117,8 +12139,11 @@ lpfc_modify_fcp_eq_delay(struct lpfc_hba *phba, uint16_t startq) | |||
| 12117 | eq_delay = &mbox->u.mqe.un.eq_delay; | 12139 | eq_delay = &mbox->u.mqe.un.eq_delay; |
| 12118 | 12140 | ||
| 12119 | /* Calculate delay multiper from maximum interrupt per second */ | 12141 | /* Calculate delay multiper from maximum interrupt per second */ |
| 12120 | dmult = phba->cfg_fcp_imax / phba->cfg_fcp_io_channel; | 12142 | result = phba->cfg_fcp_imax / phba->cfg_fcp_io_channel; |
| 12121 | dmult = LPFC_DMULT_CONST/dmult - 1; | 12143 | if (result > LPFC_DMULT_CONST) |
| 12144 | dmult = 0; | ||
| 12145 | else | ||
| 12146 | dmult = LPFC_DMULT_CONST/result - 1; | ||
| 12122 | 12147 | ||
| 12123 | cnt = 0; | 12148 | cnt = 0; |
| 12124 | for (fcp_eqidx = startq; fcp_eqidx < phba->cfg_fcp_io_channel; | 12149 | for (fcp_eqidx = startq; fcp_eqidx < phba->cfg_fcp_io_channel; |
| @@ -12174,7 +12199,7 @@ lpfc_modify_fcp_eq_delay(struct lpfc_hba *phba, uint16_t startq) | |||
| 12174 | * fails this function will return -ENXIO. | 12199 | * fails this function will return -ENXIO. |
| 12175 | **/ | 12200 | **/ |
| 12176 | uint32_t | 12201 | uint32_t |
| 12177 | lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint16_t imax) | 12202 | lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint32_t imax) |
| 12178 | { | 12203 | { |
| 12179 | struct lpfc_mbx_eq_create *eq_create; | 12204 | struct lpfc_mbx_eq_create *eq_create; |
| 12180 | LPFC_MBOXQ_t *mbox; | 12205 | LPFC_MBOXQ_t *mbox; |
| @@ -12206,7 +12231,10 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint16_t imax) | |||
| 12206 | LPFC_EQE_SIZE); | 12231 | LPFC_EQE_SIZE); |
| 12207 | bf_set(lpfc_eq_context_valid, &eq_create->u.request.context, 1); | 12232 | bf_set(lpfc_eq_context_valid, &eq_create->u.request.context, 1); |
| 12208 | /* Calculate delay multiper from maximum interrupt per second */ | 12233 | /* Calculate delay multiper from maximum interrupt per second */ |
| 12209 | dmult = LPFC_DMULT_CONST/imax - 1; | 12234 | if (imax > LPFC_DMULT_CONST) |
| 12235 | dmult = 0; | ||
| 12236 | else | ||
| 12237 | dmult = LPFC_DMULT_CONST/imax - 1; | ||
| 12210 | bf_set(lpfc_eq_context_delay_multi, &eq_create->u.request.context, | 12238 | bf_set(lpfc_eq_context_delay_multi, &eq_create->u.request.context, |
| 12211 | dmult); | 12239 | dmult); |
| 12212 | switch (eq->entry_count) { | 12240 | switch (eq->entry_count) { |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index bd4bc4342ae2..f44a06a4c6e7 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | /* Multi-queue arrangement for FCP EQ/CQ/WQ tuples */ | 37 | /* Multi-queue arrangement for FCP EQ/CQ/WQ tuples */ |
| 38 | #define LPFC_FCP_IO_CHAN_DEF 4 | 38 | #define LPFC_FCP_IO_CHAN_DEF 4 |
| 39 | #define LPFC_FCP_IO_CHAN_MIN 1 | 39 | #define LPFC_FCP_IO_CHAN_MIN 1 |
| 40 | #define LPFC_FCP_IO_CHAN_MAX 8 | 40 | #define LPFC_FCP_IO_CHAN_MAX 16 |
| 41 | 41 | ||
| 42 | /* | 42 | /* |
| 43 | * Provide the default FCF Record attributes used by the driver | 43 | * Provide the default FCF Record attributes used by the driver |
| @@ -168,7 +168,7 @@ struct lpfc_queue { | |||
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | struct lpfc_sli4_link { | 170 | struct lpfc_sli4_link { |
| 171 | uint8_t speed; | 171 | uint16_t speed; |
| 172 | uint8_t duplex; | 172 | uint8_t duplex; |
| 173 | uint8_t status; | 173 | uint8_t status; |
| 174 | uint8_t type; | 174 | uint8_t type; |
| @@ -490,8 +490,6 @@ struct lpfc_sli4_hba { | |||
| 490 | struct lpfc_pc_sli4_params pc_sli4_params; | 490 | struct lpfc_pc_sli4_params pc_sli4_params; |
| 491 | struct msix_entry *msix_entries; | 491 | struct msix_entry *msix_entries; |
| 492 | uint8_t handler_name[LPFC_FCP_IO_CHAN_MAX][LPFC_SLI4_HANDLER_NAME_SZ]; | 492 | uint8_t handler_name[LPFC_FCP_IO_CHAN_MAX][LPFC_SLI4_HANDLER_NAME_SZ]; |
| 493 | uint32_t cfg_eqn; | ||
| 494 | uint32_t msix_vec_nr; | ||
| 495 | struct lpfc_fcp_eq_hdl *fcp_eq_hdl; /* FCP per-WQ handle */ | 493 | struct lpfc_fcp_eq_hdl *fcp_eq_hdl; /* FCP per-WQ handle */ |
| 496 | 494 | ||
| 497 | /* Pointers to the constructed SLI4 queues */ | 495 | /* Pointers to the constructed SLI4 queues */ |
| @@ -626,7 +624,7 @@ void lpfc_sli4_hba_reset(struct lpfc_hba *); | |||
| 626 | struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t, | 624 | struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t, |
| 627 | uint32_t); | 625 | uint32_t); |
| 628 | void lpfc_sli4_queue_free(struct lpfc_queue *); | 626 | void lpfc_sli4_queue_free(struct lpfc_queue *); |
| 629 | uint32_t lpfc_eq_create(struct lpfc_hba *, struct lpfc_queue *, uint16_t); | 627 | uint32_t lpfc_eq_create(struct lpfc_hba *, struct lpfc_queue *, uint32_t); |
| 630 | uint32_t lpfc_modify_fcp_eq_delay(struct lpfc_hba *, uint16_t); | 628 | uint32_t lpfc_modify_fcp_eq_delay(struct lpfc_hba *, uint16_t); |
| 631 | uint32_t lpfc_cq_create(struct lpfc_hba *, struct lpfc_queue *, | 629 | uint32_t lpfc_cq_create(struct lpfc_hba *, struct lpfc_queue *, |
| 632 | struct lpfc_queue *, uint32_t, uint32_t); | 630 | struct lpfc_queue *, uint32_t, uint32_t); |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 04265a1c4e52..0c2149189dda 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | * included with this package. * | 18 | * included with this package. * |
| 19 | *******************************************************************/ | 19 | *******************************************************************/ |
| 20 | 20 | ||
| 21 | #define LPFC_DRIVER_VERSION "8.3.34" | 21 | #define LPFC_DRIVER_VERSION "8.3.35" |
| 22 | #define LPFC_DRIVER_NAME "lpfc" | 22 | #define LPFC_DRIVER_NAME "lpfc" |
| 23 | 23 | ||
| 24 | /* Used for SLI 2/3 */ | 24 | /* Used for SLI 2/3 */ |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index fcb005fa4bd1..16b7a72a70c4 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Linux MegaRAID driver for SAS based RAID controllers | 2 | * Linux MegaRAID driver for SAS based RAID controllers |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2009-2011 LSI Corporation. | 4 | * Copyright (c) 2003-2012 LSI Corporation. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
| @@ -33,9 +33,9 @@ | |||
| 33 | /* | 33 | /* |
| 34 | * MegaRAID SAS Driver meta data | 34 | * MegaRAID SAS Driver meta data |
| 35 | */ | 35 | */ |
| 36 | #define MEGASAS_VERSION "00.00.06.18-rc1" | 36 | #define MEGASAS_VERSION "06.504.01.00-rc1" |
| 37 | #define MEGASAS_RELDATE "Jun. 17, 2012" | 37 | #define MEGASAS_RELDATE "Oct. 1, 2012" |
| 38 | #define MEGASAS_EXT_VERSION "Tue. Jun. 17 17:00:00 PDT 2012" | 38 | #define MEGASAS_EXT_VERSION "Mon. Oct. 1 17:00:00 PDT 2012" |
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * Device IDs | 41 | * Device IDs |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 0393ec478cdf..d2c5366aff7f 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Linux MegaRAID driver for SAS based RAID controllers | 2 | * Linux MegaRAID driver for SAS based RAID controllers |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2009-2011 LSI Corporation. | 4 | * Copyright (c) 2003-2012 LSI Corporation. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
| @@ -18,7 +18,7 @@ | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | * | 19 | * |
| 20 | * FILE: megaraid_sas_base.c | 20 | * FILE: megaraid_sas_base.c |
| 21 | * Version : v00.00.06.18-rc1 | 21 | * Version : v06.504.01.00-rc1 |
| 22 | * | 22 | * |
| 23 | * Authors: LSI Corporation | 23 | * Authors: LSI Corporation |
| 24 | * Sreenivas Bagalkote | 24 | * Sreenivas Bagalkote |
| @@ -71,6 +71,10 @@ static int msix_disable; | |||
| 71 | module_param(msix_disable, int, S_IRUGO); | 71 | module_param(msix_disable, int, S_IRUGO); |
| 72 | MODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0"); | 72 | MODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0"); |
| 73 | 73 | ||
| 74 | static unsigned int msix_vectors; | ||
| 75 | module_param(msix_vectors, int, S_IRUGO); | ||
| 76 | MODULE_PARM_DESC(msix_vectors, "MSI-X max vector count. Default: Set by FW"); | ||
| 77 | |||
| 74 | static int throttlequeuedepth = MEGASAS_THROTTLE_QUEUE_DEPTH; | 78 | static int throttlequeuedepth = MEGASAS_THROTTLE_QUEUE_DEPTH; |
| 75 | module_param(throttlequeuedepth, int, S_IRUGO); | 79 | module_param(throttlequeuedepth, int, S_IRUGO); |
| 76 | MODULE_PARM_DESC(throttlequeuedepth, | 80 | MODULE_PARM_DESC(throttlequeuedepth, |
| @@ -3520,6 +3524,10 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
| 3520 | instance->msix_vectors = (readl(&instance->reg_set-> | 3524 | instance->msix_vectors = (readl(&instance->reg_set-> |
| 3521 | outbound_scratch_pad_2 | 3525 | outbound_scratch_pad_2 |
| 3522 | ) & 0x1F) + 1; | 3526 | ) & 0x1F) + 1; |
| 3527 | if (msix_vectors) | ||
| 3528 | instance->msix_vectors = | ||
| 3529 | min(msix_vectors, | ||
| 3530 | instance->msix_vectors); | ||
| 3523 | } else | 3531 | } else |
| 3524 | instance->msix_vectors = 1; | 3532 | instance->msix_vectors = 1; |
| 3525 | /* Don't bother allocating more MSI-X vectors than cpus */ | 3533 | /* Don't bother allocating more MSI-X vectors than cpus */ |
| @@ -5233,7 +5241,6 @@ megasas_aen_polling(struct work_struct *work) | |||
| 5233 | 5241 | ||
| 5234 | case MR_EVT_PD_REMOVED: | 5242 | case MR_EVT_PD_REMOVED: |
| 5235 | if (megasas_get_pd_list(instance) == 0) { | 5243 | if (megasas_get_pd_list(instance) == 0) { |
| 5236 | megasas_get_pd_list(instance); | ||
| 5237 | for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { | 5244 | for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) { |
| 5238 | for (j = 0; | 5245 | for (j = 0; |
| 5239 | j < MEGASAS_MAX_DEV_PER_CHANNEL; | 5246 | j < MEGASAS_MAX_DEV_PER_CHANNEL; |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index e3d251a2e26a..a11df82474ef 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Linux MegaRAID driver for SAS based RAID controllers | 2 | * Linux MegaRAID driver for SAS based RAID controllers |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2009-2011 LSI Corporation. | 4 | * Copyright (c) 2009-2012 LSI Corporation. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index ddf094e7d0ac..74030aff69ad 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Linux MegaRAID driver for SAS based RAID controllers | 2 | * Linux MegaRAID driver for SAS based RAID controllers |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2009-2011 LSI Corporation. | 4 | * Copyright (c) 2009-2012 LSI Corporation. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
| @@ -1184,8 +1184,6 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len, | |||
| 1184 | io_request->CDB.EEDP32.PrimaryReferenceTag = | 1184 | io_request->CDB.EEDP32.PrimaryReferenceTag = |
| 1185 | cpu_to_be32(ref_tag); | 1185 | cpu_to_be32(ref_tag); |
| 1186 | io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0xffff; | 1186 | io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0xffff; |
| 1187 | |||
| 1188 | io_request->DataLength = num_blocks * 512; | ||
| 1189 | io_request->IoFlags = 32; /* Specify 32-byte cdb */ | 1187 | io_request->IoFlags = 32; /* Specify 32-byte cdb */ |
| 1190 | 1188 | ||
| 1191 | /* Transfer length */ | 1189 | /* Transfer length */ |
| @@ -1329,7 +1327,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, | |||
| 1329 | struct megasas_cmd_fusion *cmd) | 1327 | struct megasas_cmd_fusion *cmd) |
| 1330 | { | 1328 | { |
| 1331 | u8 fp_possible; | 1329 | u8 fp_possible; |
| 1332 | u32 start_lba_lo, start_lba_hi, device_id; | 1330 | u32 start_lba_lo, start_lba_hi, device_id, datalength = 0; |
| 1333 | struct MPI2_RAID_SCSI_IO_REQUEST *io_request; | 1331 | struct MPI2_RAID_SCSI_IO_REQUEST *io_request; |
| 1334 | union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; | 1332 | union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; |
| 1335 | struct IO_REQUEST_INFO io_info; | 1333 | struct IO_REQUEST_INFO io_info; |
| @@ -1355,7 +1353,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, | |||
| 1355 | * 6-byte READ(0x08) or WRITE(0x0A) cdb | 1353 | * 6-byte READ(0x08) or WRITE(0x0A) cdb |
| 1356 | */ | 1354 | */ |
| 1357 | if (scp->cmd_len == 6) { | 1355 | if (scp->cmd_len == 6) { |
| 1358 | io_request->DataLength = (u32) scp->cmnd[4]; | 1356 | datalength = (u32) scp->cmnd[4]; |
| 1359 | start_lba_lo = ((u32) scp->cmnd[1] << 16) | | 1357 | start_lba_lo = ((u32) scp->cmnd[1] << 16) | |
| 1360 | ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3]; | 1358 | ((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3]; |
| 1361 | 1359 | ||
| @@ -1366,7 +1364,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, | |||
| 1366 | * 10-byte READ(0x28) or WRITE(0x2A) cdb | 1364 | * 10-byte READ(0x28) or WRITE(0x2A) cdb |
| 1367 | */ | 1365 | */ |
| 1368 | else if (scp->cmd_len == 10) { | 1366 | else if (scp->cmd_len == 10) { |
| 1369 | io_request->DataLength = (u32) scp->cmnd[8] | | 1367 | datalength = (u32) scp->cmnd[8] | |
| 1370 | ((u32) scp->cmnd[7] << 8); | 1368 | ((u32) scp->cmnd[7] << 8); |
| 1371 | start_lba_lo = ((u32) scp->cmnd[2] << 24) | | 1369 | start_lba_lo = ((u32) scp->cmnd[2] << 24) | |
| 1372 | ((u32) scp->cmnd[3] << 16) | | 1370 | ((u32) scp->cmnd[3] << 16) | |
| @@ -1377,7 +1375,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, | |||
| 1377 | * 12-byte READ(0xA8) or WRITE(0xAA) cdb | 1375 | * 12-byte READ(0xA8) or WRITE(0xAA) cdb |
| 1378 | */ | 1376 | */ |
| 1379 | else if (scp->cmd_len == 12) { | 1377 | else if (scp->cmd_len == 12) { |
| 1380 | io_request->DataLength = ((u32) scp->cmnd[6] << 24) | | 1378 | datalength = ((u32) scp->cmnd[6] << 24) | |
| 1381 | ((u32) scp->cmnd[7] << 16) | | 1379 | ((u32) scp->cmnd[7] << 16) | |
| 1382 | ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9]; | 1380 | ((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9]; |
| 1383 | start_lba_lo = ((u32) scp->cmnd[2] << 24) | | 1381 | start_lba_lo = ((u32) scp->cmnd[2] << 24) | |
| @@ -1389,7 +1387,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, | |||
| 1389 | * 16-byte READ(0x88) or WRITE(0x8A) cdb | 1387 | * 16-byte READ(0x88) or WRITE(0x8A) cdb |
| 1390 | */ | 1388 | */ |
| 1391 | else if (scp->cmd_len == 16) { | 1389 | else if (scp->cmd_len == 16) { |
| 1392 | io_request->DataLength = ((u32) scp->cmnd[10] << 24) | | 1390 | datalength = ((u32) scp->cmnd[10] << 24) | |
| 1393 | ((u32) scp->cmnd[11] << 16) | | 1391 | ((u32) scp->cmnd[11] << 16) | |
| 1394 | ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13]; | 1392 | ((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13]; |
| 1395 | start_lba_lo = ((u32) scp->cmnd[6] << 24) | | 1393 | start_lba_lo = ((u32) scp->cmnd[6] << 24) | |
| @@ -1403,8 +1401,9 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, | |||
| 1403 | 1401 | ||
| 1404 | memset(&io_info, 0, sizeof(struct IO_REQUEST_INFO)); | 1402 | memset(&io_info, 0, sizeof(struct IO_REQUEST_INFO)); |
| 1405 | io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo; | 1403 | io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo; |
| 1406 | io_info.numBlocks = io_request->DataLength; | 1404 | io_info.numBlocks = datalength; |
| 1407 | io_info.ldTgtId = device_id; | 1405 | io_info.ldTgtId = device_id; |
| 1406 | io_request->DataLength = scsi_bufflen(scp); | ||
| 1408 | 1407 | ||
| 1409 | if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) | 1408 | if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) |
| 1410 | io_info.isRead = 1; | 1409 | io_info.isRead = 1; |
| @@ -1431,7 +1430,6 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, | |||
| 1431 | if (fp_possible) { | 1430 | if (fp_possible) { |
| 1432 | megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp, | 1431 | megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp, |
| 1433 | local_map_ptr, start_lba_lo); | 1432 | local_map_ptr, start_lba_lo); |
| 1434 | io_request->DataLength = scsi_bufflen(scp); | ||
| 1435 | io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST; | 1433 | io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST; |
| 1436 | cmd->request_desc->SCSIIO.RequestFlags = | 1434 | cmd->request_desc->SCSIIO.RequestFlags = |
| 1437 | (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY | 1435 | (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY |
| @@ -1510,7 +1508,8 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, | |||
| 1510 | local_map_ptr = fusion->ld_map[(instance->map_id & 1)]; | 1508 | local_map_ptr = fusion->ld_map[(instance->map_id & 1)]; |
| 1511 | 1509 | ||
| 1512 | /* Check if this is a system PD I/O */ | 1510 | /* Check if this is a system PD I/O */ |
| 1513 | if (instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) { | 1511 | if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS && |
| 1512 | instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) { | ||
| 1514 | io_request->Function = 0; | 1513 | io_request->Function = 0; |
| 1515 | io_request->DevHandle = | 1514 | io_request->DevHandle = |
| 1516 | local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; | 1515 | local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; |
| @@ -1525,6 +1524,8 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, | |||
| 1525 | cmd->request_desc->SCSIIO.RequestFlags = | 1524 | cmd->request_desc->SCSIIO.RequestFlags = |
| 1526 | (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY << | 1525 | (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY << |
| 1527 | MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); | 1526 | MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); |
| 1527 | cmd->request_desc->SCSIIO.DevHandle = | ||
| 1528 | local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; | ||
| 1528 | } else { | 1529 | } else { |
| 1529 | io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST; | 1530 | io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST; |
| 1530 | io_request->DevHandle = device_id; | 1531 | io_request->DevHandle = device_id; |
| @@ -1732,8 +1733,6 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) | |||
| 1732 | if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) | 1733 | if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) |
| 1733 | return IRQ_NONE; | 1734 | return IRQ_NONE; |
| 1734 | 1735 | ||
| 1735 | d_val.word = desc->Words; | ||
| 1736 | |||
| 1737 | num_completed = 0; | 1736 | num_completed = 0; |
| 1738 | 1737 | ||
| 1739 | while ((d_val.u.low != UINT_MAX) && (d_val.u.high != UINT_MAX)) { | 1738 | while ((d_val.u.low != UINT_MAX) && (d_val.u.high != UINT_MAX)) { |
| @@ -1855,10 +1854,8 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr) | |||
| 1855 | } | 1854 | } |
| 1856 | spin_unlock_irqrestore(&instance->hba_lock, flags); | 1855 | spin_unlock_irqrestore(&instance->hba_lock, flags); |
| 1857 | 1856 | ||
| 1858 | spin_lock_irqsave(&instance->completion_lock, flags); | ||
| 1859 | for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++) | 1857 | for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++) |
| 1860 | complete_cmd_fusion(instance, MSIxIndex); | 1858 | complete_cmd_fusion(instance, MSIxIndex); |
| 1861 | spin_unlock_irqrestore(&instance->completion_lock, flags); | ||
| 1862 | } | 1859 | } |
| 1863 | 1860 | ||
| 1864 | /** | 1861 | /** |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 088c9f91da95..a7c64f051996 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Linux MegaRAID driver for SAS based RAID controllers | 2 | * Linux MegaRAID driver for SAS based RAID controllers |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2009-2011 LSI Corporation. | 4 | * Copyright (c) 2009-2012 LSI Corporation. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c index 783edc7c6b98..c585a925b3cd 100644 --- a/drivers/scsi/mvumi.c +++ b/drivers/scsi/mvumi.c | |||
| @@ -35,10 +35,12 @@ | |||
| 35 | #include <linux/io.h> | 35 | #include <linux/io.h> |
| 36 | #include <scsi/scsi.h> | 36 | #include <scsi/scsi.h> |
| 37 | #include <scsi/scsi_cmnd.h> | 37 | #include <scsi/scsi_cmnd.h> |
| 38 | #include <scsi/scsi_device.h> | ||
| 38 | #include <scsi/scsi_host.h> | 39 | #include <scsi/scsi_host.h> |
| 39 | #include <scsi/scsi_transport.h> | 40 | #include <scsi/scsi_transport.h> |
| 40 | #include <scsi/scsi_eh.h> | 41 | #include <scsi/scsi_eh.h> |
| 41 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
| 43 | #include <linux/kthread.h> | ||
| 42 | 44 | ||
| 43 | #include "mvumi.h" | 45 | #include "mvumi.h" |
| 44 | 46 | ||
| @@ -48,6 +50,7 @@ MODULE_DESCRIPTION("Marvell UMI Driver"); | |||
| 48 | 50 | ||
| 49 | static DEFINE_PCI_DEVICE_TABLE(mvumi_pci_table) = { | 51 | static DEFINE_PCI_DEVICE_TABLE(mvumi_pci_table) = { |
| 50 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9143) }, | 52 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9143) }, |
| 53 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9580) }, | ||
| 51 | { 0 } | 54 | { 0 } |
| 52 | }; | 55 | }; |
| 53 | 56 | ||
| @@ -118,7 +121,7 @@ static int mvumi_map_pci_addr(struct pci_dev *dev, void **addr_array) | |||
| 118 | static struct mvumi_res *mvumi_alloc_mem_resource(struct mvumi_hba *mhba, | 121 | static struct mvumi_res *mvumi_alloc_mem_resource(struct mvumi_hba *mhba, |
| 119 | enum resource_type type, unsigned int size) | 122 | enum resource_type type, unsigned int size) |
| 120 | { | 123 | { |
| 121 | struct mvumi_res *res = kzalloc(sizeof(*res), GFP_KERNEL); | 124 | struct mvumi_res *res = kzalloc(sizeof(*res), GFP_ATOMIC); |
| 122 | 125 | ||
| 123 | if (!res) { | 126 | if (!res) { |
| 124 | dev_err(&mhba->pdev->dev, | 127 | dev_err(&mhba->pdev->dev, |
| @@ -128,7 +131,7 @@ static struct mvumi_res *mvumi_alloc_mem_resource(struct mvumi_hba *mhba, | |||
| 128 | 131 | ||
| 129 | switch (type) { | 132 | switch (type) { |
| 130 | case RESOURCE_CACHED_MEMORY: | 133 | case RESOURCE_CACHED_MEMORY: |
| 131 | res->virt_addr = kzalloc(size, GFP_KERNEL); | 134 | res->virt_addr = kzalloc(size, GFP_ATOMIC); |
| 132 | if (!res->virt_addr) { | 135 | if (!res->virt_addr) { |
| 133 | dev_err(&mhba->pdev->dev, | 136 | dev_err(&mhba->pdev->dev, |
| 134 | "unable to allocate memory,size = %d.\n", size); | 137 | "unable to allocate memory,size = %d.\n", size); |
| @@ -222,11 +225,11 @@ static int mvumi_make_sgl(struct mvumi_hba *mhba, struct scsi_cmnd *scmd, | |||
| 222 | m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(busaddr)); | 225 | m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(busaddr)); |
| 223 | m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(busaddr)); | 226 | m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(busaddr)); |
| 224 | m_sg->flags = 0; | 227 | m_sg->flags = 0; |
| 225 | m_sg->size = cpu_to_le32(sg_dma_len(&sg[i])); | 228 | sgd_setsz(mhba, m_sg, cpu_to_le32(sg_dma_len(&sg[i]))); |
| 226 | if ((i + 1) == *sg_count) | 229 | if ((i + 1) == *sg_count) |
| 227 | m_sg->flags |= SGD_EOT; | 230 | m_sg->flags |= 1U << mhba->eot_flag; |
| 228 | 231 | ||
| 229 | m_sg++; | 232 | sgd_inc(mhba, m_sg); |
| 230 | } | 233 | } |
| 231 | } else { | 234 | } else { |
| 232 | scmd->SCp.dma_handle = scsi_bufflen(scmd) ? | 235 | scmd->SCp.dma_handle = scsi_bufflen(scmd) ? |
| @@ -237,8 +240,8 @@ static int mvumi_make_sgl(struct mvumi_hba *mhba, struct scsi_cmnd *scmd, | |||
| 237 | busaddr = scmd->SCp.dma_handle; | 240 | busaddr = scmd->SCp.dma_handle; |
| 238 | m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(busaddr)); | 241 | m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(busaddr)); |
| 239 | m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(busaddr)); | 242 | m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(busaddr)); |
| 240 | m_sg->flags = SGD_EOT; | 243 | m_sg->flags = 1U << mhba->eot_flag; |
| 241 | m_sg->size = cpu_to_le32(scsi_bufflen(scmd)); | 244 | sgd_setsz(mhba, m_sg, cpu_to_le32(scsi_bufflen(scmd))); |
| 242 | *sg_count = 1; | 245 | *sg_count = 1; |
| 243 | } | 246 | } |
| 244 | 247 | ||
| @@ -267,8 +270,8 @@ static int mvumi_internal_cmd_sgl(struct mvumi_hba *mhba, struct mvumi_cmd *cmd, | |||
| 267 | 270 | ||
| 268 | m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(phy_addr)); | 271 | m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(phy_addr)); |
| 269 | m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(phy_addr)); | 272 | m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(phy_addr)); |
| 270 | m_sg->flags = SGD_EOT; | 273 | m_sg->flags = 1U << mhba->eot_flag; |
| 271 | m_sg->size = cpu_to_le32(size); | 274 | sgd_setsz(mhba, m_sg, cpu_to_le32(size)); |
| 272 | 275 | ||
| 273 | return 0; | 276 | return 0; |
| 274 | } | 277 | } |
| @@ -285,7 +288,8 @@ static struct mvumi_cmd *mvumi_create_internal_cmd(struct mvumi_hba *mhba, | |||
| 285 | } | 288 | } |
| 286 | INIT_LIST_HEAD(&cmd->queue_pointer); | 289 | INIT_LIST_HEAD(&cmd->queue_pointer); |
| 287 | 290 | ||
| 288 | cmd->frame = kzalloc(mhba->ib_max_size, GFP_KERNEL); | 291 | cmd->frame = pci_alloc_consistent(mhba->pdev, |
| 292 | mhba->ib_max_size, &cmd->frame_phys); | ||
| 289 | if (!cmd->frame) { | 293 | if (!cmd->frame) { |
| 290 | dev_err(&mhba->pdev->dev, "failed to allocate memory for FW" | 294 | dev_err(&mhba->pdev->dev, "failed to allocate memory for FW" |
| 291 | " frame,size = %d.\n", mhba->ib_max_size); | 295 | " frame,size = %d.\n", mhba->ib_max_size); |
| @@ -297,7 +301,8 @@ static struct mvumi_cmd *mvumi_create_internal_cmd(struct mvumi_hba *mhba, | |||
| 297 | if (mvumi_internal_cmd_sgl(mhba, cmd, buf_size)) { | 301 | if (mvumi_internal_cmd_sgl(mhba, cmd, buf_size)) { |
| 298 | dev_err(&mhba->pdev->dev, "failed to allocate memory" | 302 | dev_err(&mhba->pdev->dev, "failed to allocate memory" |
| 299 | " for internal frame\n"); | 303 | " for internal frame\n"); |
| 300 | kfree(cmd->frame); | 304 | pci_free_consistent(mhba->pdev, mhba->ib_max_size, |
| 305 | cmd->frame, cmd->frame_phys); | ||
| 301 | kfree(cmd); | 306 | kfree(cmd); |
| 302 | return NULL; | 307 | return NULL; |
| 303 | } | 308 | } |
| @@ -317,7 +322,7 @@ static void mvumi_delete_internal_cmd(struct mvumi_hba *mhba, | |||
| 317 | if (cmd && cmd->frame) { | 322 | if (cmd && cmd->frame) { |
| 318 | if (cmd->frame->sg_counts) { | 323 | if (cmd->frame->sg_counts) { |
| 319 | m_sg = (struct mvumi_sgl *) &cmd->frame->payload[0]; | 324 | m_sg = (struct mvumi_sgl *) &cmd->frame->payload[0]; |
| 320 | size = m_sg->size; | 325 | sgd_getsz(mhba, m_sg, size); |
| 321 | 326 | ||
| 322 | phy_addr = (dma_addr_t) m_sg->baseaddr_l | | 327 | phy_addr = (dma_addr_t) m_sg->baseaddr_l | |
| 323 | (dma_addr_t) ((m_sg->baseaddr_h << 16) << 16); | 328 | (dma_addr_t) ((m_sg->baseaddr_h << 16) << 16); |
| @@ -325,7 +330,8 @@ static void mvumi_delete_internal_cmd(struct mvumi_hba *mhba, | |||
| 325 | pci_free_consistent(mhba->pdev, size, cmd->data_buf, | 330 | pci_free_consistent(mhba->pdev, size, cmd->data_buf, |
| 326 | phy_addr); | 331 | phy_addr); |
| 327 | } | 332 | } |
| 328 | kfree(cmd->frame); | 333 | pci_free_consistent(mhba->pdev, mhba->ib_max_size, |
| 334 | cmd->frame, cmd->frame_phys); | ||
| 329 | kfree(cmd); | 335 | kfree(cmd); |
| 330 | } | 336 | } |
| 331 | } | 337 | } |
| @@ -374,7 +380,8 @@ static void mvumi_free_cmds(struct mvumi_hba *mhba) | |||
| 374 | cmd = list_first_entry(&mhba->cmd_pool, struct mvumi_cmd, | 380 | cmd = list_first_entry(&mhba->cmd_pool, struct mvumi_cmd, |
| 375 | queue_pointer); | 381 | queue_pointer); |
| 376 | list_del(&cmd->queue_pointer); | 382 | list_del(&cmd->queue_pointer); |
| 377 | kfree(cmd->frame); | 383 | if (!(mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC)) |
| 384 | kfree(cmd->frame); | ||
| 378 | kfree(cmd); | 385 | kfree(cmd); |
| 379 | } | 386 | } |
| 380 | } | 387 | } |
| @@ -396,7 +403,12 @@ static int mvumi_alloc_cmds(struct mvumi_hba *mhba) | |||
| 396 | 403 | ||
| 397 | INIT_LIST_HEAD(&cmd->queue_pointer); | 404 | INIT_LIST_HEAD(&cmd->queue_pointer); |
| 398 | list_add_tail(&cmd->queue_pointer, &mhba->cmd_pool); | 405 | list_add_tail(&cmd->queue_pointer, &mhba->cmd_pool); |
| 399 | cmd->frame = kzalloc(mhba->ib_max_size, GFP_KERNEL); | 406 | if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) { |
| 407 | cmd->frame = mhba->ib_frame + i * mhba->ib_max_size; | ||
| 408 | cmd->frame_phys = mhba->ib_frame_phys | ||
| 409 | + i * mhba->ib_max_size; | ||
| 410 | } else | ||
| 411 | cmd->frame = kzalloc(mhba->ib_max_size, GFP_KERNEL); | ||
| 400 | if (!cmd->frame) | 412 | if (!cmd->frame) |
| 401 | goto err_exit; | 413 | goto err_exit; |
| 402 | } | 414 | } |
| @@ -409,48 +421,71 @@ err_exit: | |||
| 409 | cmd = list_first_entry(&mhba->cmd_pool, struct mvumi_cmd, | 421 | cmd = list_first_entry(&mhba->cmd_pool, struct mvumi_cmd, |
| 410 | queue_pointer); | 422 | queue_pointer); |
| 411 | list_del(&cmd->queue_pointer); | 423 | list_del(&cmd->queue_pointer); |
| 412 | kfree(cmd->frame); | 424 | if (!(mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC)) |
| 425 | kfree(cmd->frame); | ||
| 413 | kfree(cmd); | 426 | kfree(cmd); |
| 414 | } | 427 | } |
| 415 | return -ENOMEM; | 428 | return -ENOMEM; |
| 416 | } | 429 | } |
| 417 | 430 | ||
| 418 | static int mvumi_get_ib_list_entry(struct mvumi_hba *mhba, void **ib_entry) | 431 | static unsigned int mvumi_check_ib_list_9143(struct mvumi_hba *mhba) |
| 419 | { | 432 | { |
| 420 | unsigned int ib_rp_reg, cur_ib_entry; | 433 | unsigned int ib_rp_reg; |
| 434 | struct mvumi_hw_regs *regs = mhba->regs; | ||
| 435 | |||
| 436 | ib_rp_reg = ioread32(mhba->regs->inb_read_pointer); | ||
| 421 | 437 | ||
| 438 | if (unlikely(((ib_rp_reg & regs->cl_slot_num_mask) == | ||
| 439 | (mhba->ib_cur_slot & regs->cl_slot_num_mask)) && | ||
| 440 | ((ib_rp_reg & regs->cl_pointer_toggle) | ||
| 441 | != (mhba->ib_cur_slot & regs->cl_pointer_toggle)))) { | ||
| 442 | dev_warn(&mhba->pdev->dev, "no free slot to use.\n"); | ||
| 443 | return 0; | ||
| 444 | } | ||
| 422 | if (atomic_read(&mhba->fw_outstanding) >= mhba->max_io) { | 445 | if (atomic_read(&mhba->fw_outstanding) >= mhba->max_io) { |
| 423 | dev_warn(&mhba->pdev->dev, "firmware io overflow.\n"); | 446 | dev_warn(&mhba->pdev->dev, "firmware io overflow.\n"); |
| 424 | return -1; | 447 | return 0; |
| 448 | } else { | ||
| 449 | return mhba->max_io - atomic_read(&mhba->fw_outstanding); | ||
| 425 | } | 450 | } |
| 426 | ib_rp_reg = ioread32(mhba->mmio + CLA_INB_READ_POINTER); | 451 | } |
| 427 | 452 | ||
| 428 | if (unlikely(((ib_rp_reg & CL_SLOT_NUM_MASK) == | 453 | static unsigned int mvumi_check_ib_list_9580(struct mvumi_hba *mhba) |
| 429 | (mhba->ib_cur_slot & CL_SLOT_NUM_MASK)) && | 454 | { |
| 430 | ((ib_rp_reg & CL_POINTER_TOGGLE) != | 455 | unsigned int count; |
| 431 | (mhba->ib_cur_slot & CL_POINTER_TOGGLE)))) { | 456 | if (atomic_read(&mhba->fw_outstanding) >= (mhba->max_io - 1)) |
| 432 | dev_warn(&mhba->pdev->dev, "no free slot to use.\n"); | 457 | return 0; |
| 433 | return -1; | 458 | count = ioread32(mhba->ib_shadow); |
| 434 | } | 459 | if (count == 0xffff) |
| 460 | return 0; | ||
| 461 | return count; | ||
| 462 | } | ||
| 463 | |||
| 464 | static void mvumi_get_ib_list_entry(struct mvumi_hba *mhba, void **ib_entry) | ||
| 465 | { | ||
| 466 | unsigned int cur_ib_entry; | ||
| 435 | 467 | ||
| 436 | cur_ib_entry = mhba->ib_cur_slot & CL_SLOT_NUM_MASK; | 468 | cur_ib_entry = mhba->ib_cur_slot & mhba->regs->cl_slot_num_mask; |
| 437 | cur_ib_entry++; | 469 | cur_ib_entry++; |
| 438 | if (cur_ib_entry >= mhba->list_num_io) { | 470 | if (cur_ib_entry >= mhba->list_num_io) { |
| 439 | cur_ib_entry -= mhba->list_num_io; | 471 | cur_ib_entry -= mhba->list_num_io; |
| 440 | mhba->ib_cur_slot ^= CL_POINTER_TOGGLE; | 472 | mhba->ib_cur_slot ^= mhba->regs->cl_pointer_toggle; |
| 473 | } | ||
| 474 | mhba->ib_cur_slot &= ~mhba->regs->cl_slot_num_mask; | ||
| 475 | mhba->ib_cur_slot |= (cur_ib_entry & mhba->regs->cl_slot_num_mask); | ||
| 476 | if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) { | ||
| 477 | *ib_entry = mhba->ib_list + cur_ib_entry * | ||
| 478 | sizeof(struct mvumi_dyn_list_entry); | ||
| 479 | } else { | ||
| 480 | *ib_entry = mhba->ib_list + cur_ib_entry * mhba->ib_max_size; | ||
| 441 | } | 481 | } |
| 442 | mhba->ib_cur_slot &= ~CL_SLOT_NUM_MASK; | ||
| 443 | mhba->ib_cur_slot |= (cur_ib_entry & CL_SLOT_NUM_MASK); | ||
| 444 | *ib_entry = mhba->ib_list + cur_ib_entry * mhba->ib_max_size; | ||
| 445 | atomic_inc(&mhba->fw_outstanding); | 482 | atomic_inc(&mhba->fw_outstanding); |
| 446 | |||
| 447 | return 0; | ||
| 448 | } | 483 | } |
| 449 | 484 | ||
| 450 | static void mvumi_send_ib_list_entry(struct mvumi_hba *mhba) | 485 | static void mvumi_send_ib_list_entry(struct mvumi_hba *mhba) |
| 451 | { | 486 | { |
| 452 | iowrite32(0xfff, mhba->ib_shadow); | 487 | iowrite32(0xffff, mhba->ib_shadow); |
| 453 | iowrite32(mhba->ib_cur_slot, mhba->mmio + CLA_INB_WRITE_POINTER); | 488 | iowrite32(mhba->ib_cur_slot, mhba->regs->inb_write_pointer); |
| 454 | } | 489 | } |
| 455 | 490 | ||
| 456 | static char mvumi_check_ob_frame(struct mvumi_hba *mhba, | 491 | static char mvumi_check_ob_frame(struct mvumi_hba *mhba, |
| @@ -480,31 +515,59 @@ static char mvumi_check_ob_frame(struct mvumi_hba *mhba, | |||
| 480 | return 0; | 515 | return 0; |
| 481 | } | 516 | } |
| 482 | 517 | ||
| 483 | static void mvumi_receive_ob_list_entry(struct mvumi_hba *mhba) | 518 | static int mvumi_check_ob_list_9143(struct mvumi_hba *mhba, |
| 519 | unsigned int *cur_obf, unsigned int *assign_obf_end) | ||
| 484 | { | 520 | { |
| 485 | unsigned int ob_write_reg, ob_write_shadow_reg; | 521 | unsigned int ob_write, ob_write_shadow; |
| 486 | unsigned int cur_obf, assign_obf_end, i; | 522 | struct mvumi_hw_regs *regs = mhba->regs; |
| 487 | struct mvumi_ob_data *ob_data; | ||
| 488 | struct mvumi_rsp_frame *p_outb_frame; | ||
| 489 | 523 | ||
| 490 | do { | 524 | do { |
| 491 | ob_write_reg = ioread32(mhba->mmio + CLA_OUTB_COPY_POINTER); | 525 | ob_write = ioread32(regs->outb_copy_pointer); |
| 492 | ob_write_shadow_reg = ioread32(mhba->ob_shadow); | 526 | ob_write_shadow = ioread32(mhba->ob_shadow); |
| 493 | } while ((ob_write_reg & CL_SLOT_NUM_MASK) != ob_write_shadow_reg); | 527 | } while ((ob_write & regs->cl_slot_num_mask) != ob_write_shadow); |
| 494 | 528 | ||
| 495 | cur_obf = mhba->ob_cur_slot & CL_SLOT_NUM_MASK; | 529 | *cur_obf = mhba->ob_cur_slot & mhba->regs->cl_slot_num_mask; |
| 496 | assign_obf_end = ob_write_reg & CL_SLOT_NUM_MASK; | 530 | *assign_obf_end = ob_write & mhba->regs->cl_slot_num_mask; |
| 497 | 531 | ||
| 498 | if ((ob_write_reg & CL_POINTER_TOGGLE) != | 532 | if ((ob_write & regs->cl_pointer_toggle) != |
| 499 | (mhba->ob_cur_slot & CL_POINTER_TOGGLE)) { | 533 | (mhba->ob_cur_slot & regs->cl_pointer_toggle)) { |
| 500 | assign_obf_end += mhba->list_num_io; | 534 | *assign_obf_end += mhba->list_num_io; |
| 501 | } | 535 | } |
| 536 | return 0; | ||
| 537 | } | ||
| 538 | |||
| 539 | static int mvumi_check_ob_list_9580(struct mvumi_hba *mhba, | ||
| 540 | unsigned int *cur_obf, unsigned int *assign_obf_end) | ||
| 541 | { | ||
| 542 | unsigned int ob_write; | ||
| 543 | struct mvumi_hw_regs *regs = mhba->regs; | ||
| 544 | |||
| 545 | ob_write = ioread32(regs->outb_read_pointer); | ||
| 546 | ob_write = ioread32(regs->outb_copy_pointer); | ||
| 547 | *cur_obf = mhba->ob_cur_slot & mhba->regs->cl_slot_num_mask; | ||
| 548 | *assign_obf_end = ob_write & mhba->regs->cl_slot_num_mask; | ||
| 549 | if (*assign_obf_end < *cur_obf) | ||
| 550 | *assign_obf_end += mhba->list_num_io; | ||
| 551 | else if (*assign_obf_end == *cur_obf) | ||
| 552 | return -1; | ||
| 553 | return 0; | ||
| 554 | } | ||
| 555 | |||
| 556 | static void mvumi_receive_ob_list_entry(struct mvumi_hba *mhba) | ||
| 557 | { | ||
| 558 | unsigned int cur_obf, assign_obf_end, i; | ||
| 559 | struct mvumi_ob_data *ob_data; | ||
| 560 | struct mvumi_rsp_frame *p_outb_frame; | ||
| 561 | struct mvumi_hw_regs *regs = mhba->regs; | ||
| 562 | |||
| 563 | if (mhba->instancet->check_ob_list(mhba, &cur_obf, &assign_obf_end)) | ||
| 564 | return; | ||
| 502 | 565 | ||
| 503 | for (i = (assign_obf_end - cur_obf); i != 0; i--) { | 566 | for (i = (assign_obf_end - cur_obf); i != 0; i--) { |
| 504 | cur_obf++; | 567 | cur_obf++; |
| 505 | if (cur_obf >= mhba->list_num_io) { | 568 | if (cur_obf >= mhba->list_num_io) { |
| 506 | cur_obf -= mhba->list_num_io; | 569 | cur_obf -= mhba->list_num_io; |
| 507 | mhba->ob_cur_slot ^= CL_POINTER_TOGGLE; | 570 | mhba->ob_cur_slot ^= regs->cl_pointer_toggle; |
| 508 | } | 571 | } |
| 509 | 572 | ||
| 510 | p_outb_frame = mhba->ob_list + cur_obf * mhba->ob_max_size; | 573 | p_outb_frame = mhba->ob_list + cur_obf * mhba->ob_max_size; |
| @@ -528,7 +591,7 @@ static void mvumi_receive_ob_list_entry(struct mvumi_hba *mhba) | |||
| 528 | ob_data = NULL; | 591 | ob_data = NULL; |
| 529 | if (cur_obf == 0) { | 592 | if (cur_obf == 0) { |
| 530 | cur_obf = mhba->list_num_io - 1; | 593 | cur_obf = mhba->list_num_io - 1; |
| 531 | mhba->ob_cur_slot ^= CL_POINTER_TOGGLE; | 594 | mhba->ob_cur_slot ^= regs->cl_pointer_toggle; |
| 532 | } else | 595 | } else |
| 533 | cur_obf -= 1; | 596 | cur_obf -= 1; |
| 534 | break; | 597 | break; |
| @@ -539,18 +602,20 @@ static void mvumi_receive_ob_list_entry(struct mvumi_hba *mhba) | |||
| 539 | 602 | ||
| 540 | list_add_tail(&ob_data->list, &mhba->free_ob_list); | 603 | list_add_tail(&ob_data->list, &mhba->free_ob_list); |
| 541 | } | 604 | } |
| 542 | mhba->ob_cur_slot &= ~CL_SLOT_NUM_MASK; | 605 | mhba->ob_cur_slot &= ~regs->cl_slot_num_mask; |
| 543 | mhba->ob_cur_slot |= (cur_obf & CL_SLOT_NUM_MASK); | 606 | mhba->ob_cur_slot |= (cur_obf & regs->cl_slot_num_mask); |
| 544 | iowrite32(mhba->ob_cur_slot, mhba->mmio + CLA_OUTB_READ_POINTER); | 607 | iowrite32(mhba->ob_cur_slot, regs->outb_read_pointer); |
| 545 | } | 608 | } |
| 546 | 609 | ||
| 547 | static void mvumi_reset(void *regs) | 610 | static void mvumi_reset(struct mvumi_hba *mhba) |
| 548 | { | 611 | { |
| 549 | iowrite32(0, regs + CPU_ENPOINTA_MASK_REG); | 612 | struct mvumi_hw_regs *regs = mhba->regs; |
| 550 | if (ioread32(regs + CPU_ARM_TO_PCIEA_MSG1) != HANDSHAKE_DONESTATE) | 613 | |
| 614 | iowrite32(0, regs->enpointa_mask_reg); | ||
| 615 | if (ioread32(regs->arm_to_pciea_msg1) != HANDSHAKE_DONESTATE) | ||
| 551 | return; | 616 | return; |
| 552 | 617 | ||
| 553 | iowrite32(DRBL_SOFT_RESET, regs + CPU_PCIEA_TO_ARM_DRBL_REG); | 618 | iowrite32(DRBL_SOFT_RESET, regs->pciea_to_arm_drbl_reg); |
| 554 | } | 619 | } |
| 555 | 620 | ||
| 556 | static unsigned char mvumi_start(struct mvumi_hba *mhba); | 621 | static unsigned char mvumi_start(struct mvumi_hba *mhba); |
| @@ -558,7 +623,7 @@ static unsigned char mvumi_start(struct mvumi_hba *mhba); | |||
| 558 | static int mvumi_wait_for_outstanding(struct mvumi_hba *mhba) | 623 | static int mvumi_wait_for_outstanding(struct mvumi_hba *mhba) |
| 559 | { | 624 | { |
| 560 | mhba->fw_state = FW_STATE_ABORT; | 625 | mhba->fw_state = FW_STATE_ABORT; |
| 561 | mvumi_reset(mhba->mmio); | 626 | mvumi_reset(mhba); |
| 562 | 627 | ||
| 563 | if (mvumi_start(mhba)) | 628 | if (mvumi_start(mhba)) |
| 564 | return FAILED; | 629 | return FAILED; |
| @@ -566,6 +631,98 @@ static int mvumi_wait_for_outstanding(struct mvumi_hba *mhba) | |||
| 566 | return SUCCESS; | 631 | return SUCCESS; |
| 567 | } | 632 | } |
| 568 | 633 | ||
| 634 | static int mvumi_wait_for_fw(struct mvumi_hba *mhba) | ||
| 635 | { | ||
| 636 | struct mvumi_hw_regs *regs = mhba->regs; | ||
| 637 | u32 tmp; | ||
| 638 | unsigned long before; | ||
| 639 | before = jiffies; | ||
| 640 | |||
| 641 | iowrite32(0, regs->enpointa_mask_reg); | ||
| 642 | tmp = ioread32(regs->arm_to_pciea_msg1); | ||
| 643 | while (tmp != HANDSHAKE_READYSTATE) { | ||
| 644 | iowrite32(DRBL_MU_RESET, regs->pciea_to_arm_drbl_reg); | ||
| 645 | if (time_after(jiffies, before + FW_MAX_DELAY * HZ)) { | ||
| 646 | dev_err(&mhba->pdev->dev, | ||
| 647 | "FW reset failed [0x%x].\n", tmp); | ||
| 648 | return FAILED; | ||
| 649 | } | ||
| 650 | |||
| 651 | msleep(500); | ||
| 652 | rmb(); | ||
| 653 | tmp = ioread32(regs->arm_to_pciea_msg1); | ||
| 654 | } | ||
| 655 | |||
| 656 | return SUCCESS; | ||
| 657 | } | ||
| 658 | |||
| 659 | static void mvumi_backup_bar_addr(struct mvumi_hba *mhba) | ||
| 660 | { | ||
| 661 | unsigned char i; | ||
| 662 | |||
| 663 | for (i = 0; i < MAX_BASE_ADDRESS; i++) { | ||
| 664 | pci_read_config_dword(mhba->pdev, 0x10 + i * 4, | ||
| 665 | &mhba->pci_base[i]); | ||
| 666 | } | ||
| 667 | } | ||
| 668 | |||
| 669 | static void mvumi_restore_bar_addr(struct mvumi_hba *mhba) | ||
| 670 | { | ||
| 671 | unsigned char i; | ||
| 672 | |||
| 673 | for (i = 0; i < MAX_BASE_ADDRESS; i++) { | ||
| 674 | if (mhba->pci_base[i]) | ||
| 675 | pci_write_config_dword(mhba->pdev, 0x10 + i * 4, | ||
| 676 | mhba->pci_base[i]); | ||
| 677 | } | ||
| 678 | } | ||
| 679 | |||
| 680 | static unsigned int mvumi_pci_set_master(struct pci_dev *pdev) | ||
| 681 | { | ||
| 682 | unsigned int ret = 0; | ||
| 683 | pci_set_master(pdev); | ||
| 684 | |||
| 685 | if (IS_DMA64) { | ||
| 686 | if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) | ||
| 687 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
| 688 | } else | ||
| 689 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
| 690 | |||
| 691 | return ret; | ||
| 692 | } | ||
| 693 | |||
| 694 | static int mvumi_reset_host_9580(struct mvumi_hba *mhba) | ||
| 695 | { | ||
| 696 | mhba->fw_state = FW_STATE_ABORT; | ||
| 697 | |||
| 698 | iowrite32(0, mhba->regs->reset_enable); | ||
| 699 | iowrite32(0xf, mhba->regs->reset_request); | ||
| 700 | |||
| 701 | iowrite32(0x10, mhba->regs->reset_enable); | ||
| 702 | iowrite32(0x10, mhba->regs->reset_request); | ||
| 703 | msleep(100); | ||
| 704 | pci_disable_device(mhba->pdev); | ||
| 705 | |||
| 706 | if (pci_enable_device(mhba->pdev)) { | ||
| 707 | dev_err(&mhba->pdev->dev, "enable device failed\n"); | ||
| 708 | return FAILED; | ||
| 709 | } | ||
| 710 | if (mvumi_pci_set_master(mhba->pdev)) { | ||
| 711 | dev_err(&mhba->pdev->dev, "set master failed\n"); | ||
| 712 | return FAILED; | ||
| 713 | } | ||
| 714 | mvumi_restore_bar_addr(mhba); | ||
| 715 | if (mvumi_wait_for_fw(mhba) == FAILED) | ||
| 716 | return FAILED; | ||
| 717 | |||
| 718 | return mvumi_wait_for_outstanding(mhba); | ||
| 719 | } | ||
| 720 | |||
| 721 | static int mvumi_reset_host_9143(struct mvumi_hba *mhba) | ||
| 722 | { | ||
| 723 | return mvumi_wait_for_outstanding(mhba); | ||
| 724 | } | ||
| 725 | |||
| 569 | static int mvumi_host_reset(struct scsi_cmnd *scmd) | 726 | static int mvumi_host_reset(struct scsi_cmnd *scmd) |
| 570 | { | 727 | { |
| 571 | struct mvumi_hba *mhba; | 728 | struct mvumi_hba *mhba; |
| @@ -575,7 +732,7 @@ static int mvumi_host_reset(struct scsi_cmnd *scmd) | |||
| 575 | scmd_printk(KERN_NOTICE, scmd, "RESET -%ld cmd=%x retries=%x\n", | 732 | scmd_printk(KERN_NOTICE, scmd, "RESET -%ld cmd=%x retries=%x\n", |
| 576 | scmd->serial_number, scmd->cmnd[0], scmd->retries); | 733 | scmd->serial_number, scmd->cmnd[0], scmd->retries); |
| 577 | 734 | ||
| 578 | return mvumi_wait_for_outstanding(mhba); | 735 | return mhba->instancet->reset_host(mhba); |
| 579 | } | 736 | } |
| 580 | 737 | ||
| 581 | static int mvumi_issue_blocked_cmd(struct mvumi_hba *mhba, | 738 | static int mvumi_issue_blocked_cmd(struct mvumi_hba *mhba, |
| @@ -628,7 +785,9 @@ static void mvumi_release_fw(struct mvumi_hba *mhba) | |||
| 628 | mvumi_free_cmds(mhba); | 785 | mvumi_free_cmds(mhba); |
| 629 | mvumi_release_mem_resource(mhba); | 786 | mvumi_release_mem_resource(mhba); |
| 630 | mvumi_unmap_pci_addr(mhba->pdev, mhba->base_addr); | 787 | mvumi_unmap_pci_addr(mhba->pdev, mhba->base_addr); |
| 631 | kfree(mhba->handshake_page); | 788 | pci_free_consistent(mhba->pdev, HSP_MAX_SIZE, |
| 789 | mhba->handshake_page, mhba->handshake_page_phys); | ||
| 790 | kfree(mhba->regs); | ||
| 632 | pci_release_regions(mhba->pdev); | 791 | pci_release_regions(mhba->pdev); |
| 633 | } | 792 | } |
| 634 | 793 | ||
| @@ -665,6 +824,7 @@ get_cmd: cmd = mvumi_create_internal_cmd(mhba, 0); | |||
| 665 | frame->cdb_length = MAX_COMMAND_SIZE; | 824 | frame->cdb_length = MAX_COMMAND_SIZE; |
| 666 | memset(frame->cdb, 0, MAX_COMMAND_SIZE); | 825 | memset(frame->cdb, 0, MAX_COMMAND_SIZE); |
| 667 | frame->cdb[0] = SCSI_CMD_MARVELL_SPECIFIC; | 826 | frame->cdb[0] = SCSI_CMD_MARVELL_SPECIFIC; |
| 827 | frame->cdb[1] = CDB_CORE_MODULE; | ||
| 668 | frame->cdb[2] = CDB_CORE_SHUTDOWN; | 828 | frame->cdb[2] = CDB_CORE_SHUTDOWN; |
| 669 | 829 | ||
| 670 | mvumi_issue_blocked_cmd(mhba, cmd); | 830 | mvumi_issue_blocked_cmd(mhba, cmd); |
| @@ -695,7 +855,7 @@ mvumi_calculate_checksum(struct mvumi_hs_header *p_header, | |||
| 695 | return ret; | 855 | return ret; |
| 696 | } | 856 | } |
| 697 | 857 | ||
| 698 | void mvumi_hs_build_page(struct mvumi_hba *mhba, | 858 | static void mvumi_hs_build_page(struct mvumi_hba *mhba, |
| 699 | struct mvumi_hs_header *hs_header) | 859 | struct mvumi_hs_header *hs_header) |
| 700 | { | 860 | { |
| 701 | struct mvumi_hs_page2 *hs_page2; | 861 | struct mvumi_hs_page2 *hs_page2; |
| @@ -710,6 +870,8 @@ void mvumi_hs_build_page(struct mvumi_hba *mhba, | |||
| 710 | hs_header->frame_length = sizeof(*hs_page2) - 4; | 870 | hs_header->frame_length = sizeof(*hs_page2) - 4; |
| 711 | memset(hs_header->frame_content, 0, hs_header->frame_length); | 871 | memset(hs_header->frame_content, 0, hs_header->frame_length); |
| 712 | hs_page2->host_type = 3; /* 3 mean linux*/ | 872 | hs_page2->host_type = 3; /* 3 mean linux*/ |
| 873 | if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) | ||
| 874 | hs_page2->host_cap = 0x08;/* host dynamic source mode */ | ||
| 713 | hs_page2->host_ver.ver_major = VER_MAJOR; | 875 | hs_page2->host_ver.ver_major = VER_MAJOR; |
| 714 | hs_page2->host_ver.ver_minor = VER_MINOR; | 876 | hs_page2->host_ver.ver_minor = VER_MINOR; |
| 715 | hs_page2->host_ver.ver_oem = VER_OEM; | 877 | hs_page2->host_ver.ver_oem = VER_OEM; |
| @@ -745,8 +907,18 @@ void mvumi_hs_build_page(struct mvumi_hba *mhba, | |||
| 745 | hs_page4->ob_baseaddr_h = upper_32_bits(mhba->ob_list_phys); | 907 | hs_page4->ob_baseaddr_h = upper_32_bits(mhba->ob_list_phys); |
| 746 | hs_page4->ib_entry_size = mhba->ib_max_size_setting; | 908 | hs_page4->ib_entry_size = mhba->ib_max_size_setting; |
| 747 | hs_page4->ob_entry_size = mhba->ob_max_size_setting; | 909 | hs_page4->ob_entry_size = mhba->ob_max_size_setting; |
| 748 | hs_page4->ob_depth = mhba->list_num_io; | 910 | if (mhba->hba_capability |
| 749 | hs_page4->ib_depth = mhba->list_num_io; | 911 | & HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF) { |
| 912 | hs_page4->ob_depth = find_first_bit((unsigned long *) | ||
| 913 | &mhba->list_num_io, | ||
| 914 | BITS_PER_LONG); | ||
| 915 | hs_page4->ib_depth = find_first_bit((unsigned long *) | ||
| 916 | &mhba->list_num_io, | ||
| 917 | BITS_PER_LONG); | ||
| 918 | } else { | ||
| 919 | hs_page4->ob_depth = (u8) mhba->list_num_io; | ||
| 920 | hs_page4->ib_depth = (u8) mhba->list_num_io; | ||
| 921 | } | ||
| 750 | hs_header->checksum = mvumi_calculate_checksum(hs_header, | 922 | hs_header->checksum = mvumi_calculate_checksum(hs_header, |
| 751 | hs_header->frame_length); | 923 | hs_header->frame_length); |
| 752 | break; | 924 | break; |
| @@ -774,8 +946,11 @@ static int mvumi_init_data(struct mvumi_hba *mhba) | |||
| 774 | return 0; | 946 | return 0; |
| 775 | 947 | ||
| 776 | tmp_size = mhba->ib_max_size * mhba->max_io; | 948 | tmp_size = mhba->ib_max_size * mhba->max_io; |
| 949 | if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) | ||
| 950 | tmp_size += sizeof(struct mvumi_dyn_list_entry) * mhba->max_io; | ||
| 951 | |||
| 777 | tmp_size += 128 + mhba->ob_max_size * mhba->max_io; | 952 | tmp_size += 128 + mhba->ob_max_size * mhba->max_io; |
| 778 | tmp_size += 8 + sizeof(u32) + 16; | 953 | tmp_size += 8 + sizeof(u32)*2 + 16; |
| 779 | 954 | ||
| 780 | res_mgnt = mvumi_alloc_mem_resource(mhba, | 955 | res_mgnt = mvumi_alloc_mem_resource(mhba, |
| 781 | RESOURCE_UNCACHED_MEMORY, tmp_size); | 956 | RESOURCE_UNCACHED_MEMORY, tmp_size); |
| @@ -793,24 +968,41 @@ static int mvumi_init_data(struct mvumi_hba *mhba) | |||
| 793 | v += offset; | 968 | v += offset; |
| 794 | mhba->ib_list = v; | 969 | mhba->ib_list = v; |
| 795 | mhba->ib_list_phys = p; | 970 | mhba->ib_list_phys = p; |
| 971 | if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) { | ||
| 972 | v += sizeof(struct mvumi_dyn_list_entry) * mhba->max_io; | ||
| 973 | p += sizeof(struct mvumi_dyn_list_entry) * mhba->max_io; | ||
| 974 | mhba->ib_frame = v; | ||
| 975 | mhba->ib_frame_phys = p; | ||
| 976 | } | ||
| 796 | v += mhba->ib_max_size * mhba->max_io; | 977 | v += mhba->ib_max_size * mhba->max_io; |
| 797 | p += mhba->ib_max_size * mhba->max_io; | 978 | p += mhba->ib_max_size * mhba->max_io; |
| 979 | |||
| 798 | /* ib shadow */ | 980 | /* ib shadow */ |
| 799 | offset = round_up(p, 8) - p; | 981 | offset = round_up(p, 8) - p; |
| 800 | p += offset; | 982 | p += offset; |
| 801 | v += offset; | 983 | v += offset; |
| 802 | mhba->ib_shadow = v; | 984 | mhba->ib_shadow = v; |
| 803 | mhba->ib_shadow_phys = p; | 985 | mhba->ib_shadow_phys = p; |
| 804 | p += sizeof(u32); | 986 | p += sizeof(u32)*2; |
| 805 | v += sizeof(u32); | 987 | v += sizeof(u32)*2; |
| 806 | /* ob shadow */ | 988 | /* ob shadow */ |
| 807 | offset = round_up(p, 8) - p; | 989 | if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580) { |
| 808 | p += offset; | 990 | offset = round_up(p, 8) - p; |
| 809 | v += offset; | 991 | p += offset; |
| 810 | mhba->ob_shadow = v; | 992 | v += offset; |
| 811 | mhba->ob_shadow_phys = p; | 993 | mhba->ob_shadow = v; |
| 812 | p += 8; | 994 | mhba->ob_shadow_phys = p; |
| 813 | v += 8; | 995 | p += 8; |
| 996 | v += 8; | ||
| 997 | } else { | ||
| 998 | offset = round_up(p, 4) - p; | ||
| 999 | p += offset; | ||
| 1000 | v += offset; | ||
| 1001 | mhba->ob_shadow = v; | ||
| 1002 | mhba->ob_shadow_phys = p; | ||
| 1003 | p += 4; | ||
| 1004 | v += 4; | ||
| 1005 | } | ||
| 814 | 1006 | ||
| 815 | /* ob list */ | 1007 | /* ob list */ |
| 816 | offset = round_up(p, 128) - p; | 1008 | offset = round_up(p, 128) - p; |
| @@ -902,6 +1094,12 @@ static int mvumi_hs_process_page(struct mvumi_hba *mhba, | |||
| 902 | dev_dbg(&mhba->pdev->dev, "FW version:%d\n", | 1094 | dev_dbg(&mhba->pdev->dev, "FW version:%d\n", |
| 903 | hs_page1->fw_ver.ver_build); | 1095 | hs_page1->fw_ver.ver_build); |
| 904 | 1096 | ||
| 1097 | if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) | ||
| 1098 | mhba->eot_flag = 22; | ||
| 1099 | else | ||
| 1100 | mhba->eot_flag = 27; | ||
| 1101 | if (mhba->hba_capability & HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF) | ||
| 1102 | mhba->list_num_io = 1 << hs_page1->cl_inout_list_depth; | ||
| 905 | break; | 1103 | break; |
| 906 | default: | 1104 | default: |
| 907 | dev_err(&mhba->pdev->dev, "handshake: page code error\n"); | 1105 | dev_err(&mhba->pdev->dev, "handshake: page code error\n"); |
| @@ -923,12 +1121,12 @@ static int mvumi_handshake(struct mvumi_hba *mhba) | |||
| 923 | { | 1121 | { |
| 924 | unsigned int hs_state, tmp, hs_fun; | 1122 | unsigned int hs_state, tmp, hs_fun; |
| 925 | struct mvumi_hs_header *hs_header; | 1123 | struct mvumi_hs_header *hs_header; |
| 926 | void *regs = mhba->mmio; | 1124 | struct mvumi_hw_regs *regs = mhba->regs; |
| 927 | 1125 | ||
| 928 | if (mhba->fw_state == FW_STATE_STARTING) | 1126 | if (mhba->fw_state == FW_STATE_STARTING) |
| 929 | hs_state = HS_S_START; | 1127 | hs_state = HS_S_START; |
| 930 | else { | 1128 | else { |
| 931 | tmp = ioread32(regs + CPU_ARM_TO_PCIEA_MSG0); | 1129 | tmp = ioread32(regs->arm_to_pciea_msg0); |
| 932 | hs_state = HS_GET_STATE(tmp); | 1130 | hs_state = HS_GET_STATE(tmp); |
| 933 | dev_dbg(&mhba->pdev->dev, "handshake state[0x%x].\n", hs_state); | 1131 | dev_dbg(&mhba->pdev->dev, "handshake state[0x%x].\n", hs_state); |
| 934 | if (HS_GET_STATUS(tmp) != HS_STATUS_OK) { | 1132 | if (HS_GET_STATUS(tmp) != HS_STATUS_OK) { |
| @@ -943,21 +1141,20 @@ static int mvumi_handshake(struct mvumi_hba *mhba) | |||
| 943 | mhba->fw_state = FW_STATE_HANDSHAKING; | 1141 | mhba->fw_state = FW_STATE_HANDSHAKING; |
| 944 | HS_SET_STATUS(hs_fun, HS_STATUS_OK); | 1142 | HS_SET_STATUS(hs_fun, HS_STATUS_OK); |
| 945 | HS_SET_STATE(hs_fun, HS_S_RESET); | 1143 | HS_SET_STATE(hs_fun, HS_S_RESET); |
| 946 | iowrite32(HANDSHAKE_SIGNATURE, regs + CPU_PCIEA_TO_ARM_MSG1); | 1144 | iowrite32(HANDSHAKE_SIGNATURE, regs->pciea_to_arm_msg1); |
| 947 | iowrite32(hs_fun, regs + CPU_PCIEA_TO_ARM_MSG0); | 1145 | iowrite32(hs_fun, regs->pciea_to_arm_msg0); |
| 948 | iowrite32(DRBL_HANDSHAKE, regs + CPU_PCIEA_TO_ARM_DRBL_REG); | 1146 | iowrite32(DRBL_HANDSHAKE, regs->pciea_to_arm_drbl_reg); |
| 949 | break; | 1147 | break; |
| 950 | 1148 | ||
| 951 | case HS_S_RESET: | 1149 | case HS_S_RESET: |
| 952 | iowrite32(lower_32_bits(mhba->handshake_page_phys), | 1150 | iowrite32(lower_32_bits(mhba->handshake_page_phys), |
| 953 | regs + CPU_PCIEA_TO_ARM_MSG1); | 1151 | regs->pciea_to_arm_msg1); |
| 954 | iowrite32(upper_32_bits(mhba->handshake_page_phys), | 1152 | iowrite32(upper_32_bits(mhba->handshake_page_phys), |
| 955 | regs + CPU_ARM_TO_PCIEA_MSG1); | 1153 | regs->arm_to_pciea_msg1); |
| 956 | HS_SET_STATUS(hs_fun, HS_STATUS_OK); | 1154 | HS_SET_STATUS(hs_fun, HS_STATUS_OK); |
| 957 | HS_SET_STATE(hs_fun, HS_S_PAGE_ADDR); | 1155 | HS_SET_STATE(hs_fun, HS_S_PAGE_ADDR); |
| 958 | iowrite32(hs_fun, regs + CPU_PCIEA_TO_ARM_MSG0); | 1156 | iowrite32(hs_fun, regs->pciea_to_arm_msg0); |
| 959 | iowrite32(DRBL_HANDSHAKE, regs + CPU_PCIEA_TO_ARM_DRBL_REG); | 1157 | iowrite32(DRBL_HANDSHAKE, regs->pciea_to_arm_drbl_reg); |
| 960 | |||
| 961 | break; | 1158 | break; |
| 962 | 1159 | ||
| 963 | case HS_S_PAGE_ADDR: | 1160 | case HS_S_PAGE_ADDR: |
| @@ -997,30 +1194,37 @@ static int mvumi_handshake(struct mvumi_hba *mhba) | |||
| 997 | HS_SET_STATE(hs_fun, HS_S_END); | 1194 | HS_SET_STATE(hs_fun, HS_S_END); |
| 998 | 1195 | ||
| 999 | HS_SET_STATUS(hs_fun, HS_STATUS_OK); | 1196 | HS_SET_STATUS(hs_fun, HS_STATUS_OK); |
| 1000 | iowrite32(hs_fun, regs + CPU_PCIEA_TO_ARM_MSG0); | 1197 | iowrite32(hs_fun, regs->pciea_to_arm_msg0); |
| 1001 | iowrite32(DRBL_HANDSHAKE, regs + CPU_PCIEA_TO_ARM_DRBL_REG); | 1198 | iowrite32(DRBL_HANDSHAKE, regs->pciea_to_arm_drbl_reg); |
| 1002 | break; | 1199 | break; |
| 1003 | 1200 | ||
| 1004 | case HS_S_END: | 1201 | case HS_S_END: |
| 1005 | /* Set communication list ISR */ | 1202 | /* Set communication list ISR */ |
| 1006 | tmp = ioread32(regs + CPU_ENPOINTA_MASK_REG); | 1203 | tmp = ioread32(regs->enpointa_mask_reg); |
| 1007 | tmp |= INT_MAP_COMAOUT | INT_MAP_COMAERR; | 1204 | tmp |= regs->int_comaout | regs->int_comaerr; |
| 1008 | iowrite32(tmp, regs + CPU_ENPOINTA_MASK_REG); | 1205 | iowrite32(tmp, regs->enpointa_mask_reg); |
| 1009 | iowrite32(mhba->list_num_io, mhba->ib_shadow); | 1206 | iowrite32(mhba->list_num_io, mhba->ib_shadow); |
| 1010 | /* Set InBound List Available count shadow */ | 1207 | /* Set InBound List Available count shadow */ |
| 1011 | iowrite32(lower_32_bits(mhba->ib_shadow_phys), | 1208 | iowrite32(lower_32_bits(mhba->ib_shadow_phys), |
| 1012 | regs + CLA_INB_AVAL_COUNT_BASEL); | 1209 | regs->inb_aval_count_basel); |
| 1013 | iowrite32(upper_32_bits(mhba->ib_shadow_phys), | 1210 | iowrite32(upper_32_bits(mhba->ib_shadow_phys), |
| 1014 | regs + CLA_INB_AVAL_COUNT_BASEH); | 1211 | regs->inb_aval_count_baseh); |
| 1015 | 1212 | ||
| 1016 | /* Set OutBound List Available count shadow */ | 1213 | if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9143) { |
| 1017 | iowrite32((mhba->list_num_io-1) | CL_POINTER_TOGGLE, | 1214 | /* Set OutBound List Available count shadow */ |
| 1018 | mhba->ob_shadow); | 1215 | iowrite32((mhba->list_num_io-1) | |
| 1019 | iowrite32(lower_32_bits(mhba->ob_shadow_phys), regs + 0x5B0); | 1216 | regs->cl_pointer_toggle, |
| 1020 | iowrite32(upper_32_bits(mhba->ob_shadow_phys), regs + 0x5B4); | 1217 | mhba->ob_shadow); |
| 1218 | iowrite32(lower_32_bits(mhba->ob_shadow_phys), | ||
| 1219 | regs->outb_copy_basel); | ||
| 1220 | iowrite32(upper_32_bits(mhba->ob_shadow_phys), | ||
| 1221 | regs->outb_copy_baseh); | ||
| 1222 | } | ||
| 1021 | 1223 | ||
| 1022 | mhba->ib_cur_slot = (mhba->list_num_io - 1) | CL_POINTER_TOGGLE; | 1224 | mhba->ib_cur_slot = (mhba->list_num_io - 1) | |
| 1023 | mhba->ob_cur_slot = (mhba->list_num_io - 1) | CL_POINTER_TOGGLE; | 1225 | regs->cl_pointer_toggle; |
| 1226 | mhba->ob_cur_slot = (mhba->list_num_io - 1) | | ||
| 1227 | regs->cl_pointer_toggle; | ||
| 1024 | mhba->fw_state = FW_STATE_STARTED; | 1228 | mhba->fw_state = FW_STATE_STARTED; |
| 1025 | 1229 | ||
| 1026 | break; | 1230 | break; |
| @@ -1040,7 +1244,7 @@ static unsigned char mvumi_handshake_event(struct mvumi_hba *mhba) | |||
| 1040 | before = jiffies; | 1244 | before = jiffies; |
| 1041 | mvumi_handshake(mhba); | 1245 | mvumi_handshake(mhba); |
| 1042 | do { | 1246 | do { |
| 1043 | isr_status = mhba->instancet->read_fw_status_reg(mhba->mmio); | 1247 | isr_status = mhba->instancet->read_fw_status_reg(mhba); |
| 1044 | 1248 | ||
| 1045 | if (mhba->fw_state == FW_STATE_STARTED) | 1249 | if (mhba->fw_state == FW_STATE_STARTED) |
| 1046 | return 0; | 1250 | return 0; |
| @@ -1062,16 +1266,15 @@ static unsigned char mvumi_handshake_event(struct mvumi_hba *mhba) | |||
| 1062 | 1266 | ||
| 1063 | static unsigned char mvumi_check_handshake(struct mvumi_hba *mhba) | 1267 | static unsigned char mvumi_check_handshake(struct mvumi_hba *mhba) |
| 1064 | { | 1268 | { |
| 1065 | void *regs = mhba->mmio; | ||
| 1066 | unsigned int tmp; | 1269 | unsigned int tmp; |
| 1067 | unsigned long before; | 1270 | unsigned long before; |
| 1068 | 1271 | ||
| 1069 | before = jiffies; | 1272 | before = jiffies; |
| 1070 | tmp = ioread32(regs + CPU_ARM_TO_PCIEA_MSG1); | 1273 | tmp = ioread32(mhba->regs->arm_to_pciea_msg1); |
| 1071 | while ((tmp != HANDSHAKE_READYSTATE) && (tmp != HANDSHAKE_DONESTATE)) { | 1274 | while ((tmp != HANDSHAKE_READYSTATE) && (tmp != HANDSHAKE_DONESTATE)) { |
| 1072 | if (tmp != HANDSHAKE_READYSTATE) | 1275 | if (tmp != HANDSHAKE_READYSTATE) |
| 1073 | iowrite32(DRBL_MU_RESET, | 1276 | iowrite32(DRBL_MU_RESET, |
| 1074 | regs + CPU_PCIEA_TO_ARM_DRBL_REG); | 1277 | mhba->regs->pciea_to_arm_drbl_reg); |
| 1075 | if (time_after(jiffies, before + FW_MAX_DELAY * HZ)) { | 1278 | if (time_after(jiffies, before + FW_MAX_DELAY * HZ)) { |
| 1076 | dev_err(&mhba->pdev->dev, | 1279 | dev_err(&mhba->pdev->dev, |
| 1077 | "invalid signature [0x%x].\n", tmp); | 1280 | "invalid signature [0x%x].\n", tmp); |
| @@ -1079,7 +1282,7 @@ static unsigned char mvumi_check_handshake(struct mvumi_hba *mhba) | |||
| 1079 | } | 1282 | } |
| 1080 | usleep_range(1000, 2000); | 1283 | usleep_range(1000, 2000); |
| 1081 | rmb(); | 1284 | rmb(); |
| 1082 | tmp = ioread32(regs + CPU_ARM_TO_PCIEA_MSG1); | 1285 | tmp = ioread32(mhba->regs->arm_to_pciea_msg1); |
| 1083 | } | 1286 | } |
| 1084 | 1287 | ||
| 1085 | mhba->fw_state = FW_STATE_STARTING; | 1288 | mhba->fw_state = FW_STATE_STARTING; |
| @@ -1100,15 +1303,17 @@ static unsigned char mvumi_check_handshake(struct mvumi_hba *mhba) | |||
| 1100 | 1303 | ||
| 1101 | static unsigned char mvumi_start(struct mvumi_hba *mhba) | 1304 | static unsigned char mvumi_start(struct mvumi_hba *mhba) |
| 1102 | { | 1305 | { |
| 1103 | void *regs = mhba->mmio; | ||
| 1104 | unsigned int tmp; | 1306 | unsigned int tmp; |
| 1307 | struct mvumi_hw_regs *regs = mhba->regs; | ||
| 1308 | |||
| 1105 | /* clear Door bell */ | 1309 | /* clear Door bell */ |
| 1106 | tmp = ioread32(regs + CPU_ARM_TO_PCIEA_DRBL_REG); | 1310 | tmp = ioread32(regs->arm_to_pciea_drbl_reg); |
| 1107 | iowrite32(tmp, regs + CPU_ARM_TO_PCIEA_DRBL_REG); | 1311 | iowrite32(tmp, regs->arm_to_pciea_drbl_reg); |
| 1108 | 1312 | ||
| 1109 | iowrite32(0x3FFFFFFF, regs + CPU_ARM_TO_PCIEA_MASK_REG); | 1313 | iowrite32(regs->int_drbl_int_mask, regs->arm_to_pciea_mask_reg); |
| 1110 | tmp = ioread32(regs + CPU_ENPOINTA_MASK_REG) | INT_MAP_DL_CPU2PCIEA; | 1314 | tmp = ioread32(regs->enpointa_mask_reg) | regs->int_dl_cpu2pciea; |
| 1111 | iowrite32(tmp, regs + CPU_ENPOINTA_MASK_REG); | 1315 | iowrite32(tmp, regs->enpointa_mask_reg); |
| 1316 | msleep(100); | ||
| 1112 | if (mvumi_check_handshake(mhba)) | 1317 | if (mvumi_check_handshake(mhba)) |
| 1113 | return -1; | 1318 | return -1; |
| 1114 | 1319 | ||
| @@ -1166,6 +1371,7 @@ static void mvumi_complete_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd, | |||
| 1166 | cmd->scmd->scsi_done(scmd); | 1371 | cmd->scmd->scsi_done(scmd); |
| 1167 | mvumi_return_cmd(mhba, cmd); | 1372 | mvumi_return_cmd(mhba, cmd); |
| 1168 | } | 1373 | } |
| 1374 | |||
| 1169 | static void mvumi_complete_internal_cmd(struct mvumi_hba *mhba, | 1375 | static void mvumi_complete_internal_cmd(struct mvumi_hba *mhba, |
| 1170 | struct mvumi_cmd *cmd, | 1376 | struct mvumi_cmd *cmd, |
| 1171 | struct mvumi_rsp_frame *ob_frame) | 1377 | struct mvumi_rsp_frame *ob_frame) |
| @@ -1210,6 +1416,304 @@ static void mvumi_show_event(struct mvumi_hba *mhba, | |||
| 1210 | } | 1416 | } |
| 1211 | } | 1417 | } |
| 1212 | 1418 | ||
| 1419 | static int mvumi_handle_hotplug(struct mvumi_hba *mhba, u16 devid, int status) | ||
| 1420 | { | ||
| 1421 | struct scsi_device *sdev; | ||
| 1422 | int ret = -1; | ||
| 1423 | |||
| 1424 | if (status == DEVICE_OFFLINE) { | ||
| 1425 | sdev = scsi_device_lookup(mhba->shost, 0, devid, 0); | ||
| 1426 | if (sdev) { | ||
| 1427 | dev_dbg(&mhba->pdev->dev, "remove disk %d-%d-%d.\n", 0, | ||
| 1428 | sdev->id, 0); | ||
| 1429 | scsi_remove_device(sdev); | ||
| 1430 | scsi_device_put(sdev); | ||
| 1431 | ret = 0; | ||
| 1432 | } else | ||
| 1433 | dev_err(&mhba->pdev->dev, " no disk[%d] to remove\n", | ||
| 1434 | devid); | ||
| 1435 | } else if (status == DEVICE_ONLINE) { | ||
| 1436 | sdev = scsi_device_lookup(mhba->shost, 0, devid, 0); | ||
| 1437 | if (!sdev) { | ||
| 1438 | scsi_add_device(mhba->shost, 0, devid, 0); | ||
| 1439 | dev_dbg(&mhba->pdev->dev, " add disk %d-%d-%d.\n", 0, | ||
| 1440 | devid, 0); | ||
| 1441 | ret = 0; | ||
| 1442 | } else { | ||
| 1443 | dev_err(&mhba->pdev->dev, " don't add disk %d-%d-%d.\n", | ||
| 1444 | 0, devid, 0); | ||
| 1445 | scsi_device_put(sdev); | ||
| 1446 | } | ||
| 1447 | } | ||
| 1448 | return ret; | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | static u64 mvumi_inquiry(struct mvumi_hba *mhba, | ||
| 1452 | unsigned int id, struct mvumi_cmd *cmd) | ||
| 1453 | { | ||
| 1454 | struct mvumi_msg_frame *frame; | ||
| 1455 | u64 wwid = 0; | ||
| 1456 | int cmd_alloc = 0; | ||
| 1457 | int data_buf_len = 64; | ||
| 1458 | |||
| 1459 | if (!cmd) { | ||
| 1460 | cmd = mvumi_create_internal_cmd(mhba, data_buf_len); | ||
| 1461 | if (cmd) | ||
| 1462 | cmd_alloc = 1; | ||
| 1463 | else | ||
| 1464 | return 0; | ||
| 1465 | } else { | ||
| 1466 | memset(cmd->data_buf, 0, data_buf_len); | ||
| 1467 | } | ||
| 1468 | cmd->scmd = NULL; | ||
| 1469 | cmd->cmd_status = REQ_STATUS_PENDING; | ||
| 1470 | atomic_set(&cmd->sync_cmd, 0); | ||
| 1471 | frame = cmd->frame; | ||
| 1472 | frame->device_id = (u16) id; | ||
| 1473 | frame->cmd_flag = CMD_FLAG_DATA_IN; | ||
| 1474 | frame->req_function = CL_FUN_SCSI_CMD; | ||
| 1475 | frame->cdb_length = 6; | ||
| 1476 | frame->data_transfer_length = MVUMI_INQUIRY_LENGTH; | ||
| 1477 | memset(frame->cdb, 0, frame->cdb_length); | ||
| 1478 | frame->cdb[0] = INQUIRY; | ||
| 1479 | frame->cdb[4] = frame->data_transfer_length; | ||
| 1480 | |||
| 1481 | mvumi_issue_blocked_cmd(mhba, cmd); | ||
| 1482 | |||
| 1483 | if (cmd->cmd_status == SAM_STAT_GOOD) { | ||
| 1484 | if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9143) | ||
| 1485 | wwid = id + 1; | ||
| 1486 | else | ||
| 1487 | memcpy((void *)&wwid, | ||
| 1488 | (cmd->data_buf + MVUMI_INQUIRY_UUID_OFF), | ||
| 1489 | MVUMI_INQUIRY_UUID_LEN); | ||
| 1490 | dev_dbg(&mhba->pdev->dev, | ||
| 1491 | "inquiry device(0:%d:0) wwid(%llx)\n", id, wwid); | ||
| 1492 | } else { | ||
| 1493 | wwid = 0; | ||
| 1494 | } | ||
| 1495 | if (cmd_alloc) | ||
| 1496 | mvumi_delete_internal_cmd(mhba, cmd); | ||
| 1497 | |||
| 1498 | return wwid; | ||
| 1499 | } | ||
| 1500 | |||
| 1501 | static void mvumi_detach_devices(struct mvumi_hba *mhba) | ||
| 1502 | { | ||
| 1503 | struct mvumi_device *mv_dev = NULL , *dev_next; | ||
| 1504 | struct scsi_device *sdev = NULL; | ||
| 1505 | |||
| 1506 | mutex_lock(&mhba->device_lock); | ||
| 1507 | |||
| 1508 | /* detach Hard Disk */ | ||
| 1509 | list_for_each_entry_safe(mv_dev, dev_next, | ||
| 1510 | &mhba->shost_dev_list, list) { | ||
| 1511 | mvumi_handle_hotplug(mhba, mv_dev->id, DEVICE_OFFLINE); | ||
| 1512 | list_del_init(&mv_dev->list); | ||
| 1513 | dev_dbg(&mhba->pdev->dev, "release device(0:%d:0) wwid(%llx)\n", | ||
| 1514 | mv_dev->id, mv_dev->wwid); | ||
| 1515 | kfree(mv_dev); | ||
| 1516 | } | ||
| 1517 | list_for_each_entry_safe(mv_dev, dev_next, &mhba->mhba_dev_list, list) { | ||
| 1518 | list_del_init(&mv_dev->list); | ||
| 1519 | dev_dbg(&mhba->pdev->dev, "release device(0:%d:0) wwid(%llx)\n", | ||
| 1520 | mv_dev->id, mv_dev->wwid); | ||
| 1521 | kfree(mv_dev); | ||
| 1522 | } | ||
| 1523 | |||
| 1524 | /* detach virtual device */ | ||
| 1525 | if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580) | ||
| 1526 | sdev = scsi_device_lookup(mhba->shost, 0, | ||
| 1527 | mhba->max_target_id - 1, 0); | ||
| 1528 | |||
| 1529 | if (sdev) { | ||
| 1530 | scsi_remove_device(sdev); | ||
| 1531 | scsi_device_put(sdev); | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | mutex_unlock(&mhba->device_lock); | ||
| 1535 | } | ||
| 1536 | |||
| 1537 | static void mvumi_rescan_devices(struct mvumi_hba *mhba, int id) | ||
| 1538 | { | ||
| 1539 | struct scsi_device *sdev; | ||
| 1540 | |||
| 1541 | sdev = scsi_device_lookup(mhba->shost, 0, id, 0); | ||
| 1542 | if (sdev) { | ||
| 1543 | scsi_rescan_device(&sdev->sdev_gendev); | ||
| 1544 | scsi_device_put(sdev); | ||
| 1545 | } | ||
| 1546 | } | ||
| 1547 | |||
| 1548 | static int mvumi_match_devices(struct mvumi_hba *mhba, int id, u64 wwid) | ||
| 1549 | { | ||
| 1550 | struct mvumi_device *mv_dev = NULL; | ||
| 1551 | |||
| 1552 | list_for_each_entry(mv_dev, &mhba->shost_dev_list, list) { | ||
| 1553 | if (mv_dev->wwid == wwid) { | ||
| 1554 | if (mv_dev->id != id) { | ||
| 1555 | dev_err(&mhba->pdev->dev, | ||
| 1556 | "%s has same wwid[%llx] ," | ||
| 1557 | " but different id[%d %d]\n", | ||
| 1558 | __func__, mv_dev->wwid, mv_dev->id, id); | ||
| 1559 | return -1; | ||
| 1560 | } else { | ||
| 1561 | if (mhba->pdev->device == | ||
| 1562 | PCI_DEVICE_ID_MARVELL_MV9143) | ||
| 1563 | mvumi_rescan_devices(mhba, id); | ||
| 1564 | return 1; | ||
| 1565 | } | ||
| 1566 | } | ||
| 1567 | } | ||
| 1568 | return 0; | ||
| 1569 | } | ||
| 1570 | |||
| 1571 | static void mvumi_remove_devices(struct mvumi_hba *mhba, int id) | ||
| 1572 | { | ||
| 1573 | struct mvumi_device *mv_dev = NULL, *dev_next; | ||
| 1574 | |||
| 1575 | list_for_each_entry_safe(mv_dev, dev_next, | ||
| 1576 | &mhba->shost_dev_list, list) { | ||
| 1577 | if (mv_dev->id == id) { | ||
| 1578 | dev_dbg(&mhba->pdev->dev, | ||
| 1579 | "detach device(0:%d:0) wwid(%llx) from HOST\n", | ||
| 1580 | mv_dev->id, mv_dev->wwid); | ||
| 1581 | mvumi_handle_hotplug(mhba, mv_dev->id, DEVICE_OFFLINE); | ||
| 1582 | list_del_init(&mv_dev->list); | ||
| 1583 | kfree(mv_dev); | ||
| 1584 | } | ||
| 1585 | } | ||
| 1586 | } | ||
| 1587 | |||
| 1588 | static int mvumi_probe_devices(struct mvumi_hba *mhba) | ||
| 1589 | { | ||
| 1590 | int id, maxid; | ||
| 1591 | u64 wwid = 0; | ||
| 1592 | struct mvumi_device *mv_dev = NULL; | ||
| 1593 | struct mvumi_cmd *cmd = NULL; | ||
| 1594 | int found = 0; | ||
| 1595 | |||
| 1596 | cmd = mvumi_create_internal_cmd(mhba, 64); | ||
| 1597 | if (!cmd) | ||
| 1598 | return -1; | ||
| 1599 | |||
| 1600 | if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9143) | ||
| 1601 | maxid = mhba->max_target_id; | ||
| 1602 | else | ||
| 1603 | maxid = mhba->max_target_id - 1; | ||
| 1604 | |||
| 1605 | for (id = 0; id < maxid; id++) { | ||
| 1606 | wwid = mvumi_inquiry(mhba, id, cmd); | ||
| 1607 | if (!wwid) { | ||
| 1608 | /* device no response, remove it */ | ||
| 1609 | mvumi_remove_devices(mhba, id); | ||
| 1610 | } else { | ||
| 1611 | /* device response, add it */ | ||
| 1612 | found = mvumi_match_devices(mhba, id, wwid); | ||
| 1613 | if (!found) { | ||
| 1614 | mvumi_remove_devices(mhba, id); | ||
| 1615 | mv_dev = kzalloc(sizeof(struct mvumi_device), | ||
| 1616 | GFP_KERNEL); | ||
| 1617 | if (!mv_dev) { | ||
| 1618 | dev_err(&mhba->pdev->dev, | ||
| 1619 | "%s alloc mv_dev failed\n", | ||
| 1620 | __func__); | ||
| 1621 | continue; | ||
| 1622 | } | ||
| 1623 | mv_dev->id = id; | ||
| 1624 | mv_dev->wwid = wwid; | ||
| 1625 | mv_dev->sdev = NULL; | ||
| 1626 | INIT_LIST_HEAD(&mv_dev->list); | ||
| 1627 | list_add_tail(&mv_dev->list, | ||
| 1628 | &mhba->mhba_dev_list); | ||
| 1629 | dev_dbg(&mhba->pdev->dev, | ||
| 1630 | "probe a new device(0:%d:0)" | ||
| 1631 | " wwid(%llx)\n", id, mv_dev->wwid); | ||
| 1632 | } else if (found == -1) | ||
| 1633 | return -1; | ||
| 1634 | else | ||
| 1635 | continue; | ||
| 1636 | } | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | if (cmd) | ||
| 1640 | mvumi_delete_internal_cmd(mhba, cmd); | ||
| 1641 | |||
| 1642 | return 0; | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | static int mvumi_rescan_bus(void *data) | ||
| 1646 | { | ||
| 1647 | int ret = 0; | ||
| 1648 | struct mvumi_hba *mhba = (struct mvumi_hba *) data; | ||
| 1649 | struct mvumi_device *mv_dev = NULL , *dev_next; | ||
| 1650 | |||
| 1651 | while (!kthread_should_stop()) { | ||
| 1652 | |||
| 1653 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1654 | if (!atomic_read(&mhba->pnp_count)) | ||
| 1655 | schedule(); | ||
| 1656 | msleep(1000); | ||
| 1657 | atomic_set(&mhba->pnp_count, 0); | ||
| 1658 | __set_current_state(TASK_RUNNING); | ||
| 1659 | |||
| 1660 | mutex_lock(&mhba->device_lock); | ||
| 1661 | ret = mvumi_probe_devices(mhba); | ||
| 1662 | if (!ret) { | ||
| 1663 | list_for_each_entry_safe(mv_dev, dev_next, | ||
| 1664 | &mhba->mhba_dev_list, list) { | ||
| 1665 | if (mvumi_handle_hotplug(mhba, mv_dev->id, | ||
| 1666 | DEVICE_ONLINE)) { | ||
| 1667 | dev_err(&mhba->pdev->dev, | ||
| 1668 | "%s add device(0:%d:0) failed" | ||
| 1669 | "wwid(%llx) has exist\n", | ||
| 1670 | __func__, | ||
| 1671 | mv_dev->id, mv_dev->wwid); | ||
| 1672 | list_del_init(&mv_dev->list); | ||
| 1673 | kfree(mv_dev); | ||
| 1674 | } else { | ||
| 1675 | list_move_tail(&mv_dev->list, | ||
| 1676 | &mhba->shost_dev_list); | ||
| 1677 | } | ||
| 1678 | } | ||
| 1679 | } | ||
| 1680 | mutex_unlock(&mhba->device_lock); | ||
| 1681 | } | ||
| 1682 | return 0; | ||
| 1683 | } | ||
| 1684 | |||
| 1685 | static void mvumi_proc_msg(struct mvumi_hba *mhba, | ||
| 1686 | struct mvumi_hotplug_event *param) | ||
| 1687 | { | ||
| 1688 | u16 size = param->size; | ||
| 1689 | const unsigned long *ar_bitmap; | ||
| 1690 | const unsigned long *re_bitmap; | ||
| 1691 | int index; | ||
| 1692 | |||
| 1693 | if (mhba->fw_flag & MVUMI_FW_ATTACH) { | ||
| 1694 | index = -1; | ||
| 1695 | ar_bitmap = (const unsigned long *) param->bitmap; | ||
| 1696 | re_bitmap = (const unsigned long *) ¶m->bitmap[size >> 3]; | ||
| 1697 | |||
| 1698 | mutex_lock(&mhba->sas_discovery_mutex); | ||
| 1699 | do { | ||
| 1700 | index = find_next_zero_bit(ar_bitmap, size, index + 1); | ||
| 1701 | if (index >= size) | ||
| 1702 | break; | ||
| 1703 | mvumi_handle_hotplug(mhba, index, DEVICE_ONLINE); | ||
| 1704 | } while (1); | ||
| 1705 | |||
| 1706 | index = -1; | ||
| 1707 | do { | ||
| 1708 | index = find_next_zero_bit(re_bitmap, size, index + 1); | ||
| 1709 | if (index >= size) | ||
| 1710 | break; | ||
| 1711 | mvumi_handle_hotplug(mhba, index, DEVICE_OFFLINE); | ||
| 1712 | } while (1); | ||
| 1713 | mutex_unlock(&mhba->sas_discovery_mutex); | ||
| 1714 | } | ||
| 1715 | } | ||
| 1716 | |||
| 1213 | static void mvumi_notification(struct mvumi_hba *mhba, u8 msg, void *buffer) | 1717 | static void mvumi_notification(struct mvumi_hba *mhba, u8 msg, void *buffer) |
| 1214 | { | 1718 | { |
| 1215 | if (msg == APICDB1_EVENT_GETEVENT) { | 1719 | if (msg == APICDB1_EVENT_GETEVENT) { |
| @@ -1227,6 +1731,8 @@ static void mvumi_notification(struct mvumi_hba *mhba, u8 msg, void *buffer) | |||
| 1227 | param = &er->events[i]; | 1731 | param = &er->events[i]; |
| 1228 | mvumi_show_event(mhba, param); | 1732 | mvumi_show_event(mhba, param); |
| 1229 | } | 1733 | } |
| 1734 | } else if (msg == APICDB1_HOST_GETEVENT) { | ||
| 1735 | mvumi_proc_msg(mhba, buffer); | ||
| 1230 | } | 1736 | } |
| 1231 | } | 1737 | } |
| 1232 | 1738 | ||
| @@ -1271,17 +1777,27 @@ static void mvumi_scan_events(struct work_struct *work) | |||
| 1271 | kfree(mu_ev); | 1777 | kfree(mu_ev); |
| 1272 | } | 1778 | } |
| 1273 | 1779 | ||
| 1274 | static void mvumi_launch_events(struct mvumi_hba *mhba, u8 msg) | 1780 | static void mvumi_launch_events(struct mvumi_hba *mhba, u32 isr_status) |
| 1275 | { | 1781 | { |
| 1276 | struct mvumi_events_wq *mu_ev; | 1782 | struct mvumi_events_wq *mu_ev; |
| 1277 | 1783 | ||
| 1278 | mu_ev = kzalloc(sizeof(*mu_ev), GFP_ATOMIC); | 1784 | while (isr_status & (DRBL_BUS_CHANGE | DRBL_EVENT_NOTIFY)) { |
| 1279 | if (mu_ev) { | 1785 | if (isr_status & DRBL_BUS_CHANGE) { |
| 1280 | INIT_WORK(&mu_ev->work_q, mvumi_scan_events); | 1786 | atomic_inc(&mhba->pnp_count); |
| 1281 | mu_ev->mhba = mhba; | 1787 | wake_up_process(mhba->dm_thread); |
| 1282 | mu_ev->event = msg; | 1788 | isr_status &= ~(DRBL_BUS_CHANGE); |
| 1283 | mu_ev->param = NULL; | 1789 | continue; |
| 1284 | schedule_work(&mu_ev->work_q); | 1790 | } |
| 1791 | |||
| 1792 | mu_ev = kzalloc(sizeof(*mu_ev), GFP_ATOMIC); | ||
| 1793 | if (mu_ev) { | ||
| 1794 | INIT_WORK(&mu_ev->work_q, mvumi_scan_events); | ||
| 1795 | mu_ev->mhba = mhba; | ||
| 1796 | mu_ev->event = APICDB1_EVENT_GETEVENT; | ||
| 1797 | isr_status &= ~(DRBL_EVENT_NOTIFY); | ||
| 1798 | mu_ev->param = NULL; | ||
| 1799 | schedule_work(&mu_ev->work_q); | ||
| 1800 | } | ||
| 1285 | } | 1801 | } |
| 1286 | } | 1802 | } |
| 1287 | 1803 | ||
| @@ -1322,16 +1838,17 @@ static irqreturn_t mvumi_isr_handler(int irq, void *devp) | |||
| 1322 | return IRQ_NONE; | 1838 | return IRQ_NONE; |
| 1323 | } | 1839 | } |
| 1324 | 1840 | ||
| 1325 | if (mhba->global_isr & INT_MAP_DL_CPU2PCIEA) { | 1841 | if (mhba->global_isr & mhba->regs->int_dl_cpu2pciea) { |
| 1842 | if (mhba->isr_status & (DRBL_BUS_CHANGE | DRBL_EVENT_NOTIFY)) | ||
| 1843 | mvumi_launch_events(mhba, mhba->isr_status); | ||
| 1326 | if (mhba->isr_status & DRBL_HANDSHAKE_ISR) { | 1844 | if (mhba->isr_status & DRBL_HANDSHAKE_ISR) { |
| 1327 | dev_warn(&mhba->pdev->dev, "enter handshake again!\n"); | 1845 | dev_warn(&mhba->pdev->dev, "enter handshake again!\n"); |
| 1328 | mvumi_handshake(mhba); | 1846 | mvumi_handshake(mhba); |
| 1329 | } | 1847 | } |
| 1330 | if (mhba->isr_status & DRBL_EVENT_NOTIFY) | 1848 | |
| 1331 | mvumi_launch_events(mhba, APICDB1_EVENT_GETEVENT); | ||
| 1332 | } | 1849 | } |
| 1333 | 1850 | ||
| 1334 | if (mhba->global_isr & INT_MAP_COMAOUT) | 1851 | if (mhba->global_isr & mhba->regs->int_comaout) |
| 1335 | mvumi_receive_ob_list_entry(mhba); | 1852 | mvumi_receive_ob_list_entry(mhba); |
| 1336 | 1853 | ||
| 1337 | mhba->global_isr = 0; | 1854 | mhba->global_isr = 0; |
| @@ -1358,8 +1875,7 @@ static enum mvumi_qc_result mvumi_send_command(struct mvumi_hba *mhba, | |||
| 1358 | dev_dbg(&mhba->pdev->dev, "no free tag.\n"); | 1875 | dev_dbg(&mhba->pdev->dev, "no free tag.\n"); |
| 1359 | return MV_QUEUE_COMMAND_RESULT_NO_RESOURCE; | 1876 | return MV_QUEUE_COMMAND_RESULT_NO_RESOURCE; |
| 1360 | } | 1877 | } |
| 1361 | if (mvumi_get_ib_list_entry(mhba, &ib_entry)) | 1878 | mvumi_get_ib_list_entry(mhba, &ib_entry); |
| 1362 | return MV_QUEUE_COMMAND_RESULT_NO_RESOURCE; | ||
| 1363 | 1879 | ||
| 1364 | cmd->frame->tag = tag_get_one(mhba, &mhba->tag_pool); | 1880 | cmd->frame->tag = tag_get_one(mhba, &mhba->tag_pool); |
| 1365 | cmd->frame->request_id = mhba->io_seq++; | 1881 | cmd->frame->request_id = mhba->io_seq++; |
| @@ -1367,21 +1883,35 @@ static enum mvumi_qc_result mvumi_send_command(struct mvumi_hba *mhba, | |||
| 1367 | mhba->tag_cmd[cmd->frame->tag] = cmd; | 1883 | mhba->tag_cmd[cmd->frame->tag] = cmd; |
| 1368 | frame_len = sizeof(*ib_frame) - 4 + | 1884 | frame_len = sizeof(*ib_frame) - 4 + |
| 1369 | ib_frame->sg_counts * sizeof(struct mvumi_sgl); | 1885 | ib_frame->sg_counts * sizeof(struct mvumi_sgl); |
| 1370 | memcpy(ib_entry, ib_frame, frame_len); | 1886 | if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) { |
| 1887 | struct mvumi_dyn_list_entry *dle; | ||
| 1888 | dle = ib_entry; | ||
| 1889 | dle->src_low_addr = | ||
| 1890 | cpu_to_le32(lower_32_bits(cmd->frame_phys)); | ||
| 1891 | dle->src_high_addr = | ||
| 1892 | cpu_to_le32(upper_32_bits(cmd->frame_phys)); | ||
| 1893 | dle->if_length = (frame_len >> 2) & 0xFFF; | ||
| 1894 | } else { | ||
| 1895 | memcpy(ib_entry, ib_frame, frame_len); | ||
| 1896 | } | ||
| 1371 | return MV_QUEUE_COMMAND_RESULT_SENT; | 1897 | return MV_QUEUE_COMMAND_RESULT_SENT; |
| 1372 | } | 1898 | } |
| 1373 | 1899 | ||
| 1374 | static void mvumi_fire_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd) | 1900 | static void mvumi_fire_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd) |
| 1375 | { | 1901 | { |
| 1376 | unsigned short num_of_cl_sent = 0; | 1902 | unsigned short num_of_cl_sent = 0; |
| 1903 | unsigned int count; | ||
| 1377 | enum mvumi_qc_result result; | 1904 | enum mvumi_qc_result result; |
| 1378 | 1905 | ||
| 1379 | if (cmd) | 1906 | if (cmd) |
| 1380 | list_add_tail(&cmd->queue_pointer, &mhba->waiting_req_list); | 1907 | list_add_tail(&cmd->queue_pointer, &mhba->waiting_req_list); |
| 1908 | count = mhba->instancet->check_ib_list(mhba); | ||
| 1909 | if (list_empty(&mhba->waiting_req_list) || !count) | ||
| 1910 | return; | ||
| 1381 | 1911 | ||
| 1382 | while (!list_empty(&mhba->waiting_req_list)) { | 1912 | do { |
| 1383 | cmd = list_first_entry(&mhba->waiting_req_list, | 1913 | cmd = list_first_entry(&mhba->waiting_req_list, |
| 1384 | struct mvumi_cmd, queue_pointer); | 1914 | struct mvumi_cmd, queue_pointer); |
| 1385 | list_del_init(&cmd->queue_pointer); | 1915 | list_del_init(&cmd->queue_pointer); |
| 1386 | result = mvumi_send_command(mhba, cmd); | 1916 | result = mvumi_send_command(mhba, cmd); |
| 1387 | switch (result) { | 1917 | switch (result) { |
| @@ -1395,65 +1925,77 @@ static void mvumi_fire_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd) | |||
| 1395 | 1925 | ||
| 1396 | return; | 1926 | return; |
| 1397 | } | 1927 | } |
| 1398 | } | 1928 | } while (!list_empty(&mhba->waiting_req_list) && count--); |
| 1929 | |||
| 1399 | if (num_of_cl_sent > 0) | 1930 | if (num_of_cl_sent > 0) |
| 1400 | mvumi_send_ib_list_entry(mhba); | 1931 | mvumi_send_ib_list_entry(mhba); |
| 1401 | } | 1932 | } |
| 1402 | 1933 | ||
| 1403 | /** | 1934 | /** |
| 1404 | * mvumi_enable_intr - Enables interrupts | 1935 | * mvumi_enable_intr - Enables interrupts |
| 1405 | * @regs: FW register set | 1936 | * @mhba: Adapter soft state |
| 1406 | */ | 1937 | */ |
| 1407 | static void mvumi_enable_intr(void *regs) | 1938 | static void mvumi_enable_intr(struct mvumi_hba *mhba) |
| 1408 | { | 1939 | { |
| 1409 | unsigned int mask; | 1940 | unsigned int mask; |
| 1941 | struct mvumi_hw_regs *regs = mhba->regs; | ||
| 1410 | 1942 | ||
| 1411 | iowrite32(0x3FFFFFFF, regs + CPU_ARM_TO_PCIEA_MASK_REG); | 1943 | iowrite32(regs->int_drbl_int_mask, regs->arm_to_pciea_mask_reg); |
| 1412 | mask = ioread32(regs + CPU_ENPOINTA_MASK_REG); | 1944 | mask = ioread32(regs->enpointa_mask_reg); |
| 1413 | mask |= INT_MAP_DL_CPU2PCIEA | INT_MAP_COMAOUT | INT_MAP_COMAERR; | 1945 | mask |= regs->int_dl_cpu2pciea | regs->int_comaout | regs->int_comaerr; |
| 1414 | iowrite32(mask, regs + CPU_ENPOINTA_MASK_REG); | 1946 | iowrite32(mask, regs->enpointa_mask_reg); |
| 1415 | } | 1947 | } |
| 1416 | 1948 | ||
| 1417 | /** | 1949 | /** |
| 1418 | * mvumi_disable_intr -Disables interrupt | 1950 | * mvumi_disable_intr -Disables interrupt |
| 1419 | * @regs: FW register set | 1951 | * @mhba: Adapter soft state |
| 1420 | */ | 1952 | */ |
| 1421 | static void mvumi_disable_intr(void *regs) | 1953 | static void mvumi_disable_intr(struct mvumi_hba *mhba) |
| 1422 | { | 1954 | { |
| 1423 | unsigned int mask; | 1955 | unsigned int mask; |
| 1956 | struct mvumi_hw_regs *regs = mhba->regs; | ||
| 1424 | 1957 | ||
| 1425 | iowrite32(0, regs + CPU_ARM_TO_PCIEA_MASK_REG); | 1958 | iowrite32(0, regs->arm_to_pciea_mask_reg); |
| 1426 | mask = ioread32(regs + CPU_ENPOINTA_MASK_REG); | 1959 | mask = ioread32(regs->enpointa_mask_reg); |
| 1427 | mask &= ~(INT_MAP_DL_CPU2PCIEA | INT_MAP_COMAOUT | INT_MAP_COMAERR); | 1960 | mask &= ~(regs->int_dl_cpu2pciea | regs->int_comaout | |
| 1428 | iowrite32(mask, regs + CPU_ENPOINTA_MASK_REG); | 1961 | regs->int_comaerr); |
| 1962 | iowrite32(mask, regs->enpointa_mask_reg); | ||
| 1429 | } | 1963 | } |
| 1430 | 1964 | ||
| 1431 | static int mvumi_clear_intr(void *extend) | 1965 | static int mvumi_clear_intr(void *extend) |
| 1432 | { | 1966 | { |
| 1433 | struct mvumi_hba *mhba = (struct mvumi_hba *) extend; | 1967 | struct mvumi_hba *mhba = (struct mvumi_hba *) extend; |
| 1434 | unsigned int status, isr_status = 0, tmp = 0; | 1968 | unsigned int status, isr_status = 0, tmp = 0; |
| 1435 | void *regs = mhba->mmio; | 1969 | struct mvumi_hw_regs *regs = mhba->regs; |
| 1436 | 1970 | ||
| 1437 | status = ioread32(regs + CPU_MAIN_INT_CAUSE_REG); | 1971 | status = ioread32(regs->main_int_cause_reg); |
| 1438 | if (!(status & INT_MAP_MU) || status == 0xFFFFFFFF) | 1972 | if (!(status & regs->int_mu) || status == 0xFFFFFFFF) |
| 1439 | return 1; | 1973 | return 1; |
| 1440 | if (unlikely(status & INT_MAP_COMAERR)) { | 1974 | if (unlikely(status & regs->int_comaerr)) { |
| 1441 | tmp = ioread32(regs + CLA_ISR_CAUSE); | 1975 | tmp = ioread32(regs->outb_isr_cause); |
| 1442 | if (tmp & (CLIC_IN_ERR_IRQ | CLIC_OUT_ERR_IRQ)) | 1976 | if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580) { |
| 1443 | iowrite32(tmp & (CLIC_IN_ERR_IRQ | CLIC_OUT_ERR_IRQ), | 1977 | if (tmp & regs->clic_out_err) { |
| 1444 | regs + CLA_ISR_CAUSE); | 1978 | iowrite32(tmp & regs->clic_out_err, |
| 1445 | status ^= INT_MAP_COMAERR; | 1979 | regs->outb_isr_cause); |
| 1980 | } | ||
| 1981 | } else { | ||
| 1982 | if (tmp & (regs->clic_in_err | regs->clic_out_err)) | ||
| 1983 | iowrite32(tmp & (regs->clic_in_err | | ||
| 1984 | regs->clic_out_err), | ||
| 1985 | regs->outb_isr_cause); | ||
| 1986 | } | ||
| 1987 | status ^= mhba->regs->int_comaerr; | ||
| 1446 | /* inbound or outbound parity error, command will timeout */ | 1988 | /* inbound or outbound parity error, command will timeout */ |
| 1447 | } | 1989 | } |
| 1448 | if (status & INT_MAP_COMAOUT) { | 1990 | if (status & regs->int_comaout) { |
| 1449 | tmp = ioread32(regs + CLA_ISR_CAUSE); | 1991 | tmp = ioread32(regs->outb_isr_cause); |
| 1450 | if (tmp & CLIC_OUT_IRQ) | 1992 | if (tmp & regs->clic_irq) |
| 1451 | iowrite32(tmp & CLIC_OUT_IRQ, regs + CLA_ISR_CAUSE); | 1993 | iowrite32(tmp & regs->clic_irq, regs->outb_isr_cause); |
| 1452 | } | 1994 | } |
| 1453 | if (status & INT_MAP_DL_CPU2PCIEA) { | 1995 | if (status & regs->int_dl_cpu2pciea) { |
| 1454 | isr_status = ioread32(regs + CPU_ARM_TO_PCIEA_DRBL_REG); | 1996 | isr_status = ioread32(regs->arm_to_pciea_drbl_reg); |
| 1455 | if (isr_status) | 1997 | if (isr_status) |
| 1456 | iowrite32(isr_status, regs + CPU_ARM_TO_PCIEA_DRBL_REG); | 1998 | iowrite32(isr_status, regs->arm_to_pciea_drbl_reg); |
| 1457 | } | 1999 | } |
| 1458 | 2000 | ||
| 1459 | mhba->global_isr = status; | 2001 | mhba->global_isr = status; |
| @@ -1464,24 +2006,38 @@ static int mvumi_clear_intr(void *extend) | |||
| 1464 | 2006 | ||
| 1465 | /** | 2007 | /** |
| 1466 | * mvumi_read_fw_status_reg - returns the current FW status value | 2008 | * mvumi_read_fw_status_reg - returns the current FW status value |
| 1467 | * @regs: FW register set | 2009 | * @mhba: Adapter soft state |
| 1468 | */ | 2010 | */ |
| 1469 | static unsigned int mvumi_read_fw_status_reg(void *regs) | 2011 | static unsigned int mvumi_read_fw_status_reg(struct mvumi_hba *mhba) |
| 1470 | { | 2012 | { |
| 1471 | unsigned int status; | 2013 | unsigned int status; |
| 1472 | 2014 | ||
| 1473 | status = ioread32(regs + CPU_ARM_TO_PCIEA_DRBL_REG); | 2015 | status = ioread32(mhba->regs->arm_to_pciea_drbl_reg); |
| 1474 | if (status) | 2016 | if (status) |
| 1475 | iowrite32(status, regs + CPU_ARM_TO_PCIEA_DRBL_REG); | 2017 | iowrite32(status, mhba->regs->arm_to_pciea_drbl_reg); |
| 1476 | return status; | 2018 | return status; |
| 1477 | } | 2019 | } |
| 1478 | 2020 | ||
| 1479 | static struct mvumi_instance_template mvumi_instance_template = { | 2021 | static struct mvumi_instance_template mvumi_instance_9143 = { |
| 1480 | .fire_cmd = mvumi_fire_cmd, | 2022 | .fire_cmd = mvumi_fire_cmd, |
| 1481 | .enable_intr = mvumi_enable_intr, | 2023 | .enable_intr = mvumi_enable_intr, |
| 1482 | .disable_intr = mvumi_disable_intr, | 2024 | .disable_intr = mvumi_disable_intr, |
| 1483 | .clear_intr = mvumi_clear_intr, | 2025 | .clear_intr = mvumi_clear_intr, |
| 1484 | .read_fw_status_reg = mvumi_read_fw_status_reg, | 2026 | .read_fw_status_reg = mvumi_read_fw_status_reg, |
| 2027 | .check_ib_list = mvumi_check_ib_list_9143, | ||
| 2028 | .check_ob_list = mvumi_check_ob_list_9143, | ||
| 2029 | .reset_host = mvumi_reset_host_9143, | ||
| 2030 | }; | ||
| 2031 | |||
| 2032 | static struct mvumi_instance_template mvumi_instance_9580 = { | ||
| 2033 | .fire_cmd = mvumi_fire_cmd, | ||
| 2034 | .enable_intr = mvumi_enable_intr, | ||
| 2035 | .disable_intr = mvumi_disable_intr, | ||
| 2036 | .clear_intr = mvumi_clear_intr, | ||
| 2037 | .read_fw_status_reg = mvumi_read_fw_status_reg, | ||
| 2038 | .check_ib_list = mvumi_check_ib_list_9580, | ||
| 2039 | .check_ob_list = mvumi_check_ob_list_9580, | ||
| 2040 | .reset_host = mvumi_reset_host_9580, | ||
| 1485 | }; | 2041 | }; |
| 1486 | 2042 | ||
| 1487 | static int mvumi_slave_configure(struct scsi_device *sdev) | 2043 | static int mvumi_slave_configure(struct scsi_device *sdev) |
| @@ -1681,6 +2237,124 @@ static struct scsi_transport_template mvumi_transport_template = { | |||
| 1681 | .eh_timed_out = mvumi_timed_out, | 2237 | .eh_timed_out = mvumi_timed_out, |
| 1682 | }; | 2238 | }; |
| 1683 | 2239 | ||
| 2240 | static int mvumi_cfg_hw_reg(struct mvumi_hba *mhba) | ||
| 2241 | { | ||
| 2242 | void *base = NULL; | ||
| 2243 | struct mvumi_hw_regs *regs; | ||
| 2244 | |||
| 2245 | switch (mhba->pdev->device) { | ||
| 2246 | case PCI_DEVICE_ID_MARVELL_MV9143: | ||
| 2247 | mhba->mmio = mhba->base_addr[0]; | ||
| 2248 | base = mhba->mmio; | ||
| 2249 | if (!mhba->regs) { | ||
| 2250 | mhba->regs = kzalloc(sizeof(*regs), GFP_KERNEL); | ||
| 2251 | if (mhba->regs == NULL) | ||
| 2252 | return -ENOMEM; | ||
| 2253 | } | ||
| 2254 | regs = mhba->regs; | ||
| 2255 | |||
| 2256 | /* For Arm */ | ||
| 2257 | regs->ctrl_sts_reg = base + 0x20104; | ||
| 2258 | regs->rstoutn_mask_reg = base + 0x20108; | ||
| 2259 | regs->sys_soft_rst_reg = base + 0x2010C; | ||
| 2260 | regs->main_int_cause_reg = base + 0x20200; | ||
| 2261 | regs->enpointa_mask_reg = base + 0x2020C; | ||
| 2262 | regs->rstoutn_en_reg = base + 0xF1400; | ||
| 2263 | /* For Doorbell */ | ||
| 2264 | regs->pciea_to_arm_drbl_reg = base + 0x20400; | ||
| 2265 | regs->arm_to_pciea_drbl_reg = base + 0x20408; | ||
| 2266 | regs->arm_to_pciea_mask_reg = base + 0x2040C; | ||
| 2267 | regs->pciea_to_arm_msg0 = base + 0x20430; | ||
| 2268 | regs->pciea_to_arm_msg1 = base + 0x20434; | ||
| 2269 | regs->arm_to_pciea_msg0 = base + 0x20438; | ||
| 2270 | regs->arm_to_pciea_msg1 = base + 0x2043C; | ||
| 2271 | |||
| 2272 | /* For Message Unit */ | ||
| 2273 | |||
| 2274 | regs->inb_aval_count_basel = base + 0x508; | ||
| 2275 | regs->inb_aval_count_baseh = base + 0x50C; | ||
| 2276 | regs->inb_write_pointer = base + 0x518; | ||
| 2277 | regs->inb_read_pointer = base + 0x51C; | ||
| 2278 | regs->outb_coal_cfg = base + 0x568; | ||
| 2279 | regs->outb_copy_basel = base + 0x5B0; | ||
| 2280 | regs->outb_copy_baseh = base + 0x5B4; | ||
| 2281 | regs->outb_copy_pointer = base + 0x544; | ||
| 2282 | regs->outb_read_pointer = base + 0x548; | ||
| 2283 | regs->outb_isr_cause = base + 0x560; | ||
| 2284 | regs->outb_coal_cfg = base + 0x568; | ||
| 2285 | /* Bit setting for HW */ | ||
| 2286 | regs->int_comaout = 1 << 8; | ||
| 2287 | regs->int_comaerr = 1 << 6; | ||
| 2288 | regs->int_dl_cpu2pciea = 1 << 1; | ||
| 2289 | regs->cl_pointer_toggle = 1 << 12; | ||
| 2290 | regs->clic_irq = 1 << 1; | ||
| 2291 | regs->clic_in_err = 1 << 8; | ||
| 2292 | regs->clic_out_err = 1 << 12; | ||
| 2293 | regs->cl_slot_num_mask = 0xFFF; | ||
| 2294 | regs->int_drbl_int_mask = 0x3FFFFFFF; | ||
| 2295 | regs->int_mu = regs->int_dl_cpu2pciea | regs->int_comaout | | ||
| 2296 | regs->int_comaerr; | ||
| 2297 | break; | ||
| 2298 | case PCI_DEVICE_ID_MARVELL_MV9580: | ||
| 2299 | mhba->mmio = mhba->base_addr[2]; | ||
| 2300 | base = mhba->mmio; | ||
| 2301 | if (!mhba->regs) { | ||
| 2302 | mhba->regs = kzalloc(sizeof(*regs), GFP_KERNEL); | ||
| 2303 | if (mhba->regs == NULL) | ||
| 2304 | return -ENOMEM; | ||
| 2305 | } | ||
| 2306 | regs = mhba->regs; | ||
| 2307 | /* For Arm */ | ||
| 2308 | regs->ctrl_sts_reg = base + 0x20104; | ||
| 2309 | regs->rstoutn_mask_reg = base + 0x1010C; | ||
| 2310 | regs->sys_soft_rst_reg = base + 0x10108; | ||
| 2311 | regs->main_int_cause_reg = base + 0x10200; | ||
| 2312 | regs->enpointa_mask_reg = base + 0x1020C; | ||
| 2313 | regs->rstoutn_en_reg = base + 0xF1400; | ||
| 2314 | |||
| 2315 | /* For Doorbell */ | ||
| 2316 | regs->pciea_to_arm_drbl_reg = base + 0x10460; | ||
| 2317 | regs->arm_to_pciea_drbl_reg = base + 0x10480; | ||
| 2318 | regs->arm_to_pciea_mask_reg = base + 0x10484; | ||
| 2319 | regs->pciea_to_arm_msg0 = base + 0x10400; | ||
| 2320 | regs->pciea_to_arm_msg1 = base + 0x10404; | ||
| 2321 | regs->arm_to_pciea_msg0 = base + 0x10420; | ||
| 2322 | regs->arm_to_pciea_msg1 = base + 0x10424; | ||
| 2323 | |||
| 2324 | /* For reset*/ | ||
| 2325 | regs->reset_request = base + 0x10108; | ||
| 2326 | regs->reset_enable = base + 0x1010c; | ||
| 2327 | |||
| 2328 | /* For Message Unit */ | ||
| 2329 | regs->inb_aval_count_basel = base + 0x4008; | ||
| 2330 | regs->inb_aval_count_baseh = base + 0x400C; | ||
| 2331 | regs->inb_write_pointer = base + 0x4018; | ||
| 2332 | regs->inb_read_pointer = base + 0x401C; | ||
| 2333 | regs->outb_copy_basel = base + 0x4058; | ||
| 2334 | regs->outb_copy_baseh = base + 0x405C; | ||
| 2335 | regs->outb_copy_pointer = base + 0x406C; | ||
| 2336 | regs->outb_read_pointer = base + 0x4070; | ||
| 2337 | regs->outb_coal_cfg = base + 0x4080; | ||
| 2338 | regs->outb_isr_cause = base + 0x4088; | ||
| 2339 | /* Bit setting for HW */ | ||
| 2340 | regs->int_comaout = 1 << 4; | ||
| 2341 | regs->int_dl_cpu2pciea = 1 << 12; | ||
| 2342 | regs->int_comaerr = 1 << 29; | ||
| 2343 | regs->cl_pointer_toggle = 1 << 14; | ||
| 2344 | regs->cl_slot_num_mask = 0x3FFF; | ||
| 2345 | regs->clic_irq = 1 << 0; | ||
| 2346 | regs->clic_out_err = 1 << 1; | ||
| 2347 | regs->int_drbl_int_mask = 0x3FFFFFFF; | ||
| 2348 | regs->int_mu = regs->int_dl_cpu2pciea | regs->int_comaout; | ||
| 2349 | break; | ||
| 2350 | default: | ||
| 2351 | return -1; | ||
| 2352 | break; | ||
| 2353 | } | ||
| 2354 | |||
| 2355 | return 0; | ||
| 2356 | } | ||
| 2357 | |||
| 1684 | /** | 2358 | /** |
| 1685 | * mvumi_init_fw - Initializes the FW | 2359 | * mvumi_init_fw - Initializes the FW |
| 1686 | * @mhba: Adapter soft state | 2360 | * @mhba: Adapter soft state |
| @@ -1699,15 +2373,18 @@ static int mvumi_init_fw(struct mvumi_hba *mhba) | |||
| 1699 | if (ret) | 2373 | if (ret) |
| 1700 | goto fail_ioremap; | 2374 | goto fail_ioremap; |
| 1701 | 2375 | ||
| 1702 | mhba->mmio = mhba->base_addr[0]; | ||
| 1703 | |||
| 1704 | switch (mhba->pdev->device) { | 2376 | switch (mhba->pdev->device) { |
| 1705 | case PCI_DEVICE_ID_MARVELL_MV9143: | 2377 | case PCI_DEVICE_ID_MARVELL_MV9143: |
| 1706 | mhba->instancet = &mvumi_instance_template; | 2378 | mhba->instancet = &mvumi_instance_9143; |
| 1707 | mhba->io_seq = 0; | 2379 | mhba->io_seq = 0; |
| 1708 | mhba->max_sge = MVUMI_MAX_SG_ENTRY; | 2380 | mhba->max_sge = MVUMI_MAX_SG_ENTRY; |
| 1709 | mhba->request_id_enabled = 1; | 2381 | mhba->request_id_enabled = 1; |
| 1710 | break; | 2382 | break; |
| 2383 | case PCI_DEVICE_ID_MARVELL_MV9580: | ||
| 2384 | mhba->instancet = &mvumi_instance_9580; | ||
| 2385 | mhba->io_seq = 0; | ||
| 2386 | mhba->max_sge = MVUMI_MAX_SG_ENTRY; | ||
| 2387 | break; | ||
| 1711 | default: | 2388 | default: |
| 1712 | dev_err(&mhba->pdev->dev, "device 0x%x not supported!\n", | 2389 | dev_err(&mhba->pdev->dev, "device 0x%x not supported!\n", |
| 1713 | mhba->pdev->device); | 2390 | mhba->pdev->device); |
| @@ -1717,15 +2394,21 @@ static int mvumi_init_fw(struct mvumi_hba *mhba) | |||
| 1717 | } | 2394 | } |
| 1718 | dev_dbg(&mhba->pdev->dev, "device id : %04X is found.\n", | 2395 | dev_dbg(&mhba->pdev->dev, "device id : %04X is found.\n", |
| 1719 | mhba->pdev->device); | 2396 | mhba->pdev->device); |
| 1720 | 2397 | ret = mvumi_cfg_hw_reg(mhba); | |
| 1721 | mhba->handshake_page = kzalloc(HSP_MAX_SIZE, GFP_KERNEL); | 2398 | if (ret) { |
| 2399 | dev_err(&mhba->pdev->dev, | ||
| 2400 | "failed to allocate memory for reg\n"); | ||
| 2401 | ret = -ENOMEM; | ||
| 2402 | goto fail_alloc_mem; | ||
| 2403 | } | ||
| 2404 | mhba->handshake_page = pci_alloc_consistent(mhba->pdev, HSP_MAX_SIZE, | ||
| 2405 | &mhba->handshake_page_phys); | ||
| 1722 | if (!mhba->handshake_page) { | 2406 | if (!mhba->handshake_page) { |
| 1723 | dev_err(&mhba->pdev->dev, | 2407 | dev_err(&mhba->pdev->dev, |
| 1724 | "failed to allocate memory for handshake\n"); | 2408 | "failed to allocate memory for handshake\n"); |
| 1725 | ret = -ENOMEM; | 2409 | ret = -ENOMEM; |
| 1726 | goto fail_alloc_mem; | 2410 | goto fail_alloc_page; |
| 1727 | } | 2411 | } |
| 1728 | mhba->handshake_page_phys = virt_to_phys(mhba->handshake_page); | ||
| 1729 | 2412 | ||
| 1730 | if (mvumi_start(mhba)) { | 2413 | if (mvumi_start(mhba)) { |
| 1731 | ret = -EINVAL; | 2414 | ret = -EINVAL; |
| @@ -1739,7 +2422,10 @@ static int mvumi_init_fw(struct mvumi_hba *mhba) | |||
| 1739 | 2422 | ||
| 1740 | fail_ready_state: | 2423 | fail_ready_state: |
| 1741 | mvumi_release_mem_resource(mhba); | 2424 | mvumi_release_mem_resource(mhba); |
| 1742 | kfree(mhba->handshake_page); | 2425 | pci_free_consistent(mhba->pdev, HSP_MAX_SIZE, |
| 2426 | mhba->handshake_page, mhba->handshake_page_phys); | ||
| 2427 | fail_alloc_page: | ||
| 2428 | kfree(mhba->regs); | ||
| 1743 | fail_alloc_mem: | 2429 | fail_alloc_mem: |
| 1744 | mvumi_unmap_pci_addr(mhba->pdev, mhba->base_addr); | 2430 | mvumi_unmap_pci_addr(mhba->pdev, mhba->base_addr); |
| 1745 | fail_ioremap: | 2431 | fail_ioremap: |
| @@ -1755,6 +2441,7 @@ fail_ioremap: | |||
| 1755 | static int mvumi_io_attach(struct mvumi_hba *mhba) | 2441 | static int mvumi_io_attach(struct mvumi_hba *mhba) |
| 1756 | { | 2442 | { |
| 1757 | struct Scsi_Host *host = mhba->shost; | 2443 | struct Scsi_Host *host = mhba->shost; |
| 2444 | struct scsi_device *sdev = NULL; | ||
| 1758 | int ret; | 2445 | int ret; |
| 1759 | unsigned int max_sg = (mhba->ib_max_size + 4 - | 2446 | unsigned int max_sg = (mhba->ib_max_size + 4 - |
| 1760 | sizeof(struct mvumi_msg_frame)) / sizeof(struct mvumi_sgl); | 2447 | sizeof(struct mvumi_msg_frame)) / sizeof(struct mvumi_sgl); |
| @@ -1764,7 +2451,7 @@ static int mvumi_io_attach(struct mvumi_hba *mhba) | |||
| 1764 | host->can_queue = (mhba->max_io - 1) ? (mhba->max_io - 1) : 1; | 2451 | host->can_queue = (mhba->max_io - 1) ? (mhba->max_io - 1) : 1; |
| 1765 | host->sg_tablesize = mhba->max_sge > max_sg ? max_sg : mhba->max_sge; | 2452 | host->sg_tablesize = mhba->max_sge > max_sg ? max_sg : mhba->max_sge; |
| 1766 | host->max_sectors = mhba->max_transfer_size / 512; | 2453 | host->max_sectors = mhba->max_transfer_size / 512; |
| 1767 | host->cmd_per_lun = (mhba->max_io - 1) ? (mhba->max_io - 1) : 1; | 2454 | host->cmd_per_lun = (mhba->max_io - 1) ? (mhba->max_io - 1) : 1; |
| 1768 | host->max_id = mhba->max_target_id; | 2455 | host->max_id = mhba->max_target_id; |
| 1769 | host->max_cmd_len = MAX_COMMAND_SIZE; | 2456 | host->max_cmd_len = MAX_COMMAND_SIZE; |
| 1770 | host->transportt = &mvumi_transport_template; | 2457 | host->transportt = &mvumi_transport_template; |
| @@ -1775,9 +2462,43 @@ static int mvumi_io_attach(struct mvumi_hba *mhba) | |||
| 1775 | return ret; | 2462 | return ret; |
| 1776 | } | 2463 | } |
| 1777 | mhba->fw_flag |= MVUMI_FW_ATTACH; | 2464 | mhba->fw_flag |= MVUMI_FW_ATTACH; |
| 1778 | scsi_scan_host(host); | ||
| 1779 | 2465 | ||
| 2466 | mutex_lock(&mhba->sas_discovery_mutex); | ||
| 2467 | if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580) | ||
| 2468 | ret = scsi_add_device(host, 0, mhba->max_target_id - 1, 0); | ||
| 2469 | else | ||
| 2470 | ret = 0; | ||
| 2471 | if (ret) { | ||
| 2472 | dev_err(&mhba->pdev->dev, "add virtual device failed\n"); | ||
| 2473 | mutex_unlock(&mhba->sas_discovery_mutex); | ||
| 2474 | goto fail_add_device; | ||
| 2475 | } | ||
| 2476 | |||
| 2477 | mhba->dm_thread = kthread_create(mvumi_rescan_bus, | ||
| 2478 | mhba, "mvumi_scanthread"); | ||
| 2479 | if (IS_ERR(mhba->dm_thread)) { | ||
| 2480 | dev_err(&mhba->pdev->dev, | ||
| 2481 | "failed to create device scan thread\n"); | ||
| 2482 | mutex_unlock(&mhba->sas_discovery_mutex); | ||
| 2483 | goto fail_create_thread; | ||
| 2484 | } | ||
| 2485 | atomic_set(&mhba->pnp_count, 1); | ||
| 2486 | wake_up_process(mhba->dm_thread); | ||
| 2487 | |||
| 2488 | mutex_unlock(&mhba->sas_discovery_mutex); | ||
| 1780 | return 0; | 2489 | return 0; |
| 2490 | |||
| 2491 | fail_create_thread: | ||
| 2492 | if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580) | ||
| 2493 | sdev = scsi_device_lookup(mhba->shost, 0, | ||
| 2494 | mhba->max_target_id - 1, 0); | ||
| 2495 | if (sdev) { | ||
| 2496 | scsi_remove_device(sdev); | ||
| 2497 | scsi_device_put(sdev); | ||
| 2498 | } | ||
| 2499 | fail_add_device: | ||
| 2500 | scsi_remove_host(mhba->shost); | ||
| 2501 | return ret; | ||
| 1781 | } | 2502 | } |
| 1782 | 2503 | ||
| 1783 | /** | 2504 | /** |
| @@ -1828,8 +2549,12 @@ static int __devinit mvumi_probe_one(struct pci_dev *pdev, | |||
| 1828 | INIT_LIST_HEAD(&mhba->free_ob_list); | 2549 | INIT_LIST_HEAD(&mhba->free_ob_list); |
| 1829 | INIT_LIST_HEAD(&mhba->res_list); | 2550 | INIT_LIST_HEAD(&mhba->res_list); |
| 1830 | INIT_LIST_HEAD(&mhba->waiting_req_list); | 2551 | INIT_LIST_HEAD(&mhba->waiting_req_list); |
| 2552 | mutex_init(&mhba->device_lock); | ||
| 2553 | INIT_LIST_HEAD(&mhba->mhba_dev_list); | ||
| 2554 | INIT_LIST_HEAD(&mhba->shost_dev_list); | ||
| 1831 | atomic_set(&mhba->fw_outstanding, 0); | 2555 | atomic_set(&mhba->fw_outstanding, 0); |
| 1832 | init_waitqueue_head(&mhba->int_cmd_wait_q); | 2556 | init_waitqueue_head(&mhba->int_cmd_wait_q); |
| 2557 | mutex_init(&mhba->sas_discovery_mutex); | ||
| 1833 | 2558 | ||
| 1834 | mhba->pdev = pdev; | 2559 | mhba->pdev = pdev; |
| 1835 | mhba->shost = host; | 2560 | mhba->shost = host; |
| @@ -1845,19 +2570,22 @@ static int __devinit mvumi_probe_one(struct pci_dev *pdev, | |||
| 1845 | dev_err(&pdev->dev, "failed to register IRQ\n"); | 2570 | dev_err(&pdev->dev, "failed to register IRQ\n"); |
| 1846 | goto fail_init_irq; | 2571 | goto fail_init_irq; |
| 1847 | } | 2572 | } |
| 1848 | mhba->instancet->enable_intr(mhba->mmio); | 2573 | |
| 2574 | mhba->instancet->enable_intr(mhba); | ||
| 1849 | pci_set_drvdata(pdev, mhba); | 2575 | pci_set_drvdata(pdev, mhba); |
| 1850 | 2576 | ||
| 1851 | ret = mvumi_io_attach(mhba); | 2577 | ret = mvumi_io_attach(mhba); |
| 1852 | if (ret) | 2578 | if (ret) |
| 1853 | goto fail_io_attach; | 2579 | goto fail_io_attach; |
| 2580 | |||
| 2581 | mvumi_backup_bar_addr(mhba); | ||
| 1854 | dev_dbg(&pdev->dev, "probe mvumi driver successfully.\n"); | 2582 | dev_dbg(&pdev->dev, "probe mvumi driver successfully.\n"); |
| 1855 | 2583 | ||
| 1856 | return 0; | 2584 | return 0; |
| 1857 | 2585 | ||
| 1858 | fail_io_attach: | 2586 | fail_io_attach: |
| 1859 | pci_set_drvdata(pdev, NULL); | 2587 | pci_set_drvdata(pdev, NULL); |
| 1860 | mhba->instancet->disable_intr(mhba->mmio); | 2588 | mhba->instancet->disable_intr(mhba); |
| 1861 | free_irq(mhba->pdev->irq, mhba); | 2589 | free_irq(mhba->pdev->irq, mhba); |
| 1862 | fail_init_irq: | 2590 | fail_init_irq: |
| 1863 | mvumi_release_fw(mhba); | 2591 | mvumi_release_fw(mhba); |
| @@ -1877,11 +2605,17 @@ static void mvumi_detach_one(struct pci_dev *pdev) | |||
| 1877 | struct mvumi_hba *mhba; | 2605 | struct mvumi_hba *mhba; |
| 1878 | 2606 | ||
| 1879 | mhba = pci_get_drvdata(pdev); | 2607 | mhba = pci_get_drvdata(pdev); |
| 2608 | if (mhba->dm_thread) { | ||
| 2609 | kthread_stop(mhba->dm_thread); | ||
| 2610 | mhba->dm_thread = NULL; | ||
| 2611 | } | ||
| 2612 | |||
| 2613 | mvumi_detach_devices(mhba); | ||
| 1880 | host = mhba->shost; | 2614 | host = mhba->shost; |
| 1881 | scsi_remove_host(mhba->shost); | 2615 | scsi_remove_host(mhba->shost); |
| 1882 | mvumi_flush_cache(mhba); | 2616 | mvumi_flush_cache(mhba); |
| 1883 | 2617 | ||
| 1884 | mhba->instancet->disable_intr(mhba->mmio); | 2618 | mhba->instancet->disable_intr(mhba); |
| 1885 | free_irq(mhba->pdev->irq, mhba); | 2619 | free_irq(mhba->pdev->irq, mhba); |
| 1886 | mvumi_release_fw(mhba); | 2620 | mvumi_release_fw(mhba); |
| 1887 | scsi_host_put(host); | 2621 | scsi_host_put(host); |
| @@ -1909,7 +2643,7 @@ static int mvumi_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 1909 | mvumi_flush_cache(mhba); | 2643 | mvumi_flush_cache(mhba); |
| 1910 | 2644 | ||
| 1911 | pci_set_drvdata(pdev, mhba); | 2645 | pci_set_drvdata(pdev, mhba); |
| 1912 | mhba->instancet->disable_intr(mhba->mmio); | 2646 | mhba->instancet->disable_intr(mhba); |
| 1913 | free_irq(mhba->pdev->irq, mhba); | 2647 | free_irq(mhba->pdev->irq, mhba); |
| 1914 | mvumi_unmap_pci_addr(pdev, mhba->base_addr); | 2648 | mvumi_unmap_pci_addr(pdev, mhba->base_addr); |
| 1915 | pci_release_regions(pdev); | 2649 | pci_release_regions(pdev); |
| @@ -1956,8 +2690,13 @@ static int mvumi_resume(struct pci_dev *pdev) | |||
| 1956 | if (ret) | 2690 | if (ret) |
| 1957 | goto release_regions; | 2691 | goto release_regions; |
| 1958 | 2692 | ||
| 2693 | if (mvumi_cfg_hw_reg(mhba)) { | ||
| 2694 | ret = -EINVAL; | ||
| 2695 | goto unmap_pci_addr; | ||
| 2696 | } | ||
| 2697 | |||
| 1959 | mhba->mmio = mhba->base_addr[0]; | 2698 | mhba->mmio = mhba->base_addr[0]; |
| 1960 | mvumi_reset(mhba->mmio); | 2699 | mvumi_reset(mhba); |
| 1961 | 2700 | ||
| 1962 | if (mvumi_start(mhba)) { | 2701 | if (mvumi_start(mhba)) { |
| 1963 | ret = -EINVAL; | 2702 | ret = -EINVAL; |
| @@ -1970,7 +2709,7 @@ static int mvumi_resume(struct pci_dev *pdev) | |||
| 1970 | dev_err(&pdev->dev, "failed to register IRQ\n"); | 2709 | dev_err(&pdev->dev, "failed to register IRQ\n"); |
| 1971 | goto unmap_pci_addr; | 2710 | goto unmap_pci_addr; |
| 1972 | } | 2711 | } |
| 1973 | mhba->instancet->enable_intr(mhba->mmio); | 2712 | mhba->instancet->enable_intr(mhba); |
| 1974 | 2713 | ||
| 1975 | return 0; | 2714 | return 0; |
| 1976 | 2715 | ||
diff --git a/drivers/scsi/mvumi.h b/drivers/scsi/mvumi.h index 10b9237566f0..e360135fd1bd 100644 --- a/drivers/scsi/mvumi.h +++ b/drivers/scsi/mvumi.h | |||
| @@ -34,51 +34,87 @@ | |||
| 34 | #define MV_DRIVER_NAME "mvumi" | 34 | #define MV_DRIVER_NAME "mvumi" |
| 35 | #define PCI_VENDOR_ID_MARVELL_2 0x1b4b | 35 | #define PCI_VENDOR_ID_MARVELL_2 0x1b4b |
| 36 | #define PCI_DEVICE_ID_MARVELL_MV9143 0x9143 | 36 | #define PCI_DEVICE_ID_MARVELL_MV9143 0x9143 |
| 37 | #define PCI_DEVICE_ID_MARVELL_MV9580 0x9580 | ||
| 37 | 38 | ||
| 38 | #define MVUMI_INTERNAL_CMD_WAIT_TIME 45 | 39 | #define MVUMI_INTERNAL_CMD_WAIT_TIME 45 |
| 40 | #define MVUMI_INQUIRY_LENGTH 44 | ||
| 41 | #define MVUMI_INQUIRY_UUID_OFF 36 | ||
| 42 | #define MVUMI_INQUIRY_UUID_LEN 8 | ||
| 39 | 43 | ||
| 40 | #define IS_DMA64 (sizeof(dma_addr_t) == 8) | 44 | #define IS_DMA64 (sizeof(dma_addr_t) == 8) |
| 41 | 45 | ||
| 42 | enum mvumi_qc_result { | 46 | enum mvumi_qc_result { |
| 43 | MV_QUEUE_COMMAND_RESULT_SENT = 0, | 47 | MV_QUEUE_COMMAND_RESULT_SENT = 0, |
| 44 | MV_QUEUE_COMMAND_RESULT_NO_RESOURCE, | 48 | MV_QUEUE_COMMAND_RESULT_NO_RESOURCE, |
| 45 | }; | 49 | }; |
| 46 | 50 | ||
| 47 | enum { | 51 | struct mvumi_hw_regs { |
| 48 | /*******************************************/ | 52 | /* For CPU */ |
| 49 | 53 | void *main_int_cause_reg; | |
| 50 | /* ARM Mbus Registers Map */ | 54 | void *enpointa_mask_reg; |
| 51 | 55 | void *enpointb_mask_reg; | |
| 52 | /*******************************************/ | 56 | void *rstoutn_en_reg; |
| 53 | CPU_MAIN_INT_CAUSE_REG = 0x20200, | 57 | void *ctrl_sts_reg; |
| 54 | CPU_MAIN_IRQ_MASK_REG = 0x20204, | 58 | void *rstoutn_mask_reg; |
| 55 | CPU_MAIN_FIQ_MASK_REG = 0x20208, | 59 | void *sys_soft_rst_reg; |
| 56 | CPU_ENPOINTA_MASK_REG = 0x2020C, | 60 | |
| 57 | CPU_ENPOINTB_MASK_REG = 0x20210, | 61 | /* For Doorbell */ |
| 58 | 62 | void *pciea_to_arm_drbl_reg; | |
| 59 | INT_MAP_COMAERR = 1 << 6, | 63 | void *arm_to_pciea_drbl_reg; |
| 60 | INT_MAP_COMAIN = 1 << 7, | 64 | void *arm_to_pciea_mask_reg; |
| 61 | INT_MAP_COMAOUT = 1 << 8, | 65 | void *pciea_to_arm_msg0; |
| 62 | INT_MAP_COMBERR = 1 << 9, | 66 | void *pciea_to_arm_msg1; |
| 63 | INT_MAP_COMBIN = 1 << 10, | 67 | void *arm_to_pciea_msg0; |
| 64 | INT_MAP_COMBOUT = 1 << 11, | 68 | void *arm_to_pciea_msg1; |
| 65 | 69 | ||
| 66 | INT_MAP_COMAINT = (INT_MAP_COMAOUT | INT_MAP_COMAERR), | 70 | /* reset register */ |
| 67 | INT_MAP_COMBINT = (INT_MAP_COMBOUT | INT_MAP_COMBIN | INT_MAP_COMBERR), | 71 | void *reset_request; |
| 68 | 72 | void *reset_enable; | |
| 69 | INT_MAP_DL_PCIEA2CPU = 1 << 0, | 73 | |
| 70 | INT_MAP_DL_CPU2PCIEA = 1 << 1, | 74 | /* For Message Unit */ |
| 71 | 75 | void *inb_list_basel; | |
| 72 | /***************************************/ | 76 | void *inb_list_baseh; |
| 77 | void *inb_aval_count_basel; | ||
| 78 | void *inb_aval_count_baseh; | ||
| 79 | void *inb_write_pointer; | ||
| 80 | void *inb_read_pointer; | ||
| 81 | void *outb_list_basel; | ||
| 82 | void *outb_list_baseh; | ||
| 83 | void *outb_copy_basel; | ||
| 84 | void *outb_copy_baseh; | ||
| 85 | void *outb_copy_pointer; | ||
| 86 | void *outb_read_pointer; | ||
| 87 | void *inb_isr_cause; | ||
| 88 | void *outb_isr_cause; | ||
| 89 | void *outb_coal_cfg; | ||
| 90 | void *outb_coal_timeout; | ||
| 91 | |||
| 92 | /* Bit setting for HW */ | ||
| 93 | u32 int_comaout; | ||
| 94 | u32 int_comaerr; | ||
| 95 | u32 int_dl_cpu2pciea; | ||
| 96 | u32 int_mu; | ||
| 97 | u32 int_drbl_int_mask; | ||
| 98 | u32 int_main_int_mask; | ||
| 99 | u32 cl_pointer_toggle; | ||
| 100 | u32 cl_slot_num_mask; | ||
| 101 | u32 clic_irq; | ||
| 102 | u32 clic_in_err; | ||
| 103 | u32 clic_out_err; | ||
| 104 | }; | ||
| 73 | 105 | ||
| 74 | /* ARM Doorbell Registers Map */ | 106 | struct mvumi_dyn_list_entry { |
| 107 | u32 src_low_addr; | ||
| 108 | u32 src_high_addr; | ||
| 109 | u32 if_length; | ||
| 110 | u32 reserve; | ||
| 111 | }; | ||
| 75 | 112 | ||
| 76 | /***************************************/ | 113 | #define SCSI_CMD_MARVELL_SPECIFIC 0xE1 |
| 77 | CPU_PCIEA_TO_ARM_DRBL_REG = 0x20400, | 114 | #define CDB_CORE_MODULE 0x1 |
| 78 | CPU_PCIEA_TO_ARM_MASK_REG = 0x20404, | 115 | #define CDB_CORE_SHUTDOWN 0xB |
| 79 | CPU_ARM_TO_PCIEA_DRBL_REG = 0x20408, | ||
| 80 | CPU_ARM_TO_PCIEA_MASK_REG = 0x2040C, | ||
| 81 | 116 | ||
| 117 | enum { | ||
| 82 | DRBL_HANDSHAKE = 1 << 0, | 118 | DRBL_HANDSHAKE = 1 << 0, |
| 83 | DRBL_SOFT_RESET = 1 << 1, | 119 | DRBL_SOFT_RESET = 1 << 1, |
| 84 | DRBL_BUS_CHANGE = 1 << 2, | 120 | DRBL_BUS_CHANGE = 1 << 2, |
| @@ -86,46 +122,6 @@ enum { | |||
| 86 | DRBL_MU_RESET = 1 << 4, | 122 | DRBL_MU_RESET = 1 << 4, |
| 87 | DRBL_HANDSHAKE_ISR = DRBL_HANDSHAKE, | 123 | DRBL_HANDSHAKE_ISR = DRBL_HANDSHAKE, |
| 88 | 124 | ||
| 89 | CPU_PCIEA_TO_ARM_MSG0 = 0x20430, | ||
| 90 | CPU_PCIEA_TO_ARM_MSG1 = 0x20434, | ||
| 91 | CPU_ARM_TO_PCIEA_MSG0 = 0x20438, | ||
| 92 | CPU_ARM_TO_PCIEA_MSG1 = 0x2043C, | ||
| 93 | |||
| 94 | /*******************************************/ | ||
| 95 | |||
| 96 | /* ARM Communication List Registers Map */ | ||
| 97 | |||
| 98 | /*******************************************/ | ||
| 99 | CLA_INB_LIST_BASEL = 0x500, | ||
| 100 | CLA_INB_LIST_BASEH = 0x504, | ||
| 101 | CLA_INB_AVAL_COUNT_BASEL = 0x508, | ||
| 102 | CLA_INB_AVAL_COUNT_BASEH = 0x50C, | ||
| 103 | CLA_INB_DESTI_LIST_BASEL = 0x510, | ||
| 104 | CLA_INB_DESTI_LIST_BASEH = 0x514, | ||
| 105 | CLA_INB_WRITE_POINTER = 0x518, | ||
| 106 | CLA_INB_READ_POINTER = 0x51C, | ||
| 107 | |||
| 108 | CLA_OUTB_LIST_BASEL = 0x530, | ||
| 109 | CLA_OUTB_LIST_BASEH = 0x534, | ||
| 110 | CLA_OUTB_SOURCE_LIST_BASEL = 0x538, | ||
| 111 | CLA_OUTB_SOURCE_LIST_BASEH = 0x53C, | ||
| 112 | CLA_OUTB_COPY_POINTER = 0x544, | ||
| 113 | CLA_OUTB_READ_POINTER = 0x548, | ||
| 114 | |||
| 115 | CLA_ISR_CAUSE = 0x560, | ||
| 116 | CLA_ISR_MASK = 0x564, | ||
| 117 | |||
| 118 | INT_MAP_MU = (INT_MAP_DL_CPU2PCIEA | INT_MAP_COMAINT), | ||
| 119 | |||
| 120 | CL_POINTER_TOGGLE = 1 << 12, | ||
| 121 | |||
| 122 | CLIC_IN_IRQ = 1 << 0, | ||
| 123 | CLIC_OUT_IRQ = 1 << 1, | ||
| 124 | CLIC_IN_ERR_IRQ = 1 << 8, | ||
| 125 | CLIC_OUT_ERR_IRQ = 1 << 12, | ||
| 126 | |||
| 127 | CL_SLOT_NUM_MASK = 0xFFF, | ||
| 128 | |||
| 129 | /* | 125 | /* |
| 130 | * Command flag is the flag for the CDB command itself | 126 | * Command flag is the flag for the CDB command itself |
| 131 | */ | 127 | */ |
| @@ -137,15 +133,23 @@ enum { | |||
| 137 | CMD_FLAG_DATA_IN = 1 << 3, | 133 | CMD_FLAG_DATA_IN = 1 << 3, |
| 138 | /* 1-host write data */ | 134 | /* 1-host write data */ |
| 139 | CMD_FLAG_DATA_OUT = 1 << 4, | 135 | CMD_FLAG_DATA_OUT = 1 << 4, |
| 140 | 136 | CMD_FLAG_PRDT_IN_HOST = 1 << 5, | |
| 141 | SCSI_CMD_MARVELL_SPECIFIC = 0xE1, | ||
| 142 | CDB_CORE_SHUTDOWN = 0xB, | ||
| 143 | }; | 137 | }; |
| 144 | 138 | ||
| 145 | #define APICDB0_EVENT 0xF4 | 139 | #define APICDB0_EVENT 0xF4 |
| 146 | #define APICDB1_EVENT_GETEVENT 0 | 140 | #define APICDB1_EVENT_GETEVENT 0 |
| 141 | #define APICDB1_HOST_GETEVENT 1 | ||
| 147 | #define MAX_EVENTS_RETURNED 6 | 142 | #define MAX_EVENTS_RETURNED 6 |
| 148 | 143 | ||
| 144 | #define DEVICE_OFFLINE 0 | ||
| 145 | #define DEVICE_ONLINE 1 | ||
| 146 | |||
| 147 | struct mvumi_hotplug_event { | ||
| 148 | u16 size; | ||
| 149 | u8 dummy[2]; | ||
| 150 | u8 bitmap[0]; | ||
| 151 | }; | ||
| 152 | |||
| 149 | struct mvumi_driver_event { | 153 | struct mvumi_driver_event { |
| 150 | u32 time_stamp; | 154 | u32 time_stamp; |
| 151 | u32 sequence_no; | 155 | u32 sequence_no; |
| @@ -172,8 +176,14 @@ struct mvumi_events_wq { | |||
| 172 | void *param; | 176 | void *param; |
| 173 | }; | 177 | }; |
| 174 | 178 | ||
| 179 | #define HS_CAPABILITY_SUPPORT_COMPACT_SG (1U << 4) | ||
| 180 | #define HS_CAPABILITY_SUPPORT_PRD_HOST (1U << 5) | ||
| 181 | #define HS_CAPABILITY_SUPPORT_DYN_SRC (1U << 6) | ||
| 182 | #define HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF (1U << 14) | ||
| 183 | |||
| 175 | #define MVUMI_MAX_SG_ENTRY 32 | 184 | #define MVUMI_MAX_SG_ENTRY 32 |
| 176 | #define SGD_EOT (1L << 27) | 185 | #define SGD_EOT (1L << 27) |
| 186 | #define SGD_EOT_CP (1L << 22) | ||
| 177 | 187 | ||
| 178 | struct mvumi_sgl { | 188 | struct mvumi_sgl { |
| 179 | u32 baseaddr_l; | 189 | u32 baseaddr_l; |
| @@ -181,6 +191,39 @@ struct mvumi_sgl { | |||
| 181 | u32 flags; | 191 | u32 flags; |
| 182 | u32 size; | 192 | u32 size; |
| 183 | }; | 193 | }; |
| 194 | struct mvumi_compact_sgl { | ||
| 195 | u32 baseaddr_l; | ||
| 196 | u32 baseaddr_h; | ||
| 197 | u32 flags; | ||
| 198 | }; | ||
| 199 | |||
| 200 | #define GET_COMPACT_SGD_SIZE(sgd) \ | ||
| 201 | ((((struct mvumi_compact_sgl *)(sgd))->flags) & 0x3FFFFFL) | ||
| 202 | |||
| 203 | #define SET_COMPACT_SGD_SIZE(sgd, sz) do { \ | ||
| 204 | (((struct mvumi_compact_sgl *)(sgd))->flags) &= ~0x3FFFFFL; \ | ||
| 205 | (((struct mvumi_compact_sgl *)(sgd))->flags) |= (sz); \ | ||
| 206 | } while (0) | ||
| 207 | #define sgd_getsz(_mhba, sgd, sz) do { \ | ||
| 208 | if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \ | ||
| 209 | (sz) = GET_COMPACT_SGD_SIZE(sgd); \ | ||
| 210 | else \ | ||
| 211 | (sz) = (sgd)->size; \ | ||
| 212 | } while (0) | ||
| 213 | |||
| 214 | #define sgd_setsz(_mhba, sgd, sz) do { \ | ||
| 215 | if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \ | ||
| 216 | SET_COMPACT_SGD_SIZE(sgd, sz); \ | ||
| 217 | else \ | ||
| 218 | (sgd)->size = (sz); \ | ||
| 219 | } while (0) | ||
| 220 | |||
| 221 | #define sgd_inc(_mhba, sgd) do { \ | ||
| 222 | if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \ | ||
| 223 | sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 12); \ | ||
| 224 | else \ | ||
| 225 | sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 16); \ | ||
| 226 | } while (0) | ||
| 184 | 227 | ||
| 185 | struct mvumi_res { | 228 | struct mvumi_res { |
| 186 | struct list_head entry; | 229 | struct list_head entry; |
| @@ -197,7 +240,7 @@ enum resource_type { | |||
| 197 | }; | 240 | }; |
| 198 | 241 | ||
| 199 | struct mvumi_sense_data { | 242 | struct mvumi_sense_data { |
| 200 | u8 error_eode:7; | 243 | u8 error_code:7; |
| 201 | u8 valid:1; | 244 | u8 valid:1; |
| 202 | u8 segment_number; | 245 | u8 segment_number; |
| 203 | u8 sense_key:4; | 246 | u8 sense_key:4; |
| @@ -220,6 +263,7 @@ struct mvumi_sense_data { | |||
| 220 | struct mvumi_cmd { | 263 | struct mvumi_cmd { |
| 221 | struct list_head queue_pointer; | 264 | struct list_head queue_pointer; |
| 222 | struct mvumi_msg_frame *frame; | 265 | struct mvumi_msg_frame *frame; |
| 266 | dma_addr_t frame_phys; | ||
| 223 | struct scsi_cmnd *scmd; | 267 | struct scsi_cmnd *scmd; |
| 224 | atomic_t sync_cmd; | 268 | atomic_t sync_cmd; |
| 225 | void *data_buf; | 269 | void *data_buf; |
| @@ -393,7 +437,8 @@ struct mvumi_hs_page2 { | |||
| 393 | u16 frame_length; | 437 | u16 frame_length; |
| 394 | 438 | ||
| 395 | u8 host_type; | 439 | u8 host_type; |
| 396 | u8 reserved[3]; | 440 | u8 host_cap; |
| 441 | u8 reserved[2]; | ||
| 397 | struct version_info host_ver; | 442 | struct version_info host_ver; |
| 398 | u32 system_io_bus; | 443 | u32 system_io_bus; |
| 399 | u32 slot_number; | 444 | u32 slot_number; |
| @@ -435,8 +480,17 @@ struct mvumi_tag { | |||
| 435 | unsigned short size; | 480 | unsigned short size; |
| 436 | }; | 481 | }; |
| 437 | 482 | ||
| 483 | struct mvumi_device { | ||
| 484 | struct list_head list; | ||
| 485 | struct scsi_device *sdev; | ||
| 486 | u64 wwid; | ||
| 487 | u8 dev_type; | ||
| 488 | int id; | ||
| 489 | }; | ||
| 490 | |||
| 438 | struct mvumi_hba { | 491 | struct mvumi_hba { |
| 439 | void *base_addr[MAX_BASE_ADDRESS]; | 492 | void *base_addr[MAX_BASE_ADDRESS]; |
| 493 | u32 pci_base[MAX_BASE_ADDRESS]; | ||
| 440 | void *mmio; | 494 | void *mmio; |
| 441 | struct list_head cmd_pool; | 495 | struct list_head cmd_pool; |
| 442 | struct Scsi_Host *shost; | 496 | struct Scsi_Host *shost; |
| @@ -449,6 +503,9 @@ struct mvumi_hba { | |||
| 449 | void *ib_list; | 503 | void *ib_list; |
| 450 | dma_addr_t ib_list_phys; | 504 | dma_addr_t ib_list_phys; |
| 451 | 505 | ||
| 506 | void *ib_frame; | ||
| 507 | dma_addr_t ib_frame_phys; | ||
| 508 | |||
| 452 | void *ob_list; | 509 | void *ob_list; |
| 453 | dma_addr_t ob_list_phys; | 510 | dma_addr_t ob_list_phys; |
| 454 | 511 | ||
| @@ -477,12 +534,14 @@ struct mvumi_hba { | |||
| 477 | unsigned char hba_total_pages; | 534 | unsigned char hba_total_pages; |
| 478 | unsigned char fw_flag; | 535 | unsigned char fw_flag; |
| 479 | unsigned char request_id_enabled; | 536 | unsigned char request_id_enabled; |
| 537 | unsigned char eot_flag; | ||
| 480 | unsigned short hba_capability; | 538 | unsigned short hba_capability; |
| 481 | unsigned short io_seq; | 539 | unsigned short io_seq; |
| 482 | 540 | ||
| 483 | unsigned int ib_cur_slot; | 541 | unsigned int ib_cur_slot; |
| 484 | unsigned int ob_cur_slot; | 542 | unsigned int ob_cur_slot; |
| 485 | unsigned int fw_state; | 543 | unsigned int fw_state; |
| 544 | struct mutex sas_discovery_mutex; | ||
| 486 | 545 | ||
| 487 | struct list_head ob_data_list; | 546 | struct list_head ob_data_list; |
| 488 | struct list_head free_ob_list; | 547 | struct list_head free_ob_list; |
| @@ -491,14 +550,24 @@ struct mvumi_hba { | |||
| 491 | 550 | ||
| 492 | struct mvumi_tag tag_pool; | 551 | struct mvumi_tag tag_pool; |
| 493 | struct mvumi_cmd **tag_cmd; | 552 | struct mvumi_cmd **tag_cmd; |
| 553 | struct mvumi_hw_regs *regs; | ||
| 554 | struct mutex device_lock; | ||
| 555 | struct list_head mhba_dev_list; | ||
| 556 | struct list_head shost_dev_list; | ||
| 557 | struct task_struct *dm_thread; | ||
| 558 | atomic_t pnp_count; | ||
| 494 | }; | 559 | }; |
| 495 | 560 | ||
| 496 | struct mvumi_instance_template { | 561 | struct mvumi_instance_template { |
| 497 | void (*fire_cmd)(struct mvumi_hba *, struct mvumi_cmd *); | 562 | void (*fire_cmd) (struct mvumi_hba *, struct mvumi_cmd *); |
| 498 | void (*enable_intr)(void *) ; | 563 | void (*enable_intr) (struct mvumi_hba *); |
| 499 | void (*disable_intr)(void *); | 564 | void (*disable_intr) (struct mvumi_hba *); |
| 500 | int (*clear_intr)(void *); | 565 | int (*clear_intr) (void *); |
| 501 | unsigned int (*read_fw_status_reg)(void *); | 566 | unsigned int (*read_fw_status_reg) (struct mvumi_hba *); |
| 567 | unsigned int (*check_ib_list) (struct mvumi_hba *); | ||
| 568 | int (*check_ob_list) (struct mvumi_hba *, unsigned int *, | ||
| 569 | unsigned int *); | ||
| 570 | int (*reset_host) (struct mvumi_hba *); | ||
| 502 | }; | 571 | }; |
| 503 | 572 | ||
| 504 | extern struct timezone sys_tz; | 573 | extern struct timezone sys_tz; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 799a58bb9859..48fca47384b7 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -2080,6 +2080,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha) | |||
| 2080 | uint8_t domain; | 2080 | uint8_t domain; |
| 2081 | char connect_type[22]; | 2081 | char connect_type[22]; |
| 2082 | struct qla_hw_data *ha = vha->hw; | 2082 | struct qla_hw_data *ha = vha->hw; |
| 2083 | unsigned long flags; | ||
| 2083 | 2084 | ||
| 2084 | /* Get host addresses. */ | 2085 | /* Get host addresses. */ |
| 2085 | rval = qla2x00_get_adapter_id(vha, | 2086 | rval = qla2x00_get_adapter_id(vha, |
| @@ -2154,9 +2155,9 @@ qla2x00_configure_hba(scsi_qla_host_t *vha) | |||
| 2154 | vha->d_id.b.area = area; | 2155 | vha->d_id.b.area = area; |
| 2155 | vha->d_id.b.al_pa = al_pa; | 2156 | vha->d_id.b.al_pa = al_pa; |
| 2156 | 2157 | ||
| 2157 | spin_lock(&ha->vport_slock); | 2158 | spin_lock_irqsave(&ha->vport_slock, flags); |
| 2158 | qlt_update_vp_map(vha, SET_AL_PA); | 2159 | qlt_update_vp_map(vha, SET_AL_PA); |
| 2159 | spin_unlock(&ha->vport_slock); | 2160 | spin_unlock_irqrestore(&ha->vport_slock, flags); |
| 2160 | 2161 | ||
| 2161 | if (!vha->flags.init_done) | 2162 | if (!vha->flags.init_done) |
| 2162 | ql_log(ql_log_info, vha, 0x2010, | 2163 | ql_log(ql_log_info, vha, 0x2010, |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 57fbd5a3d4e2..5cda11c07c68 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
| @@ -2055,7 +2055,7 @@ static void unmap_region(sector_t lba, unsigned int len) | |||
| 2055 | block = lba + alignment; | 2055 | block = lba + alignment; |
| 2056 | rem = do_div(block, granularity); | 2056 | rem = do_div(block, granularity); |
| 2057 | 2057 | ||
| 2058 | if (rem == 0 && lba + granularity <= end && block < map_size) { | 2058 | if (rem == 0 && lba + granularity < end && block < map_size) { |
| 2059 | clear_bit(block, map_storep); | 2059 | clear_bit(block, map_storep); |
| 2060 | if (scsi_debug_lbprz) | 2060 | if (scsi_debug_lbprz) |
| 2061 | memset(fake_storep + | 2061 | memset(fake_storep + |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index de2337f255a7..c1b05a83d403 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
| @@ -789,7 +789,6 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
| 789 | int cmnd_size, int timeout, unsigned sense_bytes) | 789 | int cmnd_size, int timeout, unsigned sense_bytes) |
| 790 | { | 790 | { |
| 791 | struct scsi_device *sdev = scmd->device; | 791 | struct scsi_device *sdev = scmd->device; |
| 792 | struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd); | ||
| 793 | struct Scsi_Host *shost = sdev->host; | 792 | struct Scsi_Host *shost = sdev->host; |
| 794 | DECLARE_COMPLETION_ONSTACK(done); | 793 | DECLARE_COMPLETION_ONSTACK(done); |
| 795 | unsigned long timeleft; | 794 | unsigned long timeleft; |
| @@ -845,8 +844,11 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
| 845 | 844 | ||
| 846 | scsi_eh_restore_cmnd(scmd, &ses); | 845 | scsi_eh_restore_cmnd(scmd, &ses); |
| 847 | 846 | ||
| 848 | if (sdrv && sdrv->eh_action) | 847 | if (scmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { |
| 849 | rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn); | 848 | struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd); |
| 849 | if (sdrv->eh_action) | ||
| 850 | rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn); | ||
| 851 | } | ||
| 850 | 852 | ||
| 851 | return rtn; | 853 | return rtn; |
| 852 | } | 854 | } |
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 528d52beaa1c..01440782feb2 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c | |||
| @@ -1221,7 +1221,12 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) | |||
| 1221 | /* | 1221 | /* |
| 1222 | * At this point, all outstanding requests in the adapter | 1222 | * At this point, all outstanding requests in the adapter |
| 1223 | * should have been flushed out and return to us | 1223 | * should have been flushed out and return to us |
| 1224 | * There is a potential race here where the host may be in | ||
| 1225 | * the process of responding when we return from here. | ||
| 1226 | * Just wait for all in-transit packets to be accounted for | ||
| 1227 | * before we return from here. | ||
| 1224 | */ | 1228 | */ |
| 1229 | storvsc_wait_to_drain(stor_device); | ||
| 1225 | 1230 | ||
| 1226 | return SUCCESS; | 1231 | return SUCCESS; |
| 1227 | } | 1232 | } |
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 3e79a2f00042..595af1ae4421 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
| @@ -219,7 +219,7 @@ static int virtscsi_kick_event(struct virtio_scsi *vscsi, | |||
| 219 | struct scatterlist sg; | 219 | struct scatterlist sg; |
| 220 | unsigned long flags; | 220 | unsigned long flags; |
| 221 | 221 | ||
| 222 | sg_set_buf(&sg, &event_node->event, sizeof(struct virtio_scsi_event)); | 222 | sg_init_one(&sg, &event_node->event, sizeof(struct virtio_scsi_event)); |
| 223 | 223 | ||
| 224 | spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags); | 224 | spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags); |
| 225 | 225 | ||
| @@ -279,6 +279,31 @@ static void virtscsi_handle_transport_reset(struct virtio_scsi *vscsi, | |||
| 279 | } | 279 | } |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | static void virtscsi_handle_param_change(struct virtio_scsi *vscsi, | ||
| 283 | struct virtio_scsi_event *event) | ||
| 284 | { | ||
| 285 | struct scsi_device *sdev; | ||
| 286 | struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev); | ||
| 287 | unsigned int target = event->lun[1]; | ||
| 288 | unsigned int lun = (event->lun[2] << 8) | event->lun[3]; | ||
| 289 | u8 asc = event->reason & 255; | ||
| 290 | u8 ascq = event->reason >> 8; | ||
| 291 | |||
| 292 | sdev = scsi_device_lookup(shost, 0, target, lun); | ||
| 293 | if (!sdev) { | ||
| 294 | pr_err("SCSI device %d 0 %d %d not found\n", | ||
| 295 | shost->host_no, target, lun); | ||
| 296 | return; | ||
| 297 | } | ||
| 298 | |||
| 299 | /* Handle "Parameters changed", "Mode parameters changed", and | ||
| 300 | "Capacity data has changed". */ | ||
| 301 | if (asc == 0x2a && (ascq == 0x00 || ascq == 0x01 || ascq == 0x09)) | ||
| 302 | scsi_rescan_device(&sdev->sdev_gendev); | ||
| 303 | |||
| 304 | scsi_device_put(sdev); | ||
| 305 | } | ||
| 306 | |||
| 282 | static void virtscsi_handle_event(struct work_struct *work) | 307 | static void virtscsi_handle_event(struct work_struct *work) |
| 283 | { | 308 | { |
| 284 | struct virtio_scsi_event_node *event_node = | 309 | struct virtio_scsi_event_node *event_node = |
| @@ -297,6 +322,9 @@ static void virtscsi_handle_event(struct work_struct *work) | |||
| 297 | case VIRTIO_SCSI_T_TRANSPORT_RESET: | 322 | case VIRTIO_SCSI_T_TRANSPORT_RESET: |
| 298 | virtscsi_handle_transport_reset(vscsi, event); | 323 | virtscsi_handle_transport_reset(vscsi, event); |
| 299 | break; | 324 | break; |
| 325 | case VIRTIO_SCSI_T_PARAM_CHANGE: | ||
| 326 | virtscsi_handle_param_change(vscsi, event); | ||
| 327 | break; | ||
| 300 | default: | 328 | default: |
| 301 | pr_err("Unsupport virtio scsi event %x\n", event->event); | 329 | pr_err("Unsupport virtio scsi event %x\n", event->event); |
| 302 | } | 330 | } |
| @@ -677,7 +705,11 @@ static int __devinit virtscsi_probe(struct virtio_device *vdev) | |||
| 677 | cmd_per_lun = virtscsi_config_get(vdev, cmd_per_lun) ?: 1; | 705 | cmd_per_lun = virtscsi_config_get(vdev, cmd_per_lun) ?: 1; |
| 678 | shost->cmd_per_lun = min_t(u32, cmd_per_lun, shost->can_queue); | 706 | shost->cmd_per_lun = min_t(u32, cmd_per_lun, shost->can_queue); |
| 679 | shost->max_sectors = virtscsi_config_get(vdev, max_sectors) ?: 0xFFFF; | 707 | shost->max_sectors = virtscsi_config_get(vdev, max_sectors) ?: 0xFFFF; |
| 680 | shost->max_lun = virtscsi_config_get(vdev, max_lun) + 1; | 708 | |
| 709 | /* LUNs > 256 are reported with format 1, so they go in the range | ||
| 710 | * 16640-32767. | ||
| 711 | */ | ||
| 712 | shost->max_lun = virtscsi_config_get(vdev, max_lun) + 1 + 0x4000; | ||
| 681 | shost->max_id = num_targets; | 713 | shost->max_id = num_targets; |
| 682 | shost->max_channel = 0; | 714 | shost->max_channel = 0; |
| 683 | shost->max_cmd_len = VIRTIO_SCSI_CDB_SIZE; | 715 | shost->max_cmd_len = VIRTIO_SCSI_CDB_SIZE; |
| @@ -733,7 +765,8 @@ static struct virtio_device_id id_table[] = { | |||
| 733 | }; | 765 | }; |
| 734 | 766 | ||
| 735 | static unsigned int features[] = { | 767 | static unsigned int features[] = { |
| 736 | VIRTIO_SCSI_F_HOTPLUG | 768 | VIRTIO_SCSI_F_HOTPLUG, |
| 769 | VIRTIO_SCSI_F_CHANGE, | ||
| 737 | }; | 770 | }; |
| 738 | 771 | ||
| 739 | static struct virtio_driver virtio_scsi_driver = { | 772 | static struct virtio_driver virtio_scsi_driver = { |
diff --git a/include/linux/virtio_scsi.h b/include/linux/virtio_scsi.h index dc8d305b0e05..d6b4440387b7 100644 --- a/include/linux/virtio_scsi.h +++ b/include/linux/virtio_scsi.h | |||
| @@ -72,6 +72,7 @@ struct virtio_scsi_config { | |||
| 72 | /* Feature Bits */ | 72 | /* Feature Bits */ |
| 73 | #define VIRTIO_SCSI_F_INOUT 0 | 73 | #define VIRTIO_SCSI_F_INOUT 0 |
| 74 | #define VIRTIO_SCSI_F_HOTPLUG 1 | 74 | #define VIRTIO_SCSI_F_HOTPLUG 1 |
| 75 | #define VIRTIO_SCSI_F_CHANGE 2 | ||
| 75 | 76 | ||
| 76 | /* Response codes */ | 77 | /* Response codes */ |
| 77 | #define VIRTIO_SCSI_S_OK 0 | 78 | #define VIRTIO_SCSI_S_OK 0 |
| @@ -108,6 +109,7 @@ struct virtio_scsi_config { | |||
| 108 | #define VIRTIO_SCSI_T_NO_EVENT 0 | 109 | #define VIRTIO_SCSI_T_NO_EVENT 0 |
| 109 | #define VIRTIO_SCSI_T_TRANSPORT_RESET 1 | 110 | #define VIRTIO_SCSI_T_TRANSPORT_RESET 1 |
| 110 | #define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 | 111 | #define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 |
| 112 | #define VIRTIO_SCSI_T_PARAM_CHANGE 3 | ||
| 111 | 113 | ||
| 112 | /* Reasons of transport reset event */ | 114 | /* Reasons of transport reset event */ |
| 113 | #define VIRTIO_SCSI_EVT_RESET_HARD 0 | 115 | #define VIRTIO_SCSI_EVT_RESET_HARD 0 |
diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h index 0d7d67e96d43..9c8702942b61 100644 --- a/include/scsi/fc/fc_fcp.h +++ b/include/scsi/fc/fc_fcp.h | |||
| @@ -127,6 +127,9 @@ struct fcp_txrdy { | |||
| 127 | * | 127 | * |
| 128 | * All response frames will always contain the fcp_resp template. Some | 128 | * All response frames will always contain the fcp_resp template. Some |
| 129 | * will also include the fcp_resp_len template. | 129 | * will also include the fcp_resp_len template. |
| 130 | * | ||
| 131 | * From Table 23, the FCP_RSP_INFO can either be 4 bytes or 8 bytes, both | ||
| 132 | * are valid length. | ||
| 130 | */ | 133 | */ |
| 131 | struct fcp_resp { | 134 | struct fcp_resp { |
| 132 | __u8 _fr_resvd[8]; /* reserved */ | 135 | __u8 _fr_resvd[8]; /* reserved */ |
| @@ -156,6 +159,9 @@ struct fcp_resp_rsp_info { | |||
| 156 | __u8 _fr_resvd2[4]; /* reserved */ | 159 | __u8 _fr_resvd2[4]; /* reserved */ |
| 157 | }; | 160 | }; |
| 158 | 161 | ||
| 162 | #define FCP_RESP_RSP_INFO_LEN4 4 /* without reserved field */ | ||
| 163 | #define FCP_RESP_RSP_INFO_LEN8 8 /* with reserved field */ | ||
| 164 | |||
| 159 | struct fcp_resp_with_ext { | 165 | struct fcp_resp_with_ext { |
| 160 | struct fcp_resp resp; | 166 | struct fcp_resp resp; |
| 161 | struct fcp_resp_ext ext; | 167 | struct fcp_resp_ext ext; |
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index 22b07cc99808..8742d853a3b8 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h | |||
| @@ -327,7 +327,6 @@ struct fcoe_percpu_s { | |||
| 327 | * @lport: The associated local port | 327 | * @lport: The associated local port |
| 328 | * @fcoe_pending_queue: The pending Rx queue of skbs | 328 | * @fcoe_pending_queue: The pending Rx queue of skbs |
| 329 | * @fcoe_pending_queue_active: Indicates if the pending queue is active | 329 | * @fcoe_pending_queue_active: Indicates if the pending queue is active |
| 330 | * @priority: Packet priority (DCB) | ||
| 331 | * @max_queue_depth: Max queue depth of pending queue | 330 | * @max_queue_depth: Max queue depth of pending queue |
| 332 | * @min_queue_depth: Min queue depth of pending queue | 331 | * @min_queue_depth: Min queue depth of pending queue |
| 333 | * @timer: The queue timer | 332 | * @timer: The queue timer |
| @@ -343,7 +342,6 @@ struct fcoe_port { | |||
| 343 | struct fc_lport *lport; | 342 | struct fc_lport *lport; |
| 344 | struct sk_buff_head fcoe_pending_queue; | 343 | struct sk_buff_head fcoe_pending_queue; |
| 345 | u8 fcoe_pending_queue_active; | 344 | u8 fcoe_pending_queue_active; |
| 346 | u8 priority; | ||
| 347 | u32 max_queue_depth; | 345 | u32 max_queue_depth; |
| 348 | u32 min_queue_depth; | 346 | u32 min_queue_depth; |
| 349 | struct timer_list timer; | 347 | struct timer_list timer; |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index ac06cc595890..de5f5d8f1f8a 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
| @@ -132,18 +132,10 @@ struct scsi_cmnd { | |||
| 132 | unsigned char tag; /* SCSI-II queued command tag */ | 132 | unsigned char tag; /* SCSI-II queued command tag */ |
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | /* make sure not to use it with REQ_TYPE_BLOCK_PC commands */ | ||
| 135 | static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) | 136 | static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) |
| 136 | { | 137 | { |
| 137 | struct scsi_driver **sdp; | 138 | return *(struct scsi_driver **)cmd->request->rq_disk->private_data; |
| 138 | |||
| 139 | if (!cmd->request->rq_disk) | ||
| 140 | return NULL; | ||
| 141 | |||
| 142 | sdp = (struct scsi_driver **)cmd->request->rq_disk->private_data; | ||
| 143 | if (!sdp) | ||
| 144 | return NULL; | ||
| 145 | |||
| 146 | return *sdp; | ||
| 147 | } | 139 | } |
| 148 | 140 | ||
| 149 | extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); | 141 | extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); |
