aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/wme.c')
-rw-r--r--net/mac80211/wme.c38
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 */
56u16 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. */
57u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, 81u16 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) ?