Browse Source

qcacld-3.0: Enable dynamic puncture for DFS radar

Once the radar is found, identify the affected sub 20 MHz channels in the
current channel. From the  position(s) of the sub 20 MHz subchannels, find
the nearest valid puncturing pattern.
If a valid puncturing pattern is found, find the corresponding reduced
bandwidth new channel for the legacy ( <= 11AX) devices and send CSA. At
the end of CSA, do a vdev restart so that the 11BE devices see a new
puncturing pattern.
And If not found, then fallback to the default behavior of changing channel
using Random channel selection.

Change-Id: I41e6206f310722bc3dacc9ce8d024f679ff1af3e
CRs-Fixed: 3386022
Jianmin Zhu 2 years ago
parent
commit
589a32f847

+ 1 - 0
Kbuild

@@ -4205,6 +4205,7 @@ endif
 cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DDFS_COMPONENT_ENABLE
 cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DQCA_DFS_USE_POLICY_MANAGER
 cppflags-$(CONFIG_WLAN_DFS_MASTER_ENABLE) += -DQCA_DFS_NOL_PLATFORM_DRV_SUPPORT
+cppflags-$(CONFIG_QCA_DFS_BW_PUNCTURE) += -DQCA_DFS_BW_PUNCTURE
 
 cppflags-$(CONFIG_WLAN_DEBUGFS) += -DWLAN_DEBUGFS
 cppflags-$(CONFIG_WLAN_STREAMFS) += -DWLAN_STREAMFS

+ 2 - 0
configs/kiwi_v2_defconfig

@@ -55,6 +55,8 @@ CONFIG_WLAN_FEATURE_COAP := y
 #Enable TSF read using scratch register
 CONFIG_QCA_GET_TSF_VIA_REG := y
 
+CONFIG_QCA_DFS_BW_PUNCTURE := y
+
 ifeq ($(CONFIG_ARCH_SDXPINN), y)
 CONFIG_DP_FEATURE_HW_COOKIE_CONVERSION := n
 CONFIG_DP_HW_COOKIE_CONVERT_EXCEPTION := n

