Преглед на файлове

qcacld-3.0: Add STA+SAP indoor channel scc support

Based on the ini "sta_sap_scc_on_indoor_chan" the behavior of
STA+SAP in scc is as follows:
1. STA is on 2.4 GHz & SAP is on 2.4 GHz and SAP user configured
initial channel was on 5 GHz, then move SAP to 5 GHz initially
started channel

2. When STA + SAP are doing SCC on indoor only channel and
  a) STA moves to 2.4 GHz -> then SAP moves to initialy started
channel
  b) STA moves to another indoor only channel -> SAP follows
STA channel
  c) STA moves to non-indoor, non-dfs channel -> SAP follows
STA channel.
  d) STA moves to DFS channel -> SAP moves to 2.4 GHz channel
  e) STA disconnects -> Move SAP to initially started channel

3. STA is on 2.4 GHz & SAP is on 5 GHz non-indoor, non-dfs channel
and STA moves to 5 GHz channel, then SAP should follow STA to 5 GHz
if SAP was initially started on 5 GHz channel. Else SAP restart
is not required and SAP will remain on the 2.4 GHz channel

Change-Id: I655dffff026d8147e13599dddc024980ba157be5
CRs-Fixed: 3186965
Surya Prakash Sivaraj преди 2 години
родител
ревизия
a0b6b2c739

+ 14 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ucfg.h

@@ -323,4 +323,18 @@ QDF_STATUS ucfg_policy_mgr_get_sap_mandt_chnl(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS
 ucfg_policy_mgr_get_indoor_chnl_marking(struct wlan_objmgr_psoc *psoc,
 					uint8_t *indoor_chnl_marking);
+
+/**
+ * ucfg_policy_mgr_get_sta_sap_scc_on_indoor_chnl() - to get if
+ * sta sap scc on indoor channel is allowed
+ * @psoc: pointer to psoc
+ * @sap_scc_on_indoor: value to be filled
+ *
+ * This API is used to get the value of  sta+sap scc on indoor channel
+ *
+ * Return: TRUE or FALSE
+ */
+
+bool
+ucfg_policy_mgr_get_sta_sap_scc_on_indoor_chnl(struct wlan_objmgr_psoc *psoc);
 #endif //__WLAN_POLICY_MGR_UCFG

+ 43 - 7
components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -1581,6 +1581,8 @@ bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
 	bool sta_sap_scc_on_lte_coex_chan =
 		policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc);
+	bool sta_sap_scc_on_indoor_channel =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
 	uint8_t sta_sap_scc_on_dfs_chnl_config_value = 0;
 	uint32_t cc_count, i, go_index_start, pcl_len = 0;
 	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
@@ -1601,7 +1603,9 @@ bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
 	}
 	if (!pm_ctx->do_sap_unsafe_ch_check)
 		return false;
-	if (!sta_sap_scc_on_dfs_chan && !sta_sap_scc_on_lte_coex_chan)
+
+	if (!sta_sap_scc_on_dfs_chan && !sta_sap_scc_on_lte_coex_chan &&
+	    !sta_sap_scc_on_indoor_channel)
 		return false;
 
 	policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &sta_sap_scc_on_dfs_chnl_config_value);
@@ -1642,6 +1646,7 @@ bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
 					 curr_sap_freq);
 			break;
 		}
+
 		if (sta_sap_scc_on_lte_coex_chan &&
 		    !policy_mgr_is_safe_channel(psoc, op_ch_freq_list[i]) &&
 		    pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) {
@@ -1652,14 +1657,28 @@ bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
 					 curr_sap_freq);
 			break;
 		}
+
+		if (sta_sap_scc_on_indoor_channel &&
+		    wlan_reg_is_freq_indoor(pm_ctx->pdev, op_ch_freq_list[i]) &&
+		    pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) {
+			sap_vdev_id = vdev_id[i];
+			curr_sap_freq = op_ch_freq_list[i];
+			policy_mgr_debug("indoor sap_ch_freq %u",
+					 curr_sap_freq);
+			break;
+		}
 	}
 
