]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: handle different TX power between RF path
authorKuan-Chung Chen <damon.chen@realtek.com>
Mon, 11 Nov 2024 06:51:32 +0000 (14:51 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Mon, 18 Nov 2024 02:12:45 +0000 (10:12 +0800)
The dynamic antenna gain (DAG) may independently apply different TX
powers for each RF path. This can be accomplished by using the larger
TX power as the reference path and adjusting the TX power of the
other path based on the difference. Currently only 8852BE/8852BTE/
8852CE are supported.

Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20241111065132.19587-4-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/phy.c
drivers/net/wireless/realtek/rtw89/phy.h
drivers/net/wireless/realtek/rtw89/rtw8851b.c
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852b.c
drivers/net/wireless/realtek/rtw89/rtw8852b_common.c
drivers/net/wireless/realtek/rtw89/rtw8852bt.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c
drivers/net/wireless/realtek/rtw89/rtw8922a.c

index bf7aff4268968a85e85a752c66921be0eba47d83..ecccb51184be940887845a928eee86d21113bf9f 100644 (file)
@@ -4297,6 +4297,7 @@ struct rtw89_chip_info {
        const struct rtw89_rfe_parms *dflt_parms;
        const struct rtw89_chanctx_listener *chanctx_listener;
 
+       u8 txpwr_factor_bb;
        u8 txpwr_factor_rf;
        u8 txpwr_factor_mac;
 
index e9a635c43a815a0f326735cbb69a32d7f61423b5..be2f5338c3a0b7759a883b8c0e72f5c20905e764 100644 (file)
@@ -2040,6 +2040,23 @@ static s8 rtw89_phy_ant_gain_offset(struct rtw89_dev *rtwdev, u8 band, u32 cente
        return max(offset_patha, offset_pathb);
 }
 
+s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev,
+                                 const struct rtw89_chan *chan)
+{
+       struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
+       u8 regd = rtw89_regd_get(rtwdev, chan->band_type);
+       s8 offset_patha, offset_pathb;
+
+       if (!(ant_gain->regd_enabled & BIT(regd)))
+               return 0;
+
+       offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq);
+       offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, chan->freq);
+
+       return rtw89_phy_txpwr_rf_to_bb(rtwdev, offset_patha - offset_pathb);
+}
+EXPORT_SYMBOL(rtw89_phy_ant_gain_pwr_offset);
+
 void rtw89_print_ant_gain(struct seq_file *m, struct rtw89_dev *rtwdev,
                          const struct rtw89_chan *chan)
 {
@@ -2123,20 +2140,6 @@ void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev,
 }
 EXPORT_SYMBOL(rtw89_phy_load_txpwr_byrate);
 
-static s8 rtw89_phy_txpwr_rf_to_mac(struct rtw89_dev *rtwdev, s8 txpwr_rf)
-{
-       const struct rtw89_chip_info *chip = rtwdev->chip;
-
-       return txpwr_rf >> (chip->txpwr_factor_rf - chip->txpwr_factor_mac);
-}
-
-static s8 rtw89_phy_txpwr_dbm_to_mac(struct rtw89_dev *rtwdev, s8 dbm)
-{
-       const struct rtw89_chip_info *chip = rtwdev->chip;
-
-       return clamp_t(s16, dbm << chip->txpwr_factor_mac, -64, 63);
-}
-
 static s8 rtw89_phy_txpwr_dbm_without_tolerance(s8 dbm)
 {
        const u8 tssi_deviation_point = 0;
index 2720cabfafe4b5e3c764c06fe00f3c65a3295d97..f4ef7f5fb0814255e5d77b4a48eed10504ba5872 100644 (file)
@@ -827,6 +827,8 @@ s8 *rtw89_phy_raw_byr_seek(struct rtw89_dev *rtwdev,
 s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, u8 bw,
                               const struct rtw89_rate_desc *rate_desc);
 void rtw89_phy_ant_gain_init(struct rtw89_dev *rtwdev);
+s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev,
+                                 const struct rtw89_chan *chan);
 void rtw89_print_ant_gain(struct seq_file *m, struct rtw89_dev *rtwdev,
                          const struct rtw89_chan *chan);
 void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev,
@@ -899,6 +901,27 @@ void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
        phy->set_txpwr_limit_ru(rtwdev, chan, phy_idx);
 }
 
