aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2008-12-02 15:14:04 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-12-05 09:35:55 -0500
commitf3f911d1773d31f11038d90b04244bc3986c4ccd (patch)
tree83e5f2f8faf67c817b0617241a69e87cc6be1e3b
parent74221d07408c473721cce853ef4e0e66c0b326ba (diff)
iwlwifi: fix DMA channel number in iwl_txq_ctx_stop
The patch fixes the misuse of DMA channel number by Tx queue number in iwl_tx_ctx_stop(). The problem was originally reported by Wu Fengguang who complains iwlagn driver takes too long time when issuing `ifconfig wlan0 down`. The patch now decreases the interface bring down time from 2 seconds to 0.8 second. This fixes bugs: http://bugzilla.kernel.org/show_bug.cgi?id=11956 http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1790 Signed-off-by: Zhu Yi <yi.zhu@intel.com> Tested-by: Fengguang Wu <fengguang.wu@intel.com> Acked-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c11
4 files changed, 10 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index f90c9e92ef71..93d3df87fdaa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -816,6 +816,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
816 } 816 }
817 817
818 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 818 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
819 priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
819 priv->hw_params.scd_bc_tbls_size = 820 priv->hw_params.scd_bc_tbls_size =
820 IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl); 821 IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
821 priv->hw_params.max_stations = IWL4965_STATION_COUNT; 822 priv->hw_params.max_stations = IWL4965_STATION_COUNT;
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index b6c57cbf6f33..f7a8df8dcaa7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -827,6 +827,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
827 } 827 }
828 828
829 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 829 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
830 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
830 priv->hw_params.scd_bc_tbls_size = 831 priv->hw_params.scd_bc_tbls_size =
831 IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); 832 IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
832 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 833 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 846b8b01fa73..5f6805bfec3f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -508,6 +508,7 @@ struct iwl_sensitivity_ranges {
508/** 508/**
509 * struct iwl_hw_params 509 * struct iwl_hw_params
510 * @max_txq_num: Max # Tx queues supported 510 * @max_txq_num: Max # Tx queues supported
511 * @dma_chnl_num: Number of Tx DMA/FIFO channels
511 * @scd_bc_tbls_size: size of scheduler byte count tables 512 * @scd_bc_tbls_size: size of scheduler byte count tables
512 * @tx/rx_chains_num: Number of TX/RX chains 513 * @tx/rx_chains_num: Number of TX/RX chains
513 * @valid_tx/rx_ant: usable antennas 514 * @valid_tx/rx_ant: usable antennas
@@ -525,7 +526,8 @@ struct iwl_sensitivity_ranges {
525 * @struct iwl_sensitivity_ranges: range of sensitivity values 526 * @struct iwl_sensitivity_ranges: range of sensitivity values
526 */ 527 */
527struct iwl_hw_params { 528struct iwl_hw_params {
528 u16 max_txq_num; 529 u8 max_txq_num;
530 u8 dma_chnl_num;
529 u16 scd_bc_tbls_size; 531 u16 scd_bc_tbls_size;
530 u8 tx_chains_num; 532 u8 tx_chains_num;
531 u8 rx_chains_num; 533 u8 rx_chains_num;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index e045dfeaa1fe..18d6cf67d9b7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -611,7 +611,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
611 */ 611 */
612void iwl_txq_ctx_stop(struct iwl_priv *priv) 612void iwl_txq_ctx_stop(struct iwl_priv *priv)
613{ 613{
614 int txq_id; 614 int ch;
615 unsigned long flags; 615 unsigned long flags;
616 616
617 /* Turn off all Tx DMA fifos */ 617 /* Turn off all Tx DMA fifos */
@@ -624,12 +624,11 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
624 priv->cfg->ops->lib->txq_set_sched(priv, 0); 624 priv->cfg->ops->lib->txq_set_sched(priv, 0);
625 625
626 /* Stop each Tx DMA channel, and wait for it to be idle */ 626 /* Stop each Tx DMA channel, and wait for it to be idle */
627 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { 627 for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
628 iwl_write_direct32(priv, 628 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
629 FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), 0x0);
630 iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, 629 iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
631 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE 630 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
632 (txq_id), 200); 631 200);
633 } 632 }
634 iwl_release_nic_access(priv); 633 iwl_release_nic_access(priv);
635 spin_unlock_irqrestore(&priv->lock, flags); 634 spin_unlock_irqrestore(&priv->lock, flags);