Commit 8f7ffbe2 authored by David Spinadel's avatar David Spinadel Committed by John W. Linville

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: default avatarDavid Spinadel <david.spinadel@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 69a10b29
...@@ -1189,6 +1189,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) ...@@ -1189,6 +1189,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan)
memcpy(&rxon, &ctx->active, sizeof(rxon)); memcpy(&rxon, &ctx->active, sizeof(rxon));
priv->ucode_loaded = false;
iwl_trans_stop_device(trans(priv)); iwl_trans_stop_device(trans(priv));
priv->wowlan = true; priv->wowlan = true;
......
...@@ -816,6 +816,7 @@ void iwl_down(struct iwl_priv *priv) ...@@ -816,6 +816,7 @@ void iwl_down(struct iwl_priv *priv)
if (priv->mac80211_registered) if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw); ieee80211_stop_queues(priv->hw);
priv->ucode_loaded = false;
iwl_trans_stop_device(trans(priv)); iwl_trans_stop_device(trans(priv));
/* Clear out all status bits but a few that are stable across reset */ /* Clear out all status bits but a few that are stable across reset */
...@@ -1406,6 +1407,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) ...@@ -1406,6 +1407,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
iwl_tt_exit(priv); iwl_tt_exit(priv);
/*This will stop the queues, move the device to low power state */ /*This will stop the queues, move the device to low power state */
priv->ucode_loaded = false;
iwl_trans_stop_device(trans(priv)); iwl_trans_stop_device(trans(priv));
iwl_eeprom_free(priv->shrd); iwl_eeprom_free(priv->shrd);
......
...@@ -838,6 +838,9 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) ...@@ -838,6 +838,9 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
#endif #endif
/* uCode is no longer loaded. */
priv->ucode_loaded = false;
/* Set the FW error flag -- cleared on iwl_down */ /* Set the FW error flag -- cleared on iwl_down */
set_bit(STATUS_FW_ERROR, &priv->shrd->status); set_bit(STATUS_FW_ERROR, &priv->shrd->status);
......
...@@ -235,10 +235,21 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, ...@@ -235,10 +235,21 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
/* default is to dump the entire data segment */ /* default is to dump the entire data segment */
if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
priv->dbgfs_sram_offset = 0x800000; 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; 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; 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; len = priv->dbgfs_sram_len;
......
...@@ -769,6 +769,7 @@ struct iwl_priv { ...@@ -769,6 +769,7 @@ struct iwl_priv {
/* firmware reload counter and timestamp */ /* firmware reload counter and timestamp */
unsigned long reload_jiffies; unsigned long reload_jiffies;
int reload_count; int reload_count;
bool ucode_loaded;
/* we allocate array of iwl_channel_info for NIC's valid channels. /* we allocate array of iwl_channel_info for NIC's valid channels.
* Access via channel # using indirect index array */ * Access via channel # using indirect index array */
......
...@@ -494,6 +494,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) ...@@ -494,6 +494,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
iwl_testmode_cfg_init_calib(priv); iwl_testmode_cfg_init_calib(priv);
priv->ucode_loaded = false;
iwl_trans_stop_device(trans); iwl_trans_stop_device(trans);
break; break;
...@@ -512,6 +513,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) ...@@ -512,6 +513,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
iwl_scan_cancel_timeout(priv, 200); iwl_scan_cancel_timeout(priv, 200);
priv->ucode_loaded = false;
iwl_trans_stop_device(trans); iwl_trans_stop_device(trans);
status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
if (status) { if (status) {
...@@ -591,25 +593,27 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) ...@@ -591,25 +593,27 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
IWL_ERR(priv, "Memory allocation fail\n"); IWL_ERR(priv, "Memory allocation fail\n");
return -ENOMEM; return -ENOMEM;
} }
switch (priv->shrd->ucode_type) { if (!priv->ucode_loaded) {
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:
IWL_ERR(priv, "No uCode has not been loaded\n"); IWL_ERR(priv, "No uCode has not been loaded\n");
break; return -EINVAL;
default: } else {
IWL_ERR(priv, "Unsupported uCode type\n"); switch (priv->shrd->ucode_type) {
break; 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_TYPE, priv->shrd->ucode_type);
NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size); NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
......
...@@ -465,6 +465,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, ...@@ -465,6 +465,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
priv->shrd->ucode_type = ucode_type; priv->shrd->ucode_type = ucode_type;
fw = iwl_get_ucode_image(priv, ucode_type); fw = iwl_get_ucode_image(priv, ucode_type);
priv->ucode_loaded = false;
if (!fw) if (!fw)
return -EINVAL; return -EINVAL;
...@@ -519,6 +521,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, ...@@ -519,6 +521,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
return ret; return ret;
} }
priv->ucode_loaded = true;
return 0; return 0;
} }
...@@ -563,5 +567,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv) ...@@ -563,5 +567,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv)
out: out:
/* Whatever happened, stop the device */ /* Whatever happened, stop the device */
iwl_trans_stop_device(trans(priv)); iwl_trans_stop_device(trans(priv));
priv->ucode_loaded = false;
return ret; return ret;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment