3
0
Fork 0
forked from mirrors/linux

wifi: cfg80211: move link reconfig parameters into a struct

Add a new struct cfg80211_ml_reconf_req to collect the link
reconfiguration parameters.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250308225541.0cf299c1fdd0.Id1a3b1092dc52d0d3731a8798522fdf2e052bf0b@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2025-03-08 23:03:27 +02:00
parent fc56639937
commit a096a8602f
9 changed files with 67 additions and 65 deletions

View file

@ -7,7 +7,7 @@
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright 2015-2017 Intel Deutschland GmbH * Copyright 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018-2024 Intel Corporation * Copyright (C) 2018-2025 Intel Corporation
*/ */
#include <linux/ethtool.h> #include <linux/ethtool.h>
@ -3082,6 +3082,16 @@ struct cfg80211_assoc_link {
int error; int error;
}; };
/**
* struct cfg80211_ml_reconf_req - MLO link reconfiguration request
* @add_links: data for links to add, see &struct cfg80211_assoc_link
* @rem_links: bitmap of links to remove
*/
struct cfg80211_ml_reconf_req {
struct cfg80211_assoc_link add_links[IEEE80211_MLD_MAX_NUM_LINKS];
u16 rem_links;
};
/** /**
* enum cfg80211_assoc_req_flags - Over-ride default behaviour in association. * enum cfg80211_assoc_req_flags - Over-ride default behaviour in association.
* *
@ -4972,8 +4982,7 @@ struct cfg80211_ops {
struct cfg80211_ttlm_params *params); struct cfg80211_ttlm_params *params);
u32 (*get_radio_mask)(struct wiphy *wiphy, struct net_device *dev); u32 (*get_radio_mask)(struct wiphy *wiphy, struct net_device *dev);
int (*assoc_ml_reconf)(struct wiphy *wiphy, struct net_device *dev, int (*assoc_ml_reconf)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_assoc_link *add_links, struct cfg80211_ml_reconf_req *req);
u16 rem_links);
int (*set_epcs)(struct wiphy *wiphy, struct net_device *dev, int (*set_epcs)(struct wiphy *wiphy, struct net_device *dev,
bool val); bool val);
}; };

View file

@ -5,7 +5,7 @@
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2015 Intel Mobile Communications GmbH * Copyright 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018-2024 Intel Corporation * Copyright (C) 2018-2025 Intel Corporation
*/ */
#include <linux/ieee80211.h> #include <linux/ieee80211.h>
@ -5185,14 +5185,13 @@ ieee80211_set_ttlm(struct wiphy *wiphy, struct net_device *dev,
static int static int
ieee80211_assoc_ml_reconf(struct wiphy *wiphy, struct net_device *dev, ieee80211_assoc_ml_reconf(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_assoc_link *add_links, struct cfg80211_ml_reconf_req *req)
u16 rem_links)
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
lockdep_assert_wiphy(sdata->local->hw.wiphy); lockdep_assert_wiphy(sdata->local->hw.wiphy);
return ieee80211_mgd_assoc_ml_reconf(sdata, add_links, rem_links); return ieee80211_mgd_assoc_ml_reconf(sdata, req);
} }
static int static int

View file

@ -5,7 +5,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2015 Intel Mobile Communications GmbH * Copyright 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2018-2024 Intel Corporation * Copyright (C) 2018-2025 Intel Corporation
*/ */
#ifndef IEEE80211_I_H #ifndef IEEE80211_I_H
@ -2789,8 +2789,7 @@ void ieee80211_process_epcs_teardown(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len); struct ieee80211_mgmt *mgmt, size_t len);
int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata, int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
struct cfg80211_assoc_link *add_links, struct cfg80211_ml_reconf_req *req);
u16 rem_links);
void ieee80211_process_ml_reconf_resp(struct ieee80211_sub_if_data *sdata, void ieee80211_process_ml_reconf_resp(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len); struct ieee80211_mgmt *mgmt, size_t len);

View file

