OSDN Git Service

rtw88: coex: update BT PTA counter regularly
authorChing-Te Ku <ku920601@realtek.com>
Tue, 15 Feb 2022 00:48:52 +0000 (08:48 +0800)
committerKalle Valo <kvalo@kernel.org>
Mon, 21 Feb 2022 08:48:59 +0000 (10:48 +0200)
If BT PTA counter can not update regularly, it will lead coex mechanism
run into some unexpected state.

Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220215004855.4098-4-pkshih@realtek.com
drivers/net/wireless/realtek/rtw88/coex.c
drivers/net/wireless/realtek/rtw88/coex.h
drivers/net/wireless/realtek/rtw88/main.c

index 70adaee..0aca8f0 100644 (file)
@@ -460,6 +460,29 @@ static void rtw_coex_gnt_workaround(struct rtw_dev *rtwdev, bool force, u8 mode)
        rtw_coex_set_gnt_fix(rtwdev);
 }
 
+static void rtw_coex_monitor_bt_ctr(struct rtw_dev *rtwdev)
+{
+       struct rtw_coex *coex = &rtwdev->coex;
+       struct rtw_coex_stat *coex_stat = &coex->stat;
+       u32 tmp;
+
+       tmp = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS);
+       coex_stat->hi_pri_tx = FIELD_GET(MASKLWORD, tmp);
+       coex_stat->hi_pri_rx = FIELD_GET(MASKHWORD, tmp);
+
+       tmp = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS_1);
+       coex_stat->lo_pri_tx = FIELD_GET(MASKLWORD, tmp);
+       coex_stat->lo_pri_rx = FIELD_GET(MASKHWORD, tmp);
+
+       rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL,
+                  BIT_R_GRANTALL_WLMASK | BIT_STATIS_BT_EN);
+
+       rtw_dbg(rtwdev, RTW_DBG_COEX,
+               "[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n",
+               coex_stat->hi_pri_rx, coex_stat->hi_pri_tx,
+               coex_stat->lo_pri_rx, coex_stat->lo_pri_tx);
+}
+
 static void rtw_coex_monitor_bt_enable(struct rtw_dev *rtwdev)
 {
        struct rtw_chip_info *chip = rtwdev->chip;
@@ -3170,6 +3193,17 @@ void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev, u32 type)
        rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS);
 }
 
+void rtw_coex_wl_status_check(struct rtw_dev *rtwdev)
+{
+       struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
+
+       if ((coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl) ||
+           coex_stat->wl_under_ips)
+               return;
+
+       rtw_coex_monitor_bt_ctr(rtwdev);
+}
+
 void rtw_coex_bt_relink_work(struct work_struct *work)
 {
        struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
@@ -3653,7 +3687,6 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m)
        u16 score_board_WB, score_board_BW;
        u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc;
        u32 lte_coex, bt_coex;
-       u32 bt_hi_pri, bt_lo_pri;
        int i;
 
        score_board_BW = rtw_coex_read_scbd(rtwdev);
@@ -3664,17 +3697,6 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m)
        wl_reg_6cc = rtw_read32(rtwdev, REG_BT_COEX_TABLE_H);
        wl_reg_778 = rtw_read8(rtwdev, REG_BT_STAT_CTRL);
 
-       bt_hi_pri = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS);
-       bt_lo_pri = rtw_read32(rtwdev, REG_BT_ACT_STATISTICS_1);
-       rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL,
-                  BIT_R_GRANTALL_WLMASK | BIT_STATIS_BT_EN);
-
-       coex_stat->hi_pri_tx = FIELD_GET(MASKLWORD, bt_hi_pri);
-       coex_stat->hi_pri_rx = FIELD_GET(MASKHWORD, bt_hi_pri);
-
-       coex_stat->lo_pri_tx = FIELD_GET(MASKLWORD, bt_lo_pri);
-       coex_stat->lo_pri_rx = FIELD_GET(MASKHWORD, bt_lo_pri);
-
        sys_lte = rtw_read8(rtwdev, 0x73);
        lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38);
        bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54);
index fc61a0c..60a701c 100644 (file)
@@ -404,6 +404,7 @@ void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length);
 void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length);
 void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type);
 void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev, u32 type);
+void rtw_coex_wl_status_check(struct rtw_dev *rtwdev);
 void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m);
 
 static inline bool rtw_coex_disabled(struct rtw_dev *rtwdev)
index 41b6db4..da4657a 100644 (file)
@@ -207,6 +207,8 @@ static void rtw_watch_dog_work(struct work_struct *work)
        else
                clear_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
 
+       rtw_coex_wl_status_check(rtwdev);
+
        if (busy_traffic != test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags))
                rtw_coex_wl_status_change_notify(rtwdev, 0);