The branch main has been updated by bz:

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

commit e2340276fc734a1f0bd0d2cf16fcfba7936c9462
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2023-05-16 23:44:56 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
CommitDate: 2023-08-21 01:35:29 +0000

    rtw89: update driver from upstream
    
    This is a set of updates of the rtw89 driver based on wireless-testing
    (wt-2023-05-11) 711dca0ca3d77414f8f346e564e9c8640147f40d (after v6.4-rc1).
    (wt-2023-06-09) 7bd20e011626ccc3ad53e57873452b1716fcfaaa (after v6.4-rc5).
    (wt-2023-07-24) 62e409149b62a285e89018e49b2e115757fb9022 (after v6.5-rc3).
    (wt-2023-08-06) 2a220a15be657a24868368892e3e2caba2115283 (after v6.5-rc4).
    (wt-2023-08-13) 81e147b1317ee7cde8b624ee8c0501b470d7e91c (after v6.5-rc5).
    
    MFC after:      20 days
---
 sys/contrib/dev/rtw89/Kconfig              |    28 +
 sys/contrib/dev/rtw89/Makefile             |    23 +-
 sys/contrib/dev/rtw89/acpi.c               |    60 +
 sys/contrib/dev/rtw89/acpi.h               |    21 +
 sys/contrib/dev/rtw89/chan.c               |    75 +-
 sys/contrib/dev/rtw89/chan.h               |     3 +
 sys/contrib/dev/rtw89/coex.c               |  3543 +++-
 sys/contrib/dev/rtw89/coex.h               |     7 +
 sys/contrib/dev/rtw89/core.c               |  1060 +-
 sys/contrib/dev/rtw89/core.h               |  1506 +-
 sys/contrib/dev/rtw89/debug.c              |  1282 +-
 sys/contrib/dev/rtw89/debug.h              |     4 +
 sys/contrib/dev/rtw89/efuse.c              |    21 +
 sys/contrib/dev/rtw89/efuse.h              |     1 +
 sys/contrib/dev/rtw89/fw.c                 |  2911 ++-
 sys/contrib/dev/rtw89/fw.h                 |  1968 +-
 sys/contrib/dev/rtw89/mac.c                |  1437 +-
 sys/contrib/dev/rtw89/mac.h                |   209 +-
 sys/contrib/dev/rtw89/mac80211.c           |   274 +-
 sys/contrib/dev/rtw89/pci.c                |   323 +-
 sys/contrib/dev/rtw89/pci.h                |    64 +-
 sys/contrib/dev/rtw89/phy.c                |  1139 +-
 sys/contrib/dev/rtw89/phy.h                |   104 +-
 sys/contrib/dev/rtw89/ps.c                 |   109 +-
 sys/contrib/dev/rtw89/ps.h                 |    22 +-
 sys/contrib/dev/rtw89/reg.h                |   749 +-
 sys/contrib/dev/rtw89/regd.c               |   326 +-
 sys/contrib/dev/rtw89/rtw8851b.c           |  2450 +++
 sys/contrib/dev/rtw89/rtw8851b.h           |    76 +
 sys/contrib/dev/rtw89/rtw8851b_rfk.c       |  3621 ++++
 sys/contrib/dev/rtw89/rtw8851b_rfk.h       |    28 +
 sys/contrib/dev/rtw89/rtw8851b_rfk_table.c |   534 +
 sys/contrib/dev/rtw89/rtw8851b_rfk_table.h |    38 +
 sys/contrib/dev/rtw89/rtw8851b_table.c     | 14840 +++++++++++++
 sys/contrib/dev/rtw89/rtw8851b_table.h     |    21 +
 sys/contrib/dev/rtw89/rtw8851be.c          |    86 +
 sys/contrib/dev/rtw89/rtw8852a.c           |   344 +-
 sys/contrib/dev/rtw89/rtw8852a.h           |     1 -
 sys/contrib/dev/rtw89/rtw8852a_rfk.c       |    38 +-
 sys/contrib/dev/rtw89/rtw8852a_rfk.h       |     1 -
 sys/contrib/dev/rtw89/rtw8852a_table.c     |    15 +
 sys/contrib/dev/rtw89/rtw8852a_table.h     |    11 +-
 sys/contrib/dev/rtw89/rtw8852ae.c          |     8 +-
 sys/contrib/dev/rtw89/rtw8852b.c           |  2621 +++
 sys/contrib/dev/rtw89/rtw8852b.h           |   137 +
 sys/contrib/dev/rtw89/rtw8852b_rfk.c       |  4168 ++++
 sys/contrib/dev/rtw89/rtw8852b_rfk.h       |    25 +
 sys/contrib/dev/rtw89/rtw8852b_rfk_table.c |   794 +
 sys/contrib/dev/rtw89/rtw8852b_rfk_table.h |    62 +
 sys/contrib/dev/rtw89/rtw8852b_table.c     | 22892 ++++++++++++++++++++
 sys/contrib/dev/rtw89/rtw8852b_table.h     |    21 +
 sys/contrib/dev/rtw89/rtw8852be.c          |    90 +
 sys/contrib/dev/rtw89/rtw8852c.c           |   508 +-
 sys/contrib/dev/rtw89/rtw8852c.h           |     1 -
 sys/contrib/dev/rtw89/rtw8852c_rfk.c       |   396 +-
 sys/contrib/dev/rtw89/rtw8852c_table.c     | 29891 ++++++++++++++++++++++-----
 sys/contrib/dev/rtw89/rtw8852c_table.h     |    18 +-
 sys/contrib/dev/rtw89/rtw8852ce.c          |     8 +-
 sys/contrib/dev/rtw89/ser.c                |    58 +-
 sys/contrib/dev/rtw89/txrx.h               |   223 +-
 sys/contrib/dev/rtw89/util.h               |    11 +
 sys/contrib/dev/rtw89/wow.c                |   842 +
 sys/contrib/dev/rtw89/wow.h                |    21 +
 sys/modules/rtw89/Makefile                 |    17 +-
 64 files changed, 93533 insertions(+), 8652 deletions(-)

diff --git a/sys/contrib/dev/rtw89/Kconfig b/sys/contrib/dev/rtw89/Kconfig
index 93e09400aac4..90ffbab7cc4c 100644
--- a/sys/contrib/dev/rtw89/Kconfig
+++ b/sys/contrib/dev/rtw89/Kconfig
@@ -16,12 +16,29 @@ config RTW89_CORE
 config RTW89_PCI
        tristate
 
+config RTW89_8851B
+       tristate
+
 config RTW89_8852A
        tristate
 
