From patchwork Fri Feb 16 11:54:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miri Korenblit X-Patchwork-Id: 773688 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED13977F39 for ; Fri, 16 Feb 2024 11:54:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084488; cv=none; b=hcurv4iOdfZ7+heseDRihUVsbZc6A/YoqK/VE8bnQQ3nWCu8RUeFz6RiF8DcFW3He7nBEfe91/e1KyFttMpo6kjpViDYjA0u5RVcW8QKgfbGLZ1TeGjwCVvkwvilR6d0gazR45/BGjtiVPD8+K3expxTbyx2Uhpzu+ku/4aKg54= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084488; c=relaxed/simple; bh=An5IbM/rzTccK9cdGmFfqS+w+56mMigA5TUhHt1SkmE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=g3GTGBAaYgYezqU/chs55rDO9aSP39mFWErtdnBQ8QigQoVM42NlMc+OvFGxsZoyCYwh0wA+EMVan9P3qN60bH6zy4I2G70xkzkJYU6/D/xNHVzjK1bElwdXVpp/vMKzIR1PlVVbso0D3bhKTScQJ56a3h+UjJEneb+1aSXPen0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=aUS7UuS6; arc=none smtp.client-ip=198.175.65.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="aUS7UuS6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1708084487; x=1739620487; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=An5IbM/rzTccK9cdGmFfqS+w+56mMigA5TUhHt1SkmE=; b=aUS7UuS6I8h+jPKsgBW9vdVLn5emUY892Btvtsy52IZjcf+CKWrX1M/8 iLgbpyQPE3nA87p5t/RgHSs3sniVx9GkEHP7sAwqN3Gu5mWJrZzm8v3Tl wcvo1uTwkqBUQXfg7JhfEjFrlr57kUYUKL6COIg9sY7dDZd+9y1jg2jxu gf4XVUdV4TFhLI2Ya+JSWBTWviZs4eROUEBGnku/ZW4VCEldtkgdNUvD/ B3hbKJVnYHRIMJxOvO3j7CoaU7aHX+Qo0dUYxXX4QHQnY2W+zeeyFZnAo pKsfkbMNAO1ucOTZ34yMdfi6Dr9dstiZu0HCh7VNIdYimJquDBjleMzil w==; X-IronPort-AV: E=McAfee;i="6600,9927,10985"; a="2321905" X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="2321905" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:46 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="3795589" Received: from unknown (HELO WEIS0040.iil.intel.com) ([10.12.217.108]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:45 -0800 From: Miri Korenblit To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Benjamin Berg , Johannes Berg Subject: [PATCH 1/7] wifi: cfg80211: set correct param change count in ML element Date: Fri, 16 Feb 2024 13:54:27 +0200 Message-Id: <20240216135047.f2a507634692.I06b122c7a319a38b4e970f5e0bd3d3ef9cac4cbe@changeid> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> References: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Intel Israel (74) Limited From: Benjamin Berg The ML element generation code to create a BSS entry from a per-STA profile was not overwriting the BSS parameter change count. This meant that the incorrect parameter change count would be reported within the multi-link element. Fix this by returning the BSS parameter change count from the function and placing it into the ML element. The returned tbtt info was never used, so just drop that to simplify the code. Fixes: 5f478adf1f99 ("wifi: cfg80211: generate an ML element for per-STA profiles") Signed-off-by: Benjamin Berg Reviewed-by: Johannes Berg Signed-off-by: Miri Korenblit --- net/wireless/scan.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 88e8b25c073a..0907a72231ee 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -2567,9 +2567,9 @@ cfg80211_defrag_mle(const struct element *mle, const u8 *ie, size_t ielen, } static u8 -cfg80211_tbtt_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id, - const struct ieee80211_neighbor_ap_info **ap_info, - const u8 **tbtt_info) +cfg80211_rnr_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id, + const struct ieee80211_neighbor_ap_info **ap_info, + u8 *param_ch_count) { const struct ieee80211_neighbor_ap_info *info; const struct element *rnr; @@ -2626,7 +2626,9 @@ cfg80211_tbtt_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id, if (mld_id == mld_params->mld_id && link_id == lid) { *ap_info = info; - *tbtt_info = pos; + *param_ch_count = + le16_get_bits(mld_params->params, + IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT); return use_for; } @@ -2836,8 +2838,8 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy, enum nl80211_band band; u32 freq; const u8 *profile; - const u8 *tbtt_info; ssize_t profile_len; + u8 param_ch_count; u8 link_id, use_for; if (!ieee80211_mle_basic_sta_prof_size_ok((u8 *)mle->sta_prof[i], @@ -2880,10 +2882,11 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy, profile_len -= 2; /* Find in RNR to look up channel information */ - use_for = cfg80211_tbtt_info_for_mld_ap(tx_data->ie, - tx_data->ielen, - mld_id, link_id, - &ap_info, &tbtt_info); + use_for = cfg80211_rnr_info_for_mld_ap(tx_data->ie, + tx_data->ielen, + mld_id, link_id, + &ap_info, + ¶m_ch_count); if (!use_for) continue; @@ -2926,7 +2929,8 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy, continue; /* Copy the Basic Multi-Link element including the common - * information, and then fix up the link ID. + * information, and then fix up the link ID and BSS param + * change count. * Note that the ML element length has been verified and we * also checked that it contains the link ID. */ @@ -2937,6 +2941,8 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy, sizeof(*ml_elem) + ml_common_len); new_ie[data.ielen + sizeof(*ml_elem) + 1 + ETH_ALEN] = link_id; + new_ie[data.ielen + sizeof(*ml_elem) + 1 + ETH_ALEN + 1] = + param_ch_count; data.ielen += sizeof(*ml_elem) + ml_common_len; From patchwork Fri Feb 16 11:54:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miri Korenblit X-Patchwork-Id: 774075 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E529577F39 for ; Fri, 16 Feb 2024 11:54:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084492; cv=none; b=mUdiHOacvlQ9fwJe/WPpe5m0TlnA1TxYwRhkjlgbUmUMbp9QfNOtcIyve1t2bdxIzsBQqVHm3P4Sxefu3kYWc1NbiaENyb2/gegzB0CZGPpqjCbOOR+yLwIW7+S5S6blJ1t3i0giGQFgwTI4rzTB1XoAOu5DsZCy8D4NPPLQAJY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084492; c=relaxed/simple; bh=qXzMb+/A626zW2fG362UVo02rLxO6Gbsb0rr8AYE1ro=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fGV/6rxNIg3GZSHnz1+sYpCQ8VZNdskyPVKEv4Zf2Cr8J4A3Gu60eww1N48ycA1m071t8rrYpdwGwF+wrJnmqRtuHGbtqjGQYMT8mUIkLK68NvetjbAIExfJ/MBVeXyr+R8Qxjo8qhkKHIQlrxZ9lw1wDqKAC+QQ1HfDB4zPaRE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=kxLZ7t5H; arc=none smtp.client-ip=198.175.65.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="kxLZ7t5H" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1708084490; x=1739620490; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qXzMb+/A626zW2fG362UVo02rLxO6Gbsb0rr8AYE1ro=; b=kxLZ7t5HDp2bpflnSqDuXfqUK7wlxI6yBp+gx2AE9nL/OKc0vG9jsATz yixVF/G984w4izYRP5RcG+NU4xz1rgkZgcyQQdr+BDXxfyt0CVbJCTGEy Y3sndV1Dg6sb6zgxHXRZZ/EoqcX0XzZYAZbuLZkUnlFBFRZU4PiNlEc8t aLgOje9x/RuEUYSKmiHk2xQ8lxTbLvwZBOIX0YqNud88rwEP9cQr7kGhr r6kzUQqZpk4H8QcneZUHGxNsjx/dGZeqrnPo95lGMgg4JOpEL+f46Ciky XjEG6tutgdoI9ZKeRmqJPlhkdo0Mmgj2prrkYGi1g4EBsHmcLs/4XyVQo A==; X-IronPort-AV: E=McAfee;i="6600,9927,10985"; a="2321911" X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="2321911" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="3795592" Received: from unknown (HELO WEIS0040.iil.intel.com) ([10.12.217.108]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:48 -0800 From: Miri Korenblit To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Johannes Berg Subject: [PATCH 2/7] wifi: cfg80211: remove cfg80211_inform_single_bss_frame_data() Date: Fri, 16 Feb 2024 13:54:28 +0200 Message-Id: <20240216135047.f3f864f94c78.I2192adb32ab10713e71f395a9d203386264f6ed5@changeid> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> References: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Intel Israel (74) Limited From: Johannes Berg This function pretty much does what cfg80211_inform_single_bss_data() already does, except on a frame data. But we can call the other one, after populating the inform_data more completely, so we don't need to do everything twice. This also uncovered a few bugs: * the 6 GHz power type checks were only done in this function, move (and rename from 'uhb') those; * the chains/chain_signal information wasn't used in the latter, add that Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit --- net/wireless/scan.c | 245 +++++++++++++++----------------------------- 1 file changed, 80 insertions(+), 165 deletions(-) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 0907a72231ee..754138168646 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -2087,6 +2087,35 @@ struct cfg80211_inform_single_bss_data { u64 cannot_use_reasons; }; +static bool cfg80211_6ghz_power_type_valid(const u8 *ie, size_t ielen, + const u32 flags) +{ + const struct element *tmp; + struct ieee80211_he_operation *he_oper; + + tmp = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ie, ielen); + if (tmp && tmp->datalen >= sizeof(*he_oper) + 1) { + const struct ieee80211_he_6ghz_oper *he_6ghz_oper; + + he_oper = (void *)&tmp->data[1]; + he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper); + + if (!he_6ghz_oper) + return false; + + switch (u8_get_bits(he_6ghz_oper->control, + IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) { + case IEEE80211_6GHZ_CTRL_REG_LPI_AP: + return true; + case IEEE80211_6GHZ_CTRL_REG_SP_AP: + return !(flags & IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT); + case IEEE80211_6GHZ_CTRL_REG_VLP_AP: + return !(flags & IEEE80211_CHAN_NO_6GHZ_VLP_CLIENT); + } + } + return false; +} + /* Returned bss is reference counted and must be cleaned up appropriately. */ static struct cfg80211_bss * cfg80211_inform_single_bss_data(struct wiphy *wiphy, @@ -2119,6 +2148,14 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, if (!channel) return NULL; + if (channel->band == NL80211_BAND_6GHZ && + !cfg80211_6ghz_power_type_valid(data->ie, data->ielen, + channel->flags)) { + data->use_for = 0; + data->cannot_use_reasons = + NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH; + } + memcpy(tmp.pub.bssid, data->bssid, ETH_ALEN); tmp.pub.channel = channel; if (data->bss_source != BSS_SOURCE_STA_PROFILE) @@ -2130,6 +2167,9 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, tmp.ts_boottime = drv_data->boottime_ns; tmp.parent_tsf = drv_data->parent_tsf; ether_addr_copy(tmp.parent_bssid, drv_data->parent_bssid); + tmp.pub.chains = drv_data->chains; + memcpy(tmp.pub.chain_signal, drv_data->chain_signal, + IEEE80211_MAX_CHAINS); tmp.pub.use_for = data->use_for; tmp.pub.cannot_use_reasons = data->cannot_use_reasons; @@ -3025,59 +3065,23 @@ cfg80211_inform_bss_data(struct wiphy *wiphy, } EXPORT_SYMBOL(cfg80211_inform_bss_data); -static bool cfg80211_uhb_power_type_valid(const u8 *ie, - size_t ielen, - const u32 flags) -{ - const struct element *tmp; - struct ieee80211_he_operation *he_oper; - - tmp = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ie, ielen); - if (tmp && tmp->datalen >= sizeof(*he_oper) + 1) { - const struct ieee80211_he_6ghz_oper *he_6ghz_oper; - - he_oper = (void *)&tmp->data[1]; - he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper); - - if (!he_6ghz_oper) - return false; - - switch (u8_get_bits(he_6ghz_oper->control, - IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) { - case IEEE80211_6GHZ_CTRL_REG_LPI_AP: - return true; - case IEEE80211_6GHZ_CTRL_REG_SP_AP: - return !(flags & IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT); - case IEEE80211_6GHZ_CTRL_REG_VLP_AP: - return !(flags & IEEE80211_CHAN_NO_6GHZ_VLP_CLIENT); - } - } - return false; -} - -/* cfg80211_inform_bss_width_frame helper */ -static struct cfg80211_bss * -cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, - struct cfg80211_inform_bss *data, - struct ieee80211_mgmt *mgmt, size_t len, - gfp_t gfp) +struct cfg80211_bss * +cfg80211_inform_bss_frame_data(struct wiphy *wiphy, + struct cfg80211_inform_bss *data, + struct ieee80211_mgmt *mgmt, size_t len, + gfp_t gfp) { - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - struct cfg80211_internal_bss tmp = {}, *res; - struct cfg80211_bss_ies *ies; - struct ieee80211_channel *channel; - bool signal_valid; + struct cfg80211_inform_single_bss_data inform_data = { + .drv_data = data, + .use_for = data->restrict_use ? + data->use_for : + NL80211_BSS_USE_FOR_ALL, + .cannot_use_reasons = data->cannot_use_reasons, + }; + size_t min_hdr_len = offsetof(struct ieee80211_mgmt, + u.probe_resp.variable); struct ieee80211_ext *ext = NULL; - u8 *bssid, *variable; - u16 capability, beacon_int; - size_t ielen, min_hdr_len = offsetof(struct ieee80211_mgmt, - u.probe_resp.variable); - int bss_type; - - BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != - offsetof(struct ieee80211_mgmt, u.beacon.variable)); - - trace_cfg80211_inform_bss_frame(wiphy, data, mgmt, len); + struct cfg80211_bss *res; if (WARN_ON(!mgmt)) return NULL; @@ -3085,9 +3089,10 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, if (WARN_ON(!wiphy)) return NULL; - if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && - (data->signal < 0 || data->signal > 100))) - return NULL; + BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != + offsetof(struct ieee80211_mgmt, u.beacon.variable)); + + trace_cfg80211_inform_bss_frame(wiphy, data, mgmt, len); if (ieee80211_is_s1g_beacon(mgmt->frame_control)) { ext = (void *) mgmt; @@ -3100,140 +3105,50 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, if (WARN_ON(len < min_hdr_len)) return NULL; - ielen = len - min_hdr_len; - variable = mgmt->u.probe_resp.variable; - if (ext) { - if (ieee80211_is_s1g_short_beacon(mgmt->frame_control)) - variable = ext->u.s1g_short_beacon.variable; - else - variable = ext->u.s1g_beacon.variable; - } - - channel = cfg80211_get_bss_channel(wiphy, variable, ielen, data->chan); - if (!channel) - return NULL; - - if (channel->band == NL80211_BAND_6GHZ && - !cfg80211_uhb_power_type_valid(variable, ielen, channel->flags)) { - data->restrict_use = 1; - data->use_for = 0; - data->cannot_use_reasons = - NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH; - } - + inform_data.ielen = len - min_hdr_len; + inform_data.ie = mgmt->u.probe_resp.variable; if (ext) { const struct ieee80211_s1g_bcn_compat_ie *compat; const struct element *elem; + if (ieee80211_is_s1g_short_beacon(mgmt->frame_control)) + inform_data.ie = ext->u.s1g_short_beacon.variable; + else + inform_data.ie = ext->u.s1g_beacon.variable; + elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT, - variable, ielen); + inform_data.ie, inform_data.ielen); if (!elem) return NULL; if (elem->datalen < sizeof(*compat)) return NULL; compat = (void *)elem->data; - bssid = ext->u.s1g_beacon.sa; - capability = le16_to_cpu(compat->compat_info); - beacon_int = le16_to_cpu(compat->beacon_int); + memcpy(inform_data.bssid, ext->u.s1g_beacon.sa, ETH_ALEN); + inform_data.capability = le16_to_cpu(compat->compat_info); + inform_data.beacon_interval = le16_to_cpu(compat->beacon_int); } else { - bssid = mgmt->bssid; - beacon_int = le16_to_cpu(mgmt->u.probe_resp.beacon_int); - capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); + memcpy(inform_data.bssid, mgmt->bssid, ETH_ALEN); + inform_data.beacon_interval = + le16_to_cpu(mgmt->u.probe_resp.beacon_int); + inform_data.capability = + le16_to_cpu(mgmt->u.probe_resp.capab_info); } - if (channel->band == NL80211_BAND_60GHZ) { - bss_type = capability & WLAN_CAPABILITY_DMG_TYPE_MASK; - if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP || - bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS) - regulatory_hint_found_beacon(wiphy, channel, gfp); - } else { - if (capability & WLAN_CAPABILITY_ESS) - regulatory_hint_found_beacon(wiphy, channel, gfp); - } - - ies = kzalloc(sizeof(*ies) + ielen, gfp); - if (!ies) - return NULL; - ies->len = ielen; - ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); - ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control) || - ieee80211_is_s1g_beacon(mgmt->frame_control); - memcpy(ies->data, variable, ielen); + inform_data.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); if (ieee80211_is_probe_resp(mgmt->frame_control)) - rcu_assign_pointer(tmp.pub.proberesp_ies, ies); + inform_data.ftype = CFG80211_BSS_FTYPE_PRESP; else - rcu_assign_pointer(tmp.pub.beacon_ies, ies); - rcu_assign_pointer(tmp.pub.ies, ies); + inform_data.ftype = CFG80211_BSS_FTYPE_BEACON; - memcpy(tmp.pub.bssid, bssid, ETH_ALEN); - tmp.pub.beacon_interval = beacon_int; - tmp.pub.capability = capability; - tmp.pub.channel = channel; - tmp.pub.signal = data->signal; - tmp.ts_boottime = data->boottime_ns; - tmp.parent_tsf = data->parent_tsf; - tmp.pub.chains = data->chains; - memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS); - ether_addr_copy(tmp.parent_bssid, data->parent_bssid); - tmp.pub.use_for = data->restrict_use ? - data->use_for : - NL80211_BSS_USE_FOR_ALL; - tmp.pub.cannot_use_reasons = data->cannot_use_reasons; - - signal_valid = data->chan == channel; - spin_lock_bh(&rdev->bss_lock); - res = __cfg80211_bss_update(rdev, &tmp, signal_valid, jiffies); - if (!res) - goto drop; - - rdev_inform_bss(rdev, &res->pub, ies, data->drv_data); - - spin_unlock_bh(&rdev->bss_lock); - - trace_cfg80211_return_bss(&res->pub); - /* __cfg80211_bss_update gives us a referenced result */ - return &res->pub; - -drop: - spin_unlock_bh(&rdev->bss_lock); - return NULL; -} - -struct cfg80211_bss * -cfg80211_inform_bss_frame_data(struct wiphy *wiphy, - struct cfg80211_inform_bss *data, - struct ieee80211_mgmt *mgmt, size_t len, - gfp_t gfp) -{ - struct cfg80211_inform_single_bss_data inform_data = { - .drv_data = data, - .ie = mgmt->u.probe_resp.variable, - .ielen = len - offsetof(struct ieee80211_mgmt, - u.probe_resp.variable), - .use_for = data->restrict_use ? - data->use_for : - NL80211_BSS_USE_FOR_ALL, - .cannot_use_reasons = data->cannot_use_reasons, - }; - struct cfg80211_bss *res; - - res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt, - len, gfp); + res = cfg80211_inform_single_bss_data(wiphy, &inform_data, gfp); if (!res) return NULL; /* don't do any further MBSSID/ML handling for S1G */ - if (ieee80211_is_s1g_beacon(mgmt->frame_control)) + if (ext) return res; - inform_data.ftype = ieee80211_is_beacon(mgmt->frame_control) ? - CFG80211_BSS_FTYPE_BEACON : CFG80211_BSS_FTYPE_PRESP; - memcpy(inform_data.bssid, mgmt->bssid, ETH_ALEN); - inform_data.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); - inform_data.beacon_interval = - le16_to_cpu(mgmt->u.probe_resp.beacon_int); - /* process each non-transmitting bss */ cfg80211_parse_mbssid_data(wiphy, &inform_data, res, gfp); From patchwork Fri Feb 16 11:54:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miri Korenblit X-Patchwork-Id: 773687 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 023F07867E for ; Fri, 16 Feb 2024 11:54:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084494; cv=none; b=TvW/gf9keAFPWSRZ9GWmrqMsQEdlX9f6SMNUlgqYAktf7s6UAtTeR8k0nElObhWfGxihMWKgJXAfQpDLct9dYuwZOmUq1qQBdKErORVZPIAZ5ylGrLHPnpSUT+aKC1VhCQJ+scljDKp3p9QpM39MfO1oQ82JIQpqo0EcehTeOLg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084494; c=relaxed/simple; bh=yfQujVR5rVP+exuWqjFoFBM/6o8hMUBp0nzrtG1UsCI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=V/Ex46Z2f0LuR6tgXP20BVIlOchYGrikLrBgEaEPvWg97UW/IZZfZoYSM7oaGh8uao+ERxhEVA8TlyRiA8DPqZ/Fc31Dgs4uX2YoGuAbR67XsUKFX8IBQd6NeGhqFbrlLvxnskC3RggcPTbtNJGU+jHXV69ybO2ROBPoBHgdqKE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=WYOdC3g8; arc=none smtp.client-ip=198.175.65.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="WYOdC3g8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1708084492; x=1739620492; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yfQujVR5rVP+exuWqjFoFBM/6o8hMUBp0nzrtG1UsCI=; b=WYOdC3g8lSGw9/FZuV9+j/nLMoiIp1ehXZ0wlFses8mi2FRy/Go68KHB XG0/51V85xPxwtYs4rpCZB8WqcTB74pmz2Y5JLU4rHvfUUlFXGcTW9pwO dp5GlO3wJLqrEE2w/orp7n2OOCuZ8Lhs1CTDe8eM1HEHo3KQCHxEGSt+S sCFNn0YEn8QG1HxCYVGw8ACiYkEnaO/cKW8ouxE/tD1+1wZCI+nZCJsWy 8OuJRQicJe5p6RiW5Jtr/2Guwe9PduLmzloniPGWMknxb/4AroR25RvOi tKK/Nul6hySjeyKu2YNjY9H6f207gymfAOyxs0/uE7eXz/22UEt4WaR/E w==; X-IronPort-AV: E=McAfee;i="6600,9927,10985"; a="2321915" X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="2321915" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="3795595" Received: from unknown (HELO WEIS0040.iil.intel.com) ([10.12.217.108]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:50 -0800 From: Miri Korenblit To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Johannes Berg Subject: [PATCH 3/7] wifi: cfg80211: clean up cfg80211_inform_bss_frame_data() Date: Fri, 16 Feb 2024 13:54:29 +0200 Message-Id: <20240216135047.874aed1eff5f.Ib7d88d126eec50c64763251a78cb432bb5df14df@changeid> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> References: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Intel Israel (74) Limited From: Johannes Berg Make cfg80211_inform_bss_frame_data() call the existing cfg80211_inform_bss_data() after parsing the frame in the appropriate way, so we have less code duplication. This required introducing a new CFG80211_BSS_FTYPE_S1G_BEACON, but that can be used by other drivers as well. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit --- include/net/cfg80211.h | 2 ++ net/wireless/scan.c | 71 +++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 57c2298af35b..f9eada2a26ec 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -7175,11 +7175,13 @@ size_t cfg80211_merge_profile(const u8 *ie, size_t ielen, * from a beacon or probe response * @CFG80211_BSS_FTYPE_BEACON: data comes from a beacon * @CFG80211_BSS_FTYPE_PRESP: data comes from a probe response + * @CFG80211_BSS_FTYPE_S1G_BEACON: data comes from an S1G beacon */ enum cfg80211_bss_frame_type { CFG80211_BSS_FTYPE_UNKNOWN, CFG80211_BSS_FTYPE_BEACON, CFG80211_BSS_FTYPE_PRESP, + CFG80211_BSS_FTYPE_S1G_BEACON, }; /** diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 754138168646..c2d85fa4b75d 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -2213,6 +2213,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, switch (data->ftype) { case CFG80211_BSS_FTYPE_BEACON: + case CFG80211_BSS_FTYPE_S1G_BEACON: ies->from_beacon = true; fallthrough; case CFG80211_BSS_FTYPE_UNKNOWN: @@ -3057,6 +3058,10 @@ cfg80211_inform_bss_data(struct wiphy *wiphy, if (!res) return NULL; + /* don't do any further MBSSID/ML handling for S1G */ + if (ftype == CFG80211_BSS_FTYPE_S1G_BEACON) + return res; + cfg80211_parse_mbssid_data(wiphy, &inform_data, res, gfp); cfg80211_parse_ml_sta_data(wiphy, &inform_data, res, gfp); @@ -3071,17 +3076,16 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, struct ieee80211_mgmt *mgmt, size_t len, gfp_t gfp) { - struct cfg80211_inform_single_bss_data inform_data = { - .drv_data = data, - .use_for = data->restrict_use ? - data->use_for : - NL80211_BSS_USE_FOR_ALL, - .cannot_use_reasons = data->cannot_use_reasons, - }; size_t min_hdr_len = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); struct ieee80211_ext *ext = NULL; - struct cfg80211_bss *res; + enum cfg80211_bss_frame_type ftype; + u16 beacon_interval; + const u8 *bssid; + u16 capability; + const u8 *ie; + size_t ielen; + u64 tsf; if (WARN_ON(!mgmt)) return NULL; @@ -3105,56 +3109,45 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, if (WARN_ON(len < min_hdr_len)) return NULL; - inform_data.ielen = len - min_hdr_len; - inform_data.ie = mgmt->u.probe_resp.variable; + ielen = len - min_hdr_len; + ie = mgmt->u.probe_resp.variable; if (ext) { const struct ieee80211_s1g_bcn_compat_ie *compat; const struct element *elem; if (ieee80211_is_s1g_short_beacon(mgmt->frame_control)) - inform_data.ie = ext->u.s1g_short_beacon.variable; + ie = ext->u.s1g_short_beacon.variable; else - inform_data.ie = ext->u.s1g_beacon.variable; + ie = ext->u.s1g_beacon.variable; - elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT, - inform_data.ie, inform_data.ielen); + elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT, ie, ielen); if (!elem) return NULL; if (elem->datalen < sizeof(*compat)) return NULL; compat = (void *)elem->data; - memcpy(inform_data.bssid, ext->u.s1g_beacon.sa, ETH_ALEN); - inform_data.capability = le16_to_cpu(compat->compat_info); - inform_data.beacon_interval = le16_to_cpu(compat->beacon_int); + bssid = ext->u.s1g_beacon.sa; + capability = le16_to_cpu(compat->compat_info); + beacon_interval = le16_to_cpu(compat->beacon_int); } else { - memcpy(inform_data.bssid, mgmt->bssid, ETH_ALEN); - inform_data.beacon_interval = - le16_to_cpu(mgmt->u.probe_resp.beacon_int); - inform_data.capability = - le16_to_cpu(mgmt->u.probe_resp.capab_info); + bssid = mgmt->bssid; + beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); + capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); } - inform_data.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); + tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); if (ieee80211_is_probe_resp(mgmt->frame_control)) - inform_data.ftype = CFG80211_BSS_FTYPE_PRESP; + ftype = CFG80211_BSS_FTYPE_PRESP; + else if (ext) + ftype = CFG80211_BSS_FTYPE_S1G_BEACON; else - inform_data.ftype = CFG80211_BSS_FTYPE_BEACON; - - res = cfg80211_inform_single_bss_data(wiphy, &inform_data, gfp); - if (!res) - return NULL; - - /* don't do any further MBSSID/ML handling for S1G */ - if (ext) - return res; - - /* process each non-transmitting bss */ - cfg80211_parse_mbssid_data(wiphy, &inform_data, res, gfp); + ftype = CFG80211_BSS_FTYPE_BEACON; - cfg80211_parse_ml_sta_data(wiphy, &inform_data, res, gfp); - - return res; + return cfg80211_inform_bss_data(wiphy, data, ftype, + bssid, tsf, capability, + beacon_interval, ie, ielen, + gfp); } EXPORT_SYMBOL(cfg80211_inform_bss_frame_data); From patchwork Fri Feb 16 11:54:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miri Korenblit X-Patchwork-Id: 774074 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DBEDD78691 for ; Fri, 16 Feb 2024 11:54:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084497; cv=none; b=ErVfKCTv/ne/EhFvrG23xQI/SoSaZ2J+t5hfDQ7ERB6DOHyze4VbR5tJ/58EXCNUmCPTuZkattS0xpLnda2NTaVjxrck2w7CJOJYTER6waTRCIn12pIeE9FXZ2045sZqqhBKwo/3Ue32woNfoZ7kQuc5bEeZvKCQ0Utk3SEDjZo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084497; c=relaxed/simple; bh=qJMbBa6LYVbPqHUIDD6bmyY3aKkis/CiIB8rR83nvXY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tZifX/hxt+xUfpslBkQGsUoa3qwArv8OUJlJyUDkViB5niDHqHYSfqWcpmIV5ol8HGmy8xgUB+mezKJNyATxscnvaGiRvjywS1Tnn/s9Ljw8cBRNX9M4EyjRzFCZmF/gd8gUSz6QX2NDqoVWtKu5s0ZcYbUbti6ZlAgmEnERsDI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=O1n/F9u4; arc=none smtp.client-ip=198.175.65.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="O1n/F9u4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1708084495; x=1739620495; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qJMbBa6LYVbPqHUIDD6bmyY3aKkis/CiIB8rR83nvXY=; b=O1n/F9u4pJA3Pi52zXnEV3vcBGRJeoE1iNtPIs1O/0Fdxbh9hBO5yX+F +8hEBXfFCM7pLfV2D1+1S1nnmQS/qU16rVFm2cXHWIJ0c4DipvD7uFw16 fx680oarMm33XEOdczdWTVjs013TN2RBeZMxJsXn/KWTjcQobb0P529+Q fBiTr4uFpyPhN3DqLCbhDLykjGFlGbwVx9rSFCIg65G7ZZ9gDWqZ65Ozn HPn93sOUmY5LL8yKbFfGwtLtVfPfOu5f0Oc4fzL1puWult9lkLHmfpima 2ZI06Z+Vt3k1epNVhClxVNbMytBJ0pLZ3BQko6dPgyAnuDz8tjl8xHxoL A==; X-IronPort-AV: E=McAfee;i="6600,9927,10985"; a="2321919" X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="2321919" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:54 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="3795598" Received: from unknown (HELO WEIS0040.iil.intel.com) ([10.12.217.108]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:53 -0800 From: Miri Korenblit To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Johannes Berg , Benjamin Berg Subject: [PATCH 4/7] wifi: cfg80211: refactor RNR parsing Date: Fri, 16 Feb 2024 13:54:30 +0200 Message-Id: <20240216135047.cfff14b692fc.Ibe25be88a769eab29ebb17b9d19af666df6a2227@changeid> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> References: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Intel Israel (74) Limited From: Johannes Berg We'll need more parsing of the reduced neighbor report element, and we already have two places doing pretty much the same. Combine by refactoring the parsing into a separate function with a callback for each item found. Signed-off-by: Johannes Berg Reviewed-by: Benjamin Berg Signed-off-by: Miri Korenblit --- net/wireless/scan.c | 306 ++++++++++++++++++++++++-------------------- 1 file changed, 169 insertions(+), 137 deletions(-) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index c2d85fa4b75d..e46dfc71c497 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -611,104 +611,144 @@ static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry, return 0; } -VISIBLE_IF_CFG80211_KUNIT int -cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies, - struct list_head *list) +enum cfg80211_rnr_iter_ret { + RNR_ITER_CONTINUE, + RNR_ITER_BREAK, + RNR_ITER_ERROR, +}; + +static bool +cfg80211_iter_rnr(const u8 *elems, size_t elems_len, + enum cfg80211_rnr_iter_ret + (*iter)(void *data, u8 type, + const struct ieee80211_neighbor_ap_info *info, + const u8 *tbtt_info, u8 tbtt_info_len), + void *iter_data) { - struct ieee80211_neighbor_ap_info *ap_info; - const struct element *elem, *ssid_elem; + const struct element *rnr; const u8 *pos, *end; - u32 s_ssid_tmp; - int n_coloc = 0, ret; - LIST_HEAD(ap_list); - ret = cfg80211_calc_short_ssid(ies, &ssid_elem, &s_ssid_tmp); - if (ret) - return 0; + for_each_element_id(rnr, WLAN_EID_REDUCED_NEIGHBOR_REPORT, + elems, elems_len) { + const struct ieee80211_neighbor_ap_info *info; - for_each_element_id(elem, WLAN_EID_REDUCED_NEIGHBOR_REPORT, - ies->data, ies->len) { - pos = elem->data; - end = elem->data + elem->datalen; + pos = rnr->data; + end = rnr->data + rnr->datalen; /* RNR IE may contain more than one NEIGHBOR_AP_INFO */ - while (pos + sizeof(*ap_info) <= end) { - enum nl80211_band band; - int freq; + while (sizeof(*info) <= end - pos) { u8 length, i, count; + u8 type; - ap_info = (void *)pos; - count = u8_get_bits(ap_info->tbtt_info_hdr, - IEEE80211_AP_INFO_TBTT_HDR_COUNT) + 1; - length = ap_info->tbtt_info_len; + info = (void *)pos; + count = u8_get_bits(info->tbtt_info_hdr, + IEEE80211_AP_INFO_TBTT_HDR_COUNT) + + 1; + length = info->tbtt_info_len; - pos += sizeof(*ap_info); + pos += sizeof(*info); - if (!ieee80211_operating_class_to_band(ap_info->op_class, - &band)) - break; + if (count * length > end - pos) + return false; - freq = ieee80211_channel_to_frequency(ap_info->channel, - band); + type = u8_get_bits(info->tbtt_info_hdr, + IEEE80211_AP_INFO_TBTT_HDR_TYPE); - if (end - pos < count * length) - break; + for (i = 0; i < count; i++) { + switch (iter(iter_data, type, info, + pos, length)) { + case RNR_ITER_CONTINUE: + break; + case RNR_ITER_BREAK: + return true; + case RNR_ITER_ERROR: + return false; + } - if (u8_get_bits(ap_info->tbtt_info_hdr, - IEEE80211_AP_INFO_TBTT_HDR_TYPE) != - IEEE80211_TBTT_INFO_TYPE_TBTT) { - pos += count * length; - continue; + pos += length; } + } - /* TBTT info must include bss param + BSSID + - * (short SSID or same_ssid bit to be set). - * ignore other options, and move to the - * next AP info - */ - if (band != NL80211_BAND_6GHZ || - !(length == offsetofend(struct ieee80211_tbtt_info_7_8_9, - bss_params) || - length == sizeof(struct ieee80211_tbtt_info_7_8_9) || - length >= offsetofend(struct ieee80211_tbtt_info_ge_11, - bss_params))) { - pos += count * length; - continue; - } + if (pos != end) + return false; + } - for (i = 0; i < count; i++) { - struct cfg80211_colocated_ap *entry; + return true; +} + +struct colocated_ap_data { + const struct element *ssid_elem; + struct list_head ap_list; + u32 s_ssid_tmp; + int n_coloc; +}; - entry = kzalloc(sizeof(*entry) + IEEE80211_MAX_SSID_LEN, - GFP_ATOMIC); +static enum cfg80211_rnr_iter_ret +cfg80211_parse_colocated_ap_iter(void *_data, u8 type, + const struct ieee80211_neighbor_ap_info *info, + const u8 *tbtt_info, u8 tbtt_info_len) +{ + struct colocated_ap_data *data = _data; + struct cfg80211_colocated_ap *entry; + enum nl80211_band band; - if (!entry) - goto error; + if (type != IEEE80211_TBTT_INFO_TYPE_TBTT) + return RNR_ITER_CONTINUE; - entry->center_freq = freq; + if (!ieee80211_operating_class_to_band(info->op_class, &band)) + return RNR_ITER_CONTINUE; - if (!cfg80211_parse_ap_info(entry, pos, length, - ssid_elem, - s_ssid_tmp)) { - n_coloc++; - list_add_tail(&entry->list, &ap_list); - } else { - kfree(entry); - } + /* TBTT info must include bss param + BSSID + (short SSID or + * same_ssid bit to be set). Ignore other options, and move to + * the next AP info + */ + if (band != NL80211_BAND_6GHZ || + !(tbtt_info_len == offsetofend(struct ieee80211_tbtt_info_7_8_9, + bss_params) || + tbtt_info_len == sizeof(struct ieee80211_tbtt_info_7_8_9) || + tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11, + bss_params))) + return RNR_ITER_CONTINUE; + + entry = kzalloc(sizeof(*entry) + IEEE80211_MAX_SSID_LEN, GFP_ATOMIC); + if (!entry) + return RNR_ITER_ERROR; + + entry->center_freq = + ieee80211_channel_to_frequency(info->channel, band); + + if (!cfg80211_parse_ap_info(entry, tbtt_info, tbtt_info_len, + data->ssid_elem, data->s_ssid_tmp)) { + data->n_coloc++; + list_add_tail(&entry->list, &data->ap_list); + } else { + kfree(entry); + } - pos += length; - } - } + return RNR_ITER_CONTINUE; +} -error: - if (pos != end) { - cfg80211_free_coloc_ap_list(&ap_list); - return 0; - } +VISIBLE_IF_CFG80211_KUNIT int +cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies, + struct list_head *list) +{ + struct colocated_ap_data data = {}; + int ret; + + INIT_LIST_HEAD(&data.ap_list); + + ret = cfg80211_calc_short_ssid(ies, &data.ssid_elem, &data.s_ssid_tmp); + if (ret) + return 0; + + if (!cfg80211_iter_rnr(ies->data, ies->len, + cfg80211_parse_colocated_ap_iter, &data)) { + cfg80211_free_coloc_ap_list(&data.ap_list); + return 0; } - list_splice_tail(&ap_list, list); - return n_coloc; + list_splice_tail(&data.ap_list, list); + return data.n_coloc; } EXPORT_SYMBOL_IF_CFG80211_KUNIT(cfg80211_parse_colocated_ap); @@ -2607,79 +2647,71 @@ cfg80211_defrag_mle(const struct element *mle, const u8 *ie, size_t ielen, return NULL; } -static u8 -cfg80211_rnr_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id, - const struct ieee80211_neighbor_ap_info **ap_info, - u8 *param_ch_count) -{ - const struct ieee80211_neighbor_ap_info *info; - const struct element *rnr; - const u8 *pos, *end; - - for_each_element_id(rnr, WLAN_EID_REDUCED_NEIGHBOR_REPORT, ie, ielen) { - pos = rnr->data; - end = rnr->data + rnr->datalen; - - /* RNR IE may contain more than one NEIGHBOR_AP_INFO */ - while (sizeof(*info) <= end - pos) { - const struct ieee80211_rnr_mld_params *mld_params; - u16 params; - u8 length, i, count, mld_params_offset; - u8 type, lid; - u32 use_for; - - info = (void *)pos; - count = u8_get_bits(info->tbtt_info_hdr, - IEEE80211_AP_INFO_TBTT_HDR_COUNT) + 1; - length = info->tbtt_info_len; +struct tbtt_info_iter_data { + const struct ieee80211_neighbor_ap_info *ap_info; + u8 param_ch_count; + u32 use_for; + u8 mld_id, link_id; +}; - pos += sizeof(*info); +static enum cfg80211_rnr_iter_ret +cfg802121_mld_ap_rnr_iter(void *_data, u8 type, + const struct ieee80211_neighbor_ap_info *info, + const u8 *tbtt_info, u8 tbtt_info_len) +{ + const struct ieee80211_rnr_mld_params *mld_params; + struct tbtt_info_iter_data *data = _data; + u8 link_id; + + if (type == IEEE80211_TBTT_INFO_TYPE_TBTT && + tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11, + mld_params)) + mld_params = (void *)(tbtt_info + + offsetof(struct ieee80211_tbtt_info_ge_11, + mld_params)); + else if (type == IEEE80211_TBTT_INFO_TYPE_MLD && + tbtt_info_len >= sizeof(struct ieee80211_rnr_mld_params)) + mld_params = (void *)tbtt_info; + else + return RNR_ITER_CONTINUE; - if (count * length > end - pos) - return 0; + link_id = le16_get_bits(mld_params->params, + IEEE80211_RNR_MLD_PARAMS_LINK_ID); - type = u8_get_bits(info->tbtt_info_hdr, - IEEE80211_AP_INFO_TBTT_HDR_TYPE); + if (data->mld_id != mld_params->mld_id) + return RNR_ITER_CONTINUE; - if (type == IEEE80211_TBTT_INFO_TYPE_TBTT && - length >= - offsetofend(struct ieee80211_tbtt_info_ge_11, - mld_params)) { - mld_params_offset = - offsetof(struct ieee80211_tbtt_info_ge_11, mld_params); - use_for = NL80211_BSS_USE_FOR_ALL; - } else if (type == IEEE80211_TBTT_INFO_TYPE_MLD && - length >= sizeof(struct ieee80211_rnr_mld_params)) { - mld_params_offset = 0; - use_for = NL80211_BSS_USE_FOR_MLD_LINK; - } else { - pos += count * length; - continue; - } + if (data->link_id != link_id) + return RNR_ITER_CONTINUE; - for (i = 0; i < count; i++) { - mld_params = (void *)pos + mld_params_offset; - params = le16_to_cpu(mld_params->params); + data->ap_info = info; + data->param_ch_count = + le16_get_bits(mld_params->params, + IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT); - lid = u16_get_bits(params, - IEEE80211_RNR_MLD_PARAMS_LINK_ID); + if (type == IEEE80211_TBTT_INFO_TYPE_TBTT) + data->use_for = NL80211_BSS_USE_FOR_ALL; + else + data->use_for = NL80211_BSS_USE_FOR_MLD_LINK; + return RNR_ITER_BREAK; +} - if (mld_id == mld_params->mld_id && - link_id == lid) { - *ap_info = info; - *param_ch_count = - le16_get_bits(mld_params->params, - IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT); +static u8 +cfg80211_rnr_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id, + const struct ieee80211_neighbor_ap_info **ap_info, + u8 *param_ch_count) +{ + struct tbtt_info_iter_data data = { + .mld_id = mld_id, + .link_id = link_id, + }; - return use_for; - } + cfg80211_iter_rnr(ie, ielen, cfg802121_mld_ap_rnr_iter, &data); - pos += length; - } - } - } + *ap_info = data.ap_info; + *param_ch_count = data.param_ch_count; - return 0; + return data.use_for; } static struct element * From patchwork Fri Feb 16 11:54:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miri Korenblit X-Patchwork-Id: 773686 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2DA7B77F3F for ; Fri, 16 Feb 2024 11:54:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084498; cv=none; b=Bos1HJAqzLL8ILv5Goo6ZdRg9jW7Y7XBpX30YqtydUDhewousWrgNJqNlhMBCK2Ks5+1OSIcSA5tItTjxSmqoEcOZfnsHz/OGBlcB/jOkErSwwOAycZy9MlKdyHAONmH9C2uL+ZQ0hWozpsYM4pF9Ia1aA4IAyCSyAbGKYqi4ps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084498; c=relaxed/simple; bh=BjldIYSrBiB+GBQlfKKhorsMTLtAV7zoHOVeu2b+tb8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Ol1DxROLnASOxWL9GBecpikcBlTCzy36rka60LHHzI2WnrXD/Q3G6KyGuTdZFQHiWEQDmO9NOxu305859STpLZso6ytqExgiUjQDrGolcYhorPeFdjpxzTOjvOerEZl3vYtApxazDRY2kHZHhhRtFxc9SGwVkJUhu93Zdf4f6I0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=OEAxM/lY; arc=none smtp.client-ip=198.175.65.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="OEAxM/lY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1708084497; x=1739620497; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BjldIYSrBiB+GBQlfKKhorsMTLtAV7zoHOVeu2b+tb8=; b=OEAxM/lYHqIz9MvWOEzRUN1Z1G2Afn40ap51KjM8YNkJ80e71ks3+keW PmMviv3tm7MveFf/UHsytuqcFzpCXEVHXMHRthwLBlLw0bfCKU4r70yiA GMpzygqoj05Uj4/9uO8rV1MOkWZMj2SY6BZT+pXOAxVVvYjvNHUokBd1U yH9MCEGAETOTdN35KmtmIew+GhHfTda/of8aukYcg2jpj9x0hSzKu7QjB ymIEg26zBriV/tCf6t0ZAJjmpwvzisxSLbArOZvBzdQapgpOXv6Dk2Ipa cagRVpHSyqargIYnNVYWb86TgVzj3prw77W51QHsEh0mlyHc8VM8jDsH4 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10985"; a="2321925" X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="2321925" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="3795601" Received: from unknown (HELO WEIS0040.iil.intel.com) ([10.12.217.108]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:56 -0800 From: Miri Korenblit To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Johannes Berg Subject: [PATCH 5/7] wifi: mac80211: align ieee80211_mle_get_bss_param_ch_cnt() Date: Fri, 16 Feb 2024 13:54:31 +0200 Message-Id: <20240216135047.583309181bc3.Ia61cb0b4fc034d5ac8fcfaf6f6fb2e115fadafe7@changeid> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> References: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Intel Israel (74) Limited From: Johannes Berg Align the prototype of ieee80211_mle_get_bss_param_ch_cnt() to also take a u8 * like the other functions, and make it return -1 when the field isn't found, so that mac80211 can check that instead of explicitly open-coding the check. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit --- include/linux/ieee80211.h | 11 ++++++----- net/mac80211/mlme.c | 9 +++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index e4322238f273..303c75459897 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -4990,17 +4990,18 @@ static inline int ieee80211_mle_get_link_id(const u8 *data) /** * ieee80211_mle_get_bss_param_ch_cnt - returns the BSS parameter change count - * @mle: the basic multi link element + * @data: pointer to the basic multi link element * * The element is assumed to be of the correct type (BASIC) and big enough, * this must be checked using ieee80211_mle_type_ok(). * * If the BSS parameter change count value can't be found (the presence bit - * for it is clear), 0 will be returned. + * for it is clear), -1 will be returned. */ -static inline u8 -ieee80211_mle_get_bss_param_ch_cnt(const struct ieee80211_multi_link_elem *mle) +static inline int +ieee80211_mle_get_bss_param_ch_cnt(const u8 *data) { + const struct ieee80211_multi_link_elem *mle = (const void *)data; u16 control = le16_to_cpu(mle->control); const u8 *common = mle->variable; @@ -5008,7 +5009,7 @@ ieee80211_mle_get_bss_param_ch_cnt(const struct ieee80211_multi_link_elem *mle) common += sizeof(struct ieee80211_mle_basic_common_info); if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)) - return 0; + return -1; if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) common += 1; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e1554666d706..2f13451ba003 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -4202,13 +4202,14 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link, */ assoc_data->link[link_id].status = WLAN_STATUS_SUCCESS; if (elems->ml_basic) { - if (!(elems->ml_basic->control & - cpu_to_le16(IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT))) { + int bss_param_ch_cnt = + ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic); + + if (bss_param_ch_cnt < 0) { ret = false; goto out; } - link->u.mgd.bss_param_ch_cnt = - ieee80211_mle_get_bss_param_ch_cnt(elems->ml_basic); + link->u.mgd.bss_param_ch_cnt = bss_param_ch_cnt; } } else if (elems->parse_error & IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC || !elems->prof || From patchwork Fri Feb 16 11:54:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miri Korenblit X-Patchwork-Id: 774073 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A80477F3F for ; Fri, 16 Feb 2024 11:55:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084501; cv=none; b=FDDY/4Tz1OgJnv7q9kSiIsEm2jOaWp6izOtUUMRmre46jYv9a5h0TVSghVgmv89MpwK/zgwISU+1fYcVyI6DQ09pPBhgnDZk4IVkQHvwqTae7Sv1UYV4T1VA262kCGF1SKVGZRbyrDu9YcAxmGjdgz8+J6qw1iL7LXWneQWo24M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084501; c=relaxed/simple; bh=oU0kMhfMl708n20leEkeT9QNrTLv/EetNUIlektje2s=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=SJqqzANYA9u/SU5/chgfGbQ0576r3jTgd/PILSBrtUFafLqiI5/PRRMYWMMnem5lsIYxWtvrPvT48HfdFzw3TvYqKs3eqylmZs+36W7qpAX+0/SVnyT3eIux+vtpVT17W6eZw9eC2BQF1PZ8tyRdjTggrIvdDAvXRvA4jJI+6p4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=oG1ZBQyd; arc=none smtp.client-ip=198.175.65.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="oG1ZBQyd" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1708084500; x=1739620500; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oU0kMhfMl708n20leEkeT9QNrTLv/EetNUIlektje2s=; b=oG1ZBQydwX0XgaCGBMFaAv+zRnbnsA2qBwbumSCZnxhZd2nj4H+6OIrK U9LxLFmdkT8kUreT/OP2iLANZinLt5sFNxJlnTqmjJVWIhwxs+wsvlea1 Gl3NrFRV7EPYTQUpZnYMANH8LuKF193KnZc0SUrJOYlW2OXiln655FC4J ViEMMmefR3FiS/0yOjS47O+7mBC/cxGZQzfDD0P4u0Qwe70/5TK/97E50 e4SdsuvWWBAUxuWBr/2uNRlTm8CrmJBwPuF6JtlMDHgTd+KRcNhpJr1fK pOS2UhQM85bxuzd0RXTzfGUMq5L8OyLR98pQU0vtr3ooEZmkaojV3q2Ba A==; X-IronPort-AV: E=McAfee;i="6600,9927,10985"; a="2321929" X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="2321929" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:55:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="3795605" Received: from unknown (HELO WEIS0040.iil.intel.com) ([10.12.217.108]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:54:58 -0800 From: Miri Korenblit To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Johannes Berg Subject: [PATCH 6/7] wifi: cfg80211: use ML element parsing helpers Date: Fri, 16 Feb 2024 13:54:32 +0200 Message-Id: <20240216135047.4da47b1f035b.I437a5570ac456449facb0b147851ef24a1e473c2@changeid> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> References: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Intel Israel (74) Limited From: Johannes Berg Use the existing ML element parsing helpers and add a new one for this (ieee80211_mle_get_mld_id). Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit --- include/linux/ieee80211.h | 38 ++++++++++++++++++++++++++++++++++++ net/wireless/scan.c | 41 ++++++++------------------------------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 303c75459897..3385a2cc5b09 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -5115,6 +5115,44 @@ static inline u16 ieee80211_mle_get_mld_capa_op(const u8 *data) return get_unaligned_le16(common); } +/** + * ieee80211_mle_get_mld_id - returns the MLD ID + * @data: pointer to the multi link element + * + * The element is assumed to be of the correct type (BASIC) and big enough, + * this must be checked using ieee80211_mle_type_ok(). + * + * If the MLD ID is not present, 0 will be returned. + */ +static inline u8 ieee80211_mle_get_mld_id(const u8 *data) +{ + const struct ieee80211_multi_link_elem *mle = (const void *)data; + u16 control = le16_to_cpu(mle->control); + const u8 *common = mle->variable; + + /* + * common points now at the beginning of + * ieee80211_mle_basic_common_info + */ + common += sizeof(struct ieee80211_mle_basic_common_info); + + if (!(control & IEEE80211_MLC_BASIC_PRES_MLD_ID)) + return 0; + + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) + common += 1; + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) + common += 1; + if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) + common += 2; + if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) + common += 2; + if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) + common += 2; + + return *common; +} + /** * ieee80211_mle_size_ok - validate multi-link element size * @data: pointer to the element data diff --git a/net/wireless/scan.c b/net/wireless/scan.c index e46dfc71c497..7cf36b8d3ae7 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -2833,17 +2833,16 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy, struct cfg80211_bss *bss; u8 mld_id, reporter_link_id, bss_change_count; u16 seen_links = 0; - const u8 *pos; u8 i; - if (!ieee80211_mle_size_ok(elem->data + 1, elem->datalen - 1)) + if (!ieee80211_mle_type_ok(elem->data + 1, + IEEE80211_ML_CONTROL_TYPE_BASIC, + elem->datalen - 1)) return; - ml_elem = (void *)elem->data + 1; + ml_elem = (void *)(elem->data + 1); control = le16_to_cpu(ml_elem->control); - if (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE) != - IEEE80211_ML_CONTROL_TYPE_BASIC) - return; + ml_common_len = ml_elem->variable[0]; /* Must be present when transmitted by an AP (in a probe response) */ if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) || @@ -2851,24 +2850,8 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy, !(control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP)) return; - ml_common_len = ml_elem->variable[0]; - - /* length + MLD MAC address */ - pos = ml_elem->variable + 1 + 6; - - reporter_link_id = pos[0]; - pos += 1; - - bss_change_count = pos[0]; - pos += 1; - - if (u16_get_bits(control, IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY)) - pos += 2; - if (u16_get_bits(control, IEEE80211_MLC_BASIC_PRES_EML_CAPA)) - pos += 2; - - /* MLD capabilities and operations */ - pos += 2; + reporter_link_id = ieee80211_mle_get_link_id(elem->data + 1); + bss_change_count = ieee80211_mle_get_bss_param_ch_cnt(elem->data + 1); /* * The MLD ID of the reporting AP is always zero. It is set if the AP @@ -2876,15 +2859,7 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy, * relating to a nontransmitted BSS (matching the Multi-BSSID Index, * Draft P802.11be_D3.2, 35.3.4.2) */ - if (u16_get_bits(control, IEEE80211_MLC_BASIC_PRES_MLD_ID)) { - mld_id = *pos; - pos += 1; - } else { - mld_id = 0; - } - - /* Extended MLD capabilities and operations */ - pos += 2; + mld_id = ieee80211_mle_get_mld_id(elem->data + 1); /* Fully defrag the ML element for sta information/profile iteration */ mle = cfg80211_defrag_mle(elem, tx_data->ie, tx_data->ielen, gfp); From patchwork Fri Feb 16 11:54:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miri Korenblit X-Patchwork-Id: 773685 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 49E5678677 for ; Fri, 16 Feb 2024 11:55:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084504; cv=none; b=lq/Z9iYBEgx74+2HO/c9hm3IriGHfiynNtxrFHkwFYRe2zEEr/Hm60cCX4KbnCVNba5HloclHLUWA1gP209PSVQ171F1IHE7f3PvzknyvahyDDGbfsqTDfNOnppQVzFKg/NfmsrqQfBI0JPOXMtV4jbuu1kGzjbO7QVxvM6XW4E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708084504; c=relaxed/simple; bh=QAuuiswwm91RMzn9rmv9lhDLCjvf7228VRt8om8MfJg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=kwzMCPRfDzODs9cZhOzmPeAHG5zRcR7IOBNGh0cQ4V5ZKD1EjyvO6SsgmdIO6ZpcCSw3IB3VisyYTnAedyPxWgP7BWMrAmZhxtln1lYkIA78lrgJe/20e7lXurjJDCGQG68zBLa1cHQNzffr+3a+iW1RR4kp22zrKk+dUGcFgQw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=ehtu8yGS; arc=none smtp.client-ip=198.175.65.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="ehtu8yGS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1708084502; x=1739620502; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QAuuiswwm91RMzn9rmv9lhDLCjvf7228VRt8om8MfJg=; b=ehtu8yGSl9IHLdS1uPgAx4xJ3AIzyexK2AGrLe77i8VktbkFZJcrn50I b3gUzANOxXuCIsbr4oLRrJnEIrKUL8c6br1RfJc7w5Pf1SwaEPQ4Gj7z2 36tGxUMqpfz0QbAXovlAWYktJSd7BD+8khBi/01oVRIOB28QnC4hVXMeC g0BAOxmRDxWnC/ROu2jwXlVVFWuSslUg4qFcTkbpcXbHVIxS9oM1HWX81 FAol9sbEli0P/OwFmLI6KQykvoKN86N0Ga4+tKZWH7YwetKk11d8BzdES 2JEpOOH8vXZ4bUz6QRk/swnSWnSa4sJYnC6EY/jcM5polkWMabYe3Xp3I Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10985"; a="2321933" X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="2321933" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:55:02 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.06,164,1705392000"; d="scan'208";a="3795607" Received: from unknown (HELO WEIS0040.iil.intel.com) ([10.12.217.108]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2024 03:55:01 -0800 From: Miri Korenblit To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org Subject: [PATCH 7/7] wifi: mac80211: parse the BSS Load element Date: Fri, 16 Feb 2024 13:54:33 +0200 Message-Id: <20240216135047.b771830d9b12.If5885d651cb0114711ee1f6c1cb8fe31a69bf0a7@changeid> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> References: <20240216115433.1044027-1-miriam.rachel.korenblit@intel.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Intel Israel (74) Limited Some drivers need this. Parse the element and save the channel utilization field in the link conf. Signed-off-by: Miri Korenblit --- include/linux/ieee80211.h | 18 ++++++++++++++++++ include/net/mac80211.h | 7 +++++++ net/mac80211/ieee80211_i.h | 1 + net/mac80211/mlme.c | 5 +++++ net/mac80211/parse.c | 8 ++++++++ 5 files changed, 39 insertions(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 3385a2cc5b09..f23340654ecf 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1287,6 +1287,24 @@ struct ieee80211_ttlm_elem { u8 optional[]; } __packed; +/** + * struct ieee80211_bss_load_elem - BSS Load elemen + * + * Defined in section 9.4.2.26 in IEEE 802.11-REVme D4.1 + * + * @sta_count: total number of STAs currently associated with the AP. + * @channel_util: Percentage of time that the access point sensed the channel + * was busy. This value is in range [0, 255], the highest value means + * 100% busy. + * @avail_admission_capa: remaining amount of medium time used for admission + * control. + */ +struct ieee80211_bss_load_elem { + __le16 sta_count; + u8 channel_util; + __le16 avail_admission_capa; +} __packed; + struct ieee80211_mgmt { __le16 frame_control; __le16 duration; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index fc223761e3af..0af80a2b6cfc 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -671,6 +671,11 @@ struct ieee80211_fils_discovery { * processed after it switches back to %NULL. * @color_change_active: marks whether a color change is ongoing. * @color_change_color: the bss color that will be used after the change. + * @channel_util: Channel utilization as published by the AP in the + * WLAN_EID_QBSS_LOAD information element. An unsigned integer in the + * range [0,255], when 255 means the 100% busy. Valid only for a + * station, and only when associated. Will be -1 if AP didn't + * send the element. * @ht_ldpc: in AP mode, indicates interface has HT LDPC capability. * @vht_ldpc: in AP mode, indicates interface has VHT LDPC capability. * @he_ldpc: in AP mode, indicates interface has HE LDPC capability. @@ -774,6 +779,8 @@ struct ieee80211_bss_conf { bool color_change_active; u8 color_change_color; + s16 channel_util; + bool ht_ldpc; bool vht_ldpc; bool he_ldpc; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f3edb1a148a7..7bc1e55de358 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1741,6 +1741,7 @@ struct ieee802_11_elems { const struct ieee80211_multi_link_elem *ml_reconf; const struct ieee80211_bandwidth_indication *bandwidth_indication; const struct ieee80211_ttlm_elem *ttlm[IEEE80211_TTLM_MAX_CNT]; + const struct ieee80211_bss_load_elem *bss_load; /* length of them, respectively */ u8 ext_capab_len; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2f13451ba003..8a9c9188eb65 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3078,6 +3078,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, /* other links will be destroyed */ sdata->deflink.u.mgd.bss = NULL; sdata->deflink.smps_mode = IEEE80211_SMPS_OFF; + sdata->deflink.conf->channel_util = -1; netif_carrier_off(sdata->dev); @@ -6359,6 +6360,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link, erp_valid = false; } + bss_conf->channel_util = + elems->bss_load ? elems->bss_load->channel_util : -1; + if (!ieee80211_is_s1g_beacon(hdr->frame_control)) changed |= ieee80211_handle_bss_capability(link, le16_to_cpu(mgmt->u.beacon.capab_info), @@ -7444,6 +7448,7 @@ void ieee80211_mgd_setup_link(struct ieee80211_link_data *link) link->u.mgd.p2p_noa_index = -1; link->conf->bssid = link->u.mgd.bssid; link->smps_mode = IEEE80211_SMPS_OFF; + link->conf->channel_util = -1; wiphy_work_init(&link->u.mgd.request_smps_work, ieee80211_request_smps_mgd_work); diff --git a/net/mac80211/parse.c b/net/mac80211/parse.c index 196a882e4c19..07bb21a92360 100644 --- a/net/mac80211/parse.c +++ b/net/mac80211/parse.c @@ -203,6 +203,7 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params, case WLAN_EID_CF_PARAMS: case WLAN_EID_TIM: case WLAN_EID_IBSS_PARAMS: + case WLAN_EID_QBSS_LOAD: case WLAN_EID_CHALLENGE: case WLAN_EID_RSN: case WLAN_EID_ERP_INFO: @@ -297,6 +298,13 @@ _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params, elem_parse_failed = IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; break; + case WLAN_EID_QBSS_LOAD: + if (elen == sizeof(struct ieee80211_bss_load_elem)) + elems->bss_load = (void *)pos; + else + elem_parse_failed = + IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; + break; case WLAN_EID_VENDOR_SPECIFIC: if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && pos[2] == 0xf2) {