mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-20 19:48:54 +00:00
mac80211: backport some upstream EHT patches
Those changes are needed by Wi-Fi 7 drivers. Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
parent
77b7c10884
commit
afe2ddf827
@ -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
|
||||
|
@ -0,0 +1,189 @@
|
||||
From 0ff57171d6d225558c81a69439d5323e35b40549 Mon Sep 17 00:00:00 2001
|
||||
From: Vinayak Yadawad <vinayak.yadawad@broadcom.com>
|
||||
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 <vinayak.yadawad@broadcom.com>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
.../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);
|
@ -0,0 +1,179 @@
|
||||
From f66c48af7a110c0d694c4ac4a1257affb272a2ea Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
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 <johannes.berg@intel.com>
|
||||
---
|
||||
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 <jbenc@suse.cz>
|
||||
* 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 <linux/module.h>
|
||||
@@ -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;
|
@ -0,0 +1,387 @@
|
||||
From aa87cd8b35736a5183745ab0ec4b82419024dfd7 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
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 <miriam.rachel.korenblit@intel.com>
|
||||
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
|
||||
Link: https://lore.kernel.org/r/20230127123930.4fbc74582331.I3547481d49f958389f59dfeba3fcc75e72b0aa6e@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
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 <flamingice@sourmilk.net>
|
||||
* 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 <linux/delay.h>
|
||||
@@ -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();
|
||||
|
@ -0,0 +1,219 @@
|
||||
From b25413fed3d43e1ed3340df4d928971bb8639f66 Mon Sep 17 00:00:00 2001
|
||||
From: Aloka Dixit <quic_alokad@quicinc.com>
|
||||
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 <quic_alokad@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230131001227.25014-2-quic_alokad@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
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);
|
@ -0,0 +1,169 @@
|
||||
From d7c1a9a0ed180d8884798ce97afe7283622a484f Mon Sep 17 00:00:00 2001
|
||||
From: Aloka Dixit <quic_alokad@quicinc.com>
|
||||
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 <quic_alokad@quicinc.com>
|
||||
Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230131001227.25014-3-quic_alokad@quicinc.com
|
||||
[move validation against 0xffff into policy]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
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);
|
@ -0,0 +1,263 @@
|
||||
From b345f0637c0042f9e6b78378a32256d90f485774 Mon Sep 17 00:00:00 2001
|
||||
From: Aloka Dixit <quic_alokad@quicinc.com>
|
||||
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 <quic_alokad@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230131001227.25014-4-quic_alokad@quicinc.com
|
||||
[fix qtnfmac]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
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,
|
@ -0,0 +1,107 @@
|
||||
From 2cc25e4b2a04cdd90dbb2916678745565cc4aeed Mon Sep 17 00:00:00 2001
|
||||
From: Aloka Dixit <quic_alokad@quicinc.com>
|
||||
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 <quic_alokad@quicinc.com>
|
||||
Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230131001227.25014-5-quic_alokad@quicinc.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
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,
|
@ -0,0 +1,68 @@
|
||||
From f4d1181e4759c9c6c97c86cda2cf2d1ddb6a74d2 Mon Sep 17 00:00:00 2001
|
||||
From: Ryder Lee <ryder.lee@mediatek.com>
|
||||
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 <ryder.lee@mediatek.com>
|
||||
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 <johannes.berg@intel.com>
|
||||
---
|
||||
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 &&
|
@ -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;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
|
||||
--- 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];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user