diff options
Diffstat (limited to 'net/mac80211/wme.c')
-rw-r--r-- | net/mac80211/wme.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index fd52e695c071..89511be3111e 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -52,6 +52,30 @@ static int wme_downgrade_ac(struct sk_buff *skb) | |||
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | /* Indicate which queue to use for this fully formed 802.11 frame */ | ||
56 | u16 ieee80211_select_queue_80211(struct ieee80211_local *local, | ||
57 | struct sk_buff *skb, | ||
58 | struct ieee80211_hdr *hdr) | ||
59 | { | ||
60 | u8 *p; | ||
61 | |||
62 | if (local->hw.queues < 4) | ||
63 | return 0; | ||
64 | |||
65 | if (!ieee80211_is_data(hdr->frame_control)) { | ||
66 | skb->priority = 7; | ||
67 | return ieee802_1d_to_ac[skb->priority]; | ||
68 | } | ||
69 | if (!ieee80211_is_data_qos(hdr->frame_control)) { | ||
70 | skb->priority = 0; | ||
71 | return ieee802_1d_to_ac[skb->priority]; | ||
72 | } | ||
73 | |||
74 | p = ieee80211_get_qos_ctl(hdr); | ||
75 | skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; | ||
76 | |||
77 | return ieee80211_downgrade_queue(local, skb); | ||
78 | } | ||
55 | 79 | ||
56 | /* Indicate which queue to use. */ | 80 | /* Indicate which queue to use. */ |
57 | u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | 81 | u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, |
@@ -83,7 +107,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
83 | break; | 107 | break; |
84 | #ifdef CONFIG_MAC80211_MESH | 108 | #ifdef CONFIG_MAC80211_MESH |
85 | case NL80211_IFTYPE_MESH_POINT: | 109 | case NL80211_IFTYPE_MESH_POINT: |
86 | ra = skb->data; | 110 | qos = true; |
87 | break; | 111 | break; |
88 | #endif | 112 | #endif |
89 | case NL80211_IFTYPE_STATION: | 113 | case NL80211_IFTYPE_STATION: |
@@ -139,16 +163,24 @@ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, | |||
139 | struct sk_buff *skb) | 163 | struct sk_buff *skb) |
140 | { | 164 | { |
141 | struct ieee80211_hdr *hdr = (void *)skb->data; | 165 | struct ieee80211_hdr *hdr = (void *)skb->data; |
166 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
142 | 167 | ||
143 | /* Fill in the QoS header if there is one. */ | 168 | /* Fill in the QoS header if there is one. */ |
144 | if (ieee80211_is_data_qos(hdr->frame_control)) { | 169 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
145 | u8 *p = ieee80211_get_qos_ctl(hdr); | 170 | u8 *p = ieee80211_get_qos_ctl(hdr); |
146 | u8 ack_policy = 0, tid; | 171 | u8 ack_policy, tid; |
147 | 172 | ||
148 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; | 173 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
149 | 174 | ||
150 | if (unlikely(sdata->local->wifi_wme_noack_test)) | 175 | /* preserve EOSP bit */ |
176 | ack_policy = *p & IEEE80211_QOS_CTL_EOSP; | ||
177 | |||
178 | if (is_multicast_ether_addr(hdr->addr1) || | ||
179 | sdata->noack_map & BIT(tid)) { | ||
151 | ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; | 180 | ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; |
181 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
182 | } | ||
183 | |||
152 | /* qos header is 2 bytes */ | 184 | /* qos header is 2 bytes */ |
153 | *p++ = ack_policy | tid; | 185 | *p++ = ack_policy | tid; |
154 | *p = ieee80211_vif_is_mesh(&sdata->vif) ? | 186 | *p = ieee80211_vif_is_mesh(&sdata->vif) ? |