浏览代码

qcacmn: Fill only supported opclass in the AFC request buffer

In case of a split-phy 6 GHz radio, there are 6 GHz opclasses and cfis
that do not intersect with the chip range for a given pdev.
The current algorithm appends such opclasses with "num_cfis as 0" to
the AFC request buffer and the buffer with empty cfis are
sent to the AFC server.
This change ensures that the chip unsupported opclasses/cfis are not sent
to the AFC server.

Also, if the reg rule frequency range is not supported by the chip range,
reg_intersect_ranges() is expected to set the out_range as
{low_freq = 0,high_freq = 0}. However, it only sets the low_freq to 0.
Since high_freq is a non-zero value, the chip un-supported range is
considered as a valid range with frequency_low as 0.
This causes the following error from the AFC server:
"error": "The frequency range indicated in the Available Spectrum
Inquiry Request is at least partially outside of the frequency band
under the management of the AFC System (e.g. 5.925-6.425 GHz and
					6.525-6.875 GHz bands in US).

To fix this issue, assign high_freq also to 0 if the
reg rule frequency range is not supported by the chip range.

CRs-Fixed: 3442719
Change-Id: I5504376ac31203045b32e23f54a9ab6a41e63a3f
Priyadarshnee Srinivasan 2 年之前
父节点
当前提交
30e5729efd
共有 2 个文件被更改,包括 60 次插入27 次删除
  1. 59 26
      umac/regulatory/core/src/reg_opclass.c
  2. 1 1
      umac/regulatory/core/src/reg_services_common.c

+ 59 - 26
umac/regulatory/core/src/reg_opclass.c

@@ -696,6 +696,40 @@ static uint8_t reg_dmn_get_num_6g_opclasses(struct wlan_objmgr_pdev *pdev)
 	return count;
 }
 