+config RTW89_8852B
+       tristate
+
 config RTW89_8852C
        tristate
 
+config RTW89_8851BE
+       tristate "Realtek 8851BE PCI wireless network (Wi-Fi 6) adapter"
+       depends on PCI
+       select RTW89_CORE
+       select RTW89_PCI
+       select RTW89_8851B
+       help
+         Select this option will enable support for 8851BE chipset
+
+         802.11ax PCIe wireless network (Wi-Fi 6) adapter
+
 config RTW89_8852AE
        tristate "Realtek 8852AE PCI wireless network (Wi-Fi 6) adapter"
        depends on PCI
@@ -33,6 +50,17 @@ config RTW89_8852AE
 
          802.11ax PCIe wireless network (Wi-Fi 6) adapter
 
+config RTW89_8852BE
+       tristate "Realtek 8852BE PCI wireless network (Wi-Fi 6) adapter"
+       depends on PCI
+       select RTW89_CORE
+       select RTW89_PCI
+       select RTW89_8852B
+       help
+         Select this option will enable support for 8852BE chipset
+
+         802.11ax PCIe wireless network (Wi-Fi 6) adapter
+
 config RTW89_8852CE
        tristate "Realtek 8852CE PCI wireless network (Wi-Fi 6E) adapter"
        depends on PCI
diff --git a/sys/contrib/dev/rtw89/Makefile b/sys/contrib/dev/rtw89/Makefile
index a87f2aff4def..41940099af1b 100644
--- a/sys/contrib/dev/rtw89/Makefile
+++ b/sys/contrib/dev/rtw89/Makefile
@@ -13,7 +13,19 @@ rtw89_core-y += core.o \
                coex.o \
                ps.o \
                chan.o \
-               ser.o
+               ser.o \
+               acpi.o
+
+rtw89_core-$(CONFIG_PM) += wow.o
+
+obj-$(CONFIG_RTW89_8851B) += rtw89_8851b.o
+rtw89_8851b-objs := rtw8851b.o \
+                   rtw8851b_table.o \
+                   rtw8851b_rfk.o \
+                   rtw8851b_rfk_table.o
+
+obj-$(CONFIG_RTW89_8851BE) += rtw89_8851be.o
+rtw89_8851be-objs := rtw8851be.o
 
 obj-$(CONFIG_RTW89_8852A) += rtw89_8852a.o
 rtw89_8852a-objs := rtw8852a.o \
@@ -24,6 +36,15 @@ rtw89_8852a-objs := rtw8852a.o \
 obj-$(CONFIG_RTW89_8852AE) += rtw89_8852ae.o
 rtw89_8852ae-objs := rtw8852ae.o
 
+obj-$(CONFIG_RTW89_8852B) += rtw89_8852b.o
+rtw89_8852b-objs := rtw8852b.o \
+                   rtw8852b_table.o \
+                   rtw8852b_rfk.o \
+                   rtw8852b_rfk_table.o
+
+obj-$(CONFIG_RTW89_8852BE) += rtw89_8852be.o
+rtw89_8852be-objs := rtw8852be.o
+
 obj-$(CONFIG_RTW89_8852C) += rtw89_8852c.o
 rtw89_8852c-objs := rtw8852c.o \
                    rtw8852c_table.o \
diff --git a/sys/contrib/dev/rtw89/acpi.c b/sys/contrib/dev/rtw89/acpi.c
new file mode 100644
index 000000000000..83252c861c82
--- /dev/null
+++ b/sys/contrib/dev/rtw89/acpi.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2021-2023  Realtek Corporation
+ */
+
+#include <linux/acpi.h>
+#include <linux/uuid.h>
+
+#include "acpi.h"
+#include "debug.h"
+
+#if defined(__linux__)
+static const guid_t rtw89_guid = GUID_INIT(0xD2A8C3E8, 0x4B69, 0x4F00,
+                                          0x82, 0xBD, 0xFE, 0x86,
+                                          0x07, 0x80, 0x3A, 0xA7);
+
+static int rtw89_acpi_dsm_get(struct rtw89_dev *rtwdev, union acpi_object *obj,
+                             u8 *value)
+{
+       switch (obj->type) {
+       case ACPI_TYPE_INTEGER:
+               *value = (u8)obj->integer.value;
+               break;
+       case ACPI_TYPE_BUFFER:
+               *value = obj->buffer.pointer[0];
+               break;
+       default:
+               rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
+                           "acpi dsm return unhandled type: %d\n", obj->type);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
+                           enum rtw89_acpi_dsm_func func, u8 *value)
+{
+       union acpi_object *obj;
+       int ret;
+
+       obj = acpi_evaluate_dsm(ACPI_HANDLE(rtwdev->dev), &rtw89_guid,
+                               0, func, NULL);
+       if (!obj) {
+               rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
+                           "acpi dsm fail to evaluate func: %d\n", func);
+               return -ENOENT;
+       }
+
+       ret = rtw89_acpi_dsm_get(rtwdev, obj, value);
+
+       ACPI_FREE(obj);
+       return ret;
+}
+#elif defined(__FreeBSD__)
+int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
+                           enum rtw89_acpi_dsm_func func, u8 *value)
+{
+       return -ENOENT;
+}
+#endif
diff --git a/sys/contrib/dev/rtw89/acpi.h b/sys/contrib/dev/rtw89/acpi.h
new file mode 100644
index 000000000000..ed74d8ceb733
--- /dev/null
+++ b/sys/contrib/dev/rtw89/acpi.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* Copyright(c) 2021-2023  Realtek Corporation
+ */
+
+#ifndef __RTW89_ACPI_H__
+#define __RTW89_ACPI_H__
+
+#include "core.h"
+
+enum rtw89_acpi_dsm_func {
+       RTW89_ACPI_DSM_FUNC_IDN_BAND_SUP = 2,
+       RTW89_ACPI_DSM_FUNC_6G_DIS = 3,
+       RTW89_ACPI_DSM_FUNC_6G_BP = 4,
+       RTW89_ACPI_DSM_FUNC_TAS_EN = 5,
+       RTW89_ACPI_DSM_FUNC_59G_EN = 6,
+};
+
+int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev,
+                           enum rtw89_acpi_dsm_func func, u8 *value);
+
+#endif
diff --git a/sys/contrib/dev/rtw89/chan.c b/sys/contrib/dev/rtw89/chan.c
index a4f61c2f6512..4663db4ce2f6 100644
--- a/sys/contrib/dev/rtw89/chan.c
+++ b/sys/contrib/dev/rtw89/chan.c
@@ -4,6 +4,7 @@
 
 #include "chan.h"
 #include "debug.h"
