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 | .ptcl_dbg = R_BE_PTCL_DBG, |
56 | .ptcl_dbg_info = R_BE_PTCL_DBG_INFO, |
57 | .bcn_drop_all = R_BE_BCN_DROP_ALL0, |
58 | .hiq_win = {R_BE_P0MB_HGQ_WINDOW_CFG_0, R_BE_PORT_HGQ_WINDOW_CFG, |
59 | R_BE_PORT_HGQ_WINDOW_CFG + 1, R_BE_PORT_HGQ_WINDOW_CFG + 2, |
60 | R_BE_PORT_HGQ_WINDOW_CFG + 3}, |
61 | }; |
62 | |
63 | static int rtw89_mac_check_mac_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, |
64 | enum rtw89_mac_hwmod_sel sel) |
65 | { |
66 | if (sel == RTW89_DMAC_SEL && |
67 | test_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags)) |
68 | return 0; |
69 | if (sel == RTW89_CMAC_SEL && mac_idx == RTW89_MAC_0 && |
70 | test_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags)) |
71 | 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 | |
79 | static bool is_qta_poh(struct rtw89_dev *rtwdev) |
80 | { |
81 | return rtwdev->hci.type == RTW89_HCI_TYPE_PCIE; |
82 | } |
83 | |
84 | static 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 = ¶m->prec_cfg; |
88 | struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; |
89 | struct rtw89_hfc_pub_info *info = ¶m->pub_info; |
90 | u32 val; |
91 | |
92 | val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO1); |
93 | info->g0_used = u32_get_bits(v: val, B_BE_G0_USE_PG_MASK); |
94 | info->g1_used = u32_get_bits(v: 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(v: val, B_BE_G0_AVAL_PG_MASK); |
98 | info->g1_aval = u32_get_bits(v: val, B_BE_G1_AVAL_PG_MASK); |
99 | info->pub_aval = u32_get_bits(v: rtw89_read32(rtwdev, R_BE_PUB_PAGE_INFO2), |
100 | B_BE_PUB_AVAL_PG_MASK); |
101 | info->wp_aval = u32_get_bits(v: 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(v: val, B_BE_HCI_FC_MODE_MASK); |
108 | prec_cfg->ch011_full_cond = u32_get_bits(v: val, B_BE_HCI_FC_WD_FULL_COND_MASK); |
109 | prec_cfg->h2c_full_cond = u32_get_bits(v: val, B_BE_HCI_FC_CH12_FULL_COND_MASK); |
110 | prec_cfg->wp_ch07_full_cond = |
111 | u32_get_bits(v: val, B_BE_HCI_FC_WP_CH07_FULL_COND_MASK); |
112 | prec_cfg->wp_ch811_full_cond = |
113 | u32_get_bits(v: 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(v: val, B_BE_PREC_PAGE_CH011_V1_MASK); |
117 | prec_cfg->h2c_prec = u32_get_bits(v: 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(v: 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(v: val, B_BE_PREC_PAGE_WP_CH07_MASK); |
124 | prec_cfg->wp_ch811_prec = u32_get_bits(v: 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(v: val, B_BE_WP_THRD_MASK); |
128 | |
129 | val = rtw89_read32(rtwdev, R_BE_PUB_PAGE_CTRL1); |
130 | pub_cfg->grp0 = u32_get_bits(v: val, B_BE_PUBPG_G0_MASK); |
131 | pub_cfg->grp1 = u32_get_bits(v: val, B_BE_PUBPG_G1_MASK); |
132 | } |
133 | |
134 | static 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 = ¶m->prec_cfg; |
138 | u32 val; |
139 | |
140 | val = u32_encode_bits(v: prec_cfg->h2c_prec, B_BE_PREC_PAGE_CH12_V1_MASK); |
141 | rtw89_write32(rtwdev, R_BE_CH_PAGE_CTRL, data: val); |
142 | } |
143 | |
144 | static 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 = ¶m->prec_cfg; |
148 | const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; |
149 | u32 val; |
150 | |
151 | val = u32_encode_bits(v: prec_cfg->ch011_prec, B_BE_PREC_PAGE_CH011_V1_MASK) | |
152 | u32_encode_bits(v: prec_cfg->h2c_prec, B_BE_PREC_PAGE_CH12_V1_MASK); |
153 | rtw89_write32(rtwdev, R_BE_CH_PAGE_CTRL, data: val); |
154 | |
155 | val = u32_encode_bits(v: pub_cfg->pub_max, B_BE_PUBPG_ALL_MASK); |
156 | rtw89_write32(rtwdev, R_BE_PUB_PAGE_CTRL2, data: val); |
157 | |
158 | val = u32_encode_bits(v: prec_cfg->wp_ch07_prec, B_BE_PREC_PAGE_WP_CH07_MASK) | |
159 | u32_encode_bits(v: prec_cfg->wp_ch811_prec, B_BE_PREC_PAGE_WP_CH811_MASK); |
160 | rtw89_write32(rtwdev, R_BE_WP_PAGE_CTRL1, data: val); |
161 | |
162 | val = u32_replace_bits(old: rtw89_read32(rtwdev, R_BE_HCI_FC_CTRL), |
163 | val: param->mode, B_BE_HCI_FC_MODE_MASK); |
164 | val = u32_replace_bits(old: val, val: prec_cfg->ch011_full_cond, |
165 | B_BE_HCI_FC_WD_FULL_COND_MASK); |
166 | val = u32_replace_bits(old: val, val: prec_cfg->h2c_full_cond, |
167 | B_BE_HCI_FC_CH12_FULL_COND_MASK); |
168 | val = u32_replace_bits(old: val, val: prec_cfg->wp_ch07_full_cond, |
169 | B_BE_HCI_FC_WP_CH07_FULL_COND_MASK); |
170 | val = u32_replace_bits(old: val, 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, data: val); |
173 | } |
174 | |
175 | static 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, data: val); |
187 | } |
188 | |
189 | static 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 | |
199 | static 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 | |
209 | static 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(old: 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(old: 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(old: val, val: bound, B_BE_WDE_START_BOUND_MASK); |
237 | val = u32_replace_bits(old: val, val: wde_size_cfg->lnk_pge_num, |
238 | B_BE_WDE_FREE_PAGE_NUM_MASK); |
239 | rtw89_write32(rtwdev, R_BE_WDE_PKTBUF_CFG, data: 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(old: 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(old: 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(old: val, val: bound, B_BE_PLE_START_BOUND_MASK); |
260 | val = u32_replace_bits(old: val, val: ple_size_cfg->lnk_pge_num, |
261 | B_BE_PLE_FREE_PAGE_NUM_MASK); |
262 | rtw89_write32(rtwdev, R_BE_PLE_PKTBUF_CFG, data: val); |
263 | |
264 | return 0; |
265 | } |
266 | |
267 | static 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 | |
296 | static 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 | |
313 | static 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 | |
334 | static 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 | |
340 | static 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(old: 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(old: 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(old: 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, data: 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 | |
375 | static |
376 | int 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(v: offset, B_BE_WL_XTAL_SI_ADDR_MASK) | |
382 | u32_encode_bits(v: val, B_BE_WL_XTAL_SI_DATA_MASK) | |
383 | u32_encode_bits(v: 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(v: 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, data: 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 | |
400 | static |
401 | int 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(v: offset, B_BE_WL_XTAL_SI_ADDR_MASK) | |
407 | u32_encode_bits(v: 0x0, B_BE_WL_XTAL_SI_DATA_MASK) | |
408 | u32_encode_bits(v: 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(v: 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, data: 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 | |
426 | static void rtw89_mac_disable_cpu_be(struct rtw89_dev *rtwdev) |
427 | { |
428 | u32 val32; |
429 | |
430 | clear_bit(nr: RTW89_FLAG_FW_RDY, addr: 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, data: 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, data: 0); |
443 | rtw89_write32(rtwdev, R_BE_HALT_C2H, data: 0); |
444 | rtw89_write32(rtwdev, R_BE_UDM2, data: 0); |
445 | } |
446 | |
447 | static 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, bit: set); |
455 | } |
456 | |
457 | static 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, data: 0); |
479 | rtw89_write32(rtwdev, R_BE_UDM2, data: 0); |
480 | rtw89_write32(rtwdev, R_BE_HALT_H2C, data: 0); |
481 | rtw89_write32(rtwdev, R_BE_HALT_C2H, data: 0); |
482 | rtw89_write32(rtwdev, R_BE_HALT_H2C_CTRL, data: 0); |
483 | rtw89_write32(rtwdev, R_BE_HALT_C2H_CTRL, data: 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, mask: RTW89_DBG_SER, fmt: "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, data: 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, type: RTW89_FWDL_CHECK_FREERTOS_DONE); |
502 | if (ret) |
503 | return ret; |
504 | } |
505 | |
506 | return 0; |
507 | } |
508 | |
509 | static 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 | |
518 | static 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 | |
531 | static 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(v: 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 | |
566 | static 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 | |
577 | static int dmac_func_en_be(struct rtw89_dev *rtwdev) |
578 | { |
579 | return 0; |
580 | } |
581 | |
582 | static 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, band: mac_idx); |
598 | rtw89_write32_set(rtwdev, addr: reg, B_BE_CK_EN_SET); |
599 | |
600 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, band: mac_idx); |
601 | rtw89_write32_set(rtwdev, addr: reg, B_BE_CMAC_FUNC_EN_SET); |
602 | |
603 | set_bit(nr: RTW89_FLAG_CMAC1_FUNC, addr: rtwdev->flags); |
604 | } else { |
605 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, band: mac_idx); |
606 | rtw89_write32_clr(rtwdev, addr: reg, B_BE_CMAC_FUNC_EN_SET); |
607 | |
608 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CK_EN, band: mac_idx); |
609 | rtw89_write32_clr(rtwdev, addr: 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(nr: RTW89_FLAG_CMAC1_FUNC, addr: rtwdev->flags); |
616 | } |
617 | |
618 | return 0; |
619 | } |
620 | |
621 | static int chip_func_en_be(struct rtw89_dev *rtwdev) |
622 | { |
623 | return 0; |
624 | } |
625 | |
626 | static 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, mac_idx: RTW89_MAC_0, en: 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 | |
645 | static 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, band: RTW89_MAC_0, sel: 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 | |
669 | static 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, band: RTW89_MAC_0, sel: 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, bit: 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(old: val32, val: 1, B_BE_FWD_WLAN_CPU_TYPE_0_DATA_MASK); |
690 | val32 = u32_replace_bits(old: val32, val: 1, B_BE_FWD_WLAN_CPU_TYPE_0_MNG_MASK); |
691 | val32 = u32_replace_bits(old: val32, val: 1, B_BE_FWD_WLAN_CPU_TYPE_0_CTL_MASK); |
692 | val32 = u32_replace_bits(old: val32, val: 1, B_BE_FWD_WLAN_CPU_TYPE_1_MASK); |
693 | rtw89_write32(rtwdev, R_BE_DISP_FWD_WLAN_0, data: val32); |
694 | |
695 | return 0; |
696 | } |
697 | |
698 | static 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, band: RTW89_MAC_0, sel: 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, data: 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 | |
720 | static 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, type: DLE_RSVD_QT_MPDU_INFO, cfg: &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(old: val32, val: qt_cfg.pktid, B_BE_MPDUINFO_PKTID_MASK); |
735 | val32 = u32_replace_bits(old: 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, data: val32); |
738 | |
739 | return 0; |
740 | } |
741 | |
742 | static 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, data: val32); |
751 | val32 &= ~B_BE_MLO_TABLE_REINIT; |
752 | rtw89_write32(rtwdev, R_BE_MLO_INIT_CTL, data: 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 | |
766 | static int dmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) |
767 | { |
768 | int ret; |
769 | |
770 | ret = rtw89_mac_dle_init(rtwdev, mode: rtwdev->mac.qta_mode, ext_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, mac_idx: RTW89_MAC_0, mode: 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, reset: true, en: true, h2c_en: 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 | |
821 | static 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, band: mac_idx, sel: 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, band: 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, addr: reg, data: val32); |
837 | |
838 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_HE_SIFS_CHK_CCA_NAV, band: 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, addr: reg, data: val32); |
842 | |
843 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TB_CHK_CCA_NAV, band: 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, addr: reg, data: val32); |
846 | |
847 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CCA_CFG_0, band: mac_idx); |
848 | rtw89_write32_clr(rtwdev, addr: 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, band: mac_idx); |
852 | rtw89_write32_mask(rtwdev, addr: reg, B_BE_PREBKF_TIME_MASK, |
853 | SCH_PREBKF_24US); |
854 | |
855 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CTN_CFG_0, band: mac_idx); |
856 | rtw89_write32_mask(rtwdev, addr: 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, band: mac_idx); |
861 | rtw89_write32_mask(rtwdev, addr: reg, B_BE_BCNQ_CW_MASK, data: 0x32); |
862 | rtw89_write32_mask(rtwdev, addr: reg, B_BE_BCNQ_AIFS_MASK, BCN_IFS_25US); |
863 | |
864 | return 0; |
865 | } |
866 | |
867 | static 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, band: mac_idx, sel: RTW89_CMAC_SEL); |
875 | if (ret) |
876 | return ret; |
877 | |
878 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_ADDR_CAM_CTRL, band: mac_idx); |
879 | val32 = rtw89_read32(rtwdev, addr: reg); |
880 | val32 = u32_replace_bits(old: 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, addr: reg, data: val32); |
885 | |
886 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_ADDR_CAM_CTRL, band: 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 | |
895 | static 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, band: mac_idx); |
919 | break; |
920 | case RTW89_CTRL: |
921 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CTRL_FLTR, band: mac_idx); |
922 | break; |
923 | case RTW89_DATA: |
924 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_DATA_FLTR, band: 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, addr: reg, data: val); |
931 | |
932 | return 0; |
933 | } |
934 | |
935 | static 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, type: RTW89_MGNT, fwd_target: RTW89_FWD_TO_HOST, mac_idx); |
941 | rtw89_mac_typ_fltr_opt_be(rtwdev, type: RTW89_CTRL, fwd_target: RTW89_FWD_TO_HOST, mac_idx); |
942 | rtw89_mac_typ_fltr_opt_be(rtwdev, type: RTW89_DATA, fwd_target: RTW89_FWD_TO_HOST, mac_idx); |
943 | |
944 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_FLTR_OPT, band: 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(v: 15, B_BE_UID_FILTER_MASK); |
948 | rtw89_write32(rtwdev, addr: reg, data: val); |
949 | u32p_replace_bits(p: &rtwdev->hal.rx_fltr, val: 15, B_BE_UID_FILTER_MASK); |
950 | |
951 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PLCP_HDR_FLTR, band: 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, addr: reg, data: val); |
956 | |
957 | return 0; |
958 | } |
959 | |
960 | static int cca_ctrl_init_be(struct rtw89_dev *rtwdev, u8 mac_idx) |
961 | { |
962 | return 0; |
963 | } |
964 | |
965 | static 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, band: mac_idx); |
971 | |
972 | val32 = rtw89_read32(rtwdev, addr: 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(old: val32, NAV_25MS, B_BE_WMAC_NAV_UPPER_MASK); |
976 | |
977 | rtw89_write32(rtwdev, addr: reg, data: val32); |
978 | |
979 | return 0; |
980 | } |
981 | |
982 | static 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, band: mac_idx, sel: RTW89_CMAC_SEL); |
988 | if (ret) |
989 | return ret; |
990 | |
991 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_SR_CTRL, band: mac_idx); |
992 | rtw89_write8_clr(rtwdev, addr: 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, band: mac_idx); |
995 | rtw89_write8_set(rtwdev, addr: reg, B_BE_PLCP_SRC_EN); |
996 | |
997 | return 0; |
998 | } |
999 | |
1000 | static 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, band: mac_idx); |
1005 | rtw89_write32_clr(rtwdev, addr: reg, B_BE_QOSNULL_UPD_MUEDCA_EN); |
1006 | |
1007 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMTX_TCR_BE_4, band: mac_idx); |
1008 | rtw89_write32_mask(rtwdev, addr: reg, B_BE_EHT_HE_PPDU_4XLTF_ZLD_USTIMER_MASK, data: 0x12); |
1009 | rtw89_write32_mask(rtwdev, addr: reg, B_BE_EHT_HE_PPDU_2XLTF_ZLD_USTIMER_MASK, data: 0xe); |
1010 | |
1011 | return 0; |
1012 | } |
1013 | |
1014 | static 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, band: mac_idx, sel: RTW89_CMAC_SEL); |
1024 | if (ret) |
1025 | return ret; |
1026 | |
1027 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MAC_LOOPBACK, band: mac_idx); |
1028 | val32 = rtw89_read32(rtwdev, addr: reg); |
1029 | val32 = u32_replace_bits(old: val32, S_BE_MACLBK_PLCP_DLY_DEF, |
1030 | B_BE_MACLBK_PLCP_DLY_MASK); |
1031 | val32 &= ~B_BE_MACLBK_EN; |
1032 | rtw89_write32(rtwdev, addr: reg, data: val32); |
1033 | |
1034 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_0, band: mac_idx); |
1035 | val32 = rtw89_read32(rtwdev, addr: reg); |
1036 | val32 = u32_replace_bits(old: val32, WMAC_SPEC_SIFS_CCK, |
1037 | B_BE_WMAC_SPEC_SIFS_CCK_MASK); |
1038 | val32 = u32_replace_bits(old: val32, WMAC_SPEC_SIFS_OFDM_1115E, |
1039 | B_BE_WMAC_SPEC_SIFS_OFDM_MASK); |
1040 | rtw89_write32(rtwdev, addr: reg, data: val32); |
1041 | |
1042 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_ACK_BA_RESP_LEGACY, band: mac_idx); |
1043 | rtw89_write32_clr(rtwdev, addr: 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, band: mac_idx); |
1046 | rtw89_write32_clr(rtwdev, addr: 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, band: mac_idx); |
1049 | rtw89_write32_clr(rtwdev, addr: 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, band: mac_idx); |
1052 | rtw89_write32_set(rtwdev, addr: reg, B_BE_RXTRIG_FCSCHK_EN); |
1053 | |
1054 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_1, band: mac_idx); |
1055 | val32 = rtw89_read32(rtwdev, addr: 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, addr: reg, data: val32); |
1059 | rtw89_write32_mask(rtwdev, addr: reg, mask: rrsr->ref_rate.mask, data: rrsr->ref_rate.data); |
1060 | |
1061 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_RRSR1, band: mac_idx); |
1062 | val32 = rtw89_read32(rtwdev, addr: reg); |
1063 | val32 &= B_BE_RRSR_RATE_EN_MASK | B_BE_RRSR_CCK_MASK | B_BE_RSC_MASK; |
1064 | rtw89_write32(rtwdev, addr: reg, data: val32); |
1065 | |
1066 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_RRSR0, band: mac_idx); |
1067 | val32 = rtw89_read32(rtwdev, addr: 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, addr: reg, data: val32); |
1071 | |
1072 | if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV) { |
1073 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_RRSR1, band: mac_idx); |
1074 | rtw89_write32_mask(rtwdev, addr: reg, B_BE_RSC_MASK, data: 1); |
1075 | } |
1076 | |
1077 | return 0; |
1078 | } |
1079 | |
1080 | static 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 | |
1101 | static 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, band: mac_idx, sel: 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, band: mac_idx); |
1119 | val16 = rtw89_read16(rtwdev, addr: reg); |
1120 | val16 = u16_replace_bits(old: val16, TRXCFG_RMAC_DATA_TO, B_BE_RX_DLK_DATA_TIME_MASK); |
1121 | val16 = u16_replace_bits(old: val16, TRXCFG_RMAC_CCA_TO, B_BE_RX_DLK_CCA_TIME_MASK); |
1122 | val16 |= B_BE_RX_DLK_RST_EN; |
1123 | rtw89_write16(rtwdev, addr: reg, data: 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, band: mac_idx); |
1135 | rtw89_write32_mask(rtwdev, addr: reg, B_BE_RX_MPDU_MAX_LEN_MASK, data: rx_max_len); |
1136 | |
1137 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PLCP_HDR_FLTR, band: mac_idx); |
1138 | rtw89_write8_clr(rtwdev, addr: reg, B_BE_VHT_SU_SIGB_CRC_CHK); |
1139 | |
1140 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RCR, band: mac_idx); |
1141 | rtw89_write16_set(rtwdev, addr: reg, B_BE_BUSY_CHKSN); |
1142 | |
1143 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_PLCP_EXT_OPTION_1, band: mac_idx); |
1144 | rtw89_write16_set(rtwdev, addr: reg, B_BE_PLCP_SU_PSDU_LEN_SRC); |
1145 | |
1146 | return 0; |
1147 | } |
1148 | |
1149 | static 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, cfg: &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, band: mac_idx); |
1168 | rtw89_write32_mask(rtwdev, addr: reg, B_BE_CSI_RESERVED_START_PAGE_MASK, data: qt_cfg.pktid); |
1169 | rtw89_write32_mask(rtwdev, addr: reg, B_BE_CSI_RESERVED_PAGE_NUM_MASK, data: qt_cfg.pg_num); |
1170 | |
1171 | return 0; |
1172 | } |
1173 | |
1174 | static 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, band: mac_idx, sel: 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(old: val32, S_BE_TXSB_20M_8, B_BE_TXSB_20M_MASK); |
1186 | val32 = u32_replace_bits(old: val32, S_BE_TXSB_40M_4, B_BE_TXSB_40M_MASK); |
1187 | val32 = u32_replace_bits(old: val32, S_BE_TXSB_80M_2, B_BE_TXSB_80M_MASK); |
1188 | val32 = u32_replace_bits(old: val32, S_BE_TXSB_160M_1, B_BE_TXSB_160M_MASK); |
1189 | rtw89_write32(rtwdev, R_BE_TX_SUB_BAND_VALUE, data: val32); |
1190 | } else { |
1191 | val32 = rtw89_read32(rtwdev, R_BE_TX_SUB_BAND_VALUE_C1); |
1192 | val32 = u32_replace_bits(old: val32, S_BE_TXSB_20M_2, B_BE_TXSB_20M_MASK); |
1193 | val32 = u32_replace_bits(old: val32, S_BE_TXSB_40M_1, B_BE_TXSB_40M_MASK); |
1194 | val32 = u32_replace_bits(old: val32, S_BE_TXSB_80M_0, B_BE_TXSB_80M_MASK); |
1195 | val32 = u32_replace_bits(old: val32, S_BE_TXSB_160M_0, B_BE_TXSB_160M_MASK); |
1196 | rtw89_write32(rtwdev, R_BE_TX_SUB_BAND_VALUE_C1, data: val32); |
1197 | } |
1198 | |
1199 | return 0; |
1200 | } |
1201 | |
1202 | static 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, band: mac_idx, sel: 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, band: mac_idx); |
1215 | val32 = rtw89_read32(rtwdev, addr: reg); |
1216 | val32 = u32_replace_bits(old: val32, S_AX_CTS2S_TH_1K, |
1217 | B_BE_HW_CTS2SELF_PKT_LEN_TH_MASK); |
1218 | val32 = u32_replace_bits(old: 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, addr: reg, data: val32); |
1222 | |
1223 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_FSM_MON, band: mac_idx); |
1224 | val32 = rtw89_read32(rtwdev, addr: reg); |
1225 | val32 = u32_replace_bits(old: 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, addr: reg, data: val32); |
1229 | } |
1230 | |
1231 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_COMMON_SETTING_0, band: mac_idx); |
1232 | val8 = rtw89_read8(rtwdev, addr: 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, addr: reg, data: val8); |
1238 | |
1239 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AMPDU_AGG_LIMIT, band: mac_idx); |
1240 | rtw89_write32_mask(rtwdev, addr: reg, B_BE_AMPDU_MAX_TIME_MASK, AMPDU_MAX_TIME); |
1241 | |
1242 | return 0; |
1243 | } |
1244 | |
1245 | static 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, band: mac_idx, sel: RTW89_CMAC_SEL); |
1252 | if (ret) |
1253 | return ret; |
1254 | |
1255 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_RX_CTRL_1, band: mac_idx); |
1256 | |
1257 | val32 = rtw89_read32(rtwdev, addr: reg); |
1258 | val32 = u32_replace_bits(old: val32, WLCPU_RXCH2_QID, |
1259 | B_BE_RXDMA_TXRPT_QUEUE_ID_SW_MASK); |
1260 | val32 = u32_replace_bits(old: val32, WLCPU_RXCH2_QID, |
1261 | B_BE_RXDMA_F2PCMDRPT_QUEUE_ID_SW_MASK); |
1262 | rtw89_write32(rtwdev, addr: reg, data: val32); |
1263 | |
1264 | return 0; |
1265 | } |
1266 | |
1267 | static 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 | |
1357 | static 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, band: mac_idx, sel: RTW89_CMAC_SEL); |
1364 | if (ret) |
1365 | return ret; |
1366 | |
1367 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_PTCL_TX_CTN_SEL, band: 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 | |
1375 | static 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, addr: reg, data: 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(v: 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 | |
1399 | static 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(old: 0, val: ctrl_para->start_pktid, |
1410 | B_BE_WD_CPUQ_OP_STRT_PKTID_MASK); |
1411 | val_op3 = u32_replace_bits(old: val_op3, val: ctrl_para->end_pktid, |
1412 | B_BE_WD_CPUQ_OP_END_PKTID_MASK); |
1413 | rtw89_write32(rtwdev, addr: reg, data: val_op3); |
1414 | |
1415 | reg = wd ? R_BE_WD_CPUQ_OP_1 : R_BE_PL_CPUQ_OP_1; |
1416 | val_op1 = u32_replace_bits(old: 0, val: ctrl_para->src_pid, |
1417 | B_BE_WD_CPUQ_OP_SRC_PID_MASK); |
1418 | val_op1 = u32_replace_bits(old: val_op1, val: ctrl_para->src_qid, |
1419 | B_BE_WD_CPUQ_OP_SRC_QID_MASK); |
1420 | val_op1 = u32_replace_bits(old: val_op1, val: ctrl_para->macid, |
1421 | B_BE_WD_CPUQ_OP_SRC_MACID_MASK); |
1422 | rtw89_write32(rtwdev, addr: reg, data: val_op1); |
1423 | |
1424 | reg = wd ? R_BE_WD_CPUQ_OP_2 : R_BE_PL_CPUQ_OP_2; |
1425 | val_op2 = u32_replace_bits(old: 0, val: ctrl_para->dst_pid, |
1426 | B_BE_WD_CPUQ_OP_DST_PID_MASK); |
1427 | val_op2 = u32_replace_bits(old: val_op2, val: ctrl_para->dst_qid, |
1428 | B_BE_WD_CPUQ_OP_DST_QID_MASK); |
1429 | val_op2 = u32_replace_bits(old: val_op2, val: ctrl_para->macid, |
1430 | B_BE_WD_CPUQ_OP_DST_MACID_MASK); |
1431 | rtw89_write32(rtwdev, addr: reg, data: val_op2); |
1432 | |
1433 | reg = wd ? R_BE_WD_CPUQ_OP_0 : R_BE_PL_CPUQ_OP_0; |
1434 | val_op0 = u32_replace_bits(old: 0, val: cmd_type, |
1435 | B_BE_WD_CPUQ_OP_CMD_TYPE_MASK); |
1436 | val_op0 = u32_replace_bits(old: val_op0, val: 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, addr: reg, data: 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(v: val, B_BE_WD_CPUQ_OP_PKTID_MASK); |
1455 | |
1456 | return 0; |
1457 | } |
1458 | |
1459 | static 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, data: 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, data: 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 | |
1487 | static 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, type: DLE_CTRL_TYPE_PLE, |
1493 | quota_id: 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, type: DLE_CTRL_TYPE_PLE, |
1500 | quota_id: 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, type: DLE_CTRL_TYPE_PLE, |
1507 | quota_id: 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, type: DLE_CTRL_TYPE_PLE, |
1514 | quota_id: 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 | |
1524 | static 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, addr: reg); |
1538 | val32 = u32_replace_bits(old: val32, val: max_preld_size, B_BE_B0_PRELD_USEMAXSZ_MASK); |
1539 | val32 |= B_BE_B0_PRELD_FEN; |
1540 | rtw89_write32(rtwdev, addr: reg, data: 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, addr: reg); |
1546 | val32 = u32_replace_bits(old: val32, PRELD_NEXT_WND, B_BE_B0_PRELD_NXT_TXENDWIN_MASK); |
1547 | val32 = u32_replace_bits(old: val32, val: min_rsvd_size, B_BE_B0_PRELD_NXT_RSVMINSZ_MASK); |
1548 | rtw89_write32(rtwdev, addr: reg, data: val32); |
1549 | |
1550 | return 0; |
1551 | } |
1552 | |
1553 | static 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, bit: set); |
1559 | else |
1560 | rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, bit: set); |
1561 | |
1562 | return 0; |
1563 | } |
1564 | |
1565 | static 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_base: reg->addr, band: mac_idx); |
1585 | |
1586 | val = rtw89_read32(rtwdev, addr); |
1587 | val &= ~reg->clr; |
1588 | val |= reg->set; |
1589 | rtw89_write32(rtwdev, addr, data: val); |
1590 | } |
1591 | |
1592 | return 0; |
1593 | } |
1594 | |
1595 | static 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, data: v32_dmac); |
1604 | rtw89_write32(rtwdev, R_BE_CMAC_ERR_IMR, data: v32_cmac0); |
1605 | |
1606 | if (rtwdev->dbcc_en) |
1607 | rtw89_write32(rtwdev, R_BE_CMAC_ERR_IMR_C1, data: v32_cmac1); |
1608 | } |
1609 | |
1610 | static int band1_enable_be(struct rtw89_dev *rtwdev) |
1611 | { |
1612 | int ret; |
1613 | |
1614 | ret = tx_idle_poll_band_be(rtwdev, mac_idx: 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, mode: rtwdev->mac.qta_mode, band1_en: 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, mac_idx: RTW89_MAC_1, mode: 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, mac_idx: RTW89_MAC_1, en: 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, mac_idx: 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, bb1_en: 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, mac_idx: RTW89_MAC_1, sel: 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 | |
1659 | static int band1_disable_be(struct rtw89_dev *rtwdev) |
1660 | { |
1661 | int ret; |
1662 | |
1663 | ret = dbcc_bb_ctrl_be(rtwdev, bb1_en: 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, mac_idx: RTW89_MAC_1, en: 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, mode: rtwdev->mac.qta_mode, band1_en: 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 | |
1684 | static 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, en: 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, en: 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 | |
1723 | static 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, data: mode); |
1742 | |
1743 | val32 = rtw89_read32(rtwdev, R_BE_RLSRPT0_CFG1); |
1744 | val32 = u32_replace_bits(old: val32, val: fltr, B_BE_RLSRPT0_FLTR_MAP_MASK); |
1745 | val32 = u32_replace_bits(old: val32, val: 30, B_BE_RLSRPT0_AGGNUM_MASK); |
1746 | val32 = u32_replace_bits(old: val32, val: 255, B_BE_RLSRPT0_TO_MASK); |
1747 | rtw89_write32(rtwdev, R_BE_RLSRPT0_CFG1, data: val32); |
1748 | |
1749 | return 0; |
1750 | } |
1751 | |
1752 | static 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, mac_idx: 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, mac_idx: 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, mode: qta_mode)) { |
1770 | ret = dbcc_enable_be(rtwdev, enable: 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, mac_idx: RTW89_MAC_0, sel: 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, mac_idx: RTW89_MAC_0, sel: 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, en: 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 | |
1800 | int 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, data: val); |
1847 | |
1848 | return 0; |
1849 | } |
1850 | EXPORT_SYMBOL(rtw89_mac_cfg_gnt_v2); |
1851 | |
1852 | int 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 | } |
1874 | EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v2); |
1875 | |
1876 | static |
1877 | int 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, band: plt->band, sel: RTW89_CMAC_SEL); |
1884 | if (ret) |
1885 | return ret; |
1886 | |
1887 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_BT_PLT, band: 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, addr: reg, data: val); |
1898 | |
1899 | return 0; |
1900 | } |
1901 | |
1902 | static 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, addr: reg, B_BE_BT_PLT_PKT_CNT_MASK); |
1909 | rtw89_write16_set(rtwdev, addr: reg, B_BE_BT_PLT_RST); |
1910 | |
1911 | return cnt; |
1912 | } |
1913 | |
1914 | static 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, band: mac_idx); |
1918 | u32 val; |
1919 | int ret; |
1920 | |
1921 | ret = rtw89_mac_check_mac_en(rtwdev, band: mac_idx, sel: RTW89_CMAC_SEL); |
1922 | if (ret) |
1923 | return ret; |
1924 | |
1925 | val = rtw89_read32(rtwdev, addr: reg); |
1926 | val = (val & ~tx_en_mask) | (tx_en & tx_en_mask); |
1927 | rtw89_write32(rtwdev, addr: reg, data: val); |
1928 | |
1929 | return 0; |
1930 | } |
1931 | |
1932 | int 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 | addr: rtw89_mac_reg_by_idx(rtwdev, R_BE_CTN_DRV_TXEN, band: 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, tx_en: 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 | tx_en: 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 | tx_en: 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, tx_en: 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 | } |
1971 | EXPORT_SYMBOL(rtw89_mac_stop_sch_tx_v2); |
1972 | |
1973 | int 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 | } |
1984 | EXPORT_SYMBOL(rtw89_mac_resume_sch_tx_v2); |
1985 | |
1986 | static |
1987 | int 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, band: mac_idx); |
1990 | int ret; |
1991 | |
1992 | ret = rtw89_mac_check_mac_en(rtwdev, band: mac_idx, sel: RTW89_CMAC_SEL); |
1993 | if (ret) |
1994 | return ret; |
1995 | |
1996 | if (!enable) { |
1997 | rtw89_write32_clr(rtwdev, addr: 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, data: 3); |
2002 | rtw89_write32(rtwdev, addr: 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 | |
2009 | static 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, band: (enum rtw89_mac_idx)phy_idx, |
2017 | sel: 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, band: 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 | |
2046 | static 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, band: mac_idx, sel: RTW89_CMAC_SEL); |
2053 | if (ret) |
2054 | return ret; |
2055 | |
2056 | rtw89_mac_bfee_ctrl(rtwdev, mac_idx, en: true); |
2057 | |
2058 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, band: mac_idx); |
2059 | rtw89_write32_set(rtwdev, addr: 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, addr: reg, B_BE_BFMEE_CSI_RSC_MASK, CSI_RX_BW_CFG); |
2064 | |
2065 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CSIRPT_OPTION, band: mac_idx); |
2066 | rtw89_write32_set(rtwdev, addr: 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, band: mac_idx); |
2071 | rtw89_write32(rtwdev, addr: reg, CSI_RRSC_BMAP_BE); |
2072 | |
2073 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_1, band: mac_idx); |
2074 | rtw89_write32_mask(rtwdev, addr: 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, band: 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, addr: reg, data: val); |
2084 | |
2085 | return 0; |
2086 | } |
2087 | |
2088 | static 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, band: mac_idx, sel: 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(v: 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(v: 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, band: mac_idx); |
2130 | rtw89_write32_set(rtwdev, addr: reg, B_BE_BFMEE_BFPARAM_SEL); |
2131 | |
2132 | val = u16_encode_bits(v: nc, B_BE_BFMEE_CSIINFO0_NC_MASK) | |
2133 | u16_encode_bits(v: nr, B_BE_BFMEE_CSIINFO0_NR_MASK) | |
2134 | u16_encode_bits(v: ng, B_BE_BFMEE_CSIINFO0_NG_MASK) | |
2135 | u16_encode_bits(v: cb, B_BE_BFMEE_CSIINFO0_CB_MASK) | |
2136 | u16_encode_bits(v: cs, B_BE_BFMEE_CSIINFO0_CS_MASK) | |
2137 | u16_encode_bits(v: ldpc_en, B_BE_BFMEE_CSIINFO0_LDPC_EN) | |
2138 | u16_encode_bits(v: 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 | band: mac_idx); |
2143 | else |
2144 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_1, |
2145 | band: mac_idx); |
2146 | |
2147 | rtw89_write16(rtwdev, addr: reg, data: val); |
2148 | |
2149 | return 0; |
2150 | } |
2151 | |
2152 | static 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, band: mac_idx, sel: 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, band: mac_idx); |
2183 | rtw89_write32_set(rtwdev, addr: reg, B_BE_BFMEE_BFPARAM_SEL); |
2184 | rtw89_write32_clr(rtwdev, addr: reg, B_BE_BFMEE_CSI_FORCE_RETE_EN); |
2185 | |
2186 | reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_RRSC, band: mac_idx); |
2187 | rtw89_write32(rtwdev, addr: reg, data: rrsc); |
2188 | |
2189 | return 0; |
2190 | } |
2191 | |
2192 | static 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, mask: RTW89_DBG_BF, |
2200 | fmt: "initialize bfee for new association\n" ); |
2201 | rtw89_mac_init_bfee_be(rtwdev, mac_idx: 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 | |
2207 | static 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 | |
2223 | static 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: &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(v: i, QLNKTBL_ADDR_TBL_IDX_MASK); |
2247 | ret = rtw89_mac_dle_dfi_cfg(rtwdev, ctrl: &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: "a); |
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, band: RTW89_MAC_1, sel: 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: "a); |
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 | |
2310 | static 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(v: wow_enable, RTW89_H2CREG_WOW_CPUIO_RX_CTRL_EN); |
2319 | |
2320 | ret = rtw89_fw_msg_reg(rtwdev, h2c_info: &h2c_info, c2h_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 | |
2330 | static 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, wow_enable: enable_wow); |
2336 | rtw89_mac_cfg_ppdu_status(rtwdev, mac_idx: RTW89_MAC_0, enable: false); |
2337 | rtw89_write32(rtwdev, R_BE_FWD_ERR, data: 0); |
2338 | rtw89_write32(rtwdev, R_BE_FWD_ACTN0, data: 0); |
2339 | rtw89_write32(rtwdev, R_BE_FWD_ACTN1, data: 0); |
2340 | rtw89_write32(rtwdev, R_BE_FWD_ACTN2, data: 0); |
2341 | rtw89_write32(rtwdev, R_BE_FWD_TF0, data: 0); |
2342 | rtw89_write32(rtwdev, R_BE_FWD_TF1, data: 0); |
2343 | rtw89_write32(rtwdev, R_BE_FWD_ERR, data: 0); |
2344 | rtw89_write32(rtwdev, R_BE_HW_PPDU_STATUS, data: 0); |
2345 | rtw89_write8(rtwdev, R_BE_DBG_WOW_READY, data: WOWLAN_NOT_READY); |
2346 | } else { |
2347 | rtw89_mac_cpu_io_rx(rtwdev, wow_enable: 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, mac_idx: RTW89_MAC_0, enable: true); |
2351 | } |
2352 | |
2353 | return 0; |
2354 | } |
2355 | |
2356 | static 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, sel: 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 | |
2445 | static 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, band: RTW89_MAC_1, sel: 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, band: RTW89_MAC_0); |
2491 | rtw89_mac_dump_cmac_err_status_be(rtwdev, band: 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 | |
2501 | static 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: &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: &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 | |
2546 | const 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 | }; |
2621 | EXPORT_SYMBOL(rtw89_mac_gen_be); |
2622 | |