The branch main has been updated by bz:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9c951734c28914f51b2fe2f2028272b572ade1ee

commit 9c951734c28914f51b2fe2f2028272b572ade1ee
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2022-06-13 13:57:42 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
CommitDate: 2022-06-13 13:57:42 +0000

    rtw88: update Realtek's rtw88 driver
    
    Update rtw88 based on wireless-testing at
    4e051428044d5c47cd2c81c3b154788efe07ee11 (tag: wt-2022-06-10).
    
    This is in preparation to apply USB changes to work on these and
    LinuxKPI for them over the next weeks, as well to debug a
    reported issue, and possibly extract and upstream some local fixes.
    
    MFC after:      3 days
---
 sys/contrib/dev/rtw88/coex.c           | 298 ++++++++++++++++++++++++++++++---
 sys/contrib/dev/rtw88/coex.h           |   5 +
 sys/contrib/dev/rtw88/debug.c          |  12 +-
 sys/contrib/dev/rtw88/debug.h          |   1 +
 sys/contrib/dev/rtw88/fw.c             | 100 ++++++++---
 sys/contrib/dev/rtw88/fw.h             |  14 +-
 sys/contrib/dev/rtw88/mac.c            |   2 +-
 sys/contrib/dev/rtw88/mac80211.c       |  63 +++++--
 sys/contrib/dev/rtw88/main.c           | 161 +++++++++++++-----
 sys/contrib/dev/rtw88/main.h           |  67 +++++++-
 sys/contrib/dev/rtw88/pci.c            |  19 ++-
 sys/contrib/dev/rtw88/phy.c            |   2 +-
 sys/contrib/dev/rtw88/reg.h            |   2 +
 sys/contrib/dev/rtw88/rtw8723d.c       |   4 +-
 sys/contrib/dev/rtw88/rtw8723d.h       |   2 +
 sys/contrib/dev/rtw88/rtw8723de.c      |   2 +-
 sys/contrib/dev/rtw88/rtw8723de.h      |  10 --
 sys/contrib/dev/rtw88/rtw8821c.c       |  25 ++-
 sys/contrib/dev/rtw88/rtw8821c.h       |   2 +
 sys/contrib/dev/rtw88/rtw8821c_table.c |   2 +-
 sys/contrib/dev/rtw88/rtw8821ce.c      |   6 +-
 sys/contrib/dev/rtw88/rtw8821ce.h      |  10 --
 sys/contrib/dev/rtw88/rtw8822b.c       |   8 +-
 sys/contrib/dev/rtw88/rtw8822b.h       |   2 +
 sys/contrib/dev/rtw88/rtw8822be.c      |   2 +-
 sys/contrib/dev/rtw88/rtw8822be.h      |  10 --
 sys/contrib/dev/rtw88/rtw8822c.c       |  50 ++++--
 sys/contrib/dev/rtw88/rtw8822c.h       |   2 +
 sys/contrib/dev/rtw88/rtw8822ce.c      |   2 +-
 sys/contrib/dev/rtw88/rtw8822ce.h      |  10 --
 sys/contrib/dev/rtw88/rx.c             |   3 +-
 sys/contrib/dev/rtw88/sar.c            |   8 +-
 sys/contrib/dev/rtw88/tx.c             |  19 ++-
 sys/contrib/dev/rtw88/tx.h             |   4 +
 34 files changed, 741 insertions(+), 188 deletions(-)

diff --git a/sys/contrib/dev/rtw88/coex.c b/sys/contrib/dev/rtw88/coex.c
index 2551e228b581..cac053f485c3 100644
--- a/sys/contrib/dev/rtw88/coex.c
+++ b/sys/contrib/dev/rtw88/coex.c
@@ -211,6 +211,10 @@ static void rtw_coex_wl_ccklock_detect(struct rtw_dev 
*rtwdev)
 
        bool is_cck_lock_rate = false;
 
