Преглед изворни кода

qcacld-3.0: Refine SAP force SCC target channel bandwdith selection

Merge the bandwidth selection of the two API
wlansap_get_csa_chanwidth_from_phymode &
wlan_sap_get_concurrent.
Update 5G Force SCC target Max BW selection for dbs hw:
1. Max BW 80Mhz if sta_sap_scc_on_dfs_chan = 1 and Single SAP
2. Max BW 80Mhz if sta_sap_scc_on_dfs_chan = 0 and STA+SAP SCC
3. other case use User configured BW

The above Max BW value will be limited by SAP user configured
BW at the end.

Change-Id: I1b165d1411288ca6845f90103adbf8bbfc34f67d
CRs-Fixed: 2925750
Liangwei Dong пре 4 година
родитељ
комит
9a7ab6fe1d

+ 6 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -1462,6 +1462,8 @@ struct policy_mgr_sme_cbacks {
  * @wlan_hdd_set_sap_csa_reason: Set the sap csa reason in cases like NAN.
  * @hdd_get_ap_6ghz_capable: get ap vdev 6ghz capable info from hdd ap adapter.
  * @wlan_hdd_indicate_active_ndp_cnt: indicate active ndp cnt to hdd
+ * @wlan_get_ap_prefer_conc_ch_params: get prefer ap channel bw parameters
+ *  based on target channel frequency and concurrent connections.
  */
 struct policy_mgr_hdd_cbacks {
 	void (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc,
@@ -1483,6 +1485,10 @@ struct policy_mgr_hdd_cbacks {
 					    uint8_t vdev_id);
 	void (*wlan_hdd_indicate_active_ndp_cnt)(struct wlan_objmgr_psoc *psoc,
 						 uint8_t vdev_id, uint8_t cnt);
+	QDF_STATUS (*wlan_get_ap_prefer_conc_ch_params)(
+			struct wlan_objmgr_psoc *psoc,
+			uint8_t vdev_id, uint32_t chan_freq,
+			struct ch_params *ch_params);
 };
 
 

+ 28 - 4
components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -2156,6 +2156,7 @@ static uint32_t policy_mgr_select_2g_chan(struct wlan_objmgr_psoc *psoc)
  * @sap_ch_freq: SAP starting channel
  * @sap_vdev_id: sap vdev id
  * @vdev_opmode: vdev opmode
+ * @ch_params: channel bw parameters
  *
  * Validate whether SAP can be forced scc to 6ghz band or not.
  * If not, select 2G band channel for DBS hw
@@ -2165,10 +2166,18 @@ static uint32_t policy_mgr_select_2g_chan(struct wlan_objmgr_psoc *psoc)
  */
 static QDF_STATUS policy_mgr_check_6ghz_sap_conc(
 	struct wlan_objmgr_psoc *psoc, uint32_t *con_ch_freq,
-	uint32_t sap_ch_freq, uint8_t sap_vdev_id, enum QDF_OPMODE vdev_opmode)
+	uint32_t sap_ch_freq, uint8_t sap_vdev_id, enum QDF_OPMODE vdev_opmode,
+	struct ch_params *ch_params)
 {
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
 	uint32_t ch_freq = *con_ch_freq;
 
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
 	if (ch_freq && WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) &&
 	    !WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) &&
 	    !policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL)) {
@@ -2193,6 +2202,10 @@ static QDF_STATUS policy_mgr_check_6ghz_sap_conc(
 	}
 	if (ch_freq != sap_ch_freq)
 		*con_ch_freq = ch_freq;
+	if (*con_ch_freq &&
+	    pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params)
+		pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
+			psoc, sap_vdev_id, ch_freq, ch_params);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -2210,6 +2223,7 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
 	struct wlan_objmgr_vdev *vdev;
 	enum QDF_OPMODE vdev_opmode;
 	bool enable_srd_channel;
+	enum phy_ch_width old_ch_width;
 
 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, sap_vdev_id,
 						    WLAN_POLICY_MGR_ID);
