浏览代码

qcacmn: DFS random channel selection for 11BE

Enable the wmi_service to fetch the radar found cfreq from
wmi_service_radar_found_chan_freq_eq_center_freq.

Add changes in DFS random channel selection algorithm
(1) To find a channel of input width 320MHZ. Since 320MHZ in 5G
is 240MHZ (320 - 80 punctured), there are 12 valid 20MHZ subchannels
possible in 240MHZ. Validate the continuity of 240MHZ channel before
declaring the channel to be found.
(2) To find a fallback channel for the input channel
width of CH_WIDTH_320MHZ. The fallback channel of 320MHHZ is
160MHZ.

CRs-Fixed: 3149475
Change-Id: I03cac7f090de20efd912402b5e4df543b47aafed
Priyadarshnee Srinivasan 3 年之前
父节点
当前提交
4f3cbf6b28
共有 3 个文件被更改,包括 116 次插入42 次删除
  1. 3 8
      target_if/dfs/src/target_if_dfs.c
  2. 6 3
      umac/dfs/core/src/dfs_random_chan_sel.h
  3. 107 31
      umac/dfs/core/src/misc/dfs_random_chan_sel.c

+ 3 - 8
target_if/dfs/src/target_if_dfs.c

@@ -232,14 +232,9 @@ target_if_dfs_is_radar_found_chan_freq_eq_center_freq(
 		target_if_err("null wmi_handle");
 		target_if_err("null wmi_handle");
 		return false;
 		return false;
 	}
 	}
-
-	/*
-	 * Uncomment the following service as soon as it is ready.
-	 *
-	 * return wmi_service_enabled(wmi_handle,
-	 * wmi_is_radar_found_chan_freq_eq_center_freq);
-	 */
-	return false;
+	return wmi_service_enabled
+		(wmi_handle,
+		 wmi_service_radar_found_chan_freq_eq_center_freq);
 }
 }
 #else
 #else
 static bool
 static bool

+ 6 - 3
umac/dfs/core/src/dfs_random_chan_sel.h

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * any purpose with or without fee is hereby granted, provided that the
@@ -41,11 +42,12 @@
 /* 10MHz channel width */
 /* 10MHz channel width */
 #define DFS_CH_WIDTH_10MHZ      6
 #define DFS_CH_WIDTH_10MHZ      6
 
 
+#define DFS_CH_WIDTH_320MHZ     7
 /* Invalid channel width */
 /* Invalid channel width */
-#define DFS_CH_WIDTH_INVALID    7
+#define DFS_CH_WIDTH_INVALID    8
 
 
 /* Max channel width */
 /* Max channel width */
-#define DFS_CH_WIDTH_MAX        8
+#define DFS_CH_WIDTH_MAX        9
 
 
 /* Next 5GHz channel number */
 /* Next 5GHz channel number */
 #define DFS_80_NUM_SUB_CHANNEL                 4
 #define DFS_80_NUM_SUB_CHANNEL                 4
@@ -60,8 +62,9 @@
 #define DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET       20
 #define DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET       20
 
 
 /* Number of 20MHz channels in bitmap */
 /* Number of 20MHz channels in bitmap */
-#define DFS_MAX_20M_SUB_CH                      8
+#define DFS_MAX_NUM_160_SUBCHAN                 8
 
 
+#define DFS_MAX_NUM_240_SUBCHAN                 12
 /* Frequency difference between 80+80 MHz */
 /* Frequency difference between 80+80 MHz */
 #define DFS_80P80M_FREQ_DIFF                    40
 #define DFS_80P80M_FREQ_DIFF                    40
 
 

+ 107 - 31
umac/dfs/core/src/misc/dfs_random_chan_sel.c

