]> err.no Git - linux-2.6/commitdiff
mac80211: QoS related cleanups
authorJohannes Berg <johannes@sipsolutions.net>
Wed, 30 Apr 2008 16:51:21 +0000 (18:51 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 7 May 2008 19:02:26 +0000 (15:02 -0400)
This
 * makes the queue number passed to drivers a u16
   (as it will be with skb_get_queue_mapping)
 * removes the useless queue number defines
 * splits hw->queues into hw->queues/ampdu_queues
 * removes the debugfs files for per-queue counters
 * removes some dead QoS code
 * removes the beacon queue configuration for IBSS
   so that the drivers now never get a queue number
   bigger than (hw->queues + hw->ampdu_queues - 1)
   for tx and only in the range 0..hw->queues-1 for
   conf_tx.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
19 files changed:
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl4965-base.c
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00queue.h
include/net/mac80211.h
net/mac80211/debugfs.c
net/mac80211/debugfs_sta.c
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/wme.c

index cf546e367d3e876a1c0788771863cd3b761e1f5c..c6e79a15d3cbc96971614ff853c97bae6fb75dc0 100644 (file)
@@ -2996,8 +2996,7 @@ static void b43_qos_update_work(struct work_struct *work)
        mutex_unlock(&wl->mutex);
 }
 
-static int b43_op_conf_tx(struct ieee80211_hw *hw,
-                         int _queue,
+static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
                          const struct ieee80211_tx_queue_params *params)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
index 14a5eea2573e8a01e28f2b9cb23cda7f4450bc8e..1ccc51e90a8ea170a57ad2e7f51c4a61658d627d 100644 (file)
@@ -2383,8 +2383,7 @@ out:
        return NETDEV_TX_OK;
 }
 
-static int b43legacy_op_conf_tx(struct ieee80211_hw *hw,
-                               int queue,
+static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
                                const struct ieee80211_tx_queue_params *params)
 {
        return 0;
index 27e5f496bc12a5be131a04b8e349b6a7b9a33bd1..c4b5c1a100f29c0de1c1e963869f54a5a0b7b648 100644 (file)
@@ -568,7 +568,7 @@ static void iwlcore_init_hw(struct iwl_priv *priv)
        hw->queues = 4;
 #ifdef CONFIG_IWL4965_HT
        /* Enhanced value; more queues, to support 11n aggregation */
-       hw->queues = 16;
+       hw->ampdu_queues = 12;
 #endif /* CONFIG_IWL4965_HT */
 }
 
index bad367cfbee3d859d5e6b82d7e74af004c0ba1b2..7040cde8bc28e9a337aee3ec4a663912fe16e7fc 100644 (file)
@@ -7143,7 +7143,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        return rc;
 }
 
-static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue,
+static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
                           const struct ieee80211_tx_queue_params *params)
 {
        struct iwl3945_priv *priv = hw->priv;
index 5363be7a305e212cebce78c62ed1f2e8bc563fd1..4406fc72d881f811f314b9ddce23e15d14235393 100644 (file)
@@ -6339,7 +6339,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        return ret;
 }
 
-static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
+static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
                           const struct ieee80211_tx_queue_params *params)
 {
        struct iwl_priv *priv = hw->priv;
index 59a26978f8771b01c43a4e79514553c23e5e9e35..34b91ccd8aec7b23cbbaaea3d3a226f48aae71f2 100644 (file)
@@ -935,7 +935,7 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
        }
 }
 
-static int p54_conf_tx(struct ieee80211_hw *dev, int queue,
+static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
                       const struct ieee80211_tx_queue_params *params)
 {
        struct p54_common *priv = dev->priv;
index 705bc2d41dc171b76fd1bf95cbb2dafaa140938e..247fbbfb0f2b2a9b46b63561cbfe1268f25025b5 100644 (file)
@@ -1442,8 +1442,7 @@ static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw,
        return 0;
 }
 
-static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
-                            int queue,
+static int rt2400pci_conf_tx(struct ieee80211_hw *hw, u16 queue,
                             const struct ieee80211_tx_queue_params *params)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -1453,7 +1452,7 @@ static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
         * per queue. So by default we only configure the TX queue,
         * and ignore all other configurations.
         */
-       if (queue != IEEE80211_TX_QUEUE_DATA0)
+       if (queue != 0)
                return -EINVAL;
 
        if (rt2x00mac_conf_tx(hw, queue, params))
index 48a9af47921efe889a0354fa1640ebf0906973ed..79bd9c9f896312185b52db85be7a85d8ec22fcf8 100644 (file)
@@ -997,7 +997,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
                                struct ieee80211_vif *vif,
                                struct ieee80211_bss_conf *bss_conf,
                                u32 changes);
-int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue,
+int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
                      const struct ieee80211_tx_queue_params *params);
 
 /*
index 7bc5129484f25ff2c3a435f12f2ed79d4c142e93..767e0ffce04e8d086712d7501fc99ebf3126648b 100644 (file)
@@ -517,7 +517,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
 
-int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue_idx,
+int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
                      const struct ieee80211_tx_queue_params *params)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
index 29fe26525550f5fe554ab1b6e07220573b542780..d1707a7ca41f73c109d3261a514c9f460cb572d4 100644 (file)
@@ -86,12 +86,9 @@ enum data_queue_qid {
 static inline enum data_queue_qid mac80211_queue_to_qid(unsigned int queue)
 {
        /* Regular TX queues are mapped directly */
-       if (queue < NUM_TX_DATA_QUEUES)
+       if (queue < 4)
                return queue;
-       else if (queue == IEEE80211_TX_QUEUE_BEACON)
-               return QID_BEACON;
-       else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)
-               return QID_ATIM;
+       WARN_ON(1);
        return QID_OTHER;
 }
 
index ef701d6fd66a7fc05fe7c16b8df60654c553b2f4..75a34609eed7955ef84576e3667bc8540c5f4c05 100644 (file)
@@ -97,6 +97,18 @@ struct ieee80211_ht_bss_info {
        u8 bss_op_mode; /* use IEEE80211_HT_IE_ */
 };
 
