wifi: rtw89: 8922a: pass channel information when enter LPS

Newer firmware requires the driver to pass channel information
when switching from normal mode to low power mode; otherwise it
will result in poor RX beacon performance.

Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250606020437.17160-1-pkshih@realtek.com
This commit is contained in:
Kuan-Chung Chen 2025-06-06 10:04:37 +08:00 committed by Ping-Ke Shih
parent d310eaf4ad
commit 389e578dd2
3 changed files with 69 additions and 0 deletions

View File

@ -5919,6 +5919,65 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
}
EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc);
int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_h2c_rf_ps_info *h2c;
const struct rtw89_chan *chan;
u32 len = sizeof(*h2c);
unsigned int link_id;
struct sk_buff *skb;
int ret;
u8 path;
u32 val;
if (chip->chip_gen != RTW89_CHIP_BE)
return 0;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c rf ps info\n");
return -ENOMEM;
}
skb_put(skb, len);
h2c = (struct rtw89_h2c_rf_ps_info *)skb->data;
h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
path = rtw89_phy_get_syn_sel(rtwdev, rtwvif_link->phy_idx);
val = rtw89_chip_chan_to_rf18_val(rtwdev, chan);
if (path >= chip->rf_path_num) {
rtw89_err(rtwdev, "unsupported rf path (%d)\n", path);
ret = -ENOENT;
goto fail;
}
h2c->rf18[path] = cpu_to_le32(val);
h2c->pri_ch[path] = chan->primary_channel;
}
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
H2C_FUNC_OUTSRC_RF_PS_INFO, 0, 0,
sizeof(*h2c));
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
rtw89_err(rtwdev, "failed to send h2c\n");
goto fail;
}
return 0;
fail:
dev_kfree_skb_any(skb);
return ret;
}
EXPORT_SYMBOL(rtw89_fw_h2c_rf_ps_info);
int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{

View File

@ -4337,6 +4337,7 @@ enum rtw89_mrc_h2c_func {
#define H2C_CL_OUTSRC_RF_REG_B 0x9
#define H2C_CL_OUTSRC_RF_FW_NOTIFY 0xa
#define H2C_FUNC_OUTSRC_RF_GET_MCCCH 0x2
#define H2C_FUNC_OUTSRC_RF_PS_INFO 0x10
#define H2C_CL_OUTSRC_RF_FW_RFK 0xb
enum rtw89_rfk_offload_h2c_func {
@ -4361,6 +4362,12 @@ struct rtw89_fw_h2c_rf_get_mccch {
#define NUM_OF_RTW89_FW_RFK_PATH 2
#define NUM_OF_RTW89_FW_RFK_TBL 3
struct rtw89_h2c_rf_ps_info {
__le32 rf18[NUM_OF_RTW89_FW_RFK_PATH];
__le32 mlo_mode;
u8 pri_ch[NUM_OF_RTW89_FW_RFK_PATH];
} __packed;
struct rtw89_fw_h2c_rfk_pre_info_common {
struct {
__le32 ch[NUM_OF_RTW89_FW_RFK_PATH][NUM_OF_RTW89_FW_RFK_TBL];
@ -4744,6 +4751,7 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
struct rtw89_fw_h2c_rf_reg_info *info,
u16 len, u8 page);
int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx);
int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,

View File

@ -137,6 +137,8 @@ void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
can_ps_mode = false;
}
rtw89_fw_h2c_rf_ps_info(rtwdev, rtwvif);
if (RTW89_CHK_FW_FEATURE(LPS_CH_INFO, &rtwdev->fw))
rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif);
else