+/**
+ * reg_dmn_fill_cfis() - Fill the cfis for the given
+ * opclass and frequency range.
+ * @op_class_tbl: Pointer to struct reg_dmn_op_class_map_t
+ * @p_lst: Pointer to struct c_freq_lst
+ * @p_frange_lst: Pointer to struct wlan_afc_frange_list
+ * @dst: Pointer to dst buffer
+ *
+ * Return: Number of valid cfis
+ */
+static uint8_t
+reg_dmn_fill_cfis(const struct reg_dmn_op_class_map_t *op_class_tbl,
+		  const struct c_freq_lst *p_lst,
+		  struct wlan_afc_frange_list *p_frange_lst,
+		  uint8_t *dst)
+{
+	uint8_t j;
+	uint8_t cfi_idx = 0;
+
+	for (j = 0; j < p_lst->num_cfis; j++) {
+		uint8_t cfi;
+		qdf_freq_t cfi_freq;
+		qdf_freq_t start_freq = op_class_tbl->start_freq;
+		uint16_t bw = op_class_tbl->chan_spacing;
+
+		cfi = p_lst->p_cfis_arr[j];
+		cfi_freq = start_freq + FREQ_TO_CHAN_SCALE * cfi;
+
+		if (reg_is_cfi_freq_in_ranges(cfi_freq, bw, p_frange_lst))
+			dst[cfi_idx++] = cfi;
+	}
+	return cfi_idx;
+}
+
 /**
  * reg_dmn_fill_6g_opcls_chan_lists() - Copy the channel lists for 6g opclasses
  * to the output argument list ('channel_lists')
@@ -723,28 +757,19 @@ static void reg_dmn_fill_6g_opcls_chan_lists(struct wlan_objmgr_pdev *pdev,
 		p_lst = op_class_tbl->p_cfi_lst_obj;
 		if (p_lst &&
 		    reg_is_6ghz_op_class(pdev, op_class_tbl->op_class)) {
-			uint8_t j;
-			uint8_t cfi_idx = 0;
 			uint8_t *dst;
+			uint8_t num_valid_cfi = 0;
 
 			dst = channel_lists[i];
-			for (j = 0; j < p_lst->num_cfis; j++) {
-				uint8_t cfi;
-				qdf_freq_t cfi_freq;
-				qdf_freq_t start_freq = op_class_tbl->start_freq;
-				uint16_t bw = op_class_tbl->chan_spacing;
-
-				cfi = p_lst->p_cfis_arr[j];
-				cfi_freq = start_freq +
-					FREQ_TO_CHAN_SCALE * cfi;
-
-				if (reg_is_cfi_freq_in_ranges(cfi_freq,
-							      bw,
-							      p_frange_lst)) {
-					dst[cfi_idx++] = cfi;
-				}
+			if (!dst) {
+				reg_debug("dest list empty\n");
+				return;
 			}
-			i++;
+			num_valid_cfi = reg_dmn_fill_cfis(op_class_tbl, p_lst,
+							  p_frange_lst, dst);
+			if (num_valid_cfi)
+				i++;
+
 		}
 		op_class_tbl++;
 	}
@@ -770,17 +795,18 @@ QDF_STATUS reg_dmn_get_6g_opclasses_and_channels(struct wlan_objmgr_pdev *pdev,
 	uint8_t *p_total_alloc1;
 	uint8_t *p_total_alloc2;
 	uint8_t *p_temp_alloc;
+	uint8_t n_tot_opclss;
 
 	*opclass_lst = NULL;
 	*chansize_lst =  NULL;
 	*channel_lists = NULL;
+	*num_opclasses = 0;
 
 	op_class_tbl = global_op_class;
-
-	*num_opclasses = reg_dmn_get_num_6g_opclasses(pdev);
-	opcls_lst_size = *num_opclasses * sizeof(uint8_t);
-	chansize_lst_size = *num_opclasses * sizeof(uint8_t);
-	arr_chan_lists_size = *num_opclasses * sizeof(uint8_t *);
+	n_tot_opclss = reg_dmn_get_num_6g_opclasses(pdev);
+	opcls_lst_size = n_tot_opclss * sizeof(uint8_t);
+	chansize_lst_size = n_tot_opclss * sizeof(uint8_t);
+	arr_chan_lists_size = n_tot_opclss * sizeof(uint8_t *);
 
 	total_alloc_size = 0;
 	total_alloc_size += opcls_lst_size
@@ -819,7 +845,6 @@ QDF_STATUS reg_dmn_get_6g_opclasses_and_channels(struct wlan_objmgr_pdev *pdev,
 			uint8_t n_supp_cfis = 0;
 			uint8_t j;
 
-			l_opcls_lst[count] = op_class_tbl->op_class;
 			for (j = 0; j < p_lst->num_cfis; j++) {
 				uint8_t cfi;
 				qdf_freq_t cfi_freq;
@@ -835,8 +860,16 @@ QDF_STATUS reg_dmn_get_6g_opclasses_and_channels(struct wlan_objmgr_pdev *pdev,
 					n_supp_cfis++;
 				}
 			}
-			l_chansize_lst[count] = n_supp_cfis;
-			count++;
+			/* Fill opclass number, num cfis and increment
+			 * num_opclasses only if the cfi of the opclass
+			 * is within the frequency range of interest.
+			 */
+			if (n_supp_cfis) {
+				l_chansize_lst[count] = n_supp_cfis;
+				l_opcls_lst[count] = op_class_tbl->op_class;
+				(*num_opclasses)++;
+				count++;
+			}
 		}
 		op_class_tbl++;
 	}

+ 1 - 1
umac/regulatory/core/src/reg_services_common.c

@@ -6905,7 +6905,7 @@ reg_intersect_ranges(struct freq_range *first_range,
 
 	if (l_freq > r_freq) {
 		l_freq = 0;
-		l_freq = 0;
+		r_freq = 0;
 
 		reg_debug("Ranges do not overlap first= [%u, %u], second = [%u, %u]",
 			  first_range->left,