qcacld-3.0: Modify TPE information elements for 6ghz

Re-write TPE IE populating code. For 6ghz AP, there can be multiple
TPE IEs.The TPE IE can be of type PSD or non-psd.

Change-Id: I029d4826cbc73abb382d885260c355217b2cc6b4
CRs-Fixed: 2863009
This commit is contained in:
Amar Singhal 2020-12-10 12:48:01 -08:00 • committed by snandini
commit efdd75523f
3 changed files with 218 additions and 41 deletions

View file

@ -710,6 +710,15 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx,
is_vht_enabled = true;
}
if (wlan_reg_is_6ghz_chan_freq(pe_session->curr_op_freq)) {
populate_dot11f_tx_power_env(mac_ctx,
&frm->transmit_power_env[0],
pe_session->ch_width,
pe_session->curr_op_freq,
&frm->num_transmit_power_env,
false);
}
if (lim_is_session_he_capable(pe_session)) {
pe_debug("Populate HE IEs");
populate_dot11f_he_caps(mac_ctx, pe_session,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -474,6 +474,15 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
QCN_IE_ATTR_ID_ALL);
}
if (wlan_reg_is_6ghz_chan_freq(session->curr_op_freq)) {
populate_dot11f_tx_power_env(mac_ctx,
&bcn_2->transmit_power_env[0],
session->ch_width,
session->curr_op_freq,
&bcn_2->num_transmit_power_env,
false);
}
if (lim_is_session_he_capable(session)) {
pe_debug("Populate HE IEs");
populate_dot11f_he_caps(mac_ctx, session,

View file

@ -265,64 +265,222 @@ populate_dot11_supp_operating_classes(struct mac_context *mac_ptr,
void
populate_dot11f_tx_power_env(struct mac_context *mac,
tDot11fIEtransmit_power_env *pDot11f,
enum phy_ch_width ch_width, uint32_t chan_freq,
uint16_t *num_tpe, bool is_ch_switch)
tDot11fIEtransmit_power_env *tpe_ptr,
enum phy_ch_width chan_width, uint32_t chan_freq,
uint16_t *num_tpe, bool is_chan_switch)
{
uint8_t num_tx_power, i, tx_power;
int reg_max;
uint8_t count;
uint16_t eirp_power, reg_power;
int power_for_bss;
bool add_eirp_power = false;
struct ch_params chan_params;
bool psd_tpe = false;
uint32_t bw_threshold, bw_val;
int num_tpe_ies = 0;
uint32_t num_tx_power, num_tx_power_psd;
uint32_t max_tx_pwr_count, max_tx_pwr_count_psd;
qdf_freq_t psd_start_freq;
if (!is_ch_switch)
*num_tpe = 1;
if (!wlan_reg_is_6ghz_chan_freq(chan_freq)) {
psd_tpe = false;
} else {
wlan_reg_get_client_power_for_6ghz_ap(mac->pdev,
REG_DEFAULT_CLIENT,
chan_freq,
&psd_tpe,
&reg_power, &eirp_power);
}
switch (ch_width) {
switch (chan_width) {
case CH_WIDTH_20MHZ:
/* Max Transmit Power count = 0 (20 MHz) */
num_tx_power = 0;
break;
case CH_WIDTH_40MHZ:
/* Max Transmit Power count = 1 (20, 40 MHz) */
max_tx_pwr_count = 0;
max_tx_pwr_count_psd = 1;
num_tx_power = 1;
num_tx_power_psd = 1;
break;
case CH_WIDTH_80MHZ:
/* Max Transmit Power count = 2 (20, 40, and 80 MHz) */
case CH_WIDTH_40MHZ:
max_tx_pwr_count = 1;
max_tx_pwr_count_psd = 2;
num_tx_power = 2;
num_tx_power_psd = 2;
break;
case CH_WIDTH_80MHZ:
max_tx_pwr_count = 2;
max_tx_pwr_count_psd = 3;
num_tx_power = 3;
num_tx_power_psd = 4;
break;
case CH_WIDTH_160MHZ:
case CH_WIDTH_80P80MHZ:
/* Max Transmit Power count = 3 (20, 40, 80, 160/80+80 MHz) */
num_tx_power = 3;
max_tx_pwr_count = 3;
max_tx_pwr_count_psd = 4;
num_tx_power = 4;
num_tx_power_psd = 8;
break;
default:
return;
}
reg_max = wlan_reg_get_channel_reg_power_for_freq(mac->pdev, chan_freq);
if (!psd_tpe) {
reg_power = wlan_reg_get_channel_reg_power_for_freq(
mac->pdev, chan_freq);
/* in 0.5 dB steps */
reg_max *= 2;
if (reg_max > 127)
/* 63.5 has special meaning of 63.5 dBm or higher */
reg_max = 127;
tpe_ptr->present = 1;
tpe_ptr->max_tx_pwr_count = max_tx_pwr_count;
tpe_ptr->max_tx_pwr_interpret = 0;
tpe_ptr->max_tx_pwr_category = 0;
tpe_ptr->num_tx_power = num_tx_power;
for (count = 0; count < num_tx_power; count++)
tpe_ptr->tx_power[count] = reg_power;
if (reg_max < -128)
reg_max = -128;
num_tpe_ies++;
tpe_ptr++;
} else {
if (reg_max < 0)
tx_power = 0x80 + reg_max + 128;
else
tx_power = reg_max;
bw_val = wlan_reg_get_bw_value(chan_width);
bw_threshold = 20;
power_for_bss = reg_power + 13;
/* Ignore EID field */
pDot11f[0].present = 1;
pDot11f[0].num_tx_power = num_tx_power + 2;
/*
* Max Transmit Power count and
* Max Transmit Power units = 0 (EIRP)
*/
pDot11f[0].tx_power[0] = num_tx_power;
for (i = 0; i <= num_tx_power; i++)
pDot11f[0].tx_power[i + 1] = tx_power;
while ((eirp_power > power_for_bss) &&
(bw_threshold < bw_val)) {
bw_threshold = 2 * bw_threshold;
power_for_bss += 3;
}
if (bw_threshold < bw_val)
add_eirp_power = true;
if (add_eirp_power) {
tpe_ptr->present = 1;
tpe_ptr->max_tx_pwr_count = max_tx_pwr_count;
tpe_ptr->max_tx_pwr_interpret = 2;
tpe_ptr->max_tx_pwr_category = 0;
tpe_ptr->num_tx_power = num_tx_power;
for (count = 0, bw_val = 20; count < num_tx_power;
count++, bw_val += 20) {
if (bw_val >= bw_threshold)
tpe_ptr->tx_power[count] =
eirp_power * 2;
else
tpe_ptr->tx_power[count] =
reg_power * 2;
}
num_tpe_ies++;
tpe_ptr++;
}
wlan_reg_get_client_power_for_6ghz_ap(mac->pdev,
REG_SUBORDINATE_CLIENT,
chan_freq,
&psd_tpe,
&reg_power,
&eirp_power);
if (reg_power) {
bw_val = wlan_reg_get_bw_value(chan_width);
bw_threshold = 20;
power_for_bss = reg_power + 13;
while ((eirp_power > power_for_bss) &&
(bw_threshold < bw_val)) {
bw_threshold = 2 * bw_threshold;
power_for_bss += 3;
}
if (bw_threshold < bw_val)
add_eirp_power = true;
if (add_eirp_power) {
tpe_ptr->present = 1;
tpe_ptr->max_tx_pwr_count = max_tx_pwr_count;
tpe_ptr->max_tx_pwr_interpret = 2;
tpe_ptr->max_tx_pwr_category = 1;
tpe_ptr->num_tx_power = num_tx_power;
for (count = 0, bw_val = 20;
count < num_tx_power;
count++, bw_val += 20) {
if (bw_val >= bw_threshold)
tpe_ptr->tx_power[count] =
eirp_power * 2;
else
tpe_ptr->tx_power[count] =
reg_power * 2;
}
num_tpe_ies++;
tpe_ptr++;
}
}
tpe_ptr->present = 1;
tpe_ptr->max_tx_pwr_count = max_tx_pwr_count_psd;
tpe_ptr->max_tx_pwr_interpret = 3;
tpe_ptr->max_tx_pwr_category = 0;
tpe_ptr->num_tx_power = num_tx_power_psd;
chan_params.ch_width = chan_width;
bw_val = wlan_reg_get_bw_value(chan_width);
wlan_reg_set_channel_params_for_freq(mac->pdev, chan_freq,
chan_freq,
&chan_params);
psd_start_freq = chan_params.mhz_freq_seg0 - bw_val + 10;
for (count = 0; count < num_tx_power_psd; count++) {
wlan_reg_get_client_power_for_6ghz_ap(
mac->pdev,
REG_DEFAULT_CLIENT,
psd_start_freq +
20 * num_tx_power_psd,
&psd_tpe,
&reg_power,
&eirp_power);
tpe_ptr->tx_power[count] = reg_power * 2;
}
num_tpe_ies++;
tpe_ptr++;
wlan_reg_get_client_power_for_6ghz_ap(mac->pdev,
REG_SUBORDINATE_CLIENT,
chan_freq,
&psd_tpe,
&reg_power,
&eirp_power);
if (reg_power) {
tpe_ptr->present = 1;
tpe_ptr->max_tx_pwr_count = max_tx_pwr_count_psd;
tpe_ptr->max_tx_pwr_interpret = 3;
tpe_ptr->max_tx_pwr_category = 1;
tpe_ptr->num_tx_power = num_tx_power_psd;
chan_params.ch_width = chan_width;
wlan_reg_set_channel_params_for_freq(mac->pdev,
chan_freq,
chan_freq,
&chan_params);
for (count = 0; count < num_tx_power_psd; count++) {
wlan_reg_get_client_power_for_6ghz_ap(
mac->pdev,
REG_SUBORDINATE_CLIENT,
psd_start_freq +
20 * num_tx_power_psd,
&psd_tpe,
&reg_power,
&eirp_power);
tpe_ptr->tx_power[count] = reg_power * 2;
}
num_tpe_ies++;
tpe_ptr++;
}
}
*num_tpe = num_tpe_ies;
}
void
@ -330,6 +488,7 @@ populate_dot11f_chan_switch_wrapper(struct mac_context *mac,
tDot11fIEChannelSwitchWrapper *pDot11f,
struct pe_session *pe_session)
{
uint16_t num_tpe;
/*
* The new country subelement is present only when
* 1. AP performs Extended Channel switching to new country.
@ -367,7 +526,7 @@ populate_dot11f_chan_switch_wrapper(struct mac_context *mac,
&pDot11f->transmit_power_env,
pe_session->gLimChannelSwitch.ch_width,
pe_session->gLimChannelSwitch.sw_target_freq,
NULL, true);
&num_tpe, true);
}
}