Sfoglia il codice sorgente

qcacld-3.0: Fix SAP+SAP SCC DFS concurrency on DBS platform

As per current implementation, if one SAP is on DFS channel & another
SAP is non-DFS and if RADAR is detected on DFS channel then both SAPs
are changing channels which is incorrect behavior for new platforms.

Above limitation was added for old platform where SAP+SAP concurrency
was allowed only for DFS SCC feature.

Allow both SAPs to change the channel back to back when they are on
same SCC DFS channel. This change will allow to maintain backward
compatiblity with old platform.

CRs-Fixed: 2114154
Change-Id: I9c426f9a148d0feac552c34929daad1e802edd2f
Krunal Soni 7 anni fa
parent
commit
e8324ce7d8
3 ha cambiato i file con 122 aggiunte e 5 eliminazioni
  1. 29 2
      core/sap/src/sap_api_link_cntl.c
  2. 91 2
      core/sap/src/sap_fsm.c
  3. 2 1
      core/sap/src/sap_internal.h

+ 29 - 2
core/sap/src/sap_api_link_cntl.c

@@ -532,6 +532,7 @@ wlansap_roam_process_dfs_chansw_update(tHalHandle hHal,
 	QDF_STATUS qdf_status;
 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal);
 	uint8_t dfs_beacon_start_req = 0;