-	if (!curr_sap_freq)
+	if (!curr_sap_freq) {
+		policy_mgr_debug("SAP restart is not required");
 		return false;
+	}
+
 	mode = i >= go_index_start ? PM_P2P_GO_MODE : PM_SAP_MODE;
 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
 	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id,
 						      &info, &num_cxn_del);
+
 	/* Add the user config ch as first condidate */
 	pcl_channels[0] = pm_ctx->user_config_sap_ch_freq;
 	pcl_weight[0] = 0;
@@ -2144,7 +2163,7 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
 						uint32_t sta_ch_freq)
 {
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
-	bool sta_sap_scc_on_dfs_chan;
+	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel;
 
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
@@ -2160,10 +2179,22 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
 				 sta_ch_freq);
 		return true;
 	}
+
+	sta_sap_scc_on_indoor_channel =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+	if (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) &&
+	    sta_sap_scc_on_indoor_channel) {
+		policy_mgr_debug("STA, SAP SCC is allowed on indoor chan %u",
+				 sta_ch_freq);
+		return true;
+	}
+
 	if ((wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) &&
 	     !sta_sap_scc_on_dfs_chan) ||
 	    wlan_reg_is_passive_or_disable_for_freq(
 	    pm_ctx->pdev, sta_ch_freq) ||
+	    (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) &&
+	    !sta_sap_scc_on_indoor_channel) ||
 	    !policy_mgr_is_safe_channel(psoc, sta_ch_freq)) {
 		if (policy_mgr_is_hw_dbs_capable(psoc))
 			return true;
@@ -2225,7 +2256,7 @@ policy_mgr_valid_sap_conc_channel_check(struct wlan_objmgr_psoc *psoc,
 	uint32_t ch_freq = *con_ch_freq;
 	bool find_alternate = false;
 	enum phy_ch_width old_ch_width;
-	bool sta_sap_scc_on_dfs_chan;
+	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel;
 	bool is_dfs;
 	bool is_6ghz_cap;
 	bool is_sta_sap_scc;
@@ -2262,10 +2293,13 @@ policy_mgr_valid_sap_conc_channel_check(struct wlan_objmgr_psoc *psoc,
 	sta_sap_scc_on_dfs_chan =
 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
 
+	sta_sap_scc_on_indoor_channel =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(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);
 	is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL);
@@ -2304,9 +2338,11 @@ policy_mgr_valid_sap_conc_channel_check(struct wlan_objmgr_psoc *psoc,
 		policymgr_nofl_debug("sap not capable on SRD con ch_freq %d",
 				     ch_freq);
 	} else if (!policy_mgr_sap_allowed_on_indoor_freq(psoc, pm_ctx->pdev,
-							  ch_freq)) {
-		policymgr_nofl_debug("sap not capable on indoor con ch_freq %d",
-				     ch_freq);
+							  ch_freq) &&
+		   !(is_sta_sap_scc && sta_sap_scc_on_indoor_channel &&
+		     wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq))) {
+		policymgr_nofl_debug("sap not capable on indoor con ch_freq %d is_sta_sap_scc:%d",
+				     ch_freq, is_sta_sap_scc);
 		find_alternate = true;
 	}
 

