qcacmn: Choose SP during STOP-TX in outdoor deployment

In outdoor deployment, when the target sends STOP_TX event, the 6 GHz
AP continues to beacon in the SP power mode, without bringing down the VAP.

In mlme_check_curchan_and_set_ap_pwr_type, since the
afc_power_event_received flag is cleared and set to false during STOP_TX,
the API wlan_reg_get_best_pwr_mode returns LPI as the best power mode.
When LPI is given as input to wlan_reg_set_ap_pwr_and_update_chan_list,
it returns an error as LPI rules are absent in the pdev
(outdoor deployment). But the error status is not handled. Current channel
list also is not updated with the AFC_NOT_FLAG. When the channel list is
sent to the hostapd, NO_IR flag is set based on the presence of the
AFC_NOT_DONE flag in the current channel list. As a result NO_IR flag is
not sent to the hostapd, and the VAP remains in the up state.

To fix this issue, in reg_get_best_pwr_mode_from_eirp_list, skip the
unsupported modes (in this case LPI and VLP), from best power mode
computation. Also, in reg_get_sp_eirp, return the SP EIRP when no rules
other than SP are available.

Also, rename reg_get_eirp_for_non_sp to reg_get_eirp_from_mas_chan_list.
Modify reg_get_sp_eirp to call reg_get_eirp_from_mas_chan_list when
CONFIG_AFC_SUPPORT is not defined.

Change-Id: I1b11bf0580ec6af09ee8f9827bc85fae7930e414
CRs-Fixed: 3436245
This commit is contained in:
Hariharan Basuthkar
2023-04-04 11:27:45 +05:30
committed by Madan Koyyalamudi
parent 30ff1d4085
commit 419d6ffcc9

View File

