Prechádzať zdrojové kódy

qcacld-3.0: Add force MCC logic for LL_LT_SAP

LL_LT_SAP supports MCC with sta interface and does not
support SCC with any interface. Add a logic to force
MCC if any STA comes up in SCC with the LL_LT_SAP interface.
This change adds below logic to force MCC on LL_LT_SAP:
1. If STA is present and LL_LT_SAP comes up, select MCC
   channel in ACS and make sure to bring LL_LT_SAP on MCC channel.
2. If LL_LT_SAP starts without ACS in SCC channel, then
   overwrite this SCC channel with MCC channel.
3. If LL_LT_SAP is present and STA comes up in SCC with
   LL_LT_SAP, move LL_LT_SAP to an MCC channel or on different
   MAC channel.
4. If LL_LT_SAP and STA are present in MCC and STA receives
   CSA on LL_LT_SAP frequency resulting in SCC then move
   LL_LT_SAP to MCC frequency.
5. If LL_LT_SAP and STA are present in MCC and STA roams
   to LL_LT_SAP frequency resulting in SCC then move
   LL_LT_SAP to MCC frequency.

Preference to lower 5 GHz will be given followed by
standalone MAC frequency then MCC frequency.

Change-Id: I7f4380ed7d726112bbc2aa94a50ffbb5d8b6036d
CRs-Fixed: 3640669
Ashish Kumar Dhanotiya 1 rok pred
rodič
commit
e570b01a0c

+ 28 - 7
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ll_sap.h

@@ -20,16 +20,37 @@
 
 #include "wlan_objmgr_psoc_obj.h"
 
+#ifdef WLAN_FEATURE_LL_LT_SAP
 /**
- * wlan_policy_mgr_get_ll_lt_sap_vdev() - Get ll_lt_sap vdev
+ * wlan_policy_mgr_get_ll_lt_sap_vdev_id() - Get ll_lt_sap vdev id
  * @psoc: PSOC object
  *
- * API to find ll_lt_sap vdev pointer
- *
- * This API increments the ref count of the vdev object internally, the
- * caller has to invoke the wlan_objmgr_vdev_release_ref() to decrement
- * ref count
+ * API to find ll_lt_sap vdev id
  *
  * Return: vdev id
  */
-uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev(struct wlan_objmgr_psoc *psoc);
+uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev_id(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * __policy_mgr_is_ll_lt_sap_restart_required() - Check in ll_lt_sap restart is
+ * required
+ * @psoc: PSOC object
+ * @func: Function pointer of the caller function.
+ *
+ * This API checks if ll_lt_sap restart is required or not
+ *
+ * Return: true/false
+ */
+bool __policy_mgr_is_ll_lt_sap_restart_required(struct wlan_objmgr_psoc *psoc,
+						const char *func);
+
+#define policy_mgr_is_ll_lt_sap_restart_required(psoc) \
+	__policy_mgr_is_ll_lt_sap_restart_required(psoc, __func__)
+#else
+
+static inline bool
+policy_mgr_is_ll_lt_sap_restart_required(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+#endif

+ 8 - 1
components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -44,6 +44,7 @@
 #include "wlan_mlo_mgr_sta.h"
 #include "wlan_mlo_mgr_link_switch.h"
 #include "wlan_psoc_mlme_api.h"
+#include "wlan_policy_mgr_ll_sap.h"
 
 enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr)
 	(struct wlan_objmgr_psoc *psoc);
@@ -2833,7 +2834,7 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(
 				wlan_hdd_get_channel_for_sap_restart
 					(pm_ctx->psoc, vdev_id[i], &ch_freq);
 			if (status == QDF_STATUS_SUCCESS) {
-				policy_mgr_debug("SAP vdev id %d restarts due to MCC->SCC switch, old ch freq :%d new ch freq: %d",
+				policy_mgr_debug("SAP vdev id %d restarts, old ch freq :%d new ch freq: %d",
 						 vdev_id[i],
 						 op_ch_freq_list[i], ch_freq);
 				break;
@@ -3149,6 +3150,12 @@ void policy_mgr_check_concurrent_intf_and_restart_sap(
 			"No action taken at check_concurrent_intf_and_restart_sap");
 		return;
 	}
+
+	if (policy_mgr_is_ll_lt_sap_restart_required(psoc)) {
+		restart_sap = true;
+		goto sap_restart;
+	}
+
 	/*
 	 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
 	 * enabled on DFS channel then move the SAP out of DFS channel

+ 8 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -47,6 +47,7 @@
 #include "wlan_p2p_ucfg_api.h"
 #include "wlan_mlo_link_force.h"
 #include "wlan_connectivity_logging.h"
+#include "wlan_policy_mgr_ll_sap.h"
 
 /* invalid channel id. */
 #define INVALID_CHANNEL_ID 0
@@ -11703,6 +11704,13 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
 		policy_mgr_err("Invalid psoc");
 		return false;
 	}
+
+	if (policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id)) {
+		if (policy_mgr_is_ll_lt_sap_restart_required(psoc))
+			return true;
+		return false;
+	}
+
 	if (scc_mode == QDF_MCC_TO_SCC_SWITCH_DISABLE) {
 		policy_mgr_debug("No scc required");
 		return false;

+ 53 - 1
components/cmn_services/policy_mgr/src/wlan_policy_mgr_ll_sap.c

@@ -24,7 +24,7 @@
 #include "wlan_policy_mgr_i.h"
 #include "wlan_cmn.h"
 
-uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev(struct wlan_objmgr_psoc *psoc)
+uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev_id(struct wlan_objmgr_psoc *psoc)
 {
 	uint8_t ll_lt_sap_cnt;
 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
@@ -39,3 +39,55 @@ uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev(struct wlan_objmgr_psoc *psoc)
 
 	return vdev_id_list[0];
 }
+
+bool __policy_mgr_is_ll_lt_sap_restart_required(struct wlan_objmgr_psoc *psoc,
+						const char *func)
+{
+	qdf_freq_t ll_lt_sap_freq = 0;
+	uint8_t scc_vdev_id;
+	bool is_scc = false;
+	uint8_t conn_idx = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid pm ctx");
+		return false;
+	}
+
+	ll_lt_sap_freq = policy_mgr_get_ll_lt_sap_freq(psoc);
+
+	if (!ll_lt_sap_freq)
+		return false;
+
+	/*
+	 * Restart ll_lt_sap if any other interface is present in SCC
+	 * with LL_LT_SAP.
+	 */
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS;
+	     conn_idx++) {
+		if (pm_conc_connection_list[conn_idx].mode ==
+		      PM_LL_LT_SAP_MODE)
+			continue;
+
+		if (ll_lt_sap_freq == pm_conc_connection_list[conn_idx].freq) {
+			scc_vdev_id = pm_conc_connection_list[conn_idx].vdev_id;
+			is_scc = true;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	if (is_scc) {
+		uint8_t ll_lt_sap_vdev_id =
+				wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc);
+
+		policymgr_nofl_debug("%s ll_lt_sap vdev %d with freq %d is in scc with vdev %d",
+				     func, ll_lt_sap_vdev_id, ll_lt_sap_freq,
+				     scc_vdev_id);
+		return true;
+	}
+
+	return false;
+}

+ 4 - 3
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_bearer_switch.c

@@ -32,7 +32,7 @@ wlan_bs_req_id ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_psoc *psoc)
 	struct wlan_objmgr_vdev *vdev;
 	uint8_t vdev_id;
 
-	vdev_id = wlan_policy_mgr_get_ll_lt_sap_vdev(psoc);
+	vdev_id = wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc);
 	if (vdev_id == WLAN_INVALID_VDEV_ID)
 		return request_id;
 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
@@ -1458,7 +1458,7 @@ QDF_STATUS bs_sm_deliver_event(struct wlan_objmgr_psoc *psoc,
 	struct ll_sap_vdev_priv_obj *ll_sap_obj;
 	uint8_t vdev_id;
 
-	vdev_id = wlan_policy_mgr_get_ll_lt_sap_vdev(psoc);
+	vdev_id = wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc);
 	if (vdev_id == WLAN_INVALID_VDEV_ID)
 		return QDF_STATUS_E_INVAL;
 
