rtw89: add RF H2C to notify firmware
authorPing-Ke Shih <pkshih@realtek.com>
Thu, 21 Apr 2022 12:08:58 +0000 (20:08 +0800)
committerKalle Valo <kvalo@kernel.org>
Sun, 24 Apr 2022 11:30:35 +0000 (14:30 +0300)
IQK results in hardware has two copies that are used by firmware to switch
these two to support MCC.

This H2C tell firmware the corresponding channel and band of each IQK
results, and currrent one.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220421120903.73715-10-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/rtw8852c.c

index 6ca915cb7a29fceff564c11935bfa0cc4c9653a7..9be74d8673cfd77e45a840b9f599f74c47364782 100644 (file)
@@ -2634,6 +2634,13 @@ struct rtw89_dack_info {
 
 #define RTW89_IQK_CHS_NR 2
 #define RTW89_IQK_PATH_NR 4
+
+struct rtw89_mcc_info {
+       u8 ch[RTW89_IQK_CHS_NR];
+       u8 band[RTW89_IQK_CHS_NR];
+       u8 table_idx;
+};
+
 struct rtw89_iqk_info {
        bool lok_cor_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR];
        bool lok_fin_fail[RTW89_IQK_CHS_NR][RTW89_IQK_PATH_NR];
@@ -3105,6 +3112,7 @@ struct rtw89_dev {
        struct rtw89_dack_info dack;
        struct rtw89_iqk_info iqk;
        struct rtw89_dpk_info dpk;
+       struct rtw89_mcc_info mcc;
        bool is_tssi_mode[RF_PATH_MAX];
        bool is_bt_iqk_timeout;
 
index 7bef8b4288f0cf5bbf1b8492e119341f8ccaeb54..e4be785709d10fb8b34be57f1ab1fa4d69d23505 100644 (file)
@@ -1785,6 +1785,45 @@ fail:
        return -EBUSY;
 }
 
+int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
+       struct rtw89_fw_h2c_rf_get_mccch *mccch;
+       struct sk_buff *skb;
+
+       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, sizeof(*mccch));
+       if (!skb) {
+               rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl\n");
+               return -ENOMEM;
+       }
+       skb_put(skb, sizeof(*mccch));
+       mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data;
+
+       mccch->ch_0 = cpu_to_le32(mcc_info->ch[0]);
+       mccch->ch_1 = cpu_to_le32(mcc_info->ch[1]);
+       mccch->band_0 = cpu_to_le32(mcc_info->band[0]);
+       mccch->band_1 = cpu_to_le32(mcc_info->band[1]);
+       mccch->current_channel = cpu_to_le32(rtwdev->hal.current_channel);
+       mccch->current_band_type = cpu_to_le32(rtwdev->hal.current_band_type);
+
+       rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+                             H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
+                             H2C_FUNC_OUTSRC_RF_GET_MCCCH, 0, 0,
+                             sizeof(*mccch));
+
+       if (rtw89_h2c_tx(rtwdev, skb, false)) {
+               rtw89_err(rtwdev, "failed to send h2c\n");
+               goto fail;
+       }
+
+       return 0;
+fail:
+       dev_kfree_skb_any(skb);
+
+       return -EBUSY;
+}
+EXPORT_SYMBOL(rtw89_fw_h2c_rf_ntfy_mcc);
+
 int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
                              u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
                              bool rack, bool dack)
index aaabfc0dfd71392ec50dce4885048bfeb0a2594a..95a55c4213db3d9b2475b53b870a579127e9365e 100644 (file)
@@ -2538,6 +2538,17 @@ struct rtw89_fw_h2c_rf_reg_info {
 
 #define H2C_CL_OUTSRC_RF_REG_A         0x8
 #define H2C_CL_OUTSRC_RF_REG_B         0x9
+#define H2C_CL_OUTSRC_RF_FW_NOTIFY     0xa
+#define H2C_FUNC_OUTSRC_RF_GET_MCCCH   0x2
+
+struct rtw89_fw_h2c_rf_get_mccch {
+       __le32 ch_0;
+       __le32 ch_1;
+       __le32 band_0;
+       __le32 band_1;
+       __le32 current_channel;
+       __le32 current_band_type;
+} __packed;
 
 #define RTW89_FW_RSVD_PLE_SIZE 0x800
 
@@ -2602,6 +2613,7 @@ int rtw89_fw_h2c_scan_offload(struct rtw89_dev *rtwdev,
 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_raw_with_hdr(struct rtw89_dev *rtwdev,
                              u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
                              bool rack, bool dack);
index 1302d4324473e618850c17934368dcead667e783..3ee57df0a63961c2758b1dccb0b4df489a9fa925 100644 (file)
@@ -1766,6 +1766,18 @@ static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter,
        }
 }
 
+static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
+
+       memset(mcc_info, 0, sizeof(*mcc_info));
+}
+
+static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev)
+{
+       rtw89_fw_h2c_rf_ntfy_mcc(rtwdev);
+}
+
 static
 void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
                                     s8 pw_ofst, enum rtw89_mac_idx mac_idx)
@@ -1955,6 +1967,8 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
        .set_channel_help       = rtw8852c_set_channel_help,
        .read_efuse             = rtw8852c_read_efuse,
        .read_phycap            = rtw8852c_read_phycap,
+       .rfk_init               = rtw8852c_rfk_init,
+       .rfk_channel            = rtw8852c_rfk_channel,
        .power_trim             = rtw8852c_power_trim,
        .read_rf                = rtw89_phy_read_rf_v1,
        .write_rf               = rtw89_phy_write_rf_v1,