aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2010-03-01 20:23:50 -0500
committerReinette Chatre <reinette.chatre@intel.com>2010-03-19 16:41:25 -0400
commitb74e31a9bc1013e69b85b139072485dc153453dd (patch)
treecf3fa8db0a9a5d58d9bc633c5fe7b8e641d28d43 /drivers/net/wireless/iwlwifi/iwl-agn.c
parentc11362c01b280f8b2c728bc64793d484282b8734 (diff)
iwlwifi: Recover TX flow stall due to stuck queue
Monitors the internal TX queues periodically. When a queue is stuck for some unknown conditions causing the throughput to drop and the transfer is stop, the driver will force firmware reload and bring the system back to normal operational state. The iwlwifi devices behave differently in this regard so this feature is made part of the ops infrastructure so we can have more control on how to monitor and recover from tx queue stall case per device. Signed-off-by: Trieu 'Andrew' Nguyen <trieux.t.nguyen@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 93931b61304b..82b1a3fb54ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2074,6 +2074,13 @@ static void iwl_alive_start(struct iwl_priv *priv)
2074 /* After the ALIVE response, we can send host commands to the uCode */ 2074 /* After the ALIVE response, we can send host commands to the uCode */
2075 set_bit(STATUS_ALIVE, &priv->status); 2075 set_bit(STATUS_ALIVE, &priv->status);
2076 2076
2077 if (priv->cfg->ops->lib->recover_from_tx_stall) {
2078 /* Enable timer to monitor the driver queues */
2079 mod_timer(&priv->monitor_recover,
2080 jiffies +
2081 msecs_to_jiffies(priv->cfg->monitor_recover_period));
2082 }
2083
2077 if (iwl_is_rfkill(priv)) 2084 if (iwl_is_rfkill(priv))
2078 return; 2085 return;
2079 2086
@@ -3224,6 +3231,13 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3224 priv->ucode_trace.data = (unsigned long)priv; 3231 priv->ucode_trace.data = (unsigned long)priv;
3225 priv->ucode_trace.function = iwl_bg_ucode_trace; 3232 priv->ucode_trace.function = iwl_bg_ucode_trace;
3226 3233
3234 if (priv->cfg->ops->lib->recover_from_tx_stall) {
3235 init_timer(&priv->monitor_recover);
3236 priv->monitor_recover.data = (unsigned long)priv;
3237 priv->monitor_recover.function =
3238 priv->cfg->ops->lib->recover_from_tx_stall;
3239 }
3240
3227 if (!priv->cfg->use_isr_legacy) 3241 if (!priv->cfg->use_isr_legacy)
3228 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3242 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3229 iwl_irq_tasklet, (unsigned long)priv); 3243 iwl_irq_tasklet, (unsigned long)priv);
@@ -3243,6 +3257,8 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3243 cancel_work_sync(&priv->beacon_update); 3257 cancel_work_sync(&priv->beacon_update);
3244 del_timer_sync(&priv->statistics_periodic); 3258 del_timer_sync(&priv->statistics_periodic);
3245 del_timer_sync(&priv->ucode_trace); 3259 del_timer_sync(&priv->ucode_trace);
3260 if (priv->cfg->ops->lib->recover_from_tx_stall)
3261 del_timer_sync(&priv->monitor_recover);
3246} 3262}
3247 3263
3248static void iwl_init_hw_rates(struct iwl_priv *priv, 3264static void iwl_init_hw_rates(struct iwl_priv *priv,