diff options
author | Zhu Yi <yi.zhu@intel.com> | 2008-12-02 15:14:04 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-12-05 09:35:55 -0500 |
commit | f3f911d1773d31f11038d90b04244bc3986c4ccd (patch) | |
tree | 83e5f2f8faf67c817b0617241a69e87cc6be1e3b | |
parent | 74221d07408c473721cce853ef4e0e66c0b326ba (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.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 11 |
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 | */ |
527 | struct iwl_hw_params { | 528 | struct 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 | */ |
612 | void iwl_txq_ctx_stop(struct iwl_priv *priv) | 612 | void 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); |