@@ -1562,7 +1562,8 @@ ll_lt_sap_request_for_audio_transport_switch(
 
 		return QDF_STATUS_E_FAILURE;
 	}
-	ll_sap_err("BS_SM vdev %d Invalid audio transport type %d", req_type);
+	ll_sap_err("BS_SM vdev %d Invalid audio transport type %d",
+		   wlan_vdev_get_id(vdev), req_type);
 
 	return QDF_STATUS_E_INVAL;
 }

+ 22 - 24
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_main.c

@@ -100,12 +100,12 @@ QDF_STATUS ll_lt_sap_init(struct wlan_objmgr_vdev *vdev)
 		return QDF_STATUS_E_INVAL;
 	}
 
-	bs_ctx = ll_sap_obj->bearer_switch_ctx;
-
 	bs_ctx = qdf_mem_malloc(sizeof(struct bearer_switch_info));
 	if (!bs_ctx)
 		return QDF_STATUS_E_NOMEM;
 
+	ll_sap_obj->bearer_switch_ctx = bs_ctx;
+
 	qdf_atomic_init(&bs_ctx->request_id);
 
 	for (i = 0; i < WLAN_UMAC_PSOC_MAX_VDEVS; i++)
@@ -424,27 +424,25 @@ release_mem:
 	return status;
 }
 
-QDF_STATUS ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
-				struct wlan_bearer_switch_request *bs_request)
-{
-	return bs_sm_deliver_event(psoc, WLAN_BS_SM_EV_SWITCH_TO_NON_WLAN,
-				   sizeof(*bs_request), bs_request);
-}
-
-QDF_STATUS ll_lt_sap_request_for_audio_transport_switch(
-					enum bearer_switch_req_type req_type)
+qdf_freq_t ll_lt_sap_get_valid_freq(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id)
 {
-	/*
-	 * return status as QDF_STATUS_SUCCESS or failure based on the current
-	 * pending requests of the transport switch
-	 */
-	if (req_type == WLAN_BS_REQ_TO_NON_WLAN) {
-		ll_sap_debug("request SWITCH_TYPE_NON_WLAN accepted");
-		return QDF_STATUS_SUCCESS;
-	} else if (req_type == WLAN_BS_REQ_TO_WLAN) {
-		ll_sap_debug("request SWITCH_TYPE_WLAN accepted");
-		return QDF_STATUS_SUCCESS;
-	}
-
-	return QDF_STATUS_E_RESOURCES;
+	struct wlan_ll_lt_sap_freq_list freq_list;
+
+	ll_lt_sap_get_freq_list(psoc, &freq_list, vdev_id);
+
+	if (freq_list.standalone_mac.freq_5GHz_low)
+		return freq_list.standalone_mac.freq_5GHz_low;
+	if (freq_list.shared_mac.freq_5GHz_low)
+		return freq_list.shared_mac.freq_5GHz_low;
+	if (freq_list.standalone_mac.freq_6GHz)
+		return freq_list.standalone_mac.freq_6GHz;
+	if (freq_list.standalone_mac.freq_5GHz_high)
+		return freq_list.standalone_mac.freq_5GHz_high;
+	if (freq_list.shared_mac.freq_6GHz)
+		return freq_list.shared_mac.freq_6GHz;
+	if (freq_list.shared_mac.freq_5GHz_high)
+		return freq_list.shared_mac.freq_5GHz_high;
+
+	return freq_list.best_freq;
 }

+ 10 - 20
components/umac/mlme/sap/ll_sap/core/src/wlan_ll_lt_sap_main.h

@@ -47,6 +47,16 @@ QDF_STATUS ll_lt_sap_get_freq_list(struct wlan_objmgr_psoc *psoc,
 				   struct wlan_ll_lt_sap_freq_list *freq_list,
 				   uint8_t vdev_id);
 
