diff mbox series

mac80211: disable BSS color collision detection in case of no free colors

Message ID 1638506507-21139-1-git-send-email-quic_ramess@quicinc.com
State New
Headers show
Series mac80211: disable BSS color collision detection in case of no free colors | expand

Commit Message

Rameshkumar Sundaram Dec. 3, 2021, 4:41 a.m. UTC
From: Lavanya Suresh <lavaks@codeaurora.org>

AP may run out of BSS color after color collision
detection event from driver.
Disable BSS color collision detection if no free colors are available
based on bss color disabled bit of he_oper_params in beacon.
It can be reenabled once new color is available.

Signed-off-by: Lavanya Suresh <lavaks@codeaurora.org>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
---
 include/linux/ieee80211.h |  1 +
 net/mac80211/cfg.c        | 23 +++++++++++++++++++++++
 2 files changed, 24 insertions(+)
diff mbox series

Patch

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 11d7af2..cc629d7 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1874,6 +1874,7 @@  struct ieee80211_he_mcs_nss_supp {
 	__le16 tx_mcs_80p80;
 } __packed;
 
+#define HE_OPERATION_BSS_COLOR_DISABLED		((u32)BIT(31))
 /**
  * struct ieee80211_he_operation - HE capabilities element
  *
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f36f249..eaa04b7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -995,6 +995,8 @@  static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
 	struct beacon_data *new, *old;
 	int new_head_len, new_tail_len;
 	int size, err;
+	const u8 *cap;
+	struct ieee80211_he_operation *he_oper = NULL;
 	u32 changed = BSS_CHANGED_BEACON;
 
 	old = sdata_dereference(sdata->u.ap.beacon, sdata);
@@ -1082,6 +1084,27 @@  static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
 		changed |= BSS_CHANGED_FTM_RESPONDER;
 	}
 
+	if (sdata->vif.bss_conf.he_support) {
+		cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_OPERATION,
+					   params->tail, params->tail_len);
+		if (cap && cap[1] >= sizeof(*he_oper) + 1)
+			he_oper = (void *)(cap + 3);
+
+		if (he_oper) {
+			if (he_oper->he_oper_params & HE_OPERATION_BSS_COLOR_DISABLED) {
+				if (sdata->vif.bss_conf.he_bss_color.enabled) {
+					sdata->vif.bss_conf.he_bss_color.enabled = false;
+					changed |= BSS_CHANGED_HE_BSS_COLOR;
+				}
+			} else {
+				if (!sdata->vif.bss_conf.he_bss_color.enabled) {
+					sdata->vif.bss_conf.he_bss_color.enabled = true;
+					changed |= BSS_CHANGED_HE_BSS_COLOR;
+				}
+			}
+		}
+	}
+
 	rcu_assign_pointer(sdata->u.ap.beacon, new);
 
 	if (old)