+/**
+ * enum ieee80211_max_queues - maximum number of queues
+ *
+ * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
+ * @IEEE80211_MAX_AMPDU_QUEUES: Maximum number of queues usable
+ *     for A-MPDU operation.
+ */
+enum ieee80211_max_queues {
+       IEEE80211_MAX_QUEUES =          16,
+       IEEE80211_MAX_AMPDU_QUEUES =    16,
+};
+
 /**
  * struct ieee80211_tx_queue_params - transmit queue configuration
  *
@@ -129,42 +141,6 @@ struct ieee80211_tx_queue_stats {
        unsigned int count;
 };
 
-/**
- * enum ieee80211_tx_queue - transmit queue number
- *
- * These constants are used with some callbacks that take a
- * queue number to set parameters for a queue.
- *
- * @IEEE80211_TX_QUEUE_DATA0: data queue 0
- * @IEEE80211_TX_QUEUE_DATA1: data queue 1
- * @IEEE80211_TX_QUEUE_DATA2: data queue 2
- * @IEEE80211_TX_QUEUE_DATA3: data queue 3
- * @IEEE80211_TX_QUEUE_DATA4: data queue 4
- * @IEEE80211_TX_QUEUE_SVP: ??
- * @NUM_TX_DATA_QUEUES: number of data queues
- * @IEEE80211_TX_QUEUE_AFTER_BEACON: transmit queue for frames to be
- *     sent after a beacon
- * @IEEE80211_TX_QUEUE_BEACON: transmit queue for beacon frames
- * @NUM_TX_DATA_QUEUES_AMPDU: adding more queues for A-MPDU
- */
-enum ieee80211_tx_queue {
-       IEEE80211_TX_QUEUE_DATA0,
-       IEEE80211_TX_QUEUE_DATA1,
-       IEEE80211_TX_QUEUE_DATA2,
-       IEEE80211_TX_QUEUE_DATA3,
-       IEEE80211_TX_QUEUE_DATA4,
-       IEEE80211_TX_QUEUE_SVP,
-
-       NUM_TX_DATA_QUEUES,
-
-/* due to stupidity in the sub-ioctl userspace interface, the items in
- * this struct need to have fixed values. As soon as it is removed, we can
- * fix these entries. */
-       IEEE80211_TX_QUEUE_AFTER_BEACON = 6,
-       IEEE80211_TX_QUEUE_BEACON = 7,
-       NUM_TX_DATA_QUEUES_AMPDU = 16
-};
-
 struct ieee80211_low_level_stats {
        unsigned int dot11ACKFailureCount;
        unsigned int dot11RTSFailureCount;
@@ -315,7 +291,7 @@ struct ieee80211_tx_control {
                                 * position represents antenna number used */
        u8 icv_len;             /* length of the ICV/MIC field in octets */
        u8 iv_len;              /* length of the IV field in octets */
-       u8 queue;               /* hardware queue to use for this frame;
+       u16 queue;              /* hardware queue to use for this frame;
                                 * 0 = highest, hw->queues-1 = lowest */
        u16 aid;                /* Station AID */
        int type;       /* internal */
@@ -772,7 +748,14 @@ enum ieee80211_hw_flags {
  * @max_noise: like @max_rssi, but for the noise value.
  *
  * @queues: number of available hardware transmit queues for
- *     data packets. WMM/QoS requires at least four.
+ *     data packets. WMM/QoS requires at least four, these
+ *     queues need to have configurable access parameters.
+ *
+ * @ampdu_queues: number of available hardware transmit queues
+ *     for A-MPDU packets, these have no access parameters
+ *     because they're used only for A-MPDU frames. Note that
+ *     mac80211 will not currently use any of the regular queues
+ *     for aggregation.
  *
  * @rate_control_algorithm: rate control algorithm for this hardware.
  *     If unset (NULL), the default algorithm will be used. Must be
@@ -791,7 +774,7 @@ struct ieee80211_hw {
        unsigned int extra_tx_headroom;
        int channel_change_time;
        int vif_data_size;
-       uqueues;
+       u16 queues, ampdu_queues;
        s8 max_rssi;
        s8 max_signal;
        s8 max_noise;
@@ -1069,8 +1052,7 @@ enum ieee80211_ampdu_mlme_action {
  *     of assocaited station or AP.
  *
  * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
- *     bursting) for a hardware TX queue. The @queue parameter uses the
- *     %IEEE80211_TX_QUEUE_* constants. Must be atomic.
+ *     bursting) for a hardware TX queue. Must be atomic.
  *
  * @get_tx_stats: Get statistics of the current TX queue status. This is used
  *     to get number of currently queued packets (queue length), maximum queue
@@ -1150,7 +1132,7 @@ struct ieee80211_ops {
                               u32 short_retry, u32 long_retr);
        void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        enum sta_notify_cmd, const u8 *addr);
-       int (*conf_tx)(struct ieee80211_hw *hw, int queue,
+       int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
                       const struct ieee80211_tx_queue_params *params);
        int (*get_tx_stats)(struct ieee80211_hw *hw,
                            struct ieee80211_tx_queue_stats *stats);
index 1cccbfd781f67e651dd72ff0423a2eaaae616eda..d20d90eead1f95ea90755045a87814fcecb4bb43 100644 (file)
@@ -197,45 +197,6 @@ DEBUGFS_STATS_FILE(rx_handlers_fragments, 20, "%u",
 DEBUGFS_STATS_FILE(tx_status_drop, 20, "%u",
                   local->tx_status_drop);
 
-static ssize_t stats_wme_rx_queue_read(struct file *file,
-                                      char __user *userbuf,
-                                      size_t count, loff_t *ppos)
-{
-       struct ieee80211_local *local = file->private_data;
-       char buf[NUM_RX_DATA_QUEUES*15], *p = buf;
-       int i;
-
-       for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
-               p += scnprintf(p, sizeof(buf)+buf-p,
-                              "%u\n", local->wme_rx_queue[i]);
-
-       return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf);
-}
-
-static const struct file_operations stats_wme_rx_queue_ops = {
-       .read = stats_wme_rx_queue_read,
-       .open = mac80211_open_file_generic,
-};
-
-static ssize_t stats_wme_tx_queue_read(struct file *file,
-                                      char __user *userbuf,
-                                      size_t count, loff_t *ppos)
-{
-       struct ieee80211_local *local = file->private_data;
-       char buf[NUM_TX_DATA_QUEUES*15], *p = buf;
-       int i;
-
-       for (i = 0; i < NUM_TX_DATA_QUEUES; i++)
-               p += scnprintf(p, sizeof(buf)+buf-p,
-                              "%u\n", local->wme_tx_queue[i]);
-
-       return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf);
-}
-
-static const struct file_operations stats_wme_tx_queue_ops = {
-       .read = stats_wme_tx_queue_read,
-       .open = mac80211_open_file_generic,
-};
 #endif
 
 DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount);