+ 5 - 1
core/mac/inc/sir_api.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -5253,6 +5253,7 @@ struct sir_update_session_txq_edca_param {
  * @sec_ch_offset: second channel offset
  * @center_freq_seg0: channel center freq 0
  * @center_freq_seg1: channel center freq 1
+ * @target_punc_bitmap: New channel puncturing bitmap
  * @dot11mode: dot11 mode
  * @nw_type: nw type
  * @cac_duration_ms:  cac duration in ms
@@ -5267,6 +5268,9 @@ struct channel_change_req {
 	enum phy_ch_width ch_width;
 	uint8_t center_freq_seg0;
 	uint8_t center_freq_seg1;
+#ifdef WLAN_FEATURE_11BE
+	uint16_t target_punc_bitmap;
+#endif
 	uint32_t dot11mode;
 	tSirNwType nw_type;
 	uint32_t cac_duration_ms;

+ 33 - 2
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -8556,6 +8556,27 @@ static void lim_change_channel(
 					      session_entry);
 }
 
+#ifdef WLAN_FEATURE_11BE
+static bool
+lim_is_puncture_bitmap_changed(struct pe_session *session,
+			       struct channel_change_req *ch_change_req)
+{
+	uint16_t ori_puncture_bitmap;
+
+	ori_puncture_bitmap =
+		*(uint16_t *)session->eht_op.disabled_sub_chan_bitmap;
+
+	return ori_puncture_bitmap != ch_change_req->target_punc_bitmap;
+}
+#else
+static inline bool
+lim_is_puncture_bitmap_changed(struct pe_session *session,
+			       struct channel_change_req *ch_change_req)
+{
+	return false;
+}
+#endif
+
 /**
  * lim_process_sme_channel_change_request() - process sme ch change req
  *
@@ -8600,8 +8621,10 @@ static void lim_process_sme_channel_change_request(struct mac_context *mac_ctx,
 		return;
 	}
 
-	if (session_entry->curr_op_freq == target_freq &&
-	    session_entry->ch_width == ch_change_req->ch_width) {
+	if ((session_entry->curr_op_freq == target_freq &&
+	     session_entry->ch_width == ch_change_req->ch_width) &&
+	    (!IS_DOT11_MODE_EHT(session_entry->dot11mode) ||
+	     !lim_is_puncture_bitmap_changed(session_entry, ch_change_req))) {
 		pe_err("Target channel and mode is same as current channel and mode channel freq %d and mode %d",
 		       session_entry->curr_op_freq, session_entry->ch_width);
 		return;
@@ -9165,6 +9188,14 @@ static void lim_process_sme_dfs_csa_ie_request(struct mac_context *mac_ctx,
 	session_entry->dfsIncludeChanSwIe = true;
 	session_entry->gLimChannelSwitch.switchCount =
 		 dfs_csa_ie_req->ch_switch_beacon_cnt;
+
+	wlan_reg_set_create_punc_bitmap(&dfs_csa_ie_req->ch_params, false);
+	wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
+						dfs_csa_ie_req->target_chan_freq,
+						0,
+						&dfs_csa_ie_req->ch_params,
+						REG_CURRENT_PWR_MODE);
+
 	ch_width = dfs_csa_ie_req->ch_params.ch_width;
 	if (ch_width >= CH_WIDTH_160MHZ &&
 	    wma_get_vht_ch_width() < WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) {

+ 2 - 1
core/mac/src/pe/lim/lim_utils.c

@@ -10802,7 +10802,8 @@ QDF_STATUS lim_pre_vdev_start(struct mac_context *mac,
 		if (ch_params.mhz_freq_seg0 ==  session->curr_op_freq - 10)
 			sec_chan_freq = session->curr_op_freq - 20;
 	}
-	if (LIM_IS_AP_ROLE(session))
+	if (LIM_IS_AP_ROLE(session) &&
+	    !mlme_is_chan_switch_in_progress(mlme_obj->vdev))
 		lim_apply_puncture(mac, session, ch_params.mhz_freq_seg1);
 
 	if (IS_DOT11_MODE_EHT(session->dot11mode))

+ 72 - 6
core/sap/src/sap_fsm.c

@@ -169,13 +169,75 @@ static uint8_t *sap_hdd_event_to_string(eSapHddEvent event)
 	}
 }
 
-/*----------------------------------------------------------------------------
- * Externalized Function Definitions
- * -------------------------------------------------------------------------*/
+#ifdef QCA_DFS_BW_PUNCTURE
+/**
+ * sap_is_chan_change_needed() - Check if SAP channel change needed
+ * @sap_ctx: sap context.
+ *
+ * Even some 20 MHz sub channel disabled for nol, if puncture pattern is valid,
+ * SAP still can keep current channel width and primary channel, don't need
+ * change channel.
+ *
+ * Return: bool, true: channel change needed
+ */
+static bool
+sap_is_chan_change_needed(struct sap_context *sap_ctx)
+{
+	uint8_t ch_wd;
+	uint16_t pri_freq_puncture = 0;
+	struct ch_params *ch_params;
+	QDF_STATUS status;
+	struct mac_context *mac_ctx;
 
-/*----------------------------------------------------------------------------
- * Function Declarations and Documentation
- * -------------------------------------------------------------------------*/
+	mac_ctx = sap_get_mac_context();
+	if (!mac_ctx) {
+		sap_err("Invalid MAC context");
+		return true;
+	}
+
+	ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
+	if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) {
+		ch_wd = sap_ctx->ch_width_orig;
+		mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd;
+	} else {
+		ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth;
+	}
+
+	ch_params->ch_width = ch_wd;
+
+	if (sap_phymode_is_eht(sap_ctx->phyMode))
+		wlan_reg_set_create_punc_bitmap(ch_params, true);
+	wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
+						sap_ctx->chan_freq,
+						0,
+						ch_params,
+						REG_CURRENT_PWR_MODE);
+	if (ch_params->ch_width == sap_ctx->ch_params.ch_width) {
+		status = wlan_reg_extract_puncture_by_bw(ch_params->ch_width,
+							 ch_params->reg_punc_bitmap,
+							 sap_ctx->chan_freq,
+							 ch_params->mhz_freq_seg1,
+							 CH_WIDTH_20MHZ,
+							 &pri_freq_puncture);
+		if (QDF_IS_STATUS_SUCCESS(status) && !pri_freq_puncture) {
+			sap_debug("Eht valid puncture : 0x%x, keep freq %d",
+				  ch_params->reg_punc_bitmap,
+				  sap_ctx->chan_freq);
+			mac_ctx->sap.SapDfsInfo.new_chanWidth =
+						ch_params->ch_width;
+			return false;
+		}
+	}
+
+	return true;
+}
+#else
+static inline bool
+sap_is_chan_change_needed(struct sap_context *sap_ctx)
+{
+	return true;
+}
+#endif
 
 #ifdef DFS_COMPONENT_ENABLE
 /**
@@ -271,6 +333,7 @@ static qdf_freq_t sap_random_channel_sel(struct sap_context *sap_ctx)
 				     (void *)eSAP_STATUS_SUCCESS);
 		return 0;
 	}
+
 	mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_params->ch_width;
 	sap_ctx->ch_params.ch_width = ch_params->ch_width;
 	sap_ctx->ch_params.sec_ch_offset = ch_params->sec_ch_offset;
@@ -4520,6 +4583,9 @@ qdf_freq_t sap_indicate_radar(struct sap_context *sap_ctx)
 	    (void *) eSAP_STATUS_SUCCESS)))
 		return 0;
 
+	if (!sap_is_chan_change_needed(sap_ctx))
+		return sap_ctx->chan_freq;
+
 	chan_freq = sap_random_channel_sel(sap_ctx);
 	if (!chan_freq)
 		sap_signal_hdd_event(sap_ctx, NULL,

+ 17 - 0
core/sap/src/sap_module.c

@@ -1824,6 +1824,21 @@ void wlansap_get_sec_channel(uint8_t sec_ch_offset,
 	}
 }
 
+#ifdef WLAN_FEATURE_11BE
+static void
+wlansap_fill_channel_change_puncture(struct channel_change_req *req,
+				     struct ch_params *ch_param)
+{
+	req->target_punc_bitmap = ch_param->reg_punc_bitmap;
+}
+#else
+static inline void
+wlansap_fill_channel_change_puncture(struct channel_change_req *req,
+				     struct ch_params *ch_param)
+{
+}
+#endif
+
 /**
  * wlansap_fill_channel_change_request() - Fills the channel change request
  * @sap_ctx: sap context
@@ -1868,6 +1883,8 @@ wlansap_fill_channel_change_request(struct sap_context *sap_ctx,
 	req->ch_width =  sap_ctx->ch_params.ch_width;
 	req->center_freq_seg0 = sap_ctx->ch_params.center_freq_seg0;
 	req->center_freq_seg1 = sap_ctx->ch_params.center_freq_seg1;
+	wlansap_fill_channel_change_puncture(req, &sap_ctx->ch_params);
+
 	req->dot11mode = dot11_cfg.dot11_mode;
 	req->nw_type = dot11_cfg.nw_type;