diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-13 18:52:12 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 16:46:19 -0400 |
commit | 775c7742adfd7726f05914198bf33eaa3b9f64bb (patch) | |
tree | 87c9373091ca11b5808dc28a2acb7d4a4efe33a2 /drivers/scsi/bfa/bfa_ioc.c | |
parent | dd5aaf4536c5111784a18d935b9b5adeac9f914c (diff) |
[SCSI] bfa: IOC and PLL init changes for Brocade-1860 Fabric Adapter.
- Introduced IOC poll mechanism which replaces current interrupt
based FW READY method.
- The timer based poll routine in IOC will query the ioc_fwstate
register to see if there is a state change in FW, and sends the READY event.
- Bug fixes in the new asic PLL initialization.
- Added logic to handle CPE/RME queue interrupts before iocfc config done.
1. Use the queue_process flag to see if iocfc configuration is done
in INTX mode.
2. Split the MSIX handler installation in two - one for IOC intr
handler and the other for cpe/rme queue handler - and delay
assigning queue handlers until iocfc config is done in MSIX mode.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_ioc.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.c | 130 |
1 files changed, 57 insertions, 73 deletions
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 3d336c279c42..9c6e493cb9c7 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
@@ -29,8 +29,8 @@ BFA_TRC_FILE(CNA, IOC); | |||
29 | #define BFA_IOC_TOV 3000 /* msecs */ | 29 | #define BFA_IOC_TOV 3000 /* msecs */ |
30 | #define BFA_IOC_HWSEM_TOV 500 /* msecs */ | 30 | #define BFA_IOC_HWSEM_TOV 500 /* msecs */ |
31 | #define BFA_IOC_HB_TOV 500 /* msecs */ | 31 | #define BFA_IOC_HB_TOV 500 /* msecs */ |
32 | #define BFA_IOC_HWINIT_MAX 5 | ||
33 | #define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV | 32 | #define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV |
33 | #define BFA_IOC_POLL_TOV BFA_TIMER_FREQ | ||
34 | 34 | ||
35 | #define bfa_ioc_timer_start(__ioc) \ | 35 | #define bfa_ioc_timer_start(__ioc) \ |
36 | bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ | 36 | bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ |
@@ -79,6 +79,7 @@ bfa_boolean_t bfa_auto_recover = BFA_TRUE; | |||
79 | static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc); | 79 | static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc); |
80 | static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force); | 80 | static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force); |
81 | static void bfa_ioc_timeout(void *ioc); | 81 | static void bfa_ioc_timeout(void *ioc); |
82 | static void bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc); | ||
82 | static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc); | 83 | static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc); |
83 | static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc); | 84 | static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc); |
84 | static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc); | 85 | static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc); |
@@ -107,11 +108,10 @@ enum ioc_event { | |||
107 | IOC_E_ENABLED = 5, /* f/w enabled */ | 108 | IOC_E_ENABLED = 5, /* f/w enabled */ |
108 | IOC_E_FWRSP_GETATTR = 6, /* IOC get attribute response */ | 109 | IOC_E_FWRSP_GETATTR = 6, /* IOC get attribute response */ |
109 | IOC_E_DISABLED = 7, /* f/w disabled */ | 110 | IOC_E_DISABLED = 7, /* f/w disabled */ |
110 | IOC_E_INITFAILED = 8, /* failure notice by iocpf sm */ | 111 | IOC_E_PFFAILED = 8, /* failure notice by iocpf sm */ |
111 | IOC_E_PFFAILED = 9, /* failure notice by iocpf sm */ | 112 | IOC_E_HBFAIL = 9, /* heartbeat failure */ |
112 | IOC_E_HBFAIL = 10, /* heartbeat failure */ | 113 | IOC_E_HWERROR = 10, /* hardware error interrupt */ |
113 | IOC_E_HWERROR = 11, /* hardware error interrupt */ | 114 | IOC_E_TIMEOUT = 11, /* timeout */ |
114 | IOC_E_TIMEOUT = 12, /* timeout */ | ||
115 | }; | 115 | }; |
116 | 116 | ||
117 | bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event); | 117 | bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event); |
@@ -145,9 +145,9 @@ static struct bfa_sm_table_s ioc_sm_table[] = { | |||
145 | bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV) | 145 | bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV) |
146 | #define bfa_iocpf_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer) | 146 | #define bfa_iocpf_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer) |
147 | 147 | ||
148 | #define bfa_iocpf_recovery_timer_start(__ioc) \ | 148 | #define bfa_iocpf_poll_timer_start(__ioc) \ |
149 | bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ | 149 | bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ |
150 | bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV_RECOVER) | 150 | bfa_iocpf_poll_timeout, (__ioc), BFA_IOC_POLL_TOV) |
151 | 151 | ||
152 | #define bfa_sem_timer_start(__ioc) \ | 152 | #define bfa_sem_timer_start(__ioc) \ |
153 | bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->sem_timer, \ | 153 | bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->sem_timer, \ |
@@ -159,6 +159,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = { | |||
159 | */ | 159 | */ |
160 | static void bfa_iocpf_timeout(void *ioc_arg); | 160 | static void bfa_iocpf_timeout(void *ioc_arg); |
161 | static void bfa_iocpf_sem_timeout(void *ioc_arg); | 161 | static void bfa_iocpf_sem_timeout(void *ioc_arg); |
162 | static void bfa_iocpf_poll_timeout(void *ioc_arg); | ||
162 | 163 | ||
163 | /* | 164 | /* |
164 | * IOCPF state machine events | 165 | * IOCPF state machine events |
@@ -316,7 +317,7 @@ bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
316 | /* !!! fall through !!! */ | 317 | /* !!! fall through !!! */ |
317 | case IOC_E_HWERROR: | 318 | case IOC_E_HWERROR: |
318 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); | 319 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); |
319 | bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); | 320 | bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); |
320 | if (event != IOC_E_PFFAILED) | 321 | if (event != IOC_E_PFFAILED) |
321 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); | 322 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); |
322 | break; | 323 | break; |
@@ -368,7 +369,7 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
368 | /* !!! fall through !!! */ | 369 | /* !!! fall through !!! */ |
369 | case IOC_E_TIMEOUT: | 370 | case IOC_E_TIMEOUT: |
370 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); | 371 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); |
371 | bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); | 372 | bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); |
372 | if (event != IOC_E_PFFAILED) | 373 | if (event != IOC_E_PFFAILED) |
373 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL); | 374 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL); |
374 | break; | 375 | break; |
@@ -417,13 +418,13 @@ bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
417 | bfa_hb_timer_stop(ioc); | 418 | bfa_hb_timer_stop(ioc); |
418 | /* !!! fall through !!! */ | 419 | /* !!! fall through !!! */ |
419 | case IOC_E_HBFAIL: | 420 | case IOC_E_HBFAIL: |
420 | bfa_ioc_fail_notify(ioc); | ||
421 | |||
422 | if (ioc->iocpf.auto_recover) | 421 | if (ioc->iocpf.auto_recover) |
423 | bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); | 422 | bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); |
424 | else | 423 | else |
425 | bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); | 424 | bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); |
426 | 425 | ||
426 | bfa_ioc_fail_notify(ioc); | ||
427 | |||
427 | if (event != IOC_E_PFFAILED) | 428 | if (event != IOC_E_PFFAILED) |
428 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); | 429 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); |
429 | break; | 430 | break; |
@@ -528,14 +529,11 @@ bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
528 | * Initialization retry failed. | 529 | * Initialization retry failed. |
529 | */ | 530 | */ |
530 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); | 531 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); |
532 | bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); | ||
531 | if (event != IOC_E_PFFAILED) | 533 | if (event != IOC_E_PFFAILED) |
532 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); | 534 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); |
533 | break; | 535 | break; |
534 | 536 | ||
535 | case IOC_E_INITFAILED: | ||
536 | bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); | ||
537 | break; | ||
538 | |||
539 | case IOC_E_ENABLE: | 537 | case IOC_E_ENABLE: |
540 | break; | 538 | break; |
541 | 539 | ||
@@ -603,7 +601,7 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
603 | static void | 601 | static void |
604 | bfa_iocpf_sm_reset_entry(struct bfa_iocpf_s *iocpf) | 602 | bfa_iocpf_sm_reset_entry(struct bfa_iocpf_s *iocpf) |
605 | { | 603 | { |
606 | iocpf->retry_count = 0; | 604 | iocpf->fw_mismatch_notified = BFA_FALSE; |
607 | iocpf->auto_recover = bfa_auto_recover; | 605 | iocpf->auto_recover = bfa_auto_recover; |
608 | } | 606 | } |
609 | 607 | ||
@@ -653,7 +651,6 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
653 | case IOCPF_E_SEMLOCKED: | 651 | case IOCPF_E_SEMLOCKED: |
654 | if (bfa_ioc_firmware_lock(ioc)) { | 652 | if (bfa_ioc_firmware_lock(ioc)) { |
655 | if (bfa_ioc_sync_start(ioc)) { | 653 | if (bfa_ioc_sync_start(ioc)) { |
656 | iocpf->retry_count = 0; | ||
657 | bfa_ioc_sync_join(ioc); | 654 | bfa_ioc_sync_join(ioc); |
658 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); | 655 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); |
659 | } else { | 656 | } else { |
@@ -692,10 +689,10 @@ bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf_s *iocpf) | |||
692 | /* | 689 | /* |
693 | * Call only the first time sm enters fwmismatch state. | 690 | * Call only the first time sm enters fwmismatch state. |
694 | */ | 691 | */ |
695 | if (iocpf->retry_count == 0) | 692 | if (iocpf->fw_mismatch_notified == BFA_FALSE) |
696 | bfa_ioc_pf_fwmismatch(iocpf->ioc); | 693 | bfa_ioc_pf_fwmismatch(iocpf->ioc); |
697 | 694 | ||
698 | iocpf->retry_count++; | 695 | iocpf->fw_mismatch_notified = BFA_TRUE; |
699 | bfa_iocpf_timer_start(iocpf->ioc); | 696 | bfa_iocpf_timer_start(iocpf->ioc); |
700 | } | 697 | } |
701 | 698 | ||
@@ -773,7 +770,7 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
773 | static void | 770 | static void |
774 | bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf) | 771 | bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf) |
775 | { | 772 | { |
776 | bfa_iocpf_timer_start(iocpf->ioc); | 773 | iocpf->poll_time = 0; |
777 | bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE); | 774 | bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE); |
778 | } | 775 | } |
779 | 776 | ||
@@ -790,20 +787,12 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
790 | 787 | ||
791 | switch (event) { | 788 | switch (event) { |
792 | case IOCPF_E_FWREADY: | 789 | case IOCPF_E_FWREADY: |
793 | bfa_iocpf_timer_stop(ioc); | ||
794 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling); | 790 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling); |
795 | break; | 791 | break; |
796 | 792 | ||
797 | case IOCPF_E_INITFAIL: | ||
798 | bfa_iocpf_timer_stop(ioc); | ||
799 | /* | ||
800 | * !!! fall through !!! | ||
801 | */ | ||
802 | |||
803 | case IOCPF_E_TIMEOUT: | 793 | case IOCPF_E_TIMEOUT: |
804 | writel(1, ioc->ioc_regs.ioc_sem_reg); | 794 | writel(1, ioc->ioc_regs.ioc_sem_reg); |
805 | if (event == IOCPF_E_TIMEOUT) | 795 | bfa_fsm_send_event(ioc, IOC_E_PFFAILED); |
806 | bfa_fsm_send_event(ioc, IOC_E_PFFAILED); | ||
807 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); | 796 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); |
808 | break; | 797 | break; |
809 | 798 | ||
@@ -823,6 +812,10 @@ static void | |||
823 | bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf) | 812 | bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf) |
824 | { | 813 | { |
825 | bfa_iocpf_timer_start(iocpf->ioc); | 814 | bfa_iocpf_timer_start(iocpf->ioc); |
815 | /* | ||
816 | * Enable Interrupts before sending fw IOC ENABLE cmd. | ||
817 | */ | ||
818 | iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa); | ||
826 | bfa_ioc_send_enable(iocpf->ioc); | 819 | bfa_ioc_send_enable(iocpf->ioc); |
827 | } | 820 | } |
828 | 821 | ||
@@ -863,10 +856,6 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
863 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); | 856 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); |
864 | break; | 857 | break; |
865 | 858 | ||
866 | case IOCPF_E_FWREADY: | ||
867 | bfa_ioc_send_enable(ioc); | ||
868 | break; | ||
869 | |||
870 | default: | 859 | default: |
871 | bfa_sm_fault(ioc, event); | 860 | bfa_sm_fault(ioc, event); |
872 | } | 861 | } |
@@ -898,16 +887,6 @@ bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
898 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); | 887 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); |
899 | break; | 888 | break; |
900 | 889 | ||
901 | case IOCPF_E_FWREADY: | ||
902 | if (bfa_ioc_is_operational(ioc)) { | ||
903 | bfa_fsm_send_event(ioc, IOC_E_PFFAILED); | ||
904 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); | ||
905 | } else { | ||
906 | bfa_fsm_send_event(ioc, IOC_E_PFFAILED); | ||
907 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); | ||
908 | } | ||
909 | break; | ||
910 | |||
911 | default: | 890 | default: |
912 | bfa_sm_fault(ioc, event); | 891 | bfa_sm_fault(ioc, event); |
913 | } | 892 | } |
@@ -932,7 +911,6 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
932 | 911 | ||
933 | switch (event) { | 912 | switch (event) { |
934 | case IOCPF_E_FWRSP_DISABLE: | 913 | case IOCPF_E_FWRSP_DISABLE: |
935 | case IOCPF_E_FWREADY: | ||
936 | bfa_iocpf_timer_stop(ioc); | 914 | bfa_iocpf_timer_stop(ioc); |
937 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); | 915 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); |
938 | break; | 916 | break; |
@@ -1005,7 +983,6 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
1005 | 983 | ||
1006 | switch (event) { | 984 | switch (event) { |
1007 | case IOCPF_E_ENABLE: | 985 | case IOCPF_E_ENABLE: |
1008 | iocpf->retry_count = 0; | ||
1009 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); | 986 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); |
1010 | break; | 987 | break; |
1011 | 988 | ||
@@ -1038,20 +1015,10 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
1038 | switch (event) { | 1015 | switch (event) { |
1039 | case IOCPF_E_SEMLOCKED: | 1016 | case IOCPF_E_SEMLOCKED: |
1040 | bfa_ioc_notify_fail(ioc); | 1017 | bfa_ioc_notify_fail(ioc); |
1041 | bfa_ioc_sync_ack(ioc); | 1018 | bfa_ioc_sync_leave(ioc); |
1042 | iocpf->retry_count++; | 1019 | writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); |
1043 | if (iocpf->retry_count >= BFA_IOC_HWINIT_MAX) { | 1020 | writel(1, ioc->ioc_regs.ioc_sem_reg); |
1044 | bfa_ioc_sync_leave(ioc); | 1021 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); |
1045 | writel(1, ioc->ioc_regs.ioc_sem_reg); | ||
1046 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); | ||
1047 | } else { | ||
1048 | if (bfa_ioc_sync_complete(ioc)) | ||
1049 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); | ||
1050 | else { | ||
1051 | writel(1, ioc->ioc_regs.ioc_sem_reg); | ||
1052 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); | ||
1053 | } | ||
1054 | } | ||
1055 | break; | 1022 | break; |
1056 | 1023 | ||
1057 | case IOCPF_E_DISABLE: | 1024 | case IOCPF_E_DISABLE: |
@@ -1076,7 +1043,6 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
1076 | static void | 1043 | static void |
1077 | bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf) | 1044 | bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf) |
1078 | { | 1045 | { |
1079 | bfa_fsm_send_event(iocpf->ioc, IOC_E_INITFAILED); | ||
1080 | } | 1046 | } |
1081 | 1047 | ||
1082 | /* | 1048 | /* |
@@ -1129,11 +1095,11 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
1129 | 1095 | ||
1130 | switch (event) { | 1096 | switch (event) { |
1131 | case IOCPF_E_SEMLOCKED: | 1097 | case IOCPF_E_SEMLOCKED: |
1132 | iocpf->retry_count = 0; | ||
1133 | bfa_ioc_sync_ack(ioc); | 1098 | bfa_ioc_sync_ack(ioc); |
1134 | bfa_ioc_notify_fail(ioc); | 1099 | bfa_ioc_notify_fail(ioc); |
1135 | if (!iocpf->auto_recover) { | 1100 | if (!iocpf->auto_recover) { |
1136 | bfa_ioc_sync_leave(ioc); | 1101 | bfa_ioc_sync_leave(ioc); |
1102 | writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); | ||
1137 | writel(1, ioc->ioc_regs.ioc_sem_reg); | 1103 | writel(1, ioc->ioc_regs.ioc_sem_reg); |
1138 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); | 1104 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); |
1139 | } else { | 1105 | } else { |
@@ -1441,7 +1407,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force) | |||
1441 | * just wait for an initialization completion interrupt. | 1407 | * just wait for an initialization completion interrupt. |
1442 | */ | 1408 | */ |
1443 | if (ioc_fwstate == BFI_IOC_INITING) { | 1409 | if (ioc_fwstate == BFI_IOC_INITING) { |
1444 | ioc->cbfn->reset_cbfn(ioc->bfa); | 1410 | bfa_ioc_poll_fwinit(ioc); |
1445 | return; | 1411 | return; |
1446 | } | 1412 | } |
1447 | 1413 | ||
@@ -1460,7 +1426,6 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force) | |||
1460 | * be flushed. Otherwise MSI-X interrupts are not delivered. | 1426 | * be flushed. Otherwise MSI-X interrupts are not delivered. |
1461 | */ | 1427 | */ |
1462 | bfa_ioc_msgflush(ioc); | 1428 | bfa_ioc_msgflush(ioc); |
1463 | ioc->cbfn->reset_cbfn(ioc->bfa); | ||
1464 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); | 1429 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); |
1465 | return; | 1430 | return; |
1466 | } | 1431 | } |
@@ -1902,11 +1867,6 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env) | |||
1902 | 1867 | ||
1903 | bfa_ioc_msgflush(ioc); | 1868 | bfa_ioc_msgflush(ioc); |
1904 | bfa_ioc_download_fw(ioc, boot_type, boot_env); | 1869 | bfa_ioc_download_fw(ioc, boot_type, boot_env); |
1905 | |||
1906 | /* | ||
1907 | * Enable interrupts just before starting LPU | ||
1908 | */ | ||
1909 | ioc->cbfn->reset_cbfn(ioc->bfa); | ||
1910 | bfa_ioc_lpu_start(ioc); | 1870 | bfa_ioc_lpu_start(ioc); |
1911 | } | 1871 | } |
1912 | 1872 | ||
@@ -1981,10 +1941,6 @@ bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m) | |||
1981 | case BFI_IOC_I2H_HBEAT: | 1941 | case BFI_IOC_I2H_HBEAT: |
1982 | break; | 1942 | break; |
1983 | 1943 | ||
1984 | case BFI_IOC_I2H_READY_EVENT: | ||
1985 | bfa_fsm_send_event(iocpf, IOCPF_E_FWREADY); | ||
1986 | break; | ||
1987 | |||
1988 | case BFI_IOC_I2H_ENABLE_REPLY: | 1944 | case BFI_IOC_I2H_ENABLE_REPLY: |
1989 | bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE); | 1945 | bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE); |
1990 | break; | 1946 | break; |
@@ -2752,6 +2708,34 @@ bfa_iocpf_sem_timeout(void *ioc_arg) | |||
2752 | bfa_ioc_hw_sem_get(ioc); | 2708 | bfa_ioc_hw_sem_get(ioc); |
2753 | } | 2709 | } |
2754 | 2710 | ||
2711 | static void | ||
2712 | bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc) | ||
2713 | { | ||
2714 | u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate); | ||
2715 | |||
2716 | bfa_trc(ioc, fwstate); | ||
2717 | |||
2718 | if (fwstate == BFI_IOC_DISABLED) { | ||
2719 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); | ||
2720 | return; | ||
2721 | } | ||
2722 | |||
2723 | if (ioc->iocpf.poll_time >= BFA_IOC_TOV) | ||
2724 | bfa_iocpf_timeout(ioc); | ||
2725 | else { | ||
2726 | ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; | ||
2727 | bfa_iocpf_poll_timer_start(ioc); | ||
2728 | } | ||
2729 | } | ||
2730 | |||
2731 | static void | ||
2732 | bfa_iocpf_poll_timeout(void *ioc_arg) | ||
2733 | { | ||
2734 | struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; | ||
2735 | |||
2736 | bfa_ioc_poll_fwinit(ioc); | ||
2737 | } | ||
2738 | |||
2755 | /* | 2739 | /* |
2756 | * bfa timer function | 2740 | * bfa timer function |
2757 | */ | 2741 | */ |