diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 0789a943074f..d49e06f81ba4 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4284,6 +4284,7 @@ struct rtw89_chip_info { bool support_rnr; bool support_ant_gain; bool support_tas; + bool support_sar_by_ant; bool ul_tb_waveform_ctrl; bool ul_tb_pwr_diff; bool rx_freq_frome_ie; diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index 518a100375fb..cafb1a06d7b8 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -935,6 +935,20 @@ static inline s8 rtw89_phy_txpwr_dbm_to_mac(struct rtw89_dev *rtwdev, s8 dbm) return clamp_t(s16, dbm << chip->txpwr_factor_mac, -64, 63); } +static inline s16 rtw89_phy_txpwr_mac_to_rf(struct rtw89_dev *rtwdev, s8 txpwr_mac) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return txpwr_mac << (chip->txpwr_factor_rf - chip->txpwr_factor_mac); +} + +static inline s16 rtw89_phy_txpwr_mac_to_bb(struct rtw89_dev *rtwdev, s8 txpwr_mac) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return txpwr_mac << (chip->txpwr_factor_bb - chip->txpwr_factor_mac); +} + void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link); void rtw89_phy_ra_update(struct rtw89_dev *rtwdev); void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index 0d482cd57f6e..174b90661037 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -2499,6 +2499,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = { .support_unii4 = true, .support_ant_gain = false, .support_tas = false, + .support_sar_by_ant = false, .ul_tb_waveform_ctrl = true, .ul_tb_pwr_diff = false, .rx_freq_frome_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 286334e26c84..408c2f7b3eec 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2217,6 +2217,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .support_unii4 = false, .support_ant_gain = false, .support_tas = false, + .support_sar_by_ant = false, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = false, .rx_freq_frome_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index eceb4fb9880d..47233f0c6ea0 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -853,6 +853,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .support_unii4 = true, .support_ant_gain = true, .support_tas = false, + .support_sar_by_ant = false, .ul_tb_waveform_ctrl = true, .ul_tb_pwr_diff = false, .rx_freq_frome_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c index bbf37442c492..0903e902d8f4 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c @@ -786,6 +786,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = { .support_unii4 = true, .support_ant_gain = true, .support_tas = false, + .support_sar_by_ant = false, .ul_tb_waveform_ctrl = true, .ul_tb_pwr_diff = false, .rx_freq_frome_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 08bcdf246382..cbbb6a9169d1 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -3014,6 +3014,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .support_unii4 = true, .support_ant_gain = true, .support_tas = true, + .support_sar_by_ant = false, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = true, .rx_freq_frome_ie = false, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index 8082592db84a..5b45c18fbbf6 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -2823,6 +2823,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = { .support_unii4 = true, .support_ant_gain = true, .support_tas = false, + .support_sar_by_ant = false, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = false, .rx_freq_frome_ie = false, diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c index 120cf2088c9e..d15dafcae39b 100644 --- a/drivers/net/wireless/realtek/rtw89/sar.c +++ b/drivers/net/wireless/realtek/rtw89/sar.c @@ -120,6 +120,7 @@ static int rtw89_query_sar_config_acpi(struct rtw89_dev *rtwdev, const struct rtw89_sar_parm *sar_parm, s32 *cfg) { + const struct rtw89_chip_info *chip = rtwdev->chip; const struct rtw89_sar_cfg_acpi *rtwsar = &rtwdev->sar.cfg_acpi; const struct rtw89_sar_entry_from_acpi *ent_a, *ent_b; enum rtw89_acpi_sar_subband subband_l, subband_h; @@ -147,7 +148,30 @@ static int rtw89_query_sar_config_acpi(struct rtw89_dev *rtwdev, cfg_a = rtw89_sar_cfg_acpi_get_min(ent_a, RF_PATH_A, subband_l, subband_h); cfg_b = rtw89_sar_cfg_acpi_get_min(ent_b, RF_PATH_B, subband_l, subband_h); - *cfg = min(cfg_a, cfg_b); + + if (chip->support_sar_by_ant) { + /* With declaration of support_sar_by_ant, relax the general + * SAR querying to return the maximum between paths. However, + * expect chip has dealt with the corresponding SAR settings + * by path. (To get SAR for a given path, chip can then query + * with force_path.) + */ + if (sar_parm->force_path) { + switch (sar_parm->path) { + default: + case RF_PATH_A: + *cfg = cfg_a; + break; + case RF_PATH_B: + *cfg = cfg_b; + break; + } + } else { + *cfg = max(cfg_a, cfg_b); + } + } else { + *cfg = min(cfg_a, cfg_b); + } if (sar_parm->ntx == RTW89_2TX) *cfg -= rtwsar->downgrade_2tx; @@ -285,6 +309,7 @@ s8 rtw89_query_sar(struct rtw89_dev *rtwdev, const struct rtw89_sar_parm *sar_pa return rtw89_txpwr_sar_to_mac(rtwdev, fct, cfg); } +EXPORT_SYMBOL(rtw89_query_sar); int rtw89_print_sar(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, const struct rtw89_sar_parm *sar_parm) @@ -322,6 +347,8 @@ int rtw89_print_sar(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, p += scnprintf(p, end - p, "config: %d (unit: 1/%lu dBm)\n", cfg, BIT(fct)); + p += scnprintf(p, end - p, "support different configs by antenna: %s\n", + str_yes_no(rtwdev->chip->support_sar_by_ant)); out: return p - buf; } diff --git a/drivers/net/wireless/realtek/rtw89/sar.h b/drivers/net/wireless/realtek/rtw89/sar.h index 038a5c0d1e09..4b7f3d44f57b 100644 --- a/drivers/net/wireless/realtek/rtw89/sar.h +++ b/drivers/net/wireless/realtek/rtw89/sar.h @@ -13,6 +13,9 @@ struct rtw89_sar_parm { u32 center_freq; enum rtw89_ntx ntx; + + bool force_path; + enum rtw89_rf_path path; }; struct rtw89_sar_handler {