diff options
author | Jesse Keating <jkeating@redhat.com> | 2010-07-29 17:18:45 -0700 |
---|---|---|
committer | Jesse Keating <jkeating@redhat.com> | 2010-07-29 17:18:45 -0700 |
commit | 2f82dda4a9bf41e64e864889bf06564bdf826e25 (patch) | |
tree | 118a7b483ae5de4dbf83d20001302f1404866ef0 /iwlwifi_-Recover-TX-flow-stall-due-to-stuck-queue.patch | |
parent | 64ba2e5ffde5f2418eb26c700cb0ab62b04e5013 (diff) | |
download | dom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.tar.gz dom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.tar.xz dom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.zip |
initial srpm import
Diffstat (limited to 'iwlwifi_-Recover-TX-flow-stall-due-to-stuck-queue.patch')
-rw-r--r-- | iwlwifi_-Recover-TX-flow-stall-due-to-stuck-queue.patch | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/iwlwifi_-Recover-TX-flow-stall-due-to-stuck-queue.patch b/iwlwifi_-Recover-TX-flow-stall-due-to-stuck-queue.patch new file mode 100644 index 0000000..e3b4b5c --- /dev/null +++ b/iwlwifi_-Recover-TX-flow-stall-due-to-stuck-queue.patch @@ -0,0 +1,446 @@ +This patch is not yet upstream... + +From a5e660b4e294556822913627544f661e59b39716 Mon Sep 17 00:00:00 2001 +From: Wey-Yi Guy <wey-yi.w.guy@intel.com> +Date: Mon, 1 Mar 2010 17:23:50 -0800 +Subject: [PATCH 13/17] 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> + +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-1000.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-1000.c +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-1000.c.orig 2010-03-22 15:33:38.000000000 -0400 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-1000.c 2010-03-22 15:48:54.000000000 -0400 +@@ -135,6 +135,7 @@ static struct iwl_lib_ops iwl1000_lib = + .temperature = iwl5000_temperature, + .set_ct_kill = iwl1000_set_ct_threshold, + }, ++ .recover_from_tx_stall = iwl_bg_monitor_recover, + }; + + static struct iwl_ops iwl1000_ops = { +@@ -163,5 +164,6 @@ struct iwl_cfg iwl1000_bgn_cfg = { + .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c.orig 2010-03-22 15:44:04.000000000 -0400 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c 2010-03-22 15:48:54.000000000 -0400 +@@ -2453,6 +2453,13 @@ static void iwl3945_alive_start(struct i + /* After the ALIVE response, we can send commands to 3945 uCode */ + set_bit(STATUS_ALIVE, &priv->status); + ++ if (priv->cfg->ops->lib->recover_from_tx_stall) { ++ /* Enable timer to monitor the driver queues */ ++ mod_timer(&priv->monitor_recover, ++ jiffies + ++ msecs_to_jiffies(priv->cfg->monitor_recover_period)); ++ } ++ + if (iwl_is_rfkill(priv)) + return; + +@@ -3730,6 +3737,13 @@ static void iwl3945_setup_deferred_work( + + iwl3945_hw_setup_deferred_work(priv); + ++ if (priv->cfg->ops->lib->recover_from_tx_stall) { ++ init_timer(&priv->monitor_recover); ++ priv->monitor_recover.data = (unsigned long)priv; ++ priv->monitor_recover.function = ++ priv->cfg->ops->lib->recover_from_tx_stall; ++ } ++ + tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) + iwl3945_irq_tasklet, (unsigned long)priv); + } +@@ -3742,6 +3756,8 @@ static void iwl3945_cancel_deferred_work + cancel_delayed_work(&priv->scan_check); + cancel_delayed_work(&priv->alive_start); + cancel_work_sync(&priv->beacon_update); ++ if (priv->cfg->ops->lib->recover_from_tx_stall) ++ del_timer_sync(&priv->monitor_recover); + } + + static struct attribute *iwl3945_sysfs_entries[] = { +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-3945.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-3945.c +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-3945.c.orig 2010-03-22 14:20:28.000000000 -0400 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-3945.c 2010-03-22 15:48:54.000000000 -0400 +@@ -2897,6 +2897,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { + .ht_greenfield_support = false, + .broken_powersave = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + static struct iwl_cfg iwl3945_abg_cfg = { +@@ -2913,6 +2914,7 @@ static struct iwl_cfg iwl3945_abg_cfg = + .ht_greenfield_support = false, + .broken_powersave = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + struct pci_device_id iwl3945_hw_card_ids[] = { +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c.orig 2010-03-22 14:24:14.000000000 -0400 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c 2010-03-22 15:48:54.000000000 -0400 +@@ -2364,6 +2364,7 @@ struct iwl_cfg iwl4965_agn_cfg = { + .ht_greenfield_support = false, + .broken_powersave = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + /* Module firmware */ +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-5000.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-5000.c +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-5000.c.orig 2010-03-22 14:27:05.000000000 -0400 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-5000.c 2010-03-22 15:48:54.000000000 -0400 +@@ -1579,6 +1579,7 @@ struct iwl_lib_ops iwl5000_lib = { + .temperature = iwl5000_temperature, + .set_ct_kill = iwl5000_set_ct_threshold, + }, ++ .recover_from_tx_stall = iwl_bg_monitor_recover, + }; + + static struct iwl_lib_ops iwl5150_lib = { +@@ -1631,6 +1632,7 @@ static struct iwl_lib_ops iwl5150_lib = + .temperature = iwl5150_temperature, + .set_ct_kill = iwl5150_set_ct_threshold, + }, ++ .recover_from_tx_stall = iwl_bg_monitor_recover, + }; + + struct iwl_ops iwl5000_ops = { +@@ -1673,6 +1675,7 @@ struct iwl_cfg iwl5300_agn_cfg = { + .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + struct iwl_cfg iwl5100_bg_cfg = { +@@ -1691,6 +1694,7 @@ struct iwl_cfg iwl5100_bg_cfg = { + .need_pll_cfg = true, + .ht_greenfield_support = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + struct iwl_cfg iwl5100_abg_cfg = { +@@ -1709,6 +1713,7 @@ struct iwl_cfg iwl5100_abg_cfg = { + .valid_rx_ant = ANT_AB, + .need_pll_cfg = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + struct iwl_cfg iwl5100_agn_cfg = { +@@ -1728,6 +1733,7 @@ struct iwl_cfg iwl5100_agn_cfg = { + .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + struct iwl_cfg iwl5350_agn_cfg = { +@@ -1747,6 +1753,7 @@ struct iwl_cfg iwl5350_agn_cfg = { + .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + struct iwl_cfg iwl5150_agn_cfg = { +@@ -1766,6 +1773,7 @@ struct iwl_cfg iwl5150_agn_cfg = { + .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-6000.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-6000.c +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-6000.c.orig 2010-03-22 14:28:04.000000000 -0400 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-6000.c 2010-03-22 15:51:12.000000000 -0400 +@@ -137,6 +137,7 @@ static struct iwl_lib_ops iwl6000_lib = + .temperature = iwl5000_temperature, + .set_ct_kill = iwl6000_set_ct_threshold, + }, ++ .recover_from_tx_stall = iwl_bg_monitor_recover, + }; + + static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = { +@@ -177,6 +178,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = { + .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + /* +@@ -202,6 +204,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = { + .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + struct iwl_cfg iwl6050_2agn_cfg = { +@@ -224,6 +227,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { + .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + struct iwl_cfg iwl6000_3agn_cfg = { +@@ -246,6 +250,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { + .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + struct iwl_cfg iwl6050_3agn_cfg = { +@@ -268,6 +273,7 @@ struct iwl_cfg iwl6050_3agn_cfg = { + .ht_greenfield_support = true, + .use_rts_for_ht = true, /* use rts/cts protection */ + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, ++ .monitor_recover_period = IWL_MONITORING_PERIOD, + }; + + MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-agn.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-agn.c +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-agn.c.orig 2009-12-02 22:51:21.000000000 -0500 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-agn.c 2010-03-22 15:48:54.000000000 -0400 +@@ -1755,6 +1755,13 @@ static void iwl_alive_start(struct iwl_p + /* After the ALIVE response, we can send host commands to the uCode */ + set_bit(STATUS_ALIVE, &priv->status); + ++ if (priv->cfg->ops->lib->recover_from_tx_stall) { ++ /* Enable timer to monitor the driver queues */ ++ mod_timer(&priv->monitor_recover, ++ jiffies + ++ msecs_to_jiffies(priv->cfg->monitor_recover_period)); ++ } ++ + if (iwl_is_rfkill(priv)) + return; + +@@ -2829,6 +2836,13 @@ static void iwl_setup_deferred_work(stru + priv->statistics_periodic.data = (unsigned long)priv; + priv->statistics_periodic.function = iwl_bg_statistics_periodic; + ++ if (priv->cfg->ops->lib->recover_from_tx_stall) { ++ init_timer(&priv->monitor_recover); ++ priv->monitor_recover.data = (unsigned long)priv; ++ priv->monitor_recover.function = ++ priv->cfg->ops->lib->recover_from_tx_stall; ++ } ++ + if (!priv->cfg->use_isr_legacy) + tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) + iwl_irq_tasklet, (unsigned long)priv); +@@ -2847,6 +2861,8 @@ static void iwl_cancel_deferred_work(str + cancel_delayed_work(&priv->alive_start); + cancel_work_sync(&priv->beacon_update); + del_timer_sync(&priv->statistics_periodic); ++ if (priv->cfg->ops->lib->recover_from_tx_stall) ++ del_timer_sync(&priv->monitor_recover); + } + + static struct attribute *iwl_sysfs_entries[] = { +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.c +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.c.orig 2010-03-22 15:40:48.000000000 -0400 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.c 2010-03-22 15:48:54.000000000 -0400 +@@ -3107,6 +3107,99 @@ int iwl_force_reset(struct iwl_priv *pri + } + return 0; + } ++EXPORT_SYMBOL(iwl_force_reset); ++ ++/** ++ * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover ++ * ++ * During normal condition (no queue is stuck), the timer is continually set to ++ * execute every monitor_recover_period milliseconds after the last timer ++ * expired. When the queue read_ptr is at the same place, the timer is ++ * shorten to 100mSecs. This is ++ * 1) to reduce the chance that the read_ptr may wrap around (not stuck) ++ * 2) to detect the stuck queues quicker before the station and AP can ++ * disassociate each other. ++ * ++ * This function monitors all the tx queues and recover from it if any ++ * of the queues are stuck. ++ * 1. It first check the cmd queue for stuck conditions. If it is stuck, ++ * it will recover by resetting the firmware and return. ++ * 2. Then, it checks for station association. If it associates it will check ++ * other queues. If any queue is stuck, it will recover by resetting ++ * the firmware. ++ * Note: It the number of times the queue read_ptr to be at the same place to ++ * be MAX_REPEAT+1 in order to consider to be stuck. ++ */ ++/* ++ * The maximum number of times the read pointer of the tx queue at the ++ * same place without considering to be stuck. ++ */ ++#define MAX_REPEAT (2) ++static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt) ++{ ++ struct iwl_tx_queue *txq; ++ struct iwl_queue *q; ++ ++ txq = &priv->txq[cnt]; ++ q = &txq->q; ++ /* queue is empty, skip */ ++ if (q->read_ptr != q->write_ptr) { ++ if (q->read_ptr == q->last_read_ptr) { ++ /* a queue has not been read from last time */ ++ if (q->repeat_same_read_ptr > MAX_REPEAT) { ++ IWL_ERR(priv, ++ "queue %d stuck %d time. Fw reload.\n", ++ q->id, q->repeat_same_read_ptr); ++ q->repeat_same_read_ptr = 0; ++ iwl_force_reset(priv, IWL_FW_RESET); ++ } else { ++ q->repeat_same_read_ptr++; ++ IWL_DEBUG_RADIO(priv, ++ "queue %d, not read %d time\n", ++ q->id, ++ q->repeat_same_read_ptr); ++ mod_timer(&priv->monitor_recover, jiffies + ++ msecs_to_jiffies(IWL_ONE_HUNDRED_MSECS)); ++ } ++ return 1; ++ } else { ++ q->last_read_ptr = q->read_ptr; ++ q->repeat_same_read_ptr = 0; ++ } ++ } ++ return 0; ++} ++ ++void iwl_bg_monitor_recover(unsigned long data) ++{ ++ struct iwl_priv *priv = (struct iwl_priv *)data; ++ int cnt; ++ ++ if (test_bit(STATUS_EXIT_PENDING, &priv->status)) ++ return; ++ ++ /* monitor and check for stuck cmd queue */ ++ if (iwl_check_stuck_queue(priv, IWL_CMD_QUEUE_NUM)) ++ return; ++ ++ /* monitor and check for other stuck queues */ ++ if (iwl_is_associated(priv)) { ++ for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { ++ /* skip as we already checked the command queue */ ++ if (cnt == IWL_CMD_QUEUE_NUM) ++ continue; ++ if (iwl_check_stuck_queue(priv, cnt)) ++ return; ++ } ++ } ++ /* ++ * Reschedule the timer to occur in ++ * priv->cfg->monitor_recover_period ++ */ ++ mod_timer(&priv->monitor_recover, ++ jiffies + msecs_to_jiffies(priv->cfg->monitor_recover_period)); ++} ++EXPORT_SYMBOL(iwl_bg_monitor_recover); + + #ifdef CONFIG_PM + +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.h.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.h +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.h.orig 2010-03-22 15:24:28.000000000 -0400 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.h 2010-03-22 15:48:54.000000000 -0400 +@@ -183,6 +183,8 @@ struct iwl_lib_ops { + + /* temperature */ + struct iwl_temp_ops temp_ops; ++ /* recover from tx queue stall */ ++ void (*recover_from_tx_stall)(unsigned long data); + }; + + struct iwl_ops { +@@ -260,6 +262,8 @@ struct iwl_cfg { + const bool broken_powersave; + bool use_rts_for_ht; + u8 plcp_delta_threshold; ++ /* timer period for monitor the driver queues */ ++ u32 monitor_recover_period; + }; + + /*************************** +@@ -543,6 +547,9 @@ static inline u16 iwl_pcie_link_ctl(stru + pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); + return pci_lnk_ctl; + } ++ ++void iwl_bg_monitor_recover(unsigned long data); ++ + #ifdef CONFIG_PM + int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state); + int iwl_pci_resume(struct pci_dev *pdev); +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-dev.h.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-dev.h +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-dev.h.orig 2010-03-22 15:37:04.000000000 -0400 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-dev.h 2010-03-22 15:48:54.000000000 -0400 +@@ -184,6 +184,10 @@ struct iwl_queue { + int n_bd; /* number of BDs in this queue */ + int write_ptr; /* 1-st empty entry (index) host_w*/ + int read_ptr; /* last used entry (index) host_r*/ ++ /* use for monitoring and recovering the stuck queue */ ++ int last_read_ptr; /* storing the last read_ptr */ ++ /* number of time read_ptr and last_read_ptr are the same */ ++ u8 repeat_same_read_ptr; + dma_addr_t dma_addr; /* physical addr for BD's */ + int n_window; /* safe queue window */ + u32 id; +@@ -976,6 +980,11 @@ struct traffic_stats { + #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) + #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) + ++/* timer constants use to monitor and recover stuck tx queues in mSecs */ ++#define IWL_MONITORING_PERIOD (1000) ++#define IWL_ONE_HUNDRED_MSECS (100) ++#define IWL_SIXTY_SECS (60000) ++ + enum iwl_reset { + IWL_RF_RESET = 0, + IWL_FW_RESET, +@@ -1275,6 +1284,7 @@ struct iwl_priv { + u32 disable_tx_power_cal; + struct work_struct run_time_calib_work; + struct timer_list statistics_periodic; ++ struct timer_list monitor_recover; + bool hw_ready; + /*For 3945*/ + #define IWL_DEFAULT_TX_POWER 0x0F +diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-tx.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-tx.c +--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-tx.c.orig 2010-03-22 11:07:02.000000000 -0400 ++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-tx.c 2010-03-22 15:48:54.000000000 -0400 +@@ -291,6 +291,8 @@ static int iwl_queue_init(struct iwl_pri + q->high_mark = 2; + + q->write_ptr = q->read_ptr = 0; ++ q->last_read_ptr = 0; ++ q->repeat_same_read_ptr = 0; + + return 0; + } |