diff options
author | Johannes Berg | 2022-06-28 17:17:05 +0200 |
---|---|---|
committer | Johannes Berg | 2022-07-15 11:43:17 +0200 |
commit | 5cd212cb6415aa604ada17d5150847fd65d27337 (patch) | |
tree | 589ad6e705fb23ba061aa9844af1b1dadd4a6916 /net/wireless | |
parent | cd47c0f57ae6607cfa3d161e341cbdd283bc444f (diff) |
wifi: cfg80211: extend cfg80211_rx_assoc_resp() for MLO
Extend the cfg80211_rx_assoc_resp() to cover multiple
BSSes, the AP MLD address and local link addresses
for MLO.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/mlme.c | 64 | ||||
-rw-r--r-- | net/wireless/trace.h | 16 |
2 files changed, 50 insertions, 30 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index a6ad696f131b..80f11a29cb86 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -28,28 +28,41 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)data->buf; - struct cfg80211_connect_resp_params cr; - const u8 *resp_ie = mgmt->u.assoc_resp.variable; - size_t resp_ie_len = data->len - offsetof(struct ieee80211_mgmt, - u.assoc_resp.variable); - - if (data->bss->channel->band == NL80211_BAND_S1GHZ) { - resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable; - resp_ie_len = data->len - offsetof(struct ieee80211_mgmt, - u.s1g_assoc_resp.variable); - } + struct cfg80211_connect_resp_params cr = { + .timeout_reason = NL80211_TIMEOUT_UNSPECIFIED, + .req_ie = data->req_ies, + .req_ie_len = data->req_ies_len, + .resp_ie = mgmt->u.assoc_resp.variable, + .resp_ie_len = data->len - + offsetof(struct ieee80211_mgmt, + u.assoc_resp.variable), + .status = le16_to_cpu(mgmt->u.assoc_resp.status_code), + .ap_mld_addr = data->ap_mld_addr, + }; + unsigned int link_id; + + for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) { + cr.links[link_id].bss = data->links[link_id].bss; + if (!cr.links[link_id].bss) + continue; + cr.links[link_id].bssid = data->links[link_id].bss->bssid; + cr.links[link_id].addr = data->links[link_id].addr; + /* need to have local link addresses for MLO connections */ + WARN_ON(cr.ap_mld_addr && !cr.links[link_id].addr); + + if (cr.links[link_id].bss->channel->band == NL80211_BAND_S1GHZ) { + WARN_ON(link_id); + cr.resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable; + cr.resp_ie_len = data->len - + offsetof(struct ieee80211_mgmt, + u.s1g_assoc_resp.variable); + } - memset(&cr, 0, sizeof(cr)); - cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code); - cr.links[0].bssid = mgmt->bssid; - cr.links[0].bss = data->bss; - cr.req_ie = data->req_ies; - cr.req_ie_len = data->req_ies_len; - cr.resp_ie = resp_ie; - cr.resp_ie_len = resp_ie_len; - cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED; + if (cr.ap_mld_addr) + cr.valid_links |= BIT(link_id); + } - trace_cfg80211_send_rx_assoc(dev, data->bss); + trace_cfg80211_send_rx_assoc(dev, data); /* * This is a bit of a hack, we don't notify userspace of @@ -58,8 +71,15 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, * frame instead of reassoc. */ if (cfg80211_sme_rx_assoc_resp(wdev, cr.status)) { - cfg80211_unhold_bss(bss_from_pub(data->bss)); - cfg80211_put_bss(wiphy, data->bss); + for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) { + struct cfg80211_bss *bss = data->links[link_id].bss; + + if (!bss) + continue; + + cfg80211_unhold_bss(bss_from_pub(bss)); + cfg80211_put_bss(wiphy, bss); + } return; } diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 94d107cab72c..dac66ad5937d 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -2887,20 +2887,20 @@ DEFINE_EVENT(netdev_evt_only, cfg80211_send_rx_auth, ); TRACE_EVENT(cfg80211_send_rx_assoc, - TP_PROTO(struct net_device *netdev, struct cfg80211_bss *bss), - TP_ARGS(netdev, bss), + TP_PROTO(struct net_device *netdev, + struct cfg80211_rx_assoc_resp *data), + TP_ARGS(netdev, data), TP_STRUCT__entry( NETDEV_ENTRY - MAC_ENTRY(bssid) - CHAN_ENTRY + MAC_ENTRY(ap_addr) ), TP_fast_assign( NETDEV_ASSIGN; - MAC_ASSIGN(bssid, bss->bssid); - CHAN_ASSIGN(bss->channel); + MAC_ASSIGN(ap_addr, + data->ap_mld_addr ?: data->links[0].bss->bssid); ), - TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", " CHAN_PR_FMT, - NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) + TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, + NETDEV_PR_ARG, MAC_PR_ARG(ap_addr)) ); DECLARE_EVENT_CLASS(netdev_frame_event, |