+ 22 - 2
components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -3970,7 +3970,7 @@ void policy_mgr_check_scc_sbs_channel(struct wlan_objmgr_psoc *psoc,
 	uint8_t num_cxn_del = 0;
 	bool same_band_present = false;
 	bool sbs_mlo_present = false;
-	bool allow_6ghz = true;
+	bool allow_6ghz = true, sta_sap_scc_on_indoor_channel_allowed;
 	uint8_t sta_count;
 
 	pm_ctx = policy_mgr_get_context(psoc);
@@ -4013,6 +4013,25 @@ void policy_mgr_check_scc_sbs_channel(struct wlan_objmgr_psoc *psoc,
 	 * set *intf_ch_freq = 0, to bring sap on sap_ch_freq.
 	 */
 	if (!same_band_present) {
+		/*
+		 * STA + SAP where doing SCC on 5 GHz indoor channel.
+		 * STA moved/roamed to 2.4 GHz. Move SAP to initially
+		 * started channel
+		 */
+		sta_sap_scc_on_indoor_channel_allowed =
+			policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+		if (wlan_reg_is_freq_indoor(pm_ctx->pdev, sap_ch_freq) &&
+		    WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq) &&
+		    sta_sap_scc_on_indoor_channel_allowed) {
+			status = policy_mgr_get_sap_mandatory_channel(
+							psoc, sap_ch_freq,
+							intf_ch_freq);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				return;
+
+			policy_mgr_err("No mandatory channels");
+		}
+
 		if (policy_mgr_is_current_hwmode_sbs(psoc) || sbs_mlo_present)
 			goto sbs_check;
 		/*
@@ -4046,7 +4065,6 @@ void policy_mgr_check_scc_sbs_channel(struct wlan_objmgr_psoc *psoc,
 		status = policy_mgr_get_sap_mandatory_channel(psoc,
 							      sap_ch_freq,
 							      intf_ch_freq);
-
 		if (QDF_IS_STATUS_SUCCESS(status))
 			return;
 
@@ -4635,7 +4653,9 @@ void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
 		policy_mgr_err("mand list overflow (%u)", ch_freq);
 		return;
 	}
+
 	policy_mgr_debug("Ch freq: %u", ch_freq);
+
 	pm_ctx->sap_mandatory_channels[pm_ctx->sap_mandatory_channels_len++]
 		= ch_freq;
 }

+ 64 - 3
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -6676,7 +6676,7 @@ bool policy_mgr_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc,
 bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc,
 					    uint32_t ch_freq)
 {
-	uint32_t sta_sap_scc_on_dfs_chan;
+	uint32_t sta_sap_scc_on_dfs_chan, sta_sap_scc_allowed_on_indoor_chan;
 	uint32_t sap_count;
 	enum channel_state state;
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
@@ -6689,6 +6689,9 @@ bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc,
 
 	sta_sap_scc_on_dfs_chan =
 			policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
+	sta_sap_scc_allowed_on_indoor_chan =
+			policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+
 	sap_count = policy_mgr_mode_specific_connection_count(psoc,
 							      PM_SAP_MODE,
 							      NULL);
@@ -6698,7 +6701,10 @@ bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc,
 			 sta_sap_scc_on_dfs_chan, sap_count, ch_freq, state);
 
 	if ((state == CHANNEL_STATE_ENABLE) || (sap_count == 0) ||
-	    ((state == CHANNEL_STATE_DFS) && sta_sap_scc_on_dfs_chan)) {
+	    (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq) &&
+	     sta_sap_scc_on_dfs_chan) ||
+	    (sta_sap_scc_allowed_on_indoor_chan &&
+	     wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq))) {
 		policy_mgr_debug("Valid channel for channel switch");
 		return true;
 	}
@@ -6887,7 +6893,7 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
 	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;
+	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_allowed_on_indoor_ch;
 
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
@@ -6918,6 +6924,9 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
 	sta_sap_scc_on_dfs_chan =
 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
 
+	sta_sap_scc_allowed_on_indoor_ch =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+
 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
 		is_sta_p2p_cli =
 			connection[i].in_use &&
@@ -6937,6 +6946,58 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
 			restart_required = true;
 			break;
 		}
+
+		if (connection[i].freq == freq &&
+		    !sta_sap_scc_allowed_on_indoor_ch &&
+		    wlan_reg_is_freq_indoor(pm_ctx->pdev, connection[i].freq)) {
+			restart_required = true;
+			break;
+		}
+
+		/*
+		 * Existing connection:
+		 * 1. "STA in DFS ch and SoftAP in 2.4 GHz channel, and then
+		 * STA moves to 5 GHz non-DFS channel
+		 *
+		 * 2. "STA in indoor channel and sta_sap_scc_on_indoor_ch
+		 * ini is false & SAP has moved to 2.4 GHz channel"
+		 * STA moves back to 5 GHZ non indoor/non DFS channel
+		 *
+		 * Now SAP has to move to STA 5 GHz channel if SAP
+		 * was started on 5 GHz channel initialy.
+		 */
+		if (connection[i].freq != freq &&
+		    WLAN_REG_IS_24GHZ_CH_FREQ(freq) &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(connection[i].freq) &&
+		    !wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
+					      connection[i].freq) &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(pm_ctx->user_config_sap_ch_freq)) {
+			restart_required = true;
+
+			if (wlan_reg_is_freq_indoor(pm_ctx->pdev,
+						    connection[i].freq) &&
+			    !sta_sap_scc_allowed_on_indoor_ch)
+				restart_required = false;
+			break;
+		}
+
+		/*
+		 * SAP has to move away from indoor only channel
+		 * when STA moves out of indoor only channel and
+		 * SAP standalone support on indoor only
+		 * channel ini is disabled
+		 **/
+		if (connection[i].freq != freq &&
+		    WLAN_REG_IS_24GHZ_CH_FREQ(connection[i].freq) &&
+		    WLAN_REG_IS_5GHZ_CH_FREQ(freq) &&
+		    wlan_reg_is_freq_indoor(pm_ctx->pdev, freq) &&
+		    !policy_mgr_sap_allowed_on_indoor_freq(pm_ctx->psoc,
+							   pm_ctx->pdev,
+							   freq)) {
+			policy_mgr_debug("SAP in indoor freq: sta:%d sap:%d",
+					 connection[i].freq, freq);
+			restart_required = true;
+		}
 	}
 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
 

