]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: nl80211: Add a notification to notify NAN channel evacuation
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Wed, 18 Mar 2026 12:39:24 +0000 (14:39 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 25 Mar 2026 19:56:55 +0000 (20:56 +0100)
If all available channel resources are used for NAN channels, and one of
them is shared with another interface, and that interface needs to move
to a different channel (for example STA interface that needs to do a
channel or a link switch), then the driver can evacuate one of the NAN
channels (i.e. detach it from its channel resource and announce to the
peers that this channel is ULWed). In that case, the driver needs to
notify user space about the channel evacuation, so the user space can
adjust the local schedule accordingly.

Add a notification to let userspace know about it.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260219114327.d5bebfd5ff73.Iaaf5ef17e1ab7a38c19d60558e68fcf517e2b400@changeid
Link: https://patch.msgid.link/20260318123926.206536-11-miriam.rachel.korenblit@intel.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/nl80211.c
net/wireless/trace.h

index ee173f69c417aa9eb1216647a0afd9095ebe880e..9d3639ff9c28e7123f1866d646e02cff2cb538fc 100644 (file)
@@ -10588,6 +10588,25 @@ void cfg80211_nan_cluster_joined(struct wireless_dev *wdev,
 void cfg80211_nan_ulw_update(struct wireless_dev *wdev,
                             const u8 *ulw, size_t ulw_len, gfp_t gfp);
 
+/**
+ * cfg80211_nan_channel_evac - Notify user space about NAN channel evacuation
+ * @wdev: Pointer to the wireless device structure
+ * @chandef: Pointer to the channel definition of the NAN channel that was
+ *     evacuated
+ * @gfp: Memory allocation flags
+ *
+ * This function is used by drivers to notify user space when a NAN
+ * channel has been evacuated (i.e. ULWed) due to channel resource conflicts
+ * with other interfaces.
+ * This can happen when another interface sharing the channel resource with NAN
+ * needs to move to a different channel (e.g. due to channel switch or link
+ * switch). User space may reconfigure the local schedule to exclude the
+ * evacuated channel.
+ */
+void cfg80211_nan_channel_evac(struct wireless_dev *wdev,
+                              const struct cfg80211_chan_def *chandef,
+                              gfp_t gfp);
+
 #ifdef CONFIG_CFG80211_DEBUGFS
 /**
  * wiphy_locked_debugfs_read - do a locked read in debugfs
index 947ec7079484d9788ad72c85a4d5fa6c0d18e25c..3d55bf4be36fe5f55b8e7171c825c476f56c9926 100644 (file)
  *     with the updated ULW blob of the device. User space can use this blob
  *     to attach to frames sent to peers. This notification contains
  *     %NL80211_ATTR_NAN_ULW with the ULW blob.
+ * @NL80211_CMD_NAN_CHANNEL_EVAC: Notification to indicate that a NAN
+ *     channel has been evacuated due to resource conflicts with other
+ *     interfaces. This can happen when another interface sharing the channel
+ *     resource with NAN needs to move to a different channel (e.g., channel
+ *     switch or link switch on a BSS interface).
+ *     The notification contains %NL80211_ATTR_NAN_CHANNEL attribute
+ *     identifying the evacuated channel.
+ *     User space may reconfigure the local schedule in response to this
+ *     notification.
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1678,6 +1687,9 @@ enum nl80211_commands {
        NL80211_CMD_NAN_SET_PEER_SCHED,
 
        NL80211_CMD_NAN_ULW_UPDATE,
+
+       NL80211_CMD_NAN_CHANNEL_EVAC,
+
        /* add new commands above here */
 
        /* used to define NL80211_CMD_MAX below */
@@ -3040,20 +3052,23 @@ enum nl80211_commands {
  *     Currently only supported in mac80211 drivers.
  * @NL80211_ATTR_NAN_CHANNEL: This is a nested attribute. There can be multiple
  *     attributes of this type, each one represents a channel definition and
- *     consists of top-level attributes like %NL80211_ATTR_WIPHY_FREQ. Must
- *     contain %NL80211_ATTR_NAN_CHANNEL_ENTRY and
- *     %NL80211_ATTR_NAN_RX_NSS.
- *     This attribute is used with %NL80211_CMD_NAN_SET_LOCAL_SCHED to specify
+ *     consists of top-level attributes like %NL80211_ATTR_WIPHY_FREQ.
+ *     When used with %NL80211_CMD_NAN_SET_LOCAL_SCHED, it specifies
  *     the channel definitions on which the radio needs to operate during
  *     specific time slots. All of the channel definitions should be mutually
- *     incompatible.
- *     This is also used with %NL80211_CMD_NAN_SET_PEER_SCHED to configure the
+ *     incompatible. With this command, %NL80211_ATTR_NAN_CHANNEL_ENTRY and
+ *     %NL80211_ATTR_NAN_RX_NSS are mandatory.
+ *     When used with %NL80211_CMD_NAN_SET_PEER_SCHED, it configures the
  *     peer NAN channels. In that case, the channel definitions can be
  *     compatible to each other, or even identical just with different RX NSS.
+ *     With this command, %NL80211_ATTR_NAN_CHANNEL_ENTRY and
+ *     %NL80211_ATTR_NAN_RX_NSS are mandatory.
  *     The number of channels should fit the current configuration of channels
  *     and the possible interface combinations.
  *     If an existing NAN channel is changed but the chandef isn't, the
  *     channel entry must also remain unchanged.
+ *     When used with %NL80211_CMD_NAN_CHANNEL_EVAC, this identifies the
+ *     channels that were evacuated.
  * @NL80211_ATTR_NAN_CHANNEL_ENTRY: a byte array of 6 bytes. contains the
  *     Channel Entry as defined in Wi-Fi Aware (TM) 4.0 specification Table
  *     100 (Channel Entry format for the NAN Availability attribute).
index b5185655e6878dccf1d6396174d109c8b7af011c..d65ebba0970bf462b06b1a5dbab9163640b129d1 100644 (file)
@@ -22936,6 +22936,54 @@ void cfg80211_nan_ulw_update(struct wireless_dev *wdev,
 }
 EXPORT_SYMBOL(cfg80211_nan_ulw_update);
 
+void cfg80211_nan_channel_evac(struct wireless_dev *wdev,
+                              const struct cfg80211_chan_def *chandef,
+                              gfp_t gfp)
+{
+       struct wiphy *wiphy = wdev->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+       struct sk_buff *msg;
+       struct nlattr *chan_attr;
+       void *hdr;
+
+       trace_cfg80211_nan_channel_evac(wiphy, wdev, chandef);
+
+       if (!wdev->owner_nlportid)
+               return;
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_CHANNEL_EVAC);
+       if (!hdr)
+               goto nla_put_failure;
+
+       if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+           nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+                             NL80211_ATTR_PAD))
+               goto nla_put_failure;
+
+       chan_attr = nla_nest_start(msg, NL80211_ATTR_NAN_CHANNEL);
+       if (!chan_attr)
+               goto nla_put_failure;
+
+       if (nl80211_send_chandef(msg, chandef))
+               goto nla_put_failure;
+
+       nla_nest_end(msg, chan_attr);
+
+       genlmsg_end(msg, hdr);
+
+       genlmsg_unicast(wiphy_net(wiphy), msg, wdev->owner_nlportid);
+
+       return;
+
+ nla_put_failure:
+       nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_nan_channel_evac);
+
 /* initialisation/exit functions */
 
 int __init nl80211_init(void)
index 061bb84f1a488afe9960e1e30a5751226ee6c9d8..eb5bedf9c92a4366414df2a25a4e175883be3f98 100644 (file)
@@ -4363,6 +4363,24 @@ TRACE_EVENT(cfg80211_nan_ulw_update,
                  __print_array(__get_dynamic_array(ulw),
                                __get_dynamic_array_len(ulw), 1))
 );
+
+TRACE_EVENT(cfg80211_nan_channel_evac,
+       TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+                const struct cfg80211_chan_def *chandef),
+       TP_ARGS(wiphy, wdev, chandef),
+       TP_STRUCT__entry(
+               WDEV_ENTRY
+               WIPHY_ENTRY
+               CHAN_DEF_ENTRY
+       ),
+       TP_fast_assign(
+               WDEV_ASSIGN;
+               WIPHY_ASSIGN;
+               CHAN_DEF_ASSIGN(chandef);
+       ),
+       TP_printk(WDEV_PR_FMT ", " WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
+                 WDEV_PR_ARG, WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
+);
 #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH