wifi: rtw89: 8922a: rfk: implement chip_ops to call RF calibrations
authorPing-Ke Shih <pkshih@realtek.com>
Fri, 2 Feb 2024 03:06:40 +0000 (11:06 +0800)
committerKalle Valo <kvalo@kernel.org>
Tue, 6 Feb 2024 18:05:23 +0000 (20:05 +0200)
Calling RF calibrations when interface up, connection, switching bands and
going to scan.

For 8922AE, RF calibrations are moved to firmware, so use H2C commands to
trigger RF calibrations and wait for a C2H event to indicate completion.
Then, do next RF calibration.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20240202030642.108385-10-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/coex.h
drivers/net/wireless/realtek/rtw89/phy.c
drivers/net/wireless/realtek/rtw89/phy.h
drivers/net/wireless/realtek/rtw89/rtw8922a.c

index 46e25c6f88a6fe18b10abd3f8caa36b795f173d8..08121fd899e68f4a767f8c2cbe2f453bb7e1b772 100644 (file)
@@ -23,6 +23,7 @@ enum btc_wl_rfk_type {
        BTC_WRFKT_DACK = 4,
        BTC_WRFKT_RXDCK = 5,
        BTC_WRFKT_TSSI = 6,
+       BTC_WRFKT_CHLK = 7,
 };
 
 #define NM_EXEC false
index 77b3b233697b50453ce1ec9b4e97c5191a00c03c..f02b365b0cecc19531a2900d11a69e2698606dec 100644 (file)
@@ -2834,6 +2834,7 @@ void (* const rtw89_phy_c2h_rfk_log_handler[])(struct rtw89_dev *rtwdev,
        [RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK] = rtw89_phy_c2h_rfk_log_txgapk,
 };
 
+static
 void rtw89_phy_rfk_report_prep(struct rtw89_dev *rtwdev)
 {
        struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait;
@@ -2843,6 +2844,7 @@ void rtw89_phy_rfk_report_prep(struct rtw89_dev *rtwdev)
        reinit_completion(&wait->completion);
 }
 
+static
 int rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, const char *rfk_name,
                              unsigned int ms)
 {
@@ -2959,6 +2961,119 @@ void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
        handler(rtwdev, skb, len);
 }
 
+int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
+                                   enum rtw89_phy_idx phy_idx,
+                                   unsigned int ms)
+{
+       int ret;
+
+       rtw89_phy_rfk_report_prep(rtwdev);
+
+       ret = rtw89_fw_h2c_rf_pre_ntfy(rtwdev, phy_idx);
+       if (ret)
+               return ret;
+
+       return rtw89_phy_rfk_report_wait(rtwdev, "PRE_NTFY", ms);
+}
+EXPORT_SYMBOL(rtw89_phy_rfk_pre_ntfy_and_wait);
+
+int rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev *rtwdev,
+                               enum rtw89_phy_idx phy_idx,
+                               enum rtw89_tssi_mode tssi_mode,
+                               unsigned int ms)
+{
+       int ret;
+
+       rtw89_phy_rfk_report_prep(rtwdev);
+
+       ret = rtw89_fw_h2c_rf_tssi(rtwdev, phy_idx, tssi_mode);
+       if (ret)
+               return ret;
+
+       return rtw89_phy_rfk_report_wait(rtwdev, "TSSI", ms);
+}
+EXPORT_SYMBOL(rtw89_phy_rfk_tssi_and_wait);
+
+int rtw89_phy_rfk_iqk_and_wait(struct rtw89_dev *rtwdev,
+                              enum rtw89_phy_idx phy_idx,
+                              unsigned int ms)
+{
+       int ret;
+
+       rtw89_phy_rfk_report_prep(rtwdev);
+
+       ret = rtw89_fw_h2c_rf_iqk(rtwdev, phy_idx);
+       if (ret)
+               return ret;
+
+       return rtw89_phy_rfk_report_wait(rtwdev, "IQK", ms);
+}
+EXPORT_SYMBOL(rtw89_phy_rfk_iqk_and_wait);
+
+int rtw89_phy_rfk_dpk_and_wait(struct rtw89_dev *rtwdev,
+                              enum rtw89_phy_idx phy_idx,
+                              unsigned int ms)
+{
+       int ret;
+
+       rtw89_phy_rfk_report_prep(rtwdev);
+
+       ret = rtw89_fw_h2c_rf_dpk(rtwdev, phy_idx);
+       if (ret)
+               return ret;
+
+       return rtw89_phy_rfk_report_wait(rtwdev, "DPK", ms);
+}
+EXPORT_SYMBOL(rtw89_phy_rfk_dpk_and_wait);
+
+int rtw89_phy_rfk_txgapk_and_wait(struct rtw89_dev *rtwdev,
+                                 enum rtw89_phy_idx phy_idx,
+                                 unsigned int ms)
+{
+       int ret;
+
+       rtw89_phy_rfk_report_prep(rtwdev);
+
+       ret = rtw89_fw_h2c_rf_txgapk(rtwdev, phy_idx);
+       if (ret)
+               return ret;
+
+       return rtw89_phy_rfk_report_wait(rtwdev, "TXGAPK", ms);
+}
+EXPORT_SYMBOL(rtw89_phy_rfk_txgapk_and_wait);
+
+int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev,
+                               enum rtw89_phy_idx phy_idx,
+                               unsigned int ms)
+{
+       int ret;
+
+       rtw89_phy_rfk_report_prep(rtwdev);
+
+       ret = rtw89_fw_h2c_rf_dack(rtwdev, phy_idx);
+       if (ret)
+               return ret;
+
+       return rtw89_phy_rfk_report_wait(rtwdev, "DACK", ms);
+}
+EXPORT_SYMBOL(rtw89_phy_rfk_dack_and_wait);
+
+int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev,
+                                enum rtw89_phy_idx phy_idx,
+                                unsigned int ms)
+{
+       int ret;
+
+       rtw89_phy_rfk_report_prep(rtwdev);
+
+       ret = rtw89_fw_h2c_rf_rxdck(rtwdev, phy_idx);
+       if (ret)
+               return ret;
+
+       return rtw89_phy_rfk_report_wait(rtwdev, "RX_DCK", ms);
+}
+EXPORT_SYMBOL(rtw89_phy_rfk_rxdck_and_wait);
+
 static u32 phy_tssi_get_cck_group(u8 ch)
 {
        switch (ch) {
index 459e919ddd243bdf5dddb0407c5b7761d1aac7b2..d80ddc723e8644d3a10bf6876b61ccc69924ed38 100644 (file)
@@ -885,9 +885,28 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
 bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func);
 void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
                          u32 len, u8 class, u8 func);
-void rtw89_phy_rfk_report_prep(struct rtw89_dev *rtwdev);
-int rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, const char *rfk_name,
-                             unsigned int ms);
+int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
+                                   enum rtw89_phy_idx phy_idx,
+                                   unsigned int ms);
+int rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev *rtwdev,
+                               enum rtw89_phy_idx phy_idx,
+                               enum rtw89_tssi_mode tssi_mode,
+                               unsigned int ms);
+int rtw89_phy_rfk_iqk_and_wait(struct rtw89_dev *rtwdev,
+                              enum rtw89_phy_idx phy_idx,
+                              unsigned int ms);
+int rtw89_phy_rfk_dpk_and_wait(struct rtw89_dev *rtwdev,
+                              enum rtw89_phy_idx phy_idx,
+                              unsigned int ms);
+int rtw89_phy_rfk_txgapk_and_wait(struct rtw89_dev *rtwdev,
+                                 enum rtw89_phy_idx phy_idx,
+                                 unsigned int ms);
+int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev,
+                               enum rtw89_phy_idx phy_idx,
+                               unsigned int ms);
+int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev,
+                                enum rtw89_phy_idx phy_idx,
+                                unsigned int ms);
 void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev,
                                               enum rtw89_phy_idx phy,
                                               const struct rtw89_chan *chan,
index aefad3f2e612f0757403155ee488894f2cd13623..69ae8f81181e4618bc896940d0d20178ae8aa966 100644 (file)
@@ -2,6 +2,7 @@
 /* Copyright(c) 2023  Realtek Corporation
  */
 
+#include "coex.h"
 #include "debug.h"
 #include "efuse.h"
 #include "fw.h"
@@ -1369,6 +1370,69 @@ void rtw8922a_hal_reset(struct rtw89_dev *rtwdev,
        }
 }
 
+static void rtw8922a_rfk_init(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
+
+       rtwdev->is_tssi_mode[RF_PATH_A] = false;
+       rtwdev->is_tssi_mode[RF_PATH_B] = false;
+       memset(rfk_mcc, 0, sizeof(*rfk_mcc));
+}
+
+static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
+{
+       u32 rf_mode;
+       u8 path;
+       int ret;
+
+       for (path = 0; path < RF_PATH_NUM_8922A; path++) {
+               if (!(kpath & BIT(path)))
+                       continue;
+
+               ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2,
+                                              2, 5000, false, rtwdev, path, 0x00,
+                                              RR_MOD_MASK);
+               rtw89_debug(rtwdev, RTW89_DBG_RFK,
+                           "[RFK] Wait S%d to Rx mode!! (ret = %d)\n",
+                           path, ret);
+       }
+}
+
+static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev)
+{
+       enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
+       u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB);
+       u32 tx_en;
+
+       rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_START);
+       rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
+       _wait_rx_mode(rtwdev, RF_AB);
+
+       rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
+       rtw89_phy_rfk_txgapk_and_wait(rtwdev, phy_idx, 54);
+       rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, 84);
+       rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, RTW89_TSSI_NORMAL, 6);
+       rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, 34);
+       rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, 32);
+
+       rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
+       rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_STOP);
+}
+
+static void rtw8922a_rfk_band_changed(struct rtw89_dev *rtwdev,
+                                     enum rtw89_phy_idx phy_idx)
+{
+       rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, RTW89_TSSI_SCAN, 6);
+}
+
+static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev, bool start)
+{
+}
+
+static void rtw8922a_rfk_track(struct rtw89_dev *rtwdev)
+{
+}
+
 static void rtw8922a_set_txpwr_ref(struct rtw89_dev *rtwdev,
                                   enum rtw89_phy_idx phy_idx)
 {
@@ -1622,6 +1686,11 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
        .read_phycap            = rtw8922a_read_phycap,
        .fem_setup              = NULL,
        .rfe_gpio               = NULL,
+       .rfk_init               = rtw8922a_rfk_init,
+       .rfk_channel            = rtw8922a_rfk_channel,
+       .rfk_band_changed       = rtw8922a_rfk_band_changed,
+       .rfk_scan               = rtw8922a_rfk_scan,
+       .rfk_track              = rtw8922a_rfk_track,
        .power_trim             = rtw8922a_power_trim,
        .set_txpwr              = rtw8922a_set_txpwr,
        .set_txpwr_ctrl         = rtw8922a_set_txpwr_ctrl,