blob: a6c01741d66d7088d839d2dedfb82377bda4702c [file] [log] [blame]
Googler9398cc32022-12-02 17:21:52 +08001// SPDX-License-Identifier: GPL-2.0-only
Googleraf606d22022-10-26 21:40:12 -07002/*
3 * Copyright 2002-2005, Instant802 Networks, Inc.
4 * Copyright 2005-2006, Devicescape Software, Inc.
5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
6 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2013-2014 Intel Mobile Communications GmbH
Googler9398cc32022-12-02 17:21:52 +08008 * Copyright (C) 2015-2017 Intel Deutschland GmbH
Googlerb48fa912023-03-17 12:40:29 +05309 * Copyright (C) 2018-2020 Intel Corporation
Googleraf606d22022-10-26 21:40:12 -070010 *
11 * utilities for mac80211
12 */
13
14#include <net/mac80211.h>
15#include <linux/netdevice.h>
16#include <linux/export.h>
17#include <linux/types.h>
18#include <linux/slab.h>
19#include <linux/skbuff.h>
20#include <linux/etherdevice.h>
21#include <linux/if_arp.h>
22#include <linux/bitmap.h>
23#include <linux/crc32.h>
24#include <net/net_namespace.h>
25#include <net/cfg80211.h>
26#include <net/rtnetlink.h>
27
28#include "ieee80211_i.h"
29#include "driver-ops.h"
30#include "rate.h"
31#include "mesh.h"
32#include "wme.h"
33#include "led.h"
34#include "wep.h"
35
36/* privid for wiphys to determine whether they belong to us or not */
37const void *const mac80211_wiphy_privid = &mac80211_wiphy_privid;
38
39struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy)
40{
41 struct ieee80211_local *local;
Googleraf606d22022-10-26 21:40:12 -070042
43 local = wiphy_priv(wiphy);
44 return &local->hw;
45}
46EXPORT_SYMBOL(wiphy_to_ieee80211_hw);
47
Googlerb48fa912023-03-17 12:40:29 +053048u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
49 enum nl80211_iftype type)
50{
51 __le16 fc = hdr->frame_control;
52
53 if (ieee80211_is_data(fc)) {
54 if (len < 24) /* drop incorrect hdr len (data) */
55 return NULL;
56
57 if (ieee80211_has_a4(fc))
58 return NULL;
59 if (ieee80211_has_tods(fc))
60 return hdr->addr1;
61 if (ieee80211_has_fromds(fc))
62 return hdr->addr2;
63
64 return hdr->addr3;
65 }
66
67 if (ieee80211_is_s1g_beacon(fc)) {
68 struct ieee80211_ext *ext = (void *) hdr;
69
70 return ext->u.s1g_beacon.sa;
71 }
72
73 if (ieee80211_is_mgmt(fc)) {
74 if (len < 24) /* drop incorrect hdr len (mgmt) */
75 return NULL;
76 return hdr->addr3;
77 }
78
79 if (ieee80211_is_ctl(fc)) {
80 if (ieee80211_is_pspoll(fc))
81 return hdr->addr1;
82
83 if (ieee80211_is_back_req(fc)) {
84 switch (type) {
85 case NL80211_IFTYPE_STATION:
86 return hdr->addr2;
87 case NL80211_IFTYPE_AP:
88 case NL80211_IFTYPE_AP_VLAN:
89 return hdr->addr1;
90 default:
91 break; /* fall through to the return */
92 }
93 }
94 }
95
96 return NULL;
97}
98EXPORT_SYMBOL(ieee80211_get_bssid);
99
Googleraf606d22022-10-26 21:40:12 -0700100void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
101{
102 struct sk_buff *skb;
103 struct ieee80211_hdr *hdr;
104
105 skb_queue_walk(&tx->skbs, skb) {
106 hdr = (struct ieee80211_hdr *) skb->data;
107 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
108 }
109}
110
111int ieee80211_frame_duration(enum nl80211_band band, size_t len,
112 int rate, int erp, int short_preamble,
113 int shift)
114{
115 int dur;
116
117 /* calculate duration (in microseconds, rounded up to next higher
118 * integer if it includes a fractional microsecond) to send frame of
119 * len bytes (does not include FCS) at the given rate. Duration will
120 * also include SIFS.
121 *
122 * rate is in 100 kbps, so divident is multiplied by 10 in the
123 * DIV_ROUND_UP() operations.
124 *
125 * shift may be 2 for 5 MHz channels or 1 for 10 MHz channels, and
126 * is assumed to be 0 otherwise.
127 */
128
129 if (band == NL80211_BAND_5GHZ || erp) {
130 /*
131 * OFDM:
132 *
133 * N_DBPS = DATARATE x 4
134 * N_SYM = Ceiling((16+8xLENGTH+6) / N_DBPS)
135 * (16 = SIGNAL time, 6 = tail bits)
136 * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext
137 *
138 * T_SYM = 4 usec
139 * 802.11a - 18.5.2: aSIFSTime = 16 usec
140 * 802.11g - 19.8.4: aSIFSTime = 10 usec +
141 * signal ext = 6 usec
142 */
143 dur = 16; /* SIFS + signal ext */
144 dur += 16; /* IEEE 802.11-2012 18.3.2.4: T_PREAMBLE = 16 usec */
145 dur += 4; /* IEEE 802.11-2012 18.3.2.4: T_SIGNAL = 4 usec */
146
147 /* IEEE 802.11-2012 18.3.2.4: all values above are:
148 * * times 4 for 5 MHz
149 * * times 2 for 10 MHz
150 */
151 dur *= 1 << shift;
152
153 /* rates should already consider the channel bandwidth,
154 * don't apply divisor again.
155 */
156 dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
157 4 * rate); /* T_SYM x N_SYM */
158 } else {
159 /*
160 * 802.11b or 802.11g with 802.11b compatibility:
161 * 18.3.4: TXTIME = PreambleLength + PLCPHeaderTime +
162 * Ceiling(((LENGTH+PBCC)x8)/DATARATE). PBCC=0.
163 *
164 * 802.11 (DS): 15.3.3, 802.11b: 18.3.4
165 * aSIFSTime = 10 usec
166 * aPreambleLength = 144 usec or 72 usec with short preamble
167 * aPLCPHeaderLength = 48 usec or 24 usec with short preamble
168 */
169 dur = 10; /* aSIFSTime = 10 usec */
170 dur += short_preamble ? (72 + 24) : (144 + 48);
171
172 dur += DIV_ROUND_UP(8 * (len + 4) * 10, rate);
173 }
174
175 return dur;
176}
177
178/* Exported duration function for driver use */
179__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
180 struct ieee80211_vif *vif,
181 enum nl80211_band band,
182 size_t frame_len,
183 struct ieee80211_rate *rate)
184{
185 struct ieee80211_sub_if_data *sdata;
186 u16 dur;
187 int erp, shift = 0;
188 bool short_preamble = false;
189
190 erp = 0;
191 if (vif) {
192 sdata = vif_to_sdata(vif);
193 short_preamble = sdata->vif.bss_conf.use_short_preamble;
194 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
195 erp = rate->flags & IEEE80211_RATE_ERP_G;
196 shift = ieee80211_vif_get_shift(vif);
197 }
198
199 dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp,
200 short_preamble, shift);
201
202 return cpu_to_le16(dur);
203}
204EXPORT_SYMBOL(ieee80211_generic_frame_duration);
205
206__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
207 struct ieee80211_vif *vif, size_t frame_len,
208 const struct ieee80211_tx_info *frame_txctl)
209{
210 struct ieee80211_local *local = hw_to_local(hw);
211 struct ieee80211_rate *rate;
212 struct ieee80211_sub_if_data *sdata;
213 bool short_preamble;
214 int erp, shift = 0, bitrate;
215 u16 dur;
216 struct ieee80211_supported_band *sband;
217
218 sband = local->hw.wiphy->bands[frame_txctl->band];
219
220 short_preamble = false;
221
222 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
223
224 erp = 0;
225 if (vif) {
226 sdata = vif_to_sdata(vif);
227 short_preamble = sdata->vif.bss_conf.use_short_preamble;
228 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
229 erp = rate->flags & IEEE80211_RATE_ERP_G;
230 shift = ieee80211_vif_get_shift(vif);
231 }
232
233 bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
234
235 /* CTS duration */
236 dur = ieee80211_frame_duration(sband->band, 10, bitrate,
237 erp, short_preamble, shift);
238 /* Data frame duration */
239 dur += ieee80211_frame_duration(sband->band, frame_len, bitrate,
240 erp, short_preamble, shift);
241 /* ACK duration */
242 dur += ieee80211_frame_duration(sband->band, 10, bitrate,
243 erp, short_preamble, shift);
244
245 return cpu_to_le16(dur);
246}
247EXPORT_SYMBOL(ieee80211_rts_duration);
248
249__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
250 struct ieee80211_vif *vif,
251 size_t frame_len,
252 const struct ieee80211_tx_info *frame_txctl)
253{
254 struct ieee80211_local *local = hw_to_local(hw);
255 struct ieee80211_rate *rate;
256 struct ieee80211_sub_if_data *sdata;
257 bool short_preamble;
258 int erp, shift = 0, bitrate;
259 u16 dur;
260 struct ieee80211_supported_band *sband;
261
262 sband = local->hw.wiphy->bands[frame_txctl->band];
263
264 short_preamble = false;
265
266 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
267 erp = 0;
268 if (vif) {
269 sdata = vif_to_sdata(vif);
270 short_preamble = sdata->vif.bss_conf.use_short_preamble;
271 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
272 erp = rate->flags & IEEE80211_RATE_ERP_G;
273 shift = ieee80211_vif_get_shift(vif);
274 }
275
276 bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
277
278 /* Data frame duration */
279 dur = ieee80211_frame_duration(sband->band, frame_len, bitrate,
280 erp, short_preamble, shift);
281 if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
282 /* ACK duration */
283 dur += ieee80211_frame_duration(sband->band, 10, bitrate,
284 erp, short_preamble, shift);
285 }
286
287 return cpu_to_le16(dur);
288}
289EXPORT_SYMBOL(ieee80211_ctstoself_duration);
290
Googler9398cc32022-12-02 17:21:52 +0800291static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
292{
293 struct ieee80211_local *local = sdata->local;
294 struct ieee80211_vif *vif = &sdata->vif;
295 struct fq *fq = &local->fq;
296 struct ps_data *ps = NULL;
297 struct txq_info *txqi;
298 struct sta_info *sta;
299 int i;
300
301 local_bh_disable();
302 spin_lock(&fq->lock);
303
304 if (sdata->vif.type == NL80211_IFTYPE_AP)
305 ps = &sdata->bss->ps;
306
307 sdata->vif.txqs_stopped[ac] = false;
308
309 list_for_each_entry_rcu(sta, &local->sta_list, list) {
310 if (sdata != sta->sdata)
311 continue;
312
313 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
314 struct ieee80211_txq *txq = sta->sta.txq[i];
315
316 if (!txq)
317 continue;
318
319 txqi = to_txq_info(txq);
320
321 if (ac != txq->ac)
322 continue;
323
324 if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX,
325 &txqi->flags))
326 continue;
327
328 spin_unlock(&fq->lock);
329 drv_wake_tx_queue(local, txqi);
330 spin_lock(&fq->lock);
331 }
332 }
333
334 if (!vif->txq)
335 goto out;
336
337 txqi = to_txq_info(vif->txq);
338
339 if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags) ||
340 (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac)
341 goto out;
342
343 spin_unlock(&fq->lock);
344
345 drv_wake_tx_queue(local, txqi);
346 local_bh_enable();
347 return;
348out:
349 spin_unlock(&fq->lock);
350 local_bh_enable();
351}
352
Googlerb48fa912023-03-17 12:40:29 +0530353void ieee80211_wake_txqs(unsigned long data)
Googler9398cc32022-12-02 17:21:52 +0800354{
Googlerb48fa912023-03-17 12:40:29 +0530355 struct ieee80211_local *local = (struct ieee80211_local *)data;
Googler9398cc32022-12-02 17:21:52 +0800356 struct ieee80211_sub_if_data *sdata;
357 int n_acs = IEEE80211_NUM_ACS;
Googlerb48fa912023-03-17 12:40:29 +0530358 unsigned long flags;
Googler9398cc32022-12-02 17:21:52 +0800359 int i;
360
361 rcu_read_lock();
Googlerb48fa912023-03-17 12:40:29 +0530362 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
Googler9398cc32022-12-02 17:21:52 +0800363
364 if (local->hw.queues < IEEE80211_NUM_ACS)
365 n_acs = 1;
366
367 for (i = 0; i < local->hw.queues; i++) {
368 if (local->queue_stop_reasons[i])
369 continue;
370
Googlerb48fa912023-03-17 12:40:29 +0530371 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
Googler9398cc32022-12-02 17:21:52 +0800372 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
373 int ac;
374
375 for (ac = 0; ac < n_acs; ac++) {
376 int ac_queue = sdata->vif.hw_queue[ac];
377
378 if (ac_queue == i ||
379 sdata->vif.cab_queue == i)
380 __ieee80211_wake_txqs(sdata, ac);
381 }
382 }
Googlerb48fa912023-03-17 12:40:29 +0530383 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
Googler9398cc32022-12-02 17:21:52 +0800384 }
385
Googler9398cc32022-12-02 17:21:52 +0800386 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
Googlerb48fa912023-03-17 12:40:29 +0530387 rcu_read_unlock();
Googler9398cc32022-12-02 17:21:52 +0800388}
389
Googleraf606d22022-10-26 21:40:12 -0700390void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
391{
392 struct ieee80211_sub_if_data *sdata;
393 int n_acs = IEEE80211_NUM_ACS;
394
395 if (local->ops->wake_tx_queue)
396 return;
397
398 if (local->hw.queues < IEEE80211_NUM_ACS)
399 n_acs = 1;
400
401 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
402 int ac;
403
404 if (!sdata->dev)
405 continue;
406
407 if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE &&
408 local->queue_stop_reasons[sdata->vif.cab_queue] != 0)
409 continue;
410
411 for (ac = 0; ac < n_acs; ac++) {
412 int ac_queue = sdata->vif.hw_queue[ac];
413
414 if (ac_queue == queue ||
415 (sdata->vif.cab_queue == queue &&
416 local->queue_stop_reasons[ac_queue] == 0 &&
Googlerb48fa912023-03-17 12:40:29 +0530417 skb_queue_empty(&local->pending[ac_queue]))) {
418 if (sdata->vif.noqueue_enable)
419 continue;
420
Googleraf606d22022-10-26 21:40:12 -0700421 netif_wake_subqueue(sdata->dev, ac);
Googlerb48fa912023-03-17 12:40:29 +0530422 }
Googleraf606d22022-10-26 21:40:12 -0700423 }
424 }
425}
426
427static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
428 enum queue_stop_reason reason,
Googlerb48fa912023-03-17 12:40:29 +0530429 bool refcounted)
Googleraf606d22022-10-26 21:40:12 -0700430{
431 struct ieee80211_local *local = hw_to_local(hw);
432
433 trace_wake_queue(local, queue, reason);
434
435 if (WARN_ON(queue >= hw->queues))
436 return;
437
438 if (!test_bit(reason, &local->queue_stop_reasons[queue]))
439 return;
440
441 if (!refcounted) {
442 local->q_stop_reasons[queue][reason] = 0;
443 } else {
444 local->q_stop_reasons[queue][reason]--;
445 if (WARN_ON(local->q_stop_reasons[queue][reason] < 0))
446 local->q_stop_reasons[queue][reason] = 0;
447 }
448
449 if (local->q_stop_reasons[queue][reason] == 0)
450 __clear_bit(reason, &local->queue_stop_reasons[queue]);
451
452 if (local->queue_stop_reasons[queue] != 0)
453 /* someone still has this queue stopped */
454 return;
455
456 if (skb_queue_empty(&local->pending[queue])) {
457 rcu_read_lock();
458 ieee80211_propagate_queue_wake(local, queue);
459 rcu_read_unlock();
460 } else
461 tasklet_schedule(&local->tx_pending_tasklet);
Googler9398cc32022-12-02 17:21:52 +0800462
Googlerb48fa912023-03-17 12:40:29 +0530463 if (local->ops->wake_tx_queue)
464 tasklet_schedule(&local->wake_txqs_tasklet);
Googleraf606d22022-10-26 21:40:12 -0700465}
466
467void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
468 enum queue_stop_reason reason,
469 bool refcounted)
470{
471 struct ieee80211_local *local = hw_to_local(hw);
472 unsigned long flags;
473
474 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
Googlerb48fa912023-03-17 12:40:29 +0530475 __ieee80211_wake_queue(hw, queue, reason, refcounted);
Googleraf606d22022-10-26 21:40:12 -0700476 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
477}
478
479void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
480{
481 ieee80211_wake_queue_by_reason(hw, queue,
482 IEEE80211_QUEUE_STOP_REASON_DRIVER,
483 false);
484}
485EXPORT_SYMBOL(ieee80211_wake_queue);
486
487static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
488 enum queue_stop_reason reason,
489 bool refcounted)
490{
491 struct ieee80211_local *local = hw_to_local(hw);
492 struct ieee80211_sub_if_data *sdata;
493 int n_acs = IEEE80211_NUM_ACS;
494
495 trace_stop_queue(local, queue, reason);
496
497 if (WARN_ON(queue >= hw->queues))
498 return;
499
500 if (!refcounted)
501 local->q_stop_reasons[queue][reason] = 1;
502 else
503 local->q_stop_reasons[queue][reason]++;
504
505 if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue]))
506 return;
507
Googleraf606d22022-10-26 21:40:12 -0700508 if (local->hw.queues < IEEE80211_NUM_ACS)
509 n_acs = 1;
510
511 rcu_read_lock();
512 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
513 int ac;
514
515 if (!sdata->dev)
516 continue;
517
518 for (ac = 0; ac < n_acs; ac++) {
519 if (sdata->vif.hw_queue[ac] == queue ||
Googler9398cc32022-12-02 17:21:52 +0800520 sdata->vif.cab_queue == queue) {
Googlerb48fa912023-03-17 12:40:29 +0530521 if (!local->ops->wake_tx_queue && sdata->vif.noqueue_enable)
522 continue;
523
Googler9398cc32022-12-02 17:21:52 +0800524 if (!local->ops->wake_tx_queue) {
525 netif_stop_subqueue(sdata->dev, ac);
526 continue;
527 }
528 spin_lock(&local->fq.lock);
529 sdata->vif.txqs_stopped[ac] = true;
530 spin_unlock(&local->fq.lock);
531 }
Googleraf606d22022-10-26 21:40:12 -0700532 }
533 }
534 rcu_read_unlock();
535}
536
537void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
538 enum queue_stop_reason reason,
539 bool refcounted)
540{
541 struct ieee80211_local *local = hw_to_local(hw);
542 unsigned long flags;
543
544 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
545 __ieee80211_stop_queue(hw, queue, reason, refcounted);
546 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
547}
548
549void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
550{
551 ieee80211_stop_queue_by_reason(hw, queue,
552 IEEE80211_QUEUE_STOP_REASON_DRIVER,
553 false);
554}
555EXPORT_SYMBOL(ieee80211_stop_queue);
556
557void ieee80211_add_pending_skb(struct ieee80211_local *local,
558 struct sk_buff *skb)
559{
560 struct ieee80211_hw *hw = &local->hw;
561 unsigned long flags;
562 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
563 int queue = info->hw_queue;
564
565 if (WARN_ON(!info->control.vif)) {
566 ieee80211_free_txskb(&local->hw, skb);
567 return;
568 }
569
570 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
571 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
572 false);
573 __skb_queue_tail(&local->pending[queue], skb);
574 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
Googlerb48fa912023-03-17 12:40:29 +0530575 false);
Googleraf606d22022-10-26 21:40:12 -0700576 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
577}
578
579void ieee80211_add_pending_skbs(struct ieee80211_local *local,
580 struct sk_buff_head *skbs)
581{
582 struct ieee80211_hw *hw = &local->hw;
583 struct sk_buff *skb;
584 unsigned long flags;
585 int queue, i;
586
587 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
588 while ((skb = skb_dequeue(skbs))) {
589 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
590
591 if (WARN_ON(!info->control.vif)) {
592 ieee80211_free_txskb(&local->hw, skb);
593 continue;
594 }
595
596 queue = info->hw_queue;
597
598 __ieee80211_stop_queue(hw, queue,
599 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
600 false);
601
602 __skb_queue_tail(&local->pending[queue], skb);
603 }
604
605 for (i = 0; i < hw->queues; i++)
606 __ieee80211_wake_queue(hw, i,
607 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
Googlerb48fa912023-03-17 12:40:29 +0530608 false);
Googleraf606d22022-10-26 21:40:12 -0700609 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
610}
611
612void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
613 unsigned long queues,
614 enum queue_stop_reason reason,
615 bool refcounted)
616{
617 struct ieee80211_local *local = hw_to_local(hw);
618 unsigned long flags;
619 int i;
620
621 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
622
623 for_each_set_bit(i, &queues, hw->queues)
624 __ieee80211_stop_queue(hw, i, reason, refcounted);
625
626 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
627}
628
629void ieee80211_stop_queues(struct ieee80211_hw *hw)
630{
631 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
632 IEEE80211_QUEUE_STOP_REASON_DRIVER,
633 false);
634}
635EXPORT_SYMBOL(ieee80211_stop_queues);
636
637int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
638{
639 struct ieee80211_local *local = hw_to_local(hw);
640 unsigned long flags;
641 int ret;
642
643 if (WARN_ON(queue >= hw->queues))
644 return true;
645
646 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
647 ret = test_bit(IEEE80211_QUEUE_STOP_REASON_DRIVER,
648 &local->queue_stop_reasons[queue]);
649 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
650 return ret;
651}
652EXPORT_SYMBOL(ieee80211_queue_stopped);
653
654void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
655 unsigned long queues,
656 enum queue_stop_reason reason,
657 bool refcounted)
658{
659 struct ieee80211_local *local = hw_to_local(hw);
660 unsigned long flags;
661 int i;
662
663 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
664
665 for_each_set_bit(i, &queues, hw->queues)
Googlerb48fa912023-03-17 12:40:29 +0530666 __ieee80211_wake_queue(hw, i, reason, refcounted);
Googleraf606d22022-10-26 21:40:12 -0700667
668 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
669}
670
671void ieee80211_wake_queues(struct ieee80211_hw *hw)
672{
673 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
674 IEEE80211_QUEUE_STOP_REASON_DRIVER,
675 false);
676}
677EXPORT_SYMBOL(ieee80211_wake_queues);
678
679static unsigned int
680ieee80211_get_vif_queues(struct ieee80211_local *local,
681 struct ieee80211_sub_if_data *sdata)
682{
683 unsigned int queues;
684
685 if (sdata && ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
686 int ac;
687
688 queues = 0;
689
690 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
691 queues |= BIT(sdata->vif.hw_queue[ac]);
692 if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE)
693 queues |= BIT(sdata->vif.cab_queue);
694 } else {
695 /* all queues */
696 queues = BIT(local->hw.queues) - 1;
697 }
698
699 return queues;
700}
701
702void __ieee80211_flush_queues(struct ieee80211_local *local,
703 struct ieee80211_sub_if_data *sdata,
704 unsigned int queues, bool drop)
705{
706 if (!local->ops->flush)
707 return;
708
709 /*
710 * If no queue was set, or if the HW doesn't support
711 * IEEE80211_HW_QUEUE_CONTROL - flush all queues
712 */
713 if (!queues || !ieee80211_hw_check(&local->hw, QUEUE_CONTROL))
714 queues = ieee80211_get_vif_queues(local, sdata);
715
716 ieee80211_stop_queues_by_reason(&local->hw, queues,
717 IEEE80211_QUEUE_STOP_REASON_FLUSH,
718 false);
719
720 drv_flush(local, sdata, queues, drop);
721
722 ieee80211_wake_queues_by_reason(&local->hw, queues,
723 IEEE80211_QUEUE_STOP_REASON_FLUSH,
724 false);
725}
726
727void ieee80211_flush_queues(struct ieee80211_local *local,
728 struct ieee80211_sub_if_data *sdata, bool drop)
729{
730 __ieee80211_flush_queues(local, sdata, 0, drop);
731}
732
733void ieee80211_stop_vif_queues(struct ieee80211_local *local,
734 struct ieee80211_sub_if_data *sdata,
735 enum queue_stop_reason reason)
736{
737 ieee80211_stop_queues_by_reason(&local->hw,
738 ieee80211_get_vif_queues(local, sdata),
739 reason, true);
740}
741
742void ieee80211_wake_vif_queues(struct ieee80211_local *local,
743 struct ieee80211_sub_if_data *sdata,
744 enum queue_stop_reason reason)
745{
746 ieee80211_wake_queues_by_reason(&local->hw,
747 ieee80211_get_vif_queues(local, sdata),
748 reason, true);
749}
750
751static void __iterate_interfaces(struct ieee80211_local *local,
752 u32 iter_flags,
753 void (*iterator)(void *data, u8 *mac,
754 struct ieee80211_vif *vif),
755 void *data)
756{
757 struct ieee80211_sub_if_data *sdata;
758 bool active_only = iter_flags & IEEE80211_IFACE_ITER_ACTIVE;
759
760 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
761 switch (sdata->vif.type) {
762 case NL80211_IFTYPE_MONITOR:
763 if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
764 continue;
765 break;
766 case NL80211_IFTYPE_AP_VLAN:
767 continue;
768 default:
769 break;
770 }
771 if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) &&
772 active_only && !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
773 continue;
Googlerb48fa912023-03-17 12:40:29 +0530774 if ((iter_flags & IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER) &&
775 !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
776 continue;
Googleraf606d22022-10-26 21:40:12 -0700777 if (ieee80211_sdata_running(sdata) || !active_only)
778 iterator(data, sdata->vif.addr,
779 &sdata->vif);
780 }
781
782 sdata = rcu_dereference_check(local->monitor_sdata,
783 lockdep_is_held(&local->iflist_mtx) ||
784 lockdep_rtnl_is_held());
785 if (sdata &&
786 (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only ||
787 sdata->flags & IEEE80211_SDATA_IN_DRIVER))
788 iterator(data, sdata->vif.addr, &sdata->vif);
789}
790
791void ieee80211_iterate_interfaces(
792 struct ieee80211_hw *hw, u32 iter_flags,
793 void (*iterator)(void *data, u8 *mac,
794 struct ieee80211_vif *vif),
795 void *data)
796{
797 struct ieee80211_local *local = hw_to_local(hw);
798
799 mutex_lock(&local->iflist_mtx);
800 __iterate_interfaces(local, iter_flags, iterator, data);
801 mutex_unlock(&local->iflist_mtx);
802}
803EXPORT_SYMBOL_GPL(ieee80211_iterate_interfaces);
804
805void ieee80211_iterate_active_interfaces_atomic(
806 struct ieee80211_hw *hw, u32 iter_flags,
807 void (*iterator)(void *data, u8 *mac,
808 struct ieee80211_vif *vif),
809 void *data)
810{
811 struct ieee80211_local *local = hw_to_local(hw);
812
813 rcu_read_lock();
814 __iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE,
815 iterator, data);
816 rcu_read_unlock();
817}
818EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
819
Googlerb48fa912023-03-17 12:40:29 +0530820void ieee80211_iterate_active_interfaces_mtx(
Googleraf606d22022-10-26 21:40:12 -0700821 struct ieee80211_hw *hw, u32 iter_flags,
822 void (*iterator)(void *data, u8 *mac,
823 struct ieee80211_vif *vif),
824 void *data)
825{
826 struct ieee80211_local *local = hw_to_local(hw);
827
Googlerb48fa912023-03-17 12:40:29 +0530828 lockdep_assert_wiphy(hw->wiphy);
Googleraf606d22022-10-26 21:40:12 -0700829
830 __iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE,
831 iterator, data);
832}
Googlerb48fa912023-03-17 12:40:29 +0530833EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_mtx);
Googleraf606d22022-10-26 21:40:12 -0700834
835static void __iterate_stations(struct ieee80211_local *local,
836 void (*iterator)(void *data,
837 struct ieee80211_sta *sta),
838 void *data)
839{
840 struct sta_info *sta;
841
842 list_for_each_entry_rcu(sta, &local->sta_list, list) {
843 if (!sta->uploaded)
844 continue;
845
846 iterator(data, &sta->sta);
847 }
848}
849
850void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
851 void (*iterator)(void *data,
852 struct ieee80211_sta *sta),
853 void *data)
854{
855 struct ieee80211_local *local = hw_to_local(hw);
856
857 rcu_read_lock();
858 __iterate_stations(local, iterator, data);
859 rcu_read_unlock();
860}
861EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic);
862
863struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev)
864{
865 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
866
867 if (!ieee80211_sdata_running(sdata) ||
868 !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
869 return NULL;
870 return &sdata->vif;
871}
872EXPORT_SYMBOL_GPL(wdev_to_ieee80211_vif);
873
874struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
875{
876 struct ieee80211_sub_if_data *sdata;
877
878 if (!vif)
879 return NULL;
880
881 sdata = vif_to_sdata(vif);
882
883 if (!ieee80211_sdata_running(sdata) ||
884 !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
885 return NULL;
886
887 return &sdata->wdev;
888}
889EXPORT_SYMBOL_GPL(ieee80211_vif_to_wdev);
890
Googlerb48fa912023-03-17 12:40:29 +0530891struct wireless_dev *ieee80211_vif_to_wdev_relaxed(struct ieee80211_vif *vif)
892{
893 struct ieee80211_sub_if_data *sdata;
894
895 if (!vif)
896 return NULL;
897
898 sdata = vif_to_sdata(vif);
899
900 if (sdata)
901 return &sdata->wdev;
902
903 return NULL;
904}
905EXPORT_SYMBOL(ieee80211_vif_to_wdev_relaxed);
906
Googleraf606d22022-10-26 21:40:12 -0700907/*
908 * Nothing should have been stuffed into the workqueue during
909 * the suspend->resume cycle. Since we can't check each caller
910 * of this function if we are already quiescing / suspended,
911 * check here and don't WARN since this can actually happen when
912 * the rx path (for example) is racing against __ieee80211_suspend
913 * and suspending / quiescing was set after the rx path checked
914 * them.
915 */
916static bool ieee80211_can_queue_work(struct ieee80211_local *local)
917{
918 if (local->quiescing || (local->suspended && !local->resuming)) {
919 pr_warn("queueing ieee80211 work while going to suspend\n");
920 return false;
921 }
922
923 return true;
924}
925
926void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work)
927{
928 struct ieee80211_local *local = hw_to_local(hw);
929
930 if (!ieee80211_can_queue_work(local))
931 return;
932
933 queue_work(local->workqueue, work);
934}
935EXPORT_SYMBOL(ieee80211_queue_work);
936
937void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
938 struct delayed_work *dwork,
939 unsigned long delay)
940{
941 struct ieee80211_local *local = hw_to_local(hw);
942
943 if (!ieee80211_can_queue_work(local))
944 return;
945
946 queue_delayed_work(local->workqueue, dwork, delay);
947}
948EXPORT_SYMBOL(ieee80211_queue_delayed_work);
949
Googlerb48fa912023-03-17 12:40:29 +0530950static void ieee80211_parse_extension_element(u32 *crc,
951 const struct element *elem,
952 struct ieee802_11_elems *elems)
953{
954 const void *data = elem->data + 1;
955 u8 len = elem->datalen - 1;
956
957 switch (elem->data[0]) {
958 case WLAN_EID_EXT_HE_MU_EDCA:
959 if (len == sizeof(*elems->mu_edca_param_set)) {
960 elems->mu_edca_param_set = data;
961 if (crc)
962 *crc = crc32_be(*crc, (void *)elem,
963 elem->datalen + 2);
964 }
965 break;
966 case WLAN_EID_EXT_HE_CAPABILITY:
967 elems->he_cap = data;
968 elems->he_cap_len = len;
969 break;
970 case WLAN_EID_EXT_HE_OPERATION:
971 if (len >= sizeof(*elems->he_operation) &&
972 len == ieee80211_he_oper_size(data) - 1) {
973 if (crc)
974 *crc = crc32_be(*crc, (void *)elem,
975 elem->datalen + 2);
976 elems->he_operation = data;
977 }
978 break;
979 case WLAN_EID_EXT_UORA:
980 if (len == 1)
981 elems->uora_element = data;
982 break;
983 case WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME:
984 if (len == 3)
985 elems->max_channel_switch_time = data;
986 break;
987 case WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION:
988 if (len == sizeof(*elems->mbssid_config_ie))
989 elems->mbssid_config_ie = data;
990 break;
991 case WLAN_EID_EXT_HE_SPR:
992 if (len >= sizeof(*elems->he_spr) &&
993 len >= ieee80211_he_spr_size(data))
994 elems->he_spr = data;
995 break;
996 case WLAN_EID_EXT_HE_6GHZ_CAPA:
997 if (len == sizeof(*elems->he_6ghz_capa))
998 elems->he_6ghz_capa = data;
999 break;
1000 }
1001}
1002
Googler9398cc32022-12-02 17:21:52 +08001003static u32
1004_ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
1005 struct ieee802_11_elems *elems,
1006 u64 filter, u32 crc,
1007 const struct element *check_inherit)
Googleraf606d22022-10-26 21:40:12 -07001008{
Googler9398cc32022-12-02 17:21:52 +08001009 const struct element *elem;
Googleraf606d22022-10-26 21:40:12 -07001010 bool calc_crc = filter != 0;
1011 DECLARE_BITMAP(seen_elems, 256);
1012 const u8 *ie;
1013
1014 bitmap_zero(seen_elems, 256);
Googleraf606d22022-10-26 21:40:12 -07001015
Googler9398cc32022-12-02 17:21:52 +08001016 for_each_element(elem, start, len) {
Googleraf606d22022-10-26 21:40:12 -07001017 bool elem_parse_failed;
Googler9398cc32022-12-02 17:21:52 +08001018 u8 id = elem->id;
1019 u8 elen = elem->datalen;
1020 const u8 *pos = elem->data;
Googleraf606d22022-10-26 21:40:12 -07001021
Googler9398cc32022-12-02 17:21:52 +08001022 if (check_inherit &&
1023 !cfg80211_is_element_inherited(elem,
1024 check_inherit))
1025 continue;
Googleraf606d22022-10-26 21:40:12 -07001026
1027 switch (id) {
1028 case WLAN_EID_SSID:
1029 case WLAN_EID_SUPP_RATES:
1030 case WLAN_EID_FH_PARAMS:
1031 case WLAN_EID_DS_PARAMS:
1032 case WLAN_EID_CF_PARAMS:
1033 case WLAN_EID_TIM:
1034 case WLAN_EID_IBSS_PARAMS:
1035 case WLAN_EID_CHALLENGE:
1036 case WLAN_EID_RSN:
1037 case WLAN_EID_ERP_INFO:
1038 case WLAN_EID_EXT_SUPP_RATES:
1039 case WLAN_EID_HT_CAPABILITY:
1040 case WLAN_EID_HT_OPERATION:
1041 case WLAN_EID_VHT_CAPABILITY:
1042 case WLAN_EID_VHT_OPERATION:
1043 case WLAN_EID_MESH_ID:
1044 case WLAN_EID_MESH_CONFIG:
1045 case WLAN_EID_PEER_MGMT:
1046 case WLAN_EID_PREQ:
1047 case WLAN_EID_PREP:
1048 case WLAN_EID_PERR:
1049 case WLAN_EID_RANN:
1050 case WLAN_EID_CHANNEL_SWITCH:
1051 case WLAN_EID_EXT_CHANSWITCH_ANN:
1052 case WLAN_EID_COUNTRY:
1053 case WLAN_EID_PWR_CONSTRAINT:
1054 case WLAN_EID_TIMEOUT_INTERVAL:
1055 case WLAN_EID_SECONDARY_CHANNEL_OFFSET:
1056 case WLAN_EID_WIDE_BW_CHANNEL_SWITCH:
1057 case WLAN_EID_CHAN_SWITCH_PARAM:
1058 case WLAN_EID_EXT_CAPABILITY:
1059 case WLAN_EID_CHAN_SWITCH_TIMING:
1060 case WLAN_EID_LINK_ID:
Googler9398cc32022-12-02 17:21:52 +08001061 case WLAN_EID_BSS_MAX_IDLE_PERIOD:
Googlerb48fa912023-03-17 12:40:29 +05301062 case WLAN_EID_RSNX:
1063 case WLAN_EID_S1G_BCN_COMPAT:
1064 case WLAN_EID_S1G_CAPABILITIES:
1065 case WLAN_EID_S1G_OPERATION:
1066 case WLAN_EID_AID_RESPONSE:
1067 case WLAN_EID_S1G_SHORT_BCN_INTERVAL:
Googleraf606d22022-10-26 21:40:12 -07001068 /*
1069 * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible
1070 * that if the content gets bigger it might be needed more than once
1071 */
1072 if (test_bit(id, seen_elems)) {
1073 elems->parse_error = true;
Googleraf606d22022-10-26 21:40:12 -07001074 continue;
1075 }
1076 break;
1077 }
1078
1079 if (calc_crc && id < 64 && (filter & (1ULL << id)))
1080 crc = crc32_be(crc, pos - 2, elen + 2);
1081
1082 elem_parse_failed = false;
1083
1084 switch (id) {
1085 case WLAN_EID_LINK_ID:
1086 if (elen + 2 != sizeof(struct ieee80211_tdls_lnkie)) {
1087 elem_parse_failed = true;
1088 break;
1089 }
1090 elems->lnk_id = (void *)(pos - 2);
1091 break;
1092 case WLAN_EID_CHAN_SWITCH_TIMING:
1093 if (elen != sizeof(struct ieee80211_ch_switch_timing)) {
1094 elem_parse_failed = true;
1095 break;
1096 }
1097 elems->ch_sw_timing = (void *)pos;
1098 break;
1099 case WLAN_EID_EXT_CAPABILITY:
1100 elems->ext_capab = pos;
1101 elems->ext_capab_len = elen;
1102 break;
1103 case WLAN_EID_SSID:
1104 elems->ssid = pos;
1105 elems->ssid_len = elen;
1106 break;
1107 case WLAN_EID_SUPP_RATES:
1108 elems->supp_rates = pos;
1109 elems->supp_rates_len = elen;
1110 break;
1111 case WLAN_EID_DS_PARAMS:
1112 if (elen >= 1)
1113 elems->ds_params = pos;
1114 else
1115 elem_parse_failed = true;
1116 break;
1117 case WLAN_EID_TIM:
1118 if (elen >= sizeof(struct ieee80211_tim_ie)) {
1119 elems->tim = (void *)pos;
1120 elems->tim_len = elen;
1121 } else
1122 elem_parse_failed = true;
1123 break;
Googlerb48fa912023-03-17 12:40:29 +05301124 case WLAN_EID_CHALLENGE:
1125 elems->challenge = pos;
1126 elems->challenge_len = elen;
1127 break;
Googleraf606d22022-10-26 21:40:12 -07001128 case WLAN_EID_VENDOR_SPECIFIC:
1129 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
1130 pos[2] == 0xf2) {
1131 /* Microsoft OUI (00:50:F2) */
1132
1133 if (calc_crc)
1134 crc = crc32_be(crc, pos - 2, elen + 2);
1135
1136 if (elen >= 5 && pos[3] == 2) {
1137 /* OUI Type 2 - WMM IE */
1138 if (pos[4] == 0) {
1139 elems->wmm_info = pos;
1140 elems->wmm_info_len = elen;
1141 } else if (pos[4] == 1) {
1142 elems->wmm_param = pos;
1143 elems->wmm_param_len = elen;
1144 }
1145 }
1146 }
1147 break;
1148 case WLAN_EID_RSN:
1149 elems->rsn = pos;
1150 elems->rsn_len = elen;
1151 break;
1152 case WLAN_EID_ERP_INFO:
1153 if (elen >= 1)
1154 elems->erp_info = pos;
1155 else
1156 elem_parse_failed = true;
1157 break;
1158 case WLAN_EID_EXT_SUPP_RATES:
1159 elems->ext_supp_rates = pos;
1160 elems->ext_supp_rates_len = elen;
1161 break;
1162 case WLAN_EID_HT_CAPABILITY:
1163 if (elen >= sizeof(struct ieee80211_ht_cap))
1164 elems->ht_cap_elem = (void *)pos;
1165 else
1166 elem_parse_failed = true;
1167 break;
1168 case WLAN_EID_HT_OPERATION:
1169 if (elen >= sizeof(struct ieee80211_ht_operation))
1170 elems->ht_operation = (void *)pos;
1171 else
1172 elem_parse_failed = true;
1173 break;
1174 case WLAN_EID_VHT_CAPABILITY:
1175 if (elen >= sizeof(struct ieee80211_vht_cap))
1176 elems->vht_cap_elem = (void *)pos;
1177 else
1178 elem_parse_failed = true;
1179 break;
1180 case WLAN_EID_VHT_OPERATION:
1181 if (elen >= sizeof(struct ieee80211_vht_operation)) {
1182 elems->vht_operation = (void *)pos;
1183 if (calc_crc)
1184 crc = crc32_be(crc, pos - 2, elen + 2);
1185 break;
1186 }
1187 elem_parse_failed = true;
1188 break;
1189 case WLAN_EID_OPMODE_NOTIF:
1190 if (elen > 0) {
1191 elems->opmode_notif = pos;
1192 if (calc_crc)
1193 crc = crc32_be(crc, pos - 2, elen + 2);
1194 break;
1195 }
1196 elem_parse_failed = true;
1197 break;
1198 case WLAN_EID_MESH_ID:
1199 elems->mesh_id = pos;
1200 elems->mesh_id_len = elen;
1201 break;
1202 case WLAN_EID_MESH_CONFIG:
1203 if (elen >= sizeof(struct ieee80211_meshconf_ie))
1204 elems->mesh_config = (void *)pos;
1205 else
1206 elem_parse_failed = true;
1207 break;
1208 case WLAN_EID_PEER_MGMT:
1209 elems->peering = pos;
1210 elems->peering_len = elen;
1211 break;
1212 case WLAN_EID_MESH_AWAKE_WINDOW:
1213 if (elen >= 2)
1214 elems->awake_window = (void *)pos;
1215 break;
1216 case WLAN_EID_PREQ:
1217 elems->preq = pos;
1218 elems->preq_len = elen;
1219 break;
1220 case WLAN_EID_PREP:
1221 elems->prep = pos;
1222 elems->prep_len = elen;
1223 break;
1224 case WLAN_EID_PERR:
1225 elems->perr = pos;
1226 elems->perr_len = elen;
1227 break;
1228 case WLAN_EID_RANN:
1229 if (elen >= sizeof(struct ieee80211_rann_ie))
1230 elems->rann = (void *)pos;
1231 else
1232 elem_parse_failed = true;
1233 break;
1234 case WLAN_EID_CHANNEL_SWITCH:
1235 if (elen != sizeof(struct ieee80211_channel_sw_ie)) {
1236 elem_parse_failed = true;
1237 break;
1238 }
1239 elems->ch_switch_ie = (void *)pos;
1240 break;
1241 case WLAN_EID_EXT_CHANSWITCH_ANN:
1242 if (elen != sizeof(struct ieee80211_ext_chansw_ie)) {
1243 elem_parse_failed = true;
1244 break;
1245 }
1246 elems->ext_chansw_ie = (void *)pos;
1247 break;
1248 case WLAN_EID_SECONDARY_CHANNEL_OFFSET:
1249 if (elen != sizeof(struct ieee80211_sec_chan_offs_ie)) {
1250 elem_parse_failed = true;
1251 break;
1252 }
1253 elems->sec_chan_offs = (void *)pos;
1254 break;
1255 case WLAN_EID_CHAN_SWITCH_PARAM:
1256 if (elen !=
1257 sizeof(*elems->mesh_chansw_params_ie)) {
1258 elem_parse_failed = true;
1259 break;
1260 }
1261 elems->mesh_chansw_params_ie = (void *)pos;
1262 break;
1263 case WLAN_EID_WIDE_BW_CHANNEL_SWITCH:
1264 if (!action ||
1265 elen != sizeof(*elems->wide_bw_chansw_ie)) {
1266 elem_parse_failed = true;
1267 break;
1268 }
1269 elems->wide_bw_chansw_ie = (void *)pos;
1270 break;
1271 case WLAN_EID_CHANNEL_SWITCH_WRAPPER:
1272 if (action) {
1273 elem_parse_failed = true;
1274 break;
1275 }
1276 /*
1277 * This is a bit tricky, but as we only care about
1278 * the wide bandwidth channel switch element, so
1279 * just parse it out manually.
1280 */
1281 ie = cfg80211_find_ie(WLAN_EID_WIDE_BW_CHANNEL_SWITCH,
1282 pos, elen);
1283 if (ie) {
1284 if (ie[1] == sizeof(*elems->wide_bw_chansw_ie))
1285 elems->wide_bw_chansw_ie =
1286 (void *)(ie + 2);
1287 else
1288 elem_parse_failed = true;
1289 }
1290 break;
1291 case WLAN_EID_COUNTRY:
1292 elems->country_elem = pos;
1293 elems->country_elem_len = elen;
1294 break;
1295 case WLAN_EID_PWR_CONSTRAINT:
1296 if (elen != 1) {
1297 elem_parse_failed = true;
1298 break;
1299 }
1300 elems->pwr_constr_elem = pos;
1301 break;
1302 case WLAN_EID_CISCO_VENDOR_SPECIFIC:
1303 /* Lots of different options exist, but we only care
1304 * about the Dynamic Transmit Power Control element.
1305 * First check for the Cisco OUI, then for the DTPC
1306 * tag (0x00).
1307 */
1308 if (elen < 4) {
1309 elem_parse_failed = true;
1310 break;
1311 }
1312
1313 if (pos[0] != 0x00 || pos[1] != 0x40 ||
1314 pos[2] != 0x96 || pos[3] != 0x00)
1315 break;
1316
1317 if (elen != 6) {
1318 elem_parse_failed = true;
1319 break;
1320 }
1321
1322 if (calc_crc)
1323 crc = crc32_be(crc, pos - 2, elen + 2);
1324
1325 elems->cisco_dtpc_elem = pos;
1326 break;
Googler9398cc32022-12-02 17:21:52 +08001327 case WLAN_EID_ADDBA_EXT:
1328 if (elen != sizeof(struct ieee80211_addba_ext_ie)) {
1329 elem_parse_failed = true;
1330 break;
1331 }
1332 elems->addba_ext_ie = (void *)pos;
1333 break;
Googleraf606d22022-10-26 21:40:12 -07001334 case WLAN_EID_TIMEOUT_INTERVAL:
1335 if (elen >= sizeof(struct ieee80211_timeout_interval_ie))
1336 elems->timeout_int = (void *)pos;
1337 else
1338 elem_parse_failed = true;
1339 break;
Googler9398cc32022-12-02 17:21:52 +08001340 case WLAN_EID_BSS_MAX_IDLE_PERIOD:
1341 if (elen >= sizeof(*elems->max_idle_period_ie))
1342 elems->max_idle_period_ie = (void *)pos;
1343 break;
Googlerb48fa912023-03-17 12:40:29 +05301344 case WLAN_EID_RSNX:
1345 elems->rsnx = pos;
1346 elems->rsnx_len = elen;
1347 break;
1348 case WLAN_EID_TX_POWER_ENVELOPE:
1349 if (elen < 1 ||
1350 elen > sizeof(struct ieee80211_tx_pwr_env))
Googler9398cc32022-12-02 17:21:52 +08001351 break;
Googlerb48fa912023-03-17 12:40:29 +05301352
1353 if (elems->tx_pwr_env_num >= ARRAY_SIZE(elems->tx_pwr_env))
1354 break;
1355
1356 elems->tx_pwr_env[elems->tx_pwr_env_num] = (void *)pos;
1357 elems->tx_pwr_env_len[elems->tx_pwr_env_num] = elen;
1358 elems->tx_pwr_env_num++;
1359 break;
1360 case WLAN_EID_EXTENSION:
1361 ieee80211_parse_extension_element(calc_crc ?
1362 &crc : NULL,
1363 elem, elems);
1364 break;
1365 case WLAN_EID_S1G_CAPABILITIES:
1366 if (elen == sizeof(*elems->s1g_capab))
1367 elems->s1g_capab = (void *)pos;
1368 else
1369 elem_parse_failed = true;
1370 break;
1371 case WLAN_EID_S1G_OPERATION:
1372 if (elen == sizeof(*elems->s1g_oper))
1373 elems->s1g_oper = (void *)pos;
1374 else
1375 elem_parse_failed = true;
1376 break;
1377 case WLAN_EID_S1G_BCN_COMPAT:
1378 if (elen == sizeof(*elems->s1g_bcn_compat))
1379 elems->s1g_bcn_compat = (void *)pos;
1380 else
1381 elem_parse_failed = true;
1382 break;
1383 case WLAN_EID_AID_RESPONSE:
1384 if (elen == sizeof(struct ieee80211_aid_response_ie))
1385 elems->aid_resp = (void *)pos;
1386 else
1387 elem_parse_failed = true;
Googler9398cc32022-12-02 17:21:52 +08001388 break;
Googleraf606d22022-10-26 21:40:12 -07001389 default:
1390 break;
1391 }
1392
1393 if (elem_parse_failed)
1394 elems->parse_error = true;
1395 else
1396 __set_bit(id, seen_elems);
Googleraf606d22022-10-26 21:40:12 -07001397 }
1398
Googler9398cc32022-12-02 17:21:52 +08001399 if (!for_each_element_completed(elem, start, len))
Googleraf606d22022-10-26 21:40:12 -07001400 elems->parse_error = true;
1401
1402 return crc;
1403}
1404
Googler9398cc32022-12-02 17:21:52 +08001405static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
1406 struct ieee802_11_elems *elems,
1407 u8 *transmitter_bssid,
1408 u8 *bss_bssid,
1409 u8 *nontransmitted_profile)
1410{
1411 const struct element *elem, *sub;
1412 size_t profile_len = 0;
1413 bool found = false;
1414
1415 if (!bss_bssid || !transmitter_bssid)
1416 return profile_len;
1417
1418 for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
1419 if (elem->datalen < 2)
1420 continue;
Googler9398cc32022-12-02 17:21:52 +08001421
1422 for_each_element(sub, elem->data + 1, elem->datalen - 1) {
1423 u8 new_bssid[ETH_ALEN];
1424 const u8 *index;
1425
1426 if (sub->id != 0 || sub->datalen < 4) {
1427 /* not a valid BSS profile */
1428 continue;
1429 }
1430
1431 if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
1432 sub->data[1] != 2) {
1433 /* The first element of the
1434 * Nontransmitted BSSID Profile is not
1435 * the Nontransmitted BSSID Capability
1436 * element.
1437 */
1438 continue;
1439 }
1440
1441 memset(nontransmitted_profile, 0, len);
1442 profile_len = cfg80211_merge_profile(start, len,
1443 elem,
1444 sub,
1445 nontransmitted_profile,
1446 len);
1447
1448 /* found a Nontransmitted BSSID Profile */
1449 index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
1450 nontransmitted_profile,
1451 profile_len);
1452 if (!index || index[1] < 1 || index[2] == 0) {
1453 /* Invalid MBSSID Index element */
1454 continue;
1455 }
1456
1457 cfg80211_gen_new_bssid(transmitter_bssid,
1458 elem->data[0],
1459 index[2],
1460 new_bssid);
1461 if (ether_addr_equal(new_bssid, bss_bssid)) {
1462 found = true;
1463 elems->bssid_index_len = index[1];
1464 elems->bssid_index = (void *)&index[2];
1465 break;
1466 }
1467 }
1468 }
1469
1470 return found ? profile_len : 0;
1471}
1472
1473u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
1474 struct ieee802_11_elems *elems,
1475 u64 filter, u32 crc, u8 *transmitter_bssid,
1476 u8 *bss_bssid)
1477{
1478 const struct element *non_inherit = NULL;
1479 u8 *nontransmitted_profile;
1480 int nontransmitted_profile_len = 0;
1481
1482 memset(elems, 0, sizeof(*elems));
1483 elems->ie_start = start;
1484 elems->total_len = len;
1485
1486 nontransmitted_profile = kmalloc(len, GFP_ATOMIC);
1487 if (nontransmitted_profile) {
1488 nontransmitted_profile_len =
1489 ieee802_11_find_bssid_profile(start, len, elems,
1490 transmitter_bssid,
1491 bss_bssid,
1492 nontransmitted_profile);
1493 non_inherit =
1494 cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
1495 nontransmitted_profile,
1496 nontransmitted_profile_len);
Googler9398cc32022-12-02 17:21:52 +08001497 }
1498
1499 crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter,
1500 crc, non_inherit);
1501
1502 /* Override with nontransmitted profile, if found */
1503 if (nontransmitted_profile_len)
1504 _ieee802_11_parse_elems_crc(nontransmitted_profile,
1505 nontransmitted_profile_len,
1506 action, elems, 0, 0, NULL);
1507
1508 if (elems->tim && !elems->parse_error) {
1509 const struct ieee80211_tim_ie *tim_ie = elems->tim;
1510
1511 elems->dtim_period = tim_ie->dtim_period;
1512 elems->dtim_count = tim_ie->dtim_count;
1513 }
1514
1515 /* Override DTIM period and count if needed */
1516 if (elems->bssid_index &&
1517 elems->bssid_index_len >=
1518 offsetofend(struct ieee80211_bssid_index, dtim_period))
1519 elems->dtim_period = elems->bssid_index->dtim_period;
1520
1521 if (elems->bssid_index &&
1522 elems->bssid_index_len >=
1523 offsetofend(struct ieee80211_bssid_index, dtim_count))
1524 elems->dtim_count = elems->bssid_index->dtim_count;
1525
Googlerb48fa912023-03-17 12:40:29 +05301526 kfree(nontransmitted_profile);
Googler9398cc32022-12-02 17:21:52 +08001527
1528 return crc;
1529}
1530
1531void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
1532 struct ieee80211_tx_queue_params
1533 *qparam, int ac)
1534{
1535 struct ieee80211_chanctx_conf *chanctx_conf;
1536 const struct ieee80211_reg_rule *rrule;
1537 const struct ieee80211_wmm_ac *wmm_ac;
1538 u16 center_freq = 0;
1539
1540 if (sdata->vif.type != NL80211_IFTYPE_AP &&
1541 sdata->vif.type != NL80211_IFTYPE_STATION)
1542 return;
1543
1544 rcu_read_lock();
1545 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1546 if (chanctx_conf)
1547 center_freq = chanctx_conf->def.chan->center_freq;
1548
1549 if (!center_freq) {
1550 rcu_read_unlock();
1551 return;
1552 }
1553
1554 rrule = freq_reg_info(sdata->wdev.wiphy, MHZ_TO_KHZ(center_freq));
1555
1556 if (IS_ERR_OR_NULL(rrule) || !rrule->has_wmm) {
1557 rcu_read_unlock();
1558 return;
1559 }
1560
1561 if (sdata->vif.type == NL80211_IFTYPE_AP)
1562 wmm_ac = &rrule->wmm_rule.ap[ac];
1563 else
1564 wmm_ac = &rrule->wmm_rule.client[ac];
1565 qparam->cw_min = max_t(u16, qparam->cw_min, wmm_ac->cw_min);
1566 qparam->cw_max = max_t(u16, qparam->cw_max, wmm_ac->cw_max);
1567 qparam->aifs = max_t(u8, qparam->aifs, wmm_ac->aifsn);
1568 qparam->txop = min_t(u16, qparam->txop, wmm_ac->cot / 32);
1569 rcu_read_unlock();
1570}
1571
Googleraf606d22022-10-26 21:40:12 -07001572void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1573 bool bss_notify, bool enable_qos)
1574{
1575 struct ieee80211_local *local = sdata->local;
1576 struct ieee80211_tx_queue_params qparam;
1577 struct ieee80211_chanctx_conf *chanctx_conf;
1578 int ac;
1579 bool use_11b;
1580 bool is_ocb; /* Use another EDCA parameters if dot11OCBActivated=true */
1581 int aCWmin, aCWmax;
1582
1583 if (!local->ops->conf_tx)
1584 return;
1585
1586 if (local->hw.queues < IEEE80211_NUM_ACS)
1587 return;
1588
1589 memset(&qparam, 0, sizeof(qparam));
1590
1591 rcu_read_lock();
1592 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
1593 use_11b = (chanctx_conf &&
1594 chanctx_conf->def.chan->band == NL80211_BAND_2GHZ) &&
1595 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
1596 rcu_read_unlock();
1597
1598 is_ocb = (sdata->vif.type == NL80211_IFTYPE_OCB);
1599
1600 /* Set defaults according to 802.11-2007 Table 7-37 */
1601 aCWmax = 1023;
1602 if (use_11b)
1603 aCWmin = 31;
1604 else
1605 aCWmin = 15;
1606
1607 /* Confiure old 802.11b/g medium access rules. */
1608 qparam.cw_max = aCWmax;
1609 qparam.cw_min = aCWmin;
1610 qparam.txop = 0;
1611 qparam.aifs = 2;
1612
1613 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
1614 /* Update if QoS is enabled. */
1615 if (enable_qos) {
1616 switch (ac) {
1617 case IEEE80211_AC_BK:
1618 qparam.cw_max = aCWmax;
1619 qparam.cw_min = aCWmin;
1620 qparam.txop = 0;
1621 if (is_ocb)
1622 qparam.aifs = 9;
1623 else
1624 qparam.aifs = 7;
1625 break;
1626 /* never happens but let's not leave undefined */
1627 default:
1628 case IEEE80211_AC_BE:
1629 qparam.cw_max = aCWmax;
1630 qparam.cw_min = aCWmin;
1631 qparam.txop = 0;
1632 if (is_ocb)
1633 qparam.aifs = 6;
1634 else
1635 qparam.aifs = 3;
1636 break;
1637 case IEEE80211_AC_VI:
1638 qparam.cw_max = aCWmin;
1639 qparam.cw_min = (aCWmin + 1) / 2 - 1;
1640 if (is_ocb)
1641 qparam.txop = 0;
1642 else if (use_11b)
1643 qparam.txop = 6016/32;
1644 else
1645 qparam.txop = 3008/32;
1646
1647 if (is_ocb)
1648 qparam.aifs = 3;
1649 else
1650 qparam.aifs = 2;
1651 break;
1652 case IEEE80211_AC_VO:
1653 qparam.cw_max = (aCWmin + 1) / 2 - 1;
1654 qparam.cw_min = (aCWmin + 1) / 4 - 1;
1655 if (is_ocb)
1656 qparam.txop = 0;
1657 else if (use_11b)
1658 qparam.txop = 3264/32;
1659 else
1660 qparam.txop = 1504/32;
1661 qparam.aifs = 2;
1662 break;
1663 }
1664 }
Googler9398cc32022-12-02 17:21:52 +08001665 ieee80211_regulatory_limit_wmm_params(sdata, &qparam, ac);
Googleraf606d22022-10-26 21:40:12 -07001666
1667 qparam.uapsd = false;
1668
1669 sdata->tx_conf[ac] = qparam;
1670 drv_conf_tx(local, sdata, ac, &qparam);
1671 }
1672
1673 if (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
1674 sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
1675 sdata->vif.type != NL80211_IFTYPE_NAN) {
1676 sdata->vif.bss_conf.qos = enable_qos;
1677 if (bss_notify)
1678 ieee80211_bss_info_change_notify(sdata,
1679 BSS_CHANGED_QOS);
1680 }
1681}
1682
1683void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1684 u16 transaction, u16 auth_alg, u16 status,
1685 const u8 *extra, size_t extra_len, const u8 *da,
1686 const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx,
1687 u32 tx_flags)
1688{
1689 struct ieee80211_local *local = sdata->local;
1690 struct sk_buff *skb;
1691 struct ieee80211_mgmt *mgmt;
1692 int err;
1693
1694 /* 24 + 6 = header + auth_algo + auth_transaction + status_code */
1695 skb = dev_alloc_skb(local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN +
1696 24 + 6 + extra_len + IEEE80211_WEP_ICV_LEN);
1697 if (!skb)
1698 return;
1699
1700 skb_reserve(skb, local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN);
1701
Googler9398cc32022-12-02 17:21:52 +08001702 mgmt = skb_put_zero(skb, 24 + 6);
Googleraf606d22022-10-26 21:40:12 -07001703 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1704 IEEE80211_STYPE_AUTH);
1705 memcpy(mgmt->da, da, ETH_ALEN);
1706 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
1707 memcpy(mgmt->bssid, bssid, ETH_ALEN);
1708 mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg);
1709 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction);
1710 mgmt->u.auth.status_code = cpu_to_le16(status);
1711 if (extra)
Googler9398cc32022-12-02 17:21:52 +08001712 skb_put_data(skb, extra, extra_len);
Googleraf606d22022-10-26 21:40:12 -07001713
1714 if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
1715 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
1716 err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
1717 WARN_ON(err);
1718 }
1719
1720 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
1721 tx_flags;
1722 ieee80211_tx_skb(sdata, skb);
1723}
1724
1725void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
Googler9398cc32022-12-02 17:21:52 +08001726 const u8 *da, const u8 *bssid,
1727 u16 stype, u16 reason,
Googleraf606d22022-10-26 21:40:12 -07001728 bool send_frame, u8 *frame_buf)
1729{
1730 struct ieee80211_local *local = sdata->local;
1731 struct sk_buff *skb;
1732 struct ieee80211_mgmt *mgmt = (void *)frame_buf;
1733
1734 /* build frame */
1735 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
1736 mgmt->duration = 0; /* initialize only */
1737 mgmt->seq_ctrl = 0; /* initialize only */
Googler9398cc32022-12-02 17:21:52 +08001738 memcpy(mgmt->da, da, ETH_ALEN);
Googleraf606d22022-10-26 21:40:12 -07001739 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
1740 memcpy(mgmt->bssid, bssid, ETH_ALEN);
1741 /* u.deauth.reason_code == u.disassoc.reason_code */
1742 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
1743
1744 if (send_frame) {
1745 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
1746 IEEE80211_DEAUTH_FRAME_LEN);
1747 if (!skb)
1748 return;
1749
1750 skb_reserve(skb, local->hw.extra_tx_headroom);
1751
1752 /* copy in frame */
Googler9398cc32022-12-02 17:21:52 +08001753 skb_put_data(skb, mgmt, IEEE80211_DEAUTH_FRAME_LEN);
Googleraf606d22022-10-26 21:40:12 -07001754
1755 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
1756 !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
1757 IEEE80211_SKB_CB(skb)->flags |=
1758 IEEE80211_TX_INTFL_DONT_ENCRYPT;
1759
1760 ieee80211_tx_skb(sdata, skb);
1761 }
1762}
1763
Googler9398cc32022-12-02 17:21:52 +08001764static u8 *ieee80211_write_he_6ghz_cap(u8 *pos, __le16 cap, u8 *end)
1765{
1766 if ((end - pos) < 5)
1767 return pos;
1768
1769 *pos++ = WLAN_EID_EXTENSION;
1770 *pos++ = 1 + sizeof(cap);
1771 *pos++ = WLAN_EID_EXT_HE_6GHZ_CAPA;
1772 memcpy(pos, &cap, sizeof(cap));
1773
1774 return pos + 2;
1775}
1776
1777static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
Googleraf606d22022-10-26 21:40:12 -07001778 u8 *buffer, size_t buffer_len,
1779 const u8 *ie, size_t ie_len,
1780 enum nl80211_band band,
1781 u32 rate_mask,
1782 struct cfg80211_chan_def *chandef,
Googler9398cc32022-12-02 17:21:52 +08001783 size_t *offset, u32 flags)
Googleraf606d22022-10-26 21:40:12 -07001784{
Googler9398cc32022-12-02 17:21:52 +08001785 struct ieee80211_local *local = sdata->local;
Googleraf606d22022-10-26 21:40:12 -07001786 struct ieee80211_supported_band *sband;
Googler9398cc32022-12-02 17:21:52 +08001787 const struct ieee80211_sta_he_cap *he_cap;
Googleraf606d22022-10-26 21:40:12 -07001788 u8 *pos = buffer, *end = buffer + buffer_len;
1789 size_t noffset;
1790 int supp_rates_len, i;
1791 u8 rates[32];
1792 int num_rates;
1793 int ext_rates_len;
1794 int shift;
1795 u32 rate_flags;
1796 bool have_80mhz = false;
1797
1798 *offset = 0;
1799
1800 sband = local->hw.wiphy->bands[band];
1801 if (WARN_ON_ONCE(!sband))
1802 return 0;
1803
1804 rate_flags = ieee80211_chandef_rate_flags(chandef);
1805 shift = ieee80211_chandef_get_shift(chandef);
1806
1807 num_rates = 0;
1808 for (i = 0; i < sband->n_bitrates; i++) {
1809 if ((BIT(i) & rate_mask) == 0)
1810 continue; /* skip rate */
1811 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
1812 continue;
1813
1814 rates[num_rates++] =
1815 (u8) DIV_ROUND_UP(sband->bitrates[i].bitrate,
1816 (1 << shift) * 5);
1817 }
1818
1819 supp_rates_len = min_t(int, num_rates, 8);
1820
1821 if (end - pos < 2 + supp_rates_len)
1822 goto out_err;
1823 *pos++ = WLAN_EID_SUPP_RATES;
1824 *pos++ = supp_rates_len;
1825 memcpy(pos, rates, supp_rates_len);
1826 pos += supp_rates_len;
1827
1828 /* insert "request information" if in custom IEs */
1829 if (ie && ie_len) {
1830 static const u8 before_extrates[] = {
1831 WLAN_EID_SSID,
1832 WLAN_EID_SUPP_RATES,
1833 WLAN_EID_REQUEST,
1834 };
1835 noffset = ieee80211_ie_split(ie, ie_len,
1836 before_extrates,
1837 ARRAY_SIZE(before_extrates),
1838 *offset);
1839 if (end - pos < noffset - *offset)
1840 goto out_err;
1841 memcpy(pos, ie + *offset, noffset - *offset);
1842 pos += noffset - *offset;
1843 *offset = noffset;
1844 }
1845
1846 ext_rates_len = num_rates - supp_rates_len;
1847 if (ext_rates_len > 0) {
1848 if (end - pos < 2 + ext_rates_len)
1849 goto out_err;
1850 *pos++ = WLAN_EID_EXT_SUPP_RATES;
1851 *pos++ = ext_rates_len;
1852 memcpy(pos, rates + supp_rates_len, ext_rates_len);
1853 pos += ext_rates_len;
1854 }
1855
1856 if (chandef->chan && sband->band == NL80211_BAND_2GHZ) {
1857 if (end - pos < 3)
1858 goto out_err;
1859 *pos++ = WLAN_EID_DS_PARAMS;
1860 *pos++ = 1;
1861 *pos++ = ieee80211_frequency_to_channel(
1862 chandef->chan->center_freq);
1863 }
1864
Googler9398cc32022-12-02 17:21:52 +08001865 if (flags & IEEE80211_PROBE_FLAG_MIN_CONTENT)
1866 goto done;
1867
Googleraf606d22022-10-26 21:40:12 -07001868 /* insert custom IEs that go before HT */
1869 if (ie && ie_len) {
1870 static const u8 before_ht[] = {
Googler9398cc32022-12-02 17:21:52 +08001871 /*
1872 * no need to list the ones split off already
1873 * (or generated here)
1874 */
Googleraf606d22022-10-26 21:40:12 -07001875 WLAN_EID_DS_PARAMS,
1876 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
1877 };
1878 noffset = ieee80211_ie_split(ie, ie_len,
1879 before_ht, ARRAY_SIZE(before_ht),
1880 *offset);
1881 if (end - pos < noffset - *offset)
1882 goto out_err;
1883 memcpy(pos, ie + *offset, noffset - *offset);
1884 pos += noffset - *offset;
1885 *offset = noffset;
1886 }
1887
1888 if (sband->ht_cap.ht_supported) {
1889 if (end - pos < 2 + sizeof(struct ieee80211_ht_cap))
1890 goto out_err;
1891 pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
1892 sband->ht_cap.cap);
1893 }
1894
Googleraf606d22022-10-26 21:40:12 -07001895 /* insert custom IEs that go before VHT */
1896 if (ie && ie_len) {
1897 static const u8 before_vht[] = {
Googler9398cc32022-12-02 17:21:52 +08001898 /*
1899 * no need to list the ones split off already
1900 * (or generated here)
1901 */
Googleraf606d22022-10-26 21:40:12 -07001902 WLAN_EID_BSS_COEX_2040,
1903 WLAN_EID_EXT_CAPABILITY,
1904 WLAN_EID_SSID_LIST,
1905 WLAN_EID_CHANNEL_USAGE,
1906 WLAN_EID_INTERWORKING,
Googler9398cc32022-12-02 17:21:52 +08001907 WLAN_EID_MESH_ID,
1908 /* 60 GHz (Multi-band, DMG, MMS) can't happen */
Googleraf606d22022-10-26 21:40:12 -07001909 };
1910 noffset = ieee80211_ie_split(ie, ie_len,
1911 before_vht, ARRAY_SIZE(before_vht),
1912 *offset);
1913 if (end - pos < noffset - *offset)
1914 goto out_err;
1915 memcpy(pos, ie + *offset, noffset - *offset);
1916 pos += noffset - *offset;
1917 *offset = noffset;
1918 }
1919
1920 /* Check if any channel in this sband supports at least 80 MHz */
1921 for (i = 0; i < sband->n_channels; i++) {
1922 if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
1923 IEEE80211_CHAN_NO_80MHZ))
1924 continue;
1925
1926 have_80mhz = true;
1927 break;
1928 }
1929
1930 if (sband->vht_cap.vht_supported && have_80mhz) {
1931 if (end - pos < 2 + sizeof(struct ieee80211_vht_cap))
1932 goto out_err;
1933 pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap,
1934 sband->vht_cap.cap);
1935 }
1936
Googler9398cc32022-12-02 17:21:52 +08001937 /* insert custom IEs that go before HE */
1938 if (ie && ie_len) {
1939 static const u8 before_he[] = {
1940 /*
1941 * no need to list the ones split off before VHT
1942 * or generated here
1943 */
1944 WLAN_EID_EXTENSION, WLAN_EID_EXT_FILS_REQ_PARAMS,
1945 WLAN_EID_AP_CSN,
1946 /* TODO: add 11ah/11aj/11ak elements */
1947 };
1948 noffset = ieee80211_ie_split(ie, ie_len,
1949 before_he, ARRAY_SIZE(before_he),
1950 *offset);
1951 if (end - pos < noffset - *offset)
1952 goto out_err;
1953 memcpy(pos, ie + *offset, noffset - *offset);
1954 pos += noffset - *offset;
1955 *offset = noffset;
1956 }
1957
1958 he_cap = ieee80211_get_he_sta_cap(sband);
1959 if (he_cap) {
1960 pos = ieee80211_ie_build_he_cap(pos, he_cap, end);
1961 if (!pos)
1962 goto out_err;
1963
1964 if (sband->band == NL80211_BAND_6GHZ) {
1965 enum nl80211_iftype iftype =
1966 ieee80211_vif_type_p2p(&sdata->vif);
1967 __le16 cap = ieee80211_get_he_6ghz_capa(sband, iftype);
1968
1969 pos = ieee80211_write_he_6ghz_cap(pos, cap, end);
1970 }
1971 }
1972
1973 /*
1974 * If adding more here, adjust code in main.c
1975 * that calculates local->scan_ies_len.
1976 */
1977
Googleraf606d22022-10-26 21:40:12 -07001978 return pos - buffer;
1979 out_err:
1980 WARN_ONCE(1, "not enough space for preq IEs\n");
Googler9398cc32022-12-02 17:21:52 +08001981 done:
Googleraf606d22022-10-26 21:40:12 -07001982 return pos - buffer;
1983}
1984
Googler9398cc32022-12-02 17:21:52 +08001985int ieee80211_build_preq_ies(struct ieee80211_sub_if_data *sdata, u8 *buffer,
Googleraf606d22022-10-26 21:40:12 -07001986 size_t buffer_len,
1987 struct ieee80211_scan_ies *ie_desc,
1988 const u8 *ie, size_t ie_len,
1989 u8 bands_used, u32 *rate_masks,
Googler9398cc32022-12-02 17:21:52 +08001990 struct cfg80211_chan_def *chandef,
1991 u32 flags)
Googleraf606d22022-10-26 21:40:12 -07001992{
1993 size_t pos = 0, old_pos = 0, custom_ie_offset = 0;
1994 int i;
1995
1996 memset(ie_desc, 0, sizeof(*ie_desc));
1997
1998 for (i = 0; i < NUM_NL80211_BANDS; i++) {
1999 if (bands_used & BIT(i)) {
Googler9398cc32022-12-02 17:21:52 +08002000 pos += ieee80211_build_preq_ies_band(sdata,
Googleraf606d22022-10-26 21:40:12 -07002001 buffer + pos,
2002 buffer_len - pos,
2003 ie, ie_len, i,
2004 rate_masks[i],
2005 chandef,
Googler9398cc32022-12-02 17:21:52 +08002006 &custom_ie_offset,
2007 flags);
Googleraf606d22022-10-26 21:40:12 -07002008 ie_desc->ies[i] = buffer + old_pos;
2009 ie_desc->len[i] = pos - old_pos;
2010 old_pos = pos;
2011 }
2012 }
2013
2014 /* add any remaining custom IEs */
2015 if (ie && ie_len) {
2016 if (WARN_ONCE(buffer_len - pos < ie_len - custom_ie_offset,
2017 "not enough space for preq custom IEs\n"))
2018 return pos;
2019 memcpy(buffer + pos, ie + custom_ie_offset,
2020 ie_len - custom_ie_offset);
2021 ie_desc->common_ies = buffer + pos;
2022 ie_desc->common_ie_len = ie_len - custom_ie_offset;
2023 pos += ie_len - custom_ie_offset;
2024 }
2025
2026 return pos;
2027};
2028
2029struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
2030 const u8 *src, const u8 *dst,
2031 u32 ratemask,
2032 struct ieee80211_channel *chan,
2033 const u8 *ssid, size_t ssid_len,
2034 const u8 *ie, size_t ie_len,
Googler9398cc32022-12-02 17:21:52 +08002035 u32 flags)
Googleraf606d22022-10-26 21:40:12 -07002036{
2037 struct ieee80211_local *local = sdata->local;
2038 struct cfg80211_chan_def chandef;
2039 struct sk_buff *skb;
2040 struct ieee80211_mgmt *mgmt;
2041 int ies_len;
2042 u32 rate_masks[NUM_NL80211_BANDS] = {};
2043 struct ieee80211_scan_ies dummy_ie_desc;
2044
2045 /*
2046 * Do not send DS Channel parameter for directed probe requests
2047 * in order to maximize the chance that we get a response. Some
2048 * badly-behaved APs don't respond when this parameter is included.
2049 */
2050 chandef.width = sdata->vif.bss_conf.chandef.width;
Googler9398cc32022-12-02 17:21:52 +08002051 if (flags & IEEE80211_PROBE_FLAG_DIRECTED)
Googleraf606d22022-10-26 21:40:12 -07002052 chandef.chan = NULL;
2053 else
2054 chandef.chan = chan;
2055
2056 skb = ieee80211_probereq_get(&local->hw, src, ssid, ssid_len,
2057 100 + ie_len);
2058 if (!skb)
2059 return NULL;
2060
2061 rate_masks[chan->band] = ratemask;
Googler9398cc32022-12-02 17:21:52 +08002062 ies_len = ieee80211_build_preq_ies(sdata, skb_tail_pointer(skb),
Googleraf606d22022-10-26 21:40:12 -07002063 skb_tailroom(skb), &dummy_ie_desc,
2064 ie, ie_len, BIT(chan->band),
Googler9398cc32022-12-02 17:21:52 +08002065 rate_masks, &chandef, flags);
Googleraf606d22022-10-26 21:40:12 -07002066 skb_put(skb, ies_len);
2067
2068 if (dst) {
2069 mgmt = (struct ieee80211_mgmt *) skb->data;
2070 memcpy(mgmt->da, dst, ETH_ALEN);
2071 memcpy(mgmt->bssid, dst, ETH_ALEN);
2072 }
2073
2074 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
2075
2076 return skb;
2077}
2078
Googleraf606d22022-10-26 21:40:12 -07002079u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
2080 struct ieee802_11_elems *elems,
2081 enum nl80211_band band, u32 *basic_rates)
2082{
2083 struct ieee80211_supported_band *sband;
2084 size_t num_rates;
2085 u32 supp_rates, rate_flags;
2086 int i, j, shift;
2087
2088 sband = sdata->local->hw.wiphy->bands[band];
2089 if (WARN_ON(!sband))
2090 return 1;
2091
2092 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
2093 shift = ieee80211_vif_get_shift(&sdata->vif);
2094
2095 num_rates = sband->n_bitrates;
2096 supp_rates = 0;
2097 for (i = 0; i < elems->supp_rates_len +
2098 elems->ext_supp_rates_len; i++) {
2099 u8 rate = 0;
2100 int own_rate;
2101 bool is_basic;
2102 if (i < elems->supp_rates_len)
2103 rate = elems->supp_rates[i];
2104 else if (elems->ext_supp_rates)
2105 rate = elems->ext_supp_rates
2106 [i - elems->supp_rates_len];
2107 own_rate = 5 * (rate & 0x7f);
2108 is_basic = !!(rate & 0x80);
2109
2110 if (is_basic && (rate & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
2111 continue;
2112
2113 for (j = 0; j < num_rates; j++) {
2114 int brate;
2115 if ((rate_flags & sband->bitrates[j].flags)
2116 != rate_flags)
2117 continue;
2118
2119 brate = DIV_ROUND_UP(sband->bitrates[j].bitrate,
2120 1 << shift);
2121
2122 if (brate == own_rate) {
2123 supp_rates |= BIT(j);
2124 if (basic_rates && is_basic)
2125 *basic_rates |= BIT(j);
2126 }
2127 }
2128 }
2129 return supp_rates;
2130}
2131
2132void ieee80211_stop_device(struct ieee80211_local *local)
2133{
2134 ieee80211_led_radio(local, false);
2135 ieee80211_mod_tpt_led_trig(local, 0, IEEE80211_TPT_LEDTRIG_FL_RADIO);
2136
2137 cancel_work_sync(&local->reconfig_filter);
2138
2139 flush_workqueue(local->workqueue);
2140 drv_stop(local);
2141}
2142
2143static void ieee80211_flush_completed_scan(struct ieee80211_local *local,
2144 bool aborted)
2145{
2146 /* It's possible that we don't handle the scan completion in
2147 * time during suspend, so if it's still marked as completed
2148 * here, queue the work and flush it to clean things up.
2149 * Instead of calling the worker function directly here, we
2150 * really queue it to avoid potential races with other flows
2151 * scheduling the same work.
2152 */
2153 if (test_bit(SCAN_COMPLETED, &local->scanning)) {
2154 /* If coming from reconfiguration failure, abort the scan so
2155 * we don't attempt to continue a partial HW scan - which is
2156 * possible otherwise if (e.g.) the 2.4 GHz portion was the
2157 * completed scan, and a 5 GHz portion is still pending.
2158 */
2159 if (aborted)
2160 set_bit(SCAN_ABORTED, &local->scanning);
2161 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
2162 flush_delayed_work(&local->scan_work);
2163 }
2164}
2165
2166static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
2167{
2168 struct ieee80211_sub_if_data *sdata;
2169 struct ieee80211_chanctx *ctx;
2170
2171 /*
2172 * We get here if during resume the device can't be restarted properly.
2173 * We might also get here if this happens during HW reset, which is a
2174 * slightly different situation and we need to drop all connections in
2175 * the latter case.
2176 *
2177 * Ask cfg80211 to turn off all interfaces, this will result in more
2178 * warnings but at least we'll then get into a clean stopped state.
2179 */
2180
2181 local->resuming = false;
2182 local->suspended = false;
2183 local->in_reconfig = false;
2184
2185 ieee80211_flush_completed_scan(local, true);
2186
2187 /* scheduled scan clearly can't be running any more, but tell
2188 * cfg80211 and clear local state
2189 */
2190 ieee80211_sched_scan_end(local);
2191
2192 list_for_each_entry(sdata, &local->interfaces, list)
2193 sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;
2194
2195 /* Mark channel contexts as not being in the driver any more to avoid
2196 * removing them from the driver during the shutdown process...
2197 */
2198 mutex_lock(&local->chanctx_mtx);
2199 list_for_each_entry(ctx, &local->chanctx_list, list)
2200 ctx->driver_present = false;
2201 mutex_unlock(&local->chanctx_mtx);
2202
2203 cfg80211_shutdown_all_interfaces(local->hw.wiphy);
2204}
2205
2206static void ieee80211_assign_chanctx(struct ieee80211_local *local,
2207 struct ieee80211_sub_if_data *sdata)
2208{
2209 struct ieee80211_chanctx_conf *conf;
2210 struct ieee80211_chanctx *ctx;
2211
2212 if (!local->use_chanctx)
2213 return;
2214
Googlerb48fa912023-03-17 12:40:29 +05302215 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
2216 !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))
2217 return;
2218
Googleraf606d22022-10-26 21:40:12 -07002219 mutex_lock(&local->chanctx_mtx);
2220 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
2221 lockdep_is_held(&local->chanctx_mtx));
2222 if (conf) {
2223 ctx = container_of(conf, struct ieee80211_chanctx, conf);
2224 drv_assign_vif_chanctx(local, sdata, ctx);
2225 }
2226 mutex_unlock(&local->chanctx_mtx);
2227}
2228
2229static void ieee80211_reconfig_stations(struct ieee80211_sub_if_data *sdata)
2230{
2231 struct ieee80211_local *local = sdata->local;
2232 struct sta_info *sta;
2233
2234 /* add STAs back */
2235 mutex_lock(&local->sta_mtx);
2236 list_for_each_entry(sta, &local->sta_list, list) {
2237 enum ieee80211_sta_state state;
2238
2239 if (!sta->uploaded || sta->sdata != sdata)
2240 continue;
2241
2242 for (state = IEEE80211_STA_NOTEXIST;
2243 state < sta->sta_state; state++)
2244 WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
2245 state + 1));
2246 }
2247 mutex_unlock(&local->sta_mtx);
2248}
2249
2250static int ieee80211_reconfig_nan(struct ieee80211_sub_if_data *sdata)
2251{
2252 struct cfg80211_nan_func *func, **funcs;
2253 int res, id, i = 0;
2254
2255 res = drv_start_nan(sdata->local, sdata,
2256 &sdata->u.nan.conf);
2257 if (WARN_ON(res))
2258 return res;
2259
Googler9398cc32022-12-02 17:21:52 +08002260 funcs = kcalloc(sdata->local->hw.max_nan_de_entries + 1,
2261 sizeof(*funcs),
2262 GFP_KERNEL);
Googleraf606d22022-10-26 21:40:12 -07002263 if (!funcs)
2264 return -ENOMEM;
2265
2266 /* Add all the functions:
2267 * This is a little bit ugly. We need to call a potentially sleeping
2268 * callback for each NAN function, so we can't hold the spinlock.
2269 */
2270 spin_lock_bh(&sdata->u.nan.func_lock);
2271
2272 idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, id)
2273 funcs[i++] = func;
2274
2275 spin_unlock_bh(&sdata->u.nan.func_lock);
2276
2277 for (i = 0; funcs[i]; i++) {
2278 res = drv_add_nan_func(sdata->local, sdata, funcs[i]);
2279 if (WARN_ON(res))
2280 ieee80211_nan_func_terminated(&sdata->vif,
2281 funcs[i]->instance_id,
2282 NL80211_NAN_FUNC_TERM_REASON_ERROR,
2283 GFP_KERNEL);
2284 }
2285
2286 kfree(funcs);
2287
2288 return 0;
2289}
2290
2291int ieee80211_reconfig(struct ieee80211_local *local)
2292{
2293 struct ieee80211_hw *hw = &local->hw;
2294 struct ieee80211_sub_if_data *sdata;
2295 struct ieee80211_chanctx *ctx;
2296 struct sta_info *sta;
2297 int res, i;
2298 bool reconfig_due_to_wowlan = false;
2299 struct ieee80211_sub_if_data *sched_scan_sdata;
2300 struct cfg80211_sched_scan_request *sched_scan_req;
2301 bool sched_scan_stopped = false;
2302 bool suspended = local->suspended;
2303
2304 /* nothing to do if HW shouldn't run */
2305 if (!local->open_count)
2306 goto wake_up;
2307
2308#ifdef CONFIG_PM
2309 if (suspended)
2310 local->resuming = true;
2311
2312 if (local->wowlan) {
2313 /*
2314 * In the wowlan case, both mac80211 and the device
2315 * are functional when the resume op is called, so
2316 * clear local->suspended so the device could operate
2317 * normally (e.g. pass rx frames).
2318 */
2319 local->suspended = false;
2320 res = drv_resume(local);
2321 local->wowlan = false;
2322 if (res < 0) {
2323 local->resuming = false;
2324 return res;
2325 }
2326 if (res == 0)
2327 goto wake_up;
2328 WARN_ON(res > 1);
2329 /*
2330 * res is 1, which means the driver requested
2331 * to go through a regular reset on wakeup.
2332 * restore local->suspended in this case.
2333 */
2334 reconfig_due_to_wowlan = true;
2335 local->suspended = true;
2336 }
2337#endif
2338
2339 /*
2340 * In case of hw_restart during suspend (without wowlan),
2341 * cancel restart work, as we are reconfiguring the device
2342 * anyway.
2343 * Note that restart_work is scheduled on a frozen workqueue,
2344 * so we can't deadlock in this case.
2345 */
2346 if (suspended && local->in_reconfig && !reconfig_due_to_wowlan)
2347 cancel_work_sync(&local->restart_work);
2348
2349 local->started = false;
2350
2351 /*
2352 * Upon resume hardware can sometimes be goofy due to
2353 * various platform / driver / bus issues, so restarting
2354 * the device may at times not work immediately. Propagate
2355 * the error.
2356 */
2357 res = drv_start(local);
2358 if (res) {
2359 if (suspended)
2360 WARN(1, "Hardware became unavailable upon resume. This could be a software issue prior to suspend or a hardware issue.\n");
2361 else
2362 WARN(1, "Hardware became unavailable during restart.\n");
2363 ieee80211_handle_reconfig_failure(local);
2364 return res;
2365 }
2366
2367 /* setup fragmentation threshold */
2368 drv_set_frag_threshold(local, hw->wiphy->frag_threshold);
2369
2370 /* setup RTS threshold */
2371 drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
2372
2373 /* reset coverage class */
2374 drv_set_coverage_class(local, hw->wiphy->coverage_class);
2375
2376 ieee80211_led_radio(local, true);
2377 ieee80211_mod_tpt_led_trig(local,
2378 IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
2379
2380 /* add interfaces */
2381 sdata = rtnl_dereference(local->monitor_sdata);
2382 if (sdata) {
2383 /* in HW restart it exists already */
2384 WARN_ON(local->resuming);
2385 res = drv_add_interface(local, sdata);
2386 if (WARN_ON(res)) {
2387 RCU_INIT_POINTER(local->monitor_sdata, NULL);
2388 synchronize_net();
2389 kfree(sdata);
2390 }
2391 }
2392
2393 list_for_each_entry(sdata, &local->interfaces, list) {
Googlerb48fa912023-03-17 12:40:29 +05302394 if ((sdata->vif.type != NL80211_IFTYPE_AP_VLAN ||
2395 ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) &&
Googleraf606d22022-10-26 21:40:12 -07002396 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
2397 ieee80211_sdata_running(sdata)) {
2398 res = drv_add_interface(local, sdata);
2399 if (WARN_ON(res))
2400 break;
2401 }
2402 }
2403
2404 /* If adding any of the interfaces failed above, roll back and
2405 * report failure.
2406 */
2407 if (res) {
2408 list_for_each_entry_continue_reverse(sdata, &local->interfaces,
2409 list)
Googlerb48fa912023-03-17 12:40:29 +05302410 if ((sdata->vif.type != NL80211_IFTYPE_AP_VLAN ||
2411 ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) &&
Googleraf606d22022-10-26 21:40:12 -07002412 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
2413 ieee80211_sdata_running(sdata))
2414 drv_remove_interface(local, sdata);
2415 ieee80211_handle_reconfig_failure(local);
2416 return res;
2417 }
2418
2419 /* add channel contexts */
2420 if (local->use_chanctx) {
2421 mutex_lock(&local->chanctx_mtx);
2422 list_for_each_entry(ctx, &local->chanctx_list, list)
2423 if (ctx->replace_state !=
2424 IEEE80211_CHANCTX_REPLACES_OTHER)
2425 WARN_ON(drv_add_chanctx(local, ctx));
2426 mutex_unlock(&local->chanctx_mtx);
2427
2428 sdata = rtnl_dereference(local->monitor_sdata);
2429 if (sdata && ieee80211_sdata_running(sdata))
2430 ieee80211_assign_chanctx(local, sdata);
2431 }
2432
2433 /* reconfigure hardware */
2434 ieee80211_hw_config(local, ~0);
2435
2436 ieee80211_configure_filter(local);
2437
2438 /* Finally also reconfigure all the BSS information */
2439 list_for_each_entry(sdata, &local->interfaces, list) {
2440 u32 changed;
2441
2442 if (!ieee80211_sdata_running(sdata))
2443 continue;
2444
2445 ieee80211_assign_chanctx(local, sdata);
2446
2447 switch (sdata->vif.type) {
2448 case NL80211_IFTYPE_AP_VLAN:
2449 case NL80211_IFTYPE_MONITOR:
2450 break;
Googler9398cc32022-12-02 17:21:52 +08002451 case NL80211_IFTYPE_ADHOC:
2452 if (sdata->vif.bss_conf.ibss_joined)
2453 WARN_ON(drv_join_ibss(local, sdata));
Googlerb48fa912023-03-17 12:40:29 +05302454 fallthrough;
Googleraf606d22022-10-26 21:40:12 -07002455 default:
2456 ieee80211_reconfig_stations(sdata);
Googlerb48fa912023-03-17 12:40:29 +05302457 fallthrough;
Googleraf606d22022-10-26 21:40:12 -07002458 case NL80211_IFTYPE_AP: /* AP stations are handled later */
2459 for (i = 0; i < IEEE80211_NUM_ACS; i++)
2460 drv_conf_tx(local, sdata, i,
2461 &sdata->tx_conf[i]);
2462 break;
2463 }
2464
2465 /* common change flags for all interface types */
2466 changed = BSS_CHANGED_ERP_CTS_PROT |
2467 BSS_CHANGED_ERP_PREAMBLE |
2468 BSS_CHANGED_ERP_SLOT |
2469 BSS_CHANGED_HT |
2470 BSS_CHANGED_BASIC_RATES |
2471 BSS_CHANGED_BEACON_INT |
2472 BSS_CHANGED_BSSID |
2473 BSS_CHANGED_CQM |
2474 BSS_CHANGED_QOS |
2475 BSS_CHANGED_IDLE |
Googler9398cc32022-12-02 17:21:52 +08002476 BSS_CHANGED_TXPOWER |
2477 BSS_CHANGED_MCAST_RATE;
Googleraf606d22022-10-26 21:40:12 -07002478
2479 if (sdata->vif.mu_mimo_owner)
2480 changed |= BSS_CHANGED_MU_GROUPS;
2481
2482 switch (sdata->vif.type) {
2483 case NL80211_IFTYPE_STATION:
2484 changed |= BSS_CHANGED_ASSOC |
2485 BSS_CHANGED_ARP_FILTER |
2486 BSS_CHANGED_PS;
2487
2488 /* Re-send beacon info report to the driver */
2489 if (sdata->u.mgd.have_beacon)
2490 changed |= BSS_CHANGED_BEACON_INFO;
2491
Googler9398cc32022-12-02 17:21:52 +08002492 if (sdata->vif.bss_conf.max_idle_period ||
2493 sdata->vif.bss_conf.protected_keep_alive)
2494 changed |= BSS_CHANGED_KEEP_ALIVE;
2495
Googleraf606d22022-10-26 21:40:12 -07002496 sdata_lock(sdata);
2497 ieee80211_bss_info_change_notify(sdata, changed);
2498 sdata_unlock(sdata);
2499 break;
2500 case NL80211_IFTYPE_OCB:
2501 changed |= BSS_CHANGED_OCB;
2502 ieee80211_bss_info_change_notify(sdata, changed);
2503 break;
2504 case NL80211_IFTYPE_ADHOC:
2505 changed |= BSS_CHANGED_IBSS;
Googlerb48fa912023-03-17 12:40:29 +05302506 fallthrough;
Googleraf606d22022-10-26 21:40:12 -07002507 case NL80211_IFTYPE_AP:
2508 changed |= BSS_CHANGED_SSID | BSS_CHANGED_P2P_PS;
2509
Googler9398cc32022-12-02 17:21:52 +08002510 if (sdata->vif.bss_conf.ftm_responder == 1 &&
2511 wiphy_ext_feature_isset(sdata->local->hw.wiphy,
2512 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
2513 changed |= BSS_CHANGED_FTM_RESPONDER;
2514
Googleraf606d22022-10-26 21:40:12 -07002515 if (sdata->vif.type == NL80211_IFTYPE_AP) {
2516 changed |= BSS_CHANGED_AP_PROBE_RESP;
2517
2518 if (rcu_access_pointer(sdata->u.ap.beacon))
2519 drv_start_ap(local, sdata);
2520 }
Googlerb48fa912023-03-17 12:40:29 +05302521 fallthrough;
Googleraf606d22022-10-26 21:40:12 -07002522 case NL80211_IFTYPE_MESH_POINT:
2523 if (sdata->vif.bss_conf.enable_beacon) {
2524 changed |= BSS_CHANGED_BEACON |
2525 BSS_CHANGED_BEACON_ENABLED;
2526 ieee80211_bss_info_change_notify(sdata, changed);
2527 }
2528 break;
2529 case NL80211_IFTYPE_NAN:
2530 res = ieee80211_reconfig_nan(sdata);
2531 if (res < 0) {
2532 ieee80211_handle_reconfig_failure(local);
2533 return res;
2534 }
2535 break;
Googleraf606d22022-10-26 21:40:12 -07002536 case NL80211_IFTYPE_AP_VLAN:
2537 case NL80211_IFTYPE_MONITOR:
2538 case NL80211_IFTYPE_P2P_DEVICE:
2539 /* nothing to do */
2540 break;
2541 case NL80211_IFTYPE_UNSPECIFIED:
2542 case NUM_NL80211_IFTYPES:
2543 case NL80211_IFTYPE_P2P_CLIENT:
2544 case NL80211_IFTYPE_P2P_GO:
Googlerb48fa912023-03-17 12:40:29 +05302545 case NL80211_IFTYPE_WDS:
Googleraf606d22022-10-26 21:40:12 -07002546 WARN_ON(1);
2547 break;
2548 }
2549 }
2550
2551 ieee80211_recalc_ps(local);
2552
2553 /*
2554 * The sta might be in psm against the ap (e.g. because
2555 * this was the state before a hw restart), so we
2556 * explicitly send a null packet in order to make sure
2557 * it'll sync against the ap (and get out of psm).
2558 */
2559 if (!(local->hw.conf.flags & IEEE80211_CONF_PS)) {
2560 list_for_each_entry(sdata, &local->interfaces, list) {
2561 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2562 continue;
2563 if (!sdata->u.mgd.associated)
2564 continue;
2565
2566 ieee80211_send_nullfunc(local, sdata, false);
2567 }
2568 }
2569
2570 /* APs are now beaconing, add back stations */
2571 mutex_lock(&local->sta_mtx);
2572 list_for_each_entry(sta, &local->sta_list, list) {
2573 enum ieee80211_sta_state state;
2574
2575 if (!sta->uploaded)
2576 continue;
2577
2578 if (sta->sdata->vif.type != NL80211_IFTYPE_AP &&
2579 sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
2580 continue;
2581
2582 for (state = IEEE80211_STA_NOTEXIST;
2583 state < sta->sta_state; state++)
2584 WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
2585 state + 1));
2586 }
2587 mutex_unlock(&local->sta_mtx);
2588
2589 /* add back keys */
2590 list_for_each_entry(sdata, &local->interfaces, list)
Googler9398cc32022-12-02 17:21:52 +08002591 ieee80211_reenable_keys(sdata);
Googleraf606d22022-10-26 21:40:12 -07002592
2593 /* Reconfigure sched scan if it was interrupted by FW restart */
2594 mutex_lock(&local->mtx);
2595 sched_scan_sdata = rcu_dereference_protected(local->sched_scan_sdata,
2596 lockdep_is_held(&local->mtx));
2597 sched_scan_req = rcu_dereference_protected(local->sched_scan_req,
2598 lockdep_is_held(&local->mtx));
2599 if (sched_scan_sdata && sched_scan_req)
2600 /*
2601 * Sched scan stopped, but we don't want to report it. Instead,
2602 * we're trying to reschedule. However, if more than one scan
2603 * plan was set, we cannot reschedule since we don't know which
2604 * scan plan was currently running (and some scan plans may have
2605 * already finished).
2606 */
2607 if (sched_scan_req->n_scan_plans > 1 ||
2608 __ieee80211_request_sched_scan_start(sched_scan_sdata,
2609 sched_scan_req)) {
2610 RCU_INIT_POINTER(local->sched_scan_sdata, NULL);
2611 RCU_INIT_POINTER(local->sched_scan_req, NULL);
2612 sched_scan_stopped = true;
2613 }
2614 mutex_unlock(&local->mtx);
2615
2616 if (sched_scan_stopped)
Googlerb48fa912023-03-17 12:40:29 +05302617 cfg80211_sched_scan_stopped_locked(local->hw.wiphy, 0);
Googleraf606d22022-10-26 21:40:12 -07002618
2619 wake_up:
Googleraf606d22022-10-26 21:40:12 -07002620
2621 if (local->monitors == local->open_count && local->monitors > 0)
2622 ieee80211_add_virtual_monitor(local);
2623
2624 /*
2625 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
2626 * sessions can be established after a resume.
2627 *
2628 * Also tear down aggregation sessions since reconfiguring
2629 * them in a hardware restart scenario is not easily done
2630 * right now, and the hardware will have lost information
2631 * about the sessions, but we and the AP still think they
2632 * are active. This is really a workaround though.
2633 */
2634 if (ieee80211_hw_check(hw, AMPDU_AGGREGATION)) {
2635 mutex_lock(&local->sta_mtx);
2636
2637 list_for_each_entry(sta, &local->sta_list, list) {
2638 if (!local->resuming)
2639 ieee80211_sta_tear_down_BA_sessions(
2640 sta, AGG_STOP_LOCAL_REQUEST);
2641 clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
2642 }
2643
2644 mutex_unlock(&local->sta_mtx);
2645 }
2646
Googler9398cc32022-12-02 17:21:52 +08002647 if (local->in_reconfig) {
2648 local->in_reconfig = false;
2649 barrier();
2650
2651 /* Restart deferred ROCs */
2652 mutex_lock(&local->mtx);
2653 ieee80211_start_next_roc(local);
2654 mutex_unlock(&local->mtx);
2655
2656 /* Requeue all works */
2657 list_for_each_entry(sdata, &local->interfaces, list)
2658 ieee80211_queue_work(&local->hw, &sdata->work);
2659 }
2660
Googleraf606d22022-10-26 21:40:12 -07002661 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
2662 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
2663 false);
2664
2665 /*
2666 * If this is for hw restart things are still running.
2667 * We may want to change that later, however.
2668 */
2669 if (local->open_count && (!suspended || reconfig_due_to_wowlan))
2670 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);
2671
2672 if (!suspended)
2673 return 0;
2674
2675#ifdef CONFIG_PM
2676 /* first set suspended false, then resuming */
2677 local->suspended = false;
2678 mb();
2679 local->resuming = false;
2680
2681 ieee80211_flush_completed_scan(local, false);
2682
2683 if (local->open_count && !reconfig_due_to_wowlan)
2684 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);
2685
2686 list_for_each_entry(sdata, &local->interfaces, list) {
2687 if (!ieee80211_sdata_running(sdata))
2688 continue;
2689 if (sdata->vif.type == NL80211_IFTYPE_STATION)
2690 ieee80211_sta_restart(sdata);
2691 }
2692
2693 mod_timer(&local->sta_cleanup, jiffies + 1);
2694#else
2695 WARN_ON(1);
2696#endif
2697
2698 return 0;
2699}
2700
2701void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
2702{
2703 struct ieee80211_sub_if_data *sdata;
2704 struct ieee80211_local *local;
2705 struct ieee80211_key *key;
2706
2707 if (WARN_ON(!vif))
2708 return;
2709
2710 sdata = vif_to_sdata(vif);
2711 local = sdata->local;
2712
2713 if (WARN_ON(!local->resuming))
2714 return;
2715
2716 if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
2717 return;
2718
2719 sdata->flags |= IEEE80211_SDATA_DISCONNECT_RESUME;
2720
2721 mutex_lock(&local->key_mtx);
2722 list_for_each_entry(key, &sdata->key_list, list)
2723 key->flags |= KEY_FLAG_TAINTED;
2724 mutex_unlock(&local->key_mtx);
2725}
2726EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect);
2727
2728void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata)
2729{
2730 struct ieee80211_local *local = sdata->local;
2731 struct ieee80211_chanctx_conf *chanctx_conf;
2732 struct ieee80211_chanctx *chanctx;
2733
2734 mutex_lock(&local->chanctx_mtx);
2735
2736 chanctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
2737 lockdep_is_held(&local->chanctx_mtx));
2738
2739 /*
2740 * This function can be called from a work, thus it may be possible
2741 * that the chanctx_conf is removed (due to a disconnection, for
2742 * example).
2743 * So nothing should be done in such case.
2744 */
2745 if (!chanctx_conf)
2746 goto unlock;
2747
2748 chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
2749 ieee80211_recalc_smps_chanctx(local, chanctx);
2750 unlock:
2751 mutex_unlock(&local->chanctx_mtx);
2752}
2753
2754void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata)
2755{
2756 struct ieee80211_local *local = sdata->local;
2757 struct ieee80211_chanctx_conf *chanctx_conf;
2758 struct ieee80211_chanctx *chanctx;
2759
2760 mutex_lock(&local->chanctx_mtx);
2761
2762 chanctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
2763 lockdep_is_held(&local->chanctx_mtx));
2764
2765 if (WARN_ON_ONCE(!chanctx_conf))
2766 goto unlock;
2767
2768 chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
2769 ieee80211_recalc_chanctx_min_def(local, chanctx);
2770 unlock:
2771 mutex_unlock(&local->chanctx_mtx);
2772}
2773
2774size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
2775{
2776 size_t pos = offset;
2777
2778 while (pos < ielen && ies[pos] != WLAN_EID_VENDOR_SPECIFIC)
2779 pos += 2 + ies[pos + 1];
2780
2781 return pos;
2782}
2783
2784static void _ieee80211_enable_rssi_reports(struct ieee80211_sub_if_data *sdata,
2785 int rssi_min_thold,
2786 int rssi_max_thold)
2787{
2788 trace_api_enable_rssi_reports(sdata, rssi_min_thold, rssi_max_thold);
2789
2790 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
2791 return;
2792
2793 /*
2794 * Scale up threshold values before storing it, as the RSSI averaging
2795 * algorithm uses a scaled up value as well. Change this scaling
2796 * factor if the RSSI averaging algorithm changes.
2797 */
2798 sdata->u.mgd.rssi_min_thold = rssi_min_thold*16;
2799 sdata->u.mgd.rssi_max_thold = rssi_max_thold*16;
2800}
2801
2802void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
2803 int rssi_min_thold,
2804 int rssi_max_thold)
2805{
2806 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
2807
2808 WARN_ON(rssi_min_thold == rssi_max_thold ||
2809 rssi_min_thold > rssi_max_thold);
2810
2811 _ieee80211_enable_rssi_reports(sdata, rssi_min_thold,
2812 rssi_max_thold);
2813}
2814EXPORT_SYMBOL(ieee80211_enable_rssi_reports);
2815
2816void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif)
2817{
2818 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
2819
2820 _ieee80211_enable_rssi_reports(sdata, 0, 0);
2821}
2822EXPORT_SYMBOL(ieee80211_disable_rssi_reports);
2823
2824u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
2825 u16 cap)
2826{
2827 __le16 tmp;
2828
2829 *pos++ = WLAN_EID_HT_CAPABILITY;
2830 *pos++ = sizeof(struct ieee80211_ht_cap);
2831 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
2832
2833 /* capability flags */
2834 tmp = cpu_to_le16(cap);
2835 memcpy(pos, &tmp, sizeof(u16));
2836 pos += sizeof(u16);
2837
2838 /* AMPDU parameters */
2839 *pos++ = ht_cap->ampdu_factor |
2840 (ht_cap->ampdu_density <<
2841 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
2842
2843 /* MCS set */
2844 memcpy(pos, &ht_cap->mcs, sizeof(ht_cap->mcs));
2845 pos += sizeof(ht_cap->mcs);
2846
2847 /* extended capabilities */
2848 pos += sizeof(__le16);
2849
2850 /* BF capabilities */
2851 pos += sizeof(__le32);
2852
2853 /* antenna selection */
2854 pos += sizeof(u8);
2855
2856 return pos;
2857}
2858
2859u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
2860 u32 cap)
2861{
2862 __le32 tmp;
2863
2864 *pos++ = WLAN_EID_VHT_CAPABILITY;
2865 *pos++ = sizeof(struct ieee80211_vht_cap);
2866 memset(pos, 0, sizeof(struct ieee80211_vht_cap));
2867
2868 /* capability flags */
2869 tmp = cpu_to_le32(cap);
2870 memcpy(pos, &tmp, sizeof(u32));
2871 pos += sizeof(u32);
2872
2873 /* VHT MCS set */
2874 memcpy(pos, &vht_cap->vht_mcs, sizeof(vht_cap->vht_mcs));
2875 pos += sizeof(vht_cap->vht_mcs);
2876
2877 return pos;
2878}
2879
Googler9398cc32022-12-02 17:21:52 +08002880u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata, u8 iftype)
2881{
2882 const struct ieee80211_sta_he_cap *he_cap;
2883 struct ieee80211_supported_band *sband;
2884 u8 n;
2885
2886 sband = ieee80211_get_sband(sdata);
2887 if (!sband)
2888 return 0;
2889
2890 he_cap = ieee80211_get_he_iftype_cap(sband, iftype);
2891 if (!he_cap)
2892 return 0;
2893
2894 n = ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem);
2895 return 2 + 1 +
2896 sizeof(he_cap->he_cap_elem) + n +
2897 ieee80211_he_ppe_size(he_cap->ppe_thres[0],
2898 he_cap->he_cap_elem.phy_cap_info);
2899}
2900
2901u8 *ieee80211_ie_build_he_cap(u8 *pos,
2902 const struct ieee80211_sta_he_cap *he_cap,
2903 u8 *end)
2904{
2905 u8 n;
2906 u8 ie_len;
2907 u8 *orig_pos = pos;
2908
2909 /* Make sure we have place for the IE */
2910 /*
2911 * TODO: the 1 added is because this temporarily is under the EXTENSION
2912 * IE. Get rid of it when it moves.
2913 */
2914 if (!he_cap)
2915 return orig_pos;
2916
2917 n = ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem);
2918 ie_len = 2 + 1 +
2919 sizeof(he_cap->he_cap_elem) + n +
2920 ieee80211_he_ppe_size(he_cap->ppe_thres[0],
2921 he_cap->he_cap_elem.phy_cap_info);
2922
2923 if ((end - pos) < ie_len)
2924 return orig_pos;
2925
2926 *pos++ = WLAN_EID_EXTENSION;
2927 pos++; /* We'll set the size later below */
2928 *pos++ = WLAN_EID_EXT_HE_CAPABILITY;
2929
2930 /* Fixed data */
2931 memcpy(pos, &he_cap->he_cap_elem, sizeof(he_cap->he_cap_elem));
2932 pos += sizeof(he_cap->he_cap_elem);
2933
2934 memcpy(pos, &he_cap->he_mcs_nss_supp, n);
2935 pos += n;
2936
2937 /* Check if PPE Threshold should be present */
2938 if ((he_cap->he_cap_elem.phy_cap_info[6] &
2939 IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) == 0)
2940 goto end;
2941
2942 /*
2943 * Calculate how many PPET16/PPET8 pairs are to come. Algorithm:
2944 * (NSS_M1 + 1) x (num of 1 bits in RU_INDEX_BITMASK)
2945 */
2946 n = hweight8(he_cap->ppe_thres[0] &
2947 IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK);
2948 n *= (1 + ((he_cap->ppe_thres[0] & IEEE80211_PPE_THRES_NSS_MASK) >>
2949 IEEE80211_PPE_THRES_NSS_POS));
2950
2951 /*
2952 * Each pair is 6 bits, and we need to add the 7 "header" bits to the
2953 * total size.
2954 */
2955 n = (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) + 7;
2956 n = DIV_ROUND_UP(n, 8);
2957
2958 /* Copy PPE Thresholds */
2959 memcpy(pos, &he_cap->ppe_thres, n);
2960 pos += n;
2961
2962end:
2963 orig_pos[1] = (pos - orig_pos) - 2;
2964 return pos;
2965}
2966
2967void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
2968 struct sk_buff *skb)
2969{
2970 struct ieee80211_supported_band *sband;
2971 const struct ieee80211_sband_iftype_data *iftd;
2972 enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
2973 u8 *pos;
2974 u16 cap;
2975
2976 sband = ieee80211_get_sband(sdata);
2977 if (!sband)
2978 return;
2979
2980 iftd = ieee80211_get_sband_iftype_data(sband, iftype);
2981 if (WARN_ON(!iftd))
2982 return;
2983
2984 /* Check for device HE 6 GHz capability before adding element */
2985 if (!iftd->he_6ghz_capa.capa)
2986 return;
2987
2988 cap = le16_to_cpu(iftd->he_6ghz_capa.capa);
2989 cap &= ~IEEE80211_HE_6GHZ_CAP_SM_PS;
2990
2991 switch (sdata->smps_mode) {
2992 case IEEE80211_SMPS_AUTOMATIC:
2993 case IEEE80211_SMPS_NUM_MODES:
2994 WARN_ON(1);
Googlerb48fa912023-03-17 12:40:29 +05302995 fallthrough;
Googler9398cc32022-12-02 17:21:52 +08002996 case IEEE80211_SMPS_OFF:
2997 cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DISABLED,
2998 IEEE80211_HE_6GHZ_CAP_SM_PS);
2999 break;
3000 case IEEE80211_SMPS_STATIC:
3001 cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_STATIC,
3002 IEEE80211_HE_6GHZ_CAP_SM_PS);
3003 break;
3004 case IEEE80211_SMPS_DYNAMIC:
3005 cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DYNAMIC,
3006 IEEE80211_HE_6GHZ_CAP_SM_PS);
3007 break;
3008 }
3009
3010 pos = skb_put(skb, 2 + 1 + sizeof(cap));
3011 ieee80211_write_he_6ghz_cap(pos, cpu_to_le16(cap),
3012 pos + 2 + 1 + sizeof(cap));
3013}
3014
Googleraf606d22022-10-26 21:40:12 -07003015u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
3016 const struct cfg80211_chan_def *chandef,
3017 u16 prot_mode, bool rifs_mode)
3018{
3019 struct ieee80211_ht_operation *ht_oper;
3020 /* Build HT Information */
3021 *pos++ = WLAN_EID_HT_OPERATION;
3022 *pos++ = sizeof(struct ieee80211_ht_operation);
3023 ht_oper = (struct ieee80211_ht_operation *)pos;
3024 ht_oper->primary_chan = ieee80211_frequency_to_channel(
3025 chandef->chan->center_freq);
3026 switch (chandef->width) {
3027 case NL80211_CHAN_WIDTH_160:
3028 case NL80211_CHAN_WIDTH_80P80:
3029 case NL80211_CHAN_WIDTH_80:
3030 case NL80211_CHAN_WIDTH_40:
3031 if (chandef->center_freq1 > chandef->chan->center_freq)
3032 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
3033 else
3034 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
3035 break;
3036 default:
3037 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
3038 break;
3039 }
3040 if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
3041 chandef->width != NL80211_CHAN_WIDTH_20_NOHT &&
3042 chandef->width != NL80211_CHAN_WIDTH_20)
3043 ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
3044
3045 if (rifs_mode)
3046 ht_oper->ht_param |= IEEE80211_HT_PARAM_RIFS_MODE;
3047
3048 ht_oper->operation_mode = cpu_to_le16(prot_mode);
3049 ht_oper->stbc_param = 0x0000;
3050
3051 /* It seems that Basic MCS set and Supported MCS set
3052 are identical for the first 10 bytes */
3053 memset(&ht_oper->basic_set, 0, 16);
3054 memcpy(&ht_oper->basic_set, &ht_cap->mcs, 10);
3055
3056 return pos + sizeof(struct ieee80211_ht_operation);
3057}
3058
Googler9398cc32022-12-02 17:21:52 +08003059void ieee80211_ie_build_wide_bw_cs(u8 *pos,
3060 const struct cfg80211_chan_def *chandef)
3061{
3062 *pos++ = WLAN_EID_WIDE_BW_CHANNEL_SWITCH; /* EID */
3063 *pos++ = 3; /* IE length */
3064 /* New channel width */
3065 switch (chandef->width) {
3066 case NL80211_CHAN_WIDTH_80:
3067 *pos++ = IEEE80211_VHT_CHANWIDTH_80MHZ;
3068 break;
3069 case NL80211_CHAN_WIDTH_160:
3070 *pos++ = IEEE80211_VHT_CHANWIDTH_160MHZ;
3071 break;
3072 case NL80211_CHAN_WIDTH_80P80:
3073 *pos++ = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
3074 break;
3075 default:
3076 *pos++ = IEEE80211_VHT_CHANWIDTH_USE_HT;
3077 }
3078
3079 /* new center frequency segment 0 */
3080 *pos++ = ieee80211_frequency_to_channel(chandef->center_freq1);
3081 /* new center frequency segment 1 */
3082 if (chandef->center_freq2)
3083 *pos++ = ieee80211_frequency_to_channel(chandef->center_freq2);
3084 else
3085 *pos++ = 0;
3086}
3087
Googleraf606d22022-10-26 21:40:12 -07003088u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
3089 const struct cfg80211_chan_def *chandef)
3090{
3091 struct ieee80211_vht_operation *vht_oper;
3092
3093 *pos++ = WLAN_EID_VHT_OPERATION;
3094 *pos++ = sizeof(struct ieee80211_vht_operation);
3095 vht_oper = (struct ieee80211_vht_operation *)pos;
Googler9398cc32022-12-02 17:21:52 +08003096 vht_oper->center_freq_seg0_idx = ieee80211_frequency_to_channel(
Googleraf606d22022-10-26 21:40:12 -07003097 chandef->center_freq1);
3098 if (chandef->center_freq2)
Googler9398cc32022-12-02 17:21:52 +08003099 vht_oper->center_freq_seg1_idx =
Googleraf606d22022-10-26 21:40:12 -07003100 ieee80211_frequency_to_channel(chandef->center_freq2);
3101 else
Googler9398cc32022-12-02 17:21:52 +08003102 vht_oper->center_freq_seg1_idx = 0x00;
Googleraf606d22022-10-26 21:40:12 -07003103
3104 switch (chandef->width) {
3105 case NL80211_CHAN_WIDTH_160:
3106 /*
3107 * Convert 160 MHz channel width to new style as interop
3108 * workaround.
3109 */
3110 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
Googler9398cc32022-12-02 17:21:52 +08003111 vht_oper->center_freq_seg1_idx = vht_oper->center_freq_seg0_idx;
Googleraf606d22022-10-26 21:40:12 -07003112 if (chandef->chan->center_freq < chandef->center_freq1)
Googler9398cc32022-12-02 17:21:52 +08003113 vht_oper->center_freq_seg0_idx -= 8;
Googleraf606d22022-10-26 21:40:12 -07003114 else
Googler9398cc32022-12-02 17:21:52 +08003115 vht_oper->center_freq_seg0_idx += 8;
Googleraf606d22022-10-26 21:40:12 -07003116 break;
3117 case NL80211_CHAN_WIDTH_80P80:
3118 /*
3119 * Convert 80+80 MHz channel width to new style as interop
3120 * workaround.
3121 */
3122 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
3123 break;
3124 case NL80211_CHAN_WIDTH_80:
3125 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
3126 break;
3127 default:
3128 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
3129 break;
3130 }
3131
3132 /* don't require special VHT peer rates */
3133 vht_oper->basic_mcs_set = cpu_to_le16(0xffff);
3134
3135 return pos + sizeof(struct ieee80211_vht_operation);
3136}
3137
Googlerb48fa912023-03-17 12:40:29 +05303138u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef)
Googler9398cc32022-12-02 17:21:52 +08003139{
3140 struct ieee80211_he_operation *he_oper;
Googlerb48fa912023-03-17 12:40:29 +05303141 struct ieee80211_he_6ghz_oper *he_6ghz_op;
Googler9398cc32022-12-02 17:21:52 +08003142 u32 he_oper_params;
Googlerb48fa912023-03-17 12:40:29 +05303143 u8 ie_len = 1 + sizeof(struct ieee80211_he_operation);
3144
3145 if (chandef->chan->band == NL80211_BAND_6GHZ)
3146 ie_len += sizeof(struct ieee80211_he_6ghz_oper);
Googler9398cc32022-12-02 17:21:52 +08003147
3148 *pos++ = WLAN_EID_EXTENSION;
Googlerb48fa912023-03-17 12:40:29 +05303149 *pos++ = ie_len;
Googler9398cc32022-12-02 17:21:52 +08003150 *pos++ = WLAN_EID_EXT_HE_OPERATION;
3151
3152 he_oper_params = 0;
3153 he_oper_params |= u32_encode_bits(1023, /* disabled */
3154 IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
3155 he_oper_params |= u32_encode_bits(1,
3156 IEEE80211_HE_OPERATION_ER_SU_DISABLE);
3157 he_oper_params |= u32_encode_bits(1,
3158 IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
Googlerb48fa912023-03-17 12:40:29 +05303159 if (chandef->chan->band == NL80211_BAND_6GHZ)
3160 he_oper_params |= u32_encode_bits(1,
3161 IEEE80211_HE_OPERATION_6GHZ_OP_INFO);
Googler9398cc32022-12-02 17:21:52 +08003162
3163 he_oper = (struct ieee80211_he_operation *)pos;
3164 he_oper->he_oper_params = cpu_to_le32(he_oper_params);
3165
3166 /* don't require special HE peer rates */
3167 he_oper->he_mcs_nss_set = cpu_to_le16(0xffff);
Googlerb48fa912023-03-17 12:40:29 +05303168 pos += sizeof(struct ieee80211_he_operation);
Googler9398cc32022-12-02 17:21:52 +08003169
Googlerb48fa912023-03-17 12:40:29 +05303170 if (chandef->chan->band != NL80211_BAND_6GHZ)
3171 goto out;
Googler9398cc32022-12-02 17:21:52 +08003172
Googlerb48fa912023-03-17 12:40:29 +05303173 /* TODO add VHT operational */
3174 he_6ghz_op = (struct ieee80211_he_6ghz_oper *)pos;
3175 he_6ghz_op->minrate = 6; /* 6 Mbps */
3176 he_6ghz_op->primary =
3177 ieee80211_frequency_to_channel(chandef->chan->center_freq);
3178 he_6ghz_op->ccfs0 =
3179 ieee80211_frequency_to_channel(chandef->center_freq1);
3180 if (chandef->center_freq2)
3181 he_6ghz_op->ccfs1 =
3182 ieee80211_frequency_to_channel(chandef->center_freq2);
3183 else
3184 he_6ghz_op->ccfs1 = 0;
3185
3186 switch (chandef->width) {
3187 case NL80211_CHAN_WIDTH_160:
3188 /* Convert 160 MHz channel width to new style as interop
3189 * workaround.
3190 */
3191 he_6ghz_op->control =
3192 IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
3193 he_6ghz_op->ccfs1 = he_6ghz_op->ccfs0;
3194 if (chandef->chan->center_freq < chandef->center_freq1)
3195 he_6ghz_op->ccfs0 -= 8;
3196 else
3197 he_6ghz_op->ccfs0 += 8;
3198 fallthrough;
3199 case NL80211_CHAN_WIDTH_80P80:
3200 he_6ghz_op->control =
3201 IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
3202 break;
3203 case NL80211_CHAN_WIDTH_80:
3204 he_6ghz_op->control =
3205 IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ;
3206 break;
3207 case NL80211_CHAN_WIDTH_40:
3208 he_6ghz_op->control =
3209 IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ;
3210 break;
3211 default:
3212 he_6ghz_op->control =
3213 IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ;
3214 break;
3215 }
3216
3217 pos += sizeof(struct ieee80211_he_6ghz_oper);
3218
3219out:
3220 return pos;
Googler9398cc32022-12-02 17:21:52 +08003221}
3222
Googleraf606d22022-10-26 21:40:12 -07003223bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
3224 struct cfg80211_chan_def *chandef)
3225{
3226 enum nl80211_channel_type channel_type;
3227
3228 if (!ht_oper)
3229 return false;
3230
3231 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
3232 case IEEE80211_HT_PARAM_CHA_SEC_NONE:
3233 channel_type = NL80211_CHAN_HT20;
3234 break;
3235 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
3236 channel_type = NL80211_CHAN_HT40PLUS;
3237 break;
3238 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
3239 channel_type = NL80211_CHAN_HT40MINUS;
3240 break;
3241 default:
3242 channel_type = NL80211_CHAN_NO_HT;
3243 return false;
3244 }
3245
3246 cfg80211_chandef_create(chandef, chandef->chan, channel_type);
3247 return true;
3248}
3249
Googlerb48fa912023-03-17 12:40:29 +05303250bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, u32 vht_cap_info,
Googler9398cc32022-12-02 17:21:52 +08003251 const struct ieee80211_vht_operation *oper,
3252 const struct ieee80211_ht_operation *htop,
Googleraf606d22022-10-26 21:40:12 -07003253 struct cfg80211_chan_def *chandef)
3254{
3255 struct cfg80211_chan_def new = *chandef;
Googler9398cc32022-12-02 17:21:52 +08003256 int cf0, cf1;
3257 int ccfs0, ccfs1, ccfs2;
3258 int ccf0, ccf1;
3259 u32 vht_cap;
3260 bool support_80_80 = false;
3261 bool support_160 = false;
Googlerb48fa912023-03-17 12:40:29 +05303262 u8 ext_nss_bw_supp = u32_get_bits(vht_cap_info,
3263 IEEE80211_VHT_CAP_EXT_NSS_BW_MASK);
3264 u8 supp_chwidth = u32_get_bits(vht_cap_info,
3265 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK);
Googleraf606d22022-10-26 21:40:12 -07003266
Googler9398cc32022-12-02 17:21:52 +08003267 if (!oper || !htop)
Googleraf606d22022-10-26 21:40:12 -07003268 return false;
3269
Googler9398cc32022-12-02 17:21:52 +08003270 vht_cap = hw->wiphy->bands[chandef->chan->band]->vht_cap.cap;
3271 support_160 = (vht_cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK |
3272 IEEE80211_VHT_CAP_EXT_NSS_BW_MASK));
3273 support_80_80 = ((vht_cap &
3274 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) ||
3275 (vht_cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
3276 vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) ||
3277 ((vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) >>
3278 IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT > 1));
3279 ccfs0 = oper->center_freq_seg0_idx;
3280 ccfs1 = oper->center_freq_seg1_idx;
3281 ccfs2 = (le16_to_cpu(htop->operation_mode) &
3282 IEEE80211_HT_OP_MODE_CCFS2_MASK)
3283 >> IEEE80211_HT_OP_MODE_CCFS2_SHIFT;
3284
Googler9398cc32022-12-02 17:21:52 +08003285 ccf0 = ccfs0;
Googlerb48fa912023-03-17 12:40:29 +05303286
3287 /* if not supported, parse as though we didn't understand it */
3288 if (!ieee80211_hw_check(hw, SUPPORTS_VHT_EXT_NSS_BW))
3289 ext_nss_bw_supp = 0;
3290
3291 /*
3292 * Cf. IEEE 802.11 Table 9-250
3293 *
3294 * We really just consider that because it's inefficient to connect
3295 * at a higher bandwidth than we'll actually be able to use.
3296 */
3297 switch ((supp_chwidth << 4) | ext_nss_bw_supp) {
3298 default:
3299 case 0x00:
3300 ccf1 = 0;
3301 support_160 = false;
3302 support_80_80 = false;
3303 break;
3304 case 0x01:
3305 support_80_80 = false;
3306 fallthrough;
3307 case 0x02:
3308 case 0x03:
Googler9398cc32022-12-02 17:21:52 +08003309 ccf1 = ccfs2;
Googlerb48fa912023-03-17 12:40:29 +05303310 break;
3311 case 0x10:
3312 ccf1 = ccfs1;
3313 break;
3314 case 0x11:
3315 case 0x12:
3316 if (!ccfs1)
3317 ccf1 = ccfs2;
3318 else
3319 ccf1 = ccfs1;
3320 break;
3321 case 0x13:
3322 case 0x20:
3323 case 0x23:
3324 ccf1 = ccfs1;
3325 break;
3326 }
Googler9398cc32022-12-02 17:21:52 +08003327
3328 cf0 = ieee80211_channel_to_frequency(ccf0, chandef->chan->band);
3329 cf1 = ieee80211_channel_to_frequency(ccf1, chandef->chan->band);
Googleraf606d22022-10-26 21:40:12 -07003330
3331 switch (oper->chan_width) {
3332 case IEEE80211_VHT_CHANWIDTH_USE_HT:
Googler9398cc32022-12-02 17:21:52 +08003333 /* just use HT information directly */
Googleraf606d22022-10-26 21:40:12 -07003334 break;
3335 case IEEE80211_VHT_CHANWIDTH_80MHZ:
3336 new.width = NL80211_CHAN_WIDTH_80;
Googler9398cc32022-12-02 17:21:52 +08003337 new.center_freq1 = cf0;
Googleraf606d22022-10-26 21:40:12 -07003338 /* If needed, adjust based on the newer interop workaround. */
Googler9398cc32022-12-02 17:21:52 +08003339 if (ccf1) {
Googleraf606d22022-10-26 21:40:12 -07003340 unsigned int diff;
3341
Googler9398cc32022-12-02 17:21:52 +08003342 diff = abs(ccf1 - ccf0);
3343 if ((diff == 8) && support_160) {
Googleraf606d22022-10-26 21:40:12 -07003344 new.width = NL80211_CHAN_WIDTH_160;
Googler9398cc32022-12-02 17:21:52 +08003345 new.center_freq1 = cf1;
3346 } else if ((diff > 8) && support_80_80) {
Googleraf606d22022-10-26 21:40:12 -07003347 new.width = NL80211_CHAN_WIDTH_80P80;
Googler9398cc32022-12-02 17:21:52 +08003348 new.center_freq2 = cf1;
Googleraf606d22022-10-26 21:40:12 -07003349 }
3350 }
3351 break;
3352 case IEEE80211_VHT_CHANWIDTH_160MHZ:
Googler9398cc32022-12-02 17:21:52 +08003353 /* deprecated encoding */
Googleraf606d22022-10-26 21:40:12 -07003354 new.width = NL80211_CHAN_WIDTH_160;
Googler9398cc32022-12-02 17:21:52 +08003355 new.center_freq1 = cf0;
Googleraf606d22022-10-26 21:40:12 -07003356 break;
3357 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
Googler9398cc32022-12-02 17:21:52 +08003358 /* deprecated encoding */
Googleraf606d22022-10-26 21:40:12 -07003359 new.width = NL80211_CHAN_WIDTH_80P80;
Googler9398cc32022-12-02 17:21:52 +08003360 new.center_freq1 = cf0;
3361 new.center_freq2 = cf1;
Googleraf606d22022-10-26 21:40:12 -07003362 break;
3363 default:
3364 return false;
3365 }
3366
3367 if (!cfg80211_chandef_valid(&new))
3368 return false;
3369
3370 *chandef = new;
3371 return true;
3372}
3373
Googlerb48fa912023-03-17 12:40:29 +05303374bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
3375 const struct ieee80211_he_operation *he_oper,
3376 struct cfg80211_chan_def *chandef)
3377{
3378 struct ieee80211_local *local = sdata->local;
3379 struct ieee80211_supported_band *sband;
3380 enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
3381 const struct ieee80211_sta_he_cap *he_cap;
3382 struct cfg80211_chan_def he_chandef = *chandef;
3383 const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
3384 enum nl80211_regulatory_power_modes mode;
3385 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
3386 bool support_80_80, support_160;
3387 u8 he_phy_cap;
3388 u32 freq;
3389 u8 reg_info;
3390 u8 reg_6g_power_mode;
3391
3392 if (chandef->chan->band != NL80211_BAND_6GHZ)
3393 return true;
3394
3395 sband = local->hw.wiphy->bands[NL80211_BAND_6GHZ];
3396
3397 he_cap = ieee80211_get_he_iftype_cap(sband, iftype);
3398 if (!he_cap) {
3399 sdata_info(sdata, "Missing iftype sband data/HE cap");
3400 return false;
3401 }
3402
3403 he_phy_cap = he_cap->he_cap_elem.phy_cap_info[0];
3404 support_160 =
3405 he_phy_cap &
3406 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
3407 support_80_80 =
3408 he_phy_cap &
3409 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
3410
3411 if (!he_oper) {
3412 sdata_info(sdata,
3413 "HE is not advertised on (on %d MHz), expect issues\n",
3414 chandef->chan->center_freq);
3415 return false;
3416 }
3417
3418 he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
3419
3420 if (!he_6ghz_oper) {
3421 sdata_info(sdata,
3422 "HE 6GHz operation missing (on %d MHz), expect issues\n",
3423 chandef->chan->center_freq);
3424 return false;
3425 }
3426
3427 /* 6G Power mode present in the beacon */
3428 reg_info = (he_6ghz_oper->control & IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO) >>
3429 IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB;
3430
3431 /* 6G Power mode configured by the user */
3432 reg_6g_power_mode = sdata->wdev.reg_6g_power_mode;
3433
3434 /**
3435 * For AP/AP_VLAN/MESH_POINT interfaces, the 6G power mode depends on the
3436 * mode configured by user (LPI/SP/VLP). For other interfaces (for ex STA)
3437 * mode depends on the power mode present in beacon as well as power mode
3438 * configured by the user for that interface
3439 */
3440 if (iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_AP_VLAN ||
3441 iftype == NL80211_IFTYPE_MESH_POINT) {
3442 mode = reg_6g_power_mode;
3443 } else
3444 mode = 3 * (1 + reg_6g_power_mode) + reg_info;
3445
3446 freq = ieee80211_channel_to_frequency(he_6ghz_oper->primary,
3447 NL80211_BAND_6GHZ);
3448 he_chandef.chan = ieee80211_get_6g_channel_khz(sdata->local->hw.wiphy,
3449 MHZ_TO_KHZ(freq), mode);
3450
3451 switch (u8_get_bits(he_6ghz_oper->control,
3452 IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) {
3453 case IEEE80211_6GHZ_CTRL_REG_LPI_AP:
3454 bss_conf->power_type = IEEE80211_REG_LPI_AP;
3455 break;
3456 case IEEE80211_6GHZ_CTRL_REG_SP_AP:
3457 bss_conf->power_type = IEEE80211_REG_SP_AP;
3458 break;
3459 default:
3460 bss_conf->power_type = IEEE80211_REG_UNSET_AP;
3461 break;
3462 }
3463
3464 switch (u8_get_bits(he_6ghz_oper->control,
3465 IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH)) {
3466 case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ:
3467 he_chandef.width = NL80211_CHAN_WIDTH_20;
3468 break;
3469 case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ:
3470 he_chandef.width = NL80211_CHAN_WIDTH_40;
3471 break;
3472 case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ:
3473 he_chandef.width = NL80211_CHAN_WIDTH_80;
3474 break;
3475 case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ:
3476 he_chandef.width = NL80211_CHAN_WIDTH_80;
3477 if (!he_6ghz_oper->ccfs1)
3478 break;
3479 if (abs(he_6ghz_oper->ccfs1 - he_6ghz_oper->ccfs0) == 8) {
3480 if (support_160)
3481 he_chandef.width = NL80211_CHAN_WIDTH_160;
3482 } else {
3483 if (support_80_80)
3484 he_chandef.width = NL80211_CHAN_WIDTH_80P80;
3485 }
3486 break;
3487 }
3488
3489 if (he_chandef.width == NL80211_CHAN_WIDTH_160) {
3490 he_chandef.center_freq1 =
3491 ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1,
3492 NL80211_BAND_6GHZ);
3493 } else {
3494 he_chandef.center_freq1 =
3495 ieee80211_channel_to_frequency(he_6ghz_oper->ccfs0,
3496 NL80211_BAND_6GHZ);
3497 if (support_80_80 || support_160)
3498 he_chandef.center_freq2 =
3499 ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1,
3500 NL80211_BAND_6GHZ);
3501 }
3502
3503 if (!cfg80211_chandef_valid(&he_chandef)) {
3504 sdata_info(sdata,
3505 "HE 6GHz operation resulted in invalid chandef: %d MHz/%d/%d MHz/%d MHz\n",
3506 he_chandef.chan ? he_chandef.chan->center_freq : 0,
3507 he_chandef.width,
3508 he_chandef.center_freq1,
3509 he_chandef.center_freq2);
3510 return false;
3511 }
3512
3513 *chandef = he_chandef;
3514
3515 return true;
3516}
3517
3518bool ieee80211_chandef_s1g_oper(const struct ieee80211_s1g_oper_ie *oper,
3519 struct cfg80211_chan_def *chandef)
3520{
3521 u32 oper_freq;
3522
3523 if (!oper)
3524 return false;
3525
3526 switch (FIELD_GET(S1G_OPER_CH_WIDTH_OPER, oper->ch_width)) {
3527 case IEEE80211_S1G_CHANWIDTH_1MHZ:
3528 chandef->width = NL80211_CHAN_WIDTH_1;
3529 break;
3530 case IEEE80211_S1G_CHANWIDTH_2MHZ:
3531 chandef->width = NL80211_CHAN_WIDTH_2;
3532 break;
3533 case IEEE80211_S1G_CHANWIDTH_4MHZ:
3534 chandef->width = NL80211_CHAN_WIDTH_4;
3535 break;
3536 case IEEE80211_S1G_CHANWIDTH_8MHZ:
3537 chandef->width = NL80211_CHAN_WIDTH_8;
3538 break;
3539 case IEEE80211_S1G_CHANWIDTH_16MHZ:
3540 chandef->width = NL80211_CHAN_WIDTH_16;
3541 break;
3542 default:
3543 return false;
3544 }
3545
3546 oper_freq = ieee80211_channel_to_freq_khz(oper->oper_ch,
3547 NL80211_BAND_S1GHZ);
3548 chandef->center_freq1 = KHZ_TO_MHZ(oper_freq);
3549 chandef->freq1_offset = oper_freq % 1000;
3550
3551 return true;
3552}
3553
Googleraf606d22022-10-26 21:40:12 -07003554int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
3555 const struct ieee80211_supported_band *sband,
3556 const u8 *srates, int srates_len, u32 *rates)
3557{
3558 u32 rate_flags = ieee80211_chandef_rate_flags(chandef);
3559 int shift = ieee80211_chandef_get_shift(chandef);
3560 struct ieee80211_rate *br;
3561 int brate, rate, i, j, count = 0;
3562
3563 *rates = 0;
3564
3565 for (i = 0; i < srates_len; i++) {
3566 rate = srates[i] & 0x7f;
3567
3568 for (j = 0; j < sband->n_bitrates; j++) {
3569 br = &sband->bitrates[j];
3570 if ((rate_flags & br->flags) != rate_flags)
3571 continue;
3572
3573 brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
3574 if (brate == rate) {
3575 *rates |= BIT(j);
3576 count++;
3577 break;
3578 }
3579 }
3580 }
3581 return count;
3582}
3583
3584int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
3585 struct sk_buff *skb, bool need_basic,
3586 enum nl80211_band band)
3587{
3588 struct ieee80211_local *local = sdata->local;
3589 struct ieee80211_supported_band *sband;
3590 int rate, shift;
3591 u8 i, rates, *pos;
3592 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
3593 u32 rate_flags;
3594
3595 shift = ieee80211_vif_get_shift(&sdata->vif);
3596 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
3597 sband = local->hw.wiphy->bands[band];
3598 rates = 0;
3599 for (i = 0; i < sband->n_bitrates; i++) {
3600 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
3601 continue;
3602 rates++;
3603 }
3604 if (rates > 8)
3605 rates = 8;
3606
3607 if (skb_tailroom(skb) < rates + 2)
3608 return -ENOMEM;
3609
3610 pos = skb_put(skb, rates + 2);
3611 *pos++ = WLAN_EID_SUPP_RATES;
3612 *pos++ = rates;
3613 for (i = 0; i < rates; i++) {
3614 u8 basic = 0;
3615 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
3616 continue;
3617
3618 if (need_basic && basic_rates & BIT(i))
3619 basic = 0x80;
3620 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
3621 5 * (1 << shift));
3622 *pos++ = basic | (u8) rate;
3623 }
3624
3625 return 0;
3626}
3627
3628int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
3629 struct sk_buff *skb, bool need_basic,
3630 enum nl80211_band band)
3631{
3632 struct ieee80211_local *local = sdata->local;
3633 struct ieee80211_supported_band *sband;
3634 int rate, shift;
3635 u8 i, exrates, *pos;
3636 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
3637 u32 rate_flags;
3638
3639 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
3640 shift = ieee80211_vif_get_shift(&sdata->vif);
3641
3642 sband = local->hw.wiphy->bands[band];
3643 exrates = 0;
3644 for (i = 0; i < sband->n_bitrates; i++) {
3645 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
3646 continue;
3647 exrates++;
3648 }
3649
3650 if (exrates > 8)
3651 exrates -= 8;
3652 else
3653 exrates = 0;
3654
3655 if (skb_tailroom(skb) < exrates + 2)
3656 return -ENOMEM;
3657
3658 if (exrates) {
3659 pos = skb_put(skb, exrates + 2);
3660 *pos++ = WLAN_EID_EXT_SUPP_RATES;
3661 *pos++ = exrates;
3662 for (i = 8; i < sband->n_bitrates; i++) {
3663 u8 basic = 0;
3664 if ((rate_flags & sband->bitrates[i].flags)
3665 != rate_flags)
3666 continue;
3667 if (need_basic && basic_rates & BIT(i))
3668 basic = 0x80;
3669 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
3670 5 * (1 << shift));
3671 *pos++ = basic | (u8) rate;
3672 }
3673 }
3674 return 0;
3675}
3676
3677int ieee80211_ave_rssi(struct ieee80211_vif *vif)
3678{
3679 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
3680 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3681
3682 if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION)) {
3683 /* non-managed type inferfaces */
3684 return 0;
3685 }
3686 return -ewma_beacon_signal_read(&ifmgd->ave_beacon_signal);
3687}
3688EXPORT_SYMBOL_GPL(ieee80211_ave_rssi);
3689
3690u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs)
3691{
3692 if (!mcs)
3693 return 1;
3694
3695 /* TODO: consider rx_highest */
3696
3697 if (mcs->rx_mask[3])
3698 return 4;
3699 if (mcs->rx_mask[2])
3700 return 3;
3701 if (mcs->rx_mask[1])
3702 return 2;
3703 return 1;
3704}
3705
3706/**
3707 * ieee80211_calculate_rx_timestamp - calculate timestamp in frame
3708 * @local: mac80211 hw info struct
3709 * @status: RX status
3710 * @mpdu_len: total MPDU length (including FCS)
3711 * @mpdu_offset: offset into MPDU to calculate timestamp at
3712 *
3713 * This function calculates the RX timestamp at the given MPDU offset, taking
3714 * into account what the RX timestamp was. An offset of 0 will just normalize
3715 * the timestamp to TSF at beginning of MPDU reception.
3716 */
3717u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
3718 struct ieee80211_rx_status *status,
3719 unsigned int mpdu_len,
3720 unsigned int mpdu_offset)
3721{
3722 u64 ts = status->mactime;
3723 struct rate_info ri;
3724 u16 rate;
Googlerb48fa912023-03-17 12:40:29 +05303725 u8 n_ltf;
Googleraf606d22022-10-26 21:40:12 -07003726
3727 if (WARN_ON(!ieee80211_have_rx_timestamp(status)))
3728 return 0;
3729
3730 memset(&ri, 0, sizeof(ri));
3731
Googler9398cc32022-12-02 17:21:52 +08003732 ri.bw = status->bw;
3733
Googleraf606d22022-10-26 21:40:12 -07003734 /* Fill cfg80211 rate info */
Googler9398cc32022-12-02 17:21:52 +08003735 switch (status->encoding) {
Googlerb48fa912023-03-17 12:40:29 +05303736 case RX_ENC_HE:
3737 ri.flags |= RATE_INFO_FLAGS_HE_MCS;
3738 ri.mcs = status->rate_idx;
3739 ri.nss = status->nss;
3740 ri.he_ru_alloc = status->he_ru;
3741 if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
3742 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
3743
3744 /*
3745 * See P802.11ax_D6.0, section 27.3.4 for
3746 * VHT PPDU format.
3747 */
3748 if (status->flag & RX_FLAG_MACTIME_PLCP_START) {
3749 mpdu_offset += 2;
3750 ts += 36;
3751
3752 /*
3753 * TODO:
3754 * For HE MU PPDU, add the HE-SIG-B.
3755 * For HE ER PPDU, add 8us for the HE-SIG-A.
3756 * For HE TB PPDU, add 4us for the HE-STF.
3757 * Add the HE-LTF durations - variable.
3758 */
3759 }
3760
3761 break;
Googler9398cc32022-12-02 17:21:52 +08003762 case RX_ENC_HT:
Googleraf606d22022-10-26 21:40:12 -07003763 ri.mcs = status->rate_idx;
3764 ri.flags |= RATE_INFO_FLAGS_MCS;
Googler9398cc32022-12-02 17:21:52 +08003765 if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
Googleraf606d22022-10-26 21:40:12 -07003766 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
Googlerb48fa912023-03-17 12:40:29 +05303767
3768 /*
3769 * See P802.11REVmd_D3.0, section 19.3.2 for
3770 * HT PPDU format.
3771 */
3772 if (status->flag & RX_FLAG_MACTIME_PLCP_START) {
3773 mpdu_offset += 2;
3774 if (status->enc_flags & RX_ENC_FLAG_HT_GF)
3775 ts += 24;
3776 else
3777 ts += 32;
3778
3779 /*
3780 * Add Data HT-LTFs per streams
3781 * TODO: add Extension HT-LTFs, 4us per LTF
3782 */
3783 n_ltf = ((ri.mcs >> 3) & 3) + 1;
3784 n_ltf = n_ltf == 3 ? 4 : n_ltf;
3785 ts += n_ltf * 4;
3786 }
3787
Googler9398cc32022-12-02 17:21:52 +08003788 break;
3789 case RX_ENC_VHT:
Googleraf606d22022-10-26 21:40:12 -07003790 ri.flags |= RATE_INFO_FLAGS_VHT_MCS;
3791 ri.mcs = status->rate_idx;
Googler9398cc32022-12-02 17:21:52 +08003792 ri.nss = status->nss;
3793 if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
Googleraf606d22022-10-26 21:40:12 -07003794 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
Googlerb48fa912023-03-17 12:40:29 +05303795
3796 /*
3797 * See P802.11REVmd_D3.0, section 21.3.2 for
3798 * VHT PPDU format.
3799 */
3800 if (status->flag & RX_FLAG_MACTIME_PLCP_START) {
3801 mpdu_offset += 2;
3802 ts += 36;
3803
3804 /*
3805 * Add VHT-LTFs per streams
3806 */
3807 n_ltf = (ri.nss != 1) && (ri.nss % 2) ?
3808 ri.nss + 1 : ri.nss;
3809 ts += 4 * n_ltf;
3810 }
3811
Googler9398cc32022-12-02 17:21:52 +08003812 break;
3813 default:
3814 WARN_ON(1);
Googlerb48fa912023-03-17 12:40:29 +05303815 fallthrough;
Googler9398cc32022-12-02 17:21:52 +08003816 case RX_ENC_LEGACY: {
Googleraf606d22022-10-26 21:40:12 -07003817 struct ieee80211_supported_band *sband;
3818 int shift = 0;
3819 int bitrate;
3820
Googler9398cc32022-12-02 17:21:52 +08003821 switch (status->bw) {
3822 case RATE_INFO_BW_10:
Googleraf606d22022-10-26 21:40:12 -07003823 shift = 1;
Googler9398cc32022-12-02 17:21:52 +08003824 break;
3825 case RATE_INFO_BW_5:
Googleraf606d22022-10-26 21:40:12 -07003826 shift = 2;
Googler9398cc32022-12-02 17:21:52 +08003827 break;
Googleraf606d22022-10-26 21:40:12 -07003828 }
3829
3830 sband = local->hw.wiphy->bands[status->band];
3831 bitrate = sband->bitrates[status->rate_idx].bitrate;
3832 ri.legacy = DIV_ROUND_UP(bitrate, (1 << shift));
3833
3834 if (status->flag & RX_FLAG_MACTIME_PLCP_START) {
Googleraf606d22022-10-26 21:40:12 -07003835 if (status->band == NL80211_BAND_5GHZ) {
3836 ts += 20 << shift;
3837 mpdu_offset += 2;
Googler9398cc32022-12-02 17:21:52 +08003838 } else if (status->enc_flags & RX_ENC_FLAG_SHORTPRE) {
Googleraf606d22022-10-26 21:40:12 -07003839 ts += 96;
3840 } else {
3841 ts += 192;
3842 }
3843 }
Googler9398cc32022-12-02 17:21:52 +08003844 break;
3845 }
Googleraf606d22022-10-26 21:40:12 -07003846 }
3847
3848 rate = cfg80211_calculate_bitrate(&ri);
3849 if (WARN_ONCE(!rate,
3850 "Invalid bitrate: flags=0x%llx, idx=%d, vht_nss=%d\n",
3851 (unsigned long long)status->flag, status->rate_idx,
Googler9398cc32022-12-02 17:21:52 +08003852 status->nss))
Googleraf606d22022-10-26 21:40:12 -07003853 return 0;
3854
3855 /* rewind from end of MPDU */
3856 if (status->flag & RX_FLAG_MACTIME_END)
3857 ts -= mpdu_len * 8 * 10 / rate;
3858
3859 ts += mpdu_offset * 8 * 10 / rate;
3860
3861 return ts;
3862}
3863
3864void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
3865{
3866 struct ieee80211_sub_if_data *sdata;
3867 struct cfg80211_chan_def chandef;
3868
Googler9398cc32022-12-02 17:21:52 +08003869 /* for interface list, to avoid linking iflist_mtx and chanctx_mtx */
Googlerb48fa912023-03-17 12:40:29 +05303870 lockdep_assert_wiphy(local->hw.wiphy);
Googler9398cc32022-12-02 17:21:52 +08003871
Googleraf606d22022-10-26 21:40:12 -07003872 mutex_lock(&local->mtx);
Googleraf606d22022-10-26 21:40:12 -07003873 list_for_each_entry(sdata, &local->interfaces, list) {
3874 /* it might be waiting for the local->mtx, but then
3875 * by the time it gets it, sdata->wdev.cac_started
3876 * will no longer be true
3877 */
3878 cancel_delayed_work(&sdata->dfs_cac_timer_work);
3879
3880 if (sdata->wdev.cac_started) {
3881 chandef = sdata->vif.bss_conf.chandef;
3882 ieee80211_vif_release_channel(sdata);
3883 cfg80211_cac_event(sdata->dev,
3884 &chandef,
3885 NL80211_RADAR_CAC_ABORTED,
3886 GFP_KERNEL);
3887 }
3888 }
Googleraf606d22022-10-26 21:40:12 -07003889 mutex_unlock(&local->mtx);
3890}
3891
Googlerb48fa912023-03-17 12:40:29 +05303892void ieee80211_awgn_detected_work(struct work_struct *work)
3893{
3894 struct ieee80211_local *local =
3895 container_of(work, struct ieee80211_local, awgn_detected_work);
3896 struct cfg80211_chan_def chandef = local->hw.conf.chandef;
3897 struct ieee80211_chanctx *ctx;
3898 int num_chanctx = 0;
3899
3900 mutex_lock(&local->chanctx_mtx);
3901 list_for_each_entry(ctx, &local->chanctx_list, list) {
3902 if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
3903 continue;
3904
3905 num_chanctx++;
3906 chandef = ctx->conf.def;
3907 }
3908 mutex_unlock(&local->chanctx_mtx);
3909
3910 if (num_chanctx > 1)
3911 /* XXX: multi-channel is not supported yet */
3912 WARN_ON_ONCE(1);
3913 else
3914 cfg80211_awgn_event(local->hw.wiphy, &chandef, GFP_KERNEL,
3915 local->chan_bw_interference_bitmap);
3916}
3917
Googleraf606d22022-10-26 21:40:12 -07003918void ieee80211_dfs_radar_detected_work(struct work_struct *work)
3919{
3920 struct ieee80211_local *local =
3921 container_of(work, struct ieee80211_local, radar_detected_work);
3922 struct cfg80211_chan_def chandef = local->hw.conf.chandef;
3923 struct ieee80211_chanctx *ctx;
3924 int num_chanctx = 0;
3925
3926 mutex_lock(&local->chanctx_mtx);
3927 list_for_each_entry(ctx, &local->chanctx_list, list) {
3928 if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
3929 continue;
3930
3931 num_chanctx++;
3932 chandef = ctx->conf.def;
3933 }
3934 mutex_unlock(&local->chanctx_mtx);
3935
Googlerb48fa912023-03-17 12:40:29 +05303936 wiphy_lock(local->hw.wiphy);
Googleraf606d22022-10-26 21:40:12 -07003937 ieee80211_dfs_cac_cancel(local);
Googlerb48fa912023-03-17 12:40:29 +05303938 wiphy_unlock(local->hw.wiphy);
Googleraf606d22022-10-26 21:40:12 -07003939
3940 if (num_chanctx > 1)
3941 /* XXX: multi-channel is not supported yet */
3942 WARN_ON(1);
3943 else
3944 cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
3945}
3946
3947void ieee80211_radar_detected(struct ieee80211_hw *hw)
3948{
3949 struct ieee80211_local *local = hw_to_local(hw);
3950
3951 trace_api_radar_detected(local);
3952
Googler9398cc32022-12-02 17:21:52 +08003953 schedule_work(&local->radar_detected_work);
Googleraf606d22022-10-26 21:40:12 -07003954}
3955EXPORT_SYMBOL(ieee80211_radar_detected);
3956
Googlerb48fa912023-03-17 12:40:29 +05303957void ieee80211_awgn_detected(struct ieee80211_hw *hw, u32 chan_bw_interference_bitmap)
3958{
3959 struct ieee80211_local *local = hw_to_local(hw);
3960
3961 local->chan_bw_interference_bitmap = chan_bw_interference_bitmap;
3962 schedule_work(&local->awgn_detected_work);
3963}
3964EXPORT_SYMBOL(ieee80211_awgn_detected);
3965
Googleraf606d22022-10-26 21:40:12 -07003966u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c)
3967{
3968 u32 ret;
3969 int tmp;
3970
3971 switch (c->width) {
3972 case NL80211_CHAN_WIDTH_20:
3973 c->width = NL80211_CHAN_WIDTH_20_NOHT;
3974 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
3975 break;
3976 case NL80211_CHAN_WIDTH_40:
3977 c->width = NL80211_CHAN_WIDTH_20;
3978 c->center_freq1 = c->chan->center_freq;
3979 ret = IEEE80211_STA_DISABLE_40MHZ |
3980 IEEE80211_STA_DISABLE_VHT;
3981 break;
3982 case NL80211_CHAN_WIDTH_80:
3983 tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
3984 /* n_P40 */
3985 tmp /= 2;
3986 /* freq_P40 */
3987 c->center_freq1 = c->center_freq1 - 20 + 40 * tmp;
3988 c->width = NL80211_CHAN_WIDTH_40;
3989 ret = IEEE80211_STA_DISABLE_VHT;
3990 break;
3991 case NL80211_CHAN_WIDTH_80P80:
3992 c->center_freq2 = 0;
3993 c->width = NL80211_CHAN_WIDTH_80;
3994 ret = IEEE80211_STA_DISABLE_80P80MHZ |
3995 IEEE80211_STA_DISABLE_160MHZ;
3996 break;
3997 case NL80211_CHAN_WIDTH_160:
3998 /* n_P20 */
3999 tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
4000 /* n_P80 */
4001 tmp /= 4;
4002 c->center_freq1 = c->center_freq1 - 40 + 80 * tmp;
4003 c->width = NL80211_CHAN_WIDTH_80;
4004 ret = IEEE80211_STA_DISABLE_80P80MHZ |
4005 IEEE80211_STA_DISABLE_160MHZ;
4006 break;
4007 default:
4008 case NL80211_CHAN_WIDTH_20_NOHT:
4009 WARN_ON_ONCE(1);
4010 c->width = NL80211_CHAN_WIDTH_20_NOHT;
4011 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
4012 break;
Googlerb48fa912023-03-17 12:40:29 +05304013 case NL80211_CHAN_WIDTH_1:
4014 case NL80211_CHAN_WIDTH_2:
4015 case NL80211_CHAN_WIDTH_4:
4016 case NL80211_CHAN_WIDTH_8:
4017 case NL80211_CHAN_WIDTH_16:
Googleraf606d22022-10-26 21:40:12 -07004018 case NL80211_CHAN_WIDTH_5:
4019 case NL80211_CHAN_WIDTH_10:
4020 WARN_ON_ONCE(1);
4021 /* keep c->width */
4022 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
4023 break;
4024 }
4025
4026 WARN_ON_ONCE(!cfg80211_chandef_valid(c));
4027
4028 return ret;
4029}
4030
4031/*
4032 * Returns true if smps_mode_new is strictly more restrictive than
4033 * smps_mode_old.
4034 */
4035bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old,
4036 enum ieee80211_smps_mode smps_mode_new)
4037{
4038 if (WARN_ON_ONCE(smps_mode_old == IEEE80211_SMPS_AUTOMATIC ||
4039 smps_mode_new == IEEE80211_SMPS_AUTOMATIC))
4040 return false;
4041
4042 switch (smps_mode_old) {
4043 case IEEE80211_SMPS_STATIC:
4044 return false;
4045 case IEEE80211_SMPS_DYNAMIC:
4046 return smps_mode_new == IEEE80211_SMPS_STATIC;
4047 case IEEE80211_SMPS_OFF:
4048 return smps_mode_new != IEEE80211_SMPS_OFF;
4049 default:
4050 WARN_ON(1);
4051 }
4052
4053 return false;
4054}
4055
4056int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
4057 struct cfg80211_csa_settings *csa_settings)
4058{
4059 struct sk_buff *skb;
4060 struct ieee80211_mgmt *mgmt;
4061 struct ieee80211_local *local = sdata->local;
4062 int freq;
Googler9398cc32022-12-02 17:21:52 +08004063 int hdr_len = offsetofend(struct ieee80211_mgmt,
4064 u.action.u.chan_switch);
Googleraf606d22022-10-26 21:40:12 -07004065 u8 *pos;
4066
4067 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
4068 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
4069 return -EOPNOTSUPP;
4070
4071 skb = dev_alloc_skb(local->tx_headroom + hdr_len +
4072 5 + /* channel switch announcement element */
4073 3 + /* secondary channel offset element */
Googler9398cc32022-12-02 17:21:52 +08004074 5 + /* wide bandwidth channel switch announcement */
Googleraf606d22022-10-26 21:40:12 -07004075 8); /* mesh channel switch parameters element */
4076 if (!skb)
4077 return -ENOMEM;
4078
4079 skb_reserve(skb, local->tx_headroom);
Googler9398cc32022-12-02 17:21:52 +08004080 mgmt = skb_put_zero(skb, hdr_len);
Googleraf606d22022-10-26 21:40:12 -07004081 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
4082 IEEE80211_STYPE_ACTION);
4083
4084 eth_broadcast_addr(mgmt->da);
4085 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
4086 if (ieee80211_vif_is_mesh(&sdata->vif)) {
4087 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
4088 } else {
4089 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
4090 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
4091 }
4092 mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
4093 mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
4094 pos = skb_put(skb, 5);
4095 *pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */
4096 *pos++ = 3; /* IE length */
4097 *pos++ = csa_settings->block_tx ? 1 : 0; /* CSA mode */
4098 freq = csa_settings->chandef.chan->center_freq;
4099 *pos++ = ieee80211_frequency_to_channel(freq); /* channel */
4100 *pos++ = csa_settings->count; /* count */
4101
4102 if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) {
4103 enum nl80211_channel_type ch_type;
4104
4105 skb_put(skb, 3);
4106 *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */
4107 *pos++ = 1; /* IE length */
4108 ch_type = cfg80211_get_chandef_type(&csa_settings->chandef);
4109 if (ch_type == NL80211_CHAN_HT40PLUS)
4110 *pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
4111 else
4112 *pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
4113 }
4114
4115 if (ieee80211_vif_is_mesh(&sdata->vif)) {
4116 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
4117
4118 skb_put(skb, 8);
4119 *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; /* EID */
4120 *pos++ = 6; /* IE length */
4121 *pos++ = sdata->u.mesh.mshcfg.dot11MeshTTL; /* Mesh TTL */
4122 *pos = 0x00; /* Mesh Flag: Tx Restrict, Initiator, Reason */
4123 *pos |= WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
4124 *pos++ |= csa_settings->block_tx ?
4125 WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
4126 put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */
4127 pos += 2;
4128 put_unaligned_le16(ifmsh->pre_value, pos);/* Precedence Value */
4129 pos += 2;
4130 }
4131
Googler9398cc32022-12-02 17:21:52 +08004132 if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_80 ||
4133 csa_settings->chandef.width == NL80211_CHAN_WIDTH_80P80 ||
4134 csa_settings->chandef.width == NL80211_CHAN_WIDTH_160) {
4135 skb_put(skb, 5);
4136 ieee80211_ie_build_wide_bw_cs(pos, &csa_settings->chandef);
4137 }
4138
Googleraf606d22022-10-26 21:40:12 -07004139 ieee80211_tx_skb(sdata, skb);
4140 return 0;
4141}
4142
4143bool ieee80211_cs_valid(const struct ieee80211_cipher_scheme *cs)
4144{
4145 return !(cs == NULL || cs->cipher == 0 ||
4146 cs->hdr_len < cs->pn_len + cs->pn_off ||
4147 cs->hdr_len <= cs->key_idx_off ||
4148 cs->key_idx_shift > 7 ||
4149 cs->key_idx_mask == 0);
4150}
4151
4152bool ieee80211_cs_list_valid(const struct ieee80211_cipher_scheme *cs, int n)
4153{
4154 int i;
4155
4156 /* Ensure we have enough iftype bitmap space for all iftype values */
4157 WARN_ON((NUM_NL80211_IFTYPES / 8 + 1) > sizeof(cs[0].iftype));
4158
4159 for (i = 0; i < n; i++)
4160 if (!ieee80211_cs_valid(&cs[i]))
4161 return false;
4162
4163 return true;
4164}
4165
4166const struct ieee80211_cipher_scheme *
4167ieee80211_cs_get(struct ieee80211_local *local, u32 cipher,
4168 enum nl80211_iftype iftype)
4169{
4170 const struct ieee80211_cipher_scheme *l = local->hw.cipher_schemes;
4171 int n = local->hw.n_cipher_schemes;
4172 int i;
4173 const struct ieee80211_cipher_scheme *cs = NULL;
4174
4175 for (i = 0; i < n; i++) {
4176 if (l[i].cipher == cipher) {
4177 cs = &l[i];
4178 break;
4179 }
4180 }
4181
4182 if (!cs || !(cs->iftype & BIT(iftype)))
4183 return NULL;
4184
4185 return cs;
4186}
4187
4188int ieee80211_cs_headroom(struct ieee80211_local *local,
4189 struct cfg80211_crypto_settings *crypto,
4190 enum nl80211_iftype iftype)
4191{
4192 const struct ieee80211_cipher_scheme *cs;
4193 int headroom = IEEE80211_ENCRYPT_HEADROOM;
4194 int i;
4195
4196 for (i = 0; i < crypto->n_ciphers_pairwise; i++) {
4197 cs = ieee80211_cs_get(local, crypto->ciphers_pairwise[i],
4198 iftype);
4199
4200 if (cs && headroom < cs->hdr_len)
4201 headroom = cs->hdr_len;
4202 }
4203
4204 cs = ieee80211_cs_get(local, crypto->cipher_group, iftype);
4205 if (cs && headroom < cs->hdr_len)
4206 headroom = cs->hdr_len;
4207
4208 return headroom;
4209}
4210
4211static bool
4212ieee80211_extend_noa_desc(struct ieee80211_noa_data *data, u32 tsf, int i)
4213{
4214 s32 end = data->desc[i].start + data->desc[i].duration - (tsf + 1);
4215 int skip;
4216
4217 if (end > 0)
4218 return false;
4219
4220 /* One shot NOA */
4221 if (data->count[i] == 1)
4222 return false;
4223
4224 if (data->desc[i].interval == 0)
4225 return false;
4226
4227 /* End time is in the past, check for repetitions */
4228 skip = DIV_ROUND_UP(-end, data->desc[i].interval);
4229 if (data->count[i] < 255) {
4230 if (data->count[i] <= skip) {
4231 data->count[i] = 0;
4232 return false;
4233 }
4234
4235 data->count[i] -= skip;
4236 }
4237
4238 data->desc[i].start += skip * data->desc[i].interval;
4239
4240 return true;
4241}
4242
4243static bool
4244ieee80211_extend_absent_time(struct ieee80211_noa_data *data, u32 tsf,
4245 s32 *offset)
4246{
4247 bool ret = false;
4248 int i;
4249
4250 for (i = 0; i < IEEE80211_P2P_NOA_DESC_MAX; i++) {
4251 s32 cur;
4252
4253 if (!data->count[i])
4254 continue;
4255
4256 if (ieee80211_extend_noa_desc(data, tsf + *offset, i))
4257 ret = true;
4258
4259 cur = data->desc[i].start - tsf;
4260 if (cur > *offset)
4261 continue;
4262
4263 cur = data->desc[i].start + data->desc[i].duration - tsf;
4264 if (cur > *offset)
4265 *offset = cur;
4266 }
4267
4268 return ret;
4269}
4270
4271static u32
4272ieee80211_get_noa_absent_time(struct ieee80211_noa_data *data, u32 tsf)
4273{
4274 s32 offset = 0;
4275 int tries = 0;
4276 /*
4277 * arbitrary limit, used to avoid infinite loops when combined NoA
4278 * descriptors cover the full time period.
4279 */
4280 int max_tries = 5;
4281
4282 ieee80211_extend_absent_time(data, tsf, &offset);
4283 do {
4284 if (!ieee80211_extend_absent_time(data, tsf, &offset))
4285 break;
4286
4287 tries++;
4288 } while (tries < max_tries);
4289
4290 return offset;
4291}
4292
4293void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf)
4294{
4295 u32 next_offset = BIT(31) - 1;
4296 int i;
4297
4298 data->absent = 0;
4299 data->has_next_tsf = false;
4300 for (i = 0; i < IEEE80211_P2P_NOA_DESC_MAX; i++) {
4301 s32 start;
4302
4303 if (!data->count[i])
4304 continue;
4305
4306 ieee80211_extend_noa_desc(data, tsf, i);
4307 start = data->desc[i].start - tsf;
4308 if (start <= 0)
4309 data->absent |= BIT(i);
4310
4311 if (next_offset > start)
4312 next_offset = start;
4313
4314 data->has_next_tsf = true;
4315 }
4316
4317 if (data->absent)
4318 next_offset = ieee80211_get_noa_absent_time(data, tsf);
4319
4320 data->next_tsf = tsf + next_offset;
4321}
4322EXPORT_SYMBOL(ieee80211_update_p2p_noa);
4323
4324int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr,
4325 struct ieee80211_noa_data *data, u32 tsf)
4326{
4327 int ret = 0;
4328 int i;
4329
4330 memset(data, 0, sizeof(*data));
4331
4332 for (i = 0; i < IEEE80211_P2P_NOA_DESC_MAX; i++) {
4333 const struct ieee80211_p2p_noa_desc *desc = &attr->desc[i];
4334
4335 if (!desc->count || !desc->duration)
4336 continue;
4337
4338 data->count[i] = desc->count;
4339 data->desc[i].start = le32_to_cpu(desc->start_time);
4340 data->desc[i].duration = le32_to_cpu(desc->duration);
4341 data->desc[i].interval = le32_to_cpu(desc->interval);
4342
4343 if (data->count[i] > 1 &&
4344 data->desc[i].interval < data->desc[i].duration)
4345 continue;
4346
4347 ieee80211_extend_noa_desc(data, tsf, i);
4348 ret++;
4349 }
4350
4351 if (ret)
4352 ieee80211_update_p2p_noa(data, tsf);
4353
4354 return ret;
4355}
4356EXPORT_SYMBOL(ieee80211_parse_p2p_noa);
4357
4358void ieee80211_recalc_dtim(struct ieee80211_local *local,
4359 struct ieee80211_sub_if_data *sdata)
4360{
4361 u64 tsf = drv_get_tsf(local, sdata);
4362 u64 dtim_count = 0;
4363 u16 beacon_int = sdata->vif.bss_conf.beacon_int * 1024;
4364 u8 dtim_period = sdata->vif.bss_conf.dtim_period;
4365 struct ps_data *ps;
4366 u8 bcns_from_dtim;
4367
4368 if (tsf == -1ULL || !beacon_int || !dtim_period)
4369 return;
4370
4371 if (sdata->vif.type == NL80211_IFTYPE_AP ||
4372 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
4373 if (!sdata->bss)
4374 return;
4375
4376 ps = &sdata->bss->ps;
4377 } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
4378 ps = &sdata->u.mesh.ps;
4379 } else {
4380 return;
4381 }
4382
4383 /*
4384 * actually finds last dtim_count, mac80211 will update in
4385 * __beacon_add_tim().
4386 * dtim_count = dtim_period - (tsf / bcn_int) % dtim_period
4387 */
4388 do_div(tsf, beacon_int);
4389 bcns_from_dtim = do_div(tsf, dtim_period);
4390 /* just had a DTIM */
4391 if (!bcns_from_dtim)
4392 dtim_count = 0;
4393 else
4394 dtim_count = dtim_period - bcns_from_dtim;
4395
4396 ps->dtim_count = dtim_count;
4397}
4398
4399static u8 ieee80211_chanctx_radar_detect(struct ieee80211_local *local,
4400 struct ieee80211_chanctx *ctx)
4401{
4402 struct ieee80211_sub_if_data *sdata;
4403 u8 radar_detect = 0;
4404
4405 lockdep_assert_held(&local->chanctx_mtx);
4406
4407 if (WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED))
4408 return 0;
4409
4410 list_for_each_entry(sdata, &ctx->reserved_vifs, reserved_chanctx_list)
4411 if (sdata->reserved_radar_required)
4412 radar_detect |= BIT(sdata->reserved_chandef.width);
4413
4414 /*
4415 * An in-place reservation context should not have any assigned vifs
4416 * until it replaces the other context.
4417 */
4418 WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER &&
4419 !list_empty(&ctx->assigned_vifs));
4420
4421 list_for_each_entry(sdata, &ctx->assigned_vifs, assigned_chanctx_list)
4422 if (sdata->radar_required)
4423 radar_detect |= BIT(sdata->vif.bss_conf.chandef.width);
4424
4425 return radar_detect;
4426}
4427
4428int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
4429 const struct cfg80211_chan_def *chandef,
4430 enum ieee80211_chanctx_mode chanmode,
4431 u8 radar_detect)
4432{
4433 struct ieee80211_local *local = sdata->local;
4434 struct ieee80211_sub_if_data *sdata_iter;
4435 enum nl80211_iftype iftype = sdata->wdev.iftype;
Googleraf606d22022-10-26 21:40:12 -07004436 struct ieee80211_chanctx *ctx;
Googleraf606d22022-10-26 21:40:12 -07004437 int total = 1;
Googler9398cc32022-12-02 17:21:52 +08004438 struct iface_combination_params params = {
4439 .radar_detect = radar_detect,
4440 };
Googleraf606d22022-10-26 21:40:12 -07004441
4442 lockdep_assert_held(&local->chanctx_mtx);
4443
4444 if (WARN_ON(hweight32(radar_detect) > 1))
4445 return -EINVAL;
4446
4447 if (WARN_ON(chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
4448 !chandef->chan))
4449 return -EINVAL;
4450
Googleraf606d22022-10-26 21:40:12 -07004451 if (WARN_ON(iftype >= NUM_NL80211_IFTYPES))
4452 return -EINVAL;
4453
Googler9398cc32022-12-02 17:21:52 +08004454 if (sdata->vif.type == NL80211_IFTYPE_AP ||
4455 sdata->vif.type == NL80211_IFTYPE_MESH_POINT) {
4456 /*
4457 * always passing this is harmless, since it'll be the
4458 * same value that cfg80211 finds if it finds the same
4459 * interface ... and that's always allowed
4460 */
4461 params.new_beacon_int = sdata->vif.bss_conf.beacon_int;
4462 }
4463
Googleraf606d22022-10-26 21:40:12 -07004464 /* Always allow software iftypes */
Googler9398cc32022-12-02 17:21:52 +08004465 if (cfg80211_iftype_allowed(local->hw.wiphy, iftype, 0, 1)) {
Googleraf606d22022-10-26 21:40:12 -07004466 if (radar_detect)
4467 return -EINVAL;
4468 return 0;
4469 }
4470
Googler9398cc32022-12-02 17:21:52 +08004471 if (chandef)
4472 params.num_different_channels = 1;
Googleraf606d22022-10-26 21:40:12 -07004473
4474 if (iftype != NL80211_IFTYPE_UNSPECIFIED)
Googler9398cc32022-12-02 17:21:52 +08004475 params.iftype_num[iftype] = 1;
Googleraf606d22022-10-26 21:40:12 -07004476
4477 list_for_each_entry(ctx, &local->chanctx_list, list) {
4478 if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
4479 continue;
Googler9398cc32022-12-02 17:21:52 +08004480 params.radar_detect |=
4481 ieee80211_chanctx_radar_detect(local, ctx);
Googleraf606d22022-10-26 21:40:12 -07004482 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) {
Googler9398cc32022-12-02 17:21:52 +08004483 params.num_different_channels++;
Googleraf606d22022-10-26 21:40:12 -07004484 continue;
4485 }
Googlerb48fa912023-03-17 12:40:29 +05304486 if (chandef && chanmode == IEEE80211_CHANCTX_SHARED) {
4487 /* 6 GHz chandefs could be different for different
4488 * interfaces because of operating power modes.
4489 * Hence, we skip the chandef compatibility check.
4490 */
4491 enum nl80211_band chan_band = chandef->chan->band;
4492 bool is_6ghz_band = chan_band == NL80211_BAND_6GHZ
4493 ? true : false;
4494
4495 if (is_6ghz_band)
4496 continue;
4497
4498 if (cfg80211_chandef_compatible(chandef,
4499 &ctx->conf.def))
4500 continue;
4501 }
Googler9398cc32022-12-02 17:21:52 +08004502 params.num_different_channels++;
Googleraf606d22022-10-26 21:40:12 -07004503 }
4504
4505 list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) {
4506 struct wireless_dev *wdev_iter;
4507
4508 wdev_iter = &sdata_iter->wdev;
4509
4510 if (sdata_iter == sdata ||
4511 !ieee80211_sdata_running(sdata_iter) ||
Googler9398cc32022-12-02 17:21:52 +08004512 cfg80211_iftype_allowed(local->hw.wiphy,
4513 wdev_iter->iftype, 0, 1))
Googleraf606d22022-10-26 21:40:12 -07004514 continue;
4515
Googler9398cc32022-12-02 17:21:52 +08004516 params.iftype_num[wdev_iter->iftype]++;
Googleraf606d22022-10-26 21:40:12 -07004517 total++;
4518 }
4519
Googler9398cc32022-12-02 17:21:52 +08004520 if (total == 1 && !params.radar_detect)
Googleraf606d22022-10-26 21:40:12 -07004521 return 0;
4522
Googler9398cc32022-12-02 17:21:52 +08004523 return cfg80211_check_combinations(local->hw.wiphy, &params);
Googleraf606d22022-10-26 21:40:12 -07004524}
4525
4526static void
4527ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c,
4528 void *data)
4529{
4530 u32 *max_num_different_channels = data;
4531
4532 *max_num_different_channels = max(*max_num_different_channels,
4533 c->num_different_channels);
4534}
4535
4536int ieee80211_max_num_channels(struct ieee80211_local *local)
4537{
4538 struct ieee80211_sub_if_data *sdata;
Googleraf606d22022-10-26 21:40:12 -07004539 struct ieee80211_chanctx *ctx;
Googleraf606d22022-10-26 21:40:12 -07004540 u32 max_num_different_channels = 1;
4541 int err;
Googler9398cc32022-12-02 17:21:52 +08004542 struct iface_combination_params params = {0};
Googleraf606d22022-10-26 21:40:12 -07004543
4544 lockdep_assert_held(&local->chanctx_mtx);
4545
4546 list_for_each_entry(ctx, &local->chanctx_list, list) {
4547 if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
4548 continue;
4549
Googler9398cc32022-12-02 17:21:52 +08004550 params.num_different_channels++;
Googleraf606d22022-10-26 21:40:12 -07004551
Googler9398cc32022-12-02 17:21:52 +08004552 params.radar_detect |=
4553 ieee80211_chanctx_radar_detect(local, ctx);
Googleraf606d22022-10-26 21:40:12 -07004554 }
4555
4556 list_for_each_entry_rcu(sdata, &local->interfaces, list)
Googler9398cc32022-12-02 17:21:52 +08004557 params.iftype_num[sdata->wdev.iftype]++;
Googleraf606d22022-10-26 21:40:12 -07004558
Googler9398cc32022-12-02 17:21:52 +08004559 err = cfg80211_iter_combinations(local->hw.wiphy, &params,
4560 ieee80211_iter_max_chans,
Googleraf606d22022-10-26 21:40:12 -07004561 &max_num_different_channels);
4562 if (err < 0)
4563 return err;
4564
4565 return max_num_different_channels;
4566}
4567
Googlerb48fa912023-03-17 12:40:29 +05304568void ieee80211_add_s1g_capab_ie(struct ieee80211_sub_if_data *sdata,
4569 struct ieee80211_sta_s1g_cap *caps,
4570 struct sk_buff *skb)
4571{
4572 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
4573 struct ieee80211_s1g_cap s1g_capab;
4574 u8 *pos;
4575 int i;
4576
4577 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
4578 return;
4579
4580 if (!caps->s1g)
4581 return;
4582
4583 memcpy(s1g_capab.capab_info, caps->cap, sizeof(caps->cap));
4584 memcpy(s1g_capab.supp_mcs_nss, caps->nss_mcs, sizeof(caps->nss_mcs));
4585
4586 /* override the capability info */
4587 for (i = 0; i < sizeof(ifmgd->s1g_capa.capab_info); i++) {
4588 u8 mask = ifmgd->s1g_capa_mask.capab_info[i];
4589
4590 s1g_capab.capab_info[i] &= ~mask;
4591 s1g_capab.capab_info[i] |= ifmgd->s1g_capa.capab_info[i] & mask;
4592 }
4593
4594 /* then MCS and NSS set */
4595 for (i = 0; i < sizeof(ifmgd->s1g_capa.supp_mcs_nss); i++) {
4596 u8 mask = ifmgd->s1g_capa_mask.supp_mcs_nss[i];
4597
4598 s1g_capab.supp_mcs_nss[i] &= ~mask;
4599 s1g_capab.supp_mcs_nss[i] |=
4600 ifmgd->s1g_capa.supp_mcs_nss[i] & mask;
4601 }
4602
4603 pos = skb_put(skb, 2 + sizeof(s1g_capab));
4604 *pos++ = WLAN_EID_S1G_CAPABILITIES;
4605 *pos++ = sizeof(s1g_capab);
4606
4607 memcpy(pos, &s1g_capab, sizeof(s1g_capab));
4608}
4609
4610void ieee80211_add_aid_request_ie(struct ieee80211_sub_if_data *sdata,
4611 struct sk_buff *skb)
4612{
4613 u8 *pos = skb_put(skb, 3);
4614
4615 *pos++ = WLAN_EID_AID_REQUEST;
4616 *pos++ = 1;
4617 *pos++ = 0;
4618}
4619
Googleraf606d22022-10-26 21:40:12 -07004620u8 *ieee80211_add_wmm_info_ie(u8 *buf, u8 qosinfo)
4621{
4622 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
4623 *buf++ = 7; /* len */
4624 *buf++ = 0x00; /* Microsoft OUI 00:50:F2 */
4625 *buf++ = 0x50;
4626 *buf++ = 0xf2;
4627 *buf++ = 2; /* WME */
4628 *buf++ = 0; /* WME info */
4629 *buf++ = 1; /* WME ver */
4630 *buf++ = qosinfo; /* U-APSD no in use */
4631
4632 return buf;
4633}
4634
4635void ieee80211_txq_get_depth(struct ieee80211_txq *txq,
4636 unsigned long *frame_cnt,
4637 unsigned long *byte_cnt)
4638{
4639 struct txq_info *txqi = to_txq_info(txq);
4640 u32 frag_cnt = 0, frag_bytes = 0;
4641 struct sk_buff *skb;
4642
4643 skb_queue_walk(&txqi->frags, skb) {
4644 frag_cnt++;
4645 frag_bytes += skb->len;
4646 }
4647
4648 if (frame_cnt)
4649 *frame_cnt = txqi->tin.backlog_packets + frag_cnt;
4650
4651 if (byte_cnt)
4652 *byte_cnt = txqi->tin.backlog_bytes + frag_bytes;
4653}
4654EXPORT_SYMBOL(ieee80211_txq_get_depth);
Googler9398cc32022-12-02 17:21:52 +08004655
4656const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS] = {
4657 IEEE80211_WMM_IE_STA_QOSINFO_AC_VO,
4658 IEEE80211_WMM_IE_STA_QOSINFO_AC_VI,
4659 IEEE80211_WMM_IE_STA_QOSINFO_AC_BE,
4660 IEEE80211_WMM_IE_STA_QOSINFO_AC_BK
4661};
Googlerb48fa912023-03-17 12:40:29 +05304662
4663u16 ieee80211_encode_usf(int listen_interval)
4664{
4665 static const int listen_int_usf[] = { 1, 10, 1000, 10000 };
4666 u16 ui, usf = 0;
4667
4668 /* find greatest USF */
4669 while (usf < IEEE80211_MAX_USF) {
4670 if (listen_interval % listen_int_usf[usf + 1])
4671 break;
4672 usf += 1;
4673 }
4674 ui = listen_interval / listen_int_usf[usf];
4675
4676 /* error if there is a remainder. Should've been checked by user */
4677 WARN_ON_ONCE(ui > IEEE80211_MAX_UI);
4678 listen_interval = FIELD_PREP(LISTEN_INT_USF, usf) |
4679 FIELD_PREP(LISTEN_INT_UI, ui);
4680
4681 return (u16) listen_interval;
4682}