@@ -303,8 +264,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
        DEBUGFS_STATS_ADD(rx_expand_skb_head2);
        DEBUGFS_STATS_ADD(rx_handlers_fragments);
        DEBUGFS_STATS_ADD(tx_status_drop);
-       DEBUGFS_STATS_ADD(wme_tx_queue);
-       DEBUGFS_STATS_ADD(wme_rx_queue);
 #endif
        DEBUGFS_STATS_ADD(dot11ACKFailureCount);
        DEBUGFS_STATS_ADD(dot11RTSFailureCount);
@@ -356,8 +315,6 @@ void debugfs_hw_del(struct ieee80211_local *local)
        DEBUGFS_STATS_DEL(rx_expand_skb_head2);
        DEBUGFS_STATS_DEL(rx_handlers_fragments);
        DEBUGFS_STATS_DEL(tx_status_drop);
-       DEBUGFS_STATS_DEL(wme_tx_queue);
-       DEBUGFS_STATS_DEL(wme_rx_queue);
 #endif
        DEBUGFS_STATS_DEL(dot11ACKFailureCount);
        DEBUGFS_STATS_DEL(dot11RTSFailureCount);
index 6d47a1d31b37a550164e424ca9571b67709418db..676a93202ff9c0286706ec1bde3558923c7ef386 100644 (file)
@@ -123,36 +123,6 @@ static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
 }
 STA_OPS(last_seq_ctrl);
 
-#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
-static ssize_t sta_wme_rx_queue_read(struct file *file, char __user *userbuf,
-                                    size_t count, loff_t *ppos)
-{
-       char buf[15*NUM_RX_DATA_QUEUES], *p = buf;
-       int i;
-       struct sta_info *sta = file->private_data;
-       for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
-               p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
-                              sta->wme_rx_queue[i]);
-       p += scnprintf(p, sizeof(buf)+buf-p, "\n");
-       return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
-}
-STA_OPS(wme_rx_queue);
-
-static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf,
-                                    size_t count, loff_t *ppos)
-{
-       char buf[15*NUM_TX_DATA_QUEUES], *p = buf;
-       int i;
-       struct sta_info *sta = file->private_data;
-       for (i = 0; i < NUM_TX_DATA_QUEUES; i++)
-               p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
-                              sta->wme_tx_queue[i]);
-       p += scnprintf(p, sizeof(buf)+buf-p, "\n");
-       return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
-}
-STA_OPS(wme_tx_queue);
-#endif
-
 static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
                                        size_t count, loff_t *ppos)
 {
@@ -293,10 +263,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
        DEBUGFS_ADD(num_ps_buf_frames);
        DEBUGFS_ADD(inactive_ms);
        DEBUGFS_ADD(last_seq_ctrl);
-#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
-       DEBUGFS_ADD(wme_rx_queue);
-       DEBUGFS_ADD(wme_tx_queue);
-#endif
        DEBUGFS_ADD(agg_status);
 }
 
@@ -306,10 +272,6 @@ void ieee80211_sta_debugfs_remove(struct sta_info *sta)
        DEBUGFS_DEL(num_ps_buf_frames);
        DEBUGFS_DEL(inactive_ms);
        DEBUGFS_DEL(last_seq_ctrl);
-#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
-       DEBUGFS_DEL(wme_rx_queue);
-       DEBUGFS_DEL(wme_tx_queue);
-#endif
        DEBUGFS_DEL(agg_status);
 
        debugfs_remove(sta->debugfs.dir);
index cabdc1439d573e6ad46c8e8ece6dd76ce89a634a..d82ed20a344c1c9f89c42301b3407fbfe1ebe93c 100644 (file)
@@ -610,8 +610,8 @@ struct ieee80211_local {
        struct sta_info *sta_hash[STA_HASH_SIZE];
        struct timer_list sta_cleanup;
 
-       unsigned long state[NUM_TX_DATA_QUEUES_AMPDU];
-       struct ieee80211_tx_stored_packet pending_packet[NUM_TX_DATA_QUEUES_AMPDU];
+       unsigned long state[IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_AMPDU_QUEUES];
+       struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_AMPDU_QUEUES];
        struct tasklet_struct tx_pending_tasklet;
 
        /* number of interfaces with corresponding IFF_ flags */
