Explorar el Código

qcacld-3.0: Add SAP P2P GO force SCC in same band

When SAP and GO home channels are in MCC in same band,
implement below requirement to avoid MCC:
1. SAP starts at first and GO starts later, then SAP will
  force SCC to GO's home channel after GO starts up.
2. GO starts at first and SAP starts later, then SAP will
  force SCC to GO's home channel during starting up.
3. SAP and GO SCC in same band, SAP changes channel to
  the other channel in same band, GO will follow SAP and
  move to SAP home channel.
4. SAP and GO SCC in same band, GO changes channel to the
  other channel in same band, SAP will follow GO and move
  to GO home channel.

And all the force SCC cases, if the target channel of force
SCC is not supported by the SAP or GO, then driver will
select other band's channel for the interface.

Change-Id: I7b24f3a972a401fd144a0c81dc19bd48ba224d85
CRs-Fixed: 3176087
Liangwei Dong hace 3 años
padre
commit
00c79e5785

+ 3 - 1
components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c

@@ -89,7 +89,9 @@ if_mgr_ap_start_bss_complete(struct wlan_objmgr_vdev *vdev,
 		/* Enable Roaming after start bss in case of failure/success */
 		if_mgr_enable_roaming(pdev, vdev, RSO_START_BSS);
 	}
-
+	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
+		policy_mgr_check_sap_go_force_scc(psoc, vdev,
+						  CSA_REASON_GO_BSS_STARTED);
 	ifmgr_debug("check for SAP restart");
 	policy_mgr_check_concurrent_intf_and_restart_sap(psoc);
 

+ 43 - 64
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -68,38 +68,6 @@ typedef const enum policy_mgr_conc_next_action
 	((channel_select_logic_conc & PM_FW_MODE_STA_P2P_BIT_MASK) >>   \
 	 PM_FW_MODE_STA_P2P_BIT_POS)
 
