wifi: rtw89: 8852a: report per-channel noise level by get_survey ops

To optimize roaming decisions, report per-channel noise levels
during scans so supplicant can have a better view of the current
channel condition. This allows it to prefer the APs operating on
channels with lower noise levels.

Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250819034428.26307-2-pkshih@realtek.com
This commit is contained in:
Po-Hao Huang 2025-08-19 11:44:25 +08:00 committed by Ping-Ke Shih
parent 33319e8fd7
commit 4367000c0e
13 changed files with 482 additions and 4 deletions

View File

@ -6258,6 +6258,7 @@ int rtw89_core_register(struct rtw89_dev *rtwdev)
return ret;
}
rtw89_phy_dm_init_data(rtwdev);
rtw89_debugfs_init(rtwdev);
return 0;
@ -6308,6 +6309,9 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
ops->cancel_remain_on_channel = NULL;
}
if (!chip->support_noise)
ops->get_survey = NULL;
driver_data_size = sizeof(struct rtw89_dev) + bus_data_size;
hw = ieee80211_alloc_hw(driver_data_size, ops);
if (!hw)

View File

@ -4364,6 +4364,9 @@ struct rtw89_chanctx_listener {
(struct rtw89_dev *rtwdev, enum rtw89_chanctx_state state);
};
#define RTW89_NHM_TH_NUM 11
#define RTW89_NHM_RPT_NUM 12
struct rtw89_chip_info {
enum rtw89_core_chip_id chip_id;
enum rtw89_chip_gen chip_gen;
@ -4398,6 +4401,7 @@ struct rtw89_chip_info {
bool support_ant_gain;
bool support_tas;
bool support_sar_by_ant;
bool support_noise;
bool ul_tb_waveform_ctrl;
bool ul_tb_pwr_diff;
bool rx_freq_frome_ie;
@ -4482,6 +4486,8 @@ struct rtw89_chip_info {
bool cfo_hw_comp;
const struct rtw89_reg_def *dcfo_comp;
u8 dcfo_comp_sft;
const struct rtw89_reg_def (*nhm_report)[RTW89_NHM_RPT_NUM];
const struct rtw89_reg_def (*nhm_th)[RTW89_NHM_TH_NUM];
const struct rtw89_imr_info *imr_info;
const struct rtw89_imr_table *imr_dmac_table;
const struct rtw89_imr_table *imr_cmac_table;
@ -5464,6 +5470,7 @@ enum rtw89_env_racing_lv {
struct rtw89_ccx_para_info {
enum rtw89_env_racing_lv rac_lv;
u16 mntr_time;
bool nhm_incld_cca;
u8 nhm_manual_th_ofst;
u8 nhm_manual_th0;
enum rtw89_ifs_clm_application ifs_clm_app;
@ -5497,9 +5504,13 @@ enum rtw89_ccx_edcca_opt_bw_idx {
RTW89_CCX_EDCCA_BW20_7 = 7
};
#define RTW89_NHM_TH_NUM 11
struct rtw89_nhm_report {
struct list_head list;
struct ieee80211_channel *channel;
u8 noise;
};
#define RTW89_FAHM_TH_NUM 11
#define RTW89_NHM_RPT_NUM 12
#define RTW89_FAHM_RPT_NUM 12
#define RTW89_IFS_CLM_NUM 4
struct rtw89_env_monitor_info {
@ -5533,6 +5544,13 @@ struct rtw89_env_monitor_info {
u16 ifs_clm_ofdm_fa_permil;
u32 ifs_clm_ifs_avg[RTW89_IFS_CLM_NUM];
u32 ifs_clm_cca_avg[RTW89_IFS_CLM_NUM];
bool nhm_include_cca;
u32 nhm_sum;
u32 nhm_mntr_time;
u16 nhm_result[RTW89_NHM_RPT_NUM];
u8 nhm_th[RTW89_NHM_RPT_NUM];
struct rtw89_nhm_report *nhm_his[RTW89_BAND_NUM];
struct list_head nhm_rpt_list;
};
enum rtw89_ser_rcvy_step {

View File

@ -9,6 +9,7 @@
#include "fw.h"
#include "mac.h"
#include "pci.h"
#include "phy.h"
#include "ps.h"
#include "reg.h"
#include "util.h"
@ -5045,6 +5046,8 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (op_chan) {
rtw89_mac_enable_aps_bcn_by_chan(rtwdev, op_chan, false);
ieee80211_stop_queues(rtwdev->hw);
} else {
rtw89_phy_nhm_get_result(rtwdev, band, chan);
}
return;
case RTW89_SCAN_END_SCAN_NOTIFY:
@ -5075,6 +5078,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
RTW89_CHANNEL_WIDTH_20);
rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx,
&new);
rtw89_phy_nhm_trigger(rtwdev);
}
break;
default:

View File

@ -1837,6 +1837,40 @@ static void rtw89_set_rekey_data(struct ieee80211_hw *hw,
}
#endif
static int rtw89_ops_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey)
{
struct ieee80211_conf *conf = &hw->conf;
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_bb_ctx *bb;
if (idx == 0) {
survey->channel = conf->chandef.chan;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = RTW89_NOISE_DEFAULT;
return 0;
}
rtw89_for_each_active_bb(rtwdev, bb) {
struct rtw89_env_monitor_info *env = &bb->env_monitor;
struct rtw89_nhm_report *rpt;
rpt = list_first_entry_or_null(&env->nhm_rpt_list, typeof(*rpt), list);
if (!rpt)
continue;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = rpt->noise - MAX_RSSI;
survey->channel = rpt->channel;
list_del_init(&rpt->list);
return 0;
}
return -EINVAL;
}
static void rtw89_ops_rfkill_poll(struct ieee80211_hw *hw)
{
struct rtw89_dev *rtwdev = hw->priv;
@ -1869,6 +1903,7 @@ const struct ieee80211_ops rtw89_ops = {
.sta_state = rtw89_ops_sta_state,
.set_key = rtw89_ops_set_key,
.ampdu_action = rtw89_ops_ampdu_action,
.get_survey = rtw89_ops_get_survey,
.set_rts_threshold = rtw89_ops_set_rts_threshold,
.sta_statistics = rtw89_ops_sta_statistics,
.flush = rtw89_ops_flush,

View File

@ -5496,6 +5496,34 @@ static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev,
i + 1, env->ifs_clm_th_l[i], env->ifs_clm_th_h[i]);
}
static void __rtw89_phy_nhm_setting_init(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb)
{
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
struct rtw89_env_monitor_info *env = &bb->env_monitor;
const struct rtw89_ccx_regs *ccx = phy->ccx;
env->nhm_include_cca = false;
env->nhm_mntr_time = 0;
env->nhm_sum = 0;
rtw89_phy_write32_idx_set(rtwdev, ccx->nhm_config, ccx->nhm_en_mask, bb->phy_idx);
rtw89_phy_write32_idx_set(rtwdev, ccx->nhm_method, ccx->nhm_pwr_method_msk,
bb->phy_idx);
}
void rtw89_phy_nhm_setting_init(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_bb_ctx *bb;
if (!chip->support_noise)
return;
rtw89_for_each_active_bb(rtwdev, bb)
__rtw89_phy_nhm_setting_init(rtwdev, bb);
}
static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb)
{
@ -5557,7 +5585,7 @@ static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev,
}
static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb)
struct rtw89_bb_ctx *bb, u8 sel)
{
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
struct rtw89_env_monitor_info *env = &bb->env_monitor;
@ -5567,10 +5595,17 @@ static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev,
bb->phy_idx);
rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 0,
bb->phy_idx);
if (sel & RTW89_PHY_ENV_MON_NHM)
rtw89_phy_write32_idx_clr(rtwdev, ccx->nhm_config,
ccx->nhm_en_mask, bb->phy_idx);
rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 1,
bb->phy_idx);
rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1,
bb->phy_idx);
if (sel & RTW89_PHY_ENV_MON_NHM)
rtw89_phy_write32_idx_set(rtwdev, ccx->nhm_config,
ccx->nhm_en_mask, bb->phy_idx);
env->ccx_ongoing = true;
}
@ -5641,6 +5676,125 @@ static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev,
env->ifs_clm_cca_avg[i]);
}
static u8 rtw89_nhm_weighted_avg(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
struct rtw89_env_monitor_info *env = &bb->env_monitor;
u8 nhm_weight[RTW89_NHM_RPT_NUM];
u32 nhm_weighted_sum = 0;
u8 weight_zero;
u8 i;
if (env->nhm_sum == 0)
return 0;
weight_zero = clamp_t(u16, env->nhm_th[0] - RTW89_NHM_WEIGHT_OFFSET, 0, U8_MAX);
for (i = 0; i < RTW89_NHM_RPT_NUM; i++) {
if (i == 0)
nhm_weight[i] = weight_zero;
else if (i == (RTW89_NHM_RPT_NUM - 1))
nhm_weight[i] = env->nhm_th[i - 1] + RTW89_NHM_WEIGHT_OFFSET;
else
nhm_weight[i] = (env->nhm_th[i - 1] + env->nhm_th[i]) / 2;
}
if (rtwdev->chip->chip_id == RTL8852A || rtwdev->chip->chip_id == RTL8852B ||
rtwdev->chip->chip_id == RTL8852C) {
if (env->nhm_th[RTW89_NHM_TH_NUM - 1] == RTW89_NHM_WA_TH) {
nhm_weight[RTW89_NHM_RPT_NUM - 1] =
env->nhm_th[RTW89_NHM_TH_NUM - 2] +
RTW89_NHM_WEIGHT_OFFSET;
nhm_weight[RTW89_NHM_RPT_NUM - 2] =
nhm_weight[RTW89_NHM_RPT_NUM - 1];
}
env->nhm_result[0] += env->nhm_result[RTW89_NHM_RPT_NUM - 1];
env->nhm_result[RTW89_NHM_RPT_NUM - 1] = 0;
}
for (i = 0; i < RTW89_NHM_RPT_NUM; i++)
nhm_weighted_sum += env->nhm_result[i] * nhm_weight[i];
return (nhm_weighted_sum / env->nhm_sum) >> RTW89_NHM_TH_FACTOR;
}
static void __rtw89_phy_nhm_get_result(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb, enum rtw89_band hw_band,
u16 ch_hw_value)
{
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
struct rtw89_env_monitor_info *env = &bb->env_monitor;
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_ccx_regs *ccx = phy->ccx;
struct ieee80211_supported_band *sband;
const struct rtw89_reg_def *nhm_rpt;
enum nl80211_band band;
u32 sum = 0;
u8 chan_idx;
u8 nhm_pwr;
u8 i;
if (!rtw89_phy_read32_idx(rtwdev, ccx->nhm, ccx->nhm_ready, bb->phy_idx)) {
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "[NHM] Get NHM report Fail\n");
return;
}
for (i = 0; i < RTW89_NHM_RPT_NUM; i++) {
nhm_rpt = &(*chip->nhm_report)[i];
env->nhm_result[i] =
rtw89_phy_read32_idx(rtwdev, nhm_rpt->addr,
nhm_rpt->mask, bb->phy_idx);
sum += env->nhm_result[i];
}
env->nhm_sum = sum;
nhm_pwr = rtw89_nhm_weighted_avg(rtwdev, bb);
if (!ch_hw_value)
return;
band = rtw89_hw_to_nl80211_band(hw_band);
sband = rtwdev->hw->wiphy->bands[band];
if (!sband)
return;
for (chan_idx = 0; chan_idx < sband->n_channels; chan_idx++) {
struct ieee80211_channel *channel;
struct rtw89_nhm_report *rpt;
struct list_head *nhm_list;
channel = &sband->channels[chan_idx];
if (channel->hw_value != ch_hw_value)
continue;
rpt = &env->nhm_his[hw_band][chan_idx];
nhm_list = &env->nhm_rpt_list;
rpt->channel = channel;
rpt->noise = nhm_pwr;
if (list_empty(&rpt->list))
list_add_tail(&rpt->list, nhm_list);
return;
}
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "[NHM] channel not found\n");
}
void rtw89_phy_nhm_get_result(struct rtw89_dev *rtwdev, enum rtw89_band hw_band,
u16 ch_hw_value)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_bb_ctx *bb;
if (!chip->support_noise)
return;
rtw89_for_each_active_bb(rtwdev, bb)
__rtw89_phy_nhm_get_result(rtwdev, bb, hw_band, ch_hw_value);
}
static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb)
{
@ -5741,6 +5895,107 @@ static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev,
return true;
}
static void rtw89_phy_nhm_th_update(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb)
{
struct rtw89_env_monitor_info *env = &bb->env_monitor;
static const u8 nhm_th_11k[RTW89_NHM_RPT_NUM] = {
18, 21, 24, 27, 30, 35, 40, 45, 50, 55, 60, 0
};
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_reg_def *nhm_th;
u8 i;
for (i = 0; i < RTW89_NHM_RPT_NUM; i++)
env->nhm_th[i] = nhm_th_11k[i] << RTW89_NHM_TH_FACTOR;
if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
chip->chip_id == RTL8852C)
env->nhm_th[RTW89_NHM_TH_NUM - 1] = RTW89_NHM_WA_TH;
for (i = 0; i < RTW89_NHM_TH_NUM; i++) {
nhm_th = &(*chip->nhm_th)[i];
rtw89_phy_write32_idx(rtwdev, nhm_th->addr, nhm_th->mask,
env->nhm_th[i], bb->phy_idx);
}
}
static int rtw89_phy_nhm_set(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb,
struct rtw89_ccx_para_info *para)
{
const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
struct rtw89_env_monitor_info *env = &bb->env_monitor;
const struct rtw89_ccx_regs *ccx = phy->ccx;
u32 unit_idx = 0;
u32 period = 0;
if (para->mntr_time == 0) {
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
"[NHM] MNTR_TIME is 0\n");
return -EINVAL;
}
if (rtw89_phy_ccx_racing_ctrl(rtwdev, bb, para->rac_lv))
return -EINVAL;
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
"[NHM]nhm_incld_cca=%d, mntr_time=%d ms\n",
para->nhm_incld_cca, para->mntr_time);
if (para->mntr_time != env->nhm_mntr_time) {
rtw89_phy_ccx_ms_to_period_unit(rtwdev, para->mntr_time,
&period, &unit_idx);
rtw89_phy_write32_idx(rtwdev, ccx->nhm_config,
ccx->nhm_period_mask, period, bb->phy_idx);
rtw89_phy_write32_idx(rtwdev, ccx->nhm_config,
ccx->nhm_unit_mask, period, bb->phy_idx);
env->nhm_mntr_time = para->mntr_time;
env->ccx_period = period;
env->ccx_unit_idx = unit_idx;
}
if (para->nhm_incld_cca != env->nhm_include_cca) {
rtw89_phy_write32_idx(rtwdev, ccx->nhm_config,
ccx->nhm_include_cca_mask, para->nhm_incld_cca,
bb->phy_idx);
env->nhm_include_cca = para->nhm_incld_cca;
}
rtw89_phy_nhm_th_update(rtwdev, bb);
return 0;
}
static void __rtw89_phy_nhm_trigger(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
struct rtw89_ccx_para_info para = {
.mntr_time = RTW89_NHM_MNTR_TIME,
.rac_lv = RTW89_RAC_LV_1,
.nhm_incld_cca = true,
};
rtw89_phy_ccx_racing_release(rtwdev, bb);
rtw89_phy_nhm_set(rtwdev, bb, &para);
rtw89_phy_ccx_trigger(rtwdev, bb, RTW89_PHY_ENV_MON_NHM);
}
void rtw89_phy_nhm_trigger(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_bb_ctx *bb;
if (!chip->support_noise)
return;
rtw89_for_each_active_bb(rtwdev, bb)
__rtw89_phy_nhm_trigger(rtwdev, bb);
}
static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb,
struct rtw89_ccx_para_info *para)
@ -5815,7 +6070,7 @@ static void __rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev,
if (rtw89_phy_ifs_clm_set(rtwdev, bb, &para) == 0)
chk_result |= RTW89_PHY_ENV_MON_IFS_CLM;
if (chk_result)
rtw89_phy_ccx_trigger(rtwdev, bb);
rtw89_phy_ccx_trigger(rtwdev, bb, chk_result);
rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
"get_result=0x%x, chk_result:0x%x\n",
@ -6909,6 +7164,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
rtw89_chip_bb_sethw(rtwdev);
rtw89_phy_env_monitor_init(rtwdev);
rtw89_phy_nhm_setting_init(rtwdev);
rtw89_physts_parsing_init(rtwdev);
rtw89_phy_dig_init(rtwdev);
rtw89_phy_cfo_init(rtwdev);
@ -6934,6 +7190,43 @@ void rtw89_phy_dm_reinit(struct rtw89_dev *rtwdev)
rtw89_physts_parsing_init(rtwdev);
}
static void __rtw89_phy_dm_init_data(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
{
struct rtw89_env_monitor_info *env = &bb->env_monitor;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct ieee80211_supported_band *sband;
enum rtw89_band hw_band;
enum nl80211_band band;
u8 idx;
if (!chip->support_noise)
return;
for (band = 0; band < NUM_NL80211_BANDS; band++) {
sband = rtwdev->hw->wiphy->bands[band];
if (!sband)
continue;
hw_band = rtw89_nl80211_to_hw_band(band);
env->nhm_his[hw_band] =
devm_kcalloc(rtwdev->dev, sband->n_channels,
sizeof(*env->nhm_his[0]), GFP_KERNEL);
for (idx = 0; idx < sband->n_channels; idx++)
INIT_LIST_HEAD(&env->nhm_his[hw_band][idx].list);
INIT_LIST_HEAD(&env->nhm_rpt_list);
}
}
void rtw89_phy_dm_init_data(struct rtw89_dev *rtwdev)
{
struct rtw89_bb_ctx *bb;
rtw89_for_each_capab_bb(rtwdev, bb)
__rtw89_phy_dm_init_data(rtwdev, bb);
}
void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
@ -7589,6 +7882,15 @@ static const struct rtw89_ccx_regs rtw89_ccx_regs_ax = {
.ifs_total_addr = R_IFSCNT,
.ifs_cnt_done_mask = B_IFSCNT_DONE_MSK,
.ifs_total_mask = B_IFSCNT_TOTAL_CNT_MSK,
.nhm = R_NHM_AX,
.nhm_ready = B_NHM_READY_MSK,
.nhm_config = R_NHM_CFG,
.nhm_period_mask = B_NHM_PERIOD_MSK,
.nhm_unit_mask = B_NHM_COUNTER_MSK,
.nhm_include_cca_mask = B_NHM_INCLUDE_CCA_MSK,
.nhm_en_mask = B_NHM_EN_MSK,
.nhm_method = R_NHM_TH9,
.nhm_pwr_method_msk = B_NHM_PWDB_METHOD_MSK,
};
static const struct rtw89_physts_regs rtw89_physts_regs_ax = {

View File

@ -188,6 +188,12 @@ enum rtw89_env_monitor_result_level {
RTW89_PHY_ENV_MON_EDCCA_CLM = BIT(4),
};
#define RTW89_NHM_WEIGHT_OFFSET 2
#define RTW89_NHM_WA_TH (109 << 1)
#define RTW89_NOISE_DEFAULT -96
#define RTW89_NHM_MNTR_TIME 40
#define RTW89_NHM_TH_FACTOR 1
#define CCX_US_BASE_RATIO 4
enum rtw89_ccx_unit {
RTW89_CCX_4_US = 0,
@ -428,6 +434,15 @@ struct rtw89_ccx_regs {
u32 ifs_total_addr;
u32 ifs_cnt_done_mask;
u32 ifs_total_mask;
u32 nhm;
u32 nhm_ready;
u32 nhm_config;
u32 nhm_period_mask;
u32 nhm_unit_mask;
u32 nhm_include_cca_mask;
u32 nhm_en_mask;
u32 nhm_method;
u32 nhm_pwr_method_msk;
};
struct rtw89_physts_regs {
@ -821,6 +836,7 @@ void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev,
void *extra_data);
void rtw89_phy_dm_init(struct rtw89_dev *rtwdev);
void rtw89_phy_dm_reinit(struct rtw89_dev *rtwdev);
void rtw89_phy_dm_init_data(struct rtw89_dev *rtwdev);
void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 data, enum rtw89_phy_idx phy_idx);
void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
@ -1038,5 +1054,9 @@ enum rtw89_rf_path rtw89_phy_get_syn_sel(struct rtw89_dev *rtwdev,
u8 rtw89_rfk_chan_lookup(struct rtw89_dev *rtwdev,
const struct rtw89_rfk_chan_desc *desc, u8 desc_nr,
const struct rtw89_chan *target_chan);
void rtw89_phy_nhm_setting_init(struct rtw89_dev *rtwdev);
void rtw89_phy_nhm_get_result(struct rtw89_dev *rtwdev, enum rtw89_band hw_band,
u16 ch_hw_value);
void rtw89_phy_nhm_trigger(struct rtw89_dev *rtwdev);
#endif

View File

@ -63,6 +63,15 @@ static const struct rtw89_ccx_regs rtw89_ccx_regs_be = {
.ifs_total_addr = R_IFSCNT_V1,
.ifs_cnt_done_mask = B_IFSCNT_DONE_MSK,
.ifs_total_mask = B_IFSCNT_TOTAL_CNT_MSK,
.nhm = R_NHM_BE,
.nhm_ready = B_NHM_READY_BE_MSK,
.nhm_config = R_NHM_CFG,
.nhm_period_mask = B_NHM_PERIOD_MSK,
.nhm_unit_mask = B_NHM_COUNTER_MSK,
.nhm_include_cca_mask = B_NHM_INCLUDE_CCA_MSK,
.nhm_en_mask = B_NHM_EN_MSK,
.nhm_method = R_NHM_TH9,
.nhm_pwr_method_msk = B_NHM_PWDB_METHOD_MSK,
};
static const struct rtw89_physts_regs rtw89_physts_regs_be = {

View File

@ -8100,6 +8100,26 @@
#define B_MEASUREMENT_TRIG_MSK BIT(2)
#define B_CCX_TRIG_OPT_MSK BIT(1)
#define B_CCX_EN_MSK BIT(0)
#define R_NHM_CFG 0x0C08
#define B_NHM_PERIOD_MSK GENMASK(15, 0)
#define B_NHM_COUNTER_MSK GENMASK(17, 16)
#define B_NHM_EN_MSK BIT(18)
#define B_NHM_INCLUDE_CCA_MSK BIT(19)
#define B_NHM_TH0_MSK GENMASK(31, 24)
#define R_NHM_TH1 0x0C0C
#define B_NHM_TH1_MSK GENMASK(7, 0)
#define B_NHM_TH2_MSK GENMASK(15, 8)
#define B_NHM_TH3_MSK GENMASK(23, 16)
#define B_NHM_TH4_MSK GENMASK(31, 24)
#define R_NHM_TH5 0x0C10
#define B_NHM_TH5_MSK GENMASK(7, 0)
#define B_NHM_TH6_MSK GENMASK(15, 8)
#define B_NHM_TH7_MSK GENMASK(23, 16)
#define B_NHM_TH8_MSK GENMASK(31, 24)
#define R_NHM_TH9 0x0C14
#define B_NHM_TH9_MSK GENMASK(7, 0)
#define B_NHM_TH10_MSK GENMASK(15, 8)
#define B_NHM_PWDB_METHOD_MSK GENMASK(17, 16)
#define R_FAHM 0x0C1C
#define B_RXTD_CKEN BIT(2)
#define R_IFS_COUNTER 0x0C28
@ -8169,6 +8189,8 @@
#define R_BRK_ASYNC_RST_EN_1 0x0DC0
#define R_BRK_ASYNC_RST_EN_2 0x0DC4
#define R_BRK_ASYNC_RST_EN_3 0x0DC8
#define R_NHM_BE 0x0EA4
#define B_NHM_READY_BE_MSK BIT(16)
#define R_CTLTOP 0x1008
#define B_CTLTOP_ON BIT(23)
#define B_CTLTOP_VAL GENMASK(15, 12)
@ -8224,6 +8246,26 @@
#define B_SWSI_R_BUSY_V1 BIT(25)
#define B_SWSI_R_DATA_DONE_V1 BIT(26)
#define R_TX_COUNTER 0x1A40
#define R_NHM_CNT0 0x1A88
#define B_NHM_CNT0_MSK GENMASK(15, 0)
#define B_NHM_CNT1_MSK GENMASK(31, 16)
#define R_NHM_CNT2 0x1A8C
#define B_NHM_CNT2_MSK GENMASK(15, 0)
#define B_NHM_CNT3_MSK GENMASK(31, 16)
#define R_NHM_CNT4 0x1A90
#define B_NHM_CNT4_MSK GENMASK(15, 0)
#define B_NHM_CNT5_MSK GENMASK(31, 16)
#define R_NHM_CNT6 0x1A94
#define B_NHM_CNT6_MSK GENMASK(15, 0)
#define B_NHM_CNT7_MSK GENMASK(31, 16)
#define R_NHM_CNT8 0x1A98
#define B_NHM_CNT8_MSK GENMASK(15, 0)
#define B_NHM_CNT9_MSK GENMASK(31, 16)
#define R_NHM_CNT10 0x1A9C
#define B_NHM_CNT10_MSK GENMASK(15, 0)
#define B_NHM_CNT11_MSK GENMASK(31, 16)
#define R_NHM_AX 0x1AA4
#define B_NHM_READY_MSK BIT(16)
#define R_IFS_CLM_TX_CNT 0x1ACC
#define R_IFS_CLM_TX_CNT_V1 0x0ECC
#define B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK GENMASK(31, 16)

View File

@ -2628,6 +2628,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.support_ant_gain = false,
.support_tas = false,
.support_sar_by_ant = false,
.support_noise = false,
.ul_tb_waveform_ctrl = true,
.ul_tb_pwr_diff = false,
.rx_freq_frome_ie = true,
@ -2689,6 +2690,8 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.cfo_hw_comp = true,
.dcfo_comp = &rtw8851b_dcfo_comp,
.dcfo_comp_sft = 12,
.nhm_report = NULL,
.nhm_th = NULL,
.imr_info = &rtw8851b_imr_info,
.imr_dmac_table = NULL,
.imr_cmac_table = NULL,

View File

@ -426,6 +426,35 @@ static const struct rtw89_reg_def rtw8852a_dcfo_comp = {
R_DCFO_COMP_S0, B_DCFO_COMP_S0_MSK
};
static const struct rtw89_reg_def rtw8852a_nhm_th[RTW89_NHM_TH_NUM] = {
{R_NHM_CFG, B_NHM_TH0_MSK},
{R_NHM_TH1, B_NHM_TH1_MSK},
{R_NHM_TH1, B_NHM_TH2_MSK},
{R_NHM_TH1, B_NHM_TH3_MSK},
{R_NHM_TH1, B_NHM_TH4_MSK},
{R_NHM_TH5, B_NHM_TH5_MSK},
{R_NHM_TH5, B_NHM_TH6_MSK},
{R_NHM_TH5, B_NHM_TH7_MSK},
{R_NHM_TH5, B_NHM_TH8_MSK},
{R_NHM_TH9, B_NHM_TH9_MSK},
{R_NHM_TH9, B_NHM_TH10_MSK},
};
static const struct rtw89_reg_def rtw8852a_nhm_rpt[RTW89_NHM_RPT_NUM] = {
{R_NHM_CNT0, B_NHM_CNT0_MSK},
{R_NHM_CNT0, B_NHM_CNT1_MSK},
{R_NHM_CNT2, B_NHM_CNT2_MSK},
{R_NHM_CNT2, B_NHM_CNT3_MSK},
{R_NHM_CNT4, B_NHM_CNT4_MSK},
{R_NHM_CNT4, B_NHM_CNT5_MSK},
{R_NHM_CNT6, B_NHM_CNT6_MSK},
{R_NHM_CNT6, B_NHM_CNT7_MSK},
{R_NHM_CNT8, B_NHM_CNT8_MSK},
{R_NHM_CNT8, B_NHM_CNT9_MSK},
{R_NHM_CNT10, B_NHM_CNT10_MSK},
{R_NHM_CNT10, B_NHM_CNT11_MSK},
};
static const struct rtw89_imr_info rtw8852a_imr_info = {
.wdrls_imr_set = B_AX_WDRLS_IMR_SET,
.wsec_imr_reg = R_AX_SEC_DEBUG,
@ -2220,6 +2249,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.support_ant_gain = false,
.support_tas = false,
.support_sar_by_ant = false,
.support_noise = true,
.ul_tb_waveform_ctrl = false,
.ul_tb_pwr_diff = false,
.rx_freq_frome_ie = true,
@ -2282,6 +2312,8 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.cfo_hw_comp = false,
.dcfo_comp = &rtw8852a_dcfo_comp,
.dcfo_comp_sft = 10,
.nhm_report = &rtw8852a_nhm_rpt,
.nhm_th = &rtw8852a_nhm_th,
.imr_info = &rtw8852a_imr_info,
.imr_dmac_table = NULL,
.imr_cmac_table = NULL,

View File

@ -939,6 +939,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.support_ant_gain = true,
.support_tas = false,
.support_sar_by_ant = true,
.support_noise = false,
.ul_tb_waveform_ctrl = true,
.ul_tb_pwr_diff = false,
.rx_freq_frome_ie = true,
@ -1001,6 +1002,8 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.cfo_hw_comp = true,
.dcfo_comp = &rtw8852b_dcfo_comp,
.dcfo_comp_sft = 10,
.nhm_report = NULL,
.nhm_th = NULL,
.imr_info = &rtw8852b_imr_info,
.imr_dmac_table = NULL,
.imr_cmac_table = NULL,

View File

@ -3043,6 +3043,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.support_ant_gain = true,
.support_tas = true,
.support_sar_by_ant = true,
.support_noise = false,
.ul_tb_waveform_ctrl = false,
.ul_tb_pwr_diff = true,
.rx_freq_frome_ie = false,
@ -3106,6 +3107,8 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.cfo_hw_comp = false,
.dcfo_comp = &rtw8852c_dcfo_comp,
.dcfo_comp_sft = 12,
.nhm_report = NULL,
.nhm_th = NULL,
.imr_info = &rtw8852c_imr_info,
.imr_dmac_table = NULL,
.imr_cmac_table = NULL,

View File

@ -2896,6 +2896,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.support_ant_gain = true,
.support_tas = false,
.support_sar_by_ant = true,
.support_noise = false,
.ul_tb_waveform_ctrl = false,
.ul_tb_pwr_diff = false,
.rx_freq_frome_ie = false,
@ -2958,6 +2959,8 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.cfo_hw_comp = true,
.dcfo_comp = NULL,
.dcfo_comp_sft = 0,
.nhm_report = NULL,
.nhm_th = NULL,
.imr_info = NULL,
.imr_dmac_table = &rtw8922a_imr_dmac_table,
.imr_cmac_table = &rtw8922a_imr_cmac_table,