From 0f53914ca5e62231f2d5316a6acf714227fd6ba9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 1 Apr 2024 22:59:10 +0200 Subject: [PATCH] mac80211: backport some upstream EHT patches MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Those changes are needed by Wi-Fi 7 drivers. Signed-off-by: Rafał Miłecki --- package/kernel/mac80211/Makefile | 2 +- ...Transition-Disable-policy-during-por.patch | 189 +++++++++ ...ort-minimal-EHT-rate-reporting-on-RX.patch | 179 ++++++++ ...1-mlme-handle-EHT-channel-puncturing.patch | 387 ++++++++++++++++++ ...ve-puncturing-bitmap-validation-from.patch | 219 ++++++++++ ...idate-and-configure-puncturing-bitma.patch | 169 ++++++++ ...clude-puncturing-bitmap-in-channel-s.patch | 263 ++++++++++++ ...mac80211-configure-puncturing-bitmap.patch | 107 +++++ ...d-EHT-MU-MIMO-related-flags-in-ieee8.patch | 68 +++ .../500-mac80211_configure_antenna_gain.patch | 35 +- .../780-avoid-crashing-missing-band.patch | 2 +- 11 files changed, 1600 insertions(+), 20 deletions(-) create mode 100644 package/kernel/mac80211/patches/subsys/341-v6.2-cfg80211-Update-Transition-Disable-policy-during-por.patch create mode 100644 package/kernel/mac80211/patches/subsys/342-v6.3-mac80211-support-minimal-EHT-rate-reporting-on-RX.patch create mode 100644 package/kernel/mac80211/patches/subsys/343-v6.3-wifi-mac80211-mlme-handle-EHT-channel-puncturing.patch create mode 100644 package/kernel/mac80211/patches/subsys/344-v6.3-0001-wifi-cfg80211-move-puncturing-bitmap-validation-from.patch create mode 100644 package/kernel/mac80211/patches/subsys/344-v6.3-0002-wifi-nl80211-validate-and-configure-puncturing-bitma.patch create mode 100644 package/kernel/mac80211/patches/subsys/344-v6.3-0003-wifi-cfg80211-include-puncturing-bitmap-in-channel-s.patch create mode 100644 package/kernel/mac80211/patches/subsys/344-v6.3-0004-wifi-mac80211-configure-puncturing-bitmap.patch create mode 100644 package/kernel/mac80211/patches/subsys/345-v6.4-wifi-mac80211-add-EHT-MU-MIMO-related-flags-in-ieee8.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 4c0144decf..1f31ecd90f 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=6.1.24 -PKG_RELEASE:=3 +PKG_RELEASE:=4 # PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ PKG_HASH:=5d39aca7e34c33cb9b3e366117b2e86841b7bdd37933679d6b1e61be6b150648 diff --git a/package/kernel/mac80211/patches/subsys/341-v6.2-cfg80211-Update-Transition-Disable-policy-during-por.patch b/package/kernel/mac80211/patches/subsys/341-v6.2-cfg80211-Update-Transition-Disable-policy-during-por.patch new file mode 100644 index 0000000000..d0551c509f --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/341-v6.2-cfg80211-Update-Transition-Disable-policy-during-por.patch @@ -0,0 +1,189 @@ +From 0ff57171d6d225558c81a69439d5323e35b40549 Mon Sep 17 00:00:00 2001 +From: Vinayak Yadawad +Date: Wed, 7 Sep 2022 18:14:48 +0530 +Subject: [PATCH] cfg80211: Update Transition Disable policy during port + authorization + +In case of 4way handshake offload, transition disable policy +updated by the AP during EAPOL 3/4 is not updated to the upper layer. +This results in mismatch between transition disable policy +between the upper layer and the driver. This patch addresses this +issue by updating transition disable policy as part of port +authorization indication. + +Signed-off-by: Vinayak Yadawad +Signed-off-by: Johannes Berg +--- + .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- + include/net/cfg80211.h | 4 +++- + include/uapi/linux/nl80211.h | 3 +++ + net/wireless/core.h | 5 ++++- + net/wireless/nl80211.c | 8 +++++++- + net/wireless/nl80211.h | 3 ++- + net/wireless/sme.c | 12 ++++++++---- + net/wireless/util.c | 4 +++- + 8 files changed, 31 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6005,7 +6005,7 @@ done: + brcmf_dbg(CONN, "Report roaming result\n"); + + if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) { +- cfg80211_port_authorized(ndev, profile->bssid, GFP_KERNEL); ++ cfg80211_port_authorized(ndev, profile->bssid, NULL, 0, GFP_KERNEL); + brcmf_dbg(CONN, "Report port authorized\n"); + } + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -7720,6 +7720,8 @@ void cfg80211_roamed(struct net_device * + * + * @dev: network device + * @bssid: the BSSID of the AP ++ * @td_bitmap: transition disable policy ++ * @td_bitmap_len: Length of transition disable policy + * @gfp: allocation flags + * + * This function should be called by a driver that supports 4 way handshake +@@ -7730,7 +7732,7 @@ void cfg80211_roamed(struct net_device * + * indicate the 802.11 association. + */ + void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid, +- gfp_t gfp); ++ const u8* td_bitmap, u8 td_bitmap_len, gfp_t gfp); + + /** + * cfg80211_disconnected - notify cfg80211 that connection was dropped +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -2749,6 +2749,8 @@ enum nl80211_commands { + * When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the ack RX + * timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates + * the incoming frame RX timestamp. ++ * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent ++ * (re)associations. + * @NUM_NL80211_ATTR: total number of nl80211_attrs available + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use +@@ -3276,6 +3278,7 @@ enum nl80211_attrs { + + NL80211_ATTR_TX_HW_TIMESTAMP, + NL80211_ATTR_RX_HW_TIMESTAMP, ++ NL80211_ATTR_TD_BITMAP, + + /* add attributes here, update the policy in nl80211.c */ + +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -271,6 +271,8 @@ struct cfg80211_event { + } ij; + struct { + u8 bssid[ETH_ALEN]; ++ const u8 *td_bitmap; ++ u8 td_bitmap_len; + } pa; + }; + }; +@@ -409,7 +411,8 @@ int cfg80211_disconnect(struct cfg80211_ + bool wextev); + void __cfg80211_roamed(struct wireless_dev *wdev, + struct cfg80211_roam_info *info); +-void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid); ++void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid, ++ const u8 *td_bitmap, u8 td_bitmap_len); + int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev); + void cfg80211_autodisconnect_wk(struct work_struct *work); +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -17936,7 +17936,8 @@ void nl80211_send_roamed(struct cfg80211 + } + + void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev, +- struct net_device *netdev, const u8 *bssid) ++ struct net_device *netdev, const u8 *bssid, ++ const u8 *td_bitmap, u8 td_bitmap_len) + { + struct sk_buff *msg; + void *hdr; +@@ -17956,6 +17957,11 @@ void nl80211_send_port_authorized(struct + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) + goto nla_put_failure; + ++ if ((td_bitmap_len > 0) && td_bitmap) ++ if (nla_put(msg, NL80211_ATTR_TD_BITMAP, ++ td_bitmap_len, td_bitmap)) ++ goto nla_put_failure; ++ + genlmsg_end(msg, hdr); + + genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, +--- a/net/wireless/nl80211.h ++++ b/net/wireless/nl80211.h +@@ -83,7 +83,8 @@ void nl80211_send_roamed(struct cfg80211 + struct net_device *netdev, + struct cfg80211_roam_info *info, gfp_t gfp); + void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev, +- struct net_device *netdev, const u8 *bssid); ++ struct net_device *netdev, const u8 *bssid, ++ const u8 *td_bitmap, u8 td_bitmap_len); + void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u16 reason, + const u8 *ie, size_t ie_len, bool from_ap); +--- a/net/wireless/sme.c ++++ b/net/wireless/sme.c +@@ -1266,7 +1266,8 @@ out: + } + EXPORT_SYMBOL(cfg80211_roamed); + +-void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid) ++void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid, ++ const u8 *td_bitmap, u8 td_bitmap_len) + { + ASSERT_WDEV_LOCK(wdev); + +@@ -1279,11 +1280,11 @@ void __cfg80211_port_authorized(struct w + return; + + nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev, +- bssid); ++ bssid, td_bitmap, td_bitmap_len); + } + + void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid, +- gfp_t gfp) ++ const u8 *td_bitmap, u8 td_bitmap_len, gfp_t gfp) + { + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); +@@ -1293,12 +1294,15 @@ void cfg80211_port_authorized(struct net + if (WARN_ON(!bssid)) + return; + +- ev = kzalloc(sizeof(*ev), gfp); ++ ev = kzalloc(sizeof(*ev) + td_bitmap_len, gfp); + if (!ev) + return; + + ev->type = EVENT_PORT_AUTHORIZED; + memcpy(ev->pa.bssid, bssid, ETH_ALEN); ++ ev->pa.td_bitmap = ((u8 *)ev) + sizeof(*ev); ++ ev->pa.td_bitmap_len = td_bitmap_len; ++ memcpy((void *)ev->pa.td_bitmap, td_bitmap, td_bitmap_len); + + /* + * Use the wdev event list so that if there are pending +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -1057,7 +1057,9 @@ void cfg80211_process_wdev_events(struct + __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev); + break; + case EVENT_PORT_AUTHORIZED: +- __cfg80211_port_authorized(wdev, ev->pa.bssid); ++ __cfg80211_port_authorized(wdev, ev->pa.bssid, ++ ev->pa.td_bitmap, ++ ev->pa.td_bitmap_len); + break; + } + wdev_unlock(wdev); diff --git a/package/kernel/mac80211/patches/subsys/342-v6.3-mac80211-support-minimal-EHT-rate-reporting-on-RX.patch b/package/kernel/mac80211/patches/subsys/342-v6.3-mac80211-support-minimal-EHT-rate-reporting-on-RX.patch new file mode 100644 index 0000000000..0b1111505c --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/342-v6.3-mac80211-support-minimal-EHT-rate-reporting-on-RX.patch @@ -0,0 +1,179 @@ +From f66c48af7a110c0d694c4ac4a1257affb272a2ea Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 9 Jan 2023 13:07:21 +0200 +Subject: [PATCH] mac80211: support minimal EHT rate reporting on RX + +Add minimal support for RX EHT rate reporting, not yet +adding (modifying) any radiotap headers, just statistics +for cfg80211. + +Signed-off-by: Johannes Berg +--- + include/net/mac80211.h | 19 ++++++++++++++++--- + net/mac80211/rx.c | 9 +++++++++ + net/mac80211/sta_info.c | 9 ++++++++- + net/mac80211/sta_info.h | 24 ++++++++++++++++++------ + net/mac80211/util.c | 13 +++++++++++++ + 5 files changed, 64 insertions(+), 10 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1468,6 +1468,7 @@ enum mac80211_rx_encoding { + RX_ENC_HT, + RX_ENC_VHT, + RX_ENC_HE, ++ RX_ENC_EHT, + }; + + /** +@@ -1501,7 +1502,7 @@ enum mac80211_rx_encoding { + * @antenna: antenna used + * @rate_idx: index of data rate into band's supported rates or MCS index if + * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT) +- * @nss: number of streams (VHT and HE only) ++ * @nss: number of streams (VHT, HE and EHT only) + * @flag: %RX_FLAG_\* + * @encoding: &enum mac80211_rx_encoding + * @bw: &enum rate_info_bw +@@ -1509,6 +1510,8 @@ enum mac80211_rx_encoding { + * @he_ru: HE RU, from &enum nl80211_he_ru_alloc + * @he_gi: HE GI, from &enum nl80211_he_gi + * @he_dcm: HE DCM value ++ * @eht.ru: EHT RU, from &enum nl80211_eht_ru_alloc ++ * @eht.gi: EHT GI, from &enum nl80211_eht_gi + * @rx_flags: internal RX flags for mac80211 + * @ampdu_reference: A-MPDU reference number, must be a different value for + * each A-MPDU but the same for each subframe within one A-MPDU +@@ -1530,8 +1533,18 @@ struct ieee80211_rx_status { + u32 flag; + u16 freq: 13, freq_offset: 1; + u8 enc_flags; +- u8 encoding:2, bw:3, he_ru:3; +- u8 he_gi:2, he_dcm:1; ++ u8 encoding:3, bw:4; ++ union { ++ struct { ++ u8 he_ru:3; ++ u8 he_gi:2; ++ u8 he_dcm:1; ++ }; ++ struct { ++ u8 ru:4; ++ u8 gi:2; ++ } eht; ++ }; + u8 rate_idx; + u8 nss; + u8 rx_flags; +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -5328,6 +5328,15 @@ void ieee80211_rx_list(struct ieee80211_ + status->rate_idx, status->nss)) + goto drop; + break; ++ case RX_ENC_EHT: ++ if (WARN_ONCE(status->rate_idx > 15 || ++ !status->nss || ++ status->nss > 8 || ++ status->eht.gi > NL80211_RATE_INFO_EHT_GI_3_2, ++ "Rate marked as an EHT rate but data is invalid: MCS:%d, NSS:%d, GI:%d\n", ++ status->rate_idx, status->nss, status->eht.gi)) ++ goto drop; ++ break; + default: + WARN_ON_ONCE(1); + fallthrough; +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -4,7 +4,7 @@ + * Copyright 2006-2007 Jiri Benc + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright (C) 2015 - 2017 Intel Deutschland GmbH +- * Copyright (C) 2018-2021 Intel Corporation ++ * Copyright (C) 2018-2022 Intel Corporation + */ + + #include +@@ -2385,6 +2385,13 @@ static void sta_stats_decode_rate(struct + rinfo->he_ru_alloc = STA_STATS_GET(HE_RU, rate); + rinfo->he_dcm = STA_STATS_GET(HE_DCM, rate); + break; ++ case STA_STATS_RATE_TYPE_EHT: ++ rinfo->flags = RATE_INFO_FLAGS_EHT_MCS; ++ rinfo->mcs = STA_STATS_GET(EHT_MCS, rate); ++ rinfo->nss = STA_STATS_GET(EHT_NSS, rate); ++ rinfo->eht_gi = STA_STATS_GET(EHT_GI, rate); ++ rinfo->eht_ru_alloc = STA_STATS_GET(EHT_RU, rate); ++ break; + } + } + +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -930,6 +930,7 @@ enum sta_stats_type { + STA_STATS_RATE_TYPE_VHT, + STA_STATS_RATE_TYPE_HE, + STA_STATS_RATE_TYPE_S1G, ++ STA_STATS_RATE_TYPE_EHT, + }; + + #define STA_STATS_FIELD_HT_MCS GENMASK( 7, 0) +@@ -939,12 +940,16 @@ enum sta_stats_type { + #define STA_STATS_FIELD_VHT_NSS GENMASK( 7, 4) + #define STA_STATS_FIELD_HE_MCS GENMASK( 3, 0) + #define STA_STATS_FIELD_HE_NSS GENMASK( 7, 4) +-#define STA_STATS_FIELD_BW GENMASK(11, 8) +-#define STA_STATS_FIELD_SGI GENMASK(12, 12) +-#define STA_STATS_FIELD_TYPE GENMASK(15, 13) +-#define STA_STATS_FIELD_HE_RU GENMASK(18, 16) +-#define STA_STATS_FIELD_HE_GI GENMASK(20, 19) +-#define STA_STATS_FIELD_HE_DCM GENMASK(21, 21) ++#define STA_STATS_FIELD_EHT_MCS GENMASK( 3, 0) ++#define STA_STATS_FIELD_EHT_NSS GENMASK( 7, 4) ++#define STA_STATS_FIELD_BW GENMASK(12, 8) ++#define STA_STATS_FIELD_SGI GENMASK(13, 13) ++#define STA_STATS_FIELD_TYPE GENMASK(16, 14) ++#define STA_STATS_FIELD_HE_RU GENMASK(19, 17) ++#define STA_STATS_FIELD_HE_GI GENMASK(21, 20) ++#define STA_STATS_FIELD_HE_DCM GENMASK(22, 22) ++#define STA_STATS_FIELD_EHT_RU GENMASK(20, 17) ++#define STA_STATS_FIELD_EHT_GI GENMASK(22, 21) + + #define STA_STATS_FIELD(_n, _v) FIELD_PREP(STA_STATS_FIELD_ ## _n, _v) + #define STA_STATS_GET(_n, _v) FIELD_GET(STA_STATS_FIELD_ ## _n, _v) +@@ -983,6 +988,13 @@ static inline u32 sta_stats_encode_rate( + r |= STA_STATS_FIELD(HE_RU, s->he_ru); + r |= STA_STATS_FIELD(HE_DCM, s->he_dcm); + break; ++ case RX_ENC_EHT: ++ r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_EHT); ++ r |= STA_STATS_FIELD(EHT_NSS, s->nss); ++ r |= STA_STATS_FIELD(EHT_MCS, s->rate_idx); ++ r |= STA_STATS_FIELD(EHT_GI, s->eht.gi); ++ r |= STA_STATS_FIELD(EHT_RU, s->eht.ru); ++ break; + default: + WARN_ON(1); + return STA_STATS_RATE_INVALID; +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -3900,6 +3900,19 @@ u64 ieee80211_calculate_rx_timestamp(str + + /* Fill cfg80211 rate info */ + switch (status->encoding) { ++ case RX_ENC_EHT: ++ ri.flags |= RATE_INFO_FLAGS_EHT_MCS; ++ ri.mcs = status->rate_idx; ++ ri.nss = status->nss; ++ ri.eht_ru_alloc = status->eht.ru; ++ if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) ++ ri.flags |= RATE_INFO_FLAGS_SHORT_GI; ++ /* TODO/FIXME: is this right? handle other PPDUs */ ++ if (status->flag & RX_FLAG_MACTIME_PLCP_START) { ++ mpdu_offset += 2; ++ ts += 36; ++ } ++ break; + case RX_ENC_HE: + ri.flags |= RATE_INFO_FLAGS_HE_MCS; + ri.mcs = status->rate_idx; diff --git a/package/kernel/mac80211/patches/subsys/343-v6.3-wifi-mac80211-mlme-handle-EHT-channel-puncturing.patch b/package/kernel/mac80211/patches/subsys/343-v6.3-wifi-mac80211-mlme-handle-EHT-channel-puncturing.patch new file mode 100644 index 0000000000..b5bd501937 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/343-v6.3-wifi-mac80211-mlme-handle-EHT-channel-puncturing.patch @@ -0,0 +1,387 @@ +From aa87cd8b35736a5183745ab0ec4b82419024dfd7 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 27 Jan 2023 12:39:31 +0100 +Subject: [PATCH] wifi: mac80211: mlme: handle EHT channel puncturing + +Handle the Puncturing info received from the AP in the +EHT Operation element in beacons. + +If the info is invalid: + - during association: disable EHT connection for the AP + - after association: disconnect + +This commit includes many (internal) bugfixes and spec +updates various people. + +Co-developed-by: Miri Korenblit +Signed-off-by: Miri Korenblit +Link: https://lore.kernel.org/r/20230127123930.4fbc74582331.I3547481d49f958389f59dfeba3fcc75e72b0aa6e@changeid +Signed-off-by: Johannes Berg +--- + include/net/mac80211.h | 5 +- + net/mac80211/cfg.c | 2 +- + net/mac80211/chan.c | 2 +- + net/mac80211/ieee80211_i.h | 2 +- + net/mac80211/mlme.c | 224 ++++++++++++++++++++++++++++++++++++- + 5 files changed, 228 insertions(+), 7 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -340,7 +340,7 @@ struct ieee80211_vif_chanctx_switch { + * @BSS_CHANGED_FILS_DISCOVERY: FILS discovery status changed. + * @BSS_CHANGED_UNSOL_BCAST_PROBE_RESP: Unsolicited broadcast probe response + * status changed. +- * ++ * @BSS_CHANGED_EHT_PUNCTURING: The channel puncturing bitmap changed. + */ + enum ieee80211_bss_change { + BSS_CHANGED_ASSOC = 1<<0, +@@ -375,6 +375,7 @@ enum ieee80211_bss_change { + BSS_CHANGED_HE_BSS_COLOR = 1<<29, + BSS_CHANGED_FILS_DISCOVERY = 1<<30, + BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = 1<<31, ++ BSS_CHANGED_EHT_PUNCTURING = BIT_ULL(32), + + /* when adding here, make sure to change ieee80211_reconfig */ + }; +@@ -640,6 +641,7 @@ struct ieee80211_fils_discovery { + * @tx_pwr_env_num: number of @tx_pwr_env. + * @pwr_reduction: power constraint of BSS. + * @eht_support: does this BSS support EHT ++ * @eht_puncturing: bitmap to indicate which channels are punctured in this BSS + * @csa_active: marks whether a channel switch is going on. Internally it is + * write-protected by sdata_lock and local->mtx so holding either is fine + * for read access. +@@ -739,6 +741,7 @@ struct ieee80211_bss_conf { + u8 tx_pwr_env_num; + u8 pwr_reduction; + bool eht_support; ++ u16 eht_puncturing; + + bool csa_active; + bool mu_mimo_owner; +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -4184,7 +4184,7 @@ static int ieee80211_set_ap_chanwidth(st + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_link_data *link; + int ret; +- u32 changed = 0; ++ u64 changed = 0; + + link = sdata_dereference(sdata->link[link_id], sdata); + +--- a/net/mac80211/chan.c ++++ b/net/mac80211/chan.c +@@ -1916,7 +1916,7 @@ int ieee80211_link_use_reserved_context( + + int ieee80211_link_change_bandwidth(struct ieee80211_link_data *link, + const struct cfg80211_chan_def *chandef, +- u32 *changed) ++ u64 *changed) + { + struct ieee80211_sub_if_data *sdata = link->sdata; + struct ieee80211_bss_conf *link_conf = link->conf; +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2491,7 +2491,7 @@ int ieee80211_link_unreserve_chanctx(str + int __must_check + ieee80211_link_change_bandwidth(struct ieee80211_link_data *link, + const struct cfg80211_chan_def *chandef, +- u32 *changed); ++ u64 *changed); + void ieee80211_link_release_channel(struct ieee80211_link_data *link); + void ieee80211_link_vlan_copy_chanctx(struct ieee80211_link_data *link); + void ieee80211_link_copy_chanctx_to_vlans(struct ieee80211_link_data *link, +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -8,7 +8,7 @@ + * Copyright 2007, Michael Wu + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright (C) 2015 - 2017 Intel Deutschland GmbH +- * Copyright (C) 2018 - 2022 Intel Corporation ++ * Copyright (C) 2018 - 2023 Intel Corporation + */ + + #include +@@ -88,6 +88,141 @@ MODULE_PARM_DESC(probe_wait_ms, + */ + #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 + ++struct ieee80211_per_bw_puncturing_values { ++ u8 len; ++ const u16 *valid_values; ++}; ++ ++static const u16 puncturing_values_80mhz[] = { ++ 0x8, 0x4, 0x2, 0x1 ++}; ++ ++static const u16 puncturing_values_160mhz[] = { ++ 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3 ++}; ++ ++static const u16 puncturing_values_320mhz[] = { ++ 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00, ++ 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f, ++ 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f ++}; ++ ++#define IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \ ++ { \ ++ .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \ ++ .valid_values = puncturing_values_ ## _bw ## mhz \ ++ } ++ ++static const struct ieee80211_per_bw_puncturing_values per_bw_puncturing[] = { ++ IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(80), ++ IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(160), ++ IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(320) ++}; ++ ++static bool ieee80211_valid_disable_subchannel_bitmap(u16 *bitmap, ++ enum nl80211_chan_width bw) ++{ ++ u32 idx, i; ++ ++ switch (bw) { ++ case NL80211_CHAN_WIDTH_80: ++ idx = 0; ++ break; ++ case NL80211_CHAN_WIDTH_160: ++ idx = 1; ++ break; ++ case NL80211_CHAN_WIDTH_320: ++ idx = 2; ++ break; ++ default: ++ *bitmap = 0; ++ break; ++ } ++ ++ if (!*bitmap) ++ return true; ++ ++ for (i = 0; i < per_bw_puncturing[idx].len; i++) ++ if (per_bw_puncturing[idx].valid_values[i] == *bitmap) ++ return true; ++ ++ return false; ++} ++ ++/* ++ * Extract from the given disabled subchannel bitmap (raw format ++ * from the EHT Operation Element) the bits for the subchannel ++ * we're using right now. ++ */ ++static u16 ++ieee80211_extract_dis_subch_bmap(const struct ieee80211_eht_operation *eht_oper, ++ struct cfg80211_chan_def *chandef, u16 bitmap) ++{ ++ struct ieee80211_eht_operation_info *info = (void *)eht_oper->optional; ++ struct cfg80211_chan_def ap_chandef = *chandef; ++ u32 ap_center_freq, local_center_freq; ++ u32 ap_bw, local_bw; ++ int ap_start_freq, local_start_freq; ++ u16 shift, mask; ++ ++ if (!(eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT) || ++ !(eht_oper->params & ++ IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT)) ++ return 0; ++ ++ /* set 160/320 supported to get the full AP definition */ ++ ieee80211_chandef_eht_oper(eht_oper, true, true, &ap_chandef); ++ ap_center_freq = ap_chandef.center_freq1; ++ ap_bw = 20 * BIT(u8_get_bits(info->control, ++ IEEE80211_EHT_OPER_CHAN_WIDTH)); ++ ap_start_freq = ap_center_freq - ap_bw / 2; ++ local_center_freq = chandef->center_freq1; ++ local_bw = 20 * BIT(ieee80211_chan_width_to_rx_bw(chandef->width)); ++ local_start_freq = local_center_freq - local_bw / 2; ++ shift = (local_start_freq - ap_start_freq) / 20; ++ mask = BIT(local_bw / 20) - 1; ++ ++ return (bitmap >> shift) & mask; ++} ++ ++/* ++ * Handle the puncturing bitmap, possibly downgrading bandwidth to get a ++ * valid bitmap. ++ */ ++static void ++ieee80211_handle_puncturing_bitmap(struct ieee80211_link_data *link, ++ const struct ieee80211_eht_operation *eht_oper, ++ u16 bitmap, u64 *changed) ++{ ++ struct cfg80211_chan_def *chandef = &link->conf->chandef; ++ u16 extracted; ++ u64 _changed = 0; ++ ++ if (!changed) ++ changed = &_changed; ++ ++ while (chandef->width > NL80211_CHAN_WIDTH_40) { ++ extracted = ++ ieee80211_extract_dis_subch_bmap(eht_oper, chandef, ++ bitmap); ++ ++ if (ieee80211_valid_disable_subchannel_bitmap(&bitmap, ++ chandef->width)) ++ break; ++ link->u.mgd.conn_flags |= ++ ieee80211_chandef_downgrade(chandef); ++ *changed |= BSS_CHANGED_BANDWIDTH; ++ } ++ ++ if (chandef->width <= NL80211_CHAN_WIDTH_40) ++ extracted = 0; ++ ++ if (link->conf->eht_puncturing != extracted) { ++ link->conf->eht_puncturing = extracted; ++ *changed |= BSS_CHANGED_EHT_PUNCTURING; ++ } ++} ++ + /* + * We can have multiple work items (and connection probing) + * scheduling this timer, but we need to take care to only +@@ -413,7 +548,7 @@ static int ieee80211_config_bw(struct ie + const struct ieee80211_he_operation *he_oper, + const struct ieee80211_eht_operation *eht_oper, + const struct ieee80211_s1g_oper_ie *s1g_oper, +- const u8 *bssid, u32 *changed) ++ const u8 *bssid, u64 *changed) + { + struct ieee80211_sub_if_data *sdata = link->sdata; + struct ieee80211_local *local = sdata->local; +@@ -4111,6 +4246,7 @@ static bool ieee80211_assoc_config_link( + link_sta); + + bss_conf->eht_support = link_sta->pub->eht_cap.has_eht; ++ *changed |= BSS_CHANGED_EHT_PUNCTURING; + } else { + bss_conf->eht_support = false; + } +@@ -5423,6 +5559,45 @@ static bool ieee80211_rx_our_beacon(cons + return ether_addr_equal(tx_bssid, bss->transmitted_bss->bssid); + } + ++static bool ieee80211_config_puncturing(struct ieee80211_link_data *link, ++ const struct ieee80211_eht_operation *eht_oper, ++ u64 *changed) ++{ ++ u16 bitmap = 0, extracted; ++ ++ if ((eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT) && ++ (eht_oper->params & ++ IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT)) { ++ const struct ieee80211_eht_operation_info *info = ++ (void *)eht_oper->optional; ++ const u8 *disable_subchannel_bitmap = info->optional; ++ ++ bitmap = get_unaligned_le16(disable_subchannel_bitmap); ++ } ++ ++ extracted = ieee80211_extract_dis_subch_bmap(eht_oper, ++ &link->conf->chandef, ++ bitmap); ++ ++ /* accept if there are no changes */ ++ if (!(*changed & BSS_CHANGED_BANDWIDTH) && ++ extracted == link->conf->eht_puncturing) ++ return true; ++ ++ if (!ieee80211_valid_disable_subchannel_bitmap(&bitmap, ++ link->conf->chandef.width)) { ++ link_info(link, ++ "Got an invalid disable subchannel bitmap from AP %pM: bitmap = 0x%x, bw = 0x%x. disconnect\n", ++ link->u.mgd.bssid, ++ bitmap, ++ link->conf->chandef.width); ++ return false; ++ } ++ ++ ieee80211_handle_puncturing_bitmap(link, eht_oper, bitmap, changed); ++ return true; ++} ++ + static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link, + struct ieee80211_hdr *hdr, size_t len, + struct ieee80211_rx_status *rx_status) +@@ -5439,7 +5614,7 @@ static void ieee80211_rx_mgmt_beacon(str + struct ieee80211_channel *chan; + struct link_sta_info *link_sta; + struct sta_info *sta; +- u32 changed = 0; ++ u64 changed = 0; + bool erp_valid; + u8 erp_value = 0; + u32 ncrc = 0; +@@ -5731,6 +5906,21 @@ static void ieee80211_rx_mgmt_beacon(str + elems->pwr_constr_elem, + elems->cisco_dtpc_elem); + ++ if (elems->eht_operation && ++ !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_EHT)) { ++ if (!ieee80211_config_puncturing(link, elems->eht_operation, ++ &changed)) { ++ ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, ++ WLAN_REASON_DEAUTH_LEAVING, ++ true, deauth_buf); ++ ieee80211_report_disconnect(sdata, deauth_buf, ++ sizeof(deauth_buf), true, ++ WLAN_REASON_DEAUTH_LEAVING, ++ false); ++ goto free; ++ } ++ } ++ + ieee80211_link_info_change_notify(sdata, link, changed); + free: + kfree(elems); +@@ -6832,9 +7022,12 @@ ieee80211_setup_assoc_link(struct ieee80 + ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap); + } + ++ link->conf->eht_puncturing = 0; ++ + rcu_read_lock(); + beacon_ies = rcu_dereference(cbss->beacon_ies); + if (beacon_ies) { ++ const struct ieee80211_eht_operation *eht_oper; + const struct element *elem; + u8 dtim_count = 0; + +@@ -6863,6 +7056,31 @@ ieee80211_setup_assoc_link(struct ieee80 + link->conf->ema_ap = true; + else + link->conf->ema_ap = false; ++ ++ elem = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_OPERATION, ++ beacon_ies->data, beacon_ies->len); ++ eht_oper = (const void *)(elem->data + 1); ++ ++ if (elem && ++ ieee80211_eht_oper_size_ok((const void *)(elem->data + 1), ++ elem->datalen - 1) && ++ (eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT) && ++ (eht_oper->params & IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT)) { ++ const struct ieee80211_eht_operation_info *info = ++ (void *)eht_oper->optional; ++ const u8 *disable_subchannel_bitmap = info->optional; ++ u16 bitmap; ++ ++ bitmap = get_unaligned_le16(disable_subchannel_bitmap); ++ if (ieee80211_valid_disable_subchannel_bitmap(&bitmap, ++ link->conf->chandef.width)) ++ ieee80211_handle_puncturing_bitmap(link, ++ eht_oper, ++ bitmap, ++ NULL); ++ else ++ conn_flags |= IEEE80211_CONN_DISABLE_EHT; ++ } + } + rcu_read_unlock(); + diff --git a/package/kernel/mac80211/patches/subsys/344-v6.3-0001-wifi-cfg80211-move-puncturing-bitmap-validation-from.patch b/package/kernel/mac80211/patches/subsys/344-v6.3-0001-wifi-cfg80211-move-puncturing-bitmap-validation-from.patch new file mode 100644 index 0000000000..31bc86197e --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/344-v6.3-0001-wifi-cfg80211-move-puncturing-bitmap-validation-from.patch @@ -0,0 +1,219 @@ +From b25413fed3d43e1ed3340df4d928971bb8639f66 Mon Sep 17 00:00:00 2001 +From: Aloka Dixit +Date: Mon, 30 Jan 2023 16:12:24 -0800 +Subject: [PATCH] wifi: cfg80211: move puncturing bitmap validation from + mac80211 + +- Move ieee80211_valid_disable_subchannel_bitmap() from mlme.c to + chan.c, rename it as cfg80211_valid_disable_subchannel_bitmap() + and export it. +- Modify the prototype to include struct cfg80211_chan_def instead + of only bandwidth to support a check which returns false if the + primary channel is punctured. + +Signed-off-by: Aloka Dixit +Link: https://lore.kernel.org/r/20230131001227.25014-2-quic_alokad@quicinc.com +Signed-off-by: Johannes Berg +--- + include/net/cfg80211.h | 12 +++++++ + net/mac80211/mlme.c | 73 ++++-------------------------------------- + net/wireless/chan.c | 69 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 87 insertions(+), 67 deletions(-) + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -8951,4 +8951,16 @@ static inline int cfg80211_color_change_ + 0, 0); + } + ++/** ++ * cfg80211_valid_disable_subchannel_bitmap - validate puncturing bitmap ++ * @bitmap: bitmap to be validated ++ * @chandef: channel definition ++ * ++ * Validate the puncturing bitmap. ++ * ++ * Return: %true if the bitmap is valid. %false otherwise. ++ */ ++bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap, ++ const struct cfg80211_chan_def *chandef); ++ + #endif /* __NET_CFG80211_H */ +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -88,67 +88,6 @@ MODULE_PARM_DESC(probe_wait_ms, + */ + #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 + +-struct ieee80211_per_bw_puncturing_values { +- u8 len; +- const u16 *valid_values; +-}; +- +-static const u16 puncturing_values_80mhz[] = { +- 0x8, 0x4, 0x2, 0x1 +-}; +- +-static const u16 puncturing_values_160mhz[] = { +- 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3 +-}; +- +-static const u16 puncturing_values_320mhz[] = { +- 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00, +- 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f, +- 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f +-}; +- +-#define IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \ +- { \ +- .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \ +- .valid_values = puncturing_values_ ## _bw ## mhz \ +- } +- +-static const struct ieee80211_per_bw_puncturing_values per_bw_puncturing[] = { +- IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(80), +- IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(160), +- IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(320) +-}; +- +-static bool ieee80211_valid_disable_subchannel_bitmap(u16 *bitmap, +- enum nl80211_chan_width bw) +-{ +- u32 idx, i; +- +- switch (bw) { +- case NL80211_CHAN_WIDTH_80: +- idx = 0; +- break; +- case NL80211_CHAN_WIDTH_160: +- idx = 1; +- break; +- case NL80211_CHAN_WIDTH_320: +- idx = 2; +- break; +- default: +- *bitmap = 0; +- break; +- } +- +- if (!*bitmap) +- return true; +- +- for (i = 0; i < per_bw_puncturing[idx].len; i++) +- if (per_bw_puncturing[idx].valid_values[i] == *bitmap) +- return true; +- +- return false; +-} +- + /* + * Extract from the given disabled subchannel bitmap (raw format + * from the EHT Operation Element) the bits for the subchannel +@@ -206,8 +145,8 @@ ieee80211_handle_puncturing_bitmap(struc + ieee80211_extract_dis_subch_bmap(eht_oper, chandef, + bitmap); + +- if (ieee80211_valid_disable_subchannel_bitmap(&bitmap, +- chandef->width)) ++ if (cfg80211_valid_disable_subchannel_bitmap(&bitmap, ++ chandef)) + break; + link->u.mgd.conn_flags |= + ieee80211_chandef_downgrade(chandef); +@@ -5584,8 +5523,8 @@ static bool ieee80211_config_puncturing( + extracted == link->conf->eht_puncturing) + return true; + +- if (!ieee80211_valid_disable_subchannel_bitmap(&bitmap, +- link->conf->chandef.width)) { ++ if (!cfg80211_valid_disable_subchannel_bitmap(&bitmap, ++ &link->conf->chandef)) { + link_info(link, + "Got an invalid disable subchannel bitmap from AP %pM: bitmap = 0x%x, bw = 0x%x. disconnect\n", + link->u.mgd.bssid, +@@ -7072,8 +7011,8 @@ ieee80211_setup_assoc_link(struct ieee80 + u16 bitmap; + + bitmap = get_unaligned_le16(disable_subchannel_bitmap); +- if (ieee80211_valid_disable_subchannel_bitmap(&bitmap, +- link->conf->chandef.width)) ++ if (cfg80211_valid_disable_subchannel_bitmap(&bitmap, ++ &link->conf->chandef)) + ieee80211_handle_puncturing_bitmap(link, + eht_oper, + bitmap, +--- a/net/wireless/chan.c ++++ b/net/wireless/chan.c +@@ -1505,3 +1505,72 @@ struct cfg80211_chan_def *wdev_chandef(s + } + } + EXPORT_SYMBOL(wdev_chandef); ++ ++struct cfg80211_per_bw_puncturing_values { ++ u8 len; ++ const u16 *valid_values; ++}; ++ ++static const u16 puncturing_values_80mhz[] = { ++ 0x8, 0x4, 0x2, 0x1 ++}; ++ ++static const u16 puncturing_values_160mhz[] = { ++ 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3 ++}; ++ ++static const u16 puncturing_values_320mhz[] = { ++ 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00, ++ 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f, ++ 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f ++}; ++ ++#define CFG80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \ ++ { \ ++ .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \ ++ .valid_values = puncturing_values_ ## _bw ## mhz \ ++ } ++ ++static const struct cfg80211_per_bw_puncturing_values per_bw_puncturing[] = { ++ CFG80211_PER_BW_VALID_PUNCTURING_VALUES(80), ++ CFG80211_PER_BW_VALID_PUNCTURING_VALUES(160), ++ CFG80211_PER_BW_VALID_PUNCTURING_VALUES(320) ++}; ++ ++bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap, ++ const struct cfg80211_chan_def *chandef) ++{ ++ u32 idx, i, start_freq; ++ ++ switch (chandef->width) { ++ case NL80211_CHAN_WIDTH_80: ++ idx = 0; ++ start_freq = chandef->center_freq1 - 40; ++ break; ++ case NL80211_CHAN_WIDTH_160: ++ idx = 1; ++ start_freq = chandef->center_freq1 - 80; ++ break; ++ case NL80211_CHAN_WIDTH_320: ++ idx = 2; ++ start_freq = chandef->center_freq1 - 160; ++ break; ++ default: ++ *bitmap = 0; ++ break; ++ } ++ ++ if (!*bitmap) ++ return true; ++ ++ /* check if primary channel is punctured */ ++ if (*bitmap & (u16)BIT((chandef->chan->center_freq - start_freq) / 20)) ++ return false; ++ ++ for (i = 0; i < per_bw_puncturing[idx].len; i++) ++ if (per_bw_puncturing[idx].valid_values[i] == *bitmap) ++ return true; ++ ++ return false; ++} ++EXPORT_SYMBOL(cfg80211_valid_disable_subchannel_bitmap); diff --git a/package/kernel/mac80211/patches/subsys/344-v6.3-0002-wifi-nl80211-validate-and-configure-puncturing-bitma.patch b/package/kernel/mac80211/patches/subsys/344-v6.3-0002-wifi-nl80211-validate-and-configure-puncturing-bitma.patch new file mode 100644 index 0000000000..6a84feeeba --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/344-v6.3-0002-wifi-nl80211-validate-and-configure-puncturing-bitma.patch @@ -0,0 +1,169 @@ +From d7c1a9a0ed180d8884798ce97afe7283622a484f Mon Sep 17 00:00:00 2001 +From: Aloka Dixit +Date: Mon, 30 Jan 2023 16:12:25 -0800 +Subject: [PATCH] wifi: nl80211: validate and configure puncturing bitmap + +- New feature flag, NL80211_EXT_FEATURE_PUNCT, to advertise + driver support for preamble puncturing in AP mode. +- New attribute, NL80211_ATTR_PUNCT_BITMAP, to receive a puncturing + bitmap from the userspace during AP bring up (NL80211_CMD_START_AP) + and channel switch (NL80211_CMD_CHANNEL_SWITCH) operations. Each bit + corresponds to a 20 MHz channel in the operating bandwidth, lowest + bit for the lowest channel. Bit set to 1 indicates that the channel + is punctured. Higher 16 bits are reserved. +- New members added to structures cfg80211_ap_settings and + cfg80211_csa_settings to propagate the bitmap to the driver after + validation. + +Signed-off-by: Aloka Dixit +Signed-off-by: Muna Sinada +Link: https://lore.kernel.org/r/20230131001227.25014-3-quic_alokad@quicinc.com +[move validation against 0xffff into policy] +Signed-off-by: Johannes Berg +--- + include/net/cfg80211.h | 8 ++++++++ + include/uapi/linux/nl80211.h | 11 +++++++++++ + net/wireless/nl80211.c | 32 ++++++++++++++++++++++++++++++++ + 3 files changed, 51 insertions(+) + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -1330,6 +1330,9 @@ struct cfg80211_unsol_bcast_probe_resp { + * @fils_discovery: FILS discovery transmission parameters + * @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters + * @mbssid_config: AP settings for multiple bssid ++ * @punct_bitmap: Preamble puncturing bitmap. Each bit represents ++ * a 20 MHz channel, lowest bit corresponding to the lowest channel. ++ * Bit set to 1 indicates that the channel is punctured. + */ + struct cfg80211_ap_settings { + struct cfg80211_chan_def chandef; +@@ -1364,6 +1367,7 @@ struct cfg80211_ap_settings { + struct cfg80211_fils_discovery fils_discovery; + struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp; + struct cfg80211_mbssid_config mbssid_config; ++ u16 punct_bitmap; + }; + + /** +@@ -1381,6 +1385,9 @@ struct cfg80211_ap_settings { + * @radar_required: whether radar detection is required on the new channel + * @block_tx: whether transmissions should be blocked while changing + * @count: number of beacons until switch ++ * @punct_bitmap: Preamble puncturing bitmap. Each bit represents ++ * a 20 MHz channel, lowest bit corresponding to the lowest channel. ++ * Bit set to 1 indicates that the channel is punctured. + */ + struct cfg80211_csa_settings { + struct cfg80211_chan_def chandef; +@@ -1393,6 +1400,7 @@ struct cfg80211_csa_settings { + bool radar_required; + bool block_tx; + u8 count; ++ u16 punct_bitmap; + }; + + /** +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -2751,6 +2751,12 @@ enum nl80211_commands { + * the incoming frame RX timestamp. + * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent + * (re)associations. ++ * ++ * @NL80211_ATTR_PUNCT_BITMAP: (u32) Preamble puncturing bitmap, lowest ++ * bit corresponds to the lowest 20 MHz channel. Each bit set to 1 ++ * indicates that the sub-channel is punctured. Higher 16 bits are ++ * reserved. ++ * + * @NUM_NL80211_ATTR: total number of nl80211_attrs available + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use +@@ -3280,6 +3286,8 @@ enum nl80211_attrs { + NL80211_ATTR_RX_HW_TIMESTAMP, + NL80211_ATTR_TD_BITMAP, + ++ NL80211_ATTR_PUNCT_BITMAP, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +@@ -6294,6 +6302,8 @@ enum nl80211_feature_flags { + * might apply, e.g. no scans in progress, no offchannel operations + * in progress, and no active connections. + * ++ * @NL80211_EXT_FEATURE_PUNCT: Driver supports preamble puncturing in AP mode. ++ * + * @NUM_NL80211_EXT_FEATURES: number of extended features. + * @MAX_NL80211_EXT_FEATURES: highest extended feature index. + */ +@@ -6362,6 +6372,7 @@ enum nl80211_ext_feature_index { + NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD, + NL80211_EXT_FEATURE_RADAR_BACKGROUND, + NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE, ++ NL80211_EXT_FEATURE_PUNCT, + + /* add new features before the definition below */ + NUM_NL80211_EXT_FEATURES, +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -799,6 +799,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN), + [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG }, + [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT }, ++ [NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff), + }; + + /* policy for the key attributes */ +@@ -3167,6 +3168,21 @@ static bool nl80211_can_set_dev_channel( + wdev->iftype == NL80211_IFTYPE_P2P_GO; + } + ++static int nl80211_parse_punct_bitmap(struct cfg80211_registered_device *rdev, ++ struct genl_info *info, ++ const struct cfg80211_chan_def *chandef, ++ u16 *punct_bitmap) ++{ ++ if (!wiphy_ext_feature_isset(&rdev->wiphy, NL80211_EXT_FEATURE_PUNCT)) ++ return -EINVAL; ++ ++ *punct_bitmap = nla_get_u32(info->attrs[NL80211_ATTR_PUNCT_BITMAP]); ++ if (!cfg80211_valid_disable_subchannel_bitmap(punct_bitmap, chandef)) ++ return -EINVAL; ++ ++ return 0; ++} ++ + int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, + struct genl_info *info, + struct cfg80211_chan_def *chandef) +@@ -5912,6 +5928,14 @@ static int nl80211_start_ap(struct sk_bu + goto out; + } + ++ if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) { ++ err = nl80211_parse_punct_bitmap(rdev, info, ++ ¶ms->chandef, ++ ¶ms->punct_bitmap); ++ if (err) ++ goto out; ++ } ++ + if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, ¶ms->chandef, + wdev->iftype)) { + err = -EINVAL; +@@ -10050,6 +10074,14 @@ skip_beacons: + if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) + params.block_tx = true; + ++ if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) { ++ err = nl80211_parse_punct_bitmap(rdev, info, ++ ¶ms.chandef, ++ ¶ms.punct_bitmap); ++ if (err) ++ goto free; ++ } ++ + wdev_lock(wdev); + err = rdev_channel_switch(rdev, dev, ¶ms); + wdev_unlock(wdev); diff --git a/package/kernel/mac80211/patches/subsys/344-v6.3-0003-wifi-cfg80211-include-puncturing-bitmap-in-channel-s.patch b/package/kernel/mac80211/patches/subsys/344-v6.3-0003-wifi-cfg80211-include-puncturing-bitmap-in-channel-s.patch new file mode 100644 index 0000000000..e3872f31f3 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/344-v6.3-0003-wifi-cfg80211-include-puncturing-bitmap-in-channel-s.patch @@ -0,0 +1,263 @@ +From b345f0637c0042f9e6b78378a32256d90f485774 Mon Sep 17 00:00:00 2001 +From: Aloka Dixit +Date: Mon, 30 Jan 2023 16:12:26 -0800 +Subject: [PATCH] wifi: cfg80211: include puncturing bitmap in channel switch + events + +Add puncturing bitmap in channel switch notifications +and corresponding trace functions. + +Signed-off-by: Aloka Dixit +Link: https://lore.kernel.org/r/20230131001227.25014-4-quic_alokad@quicinc.com +[fix qtnfmac] +Signed-off-by: Johannes Berg +--- + drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +- + drivers/net/wireless/marvell/mwifiex/11h.c | 2 +- + .../net/wireless/quantenna/qtnfmac/event.c | 2 +- + include/net/cfg80211.h | 6 +++-- + net/mac80211/cfg.c | 5 ++-- + net/mac80211/mlme.c | 4 ++-- + net/wireless/nl80211.c | 20 ++++++++++------ + net/wireless/trace.h | 24 ++++++++++++------- + 8 files changed, 41 insertions(+), 24 deletions(-) + +--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c ++++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c +@@ -1119,7 +1119,7 @@ void ath6kl_cfg80211_ch_switch_notify(st + NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT); + + mutex_lock(&vif->wdev.mtx); +- cfg80211_ch_switch_notify(vif->ndev, &chandef, 0); ++ cfg80211_ch_switch_notify(vif->ndev, &chandef, 0, 0); + mutex_unlock(&vif->wdev.mtx); + } + +--- a/drivers/net/wireless/marvell/mwifiex/11h.c ++++ b/drivers/net/wireless/marvell/mwifiex/11h.c +@@ -292,6 +292,6 @@ void mwifiex_dfs_chan_sw_work_queue(stru + mwifiex_dbg(priv->adapter, MSG, + "indicating channel switch completion to kernel\n"); + mutex_lock(&priv->wdev.mtx); +- cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef, 0); ++ cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef, 0, 0); + mutex_unlock(&priv->wdev.mtx); + } +--- a/drivers/net/wireless/quantenna/qtnfmac/event.c ++++ b/drivers/net/wireless/quantenna/qtnfmac/event.c +@@ -478,7 +478,7 @@ qtnf_event_handle_freq_change(struct qtn + continue; + + mutex_lock(&vif->wdev.mtx); +- cfg80211_ch_switch_notify(vif->netdev, &chandef, 0); ++ cfg80211_ch_switch_notify(vif->netdev, &chandef, 0, 0); + mutex_unlock(&vif->wdev.mtx); + } + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -8325,13 +8325,14 @@ bool cfg80211_reg_can_beacon_relax(struc + * @dev: the device which switched channels + * @chandef: the new channel definition + * @link_id: the link ID for MLO, must be 0 for non-MLO ++ * @punct_bitmap: the new puncturing bitmap + * + * Caller must acquire wdev_lock, therefore must only be called from sleepable + * driver context! + */ + void cfg80211_ch_switch_notify(struct net_device *dev, + struct cfg80211_chan_def *chandef, +- unsigned int link_id); ++ unsigned int link_id, u16 punct_bitmap); + + /* + * cfg80211_ch_switch_started_notify - notify channel switch start +@@ -8340,6 +8341,7 @@ void cfg80211_ch_switch_notify(struct ne + * @link_id: the link ID for MLO, must be 0 for non-MLO + * @count: the number of TBTTs until the channel switch happens + * @quiet: whether or not immediate quiet was requested by the AP ++ * @punct_bitmap: the future puncturing bitmap + * + * Inform the userspace about the channel switch that has just + * started, so that it can take appropriate actions (eg. starting +@@ -8348,7 +8350,7 @@ void cfg80211_ch_switch_notify(struct ne + void cfg80211_ch_switch_started_notify(struct net_device *dev, + struct cfg80211_chan_def *chandef, + unsigned int link_id, u8 count, +- bool quiet); ++ bool quiet, u16 punct_bitmap); + + /** + * ieee80211_operating_class_to_band - convert operating class to band +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -3600,7 +3600,8 @@ static int __ieee80211_csa_finalize(stru + if (err) + return err; + +- cfg80211_ch_switch_notify(sdata->dev, &sdata->deflink.csa_chandef, 0); ++ cfg80211_ch_switch_notify(sdata->dev, &sdata->deflink.csa_chandef, 0, ++ 0); + + return 0; + } +@@ -3872,7 +3873,7 @@ __ieee80211_channel_switch(struct wiphy + + cfg80211_ch_switch_started_notify(sdata->dev, + &sdata->deflink.csa_chandef, 0, +- params->count, params->block_tx); ++ params->count, params->block_tx, 0); + + if (changed) { + ieee80211_link_info_change_notify(sdata, &sdata->deflink, +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -1778,7 +1778,7 @@ static void ieee80211_chswitch_post_beac + return; + } + +- cfg80211_ch_switch_notify(sdata->dev, &link->reserved_chandef, 0); ++ cfg80211_ch_switch_notify(sdata->dev, &link->reserved_chandef, 0, 0); + } + + void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) +@@ -1988,7 +1988,7 @@ ieee80211_sta_process_chanswitch(struct + mutex_unlock(&local->mtx); + + cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef, 0, +- csa_ie.count, csa_ie.mode); ++ csa_ie.count, csa_ie.mode, 0); + + if (local->ops->channel_switch) { + /* use driver's channel switch callback */ +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -18973,7 +18973,7 @@ static void nl80211_ch_switch_notify(str + struct cfg80211_chan_def *chandef, + gfp_t gfp, + enum nl80211_commands notif, +- u8 count, bool quiet) ++ u8 count, bool quiet, u16 punct_bitmap) + { + struct wireless_dev *wdev = netdev->ieee80211_ptr; + struct sk_buff *msg; +@@ -19007,6 +19007,9 @@ static void nl80211_ch_switch_notify(str + goto nla_put_failure; + } + ++ if (nla_put_u32(msg, NL80211_ATTR_PUNCT_BITMAP, punct_bitmap)) ++ goto nla_put_failure; ++ + genlmsg_end(msg, hdr); + + genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, +@@ -19019,7 +19022,7 @@ static void nl80211_ch_switch_notify(str + + void cfg80211_ch_switch_notify(struct net_device *dev, + struct cfg80211_chan_def *chandef, +- unsigned int link_id) ++ unsigned int link_id, u16 punct_bitmap) + { + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; +@@ -19028,7 +19031,7 @@ void cfg80211_ch_switch_notify(struct ne + ASSERT_WDEV_LOCK(wdev); + WARN_INVALID_LINK_ID(wdev, link_id); + +- trace_cfg80211_ch_switch_notify(dev, chandef, link_id); ++ trace_cfg80211_ch_switch_notify(dev, chandef, link_id, punct_bitmap); + + switch (wdev->iftype) { + case NL80211_IFTYPE_STATION: +@@ -19056,14 +19059,15 @@ void cfg80211_ch_switch_notify(struct ne + cfg80211_sched_dfs_chan_update(rdev); + + nl80211_ch_switch_notify(rdev, dev, link_id, chandef, GFP_KERNEL, +- NL80211_CMD_CH_SWITCH_NOTIFY, 0, false); ++ NL80211_CMD_CH_SWITCH_NOTIFY, 0, false, ++ punct_bitmap); + } + EXPORT_SYMBOL(cfg80211_ch_switch_notify); + + void cfg80211_ch_switch_started_notify(struct net_device *dev, + struct cfg80211_chan_def *chandef, + unsigned int link_id, u8 count, +- bool quiet) ++ bool quiet, u16 punct_bitmap) + { + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; +@@ -19072,11 +19076,13 @@ void cfg80211_ch_switch_started_notify(s + ASSERT_WDEV_LOCK(wdev); + WARN_INVALID_LINK_ID(wdev, link_id); + +- trace_cfg80211_ch_switch_started_notify(dev, chandef, link_id); ++ trace_cfg80211_ch_switch_started_notify(dev, chandef, link_id, ++ punct_bitmap); ++ + + nl80211_ch_switch_notify(rdev, dev, link_id, chandef, GFP_KERNEL, + NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, +- count, quiet); ++ count, quiet, punct_bitmap); + } + EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); + +--- a/net/wireless/trace.h ++++ b/net/wireless/trace.h +@@ -3245,39 +3245,47 @@ TRACE_EVENT(cfg80211_chandef_dfs_require + TRACE_EVENT(cfg80211_ch_switch_notify, + TP_PROTO(struct net_device *netdev, + struct cfg80211_chan_def *chandef, +- unsigned int link_id), +- TP_ARGS(netdev, chandef, link_id), ++ unsigned int link_id, ++ u16 punct_bitmap), ++ TP_ARGS(netdev, chandef, link_id, punct_bitmap), + TP_STRUCT__entry( + NETDEV_ENTRY + CHAN_DEF_ENTRY + __field(unsigned int, link_id) ++ __field(u16, punct_bitmap) + ), + TP_fast_assign( + NETDEV_ASSIGN; + CHAN_DEF_ASSIGN(chandef); + __entry->link_id = link_id; ++ __entry->punct_bitmap = punct_bitmap; + ), +- TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ", link:%d", +- NETDEV_PR_ARG, CHAN_DEF_PR_ARG, __entry->link_id) ++ TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ", link:%d, punct_bitmap:%u", ++ NETDEV_PR_ARG, CHAN_DEF_PR_ARG, __entry->link_id, ++ __entry->punct_bitmap) + ); + + TRACE_EVENT(cfg80211_ch_switch_started_notify, + TP_PROTO(struct net_device *netdev, + struct cfg80211_chan_def *chandef, +- unsigned int link_id), +- TP_ARGS(netdev, chandef, link_id), ++ unsigned int link_id, ++ u16 punct_bitmap), ++ TP_ARGS(netdev, chandef, link_id, punct_bitmap), + TP_STRUCT__entry( + NETDEV_ENTRY + CHAN_DEF_ENTRY + __field(unsigned int, link_id) ++ __field(u16, punct_bitmap) + ), + TP_fast_assign( + NETDEV_ASSIGN; + CHAN_DEF_ASSIGN(chandef); + __entry->link_id = link_id; ++ __entry->punct_bitmap = punct_bitmap; + ), +- TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ", link:%d", +- NETDEV_PR_ARG, CHAN_DEF_PR_ARG, __entry->link_id) ++ TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ", link:%d, punct_bitmap:%u", ++ NETDEV_PR_ARG, CHAN_DEF_PR_ARG, __entry->link_id, ++ __entry->punct_bitmap) + ); + + TRACE_EVENT(cfg80211_radar_event, diff --git a/package/kernel/mac80211/patches/subsys/344-v6.3-0004-wifi-mac80211-configure-puncturing-bitmap.patch b/package/kernel/mac80211/patches/subsys/344-v6.3-0004-wifi-mac80211-configure-puncturing-bitmap.patch new file mode 100644 index 0000000000..06951b403d --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/344-v6.3-0004-wifi-mac80211-configure-puncturing-bitmap.patch @@ -0,0 +1,107 @@ +From 2cc25e4b2a04cdd90dbb2916678745565cc4aeed Mon Sep 17 00:00:00 2001 +From: Aloka Dixit +Date: Mon, 30 Jan 2023 16:12:27 -0800 +Subject: [PATCH] wifi: mac80211: configure puncturing bitmap + +- Configure the bitmap in link_conf and notify the driver. +- Modify 'change' in ieee80211_start_ap() from u32 to u64 to support +BSS_CHANGED_EHT_PUNCTURING. +- Propagate the bitmap in channel switch events to userspace. + +Signed-off-by: Aloka Dixit +Signed-off-by: Muna Sinada +Link: https://lore.kernel.org/r/20230131001227.25014-5-quic_alokad@quicinc.com +Signed-off-by: Johannes Berg +--- + include/net/mac80211.h | 3 +++ + net/mac80211/cfg.c | 22 +++++++++++++++++++--- + 2 files changed, 22 insertions(+), 3 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -645,6 +645,7 @@ struct ieee80211_fils_discovery { + * @csa_active: marks whether a channel switch is going on. Internally it is + * write-protected by sdata_lock and local->mtx so holding either is fine + * for read access. ++ * @csa_punct_bitmap: new puncturing bitmap for channel switch + * @mu_mimo_owner: indicates interface owns MU-MIMO capability + * @chanctx_conf: The channel context this interface is assigned to, or %NULL + * when it is not assigned. This pointer is RCU-protected due to the TX +@@ -744,6 +745,8 @@ struct ieee80211_bss_conf { + u16 eht_puncturing; + + bool csa_active; ++ u16 csa_punct_bitmap; ++ + bool mu_mimo_owner; + struct ieee80211_chanctx_conf __rcu *chanctx_conf; + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1220,7 +1220,7 @@ static int ieee80211_start_ap(struct wip + struct ieee80211_local *local = sdata->local; + struct beacon_data *old; + struct ieee80211_sub_if_data *vlan; +- u32 changed = BSS_CHANGED_BEACON_INT | ++ u64 changed = BSS_CHANGED_BEACON_INT | + BSS_CHANGED_BEACON_ENABLED | + BSS_CHANGED_BEACON | + BSS_CHANGED_P2P_PS | +@@ -1307,6 +1307,11 @@ static int ieee80211_start_ap(struct wip + IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO; + } + ++ if (params->eht_cap) { ++ link_conf->eht_puncturing = params->punct_bitmap; ++ changed |= BSS_CHANGED_EHT_PUNCTURING; ++ } ++ + if (sdata->vif.type == NL80211_IFTYPE_AP && + params->mbssid_config.tx_wdev) { + err = ieee80211_set_ap_mbssid_options(sdata, +@@ -3559,6 +3564,12 @@ static int __ieee80211_csa_finalize(stru + lockdep_assert_held(&local->mtx); + lockdep_assert_held(&local->chanctx_mtx); + ++ if (sdata->vif.bss_conf.eht_puncturing != sdata->vif.bss_conf.csa_punct_bitmap) { ++ sdata->vif.bss_conf.eht_puncturing = ++ sdata->vif.bss_conf.csa_punct_bitmap; ++ changed |= BSS_CHANGED_EHT_PUNCTURING; ++ } ++ + /* + * using reservation isn't immediate as it may be deferred until later + * with multi-vif. once reservation is complete it will re-schedule the +@@ -3601,7 +3612,7 @@ static int __ieee80211_csa_finalize(stru + return err; + + cfg80211_ch_switch_notify(sdata->dev, &sdata->deflink.csa_chandef, 0, +- 0); ++ sdata->vif.bss_conf.eht_puncturing); + + return 0; + } +@@ -3863,9 +3874,13 @@ __ieee80211_channel_switch(struct wiphy + goto out; + } + ++ if (params->punct_bitmap && !sdata->vif.bss_conf.eht_support) ++ goto out; ++ + sdata->deflink.csa_chandef = params->chandef; + sdata->deflink.csa_block_tx = params->block_tx; + sdata->vif.bss_conf.csa_active = true; ++ sdata->vif.bss_conf.csa_punct_bitmap = params->punct_bitmap; + + if (sdata->deflink.csa_block_tx) + ieee80211_stop_vif_queues(local, sdata, +@@ -3873,7 +3888,8 @@ __ieee80211_channel_switch(struct wiphy + + cfg80211_ch_switch_started_notify(sdata->dev, + &sdata->deflink.csa_chandef, 0, +- params->count, params->block_tx, 0); ++ params->count, params->block_tx, ++ sdata->vif.bss_conf.csa_punct_bitmap); + + if (changed) { + ieee80211_link_info_change_notify(sdata, &sdata->deflink, diff --git a/package/kernel/mac80211/patches/subsys/345-v6.4-wifi-mac80211-add-EHT-MU-MIMO-related-flags-in-ieee8.patch b/package/kernel/mac80211/patches/subsys/345-v6.4-wifi-mac80211-add-EHT-MU-MIMO-related-flags-in-ieee8.patch new file mode 100644 index 0000000000..607f86f295 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/345-v6.4-wifi-mac80211-add-EHT-MU-MIMO-related-flags-in-ieee8.patch @@ -0,0 +1,68 @@ +From f4d1181e4759c9c6c97c86cda2cf2d1ddb6a74d2 Mon Sep 17 00:00:00 2001 +From: Ryder Lee +Date: Sat, 18 Feb 2023 01:48:59 +0800 +Subject: [PATCH] wifi: mac80211: add EHT MU-MIMO related flags in + ieee80211_bss_conf + +Similar to VHT/HE. This is utilized to pass MU-MIMO configurations +from user space (i.e. hostapd) to driver. + +Signed-off-by: Ryder Lee +Link: https://lore.kernel.org/r/8d9966c4c1e77cb1ade77d42bdc49905609192e9.1676628065.git.ryder.lee@mediatek.com +[move into combined if statement, reset on !eht] +Signed-off-by: Johannes Berg +--- + include/net/mac80211.h | 9 +++++++++ + net/mac80211/cfg.c | 16 ++++++++++++++++ + 2 files changed, 25 insertions(+) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -676,6 +676,12 @@ struct ieee80211_fils_discovery { + * @he_full_ul_mumimo: does this BSS support the reception (AP) or transmission + * (non-AP STA) of an HE TB PPDU on an RU that spans the entire PPDU + * bandwidth ++ * @eht_su_beamformer: in AP-mode, does this BSS enable operation as an EHT SU ++ * beamformer ++ * @eht_su_beamformee: in AP-mode, does this BSS enable operation as an EHT SU ++ * beamformee ++ * @eht_mu_beamformer: in AP-mode, does this BSS enable operation as an EHT MU ++ * beamformer + */ + struct ieee80211_bss_conf { + const u8 *bssid; +@@ -764,6 +770,9 @@ struct ieee80211_bss_conf { + bool he_su_beamformee; + bool he_mu_beamformer; + bool he_full_ul_mumimo; ++ bool eht_su_beamformer; ++ bool eht_su_beamformee; ++ bool eht_mu_beamformer; + }; + + /** +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1310,6 +1310,22 @@ static int ieee80211_start_ap(struct wip + if (params->eht_cap) { + link_conf->eht_puncturing = params->punct_bitmap; + changed |= BSS_CHANGED_EHT_PUNCTURING; ++ ++ link_conf->eht_su_beamformer = ++ params->eht_cap->fixed.phy_cap_info[0] & ++ IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER; ++ link_conf->eht_su_beamformee = ++ params->eht_cap->fixed.phy_cap_info[0] & ++ IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE; ++ link_conf->eht_mu_beamformer = ++ params->eht_cap->fixed.phy_cap_info[7] & ++ (IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ | ++ IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ | ++ IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ); ++ } else { ++ link_conf->eht_su_beamformer = false; ++ link_conf->eht_su_beamformee = false; ++ link_conf->eht_mu_beamformer = false; + } + + if (sdata->vif.type == NL80211_IFTYPE_AP && diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch index 58a590682a..69b23acc79 100644 --- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch @@ -1,6 +1,6 @@ --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -4084,6 +4084,7 @@ struct mgmt_frame_regs { +@@ -4092,6 +4092,7 @@ struct mgmt_frame_regs { * (as advertised by the nl80211 feature flag.) * @get_tx_power: store the current TX power into the dbm variable; * return 0 if successful @@ -8,7 +8,7 @@ * * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting * functions to adjust rfkill hw state -@@ -4434,6 +4435,7 @@ struct cfg80211_ops { +@@ -4442,6 +4443,7 @@ struct cfg80211_ops { enum nl80211_tx_power_setting type, int mbm); int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); @@ -18,7 +18,7 @@ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1677,6 +1677,7 @@ enum ieee80211_smps_mode { +@@ -1705,6 +1705,7 @@ enum ieee80211_smps_mode { * * @power_level: requested transmit power (in dBm), backward compatibility * value only that is set to the minimum of all interfaces @@ -26,7 +26,7 @@ * * @chandef: the channel definition to tune to * @radar_enabled: whether radar detection is enabled -@@ -1697,6 +1698,7 @@ enum ieee80211_smps_mode { +@@ -1725,6 +1726,7 @@ enum ieee80211_smps_mode { struct ieee80211_conf { u32 flags; int power_level, dynamic_ps_timeout; @@ -36,19 +36,18 @@ u8 ps_dtim_period; --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h -@@ -2749,6 +2749,9 @@ enum nl80211_commands { - * When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the ack RX - * timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates - * the incoming frame RX timestamp. +@@ -2756,6 +2756,8 @@ enum nl80211_commands { + * bit corresponds to the lowest 20 MHz channel. Each bit set to 1 + * indicates that the sub-channel is punctured. Higher 16 bits are + * reserved. + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce + * transmit power to stay within regulatory limits. u32, dBi. -+ * + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3277,6 +3280,8 @@ enum nl80211_attrs { - NL80211_ATTR_TX_HW_TIMESTAMP, - NL80211_ATTR_RX_HW_TIMESTAMP, +@@ -3288,6 +3290,8 @@ enum nl80211_attrs { + + NL80211_ATTR_PUNCT_BITMAP, + NL80211_ATTR_WIPHY_ANTENNA_GAIN, + @@ -57,7 +56,7 @@ __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -3046,6 +3046,19 @@ static int ieee80211_get_tx_power(struct +@@ -3067,6 +3067,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -77,7 +76,7 @@ static void ieee80211_rfkill_poll(struct wiphy *wiphy) { struct ieee80211_local *local = wiphy_priv(wiphy); -@@ -4956,6 +4969,7 @@ const struct cfg80211_ops mac80211_confi +@@ -4989,6 +5002,7 @@ const struct cfg80211_ops mac80211_confi .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, @@ -129,15 +128,15 @@ local->hw.max_mtu = IEEE80211_MAX_DATA_LEN; --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -799,6 +799,7 @@ static const struct nla_policy nl80211_p - [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN), +@@ -800,6 +800,7 @@ static const struct nla_policy nl80211_p [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG }, [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT }, + [NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff), + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, }; /* policy for the key attributes */ -@@ -3511,6 +3512,22 @@ static int nl80211_set_wiphy(struct sk_b +@@ -3527,6 +3528,22 @@ static int nl80211_set_wiphy(struct sk_b if (result) goto out; } diff --git a/package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch b/package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch index 2bc11efd00..0e6e51884d 100644 --- a/package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch +++ b/package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch @@ -18,7 +18,7 @@ Signed-off-by: David Bauer --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -2422,6 +2422,13 @@ static void sta_stats_decode_rate(struct +@@ -2364,6 +2364,13 @@ static void sta_stats_decode_rate(struct sband = local->hw.wiphy->bands[band]; -- 2.25.1