Commit ea9b307f authored by Johannes Berg's avatar Johannes Berg Committed by Wey-Yi Guy

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: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent 549a04e0
...@@ -449,7 +449,6 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, ...@@ -449,7 +449,6 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
iwl_wake_queue(priv, txq); iwl_wake_queue(priv, txq);
} }
} else { } else {
BUG_ON(txq_id != txq->swq_id);
iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false);
freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
iwl_free_tfds_in_queue(priv, sta_id, tid, freed); iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
......
...@@ -1012,7 +1012,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -1012,7 +1012,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
tid_data = &priv->stations[sta_id].tid[tid]; tid_data = &priv->stations[sta_id].tid[tid];
*ssn = SEQ_TO_SN(tid_data->seq_number); *ssn = SEQ_TO_SN(tid_data->seq_number);
tid_data->agg.txq_id = txq_id; tid_data->agg.txq_id = txq_id;
priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id); iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
......
...@@ -992,11 +992,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, ...@@ -992,11 +992,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
" swq_id=%#.2x (ac %d/hwq %d)\n", " swq_id=%#.2x (ac %d/hwq %d)\n",
cnt, q->read_ptr, q->write_ptr, cnt, q->read_ptr, q->write_ptr,
!!test_bit(cnt, priv->queue_stopped), !!test_bit(cnt, priv->queue_stopped),
txq->swq_id, txq->swq_id, txq->swq_id & 3,
txq->swq_id & 0x80 ? txq->swq_id & 3 : (txq->swq_id >> 2) & 0x1f);
txq->swq_id,
txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
0x1f : txq->swq_id);
if (cnt >= 4) if (cnt >= 4)
continue; continue;
/* for the ACs, display the stop count too */ /* for the ACs, display the stop count too */
......
...@@ -104,29 +104,24 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, ...@@ -104,29 +104,24 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
* | | | | | | | | * | | | | | | | |
* | | | | | | +-+-------- AC queue (0-3) * | | | | | | +-+-------- AC queue (0-3)
* | | | | | | * | | | | | |
* | +-+-+-+-+------------ HW A-MPDU queue * | +-+-+-+-+------------ HW queue ID
* | * |
* +---------------------- indicates agg queue * +---------------------- unused
*/ */
static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq) static inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq)
{ {
BUG_ON(ac > 3); /* only have 2 bits */ BUG_ON(ac > 3); /* only have 2 bits */
BUG_ON(hwq > 31); /* only have 5 bits */ BUG_ON(hwq > 31); /* only use 5 bits */
return 0x80 | (hwq << 2) | ac; txq->swq_id = (hwq << 2) | ac;
} }
static inline void iwl_wake_queue(struct iwl_priv *priv, static inline void iwl_wake_queue(struct iwl_priv *priv,
struct iwl_tx_queue *txq) struct iwl_tx_queue *txq)
{ {
u8 queue = txq->swq_id; u8 queue = txq->swq_id;
u8 ac = queue; u8 ac = queue & 3;
u8 hwq = queue; u8 hwq = (queue >> 2) & 0x1f;
if (queue & 0x80) {
ac = queue & 3;
hwq = (queue >> 2) & 0x1f;
}
if (test_and_clear_bit(hwq, priv->queue_stopped)) if (test_and_clear_bit(hwq, priv->queue_stopped))
if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0) 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,13 +132,8 @@ static inline void iwl_stop_queue(struct iwl_priv *priv,
struct iwl_tx_queue *txq) struct iwl_tx_queue *txq)
{ {
u8 queue = txq->swq_id; u8 queue = txq->swq_id;
u8 ac = queue; u8 ac = queue & 3;
u8 hwq = queue; u8 hwq = (queue >> 2) & 0x1f;
if (queue & 0x80) {
ac = queue & 3;
hwq = (queue >> 2) & 0x1f;
}
if (!test_and_set_bit(hwq, priv->queue_stopped)) if (!test_and_set_bit(hwq, priv->queue_stopped))
if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0) if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0)
......
...@@ -359,13 +359,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, ...@@ -359,13 +359,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
txq->need_update = 0; txq->need_update = 0;
/* /*
* Aggregation TX queues will get their ID when aggregation begins; * For the default queues 0-3, set up the swq_id
* they overwrite the setting done here. The command FIFO doesn't * already -- all others need to get one later
* need an swq_id so don't set one to catch errors, all others can * (if they need one at all).
* be set up to the identity mapping.
*/ */
if (txq_id != priv->cmd_queue) if (txq_id < 4)
txq->swq_id = txq_id; iwl_set_swq_id(txq, txq_id, txq_id);
/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
* iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
......
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