+#include "util.h"
 
 static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
                                                 u8 center_chan)
@@ -108,8 +109,8 @@ bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
                              const struct rtw89_chan *new)
 {
        struct rtw89_hal *hal = &rtwdev->hal;
-       struct rtw89_chan *chan = &hal->chan[idx];
-       struct rtw89_chan_rcd *rcd = &hal->chan_rcd[idx];
+       struct rtw89_chan *chan = &hal->sub[idx].chan;
+       struct rtw89_chan_rcd *rcd = &hal->sub[idx].rcd;
        bool band_changed;
 
        rcd->prev_primary_channel = chan->primary_channel;
@@ -127,7 +128,7 @@ static void __rtw89_config_entity_chandef(struct rtw89_dev 
*rtwdev,
 {
        struct rtw89_hal *hal = &rtwdev->hal;
 
-       hal->chandef[idx] = *chandef;
+       hal->sub[idx].chandef = *chandef;
 
        if (from_stack)
                set_bit(idx, hal->entity_map);
@@ -140,6 +141,38 @@ void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
        __rtw89_config_entity_chandef(rtwdev, idx, chandef, true);
 }
 
+void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
+                             enum rtw89_sub_entity_idx idx,
+                             const struct cfg80211_chan_def *chandef)
+{
+       struct rtw89_hal *hal = &rtwdev->hal;
+       enum rtw89_sub_entity_idx cur;
+
+       if (chandef) {
+               cur = atomic_cmpxchg(&hal->roc_entity_idx,
+                                    RTW89_SUB_ENTITY_IDLE, idx);
+               if (cur != RTW89_SUB_ENTITY_IDLE) {
+                       rtw89_debug(rtwdev, RTW89_DBG_TXRX,
+                                   "ROC still processing on entity %d\n", idx);
+                       return;
+               }
+
+               hal->roc_chandef = *chandef;
+       } else {
+               cur = atomic_cmpxchg(&hal->roc_entity_idx, idx,
+                                    RTW89_SUB_ENTITY_IDLE);
+               if (cur == idx)
+                       return;
+
+               if (cur == RTW89_SUB_ENTITY_IDLE)
+                       rtw89_debug(rtwdev, RTW89_DBG_TXRX,
+                                   "ROC already finished on entity %d\n", idx);
+               else
+                       rtw89_debug(rtwdev, RTW89_DBG_TXRX,
+                                   "ROC is processing on entity %d\n", cur);
+       }
+}
+
 static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
 {
        struct cfg80211_chan_def chandef = {0};
@@ -153,6 +186,7 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
        struct rtw89_hal *hal = &rtwdev->hal;
 
        bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
+       atomic_set(&hal->roc_entity_idx, RTW89_SUB_ENTITY_IDLE);
        rtw89_config_default_chandef(rtwdev);
 }
 
@@ -195,6 +229,7 @@ int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
        rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
        rtw89_set_channel(rtwdev);
        cfg->idx = idx;
+       hal->sub[idx].cfg = cfg;
        return 0;
 }
 
@@ -203,8 +238,36 @@ void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
 {
        struct rtw89_hal *hal = &rtwdev->hal;
        struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg 
*)ctx->drv_priv;
+       struct rtw89_vif *rtwvif;
+       u8 drop, roll;
 
-       clear_bit(cfg->idx, hal->entity_map);
+       drop = cfg->idx;
+       if (drop != RTW89_SUB_ENTITY_0)
+               goto out;
+
+       roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY, drop + 
1);
+
+       /* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */
+       if (roll == NUM_OF_RTW89_SUB_ENTITY)
+               goto out;
+
+       /* RTW89_SUB_ENTITY_0 is going to release, and another exists.
+        * Make another roll down to RTW89_SUB_ENTITY_0 to replace.
+        */
+       hal->sub[roll].cfg->idx = RTW89_SUB_ENTITY_0;
+       hal->sub[RTW89_SUB_ENTITY_0] = hal->sub[roll];
+
+       rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+               if (rtwvif->sub_entity_idx == roll)
+                       rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
+       }
+
+       atomic_cmpxchg(&hal->roc_entity_idx, roll, RTW89_SUB_ENTITY_0);
+
+       drop = roll;
+
+out:
+       clear_bit(drop, hal->entity_map);
        rtw89_set_channel(rtwdev);
 }
 
@@ -225,6 +288,9 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
                                 struct rtw89_vif *rtwvif,
                                 struct ieee80211_chanctx_conf *ctx)
 {
+       struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg 
*)ctx->drv_priv;
+
+       rtwvif->sub_entity_idx = cfg->idx;
        return 0;
 }
 
@@ -232,4 +298,5 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev 
*rtwdev,
                                    struct rtw89_vif *rtwvif,
                                    struct ieee80211_chanctx_conf *ctx)
 {
+       rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
 }
diff --git a/sys/contrib/dev/rtw89/chan.h b/sys/contrib/dev/rtw89/chan.h
index ecbd4503bead..bdf369db5041 100644
--- a/sys/contrib/dev/rtw89/chan.h
+++ b/sys/contrib/dev/rtw89/chan.h
@@ -45,6 +45,9 @@ bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
 void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
                                 enum rtw89_sub_entity_idx idx,
                                 const struct cfg80211_chan_def *chandef);
+void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
+                             enum rtw89_sub_entity_idx idx,
+                             const struct cfg80211_chan_def *chandef);
 void rtw89_entity_init(struct rtw89_dev *rtwdev);
 enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev);
 int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
diff --git a/sys/contrib/dev/rtw89/coex.c b/sys/contrib/dev/rtw89/coex.c
index aa90bf616b41..bda0e1e99a8c 100644
--- a/sys/contrib/dev/rtw89/coex.c
+++ b/sys/contrib/dev/rtw89/coex.c
@@ -9,6 +9,7 @@
 #include "ps.h"
 #include "reg.h"
 