+static inline s8 rtw89_phy_txpwr_rf_to_bb(struct rtw89_dev *rtwdev, s8 txpwr_rf)
+{
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+
+       return txpwr_rf << (chip->txpwr_factor_bb - chip->txpwr_factor_rf);
+}
+
+static inline s8 rtw89_phy_txpwr_rf_to_mac(struct rtw89_dev *rtwdev, s8 txpwr_rf)
+{
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+
+       return txpwr_rf >> (chip->txpwr_factor_rf - chip->txpwr_factor_mac);
+}
+
+static inline s8 rtw89_phy_txpwr_dbm_to_mac(struct rtw89_dev *rtwdev, s8 dbm)
+{
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+
+       return clamp_t(s16, dbm << chip->txpwr_factor_mac, -64, 63);
+}
+
 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,
index 29c697a251d33009600cbb0795944ea845d374fd..1ed4e64cbd2c88d4166d9a2f6c27f14d022bfa8f 100644 (file)
@@ -2464,6 +2464,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
        .nctl_post_table        = &rtw8851b_nctl_post_defs_tbl,
        .dflt_parms             = &rtw89_8851b_dflt_parms,
        .rfe_parms_conf         = rtw89_8851b_rfe_parms_conf,
+       .txpwr_factor_bb        = 3,
        .txpwr_factor_rf        = 2,
        .txpwr_factor_mac       = 1,
        .dig_table              = NULL,
index fd59ee9f36265e30e968eae9f3c44112ee61dd04..a7105a288bc477e396369ce79b5e5b30acc118dd 100644 (file)
@@ -2181,6 +2181,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
        .nctl_post_table        = NULL,
        .dflt_parms             = &rtw89_8852a_dflt_parms,
        .rfe_parms_conf         = NULL,
+       .txpwr_factor_bb        = 3,
        .txpwr_factor_rf        = 2,
        .txpwr_factor_mac       = 1,
        .dig_table              = &rtw89_8852a_phy_dig_table,
index 76667d4f3631233f01b40747786553f19881c70c..ebc853a905dd286e3ce2d0d7369bf135414754bb 100644 (file)
@@ -819,6 +819,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
        .nctl_post_table        = NULL,
        .dflt_parms             = &rtw89_8852b_dflt_parms,
        .rfe_parms_conf         = NULL,
+       .txpwr_factor_bb        = 3,
        .txpwr_factor_rf        = 2,
        .txpwr_factor_mac       = 1,
        .dig_table              = NULL,
index f4aa4437fb7593432bb4702c851551613f7b0505..012739d97f71a16b73f4f2a2deec4fbdffc2ad9c 100644 (file)
@@ -1206,24 +1206,25 @@ void __rtw8852bx_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_cha
 }
 
 static u32 rtw8852bx_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
-                                     enum rtw89_phy_idx phy_idx, s16 ref)
+                                     enum rtw89_phy_idx phy_idx,
+                                     s16 ref, u16 pwr_ofst_decrease)
 {
        const u16 tssi_16dbm_cw = 0x12c;
        const u8 base_cw_0db = 0x27;
-       const s8 ofst_int = 0;
        s16 pwr_s10_3;
        s16 rf_pwr_cw;
        u16 bb_pwr_cw;
        u32 pwr_cw;
        u32 tssi_ofst_cw;
 
-       pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3);
+       pwr_s10_3 = (ref << 1) + (s16)(base_cw_0db << 3) - pwr_ofst_decrease;
        bb_pwr_cw = u16_get_bits(pwr_s10_3, GENMASK(2, 0));
        rf_pwr_cw = u16_get_bits(pwr_s10_3, GENMASK(8, 3));
        rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63);
        pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw;
 
-       tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3));
+       tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)) -
+                      pwr_ofst_decrease;
        rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
                    "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n",
                    tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw);
@@ -1234,10 +1235,11 @@ static u32 rtw8852bx_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
 }
 
 static void rtw8852bx_set_txpwr_ref(struct rtw89_dev *rtwdev,
-                                   enum rtw89_phy_idx phy_idx)
+                                   enum rtw89_phy_idx phy_idx, s16 pwr_ofst)
 {
        static const u32 addr[RF_PATH_NUM_8852BX] = {0x5800, 0x7800};
        const u32 mask = B_DPD_TSSI_CW | B_DPD_PWR_CW | B_DPD_REF;
+       u16 ofst_dec[RF_PATH_NUM_8852BX];
        const u8 ofst_ofdm = 0x4;
        const u8 ofst_cck = 0x8;
        const s16 ref_ofdm = 0;
@@ -1250,19 +1252,20 @@ static void rtw8852bx_set_txpwr_ref(struct rtw89_dev *rtwdev,
        rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL,
                                     B_AX_PWR_REF, 0x0);
 
-       rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
-       val = rtw8852bx_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm);
+       ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? 0 : abs(pwr_ofst);
+       ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ofst : 0;
 
-       for (i = 0; i < RF_PATH_NUM_8852BX; i++)
-               rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val,
-                                     phy_idx);
+       rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
+       for (i = 0; i < RF_PATH_NUM_8852BX; i++) {
+               val = rtw8852bx_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm, ofst_dec[i]);
+               rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, phy_idx);
+       }
 
        rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n");
-       val = rtw8852bx_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck);
-
-       for (i = 0; i < RF_PATH_NUM_8852BX; i++)
-               rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val,
-                                     phy_idx);
+       for (i = 0; i < RF_PATH_NUM_8852BX; i++) {
+               val = rtw8852bx_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck, ofst_dec[i]);
+               rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, phy_idx);
+       }
 }
 
 static void rtw8852bx_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
@@ -1333,6 +1336,16 @@ static void rtw8852bx_set_tx_shape(struct rtw89_dev *rtwdev,
                               tx_shape_ofdm);
 }
 
+static void rtw8852bx_set_txpwr_diff(struct rtw89_dev *rtwdev,
+                                    const struct rtw89_chan *chan,
+                                    enum rtw89_phy_idx phy_idx)
+{
+       s16 pwr_ofst;
+
+       pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan);
+       rtw8852bx_set_txpwr_ref(rtwdev, phy_idx, pwr_ofst);
+}
+
 static void __rtw8852bx_set_txpwr(struct rtw89_dev *rtwdev,
                                  const struct rtw89_chan *chan,
                                  enum rtw89_phy_idx phy_idx)
@@ -1342,12 +1355,13 @@ static void __rtw8852bx_set_txpwr(struct rtw89_dev *rtwdev,
        rtw8852bx_set_tx_shape(rtwdev, chan, phy_idx);
        rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
        rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
+       rtw8852bx_set_txpwr_diff(rtwdev, chan, phy_idx);
 }
 
 static void __rtw8852bx_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
                                       enum rtw89_phy_idx phy_idx)
 {
-       rtw8852bx_set_txpwr_ref(rtwdev, phy_idx);
+       rtw8852bx_set_txpwr_ref(rtwdev, phy_idx, 0);
 }
 
 static
index d8c0fb87b625ebfe996ff87a9628030b4e45e0ad..cd1385ff800306e45b903e3f8ee4da80df1cf4ed 100644 (file)
@@ -752,6 +752,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
        .nctl_post_table        = NULL,
        .dflt_parms             = NULL,
        .rfe_parms_conf         = NULL,
+       .txpwr_factor_bb        = 3,
        .txpwr_factor_rf        = 2,
        .txpwr_factor_mac       = 1,
        .dig_table              = NULL,
index b639710107519cedc98d5bbda675c0bf880b929b..c7d39499ca75a8cda126e6a53a599059b94c0415 100644 (file)
@@ -1882,9 +1882,9 @@ static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev)
 }
 
 static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
-                                    enum rtw89_phy_idx phy_idx, s16 ref)
+                                    enum rtw89_phy_idx phy_idx,
+                                    s16 ref, u16 pwr_ofst_decrease)
 {
-       s8 ofst_int = 0;
        u8 base_cw_0db = 0x27;
        u16 tssi_16dbm_cw = 0x12c;
        s16 pwr_s10_3 = 0;
@@ -1893,13 +1893,14 @@ static u32 rtw8852c_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev,
        u32 pwr_cw = 0;
        u32 tssi_ofst_cw = 0;
 
-       pwr_s10_3 = (ref << 1) + (s16)(ofst_int) + (s16)(base_cw_0db << 3);
+       pwr_s10_3 = (ref << 1) + (s16)(base_cw_0db << 3) - pwr_ofst_decrease;
        bb_pwr_cw = FIELD_GET(GENMASK(2, 0), pwr_s10_3);
        rf_pwr_cw = FIELD_GET(GENMASK(8, 3), pwr_s10_3);
        rf_pwr_cw = clamp_t(s16, rf_pwr_cw, 15, 63);
        pwr_cw = (rf_pwr_cw << 3) | bb_pwr_cw;
 
-       tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3));
+       tssi_ofst_cw = (u32)((s16)tssi_16dbm_cw + (ref << 1) - (16 << 3)) -
+                      pwr_ofst_decrease;
        rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
                    "[TXPWR] tssi_ofst_cw=%d rf_cw=0x%x bb_cw=0x%x\n",
                    tssi_ofst_cw, rf_pwr_cw, bb_pwr_cw);
