diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-11-10 21:25:45 -0500 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-11-16 10:46:00 -0500 |
commit | ea9b307f8e859186a6791e0d508c5993448ac900 (patch) | |
tree | e9d4a87fd4570d8720cba2c6945e2068c6833b77 /drivers/net | |
parent | 549a04e092e5e043df82fd0541f3b67ab488359b (diff) |
iwlwifi: always build swq_id as virtual queue ID
Previously, we used the swq_id's mechanism
to have AC and HW queue different only for
aggregation queues. To be able to fix a bug
with iPAN simply always build the swq_id as
ac | (hwq << 2) and remove the flag bit.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-helpers.h | 28 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 11 |
5 files changed, 17 insertions, 32 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index eef90b5c972..881475cf5ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -449,7 +449,6 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, | |||
449 | iwl_wake_queue(priv, txq); | 449 | iwl_wake_queue(priv, txq); |
450 | } | 450 | } |
451 | } else { | 451 | } else { |
452 | BUG_ON(txq_id != txq->swq_id); | ||
453 | iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); | 452 | iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); |
454 | freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); | 453 | freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); |
455 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); | 454 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 179a9c85045..330852cc469 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -1012,7 +1012,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
1012 | tid_data = &priv->stations[sta_id].tid[tid]; | 1012 | tid_data = &priv->stations[sta_id].tid[tid]; |
1013 | *ssn = SEQ_TO_SN(tid_data->seq_number); | 1013 | *ssn = SEQ_TO_SN(tid_data->seq_number); |
1014 | tid_data->agg.txq_id = txq_id; | 1014 | tid_data->agg.txq_id = txq_id; |
1015 | priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id); | 1015 | iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id); |
1016 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 1016 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
1017 | 1017 | ||
1018 | ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, | 1018 | ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 4876e26e054..3cc58420d44 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -992,11 +992,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
992 | " swq_id=%#.2x (ac %d/hwq %d)\n", | 992 | " swq_id=%#.2x (ac %d/hwq %d)\n", |
993 | cnt, q->read_ptr, q->write_ptr, | 993 | cnt, q->read_ptr, q->write_ptr, |
994 | !!test_bit(cnt, priv->queue_stopped), | 994 | !!test_bit(cnt, priv->queue_stopped), |
995 | txq->swq_id, | 995 | txq->swq_id, txq->swq_id & 3, |
996 | txq->swq_id & 0x80 ? txq->swq_id & 3 : | 996 | (txq->swq_id >> 2) & 0x1f); |
997 | txq->swq_id, | ||
998 | txq->swq_id & 0x80 ? (txq->swq_id >> 2) & | ||
999 | 0x1f : txq->swq_id); | ||
1000 | if (cnt >= 4) | 997 | if (cnt >= 4) |
1001 | continue; | 998 | continue; |
1002 | /* for the ACs, display the stop count too */ | 999 | /* for the ACs, display the stop count too */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 23fa8e88356..e53cd7f7ea3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h | |||
@@ -104,29 +104,24 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, | |||
104 | * | | | | | | | | | 104 | * | | | | | | | | |
105 | * | | | | | | +-+-------- AC queue (0-3) | 105 | * | | | | | | +-+-------- AC queue (0-3) |
106 | * | | | | | | | 106 | * | | | | | | |
107 | * | +-+-+-+-+------------ HW A-MPDU queue | 107 | * | +-+-+-+-+------------ HW queue ID |
108 | * | | 108 | * | |
109 | * +---------------------- indicates agg queue | 109 | * +---------------------- unused |
110 | */ | 110 | */ |
111 | static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq) | 111 | static inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq) |
112 | { | 112 | { |
113 | BUG_ON(ac > 3); /* only have 2 bits */ | 113 | BUG_ON(ac > 3); /* only have 2 bits */ |
114 | BUG_ON(hwq > 31); /* only have 5 bits */ | 114 | BUG_ON(hwq > 31); /* only use 5 bits */ |
115 | 115 | ||
116 | return 0x80 | (hwq << 2) | ac; | 116 | txq->swq_id = (hwq << 2) | ac; |
117 | } | 117 | } |
118 | 118 | ||
119 | static inline void iwl_wake_queue(struct iwl_priv *priv, | 119 | static inline void iwl_wake_queue(struct iwl_priv *priv, |
120 | struct iwl_tx_queue *txq) | 120 | struct iwl_tx_queue *txq) |
121 | { | 121 | { |
122 | u8 queue = txq->swq_id; | 122 | u8 queue = txq->swq_id; |
123 | u8 ac = queue; | 123 | u8 ac = queue & 3; |
124 | u8 hwq = queue; | 124 | u8 hwq = (queue >> 2) & 0x1f; |
125 | |||
126 | if (queue & 0x80) { | ||
127 | ac = queue & 3; | ||
128 | hwq = (queue >> 2) & 0x1f; | ||
129 | } | ||
130 | 125 | ||
131 | if (test_and_clear_bit(hwq, priv->queue_stopped)) | 126 | if (test_and_clear_bit(hwq, priv->queue_stopped)) |
132 | if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0) | 127 | if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0) |
@@ -137,13 +132,8 @@ static inline void iwl_stop_queue(struct iwl_priv *priv, | |||
137 | struct iwl_tx_queue *txq) | 132 | struct iwl_tx_queue *txq) |
138 | { | 133 | { |
139 | u8 queue = txq->swq_id; | 134 | u8 queue = txq->swq_id; |
140 | u8 ac = queue; | 135 | u8 ac = queue & 3; |
141 | u8 hwq = queue; | 136 | u8 hwq = (queue >> 2) & 0x1f; |
142 | |||
143 | if (queue & 0x80) { | ||
144 | ac = queue & 3; | ||
145 | hwq = (queue >> 2) & 0x1f; | ||
146 | } | ||
147 | 137 | ||
148 | if (!test_and_set_bit(hwq, priv->queue_stopped)) | 138 | if (!test_and_set_bit(hwq, priv->queue_stopped)) |
149 | if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0) | 139 | if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index feaa3670c6b..90659bcf580 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -359,13 +359,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | |||
359 | txq->need_update = 0; | 359 | txq->need_update = 0; |
360 | 360 | ||
361 | /* | 361 | /* |
362 | * Aggregation TX queues will get their ID when aggregation begins; | 362 | * For the default queues 0-3, set up the swq_id |
363 | * they overwrite the setting done here. The command FIFO doesn't | 363 | * already -- all others need to get one later |
364 | * need an swq_id so don't set one to catch errors, all others can | 364 | * (if they need one at all). |
365 | * be set up to the identity mapping. | ||
366 | */ | 365 | */ |
367 | if (txq_id != priv->cmd_queue) | 366 | if (txq_id < 4) |
368 | txq->swq_id = txq_id; | 367 | iwl_set_swq_id(txq, txq_id, txq_id); |
369 | 368 | ||
370 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | 369 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise |
371 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ | 370 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ |