Explorar o código

qcacmn: Add support to use new random channel algorithm

1) Add support to use new random channel selection algorithm
   from converged DFS component.

2) Move random channel filtering flags from dfs_internal.h to
   dfs_ioctl.h as these flags are common between MLME and DFS
   component.

Change-Id: I5ef789dd9e9c28706f1c581997a646a80caec5ee
CRs-Fixed: 2120265
Shashikala Prabhu %!s(int64=7) %!d(string=hai) anos
pai
achega
68431d3ea5

+ 22 - 0
umac/cmn_services/dfs/inc/dfs_ioctl.h

@@ -122,4 +122,26 @@ struct dfs_ioctl_params {
 #define DFS_IOCTL_PARAM_NOVAL  65535
 #define DFS_IOCTL_PARAM_ENABLE 0x8000
 
+/* Random channel flags */
+/* Flag to exclude current operating channels */
+#define DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH       0x0001 /* 0000 0000 0000 0001 */
+
+/* Flag to exclude weather channels */
+#define DFS_RANDOM_CH_FLAG_NO_WEATHER_CH        0x0002 /* 0000 0000 0000 0010 */
+
+/* Flag to exclude indoor channels */
+#define DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH       0x0004 /* 0000 0000 0000 0100 */
+
+/* Flag to exclude outdoor channels */
+#define DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH       0x0008 /* 0000 0000 0000 1000 */
+
+/* Flag to exclude dfs channels */
+#define DFS_RANDOM_CH_FLAG_NO_DFS_CH            0x0010 /* 0000 0000 0001 0000 */
+
+/* Flag to exclude all 5GHz channels */
+#define DFS_RANDOM_CH_FLAG_NO_5GHZ_CH           0x0020 /* 0000 0000 0010 0000 */
+
+/* Flag to exclude all 2.4GHz channels */
+#define DFS_RANDOM_CH_FLAG_NO_2GHZ_CH           0x0040 /* 0000 0000 0100 0000 */
+
 #endif  /* _DFS_IOCTL_H_ */

+ 0 - 5
umac/dfs/core/src/dfs_internal.h

@@ -51,11 +51,6 @@ enum DFS_DOMAIN {
 /* CAPABILITY: the device support STA DFS */
 #define IEEE80211_CEXT_STADFS 0x00000040
 
-#define IEEE80211_SELECT_NONDFS_AND_DFS 0
-#define IEEE80211_SELECT_NONDFS_ONLY    1
-#define IEEE80211_SELECT_NXT_CH_POST_RADAR_DETECT   0
-#define IEEE80211_SELECT_APRIORI_NXT_CH             1
-
 /**
  * dfs_ieee80211_chan2freq() - Convert channel to frequency value.
  * @chan: Pointer to dfs_ieee80211_channel structure.

+ 4 - 23
umac/dfs/core/src/dfs_random_chan_sel.h

@@ -75,28 +75,6 @@
 /* Max channel width */
 #define DFS_CH_WIDTH_MAX        8
 
-/* Random channel flags */
-/* Flag to exclude current operating channels */
-#define DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH       0x0001 /* 0000 0000 0000 0001 */
-
-/* Flag to exclude weather channels */
-#define DFS_RANDOM_CH_FLAG_NO_WEATHER_CH        0x0002 /* 0000 0000 0000 0010 */
-
-/* Flag to exclude indoor channels */
-#define DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH       0x0004 /* 0000 0000 0000 0100 */
-
-/* Flag to exclude outdoor channels */
-#define DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH       0x0008 /* 0000 0000 0000 1000 */
-
-/* Flag to exclude dfs channels */
-#define DFS_RANDOM_CH_FLAG_NO_DFS_CH            0x0010 /* 0000 0000 0001 0000 */
-
-/* Flag to exclude all 5GHz channels */
-#define DFS_RANDOM_CH_FLAG_NO_5GHZ_CH           0x0020 /* 0000 0000 0010 0000 */
-
-/* Flag to exclude all 2.4GHz channels */
-#define DFS_RANDOM_CH_FLAG_NO_2GHZ_CH           0x0040 /* 0000 0000 0100 0000 */
-
 /* Next 5GHz channel number */
 #define DFS_80_NUM_SUB_CHANNNEL                 4
 
@@ -124,9 +102,12 @@
 /* Bitmap mask for 40MHz higher */
 #define DFS_40MHZ_MASK_H                        0x0C
 
-/* Adjacent weather radar channel */
+/* Adjacent weather radar channel frequency */
 #define DFS_ADJACENT_WEATHER_RADAR_CHANNEL      5580
 
+/* Adjacent weather radar channel number */
+#define DFS_ADJACENT_WEATHER_RADAR_CHANNEL_NUM  116
+
 /* Max 2.4 GHz channel number */
 #define DFS_MAX_24GHZ_CHANNEL                   14
 

+ 36 - 19
umac/dfs/core/src/misc/dfs_random_chan_sel.c

@@ -415,7 +415,7 @@ static void dfs_apply_rules(struct wlan_dfs *dfs,
 	struct dfs_acs_info *acs_info)
 {
 	struct dfs_ieee80211_channel *chan;
-	uint16_t flag_no_wheather = 0;
+	uint16_t flag_no_weather = 0;
 	uint16_t flag_no_lower_5g = 0;
 	uint16_t flag_no_upper_5g = 0;
 	uint16_t flag_no_dfs_chan = 0;
@@ -424,7 +424,7 @@ static void dfs_apply_rules(struct wlan_dfs *dfs,
 	int i;
 
 	dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "flags %d", flags);
-	flag_no_wheather = (dfs_region == DFS_ETSI_REGION_VAL) ?
+	flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ?
 		flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
 
 	flag_no_lower_5g = (dfs_region == DFS_MKK_REGION_VAL) ?
@@ -447,6 +447,17 @@ static void dfs_apply_rules(struct wlan_dfs *dfs,
 			continue;
 		}
 
+		if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) {
+			/* TODO : Skip all HT20 channels in the given mode */
+			if (chan->dfs_ch_ieee ==
+					dfs->dfs_curchan->dfs_ch_ieee) {
+				dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+						"skip %d current operating channel\n",
+						chan->dfs_ch_ieee);
+				continue;
+			}
+		}
+
 		if (acs_info && (acs_info->acs_mode == 1) &&
 		    ((chan->dfs_ch_ieee < acs_info->start_ch) ||
 		    (chan->dfs_ch_ieee > acs_info->end_ch))) {
@@ -474,31 +485,17 @@ static void dfs_apply_rules(struct wlan_dfs *dfs,
 			continue;
 		}
 
-		if (flag_no_wheather) {
-			/*
-			 * We should also avoid this channel in HT40 mode as
-			 * extension channel will be on 5600.
-			 */
-			/* TODO check if reg updating chan->dfs_ch_flags for
-			 * IEEE80211_CHAN_11NA_HT40PLUS
-			 */
+		if (flag_no_weather) {
 			if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) {
 				dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
 						"skip weather channel=%d",
 						chan->dfs_ch_ieee);
 				continue;
-			} else if (DFS_ADJACENT_WEATHER_RADAR_CHANNEL ==
-				   chan->dfs_ch_freq && (chan->dfs_ch_flags &
-				   IEEE80211_CHAN_11NA_HT40PLUS)) {
-				dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
-						"skip weather adjacent ch=%d",
-					    chan->dfs_ch_ieee);
-				continue;
 			}
 		}
 
 		if (flag_no_lower_5g &&
-		    DFS_IS_CHAN_JAPAN_INDOOR(chan->dfs_ch_freq)) {
+		    DFS_IS_CHAN_JAPAN_INDOOR(chan->dfs_ch_ieee)) {
 			dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
 					"skip indoor channel=%d",
 					chan->dfs_ch_ieee);
@@ -506,7 +503,7 @@ static void dfs_apply_rules(struct wlan_dfs *dfs,
 		}
 
 		if (flag_no_upper_5g &&
-		    DFS_IS_CHAN_JAPAN_OUTDOOR(chan->dfs_ch_freq)) {
+		    DFS_IS_CHAN_JAPAN_OUTDOOR(chan->dfs_ch_ieee)) {
 			dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "skip outdoor channel=%d",
 				    chan->dfs_ch_ieee);
 			continue;
@@ -542,6 +539,7 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs,
 	uint8_t target_ch = 0;
 	uint8_t *random_chan_list = NULL;
 	uint32_t random_chan_cnt = 0;
+	uint16_t flag_no_weather = 0;
 
 	if (!ch_list || !ch_cnt) {
 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
@@ -569,6 +567,9 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs,
 	dfs_apply_rules(dfs, flags, random_chan_list, &random_chan_cnt,
 		    ch_list, ch_cnt, dfs_region, acs_info);
 
+	flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ?
+		flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
+
 	do {
 		if (*ch_wd == DFS_CH_WIDTH_20MHZ) {
 			target_ch = dfs_get_rand_from_lst(
@@ -580,6 +581,22 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs,
 				&cur_chan->dfs_ch_vhtop_ch_freq_seg2,
 				random_chan_list,
 				random_chan_cnt);
+
+		/*
+		 * When flag_no_weather is set, avoid usage of Adjacent
+		 * weather radar channel in HT40 mode as extension channel
+		 * will be on 5600.
+		 */
+		if (flag_no_weather &&
+				(target_ch ==
+				 DFS_ADJACENT_WEATHER_RADAR_CHANNEL_NUM) &&
+				(*ch_wd == DFS_CH_WIDTH_40MHZ)) {
+			dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+					"skip weather adjacent ch=%d\n",
+					target_ch);
+			continue;
+		}
+
 		if (target_ch)
 			break;
 	} while (true);

+ 105 - 3
umac/dfs/dispatcher/src/wlan_dfs_utils_api.c

@@ -24,6 +24,7 @@
 #include "wlan_dfs_utils_api.h"
 #include "../../core/src/dfs.h"
 #include "../../core/src/dfs_zero_cac.h"
+#include <wlan_reg_services_api.h>
 #include "../../core/src/dfs_random_chan_sel.h"
 #ifdef QCA_DFS_USE_POLICY_MANAGER
 #include "wlan_policy_mgr_api.h"
@@ -421,6 +422,13 @@ static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev,
 	return;
 }
 
+/**
+ * utils_dfs_get_chan_list() - Get channel list from regdb based on current
+ *                             operating channel.
+ * @pdev: Pointer to DFS pdev object.
+ * @chan_list: Pointer to current channel list
+ * @num_chan: number of channels in the current channel list.
+ */
 #ifndef QCA_DFS_USE_POLICY_MANAGER
 static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 	struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan)
@@ -436,8 +444,11 @@ static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 
 	cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
 			sizeof(struct regulatory_channel));
-	if (cur_chan_list == NULL)
+	if (!cur_chan_list) {
 		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "fail to alloc");
+		*num_chan = 0;
+		return;
+	}
 
 	if (wlan_reg_get_current_chan_list(
 			pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
@@ -450,9 +461,12 @@ static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 	for (i = 0; i < NUM_CHANNELS; i++) {
 		state = cur_chan_list[i].state;
 		if (state == CHANNEL_STATE_DFS ||
-		    state == CHANNEL_STATE_ENABLE) {
+				state == CHANNEL_STATE_ENABLE) {
 			chan_list[j].dfs_ch_ieee = cur_chan_list[i].chan_num;
 			chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq;
+			if (state == CHANNEL_STATE_DFS)
+				chan_list[j].dfs_ch_flagext =
+					IEEE80211_CHAN_DFS;
 			j++;
 		}
 	}
@@ -461,7 +475,82 @@ static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 
 	return;
 }
+
+/**
+ * utils_dfs_get_channel_list() - Get channel list from regdb component based
+ * on current channel list.
+ * @pdev: Pointer to pdev structure.
+ * @chan_list: Pointer to regdb channel list.
+ * @num_chan: number of channels.
+ *
+ * Get regdb channel list based on dfs current channel.
+ * ex: When  AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels
+ * so that the random channel function does not select either 2.4GHz or 4.9GHz
+ * channel.
+ */
+static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
+	struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan)
+{
+	struct dfs_ieee80211_channel *tmp_chan_list = NULL;
+	struct wlan_dfs *dfs;
+	bool is_curchan_5g;
+	bool is_curchan_24g;
+	bool is_curchan_49g;
+	uint32_t chan_num;
+	uint32_t center_freq;
+	uint16_t flagext;
+	int i, j = 0;
+
+	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
+	if (!dfs) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
+		return;
+	}
+
+	tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list));
+	if (!tmp_chan_list) {
+		dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "mem alloc failed");
+		return;
+	}
+
+	utils_dfs_get_chan_list(pdev, tmp_chan_list, num_chan);
+
+	chan_num = dfs->dfs_curchan->dfs_ch_ieee;
+	center_freq = dfs->dfs_curchan->dfs_ch_freq;
+	is_curchan_5g = WLAN_REG_IS_5GHZ_CH(chan_num);
+	is_curchan_24g = WLAN_REG_IS_24GHZ_CH(chan_num);
+	is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq);
+
+	for (i = 0; i < *num_chan; i++) {
+		chan_num = tmp_chan_list[i].dfs_ch_ieee;
+		center_freq = tmp_chan_list[i].dfs_ch_freq;
+		flagext = tmp_chan_list[i].dfs_ch_flagext;
+
+		if ((is_curchan_5g) && WLAN_REG_IS_5GHZ_CH(chan_num)) {
+			chan_list[j].dfs_ch_ieee = chan_num;
+			chan_list[j].dfs_ch_freq = center_freq;
+			chan_list[j].dfs_ch_flagext = flagext;
+			j++;
+		} else if ((is_curchan_24g) &&
+				WLAN_REG_IS_24GHZ_CH(chan_num)) {
+			chan_list[j].dfs_ch_ieee = chan_num;
+			chan_list[j].dfs_ch_freq = center_freq;
+			j++;
+		} else if ((is_curchan_49g) &&
+				WLAN_REG_IS_49GHZ_FREQ(center_freq)) {
+			chan_list[j].dfs_ch_ieee = chan_num;
+			chan_list[j].dfs_ch_freq = center_freq;
+			j++;
+		}
+	}
+
+	*num_chan = j;
+
+	qdf_mem_free(tmp_chan_list);
+}
+
 #else
+
 static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 	struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan)
 {
@@ -507,6 +596,19 @@ static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
 	*num_chan = i;
 	dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i);
 }
+
+/**
+ * utils_dfs_get_channel_list() - Wrapper function to get channel list from
+ * regdb component.
+ * @pdev: Pointer to pdev structure.
+ * @chan_list: Pointer to regdb channel list.
+ * @num_chan: number of channels.
+ */
+static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
+	struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan)
+{
+	utils_dfs_get_chan_list(pdev, chan_list, num_chan);
+}
 #endif
 
 QDF_STATUS utils_dfs_get_random_channel(
@@ -545,7 +647,7 @@ QDF_STATUS utils_dfs_get_random_channel(
 		goto random_chan_error;
 	}
 
-	utils_dfs_get_chan_list(pdev, chan_list, &num_chan);
+	utils_dfs_get_channel_list(pdev, chan_list, &num_chan);
 	if (!num_chan) {
 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "zero channels");
 		goto random_chan_error;