@@ -2246,18 +2260,24 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
 	 */
 	if (!ch_freq &&
 	    sap_ch_freq != policy_mgr_mode_specific_get_channel(psoc,
-	    PM_STA_MODE)) {
+	    PM_STA_MODE) &&
+	    sap_ch_freq != policy_mgr_mode_specific_get_channel(psoc,
+	    PM_P2P_CLIENT_MODE)) {
 		return QDF_STATUS_SUCCESS;
 	} else if (!ch_freq) {
 		ch_freq = sap_ch_freq;
 	} else if (ch_freq && WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) {
 		return policy_mgr_check_6ghz_sap_conc(
 			psoc, con_ch_freq, sap_ch_freq, sap_vdev_id,
-			vdev_opmode);
+			vdev_opmode, ch_params);
 	}
 
 	sta_sap_scc_on_dfs_chan =
 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+	old_ch_width = ch_params->ch_width;
+	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params)
+		pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
+			psoc, sap_vdev_id, ch_freq, ch_params);
 	is_dfs = wlan_mlme_check_chan_param_has_dfs(
 			pm_ctx->pdev, ch_params, ch_freq);
 	if (policy_mgr_valid_sta_channel_check(psoc, ch_freq)) {
@@ -2307,8 +2327,12 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
 	}
 
 update_chan:
-	if (ch_freq != sap_ch_freq)
+	if (ch_freq != sap_ch_freq || old_ch_width != ch_params->ch_width)
 		*con_ch_freq = ch_freq;
+	if (*con_ch_freq &&
+	    pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params)
+		pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
+			psoc, sap_vdev_id, ch_freq, ch_params);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 19 - 4
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -4537,8 +4537,10 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
 	bool restart_required = false;
 	bool is_sta_p2p_cli;
 	bool is_same_mac;
+	bool sap_on_dfs = false;
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
 	struct policy_mgr_conc_connection_info *connection;
+	bool sta_sap_scc_on_dfs_chan;
 
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
@@ -4553,8 +4555,14 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
 	connection = pm_conc_connection_list;
 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
-		if (connection[i].vdev_id == vdev_id) {
+		if (connection[i].vdev_id == vdev_id &&
+		    connection[i].in_use) {
 			mac = connection[i].mac;
+
+			if (WLAN_REG_IS_5GHZ_CH_FREQ(connection[i].freq) &&
+			    (connection[i].ch_flagext & (IEEE80211_CHAN_DFS |
+					      IEEE80211_CHAN_DFS_CFREQ2)))
+				sap_on_dfs = true;
 			break;
 		}
 	}
@@ -4562,18 +4570,25 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
 		policy_mgr_err("Invalid vdev id: %d", vdev_id);
 		return false;
 	}
+	sta_sap_scc_on_dfs_chan =
+		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
 
 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
 		is_sta_p2p_cli =
 			connection[i].in_use &&
 			(connection[i].mode == PM_STA_MODE ||
 			connection[i].mode == PM_P2P_CLIENT_MODE);
-
+		if (!is_sta_p2p_cli)
+			continue;
 		is_same_mac = connection[i].freq != freq &&
 			      (connection[i].mac == mac ||
 			       !policy_mgr_is_hw_dbs_capable(psoc));
-
-		if (is_sta_p2p_cli && is_same_mac) {
+		if (is_same_mac) {
+			restart_required = true;
+			break;
+		}
+		if (connection[i].freq == freq &&
+		    !sta_sap_scc_on_dfs_chan && sap_on_dfs) {
 			restart_required = true;
 			break;
 		}

+ 3 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c

@@ -680,6 +680,8 @@ QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc,
 		hdd_cbacks->hdd_get_ap_6ghz_capable;
 	pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt =
 		hdd_cbacks->wlan_hdd_indicate_active_ndp_cnt;
+	pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params =
+		hdd_cbacks->wlan_get_ap_prefer_conc_ch_params;
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -701,6 +703,7 @@ QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc)
 	pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress = NULL;
 	pm_ctx->hdd_cbacks.hdd_is_cac_in_progress = NULL;
 	pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable = NULL;
+	pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params = NULL;
 
 	return QDF_STATUS_SUCCESS;
 }

+ 49 - 17
core/hdd/src/wlan_hdd_hostapd.c

@@ -3293,10 +3293,8 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
 		  vdev_id, intf_ch_freq, sap_ch_freq);
 
 	temp_ch_freq = intf_ch_freq ? intf_ch_freq : sap_ch_freq;