-/**
- * enum sap_csa_reason_code - SAP channel switch reason code
- * @CSA_REASON_UNKNOWN: Unknown reason
- * @CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS: STA connection from DFS to NON DFS.
- * @CSA_REASON_USER_INITIATED: User initiated form north bound.
- * @CSA_REASON_PEER_ACTION_FRAME: Action frame received on sta iface.
- * @CSA_REASON_PRE_CAC_SUCCESS: Pre CAC success.
- * @CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL: concurrent sta changed channel.
- * @CSA_REASON_UNSAFE_CHANNEL: Unsafe channel.
- * @CSA_REASON_LTE_COEX: LTE coex.
- * @CSA_REASON_CONCURRENT_NAN_EVENT: NAN concurrency.
- * @CSA_REASON_BAND_RESTRICTED: band disabled or re-enabled
- * @CSA_REASON_DCS: DCS
- * @CSA_REASON_CHAN_DISABLED: channel is disabled
- * @CSA_REASON_CHAN_PASSIVE: channel is passive
- */
-enum sap_csa_reason_code {
-	CSA_REASON_UNKNOWN,
-	CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS,
-	CSA_REASON_USER_INITIATED,
-	CSA_REASON_PEER_ACTION_FRAME,
-	CSA_REASON_PRE_CAC_SUCCESS,
-	CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL,
-	CSA_REASON_UNSAFE_CHANNEL,
-	CSA_REASON_LTE_COEX,
-	CSA_REASON_CONCURRENT_NAN_EVENT,
-	CSA_REASON_BAND_RESTRICTED,
-	CSA_REASON_DCS,
-	CSA_REASON_CHAN_DISABLED,
-	CSA_REASON_CHAN_PASSIVE,
-};
-
 /**
  * enum PM_AP_DFS_MASTER_MODE - AP dfs master mode
  * @PM_STA_SAP_ON_DFS_DEFAULT - Disallow STA+SAP SCC on DFS channel
@@ -790,27 +758,6 @@ policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc *psoc)
 }
 #endif
 
-#define GO_FORCE_SCC_DISABLE 0
-#define GO_FORCE_SCC_STRICT 1
-#define GO_FORCE_SCC_LIBERAL 2
-#ifdef WLAN_FEATURE_P2P_P2P_STA
-/**
- * Stay in MCC for 1 second, in case of first p2p go channel
- * needs to be moved to curr go channel
- */
-#define WAIT_BEFORE_GO_FORCESCC_RESTART (1000)
-
-/**
- * policy_mgr_is_go_scc_strict() - Get GO force SCC enabled or not
- * @psoc: psoc object
- *
- * This function checks if force SCC logic should be used on GO interface
- * as a strict mode.
- *
- * Return: True if p2p needs o be start on provided channel only.
- */
-bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc);
-
 /**
  * policy_mgr_fetch_existing_con_info() - check if another vdev
  * is present and find mode, freq , vdev id and chan width
@@ -836,6 +783,27 @@ policy_mgr_fetch_existing_con_info(struct wlan_objmgr_psoc *psoc,
 				   uint32_t *con_freq,
 				   enum phy_ch_width *ch_width);
 
+#define GO_FORCE_SCC_DISABLE 0
+#define GO_FORCE_SCC_STRICT 1
+#define GO_FORCE_SCC_LIBERAL 2
+/**
+ * Stay in MCC for 1 second, in case of first p2p go channel
+ * needs to be moved to curr go channel
+ */
+#define WAIT_BEFORE_GO_FORCESCC_RESTART (1000)
+
+#ifdef WLAN_FEATURE_P2P_P2P_STA
+/**
+ * policy_mgr_is_go_scc_strict() - Get GO force SCC enabled or not
+ * @psoc: psoc object
+ *
+ * This function checks if force SCC logic should be used on GO interface
+ * as a strict mode.
+ *
+ * Return: True if p2p needs o be start on provided channel only.
+ */
+bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc);
+
 /**
  * policy_mgr_process_forcescc_for_go () - start work queue to move first p2p go
  * to new p2p go's channel
@@ -880,17 +848,6 @@ bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc)
 	return false;
 }
 
-static inline
-uint8_t policy_mgr_fetch_existing_con_info(struct wlan_objmgr_psoc *psoc,
-					   uint8_t vdev_id,
-					   uint32_t curr_go_freq,
-					   enum policy_mgr_con_mode *mode,
-					   uint32_t *con_freq,
-					   enum phy_ch_width *ch_width)
-{
-	return WLAN_UMAC_VDEV_ID_MAX;
-}
-
 static inline
 void policy_mgr_process_forcescc_for_go(
 		struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
@@ -905,6 +862,24 @@ void policy_mgr_do_go_plus_go_force_scc(
 {}
 #endif
 
+/**
+ * policy_mgr_check_sap_go_force_scc() - Check SAP GO MCC and save interface
+ * information
+ * @psoc: pointer to psoc
+ * @vdev: initiator vdev
+ * @reason_code: CSA reason code
+ *
+ * This API will check SAP and GO are coexistent on same band MCC or not. If
+ * it is, the interface ids will be saved and a delayed workqueue will be
+ * scheduled. The workqueue will handle the new channel selection and change
+ * the channel of second interface to avoid MCC.
+ *
+ * Return: void
+ */
+void policy_mgr_check_sap_go_force_scc(struct wlan_objmgr_psoc *psoc,
+				       struct wlan_objmgr_vdev *vdev,
+				       enum sap_csa_reason_code reason_code);
+
 /**
  * policy_mgr_set_pcl_for_existing_combo() - SET PCL for existing combo
  * @psoc: PSOC object information
@@ -1744,6 +1719,7 @@ struct policy_mgr_sme_cbacks {
  * @wlan_get_ap_prefer_conc_ch_params: get prefer ap channel bw parameters
  *  based on target channel frequency and concurrent connections.
  * @wlan_get_sap_acs_band: get acs band from sap config
+ * @wlan_check_cc_intf_cb: get interference frequency of input SAP/GO interface
  */
 struct policy_mgr_hdd_cbacks {
 	QDF_STATUS (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc,
@@ -1772,6 +1748,9 @@ struct policy_mgr_hdd_cbacks {
 			struct ch_params *ch_params);
 	uint32_t (*wlan_get_sap_acs_band)(struct wlan_objmgr_psoc *psoc,
 					  uint8_t vdev_id, uint32_t *acs_band);
+	QDF_STATUS (*wlan_check_cc_intf_cb)(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id,
+					    uint32_t *ch_freq);
 };
 
 /**

+ 50 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h

@@ -78,6 +78,40 @@
 
 typedef int (*send_mode_change_event_cb)(void);
 
+/**
+ * enum sap_csa_reason_code - SAP channel switch reason code
+ * @CSA_REASON_UNKNOWN: Unknown reason
+ * @CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS: STA connection from DFS to NON DFS.
+ * @CSA_REASON_USER_INITIATED: User initiated form north bound.
+ * @CSA_REASON_PEER_ACTION_FRAME: Action frame received on sta iface.
+ * @CSA_REASON_PRE_CAC_SUCCESS: Pre CAC success.
+ * @CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL: concurrent sta changed channel.
+ * @CSA_REASON_UNSAFE_CHANNEL: Unsafe channel.
+ * @CSA_REASON_LTE_COEX: LTE coex.
+ * @CSA_REASON_CONCURRENT_NAN_EVENT: NAN concurrency.
+ * @CSA_REASON_BAND_RESTRICTED: band disabled or re-enabled
+ * @CSA_REASON_DCS: DCS
+ * @CSA_REASON_CHAN_DISABLED: channel is disabled
+ * @CSA_REASON_CHAN_PASSIVE: channel is passive
+ * @CSA_REASON_GO_BSS_STARED: P2P go started
+ */
+enum sap_csa_reason_code {
+	CSA_REASON_UNKNOWN,
+	CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS,
+	CSA_REASON_USER_INITIATED,
+	CSA_REASON_PEER_ACTION_FRAME,
+	CSA_REASON_PRE_CAC_SUCCESS,
+	CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL,
+	CSA_REASON_UNSAFE_CHANNEL,
+	CSA_REASON_LTE_COEX,
+	CSA_REASON_CONCURRENT_NAN_EVENT,
+	CSA_REASON_BAND_RESTRICTED,
+	CSA_REASON_DCS,
+	CSA_REASON_CHAN_DISABLED,
+	CSA_REASON_CHAN_PASSIVE,
+	CSA_REASON_GO_BSS_STARTED,
+};
+
 /**
  * enum hw_mode_ss_config - Possible spatial stream configuration
  * @HW_MODE_SS_0x0: Unused Tx and Rx of MAC
@@ -1521,16 +1555,32 @@ struct go_plus_go_force_scc {
 	uint32_t ch_width;
 };
 
+/**
+ * struct sap_plus_go_force_scc - structure to hold
+ * params for forcescc restart in sap plus go
+ *
+ * @reason: channel change reason code
+ * @initiator_vdev_id: the first interface ID to trigger CSA
+ * @responder_vdev_id: the second interface ID to follow CSA
+ */
+struct sap_plus_go_force_scc {
+	enum sap_csa_reason_code reason;
+	uint8_t initiator_vdev_id;
+	uint8_t responder_vdev_id;
+};
+
 /**
  * struct sta_ap_intf_check_work_ctx - sta_ap_intf_check_work
  * related info
  * @psoc: pointer to PSOC object information
  * @go_plus_go_force_scc: structure to hold params of
  *			  curr and first p2p go ctx
+ * @sap_plus_go_force_scc: sap p2p force SCC ctx
  */
 struct sta_ap_intf_check_work_ctx {
 	struct wlan_objmgr_psoc *psoc;
 	struct go_plus_go_force_scc go_plus_go_force_scc;
+	struct sap_plus_go_force_scc sap_plus_go_force_scc;
 };
 
 #endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */

+ 199 - 2
components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -2099,6 +2099,194 @@ end:
 	pm_ctx->last_disconn_sta_freq = 0;
 }
 