+/**
+ * ll_lt_sap_get_valid_freq() - API to get valid frequency for LL_LT_SAP
+ * @psoc: Pointer to psoc object
+ * @vdev_id: Vdev Id of ll_lt_sap
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ll_lt_sap_get_valid_freq(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id);
+
 /*
  * ll_lt_sap_init() - Initialize ll_lt_sap infrastructure
  * @vdev: Pointer to vdev
@@ -64,24 +74,4 @@ QDF_STATUS ll_lt_sap_init(struct wlan_objmgr_vdev *vdev);
  * else error code
  */
 QDF_STATUS ll_lt_sap_deinit(struct wlan_objmgr_vdev *vdev);
-
-/**
- * ll_lt_sap_switch_bearer_to_ble() - Switch audio transport to BLE
- * @psoc: Pointer to psoc
- * @bs_request: Pointer to bearer switch request
- * Return: QDF_STATUS_SUCCESS on successful bearer switch else failure
- */
-QDF_STATUS
-ll_lt_sap_switch_bearer_to_ble(struct wlan_objmgr_psoc *psoc,
-			       struct wlan_bearer_switch_request *bs_request);
-
-/**
- * ll_lt_sap_request_for_audio_transport_switch() - Handls audio transport
- * switch request from userspace
- * @req_type: requested transport switch type
- *
- * Return: True/False
- */
-QDF_STATUS ll_lt_sap_request_for_audio_transport_switch(
-					enum bearer_switch_req_type req_type);
 #endif /* _WLAN_LL_SAP_MAIN_H_ */

+ 47 - 0
components/umac/mlme/sap/ll_sap/dispatcher/inc/wlan_ll_sap_api.h

@@ -27,6 +27,7 @@
 #include "wlan_objmgr_psoc_obj.h"
 #include "wlan_ll_sap_public_structs.h"
 #include "wlan_cm_public_struct.h"
+#include "wlan_policy_mgr_public_struct.h"
 
 #ifdef WLAN_FEATURE_LL_LT_SAP
 /**
@@ -90,6 +91,44 @@ QDF_STATUS wlan_ll_lt_sap_get_freq_list(
 				struct wlan_objmgr_psoc *psoc,
 				struct wlan_ll_lt_sap_freq_list *freq_list,
 				uint8_t vdev_id);
+
+/**
+ * wlan_ll_lt_sap_override_freq() - Return frequency on which LL_LT_SAP can
+ * be started
+ * @psoc: Pointer to psoc object
+ * @vdev_id: Vdev Id of LL_LT_SAP
+ * @chan_freq: current frequency of ll_lt_sap
+ *
+ * This function checks if ll_lt_sap can come up on the given frequency, if it
+ * can come up on given frequency then return same frequency else return a
+ * different frequency on which ll_lt_sap can come up
+ *
+ * Return: valid ll_lt_sap frequency
+ */
+qdf_freq_t wlan_ll_lt_sap_override_freq(struct wlan_objmgr_psoc *psoc,
+					uint32_t vdev_id,
+					qdf_freq_t chan_freq);
+
+/**
+ * wlan_get_ll_lt_sap_restart_freq() - Get restart frequency on which LL_LT_SAP
+ * can be re-started
+ * @pdev: Pointer to pdev object
+ * @chan_freq: current frequency of ll_lt_sap
+ * @vdev_id: Vdev Id of LL_LT_SAP
+ * @csa_reason: Reason for the CSA
+ *
+ * This function checks if ll_lt_sap needs to be restarted, if yes, it returns
+ * new valid frequency on which ll_lt_sap can be restarted else return same
+ * frequency.
+ *
+ * Return: valid ll_lt_sap frequency
+ */
+qdf_freq_t
+wlan_get_ll_lt_sap_restart_freq(struct wlan_objmgr_pdev *pdev,
+				qdf_freq_t chan_freq,
+				uint8_t vdev_id,
+				enum sap_csa_reason_code *csa_reason);
+
 #else
 static inline wlan_bs_req_id
 wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_vdev *vdev)
@@ -130,5 +169,13 @@ QDF_STATUS wlan_ll_lt_sap_get_freq_list(
 {
 	return QDF_STATUS_E_FAILURE;
 }
+
+static inline
+qdf_freq_t wlan_ll_lt_sap_override_freq(struct wlan_objmgr_psoc *psoc,
+					uint32_t vdev_id,
+					qdf_freq_t chan_freq)
+{
+	return chan_freq;
+}
 #endif /* WLAN_FEATURE_LL_LT_SAP */
 #endif /* _WLAN_LL_LT_SAP_API_H_ */

+ 64 - 5
components/umac/mlme/sap/ll_sap/dispatcher/src/wlan_ll_sap_api.c

@@ -20,6 +20,8 @@
 #include "wlan_cm_api.h"
 #include "wlan_policy_mgr_ll_sap.h"
 #include "wlan_policy_mgr_api.h"
+#include "wlan_reg_services_api.h"
+#include "wlan_dfs_utils_api.h"
 
 wlan_bs_req_id
 wlan_ll_lt_sap_bearer_switch_get_id(struct wlan_objmgr_psoc *psoc)
@@ -61,13 +63,13 @@ wlan_ll_sap_switch_bearer_on_sta_connect_start(struct wlan_objmgr_psoc *psoc,
 	qdf_freq_t ll_lt_sap_freq;
 	bool is_bearer_switch_required = false;
 	QDF_STATUS status = QDF_STATUS_E_ALREADY;
-	uint8_t vdev_id;
+	uint8_t ll_lt_sap_vdev_id;
 
-	vdev_id = wlan_policy_mgr_get_ll_lt_sap_vdev(psoc);
+	ll_lt_sap_vdev_id = wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc);
 	/* LL_LT SAP is not present, bearer switch is not required */
-	if (vdev_id == WLAN_INVALID_VDEV_ID)
+	if (ll_lt_sap_vdev_id == WLAN_INVALID_VDEV_ID)
 		return status;
-	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, ll_lt_sap_vdev_id,
 						    WLAN_LL_SAP_ID);
 	if (!vdev)
 		return status;
