All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luca Coelho <luca@coelho.fi>
To: johannes@sipsolutions.net
Cc: luca@coelho.fi, linux-wireless@vger.kernel.org
Subject: [PATCH v2] cfg80211: Use the HE operation IE to determine a 6GHz BSS channel
Date: Thu,  2 Dec 2021 14:36:10 +0200	[thread overview]
Message-ID: <iwlwifi.20211202143322.71eb2176e54e.I130f678e4aa390973ab39d838bbfe7b2d54bff8e@changeid> (raw)
In-Reply-To: <iwlwifi.20211129152938.8efcf1856975.I130f678e4aa390973ab39d838bbfe7b2d54bff8e@changeid>

From: Ayala Beker <ayala.beker@intel.com>

A non-collocated AP whose primary channel is not a PSC channel
may transmit a duplicated beacon on the corresponding PSC channel
in which it would indicate its true primary channel.
Use this inforamtion contained in the HE operation IE to determine
the primary channel of the AP.
In case of invalid infomration ignore it and use the channel
the frame was received on.

Signed-off-by: Ayala Beker <ayala.beker@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---

In v2, I  changed the patch so it will fit the code after the refactor.  This includes:

    * add the ftype to cfg80211_get_ies_channel_number();
    * return the channel number if !beacon or it's a dup beacon;
    * move the other checks to the caller function.

include/net/cfg80211.h | 24 ++++++++++---------
 net/wireless/scan.c    | 54 ++++++++++++++++++++++++++++++++++++------
 2 files changed, 60 insertions(+), 18 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b9b269504591..28f135873286 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -6385,17 +6385,6 @@ static inline void cfg80211_gen_new_bssid(const u8 *bssid, u8 max_bssid,
 	u64_to_ether_addr(new_bssid_u64, new_bssid);
 }
 
-/**
- * cfg80211_get_ies_channel_number - returns the channel number from ies
- * @ie: IEs
- * @ielen: length of IEs
- * @band: enum nl80211_band of the channel
- *
- * Returns the channel number, or -1 if none could be determined.
- */
-int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen,
-				    enum nl80211_band band);
-
 /**
  * cfg80211_is_element_inherited - returns if element ID should be inherited
  * @element: element to check
@@ -6431,6 +6420,19 @@ enum cfg80211_bss_frame_type {
 	CFG80211_BSS_FTYPE_PRESP,
 };
 
+/**
+ * cfg80211_get_ies_channel_number - returns the channel number from ies
+ * @ie: IEs
+ * @ielen: length of IEs
+ * @band: enum nl80211_band of the channel
+ * @ftype: frame type
+ *
+ * Returns the channel number, or -1 if none could be determined.
+ */
+int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen,
+				    enum nl80211_band band,
+				    enum cfg80211_bss_frame_type ftype);
+
 /**
  * cfg80211_inform_bss_data - inform cfg80211 of a new BSS
  *
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 22e92be61938..350d90d7b01c 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1795,12 +1795,31 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
 }
 
 int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen,
-				    enum nl80211_band band)
+				    enum nl80211_band band,
+				    enum cfg80211_bss_frame_type ftype)
 {
 	const u8 *tmp;
 	int channel_number = -1;
 
-	if (band == NL80211_BAND_S1GHZ) {
+	if (band == NL80211_BAND_6GHZ) {
+		const struct element *elem;
+
+		elem = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ie,
+					      ielen);
+		if (elem && elem->datalen >= ieee80211_he_oper_size(&elem->data[1])) {
+			struct ieee80211_he_operation *he_oper =
+				(void *)(&elem->data[1]);
+			const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
+
+			he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
+			if (!he_6ghz_oper)
+				return channel_number;
+
+			if (ftype != CFG80211_BSS_FTYPE_BEACON ||
+			    he_6ghz_oper->control & IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON)
+				channel_number = he_6ghz_oper->primary;
+		}
+	} else if (band == NL80211_BAND_S1GHZ) {
 		tmp = cfg80211_find_ie(WLAN_EID_S1G_OPERATION, ie, ielen);
 		if (tmp && tmp[1] >= sizeof(struct ieee80211_s1g_oper_ie)) {
 			struct ieee80211_s1g_oper_ie *s1gop = (void *)(tmp + 2);
@@ -1831,18 +1850,20 @@ EXPORT_SYMBOL(cfg80211_get_ies_channel_number);
  * from neighboring channels and the Beacon frames use the DSSS Parameter Set
  * element to indicate the current (transmitting) channel, but this might also
  * be needed on other bands if RX frequency does not match with the actual
- * operating channel of a BSS.
+ * operating channel of a BSS, or if the AP reports a different primary channel.
  */
 static struct ieee80211_channel *
 cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
 			 struct ieee80211_channel *channel,