@@ -957,10 +957,11 @@ dfs_populate_40mhz_available_channel_for_freq(struct wlan_dfs *dfs,
 static uint8_t
 static uint8_t
 dfs_populate_available_channel_for_freq(struct wlan_dfs *dfs,
 dfs_populate_available_channel_for_freq(struct wlan_dfs *dfs,
 					struct chan_bonding_bitmap *bitmap,
 					struct chan_bonding_bitmap *bitmap,
-					uint8_t chan_width,
+					uint16_t chan_width,
 					uint16_t *freq_list)
 					uint16_t *freq_list)
 {
 {
 	switch (chan_width) {
 	switch (chan_width) {
+	case DFS_CH_WIDTH_320MHZ:
 	case DFS_CH_WIDTH_160MHZ:
 	case DFS_CH_WIDTH_160MHZ:
 	case DFS_CH_WIDTH_80P80MHZ:
 	case DFS_CH_WIDTH_80P80MHZ:
 	case DFS_CH_WIDTH_80MHZ:
 	case DFS_CH_WIDTH_80MHZ:
@@ -1087,6 +1088,63 @@ static inline void dfs_assign_6g_channels(struct  chan_bonding_bitmap *ch_map)
 }
 }
 #endif
 #endif
 
 
+/**
+ * dfs_find_num_sub_channels_for_chwidth_320_160() - Find the max number
+ * of sub channels for the given channel width (320/160)
+ * @chan_width: Channel width
+ *
+ * Return - Number of sub-channels
+ */
+static uint8_t
+dfs_find_num_sub_channels_for_chwidth_320_160(uint16_t chan_width)
+{
+	if (chan_width == DFS_CH_WIDTH_160MHZ)
+		return DFS_MAX_NUM_160_SUBCHAN;
+	else if (chan_width == DFS_CH_WIDTH_320MHZ)
+		return DFS_MAX_NUM_240_SUBCHAN;
+
+	return 0;
+}
+
+/**
+ * dfs_find_next_chan_start_freq_for_320_160() - Find the next 160/320 channel's
+ * start freq based on the available channel list. Validate the
+ * continuity of the sub channels of 160/320M BW, if they are contiguous
+ * declare channel to be found. Return the start_freq of the channel band found.
+ * @chan_count: Total number of available channels.
+ * @freq_list: Available list of frequency
+ * @chan_width: Target channel width
+ * @chan_found: Bool to indicate if channel is found
+ *
+ * Return: Next chan's start freq
+ */
+
+static qdf_freq_t
+dfs_find_next_chan_start_freq_for_320_160(uint8_t chan_count,
+					  uint16_t *freq_list,
+					  uint16_t chan_width, bool *chan_found)
+{
+	uint8_t i;
+	uint8_t count = 0;
+	qdf_freq_t next_chan_start_freq = 0;
+	uint8_t num_sub_chans =
+		dfs_find_num_sub_channels_for_chwidth_320_160(chan_width);
+
+	for (i = 1; i < chan_count; i++) {
+		if ((freq_list[i] - freq_list[i - 1]) ==
+		    DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET)
+			count++;
+		else
+			count = 0;
+		if (count == num_sub_chans - 1) {
+			*chan_found = true;
+			next_chan_start_freq = freq_list[i - count];
+			break;
+		}
+	}
+	return next_chan_start_freq;
+}
+
 /**
 /**
  * dfs_find_ch_with_fallback_for_freq()- find random channel
  * dfs_find_ch_with_fallback_for_freq()- find random channel
  * @dfs: Pointer to DFS structure.
  * @dfs: Pointer to DFS structure.
@@ -1102,7 +1160,7 @@ static inline void dfs_assign_6g_channels(struct  chan_bonding_bitmap *ch_map)
  */
  */
 #ifdef CONFIG_CHAN_FREQ_API
 #ifdef CONFIG_CHAN_FREQ_API
 static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs,
 static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs,
-						   uint8_t *chan_wd,
+						   uint16_t *chan_wd,
 						   qdf_freq_t *center_freq_seg1,
 						   qdf_freq_t *center_freq_seg1,
 						   uint16_t *freq_lst,
 						   uint16_t *freq_lst,
 						   uint32_t num_chan)
 						   uint32_t num_chan)
@@ -1110,9 +1168,9 @@ static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs,
 	bool flag = false;
 	bool flag = false;
 	uint32_t rand_byte = 0;
 	uint32_t rand_byte = 0;
 	struct  chan_bonding_bitmap ch_map = { { {0} } };
 	struct  chan_bonding_bitmap ch_map = { { {0} } };
-	uint8_t count = 0, i, index = 0, final_cnt = 0;
+	uint8_t i, index = 0, final_cnt = 0;
 	uint16_t target_channel = 0;
 	uint16_t target_channel = 0;
-	uint16_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0;
+	uint16_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_start_ch;
 	uint16_t final_lst[NUM_CHANNELS] = {0};
 	uint16_t final_lst[NUM_CHANNELS] = {0};
 
 
 	/* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */
 	/* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */
@@ -1136,9 +1194,10 @@ static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs,
 	final_cnt = dfs_populate_available_channel_for_freq(dfs, &ch_map,
 	final_cnt = dfs_populate_available_channel_for_freq(dfs, &ch_map,
 							    *chan_wd, final_lst);
 							    *chan_wd, final_lst);
 
 
-	/* If no valid ch bonding found, fallback */
+	/* If no valid 80mhz bonded chan found, fallback */
 	if (final_cnt == 0) {
 	if (final_cnt == 0) {
-		if ((*chan_wd == DFS_CH_WIDTH_160MHZ) ||
+		if ((*chan_wd == DFS_CH_WIDTH_320MHZ) ||
+		    (*chan_wd == DFS_CH_WIDTH_160MHZ) ||
 		    (*chan_wd == DFS_CH_WIDTH_80P80MHZ) ||
 		    (*chan_wd == DFS_CH_WIDTH_80P80MHZ) ||
 		    (*chan_wd == DFS_CH_WIDTH_80MHZ)) {
 		    (*chan_wd == DFS_CH_WIDTH_80MHZ)) {
 			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
 			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
@@ -1155,47 +1214,64 @@ static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs,
 	/* ch count should be > 8 to switch new channel in 160Mhz band */
 	/* ch count should be > 8 to switch new channel in 160Mhz band */
 	if (((*chan_wd == DFS_CH_WIDTH_160MHZ) ||
 	if (((*chan_wd == DFS_CH_WIDTH_160MHZ) ||
 	     (*chan_wd == DFS_CH_WIDTH_80P80MHZ)) &&
 	     (*chan_wd == DFS_CH_WIDTH_80P80MHZ)) &&
-	     (final_cnt < DFS_MAX_20M_SUB_CH)) {
+	     (final_cnt < DFS_MAX_NUM_160_SUBCHAN)) {
 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
 			 "from [%d] to 80Mhz", *chan_wd);
 			 "from [%d] to 80Mhz", *chan_wd);
 		*chan_wd = DFS_CH_WIDTH_80MHZ;
 		*chan_wd = DFS_CH_WIDTH_80MHZ;
 		return 0;
 		return 0;
 	}
 	}
 
 
-	if (*chan_wd == DFS_CH_WIDTH_160MHZ) {
+	/* ch count should be 12 to switch new 320 channel band (240MHZ) */
+	if (*chan_wd == DFS_CH_WIDTH_320MHZ) {
+		if (final_cnt < DFS_MAX_NUM_240_SUBCHAN) {
+			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
+				 "from [%d] to 160Mhz", *chan_wd);
+			*chan_wd = DFS_CH_WIDTH_160MHZ;
+			return 0;
+		}
+	}
+
+	if (*chan_wd == DFS_CH_WIDTH_320MHZ ||
+	    *chan_wd == DFS_CH_WIDTH_160MHZ) {
 		/*
 		/*
 		 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128
 		 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128
 		 * and all the channels in these blocks are continuous
 		 * and all the channels in these blocks are continuous
 		 * and separated by 4Mhz.
 		 * and separated by 4Mhz.
+		 * Only 1 block of 240 channel is
+		 * available from 100 - 140 comprising of 12 sub 20 channels.
+		 * These are continuous and separated by 20MHZ in
+		 * frequency spectrum.
 		 */
 		 */
-		for (i = 1; ((i < final_cnt)); i++) {
-			if ((final_lst[i] - final_lst[i - 1]) ==
-			     DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET)
-				count++;
-			else
-				count = 0;
-			if (count == DFS_MAX_20M_SUB_CH - 1) {
-				flag = true;
-				new_160_start_ch = final_lst[i - count];
-				break;
-			}
-		}
+		new_start_ch =
+		    dfs_find_next_chan_start_freq_for_320_160(final_cnt,
+							      final_lst,
+							      *chan_wd,
+							      &flag);
 	} else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) {
 	} else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) {
 		flag = true;
 		flag = true;
 	}
 	}
 
 