+#define RTW89_COEX_VERSION 0x07000113
 #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/
 
 enum btc_fbtc_tdma_template {
@@ -62,7 +63,7 @@ struct btc_fbtc_1slot {
 static const struct rtw89_btc_fbtc_tdma t_def[] = {
        [CXTD_OFF]      = { CXTDMA_OFF,    CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0},
        [CXTD_OFF_B2]   = { CXTDMA_OFF,    CXFLC_OFF, CXTPS_OFF, 0, 0, 1, 0, 0},
-       [CXTD_OFF_EXT]  = { CXTDMA_OFF,    CXFLC_OFF, CXTPS_OFF, 0, 0, 3, 0, 0},
+       [CXTD_OFF_EXT]  = { CXTDMA_OFF,    CXFLC_OFF, CXTPS_OFF, 0, 0, 2, 0, 0},
        [CXTD_FIX]      = { CXTDMA_FIX,    CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0},
        [CXTD_PFIX]     = { CXTDMA_FIX,  CXFLC_NULLP,  CXTPS_ON, 0, 5, 0, 0, 0},
        [CXTD_AUTO]     = { CXTDMA_AUTO,   CXFLC_OFF, CXTPS_OFF, 0, 0, 0, 0, 0},
@@ -77,35 +78,35 @@ static const struct rtw89_btc_fbtc_tdma t_def[] = {
 
 static const struct rtw89_btc_fbtc_slot s_def[] = {
        [CXST_OFF]      = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX),
-       [CXST_B2W]      = __DEF_FBTC_SLOT(5,   0x5a5a5a5a, SLOT_ISO),
-       [CXST_W1]       = __DEF_FBTC_SLOT(70,  0x5a5a5a5a, SLOT_ISO),
-       [CXST_W2]       = __DEF_FBTC_SLOT(70,  0x5a5a5aaa, SLOT_ISO),
-       [CXST_W2B]      = __DEF_FBTC_SLOT(15,  0x5a5a5a5a, SLOT_ISO),
-       [CXST_B1]       = __DEF_FBTC_SLOT(100, 0x55555555, SLOT_MIX),
-       [CXST_B2]       = __DEF_FBTC_SLOT(7,   0x6a5a5a5a, SLOT_MIX),
-       [CXST_B3]       = __DEF_FBTC_SLOT(5,   0x55555555, SLOT_MIX),
-       [CXST_B4]       = __DEF_FBTC_SLOT(50,  0x55555555, SLOT_MIX),
-       [CXST_LK]       = __DEF_FBTC_SLOT(20,  0x5a5a5a5a, SLOT_ISO),
-       [CXST_BLK]      = __DEF_FBTC_SLOT(250, 0x55555555, SLOT_MIX),
-       [CXST_E2G]      = __DEF_FBTC_SLOT(20,  0x6a5a5a5a, SLOT_MIX),
-       [CXST_E5G]      = __DEF_FBTC_SLOT(20,  0xffffffff, SLOT_MIX),
-       [CXST_EBT]      = __DEF_FBTC_SLOT(20,  0x55555555, SLOT_MIX),
-       [CXST_ENULL]    = __DEF_FBTC_SLOT(7,   0xaaaaaaaa, SLOT_ISO),
-       [CXST_WLK]      = __DEF_FBTC_SLOT(250, 0x6a5a6a5a, SLOT_MIX),
-       [CXST_W1FDD]    = __DEF_FBTC_SLOT(35,  0xfafafafa, SLOT_ISO),
-       [CXST_B1FDD]    = __DEF_FBTC_SLOT(100, 0xffffffff, SLOT_MIX),
+       [CXST_B2W]      = __DEF_FBTC_SLOT(5,   0xea5a5a5a, SLOT_ISO),
+       [CXST_W1]       = __DEF_FBTC_SLOT(70,  0xea5a5a5a, SLOT_ISO),
+       [CXST_W2]       = __DEF_FBTC_SLOT(15,  0xea5a5a5a, SLOT_ISO),
+       [CXST_W2B]      = __DEF_FBTC_SLOT(15,  0xea5a5a5a, SLOT_ISO),
+       [CXST_B1]       = __DEF_FBTC_SLOT(250, 0xe5555555, SLOT_MIX),
+       [CXST_B2]       = __DEF_FBTC_SLOT(7,   0xea5a5a5a, SLOT_MIX),
+       [CXST_B3]       = __DEF_FBTC_SLOT(5,   0xe5555555, SLOT_MIX),
+       [CXST_B4]       = __DEF_FBTC_SLOT(50,  0xe5555555, SLOT_MIX),
+       [CXST_LK]       = __DEF_FBTC_SLOT(20,  0xea5a5a5a, SLOT_ISO),
+       [CXST_BLK]      = __DEF_FBTC_SLOT(500, 0x55555555, SLOT_MIX),
+       [CXST_E2G]      = __DEF_FBTC_SLOT(0,   0xea5a5a5a, SLOT_MIX),
+       [CXST_E5G]      = __DEF_FBTC_SLOT(0,   0xffffffff, SLOT_ISO),
+       [CXST_EBT]      = __DEF_FBTC_SLOT(0,   0xe5555555, SLOT_MIX),
+       [CXST_ENULL]    = __DEF_FBTC_SLOT(0,   0xaaaaaaaa, SLOT_ISO),
+       [CXST_WLK]      = __DEF_FBTC_SLOT(250, 0xea5a5a5a, SLOT_MIX),
+       [CXST_W1FDD]    = __DEF_FBTC_SLOT(50,  0xffffffff, SLOT_ISO),
+       [CXST_B1FDD]    = __DEF_FBTC_SLOT(50,  0xffffdfff, SLOT_ISO),
 };
 
 static const u32 cxtbl[] = {
        0xffffffff, /* 0 */
        0xaaaaaaaa, /* 1 */
-       0x55555555, /* 2 */
-       0x66555555, /* 3 */
-       0x66556655, /* 4 */
+       0xe5555555, /* 2 */
+       0xee555555, /* 3 */
+       0xd5555555, /* 4 */
        0x5a5a5a5a, /* 5 */
-       0x5a5a5aaa, /* 6 */
-       0xaa5a5a5a, /* 7 */
-       0x6a5a5a5a, /* 8 */
+       0xfa5a5a5a, /* 6 */
+       0xda5a5a5a, /* 7 */
+       0xea5a5a5a, /* 8 */
        0x6a5a5aaa, /* 9 */
        0x6a5a6a5a, /* 10 */
        0x6a5a6aaa, /* 11 */
@@ -116,26 +117,113 @@ static const u32 cxtbl[] = {
        0xfafafafa, /* 16 */
        0xffffddff, /* 17 */
        0xdaffdaff, /* 18 */
-       0xfafadafa  /* 19 */
+       0xfafadafa, /* 19 */
+       0xea6a6a6a, /* 20 */
+       0xea55556a, /* 21 */
+       0xaafafafa, /* 22 */
+       0xfafaaafa, /* 23 */
+       0xfafffaff  /* 24 */
 };
 
+static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
+       /* firmware version must be in decreasing order for each chip */
+       {RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0),
+        .fcxbtcrpt = 105, .fcxtdma = 3,    .fcxslots = 1, .fcxcysta = 5,
+        .fcxstep = 3,   .fcxnullsta = 2, .fcxmreg = 2,  .fcxgpiodbg = 1,
+        .fcxbtver = 1,  .fcxbtscan = 2,  .fcxbtafh = 2, .fcxbtdevinfo = 1,
+        .fwlrole = 1,   .frptmap = 3,    .fcxctrl = 1,
+        .info_buf = 1800, .max_role_num = 6,
+       },
+       {RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0),
+        .fcxbtcrpt = 4, .fcxtdma = 3,    .fcxslots = 1, .fcxcysta = 3,
+        .fcxstep = 3,   .fcxnullsta = 2, .fcxmreg = 1,  .fcxgpiodbg = 1,
+        .fcxbtver = 1,  .fcxbtscan = 1,  .fcxbtafh = 2, .fcxbtdevinfo = 1,
+        .fwlrole = 1,   .frptmap = 3,    .fcxctrl = 1,
+        .info_buf = 1280, .max_role_num = 5,
+       },
+       {RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0),
+        .fcxbtcrpt = 4, .fcxtdma = 3,    .fcxslots = 1, .fcxcysta = 3,
+        .fcxstep = 3,   .fcxnullsta = 2, .fcxmreg = 1,  .fcxgpiodbg = 1,
+        .fcxbtver = 1,  .fcxbtscan = 1,  .fcxbtafh = 2, .fcxbtdevinfo = 1,
+        .fwlrole = 1,   .frptmap = 2,    .fcxctrl = 1,
+        .info_buf = 1280, .max_role_num = 5,
+       },
+       {RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0),
+        .fcxbtcrpt = 4, .fcxtdma = 3,    .fcxslots = 1, .fcxcysta = 3,
+        .fcxstep = 3,   .fcxnullsta = 2, .fcxmreg = 1,  .fcxgpiodbg = 1,
+        .fcxbtver = 1,  .fcxbtscan = 1,  .fcxbtafh = 1, .fcxbtdevinfo = 1,
+        .fwlrole = 1,   .frptmap = 2,    .fcxctrl = 1,
+        .info_buf = 1280, .max_role_num = 5,
+       },
+       {RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0),
+        .fcxbtcrpt = 105, .fcxtdma = 3,  .fcxslots = 1, .fcxcysta = 5,
+        .fcxstep = 3,   .fcxnullsta = 2, .fcxmreg = 2,  .fcxgpiodbg = 1,
+        .fcxbtver = 1,  .fcxbtscan = 2,  .fcxbtafh = 2, .fcxbtdevinfo = 1,
+        .fwlrole = 1,   .frptmap = 3,    .fcxctrl = 1,
+        .info_buf = 1800, .max_role_num = 6,
+       },
+       {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0),
+        .fcxbtcrpt = 5, .fcxtdma = 3,    .fcxslots = 1, .fcxcysta = 4,
+        .fcxstep = 3,   .fcxnullsta = 2, .fcxmreg = 1,  .fcxgpiodbg = 1,
+        .fcxbtver = 1,  .fcxbtscan = 1,  .fcxbtafh = 2, .fcxbtdevinfo = 1,
+        .fwlrole = 1,   .frptmap = 3,    .fcxctrl = 1,
+        .info_buf = 1800, .max_role_num = 6,
+       },
+       {RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0),
+        .fcxbtcrpt = 4, .fcxtdma = 3,    .fcxslots = 1, .fcxcysta = 3,
+        .fcxstep = 3,   .fcxnullsta = 2, .fcxmreg = 1,  .fcxgpiodbg = 1,
+        .fcxbtver = 1,  .fcxbtscan = 1,  .fcxbtafh = 1, .fcxbtdevinfo = 1,
+        .fwlrole = 1,   .frptmap = 1,    .fcxctrl = 1,
+        .info_buf = 1280, .max_role_num = 5,
+       },
+       {RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0),
+        .fcxbtcrpt = 4, .fcxtdma = 3,    .fcxslots = 1, .fcxcysta = 3,
+        .fcxstep = 3,   .fcxnullsta = 2, .fcxmreg = 1,  .fcxgpiodbg = 1,
+        .fcxbtver = 1,  .fcxbtscan = 1,  .fcxbtafh = 2, .fcxbtdevinfo = 1,
+        .fwlrole = 1,   .frptmap = 3,    .fcxctrl = 1,
+        .info_buf = 1280, .max_role_num = 5,
+       },
+       {RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0),
+        .fcxbtcrpt = 1, .fcxtdma = 1,    .fcxslots = 1, .fcxcysta = 2,
+        .fcxstep = 2,   .fcxnullsta = 1, .fcxmreg = 1,  .fcxgpiodbg = 1,
+        .fcxbtver = 1,  .fcxbtscan = 1,  .fcxbtafh = 1, .fcxbtdevinfo = 1,
+        .fwlrole = 0,   .frptmap = 0,    .fcxctrl = 0,
+        .info_buf = 1024, .max_role_num = 5,
+       },
+
+       /* keep it to be the last as default entry */
+       {0, RTW89_FW_VER_CODE(0, 0, 0, 0),
+        .fcxbtcrpt = 1, .fcxtdma = 1,    .fcxslots = 1, .fcxcysta = 2,
+        .fcxstep = 2,   .fcxnullsta = 1, .fcxmreg = 1,  .fcxgpiodbg = 1,
+        .fcxbtver = 1,  .fcxbtscan = 1,  .fcxbtafh = 1, .fcxbtdevinfo = 1,
+        .fwlrole = 0,   .frptmap = 0,    .fcxctrl = 0,
+        .info_buf = 1024, .max_role_num = 5,
+       },
+};
+
+#define RTW89_DEFAULT_BTC_VER_IDX (ARRAY_SIZE(rtw89_btc_ver_defs) - 1)
+
 struct rtw89_btc_btf_tlv {
        u8 type;
        u8 len;
-       u8 val[1];
+       u8 val[];
 } __packed;
 
 enum btc_btf_set_report_en {
-       RPT_EN_TDMA = BIT(0),
-       RPT_EN_CYCLE = BIT(1),
-       RPT_EN_MREG = BIT(2),
-       RPT_EN_BT_VER_INFO = BIT(3),
-       RPT_EN_BT_SCAN_INFO = BIT(4),
-       RPT_EN_BT_AFH_MAP = BIT(5),
-       RPT_EN_BT_DEVICE_INFO = BIT(6),
-       RPT_EN_WL_ALL = GENMASK(2, 0),
-       RPT_EN_BT_ALL = GENMASK(6, 3),
-       RPT_EN_ALL = GENMASK(6, 0),
+       RPT_EN_TDMA,
+       RPT_EN_CYCLE,
+       RPT_EN_MREG,
+       RPT_EN_BT_VER_INFO,
+       RPT_EN_BT_SCAN_INFO,
+       RPT_EN_BT_DEVICE_INFO,
+       RPT_EN_BT_AFH_MAP,
+       RPT_EN_BT_AFH_MAP_LE,
+       RPT_EN_FW_STEP_INFO,
+       RPT_EN_TEST,
+       RPT_EN_WL_ALL,
+       RPT_EN_BT_ALL,
+       RPT_EN_ALL,
+       RPT_EN_MONITER,
 };
 
 #define BTF_SET_REPORT_VER 1
