Commit f3f911d1 authored by Zhu Yi's avatar Zhu Yi Committed by John W. Linville

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=1790Signed-off-by: default avatarZhu Yi <yi.zhu@intel.com>
Tested-by: default avatarFengguang Wu <fengguang.wu@intel.com>
Acked-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 74221d07
...@@ -816,6 +816,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) ...@@ -816,6 +816,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
} }
priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size = priv->hw_params.scd_bc_tbls_size =
IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl); IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
priv->hw_params.max_stations = IWL4965_STATION_COUNT; priv->hw_params.max_stations = IWL4965_STATION_COUNT;
......
...@@ -827,6 +827,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) ...@@ -827,6 +827,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
} }
priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size = priv->hw_params.scd_bc_tbls_size =
IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
priv->hw_params.max_stations = IWL5000_STATION_COUNT; priv->hw_params.max_stations = IWL5000_STATION_COUNT;
......
...@@ -508,6 +508,7 @@ struct iwl_sensitivity_ranges { ...@@ -508,6 +508,7 @@ struct iwl_sensitivity_ranges {
/** /**
* struct iwl_hw_params * struct iwl_hw_params
* @max_txq_num: Max # Tx queues supported * @max_txq_num: Max # Tx queues supported
* @dma_chnl_num: Number of Tx DMA/FIFO channels
* @scd_bc_tbls_size: size of scheduler byte count tables * @scd_bc_tbls_size: size of scheduler byte count tables
* @tx/rx_chains_num: Number of TX/RX chains * @tx/rx_chains_num: Number of TX/RX chains
* @valid_tx/rx_ant: usable antennas * @valid_tx/rx_ant: usable antennas
...@@ -525,7 +526,8 @@ struct iwl_sensitivity_ranges { ...@@ -525,7 +526,8 @@ struct iwl_sensitivity_ranges {
* @struct iwl_sensitivity_ranges: range of sensitivity values * @struct iwl_sensitivity_ranges: range of sensitivity values
*/ */
struct iwl_hw_params { struct iwl_hw_params {
u16 max_txq_num; u8 max_txq_num;
u8 dma_chnl_num;
u16 scd_bc_tbls_size; u16 scd_bc_tbls_size;
u8 tx_chains_num; u8 tx_chains_num;
u8 rx_chains_num; u8 rx_chains_num;
......
...@@ -611,7 +611,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) ...@@ -611,7 +611,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
*/ */
void iwl_txq_ctx_stop(struct iwl_priv *priv) void iwl_txq_ctx_stop(struct iwl_priv *priv)
{ {
int txq_id; int ch;
unsigned long flags; unsigned long flags;
/* Turn off all Tx DMA fifos */ /* Turn off all Tx DMA fifos */
...@@ -624,12 +624,11 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv) ...@@ -624,12 +624,11 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
priv->cfg->ops->lib->txq_set_sched(priv, 0); priv->cfg->ops->lib->txq_set_sched(priv, 0);
/* Stop each Tx DMA channel, and wait for it to be idle */ /* Stop each Tx DMA channel, and wait for it to be idle */
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
iwl_write_direct32(priv, iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), 0x0);
iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
(txq_id), 200); 200);
} }
iwl_release_nic_access(priv); iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment