提交 5cd212cb 编写于 作者: J Johannes Berg

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: NJohannes Berg <johannes.berg@intel.com>
上级 cd47c0f5
...@@ -6886,14 +6886,21 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr); ...@@ -6886,14 +6886,21 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr);
* as the AC bitmap in the QoS info field * as the AC bitmap in the QoS info field
* @req_ies: information elements from the (Re)Association Request frame * @req_ies: information elements from the (Re)Association Request frame
* @req_ies_len: length of req_ies data * @req_ies_len: length of req_ies data
* @ap_mld_addr: AP MLD address (in case of MLO)
* @links: per-link information indexed by link ID, use links[0] for
* non-MLO connections
*/ */
struct cfg80211_rx_assoc_resp { struct cfg80211_rx_assoc_resp {
struct cfg80211_bss *bss;
const u8 *buf; const u8 *buf;
size_t len; size_t len;
const u8 *req_ies; const u8 *req_ies;
size_t req_ies_len; size_t req_ies_len;
int uapsd_queues; int uapsd_queues;
const u8 *ap_mld_addr;
struct {
const u8 *addr;
struct cfg80211_bss *bss;
} links[IEEE80211_MLD_MAX_NUM_LINKS];
}; };
/** /**
......
...@@ -3995,7 +3995,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, ...@@ -3995,7 +3995,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
info.success = 1; info.success = 1;
} }
resp.bss = cbss; resp.links[0].bss = cbss;
resp.buf = (u8 *)mgmt; resp.buf = (u8 *)mgmt;
resp.len = len; resp.len = len;
resp.req_ies = ifmgd->assoc_req_ies; resp.req_ies = ifmgd->assoc_req_ies;
......
...@@ -28,28 +28,41 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, ...@@ -28,28 +28,41 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
struct wiphy *wiphy = wdev->wiphy; struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)data->buf; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)data->buf;
struct cfg80211_connect_resp_params cr; struct cfg80211_connect_resp_params cr = {
const u8 *resp_ie = mgmt->u.assoc_resp.variable; .timeout_reason = NL80211_TIMEOUT_UNSPECIFIED,
size_t resp_ie_len = data->len - offsetof(struct ieee80211_mgmt, .req_ie = data->req_ies,
u.assoc_resp.variable); .req_ie_len = data->req_ies_len,
.resp_ie = mgmt->u.assoc_resp.variable,
if (data->bss->channel->band == NL80211_BAND_S1GHZ) { .resp_ie_len = data->len -
resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable; offsetof(struct ieee80211_mgmt,
resp_ie_len = data->len - offsetof(struct ieee80211_mgmt, u.assoc_resp.variable),
u.s1g_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)); if (cr.ap_mld_addr)
cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code); cr.valid_links |= BIT(link_id);
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;
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 * 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, ...@@ -58,8 +71,15 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
* frame instead of reassoc. * frame instead of reassoc.
*/ */
if (cfg80211_sme_rx_assoc_resp(wdev, cr.status)) { if (cfg80211_sme_rx_assoc_resp(wdev, cr.status)) {
cfg80211_unhold_bss(bss_from_pub(data->bss)); for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) {
cfg80211_put_bss(wiphy, data->bss); 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; return;
} }
......
...@@ -2887,20 +2887,20 @@ DEFINE_EVENT(netdev_evt_only, cfg80211_send_rx_auth, ...@@ -2887,20 +2887,20 @@ DEFINE_EVENT(netdev_evt_only, cfg80211_send_rx_auth,
); );
TRACE_EVENT(cfg80211_send_rx_assoc, TRACE_EVENT(cfg80211_send_rx_assoc,
TP_PROTO(struct net_device *netdev, struct cfg80211_bss *bss), TP_PROTO(struct net_device *netdev,
TP_ARGS(netdev, bss), struct cfg80211_rx_assoc_resp *data),
TP_ARGS(netdev, data),
TP_STRUCT__entry( TP_STRUCT__entry(
NETDEV_ENTRY NETDEV_ENTRY
MAC_ENTRY(bssid) MAC_ENTRY(ap_addr)
CHAN_ENTRY
), ),
TP_fast_assign( TP_fast_assign(
NETDEV_ASSIGN; NETDEV_ASSIGN;
MAC_ASSIGN(bssid, bss->bssid); MAC_ASSIGN(ap_addr,
CHAN_ASSIGN(bss->channel); data->ap_mld_addr ?: data->links[0].bss->bssid);
), ),
TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", " CHAN_PR_FMT, TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT,
NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) NETDEV_PR_ARG, MAC_PR_ARG(ap_addr))
); );
DECLARE_EVENT_CLASS(netdev_frame_event, DECLARE_EVENT_CLASS(netdev_frame_event,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册