@@ -75,7 +77,7 @@ wlan_ll_sap_switch_bearer_on_sta_connect_start(struct wlan_objmgr_psoc *psoc,
 	if (!scan_list || !qdf_list_size(scan_list))
 		goto rel_ref;
 
-	ll_lt_sap_freq = policy_mgr_get_lt_ll_sap_freq(psoc);
+	ll_lt_sap_freq = policy_mgr_get_ll_lt_sap_freq(psoc);
 	qdf_list_peek_front(scan_list, &cur_node);
 
 	while (cur_node) {
@@ -161,3 +163,60 @@ QDF_STATUS wlan_ll_lt_sap_get_freq_list(
 {
 	return ll_lt_sap_get_freq_list(psoc, freq_list, vdev_id);
 }
+
+qdf_freq_t wlan_ll_lt_sap_override_freq(struct wlan_objmgr_psoc *psoc,
+					uint32_t vdev_id,
+					qdf_freq_t chan_freq)
+{
+	qdf_freq_t freq;
+
+	if (!policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id))
+		return chan_freq;
+
+	/*
+	 * If already any concurrent interface is present on this frequency,
+	 * select a different frequency to start ll_lt_sap
+	 */
+	if (!policy_mgr_get_connection_count_with_ch_freq(chan_freq))
+		return chan_freq;
+
+	freq = ll_lt_sap_get_valid_freq(psoc, vdev_id);
+
+	ll_sap_debug("Vdev %d ll_lt_sap old freq %d new freq %d", vdev_id,
+		     chan_freq, freq);
+
+	return freq;
+}
+
+qdf_freq_t wlan_get_ll_lt_sap_restart_freq(struct wlan_objmgr_pdev *pdev,
+					   qdf_freq_t chan_freq,
+					   uint8_t vdev_id,
+					   enum sap_csa_reason_code *csa_reason)
+{
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+	qdf_freq_t restart_freq;
+
+	if (wlan_reg_is_disable_in_secondary_list_for_freq(pdev, chan_freq) &&
+	    !utils_dfs_is_freq_in_nol(pdev, chan_freq)) {
+		*csa_reason = CSA_REASON_CHAN_DISABLED;
+		goto get_new_ll_lt_sap_freq;
+	} else if (wlan_reg_is_passive_for_freq(pdev, chan_freq))  {
+		*csa_reason = CSA_REASON_CHAN_PASSIVE;
+		goto get_new_ll_lt_sap_freq;
+	} else if (!policy_mgr_is_sap_freq_allowed(psoc, chan_freq)) {
+		*csa_reason = CSA_REASON_UNSAFE_CHANNEL;
+		goto get_new_ll_lt_sap_freq;
+	} else if (policy_mgr_is_ll_lt_sap_restart_required(psoc)) {
+		*csa_reason = CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL;
+		goto get_new_ll_lt_sap_freq;
+	}
+
+	return chan_freq;
+
+get_new_ll_lt_sap_freq:
+	restart_freq = ll_lt_sap_get_valid_freq(psoc, vdev_id);
+
+	ll_sap_debug("vdev %d old freq %d restart freq %d CSA reason %d ",
+		     vdev_id, chan_freq, restart_freq, *csa_reason);
+	return restart_freq;
+}

+ 34 - 9
core/hdd/src/wlan_hdd_hostapd.c

@@ -120,6 +120,7 @@
 #include "wlan_twt_ucfg_api.h"
 #include "wlan_vdev_mgr_ucfg_api.h"
 #include <wlan_psoc_mlme_ucfg_api.h>
+#include "wlan_ll_sap_api.h"
 
 #define ACS_SCAN_EXPIRY_TIMEOUT_S 4
 
@@ -3930,16 +3931,35 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(struct wlan_objmgr_psoc *psoc,
 	else
 		ch_params.ch_width = CH_WIDTH_MAX;
 
-	intf_ch_freq = wlansap_get_chan_band_restrict(sap_context, &csa_reason);
-	if (intf_ch_freq && intf_ch_freq != sap_context->chan_freq) {
-		goto sap_restart;
-	} else if (!intf_ch_freq &&
-		  policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id)) {
-		schedule_work(&ap_adapter->sap_stop_bss_work);
-		wlansap_context_put(sap_context);
-		hdd_debug("stop ll_lt_sap, no channel found for csa");
-		return QDF_STATUS_E_FAILURE;
+	if (policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id)) {
+		/*
+		 * Adding this feature flag temporarily, will remove this once
+		 * feature flag is enabled.
+		 */
+#ifdef WLAN_FEATURE_LL_LT_SAP
+		intf_ch_freq =
+			wlan_get_ll_lt_sap_restart_freq(hdd_ctx->pdev,
+							sap_context->chan_freq,
+							sap_context->vdev_id,
+							&csa_reason);
+#else
+		intf_ch_freq = wlansap_get_chan_band_restrict(sap_context,
+							      &csa_reason);
+#endif
+		if (!intf_ch_freq) {
+			schedule_work(&ap_adapter->sap_stop_bss_work);
+			wlansap_context_put(sap_context);
+			hdd_debug("vdev %d stop ll_lt_sap, no channel found for csa",
+				  vdev_id);
+			return QDF_STATUS_E_FAILURE;
+		}
+	} else {
+		intf_ch_freq = wlansap_get_chan_band_restrict(sap_context,
+							      &csa_reason);
 	}
+	if (intf_ch_freq && intf_ch_freq != sap_context->chan_freq)
+		goto sap_restart;
+
 	/*
 	 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
 	 * enabled on DFS channel then move the SAP out of DFS channel
@@ -6542,6 +6562,11 @@ int wlan_hdd_cfg80211_start_bss(struct wlan_hdd_link_info *link_info,
 		if (ret < 0)
 			goto error;
 	}
+
+	config->chan_freq = wlan_ll_lt_sap_override_freq(hdd_ctx->psoc,
+							 link_info->vdev_id,
+							 config->chan_freq);
+
 	if (!ret && wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, config->chan_freq))
 		hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;