qcacmn: Find 6 GHz power type for connection channel

Currently host doesn't check if power type is supported
for connection channel while calculating best 6 GHz
power type for connection. This results in calculation
of incorrect power for connection values if 6 GHz power
type is not supported for that particular channel.

To address this issue configure power type for connection
only if that power type is supported for connection
channel.

Change-Id: I0570dbf7c8dc41b3f0a92480b8d8f57d89ea65f6
CRs-Fixed: 3697209
This commit is contained in:
Surya Prakash Sivaraj 2024-01-09 12:56:53 +05:30 • committed by Ravindra Konda
commit b2b9cad3d2
4 changed files with 81 additions and 9 deletions

View file

@ -373,15 +373,70 @@ QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
return QDF_STATUS_SUCCESS;
}
static inline bool reg_is_state_allowed(enum channel_state chan_state)
{
return !((chan_state == CHANNEL_STATE_INVALID) ||
(chan_state == CHANNEL_STATE_DISABLE));
}
#ifdef CONFIG_REG_CLIENT
#ifdef CONFIG_BAND_6GHZ
/**
* reg_check_if_6g_pwr_type_supp_for_chan() - Check if 6 GHz power type is
* supported for the channel
* @pdev: Pointer to pdev
* @pwr_type: 6 GHz power type
* @chan_idx: Connection channel index
*
* Return: Return QDF_STATUS_SUCCESS if 6 GHz power type supported for
* the given channel, else return QDF_STATUS_E_FAILURE.
*/
static
QDF_STATUS reg_check_if_6g_pwr_type_supp_for_chan(
struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type pwr_type,
enum channel_enum chan_idx)
{
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
struct regulatory_channel *ch_info;
enum reg_6g_client_type client_type;
uint16_t ch_idx_6g;
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!pdev_priv_obj) {
reg_err("pdev priv obj null");
return QDF_STATUS_E_FAILURE;
}
ch_idx_6g = reg_convert_enum_to_6g_idx(chan_idx);
if (ch_idx_6g >= NUM_6GHZ_CHANNELS) {
reg_err("Invalid channel");
return QDF_STATUS_E_NOSUPPORT;
}
if (QDF_IS_STATUS_ERROR(reg_get_cur_6g_client_type(pdev, &client_type)))
return QDF_STATUS_E_FAILURE;
ch_info = &pdev_priv_obj->mas_chan_list_6g_client[pwr_type][client_type][ch_idx_6g];
if (reg_is_state_allowed(ch_info->state) &&
!(ch_info->chan_flags & REGULATORY_CHAN_DISABLED))
return QDF_STATUS_SUCCESS;
reg_err("6 GHz power type = %d not supported by STA %d index %d",
pwr_type, client_type, ch_idx_6g);
return QDF_STATUS_E_NOSUPPORT;
}
QDF_STATUS
reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type *pwr_type_6g,
enum reg_6g_ap_type ap_pwr_type)
enum reg_6g_ap_type ap_pwr_type,
uint32_t chan_freq)
{
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
enum channel_enum chan_idx = reg_get_chan_enum_for_freq(chan_freq);
*pwr_type_6g = ap_pwr_type;
pdev_priv_obj = reg_get_pdev_obj(pdev);
@ -390,14 +445,21 @@ reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_E_FAILURE;
}
if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[ap_pwr_type]) {
if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[ap_pwr_type] &&
QDF_IS_STATUS_SUCCESS(reg_check_if_6g_pwr_type_supp_for_chan(
pdev,
ap_pwr_type, chan_idx))) {
reg_debug("AP power type: %d , is supported by client",
ap_pwr_type);
return QDF_STATUS_SUCCESS;
}
if (ap_pwr_type == REG_INDOOR_AP) {
if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP]) {
if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP] &&
QDF_IS_STATUS_SUCCESS(
reg_check_if_6g_pwr_type_supp_for_chan(pdev,
REG_VERY_LOW_POWER_AP,
chan_idx))) {
*pwr_type_6g = REG_VERY_LOW_POWER_AP;
reg_debug("AP power type = %d, selected power type = %d",
ap_pwr_type, *pwr_type_6g);
@ -406,7 +468,11 @@ reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc,
goto no_support;
}
} else if (ap_pwr_type == REG_STANDARD_POWER_AP) {
if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP]) {
if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP] &&
QDF_IS_STATUS_SUCCESS(
reg_check_if_6g_pwr_type_supp_for_chan(pdev,
REG_VERY_LOW_POWER_AP,
chan_idx))) {
*pwr_type_6g = REG_VERY_LOW_POWER_AP;
reg_debug("AP power type = %d, selected power type = %d",
ap_pwr_type, *pwr_type_6g);
@ -425,7 +491,8 @@ QDF_STATUS
reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type *pwr_type_6g,
enum reg_6g_ap_type ap_pwr_type)
enum reg_6g_ap_type ap_pwr_type,
uint32_t chan_freq)
{
return QDF_STATUS_SUCCESS;
}

View file

@ -304,6 +304,7 @@ QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
* @pdev: pointer to pdev
* @pwr_type_6g: ptr to 6G power type
* @ap_pwr_type: AP's power type as advertised in HE ops IE
* @chan_freq: Connection channel frequency
*
* This function computes best power type for 6 GHz connection.
* SP power type is selected only if AP advertises SP and client supports SP.
@ -319,7 +320,8 @@ QDF_STATUS
reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type *pwr_type_6g,
enum reg_6g_ap_type ap_pwr_type);
enum reg_6g_ap_type ap_pwr_type,
uint32_t chan_freq);
#endif
/**

View file

@ -551,13 +551,15 @@ QDF_STATUS wlan_reg_read_current_country(struct wlan_objmgr_psoc *psoc,
* @pwr_type_6g: ptr to 6G power type
* @ctry_code_match: Check for country IE and sta country code match
* @ap_pwr_type: AP's power type for 6G as advertised in HE ops IE
* @chan_freq: Connection channel frequency
* Return: QDF_STATUS
*/
QDF_STATUS
wlan_reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type *pwr_type_6g,
enum reg_6g_ap_type ap_pwr_type);
enum reg_6g_ap_type ap_pwr_type,
uint32_t chan_freq);
#endif
#ifdef CONFIG_CHAN_NUM_API

View file

@ -90,10 +90,11 @@ QDF_STATUS
wlan_reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
enum reg_6g_ap_type *pwr_type_6g,
enum reg_6g_ap_type ap_pwr_type)
enum reg_6g_ap_type ap_pwr_type,
uint32_t chan_freq)
{
return reg_get_best_6g_power_type(psoc, pdev, pwr_type_6g,
ap_pwr_type);
ap_pwr_type, chan_freq);
}
#endif