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