Skip to content

Commit

Permalink
iwlwifi: avoid some operations if no uCode loaded
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David Spinadel authored and John W. Linville committed Mar 12, 2012
1 parent 69a10b2 commit 8f7ffbe
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 20 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-agn-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan)

memcpy(&rxon, &ctx->active, sizeof(rxon));

priv->ucode_loaded = false;
iwl_trans_stop_device(trans(priv));

priv->wowlan = true;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,7 @@ void iwl_down(struct iwl_priv *priv)
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 */
Expand Down Expand Up @@ -1406,6 +1407,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
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);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
#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);

Expand Down
15 changes: 13 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,21 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
/* 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;

Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ struct iwl_priv {
/* 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 */
Expand Down
40 changes: 22 additions & 18 deletions drivers/net/wireless/iwlwifi/iwl-testmode.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)

case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
iwl_testmode_cfg_init_calib(priv);
priv->ucode_loaded = false;
iwl_trans_stop_device(trans);
break;

Expand All @@ -512,6 +513,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)

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) {
Expand Down Expand Up @@ -591,25 +593,27 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
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);
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-ucode.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
priv->shrd->ucode_type = ucode_type;
fw = iwl_get_ucode_image(priv, ucode_type);

priv->ucode_loaded = false;

if (!fw)
return -EINVAL;

Expand Down Expand Up @@ -519,6 +521,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
return ret;
}

priv->ucode_loaded = true;

return 0;
}

Expand Down Expand Up @@ -563,5 +567,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv)
out:
/* Whatever happened, stop the device */
iwl_trans_stop_device(trans(priv));
priv->ucode_loaded = false;

return ret;
}

0 comments on commit 8f7ffbe

Please sign in to comment.