aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2011-06-24 23:22:56 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-06-29 17:57:52 -0400
commit5a0adaedffce91100d03fc1036dde024c8589295 (patch)
tree672bba0f2dd33eea68a492dc4567f42d16a53c4d /drivers
parent1a4d8e1bd81c018f7b8c7622066d5cfead59b38a (diff)
[SCSI] bfa: IOC bug fixes.
- Add logic to handle the case where PCI mapping goes away when IOCPF state machine is waiting for semaphore. - Added logic to unlock hw semaphore if the previos FW boot was from flash based and the current FW initialization attempt is from OS. - Added fix to update hbfails and hb_count stats during hwerror event. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/bfa/bfa_defs.h2
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c116
-rw-r--r--drivers/scsi/bfa/bfa_ioc_cb.c15
-rw-r--r--drivers/scsi/bfa/bfa_ioc_ct.c23
-rw-r--r--drivers/scsi/bfa/bfi.h3
5 files changed, 125 insertions, 34 deletions
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h
index cced5874cb55..c675e65c77a4 100644
--- a/drivers/scsi/bfa/bfa_defs.h
+++ b/drivers/scsi/bfa/bfa_defs.h
@@ -274,6 +274,7 @@ enum bfa_ioc_state {
274 BFA_IOC_DISABLED = 10, /* IOC is disabled */ 274 BFA_IOC_DISABLED = 10, /* IOC is disabled */
275 BFA_IOC_FWMISMATCH = 11, /* IOC f/w different from drivers */ 275 BFA_IOC_FWMISMATCH = 11, /* IOC f/w different from drivers */
276 BFA_IOC_ENABLING = 12, /* IOC is being enabled */ 276 BFA_IOC_ENABLING = 12, /* IOC is being enabled */
277 BFA_IOC_HWFAIL = 13, /* PCI mapping doesn't exist */
277}; 278};
278 279
279/* 280/*
@@ -303,6 +304,7 @@ struct bfa_ioc_drv_stats_s {
303 u32 enable_reqs; 304 u32 enable_reqs;
304 u32 disable_replies; 305 u32 disable_replies;
305 u32 enable_replies; 306 u32 enable_replies;
307 u32 rsvd;
306}; 308};
307 309
308/* 310/*
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index 2c575f5dea04..931bf9769ff2 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -112,6 +112,7 @@ enum ioc_event {
112 IOC_E_HBFAIL = 9, /* heartbeat failure */ 112 IOC_E_HBFAIL = 9, /* heartbeat failure */
113 IOC_E_HWERROR = 10, /* hardware error interrupt */ 113 IOC_E_HWERROR = 10, /* hardware error interrupt */
114 IOC_E_TIMEOUT = 11, /* timeout */ 114 IOC_E_TIMEOUT = 11, /* timeout */
115 IOC_E_HWFAILED = 12, /* PCI mapping failure notice */
115}; 116};
116 117
117bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event); 118bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event);
@@ -123,6 +124,7 @@ bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc_s, enum ioc_event);
123bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event); 124bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event);
124bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event); 125bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
125bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event); 126bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
127bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc_s, enum ioc_event);
126 128
127static struct bfa_sm_table_s ioc_sm_table[] = { 129static struct bfa_sm_table_s ioc_sm_table[] = {
128 {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, 130 {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
@@ -134,6 +136,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
134 {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL}, 136 {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
135 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, 137 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
136 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, 138 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
139 {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL},
137}; 140};
138 141
139/* 142/*
@@ -176,6 +179,7 @@ enum iocpf_event {
176 IOCPF_E_GETATTRFAIL = 9, /* init fail notice by ioc sm */ 179 IOCPF_E_GETATTRFAIL = 9, /* init fail notice by ioc sm */
177 IOCPF_E_SEMLOCKED = 10, /* h/w semaphore is locked */ 180 IOCPF_E_SEMLOCKED = 10, /* h/w semaphore is locked */
178 IOCPF_E_TIMEOUT = 11, /* f/w response timeout */ 181 IOCPF_E_TIMEOUT = 11, /* f/w response timeout */
182 IOCPF_E_SEM_ERROR = 12, /* h/w sem mapping error */
179}; 183};
180 184
181/* 185/*
@@ -322,6 +326,11 @@ bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
322 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); 326 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
323 break; 327 break;
324 328
329 case IOC_E_HWFAILED:
330 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
331 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
332 break;
333
325 case IOC_E_DISABLE: 334 case IOC_E_DISABLE:
326 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 335 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
327 break; 336 break;
@@ -465,6 +474,11 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
465 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); 474 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
466 break; 475 break;
467 476
477 case IOC_E_HWFAILED:
478 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
479 bfa_ioc_disable_comp(ioc);
480 break;
481
468 default: 482 default:
469 bfa_sm_fault(ioc, event); 483 bfa_sm_fault(ioc, event);
470 } 484 }
@@ -534,6 +548,11 @@ bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event)
534 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); 548 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
535 break; 549 break;
536 550
551 case IOC_E_HWFAILED:
552 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
553 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
554 break;
555
537 case IOC_E_ENABLE: 556 case IOC_E_ENABLE:
538 break; 557 break;
539 558
@@ -591,6 +610,35 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
591 } 610 }
592} 611}
593 612
613static void
614bfa_ioc_sm_hwfail_entry(struct bfa_ioc_s *ioc)
615{
616 bfa_trc(ioc, 0);
617}
618
619static void
620bfa_ioc_sm_hwfail(struct bfa_ioc_s *ioc, enum ioc_event event)
621{
622 bfa_trc(ioc, event);
623
624 switch (event) {
625 case IOC_E_ENABLE:
626 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
627 break;
628
629 case IOC_E_DISABLE:
630 ioc->cbfn->disable_cbfn(ioc->bfa);
631 break;
632
633 case IOC_E_DETACH:
634 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
635 break;
636
637 default:
638 bfa_sm_fault(ioc, event);
639 }
640}
641
594/* 642/*
595 * IOCPF State Machine 643 * IOCPF State Machine
596 */ 644 */
@@ -634,6 +682,28 @@ bfa_iocpf_sm_reset(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
634static void 682static void
635bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) 683bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf)
636{ 684{
685 struct bfi_ioc_image_hdr_s fwhdr;
686 u32 fwstate = readl(iocpf->ioc->ioc_regs.ioc_fwstate);
687
688 /* h/w sem init */
689 if (fwstate == BFI_IOC_UNINIT)
690 goto sem_get;
691
692 bfa_ioc_fwver_get(iocpf->ioc, &fwhdr);
693
694 if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL)
695 goto sem_get;
696
697 bfa_trc(iocpf->ioc, fwstate);
698 bfa_trc(iocpf->ioc, fwhdr.exec);
699 writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.ioc_fwstate);
700
701 /*
702 * Try to lock and then unlock the semaphore.
703 */
704 readl(iocpf->ioc->ioc_regs.ioc_sem_reg);
705 writel(1, iocpf->ioc->ioc_regs.ioc_sem_reg);
706sem_get:
637 bfa_ioc_hw_sem_get(iocpf->ioc); 707 bfa_ioc_hw_sem_get(iocpf->ioc);
638} 708}
639 709
@@ -664,6 +734,11 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
664 } 734 }
665 break; 735 break;
666 736
737 case IOCPF_E_SEM_ERROR:
738 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
739 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
740 break;
741
667 case IOCPF_E_DISABLE: 742 case IOCPF_E_DISABLE:
668 bfa_sem_timer_stop(ioc); 743 bfa_sem_timer_stop(ioc);
669 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 744 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
@@ -757,6 +832,11 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
757 } 832 }
758 break; 833 break;
759 834
835 case IOCPF_E_SEM_ERROR:
836 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
837 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
838 break;
839
760 case IOCPF_E_DISABLE: 840 case IOCPF_E_DISABLE:
761 bfa_sem_timer_stop(ioc); 841 bfa_sem_timer_stop(ioc);
762 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 842 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
@@ -957,6 +1037,11 @@ bfa_iocpf_sm_disabling_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
957 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 1037 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
958 break; 1038 break;
959 1039
1040 case IOCPF_E_SEM_ERROR:
1041 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1042 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1043 break;
1044
960 case IOCPF_E_FAIL: 1045 case IOCPF_E_FAIL:
961 break; 1046 break;
962 1047
@@ -1000,6 +1085,7 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1000static void 1085static void
1001bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf) 1086bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf)
1002{ 1087{
1088 bfa_ioc_debug_save_ftrc(iocpf->ioc);
1003 bfa_ioc_hw_sem_get(iocpf->ioc); 1089 bfa_ioc_hw_sem_get(iocpf->ioc);
1004} 1090}
1005 1091
@@ -1022,6 +1108,11 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1022 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); 1108 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
1023 break; 1109 break;
1024 1110
1111 case IOCPF_E_SEM_ERROR:
1112 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1113 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1114 break;
1115
1025 case IOCPF_E_DISABLE: 1116 case IOCPF_E_DISABLE:
1026 bfa_sem_timer_stop(ioc); 1117 bfa_sem_timer_stop(ioc);
1027 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1118 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
@@ -1044,6 +1135,7 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1044static void 1135static void
1045bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf) 1136bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf)
1046{ 1137{
1138 bfa_trc(iocpf->ioc, 0);
1047} 1139}
1048 1140
1049/* 1141/*
@@ -1113,6 +1205,11 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1113 } 1205 }
1114 break; 1206 break;
1115 1207
1208 case IOCPF_E_SEM_ERROR:
1209 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1210 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1211 break;
1212
1116 case IOCPF_E_DISABLE: 1213 case IOCPF_E_DISABLE:
1117 bfa_sem_timer_stop(ioc); 1214 bfa_sem_timer_stop(ioc);
1118 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1215 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
@@ -1129,6 +1226,7 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1129static void 1226static void
1130bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf) 1227bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
1131{ 1228{
1229 bfa_trc(iocpf->ioc, 0);
1132} 1230}
1133 1231
1134/* 1232/*
@@ -1195,7 +1293,6 @@ bfa_ioc_sem_get(void __iomem *sem_reg)
1195 if (!(r32 & 1)) 1293 if (!(r32 & 1))
1196 return BFA_TRUE; 1294 return BFA_TRUE;
1197 1295
1198 WARN_ON(cnt >= BFA_SEM_SPINCNT);
1199 return BFA_FALSE; 1296 return BFA_FALSE;
1200} 1297}
1201 1298
@@ -1209,6 +1306,11 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
1209 * will return 1. Semaphore is released by writing 1 to the register 1306 * will return 1. Semaphore is released by writing 1 to the register
1210 */ 1307 */
1211 r32 = readl(ioc->ioc_regs.ioc_sem_reg); 1308 r32 = readl(ioc->ioc_regs.ioc_sem_reg);
1309 if (r32 == ~0) {
1310 WARN_ON(r32 == ~0);
1311 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEM_ERROR);
1312 return;
1313 }
1212 if (!(r32 & 1)) { 1314 if (!(r32 & 1)) {
1213 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED); 1315 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED);
1214 return; 1316 return;
@@ -1617,6 +1719,7 @@ bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
1617 attr->adapter_prop = be32_to_cpu(attr->adapter_prop); 1719 attr->adapter_prop = be32_to_cpu(attr->adapter_prop);
1618 attr->card_type = be32_to_cpu(attr->card_type); 1720 attr->card_type = be32_to_cpu(attr->card_type);
1619 attr->maxfrsize = be16_to_cpu(attr->maxfrsize); 1721 attr->maxfrsize = be16_to_cpu(attr->maxfrsize);
1722 ioc->fcmode = (attr->port_mode == BFI_PORT_MODE_FC);
1620 1723
1621 bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); 1724 bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
1622} 1725}
@@ -1733,6 +1836,7 @@ bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
1733 /* 1836 /*
1734 * release semaphore. 1837 * release semaphore.
1735 */ 1838 */
1839 readl(ioc->ioc_regs.ioc_init_sem_reg);
1736 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1840 writel(1, ioc->ioc_regs.ioc_init_sem_reg);
1737 1841
1738 bfa_trc(ioc, pgnum); 1842 bfa_trc(ioc, pgnum);
@@ -1789,6 +1893,7 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
1789 /* 1893 /*
1790 * release semaphore. 1894 * release semaphore.
1791 */ 1895 */
1896 readl(ioc->ioc_regs.ioc_init_sem_reg);
1792 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1897 writel(1, ioc->ioc_regs.ioc_init_sem_reg);
1793 bfa_trc(ioc, pgnum); 1898 bfa_trc(ioc, pgnum);
1794 return BFA_STATUS_OK; 1899 return BFA_STATUS_OK;
@@ -1840,6 +1945,7 @@ bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
1840 /* 1945 /*
1841 * release semaphore. 1946 * release semaphore.
1842 */ 1947 */
1948 readl(ioc->ioc_regs.ioc_init_sem_reg);
1843 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1949 writel(1, ioc->ioc_regs.ioc_init_sem_reg);
1844 1950
1845 return BFA_STATUS_OK; 1951 return BFA_STATUS_OK;
@@ -2232,6 +2338,8 @@ bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc)
2232void 2338void
2233bfa_ioc_error_isr(struct bfa_ioc_s *ioc) 2339bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
2234{ 2340{
2341 bfa_ioc_stats(ioc, ioc_hbfails);
2342 ioc->stats.hb_count = ioc->hb_count;
2235 bfa_fsm_send_event(ioc, IOC_E_HWERROR); 2343 bfa_fsm_send_event(ioc, IOC_E_HWERROR);
2236} 2344}
2237 2345
@@ -2354,15 +2462,12 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2354enum bfa_ioc_type_e 2462enum bfa_ioc_type_e
2355bfa_ioc_get_type(struct bfa_ioc_s *ioc) 2463bfa_ioc_get_type(struct bfa_ioc_s *ioc)
2356{ 2464{
2357 enum bfi_port_mode mode;
2358
2359 if (ioc->clscode == BFI_PCIFN_CLASS_ETH) 2465 if (ioc->clscode == BFI_PCIFN_CLASS_ETH)
2360 return BFA_IOC_TYPE_LL; 2466 return BFA_IOC_TYPE_LL;
2361 2467
2362 WARN_ON(ioc->clscode != BFI_PCIFN_CLASS_FC); 2468 WARN_ON(ioc->clscode != BFI_PCIFN_CLASS_FC);
2363 2469
2364 mode = (ioc->port_id == 0) ? ioc->port0_mode : ioc->port1_mode; 2470 return (ioc->attr->port_mode == BFI_PORT_MODE_FC)
2365 return (mode == BFI_PORT_MODE_FC)
2366 ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE; 2471 ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE;
2367} 2472}
2368 2473
@@ -2739,6 +2844,7 @@ static void
2739bfa_ioc_recover(struct bfa_ioc_s *ioc) 2844bfa_ioc_recover(struct bfa_ioc_s *ioc)
2740{ 2845{
2741 bfa_ioc_stats(ioc, ioc_hbfails); 2846 bfa_ioc_stats(ioc, ioc_hbfails);
2847 ioc->stats.hb_count = ioc->hb_count;
2742 bfa_fsm_send_event(ioc, IOC_E_HBFAIL); 2848 bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
2743} 2849}
2744 2850
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c
index e858bc0c48d0..30df8a284715 100644
--- a/drivers/scsi/bfa/bfa_ioc_cb.c
+++ b/drivers/scsi/bfa/bfa_ioc_cb.c
@@ -69,21 +69,6 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
69static bfa_boolean_t 69static bfa_boolean_t
70bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc) 70bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
71{ 71{
72 struct bfi_ioc_image_hdr_s fwhdr;
73 uint32_t fwstate = readl(ioc->ioc_regs.ioc_fwstate);
74
75 if (fwstate == BFI_IOC_UNINIT)
76 return BFA_TRUE;
77
78 bfa_ioc_fwver_get(ioc, &fwhdr);
79
80 if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL)
81 return BFA_TRUE;
82
83 bfa_trc(ioc, fwstate);
84 bfa_trc(ioc, fwhdr.exec);
85 writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
86
87 return BFA_TRUE; 72 return BFA_TRUE;
88} 73}
89 74
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
index 5b5579401d43..216016c50d11 100644
--- a/drivers/scsi/bfa/bfa_ioc_ct.c
+++ b/drivers/scsi/bfa/bfa_ioc_ct.c
@@ -58,12 +58,6 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
58 struct bfi_ioc_image_hdr_s fwhdr; 58 struct bfi_ioc_image_hdr_s fwhdr;
59 59
60 /* 60 /*
61 * Firmware match check is relevant only for CNA.
62 */
63 if (!bfa_ioc_is_cna(ioc))
64 return BFA_TRUE;
65
66 /*
67 * If bios boot (flash based) -- do not increment usage count 61 * If bios boot (flash based) -- do not increment usage count
68 */ 62 */
69 if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) < 63 if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) <
@@ -78,6 +72,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
78 */ 72 */
79 if (usecnt == 0) { 73 if (usecnt == 0) {
80 writel(1, ioc->ioc_regs.ioc_usage_reg); 74 writel(1, ioc->ioc_regs.ioc_usage_reg);
75 readl(ioc->ioc_regs.ioc_usage_sem_reg);
81 writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 76 writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
82 writel(0, ioc->ioc_regs.ioc_fail_sync); 77 writel(0, ioc->ioc_regs.ioc_fail_sync);
83 bfa_trc(ioc, usecnt); 78 bfa_trc(ioc, usecnt);
@@ -97,6 +92,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
97 */ 92 */
98 bfa_ioc_fwver_get(ioc, &fwhdr); 93 bfa_ioc_fwver_get(ioc, &fwhdr);
99 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { 94 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
95 readl(ioc->ioc_regs.ioc_usage_sem_reg);
100 writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 96 writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
101 bfa_trc(ioc, usecnt); 97 bfa_trc(ioc, usecnt);
102 return BFA_FALSE; 98 return BFA_FALSE;
@@ -107,6 +103,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
107 */ 103 */
108 usecnt++; 104 usecnt++;
109 writel(usecnt, ioc->ioc_regs.ioc_usage_reg); 105 writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
106 readl(ioc->ioc_regs.ioc_usage_sem_reg);
110 writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 107 writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
111 bfa_trc(ioc, usecnt); 108 bfa_trc(ioc, usecnt);
112 return BFA_TRUE; 109 return BFA_TRUE;
@@ -118,12 +115,6 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
118 u32 usecnt; 115 u32 usecnt;
119 116
120 /* 117 /*
121 * Firmware lock is relevant only for CNA.
122 */
123 if (!bfa_ioc_is_cna(ioc))
124 return;
125
126 /*
127 * If bios boot (flash based) -- do not decrement usage count 118 * If bios boot (flash based) -- do not decrement usage count
128 */ 119 */
129 if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) < 120 if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) <
@@ -141,6 +132,7 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
141 writel(usecnt, ioc->ioc_regs.ioc_usage_reg); 132 writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
142 bfa_trc(ioc, usecnt); 133 bfa_trc(ioc, usecnt);
143 134
135 readl(ioc->ioc_regs.ioc_usage_sem_reg);
144 writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 136 writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
145} 137}
146 138
@@ -344,7 +336,11 @@ bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
344static void 336static void
345bfa_ioc_ct2_map_port(struct bfa_ioc_s *ioc) 337bfa_ioc_ct2_map_port(struct bfa_ioc_s *ioc)
346{ 338{
347 ioc->port_id = bfa_ioc_pcifn(ioc) % 2; 339 void __iomem *rb = ioc->pcidev.pci_bar_kva;
340 u32 r32;
341
342 r32 = readl(rb + CT2_HOSTFN_PERSONALITY0);
343 ioc->port_id = ((r32 & __FC_LL_PORT_MAP__MK) >> __FC_LL_PORT_MAP__SH);
348 344
349 bfa_trc(ioc, bfa_ioc_pcifn(ioc)); 345 bfa_trc(ioc, bfa_ioc_pcifn(ioc));
350 bfa_trc(ioc, ioc->port_id); 346 bfa_trc(ioc, ioc->port_id);
@@ -407,6 +403,7 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
407 if (bfa_ioc_is_cna(ioc)) { 403 if (bfa_ioc_is_cna(ioc)) {
408 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); 404 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
409 writel(0, ioc->ioc_regs.ioc_usage_reg); 405 writel(0, ioc->ioc_regs.ioc_usage_reg);
406 readl(ioc->ioc_regs.ioc_usage_sem_reg);
410 writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 407 writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
411 } 408 }
412 409
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h
index d28c7c55a60c..02e445612546 100644
--- a/drivers/scsi/bfa/bfi.h
+++ b/drivers/scsi/bfa/bfi.h
@@ -236,7 +236,8 @@ struct bfi_ioc_attr_s {
236 wwn_t mfg_pwwn; /* Mfg port wwn */ 236 wwn_t mfg_pwwn; /* Mfg port wwn */
237 wwn_t mfg_nwwn; /* Mfg node wwn */ 237 wwn_t mfg_nwwn; /* Mfg node wwn */
238 mac_t mfg_mac; /* Mfg mac */ 238 mac_t mfg_mac; /* Mfg mac */
239 u16 rsvd_a; 239 u8 port_mode; /* bfi_port_mode */
240 u8 rsvd_a;
240 wwn_t pwwn; 241 wwn_t pwwn;
241 wwn_t nwwn; 242 wwn_t nwwn;
242 mac_t mac; /* PBC or Mfg mac */ 243 mac_t mac; /* PBC or Mfg mac */