+       if (coex_stat->wl_coex_mode != COEX_WLINK_2G1PORT &&
+           coex_stat->wl_coex_mode != COEX_WLINK_2GFREE)
+               return;
+
        if (coex_dm->bt_status == COEX_BTSTATUS_INQ_PAGE ||
            coex_stat->bt_setup_link) {
                coex_stat->wl_cck_lock = false;
@@ -460,6 +464,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;
@@ -780,7 +807,9 @@ static void rtw_coex_update_bt_link_info(struct rtw_dev 
*rtwdev)
 static void rtw_coex_update_wl_ch_info(struct rtw_dev *rtwdev, u8 type)
 {
        struct rtw_chip_info *chip = rtwdev->chip;
+       struct rtw_efuse *efuse = &rtwdev->efuse;
        struct rtw_coex_dm *coex_dm = &rtwdev->coex.dm;
+       struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
        u8 link = 0;
        u8 center_chan = 0;
        u8 bw;
@@ -791,7 +820,9 @@ static void rtw_coex_update_wl_ch_info(struct rtw_dev 
*rtwdev, u8 type)
        if (type != COEX_MEDIA_DISCONNECT)
                center_chan = rtwdev->hal.current_channel;
 
-       if (center_chan == 0) {
+       if (center_chan == 0 ||
+           (efuse->share_ant && center_chan <= 14 &&
+            coex_stat->wl_coex_mode != COEX_WLINK_2GFREE)) {
                link = 0;
                center_chan = 0;
                bw = 0;
@@ -930,6 +961,23 @@ static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 
state)
        rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state);
 }
 
+static void rtw_coex_mimo_ps(struct rtw_dev *rtwdev, bool force, bool state)
+{
+       struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
+
+       if (!force && state == coex_stat->wl_mimo_ps)
+               return;
+
+       coex_stat->wl_mimo_ps = state;
+
+       rtw_set_txrx_1ss(rtwdev, state);
+
+       rtw_coex_update_wl_ch_info(rtwdev, (u8)coex_stat->wl_connected);
+
+       rtw_dbg(rtwdev, RTW_DBG_COEX,
+               "[BTCoex], %s(): state = %d\n", __func__, state);
+}
+
 static void rtw_btc_wltoggle_table_a(struct rtw_dev *rtwdev, bool force,
                                     u8 table_case)
 {
@@ -1106,7 +1154,8 @@ static void rtw_coex_set_tdma(struct rtw_dev *rtwdev, u8 
byte1, u8 byte2,
 
                ps_type = COEX_PS_WIFI_NATIVE;
                rtw_coex_power_save_state(rtwdev, ps_type, 0x0, 0x0);
-       } else if (byte1 & BIT(4) && !(byte1 & BIT(5))) {
+       } else if ((byte1 & BIT(4) && !(byte1 & BIT(5))) ||
+                  coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) {
                rtw_dbg(rtwdev, RTW_DBG_COEX,
                        "[BTCoex], %s(): Force LPS (byte1 = 0x%x)\n", __func__,
                        byte1);
@@ -1802,6 +1851,54 @@ static void rtw_coex_action_bt_inquiry(struct rtw_dev 
*rtwdev)
        rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
 }
 
+static void rtw_coex_action_bt_game_hid(struct rtw_dev *rtwdev)
+{
+       struct rtw_coex *coex = &rtwdev->coex;
+       struct rtw_coex_stat *coex_stat = &coex->stat;
+       struct rtw_efuse *efuse = &rtwdev->efuse;
+       struct rtw_coex_dm *coex_dm = &coex->dm;
+       struct rtw_chip_info *chip = rtwdev->chip;
+       u8 table_case, tdma_case;
+
+       rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
+       rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
+
+       if (efuse->share_ant) {
+               coex_stat->wl_coex_mode = COEX_WLINK_2GFREE;
+               if (coex_stat->bt_whck_test)
+                       table_case = 2;
+               else if (coex_stat->wl_linkscan_proc || coex_stat->bt_hid_exist)
+                       table_case = 33;
+               else if (coex_stat->bt_setup_link || coex_stat->bt_inq_page)
+                       table_case = 0;
+               else if (coex_stat->bt_a2dp_exist)
+                       table_case = 34;
+               else
+                       table_case = 33;
+
+               tdma_case = 0;
+       } else {
+               if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1]))
+                       tdma_case = 112;
+               else
+                       tdma_case = 113;
+
+               table_case = 121;
+       }
+
+       if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) {
+               if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX)
+                       rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_tx[6]);
+               else
+                       rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[5]);
+       } else {
+               rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
+       }
+
+       rtw_coex_table(rtwdev, false, table_case);
+       rtw_coex_tdma(rtwdev, false, tdma_case);
+}
+
 static void rtw_coex_action_bt_hfp(struct rtw_dev *rtwdev)
 {
        struct rtw_coex *coex = &rtwdev->coex;
@@ -1816,13 +1913,8 @@ static void rtw_coex_action_bt_hfp(struct rtw_dev 
*rtwdev)
 
        if (efuse->share_ant) {
                /* Shared-Ant */
-               if (coex_stat->bt_multi_link) {
-                       table_case = 10;
-                       tdma_case = 17;
-               } else {
-                       table_case = 10;
-                       tdma_case = 5;
-               }
+               table_case = 10;
+               tdma_case = 5;
        } else {
                /* Non-Shared-Ant */
                if (coex_stat->bt_multi_link) {
@@ -2224,8 +2316,10 @@ static void rtw_coex_action_bt_a2dp_pan_hid(struct 
rtw_dev *rtwdev)
 
 static void rtw_coex_action_wl_under5g(struct rtw_dev *rtwdev)
 {
+       struct rtw_coex *coex = &rtwdev->coex;
        struct rtw_efuse *efuse = &rtwdev->efuse;
        struct rtw_chip_info *chip = rtwdev->chip;
+       struct rtw_coex_stat *coex_stat = &coex->stat;
        u8 table_case, tdma_case;
 
        rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
@@ -2235,6 +2329,9 @@ static void rtw_coex_action_wl_under5g(struct rtw_dev 
*rtwdev)
 
        rtw_coex_write_scbd(rtwdev, COEX_SCBD_FIX2M, false);
 
+       if (coex_stat->bt_game_hid_exist && coex_stat->wl_linkscan_proc)
+               coex_stat->wl_coex_mode = COEX_WLINK_2GFREE;
+
        if (efuse->share_ant) {
                /* Shared-Ant */
                table_case = 0;
@@ -2278,6 +2375,7 @@ static void rtw_coex_action_wl_native_lps(struct rtw_dev 
*rtwdev)
        struct rtw_coex *coex = &rtwdev->coex;
        struct rtw_efuse *efuse = &rtwdev->efuse;
        struct rtw_chip_info *chip = rtwdev->chip;
+       struct rtw_coex_stat *coex_stat = &coex->stat;
        u8 table_case, tdma_case;
 
        if (coex->under_5g)
@@ -2286,7 +2384,6 @@ static void rtw_coex_action_wl_native_lps(struct rtw_dev 
*rtwdev)
        rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
 
        rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
-       rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
 
        if (efuse->share_ant) {
                /* Shared-Ant */
@@ -2298,6 +2395,16 @@ static void rtw_coex_action_wl_native_lps(struct rtw_dev 
*rtwdev)
                tdma_case = 100;
        }
 
+       if (coex_stat->bt_game_hid_exist) {
+               coex_stat->wl_coex_mode = COEX_WLINK_2GFREE;
+               if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX)
+                       rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_tx[6]);
+               else
+                       rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[5]);
+       } else {
+               rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
+       }
+
        rtw_coex_table(rtwdev, false, table_case);
        rtw_coex_tdma(rtwdev, false, tdma_case);
 }
@@ -2422,6 +2529,7 @@ static void rtw_coex_action_wl_connected(struct rtw_dev 
*rtwdev)
 static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 reason)
 {
        struct rtw_coex *coex = &rtwdev->coex;
+       struct rtw_chip_info *chip = rtwdev->chip;
        struct rtw_coex_dm *coex_dm = &coex->dm;
        struct rtw_coex_stat *coex_stat = &coex->stat;
        bool rf4ce_en = false;
@@ -2494,6 +2602,11 @@ static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 
reason)
                goto exit;
        }
 
