diff options
author | Eran Harary <eran.harary@intel.com> | 2014-10-19 06:20:14 -0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-12-01 06:00:16 -0500 |
commit | dcab8ecd561769203185edb5273bebf28f2880a6 (patch) | |
tree | a9ebbbb31cc710fe6ab7f99bdc898f00155d96f8 /drivers/net | |
parent | a993749dc99772319f731876b24819c1218074a4 (diff) |
iwlwifi: mvm: support ucode load for family_8000 B0 only
The ucode load flow changed for B0 hardware step.
Change the code accordingly.
Signed-off-by: Eran Harary <eran.harary@intel.com>
Signed-off-by: Liad Kaufman <liad.kaufman@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-prph.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/trans.c | 135 |
2 files changed, 72 insertions, 71 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 1dae702e97ef..2df51eab1348 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -322,6 +322,7 @@ enum secure_boot_config_reg { | |||
322 | LMPM_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ = 0x00000002, | 322 | LMPM_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ = 0x00000002, |
323 | }; | 323 | }; |
324 | 324 | ||
325 | #define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0 (0xA01E30) | ||
325 | #define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR (0x1E30) | 326 | #define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR (0x1E30) |
326 | #define LMPM_SECURE_BOOT_CPU2_STATUS_ADDR (0x1E34) | 327 | #define LMPM_SECURE_BOOT_CPU2_STATUS_ADDR (0x1E34) |
327 | enum secure_boot_status_reg { | 328 | enum secure_boot_status_reg { |
@@ -333,6 +334,7 @@ enum secure_boot_status_reg { | |||
333 | LMPM_SECURE_BOOT_STATUS_SUCCESS = 0x00000003, | 334 | LMPM_SECURE_BOOT_STATUS_SUCCESS = 0x00000003, |
334 | }; | 335 | }; |
335 | 336 | ||
337 | #define FH_UCODE_LOAD_STATUS (0x1AF0) | ||
336 | #define CSR_UCODE_LOAD_STATUS_ADDR (0x1E70) | 338 | #define CSR_UCODE_LOAD_STATUS_ADDR (0x1E70) |
337 | enum secure_load_status_reg { | 339 | enum secure_load_status_reg { |
338 | LMPM_CPU_UCODE_LOADING_STARTED = 0x00000001, | 340 | LMPM_CPU_UCODE_LOADING_STARTED = 0x00000001, |
@@ -349,10 +351,10 @@ enum secure_load_status_reg { | |||
349 | 351 | ||
350 | #define LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE (0x400000) | 352 | #define LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE (0x400000) |
351 | #define LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE (0x402000) | 353 | #define LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE (0x402000) |
352 | #define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x404000) | 354 | #define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x420000) |
353 | #define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x405000) | 355 | #define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x420400) |
354 | 356 | ||
355 | #define LMPM_SECURE_TIME_OUT (50000) /* 5 msec */ | 357 | #define LMPM_SECURE_TIME_OUT (100) /* 10 micro */ |
356 | 358 | ||
357 | /* Rx FIFO */ | 359 | /* Rx FIFO */ |
358 | #define RXF_SIZE_ADDR (0xa00c88) | 360 | #define RXF_SIZE_ADDR (0xa00c88) |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 7d7f05ebe05d..666925c2a673 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -665,14 +665,14 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, | |||
665 | return ret; | 665 | return ret; |
666 | } | 666 | } |
667 | 667 | ||
668 | static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans, | 668 | static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans, |
669 | const struct fw_img *image, | 669 | const struct fw_img *image, |
670 | int cpu, | 670 | int cpu, |
671 | int *first_ucode_section) | 671 | int *first_ucode_section) |
672 | { | 672 | { |
673 | int shift_param; | 673 | int shift_param; |
674 | int i, ret = 0; | 674 | int i, ret = 0, sec_num = 0x1; |
675 | u32 last_read_idx = 0; | 675 | u32 val, last_read_idx = 0; |
676 | 676 | ||
677 | if (cpu == 1) { | 677 | if (cpu == 1) { |
678 | shift_param = 0; | 678 | shift_param = 0; |
@@ -693,21 +693,16 @@ static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans, | |||
693 | break; | 693 | break; |
694 | } | 694 | } |
695 | 695 | ||
696 | if (i == (*first_ucode_section) + 1) | ||
697 | /* set CPU to started */ | ||
698 | iwl_set_bits_prph(trans, | ||
699 | CSR_UCODE_LOAD_STATUS_ADDR, | ||
700 | LMPM_CPU_HDRS_LOADING_COMPLETED | ||
701 | << shift_param); | ||
702 | |||
703 | ret = iwl_pcie_load_section(trans, i, &image->sec[i]); | 696 | ret = iwl_pcie_load_section(trans, i, &image->sec[i]); |
704 | if (ret) | 697 | if (ret) |
705 | return ret; | 698 | return ret; |
699 | |||
700 | /* Notify the ucode of the loaded section number and status */ | ||
701 | val = iwl_read_direct32(trans, FH_UCODE_LOAD_STATUS); | ||
702 | val = val | (sec_num << shift_param); | ||
703 | iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, val); | ||
704 | sec_num = (sec_num << 1) | 0x1; | ||
706 | } | 705 | } |
707 | /* image loading complete */ | ||
708 | iwl_set_bits_prph(trans, | ||
709 | CSR_UCODE_LOAD_STATUS_ADDR, | ||
710 | LMPM_CPU_UCODE_LOADING_COMPLETED << shift_param); | ||
711 | 706 | ||
712 | *first_ucode_section = last_read_idx; | 707 | *first_ucode_section = last_read_idx; |
713 | 708 | ||
@@ -767,39 +762,13 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, | |||
767 | int ret = 0; | 762 | int ret = 0; |
768 | int first_ucode_section; | 763 | int first_ucode_section; |
769 | 764 | ||
770 | IWL_DEBUG_FW(trans, | 765 | IWL_DEBUG_FW(trans, "working with %s CPU\n", |
771 | "working with %s CPU\n", | ||
772 | image->is_dual_cpus ? "Dual" : "Single"); | 766 | image->is_dual_cpus ? "Dual" : "Single"); |
773 | 767 | ||
774 | /* configure the ucode to be ready to get the secured image */ | 768 | /* load to FW the binary non secured sections of CPU1 */ |
775 | if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) { | 769 | ret = iwl_pcie_load_cpu_sections(trans, image, 1, &first_ucode_section); |
776 | /* set secure boot inspector addresses */ | 770 | if (ret) |
777 | iwl_write_prph(trans, | 771 | return ret; |
778 | LMPM_SECURE_INSPECTOR_CODE_ADDR, | ||
779 | LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE); | ||
780 | |||
781 | iwl_write_prph(trans, | ||
782 | LMPM_SECURE_INSPECTOR_DATA_ADDR, | ||
783 | LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE); | ||
784 | |||
785 | /* set CPU1 header address */ | ||
786 | iwl_write_prph(trans, | ||
787 | LMPM_SECURE_UCODE_LOAD_CPU1_HDR_ADDR, | ||
788 | LMPM_SECURE_CPU1_HDR_MEM_SPACE); | ||
789 | |||
790 | /* load to FW the binary Secured sections of CPU1 */ | ||
791 | ret = iwl_pcie_load_cpu_secured_sections(trans, image, 1, | ||
792 | &first_ucode_section); | ||
793 | if (ret) | ||
794 | return ret; | ||
795 | |||
796 | } else { | ||
797 | /* load to FW the binary Non secured sections of CPU1 */ | ||
798 | ret = iwl_pcie_load_cpu_sections(trans, image, 1, | ||
799 | &first_ucode_section); | ||
800 | if (ret) | ||
801 | return ret; | ||
802 | } | ||
803 | 772 | ||
804 | if (image->is_dual_cpus) { | 773 | if (image->is_dual_cpus) { |
805 | /* set CPU2 header address */ | 774 | /* set CPU2 header address */ |
@@ -808,14 +777,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, | |||
808 | LMPM_SECURE_CPU2_HDR_MEM_SPACE); | 777 | LMPM_SECURE_CPU2_HDR_MEM_SPACE); |
809 | 778 | ||
810 | /* load to FW the binary sections of CPU2 */ | 779 | /* load to FW the binary sections of CPU2 */ |
811 | if (iwl_has_secure_boot(trans->hw_rev, | 780 | ret = iwl_pcie_load_cpu_sections(trans, image, 2, |
812 | trans->cfg->device_family)) | 781 | &first_ucode_section); |
813 | ret = iwl_pcie_load_cpu_secured_sections( | ||
814 | trans, image, 2, | ||
815 | &first_ucode_section); | ||
816 | else | ||
817 | ret = iwl_pcie_load_cpu_sections(trans, image, 2, | ||
818 | &first_ucode_section); | ||
819 | if (ret) | 782 | if (ret) |
820 | return ret; | 783 | return ret; |
821 | } | 784 | } |
@@ -840,18 +803,50 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, | |||
840 | else | 803 | else |
841 | iwl_write32(trans, CSR_RESET, 0); | 804 | iwl_write32(trans, CSR_RESET, 0); |
842 | 805 | ||
843 | if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) { | 806 | return 0; |
844 | /* wait for image verification to complete */ | 807 | } |
845 | ret = iwl_poll_prph_bit(trans, | ||
846 | LMPM_SECURE_BOOT_CPU1_STATUS_ADDR, | ||
847 | LMPM_SECURE_BOOT_STATUS_SUCCESS, | ||
848 | LMPM_SECURE_BOOT_STATUS_SUCCESS, | ||
849 | LMPM_SECURE_TIME_OUT); | ||
850 | 808 | ||
851 | if (ret < 0) { | 809 | static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans, |
852 | IWL_ERR(trans, "Time out on secure boot process\n"); | 810 | const struct fw_img *image) |
853 | return ret; | 811 | { |
854 | } | 812 | int ret = 0; |
813 | int first_ucode_section; | ||
814 | u32 reg; | ||
815 | |||
816 | IWL_DEBUG_FW(trans, "working with %s CPU\n", | ||
817 | image->is_dual_cpus ? "Dual" : "Single"); | ||
818 | |||
819 | /* configure the ucode to be ready to get the secured image */ | ||
820 | /* release CPU reset */ | ||
821 | iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); | ||
822 | |||
823 | /* load to FW the binary Secured sections of CPU1 */ | ||
824 | ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 1, | ||
825 | &first_ucode_section); | ||
826 | if (ret) | ||
827 | return ret; | ||
828 | |||
829 | /* load to FW the binary sections of CPU2 */ | ||
830 | ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 2, | ||
831 | &first_ucode_section); | ||
832 | if (ret) | ||
833 | return ret; | ||
834 | |||
835 | /* Notify FW loading is done */ | ||
836 | iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF); | ||
837 | |||
838 | /* wait for image verification to complete */ | ||
839 | ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0, | ||
840 | LMPM_SECURE_BOOT_STATUS_SUCCESS, | ||
841 | LMPM_SECURE_BOOT_STATUS_SUCCESS, | ||
842 | LMPM_SECURE_TIME_OUT); | ||
843 | if (ret < 0) { | ||
844 | reg = iwl_read_prph(trans, | ||
845 | LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0); | ||
846 | |||
847 | IWL_ERR(trans, "Timeout on secure boot process, reg = %x\n", | ||
848 | reg); | ||
849 | return ret; | ||
855 | } | 850 | } |
856 | 851 | ||
857 | return 0; | 852 | return 0; |
@@ -903,7 +898,11 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | |||
903 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 898 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
904 | 899 | ||
905 | /* Load the given image to the HW */ | 900 | /* Load the given image to the HW */ |
906 | return iwl_pcie_load_given_ucode(trans, fw); | 901 | if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) && |
902 | (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP)) | ||
903 | return iwl_pcie_load_given_ucode_8000b(trans, fw); | ||
904 | else | ||
905 | return iwl_pcie_load_given_ucode(trans, fw); | ||
907 | } | 906 | } |
908 | 907 | ||
909 | static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) | 908 | static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) |