qcacmn: Fix incorrect 6g supported channels reported for opclass 133 & 134
API reg_get_channels_from_opclassmap populates channels from opclass map to reg_ap_cap as supported and non-supported channels. But for 6g opclass 133 and 134, non-supported channels were also getting reported as supported channels. This was due to an error in the logic of reg_get_channels_from_opclassmap API for opclass 133 and 134. The 20Mhz channels towards the end of the channel list in the op_class_tbl were causing the issue. To address this issue, add a logic to get the supported and non-supported channels from the cfi list object of op_class_tbl for 6GHz in the reg_get_channels_from_opclassmap API. Also remove the 40MHz centre channel calculation condition for 6GHz in reg_get_chan_or_chan_center API as it is being handled in the new API. CRs-Fixed: 3133022 Change-Id: If6ea18f79786c8549a1c75c557adffa178dd5c71
This commit is contained in:

committed by
Madan Koyyalamudi

vanhempi
055dfbe881
commit
c3bb3fb37a
@@ -1474,12 +1474,6 @@ static uint8_t reg_get_chan_or_chan_center(const struct
|
||||
idx,
|
||||
NUM_20_MHZ_CHAN_IN_160_MHZ_CHAN,
|
||||
¢er_chan);
|
||||
} else if ((op_class_tbl->op_class == BW_40_MHZ) &&
|
||||
(op_class_tbl->op_class == OPCLS_132)) {
|
||||
reg_get_channel_cen(op_class_tbl,
|
||||
idx,
|
||||
NUM_20_MHZ_CHAN_IN_40_MHZ_CHAN,
|
||||
¢er_chan);
|
||||
} else {
|
||||
center_chan = op_class_tbl->channels[*idx];
|
||||
*idx = *idx + 1;
|
||||
@@ -1488,6 +1482,200 @@ static uint8_t reg_get_chan_or_chan_center(const struct
|
||||
return center_chan;
|
||||
}
|
||||
|
||||
static inline qdf_freq_t reg_get_nearest_primary_freq(uint16_t bw,
|
||||
qdf_freq_t cfi_freq,
|
||||
uint8_t op_class)
|
||||
{
|
||||
qdf_freq_t pri_freq;
|
||||
|
||||
if (bw <= BW_40_MHZ && op_class != OPCLS_132) {
|
||||
pri_freq = cfi_freq;
|
||||
} else {
|
||||
if (cfi_freq >= BW_10_MHZ)
|
||||
pri_freq = cfi_freq - BW_10_MHZ;
|
||||
else
|
||||
pri_freq = 0;
|
||||
}
|
||||
|
||||
return pri_freq;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE
|
||||
/**
|
||||
* reg_is_chan_supported()- Check if given channel is supported based on its
|
||||
* freq provided
|
||||
* @pdev: Pointer to pdev
|
||||
* @pri_freq: Primary frequency of the input channel
|
||||
* @cfi_freq: cfi frequency of the input channel
|
||||
* @ch_width: Input channel width
|
||||
*
|
||||
* Return: True if the channel is supported, else false
|
||||
*/
|
||||
static bool reg_is_chan_supported(struct wlan_objmgr_pdev *pdev,
|
||||
qdf_freq_t pri_freq,
|
||||
qdf_freq_t cfi_freq,
|
||||
enum phy_ch_width ch_width)
|
||||
{
|
||||
struct reg_channel_list chan_list;
|
||||
qdf_freq_t center_320;
|
||||
struct ch_params ch_params;
|
||||
|
||||
center_320 = (ch_width == CH_WIDTH_320MHZ) ? cfi_freq : 0;
|
||||
reg_fill_channel_list(pdev,
|
||||
pri_freq,
|
||||
0,
|
||||
ch_width,
|
||||
center_320,
|
||||
&chan_list);
|
||||
ch_params = chan_list.chan_param[0];
|
||||
|
||||
if (ch_params.ch_width == ch_width)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
static bool reg_is_chan_supported(struct wlan_objmgr_pdev *pdev,
|
||||
qdf_freq_t pri_freq,
|
||||
qdf_freq_t cfi_freq,
|
||||
enum phy_ch_width ch_width)
|
||||
{
|
||||
struct ch_params ch_params;
|
||||
|
||||
ch_params.ch_width = ch_width;
|
||||
reg_set_channel_params_for_freq(pdev, pri_freq, 0, &ch_params);
|
||||
if (ch_params.ch_width == ch_width)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* reg_is_cfi_supported()- Check if given cfi is supported
|
||||
* @pdev: Pointer to pdev
|
||||
* @cfi_freq: cfi frequency
|
||||
* @bw: bandwidth
|
||||
*
|
||||
* Return: True if the cfi is supported, else false
|
||||
*/
|
||||
static bool reg_is_cfi_supported(struct wlan_objmgr_pdev *pdev,
|
||||
qdf_freq_t cfi_freq,
|
||||
uint16_t bw,
|
||||
uint8_t op_class)
|
||||
{
|
||||
enum phy_ch_width ch_width;
|
||||
qdf_freq_t pri_freq;
|
||||
bool is_cfi_supported;
|
||||
|
||||
ch_width = reg_find_chwidth_from_bw(bw);
|
||||
pri_freq = reg_get_nearest_primary_freq(bw, cfi_freq, op_class);
|
||||
is_cfi_supported = reg_is_chan_supported(pdev,
|
||||
pri_freq,
|
||||
cfi_freq,
|
||||
ch_width);
|
||||
|
||||
return is_cfi_supported;
|
||||
}
|
||||
|
||||
/**
|
||||
* reg_get_cfis_from_opclassmap_for_6g()- Get channels from the opclass map
|
||||
* for 6GHz
|
||||
* @pdev: Pointer to pdev
|
||||
* @cap: Pointer to regdmn_ap_cap_opclass_t
|
||||
* @op_class_tbl: Pointer to op_class_tbl
|
||||
*
|
||||
* Populate channels from opclass map to regdmn_ap_cap_opclass_t as supported
|
||||
* and non-supported channels for 6Ghz.
|
||||
*
|
||||
* Return: void.
|
||||
*/
|
||||
static void reg_get_cfis_from_opclassmap_for_6g(
|
||||
struct wlan_objmgr_pdev *pdev,
|
||||
struct regdmn_ap_cap_opclass_t *cap,
|
||||
const struct reg_dmn_op_class_map_t *op_class_tbl)
|
||||
{
|
||||
uint8_t n_sup_chans = 0, n_unsup_chans = 0, j;
|
||||
const struct c_freq_lst *p_cfi_lst = op_class_tbl->p_cfi_lst_obj;
|
||||
qdf_freq_t cfi_freq;
|
||||
qdf_freq_t start_freq = op_class_tbl->start_freq;
|
||||
uint16_t bw = op_class_tbl->chan_spacing;
|
||||
|
||||
for (j = 0; j < p_cfi_lst->num_cfis; j++) {
|
||||
uint8_t cfi = p_cfi_lst->p_cfis_arr[j];
|
||||
bool is_cfi_supported;
|
||||
|
||||
cfi_freq = start_freq + FREQ_TO_CHAN_SCALE * cfi;
|
||||
is_cfi_supported = reg_is_cfi_supported(pdev,
|
||||
cfi_freq,
|
||||
bw,
|
||||
op_class_tbl->op_class);
|
||||
if (is_cfi_supported) {
|
||||
cap->sup_chan_list[n_sup_chans++] = cfi;
|
||||
cap->num_supported_chan++;
|
||||
} else {
|
||||
cap->non_sup_chan_list[n_unsup_chans++] = cfi;
|
||||
cap->num_non_supported_chan++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t reg_find_nearest_ieee_bw(uint16_t spacing)
|
||||
{
|
||||
#define SMALLEST_BW 20
|
||||
return (spacing / SMALLEST_BW) * SMALLEST_BW;
|
||||
}
|
||||
|
||||
/**
|
||||
* reg_get_cfis_from_opclassmap_for_non6g()- Get channels from the opclass map
|
||||
* for non-6GHz
|
||||
* @pdev: Pointer to pdev
|
||||
* @cap: Pointer to regdmn_ap_cap_opclass_t
|
||||
* @op_class_tbl: Pointer to op_class_tbl
|
||||
*
|
||||
* Populate channels from opclass map to regdmn_ap_cap_opclass_t as supported
|
||||
* and non-supported channels for non-6Ghz.
|
||||
*
|
||||
* Return: void.
|
||||
*/
|
||||
static void reg_get_cfis_from_opclassmap_for_non6g(
|
||||
struct wlan_objmgr_pdev *pdev,
|
||||
struct regdmn_ap_cap_opclass_t *cap,
|
||||
const struct reg_dmn_op_class_map_t *op_class_tbl)
|
||||
{
|
||||
qdf_freq_t start_freq = op_class_tbl->start_freq;
|
||||
uint8_t chan_idx = 0, n_sup_chans = 0, n_unsup_chans = 0;
|
||||
|
||||
while (op_class_tbl->channels[chan_idx]) {
|
||||
uint8_t op_cls_chan;
|
||||
qdf_freq_t pri_freq;
|
||||
enum phy_ch_width ch_width;
|
||||
bool is_supported;
|
||||
uint16_t opcls_bw;
|
||||
|
||||
op_cls_chan = reg_get_chan_or_chan_center(op_class_tbl,
|
||||
&chan_idx);
|
||||
pri_freq = start_freq + FREQ_TO_CHAN_SCALE * op_cls_chan;
|
||||
opcls_bw = reg_find_nearest_ieee_bw(op_class_tbl->chan_spacing);
|
||||
ch_width = reg_find_chwidth_from_bw(opcls_bw);
|
||||
pri_freq = reg_get_nearest_primary_freq(opcls_bw,
|
||||
pri_freq,
|
||||
op_class_tbl->op_class);
|
||||
is_supported = reg_is_chan_supported(pdev,
|
||||
pri_freq,
|
||||
0,
|
||||
ch_width);
|
||||
|
||||
if (!is_supported) {
|
||||
cap->non_sup_chan_list[n_unsup_chans++] = op_cls_chan;
|
||||
cap->num_non_supported_chan++;
|
||||
} else {
|
||||
cap->sup_chan_list[n_sup_chans++] = op_cls_chan;
|
||||
cap->num_supported_chan++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reg_get_channels_from_opclassmap()- Get channels from the opclass map
|
||||
* @pdev: Pointer to pdev
|
||||
@@ -1509,32 +1697,19 @@ reg_get_channels_from_opclassmap(
|
||||
const struct reg_dmn_op_class_map_t *op_class_tbl,
|
||||
bool *is_opclass_operable)
|
||||
{
|
||||
uint8_t op_cls_chan;
|
||||
qdf_freq_t search_freq;
|
||||
bool is_freq_present;
|
||||
uint8_t chan_idx = 0, n_sup_chans = 0, n_unsup_chans = 0;
|
||||
struct regdmn_ap_cap_opclass_t *cap = ®_ap_cap[index];
|
||||
|
||||
while (op_class_tbl->channels[chan_idx]) {
|
||||
op_cls_chan = op_class_tbl->channels[chan_idx];
|
||||
search_freq = op_class_tbl->start_freq +
|
||||
(FREQ_TO_CHAN_SCALE * op_cls_chan);
|
||||
is_freq_present =
|
||||
reg_is_freq_present_in_cur_chan_list(pdev, search_freq);
|
||||
|
||||
if (!is_freq_present) {
|
||||
reg_ap_cap[index].non_sup_chan_list[n_unsup_chans++] =
|
||||
reg_get_chan_or_chan_center(op_class_tbl,
|
||||
&chan_idx);
|
||||
reg_ap_cap[index].num_non_supported_chan++;
|
||||
} else {
|
||||
reg_ap_cap[index].sup_chan_list[n_sup_chans++] =
|
||||
reg_get_chan_or_chan_center(op_class_tbl,
|
||||
&chan_idx);
|
||||
reg_ap_cap[index].num_supported_chan++;
|
||||
}
|
||||
if (reg_is_6ghz_op_class(pdev, op_class_tbl->op_class)) {
|
||||
reg_get_cfis_from_opclassmap_for_6g(pdev,
|
||||
cap,
|
||||
op_class_tbl);
|
||||
} else {
|
||||
reg_get_cfis_from_opclassmap_for_non6g(pdev,
|
||||
cap,
|
||||
op_class_tbl);
|
||||
}
|
||||
|
||||
if (reg_ap_cap[index].num_supported_chan >= 1)
|
||||
if (cap->num_supported_chan >= 1)
|
||||
*is_opclass_operable = true;
|
||||
}
|
||||
|
||||
|
@@ -8118,3 +8118,46 @@ bool reg_is_freq_idx_enabled(struct wlan_objmgr_pdev *pdev,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE
|
||||
enum phy_ch_width reg_find_chwidth_from_bw(uint16_t bw)
|
||||
{
|
||||
switch (bw) {
|
||||
case BW_5_MHZ:
|
||||
return CH_WIDTH_5MHZ;
|
||||
case BW_10_MHZ:
|
||||
return CH_WIDTH_10MHZ;
|
||||
case BW_20_MHZ:
|
||||
return CH_WIDTH_20MHZ;
|
||||
case BW_40_MHZ:
|
||||
return CH_WIDTH_40MHZ;
|
||||
case BW_80_MHZ:
|
||||
return CH_WIDTH_80MHZ;
|
||||
case BW_160_MHZ:
|
||||
return CH_WIDTH_160MHZ;
|
||||
case BW_320_MHZ:
|
||||
return CH_WIDTH_320MHZ;
|
||||
default:
|
||||
return CH_WIDTH_INVALID;
|
||||
}
|
||||
}
|
||||
#else
|
||||
enum phy_ch_width reg_find_chwidth_from_bw(uint16_t bw)
|
||||
{
|
||||
switch (bw) {
|
||||
case BW_5_MHZ:
|
||||
return CH_WIDTH_5MHZ;
|
||||
case BW_10_MHZ:
|
||||
return CH_WIDTH_10MHZ;
|
||||
case BW_20_MHZ:
|
||||
return CH_WIDTH_20MHZ;
|
||||
case BW_40_MHZ:
|
||||
return CH_WIDTH_40MHZ;
|
||||
case BW_80_MHZ:
|
||||
return CH_WIDTH_80MHZ;
|
||||
case BW_160_MHZ:
|
||||
return CH_WIDTH_160MHZ;
|
||||
default:
|
||||
return CH_WIDTH_INVALID;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@@ -2217,4 +2217,14 @@ reg_get_best_6g_pwr_type(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq);
|
||||
*/
|
||||
enum supported_6g_pwr_types
|
||||
reg_conv_6g_ap_type_to_supported_6g_pwr_types(enum reg_6g_ap_type ap_pwr_type);
|
||||
|
||||
/**
|
||||
* reg_find_chwidth_from_bw () - Gets channel width for given
|
||||
* bandwidth
|
||||
* @bw: Bandwidth
|
||||
*
|
||||
* Return: phy_ch_width
|
||||
*/
|
||||
enum phy_ch_width reg_find_chwidth_from_bw(uint16_t bw);
|
||||
|
||||
#endif
|
||||
|
Viittaa uudesa ongelmassa
Block a user