瀏覽代碼

qcacld-3.0: Fix recursive calling of CSR roam API

If STA is trying to connect and same time SAP initiate the
change channel the HW mode calculated during connection start will
may not be valid for some STA's candidate and thus, it will avoid
connecting to these candidate leading to recursive calling of CSR
roam API.

To fix this while selecting the candidate skip the candidate itself
even before trying to connect if the candidate channel is not allowed
for current HW mode. Also block SAP channel change from user
space during connection.

Change-Id: Ic04aa983d95986f05d6359eb112d489e8ef80478
CRs-Fixed: 2380459
Abhishek Singh 6 年之前
父節點
當前提交
f8364e11b7
共有 2 個文件被更改,包括 33 次插入26 次删除
  1. 10 0
      core/hdd/src/wlan_hdd_hostapd.c
  2. 23 26
      core/sme/src/csr/csr_api_roam.c

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

@@ -2793,6 +2793,16 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel,
 	if (ret)
 		return ret;
 
+	/*
+	 * If sta connection is in progress do not allow SAP channel change from
+	 * user space as it may change the HW mode requirement, for which sta is
+	 * trying to connect.
+	 */
+	if (hdd_get_sta_connection_in_progress(hdd_ctx)) {
+		hdd_err("STA connection is in progress");
+		return -EBUSY;
+	}
+
 	ret = hdd_validate_channel_and_bandwidth(adapter,
 						target_channel, target_bw);
 	if (ret) {

+ 23 - 26
core/sme/src/csr/csr_api_roam.c

@@ -4988,7 +4988,7 @@ static void csr_roam_assign_default_param(struct mac_context *mac,
  * Return: true if the entire BSS list is done, false otherwise.
  */
 static bool csr_roam_select_bss(struct mac_context *mac_ctx,
-		tListElem *roam_bss_entry, tCsrScanResultInfo **csr_result_info,
+		tListElem **roam_bss_entry, tCsrScanResultInfo **csr_result_info,
 		struct tag_csrscan_result **csr_scan_result,
 		uint32_t session_id, uint32_t roam_id,
 		enum csr_join_state *roam_state,
@@ -4999,8 +4999,8 @@ static bool csr_roam_select_bss(struct mac_context *mac_ctx,
 	struct tag_csrscan_result *scan_result = NULL;
 	tCsrScanResultInfo *result = NULL;
 
-	while (roam_bss_entry) {
-		scan_result = GET_BASE_ADDR(roam_bss_entry, struct
+	while (*roam_bss_entry) {
+		scan_result = GET_BASE_ADDR(*roam_bss_entry, struct
 				tag_csrscan_result, Link);
 		/*
 		 * If concurrency enabled take the
@@ -5009,6 +5009,23 @@ static bool csr_roam_select_bss(struct mac_context *mac_ctx,
 		 * sessions exempted
 		 */
 		result = &scan_result->Result;
+
+		/*
+		 * check if channel is allowed for current hw mode, if not fetch
+		 * next BSS.
+		 */
+		if (!policy_mgr_is_hwmode_set_for_given_chnl(mac_ctx->psoc,
+					result->BssDescriptor.channelId)) {
+			sme_err("HW mode is not properly set for channel %d BSSID %pM",
+				result->BssDescriptor.channelId,
+				result->BssDescriptor.bssId);
+			*roam_state = eCsrStopRoamingDueToConcurrency;
+			status = true;
+			*roam_bss_entry = csr_ll_next(&bss_list->List,
+						     *roam_bss_entry,
+						     LL_ACCESS_LOCK);
+			continue;
+		}
 		if (policy_mgr_concurrent_open_sessions_running(mac_ctx->psoc)
 			&& !csr_is_valid_mc_concurrent_session(mac_ctx,
 					session_id, &result->BssDescriptor)) {
@@ -5036,7 +5053,7 @@ static bool csr_roam_select_bss(struct mac_context *mac_ctx,
 		}
 		*roam_state = eCsrStopRoamingDueToConcurrency;
 		status = true;
-		roam_bss_entry = csr_ll_next(&bss_list->List, roam_bss_entry,
+		*roam_bss_entry = csr_ll_next(&bss_list->List, *roam_bss_entry,
 					LL_ACCESS_LOCK);
 	}
 	*csr_result_info = result;
@@ -5289,7 +5306,7 @@ static enum csr_join_state csr_roam_join_next_bss(struct mac_context *mac_ctx,
 			roam_info->reasonCode = join_status->reasonCode;
 		}
 		done = csr_roam_select_bss(mac_ctx,
-				cmd->u.roamCmd.pRoamBssEntry, &result,
+				&cmd->u.roamCmd.pRoamBssEntry, &result,
 				&scan_result, session_id, cmd->u.roamCmd.roamId,
 				&roam_state, bss_list);
 		if (done)
@@ -14365,7 +14382,7 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
 	int8_t pwrLimit = 0;
 	struct ps_global_info *ps_global_info = &mac->sme.ps_global_info;
 	struct ps_params *ps_param = &ps_global_info->ps_params[sessionId];
-	uint8_t ese_config = 0, channel_id;
+	uint8_t ese_config = 0;
 	tpCsrNeighborRoamControlInfo neigh_roam_info;
 	uint32_t value = 0, value1 = 0;
 	QDF_STATUS packetdump_timer_status;
@@ -14394,26 +14411,6 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
 		pSession->disable_hi_rssi = false;
 	}
 
-	/*
-	 * When STA's join req times out on current BSS, SME issues next BSS
-	 * internally without checking HW mode for new channel.
-	 *
-	 * For example, STA tries to connect SSID="abc",
-	 * BSSID="a1:a2:a3:a4:a5:a6", channel=36 and lets say it fails. It
-	 * should try few more times to same BSSID and after that it will try
-	 * next bss. Lets say next BSS it found has, SSID="abc",
-	 * BSSID="b1:b2:b3:b4:b5:b6", channel=1 then it needs to check whether
-	 * hardware mode change is required for channel=1. If driver fails in
-	 * checking hardware mode then following check will prevent the bad
-	 * situation.
-	 */
-	channel_id = pBssDescription->channelId;
-	if (!policy_mgr_is_hwmode_set_for_given_chnl(mac->psoc, channel_id)) {
-		sme_err("HW mode is not properly set for channel %d",
-			channel_id);
-		return QDF_STATUS_E_FAILURE;
-	}
-
 	do {
 		pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS;
 		pSession->joinFailStatusCode.reasonCode = 0;