+ 30 - 3
components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c

@@ -858,7 +858,7 @@ policy_mgr_modify_pcl_based_on_indoor(struct wlan_objmgr_psoc *psoc,
 	uint32_t pcl_list[NUM_CHANNELS];
 	uint8_t weight_list[NUM_CHANNELS];
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
-	bool include_indoor_channel;
+	bool include_indoor_channel, sta_sap_scc_on_indoor_channel_allowed;
 	QDF_STATUS status;
 
 	pm_ctx = policy_mgr_get_context(psoc);
@@ -879,8 +879,19 @@ policy_mgr_modify_pcl_based_on_indoor(struct wlan_objmgr_psoc *psoc,
 		return status;
 	}
 
+	/*
+	 * If STA SAP scc is allowed on indoor channels, and if STA/P2P
+	 * client is present on 5 GHz channel, include indoor channels
+	 */
+	sta_sap_scc_on_indoor_channel_allowed =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
+	if (!include_indoor_channel && sta_sap_scc_on_indoor_channel_allowed &&
+	    (policy_mgr_is_special_mode_active_5g(psoc, PM_P2P_CLIENT_MODE) ||
+	     policy_mgr_is_special_mode_active_5g(psoc, PM_STA_MODE)))
+		include_indoor_channel = true;
+
 	if (include_indoor_channel) {
-		policy_mgr_debug("No more operation on indoor channel");
+		policy_mgr_debug("Indoor channels allowed. PCL not modifed for indoor channels");
 		return QDF_STATUS_SUCCESS;
 	}
 
@@ -2530,11 +2541,18 @@ policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc,
 				     uint32_t sap_ch_freq,
 				     uint32_t *intf_ch_freq)
 {
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
 	QDF_STATUS status;
 	struct policy_mgr_pcl_list pcl;
 	uint32_t i;
 	uint32_t sap_new_freq;
 
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
 	qdf_mem_zero(&pcl, sizeof(pcl));
 
 	status = policy_mgr_get_pcl_for_existing_conn(
@@ -2611,6 +2629,15 @@ policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc,
 	}
 
 	sap_new_freq = pcl.pcl_list[0];
+	for (i = 0; i < pcl.pcl_len; i++) {
+		if (pcl.pcl_list[i] ==  pm_ctx->user_config_sap_ch_freq) {
+			sap_new_freq = pcl.pcl_list[i];
+			policy_mgr_debug("Prefer starting SAP on user configured channel:%d",
+					 sap_ch_freq);
+			goto update_freq;
+		}
+	}
+
 	/* If no SBS Try get SCC freq */
 	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) ||
 	    (WLAN_REG_IS_5GHZ_CH_FREQ(sap_ch_freq) &&
@@ -2625,7 +2652,7 @@ policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc,
 
 update_freq:
 	*intf_ch_freq = sap_new_freq;
-	policy_mgr_debug("mandatory channel:%d org sap ch %d", *intf_ch_freq,
+	policy_mgr_debug("Mandatory channel:%d org sap ch %d", *intf_ch_freq,
 			 sap_ch_freq);
 
 	return QDF_STATUS_SUCCESS;

+ 11 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c

@@ -63,6 +63,10 @@ static QDF_STATUS policy_mgr_init_cfg(struct wlan_objmgr_psoc *psoc)
 	cfg->sta_sap_scc_on_dfs_chnl =
 		cfg_get(psoc, CFG_STA_SAP_SCC_ON_DFS_CHAN);
 
+	/*
+	 * Override concurrency sta+sap indoor flag to true if global indoor
+	 * flag is true
+	 */
 	cfg->sta_sap_scc_on_indoor_channel =
 		cfg_get(psoc, CFG_STA_SAP_SCC_ON_INDOOR_CHAN);
 	if (cfg_get(psoc, CFG_INDOOR_CHANNEL_SUPPORT))
@@ -262,3 +266,10 @@ ucfg_policy_mgr_get_indoor_chnl_marking(struct wlan_objmgr_psoc *psoc,
 {
 	return policy_mgr_get_indoor_chnl_marking(psoc, indoor_chnl_marking);
 }
+
+bool
+ucfg_policy_mgr_get_sta_sap_scc_on_indoor_chnl(struct wlan_objmgr_psoc *psoc)
+{
+	return policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc) ?
+								true : false;
+}

+ 6 - 2
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -4992,10 +4992,14 @@ wlan_mlme_check_chan_param_has_dfs(struct wlan_objmgr_pdev *pdev,
 			pdev,
 			ch_params->mhz_freq_seg1) == CHANNEL_STATE_DFS)
 			is_dfs = true;
-	} else if (wlan_reg_get_channel_state_for_freq(
-			pdev, chan_freq) == CHANNEL_STATE_DFS) {
+	} else if (wlan_reg_is_dfs_for_freq(pdev, chan_freq)) {
+		/*Indoor channels are also marked DFS, therefore
+		 * check if the channel has REGULATORY_CHAN_RADAR
+		 * channel flag to identify if the channel is DFS
+		 */
 		is_dfs = true;
 	}
