diff options
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 80c16f6e2af6..32abae3ce32a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -15,12 +15,14 @@ | |||
15 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
16 | #include <linux/rtnetlink.h> | 16 | #include <linux/rtnetlink.h> |
17 | #include <net/mac80211.h> | 17 | #include <net/mac80211.h> |
18 | #include <net/ieee80211_radiotap.h> | ||
18 | #include "ieee80211_i.h" | 19 | #include "ieee80211_i.h" |
19 | #include "sta_info.h" | 20 | #include "sta_info.h" |
20 | #include "debugfs_netdev.h" | 21 | #include "debugfs_netdev.h" |
21 | #include "mesh.h" | 22 | #include "mesh.h" |
22 | #include "led.h" | 23 | #include "led.h" |
23 | #include "driver-ops.h" | 24 | #include "driver-ops.h" |
25 | #include "wme.h" | ||
24 | 26 | ||
25 | /** | 27 | /** |
26 | * DOC: Interface list locking | 28 | * DOC: Interface list locking |
@@ -314,7 +316,7 @@ static int ieee80211_open(struct net_device *dev) | |||
314 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 316 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
315 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); | 317 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); |
316 | 318 | ||
317 | netif_start_queue(dev); | 319 | netif_tx_start_all_queues(dev); |
318 | 320 | ||
319 | return 0; | 321 | return 0; |
320 | err_del_interface: | 322 | err_del_interface: |
@@ -343,7 +345,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
343 | /* | 345 | /* |
344 | * Stop TX on this interface first. | 346 | * Stop TX on this interface first. |
345 | */ | 347 | */ |
346 | netif_stop_queue(dev); | 348 | netif_tx_stop_all_queues(dev); |
347 | 349 | ||
348 | /* | 350 | /* |
349 | * Now delete all active aggregation sessions. | 351 | * Now delete all active aggregation sessions. |
@@ -644,6 +646,12 @@ static void ieee80211_teardown_sdata(struct net_device *dev) | |||
644 | WARN_ON(flushed); | 646 | WARN_ON(flushed); |
645 | } | 647 | } |
646 | 648 | ||
649 | static u16 ieee80211_netdev_select_queue(struct net_device *dev, | ||
650 | struct sk_buff *skb) | ||
651 | { | ||
652 | return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); | ||
653 | } | ||
654 | |||
647 | static const struct net_device_ops ieee80211_dataif_ops = { | 655 | static const struct net_device_ops ieee80211_dataif_ops = { |
648 | .ndo_open = ieee80211_open, | 656 | .ndo_open = ieee80211_open, |
649 | .ndo_stop = ieee80211_stop, | 657 | .ndo_stop = ieee80211_stop, |
@@ -652,8 +660,38 @@ static const struct net_device_ops ieee80211_dataif_ops = { | |||
652 | .ndo_set_multicast_list = ieee80211_set_multicast_list, | 660 | .ndo_set_multicast_list = ieee80211_set_multicast_list, |
653 | .ndo_change_mtu = ieee80211_change_mtu, | 661 | .ndo_change_mtu = ieee80211_change_mtu, |
654 | .ndo_set_mac_address = eth_mac_addr, | 662 | .ndo_set_mac_address = eth_mac_addr, |
663 | .ndo_select_queue = ieee80211_netdev_select_queue, | ||
655 | }; | 664 | }; |
656 | 665 | ||
666 | static u16 ieee80211_monitor_select_queue(struct net_device *dev, | ||
667 | struct sk_buff *skb) | ||
668 | { | ||
669 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
670 | struct ieee80211_local *local = sdata->local; | ||
671 | struct ieee80211_hdr *hdr; | ||
672 | struct ieee80211_radiotap_header *rtap = (void *)skb->data; | ||
673 | u8 *p; | ||
674 | |||
675 | if (local->hw.queues < 4) | ||
676 | return 0; | ||
677 | |||
678 | if (skb->len < 4 || | ||
679 | skb->len < le16_to_cpu(rtap->it_len) + 2 /* frame control */) | ||
680 | return 0; /* doesn't matter, frame will be dropped */ | ||
681 | |||
682 | hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); | ||
683 | |||
684 | if (!ieee80211_is_data_qos(hdr->frame_control)) { | ||
685 | skb->priority = 7; | ||
686 | return ieee802_1d_to_ac[skb->priority]; | ||
687 | } | ||
688 | |||
689 | p = ieee80211_get_qos_ctl(hdr); | ||
690 | skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; | ||
691 | |||
692 | return ieee80211_downgrade_queue(local, skb); | ||
693 | } | ||
694 | |||
657 | static const struct net_device_ops ieee80211_monitorif_ops = { | 695 | static const struct net_device_ops ieee80211_monitorif_ops = { |
658 | .ndo_open = ieee80211_open, | 696 | .ndo_open = ieee80211_open, |
659 | .ndo_stop = ieee80211_stop, | 697 | .ndo_stop = ieee80211_stop, |
@@ -662,6 +700,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = { | |||
662 | .ndo_set_multicast_list = ieee80211_set_multicast_list, | 700 | .ndo_set_multicast_list = ieee80211_set_multicast_list, |
663 | .ndo_change_mtu = ieee80211_change_mtu, | 701 | .ndo_change_mtu = ieee80211_change_mtu, |
664 | .ndo_set_mac_address = eth_mac_addr, | 702 | .ndo_set_mac_address = eth_mac_addr, |
703 | .ndo_select_queue = ieee80211_monitor_select_queue, | ||
665 | }; | 704 | }; |
666 | 705 | ||
667 | static void ieee80211_if_setup(struct net_device *dev) | 706 | static void ieee80211_if_setup(struct net_device *dev) |
@@ -768,8 +807,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
768 | 807 | ||
769 | ASSERT_RTNL(); | 808 | ASSERT_RTNL(); |
770 | 809 | ||
771 | ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, | 810 | ndev = alloc_netdev_mq(sizeof(*sdata) + local->hw.vif_data_size, |
772 | name, ieee80211_if_setup); | 811 | name, ieee80211_if_setup, local->hw.queues); |
773 | if (!ndev) | 812 | if (!ndev) |
774 | return -ENOMEM; | 813 | return -ENOMEM; |
775 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); | 814 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); |