iwlwifi: always build swq_id as virtual queue ID
authorJohannes Berg <johannes.berg@intel.com>
Thu, 11 Nov 2010 02:25:45 +0000 (18:25 -0800)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Tue, 16 Nov 2010 15:46:00 +0000 (07:46 -0800)
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>
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-helpers.h
drivers/net/wireless/iwlwifi/iwl-tx.c

index eef90b5c972827554fa595e2f2bb76ef2c28e99d..881475cf5ad72f8a6ee8cda9adece3eb19d1193c 100644 (file)
@@ -449,7 +449,6 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
                                iwl_wake_queue(priv, txq);
                }
        } else {
-               BUG_ON(txq_id != txq->swq_id);
                iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false);
                freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
                iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
index 179a9c85045cbc89a5635e7019a9d2106bc960de..330852cc46901b1909130cf00164ecaa58b74a08 100644 (file)
@@ -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];
        *ssn = SEQ_TO_SN(tid_data->seq_number);
        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);
 
        ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
index 4876e26e054db6b6de63a60bb8338e725021a6f3..3cc58420d445ec02273078d76c68c6f8bf148a53 100644 (file)
@@ -992,11 +992,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
                                " swq_id=%#.2x (ac %d/hwq %d)\n",
                                cnt, q->read_ptr, q->write_ptr,
                                !!test_bit(cnt, priv->queue_stopped),
-                               txq->swq_id,
-                               txq->swq_id & 0x80 ? txq->swq_id & 3 :
-                               txq->swq_id,
-                               txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
-                               0x1f : txq->swq_id);
+                               txq->swq_id, txq->swq_id & 3,
+                               (txq->swq_id >> 2) & 0x1f);
                if (cnt >= 4)
                        continue;
                /* for the ACs, display the stop count too */
index 23fa8e88356b09b8d5bf8bbc8e7307db0ff20c18..e53cd7f7ea3612ac0a5a69609f64e31c93ca06ba 100644 (file)
@@ -104,29 +104,24 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
  * | | | | | | | |
  * | | | | | | +-+-------- 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(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,
                                  struct iwl_tx_queue *txq)
 {
        u8 queue = txq->swq_id;
-       u8 ac = queue;
-       u8 hwq = queue;
-
-       if (queue & 0x80) {
-               ac = queue & 3;
-               hwq = (queue >> 2) & 0x1f;
-       }
+       u8 ac = queue & 3;
+       u8 hwq = (queue >> 2) & 0x1f;
 
        if (test_and_clear_bit(hwq, priv->queue_stopped))
                if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0)
@@ -137,13 +132,8 @@ static inline void iwl_stop_queue(struct iwl_priv *priv,
                                  struct iwl_tx_queue *txq)
 {
        u8 queue = txq->swq_id;
-       u8 ac = queue;
-       u8 hwq = queue;
-
-       if (queue & 0x80) {
-               ac = queue & 3;
-               hwq = (queue >> 2) & 0x1f;
-       }
+       u8 ac = queue & 3;
+       u8 hwq = (queue >> 2) & 0x1f;
 
        if (!test_and_set_bit(hwq, priv->queue_stopped))
                if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0)
index feaa3670c6bb62621b39c4b812474f1ac9a86c6f..90659bcf58041b54879f9d958526dc096af02826 100644 (file)
@@ -359,13 +359,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
        txq->need_update = 0;
 
        /*
-        * Aggregation TX queues will get their ID when aggregation begins;
-        * they overwrite the setting done here. The command FIFO doesn't
-        * need an swq_id so don't set one to catch errors, all others can
-        * be set up to the identity mapping.
+        * For the default queues 0-3, set up the swq_id
+        * already -- all others need to get one later
+        * (if they need one at all).
         */
-       if (txq_id != priv->cmd_queue)
-               txq->swq_id = txq_id;
+       if (txq_id < 4)
+               iwl_set_swq_id(txq, txq_id, txq_id);
 
        /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
         * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */