From: Ching-Te Ku <ku920601@xxxxxxxxxxx> Add the firmware related version code for RTL8852BT version 0.29.90.0. And add the version 7 report control structure format. Firmware will collect counters like mailbox count, RF on/off count, and some Bluetooth related counters into this structure and pass to driver periodically. It will help to understand how the firmware mechanism working. Signed-off-by: Ching-Te Ku <ku920601@xxxxxxxxxxx> Signed-off-by: Ping-Ke Shih <pkshih@xxxxxxxxxxx> --- drivers/net/wireless/realtek/rtw89/coex.c | 149 +++++++++++++++++++++- drivers/net/wireless/realtek/rtw89/core.h | 14 ++ 2 files changed, 162 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index c1f6fcef904b..97e34287dfca 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -129,6 +129,13 @@ static const u32 cxtbl[] = { static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { /* firmware version must be in decreasing order for each chip */ + {RTL8852BT, RTW89_FW_VER_CODE(0, 29, 90, 0), + .fcxbtcrpt = 7, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, + .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, + .fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7, + .fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7, + .fwevntrptl = 1, .drvinfo_type = 1, .info_buf = 1800, .max_role_num = 6, + }, {RTL8922A, RTW89_FW_VER_CODE(0, 35, 8, 0), .fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7, .fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7, @@ -1351,6 +1358,10 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, pfinfo = &pfwinfo->rpt_ctrl.finfo.v8; pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v8); break; + } else if (ver->fcxbtcrpt == 7) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v7; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v7); + break; } else { goto err; } @@ -1655,6 +1666,38 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, pfwinfo->event[BTF_EVNT_RPT]); dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; + } else if (ver->fcxbtcrpt == 7) { + prpt->v7 = pfwinfo->rpt_ctrl.finfo.v7; + pfwinfo->rpt_en_map = le32_to_cpu(prpt->v7.rpt_info.en); + wl->ver_info.fw_coex = le32_to_cpu(prpt->v7.rpt_info.cx_ver); + wl->ver_info.fw = le32_to_cpu(prpt->v7.rpt_info.fw_ver); + + for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) + memcpy(&dm->gnt.band[i], &prpt->v7.gnt_val[i][0], + sizeof(dm->gnt.band[i])); + + btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = + le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_HI_TX_V105]); + btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = + le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_HI_RX_V105]); + btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = + le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_LO_TX_V105]); + btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = + le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_LO_RX_V105]); + + val1 = le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_POLLUTED_V105]); + if (val1 > btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW]) + val1 -= btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW]; /* diff */ + + btc->cx.cnt_bt[BTC_BCNT_POLUT_DIFF] = val1; + btc->cx.cnt_bt[BTC_BCNT_POLUT_NOW] = + le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_POLLUTED_V105]); + + val1 = pfwinfo->event[BTF_EVNT_RPT]; + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); + _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, val1); + _chk_btc_err(rtwdev, BTC_DCNT_WL_FW_VER_MATCH, 0); + _chk_btc_err(rtwdev, BTC_DCNT_BTTX_HANG, 0); } else if (ver->fcxbtcrpt == 8) { prpt->v8 = pfwinfo->rpt_ctrl.finfo.v8; pfwinfo->rpt_en_map = le32_to_cpu(prpt->v8.rpt_info.en); @@ -2397,7 +2440,7 @@ static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev, if (val == fwinfo->rpt_en_map) return; - if (btc->ver->fcxbtcrpt == 8) { + if (btc->ver->fcxbtcrpt == 7 || btc->ver->fcxbtcrpt == 8) { r.v8.type = SET_REPORT_EN; r.v8.fver = btc->ver->fcxbtcrpt; r.v8.len = sizeof(r.v8.map); @@ -10288,6 +10331,108 @@ static void _show_summary_v105(struct rtw89_dev *rtwdev, struct seq_file *m) cnt[BTC_NCNT_CUSTOMERIZE]); } +static void _show_summary_v7(struct rtw89_dev *rtwdev, struct seq_file *m) +{ + struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; + struct rtw89_btc_fbtc_rpt_ctrl_v7 *prptctrl = NULL; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_cx *cx = &rtwdev->btc.cx; + struct rtw89_btc_dm *dm = &rtwdev->btc.dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + u32 *cnt = rtwdev->btc.dm.cnt_notify; + u32 cnt_sum = 0; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return; + + seq_printf(m, "%s", "\n\r========== [Statistics] =========="); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF && + !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo.v7; + + seq_printf(m, + "\n\r %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d)," + "c2h_cnt=%d(fw_send:%d, len:%d, max:%d), ", + "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h), + rtwdev->btc.ver->info_buf); + + seq_printf(m, "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); + + if (dm->error.map.wl_fw_hang) + seq_puts(m, " (WL FW Hang!!)"); + + seq_printf(m, "\n\r %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + seq_printf(m, "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + seq_printf(m, + "\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]", + "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], + cx->cnt_wl[BTC_WCNT_RFK_GO], + cx->cnt_wl[BTC_WCNT_RFK_REJECT], + cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT], + wl->rfk_info.proc_time); + + seq_printf(m, ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + seq_printf(m, ", AOAC[RF_on:%d/RF_off:%d]", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + } else { + seq_printf(m, + "\n\r %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)", + "[summary]", + pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, + pfwinfo->cnt_c2h, + wl->status.map.lps, wl->status.map.rf_off); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + seq_printf(m, + "\n\r %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + seq_printf(m, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + seq_printf(m, + "\n\r %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW], + cnt[BTC_NCNT_SPECIAL_PACKET]); + + seq_printf(m, "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE], + rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW], + cnt[BTC_NCNT_COUNTRYCODE]); +} + static void _show_summary_v8(struct rtw89_dev *rtwdev, struct seq_file *m) { struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo; @@ -10440,6 +10585,8 @@ void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) _show_summary_v5(rtwdev, m); else if (ver->fcxbtcrpt == 105) _show_summary_v105(rtwdev, m); + else if (ver->fcxbtcrpt == 7) + _show_summary_v7(rtwdev, m); else if (ver->fcxbtcrpt == 8) _show_summary_v8(rtwdev, m); } diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 3edb2f4372e4..a9feb235c269 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2202,6 +2202,19 @@ struct rtw89_btc_fbtc_rpt_ctrl_v105 { struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; } __packed; +struct rtw89_btc_fbtc_rpt_ctrl_v7 { + u8 fver; + u8 rsvd0; + u8 rsvd1; + u8 rsvd2; + + u8 gnt_val[RTW89_PHY_MAX][4]; + __le16 bt_cnt[BTC_BCNT_STA_MAX_V105]; + + struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info; + struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; +} __packed; + struct rtw89_btc_fbtc_rpt_ctrl_v8 { u8 fver; u8 rsvd0; @@ -2220,6 +2233,7 @@ union rtw89_btc_fbtc_rpt_ctrl_ver_info { struct rtw89_btc_fbtc_rpt_ctrl_v4 v4; struct rtw89_btc_fbtc_rpt_ctrl_v5 v5; struct rtw89_btc_fbtc_rpt_ctrl_v105 v105; + struct rtw89_btc_fbtc_rpt_ctrl_v7 v7; struct rtw89_btc_fbtc_rpt_ctrl_v8 v8; }; -- 2.25.1