iwlwifi: avoid some operations if no uCode loaded
Printing the SRAM and similar testmode operations could
be triggered when no uCode is loaded; prevent those
invalid operations by tracking whether uCode is loaded.
Signed-off-by: David Spinadel <david.spinadel@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 915183a..3e1698d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1189,6 +1189,7 @@
memcpy(&rxon, &ctx->active, sizeof(rxon));
+ priv->ucode_loaded = false;
iwl_trans_stop_device(trans(priv));
priv->wowlan = true;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 66d7446..f1226dbf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -816,6 +816,7 @@
if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw);
+ priv->ucode_loaded = false;
iwl_trans_stop_device(trans(priv));
/* Clear out all status bits but a few that are stable across reset */
@@ -1406,6 +1407,7 @@
iwl_tt_exit(priv);
/*This will stop the queues, move the device to low power state */
+ priv->ucode_loaded = false;
iwl_trans_stop_device(trans(priv));
iwl_eeprom_free(priv->shrd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e3eda50..46490d3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -838,6 +838,9 @@
iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
#endif
+ /* uCode is no longer loaded. */
+ priv->ucode_loaded = false;
+
/* Set the FW error flag -- cleared on iwl_down */
set_bit(STATUS_FW_ERROR, &priv->shrd->status);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 9b71c87..89cb9a7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -235,10 +235,21 @@
/* default is to dump the entire data segment */
if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
priv->dbgfs_sram_offset = 0x800000;
- if (priv->shrd->ucode_type == IWL_UCODE_INIT)
+ if (!priv->ucode_loaded) {
+ IWL_ERR(priv, "No uCode has been loadded.\n");
+ return -EINVAL;
+ }
+ if (priv->shrd->ucode_type == IWL_UCODE_INIT) {
priv->dbgfs_sram_len = priv->fw->ucode_init.data.len;
- else
+ } else if (priv->shrd->ucode_type == IWL_UCODE_REGULAR) {
priv->dbgfs_sram_len = priv->fw->ucode_rt.data.len;
+ } else if (priv->shrd->ucode_type == IWL_UCODE_WOWLAN) {
+ priv->dbgfs_sram_len = priv->fw->ucode_wowlan.data.len;
+ } else {
+ IWL_ERR(priv, "Unsupported type of uCode loaded?"
+ " that shouldn't happen.\n");
+ return -EINVAL;
+ }
}
len = priv->dbgfs_sram_len;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index aa4b3b1..01dbe11 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -769,6 +769,7 @@
/* firmware reload counter and timestamp */
unsigned long reload_jiffies;
int reload_count;
+ bool ucode_loaded;
/* we allocate array of iwl_channel_info for NIC's valid channels.
* Access via channel # using indirect index array */
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c
index b06c676..c6c084f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c
@@ -494,6 +494,7 @@
case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
iwl_testmode_cfg_init_calib(priv);
+ priv->ucode_loaded = false;
iwl_trans_stop_device(trans);
break;
@@ -512,6 +513,7 @@
case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
iwl_scan_cancel_timeout(priv, 200);
+ priv->ucode_loaded = false;
iwl_trans_stop_device(trans);
status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
if (status) {
@@ -591,25 +593,27 @@
IWL_ERR(priv, "Memory allocation fail\n");
return -ENOMEM;
}
- switch (priv->shrd->ucode_type) {
- case IWL_UCODE_REGULAR:
- inst_size = priv->fw->ucode_rt.code.len;
- data_size = priv->fw->ucode_rt.data.len;
- break;
- case IWL_UCODE_INIT:
- inst_size = priv->fw->ucode_init.code.len;
- data_size = priv->fw->ucode_init.data.len;
- break;
- case IWL_UCODE_WOWLAN:
- inst_size = priv->fw->ucode_wowlan.code.len;
- data_size = priv->fw->ucode_wowlan.data.len;
- break;
- case IWL_UCODE_NONE:
+ if (!priv->ucode_loaded) {
IWL_ERR(priv, "No uCode has not been loaded\n");
- break;
- default:
- IWL_ERR(priv, "Unsupported uCode type\n");
- break;
+ return -EINVAL;
+ } else {
+ switch (priv->shrd->ucode_type) {
+ case IWL_UCODE_REGULAR:
+ inst_size = priv->fw->ucode_rt.code.len;
+ data_size = priv->fw->ucode_rt.data.len;
+ break;
+ case IWL_UCODE_INIT:
+ inst_size = priv->fw->ucode_init.code.len;
+ data_size = priv->fw->ucode_init.data.len;
+ break;
+ case IWL_UCODE_WOWLAN:
+ inst_size = priv->fw->ucode_wowlan.code.len;
+ data_size = priv->fw->ucode_wowlan.data.len;
+ break;
+ default:
+ IWL_ERR(priv, "Unsupported uCode type\n");
+ break;
+ }
}
NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type);
NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c
index d97cf44..ae935c0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c
@@ -465,6 +465,8 @@
priv->shrd->ucode_type = ucode_type;
fw = iwl_get_ucode_image(priv, ucode_type);
+ priv->ucode_loaded = false;
+
if (!fw)
return -EINVAL;
@@ -519,6 +521,8 @@
return ret;
}
+ priv->ucode_loaded = true;
+
return 0;
}
@@ -563,5 +567,7 @@
out:
/* Whatever happened, stop the device */
iwl_trans_stop_device(trans(priv));
+ priv->ucode_loaded = false;
+
return ret;
}