Commit ce71c2f7 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach

iwlwifi: mvm: enable watchdog on Tx queues for mvm

This watchdog allows to monitor the transmit queues. When a
queue doesn't progress for a too long time, a timer fires
and then, debug data can be collected.
This watchdog has never been enabled on dvm controlled
devices, so don't enable it there.
In order to have it running on mvm controlled devices, we
need to fix a small issue in the transport layer: mvm
controlled devices use the shadow registers optimization.
In this case, the watchdog wasn't running at all, even if
enabled by the module parameter. Fix that on the way.
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent b9dccdb3
...@@ -1228,10 +1228,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, ...@@ -1228,10 +1228,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
trans_cfg.no_reclaim_cmds = no_reclaim_cmds; trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
if (!iwlwifi_mod_params.wd_disable)
trans_cfg.queue_watchdog_timeout =
priv->cfg->base_params->wd_timeout;
else
trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED; trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
trans_cfg.command_names = iwl_dvm_cmd_strings; trans_cfg.command_names = iwl_dvm_cmd_strings;
trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM; trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM;
......
...@@ -1367,7 +1367,6 @@ struct iwl_mod_params iwlwifi_mod_params = { ...@@ -1367,7 +1367,6 @@ struct iwl_mod_params iwlwifi_mod_params = {
.restart_fw = true, .restart_fw = true,
.bt_coex_active = true, .bt_coex_active = true,
.power_level = IWL_POWER_INDEX_1, .power_level = IWL_POWER_INDEX_1,
.wd_disable = true,
.d0i3_disable = true, .d0i3_disable = true,
#ifndef CONFIG_IWLWIFI_UAPSD #ifndef CONFIG_IWLWIFI_UAPSD
.uapsd_disable = true, .uapsd_disable = true,
...@@ -1478,10 +1477,6 @@ module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, ...@@ -1478,10 +1477,6 @@ module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,
MODULE_PARM_DESC(antenna_coupling, MODULE_PARM_DESC(antenna_coupling,
"specify antenna coupling in dB (default: 0 dB)"); "specify antenna coupling in dB (default: 0 dB)");
module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
MODULE_PARM_DESC(wd_disable,
"Disable stuck queue watchdog timer 0=system default, 1=disable (default: 1)");
module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO); module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
MODULE_PARM_DESC(nvm_file, "NVM file name"); MODULE_PARM_DESC(nvm_file, "NVM file name");
......
...@@ -96,7 +96,6 @@ enum iwl_disable_11n { ...@@ -96,7 +96,6 @@ enum iwl_disable_11n {
* use IWL_[DIS,EN]ABLE_HT_* constants * use IWL_[DIS,EN]ABLE_HT_* constants
* @amsdu_size_8K: enable 8K amsdu size, default = 0 * @amsdu_size_8K: enable 8K amsdu size, default = 0
* @restart_fw: restart firmware, default = 1 * @restart_fw: restart firmware, default = 1
* @wd_disable: disable stuck queue check, default = 1
* @bt_coex_active: enable bt coex, default = true * @bt_coex_active: enable bt coex, default = true
* @led_mode: system default, default = 0 * @led_mode: system default, default = 0
* @power_save: enable power save, default = false * @power_save: enable power save, default = false
...@@ -111,7 +110,6 @@ struct iwl_mod_params { ...@@ -111,7 +110,6 @@ struct iwl_mod_params {
unsigned int disable_11n; unsigned int disable_11n;
int amsdu_size_8K; int amsdu_size_8K;
bool restart_fw; bool restart_fw;
int wd_disable;
bool bt_coex_active; bool bt_coex_active;
int led_mode; int led_mode;
bool power_save; bool power_save;
......
...@@ -119,11 +119,13 @@ extern const struct ieee80211_ops iwl_mvm_hw_ops; ...@@ -119,11 +119,13 @@ extern const struct ieee80211_ops iwl_mvm_hw_ops;
* We will register to mac80211 to have testmode working. The NIC must not * We will register to mac80211 to have testmode working. The NIC must not
* be up'ed after the INIT fw asserted. This is useful to be able to use * be up'ed after the INIT fw asserted. This is useful to be able to use
* proprietary tools over testmode to debug the INIT fw. * proprietary tools over testmode to debug the INIT fw.
* @tfd_q_hang_detect: enabled the detection of hung transmit queues
* @power_scheme: CAM(Continuous Active Mode)-1, BPS(Balanced Power * @power_scheme: CAM(Continuous Active Mode)-1, BPS(Balanced Power
* Save)-2(default), LP(Low Power)-3 * Save)-2(default), LP(Low Power)-3
*/ */
struct iwl_mvm_mod_params { struct iwl_mvm_mod_params {
bool init_dbg; bool init_dbg;
bool tfd_q_hang_detect;
int power_scheme; int power_scheme;
}; };
extern struct iwl_mvm_mod_params iwlmvm_mod_params; extern struct iwl_mvm_mod_params iwlmvm_mod_params;
......
...@@ -93,6 +93,7 @@ static const struct iwl_op_mode_ops iwl_mvm_ops; ...@@ -93,6 +93,7 @@ static const struct iwl_op_mode_ops iwl_mvm_ops;
struct iwl_mvm_mod_params iwlmvm_mod_params = { struct iwl_mvm_mod_params iwlmvm_mod_params = {
.power_scheme = IWL_POWER_SCHEME_BPS, .power_scheme = IWL_POWER_SCHEME_BPS,
.tfd_q_hang_detect = true
/* rest of fields are 0 by default */ /* rest of fields are 0 by default */
}; };
...@@ -102,6 +103,10 @@ MODULE_PARM_DESC(init_dbg, ...@@ -102,6 +103,10 @@ MODULE_PARM_DESC(init_dbg,
module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO); module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO);
MODULE_PARM_DESC(power_scheme, MODULE_PARM_DESC(power_scheme,
"power management scheme: 1-active, 2-balanced, 3-low power, default: 2"); "power management scheme: 1-active, 2-balanced, 3-low power, default: 2");
module_param_named(tfd_q_hang_detect, iwlmvm_mod_params.tfd_q_hang_detect,
bool, S_IRUGO);
MODULE_PARM_DESC(tfd_q_hang_detect,
"TFD queues hang detection (default: true");
/* /*
* module init and exit functions * module init and exit functions
...@@ -473,10 +478,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -473,10 +478,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE) if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE)
trans_cfg.bc_table_dword = true; trans_cfg.bc_table_dword = true;
if (!iwlwifi_mod_params.wd_disable) if (iwlmvm_mod_params.tfd_q_hang_detect)
trans_cfg.queue_watchdog_timeout = cfg->base_params->wd_timeout; trans_cfg.queue_watchdog_timeout = cfg->base_params->wd_timeout;
else
trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
trans_cfg.command_names = iwl_mvm_cmd_strings; trans_cfg.command_names = iwl_mvm_cmd_strings;
......
...@@ -1849,7 +1849,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, ...@@ -1849,7 +1849,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
/* start timer if queue currently empty */ /* start timer if queue currently empty */
if (q->read_ptr == q->write_ptr) { if (q->read_ptr == q->write_ptr) {
if (txq->need_update && trans_pcie->wd_timeout) if (trans_pcie->wd_timeout)
mod_timer(&txq->stuck_timer, mod_timer(&txq->stuck_timer,
jiffies + trans_pcie->wd_timeout); jiffies + trans_pcie->wd_timeout);
IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", q->id); IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", q->id);
......
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