@@ -152,7 +240,6 @@ struct rtw89_btc_btf_set_slot_table {
        u8 buf[];
 } __packed;
 
-#define BTF_SET_MON_REG_VER 1
 struct rtw89_btc_btf_set_mon_reg {
        u8 fver;
        u8 reg_num;
@@ -264,6 +351,9 @@ enum btc_cx_poicy_type {
        /* TDMA off + pri: WL_Hi-Tx > BT, BT_Hi > other-WL > BT_Lo */
        BTC_CXP_OFF_BWB2 = (BTC_CXP_OFF << 8) | 8,
 
+       /* TDMA off + pri: WL_Hi-Tx = BT */
+       BTC_CXP_OFF_BWB3 = (BTC_CXP_OFF << 8) | 9,
+
        /* TDMA off+Bcn-Protect + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo*/
        BTC_CXP_OFFB_BWB0 = (BTC_CXP_OFFB << 8) | 0,
 
@@ -433,7 +523,7 @@ enum btc_w2b_scoreboard {
        BTC_WSCB_TDMA = BIT(9),
        BTC_WSCB_FIX2M = BIT(10),
        BTC_WSCB_WLRFK = BIT(11),
-       BTC_WSCB_BTRFK_GNT = BIT(12), /* not used, use mailbox to inform BT */
+       BTC_WSCB_RXSCAN_PRI = BIT(12),
        BTC_WSCB_BT_HILNA = BIT(13),
        BTC_WSCB_BTLOG = BIT(14),
        BTC_WSCB_ALL = GENMASK(23, 0),
@@ -491,6 +581,11 @@ enum btc_gnt_state {
        BTC_GNT_MAX
 };
 
+enum btc_ctr_path {
+       BTC_CTRL_BY_BT = 0,
+       BTC_CTRL_BY_WL
+};
+
 enum btc_wl_max_tx_time {
        BTC_MAX_TX_TIME_L1 = 500,
        BTC_MAX_TX_TIME_L2 = 1000,
@@ -650,10 +745,9 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 
type)
                memset(&btc->mdinfo, 0, sizeof(btc->mdinfo));
 }
 
-#define BTC_FWINFO_BUF 1024
-
 #define BTC_RPT_HDR_SIZE 3
 #define BTC_CHK_WLSLOT_DRIFT_MAX 15
+#define BTC_CHK_BTSLOT_DRIFT_MAX 15
 #define BTC_CHK_HANG_MAX 3
 
 static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt)
@@ -668,62 +762,76 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 
type, u32 cnt)
                    __func__, type, cnt);
 
        switch (type) {
-       case BTC_DCNT_RPT_FREEZE:
+       case BTC_DCNT_RPT_HANG:
                if (dm->cnt_dm[BTC_DCNT_RPT] == cnt && btc->fwinfo.rpt_en_map)
-                       dm->cnt_dm[BTC_DCNT_RPT_FREEZE]++;
+                       dm->cnt_dm[BTC_DCNT_RPT_HANG]++;
                else
-                       dm->cnt_dm[BTC_DCNT_RPT_FREEZE] = 0;
+                       dm->cnt_dm[BTC_DCNT_RPT_HANG] = 0;
 
-               if (dm->cnt_dm[BTC_DCNT_RPT_FREEZE] >= BTC_CHK_HANG_MAX)
+               if (dm->cnt_dm[BTC_DCNT_RPT_HANG] >= BTC_CHK_HANG_MAX)
                        dm->error.map.wl_fw_hang = true;
                else
                        dm->error.map.wl_fw_hang = false;
 
                dm->cnt_dm[BTC_DCNT_RPT] = cnt;
                break;
-       case BTC_DCNT_CYCLE_FREEZE:
+       case BTC_DCNT_CYCLE_HANG:
                if (dm->cnt_dm[BTC_DCNT_CYCLE] == cnt &&
                    (dm->tdma_now.type != CXTDMA_OFF ||
                     dm->tdma_now.ext_ctrl == CXECTL_EXT))
-                       dm->cnt_dm[BTC_DCNT_CYCLE_FREEZE]++;
+                       dm->cnt_dm[BTC_DCNT_CYCLE_HANG]++;
                else
-                       dm->cnt_dm[BTC_DCNT_CYCLE_FREEZE] = 0;
+                       dm->cnt_dm[BTC_DCNT_CYCLE_HANG] = 0;
 
-               if (dm->cnt_dm[BTC_DCNT_CYCLE_FREEZE] >= BTC_CHK_HANG_MAX)
+               if (dm->cnt_dm[BTC_DCNT_CYCLE_HANG] >= BTC_CHK_HANG_MAX)
                        dm->error.map.cycle_hang = true;
                else
                        dm->error.map.cycle_hang = false;
 
                dm->cnt_dm[BTC_DCNT_CYCLE] = cnt;
                break;
-       case BTC_DCNT_W1_FREEZE:
+       case BTC_DCNT_W1_HANG:
                if (dm->cnt_dm[BTC_DCNT_W1] == cnt &&
                    dm->tdma_now.type != CXTDMA_OFF)
-                       dm->cnt_dm[BTC_DCNT_W1_FREEZE]++;
+                       dm->cnt_dm[BTC_DCNT_W1_HANG]++;
                else
-                       dm->cnt_dm[BTC_DCNT_W1_FREEZE] = 0;
+                       dm->cnt_dm[BTC_DCNT_W1_HANG] = 0;
 
-               if (dm->cnt_dm[BTC_DCNT_W1_FREEZE] >= BTC_CHK_HANG_MAX)
+               if (dm->cnt_dm[BTC_DCNT_W1_HANG] >= BTC_CHK_HANG_MAX)
                        dm->error.map.w1_hang = true;
                else
                        dm->error.map.w1_hang = false;
 
                dm->cnt_dm[BTC_DCNT_W1] = cnt;
                break;
-       case BTC_DCNT_B1_FREEZE:
+       case BTC_DCNT_B1_HANG:
                if (dm->cnt_dm[BTC_DCNT_B1] == cnt &&
                    dm->tdma_now.type != CXTDMA_OFF)
-                       dm->cnt_dm[BTC_DCNT_B1_FREEZE]++;
+                       dm->cnt_dm[BTC_DCNT_B1_HANG]++;
                else
-                       dm->cnt_dm[BTC_DCNT_B1_FREEZE] = 0;
+                       dm->cnt_dm[BTC_DCNT_B1_HANG] = 0;
 
-               if (dm->cnt_dm[BTC_DCNT_B1_FREEZE] >= BTC_CHK_HANG_MAX)
+               if (dm->cnt_dm[BTC_DCNT_B1_HANG] >= BTC_CHK_HANG_MAX)
                        dm->error.map.b1_hang = true;
                else
                        dm->error.map.b1_hang = false;
 
                dm->cnt_dm[BTC_DCNT_B1] = cnt;
                break;
+       case BTC_DCNT_E2G_HANG:
+               if (dm->cnt_dm[BTC_DCNT_E2G] == cnt &&
+                   dm->tdma_now.ext_ctrl == CXECTL_EXT)
+                       dm->cnt_dm[BTC_DCNT_E2G_HANG]++;
+               else
+                       dm->cnt_dm[BTC_DCNT_E2G_HANG] = 0;
+
+               if (dm->cnt_dm[BTC_DCNT_E2G_HANG] >= BTC_CHK_HANG_MAX)
+                       dm->error.map.wl_e2g_hang = true;
+               else
+                       dm->error.map.wl_e2g_hang = false;
+
+               dm->cnt_dm[BTC_DCNT_E2G] = cnt;
+               break;
        case BTC_DCNT_TDMA_NONSYNC:
                if (cnt != 0) /* if tdma not sync between drv/fw  */
                        dm->cnt_dm[BTC_DCNT_TDMA_NONSYNC]++;
@@ -742,23 +850,23 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 
type, u32 cnt)
                        dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] = 0;
 
                if (dm->cnt_dm[BTC_DCNT_SLOT_NONSYNC] >= BTC_CHK_HANG_MAX)