+
 	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq) ||
 	    WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq))
 		is_dfs = false;

+ 15 - 9
core/hdd/src/wlan_hdd_cfg80211.c

@@ -6333,11 +6333,14 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx,
 			 *  with SAP on DFS, there cannot be conurrency on
 			 *  single radio. But then we can have multiple
 			 *  radios !!
+			 *
+			 *  Indoor channels are also marked DFS, therefore
+			 *  check if the channel has REGULATORY_CHAN_RADAR
+			 *  channel flag to identify if the channel is DFS
 			 */
-			if (CHANNEL_STATE_DFS ==
-			    wlan_reg_get_channel_state_from_secondary_list_for_freq(
-				hdd_ctx->pdev,
-				ap_ctx->operating_chan_freq)) {
+			if (wlan_reg_is_dfs_for_freq(
+						hdd_ctx->pdev,
+						ap_ctx->operating_chan_freq)) {
 				hdd_err("SAP running on DFS channel");
 				hdd_adapter_dev_put_debug(adapter, dbgid);
 				if (next_adapter)
@@ -6353,13 +6356,16 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx,
 				WLAN_HDD_GET_STATION_CTX_PTR(adapter);
 			/*
 			 *  if STA is already connected on DFS channel,
-			 *  do not disable scan on dfs channels
+			 *  do not disable scan on dfs channels.
+			 *
+			 *  Indoor channels are also marked DFS, therefore
+			 *  check if the channel has REGULATORY_CHAN_RADAR
+			 *  channel flag to identify if the channel is DFS
 			 */
 			if (hdd_cm_is_vdev_associated(adapter) &&
-			    (CHANNEL_STATE_DFS ==
-			     wlan_reg_get_channel_state_for_freq(
-				hdd_ctx->pdev,
-				sta_ctx->conn_info.chan_freq))) {
+			    wlan_reg_is_dfs_for_freq(
+				    hdd_ctx->pdev,
+				    sta_ctx->conn_info.chan_freq)) {
 				hdd_err("client connected on DFS channel");
 				hdd_adapter_dev_put_debug(adapter, dbgid);
 				if (next_adapter)

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

@@ -2092,13 +2092,16 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
 		wlansap_get_dfs_cac_state(mac_handle, &cac_state);
 
 		/* DFS requirement: DO NOT transmit during CAC. */
-		if (CHANNEL_STATE_DFS !=
-		    wlan_reg_get_channel_state_from_secondary_list_for_freq(
-			hdd_ctx->pdev, ap_ctx->operating_chan_freq) ||
-			ignoreCAC ||
-			(hdd_ctx->dev_dfs_cac_status ==
-			DFS_CAC_ALREADY_DONE) ||
-			(eSAP_DFS_SKIP_CAC == cac_state))
+
+		/* Indoor channels are also marked DFS, therefore
+		 * check if the channel has REGULATORY_CHAN_RADAR
+		 * channel flag to identify if the channel is DFS
+		 */
+		if (!wlan_reg_is_dfs_for_freq(hdd_ctx->pdev,
+					      ap_ctx->operating_chan_freq) ||
+		    ignoreCAC ||
+		    hdd_ctx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE ||
+		    eSAP_DFS_SKIP_CAC == cac_state)
 			ap_ctx->dfs_cac_block_tx = false;
 		else
 			ap_ctx->dfs_cac_block_tx = true;
@@ -3011,10 +3014,13 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
 		policy_mgr_set_chan_switch_complete_evt(hdd_ctx->psoc);
 		wlan_hdd_enable_roaming(adapter,
 					RSO_SAP_CHANNEL_CHANGE);
-		if (CHANNEL_STATE_DFS !=
-		    wlan_reg_get_channel_state_from_secondary_list_for_freq(
-						hdd_ctx->pdev,
-						ap_ctx->operating_chan_freq)) {
+
+		/* Indoor channels are also marked DFS, therefore
+		 * check if the channel has REGULATORY_CHAN_RADAR
+		 * channel flag to identify if the channel is DFS
+		 */
+		if (!wlan_reg_is_dfs_for_freq(hdd_ctx->pdev,
+					      ap_ctx->operating_chan_freq)) {
 			ap_ctx->dfs_cac_block_tx = false;
 			vdev = hdd_objmgr_get_vdev_by_user(adapter, WLAN_DP_ID);
 			if (vdev) {

+ 10 - 3
core/hdd/src/wlan_hdd_regulatory.c

@@ -321,6 +321,8 @@ static void reg_program_config_vars(struct hdd_context *hdd_ctx,
 						enable_5dot9_ghz_chan;
 	hdd_update_coex_unsafe_chan_nb_user_prefer(hdd_ctx, config_vars);
 	hdd_update_coex_unsafe_chan_reg_disable(hdd_ctx, config_vars);
+	config_vars->sta_sap_scc_on_indoor_channel =
+		ucfg_policy_mgr_get_sta_sap_scc_on_indoor_chnl(hdd_ctx->psoc);
 }
 
 /**
@@ -502,16 +504,20 @@ static void hdd_process_regulatory_data(struct hdd_context *hdd_ctx,
 	struct ieee80211_channel *wiphy_chan, *wiphy_chan_144 = NULL;
 	struct regulatory_channel *cds_chan;
 	uint8_t band_capability, indoor_chnl_marking = 0;
-	bool indoor;
+	bool indoor, sta_sap_con_on_indoor;
 	QDF_STATUS status;
 
 	band_capability = hdd_ctx->curr_band;
 
 	status = ucfg_policy_mgr_get_indoor_chnl_marking(hdd_ctx->psoc,
 							 &indoor_chnl_marking);
+
 	if (QDF_STATUS_SUCCESS != status)
 		hdd_err("can't get indoor channel marking, using default");
 
+	 sta_sap_con_on_indoor =
+		 ucfg_policy_mgr_get_sta_sap_scc_on_indoor_chnl(hdd_ctx->psoc);
+
 	for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
 
 		if (!wiphy->bands[band_num])
@@ -565,8 +571,9 @@ static void hdd_process_regulatory_data(struct hdd_context *hdd_ctx,
 					cds_chan->state = CHANNEL_STATE_DFS;
 					wiphy_chan->flags |=
 						IEEE80211_CHAN_PASSIVE_SCAN;
-					cds_chan->chan_flags |=
-						REGULATORY_CHAN_NO_IR;
+					if (!sta_sap_con_on_indoor)
+						cds_chan->chan_flags |=
+							REGULATORY_CHAN_NO_IR;
 				} else
 					cds_chan->state = CHANNEL_STATE_ENABLE;
 			} else

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

@@ -192,8 +192,7 @@ lim_process_ext_channel_switch_action_frame(struct mac_context *mac_ctx,
 	if (!(session_entry->curr_op_freq != target_freq &&
 	      ((wlan_reg_get_channel_state_for_freq(mac_ctx->pdev, target_freq) ==
 		  CHANNEL_STATE_ENABLE) ||
-	       (wlan_reg_get_channel_state_for_freq(mac_ctx->pdev, target_freq) ==
-		  CHANNEL_STATE_DFS &&
+	       (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, target_freq) &&
 		!policy_mgr_concurrent_open_sessions_running(
 			mac_ctx->psoc))))) {
 		pe_err("Channel freq: %d is not valid", target_freq);

+ 5 - 3
core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c

@@ -244,9 +244,11 @@ void lim_process_mlm_start_cnf(struct mac_context *mac, uint32_t *msg_buf)
 					CHANNEL_STATE_DFS))
 				send_bcon_ind = true;
 		} else {
-			if (wlan_reg_get_channel_state_for_freq(mac->pdev,
-								chan_freq)
-					!= CHANNEL_STATE_DFS)
+			/* Indoor channels are also marked DFS, therefore
+			 * check if the channel has REGULATORY_CHAN_RADAR
+			 * channel flag to identify if the channel is DFS
+			 */
+			if (!wlan_reg_is_dfs_for_freq(mac->pdev, chan_freq))
 				send_bcon_ind = true;
 		}
 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pe_session->curr_op_freq))

+ 6 - 4
core/mac/src/pe/lim/lim_send_sme_rsp_messages.c

@@ -2236,10 +2236,12 @@ lim_send_sme_ap_channel_switch_resp(struct mac_context *mac,
 				CHANNEL_STATE_DFS)
 			is_ch_dfs = true;
 	} else {
-		if (wlan_reg_get_channel_state_for_freq(
-						mac->pdev,
-						pe_session->curr_op_freq) ==
-		    CHANNEL_STATE_DFS)
+		/* Indoor channels are also marked DFS, therefore
+		 * check if the channel has REGULATORY_CHAN_RADAR
+		 * channel flag to identify if the channel is DFS
+		 */
+		if (wlan_reg_is_dfs_for_freq(mac->pdev,
+					     pe_session->curr_op_freq))
 			is_ch_dfs = true;
 	}
 	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pe_session->curr_op_freq))