-	if ((flag == false) && (*chan_wd > DFS_CH_WIDTH_80MHZ)) {
-		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
-			 "from [%d] to 80Mhz", *chan_wd);
-		*chan_wd = DFS_CH_WIDTH_80MHZ;
-		return 0;
+	if (!flag) {
+		if (*chan_wd == DFS_CH_WIDTH_320MHZ) {
+			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
+				 "from [%d] to 160Mhz", *chan_wd);
+			*chan_wd = DFS_CH_WIDTH_160MHZ;
+			return 0;
+		} else if (*chan_wd == DFS_CH_WIDTH_160MHZ) {
+			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
+				 "from [%d] to 80Mhz", *chan_wd);
+			*chan_wd = DFS_CH_WIDTH_80MHZ;
+			return 0;
+		}
 	}
 	}
 
 
-	if (*chan_wd == DFS_CH_WIDTH_160MHZ) {
+	if (*chan_wd == DFS_CH_WIDTH_320MHZ ||
+	    *chan_wd == DFS_CH_WIDTH_160MHZ) {
 		get_random_bytes((uint8_t *)&rand_byte, 1);
 		get_random_bytes((uint8_t *)&rand_byte, 1);
 		rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks())
 		rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks())
-			% DFS_MAX_20M_SUB_CH;
-		target_channel = new_160_start_ch + (rand_byte *
+			% dfs_find_num_sub_channels_for_chwidth_320_160
+			(*chan_wd);
+		target_channel = new_start_ch + (rand_byte *
 				DFS_80_NUM_SUB_CHANNEL_FREQ);
 				DFS_80_NUM_SUB_CHANNEL_FREQ);
 	} else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) {
 	} else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) {
 		get_random_bytes((uint8_t *)&rand_byte, 1);
 		get_random_bytes((uint8_t *)&rand_byte, 1);
@@ -1221,7 +1297,7 @@ static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs,
 			}
 			}
 		}
 		}
 
 