-                       dm->error.map.tdma_no_sync = true;
+                       dm->error.map.slot_no_sync = true;
                else
-                       dm->error.map.tdma_no_sync = false;
+                       dm->error.map.slot_no_sync = false;
                break;
-       case BTC_DCNT_BTCNT_FREEZE:
+       case BTC_DCNT_BTCNT_HANG:
                cnt = cx->cnt_bt[BTC_BCNT_HIPRI_RX] +
                      cx->cnt_bt[BTC_BCNT_HIPRI_TX] +
                      cx->cnt_bt[BTC_BCNT_LOPRI_RX] +
                      cx->cnt_bt[BTC_BCNT_LOPRI_TX];
 
                if (cnt == 0)
-                       dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE]++;
+                       dm->cnt_dm[BTC_DCNT_BTCNT_HANG]++;
                else
-                       dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0;
+                       dm->cnt_dm[BTC_DCNT_BTCNT_HANG] = 0;
 
-               if ((dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE] >= BTC_CHK_HANG_MAX &&
-                    bt->enable.now) || (!dm->cnt_dm[BTC_DCNT_BTCNT_FREEZE] &&
+               if ((dm->cnt_dm[BTC_DCNT_BTCNT_HANG] >= BTC_CHK_HANG_MAX &&
+                    bt->enable.now) || (!dm->cnt_dm[BTC_DCNT_BTCNT_HANG] &&
                     !bt->enable.now))
                        _update_bt_scbd(rtwdev, false);
                break;
@@ -773,23 +881,38 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 
type, u32 cnt)
                else
                        dm->error.map.wl_slot_drift = false;
                break;