+ 6 - 5
core/mac/src/pe/lim/lim_utils.c

@@ -4796,13 +4796,14 @@ void pe_set_resume_channel(struct mac_context *mac, uint16_t channel,
 bool lim_isconnected_on_dfs_freq(struct mac_context *mac_ctx,
 				 qdf_freq_t oper_freq)
 {
-	if (CHANNEL_STATE_DFS ==
-	    wlan_reg_get_channel_state_for_freq(mac_ctx->pdev,
-						oper_freq)) {
+	/* Indoor channels are also marked DFS, therefore
+	 * check if the channel has REGULATORY_CHAN_RADAR
+	 * channel flag to identify if the channel is DFS
+	 */
+	if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, oper_freq))
 		return true;
-	} else {
+	else
 		return false;
-	}
 }
 
 void lim_pmf_sa_query_timer_handler(void *pMacGlobal, uint32_t param)

+ 5 - 4
core/sap/src/sap_api_link_cntl.c

@@ -461,10 +461,11 @@ wlansap_roam_process_ch_change_success(struct mac_context *mac_ctx,
 				CHANNEL_STATE_DFS)
 			is_ch_dfs = true;
 	} else {
-		if (wlan_reg_get_channel_state_for_freq(
-						mac_ctx->pdev,
-						target_chan_freq) ==
-		    CHANNEL_STATE_DFS)
+		/* Indoor channels are also marked DFS, therefore
+		 * check if the channel has REGULATORY_CHAN_RADAR
+		 * channel flag to identify if the channel is DFS
+		 */
+		if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, target_chan_freq))
 			is_ch_dfs = true;
 	}
 	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq))

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