@@ -9325,7 +9325,7 @@ reg_get_mas_chan_list_for_lookup(struct wlan_objmgr_pdev *pdev,
}
/**
* reg_get_eirp_for_non_sp() - For the given power mode, using the bandwidth
* reg_get_eirp_from_mas_chan_list() - For the given power mode, using the bandwidth
* and psd(from master channel entry), calculate an EIRP value. The minimum
* of calculated EIRP and regulatory max EIRP is returned.
* @pdev: Pointer to pdev
@@ -9339,7 +9339,7 @@ reg_get_mas_chan_list_for_lookup(struct wlan_objmgr_pdev *pdev,
* Return: EIRP
*/
static uint8_t
reg_get_eirp_for_non_sp(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq,
reg_get_eirp_from_mas_chan_list(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq,
uint16_t bw, enum reg_6g_ap_type ap_pwr_type,
bool is_client_list_lookup_needed,
enum reg_6g_client_type client_type)
@@ -9348,12 +9348,6 @@ reg_get_eirp_for_non_sp(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq,
struct regulatory_channel *master_chan_list = NULL;
uint16_t txpower = 0;
if (!((ap_pwr_type == REG_INDOOR_AP) ||
(ap_pwr_type == REG_VERY_LOW_POWER_AP))) {
reg_err("Only LPI and VLP are supported in this function ");
return 0;
}
reg_get_mas_chan_list_for_lookup(pdev, &master_chan_list, ap_pwr_type,
is_client_list_lookup_needed,
client_type);
@@ -9611,6 +9605,53 @@ reg_get_sp_eirp_for_punc_chans(struct wlan_objmgr_pdev *pdev,
return 0;
}
/**
* reg_get_sp_eirp_before_afc_resp_rx() - Before the AFC response is received
* from the target, for a given input frequency and bw, find the EIRP values
* based on the deployment type and, the presence of SP AP and VLP AP reg rules.
* @pdev: Pointer to pdev
* @freq: Frequency in MHz
* @bw: Bandwidth in MHz
* @is_client_list_lookup_needed: Boolean to indicate if client list lookup is
* needed
* @client_type: Client power type
*
* Return: EIRP
*/
static uint8_t
reg_get_sp_eirp_before_afc_resp_rx(struct wlan_objmgr_pdev *pdev,
qdf_freq_t freq,
uint16_t bw,
bool is_client_list_lookup_needed,
enum reg_6g_client_type client_type)
{
enum reg_afc_dev_deploy_type reg_afc_dev_type;
struct wlan_objmgr_psoc *psoc;
uint8_t num_ap_sp_rules, num_ap_vlp_rules;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
reg_err("psoc is NULL");
return 0;
}
reg_get_afc_soc_dev_type(psoc, &reg_afc_dev_type);
num_ap_sp_rules =
reg_get_num_rules_of_ap_pwr_type(pdev, REG_STANDARD_POWER_AP);
num_ap_vlp_rules =
reg_get_num_rules_of_ap_pwr_type(pdev, REG_VERY_LOW_POWER_AP);
if (reg_afc_dev_type == AFC_DEPLOYMENT_OUTDOOR && num_ap_sp_rules &&
!num_ap_vlp_rules)
return reg_get_eirp_from_mas_chan_list(pdev, freq, bw,
REG_STANDARD_POWER_AP,
is_client_list_lookup_needed,
client_type);
else
return 0;
}
/**
* reg_get_sp_eirp() - For the given power mode, using the bandwidth, find the
* corresponding EIRP values from the afc power info array. The minimum of found
@@ -9649,7 +9690,9 @@ static uint8_t reg_get_sp_eirp(struct wlan_objmgr_pdev *pdev,
}
if (!reg_is_afc_power_event_received(pdev))
return 0;
return reg_get_sp_eirp_before_afc_resp_rx(pdev, freq, bw,
is_client_list_lookup_needed,
client_type);
sp_master_chan_list =
pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP];
@@ -9727,29 +9770,9 @@ static uint8_t reg_get_sp_eirp(struct wlan_objmgr_pdev *pdev,
bool is_client_list_lookup_needed,
enum reg_6g_client_type client_type)
{
struct regulatory_channel *sp_master_chan_list = NULL;
uint16_t reg_sp_eirp_pwr = 0;
bool is_psd;
reg_get_mas_chan_list_for_lookup(pdev, &sp_master_chan_list,
REG_STANDARD_POWER_AP,
return reg_get_eirp_from_mas_chan_list(pdev, freq, bw, REG_STANDARD_POWER_AP,
is_client_list_lookup_needed,
client_type);
if (!sp_master_chan_list) {
reg_err("sp_master_chan_list is NULL");
return 0;
}
reg_find_txpower_from_6g_list(freq, sp_master_chan_list,
&reg_sp_eirp_pwr);
is_psd = reg_is_6g_psd_power(pdev);
if (is_psd)
reg_get_eirp_from_psd_and_reg_max_eirp(pdev,
sp_master_chan_list,
freq, bw,
&reg_sp_eirp_pwr);
return reg_sp_eirp_pwr;
}
#endif
@@ -9765,9 +9788,17 @@ static enum reg_6g_ap_type
reg_get_best_pwr_mode_from_eirp_list(uint8_t *eirp_list, uint8_t size)
{
uint8_t max = 0, i;
enum reg_6g_ap_type best_pwr_mode = REG_INDOOR_AP;
enum reg_6g_ap_type best_pwr_mode = REG_CURRENT_MAX_AP_TYPE;
for (i = 0; i < size; i++) {
/* Assuming the eirp = 0 means the mode is not available,
* skip the mode.
* EIRP = 0 may be a valid value. We need to fix this in
* future by setting the min negative value (-128) to
* the channels for which power mode is not available.
*/
if (!eirp_list[i])
continue;
if (eirp_list[i] > max) {
max = eirp_list[i];
best_pwr_mode = i;
@@ -9789,7 +9820,7 @@ uint8_t reg_get_eirp_pwr(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq,
is_client_list_lookup_needed,
client_type);
return reg_get_eirp_for_non_sp(pdev, freq, bw, ap_pwr_type,
return reg_get_eirp_from_mas_chan_list(pdev, freq, bw, ap_pwr_type,
is_client_list_lookup_needed,
client_type);
}