@@ -705,8 +705,6 @@ struct ieee80211_local {
        unsigned int rx_expand_skb_head2;
        unsigned int rx_handlers_fragments;
        unsigned int tx_status_drop;
-       unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES];
-       unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES];
 #define I802_DEBUG_INC(c) (c)++
 #else /* CONFIG_MAC80211_DEBUG_COUNTERS */
 #define I802_DEBUG_INC(c) do { } while (0)
@@ -764,8 +762,6 @@ struct ieee80211_local {
                        struct dentry *rx_expand_skb_head2;
                        struct dentry *rx_handlers_fragments;
                        struct dentry *tx_status_drop;
-                       struct dentry *wme_tx_queue;
-                       struct dentry *wme_rx_queue;
 #endif
                        struct dentry *dot11ACKFailureCount;
                        struct dentry *dot11RTSFailureCount;
index e19be27a3deffeda1dc395cc8a097b101dd1e4d4..55e76117da9e623ca51a970e7cfe9490ae343fad 100644 (file)
@@ -1745,6 +1745,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
                goto fail_wep;
        }
 
+       if (hw->queues > IEEE80211_MAX_QUEUES)
+               hw->queues = IEEE80211_MAX_QUEUES;
+       if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES)
+               hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES;
+
        ieee80211_install_qdisc(local->mdev);
 
        /* add one default STA interface */
index e860d0bacea9bbdee08a5baabe3aab10b47e2004..55b85ae5bc11e85909f185f76229950fc4b861d2 100644 (file)
@@ -257,19 +257,8 @@ static void ieee80211_sta_def_wmm_params(struct net_device *dev,
                qparam.cw_max = 1023;
                qparam.txop = 0;
 
-               for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++)
-                       local->ops->conf_tx(local_to_hw(local),
-                                          i + IEEE80211_TX_QUEUE_DATA0,
-                                          &qparam);
-
-               if (ibss) {
-                       /* IBSS uses different parameters for Beacon sending */
-                       qparam.cw_min++;
-                       qparam.cw_min *= 2;
-                       qparam.cw_min--;
-                       local->ops->conf_tx(local_to_hw(local),
-                                          IEEE80211_TX_QUEUE_BEACON, &qparam);
-               }
+               for (i = 0; i < local_to_hw(local)->queues; i++)
+                       local->ops->conf_tx(local_to_hw(local), i, &qparam);
        }
 }
 
@@ -306,23 +295,23 @@ static void ieee80211_sta_wmm_params(struct net_device *dev,
 
                switch (aci) {
                case 1:
-                       queue = IEEE80211_TX_QUEUE_DATA3;
+                       queue = 3;
                        if (acm)
                                local->wmm_acm |= BIT(0) | BIT(3);
                        break;
                case 2:
-                       queue = IEEE80211_TX_QUEUE_DATA1;
+                       queue = 1;
                        if (acm)
                                local->wmm_acm |= BIT(4) | BIT(5);
                        break;
                case 3:
-                       queue = IEEE80211_TX_QUEUE_DATA0;
+                       queue = 0;
                        if (acm)
                                local->wmm_acm |= BIT(6) | BIT(7);
                        break;
                case 0:
                default:
-                       queue = IEEE80211_TX_QUEUE_DATA2;
+                       queue = 2;
                        if (acm)
                                local->wmm_acm |= BIT(1) | BIT(2);
                        break;
index 02f436a86061a33c99c3c38dc4787b03d27c6c39..e8b89c89e8756be7e4ee59751b983ff429df7be1 100644 (file)
@@ -275,11 +275,6 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
                }
        }
 
-       I802_DEBUG_INC(rx->local->wme_rx_queue[tid]);
-       /* only a debug counter, sta might not be assigned properly yet */
-       if (rx->sta)
-               I802_DEBUG_INC(rx->sta->wme_rx_queue[tid]);
-
        rx->queue = tid;
        /* Set skb->priority to 1d tag if highest order bit of TID is not set.
         * For now, set skb->priority to 0 for other cases. */
index 7d4fe4a52929292a685ef3cfaebfb3a07097754b..631943e8af8ba3d33c7d95939c1dab9daf2a5472 100644 (file)
@@ -257,7 +257,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
                 * sta_rx_agg_session_timer_expired for useage */
                sta->timer_to_tid[i] = i;
                /* tid to tx queue: initialize according to HW (0 is valid) */
-               sta->tid_to_tx_q[i] = local->hw.queues;
+               sta->tid_to_tx_q[i] = local->hw.queues + local->hw.ampdu_queues;
                /* rx */
                sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
                sta->ampdu_mlme.tid_rx[i] = NULL;
