diff options
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 80c16f6e2af6..c261cdb359eb 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 |
@@ -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,34 @@ 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 | |||
674 | if (local->hw.queues < 4) | ||
675 | return 0; | ||
676 | |||
677 | if (skb->len < 4 || | ||
678 | skb->len < rtap->it_len + 2 /* frame control */) | ||
679 | return 0; /* doesn't matter, frame will be dropped */ | ||
680 | |||
681 | hdr = (void *)((u8 *)skb->data + rtap->it_len); | ||
682 | |||
683 | if (!ieee80211_is_data(hdr->frame_control)) { | ||
684 | skb->priority = 7; | ||
685 | return ieee802_1d_to_ac[skb->priority]; | ||
686 | } | ||
687 | |||
688 | return ieee80211_downgrade_queue(local, skb); | ||
689 | } | ||
690 | |||
657 | static const struct net_device_ops ieee80211_monitorif_ops = { | 691 | static const struct net_device_ops ieee80211_monitorif_ops = { |
658 | .ndo_open = ieee80211_open, | 692 | .ndo_open = ieee80211_open, |
659 | .ndo_stop = ieee80211_stop, | 693 | .ndo_stop = ieee80211_stop, |
@@ -662,6 +696,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = { | |||
662 | .ndo_set_multicast_list = ieee80211_set_multicast_list, | 696 | .ndo_set_multicast_list = ieee80211_set_multicast_list, |
663 | .ndo_change_mtu = ieee80211_change_mtu, | 697 | .ndo_change_mtu = ieee80211_change_mtu, |
664 | .ndo_set_mac_address = eth_mac_addr, | 698 | .ndo_set_mac_address = eth_mac_addr, |
699 | .ndo_select_queue = ieee80211_monitor_select_queue, | ||
665 | }; | 700 | }; |
666 | 701 | ||
667 | static void ieee80211_if_setup(struct net_device *dev) | 702 | static void ieee80211_if_setup(struct net_device *dev) |
@@ -768,8 +803,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
768 | 803 | ||
769 | ASSERT_RTNL(); | 804 | ASSERT_RTNL(); |
770 | 805 | ||
771 | ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, | 806 | ndev = alloc_netdev_mq(sizeof(*sdata) + local->hw.vif_data_size, |
772 | name, ieee80211_if_setup); | 807 | name, ieee80211_if_setup, local->hw.queues); |
773 | if (!ndev) | 808 | if (!ndev) |
774 | return -ENOMEM; | 809 | return -ENOMEM; |
775 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); | 810 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); |