+       case BTC_DCNT_BT_SLOT_DRIFT:
+               if (cnt >= BTC_CHK_BTSLOT_DRIFT_MAX)
+                       dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT]++;
+               else
+                       dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT] = 0;
+
+               if (dm->cnt_dm[BTC_DCNT_BT_SLOT_DRIFT] >= BTC_CHK_HANG_MAX)
+                       dm->error.map.bt_slot_drift = true;
+               else
+                       dm->error.map.bt_slot_drift = false;
+
+               break;
        }
 }
 
 static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 
*pfinfo)
 {
        struct rtw89_btc *btc = &rtwdev->btc;
+       const struct rtw89_btc_ver *ver = btc->ver;
        struct rtw89_btc_bt_info *bt = &btc->cx.bt;
        struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
        struct rtw89_btc_bt_a2dp_desc *a2dp = &bt_linfo->a2dp_desc;
        struct rtw89_btc_fbtc_btver *pver = NULL;
-       struct rtw89_btc_fbtc_btscan *pscan = NULL;
-       struct rtw89_btc_fbtc_btafh *pafh = NULL;
+       struct rtw89_btc_fbtc_btscan_v1 *pscan_v1;
+       struct rtw89_btc_fbtc_btscan_v2 *pscan_v2;
+       struct rtw89_btc_fbtc_btafh *pafh_v1 = NULL;
+       struct rtw89_btc_fbtc_btafh_v2 *pafh_v2 = NULL;
        struct rtw89_btc_fbtc_btdevinfo *pdev = NULL;
+       bool scan_update = true;
+       int i;
 
        pver = (struct rtw89_btc_fbtc_btver *)pfinfo;
-       pscan = (struct rtw89_btc_fbtc_btscan *)pfinfo;
-       pafh = (struct rtw89_btc_fbtc_btafh *)pfinfo;
        pdev = (struct rtw89_btc_fbtc_btdevinfo *)pfinfo;
 
        rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -803,12 +926,45 @@ static void _update_bt_report(struct rtw89_dev *rtwdev, 
u8 rpt_type, u8 *pfinfo)
                bt->feature = le32_to_cpu(pver->feature);
                break;
        case BTC_RPT_TYPE_BT_SCAN:
-               memcpy(bt->scan_info, pscan->scan, BTC_SCAN_MAX1);
+               if (ver->fcxbtscan == 1) {
+                       pscan_v1 = (struct rtw89_btc_fbtc_btscan_v1 *)pfinfo;
+                       for (i = 0; i < BTC_SCAN_MAX1; i++) {
+                               bt->scan_info_v1[i] = pscan_v1->scan[i];
+                               if (bt->scan_info_v1[i].win == 0 &&
+                                   bt->scan_info_v1[i].intvl == 0)
+                                       scan_update = false;
+                       }
+               } else if (ver->fcxbtscan == 2) {
+                       pscan_v2 = (struct rtw89_btc_fbtc_btscan_v2 *)pfinfo;
+                       for (i = 0; i < CXSCAN_MAX; i++) {
+                               bt->scan_info_v2[i] = pscan_v2->para[i];
+                               if ((pscan_v2->type & BIT(i)) &&
+                                   pscan_v2->para[i].win == 0 &&
+                                   pscan_v2->para[i].intvl == 0)
+                                       scan_update = false;
+                       }
+               }
+               if (scan_update)
+                       bt->scan_info_update = 1;
                break;
        case BTC_RPT_TYPE_BT_AFH:
-               memcpy(&bt_linfo->afh_map[0], pafh->afh_l, 4);
-               memcpy(&bt_linfo->afh_map[4], pafh->afh_m, 4);
-               memcpy(&bt_linfo->afh_map[8], pafh->afh_h, 2);
+               if (ver->fcxbtafh == 2) {
+                       pafh_v2 = (struct rtw89_btc_fbtc_btafh_v2 *)pfinfo;
+                       if (pafh_v2->map_type & RPT_BT_AFH_SEQ_LEGACY) {
+                               memcpy(&bt_linfo->afh_map[0], pafh_v2->afh_l, 
4);
+                               memcpy(&bt_linfo->afh_map[4], pafh_v2->afh_m, 
4);
+                               memcpy(&bt_linfo->afh_map[8], pafh_v2->afh_h, 
2);
+                       }
+                       if (pafh_v2->map_type & RPT_BT_AFH_SEQ_LE) {
+                               memcpy(&bt_linfo->afh_map_le[0], 
pafh_v2->afh_le_a, 4);
+                               memcpy(&bt_linfo->afh_map_le[4], 
pafh_v2->afh_le_b, 1);
+                       }
+               } else if (ver->fcxbtafh == 1) {
+                       pafh_v1 = (struct rtw89_btc_fbtc_btafh *)pfinfo;
+                       memcpy(&bt_linfo->afh_map[0], pafh_v1->afh_l, 4);
+                       memcpy(&bt_linfo->afh_map[4], pafh_v1->afh_m, 4);
+                       memcpy(&bt_linfo->afh_map[8], pafh_v1->afh_h, 2);
+               }
                break;
        case BTC_RPT_TYPE_BT_DEVICE:
                a2dp->device_name = le32_to_cpu(pdev->dev_name);
@@ -820,80 +976,6 @@ static void _update_bt_report(struct rtw89_dev *rtwdev, u8 
rpt_type, u8 *pfinfo)
        }
 }
 
