iwlwifi: allow combining different phy images with mac images
authorHaim Dreyfuss <haim.dreyfuss@intel.com>
Sun, 3 Apr 2016 16:55:59 +0000 (19:55 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Tue, 10 May 2016 19:14:49 +0000 (22:14 +0300)
Currently there is one to one function between device id to it's ucode.
The new generation devices allows to combine different phy and mac images.
Now we have two different ucode images with the same device id.
Read RF ID to identify phy image and overwrite it if needed.

Signed-off-by: Haim Dreyfuss <haim.dreyfuss@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/iwl-9000.c
drivers/net/wireless/intel/iwlwifi/iwl-config.h
drivers/net/wireless/intel/iwlwifi/iwl-csr.h
drivers/net/wireless/intel/iwlwifi/iwl-trans.h
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c

index 86a55996ea75b7eb6d6524731332a2dd1f271b00..a0eeb536ad72296bfe6529414b240580602e5481 100644 (file)
 #define IWL9000_SMEM_OFFSET            0x400000
 #define IWL9000_SMEM_LEN               0x68000
 
-#define  IWL9000_FW_PRE "iwlwifi-9000-"
+#define  IWL9000_FW_PRE "iwlwifi-9000-pu-a0-lc-a0-"
+#define  IWL9260_FW_PRE "iwlwifi-9260-th-a0-jf-a0-"
+#define  IWL9260LC_FW_PRE "iwlwifi-9260-th-a0-lc-a0-"
 #define IWL9000_MODULE_FIRMWARE(api) \
        IWL9000_FW_PRE "-" __stringify(api) ".ucode"
+#define IWL9260_MODULE_FIRMWARE(api) \
+       IWL9260_FW_PRE "-" __stringify(api) ".ucode"
+#define IWL9260LC_MODULE_FIRMWARE(api) \
+       IWL9260LC_FW_PRE "-" __stringify(api) ".ucode"
 
 #define NVM_HW_SECTION_NUM_FAMILY_9000         10
 
@@ -138,11 +144,26 @@ static const struct iwl_tt_params iwl9000_tt_params = {
        .apmg_not_supported = true,                                     \
        .mq_rx_supported = true,                                        \
        .vht_mu_mimo_supported = true,                                  \
-       .mac_addr_from_csr = true
+       .mac_addr_from_csr = true,                                      \
+       .rf_id = true
 
 const struct iwl_cfg iwl9260_2ac_cfg = {
                .name = "Intel(R) Dual Band Wireless AC 9260",
-               .fw_name_pre = IWL9000_FW_PRE,
+               .fw_name_pre = IWL9260_FW_PRE,
+               IWL_DEVICE_9000,
+               .ht_params = &iwl9000_ht_params,
+               .nvm_ver = IWL9000_NVM_VERSION,
+               .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+               .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+};
+
+/*
+ * TODO the struct below is for internal testing only this should be
+ * removed by EO 2016~
+ */
+const struct iwl_cfg iwl9260lc_2ac_cfg = {
+               .name = "Intel(R) Dual Band Wireless AC 9260",
+               .fw_name_pre = IWL9260LC_FW_PRE,
                IWL_DEVICE_9000,
                .ht_params = &iwl9000_ht_params,
                .nvm_ver = IWL9000_NVM_VERSION,
@@ -161,3 +182,5 @@ const struct iwl_cfg iwl5165_2ac_cfg = {
 };
 
 MODULE_FIRMWARE(IWL9000_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL9260_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL9260LC_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
index 2e71e886627c8c7ea0416af71b5644ab087ef4a4..6eef5dc50293600e2e3e77d5fa1a7747b796dc02 100644 (file)
@@ -314,6 +314,7 @@ struct iwl_pwr_tx_backoff {
  * @smem_len: the length of SMEM
  * @mq_rx_supported: multi-queue rx support
  * @vht_mu_mimo_supported: VHT MU-MIMO support
+ * @rf_id: need to read rf_id to determine the firmware image
  *
  * We enable the driver to be backward compatible wrt. hardware features.
  * API differences in uCode shouldn't be handled here but through TLVs
@@ -367,6 +368,7 @@ struct iwl_cfg {
        bool apmg_not_supported;
        bool mq_rx_supported;
        bool vht_mu_mimo_supported;
+       bool rf_id;
 };
 
 /*
@@ -440,6 +442,7 @@ extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
 extern const struct iwl_cfg iwl8265_2ac_sdio_cfg;
 extern const struct iwl_cfg iwl4165_2ac_sdio_cfg;
 extern const struct iwl_cfg iwl9260_2ac_cfg;
+extern const struct iwl_cfg iwl9260lc_2ac_cfg;
 extern const struct iwl_cfg iwl5165_2ac_cfg;
 #endif /* CONFIG_IWLMVM */
 
index b978f6cae55cd95a2904eaf5cd98c20eac2b8f05..b52913448c4acab76bc5e70c37acade0add76094 100644 (file)
  */
 #define CSR_HW_REV              (CSR_BASE+0x028)
 
+/*
+ * RF ID revision info
+ * Bit fields:
+ * 31:24: Reserved (set to 0x0)
+ * 23:12: Type
+ * 11:8:  Step (A - 0x0, B - 0x1, etc)
+ * 7:4:   Dash
+ * 3:0:   Flavor
+ */
+#define CSR_HW_RF_ID           (CSR_BASE+0x09c)
+
 /*
  * EEPROM and OTP (one-time-programmable) memory reads
  *
@@ -333,6 +344,10 @@ enum {
 #define CSR_HW_REV_TYPE_7265D          (0x0000210)
 #define CSR_HW_REV_TYPE_NONE           (0x00001F0)
 
+/* RF_ID value */
+#define CSR_HW_RF_ID_TYPE_JF           (0x00105000)
+#define CSR_HW_RF_ID_TYPE_LC           (0x00101000)
+
 /* EEPROM REG */
 #define CSR_EEPROM_REG_READ_VALID_MSK  (0x00000001)
 #define CSR_EEPROM_REG_BIT_CMD         (0x00000002)
index fa4ab4b9436fa3b6fb5d49103a06418f5a95c27f..8193d36ae2dd7a68024bb66f83d19a6321d26403 100644 (file)
@@ -753,6 +753,7 @@ enum iwl_plat_pm_mode {
  * @dev - pointer to struct device * that represents the device
  * @max_skb_frags: maximum number of fragments an SKB can have when transmitted.
  *     0 indicates that frag SKBs (NETIF_F_SG) aren't supported.
+ * @hw_rf_id a u32 with the device RF ID
  * @hw_id: a u32 with the ID of the device / sub-device.
  *     Set during transport allocation.
  * @hw_id_str: a string with info about HW ID. Set during transport allocation.
@@ -797,6 +798,7 @@ struct iwl_trans {
        struct device *dev;
        u32 max_skb_frags;
        u32 hw_rev;
+       u32 hw_rf_id;
        u32 hw_id;
        char hw_id_str[52];
 
index 8f139d0550d978b96f95c959c5a8ff011d46e9d8..a588b05e38ebaa2902e5f0fa7822604f92b4013a 100644 (file)
@@ -596,6 +596,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
        const struct iwl_cfg *cfg_7265d __maybe_unused = NULL;
+       const struct iwl_cfg *cfg_9260lc __maybe_unused = NULL;
        struct iwl_trans *iwl_trans;
        struct iwl_trans_pcie *trans_pcie;
        int ret;
@@ -623,6 +624,15 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                cfg = cfg_7265d;
                iwl_trans->cfg = cfg_7265d;
        }
+
+       if (iwl_trans->cfg->rf_id) {
+               if (cfg == &iwl9260_2ac_cfg)
+                       cfg_9260lc = &iwl9260lc_2ac_cfg;
+               if (cfg_9260lc && iwl_trans->hw_rf_id == CSR_HW_RF_ID_TYPE_LC) {
+                       cfg = cfg_9260lc;
+                       iwl_trans->cfg = cfg_9260lc;
+               }
+       }
 #endif
 
        pci_set_drvdata(pdev, iwl_trans);
index 37e134d10fd55da77cfb13c010db4b2d8e7aaedf..eb9bdf0ba02ae706c17e398562207423ff0e0e2d 100644 (file)
@@ -2907,6 +2907,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
                }
        }
 
+       trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID);
+
        iwl_pcie_set_interrupt_capa(pdev, trans);
        trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
        snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),