+       if (coex_stat->bt_game_hid_exist && coex_stat->wl_connected) {
+               rtw_coex_action_bt_game_hid(rtwdev);
+               goto exit;
+       }
+
        if (coex_stat->bt_whck_test) {
                rtw_coex_action_bt_whql_test(rtwdev);
                goto exit;
@@ -2530,6 +2643,18 @@ static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 
reason)
        }
 
 exit:
+
+       if (chip->wl_mimo_ps_support) {
+               if (coex_stat->wl_coex_mode == COEX_WLINK_2GFREE) {
+                       if (coex_dm->reason == COEX_RSN_2GMEDIA)
+                               rtw_coex_mimo_ps(rtwdev, true, true);
+                       else
+                               rtw_coex_mimo_ps(rtwdev, false, true);
+               } else {
+                       rtw_coex_mimo_ps(rtwdev, false, false);
+               }
+       }
+
        rtw_coex_gnt_workaround(rtwdev, false, coex_stat->wl_coex_mode);
        rtw_coex_limited_wl(rtwdev);
 }
@@ -3139,6 +3264,135 @@ void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 
*buf, u8 length)
        rtw_coex_run_coex(rtwdev, COEX_RSN_BTINFO);
 }
 
+#define COEX_BT_HIDINFO_MTK    0x46
+static const u8 coex_bt_hidinfo_ps[] = {0x57, 0x69, 0x72};
+static const u8 coex_bt_hidinfo_xb[] = {0x58, 0x62, 0x6f};
+
+void rtw_coex_bt_hid_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length)
+{
+       struct rtw_coex *coex = &rtwdev->coex;
+       struct rtw_chip_info *chip = rtwdev->chip;
+       struct rtw_coex_stat *coex_stat = &coex->stat;
+       struct rtw_coex_hid *hidinfo;
+       struct rtw_coex_hid_info_a *hida;
+       struct rtw_coex_hid_handle_list *hl, *bhl;
+       u8 sub_id = buf[2], gamehid_cnt = 0, handle, i;
+       bool cur_game_hid_exist, complete;
+
+       if (!chip->wl_mimo_ps_support &&
+           (sub_id == COEX_BT_HIDINFO_LIST || sub_id == COEX_BT_HIDINFO_A))
+               return;
+
+       rtw_dbg(rtwdev, RTW_DBG_COEX,
+               "[BTCoex], HID info notify, sub_id = 0x%x\n", sub_id);
+
+       switch (sub_id) {
+       case COEX_BT_HIDINFO_LIST:
+               hl = &coex_stat->hid_handle_list;
+               bhl = (struct rtw_coex_hid_handle_list *)buf;
+               if (!memcmp(hl, bhl, sizeof(*hl)))
+                       return;
+               coex_stat->hid_handle_list = *bhl;
+               memset(&coex_stat->hid_info, 0, sizeof(coex_stat->hid_info));
+               for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) {
+                       hidinfo = &coex_stat->hid_info[i];
+                       if (hl->handle[i] != COEX_BT_HIDINFO_NOTCON &&
+                           hl->handle[i] != 0)
+                               hidinfo->hid_handle = hl->handle[i];
+               }
+               break;
+       case COEX_BT_HIDINFO_A:
+               hida = (struct rtw_coex_hid_info_a *)buf;
+               handle = hida->handle;
+               for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) {
+                       hidinfo = &coex_stat->hid_info[i];
+                       if (hidinfo->hid_handle == handle) {
+                               hidinfo->hid_vendor = hida->vendor;
+                               memcpy(hidinfo->hid_name, hida->name,
+                                      sizeof(hidinfo->hid_name));
+                               hidinfo->hid_info_completed = true;
+                               break;
+                       }
+               }
+               break;
+       }
+       for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) {
+               hidinfo = &coex_stat->hid_info[i];
+               complete = hidinfo->hid_info_completed;
+               handle = hidinfo->hid_handle;
+               if (!complete || handle == COEX_BT_HIDINFO_NOTCON ||
+                   handle == 0 || handle >= COEX_BT_BLE_HANDLE_THRS) {
+                       hidinfo->is_game_hid = false;
+                       continue;
+               }
+
+               if (hidinfo->hid_vendor == COEX_BT_HIDINFO_MTK) {
+                       if ((memcmp(hidinfo->hid_name,
+                                   coex_bt_hidinfo_ps,
+                                   COEX_BT_HIDINFO_NAME)) == 0)
+                               hidinfo->is_game_hid = true;
+                       else if ((memcmp(hidinfo->hid_name,
+                                        coex_bt_hidinfo_xb,
+                                        COEX_BT_HIDINFO_NAME)) == 0)
+                               hidinfo->is_game_hid = true;
+                       else
+                               hidinfo->is_game_hid = false;
+               } else {
+                       hidinfo->is_game_hid = false;
+               }
+               if (hidinfo->is_game_hid)
+                       gamehid_cnt++;
+       }
+
+       if (gamehid_cnt > 0)
+               cur_game_hid_exist = true;
+       else
+               cur_game_hid_exist = false;
+
+       if (cur_game_hid_exist != coex_stat->bt_game_hid_exist) {
+               coex_stat->bt_game_hid_exist = cur_game_hid_exist;
+               rtw_dbg(rtwdev, RTW_DBG_COEX,
+                       "[BTCoex], HID info changed!bt_game_hid_exist = %d!\n",
+                       coex_stat->bt_game_hid_exist);
+               rtw_coex_run_coex(rtwdev, COEX_RSN_BTSTATUS);
+       }
+}
+
+void rtw_coex_query_bt_hid_list(struct rtw_dev *rtwdev)
+{
+       struct rtw_coex *coex = &rtwdev->coex;
+       struct rtw_chip_info *chip = rtwdev->chip;
+       struct rtw_coex_stat *coex_stat = &coex->stat;
+       struct rtw_coex_hid *hidinfo;
+       u8 i, handle;
+       bool complete;
+
+       if (!chip->wl_mimo_ps_support || coex_stat->wl_under_ips ||
+           (coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl))
+               return;
+
+       if (!coex_stat->bt_hid_exist &&
+           !((coex_stat->bt_info_lb2 & COEX_INFO_CONNECTION) &&
+             (coex_stat->hi_pri_tx + coex_stat->hi_pri_rx >
+              COEX_BT_GAMEHID_CNT)))
+               return;
+
+       rtw_fw_coex_query_hid_info(rtwdev, COEX_BT_HIDINFO_LIST, 0);
+
+       for (i = 0; i < COEX_BT_HIDINFO_HANDLE_NUM; i++) {
+               hidinfo = &coex_stat->hid_info[i];
+               complete = hidinfo->hid_info_completed;
+               handle = hidinfo->hid_handle;
+               if (handle == 0 || handle == COEX_BT_HIDINFO_NOTCON ||
+                   handle >= COEX_BT_BLE_HANDLE_THRS || complete)
+                       continue;
+
+               rtw_fw_coex_query_hid_info(rtwdev,
+                                          COEX_BT_HIDINFO_A,
+                                          handle);
+       }
+}
+
 void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length)
 {
        struct rtw_coex *coex = &rtwdev->coex;
@@ -3175,6 +3429,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,
@@ -3637,6 +3902,7 @@ static const char *rtw_coex_get_wl_coex_mode(u8 
coex_wl_link_mode)
        switch (coex_wl_link_mode) {
        case_WLINK(2G1PORT);
        case_WLINK(5G);
+       case_WLINK(2GFREE);
        default:
                return "Unknown";
        }
@@ -3658,7 +3924,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);
@@ -3669,17 +3934,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);
diff --git a/sys/contrib/dev/rtw88/coex.h b/sys/contrib/dev/rtw88/coex.h
index fc61a0cab3e4..07fa7aa34d4b 100644
--- a/sys/contrib/dev/rtw88/coex.h
+++ b/sys/contrib/dev/rtw88/coex.h
@@ -11,6 +11,7 @@
 
 #define COEX_MIN_DELAY         10 /* delay unit in ms */
 #define COEX_RFK_TIMEOUT       600 /* RFK timeout in ms */
