struct rtw89_btc_bt_info *bt = &btc->cx.bt;
        struct rtw89_btc_fbtc_rpt_ctrl *prpt;
        struct rtw89_btc_fbtc_rpt_ctrl_v1 *prpt_v1;
-       struct rtw89_btc_fbtc_cysta *pcysta = NULL;
-       struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1 = NULL;
+       union rtw89_btc_fbtc_cysta_info *pcysta = NULL;
        struct rtw89_btc_prpt *btc_prpt = NULL;
        void *rpt_content = NULL, *pfinfo = NULL;
        u8 rpt_type = 0;
                break;
        case BTC_RPT_TYPE_CYSTA:
                pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
-               if (chip->chip_id == RTL8852A) {
-                       pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo;
-                       pcysta = &pfwinfo->rpt_fbtc_cysta.finfo;
-                       pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo);
+               pcysta = &pfwinfo->rpt_fbtc_cysta.finfo;
+               if (ver->fcxcysta == 2) {
+                       pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v2;
+                       pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2;
+                       pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v2);
+               } else if (ver->fcxcysta == 3) {
+                       pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v3;
+                       pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3;
+                       pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v3);
                } else {
-                       pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo_v1;
-                       pcysta_v1 = &pfwinfo->rpt_fbtc_cysta.finfo_v1;
-                       pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo_v1);
+                       goto err;
                }
                pcinfo->req_fver = ver->fcxcysta;
                break;
                                    sizeof(dm->slot_now)));
                break;
        case BTC_RPT_TYPE_CYSTA:
-               if (chip->chip_id == RTL8852A) {
-                       if (le16_to_cpu(pcysta->cycles) < BTC_CYSTA_CHK_PERIOD)
+               if (ver->fcxcysta == 2) {
+                       if (le16_to_cpu(pcysta->v2.cycles) < BTC_CYSTA_CHK_PERIOD)
                                break;
                        /* Check Leak-AP */
-                       if (le32_to_cpu(pcysta->slot_cnt[CXST_LK]) != 0 &&
-                           le32_to_cpu(pcysta->leakrx_cnt) != 0 && dm->tdma_now.rxflctrl) {
-                               if (le32_to_cpu(pcysta->slot_cnt[CXST_LK]) <
-                                   BTC_LEAK_AP_TH * le32_to_cpu(pcysta->leakrx_cnt))
+                       if (le32_to_cpu(pcysta->v2.slot_cnt[CXST_LK]) != 0 &&
+                           le32_to_cpu(pcysta->v2.leakrx_cnt) != 0 && dm->tdma_now.rxflctrl) {
+                               if (le32_to_cpu(pcysta->v2.slot_cnt[CXST_LK]) <
+                                   BTC_LEAK_AP_TH * le32_to_cpu(pcysta->v2.leakrx_cnt))
                                        dm->leak_ap = 1;
                        }
 
                        else
                                wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur);
 
-                       if (le16_to_cpu(pcysta->tavg_cycle[CXT_WL]) > wl_slot_set) {
-                               diff_t = le16_to_cpu(pcysta->tavg_cycle[CXT_WL]) - wl_slot_set;
+                       if (le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) > wl_slot_set) {
+                               diff_t = le16_to_cpu(pcysta->v2.tavg_cycle[CXT_WL]) - wl_slot_set;
                                _chk_btc_err(rtwdev,
                                             BTC_DCNT_WL_SLOT_DRIFT, diff_t);
                        }
 
                        _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE,
-                                    le32_to_cpu(pcysta->slot_cnt[CXST_W1]));
+                                    le32_to_cpu(pcysta->v2.slot_cnt[CXST_W1]));
                        _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE,
-                                    le32_to_cpu(pcysta->slot_cnt[CXST_B1]));
+                                    le32_to_cpu(pcysta->v2.slot_cnt[CXST_B1]));
                        _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE,
-                                    le16_to_cpu(pcysta->cycles));
-               } else {
-                       if (le16_to_cpu(pcysta_v1->cycles) < BTC_CYSTA_CHK_PERIOD)
+                                    le16_to_cpu(pcysta->v2.cycles));
+               } else if (ver->fcxcysta == 3) {
+                       if (le16_to_cpu(pcysta->v3.cycles) < BTC_CYSTA_CHK_PERIOD)
                                break;
 
-                       cnt_leak_slot = le32_to_cpu(pcysta_v1->slot_cnt[CXST_LK]);
-                       cnt_rx_imr = le32_to_cpu(pcysta_v1->leak_slot.cnt_rximr);
+                       cnt_leak_slot = le32_to_cpu(pcysta->v3.slot_cnt[CXST_LK]);
+                       cnt_rx_imr = le32_to_cpu(pcysta->v3.leak_slot.cnt_rximr);
 
                        /* Check Leak-AP */
                        if (cnt_leak_slot != 0 && cnt_rx_imr != 0 &&
                        /* Check diff time between real WL slot and W1 slot */
                        if (dm->tdma_now.type == CXTDMA_OFF) {
                                wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur);
-                               wl_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_WL]);
+                               wl_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_WL]);
                                if (wl_slot_real > wl_slot_set) {
                                        diff_t = wl_slot_real - wl_slot_set;
                                        _chk_btc_err(rtwdev, BTC_DCNT_WL_SLOT_DRIFT, diff_t);
                        if (dm->tdma_now.type == CXTDMA_OFF &&
                            dm->tdma_now.ext_ctrl == CXECTL_EXT &&
                            btc->bt_req_len != 0) {
-                               bt_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_BT]);
-
+                               bt_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_BT]);
                                if (btc->bt_req_len > bt_slot_real) {
                                        diff_t = btc->bt_req_len - bt_slot_real;
                                        _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t);
                        }
 
                        _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE,
