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
Cette révision appartient à :
Priyadarshnee Srinivasan
2023-03-23 15:16:13 +05:30
révisé par Madan Koyyalamudi
Parent d33baafbe5
révision 30e5729efd
2 fichiers modifiés avec 60 ajouts et 27 suppressions

Voir le fichier

@@ -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++;
}

Voir le fichier

@@ -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,