aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/bfa/Makefile8
-rw-r--r--drivers/scsi/bfa/bfa_core.c10
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c546
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h45
-rw-r--r--drivers/scsi/bfa/bfa_ioc_cb.c273
-rw-r--r--drivers/scsi/bfa/bfa_ioc_ct.c422
-rw-r--r--drivers/scsi/bfa/include/bfa.h1
-rw-r--r--drivers/scsi/bfa/include/bfa_timer.h2
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_cbreg.h3
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ctreg.h2
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ioc.h2
-rw-r--r--drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h4
12 files changed, 859 insertions, 459 deletions
diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile
index 1d6009490d1c..17e06cae71b2 100644
--- a/drivers/scsi/bfa/Makefile
+++ b/drivers/scsi/bfa/Makefile
@@ -2,14 +2,14 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
2 2
3bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o 3bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
4 4
5bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o 5bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o
6bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o 6bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
7bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o 7bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
8bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o 8bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o
9bfa-y += bfa_csdebug.o bfa_sm.o plog.o 9bfa-y += bfa_csdebug.o bfa_sm.o plog.o
10 10
11bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o 11bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
12bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o 12bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o
13bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o 13bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o
14 14
15ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna 15ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna -DBFA_PERF_BUILD
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 44e2d1155c51..72e3f2f63b2e 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -399,4 +399,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
399{ 399{
400 return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen); 400 return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
401} 401}
402
403/**
404 * Reset hw semaphore & usage cnt regs and initialize.
405 */
406void
407bfa_chip_reset(struct bfa_s *bfa)
408{
409 bfa_ioc_ownership_reset(&bfa->ioc);
410 bfa_ioc_pll_init(&bfa->ioc);
411}
402#endif 412#endif
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index 569b35d19a25..a5f9745315b1 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -33,12 +33,11 @@ BFA_TRC_FILE(HAL, IOC);
33 * IOC local definitions 33 * IOC local definitions
34 */ 34 */
35#define BFA_IOC_TOV 2000 /* msecs */ 35#define BFA_IOC_TOV 2000 /* msecs */
36#define BFA_IOC_HB_TOV 1000 /* msecs */ 36#define BFA_IOC_HWSEM_TOV 500 /* msecs */
37#define BFA_IOC_HB_FAIL_MAX 4 37#define BFA_IOC_HB_TOV 500 /* msecs */
38#define BFA_IOC_HWINIT_MAX 2 38#define BFA_IOC_HWINIT_MAX 2
39#define BFA_IOC_FWIMG_MINSZ (16 * 1024) 39#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
40#define BFA_IOC_TOV_RECOVER (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \ 40#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV
41 + BFA_IOC_TOV)
42 41
43#define bfa_ioc_timer_start(__ioc) \ 42#define bfa_ioc_timer_start(__ioc) \
44 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ 43 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \
@@ -51,11 +50,24 @@ BFA_TRC_FILE(HAL, IOC);
51 (sizeof(struct bfa_trc_mod_s) - \ 50 (sizeof(struct bfa_trc_mod_s) - \
52 BFA_TRC_MAX * sizeof(struct bfa_trc_s))) 51 BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
53#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn)) 52#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
54#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
55 53
56#define BFA_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS) 54/**
57#define BFA_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS) 55 * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
58#define BFA_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS) 56 */
57
58#define bfa_ioc_firmware_lock(__ioc) \
59 ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
60#define bfa_ioc_firmware_unlock(__ioc) \
61 ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
62#define bfa_ioc_fwimg_get_chunk(__ioc, __off) \
63 ((__ioc)->ioc_hwif->ioc_fwimg_get_chunk(__ioc, __off))
64#define bfa_ioc_fwimg_get_size(__ioc) \
65 ((__ioc)->ioc_hwif->ioc_fwimg_get_size(__ioc))
66#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
67#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
68#define bfa_ioc_notify_hbfail(__ioc) \
69 ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
70
59bfa_boolean_t bfa_auto_recover = BFA_TRUE; 71bfa_boolean_t bfa_auto_recover = BFA_TRUE;
60 72
61/* 73/*
@@ -64,7 +76,6 @@ bfa_boolean_t bfa_auto_recover = BFA_TRUE;
64static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa, 76static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
65 enum bfa_ioc_aen_event event); 77 enum bfa_ioc_aen_event event);
66static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc); 78static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
67static void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
68static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc); 79static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
69static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force); 80static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
70static void bfa_ioc_timeout(void *ioc); 81static void bfa_ioc_timeout(void *ioc);
@@ -77,8 +88,6 @@ static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
77static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc); 88static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
78static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc); 89static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
79static void bfa_ioc_recover(struct bfa_ioc_s *ioc); 90static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
80static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc);
81static void bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc);
82static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); 91static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
83static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); 92static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
84 93
@@ -508,14 +517,19 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
508 bfa_trc(ioc, event); 517 bfa_trc(ioc, event);
509 518
510 switch (event) { 519 switch (event) {
511 case IOC_E_HWERROR:
512 case IOC_E_FWRSP_DISABLE: 520 case IOC_E_FWRSP_DISABLE:
513 bfa_ioc_timer_stop(ioc); 521 bfa_ioc_timer_stop(ioc);
522 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
523 break;
524
525 case IOC_E_HWERROR:
526 bfa_ioc_timer_stop(ioc);
514 /* 527 /*
515 * !!! fall through !!! 528 * !!! fall through !!!
516 */ 529 */
517 530
518 case IOC_E_TIMEOUT: 531 case IOC_E_TIMEOUT:
532 bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
519 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); 533 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
520 break; 534 break;
521 535
@@ -608,15 +622,12 @@ bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc)
608 * Mark IOC as failed in hardware and stop firmware. 622 * Mark IOC as failed in hardware and stop firmware.
609 */ 623 */
610 bfa_ioc_lpu_stop(ioc); 624 bfa_ioc_lpu_stop(ioc);
611 bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL); 625 bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
612 626
613 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { 627 /**
614 bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); 628 * Notify other functions on HB failure.
615 /* 629 */
616 * Wait for halt to take effect 630 bfa_ioc_notify_hbfail(ioc);
617 */
618 bfa_reg_read(ioc->ioc_regs.ll_halt);
619 }
620 631
621 /** 632 /**
622 * Notify driver and common modules registered for notification. 633 * Notify driver and common modules registered for notification.
@@ -672,6 +683,12 @@ bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event)
672 */ 683 */
673 break; 684 break;
674 685
686 case IOC_E_HWERROR:
687 /*
688 * HB failure notification, ignore.
689 */
690 break;
691
675 default: 692 default:
676 bfa_sm_fault(ioc, event); 693 bfa_sm_fault(ioc, event);
677 } 694 }
@@ -700,7 +717,7 @@ bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
700 } 717 }
701} 718}
702 719
703static void 720void
704bfa_ioc_sem_timeout(void *ioc_arg) 721bfa_ioc_sem_timeout(void *ioc_arg)
705{ 722{
706 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg; 723 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
@@ -708,26 +725,32 @@ bfa_ioc_sem_timeout(void *ioc_arg)
708 bfa_ioc_hw_sem_get(ioc); 725 bfa_ioc_hw_sem_get(ioc);
709} 726}
710 727
711static void 728bfa_boolean_t
712bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc) 729bfa_ioc_sem_get(bfa_os_addr_t sem_reg)
713{ 730{
714 u32 r32; 731 u32 r32;
715 int cnt = 0; 732 int cnt = 0;
716#define BFA_SEM_SPINCNT 1000 733#define BFA_SEM_SPINCNT 3000
717 734
718 do { 735 r32 = bfa_reg_read(sem_reg);
719 r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg); 736
737 while (r32 && (cnt < BFA_SEM_SPINCNT)) {
720 cnt++; 738 cnt++;
721 if (cnt > BFA_SEM_SPINCNT) 739 bfa_os_udelay(2);
722 break; 740 r32 = bfa_reg_read(sem_reg);
723 } while (r32 != 0); 741 }
742
743 if (r32 == 0)
744 return BFA_TRUE;
745
724 bfa_assert(cnt < BFA_SEM_SPINCNT); 746 bfa_assert(cnt < BFA_SEM_SPINCNT);
747 return BFA_FALSE;
725} 748}
726 749
727static void 750void
728bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc) 751bfa_ioc_sem_release(bfa_os_addr_t sem_reg)
729{ 752{
730 bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1); 753 bfa_reg_write(sem_reg, 1);
731} 754}
732 755
733static void 756static void
@@ -737,7 +760,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
737 760
738 /** 761 /**
739 * First read to the semaphore register will return 0, subsequent reads 762 * First read to the semaphore register will return 0, subsequent reads
740 * will return 1. Semaphore is released by writing 0 to the register 763 * will return 1. Semaphore is released by writing 1 to the register
741 */ 764 */
742 r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); 765 r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
743 if (r32 == 0) { 766 if (r32 == 0) {
@@ -746,10 +769,10 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
746 } 769 }
747 770
748 bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout, 771 bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout,
749 ioc, BFA_IOC_TOV); 772 ioc, BFA_IOC_HWSEM_TOV);
750} 773}
751 774
752static void 775void
753bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc) 776bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
754{ 777{
755 bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1); 778 bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
@@ -828,7 +851,7 @@ bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
828/** 851/**
829 * Get driver and firmware versions. 852 * Get driver and firmware versions.
830 */ 853 */
831static void 854void
832bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) 855bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
833{ 856{
834 u32 pgnum, pgoff; 857 u32 pgnum, pgoff;
@@ -847,24 +870,10 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
847 } 870 }
848} 871}
849 872
850static u32 *
851bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
852{
853 if (ioc->ctdev)
854 return bfi_image_ct_get_chunk(off);
855 return bfi_image_cb_get_chunk(off);
856}
857
858static u32
859bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc)
860{
861return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size;
862}
863
864/** 873/**
865 * Returns TRUE if same. 874 * Returns TRUE if same.
866 */ 875 */
867static bfa_boolean_t 876bfa_boolean_t
868bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) 877bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
869{ 878{
870 struct bfi_ioc_image_hdr_s *drv_fwhdr; 879 struct bfi_ioc_image_hdr_s *drv_fwhdr;
@@ -921,95 +930,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
921} 930}
922 931
923/** 932/**
924 * Return true if firmware of current driver matches the running firmware.
925 */
926static bfa_boolean_t
927bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc)
928{
929 enum bfi_ioc_state ioc_fwstate;
930 u32 usecnt;
931 struct bfi_ioc_image_hdr_s fwhdr;
932
933 /**
934 * Firmware match check is relevant only for CNA.
935 */
936 if (!ioc->cna)
937 return BFA_TRUE;
938
939 /**
940 * If bios boot (flash based) -- do not increment usage count
941 */
942 if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
943 return BFA_TRUE;
944
945 bfa_ioc_usage_sem_get(ioc);
946 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
947
948 /**
949 * If usage count is 0, always return TRUE.
950 */
951 if (usecnt == 0) {
952 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
953 bfa_ioc_usage_sem_release(ioc);
954 bfa_trc(ioc, usecnt);
955 return BFA_TRUE;
956 }
957
958 ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
959 bfa_trc(ioc, ioc_fwstate);
960
961 /**
962 * Use count cannot be non-zero and chip in uninitialized state.
963 */
964 bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
965
966 /**
967 * Check if another driver with a different firmware is active
968 */
969 bfa_ioc_fwver_get(ioc, &fwhdr);
970 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
971 bfa_ioc_usage_sem_release(ioc);
972 bfa_trc(ioc, usecnt);
973 return BFA_FALSE;
974 }
975
976 /**
977 * Same firmware version. Increment the reference count.
978 */
979 usecnt++;
980 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
981 bfa_ioc_usage_sem_release(ioc);
982 bfa_trc(ioc, usecnt);
983 return BFA_TRUE;
984}
985
986static void
987bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc)
988{
989 u32 usecnt;
990
991 /**
992 * Firmware lock is relevant only for CNA.
993 * If bios boot (flash based) -- do not decrement usage count
994 */
995 if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ))
996 return;
997
998 /**
999 * decrement usage count
1000 */
1001 bfa_ioc_usage_sem_get(ioc);
1002 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
1003 bfa_assert(usecnt > 0);
1004
1005 usecnt--;
1006 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
1007 bfa_trc(ioc, usecnt);
1008
1009 bfa_ioc_usage_sem_release(ioc);
1010}
1011
1012/**
1013 * Conditionally flush any pending message from firmware at start. 933 * Conditionally flush any pending message from firmware at start.
1014 */ 934 */
1015static void 935static void
@@ -1152,33 +1072,27 @@ bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
1152static void 1072static void
1153bfa_ioc_hb_check(void *cbarg) 1073bfa_ioc_hb_check(void *cbarg)
1154{ 1074{
1155 struct bfa_ioc_s *ioc = cbarg; 1075 struct bfa_ioc_s *ioc = cbarg;
1156 u32 hb_count; 1076 u32 hb_count;
1157 1077
1158 hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); 1078 hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
1159 if (ioc->hb_count == hb_count) { 1079 if (ioc->hb_count == hb_count) {
1160 ioc->hb_fail++; 1080 bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE,
1161 } else { 1081 hb_count);
1162 ioc->hb_count = hb_count;
1163 ioc->hb_fail = 0;
1164 }
1165
1166 if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) {
1167 bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count);
1168 ioc->hb_fail = 0;
1169 bfa_ioc_recover(ioc); 1082 bfa_ioc_recover(ioc);
1170 return; 1083 return;
1084 } else {
1085 ioc->hb_count = hb_count;
1171 } 1086 }
1172 1087
1173 bfa_ioc_mbox_poll(ioc); 1088 bfa_ioc_mbox_poll(ioc);
1174 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, 1089 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check,
1175 BFA_IOC_HB_TOV); 1090 ioc, BFA_IOC_HB_TOV);
1176} 1091}
1177 1092
1178static void 1093static void
1179bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc) 1094bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
1180{ 1095{
1181 ioc->hb_fail = 0;
1182 ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); 1096 ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
1183 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, 1097 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
1184 BFA_IOC_HB_TOV); 1098 BFA_IOC_HB_TOV);
@@ -1191,112 +1105,6 @@ bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
1191} 1105}
1192 1106
1193/** 1107/**
1194 * Host to LPU mailbox message addresses
1195 */
1196static struct {
1197 u32 hfn_mbox, lpu_mbox, hfn_pgn;
1198} iocreg_fnreg[] = {
1199 {
1200 HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, {
1201 HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, {
1202 HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, {
1203 HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3}
1204};
1205
1206/**
1207 * Host <-> LPU mailbox command/status registers - port 0
1208 */
1209static struct {
1210 u32 hfn, lpu;
1211} iocreg_mbcmd_p0[] = {
1212 {
1213 HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, {
1214 HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, {
1215 HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, {
1216 HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT}
1217};
1218
1219/**
1220 * Host <-> LPU mailbox command/status registers - port 1
1221 */
1222static struct {
1223 u32 hfn, lpu;
1224} iocreg_mbcmd_p1[] = {
1225 {
1226 HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, {
1227 HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, {
1228 HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, {
1229 HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT}
1230};
1231
1232/**
1233 * Shared IRQ handling in INTX mode
1234 */
1235static struct {
1236 u32 isr, msk;
1237} iocreg_shirq_next[] = {
1238 {
1239 HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, {
1240 HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, {
1241 HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, {
1242HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},};
1243
1244static void
1245bfa_ioc_reg_init(struct bfa_ioc_s *ioc)
1246{
1247 bfa_os_addr_t rb;
1248 int pcifn = bfa_ioc_pcifn(ioc);
1249
1250 rb = bfa_ioc_bar0(ioc);
1251
1252 ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
1253 ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
1254 ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
1255
1256 if (ioc->port_id == 0) {
1257 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
1258 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
1259 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
1260 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
1261 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
1262 } else {
1263 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
1264 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
1265 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
1266 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
1267 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
1268 }
1269
1270 /**
1271 * Shared IRQ handling in INTX mode
1272 */
1273 ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr;
1274 ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk;
1275
1276 /*
1277 * PSS control registers
1278 */
1279 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
1280 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
1281 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
1282
1283 /*
1284 * IOC semaphore registers and serialization
1285 */
1286 ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
1287 ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
1288 ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
1289
1290 /**
1291 * sram memory access
1292 */
1293 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
1294 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
1295 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT)
1296 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
1297}
1298
1299/**
1300 * Initiate a full firmware download. 1108 * Initiate a full firmware download.
1301 */ 1109 */
1302static void 1110static void
@@ -1332,17 +1140,17 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1332 1140
1333 for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) { 1141 for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
1334 1142
1335 if (BFA_FLASH_CHUNK_NO(i) != chunkno) { 1143 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
1336 chunkno = BFA_FLASH_CHUNK_NO(i); 1144 chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
1337 fwimg = bfa_ioc_fwimg_get_chunk(ioc, 1145 fwimg = bfa_ioc_fwimg_get_chunk(ioc,
1338 BFA_FLASH_CHUNK_ADDR(chunkno)); 1146 BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1339 } 1147 }
1340 1148
1341 /** 1149 /**
1342 * write smem 1150 * write smem
1343 */ 1151 */
1344 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 1152 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
1345 fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]); 1153 fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
1346 1154
1347 loff += sizeof(u32); 1155 loff += sizeof(u32);
1348 1156
@@ -1440,168 +1248,10 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
1440} 1248}
1441 1249
1442/** 1250/**
1443 * Initialize IOC to port mapping.
1444 */
1445
1446#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
1447static void
1448bfa_ioc_map_port(struct bfa_ioc_s *ioc)
1449{
1450 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1451 u32 r32;
1452
1453 /**
1454 * For crossbow, port id is same as pci function.
1455 */
1456 if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) {
1457 ioc->port_id = bfa_ioc_pcifn(ioc);
1458 return;
1459 }
1460
1461 /**
1462 * For catapult, base port id on personality register and IOC type
1463 */
1464 r32 = bfa_reg_read(rb + FNC_PERS_REG);
1465 r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
1466 ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
1467
1468 bfa_trc(ioc, bfa_ioc_pcifn(ioc));
1469 bfa_trc(ioc, ioc->port_id);
1470}
1471
1472
1473
1474/**
1475 * bfa_ioc_public 1251 * bfa_ioc_public
1476 */ 1252 */
1477 1253
1478/** 1254/**
1479* Set interrupt mode for a function: INTX or MSIX
1480 */
1481void
1482bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
1483{
1484 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1485 u32 r32, mode;
1486
1487 r32 = bfa_reg_read(rb + FNC_PERS_REG);
1488 bfa_trc(ioc, r32);
1489
1490 mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
1491 __F0_INTX_STATUS;
1492
1493 /**
1494 * If already in desired mode, do not change anything
1495 */
1496 if (!msix && mode)
1497 return;
1498
1499 if (msix)
1500 mode = __F0_INTX_STATUS_MSIX;
1501 else
1502 mode = __F0_INTX_STATUS_INTA;
1503
1504 r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
1505 r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
1506 bfa_trc(ioc, r32);
1507
1508 bfa_reg_write(rb + FNC_PERS_REG, r32);
1509}
1510
1511bfa_status_t
1512bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
1513{
1514 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1515 u32 pll_sclk, pll_fclk, r32;
1516
1517 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
1518 pll_sclk =
1519 __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
1520 __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
1521 __APP_PLL_312_JITLMT0_1(3U) |
1522 __APP_PLL_312_CNTLMT0_1(1U);
1523 pll_fclk =
1524 __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
1525 __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
1526 __APP_PLL_425_JITLMT0_1(3U) |
1527 __APP_PLL_425_CNTLMT0_1(1U);
1528
1529 /**
1530 * For catapult, choose operational mode FC/FCoE
1531 */
1532 if (ioc->fcmode) {
1533 bfa_reg_write((rb + OP_MODE), 0);
1534 bfa_reg_write((rb + ETH_MAC_SER_REG),
1535 __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2
1536 | __APP_EMS_CHANNEL_SEL);
1537 } else {
1538 ioc->pllinit = BFA_TRUE;
1539 bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
1540 bfa_reg_write((rb + ETH_MAC_SER_REG),
1541 __APP_EMS_REFCKBUFEN1);
1542 }
1543 } else {
1544 pll_sclk =
1545 __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
1546 __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) |
1547 __APP_PLL_312_CNTLMT0_1(3U);
1548 pll_fclk =
1549 __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
1550 __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
1551 __APP_PLL_425_JITLMT0_1(3U) |
1552 __APP_PLL_425_CNTLMT0_1(3U);
1553 }
1554
1555 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
1556 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
1557
1558 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
1559 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
1560 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
1561 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
1562 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
1563 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
1564
1565 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1566 __APP_PLL_312_LOGIC_SOFT_RESET);
1567 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1568 __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET);
1569 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1570 __APP_PLL_425_LOGIC_SOFT_RESET);
1571 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1572 __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET);
1573 bfa_os_udelay(2);
1574 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1575 __APP_PLL_312_LOGIC_SOFT_RESET);
1576 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1577 __APP_PLL_425_LOGIC_SOFT_RESET);
1578
1579 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1580 pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
1581 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1582 pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
1583
1584 /**
1585 * Wait for PLLs to lock.
1586 */
1587 bfa_os_udelay(2000);
1588 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
1589 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
1590
1591 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
1592 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
1593
1594 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
1595 bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
1596 bfa_os_udelay(1000);
1597 r32 = bfa_reg_read((rb + MBIST_STAT_REG));
1598 bfa_trc(ioc, r32);
1599 }
1600
1601 return BFA_STATUS_OK;
1602}
1603
1604/**
1605 * Interface used by diag module to do firmware boot with memory test 1255 * Interface used by diag module to do firmware boot with memory test
1606 * as the entry vector. 1256 * as the entry vector.
1607 */ 1257 */
@@ -1764,6 +1414,14 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
1764 ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT); 1414 ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
1765 ioc->cna = ioc->ctdev && !ioc->fcmode; 1415 ioc->cna = ioc->ctdev && !ioc->fcmode;
1766 1416
1417 /**
1418 * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
1419 */
1420 if (ioc->ctdev)
1421 bfa_ioc_set_ct_hwif(ioc);
1422 else
1423 bfa_ioc_set_cb_hwif(ioc);
1424
1767 bfa_ioc_map_port(ioc); 1425 bfa_ioc_map_port(ioc);
1768 bfa_ioc_reg_init(ioc); 1426 bfa_ioc_reg_init(ioc);
1769} 1427}
@@ -1973,7 +1631,7 @@ bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
1973 ((__sm) == BFI_IOC_INITING) || \ 1631 ((__sm) == BFI_IOC_INITING) || \
1974 ((__sm) == BFI_IOC_HWINIT) || \ 1632 ((__sm) == BFI_IOC_HWINIT) || \
1975 ((__sm) == BFI_IOC_DISABLED) || \ 1633 ((__sm) == BFI_IOC_DISABLED) || \
1976 ((__sm) == BFI_IOC_HBFAIL) || \ 1634 ((__sm) == BFI_IOC_FAIL) || \
1977 ((__sm) == BFI_IOC_CFG_DISABLED)) 1635 ((__sm) == BFI_IOC_CFG_DISABLED))
1978 1636
1979/** 1637/**
@@ -2195,29 +1853,6 @@ bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
2195} 1853}
2196 1854
2197/** 1855/**
2198 * Return true if interrupt should be claimed.
2199 */
2200bfa_boolean_t
2201bfa_ioc_intx_claim(struct bfa_ioc_s *ioc)
2202{
2203 u32 isr, msk;
2204
2205 /**
2206 * Always claim if not catapult.
2207 */
2208 if (!ioc->ctdev)
2209 return BFA_TRUE;
2210
2211 /**
2212 * FALSE if next device is claiming interrupt.
2213 * TRUE if next device is not interrupting or not present.
2214 */
2215 msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next);
2216 isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next);
2217 return !(isr & ~msk);
2218}
2219
2220/**
2221 * Send AEN notification 1856 * Send AEN notification
2222 */ 1857 */
2223static void 1858static void
@@ -2304,6 +1939,13 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2304 1939
2305 pgnum = bfa_ioc_smem_pgnum(ioc, loff); 1940 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
2306 loff = bfa_ioc_smem_pgoff(ioc, loff); 1941 loff = bfa_ioc_smem_pgoff(ioc, loff);
1942
1943 /*
1944 * Hold semaphore to serialize pll init and fwtrc.
1945 */
1946 if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg))
1947 return BFA_STATUS_FAILED;
1948
2307 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum); 1949 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
2308 1950
2309 tlen = *trclen; 1951 tlen = *trclen;
@@ -2329,6 +1971,12 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2329 } 1971 }
2330 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, 1972 bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
2331 bfa_ioc_smem_pgnum(ioc, 0)); 1973 bfa_ioc_smem_pgnum(ioc, 0));
1974
1975 /*
1976 * release semaphore.
1977 */
1978 bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
1979
2332 bfa_trc(ioc, pgnum); 1980 bfa_trc(ioc, pgnum);
2333 1981
2334 *trclen = tlen * sizeof(u32); 1982 *trclen = tlen * sizeof(u32);
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index 7c30f05ab137..1633a50187f7 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -78,11 +78,13 @@ struct bfa_ioc_regs_s {
78 bfa_os_addr_t app_pll_slow_ctl_reg; 78 bfa_os_addr_t app_pll_slow_ctl_reg;
79 bfa_os_addr_t ioc_sem_reg; 79 bfa_os_addr_t ioc_sem_reg;
80 bfa_os_addr_t ioc_usage_sem_reg; 80 bfa_os_addr_t ioc_usage_sem_reg;
81 bfa_os_addr_t ioc_init_sem_reg;
81 bfa_os_addr_t ioc_usage_reg; 82 bfa_os_addr_t ioc_usage_reg;
82 bfa_os_addr_t host_page_num_fn; 83 bfa_os_addr_t host_page_num_fn;
83 bfa_os_addr_t heartbeat; 84 bfa_os_addr_t heartbeat;
84 bfa_os_addr_t ioc_fwstate; 85 bfa_os_addr_t ioc_fwstate;
85 bfa_os_addr_t ll_halt; 86 bfa_os_addr_t ll_halt;
87 bfa_os_addr_t err_set;
86 bfa_os_addr_t shirq_isr_next; 88 bfa_os_addr_t shirq_isr_next;
87 bfa_os_addr_t shirq_msk_next; 89 bfa_os_addr_t shirq_msk_next;
88 bfa_os_addr_t smem_page_start; 90 bfa_os_addr_t smem_page_start;
@@ -154,7 +156,6 @@ struct bfa_ioc_s {
154 struct bfa_timer_s ioc_timer; 156 struct bfa_timer_s ioc_timer;
155 struct bfa_timer_s sem_timer; 157 struct bfa_timer_s sem_timer;
156 u32 hb_count; 158 u32 hb_count;
157 u32 hb_fail;
158 u32 retry_count; 159 u32 retry_count;
159 struct list_head hb_notify_q; 160 struct list_head hb_notify_q;
160 void *dbg_fwsave; 161 void *dbg_fwsave;
@@ -177,6 +178,22 @@ struct bfa_ioc_s {
177 struct bfi_ioc_attr_s *attr; 178 struct bfi_ioc_attr_s *attr;
178 struct bfa_ioc_cbfn_s *cbfn; 179 struct bfa_ioc_cbfn_s *cbfn;
179 struct bfa_ioc_mbox_mod_s mbox_mod; 180 struct bfa_ioc_mbox_mod_s mbox_mod;
181 struct bfa_ioc_hwif_s *ioc_hwif;
182};
183
184struct bfa_ioc_hwif_s {
185 bfa_status_t (*ioc_pll_init) (struct bfa_ioc_s *ioc);
186 bfa_boolean_t (*ioc_firmware_lock) (struct bfa_ioc_s *ioc);
187 void (*ioc_firmware_unlock) (struct bfa_ioc_s *ioc);
188 u32 * (*ioc_fwimg_get_chunk) (struct bfa_ioc_s *ioc,
189 u32 off);
190 u32 (*ioc_fwimg_get_size) (struct bfa_ioc_s *ioc);
191 void (*ioc_reg_init) (struct bfa_ioc_s *ioc);
192 void (*ioc_map_port) (struct bfa_ioc_s *ioc);
193 void (*ioc_isr_mode_set) (struct bfa_ioc_s *ioc,
194 bfa_boolean_t msix);
195 void (*ioc_notify_hbfail) (struct bfa_ioc_s *ioc);
196 void (*ioc_ownership_reset) (struct bfa_ioc_s *ioc);
180}; 197};
181 198
182#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) 199#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
@@ -191,6 +208,15 @@ struct bfa_ioc_s {
191#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit) 208#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit)
192#define bfa_ioc_speed_sup(__ioc) \ 209#define bfa_ioc_speed_sup(__ioc) \
193 BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop) 210 BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
211#define bfa_ioc_get_nports(__ioc) \
212 BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
213
214#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
215#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
216
217#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
218#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
219#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
194 220
195/** 221/**
196 * IOC mailbox interface 222 * IOC mailbox interface
@@ -207,6 +233,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
207/** 233/**
208 * IOC interfaces 234 * IOC interfaces
209 */ 235 */
236#define bfa_ioc_pll_init(__ioc) ((__ioc)->ioc_hwif->ioc_pll_init(__ioc))
237#define bfa_ioc_isr_mode_set(__ioc, __msix) \
238 ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
239#define bfa_ioc_ownership_reset(__ioc) \
240 ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
241
242void bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc);
243void bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc);
210void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, 244void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
211 struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod, 245 struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod,
212 struct bfa_trc_mod_s *trcmod, 246 struct bfa_trc_mod_s *trcmod,
@@ -223,8 +257,6 @@ bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc);
223void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param); 257void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param);
224void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg); 258void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
225void bfa_ioc_error_isr(struct bfa_ioc_s *ioc); 259void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
226void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx);
227bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc);
228bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc); 260bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
229bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc); 261bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
230bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc); 262bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
@@ -245,6 +277,13 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc);
245bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc); 277bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
246void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc, 278void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
247 struct bfa_ioc_hbfail_notify_s *notify); 279 struct bfa_ioc_hbfail_notify_s *notify);
280bfa_boolean_t bfa_ioc_sem_get(bfa_os_addr_t sem_reg);
281void bfa_ioc_sem_release(bfa_os_addr_t sem_reg);
282void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
283void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
284 struct bfi_ioc_image_hdr_s *fwhdr);
285bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
286 struct bfi_ioc_image_hdr_s *fwhdr);
248 287
249/* 288/*
250 * bfa mfg wwn API functions 289 * bfa mfg wwn API functions
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c
new file mode 100644
index 000000000000..d1d625bcd721
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioc_cb.c
@@ -0,0 +1,273 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_ioc.h>
20#include <bfa_fwimg_priv.h>
21#include <cna/bfa_cna_trcmod.h>
22#include <cs/bfa_debug.h>
23#include <bfi/bfi_ioc.h>
24#include <bfi/bfi_cbreg.h>
25#include <log/bfa_log_hal.h>
26#include <defs/bfa_defs_pci.h>
27
28BFA_TRC_FILE(CNA, IOC_CB);
29
30/*
31 * forward declarations
32 */
33static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc);
34static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc);
35static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
36static u32 *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off);
37static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc);
38static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
39static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
40static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
41static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc);
42static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
43
44struct bfa_ioc_hwif_s hwif_cb = {
45 bfa_ioc_cb_pll_init,
46 bfa_ioc_cb_firmware_lock,
47 bfa_ioc_cb_firmware_unlock,
48 bfa_ioc_cb_fwimg_get_chunk,
49 bfa_ioc_cb_fwimg_get_size,
50 bfa_ioc_cb_reg_init,
51 bfa_ioc_cb_map_port,
52 bfa_ioc_cb_isr_mode_set,
53 bfa_ioc_cb_notify_hbfail,
54 bfa_ioc_cb_ownership_reset,
55};
56
57/**
58 * Called from bfa_ioc_attach() to map asic specific calls.
59 */
60void
61bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
62{
63 ioc->ioc_hwif = &hwif_cb;
64}
65
66static uint32_t *
67bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, uint32_t off)
68{
69 return bfi_image_cb_get_chunk(off);
70}
71
72static uint32_t
73bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc)
74{
75 return bfi_image_cb_size;
76}
77
78/**
79 * Return true if firmware of current driver matches the running firmware.
80 */
81static bfa_boolean_t
82bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
83{
84 return BFA_TRUE;
85}
86
87static void
88bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc)
89{
90}
91
92/**
93 * Notify other functions on HB failure.
94 */
95static void
96bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc)
97{
98 bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
99 bfa_reg_read(ioc->ioc_regs.err_set);
100}
101
102/**
103 * Host to LPU mailbox message addresses
104 */
105static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
106 { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
107 { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }
108};
109
110/**
111 * Host <-> LPU mailbox command/status registers
112 */
113static struct { uint32_t hfn, lpu; } iocreg_mbcmd[] = {
114 { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
115 { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT }
116};
117
118static void
119bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
120{
121 bfa_os_addr_t rb;
122 int pcifn = bfa_ioc_pcifn(ioc);
123
124 rb = bfa_ioc_bar0(ioc);
125
126 ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
127 ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
128 ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
129
130 if (ioc->port_id == 0) {
131 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
132 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
133 } else {
134 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
135 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
136 }
137
138 /**
139 * Host <-> LPU mailbox command/status registers
140 */
141 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn;
142 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu;
143
144 /*
145 * PSS control registers
146 */
147 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
148 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG);
149 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG);
150
151 /*
152 * IOC semaphore registers and serialization
153 */
154 ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
155 ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
156
157 /**
158 * sram memory access
159 */
160 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
161 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
162
163 /*
164 * err set reg : for notification of hb failure
165 */
166 ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
167}
168
169/**
170 * Initialize IOC to port mapping.
171 */
172static void
173bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc)
174{
175 /**
176 * For crossbow, port id is same as pci function.
177 */
178 ioc->port_id = bfa_ioc_pcifn(ioc);
179 bfa_trc(ioc, ioc->port_id);
180}
181
182/**
183 * Set interrupt mode for a function: INTX or MSIX
184 */
185static void
186bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
187{
188}
189
190static bfa_status_t
191bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc)
192{
193 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
194 uint32_t pll_sclk, pll_fclk;
195
196 /*
197 * Hold semaphore so that nobody can access the chip during init.
198 */
199 bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
200
201 pll_sclk = __APP_PLL_212_ENABLE | __APP_PLL_212_LRESETN |
202 __APP_PLL_212_P0_1(3U) |
203 __APP_PLL_212_JITLMT0_1(3U) |
204 __APP_PLL_212_CNTLMT0_1(3U);
205 pll_fclk = __APP_PLL_400_ENABLE | __APP_PLL_400_LRESETN |
206 __APP_PLL_400_RSEL200500 | __APP_PLL_400_P0_1(3U) |
207 __APP_PLL_400_JITLMT0_1(3U) |
208 __APP_PLL_400_CNTLMT0_1(3U);
209
210 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
211 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
212
213 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
214 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
215 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
216 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
217 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
218 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
219
220 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
221 __APP_PLL_212_LOGIC_SOFT_RESET);
222 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
223 __APP_PLL_212_BYPASS |
224 __APP_PLL_212_LOGIC_SOFT_RESET);
225 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
226 __APP_PLL_400_LOGIC_SOFT_RESET);
227 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
228 __APP_PLL_400_BYPASS |
229 __APP_PLL_400_LOGIC_SOFT_RESET);
230 bfa_os_udelay(2);
231 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
232 __APP_PLL_212_LOGIC_SOFT_RESET);
233 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
234 __APP_PLL_400_LOGIC_SOFT_RESET);
235
236 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
237 pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET);
238 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
239 pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET);
240
241 /**
242 * Wait for PLLs to lock.
243 */
244 bfa_os_udelay(2000);
245 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
246 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
247
248 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
249 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
250
251 /*
252 * release semaphore.
253 */
254 bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
255
256 return BFA_STATUS_OK;
257}
258
259/**
260 * Cleanup hw semaphore and usecnt registers
261 */
262static void
263bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
264{
265
266 /*
267 * Read the hw sem reg to make sure that it is locked
268 * before we clear it. If it is not locked, writing 1
269 * will lock it instead of clearing it.
270 */
271 bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
272 bfa_ioc_hw_sem_release(ioc);
273}
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
new file mode 100644
index 000000000000..5de9c24efacf
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioc_ct.c
@@ -0,0 +1,422 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_ioc.h>
20#include <bfa_fwimg_priv.h>
21#include <cna/bfa_cna_trcmod.h>
22#include <cs/bfa_debug.h>
23#include <bfi/bfi_ioc.h>
24#include <bfi/bfi_ctreg.h>
25#include <log/bfa_log_hal.h>
26#include <defs/bfa_defs_pci.h>
27
28BFA_TRC_FILE(CNA, IOC_CT);
29
30/*
31 * forward declarations
32 */
33static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc);
34static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
35static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
36static uint32_t* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
37 uint32_t off);
38static uint32_t bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc);
39static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
40static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
41static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
42static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
43static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
44
45struct bfa_ioc_hwif_s hwif_ct = {
46 bfa_ioc_ct_pll_init,
47 bfa_ioc_ct_firmware_lock,
48 bfa_ioc_ct_firmware_unlock,
49 bfa_ioc_ct_fwimg_get_chunk,
50 bfa_ioc_ct_fwimg_get_size,
51 bfa_ioc_ct_reg_init,
52 bfa_ioc_ct_map_port,
53 bfa_ioc_ct_isr_mode_set,
54 bfa_ioc_ct_notify_hbfail,
55 bfa_ioc_ct_ownership_reset,
56};
57
58/**
59 * Called from bfa_ioc_attach() to map asic specific calls.
60 */
61void
62bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
63{
64 ioc->ioc_hwif = &hwif_ct;
65}
66
67static uint32_t*
68bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, uint32_t off)
69{
70 return bfi_image_ct_get_chunk(off);
71}
72
73static uint32_t
74bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc)
75{
76 return bfi_image_ct_size;
77}
78
79/**
80 * Return true if firmware of current driver matches the running firmware.
81 */
82static bfa_boolean_t
83bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
84{
85 enum bfi_ioc_state ioc_fwstate;
86 uint32_t usecnt;
87 struct bfi_ioc_image_hdr_s fwhdr;
88
89 /**
90 * Firmware match check is relevant only for CNA.
91 */
92 if (!ioc->cna)
93 return BFA_TRUE;
94
95 /**
96 * If bios boot (flash based) -- do not increment usage count
97 */
98 if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
99 return BFA_TRUE;
100
101 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
102 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
103
104 /**
105 * If usage count is 0, always return TRUE.
106 */
107 if (usecnt == 0) {
108 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
109 bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
110 bfa_trc(ioc, usecnt);
111 return BFA_TRUE;
112 }
113
114 ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
115 bfa_trc(ioc, ioc_fwstate);
116
117 /**
118 * Use count cannot be non-zero and chip in uninitialized state.
119 */
120 bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
121
122 /**
123 * Check if another driver with a different firmware is active
124 */
125 bfa_ioc_fwver_get(ioc, &fwhdr);
126 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
127 bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
128 bfa_trc(ioc, usecnt);
129 return BFA_FALSE;
130 }
131
132 /**
133 * Same firmware version. Increment the reference count.
134 */
135 usecnt++;
136 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
137 bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
138 bfa_trc(ioc, usecnt);
139 return BFA_TRUE;
140}
141
142static void
143bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
144{
145 uint32_t usecnt;
146
147 /**
148 * Firmware lock is relevant only for CNA.
149 * If bios boot (flash based) -- do not decrement usage count
150 */
151 if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
152 return;
153
154 /**
155 * decrement usage count
156 */
157 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
158 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
159 bfa_assert(usecnt > 0);
160
161 usecnt--;
162 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
163 bfa_trc(ioc, usecnt);
164
165 bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
166}
167
168/**
169 * Notify other functions on HB failure.
170 */
171static void
172bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc)
173{
174
175 bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
176 /* Wait for halt to take effect */
177 bfa_reg_read(ioc->ioc_regs.ll_halt);
178}
179
180/**
181 * Host to LPU mailbox message addresses
182 */
183static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
184 { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
185 { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
186 { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
187 { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
188};
189
190/**
191 * Host <-> LPU mailbox command/status registers - port 0
192 */
193static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p0[] = {
194 { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
195 { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
196 { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
197 { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
198};
199
200/**
201 * Host <-> LPU mailbox command/status registers - port 1
202 */
203static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p1[] = {
204 { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
205 { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
206 { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
207 { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
208};
209
210static void
211bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
212{
213 bfa_os_addr_t rb;
214 int pcifn = bfa_ioc_pcifn(ioc);
215
216 rb = bfa_ioc_bar0(ioc);
217
218 ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
219 ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
220 ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
221
222 if (ioc->port_id == 0) {
223 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
224 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
225 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
226 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
227 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
228 } else {
229 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
230 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
231 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
232 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
233 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
234 }
235
236 /*
237 * PSS control registers
238 */
239 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
240 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
241 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
242
243 /*
244 * IOC semaphore registers and serialization
245 */
246 ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
247 ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
248 ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
249 ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
250
251 /**
252 * sram memory access
253 */
254 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
255 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
256}
257
258/**
259 * Initialize IOC to port mapping.
260 */
261
262#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
263static void
264bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
265{
266 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
267 uint32_t r32;
268
269 /**
270 * For catapult, base port id on personality register and IOC type
271 */
272 r32 = bfa_reg_read(rb + FNC_PERS_REG);
273 r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
274 ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
275
276 bfa_trc(ioc, bfa_ioc_pcifn(ioc));
277 bfa_trc(ioc, ioc->port_id);
278}
279
280/**
281 * Set interrupt mode for a function: INTX or MSIX
282 */
283static void
284bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
285{
286 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
287 uint32_t r32, mode;
288
289 r32 = bfa_reg_read(rb + FNC_PERS_REG);
290 bfa_trc(ioc, r32);
291
292 mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
293 __F0_INTX_STATUS;
294
295 /**
296 * If already in desired mode, do not change anything
297 */
298 if (!msix && mode)
299 return;
300
301 if (msix)
302 mode = __F0_INTX_STATUS_MSIX;
303 else
304 mode = __F0_INTX_STATUS_INTA;
305
306 r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
307 r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
308 bfa_trc(ioc, r32);
309
310 bfa_reg_write(rb + FNC_PERS_REG, r32);
311}
312
313static bfa_status_t
314bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
315{
316 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
317 uint32_t pll_sclk, pll_fclk, r32;
318
319 /*
320 * Hold semaphore so that nobody can access the chip during init.
321 */
322 bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
323
324 pll_sclk = __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
325 __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
326 __APP_PLL_312_JITLMT0_1(3U) |
327 __APP_PLL_312_CNTLMT0_1(1U);
328 pll_fclk = __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
329 __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
330 __APP_PLL_425_JITLMT0_1(3U) |
331 __APP_PLL_425_CNTLMT0_1(1U);
332
333 /**
334 * For catapult, choose operational mode FC/FCoE
335 */
336 if (ioc->fcmode) {
337 bfa_reg_write((rb + OP_MODE), 0);
338 bfa_reg_write((rb + ETH_MAC_SER_REG),
339 __APP_EMS_CMLCKSEL |
340 __APP_EMS_REFCKBUFEN2 |
341 __APP_EMS_CHANNEL_SEL);
342 } else {
343 ioc->pllinit = BFA_TRUE;
344 bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
345 bfa_reg_write((rb + ETH_MAC_SER_REG),
346 __APP_EMS_REFCKBUFEN1);
347 }
348
349 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
350 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
351
352 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
353 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
354 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
355 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
356 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
357 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
358
359 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
360 __APP_PLL_312_LOGIC_SOFT_RESET);
361 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
362 __APP_PLL_312_BYPASS |
363 __APP_PLL_312_LOGIC_SOFT_RESET);
364 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
365 __APP_PLL_425_LOGIC_SOFT_RESET);
366 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
367 __APP_PLL_425_BYPASS |
368 __APP_PLL_425_LOGIC_SOFT_RESET);
369 bfa_os_udelay(2);
370 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
371 __APP_PLL_312_LOGIC_SOFT_RESET);
372 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
373 __APP_PLL_425_LOGIC_SOFT_RESET);
374
375 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
376 pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
377 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
378 pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
379
380 /**
381 * Wait for PLLs to lock.
382 */
383 bfa_os_udelay(2000);
384 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
385 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
386
387 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
388 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
389
390 bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
391 bfa_os_udelay(1000);
392 r32 = bfa_reg_read((rb + MBIST_STAT_REG));
393 bfa_trc(ioc, r32);
394 /*
395 * release semaphore.
396 */
397 bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
398
399 return BFA_STATUS_OK;
400}
401
402/**
403 * Cleanup hw semaphore and usecnt registers
404 */
405static void
406bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
407{
408
409 if (ioc->cna) {
410 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
411 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0);
412 bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
413 }
414
415 /*
416 * Read the hw sem reg to make sure that it is locked
417 * before we clear it. If it is not locked, writing 1
418 * will lock it instead of clearing it.
419 */
420 bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
421 bfa_ioc_hw_sem_release(ioc);
422}
diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h
index d4bc0d9fa42c..942ae64038c9 100644
--- a/drivers/scsi/bfa/include/bfa.h
+++ b/drivers/scsi/bfa/include/bfa.h
@@ -161,6 +161,7 @@ bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa,
161void bfa_iocfc_enable(struct bfa_s *bfa); 161void bfa_iocfc_enable(struct bfa_s *bfa);
162void bfa_iocfc_disable(struct bfa_s *bfa); 162void bfa_iocfc_disable(struct bfa_s *bfa);
163void bfa_ioc_auto_recover(bfa_boolean_t auto_recover); 163void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
164void bfa_chip_reset(struct bfa_s *bfa);
164void bfa_cb_ioc_disable(void *bfad); 165void bfa_cb_ioc_disable(void *bfad);
165void bfa_timer_tick(struct bfa_s *bfa); 166void bfa_timer_tick(struct bfa_s *bfa);
166#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \ 167#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \
diff --git a/drivers/scsi/bfa/include/bfa_timer.h b/drivers/scsi/bfa/include/bfa_timer.h
index e407103fa565..f71087448222 100644
--- a/drivers/scsi/bfa/include/bfa_timer.h
+++ b/drivers/scsi/bfa/include/bfa_timer.h
@@ -41,7 +41,7 @@ struct bfa_timer_mod_s {
41 struct list_head timer_q; 41 struct list_head timer_q;
42}; 42};
43 43
44#define BFA_TIMER_FREQ 500 /**< specified in millisecs */ 44#define BFA_TIMER_FREQ 200 /**< specified in millisecs */
45 45
46void bfa_timer_beat(struct bfa_timer_mod_s *mod); 46void bfa_timer_beat(struct bfa_timer_mod_s *mod);
47void bfa_timer_init(struct bfa_timer_mod_s *mod); 47void bfa_timer_init(struct bfa_timer_mod_s *mod);
diff --git a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
index b3bb52b565b1..781cefafb659 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
@@ -177,7 +177,8 @@
177#define __PSS_LMEM_INIT_EN 0x00000100 177#define __PSS_LMEM_INIT_EN 0x00000100
178#define __PSS_LPU1_RESET 0x00000002 178#define __PSS_LPU1_RESET 0x00000002
179#define __PSS_LPU0_RESET 0x00000001 179#define __PSS_LPU0_RESET 0x00000001
180 180#define ERR_SET_REG 0x00018818
181#define __PSS_ERR_STATUS_SET 0x00000fff
181 182
182/* 183/*
183 * These definitions are either in error/missing in spec. Its auto-generated 184 * These definitions are either in error/missing in spec. Its auto-generated
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
index dd2992c38afb..d84ebae70cb4 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
@@ -430,6 +430,8 @@ enum {
430#define __PSS_LMEM_INIT_EN 0x00000100 430#define __PSS_LMEM_INIT_EN 0x00000100
431#define __PSS_LPU1_RESET 0x00000002 431#define __PSS_LPU1_RESET 0x00000002
432#define __PSS_LPU0_RESET 0x00000001 432#define __PSS_LPU0_RESET 0x00000001
433#define ERR_SET_REG 0x00018818
434#define __PSS_ERR_STATUS_SET 0x003fffff
433#define HQM_QSET0_RXQ_DRBL_P0 0x00038000 435#define HQM_QSET0_RXQ_DRBL_P0 0x00038000
434#define __RXQ0_ADD_VECTORS_P 0x80000000 436#define __RXQ0_ADD_VECTORS_P 0x80000000
435#define __RXQ0_STOP_P 0x40000000 437#define __RXQ0_STOP_P 0x40000000
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ioc.h b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
index 96ef05670659..a0158aac0024 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_ioc.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
@@ -123,7 +123,7 @@ enum bfi_ioc_state {
123 BFI_IOC_DISABLING = 5, /* IOC is being disabled */ 123 BFI_IOC_DISABLING = 5, /* IOC is being disabled */
124 BFI_IOC_DISABLED = 6, /* IOC is disabled */ 124 BFI_IOC_DISABLED = 6, /* IOC is disabled */
125 BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */ 125 BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */
126 BFI_IOC_HBFAIL = 8, /* IOC heart-beat failure */ 126 BFI_IOC_FAIL = 8, /* IOC heart-beat failure */
127 BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */ 127 BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */
128}; 128};
129 129
diff --git a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
index 43ba7064e81a..a75a1f3be315 100644
--- a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
+++ b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
@@ -31,6 +31,10 @@
31enum { 31enum {
32 BFA_TRC_CNA_CEE = 1, 32 BFA_TRC_CNA_CEE = 1,
33 BFA_TRC_CNA_PORT = 2, 33 BFA_TRC_CNA_PORT = 2,
34 BFA_TRC_CNA_IOC = 3,
35 BFA_TRC_CNA_DIAG = 4,
36 BFA_TRC_CNA_IOC_CB = 5,
37 BFA_TRC_CNA_IOC_CT = 6,
34}; 38};
35 39
36#endif /* __BFA_CNA_TRCMOD_H__ */ 40#endif /* __BFA_CNA_TRCMOD_H__ */