}
 }
 
-void rtw89_phy_set_txpwr_offset(struct rtw89_dev *rtwdev,
-                               const struct rtw89_chan *chan,
-                               enum rtw89_phy_idx phy_idx)
+static
+void rtw89_phy_set_txpwr_offset_ax(struct rtw89_dev *rtwdev,
+                                  const struct rtw89_chan *chan,
+                                  enum rtw89_phy_idx phy_idx)
 {
        struct rtw89_rate_desc desc = {
                .nss = RTW89_NSS_1,
        rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL,
                                     GENMASK(19, 0), val);
 }
-EXPORT_SYMBOL(rtw89_phy_set_txpwr_offset);
 
 void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev,
                               const struct rtw89_chan *chan,
        .physts = &rtw89_physts_regs_ax,
 
        .set_txpwr_byrate = rtw89_phy_set_txpwr_byrate_ax,
+       .set_txpwr_offset = rtw89_phy_set_txpwr_offset_ax,
 };
 EXPORT_SYMBOL(rtw89_phy_gen_ax);
 
        void (*set_txpwr_byrate)(struct rtw89_dev *rtwdev,
                                 const struct rtw89_chan *chan,
                                 enum rtw89_phy_idx phy_idx);
+       void (*set_txpwr_offset)(struct rtw89_dev *rtwdev,
+                                const struct rtw89_chan *chan,
+                                enum rtw89_phy_idx phy_idx);
 };
 
 extern const struct rtw89_phy_gen_def rtw89_phy_gen_ax;
        phy->set_txpwr_byrate(rtwdev, chan, phy_idx);
 }
 
+static inline
 void rtw89_phy_set_txpwr_offset(struct rtw89_dev *rtwdev,
                                const struct rtw89_chan *chan,
-                               enum rtw89_phy_idx phy_idx);
+                               enum rtw89_phy_idx phy_idx)
+{
+       const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
+
+       phy->set_txpwr_offset(rtwdev, chan, phy_idx);
+}
+
 void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev,
                               const struct rtw89_chan *chan,
                               enum rtw89_phy_idx phy_idx);
 
                                                  &addr, phy_idx);
 }
 
+static void rtw89_phy_set_txpwr_offset_be(struct rtw89_dev *rtwdev,
+                                         const struct rtw89_chan *chan,
+                                         enum rtw89_phy_idx phy_idx)
+{
+       struct rtw89_rate_desc desc = {
+               .nss = RTW89_NSS_1,
+               .rs = RTW89_RS_OFFSET,
+       };
+       u8 band = chan->band_type;
+       s8 v[RTW89_RATE_OFFSET_NUM_BE] = {};
+       u32 val;
+
+       rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
+                   "[TXPWR] set txpwr offset on band %d\n", band);
+
+       for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_NUM_BE; desc.idx++)
+               v[desc.idx] = rtw89_phy_read_txpwr_byrate(rtwdev, band, 0, &desc);
+
+       val = u32_encode_bits(v[RTW89_RATE_OFFSET_CCK], GENMASK(3, 0)) |
+             u32_encode_bits(v[RTW89_RATE_OFFSET_OFDM], GENMASK(7, 4)) |
+             u32_encode_bits(v[RTW89_RATE_OFFSET_HT], GENMASK(11, 8)) |
+             u32_encode_bits(v[RTW89_RATE_OFFSET_VHT], GENMASK(15, 12)) |
+             u32_encode_bits(v[RTW89_RATE_OFFSET_HE], GENMASK(19, 16)) |
+             u32_encode_bits(v[RTW89_RATE_OFFSET_EHT], GENMASK(23, 20)) |
+             u32_encode_bits(v[RTW89_RATE_OFFSET_DLRU_HE], GENMASK(27, 24)) |
+             u32_encode_bits(v[RTW89_RATE_OFFSET_DLRU_EHT], GENMASK(31, 28));
+
+       rtw89_mac_txpwr_write32(rtwdev, phy_idx, R_BE_PWR_RATE_OFST_CTRL, val);
+}
+
 const struct rtw89_phy_gen_def rtw89_phy_gen_be = {
        .cr_base = 0x20000,
        .ccx = &rtw89_ccx_regs_be,
        .physts = &rtw89_physts_regs_be,
 
        .set_txpwr_byrate = rtw89_phy_set_txpwr_byrate_be,
+       .set_txpwr_offset = rtw89_phy_set_txpwr_offset_be,
 };
 EXPORT_SYMBOL(rtw89_phy_gen_be);
 
 #define R_BE_PWR_MODULE 0x11900
 #define R_BE_PWR_MODULE_C1 0x15900
 
+#define R_BE_PWR_RATE_OFST_CTRL 0x11A30
 #define R_BE_PWR_BY_RATE 0x11E00
 
 #define CMAC1_START_ADDR_BE 0x14000