OSDN Git Service

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 86a5599..a0eeb53 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 2e71e88..6eef5dc 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 b978f6c..b529134 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
  *
  * NOTE:  Device must be awake, initialized via apm_ops.init(),
@@ -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 fa4ab4b..8193d36 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 8f139d0..a588b05 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 37e134d..eb9bdf0 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),