+#define COEX_BT_GAMEHID_CNT    800
 
 #define COEX_RF_OFF    0x0
 #define COEX_RF_ON     0x1
@@ -172,6 +173,7 @@ enum coex_bt_profile {
 enum coex_wl_link_mode {
        COEX_WLINK_2G1PORT      = 0x0,
        COEX_WLINK_5G           = 0x3,
+       COEX_WLINK_2GFREE       = 0x7,
        COEX_WLINK_MAX
 };
 
@@ -401,9 +403,12 @@ void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type);
 void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 type);
 void rtw_coex_media_status_notify(struct rtw_dev *rtwdev, u8 type);
 void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length);
+void rtw_coex_bt_hid_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_query_bt_hid_list(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)
diff --git a/sys/contrib/dev/rtw88/debug.c b/sys/contrib/dev/rtw88/debug.c
index ff00c739d5e2..7b6319c07b65 100644
--- a/sys/contrib/dev/rtw88/debug.c
+++ b/sys/contrib/dev/rtw88/debug.c
@@ -269,11 +269,7 @@ static int rtw_debugfs_get_rsvd_page(struct seq_file *m, 
void *v)
        for (i = 0 ; i < buf_size ; i += 8) {
                if (i % page_size == 0)
                        seq_printf(m, "PAGE %d\n", (i + offset) / page_size);
-               seq_printf(m, "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x 
%2.2x\n",
-                          *(buf + i), *(buf + i + 1),
-                          *(buf + i + 2), *(buf + i + 3),
-                          *(buf + i + 4), *(buf + i + 5),
-                          *(buf + i + 6), *(buf + i + 7));
+               seq_printf(m, "%8ph\n", buf + i);
        }
        vfree(buf);
 