-struct rtw89_btc_fbtc_cysta_cpu {
-       u8 fver;
-       u8 rsvd;
-       u16 cycles;
-       u16 cycles_a2dp[CXT_FLCTRL_MAX];
-       u16 a2dpept;
-       u16 a2dpeptto;
-       u16 tavg_cycle[CXT_MAX];
-       u16 tmax_cycle[CXT_MAX];
-       u16 tmaxdiff_cycle[CXT_MAX];
-       u16 tavg_a2dp[CXT_FLCTRL_MAX];
-       u16 tmax_a2dp[CXT_FLCTRL_MAX];
-       u16 tavg_a2dpept;
-       u16 tmax_a2dpept;
-       u16 tavg_lk;
-       u16 tmax_lk;
-       u32 slot_cnt[CXST_MAX];
-       u32 bcn_cnt[CXBCN_MAX];
-       u32 leakrx_cnt;
-       u32 collision_cnt;
-       u32 skip_cnt;
-       u32 exception;
-       u32 except_cnt;
-       u16 tslot_cycle[BTC_CYCLE_SLOT_MAX];
-};
-
-static void rtw89_btc_fbtc_cysta_to_cpu(const struct rtw89_btc_fbtc_cysta *src,
-                                       struct rtw89_btc_fbtc_cysta_cpu *dst)
-{
-#if defined(__linux__)
-       static_assert(sizeof(*src) == sizeof(*dst));
-#elif defined(__FreeBSD__)
-       rtw89_static_assert(sizeof(*src) == sizeof(*dst));
-#endif
-
-#define __CPY_U8(_x)   ({dst->_x = src->_x; })
-#define __CPY_LE16(_x) ({dst->_x = le16_to_cpu(src->_x); })
-#define __CPY_LE16S(_x)        ({int _i; for (_i = 0; _i < 
ARRAY_SIZE(dst->_x); _i++) \
-                                  dst->_x[_i] = le16_to_cpu(src->_x[_i]); })
-#define __CPY_LE32(_x) ({dst->_x = le32_to_cpu(src->_x); })
-#define __CPY_LE32S(_x)        ({int _i; for (_i = 0; _i < 
ARRAY_SIZE(dst->_x); _i++) \
-                                  dst->_x[_i] = le32_to_cpu(src->_x[_i]); })
-
-       __CPY_U8(fver);
-       __CPY_U8(rsvd);
-       __CPY_LE16(cycles);
-       __CPY_LE16S(cycles_a2dp);
-       __CPY_LE16(a2dpept);
-       __CPY_LE16(a2dpeptto);
-       __CPY_LE16S(tavg_cycle);
-       __CPY_LE16S(tmax_cycle);
-       __CPY_LE16S(tmaxdiff_cycle);
-       __CPY_LE16S(tavg_a2dp);
-       __CPY_LE16S(tmax_a2dp);
-       __CPY_LE16(tavg_a2dpept);
-       __CPY_LE16(tmax_a2dpept);
-       __CPY_LE16(tavg_lk);
-       __CPY_LE16(tmax_lk);
-       __CPY_LE32S(slot_cnt);
-       __CPY_LE32S(bcn_cnt);
-       __CPY_LE32(leakrx_cnt);
-       __CPY_LE32(collision_cnt);
-       __CPY_LE32(skip_cnt);
-       __CPY_LE32(exception);
-       __CPY_LE32(except_cnt);
-       __CPY_LE16S(tslot_cycle);
-
-#undef __CPY_U8
-#undef __CPY_LE16
-#undef __CPY_LE16S
-#undef __CPY_LE32
-#undef __CPY_LE32S
-}
-
 #define BTC_LEAK_AP_TH 10
 #define BTC_CYSTA_CHK_PERIOD 100
 
@@ -907,23 +989,20 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
                           struct rtw89_btc_btf_fwinfo *pfwinfo,
                           u8 *prptbuf, u32 index)
*** 119065 LINES SKIPPED ***

Reply via email to