Thread (3 messages) 3 messages, 1 author, 14d ago
DORMANTno replies
Revisions (2)
  1. v1 [diff vs current]
  2. v2 current

[PATCH wireless-next v2 1/2] wifi: nl80211/cfg80211: Add MCST value to channel switch started notification

From: Shashikala Prabhu <hidden>
Date: 2026-07-06 08:39:11
Subsystem: 802.11 (including cfg80211/nl80211), the rest · Maintainers: Johannes Berg, Linus Torvalds

From: Chandru Gopi <redacted>

IEEE Std 802.11-2024 subclause 9.4.2.216 (Max Channel Switch Time element)
defines a Switch Time field in the Channel Switch Announcement (CSA)
element that indicates the time delta between the time the last beacon
is transmitted by the AP in the current channel and the expected time
of the first beacon transmitted by the AP in the new channel.

Add a new u32 nl80211 attribute, NL80211_ATTR_MAX_CH_SWITCH_TIME,
and extend cfg80211_ch_switch_started_notify() to carry this
value. The value is forwarded to userspace via the
NL80211_CMD_CH_SWITCH_STARTED_NOTIFY event. Userspace can use this
information to decide whether to remain connected or disconnect
before the AP moves to the new channel.

Signed-off-by: Chandru Gopi <redacted>
Signed-off-by: Shashikala Prabhu <redacted>
---
 include/net/cfg80211.h       |  4 +++-
 include/uapi/linux/nl80211.h | 11 +++++++++++
 net/wireless/nl80211.c       | 13 +++++++++----
 3 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 8188ad200de5..93ce6bf4d385 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -9987,6 +9987,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
  * @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
+ * @mcst_tu: max channel switch time in TUs, 0 if the MCST element was not
+ *	present
  *
  * Inform the userspace about the channel switch that has just
  * started, so that it can take appropriate actions (eg. starting
@@ -9995,7 +9997,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
 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, u32 mcst_tu);
 
 /**
  * ieee80211_operating_class_to_band - convert operating class to band
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 9998f6c0a665..daee71bcf9cd 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -953,6 +953,10 @@
  *	after %NL80211_ATTR_CH_SWITCH_COUNT TBTT's.  The userspace may
  *	decide to react to this indication by requesting other
  *	interfaces to change channel as well.
+ *	%NL80211_ATTR_MAX_CH_SWITCH_TIME included in this command indicates the
+ *	AP's Max Channel Switch Time. Userspace can use this information to
+ *	decide whether to remain connected or disconnect before the AP moves to
+ *	the new channel.
  *
  * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by
  *	its %NL80211_ATTR_WDEV identifier. It must have been created with
@@ -3165,6 +3169,12 @@ enum nl80211_commands {
  * @NL80211_ATTR_NPCA_PRIMARY_FREQ: NPCA primary channel (u32)
  * @NL80211_ATTR_NPCA_PUNCT_BITMAP: NPCA puncturing bitmap (u32)
  *
+ * @NL80211_ATTR_MAX_CH_SWITCH_TIME: u32 attribute carrying the Switch Time
+ *	field from the MCST (Max Channel Switch Time) element, indicating the
+ *	time delta between the time the last beacon is transmitted by the AP in
+ *	the current channel and the expected time of the first beacon
+ *	transmitted by the AP in the new channel, expressed in TUs.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3762,6 +3772,7 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_NPCA_PRIMARY_FREQ,
 	NL80211_ATTR_NPCA_PUNCT_BITMAP,
+	NL80211_ATTR_MAX_CH_SWITCH_TIME,
 
 	/* add attributes here, update the policy in nl80211.c */
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 53b4b3f76697..b6bc5e395a7f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -22290,7 +22290,8 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
 				     struct cfg80211_chan_def *chandef,
 				     gfp_t gfp,
 				     enum nl80211_commands notif,
-				     u8 count, bool quiet)
+				     u8 count, bool quiet,
+				     u32 mcst_tu)
 {
 	struct wireless_dev *wdev = netdev->ieee80211_ptr;
 	struct sk_buff *msg;
@@ -22322,6 +22323,10 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
 		if (quiet &&
 		    nla_put_flag(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX))
 			goto nla_put_failure;
+		if (mcst_tu && (wdev->iftype == NL80211_IFTYPE_STATION ||
+				wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
+		    nla_put_u32(msg, NL80211_ATTR_MAX_CH_SWITCH_TIME, mcst_tu))
+			goto nla_put_failure;
 	}
 
 	genlmsg_end(msg, hdr);
@@ -22374,7 +22379,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
 	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, 0);
 }
 EXPORT_SYMBOL(cfg80211_ch_switch_notify);
 
@@ -22421,7 +22426,7 @@ EXPORT_SYMBOL(cfg80211_incumbent_signal_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, u32 mcst_tu)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
@@ -22435,7 +22440,7 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev,
 
 	nl80211_ch_switch_notify(rdev, dev, link_id, chandef, GFP_KERNEL,
 				 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY,
-				 count, quiet);
+				 count, quiet, mcst_tu);
 }
 EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
 
-- 
2.34.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help