11556Srgrimes// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
21556Srgrimes/* Copyright(c) 2019-2020  Realtek Corporation
31556Srgrimes */
41556Srgrimes
51556Srgrimes#include "debug.h"
61556Srgrimes#include "efuse.h"
71556Srgrimes#include "fw.h"
81556Srgrimes#include "mac.h"
91556Srgrimes#include "reg.h"
101556Srgrimes
111556Srgrimesstatic const u32 rtw89_mac_mem_base_addrs_be[RTW89_MAC_MEM_NUM] = {
121556Srgrimes	[RTW89_MAC_MEM_AXIDMA]	        = AXIDMA_BASE_ADDR_BE,
131556Srgrimes	[RTW89_MAC_MEM_SHARED_BUF]	= SHARED_BUF_BASE_ADDR_BE,
141556Srgrimes	[RTW89_MAC_MEM_DMAC_TBL]	= DMAC_TBL_BASE_ADDR_BE,
151556Srgrimes	[RTW89_MAC_MEM_SHCUT_MACHDR]	= SHCUT_MACHDR_BASE_ADDR_BE,
161556Srgrimes	[RTW89_MAC_MEM_STA_SCHED]	= STA_SCHED_BASE_ADDR_BE,
171556Srgrimes	[RTW89_MAC_MEM_RXPLD_FLTR_CAM]	= RXPLD_FLTR_CAM_BASE_ADDR_BE,
181556Srgrimes	[RTW89_MAC_MEM_SECURITY_CAM]	= SEC_CAM_BASE_ADDR_BE,
191556Srgrimes	[RTW89_MAC_MEM_WOW_CAM]		= WOW_CAM_BASE_ADDR_BE,
201556Srgrimes	[RTW89_MAC_MEM_CMAC_TBL]	= CMAC_TBL_BASE_ADDR_BE,
211556Srgrimes	[RTW89_MAC_MEM_ADDR_CAM]	= ADDR_CAM_BASE_ADDR_BE,
221556Srgrimes	[RTW89_MAC_MEM_BA_CAM]		= BA_CAM_BASE_ADDR_BE,
231556Srgrimes	[RTW89_MAC_MEM_BCN_IE_CAM0]	= BCN_IE_CAM0_BASE_ADDR_BE,
241556Srgrimes	[RTW89_MAC_MEM_BCN_IE_CAM1]	= BCN_IE_CAM1_BASE_ADDR_BE,
251556Srgrimes	[RTW89_MAC_MEM_TXD_FIFO_0]	= TXD_FIFO_0_BASE_ADDR_BE,
261556Srgrimes	[RTW89_MAC_MEM_TXD_FIFO_1]	= TXD_FIFO_1_BASE_ADDR_BE,
271556Srgrimes	[RTW89_MAC_MEM_TXDATA_FIFO_0]	= TXDATA_FIFO_0_BASE_ADDR_BE,
281556Srgrimes	[RTW89_MAC_MEM_TXDATA_FIFO_1]	= TXDATA_FIFO_1_BASE_ADDR_BE,
291556Srgrimes	[RTW89_MAC_MEM_CPU_LOCAL]	= CPU_LOCAL_BASE_ADDR_BE,
301556Srgrimes	[RTW89_MAC_MEM_BSSID_CAM]	= BSSID_CAM_BASE_ADDR_BE,
311556Srgrimes	[RTW89_MAC_MEM_WD_PAGE]		= WD_PAGE_BASE_ADDR_BE,
321556Srgrimes};
331556Srgrimes
341556Srgrimesstatic const struct rtw89_port_reg rtw89_port_base_be = {
351556Srgrimes	.port_cfg = R_BE_PORT_CFG_P0,
361556Srgrimes	.tbtt_prohib = R_BE_TBTT_PROHIB_P0,
371556Srgrimes	.bcn_area = R_BE_BCN_AREA_P0,
381556Srgrimes	.bcn_early = R_BE_BCNERLYINT_CFG_P0,
391556Srgrimes	.tbtt_early = R_BE_TBTTERLYINT_CFG_P0,
401556Srgrimes	.tbtt_agg = R_BE_TBTT_AGG_P0,
411556Srgrimes	.bcn_space = R_BE_BCN_SPACE_CFG_P0,
421556Srgrimes	.bcn_forcetx = R_BE_BCN_FORCETX_P0,
431556Srgrimes	.bcn_err_cnt = R_BE_BCN_ERR_CNT_P0,
441556Srgrimes	.bcn_err_flag = R_BE_BCN_ERR_FLAG_P0,
451556Srgrimes	.dtim_ctrl = R_BE_DTIM_CTRL_P0,
461556Srgrimes	.tbtt_shift = R_BE_TBTT_SHIFT_P0,
471556Srgrimes	.bcn_cnt_tmr = R_BE_BCN_CNT_TMR_P0,
481556Srgrimes	.tsftr_l = R_BE_TSFTR_LOW_P0,
491556Srgrimes	.tsftr_h = R_BE_TSFTR_HIGH_P0,
501556Srgrimes	.md_tsft = R_BE_WMTX_MOREDATA_TSFT_STMP_CTL,
511556Srgrimes	.bss_color = R_BE_PTCL_BSS_COLOR_0,
521556Srgrimes	.mbssid = R_BE_MBSSID_CTRL,
531556Srgrimes	.mbssid_drop = R_BE_MBSSID_DROP_0,
541556Srgrimes	.tsf_sync = R_BE_PORT_0_TSF_SYNC,
551556Srgrimes	.ptcl_dbg = R_BE_PTCL_DBG,
561556Srgrimes	.ptcl_dbg_info = R_BE_PTCL_DBG_INFO,
571556Srgrimes	.bcn_drop_all = R_BE_BCN_DROP_ALL0,
581556Srgrimes	.hiq_win = {R_BE_P0MB_HGQ_WINDOW_CFG_0, R_BE_PORT_HGQ_WINDOW_CFG,
591556Srgrimes		    R_BE_PORT_HGQ_WINDOW_CFG + 1, R_BE_PORT_HGQ_WINDOW_CFG + 2,
601556Srgrimes		    R_BE_PORT_HGQ_WINDOW_CFG + 3},
611556Srgrimes};
621556Srgrimes
631556Srgrimesstatic int rtw89_mac_check_mac_en_be(struct rtw89_dev *rtwdev, u8 mac_idx,
641556Srgrimes				     enum rtw89_mac_hwmod_sel sel)
651556Srgrimes{
661556Srgrimes	if (sel == RTW89_DMAC_SEL &&
671556Srgrimes	    test_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags))
681556Srgrimes		return 0;
691556Srgrimes	if (sel == RTW89_CMAC_SEL && mac_idx == RTW89_MAC_0 &&
701556Srgrimes	    test_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags))
711556Srgrimes		return 0;
72	if (sel == RTW89_CMAC_SEL && mac_idx == RTW89_MAC_1 &&
73	    test_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags))
74		return 0;
75
76	return -EFAULT;
77}
78
79static bool is_qta_poh(struct rtw89_dev *rtwdev)
80{
81	return rtwdev->hci.type == RTW89_HCI_TYPE_PCIE;
82}
83
84static void hfc_get_mix_info_be(struct rtw89_dev *rtwdev)
85{
86	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
87	struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
88	struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
89	struct rtw89_hfc_pub_info *info = &param->pub_info;
90	u32 val;
91
92	val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO1);
93	info->g0_used = u32_get_bits(val, B_BE_G0_USE_PG_MASK);
94	info->g1_used = u32_get_bits(val, B_BE_G1_USE_PG_MASK);
95
96	val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO3);
97	info->g0_aval = u32_get_bits(val, B_BE_G0_AVAL_PG_MASK);
98	info->g1_aval = u32_get_bits(val, B_BE_G1_AVAL_PG_MASK);
99	info->pub_aval = u32_get_bits(rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO2),
100				      B_BE_PUB_AVAL_PG_MASK);
101	info->wp_aval = u32_get_bits(rtw89_read32(rtwdev, R_BE_WP_PAGE_INFO1),
102				     B_BE_WP_AVAL_PG_MASK);
103
104	val = rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL);
105	param->en = !!(val & B_BE_HCI_FC_EN);
106	param->h2c_en = !!(val & B_BE_HCI_FC_CH12_EN);
107	param->mode = u32_get_bits(val, B_BE_HCI_FC_MODE_MASK);
108	prec_cfg->ch011_full_cond = u32_get_bits(val, B_BE_HCI_FC_WD_FULL_COND_MASK);
109	prec_cfg->h2c_full_cond = u32_get_bits(val, B_BE_HCI_FC_CH12_FULL_COND_MASK);
110	prec_cfg->wp_ch07_full_cond =
111		u32_get_bits(val, B_BE_HCI_FC_WP_CH07_FULL_COND_MASK);
112	prec_cfg->wp_ch811_full_cond =
113		u32_get_bits(val, B_BE_HCI_FC_WP_CH811_FULL_COND_MASK);
114
115	val = rtw89_read32(rtwdev, R_BE_CH_PAGE_CTRL);
116	prec_cfg->ch011_prec = u32_get_bits(val, B_BE_PREC_PAGE_CH011_V1_MASK);
117	prec_cfg->h2c_prec = u32_get_bits(val, B_BE_PREC_PAGE_CH12_V1_MASK);
118
119	val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_CTRL2);
120	pub_cfg->pub_max = u32_get_bits(val, B_BE_PUBPG_ALL_MASK);
121
122	val = rtw89_read32(rtwdev, R_BE_WP_PAGE_CTRL1);
123	prec_cfg->wp_ch07_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH07_MASK);
124	prec_cfg->wp_ch811_prec = u32_get_bits(val, B_BE_PREC_PAGE_WP_CH811_MASK);
125
126	val = rtw89_read32(rtwdev, R_BE_WP_PAGE_CTRL2);
127	pub_cfg->wp_thrd = u32_get_bits(val, B_BE_WP_THRD_MASK);
128
129	val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_CTRL1);
130	pub_cfg->grp0 = u32_get_bits(val, B_BE_PUBPG_G0_MASK);
131	pub_cfg->grp1 = u32_get_bits(val, B_BE_PUBPG_G1_MASK);
132}
133
134static void hfc_h2c_cfg_be(struct rtw89_dev *rtwdev)
135{
136	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
137	const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
138	u32 val;
139
140	val = u32_encode_bits(prec_cfg->h2c_prec, B_BE_PREC_PAGE_CH12_V1_MASK);
141	rtw89_write32(rtwdev, R_BE_CH_PAGE_CTRL, val);
142}
143
144static void hfc_mix_cfg_be(struct rtw89_dev *rtwdev)
145{
146	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
147	const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
148	const struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
149	u32 val;
150
151	val = u32_encode_bits(prec_cfg->ch011_prec, B_BE_PREC_PAGE_CH011_V1_MASK) |
152	      u32_encode_bits(prec_cfg->h2c_prec, B_BE_PREC_PAGE_CH12_V1_MASK);
153	rtw89_write32(rtwdev, R_BE_CH_PAGE_CTRL, val);
154
155	val = u32_encode_bits(pub_cfg->pub_max, B_BE_PUBPG_ALL_MASK);
156	rtw89_write32(rtwdev, R_BE_PUB_PAGE_CTRL2, val);
157
158	val = u32_encode_bits(prec_cfg->wp_ch07_prec, B_BE_PREC_PAGE_WP_CH07_MASK) |
159	      u32_encode_bits(prec_cfg->wp_ch811_prec, B_BE_PREC_PAGE_WP_CH811_MASK);
160	rtw89_write32(rtwdev, R_BE_WP_PAGE_CTRL1, val);
161
162	val = u32_replace_bits(rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL),
163			       param->mode, B_BE_HCI_FC_MODE_MASK);
164	val = u32_replace_bits(val, prec_cfg->ch011_full_cond,
165			       B_BE_HCI_FC_WD_FULL_COND_MASK);
166	val = u32_replace_bits(val, prec_cfg->h2c_full_cond,
167			       B_BE_HCI_FC_CH12_FULL_COND_MASK);
168	val = u32_replace_bits(val, prec_cfg->wp_ch07_full_cond,
169			       B_BE_HCI_FC_WP_CH07_FULL_COND_MASK);
170	val = u32_replace_bits(val, prec_cfg->wp_ch811_full_cond,
171			       B_BE_HCI_FC_WP_CH811_FULL_COND_MASK);
172	rtw89_write32(rtwdev, R_BE_HCI_FC_CTRL, val);
173}
174
175static void hfc_func_en_be(struct rtw89_dev *rtwdev, bool en, bool h2c_en)
176{
177	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
178	u32 val;
179
180	val = rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL);
181	param->en = en;
182	param->h2c_en = h2c_en;
183	val = en ? (val | B_BE_HCI_FC_EN) : (val & ~B_BE_HCI_FC_EN);
184	val = h2c_en ? (val | B_BE_HCI_FC_CH12_EN) :
185		       (val & ~B_BE_HCI_FC_CH12_EN);
186	rtw89_write32(rtwdev, R_BE_HCI_FC_CTRL, val);
187}
188
189static void dle_func_en_be(struct rtw89_dev *rtwdev, bool enable)
190{
191	if (enable)
192		rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN,
193				  B_BE_DLE_WDE_EN | B_BE_DLE_PLE_EN);
194	else
195		rtw89_write32_clr(rtwdev, R_BE_DMAC_FUNC_EN,
196				  B_BE_DLE_WDE_EN | B_BE_DLE_PLE_EN);
197}
198
199static void dle_clk_en_be(struct rtw89_dev *rtwdev, bool enable)
200{
201	if (enable)
202		rtw89_write32_set(rtwdev, R_BE_DMAC_CLK_EN,
203				  B_BE_DLE_WDE_CLK_EN | B_BE_DLE_PLE_CLK_EN);
204	else
205		rtw89_write32_clr(rtwdev, R_BE_DMAC_CLK_EN,
206				  B_BE_DLE_WDE_CLK_EN | B_BE_DLE_PLE_CLK_EN);
207}
208
209static int dle_mix_cfg_be(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg)
210{
211	const struct rtw89_dle_size *wde_size_cfg, *ple_size_cfg;
212	u32 bound;
213	u32 val;
214
215	wde_size_cfg = cfg->wde_size;
216	ple_size_cfg = cfg->ple_size;
217
218	val = rtw89_read32(rtwdev, R_BE_WDE_PKTBUF_CFG);
219
220	switch (wde_size_cfg->pge_size) {
221	default:
222	case RTW89_WDE_PG_64:
223		val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_64,
224				       B_BE_WDE_PAGE_SEL_MASK);
225		break;
226	case RTW89_WDE_PG_128:
227		val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_128,
228				       B_BE_WDE_PAGE_SEL_MASK);
229		break;
230	case RTW89_WDE_PG_256:
231		rtw89_err(rtwdev, "[ERR]WDE DLE doesn't support 256 byte!\n");
232		return -EINVAL;
233	}
234
235	bound = wde_size_cfg->srt_ofst / DLE_BOUND_UNIT;
236	val = u32_replace_bits(val, bound, B_BE_WDE_START_BOUND_MASK);
237	val = u32_replace_bits(val, wde_size_cfg->lnk_pge_num,
238			       B_BE_WDE_FREE_PAGE_NUM_MASK);
239	rtw89_write32(rtwdev, R_BE_WDE_PKTBUF_CFG, val);
240
241	val = rtw89_read32(rtwdev, R_BE_PLE_PKTBUF_CFG);
242
243	switch (ple_size_cfg->pge_size) {
244	default:
245	case RTW89_PLE_PG_64:
246		rtw89_err(rtwdev, "[ERR]PLE DLE doesn't support 64 byte!\n");
247		return -EINVAL;
248	case RTW89_PLE_PG_128:
249		val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_128,
250				       B_BE_PLE_PAGE_SEL_MASK);
251		break;
252	case RTW89_PLE_PG_256:
253		val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_256,
254				       B_BE_PLE_PAGE_SEL_MASK);
255		break;
256	}
257
258	bound = ple_size_cfg->srt_ofst / DLE_BOUND_UNIT;
259	val = u32_replace_bits(val, bound, B_BE_PLE_START_BOUND_MASK);
260	val = u32_replace_bits(val, ple_size_cfg->lnk_pge_num,
261			       B_BE_PLE_FREE_PAGE_NUM_MASK);
262	rtw89_write32(rtwdev, R_BE_PLE_PKTBUF_CFG, val);
263
264	return 0;
265}
266
267static int chk_dle_rdy_be(struct rtw89_dev *rtwdev, bool wde_or_ple)
268{
269	u32 reg, mask;
270	u32 ini;
271
272	if (wde_or_ple) {
273		reg = R_AX_WDE_INI_STATUS;
274		mask = WDE_MGN_INI_RDY;
275	} else {
276		reg = R_AX_PLE_INI_STATUS;
277		mask = PLE_MGN_INI_RDY;
278	}
279
280	return read_poll_timeout(rtw89_read32, ini, (ini & mask) == mask, 1,
281				2000, false, rtwdev, reg);
282}
283
284#define INVALID_QT_WCPU U16_MAX
285#define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx)			\
286	do {								\
287		val = u32_encode_bits(_min_x, B_BE_ ## _module ## _Q ## _idx ## _MIN_SIZE_MASK) | \
288		      u32_encode_bits(_max_x, B_BE_ ## _module ## _Q ## _idx ## _MAX_SIZE_MASK);  \
289		rtw89_write32(rtwdev,					\
290			      R_BE_ ## _module ## _QTA ## _idx ## _CFG,	\
291			      val);					\
292	} while (0)
293#define SET_QUOTA(_x, _module, _idx)					\
294	SET_QUOTA_VAL(min_cfg->_x, max_cfg->_x, _module, _idx)
295
296static void wde_quota_cfg_be(struct rtw89_dev *rtwdev,
297			     const struct rtw89_wde_quota *min_cfg,
298			     const struct rtw89_wde_quota *max_cfg,
299			     u16 ext_wde_min_qt_wcpu)
300{
301	u16 min_qt_wcpu = ext_wde_min_qt_wcpu != INVALID_QT_WCPU ?
302			  ext_wde_min_qt_wcpu : min_cfg->wcpu;
303	u16 max_qt_wcpu = max(max_cfg->wcpu, min_qt_wcpu);
304	u32 val;
305
306	SET_QUOTA(hif, WDE, 0);
307	SET_QUOTA_VAL(min_qt_wcpu, max_qt_wcpu, WDE, 1);
308	SET_QUOTA_VAL(0, 0, WDE, 2);
309	SET_QUOTA(pkt_in, WDE, 3);
310	SET_QUOTA(cpu_io, WDE, 4);
311}
312
313static void ple_quota_cfg_be(struct rtw89_dev *rtwdev,
314			     const struct rtw89_ple_quota *min_cfg,
315			     const struct rtw89_ple_quota *max_cfg)
316{
317	u32 val;
318
319	SET_QUOTA(cma0_tx, PLE, 0);
320	SET_QUOTA(cma1_tx, PLE, 1);
321	SET_QUOTA(c2h, PLE, 2);
322	SET_QUOTA(h2c, PLE, 3);
323	SET_QUOTA(wcpu, PLE, 4);
324	SET_QUOTA(mpdu_proc, PLE, 5);
325	SET_QUOTA(cma0_dma, PLE, 6);
326	SET_QUOTA(cma1_dma, PLE, 7);
327	SET_QUOTA(bb_rpt, PLE, 8);
328	SET_QUOTA(wd_rel, PLE, 9);
329	SET_QUOTA(cpu_io, PLE, 10);
330	SET_QUOTA(tx_rpt, PLE, 11);
331	SET_QUOTA(h2d, PLE, 12);
332}
333
334static void rtw89_mac_hci_func_en_be(struct rtw89_dev *rtwdev)
335{
336	rtw89_write32_set(rtwdev, R_BE_HCI_FUNC_EN, B_BE_HCI_TXDMA_EN |
337						    B_BE_HCI_RXDMA_EN);
338}
339
340static void rtw89_mac_dmac_func_pre_en_be(struct rtw89_dev *rtwdev)
341{
342	u32 val;
343
344	val = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1);
345
346	switch (rtwdev->hci.type) {
347	case RTW89_HCI_TYPE_PCIE:
348		val = u32_replace_bits(val, S_BE_DMA_MOD_PCIE_NO_DATA_CPU,
349				       B_BE_DMA_MODE_MASK);
350		break;
351	case RTW89_HCI_TYPE_USB:
352		val = u32_replace_bits(val, S_BE_DMA_MOD_USB, B_BE_DMA_MODE_MASK);
353		val = (val & ~B_BE_STOP_AXI_MST) | B_BE_TXDMA_EN | B_BE_RXDMA_EN;
354		break;
355	case RTW89_HCI_TYPE_SDIO:
356		val = u32_replace_bits(val, S_BE_DMA_MOD_SDIO, B_BE_DMA_MODE_MASK);
357		val = (val & ~B_BE_STOP_AXI_MST) | B_BE_TXDMA_EN | B_BE_RXDMA_EN;
358		break;
359	default:
360		return;
361	}
362
363	rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val);
364
365	rtw89_write32_clr(rtwdev, R_BE_HAXI_DMA_STOP1,
366			  B_BE_STOP_CH0 | B_BE_STOP_CH1 | B_BE_STOP_CH2 |
367			  B_BE_STOP_CH3 | B_BE_STOP_CH4 | B_BE_STOP_CH5 |
368			  B_BE_STOP_CH6 | B_BE_STOP_CH7 | B_BE_STOP_CH8 |
369			  B_BE_STOP_CH9 | B_BE_STOP_CH10 | B_BE_STOP_CH11 |
370			  B_BE_STOP_CH12 | B_BE_STOP_CH13 | B_BE_STOP_CH14);
371
372	rtw89_write32_set(rtwdev, R_BE_DMAC_TABLE_CTRL, B_BE_DMAC_ADDR_MODE);
373}
374
375static
376int rtw89_mac_write_xtal_si_be(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask)
377{
378	u32 val32;
379	int ret;
380
381	val32 = u32_encode_bits(offset, B_BE_WL_XTAL_SI_ADDR_MASK) |
382		u32_encode_bits(val, B_BE_WL_XTAL_SI_DATA_MASK) |
383		u32_encode_bits(mask, B_BE_WL_XTAL_SI_BITMASK_MASK) |
384		u32_encode_bits(XTAL_SI_NORMAL_WRITE, B_BE_WL_XTAL_SI_MODE_MASK) |
385		u32_encode_bits(0, B_BE_WL_XTAL_SI_CHIPID_MASK) |
386		B_BE_WL_XTAL_SI_CMD_POLL;
387	rtw89_write32(rtwdev, R_BE_WLAN_XTAL_SI_CTRL, val32);
388
389	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_WL_XTAL_SI_CMD_POLL),
390				50, 50000, false, rtwdev, R_BE_WLAN_XTAL_SI_CTRL);
391	if (ret) {
392		rtw89_warn(rtwdev, "xtal si not ready(W): offset=%x val=%x mask=%x\n",
393			   offset, val, mask);
394		return ret;
395	}
396
397	return 0;
398}
399
400static
401int rtw89_mac_read_xtal_si_be(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
402{
403	u32 val32;
404	int ret;
405
406	val32 = u32_encode_bits(offset, B_BE_WL_XTAL_SI_ADDR_MASK) |
407		u32_encode_bits(0x0, B_BE_WL_XTAL_SI_DATA_MASK) |
408		u32_encode_bits(0x0, B_BE_WL_XTAL_SI_BITMASK_MASK) |
409		u32_encode_bits(XTAL_SI_NORMAL_READ, B_BE_WL_XTAL_SI_MODE_MASK) |
410		u32_encode_bits(0, B_BE_WL_XTAL_SI_CHIPID_MASK) |
411		B_BE_WL_XTAL_SI_CMD_POLL;
412	rtw89_write32(rtwdev, R_BE_WLAN_XTAL_SI_CTRL, val32);
413
414	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_WL_XTAL_SI_CMD_POLL),
415				50, 50000, false, rtwdev, R_BE_WLAN_XTAL_SI_CTRL);
416	if (ret) {
417		rtw89_warn(rtwdev, "xtal si not ready(R): offset=%x\n", offset);
418		return ret;
419	}
420
421	*val = rtw89_read8(rtwdev, R_BE_WLAN_XTAL_SI_CTRL + 1);
422
423	return 0;
424}
425
426static void rtw89_mac_disable_cpu_be(struct rtw89_dev *rtwdev)
427{
428	u32 val32;
429
430	clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
431
432	rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN);
433	rtw89_write32_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_HOLD_AFTER_RESET);
434	rtw89_write32_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN);
435
436	val32 = rtw89_read32(rtwdev, R_BE_WCPU_FW_CTRL);
437	val32 &= B_BE_RUN_ENV_MASK;
438	rtw89_write32(rtwdev, R_BE_WCPU_FW_CTRL, val32);
439
440	rtw89_write32_set(rtwdev, R_BE_DCPU_PLATFORM_ENABLE, B_BE_DCPU_PLATFORM_EN);
441
442	rtw89_write32(rtwdev, R_BE_UDM0, 0);
443	rtw89_write32(rtwdev, R_BE_HALT_C2H, 0);
444	rtw89_write32(rtwdev, R_BE_UDM2, 0);
445}
446
447static void set_cpu_en(struct rtw89_dev *rtwdev, bool include_bb)
448{
449	u32 set = B_BE_WLANCPU_FWDL_EN;
450
451	if (include_bb)
452		set |= B_BE_BBMCU0_FWDL_EN;
453
454	rtw89_write32_set(rtwdev, R_BE_WCPU_FW_CTRL, set);
455}
456
457static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw)
458{
459	u32 val32;
460	int ret;
461
462	val32 = rtw89_read32(rtwdev, R_BE_HALT_C2H);
463	if (val32) {
464		rtw89_warn(rtwdev, "[SER] AON L2 Debug register not empty before Boot.\n");
465		rtw89_warn(rtwdev, "[SER] %s: R_BE_HALT_C2H = 0x%x\n", __func__, val32);
466	}
467	val32 = rtw89_read32(rtwdev, R_BE_UDM1);
468	if (val32) {
469		rtw89_warn(rtwdev, "[SER] AON L2 Debug register not empty before Boot.\n");
470		rtw89_warn(rtwdev, "[SER] %s: R_BE_UDM1 = 0x%x\n", __func__, val32);
471	}
472	val32 = rtw89_read32(rtwdev, R_BE_UDM2);
473	if (val32) {
474		rtw89_warn(rtwdev, "[SER] AON L2 Debug register not empty before Boot.\n");
475		rtw89_warn(rtwdev, "[SER] %s: R_BE_UDM2 = 0x%x\n", __func__, val32);
476	}
477
478	rtw89_write32(rtwdev, R_BE_UDM1, 0);
479	rtw89_write32(rtwdev, R_BE_UDM2, 0);
480	rtw89_write32(rtwdev, R_BE_HALT_H2C, 0);
481	rtw89_write32(rtwdev, R_BE_HALT_C2H, 0);
482	rtw89_write32(rtwdev, R_BE_HALT_H2C_CTRL, 0);
483	rtw89_write32(rtwdev, R_BE_HALT_C2H_CTRL, 0);
484
485	val32 = rtw89_read32(rtwdev, R_BE_HISR0);
486	rtw89_write32(rtwdev, R_BE_HISR0, B_BE_HALT_C2H_INT);
487	rtw89_debug(rtwdev, RTW89_DBG_SER, "HISR0=0x%x\n", val32);
488
489	rtw89_write32_set(rtwdev, R_BE_SYS_CLK_CTRL, B_BE_CPU_CLK_EN);
490	rtw89_write32_clr(rtwdev, R_BE_SYS_CFG5,
491			  B_BE_WDT_WAKE_PCIE_EN | B_BE_WDT_WAKE_USB_EN);
492	rtw89_write32_clr(rtwdev, R_BE_WCPU_FW_CTRL,
493			  B_BE_WDT_PLT_RST_EN | B_BE_WCPU_ROM_CUT_GET);
494
495	rtw89_write16_mask(rtwdev, R_BE_BOOT_REASON, B_BE_BOOT_REASON_MASK, boot_reason);
496	rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN);
497	rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_HOLD_AFTER_RESET);
498	rtw89_write32_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN);
499
500	if (!dlfw) {
501		ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE);
502		if (ret)
503			return ret;
504	}
505
506	return 0;
507}
508
509static int rtw89_mac_fwdl_enable_wcpu_be(struct rtw89_dev *rtwdev,
510					 u8 boot_reason, bool dlfw,
511					 bool include_bb)
512{
513	set_cpu_en(rtwdev, include_bb);
514
515	return wcpu_on(rtwdev, boot_reason, dlfw);
516}
517
518static const u8 fwdl_status_map[] = {
519	[0] = RTW89_FWDL_INITIAL_STATE,
520	[1] = RTW89_FWDL_FWDL_ONGOING,
521	[4] = RTW89_FWDL_CHECKSUM_FAIL,
522	[5] = RTW89_FWDL_SECURITY_FAIL,
523	[6] = RTW89_FWDL_SECURITY_FAIL,
524	[7] = RTW89_FWDL_CV_NOT_MATCH,
525	[8] = RTW89_FWDL_RSVD0,
526	[2] = RTW89_FWDL_WCPU_FWDL_RDY,
527	[3] = RTW89_FWDL_WCPU_FW_INIT_RDY,
528	[9] = RTW89_FWDL_RSVD0,
529};
530
531static u8 fwdl_get_status_be(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type)
532{
533	bool check_pass = false;
534	u32 val32;
535	u8 st;
536
537	val32 = rtw89_read32(rtwdev, R_BE_WCPU_FW_CTRL);
538
539	switch (type) {
540	case RTW89_FWDL_CHECK_WCPU_FWDL_DONE:
541		check_pass = !(val32 & B_BE_WLANCPU_FWDL_EN);
542		break;
543	case RTW89_FWDL_CHECK_DCPU_FWDL_DONE:
544		check_pass = !(val32 & B_BE_DATACPU_FWDL_EN);
545		break;
546	case RTW89_FWDL_CHECK_BB0_FWDL_DONE:
547		check_pass = !(val32 & B_BE_BBMCU0_FWDL_EN);
548		break;
549	case RTW89_FWDL_CHECK_BB1_FWDL_DONE:
550		check_pass = !(val32 & B_BE_BBMCU1_FWDL_EN);
551		break;
552	default:
553		break;
554	}
555
556	if (check_pass)
557		return RTW89_FWDL_WCPU_FW_INIT_RDY;
558
559	st = u32_get_bits(val32, B_BE_WCPU_FWDL_STATUS_MASK);
560	if (st < ARRAY_SIZE(fwdl_status_map))
561		return fwdl_status_map[st];
562
563	return st;
564}
565
566static int rtw89_fwdl_check_path_ready_be(struct rtw89_dev *rtwdev,
567					  bool h2c_or_fwdl)
568{
569	u32 check = h2c_or_fwdl ? B_BE_H2C_PATH_RDY : B_BE_DLFW_PATH_RDY;
570	u32 val;
571
572	return read_poll_timeout_atomic(rtw89_read32, val, val & check,
573					1, 1000000, false,
574					rtwdev, R_BE_WCPU_FW_CTRL);
575}
576
577static int dmac_func_en_be(struct rtw89_dev *rtwdev)
578{
579	return 0;
580}
581
582static int cmac_func_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
583{
584	u32 reg;
585
586	if (mac_idx > RTW89_MAC_1)
587		return -EINVAL;
588
589	if (mac_idx == RTW89_MAC_0)
590		return 0;
591
592	if (en) {
593		rtw89_write32_set(rtwdev, R_BE_AFE_CTRL1, B_BE_AFE_CTRL1_SET);
594		rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL_EXTEND, B_BE_R_SYM_ISO_CMAC12PP);
595		rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_CMAC1_FEN);
596
597		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CK_EN, mac_idx);
598		rtw89_write32_set(rtwdev, reg, B_BE_CK_EN_SET);
599
600		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, mac_idx);
601		rtw89_write32_set(rtwdev, reg, B_BE_CMAC_FUNC_EN_SET);
602
603		set_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags);
604	} else {
605		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, mac_idx);
606		rtw89_write32_clr(rtwdev, reg, B_BE_CMAC_FUNC_EN_SET);
607
608		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CK_EN, mac_idx);
609		rtw89_write32_clr(rtwdev, reg, B_BE_CK_EN_SET);
610
611		rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_CMAC1_FEN);
612		rtw89_write32_set(rtwdev, R_BE_SYS_ISO_CTRL_EXTEND, B_BE_R_SYM_ISO_CMAC12PP);
613		rtw89_write32_clr(rtwdev, R_BE_AFE_CTRL1, B_BE_AFE_CTRL1_SET);
614
615		clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags);
616	}
617
618	return 0;
619}
620
621static int chip_func_en_be(struct rtw89_dev *rtwdev)
622{
623	return 0;
624}
625
626static int sys_init_be(struct rtw89_dev *rtwdev)
627{
628	int ret;
629
630	ret = dmac_func_en_be(rtwdev);
631	if (ret)
632		return ret;
633
634	ret = cmac_func_en_be(rtwdev, RTW89_MAC_0, true);
635	if (ret)
636		return ret;
637
638	ret = chip_func_en_be(rtwdev);
639	if (ret)
640		return ret;
641
642	return ret;
643}
644
645static int sta_sch_init_be(struct rtw89_dev *rtwdev)
646{
647	u32 p_val;
648	int ret;
649
650	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
651	if (ret)
652		return ret;
653
654	rtw89_write8_set(rtwdev, R_BE_SS_CTRL, B_BE_SS_EN);
655
656	ret = read_poll_timeout(rtw89_read32, p_val, p_val & B_BE_SS_INIT_DONE,
657				1, TRXCFG_WAIT_CNT, false, rtwdev, R_BE_SS_CTRL);
658	if (ret) {
659		rtw89_err(rtwdev, "[ERR]STA scheduler init\n");
660		return ret;
661	}
662
663	rtw89_write32_set(rtwdev, R_BE_SS_CTRL, B_BE_WARM_INIT);
664	rtw89_write32_clr(rtwdev, R_BE_SS_CTRL, B_BE_BAND_TRIG_EN | B_BE_BAND1_TRIG_EN);
665
666	return 0;
667}
668
669static int mpdu_proc_init_be(struct rtw89_dev *rtwdev)
670{
671	u32 val32;
672	int ret;
673
674	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
675	if (ret)
676		return ret;
677
678	rtw89_write32_set(rtwdev, R_BE_MPDU_PROC, B_BE_APPEND_FCS);
679	rtw89_write32(rtwdev, R_BE_CUT_AMSDU_CTRL, TRXCFG_MPDU_PROC_CUT_CTRL);
680
681	val32 = rtw89_read32(rtwdev, R_BE_HDR_SHCUT_SETTING);
682	val32 |= (B_BE_TX_HW_SEQ_EN | B_BE_TX_HW_ACK_POLICY_EN | B_BE_TX_MAC_MPDU_PROC_EN);
683	val32 &= ~B_BE_TX_ADDR_MLD_TO_LIK;
684	rtw89_write32_set(rtwdev, R_BE_HDR_SHCUT_SETTING, val32);
685
686	rtw89_write32(rtwdev, R_BE_RX_HDRTRNS, TRXCFG_MPDU_PROC_RX_HDR_CONV);
687
688	val32 = rtw89_read32(rtwdev, R_BE_DISP_FWD_WLAN_0);
689	val32 = u32_replace_bits(val32, 1, B_BE_FWD_WLAN_CPU_TYPE_0_DATA_MASK);
690	val32 = u32_replace_bits(val32, 1, B_BE_FWD_WLAN_CPU_TYPE_0_MNG_MASK);
691	val32 = u32_replace_bits(val32, 1, B_BE_FWD_WLAN_CPU_TYPE_0_CTL_MASK);
692	val32 = u32_replace_bits(val32, 1, B_BE_FWD_WLAN_CPU_TYPE_1_MASK);
693	rtw89_write32(rtwdev, R_BE_DISP_FWD_WLAN_0, val32);
694
695	return 0;
696}
697
698static int sec_eng_init_be(struct rtw89_dev *rtwdev)
699{
700	u32 val32;
701	int ret;
702
703	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
704	if (ret)
705		return ret;
706
707	val32 = rtw89_read32(rtwdev, R_BE_SEC_ENG_CTRL);
708	val32 |= B_BE_CLK_EN_CGCMP | B_BE_CLK_EN_WAPI | B_BE_CLK_EN_WEP_TKIP |
709		 B_BE_SEC_TX_ENC | B_BE_SEC_RX_DEC |
710		 B_BE_MC_DEC | B_BE_BC_DEC |
711		 B_BE_BMC_MGNT_DEC | B_BE_UC_MGNT_DEC;
712	val32 &= ~B_BE_SEC_PRE_ENQUE_TX;
713	rtw89_write32(rtwdev, R_BE_SEC_ENG_CTRL, val32);
714
715	rtw89_write32_set(rtwdev, R_BE_SEC_MPDU_PROC, B_BE_APPEND_ICV | B_BE_APPEND_MIC);
716
717	return 0;
718}
719
720static int txpktctrl_init_be(struct rtw89_dev *rtwdev)
721{
722	struct rtw89_mac_dle_rsvd_qt_cfg qt_cfg;
723	u32 val32;
724	int ret;
725
726	ret = rtw89_mac_get_dle_rsvd_qt_cfg(rtwdev, DLE_RSVD_QT_MPDU_INFO, &qt_cfg);
727	if (ret) {
728		rtw89_err(rtwdev, "get dle rsvd qt %d cfg fail %d\n",
729			  DLE_RSVD_QT_MPDU_INFO, ret);
730		return ret;
731	}
732
733	val32 = rtw89_read32(rtwdev, R_BE_TXPKTCTL_MPDUINFO_CFG);
734	val32 = u32_replace_bits(val32, qt_cfg.pktid, B_BE_MPDUINFO_PKTID_MASK);
735	val32 = u32_replace_bits(val32, MPDU_INFO_B1_OFST, B_BE_MPDUINFO_B1_BADDR_MASK);
736	val32 |= B_BE_MPDUINFO_FEN;
737	rtw89_write32(rtwdev, R_BE_TXPKTCTL_MPDUINFO_CFG, val32);
738
739	return 0;
740}
741
742static int mlo_init_be(struct rtw89_dev *rtwdev)
743{
744	u32 val32;
745	int ret;
746
747	val32 = rtw89_read32(rtwdev, R_BE_MLO_INIT_CTL);
748
749	val32 |= B_BE_MLO_TABLE_REINIT;
750	rtw89_write32(rtwdev, R_BE_MLO_INIT_CTL, val32);
751	val32 &= ~B_BE_MLO_TABLE_REINIT;
752	rtw89_write32(rtwdev, R_BE_MLO_INIT_CTL, val32);
753
754	ret = read_poll_timeout_atomic(rtw89_read32, val32,
755				       val32 & B_BE_MLO_TABLE_INIT_DONE,
756				       1, 1000, false, rtwdev, R_BE_MLO_INIT_CTL);
757	if (ret)
758		rtw89_err(rtwdev, "[MLO]%s: MLO init polling timeout\n", __func__);
759
760	rtw89_write32_set(rtwdev, R_BE_SS_CTRL, B_BE_MLO_HW_CHGLINK_EN);
761	rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_ACQCHK_CFG_0, B_BE_R_MACID_ACQ_CHK_EN);
762
763	return ret;
764}
765
766static int dmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
767{
768	int ret;
769
770	ret = rtw89_mac_dle_init(rtwdev, rtwdev->mac.qta_mode, RTW89_QTA_INVALID);
771	if (ret) {
772		rtw89_err(rtwdev, "[ERR]DLE init %d\n", ret);
773		return ret;
774	}
775
776	ret = rtw89_mac_preload_init(rtwdev, RTW89_MAC_0, rtwdev->mac.qta_mode);
777	if (ret) {
778		rtw89_err(rtwdev, "[ERR]preload init %d\n", ret);
779		return ret;
780	}
781
782	ret = rtw89_mac_hfc_init(rtwdev, true, true, true);
783	if (ret) {
784		rtw89_err(rtwdev, "[ERR]HCI FC init %d\n", ret);
785		return ret;
786	}
787
788	ret = sta_sch_init_be(rtwdev);
789	if (ret) {
790		rtw89_err(rtwdev, "[ERR]STA SCH init %d\n", ret);
791		return ret;
792	}
793
794	ret = mpdu_proc_init_be(rtwdev);
795	if (ret) {
796		rtw89_err(rtwdev, "[ERR]MPDU Proc init %d\n", ret);
797		return ret;
798	}
799
800	ret = sec_eng_init_be(rtwdev);
801	if (ret) {
802		rtw89_err(rtwdev, "[ERR]Security Engine init %d\n", ret);
803		return ret;
804	}
805
806	ret = txpktctrl_init_be(rtwdev);
807	if (ret) {
808		rtw89_err(rtwdev, "[ERR]TX pkt ctrl init %d\n", ret);
809		return ret;
810	}
811
812	ret = mlo_init_be(rtwdev);
813	if (ret) {
814		rtw89_err(rtwdev, "[ERR]MLO init %d\n", ret);
815		return ret;
816	}
817
818	return ret;
819}
820
821static int scheduler_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
822{
823	u32 val32;
824	u32 reg;
825	int ret;
826
827	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
828	if (ret)
829		return ret;
830
831	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_HE_CTN_CHK_CCA_NAV, mac_idx);
832	val32 = B_BE_HE_CTN_CHK_CCA_P20 | B_BE_HE_CTN_CHK_EDCCA_P20 |
833		B_BE_HE_CTN_CHK_CCA_BITMAP | B_BE_HE_CTN_CHK_EDCCA_BITMAP |
834		B_BE_HE_CTN_CHK_NO_GNT_WL | B_BE_HE_CTN_CHK_BASIC_NAV |
835		B_BE_HE_CTN_CHK_INTRA_NAV | B_BE_HE_CTN_CHK_TX_NAV;
836	rtw89_write32(rtwdev, reg, val32);
837
838	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_HE_SIFS_CHK_CCA_NAV, mac_idx);
839	val32 = B_BE_HE_SIFS_CHK_EDCCA_P20 | B_BE_HE_SIFS_CHK_EDCCA_BITMAP |
840		B_BE_HE_SIFS_CHK_NO_GNT_WL;
841	rtw89_write32(rtwdev, reg, val32);
842
843	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TB_CHK_CCA_NAV, mac_idx);
844	val32 = B_BE_TB_CHK_EDCCA_BITMAP | B_BE_TB_CHK_NO_GNT_WL | B_BE_TB_CHK_BASIC_NAV;
845	rtw89_write32(rtwdev, reg, val32);
846
847	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CCA_CFG_0, mac_idx);
848	rtw89_write32_clr(rtwdev, reg, B_BE_NO_GNT_WL_EN);
849
850	if (is_qta_poh(rtwdev)) {
851		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PREBKF_CFG_0, mac_idx);
852		rtw89_write32_mask(rtwdev, reg, B_BE_PREBKF_TIME_MASK,
853				   SCH_PREBKF_24US);
854
855		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CTN_CFG_0, mac_idx);
856		rtw89_write32_mask(rtwdev, reg, B_BE_PREBKF_TIME_NONAC_MASK,
857				   SCH_PREBKF_24US);
858	}
859
860	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_EDCA_BCNQ_PARAM, mac_idx);
861	rtw89_write32_mask(rtwdev, reg, B_BE_BCNQ_CW_MASK, 0x32);
862	rtw89_write32_mask(rtwdev, reg, B_BE_BCNQ_AIFS_MASK, BCN_IFS_25US);
863
864	return 0;
865}
866
867static int addr_cam_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
868{
869	u32 val32;
870	u16 val16;
871	u32 reg;
872	int ret;
873
874	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
875	if (ret)
876		return ret;
877
878	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_ADDR_CAM_CTRL, mac_idx);
879	val32 = rtw89_read32(rtwdev, reg);
880	val32 = u32_replace_bits(val32, ADDR_CAM_SERCH_RANGE, B_BE_ADDR_CAM_RANGE_MASK);
881	val32 |= B_BE_ADDR_CAM_EN;
882	if (mac_idx == RTW89_MAC_0)
883		val32 |= B_BE_ADDR_CAM_CLR;
884	rtw89_write32(rtwdev, reg, val32);
885
886	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_ADDR_CAM_CTRL, mac_idx);
887	ret = read_poll_timeout_atomic(rtw89_read16, val16, !(val16 & B_BE_ADDR_CAM_CLR),
888				       1, TRXCFG_WAIT_CNT, false, rtwdev, reg);
889	if (ret)
890		rtw89_err(rtwdev, "[ERR]ADDR_CAM reset\n");
891
892	return ret;
893}
894
895static int rtw89_mac_typ_fltr_opt_be(struct rtw89_dev *rtwdev,
896				     enum rtw89_machdr_frame_type type,
897				     enum rtw89_mac_fwd_target fwd_target,
898				     u8 mac_idx)
899{
900	u32 reg;
901	u32 val;
902
903	switch (fwd_target) {
904	case RTW89_FWD_DONT_CARE:
905		val = RX_FLTR_FRAME_DROP_BE;
906		break;
907	case RTW89_FWD_TO_HOST:
908	case RTW89_FWD_TO_WLAN_CPU:
909		val = RX_FLTR_FRAME_ACCEPT_BE;
910		break;
911	default:
912		rtw89_err(rtwdev, "[ERR]set rx filter fwd target err\n");
913		return -EINVAL;
914	}
915
916	switch (type) {
917	case RTW89_MGNT:
918		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MGNT_FLTR, mac_idx);
919		break;
920	case RTW89_CTRL:
921		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CTRL_FLTR, mac_idx);
922		break;
923	case RTW89_DATA:
924		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_DATA_FLTR, mac_idx);
925		break;
926	default:
927		rtw89_err(rtwdev, "[ERR]set rx filter type err\n");
928		return -EINVAL;
929	}
930	rtw89_write32(rtwdev, reg, val);
931
932	return 0;
933}
934
935static int rx_fltr_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
936{
937	u32 reg;
938	u32 val;
939
940	rtw89_mac_typ_fltr_opt_be(rtwdev, RTW89_MGNT, RTW89_FWD_TO_HOST, mac_idx);
941	rtw89_mac_typ_fltr_opt_be(rtwdev, RTW89_CTRL, RTW89_FWD_TO_HOST, mac_idx);
942	rtw89_mac_typ_fltr_opt_be(rtwdev, RTW89_DATA, RTW89_FWD_TO_HOST, mac_idx);
943
944	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_FLTR_OPT, mac_idx);
945	val = B_BE_A_BC_CAM_MATCH | B_BE_A_UC_CAM_MATCH | B_BE_A_MC |
946	      B_BE_A_BC | B_BE_A_A1_MATCH | B_BE_SNIFFER_MODE |
947	      u32_encode_bits(15, B_BE_UID_FILTER_MASK);
948	rtw89_write32(rtwdev, reg, val);
949	u32p_replace_bits(&rtwdev->hal.rx_fltr, 15, B_BE_UID_FILTER_MASK);
950
951	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PLCP_HDR_FLTR, mac_idx);
952	val = B_BE_HE_SIGB_CRC_CHK | B_BE_VHT_MU_SIGB_CRC_CHK |
953	      B_BE_VHT_SU_SIGB_CRC_CHK | B_BE_SIGA_CRC_CHK |
954	      B_BE_LSIG_PARITY_CHK_EN | B_BE_CCK_SIG_CHK | B_BE_CCK_CRC_CHK;
955	rtw89_write16(rtwdev, reg, val);
956
957	return 0;
958}
959
960static int cca_ctrl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
961{
962	return 0;
963}
964
965static int nav_ctrl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
966{
967	u32 val32;
968	u32 reg;
969
970	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_NAV_CTL, mac_idx);
971
972	val32 = rtw89_read32(rtwdev, reg);
973	val32 &= ~B_BE_WMAC_PLCP_UP_NAV_EN;
974	val32 |= B_BE_WMAC_TF_UP_NAV_EN | B_BE_WMAC_NAV_UPPER_EN;
975	val32 = u32_replace_bits(val32, NAV_25MS, B_BE_WMAC_NAV_UPPER_MASK);
976
977	rtw89_write32(rtwdev, reg, val32);
978
979	return 0;
980}
981
982static int spatial_reuse_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
983{
984	u32 reg;
985	int ret;
986
987	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
988	if (ret)
989		return ret;
990
991	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_SR_CTRL, mac_idx);
992	rtw89_write8_clr(rtwdev, reg, B_BE_SR_EN | B_BE_SR_CTRL_PLCP_EN);
993
994	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_BSSID_SRC_CTRL, mac_idx);
995	rtw89_write8_set(rtwdev, reg, B_BE_PLCP_SRC_EN);
996
997	return 0;
998}
999
1000static int tmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
1001{
1002	u32 reg;
1003
1004	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TB_PPDU_CTRL, mac_idx);
1005	rtw89_write32_clr(rtwdev, reg, B_BE_QOSNULL_UPD_MUEDCA_EN);
1006
1007	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMTX_TCR_BE_4, mac_idx);
1008	rtw89_write32_mask(rtwdev, reg, B_BE_EHT_HE_PPDU_4XLTF_ZLD_USTIMER_MASK, 0x12);
1009	rtw89_write32_mask(rtwdev, reg, B_BE_EHT_HE_PPDU_2XLTF_ZLD_USTIMER_MASK, 0xe);
1010
1011	return 0;
1012}
1013
1014static int trxptcl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
1015{
1016	const struct rtw89_chip_info *chip = rtwdev->chip;
1017	const struct rtw89_rrsr_cfgs *rrsr = chip->rrsr_cfgs;
1018	struct rtw89_hal *hal = &rtwdev->hal;
1019	u32 val32;
1020	u32 reg;
1021	int ret;
1022
1023	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
1024	if (ret)
1025		return ret;
1026
1027	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MAC_LOOPBACK, mac_idx);
1028	val32 = rtw89_read32(rtwdev, reg);
1029	val32 = u32_replace_bits(val32, S_BE_MACLBK_PLCP_DLY_DEF,
1030				 B_BE_MACLBK_PLCP_DLY_MASK);
1031	val32 &= ~B_BE_MACLBK_EN;
1032	rtw89_write32(rtwdev, reg, val32);
1033
1034	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_0, mac_idx);
1035	val32 = rtw89_read32(rtwdev, reg);
1036	val32 = u32_replace_bits(val32, WMAC_SPEC_SIFS_CCK,
1037				 B_BE_WMAC_SPEC_SIFS_CCK_MASK);
1038	val32 = u32_replace_bits(val32, WMAC_SPEC_SIFS_OFDM_1115E,
1039				 B_BE_WMAC_SPEC_SIFS_OFDM_MASK);
1040	rtw89_write32(rtwdev, reg, val32);
1041
1042	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_LEGACY, mac_idx);
1043	rtw89_write32_clr(rtwdev, reg, B_BE_ACK_BA_RESP_LEGACY_CHK_EDCCA);
1044
1045	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_HE, mac_idx);
1046	rtw89_write32_clr(rtwdev, reg, B_BE_ACK_BA_RESP_HE_CHK_EDCCA);
1047
1048	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_EHT_LEG_PUNC, mac_idx);
1049	rtw89_write32_clr(rtwdev, reg, B_BE_ACK_BA_EHT_LEG_PUNC_CHK_EDCCA);
1050
1051	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RXTRIG_TEST_USER_2, mac_idx);
1052	rtw89_write32_set(rtwdev, reg, B_BE_RXTRIG_FCSCHK_EN);
1053
1054	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_1, mac_idx);
1055	val32 = rtw89_read32(rtwdev, reg);
1056	val32 &= B_BE_FTM_RRSR_RATE_EN_MASK | B_BE_WMAC_RESP_DOPPLEB_BE_EN |
1057		 B_BE_WMAC_RESP_DCM_EN | B_BE_WMAC_RESP_REF_RATE_MASK;
1058	rtw89_write32(rtwdev, reg, val32);
1059	rtw89_write32_mask(rtwdev, reg, rrsr->ref_rate.mask, rrsr->ref_rate.data);
1060
1061	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_RRSR1, mac_idx);
1062	val32 = rtw89_read32(rtwdev, reg);
1063	val32 &= B_BE_RRSR_RATE_EN_MASK | B_BE_RRSR_CCK_MASK | B_BE_RSC_MASK;
1064	rtw89_write32(rtwdev, reg, val32);
1065
1066	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_RRSR0, mac_idx);
1067	val32 = rtw89_read32(rtwdev, reg);
1068	val32 &= B_BE_RRSR_OFDM_MASK | B_BE_RRSR_HT_MASK | B_BE_RRSR_VHT_MASK |
1069		 B_BE_RRSR_HE_MASK;
1070	rtw89_write32(rtwdev, reg, val32);
1071
1072	if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV) {
1073		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_RRSR1, mac_idx);
1074		rtw89_write32_mask(rtwdev, reg, B_BE_RSC_MASK, 1);
1075	}
1076
1077	return 0;
1078}
1079
1080static int rst_bacam_be(struct rtw89_dev *rtwdev)
1081{
1082	u32 val;
1083	int ret;
1084
1085	rtw89_write32_mask(rtwdev, R_BE_RESPBA_CAM_CTRL, B_BE_BACAM_RST_MASK,
1086			   S_BE_BACAM_RST_ALL);
1087
1088	ret = read_poll_timeout_atomic(rtw89_read32_mask, val, val == S_BE_BACAM_RST_DONE,
1089				       1, 1000, false,
1090				       rtwdev, R_BE_RESPBA_CAM_CTRL, B_BE_BACAM_RST_MASK);
1091	if (ret)
1092		rtw89_err(rtwdev, "[ERR]bacam rst timeout\n");
1093
1094	return ret;
1095}
1096
1097#define PLD_RLS_MAX_PG 127
1098#define RX_MAX_LEN_UNIT 512
1099#define RX_SPEC_MAX_LEN (11454 + RX_MAX_LEN_UNIT)
1100
1101static int rmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
1102{
1103	u32 rx_min_qta, rx_max_len, rx_max_pg;
1104	u16 val16;
1105	u32 reg;
1106	int ret;
1107
1108	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
1109	if (ret)
1110		return ret;
1111
1112	if (mac_idx == RTW89_MAC_0) {
1113		ret = rst_bacam_be(rtwdev);
1114		if (ret)
1115			return ret;
1116	}
1117
1118	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_DLK_PROTECT_CTL, mac_idx);
1119	val16 = rtw89_read16(rtwdev, reg);
1120	val16 = u16_replace_bits(val16, TRXCFG_RMAC_DATA_TO, B_BE_RX_DLK_DATA_TIME_MASK);
1121	val16 = u16_replace_bits(val16, TRXCFG_RMAC_CCA_TO, B_BE_RX_DLK_CCA_TIME_MASK);
1122	val16 |= B_BE_RX_DLK_RST_EN;
1123	rtw89_write16(rtwdev, reg, val16);
1124
1125	if (mac_idx == RTW89_MAC_0)
1126		rx_min_qta = rtwdev->mac.dle_info.c0_rx_qta;
1127	else
1128		rx_min_qta = rtwdev->mac.dle_info.c1_rx_qta;
1129	rx_max_pg = min_t(u32, rx_min_qta, PLD_RLS_MAX_PG);
1130	rx_max_len = rx_max_pg * rtwdev->mac.dle_info.ple_pg_size;
1131	rx_max_len = min_t(u32, rx_max_len, RX_SPEC_MAX_LEN);
1132	rx_max_len /= RX_MAX_LEN_UNIT;
1133
1134	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_FLTR_OPT, mac_idx);
1135	rtw89_write32_mask(rtwdev, reg, B_BE_RX_MPDU_MAX_LEN_MASK, rx_max_len);
1136
1137	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PLCP_HDR_FLTR, mac_idx);
1138	rtw89_write8_clr(rtwdev, reg, B_BE_VHT_SU_SIGB_CRC_CHK);
1139
1140	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RCR, mac_idx);
1141	rtw89_write16_set(rtwdev, reg, B_BE_BUSY_CHKSN);
1142
1143	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_PLCP_EXT_OPTION_1, mac_idx);
1144	rtw89_write16_set(rtwdev, reg, B_BE_PLCP_SU_PSDU_LEN_SRC);
1145
1146	return 0;
1147}
1148
1149static int resp_pktctl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
1150{
1151	struct rtw89_mac_dle_rsvd_qt_cfg qt_cfg;
1152	enum rtw89_mac_dle_rsvd_qt_type type;
1153	u32 reg;
1154	int ret;
1155
1156	if (mac_idx == RTW89_MAC_1)
1157		type = DLE_RSVD_QT_B1_CSI;
1158	else
1159		type = DLE_RSVD_QT_B0_CSI;
1160
1161	ret = rtw89_mac_get_dle_rsvd_qt_cfg(rtwdev, type, &qt_cfg);
1162	if (ret) {
1163		rtw89_err(rtwdev, "get dle rsvd qt %d cfg fail %d\n", type, ret);
1164		return ret;
1165	}
1166
1167	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RESP_CSI_RESERVED_PAGE, mac_idx);
1168	rtw89_write32_mask(rtwdev, reg, B_BE_CSI_RESERVED_START_PAGE_MASK, qt_cfg.pktid);
1169	rtw89_write32_mask(rtwdev, reg, B_BE_CSI_RESERVED_PAGE_NUM_MASK, qt_cfg.pg_num);
1170
1171	return 0;
1172}
1173
1174static int cmac_com_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
1175{
1176	u32 val32;
1177	int ret;
1178
1179	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
1180	if (ret)
1181		return ret;
1182
1183	if (mac_idx == RTW89_MAC_0) {
1184		val32 = rtw89_read32(rtwdev, R_BE_TX_SUB_BAND_VALUE);
1185		val32 = u32_replace_bits(val32, S_BE_TXSB_20M_8, B_BE_TXSB_20M_MASK);
1186		val32 = u32_replace_bits(val32, S_BE_TXSB_40M_4, B_BE_TXSB_40M_MASK);
1187		val32 = u32_replace_bits(val32, S_BE_TXSB_80M_2, B_BE_TXSB_80M_MASK);
1188		val32 = u32_replace_bits(val32, S_BE_TXSB_160M_1, B_BE_TXSB_160M_MASK);
1189		rtw89_write32(rtwdev, R_BE_TX_SUB_BAND_VALUE, val32);
1190	} else {
1191		val32 = rtw89_read32(rtwdev, R_BE_TX_SUB_BAND_VALUE_C1);
1192		val32 = u32_replace_bits(val32, S_BE_TXSB_20M_2, B_BE_TXSB_20M_MASK);
1193		val32 = u32_replace_bits(val32, S_BE_TXSB_40M_1, B_BE_TXSB_40M_MASK);
1194		val32 = u32_replace_bits(val32, S_BE_TXSB_80M_0, B_BE_TXSB_80M_MASK);
1195		val32 = u32_replace_bits(val32, S_BE_TXSB_160M_0, B_BE_TXSB_160M_MASK);
1196		rtw89_write32(rtwdev, R_BE_TX_SUB_BAND_VALUE_C1, val32);
1197	}
1198
1199	return 0;
1200}
1201
1202static int ptcl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
1203{
1204	u32 val32;
1205	u8 val8;
1206	u32 reg;
1207	int ret;
1208
1209	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
1210	if (ret)
1211		return ret;
1212
1213	if (is_qta_poh(rtwdev)) {
1214		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_SIFS_SETTING, mac_idx);
1215		val32 = rtw89_read32(rtwdev, reg);
1216		val32 = u32_replace_bits(val32, S_AX_CTS2S_TH_1K,
1217					 B_BE_HW_CTS2SELF_PKT_LEN_TH_MASK);
1218		val32 = u32_replace_bits(val32, S_AX_CTS2S_TH_SEC_256B,
1219					 B_BE_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK);
1220		val32 |= B_BE_HW_CTS2SELF_EN;
1221		rtw89_write32(rtwdev, reg, val32);
1222
1223		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_FSM_MON, mac_idx);
1224		val32 = rtw89_read32(rtwdev, reg);
1225		val32 = u32_replace_bits(val32, S_AX_PTCL_TO_2MS,
1226					 B_BE_PTCL_TX_ARB_TO_THR_MASK);
1227		val32 &= ~B_BE_PTCL_TX_ARB_TO_MODE;
1228		rtw89_write32(rtwdev, reg, val32);
1229	}
1230
1231	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_COMMON_SETTING_0, mac_idx);
1232	val8 = rtw89_read8(rtwdev, reg);
1233	val8 |= B_BE_CMAC_TX_MODE_0 | B_BE_CMAC_TX_MODE_1;
1234	val8 &= ~(B_BE_PTCL_TRIGGER_SS_EN_0 |
1235		  B_BE_PTCL_TRIGGER_SS_EN_1 |
1236		  B_BE_PTCL_TRIGGER_SS_EN_UL);
1237	rtw89_write8(rtwdev, reg, val8);
1238
1239	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AMPDU_AGG_LIMIT, mac_idx);
1240	rtw89_write32_mask(rtwdev, reg, B_BE_AMPDU_MAX_TIME_MASK, AMPDU_MAX_TIME);
1241
1242	return 0;
1243}
1244
1245static int cmac_dma_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
1246{
1247	u32 val32;
1248	u32 reg;
1249	int ret;
1250
1251	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
1252	if (ret)
1253		return ret;
1254
1255	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_CTRL_1, mac_idx);
1256
1257	val32 = rtw89_read32(rtwdev, reg);
1258	val32 = u32_replace_bits(val32, WLCPU_RXCH2_QID,
1259				 B_BE_RXDMA_TXRPT_QUEUE_ID_SW_MASK);
1260	val32 = u32_replace_bits(val32, WLCPU_RXCH2_QID,
1261				 B_BE_RXDMA_F2PCMDRPT_QUEUE_ID_SW_MASK);
1262	rtw89_write32(rtwdev, reg, val32);
1263
1264	return 0;
1265}
1266
1267static int cmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
1268{
1269	int ret;
1270
1271	ret = scheduler_init_be(rtwdev, mac_idx);
1272	if (ret) {
1273		rtw89_err(rtwdev, "[ERR]CMAC%d SCH init %d\n", mac_idx, ret);
1274		return ret;
1275	}
1276
1277	ret = addr_cam_init_be(rtwdev, mac_idx);
1278	if (ret) {
1279		rtw89_err(rtwdev, "[ERR]CMAC%d ADDR_CAM reset %d\n", mac_idx,
1280			  ret);
1281		return ret;
1282	}
1283
1284	ret = rx_fltr_init_be(rtwdev, mac_idx);
1285	if (ret) {
1286		rtw89_err(rtwdev, "[ERR]CMAC%d RX filter init %d\n", mac_idx,
1287			  ret);
1288		return ret;
1289	}
1290
1291	ret = cca_ctrl_init_be(rtwdev, mac_idx);
1292	if (ret) {
1293		rtw89_err(rtwdev, "[ERR]CMAC%d CCA CTRL init %d\n", mac_idx,
1294			  ret);
1295		return ret;
1296	}
1297
1298	ret = nav_ctrl_init_be(rtwdev, mac_idx);
1299	if (ret) {
1300		rtw89_err(rtwdev, "[ERR]CMAC%d NAV CTRL init %d\n", mac_idx,
1301			  ret);
1302		return ret;
1303	}
1304
1305	ret = spatial_reuse_init_be(rtwdev, mac_idx);
1306	if (ret) {
1307		rtw89_err(rtwdev, "[ERR]CMAC%d Spatial Reuse init %d\n",
1308			  mac_idx, ret);
1309		return ret;
1310	}
1311
1312	ret = tmac_init_be(rtwdev, mac_idx);
1313	if (ret) {
1314		rtw89_err(rtwdev, "[ERR]CMAC%d TMAC init %d\n", mac_idx, ret);
1315		return ret;
1316	}
1317
1318	ret = trxptcl_init_be(rtwdev, mac_idx);
1319	if (ret) {
1320		rtw89_err(rtwdev, "[ERR]CMAC%d TRXPTCL init %d\n", mac_idx, ret);
1321		return ret;
1322	}
1323
1324	ret = rmac_init_be(rtwdev, mac_idx);
1325	if (ret) {
1326		rtw89_err(rtwdev, "[ERR]CMAC%d RMAC init %d\n", mac_idx, ret);
1327		return ret;
1328	}
1329
1330	ret = resp_pktctl_init_be(rtwdev, mac_idx);
1331	if (ret) {
1332		rtw89_err(rtwdev, "[ERR]CMAC%d resp pktctl init %d\n", mac_idx, ret);
1333		return ret;
1334	}
1335
1336	ret = cmac_com_init_be(rtwdev, mac_idx);
1337	if (ret) {
1338		rtw89_err(rtwdev, "[ERR]CMAC%d Com init %d\n", mac_idx, ret);
1339		return ret;
1340	}
1341
1342	ret = ptcl_init_be(rtwdev, mac_idx);
1343	if (ret) {
1344		rtw89_err(rtwdev, "[ERR]CMAC%d PTCL init %d\n", mac_idx, ret);
1345		return ret;
1346	}
1347
1348	ret = cmac_dma_init_be(rtwdev, mac_idx);
1349	if (ret) {
1350		rtw89_err(rtwdev, "[ERR]CMAC%d DMA init %d\n", mac_idx, ret);
1351		return ret;
1352	}
1353
1354	return ret;
1355}
1356
1357static int tx_idle_poll_band_be(struct rtw89_dev *rtwdev, u8 mac_idx)
1358{
1359	u32 reg;
1360	u8 val8;
1361	int ret;
1362
1363	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
1364	if (ret)
1365		return ret;
1366
1367	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_TX_CTN_SEL, mac_idx);
1368
1369	ret = read_poll_timeout_atomic(rtw89_read8, val8, !(val8 & B_BE_PTCL_BUSY),
1370				       30, 66000, false, rtwdev, reg);
1371
1372	return ret;
1373}
1374
1375static int dle_buf_req_be(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id)
1376{
1377	u32 val, reg;
1378	int ret;
1379
1380	reg = wd ? R_BE_WD_BUF_REQ : R_BE_PL_BUF_REQ;
1381	val = buf_len;
1382	val |= B_BE_WD_BUF_REQ_EXEC;
1383	rtw89_write32(rtwdev, reg, val);
1384
1385	reg = wd ? R_BE_WD_BUF_STATUS : R_BE_PL_BUF_STATUS;
1386
1387	ret = read_poll_timeout(rtw89_read32, val, val & B_BE_WD_BUF_STAT_DONE,
1388				1, 2000, false, rtwdev, reg);
1389	if (ret)
1390		return ret;
1391
1392	*pkt_id = u32_get_bits(val, B_BE_WD_BUF_STAT_PKTID_MASK);
1393	if (*pkt_id == S_WD_BUF_STAT_PKTID_INVALID)
1394		return -ENOENT;
1395
1396	return 0;
1397}
1398
1399static int set_cpuio_be(struct rtw89_dev *rtwdev,
1400			struct rtw89_cpuio_ctrl *ctrl_para, bool wd)
1401{
1402	u32 val_op0, val_op1, val_op2, val_op3;
1403	u32 val, cmd_type, reg;
1404	int ret;
1405
1406	cmd_type = ctrl_para->cmd_type;
1407
1408	reg = wd ? R_BE_WD_CPUQ_OP_3 : R_BE_PL_CPUQ_OP_3;
1409	val_op3 = u32_replace_bits(0, ctrl_para->start_pktid,
1410				   B_BE_WD_CPUQ_OP_STRT_PKTID_MASK);
1411	val_op3 = u32_replace_bits(val_op3, ctrl_para->end_pktid,
1412				   B_BE_WD_CPUQ_OP_END_PKTID_MASK);
1413	rtw89_write32(rtwdev, reg, val_op3);
1414
1415	reg = wd ? R_BE_WD_CPUQ_OP_1 : R_BE_PL_CPUQ_OP_1;
1416	val_op1 = u32_replace_bits(0, ctrl_para->src_pid,
1417				   B_BE_WD_CPUQ_OP_SRC_PID_MASK);
1418	val_op1 = u32_replace_bits(val_op1, ctrl_para->src_qid,
1419				   B_BE_WD_CPUQ_OP_SRC_QID_MASK);
1420	val_op1 = u32_replace_bits(val_op1, ctrl_para->macid,
1421				   B_BE_WD_CPUQ_OP_SRC_MACID_MASK);
1422	rtw89_write32(rtwdev, reg, val_op1);
1423
1424	reg = wd ? R_BE_WD_CPUQ_OP_2 : R_BE_PL_CPUQ_OP_2;
1425	val_op2 = u32_replace_bits(0, ctrl_para->dst_pid,
1426				   B_BE_WD_CPUQ_OP_DST_PID_MASK);
1427	val_op2 = u32_replace_bits(val_op2, ctrl_para->dst_qid,
1428				   B_BE_WD_CPUQ_OP_DST_QID_MASK);
1429	val_op2 = u32_replace_bits(val_op2, ctrl_para->macid,
1430				   B_BE_WD_CPUQ_OP_DST_MACID_MASK);
1431	rtw89_write32(rtwdev, reg, val_op2);
1432
1433	reg = wd ? R_BE_WD_CPUQ_OP_0 : R_BE_PL_CPUQ_OP_0;
1434	val_op0 = u32_replace_bits(0, cmd_type,
1435				   B_BE_WD_CPUQ_OP_CMD_TYPE_MASK);
1436	val_op0 = u32_replace_bits(val_op0, ctrl_para->pkt_num,
1437				   B_BE_WD_CPUQ_OP_PKTNUM_MASK);
1438	val_op0 |= B_BE_WD_CPUQ_OP_EXEC;
1439	rtw89_write32(rtwdev, reg, val_op0);
1440
1441	reg = wd ? R_BE_WD_CPUQ_OP_STATUS : R_BE_PL_CPUQ_OP_STATUS;
1442
1443	ret = read_poll_timeout(rtw89_read32, val, val & B_BE_WD_CPUQ_OP_STAT_DONE,
1444				1, 2000, false, rtwdev, reg);
1445	if (ret) {
1446		rtw89_err(rtwdev, "[ERR]set cpuio wd timeout\n");
1447		rtw89_err(rtwdev, "[ERR]op_0=0x%X, op_1=0x%X, op_2=0x%X\n",
1448			  val_op0, val_op1, val_op2);
1449		return ret;
1450	}
1451
1452	if (cmd_type == CPUIO_OP_CMD_GET_NEXT_PID ||
1453	    cmd_type == CPUIO_OP_CMD_GET_1ST_PID)
1454		ctrl_para->pktid = u32_get_bits(val, B_BE_WD_CPUQ_OP_PKTID_MASK);
1455
1456	return 0;
1457}
1458
1459static int dle_upd_qta_aval_page_be(struct rtw89_dev *rtwdev,
1460				    enum rtw89_mac_dle_ctrl_type type,
1461				    enum rtw89_mac_dle_ple_quota_id quota_id)
1462{
1463	u32 val;
1464
1465	if (type == DLE_CTRL_TYPE_WDE) {
1466		rtw89_write32_mask(rtwdev, R_BE_WDE_BUFMGN_CTL,
1467				   B_BE_WDE_AVAL_UPD_QTAID_MASK, quota_id);
1468		rtw89_write32_set(rtwdev, R_BE_WDE_BUFMGN_CTL, B_BE_WDE_AVAL_UPD_REQ);
1469
1470		return read_poll_timeout(rtw89_read32, val,
1471					 !(val & B_BE_WDE_AVAL_UPD_REQ),
1472					 1, 2000, false, rtwdev, R_BE_WDE_BUFMGN_CTL);
1473	} else if (type == DLE_CTRL_TYPE_PLE) {
1474		rtw89_write32_mask(rtwdev, R_BE_PLE_BUFMGN_CTL,
1475				   B_BE_PLE_AVAL_UPD_QTAID_MASK, quota_id);
1476		rtw89_write32_set(rtwdev, R_BE_PLE_BUFMGN_CTL, B_BE_PLE_AVAL_UPD_REQ);
1477
1478		return read_poll_timeout(rtw89_read32, val,
1479					 !(val & B_BE_PLE_AVAL_UPD_REQ),
1480					 1, 2000, false, rtwdev, R_BE_PLE_BUFMGN_CTL);
1481	}
1482
1483	rtw89_warn(rtwdev, "%s wrong type %d\n", __func__, type);
1484	return -EINVAL;
1485}
1486
1487static int dle_quota_change_be(struct rtw89_dev *rtwdev, bool band1_en)
1488{
1489	int ret;
1490
1491	if (band1_en) {
1492		ret = dle_upd_qta_aval_page_be(rtwdev, DLE_CTRL_TYPE_PLE,
1493					       PLE_QTAID_B0_TXPL);
1494		if (ret) {
1495			rtw89_err(rtwdev, "update PLE B0 TX avail page fail %d\n", ret);
1496			return ret;
1497		}
1498
1499		ret = dle_upd_qta_aval_page_be(rtwdev, DLE_CTRL_TYPE_PLE,
1500					       PLE_QTAID_CMAC0_RX);
1501		if (ret) {
1502			rtw89_err(rtwdev, "update PLE CMAC0 RX avail page fail %d\n", ret);
1503			return ret;
1504		}
1505	} else {
1506		ret = dle_upd_qta_aval_page_be(rtwdev, DLE_CTRL_TYPE_PLE,
1507					       PLE_QTAID_B1_TXPL);
1508		if (ret) {
1509			rtw89_err(rtwdev, "update PLE B1 TX avail page fail %d\n", ret);
1510			return ret;
1511		}
1512
1513		ret = dle_upd_qta_aval_page_be(rtwdev, DLE_CTRL_TYPE_PLE,
1514					       PLE_QTAID_CMAC1_RX);
1515		if (ret) {
1516			rtw89_err(rtwdev, "update PLE CMAC1 RX avail page fail %d\n", ret);
1517			return ret;
1518		}
1519	}
1520
1521	return 0;
1522}
1523
1524static int preload_init_be(struct rtw89_dev *rtwdev, u8 mac_idx,
1525			   enum rtw89_qta_mode mode)
1526{
1527	u32 max_preld_size, min_rsvd_size;
1528	u32 val32;
1529	u32 reg;
1530
1531	max_preld_size = mac_idx == RTW89_MAC_0 ?
1532			 PRELD_B0_ENT_NUM : PRELD_B1_ENT_NUM;
1533	max_preld_size *= PRELD_AMSDU_SIZE;
1534
1535	reg = mac_idx == RTW89_MAC_0 ? R_BE_TXPKTCTL_B0_PRELD_CFG0 :
1536				       R_BE_TXPKTCTL_B1_PRELD_CFG0;
1537	val32 = rtw89_read32(rtwdev, reg);
1538	val32 = u32_replace_bits(val32, max_preld_size, B_BE_B0_PRELD_USEMAXSZ_MASK);
1539	val32 |= B_BE_B0_PRELD_FEN;
1540	rtw89_write32(rtwdev, reg, val32);
1541
1542	min_rsvd_size = PRELD_AMSDU_SIZE;
1543	reg = mac_idx == RTW89_MAC_0 ? R_BE_TXPKTCTL_B0_PRELD_CFG1 :
1544				       R_BE_TXPKTCTL_B1_PRELD_CFG1;
1545	val32 = rtw89_read32(rtwdev, reg);
1546	val32 = u32_replace_bits(val32, PRELD_NEXT_WND, B_BE_B0_PRELD_NXT_TXENDWIN_MASK);
1547	val32 = u32_replace_bits(val32, min_rsvd_size, B_BE_B0_PRELD_NXT_RSVMINSZ_MASK);
1548	rtw89_write32(rtwdev, reg, val32);
1549
1550	return 0;
1551}
1552
1553static int dbcc_bb_ctrl_be(struct rtw89_dev *rtwdev, bool bb1_en)
1554{
1555	u32 set = B_BE_FEN_BB1PLAT_RSTB | B_BE_FEN_BB1_IP_RSTN;
1556
1557	if (bb1_en)
1558		rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, set);
1559	else
1560		rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, set);
1561
1562	return 0;
1563}
1564
1565static int enable_imr_be(struct rtw89_dev *rtwdev, u8 mac_idx,
1566			 enum rtw89_mac_hwmod_sel sel)
1567{
1568	const struct rtw89_chip_info *chip = rtwdev->chip;
1569	const struct rtw89_imr_table *table;
1570	const struct rtw89_reg_imr *reg;
1571	u32 addr;
1572	u32 val;
1573	int i;
1574
1575	if (sel == RTW89_DMAC_SEL)
1576		table = chip->imr_dmac_table;
1577	else if (sel == RTW89_CMAC_SEL)
1578		table = chip->imr_cmac_table;
1579	else
1580		return -EINVAL;
1581
1582	for (i = 0; i < table->n_regs; i++) {
1583		reg = &table->regs[i];
1584		addr = rtw89_mac_reg_by_idx(rtwdev, reg->addr, mac_idx);
1585
1586		val = rtw89_read32(rtwdev, addr);
1587		val &= ~reg->clr;
1588		val |= reg->set;
1589		rtw89_write32(rtwdev, addr, val);
1590	}
1591
1592	return 0;
1593}
1594
1595static void err_imr_ctrl_be(struct rtw89_dev *rtwdev, bool en)
1596{
1597	u32 v32_dmac = en ? DMAC_ERR_IMR_EN : DMAC_ERR_IMR_DIS;
1598	u32 v32_cmac0 = en ? CMAC0_ERR_IMR_EN : CMAC0_ERR_IMR_DIS;
1599	u32 v32_cmac1 = en ? CMAC1_ERR_IMR_EN : CMAC1_ERR_IMR_DIS;
1600
1601	v32_dmac &= ~B_BE_DMAC_NOTX_ERR_INT_EN;
1602
1603	rtw89_write32(rtwdev, R_BE_DMAC_ERR_IMR, v32_dmac);
1604	rtw89_write32(rtwdev, R_BE_CMAC_ERR_IMR, v32_cmac0);
1605
1606	if (rtwdev->dbcc_en)
1607		rtw89_write32(rtwdev, R_BE_CMAC_ERR_IMR_C1, v32_cmac1);
1608}
1609
1610static int band1_enable_be(struct rtw89_dev *rtwdev)
1611{
1612	int ret;
1613
1614	ret = tx_idle_poll_band_be(rtwdev, RTW89_MAC_0);
1615	if (ret) {
1616		rtw89_err(rtwdev, "[ERR]tx idle poll %d\n", ret);
1617		return ret;
1618	}
1619
1620	ret = rtw89_mac_dle_quota_change(rtwdev, rtwdev->mac.qta_mode, true);
1621	if (ret) {
1622		rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret);
1623		return ret;
1624	}
1625
1626	ret = preload_init_be(rtwdev, RTW89_MAC_1, rtwdev->mac.qta_mode);
1627	if (ret) {
1628		rtw89_err(rtwdev, "[ERR]preload init B1 %d\n", ret);
1629		return ret;
1630	}
1631
1632	ret = cmac_func_en_be(rtwdev, RTW89_MAC_1, true);
1633	if (ret) {
1634		rtw89_err(rtwdev, "[ERR]CMAC%d func en %d\n", RTW89_MAC_1, ret);
1635		return ret;
1636	}
1637
1638	ret = cmac_init_be(rtwdev, RTW89_MAC_1);
1639	if (ret) {
1640		rtw89_err(rtwdev, "[ERR]CMAC%d init %d\n", RTW89_MAC_1, ret);
1641		return ret;
1642	}
1643
1644	ret = dbcc_bb_ctrl_be(rtwdev, true);
1645	if (ret) {
1646		rtw89_err(rtwdev, "[ERR]enable bb 1 %d\n", ret);
1647		return ret;
1648	}
1649
1650	ret = enable_imr_be(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL);
1651	if (ret) {
1652		rtw89_err(rtwdev, "[ERR] enable CMAC1 IMR %d\n", ret);
1653		return ret;
1654	}
1655
1656	return 0;
1657}
1658
1659static int band1_disable_be(struct rtw89_dev *rtwdev)
1660{
1661	int ret;
1662
1663	ret = dbcc_bb_ctrl_be(rtwdev, false);
1664	if (ret) {
1665		rtw89_err(rtwdev, "[ERR]disable bb 1 %d\n", ret);
1666		return ret;
1667	}
1668
1669	ret = cmac_func_en_be(rtwdev, RTW89_MAC_1, false);
1670	if (ret) {
1671		rtw89_err(rtwdev, "[ERR]CMAC%d func dis %d\n", RTW89_MAC_1, ret);
1672		return ret;
1673	}
1674
1675	ret = rtw89_mac_dle_quota_change(rtwdev, rtwdev->mac.qta_mode, false);
1676	if (ret) {
1677		rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret);
1678		return ret;
1679	}
1680
1681	return 0;
1682}
1683
1684static int dbcc_enable_be(struct rtw89_dev *rtwdev, bool enable)
1685{
1686	int ret;
1687
1688	if (enable) {
1689		ret = band1_enable_be(rtwdev);
1690		if (ret) {
1691			rtw89_err(rtwdev, "[ERR] band1_enable %d\n", ret);
1692			return ret;
1693		}
1694
1695		if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) {
1696			ret = rtw89_fw_h2c_notify_dbcc(rtwdev, true);
1697			if (ret) {
1698				rtw89_err(rtwdev, "%s:[ERR] notify dbcc1 fail %d\n",
1699					  __func__, ret);
1700				return ret;
1701			}
1702		}
1703	} else {
1704		if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) {
1705			ret = rtw89_fw_h2c_notify_dbcc(rtwdev, false);
1706			if (ret) {
1707				rtw89_err(rtwdev, "%s:[ERR] notify dbcc1 fail %d\n",
1708					  __func__, ret);
1709				return ret;
1710			}
1711		}
1712
1713		ret = band1_disable_be(rtwdev);
1714		if (ret) {
1715			rtw89_err(rtwdev, "[ERR] band1_disable %d\n", ret);
1716			return ret;
1717		}
1718	}
1719
1720	return 0;
1721}
1722
1723static int set_host_rpr_be(struct rtw89_dev *rtwdev)
1724{
1725	u32 val32;
1726	u32 mode;
1727	u32 fltr;
1728	bool poh;
1729
1730	poh = is_qta_poh(rtwdev);
1731
1732	if (poh) {
1733		mode = RTW89_RPR_MODE_POH;
1734		fltr = S_BE_WDRLS_FLTR_TXOK | S_BE_WDRLS_FLTR_RTYLMT |
1735		       S_BE_WDRLS_FLTR_LIFTIM | S_BE_WDRLS_FLTR_MACID;
1736	} else {
1737		mode = RTW89_RPR_MODE_STF;
1738		fltr = 0;
1739	}
1740
1741	rtw89_write32_mask(rtwdev, R_BE_WDRLS_CFG, B_BE_WDRLS_MODE_MASK, mode);
1742
1743	val32 = rtw89_read32(rtwdev, R_BE_RLSRPT0_CFG1);
1744	val32 = u32_replace_bits(val32, fltr, B_BE_RLSRPT0_FLTR_MAP_MASK);
1745	val32 = u32_replace_bits(val32, 30, B_BE_RLSRPT0_AGGNUM_MASK);
1746	val32 = u32_replace_bits(val32, 255, B_BE_RLSRPT0_TO_MASK);
1747	rtw89_write32(rtwdev, R_BE_RLSRPT0_CFG1, val32);
1748
1749	return 0;
1750}
1751
1752static int trx_init_be(struct rtw89_dev *rtwdev)
1753{
1754	enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode;
1755	int ret;
1756
1757	ret = dmac_init_be(rtwdev, 0);
1758	if (ret) {
1759		rtw89_err(rtwdev, "[ERR]DMAC init %d\n", ret);
1760		return ret;
1761	}
1762
1763	ret = cmac_init_be(rtwdev, 0);
1764	if (ret) {
1765		rtw89_err(rtwdev, "[ERR]CMAC%d init %d\n", 0, ret);
1766		return ret;
1767	}
1768
1769	if (rtw89_mac_is_qta_dbcc(rtwdev, qta_mode)) {
1770		ret = dbcc_enable_be(rtwdev, true);
1771		if (ret) {
1772			rtw89_err(rtwdev, "[ERR]dbcc_enable init %d\n", ret);
1773			return ret;
1774		}
1775	}
1776
1777	ret = enable_imr_be(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
1778	if (ret) {
1779		rtw89_err(rtwdev, "[ERR] enable DMAC IMR %d\n", ret);
1780		return ret;
1781	}
1782
1783	ret = enable_imr_be(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL);
1784	if (ret) {
1785		rtw89_err(rtwdev, "[ERR] to enable CMAC0 IMR %d\n", ret);
1786		return ret;
1787	}
1788
1789	err_imr_ctrl_be(rtwdev, true);
1790
1791	ret = set_host_rpr_be(rtwdev);
1792	if (ret) {
1793		rtw89_err(rtwdev, "[ERR] set host rpr %d\n", ret);
1794		return ret;
1795	}
1796
1797	return 0;
1798}
1799
1800int rtw89_mac_cfg_gnt_v2(struct rtw89_dev *rtwdev,
1801			 const struct rtw89_mac_ax_coex_gnt *gnt_cfg)
1802{
1803	u32 val = 0;
1804
1805	if (gnt_cfg->band[0].gnt_bt)
1806		val |= B_BE_GNT_BT_BB0_VAL | B_BE_GNT_BT_RX_BB0_VAL |
1807		       B_BE_GNT_BT_TX_BB0_VAL;
1808
1809	if (gnt_cfg->band[0].gnt_bt_sw_en)
1810		val |= B_BE_GNT_BT_BB0_SWCTRL | B_BE_GNT_BT_RX_BB0_SWCTRL |
1811		       B_BE_GNT_BT_TX_BB0_SWCTRL;
1812
1813	if (gnt_cfg->band[0].gnt_wl)
1814		val |= B_BE_GNT_WL_BB0_VAL | B_BE_GNT_WL_RX_VAL |
1815		       B_BE_GNT_WL_TX_VAL | B_BE_GNT_WL_BB_PWR_VAL;
1816
1817	if (gnt_cfg->band[0].gnt_wl_sw_en)
1818		val |= B_BE_GNT_WL_BB0_SWCTRL | B_BE_GNT_WL_RX_SWCTRL |
1819		       B_BE_GNT_WL_TX_SWCTRL | B_BE_GNT_WL_BB_PWR_SWCTRL;
1820
1821	if (gnt_cfg->band[1].gnt_bt)
1822		val |= B_BE_GNT_BT_BB1_VAL | B_BE_GNT_BT_RX_BB1_VAL |
1823		       B_BE_GNT_BT_TX_BB1_VAL;
1824
1825	if (gnt_cfg->band[1].gnt_bt_sw_en)
1826		val |= B_BE_GNT_BT_BB1_SWCTRL | B_BE_GNT_BT_RX_BB1_SWCTRL |
1827		       B_BE_GNT_BT_TX_BB1_SWCTRL;
1828
1829	if (gnt_cfg->band[1].gnt_wl)
1830		val |= B_BE_GNT_WL_BB1_VAL | B_BE_GNT_WL_RX_VAL |
1831		       B_BE_GNT_WL_TX_VAL | B_BE_GNT_WL_BB_PWR_VAL;
1832
1833	if (gnt_cfg->band[1].gnt_wl_sw_en)
1834		val |= B_BE_GNT_WL_BB1_SWCTRL | B_BE_GNT_WL_RX_SWCTRL |
1835		       B_BE_GNT_WL_TX_SWCTRL | B_BE_GNT_WL_BB_PWR_SWCTRL;
1836
1837	if (gnt_cfg->bt[0].wlan_act_en)
1838		val |= B_BE_WL_ACT_SWCTRL;
1839	if (gnt_cfg->bt[0].wlan_act)
1840		val |= B_BE_WL_ACT_VAL;
1841	if (gnt_cfg->bt[1].wlan_act_en)
1842		val |= B_BE_WL_ACT2_SWCTRL;
1843	if (gnt_cfg->bt[1].wlan_act)
1844		val |= B_BE_WL_ACT2_VAL;
1845
1846	rtw89_write32(rtwdev, R_BE_GNT_SW_CTRL, val);
1847
1848	return 0;
1849}
1850EXPORT_SYMBOL(rtw89_mac_cfg_gnt_v2);
1851
1852int rtw89_mac_cfg_ctrl_path_v2(struct rtw89_dev *rtwdev, bool wl)
1853{
1854	struct rtw89_btc *btc = &rtwdev->btc;
1855	struct rtw89_btc_dm *dm = &btc->dm;
1856	struct rtw89_mac_ax_gnt *g = dm->gnt.band;
1857	struct rtw89_mac_ax_wl_act *gbt = dm->gnt.bt;
1858	int i;
1859
1860	if (wl)
1861		return 0;
1862
1863	for (i = 0; i < RTW89_PHY_MAX; i++) {
1864		g[i].gnt_bt_sw_en = 1;
1865		g[i].gnt_bt = 1;
1866		g[i].gnt_wl_sw_en = 1;
1867		g[i].gnt_wl = 0;
1868		gbt[i].wlan_act = 1;
1869		gbt[i].wlan_act_en = 0;
1870	}
1871
1872	return rtw89_mac_cfg_gnt_v2(rtwdev, &dm->gnt);
1873}
1874EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v2);
1875
1876static
1877int rtw89_mac_cfg_plt_be(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt)
1878{
1879	u32 reg;
1880	u16 val;
1881	int ret;
1882
1883	ret = rtw89_mac_check_mac_en(rtwdev, plt->band, RTW89_CMAC_SEL);
1884	if (ret)
1885		return ret;
1886
1887	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_BT_PLT, plt->band);
1888	val = (plt->tx & RTW89_MAC_AX_PLT_LTE_RX ? B_BE_TX_PLT_GNT_LTE_RX : 0) |
1889	      (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_BE_TX_PLT_GNT_BT_TX : 0) |
1890	      (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_BE_TX_PLT_GNT_BT_RX : 0) |
1891	      (plt->tx & RTW89_MAC_AX_PLT_GNT_WL ? B_BE_TX_PLT_GNT_WL : 0) |
1892	      (plt->rx & RTW89_MAC_AX_PLT_LTE_RX ? B_BE_RX_PLT_GNT_LTE_RX : 0) |
1893	      (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_BE_RX_PLT_GNT_BT_TX : 0) |
1894	      (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_BE_RX_PLT_GNT_BT_RX : 0) |
1895	      (plt->rx & RTW89_MAC_AX_PLT_GNT_WL ? B_BE_RX_PLT_GNT_WL : 0) |
1896	      B_BE_PLT_EN;
1897	rtw89_write16(rtwdev, reg, val);
1898
1899	return 0;
1900}
1901
1902static u16 rtw89_mac_get_plt_cnt_be(struct rtw89_dev *rtwdev, u8 band)
1903{
1904	u32 reg;
1905	u16 cnt;
1906
1907	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_BT_PLT, band);
1908	cnt = rtw89_read32_mask(rtwdev, reg, B_BE_BT_PLT_PKT_CNT_MASK);
1909	rtw89_write16_set(rtwdev, reg, B_BE_BT_PLT_RST);
1910
1911	return cnt;
1912}
1913
1914static int rtw89_set_hw_sch_tx_en_v2(struct rtw89_dev *rtwdev, u8 mac_idx,
1915				     u32 tx_en, u32 tx_en_mask)
1916{
1917	u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CTN_DRV_TXEN, mac_idx);
1918	u32 val;
1919	int ret;
1920
1921	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
1922	if (ret)
1923		return ret;
1924
1925	val = rtw89_read32(rtwdev, reg);
1926	val = (val & ~tx_en_mask) | (tx_en & tx_en_mask);
1927	rtw89_write32(rtwdev, reg, val);
1928
1929	return 0;
1930}
1931
1932int rtw89_mac_stop_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx,
1933			     u32 *tx_en, enum rtw89_sch_tx_sel sel)
1934{
1935	int ret;
1936
1937	*tx_en = rtw89_read32(rtwdev,
1938			      rtw89_mac_reg_by_idx(rtwdev, R_BE_CTN_DRV_TXEN, mac_idx));
1939
1940	switch (sel) {
1941	case RTW89_SCH_TX_SEL_ALL:
1942		ret = rtw89_set_hw_sch_tx_en_v2(rtwdev, mac_idx, 0,
1943						B_BE_CTN_TXEN_ALL_MASK);
1944		if (ret)
1945			return ret;
1946		break;
1947	case RTW89_SCH_TX_SEL_HIQ:
1948		ret = rtw89_set_hw_sch_tx_en_v2(rtwdev, mac_idx,
1949						0, B_BE_CTN_TXEN_HGQ);
1950		if (ret)
1951			return ret;
1952		break;
1953	case RTW89_SCH_TX_SEL_MG0:
1954		ret = rtw89_set_hw_sch_tx_en_v2(rtwdev, mac_idx,
1955						0, B_BE_CTN_TXEN_MGQ);
1956		if (ret)
1957			return ret;
1958		break;
1959	case RTW89_SCH_TX_SEL_MACID:
1960		ret = rtw89_set_hw_sch_tx_en_v2(rtwdev, mac_idx, 0,
1961						B_BE_CTN_TXEN_ALL_MASK);
1962		if (ret)
1963			return ret;
1964		break;
1965	default:
1966		return 0;
1967	}
1968
1969	return 0;
1970}
1971EXPORT_SYMBOL(rtw89_mac_stop_sch_tx_v2);
1972
1973int rtw89_mac_resume_sch_tx_v2(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en)
1974{
1975	int ret;
1976
1977	ret = rtw89_set_hw_sch_tx_en_v2(rtwdev, mac_idx, tx_en,
1978					B_BE_CTN_TXEN_ALL_MASK);
1979	if (ret)
1980		return ret;
1981
1982	return 0;
1983}
1984EXPORT_SYMBOL(rtw89_mac_resume_sch_tx_v2);
1985
1986static
1987int rtw89_mac_cfg_ppdu_status_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
1988{
1989	u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PPDU_STAT, mac_idx);
1990	int ret;
1991
1992	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
1993	if (ret)
1994		return ret;
1995
1996	if (!enable) {
1997		rtw89_write32_clr(rtwdev, reg, B_BE_PPDU_STAT_RPT_EN);
1998		return 0;
1999	}
2000
2001	rtw89_write32_mask(rtwdev, R_BE_HW_PPDU_STATUS, B_BE_FWD_PPDU_STAT_MASK, 3);
2002	rtw89_write32(rtwdev, reg, B_BE_PPDU_STAT_RPT_EN | B_BE_PPDU_MAC_INFO |
2003				   B_BE_APP_RX_CNT_RPT | B_BE_APP_PLCP_HDR_RPT |
2004				   B_BE_PPDU_STAT_RPT_CRC32 | B_BE_PPDU_STAT_RPT_DMA);
2005
2006	return 0;
2007}
2008
2009static bool rtw89_mac_get_txpwr_cr_be(struct rtw89_dev *rtwdev,
2010				      enum rtw89_phy_idx phy_idx,
2011				      u32 reg_base, u32 *cr)
2012{
2013	enum rtw89_qta_mode mode = rtwdev->mac.qta_mode;
2014	int ret;
2015
2016	ret = rtw89_mac_check_mac_en(rtwdev, (enum rtw89_mac_idx)phy_idx,
2017				     RTW89_CMAC_SEL);
2018	if (ret) {
2019		if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
2020			return false;
2021
2022		rtw89_err(rtwdev, "[TXPWR] check mac enable failed\n");
2023		return false;
2024	}
2025
2026	if (reg_base < R_BE_PWR_MODULE || reg_base > R_BE_CMAC_FUNC_EN_C1) {
2027		rtw89_err(rtwdev, "[TXPWR] reg_base=0x%x exceed txpwr cr\n",
2028			  reg_base);
2029		return false;
2030	}
2031
2032	*cr = rtw89_mac_reg_by_idx(rtwdev, reg_base, phy_idx);
2033
2034	if (*cr >= CMAC1_START_ADDR_BE && *cr <= CMAC1_END_ADDR_BE) {
2035		if (mode == RTW89_QTA_SCC) {
2036			rtw89_err(rtwdev,
2037				  "[TXPWR] addr=0x%x but hw not enable\n",
2038				  *cr);
2039			return false;
2040		}
2041	}
2042
2043	return true;
2044}
2045
2046static int rtw89_mac_init_bfee_be(struct rtw89_dev *rtwdev, u8 mac_idx)
2047{
2048	u32 reg;
2049	u32 val;
2050	int ret;
2051
2052	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2053	if (ret)
2054		return ret;
2055
2056	rtw89_mac_bfee_ctrl(rtwdev, mac_idx, true);
2057
2058	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
2059	rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL |
2060				       B_BE_BFMEE_USE_NSTS |
2061				       B_BE_BFMEE_CSI_GID_SEL |
2062				       B_BE_BFMEE_CSI_FORCE_RETE_EN);
2063	rtw89_write32_mask(rtwdev, reg, B_BE_BFMEE_CSI_RSC_MASK, CSI_RX_BW_CFG);
2064
2065	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CSIRPT_OPTION, mac_idx);
2066	rtw89_write32_set(rtwdev, reg, B_BE_CSIPRT_VHTSU_AID_EN |
2067				       B_BE_CSIPRT_HESU_AID_EN |
2068				       B_BE_CSIPRT_EHTSU_AID_EN);
2069
2070	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_RRSC, mac_idx);
2071	rtw89_write32(rtwdev, reg, CSI_RRSC_BMAP_BE);
2072
2073	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_1, mac_idx);
2074	rtw89_write32_mask(rtwdev, reg, B_BE_BFMEE_BE_CSI_RRSC_BITMAP_MASK,
2075			   CSI_RRSC_BITMAP_CFG);
2076
2077	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_RATE, mac_idx);
2078	val = u32_encode_bits(CSI_INIT_RATE_HT, B_BE_BFMEE_HT_CSI_RATE_MASK) |
2079	      u32_encode_bits(CSI_INIT_RATE_VHT, B_BE_BFMEE_VHT_CSI_RATE_MASK) |
2080	      u32_encode_bits(CSI_INIT_RATE_HE, B_BE_BFMEE_HE_CSI_RATE_MASK) |
2081	      u32_encode_bits(CSI_INIT_RATE_EHT, B_BE_BFMEE_EHT_CSI_RATE_MASK);
2082
2083	rtw89_write32(rtwdev, reg, val);
2084
2085	return 0;
2086}
2087
2088static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
2089					 struct ieee80211_vif *vif,
2090					 struct ieee80211_sta *sta)
2091{
2092	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
2093	u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1;
2094	u8 mac_idx = rtwvif->mac_idx;
2095	u8 port_sel = rtwvif->port;
2096	u8 sound_dim = 3, t;
2097	u8 *phy_cap;
2098	u32 reg;
2099	u16 val;
2100	int ret;
2101
2102	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2103	if (ret)
2104		return ret;
2105
2106	phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info;
2107
2108	if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
2109	    (phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) {
2110		ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD);
2111		stbc_en &= !!(phy_cap[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ);
2112		t = u8_get_bits(phy_cap[5],
2113				IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK);
2114		sound_dim = min(sound_dim, t);
2115	}
2116
2117	if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
2118	    (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
2119		ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
2120		stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
2121		t = u32_get_bits(sta->deflink.vht_cap.cap,
2122				 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK);
2123		sound_dim = min(sound_dim, t);
2124	}
2125
2126	nc = min(nc, sound_dim);
2127	nr = min(nr, sound_dim);
2128
2129	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
2130	rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL);
2131
2132	val = u16_encode_bits(nc, B_BE_BFMEE_CSIINFO0_NC_MASK) |
2133	      u16_encode_bits(nr, B_BE_BFMEE_CSIINFO0_NR_MASK) |
2134	      u16_encode_bits(ng, B_BE_BFMEE_CSIINFO0_NG_MASK) |
2135	      u16_encode_bits(cb, B_BE_BFMEE_CSIINFO0_CB_MASK) |
2136	      u16_encode_bits(cs, B_BE_BFMEE_CSIINFO0_CS_MASK) |
2137	      u16_encode_bits(ldpc_en, B_BE_BFMEE_CSIINFO0_LDPC_EN) |
2138	      u16_encode_bits(stbc_en, B_BE_BFMEE_CSIINFO0_STBC_EN);
2139
2140	if (port_sel == 0)
2141		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0,
2142					   mac_idx);
2143	else
2144		reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_1,
2145					   mac_idx);
2146
2147	rtw89_write16(rtwdev, reg, val);
2148
2149	return 0;
2150}
2151
2152static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev,
2153				 struct ieee80211_vif *vif,
2154				 struct ieee80211_sta *sta)
2155{
2156	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
2157	u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M);
2158	u8 mac_idx = rtwvif->mac_idx;
2159	int ret;
2160	u32 reg;
2161
2162	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2163	if (ret)
2164		return ret;
2165
2166	if (sta->deflink.he_cap.has_he) {
2167		rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) |
2168			 BIT(RTW89_MAC_BF_RRSC_HE_MSC3) |
2169			 BIT(RTW89_MAC_BF_RRSC_HE_MSC5));
2170	}
2171	if (sta->deflink.vht_cap.vht_supported) {
2172		rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) |
2173			 BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) |
2174			 BIT(RTW89_MAC_BF_RRSC_VHT_MSC5));
2175	}
2176	if (sta->deflink.ht_cap.ht_supported) {
2177		rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) |
2178			 BIT(RTW89_MAC_BF_RRSC_HT_MSC3) |
2179			 BIT(RTW89_MAC_BF_RRSC_HT_MSC5));
2180	}
2181
2182	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
2183	rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL);
2184	rtw89_write32_clr(rtwdev, reg, B_BE_BFMEE_CSI_FORCE_RETE_EN);
2185
2186	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_RRSC, mac_idx);
2187	rtw89_write32(rtwdev, reg, rrsc);
2188
2189	return 0;
2190}
2191
2192static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev,
2193				  struct ieee80211_vif *vif,
2194				  struct ieee80211_sta *sta)
2195{
2196	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
2197
2198	if (rtw89_sta_has_beamformer_cap(sta)) {
2199		rtw89_debug(rtwdev, RTW89_DBG_BF,
2200			    "initialize bfee for new association\n");
2201		rtw89_mac_init_bfee_be(rtwdev, rtwvif->mac_idx);
2202		rtw89_mac_set_csi_para_reg_be(rtwdev, vif, sta);
2203		rtw89_mac_csi_rrsc_be(rtwdev, vif, sta);
2204	}
2205}
2206
2207static void dump_err_status_dispatcher_be(struct rtw89_dev *rtwdev)
2208{
2209	rtw89_info(rtwdev, "R_BE_DISP_HOST_IMR=0x%08x ",
2210		   rtw89_read32(rtwdev, R_BE_DISP_HOST_IMR));
2211	rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR1=0x%08x\n",
2212		   rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR1));
2213	rtw89_info(rtwdev, "R_BE_DISP_CPU_IMR=0x%08x ",
2214		   rtw89_read32(rtwdev, R_BE_DISP_CPU_IMR));
2215	rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR2=0x%08x\n",
2216		   rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR2));
2217	rtw89_info(rtwdev, "R_BE_DISP_OTHER_IMR=0x%08x ",
2218		   rtw89_read32(rtwdev, R_BE_DISP_OTHER_IMR));
2219	rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR0=0x%08x\n",
2220		   rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR0));
2221}
2222
2223static void rtw89_mac_dump_qta_lost_be(struct rtw89_dev *rtwdev)
2224{
2225	struct rtw89_mac_dle_dfi_qempty qempty;
2226	struct rtw89_mac_dle_dfi_quota quota;
2227	struct rtw89_mac_dle_dfi_ctrl ctrl;
2228	u32 val, not_empty, i;
2229	int ret;
2230
2231	qempty.dle_type = DLE_CTRL_TYPE_PLE;
2232	qempty.grpsel = 0;
2233	qempty.qempty = ~(u32)0;
2234	ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
2235	if (ret)
2236		rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
2237	else
2238		rtw89_info(rtwdev, "DLE group0 empty: 0x%x\n", qempty.qempty);
2239
2240	for (not_empty = ~qempty.qempty, i = 0; not_empty != 0; not_empty >>= 1, i++) {
2241		if (!(not_empty & BIT(0)))
2242			continue;
2243		ctrl.type = DLE_CTRL_TYPE_PLE;
2244		ctrl.target = DLE_DFI_TYPE_QLNKTBL;
2245		ctrl.addr = (QLNKTBL_ADDR_INFO_SEL_0 ? QLNKTBL_ADDR_INFO_SEL : 0) |
2246			    u32_encode_bits(i, QLNKTBL_ADDR_TBL_IDX_MASK);
2247		ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl);
2248		if (ret)
2249			rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
2250		else
2251			rtw89_info(rtwdev, "qidx%d pktcnt = %d\n", i,
2252				   u32_get_bits(ctrl.out_data,
2253						QLNKTBL_DATA_SEL1_PKT_CNT_MASK));
2254	}
2255
2256	quota.dle_type = DLE_CTRL_TYPE_PLE;
2257	quota.qtaid = 6;
2258	ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, &quota);
2259	if (ret)
2260		rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
2261	else
2262		rtw89_info(rtwdev, "quota6 rsv/use: 0x%x/0x%x\n",
2263			   quota.rsv_pgnum, quota.use_pgnum);
2264
2265	val = rtw89_read32(rtwdev, R_BE_PLE_QTA6_CFG);
2266	rtw89_info(rtwdev, "[PLE][CMAC0_RX]min_pgnum=0x%x\n",
2267		   u32_get_bits(val, B_BE_PLE_Q6_MIN_SIZE_MASK));
2268	rtw89_info(rtwdev, "[PLE][CMAC0_RX]max_pgnum=0x%x\n",
2269		   u32_get_bits(val, B_BE_PLE_Q6_MAX_SIZE_MASK));
2270	val = rtw89_read32(rtwdev, R_BE_RX_FLTR_OPT);
2271	rtw89_info(rtwdev, "[PLE][CMAC0_RX]B_BE_RX_MPDU_MAX_LEN=0x%x\n",
2272		   u32_get_bits(val, B_BE_RX_MPDU_MAX_LEN_MASK));
2273	rtw89_info(rtwdev, "R_BE_RSP_CHK_SIG=0x%08x\n",
2274		   rtw89_read32(rtwdev, R_BE_RSP_CHK_SIG));
2275	rtw89_info(rtwdev, "R_BE_TRXPTCL_RESP_0=0x%08x\n",
2276		   rtw89_read32(rtwdev, R_BE_TRXPTCL_RESP_0));
2277
2278	if (!rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL)) {
2279		quota.dle_type = DLE_CTRL_TYPE_PLE;
2280		quota.qtaid = 7;
2281		ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, &quota);
2282		if (ret)
2283			rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
2284		else
2285			rtw89_info(rtwdev, "quota7 rsv/use: 0x%x/0x%x\n",
2286				   quota.rsv_pgnum, quota.use_pgnum);
2287
2288		val = rtw89_read32(rtwdev, R_BE_PLE_QTA7_CFG);
2289		rtw89_info(rtwdev, "[PLE][CMAC1_RX]min_pgnum=0x%x\n",
2290			   u32_get_bits(val, B_BE_PLE_Q7_MIN_SIZE_MASK));
2291		rtw89_info(rtwdev, "[PLE][CMAC1_RX]max_pgnum=0x%x\n",
2292			   u32_get_bits(val, B_BE_PLE_Q7_MAX_SIZE_MASK));
2293		val = rtw89_read32(rtwdev, R_BE_RX_FLTR_OPT_C1);
2294		rtw89_info(rtwdev, "[PLE][CMAC1_RX]B_BE_RX_MPDU_MAX_LEN=0x%x\n",
2295			   u32_get_bits(val, B_BE_RX_MPDU_MAX_LEN_MASK));
2296		rtw89_info(rtwdev, "R_BE_RSP_CHK_SIG_C1=0x%08x\n",
2297			   rtw89_read32(rtwdev, R_BE_RSP_CHK_SIG_C1));
2298		rtw89_info(rtwdev, "R_BE_TRXPTCL_RESP_0_C1=0x%08x\n",
2299			   rtw89_read32(rtwdev, R_BE_TRXPTCL_RESP_0_C1));
2300	}
2301
2302	rtw89_info(rtwdev, "R_BE_DLE_EMPTY0=0x%08x\n",
2303		   rtw89_read32(rtwdev, R_BE_DLE_EMPTY0));
2304	rtw89_info(rtwdev, "R_BE_DLE_EMPTY1=0x%08x\n",
2305		   rtw89_read32(rtwdev, R_BE_DLE_EMPTY1));
2306
2307	dump_err_status_dispatcher_be(rtwdev);
2308}
2309
2310static int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable)
2311{
2312	struct rtw89_mac_h2c_info h2c_info = {};
2313	struct rtw89_mac_c2h_info c2h_info = {};
2314	u32 ret;
2315
2316	h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL;
2317	h2c_info.content_len = sizeof(h2c_info.u.hdr);
2318	h2c_info.u.hdr.w0 = u32_encode_bits(wow_enable, RTW89_H2CREG_WOW_CPUIO_RX_CTRL_EN);
2319
2320	ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info);
2321	if (ret)
2322		return ret;
2323
2324	if (c2h_info.id != RTW89_FWCMD_C2HREG_FUNC_WOW_CPUIO_RX_ACK)
2325		ret = -EINVAL;
2326
2327	return ret;
2328}
2329
2330static int rtw89_wow_config_mac_be(struct rtw89_dev *rtwdev, bool enable_wow)
2331{
2332	if (enable_wow) {
2333		rtw89_write32_set(rtwdev, R_BE_RX_STOP, B_BE_HOST_RX_STOP);
2334		rtw89_write32_clr(rtwdev, R_BE_RX_FLTR_OPT, B_BE_SNIFFER_MODE);
2335		rtw89_mac_cpu_io_rx(rtwdev, enable_wow);
2336		rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false);
2337		rtw89_write32(rtwdev, R_BE_FWD_ERR, 0);
2338		rtw89_write32(rtwdev, R_BE_FWD_ACTN0, 0);
2339		rtw89_write32(rtwdev, R_BE_FWD_ACTN1, 0);
2340		rtw89_write32(rtwdev, R_BE_FWD_ACTN2, 0);
2341		rtw89_write32(rtwdev, R_BE_FWD_TF0, 0);
2342		rtw89_write32(rtwdev, R_BE_FWD_TF1, 0);
2343		rtw89_write32(rtwdev, R_BE_FWD_ERR, 0);
2344		rtw89_write32(rtwdev, R_BE_HW_PPDU_STATUS, 0);
2345		rtw89_write8(rtwdev, R_BE_DBG_WOW_READY, WOWLAN_NOT_READY);
2346	} else {
2347		rtw89_mac_cpu_io_rx(rtwdev, enable_wow);
2348		rtw89_write32_clr(rtwdev, R_BE_RX_STOP, B_BE_HOST_RX_STOP);
2349		rtw89_write32_set(rtwdev, R_BE_RX_FLTR_OPT, R_BE_RX_FLTR_OPT);
2350		rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
2351	}
2352
2353	return 0;
2354}
2355
2356static void rtw89_mac_dump_cmac_err_status_be(struct rtw89_dev *rtwdev,
2357					      u8 band)
2358{
2359	u32 offset = 0;
2360	u32 cmac_err;
2361	int ret;
2362
2363	ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL);
2364	if (ret) {
2365		rtw89_info(rtwdev, "[CMAC] : CMAC%d not enabled\n", band);
2366		return;
2367	}
2368
2369	if (band)
2370		offset = RTW89_MAC_BE_BAND_REG_OFFSET;
2371
2372	cmac_err = rtw89_read32(rtwdev, R_BE_CMAC_ERR_ISR + offset);
2373	rtw89_info(rtwdev, "R_BE_CMAC_ERR_ISR [%d]=0x%08x\n", band,
2374		   rtw89_read32(rtwdev, R_BE_CMAC_ERR_ISR + offset));
2375	rtw89_info(rtwdev, "R_BE_CMAC_FUNC_EN [%d]=0x%08x\n", band,
2376		   rtw89_read32(rtwdev, R_BE_CMAC_FUNC_EN + offset));
2377	rtw89_info(rtwdev, "R_BE_CK_EN [%d]=0x%08x\n", band,
2378		   rtw89_read32(rtwdev, R_BE_CK_EN + offset));
2379
2380	if (cmac_err & B_BE_SCHEDULE_TOP_ERR_IND) {
2381		rtw89_info(rtwdev, "R_BE_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band,
2382			   rtw89_read32(rtwdev, R_BE_SCHEDULE_ERR_IMR + offset));
2383		rtw89_info(rtwdev, "R_BE_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band,
2384			   rtw89_read32(rtwdev, R_BE_SCHEDULE_ERR_ISR + offset));
2385	}
2386
2387	if (cmac_err & B_BE_PTCL_TOP_ERR_IND) {
2388		rtw89_info(rtwdev, "R_BE_PTCL_IMR0 [%d]=0x%08x\n", band,
2389			   rtw89_read32(rtwdev, R_BE_PTCL_IMR0 + offset));
2390		rtw89_info(rtwdev, "R_BE_PTCL_ISR0 [%d]=0x%08x\n", band,
2391			   rtw89_read32(rtwdev, R_BE_PTCL_ISR0 + offset));
2392		rtw89_info(rtwdev, "R_BE_PTCL_IMR1 [%d]=0x%08x\n", band,
2393			   rtw89_read32(rtwdev, R_BE_PTCL_IMR1 + offset));
2394		rtw89_info(rtwdev, "R_BE_PTCL_ISR1 [%d]=0x%08x\n", band,
2395			   rtw89_read32(rtwdev, R_BE_PTCL_ISR1 + offset));
2396	}
2397
2398	if (cmac_err & B_BE_DMA_TOP_ERR_IND) {
2399		rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG_IMR [%d]=0x%08x\n", band,
2400			   rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG_IMR + offset));
2401		rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG [%d]=0x%08x\n", band,
2402			   rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG + offset));
2403		rtw89_info(rtwdev, "R_BE_TX_ERROR_FLAG_IMR [%d]=0x%08x\n", band,
2404			   rtw89_read32(rtwdev, R_BE_TX_ERROR_FLAG_IMR + offset));
2405		rtw89_info(rtwdev, "R_BE_TX_ERROR_FLAG [%d]=0x%08x\n", band,
2406			   rtw89_read32(rtwdev, R_BE_TX_ERROR_FLAG + offset));
2407		rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG_IMR_1 [%d]=0x%08x\n", band,
2408			   rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG_IMR_1 + offset));
2409		rtw89_info(rtwdev, "R_BE_RX_ERROR_FLAG_1 [%d]=0x%08x\n", band,
2410			   rtw89_read32(rtwdev, R_BE_RX_ERROR_FLAG_1 + offset));
2411	}
2412
2413	if (cmac_err & B_BE_PHYINTF_ERR_IND) {
2414		rtw89_info(rtwdev, "R_BE_PHYINFO_ERR_IMR [%d]=0x%08x\n", band,
2415			   rtw89_read32(rtwdev, R_BE_PHYINFO_ERR_IMR_V1 + offset));
2416		rtw89_info(rtwdev, "R_BE_PHYINFO_ERR_ISR [%d]=0x%08x\n", band,
2417			   rtw89_read32(rtwdev, R_BE_PHYINFO_ERR_ISR + offset));
2418	}
2419
2420	if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) {
2421		rtw89_info(rtwdev, "R_BE_TXPWR_ERR_FLAG [%d]=0x%08x\n", band,
2422			   rtw89_read32(rtwdev, R_BE_TXPWR_ERR_FLAG + offset));
2423		rtw89_info(rtwdev, "R_BE_TXPWR_ERR_IMR [%d]=0x%08x\n", band,
2424			   rtw89_read32(rtwdev, R_BE_TXPWR_ERR_IMR + offset));
2425	}
2426
2427	if (cmac_err & (B_BE_WMAC_RX_ERR_IND | B_BE_WMAC_TX_ERR_IND |
2428			B_BE_WMAC_RX_IDLETO_IDCT | B_BE_PTCL_TX_IDLETO_IDCT)) {
2429		rtw89_info(rtwdev, "R_BE_DBGSEL_TRXPTCL [%d]=0x%08x\n", band,
2430			   rtw89_read32(rtwdev, R_BE_DBGSEL_TRXPTCL + offset));
2431		rtw89_info(rtwdev, "R_BE_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band,
2432			   rtw89_read32(rtwdev, R_BE_TRXPTCL_ERROR_INDICA_MASK + offset));
2433		rtw89_info(rtwdev, "R_BE_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band,
2434			   rtw89_read32(rtwdev, R_BE_TRXPTCL_ERROR_INDICA + offset));
2435		rtw89_info(rtwdev, "R_BE_RX_ERR_IMR [%d]=0x%08x\n", band,
2436			   rtw89_read32(rtwdev, R_BE_RX_ERR_IMR + offset));
2437		rtw89_info(rtwdev, "R_BE_RX_ERR_ISR [%d]=0x%08x\n", band,
2438			   rtw89_read32(rtwdev, R_BE_RX_ERR_ISR + offset));
2439	}
2440
2441	rtw89_info(rtwdev, "R_BE_CMAC_ERR_IMR [%d]=0x%08x\n", band,
2442		   rtw89_read32(rtwdev, R_BE_CMAC_ERR_IMR + offset));
2443}
2444
2445static void rtw89_mac_dump_err_status_be(struct rtw89_dev *rtwdev,
2446					 enum mac_ax_err_info err)
2447{
2448	if (err != MAC_AX_ERR_L1_ERR_DMAC &&
2449	    err != MAC_AX_ERR_L0_PROMOTE_TO_L1 &&
2450	    err != MAC_AX_ERR_L0_ERR_CMAC0 &&
2451	    err != MAC_AX_ERR_L0_ERR_CMAC1 &&
2452	    err != MAC_AX_ERR_RXI300)
2453		return;
2454
2455	rtw89_info(rtwdev, "--->\nerr=0x%x\n", err);
2456	rtw89_info(rtwdev, "R_BE_SER_DBG_INFO=0x%08x\n",
2457		   rtw89_read32(rtwdev, R_BE_SER_DBG_INFO));
2458	rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT=0x%08x\n",
2459		   rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT));
2460	rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT1=0x%08x\n",
2461		   rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT1));
2462	rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT2=0x%08x\n",
2463		   rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT2));
2464	rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT3=0x%08x\n",
2465		   rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT3));
2466	if (!rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL)) {
2467		rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT_C1=0x%08x\n",
2468			   rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT_C1));
2469		rtw89_info(rtwdev, "R_BE_SER_L0_DBG_CNT1_C1=0x%08x\n",
2470			   rtw89_read32(rtwdev, R_BE_SER_L0_DBG_CNT1_C1));
2471	}
2472	rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_0=0x%08x\n",
2473		   rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_0));
2474	rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_1=0x%08x\n",
2475		   rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_1));
2476	rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_2=0x%08x\n",
2477		   rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_2));
2478	rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_3=0x%08x\n",
2479		   rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_3));
2480	rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_4=0x%08x\n",
2481		   rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_4));
2482	rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_5=0x%08x\n",
2483		   rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_5));
2484	rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_6=0x%08x\n",
2485		   rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_6));
2486	rtw89_info(rtwdev, "R_BE_SER_L1_DBG_CNT_7=0x%08x\n",
2487		   rtw89_read32(rtwdev, R_BE_SER_L1_DBG_CNT_7));
2488
2489	rtw89_mac_dump_dmac_err_status(rtwdev);
2490	rtw89_mac_dump_cmac_err_status_be(rtwdev, RTW89_MAC_0);
2491	rtw89_mac_dump_cmac_err_status_be(rtwdev, RTW89_MAC_1);
2492
2493	rtwdev->hci.ops->dump_err_status(rtwdev);
2494
2495	if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1)
2496		rtw89_mac_dump_l0_to_l1(rtwdev, err);
2497
2498	rtw89_info(rtwdev, "<---\n");
2499}
2500
2501static bool mac_is_txq_empty_be(struct rtw89_dev *rtwdev)
2502{
2503	struct rtw89_mac_dle_dfi_qempty qempty;
2504	u32 val32, msk32;
2505	u32 grpnum;
2506	int ret;
2507	int i;
2508
2509	grpnum = rtwdev->chip->wde_qempty_acq_grpnum;
2510	qempty.dle_type = DLE_CTRL_TYPE_WDE;
2511
2512	for (i = 0; i < grpnum; i++) {
2513		qempty.grpsel = i;
2514		ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
2515		if (ret) {
2516			rtw89_warn(rtwdev,
2517				   "%s: failed to dle dfi acq empty: %d\n",
2518				   __func__, ret);
2519			return false;
2520		}
2521
2522		/* Each acq group contains 32 queues (8 macid * 4 acq),
2523		 * but here, we can simply check if all bits are set.
2524		 */
2525		if (qempty.qempty != MASKDWORD)
2526			return false;
2527	}
2528
2529	qempty.grpsel = rtwdev->chip->wde_qempty_mgq_grpsel;
2530	ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
2531	if (ret) {
2532		rtw89_warn(rtwdev, "%s: failed to dle dfi mgq empty: %d\n",
2533			   __func__, ret);
2534		return false;
2535	}
2536
2537	msk32 = B_CMAC0_MGQ_NORMAL_BE | B_CMAC1_MGQ_NORMAL_BE;
2538	if ((qempty.qempty & msk32) != msk32)
2539		return false;
2540
2541	msk32 = B_BE_WDE_EMPTY_QUE_OTHERS;
2542	val32 = rtw89_read32(rtwdev, R_BE_DLE_EMPTY0);
2543	return (val32 & msk32) == msk32;
2544}
2545
2546const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
2547	.band1_offset = RTW89_MAC_BE_BAND_REG_OFFSET,
2548	.filter_model_addr = R_BE_FILTER_MODEL_ADDR,
2549	.indir_access_addr = R_BE_INDIR_ACCESS_ENTRY,
2550	.mem_base_addrs = rtw89_mac_mem_base_addrs_be,
2551	.rx_fltr = R_BE_RX_FLTR_OPT,
2552	.port_base = &rtw89_port_base_be,
2553	.agg_len_ht = R_BE_AGG_LEN_HT_0,
2554	.ps_status = R_BE_WMTX_POWER_BE_BIT_CTL,
2555
2556	.muedca_ctrl = {
2557		.addr = R_BE_MUEDCA_EN,
2558		.mask = B_BE_MUEDCA_EN_0 | B_BE_SET_MUEDCATIMER_TF_0,
2559	},
2560	.bfee_ctrl = {
2561		.addr = R_BE_BFMEE_RESP_OPTION,
2562		.mask = B_BE_BFMEE_HT_NDPA_EN | B_BE_BFMEE_VHT_NDPA_EN |
2563			B_BE_BFMEE_HE_NDPA_EN | B_BE_BFMEE_EHT_NDPA_EN,
2564	},
2565	.narrow_bw_ru_dis = {
2566		.addr = R_BE_RXTRIG_TEST_USER_2,
2567		.mask = B_BE_RXTRIG_RU26_DIS,
2568	},
2569	.wow_ctrl = {.addr = R_BE_WOW_CTRL, .mask = B_BE_WOW_WOWEN,},
2570
2571	.check_mac_en = rtw89_mac_check_mac_en_be,
2572	.sys_init = sys_init_be,
2573	.trx_init = trx_init_be,
2574	.hci_func_en = rtw89_mac_hci_func_en_be,
2575	.dmac_func_pre_en = rtw89_mac_dmac_func_pre_en_be,
2576	.dle_func_en = dle_func_en_be,
2577	.dle_clk_en = dle_clk_en_be,
2578	.bf_assoc = rtw89_mac_bf_assoc_be,
2579
2580	.typ_fltr_opt = rtw89_mac_typ_fltr_opt_be,
2581	.cfg_ppdu_status = rtw89_mac_cfg_ppdu_status_be,
2582
2583	.dle_mix_cfg = dle_mix_cfg_be,
2584	.chk_dle_rdy = chk_dle_rdy_be,
2585	.dle_buf_req = dle_buf_req_be,
2586	.hfc_func_en = hfc_func_en_be,
2587	.hfc_h2c_cfg = hfc_h2c_cfg_be,
2588	.hfc_mix_cfg = hfc_mix_cfg_be,
2589	.hfc_get_mix_info = hfc_get_mix_info_be,
2590	.wde_quota_cfg = wde_quota_cfg_be,
2591	.ple_quota_cfg = ple_quota_cfg_be,
2592	.set_cpuio = set_cpuio_be,
2593	.dle_quota_change = dle_quota_change_be,
2594
2595	.disable_cpu = rtw89_mac_disable_cpu_be,
2596	.fwdl_enable_wcpu = rtw89_mac_fwdl_enable_wcpu_be,
2597	.fwdl_get_status = fwdl_get_status_be,
2598	.fwdl_check_path_ready = rtw89_fwdl_check_path_ready_be,
2599	.parse_efuse_map = rtw89_parse_efuse_map_be,
2600	.parse_phycap_map = rtw89_parse_phycap_map_be,
2601	.cnv_efuse_state = rtw89_cnv_efuse_state_be,
2602
2603	.cfg_plt = rtw89_mac_cfg_plt_be,
2604	.get_plt_cnt = rtw89_mac_get_plt_cnt_be,
2605
2606	.get_txpwr_cr = rtw89_mac_get_txpwr_cr_be,
2607
2608	.write_xtal_si = rtw89_mac_write_xtal_si_be,
2609	.read_xtal_si = rtw89_mac_read_xtal_si_be,
2610
2611	.dump_qta_lost = rtw89_mac_dump_qta_lost_be,
2612	.dump_err_status = rtw89_mac_dump_err_status_be,
2613
2614	.is_txq_empty = mac_is_txq_empty_be,
2615
2616	.add_chan_list = rtw89_hw_scan_add_chan_list_be,
2617	.scan_offload = rtw89_fw_h2c_scan_offload_be,
2618
2619	.wow_config_mac = rtw89_wow_config_mac_be,
2620};
2621EXPORT_SYMBOL(rtw89_mac_gen_be);
2622