hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/mac80211/wme.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright 2004, Instant802 Networks, Inc.
34 * Copyright 2013-2014 Intel Mobile Communications GmbH
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License version 2 as
7
- * published by the Free Software Foundation.
85 */
96
107 #include <linux/netdevice.h>
....@@ -141,71 +138,26 @@
141138 return ieee80211_downgrade_queue(sdata, NULL, skb);
142139 }
143140
144
-/* Indicate which queue to use. */
145
-u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
146
- struct sk_buff *skb)
141
+u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
142
+ struct sta_info *sta, struct sk_buff *skb)
147143 {
148
- struct ieee80211_local *local = sdata->local;
149
- struct sta_info *sta = NULL;
150
- const u8 *ra = NULL;
151
- bool qos = false;
144
+ const struct ethhdr *eth = (void *)skb->data;
152145 struct mac80211_qos_map *qos_map;
153
- u16 ret;
146
+ bool qos;
154147
155
- if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
156
- skb->priority = 0; /* required for correct WPA/11i MIC */
157
- return 0;
158
- }
159
-
160
- rcu_read_lock();
161
- switch (sdata->vif.type) {
162
- case NL80211_IFTYPE_AP_VLAN:
163
- sta = rcu_dereference(sdata->u.vlan.sta);
164
- if (sta) {
165
- qos = sta->sta.wme;
166
- break;
167
- }
168
- /* fall through */
169
- case NL80211_IFTYPE_AP:
170
- ra = skb->data;
171
- break;
172
- case NL80211_IFTYPE_WDS:
173
- ra = sdata->u.wds.remote_addr;
174
- break;
175
-#ifdef CONFIG_MAC80211_MESH
176
- case NL80211_IFTYPE_MESH_POINT:
148
+ /* all mesh/ocb stations are required to support WME */
149
+ if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT &&
150
+ !is_multicast_ether_addr(eth->h_dest)) ||
151
+ (sdata->vif.type == NL80211_IFTYPE_OCB && sta))
177152 qos = true;
178
- break;
179
-#endif
180
- case NL80211_IFTYPE_STATION:
181
- /* might be a TDLS station */
182
- sta = sta_info_get(sdata, skb->data);
183
- if (sta)
184
- qos = sta->sta.wme;
185
-
186
- ra = sdata->u.mgd.bssid;
187
- break;
188
- case NL80211_IFTYPE_ADHOC:
189
- ra = skb->data;
190
- break;
191
- case NL80211_IFTYPE_OCB:
192
- /* all stations are required to support WME */
193
- qos = true;
194
- break;
195
- default:
196
- break;
197
- }
198
-
199
- if (!sta && ra && !is_multicast_ether_addr(ra)) {
200
- sta = sta_info_get(sdata, ra);
201
- if (sta)
202
- qos = sta->sta.wme;
203
- }
153
+ else if (sta)
154
+ qos = sta->sta.wme;
155
+ else
156
+ qos = false;
204157
205158 if (!qos) {
206159 skb->priority = 0; /* required for correct WPA/11i MIC */
207
- ret = IEEE80211_AC_BE;
208
- goto out;
160
+ return IEEE80211_AC_BE;
209161 }
210162
211163 if (skb->protocol == sdata->control_port_protocol) {
....@@ -220,8 +172,61 @@
220172 &qos_map->qos_map : NULL);
221173
222174 downgrade:
223
- ret = ieee80211_downgrade_queue(sdata, sta, skb);
224
- out:
175
+ return ieee80211_downgrade_queue(sdata, sta, skb);
176
+}
177
+
178
+
179
+/* Indicate which queue to use. */
180
+u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
181
+ struct sk_buff *skb)
182
+{
183
+ struct ieee80211_local *local = sdata->local;
184
+ struct sta_info *sta = NULL;
185
+ const u8 *ra = NULL;
186
+ u16 ret;
187
+
188
+ /* when using iTXQ, we can do this later */
189
+ if (local->ops->wake_tx_queue)
190
+ return 0;
191
+
192
+ if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
193
+ skb->priority = 0; /* required for correct WPA/11i MIC */
194
+ return 0;
195
+ }
196
+
197
+ rcu_read_lock();
198
+ switch (sdata->vif.type) {
199
+ case NL80211_IFTYPE_AP_VLAN:
200
+ sta = rcu_dereference(sdata->u.vlan.sta);
201
+ if (sta)
202
+ break;
203
+ fallthrough;
204
+ case NL80211_IFTYPE_AP:
205
+ ra = skb->data;
206
+ break;
207
+ case NL80211_IFTYPE_WDS:
208
+ ra = sdata->u.wds.remote_addr;
209
+ break;
210
+ case NL80211_IFTYPE_STATION:
211
+ /* might be a TDLS station */
212
+ sta = sta_info_get(sdata, skb->data);
213
+ if (sta)
214
+ break;
215
+
216
+ ra = sdata->u.mgd.bssid;
217
+ break;
218
+ case NL80211_IFTYPE_ADHOC:
219
+ ra = skb->data;
220
+ break;
221
+ default:
222
+ break;
223
+ }
224
+
225
+ if (!sta && ra && !is_multicast_ether_addr(ra))
226
+ sta = sta_info_get(sdata, ra);
227
+
228
+ ret = __ieee80211_select_queue(sdata, sta, skb);
229
+
225230 rcu_read_unlock();
226231 return ret;
227232 }