@@ -508,10 +508,11 @@ is_wlansap_cac_required_for_chan(struct mac_context *mac_ctx,
 				CHANNEL_STATE_DFS)
 			is_ch_dfs = true;
 	} else {
-		if (wlan_reg_get_channel_state_for_freq(
-						mac_ctx->pdev,
-						chan_freq) ==
-		    CHANNEL_STATE_DFS)
+		/* Indoor channels are also marked DFS, therefore
+		 * check if the channel has REGULATORY_CHAN_RADAR
+		 * channel flag to identify if the channel is DFS
+		 */
+		if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, chan_freq))
 			is_ch_dfs = true;
 	}
 	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))
@@ -3387,10 +3388,12 @@ static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx,
 					CHANNEL_STATE_DFS)
 				is_dfs = true;
 		} else {
-			if (wlan_reg_get_channel_state_for_freq(
-							mac_ctx->pdev,
-							sap_chan_freq) ==
-			    CHANNEL_STATE_DFS)
+			/* Indoor channels are also marked DFS, therefore
+			 * check if the channel has REGULATORY_CHAN_RADAR
+			 * channel flag to identify if the channel is DFS
+			 */
+			if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
+						     sap_chan_freq))
 				is_dfs = true;
 		}
 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq))

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

@@ -3235,6 +3235,7 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
 	uint8_t vdev_id;
 	enum reg_wifi_band sap_band;
 	enum band_info band;
+	bool sta_sap_scc_on_indoor_channel;
 
 	if (!sap_ctx) {
 		sap_err("sap_ctx NULL parameter");
@@ -3257,6 +3258,9 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
 		sap_err("Failed to get current band config");
 		return 0;
 	}
+
+	sta_sap_scc_on_indoor_channel =
+		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(mac->psoc);
 	sap_band = wlan_reg_freq_to_band(sap_ctx->chan_freq);
 
 	sap_debug("SAP/Go current band: %d, pdev band capability: %d, cur freq %d (is valid %d), prev freq %d (is valid %d)",
@@ -3300,7 +3304,7 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
 		*csa_reason = CSA_REASON_CHAN_DISABLED;
 		return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx);
 	} else if (wlan_reg_is_passive_for_freq(mac->pdev,
-						sap_ctx->chan_freq)) {
+						sap_ctx->chan_freq))  {
 		sap_ctx->chan_freq_before_switch_band = sap_ctx->chan_freq;
 		sap_ctx->chan_width_before_switch_band =
 			sap_ctx->ch_params.ch_width;