Search Linux Wireless

[PATCH] wifi: mac80211: check the control channel before downgrading the bandwidth

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When the link fails to use the channel, chandef's bandwidth will be 
downgraded without checking the control channel.
The issue happens when the STA of an extender with limited channel 
context associates with a root AP operating on a different channel.

Below is an example:

    ______________           ________________
   | RootAP(ch36) |         | Extender(ch44) |
   |              | (ASSOC) |       AP       |
   |      AP <-------------------- STA       |
   |______________|         |________________|

- RootAP is operating on channel 36, while Extender is operating
  on channel 44
- When associating with RootAP, Extender-STA downgrades the
  chandef's bandwidth to be compatible with any channels on the phy
- Finally, chandef's bandwidth is downgraded to 20MHz and 
  the association fails

In this patch, a control channel checking is added to avoid unnecessary
bandwidth downgrading

Signed-off-by: Michael Lee <michael-cy.lee@xxxxxxxxxxxx>
---
 net/mac80211/mlme.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 0aee2392dd29..bc435e8508e2 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4616,6 +4616,27 @@ ieee80211_verify_sta_he_mcs_support(struct ieee80211_sub_if_data *sdata,
 	return false;
 }
 
+static bool
+ieee80211_check_same_ctrl_channel(struct ieee80211_sub_if_data *sdata,
+				  const struct cfg80211_chan_def *chandef)
+{
+	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_chanctx *ctx;
+
+	mutex_lock(&local->chanctx_mtx);
+	list_for_each_entry(ctx, &local->chanctx_list, list) {
+		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
+			continue;
+		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
+			continue;
+		if (chandef->chan == ctx->conf.def.chan)
+			return true;
+	}
+
+	mutex_unlock(&local->chanctx_mtx);
+	return false;
+}
+
 static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 				  struct ieee80211_link_data *link,
 				  struct cfg80211_bss *cbss,
@@ -4842,6 +4863,9 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 	    chandef.width == NL80211_CHAN_WIDTH_10)
 		goto out;
 
+	if (!ret || !ieee80211_check_same_ctrl_channel(sdata, &chandef))
+		goto out;
+
 	while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
 		*conn_flags |=
 			ieee80211_chandef_downgrade(&chandef);
-- 
2.25.1




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux