Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'wireless-next-2026-03-19' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Johannes Berg says:

====================
Aside from various small improvements/cleanups, not much:
- cfg80211/mac80211: S1G and UHR improvements
- hwsim: incumbent signal report test support

* tag 'wireless-next-2026-03-19' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (31 commits)
qtnfmac: use alloc_netdev macro for single queue devices
wifi: libertas: don't kill URBs in interrupt context
wifi: libertas: use USB anchors for tracking in-flight URBs
wifi: nl80211: use int for band coming from netlink
wifi: rsi_91x_usb: do not pause rfkill polling when stopping mac80211
wifi: mac80211: fix STA link removal during link removal
wifi: nl80211: reject S1G/60G with HT chantype
wifi: ieee80211: fix definition of EHT-MCS 15 in MRU
wifi: cfg80211: check non-S1G width with S1G chandef
wifi: cfg80211: restrict cfg80211_chandef_create() to only HT-based bands
wifi: mac80211: don't use cfg80211_chandef_create() for default chandef
wifi: mac80211: Remove deleted sta links in ieee80211_ml_reconf_work()
wifi: b43: use register definitions in nphy_op_software_rfkill
wifi: cfg80211: split control freq check from chandef check
wifi: mac80211: always use full chanctx compatible check
wifi: mac80211: refactor chandef tracing macros
wifi: mac80211: validate HE 6 GHz operation when EHT is used
wifi: nl80211: split out UHR operation information
wifi: mwifiex: drop redundant device reference
wifi: rt2x00: drop redundant device reference
...
====================

