aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-16 18:57:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:48:14 -0400
commite2530083609148a7835b54c431f6b8956407c1f6 (patch)
tree8ed43347541444c7a72d2c79f550f69a93cad591
parenteefce91a384a64c7bbf913eb08c4adfb911c3639 (diff)
mac80211: use multi-queue master netdevice
This patch updates mac80211 and drivers to be multi-queue aware and use that instead of the internal queue mapping. Also does a number of cleanups in various pieces of the code that fall out and reduces internal mac80211 state size. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath5k/base.c2
-rw-r--r--drivers/net/wireless/b43/dma.c7
-rw-r--r--drivers/net/wireless/b43/pio.c8
-rw-r--r--drivers/net/wireless/b43legacy/dma.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c4
-rw-r--r--drivers/net/wireless/p54/p54common.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h13
-rw-r--r--drivers/net/wireless/rtl8180_dev.c4
-rw-r--r--include/net/mac80211.h20
-rw-r--r--net/mac80211/Kconfig14
-rw-r--r--net/mac80211/Makefile2
-rw-r--r--net/mac80211/ieee80211_i.h16
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/main.c29
-rw-r--r--net/mac80211/sta_info.c2
-rw-r--r--net/mac80211/tx.c97
-rw-r--r--net/mac80211/util.c29
-rw-r--r--net/mac80211/wme.c14
-rw-r--r--net/mac80211/wme.h2
21 files changed, 158 insertions, 132 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 7d97934265db..18e9422d26dd 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -2657,7 +2657,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2657 if (list_empty(&sc->txbuf)) { 2657 if (list_empty(&sc->txbuf)) {
2658 ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); 2658 ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
2659 spin_unlock_irqrestore(&sc->txbuflock, flags); 2659 spin_unlock_irqrestore(&sc->txbuflock, flags);
2660 ieee80211_stop_queue(hw, info->queue); 2660 ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
2661 return -1; 2661 return -1;
2662 } 2662 }
2663 bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); 2663 bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index aced9866d815..b4eadd908bea 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1297,7 +1297,8 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1297 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1297 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1298 } else { 1298 } else {
1299 /* Decide by priority where to put this frame. */ 1299 /* Decide by priority where to put this frame. */
1300 ring = select_ring_by_priority(dev, info->queue); 1300 ring = select_ring_by_priority(
1301 dev, skb_get_queue_mapping(skb));
1301 } 1302 }
1302 1303
1303 spin_lock_irqsave(&ring->lock, flags); 1304 spin_lock_irqsave(&ring->lock, flags);
@@ -1315,7 +1316,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1315 /* Assign the queue number to the ring (if not already done before) 1316 /* Assign the queue number to the ring (if not already done before)
1316 * so TX status handling can use it. The queue to ring mapping is 1317 * so TX status handling can use it. The queue to ring mapping is
1317 * static, so we don't need to store it per frame. */ 1318 * static, so we don't need to store it per frame. */
1318 ring->queue_prio = info->queue; 1319 ring->queue_prio = skb_get_queue_mapping(skb);
1319 1320
1320 err = dma_tx_fragment(ring, skb); 1321 err = dma_tx_fragment(ring, skb);
1321 if (unlikely(err == -ENOKEY)) { 1322 if (unlikely(err == -ENOKEY)) {
@@ -1333,7 +1334,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1333 if ((free_slots(ring) < SLOTS_PER_PACKET) || 1334 if ((free_slots(ring) < SLOTS_PER_PACKET) ||
1334 should_inject_overflow(ring)) { 1335 should_inject_overflow(ring)) {
1335 /* This TX ring is full. */ 1336 /* This TX ring is full. */
1336 ieee80211_stop_queue(dev->wl->hw, info->queue); 1337 ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
1337 ring->stopped = 1; 1338 ring->stopped = 1;
1338 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { 1339 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
1339 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); 1340 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 284786a94e7d..8b1555d95f1c 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -509,7 +509,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
509 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); 509 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
510 } else { 510 } else {
511 /* Decide by priority where to put this frame. */ 511 /* Decide by priority where to put this frame. */
512 q = select_queue_by_priority(dev, info->queue); 512 q = select_queue_by_priority(dev, skb_get_queue_mapping(skb));
513 } 513 }
514 514
515 spin_lock_irqsave(&q->lock, flags); 515 spin_lock_irqsave(&q->lock, flags);
@@ -532,7 +532,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
532 if (total_len > (q->buffer_size - q->buffer_used)) { 532 if (total_len > (q->buffer_size - q->buffer_used)) {
533 /* Not enough memory on the queue. */ 533 /* Not enough memory on the queue. */
534 err = -EBUSY; 534 err = -EBUSY;
535 ieee80211_stop_queue(dev->wl->hw, info->queue); 535 ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
536 q->stopped = 1; 536 q->stopped = 1;
537 goto out_unlock; 537 goto out_unlock;
538 } 538 }
@@ -540,7 +540,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
540 /* Assign the queue number to the ring (if not already done before) 540 /* Assign the queue number to the ring (if not already done before)
541 * so TX status handling can use it. The mac80211-queue to b43-queue 541 * so TX status handling can use it. The mac80211-queue to b43-queue
542 * mapping is static, so we don't need to store it per frame. */ 542 * mapping is static, so we don't need to store it per frame. */
543 q->queue_prio = info->queue; 543 q->queue_prio = skb_get_queue_mapping(skb);
544 544
545 err = pio_tx_frame(q, skb); 545 err = pio_tx_frame(q, skb);
546 if (unlikely(err == -ENOKEY)) { 546 if (unlikely(err == -ENOKEY)) {
@@ -560,7 +560,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
560 if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) || 560 if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) ||
561 (q->free_packet_slots == 0)) { 561 (q->free_packet_slots == 0)) {
562 /* The queue is full. */ 562 /* The queue is full. */
563 ieee80211_stop_queue(dev->wl->hw, info->queue); 563 ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
564 q->stopped = 1; 564 q->stopped = 1;
565 } 565 }
566 566
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index c1c501d963bc..33cc256c5baf 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -1325,11 +1325,10 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1325 struct sk_buff *skb) 1325 struct sk_buff *skb)
1326{ 1326{
1327 struct b43legacy_dmaring *ring; 1327 struct b43legacy_dmaring *ring;
1328 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1329 int err = 0; 1328 int err = 0;
1330 unsigned long flags; 1329 unsigned long flags;
1331 1330
1332 ring = priority_to_txring(dev, info->queue); 1331 ring = priority_to_txring(dev, skb_get_queue_mapping(skb));
1333 spin_lock_irqsave(&ring->lock, flags); 1332 spin_lock_irqsave(&ring->lock, flags);
1334 B43legacy_WARN_ON(!ring->tx); 1333 B43legacy_WARN_ON(!ring->tx);
1335 if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) { 1334 if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index a61293ba3f6b..0ebab967d5e7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -696,7 +696,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
696 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 696 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
697 struct iwl_tfd_frame *tfd; 697 struct iwl_tfd_frame *tfd;
698 u32 *control_flags; 698 u32 *control_flags;
699 int txq_id = info->queue; 699 int txq_id = skb_get_queue_mapping(skb);
700 struct iwl_tx_queue *txq = NULL; 700 struct iwl_tx_queue *txq = NULL;
701 struct iwl_queue *q = NULL; 701 struct iwl_queue *q = NULL;
702 dma_addr_t phys_addr; 702 dma_addr_t phys_addr;
@@ -917,7 +917,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
917 spin_unlock_irqrestore(&priv->lock, flags); 917 spin_unlock_irqrestore(&priv->lock, flags);
918 } 918 }
919 919
920 ieee80211_stop_queue(priv->hw, info->queue); 920 ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb));
921 } 921 }
922 922
923 return 0; 923 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index a740a1817d16..e0f52e264418 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2552,7 +2552,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
2552 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2552 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2553 struct iwl3945_tfd_frame *tfd; 2553 struct iwl3945_tfd_frame *tfd;
2554 u32 *control_flags; 2554 u32 *control_flags;
2555 int txq_id = info->queue; 2555 int txq_id = skb_get_queue_mapping(skb);
2556 struct iwl3945_tx_queue *txq = NULL; 2556 struct iwl3945_tx_queue *txq = NULL;
2557 struct iwl3945_queue *q = NULL; 2557 struct iwl3945_queue *q = NULL;
2558 dma_addr_t phys_addr; 2558 dma_addr_t phys_addr;
@@ -2765,7 +2765,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
2765 spin_unlock_irqrestore(&priv->lock, flags); 2765 spin_unlock_irqrestore(&priv->lock, flags);
2766 } 2766 }
2767 2767
2768 ieee80211_stop_queue(priv->hw, info->queue); 2768 ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb));
2769 } 2769 }
2770 2770
2771 return 0; 2771 return 0;
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 850857932e29..91ac9208b77d 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -407,7 +407,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
407 last_addr = range->end_addr; 407 last_addr = range->end_addr;
408 __skb_unlink(entry, &priv->tx_queue); 408 __skb_unlink(entry, &priv->tx_queue);
409 memset(&info->status, 0, sizeof(info->status)); 409 memset(&info->status, 0, sizeof(info->status));
410 priv->tx_stats[info->queue].len--; 410 priv->tx_stats[skb_get_queue_mapping(skb)].len--;
411 entry_hdr = (struct p54_control_hdr *) entry->data; 411 entry_hdr = (struct p54_control_hdr *) entry->data;
412 entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data; 412 entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
413 if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0) 413 if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
@@ -551,13 +551,13 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
551 size_t padding, len; 551 size_t padding, len;
552 u8 rate; 552 u8 rate;
553 553
554 current_queue = &priv->tx_stats[info->queue]; 554 current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)];
555 if (unlikely(current_queue->len > current_queue->limit)) 555 if (unlikely(current_queue->len > current_queue->limit))
556 return NETDEV_TX_BUSY; 556 return NETDEV_TX_BUSY;
557 current_queue->len++; 557 current_queue->len++;
558 current_queue->count++; 558 current_queue->count++;
559 if (current_queue->len == current_queue->limit) 559 if (current_queue->len == current_queue->limit)
560 ieee80211_stop_queue(dev, info->queue); 560 ieee80211_stop_queue(dev, skb_get_queue_mapping(skb));
561 561
562 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3; 562 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
563 len = skb->len; 563 len = skb->len;
@@ -589,7 +589,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
589 memset(txhdr->rateset, rate, 8); 589 memset(txhdr->rateset, rate, 8);
590 txhdr->wep_key_present = 0; 590 txhdr->wep_key_present = 0;
591 txhdr->wep_key_len = 0; 591 txhdr->wep_key_len = 0;
592 txhdr->frame_type = cpu_to_le32(info->queue + 4); 592 txhdr->frame_type = cpu_to_le32(skb_get_queue_mapping(skb) + 4);
593 txhdr->magic4 = 0; 593 txhdr->magic4 = 0;
594 txhdr->antenna = (info->antenna_sel_tx == 0) ? 594 txhdr->antenna = (info->antenna_sel_tx == 0) ?
595 2 : info->antenna_sel_tx - 1; 595 2 : info->antenna_sel_tx - 1;
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index b5379b027b18..c05e05b58887 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -102,7 +102,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
102 struct rt2x00_dev *rt2x00dev = hw->priv; 102 struct rt2x00_dev *rt2x00dev = hw->priv;
103 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 103 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
104 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; 104 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
105 enum data_queue_qid qid = mac80211_queue_to_qid(tx_info->queue); 105 enum data_queue_qid qid = skb_get_queue_mapping(skb);
106 struct data_queue *queue; 106 struct data_queue *queue;
107 u16 frame_control; 107 u16 frame_control;
108 108
@@ -149,23 +149,23 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
149 IEEE80211_TX_CTL_USE_CTS_PROTECT)) && 149 IEEE80211_TX_CTL_USE_CTS_PROTECT)) &&
150 !rt2x00dev->ops->hw->set_rts_threshold) { 150 !rt2x00dev->ops->hw->set_rts_threshold) {
151 if (rt2x00queue_available(queue) <= 1) { 151 if (rt2x00queue_available(queue) <= 1) {
152 ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue); 152 ieee80211_stop_queue(rt2x00dev->hw, qid);
153 return NETDEV_TX_BUSY; 153 return NETDEV_TX_BUSY;
154 } 154 }
155 155
156 if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb)) { 156 if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb)) {
157 ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue); 157 ieee80211_stop_queue(rt2x00dev->hw, qid);
158 return NETDEV_TX_BUSY; 158 return NETDEV_TX_BUSY;
159 } 159 }
160 } 160 }
161 161
162 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) { 162 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {
163 ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue); 163 ieee80211_stop_queue(rt2x00dev->hw, qid);
164 return NETDEV_TX_BUSY; 164 return NETDEV_TX_BUSY;
165 } 165 }
166 166
167 if (rt2x00queue_full(queue)) 167 if (rt2x00queue_full(queue))
168 ieee80211_stop_queue(rt2x00dev->hw, tx_info->queue); 168 ieee80211_stop_queue(rt2x00dev->hw, qid);
169 169
170 if (rt2x00dev->ops->lib->kick_tx_queue) 170 if (rt2x00dev->ops->lib->kick_tx_queue)
171 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid); 171 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index f263fe422f87..4d00ced14cc7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -80,19 +80,6 @@ enum data_queue_qid {
80}; 80};
81 81
82/** 82/**
83 * mac80211_queue_to_qid - Convert mac80211 queue to rt2x00 qid
84 * @queue: mac80211 queue.
85 */
86static inline enum data_queue_qid mac80211_queue_to_qid(unsigned int queue)
87{
88 /* Regular TX queues are mapped directly */
89 if (queue < 4)
90 return queue;
91 WARN_ON(1);
92 return QID_OTHER;
93}
94
95/**
96 * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc 83 * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc
97 * 84 *
98 * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver 85 * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 4427bc9f78a9..b7172a12c057 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -246,7 +246,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
246 u16 plcp_len = 0; 246 u16 plcp_len = 0;
247 __le16 rts_duration = 0; 247 __le16 rts_duration = 0;
248 248
249 prio = info->queue; 249 prio = skb_get_queue_mapping(skb);
250 ring = &priv->tx_ring[prio]; 250 ring = &priv->tx_ring[prio];
251 251
252 mapping = pci_map_single(priv->pdev, skb->data, 252 mapping = pci_map_single(priv->pdev, skb->data,
@@ -298,7 +298,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
298 entry->flags = cpu_to_le32(tx_flags); 298 entry->flags = cpu_to_le32(tx_flags);
299 __skb_queue_tail(&ring->queue, skb); 299 __skb_queue_tail(&ring->queue, skb);
300 if (ring->entries - skb_queue_len(&ring->queue) < 2) 300 if (ring->entries - skb_queue_len(&ring->queue) < 2)
301 ieee80211_stop_queue(dev, info->queue); 301 ieee80211_stop_queue(dev, skb_get_queue_mapping(skb));
302 spin_unlock_irqrestore(&priv->lock, flags); 302 spin_unlock_irqrestore(&priv->lock, flags);
303 303
304 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); 304 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 4df39eb9115f..c80e3be8f79e 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -293,7 +293,7 @@ struct ieee80211_tx_info {
293 s8 tx_rate_idx; 293 s8 tx_rate_idx;
294 u8 antenna_sel_tx; 294 u8 antenna_sel_tx;
295 295
296 u8 queue; /* use skb_queue_mapping soon */ 296 /* 1 byte hole */
297 297
298 union { 298 union {
299 struct { 299 struct {
@@ -802,6 +802,24 @@ static inline void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, u8 *addr)
802 memcpy(hw->wiphy->perm_addr, addr, ETH_ALEN); 802 memcpy(hw->wiphy->perm_addr, addr, ETH_ALEN);
803} 803}
804 804
805static inline int ieee80211_num_regular_queues(struct ieee80211_hw *hw)
806{
807#ifdef CONFIG_MAC80211_QOS
808 return hw->queues;
809#else
810 return 1;
811#endif
812}
813
814static inline int ieee80211_num_queues(struct ieee80211_hw *hw)
815{
816#ifdef CONFIG_MAC80211_QOS
817 return hw->queues + hw->ampdu_queues;
818#else
819 return 1;
820#endif
821}
822
805static inline struct ieee80211_rate * 823static inline struct ieee80211_rate *
806ieee80211_get_tx_rate(const struct ieee80211_hw *hw, 824ieee80211_get_tx_rate(const struct ieee80211_hw *hw,
807 const struct ieee80211_tx_info *c) 825 const struct ieee80211_tx_info *c)
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index a24b459dd45a..590e00b2766c 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -7,11 +7,23 @@ config MAC80211
7 select CRC32 7 select CRC32
8 select WIRELESS_EXT 8 select WIRELESS_EXT
9 select CFG80211 9 select CFG80211
10 select NET_SCH_FIFO
11 ---help--- 10 ---help---
12 This option enables the hardware independent IEEE 802.11 11 This option enables the hardware independent IEEE 802.11
13 networking stack. 12 networking stack.
14 13
14config MAC80211_QOS
15 def_bool y
16 depends on MAC80211
17 depends on NET_SCHED
18 depends on NETDEVICES_MULTIQUEUE
19
20comment "QoS/HT support disabled"
21 depends on MAC80211 && !MAC80211_QOS
22comment "QoS/HT support needs CONFIG_NET_SCHED"
23 depends on MAC80211 && !NET_SCHED
24comment "QoS/HT support needs CONFIG_NETDEVICES_MULTIQUEUE"
25 depends on MAC80211 && !NETDEVICES_MULTIQUEUE
26
15menu "Rate control algorithm selection" 27menu "Rate control algorithm selection"
16 depends on MAC80211 != n 28 depends on MAC80211 != n
17 29
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 4e5847fd316c..1d2a4e010e5c 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -29,7 +29,7 @@ mac80211-y := \
29 event.o 29 event.o
30 30
31mac80211-$(CONFIG_MAC80211_LEDS) += led.o 31mac80211-$(CONFIG_MAC80211_LEDS) += led.o
32mac80211-$(CONFIG_NET_SCHED) += wme.o 32mac80211-$(CONFIG_MAC80211_QOS) += wme.o
33mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ 33mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
34 debugfs.o \ 34 debugfs.o \
35 debugfs_sta.o \ 35 debugfs_sta.o \
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 86a861251e8c..7d614cdcefcb 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -594,7 +594,7 @@ struct ieee80211_local {
594 struct sta_info *sta_hash[STA_HASH_SIZE]; 594 struct sta_info *sta_hash[STA_HASH_SIZE];
595 struct timer_list sta_cleanup; 595 struct timer_list sta_cleanup;
596 596
597 unsigned long state[IEEE80211_MAX_QUEUES + IEEE80211_MAX_AMPDU_QUEUES]; 597 unsigned long queues_pending[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)];
598 struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES]; 598 struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES];
599 struct tasklet_struct tx_pending_tasklet; 599 struct tasklet_struct tx_pending_tasklet;
600 600
@@ -758,6 +758,15 @@ struct ieee80211_local {
758#endif 758#endif
759}; 759};
760 760
761static inline int ieee80211_is_multiqueue(struct ieee80211_local *local)
762{
763#ifdef CONFIG_MAC80211_QOS
764 return netif_is_multiqueue(local->mdev);
765#else
766 return 0;
767#endif
768}
769
761/* this struct represents 802.11n's RA/TID combination */ 770/* this struct represents 802.11n's RA/TID combination */
762struct ieee80211_ra_tid { 771struct ieee80211_ra_tid {
763 u8 ra[ETH_ALEN]; 772 u8 ra[ETH_ALEN];
@@ -827,11 +836,6 @@ static inline struct ieee80211_hw *local_to_hw(
827 return &local->hw; 836 return &local->hw;
828} 837}
829 838
830enum ieee80211_link_state_t {
831 IEEE80211_LINK_STATE_XOFF = 0,
832 IEEE80211_LINK_STATE_PENDING,
833};
834
835struct sta_attribute { 839struct sta_attribute {
836 struct attribute attr; 840 struct attribute attr;
837 ssize_t (*show)(const struct sta_info *, char *buf); 841 ssize_t (*show)(const struct sta_info *, char *buf);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 3c64e42eb12e..984472702381 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -168,7 +168,7 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
168 ifsta->flags |= IEEE80211_STA_CREATE_IBSS | 168 ifsta->flags |= IEEE80211_STA_CREATE_IBSS |
169 IEEE80211_STA_AUTO_BSSID_SEL | 169 IEEE80211_STA_AUTO_BSSID_SEL |
170 IEEE80211_STA_AUTO_CHANNEL_SEL; 170 IEEE80211_STA_AUTO_CHANNEL_SEL;
171 if (sdata->local->hw.queues >= 4) 171 if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4)
172 ifsta->flags |= IEEE80211_STA_WMM_ENABLED; 172 ifsta->flags |= IEEE80211_STA_WMM_ENABLED;
173 173
174 msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); 174 msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 8f1ff7ef1667..97d4a537ca2f 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1634,12 +1634,32 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1634 if (result < 0) 1634 if (result < 0)
1635 return result; 1635 return result;
1636 1636
1637 /*
1638 * We use the number of queues for feature tests (QoS, HT) internally
1639 * so restrict them appropriately.
1640 */
1641#ifdef CONFIG_MAC80211_QOS
1642 if (hw->queues > IEEE80211_MAX_QUEUES)
1643 hw->queues = IEEE80211_MAX_QUEUES;
1644 if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES)
1645 hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES;
1646 if (hw->queues < 4)
1647 hw->ampdu_queues = 0;
1648#else
1649 hw->queues = 1;
1650 hw->ampdu_queues = 0;
1651#endif
1652
1637 /* for now, mdev needs sub_if_data :/ */ 1653 /* for now, mdev needs sub_if_data :/ */
1638 mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), 1654 mdev = alloc_netdev_mq(sizeof(struct ieee80211_sub_if_data),
1639 "wmaster%d", ether_setup); 1655 "wmaster%d", ether_setup,
1656 ieee80211_num_queues(hw));
1640 if (!mdev) 1657 if (!mdev)
1641 goto fail_mdev_alloc; 1658 goto fail_mdev_alloc;
1642 1659
1660 if (ieee80211_num_queues(hw) > 1)
1661 mdev->features |= NETIF_F_MULTI_QUEUE;
1662
1643 sdata = IEEE80211_DEV_TO_SUB_IF(mdev); 1663 sdata = IEEE80211_DEV_TO_SUB_IF(mdev);
1644 mdev->ieee80211_ptr = &sdata->wdev; 1664 mdev->ieee80211_ptr = &sdata->wdev;
1645 sdata->wdev.wiphy = local->hw.wiphy; 1665 sdata->wdev.wiphy = local->hw.wiphy;
@@ -1728,11 +1748,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1728 goto fail_wep; 1748 goto fail_wep;
1729 } 1749 }
1730 1750
1731 if (hw->queues > IEEE80211_MAX_QUEUES)
1732 hw->queues = IEEE80211_MAX_QUEUES;
1733 if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES)
1734 hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES;
1735
1736 ieee80211_install_qdisc(local->mdev); 1751 ieee80211_install_qdisc(local->mdev);
1737 1752
1738 /* add one default STA interface */ 1753 /* add one default STA interface */
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index ef3149324d54..c24770cb02c5 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -255,7 +255,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
255 * sta_rx_agg_session_timer_expired for useage */ 255 * sta_rx_agg_session_timer_expired for useage */
256 sta->timer_to_tid[i] = i; 256 sta->timer_to_tid[i] = i;
257 /* tid to tx queue: initialize according to HW (0 is valid) */ 257 /* tid to tx queue: initialize according to HW (0 is valid) */
258 sta->tid_to_tx_q[i] = local->hw.queues + local->hw.ampdu_queues; 258 sta->tid_to_tx_q[i] = ieee80211_num_queues(&local->hw);
259 /* rx */ 259 /* rx */
260 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; 260 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
261 sta->ampdu_mlme.tid_rx[i] = NULL; 261 sta->ampdu_mlme.tid_rx[i] = NULL;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 6268bbca148e..9273651d3d7c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -213,18 +213,6 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
213 return dur; 213 return dur;
214} 214}
215 215
216static inline int __ieee80211_queue_stopped(const struct ieee80211_local *local,
217 int queue)
218{
219 return test_bit(IEEE80211_LINK_STATE_XOFF, &local->state[queue]);
220}
221
222static inline int __ieee80211_queue_pending(const struct ieee80211_local *local,
223 int queue)
224{
225 return test_bit(IEEE80211_LINK_STATE_PENDING, &local->state[queue]);
226}
227
228static int inline is_ieee80211_device(struct net_device *dev, 216static int inline is_ieee80211_device(struct net_device *dev,
229 struct net_device *master) 217 struct net_device *master)
230{ 218{
@@ -680,7 +668,8 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
680 * etc. 668 * etc.
681 */ 669 */
682 if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU || 670 if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU ||
683 IEEE80211_SKB_CB(tx->skb)->queue >= tx->local->hw.queues)) 671 skb_get_queue_mapping(tx->skb) >=
672 ieee80211_num_regular_queues(&tx->local->hw)))
684 return TX_DROP; 673 return TX_DROP;
685 674
686 first = tx->skb; 675 first = tx->skb;
@@ -1098,11 +1087,9 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1098 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1087 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1099 int ret, i; 1088 int ret, i;
1100 1089
1101 if (!ieee80211_qdisc_installed(local->mdev) && 1090 if (netif_subqueue_stopped(local->mdev, skb))
1102 __ieee80211_queue_stopped(local, 0)) {
1103 netif_stop_queue(local->mdev);
1104 return IEEE80211_TX_AGAIN; 1091 return IEEE80211_TX_AGAIN;
1105 } 1092
1106 if (skb) { 1093 if (skb) {
1107 ieee80211_dump_frame(wiphy_name(local->hw.wiphy), 1094 ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
1108 "TX to low-level driver", skb); 1095 "TX to low-level driver", skb);
@@ -1121,7 +1108,8 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1121 IEEE80211_TX_CTL_USE_CTS_PROTECT | 1108 IEEE80211_TX_CTL_USE_CTS_PROTECT |
1122 IEEE80211_TX_CTL_CLEAR_PS_FILT | 1109 IEEE80211_TX_CTL_CLEAR_PS_FILT |
1123 IEEE80211_TX_CTL_FIRST_FRAGMENT); 1110 IEEE80211_TX_CTL_FIRST_FRAGMENT);
1124 if (__ieee80211_queue_stopped(local, info->queue)) 1111 if (netif_subqueue_stopped(local->mdev,
1112 tx->extra_frag[i]))
1125 return IEEE80211_TX_FRAG_AGAIN; 1113 return IEEE80211_TX_FRAG_AGAIN;
1126 if (i == tx->num_extra_frag) { 1114 if (i == tx->num_extra_frag) {
1127 info->tx_rate_idx = tx->last_frag_rate_idx; 1115 info->tx_rate_idx = tx->last_frag_rate_idx;
@@ -1160,9 +1148,11 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb)
1160 ieee80211_tx_result res = TX_DROP, res_prepare; 1148 ieee80211_tx_result res = TX_DROP, res_prepare;
1161 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1149 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1162 int ret, i; 1150 int ret, i;
1163 int queue = info->queue; 1151 u16 queue;
1164 1152
1165 WARN_ON(__ieee80211_queue_pending(local, queue)); 1153 queue = skb_get_queue_mapping(skb);
1154
1155 WARN_ON(test_bit(queue, local->queues_pending));
1166 1156
1167 if (unlikely(skb->len < 10)) { 1157 if (unlikely(skb->len < 10)) {
1168 dev_kfree_skb(skb); 1158 dev_kfree_skb(skb);
@@ -1233,28 +1223,28 @@ retry:
1233 * queues, there's no reason for a driver to reject 1223 * queues, there's no reason for a driver to reject
1234 * a frame there, warn and drop it. 1224 * a frame there, warn and drop it.
1235 */ 1225 */
1236 if (WARN_ON(queue >= local->hw.queues)) 1226 if (WARN_ON(queue >= ieee80211_num_regular_queues(&local->hw)))
1237 goto drop; 1227 goto drop;
1238 1228
1239 store = &local->pending_packet[queue]; 1229 store = &local->pending_packet[queue];
1240 1230
1241 if (ret == IEEE80211_TX_FRAG_AGAIN) 1231 if (ret == IEEE80211_TX_FRAG_AGAIN)
1242 skb = NULL; 1232 skb = NULL;
1243 set_bit(IEEE80211_LINK_STATE_PENDING, 1233 set_bit(queue, local->queues_pending);
1244 &local->state[queue]);
1245 smp_mb(); 1234 smp_mb();
1246 /* When the driver gets out of buffers during sending of 1235 /*
1247 * fragments and calls ieee80211_stop_queue, there is 1236 * When the driver gets out of buffers during sending of
1248 * a small window between IEEE80211_LINK_STATE_XOFF and 1237 * fragments and calls ieee80211_stop_queue, the netif
1249 * IEEE80211_LINK_STATE_PENDING flags are set. If a buffer 1238 * subqueue is stopped. There is, however, a small window
1239 * in which the PENDING bit is not yet set. If a buffer
1250 * gets available in that window (i.e. driver calls 1240 * gets available in that window (i.e. driver calls
1251 * ieee80211_wake_queue), we would end up with ieee80211_tx 1241 * ieee80211_wake_queue), we would end up with ieee80211_tx
1252 * called with IEEE80211_LINK_STATE_PENDING. Prevent this by 1242 * called with the PENDING bit still set. Prevent this by
1253 * continuing transmitting here when that situation is 1243 * continuing transmitting here when that situation is
1254 * possible to have happened. */ 1244 * possible to have happened.
1255 if (!__ieee80211_queue_stopped(local, queue)) { 1245 */
1256 clear_bit(IEEE80211_LINK_STATE_PENDING, 1246 if (!__netif_subqueue_stopped(local->mdev, queue)) {
1257 &local->state[queue]); 1247 clear_bit(queue, local->queues_pending);
1258 goto retry; 1248 goto retry;
1259 } 1249 }
1260 store->skb = skb; 1250 store->skb = skb;
@@ -1509,7 +1499,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1509 } 1499 }
1510 1500
1511 /* receiver and we are QoS enabled, use a QoS type frame */ 1501 /* receiver and we are QoS enabled, use a QoS type frame */
1512 if (sta_flags & WLAN_STA_WME && local->hw.queues >= 4) { 1502 if (sta_flags & WLAN_STA_WME &&
1503 ieee80211_num_regular_queues(&local->hw) >= 4) {
1513 fc |= IEEE80211_STYPE_QOS_DATA; 1504 fc |= IEEE80211_STYPE_QOS_DATA;
1514 hdrlen += 2; 1505 hdrlen += 2;
1515 } 1506 }
@@ -1661,41 +1652,51 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1661 return ret; 1652 return ret;
1662} 1653}
1663 1654
1664/* helper functions for pending packets for when queues are stopped */
1665 1655
1656/*
1657 * ieee80211_clear_tx_pending may not be called in a context where
1658 * it is possible that it packets could come in again.
1659 */
1666void ieee80211_clear_tx_pending(struct ieee80211_local *local) 1660void ieee80211_clear_tx_pending(struct ieee80211_local *local)
1667{ 1661{
1668 int i, j; 1662 int i, j;
1669 struct ieee80211_tx_stored_packet *store; 1663 struct ieee80211_tx_stored_packet *store;
1670 1664
1671 for (i = 0; i < local->hw.queues; i++) { 1665 for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) {
1672 if (!__ieee80211_queue_pending(local, i)) 1666 if (!test_bit(i, local->queues_pending))
1673 continue; 1667 continue;
1674 store = &local->pending_packet[i]; 1668 store = &local->pending_packet[i];
1675 kfree_skb(store->skb); 1669 kfree_skb(store->skb);
1676 for (j = 0; j < store->num_extra_frag; j++) 1670 for (j = 0; j < store->num_extra_frag; j++)
1677 kfree_skb(store->extra_frag[j]); 1671 kfree_skb(store->extra_frag[j]);
1678 kfree(store->extra_frag); 1672 kfree(store->extra_frag);
1679 clear_bit(IEEE80211_LINK_STATE_PENDING, &local->state[i]); 1673 clear_bit(i, local->queues_pending);
1680 } 1674 }
1681} 1675}
1682 1676
1677/*
1678 * Transmit all pending packets. Called from tasklet, locks master device
1679 * TX lock so that no new packets can come in.
1680 */
1683void ieee80211_tx_pending(unsigned long data) 1681void ieee80211_tx_pending(unsigned long data)
1684{ 1682{
1685 struct ieee80211_local *local = (struct ieee80211_local *)data; 1683 struct ieee80211_local *local = (struct ieee80211_local *)data;
1686 struct net_device *dev = local->mdev; 1684 struct net_device *dev = local->mdev;
1687 struct ieee80211_tx_stored_packet *store; 1685 struct ieee80211_tx_stored_packet *store;
1688 struct ieee80211_tx_data tx; 1686 struct ieee80211_tx_data tx;
1689 int i, ret, reschedule = 0; 1687 int i, ret;
1690 1688
1691 netif_tx_lock_bh(dev); 1689 netif_tx_lock_bh(dev);
1692 for (i = 0; i < local->hw.queues; i++) { 1690 for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) {
1693 if (__ieee80211_queue_stopped(local, i)) 1691 /* Check that this queue is ok */
1692 if (__netif_subqueue_stopped(local->mdev, i))
1694 continue; 1693 continue;
1695 if (!__ieee80211_queue_pending(local, i)) { 1694
1696 reschedule = 1; 1695 if (!test_bit(i, local->queues_pending)) {
1696 ieee80211_wake_queue(&local->hw, i);
1697 continue; 1697 continue;
1698 } 1698 }
1699
1699 store = &local->pending_packet[i]; 1700 store = &local->pending_packet[i];
1700 tx.extra_frag = store->extra_frag; 1701 tx.extra_frag = store->extra_frag;
1701 tx.num_extra_frag = store->num_extra_frag; 1702 tx.num_extra_frag = store->num_extra_frag;
@@ -1708,19 +1709,11 @@ void ieee80211_tx_pending(unsigned long data)
1708 if (ret == IEEE80211_TX_FRAG_AGAIN) 1709 if (ret == IEEE80211_TX_FRAG_AGAIN)
1709 store->skb = NULL; 1710 store->skb = NULL;
1710 } else { 1711 } else {
1711 clear_bit(IEEE80211_LINK_STATE_PENDING, 1712 clear_bit(i, local->queues_pending);
1712 &local->state[i]); 1713 ieee80211_wake_queue(&local->hw, i);
1713 reschedule = 1;
1714 } 1714 }
1715 } 1715 }
1716 netif_tx_unlock_bh(dev); 1716 netif_tx_unlock_bh(dev);
1717 if (reschedule) {
1718 if (!ieee80211_qdisc_installed(dev)) {
1719 if (!__ieee80211_queue_stopped(local, 0))
1720 netif_wake_queue(dev);
1721 } else
1722 netif_schedule(dev);
1723 }
1724} 1717}
1725 1718
1726/* functions for drivers to get certain frames */ 1719/* functions for drivers to get certain frames */
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index d9109dee461f..4f7180b287da 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -331,17 +331,15 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
331{ 331{
332 struct ieee80211_local *local = hw_to_local(hw); 332 struct ieee80211_local *local = hw_to_local(hw);
333 333
334 if (test_and_clear_bit(IEEE80211_LINK_STATE_XOFF, 334 if (test_bit(queue, local->queues_pending)) {
335 &local->state[queue])) { 335 tasklet_schedule(&local->tx_pending_tasklet);
336 if (test_bit(IEEE80211_LINK_STATE_PENDING, 336 } else {
337 &local->state[queue])) 337 if (ieee80211_is_multiqueue(local)) {
338 tasklet_schedule(&local->tx_pending_tasklet); 338 netif_wake_subqueue(local->mdev, queue);
339 else 339 } else {
340 if (!ieee80211_qdisc_installed(local->mdev)) { 340 WARN_ON(queue != 0);
341 if (queue == 0) 341 netif_wake_queue(local->mdev);
342 netif_wake_queue(local->mdev); 342 }
343 } else
344 __netif_schedule(local->mdev);
345 } 343 }
346} 344}
347EXPORT_SYMBOL(ieee80211_wake_queue); 345EXPORT_SYMBOL(ieee80211_wake_queue);
@@ -350,9 +348,12 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
350{ 348{
351 struct ieee80211_local *local = hw_to_local(hw); 349 struct ieee80211_local *local = hw_to_local(hw);
352 350
353 if (!ieee80211_qdisc_installed(local->mdev) && queue == 0) 351 if (ieee80211_is_multiqueue(local)) {
352 netif_stop_subqueue(local->mdev, queue);
353 } else {
354 WARN_ON(queue != 0);
354 netif_stop_queue(local->mdev); 355 netif_stop_queue(local->mdev);
355 set_bit(IEEE80211_LINK_STATE_XOFF, &local->state[queue]); 356 }
356} 357}
357EXPORT_SYMBOL(ieee80211_stop_queue); 358EXPORT_SYMBOL(ieee80211_stop_queue);
358 359
@@ -360,7 +361,7 @@ void ieee80211_stop_queues(struct ieee80211_hw *hw)
360{ 361{
361 int i; 362 int i;
362 363
363 for (i = 0; i < hw->queues + hw->ampdu_queues; i++) 364 for (i = 0; i < ieee80211_num_queues(hw); i++)
364 ieee80211_stop_queue(hw, i); 365 ieee80211_stop_queue(hw, i);
365} 366}
366EXPORT_SYMBOL(ieee80211_stop_queues); 367EXPORT_SYMBOL(ieee80211_stop_queues);
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 477690f4dca7..14a9ff10a1e9 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -158,7 +158,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
158 u8 tid; 158 u8 tid;
159 159
160 if (info->flags & IEEE80211_TX_CTL_REQUEUE) { 160 if (info->flags & IEEE80211_TX_CTL_REQUEUE) {
161 queue = info->queue; 161 queue = skb_get_queue_mapping(skb);
162 rcu_read_lock(); 162 rcu_read_lock();
163 sta = sta_info_get(local, hdr->addr1); 163 sta = sta_info_get(local, hdr->addr1);
164 tid = skb->priority & QOS_CONTROL_TAG1D_MASK; 164 tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
@@ -219,7 +219,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
219 err = NET_XMIT_DROP; 219 err = NET_XMIT_DROP;
220 } else { 220 } else {
221 tid = skb->priority & QOS_CONTROL_TAG1D_MASK; 221 tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
222 info->queue = (unsigned int) queue; 222 skb_set_queue_mapping(skb, queue);
223 qdisc = q->queues[queue]; 223 qdisc = q->queues[queue];
224 err = qdisc->enqueue(skb, qdisc); 224 err = qdisc->enqueue(skb, qdisc);
225 if (err == NET_XMIT_SUCCESS) { 225 if (err == NET_XMIT_SUCCESS) {
@@ -240,12 +240,11 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
240static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) 240static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd)
241{ 241{
242 struct ieee80211_sched_data *q = qdisc_priv(qd); 242 struct ieee80211_sched_data *q = qdisc_priv(qd);
243 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
244 struct Qdisc *qdisc; 243 struct Qdisc *qdisc;
245 int err; 244 int err;
246 245
247 /* we recorded which queue to use earlier! */ 246 /* we recorded which queue to use earlier! */
248 qdisc = q->queues[info->queue]; 247 qdisc = q->queues[skb_get_queue_mapping(skb)];
249 248
250 if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) { 249 if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) {
251 qd->q.qlen++; 250 qd->q.qlen++;
@@ -269,11 +268,8 @@ static struct sk_buff *wme_qdiscop_dequeue(struct Qdisc* qd)
269 /* check all the h/w queues in numeric/priority order */ 268 /* check all the h/w queues in numeric/priority order */
270 for (queue = 0; queue < QD_NUM(hw); queue++) { 269 for (queue = 0; queue < QD_NUM(hw); queue++) {
271 /* see if there is room in this hardware queue */ 270 /* see if there is room in this hardware queue */
272 if ((test_bit(IEEE80211_LINK_STATE_XOFF, 271 if (__netif_subqueue_stopped(local->mdev, queue) ||
273 &local->state[queue])) || 272 !test_bit(queue, q->qdisc_pool))
274 (test_bit(IEEE80211_LINK_STATE_PENDING,
275 &local->state[queue])) ||
276 (!test_bit(queue, q->qdisc_pool)))
277 continue; 273 continue;
278 274
279 /* there is space - try and get a frame */ 275 /* there is space - try and get a frame */
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index fcc6b05508cc..bbdb53344817 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -31,7 +31,7 @@ static inline int WLAN_FC_IS_QOS_DATA(u16 fc)
31 return (fc & 0x8C) == 0x88; 31 return (fc & 0x8C) == 0x88;
32} 32}
33 33
34#ifdef CONFIG_NET_SCHED 34#ifdef CONFIG_MAC80211_QOS
35void ieee80211_install_qdisc(struct net_device *dev); 35void ieee80211_install_qdisc(struct net_device *dev);
36int ieee80211_qdisc_installed(struct net_device *dev); 36int ieee80211_qdisc_installed(struct net_device *dev);
37int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, 37int ieee80211_ht_agg_queue_add(struct ieee80211_local *local,