index 64faa3dc488f70d2cfb09fae1bb1c3470424153e..5eddf1f32ed99b2c1be49bdae5499215dd2feeee 100644 (file)
 #include "wme.h"
 
 /* maximum number of hardware queues we support. */
-#define TC_80211_MAX_QUEUES 16
+#define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES)
+/* current number of hardware queues we support. */
+#define QD_NUM(hw) ((hw)->queues + (hw)->ampdu_queues)
 
+/*
+ * Default mapping in classifier to work with default
+ * queue setup.
+ */
 const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 };
 
 struct ieee80211_sched_data
 {
-       unsigned long qdisc_pool[BITS_TO_LONGS(TC_80211_MAX_QUEUES)];
+       unsigned long qdisc_pool[BITS_TO_LONGS(QD_MAX_QUEUES)];
        struct tcf_proto *filter_list;
-       struct Qdisc *queues[TC_80211_MAX_QUEUES];
-       struct sk_buff_head requeued[TC_80211_MAX_QUEUES];
+       struct Qdisc *queues[QD_MAX_QUEUES];
+       struct sk_buff_head requeued[QD_MAX_QUEUES];
 };
 
 static const char llc_ip_hdr[8] = {0xAA, 0xAA, 0x3, 0, 0, 0, 0x08, 0};
@@ -95,7 +101,7 @@ static inline int wme_downgrade_ac(struct sk_buff *skb)
 
 /* positive return value indicates which queue to use
  * negative return value indicates to drop the frame */