@ -10362,8 +10362,7 @@ ieee80211_build_ml_reconf_req(struct ieee80211_sub_if_data *sdata,
} }
int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata, int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
struct cfg80211_assoc_link *add_links, struct cfg80211_ml_reconf_req *req)
u16 rem_links)
{ {
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct ieee80211_mgd_assoc_data *data = NULL; struct ieee80211_mgd_assoc_data *data = NULL;
@ -10383,9 +10382,8 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
return -EBUSY; return -EBUSY;
added_links = 0; added_links = 0;
for (link_id = 0; add_links && link_id < IEEE80211_MLD_MAX_NUM_LINKS; for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
link_id++) { if (!req->add_links[link_id].bss)
if (!add_links[link_id].bss)
continue; continue;
added_links |= BIT(link_id); added_links |= BIT(link_id);
@ -10413,7 +10411,8 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
link_id++) { link_id++) {
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct cfg80211_bss *link_cbss = add_links[link_id].bss; struct cfg80211_bss *link_cbss =
req->add_links[link_id].bss;
struct ieee80211_bss *bss; struct ieee80211_bss *bss;
if (!link_cbss) if (!link_cbss)
@ -10443,11 +10442,11 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
data->link[link_id].bss = link_cbss; data->link[link_id].bss = link_cbss;
data->link[link_id].disabled = data->link[link_id].disabled =
add_links[link_id].disabled; req->add_links[link_id].disabled;
data->link[link_id].elems = data->link[link_id].elems =
(u8 *)add_links[link_id].elems; (u8 *)req->add_links[link_id].elems;
data->link[link_id].elems_len = data->link[link_id].elems_len =
add_links[link_id].elems_len; req->add_links[link_id].elems_len;
if (!bss->uapsd_supported) if (!bss->uapsd_supported)
uapsd_supported = false; uapsd_supported = false;
@ -10497,10 +10496,11 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
* Section 35.3.6.4 in Draft P802.11be_D7.0 the AP MLD should accept the * Section 35.3.6.4 in Draft P802.11be_D7.0 the AP MLD should accept the
* link removal request. * link removal request.
*/ */
if (rem_links) { if (req->rem_links) {
u16 new_active_links = sdata->vif.active_links & ~rem_links; u16 new_active_links =
sdata->vif.active_links & ~req->rem_links;
new_valid_links = sdata->vif.valid_links & ~rem_links; new_valid_links = sdata->vif.valid_links & ~req->rem_links;
/* Should not be left with no valid links to perform the /* Should not be left with no valid links to perform the
* ML reconfiguration * ML reconfiguration
@ -10535,14 +10535,15 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
* is expected to send the ML reconfiguration response frame on the link * is expected to send the ML reconfiguration response frame on the link
* on which the request was received. * on which the request was received.
*/ */
skb = ieee80211_build_ml_reconf_req(sdata, data, rem_links); skb = ieee80211_build_ml_reconf_req(sdata, data, req->rem_links);
if (!skb) { if (!skb) {
err = -ENOMEM; err = -ENOMEM;
goto err_free; goto err_free;
} }
if (rem_links) { if (req->rem_links) {
u16 new_dormant_links = sdata->vif.dormant_links & ~rem_links; u16 new_dormant_links =
sdata->vif.dormant_links & ~req->rem_links;
err = ieee80211_vif_set_links(sdata, new_valid_links, err = ieee80211_vif_set_links(sdata, new_valid_links,
new_dormant_links); new_dormant_links);
@ -10555,7 +10556,7 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
link_id++) { link_id++) {
if (!(rem_links & BIT(link_id))) if (!(req->rem_links & BIT(link_id)))
continue; continue;
ieee80211_sta_remove_link(sta, link_id); ieee80211_sta_remove_link(sta, link_id);
@ -10564,17 +10565,17 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
/* notify the driver and upper layers */ /* notify the driver and upper layers */
ieee80211_vif_cfg_change_notify(sdata, ieee80211_vif_cfg_change_notify(sdata,
BSS_CHANGED_MLD_VALID_LINKS); BSS_CHANGED_MLD_VALID_LINKS);
cfg80211_links_removed(sdata->dev, rem_links); cfg80211_links_removed(sdata->dev, req->rem_links);
} }
sdata_info(sdata, "mlo: reconf: adding=0x%x, removed=0x%x\n", sdata_info(sdata, "mlo: reconf: adding=0x%x, removed=0x%x\n",
added_links, rem_links); added_links, req->rem_links);
ieee80211_tx_skb(sdata, skb); ieee80211_tx_skb(sdata, skb);
sdata->u.mgd.reconf.added_links = added_links; sdata->u.mgd.reconf.added_links = added_links;
sdata->u.mgd.reconf.add_links_data = data; sdata->u.mgd.reconf.add_links_data = data;
sdata->u.mgd.reconf.removed_links = rem_links; sdata->u.mgd.reconf.removed_links = req->rem_links;
wiphy_delayed_work_queue(sdata->local->hw.wiphy, wiphy_delayed_work_queue(sdata->local->hw.wiphy,
&sdata->u.mgd.reconf.wk, &sdata->u.mgd.reconf.wk,
IEEE80211_ASSOC_TIMEOUT_SHORT); IEEE80211_ASSOC_TIMEOUT_SHORT);

View file

@ -3,7 +3,7 @@
* Wireless configuration interface internals. * Wireless configuration interface internals.
* *
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright (C) 2018-2024 Intel Corporation * Copyright (C) 2018-2025 Intel Corporation
*/ */
#ifndef __NET_WIRELESS_CORE_H #ifndef __NET_WIRELESS_CORE_H
#define __NET_WIRELESS_CORE_H #define __NET_WIRELESS_CORE_H
@ -568,8 +568,8 @@ void cfg80211_wdev_release_link_bsses(struct wireless_dev *wdev, u16 link_mask);
int cfg80211_assoc_ml_reconf(struct cfg80211_registered_device *rdev, int cfg80211_assoc_ml_reconf(struct cfg80211_registered_device *rdev,
struct net_device *dev, struct net_device *dev,
struct cfg80211_assoc_link *links, struct cfg80211_ml_reconf_req *req);
u16 rem_links);
/** /**
* struct cfg80211_colocated_ap - colocated AP information * struct cfg80211_colocated_ap - colocated AP information
* *

View file

@ -4,7 +4,7 @@
* *
* Copyright (c) 2009, Jouni Malinen <j@w1.fi> * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
* Copyright (c) 2015 Intel Deutschland GmbH * Copyright (c) 2015 Intel Deutschland GmbH
* Copyright (C) 2019-2020, 2022-2024 Intel Corporation * Copyright (C) 2019-2020, 2022-2025 Intel Corporation
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
@ -1297,25 +1297,24 @@ void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev)
int cfg80211_assoc_ml_reconf(struct cfg80211_registered_device *rdev, int cfg80211_assoc_ml_reconf(struct cfg80211_registered_device *rdev,
struct net_device *dev, struct net_device *dev,
struct cfg80211_assoc_link *links, struct cfg80211_ml_reconf_req *req)
u16 rem_links)
{ {
struct wireless_dev *wdev = dev->ieee80211_ptr; struct wireless_dev *wdev = dev->ieee80211_ptr;
int err; int err;
lockdep_assert_wiphy(wdev->wiphy); lockdep_assert_wiphy(wdev->wiphy);
err = rdev_assoc_ml_reconf(rdev, dev, links, rem_links); err = rdev_assoc_ml_reconf(rdev, dev, req);
if (!err) { if (!err) {
int link_id; int link_id;
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
link_id++) { link_id++) {
if (!links[link_id].bss) if (!req->add_links[link_id].bss)
continue; continue;
cfg80211_ref_bss(&rdev->wiphy, links[link_id].bss); cfg80211_ref_bss(&rdev->wiphy, req->add_links[link_id].bss);
cfg80211_hold_bss(bss_from_pub(links[link_id].bss)); cfg80211_hold_bss(bss_from_pub(req->add_links[link_id].bss));
} }
} }

View file

@ -5,7 +5,7 @@
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright 2015-2017 Intel Deutschland GmbH * Copyright 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018-2024 Intel Corporation * Copyright (C) 2018-2025 Intel Corporation
*/ */
#include <linux/if.h> #include <linux/if.h>
@ -16488,9 +16488,9 @@ static int nl80211_assoc_ml_reconf(struct sk_buff *skb, struct genl_info *info)
struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1]; struct net_device *dev = info->user_ptr[1];
struct wireless_dev *wdev = dev->ieee80211_ptr; struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_assoc_link links[IEEE80211_MLD_MAX_NUM_LINKS] = {}; struct cfg80211_ml_reconf_req req = {};
unsigned int link_id; unsigned int link_id;
u16 add_links, rem_links; u16 add_links;
int err; int err;
if (!wdev->valid_links) if (!wdev->valid_links)
@ -16506,39 +16506,37 @@ static int nl80211_assoc_ml_reconf(struct sk_buff *skb, struct genl_info *info)
add_links = 0; add_links = 0;
if (info->attrs[NL80211_ATTR_MLO_LINKS]) { if (info->attrs[NL80211_ATTR_MLO_LINKS]) {
err = nl80211_process_links(rdev, links, NULL, 0, info); err = nl80211_process_links(rdev, req.add_links, NULL, 0, info);
if (err) if (err)
return err; return err;
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
link_id++) { link_id++) {
if (!links[link_id].bss) if (!req.add_links[link_id].bss)
continue; continue;
add_links |= BIT(link_id); add_links |= BIT(link_id);
} }
} }
if (info->attrs[NL80211_ATTR_MLO_RECONF_REM_LINKS]) if (info->attrs[NL80211_ATTR_MLO_RECONF_REM_LINKS])
rem_links = req.rem_links =
nla_get_u16(info->attrs[NL80211_ATTR_MLO_RECONF_REM_LINKS]); nla_get_u16(info->attrs[NL80211_ATTR_MLO_RECONF_REM_LINKS]);
else
rem_links = 0;
/* Validate that existing links are not added, removed links are valid /* Validate that existing links are not added, removed links are valid
* and don't allow adding and removing the same links * and don't allow adding and removing the same links
*/ */
if ((add_links & rem_links) || !(add_links | rem_links) || if ((add_links & req.rem_links) || !(add_links | req.rem_links) ||
(wdev->valid_links & add_links) || (wdev->valid_links & add_links) ||
((wdev->valid_links & rem_links) != rem_links)) { ((wdev->valid_links & req.rem_links) != req.rem_links)) {
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
err = cfg80211_assoc_ml_reconf(rdev, dev, links, rem_links); err = cfg80211_assoc_ml_reconf(rdev, dev, &req);
out: out:
for (link_id = 0; link_id < ARRAY_SIZE(links); link_id++) for (link_id = 0; link_id < ARRAY_SIZE(req.add_links); link_id++)
cfg80211_put_bss(&rdev->wiphy, links[link_id].bss); cfg80211_put_bss(&rdev->wiphy, req.add_links[link_id].bss);
return err; return err;
} }

View file

@ -2,7 +2,7 @@
/* /*
* Portions of this file * Portions of this file
* Copyright(c) 2016-2017 Intel Deutschland GmbH * Copyright(c) 2016-2017 Intel Deutschland GmbH
* Copyright (C) 2018, 2021-2024 Intel Corporation * Copyright (C) 2018, 2021-2025 Intel Corporation
*/ */
#ifndef __CFG80211_RDEV_OPS #ifndef __CFG80211_RDEV_OPS
#define __CFG80211_RDEV_OPS #define __CFG80211_RDEV_OPS
@ -1551,16 +1551,14 @@ rdev_get_radio_mask(struct cfg80211_registered_device *rdev,
static inline int static inline int
rdev_assoc_ml_reconf(struct cfg80211_registered_device *rdev, rdev_assoc_ml_reconf(struct cfg80211_registered_device *rdev,
struct net_device *dev, struct net_device *dev,
struct cfg80211_assoc_link *add_links, struct cfg80211_ml_reconf_req *req)
u16 rem_links)
{ {
struct wiphy *wiphy = &rdev->wiphy; struct wiphy *wiphy = &rdev->wiphy;
int ret = -EOPNOTSUPP; int ret = -EOPNOTSUPP;
trace_rdev_assoc_ml_reconf(wiphy, dev, add_links, rem_links); trace_rdev_assoc_ml_reconf(wiphy, dev, req);
if (rdev->ops->assoc_ml_reconf) if (rdev->ops->assoc_ml_reconf)
ret = rdev->ops->assoc_ml_reconf(wiphy, dev, add_links, ret = rdev->ops->assoc_ml_reconf(wiphy, dev, req);
rem_links);
trace_rdev_return_int(wiphy, ret); trace_rdev_return_int(wiphy, ret);
return ret; return ret;

View file

@ -2,7 +2,7 @@
/* /*
* Portions of this file * Portions of this file
* Copyright(c) 2016-2017 Intel Deutschland GmbH * Copyright(c) 2016-2017 Intel Deutschland GmbH
* Copyright (C) 2018, 2020-2024 Intel Corporation * Copyright (C) 2018, 2020-2025 Intel Corporation
*/ */
#undef TRACE_SYSTEM #undef TRACE_SYSTEM
#define TRACE_SYSTEM cfg80211 #define TRACE_SYSTEM cfg80211
@ -4142,9 +4142,8 @@ TRACE_EVENT(cfg80211_mlo_reconf_add_done,
TRACE_EVENT(rdev_assoc_ml_reconf, TRACE_EVENT(rdev_assoc_ml_reconf,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_assoc_link *add_links, struct cfg80211_ml_reconf_req *req),
u16 rem_links), TP_ARGS(wiphy, netdev, req),
TP_ARGS(wiphy, netdev, add_links, rem_links),
TP_STRUCT__entry( TP_STRUCT__entry(
WIPHY_ENTRY WIPHY_ENTRY
NETDEV_ENTRY NETDEV_ENTRY
@ -4157,9 +4156,9 @@ TRACE_EVENT(rdev_assoc_ml_reconf,
u32 i; u32 i;
__entry->add_links = 0; __entry->add_links = 0;
__entry->rem_links = rem_links; __entry->rem_links = req->rem_links;
for (i = 0; add_links && i < IEEE80211_MLD_MAX_NUM_LINKS; i++) for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++)
if (add_links[i].bss) if (req->add_links[i].bss)
__entry->add_links |= BIT(i); __entry->add_links |= BIT(i);
), ),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", add_links=0x%x, rem_links=0x%x", TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", add_links=0x%x, rem_links=0x%x",