Lines Matching +full:local +full:- +full:cap +full:- +full:size

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright 2002-2005, Instant802 Networks, Inc.
4 * Copyright 2005-2006, Devicescape Software, Inc.
5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
7 * Copyright 2013-2014 Intel Mobile Communications GmbH
8 * Copyright (C) 2015-2017 Intel Deutschland GmbH
9 * Copyright (C) 2018-2022 Intel Corporation
29 #include "driver-ops.h"
41 struct ieee80211_local *local; in wiphy_to_ieee80211_hw() local
43 local = wiphy_priv(wiphy); in wiphy_to_ieee80211_hw()
44 return &local->hw; in wiphy_to_ieee80211_hw()
51 __le16 fc = hdr->frame_control; in ieee80211_get_bssid()
60 return hdr->addr1; in ieee80211_get_bssid()
62 return hdr->addr2; in ieee80211_get_bssid()
64 return hdr->addr3; in ieee80211_get_bssid()
70 return ext->u.s1g_beacon.sa; in ieee80211_get_bssid()
76 return hdr->addr3; in ieee80211_get_bssid()
81 return hdr->addr1; in ieee80211_get_bssid()
86 return hdr->addr2; in ieee80211_get_bssid()
89 return hdr->addr1; in ieee80211_get_bssid()
105 skb_queue_walk(&tx->skbs, skb) { in ieee80211_tx_set_protected()
106 hdr = (struct ieee80211_hdr *) skb->data; in ieee80211_tx_set_protected()
107 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); in ieee80211_tx_set_protected()
139 * 802.11a - 18.5.2: aSIFSTime = 16 usec in ieee80211_frame_duration()
140 * 802.11g - 19.8.4: aSIFSTime = 10 usec + in ieee80211_frame_duration()
144 dur += 16; /* IEEE 802.11-2012 18.3.2.4: T_PREAMBLE = 16 usec */ in ieee80211_frame_duration()
145 dur += 4; /* IEEE 802.11-2012 18.3.2.4: T_SIGNAL = 4 usec */ in ieee80211_frame_duration()
147 /* IEEE 802.11-2012 18.3.2.4: all values above are: in ieee80211_frame_duration()
193 short_preamble = sdata->vif.bss_conf.use_short_preamble; in ieee80211_generic_frame_duration()
194 if (sdata->deflink.operating_11g_mode) in ieee80211_generic_frame_duration()
195 erp = rate->flags & IEEE80211_RATE_ERP_G; in ieee80211_generic_frame_duration()
199 dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp, in ieee80211_generic_frame_duration()
210 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_rts_duration() local
218 sband = local->hw.wiphy->bands[frame_txctl->band]; in ieee80211_rts_duration()
222 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; in ieee80211_rts_duration()
227 short_preamble = sdata->vif.bss_conf.use_short_preamble; in ieee80211_rts_duration()
228 if (sdata->deflink.operating_11g_mode) in ieee80211_rts_duration()
229 erp = rate->flags & IEEE80211_RATE_ERP_G; in ieee80211_rts_duration()
233 bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift); in ieee80211_rts_duration()
236 dur = ieee80211_frame_duration(sband->band, 10, bitrate, in ieee80211_rts_duration()
239 dur += ieee80211_frame_duration(sband->band, frame_len, bitrate, in ieee80211_rts_duration()
242 dur += ieee80211_frame_duration(sband->band, 10, bitrate, in ieee80211_rts_duration()
254 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_ctstoself_duration() local
262 sband = local->hw.wiphy->bands[frame_txctl->band]; in ieee80211_ctstoself_duration()
266 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; in ieee80211_ctstoself_duration()
270 short_preamble = sdata->vif.bss_conf.use_short_preamble; in ieee80211_ctstoself_duration()
271 if (sdata->deflink.operating_11g_mode) in ieee80211_ctstoself_duration()
272 erp = rate->flags & IEEE80211_RATE_ERP_G; in ieee80211_ctstoself_duration()
276 bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift); in ieee80211_ctstoself_duration()
279 dur = ieee80211_frame_duration(sband->band, frame_len, bitrate, in ieee80211_ctstoself_duration()
281 if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) { in ieee80211_ctstoself_duration()
283 dur += ieee80211_frame_duration(sband->band, 10, bitrate, in ieee80211_ctstoself_duration()
293 struct ieee80211_local *local = sdata->local; in __ieee80211_wake_txqs() local
294 struct ieee80211_vif *vif = &sdata->vif; in __ieee80211_wake_txqs()
295 struct fq *fq = &local->fq; in __ieee80211_wake_txqs()
302 spin_lock(&fq->lock); in __ieee80211_wake_txqs()
304 sdata->vif.txqs_stopped[ac] = false; in __ieee80211_wake_txqs()
306 if (!test_bit(SDATA_STATE_RUNNING, &sdata->state)) in __ieee80211_wake_txqs()
309 if (sdata->vif.type == NL80211_IFTYPE_AP) in __ieee80211_wake_txqs()
310 ps = &sdata->bss->ps; in __ieee80211_wake_txqs()
312 list_for_each_entry_rcu(sta, &local->sta_list, list) { in __ieee80211_wake_txqs()
313 if (sdata != sta->sdata) in __ieee80211_wake_txqs()
316 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { in __ieee80211_wake_txqs()
317 struct ieee80211_txq *txq = sta->sta.txq[i]; in __ieee80211_wake_txqs()
324 if (ac != txq->ac) in __ieee80211_wake_txqs()
328 &txqi->flags)) in __ieee80211_wake_txqs()
331 spin_unlock(&fq->lock); in __ieee80211_wake_txqs()
332 drv_wake_tx_queue(local, txqi); in __ieee80211_wake_txqs()
333 spin_lock(&fq->lock); in __ieee80211_wake_txqs()
337 if (!vif->txq) in __ieee80211_wake_txqs()
340 txqi = to_txq_info(vif->txq); in __ieee80211_wake_txqs()
342 if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags) || in __ieee80211_wake_txqs()
343 (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac) in __ieee80211_wake_txqs()
346 spin_unlock(&fq->lock); in __ieee80211_wake_txqs()
348 drv_wake_tx_queue(local, txqi); in __ieee80211_wake_txqs()
352 spin_unlock(&fq->lock); in __ieee80211_wake_txqs()
357 __releases(&local->queue_stop_reason_lock)
358 __acquires(&local->queue_stop_reason_lock)
359 _ieee80211_wake_txqs(struct ieee80211_local *local, unsigned long *flags) in _ieee80211_wake_txqs() argument
367 if (local->hw.queues < IEEE80211_NUM_ACS) in _ieee80211_wake_txqs()
370 for (i = 0; i < local->hw.queues; i++) { in _ieee80211_wake_txqs()
371 if (local->queue_stop_reasons[i]) in _ieee80211_wake_txqs()
374 spin_unlock_irqrestore(&local->queue_stop_reason_lock, *flags); in _ieee80211_wake_txqs()
375 list_for_each_entry_rcu(sdata, &local->interfaces, list) { in _ieee80211_wake_txqs()
379 int ac_queue = sdata->vif.hw_queue[ac]; in _ieee80211_wake_txqs()
382 sdata->vif.cab_queue == i) in _ieee80211_wake_txqs()
386 spin_lock_irqsave(&local->queue_stop_reason_lock, *flags); in _ieee80211_wake_txqs()
394 struct ieee80211_local *local = from_tasklet(local, t, in ieee80211_wake_txqs() local
398 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); in ieee80211_wake_txqs()
399 _ieee80211_wake_txqs(local, &flags); in ieee80211_wake_txqs()
400 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); in ieee80211_wake_txqs()
403 void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) in ieee80211_propagate_queue_wake() argument
408 if (local->ops->wake_tx_queue) in ieee80211_propagate_queue_wake()
411 if (local->hw.queues < IEEE80211_NUM_ACS) in ieee80211_propagate_queue_wake()
414 list_for_each_entry_rcu(sdata, &local->interfaces, list) { in ieee80211_propagate_queue_wake()
417 if (!sdata->dev) in ieee80211_propagate_queue_wake()
420 if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE && in ieee80211_propagate_queue_wake()
421 local->queue_stop_reasons[sdata->vif.cab_queue] != 0) in ieee80211_propagate_queue_wake()
425 int ac_queue = sdata->vif.hw_queue[ac]; in ieee80211_propagate_queue_wake()
428 (sdata->vif.cab_queue == queue && in ieee80211_propagate_queue_wake()
429 local->queue_stop_reasons[ac_queue] == 0 && in ieee80211_propagate_queue_wake()
430 skb_queue_empty(&local->pending[ac_queue]))) in ieee80211_propagate_queue_wake()
431 netif_wake_subqueue(sdata->dev, ac); in ieee80211_propagate_queue_wake()
441 struct ieee80211_local *local = hw_to_local(hw); in __ieee80211_wake_queue() local
443 trace_wake_queue(local, queue, reason); in __ieee80211_wake_queue()
445 if (WARN_ON(queue >= hw->queues)) in __ieee80211_wake_queue()
448 if (!test_bit(reason, &local->queue_stop_reasons[queue])) in __ieee80211_wake_queue()
452 local->q_stop_reasons[queue][reason] = 0; in __ieee80211_wake_queue()
454 local->q_stop_reasons[queue][reason]--; in __ieee80211_wake_queue()
455 if (WARN_ON(local->q_stop_reasons[queue][reason] < 0)) in __ieee80211_wake_queue()
456 local->q_stop_reasons[queue][reason] = 0; in __ieee80211_wake_queue()
459 if (local->q_stop_reasons[queue][reason] == 0) in __ieee80211_wake_queue()
460 __clear_bit(reason, &local->queue_stop_reasons[queue]); in __ieee80211_wake_queue()
462 if (local->queue_stop_reasons[queue] != 0) in __ieee80211_wake_queue()
466 if (skb_queue_empty(&local->pending[queue])) { in __ieee80211_wake_queue()
468 ieee80211_propagate_queue_wake(local, queue); in __ieee80211_wake_queue()
471 tasklet_schedule(&local->tx_pending_tasklet); in __ieee80211_wake_queue()
480 if (local->ops->wake_tx_queue) { in __ieee80211_wake_queue()
482 tasklet_schedule(&local->wake_txqs_tasklet); in __ieee80211_wake_queue()
484 _ieee80211_wake_txqs(local, flags); in __ieee80211_wake_queue()
492 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_wake_queue_by_reason() local
495 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); in ieee80211_wake_queue_by_reason()
497 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); in ieee80211_wake_queue_by_reason()
512 struct ieee80211_local *local = hw_to_local(hw); in __ieee80211_stop_queue() local
516 trace_stop_queue(local, queue, reason); in __ieee80211_stop_queue()
518 if (WARN_ON(queue >= hw->queues)) in __ieee80211_stop_queue()
522 local->q_stop_reasons[queue][reason] = 1; in __ieee80211_stop_queue()
524 local->q_stop_reasons[queue][reason]++; in __ieee80211_stop_queue()
526 if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue])) in __ieee80211_stop_queue()
529 if (local->hw.queues < IEEE80211_NUM_ACS) in __ieee80211_stop_queue()
533 list_for_each_entry_rcu(sdata, &local->interfaces, list) { in __ieee80211_stop_queue()
536 if (!sdata->dev) in __ieee80211_stop_queue()
540 if (sdata->vif.hw_queue[ac] == queue || in __ieee80211_stop_queue()
541 sdata->vif.cab_queue == queue) { in __ieee80211_stop_queue()
542 if (!local->ops->wake_tx_queue) { in __ieee80211_stop_queue()
543 netif_stop_subqueue(sdata->dev, ac); in __ieee80211_stop_queue()
546 spin_lock(&local->fq.lock); in __ieee80211_stop_queue()
547 sdata->vif.txqs_stopped[ac] = true; in __ieee80211_stop_queue()
548 spin_unlock(&local->fq.lock); in __ieee80211_stop_queue()
559 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_stop_queue_by_reason() local
562 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); in ieee80211_stop_queue_by_reason()
564 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); in ieee80211_stop_queue_by_reason()
575 void ieee80211_add_pending_skb(struct ieee80211_local *local, in ieee80211_add_pending_skb() argument
578 struct ieee80211_hw *hw = &local->hw; in ieee80211_add_pending_skb()
581 int queue = info->hw_queue; in ieee80211_add_pending_skb()
583 if (WARN_ON(!info->control.vif)) { in ieee80211_add_pending_skb()
584 ieee80211_free_txskb(&local->hw, skb); in ieee80211_add_pending_skb()
588 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); in ieee80211_add_pending_skb()
591 __skb_queue_tail(&local->pending[queue], skb); in ieee80211_add_pending_skb()
594 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); in ieee80211_add_pending_skb()
597 void ieee80211_add_pending_skbs(struct ieee80211_local *local, in ieee80211_add_pending_skbs() argument
600 struct ieee80211_hw *hw = &local->hw; in ieee80211_add_pending_skbs()
605 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); in ieee80211_add_pending_skbs()
609 if (WARN_ON(!info->control.vif)) { in ieee80211_add_pending_skbs()
610 ieee80211_free_txskb(&local->hw, skb); in ieee80211_add_pending_skbs()
614 queue = info->hw_queue; in ieee80211_add_pending_skbs()
620 __skb_queue_tail(&local->pending[queue], skb); in ieee80211_add_pending_skbs()
623 for (i = 0; i < hw->queues; i++) in ieee80211_add_pending_skbs()
627 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); in ieee80211_add_pending_skbs()
635 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_stop_queues_by_reason() local
639 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); in ieee80211_stop_queues_by_reason()
641 for_each_set_bit(i, &queues, hw->queues) in ieee80211_stop_queues_by_reason()
644 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); in ieee80211_stop_queues_by_reason()
657 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_queue_stopped() local
661 if (WARN_ON(queue >= hw->queues)) in ieee80211_queue_stopped()
664 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); in ieee80211_queue_stopped()
666 &local->queue_stop_reasons[queue]); in ieee80211_queue_stopped()
667 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); in ieee80211_queue_stopped()
677 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_wake_queues_by_reason() local
681 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); in ieee80211_wake_queues_by_reason()
683 for_each_set_bit(i, &queues, hw->queues) in ieee80211_wake_queues_by_reason()
686 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); in ieee80211_wake_queues_by_reason()
698 ieee80211_get_vif_queues(struct ieee80211_local *local, in ieee80211_get_vif_queues() argument
703 if (sdata && ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) { in ieee80211_get_vif_queues()
709 queues |= BIT(sdata->vif.hw_queue[ac]); in ieee80211_get_vif_queues()
710 if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE) in ieee80211_get_vif_queues()
711 queues |= BIT(sdata->vif.cab_queue); in ieee80211_get_vif_queues()
714 queues = BIT(local->hw.queues) - 1; in ieee80211_get_vif_queues()
720 void __ieee80211_flush_queues(struct ieee80211_local *local, in __ieee80211_flush_queues() argument
724 if (!local->ops->flush) in __ieee80211_flush_queues()
729 * IEEE80211_HW_QUEUE_CONTROL - flush all queues in __ieee80211_flush_queues()
731 if (!queues || !ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) in __ieee80211_flush_queues()
732 queues = ieee80211_get_vif_queues(local, sdata); in __ieee80211_flush_queues()
734 ieee80211_stop_queues_by_reason(&local->hw, queues, in __ieee80211_flush_queues()
738 drv_flush(local, sdata, queues, drop); in __ieee80211_flush_queues()
740 ieee80211_wake_queues_by_reason(&local->hw, queues, in __ieee80211_flush_queues()
745 void ieee80211_flush_queues(struct ieee80211_local *local, in ieee80211_flush_queues() argument
748 __ieee80211_flush_queues(local, sdata, 0, drop); in ieee80211_flush_queues()
751 void ieee80211_stop_vif_queues(struct ieee80211_local *local, in ieee80211_stop_vif_queues() argument
755 ieee80211_stop_queues_by_reason(&local->hw, in ieee80211_stop_vif_queues()
756 ieee80211_get_vif_queues(local, sdata), in ieee80211_stop_vif_queues()
760 void ieee80211_wake_vif_queues(struct ieee80211_local *local, in ieee80211_wake_vif_queues() argument
764 ieee80211_wake_queues_by_reason(&local->hw, in ieee80211_wake_vif_queues()
765 ieee80211_get_vif_queues(local, sdata), in ieee80211_wake_vif_queues()
769 static void __iterate_interfaces(struct ieee80211_local *local, in __iterate_interfaces() argument
778 list_for_each_entry_rcu(sdata, &local->interfaces, list) { in __iterate_interfaces()
779 switch (sdata->vif.type) { in __iterate_interfaces()
781 if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) in __iterate_interfaces()
790 active_only && !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) in __iterate_interfaces()
793 !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) in __iterate_interfaces()
796 iterator(data, sdata->vif.addr, in __iterate_interfaces()
797 &sdata->vif); in __iterate_interfaces()
800 sdata = rcu_dereference_check(local->monitor_sdata, in __iterate_interfaces()
801 lockdep_is_held(&local->iflist_mtx) || in __iterate_interfaces()
802 lockdep_is_held(&local->hw.wiphy->mtx)); in __iterate_interfaces()
805 sdata->flags & IEEE80211_SDATA_IN_DRIVER)) in __iterate_interfaces()
806 iterator(data, sdata->vif.addr, &sdata->vif); in __iterate_interfaces()
815 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_iterate_interfaces() local
817 mutex_lock(&local->iflist_mtx); in ieee80211_iterate_interfaces()
818 __iterate_interfaces(local, iter_flags, iterator, data); in ieee80211_iterate_interfaces()
819 mutex_unlock(&local->iflist_mtx); in ieee80211_iterate_interfaces()
829 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_iterate_active_interfaces_atomic() local
832 __iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE, in ieee80211_iterate_active_interfaces_atomic()
844 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_iterate_active_interfaces_mtx() local
846 lockdep_assert_wiphy(hw->wiphy); in ieee80211_iterate_active_interfaces_mtx()
848 __iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE, in ieee80211_iterate_active_interfaces_mtx()
853 static void __iterate_stations(struct ieee80211_local *local, in __iterate_stations() argument
860 list_for_each_entry_rcu(sta, &local->sta_list, list) { in __iterate_stations()
861 if (!sta->uploaded) in __iterate_stations()
864 iterator(data, &sta->sta); in __iterate_stations()
873 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_iterate_stations() local
875 mutex_lock(&local->sta_mtx); in ieee80211_iterate_stations()
876 __iterate_stations(local, iterator, data); in ieee80211_iterate_stations()
877 mutex_unlock(&local->sta_mtx); in ieee80211_iterate_stations()
886 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_iterate_stations_atomic() local
889 __iterate_stations(local, iterator, data); in ieee80211_iterate_stations_atomic()
899 !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) in wdev_to_ieee80211_vif()
901 return &sdata->vif; in wdev_to_ieee80211_vif()
910 return &vif_to_sdata(vif)->wdev; in ieee80211_vif_to_wdev()
916 * the suspend->resume cycle. Since we can't check each caller
923 static bool ieee80211_can_queue_work(struct ieee80211_local *local) in ieee80211_can_queue_work() argument
925 if (local->quiescing || (local->suspended && !local->resuming)) { in ieee80211_can_queue_work()
935 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_queue_work() local
937 if (!ieee80211_can_queue_work(local)) in ieee80211_queue_work()
940 queue_work(local->workqueue, work); in ieee80211_queue_work()
948 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_queue_delayed_work() local
950 if (!ieee80211_can_queue_work(local)) in ieee80211_queue_delayed_work()
953 queue_delayed_work(local->workqueue, dwork, delay); in ieee80211_queue_delayed_work()
963 const void *data = elem->data + 1; in ieee80211_parse_extension_element()
966 if (!elem->datalen) in ieee80211_parse_extension_element()
969 len = elem->datalen - 1; in ieee80211_parse_extension_element()
971 switch (elem->data[0]) { in ieee80211_parse_extension_element()
973 if (len >= sizeof(*elems->mu_edca_param_set)) { in ieee80211_parse_extension_element()
974 elems->mu_edca_param_set = data; in ieee80211_parse_extension_element()
977 elem->datalen + 2); in ieee80211_parse_extension_element()
982 elems->he_cap = data; in ieee80211_parse_extension_element()
983 elems->he_cap_len = len; in ieee80211_parse_extension_element()
987 if (len >= sizeof(*elems->he_operation) && in ieee80211_parse_extension_element()
988 len >= ieee80211_he_oper_size(data) - 1) { in ieee80211_parse_extension_element()
991 elem->datalen + 2); in ieee80211_parse_extension_element()
992 elems->he_operation = data; in ieee80211_parse_extension_element()
997 elems->uora_element = data; in ieee80211_parse_extension_element()
1001 elems->max_channel_switch_time = data; in ieee80211_parse_extension_element()
1004 if (len >= sizeof(*elems->mbssid_config_ie)) in ieee80211_parse_extension_element()
1005 elems->mbssid_config_ie = data; in ieee80211_parse_extension_element()
1008 if (len >= sizeof(*elems->he_spr) && in ieee80211_parse_extension_element()
1010 elems->he_spr = data; in ieee80211_parse_extension_element()
1013 if (len >= sizeof(*elems->he_6ghz_capa)) in ieee80211_parse_extension_element()
1014 elems->he_6ghz_capa = data; in ieee80211_parse_extension_element()
1017 if (ieee80211_eht_capa_size_ok(elems->he_cap, in ieee80211_parse_extension_element()
1019 params->from_ap)) { in ieee80211_parse_extension_element()
1020 elems->eht_cap = data; in ieee80211_parse_extension_element()
1021 elems->eht_cap_len = len; in ieee80211_parse_extension_element()
1026 elems->eht_operation = data; in ieee80211_parse_extension_element()
1030 elems->multi_link = (void *)data; in ieee80211_parse_extension_element()
1041 bool calc_crc = params->filter != 0; in _ieee802_11_parse_elems_full()
1043 u32 crc = params->crc; in _ieee802_11_parse_elems_full()
1048 for_each_element(elem, params->start, params->len) { in _ieee802_11_parse_elems_full()
1050 u8 id = elem->id; in _ieee802_11_parse_elems_full()
1051 u8 elen = elem->datalen; in _ieee802_11_parse_elems_full()
1052 const u8 *pos = elem->data; in _ieee802_11_parse_elems_full()
1101 * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible in _ieee802_11_parse_elems_full()
1105 elems->parse_error = true; in _ieee802_11_parse_elems_full()
1111 if (calc_crc && id < 64 && (params->filter & (1ULL << id))) in _ieee802_11_parse_elems_full()
1112 crc = crc32_be(crc, pos - 2, elen + 2); in _ieee802_11_parse_elems_full()
1122 elems->lnk_id = (void *)(pos - 2); in _ieee802_11_parse_elems_full()
1129 elems->ch_sw_timing = (void *)pos; in _ieee802_11_parse_elems_full()
1132 elems->ext_capab = pos; in _ieee802_11_parse_elems_full()
1133 elems->ext_capab_len = elen; in _ieee802_11_parse_elems_full()
1136 elems->ssid = pos; in _ieee802_11_parse_elems_full()
1137 elems->ssid_len = elen; in _ieee802_11_parse_elems_full()
1140 elems->supp_rates = pos; in _ieee802_11_parse_elems_full()
1141 elems->supp_rates_len = elen; in _ieee802_11_parse_elems_full()
1145 elems->ds_params = pos; in _ieee802_11_parse_elems_full()
1151 elems->tim = (void *)pos; in _ieee802_11_parse_elems_full()
1152 elems->tim_len = elen; in _ieee802_11_parse_elems_full()
1162 crc = crc32_be(crc, pos - 2, elen + 2); in _ieee802_11_parse_elems_full()
1165 /* OUI Type 2 - WMM IE */ in _ieee802_11_parse_elems_full()
1167 elems->wmm_info = pos; in _ieee802_11_parse_elems_full()
1168 elems->wmm_info_len = elen; in _ieee802_11_parse_elems_full()
1170 elems->wmm_param = pos; in _ieee802_11_parse_elems_full()
1171 elems->wmm_param_len = elen; in _ieee802_11_parse_elems_full()
1177 elems->rsn = pos; in _ieee802_11_parse_elems_full()
1178 elems->rsn_len = elen; in _ieee802_11_parse_elems_full()
1182 elems->erp_info = pos; in _ieee802_11_parse_elems_full()
1187 elems->ext_supp_rates = pos; in _ieee802_11_parse_elems_full()
1188 elems->ext_supp_rates_len = elen; in _ieee802_11_parse_elems_full()
1192 elems->ht_cap_elem = (void *)pos; in _ieee802_11_parse_elems_full()
1198 elems->ht_operation = (void *)pos; in _ieee802_11_parse_elems_full()
1204 elems->vht_cap_elem = (void *)pos; in _ieee802_11_parse_elems_full()
1210 elems->vht_operation = (void *)pos; in _ieee802_11_parse_elems_full()
1212 crc = crc32_be(crc, pos - 2, elen + 2); in _ieee802_11_parse_elems_full()
1219 elems->opmode_notif = pos; in _ieee802_11_parse_elems_full()
1221 crc = crc32_be(crc, pos - 2, elen + 2); in _ieee802_11_parse_elems_full()
1227 elems->mesh_id = pos; in _ieee802_11_parse_elems_full()
1228 elems->mesh_id_len = elen; in _ieee802_11_parse_elems_full()
1232 elems->mesh_config = (void *)pos; in _ieee802_11_parse_elems_full()
1237 elems->peering = pos; in _ieee802_11_parse_elems_full()
1238 elems->peering_len = elen; in _ieee802_11_parse_elems_full()
1242 elems->awake_window = (void *)pos; in _ieee802_11_parse_elems_full()
1245 elems->preq = pos; in _ieee802_11_parse_elems_full()
1246 elems->preq_len = elen; in _ieee802_11_parse_elems_full()
1249 elems->prep = pos; in _ieee802_11_parse_elems_full()
1250 elems->prep_len = elen; in _ieee802_11_parse_elems_full()
1253 elems->perr = pos; in _ieee802_11_parse_elems_full()
1254 elems->perr_len = elen; in _ieee802_11_parse_elems_full()
1258 elems->rann = (void *)pos; in _ieee802_11_parse_elems_full()
1267 elems->ch_switch_ie = (void *)pos; in _ieee802_11_parse_elems_full()
1274 elems->ext_chansw_ie = (void *)pos; in _ieee802_11_parse_elems_full()
1281 elems->sec_chan_offs = (void *)pos; in _ieee802_11_parse_elems_full()
1285 sizeof(*elems->mesh_chansw_params_ie)) { in _ieee802_11_parse_elems_full()
1289 elems->mesh_chansw_params_ie = (void *)pos; in _ieee802_11_parse_elems_full()
1292 if (!params->action || in _ieee802_11_parse_elems_full()
1293 elen < sizeof(*elems->wide_bw_chansw_ie)) { in _ieee802_11_parse_elems_full()
1297 elems->wide_bw_chansw_ie = (void *)pos; in _ieee802_11_parse_elems_full()
1300 if (params->action) { in _ieee802_11_parse_elems_full()
1312 if (ie[1] >= sizeof(*elems->wide_bw_chansw_ie)) in _ieee802_11_parse_elems_full()
1313 elems->wide_bw_chansw_ie = in _ieee802_11_parse_elems_full()
1320 elems->country_elem = pos; in _ieee802_11_parse_elems_full()
1321 elems->country_elem_len = elen; in _ieee802_11_parse_elems_full()
1328 elems->pwr_constr_elem = pos; in _ieee802_11_parse_elems_full()
1351 crc = crc32_be(crc, pos - 2, elen + 2); in _ieee802_11_parse_elems_full()
1353 elems->cisco_dtpc_elem = pos; in _ieee802_11_parse_elems_full()
1360 elems->addba_ext_ie = (void *)pos; in _ieee802_11_parse_elems_full()
1364 elems->timeout_int = (void *)pos; in _ieee802_11_parse_elems_full()
1369 if (elen >= sizeof(*elems->max_idle_period_ie)) in _ieee802_11_parse_elems_full()
1370 elems->max_idle_period_ie = (void *)pos; in _ieee802_11_parse_elems_full()
1373 elems->rsnx = pos; in _ieee802_11_parse_elems_full()
1374 elems->rsnx_len = elen; in _ieee802_11_parse_elems_full()
1381 if (elems->tx_pwr_env_num >= ARRAY_SIZE(elems->tx_pwr_env)) in _ieee802_11_parse_elems_full()
1384 elems->tx_pwr_env[elems->tx_pwr_env_num] = (void *)pos; in _ieee802_11_parse_elems_full()
1385 elems->tx_pwr_env_len[elems->tx_pwr_env_num] = elen; in _ieee802_11_parse_elems_full()
1386 elems->tx_pwr_env_num++; in _ieee802_11_parse_elems_full()
1394 if (elen >= sizeof(*elems->s1g_capab)) in _ieee802_11_parse_elems_full()
1395 elems->s1g_capab = (void *)pos; in _ieee802_11_parse_elems_full()
1400 if (elen == sizeof(*elems->s1g_oper)) in _ieee802_11_parse_elems_full()
1401 elems->s1g_oper = (void *)pos; in _ieee802_11_parse_elems_full()
1406 if (elen == sizeof(*elems->s1g_bcn_compat)) in _ieee802_11_parse_elems_full()
1407 elems->s1g_bcn_compat = (void *)pos; in _ieee802_11_parse_elems_full()
1413 elems->aid_resp = (void *)pos; in _ieee802_11_parse_elems_full()
1422 elems->parse_error = true; in _ieee802_11_parse_elems_full()
1427 if (!for_each_element_completed(elem, params->start, params->len)) in _ieee802_11_parse_elems_full()
1428 elems->parse_error = true; in _ieee802_11_parse_elems_full()
1442 if (!bss || !bss->transmitted_bss) in ieee802_11_find_bssid_profile()
1446 if (elem->datalen < 2) in ieee802_11_find_bssid_profile()
1448 if (elem->data[0] < 1 || elem->data[0] > 8) in ieee802_11_find_bssid_profile()
1451 for_each_element(sub, elem->data + 1, elem->datalen - 1) { in ieee802_11_find_bssid_profile()
1455 if (sub->id != 0 || sub->datalen < 4) { in ieee802_11_find_bssid_profile()
1460 if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP || in ieee802_11_find_bssid_profile()
1461 sub->data[1] != 2) { in ieee802_11_find_bssid_profile()
1486 cfg80211_gen_new_bssid(bss->transmitted_bss->bssid, in ieee802_11_find_bssid_profile()
1487 elem->data[0], in ieee802_11_find_bssid_profile()
1490 if (ether_addr_equal(new_bssid, bss->bssid)) { in ieee802_11_find_bssid_profile()
1492 elems->bssid_index_len = index[1]; in ieee802_11_find_bssid_profile()
1493 elems->bssid_index = (void *)&index[2]; in ieee802_11_find_bssid_profile()
1509 size_t scratch_len = params->len; in ieee802_11_parse_elems_full()
1514 elems->ie_start = params->start; in ieee802_11_parse_elems_full()
1515 elems->total_len = params->len; in ieee802_11_parse_elems_full()
1516 elems->scratch_len = scratch_len; in ieee802_11_parse_elems_full()
1517 elems->scratch_pos = elems->scratch; in ieee802_11_parse_elems_full()
1519 nontransmitted_profile = elems->scratch_pos; in ieee802_11_parse_elems_full()
1521 ieee802_11_find_bssid_profile(params->start, params->len, in ieee802_11_parse_elems_full()
1522 elems, params->bss, in ieee802_11_parse_elems_full()
1524 elems->scratch_pos += nontransmitted_profile_len; in ieee802_11_parse_elems_full()
1525 elems->scratch_len -= nontransmitted_profile_len; in ieee802_11_parse_elems_full()
1530 elems->crc = _ieee802_11_parse_elems_full(params, elems, non_inherit); in ieee802_11_parse_elems_full()
1537 .action = params->action, in ieee802_11_parse_elems_full()
1538 .link_id = params->link_id, in ieee802_11_parse_elems_full()
1544 if (elems->tim && !elems->parse_error) { in ieee802_11_parse_elems_full()
1545 const struct ieee80211_tim_ie *tim_ie = elems->tim; in ieee802_11_parse_elems_full()
1547 elems->dtim_period = tim_ie->dtim_period; in ieee802_11_parse_elems_full()
1548 elems->dtim_count = tim_ie->dtim_count; in ieee802_11_parse_elems_full()
1552 if (elems->bssid_index && in ieee802_11_parse_elems_full()
1553 elems->bssid_index_len >= in ieee802_11_parse_elems_full()
1555 elems->dtim_period = elems->bssid_index->dtim_period; in ieee802_11_parse_elems_full()
1557 if (elems->bssid_index && in ieee802_11_parse_elems_full()
1558 elems->bssid_index_len >= in ieee802_11_parse_elems_full()
1560 elems->dtim_count = elems->bssid_index->dtim_count; in ieee802_11_parse_elems_full()
1574 if (sdata->vif.type != NL80211_IFTYPE_AP && in ieee80211_regulatory_limit_wmm_params()
1575 sdata->vif.type != NL80211_IFTYPE_STATION) in ieee80211_regulatory_limit_wmm_params()
1579 chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); in ieee80211_regulatory_limit_wmm_params()
1581 center_freq = chanctx_conf->def.chan->center_freq; in ieee80211_regulatory_limit_wmm_params()
1588 rrule = freq_reg_info(sdata->wdev.wiphy, MHZ_TO_KHZ(center_freq)); in ieee80211_regulatory_limit_wmm_params()
1590 if (IS_ERR_OR_NULL(rrule) || !rrule->has_wmm) { in ieee80211_regulatory_limit_wmm_params()
1595 if (sdata->vif.type == NL80211_IFTYPE_AP) in ieee80211_regulatory_limit_wmm_params()
1596 wmm_ac = &rrule->wmm_rule.ap[ac]; in ieee80211_regulatory_limit_wmm_params()
1598 wmm_ac = &rrule->wmm_rule.client[ac]; in ieee80211_regulatory_limit_wmm_params()
1599 qparam->cw_min = max_t(u16, qparam->cw_min, wmm_ac->cw_min); in ieee80211_regulatory_limit_wmm_params()
1600 qparam->cw_max = max_t(u16, qparam->cw_max, wmm_ac->cw_max); in ieee80211_regulatory_limit_wmm_params()
1601 qparam->aifs = max_t(u8, qparam->aifs, wmm_ac->aifsn); in ieee80211_regulatory_limit_wmm_params()
1602 qparam->txop = min_t(u16, qparam->txop, wmm_ac->cot / 32); in ieee80211_regulatory_limit_wmm_params()
1609 struct ieee80211_sub_if_data *sdata = link->sdata; in ieee80211_set_wmm_default()
1610 struct ieee80211_local *local = sdata->local; in ieee80211_set_wmm_default() local
1618 if (!local->ops->conf_tx) in ieee80211_set_wmm_default()
1621 if (local->hw.queues < IEEE80211_NUM_ACS) in ieee80211_set_wmm_default()
1627 chanctx_conf = rcu_dereference(link->conf->chanctx_conf); in ieee80211_set_wmm_default()
1629 chanctx_conf->def.chan->band == NL80211_BAND_2GHZ) && in ieee80211_set_wmm_default()
1630 !link->operating_11g_mode; in ieee80211_set_wmm_default()
1633 is_ocb = (sdata->vif.type == NL80211_IFTYPE_OCB); in ieee80211_set_wmm_default()
1635 /* Set defaults according to 802.11-2007 Table 7-37 */ in ieee80211_set_wmm_default()
1674 qparam.cw_min = (aCWmin + 1) / 2 - 1; in ieee80211_set_wmm_default()
1688 qparam.cw_max = (aCWmin + 1) / 2 - 1; in ieee80211_set_wmm_default()
1689 qparam.cw_min = (aCWmin + 1) / 4 - 1; in ieee80211_set_wmm_default()
1704 link->tx_conf[ac] = qparam; in ieee80211_set_wmm_default()
1705 drv_conf_tx(local, link, ac, &qparam); in ieee80211_set_wmm_default()
1708 if (sdata->vif.type != NL80211_IFTYPE_MONITOR && in ieee80211_set_wmm_default()
1709 sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && in ieee80211_set_wmm_default()
1710 sdata->vif.type != NL80211_IFTYPE_NAN) { in ieee80211_set_wmm_default()
1711 link->conf->qos = enable_qos; in ieee80211_set_wmm_default()
1724 struct ieee80211_local *local = sdata->local; in ieee80211_send_auth() local
1727 bool multi_link = sdata->vif.valid_links; in ieee80211_send_auth()
1736 .len = sizeof(mle) - 2, in ieee80211_send_auth()
1743 memcpy(mle.basic.mld_mac_addr, sdata->vif.addr, ETH_ALEN); in ieee80211_send_auth()
1746 skb = dev_alloc_skb(local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN + in ieee80211_send_auth()
1752 skb_reserve(skb, local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN); in ieee80211_send_auth()
1755 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | in ieee80211_send_auth()
1757 memcpy(mgmt->da, da, ETH_ALEN); in ieee80211_send_auth()
1758 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); in ieee80211_send_auth()
1759 memcpy(mgmt->bssid, bssid, ETH_ALEN); in ieee80211_send_auth()
1760 mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg); in ieee80211_send_auth()
1761 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction); in ieee80211_send_auth()
1762 mgmt->u.auth.status_code = cpu_to_le16(status); in ieee80211_send_auth()
1769 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); in ieee80211_send_auth()
1770 err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx); in ieee80211_send_auth()
1777 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | in ieee80211_send_auth()
1787 struct ieee80211_local *local = sdata->local; in ieee80211_send_deauth_disassoc() local
1792 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype); in ieee80211_send_deauth_disassoc()
1793 mgmt->duration = 0; /* initialize only */ in ieee80211_send_deauth_disassoc()
1794 mgmt->seq_ctrl = 0; /* initialize only */ in ieee80211_send_deauth_disassoc()
1795 memcpy(mgmt->da, da, ETH_ALEN); in ieee80211_send_deauth_disassoc()
1796 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); in ieee80211_send_deauth_disassoc()
1797 memcpy(mgmt->bssid, bssid, ETH_ALEN); in ieee80211_send_deauth_disassoc()
1799 mgmt->u.deauth.reason_code = cpu_to_le16(reason); in ieee80211_send_deauth_disassoc()
1802 skb = dev_alloc_skb(local->hw.extra_tx_headroom + in ieee80211_send_deauth_disassoc()
1807 skb_reserve(skb, local->hw.extra_tx_headroom); in ieee80211_send_deauth_disassoc()
1812 if (sdata->vif.type != NL80211_IFTYPE_STATION || in ieee80211_send_deauth_disassoc()
1813 !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED)) in ieee80211_send_deauth_disassoc()
1814 IEEE80211_SKB_CB(skb)->flags |= in ieee80211_send_deauth_disassoc()
1821 static u8 *ieee80211_write_he_6ghz_cap(u8 *pos, __le16 cap, u8 *end) in ieee80211_write_he_6ghz_cap() argument
1823 if ((end - pos) < 5) in ieee80211_write_he_6ghz_cap()
1827 *pos++ = 1 + sizeof(cap); in ieee80211_write_he_6ghz_cap()
1829 memcpy(pos, &cap, sizeof(cap)); in ieee80211_write_he_6ghz_cap()
1842 struct ieee80211_local *local = sdata->local; in ieee80211_build_preq_ies_band() local
1858 sband = local->hw.wiphy->bands[band]; in ieee80211_build_preq_ies_band()
1866 for (i = 0; i < sband->n_bitrates; i++) { in ieee80211_build_preq_ies_band()
1869 if ((rate_flags & sband->bitrates[i].flags) != rate_flags) in ieee80211_build_preq_ies_band()
1873 (u8) DIV_ROUND_UP(sband->bitrates[i].bitrate, in ieee80211_build_preq_ies_band()
1879 if (end - pos < 2 + supp_rates_len) in ieee80211_build_preq_ies_band()
1897 if (end - pos < noffset - *offset) in ieee80211_build_preq_ies_band()
1899 memcpy(pos, ie + *offset, noffset - *offset); in ieee80211_build_preq_ies_band()
1900 pos += noffset - *offset; in ieee80211_build_preq_ies_band()
1904 ext_rates_len = num_rates - supp_rates_len; in ieee80211_build_preq_ies_band()
1906 if (end - pos < 2 + ext_rates_len) in ieee80211_build_preq_ies_band()
1914 if (chandef->chan && sband->band == NL80211_BAND_2GHZ) { in ieee80211_build_preq_ies_band()
1915 if (end - pos < 3) in ieee80211_build_preq_ies_band()
1920 chandef->chan->center_freq); in ieee80211_build_preq_ies_band()
1939 if (end - pos < noffset - *offset) in ieee80211_build_preq_ies_band()
1941 memcpy(pos, ie + *offset, noffset - *offset); in ieee80211_build_preq_ies_band()
1942 pos += noffset - *offset; in ieee80211_build_preq_ies_band()
1946 if (sband->ht_cap.ht_supported) { in ieee80211_build_preq_ies_band()
1947 if (end - pos < 2 + sizeof(struct ieee80211_ht_cap)) in ieee80211_build_preq_ies_band()
1949 pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, in ieee80211_build_preq_ies_band()
1950 sband->ht_cap.cap); in ieee80211_build_preq_ies_band()
1966 /* 60 GHz (Multi-band, DMG, MMS) can't happen */ in ieee80211_build_preq_ies_band()
1971 if (end - pos < noffset - *offset) in ieee80211_build_preq_ies_band()
1973 memcpy(pos, ie + *offset, noffset - *offset); in ieee80211_build_preq_ies_band()
1974 pos += noffset - *offset; in ieee80211_build_preq_ies_band()
1979 for (i = 0; i < sband->n_channels; i++) { in ieee80211_build_preq_ies_band()
1980 if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED | in ieee80211_build_preq_ies_band()
1988 if (sband->vht_cap.vht_supported && have_80mhz) { in ieee80211_build_preq_ies_band()
1989 if (end - pos < 2 + sizeof(struct ieee80211_vht_cap)) in ieee80211_build_preq_ies_band()
1991 pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap, in ieee80211_build_preq_ies_band()
1992 sband->vht_cap.cap); in ieee80211_build_preq_ies_band()
2009 if (end - pos < noffset - *offset) in ieee80211_build_preq_ies_band()
2011 memcpy(pos, ie + *offset, noffset - *offset); in ieee80211_build_preq_ies_band()
2012 pos += noffset - *offset; in ieee80211_build_preq_ies_band()
2017 ieee80211_vif_type_p2p(&sdata->vif)); in ieee80211_build_preq_ies_band()
2019 cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band), in ieee80211_build_preq_ies_band()
2027 ieee80211_vif_type_p2p(&sdata->vif)); in ieee80211_build_preq_ies_band()
2030 cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band), in ieee80211_build_preq_ies_band()
2034 sdata->vif.type == NL80211_IFTYPE_AP); in ieee80211_build_preq_ies_band()
2039 if (cfg80211_any_usable_channels(local->hw.wiphy, in ieee80211_build_preq_ies_band()
2044 sband6 = local->hw.wiphy->bands[NL80211_BAND_6GHZ]; in ieee80211_build_preq_ies_band()
2046 ieee80211_vif_type_p2p(&sdata->vif)); in ieee80211_build_preq_ies_band()
2050 ieee80211_vif_type_p2p(&sdata->vif); in ieee80211_build_preq_ies_band()
2051 __le16 cap = ieee80211_get_he_6ghz_capa(sband6, iftype); in ieee80211_build_preq_ies_band() local
2053 pos = ieee80211_write_he_6ghz_cap(pos, cap, end); in ieee80211_build_preq_ies_band()
2059 * that calculates local->scan_ies_len. in ieee80211_build_preq_ies_band()
2062 return pos - buffer; in ieee80211_build_preq_ies_band()
2066 return pos - buffer; in ieee80211_build_preq_ies_band()
2086 buffer_len - pos, in ieee80211_build_preq_ies()
2092 ie_desc->ies[i] = buffer + old_pos; in ieee80211_build_preq_ies()
2093 ie_desc->len[i] = pos - old_pos; in ieee80211_build_preq_ies()
2100 if (WARN_ONCE(buffer_len - pos < ie_len - custom_ie_offset, in ieee80211_build_preq_ies()
2104 ie_len - custom_ie_offset); in ieee80211_build_preq_ies()
2105 ie_desc->common_ies = buffer + pos; in ieee80211_build_preq_ies()
2106 ie_desc->common_ie_len = ie_len - custom_ie_offset; in ieee80211_build_preq_ies()
2107 pos += ie_len - custom_ie_offset; in ieee80211_build_preq_ies()
2121 struct ieee80211_local *local = sdata->local; in ieee80211_build_probe_req() local
2132 * badly-behaved APs don't respond when this parameter is included. in ieee80211_build_probe_req()
2134 chandef.width = sdata->vif.bss_conf.chandef.width; in ieee80211_build_probe_req()
2140 skb = ieee80211_probereq_get(&local->hw, src, ssid, ssid_len, in ieee80211_build_probe_req()
2141 local->scan_ies_len + ie_len); in ieee80211_build_probe_req()
2145 rate_masks[chan->band] = ratemask; in ieee80211_build_probe_req()
2148 ie, ie_len, BIT(chan->band), in ieee80211_build_probe_req()
2153 mgmt = (struct ieee80211_mgmt *) skb->data; in ieee80211_build_probe_req()
2154 memcpy(mgmt->da, dst, ETH_ALEN); in ieee80211_build_probe_req()
2155 memcpy(mgmt->bssid, dst, ETH_ALEN); in ieee80211_build_probe_req()
2158 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; in ieee80211_build_probe_req()
2172 sband = sdata->local->hw.wiphy->bands[band]; in ieee80211_sta_get_rates()
2176 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef); in ieee80211_sta_get_rates()
2177 shift = ieee80211_vif_get_shift(&sdata->vif); in ieee80211_sta_get_rates()
2179 num_rates = sband->n_bitrates; in ieee80211_sta_get_rates()
2181 for (i = 0; i < elems->supp_rates_len + in ieee80211_sta_get_rates()
2182 elems->ext_supp_rates_len; i++) { in ieee80211_sta_get_rates()
2186 if (i < elems->supp_rates_len) in ieee80211_sta_get_rates()
2187 rate = elems->supp_rates[i]; in ieee80211_sta_get_rates()
2188 else if (elems->ext_supp_rates) in ieee80211_sta_get_rates()
2189 rate = elems->ext_supp_rates in ieee80211_sta_get_rates()
2190 [i - elems->supp_rates_len]; in ieee80211_sta_get_rates()
2199 if ((rate_flags & sband->bitrates[j].flags) in ieee80211_sta_get_rates()
2203 brate = DIV_ROUND_UP(sband->bitrates[j].bitrate, in ieee80211_sta_get_rates()
2216 void ieee80211_stop_device(struct ieee80211_local *local) in ieee80211_stop_device() argument
2218 ieee80211_led_radio(local, false); in ieee80211_stop_device()
2219 ieee80211_mod_tpt_led_trig(local, 0, IEEE80211_TPT_LEDTRIG_FL_RADIO); in ieee80211_stop_device()
2221 cancel_work_sync(&local->reconfig_filter); in ieee80211_stop_device()
2223 flush_workqueue(local->workqueue); in ieee80211_stop_device()
2224 drv_stop(local); in ieee80211_stop_device()
2227 static void ieee80211_flush_completed_scan(struct ieee80211_local *local, in ieee80211_flush_completed_scan() argument
2237 if (test_bit(SCAN_COMPLETED, &local->scanning)) { in ieee80211_flush_completed_scan()
2239 * we don't attempt to continue a partial HW scan - which is in ieee80211_flush_completed_scan()
2244 set_bit(SCAN_ABORTED, &local->scanning); in ieee80211_flush_completed_scan()
2245 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); in ieee80211_flush_completed_scan()
2246 flush_delayed_work(&local->scan_work); in ieee80211_flush_completed_scan()
2250 static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local) in ieee80211_handle_reconfig_failure() argument
2265 local->resuming = false; in ieee80211_handle_reconfig_failure()
2266 local->suspended = false; in ieee80211_handle_reconfig_failure()
2267 local->in_reconfig = false; in ieee80211_handle_reconfig_failure()
2269 ieee80211_flush_completed_scan(local, true); in ieee80211_handle_reconfig_failure()
2272 * cfg80211 and clear local state in ieee80211_handle_reconfig_failure()
2274 ieee80211_sched_scan_end(local); in ieee80211_handle_reconfig_failure()
2276 list_for_each_entry(sdata, &local->interfaces, list) in ieee80211_handle_reconfig_failure()
2277 sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; in ieee80211_handle_reconfig_failure()
2282 mutex_lock(&local->chanctx_mtx); in ieee80211_handle_reconfig_failure()
2283 list_for_each_entry(ctx, &local->chanctx_list, list) in ieee80211_handle_reconfig_failure()
2284 ctx->driver_present = false; in ieee80211_handle_reconfig_failure()
2285 mutex_unlock(&local->chanctx_mtx); in ieee80211_handle_reconfig_failure()
2288 static void ieee80211_assign_chanctx(struct ieee80211_local *local, in ieee80211_assign_chanctx() argument
2295 if (!local->use_chanctx) in ieee80211_assign_chanctx()
2298 mutex_lock(&local->chanctx_mtx); in ieee80211_assign_chanctx()
2299 conf = rcu_dereference_protected(link->conf->chanctx_conf, in ieee80211_assign_chanctx()
2300 lockdep_is_held(&local->chanctx_mtx)); in ieee80211_assign_chanctx()
2303 drv_assign_vif_chanctx(local, sdata, link->conf, ctx); in ieee80211_assign_chanctx()
2305 mutex_unlock(&local->chanctx_mtx); in ieee80211_assign_chanctx()
2310 struct ieee80211_local *local = sdata->local; in ieee80211_reconfig_stations() local
2314 mutex_lock(&local->sta_mtx); in ieee80211_reconfig_stations()
2315 list_for_each_entry(sta, &local->sta_list, list) { in ieee80211_reconfig_stations()
2318 if (!sta->uploaded || sta->sdata != sdata) in ieee80211_reconfig_stations()
2322 state < sta->sta_state; state++) in ieee80211_reconfig_stations()
2323 WARN_ON(drv_sta_state(local, sta->sdata, sta, state, in ieee80211_reconfig_stations()
2326 mutex_unlock(&local->sta_mtx); in ieee80211_reconfig_stations()
2334 res = drv_start_nan(sdata->local, sdata, in ieee80211_reconfig_nan()
2335 &sdata->u.nan.conf); in ieee80211_reconfig_nan()
2339 funcs = kcalloc(sdata->local->hw.max_nan_de_entries + 1, in ieee80211_reconfig_nan()
2343 return -ENOMEM; in ieee80211_reconfig_nan()
2349 spin_lock_bh(&sdata->u.nan.func_lock); in ieee80211_reconfig_nan()
2351 idr_for_each_entry(&sdata->u.nan.function_inst_ids, func, id) in ieee80211_reconfig_nan()
2354 spin_unlock_bh(&sdata->u.nan.func_lock); in ieee80211_reconfig_nan()
2357 res = drv_add_nan_func(sdata->local, sdata, funcs[i]); in ieee80211_reconfig_nan()
2359 ieee80211_nan_func_terminated(&sdata->vif, in ieee80211_reconfig_nan()
2360 funcs[i]->instance_id, in ieee80211_reconfig_nan()
2370 int ieee80211_reconfig(struct ieee80211_local *local) in ieee80211_reconfig() argument
2372 struct ieee80211_hw *hw = &local->hw; in ieee80211_reconfig()
2381 bool suspended = local->suspended; in ieee80211_reconfig()
2385 if (!local->open_count) in ieee80211_reconfig()
2390 local->resuming = true; in ieee80211_reconfig()
2392 if (local->wowlan) { in ieee80211_reconfig()
2396 * clear local->suspended so the device could operate in ieee80211_reconfig()
2399 local->suspended = false; in ieee80211_reconfig()
2400 res = drv_resume(local); in ieee80211_reconfig()
2401 local->wowlan = false; in ieee80211_reconfig()
2403 local->resuming = false; in ieee80211_reconfig()
2412 * restore local->suspended in this case. in ieee80211_reconfig()
2415 local->suspended = true; in ieee80211_reconfig()
2426 if (suspended && local->in_reconfig && !reconfig_due_to_wowlan) in ieee80211_reconfig()
2427 cancel_work_sync(&local->restart_work); in ieee80211_reconfig()
2429 local->started = false; in ieee80211_reconfig()
2437 res = drv_start(local); in ieee80211_reconfig()
2443 ieee80211_handle_reconfig_failure(local); in ieee80211_reconfig()
2448 drv_set_frag_threshold(local, hw->wiphy->frag_threshold); in ieee80211_reconfig()
2451 drv_set_rts_threshold(local, hw->wiphy->rts_threshold); in ieee80211_reconfig()
2454 drv_set_coverage_class(local, hw->wiphy->coverage_class); in ieee80211_reconfig()
2456 ieee80211_led_radio(local, true); in ieee80211_reconfig()
2457 ieee80211_mod_tpt_led_trig(local, in ieee80211_reconfig()
2461 sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata); in ieee80211_reconfig()
2464 WARN_ON(local->resuming); in ieee80211_reconfig()
2465 res = drv_add_interface(local, sdata); in ieee80211_reconfig()
2467 RCU_INIT_POINTER(local->monitor_sdata, NULL); in ieee80211_reconfig()
2473 list_for_each_entry(sdata, &local->interfaces, list) { in ieee80211_reconfig()
2474 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && in ieee80211_reconfig()
2475 sdata->vif.type != NL80211_IFTYPE_MONITOR && in ieee80211_reconfig()
2477 res = drv_add_interface(local, sdata); in ieee80211_reconfig()
2487 list_for_each_entry_continue_reverse(sdata, &local->interfaces, in ieee80211_reconfig()
2489 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && in ieee80211_reconfig()
2490 sdata->vif.type != NL80211_IFTYPE_MONITOR && in ieee80211_reconfig()
2492 drv_remove_interface(local, sdata); in ieee80211_reconfig()
2493 ieee80211_handle_reconfig_failure(local); in ieee80211_reconfig()
2498 if (local->use_chanctx) { in ieee80211_reconfig()
2499 mutex_lock(&local->chanctx_mtx); in ieee80211_reconfig()
2500 list_for_each_entry(ctx, &local->chanctx_list, list) in ieee80211_reconfig()
2501 if (ctx->replace_state != in ieee80211_reconfig()
2503 WARN_ON(drv_add_chanctx(local, ctx)); in ieee80211_reconfig()
2504 mutex_unlock(&local->chanctx_mtx); in ieee80211_reconfig()
2506 sdata = wiphy_dereference(local->hw.wiphy, in ieee80211_reconfig()
2507 local->monitor_sdata); in ieee80211_reconfig()
2509 ieee80211_assign_chanctx(local, sdata, &sdata->deflink); in ieee80211_reconfig()
2513 ieee80211_hw_config(local, ~0); in ieee80211_reconfig()
2515 ieee80211_configure_filter(local); in ieee80211_reconfig()
2518 list_for_each_entry(sdata, &local->interfaces, list) { in ieee80211_reconfig()
2527 link_id < ARRAY_SIZE(sdata->vif.link_conf); in ieee80211_reconfig()
2531 link = sdata_dereference(sdata->link[link_id], sdata); in ieee80211_reconfig()
2533 ieee80211_assign_chanctx(local, sdata, link); in ieee80211_reconfig()
2536 switch (sdata->vif.type) { in ieee80211_reconfig()
2541 if (sdata->vif.cfg.ibss_joined) in ieee80211_reconfig()
2542 WARN_ON(drv_join_ibss(local, sdata)); in ieee80211_reconfig()
2549 drv_conf_tx(local, &sdata->deflink, i, in ieee80211_reconfig()
2550 &sdata->deflink.tx_conf[i]); in ieee80211_reconfig()
2569 if (sdata->vif.bss_conf.mu_mimo_owner) in ieee80211_reconfig()
2572 switch (sdata->vif.type) { in ieee80211_reconfig()
2578 /* Re-send beacon info report to the driver */ in ieee80211_reconfig()
2579 if (sdata->deflink.u.mgd.have_beacon) in ieee80211_reconfig()
2582 if (sdata->vif.bss_conf.max_idle_period || in ieee80211_reconfig()
2583 sdata->vif.bss_conf.protected_keep_alive) in ieee80211_reconfig()
2600 if (sdata->vif.bss_conf.ftm_responder == 1 && in ieee80211_reconfig()
2601 wiphy_ext_feature_isset(sdata->local->hw.wiphy, in ieee80211_reconfig()
2605 if (sdata->vif.type == NL80211_IFTYPE_AP) { in ieee80211_reconfig()
2608 if (rcu_access_pointer(sdata->deflink.u.ap.beacon)) in ieee80211_reconfig()
2609 drv_start_ap(local, sdata, in ieee80211_reconfig()
2610 sdata->deflink.conf); in ieee80211_reconfig()
2614 if (sdata->vif.bss_conf.enable_beacon) { in ieee80211_reconfig()
2623 ieee80211_handle_reconfig_failure(local); in ieee80211_reconfig()
2642 ieee80211_recalc_ps(local); in ieee80211_reconfig()
2650 if (!(local->hw.conf.flags & IEEE80211_CONF_PS)) { in ieee80211_reconfig()
2651 list_for_each_entry(sdata, &local->interfaces, list) { in ieee80211_reconfig()
2652 if (sdata->vif.type != NL80211_IFTYPE_STATION) in ieee80211_reconfig()
2654 if (!sdata->u.mgd.associated) in ieee80211_reconfig()
2657 ieee80211_send_nullfunc(local, sdata, false); in ieee80211_reconfig()
2662 list_for_each_entry(sdata, &local->interfaces, list) { in ieee80211_reconfig()
2667 switch (sdata->vif.type) { in ieee80211_reconfig()
2679 list_for_each_entry(sdata, &local->interfaces, list) in ieee80211_reconfig()
2683 mutex_lock(&local->mtx); in ieee80211_reconfig()
2684 sched_scan_sdata = rcu_dereference_protected(local->sched_scan_sdata, in ieee80211_reconfig()
2685 lockdep_is_held(&local->mtx)); in ieee80211_reconfig()
2686 sched_scan_req = rcu_dereference_protected(local->sched_scan_req, in ieee80211_reconfig()
2687 lockdep_is_held(&local->mtx)); in ieee80211_reconfig()
2696 if (sched_scan_req->n_scan_plans > 1 || in ieee80211_reconfig()
2699 RCU_INIT_POINTER(local->sched_scan_sdata, NULL); in ieee80211_reconfig()
2700 RCU_INIT_POINTER(local->sched_scan_req, NULL); in ieee80211_reconfig()
2703 mutex_unlock(&local->mtx); in ieee80211_reconfig()
2706 cfg80211_sched_scan_stopped_locked(local->hw.wiphy, 0); in ieee80211_reconfig()
2710 if (local->monitors == local->open_count && local->monitors > 0) in ieee80211_reconfig()
2711 ieee80211_add_virtual_monitor(local); in ieee80211_reconfig()
2724 mutex_lock(&local->sta_mtx); in ieee80211_reconfig()
2726 list_for_each_entry(sta, &local->sta_list, list) { in ieee80211_reconfig()
2727 if (!local->resuming) in ieee80211_reconfig()
2733 mutex_unlock(&local->sta_mtx); in ieee80211_reconfig()
2740 if (local->open_count && (!suspended || reconfig_due_to_wowlan)) in ieee80211_reconfig()
2741 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART); in ieee80211_reconfig()
2743 if (local->in_reconfig) { in ieee80211_reconfig()
2744 in_reconfig = local->in_reconfig; in ieee80211_reconfig()
2745 local->in_reconfig = false; in ieee80211_reconfig()
2749 mutex_lock(&local->mtx); in ieee80211_reconfig()
2750 ieee80211_start_next_roc(local); in ieee80211_reconfig()
2751 mutex_unlock(&local->mtx); in ieee80211_reconfig()
2754 list_for_each_entry(sdata, &local->interfaces, list) in ieee80211_reconfig()
2755 ieee80211_queue_work(&local->hw, &sdata->work); in ieee80211_reconfig()
2763 list_for_each_entry(sdata, &local->interfaces, list) { in ieee80211_reconfig()
2766 if (sdata->vif.type == NL80211_IFTYPE_STATION) in ieee80211_reconfig()
2776 local->suspended = false; in ieee80211_reconfig()
2778 local->resuming = false; in ieee80211_reconfig()
2780 ieee80211_flush_completed_scan(local, false); in ieee80211_reconfig()
2782 if (local->open_count && !reconfig_due_to_wowlan) in ieee80211_reconfig()
2783 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); in ieee80211_reconfig()
2785 list_for_each_entry(sdata, &local->interfaces, list) { in ieee80211_reconfig()
2788 if (sdata->vif.type == NL80211_IFTYPE_STATION) in ieee80211_reconfig()
2792 mod_timer(&local->sta_cleanup, jiffies + 1); in ieee80211_reconfig()
2803 struct ieee80211_local *local; in ieee80211_reconfig_disconnect() local
2810 local = sdata->local; in ieee80211_reconfig_disconnect()
2813 !local->resuming)) in ieee80211_reconfig_disconnect()
2817 !local->in_reconfig)) in ieee80211_reconfig_disconnect()
2820 if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) in ieee80211_reconfig_disconnect()
2823 sdata->flags |= flag; in ieee80211_reconfig_disconnect()
2825 mutex_lock(&local->key_mtx); in ieee80211_reconfig_disconnect()
2826 list_for_each_entry(key, &sdata->key_list, list) in ieee80211_reconfig_disconnect()
2827 key->flags |= KEY_FLAG_TAINTED; in ieee80211_reconfig_disconnect()
2828 mutex_unlock(&local->key_mtx); in ieee80211_reconfig_disconnect()
2846 struct ieee80211_local *local = sdata->local; in ieee80211_recalc_smps() local
2850 mutex_lock(&local->chanctx_mtx); in ieee80211_recalc_smps()
2852 chanctx_conf = rcu_dereference_protected(link->conf->chanctx_conf, in ieee80211_recalc_smps()
2853 lockdep_is_held(&local->chanctx_mtx)); in ieee80211_recalc_smps()
2865 ieee80211_recalc_smps_chanctx(local, chanctx); in ieee80211_recalc_smps()
2867 mutex_unlock(&local->chanctx_mtx); in ieee80211_recalc_smps()
2873 struct ieee80211_local *local = sdata->local; in ieee80211_recalc_min_chandef() local
2878 mutex_lock(&local->chanctx_mtx); in ieee80211_recalc_min_chandef()
2880 for (i = 0; i < ARRAY_SIZE(sdata->vif.link_conf); i++) { in ieee80211_recalc_min_chandef()
2887 bss_conf = rcu_dereference(sdata->vif.link_conf[i]); in ieee80211_recalc_min_chandef()
2893 chanctx_conf = rcu_dereference_protected(bss_conf->chanctx_conf, in ieee80211_recalc_min_chandef()
2894 lockdep_is_held(&local->chanctx_mtx)); in ieee80211_recalc_min_chandef()
2899 * the mutex. Just the way we reached it could - in in ieee80211_recalc_min_chandef()
2900 * theory - go away, but we don't really care and in ieee80211_recalc_min_chandef()
2910 ieee80211_recalc_chanctx_min_def(local, chanctx); in ieee80211_recalc_min_chandef()
2913 mutex_unlock(&local->chanctx_mtx); in ieee80211_recalc_min_chandef()
2927 u16 cap) in ieee80211_ie_build_ht_cap() argument
2936 tmp = cpu_to_le16(cap); in ieee80211_ie_build_ht_cap()
2941 *pos++ = ht_cap->ampdu_factor | in ieee80211_ie_build_ht_cap()
2942 (ht_cap->ampdu_density << in ieee80211_ie_build_ht_cap()
2946 memcpy(pos, &ht_cap->mcs, sizeof(ht_cap->mcs)); in ieee80211_ie_build_ht_cap()
2947 pos += sizeof(ht_cap->mcs); in ieee80211_ie_build_ht_cap()
2962 u32 cap) in ieee80211_ie_build_vht_cap() argument
2971 tmp = cpu_to_le32(cap); in ieee80211_ie_build_vht_cap()
2976 memcpy(pos, &vht_cap->vht_mcs, sizeof(vht_cap->vht_mcs)); in ieee80211_ie_build_vht_cap()
2977 pos += sizeof(vht_cap->vht_mcs); in ieee80211_ie_build_vht_cap()
2996 n = ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem); in ieee80211_ie_len_he_cap()
2998 sizeof(he_cap->he_cap_elem) + n + in ieee80211_ie_len_he_cap()
2999 ieee80211_he_ppe_size(he_cap->ppe_thres[0], in ieee80211_ie_len_he_cap()
3000 he_cap->he_cap_elem.phy_cap_info); in ieee80211_ie_len_he_cap()
3021 elem = he_cap->he_cap_elem; in ieee80211_ie_build_he_cap()
3038 sizeof(he_cap->he_cap_elem) + n + in ieee80211_ie_build_he_cap()
3039 ieee80211_he_ppe_size(he_cap->ppe_thres[0], in ieee80211_ie_build_he_cap()
3040 he_cap->he_cap_elem.phy_cap_info); in ieee80211_ie_build_he_cap()
3042 if ((end - pos) < ie_len) in ieee80211_ie_build_he_cap()
3046 pos++; /* We'll set the size later below */ in ieee80211_ie_build_he_cap()
3053 memcpy(pos, &he_cap->he_mcs_nss_supp, n); in ieee80211_ie_build_he_cap()
3057 if ((he_cap->he_cap_elem.phy_cap_info[6] & in ieee80211_ie_build_he_cap()
3065 n = hweight8(he_cap->ppe_thres[0] & in ieee80211_ie_build_he_cap()
3067 n *= (1 + ((he_cap->ppe_thres[0] & IEEE80211_PPE_THRES_NSS_MASK) >> in ieee80211_ie_build_he_cap()
3072 * total size. in ieee80211_ie_build_he_cap()
3078 memcpy(pos, &he_cap->ppe_thres, n); in ieee80211_ie_build_he_cap()
3082 orig_pos[1] = (pos - orig_pos) - 2; in ieee80211_ie_build_he_cap()
3092 enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif); in ieee80211_ie_build_he_6ghz_cap()
3094 u16 cap; in ieee80211_ie_build_he_6ghz_cap() local
3096 if (!cfg80211_any_usable_channels(sdata->local->hw.wiphy, in ieee80211_ie_build_he_6ghz_cap()
3101 sband = sdata->local->hw.wiphy->bands[NL80211_BAND_6GHZ]; in ieee80211_ie_build_he_6ghz_cap()
3108 if (!iftd->he_6ghz_capa.capa) in ieee80211_ie_build_he_6ghz_cap()
3111 cap = le16_to_cpu(iftd->he_6ghz_capa.capa); in ieee80211_ie_build_he_6ghz_cap()
3112 cap &= ~IEEE80211_HE_6GHZ_CAP_SM_PS; in ieee80211_ie_build_he_6ghz_cap()
3120 cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DISABLED, in ieee80211_ie_build_he_6ghz_cap()
3124 cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_STATIC, in ieee80211_ie_build_he_6ghz_cap()
3128 cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DYNAMIC, in ieee80211_ie_build_he_6ghz_cap()
3133 pos = skb_put(skb, 2 + 1 + sizeof(cap)); in ieee80211_ie_build_he_6ghz_cap()
3134 ieee80211_write_he_6ghz_cap(pos, cpu_to_le16(cap), in ieee80211_ie_build_he_6ghz_cap()
3135 pos + 2 + 1 + sizeof(cap)); in ieee80211_ie_build_he_6ghz_cap()
3147 ht_oper->primary_chan = ieee80211_frequency_to_channel( in ieee80211_ie_build_ht_oper()
3148 chandef->chan->center_freq); in ieee80211_ie_build_ht_oper()
3149 switch (chandef->width) { in ieee80211_ie_build_ht_oper()
3154 if (chandef->center_freq1 > chandef->chan->center_freq) in ieee80211_ie_build_ht_oper()
3155 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; in ieee80211_ie_build_ht_oper()
3157 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW; in ieee80211_ie_build_ht_oper()
3164 ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; in ieee80211_ie_build_ht_oper()
3167 if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && in ieee80211_ie_build_ht_oper()
3168 chandef->width != NL80211_CHAN_WIDTH_20_NOHT && in ieee80211_ie_build_ht_oper()
3169 chandef->width != NL80211_CHAN_WIDTH_20) in ieee80211_ie_build_ht_oper()
3170 ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; in ieee80211_ie_build_ht_oper()
3173 ht_oper->ht_param |= IEEE80211_HT_PARAM_RIFS_MODE; in ieee80211_ie_build_ht_oper()
3175 ht_oper->operation_mode = cpu_to_le16(prot_mode); in ieee80211_ie_build_ht_oper()
3176 ht_oper->stbc_param = 0x0000; in ieee80211_ie_build_ht_oper()
3180 memset(&ht_oper->basic_set, 0, 16); in ieee80211_ie_build_ht_oper()
3181 memcpy(&ht_oper->basic_set, &ht_cap->mcs, 10); in ieee80211_ie_build_ht_oper()
3192 switch (chandef->width) { in ieee80211_ie_build_wide_bw_cs()
3211 *pos++ = ieee80211_frequency_to_channel(chandef->center_freq1); in ieee80211_ie_build_wide_bw_cs()
3213 if (chandef->center_freq2) in ieee80211_ie_build_wide_bw_cs()
3214 *pos++ = ieee80211_frequency_to_channel(chandef->center_freq2); in ieee80211_ie_build_wide_bw_cs()
3227 vht_oper->center_freq_seg0_idx = ieee80211_frequency_to_channel( in ieee80211_ie_build_vht_oper()
3228 chandef->center_freq1); in ieee80211_ie_build_vht_oper()
3229 if (chandef->center_freq2) in ieee80211_ie_build_vht_oper()
3230 vht_oper->center_freq_seg1_idx = in ieee80211_ie_build_vht_oper()
3231 ieee80211_frequency_to_channel(chandef->center_freq2); in ieee80211_ie_build_vht_oper()
3233 vht_oper->center_freq_seg1_idx = 0x00; in ieee80211_ie_build_vht_oper()
3235 switch (chandef->width) { in ieee80211_ie_build_vht_oper()
3241 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ; in ieee80211_ie_build_vht_oper()
3242 vht_oper->center_freq_seg1_idx = vht_oper->center_freq_seg0_idx; in ieee80211_ie_build_vht_oper()
3243 if (chandef->chan->center_freq < chandef->center_freq1) in ieee80211_ie_build_vht_oper()
3244 vht_oper->center_freq_seg0_idx -= 8; in ieee80211_ie_build_vht_oper()
3246 vht_oper->center_freq_seg0_idx += 8; in ieee80211_ie_build_vht_oper()
3253 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ; in ieee80211_ie_build_vht_oper()
3256 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ; in ieee80211_ie_build_vht_oper()
3263 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT; in ieee80211_ie_build_vht_oper()
3268 vht_oper->basic_mcs_set = cpu_to_le16(0xffff); in ieee80211_ie_build_vht_oper()
3280 if (chandef->chan->band == NL80211_BAND_6GHZ) in ieee80211_ie_build_he_oper()
3294 if (chandef->chan->band == NL80211_BAND_6GHZ) in ieee80211_ie_build_he_oper()
3299 he_oper->he_oper_params = cpu_to_le32(he_oper_params); in ieee80211_ie_build_he_oper()
3302 he_oper->he_mcs_nss_set = cpu_to_le16(0xffff); in ieee80211_ie_build_he_oper()
3305 if (chandef->chan->band != NL80211_BAND_6GHZ) in ieee80211_ie_build_he_oper()
3310 he_6ghz_op->minrate = 6; /* 6 Mbps */ in ieee80211_ie_build_he_oper()
3311 he_6ghz_op->primary = in ieee80211_ie_build_he_oper()
3312 ieee80211_frequency_to_channel(chandef->chan->center_freq); in ieee80211_ie_build_he_oper()
3313 he_6ghz_op->ccfs0 = in ieee80211_ie_build_he_oper()
3314 ieee80211_frequency_to_channel(chandef->center_freq1); in ieee80211_ie_build_he_oper()
3315 if (chandef->center_freq2) in ieee80211_ie_build_he_oper()
3316 he_6ghz_op->ccfs1 = in ieee80211_ie_build_he_oper()
3317 ieee80211_frequency_to_channel(chandef->center_freq2); in ieee80211_ie_build_he_oper()
3319 he_6ghz_op->ccfs1 = 0; in ieee80211_ie_build_he_oper()
3321 switch (chandef->width) { in ieee80211_ie_build_he_oper()
3333 he_6ghz_op->control = in ieee80211_ie_build_he_oper()
3335 he_6ghz_op->ccfs1 = he_6ghz_op->ccfs0; in ieee80211_ie_build_he_oper()
3336 if (chandef->chan->center_freq < chandef->center_freq1) in ieee80211_ie_build_he_oper()
3337 he_6ghz_op->ccfs0 -= 8; in ieee80211_ie_build_he_oper()
3339 he_6ghz_op->ccfs0 += 8; in ieee80211_ie_build_he_oper()
3342 he_6ghz_op->control = in ieee80211_ie_build_he_oper()
3346 he_6ghz_op->control = in ieee80211_ie_build_he_oper()
3350 he_6ghz_op->control = in ieee80211_ie_build_he_oper()
3354 he_6ghz_op->control = in ieee80211_ie_build_he_oper()
3373 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { in ieee80211_chandef_ht_oper()
3387 cfg80211_chandef_create(chandef, chandef->chan, channel_type); in ieee80211_chandef_ht_oper()
3411 vht_cap = hw->wiphy->bands[chandef->chan->band]->vht_cap.cap; in ieee80211_chandef_vht_oper()
3420 ccfs0 = oper->center_freq_seg0_idx; in ieee80211_chandef_vht_oper()
3421 ccfs1 = oper->center_freq_seg1_idx; in ieee80211_chandef_vht_oper()
3422 ccfs2 = (le16_to_cpu(htop->operation_mode) & in ieee80211_chandef_vht_oper()
3433 * Cf. IEEE 802.11 Table 9-250 in ieee80211_chandef_vht_oper()
3469 cf0 = ieee80211_channel_to_frequency(ccf0, chandef->chan->band); in ieee80211_chandef_vht_oper()
3470 cf1 = ieee80211_channel_to_frequency(ccf1, chandef->chan->band); in ieee80211_chandef_vht_oper()
3472 switch (oper->chan_width) { in ieee80211_chandef_vht_oper()
3483 diff = abs(ccf1 - ccf0); in ieee80211_chandef_vht_oper()
3519 struct ieee80211_eht_operation_info *info = (void *)eht_oper->optional; in ieee80211_chandef_eht_oper()
3521 chandef->center_freq1 = in ieee80211_chandef_eht_oper()
3522 ieee80211_channel_to_frequency(info->ccfs0, in ieee80211_chandef_eht_oper()
3523 chandef->chan->band); in ieee80211_chandef_eht_oper()
3525 switch (u8_get_bits(info->control, in ieee80211_chandef_eht_oper()
3528 chandef->width = NL80211_CHAN_WIDTH_20; in ieee80211_chandef_eht_oper()
3531 chandef->width = NL80211_CHAN_WIDTH_40; in ieee80211_chandef_eht_oper()
3534 chandef->width = NL80211_CHAN_WIDTH_80; in ieee80211_chandef_eht_oper()
3538 chandef->width = NL80211_CHAN_WIDTH_160; in ieee80211_chandef_eht_oper()
3539 chandef->center_freq1 = in ieee80211_chandef_eht_oper()
3540 ieee80211_channel_to_frequency(info->ccfs1, in ieee80211_chandef_eht_oper()
3541 chandef->chan->band); in ieee80211_chandef_eht_oper()
3543 chandef->width = NL80211_CHAN_WIDTH_80; in ieee80211_chandef_eht_oper()
3548 chandef->width = NL80211_CHAN_WIDTH_320; in ieee80211_chandef_eht_oper()
3549 chandef->center_freq1 = in ieee80211_chandef_eht_oper()
3550 ieee80211_channel_to_frequency(info->ccfs1, in ieee80211_chandef_eht_oper()
3551 chandef->chan->band); in ieee80211_chandef_eht_oper()
3553 chandef->width = NL80211_CHAN_WIDTH_160; in ieee80211_chandef_eht_oper()
3555 chandef->width = NL80211_CHAN_WIDTH_80; in ieee80211_chandef_eht_oper()
3557 if (chandef->center_freq1 > chandef->chan->center_freq) in ieee80211_chandef_eht_oper()
3558 chandef->center_freq1 -= 40; in ieee80211_chandef_eht_oper()
3560 chandef->center_freq1 += 40; in ieee80211_chandef_eht_oper()
3571 struct ieee80211_local *local = sdata->local; in ieee80211_chandef_he_6ghz_oper() local
3573 enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif); in ieee80211_chandef_he_6ghz_oper()
3578 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; in ieee80211_chandef_he_6ghz_oper()
3583 if (chandef->chan->band != NL80211_BAND_6GHZ) in ieee80211_chandef_he_6ghz_oper()
3586 sband = local->hw.wiphy->bands[NL80211_BAND_6GHZ]; in ieee80211_chandef_he_6ghz_oper()
3590 sdata_info(sdata, "Missing iftype sband data/HE cap"); in ieee80211_chandef_he_6ghz_oper()
3594 he_phy_cap = he_cap->he_cap_elem.phy_cap_info[0]; in ieee80211_chandef_he_6ghz_oper()
3605 chandef->chan->center_freq); in ieee80211_chandef_he_6ghz_oper()
3611 sdata_info(sdata, "Missing iftype sband data/EHT cap"); in ieee80211_chandef_he_6ghz_oper()
3620 chandef->chan->center_freq); in ieee80211_chandef_he_6ghz_oper()
3629 freq = ieee80211_channel_to_frequency(he_6ghz_oper->primary, in ieee80211_chandef_he_6ghz_oper()
3631 he_chandef.chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq); in ieee80211_chandef_he_6ghz_oper()
3633 switch (u8_get_bits(he_6ghz_oper->control, in ieee80211_chandef_he_6ghz_oper()
3636 bss_conf->power_type = IEEE80211_REG_LPI_AP; in ieee80211_chandef_he_6ghz_oper()
3639 bss_conf->power_type = IEEE80211_REG_SP_AP; in ieee80211_chandef_he_6ghz_oper()
3642 bss_conf->power_type = IEEE80211_REG_UNSET_AP; in ieee80211_chandef_he_6ghz_oper()
3647 !(eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT)) { in ieee80211_chandef_he_6ghz_oper()
3648 switch (u8_get_bits(he_6ghz_oper->control, in ieee80211_chandef_he_6ghz_oper()
3661 if (!he_6ghz_oper->ccfs1) in ieee80211_chandef_he_6ghz_oper()
3663 if (abs(he_6ghz_oper->ccfs1 - he_6ghz_oper->ccfs0) == 8) { in ieee80211_chandef_he_6ghz_oper()
3675 ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1, in ieee80211_chandef_he_6ghz_oper()
3679 ieee80211_channel_to_frequency(he_6ghz_oper->ccfs0, in ieee80211_chandef_he_6ghz_oper()
3683 ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1, in ieee80211_chandef_he_6ghz_oper()
3687 eht_phy_cap = eht_cap->eht_cap_elem.phy_cap_info[0]; in ieee80211_chandef_he_6ghz_oper()
3698 he_chandef.chan ? he_chandef.chan->center_freq : 0, in ieee80211_chandef_he_6ghz_oper()
3718 switch (FIELD_GET(S1G_OPER_CH_WIDTH_OPER, oper->ch_width)) { in ieee80211_chandef_s1g_oper()
3720 chandef->width = NL80211_CHAN_WIDTH_1; in ieee80211_chandef_s1g_oper()
3723 chandef->width = NL80211_CHAN_WIDTH_2; in ieee80211_chandef_s1g_oper()
3726 chandef->width = NL80211_CHAN_WIDTH_4; in ieee80211_chandef_s1g_oper()
3729 chandef->width = NL80211_CHAN_WIDTH_8; in ieee80211_chandef_s1g_oper()
3732 chandef->width = NL80211_CHAN_WIDTH_16; in ieee80211_chandef_s1g_oper()
3738 oper_freq = ieee80211_channel_to_freq_khz(oper->oper_ch, in ieee80211_chandef_s1g_oper()
3740 chandef->center_freq1 = KHZ_TO_MHZ(oper_freq); in ieee80211_chandef_s1g_oper()
3741 chandef->freq1_offset = oper_freq % 1000; in ieee80211_chandef_s1g_oper()
3760 for (j = 0; j < sband->n_bitrates; j++) { in ieee80211_parse_bitrates()
3761 br = &sband->bitrates[j]; in ieee80211_parse_bitrates()
3762 if ((rate_flags & br->flags) != rate_flags) in ieee80211_parse_bitrates()
3765 brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5); in ieee80211_parse_bitrates()
3780 struct ieee80211_local *local = sdata->local; in ieee80211_add_srates_ie() local
3784 u32 basic_rates = sdata->vif.bss_conf.basic_rates; in ieee80211_add_srates_ie()
3787 shift = ieee80211_vif_get_shift(&sdata->vif); in ieee80211_add_srates_ie()
3788 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef); in ieee80211_add_srates_ie()
3789 sband = local->hw.wiphy->bands[band]; in ieee80211_add_srates_ie()
3791 for (i = 0; i < sband->n_bitrates; i++) { in ieee80211_add_srates_ie()
3792 if ((rate_flags & sband->bitrates[i].flags) != rate_flags) in ieee80211_add_srates_ie()
3800 return -ENOMEM; in ieee80211_add_srates_ie()
3807 if ((rate_flags & sband->bitrates[i].flags) != rate_flags) in ieee80211_add_srates_ie()
3812 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate, in ieee80211_add_srates_ie()
3824 struct ieee80211_local *local = sdata->local; in ieee80211_add_ext_srates_ie() local
3828 u32 basic_rates = sdata->vif.bss_conf.basic_rates; in ieee80211_add_ext_srates_ie()
3831 rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef); in ieee80211_add_ext_srates_ie()
3832 shift = ieee80211_vif_get_shift(&sdata->vif); in ieee80211_add_ext_srates_ie()
3834 sband = local->hw.wiphy->bands[band]; in ieee80211_add_ext_srates_ie()
3836 for (i = 0; i < sband->n_bitrates; i++) { in ieee80211_add_ext_srates_ie()
3837 if ((rate_flags & sband->bitrates[i].flags) != rate_flags) in ieee80211_add_ext_srates_ie()
3843 exrates -= 8; in ieee80211_add_ext_srates_ie()
3848 return -ENOMEM; in ieee80211_add_ext_srates_ie()
3854 for (i = 8; i < sband->n_bitrates; i++) { in ieee80211_add_ext_srates_ie()
3856 if ((rate_flags & sband->bitrates[i].flags) in ieee80211_add_ext_srates_ie()
3861 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate, in ieee80211_add_ext_srates_ie()
3873 if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION)) in ieee80211_ave_rssi()
3876 return -ewma_beacon_signal_read(&sdata->deflink.u.mgd.ave_beacon_signal); in ieee80211_ave_rssi()
3887 if (mcs->rx_mask[3]) in ieee80211_mcs_to_chains()
3889 if (mcs->rx_mask[2]) in ieee80211_mcs_to_chains()
3891 if (mcs->rx_mask[1]) in ieee80211_mcs_to_chains()
3897 * ieee80211_calculate_rx_timestamp - calculate timestamp in frame
3898 * @local: mac80211 hw info struct
3907 u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, in ieee80211_calculate_rx_timestamp() argument
3912 u64 ts = status->mactime; in ieee80211_calculate_rx_timestamp()
3922 ri.bw = status->bw; in ieee80211_calculate_rx_timestamp()
3925 switch (status->encoding) { in ieee80211_calculate_rx_timestamp()
3928 ri.mcs = status->rate_idx; in ieee80211_calculate_rx_timestamp()
3929 ri.nss = status->nss; in ieee80211_calculate_rx_timestamp()
3930 ri.he_ru_alloc = status->he_ru; in ieee80211_calculate_rx_timestamp()
3931 if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) in ieee80211_calculate_rx_timestamp()
3938 if (status->flag & RX_FLAG_MACTIME_PLCP_START) { in ieee80211_calculate_rx_timestamp()
3944 * For HE MU PPDU, add the HE-SIG-B. in ieee80211_calculate_rx_timestamp()
3945 * For HE ER PPDU, add 8us for the HE-SIG-A. in ieee80211_calculate_rx_timestamp()
3946 * For HE TB PPDU, add 4us for the HE-STF. in ieee80211_calculate_rx_timestamp()
3947 * Add the HE-LTF durations - variable. in ieee80211_calculate_rx_timestamp()
3953 ri.mcs = status->rate_idx; in ieee80211_calculate_rx_timestamp()
3955 if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) in ieee80211_calculate_rx_timestamp()
3962 if (status->flag & RX_FLAG_MACTIME_PLCP_START) { in ieee80211_calculate_rx_timestamp()
3964 if (status->enc_flags & RX_ENC_FLAG_HT_GF) in ieee80211_calculate_rx_timestamp()
3970 * Add Data HT-LTFs per streams in ieee80211_calculate_rx_timestamp()
3971 * TODO: add Extension HT-LTFs, 4us per LTF in ieee80211_calculate_rx_timestamp()
3981 ri.mcs = status->rate_idx; in ieee80211_calculate_rx_timestamp()
3982 ri.nss = status->nss; in ieee80211_calculate_rx_timestamp()
3983 if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) in ieee80211_calculate_rx_timestamp()
3990 if (status->flag & RX_FLAG_MACTIME_PLCP_START) { in ieee80211_calculate_rx_timestamp()
3995 * Add VHT-LTFs per streams in ieee80211_calculate_rx_timestamp()
4011 switch (status->bw) { in ieee80211_calculate_rx_timestamp()
4020 sband = local->hw.wiphy->bands[status->band]; in ieee80211_calculate_rx_timestamp()
4021 bitrate = sband->bitrates[status->rate_idx].bitrate; in ieee80211_calculate_rx_timestamp()
4024 if (status->flag & RX_FLAG_MACTIME_PLCP_START) { in ieee80211_calculate_rx_timestamp()
4025 if (status->band == NL80211_BAND_5GHZ) { in ieee80211_calculate_rx_timestamp()
4028 } else if (status->enc_flags & RX_ENC_FLAG_SHORTPRE) { in ieee80211_calculate_rx_timestamp()
4041 (unsigned long long)status->flag, status->rate_idx, in ieee80211_calculate_rx_timestamp()
4042 status->nss)) in ieee80211_calculate_rx_timestamp()
4046 if (status->flag & RX_FLAG_MACTIME_END) in ieee80211_calculate_rx_timestamp()
4047 ts -= mpdu_len * 8 * 10 / rate; in ieee80211_calculate_rx_timestamp()
4054 void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) in ieee80211_dfs_cac_cancel() argument
4060 lockdep_assert_wiphy(local->hw.wiphy); in ieee80211_dfs_cac_cancel()
4062 mutex_lock(&local->mtx); in ieee80211_dfs_cac_cancel()
4063 list_for_each_entry(sdata, &local->interfaces, list) { in ieee80211_dfs_cac_cancel()
4064 /* it might be waiting for the local->mtx, but then in ieee80211_dfs_cac_cancel()
4065 * by the time it gets it, sdata->wdev.cac_started in ieee80211_dfs_cac_cancel()
4068 cancel_delayed_work(&sdata->deflink.dfs_cac_timer_work); in ieee80211_dfs_cac_cancel()
4070 if (sdata->wdev.cac_started) { in ieee80211_dfs_cac_cancel()
4071 chandef = sdata->vif.bss_conf.chandef; in ieee80211_dfs_cac_cancel()
4072 ieee80211_link_release_channel(&sdata->deflink); in ieee80211_dfs_cac_cancel()
4073 cfg80211_cac_event(sdata->dev, in ieee80211_dfs_cac_cancel()
4079 mutex_unlock(&local->mtx); in ieee80211_dfs_cac_cancel()
4084 struct ieee80211_local *local = in ieee80211_dfs_radar_detected_work() local
4086 struct cfg80211_chan_def chandef = local->hw.conf.chandef; in ieee80211_dfs_radar_detected_work()
4090 mutex_lock(&local->chanctx_mtx); in ieee80211_dfs_radar_detected_work()
4091 list_for_each_entry(ctx, &local->chanctx_list, list) { in ieee80211_dfs_radar_detected_work()
4092 if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) in ieee80211_dfs_radar_detected_work()
4096 chandef = ctx->conf.def; in ieee80211_dfs_radar_detected_work()
4098 mutex_unlock(&local->chanctx_mtx); in ieee80211_dfs_radar_detected_work()
4100 wiphy_lock(local->hw.wiphy); in ieee80211_dfs_radar_detected_work()
4101 ieee80211_dfs_cac_cancel(local); in ieee80211_dfs_radar_detected_work()
4102 wiphy_unlock(local->hw.wiphy); in ieee80211_dfs_radar_detected_work()
4105 /* XXX: multi-channel is not supported yet */ in ieee80211_dfs_radar_detected_work()
4108 cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); in ieee80211_dfs_radar_detected_work()
4113 struct ieee80211_local *local = hw_to_local(hw); in ieee80211_radar_detected() local
4115 trace_api_radar_detected(local); in ieee80211_radar_detected()
4117 schedule_work(&local->radar_detected_work); in ieee80211_radar_detected()
4126 switch (c->width) { in ieee80211_chandef_downgrade()
4128 c->width = NL80211_CHAN_WIDTH_20_NOHT; in ieee80211_chandef_downgrade()
4132 c->width = NL80211_CHAN_WIDTH_20; in ieee80211_chandef_downgrade()
4133 c->center_freq1 = c->chan->center_freq; in ieee80211_chandef_downgrade()
4138 tmp = (30 + c->chan->center_freq - c->center_freq1)/20; in ieee80211_chandef_downgrade()
4142 c->center_freq1 = c->center_freq1 - 20 + 40 * tmp; in ieee80211_chandef_downgrade()
4143 c->width = NL80211_CHAN_WIDTH_40; in ieee80211_chandef_downgrade()
4147 c->center_freq2 = 0; in ieee80211_chandef_downgrade()
4148 c->width = NL80211_CHAN_WIDTH_80; in ieee80211_chandef_downgrade()
4154 tmp = (70 + c->chan->center_freq - c->center_freq1)/20; in ieee80211_chandef_downgrade()
4157 c->center_freq1 = c->center_freq1 - 40 + 80 * tmp; in ieee80211_chandef_downgrade()
4158 c->width = NL80211_CHAN_WIDTH_80; in ieee80211_chandef_downgrade()
4164 tmp = (150 + c->chan->center_freq - c->center_freq1) / 20; in ieee80211_chandef_downgrade()
4167 c->center_freq1 = c->center_freq1 - 80 + 160 * tmp; in ieee80211_chandef_downgrade()
4168 c->width = NL80211_CHAN_WIDTH_160; in ieee80211_chandef_downgrade()
4174 c->width = NL80211_CHAN_WIDTH_20_NOHT; in ieee80211_chandef_downgrade()
4185 /* keep c->width */ in ieee80211_chandef_downgrade()
4225 struct ieee80211_local *local = sdata->local; in ieee80211_send_action_csa() local
4231 if (sdata->vif.type != NL80211_IFTYPE_ADHOC && in ieee80211_send_action_csa()
4232 sdata->vif.type != NL80211_IFTYPE_MESH_POINT) in ieee80211_send_action_csa()
4233 return -EOPNOTSUPP; in ieee80211_send_action_csa()
4235 skb = dev_alloc_skb(local->tx_headroom + hdr_len + in ieee80211_send_action_csa()
4241 return -ENOMEM; in ieee80211_send_action_csa()
4243 skb_reserve(skb, local->tx_headroom); in ieee80211_send_action_csa()
4245 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | in ieee80211_send_action_csa()
4248 eth_broadcast_addr(mgmt->da); in ieee80211_send_action_csa()
4249 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); in ieee80211_send_action_csa()
4250 if (ieee80211_vif_is_mesh(&sdata->vif)) { in ieee80211_send_action_csa()
4251 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); in ieee80211_send_action_csa()
4253 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; in ieee80211_send_action_csa()
4254 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); in ieee80211_send_action_csa()
4256 mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; in ieee80211_send_action_csa()
4257 mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH; in ieee80211_send_action_csa()
4261 *pos++ = csa_settings->block_tx ? 1 : 0; /* CSA mode */ in ieee80211_send_action_csa()
4262 freq = csa_settings->chandef.chan->center_freq; in ieee80211_send_action_csa()
4264 *pos++ = csa_settings->count; /* count */ in ieee80211_send_action_csa()
4266 if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) { in ieee80211_send_action_csa()
4272 ch_type = cfg80211_get_chandef_type(&csa_settings->chandef); in ieee80211_send_action_csa()
4279 if (ieee80211_vif_is_mesh(&sdata->vif)) { in ieee80211_send_action_csa()
4280 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; in ieee80211_send_action_csa()
4285 *pos++ = sdata->u.mesh.mshcfg.dot11MeshTTL; /* Mesh TTL */ in ieee80211_send_action_csa()
4288 *pos++ |= csa_settings->block_tx ? in ieee80211_send_action_csa()
4292 put_unaligned_le16(ifmsh->pre_value, pos);/* Precedence Value */ in ieee80211_send_action_csa()
4296 if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_80 || in ieee80211_send_action_csa()
4297 csa_settings->chandef.width == NL80211_CHAN_WIDTH_80P80 || in ieee80211_send_action_csa()
4298 csa_settings->chandef.width == NL80211_CHAN_WIDTH_160) { in ieee80211_send_action_csa()
4300 ieee80211_ie_build_wide_bw_cs(pos, &csa_settings->chandef); in ieee80211_send_action_csa()
4310 s32 end = data->desc[i].start + data->desc[i].duration - (tsf + 1); in ieee80211_extend_noa_desc()
4317 if (data->count[i] == 1) in ieee80211_extend_noa_desc()
4320 if (data->desc[i].interval == 0) in ieee80211_extend_noa_desc()
4324 skip = DIV_ROUND_UP(-end, data->desc[i].interval); in ieee80211_extend_noa_desc()
4325 if (data->count[i] < 255) { in ieee80211_extend_noa_desc()
4326 if (data->count[i] <= skip) { in ieee80211_extend_noa_desc()
4327 data->count[i] = 0; in ieee80211_extend_noa_desc()
4331 data->count[i] -= skip; in ieee80211_extend_noa_desc()
4334 data->desc[i].start += skip * data->desc[i].interval; in ieee80211_extend_noa_desc()
4349 if (!data->count[i]) in ieee80211_extend_absent_time()
4355 cur = data->desc[i].start - tsf; in ieee80211_extend_absent_time()
4359 cur = data->desc[i].start + data->desc[i].duration - tsf; in ieee80211_extend_absent_time()
4391 u32 next_offset = BIT(31) - 1; in ieee80211_update_p2p_noa()
4394 data->absent = 0; in ieee80211_update_p2p_noa()
4395 data->has_next_tsf = false; in ieee80211_update_p2p_noa()
4399 if (!data->count[i]) in ieee80211_update_p2p_noa()
4403 start = data->desc[i].start - tsf; in ieee80211_update_p2p_noa()
4405 data->absent |= BIT(i); in ieee80211_update_p2p_noa()
4410 data->has_next_tsf = true; in ieee80211_update_p2p_noa()
4413 if (data->absent) in ieee80211_update_p2p_noa()
4416 data->next_tsf = tsf + next_offset; in ieee80211_update_p2p_noa()
4429 const struct ieee80211_p2p_noa_desc *desc = &attr->desc[i]; in ieee80211_parse_p2p_noa()
4431 if (!desc->count || !desc->duration) in ieee80211_parse_p2p_noa()
4434 data->count[i] = desc->count; in ieee80211_parse_p2p_noa()
4435 data->desc[i].start = le32_to_cpu(desc->start_time); in ieee80211_parse_p2p_noa()
4436 data->desc[i].duration = le32_to_cpu(desc->duration); in ieee80211_parse_p2p_noa()
4437 data->desc[i].interval = le32_to_cpu(desc->interval); in ieee80211_parse_p2p_noa()
4439 if (data->count[i] > 1 && in ieee80211_parse_p2p_noa()
4440 data->desc[i].interval < data->desc[i].duration) in ieee80211_parse_p2p_noa()
4454 void ieee80211_recalc_dtim(struct ieee80211_local *local, in ieee80211_recalc_dtim() argument
4457 u64 tsf = drv_get_tsf(local, sdata); in ieee80211_recalc_dtim()
4459 u16 beacon_int = sdata->vif.bss_conf.beacon_int * 1024; in ieee80211_recalc_dtim()
4460 u8 dtim_period = sdata->vif.bss_conf.dtim_period; in ieee80211_recalc_dtim()
4464 if (tsf == -1ULL || !beacon_int || !dtim_period) in ieee80211_recalc_dtim()
4467 if (sdata->vif.type == NL80211_IFTYPE_AP || in ieee80211_recalc_dtim()
4468 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { in ieee80211_recalc_dtim()
4469 if (!sdata->bss) in ieee80211_recalc_dtim()
4472 ps = &sdata->bss->ps; in ieee80211_recalc_dtim()
4473 } else if (ieee80211_vif_is_mesh(&sdata->vif)) { in ieee80211_recalc_dtim()
4474 ps = &sdata->u.mesh.ps; in ieee80211_recalc_dtim()
4482 * dtim_count = dtim_period - (tsf / bcn_int) % dtim_period in ieee80211_recalc_dtim()
4490 dtim_count = dtim_period - bcns_from_dtim; in ieee80211_recalc_dtim()
4492 ps->dtim_count = dtim_count; in ieee80211_recalc_dtim()
4495 static u8 ieee80211_chanctx_radar_detect(struct ieee80211_local *local, in ieee80211_chanctx_radar_detect() argument
4501 lockdep_assert_held(&local->chanctx_mtx); in ieee80211_chanctx_radar_detect()
4503 if (WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)) in ieee80211_chanctx_radar_detect()
4506 list_for_each_entry(link, &ctx->reserved_links, reserved_chanctx_list) in ieee80211_chanctx_radar_detect()
4507 if (link->reserved_radar_required) in ieee80211_chanctx_radar_detect()
4508 radar_detect |= BIT(link->reserved_chandef.width); in ieee80211_chanctx_radar_detect()
4511 * An in-place reservation context should not have any assigned vifs in ieee80211_chanctx_radar_detect()
4514 WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER && in ieee80211_chanctx_radar_detect()
4515 !list_empty(&ctx->assigned_links)); in ieee80211_chanctx_radar_detect()
4517 list_for_each_entry(link, &ctx->assigned_links, assigned_chanctx_list) { in ieee80211_chanctx_radar_detect()
4518 if (!link->radar_required) in ieee80211_chanctx_radar_detect()
4522 BIT(link->conf->chandef.width); in ieee80211_chanctx_radar_detect()
4533 struct ieee80211_local *local = sdata->local; in ieee80211_check_combinations() local
4535 enum nl80211_iftype iftype = sdata->wdev.iftype; in ieee80211_check_combinations()
4542 lockdep_assert_held(&local->chanctx_mtx); in ieee80211_check_combinations()
4545 return -EINVAL; in ieee80211_check_combinations()
4548 !chandef->chan)) in ieee80211_check_combinations()
4549 return -EINVAL; in ieee80211_check_combinations()
4552 return -EINVAL; in ieee80211_check_combinations()
4554 if (sdata->vif.type == NL80211_IFTYPE_AP || in ieee80211_check_combinations()
4555 sdata->vif.type == NL80211_IFTYPE_MESH_POINT) { in ieee80211_check_combinations()
4561 params.new_beacon_int = sdata->vif.bss_conf.beacon_int; in ieee80211_check_combinations()
4565 if (cfg80211_iftype_allowed(local->hw.wiphy, iftype, 0, 1)) { in ieee80211_check_combinations()
4567 return -EINVAL; in ieee80211_check_combinations()
4577 list_for_each_entry(ctx, &local->chanctx_list, list) { in ieee80211_check_combinations()
4578 if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) in ieee80211_check_combinations()
4581 ieee80211_chanctx_radar_detect(local, ctx); in ieee80211_check_combinations()
4582 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) { in ieee80211_check_combinations()
4588 &ctx->conf.def)) in ieee80211_check_combinations()
4593 list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) { in ieee80211_check_combinations()
4596 wdev_iter = &sdata_iter->wdev; in ieee80211_check_combinations()
4600 cfg80211_iftype_allowed(local->hw.wiphy, in ieee80211_check_combinations()
4601 wdev_iter->iftype, 0, 1)) in ieee80211_check_combinations()
4604 params.iftype_num[wdev_iter->iftype]++; in ieee80211_check_combinations()
4611 return cfg80211_check_combinations(local->hw.wiphy, &params); in ieee80211_check_combinations()
4621 c->num_different_channels); in ieee80211_iter_max_chans()
4624 int ieee80211_max_num_channels(struct ieee80211_local *local) in ieee80211_max_num_channels() argument
4632 lockdep_assert_held(&local->chanctx_mtx); in ieee80211_max_num_channels()
4634 list_for_each_entry(ctx, &local->chanctx_list, list) { in ieee80211_max_num_channels()
4635 if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) in ieee80211_max_num_channels()
4641 ieee80211_chanctx_radar_detect(local, ctx); in ieee80211_max_num_channels()
4644 list_for_each_entry_rcu(sdata, &local->interfaces, list) in ieee80211_max_num_channels()
4645 params.iftype_num[sdata->wdev.iftype]++; in ieee80211_max_num_channels()
4647 err = cfg80211_iter_combinations(local->hw.wiphy, &params, in ieee80211_max_num_channels()
4660 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; in ieee80211_add_s1g_capab_ie()
4665 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) in ieee80211_add_s1g_capab_ie()
4668 if (!caps->s1g) in ieee80211_add_s1g_capab_ie()
4671 memcpy(s1g_capab.capab_info, caps->cap, sizeof(caps->cap)); in ieee80211_add_s1g_capab_ie()
4672 memcpy(s1g_capab.supp_mcs_nss, caps->nss_mcs, sizeof(caps->nss_mcs)); in ieee80211_add_s1g_capab_ie()
4675 for (i = 0; i < sizeof(ifmgd->s1g_capa.capab_info); i++) { in ieee80211_add_s1g_capab_ie()
4676 u8 mask = ifmgd->s1g_capa_mask.capab_info[i]; in ieee80211_add_s1g_capab_ie()
4679 s1g_capab.capab_info[i] |= ifmgd->s1g_capa.capab_info[i] & mask; in ieee80211_add_s1g_capab_ie()
4683 for (i = 0; i < sizeof(ifmgd->s1g_capa.supp_mcs_nss); i++) { in ieee80211_add_s1g_capab_ie()
4684 u8 mask = ifmgd->s1g_capa_mask.supp_mcs_nss[i]; in ieee80211_add_s1g_capab_ie()
4688 ifmgd->s1g_capa.supp_mcs_nss[i] & mask; in ieee80211_add_s1g_capab_ie()
4718 *buf++ = qosinfo; /* U-APSD no in use */ in ieee80211_add_wmm_info_ie()
4731 skb_queue_walk(&txqi->frags, skb) { in ieee80211_txq_get_depth()
4733 frag_bytes += skb->len; in ieee80211_txq_get_depth()
4737 *frame_cnt = txqi->tin.backlog_packets + frag_cnt; in ieee80211_txq_get_depth()
4740 *byte_cnt = txqi->tin.backlog_bytes + frag_bytes; in ieee80211_txq_get_depth()
4792 n = ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem, in ieee80211_ie_len_eht_cap()
4793 &eht_cap->eht_cap_elem, in ieee80211_ie_len_eht_cap()
4796 sizeof(he_cap->he_cap_elem) + n + in ieee80211_ie_len_eht_cap()
4797 ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0], in ieee80211_ie_len_eht_cap()
4798 eht_cap->eht_cap_elem.phy_cap_info); in ieee80211_ie_len_eht_cap()
4816 mcs_nss_len = ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem, in ieee80211_ie_build_eht_cap()
4817 &eht_cap->eht_cap_elem, in ieee80211_ie_build_eht_cap()
4819 ppet_len = ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0], in ieee80211_ie_build_eht_cap()
4820 eht_cap->eht_cap_elem.phy_cap_info); in ieee80211_ie_build_eht_cap()
4822 ie_len = 2 + 1 + sizeof(eht_cap->eht_cap_elem) + mcs_nss_len + ppet_len; in ieee80211_ie_build_eht_cap()
4823 if ((end - pos) < ie_len) in ieee80211_ie_build_eht_cap()
4827 *pos++ = ie_len - 2; in ieee80211_ie_build_eht_cap()
4831 memcpy(pos, &eht_cap->eht_cap_elem, sizeof(eht_cap->eht_cap_elem)); in ieee80211_ie_build_eht_cap()
4832 pos += sizeof(eht_cap->eht_cap_elem); in ieee80211_ie_build_eht_cap()
4834 memcpy(pos, &eht_cap->eht_mcs_nss_supp, mcs_nss_len); in ieee80211_ie_build_eht_cap()
4838 memcpy(pos, &eht_cap->eht_ppe_thres, ppet_len); in ieee80211_ie_build_eht_cap()
4852 elem_len = skb->data + skb->len - len_pos - 1; in ieee80211_fragment_element()
4858 elem_len -= 255; in ieee80211_fragment_element()