@@ -390,7 +386,7 @@ static ssize_t rtw_debugfs_set_h2c(struct file *filp,
                     &param[0], &param[1], &param[2], &param[3],
                     &param[4], &param[5], &param[6], &param[7]);
        if (num != 8) {
-               rtw_info(rtwdev, "invalid H2C command format for debug\n");
+               rtw_warn(rtwdev, "invalid H2C command format for debug\n");
                return -EINVAL;
        }
 
@@ -715,8 +711,10 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, 
void *v)
        seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel);
        seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width);
        seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]);
-       seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n\n",
+       seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n",
                   stats->tx_throughput, stats->rx_throughput);
+       seq_printf(m, "1SS for TX and RX = %c\n\n", rtwdev->hal.txrx_1ss ?
+                  'Y' : 'N');
 
        seq_puts(m, "==========[Tx Phy Info]========\n");
        seq_puts(m, "[Tx Rate] = ");
diff --git a/sys/contrib/dev/rtw88/debug.h b/sys/contrib/dev/rtw88/debug.h
index 5e546c235784..7bf59d3dfd5a 100644
--- a/sys/contrib/dev/rtw88/debug.h
+++ b/sys/contrib/dev/rtw88/debug.h
@@ -23,6 +23,7 @@ enum rtw_debug_mask {
        RTW_DBG_PATH_DIV        = 0x00004000,
        RTW_DBG_ADAPTIVITY      = 0x00008000,
        RTW_DBG_HW_SCAN         = 0x00010000,
+       RTW_DBG_STATE           = 0x00020000,
 
 #if defined(__FreeBSD__)
        RTW_DBG_IO_RW           = 0x80000000,
diff --git a/sys/contrib/dev/rtw88/fw.c b/sys/contrib/dev/rtw88/fw.c
index e1837ea6a13c..44b03f5a4769 100644
--- a/sys/contrib/dev/rtw88/fw.c
+++ b/sys/contrib/dev/rtw88/fw.c
@@ -233,6 +233,9 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct 
sk_buff *skb)
        case C2H_BT_INFO:
                rtw_coex_bt_info_notify(rtwdev, c2h->payload, len);
                break;
+       case C2H_BT_HID_INFO:
+               rtw_coex_bt_hid_info_notify(rtwdev, c2h->payload, len);
+               break;
        case C2H_WLAN_INFO:
                rtw_coex_wl_fwdbginfo_notify(rtwdev, c2h->payload, len);
                break;
@@ -538,6 +541,18 @@ void rtw_fw_coex_tdma_type(struct rtw_dev *rtwdev,
        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 }
 
+void rtw_fw_coex_query_hid_info(struct rtw_dev *rtwdev, u8 sub_id, u8 data)
+{
+       u8 h2c_pkt[H2C_PKT_SIZE] = {0};
+
+       SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_QUERY_BT_HID_INFO);
+
+       SET_COEX_QUERY_HID_INFO_SUBID(h2c_pkt, sub_id);
+       SET_COEX_QUERY_HID_INFO_DATA1(h2c_pkt, data);
+
+       rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
+}
+
 void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data)
 {
        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
@@ -570,10 +585,10 @@ void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct 
rtw_sta_info *si)
        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 }
 
-void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
+void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
+                        bool reset_ra_mask)
 {
        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
-       bool no_update = si->updated;
        bool disable_pt = true;
 
        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO);
@@ -584,7 +599,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct 
rtw_sta_info *si)
        SET_RA_INFO_SGI_EN(h2c_pkt, si->sgi_enable);
        SET_RA_INFO_BW_MODE(h2c_pkt, si->bw_mode);
        SET_RA_INFO_LDPC(h2c_pkt, !!si->ldpc_en);
-       SET_RA_INFO_NO_UPDATE(h2c_pkt, no_update);
+       SET_RA_INFO_NO_UPDATE(h2c_pkt, !reset_ra_mask);
        SET_RA_INFO_VHT_EN(h2c_pkt, si->vht_enable);
        SET_RA_INFO_DIS_PT(h2c_pkt, disable_pt);
        SET_RA_INFO_RA_MASK0(h2c_pkt, (si->ra_mask & 0xff));
@@ -593,7 +608,6 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct 
rtw_sta_info *si)
        SET_RA_INFO_RA_MASK3(h2c_pkt, (si->ra_mask & 0xff000000) >> 24);
 
        si->init_ra_lv = 0;
-       si->updated = true;
 
        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 }
@@ -635,7 +649,7 @@ void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, 
bool connect,
        s32 threshold = bss_conf->cqm_rssi_thold + rssi_offset;
        u8 h2c_pkt[H2C_PKT_SIZE] = {0};
 