-			 enum nl80211_bss_scan_width scan_width)
+			 enum nl80211_bss_scan_width scan_width,
+			 enum cfg80211_bss_frame_type ftype)
 {
 	u32 freq;
 	int channel_number;
 	struct ieee80211_channel *alt_channel;
 
-	channel_number = cfg80211_get_ies_channel_number(ie, ielen, channel->band);
+	channel_number = cfg80211_get_ies_channel_number(ie, ielen,
+							 channel->band, ftype);
 
 	if (channel_number < 0) {
 		/* No channel information in frame payload */
@@ -1850,6 +1871,16 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
 	}
 
 	freq = ieee80211_channel_to_freq_khz(channel_number, channel->band);
+
+	/*
+	 * In 6GHz, duplicated beacon indication is relevant for
+	 * beacons only.
+	 */
+	if (channel->band == NL80211_BAND_6GHZ &&
+	    (freq == channel->center_freq ||
+	     abs(freq - channel->center_freq) > 80))
+		return channel;
+
 	alt_channel = ieee80211_get_channel_khz(wiphy, freq);
 	if (!alt_channel) {
 		if (channel->band == NL80211_BAND_2GHZ) {
@@ -1911,7 +1942,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
 		return NULL;
 
 	channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan,
-					   data->scan_width);
+					   data->scan_width, ftype);
 	if (!channel)
 		return NULL;
 
@@ -2333,6 +2364,7 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
 	size_t ielen, min_hdr_len = offsetof(struct ieee80211_mgmt,
 					     u.probe_resp.variable);
 	int bss_type;
+	enum cfg80211_bss_frame_type ftype;
 
 	BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
 			offsetof(struct ieee80211_mgmt, u.beacon.variable));
@@ -2369,8 +2401,16 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
 			variable = ext->u.s1g_beacon.variable;
 	}
 
+	if (ieee80211_is_beacon(mgmt->frame_control))
+		ftype = CFG80211_BSS_FTYPE_BEACON;
+	else if (ieee80211_is_probe_resp(mgmt->frame_control))
+		ftype = CFG80211_BSS_FTYPE_PRESP;
+	else
+		ftype = CFG80211_BSS_FTYPE_UNKNOWN;
+
 	channel = cfg80211_get_bss_channel(wiphy, variable,
-					   ielen, data->chan, data->scan_width);
+					   ielen, data->chan, data->scan_width,
+					   ftype);
 	if (!channel)
 		return NULL;
 
-- 
2.33.1


  parent reply	other threads:[~2021-12-02 12:36 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-29 13:32 [PATCH 00/16] cfg80211/mac80211 patches from our internal tree 2021-11-29 Luca Coelho
2021-11-29 13:32 ` [PATCH 01/16] mac80211: add more HT/VHT/HE state logging Luca Coelho
2021-11-30  9:05   ` kernel test robot
2021-11-30  9:26   ` kernel test robot
2021-11-30  9:26     ` kernel test robot
2021-11-30 11:15   ` Luca Coelho
2021-11-30 11:16   ` [PATCH v2] " Luca Coelho
2021-11-30 15:50     ` Ben Greear
2021-11-29 13:32 ` [PATCH 02/16] cfg80211: Add support for notifying association comeback Luca Coelho
2021-11-29 13:32 ` [PATCH 03/16] mac80211: Notify cfg80211 about " Luca Coelho
2021-11-29 13:32 ` [PATCH 04/16] cfg80211: Use the HE operation IE to determine a 6GHz BSS channel Luca Coelho
2021-11-30  8:14   ` kernel test robot
2021-11-30 11:18   ` kernel test robot
2021-11-30 11:18     ` kernel test robot
2021-11-30 11:49   ` kernel test robot
2021-12-02 12:28   ` Luca Coelho
2021-12-02 12:36   ` Luca Coelho [this message]
2021-11-29 13:32 ` [PATCH 05/16] [BUGFIX] cfg80211: check fixed size before ieee80211_he_oper_size() Luca Coelho
2021-11-29 13:32 ` [PATCH 06/16] mac80211: introduce channel switch disconnect function Luca Coelho
2021-11-29 13:32 ` [PATCH 07/16] mac80211: mark TX-during-stop for TX in in_reconfig Luca Coelho
2021-11-29 13:32 ` [PATCH 08/16] mac80211: do drv_reconfig_complete() before restarting all Luca Coelho
2021-11-29 13:32 ` [PATCH 09/16] cfg80211: Fix order of enum nl80211_band_iftype_attr documentation Luca Coelho
2021-11-29 13:32 ` [PATCH 10/16] mac80211: update channel context before station state Luca Coelho
2021-11-29 13:32 ` [PATCH 11/16] cfg80211: simplify cfg80211_chandef_valid() Luca Coelho
2021-11-29 13:32 ` [PATCH 12/16] mac80211: Remove a couple of obsolete TODO Luca Coelho
2021-11-29 13:32 ` [PATCH 13/16] mac80211: Fix the size used for building probe request Luca Coelho
2021-11-29 13:32 ` [PATCH 14/16] mac80211: fix lookup when adding AddBA extension element Luca Coelho
2021-11-29 13:32 ` [PATCH 15/16] mac80211: agg-tx: don't schedule_and_wake_txq() under sta->lock Luca Coelho
2021-11-29 13:54   ` Toke Høiland-Jørgensen
2021-11-30 11:12     ` Luca Coelho
2021-11-30 11:32       ` Toke Høiland-Jørgensen
2021-11-30 11:52         ` Johannes Berg
2021-11-30 11:56           ` Toke Høiland-Jørgensen
2021-11-30 11:57           ` Luca Coelho
2021-11-30 12:08             ` Johannes Berg
2021-12-02 13:26   ` [PATCH v2] " Luca Coelho
2021-11-29 13:32 ` [PATCH 16/16] cfg80211: Acquire wiphy mutex on regulatory work Luca Coelho
2021-12-01 13:47   ` Kalle Valo
2021-12-02 13:27     ` Luca Coelho
2021-12-02 13:28   ` [PATCH v2] " Luca Coelho

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=iwlwifi.20211202143322.71eb2176e54e.I130f678e4aa390973ab39d838bbfe7b2d54bff8e@changeid \
    --to=luca@coelho.fi \
    --cc=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.