-static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
+static int classify80211(struct sk_buff *skb, struct Qdisc *qd)
 {
        struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -106,7 +112,7 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
        if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) {
                /* management frames go on AC_VO queue, but are sent
                * without QoS control fields */
-               return IEEE80211_TX_QUEUE_DATA0;
+               return 0;
        }
 
        if (0 /* injected */) {
@@ -141,14 +147,16 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
 static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
 {
        struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
+       struct ieee80211_hw *hw = &local->hw;
        struct ieee80211_sched_data *q = qdisc_priv(qd);
        struct ieee80211_tx_packet_data *pkt_data =
                (struct ieee80211_tx_packet_data *) skb->cb;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        unsigned short fc = le16_to_cpu(hdr->frame_control);
        struct Qdisc *qdisc;
-       int err, queue;
        struct sta_info *sta;
+       int err;
+       u16 queue;
        u8 tid;
 
        if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) {
@@ -158,7 +166,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
                tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
                if (sta) {
                        int ampdu_queue = sta->tid_to_tx_q[tid];
-                       if ((ampdu_queue < local->hw.queues) &&
+                       if ((ampdu_queue < QD_NUM(hw)) &&
                            test_bit(ampdu_queue, q->qdisc_pool)) {
                                queue = ampdu_queue;
                                pkt_data->flags |= IEEE80211_TXPD_AMPDU;
@@ -174,6 +182,9 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
 
        queue = classify80211(skb, qd);
 
+       if (unlikely(queue >= local->hw.queues))
+               queue = local->hw.queues - 1;
+
        /* now we know the 1d priority, fill in the QoS header if there is one
         */
        if (WLAN_FC_IS_QOS_DATA(fc)) {
@@ -193,8 +204,8 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
                sta = sta_info_get(local, hdr->addr1);
                if (sta) {
                        int ampdu_queue = sta->tid_to_tx_q[tid];
-                       if ((ampdu_queue < local->hw.queues) &&
-                               test_bit(ampdu_queue, q->qdisc_pool)) {
+                       if ((ampdu_queue < QD_NUM(hw)) &&
+                           test_bit(ampdu_queue, q->qdisc_pool)) {
                                queue = ampdu_queue;
                                pkt_data->flags |= IEEE80211_TXPD_AMPDU;
                        } else {
@@ -205,17 +216,6 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
                rcu_read_unlock();
        }
 
-       if (unlikely(queue >= local->hw.queues)) {
-#if 0
-               if (net_ratelimit()) {
-                       printk(KERN_DEBUG "%s - queue=%d (hw does not "
-                              "support) -> %d\n",
-                              __func__, queue, local->hw.queues - 1);
-               }
-#endif
-               queue = local->hw.queues - 1;
-       }
-
        if (unlikely(queue < 0)) {
                        kfree_skb(skb);
                        err = NET_XMIT_DROP;
@@ -270,7 +270,7 @@ static struct sk_buff *wme_qdiscop_dequeue(struct Qdisc* qd)
        int queue;
 
        /* check all the h/w queues in numeric/priority order */
-       for (queue = 0; queue < hw->queues; queue++) {
+       for (queue = 0; queue < QD_NUM(hw); queue++) {
                /* see if there is room in this hardware queue */
                if ((test_bit(IEEE80211_LINK_STATE_XOFF,
                                &local->state[queue])) ||
@@ -308,7 +308,7 @@ static void wme_qdiscop_reset(struct Qdisc* qd)
 
        /* QUESTION: should we have some hardware flush functionality here? */
 
-       for (queue = 0; queue < hw->queues; queue++) {
+       for (queue = 0; queue < QD_NUM(hw); queue++) {
                skb_queue_purge(&q->requeued[queue]);
                qdisc_reset(q->queues[queue]);
        }
@@ -326,7 +326,7 @@ static void wme_qdiscop_destroy(struct Qdisc* qd)
        tcf_destroy_chain(q->filter_list);
        q->filter_list = NULL;
 
-       for (queue=0; queue < hw->queues; queue++) {
+       for (queue = 0; queue < QD_NUM(hw); queue++) {
                skb_queue_purge(&q->requeued[queue]);
                qdisc_destroy(q->queues[queue]);
                q->queues[queue] = &noop_qdisc;
@@ -337,17 +337,6 @@ static void wme_qdiscop_destroy(struct Qdisc* qd)
 /* called whenever parameters are updated on existing qdisc */
 static int wme_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt)
 {
-/*     struct ieee80211_sched_data *q = qdisc_priv(qd);
-*/
-       /* check our options block is the right size */
-       /* copy any options to our local structure */
-/*     Ignore options block for now - always use static mapping
-       struct tc_ieee80211_qopt *qopt = nla_data(opt);
-
-       if (opt->nla_len < nla_attr_size(sizeof(*qopt)))
-               return -EINVAL;
-       memcpy(q->tag2queue, qopt->tag2queue, sizeof(qopt->tag2queue));
-*/
        return 0;
 }
 
@@ -358,7 +347,7 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
        struct ieee80211_sched_data *q = qdisc_priv(qd);
        struct net_device *dev = qd->dev;
        struct ieee80211_local *local;
-       int queues;
+       struct ieee80211_hw *hw;
        int err = 0, i;
 
        /* check that device is a mac80211 device */
@@ -366,29 +355,26 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
            dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
                return -EINVAL;
 
-       /* check this device is an ieee80211 master type device */
-       if (dev->type != ARPHRD_IEEE80211)
+       local = wdev_priv(dev->ieee80211_ptr);
+       hw = &local->hw;
+
+       /* only allow on master dev */
+       if (dev != local->mdev)
                return -EINVAL;
 
-       /* check that there is no qdisc currently attached to device
-        * this ensures that we will be the root qdisc. (I can't find a better
-        * way to test this explicitly) */
-       if (dev->qdisc_sleeping != &noop_qdisc)
+       /* ensure that we are root qdisc */
+       if (qd->parent != TC_H_ROOT)
                return -EINVAL;
 
        if (qd->flags & TCQ_F_INGRESS)
                return -EINVAL;
 
-       local = wdev_priv(dev->ieee80211_ptr);
-       queues = local->hw.queues;
-
        /* if options were passed in, set them */
-       if (opt) {
+       if (opt)
                err = wme_qdiscop_tune(qd, opt);
-       }
 
        /* create child queues */
-       for (i = 0; i < queues; i++) {
+       for (i = 0; i < QD_NUM(hw); i++) {
                skb_queue_head_init(&q->requeued[i]);
                q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops,
                                                 qd->handle);
@@ -398,8 +384,8 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
                }
        }
 
-       /* reserve all legacy QoS queues */
-       for (i = 0; i < min(IEEE80211_TX_QUEUE_DATA4, queues); i++)
+       /* non-aggregation queues: reserve/mark as used */
+       for (i = 0; i < local->hw.queues; i++)
                set_bit(i, q->qdisc_pool);
 
        return err;
@@ -407,16 +393,6 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
 
 static int wme_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb)
 {
-/*     struct ieee80211_sched_data *q = qdisc_priv(qd);
-       unsigned char *p = skb->tail;
-       struct tc_ieee80211_qopt opt;
-
-       memcpy(&opt.tag2queue, q->tag2queue, TC_80211_MAX_TAG + 1);
-       NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
-*/     return skb->len;
-/*
-nla_put_failure:
-       skb_trim(skb, p - skb->data);*/
        return -1;
 }
 
@@ -429,7 +405,7 @@ static int wme_classop_graft(struct Qdisc *qd, unsigned long arg,
        struct ieee80211_hw *hw = &local->hw;
        unsigned long queue = arg - 1;
 
-       if (queue >= hw->queues)
+       if (queue >= QD_NUM(hw))
                return -EINVAL;
 
        if (!new)
@@ -453,7 +429,7 @@ wme_classop_leaf(struct Qdisc *qd, unsigned long arg)
        struct ieee80211_hw *hw = &local->hw;
        unsigned long queue = arg - 1;
 
-       if (queue >= hw->queues)
+       if (queue >= QD_NUM(hw))
                return NULL;
 
        return q->queues[queue];
@@ -466,7 +442,7 @@ static unsigned long wme_classop_get(struct Qdisc *qd, u32 classid)
        struct ieee80211_hw *hw = &local->hw;
        unsigned long queue = TC_H_MIN(classid);
 
-       if (queue - 1 >= hw->queues)
+       if (queue - 1 >= QD_NUM(hw))
                return 0;
 
        return queue;
@@ -492,7 +468,7 @@ static int wme_classop_change(struct Qdisc *qd, u32 handle, u32 parent,
        struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
        struct ieee80211_hw *hw = &local->hw;
 
-       if (cl - 1 > hw->queues)
+       if (cl - 1 > QD_NUM(hw))
                return -ENOENT;
 
        /* TODO: put code to program hardware queue parameters here,
@@ -509,7 +485,7 @@ static int wme_classop_delete(struct Qdisc *qd, unsigned long cl)
        struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
        struct ieee80211_hw *hw = &local->hw;
 
-       if (cl - 1 > hw->queues)
+       if (cl - 1 > QD_NUM(hw))
                return -ENOENT;
        return 0;
 }
@@ -522,7 +498,7 @@ static int wme_classop_dump_class(struct Qdisc *qd, unsigned long cl,
        struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
        struct ieee80211_hw *hw = &local->hw;
 
-       if (cl - 1 > hw->queues)
+       if (cl - 1 > QD_NUM(hw))
                return -ENOENT;
        tcm->tcm_handle = TC_H_MIN(cl);
        tcm->tcm_parent = qd->handle;
@@ -540,7 +516,7 @@ static void wme_classop_walk(struct Qdisc *qd, struct qdisc_walker *arg)
        if (arg->stop)
                return;
 
-       for (queue = 0; queue < hw->queues; queue++) {
+       for (queue = 0; queue < QD_NUM(hw); queue++) {
                if (arg->count < arg->skip) {
                        arg->count++;
                        continue;
@@ -657,10 +633,13 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local,
        DECLARE_MAC_BUF(mac);
 
        /* prepare the filter and save it for the SW queue
-        * matching the recieved HW queue */
+        * matching the received HW queue */
+
+       if (!local->hw.ampdu_queues)
+               return -EPERM;
 
        /* try to get a Qdisc from the pool */
-       for (i = IEEE80211_TX_QUEUE_BEACON; i < local->hw.queues; i++)
+       for (i = local->hw.queues; i < QD_NUM(&local->hw); i++)
                if (!test_and_set_bit(i, q->qdisc_pool)) {
                        ieee80211_stop_queue(local_to_hw(local), i);
                        sta->tid_to_tx_q[tid] = i;
@@ -689,13 +668,14 @@ void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local,
                                   struct sta_info *sta, u16 tid,
                                   u8 requeue)
 {
+       struct ieee80211_hw *hw = &local->hw;
        struct ieee80211_sched_data *q =
                qdisc_priv(local->mdev->qdisc_sleeping);
        int agg_queue = sta->tid_to_tx_q[tid];
 
        /* return the qdisc to the pool */
        clear_bit(agg_queue, q->qdisc_pool);
-       sta->tid_to_tx_q[tid] = local->hw.queues;
+       sta->tid_to_tx_q[tid] = QD_NUM(hw);
 
        if (requeue)
                ieee80211_requeue(local, agg_queue);