-	ch_params.ch_width = wlansap_get_csa_chanwidth_from_phymode(
-						sap_context, temp_ch_freq);
-	wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev, temp_ch_freq, 0,
-					     &ch_params);
+	wlansap_get_csa_chanwidth_from_phymode(sap_context, temp_ch_freq,
+					       &ch_params);
 	if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION !=
 		mcc_to_scc_switch) {
 		if (QDF_IS_STATUS_ERROR(
@@ -3319,18 +3317,14 @@ sap_restart:
 	} else {
 		sap_context->csa_reason = csa_reason;
 	}
-	hdd_debug("SAP restart orig chan freq: %d, new freq: %d",
-		  hdd_ap_ctx->sap_config.chan_freq, intf_ch_freq);
-	ch_params.ch_width = wlan_sap_get_concurrent_bw(hdd_ctx->pdev,
-							hdd_ctx->psoc,
-							intf_ch_freq,
-							ch_params.ch_width);
+	if (ch_params.ch_width == CH_WIDTH_MAX)
+		wlansap_get_csa_chanwidth_from_phymode(
+					sap_context, intf_ch_freq,
+					&ch_params);
+	hdd_debug("SAP restart orig chan freq: %d, new freq: %d bw %d",
+		  hdd_ap_ctx->sap_config.chan_freq, intf_ch_freq,
+		  ch_params.ch_width);
 	hdd_ap_ctx->bss_stop_reason = BSS_STOP_DUE_TO_MCC_SCC_SWITCH;
-
-	wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev,
-					     intf_ch_freq, 0,
-					     &ch_params);
-
 	*ch_freq = intf_ch_freq;
 	hdd_debug("SAP channel change with CSA/ECSA");
 	hdd_sap_restart_chan_switch_cb(psoc, vdev_id, *ch_freq,
@@ -3340,6 +3334,41 @@ sap_restart:
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS
+wlan_get_ap_prefer_conc_ch_params(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id, uint32_t chan_freq,
+		struct ch_params *ch_params)
+{
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	struct sap_context *sap_context;
+	struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev(
+					psoc, vdev_id);
+
+	if (!ap_adapter || (ap_adapter->device_mode != QDF_SAP_MODE &&
+			    ap_adapter->device_mode != QDF_P2P_GO_MODE)) {
+		hdd_err("invalid adapter");
+		return QDF_STATUS_E_FAILURE;
+	}
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
+	sap_context = hdd_ap_ctx->sap_context;
+	if (!sap_context) {
+		hdd_err("sap_context is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_context))) {
+		hdd_err("sap_context is invalid");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wlansap_get_csa_chanwidth_from_phymode(sap_context,
+					       chan_freq,
+					       ch_params);
+	wlansap_context_put(sap_context);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 #if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX)
 uint32_t hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
 {
@@ -6508,10 +6537,13 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 	if (0 != status)
 		return status;
 
-	hdd_nofl_info("%s(vdevid-%d): START AP: Device mode %s(%d) sub20 %d",
+	hdd_nofl_info("%s(vdevid-%d): START AP: mode %s(%d) %d bw %d sub20 %d",
 		      dev->name, adapter->vdev_id,
 		      qdf_opmode_str(adapter->device_mode),
-		      adapter->device_mode, cds_is_sub_20_mhz_enabled());
+		      adapter->device_mode,
+		      params->chandef.chan->center_freq,
+		      params->chandef.width,
+		      cds_is_sub_20_mhz_enabled());
 	if (policy_mgr_is_hw_mode_change_in_progress(hdd_ctx->psoc)) {
 		status = policy_mgr_wait_for_connection_update(
 			hdd_ctx->psoc);

+ 20 - 0
core/hdd/src/wlan_hdd_hostapd.h

@@ -110,6 +110,26 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
 				struct wlan_objmgr_psoc *psoc,
 				uint8_t vdev_id, uint32_t *ch_freq);
 
+/**
+ * wlan_get_ap_prefer_conc_ch_params() - Get prefer sap target channel
+ *  bw parameters
+ * @psoc: pointer to psoc
+ * @vdev_id: vdev id
+ * @chan_freq: sap channel
+ * @ch_params: output channel parameters
+ *
+ * This function is used to get prefer sap target channel bw during sap force
+ * scc CSA. The new bw will not exceed the orginal bw during start ap
+ * request.
+ *
+ * Return: QDF_STATUS_SUCCESS if successfully
+ */
+QDF_STATUS
+wlan_get_ap_prefer_conc_ch_params(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id, uint32_t chan_freq,
+		struct ch_params *ch_params);
+
 /**
  * hdd_get_ap_6ghz_capable() - Get ap vdev 6ghz capable flags
  * @psoc: PSOC object information

+ 2 - 0
core/hdd/src/wlan_hdd_main.c

@@ -3525,6 +3525,8 @@ static void hdd_register_policy_manager_callback(
 	hdd_cbacks.hdd_get_ap_6ghz_capable = hdd_get_ap_6ghz_capable;
 	hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt =
 				hdd_indicate_active_ndp_cnt;
+	hdd_cbacks.wlan_get_ap_prefer_conc_ch_params =
+			wlan_get_ap_prefer_conc_ch_params;
 
 	if (QDF_STATUS_SUCCESS !=
 	    policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {

+ 3 - 1
core/sap/inc/sap_api.h

@@ -1166,12 +1166,14 @@ QDF_STATUS wlansap_get_dfs_cac_state(mac_handle_t mac_handle,
  * channel width from user configured phymode for csa
  * @sap_context: sap adapter context
  * @chan_freq: target channel frequency (MHz)
+ * @tgt_ch_params: target new channel bw parameters to be updated
  *
  * Return: phy_ch_width
  */
 enum phy_ch_width
 wlansap_get_csa_chanwidth_from_phymode(struct sap_context *sap_context,
-				       uint32_t chan_freq);
+				       uint32_t chan_freq,
+				       struct ch_params *tgt_ch_params);
 
 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
 QDF_STATUS

+ 8 - 22
core/sap/src/sap_fsm.c

@@ -848,12 +848,9 @@ sap_validate_chan(struct sap_context *sap_context,
 					sap_context->chan_freq,
 					sap_context->csr_roamProfile.phyMode,
 					sap_context->cc_switch_mode);
-			sap_debug("After check overlap: con_ch:%d",
-				  con_ch_freq);
+			sap_debug("After check overlap: sap freq %d con freq:%d",
+				  sap_context->chan_freq, con_ch_freq);
 			ch_params = sap_context->ch_params;
-			if (con_ch_freq &&
-			    WLAN_REG_IS_24GHZ_CH_FREQ(con_ch_freq))
-				ch_params.ch_width = CH_WIDTH_20MHZ;
 
 			if (sap_context->cc_switch_mode !=
 		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) {
@@ -867,15 +864,12 @@ sap_validate_chan(struct sap_context *sap_context,
 					return QDF_STATUS_E_ABORTED;
 				}
 			}
-			sap_debug("After check concurrency: con_ch:%d",
+
+			sap_debug("After check concurrency: con freq:%d",
 				  con_ch_freq);
 			sta_sap_scc_on_dfs_chan =
 				policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
 						mac_ctx->psoc);
-			ch_params = sap_context->ch_params;
-			if (con_ch_freq &&
-			    WLAN_REG_IS_24GHZ_CH_FREQ(con_ch_freq))
-				ch_params.ch_width = CH_WIDTH_20MHZ;
 			if (con_ch_freq &&
 			    (policy_mgr_sta_sap_scc_on_lte_coex_chan(
 						mac_ctx->psoc) ||
@@ -888,20 +882,12 @@ sap_validate_chan(struct sap_context *sap_context,
 				if (is_mcc_preferred(sap_context, con_ch_freq))
 					goto validation_done;
 
-				sap_debug("Override ch freq %d to %d due to CC Intf",
+				sap_debug("Override ch freq %d (bw %d) to %d (bw %d) due to CC Intf",
 					  sap_context->chan_freq,
-					  con_ch_freq);
+					  sap_context->ch_params.ch_width,
+					  con_ch_freq, ch_params.ch_width);
 				sap_context->chan_freq = con_ch_freq;
-				sap_context->ch_params.ch_width =
-				    wlan_sap_get_concurrent_bw(mac_ctx->pdev,
-							       mac_ctx->psoc,
-							       con_ch_freq,
-					       sap_context->ch_params.ch_width);
-				wlan_reg_set_channel_params_for_freq(
-					mac_ctx->pdev,
-					sap_context->chan_freq,
-					0,
-					&sap_context->ch_params);
+				sap_context->ch_params = ch_params;
 			}
 		}
 #endif

+ 53 - 5
core/sap/src/sap_module.c

@@ -584,6 +584,7 @@ enum phy_ch_width wlan_sap_get_concurrent_bw(struct wlan_objmgr_pdev *pdev,
 	enum phy_ch_width sta_chan_width;
 	bool sta_present, is_con_chan_dfs = false;
 	uint8_t sta_vdev_id;
+	uint8_t sta_sap_scc_on_dfs_chnl;
 
 	if (WLAN_REG_IS_24GHZ_CH_FREQ(con_ch_freq))
 		return CH_WIDTH_20MHZ;
@@ -595,6 +596,32 @@ enum phy_ch_width wlan_sap_get_concurrent_bw(struct wlan_objmgr_pdev *pdev,
 							&sta_vdev_id,
 							con_ch_freq,
 							&sta_ch_width);
+	if (policy_mgr_is_hw_dbs_capable(psoc)) {
+		policy_mgr_get_sta_sap_scc_on_dfs_chnl(
+					psoc, &sta_sap_scc_on_dfs_chnl);
+		if (sta_sap_scc_on_dfs_chnl ==
+					PM_STA_SAP_ON_DFS_MASTER_MODE_FLEX) {
+			return channel_width;
+		} else if (sta_sap_scc_on_dfs_chnl ==
+				PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED) {
+			if (sta_present)
+				return channel_width;
+			/*
+			 * sta_sap_scc_on_dfs_chnl = 1, DFS master is disabled.
+			 * If STA not present (SAP single), the SAP (160Mhz) is
+			 * not allowed on DFS, so limit SAP to 80Mhz.
+			 */
+			return QDF_MIN(channel_width, CH_WIDTH_80MHZ);
+		}
+		/*
+		 * sta_sap_scc_on_dfs_chnl = 0, not allow STA+SAP SCC
+		 * on DFS. Limit SAP to 80Mhz if STA present.
+		 */
+		if (sta_present)
+			return QDF_MIN(channel_width, CH_WIDTH_80MHZ);
+
+		return channel_width;
+	}
 
 	/* if no STA present return max of BW and 80MHZ */
 	if (!sta_present)
@@ -1200,10 +1227,13 @@ QDF_STATUS wlansap_deauth_sta(struct sap_context *sap_ctx,
 
 enum phy_ch_width
 wlansap_get_csa_chanwidth_from_phymode(struct sap_context *sap_context,
-				       uint32_t chan_freq)
+				       uint32_t chan_freq,
+				       struct ch_params *tgt_ch_params)
 {
 	uint32_t max_fw_bw;
-	enum phy_ch_width ch_width;
+	enum phy_ch_width ch_width, concurrent_bw = 0;
+	struct mac_context *mac = sap_get_mac_context();
+	struct ch_params ch_params = {0};
 
 	if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) {
 		/*
@@ -1239,7 +1269,23 @@ wlansap_get_csa_chanwidth_from_phymode(struct sap_context *sap_context,
 			/* For legacy 11a mode return 20MHz */
 			ch_width = CH_WIDTH_20MHZ;
 		}
-	}
+		concurrent_bw = wlan_sap_get_concurrent_bw(
+				mac->pdev, mac->psoc, chan_freq,
+				ch_width);
+		ch_width = QDF_MIN(ch_width, concurrent_bw);
+		ch_width = QDF_MIN(ch_width, sap_context->ch_width_orig);
+	}
+	ch_params.ch_width = ch_width;
+	wlan_reg_set_channel_params_for_freq(mac->pdev, chan_freq, 0,
+					     &ch_params);
+	ch_width = ch_params.ch_width;
+	if (tgt_ch_params)
+		*tgt_ch_params = ch_params;
+	sap_nofl_debug("freq %d bw %d (orig bw %d phymode %d, con bw %d)",
+		       chan_freq, ch_width,
+		       sap_context->ch_width_orig,
+		       sap_context->csr_roamProfile.phyMode,
+		       concurrent_bw);
 
 	return ch_width;
 }
@@ -1315,7 +1361,8 @@ wlansap_set_chan_params_for_csa(struct mac_context *mac,
 {
 	mac->sap.SapDfsInfo.new_chanWidth =
 		wlansap_get_csa_chanwidth_from_phymode(sap_ctx,
-						       target_chan_freq);
+						       target_chan_freq,
+						       NULL);
 	/*
 	 * Copy the requested target channel
 	 * to sap context.
@@ -1407,7 +1454,8 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx,
 
 	tmp_ch_params.ch_width =
 		wlansap_get_csa_chanwidth_from_phymode(sap_ctx,
-						       target_chan_freq);
+						       target_chan_freq,
+						       NULL);
 	if (target_bw != CH_WIDTH_MAX) {
 		tmp_ch_params.ch_width =
 			QDF_MIN(tmp_ch_params.ch_width, target_bw);