Skip to content

Commit 92425f7

Browse files
Wen Gongkvalo
authored andcommitted
wifi: ath11k: fill parameters for vdev set tpc power WMI command
Prepare the parameters which are needed for WMI command WMI_VDEV_SET_TPC_POWER_CMDID. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 Signed-off-by: Wen Gong <quic_wgong@quicinc.com> Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://msgid.link/20231218085844.2658-10-quic_bqiang@quicinc.com
1 parent 46f20de commit 92425f7

File tree

2 files changed

+288
-1
lines changed

2 files changed

+288
-1
lines changed

drivers/net/wireless/ath/ath11k/mac.c

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7667,6 +7667,290 @@ static u8 ath11k_mac_get_num_pwr_levels(struct cfg80211_chan_def *chan_def)
76677667
}
76687668
}
76697669

7670+
static u16 ath11k_mac_get_6ghz_start_frequency(struct cfg80211_chan_def *chan_def)
7671+
{
7672+
u16 diff_seq;
7673+
7674+
/* It is to get the lowest channel number's center frequency of the chan.
7675+
* For example,
7676+
* bandwidth=40 MHz, center frequency is 5965, lowest channel is 1
7677+
* with center frequency 5955, its diff is 5965 - 5955 = 10.
7678+
* bandwidth=80 MHz, center frequency is 5985, lowest channel is 1
7679+
* with center frequency 5955, its diff is 5985 - 5955 = 30.
7680+
* bandwidth=160 MHz, center frequency is 6025, lowest channel is 1
7681+
* with center frequency 5955, its diff is 6025 - 5955 = 70.
7682+
*/
7683+
switch (chan_def->width) {
7684+
case NL80211_CHAN_WIDTH_160:
7685+
diff_seq = 70;
7686+
break;
7687+
case NL80211_CHAN_WIDTH_80:
7688+
case NL80211_CHAN_WIDTH_80P80:
7689+
diff_seq = 30;
7690+
break;
7691+
case NL80211_CHAN_WIDTH_40:
7692+
diff_seq = 10;
7693+
break;
7694+
default:
7695+
diff_seq = 0;
7696+
}
7697+
7698+
return chan_def->center_freq1 - diff_seq;
7699+
}
7700+
7701+
static u16 ath11k_mac_get_seg_freq(struct cfg80211_chan_def *chan_def,
7702+
u16 start_seq, u8 seq)
7703+
{
7704+
u16 seg_seq;
7705+
7706+
/* It is to get the center frequency of the specific bandwidth.
7707+
* start_seq means the lowest channel number's center frequency.
7708+
* seq 0/1/2/3 means 20 MHz/40 MHz/80 MHz/160 MHz&80P80.
7709+
* For example,
7710+
* lowest channel is 1, its center frequency 5955,
7711+
* center frequency is 5955 when bandwidth=20 MHz, its diff is 5955 - 5955 = 0.
7712+
* lowest channel is 1, its center frequency 5955,
7713+
* center frequency is 5965 when bandwidth=40 MHz, its diff is 5965 - 5955 = 10.
7714+
* lowest channel is 1, its center frequency 5955,
7715+
* center frequency is 5985 when bandwidth=80 MHz, its diff is 5985 - 5955 = 30.
7716+
* lowest channel is 1, its center frequency 5955,
7717+
* center frequency is 6025 when bandwidth=160 MHz, its diff is 6025 - 5955 = 70.
7718+
*/
7719+
if (chan_def->width == NL80211_CHAN_WIDTH_80P80 && seq == 3)
7720+
return chan_def->center_freq2;
7721+
7722+
seg_seq = 10 * (BIT(seq) - 1);
7723+
return seg_seq + start_seq;
7724+
}
7725+
7726+
static void ath11k_mac_get_psd_channel(struct ath11k *ar,
7727+
u16 step_freq,
7728+
u16 *start_freq,
7729+
u16 *center_freq,
7730+
u8 i,
7731+
struct ieee80211_channel **temp_chan,
7732+
s8 *tx_power)
7733+
{
7734+
/* It is to get the center frequency for each 20 MHz.
7735+
* For example, if the chan is 160 MHz and center frequency is 6025,
7736+
* then it include 8 channels, they are 1/5/9/13/17/21/25/29,
7737+
* channel number 1's center frequency is 5955, it is parameter start_freq.
7738+
* parameter i is the step of the 8 channels. i is 0~7 for the 8 channels.
7739+
* the channel 1/5/9/13/17/21/25/29 maps i=0/1/2/3/4/5/6/7,
7740+
* and maps its center frequency is 5955/5975/5995/6015/6035/6055/6075/6095,
7741+
* the gap is 20 for each channel, parameter step_freq means the gap.
7742+
* after get the center frequency of each channel, it is easy to find the
7743+
* struct ieee80211_channel of it and get the max_reg_power.
7744+
*/
7745+
*center_freq = *start_freq + i * step_freq;
7746+
*temp_chan = ieee80211_get_channel(ar->hw->wiphy, *center_freq);
7747+
*tx_power = (*temp_chan)->max_reg_power;
7748+
}
7749+
7750+
static void ath11k_mac_get_eirp_power(struct ath11k *ar,
7751+
u16 *start_freq,
7752+
u16 *center_freq,
7753+
u8 i,
7754+
struct ieee80211_channel **temp_chan,
7755+
struct cfg80211_chan_def *def,
7756+
s8 *tx_power)
7757+
{
7758+
/* It is to get the center frequency for 20 MHz/40 MHz/80 MHz/
7759+
* 160 MHz&80P80 bandwidth, and then plus 10 to the center frequency,
7760+
* it is the center frequency of a channel number.
7761+
* For example, when configured channel number is 1.
7762+
* center frequency is 5965 when bandwidth=40 MHz, after plus 10, it is 5975,
7763+
* then it is channel number 5.
7764+
* center frequency is 5985 when bandwidth=80 MHz, after plus 10, it is 5995,
7765+
* then it is channel number 9.
7766+
* center frequency is 6025 when bandwidth=160 MHz, after plus 10, it is 6035,
7767+
* then it is channel number 17.
7768+
* after get the center frequency of each channel, it is easy to find the
7769+
* struct ieee80211_channel of it and get the max_reg_power.
7770+
*/
7771+
*center_freq = ath11k_mac_get_seg_freq(def, *start_freq, i);
7772+
7773+
/* For the 20 MHz, its center frequency is same with same channel */
7774+
if (i != 0)
7775+
*center_freq += 10;
7776+
7777+
*temp_chan = ieee80211_get_channel(ar->hw->wiphy, *center_freq);
7778+
*tx_power = (*temp_chan)->max_reg_power;
7779+
}
7780+
7781+
void ath11k_mac_fill_reg_tpc_info(struct ath11k *ar,
7782+
struct ieee80211_vif *vif,
7783+
struct ieee80211_chanctx_conf *ctx)
7784+
{
7785+
struct ath11k_base *ab = ar->ab;
7786+
struct ath11k_vif *arvif = (void *)vif->drv_priv;
7787+
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
7788+
struct ath11k_reg_tpc_power_info *reg_tpc_info = &arvif->reg_tpc_info;
7789+
struct ieee80211_channel *chan, *temp_chan;
7790+
u8 pwr_lvl_idx, num_pwr_levels, pwr_reduction;
7791+
bool is_psd_power = false, is_tpe_present = false;
7792+
s8 max_tx_power[IEEE80211_MAX_NUM_PWR_LEVEL],
7793+
psd_power, tx_power, eirp_power;
7794+
u16 start_freq, center_freq;
7795+
7796+
chan = ctx->def.chan;
7797+
start_freq = ath11k_mac_get_6ghz_start_frequency(&ctx->def);
7798+
pwr_reduction = bss_conf->pwr_reduction;
7799+
7800+
if (arvif->reg_tpc_info.num_pwr_levels) {
7801+
is_tpe_present = true;
7802+
num_pwr_levels = arvif->reg_tpc_info.num_pwr_levels;
7803+
} else {
7804+
num_pwr_levels = ath11k_mac_get_num_pwr_levels(&ctx->def);
7805+
}
7806+
7807+
for (pwr_lvl_idx = 0; pwr_lvl_idx < num_pwr_levels; pwr_lvl_idx++) {
7808+
/* STA received TPE IE*/
7809+
if (is_tpe_present) {
7810+
/* local power is PSD power*/
7811+
if (chan->flags & IEEE80211_CHAN_PSD) {
7812+
/* Connecting AP is psd power */
7813+
if (reg_tpc_info->is_psd_power) {
7814+
is_psd_power = true;
7815+
ath11k_mac_get_psd_channel(ar, 20,
7816+
&start_freq,
7817+
&center_freq,
7818+
pwr_lvl_idx,
7819+
&temp_chan,
7820+
&tx_power);
7821+
psd_power = temp_chan->psd;
7822+
eirp_power = tx_power;
7823+
max_tx_power[pwr_lvl_idx] =
7824+
min_t(s8,
7825+
psd_power,
7826+
reg_tpc_info->tpe[pwr_lvl_idx]);
7827+
/* Connecting AP is not psd power */
7828+
} else {
7829+
ath11k_mac_get_eirp_power(ar,
7830+
&start_freq,
7831+
&center_freq,
7832+
pwr_lvl_idx,
7833+
&temp_chan,
7834+
&ctx->def,
7835+
&tx_power);
7836+
psd_power = temp_chan->psd;
7837+
/* convert psd power to EIRP power based
7838+
* on channel width
7839+
*/
7840+
tx_power =
7841+
min_t(s8, tx_power,
7842+
psd_power + 13 + pwr_lvl_idx * 3);
7843+
max_tx_power[pwr_lvl_idx] =
7844+
min_t(s8,
7845+
tx_power,
7846+
reg_tpc_info->tpe[pwr_lvl_idx]);
7847+
}
7848+
/* local power is not PSD power */
7849+
} else {
7850+
/* Connecting AP is psd power */
7851+
if (reg_tpc_info->is_psd_power) {
7852+
is_psd_power = true;
7853+
ath11k_mac_get_psd_channel(ar, 20,
7854+
&start_freq,
7855+
&center_freq,
7856+
pwr_lvl_idx,
7857+
&temp_chan,
7858+
&tx_power);
7859+
eirp_power = tx_power;
7860+
max_tx_power[pwr_lvl_idx] =
7861+
reg_tpc_info->tpe[pwr_lvl_idx];
7862+
/* Connecting AP is not psd power */
7863+
} else {
7864+
ath11k_mac_get_eirp_power(ar,
7865+
&start_freq,
7866+
&center_freq,
7867+
pwr_lvl_idx,
7868+
&temp_chan,
7869+
&ctx->def,
7870+
&tx_power);
7871+
max_tx_power[pwr_lvl_idx] =
7872+
min_t(s8,
7873+
tx_power,
7874+
reg_tpc_info->tpe[pwr_lvl_idx]);
7875+
}
7876+
}
7877+
/* STA not received TPE IE */
7878+
} else {
7879+
/* local power is PSD power*/
7880+
if (chan->flags & IEEE80211_CHAN_PSD) {
7881+
is_psd_power = true;
7882+
ath11k_mac_get_psd_channel(ar, 20,
7883+
&start_freq,
7884+
&center_freq,
7885+
pwr_lvl_idx,
7886+
&temp_chan,
7887+
&tx_power);
7888+
psd_power = temp_chan->psd;
7889+
eirp_power = tx_power;
7890+
max_tx_power[pwr_lvl_idx] = psd_power;
7891+
} else {
7892+
ath11k_mac_get_eirp_power(ar,
7893+
&start_freq,
7894+
&center_freq,
7895+
pwr_lvl_idx,
7896+
&temp_chan,
7897+
&ctx->def,
7898+
&tx_power);
7899+
max_tx_power[pwr_lvl_idx] = tx_power;
7900+
}
7901+
}
7902+
7903+
if (is_psd_power) {
7904+
/* If AP local power constraint is present */
7905+
if (pwr_reduction)
7906+
eirp_power = eirp_power - pwr_reduction;
7907+
7908+
/* If firmware updated max tx power is non zero, then take
7909+
* the min of firmware updated ap tx power
7910+
* and max power derived from above mentioned parameters.
7911+
*/
7912+
ath11k_dbg(ab, ATH11K_DBG_MAC,
7913+
"eirp power : %d firmware report power : %d\n",
7914+
eirp_power, ar->max_allowed_tx_power);
7915+
/* Firmware reports lower max_allowed_tx_power during vdev
7916+
* start response. In case of 6 GHz, firmware is not aware
7917+
* of EIRP power unless driver sets EIRP power through WMI
7918+
* TPC command. So radio which does not support idle power
7919+
* save can set maximum calculated EIRP power directly to
7920+
* firmware through TPC command without min comparison with
7921+
* vdev start response's max_allowed_tx_power.
7922+
*/
7923+
if (ar->max_allowed_tx_power && ab->hw_params.idle_ps)
7924+
eirp_power = min_t(s8,
7925+
eirp_power,
7926+
ar->max_allowed_tx_power);
7927+
} else {
7928+
/* If AP local power constraint is present */
7929+
if (pwr_reduction)
7930+
max_tx_power[pwr_lvl_idx] =
7931+
max_tx_power[pwr_lvl_idx] - pwr_reduction;
7932+
/* If firmware updated max tx power is non zero, then take
7933+
* the min of firmware updated ap tx power
7934+
* and max power derived from above mentioned parameters.
7935+
*/
7936+
if (ar->max_allowed_tx_power && ab->hw_params.idle_ps)
7937+
max_tx_power[pwr_lvl_idx] =
7938+
min_t(s8,
7939+
max_tx_power[pwr_lvl_idx],
7940+
ar->max_allowed_tx_power);
7941+
}
7942+
reg_tpc_info->chan_power_info[pwr_lvl_idx].chan_cfreq = center_freq;
7943+
reg_tpc_info->chan_power_info[pwr_lvl_idx].tx_power =
7944+
max_tx_power[pwr_lvl_idx];
7945+
}
7946+
7947+
reg_tpc_info->num_pwr_levels = num_pwr_levels;
7948+
reg_tpc_info->is_psd_power = is_psd_power;
7949+
reg_tpc_info->eirp_power = eirp_power;
7950+
reg_tpc_info->ap_power_type =
7951+
ath11k_reg_ap_pwr_convert(vif->bss_conf.power_type);
7952+
}
7953+
76707954
static void ath11k_mac_parse_tx_pwr_env(struct ath11k *ar,
76717955
struct ieee80211_vif *vif,
76727956
struct ieee80211_chanctx_conf *ctx)

drivers/net/wireless/ath/ath11k/mac.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
22
/*
33
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4-
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
4+
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
55
*/
66

77
#ifndef ATH11K_MAC_H
@@ -176,4 +176,7 @@ int ath11k_mac_wait_tx_complete(struct ath11k *ar);
176176
int ath11k_mac_vif_set_keepalive(struct ath11k_vif *arvif,
177177
enum wmi_sta_keepalive_method method,
178178
u32 interval);
179+
void ath11k_mac_fill_reg_tpc_info(struct ath11k *ar,
180+
struct ieee80211_vif *vif,
181+
struct ieee80211_chanctx_conf *ctx);
179182
#endif

0 commit comments

Comments
 (0)