-       if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !si)
+       if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER))
                return;
 
        if (!connect) {
@@ -645,6 +659,10 @@ void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, 
bool connect,
 
                return;
        }
+
+       if (!si)
+               return;
+
        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_BCN_FILTER_OFFLOAD_P0);
        ether_addr_copy(&h2c_pkt[1], bss_conf->bssid);
        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
@@ -1033,6 +1051,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct 
ieee80211_hw *hw,
        struct rtw_vif *rtwvif;
        struct sk_buff *skb_new;
        struct cfg80211_ssid *ssid;
+       u16 tim_offset = 0;
 
        if (rsvd_pkt->type == RSVD_DUMMY) {
                skb_new = alloc_skb(1, GFP_KERNEL);
@@ -1051,7 +1070,8 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct 
ieee80211_hw *hw,
 
        switch (rsvd_pkt->type) {
        case RSVD_BEACON:
-               skb_new = ieee80211_beacon_get(hw, vif);
+               skb_new = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL);
+               rsvd_pkt->tim_offset = tim_offset;
                break;
        case RSVD_PS_POLL:
                skb_new = ieee80211_pspoll_get(hw, vif);
@@ -1582,6 +1602,16 @@ free:
        return ret;
 }
 
+void rtw_fw_update_beacon_work(struct work_struct *work)
+{
+       struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
+                                             update_beacon_work);
+
+       mutex_lock(&rtwdev->mutex);
+       rtw_fw_download_rsvd_page(rtwdev);
+       mutex_unlock(&rtwdev->mutex);
+}
+
 static void rtw_fw_read_fifo_page(struct rtw_dev *rtwdev, u32 offset, u32 size,
                                  u32 *buf, u32 residue, u16 start_pg)
 {
@@ -1766,7 +1796,7 @@ void rtw_fw_adaptivity(struct rtw_dev *rtwdev)
 
        SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_ADAPTIVITY);
        SET_ADAPTIVITY_MODE(h2c_pkt, dm_info->edcca_mode);
-       SET_ADAPTIVITY_OPTION(h2c_pkt, 2);
+       SET_ADAPTIVITY_OPTION(h2c_pkt, 1);
        SET_ADAPTIVITY_IGI(h2c_pkt, dm_info->igi_history[0]);
        SET_ADAPTIVITY_L2H(h2c_pkt, dm_info->l2h_th_ini);
        SET_ADAPTIVITY_DENSITY(h2c_pkt, dm_info->scan_density);
@@ -1784,9 +1814,9 @@ void rtw_fw_scan_notify(struct rtw_dev *rtwdev, bool 
start)
        rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
 }
 
-static void rtw_append_probe_req_ie(struct rtw_dev *rtwdev, struct sk_buff 
*skb,
-                                   struct sk_buff_head *list,
-                                   struct rtw_vif *rtwvif)
+static int rtw_append_probe_req_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
+                                  struct sk_buff_head *list, u8 *bands,
+                                  struct rtw_vif *rtwvif)
 {
        struct ieee80211_scan_ies *ies = rtwvif->scan_ies;
        struct rtw_chip_info *chip = rtwdev->chip;
@@ -1797,19 +1827,24 @@ static void rtw_append_probe_req_ie(struct rtw_dev 
*rtwdev, struct sk_buff *skb,
                if (!(BIT(idx) & chip->band))
                        continue;
                new = skb_copy(skb, GFP_KERNEL);
+               if (!new)
+                       return -ENOMEM;
                skb_put_data(new, ies->ies[idx], ies->len[idx]);
                skb_put_data(new, ies->common_ies, ies->common_ie_len);
                skb_queue_tail(list, new);
+               (*bands)++;
        }
+
+       return 0;
 }
 