@@ -1943,9 +1944,10 @@ void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
 }
 
 static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
-                                  enum rtw89_phy_idx phy_idx)
+                                  enum rtw89_phy_idx phy_idx, s16 pwr_ofst)
 {
        static const u32 addr[RF_PATH_NUM_8852C] = {0x5800, 0x7800};
+       u16 ofst_dec[RF_PATH_NUM_8852C];
        const u32 mask = 0x7FFFFFF;
        const u8 ofst_ofdm = 0x4;
        const u8 ofst_cck = 0x8;
@@ -1959,19 +1961,20 @@ static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev,
        rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_CTRL,
                                     GENMASK(27, 10), 0x0);
 
-       rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
-       val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm);
+       ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? 0 : abs(pwr_ofst);
+       ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ofst : 0;
 
-       for (i = 0; i < RF_PATH_NUM_8852C; i++)
-               rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val,
-                                     phy_idx);
+       rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb ofdm txpwr ref\n");
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm, ofst_dec[i]);
+               rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_ofdm, mask, val, phy_idx);
+       }
 
        rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set bb cck txpwr ref\n");
-       val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck);
-
-       for (i = 0; i < RF_PATH_NUM_8852C; i++)
-               rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val,
-                                     phy_idx);
+       for (i = 0; i < RF_PATH_NUM_8852C; i++) {
+               val = rtw8852c_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck, ofst_dec[i]);
+               rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, phy_idx);
+       }
 }
 
 static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev,
@@ -2052,6 +2055,16 @@ static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
                              B_P1_DAC_COMP_POST_DPD_EN);
 }
 
+static void rtw8852c_set_txpwr_diff(struct rtw89_dev *rtwdev,
+                                   const struct rtw89_chan *chan,
+                                   enum rtw89_phy_idx phy_idx)
+{
+       s16 pwr_ofst;
+
+       pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan);
+       rtw8852c_set_txpwr_ref(rtwdev, phy_idx, pwr_ofst);
+}
+
 static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev,
                               const struct rtw89_chan *chan,
                               enum rtw89_phy_idx phy_idx)
@@ -2061,12 +2074,13 @@ static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev,
        rtw8852c_set_tx_shape(rtwdev, chan, phy_idx);
        rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx);
        rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx);
+       rtw8852c_set_txpwr_diff(rtwdev, chan, phy_idx);
 }
 
 static void rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev,
                                    enum rtw89_phy_idx phy_idx)
 {
-       rtw8852c_set_txpwr_ref(rtwdev, phy_idx);
+       rtw8852c_set_txpwr_ref(rtwdev, phy_idx, 0);
 }
 
 static void
@@ -2959,6 +2973,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
        .dflt_parms             = &rtw89_8852c_dflt_parms,
        .rfe_parms_conf         = NULL,
        .chanctx_listener       = &rtw8852c_chanctx_listener,
+       .txpwr_factor_bb        = 3,
        .txpwr_factor_rf        = 2,
        .txpwr_factor_mac       = 1,
        .dig_table              = NULL,
index b3879b48591811720d74f1cfde2aab7f0e941331..a5333099668a15b379e3e6ffd1f995e57b943603 100644 (file)
@@ -2729,6 +2729,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
        .nctl_post_table        = NULL,
        .dflt_parms             = NULL, /* load parm from fw */
        .rfe_parms_conf         = NULL, /* load parm from fw */
+       .txpwr_factor_bb        = 3,
        .txpwr_factor_rf        = 2,
        .txpwr_factor_mac       = 1,
        .dig_table              = NULL,