Link: https://patch.msgid.link/20260319082439.79875-3-johannes@sipsolutions.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+733 -680
+2 -2
drivers/net/wireless/ath/ath11k/mac.c
··· 6288 6288 lockdep_assert_held(&ar->conf_mutex); 6289 6289 6290 6290 /* make sure category field is present */ 6291 - if (skb->len < IEEE80211_MIN_ACTION_SIZE) 6291 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 6292 6292 return -EINVAL; 6293 6293 6294 - remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE; 6294 + remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE(category); 6295 6295 has_protected = ieee80211_has_protected(hdr->frame_control); 6296 6296 6297 6297 /* In case of SW crypto and hdr protected (PMF), packet will already be encrypted,
+2 -2
drivers/net/wireless/ath/ath12k/mac.c
··· 9119 9119 lockdep_assert_wiphy(wiphy); 9120 9120 9121 9121 /* make sure category field is present */ 9122 - if (skb->len < IEEE80211_MIN_ACTION_SIZE) 9122 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 9123 9123 return -EINVAL; 9124 9124 9125 - remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE; 9125 + remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE(category); 9126 9126 has_protected = ieee80211_has_protected(hdr->frame_control); 9127 9127 9128 9128 /* In case of SW crypto and hdr protected (PMF), packet will already be encrypted,
+1 -1
drivers/net/wireless/ath/ath12k/wifi7/hw.c
··· 104 104 if (mgmt->u.action.category != WLAN_CATEGORY_BACK) 105 105 return false; 106 106 107 - if (mgmt->u.action.u.addba_resp.action_code != WLAN_ACTION_ADDBA_RESP) 107 + if (mgmt->u.action.action_code != WLAN_ACTION_ADDBA_RESP) 108 108 return false; 109 109 110 110 return true;
+4 -8
drivers/net/wireless/atmel/at76c50x-usb.c
··· 2440 2440 struct mib_fw_version *fwv; 2441 2441 int board_type = (int)id->driver_info; 2442 2442 2443 - udev = usb_get_dev(interface_to_usbdev(interface)); 2443 + udev = interface_to_usbdev(interface); 2444 2444 2445 2445 fwv = kmalloc_obj(*fwv); 2446 - if (!fwv) { 2447 - ret = -ENOMEM; 2448 - goto exit; 2449 - } 2446 + if (!fwv) 2447 + return -ENOMEM; 2450 2448 2451 2449 /* Load firmware into kernel memory */ 2452 2450 fwe = at76_load_firmware(udev, board_type); ··· 2532 2534 2533 2535 exit: 2534 2536 kfree(fwv); 2535 - if (ret < 0) 2536 - usb_put_dev(udev); 2537 + 2537 2538 return ret; 2538 2539 } 2539 2540 ··· 2549 2552 2550 2553 wiphy_info(priv->hw->wiphy, "disconnecting\n"); 2551 2554 at76_delete_device(priv); 2552 - usb_put_dev(interface_to_usbdev(interface)); 2553 2555 dev_info(&interface->dev, "disconnected\n"); 2554 2556 } 2555 2557
+12 -12
drivers/net/wireless/broadcom/b43/phy_n.c
··· 6566 6566 6567 6567 b43_radio_mask(dev, 0x09, ~0x2); 6568 6568 6569 - b43_radio_write(dev, 0x204D, 0); 6570 - b43_radio_write(dev, 0x2053, 0); 6571 - b43_radio_write(dev, 0x2058, 0); 6572 - b43_radio_write(dev, 0x205E, 0); 6573 - b43_radio_mask(dev, 0x2062, ~0xF0); 6574 - b43_radio_write(dev, 0x2064, 0); 6569 + b43_radio_write(dev, B2056_TX0 | B2056_TX_PADA_BOOST_TUNE, 0); 6570 + b43_radio_write(dev, B2056_TX0 | B2056_TX_PADG_BOOST_TUNE, 0); 6571 + b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAA_BOOST_TUNE, 0); 6572 + b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAG_BOOST_TUNE, 0); 6573 + b43_radio_mask(dev, B2056_TX0 | B2056_TX_MIXA_BOOST_TUNE, ~0xF0); 6574 + b43_radio_write(dev, B2056_TX0 | B2056_TX_MIXG_BOOST_TUNE, 0); 6575 6575 6576 - b43_radio_write(dev, 0x304D, 0); 6577 - b43_radio_write(dev, 0x3053, 0); 6578 - b43_radio_write(dev, 0x3058, 0); 6579 - b43_radio_write(dev, 0x305E, 0); 6580 - b43_radio_mask(dev, 0x3062, ~0xF0); 6581 - b43_radio_write(dev, 0x3064, 0); 6576 + b43_radio_write(dev, B2056_TX1 | B2056_TX_PADA_BOOST_TUNE, 0); 6577 + b43_radio_write(dev, B2056_TX1 | B2056_TX_PADG_BOOST_TUNE, 0); 6578 + b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAA_BOOST_TUNE, 0); 6579 + b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAG_BOOST_TUNE, 0); 6580 + b43_radio_mask(dev, B2056_TX1 | B2056_TX_MIXA_BOOST_TUNE, ~0xF0); 6581 + b43_radio_write(dev, B2056_TX1 | B2056_TX_MIXG_BOOST_TUNE, 0); 6582 6582 } 6583 6583 } else { 6584 6584 if (phy->rev >= 19) {
+3 -3
drivers/net/wireless/intel/iwlwifi/mld/time_sync.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2025 Intel Corporation 3 + * Copyright (C) 2025-2026 Intel Corporation 4 4 */ 5 5 6 6 #include "mld.h" ··· 116 116 u8 skb_dialog_token; 117 117 118 118 if (ieee80211_is_timing_measurement(skb)) 119 - skb_dialog_token = mgmt->u.action.u.wnm_timing_msr.dialog_token; 119 + skb_dialog_token = mgmt->u.action.wnm_timing_msr.dialog_token; 120 120 else 121 - skb_dialog_token = mgmt->u.action.u.ftm.dialog_token; 121 + skb_dialog_token = mgmt->u.action.ftm.dialog_token; 122 122 123 123 if ((ether_addr_equal(mgmt->sa, addr) || 124 124 ether_addr_equal(mgmt->da, addr)) &&
+3 -4
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 3 * Copyright (C) 2015-2017 Intel Deutschland GmbH 4 - * Copyright (C) 2018-2025 Intel Corporation 4 + * Copyright (C) 2018-2026 Intel Corporation 5 5 */ 6 6 #include <linux/etherdevice.h> 7 7 #include <linux/math64.h> ··· 1409 1409 struct iwl_mvm_loc_entry *entry; 1410 1410 const u8 *ies, *lci, *civic, *msr_ie; 1411 1411 size_t ies_len, lci_len = 0, civic_len = 0; 1412 - size_t baselen = IEEE80211_MIN_ACTION_SIZE + 1413 - sizeof(mgmt->u.action.u.ftm); 1412 + size_t baselen = IEEE80211_MIN_ACTION_SIZE(ftm); 1414 1413 static const u8 rprt_type_lci = IEEE80211_SPCT_MSR_RPRT_TYPE_LCI; 1415 1414 static const u8 rprt_type_civic = IEEE80211_SPCT_MSR_RPRT_TYPE_CIVIC; 1416 1415 ··· 1418 1419 1419 1420 lockdep_assert_held(&mvm->mutex); 1420 1421 1421 - ies = mgmt->u.action.u.ftm.variable; 1422 + ies = mgmt->u.action.ftm.variable; 1422 1423 ies_len = len - baselen; 1423 1424 1424 1425 msr_ie = cfg80211_find_ie_match(WLAN_EID_MEASURE_REPORT, ies, ies_len,
+3 -3
drivers/net/wireless/intel/iwlwifi/mvm/time-sync.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2022 Intel Corporation 3 + * Copyright (C) 2022, 2026 Intel Corporation 4 4 */ 5 5 6 6 #include "mvm.h" ··· 18 18 u8 skb_dialog_token; 19 19 20 20 if (ieee80211_is_timing_measurement(skb)) 21 - skb_dialog_token = mgmt->u.action.u.wnm_timing_msr.dialog_token; 21 + skb_dialog_token = mgmt->u.action.wnm_timing_msr.dialog_token; 22 22 else 23 - skb_dialog_token = mgmt->u.action.u.ftm.dialog_token; 23 + skb_dialog_token = mgmt->u.action.ftm.dialog_token; 24 24 25 25 if ((ether_addr_equal(mgmt->sa, addr) || 26 26 ether_addr_equal(mgmt->da, addr)) &&
+22 -13
drivers/net/wireless/marvell/libertas/if_usb.c
··· 114 114 static void if_usb_free(struct if_usb_card *cardp) 115 115 { 116 116 /* Unlink tx & rx urb */ 117 - usb_kill_urb(cardp->tx_urb); 118 - usb_kill_urb(cardp->rx_urb); 117 + usb_kill_anchored_urbs(&cardp->tx_submitted); 118 + usb_kill_anchored_urbs(&cardp->rx_submitted); 119 119 120 120 usb_free_urb(cardp->tx_urb); 121 121 cardp->tx_urb = NULL; ··· 221 221 udev->descriptor.bDeviceSubClass, 222 222 udev->descriptor.bDeviceProtocol); 223 223 224 + init_usb_anchor(&cardp->rx_submitted); 225 + init_usb_anchor(&cardp->tx_submitted); 226 + 224 227 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 225 228 endpoint = &iface_desc->endpoint[i].desc; 226 229 if (usb_endpoint_is_bulk_in(endpoint)) { ··· 279 276 280 277 cardp->boot2_version = udev->descriptor.bcdDevice; 281 278 282 - usb_get_dev(udev); 283 279 usb_set_intfdata(intf, cardp); 284 280 285 281 r = lbs_get_firmware_async(priv, &udev->dev, cardp->model, ··· 289 287 return 0; 290 288 291 289 err_get_fw: 292 - usb_put_dev(udev); 293 290 lbs_remove_card(priv); 294 291 err_add_card: 295 292 if_usb_reset_device(cardp); ··· 322 321 kfree(cardp); 323 322 324 323 usb_set_intfdata(intf, NULL); 325 - usb_put_dev(interface_to_usbdev(intf)); 326 324 } 327 325 328 326 /** ··· 426 426 goto tx_ret; 427 427 } 428 428 429 - usb_kill_urb(cardp->tx_urb); 429 + /* check if there are pending URBs */ 430 + if (!usb_anchor_empty(&cardp->tx_submitted)) { 431 + lbs_deb_usbd(&cardp->udev->dev, "%s failed: pending URB\n", __func__); 432 + ret = -EBUSY; 433 + goto tx_ret; 434 + } 430 435 431 436 usb_fill_bulk_urb(cardp->tx_urb, cardp->udev, 432 437 usb_sndbulkpipe(cardp->udev, ··· 440 435 441 436 cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET; 442 437 438 + usb_anchor_urb(cardp->tx_urb, &cardp->tx_submitted); 443 439 if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) { 444 440 lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret); 441 + usb_unanchor_urb(cardp->tx_urb); 445 442 } else { 446 443 lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n"); 447 444 ret = 0; ··· 474 467 cardp); 475 468 476 469 lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); 470 + usb_anchor_urb(cardp->rx_urb, &cardp->rx_submitted); 477 471 if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) { 478 472 lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret); 473 + usb_unanchor_urb(cardp->rx_urb); 479 474 kfree_skb(skb); 480 475 cardp->rx_skb = NULL; 481 476 ret = -1; ··· 847 838 } 848 839 849 840 /* Cancel any pending usb business */ 850 - usb_kill_urb(cardp->rx_urb); 851 - usb_kill_urb(cardp->tx_urb); 841 + usb_kill_anchored_urbs(&cardp->rx_submitted); 842 + usb_kill_anchored_urbs(&cardp->tx_submitted); 852 843 853 844 cardp->fwlastblksent = 0; 854 845 cardp->fwdnldover = 0; ··· 878 869 if (cardp->bootcmdresp == BOOT_CMD_RESP_NOT_SUPPORTED) { 879 870 /* Return to normal operation */ 880 871 ret = -EOPNOTSUPP; 881 - usb_kill_urb(cardp->rx_urb); 882 - usb_kill_urb(cardp->tx_urb); 872 + usb_kill_anchored_urbs(&cardp->rx_submitted); 873 + usb_kill_anchored_urbs(&cardp->tx_submitted); 883 874 if (if_usb_submit_rx_urb(cardp) < 0) 884 875 ret = -EIO; 885 876 goto done; ··· 909 900 wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover); 910 901 911 902 timer_delete_sync(&cardp->fw_timeout); 912 - usb_kill_urb(cardp->rx_urb); 903 + usb_kill_anchored_urbs(&cardp->rx_submitted); 913 904 914 905 if (!cardp->fwdnldover) { 915 906 pr_info("failed to load fw, resetting device!\n"); ··· 969 960 goto out; 970 961 971 962 /* Unlink tx & rx urb */ 972 - usb_kill_urb(cardp->tx_urb); 973 - usb_kill_urb(cardp->rx_urb); 963 + usb_kill_anchored_urbs(&cardp->tx_submitted); 964 + usb_kill_anchored_urbs(&cardp->rx_submitted); 974 965 975 966 out: 976 967 return ret;
+3
drivers/net/wireless/marvell/libertas/if_usb.h
··· 48 48 struct urb *rx_urb, *tx_urb; 49 49 struct lbs_private *priv; 50 50 51 + struct usb_anchor rx_submitted; 52 + struct usb_anchor tx_submitted; 53 + 51 54 struct sk_buff *rx_skb; 52 55 53 56 uint8_t ep_in;
-2
drivers/net/wireless/marvell/libertas_tf/if_usb.c
··· 223 223 if (!priv) 224 224 goto dealloc; 225 225 226 - usb_get_dev(udev); 227 226 usb_set_intfdata(intf, cardp); 228 227 229 228 return 0; ··· 257 258 kfree(cardp); 258 259 259 260 usb_set_intfdata(intf, NULL); 260 - usb_put_dev(interface_to_usbdev(intf)); 261 261 262 262 lbtf_deb_leave(LBTF_DEB_MAIN); 263 263 }
+4 -8
drivers/net/wireless/marvell/mwifiex/tdls.c
··· 755 755 switch (action_code) { 756 756 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 757 757 /* See the layout of 'struct ieee80211_mgmt'. */ 758 - extra = sizeof(mgmt->u.action.u.tdls_discover_resp) + 759 - sizeof(mgmt->u.action.category); 758 + extra = IEEE80211_MIN_ACTION_SIZE(tdls_discover_resp) - 24; 760 759 skb_put(skb, extra); 761 760 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; 762 - mgmt->u.action.u.tdls_discover_resp.action_code = 763 - WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 764 - mgmt->u.action.u.tdls_discover_resp.dialog_token = 765 - dialog_token; 766 - mgmt->u.action.u.tdls_discover_resp.capability = 767 - cpu_to_le16(capab); 761 + mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 762 + mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token; 763 + mgmt->u.action.tdls_discover_resp.capability = cpu_to_le16(capab); 768 764 /* move back for addr4 */ 769 765 memmove(pos + ETH_ALEN, &mgmt->u.action, extra); 770 766 /* init address 4 */
-4
drivers/net/wireless/marvell/mwifiex/usb.c
··· 520 520 return ret; 521 521 } 522 522 523 - usb_get_dev(udev); 524 - 525 523 return 0; 526 524 } 527 525 ··· 664 666 mwifiex_dbg(adapter, FATAL, 665 667 "%s: removing card\n", __func__); 666 668 mwifiex_remove_card(adapter); 667 - 668 - usb_put_dev(interface_to_usbdev(intf)); 669 669 } 670 670 671 671 static void mwifiex_usb_coredump(struct device *dev)
+2 -2
drivers/net/wireless/marvell/mwl8k.c
··· 1985 1985 */ 1986 1986 if (unlikely(ieee80211_is_action(wh->frame_control) && 1987 1987 mgmt->u.action.category == WLAN_CATEGORY_BACK && 1988 - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ && 1988 + mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ && 1989 1989 priv->ap_fw)) { 1990 - u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); 1990 + u16 capab = le16_to_cpu(mgmt->u.action.addba_req.capab); 1991 1991 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 1992 1992 index = mwl8k_tid_queue_mapping(tid); 1993 1993 }
+3 -3
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
··· 413 413 u32 val; 414 414 415 415 if (ieee80211_is_action(fc) && 416 - skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 + 1 + 2 && 416 + skb->len >= IEEE80211_MIN_ACTION_SIZE(addba_req.capab) && 417 417 mgmt->u.action.category == WLAN_CATEGORY_BACK && 418 - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) { 419 - u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); 418 + mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ) { 419 + u16 capab = le16_to_cpu(mgmt->u.action.addba_req.capab); 420 420 421 421 txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA); 422 422 tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK;
+2 -2
drivers/net/wireless/mediatek/mt76/mt7925/mac.c
··· 668 668 u32 val; 669 669 670 670 if (ieee80211_is_action(fc) && 671 - skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 && 671 + skb->len >= IEEE80211_MIN_ACTION_SIZE(action_code) && 672 672 mgmt->u.action.category == WLAN_CATEGORY_BACK && 673 - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) 673 + mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ) 674 674 tid = MT_TX_ADDBA; 675 675 else if (ieee80211_is_mgmt(hdr->frame_control)) 676 676 tid = MT_TX_NORMAL;
+2 -2
drivers/net/wireless/mediatek/mt76/mt7996/mac.c
··· 800 800 u32 val; 801 801 802 802 if (ieee80211_is_action(fc) && 803 - skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 && 803 + skb->len >= IEEE80211_MIN_ACTION_SIZE(action_code) && 804 804 mgmt->u.action.category == WLAN_CATEGORY_BACK && 805 - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) { 805 + mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ) { 806 806 if (is_mt7990(&dev->mt76)) 807 807 txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TID_ADDBA, tid)); 808 808 else
+2 -2
drivers/net/wireless/quantenna/qtnfmac/core.c
··· 452 452 void *qdev_vif; 453 453 int ret; 454 454 455 - dev = alloc_netdev_mqs(sizeof(struct qtnf_vif *), name, 456 - name_assign_type, ether_setup, 1, 1); 455 + dev = alloc_netdev(sizeof(struct qtnf_vif *), name, 456 + name_assign_type, ether_setup); 457 457 if (!dev) 458 458 return -ENOMEM; 459 459
+1 -11
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
··· 802 802 struct rt2x00_dev *rt2x00dev; 803 803 int retval; 804 804 805 - usb_dev = usb_get_dev(usb_dev); 806 805 usb_reset_device(usb_dev); 807 806 808 807 hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); 809 808 if (!hw) { 810 809 rt2x00_probe_err("Failed to allocate hardware\n"); 811 - retval = -ENOMEM; 812 - goto exit_put_device; 810 + return -ENOMEM; 813 811 } 814 812 815 813 usb_set_intfdata(usb_intf, hw); ··· 849 851 850 852 exit_free_device: 851 853 ieee80211_free_hw(hw); 852 - 853 - exit_put_device: 854 - usb_put_dev(usb_dev); 855 - 856 854 usb_set_intfdata(usb_intf, NULL); 857 855 858 856 return retval; ··· 867 873 rt2x00usb_free_reg(rt2x00dev); 868 874 ieee80211_free_hw(hw); 869 875 870 - /* 871 - * Free the USB device data. 872 - */ 873 876 usb_set_intfdata(usb_intf, NULL); 874 - usb_put_dev(interface_to_usbdev(usb_intf)); 875 877 } 876 878 EXPORT_SYMBOL_GPL(rt2x00usb_disconnect); 877 879
+7 -7
drivers/net/wireless/realtek/rtl8xxxu/core.c
··· 5146 5146 if (!(rtl8xxxu_debug & RTL8XXXU_DEBUG_ACTION)) 5147 5147 return; 5148 5148 5149 - switch (mgmt->u.action.u.addba_resp.action_code) { 5149 + switch (mgmt->u.action.action_code) { 5150 5150 case WLAN_ACTION_ADDBA_RESP: 5151 - cap = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 5152 - timeout = le16_to_cpu(mgmt->u.action.u.addba_resp.timeout); 5151 + cap = le16_to_cpu(mgmt->u.action.addba_resp.capab); 5152 + timeout = le16_to_cpu(mgmt->u.action.addba_resp.timeout); 5153 5153 dev_info(dev, "WLAN_ACTION_ADDBA_RESP: " 5154 5154 "timeout %i, tid %02x, buf_size %02x, policy %02x, " 5155 5155 "status %02x\n", ··· 5157 5157 (cap & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2, 5158 5158 (cap & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6, 5159 5159 (cap >> 1) & 0x1, 5160 - le16_to_cpu(mgmt->u.action.u.addba_resp.status)); 5160 + le16_to_cpu(mgmt->u.action.addba_resp.status)); 5161 5161 break; 5162 5162 case WLAN_ACTION_ADDBA_REQ: 5163 - cap = le16_to_cpu(mgmt->u.action.u.addba_req.capab); 5164 - timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout); 5163 + cap = le16_to_cpu(mgmt->u.action.addba_req.capab); 5164 + timeout = le16_to_cpu(mgmt->u.action.addba_req.timeout); 5165 5165 dev_info(dev, "WLAN_ACTION_ADDBA_REQ: " 5166 5166 "timeout %i, tid %02x, buf_size %02x, policy %02x\n", 5167 5167 timeout, ··· 5171 5171 break; 5172 5172 default: 5173 5173 dev_info(dev, "action frame %02x\n", 5174 - mgmt->u.action.u.addba_resp.action_code); 5174 + mgmt->u.action.action_code); 5175 5175 break; 5176 5176 } 5177 5177 }
+14 -14
drivers/net/wireless/realtek/rtlwifi/base.c
··· 1409 1409 sta_entry = 1410 1410 (struct rtl_sta_info *)sta->drv_priv; 1411 1411 capab = 1412 - le16_to_cpu(mgmt->u.action.u.addba_req.capab); 1412 + le16_to_cpu(mgmt->u.action.addba_req.capab); 1413 1413 tid = (capab & 1414 1414 IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 1415 1415 if (tid >= MAX_TID_COUNT) { ··· 2392 2392 struct sk_buff *skb; 2393 2393 struct ieee80211_mgmt *action_frame; 2394 2394 2395 - /* 27 = header + category + action + smps mode */ 2396 - skb = dev_alloc_skb(27 + hw->extra_tx_headroom); 2395 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(ht_smps) + 2396 + hw->extra_tx_headroom); 2397 2397 if (!skb) 2398 2398 return NULL; 2399 2399 2400 2400 skb_reserve(skb, hw->extra_tx_headroom); 2401 - action_frame = skb_put_zero(skb, 27); 2401 + action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(ht_smps)); 2402 2402 memcpy(action_frame->da, da, ETH_ALEN); 2403 2403 memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN); 2404 2404 memcpy(action_frame->bssid, bssid, ETH_ALEN); 2405 2405 action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 2406 2406 IEEE80211_STYPE_ACTION); 2407 2407 action_frame->u.action.category = WLAN_CATEGORY_HT; 2408 - action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS; 2408 + action_frame->u.action.action_code = WLAN_HT_ACTION_SMPS; 2409 2409 switch (smps) { 2410 2410 case IEEE80211_SMPS_AUTOMATIC:/* 0 */ 2411 2411 case IEEE80211_SMPS_NUM_MODES:/* 4 */ 2412 2412 WARN_ON(1); 2413 2413 fallthrough; 2414 2414 case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/ 2415 - action_frame->u.action.u.ht_smps.smps_control = 2415 + action_frame->u.action.ht_smps.smps_control = 2416 2416 WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */ 2417 2417 break; 2418 2418 case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/ 2419 - action_frame->u.action.u.ht_smps.smps_control = 2419 + action_frame->u.action.ht_smps.smps_control = 2420 2420 WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */ 2421 2421 break; 2422 2422 case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/ 2423 - action_frame->u.action.u.ht_smps.smps_control = 2423 + action_frame->u.action.ht_smps.smps_control = 2424 2424 WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */ 2425 2425 break; 2426 2426 } ··· 2519 2519 struct ieee80211_mgmt *action_frame; 2520 2520 u16 params; 2521 2521 2522 - /* 27 = header + category + action + smps mode */ 2523 - skb = dev_alloc_skb(34 + hw->extra_tx_headroom); 2522 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(delba) + 2523 + hw->extra_tx_headroom); 2524 2524 if (!skb) 2525 2525 return NULL; 2526 2526 2527 2527 skb_reserve(skb, hw->extra_tx_headroom); 2528 - action_frame = skb_put_zero(skb, 34); 2528 + action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(delba)); 2529 2529 memcpy(action_frame->sa, sa, ETH_ALEN); 2530 2530 memcpy(action_frame->da, rtlefuse->dev_addr, ETH_ALEN); 2531 2531 memcpy(action_frame->bssid, bssid, ETH_ALEN); 2532 2532 action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 2533 2533 IEEE80211_STYPE_ACTION); 2534 2534 action_frame->u.action.category = WLAN_CATEGORY_BACK; 2535 - action_frame->u.action.u.delba.action_code = WLAN_ACTION_DELBA; 2535 + action_frame->u.action.action_code = WLAN_ACTION_DELBA; 2536 2536 params = (u16)(1 << 11); /* bit 11 initiator */ 2537 2537 params |= (u16)(tid << 12); /* bit 15:12 TID number */ 2538 2538 2539 - action_frame->u.action.u.delba.params = cpu_to_le16(params); 2540 - action_frame->u.action.u.delba.reason_code = 2539 + action_frame->u.action.delba.params = cpu_to_le16(params); 2540 + action_frame->u.action.delba.reason_code = 2541 2541 cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); 2542 2542 2543 2543 return skb;
+1 -1
drivers/net/wireless/realtek/rtlwifi/pci.c
··· 507 507 if (ieee80211_is_action(fc)) { 508 508 struct ieee80211_mgmt *action_frame = 509 509 (struct ieee80211_mgmt *)skb->data; 510 - if (action_frame->u.action.u.ht_smps.action == 510 + if (action_frame->u.action.action_code == 511 511 WLAN_HT_ACTION_SMPS) { 512 512 dev_kfree_skb(skb); 513 513 goto tx_status_ok;
+16 -1
drivers/net/wireless/rsi/rsi_91x_mac80211.c
··· 326 326 EXPORT_SYMBOL_GPL(rsi_mac80211_detach); 327 327 328 328 /** 329 + * rsi_mac80211_rfkill_exit() - This function is used to stop rfkill polling 330 + * when the device is removed. 331 + * @adapter: Pointer to the adapter structure. 332 + * 333 + * Return: None. 334 + */ 335 + void rsi_mac80211_rfkill_exit(struct rsi_hw *adapter) 336 + { 337 + struct ieee80211_hw *hw = adapter->hw; 338 + 339 + if (hw) 340 + wiphy_rfkill_stop_polling(hw->wiphy); 341 + } 342 + EXPORT_SYMBOL_GPL(rsi_mac80211_rfkill_exit); 343 + 344 + /** 329 345 * rsi_indicate_tx_status() - This function indicates the transmit status. 330 346 * @adapter: Pointer to the adapter structure. 331 347 * @skb: Pointer to the socket buffer structure. ··· 438 422 rsi_dbg(ERR_ZONE, "===> Interface DOWN <===\n"); 439 423 mutex_lock(&common->mutex); 440 424 common->iface_down = true; 441 - wiphy_rfkill_stop_polling(hw->wiphy); 442 425 443 426 /* Block all rx frames */ 444 427 rsi_send_rx_filter_frame(common, 0xffff);
+2
drivers/net/wireless/rsi/rsi_91x_usb.c
··· 877 877 if (!adapter) 878 878 return; 879 879 880 + rsi_mac80211_rfkill_exit(adapter); 881 + 880 882 rsi_mac80211_detach(adapter); 881 883 882 884 if (IS_ENABLED(CONFIG_RSI_COEX) && adapter->priv->coex_mode > 1 &&
+1
drivers/net/wireless/rsi/rsi_common.h
··· 79 79 } 80 80 81 81 void rsi_mac80211_detach(struct rsi_hw *hw); 82 + void rsi_mac80211_rfkill_exit(struct rsi_hw *hw); 82 83 u16 rsi_get_connected_channel(struct ieee80211_vif *vif); 83 84 struct rsi_hw *rsi_91x_init(u16 oper_mode); 84 85 void rsi_91x_deinit(struct rsi_hw *adapter);
+4 -4
drivers/net/wireless/silabs/wfx/data_rx.c
··· 21 21 if (wfx_api_older_than(wvif->wdev, 3, 6)) 22 22 return; 23 23 24 - switch (mgmt->u.action.u.addba_req.action_code) { 24 + switch (mgmt->u.action.action_code) { 25 25 case WLAN_ACTION_ADDBA_REQ: 26 - params = le16_to_cpu(mgmt->u.action.u.addba_req.capab); 26 + params = le16_to_cpu(mgmt->u.action.addba_req.capab); 27 27 tid = (params & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 28 28 ieee80211_start_rx_ba_session_offl(vif, mgmt->sa, tid); 29 29 break; 30 30 case WLAN_ACTION_DELBA: 31 - params = le16_to_cpu(mgmt->u.action.u.delba.params); 31 + params = le16_to_cpu(mgmt->u.action.delba.params); 32 32 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; 33 33 ieee80211_stop_rx_ba_session_offl(vif, mgmt->sa, tid); 34 34 break; ··· 80 80 */ 81 81 if (ieee80211_is_action(frame->frame_control) && 82 82 mgmt->u.action.category == WLAN_CATEGORY_BACK && 83 - skb->len > IEEE80211_MIN_ACTION_SIZE) { 83 + skb->len > IEEE80211_MIN_ACTION_SIZE(action_code)) { 84 84 wfx_rx_handle_ba(wvif, mgmt); 85 85 goto drop; 86 86 }
+64
drivers/net/wireless/virtual/mac80211_hwsim.c
··· 36 36 #include <linux/virtio.h> 37 37 #include <linux/virtio_ids.h> 38 38 #include <linux/virtio_config.h> 39 + #include <linux/uaccess.h> 40 + #include <linux/string.h> 39 41 #include "mac80211_hwsim.h" 40 42 41 43 #define WARN_QUEUE 100 ··· 1203 1201 .write = hwsim_background_cac_write, 1204 1202 .open = simple_open, 1205 1203 .llseek = default_llseek, 1204 + }; 1205 + 1206 + struct hwsim_chanctx_iter_arg { 1207 + struct ieee80211_chanctx_conf *conf; 1208 + u32 freq_mhz; 1209 + }; 1210 + 1211 + static void hwsim_6ghz_chanctx_iter(struct ieee80211_hw *hw, 1212 + struct ieee80211_chanctx_conf *conf, 1213 + void *data) 1214 + { 1215 + struct hwsim_chanctx_iter_arg *arg = data; 1216 + 1217 + if (conf->def.chan && 1218 + conf->def.chan->band == NL80211_BAND_6GHZ && 1219 + conf->def.chan->center_freq == arg->freq_mhz) 1220 + arg->conf = conf; 1221 + } 1222 + 1223 + static ssize_t hwsim_simulate_incumbent_signal_write(struct file *file, 1224 + const char __user *ubuf, 1225 + size_t len, loff_t *ppos) 1226 + { 1227 + struct mac80211_hwsim_data *data = file->private_data; 1228 + struct hwsim_chanctx_iter_arg arg = {}; 1229 + u32 bitmap; 1230 + char buf[64]; 1231 + 1232 + if (!len || len > sizeof(buf) - 1) 1233 + return -EINVAL; 1234 + 1235 + if (copy_from_user(buf, ubuf, len)) 1236 + return -EFAULT; 1237 + buf[len] = '\0'; 1238 + 1239 + if (sscanf(buf, "%u %i", &arg.freq_mhz, &bitmap) != 2) 1240 + return -EINVAL; 1241 + 1242 + if (!arg.freq_mhz) 1243 + return -EINVAL; 1244 + 1245 + ieee80211_iter_chan_contexts_atomic(data->hw, 1246 + hwsim_6ghz_chanctx_iter, 1247 + &arg); 1248 + 1249 + if (!arg.conf) 1250 + return -EINVAL; 1251 + 1252 + cfg80211_incumbent_signal_notify(data->hw->wiphy, 1253 + &arg.conf->def, 1254 + bitmap, 1255 + GFP_KERNEL); 1256 + 1257 + return len; 1258 + } 1259 + 1260 + static const struct file_operations hwsim_simulate_incumbent_signal_fops = { 1261 + .open = simple_open, 1262 + .write = hwsim_simulate_incumbent_signal_write, 1206 1263 }; 1207 1264 1208 1265 static int hwsim_fops_group_read(void *dat, u64 *val) ··· 6011 5950 debugfs_create_file("dfs_background_cac", 0200, 6012 5951 data->debugfs, 6013 5952 data, &hwsim_background_cac_ops); 5953 + debugfs_create_file("simulate_incumbent_signal_interference", 0200, 5954 + data->debugfs, 5955 + data, &hwsim_simulate_incumbent_signal_fops); 6014 5956 6015 5957 if (param->pmsr_capa) { 6016 5958 data->pmsr_capa = *param->pmsr_capa;
+2 -2
include/linux/ieee80211-eht.h
··· 251 251 #define IEEE80211_EHT_PHY_CAP5_SUPP_EXTRA_EHT_LTF 0x40 252 252 #define IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK 0x07 253 253 254 - #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_80MHZ 0x08 255 - #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_160MHZ 0x30 254 + #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_80MHZ 0x10 255 + #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_160MHZ 0x20 256 256 #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_320MHZ 0x40 257 257 #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK 0x78 258 258 #define IEEE80211_EHT_PHY_CAP6_EHT_DUP_6GHZ_SUPP 0x80
+3
include/linux/ieee80211-ht.h
··· 281 281 WLAN_ACTION_ADDBA_REQ = 0, 282 282 WLAN_ACTION_ADDBA_RESP = 1, 283 283 WLAN_ACTION_DELBA = 2, 284 + WLAN_ACTION_NDP_ADDBA_REQ = 128, 285 + WLAN_ACTION_NDP_ADDBA_RESP = 129, 286 + WLAN_ACTION_NDP_DELBA = 130, 284 287 }; 285 288 286 289 /* BACK (block-ack) parties */
+2 -2
include/linux/ieee80211-uhr.h
··· 12 12 13 13 #define IEEE80211_UHR_OPER_PARAMS_DPS_ENA 0x0001 14 14 #define IEEE80211_UHR_OPER_PARAMS_NPCA_ENA 0x0002 15 - #define IEEE80211_UHR_OPER_PARAMS_DBE_ENA 0x0004 16 - #define IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA 0x0008 15 + #define IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA 0x0004 16 + #define IEEE80211_UHR_OPER_PARAMS_DBE_ENA 0x0008 17 17 18 18 struct ieee80211_uhr_operation { 19 19 __le16 params;
+32 -53
include/linux/ieee80211.h
··· 1046 1046 } __packed probe_resp; 1047 1047 struct { 1048 1048 u8 category; 1049 + u8 action_code; 1049 1050 union { 1050 1051 struct { 1051 - u8 action_code; 1052 1052 u8 dialog_token; 1053 1053 u8 status_code; 1054 1054 u8 variable[]; 1055 1055 } __packed wme_action; 1056 1056 struct{ 1057 - u8 action_code; 1057 + u8 no_fixed_fields[0]; 1058 1058 u8 variable[]; 1059 1059 } __packed chan_switch; 1060 1060 struct{ 1061 - u8 action_code; 1062 1061 struct ieee80211_ext_chansw_ie data; 1063 1062 u8 variable[]; 1064 1063 } __packed ext_chan_switch; 1065 1064 struct{ 1066 - u8 action_code; 1067 1065 u8 dialog_token; 1068 1066 u8 element_id; 1069 1067 u8 length; 1070 1068 struct ieee80211_msrment_ie msr_elem; 1071 1069 } __packed measurement; 1072 1070 struct{ 1073 - u8 action_code; 1074 1071 u8 dialog_token; 1075 1072 __le16 capab; 1076 1073 __le16 timeout; ··· 1076 1079 u8 variable[]; 1077 1080 } __packed addba_req; 1078 1081 struct{ 1079 - u8 action_code; 1080 1082 u8 dialog_token; 1081 1083 __le16 status; 1082 1084 __le16 capab; ··· 1084 1088 u8 variable[]; 1085 1089 } __packed addba_resp; 1086 1090 struct{ 1087 - u8 action_code; 1088 1091 __le16 params; 1089 1092 __le16 reason_code; 1090 1093 } __packed delba; 1091 1094 struct { 1092 - u8 action_code; 1095 + u8 no_fixed_fields[0]; 1093 1096 u8 variable[]; 1094 1097 } __packed self_prot; 1095 1098 struct{ 1096 - u8 action_code; 1099 + u8 no_fixed_fields[0]; 1097 1100 u8 variable[]; 1098 1101 } __packed mesh_action; 1099 1102 struct { 1100 - u8 action; 1101 1103 u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; 1102 1104 } __packed sa_query; 1103 1105 struct { 1104 - u8 action; 1105 1106 u8 smps_control; 1106 1107 } __packed ht_smps; 1107 1108 struct { 1108 - u8 action_code; 1109 1109 u8 chanwidth; 1110 1110 } __packed ht_notify_cw; 1111 1111 struct { 1112 - u8 action_code; 1113 1112 u8 dialog_token; 1114 1113 __le16 capability; 1115 1114 u8 variable[]; 1116 1115 } __packed tdls_discover_resp; 1117 1116 struct { 1118 - u8 action_code; 1119 1117 u8 operating_mode; 1120 1118 } __packed vht_opmode_notif; 1121 1119 struct { 1122 - u8 action_code; 1123 1120 u8 membership[WLAN_MEMBERSHIP_LEN]; 1124 1121 u8 position[WLAN_USER_POSITION_LEN]; 1125 1122 } __packed vht_group_notif; 1126 1123 struct { 1127 - u8 action_code; 1128 1124 u8 dialog_token; 1129 1125 u8 tpc_elem_id; 1130 1126 u8 tpc_elem_length; 1131 1127 struct ieee80211_tpc_report_ie tpc; 1132 1128 } __packed tpc_report; 1133 1129 struct { 1134 - u8 action_code; 1135 1130 u8 dialog_token; 1136 1131 u8 follow_up; 1137 1132 u8 tod[6]; ··· 1132 1145 u8 variable[]; 1133 1146 } __packed ftm; 1134 1147 struct { 1135 - u8 action_code; 1148 + u8 no_fixed_fields[0]; 1136 1149 u8 variable[]; 1137 1150 } __packed s1g; 1138 1151 struct { 1139 - u8 action_code; 1140 1152 u8 dialog_token; 1141 1153 u8 follow_up; 1142 1154 u32 tod; ··· 1144 1158 u8 max_toa_error; 1145 1159 } __packed wnm_timing_msr; 1146 1160 struct { 1147 - u8 action_code; 1148 1161 u8 dialog_token; 1149 1162 u8 variable[]; 1150 1163 } __packed ttlm_req; 1151 1164 struct { 1152 - u8 action_code; 1153 1165 u8 dialog_token; 1154 1166 __le16 status_code; 1155 1167 u8 variable[]; 1156 1168 } __packed ttlm_res; 1157 1169 struct { 1158 - u8 action_code; 1170 + u8 no_fixed_fields[0]; 1171 + /* no variable fields either */ 1159 1172 } __packed ttlm_tear_down; 1160 1173 struct { 1161 - u8 action_code; 1162 1174 u8 dialog_token; 1163 1175 u8 variable[]; 1164 1176 } __packed ml_reconf_req; 1165 1177 struct { 1166 - u8 action_code; 1167 1178 u8 dialog_token; 1168 1179 u8 count; 1169 1180 u8 variable[]; 1170 1181 } __packed ml_reconf_resp; 1171 1182 struct { 1172 - u8 action_code; 1183 + u8 no_fixed_fields[0]; 1173 1184 u8 variable[]; 1174 1185 } __packed epcs; 1175 1186 struct { 1176 - u8 action_code; 1177 1187 u8 dialog_token; 1178 1188 u8 control; 1179 1189 u8 variable[]; 1180 1190 } __packed eml_omn; 1181 - } u; 1191 + }; 1182 1192 } __packed action; 1183 1193 DECLARE_FLEX_ARRAY(u8, body); /* Generic frame body */ 1184 1194 } u; ··· 1192 1210 1193 1211 #define BSS_MEMBERSHIP_SELECTOR_MIN BSS_MEMBERSHIP_SELECTOR_UHR_PHY 1194 1212 1195 - /* mgmt header + 1 byte category code */ 1196 - #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) 1213 + #define IEEE80211_MIN_ACTION_SIZE(type) offsetofend(struct ieee80211_mgmt, u.action.type) 1197 1214 1198 1215 1199 1216 /* Management MIC information element (IEEE 802.11w) for CMAC */ ··· 1482 1501 WLAN_STATUS_REJECT_DSE_BAND = 96, 1483 1502 WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, 1484 1503 WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, 1504 + /* 802.11ah */ 1505 + WLAN_STATUS_REJECTED_NDP_BLOCK_ACK_SUGGESTED = 109, 1485 1506 /* 802.11ai */ 1486 1507 WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, 1487 1508 WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, ··· 2374 2391 if (!ieee80211_is_action(fc)) 2375 2392 return false; 2376 2393 2377 - if (skb->len < offsetofend(typeof(*mgmt), u.action.u.ftm.action_code)) 2394 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(action_code)) 2378 2395 return true; 2379 2396 2380 2397 /* action frame - additionally check for non-bufferable FTM */ ··· 2383 2400 mgmt->u.action.category != WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION) 2384 2401 return true; 2385 2402 2386 - if (mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_REQUEST || 2387 - mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_RESPONSE) 2403 + if (mgmt->u.action.action_code == WLAN_PUB_ACTION_FTM_REQUEST || 2404 + mgmt->u.action.action_code == WLAN_PUB_ACTION_FTM_RESPONSE) 2388 2405 return false; 2389 2406 2390 2407 return true; ··· 2434 2451 */ 2435 2452 static inline bool ieee80211_is_robust_mgmt_frame(struct sk_buff *skb) 2436 2453 { 2437 - if (skb->len < IEEE80211_MIN_ACTION_SIZE) 2454 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 2438 2455 return false; 2439 2456 return _ieee80211_is_robust_mgmt_frame((void *)skb->data); 2440 2457 } ··· 2450 2467 { 2451 2468 struct ieee80211_mgmt *mgmt = (void *)hdr; 2452 2469 2453 - if (len < IEEE80211_MIN_ACTION_SIZE) 2470 + if (len < IEEE80211_MIN_ACTION_SIZE(category)) 2454 2471 return false; 2455 2472 if (!ieee80211_is_action(hdr->frame_control)) 2456 2473 return false; ··· 2468 2485 static inline bool 2469 2486 ieee80211_is_protected_dual_of_public_action(struct sk_buff *skb) 2470 2487 { 2488 + struct ieee80211_mgmt *mgmt = (void *)skb->data; 2471 2489 u8 action; 2472 2490 2473 2491 if (!ieee80211_is_public_action((void *)skb->data, skb->len) || 2474 - skb->len < IEEE80211_MIN_ACTION_SIZE + 1) 2492 + skb->len < IEEE80211_MIN_ACTION_SIZE(action_code)) 2475 2493 return false; 2476 2494 2477 - action = *(u8 *)(skb->data + IEEE80211_MIN_ACTION_SIZE); 2495 + action = mgmt->u.action.action_code; 2478 2496 2479 2497 return action != WLAN_PUB_ACTION_20_40_BSS_COEX && 2480 2498 action != WLAN_PUB_ACTION_DSE_REG_LOC_ANN && ··· 2514 2530 */ 2515 2531 static inline bool ieee80211_is_group_privacy_action(struct sk_buff *skb) 2516 2532 { 2517 - if (skb->len < IEEE80211_MIN_ACTION_SIZE) 2533 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 2518 2534 return false; 2519 2535 return _ieee80211_is_group_privacy_action((void *)skb->data); 2520 2536 } ··· 2610 2626 if (!ieee80211_is_action(mgmt->frame_control)) 2611 2627 return false; 2612 2628 2613 - if (skb->len < IEEE80211_MIN_ACTION_SIZE + 2614 - sizeof(mgmt->u.action.u.tpc_report)) 2629 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(tpc_report)) 2615 2630 return false; 2616 2631 2617 2632 /* ··· 2629 2646 return false; 2630 2647 2631 2648 /* both spectrum mgmt and link measurement have same action code */ 2632 - if (mgmt->u.action.u.tpc_report.action_code != 2633 - WLAN_ACTION_SPCT_TPC_RPRT) 2649 + if (mgmt->u.action.action_code != WLAN_ACTION_SPCT_TPC_RPRT) 2634 2650 return false; 2635 2651 2636 - if (mgmt->u.action.u.tpc_report.tpc_elem_id != WLAN_EID_TPC_REPORT || 2637 - mgmt->u.action.u.tpc_report.tpc_elem_length != 2652 + if (mgmt->u.action.tpc_report.tpc_elem_id != WLAN_EID_TPC_REPORT || 2653 + mgmt->u.action.tpc_report.tpc_elem_length != 2638 2654 sizeof(struct ieee80211_tpc_report_ie)) 2639 2655 return false; 2640 2656 ··· 2649 2667 { 2650 2668 struct ieee80211_mgmt *mgmt = (void *)skb->data; 2651 2669 2652 - if (skb->len < IEEE80211_MIN_ACTION_SIZE) 2670 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(wnm_timing_msr)) 2653 2671 return false; 2654 2672 2655 2673 if (!ieee80211_is_action(mgmt->frame_control)) 2656 2674 return false; 2657 2675 2658 2676 if (mgmt->u.action.category == WLAN_CATEGORY_WNM_UNPROTECTED && 2659 - mgmt->u.action.u.wnm_timing_msr.action_code == 2660 - WLAN_UNPROTECTED_WNM_ACTION_TIMING_MEASUREMENT_RESPONSE && 2661 - skb->len >= offsetofend(typeof(*mgmt), u.action.u.wnm_timing_msr)) 2677 + mgmt->u.action.action_code == 2678 + WLAN_UNPROTECTED_WNM_ACTION_TIMING_MEASUREMENT_RESPONSE) 2662 2679 return true; 2663 2680 2664 2681 return false; ··· 2672 2691 { 2673 2692 struct ieee80211_mgmt *mgmt = (void *)skb->data; 2674 2693 2694 + if (skb->len < IEEE80211_MIN_ACTION_SIZE(ftm)) 2695 + return false; 2696 + 2675 2697 if (!ieee80211_is_public_action((void *)mgmt, skb->len)) 2676 2698 return false; 2677 2699 2678 - if (mgmt->u.action.u.ftm.action_code == 2679 - WLAN_PUB_ACTION_FTM_RESPONSE && 2680 - skb->len >= offsetofend(typeof(*mgmt), u.action.u.ftm)) 2681 - return true; 2682 - 2683 - return false; 2700 + return mgmt->u.action.action_code == WLAN_PUB_ACTION_FTM_RESPONSE; 2684 2701 } 2685 2702 2686 2703 struct element {
+4
include/net/mac80211.h
··· 2913 2913 * HW flag so drivers can opt in according to their own control, e.g. in 2914 2914 * testing. 2915 2915 * 2916 + * @IEEE80211_HW_SUPPORTS_NDP_BLOCKACK: HW can transmit/receive S1G NDP 2917 + * BlockAck frames. 2918 + * 2916 2919 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays 2917 2920 */ 2918 2921 enum ieee80211_hw_flags { ··· 2976 2973 IEEE80211_HW_DISALLOW_PUNCTURING, 2977 2974 IEEE80211_HW_HANDLES_QUIET_CSA, 2978 2975 IEEE80211_HW_STRICT, 2976 + IEEE80211_HW_SUPPORTS_NDP_BLOCKACK, 2979 2977 2980 2978 /* keep last, obviously */ 2981 2979 NUM_IEEE80211_HW_FLAGS
+6
include/uapi/linux/nl80211.h
··· 3001 3001 * interference detection is not performed on these sub-channels, their 3002 3002 * corresponding bits are consistently set to zero. 3003 3003 * 3004 + * @NL80211_ATTR_UHR_OPERATION: Full UHR Operation element, as it appears in 3005 + * association response etc., since it's abridged in the beacon. Used 3006 + * for START_AP etc. 3007 + * 3004 3008 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 3005 3009 * @NL80211_ATTR_MAX: highest attribute number currently defined 3006 3010 * @__NL80211_ATTR_AFTER_LAST: internal use ··· 3579 3575 NL80211_ATTR_DISABLE_UHR, 3580 3576 3581 3577 NL80211_ATTR_INCUMBENT_SIGNAL_INTERFERENCE_BITMAP, 3578 + 3579 + NL80211_ATTR_UHR_OPERATION, 3582 3580 3583 3581 /* add attributes here, update the policy in nl80211.c */ 3584 3582
+34 -15
net/mac80211/agg-rx.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2007-2010, Intel Corporation 11 11 * Copyright(c) 2015-2017 Intel Deutschland GmbH 12 - * Copyright (C) 2018-2025 Intel Corporation 12 + * Copyright (C) 2018-2026 Intel Corporation 13 13 */ 14 14 15 15 /** ··· 94 94 /* check if this is a self generated aggregation halt */ 95 95 if (initiator == WLAN_BACK_RECIPIENT && tx) 96 96 ieee80211_send_delba(sta->sdata, sta->sta.addr, 97 - tid, WLAN_BACK_RECIPIENT, reason); 97 + tid, WLAN_BACK_RECIPIENT, reason, 98 + ieee80211_s1g_use_ndp_ba(sta->sdata, sta)); 98 99 99 100 /* 100 101 * return here in case tid_rx is not assigned - which will happen if ··· 241 240 struct sk_buff *skb; 242 241 struct ieee80211_mgmt *mgmt; 243 242 bool amsdu = ieee80211_hw_check(&local->hw, SUPPORTS_AMSDU_IN_AMPDU); 243 + bool use_ndp = ieee80211_s1g_use_ndp_ba(sdata, sta); 244 244 u16 capab; 245 245 246 246 skb = dev_alloc_skb(sizeof(*mgmt) + ··· 253 251 skb_reserve(skb, local->hw.extra_tx_headroom); 254 252 mgmt = ieee80211_mgmt_ba(skb, da, sdata); 255 253 256 - skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp)); 254 + skb_put(skb, 2 + sizeof(mgmt->u.action.addba_resp)); 257 255 mgmt->u.action.category = WLAN_CATEGORY_BACK; 258 - mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP; 259 - mgmt->u.action.u.addba_resp.dialog_token = dialog_token; 256 + mgmt->u.action.action_code = use_ndp ? 257 + WLAN_ACTION_NDP_ADDBA_RESP : WLAN_ACTION_ADDBA_RESP; 258 + 259 + mgmt->u.action.addba_resp.dialog_token = dialog_token; 260 260 261 261 capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK); 262 262 capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK); 263 263 capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK); 264 264 capab |= u16_encode_bits(buf_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); 265 265 266 - mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab); 267 - mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout); 268 - mgmt->u.action.u.addba_resp.status = cpu_to_le16(status); 266 + mgmt->u.action.addba_resp.capab = cpu_to_le16(capab); 267 + mgmt->u.action.addba_resp.timeout = cpu_to_le16(timeout); 268 + mgmt->u.action.addba_resp.status = cpu_to_le16(status); 269 269 270 270 if (sta->sta.valid_links || sta->sta.deflink.he_cap.has_he) 271 271 ieee80211_add_addbaext(skb, req_addba_ext_data, buf_size); ··· 279 275 u8 dialog_token, u16 timeout, 280 276 u16 start_seq_num, u16 ba_policy, u16 tid, 281 277 u16 buf_size, bool tx, bool auto_seq, 278 + bool req_ndp, 282 279 const u8 addba_ext_data) 283 280 { 284 281 struct ieee80211_local *local = sta->sdata->local; ··· 301 296 if (tid >= IEEE80211_FIRST_TSPEC_TSID) { 302 297 ht_dbg(sta->sdata, 303 298 "STA %pM requests BA session on unsupported tid %d\n", 299 + sta->sta.addr, tid); 300 + goto end; 301 + } 302 + 303 + if (tx && ieee80211_s1g_use_ndp_ba(sta->sdata, sta) && !req_ndp) { 304 + /* 305 + * According to IEEE 802.11-2024: Inform S1G originator 306 + * ADDBA rejected as NDP BlockAck is preferred 307 + */ 308 + status = WLAN_STATUS_REJECTED_NDP_BLOCK_ACK_SUGGESTED; 309 + ht_dbg(sta->sdata, 310 + "Rejecting AddBA Req from %pM tid %u - require NDP BlockAck\n", 304 311 sta->sta.addr, tid); 305 312 goto end; 306 313 } ··· 490 473 struct ieee80211_mgmt *mgmt, 491 474 size_t len) 492 475 { 476 + bool req_ndp = mgmt->u.action.action_code == WLAN_ACTION_NDP_ADDBA_REQ; 493 477 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num; 494 478 u8 dialog_token, addba_ext_data; 495 479 496 480 /* extract session parameters from addba request frame */ 497 - dialog_token = mgmt->u.action.u.addba_req.dialog_token; 498 - timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout); 481 + dialog_token = mgmt->u.action.addba_req.dialog_token; 482 + timeout = le16_to_cpu(mgmt->u.action.addba_req.timeout); 499 483 start_seq_num = 500 - le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4; 484 + le16_to_cpu(mgmt->u.action.addba_req.start_seq_num) >> 4; 501 485 502 - capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); 486 + capab = le16_to_cpu(mgmt->u.action.addba_req.capab); 503 487 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1; 504 488 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 505 489 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; 506 490 507 491 addba_ext_data = 508 492 ieee80211_retrieve_addba_ext_data(sta, 509 - mgmt->u.action.u.addba_req.variable, 493 + mgmt->u.action.addba_req.variable, 510 494 len - 511 495 offsetof(typeof(*mgmt), 512 - u.action.u.addba_req.variable), 496 + u.action.addba_req.variable), 513 497 &buf_size); 514 498 515 499 __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, 516 500 start_seq_num, ba_policy, tid, 517 - buf_size, true, false, addba_ext_data); 501 + buf_size, true, false, 502 + req_ndp, addba_ext_data); 518 503 } 519 504 520 505 void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
+22 -17
net/mac80211/agg-tx.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2007-2010, Intel Corporation 11 11 * Copyright(c) 2015-2017 Intel Deutschland GmbH 12 - * Copyright (C) 2018 - 2024 Intel Corporation 12 + * Copyright (C) 2018-2026 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/ieee80211.h> ··· 60 60 61 61 static void ieee80211_send_addba_request(struct sta_info *sta, u16 tid, 62 62 u8 dialog_token, u16 start_seq_num, 63 - u16 agg_size, u16 timeout) 63 + u16 agg_size, u16 timeout, bool ndp) 64 64 { 65 65 struct ieee80211_sub_if_data *sdata = sta->sdata; 66 66 struct ieee80211_local *local = sdata->local; ··· 68 68 struct ieee80211_mgmt *mgmt; 69 69 u16 capab; 70 70 71 - skb = dev_alloc_skb(sizeof(*mgmt) + 71 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(addba_req) + 72 72 2 + sizeof(struct ieee80211_addba_ext_ie) + 73 73 local->hw.extra_tx_headroom); 74 74 if (!skb) ··· 77 77 skb_reserve(skb, local->hw.extra_tx_headroom); 78 78 mgmt = ieee80211_mgmt_ba(skb, sta->sta.addr, sdata); 79 79 80 - skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req)); 80 + skb_put(skb, 2 + sizeof(mgmt->u.action.addba_req)); 81 81 82 82 mgmt->u.action.category = WLAN_CATEGORY_BACK; 83 - mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ; 83 + mgmt->u.action.action_code = ndp ? 84 + WLAN_ACTION_NDP_ADDBA_REQ : WLAN_ACTION_ADDBA_REQ; 84 85 85 - mgmt->u.action.u.addba_req.dialog_token = dialog_token; 86 + mgmt->u.action.addba_req.dialog_token = dialog_token; 86 87 capab = IEEE80211_ADDBA_PARAM_AMSDU_MASK; 87 88 capab |= IEEE80211_ADDBA_PARAM_POLICY_MASK; 88 89 capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK); 89 90 capab |= u16_encode_bits(agg_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); 90 91 91 - mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab); 92 + mgmt->u.action.addba_req.capab = cpu_to_le16(capab); 92 93 93 - mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout); 94 - mgmt->u.action.u.addba_req.start_seq_num = 94 + mgmt->u.action.addba_req.timeout = cpu_to_le16(timeout); 95 + mgmt->u.action.addba_req.start_seq_num = 95 96 cpu_to_le16(start_seq_num << 4); 96 97 97 98 if (sta->sta.deflink.he_cap.has_he) ··· 485 484 486 485 /* send AddBA request */ 487 486 ieee80211_send_addba_request(sta, tid, tid_tx->dialog_token, 488 - tid_tx->ssn, buf_size, tid_tx->timeout); 487 + tid_tx->ssn, buf_size, tid_tx->timeout, 488 + tid_tx->ndp); 489 489 490 490 WARN_ON(test_and_set_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state)); 491 491 } ··· 523 521 */ 524 522 synchronize_net(); 525 523 524 + tid_tx->ndp = ieee80211_s1g_use_ndp_ba(sdata, sta); 526 525 params.ssn = sta->tid_seq[tid] >> 4; 527 526 ret = drv_ampdu_action(local, sdata, &params); 528 527 tid_tx->ssn = params.ssn; ··· 943 940 944 941 if (send_delba) 945 942 ieee80211_send_delba(sdata, sta->sta.addr, tid, 946 - WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); 943 + WLAN_BACK_INITIATOR, 944 + WLAN_REASON_QSTA_NOT_USE, 945 + tid_tx->ndp); 947 946 } 948 947 949 948 void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, ··· 983 978 984 979 lockdep_assert_wiphy(sta->local->hw.wiphy); 985 980 986 - capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 981 + capab = le16_to_cpu(mgmt->u.action.addba_resp.capab); 987 982 amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK; 988 983 tid = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_TID_MASK); 989 984 buf_size = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); 990 985 991 986 ieee80211_retrieve_addba_ext_data(sta, 992 - mgmt->u.action.u.addba_resp.variable, 987 + mgmt->u.action.addba_resp.variable, 993 988 len - offsetof(typeof(*mgmt), 994 - u.action.u.addba_resp.variable), 989 + u.action.addba_resp.variable), 995 990 &buf_size); 996 991 997 992 buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes); ··· 1004 999 if (!tid_tx) 1005 1000 return; 1006 1001 1007 - if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { 1002 + if (mgmt->u.action.addba_resp.dialog_token != tid_tx->dialog_token) { 1008 1003 ht_dbg(sta->sdata, "wrong addBA response token, %pM tid %d\n", 1009 1004 sta->sta.addr, tid); 1010 1005 return; ··· 1034 1029 * is set to 0, the Buffer Size subfield is set to a value 1035 1030 * of at least 1. 1036 1031 */ 1037 - if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 1032 + if (le16_to_cpu(mgmt->u.action.addba_resp.status) 1038 1033 == WLAN_STATUS_SUCCESS && buf_size) { 1039 1034 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED, 1040 1035 &tid_tx->state)) { ··· 1051 1046 sta->ampdu_mlme.addba_req_num[tid] = 0; 1052 1047 1053 1048 tid_tx->timeout = 1054 - le16_to_cpu(mgmt->u.action.u.addba_resp.timeout); 1049 + le16_to_cpu(mgmt->u.action.addba_resp.timeout); 1055 1050 1056 1051 if (tid_tx->timeout) { 1057 1052 mod_timer(&tid_tx->session_timer,
+39 -51
net/mac80211/chan.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * mac80211 - channel management 4 - * Copyright 2020 - 2025 Intel Corporation 4 + * Copyright 2020-2026 Intel Corporation 5 5 */ 6 6 7 7 #include <linux/nl80211.h> ··· 239 239 return tmp; 240 240 } 241 241 242 + /* 243 + * When checking for compatible, check against all the links using 244 + * the chanctx (except the one passed that might be changing) to 245 + * allow changes to the AP's bandwidth for wider bandwidth OFDMA 246 + * purposes, which wouldn't be treated as compatible by checking 247 + * against the chanctx's oper/ap chandefs. 248 + */ 242 249 static const struct ieee80211_chan_req * 243 - ieee80211_chanctx_compatible(struct ieee80211_chanctx *ctx, 250 + _ieee80211_chanctx_compatible(struct ieee80211_local *local, 251 + struct ieee80211_link_data *skip_link, 252 + struct ieee80211_chanctx *ctx, 253 + const struct ieee80211_chan_req *req, 254 + struct ieee80211_chan_req *tmp) 255 + { 256 + const struct ieee80211_chan_req *ret = req; 257 + struct ieee80211_chanctx_user_iter iter; 258 + 259 + lockdep_assert_wiphy(local->hw.wiphy); 260 + 261 + for_each_chanctx_user_all(local, ctx, &iter) { 262 + if (iter.link && iter.link == skip_link) 263 + continue; 264 + 265 + ret = ieee80211_chanreq_compatible(ret, iter.chanreq, tmp); 266 + if (!ret) 267 + return NULL; 268 + } 269 + 270 + *tmp = *ret; 271 + return tmp; 272 + } 273 + 274 + static const struct ieee80211_chan_req * 275 + ieee80211_chanctx_compatible(struct ieee80211_local *local, 276 + struct ieee80211_chanctx *ctx, 244 277 const struct ieee80211_chan_req *req, 245 278 struct ieee80211_chan_req *tmp) 246 279 { 247 - const struct ieee80211_chan_req *ret; 248 - struct ieee80211_chan_req tmp2; 249 - 250 - *tmp = (struct ieee80211_chan_req){ 251 - .oper = ctx->conf.def, 252 - .ap = ctx->conf.ap, 253 - }; 254 - 255 - ret = ieee80211_chanreq_compatible(tmp, req, &tmp2); 256 - if (!ret) 257 - return NULL; 258 - *tmp = *ret; 259 - return tmp; 280 + return _ieee80211_chanctx_compatible(local, NULL, ctx, req, tmp); 260 281 } 261 282 262 283 static const struct ieee80211_chan_req * ··· 777 756 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 778 757 continue; 779 758 780 - compat = ieee80211_chanctx_compatible(ctx, chanreq, &tmp); 759 + compat = ieee80211_chanctx_compatible(local, ctx, chanreq, 760 + &tmp); 781 761 if (!compat) 782 762 continue; 783 763 ··· 2150 2128 return 0; 2151 2129 } 2152 2130 2153 - /* 2154 - * This is similar to ieee80211_chanctx_compatible(), but rechecks 2155 - * against all the links actually using it (except the one that's 2156 - * passed, since that one is changing). 2157 - * This is done in order to allow changes to the AP's bandwidth for 2158 - * wider bandwidth OFDMA purposes, which wouldn't be treated as 2159 - * compatible by ieee80211_chanctx_recheck() but is OK if the link 2160 - * requesting the update is the only one using it. 2161 - */ 2162 - static const struct ieee80211_chan_req * 2163 - ieee80211_chanctx_recheck(struct ieee80211_local *local, 2164 - struct ieee80211_link_data *skip_link, 2165 - struct ieee80211_chanctx *ctx, 2166 - const struct ieee80211_chan_req *req, 2167 - struct ieee80211_chan_req *tmp) 2168 - { 2169 - const struct ieee80211_chan_req *ret = req; 2170 - struct ieee80211_chanctx_user_iter iter; 2171 - 2172 - lockdep_assert_wiphy(local->hw.wiphy); 2173 - 2174 - for_each_chanctx_user_all(local, ctx, &iter) { 2175 - if (iter.link == skip_link) 2176 - continue; 2177 - 2178 - ret = ieee80211_chanreq_compatible(ret, iter.chanreq, tmp); 2179 - if (!ret) 2180 - return NULL; 2181 - } 2182 - 2183 - *tmp = *ret; 2184 - return tmp; 2185 - } 2186 - 2187 2131 int ieee80211_link_change_chanreq(struct ieee80211_link_data *link, 2188 2132 const struct ieee80211_chan_req *chanreq, 2189 2133 u64 *changed) ··· 2186 2198 2187 2199 ctx = container_of(conf, struct ieee80211_chanctx, conf); 2188 2200 2189 - compat = ieee80211_chanctx_recheck(local, link, ctx, chanreq, &tmp); 2201 + compat = _ieee80211_chanctx_compatible(local, link, ctx, chanreq, &tmp); 2190 2202 if (!compat) 2191 2203 return -EINVAL; 2192 2204
+1
net/mac80211/debugfs.c
··· 490 490 FLAG(DISALLOW_PUNCTURING), 491 491 FLAG(HANDLES_QUIET_CSA), 492 492 FLAG(STRICT), 493 + FLAG(SUPPORTS_NDP_BLOCKACK), 493 494 #undef FLAG 494 495 }; 495 496
+10 -11
net/mac80211/eht.c
··· 108 108 ieee80211_send_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata, 109 109 struct ieee80211_mgmt *req, int opt_len) 110 110 { 111 - int len = offsetofend(struct ieee80211_mgmt, u.action.u.eml_omn); 111 + int len = IEEE80211_MIN_ACTION_SIZE(eml_omn); 112 112 struct ieee80211_local *local = sdata->local; 113 113 struct ieee80211_mgmt *mgmt; 114 114 struct sk_buff *skb; ··· 127 127 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 128 128 129 129 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 130 - mgmt->u.action.u.eml_omn.action_code = 131 - WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF; 132 - mgmt->u.action.u.eml_omn.dialog_token = 133 - req->u.action.u.eml_omn.dialog_token; 134 - mgmt->u.action.u.eml_omn.control = req->u.action.u.eml_omn.control & 130 + mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF; 131 + mgmt->u.action.eml_omn.dialog_token = 132 + req->u.action.eml_omn.dialog_token; 133 + mgmt->u.action.eml_omn.control = req->u.action.eml_omn.control & 135 134 ~(IEEE80211_EML_CTRL_EMLSR_PARAM_UPDATE | 136 135 IEEE80211_EML_CTRL_INDEV_COEX_ACT); 137 136 /* Copy optional fields from the received notification frame */ 138 - memcpy(mgmt->u.action.u.eml_omn.variable, 139 - req->u.action.u.eml_omn.variable, opt_len); 137 + memcpy(mgmt->u.action.eml_omn.variable, 138 + req->u.action.eml_omn.variable, opt_len); 140 139 141 140 ieee80211_tx_skb(sdata, skb); 142 141 } ··· 143 144 void ieee80211_rx_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata, 144 145 struct sk_buff *skb) 145 146 { 146 - int len = offsetofend(struct ieee80211_mgmt, u.action.u.eml_omn); 147 + int len = IEEE80211_MIN_ACTION_SIZE(eml_omn); 147 148 enum nl80211_iftype type = ieee80211_vif_type_p2p(&sdata->vif); 148 149 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 149 150 const struct wiphy_iftype_ext_capab *ift_ext_capa; 150 151 struct ieee80211_mgmt *mgmt = (void *)skb->data; 151 152 struct ieee80211_local *local = sdata->local; 152 - u8 control = mgmt->u.action.u.eml_omn.control; 153 - u8 *ptr = mgmt->u.action.u.eml_omn.variable; 153 + u8 control = mgmt->u.action.eml_omn.control; 154 + u8 *ptr = mgmt->u.action.eml_omn.variable; 154 155 struct ieee80211_eml_params eml_params = { 155 156 .link_id = status->link_id, 156 157 .control = control,
+20 -17
net/mac80211/ht.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2007-2010, Intel Corporation 11 11 * Copyright 2017 Intel Deutschland GmbH 12 - * Copyright(c) 2020-2025 Intel Corporation 12 + * Copyright(c) 2020-2026 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/ieee80211.h> ··· 379 379 sta->ampdu_mlme.tid_rx_manage_offl)) 380 380 __ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid, 381 381 IEEE80211_MAX_AMPDU_BUF_HT, 382 - false, true, 0); 382 + false, true, false, 0); 383 383 384 384 if (test_and_clear_bit(tid + IEEE80211_NUM_TIDS, 385 385 sta->ampdu_mlme.tid_rx_manage_offl)) ··· 455 455 456 456 void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, 457 457 const u8 *da, u16 tid, 458 - u16 initiator, u16 reason_code) 458 + u16 initiator, u16 reason_code, 459 + bool use_ndp) 459 460 { 460 461 struct ieee80211_local *local = sdata->local; 461 462 struct sk_buff *skb; 462 463 struct ieee80211_mgmt *mgmt; 463 464 u16 params; 464 465 465 - skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); 466 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(delba) + 467 + local->hw.extra_tx_headroom); 466 468 if (!skb) 467 469 return; 468 470 469 471 skb_reserve(skb, local->hw.extra_tx_headroom); 470 472 mgmt = ieee80211_mgmt_ba(skb, da, sdata); 471 473 472 - skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba)); 474 + skb_put(skb, 2 + sizeof(mgmt->u.action.delba)); 473 475 474 476 mgmt->u.action.category = WLAN_CATEGORY_BACK; 475 - mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA; 477 + mgmt->u.action.action_code = use_ndp ? 478 + WLAN_ACTION_NDP_DELBA : WLAN_ACTION_DELBA; 476 479 params = (u16)(initiator << 11); /* bit 11 initiator */ 477 480 params |= (u16)(tid << 12); /* bit 15:12 TID number */ 478 481 479 - mgmt->u.action.u.delba.params = cpu_to_le16(params); 480 - mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code); 482 + mgmt->u.action.delba.params = cpu_to_le16(params); 483 + mgmt->u.action.delba.reason_code = cpu_to_le16(reason_code); 481 484 482 485 ieee80211_tx_skb(sdata, skb); 483 486 } ··· 492 489 u16 tid, params; 493 490 u16 initiator; 494 491 495 - params = le16_to_cpu(mgmt->u.action.u.delba.params); 492 + params = le16_to_cpu(mgmt->u.action.delba.params); 496 493 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; 497 494 initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11; 498 495 499 496 ht_dbg_ratelimited(sdata, "delba from %pM (%s) tid %d reason code %d\n", 500 497 mgmt->sa, initiator ? "initiator" : "recipient", 501 498 tid, 502 - le16_to_cpu(mgmt->u.action.u.delba.reason_code)); 499 + le16_to_cpu(mgmt->u.action.delba.reason_code)); 503 500 504 501 if (initiator == WLAN_BACK_INITIATOR) 505 502 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0, ··· 533 530 struct ieee80211_tx_info *info; 534 531 u8 status_link_id = link_id < 0 ? 0 : link_id; 535 532 536 - /* 27 = header + category + action + smps mode */ 537 - skb = dev_alloc_skb(27 + local->hw.extra_tx_headroom); 533 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(ht_smps) + 534 + local->hw.extra_tx_headroom); 538 535 if (!skb) 539 536 return -ENOMEM; 540 537 541 538 skb_reserve(skb, local->hw.extra_tx_headroom); 542 - action_frame = skb_put(skb, 27); 539 + action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(ht_smps)); 543 540 memcpy(action_frame->da, da, ETH_ALEN); 544 541 memcpy(action_frame->sa, sdata->dev->dev_addr, ETH_ALEN); 545 542 memcpy(action_frame->bssid, bssid, ETH_ALEN); 546 543 action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 547 544 IEEE80211_STYPE_ACTION); 548 545 action_frame->u.action.category = WLAN_CATEGORY_HT; 549 - action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS; 546 + action_frame->u.action.action_code = WLAN_HT_ACTION_SMPS; 550 547 switch (smps) { 551 548 case IEEE80211_SMPS_AUTOMATIC: 552 549 case IEEE80211_SMPS_NUM_MODES: ··· 554 551 smps = IEEE80211_SMPS_OFF; 555 552 fallthrough; 556 553 case IEEE80211_SMPS_OFF: 557 - action_frame->u.action.u.ht_smps.smps_control = 554 + action_frame->u.action.ht_smps.smps_control = 558 555 WLAN_HT_SMPS_CONTROL_DISABLED; 559 556 break; 560 557 case IEEE80211_SMPS_STATIC: 561 - action_frame->u.action.u.ht_smps.smps_control = 558 + action_frame->u.action.ht_smps.smps_control = 562 559 WLAN_HT_SMPS_CONTROL_STATIC; 563 560 break; 564 561 case IEEE80211_SMPS_DYNAMIC: 565 - action_frame->u.action.u.ht_smps.smps_control = 562 + action_frame->u.action.ht_smps.smps_control = 566 563 WLAN_HT_SMPS_CONTROL_DYNAMIC; 567 564 break; 568 565 }
+5 -13
net/mac80211/ibss.c
··· 9 9 * Copyright 2009, Johannes Berg <johannes@sipsolutions.net> 10 10 * Copyright 2013-2014 Intel Mobile Communications GmbH 11 11 * Copyright(c) 2016 Intel Deutschland GmbH 12 - * Copyright(c) 2018-2025 Intel Corporation 12 + * Copyright(c) 2018-2026 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/delay.h> ··· 888 888 struct ieee80211_rx_status *rx_status, 889 889 struct ieee802_11_elems *elems) 890 890 { 891 - int required_len; 892 - 893 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 891 + if (len < IEEE80211_MIN_ACTION_SIZE(chan_switch)) 894 892 return; 895 893 896 894 /* CSA is the only action we handle for now */ 897 - if (mgmt->u.action.u.measurement.action_code != 898 - WLAN_ACTION_SPCT_CHL_SWITCH) 899 - return; 900 - 901 - required_len = IEEE80211_MIN_ACTION_SIZE + 902 - sizeof(mgmt->u.action.u.chan_switch); 903 - if (len < required_len) 895 + if (mgmt->u.action.action_code != WLAN_ACTION_SPCT_CHL_SWITCH) 904 896 return; 905 897 906 898 if (!sdata->vif.bss_conf.csa_active) ··· 1605 1613 case WLAN_CATEGORY_SPECTRUM_MGMT: 1606 1614 ies_len = skb->len - 1607 1615 offsetof(struct ieee80211_mgmt, 1608 - u.action.u.chan_switch.variable); 1616 + u.action.chan_switch.variable); 1609 1617 1610 1618 if (ies_len < 0) 1611 1619 break; 1612 1620 1613 - elems = ieee802_11_parse_elems(mgmt->u.action.u.chan_switch.variable, 1621 + elems = ieee802_11_parse_elems(mgmt->u.action.chan_switch.variable, 1614 1622 ies_len, 1615 1623 IEEE80211_FTYPE_MGMT | 1616 1624 IEEE80211_STYPE_ACTION,
+5 -1
net/mac80211/ieee80211_i.h
··· 2190 2190 struct link_sta_info *link_sta); 2191 2191 void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, 2192 2192 const u8 *da, u16 tid, 2193 - u16 initiator, u16 reason_code); 2193 + u16 initiator, u16 reason_code, 2194 + bool use_ndp); 2194 2195 int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, 2195 2196 enum ieee80211_smps_mode smps, const u8 *da, 2196 2197 const u8 *bssid, int link_id); ··· 2207 2206 u8 dialog_token, u16 timeout, 2208 2207 u16 start_seq_num, u16 ba_policy, u16 tid, 2209 2208 u16 buf_size, bool tx, bool auto_seq, 2209 + bool req_ndp, 2210 2210 const u8 addba_ext_data); 2211 2211 void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, 2212 2212 enum ieee80211_agg_stop_reason reason); ··· 2333 2331 void ieee80211_s1g_cap_to_sta_s1g_cap(struct ieee80211_sub_if_data *sdata, 2334 2332 const struct ieee80211_s1g_cap *s1g_cap_ie, 2335 2333 struct link_sta_info *link_sta); 2334 + bool ieee80211_s1g_use_ndp_ba(const struct ieee80211_sub_if_data *sdata, 2335 + const struct sta_info *sta); 2336 2336 2337 2337 /* Spectrum management */ 2338 2338 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
+12 -9
net/mac80211/iface.c
··· 1579 1579 1580 1580 sta = sta_info_get_bss(sdata, mgmt->sa); 1581 1581 if (sta) { 1582 - switch (mgmt->u.action.u.addba_req.action_code) { 1582 + switch (mgmt->u.action.action_code) { 1583 1583 case WLAN_ACTION_ADDBA_REQ: 1584 + case WLAN_ACTION_NDP_ADDBA_REQ: 1584 1585 ieee80211_process_addba_request(local, sta, 1585 1586 mgmt, len); 1586 1587 break; 1587 1588 case WLAN_ACTION_ADDBA_RESP: 1589 + case WLAN_ACTION_NDP_ADDBA_RESP: 1588 1590 ieee80211_process_addba_resp(local, sta, 1589 1591 mgmt, len); 1590 1592 break; 1591 1593 case WLAN_ACTION_DELBA: 1594 + case WLAN_ACTION_NDP_DELBA: 1592 1595 ieee80211_process_delba(sdata, sta, 1593 1596 mgmt, len); 1594 1597 break; ··· 1602 1599 } 1603 1600 } else if (ieee80211_is_action(mgmt->frame_control) && 1604 1601 mgmt->u.action.category == WLAN_CATEGORY_HT) { 1605 - switch (mgmt->u.action.u.ht_smps.action) { 1602 + switch (mgmt->u.action.action_code) { 1606 1603 case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { 1607 - u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth; 1604 + u8 chanwidth = mgmt->u.action.ht_notify_cw.chanwidth; 1608 1605 struct ieee80211_rx_status *status; 1609 1606 struct link_sta_info *link_sta; 1610 1607 struct sta_info *sta; ··· 1631 1628 } 1632 1629 } else if (ieee80211_is_action(mgmt->frame_control) && 1633 1630 mgmt->u.action.category == WLAN_CATEGORY_VHT) { 1634 - switch (mgmt->u.action.u.vht_group_notif.action_code) { 1631 + switch (mgmt->u.action.action_code) { 1635 1632 case WLAN_VHT_ACTION_OPMODE_NOTIF: { 1636 1633 struct ieee80211_rx_status *status; 1637 1634 enum nl80211_band band; ··· 1640 1637 1641 1638 status = IEEE80211_SKB_RXCB(skb); 1642 1639 band = status->band; 1643 - opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode; 1640 + opmode = mgmt->u.action.vht_opmode_notif.operating_mode; 1644 1641 1645 1642 sta = sta_info_get_bss(sdata, mgmt->sa); 1646 1643 ··· 1661 1658 } 1662 1659 } else if (ieee80211_is_action(mgmt->frame_control) && 1663 1660 mgmt->u.action.category == WLAN_CATEGORY_S1G) { 1664 - switch (mgmt->u.action.u.s1g.action_code) { 1661 + switch (mgmt->u.action.action_code) { 1665 1662 case WLAN_S1G_TWT_TEARDOWN: 1666 1663 case WLAN_S1G_TWT_SETUP: 1667 1664 ieee80211_s1g_rx_twt_action(sdata, skb); ··· 1672 1669 } else if (ieee80211_is_action(mgmt->frame_control) && 1673 1670 mgmt->u.action.category == WLAN_CATEGORY_PROTECTED_EHT) { 1674 1671 if (sdata->vif.type == NL80211_IFTYPE_AP) { 1675 - switch (mgmt->u.action.u.eml_omn.action_code) { 1672 + switch (mgmt->u.action.action_code) { 1676 1673 case WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF: 1677 1674 ieee80211_rx_eml_op_mode_notif(sdata, skb); 1678 1675 break; ··· 1680 1677 break; 1681 1678 } 1682 1679 } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { 1683 - switch (mgmt->u.action.u.ttlm_req.action_code) { 1680 + switch (mgmt->u.action.action_code) { 1684 1681 case WLAN_PROTECTED_EHT_ACTION_TTLM_REQ: 1685 1682 ieee80211_process_neg_ttlm_req(sdata, mgmt, 1686 1683 skb->len); ··· 1768 1765 1769 1766 if (ieee80211_is_action(mgmt->frame_control) && 1770 1767 mgmt->u.action.category == WLAN_CATEGORY_S1G) { 1771 - switch (mgmt->u.action.u.s1g.action_code) { 1768 + switch (mgmt->u.action.action_code) { 1772 1769 case WLAN_S1G_TWT_TEARDOWN: 1773 1770 case WLAN_S1G_TWT_SETUP: 1774 1771 ieee80211_s1g_status_twt_action(sdata, skb);
+15 -3
net/mac80211/main.c
··· 1118 1118 return true; 1119 1119 } 1120 1120 1121 + static void ieee80211_create_default_chandef(struct cfg80211_chan_def *chandef, 1122 + struct ieee80211_channel *chan) 1123 + { 1124 + *chandef = (struct cfg80211_chan_def) { 1125 + .chan = chan, 1126 + .width = chan->band == NL80211_BAND_S1GHZ ? 1127 + NL80211_CHAN_WIDTH_1 : 1128 + NL80211_CHAN_WIDTH_20_NOHT, 1129 + .center_freq1 = chan->center_freq, 1130 + .freq1_offset = chan->freq_offset, 1131 + }; 1132 + } 1133 + 1121 1134 int ieee80211_register_hw(struct ieee80211_hw *hw) 1122 1135 { 1123 1136 struct ieee80211_local *local = hw_to_local(hw); ··· 1274 1261 /* if none found then use the first anyway */ 1275 1262 if (i == sband->n_channels) 1276 1263 i = 0; 1277 - cfg80211_chandef_create(&dflt_chandef, 1278 - &sband->channels[i], 1279 - NL80211_CHAN_NO_HT); 1264 + ieee80211_create_default_chandef(&dflt_chandef, 1265 + &sband->channels[i]); 1280 1266 /* init channel we're on */ 1281 1267 local->monitor_chanreq.oper = dflt_chandef; 1282 1268 if (local->emulate_chanctx) {
+6 -8
net/mac80211/mesh.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (c) 2008, 2009 open80211s Ltd. 4 - * Copyright (C) 2018 - 2025 Intel Corporation 4 + * Copyright (C) 2018-2026 Intel Corporation 5 5 * Authors: Luis Carlos Cobo <luisca@cozybit.com> 6 6 * Javier Cardona <javier@cozybit.com> 7 7 */ ··· 19 19 20 20 bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt) 21 21 { 22 - return (mgmt->u.action.u.mesh_action.action_code == 23 - WLAN_MESH_ACTION_HWMP_PATH_SELECTION); 22 + return mgmt->u.action.action_code == WLAN_MESH_ACTION_HWMP_PATH_SELECTION; 24 23 } 25 24 26 25 void ieee80211s_init(void) ··· 1617 1618 size_t baselen; 1618 1619 u8 *pos; 1619 1620 1620 - if (mgmt->u.action.u.measurement.action_code != 1621 - WLAN_ACTION_SPCT_CHL_SWITCH) 1621 + if (mgmt->u.action.action_code != WLAN_ACTION_SPCT_CHL_SWITCH) 1622 1622 return; 1623 1623 1624 - pos = mgmt->u.action.u.chan_switch.variable; 1624 + pos = mgmt->u.action.chan_switch.variable; 1625 1625 baselen = offsetof(struct ieee80211_mgmt, 1626 - u.action.u.chan_switch.variable); 1626 + u.action.chan_switch.variable); 1627 1627 elems = ieee802_11_parse_elems(pos, len - baselen, 1628 1628 IEEE80211_FTYPE_MGMT | 1629 1629 IEEE80211_STYPE_ACTION, ··· 1668 1670 { 1669 1671 switch (mgmt->u.action.category) { 1670 1672 case WLAN_CATEGORY_SELF_PROTECTED: 1671 - switch (mgmt->u.action.u.self_prot.action_code) { 1673 + switch (mgmt->u.action.action_code) { 1672 1674 case WLAN_SP_MESH_PEERING_OPEN: 1673 1675 case WLAN_SP_MESH_PEERING_CLOSE: 1674 1676 case WLAN_SP_MESH_PEERING_CONFIRM:
+8 -12
net/mac80211/mesh_hwmp.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (c) 2008, 2009 open80211s Ltd. 4 - * Copyright (C) 2019, 2021-2023, 2025 Intel Corporation 4 + * Copyright (C) 2019, 2021-2023, 2025-2026 Intel Corporation 5 5 * Author: Luis Carlos Cobo <luisca@cozybit.com> 6 6 */ 7 7 ··· 105 105 u32 lifetime, u32 metric, u32 preq_id, 106 106 struct ieee80211_sub_if_data *sdata) 107 107 { 108 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(mesh_action); 108 109 struct ieee80211_local *local = sdata->local; 109 110 struct sk_buff *skb; 110 111 struct ieee80211_mgmt *mgmt; 111 112 u8 *pos, ie_len; 112 - int hdr_len = offsetofend(struct ieee80211_mgmt, 113 - u.action.u.mesh_action); 114 113 115 114 skb = dev_alloc_skb(local->tx_headroom + 116 115 hdr_len + ··· 126 127 /* BSSID == SA */ 127 128 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 128 129 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; 129 - mgmt->u.action.u.mesh_action.action_code = 130 - WLAN_MESH_ACTION_HWMP_PATH_SELECTION; 130 + mgmt->u.action.action_code = WLAN_MESH_ACTION_HWMP_PATH_SELECTION; 131 131 132 132 switch (action) { 133 133 case MPATH_PREQ: ··· 235 237 u8 ttl, const u8 *target, u32 target_sn, 236 238 u16 target_rcode, const u8 *ra) 237 239 { 240 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(mesh_action); 238 241 struct ieee80211_local *local = sdata->local; 239 242 struct sk_buff *skb; 240 243 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 241 244 struct ieee80211_mgmt *mgmt; 242 245 u8 *pos, ie_len; 243 - int hdr_len = offsetofend(struct ieee80211_mgmt, 244 - u.action.u.mesh_action); 245 246 246 247 if (time_before(jiffies, ifmsh->next_perr)) 247 248 return -EAGAIN; ··· 262 265 /* BSSID == SA */ 263 266 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 264 267 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; 265 - mgmt->u.action.u.mesh_action.action_code = 266 - WLAN_MESH_ACTION_HWMP_PATH_SELECTION; 268 + mgmt->u.action.action_code = WLAN_MESH_ACTION_HWMP_PATH_SELECTION; 267 269 ie_len = 15; 268 270 pos = skb_put(skb, 2 + ie_len); 269 271 *pos++ = WLAN_EID_PERR; ··· 934 938 struct sta_info *sta; 935 939 936 940 /* need action_code */ 937 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 941 + if (len < IEEE80211_MIN_ACTION_SIZE(mesh_action)) 938 942 return; 939 943 940 944 rcu_read_lock(); ··· 945 949 } 946 950 rcu_read_unlock(); 947 951 948 - baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; 949 - elems = ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, 952 + baselen = mgmt->u.action.mesh_action.variable - (u8 *)mgmt; 953 + elems = ieee802_11_parse_elems(mgmt->u.action.mesh_action.variable, 950 954 len - baselen, 951 955 IEEE80211_FTYPE_MGMT | 952 956 IEEE80211_STYPE_ACTION,
+10 -11
net/mac80211/mesh_plink.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (c) 2008, 2009 open80211s Ltd. 4 - * Copyright (C) 2019, 2021-2025 Intel Corporation 4 + * Copyright (C) 2019, 2021-2026 Intel Corporation 5 5 * Author: Luis Carlos Cobo <luisca@cozybit.com> 6 6 */ 7 7 #include <linux/gfp.h> ··· 13 13 #include "rate.h" 14 14 #include "mesh.h" 15 15 16 - #define PLINK_CNF_AID(mgmt) ((mgmt)->u.action.u.self_prot.variable + 2) 16 + #define PLINK_CNF_AID(mgmt) ((mgmt)->u.action.self_prot.variable + 2) 17 17 #define PLINK_GET_LLID(p) (p + 2) 18 18 #define PLINK_GET_PLID(p) (p + 4) 19 19 ··· 215 215 enum ieee80211_self_protected_actioncode action, 216 216 u8 *da, u16 llid, u16 plid, u16 reason) 217 217 { 218 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(self_prot); 218 219 struct ieee80211_local *local = sdata->local; 219 220 struct sk_buff *skb; 220 221 struct ieee80211_tx_info *info; ··· 224 223 u16 peering_proto = 0; 225 224 u8 *pos, ie_len = 4; 226 225 u8 ie_len_he_cap, ie_len_eht_cap; 227 - int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot); 228 226 int err = -ENOMEM; 229 227 230 228 ie_len_he_cap = ieee80211_ie_len_he_cap(sdata); ··· 260 260 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 261 261 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 262 262 mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED; 263 - mgmt->u.action.u.self_prot.action_code = action; 263 + mgmt->u.action.action_code = action; 264 264 265 265 if (action != WLAN_SP_MESH_PEERING_CLOSE) { 266 266 struct ieee80211_supported_band *sband; ··· 1141 1141 return; 1142 1142 } 1143 1143 1144 - ftype = mgmt->u.action.u.self_prot.action_code; 1144 + ftype = mgmt->u.action.action_code; 1145 1145 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) || 1146 1146 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || 1147 1147 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 ··· 1224 1224 size_t baselen; 1225 1225 u8 *baseaddr; 1226 1226 1227 - /* need action_code, aux */ 1228 - if (len < IEEE80211_MIN_ACTION_SIZE + 3) 1227 + /* need aux */ 1228 + if (len < IEEE80211_MIN_ACTION_SIZE(self_prot) + 1) 1229 1229 return; 1230 1230 1231 1231 if (sdata->u.mesh.user_mpm) ··· 1238 1238 return; 1239 1239 } 1240 1240 1241 - baseaddr = mgmt->u.action.u.self_prot.variable; 1242 - baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt; 1243 - if (mgmt->u.action.u.self_prot.action_code == 1244 - WLAN_SP_MESH_PEERING_CONFIRM) { 1241 + baseaddr = mgmt->u.action.self_prot.variable; 1242 + baselen = mgmt->u.action.self_prot.variable - (u8 *)mgmt; 1243 + if (mgmt->u.action.action_code == WLAN_SP_MESH_PEERING_CONFIRM) { 1245 1244 baseaddr += 4; 1246 1245 baselen += 4; 1247 1246
+66 -47
net/mac80211/mlme.c
··· 216 216 return IEEE80211_CONN_MODE_LEGACY; 217 217 } 218 218 219 + if (eht_oper && ieee80211_hw_check(&sdata->local->hw, STRICT)) { 220 + struct cfg80211_chan_def he_chandef = *chandef; 221 + 222 + if (!ieee80211_chandef_he_6ghz_oper(sdata->local, 223 + he_oper, NULL, 224 + &he_chandef)) { 225 + sdata_info(sdata, 226 + "bad HE operation in EHT AP\n"); 227 + return IEEE80211_CONN_MODE_LEGACY; 228 + } 229 + 230 + if (!cfg80211_chandef_compatible(chandef, 231 + &he_chandef)) { 232 + sdata_info(sdata, "HE/EHT incompatible\n"); 233 + return IEEE80211_CONN_MODE_LEGACY; 234 + } 235 + } 236 + 219 237 if (mode <= IEEE80211_CONN_MODE_EHT) 220 238 return mode; 221 239 goto check_uhr; ··· 6739 6721 sdata_info(sdata, 6740 6722 "RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n", 6741 6723 reassoc ? "Rea" : "A", assoc_data->ap_addr, 6742 - capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); 6724 + capab_info, status_code, aid); 6743 6725 6744 6726 ifmgd->broken_ap = false; 6745 6727 ··· 7076 7058 container_of(work, struct ieee80211_sub_if_data, 7077 7059 u.mgd.ml_reconf_work.work); 7078 7060 u16 new_valid_links, new_active_links, new_dormant_links; 7061 + struct sta_info *sta; 7079 7062 int ret; 7080 7063 7081 7064 if (!sdata->u.mgd.removed_links) ··· 7110 7091 "Failed setting active links\n"); 7111 7092 goto out; 7112 7093 } 7094 + } 7095 + 7096 + sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr); 7097 + if (sta) { 7098 + unsigned long removed_links = sdata->u.mgd.removed_links; 7099 + unsigned int link_id; 7100 + 7101 + for_each_set_bit(link_id, &removed_links, 7102 + IEEE80211_MLD_MAX_NUM_LINKS) 7103 + ieee80211_sta_remove_link(sta, link_id); 7113 7104 } 7114 7105 7115 7106 new_dormant_links = sdata->vif.dormant_links & ~sdata->u.mgd.removed_links; ··· 7986 7957 struct ieee80211_local *local = sdata->local; 7987 7958 struct ieee80211_mgmt *mgmt; 7988 7959 struct sk_buff *skb; 7989 - int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.ttlm_req); 7960 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(ttlm_req); 7990 7961 int ttlm_max_len = 2 + 1 + sizeof(struct ieee80211_ttlm_elem) + 1 + 7991 7962 2 * 2 * IEEE80211_TTLM_NUM_TIDS; 7992 7963 ··· 8003 7974 memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN); 8004 7975 8005 7976 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 8006 - mgmt->u.action.u.ttlm_req.action_code = 8007 - WLAN_PROTECTED_EHT_ACTION_TTLM_REQ; 8008 - mgmt->u.action.u.ttlm_req.dialog_token = dialog_token; 7977 + mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_TTLM_REQ; 7978 + mgmt->u.action.ttlm_req.dialog_token = dialog_token; 8009 7979 ieee80211_neg_ttlm_add_suggested_map(skb, neg_ttlm); 8010 7980 ieee80211_tx_skb(sdata, skb); 8011 7981 } ··· 8054 8026 struct ieee80211_local *local = sdata->local; 8055 8027 struct ieee80211_mgmt *mgmt; 8056 8028 struct sk_buff *skb; 8057 - int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.ttlm_res); 8029 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(ttlm_res); 8058 8030 int ttlm_max_len = 2 + 1 + sizeof(struct ieee80211_ttlm_elem) + 1 + 8059 8031 2 * 2 * IEEE80211_TTLM_NUM_TIDS; 8060 8032 u16 status_code; ··· 8072 8044 memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN); 8073 8045 8074 8046 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 8075 - mgmt->u.action.u.ttlm_res.action_code = 8076 - WLAN_PROTECTED_EHT_ACTION_TTLM_RES; 8077 - mgmt->u.action.u.ttlm_res.dialog_token = dialog_token; 8047 + mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_TTLM_RES; 8048 + mgmt->u.action.ttlm_res.dialog_token = dialog_token; 8078 8049 switch (ttlm_res) { 8079 8050 default: 8080 8051 WARN_ON(1); ··· 8090 8063 break; 8091 8064 } 8092 8065 8093 - mgmt->u.action.u.ttlm_res.status_code = cpu_to_le16(status_code); 8066 + mgmt->u.action.ttlm_res.status_code = cpu_to_le16(status_code); 8094 8067 ieee80211_tx_skb(sdata, skb); 8095 8068 } 8096 8069 ··· 8190 8163 if (!ieee80211_vif_is_mld(&sdata->vif)) 8191 8164 return; 8192 8165 8193 - dialog_token = mgmt->u.action.u.ttlm_req.dialog_token; 8194 - ies_len = len - offsetof(struct ieee80211_mgmt, 8195 - u.action.u.ttlm_req.variable); 8196 - elems = ieee802_11_parse_elems(mgmt->u.action.u.ttlm_req.variable, 8166 + dialog_token = mgmt->u.action.ttlm_req.dialog_token; 8167 + ies_len = len - IEEE80211_MIN_ACTION_SIZE(ttlm_req); 8168 + elems = ieee802_11_parse_elems(mgmt->u.action.ttlm_req.variable, 8197 8169 ies_len, 8198 8170 IEEE80211_FTYPE_MGMT | 8199 8171 IEEE80211_STYPE_ACTION, ··· 8243 8217 struct ieee80211_mgmt *mgmt, size_t len) 8244 8218 { 8245 8219 if (!ieee80211_vif_is_mld(&sdata->vif) || 8246 - mgmt->u.action.u.ttlm_req.dialog_token != 8247 - sdata->u.mgd.dialog_token_alloc) 8220 + mgmt->u.action.ttlm_res.dialog_token != sdata->u.mgd.dialog_token_alloc) 8248 8221 return; 8249 8222 8250 8223 wiphy_delayed_work_cancel(sdata->local->hw.wiphy, ··· 8257 8232 * This can be better implemented in the future, to handle request 8258 8233 * rejections. 8259 8234 */ 8260 - if (le16_to_cpu(mgmt->u.action.u.ttlm_res.status_code) != WLAN_STATUS_SUCCESS) 8235 + if (le16_to_cpu(mgmt->u.action.ttlm_res.status_code) != WLAN_STATUS_SUCCESS) 8261 8236 __ieee80211_disconnect(sdata); 8262 8237 } 8263 8238 ··· 8290 8265 8291 8266 void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif) 8292 8267 { 8268 + int frame_len = IEEE80211_MIN_ACTION_SIZE(ttlm_tear_down); 8293 8269 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 8294 8270 struct ieee80211_local *local = sdata->local; 8295 8271 struct ieee80211_mgmt *mgmt; 8296 8272 struct sk_buff *skb; 8297 - int frame_len = offsetofend(struct ieee80211_mgmt, 8298 - u.action.u.ttlm_tear_down); 8299 8273 struct ieee80211_tx_info *info; 8300 8274 8301 8275 skb = dev_alloc_skb(local->hw.extra_tx_headroom + frame_len); ··· 8310 8286 memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN); 8311 8287 8312 8288 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 8313 - mgmt->u.action.u.ttlm_tear_down.action_code = 8314 - WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN; 8289 + mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN; 8315 8290 8316 8291 info = IEEE80211_SKB_CB(skb); 8317 8292 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; ··· 8393 8370 case WLAN_CATEGORY_SPECTRUM_MGMT: 8394 8371 ies_len = skb->len - 8395 8372 offsetof(struct ieee80211_mgmt, 8396 - u.action.u.chan_switch.variable); 8373 + u.action.chan_switch.variable); 8397 8374 8398 8375 if (ies_len < 0) 8399 8376 break; 8400 8377 8401 8378 /* CSA IE cannot be overridden, no need for BSSID */ 8402 - elems = ieee802_11_parse_elems(mgmt->u.action.u.chan_switch.variable, 8379 + elems = ieee802_11_parse_elems(mgmt->u.action.chan_switch.variable, 8403 8380 ies_len, 8404 8381 IEEE80211_FTYPE_MGMT | 8405 8382 IEEE80211_STYPE_ACTION, ··· 8421 8398 case WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION: 8422 8399 ies_len = skb->len - 8423 8400 offsetof(struct ieee80211_mgmt, 8424 - u.action.u.ext_chan_switch.variable); 8401 + u.action.ext_chan_switch.variable); 8425 8402 8426 8403 if (ies_len < 0) 8427 8404 break; ··· 8430 8407 * extended CSA IE can't be overridden, no need for 8431 8408 * BSSID 8432 8409 */ 8433 - elems = ieee802_11_parse_elems(mgmt->u.action.u.ext_chan_switch.variable, 8410 + elems = ieee802_11_parse_elems(mgmt->u.action.ext_chan_switch.variable, 8434 8411 ies_len, 8435 8412 IEEE80211_FTYPE_MGMT | 8436 8413 IEEE80211_STYPE_ACTION, ··· 8447 8424 8448 8425 /* for the handling code pretend it was an IE */ 8449 8426 elems->ext_chansw_ie = 8450 - &mgmt->u.action.u.ext_chan_switch.data; 8427 + &mgmt->u.action.ext_chan_switch.data; 8451 8428 8452 8429 ieee80211_sta_process_chanswitch(link, 8453 8430 rx_status->mactime, ··· 10449 10426 u8 *pos; 10450 10427 10451 10428 if (!ieee80211_vif_is_mld(&sdata->vif) || 10452 - len < offsetofend(typeof(*mgmt), u.action.u.ml_reconf_resp) || 10453 - mgmt->u.action.u.ml_reconf_resp.dialog_token != 10454 - sdata->u.mgd.reconf.dialog_token || 10429 + len < IEEE80211_MIN_ACTION_SIZE(ml_reconf_resp) || 10430 + mgmt->u.action.ml_reconf_resp.dialog_token != 10431 + sdata->u.mgd.reconf.dialog_token || 10455 10432 !sta_changed_links) 10456 10433 return; 10457 10434 10458 - pos = mgmt->u.action.u.ml_reconf_resp.variable; 10459 - len -= offsetofend(typeof(*mgmt), u.action.u.ml_reconf_resp); 10435 + pos = mgmt->u.action.ml_reconf_resp.variable; 10436 + len -= offsetofend(typeof(*mgmt), u.action.ml_reconf_resp); 10460 10437 10461 10438 /* each status duple is 3 octets */ 10462 - if (len < mgmt->u.action.u.ml_reconf_resp.count * 3) { 10439 + if (len < mgmt->u.action.ml_reconf_resp.count * 3) { 10463 10440 sdata_info(sdata, 10464 10441 "mlo: reconf: unexpected len=%zu, count=%u\n", 10465 - len, mgmt->u.action.u.ml_reconf_resp.count); 10442 + len, mgmt->u.action.ml_reconf_resp.count); 10466 10443 goto disconnect; 10467 10444 } 10468 10445 10469 10446 link_mask = sta_changed_links; 10470 - for (i = 0; i < mgmt->u.action.u.ml_reconf_resp.count; i++) { 10447 + for (i = 0; i < mgmt->u.action.ml_reconf_resp.count; i++) { 10471 10448 u16 status = get_unaligned_le16(pos + 1); 10472 10449 10473 10450 link_id = *pos; ··· 10752 10729 return NULL; 10753 10730 10754 10731 skb_reserve(skb, local->hw.extra_tx_headroom); 10755 - mgmt = skb_put_zero(skb, offsetofend(struct ieee80211_mgmt, 10756 - u.action.u.ml_reconf_req)); 10732 + mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(ml_reconf_req)); 10757 10733 10758 10734 /* Add the MAC header */ 10759 10735 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | ··· 10763 10741 10764 10742 /* Add the action frame fixed fields */ 10765 10743 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 10766 - mgmt->u.action.u.ml_reconf_req.action_code = 10767 - WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_REQ; 10744 + mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_REQ; 10768 10745 10769 10746 /* allocate a dialog token and store it */ 10770 10747 sdata->u.mgd.reconf.dialog_token = ++sdata->u.mgd.dialog_token_alloc; 10771 - mgmt->u.action.u.ml_reconf_req.dialog_token = 10748 + mgmt->u.action.ml_reconf_req.dialog_token = 10772 10749 sdata->u.mgd.reconf.dialog_token; 10773 10750 10774 10751 /* Add the ML reconfiguration element and the common information */ ··· 11137 11116 11138 11117 int ieee80211_mgd_set_epcs(struct ieee80211_sub_if_data *sdata, bool enable) 11139 11118 { 11119 + int frame_len = IEEE80211_MIN_ACTION_SIZE(epcs) + (enable ? 1 : 0); 11140 11120 struct ieee80211_local *local = sdata->local; 11141 11121 struct ieee80211_mgmt *mgmt; 11142 11122 struct sk_buff *skb; 11143 - int frame_len = offsetofend(struct ieee80211_mgmt, 11144 - u.action.u.epcs) + (enable ? 1 : 0); 11145 11123 11146 11124 if (!ieee80211_mgd_epcs_supp(sdata)) 11147 11125 return -EINVAL; ··· 11169 11149 11170 11150 mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT; 11171 11151 if (enable) { 11172 - u8 *pos = mgmt->u.action.u.epcs.variable; 11152 + u8 *pos = mgmt->u.action.epcs.variable; 11173 11153 11174 - mgmt->u.action.u.epcs.action_code = 11154 + mgmt->u.action.action_code = 11175 11155 WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_REQ; 11176 11156 11177 11157 *pos = ++sdata->u.mgd.dialog_token_alloc; 11178 11158 sdata->u.mgd.epcs.dialog_token = *pos; 11179 11159 } else { 11180 - mgmt->u.action.u.epcs.action_code = 11160 + mgmt->u.action.action_code = 11181 11161 WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_TEARDOWN; 11182 11162 11183 11163 ieee80211_epcs_teardown(sdata); ··· 11266 11246 return; 11267 11247 11268 11248 /* Handle dialog token and status code */ 11269 - pos = mgmt->u.action.u.epcs.variable; 11249 + pos = mgmt->u.action.epcs.variable; 11270 11250 dialog_token = *pos; 11271 11251 status_code = get_unaligned_le16(pos + 1); 11272 11252 ··· 11288 11268 return; 11289 11269 11290 11270 pos += IEEE80211_EPCS_ENA_RESP_BODY_LEN; 11291 - ies_len = len - offsetof(struct ieee80211_mgmt, 11292 - u.action.u.epcs.variable) - 11271 + ies_len = len - IEEE80211_MIN_ACTION_SIZE(epcs) - 11293 11272 IEEE80211_EPCS_ENA_RESP_BODY_LEN; 11294 11273 11295 11274 elems = ieee802_11_parse_elems(pos, ies_len,
+60 -74
net/mac80211/rx.c
··· 274 274 if (!sdata) 275 275 return; 276 276 277 - BUILD_BUG_ON(sizeof(action) != IEEE80211_MIN_ACTION_SIZE + 1); 277 + BUILD_BUG_ON(sizeof(action) != IEEE80211_MIN_ACTION_SIZE(action_code)); 278 278 279 279 if (skb->len < rtap_space + sizeof(action) + 280 280 VHT_MUMIMO_GROUPS_DATA_LEN) ··· 1162 1162 u8 category; 1163 1163 1164 1164 /* make sure category field is present */ 1165 - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) 1165 + if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 1166 1166 return RX_DROP_U_RUNT_ACTION; 1167 1167 1168 1168 mgmt = (struct ieee80211_mgmt *)hdr; ··· 1475 1475 !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg)) 1476 1476 ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid, 1477 1477 WLAN_BACK_RECIPIENT, 1478 - WLAN_REASON_QSTA_REQUIRE_SETUP); 1478 + WLAN_REASON_QSTA_REQUIRE_SETUP, 1479 + ieee80211_s1g_use_ndp_ba(rx->sdata, 1480 + rx->sta)); 1479 1481 goto dont_reorder; 1480 1482 } 1481 1483 ··· 3374 3372 !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg)) 3375 3373 ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid, 3376 3374 WLAN_BACK_RECIPIENT, 3377 - WLAN_REASON_QSTA_REQUIRE_SETUP); 3375 + WLAN_REASON_QSTA_REQUIRE_SETUP, 3376 + ieee80211_s1g_use_ndp_ba(rx->sdata, 3377 + rx->sta)); 3378 3378 3379 3379 tid_agg_rx = rcu_dereference(rx->sta->ampdu_mlme.tid_rx[tid]); 3380 3380 if (!tid_agg_rx) ··· 3426 3422 return; 3427 3423 } 3428 3424 3429 - if (len < 24 + 1 + sizeof(resp->u.action.u.sa_query)) { 3425 + if (len < IEEE80211_MIN_ACTION_SIZE(sa_query)) { 3430 3426 /* Too short SA Query request frame */ 3431 3427 return; 3432 3428 } ··· 3436 3432 return; 3437 3433 3438 3434 skb_reserve(skb, local->hw.extra_tx_headroom); 3439 - resp = skb_put_zero(skb, 24); 3435 + resp = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(sa_query)); 3440 3436 memcpy(resp->da, sdata->vif.cfg.ap_addr, ETH_ALEN); 3441 3437 memcpy(resp->sa, sdata->vif.addr, ETH_ALEN); 3442 3438 memcpy(resp->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN); 3443 3439 resp->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 3444 3440 IEEE80211_STYPE_ACTION); 3445 - skb_put(skb, 1 + sizeof(resp->u.action.u.sa_query)); 3446 3441 resp->u.action.category = WLAN_CATEGORY_SA_QUERY; 3447 - resp->u.action.u.sa_query.action = WLAN_ACTION_SA_QUERY_RESPONSE; 3448 - memcpy(resp->u.action.u.sa_query.trans_id, 3449 - mgmt->u.action.u.sa_query.trans_id, 3442 + resp->u.action.action_code = WLAN_ACTION_SA_QUERY_RESPONSE; 3443 + memcpy(resp->u.action.sa_query.trans_id, 3444 + mgmt->u.action.sa_query.trans_id, 3450 3445 WLAN_SA_QUERY_TR_ID_LEN); 3451 3446 3452 3447 ieee80211_tx_skb(sdata, skb); ··· 3519 3516 3520 3517 /* drop too small action frames */ 3521 3518 if (ieee80211_is_action(mgmt->frame_control) && 3522 - rx->skb->len < IEEE80211_MIN_ACTION_SIZE) 3519 + rx->skb->len < IEEE80211_MIN_ACTION_SIZE(category)) 3523 3520 return RX_DROP_U_RUNT_ACTION; 3524 3521 3525 3522 /* Drop non-broadcast Beacon frames */ ··· 3568 3565 if (!rx->sta) 3569 3566 return false; 3570 3567 3571 - switch (mgmt->u.action.u.s1g.action_code) { 3568 + switch (mgmt->u.action.action_code) { 3572 3569 case WLAN_S1G_TWT_SETUP: { 3573 3570 struct ieee80211_twt_setup *twt; 3574 3571 3575 - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 3576 - 1 + /* action code */ 3572 + if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(action_code) + 3577 3573 sizeof(struct ieee80211_twt_setup) + 3578 3574 2 /* TWT req_type agrt */) 3579 3575 break; 3580 3576 3581 - twt = (void *)mgmt->u.action.u.s1g.variable; 3577 + twt = (void *)mgmt->u.action.s1g.variable; 3582 3578 if (twt->element_id != WLAN_EID_S1G_TWT) 3583 3579 break; 3584 3580 3585 - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 3586 - 4 + /* action code + token + tlv */ 3581 + if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(action_code) + 3582 + 3 + /* token + tlv */ 3587 3583 twt->length) 3588 3584 break; 3589 3585 3590 3586 return true; /* queue the frame */ 3591 3587 } 3592 3588 case WLAN_S1G_TWT_TEARDOWN: 3593 - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 2) 3589 + if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(action_code) + 1) 3594 3590 break; 3595 3591 3596 3592 return true; /* queue the frame */ ··· 3634 3632 break; 3635 3633 3636 3634 /* verify action & smps_control/chanwidth are present */ 3637 - if (len < IEEE80211_MIN_ACTION_SIZE + 2) 3635 + if (len < IEEE80211_MIN_ACTION_SIZE(ht_smps)) 3638 3636 goto invalid; 3639 3637 3640 - switch (mgmt->u.action.u.ht_smps.action) { 3638 + switch (mgmt->u.action.action_code) { 3641 3639 case WLAN_HT_ACTION_SMPS: { 3642 3640 struct ieee80211_supported_band *sband; 3643 3641 enum ieee80211_smps_mode smps_mode; ··· 3648 3646 goto handled; 3649 3647 3650 3648 /* convert to HT capability */ 3651 - switch (mgmt->u.action.u.ht_smps.smps_control) { 3649 + switch (mgmt->u.action.ht_smps.smps_control) { 3652 3650 case WLAN_HT_SMPS_CONTROL_DISABLED: 3653 3651 smps_mode = IEEE80211_SMPS_OFF; 3654 3652 break; ··· 3681 3679 goto handled; 3682 3680 } 3683 3681 case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { 3684 - u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth; 3682 + u8 chanwidth = mgmt->u.action.ht_notify_cw.chanwidth; 3685 3683 3686 3684 if (chanwidth != IEEE80211_HT_CHANWIDTH_20MHZ && 3687 3685 chanwidth != IEEE80211_HT_CHANWIDTH_ANY) ··· 3701 3699 break; 3702 3700 case WLAN_CATEGORY_PUBLIC: 3703 3701 case WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION: 3704 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 3702 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3705 3703 goto invalid; 3706 3704 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3707 3705 break; ··· 3709 3707 break; 3710 3708 if (!ether_addr_equal(mgmt->bssid, sdata->deflink.u.mgd.bssid)) 3711 3709 break; 3712 - if (mgmt->u.action.u.ext_chan_switch.action_code != 3710 + if (mgmt->u.action.action_code != 3713 3711 WLAN_PUB_ACTION_EXT_CHANSW_ANN) 3714 3712 break; 3715 - if (len < offsetof(struct ieee80211_mgmt, 3716 - u.action.u.ext_chan_switch.variable)) 3713 + if (len < IEEE80211_MIN_ACTION_SIZE(ext_chan_switch)) 3717 3714 goto invalid; 3718 3715 goto queue; 3719 3716 case WLAN_CATEGORY_VHT: ··· 3724 3723 break; 3725 3724 3726 3725 /* verify action code is present */ 3727 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 3726 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3728 3727 goto invalid; 3729 3728 3730 - switch (mgmt->u.action.u.vht_opmode_notif.action_code) { 3729 + switch (mgmt->u.action.action_code) { 3731 3730 case WLAN_VHT_ACTION_OPMODE_NOTIF: { 3732 3731 /* verify opmode is present */ 3733 - if (len < IEEE80211_MIN_ACTION_SIZE + 2) 3732 + if (len < IEEE80211_MIN_ACTION_SIZE(vht_opmode_notif)) 3734 3733 goto invalid; 3735 3734 goto queue; 3736 3735 } 3737 3736 case WLAN_VHT_ACTION_GROUPID_MGMT: { 3738 - if (len < IEEE80211_MIN_ACTION_SIZE + 25) 3737 + if (len < IEEE80211_MIN_ACTION_SIZE(vht_group_notif)) 3739 3738 goto invalid; 3740 3739 goto queue; 3741 3740 } ··· 3752 3751 break; 3753 3752 3754 3753 /* verify action_code is present */ 3755 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 3754 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3756 3755 break; 3757 3756 3758 - switch (mgmt->u.action.u.addba_req.action_code) { 3757 + switch (mgmt->u.action.action_code) { 3759 3758 case WLAN_ACTION_ADDBA_REQ: 3760 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3761 - sizeof(mgmt->u.action.u.addba_req))) 3759 + case WLAN_ACTION_NDP_ADDBA_REQ: 3760 + if (len < IEEE80211_MIN_ACTION_SIZE(addba_req)) 3762 3761 goto invalid; 3763 3762 break; 3764 3763 case WLAN_ACTION_ADDBA_RESP: 3765 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3766 - sizeof(mgmt->u.action.u.addba_resp))) 3764 + case WLAN_ACTION_NDP_ADDBA_RESP: 3765 + if (len < IEEE80211_MIN_ACTION_SIZE(addba_resp)) 3767 3766 goto invalid; 3768 3767 break; 3769 3768 case WLAN_ACTION_DELBA: 3770 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3771 - sizeof(mgmt->u.action.u.delba))) 3769 + case WLAN_ACTION_NDP_DELBA: 3770 + if (len < IEEE80211_MIN_ACTION_SIZE(delba)) 3772 3771 goto invalid; 3773 3772 break; 3774 3773 default: ··· 3778 3777 goto queue; 3779 3778 case WLAN_CATEGORY_SPECTRUM_MGMT: 3780 3779 /* verify action_code is present */ 3781 - if (len < IEEE80211_MIN_ACTION_SIZE + 1) 3780 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3782 3781 break; 3783 3782 3784 - switch (mgmt->u.action.u.measurement.action_code) { 3783 + switch (mgmt->u.action.action_code) { 3785 3784 case WLAN_ACTION_SPCT_MSR_REQ: 3786 3785 if (status->band != NL80211_BAND_5GHZ) 3787 3786 break; 3788 3787 3789 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3790 - sizeof(mgmt->u.action.u.measurement))) 3788 + if (len < IEEE80211_MIN_ACTION_SIZE(measurement)) 3791 3789 break; 3792 3790 3793 3791 if (sdata->vif.type != NL80211_IFTYPE_STATION) ··· 3796 3796 goto handled; 3797 3797 case WLAN_ACTION_SPCT_CHL_SWITCH: { 3798 3798 u8 *bssid; 3799 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3800 - sizeof(mgmt->u.action.u.chan_switch))) 3799 + if (len < IEEE80211_MIN_ACTION_SIZE(chan_switch)) 3801 3800 break; 3802 3801 3803 3802 if (sdata->vif.type != NL80211_IFTYPE_STATION && ··· 3821 3822 } 3822 3823 break; 3823 3824 case WLAN_CATEGORY_SELF_PROTECTED: 3824 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3825 - sizeof(mgmt->u.action.u.self_prot.action_code))) 3825 + if (len < IEEE80211_MIN_ACTION_SIZE(self_prot)) 3826 3826 break; 3827 3827 3828 - switch (mgmt->u.action.u.self_prot.action_code) { 3828 + switch (mgmt->u.action.action_code) { 3829 3829 case WLAN_SP_MESH_PEERING_OPEN: 3830 3830 case WLAN_SP_MESH_PEERING_CLOSE: 3831 3831 case WLAN_SP_MESH_PEERING_CONFIRM: ··· 3842 3844 } 3843 3845 break; 3844 3846 case WLAN_CATEGORY_MESH_ACTION: 3845 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3846 - sizeof(mgmt->u.action.u.mesh_action.action_code))) 3847 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3847 3848 break; 3848 3849 3849 3850 if (!ieee80211_vif_is_mesh(&sdata->vif)) ··· 3852 3855 break; 3853 3856 goto queue; 3854 3857 case WLAN_CATEGORY_S1G: 3855 - if (len < offsetofend(typeof(*mgmt), 3856 - u.action.u.s1g.action_code)) 3858 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3857 3859 break; 3858 3860 3859 - switch (mgmt->u.action.u.s1g.action_code) { 3861 + switch (mgmt->u.action.action_code) { 3860 3862 case WLAN_S1G_TWT_SETUP: 3861 3863 case WLAN_S1G_TWT_TEARDOWN: 3862 3864 if (ieee80211_process_rx_twt_action(rx)) ··· 3866 3870 } 3867 3871 break; 3868 3872 case WLAN_CATEGORY_PROTECTED_EHT: 3869 - if (len < offsetofend(typeof(*mgmt), 3870 - u.action.u.ttlm_req.action_code)) 3873 + if (len < IEEE80211_MIN_ACTION_SIZE(action_code)) 3871 3874 break; 3872 3875 3873 - switch (mgmt->u.action.u.ttlm_req.action_code) { 3876 + switch (mgmt->u.action.action_code) { 3874 3877 case WLAN_PROTECTED_EHT_ACTION_TTLM_REQ: 3875 3878 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3876 3879 break; 3877 3880 3878 - if (len < offsetofend(typeof(*mgmt), 3879 - u.action.u.ttlm_req)) 3881 + if (len < IEEE80211_MIN_ACTION_SIZE(ttlm_req)) 3880 3882 goto invalid; 3881 3883 goto queue; 3882 3884 case WLAN_PROTECTED_EHT_ACTION_TTLM_RES: 3883 3885 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3884 3886 break; 3885 3887 3886 - if (len < offsetofend(typeof(*mgmt), 3887 - u.action.u.ttlm_res)) 3888 + if (len < IEEE80211_MIN_ACTION_SIZE(ttlm_res)) 3888 3889 goto invalid; 3889 3890 goto queue; 3890 3891 case WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN: 3891 3892 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3892 3893 break; 3893 3894 3894 - if (len < offsetofend(typeof(*mgmt), 3895 - u.action.u.ttlm_tear_down)) 3895 + if (len < IEEE80211_MIN_ACTION_SIZE(ttlm_tear_down)) 3896 3896 goto invalid; 3897 3897 goto queue; 3898 3898 case WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_RESP: ··· 3898 3906 /* The reconfiguration response action frame must 3899 3907 * least one 'Status Duple' entry (3 octets) 3900 3908 */ 3901 - if (len < 3902 - offsetofend(typeof(*mgmt), 3903 - u.action.u.ml_reconf_resp) + 3) 3909 + if (len < IEEE80211_MIN_ACTION_SIZE(ml_reconf_resp) + 3) 3904 3910 goto invalid; 3905 3911 goto queue; 3906 3912 case WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_RESP: 3907 3913 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3908 3914 break; 3909 3915 3910 - if (len < offsetofend(typeof(*mgmt), 3911 - u.action.u.epcs) + 3912 - IEEE80211_EPCS_ENA_RESP_BODY_LEN) 3916 + if (len < IEEE80211_MIN_ACTION_SIZE(epcs) + 3917 + IEEE80211_EPCS_ENA_RESP_BODY_LEN) 3913 3918 goto invalid; 3914 3919 goto queue; 3915 3920 case WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_TEARDOWN: 3916 3921 if (sdata->vif.type != NL80211_IFTYPE_STATION) 3917 3922 break; 3918 3923 3919 - if (len < offsetofend(typeof(*mgmt), 3920 - u.action.u.epcs)) 3924 + if (len < IEEE80211_MIN_ACTION_SIZE(epcs)) 3921 3925 goto invalid; 3922 3926 goto queue; 3923 3927 case WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF: 3924 3928 if (sdata->vif.type != NL80211_IFTYPE_AP) 3925 3929 break; 3926 3930 3927 - if (len < offsetofend(typeof(*mgmt), 3928 - u.action.u.eml_omn)) 3931 + if (len < IEEE80211_MIN_ACTION_SIZE(eml_omn)) 3929 3932 goto invalid; 3930 3933 goto queue; 3931 3934 default: ··· 4002 4015 4003 4016 switch (mgmt->u.action.category) { 4004 4017 case WLAN_CATEGORY_SA_QUERY: 4005 - if (len < (IEEE80211_MIN_ACTION_SIZE + 4006 - sizeof(mgmt->u.action.u.sa_query))) 4018 + if (len < IEEE80211_MIN_ACTION_SIZE(sa_query)) 4007 4019 break; 4008 4020 4009 - switch (mgmt->u.action.u.sa_query.action) { 4021 + switch (mgmt->u.action.action_code) { 4010 4022 case WLAN_ACTION_SA_QUERY_REQUEST: 4011 4023 if (sdata->vif.type != NL80211_IFTYPE_STATION) 4012 4024 break;
+22 -14
net/mac80211/s1g.c
··· 2 2 /* 3 3 * S1G handling 4 4 * Copyright(c) 2020 Adapt-IP 5 - * Copyright (C) 2023 Intel Corporation 5 + * Copyright (C) 2023, 2026 Intel Corporation 6 6 */ 7 7 #include <linux/ieee80211.h> 8 8 #include <net/mac80211.h> ··· 27 27 if (likely(mgmt->u.action.category != WLAN_CATEGORY_S1G)) 28 28 return false; 29 29 30 - return mgmt->u.action.u.s1g.action_code == WLAN_S1G_TWT_SETUP; 30 + return mgmt->u.action.action_code == WLAN_S1G_TWT_SETUP; 31 31 } 32 32 33 33 static void 34 34 ieee80211_s1g_send_twt_setup(struct ieee80211_sub_if_data *sdata, const u8 *da, 35 35 const u8 *bssid, struct ieee80211_twt_setup *twt) 36 36 { 37 - int len = IEEE80211_MIN_ACTION_SIZE + 4 + twt->length; 37 + int len = IEEE80211_MIN_ACTION_SIZE(s1g) + 3 + twt->length; 38 38 struct ieee80211_local *local = sdata->local; 39 39 struct ieee80211_mgmt *mgmt; 40 40 struct sk_buff *skb; ··· 52 52 memcpy(mgmt->bssid, bssid, ETH_ALEN); 53 53 54 54 mgmt->u.action.category = WLAN_CATEGORY_S1G; 55 - mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_SETUP; 56 - memcpy(mgmt->u.action.u.s1g.variable, twt, 3 + twt->length); 55 + mgmt->u.action.action_code = WLAN_S1G_TWT_SETUP; 56 + memcpy(mgmt->u.action.s1g.variable, twt, 3 + twt->length); 57 57 58 58 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | 59 59 IEEE80211_TX_INTFL_MLME_CONN_TX | ··· 71 71 u8 *id; 72 72 73 73 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 74 - IEEE80211_MIN_ACTION_SIZE + 2); 74 + IEEE80211_MIN_ACTION_SIZE(s1g) + 1); 75 75 if (!skb) 76 76 return; 77 77 78 78 skb_reserve(skb, local->hw.extra_tx_headroom); 79 - mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE + 2); 79 + mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(s1g) + 1); 80 80 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 81 81 IEEE80211_STYPE_ACTION); 82 82 memcpy(mgmt->da, da, ETH_ALEN); ··· 84 84 memcpy(mgmt->bssid, bssid, ETH_ALEN); 85 85 86 86 mgmt->u.action.category = WLAN_CATEGORY_S1G; 87 - mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_TEARDOWN; 88 - id = (u8 *)mgmt->u.action.u.s1g.variable; 87 + mgmt->u.action.action_code = WLAN_S1G_TWT_TEARDOWN; 88 + id = (u8 *)mgmt->u.action.s1g.variable; 89 89 *id = flowid; 90 90 91 91 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | ··· 98 98 struct sta_info *sta, struct sk_buff *skb) 99 99 { 100 100 struct ieee80211_mgmt *mgmt = (void *)skb->data; 101 - struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable; 101 + struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.s1g.variable; 102 102 struct ieee80211_twt_params *twt_agrt = (void *)twt->params; 103 103 104 104 twt_agrt->req_type &= cpu_to_le16(~IEEE80211_TWT_REQTYPE_REQUEST); ··· 128 128 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 129 129 130 130 drv_twt_teardown_request(sdata->local, sdata, &sta->sta, 131 - mgmt->u.action.u.s1g.variable[0]); 131 + mgmt->u.action.s1g.variable[0]); 132 132 } 133 133 134 134 static void ··· 136 136 struct sta_info *sta, struct sk_buff *skb) 137 137 { 138 138 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 139 - struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable; 139 + struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.s1g.variable; 140 140 struct ieee80211_twt_params *twt_agrt = (void *)twt->params; 141 141 u8 flowid = le16_get_bits(twt_agrt->req_type, 142 142 IEEE80211_TWT_REQTYPE_FLOWID); ··· 160 160 if (!sta) 161 161 return; 162 162 163 - switch (mgmt->u.action.u.s1g.action_code) { 163 + switch (mgmt->u.action.action_code) { 164 164 case WLAN_S1G_TWT_SETUP: 165 165 ieee80211_s1g_rx_twt_setup(sdata, sta, skb); 166 166 break; ··· 185 185 if (!sta) 186 186 return; 187 187 188 - switch (mgmt->u.action.u.s1g.action_code) { 188 + switch (mgmt->u.action.action_code) { 189 189 case WLAN_S1G_TWT_SETUP: 190 190 /* process failed twt setup frames */ 191 191 ieee80211_s1g_tx_twt_setup_fail(sdata, sta, skb); ··· 219 219 } 220 220 221 221 ieee80211_sta_recalc_aggregates(&link_sta->sta->sta); 222 + } 223 + 224 + bool ieee80211_s1g_use_ndp_ba(const struct ieee80211_sub_if_data *sdata, 225 + const struct sta_info *sta) 226 + { 227 + return sdata->vif.cfg.s1g && 228 + ieee80211_hw_check(&sdata->local->hw, SUPPORTS_NDP_BLOCKACK) && 229 + (sta && sta->sta.deflink.s1g_cap.s1g); 222 230 }
+13 -18
net/mac80211/spectmgmt.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2007-2008, Intel Corporation 11 11 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> 12 - * Copyright (C) 2018, 2020, 2022-2024 Intel Corporation 12 + * Copyright (C) 2018, 2020, 2022-2024, 2026 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/ieee80211.h> ··· 409 409 struct sk_buff *skb; 410 410 struct ieee80211_mgmt *msr_report; 411 411 412 - skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom + 413 - sizeof(struct ieee80211_msrment_ie)); 412 + skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(measurement) + 413 + local->hw.extra_tx_headroom); 414 414 if (!skb) 415 415 return; 416 416 417 417 skb_reserve(skb, local->hw.extra_tx_headroom); 418 - msr_report = skb_put_zero(skb, 24); 418 + msr_report = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(measurement)); 419 419 memcpy(msr_report->da, da, ETH_ALEN); 420 420 memcpy(msr_report->sa, sdata->vif.addr, ETH_ALEN); 421 421 memcpy(msr_report->bssid, bssid, ETH_ALEN); 422 422 msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 423 423 IEEE80211_STYPE_ACTION); 424 424 425 - skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement)); 426 425 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; 427 - msr_report->u.action.u.measurement.action_code = 428 - WLAN_ACTION_SPCT_MSR_RPRT; 429 - msr_report->u.action.u.measurement.dialog_token = dialog_token; 426 + msr_report->u.action.action_code = WLAN_ACTION_SPCT_MSR_RPRT; 430 427 431 - msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT; 432 - msr_report->u.action.u.measurement.length = 428 + msr_report->u.action.measurement.dialog_token = dialog_token; 429 + msr_report->u.action.measurement.element_id = WLAN_EID_MEASURE_REPORT; 430 + msr_report->u.action.measurement.length = 433 431 sizeof(struct ieee80211_msrment_ie); 434 - 435 - memset(&msr_report->u.action.u.measurement.msr_elem, 0, 436 - sizeof(struct ieee80211_msrment_ie)); 437 - msr_report->u.action.u.measurement.msr_elem.token = request_ie->token; 438 - msr_report->u.action.u.measurement.msr_elem.mode |= 432 + msr_report->u.action.measurement.msr_elem.token = request_ie->token; 433 + msr_report->u.action.measurement.msr_elem.mode |= 439 434 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED; 440 - msr_report->u.action.u.measurement.msr_elem.type = request_ie->type; 435 + msr_report->u.action.measurement.msr_elem.type = request_ie->type; 441 436 442 437 ieee80211_tx_skb(sdata, skb); 443 438 } ··· 449 454 * TODO: Answer basic measurement as unmeasured 450 455 */ 451 456 ieee80211_send_refuse_measurement_request(sdata, 452 - &mgmt->u.action.u.measurement.msr_elem, 457 + &mgmt->u.action.measurement.msr_elem, 453 458 mgmt->sa, mgmt->bssid, 454 - mgmt->u.action.u.measurement.dialog_token); 459 + mgmt->u.action.measurement.dialog_token); 455 460 }
+2 -1
net/mac80211/sta_info.h
··· 171 171 * @bar_pending: BAR needs to be re-sent 172 172 * @amsdu: support A-MSDU within A-MDPU 173 173 * @ssn: starting sequence number of the session 174 + * @ndp: this session is using NDP Block ACKs 174 175 * 175 176 * This structure's lifetime is managed by RCU, assignments to 176 177 * the array holding it must hold the aggregation mutex. ··· 200 199 u16 failed_bar_ssn; 201 200 bool bar_pending; 202 201 bool amsdu; 202 + bool ndp; 203 203 u8 tid; 204 204 }; 205 205 ··· 512 510 * during finalize 513 511 * @debugfs_dir: debug filesystem directory dentry 514 512 * @pub: public (driver visible) link STA data 515 - * TODO Move other link params from sta_info as required for MLD operation 516 513 */ 517 514 struct link_sta_info { 518 515 u8 addr[ETH_ALEN];
+12 -17
net/mac80211/tdls.c
··· 6 6 * Copyright 2014, Intel Corporation 7 7 * Copyright 2014 Intel Mobile Communications GmbH 8 8 * Copyright 2015 - 2016 Intel Deutschland GmbH 9 - * Copyright (C) 2019, 2021-2025 Intel Corporation 9 + * Copyright (C) 2019, 2021-2026 Intel Corporation 10 10 */ 11 11 12 12 #include <linux/ieee80211.h> ··· 879 879 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 880 880 struct ieee80211_mgmt *mgmt; 881 881 882 - mgmt = skb_put_zero(skb, 24); 882 + if (action_code != WLAN_PUB_ACTION_TDLS_DISCOVER_RES) 883 + return -EINVAL; 884 + 885 + mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(tdls_discover_resp)); 883 886 memcpy(mgmt->da, peer, ETH_ALEN); 884 887 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 885 888 memcpy(mgmt->bssid, link->u.mgd.bssid, ETH_ALEN); 886 889 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 887 890 IEEE80211_STYPE_ACTION); 888 891 889 - switch (action_code) { 890 - case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 891 - skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); 892 - mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; 893 - mgmt->u.action.u.tdls_discover_resp.action_code = 894 - WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 895 - mgmt->u.action.u.tdls_discover_resp.dialog_token = 896 - dialog_token; 897 - mgmt->u.action.u.tdls_discover_resp.capability = 898 - cpu_to_le16(ieee80211_get_tdls_sta_capab(link, 899 - status_code)); 900 - break; 901 - default: 902 - return -EINVAL; 903 - } 892 + mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; 893 + mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES; 894 + 895 + mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token; 896 + mgmt->u.action.tdls_discover_resp.capability = 897 + cpu_to_le16(ieee80211_get_tdls_sta_capab(link, 898 + status_code)); 904 899 905 900 return 0; 906 901 }
+38 -56
net/mac80211/trace.h
··· 2 2 /* 3 3 * Portions of this file 4 4 * Copyright(c) 2016-2017 Intel Deutschland GmbH 5 - * Copyright (C) 2018 - 2024 Intel Corporation 5 + * Copyright (C) 2018-2024, 2026 Intel Corporation 6 6 */ 7 7 8 8 #if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ) ··· 37 37 #define VIF_PR_FMT " vif:%s(%d%s)" 38 38 #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" 39 39 40 - #define CHANDEF_ENTRY __field(u32, control_freq) \ 41 - __field(u32, freq_offset) \ 42 - __field(u32, chan_width) \ 43 - __field(u32, center_freq1) \ 44 - __field(u32, freq1_offset) \ 45 - __field(u32, center_freq2) 46 - #define CHANDEF_ASSIGN(c) \ 47 - __entry->control_freq = (c) ? ((c)->chan ? (c)->chan->center_freq : 0) : 0; \ 48 - __entry->freq_offset = (c) ? ((c)->chan ? (c)->chan->freq_offset : 0) : 0; \ 49 - __entry->chan_width = (c) ? (c)->width : 0; \ 50 - __entry->center_freq1 = (c) ? (c)->center_freq1 : 0; \ 51 - __entry->freq1_offset = (c) ? (c)->freq1_offset : 0; \ 52 - __entry->center_freq2 = (c) ? (c)->center_freq2 : 0; 53 - #define CHANDEF_PR_FMT " chandef(%d.%03d MHz,width:%d,center: %d.%03d/%d MHz)" 54 - #define CHANDEF_PR_ARG __entry->control_freq, __entry->freq_offset, __entry->chan_width, \ 55 - __entry->center_freq1, __entry->freq1_offset, __entry->center_freq2 40 + #define __CHANDEF_ENTRY(n) \ 41 + __field(u32, n##control_freq) \ 42 + __field(u32, n##freq_offset) \ 43 + __field(u32, n##chan_width) \ 44 + __field(u32, n##center_freq1) \ 45 + __field(u32, n##freq1_offset) \ 46 + __field(u32, n##center_freq2) \ 47 + __field(u16, n##punctured) 48 + #define __CHANDEF_ASSIGN(n, c) \ 49 + __entry->n##control_freq = (c) && (c)->chan ? \ 50 + (c)->chan->center_freq : 0; \ 51 + __entry->n##freq_offset = (c) && (c)->chan ? \ 52 + (c)->chan->freq_offset : 0; \ 53 + __entry->n##chan_width = (c) ? (c)->width : 0; \ 54 + __entry->n##center_freq1 = (c) ? (c)->center_freq1 : 0; \ 55 + __entry->n##freq1_offset = (c) ? (c)->freq1_offset : 0; \ 56 + __entry->n##center_freq2 = (c) ? (c)->center_freq2 : 0; \ 57 + __entry->n##punctured = (c) ? (c)->punctured : 0; 58 + #define __CHANDEF_PR_FMT(n) \ 59 + " " #n "(%d.%03d MHz,width:%d,center: %d.%03d/%d MHz, punct:0x%x)" 60 + #define __CHANDEF_PR_ARG(n) \ 61 + __entry->n##control_freq, __entry->n##freq_offset, \ 62 + __entry->n##chan_width, __entry->n##center_freq1, \ 63 + __entry->n##freq1_offset, __entry->n##center_freq2, \ 64 + __entry->n##punctured 56 65 57 - #define MIN_CHANDEF_ENTRY \ 58 - __field(u32, min_control_freq) \ 59 - __field(u32, min_freq_offset) \ 60 - __field(u32, min_chan_width) \ 61 - __field(u32, min_center_freq1) \ 62 - __field(u32, min_freq1_offset) \ 63 - __field(u32, min_center_freq2) 66 + #define CHANDEF_ENTRY __CHANDEF_ENTRY() 67 + #define CHANDEF_ASSIGN(c) __CHANDEF_ASSIGN(, c) 68 + #define CHANDEF_PR_FMT __CHANDEF_PR_FMT(chandef) 69 + #define CHANDEF_PR_ARG __CHANDEF_PR_ARG() 64 70 65 - #define MIN_CHANDEF_ASSIGN(c) \ 66 - __entry->min_control_freq = (c)->chan ? (c)->chan->center_freq : 0; \ 67 - __entry->min_freq_offset = (c)->chan ? (c)->chan->freq_offset : 0; \ 68 - __entry->min_chan_width = (c)->width; \ 69 - __entry->min_center_freq1 = (c)->center_freq1; \ 70 - __entry->min_freq1_offset = (c)->freq1_offset; \ 71 - __entry->min_center_freq2 = (c)->center_freq2; 72 - #define MIN_CHANDEF_PR_FMT " mindef(%d.%03d MHz,width:%d,center: %d.%03d/%d MHz)" 73 - #define MIN_CHANDEF_PR_ARG __entry->min_control_freq, __entry->min_freq_offset, \ 74 - __entry->min_chan_width, \ 75 - __entry->min_center_freq1, __entry->min_freq1_offset, \ 76 - __entry->min_center_freq2 71 + #define MIN_CHANDEF_ENTRY __CHANDEF_ENTRY(min) 72 + #define MIN_CHANDEF_ASSIGN(c) __CHANDEF_ASSIGN(min, c) 73 + #define MIN_CHANDEF_PR_FMT __CHANDEF_PR_FMT(mindef) 74 + #define MIN_CHANDEF_PR_ARG __CHANDEF_PR_ARG(min) 77 75 78 - #define AP_CHANDEF_ENTRY \ 79 - __field(u32, ap_control_freq) \ 80 - __field(u32, ap_freq_offset) \ 81 - __field(u32, ap_chan_width) \ 82 - __field(u32, ap_center_freq1) \ 83 - __field(u32, ap_freq1_offset) \ 84 - __field(u32, ap_center_freq2) 85 - 86 - #define AP_CHANDEF_ASSIGN(c) \ 87 - __entry->ap_control_freq = (c)->chan ? (c)->chan->center_freq : 0;\ 88 - __entry->ap_freq_offset = (c)->chan ? (c)->chan->freq_offset : 0;\ 89 - __entry->ap_chan_width = (c)->chan ? (c)->width : 0; \ 90 - __entry->ap_center_freq1 = (c)->chan ? (c)->center_freq1 : 0; \ 91 - __entry->ap_freq1_offset = (c)->chan ? (c)->freq1_offset : 0; \ 92 - __entry->ap_center_freq2 = (c)->chan ? (c)->center_freq2 : 0; 93 - #define AP_CHANDEF_PR_FMT " ap(%d.%03d MHz,width:%d,center: %d.%03d/%d MHz)" 94 - #define AP_CHANDEF_PR_ARG __entry->ap_control_freq, __entry->ap_freq_offset, \ 95 - __entry->ap_chan_width, \ 96 - __entry->ap_center_freq1, __entry->ap_freq1_offset, \ 97 - __entry->ap_center_freq2 76 + #define AP_CHANDEF_ENTRY __CHANDEF_ENTRY(ap) 77 + #define AP_CHANDEF_ASSIGN(c) __CHANDEF_ASSIGN(ap, c) 78 + #define AP_CHANDEF_PR_FMT __CHANDEF_PR_FMT(ap) 79 + #define AP_CHANDEF_PR_ARG __CHANDEF_PR_ARG(ap) 98 80 99 81 #define CHANCTX_ENTRY CHANDEF_ENTRY \ 100 82 MIN_CHANDEF_ENTRY \
+2 -3
net/mac80211/util.c
··· 3766 3766 int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, 3767 3767 struct cfg80211_csa_settings *csa_settings) 3768 3768 { 3769 + int hdr_len = IEEE80211_MIN_ACTION_SIZE(chan_switch); 3769 3770 struct sk_buff *skb; 3770 3771 struct ieee80211_mgmt *mgmt; 3771 3772 struct ieee80211_local *local = sdata->local; 3772 3773 int freq; 3773 - int hdr_len = offsetofend(struct ieee80211_mgmt, 3774 - u.action.u.chan_switch); 3775 3774 u8 *pos; 3776 3775 3777 3776 if (sdata->vif.type != NL80211_IFTYPE_ADHOC && ··· 3799 3800 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); 3800 3801 } 3801 3802 mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; 3802 - mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH; 3803 + mgmt->u.action.action_code = WLAN_ACTION_SPCT_CHL_SWITCH; 3803 3804 pos = skb_put(skb, 5); 3804 3805 *pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */ 3805 3806 *pos++ = 3; /* IE length */
+5 -5
net/mac80211/vht.c
··· 4 4 * 5 5 * Portions of this file 6 6 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH 7 - * Copyright (C) 2018 - 2024 Intel Corporation 7 + * Copyright (C) 2018-2026 Intel Corporation 8 8 */ 9 9 10 10 #include <linux/ieee80211.h> ··· 723 723 if (!link_conf->mu_mimo_owner) 724 724 return; 725 725 726 - if (!memcmp(mgmt->u.action.u.vht_group_notif.position, 726 + if (!memcmp(mgmt->u.action.vht_group_notif.position, 727 727 link_conf->mu_group.position, WLAN_USER_POSITION_LEN) && 728 - !memcmp(mgmt->u.action.u.vht_group_notif.membership, 728 + !memcmp(mgmt->u.action.vht_group_notif.membership, 729 729 link_conf->mu_group.membership, WLAN_MEMBERSHIP_LEN)) 730 730 return; 731 731 732 732 memcpy(link_conf->mu_group.membership, 733 - mgmt->u.action.u.vht_group_notif.membership, 733 + mgmt->u.action.vht_group_notif.membership, 734 734 WLAN_MEMBERSHIP_LEN); 735 735 memcpy(link_conf->mu_group.position, 736 - mgmt->u.action.u.vht_group_notif.position, 736 + mgmt->u.action.vht_group_notif.position, 737 737 WLAN_USER_POSITION_LEN); 738 738 739 739 ieee80211_link_info_change_notify(sdata, link,
+65 -45
net/wireless/chan.c
··· 6 6 * 7 7 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 8 8 * Copyright 2013-2014 Intel Mobile Communications GmbH 9 - * Copyright 2018-2025 Intel Corporation 9 + * Copyright 2018-2026 Intel Corporation 10 10 */ 11 11 12 12 #include <linux/export.h> ··· 29 29 30 30 *chandef = (struct cfg80211_chan_def) { 31 31 .chan = chan, 32 - .freq1_offset = chan->freq_offset, 33 32 }; 33 + 34 + WARN_ON(chan->band == NL80211_BAND_60GHZ || 35 + chan->band == NL80211_BAND_S1GHZ); 34 36 35 37 switch (chan_type) { 36 38 case NL80211_CHAN_NO_HT: ··· 341 339 return (center - bw / 2 - 5945) % step == 0; 342 340 } 343 341 342 + static bool 343 + cfg80211_chandef_valid_control_freq(const struct cfg80211_chan_def *chandef, 344 + u32 control_freq) 345 + { 346 + switch (chandef->width) { 347 + case NL80211_CHAN_WIDTH_5: 348 + case NL80211_CHAN_WIDTH_10: 349 + case NL80211_CHAN_WIDTH_20: 350 + case NL80211_CHAN_WIDTH_20_NOHT: 351 + case NL80211_CHAN_WIDTH_1: 352 + case NL80211_CHAN_WIDTH_2: 353 + case NL80211_CHAN_WIDTH_4: 354 + case NL80211_CHAN_WIDTH_8: 355 + case NL80211_CHAN_WIDTH_16: 356 + /* checked separately */ 357 + break; 358 + case NL80211_CHAN_WIDTH_320: 359 + if (chandef->center_freq1 == control_freq + 150 || 360 + chandef->center_freq1 == control_freq + 130 || 361 + chandef->center_freq1 == control_freq + 110 || 362 + chandef->center_freq1 == control_freq + 90 || 363 + chandef->center_freq1 == control_freq - 90 || 364 + chandef->center_freq1 == control_freq - 110 || 365 + chandef->center_freq1 == control_freq - 130 || 366 + chandef->center_freq1 == control_freq - 150) 367 + break; 368 + fallthrough; 369 + case NL80211_CHAN_WIDTH_160: 370 + if (chandef->center_freq1 == control_freq + 70 || 371 + chandef->center_freq1 == control_freq + 50 || 372 + chandef->center_freq1 == control_freq - 50 || 373 + chandef->center_freq1 == control_freq - 70) 374 + break; 375 + fallthrough; 376 + case NL80211_CHAN_WIDTH_80P80: 377 + case NL80211_CHAN_WIDTH_80: 378 + if (chandef->center_freq1 == control_freq + 30 || 379 + chandef->center_freq1 == control_freq - 30) 380 + break; 381 + fallthrough; 382 + case NL80211_CHAN_WIDTH_40: 383 + if (chandef->center_freq1 == control_freq + 10 || 384 + chandef->center_freq1 == control_freq - 10) 385 + break; 386 + fallthrough; 387 + default: 388 + return false; 389 + } 390 + 391 + return true; 392 + } 393 + 344 394 bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) 345 395 { 346 396 u32 control_freq, control_freq_khz, start_khz, end_khz; ··· 404 350 return false; 405 351 406 352 control_freq = chandef->chan->center_freq; 353 + 354 + if (cfg80211_chandef_is_s1g(chandef) && 355 + chandef->width != NL80211_CHAN_WIDTH_1 && 356 + chandef->width != NL80211_CHAN_WIDTH_2 && 357 + chandef->width != NL80211_CHAN_WIDTH_4 && 358 + chandef->width != NL80211_CHAN_WIDTH_8 && 359 + chandef->width != NL80211_CHAN_WIDTH_16) 360 + return false; 407 361 408 362 switch (chandef->width) { 409 363 case NL80211_CHAN_WIDTH_5: ··· 455 393 break; 456 394 } 457 395 458 - switch (chandef->width) { 459 - case NL80211_CHAN_WIDTH_5: 460 - case NL80211_CHAN_WIDTH_10: 461 - case NL80211_CHAN_WIDTH_20: 462 - case NL80211_CHAN_WIDTH_20_NOHT: 463 - case NL80211_CHAN_WIDTH_1: 464 - case NL80211_CHAN_WIDTH_2: 465 - case NL80211_CHAN_WIDTH_4: 466 - case NL80211_CHAN_WIDTH_8: 467 - case NL80211_CHAN_WIDTH_16: 468 - /* all checked above */ 469 - break; 470 - case NL80211_CHAN_WIDTH_320: 471 - if (chandef->center_freq1 == control_freq + 150 || 472 - chandef->center_freq1 == control_freq + 130 || 473 - chandef->center_freq1 == control_freq + 110 || 474 - chandef->center_freq1 == control_freq + 90 || 475 - chandef->center_freq1 == control_freq - 90 || 476 - chandef->center_freq1 == control_freq - 110 || 477 - chandef->center_freq1 == control_freq - 130 || 478 - chandef->center_freq1 == control_freq - 150) 479 - break; 480 - fallthrough; 481 - case NL80211_CHAN_WIDTH_160: 482 - if (chandef->center_freq1 == control_freq + 70 || 483 - chandef->center_freq1 == control_freq + 50 || 484 - chandef->center_freq1 == control_freq - 50 || 485 - chandef->center_freq1 == control_freq - 70) 486 - break; 487 - fallthrough; 488 - case NL80211_CHAN_WIDTH_80P80: 489 - case NL80211_CHAN_WIDTH_80: 490 - if (chandef->center_freq1 == control_freq + 30 || 491 - chandef->center_freq1 == control_freq - 30) 492 - break; 493 - fallthrough; 494 - case NL80211_CHAN_WIDTH_40: 495 - if (chandef->center_freq1 == control_freq + 10 || 496 - chandef->center_freq1 == control_freq - 10) 497 - break; 498 - fallthrough; 499 - default: 396 + if (!cfg80211_chandef_valid_control_freq(chandef, control_freq)) 500 397 return false; 501 - } 502 398 503 399 if (!cfg80211_valid_center_freq(chandef->center_freq1, chandef->width)) 504 400 return false;
+24 -13
net/wireless/nl80211.c
··· 339 339 const u8 *data = nla_data(attr); 340 340 unsigned int len = nla_len(attr); 341 341 342 - return ieee80211_uhr_capa_size_ok(data, len, false); 342 + if (!ieee80211_uhr_capa_size_ok(data, len, false)) 343 + return -EINVAL; 344 + return 0; 345 + } 346 + 347 + static int validate_uhr_operation(const struct nlattr *attr, 348 + struct netlink_ext_ack *extack) 349 + { 350 + const u8 *data = nla_data(attr); 351 + unsigned int len = nla_len(attr); 352 + 353 + if (!ieee80211_uhr_oper_size_ok(data, len, false)) 354 + return -EINVAL; 355 + return 0; 343 356 } 344 357 345 358 /* policy for the attributes */ ··· 960 947 [NL80211_ATTR_UHR_CAPABILITY] = 961 948 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_capa, 255), 962 949 [NL80211_ATTR_DISABLE_UHR] = { .type = NLA_FLAG }, 950 + [NL80211_ATTR_UHR_OPERATION] = 951 + NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_operation), 963 952 }; 964 953 965 954 /* policy for the key attributes */ ··· 3634 3619 case NL80211_CHAN_HT20: 3635 3620 case NL80211_CHAN_HT40PLUS: 3636 3621 case NL80211_CHAN_HT40MINUS: 3622 + if (chandef->chan->band == NL80211_BAND_60GHZ || 3623 + chandef->chan->band == NL80211_BAND_S1GHZ) 3624 + return -EINVAL; 3637 3625 cfg80211_chandef_create(chandef, chandef->chan, 3638 3626 chantype); 3639 3627 /* user input for center_freq is incorrect */ ··· 5843 5825 */ 5844 5826 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8); 5845 5827 nla_for_each_nested(tx_rates, attrs[attr], rem) { 5846 - enum nl80211_band band = nla_type(tx_rates); 5828 + int band = nla_type(tx_rates); 5847 5829 int err; 5848 5830 5849 5831 if (band < 0 || band >= NUM_NL80211_BANDS) ··· 6517 6499 return -EINVAL; 6518 6500 } 6519 6501 6520 - cap = cfg80211_find_ext_elem(WLAN_EID_EXT_UHR_OPER, ies, ies_len); 6521 - if (cap) { 6522 - if (!cap->datalen) 6523 - return -EINVAL; 6524 - params->uhr_oper = (void *)(cap->data + 1); 6525 - if (!ieee80211_uhr_oper_size_ok((const u8 *)params->uhr_oper, 6526 - cap->datalen - 1, true)) 6527 - return -EINVAL; 6528 - } 6529 - 6530 6502 return 0; 6531 6503 } 6532 6504 ··· 6957 6949 err = nl80211_calculate_ap_params(params); 6958 6950 if (err) 6959 6951 goto out; 6952 + 6953 + if (info->attrs[NL80211_ATTR_UHR_OPERATION]) 6954 + params->uhr_oper = nla_data(info->attrs[NL80211_ATTR_UHR_OPERATION]); 6960 6955 6961 6956 err = nl80211_validate_ap_phy_operation(params); 6962 6957 if (err) ··· 10705 10694 nla_for_each_nested(attr, 10706 10695 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES], 10707 10696 tmp) { 10708 - enum nl80211_band band = nla_type(attr); 10697 + int band = nla_type(attr); 10709 10698 10710 10699 if (band < 0 || band >= NUM_NL80211_BANDS) { 10711 10700 err = -EINVAL;
+1 -12
net/wireless/of.c
··· 1 + // SPDX-License-Identifier: ISC 1 2 /* 2 3 * Copyright (C) 2017 Rafał Miłecki <rafal@milecki.pl> 3 - * 4 - * Permission to use, copy, modify, and/or distribute this software for any 5 - * purpose with or without fee is hereby granted, provided that the above 6 - * copyright notice and this permission notice appear in all copies. 7 - * 8 - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 4 */ 16 5 17 6 #include <linux/of.h>
+1 -9
net/wireless/radiotap.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 1 2 /* 2 3 * Radiotap parser 3 4 * 4 5 * Copyright 2007 Andy Green <andy@warmcat.com> 5 6 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. 10 - * 11 - * Alternatively, this software may be distributed under the terms of BSD 12 - * license. 13 - * 14 - * See COPYING for more details. 15 7 */ 16 8 17 9 #include <linux/kernel.h>
+1 -12
net/wireless/reg.c
··· 1 + // SPDX-License-Identifier: ISC 1 2 /* 2 3 * Copyright 2002-2005, Instant802 Networks, Inc. 3 4 * Copyright 2005-2006, Devicescape Software, Inc. ··· 7 6 * Copyright 2013-2014 Intel Mobile Communications GmbH 8 7 * Copyright 2017 Intel Deutschland GmbH 9 8 * Copyright (C) 2018 - 2026 Intel Corporation 10 - * 11 - * Permission to use, copy, modify, and/or distribute this software for any 12 - * purpose with or without fee is hereby granted, provided that the above 13 - * copyright notice and this permission notice appear in all copies. 14 - * 15 - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 16 - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 18 - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21 - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 9 */ 23 10 24 11
+1 -12
net/wireless/reg.h
··· 1 + /* SPDX-License-Identifier: ISC */ 1 2 #ifndef __NET_WIRELESS_REG_H 2 3 #define __NET_WIRELESS_REG_H 3 4 ··· 7 6 /* 8 7 * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com> 9 8 * Copyright (C) 2019, 2023 Intel Corporation 10 - * 11 - * Permission to use, copy, modify, and/or distribute this software for any 12 - * purpose with or without fee is hereby granted, provided that the above 13 - * copyright notice and this permission notice appear in all copies. 14 - * 15 - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 16 - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 18 - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21 - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 9 */ 23 10 24 11 enum ieee80211_regd_source {
+1
net/wireless/trace.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 #include <linux/module.h> 2 3 3 4 #ifndef __CHECKER__
+1 -2
net/wireless/wext-core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * This file implement the Wireless Extensions core API. 3 4 * ··· 6 5 * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved. 7 6 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 8 7 * Copyright (C) 2024 Intel Corporation 9 - * 10 - * (As all part of the Linux kernel, this file is GPL) 11 8 */ 12 9 #include <linux/kernel.h> 13 10 #include <linux/netdevice.h>
+1 -2
net/wireless/wext-priv.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * This file implement the Wireless Extensions priv API. 3 4 * 4 5 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> 5 6 * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved. 6 7 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 7 - * 8 - * (As all part of the Linux kernel, this file is GPL) 9 8 */ 10 9 #include <linux/slab.h> 11 10 #include <linux/wireless.h>
+1 -2
net/wireless/wext-proc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * This file implement the Wireless Extensions proc API. 3 4 * 4 5 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> 5 6 * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved. 6 - * 7 - * (As all part of the Linux kernel, this file is GPL) 8 7 */ 9 8 10 9 /*