]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: cfg80211: Add support for link reconfiguration negotiation offload to driver
authorKavita Kavita <quic_kkavita@quicinc.com>
Wed, 4 Jun 2025 10:57:57 +0000 (16:27 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 20 Jun 2025 08:46:31 +0000 (10:46 +0200)
In the case of SME-in-driver, the driver can internally choose to
update the links based on the AP MLD recommendation and do link
reconfiguration negotiation with AP MLD.
(e.g., After the driver processing the BSS Transition Management request
frame received from the AP MLD with Neighbor Report containing
Multi-Link element with recommended links information chooses to do link
reconfiguration negotiation with AP MLD).

To support this, extend cfg80211_mlo_reconf_add_done() and
NL80211_CMD_ASSOC_MLO_RECONF to indicate added links information for
driver-initiated link reconfiguration requests. For removed links,
the driver indicates links information using the
NL80211_CMD_LINKS_REMOVED event for driver-initiated cases, the same as
supplicant initiated cases.

For the driver-initiated case, cfg80211 will receive link
reconfiguration result asynchronously from driver so holding BSSes of
the accepted add links is needed in the event path. Also, no need of
unhold call for the rejected add link BSSes since there was no hold call
happened previously.

Once the supplicant receives the NL80211_CMD_ASSOC_MLO_RECONF event,
it needs to process the information about newly added links and install
per-link group keys (e.g., GTK/IGTK/BIGTK etc.).

In case of the SME-in-driver, using a vendor interface etc. to notify
the supplicant to initiate a link reconfiguration request and then
supplicant sending command to the cfg80211 can lead to race conditions.
The correct design to avoid this is that the driver indicates the
cfg80211 directly with the results of the link reconfiguration
negotiation.

Signed-off-by: Kavita Kavita <quic_kkavita@quicinc.com>
Link: https://patch.msgid.link/20250604105757.2542-3-quic_kkavita@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/mlme.c
net/wireless/trace.h

index 7719a90ab4d75045983ac8a63360fd90472cbb7d..47b4235eea59ec33d646817746cadedbd51273dd 100644 (file)
@@ -9747,6 +9747,11 @@ void cfg80211_links_removed(struct net_device *dev, u16 link_mask);
  * struct cfg80211_mlo_reconf_done_data - MLO reconfiguration data
  * @buf: MLO Reconfiguration Response frame (header + body)
  * @len: length of the frame data
+ * @driver_initiated: Indicates whether the add links request is initiated by
+ *     driver. This is set to true when the link reconfiguration request
+ *     initiated by driver due to AP link recommendation requests
+ *     (Ex: BTM (BSS Transition Management) request) handling offloaded to
+ *     driver.
  * @added_links: BIT mask of links successfully added to the association
  * @links: per-link information indexed by link ID
  * @links.bss: the BSS that MLO reconfiguration was requested for, ownership of
@@ -9759,6 +9764,7 @@ void cfg80211_links_removed(struct net_device *dev, u16 link_mask);
 struct cfg80211_mlo_reconf_done_data {
        const u8 *buf;
        size_t len;
+       bool driver_initiated;
        u16 added_links;
        struct {
                struct cfg80211_bss *bss;
index e53840d009d119f5f1c665487b2e6299e5e4846b..a289014abe37df882e8c63ca3c41b0e8dff3f030 100644 (file)
  *      reconfiguration request results from the driver, this command is also
  *      used as an event to notify userspace about the added links information.
  *      For notifying the removed links information, the existing
- *      %NL80211_CMD_LINKS_REMOVED command is used.
+ *      %NL80211_CMD_LINKS_REMOVED command is used. This command is also used to
+ *      notify userspace about newly added links for the current connection in
+ *      case of AP-initiated link recommendation requests, received via
+ *      a BTM (BSS Transition Management) request or a link reconfig notify
+ *      frame, where the driver handles the link recommendation offload.
  *
  * @NL80211_CMD_EPCS_CFG: EPCS configuration for a station. Used by userland to
  *     control EPCS configuration. Used to notify userland on the current state
index 05d44a4435189cf4c08fb2fa950859ff2d648279..29e1ce8aff42cfbc3bd3f41724439c9205b02978 100644 (file)
@@ -1331,7 +1331,8 @@ void cfg80211_mlo_reconf_add_done(struct net_device *dev,
        lockdep_assert_wiphy(wiphy);
 
        trace_cfg80211_mlo_reconf_add_done(dev, data->added_links,
-                                          data->buf, data->len);
+                                          data->buf, data->len,
+                                          data->driver_initiated);
 
        if (WARN_ON(!wdev->valid_links))
                return;
@@ -1361,11 +1362,16 @@ void cfg80211_mlo_reconf_add_done(struct net_device *dev,
                        wdev->links[link_id].client.current_bss =
                                bss_from_pub(bss);
 
+                       if (data->driver_initiated)
+                               cfg80211_hold_bss(bss_from_pub(bss));
+
                        memcpy(wdev->links[link_id].addr,
                               data->links[link_id].addr,
                               ETH_ALEN);
                } else {
-                       cfg80211_unhold_bss(bss_from_pub(bss));
+                       if (!data->driver_initiated)
+                               cfg80211_unhold_bss(bss_from_pub(bss));
+
                        cfg80211_put_bss(wiphy, bss);
                }
        }
index 4ed9fada4ec0e9c19a23676890d424dc0ec0661b..61a5eca9c513753be5fc9bac065f78dd2f722197 100644 (file)
@@ -4126,20 +4126,22 @@ TRACE_EVENT(cfg80211_links_removed,
 
 TRACE_EVENT(cfg80211_mlo_reconf_add_done,
        TP_PROTO(struct net_device *netdev, u16 link_mask,
-                const u8 *buf, size_t len),
-       TP_ARGS(netdev, link_mask, buf, len),
+                const u8 *buf, size_t len, bool driver_initiated),
+       TP_ARGS(netdev, link_mask, buf, len, driver_initiated),
        TP_STRUCT__entry(
                NETDEV_ENTRY
                __field(u16, link_mask)
                __dynamic_array(u8, buf, len)
+               __field(bool, driver_initiated)
        ),
        TP_fast_assign(
                NETDEV_ASSIGN;
                __entry->link_mask = link_mask;
                memcpy(__get_dynamic_array(buf), buf, len);
+               __entry->driver_initiated = driver_initiated;
        ),
-       TP_printk(NETDEV_PR_FMT ", link_mask:0x%x",
-                 NETDEV_PR_ARG, __entry->link_mask)
+       TP_printk(NETDEV_PR_FMT ", link_mask:0x%x, driver_initiated:%d",
+                 NETDEV_PR_ARG, __entry->link_mask, __entry->driver_initiated)
 );
 
 TRACE_EVENT(rdev_assoc_ml_reconf,