aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
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 /net/mac80211
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>
Diffstat (limited to 'net/mac80211')
-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
10 files changed, 114 insertions, 93 deletions
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,