You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
357 lines
12 KiB
357 lines
12 KiB
From 0f546e1925b08b58052d8016abae821586d6117b Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@redhat.com>
|
|
Date: Wed, 24 May 2023 15:00:34 +0200
|
|
Subject: [PATCH 096/142] wifi: rtw89: coex: Add v4 version firmware cycle
|
|
report
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Bugzilla: https://bugzilla.redhat.com/2207499
|
|
|
|
commit 202c3b5c276f3f7525d9baabea7e8896d300ceff
|
|
Author: Ching-Te Ku <ku920601@realtek.com>
|
|
Date: Tue Jan 3 22:02:34 2023 +0800
|
|
|
|
wifi: rtw89: coex: Add v4 version firmware cycle report
|
|
|
|
To support v4 version firmware cycle report, apply the related
|
|
structure and functions. v4 cycle report add a group of status
|
|
to show how the free-run/TDMA training goes to. It is a firmware
|
|
mechanism that can auto adjust coexistence mode between TDMA and
|
|
free run mechanism at 3 antenna solution.
|
|
|
|
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
|
|
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
|
Signed-off-by: Kalle Valo <kvalo@kernel.org>
|
|
Link: https://lore.kernel.org/r/20230103140238.15601-4-pkshih@realtek.com
|
|
|
|
Signed-off-by: Íñigo Huguet <ihuguet@redhat.com>
|
|
---
|
|
drivers/net/wireless/realtek/rtw89/coex.c | 185 ++++++++++++++++++++++++++++++
|
|
drivers/net/wireless/realtek/rtw89/core.h | 67 +++++++++++
|
|
2 files changed, 252 insertions(+)
|
|
|
|
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
|
|
index be5ab2c4eefb3..b25329d1806a4 100644
|
|
--- a/drivers/net/wireless/realtek/rtw89/coex.c
|
|
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
|
|
@@ -1001,6 +1001,10 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
|
|
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 if (ver->fcxcysta == 4) {
|
|
+ pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo.v4;
|
|
+ pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4;
|
|
+ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo.v4);
|
|
} else {
|
|
goto err;
|
|
}
|
|
@@ -1259,6 +1263,48 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
|
|
le32_to_cpu(pcysta->v3.slot_cnt[CXST_B1]));
|
|
_chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE,
|
|
le16_to_cpu(pcysta->v3.cycles));
|
|
+ } else if (ver->fcxcysta == 4) {
|
|
+ if (le16_to_cpu(pcysta->v4.cycles) < BTC_CYSTA_CHK_PERIOD)
|
|
+ break;
|
|
+
|
|
+ cnt_leak_slot = le16_to_cpu(pcysta->v4.slot_cnt[CXST_LK]);
|
|
+ cnt_rx_imr = le32_to_cpu(pcysta->v4.leak_slot.cnt_rximr);
|
|
+
|
|
+ /* Check Leak-AP */
|
|
+ if (cnt_leak_slot != 0 && cnt_rx_imr != 0 &&
|
|
+ dm->tdma_now.rxflctrl) {
|
|
+ if (cnt_leak_slot < BTC_LEAK_AP_TH * cnt_rx_imr)
|
|
+ dm->leak_ap = 1;
|
|
+ }
|
|
+
|
|
+ /* 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->v4.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);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Check diff time between real BT slot and EBT/E5G slot */
|
|
+ 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->v4.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,
|
|
+ le16_to_cpu(pcysta->v4.slot_cnt[CXST_W1]));
|
|
+ _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE,
|
|
+ le16_to_cpu(pcysta->v4.slot_cnt[CXST_B1]));
|
|
+ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE,
|
|
+ le16_to_cpu(pcysta->v4.cycles));
|
|
} else {
|
|
goto err;
|
|
}
|
|
@@ -6178,6 +6224,10 @@ static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m)
|
|
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 if (ver->fcxcysta == 4) {
|
|
+ pcysta->v4 = pfwinfo->rpt_fbtc_cysta.finfo.v4;
|
|
+ except_cnt = pcysta->v4.except_cnt;
|
|
+ exception_map = le32_to_cpu(pcysta->v4.except_map);
|
|
} else {
|
|
return;
|
|
}
|
|
@@ -6569,6 +6619,139 @@ static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m)
|
|
}
|
|
}
|
|
|
|
+static void _show_fbtc_cysta_v4(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_v4 *a2dp_trx;
|
|
+ struct rtw89_btc_fbtc_cysta_v4 *pcysta;
|
|
+ struct rtw89_btc_rpt_cmn_info *pcinfo;
|
|
+ u8 i, cnt = 0, slot_pair, divide_cnt;
|
|
+ u16 cycle, c_begin, c_end, store_index;
|
|
+
|
|
+ pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo;
|
|
+ if (!pcinfo->valid)
|
|
+ return;
|
|
+
|
|
+ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v4;
|
|
+ seq_printf(m,
|
|
+ " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]",
|
|
+ "[cycle_cnt]",
|
|
+ le16_to_cpu(pcysta->cycles),
|
|
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL]),
|
|
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_ALL_OK]),
|
|
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_SLOT]),
|
|
+ le16_to_cpu(pcysta->bcn_cnt[CXBCN_BT_OK]));
|
|
+
|
|
+ for (i = 0; i < CXST_MAX; i++) {
|
|
+ if (!le16_to_cpu(pcysta->slot_cnt[i]))
|
|
+ continue;
|
|
+
|
|
+ seq_printf(m, ", %s:%d", id_to_slot(i),
|
|
+ le16_to_cpu(pcysta->slot_cnt[i]));
|
|
+ }
|
|
+
|
|
+ if (dm->tdma_now.rxflctrl)
|
|
+ seq_printf(m, ", leak_rx:%d",
|
|
+ le32_to_cpu(pcysta->leak_slot.cnt_rximr));
|
|
+
|
|
+ if (pcysta->collision_cnt)
|
|
+ seq_printf(m, ", collision:%d", pcysta->collision_cnt);
|
|
+
|
|
+ if (le16_to_cpu(pcysta->skip_cnt))
|
|
+ seq_printf(m, ", skip:%d",
|
|
+ le16_to_cpu(pcysta->skip_cnt));
|
|
+
|
|
+ seq_puts(m, "\n");
|
|
+
|
|
+ seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]",
|
|
+ "[cycle_time]",
|
|
+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_WL]),
|
|
+ le16_to_cpu(pcysta->cycle_time.tavg[CXT_BT]),
|
|
+ le16_to_cpu(pcysta->leak_slot.tavg) / 1000,
|
|
+ le16_to_cpu(pcysta->leak_slot.tavg) % 1000);
|
|
+ seq_printf(m,
|
|
+ ", max_t[wl:%d/bt:%d/lk:%d.%03d]",
|
|
+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_WL]),
|
|
+ le16_to_cpu(pcysta->cycle_time.tmax[CXT_BT]),
|
|
+ le16_to_cpu(pcysta->leak_slot.tmax) / 1000,
|
|
+ le16_to_cpu(pcysta->leak_slot.tmax) % 1000);
|
|
+ seq_printf(m,
|
|
+ ", maxdiff_t[wl:%d/bt:%d]\n",
|
|
+ le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_WL]),
|
|
+ le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT]));
|
|
+
|
|
+ cycle = le16_to_cpu(pcysta->cycles);
|
|
+ if (cycle == 0)
|
|
+ return;
|
|
+
|
|
+ /* 1 cycle record 1 wl-slot and 1 bt-slot */
|
|
+ slot_pair = BTC_CYCLE_SLOT_MAX / 2;
|
|
+
|
|
+ if (cycle <= slot_pair)
|
|
+ c_begin = 1;
|
|
+ else
|
|
+ c_begin = cycle - slot_pair + 1;
|
|
+
|
|
+ c_end = cycle;
|
|
+
|
|
+ if (a2dp->exist)
|
|
+ divide_cnt = 3;
|
|
+ else
|
|
+ divide_cnt = BTC_CYCLE_SLOT_MAX / 4;
|
|
+
|
|
+ for (cycle = c_begin; cycle <= c_end; cycle++) {
|
|
+ cnt++;
|
|
+ store_index = ((cycle - 1) % slot_pair) * 2;
|
|
+
|
|
+ if (cnt % divide_cnt == 1) {
|
|
+ seq_printf(m, "\n\r %-15s : ", "[cycle_step]");
|
|
+ } else {
|
|
+ seq_printf(m, "->b%02d",
|
|
+ le16_to_cpu(pcysta->slot_step_time[store_index]));
|
|
+ if (a2dp->exist) {
|
|
+ a2dp_trx = &pcysta->a2dp_trx[store_index];
|
|
+ seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
|
|
+ a2dp_trx->empty_cnt,
|
|
+ a2dp_trx->retry_cnt,
|
|
+ a2dp_trx->tx_rate ? 3 : 2,
|
|
+ a2dp_trx->tx_cnt,
|
|
+ a2dp_trx->ack_cnt,
|
|
+ a2dp_trx->nack_cnt);
|
|
+ }
|
|
+ seq_printf(m, "->w%02d",
|
|
+ le16_to_cpu(pcysta->slot_step_time[store_index + 1]));
|
|
+ if (a2dp->exist) {
|
|
+ a2dp_trx = &pcysta->a2dp_trx[store_index + 1];
|
|
+ seq_printf(m, "(%d/%d/%dM/%d/%d/%d)",
|
|
+ a2dp_trx->empty_cnt,
|
|
+ a2dp_trx->retry_cnt,
|
|
+ a2dp_trx->tx_rate ? 3 : 2,
|
|
+ a2dp_trx->tx_cnt,
|
|
+ a2dp_trx->ack_cnt,
|
|
+ a2dp_trx->nack_cnt);
|
|
+ }
|
|
+ }
|
|
+ if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end)
|
|
+ seq_puts(m, "\n");
|
|
+ }
|
|
+
|
|
+ if (a2dp->exist) {
|
|
+ seq_printf(m, "%-15s : a2dp_ept:%d, a2dp_late:%d",
|
|
+ "[a2dp_t_sta]",
|
|
+ le16_to_cpu(pcysta->a2dp_ept.cnt),
|
|
+ le16_to_cpu(pcysta->a2dp_ept.cnt_timeout));
|
|
+
|
|
+ seq_printf(m, ", avg_t:%d, max_t:%d",
|
|
+ le16_to_cpu(pcysta->a2dp_ept.tavg),
|
|
+ le16_to_cpu(pcysta->a2dp_ept.tmax));
|
|
+
|
|
+ seq_puts(m, "\n");
|
|
+ }
|
|
+}
|
|
+
|
|
static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m)
|
|
{
|
|
const struct rtw89_chip_info *chip = rtwdev->chip;
|
|
@@ -6727,6 +6910,8 @@ static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m)
|
|
_show_fbtc_cysta_v2(rtwdev, m);
|
|
else if (ver->fcxcysta == 3)
|
|
_show_fbtc_cysta_v3(rtwdev, m);
|
|
+ else if (ver->fcxcysta == 4)
|
|
+ _show_fbtc_cysta_v4(rtwdev, m);
|
|
|
|
_show_fbtc_nullsta(rtwdev, m);
|
|
_show_fbtc_step(rtwdev, m);
|
|
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
|
|
index 6af70eabb9080..9f4cb83a8326f 100644
|
|
--- a/drivers/net/wireless/realtek/rtw89/core.h
|
|
+++ b/drivers/net/wireless/realtek/rtw89/core.h
|
|
@@ -1730,6 +1730,17 @@ struct rtw89_btc_fbtc_a2dp_trx_stat {
|
|
u8 rsvd2;
|
|
} __packed;
|
|
|
|
+struct rtw89_btc_fbtc_a2dp_trx_stat_v4 {
|
|
+ u8 empty_cnt;
|
|
+ u8 retry_cnt;
|
|
+ u8 tx_rate;
|
|
+ u8 tx_cnt;
|
|
+ u8 ack_cnt;
|
|
+ u8 nack_cnt;
|
|
+ u8 no_empty_cnt;
|
|
+ u8 rsvd;
|
|
+} __packed;
|
|
+
|
|
struct rtw89_btc_fbtc_cycle_a2dp_empty_info {
|
|
__le16 cnt; /* a2dp empty cnt */
|
|
__le16 cnt_timeout; /* a2dp empty timeout cnt*/
|
|
@@ -1743,6 +1754,34 @@ struct rtw89_btc_fbtc_cycle_leak_info {
|
|
__le16 tmax; /* max leak-slot time */
|
|
} __packed;
|
|
|
|
+#define RTW89_BTC_FDDT_PHASE_CYCLE GENMASK(9, 0)
|
|
+#define RTW89_BTC_FDDT_TRAIN_STEP GENMASK(15, 10)
|
|
+
|
|
+struct rtw89_btc_fbtc_cycle_fddt_info {
|
|
+ __le16 train_cycle;
|
|
+ __le16 tp;
|
|
+
|
|
+ s8 tx_power; /* absolute Tx power (dBm), 0xff-> no BTC control */
|
|
+ s8 bt_tx_power; /* decrease Tx power (dB) */
|
|
+ s8 bt_rx_gain; /* LNA constrain level */
|
|
+ u8 no_empty_cnt;
|
|
+
|
|
+ u8 rssi; /* [7:4] -> bt_rssi_level, [3:0]-> wl_rssi_level */
|
|
+ u8 cn; /* condition_num */
|
|
+ u8 train_status; /* [7:4]-> train-state, [3:0]-> train-phase */
|
|
+ u8 train_result; /* refer to enum btc_fddt_check_map */
|
|
+} __packed;
|
|
+
|
|
+#define RTW89_BTC_FDDT_CELL_TRAIN_STATE GENMASK(3, 0)
|
|
+#define RTW89_BTC_FDDT_CELL_TRAIN_PHASE GENMASK(7, 4)
|
|
+
|
|
+struct rtw89_btc_fbtc_fddt_cell_status {
|
|
+ s8 wl_tx_pwr;
|
|
+ s8 bt_tx_pwr;
|
|
+ s8 bt_rx_gain;
|
|
+ u8 state_phase; /* [0:3] train state, [4:7] train phase */
|
|
+} __packed;
|
|
+
|
|
struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */
|
|
u8 fver;
|
|
u8 rsvd;
|
|
@@ -1761,9 +1800,37 @@ struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */
|
|
__le32 except_map;
|
|
} __packed;
|
|
|
|
+#define FDD_TRAIN_WL_DIRECTION 2
|
|
+#define FDD_TRAIN_WL_RSSI_LEVEL 5
|
|
+#define FDD_TRAIN_BT_RSSI_LEVEL 5
|
|
+
|
|
+struct rtw89_btc_fbtc_cysta_v4 { /* statistics for cycles */
|
|
+ u8 fver;
|
|
+ u8 rsvd;
|
|
+ u8 collision_cnt; /* counter for event/timer occur at the same time */
|
|
+ u8 except_cnt;
|
|
+
|
|
+ __le16 skip_cnt;
|
|
+ __le16 cycles; /* total cycle number */
|
|
+
|
|
+ __le16 slot_step_time[BTC_CYCLE_SLOT_MAX]; /* record the wl/bt slot time */
|
|
+ __le16 slot_cnt[CXST_MAX]; /* slot count */
|
|
+ __le16 bcn_cnt[CXBCN_MAX];
|
|
+ struct rtw89_btc_fbtc_cycle_time_info cycle_time;
|
|
+ struct rtw89_btc_fbtc_cycle_leak_info leak_slot;
|
|
+ struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept;
|
|
+ struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX];
|
|
+ struct rtw89_btc_fbtc_cycle_fddt_info fddt_trx[BTC_CYCLE_SLOT_MAX];
|
|
+ struct rtw89_btc_fbtc_fddt_cell_status fddt_cells[FDD_TRAIN_WL_DIRECTION]
|
|
+ [FDD_TRAIN_WL_RSSI_LEVEL]
|
|
+ [FDD_TRAIN_BT_RSSI_LEVEL];
|
|
+ __le32 except_map;
|
|
+} __packed;
|
|
+
|
|
union rtw89_btc_fbtc_cysta_info {
|
|
struct rtw89_btc_fbtc_cysta_v2 v2;
|
|
struct rtw89_btc_fbtc_cysta_v3 v3;
|
|
+ struct rtw89_btc_fbtc_cysta_v4 v4;
|
|
};
|
|
|
|
struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */
|
|
--
|
|
2.13.6
|
|
|