+/**
+ * policy_mgr_handle_sap_plus_go_force_scc() - Do SAP/GO force SCC
+ * @psoc: soc object
+ *
+ * This function will check SAP/GO channel state and select channel
+ * to avoid MCC, then do channel change on the second interface.
+ *
+ * Return: QDF_STATUS_SUCCESS if successfully handle the SAP/GO
+ * force SCC.
+ */
+static QDF_STATUS
+policy_mgr_handle_sap_plus_go_force_scc(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
+	enum policy_mgr_con_mode vdev_con_mode;
+	uint32_t existing_ch_freq, chan_freq, intf_ch_freq;
+	enum phy_ch_width existing_ch_width;
+	uint8_t vdev_id;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct sta_ap_intf_check_work_ctx *work_info;
+	struct ch_params ch_params = {0};
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return status;
+	}
+
+	work_info = pm_ctx->sta_ap_intf_check_work_info;
+	if (!work_info) {
+		policy_mgr_err("invalid work info");
+		return status;
+	}
+	if (work_info->sap_plus_go_force_scc.reason == CSA_REASON_UNKNOWN)
+		return status;
+
+	vdev_id = work_info->sap_plus_go_force_scc.initiator_vdev_id;
+	chan_freq = wlan_get_operation_chan_freq_vdev_id(pm_ctx->pdev, vdev_id);
+	vdev_con_mode = policy_mgr_convert_device_mode_to_qdf_type(
+			wlan_get_opmode_vdev_id(pm_ctx->pdev, vdev_id));
+
+	existing_vdev_id =
+		policy_mgr_fetch_existing_con_info(
+				psoc,
+				vdev_id,
+				chan_freq,
+				&existing_vdev_mode,
+				&existing_ch_freq, &existing_ch_width);
+	policy_mgr_debug("initiator vdev %d mode %d freq %d, existing vdev %d mode %d freq %d reason %d",
+			 vdev_id, vdev_con_mode, chan_freq, existing_vdev_id,
+			 existing_vdev_mode, existing_ch_freq,
+			 work_info->sap_plus_go_force_scc.reason);
+
+	if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX)
+		goto force_scc_done;
+
+	if (!((vdev_con_mode == PM_P2P_GO_MODE &&
+	       existing_vdev_mode == PM_SAP_MODE) ||
+	      (vdev_con_mode == PM_SAP_MODE &&
+	       existing_vdev_mode == PM_P2P_GO_MODE)))
+		goto force_scc_done;
+
+	if (!pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb)
+		goto force_scc_done;
+
+	intf_ch_freq = 0;
+	status = pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb(psoc,
+							  existing_vdev_id,
+							  &intf_ch_freq);
+	policy_mgr_debug("vdev %d freq %d intf %d status %d",
+			 existing_vdev_id, existing_ch_freq,
+			 intf_ch_freq, status);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto force_scc_done;
+	if (!intf_ch_freq || intf_ch_freq == existing_ch_freq)
+		goto force_scc_done;
+
+	ch_params.ch_width = existing_ch_width;
+	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) {
+		status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
+			psoc, existing_vdev_id, intf_ch_freq, &ch_params);
+		if (QDF_IS_STATUS_ERROR(status))
+			policy_mgr_debug("no candidate valid bw for vdev %d intf %d",
+					 existing_vdev_id, intf_ch_freq);
+	}
+
+	status = policy_mgr_valid_sap_conc_channel_check(
+		    psoc, &intf_ch_freq, existing_ch_freq, existing_vdev_id,
+		    &ch_params);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("warning no candidate freq for vdev %d freq %d intf %d",
+			       existing_vdev_id, existing_ch_freq,
+			       intf_ch_freq);
+		goto force_scc_done;
+	}
+
+	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
+		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(
+				psoc, existing_vdev_id,
+				work_info->sap_plus_go_force_scc.reason);
+
+	status = policy_mgr_change_sap_channel_with_csa(
+			psoc, existing_vdev_id, intf_ch_freq,
+			ch_params.ch_width, true);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		policy_mgr_err("warning sap/go vdev %d freq %d intf %d csa failed",
+			       existing_vdev_id, existing_ch_freq,
+			       intf_ch_freq);
+	}
+
+force_scc_done:
+	work_info->sap_plus_go_force_scc.reason = CSA_REASON_UNKNOWN;
+	work_info->sap_plus_go_force_scc.initiator_vdev_id =
+					WLAN_UMAC_VDEV_ID_MAX;
+	work_info->sap_plus_go_force_scc.responder_vdev_id =
+					WLAN_UMAC_VDEV_ID_MAX;
+
+	return status;
+}
+
+void
+policy_mgr_check_sap_go_force_scc(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_objmgr_vdev *vdev,
+				  enum sap_csa_reason_code reason_code)
+{
+	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
+	enum policy_mgr_con_mode vdev_con_mode;
+	uint32_t con_freq, chan_freq;
+	enum phy_ch_width ch_width;
+	uint8_t vdev_id;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct sta_ap_intf_check_work_ctx *work_info;
+
+	if (reason_code != CSA_REASON_GO_BSS_STARTED &&
+	    reason_code != CSA_REASON_USER_INITIATED)
+		return;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return;
+	}
+	if (!vdev) {
+		policy_mgr_err("vdev is null");
+		return;
+	}
+	vdev_id = wlan_vdev_get_id(vdev);
+	work_info = pm_ctx->sta_ap_intf_check_work_info;
+	if (!work_info) {
+		policy_mgr_err("invalid work info");
+		return;
+	}
+
+	chan_freq = wlan_get_operation_chan_freq(vdev);
+	vdev_con_mode = policy_mgr_convert_device_mode_to_qdf_type(
+			wlan_vdev_mlme_get_opmode(vdev));
+
+	existing_vdev_id =
+		policy_mgr_fetch_existing_con_info(psoc,
+						   vdev_id,
+						   chan_freq,
+						   &existing_vdev_mode,
+						   &con_freq, &ch_width);
+	if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX)
+		return;
+
+	if (!((vdev_con_mode == PM_P2P_GO_MODE &&
+	       existing_vdev_mode == PM_SAP_MODE) ||
+	      (vdev_con_mode == PM_SAP_MODE &&
+	       existing_vdev_mode == PM_P2P_GO_MODE)))
+		return;
+
+	work_info->sap_plus_go_force_scc.reason = reason_code;
+	work_info->sap_plus_go_force_scc.initiator_vdev_id = vdev_id;
+	work_info->sap_plus_go_force_scc.responder_vdev_id = existing_vdev_id;
+
+	policy_mgr_debug("initiator vdev %d freq %d, existing vdev %d freq %d reason %d",
+			 vdev_id, chan_freq, existing_vdev_id,
+			 con_freq, reason_code);
+
+	if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
+				    WAIT_BEFORE_GO_FORCESCC_RESTART))
+		policy_mgr_debug("change interface request already queued");
+}
+
 static void __policy_mgr_check_sta_ap_concurrent_ch_intf(
 				struct policy_mgr_psoc_priv_obj *pm_ctx)
 {
@@ -2119,8 +2307,9 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(
 	 * valid in case of GO+GO force scc only. So, for valid vdev id move
 	 * first GO to newly formed GO channel.
 	 */
-	policy_mgr_debug("p2p go vdev id: %d",
-			 work_info->go_plus_go_force_scc.vdev_id);
+	policy_mgr_debug("p2p go vdev id: %d csa reason: %d",
+			 work_info->go_plus_go_force_scc.vdev_id,
+			 work_info->sap_plus_go_force_scc.reason);
 	if (pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id <
 	    WLAN_UMAC_VDEV_ID_MAX) {
 		policy_mgr_do_go_plus_go_force_scc(
@@ -2130,6 +2319,14 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(
 		work_info->go_plus_go_force_scc.vdev_id = WLAN_UMAC_VDEV_ID_MAX;
 		goto end;
 	}
+	/*
+	 * Check if force scc is required for GO + SAP case.
+	 */
+	if (pm_ctx->sta_ap_intf_check_work_info->sap_plus_go_force_scc.reason !=
+	    CSA_REASON_UNKNOWN) {
+		status = policy_mgr_handle_sap_plus_go_force_scc(pm_ctx->psoc);
+		goto end;
+	}
 
 	mcc_to_scc_switch =
 		policy_mgr_get_mcc_to_scc_switch_mode(pm_ctx->psoc);

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

@@ -7437,7 +7437,6 @@ bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc)
 	return false;
 }
 
-#ifdef WLAN_FEATURE_P2P_P2P_STA
 uint8_t
 policy_mgr_fetch_existing_con_info(struct wlan_objmgr_psoc *psoc,
 				   uint8_t vdev_id, uint32_t freq,
@@ -7460,13 +7459,14 @@ policy_mgr_fetch_existing_con_info(struct wlan_objmgr_psoc *psoc,
 		if ((pm_conc_connection_list[conn_index].mode ==
 		    PM_P2P_GO_MODE ||
 		    pm_conc_connection_list[conn_index].mode ==
+		    PM_SAP_MODE ||
+		    pm_conc_connection_list[conn_index].mode ==
 		    PM_P2P_CLIENT_MODE ||
 		    pm_conc_connection_list[conn_index].mode ==
 		    PM_STA_MODE) &&
 		    pm_conc_connection_list[conn_index].in_use &&
-		    wlan_reg_is_same_band_freqs(
-				freq,
-				pm_conc_connection_list[conn_index].freq) &&
+		    policy_mgr_are_2_freq_on_same_mac(
+			psoc, freq, pm_conc_connection_list[conn_index].freq) &&
 		    freq != pm_conc_connection_list[conn_index].freq &&
 		    vdev_id != pm_conc_connection_list[conn_index].vdev_id) {
 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
@@ -7483,9 +7483,11 @@ policy_mgr_fetch_existing_con_info(struct wlan_objmgr_psoc *psoc,
 		}
 	}
 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
 	return WLAN_UMAC_VDEV_ID_MAX;
 }
 
+#ifdef WLAN_FEATURE_P2P_P2P_STA
 bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc)
 {
 	struct policy_mgr_psoc_priv_obj *pm_ctx;

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

@@ -342,6 +342,8 @@ QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc)
 	pm_ctx->sta_ap_intf_check_work_info->psoc = psoc;
 	pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id =
 						WLAN_UMAC_VDEV_ID_MAX;
+	pm_ctx->sta_ap_intf_check_work_info->sap_plus_go_force_scc.reason =
+						CSA_REASON_UNKNOWN;
 	if (QDF_IS_STATUS_ERROR(qdf_delayed_work_create(
 				&pm_ctx->sta_ap_intf_check_work,
 				policy_mgr_check_sta_ap_concurrent_ch_intf,
@@ -730,6 +732,8 @@ QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc,
 		hdd_cbacks->wlan_get_ap_prefer_conc_ch_params;
 	pm_ctx->hdd_cbacks.wlan_get_sap_acs_band =
 		hdd_cbacks->wlan_get_sap_acs_band;
+	pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb =
+		hdd_cbacks->wlan_check_cc_intf_cb;
 
 	return QDF_STATUS_SUCCESS;
 }

+ 37 - 0
core/hdd/src/wlan_hdd_hostapd.c

@@ -2878,6 +2878,9 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
 			hdd_dcs_hostapd_set_chan(
 				hdd_ctx, adapter->vdev_id,
 				adapter->session.ap.operating_chan_freq);
+		policy_mgr_check_sap_go_force_scc(
+				hdd_ctx->psoc, adapter->vdev,
+				ap_ctx->sap_context->csa_reason);
 		qdf_status = qdf_event_set(&hostapd_state->qdf_event);
 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
 			hdd_err("qdf_event_set failed! status: %d",
@@ -3464,6 +3467,40 @@ QDF_STATUS hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc,
 						   channel_bw, forced);
 }
 
+QDF_STATUS wlan_hdd_check_cc_intf_cb(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id, uint32_t *ch_freq)
+{
+	struct hdd_adapter *ap_adapter;
+	struct sap_context *sap_context;
+
+	ap_adapter = wlan_hdd_get_adapter_from_vdev(psoc, vdev_id);
+	if (!ap_adapter) {
+		hdd_err("ap_adapter is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
+		hdd_err("SOFTAP_BSS_STARTED not set");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sap_context = WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter);
+	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;
+	}
+
+	*ch_freq = wlansap_check_cc_intf(sap_context);
+	wlansap_context_put(sap_context);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 void wlan_hdd_set_sap_csa_reason(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 				 uint8_t reason)
 {

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

@@ -111,6 +111,21 @@ QDF_STATUS hdd_sap_restart_with_channel_switch(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc,
 					  uint8_t vdev_id, uint32_t ch_freq,
 					  uint32_t channel_bw, bool forced);
+
+/**
+ * wlan_hdd_check_cc_intf_cb() - Check force SCC for vdev interface.
+ * @psoc: PSOC object information
+ * @vdev_id: vdev id
+ * @ch_freq: channel frequency to switch to
+ *
+ * This function will return a channel frequency to avoid MCC for SAP/GO.
+ *
+ * Return: QDF_STATUS_SUCCESS if successfully
+ *
+ */
+QDF_STATUS wlan_hdd_check_cc_intf_cb(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id, uint32_t *ch_freq);
+
 /**
  * wlan_hdd_get_channel_for_sap_restart() - Function to get
  * suitable channel and restart SAP

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

@@ -3879,6 +3879,7 @@ static void hdd_register_policy_manager_callback(
 			wlan_get_ap_prefer_conc_ch_params;
 	hdd_cbacks.wlan_get_sap_acs_band =
 			wlan_get_sap_acs_band;
+	hdd_cbacks.wlan_check_cc_intf_cb = wlan_hdd_check_cc_intf_cb;
 
 	if (QDF_STATUS_SUCCESS !=
 	    policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {

+ 41 - 0
core/sap/src/sap_fsm.c

@@ -891,6 +891,42 @@ static bool is_mcc_preferred(struct sap_context *sap_context,
 	return false;
 }
 
+/**
+ * sap_process_force_scc_with_go_start - Check GO force SCC or not
+ * psoc: psoc object
+ * sap_context: sap_context
+ *
+ * This function checks the current SAP MCC or not with the GO's home channel.
+ * If it is, skip the GO's force SCC. The SAP will do force SCC after
+ * GO's started.
+ *
+ * Return: true if skip GO's force SCC
+ */
+static bool
+sap_process_force_scc_with_go_start(struct wlan_objmgr_psoc *psoc,
+				    struct sap_context *sap_context)
+{
+	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
+	uint32_t con_freq;
+	enum phy_ch_width ch_width;
+
+	existing_vdev_id =
+		policy_mgr_fetch_existing_con_info(psoc,
+						   sap_context->sessionId,
+						   sap_context->chan_freq,
+						   &existing_vdev_mode,
+						   &con_freq, &ch_width);
+	if (existing_vdev_id < WLAN_UMAC_VDEV_ID_MAX &&
+	    existing_vdev_mode == PM_SAP_MODE) {
+		sap_debug("concurrent sap vdev: %d on freq %d, skip GO force scc",
+			  existing_vdev_id, con_freq);
+		return true;
+	}
+
+	return false;
+}
+
 #ifdef WLAN_FEATURE_P2P_P2P_STA
 /**
  * sap_set_forcescc_required - set force scc flag for provided p2p go vdev
@@ -1047,6 +1083,11 @@ sap_validate_chan(struct sap_context *sap_context,
 		*/
 		go_force_scc = policy_mgr_go_scc_enforced(mac_ctx->psoc);
 		sap_debug("go force scc enabled %d", go_force_scc);
+
+		if (sap_process_force_scc_with_go_start(mac_ctx->psoc,
+							sap_context))
+			goto validation_done;
+
 		if (go_force_scc) {
 			is_go_scc_strict =
 				policy_mgr_is_go_scc_strict(mac_ctx->psoc);