-static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_ssids,
+static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_probes,
                                         struct sk_buff_head *probe_req_list)
 {
        struct rtw_chip_info *chip = rtwdev->chip;
        struct sk_buff *skb, *tmp;
        u8 page_offset = 1, *buf, page_size = chip->page_size;
-       u8 pages = page_offset + num_ssids * RTW_PROBE_PG_CNT;
+       u8 pages = page_offset + num_probes * RTW_PROBE_PG_CNT;
        u16 pg_addr = rtwdev->fifo.rsvd_h2c_info_addr, loc;
        u16 buf_offset = page_size * page_offset;
        u8 tx_desc_sz = chip->tx_pkt_desc_sz;
@@ -1851,6 +1886,8 @@ static int _rtw_hw_scan_update_probe_req(struct rtw_dev 
*rtwdev, u8 num_ssids,
        rtwdev->scan_info.probe_pg_size = page_offset;
 out:
        kfree(buf);
+       skb_queue_walk_safe(probe_req_list, skb, tmp)
+               kfree_skb(skb);
 
        return ret;
 }
@@ -1860,8 +1897,9 @@ static int rtw_hw_scan_update_probe_req(struct rtw_dev 
*rtwdev,
 {
        struct cfg80211_scan_request *req = rtwvif->scan_req;
        struct sk_buff_head list;
-       struct sk_buff *skb;
-       u8 num = req->n_ssids, i;
+       struct sk_buff *skb, *tmp;
+       u8 num = req->n_ssids, i, bands = 0;
+       int ret;
 
        skb_queue_head_init(&list);
        for (i = 0; i < num; i++) {
@@ -1869,11 +1907,25 @@ static int rtw_hw_scan_update_probe_req(struct rtw_dev 
*rtwdev,
                                             req->ssids[i].ssid,
                                             req->ssids[i].ssid_len,
                                             req->ie_len);
-               rtw_append_probe_req_ie(rtwdev, skb, &list, rtwvif);
+               if (!skb) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               ret = rtw_append_probe_req_ie(rtwdev, skb, &list, &bands,
+                                             rtwvif);
+               if (ret)
+                       goto out;
+
                kfree_skb(skb);
        }
 
-       return _rtw_hw_scan_update_probe_req(rtwdev, num, &list);
+       return _rtw_hw_scan_update_probe_req(rtwdev, num * bands, &list);
+
+out:
+       skb_queue_walk_safe(&list, skb, tmp)
+               kfree_skb(skb);
+
+       return ret;
 }
 
 static int rtw_add_chan_info(struct rtw_dev *rtwdev, struct rtw_chan_info 
*info,
@@ -2017,7 +2069,10 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct 
ieee80211_vif *vif,
        struct cfg80211_scan_info info = {
                .aborted = aborted,
        };
+       struct rtw_hw_scan_info *scan_info = &rtwdev->scan_info;
+       struct rtw_hal *hal = &rtwdev->hal;
        struct rtw_vif *rtwvif;
+       u8 chan = scan_info->op_chan;
 
        if (!vif)
                return;
@@ -2025,12 +2080,16 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, 
struct ieee80211_vif *vif,
        rtwdev->hal.rcr |= BIT_CBSSID_BCN;
        rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
 
-       rtw_core_scan_complete(rtwdev, vif);
+       rtw_core_scan_complete(rtwdev, vif, true);
 
+       rtwvif = (struct rtw_vif *)vif->drv_priv;
+       if (rtwvif->net_type == RTW_NET_MGD_LINKED) {
+               hal->current_channel = chan;
+               hal->current_band_type = chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
+       }
        ieee80211_wake_queues(rtwdev->hw);
        ieee80211_scan_completed(rtwdev->hw, &info);
 
-       rtwvif = (struct rtw_vif *)vif->drv_priv;
        rtwvif->scan_req = NULL;
        rtwvif->scan_ies = NULL;
        rtwdev->scan_info.scanning_vif = NULL;
@@ -2112,7 +2171,7 @@ void rtw_hw_scan_status_report(struct rtw_dev *rtwdev, 
struct sk_buff *skb)
        rtw_hw_scan_complete(rtwdev, vif, aborted);
 
        if (aborted)
-               rtw_info(rtwdev, "HW scan aborted with code: %d\n", rc);
+               rtw_dbg(rtwdev, RTW_DBG_HW_SCAN, "HW scan aborted with code: 
%d\n", rc);
 }
 
 void rtw_store_op_chan(struct rtw_dev *rtwdev)
@@ -2139,6 +2198,9 @@ void rtw_hw_scan_chan_switch(struct rtw_dev *rtwdev, 
struct sk_buff *skb)
        enum rtw_scan_notify_id id;
        u8 chan, status;
 
+       if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
+               return;
+
        c2h = get_c2h_from_skb(skb);
        chan = GET_CHAN_SWITCH_CENTRAL_CH(c2h->payload);
        id = GET_CHAN_SWITCH_ID(c2h->payload);
diff --git a/sys/contrib/dev/rtw88/fw.h b/sys/contrib/dev/rtw88/fw.h
index 654c3c2e5721..7a37675c61e8 100644
--- a/sys/contrib/dev/rtw88/fw.h
+++ b/sys/contrib/dev/rtw88/fw.h
@@ -47,6 +47,7 @@ enum rtw_c2h_cmd_id {
        C2H_CCX_TX_RPT = 0x03,
        C2H_BT_INFO = 0x09,
        C2H_BT_MP_INFO = 0x0b,
+       C2H_BT_HID_INFO = 0x45,
        C2H_RA_RPT = 0x0c,
        C2H_HW_FEATURE_REPORT = 0x19,
        C2H_WLAN_INFO = 0x27,
@@ -171,6 +172,7 @@ struct rtw_rsvd_page {
        struct sk_buff *skb;
        enum rtw_rsvd_packet_type type;
        u8 page;
+       u16 tim_offset;
        bool add_txdesc;
        struct cfg80211_ssid *ssid;
        u16 probe_req_size;
@@ -529,6 +531,7 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 
sub_id)
 #define H2C_CMD_QUERY_BT_MP_INFO       0x67
 #define H2C_CMD_BT_WIFI_CONTROL                0x69
 #define H2C_CMD_WIFI_CALIBRATION       0x6d
+#define H2C_CMD_QUERY_BT_HID_INFO      0x73
 
 #define H2C_CMD_KEEP_ALIVE             0x03
 #define H2C_CMD_DISCONNECT_DECISION    0x04
@@ -681,6 +684,11 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 
sub_id)
 #define SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, value)                              
\
        le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(23, 16))
 
+#define SET_COEX_QUERY_HID_INFO_SUBID(h2c_pkt, value)                          
\
+       le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8))
+#define SET_COEX_QUERY_HID_INFO_DATA1(h2c_pkt, value)                          
\
+       le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))
+
 #define SET_KEEP_ALIVE_ENABLE(h2c_pkt, value)                                 \
        le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))
 #define SET_KEEP_ALIVE_ADOPT(h2c_pkt, value)                                  \