-		if (!sec_seg_ch && (final_cnt == DFS_MAX_20M_SUB_CH))
+		if (!sec_seg_ch && (final_cnt == DFS_MAX_NUM_160_SUBCHAN))
 			*chan_wd = DFS_CH_WIDTH_160MHZ;
 			*chan_wd = DFS_CH_WIDTH_160MHZ;
 		else if (!sec_seg_ch)
 		else if (!sec_seg_ch)
 			*chan_wd = DFS_CH_WIDTH_80MHZ;
 			*chan_wd = DFS_CH_WIDTH_80MHZ;
@@ -1478,7 +1554,7 @@ uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs,
 	uint16_t flag_no_weather = 0;
 	uint16_t flag_no_weather = 0;
 	uint16_t *leakage_adjusted_lst;
 	uint16_t *leakage_adjusted_lst;
 	uint16_t final_lst[NUM_CHANNELS] = {0};
 	uint16_t final_lst[NUM_CHANNELS] = {0};
-	uint8_t *chan_wd = (uint8_t *)&chan_params->ch_width;
+	uint16_t *chan_wd = (uint16_t *)&chan_params->ch_width;
 	bool flag_no_spur_leakage_adj_chans = false;
 	bool flag_no_spur_leakage_adj_chans = false;
 
 
 	if (!chan_list || !chan_cnt) {
 	if (!chan_list || !chan_cnt) {
@@ -1488,7 +1564,7 @@ uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs,
 		return 0;
 		return 0;
 	}
 	}
 
 
-	if (*chan_wd < DFS_CH_WIDTH_20MHZ || *chan_wd > DFS_CH_WIDTH_80P80MHZ) {
+	if (*chan_wd < DFS_CH_WIDTH_20MHZ || *chan_wd > DFS_CH_WIDTH_320MHZ) {
 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
 			 "Invalid chan_wd %d", *chan_wd);
 			 "Invalid chan_wd %d", *chan_wd);
 		return 0;
 		return 0;