aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.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/iwl3945-base.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/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 6687b9456554..4995134d7e4a 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2501,6 +2501,13 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2501 /* After the ALIVE response, we can send commands to 3945 uCode */ 2501 /* After the ALIVE response, we can send commands to 3945 uCode */
2502 set_bit(STATUS_ALIVE, &priv->status); 2502 set_bit(STATUS_ALIVE, &priv->status);
2503 2503
2504 if (priv->cfg->ops->lib->recover_from_tx_stall) {
2505 /* Enable timer to monitor the driver queues */
2506 mod_timer(&priv->monitor_recover,
2507 jiffies +
2508 msecs_to_jiffies(priv->cfg->monitor_recover_period));
2509 }
2510
2504 if (iwl_is_rfkill(priv)) 2511 if (iwl_is_rfkill(priv))
2505 return; 2512 return;
2506 2513
@@ -3796,6 +3803,13 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3796 3803
3797 iwl3945_hw_setup_deferred_work(priv); 3804 iwl3945_hw_setup_deferred_work(priv);
3798 3805
3806 if (priv->cfg->ops->lib->recover_from_tx_stall) {
3807 init_timer(&priv->monitor_recover);
3808 priv->monitor_recover.data = (unsigned long)priv;
3809 priv->monitor_recover.function =
3810 priv->cfg->ops->lib->recover_from_tx_stall;
3811 }
3812
3799 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3813 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3800 iwl3945_irq_tasklet, (unsigned long)priv); 3814 iwl3945_irq_tasklet, (unsigned long)priv);
3801} 3815}
@@ -3808,6 +3822,8 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
3808 cancel_delayed_work(&priv->scan_check); 3822 cancel_delayed_work(&priv->scan_check);
3809 cancel_delayed_work(&priv->alive_start); 3823 cancel_delayed_work(&priv->alive_start);
3810 cancel_work_sync(&priv->beacon_update); 3824 cancel_work_sync(&priv->beacon_update);
3825 if (priv->cfg->ops->lib->recover_from_tx_stall)
3826 del_timer_sync(&priv->monitor_recover);
3811} 3827}
3812 3828
3813static struct attribute *iwl3945_sysfs_entries[] = { 3829static struct attribute *iwl3945_sysfs_entries[] = {