@@ -780,9 +788,12 @@ void rtw_fw_force_bt_tx_power(struct rtw_dev *rtwdev, u8 
bt_pwr_dec_lvl);
 void rtw_fw_bt_ignore_wlan_action(struct rtw_dev *rtwdev, bool enable);
 void rtw_fw_coex_tdma_type(struct rtw_dev *rtwdev,
                           u8 para1, u8 para2, u8 para3, u8 para4, u8 para5);
+void rtw_fw_coex_query_hid_info(struct rtw_dev *rtwdev, u8 sub_id, u8 data);
+
 void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data);
 void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);
-void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);
+void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
+                        bool reset_ra_mask);
 void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool conn);
 void rtw_fw_update_wl_phy_info(struct rtw_dev *rtwdev);
 void rtw_fw_beacon_filter_config(struct rtw_dev *rtwdev, bool connect,
@@ -798,6 +809,7 @@ void rtw_add_rsvd_page_pno(struct rtw_dev *rtwdev,
 void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev,
                           struct rtw_vif *rtwvif);
 int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev);
+void rtw_fw_update_beacon_work(struct work_struct *work);
 void rtw_send_rsvd_page_h2c(struct rtw_dev *rtwdev);
 int rtw_dump_drv_rsvd_page(struct rtw_dev *rtwdev,
                           u32 offset, u32 size, u32 *buf);
diff --git a/sys/contrib/dev/rtw88/mac.c b/sys/contrib/dev/rtw88/mac.c
index d1678aed9d9c..caf2603da2d6 100644
--- a/sys/contrib/dev/rtw88/mac.c
+++ b/sys/contrib/dev/rtw88/mac.c
@@ -75,7 +75,7 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
 
        switch (rtw_hci_type(rtwdev)) {
        case RTW_HCI_TYPE_PCIE:
-               rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_BT_DIG_CLK_EN);
+               rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS);
                break;
        case RTW_HCI_TYPE_USB:
                break;
diff --git a/sys/contrib/dev/rtw88/mac80211.c b/sys/contrib/dev/rtw88/mac80211.c
index 47256b59a591..94a6fb578281 100644
--- a/sys/contrib/dev/rtw88/mac80211.c
+++ b/sys/contrib/dev/rtw88/mac80211.c
@@ -72,6 +72,9 @@ static int rtw_ops_config(struct ieee80211_hw *hw, u32 
changed)
        struct rtw_dev *rtwdev = hw->priv;
        int ret = 0;
 
+       /* let previous ips work finish to ensure we don't leave ips twice */
+       cancel_work_sync(&rtwdev->ips_work);
+
        mutex_lock(&rtwdev->mutex);
 
        rtw_leave_lps_deep(rtwdev);
@@ -206,9 +209,9 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw,
        mutex_unlock(&rtwdev->mutex);
 
 #if defined(__linux__)
-       rtw_info(rtwdev, "start vif %pM on port %d\n", vif->addr, rtwvif->port);
+       rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM on port %d\n", vif->addr, 
rtwvif->port);
 #elif defined(__FreeBSD__)
-       rtw_info(rtwdev, "start vif %6D on port %d\n", vif->addr, ":", 
rtwvif->port);
+       rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %6D on port %d\n", vif->addr, 
":", rtwvif->port);
 #endif
        return 0;
 }
@@ -221,9 +224,9 @@ static void rtw_ops_remove_interface(struct ieee80211_hw 
*hw,
        u32 config = 0;
 
 #if defined(__linux__)
-       rtw_info(rtwdev, "stop vif %pM on port %d\n", vif->addr, rtwvif->port);
+       rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM on port %d\n", vif->addr, 
rtwvif->port);
 #elif defined(__FreeBSD__)
-       rtw_info(rtwdev, "stop vif %6D on port %d\n", vif->addr, ":", 
rtwvif->port);
+       rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %6D on port %d\n", vif->addr, 
":", rtwvif->port);
 #endif
 
        mutex_lock(&rtwdev->mutex);
@@ -251,11 +254,11 @@ static int rtw_ops_change_interface(struct ieee80211_hw 
*hw,
        struct rtw_dev *rtwdev = hw->priv;
 
 #if defined(__linux__)
-       rtw_info(rtwdev, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n",
-                vif->addr, vif->type, type, vif->p2p, p2p);
+       rtw_dbg(rtwdev, RTW_DBG_STATE, "change vif %pM (%d)->(%d), p2p 
(%d)->(%d)\n",
+               vif->addr, vif->type, type, vif->p2p, p2p);
 #elif defined(__FreeBSD__)
-       rtw_info(rtwdev, "change vif %6D (%d)->(%d), p2p (%d)->(%d)\n",
-                vif->addr, ":", vif->type, type, vif->p2p, p2p);
+       rtw_dbg(rtwdev, RTW_DBG_STATE, "change vif %6D (%d)->(%d), p2p 
(%d)->(%d)\n",
+               vif->addr, ":", vif->type, type, vif->p2p, p2p);
 #endif
 
        rtw_ops_remove_interface(hw, vif);
@@ -412,8 +415,10 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw 
*hw,
*** 1334 LINES SKIPPED ***

Reply via email to