summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/bz.c16
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/dr.c11
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/sc.c16
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-config.h39
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-drv.c41
5 files changed, 85 insertions, 38 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c
index 0acf52064132..3e6206e739f6 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c
@@ -9,8 +9,8 @@
#include "iwl-prph.h"
#include "fw/api/txq.h"
-/* Highest firmware API version supported */
-#define IWL_BZ_UCODE_API_MAX 102
+/* Highest firmware core release supported */
+#define IWL_BZ_UCODE_CORE_MAX 99
/* Lowest firmware API version supported */
#define IWL_BZ_UCODE_API_MIN 100
@@ -75,7 +75,7 @@ static const struct iwl_family_base_params iwl_bz_base = {
},
},
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
- .ucode_api_max = IWL_BZ_UCODE_API_MAX,
+ .ucode_api_max = ENCODE_CORE_AS_API(IWL_BZ_UCODE_CORE_MAX),
.ucode_api_min = IWL_BZ_UCODE_API_MIN,
};
@@ -101,8 +101,8 @@ const struct iwl_mac_cfg iwl_gl_mac_cfg = {
.low_latency_xtal = true,
};
-IWL_FW_AND_PNVM(IWL_BZ_A_FM_B_FW_PRE, IWL_BZ_UCODE_API_MAX);
-IWL_FW_AND_PNVM(IWL_BZ_A_FM_C_FW_PRE, IWL_BZ_UCODE_API_MAX);
-IWL_FW_AND_PNVM(IWL_BZ_A_FM4_B_FW_PRE, IWL_BZ_UCODE_API_MAX);
-IWL_FW_AND_PNVM(IWL_GL_B_FM_B_FW_PRE, IWL_BZ_UCODE_API_MAX);
-IWL_FW_AND_PNVM(IWL_GL_C_FM_C_FW_PRE, IWL_BZ_UCODE_API_MAX);
+IWL_CORE_FW(IWL_BZ_A_FM_B_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
+IWL_CORE_FW(IWL_BZ_A_FM_C_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
+IWL_CORE_FW(IWL_BZ_A_FM4_B_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
+IWL_CORE_FW(IWL_GL_B_FM_B_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
+IWL_CORE_FW(IWL_GL_C_FM_C_FW_PRE, IWL_BZ_UCODE_CORE_MAX);
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c
index 3c8fa8aa78ca..e53a785686c8 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c
@@ -8,8 +8,8 @@
#include "iwl-prph.h"
#include "fw/api/txq.h"
-/* Highest firmware API version supported */
-#define IWL_DR_UCODE_API_MAX 102
+/* Highest firmware core release supported */
+#define IWL_DR_UCODE_CORE_MAX 99
/* Lowest firmware API version supported */
#define IWL_DR_UCODE_API_MIN 100
@@ -20,9 +20,6 @@
#define IWL_DR_A_PE_A_FW_PRE "iwlwifi-dr-a0-pe-a0"
-#define IWL_DR_A_PE_A_FW_MODULE_FIRMWARE(api) \
- IWL_DR_A_PE_A_FW_PRE "-" __stringify(api) ".ucode"
-
static const struct iwl_family_base_params iwl_dr_base = {
.num_of_queues = 512,
.max_tfd_queue_size = 65536,
@@ -73,7 +70,7 @@ static const struct iwl_family_base_params iwl_dr_base = {
},
},
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
- .ucode_api_max = IWL_DR_UCODE_API_MAX,
+ .ucode_api_max = ENCODE_CORE_AS_API(IWL_DR_UCODE_CORE_MAX),
.ucode_api_min = IWL_DR_UCODE_API_MIN,
};
@@ -89,5 +86,5 @@ const struct iwl_mac_cfg iwl_dr_mac_cfg = {
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
};
-MODULE_FIRMWARE(IWL_DR_A_PE_A_FW_MODULE_FIRMWARE(IWL_DR_UCODE_API_MAX));
+IWL_CORE_FW(IWL_DR_A_PE_A_FW_PRE, IWL_DR_UCODE_CORE_MAX);
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
index ee1dc27362c5..e9449b59114a 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
@@ -9,8 +9,8 @@
#include "iwl-prph.h"
#include "fw/api/txq.h"
-/* Highest firmware API version supported */
-#define IWL_SC_UCODE_API_MAX 102
+/* Highest firmware core release supported */
+#define IWL_SC_UCODE_CORE_MAX 99
/* Lowest firmware API version supported */
#define IWL_SC_UCODE_API_MIN 100
@@ -78,7 +78,7 @@ static const struct iwl_family_base_params iwl_sc_base = {
},
},
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
- .ucode_api_max = IWL_SC_UCODE_API_MAX,
+ .ucode_api_max = ENCODE_CORE_AS_API(IWL_SC_UCODE_CORE_MAX),
.ucode_api_min = IWL_SC_UCODE_API_MIN,
};
@@ -94,8 +94,8 @@ const struct iwl_mac_cfg iwl_sc_mac_cfg = {
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
};
-IWL_FW_AND_PNVM(IWL_SC_A_FM_B_FW_PRE, IWL_SC_UCODE_API_MAX);
-IWL_FW_AND_PNVM(IWL_SC_A_FM_C_FW_PRE, IWL_SC_UCODE_API_MAX);
-IWL_FW_AND_PNVM(IWL_SC_A_WH_A_FW_PRE, IWL_SC_UCODE_API_MAX);
-IWL_FW_AND_PNVM(IWL_SC2_A_FM_C_FW_PRE, IWL_SC_UCODE_API_MAX);
-IWL_FW_AND_PNVM(IWL_SC2_A_WH_A_FW_PRE, IWL_SC_UCODE_API_MAX);
+IWL_CORE_FW(IWL_SC_A_FM_B_FW_PRE, IWL_SC_UCODE_CORE_MAX);
+IWL_CORE_FW(IWL_SC_A_FM_C_FW_PRE, IWL_SC_UCODE_CORE_MAX);
+IWL_CORE_FW(IWL_SC_A_WH_A_FW_PRE, IWL_SC_UCODE_CORE_MAX);
+IWL_CORE_FW(IWL_SC2_A_FM_C_FW_PRE, IWL_SC_UCODE_CORE_MAX);
+IWL_CORE_FW(IWL_SC2_A_WH_A_FW_PRE, IWL_SC_UCODE_CORE_MAX);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 30e5f5a5cd89..d27c9ec151f4 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -107,6 +107,9 @@ enum iwl_nvm_type {
MODULE_FIRMWARE(pfx "-" __stringify(api) ".ucode"); \
MODULE_FIRMWARE(pfx ".pnvm")
+#define IWL_CORE_FW(pfx, core) \
+ MODULE_FIRMWARE(pfx "-c" __stringify(core) ".ucode")
+
static inline u8 num_of_ant(u8 mask)
{
return !!((mask) & ANT_A) +
@@ -192,8 +195,8 @@ struct iwl_family_base_params {
u8 max_ll_items;
u8 led_compensation;
- u8 ucode_api_max;
- u8 ucode_api_min;
+ u16 ucode_api_max;
+ u16 ucode_api_min;
u32 mac_addr_from_csr:10;
u8 nvm_hw_section_num;
netdev_features_t features;
@@ -211,6 +214,34 @@ struct iwl_family_base_params {
};
/*
+ * FW is released as "core N release", and we used to have a
+ * gap of 3 between the API version and core number. Now the
+ * reported API version will be 1000 + core and we encode it
+ * in the filename as "c<core>".
+ */
+#define API_IS_CORE_START 1000
+#define API_TO_CORE_OFFS 3
+#define ENCODE_CORE_AS_API(core) (API_IS_CORE_START + (core))
+
+static inline bool iwl_api_is_core_number(int api)
+{
+ return api >= API_IS_CORE_START;
+}
+
+static inline int iwl_api_to_core(int api)
+{
+ if (iwl_api_is_core_number(api))
+ return api - API_IS_CORE_START;
+
+ return api - API_TO_CORE_OFFS;
+}
+
+#define FW_API_FMT "%s%d"
+#define FW_API_ARG(n) \
+ iwl_api_is_core_number(n) ? "c" : "", \
+ iwl_api_is_core_number(n) ? (n) - API_IS_CORE_START : (n)
+
+/*
* @stbc: support Tx STBC and 1*SS Rx STBC
* @ldpc: support Tx/Rx with LDPC
* @use_rts_for_aggregation: use rts/cts protection for HT traffic
@@ -422,8 +453,8 @@ struct iwl_rf_cfg {
u8 valid_tx_ant;
u8 valid_rx_ant;
u8 non_shared_ant;
- u8 ucode_api_max;
- u8 ucode_api_min;
+ u16 ucode_api_max;
+ u16 ucode_api_min;
u16 num_rbds;
};
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 28aad975434b..6045a7915b91 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -341,6 +341,8 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
if (first)
drv->fw_index = ucode_api_max;
+ else if (drv->fw_index == ENCODE_CORE_AS_API(99))
+ drv->fw_index = 101; /* last API-scheme number below core 99 */
else
drv->fw_index--;
@@ -348,13 +350,15 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
IWL_ERR(drv, "no suitable firmware found!\n");
if (ucode_api_min == ucode_api_max) {
- IWL_ERR(drv, "%s-%d is required\n", fw_name_pre,
- ucode_api_max);
+ IWL_ERR(drv, "%s-" FW_API_FMT " is required\n",
+ fw_name_pre, FW_API_ARG(ucode_api_max));
} else {
- IWL_ERR(drv, "minimum version required: %s-%d\n",
- fw_name_pre, ucode_api_min);
- IWL_ERR(drv, "maximum version supported: %s-%d\n",
- fw_name_pre, ucode_api_max);
+ IWL_ERR(drv,
+ "minimum version required: %s-" FW_API_FMT "\n",
+ fw_name_pre, FW_API_ARG(ucode_api_min));
+ IWL_ERR(drv,
+ "maximum version supported: %s-" FW_API_FMT "\n",
+ fw_name_pre, FW_API_ARG(ucode_api_max));
}
IWL_ERR(drv,
@@ -362,8 +366,9 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
return -ENOENT;
}
- snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s-%d.ucode",
- fw_name_pre, drv->fw_index);
+ snprintf(drv->firmware_name, sizeof(drv->firmware_name),
+ "%s-" FW_API_FMT ".ucode",
+ fw_name_pre, FW_API_ARG(drv->fw_index));
IWL_DEBUG_FW_INFO(drv, "attempting to load firmware '%s'\n",
drv->firmware_name);
@@ -1588,6 +1593,7 @@ static void _iwl_op_mode_stop(struct iwl_drv *drv)
*/
static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
{
+ unsigned int min_core, max_core, loaded_core;
struct iwl_drv *drv = context;
struct iwl_fw *fw = &drv->fw;
const struct iwl_ucode_header *ucode;
@@ -1650,11 +1656,24 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
* firmware filename ... but we don't check for that and only rely
* on the API version read from firmware header from here on forward
*/
- if (api_ver < api_min || api_ver > api_max) {
+
+ /*
+ * if -cN.ucode file was loaded, core version == file version,
+ * otherwise core version == file version (API version) - 3
+ */
+ if (iwl_api_is_core_number(drv->fw_index))
+ loaded_core = api_ver;
+ else
+ loaded_core = api_ver - API_TO_CORE_OFFS;
+
+ min_core = iwl_api_to_core(api_min);
+ max_core = iwl_api_to_core(api_max);
+
+ if (loaded_core < min_core || loaded_core > max_core) {
IWL_ERR(drv,
"Driver unable to support your firmware API. "
- "Driver supports v%u, firmware is v%u.\n",
- api_max, api_ver);
+ "Driver supports FW core %u..%u, firmware is %u.\n",
+ min_core, max_core, loaded_core);
goto try_again;
}