+	bool sap_scc_dfs;
 
 	if (sap_ctx->csr_roamProfile.disableDFSChSwitch) {
 		QDF_TRACE(QDF_MODULE_ID_SAP,
@@ -590,9 +591,22 @@ wlansap_roam_process_dfs_chansw_update(tHalHandle hHal,
 	 * immediately, as in this case the both SAP will be in different band
 	 * and channel change on one SAP doesnt mean channel change on
 	 * other interface.
+	 *
+	 * For example,
+	 * Let's say SAP(2G) + SAP(5G-DFS) is initial connection which triggered
+	 * DualBand HW mode and if SAP(5G-DFS) is moving to some channel then
+	 * SAP(2G) doesn't need to move.
+	 *
+	 * If both SAPs are not doing SCC DFS then each of them can change the
+	 * channel independently. Channel change of one SAP became dependent
+	 * second SAP's channel change due to some previous platform's single
+	 * radio limitation.
+	 *
 	 */
+	sap_scc_dfs = sap_is_conc_sap_doing_scc_dfs(hHal, sap_ctx);
 	if (sap_get_total_number_sap_intf(hHal) <= 1 ||
-	    policy_mgr_is_current_hwmode_dbs(mac_ctx->psoc)) {
+	    policy_mgr_is_current_hwmode_dbs(mac_ctx->psoc) ||
+	    !sap_scc_dfs) {
 		/* Send channel switch request */
 		sap_event.event = eWNI_SME_CHANNEL_CHANGE_REQ;
 		sap_event.params = 0;
@@ -615,6 +629,14 @@ wlansap_roam_process_dfs_chansw_update(tHalHandle hHal,
 	 * both the SAPs. If no then simply return success & we will
 	 * issue channel change when second AP's 5 CSA beacon Tx is
 	 * completed.
+	 *
+	 * This check is added to take care of following scenario:
+	 * if SAP1 + SAP2 is doing DFS SCC and radar is detected on that channel
+	 * then SAP1 sends 5 beacons with CSA/ECSA IE and wait for SAP2 to
+	 * finish sending 5 beacons. if SAP1 changes channel before SAP2 finish
+	 * sending beacons then it ends up in
+	 * (SAP1 new channel + SAP2 old channel) MCC with DFS scenario
+	 * which causes some of the stability issues in old platforms.
 	 */
 	if (false ==
 	    is_concurrent_sap_ready_for_channel_change(hHal, sap_ctx)) {
@@ -631,7 +653,6 @@ wlansap_roam_process_dfs_chansw_update(tHalHandle hHal,
 		if (!((QDF_SAP_MODE == mac_ctx->sap.sapCtxList[intf].sapPersona)
 		    && (mac_ctx->sap.sapCtxList[intf].pSapContext != NULL)))
 			continue;
-
 		pSapContext = mac_ctx->sap.sapCtxList[intf].pSapContext;
 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
 			  FL("sapdfs:issue chnl change for sapctx[%pK]"),
@@ -1038,6 +1059,8 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId,
 		/* Issue stopbss for each sapctx */
 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
 			struct sap_context *pSapContext;
+			tCsrRoamProfile *profile;
+
 			if (((QDF_SAP_MODE ==
 			    mac_ctx->sap.sapCtxList[intf].sapPersona) ||
 			    (QDF_P2P_GO_MODE ==
@@ -1046,6 +1069,10 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId,
 			    NULL) {
 				pSapContext =
 				    mac_ctx->sap.sapCtxList[intf].pSapContext;
+				profile = &pSapContext->csr_roamProfile;
+				if (!wlan_reg_is_dfs_ch(mac_ctx->pdev,
+						profile->operationChannel))
+					continue;
 				QDF_TRACE(QDF_MODULE_ID_SAP,
 					  QDF_TRACE_LEVEL_ERROR,
 					  FL("sapdfs: no available channel for sapctx[%pK], StopBss"),

+ 91 - 2
core/sap/src/sap_fsm.c

@@ -2796,11 +2796,18 @@ static QDF_STATUS sap_cac_start_notify(tHalHandle hHal)
 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
 		struct sap_context *pSapContext =
 			pMac->sap.sapCtxList[intf].pSapContext;
+		tCsrRoamProfile *profile;
+
 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
 		    ||
 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL &&
 		    (false == pSapContext->isCacStartNotified)) {
+			/* Don't start CAC for non-dfs channel, its violation */
+			profile = &pSapContext->csr_roamProfile;
+			if (!wlan_reg_is_dfs_ch(pMac->pdev,
+						profile->operationChannel))
+				continue;
 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
 				  "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]",
 				  pSapContext);
@@ -2888,6 +2895,8 @@ static QDF_STATUS sap_cac_end_notify(tHalHandle hHal, tCsrRoamInfo *roamInfo)
 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
 		struct sap_context *pSapContext =
 			pMac->sap.sapCtxList[intf].pSapContext;
+		tCsrRoamProfile *profile;
+
 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
 		    ||
 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
@@ -2895,6 +2904,11 @@ static QDF_STATUS sap_cac_end_notify(tHalHandle hHal, tCsrRoamInfo *roamInfo)
 		    (false == pSapContext->isCacEndNotified) &&
 		    (pSapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) {
 			pSapContext = pMac->sap.sapCtxList[intf].pSapContext;
+			/* Don't check CAC for non-dfs channel */
+			profile = &pSapContext->csr_roamProfile;
+			if (!wlan_reg_is_dfs_ch(pMac->pdev,
+						profile->operationChannel))
+				continue;
 
 			/* If this is an end notification of a pre cac, the
 			 * SAP must not start beaconing and must delete the
@@ -3242,6 +3256,8 @@ static QDF_STATUS sap_fsm_state_dfs_cac_wait(struct sap_context *sap_ctx,
 
 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
 			struct sap_context *t_sap_ctx;
+			tCsrRoamProfile *profile;
+
 			t_sap_ctx = mac_ctx->sap.sapCtxList[intf].pSapContext;
 			if (((QDF_SAP_MODE ==
 				 mac_ctx->sap.sapCtxList[intf].sapPersona) ||
@@ -3249,8 +3265,12 @@ static QDF_STATUS sap_fsm_state_dfs_cac_wait(struct sap_context *sap_ctx,
 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
 			    t_sap_ctx != NULL &&
 			    t_sap_ctx->sapsMachine != eSAP_DISCONNECTED) {
+				profile = &t_sap_ctx->csr_roamProfile;
+				if (!wlan_reg_is_dfs_ch(mac_ctx->pdev,
+						profile->operationChannel))
+					continue;
 				/* SAP to be moved to DISCONNECTING state */
-				sap_ctx->sapsMachine = eSAP_DISCONNECTING;
+				t_sap_ctx->sapsMachine = eSAP_DISCONNECTING;
 				/*
 				 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
 				 * A Radar is found on current DFS Channel
@@ -3460,6 +3480,8 @@ static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx,
 		 */
 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
 			struct sap_context *temp_sap_ctx;
+			tCsrRoamProfile *profile;
+
 			if (((QDF_SAP_MODE ==
 				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
 			    (QDF_P2P_GO_MODE ==
@@ -3467,6 +3489,14 @@ static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx,
 			    mac_ctx->sap.sapCtxList[intf].pSapContext != NULL) {
 				temp_sap_ctx =
 				    mac_ctx->sap.sapCtxList[intf].pSapContext;
+				/*
+				 * Radar won't come on non-dfs channel, so
+				 * no need to move them
+				 */
+				profile = &temp_sap_ctx->csr_roamProfile;
+				if (!wlan_reg_is_dfs_ch(mac_ctx->pdev,
+						profile->operationChannel))
+					continue;
 				QDF_TRACE(QDF_MODULE_ID_SAP,
 					  QDF_TRACE_LEVEL_INFO_MED,
 					  FL("sapdfs: Sending CSAIE for sapctx[%pK]"),
@@ -4505,9 +4535,17 @@ uint8_t sap_get_total_number_sap_intf(tHalHandle hHal)
 	return intf_count;
 }
 
-/*
+/**
+ * is_concurrent_sap_ready_for_channel_change() - to check all saps are ready
+ *						  for channel change
+ * @hHal: HAL pointer
+ * @sapContext: sap context for which this function has been called
+ *
  * This function will find the concurrent sap context apart from
  * passed sap context and return its channel change ready status
+ *
+ *
+ * Return: true if other SAP personas are ready to channel switch else false
  */
 bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal,
 						struct sap_context *sapContext)
@@ -4541,3 +4579,54 @@ bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal,
 	}
 	return false;
 }
+
+/**
+ * sap_is_conc_sap_doing_scc_dfs() - check if conc SAPs are doing SCC DFS
+ * @hal: pointer to hal
+ * @sap_context: current SAP persona's channel
+ *
+ * If provided SAP's channel is DFS then Loop through each SAP or GO persona and
+ * check if other beaconing entity's channel is same DFS channel. If they are
+ * same then concurrent sap is doing SCC DFS.
+ *
+ * Return: true if two or more beaconing entitity doing SCC DFS else false
+ */
+bool sap_is_conc_sap_doing_scc_dfs(tHalHandle hal,
+				   struct sap_context *given_sapctx)
+{
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct sap_context *sap_ctx;
+	uint8_t intf = 0, scc_dfs_counter = 0;
+
+	/*
+	 * current SAP persona's channel itself is not DFS, so no need to check
+	 * what other persona's channel is
+	 */
+	if (!wlan_reg_is_dfs_ch(mac->pdev,
+			given_sapctx->csr_roamProfile.operationChannel)) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
+			  FL("skip this loop as provided channel is non-dfs"));
+		return false;
+	}
+
+	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
+		if ((QDF_SAP_MODE != mac->sap.sapCtxList[intf].sapPersona) &&
+		    (QDF_P2P_GO_MODE != mac->sap.sapCtxList[intf].sapPersona))
+			continue;
+		if (!mac->sap.sapCtxList[intf].pSapContext)
+			continue;
+		sap_ctx = mac->sap.sapCtxList[intf].pSapContext;
+		/* if same SAP contexts then skip to next context */
+		if (sap_ctx == given_sapctx)
+			continue;
+		if (given_sapctx->csr_roamProfile.operationChannel ==
+				sap_ctx->csr_roamProfile.operationChannel)
+			scc_dfs_counter++;
+	}
+
+	/* Found atleast two of the beaconing entities doing SCC DFS */
+	if (scc_dfs_counter)
+		return true;
+
+	return false;
+}

+ 2 - 1
core/sap/src/sap_internal.h

@@ -391,7 +391,8 @@ sap_channel_matrix_check(struct sap_context *sapContext,
 
 bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal,
 						struct sap_context *sapContext);
-
+bool sap_is_conc_sap_doing_scc_dfs(tHalHandle hal,
+				   struct sap_context *given_sapctx);
 uint8_t sap_get_total_number_sap_intf(tHalHandle hHal);
 
 bool sap_dfs_is_w53_invalid(tHalHandle hHal, uint8_t channelID);