Răsfoiți Sursa

qcacld-3.0: Move 5GHz channels ahead of 2 GHz for Early Stop

In case prefer 5 GHz preference is set, move the 5GHz channels ahead
of 2GHz channels in channel list as used in Early Stop Roaming Scan
feature. This ensures that while roaming, when these features are
enabled DUT will scan 5 GHz channels first and roam if a candidate
AP is found.

Change-Id: I96d997560a3eca5fd378aa3ed78c5766d097cafd
CRs-Fixed: 951959
Naveen Rawat 9 ani în urmă
părinte
comite
b13bf0365c
2 a modificat fișierele cu 87 adăugiri și 4 ștergeri
  1. 4 0
      core/sme/inc/csr_internal.h
  2. 83 4
      core/sme/src/csr/csr_api_roam.c

+ 4 - 0
core/sme/inc/csr_internal.h

@@ -68,6 +68,10 @@
 
 #define CSR_IS_SESSION_ANY(sessionId) (sessionId == SME_SESSION_ID_ANY)
 #define CSR_MAX_NUM_COUNTRY_CODE  100
+#define CSR_IS_DFS_CH_ROAM_ALLOWED(mac_ctx) \
+	( \
+	  (((mac_ctx)->roam.configParam.allowDFSChannelRoam) ? true : false) \
+	)
 #define CSR_IS_SELECT_5GHZ_MARGIN(pMac) \
 	( \
 	  (((pMac)->roam.configParam.nSelect5GHzMargin) ? true : false) \

+ 83 - 4
core/sme/src/csr/csr_api_roam.c

@@ -476,8 +476,84 @@ static tPowerdBm csr_find_channel_pwr(tChannelListWithPower *
 	CDF_ASSERT(0);
 	return 0;
 }
+
+/**
+ * csr_roam_arrange_ch_list() - Updates the channel list modified with greedy
+ * order for 5 Ghz preference and DFS channels.
+ * @mac_ctx: pointer to mac context.
+ * @chan_list:    channel list updated with greedy channel order.
+ * @num_channel:  Number of channels in list
+ *
+ * To allow Early Stop Roaming Scan feature to co-exist with 5G preference,
+ * this function moves 5G channels ahead of 2G channels. This function can
+ * also move 2G channels, ahead of DFS channel or vice versa. Order is
+ * maintained among same category channels
+ *
+ * Return: None
+ */
+void csr_roam_arrange_ch_list(tpAniSirGlobal mac_ctx,
+			tSirUpdateChanParam *chan_list, uint8_t num_channel)
+{
+	bool prefer_5g = CSR_IS_ROAM_PREFER_5GHZ(mac_ctx);
+	bool prefer_dfs = CSR_IS_DFS_CH_ROAM_ALLOWED(mac_ctx);
+	int i, j = 0;
+	tSirUpdateChanParam *tmp_list = NULL;
+
+	if (!prefer_5g)
+		return;
+
+	tmp_list = (tSirUpdateChanParam *)
+		cdf_mem_malloc(sizeof(tSirUpdateChanParam) * num_channel);
+	if (tmp_list == NULL) {
+		sms_log(mac_ctx, LOGE, FL("Memory allocation failed"));
+		return;
+	}
+
+	/* Fist copy Non-DFS 5g channels */
+	for (i = 0; i < num_channel; i++) {
+		if (CDS_IS_CHANNEL_5GHZ(chan_list[i].chanId) &&
+			!CDS_IS_DFS_CH(chan_list[i].chanId)) {
+			cdf_mem_copy(&tmp_list[j++],
+				&chan_list[i], sizeof(tSirUpdateChanParam));
+			chan_list[i].chanId = INVALID_CHANNEL_ID;
+		}
+	}
+	if (prefer_dfs) {
+		/* next copy DFS channels (remaining channels in 5G) */
+		for (i = 0; i < num_channel; i++) {
+			if (CDS_IS_CHANNEL_5GHZ(chan_list[i].chanId)) {
+				cdf_mem_copy(&tmp_list[j++], &chan_list[i],
+					sizeof(tSirUpdateChanParam));
+				chan_list[i].chanId = INVALID_CHANNEL_ID;
+			}
+		}
+	} else {
+		/* next copy 2G channels */
+		for (i = 0; i < num_channel; i++) {
+			if (CDS_IS_CHANNEL_24GHZ(chan_list[i].chanId)) {
+				cdf_mem_copy(&tmp_list[j++], &chan_list[i],
+					sizeof(tSirUpdateChanParam));
+				chan_list[i].chanId = INVALID_CHANNEL_ID;
+			}
+		}
+	}
+	/* copy rest of the channels in same order to tmp list */
+	for (i = 0; i < num_channel; i++) {
+		if (chan_list[i].chanId != INVALID_CHANNEL_ID) {
+			cdf_mem_copy(&tmp_list[j++], &chan_list[i],
+				sizeof(tSirUpdateChanParam));
+			chan_list[i].chanId = INVALID_CHANNEL_ID;
+		}
+	}
+	/* copy tmp list to original channel list buffer */
+	cdf_mem_copy(chan_list, tmp_list,
+				 sizeof(tSirUpdateChanParam) * num_channel);
+	cdf_mem_free(tmp_list);
+}
+
 /**
  * csr_roam_sort_channel_for_early_stop() - Sort the channels
+ * @mac_ctx:        mac global context
  * @chan_list:      Original channel list from the upper layers
  * @num_channel:    Number of original channels
  *
@@ -495,8 +571,8 @@ static tPowerdBm csr_find_channel_pwr(tChannelListWithPower *
  *
  * Return: None
  */
-void csr_roam_sort_channel_for_early_stop(tSirUpdateChanList *chan_list,
-		uint8_t num_channel)
+void csr_roam_sort_channel_for_early_stop(tpAniSirGlobal mac_ctx,
+			tSirUpdateChanList *chan_list, uint8_t num_channel)
 {
 	tSirUpdateChanList *chan_list_greedy, *chan_list_non_greedy;
 	uint8_t i, j;
@@ -587,6 +663,9 @@ void csr_roam_sort_channel_for_early_stop(tSirUpdateChanList *chan_list,
 	cdf_mem_copy(&chan_list->chanParam[i],
 		&chan_list_non_greedy->chanParam[j],
 		num_non_greedy_chan * sizeof(tSirUpdateChanParam));
+
+	/* Update channel list for 5g preference and allow DFS roam */
+	csr_roam_arrange_ch_list(mac_ctx, chan_list->chanParam, num_channel);
 scan_list_sort_error:
 	cdf_mem_free(chan_list_greedy);
 	cdf_mem_free(chan_list_non_greedy);
@@ -673,7 +752,8 @@ CDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac)
 		}
 	}
 	if (pMac->roam.configParam.early_stop_scan_enable)
-		csr_roam_sort_channel_for_early_stop(pChanList, num_channel);
+		csr_roam_sort_channel_for_early_stop(pMac, pChanList,
+						     num_channel);
 	else
 		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
 			FL("Early Stop Scan Feature not supported"));
@@ -726,7 +806,6 @@ CDF_STATUS csr_start(tpAniSirGlobal pMac)
 		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
 			  "Scan offload is enabled, update default chan list");
 		status = csr_update_channel_list(pMac);
-
 	} while (0);
 	return status;
 }