]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: rfk: add rtw89_fw_h2c_rf_pre_ntfy_mcc for new WiFi 7 firmware
authorChih-Kang Chang <gary.chang@realtek.com>
Wed, 31 Dec 2025 09:06:38 +0000 (17:06 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Wed, 7 Jan 2026 07:42:54 +0000 (15:42 +0800)
The pre-notify is to notify firmware the configured channels, and then
RF calibration in firmware can use these values to calibrate RF properly.

Since we need more information, change and add the new H2C command format.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20251231090647.56407-3-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/fw.h
drivers/net/wireless/realtek/rtw89/phy.c

index b42d3a4df4bf3b1ced2204000ac0f406adc40883..b7d5eb25ef748028abb13d453756fa662995c985 100644 (file)
@@ -4685,6 +4685,7 @@ enum rtw89_fw_feature {
        RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0,
        RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1,
        RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V2,
+       RTW89_FW_FEATURE_WITH_RFK_PRE_NOTIFY,
        RTW89_FW_FEATURE_RFK_RXDCK_V0,
        RTW89_FW_FEATURE_RFK_IQK_V0,
        RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX,
@@ -5239,6 +5240,7 @@ struct rtw89_rfk_mcc_info_data {
        u8 ch[RTW89_RFK_CHS_NR];
        u8 band[RTW89_RFK_CHS_NR];
        u8 bw[RTW89_RFK_CHS_NR];
+       u32 rf18[RTW89_RFK_CHS_NR];
        u8 table_idx;
 };
 
index d05b15ea022ae336e9d4ffafcf02796817e06d9e..d13c93fafb34eef5b3c264de48772e8a5e3161da 100644 (file)
@@ -892,6 +892,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
        __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG),
        __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1),
        __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 80, 0, BEACON_TRACKING),
+       __CFG_FW_FEAT(RTL8922A, le, 0, 35, 80, 0, WITH_RFK_PRE_NOTIFY),
        __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 84, 0, ADDR_CAM_V0),
 };
 
@@ -6490,6 +6491,65 @@ fail:
        return ret;
 }
 
+int rtw89_fw_h2c_rf_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+       struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
+       struct rtw89_fw_h2c_rfk_pre_info_mcc *h2c;
+       struct rtw89_hal *hal = &rtwdev->hal;
+       u32 len = sizeof(*h2c);
+       struct sk_buff *skb;
+       u8 tbl, path;
+       int ret;
+
+       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+       if (!skb) {
+               rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy_mcc\n");
+               return -ENOMEM;
+       }
+       skb_put(skb, len);
+       h2c = (struct rtw89_fw_h2c_rfk_pre_info_mcc *)skb->data;
+
+       BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR);
+
+       for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++)
+               h2c->tbl_18[tbl] = cpu_to_le32(rfk_mcc->rf18[tbl]);
+
+       BUILD_BUG_ON(ARRAY_SIZE(rtwdev->rfk_mcc.data) < NUM_OF_RTW89_FW_RFK_PATH);
+
+       /* shared table array, but tbl_sel can be independent by path */
+       for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
+               tbl = rfk_mcc[path].table_idx;
+               h2c->cur_18[path] = cpu_to_le32(rfk_mcc->rf18[tbl]);
+
+               if (path == phy_idx)
+                       h2c->tbl_idx = tbl;
+       }
+
+       h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
+
+       if (rtw89_is_mlo_1_1(rtwdev))
+               h2c->mlo_1_1 = cpu_to_le32(1);
+
+       h2c->phy_idx = phy_idx;
+       h2c->aid = cpu_to_le32(hal->aid);
+
+       rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+                             H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
+                             H2C_FUNC_OUTSRC_RF_MCC_INFO, 0, 0, len);
+
+       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;
+}
+
 int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
                         const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode)
 {
index f12728ccb31fa1c5e9a98523e688a644049943a2..5292b568e2bffc02920314af5d86b9e80b9aacd5 100644 (file)
@@ -4471,6 +4471,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_MCC_INFO    0xf
 #define H2C_FUNC_OUTSRC_RF_PS_INFO     0x10
 #define H2C_CL_OUTSRC_RF_FW_RFK                0xb
 
@@ -4585,6 +4586,17 @@ struct rtw89_fw_h2c_rfk_pre_info {
        __le32 mlo_1_1;
 } __packed;
 
+struct rtw89_fw_h2c_rfk_pre_info_mcc {
+       __le32 tbl_18[NUM_OF_RTW89_FW_RFK_TBL];
+       __le32 cur_18[NUM_OF_RTW89_FW_RFK_PATH];
+       __le32 mlo_mode;
+       __le32 mlo_1_1;
+       u8 phy_idx;
+       u8 tbl_idx;
+       u8 rsvd[2];
+       __le32 aid;
+} __packed;
+
 struct rtw89_h2c_rf_tssi {
        __le16 len;
        u8 phy;
@@ -4942,6 +4954,7 @@ 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_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
 int rtw89_fw_h2c_mcc_dig(struct rtw89_dev *rtwdev,
                         enum rtw89_chanctx_idx chanctx_idx,
                         u8 mcc_role_idx, u8 pd_val, bool en);
index 9f418b1fb7ed0b807ce25d5e3c49bbd04e02392b..d0e5d52964de576fef6d2c9e8d866c320a554094 100644 (file)
@@ -3808,6 +3808,12 @@ int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
 {
        int ret;
 
+       if (RTW89_CHK_FW_FEATURE(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
+               goto pre_ntfy;
+
+       return rtw89_fw_h2c_rf_pre_ntfy_mcc(rtwdev, phy_idx);
+
+pre_ntfy:
        rtw89_phy_rfk_report_prep(rtwdev);
 
        ret = rtw89_fw_h2c_rf_pre_ntfy(rtwdev, phy_idx);