-                                    le32_to_cpu(pcysta_v1->slot_cnt[CXST_W1]));
+                                    le32_to_cpu(pcysta->v3.slot_cnt[CXST_W1]));
                        _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE,
-                                    le32_to_cpu(pcysta_v1->slot_cnt[CXST_B1]));
+                                    le32_to_cpu(pcysta->v3.slot_cnt[CXST_B1]));
                        _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE,
-                                    (u32)le16_to_cpu(pcysta_v1->cycles));
+                                    le16_to_cpu(pcysta->v3.cycles));
+               } else {
+                       goto err;
                }
                break;
        case BTC_RPT_TYPE_BT_VER:
 
 static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m)
 {
-       const struct rtw89_chip_info *chip = rtwdev->chip;
        struct rtw89_btc *btc = &rtwdev->btc;
+       const struct rtw89_btc_ver *ver = btc->ver;
        struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
-       struct rtw89_btc_fbtc_cysta *pcysta;
-       struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1;
+       union rtw89_btc_fbtc_cysta_info *pcysta;
        u32 except_cnt, exception_map;
 
-       if (chip->chip_id == RTL8852A) {
-               pcysta = &pfwinfo->rpt_fbtc_cysta.finfo;
-               except_cnt = le32_to_cpu(pcysta->except_cnt);
-               exception_map = le32_to_cpu(pcysta->exception);
+       pcysta = &pfwinfo->rpt_fbtc_cysta.finfo;
+       if (ver->fcxcysta == 2) {
+               pcysta->v2 = pfwinfo->rpt_fbtc_cysta.finfo.v2;
+               except_cnt = le32_to_cpu(pcysta->v2.except_cnt);
+               exception_map = le32_to_cpu(pcysta->v2.exception);
+       } else if (ver->fcxcysta == 3) {
+               pcysta->v3 = pfwinfo->rpt_fbtc_cysta.finfo.v3;
+               except_cnt = le32_to_cpu(pcysta->v3.except_cnt);
+               exception_map = le32_to_cpu(pcysta->v3.except_map);
        } else {
-               pcysta_v1 = &pfwinfo->rpt_fbtc_cysta.finfo_v1;
-               except_cnt = le32_to_cpu(pcysta_v1->except_cnt);
-               exception_map = le32_to_cpu(pcysta_v1->except_map);
+               return;
        }
 
        if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && except_cnt == 0 &&
        }
 }
 
-static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m)
+static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m)
 {
        struct rtw89_btc *btc = &rtwdev->btc;
        struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
        struct rtw89_btc_dm *dm = &btc->dm;
        struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
        struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
-       struct rtw89_btc_fbtc_cysta *pcysta_le32 = NULL;
+       struct rtw89_btc_fbtc_cysta_v2 *pcysta_le32 = NULL;
        union rtw89_btc_fbtc_rxflct r;
        u8 i, cnt = 0, slot_pair;
        u16 cycle, c_begin, c_end, store_index;
        if (!pcinfo->valid)
                return;
 
-       pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo;
+       pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo.v2;
        seq_printf(m,
                   " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
                   "[cycle_cnt]",
        }
 }
 
-static void _show_fbtc_cysta_v1(struct rtw89_dev *rtwdev, struct seq_file *m)
+static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m)
 {
        struct rtw89_btc *btc = &rtwdev->btc;
        struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc;
        struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
        struct rtw89_btc_dm *dm = &btc->dm;
        struct rtw89_btc_fbtc_a2dp_trx_stat *a2dp_trx;
-       struct rtw89_btc_fbtc_cysta_v1 *pcysta;
+       struct rtw89_btc_fbtc_cysta_v3 *pcysta;
        struct rtw89_btc_rpt_cmn_info *pcinfo;
        u8 i, cnt = 0, slot_pair, divide_cnt;
        u16 cycle, c_begin, c_end, store_index;
        if (!pcinfo->valid)
                return;
 
-       pcysta = &pfwinfo->rpt_fbtc_cysta.finfo_v1;
+       pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v3;
        seq_printf(m,
                   " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
                   "[cycle_cnt]",
 
 static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m)
 {
-       const struct rtw89_chip_info *chip = rtwdev->chip;
        struct rtw89_btc *btc = &rtwdev->btc;
+       const struct rtw89_btc_ver *ver = btc->ver;
 
        if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM))
                return;
        _show_fbtc_tdma(rtwdev, m);
        _show_fbtc_slots(rtwdev, m);
 
-       if (chip->chip_id == RTL8852A)
-               _show_fbtc_cysta(rtwdev, m);
-       else
-               _show_fbtc_cysta_v1(rtwdev, m);
+       if (ver->fcxcysta == 2)
+               _show_fbtc_cysta_v2(rtwdev, m);
+       else if (ver->fcxcysta == 3)
+               _show_fbtc_cysta_v3(rtwdev, m);
 
        _show_fbtc_nullsta(rtwdev, m);
        _show_fbtc_step(rtwdev, m);