iwlwifi: distinguish different RF modules in A000 devices
authorTzipi Peres <tzipi.peres@intel.com>
Tue, 25 Jul 2017 10:04:46 +0000 (13:04 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Fri, 18 Aug 2017 14:13:35 +0000 (17:13 +0300)
Newer versions of A000 devices come with two diffenent RF modules.
The PCI_ID, the subsystem ID and the RF ID are identical in these two cases,
so we need to differentiate them by using the CSR_HW_RF_ID register-
in order to load the appropriate firmware.

Signed-off-by: Tzipi Peres <tzipi.peres@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/cfg/a000.c
drivers/net/wireless/intel/iwlwifi/iwl-config.h
drivers/net/wireless/intel/iwlwifi/iwl-csr.h
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c

index 40d67a5a26354704ab67c12bf6ff174a84ed0879..dcd35b5c9d240de02970fba5109d35f014b6cbe5 100644 (file)
 #define IWL_A000_HR_FW_PRE     "iwlwifi-Qu-a0-hr-a0-"
 #define IWL_A000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-"
 #define IWL_A000_HR_F0_FW_PRE  "iwlwifi-QuQnj-f0-hr-a0-"
+#define IWL_A000_JF_B0_FW_PRE  "iwlwifi-QuQnj-a0-jf-b0-"
+#define IWL_A000_HR_A0_FW_PRE  "iwlwifi-QuQnj-a0-hr-a0-"
 
 #define IWL_A000_HR_MODULE_FIRMWARE(api) \
        IWL_A000_HR_FW_PRE "-" __stringify(api) ".ucode"
 #define IWL_A000_JF_MODULE_FIRMWARE(api) \
        IWL_A000_JF_FW_PRE "-" __stringify(api) ".ucode"
-#define IWL_A000_HR_QNJ_MODULE_FIRMWARE(api) \
+#define IWL_A000_HR_F0_QNJ_MODULE_FIRMWARE(api) \
        IWL_A000_HR_F0_FW_PRE "-" __stringify(api) ".ucode"
+#define IWL_A000_JF_B0_QNJ_MODULE_FIRMWARE(api) \
+       IWL_A000_JF_B0_FW_PRE "-" __stringify(api) ".ucode"
+#define IWL_A000_HR_A0_QNJ_MODULE_FIRMWARE(api) \
+       IWL_A000_HR_A0_FW_PRE "-" __stringify(api) ".ucode"
 
 #define NVM_HW_SECTION_NUM_FAMILY_A000         10
 
@@ -171,7 +177,7 @@ const struct iwl_cfg iwla000_2ax_cfg_hr = {
                .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
-const struct iwl_cfg iwla000_2ax_cfg_qnj_hr = {
+const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0 = {
                .name = "Intel(R) Dual Band Wireless AX a000",
                .fw_name_pre = IWL_A000_HR_F0_FW_PRE,
                IWL_DEVICE_A000,
@@ -181,6 +187,28 @@ const struct iwl_cfg iwla000_2ax_cfg_qnj_hr = {
                .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
+const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0 = {
+               .name = "Intel(R) Dual Band Wireless AX a000",
+               .fw_name_pre = IWL_A000_JF_B0_FW_PRE,
+               IWL_DEVICE_A000,
+               .ht_params = &iwl_a000_ht_params,
+               .nvm_ver = IWL_A000_NVM_VERSION,
+               .nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
+               .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+};
+
+const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0 = {
+               .name = "Intel(R) Dual Band Wireless AX a000",
+               .fw_name_pre = IWL_A000_HR_A0_FW_PRE,
+               IWL_DEVICE_A000,
+               .ht_params = &iwl_a000_ht_params,
+               .nvm_ver = IWL_A000_NVM_VERSION,
+               .nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
+               .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+};
+
 MODULE_FIRMWARE(IWL_A000_HR_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_A000_JF_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL_A000_HR_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL_A000_HR_F0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL_A000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL_A000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
index 573dbeed3fbf90236adf0b10b3a74cacb901c929..b82a3d0f64b0e86a33fe86970b1eacae98c61a93 100644 (file)
@@ -463,7 +463,9 @@ extern const struct iwl_cfg iwla000_2ac_cfg_hr;
 extern const struct iwl_cfg iwla000_2ac_cfg_hr_cdb;
 extern const struct iwl_cfg iwla000_2ac_cfg_jf;
 extern const struct iwl_cfg iwla000_2ax_cfg_hr;
-extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr;
+extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0;
+extern const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0;
+extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0;
 #endif /* CONFIG_IWLMVM */
 
 #endif /* __IWL_CONFIG_H__ */
index 7d468ad7cb6a8eca563e8bc185dff3c06c794b88..b03e0f975b5a4e5d34c2568792572ecf63f864bb 100644 (file)
@@ -354,11 +354,16 @@ enum {
 #define CSR_HW_REV_TYPE_135            (0x0000120)
 #define CSR_HW_REV_TYPE_7265D          (0x0000210)
 #define CSR_HW_REV_TYPE_NONE           (0x00001F0)
+#define CSR_HW_REV_TYPE_QNJ            (0x0000360)
+#define CSR_HW_REV_TYPE_HR_CDB         (0x0000340)
 
 /* RF_ID value */
 #define CSR_HW_RF_ID_TYPE_JF           (0x00105100)
 #define CSR_HW_RF_ID_TYPE_HR           (0x0010A000)
-#define CSR_HW_RF_ID_TYPE_HRCDB                (0x00109000)
+#define CSR_HW_RF_ID_TYPE_HRCDB                (0x00109F00)
+
+/* HW_RF CHIP ID  */
+#define CSR_HW_RF_ID_TYPE_CHIP_ID(_val) (((_val) >> 12) & 0xFFF)
 
 /* EEPROM REG */
 #define CSR_EEPROM_REG_READ_VALID_MSK  (0x00000001)
index 87712aeac31fd7d6aff0124154f3dea34fc2c725..27d1eec1c899ae8310bffb61a7ab9d4588928484 100644 (file)
@@ -690,12 +690,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                iwl_trans->cfg = cfg_7265d;
        }
 
-       if (iwl_trans->cfg->rf_id && cfg == &iwla000_2ac_cfg_hr_cdb) {
-               if (iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_JF)
-                       cfg = &iwla000_2ac_cfg_jf;
-               else if (iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_HR)
-                       cfg = &iwla000_2ac_cfg_hr;
-
+       if (iwl_trans->cfg->rf_id && cfg == &iwla000_2ac_cfg_hr_cdb &&
+           iwl_trans->hw_rev != CSR_HW_REV_TYPE_HR_CDB) {
+               u32 rf_id_chp = CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id);
+               u32 jf_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF);
+               u32 hr_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR);
+
+               if (rf_id_chp == jf_chp_id) {
+                       if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
+                               cfg = &iwla000_2ax_cfg_qnj_jf_b0;
+                       else
+                               cfg = &iwla000_2ac_cfg_jf;
+               } else if (rf_id_chp == hr_chp_id) {
+                       if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
+                               cfg = &iwla000_2ax_cfg_qnj_hr_a0;
+                       else
+                               cfg = &iwla000_2ac_cfg_hr;
+               }
                iwl_trans->cfg = cfg;
        }
 #endif
index 3ecafa2ad922ac8c920bdc744dfbf6cd90af45dc..58873cc27396f038812b33658a916cff1e408000 100644 (file)
@@ -3145,7 +3145,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
 
                hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS);
                if (hw_status & UMAG_GEN_HW_IS_FPGA)
-                       trans->cfg = &iwla000_2ax_cfg_qnj_hr;
+                       trans->cfg = &iwla000_2ax_cfg_qnj_hr_f0;
                else
                        trans->cfg = &iwla000_2ac_cfg_hr;
        }