Merge branches 'acpi-scan', 'acpi-tad', 'acpi-extlog' and 'acpi-misc'
[linux-block.git] / drivers / net / wireless / realtek / rtw89 / mac.c
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2019-2020  Realtek Corporation
3  */
4
5 #include "cam.h"
6 #include "chan.h"
7 #include "debug.h"
8 #include "fw.h"
9 #include "mac.h"
10 #include "pci.h"
11 #include "ps.h"
12 #include "reg.h"
13 #include "util.h"
14
15 const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_NUM] = {
16         [RTW89_MAC_MEM_AXIDMA]          = AXIDMA_BASE_ADDR,
17         [RTW89_MAC_MEM_SHARED_BUF]      = SHARED_BUF_BASE_ADDR,
18         [RTW89_MAC_MEM_DMAC_TBL]        = DMAC_TBL_BASE_ADDR,
19         [RTW89_MAC_MEM_SHCUT_MACHDR]    = SHCUT_MACHDR_BASE_ADDR,
20         [RTW89_MAC_MEM_STA_SCHED]       = STA_SCHED_BASE_ADDR,
21         [RTW89_MAC_MEM_RXPLD_FLTR_CAM]  = RXPLD_FLTR_CAM_BASE_ADDR,
22         [RTW89_MAC_MEM_SECURITY_CAM]    = SECURITY_CAM_BASE_ADDR,
23         [RTW89_MAC_MEM_WOW_CAM]         = WOW_CAM_BASE_ADDR,
24         [RTW89_MAC_MEM_CMAC_TBL]        = CMAC_TBL_BASE_ADDR,
25         [RTW89_MAC_MEM_ADDR_CAM]        = ADDR_CAM_BASE_ADDR,
26         [RTW89_MAC_MEM_BA_CAM]          = BA_CAM_BASE_ADDR,
27         [RTW89_MAC_MEM_BCN_IE_CAM0]     = BCN_IE_CAM0_BASE_ADDR,
28         [RTW89_MAC_MEM_BCN_IE_CAM1]     = BCN_IE_CAM1_BASE_ADDR,
29         [RTW89_MAC_MEM_TXD_FIFO_0]      = TXD_FIFO_0_BASE_ADDR,
30         [RTW89_MAC_MEM_TXD_FIFO_1]      = TXD_FIFO_1_BASE_ADDR,
31         [RTW89_MAC_MEM_TXDATA_FIFO_0]   = TXDATA_FIFO_0_BASE_ADDR,
32         [RTW89_MAC_MEM_TXDATA_FIFO_1]   = TXDATA_FIFO_1_BASE_ADDR,
33         [RTW89_MAC_MEM_CPU_LOCAL]       = CPU_LOCAL_BASE_ADDR,
34         [RTW89_MAC_MEM_BSSID_CAM]       = BSSID_CAM_BASE_ADDR,
35         [RTW89_MAC_MEM_TXD_FIFO_0_V1]   = TXD_FIFO_0_BASE_ADDR_V1,
36         [RTW89_MAC_MEM_TXD_FIFO_1_V1]   = TXD_FIFO_1_BASE_ADDR_V1,
37 };
38
39 static void rtw89_mac_mem_write(struct rtw89_dev *rtwdev, u32 offset,
40                                 u32 val, enum rtw89_mac_mem_sel sel)
41 {
42         u32 addr = rtw89_mac_mem_base_addrs[sel] + offset;
43
44         rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, addr);
45         rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, val);
46 }
47
48 static u32 rtw89_mac_mem_read(struct rtw89_dev *rtwdev, u32 offset,
49                               enum rtw89_mac_mem_sel sel)
50 {
51         u32 addr = rtw89_mac_mem_base_addrs[sel] + offset;
52
53         rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR, addr);
54         return rtw89_read32(rtwdev, R_AX_INDIR_ACCESS_ENTRY);
55 }
56
57 int rtw89_mac_check_mac_en(struct rtw89_dev *rtwdev, u8 mac_idx,
58                            enum rtw89_mac_hwmod_sel sel)
59 {
60         u32 val, r_val;
61
62         if (sel == RTW89_DMAC_SEL) {
63                 r_val = rtw89_read32(rtwdev, R_AX_DMAC_FUNC_EN);
64                 val = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN);
65         } else if (sel == RTW89_CMAC_SEL && mac_idx == 0) {
66                 r_val = rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN);
67                 val = B_AX_CMAC_EN;
68         } else if (sel == RTW89_CMAC_SEL && mac_idx == 1) {
69                 r_val = rtw89_read32(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND);
70                 val = B_AX_CMAC1_FEN;
71         } else {
72                 return -EINVAL;
73         }
74         if (r_val == RTW89_R32_EA || r_val == RTW89_R32_DEAD ||
75             (val & r_val) != val)
76                 return -EFAULT;
77
78         return 0;
79 }
80
81 int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val)
82 {
83         u8 lte_ctrl;
84         int ret;
85
86         ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0,
87                                 50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3);
88         if (ret)
89                 rtw89_err(rtwdev, "[ERR]lte not ready(W)\n");
90
91         rtw89_write32(rtwdev, R_AX_LTE_WDATA, val);
92         rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0xC00F0000 | offset);
93
94         return ret;
95 }
96
97 int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val)
98 {
99         u8 lte_ctrl;
100         int ret;
101
102         ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0,
103                                 50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3);
104         if (ret)
105                 rtw89_err(rtwdev, "[ERR]lte not ready(W)\n");
106
107         rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0x800F0000 | offset);
108         *val = rtw89_read32(rtwdev, R_AX_LTE_RDATA);
109
110         return ret;
111 }
112
113 static
114 int dle_dfi_ctrl(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_ctrl *ctrl)
115 {
116         u32 ctrl_reg, data_reg, ctrl_data;
117         u32 val;
118         int ret;
119
120         switch (ctrl->type) {
121         case DLE_CTRL_TYPE_WDE:
122                 ctrl_reg = R_AX_WDE_DBG_FUN_INTF_CTL;
123                 data_reg = R_AX_WDE_DBG_FUN_INTF_DATA;
124                 ctrl_data = FIELD_PREP(B_AX_WDE_DFI_TRGSEL_MASK, ctrl->target) |
125                             FIELD_PREP(B_AX_WDE_DFI_ADDR_MASK, ctrl->addr) |
126                             B_AX_WDE_DFI_ACTIVE;
127                 break;
128         case DLE_CTRL_TYPE_PLE:
129                 ctrl_reg = R_AX_PLE_DBG_FUN_INTF_CTL;
130                 data_reg = R_AX_PLE_DBG_FUN_INTF_DATA;
131                 ctrl_data = FIELD_PREP(B_AX_PLE_DFI_TRGSEL_MASK, ctrl->target) |
132                             FIELD_PREP(B_AX_PLE_DFI_ADDR_MASK, ctrl->addr) |
133                             B_AX_PLE_DFI_ACTIVE;
134                 break;
135         default:
136                 rtw89_warn(rtwdev, "[ERR] dfi ctrl type %d\n", ctrl->type);
137                 return -EINVAL;
138         }
139
140         rtw89_write32(rtwdev, ctrl_reg, ctrl_data);
141
142         ret = read_poll_timeout_atomic(rtw89_read32, val, !(val & B_AX_WDE_DFI_ACTIVE),
143                                        1, 1000, false, rtwdev, ctrl_reg);
144         if (ret) {
145                 rtw89_warn(rtwdev, "[ERR] dle dfi ctrl 0x%X set 0x%X timeout\n",
146                            ctrl_reg, ctrl_data);
147                 return ret;
148         }
149
150         ctrl->out_data = rtw89_read32(rtwdev, data_reg);
151         return 0;
152 }
153
154 static int dle_dfi_quota(struct rtw89_dev *rtwdev,
155                          struct rtw89_mac_dle_dfi_quota *quota)
156 {
157         struct rtw89_mac_dle_dfi_ctrl ctrl;
158         int ret;
159
160         ctrl.type = quota->dle_type;
161         ctrl.target = DLE_DFI_TYPE_QUOTA;
162         ctrl.addr = quota->qtaid;
163         ret = dle_dfi_ctrl(rtwdev, &ctrl);
164         if (ret) {
165                 rtw89_warn(rtwdev, "[ERR]dle_dfi_ctrl %d\n", ret);
166                 return ret;
167         }
168
169         quota->rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, ctrl.out_data);
170         quota->use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, ctrl.out_data);
171         return 0;
172 }
173
174 static int dle_dfi_qempty(struct rtw89_dev *rtwdev,
175                           struct rtw89_mac_dle_dfi_qempty *qempty)
176 {
177         struct rtw89_mac_dle_dfi_ctrl ctrl;
178         u32 ret;
179
180         ctrl.type = qempty->dle_type;
181         ctrl.target = DLE_DFI_TYPE_QEMPTY;
182         ctrl.addr = qempty->grpsel;
183         ret = dle_dfi_ctrl(rtwdev, &ctrl);
184         if (ret) {
185                 rtw89_warn(rtwdev, "[ERR]dle_dfi_ctrl %d\n", ret);
186                 return ret;
187         }
188
189         qempty->qempty = FIELD_GET(B_AX_DLE_QEMPTY_GRP, ctrl.out_data);
190         return 0;
191 }
192
193 static void dump_err_status_dispatcher(struct rtw89_dev *rtwdev)
194 {
195         rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_IMR=0x%08x ",
196                    rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
197         rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_ISR=0x%08x\n",
198                    rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR));
199         rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ALWAYS_IMR=0x%08x ",
200                    rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR));
201         rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ALWAYS_ISR=0x%08x\n",
202                    rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR));
203         rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ALWAYS_IMR=0x%08x ",
204                    rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR));
205         rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ALWAYS_ISR=0x%08x\n",
206                    rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
207 }
208
209 static void rtw89_mac_dump_qta_lost(struct rtw89_dev *rtwdev)
210 {
211         struct rtw89_mac_dle_dfi_qempty qempty;
212         struct rtw89_mac_dle_dfi_quota quota;
213         struct rtw89_mac_dle_dfi_ctrl ctrl;
214         u32 val, not_empty, i;
215         int ret;
216
217         qempty.dle_type = DLE_CTRL_TYPE_PLE;
218         qempty.grpsel = 0;
219         qempty.qempty = ~(u32)0;
220         ret = dle_dfi_qempty(rtwdev, &qempty);
221         if (ret)
222                 rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
223         else
224                 rtw89_info(rtwdev, "DLE group0 empty: 0x%x\n", qempty.qempty);
225
226         for (not_empty = ~qempty.qempty, i = 0; not_empty != 0; not_empty >>= 1, i++) {
227                 if (!(not_empty & BIT(0)))
228                         continue;
229                 ctrl.type = DLE_CTRL_TYPE_PLE;
230                 ctrl.target = DLE_DFI_TYPE_QLNKTBL;
231                 ctrl.addr = (QLNKTBL_ADDR_INFO_SEL_0 ? QLNKTBL_ADDR_INFO_SEL : 0) |
232                             FIELD_PREP(QLNKTBL_ADDR_TBL_IDX_MASK, i);
233                 ret = dle_dfi_ctrl(rtwdev, &ctrl);
234                 if (ret)
235                         rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
236                 else
237                         rtw89_info(rtwdev, "qidx%d pktcnt = %ld\n", i,
238                                    FIELD_GET(QLNKTBL_DATA_SEL1_PKT_CNT_MASK,
239                                              ctrl.out_data));
240         }
241
242         quota.dle_type = DLE_CTRL_TYPE_PLE;
243         quota.qtaid = 6;
244         ret = dle_dfi_quota(rtwdev, &quota);
245         if (ret)
246                 rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
247         else
248                 rtw89_info(rtwdev, "quota6 rsv/use: 0x%x/0x%x\n",
249                            quota.rsv_pgnum, quota.use_pgnum);
250
251         val = rtw89_read32(rtwdev, R_AX_PLE_QTA6_CFG);
252         rtw89_info(rtwdev, "[PLE][CMAC0_RX]min_pgnum=0x%lx\n",
253                    FIELD_GET(B_AX_PLE_Q6_MIN_SIZE_MASK, val));
254         rtw89_info(rtwdev, "[PLE][CMAC0_RX]max_pgnum=0x%lx\n",
255                    FIELD_GET(B_AX_PLE_Q6_MAX_SIZE_MASK, val));
256
257         dump_err_status_dispatcher(rtwdev);
258 }
259
260 static void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev,
261                                     enum mac_ax_err_info err)
262 {
263         u32 dbg, event;
264
265         dbg = rtw89_read32(rtwdev, R_AX_SER_DBG_INFO);
266         event = FIELD_GET(B_AX_L0_TO_L1_EVENT_MASK, dbg);
267
268         switch (event) {
269         case MAC_AX_L0_TO_L1_RX_QTA_LOST:
270                 rtw89_info(rtwdev, "quota lost!\n");
271                 rtw89_mac_dump_qta_lost(rtwdev);
272                 break;
273         default:
274                 break;
275         }
276 }
277
278 static void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev)
279 {
280         const struct rtw89_chip_info *chip = rtwdev->chip;
281         u32 dmac_err;
282         int i, ret;
283
284         ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);
285         if (ret) {
286                 rtw89_warn(rtwdev, "[DMAC] : DMAC not enabled\n");
287                 return;
288         }
289
290         dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR);
291         rtw89_info(rtwdev, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err);
292         rtw89_info(rtwdev, "R_AX_DMAC_ERR_IMR=0x%08x\n",
293                    rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR));
294
295         if (dmac_err) {
296                 rtw89_info(rtwdev, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n",
297                            rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1));
298                 rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n",
299                            rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1));
300                 if (chip->chip_id == RTL8852C) {
301                         rtw89_info(rtwdev, "R_AX_PLE_ERRFLAG_MSG=0x%08x\n",
302                                    rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG));
303                         rtw89_info(rtwdev, "R_AX_WDE_ERRFLAG_MSG=0x%08x\n",
304                                    rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG));
305                         rtw89_info(rtwdev, "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n",
306                                    rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN));
307                         rtw89_info(rtwdev, "R_AX_PLE_DBGERR_STS=0x%08x\n",
308                                    rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS));
309                 }
310         }
311
312         if (dmac_err & B_AX_WDRLS_ERR_FLAG) {
313                 rtw89_info(rtwdev, "R_AX_WDRLS_ERR_IMR=0x%08x\n",
314                            rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR));
315                 rtw89_info(rtwdev, "R_AX_WDRLS_ERR_ISR=0x%08x\n",
316                            rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR));
317                 if (chip->chip_id == RTL8852C)
318                         rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX=0x%08x\n",
319                                    rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1));
320                 else
321                         rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX=0x%08x\n",
322                                    rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX));
323         }
324
325         if (dmac_err & B_AX_WSEC_ERR_FLAG) {
326                 if (chip->chip_id == RTL8852C) {
327                         rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR=0x%08x\n",
328                                    rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR));
329                         rtw89_info(rtwdev, "R_AX_SEC_ERR_ISR=0x%08x\n",
330                                    rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG));
331                         rtw89_info(rtwdev, "R_AX_SEC_ENG_CTRL=0x%08x\n",
332                                    rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
333                         rtw89_info(rtwdev, "R_AX_SEC_MPDU_PROC=0x%08x\n",
334                                    rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
335                         rtw89_info(rtwdev, "R_AX_SEC_CAM_ACCESS=0x%08x\n",
336                                    rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
337                         rtw89_info(rtwdev, "R_AX_SEC_CAM_RDATA=0x%08x\n",
338                                    rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
339                         rtw89_info(rtwdev, "R_AX_SEC_DEBUG1=0x%08x\n",
340                                    rtw89_read32(rtwdev, R_AX_SEC_DEBUG1));
341                         rtw89_info(rtwdev, "R_AX_SEC_TX_DEBUG=0x%08x\n",
342                                    rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
343                         rtw89_info(rtwdev, "R_AX_SEC_RX_DEBUG=0x%08x\n",
344                                    rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
345
346                         rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
347                                            B_AX_DBG_SEL0, 0x8B);
348                         rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
349                                            B_AX_DBG_SEL1, 0x8B);
350                         rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1,
351                                            B_AX_SEL_0XC0_MASK, 1);
352                         for (i = 0; i < 0x10; i++) {
353                                 rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL,
354                                                    B_AX_SEC_DBG_PORT_FIELD_MASK, i);
355                                 rtw89_info(rtwdev, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n",
356                                            i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2));
357                         }
358                 } else {
359                         rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n",
360                                    rtw89_read32(rtwdev, R_AX_SEC_DEBUG));
361                         rtw89_info(rtwdev, "R_AX_SEC_ENG_CTRL=0x%08x\n",
362                                    rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
363                         rtw89_info(rtwdev, "R_AX_SEC_MPDU_PROC=0x%08x\n",
364                                    rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
365                         rtw89_info(rtwdev, "R_AX_SEC_CAM_ACCESS=0x%08x\n",
366                                    rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
367                         rtw89_info(rtwdev, "R_AX_SEC_CAM_RDATA=0x%08x\n",
368                                    rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
369                         rtw89_info(rtwdev, "R_AX_SEC_CAM_WDATA=0x%08x\n",
370                                    rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA));
371                         rtw89_info(rtwdev, "R_AX_SEC_TX_DEBUG=0x%08x\n",
372                                    rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
373                         rtw89_info(rtwdev, "R_AX_SEC_RX_DEBUG=0x%08x\n",
374                                    rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
375                         rtw89_info(rtwdev, "R_AX_SEC_TRX_PKT_CNT=0x%08x\n",
376                                    rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT));
377                         rtw89_info(rtwdev, "R_AX_SEC_TRX_BLK_CNT=0x%08x\n",
378                                    rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT));
379                 }
380         }
381
382         if (dmac_err & B_AX_MPDU_ERR_FLAG) {
383                 rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n",
384                            rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR));
385                 rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n",
386                            rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR));
387                 rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n",
388                            rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR));
389                 rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n",
390                            rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR));
391         }
392
393         if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) {
394                 rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n",
395                            rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR));
396                 rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n",
397                            rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR));
398         }
399
400         if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) {
401                 rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x\n",
402                            rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
403                 rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n",
404                            rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
405                 rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x\n",
406                            rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
407                 rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
408                            rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
409         }
410
411         if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) {
412                 if (chip->chip_id == RTL8852C) {
413                         rtw89_info(rtwdev, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n",
414                                    rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR));
415                         rtw89_info(rtwdev, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n",
416                                    rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR));
417                         rtw89_info(rtwdev, "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n",
418                                    rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR));
419                         rtw89_info(rtwdev, "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n",
420                                    rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR));
421                 } else {
422                         rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n",
423                                    rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR));
424                         rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n",
425                                    rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1));
426                 }
427         }
428
429         if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) {
430                 rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x\n",
431                            rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
432                 rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n",
433                            rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
434                 rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x\n",
435                            rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
436                 rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
437                            rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
438                 rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_0=0x%08x\n",
439                            rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0));
440                 rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_1=0x%08x\n",
441                            rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1));
442                 rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_2=0x%08x\n",
443                            rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2));
444                 rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n",
445                            rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS));
446                 rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_0=0x%08x\n",
447                            rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0));
448                 rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_1=0x%08x\n",
449                            rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1));
450                 rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_2=0x%08x\n",
451                            rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2));
452                 rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n",
453                            rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS));
454                 if (chip->chip_id == RTL8852C) {
455                         rtw89_info(rtwdev, "R_AX_RX_CTRL0=0x%08x\n",
456                                    rtw89_read32(rtwdev, R_AX_RX_CTRL0));
457                         rtw89_info(rtwdev, "R_AX_RX_CTRL1=0x%08x\n",
458                                    rtw89_read32(rtwdev, R_AX_RX_CTRL1));
459                         rtw89_info(rtwdev, "R_AX_RX_CTRL2=0x%08x\n",
460                                    rtw89_read32(rtwdev, R_AX_RX_CTRL2));
461                 } else {
462                         rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n",
463                                    rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0));
464                         rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n",
465                                    rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1));
466                         rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n",
467                                    rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2));
468                 }
469         }
470
471         if (dmac_err & B_AX_PKTIN_ERR_FLAG) {
472                 rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR=0x%08x\n",
473                            rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR));
474                 rtw89_info(rtwdev, "R_AX_PKTIN_ERR_ISR=0x%08x\n",
475                            rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR));
476         }
477
478         if (dmac_err & B_AX_DISPATCH_ERR_FLAG) {
479                 rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n",
480                            rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
481                 rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n",
482                            rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR));
483                 rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n",
484                            rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR));
485                 rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n",
486                            rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR));
487                 rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n",
488                            rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR));
489                 rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n",
490                            rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
491         }
492
493         if (dmac_err & B_AX_BBRPT_ERR_FLAG) {
494                 if (chip->chip_id == RTL8852C) {
495                         rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n",
496                                    rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR));
497                         rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n",
498                                    rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR));
499                         rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
500                                    rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
501                         rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
502                                    rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
503                         rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
504                                    rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
505                         rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
506                                    rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
507                 } else {
508                         rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n",
509                                    rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR));
510                         rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
511                                    rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
512                         rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
513                                    rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
514                         rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
515                                    rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
516                         rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
517                                    rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
518                 }
519         }
520
521         if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && chip->chip_id == RTL8852C) {
522                 rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n",
523                            rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK));
524                 rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n",
525                            rtw89_read32(rtwdev, R_AX_HAXI_IDCT));
526         }
527 }
528
529 static void rtw89_mac_dump_cmac_err_status(struct rtw89_dev *rtwdev,
530                                            u8 band)
531 {
532         const struct rtw89_chip_info *chip = rtwdev->chip;
533         u32 offset = 0;
534         u32 cmac_err;
535         int ret;
536
537         ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL);
538         if (ret) {
539                 if (band)
540                         rtw89_warn(rtwdev, "[CMAC] : CMAC1 not enabled\n");
541                 else
542                         rtw89_warn(rtwdev, "[CMAC] : CMAC0 not enabled\n");
543                 return;
544         }
545
546         if (band)
547                 offset = RTW89_MAC_AX_BAND_REG_OFFSET;
548
549         cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset);
550         rtw89_info(rtwdev, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band,
551                    rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset));
552         rtw89_info(rtwdev, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band,
553                    rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset));
554         rtw89_info(rtwdev, "R_AX_CK_EN [%d]=0x%08x\n", band,
555                    rtw89_read32(rtwdev, R_AX_CK_EN + offset));
556
557         if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) {
558                 rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band,
559                            rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset));
560                 rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band,
561                            rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset));
562         }
563
564         if (cmac_err & B_AX_PTCL_TOP_ERR_IND) {
565                 rtw89_info(rtwdev, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", band,
566                            rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset));
567                 rtw89_info(rtwdev, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", band,
568                            rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset));
569         }
570
571         if (cmac_err & B_AX_DMA_TOP_ERR_IND) {
572                 if (chip->chip_id == RTL8852C) {
573                         rtw89_info(rtwdev, "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band,
574                                    rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset));
575                         rtw89_info(rtwdev, "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", band,
576                                    rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset));
577                 } else {
578                         rtw89_info(rtwdev, "R_AX_DLE_CTRL [%d]=0x%08x\n", band,
579                                    rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset));
580                 }
581         }
582
583         if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) {
584                 if (chip->chip_id == RTL8852C) {
585                         rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", band,
586                                    rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset));
587                         rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band,
588                                    rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
589                 } else {
590                         rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band,
591                                    rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
592                 }
593         }
594
595         if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) {
596                 rtw89_info(rtwdev, "R_AX_TXPWR_IMR [%d]=0x%08x\n", band,
597                            rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset));
598                 rtw89_info(rtwdev, "R_AX_TXPWR_ISR [%d]=0x%08x\n", band,
599                            rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset));
600         }
601
602         if (cmac_err & B_AX_WMAC_TX_ERR_IND) {
603                 if (chip->chip_id == RTL8852C) {
604                         rtw89_info(rtwdev, "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band,
605                                    rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA + offset));
606                         rtw89_info(rtwdev, "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band,
607                                    rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA_MASK + offset));
608                 } else {
609                         rtw89_info(rtwdev, "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", band,
610                                    rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR + offset));
611                 }
612                 rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band,
613                            rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset));
614         }
615
616         rtw89_info(rtwdev, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band,
617                    rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset));
618 }
619
620 static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev,
621                                       enum mac_ax_err_info err)
622 {
623         if (err != MAC_AX_ERR_L1_ERR_DMAC &&
624             err != MAC_AX_ERR_L0_PROMOTE_TO_L1 &&
625             err != MAC_AX_ERR_L0_ERR_CMAC0 &&
626             err != MAC_AX_ERR_L0_ERR_CMAC1 &&
627             err != MAC_AX_ERR_RXI300)
628                 return;
629
630         rtw89_info(rtwdev, "--->\nerr=0x%x\n", err);
631         rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n",
632                    rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
633
634         rtw89_mac_dump_dmac_err_status(rtwdev);
635         rtw89_mac_dump_cmac_err_status(rtwdev, RTW89_MAC_0);
636         if (rtwdev->dbcc_en)
637                 rtw89_mac_dump_cmac_err_status(rtwdev, RTW89_MAC_1);
638
639         rtwdev->hci.ops->dump_err_status(rtwdev);
640
641         if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1)
642                 rtw89_mac_dump_l0_to_l1(rtwdev, err);
643
644         rtw89_info(rtwdev, "<---\n");
645 }
646
647 static bool rtw89_mac_suppress_log(struct rtw89_dev *rtwdev, u32 err)
648 {
649         struct rtw89_ser *ser = &rtwdev->ser;
650         u32 dmac_err, imr, isr;
651         int ret;
652
653         if (rtwdev->chip->chip_id == RTL8852C) {
654                 ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);
655                 if (ret)
656                         return true;
657
658                 if (err == MAC_AX_ERR_L1_ERR_DMAC) {
659                         dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR);
660                         imr = rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR);
661                         isr = rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR);
662
663                         if ((dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) &&
664                             ((isr & imr) & B_AX_B0_ISR_ERR_CMDPSR_FRZTO)) {
665                                 set_bit(RTW89_SER_SUPPRESS_LOG, ser->flags);
666                                 return true;
667                         }
668                 } else if (err == MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE) {
669                         if (test_bit(RTW89_SER_SUPPRESS_LOG, ser->flags))
670                                 return true;
671                 } else if (err == MAC_AX_ERR_L1_RESET_RECOVERY_DONE) {
672                         if (test_and_clear_bit(RTW89_SER_SUPPRESS_LOG, ser->flags))
673                                 return true;
674                 }
675         }
676
677         return false;
678 }
679
680 u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev)
681 {
682         u32 err, err_scnr;
683         int ret;
684
685         ret = read_poll_timeout(rtw89_read32, err, (err != 0), 1000, 100000,
686                                 false, rtwdev, R_AX_HALT_C2H_CTRL);
687         if (ret) {
688                 rtw89_warn(rtwdev, "Polling FW err status fail\n");
689                 return ret;
690         }
691
692         err = rtw89_read32(rtwdev, R_AX_HALT_C2H);
693         rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0);
694
695         err_scnr = RTW89_ERROR_SCENARIO(err);
696         if (err_scnr == RTW89_WCPU_CPU_EXCEPTION)
697                 err = MAC_AX_ERR_CPU_EXCEPTION;
698         else if (err_scnr == RTW89_WCPU_ASSERTION)
699                 err = MAC_AX_ERR_ASSERTION;
700         else if (err_scnr == RTW89_RXI300_ERROR)
701                 err = MAC_AX_ERR_RXI300;
702
703         if (rtw89_mac_suppress_log(rtwdev, err))
704                 return err;
705
706         rtw89_fw_st_dbg_dump(rtwdev);
707         rtw89_mac_dump_err_status(rtwdev, err);
708
709         return err;
710 }
711 EXPORT_SYMBOL(rtw89_mac_get_err_status);
712
713 int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err)
714 {
715         struct rtw89_ser *ser = &rtwdev->ser;
716         u32 halt;
717         int ret = 0;
718
719         if (err > MAC_AX_SET_ERR_MAX) {
720                 rtw89_err(rtwdev, "Bad set-err-status value 0x%08x\n", err);
721                 return -EINVAL;
722         }
723
724         ret = read_poll_timeout(rtw89_read32, halt, (halt == 0x0), 1000,
725                                 100000, false, rtwdev, R_AX_HALT_H2C_CTRL);
726         if (ret) {
727                 rtw89_err(rtwdev, "FW doesn't receive previous msg\n");
728                 return -EFAULT;
729         }
730
731         rtw89_write32(rtwdev, R_AX_HALT_H2C, err);
732
733         if (ser->prehandle_l1 &&
734             (err == MAC_AX_ERR_L1_DISABLE_EN || err == MAC_AX_ERR_L1_RCVY_EN))
735                 return 0;
736
737         rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, B_AX_HALT_H2C_TRIGGER);
738
739         return 0;
740 }
741 EXPORT_SYMBOL(rtw89_mac_set_err_status);
742
743 static int hfc_reset_param(struct rtw89_dev *rtwdev)
744 {
745         struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
746         struct rtw89_hfc_param_ini param_ini = {NULL};
747         u8 qta_mode = rtwdev->mac.dle_info.qta_mode;
748
749         switch (rtwdev->hci.type) {
750         case RTW89_HCI_TYPE_PCIE:
751                 param_ini = rtwdev->chip->hfc_param_ini[qta_mode];
752                 param->en = 0;
753                 break;
754         default:
755                 return -EINVAL;
756         }
757
758         if (param_ini.pub_cfg)
759                 param->pub_cfg = *param_ini.pub_cfg;
760
761         if (param_ini.prec_cfg)
762                 param->prec_cfg = *param_ini.prec_cfg;
763
764         if (param_ini.ch_cfg)
765                 param->ch_cfg = param_ini.ch_cfg;
766
767         memset(&param->ch_info, 0, sizeof(param->ch_info));
768         memset(&param->pub_info, 0, sizeof(param->pub_info));
769         param->mode = param_ini.mode;
770
771         return 0;
772 }
773
774 static int hfc_ch_cfg_chk(struct rtw89_dev *rtwdev, u8 ch)
775 {
776         struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
777         const struct rtw89_hfc_ch_cfg *ch_cfg = param->ch_cfg;
778         const struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
779         const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
780
781         if (ch >= RTW89_DMA_CH_NUM)
782                 return -EINVAL;
783
784         if ((ch_cfg[ch].min && ch_cfg[ch].min < prec_cfg->ch011_prec) ||
785             ch_cfg[ch].max > pub_cfg->pub_max)
786                 return -EINVAL;
787         if (ch_cfg[ch].grp >= grp_num)
788                 return -EINVAL;
789
790         return 0;
791 }
792
793 static int hfc_pub_info_chk(struct rtw89_dev *rtwdev)
794 {
795         struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
796         const struct rtw89_hfc_pub_cfg *cfg = &param->pub_cfg;
797         struct rtw89_hfc_pub_info *info = &param->pub_info;
798
799         if (info->g0_used + info->g1_used + info->pub_aval != cfg->pub_max) {
800                 if (rtwdev->chip->chip_id == RTL8852A)
801                         return 0;
802                 else
803                         return -EFAULT;
804         }
805
806         return 0;
807 }
808
809 static int hfc_pub_cfg_chk(struct rtw89_dev *rtwdev)
810 {
811         struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
812         const struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
813
814         if (pub_cfg->grp0 + pub_cfg->grp1 != pub_cfg->pub_max)
815                 return -EFAULT;
816
817         return 0;
818 }
819
820 static int hfc_ch_ctrl(struct rtw89_dev *rtwdev, u8 ch)
821 {
822         const struct rtw89_chip_info *chip = rtwdev->chip;
823         const struct rtw89_page_regs *regs = chip->page_regs;
824         struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
825         const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg;
826         int ret = 0;
827         u32 val = 0;
828
829         ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
830         if (ret)
831                 return ret;
832
833         ret = hfc_ch_cfg_chk(rtwdev, ch);
834         if (ret)
835                 return ret;
836
837         if (ch > RTW89_DMA_B1HI)
838                 return -EINVAL;
839
840         val = u32_encode_bits(cfg[ch].min, B_AX_MIN_PG_MASK) |
841               u32_encode_bits(cfg[ch].max, B_AX_MAX_PG_MASK) |
842               (cfg[ch].grp ? B_AX_GRP : 0);
843         rtw89_write32(rtwdev, regs->ach_page_ctrl + ch * 4, val);
844
845         return 0;
846 }
847
848 static int hfc_upd_ch_info(struct rtw89_dev *rtwdev, u8 ch)
849 {
850         const struct rtw89_chip_info *chip = rtwdev->chip;
851         const struct rtw89_page_regs *regs = chip->page_regs;
852         struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
853         struct rtw89_hfc_ch_info *info = param->ch_info;
854         const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg;
855         u32 val;
856         u32 ret;
857
858         ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
859         if (ret)
860                 return ret;
861
862         if (ch > RTW89_DMA_H2C)
863                 return -EINVAL;
864
865         val = rtw89_read32(rtwdev, regs->ach_page_info + ch * 4);
866         info[ch].aval = u32_get_bits(val, B_AX_AVAL_PG_MASK);
867         if (ch < RTW89_DMA_H2C)
868                 info[ch].used = u32_get_bits(val, B_AX_USE_PG_MASK);
869         else
870                 info[ch].used = cfg[ch].min - info[ch].aval;
871
872         return 0;
873 }
874
875 static int hfc_pub_ctrl(struct rtw89_dev *rtwdev)
876 {
877         const struct rtw89_chip_info *chip = rtwdev->chip;
878         const struct rtw89_page_regs *regs = chip->page_regs;
879         const struct rtw89_hfc_pub_cfg *cfg = &rtwdev->mac.hfc_param.pub_cfg;
880         u32 val;
881         int ret;
882
883         ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
884         if (ret)
885                 return ret;
886
887         ret = hfc_pub_cfg_chk(rtwdev);
888         if (ret)
889                 return ret;
890
891         val = u32_encode_bits(cfg->grp0, B_AX_PUBPG_G0_MASK) |
892               u32_encode_bits(cfg->grp1, B_AX_PUBPG_G1_MASK);
893         rtw89_write32(rtwdev, regs->pub_page_ctrl1, val);
894
895         val = u32_encode_bits(cfg->wp_thrd, B_AX_WP_THRD_MASK);
896         rtw89_write32(rtwdev, regs->wp_page_ctrl2, val);
897
898         return 0;
899 }
900
901 static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
902 {
903         const struct rtw89_chip_info *chip = rtwdev->chip;
904         const struct rtw89_page_regs *regs = chip->page_regs;
905         struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
906         struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
907         struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
908         struct rtw89_hfc_pub_info *info = &param->pub_info;
909         u32 val;
910         int ret;
911
912         ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
913         if (ret)
914                 return ret;
915
916         val = rtw89_read32(rtwdev, regs->pub_page_info1);
917         info->g0_used = u32_get_bits(val, B_AX_G0_USE_PG_MASK);
918         info->g1_used = u32_get_bits(val, B_AX_G1_USE_PG_MASK);
919         val = rtw89_read32(rtwdev, regs->pub_page_info3);
920         info->g0_aval = u32_get_bits(val, B_AX_G0_AVAL_PG_MASK);
921         info->g1_aval = u32_get_bits(val, B_AX_G1_AVAL_PG_MASK);
922         info->pub_aval =
923                 u32_get_bits(rtw89_read32(rtwdev, regs->pub_page_info2),
924                              B_AX_PUB_AVAL_PG_MASK);
925         info->wp_aval =
926                 u32_get_bits(rtw89_read32(rtwdev, regs->wp_page_info1),
927                              B_AX_WP_AVAL_PG_MASK);
928
929         val = rtw89_read32(rtwdev, regs->hci_fc_ctrl);
930         param->en = val & B_AX_HCI_FC_EN ? 1 : 0;
931         param->h2c_en = val & B_AX_HCI_FC_CH12_EN ? 1 : 0;
932         param->mode = u32_get_bits(val, B_AX_HCI_FC_MODE_MASK);
933         prec_cfg->ch011_full_cond =
934                 u32_get_bits(val, B_AX_HCI_FC_WD_FULL_COND_MASK);
935         prec_cfg->h2c_full_cond =
936                 u32_get_bits(val, B_AX_HCI_FC_CH12_FULL_COND_MASK);
937         prec_cfg->wp_ch07_full_cond =
938                 u32_get_bits(val, B_AX_HCI_FC_WP_CH07_FULL_COND_MASK);
939         prec_cfg->wp_ch811_full_cond =
940                 u32_get_bits(val, B_AX_HCI_FC_WP_CH811_FULL_COND_MASK);
941
942         val = rtw89_read32(rtwdev, regs->ch_page_ctrl);
943         prec_cfg->ch011_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH011_MASK);
944         prec_cfg->h2c_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH12_MASK);
945
946         val = rtw89_read32(rtwdev, regs->pub_page_ctrl2);
947         pub_cfg->pub_max = u32_get_bits(val, B_AX_PUBPG_ALL_MASK);
948
949         val = rtw89_read32(rtwdev, regs->wp_page_ctrl1);
950         prec_cfg->wp_ch07_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH07_MASK);
951         prec_cfg->wp_ch811_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH811_MASK);
952
953         val = rtw89_read32(rtwdev, regs->wp_page_ctrl2);
954         pub_cfg->wp_thrd = u32_get_bits(val, B_AX_WP_THRD_MASK);
955
956         val = rtw89_read32(rtwdev, regs->pub_page_ctrl1);
957         pub_cfg->grp0 = u32_get_bits(val, B_AX_PUBPG_G0_MASK);
958         pub_cfg->grp1 = u32_get_bits(val, B_AX_PUBPG_G1_MASK);
959
960         ret = hfc_pub_info_chk(rtwdev);
961         if (param->en && ret)
962                 return ret;
963
964         return 0;
965 }
966
967 static void hfc_h2c_cfg(struct rtw89_dev *rtwdev)
968 {
969         const struct rtw89_chip_info *chip = rtwdev->chip;
970         const struct rtw89_page_regs *regs = chip->page_regs;
971         struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
972         const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
973         u32 val;
974
975         val = u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK);
976         rtw89_write32(rtwdev, regs->ch_page_ctrl, val);
977
978         rtw89_write32_mask(rtwdev, regs->hci_fc_ctrl,
979                            B_AX_HCI_FC_CH12_FULL_COND_MASK,
980                            prec_cfg->h2c_full_cond);
981 }
982
983 static void hfc_mix_cfg(struct rtw89_dev *rtwdev)
984 {
985         const struct rtw89_chip_info *chip = rtwdev->chip;
986         const struct rtw89_page_regs *regs = chip->page_regs;
987         struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
988         const struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
989         const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
990         u32 val;
991
992         val = u32_encode_bits(prec_cfg->ch011_prec, B_AX_PREC_PAGE_CH011_MASK) |
993               u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK);
994         rtw89_write32(rtwdev, regs->ch_page_ctrl, val);
995
996         val = u32_encode_bits(pub_cfg->pub_max, B_AX_PUBPG_ALL_MASK);
997         rtw89_write32(rtwdev, regs->pub_page_ctrl2, val);
998
999         val = u32_encode_bits(prec_cfg->wp_ch07_prec,
1000                               B_AX_PREC_PAGE_WP_CH07_MASK) |
1001               u32_encode_bits(prec_cfg->wp_ch811_prec,
1002                               B_AX_PREC_PAGE_WP_CH811_MASK);
1003         rtw89_write32(rtwdev, regs->wp_page_ctrl1, val);
1004
1005         val = u32_replace_bits(rtw89_read32(rtwdev, regs->hci_fc_ctrl),
1006                                param->mode, B_AX_HCI_FC_MODE_MASK);
1007         val = u32_replace_bits(val, prec_cfg->ch011_full_cond,
1008                                B_AX_HCI_FC_WD_FULL_COND_MASK);
1009         val = u32_replace_bits(val, prec_cfg->h2c_full_cond,
1010                                B_AX_HCI_FC_CH12_FULL_COND_MASK);
1011         val = u32_replace_bits(val, prec_cfg->wp_ch07_full_cond,
1012                                B_AX_HCI_FC_WP_CH07_FULL_COND_MASK);
1013         val = u32_replace_bits(val, prec_cfg->wp_ch811_full_cond,
1014                                B_AX_HCI_FC_WP_CH811_FULL_COND_MASK);
1015         rtw89_write32(rtwdev, regs->hci_fc_ctrl, val);
1016 }
1017
1018 static void hfc_func_en(struct rtw89_dev *rtwdev, bool en, bool h2c_en)
1019 {
1020         const struct rtw89_chip_info *chip = rtwdev->chip;
1021         const struct rtw89_page_regs *regs = chip->page_regs;
1022         struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
1023         u32 val;
1024
1025         val = rtw89_read32(rtwdev, regs->hci_fc_ctrl);
1026         param->en = en;
1027         param->h2c_en = h2c_en;
1028         val = en ? (val | B_AX_HCI_FC_EN) : (val & ~B_AX_HCI_FC_EN);
1029         val = h2c_en ? (val | B_AX_HCI_FC_CH12_EN) :
1030                          (val & ~B_AX_HCI_FC_CH12_EN);
1031         rtw89_write32(rtwdev, regs->hci_fc_ctrl, val);
1032 }
1033
1034 static int hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en)
1035 {
1036         const struct rtw89_chip_info *chip = rtwdev->chip;
1037         u32 dma_ch_mask = chip->dma_ch_mask;
1038         u8 ch;
1039         u32 ret = 0;
1040
1041         if (reset)
1042                 ret = hfc_reset_param(rtwdev);
1043         if (ret)
1044                 return ret;
1045
1046         ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
1047         if (ret)
1048                 return ret;
1049
1050         hfc_func_en(rtwdev, false, false);
1051
1052         if (!en && h2c_en) {
1053                 hfc_h2c_cfg(rtwdev);
1054                 hfc_func_en(rtwdev, en, h2c_en);
1055                 return ret;
1056         }
1057
1058         for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) {
1059                 if (dma_ch_mask & BIT(ch))
1060                         continue;
1061                 ret = hfc_ch_ctrl(rtwdev, ch);
1062                 if (ret)
1063                         return ret;
1064         }
1065
1066         ret = hfc_pub_ctrl(rtwdev);
1067         if (ret)
1068                 return ret;
1069
1070         hfc_mix_cfg(rtwdev);
1071         if (en || h2c_en) {
1072                 hfc_func_en(rtwdev, en, h2c_en);
1073                 udelay(10);
1074         }
1075         for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) {
1076                 if (dma_ch_mask & BIT(ch))
1077                         continue;
1078                 ret = hfc_upd_ch_info(rtwdev, ch);
1079                 if (ret)
1080                         return ret;
1081         }
1082         ret = hfc_upd_mix_info(rtwdev);
1083
1084         return ret;
1085 }
1086
1087 #define PWR_POLL_CNT    2000
1088 static int pwr_cmd_poll(struct rtw89_dev *rtwdev,
1089                         const struct rtw89_pwr_cfg *cfg)
1090 {
1091         u8 val = 0;
1092         int ret;
1093         u32 addr = cfg->base == PWR_INTF_MSK_SDIO ?
1094                    cfg->addr | SDIO_LOCAL_BASE_ADDR : cfg->addr;
1095
1096         ret = read_poll_timeout(rtw89_read8, val, !((val ^ cfg->val) & cfg->msk),
1097                                 1000, 1000 * PWR_POLL_CNT, false, rtwdev, addr);
1098
1099         if (!ret)
1100                 return 0;
1101
1102         rtw89_warn(rtwdev, "[ERR] Polling timeout\n");
1103         rtw89_warn(rtwdev, "[ERR] addr: %X, %X\n", addr, cfg->addr);
1104         rtw89_warn(rtwdev, "[ERR] val: %X, %X\n", val, cfg->val);
1105
1106         return -EBUSY;
1107 }
1108
1109 static int rtw89_mac_sub_pwr_seq(struct rtw89_dev *rtwdev, u8 cv_msk,
1110                                  u8 intf_msk, const struct rtw89_pwr_cfg *cfg)
1111 {
1112         const struct rtw89_pwr_cfg *cur_cfg;
1113         u32 addr;
1114         u8 val;
1115
1116         for (cur_cfg = cfg; cur_cfg->cmd != PWR_CMD_END; cur_cfg++) {
1117                 if (!(cur_cfg->intf_msk & intf_msk) ||
1118                     !(cur_cfg->cv_msk & cv_msk))
1119                         continue;
1120
1121                 switch (cur_cfg->cmd) {
1122                 case PWR_CMD_WRITE:
1123                         addr = cur_cfg->addr;
1124
1125                         if (cur_cfg->base == PWR_BASE_SDIO)
1126                                 addr |= SDIO_LOCAL_BASE_ADDR;
1127
1128                         val = rtw89_read8(rtwdev, addr);
1129                         val &= ~(cur_cfg->msk);
1130                         val |= (cur_cfg->val & cur_cfg->msk);
1131
1132                         rtw89_write8(rtwdev, addr, val);
1133                         break;
1134                 case PWR_CMD_POLL:
1135                         if (pwr_cmd_poll(rtwdev, cur_cfg))
1136                                 return -EBUSY;
1137                         break;
1138                 case PWR_CMD_DELAY:
1139                         if (cur_cfg->val == PWR_DELAY_US)
1140                                 udelay(cur_cfg->addr);
1141                         else
1142                                 fsleep(cur_cfg->addr * 1000);
1143                         break;
1144                 default:
1145                         return -EINVAL;
1146                 }
1147         }
1148
1149         return 0;
1150 }
1151
1152 static int rtw89_mac_pwr_seq(struct rtw89_dev *rtwdev,
1153                              const struct rtw89_pwr_cfg * const *cfg_seq)
1154 {
1155         int ret;
1156
1157         for (; *cfg_seq; cfg_seq++) {
1158                 ret = rtw89_mac_sub_pwr_seq(rtwdev, BIT(rtwdev->hal.cv),
1159                                             PWR_INTF_MSK_PCIE, *cfg_seq);
1160                 if (ret)
1161                         return -EBUSY;
1162         }
1163
1164         return 0;
1165 }
1166
1167 static enum rtw89_rpwm_req_pwr_state
1168 rtw89_mac_get_req_pwr_state(struct rtw89_dev *rtwdev)
1169 {
1170         enum rtw89_rpwm_req_pwr_state state;
1171
1172         switch (rtwdev->ps_mode) {
1173         case RTW89_PS_MODE_RFOFF:
1174                 state = RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFOFF;
1175                 break;
1176         case RTW89_PS_MODE_CLK_GATED:
1177                 state = RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED;
1178                 break;
1179         case RTW89_PS_MODE_PWR_GATED:
1180                 state = RTW89_MAC_RPWM_REQ_PWR_STATE_PWR_GATED;
1181                 break;
1182         default:
1183                 state = RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE;
1184                 break;
1185         }
1186         return state;
1187 }
1188
1189 static void rtw89_mac_send_rpwm(struct rtw89_dev *rtwdev,
1190                                 enum rtw89_rpwm_req_pwr_state req_pwr_state,
1191                                 bool notify_wake)
1192 {
1193         u16 request;
1194
1195         spin_lock_bh(&rtwdev->rpwm_lock);
1196
1197         request = rtw89_read16(rtwdev, R_AX_RPWM);
1198         request ^= request | PS_RPWM_TOGGLE;
1199         request |= req_pwr_state;
1200
1201         if (notify_wake) {
1202                 request |= PS_RPWM_NOTIFY_WAKE;
1203         } else {
1204                 rtwdev->mac.rpwm_seq_num = (rtwdev->mac.rpwm_seq_num + 1) &
1205                                             RPWM_SEQ_NUM_MAX;
1206                 request |= FIELD_PREP(PS_RPWM_SEQ_NUM,
1207                                       rtwdev->mac.rpwm_seq_num);
1208
1209                 if (req_pwr_state < RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED)
1210                         request |= PS_RPWM_ACK;
1211         }
1212         rtw89_write16(rtwdev, rtwdev->hci.rpwm_addr, request);
1213
1214         spin_unlock_bh(&rtwdev->rpwm_lock);
1215 }
1216
1217 static int rtw89_mac_check_cpwm_state(struct rtw89_dev *rtwdev,
1218                                       enum rtw89_rpwm_req_pwr_state req_pwr_state)
1219 {
1220         bool request_deep_mode;
1221         bool in_deep_mode;
1222         u8 rpwm_req_num;
1223         u8 cpwm_rsp_seq;
1224         u8 cpwm_seq;
1225         u8 cpwm_status;
1226
1227         if (req_pwr_state >= RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED)
1228                 request_deep_mode = true;
1229         else
1230                 request_deep_mode = false;
1231
1232         if (rtw89_read32_mask(rtwdev, R_AX_LDM, B_AX_EN_32K))
1233                 in_deep_mode = true;
1234         else
1235                 in_deep_mode = false;
1236
1237         if (request_deep_mode != in_deep_mode)
1238                 return -EPERM;
1239
1240         if (request_deep_mode)
1241                 return 0;
1242
1243         rpwm_req_num = rtwdev->mac.rpwm_seq_num;
1244         cpwm_rsp_seq = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr,
1245                                          PS_CPWM_RSP_SEQ_NUM);
1246
1247         if (rpwm_req_num != cpwm_rsp_seq)
1248                 return -EPERM;
1249
1250         rtwdev->mac.cpwm_seq_num = (rtwdev->mac.cpwm_seq_num + 1) &
1251                                     CPWM_SEQ_NUM_MAX;
1252
1253         cpwm_seq = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr, PS_CPWM_SEQ_NUM);
1254         if (cpwm_seq != rtwdev->mac.cpwm_seq_num)
1255                 return -EPERM;
1256
1257         cpwm_status = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr, PS_CPWM_STATE);
1258         if (cpwm_status != req_pwr_state)
1259                 return -EPERM;
1260
1261         return 0;
1262 }
1263
1264 void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
1265 {
1266         enum rtw89_rpwm_req_pwr_state state;
1267         unsigned long delay = enter ? 10 : 150;
1268         int ret;
1269         int i;
1270
1271         if (enter)
1272                 state = rtw89_mac_get_req_pwr_state(rtwdev);
1273         else
1274                 state = RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE;
1275
1276         for (i = 0; i < RPWM_TRY_CNT; i++) {
1277                 rtw89_mac_send_rpwm(rtwdev, state, false);
1278                 ret = read_poll_timeout_atomic(rtw89_mac_check_cpwm_state, ret,
1279                                                !ret, delay, 15000, false,
1280                                                rtwdev, state);
1281                 if (!ret)
1282                         break;
1283
1284                 if (i == RPWM_TRY_CNT - 1)
1285                         rtw89_err(rtwdev, "firmware failed to ack for %s ps mode\n",
1286                                   enter ? "entering" : "leaving");
1287                 else
1288                         rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
1289                                     "%d time firmware failed to ack for %s ps mode\n",
1290                                     i + 1, enter ? "entering" : "leaving");
1291         }
1292 }
1293
1294 void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev)
1295 {
1296         enum rtw89_rpwm_req_pwr_state state;
1297
1298         state = rtw89_mac_get_req_pwr_state(rtwdev);
1299         rtw89_mac_send_rpwm(rtwdev, state, true);
1300 }
1301
1302 static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
1303 {
1304 #define PWR_ACT 1
1305         const struct rtw89_chip_info *chip = rtwdev->chip;
1306         const struct rtw89_pwr_cfg * const *cfg_seq;
1307         int (*cfg_func)(struct rtw89_dev *rtwdev);
1308         int ret;
1309         u8 val;
1310
1311         if (on) {
1312                 cfg_seq = chip->pwr_on_seq;
1313                 cfg_func = chip->ops->pwr_on_func;
1314         } else {
1315                 cfg_seq = chip->pwr_off_seq;
1316                 cfg_func = chip->ops->pwr_off_func;
1317         }
1318
1319         if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags))
1320                 __rtw89_leave_ps_mode(rtwdev);
1321
1322         val = rtw89_read32_mask(rtwdev, R_AX_IC_PWR_STATE, B_AX_WLMAC_PWR_STE_MASK);
1323         if (on && val == PWR_ACT) {
1324                 rtw89_err(rtwdev, "MAC has already powered on\n");
1325                 return -EBUSY;
1326         }
1327
1328         ret = cfg_func ? cfg_func(rtwdev) : rtw89_mac_pwr_seq(rtwdev, cfg_seq);
1329         if (ret)
1330                 return ret;
1331
1332         if (on) {
1333                 set_bit(RTW89_FLAG_POWERON, rtwdev->flags);
1334                 rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_TP_MAJOR);
1335         } else {
1336                 clear_bit(RTW89_FLAG_POWERON, rtwdev->flags);
1337                 clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
1338                 rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_PWR_MAJOR);
1339                 rtw89_set_entity_state(rtwdev, false);
1340         }
1341
1342         return 0;
1343 #undef PWR_ACT
1344 }
1345
1346 void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev)
1347 {
1348         rtw89_mac_power_switch(rtwdev, false);
1349 }
1350
1351 static int cmac_func_en(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
1352 {
1353         u32 func_en = 0;
1354         u32 ck_en = 0;
1355         u32 c1pc_en = 0;
1356         u32 addrl_func_en[] = {R_AX_CMAC_FUNC_EN, R_AX_CMAC_FUNC_EN_C1};
1357         u32 addrl_ck_en[] = {R_AX_CK_EN, R_AX_CK_EN_C1};
1358
1359         func_en = B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN |
1360                         B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN |
1361                         B_AX_SCHEDULER_EN | B_AX_TMAC_EN | B_AX_RMAC_EN |
1362                         B_AX_CMAC_CRPRT;
1363         ck_en = B_AX_CMAC_CKEN | B_AX_PHYINTF_CKEN | B_AX_CMAC_DMA_CKEN |
1364                       B_AX_PTCLTOP_CKEN | B_AX_SCHEDULER_CKEN | B_AX_TMAC_CKEN |
1365                       B_AX_RMAC_CKEN;
1366         c1pc_en = B_AX_R_SYM_WLCMAC1_PC_EN |
1367                         B_AX_R_SYM_WLCMAC1_P1_PC_EN |
1368                         B_AX_R_SYM_WLCMAC1_P2_PC_EN |
1369                         B_AX_R_SYM_WLCMAC1_P3_PC_EN |
1370                         B_AX_R_SYM_WLCMAC1_P4_PC_EN;
1371
1372         if (en) {
1373                 if (mac_idx == RTW89_MAC_1) {
1374                         rtw89_write32_set(rtwdev, R_AX_AFE_CTRL1, c1pc_en);
1375                         rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
1376                                           B_AX_R_SYM_ISO_CMAC12PP);
1377                         rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
1378                                           B_AX_CMAC1_FEN);
1379                 }
1380                 rtw89_write32_set(rtwdev, addrl_ck_en[mac_idx], ck_en);
1381                 rtw89_write32_set(rtwdev, addrl_func_en[mac_idx], func_en);
1382         } else {
1383                 rtw89_write32_clr(rtwdev, addrl_func_en[mac_idx], func_en);
1384                 rtw89_write32_clr(rtwdev, addrl_ck_en[mac_idx], ck_en);
1385                 if (mac_idx == RTW89_MAC_1) {
1386                         rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
1387                                           B_AX_CMAC1_FEN);
1388                         rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
1389                                           B_AX_R_SYM_ISO_CMAC12PP);
1390                         rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, c1pc_en);
1391                 }
1392         }
1393
1394         return 0;
1395 }
1396
1397 static int dmac_func_en(struct rtw89_dev *rtwdev)
1398 {
1399         enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
1400         u32 val32;
1401
1402         if (chip_id == RTL8852C)
1403                 val32 = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN |
1404                          B_AX_MAC_SEC_EN | B_AX_DISPATCHER_EN |
1405                          B_AX_DLE_CPUIO_EN | B_AX_PKT_IN_EN |
1406                          B_AX_DMAC_TBL_EN | B_AX_PKT_BUF_EN |
1407                          B_AX_STA_SCH_EN | B_AX_TXPKT_CTRL_EN |
1408                          B_AX_WD_RLS_EN | B_AX_MPDU_PROC_EN |
1409                          B_AX_DMAC_CRPRT | B_AX_H_AXIDMA_EN);
1410         else
1411                 val32 = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN |
1412                          B_AX_MAC_SEC_EN | B_AX_DISPATCHER_EN |
1413                          B_AX_DLE_CPUIO_EN | B_AX_PKT_IN_EN |
1414                          B_AX_DMAC_TBL_EN | B_AX_PKT_BUF_EN |
1415                          B_AX_STA_SCH_EN | B_AX_TXPKT_CTRL_EN |
1416                          B_AX_WD_RLS_EN | B_AX_MPDU_PROC_EN |
1417                          B_AX_DMAC_CRPRT);
1418         rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val32);
1419
1420         val32 = (B_AX_MAC_SEC_CLK_EN | B_AX_DISPATCHER_CLK_EN |
1421                  B_AX_DLE_CPUIO_CLK_EN | B_AX_PKT_IN_CLK_EN |
1422                  B_AX_STA_SCH_CLK_EN | B_AX_TXPKT_CTRL_CLK_EN |
1423                  B_AX_WD_RLS_CLK_EN | B_AX_BBRPT_CLK_EN);
1424         rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val32);
1425
1426         return 0;
1427 }
1428
1429 static int chip_func_en(struct rtw89_dev *rtwdev)
1430 {
1431         enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
1432
1433         if (chip_id == RTL8852A || chip_id == RTL8852B)
1434                 rtw89_write32_set(rtwdev, R_AX_SPS_DIG_ON_CTRL0,
1435                                   B_AX_OCP_L1_MASK);
1436
1437         return 0;
1438 }
1439
1440 static int rtw89_mac_sys_init(struct rtw89_dev *rtwdev)
1441 {
1442         int ret;
1443
1444         ret = dmac_func_en(rtwdev);
1445         if (ret)
1446                 return ret;
1447
1448         ret = cmac_func_en(rtwdev, 0, true);
1449         if (ret)
1450                 return ret;
1451
1452         ret = chip_func_en(rtwdev);
1453         if (ret)
1454                 return ret;
1455
1456         return ret;
1457 }
1458
1459 const struct rtw89_mac_size_set rtw89_mac_size = {
1460         .hfc_preccfg_pcie = {2, 40, 0, 0, 1, 0, 0, 0},
1461         /* PCIE 64 */
1462         .wde_size0 = {RTW89_WDE_PG_64, 4095, 1,},
1463         /* DLFW */
1464         .wde_size4 = {RTW89_WDE_PG_64, 0, 4096,},
1465         /* PCIE 64 */
1466         .wde_size6 = {RTW89_WDE_PG_64, 512, 0,},
1467         /* 8852B PCIE SCC */
1468         .wde_size7 = {RTW89_WDE_PG_64, 510, 2,},
1469         /* DLFW */
1470         .wde_size9 = {RTW89_WDE_PG_64, 0, 1024,},
1471         /* 8852C DLFW */
1472         .wde_size18 = {RTW89_WDE_PG_64, 0, 2048,},
1473         /* 8852C PCIE SCC */
1474         .wde_size19 = {RTW89_WDE_PG_64, 3328, 0,},
1475         /* PCIE */
1476         .ple_size0 = {RTW89_PLE_PG_128, 1520, 16,},
1477         /* DLFW */
1478         .ple_size4 = {RTW89_PLE_PG_128, 64, 1472,},
1479         /* PCIE 64 */
1480         .ple_size6 = {RTW89_PLE_PG_128, 496, 16,},
1481         /* DLFW */
1482         .ple_size8 = {RTW89_PLE_PG_128, 64, 960,},
1483         /* 8852C DLFW */
1484         .ple_size18 = {RTW89_PLE_PG_128, 2544, 16,},
1485         /* 8852C PCIE SCC */
1486         .ple_size19 = {RTW89_PLE_PG_128, 1904, 16,},
1487         /* PCIE 64 */
1488         .wde_qt0 = {3792, 196, 0, 107,},
1489         /* DLFW */
1490         .wde_qt4 = {0, 0, 0, 0,},
1491         /* PCIE 64 */
1492         .wde_qt6 = {448, 48, 0, 16,},
1493         /* 8852B PCIE SCC */
1494         .wde_qt7 = {446, 48, 0, 16,},
1495         /* 8852C DLFW */
1496         .wde_qt17 = {0, 0, 0,  0,},
1497         /* 8852C PCIE SCC */
1498         .wde_qt18 = {3228, 60, 0, 40,},
1499         /* PCIE SCC */
1500         .ple_qt4 = {264, 0, 16, 20, 26, 13, 356, 0, 32, 40, 8,},
1501         /* PCIE SCC */
1502         .ple_qt5 = {264, 0, 32, 20, 64, 13, 1101, 0, 64, 128, 120,},
1503         /* DLFW */
1504         .ple_qt13 = {0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0,},
1505         /* PCIE 64 */
1506         .ple_qt18 = {147, 0, 16, 20, 17, 13, 89, 0, 32, 14, 8, 0,},
1507         /* DLFW 52C */
1508         .ple_qt44 = {0, 0, 16, 256, 0, 0, 0, 0, 0, 0, 0, 0,},
1509         /* DLFW 52C */
1510         .ple_qt45 = {0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 0, 0,},
1511         /* 8852C PCIE SCC */
1512         .ple_qt46 = {525, 0, 16, 20, 13, 13, 178, 0, 32, 62, 8, 16,},
1513         /* 8852C PCIE SCC */
1514         .ple_qt47 = {525, 0, 32, 20, 1034, 13, 1199, 0, 1053, 62, 160, 1037,},
1515         /* PCIE 64 */
1516         .ple_qt58 = {147, 0, 16, 20, 157, 13, 229, 0, 172, 14, 24, 0,},
1517         /* 8852A PCIE WOW */
1518         .ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,},
1519         /* 8852B PCIE WOW */
1520         .ple_qt_52b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,},
1521         /* 8851B PCIE WOW */
1522         .ple_qt_51b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,},
1523 };
1524 EXPORT_SYMBOL(rtw89_mac_size);
1525
1526 static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev,
1527                                                    enum rtw89_qta_mode mode)
1528 {
1529         struct rtw89_mac_info *mac = &rtwdev->mac;
1530         const struct rtw89_dle_mem *cfg;
1531
1532         cfg = &rtwdev->chip->dle_mem[mode];
1533         if (!cfg)
1534                 return NULL;
1535
1536         if (cfg->mode != mode) {
1537                 rtw89_warn(rtwdev, "qta mode unmatch!\n");
1538                 return NULL;
1539         }
1540
1541         mac->dle_info.ple_pg_size = cfg->ple_size->pge_size;
1542         mac->dle_info.qta_mode = mode;
1543         mac->dle_info.c0_rx_qta = cfg->ple_min_qt->cma0_dma;
1544         mac->dle_info.c1_rx_qta = cfg->ple_min_qt->cma1_dma;
1545
1546         return cfg;
1547 }
1548
1549 static bool mac_is_txq_empty(struct rtw89_dev *rtwdev)
1550 {
1551         struct rtw89_mac_dle_dfi_qempty qempty;
1552         u32 qnum, qtmp, val32, msk32;
1553         int i, j, ret;
1554
1555         qnum = rtwdev->chip->wde_qempty_acq_num;
1556         qempty.dle_type = DLE_CTRL_TYPE_WDE;
1557
1558         for (i = 0; i < qnum; i++) {
1559                 qempty.grpsel = i;
1560                 ret = dle_dfi_qempty(rtwdev, &qempty);
1561                 if (ret) {
1562                         rtw89_warn(rtwdev, "dle dfi acq empty %d\n", ret);
1563                         return false;
1564                 }
1565                 qtmp = qempty.qempty;
1566                 for (j = 0 ; j < QEMP_ACQ_GRP_MACID_NUM; j++) {
1567                         val32 = FIELD_GET(QEMP_ACQ_GRP_QSEL_MASK, qtmp);
1568                         if (val32 != QEMP_ACQ_GRP_QSEL_MASK)
1569                                 return false;
1570                         qtmp >>= QEMP_ACQ_GRP_QSEL_SH;
1571                 }
1572         }
1573
1574         qempty.grpsel = rtwdev->chip->wde_qempty_mgq_sel;
1575         ret = dle_dfi_qempty(rtwdev, &qempty);
1576         if (ret) {
1577                 rtw89_warn(rtwdev, "dle dfi mgq empty %d\n", ret);
1578                 return false;
1579         }
1580         msk32 = B_CMAC0_MGQ_NORMAL | B_CMAC0_MGQ_NO_PWRSAV | B_CMAC0_CPUMGQ;
1581         if ((qempty.qempty & msk32) != msk32)
1582                 return false;
1583
1584         if (rtwdev->dbcc_en) {
1585                 msk32 |= B_CMAC1_MGQ_NORMAL | B_CMAC1_MGQ_NO_PWRSAV | B_CMAC1_CPUMGQ;
1586                 if ((qempty.qempty & msk32) != msk32)
1587                         return false;
1588         }
1589
1590         msk32 = B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU | B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU |
1591                 B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU | B_AX_PLE_EMPTY_QTA_DMAC_H2C |
1592                 B_AX_WDE_EMPTY_QUE_OTHERS | B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX |
1593                 B_AX_WDE_EMPTY_QTA_DMAC_CPUIO | B_AX_PLE_EMPTY_QTA_DMAC_CPUIO |
1594                 B_AX_WDE_EMPTY_QUE_DMAC_PKTIN | B_AX_WDE_EMPTY_QTA_DMAC_HIF |
1595                 B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX | B_AX_WDE_EMPTY_QTA_DMAC_PKTIN |
1596                 B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL | B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL |
1597                 B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX;
1598         val32 = rtw89_read32(rtwdev, R_AX_DLE_EMPTY0);
1599
1600         return (val32 & msk32) == msk32;
1601 }
1602
1603 static inline u32 dle_used_size(const struct rtw89_dle_size *wde,
1604                                 const struct rtw89_dle_size *ple)
1605 {
1606         return wde->pge_size * (wde->lnk_pge_num + wde->unlnk_pge_num) +
1607                ple->pge_size * (ple->lnk_pge_num + ple->unlnk_pge_num);
1608 }
1609
1610 static u32 dle_expected_used_size(struct rtw89_dev *rtwdev,
1611                                   enum rtw89_qta_mode mode)
1612 {
1613         u32 size = rtwdev->chip->fifo_size;
1614
1615         if (mode == RTW89_QTA_SCC)
1616                 size -= rtwdev->chip->dle_scc_rsvd_size;
1617
1618         return size;
1619 }
1620
1621 static void dle_func_en(struct rtw89_dev *rtwdev, bool enable)
1622 {
1623         if (enable)
1624                 rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN,
1625                                   B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN);
1626         else
1627                 rtw89_write32_clr(rtwdev, R_AX_DMAC_FUNC_EN,
1628                                   B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN);
1629 }
1630
1631 static void dle_clk_en(struct rtw89_dev *rtwdev, bool enable)
1632 {
1633         u32 val = B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN;
1634
1635         if (enable) {
1636                 if (rtwdev->chip->chip_id == RTL8851B)
1637                         val |= B_AX_AXIDMA_CLK_EN;
1638                 rtw89_write32_set(rtwdev, R_AX_DMAC_CLK_EN, val);
1639         } else {
1640                 rtw89_write32_clr(rtwdev, R_AX_DMAC_CLK_EN, val);
1641         }
1642 }
1643
1644 static int dle_mix_cfg(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg)
1645 {
1646         const struct rtw89_dle_size *size_cfg;
1647         u32 val;
1648         u8 bound = 0;
1649
1650         val = rtw89_read32(rtwdev, R_AX_WDE_PKTBUF_CFG);
1651         size_cfg = cfg->wde_size;
1652
1653         switch (size_cfg->pge_size) {
1654         default:
1655         case RTW89_WDE_PG_64:
1656                 val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_64,
1657                                        B_AX_WDE_PAGE_SEL_MASK);
1658                 break;
1659         case RTW89_WDE_PG_128:
1660                 val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_128,
1661                                        B_AX_WDE_PAGE_SEL_MASK);
1662                 break;
1663         case RTW89_WDE_PG_256:
1664                 rtw89_err(rtwdev, "[ERR]WDE DLE doesn't support 256 byte!\n");
1665                 return -EINVAL;
1666         }
1667
1668         val = u32_replace_bits(val, bound, B_AX_WDE_START_BOUND_MASK);
1669         val = u32_replace_bits(val, size_cfg->lnk_pge_num,
1670                                B_AX_WDE_FREE_PAGE_NUM_MASK);
1671         rtw89_write32(rtwdev, R_AX_WDE_PKTBUF_CFG, val);
1672
1673         val = rtw89_read32(rtwdev, R_AX_PLE_PKTBUF_CFG);
1674         bound = (size_cfg->lnk_pge_num + size_cfg->unlnk_pge_num)
1675                                 * size_cfg->pge_size / DLE_BOUND_UNIT;
1676         size_cfg = cfg->ple_size;
1677
1678         switch (size_cfg->pge_size) {
1679         default:
1680         case RTW89_PLE_PG_64:
1681                 rtw89_err(rtwdev, "[ERR]PLE DLE doesn't support 64 byte!\n");
1682                 return -EINVAL;
1683         case RTW89_PLE_PG_128:
1684                 val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_128,
1685                                        B_AX_PLE_PAGE_SEL_MASK);
1686                 break;
1687         case RTW89_PLE_PG_256:
1688                 val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_256,
1689                                        B_AX_PLE_PAGE_SEL_MASK);
1690                 break;
1691         }
1692
1693         val = u32_replace_bits(val, bound, B_AX_PLE_START_BOUND_MASK);
1694         val = u32_replace_bits(val, size_cfg->lnk_pge_num,
1695                                B_AX_PLE_FREE_PAGE_NUM_MASK);
1696         rtw89_write32(rtwdev, R_AX_PLE_PKTBUF_CFG, val);
1697
1698         return 0;
1699 }
1700
1701 #define INVALID_QT_WCPU U16_MAX
1702 #define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx)                    \
1703         do {                                                            \
1704                 val = u32_encode_bits(_min_x, B_AX_ ## _module ## _MIN_SIZE_MASK) | \
1705                       u32_encode_bits(_max_x, B_AX_ ## _module ## _MAX_SIZE_MASK);  \
1706                 rtw89_write32(rtwdev,                                   \
1707                               R_AX_ ## _module ## _QTA ## _idx ## _CFG, \
1708                               val);                                     \
1709         } while (0)
1710 #define SET_QUOTA(_x, _module, _idx)                                    \
1711         SET_QUOTA_VAL(min_cfg->_x, max_cfg->_x, _module, _idx)
1712
1713 static void wde_quota_cfg(struct rtw89_dev *rtwdev,
1714                           const struct rtw89_wde_quota *min_cfg,
1715                           const struct rtw89_wde_quota *max_cfg,
1716                           u16 ext_wde_min_qt_wcpu)
1717 {
1718         u16 min_qt_wcpu = ext_wde_min_qt_wcpu != INVALID_QT_WCPU ?
1719                           ext_wde_min_qt_wcpu : min_cfg->wcpu;
1720         u32 val;
1721
1722         SET_QUOTA(hif, WDE, 0);
1723         SET_QUOTA_VAL(min_qt_wcpu, max_cfg->wcpu, WDE, 1);
1724         SET_QUOTA(pkt_in, WDE, 3);
1725         SET_QUOTA(cpu_io, WDE, 4);
1726 }
1727
1728 static void ple_quota_cfg(struct rtw89_dev *rtwdev,
1729                           const struct rtw89_ple_quota *min_cfg,
1730                           const struct rtw89_ple_quota *max_cfg)
1731 {
1732         u32 val;
1733
1734         SET_QUOTA(cma0_tx, PLE, 0);
1735         SET_QUOTA(cma1_tx, PLE, 1);
1736         SET_QUOTA(c2h, PLE, 2);
1737         SET_QUOTA(h2c, PLE, 3);
1738         SET_QUOTA(wcpu, PLE, 4);
1739         SET_QUOTA(mpdu_proc, PLE, 5);
1740         SET_QUOTA(cma0_dma, PLE, 6);
1741         SET_QUOTA(cma1_dma, PLE, 7);
1742         SET_QUOTA(bb_rpt, PLE, 8);
1743         SET_QUOTA(wd_rel, PLE, 9);
1744         SET_QUOTA(cpu_io, PLE, 10);
1745         if (rtwdev->chip->chip_id == RTL8852C)
1746                 SET_QUOTA(tx_rpt, PLE, 11);
1747 }
1748
1749 int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow)
1750 {
1751         const struct rtw89_ple_quota *min_cfg, *max_cfg;
1752         const struct rtw89_dle_mem *cfg;
1753         u32 val;
1754
1755         if (rtwdev->chip->chip_id == RTL8852C)
1756                 return 0;
1757
1758         if (rtwdev->mac.qta_mode != RTW89_QTA_SCC) {
1759                 rtw89_err(rtwdev, "[ERR]support SCC mode only\n");
1760                 return -EINVAL;
1761         }
1762
1763         if (wow)
1764                 cfg = get_dle_mem_cfg(rtwdev, RTW89_QTA_WOW);
1765         else
1766                 cfg = get_dle_mem_cfg(rtwdev, RTW89_QTA_SCC);
1767         if (!cfg) {
1768                 rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n");
1769                 return -EINVAL;
1770         }
1771
1772         min_cfg = cfg->ple_min_qt;
1773         max_cfg = cfg->ple_max_qt;
1774         SET_QUOTA(cma0_dma, PLE, 6);
1775         SET_QUOTA(cma1_dma, PLE, 7);
1776
1777         return 0;
1778 }
1779 #undef SET_QUOTA
1780
1781 void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool enable)
1782 {
1783         u32 msk32 = B_AX_UC_MGNT_DEC | B_AX_BMC_MGNT_DEC;
1784
1785         if (enable)
1786                 rtw89_write32_set(rtwdev, R_AX_SEC_ENG_CTRL, msk32);
1787         else
1788                 rtw89_write32_clr(rtwdev, R_AX_SEC_ENG_CTRL, msk32);
1789 }
1790
1791 static void dle_quota_cfg(struct rtw89_dev *rtwdev,
1792                           const struct rtw89_dle_mem *cfg,
1793                           u16 ext_wde_min_qt_wcpu)
1794 {
1795         wde_quota_cfg(rtwdev, cfg->wde_min_qt, cfg->wde_max_qt, ext_wde_min_qt_wcpu);
1796         ple_quota_cfg(rtwdev, cfg->ple_min_qt, cfg->ple_max_qt);
1797 }
1798
1799 static int dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
1800                     enum rtw89_qta_mode ext_mode)
1801 {
1802         const struct rtw89_dle_mem *cfg, *ext_cfg;
1803         u16 ext_wde_min_qt_wcpu = INVALID_QT_WCPU;
1804         int ret = 0;
1805         u32 ini;
1806
1807         ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
1808         if (ret)
1809                 return ret;
1810
1811         cfg = get_dle_mem_cfg(rtwdev, mode);
1812         if (!cfg) {
1813                 rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n");
1814                 ret = -EINVAL;
1815                 goto error;
1816         }
1817
1818         if (mode == RTW89_QTA_DLFW) {
1819                 ext_cfg = get_dle_mem_cfg(rtwdev, ext_mode);
1820                 if (!ext_cfg) {
1821                         rtw89_err(rtwdev, "[ERR]get_dle_ext_mem_cfg %d\n",
1822                                   ext_mode);
1823                         ret = -EINVAL;
1824                         goto error;
1825                 }
1826                 ext_wde_min_qt_wcpu = ext_cfg->wde_min_qt->wcpu;
1827         }
1828
1829         if (dle_used_size(cfg->wde_size, cfg->ple_size) !=
1830             dle_expected_used_size(rtwdev, mode)) {
1831                 rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n");
1832                 ret = -EINVAL;
1833                 goto error;
1834         }
1835
1836         dle_func_en(rtwdev, false);
1837         dle_clk_en(rtwdev, true);
1838
1839         ret = dle_mix_cfg(rtwdev, cfg);
1840         if (ret) {
1841                 rtw89_err(rtwdev, "[ERR] dle mix cfg\n");
1842                 goto error;
1843         }
1844         dle_quota_cfg(rtwdev, cfg, ext_wde_min_qt_wcpu);
1845
1846         dle_func_en(rtwdev, true);
1847
1848         ret = read_poll_timeout(rtw89_read32, ini,
1849                                 (ini & WDE_MGN_INI_RDY) == WDE_MGN_INI_RDY, 1,
1850                                 2000, false, rtwdev, R_AX_WDE_INI_STATUS);
1851         if (ret) {
1852                 rtw89_err(rtwdev, "[ERR]WDE cfg ready\n");
1853                 return ret;
1854         }
1855
1856         ret = read_poll_timeout(rtw89_read32, ini,
1857                                 (ini & WDE_MGN_INI_RDY) == WDE_MGN_INI_RDY, 1,
1858                                 2000, false, rtwdev, R_AX_PLE_INI_STATUS);
1859         if (ret) {
1860                 rtw89_err(rtwdev, "[ERR]PLE cfg ready\n");
1861                 return ret;
1862         }
1863
1864         return 0;
1865 error:
1866         dle_func_en(rtwdev, false);
1867         rtw89_err(rtwdev, "[ERR]trxcfg wde 0x8900 = %x\n",
1868                   rtw89_read32(rtwdev, R_AX_WDE_INI_STATUS));
1869         rtw89_err(rtwdev, "[ERR]trxcfg ple 0x8D00 = %x\n",
1870                   rtw89_read32(rtwdev, R_AX_PLE_INI_STATUS));
1871
1872         return ret;
1873 }
1874
1875 static int preload_init_set(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx,
1876                             enum rtw89_qta_mode mode)
1877 {
1878         u32 reg, max_preld_size, min_rsvd_size;
1879
1880         max_preld_size = (mac_idx == RTW89_MAC_0 ?
1881                           PRELD_B0_ENT_NUM : PRELD_B1_ENT_NUM) * PRELD_AMSDU_SIZE;
1882         reg = mac_idx == RTW89_MAC_0 ?
1883               R_AX_TXPKTCTL_B0_PRELD_CFG0 : R_AX_TXPKTCTL_B1_PRELD_CFG0;
1884         rtw89_write32_mask(rtwdev, reg, B_AX_B0_PRELD_USEMAXSZ_MASK, max_preld_size);
1885         rtw89_write32_set(rtwdev, reg, B_AX_B0_PRELD_FEN);
1886
1887         min_rsvd_size = PRELD_AMSDU_SIZE;
1888         reg = mac_idx == RTW89_MAC_0 ?
1889               R_AX_TXPKTCTL_B0_PRELD_CFG1 : R_AX_TXPKTCTL_B1_PRELD_CFG1;
1890         rtw89_write32_mask(rtwdev, reg, B_AX_B0_PRELD_NXT_TXENDWIN_MASK, PRELD_NEXT_WND);
1891         rtw89_write32_mask(rtwdev, reg, B_AX_B0_PRELD_NXT_RSVMINSZ_MASK, min_rsvd_size);
1892
1893         return 0;
1894 }
1895
1896 static bool is_qta_poh(struct rtw89_dev *rtwdev)
1897 {
1898         return rtwdev->hci.type == RTW89_HCI_TYPE_PCIE;
1899 }
1900
1901 static int preload_init(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx,
1902                         enum rtw89_qta_mode mode)
1903 {
1904         const struct rtw89_chip_info *chip = rtwdev->chip;
1905
1906         if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
1907             chip->chip_id == RTL8851B || !is_qta_poh(rtwdev))
1908                 return 0;
1909
1910         return preload_init_set(rtwdev, mac_idx, mode);
1911 }
1912
1913 static bool dle_is_txq_empty(struct rtw89_dev *rtwdev)
1914 {
1915         u32 msk32;
1916         u32 val32;
1917
1918         msk32 = B_AX_WDE_EMPTY_QUE_CMAC0_ALL_AC | B_AX_WDE_EMPTY_QUE_CMAC0_MBH |
1919                 B_AX_WDE_EMPTY_QUE_CMAC1_MBH | B_AX_WDE_EMPTY_QUE_CMAC0_WMM0 |
1920                 B_AX_WDE_EMPTY_QUE_CMAC0_WMM1 | B_AX_WDE_EMPTY_QUE_OTHERS |
1921                 B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX | B_AX_PLE_EMPTY_QTA_DMAC_H2C |
1922                 B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX | B_AX_WDE_EMPTY_QUE_DMAC_PKTIN |
1923                 B_AX_WDE_EMPTY_QTA_DMAC_HIF | B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU |
1924                 B_AX_WDE_EMPTY_QTA_DMAC_PKTIN | B_AX_WDE_EMPTY_QTA_DMAC_CPUIO |
1925                 B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL |
1926                 B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL |
1927                 B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX |
1928                 B_AX_PLE_EMPTY_QTA_DMAC_CPUIO |
1929                 B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU |
1930                 B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU;
1931         val32 = rtw89_read32(rtwdev, R_AX_DLE_EMPTY0);
1932
1933         if ((val32 & msk32) == msk32)
1934                 return true;
1935
1936         return false;
1937 }
1938
1939 static void _patch_ss2f_path(struct rtw89_dev *rtwdev)
1940 {
1941         const struct rtw89_chip_info *chip = rtwdev->chip;
1942
1943         if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
1944             chip->chip_id == RTL8851B)
1945                 return;
1946
1947         rtw89_write32_mask(rtwdev, R_AX_SS2FINFO_PATH, B_AX_SS_DEST_QUEUE_MASK,
1948                            SS2F_PATH_WLCPU);
1949 }
1950
1951 static int sta_sch_init(struct rtw89_dev *rtwdev)
1952 {
1953         u32 p_val;
1954         u8 val;
1955         int ret;
1956
1957         ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
1958         if (ret)
1959                 return ret;
1960
1961         val = rtw89_read8(rtwdev, R_AX_SS_CTRL);
1962         val |= B_AX_SS_EN;
1963         rtw89_write8(rtwdev, R_AX_SS_CTRL, val);
1964
1965         ret = read_poll_timeout(rtw89_read32, p_val, p_val & B_AX_SS_INIT_DONE_1,
1966                                 1, TRXCFG_WAIT_CNT, false, rtwdev, R_AX_SS_CTRL);
1967         if (ret) {
1968                 rtw89_err(rtwdev, "[ERR]STA scheduler init\n");
1969                 return ret;
1970         }
1971
1972         rtw89_write32_set(rtwdev, R_AX_SS_CTRL, B_AX_SS_WARM_INIT_FLG);
1973         rtw89_write32_clr(rtwdev, R_AX_SS_CTRL, B_AX_SS_NONEMPTY_SS2FINFO_EN);
1974
1975         _patch_ss2f_path(rtwdev);
1976
1977         return 0;
1978 }
1979
1980 static int mpdu_proc_init(struct rtw89_dev *rtwdev)
1981 {
1982         int ret;
1983
1984         ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
1985         if (ret)
1986                 return ret;
1987
1988         rtw89_write32(rtwdev, R_AX_ACTION_FWD0, TRXCFG_MPDU_PROC_ACT_FRWD);
1989         rtw89_write32(rtwdev, R_AX_TF_FWD, TRXCFG_MPDU_PROC_TF_FRWD);
1990         rtw89_write32_set(rtwdev, R_AX_MPDU_PROC,
1991                           B_AX_APPEND_FCS | B_AX_A_ICV_ERR);
1992         rtw89_write32(rtwdev, R_AX_CUT_AMSDU_CTRL, TRXCFG_MPDU_PROC_CUT_CTRL);
1993
1994         return 0;
1995 }
1996
1997 static int sec_eng_init(struct rtw89_dev *rtwdev)
1998 {
1999         const struct rtw89_chip_info *chip = rtwdev->chip;
2000         u32 val = 0;
2001         int ret;
2002
2003         ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
2004         if (ret)
2005                 return ret;
2006
2007         val = rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL);
2008         /* init clock */
2009         val |= (B_AX_CLK_EN_CGCMP | B_AX_CLK_EN_WAPI | B_AX_CLK_EN_WEP_TKIP);
2010         /* init TX encryption */
2011         val |= (B_AX_SEC_TX_ENC | B_AX_SEC_RX_DEC);
2012         val |= (B_AX_MC_DEC | B_AX_BC_DEC);
2013         if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
2014             chip->chip_id == RTL8851B)
2015                 val &= ~B_AX_TX_PARTIAL_MODE;
2016         rtw89_write32(rtwdev, R_AX_SEC_ENG_CTRL, val);
2017
2018         /* init MIC ICV append */
2019         val = rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC);
2020         val |= (B_AX_APPEND_ICV | B_AX_APPEND_MIC);
2021
2022         /* option init */
2023         rtw89_write32(rtwdev, R_AX_SEC_MPDU_PROC, val);
2024
2025         if (chip->chip_id == RTL8852C)
2026                 rtw89_write32_mask(rtwdev, R_AX_SEC_DEBUG1,
2027                                    B_AX_TX_TIMEOUT_SEL_MASK, AX_TX_TO_VAL);
2028
2029         return 0;
2030 }
2031
2032 static int dmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2033 {
2034         int ret;
2035
2036         ret = dle_init(rtwdev, rtwdev->mac.qta_mode, RTW89_QTA_INVALID);
2037         if (ret) {
2038                 rtw89_err(rtwdev, "[ERR]DLE init %d\n", ret);
2039                 return ret;
2040         }
2041
2042         ret = preload_init(rtwdev, RTW89_MAC_0, rtwdev->mac.qta_mode);
2043         if (ret) {
2044                 rtw89_err(rtwdev, "[ERR]preload init %d\n", ret);
2045                 return ret;
2046         }
2047
2048         ret = hfc_init(rtwdev, true, true, true);
2049         if (ret) {
2050                 rtw89_err(rtwdev, "[ERR]HCI FC init %d\n", ret);
2051                 return ret;
2052         }
2053
2054         ret = sta_sch_init(rtwdev);
2055         if (ret) {
2056                 rtw89_err(rtwdev, "[ERR]STA SCH init %d\n", ret);
2057                 return ret;
2058         }
2059
2060         ret = mpdu_proc_init(rtwdev);
2061         if (ret) {
2062                 rtw89_err(rtwdev, "[ERR]MPDU Proc init %d\n", ret);
2063                 return ret;
2064         }
2065
2066         ret = sec_eng_init(rtwdev);
2067         if (ret) {
2068                 rtw89_err(rtwdev, "[ERR]Security Engine init %d\n", ret);
2069                 return ret;
2070         }
2071
2072         return ret;
2073 }
2074
2075 static int addr_cam_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2076 {
2077         u32 val, reg;
2078         u16 p_val;
2079         int ret;
2080
2081         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2082         if (ret)
2083                 return ret;
2084
2085         reg = rtw89_mac_reg_by_idx(R_AX_ADDR_CAM_CTRL, mac_idx);
2086
2087         val = rtw89_read32(rtwdev, reg);
2088         val |= u32_encode_bits(0x7f, B_AX_ADDR_CAM_RANGE_MASK) |
2089                B_AX_ADDR_CAM_CLR | B_AX_ADDR_CAM_EN;
2090         rtw89_write32(rtwdev, reg, val);
2091
2092         ret = read_poll_timeout(rtw89_read16, p_val, !(p_val & B_AX_ADDR_CAM_CLR),
2093                                 1, TRXCFG_WAIT_CNT, false, rtwdev, reg);
2094         if (ret) {
2095                 rtw89_err(rtwdev, "[ERR]ADDR_CAM reset\n");
2096                 return ret;
2097         }
2098
2099         return 0;
2100 }
2101
2102 static int scheduler_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2103 {
2104         u32 ret;
2105         u32 reg;
2106         u32 val;
2107
2108         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2109         if (ret)
2110                 return ret;
2111
2112         reg = rtw89_mac_reg_by_idx(R_AX_PREBKF_CFG_1, mac_idx);
2113         if (rtwdev->chip->chip_id == RTL8852C)
2114                 rtw89_write32_mask(rtwdev, reg, B_AX_SIFS_MACTXEN_T1_MASK,
2115                                    SIFS_MACTXEN_T1_V1);
2116         else
2117                 rtw89_write32_mask(rtwdev, reg, B_AX_SIFS_MACTXEN_T1_MASK,
2118                                    SIFS_MACTXEN_T1);
2119
2120         if (rtwdev->chip->chip_id == RTL8852B || rtwdev->chip->chip_id == RTL8851B) {
2121                 reg = rtw89_mac_reg_by_idx(R_AX_SCH_EXT_CTRL, mac_idx);
2122                 rtw89_write32_set(rtwdev, reg, B_AX_PORT_RST_TSF_ADV);
2123         }
2124
2125         reg = rtw89_mac_reg_by_idx(R_AX_CCA_CFG_0, mac_idx);
2126         rtw89_write32_clr(rtwdev, reg, B_AX_BTCCA_EN);
2127
2128         reg = rtw89_mac_reg_by_idx(R_AX_PREBKF_CFG_0, mac_idx);
2129         if (rtwdev->chip->chip_id == RTL8852C) {
2130                 val = rtw89_read32_mask(rtwdev, R_AX_SEC_ENG_CTRL,
2131                                         B_AX_TX_PARTIAL_MODE);
2132                 if (!val)
2133                         rtw89_write32_mask(rtwdev, reg, B_AX_PREBKF_TIME_MASK,
2134                                            SCH_PREBKF_24US);
2135         } else {
2136                 rtw89_write32_mask(rtwdev, reg, B_AX_PREBKF_TIME_MASK,
2137                                    SCH_PREBKF_24US);
2138         }
2139
2140         return 0;
2141 }
2142
2143 int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev,
2144                            enum rtw89_machdr_frame_type type,
2145                            enum rtw89_mac_fwd_target fwd_target,
2146                            u8 mac_idx)
2147 {
2148         u32 reg;
2149         u32 val;
2150
2151         switch (fwd_target) {
2152         case RTW89_FWD_DONT_CARE:
2153                 val = RX_FLTR_FRAME_DROP;
2154                 break;
2155         case RTW89_FWD_TO_HOST:
2156                 val = RX_FLTR_FRAME_TO_HOST;
2157                 break;
2158         case RTW89_FWD_TO_WLAN_CPU:
2159                 val = RX_FLTR_FRAME_TO_WLCPU;
2160                 break;
2161         default:
2162                 rtw89_err(rtwdev, "[ERR]set rx filter fwd target err\n");
2163                 return -EINVAL;
2164         }
2165
2166         switch (type) {
2167         case RTW89_MGNT:
2168                 reg = rtw89_mac_reg_by_idx(R_AX_MGNT_FLTR, mac_idx);
2169                 break;
2170         case RTW89_CTRL:
2171                 reg = rtw89_mac_reg_by_idx(R_AX_CTRL_FLTR, mac_idx);
2172                 break;
2173         case RTW89_DATA:
2174                 reg = rtw89_mac_reg_by_idx(R_AX_DATA_FLTR, mac_idx);
2175                 break;
2176         default:
2177                 rtw89_err(rtwdev, "[ERR]set rx filter type err\n");
2178                 return -EINVAL;
2179         }
2180         rtw89_write32(rtwdev, reg, val);
2181
2182         return 0;
2183 }
2184
2185 static int rx_fltr_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2186 {
2187         int ret, i;
2188         u32 mac_ftlr, plcp_ftlr;
2189
2190         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2191         if (ret)
2192                 return ret;
2193
2194         for (i = RTW89_MGNT; i <= RTW89_DATA; i++) {
2195                 ret = rtw89_mac_typ_fltr_opt(rtwdev, i, RTW89_FWD_TO_HOST,
2196                                              mac_idx);
2197                 if (ret)
2198                         return ret;
2199         }
2200         mac_ftlr = rtwdev->hal.rx_fltr;
2201         plcp_ftlr = B_AX_CCK_CRC_CHK | B_AX_CCK_SIG_CHK |
2202                     B_AX_LSIG_PARITY_CHK_EN | B_AX_SIGA_CRC_CHK |
2203                     B_AX_VHT_SU_SIGB_CRC_CHK | B_AX_VHT_MU_SIGB_CRC_CHK |
2204                     B_AX_HE_SIGB_CRC_CHK;
2205         rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, mac_idx),
2206                       mac_ftlr);
2207         rtw89_write16(rtwdev, rtw89_mac_reg_by_idx(R_AX_PLCP_HDR_FLTR, mac_idx),
2208                       plcp_ftlr);
2209
2210         return 0;
2211 }
2212
2213 static void _patch_dis_resp_chk(struct rtw89_dev *rtwdev, u8 mac_idx)
2214 {
2215         u32 reg, val32;
2216         u32 b_rsp_chk_nav, b_rsp_chk_cca;
2217
2218         b_rsp_chk_nav = B_AX_RSP_CHK_TXNAV | B_AX_RSP_CHK_INTRA_NAV |
2219                         B_AX_RSP_CHK_BASIC_NAV;
2220         b_rsp_chk_cca = B_AX_RSP_CHK_SEC_CCA_80 | B_AX_RSP_CHK_SEC_CCA_40 |
2221                         B_AX_RSP_CHK_SEC_CCA_20 | B_AX_RSP_CHK_BTCCA |
2222                         B_AX_RSP_CHK_EDCCA | B_AX_RSP_CHK_CCA;
2223
2224         switch (rtwdev->chip->chip_id) {
2225         case RTL8852A:
2226         case RTL8852B:
2227                 reg = rtw89_mac_reg_by_idx(R_AX_RSP_CHK_SIG, mac_idx);
2228                 val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_nav;
2229                 rtw89_write32(rtwdev, reg, val32);
2230
2231                 reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx);
2232                 val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_cca;
2233                 rtw89_write32(rtwdev, reg, val32);
2234                 break;
2235         default:
2236                 reg = rtw89_mac_reg_by_idx(R_AX_RSP_CHK_SIG, mac_idx);
2237                 val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_nav;
2238                 rtw89_write32(rtwdev, reg, val32);
2239
2240                 reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx);
2241                 val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_cca;
2242                 rtw89_write32(rtwdev, reg, val32);
2243                 break;
2244         }
2245 }
2246
2247 static int cca_ctrl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2248 {
2249         u32 val, reg;
2250         int ret;
2251
2252         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2253         if (ret)
2254                 return ret;
2255
2256         reg = rtw89_mac_reg_by_idx(R_AX_CCA_CONTROL, mac_idx);
2257         val = rtw89_read32(rtwdev, reg);
2258         val |= (B_AX_TB_CHK_BASIC_NAV | B_AX_TB_CHK_BTCCA |
2259                 B_AX_TB_CHK_EDCCA | B_AX_TB_CHK_CCA_P20 |
2260                 B_AX_SIFS_CHK_BTCCA | B_AX_SIFS_CHK_CCA_P20 |
2261                 B_AX_CTN_CHK_INTRA_NAV |
2262                 B_AX_CTN_CHK_BASIC_NAV | B_AX_CTN_CHK_BTCCA |
2263                 B_AX_CTN_CHK_EDCCA | B_AX_CTN_CHK_CCA_S80 |
2264                 B_AX_CTN_CHK_CCA_S40 | B_AX_CTN_CHK_CCA_S20 |
2265                 B_AX_CTN_CHK_CCA_P20);
2266         val &= ~(B_AX_TB_CHK_TX_NAV | B_AX_TB_CHK_CCA_S80 |
2267                  B_AX_TB_CHK_CCA_S40 | B_AX_TB_CHK_CCA_S20 |
2268                  B_AX_SIFS_CHK_CCA_S80 | B_AX_SIFS_CHK_CCA_S40 |
2269                  B_AX_SIFS_CHK_CCA_S20 | B_AX_CTN_CHK_TXNAV |
2270                  B_AX_SIFS_CHK_EDCCA);
2271
2272         rtw89_write32(rtwdev, reg, val);
2273
2274         _patch_dis_resp_chk(rtwdev, mac_idx);
2275
2276         return 0;
2277 }
2278
2279 static int nav_ctrl_init(struct rtw89_dev *rtwdev)
2280 {
2281         rtw89_write32_set(rtwdev, R_AX_WMAC_NAV_CTL, B_AX_WMAC_PLCP_UP_NAV_EN |
2282                                                      B_AX_WMAC_TF_UP_NAV_EN |
2283                                                      B_AX_WMAC_NAV_UPPER_EN);
2284         rtw89_write32_mask(rtwdev, R_AX_WMAC_NAV_CTL, B_AX_WMAC_NAV_UPPER_MASK, NAV_25MS);
2285
2286         return 0;
2287 }
2288
2289 static int spatial_reuse_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2290 {
2291         u32 reg;
2292         int ret;
2293
2294         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2295         if (ret)
2296                 return ret;
2297         reg = rtw89_mac_reg_by_idx(R_AX_RX_SR_CTRL, mac_idx);
2298         rtw89_write8_clr(rtwdev, reg, B_AX_SR_EN);
2299
2300         return 0;
2301 }
2302
2303 static int tmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2304 {
2305         u32 reg;
2306         int ret;
2307
2308         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2309         if (ret)
2310                 return ret;
2311
2312         reg = rtw89_mac_reg_by_idx(R_AX_MAC_LOOPBACK, mac_idx);
2313         rtw89_write32_clr(rtwdev, reg, B_AX_MACLBK_EN);
2314
2315         reg = rtw89_mac_reg_by_idx(R_AX_TCR0, mac_idx);
2316         rtw89_write32_mask(rtwdev, reg, B_AX_TCR_UDF_THSD_MASK, TCR_UDF_THSD);
2317
2318         reg = rtw89_mac_reg_by_idx(R_AX_TXD_FIFO_CTRL, mac_idx);
2319         rtw89_write32_mask(rtwdev, reg, B_AX_TXDFIFO_HIGH_MCS_THRE_MASK, TXDFIFO_HIGH_MCS_THRE);
2320         rtw89_write32_mask(rtwdev, reg, B_AX_TXDFIFO_LOW_MCS_THRE_MASK, TXDFIFO_LOW_MCS_THRE);
2321
2322         return 0;
2323 }
2324
2325 static int trxptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2326 {
2327         const struct rtw89_chip_info *chip = rtwdev->chip;
2328         const struct rtw89_rrsr_cfgs *rrsr = chip->rrsr_cfgs;
2329         u32 reg, val, sifs;
2330         int ret;
2331
2332         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2333         if (ret)
2334                 return ret;
2335
2336         reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_0, mac_idx);
2337         val = rtw89_read32(rtwdev, reg);
2338         val &= ~B_AX_WMAC_SPEC_SIFS_CCK_MASK;
2339         val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_CCK_MASK, WMAC_SPEC_SIFS_CCK);
2340
2341         switch (rtwdev->chip->chip_id) {
2342         case RTL8852A:
2343                 sifs = WMAC_SPEC_SIFS_OFDM_52A;
2344                 break;
2345         case RTL8852B:
2346                 sifs = WMAC_SPEC_SIFS_OFDM_52B;
2347                 break;
2348         default:
2349                 sifs = WMAC_SPEC_SIFS_OFDM_52C;
2350                 break;
2351         }
2352         val &= ~B_AX_WMAC_SPEC_SIFS_OFDM_MASK;
2353         val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_OFDM_MASK, sifs);
2354         rtw89_write32(rtwdev, reg, val);
2355
2356         reg = rtw89_mac_reg_by_idx(R_AX_RXTRIG_TEST_USER_2, mac_idx);
2357         rtw89_write32_set(rtwdev, reg, B_AX_RXTRIG_FCSCHK_EN);
2358
2359         reg = rtw89_mac_reg_by_idx(rrsr->ref_rate.addr, mac_idx);
2360         rtw89_write32_mask(rtwdev, reg, rrsr->ref_rate.mask, rrsr->ref_rate.data);
2361         reg = rtw89_mac_reg_by_idx(rrsr->rsc.addr, mac_idx);
2362         rtw89_write32_mask(rtwdev, reg, rrsr->rsc.mask, rrsr->rsc.data);
2363
2364         return 0;
2365 }
2366
2367 static void rst_bacam(struct rtw89_dev *rtwdev)
2368 {
2369         u32 val32;
2370         int ret;
2371
2372         rtw89_write32_mask(rtwdev, R_AX_RESPBA_CAM_CTRL, B_AX_BACAM_RST_MASK,
2373                            S_AX_BACAM_RST_ALL);
2374
2375         ret = read_poll_timeout_atomic(rtw89_read32_mask, val32, val32 == 0,
2376                                        1, 1000, false,
2377                                        rtwdev, R_AX_RESPBA_CAM_CTRL, B_AX_BACAM_RST_MASK);
2378         if (ret)
2379                 rtw89_warn(rtwdev, "failed to reset BA CAM\n");
2380 }
2381
2382 static int rmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2383 {
2384 #define TRXCFG_RMAC_CCA_TO      32
2385 #define TRXCFG_RMAC_DATA_TO     15
2386 #define RX_MAX_LEN_UNIT 512
2387 #define PLD_RLS_MAX_PG 127
2388 #define RX_SPEC_MAX_LEN (11454 + RX_MAX_LEN_UNIT)
2389         int ret;
2390         u32 reg, rx_max_len, rx_qta;
2391         u16 val;
2392
2393         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2394         if (ret)
2395                 return ret;
2396
2397         if (mac_idx == RTW89_MAC_0)
2398                 rst_bacam(rtwdev);
2399
2400         reg = rtw89_mac_reg_by_idx(R_AX_RESPBA_CAM_CTRL, mac_idx);
2401         rtw89_write8_set(rtwdev, reg, B_AX_SSN_SEL);
2402
2403         reg = rtw89_mac_reg_by_idx(R_AX_DLK_PROTECT_CTL, mac_idx);
2404         val = rtw89_read16(rtwdev, reg);
2405         val = u16_replace_bits(val, TRXCFG_RMAC_DATA_TO,
2406                                B_AX_RX_DLK_DATA_TIME_MASK);
2407         val = u16_replace_bits(val, TRXCFG_RMAC_CCA_TO,
2408                                B_AX_RX_DLK_CCA_TIME_MASK);
2409         rtw89_write16(rtwdev, reg, val);
2410
2411         reg = rtw89_mac_reg_by_idx(R_AX_RCR, mac_idx);
2412         rtw89_write8_mask(rtwdev, reg, B_AX_CH_EN_MASK, 0x1);
2413
2414         reg = rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, mac_idx);
2415         if (mac_idx == RTW89_MAC_0)
2416                 rx_qta = rtwdev->mac.dle_info.c0_rx_qta;
2417         else
2418                 rx_qta = rtwdev->mac.dle_info.c1_rx_qta;
2419         rx_qta = min_t(u32, rx_qta, PLD_RLS_MAX_PG);
2420         rx_max_len = rx_qta * rtwdev->mac.dle_info.ple_pg_size;
2421         rx_max_len = min_t(u32, rx_max_len, RX_SPEC_MAX_LEN);
2422         rx_max_len /= RX_MAX_LEN_UNIT;
2423         rtw89_write32_mask(rtwdev, reg, B_AX_RX_MPDU_MAX_LEN_MASK, rx_max_len);
2424
2425         if (rtwdev->chip->chip_id == RTL8852A &&
2426             rtwdev->hal.cv == CHIP_CBV) {
2427                 rtw89_write16_mask(rtwdev,
2428                                    rtw89_mac_reg_by_idx(R_AX_DLK_PROTECT_CTL, mac_idx),
2429                                    B_AX_RX_DLK_CCA_TIME_MASK, 0);
2430                 rtw89_write16_set(rtwdev, rtw89_mac_reg_by_idx(R_AX_RCR, mac_idx),
2431                                   BIT(12));
2432         }
2433
2434         reg = rtw89_mac_reg_by_idx(R_AX_PLCP_HDR_FLTR, mac_idx);
2435         rtw89_write8_clr(rtwdev, reg, B_AX_VHT_SU_SIGB_CRC_CHK);
2436
2437         return ret;
2438 }
2439
2440 static int cmac_com_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2441 {
2442         enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
2443         u32 val, reg;
2444         int ret;
2445
2446         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2447         if (ret)
2448                 return ret;
2449
2450         reg = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
2451         val = rtw89_read32(rtwdev, reg);
2452         val = u32_replace_bits(val, 0, B_AX_TXSC_20M_MASK);
2453         val = u32_replace_bits(val, 0, B_AX_TXSC_40M_MASK);
2454         val = u32_replace_bits(val, 0, B_AX_TXSC_80M_MASK);
2455         rtw89_write32(rtwdev, reg, val);
2456
2457         if (chip_id == RTL8852A || chip_id == RTL8852B) {
2458                 reg = rtw89_mac_reg_by_idx(R_AX_PTCL_RRSR1, mac_idx);
2459                 rtw89_write32_mask(rtwdev, reg, B_AX_RRSR_RATE_EN_MASK, RRSR_OFDM_CCK_EN);
2460         }
2461
2462         return 0;
2463 }
2464
2465 static bool is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
2466 {
2467         const struct rtw89_dle_mem *cfg;
2468
2469         cfg = get_dle_mem_cfg(rtwdev, mode);
2470         if (!cfg) {
2471                 rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n");
2472                 return false;
2473         }
2474
2475         return (cfg->ple_min_qt->cma1_dma && cfg->ple_max_qt->cma1_dma);
2476 }
2477
2478 static int ptcl_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2479 {
2480         u32 val, reg;
2481         int ret;
2482
2483         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2484         if (ret)
2485                 return ret;
2486
2487         if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) {
2488                 reg = rtw89_mac_reg_by_idx(R_AX_SIFS_SETTING, mac_idx);
2489                 val = rtw89_read32(rtwdev, reg);
2490                 val = u32_replace_bits(val, S_AX_CTS2S_TH_1K,
2491                                        B_AX_HW_CTS2SELF_PKT_LEN_TH_MASK);
2492                 val = u32_replace_bits(val, S_AX_CTS2S_TH_SEC_256B,
2493                                        B_AX_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK);
2494                 val |= B_AX_HW_CTS2SELF_EN;
2495                 rtw89_write32(rtwdev, reg, val);
2496
2497                 reg = rtw89_mac_reg_by_idx(R_AX_PTCL_FSM_MON, mac_idx);
2498                 val = rtw89_read32(rtwdev, reg);
2499                 val = u32_replace_bits(val, S_AX_PTCL_TO_2MS, B_AX_PTCL_TX_ARB_TO_THR_MASK);
2500                 val &= ~B_AX_PTCL_TX_ARB_TO_MODE;
2501                 rtw89_write32(rtwdev, reg, val);
2502         }
2503
2504         if (mac_idx == RTW89_MAC_0) {
2505                 rtw89_write8_set(rtwdev, R_AX_PTCL_COMMON_SETTING_0,
2506                                  B_AX_CMAC_TX_MODE_0 | B_AX_CMAC_TX_MODE_1);
2507                 rtw89_write8_clr(rtwdev, R_AX_PTCL_COMMON_SETTING_0,
2508                                  B_AX_PTCL_TRIGGER_SS_EN_0 |
2509                                  B_AX_PTCL_TRIGGER_SS_EN_1 |
2510                                  B_AX_PTCL_TRIGGER_SS_EN_UL);
2511                 rtw89_write8_mask(rtwdev, R_AX_PTCLRPT_FULL_HDL,
2512                                   B_AX_SPE_RPT_PATH_MASK, FWD_TO_WLCPU);
2513         } else if (mac_idx == RTW89_MAC_1) {
2514                 rtw89_write8_mask(rtwdev, R_AX_PTCLRPT_FULL_HDL_C1,
2515                                   B_AX_SPE_RPT_PATH_MASK, FWD_TO_WLCPU);
2516         }
2517
2518         return 0;
2519 }
2520
2521 static int cmac_dma_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2522 {
2523         enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
2524         u32 reg;
2525         int ret;
2526
2527         if (chip_id != RTL8852B)
2528                 return 0;
2529
2530         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2531         if (ret)
2532                 return ret;
2533
2534         reg = rtw89_mac_reg_by_idx(R_AX_RXDMA_CTRL_0, mac_idx);
2535         rtw89_write8_clr(rtwdev, reg, RX_FULL_MODE);
2536
2537         return 0;
2538 }
2539
2540 static int cmac_init(struct rtw89_dev *rtwdev, u8 mac_idx)
2541 {
2542         int ret;
2543
2544         ret = scheduler_init(rtwdev, mac_idx);
2545         if (ret) {
2546                 rtw89_err(rtwdev, "[ERR]CMAC%d SCH init %d\n", mac_idx, ret);
2547                 return ret;
2548         }
2549
2550         ret = addr_cam_init(rtwdev, mac_idx);
2551         if (ret) {
2552                 rtw89_err(rtwdev, "[ERR]CMAC%d ADDR_CAM reset %d\n", mac_idx,
2553                           ret);
2554                 return ret;
2555         }
2556
2557         ret = rx_fltr_init(rtwdev, mac_idx);
2558         if (ret) {
2559                 rtw89_err(rtwdev, "[ERR]CMAC%d RX filter init %d\n", mac_idx,
2560                           ret);
2561                 return ret;
2562         }
2563
2564         ret = cca_ctrl_init(rtwdev, mac_idx);
2565         if (ret) {
2566                 rtw89_err(rtwdev, "[ERR]CMAC%d CCA CTRL init %d\n", mac_idx,
2567                           ret);
2568                 return ret;
2569         }
2570
2571         ret = nav_ctrl_init(rtwdev);
2572         if (ret) {
2573                 rtw89_err(rtwdev, "[ERR]CMAC%d NAV CTRL init %d\n", mac_idx,
2574                           ret);
2575                 return ret;
2576         }
2577
2578         ret = spatial_reuse_init(rtwdev, mac_idx);
2579         if (ret) {
2580                 rtw89_err(rtwdev, "[ERR]CMAC%d Spatial Reuse init %d\n",
2581                           mac_idx, ret);
2582                 return ret;
2583         }
2584
2585         ret = tmac_init(rtwdev, mac_idx);
2586         if (ret) {
2587                 rtw89_err(rtwdev, "[ERR]CMAC%d TMAC init %d\n", mac_idx, ret);
2588                 return ret;
2589         }
2590
2591         ret = trxptcl_init(rtwdev, mac_idx);
2592         if (ret) {
2593                 rtw89_err(rtwdev, "[ERR]CMAC%d TRXPTCL init %d\n", mac_idx, ret);
2594                 return ret;
2595         }
2596
2597         ret = rmac_init(rtwdev, mac_idx);
2598         if (ret) {
2599                 rtw89_err(rtwdev, "[ERR]CMAC%d RMAC init %d\n", mac_idx, ret);
2600                 return ret;
2601         }
2602
2603         ret = cmac_com_init(rtwdev, mac_idx);
2604         if (ret) {
2605                 rtw89_err(rtwdev, "[ERR]CMAC%d Com init %d\n", mac_idx, ret);
2606                 return ret;
2607         }
2608
2609         ret = ptcl_init(rtwdev, mac_idx);
2610         if (ret) {
2611                 rtw89_err(rtwdev, "[ERR]CMAC%d PTCL init %d\n", mac_idx, ret);
2612                 return ret;
2613         }
2614
2615         ret = cmac_dma_init(rtwdev, mac_idx);
2616         if (ret) {
2617                 rtw89_err(rtwdev, "[ERR]CMAC%d DMA init %d\n", mac_idx, ret);
2618                 return ret;
2619         }
2620
2621         return ret;
2622 }
2623
2624 static int rtw89_mac_read_phycap(struct rtw89_dev *rtwdev,
2625                                  struct rtw89_mac_c2h_info *c2h_info)
2626 {
2627         struct rtw89_mac_h2c_info h2c_info = {0};
2628         u32 ret;
2629
2630         h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE;
2631         h2c_info.content_len = 0;
2632
2633         ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, c2h_info);
2634         if (ret)
2635                 return ret;
2636
2637         if (c2h_info->id != RTW89_FWCMD_C2HREG_FUNC_PHY_CAP)
2638                 return -EINVAL;
2639
2640         return 0;
2641 }
2642
2643 int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev)
2644 {
2645         struct rtw89_efuse *efuse = &rtwdev->efuse;
2646         struct rtw89_hal *hal = &rtwdev->hal;
2647         const struct rtw89_chip_info *chip = rtwdev->chip;
2648         struct rtw89_mac_c2h_info c2h_info = {0};
2649         const struct rtw89_c2hreg_phycap *phycap;
2650         u8 tx_nss;
2651         u8 rx_nss;
2652         u8 tx_ant;
2653         u8 rx_ant;
2654         u32 ret;
2655
2656         ret = rtw89_mac_read_phycap(rtwdev, &c2h_info);
2657         if (ret)
2658                 return ret;
2659
2660         phycap = &c2h_info.u.phycap;
2661
2662         tx_nss = u32_get_bits(phycap->w1, RTW89_C2HREG_PHYCAP_W1_TX_NSS);
2663         rx_nss = u32_get_bits(phycap->w0, RTW89_C2HREG_PHYCAP_W0_RX_NSS);
2664         tx_ant = u32_get_bits(phycap->w3, RTW89_C2HREG_PHYCAP_W3_ANT_TX_NUM);
2665         rx_ant = u32_get_bits(phycap->w3, RTW89_C2HREG_PHYCAP_W3_ANT_RX_NUM);
2666
2667         hal->tx_nss = tx_nss ? min_t(u8, tx_nss, chip->tx_nss) : chip->tx_nss;
2668         hal->rx_nss = rx_nss ? min_t(u8, rx_nss, chip->rx_nss) : chip->rx_nss;
2669
2670         if (tx_ant == 1)
2671                 hal->antenna_tx = RF_B;
2672         if (rx_ant == 1)
2673                 hal->antenna_rx = RF_B;
2674
2675         if (tx_nss == 1 && tx_ant == 2 && rx_ant == 2) {
2676                 hal->antenna_tx = RF_B;
2677                 hal->tx_path_diversity = true;
2678         }
2679
2680         if (chip->rf_path_num == 1) {
2681                 hal->antenna_tx = RF_A;
2682                 hal->antenna_rx = RF_A;
2683                 if ((efuse->rfe_type % 3) == 2)
2684                         hal->ant_diversity = true;
2685         }
2686
2687         rtw89_debug(rtwdev, RTW89_DBG_FW,
2688                     "phycap hal/phy/chip: tx_nss=0x%x/0x%x/0x%x rx_nss=0x%x/0x%x/0x%x\n",
2689                     hal->tx_nss, tx_nss, chip->tx_nss,
2690                     hal->rx_nss, rx_nss, chip->rx_nss);
2691         rtw89_debug(rtwdev, RTW89_DBG_FW,
2692                     "ant num/bitmap: tx=%d/0x%x rx=%d/0x%x\n",
2693                     tx_ant, hal->antenna_tx, rx_ant, hal->antenna_rx);
2694         rtw89_debug(rtwdev, RTW89_DBG_FW, "TX path diversity=%d\n", hal->tx_path_diversity);
2695         rtw89_debug(rtwdev, RTW89_DBG_FW, "Antenna diversity=%d\n", hal->ant_diversity);
2696
2697         return 0;
2698 }
2699
2700 static int rtw89_hw_sch_tx_en_h2c(struct rtw89_dev *rtwdev, u8 band,
2701                                   u16 tx_en_u16, u16 mask_u16)
2702 {
2703         u32 ret;
2704         struct rtw89_mac_c2h_info c2h_info = {0};
2705         struct rtw89_mac_h2c_info h2c_info = {0};
2706         struct rtw89_h2creg_sch_tx_en *sch_tx_en = &h2c_info.u.sch_tx_en;
2707
2708         h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN;
2709         h2c_info.content_len = sizeof(*sch_tx_en) - RTW89_H2CREG_HDR_LEN;
2710
2711         u32p_replace_bits(&sch_tx_en->w0, tx_en_u16, RTW89_H2CREG_SCH_TX_EN_W0_EN);
2712         u32p_replace_bits(&sch_tx_en->w1, mask_u16, RTW89_H2CREG_SCH_TX_EN_W1_MASK);
2713         u32p_replace_bits(&sch_tx_en->w1, band, RTW89_H2CREG_SCH_TX_EN_W1_BAND);
2714
2715         ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info);
2716         if (ret)
2717                 return ret;
2718
2719         if (c2h_info.id != RTW89_FWCMD_C2HREG_FUNC_TX_PAUSE_RPT)
2720                 return -EINVAL;
2721
2722         return 0;
2723 }
2724
2725 static int rtw89_set_hw_sch_tx_en(struct rtw89_dev *rtwdev, u8 mac_idx,
2726                                   u16 tx_en, u16 tx_en_mask)
2727 {
2728         u32 reg = rtw89_mac_reg_by_idx(R_AX_CTN_TXEN, mac_idx);
2729         u16 val;
2730         int ret;
2731
2732         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2733         if (ret)
2734                 return ret;
2735
2736         if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags))
2737                 return rtw89_hw_sch_tx_en_h2c(rtwdev, mac_idx,
2738                                               tx_en, tx_en_mask);
2739
2740         val = rtw89_read16(rtwdev, reg);
2741         val = (val & ~tx_en_mask) | (tx_en & tx_en_mask);
2742         rtw89_write16(rtwdev, reg, val);
2743
2744         return 0;
2745 }
2746
2747 static int rtw89_set_hw_sch_tx_en_v1(struct rtw89_dev *rtwdev, u8 mac_idx,
2748                                      u32 tx_en, u32 tx_en_mask)
2749 {
2750         u32 reg = rtw89_mac_reg_by_idx(R_AX_CTN_DRV_TXEN, mac_idx);
2751         u32 val;
2752         int ret;
2753
2754         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2755         if (ret)
2756                 return ret;
2757
2758         val = rtw89_read32(rtwdev, reg);
2759         val = (val & ~tx_en_mask) | (tx_en & tx_en_mask);
2760         rtw89_write32(rtwdev, reg, val);
2761
2762         return 0;
2763 }
2764
2765 int rtw89_mac_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx,
2766                           u32 *tx_en, enum rtw89_sch_tx_sel sel)
2767 {
2768         int ret;
2769
2770         *tx_en = rtw89_read16(rtwdev,
2771                               rtw89_mac_reg_by_idx(R_AX_CTN_TXEN, mac_idx));
2772
2773         switch (sel) {
2774         case RTW89_SCH_TX_SEL_ALL:
2775                 ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, 0,
2776                                              B_AX_CTN_TXEN_ALL_MASK);
2777                 if (ret)
2778                         return ret;
2779                 break;
2780         case RTW89_SCH_TX_SEL_HIQ:
2781                 ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx,
2782                                              0, B_AX_CTN_TXEN_HGQ);
2783                 if (ret)
2784                         return ret;
2785                 break;
2786         case RTW89_SCH_TX_SEL_MG0:
2787                 ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx,
2788                                              0, B_AX_CTN_TXEN_MGQ);
2789                 if (ret)
2790                         return ret;
2791                 break;
2792         case RTW89_SCH_TX_SEL_MACID:
2793                 ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, 0,
2794                                              B_AX_CTN_TXEN_ALL_MASK);
2795                 if (ret)
2796                         return ret;
2797                 break;
2798         default:
2799                 return 0;
2800         }
2801
2802         return 0;
2803 }
2804 EXPORT_SYMBOL(rtw89_mac_stop_sch_tx);
2805
2806 int rtw89_mac_stop_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx,
2807                              u32 *tx_en, enum rtw89_sch_tx_sel sel)
2808 {
2809         int ret;
2810
2811         *tx_en = rtw89_read32(rtwdev,
2812                               rtw89_mac_reg_by_idx(R_AX_CTN_DRV_TXEN, mac_idx));
2813
2814         switch (sel) {
2815         case RTW89_SCH_TX_SEL_ALL:
2816                 ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, 0,
2817                                                 B_AX_CTN_TXEN_ALL_MASK_V1);
2818                 if (ret)
2819                         return ret;
2820                 break;
2821         case RTW89_SCH_TX_SEL_HIQ:
2822                 ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx,
2823                                                 0, B_AX_CTN_TXEN_HGQ);
2824                 if (ret)
2825                         return ret;
2826                 break;
2827         case RTW89_SCH_TX_SEL_MG0:
2828                 ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx,
2829                                                 0, B_AX_CTN_TXEN_MGQ);
2830                 if (ret)
2831                         return ret;
2832                 break;
2833         case RTW89_SCH_TX_SEL_MACID:
2834                 ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, 0,
2835                                                 B_AX_CTN_TXEN_ALL_MASK_V1);
2836                 if (ret)
2837                         return ret;
2838                 break;
2839         default:
2840                 return 0;
2841         }
2842
2843         return 0;
2844 }
2845 EXPORT_SYMBOL(rtw89_mac_stop_sch_tx_v1);
2846
2847 int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en)
2848 {
2849         int ret;
2850
2851         ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, tx_en, B_AX_CTN_TXEN_ALL_MASK);
2852         if (ret)
2853                 return ret;
2854
2855         return 0;
2856 }
2857 EXPORT_SYMBOL(rtw89_mac_resume_sch_tx);
2858
2859 int rtw89_mac_resume_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en)
2860 {
2861         int ret;
2862
2863         ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, tx_en,
2864                                         B_AX_CTN_TXEN_ALL_MASK_V1);
2865         if (ret)
2866                 return ret;
2867
2868         return 0;
2869 }
2870 EXPORT_SYMBOL(rtw89_mac_resume_sch_tx_v1);
2871
2872 int rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id)
2873 {
2874         u32 val, reg;
2875         int ret;
2876
2877         reg = wd ? R_AX_WD_BUF_REQ : R_AX_PL_BUF_REQ;
2878         val = buf_len;
2879         val |= B_AX_WD_BUF_REQ_EXEC;
2880         rtw89_write32(rtwdev, reg, val);
2881
2882         reg = wd ? R_AX_WD_BUF_STATUS : R_AX_PL_BUF_STATUS;
2883
2884         ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_BUF_STAT_DONE,
2885                                 1, 2000, false, rtwdev, reg);
2886         if (ret)
2887                 return ret;
2888
2889         *pkt_id = FIELD_GET(B_AX_WD_BUF_STAT_PKTID_MASK, val);
2890         if (*pkt_id == S_WD_BUF_STAT_PKTID_INVALID)
2891                 return -ENOENT;
2892
2893         return 0;
2894 }
2895
2896 int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev,
2897                         struct rtw89_cpuio_ctrl *ctrl_para, bool wd)
2898 {
2899         u32 val, cmd_type, reg;
2900         int ret;
2901
2902         cmd_type = ctrl_para->cmd_type;
2903
2904         reg = wd ? R_AX_WD_CPUQ_OP_2 : R_AX_PL_CPUQ_OP_2;
2905         val = 0;
2906         val = u32_replace_bits(val, ctrl_para->start_pktid,
2907                                B_AX_WD_CPUQ_OP_STRT_PKTID_MASK);
2908         val = u32_replace_bits(val, ctrl_para->end_pktid,
2909                                B_AX_WD_CPUQ_OP_END_PKTID_MASK);
2910         rtw89_write32(rtwdev, reg, val);
2911
2912         reg = wd ? R_AX_WD_CPUQ_OP_1 : R_AX_PL_CPUQ_OP_1;
2913         val = 0;
2914         val = u32_replace_bits(val, ctrl_para->src_pid,
2915                                B_AX_CPUQ_OP_SRC_PID_MASK);
2916         val = u32_replace_bits(val, ctrl_para->src_qid,
2917                                B_AX_CPUQ_OP_SRC_QID_MASK);
2918         val = u32_replace_bits(val, ctrl_para->dst_pid,
2919                                B_AX_CPUQ_OP_DST_PID_MASK);
2920         val = u32_replace_bits(val, ctrl_para->dst_qid,
2921                                B_AX_CPUQ_OP_DST_QID_MASK);
2922         rtw89_write32(rtwdev, reg, val);
2923
2924         reg = wd ? R_AX_WD_CPUQ_OP_0 : R_AX_PL_CPUQ_OP_0;
2925         val = 0;
2926         val = u32_replace_bits(val, cmd_type,
2927                                B_AX_CPUQ_OP_CMD_TYPE_MASK);
2928         val = u32_replace_bits(val, ctrl_para->macid,
2929                                B_AX_CPUQ_OP_MACID_MASK);
2930         val = u32_replace_bits(val, ctrl_para->pkt_num,
2931                                B_AX_CPUQ_OP_PKTNUM_MASK);
2932         val |= B_AX_WD_CPUQ_OP_EXEC;
2933         rtw89_write32(rtwdev, reg, val);
2934
2935         reg = wd ? R_AX_WD_CPUQ_OP_STATUS : R_AX_PL_CPUQ_OP_STATUS;
2936
2937         ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_CPUQ_OP_STAT_DONE,
2938                                 1, 2000, false, rtwdev, reg);
2939         if (ret)
2940                 return ret;
2941
2942         if (cmd_type == CPUIO_OP_CMD_GET_1ST_PID ||
2943             cmd_type == CPUIO_OP_CMD_GET_NEXT_PID)
2944                 ctrl_para->pktid = FIELD_GET(B_AX_WD_CPUQ_OP_PKTID_MASK, val);
2945
2946         return 0;
2947 }
2948
2949 static int dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
2950 {
2951         const struct rtw89_dle_mem *cfg;
2952         struct rtw89_cpuio_ctrl ctrl_para = {0};
2953         u16 pkt_id;
2954         int ret;
2955
2956         cfg = get_dle_mem_cfg(rtwdev, mode);
2957         if (!cfg) {
2958                 rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n");
2959                 return -EINVAL;
2960         }
2961
2962         if (dle_used_size(cfg->wde_size, cfg->ple_size) !=
2963             dle_expected_used_size(rtwdev, mode)) {
2964                 rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n");
2965                 return -EINVAL;
2966         }
2967
2968         dle_quota_cfg(rtwdev, cfg, INVALID_QT_WCPU);
2969
2970         ret = rtw89_mac_dle_buf_req(rtwdev, 0x20, true, &pkt_id);
2971         if (ret) {
2972                 rtw89_err(rtwdev, "[ERR]WDE DLE buf req\n");
2973                 return ret;
2974         }
2975
2976         ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD;
2977         ctrl_para.start_pktid = pkt_id;
2978         ctrl_para.end_pktid = pkt_id;
2979         ctrl_para.pkt_num = 0;
2980         ctrl_para.dst_pid = WDE_DLE_PORT_ID_WDRLS;
2981         ctrl_para.dst_qid = WDE_DLE_QUEID_NO_REPORT;
2982         ret = rtw89_mac_set_cpuio(rtwdev, &ctrl_para, true);
2983         if (ret) {
2984                 rtw89_err(rtwdev, "[ERR]WDE DLE enqueue to head\n");
2985                 return -EFAULT;
2986         }
2987
2988         ret = rtw89_mac_dle_buf_req(rtwdev, 0x20, false, &pkt_id);
2989         if (ret) {
2990                 rtw89_err(rtwdev, "[ERR]PLE DLE buf req\n");
2991                 return ret;
2992         }
2993
2994         ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD;
2995         ctrl_para.start_pktid = pkt_id;
2996         ctrl_para.end_pktid = pkt_id;
2997         ctrl_para.pkt_num = 0;
2998         ctrl_para.dst_pid = PLE_DLE_PORT_ID_PLRLS;
2999         ctrl_para.dst_qid = PLE_DLE_QUEID_NO_REPORT;
3000         ret = rtw89_mac_set_cpuio(rtwdev, &ctrl_para, false);
3001         if (ret) {
3002                 rtw89_err(rtwdev, "[ERR]PLE DLE enqueue to head\n");
3003                 return -EFAULT;
3004         }
3005
3006         return 0;
3007 }
3008
3009 static int band_idle_ck_b(struct rtw89_dev *rtwdev, u8 mac_idx)
3010 {
3011         int ret;
3012         u32 reg;
3013         u8 val;
3014
3015         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
3016         if (ret)
3017                 return ret;
3018
3019         reg = rtw89_mac_reg_by_idx(R_AX_PTCL_TX_CTN_SEL, mac_idx);
3020
3021         ret = read_poll_timeout(rtw89_read8, val,
3022                                 (val & B_AX_PTCL_TX_ON_STAT) == 0,
3023                                 SW_CVR_DUR_US,
3024                                 SW_CVR_DUR_US * PTCL_IDLE_POLL_CNT,
3025                                 false, rtwdev, reg);
3026         if (ret)
3027                 return ret;
3028
3029         return 0;
3030 }
3031
3032 static int band1_enable(struct rtw89_dev *rtwdev)
3033 {
3034         int ret, i;
3035         u32 sleep_bak[4] = {0};
3036         u32 pause_bak[4] = {0};
3037         u32 tx_en;
3038
3039         ret = rtw89_chip_stop_sch_tx(rtwdev, 0, &tx_en, RTW89_SCH_TX_SEL_ALL);
3040         if (ret) {
3041                 rtw89_err(rtwdev, "[ERR]stop sch tx %d\n", ret);
3042                 return ret;
3043         }
3044
3045         for (i = 0; i < 4; i++) {
3046                 sleep_bak[i] = rtw89_read32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4);
3047                 pause_bak[i] = rtw89_read32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4);
3048                 rtw89_write32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4, U32_MAX);
3049                 rtw89_write32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4, U32_MAX);
3050         }
3051
3052         ret = band_idle_ck_b(rtwdev, 0);
3053         if (ret) {
3054                 rtw89_err(rtwdev, "[ERR]tx idle poll %d\n", ret);
3055                 return ret;
3056         }
3057
3058         ret = dle_quota_change(rtwdev, rtwdev->mac.qta_mode);
3059         if (ret) {
3060                 rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret);
3061                 return ret;
3062         }
3063
3064         for (i = 0; i < 4; i++) {
3065                 rtw89_write32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4, sleep_bak[i]);
3066                 rtw89_write32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4, pause_bak[i]);
3067         }
3068
3069         ret = rtw89_chip_resume_sch_tx(rtwdev, 0, tx_en);
3070         if (ret) {
3071                 rtw89_err(rtwdev, "[ERR]CMAC1 resume sch tx %d\n", ret);
3072                 return ret;
3073         }
3074
3075         ret = cmac_func_en(rtwdev, 1, true);
3076         if (ret) {
3077                 rtw89_err(rtwdev, "[ERR]CMAC1 func en %d\n", ret);
3078                 return ret;
3079         }
3080
3081         ret = cmac_init(rtwdev, 1);
3082         if (ret) {
3083                 rtw89_err(rtwdev, "[ERR]CMAC1 init %d\n", ret);
3084                 return ret;
3085         }
3086
3087         rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
3088                           B_AX_R_SYM_FEN_WLBBFUN_1 | B_AX_R_SYM_FEN_WLBBGLB_1);
3089
3090         return 0;
3091 }
3092
3093 static void rtw89_wdrls_imr_enable(struct rtw89_dev *rtwdev)
3094 {
3095         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3096
3097         rtw89_write32_clr(rtwdev, R_AX_WDRLS_ERR_IMR, B_AX_WDRLS_IMR_EN_CLR);
3098         rtw89_write32_set(rtwdev, R_AX_WDRLS_ERR_IMR, imr->wdrls_imr_set);
3099 }
3100
3101 static void rtw89_wsec_imr_enable(struct rtw89_dev *rtwdev)
3102 {
3103         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3104
3105         rtw89_write32_set(rtwdev, imr->wsec_imr_reg, imr->wsec_imr_set);
3106 }
3107
3108 static void rtw89_mpdu_trx_imr_enable(struct rtw89_dev *rtwdev)
3109 {
3110         enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
3111         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3112
3113         rtw89_write32_clr(rtwdev, R_AX_MPDU_TX_ERR_IMR,
3114                           B_AX_TX_GET_ERRPKTID_INT_EN |
3115                           B_AX_TX_NXT_ERRPKTID_INT_EN |
3116                           B_AX_TX_MPDU_SIZE_ZERO_INT_EN |
3117                           B_AX_TX_OFFSET_ERR_INT_EN |
3118                           B_AX_TX_HDR3_SIZE_ERR_INT_EN);
3119         if (chip_id == RTL8852C)
3120                 rtw89_write32_clr(rtwdev, R_AX_MPDU_TX_ERR_IMR,
3121                                   B_AX_TX_ETH_TYPE_ERR_EN |
3122                                   B_AX_TX_LLC_PRE_ERR_EN |
3123                                   B_AX_TX_NW_TYPE_ERR_EN |
3124                                   B_AX_TX_KSRCH_ERR_EN);
3125         rtw89_write32_set(rtwdev, R_AX_MPDU_TX_ERR_IMR,
3126                           imr->mpdu_tx_imr_set);
3127
3128         rtw89_write32_clr(rtwdev, R_AX_MPDU_RX_ERR_IMR,
3129                           B_AX_GETPKTID_ERR_INT_EN |
3130                           B_AX_MHDRLEN_ERR_INT_EN |
3131                           B_AX_RPT_ERR_INT_EN);
3132         rtw89_write32_set(rtwdev, R_AX_MPDU_RX_ERR_IMR,
3133                           imr->mpdu_rx_imr_set);
3134 }
3135
3136 static void rtw89_sta_sch_imr_enable(struct rtw89_dev *rtwdev)
3137 {
3138         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3139
3140         rtw89_write32_clr(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR,
3141                           B_AX_SEARCH_HANG_TIMEOUT_INT_EN |
3142                           B_AX_RPT_HANG_TIMEOUT_INT_EN |
3143                           B_AX_PLE_B_PKTID_ERR_INT_EN);
3144         rtw89_write32_set(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR,
3145                           imr->sta_sch_imr_set);
3146 }
3147
3148 static void rtw89_txpktctl_imr_enable(struct rtw89_dev *rtwdev)
3149 {
3150         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3151
3152         rtw89_write32_clr(rtwdev, imr->txpktctl_imr_b0_reg,
3153                           imr->txpktctl_imr_b0_clr);
3154         rtw89_write32_set(rtwdev, imr->txpktctl_imr_b0_reg,
3155                           imr->txpktctl_imr_b0_set);
3156         rtw89_write32_clr(rtwdev, imr->txpktctl_imr_b1_reg,
3157                           imr->txpktctl_imr_b1_clr);
3158         rtw89_write32_set(rtwdev, imr->txpktctl_imr_b1_reg,
3159                           imr->txpktctl_imr_b1_set);
3160 }
3161
3162 static void rtw89_wde_imr_enable(struct rtw89_dev *rtwdev)
3163 {
3164         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3165
3166         rtw89_write32_clr(rtwdev, R_AX_WDE_ERR_IMR, imr->wde_imr_clr);
3167         rtw89_write32_set(rtwdev, R_AX_WDE_ERR_IMR, imr->wde_imr_set);
3168 }
3169
3170 static void rtw89_ple_imr_enable(struct rtw89_dev *rtwdev)
3171 {
3172         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3173
3174         rtw89_write32_clr(rtwdev, R_AX_PLE_ERR_IMR, imr->ple_imr_clr);
3175         rtw89_write32_set(rtwdev, R_AX_PLE_ERR_IMR, imr->ple_imr_set);
3176 }
3177
3178 static void rtw89_pktin_imr_enable(struct rtw89_dev *rtwdev)
3179 {
3180         rtw89_write32_set(rtwdev, R_AX_PKTIN_ERR_IMR,
3181                           B_AX_PKTIN_GETPKTID_ERR_INT_EN);
3182 }
3183
3184 static void rtw89_dispatcher_imr_enable(struct rtw89_dev *rtwdev)
3185 {
3186         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3187
3188         rtw89_write32_clr(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR,
3189                           imr->host_disp_imr_clr);
3190         rtw89_write32_set(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR,
3191                           imr->host_disp_imr_set);
3192         rtw89_write32_clr(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR,
3193                           imr->cpu_disp_imr_clr);
3194         rtw89_write32_set(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR,
3195                           imr->cpu_disp_imr_set);
3196         rtw89_write32_clr(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR,
3197                           imr->other_disp_imr_clr);
3198         rtw89_write32_set(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR,
3199                           imr->other_disp_imr_set);
3200 }
3201
3202 static void rtw89_cpuio_imr_enable(struct rtw89_dev *rtwdev)
3203 {
3204         rtw89_write32_clr(rtwdev, R_AX_CPUIO_ERR_IMR, B_AX_CPUIO_IMR_CLR);
3205         rtw89_write32_set(rtwdev, R_AX_CPUIO_ERR_IMR, B_AX_CPUIO_IMR_SET);
3206 }
3207
3208 static void rtw89_bbrpt_imr_enable(struct rtw89_dev *rtwdev)
3209 {
3210         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3211
3212         rtw89_write32_set(rtwdev, imr->bbrpt_com_err_imr_reg,
3213                           B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_EN);
3214         rtw89_write32_clr(rtwdev, imr->bbrpt_chinfo_err_imr_reg,
3215                           B_AX_BBRPT_CHINFO_IMR_CLR);
3216         rtw89_write32_set(rtwdev, imr->bbrpt_chinfo_err_imr_reg,
3217                           imr->bbrpt_err_imr_set);
3218         rtw89_write32_set(rtwdev, imr->bbrpt_dfs_err_imr_reg,
3219                           B_AX_BBRPT_DFS_TO_ERR_INT_EN);
3220         rtw89_write32_set(rtwdev, R_AX_LA_ERRFLAG, B_AX_LA_IMR_DATA_LOSS_ERR);
3221 }
3222
3223 static void rtw89_scheduler_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3224 {
3225         u32 reg;
3226
3227         reg = rtw89_mac_reg_by_idx(R_AX_SCHEDULE_ERR_IMR, mac_idx);
3228         rtw89_write32_clr(rtwdev, reg, B_AX_SORT_NON_IDLE_ERR_INT_EN |
3229                                        B_AX_FSM_TIMEOUT_ERR_INT_EN);
3230         rtw89_write32_set(rtwdev, reg, B_AX_FSM_TIMEOUT_ERR_INT_EN);
3231 }
3232
3233 static void rtw89_ptcl_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3234 {
3235         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3236         u32 reg;
3237
3238         reg = rtw89_mac_reg_by_idx(R_AX_PTCL_IMR0, mac_idx);
3239         rtw89_write32_clr(rtwdev, reg, imr->ptcl_imr_clr);
3240         rtw89_write32_set(rtwdev, reg, imr->ptcl_imr_set);
3241 }
3242
3243 static void rtw89_cdma_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3244 {
3245         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3246         enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
3247         u32 reg;
3248
3249         reg = rtw89_mac_reg_by_idx(imr->cdma_imr_0_reg, mac_idx);
3250         rtw89_write32_clr(rtwdev, reg, imr->cdma_imr_0_clr);
3251         rtw89_write32_set(rtwdev, reg, imr->cdma_imr_0_set);
3252
3253         if (chip_id == RTL8852C) {
3254                 reg = rtw89_mac_reg_by_idx(imr->cdma_imr_1_reg, mac_idx);
3255                 rtw89_write32_clr(rtwdev, reg, imr->cdma_imr_1_clr);
3256                 rtw89_write32_set(rtwdev, reg, imr->cdma_imr_1_set);
3257         }
3258 }
3259
3260 static void rtw89_phy_intf_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3261 {
3262         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3263         u32 reg;
3264
3265         reg = rtw89_mac_reg_by_idx(imr->phy_intf_imr_reg, mac_idx);
3266         rtw89_write32_clr(rtwdev, reg, imr->phy_intf_imr_clr);
3267         rtw89_write32_set(rtwdev, reg, imr->phy_intf_imr_set);
3268 }
3269
3270 static void rtw89_rmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3271 {
3272         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3273         u32 reg;
3274
3275         reg = rtw89_mac_reg_by_idx(imr->rmac_imr_reg, mac_idx);
3276         rtw89_write32_clr(rtwdev, reg, imr->rmac_imr_clr);
3277         rtw89_write32_set(rtwdev, reg, imr->rmac_imr_set);
3278 }
3279
3280 static void rtw89_tmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3281 {
3282         const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3283         u32 reg;
3284
3285         reg = rtw89_mac_reg_by_idx(imr->tmac_imr_reg, mac_idx);
3286         rtw89_write32_clr(rtwdev, reg, imr->tmac_imr_clr);
3287         rtw89_write32_set(rtwdev, reg, imr->tmac_imr_set);
3288 }
3289
3290 static int rtw89_mac_enable_imr(struct rtw89_dev *rtwdev, u8 mac_idx,
3291                                 enum rtw89_mac_hwmod_sel sel)
3292 {
3293         int ret;
3294
3295         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, sel);
3296         if (ret) {
3297                 rtw89_err(rtwdev, "MAC%d mac_idx%d is not ready\n",
3298                           sel, mac_idx);
3299                 return ret;
3300         }
3301
3302         if (sel == RTW89_DMAC_SEL) {
3303                 rtw89_wdrls_imr_enable(rtwdev);
3304                 rtw89_wsec_imr_enable(rtwdev);
3305                 rtw89_mpdu_trx_imr_enable(rtwdev);
3306                 rtw89_sta_sch_imr_enable(rtwdev);
3307                 rtw89_txpktctl_imr_enable(rtwdev);
3308                 rtw89_wde_imr_enable(rtwdev);
3309                 rtw89_ple_imr_enable(rtwdev);
3310                 rtw89_pktin_imr_enable(rtwdev);
3311                 rtw89_dispatcher_imr_enable(rtwdev);
3312                 rtw89_cpuio_imr_enable(rtwdev);
3313                 rtw89_bbrpt_imr_enable(rtwdev);
3314         } else if (sel == RTW89_CMAC_SEL) {
3315                 rtw89_scheduler_imr_enable(rtwdev, mac_idx);
3316                 rtw89_ptcl_imr_enable(rtwdev, mac_idx);
3317                 rtw89_cdma_imr_enable(rtwdev, mac_idx);
3318                 rtw89_phy_intf_imr_enable(rtwdev, mac_idx);
3319                 rtw89_rmac_imr_enable(rtwdev, mac_idx);
3320                 rtw89_tmac_imr_enable(rtwdev, mac_idx);
3321         } else {
3322                 return -EINVAL;
3323         }
3324
3325         return 0;
3326 }
3327
3328 static void rtw89_mac_err_imr_ctrl(struct rtw89_dev *rtwdev, bool en)
3329 {
3330         enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
3331
3332         rtw89_write32(rtwdev, R_AX_DMAC_ERR_IMR,
3333                       en ? DMAC_ERR_IMR_EN : DMAC_ERR_IMR_DIS);
3334         rtw89_write32(rtwdev, R_AX_CMAC_ERR_IMR,
3335                       en ? CMAC0_ERR_IMR_EN : CMAC0_ERR_IMR_DIS);
3336         if (chip_id != RTL8852B && rtwdev->mac.dle_info.c1_rx_qta)
3337                 rtw89_write32(rtwdev, R_AX_CMAC_ERR_IMR_C1,
3338                               en ? CMAC1_ERR_IMR_EN : CMAC1_ERR_IMR_DIS);
3339 }
3340
3341 static int rtw89_mac_dbcc_enable(struct rtw89_dev *rtwdev, bool enable)
3342 {
3343         int ret = 0;
3344
3345         if (enable) {
3346                 ret = band1_enable(rtwdev);
3347                 if (ret) {
3348                         rtw89_err(rtwdev, "[ERR] band1_enable %d\n", ret);
3349                         return ret;
3350                 }
3351
3352                 ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL);
3353                 if (ret) {
3354                         rtw89_err(rtwdev, "[ERR] enable CMAC1 IMR %d\n", ret);
3355                         return ret;
3356                 }
3357         } else {
3358                 rtw89_err(rtwdev, "[ERR] disable dbcc is not implemented not\n");
3359                 return -EINVAL;
3360         }
3361
3362         return 0;
3363 }
3364
3365 static int set_host_rpr(struct rtw89_dev *rtwdev)
3366 {
3367         if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) {
3368                 rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG,
3369                                    B_AX_WDRLS_MODE_MASK, RTW89_RPR_MODE_POH);
3370                 rtw89_write32_set(rtwdev, R_AX_RLSRPT0_CFG0,
3371                                   B_AX_RLSRPT0_FLTR_MAP_MASK);
3372         } else {
3373                 rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG,
3374                                    B_AX_WDRLS_MODE_MASK, RTW89_RPR_MODE_STF);
3375                 rtw89_write32_clr(rtwdev, R_AX_RLSRPT0_CFG0,
3376                                   B_AX_RLSRPT0_FLTR_MAP_MASK);
3377         }
3378
3379         rtw89_write32_mask(rtwdev, R_AX_RLSRPT0_CFG1, B_AX_RLSRPT0_AGGNUM_MASK, 30);
3380         rtw89_write32_mask(rtwdev, R_AX_RLSRPT0_CFG1, B_AX_RLSRPT0_TO_MASK, 255);
3381
3382         return 0;
3383 }
3384
3385 static int rtw89_mac_trx_init(struct rtw89_dev *rtwdev)
3386 {
3387         enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode;
3388         int ret;
3389
3390         ret = dmac_init(rtwdev, 0);
3391         if (ret) {
3392                 rtw89_err(rtwdev, "[ERR]DMAC init %d\n", ret);
3393                 return ret;
3394         }
3395
3396         ret = cmac_init(rtwdev, 0);
3397         if (ret) {
3398                 rtw89_err(rtwdev, "[ERR]CMAC%d init %d\n", 0, ret);
3399                 return ret;
3400         }
3401
3402         if (is_qta_dbcc(rtwdev, qta_mode)) {
3403                 ret = rtw89_mac_dbcc_enable(rtwdev, true);
3404                 if (ret) {
3405                         rtw89_err(rtwdev, "[ERR]dbcc_enable init %d\n", ret);
3406                         return ret;
3407                 }
3408         }
3409
3410         ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
3411         if (ret) {
3412                 rtw89_err(rtwdev, "[ERR] enable DMAC IMR %d\n", ret);
3413                 return ret;
3414         }
3415
3416         ret = rtw89_mac_enable_imr(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL);
3417         if (ret) {
3418                 rtw89_err(rtwdev, "[ERR] to enable CMAC0 IMR %d\n", ret);
3419                 return ret;
3420         }
3421
3422         rtw89_mac_err_imr_ctrl(rtwdev, true);
3423
3424         ret = set_host_rpr(rtwdev);
3425         if (ret) {
3426                 rtw89_err(rtwdev, "[ERR] set host rpr %d\n", ret);
3427                 return ret;
3428         }
3429
3430         return 0;
3431 }
3432
3433 static void rtw89_disable_fw_watchdog(struct rtw89_dev *rtwdev)
3434 {
3435         enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
3436         u32 val32;
3437
3438         if (chip_id == RTL8852B || chip_id == RTL8851B) {
3439                 rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_APB_WRAP_EN);
3440                 rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_APB_WRAP_EN);
3441                 return;
3442         }
3443
3444         rtw89_mac_mem_write(rtwdev, R_AX_WDT_CTRL,
3445                             WDT_CTRL_ALL_DIS, RTW89_MAC_MEM_CPU_LOCAL);
3446
3447         val32 = rtw89_mac_mem_read(rtwdev, R_AX_WDT_STATUS, RTW89_MAC_MEM_CPU_LOCAL);
3448         val32 |= B_AX_FS_WDT_INT;
3449         val32 &= ~B_AX_FS_WDT_INT_MSK;
3450         rtw89_mac_mem_write(rtwdev, R_AX_WDT_STATUS, val32, RTW89_MAC_MEM_CPU_LOCAL);
3451 }
3452
3453 void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev)
3454 {
3455         clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
3456
3457         rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN);
3458         rtw89_write32_clr(rtwdev, R_AX_WCPU_FW_CTRL, B_AX_WCPU_FWDL_EN |
3459                           B_AX_H2C_PATH_RDY | B_AX_FWDL_PATH_RDY);
3460         rtw89_write32_clr(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN);
3461
3462         rtw89_disable_fw_watchdog(rtwdev);
3463
3464         rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
3465         rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
3466 }
3467
3468 int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw)
3469 {
3470         u32 val;
3471         int ret;
3472
3473         if (rtw89_read32(rtwdev, R_AX_PLATFORM_ENABLE) & B_AX_WCPU_EN)
3474                 return -EFAULT;
3475
3476         rtw89_write32(rtwdev, R_AX_UDM1, 0);
3477         rtw89_write32(rtwdev, R_AX_UDM2, 0);
3478         rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0);
3479         rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0);
3480         rtw89_write32(rtwdev, R_AX_HALT_H2C, 0);
3481         rtw89_write32(rtwdev, R_AX_HALT_C2H, 0);
3482
3483         rtw89_write32_set(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN);
3484
3485         val = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL);
3486         val &= ~(B_AX_WCPU_FWDL_EN | B_AX_H2C_PATH_RDY | B_AX_FWDL_PATH_RDY);
3487         val = u32_replace_bits(val, RTW89_FWDL_INITIAL_STATE,
3488                                B_AX_WCPU_FWDL_STS_MASK);
3489
3490         if (dlfw)
3491                 val |= B_AX_WCPU_FWDL_EN;
3492
3493         rtw89_write32(rtwdev, R_AX_WCPU_FW_CTRL, val);
3494
3495         if (rtwdev->chip->chip_id == RTL8852B)
3496                 rtw89_write32_mask(rtwdev, R_AX_SEC_CTRL,
3497                                    B_AX_SEC_IDMEM_SIZE_CONFIG_MASK, 0x2);
3498
3499         rtw89_write16_mask(rtwdev, R_AX_BOOT_REASON, B_AX_BOOT_REASON_MASK,
3500                            boot_reason);
3501         rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN);
3502
3503         if (!dlfw) {
3504                 mdelay(5);
3505
3506                 ret = rtw89_fw_check_rdy(rtwdev);
3507                 if (ret)
3508                         return ret;
3509         }
3510
3511         return 0;
3512 }
3513
3514 static int rtw89_mac_dmac_pre_init(struct rtw89_dev *rtwdev)
3515 {
3516         enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
3517         u32 val;
3518         int ret;
3519
3520         if (chip_id == RTL8852C)
3521                 val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN |
3522                       B_AX_PKT_BUF_EN | B_AX_H_AXIDMA_EN;
3523         else
3524                 val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN |
3525                       B_AX_PKT_BUF_EN;
3526         rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val);
3527
3528         if (chip_id == RTL8851B)
3529                 val = B_AX_DISPATCHER_CLK_EN | B_AX_AXIDMA_CLK_EN;
3530         else
3531                 val = B_AX_DISPATCHER_CLK_EN;
3532         rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val);
3533
3534         if (chip_id != RTL8852C)
3535                 goto dle;
3536
3537         val = rtw89_read32(rtwdev, R_AX_HAXI_INIT_CFG1);
3538         val &= ~(B_AX_DMA_MODE_MASK | B_AX_STOP_AXI_MST);
3539         val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_PCIE_1B) |
3540                B_AX_TXHCI_EN_V1 | B_AX_RXHCI_EN_V1;
3541         rtw89_write32(rtwdev, R_AX_HAXI_INIT_CFG1, val);
3542
3543         rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP1,
3544                           B_AX_STOP_ACH0 | B_AX_STOP_ACH1 | B_AX_STOP_ACH3 |
3545                           B_AX_STOP_ACH4 | B_AX_STOP_ACH5 | B_AX_STOP_ACH6 |
3546                           B_AX_STOP_ACH7 | B_AX_STOP_CH8 | B_AX_STOP_CH9 |
3547                           B_AX_STOP_CH12 | B_AX_STOP_ACH2);
3548         rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP2, B_AX_STOP_CH10 | B_AX_STOP_CH11);
3549         rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_AXIDMA_EN);
3550
3551 dle:
3552         ret = dle_init(rtwdev, RTW89_QTA_DLFW, rtwdev->mac.qta_mode);
3553         if (ret) {
3554                 rtw89_err(rtwdev, "[ERR]DLE pre init %d\n", ret);
3555                 return ret;
3556         }
3557
3558         ret = hfc_init(rtwdev, true, false, true);
3559         if (ret) {
3560                 rtw89_err(rtwdev, "[ERR]HCI FC pre init %d\n", ret);
3561                 return ret;
3562         }
3563
3564         return ret;
3565 }
3566
3567 int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
3568 {
3569         rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN,
3570                          B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
3571         rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL,
3572                           B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 |
3573                           B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1);
3574         rtw89_write8_set(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE);
3575
3576         return 0;
3577 }
3578 EXPORT_SYMBOL(rtw89_mac_enable_bb_rf);
3579
3580 int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
3581 {
3582         rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
3583                          B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
3584         rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL,
3585                           B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 |
3586                           B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1);
3587         rtw89_write8_clr(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE);
3588
3589         return 0;
3590 }
3591 EXPORT_SYMBOL(rtw89_mac_disable_bb_rf);
3592
3593 int rtw89_mac_partial_init(struct rtw89_dev *rtwdev)
3594 {
3595         int ret;
3596
3597         ret = rtw89_mac_power_switch(rtwdev, true);
3598         if (ret) {
3599                 rtw89_mac_power_switch(rtwdev, false);
3600                 ret = rtw89_mac_power_switch(rtwdev, true);
3601                 if (ret)
3602                         return ret;
3603         }
3604
3605         rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
3606
3607         ret = rtw89_mac_dmac_pre_init(rtwdev);
3608         if (ret)
3609                 return ret;
3610
3611         if (rtwdev->hci.ops->mac_pre_init) {
3612                 ret = rtwdev->hci.ops->mac_pre_init(rtwdev);
3613                 if (ret)
3614                         return ret;
3615         }
3616
3617         ret = rtw89_fw_download(rtwdev, RTW89_FW_NORMAL);
3618         if (ret)
3619                 return ret;
3620
3621         return 0;
3622 }
3623
3624 int rtw89_mac_init(struct rtw89_dev *rtwdev)
3625 {
3626         int ret;
3627
3628         ret = rtw89_mac_partial_init(rtwdev);
3629         if (ret)
3630                 goto fail;
3631
3632         ret = rtw89_chip_enable_bb_rf(rtwdev);
3633         if (ret)
3634                 goto fail;
3635
3636         ret = rtw89_mac_sys_init(rtwdev);
3637         if (ret)
3638                 goto fail;
3639
3640         ret = rtw89_mac_trx_init(rtwdev);
3641         if (ret)
3642                 goto fail;
3643
3644         if (rtwdev->hci.ops->mac_post_init) {
3645                 ret = rtwdev->hci.ops->mac_post_init(rtwdev);
3646                 if (ret)
3647                         goto fail;
3648         }
3649
3650         rtw89_fw_send_all_early_h2c(rtwdev);
3651         rtw89_fw_h2c_set_ofld_cfg(rtwdev);
3652
3653         return ret;
3654 fail:
3655         rtw89_mac_power_switch(rtwdev, false);
3656
3657         return ret;
3658 }
3659
3660 static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
3661 {
3662         u8 i;
3663
3664         for (i = 0; i < 4; i++) {
3665                 rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
3666                               DMAC_TBL_BASE_ADDR + (macid << 4) + (i << 2));
3667                 rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0);
3668         }
3669 }
3670
3671 static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
3672 {
3673         rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
3674                       CMAC_TBL_BASE_ADDR + macid * CCTL_INFO_SIZE);
3675         rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0x4);
3676         rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 4, 0x400A0004);
3677         rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 8, 0);
3678         rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 12, 0);
3679         rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 16, 0);
3680         rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 20, 0xE43000B);
3681         rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 24, 0);
3682         rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 28, 0xB8109);
3683 }
3684
3685 int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause)
3686 {
3687         u8 sh =  FIELD_GET(GENMASK(4, 0), macid);
3688         u8 grp = macid >> 5;
3689         int ret;
3690
3691         /* If this is called by change_interface() in the case of P2P, it could
3692          * be power-off, so ignore this operation.
3693          */
3694         if (test_bit(RTW89_FLAG_CHANGING_INTERFACE, rtwdev->flags) &&
3695             !test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
3696                 return 0;
3697
3698         ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL);
3699         if (ret)
3700                 return ret;
3701
3702         rtw89_fw_h2c_macid_pause(rtwdev, sh, grp, pause);
3703
3704         return 0;
3705 }
3706
3707 static const struct rtw89_port_reg rtw_port_base = {
3708         .port_cfg = R_AX_PORT_CFG_P0,
3709         .tbtt_prohib = R_AX_TBTT_PROHIB_P0,
3710         .bcn_area = R_AX_BCN_AREA_P0,
3711         .bcn_early = R_AX_BCNERLYINT_CFG_P0,
3712         .tbtt_early = R_AX_TBTTERLYINT_CFG_P0,
3713         .tbtt_agg = R_AX_TBTT_AGG_P0,
3714         .bcn_space = R_AX_BCN_SPACE_CFG_P0,
3715         .bcn_forcetx = R_AX_BCN_FORCETX_P0,
3716         .bcn_err_cnt = R_AX_BCN_ERR_CNT_P0,
3717         .bcn_err_flag = R_AX_BCN_ERR_FLAG_P0,
3718         .dtim_ctrl = R_AX_DTIM_CTRL_P0,
3719         .tbtt_shift = R_AX_TBTT_SHIFT_P0,
3720         .bcn_cnt_tmr = R_AX_BCN_CNT_TMR_P0,
3721         .tsftr_l = R_AX_TSFTR_LOW_P0,
3722         .tsftr_h = R_AX_TSFTR_HIGH_P0
3723 };
3724
3725 #define BCN_INTERVAL 100
3726 #define BCN_ERLY_DEF 160
3727 #define BCN_SETUP_DEF 2
3728 #define BCN_HOLD_DEF 200
3729 #define BCN_MASK_DEF 0
3730 #define TBTT_ERLY_DEF 5
3731 #define BCN_SET_UNIT 32
3732 #define BCN_ERLY_SET_DLY (10 * 2)
3733
3734 static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev,
3735                                        struct rtw89_vif *rtwvif)
3736 {
3737         struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
3738         const struct rtw89_port_reg *p = &rtw_port_base;
3739
3740         if (!rtw89_read32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN))
3741                 return;
3742
3743         rtw89_write32_port_clr(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK);
3744         rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK, 1);
3745         rtw89_write16_port_clr(rtwdev, rtwvif, p->tbtt_early, B_AX_TBTTERLY_MASK);
3746         rtw89_write16_port_clr(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK);
3747
3748         msleep(vif->bss_conf.beacon_int + 1);
3749
3750         rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN |
3751                                                             B_AX_BRK_SETUP);
3752         rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSFTR_RST);
3753         rtw89_write32_port(rtwdev, rtwvif, p->bcn_cnt_tmr, 0);
3754 }
3755
3756 static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev,
3757                                       struct rtw89_vif *rtwvif, bool en)
3758 {
3759         const struct rtw89_port_reg *p = &rtw_port_base;
3760
3761         if (en)
3762                 rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN);
3763         else
3764                 rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TXBCN_RPT_EN);
3765 }
3766
3767 static void rtw89_mac_port_cfg_rx_rpt(struct rtw89_dev *rtwdev,
3768                                       struct rtw89_vif *rtwvif, bool en)
3769 {
3770         const struct rtw89_port_reg *p = &rtw_port_base;
3771
3772         if (en)
3773                 rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN);
3774         else
3775                 rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_RXBCN_RPT_EN);
3776 }
3777
3778 static void rtw89_mac_port_cfg_net_type(struct rtw89_dev *rtwdev,
3779                                         struct rtw89_vif *rtwvif)
3780 {
3781         const struct rtw89_port_reg *p = &rtw_port_base;
3782
3783         rtw89_write32_port_mask(rtwdev, rtwvif, p->port_cfg, B_AX_NET_TYPE_MASK,
3784                                 rtwvif->net_type);
3785 }
3786
3787 static void rtw89_mac_port_cfg_bcn_prct(struct rtw89_dev *rtwdev,
3788                                         struct rtw89_vif *rtwvif)
3789 {
3790         const struct rtw89_port_reg *p = &rtw_port_base;
3791         bool en = rtwvif->net_type != RTW89_NET_TYPE_NO_LINK;
3792         u32 bits = B_AX_TBTT_PROHIB_EN | B_AX_BRK_SETUP;
3793
3794         if (en)
3795                 rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bits);
3796         else
3797                 rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bits);
3798 }
3799
3800 static void rtw89_mac_port_cfg_rx_sw(struct rtw89_dev *rtwdev,
3801                                      struct rtw89_vif *rtwvif)
3802 {
3803         const struct rtw89_port_reg *p = &rtw_port_base;
3804         bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA ||
3805                   rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
3806         u32 bit = B_AX_RX_BSSID_FIT_EN;
3807
3808         if (en)
3809                 rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, bit);
3810         else
3811                 rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, bit);
3812 }
3813
3814 static void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
3815                                        struct rtw89_vif *rtwvif)
3816 {
3817         const struct rtw89_port_reg *p = &rtw_port_base;
3818         bool en = rtwvif->net_type == RTW89_NET_TYPE_INFRA ||
3819                   rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
3820
3821         if (en)
3822                 rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN);
3823         else
3824                 rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_TSF_UDT_EN);
3825 }
3826
3827 static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev,
3828                                      struct rtw89_vif *rtwvif)
3829 {
3830         const struct rtw89_port_reg *p = &rtw_port_base;
3831         bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ||
3832                   rtwvif->net_type == RTW89_NET_TYPE_AD_HOC;
3833
3834         if (en)
3835                 rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
3836         else
3837                 rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN);
3838 }
3839
3840 static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev,
3841                                         struct rtw89_vif *rtwvif)
3842 {
3843         struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
3844         const struct rtw89_port_reg *p = &rtw_port_base;
3845         u16 bcn_int = vif->bss_conf.beacon_int ? vif->bss_conf.beacon_int : BCN_INTERVAL;
3846
3847         rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_space, B_AX_BCN_SPACE_MASK,
3848                                 bcn_int);
3849 }
3850
3851 static void rtw89_mac_port_cfg_hiq_win(struct rtw89_dev *rtwdev,
3852                                        struct rtw89_vif *rtwvif)
3853 {
3854         static const u32 hiq_win_addr[RTW89_PORT_NUM] = {
3855                 R_AX_P0MB_HGQ_WINDOW_CFG_0, R_AX_PORT_HGQ_WINDOW_CFG,
3856                 R_AX_PORT_HGQ_WINDOW_CFG + 1, R_AX_PORT_HGQ_WINDOW_CFG + 2,
3857                 R_AX_PORT_HGQ_WINDOW_CFG + 3,
3858         };
3859         u8 win = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE ? 16 : 0;
3860         u8 port = rtwvif->port;
3861         u32 reg;
3862
3863         reg = rtw89_mac_reg_by_idx(hiq_win_addr[port], rtwvif->mac_idx);
3864         rtw89_write8(rtwdev, reg, win);
3865 }
3866
3867 static void rtw89_mac_port_cfg_hiq_dtim(struct rtw89_dev *rtwdev,
3868                                         struct rtw89_vif *rtwvif)
3869 {
3870         struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
3871         const struct rtw89_port_reg *p = &rtw_port_base;
3872         u32 addr;
3873
3874         addr = rtw89_mac_reg_by_idx(R_AX_MD_TSFT_STMP_CTL, rtwvif->mac_idx);
3875         rtw89_write8_set(rtwdev, addr, B_AX_UPD_HGQMD | B_AX_UPD_TIMIE);
3876
3877         rtw89_write16_port_mask(rtwdev, rtwvif, p->dtim_ctrl, B_AX_DTIM_NUM_MASK,
3878                                 vif->bss_conf.dtim_period);
3879 }
3880
3881 static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev,
3882                                               struct rtw89_vif *rtwvif)
3883 {
3884         const struct rtw89_port_reg *p = &rtw_port_base;
3885
3886         rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib,
3887                                 B_AX_TBTT_SETUP_MASK, BCN_SETUP_DEF);
3888 }
3889
3890 static void rtw89_mac_port_cfg_bcn_hold_time(struct rtw89_dev *rtwdev,
3891                                              struct rtw89_vif *rtwvif)
3892 {
3893         const struct rtw89_port_reg *p = &rtw_port_base;
3894
3895         rtw89_write32_port_mask(rtwdev, rtwvif, p->tbtt_prohib,
3896                                 B_AX_TBTT_HOLD_MASK, BCN_HOLD_DEF);
3897 }
3898
3899 static void rtw89_mac_port_cfg_bcn_mask_area(struct rtw89_dev *rtwdev,
3900                                              struct rtw89_vif *rtwvif)
3901 {
3902         const struct rtw89_port_reg *p = &rtw_port_base;
3903
3904         rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_area,
3905                                 B_AX_BCN_MSK_AREA_MASK, BCN_MASK_DEF);
3906 }
3907
3908 static void rtw89_mac_port_cfg_tbtt_early(struct rtw89_dev *rtwdev,
3909                                           struct rtw89_vif *rtwvif)
3910 {
3911         const struct rtw89_port_reg *p = &rtw_port_base;
3912
3913         rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_early,
3914                                 B_AX_TBTTERLY_MASK, TBTT_ERLY_DEF);
3915 }
3916
3917 static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev,
3918                                          struct rtw89_vif *rtwvif)
3919 {
3920         struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
3921         static const u32 masks[RTW89_PORT_NUM] = {
3922                 B_AX_BSS_COLOB_AX_PORT_0_MASK, B_AX_BSS_COLOB_AX_PORT_1_MASK,
3923                 B_AX_BSS_COLOB_AX_PORT_2_MASK, B_AX_BSS_COLOB_AX_PORT_3_MASK,
3924                 B_AX_BSS_COLOB_AX_PORT_4_MASK,
3925         };
3926         u8 port = rtwvif->port;
3927         u32 reg_base;
3928         u32 reg;
3929         u8 bss_color;
3930
3931         bss_color = vif->bss_conf.he_bss_color.color;
3932         reg_base = port >= 4 ? R_AX_PTCL_BSS_COLOR_1 : R_AX_PTCL_BSS_COLOR_0;
3933         reg = rtw89_mac_reg_by_idx(reg_base, rtwvif->mac_idx);
3934         rtw89_write32_mask(rtwdev, reg, masks[port], bss_color);
3935 }
3936
3937 static void rtw89_mac_port_cfg_mbssid(struct rtw89_dev *rtwdev,
3938                                       struct rtw89_vif *rtwvif)
3939 {
3940         u8 port = rtwvif->port;
3941         u32 reg;
3942
3943         if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
3944                 return;
3945
3946         if (port == 0) {
3947                 reg = rtw89_mac_reg_by_idx(R_AX_MBSSID_CTRL, rtwvif->mac_idx);
3948                 rtw89_write32_clr(rtwdev, reg, B_AX_P0MB_ALL_MASK);
3949         }
3950 }
3951
3952 static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev,
3953                                         struct rtw89_vif *rtwvif)
3954 {
3955         u8 port = rtwvif->port;
3956         u32 reg;
3957         u32 val;
3958
3959         reg = rtw89_mac_reg_by_idx(R_AX_MBSSID_DROP_0, rtwvif->mac_idx);
3960         val = rtw89_read32(rtwdev, reg);
3961         val &= ~FIELD_PREP(B_AX_PORT_DROP_4_0_MASK, BIT(port));
3962         if (port == 0)
3963                 val &= ~BIT(0);
3964         rtw89_write32(rtwdev, reg, val);
3965 }
3966
3967 static void rtw89_mac_port_cfg_func_en(struct rtw89_dev *rtwdev,
3968                                        struct rtw89_vif *rtwvif, bool enable)
3969 {
3970         const struct rtw89_port_reg *p = &rtw_port_base;
3971
3972         if (enable)
3973                 rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg,
3974                                        B_AX_PORT_FUNC_EN);
3975         else
3976                 rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg,
3977                                        B_AX_PORT_FUNC_EN);
3978 }
3979
3980 static void rtw89_mac_port_cfg_bcn_early(struct rtw89_dev *rtwdev,
3981                                          struct rtw89_vif *rtwvif)
3982 {
3983         const struct rtw89_port_reg *p = &rtw_port_base;
3984
3985         rtw89_write32_port_mask(rtwdev, rtwvif, p->bcn_early, B_AX_BCNERLY_MASK,
3986                                 BCN_ERLY_DEF);
3987 }
3988
3989 static void rtw89_mac_port_cfg_tbtt_shift(struct rtw89_dev *rtwdev,
3990                                           struct rtw89_vif *rtwvif)
3991 {
3992         const struct rtw89_port_reg *p = &rtw_port_base;
3993         u16 val;
3994
3995         if (rtwdev->chip->chip_id != RTL8852C)
3996                 return;
3997
3998         if (rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT &&
3999             rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION)
4000                 return;
4001
4002         val = FIELD_PREP(B_AX_TBTT_SHIFT_OFST_MAG, 1) |
4003                          B_AX_TBTT_SHIFT_OFST_SIGN;
4004
4005         rtw89_write16_port_mask(rtwdev, rtwvif, p->tbtt_shift,
4006                                 B_AX_TBTT_SHIFT_OFST_MASK, val);
4007 }
4008
4009 void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
4010                              struct rtw89_vif *rtwvif,
4011                              struct rtw89_vif *rtwvif_src,
4012                              u16 offset_tu)
4013 {
4014         u32 val, reg;
4015
4016         val = RTW89_PORT_OFFSET_TU_TO_32US(offset_tu);
4017         reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4,
4018                                    rtwvif->mac_idx);
4019
4020         rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port);
4021         rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_OFFSET_VAL, val);
4022         rtw89_write32_set(rtwdev, reg, B_AX_SYNC_NOW);
4023 }
4024
4025 static void rtw89_mac_port_tsf_sync_rand(struct rtw89_dev *rtwdev,
4026                                          struct rtw89_vif *rtwvif,
4027                                          struct rtw89_vif *rtwvif_src,
4028                                          u8 offset, int *n_offset)
4029 {
4030         if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif == rtwvif_src)
4031                 return;
4032
4033         /* adjust offset randomly to avoid beacon conflict */
4034         offset = offset - offset / 4 + get_random_u32() % (offset / 2);
4035         rtw89_mac_port_tsf_sync(rtwdev, rtwvif, rtwvif_src,
4036                                 (*n_offset) * offset);
4037
4038         (*n_offset)++;
4039 }
4040
4041 static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev)
4042 {
4043         struct rtw89_vif *src = NULL, *tmp;
4044         u8 offset = 100, vif_aps = 0;
4045         int n_offset = 1;
4046
4047         rtw89_for_each_rtwvif(rtwdev, tmp) {
4048                 if (!src || tmp->net_type == RTW89_NET_TYPE_INFRA)
4049                         src = tmp;
4050                 if (tmp->net_type == RTW89_NET_TYPE_AP_MODE)
4051                         vif_aps++;
4052         }
4053
4054         if (vif_aps == 0)
4055                 return;
4056
4057         offset /= (vif_aps + 1);
4058
4059         rtw89_for_each_rtwvif(rtwdev, tmp)
4060                 rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset, &n_offset);
4061 }
4062
4063 int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
4064 {
4065         int ret;
4066
4067         ret = rtw89_mac_port_update(rtwdev, rtwvif);
4068         if (ret)
4069                 return ret;
4070
4071         rtw89_mac_dmac_tbl_init(rtwdev, rtwvif->mac_id);
4072         rtw89_mac_cmac_tbl_init(rtwdev, rtwvif->mac_id);
4073
4074         ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif->mac_id, false);
4075         if (ret)
4076                 return ret;
4077
4078         ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_CREATE);
4079         if (ret)
4080                 return ret;
4081
4082         ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
4083         if (ret)
4084                 return ret;
4085
4086         ret = rtw89_cam_init(rtwdev, rtwvif);
4087         if (ret)
4088                 return ret;
4089
4090         ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
4091         if (ret)
4092                 return ret;
4093
4094         ret = rtw89_fw_h2c_default_cmac_tbl(rtwdev, rtwvif);
4095         if (ret)
4096                 return ret;
4097
4098         return 0;
4099 }
4100
4101 int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
4102 {
4103         int ret;
4104
4105         ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_REMOVE);
4106         if (ret)
4107                 return ret;
4108
4109         rtw89_cam_deinit(rtwdev, rtwvif);
4110
4111         ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
4112         if (ret)
4113                 return ret;
4114
4115         return 0;
4116 }
4117
4118 int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
4119 {
4120         u8 port = rtwvif->port;
4121
4122         if (port >= RTW89_PORT_NUM)
4123                 return -EINVAL;
4124
4125         rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif);
4126         rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif, false);
4127         rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif, false);
4128         rtw89_mac_port_cfg_net_type(rtwdev, rtwvif);
4129         rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif);
4130         rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif);
4131         rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif);
4132         rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif);
4133         rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif);
4134         rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif);
4135         rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif);
4136         rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif);
4137         rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif);
4138         rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif);
4139         rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif);
4140         rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif);
4141         rtw89_mac_port_cfg_tbtt_shift(rtwdev, rtwvif);
4142         rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif);
4143         rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif);
4144         rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, true);
4145         rtw89_mac_port_tsf_resync_all(rtwdev);
4146         fsleep(BCN_ERLY_SET_DLY);
4147         rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif);
4148
4149         return 0;
4150 }
4151
4152 int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
4153                            u64 *tsf)
4154 {
4155         const struct rtw89_port_reg *p = &rtw_port_base;
4156         u32 tsf_low, tsf_high;
4157         int ret;
4158
4159         ret = rtw89_mac_check_mac_en(rtwdev, rtwvif->mac_idx, RTW89_CMAC_SEL);
4160         if (ret)
4161                 return ret;
4162
4163         tsf_low = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_l);
4164         tsf_high = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_h);
4165         *tsf = (u64)tsf_high << 32 | tsf_low;
4166
4167         return 0;
4168 }
4169
4170 static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
4171                                                       struct cfg80211_bss *bss,
4172                                                       void *data)
4173 {
4174         const struct cfg80211_bss_ies *ies;
4175         const struct element *elem;
4176         bool *tolerated = data;
4177
4178         rcu_read_lock();
4179         ies = rcu_dereference(bss->ies);
4180         elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data,
4181                                   ies->len);
4182
4183         if (!elem || elem->datalen < 10 ||
4184             !(elem->data[10] & WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT))
4185                 *tolerated = false;
4186         rcu_read_unlock();
4187 }
4188
4189 void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
4190                                         struct ieee80211_vif *vif)
4191 {
4192         struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
4193         struct ieee80211_hw *hw = rtwdev->hw;
4194         bool tolerated = true;
4195         u32 reg;
4196
4197         if (!vif->bss_conf.he_support || vif->type != NL80211_IFTYPE_STATION)
4198                 return;
4199
4200         if (!(vif->bss_conf.chandef.chan->flags & IEEE80211_CHAN_RADAR))
4201                 return;
4202
4203         cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chandef,
4204                           rtw89_mac_check_he_obss_narrow_bw_ru_iter,
4205                           &tolerated);
4206
4207         reg = rtw89_mac_reg_by_idx(R_AX_RXTRIG_TEST_USER_2, rtwvif->mac_idx);
4208         if (tolerated)
4209                 rtw89_write32_clr(rtwdev, reg, B_AX_RXTRIG_RU26_DIS);
4210         else
4211                 rtw89_write32_set(rtwdev, reg, B_AX_RXTRIG_RU26_DIS);
4212 }
4213
4214 void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
4215 {
4216         rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, false);
4217 }
4218
4219 int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
4220 {
4221         int ret;
4222
4223         rtwvif->mac_id = rtw89_core_acquire_bit_map(rtwdev->mac_id_map,
4224                                                     RTW89_MAX_MAC_ID_NUM);
4225         if (rtwvif->mac_id == RTW89_MAX_MAC_ID_NUM)
4226                 return -ENOSPC;
4227
4228         ret = rtw89_mac_vif_init(rtwdev, rtwvif);
4229         if (ret)
4230                 goto release_mac_id;
4231
4232         return 0;
4233
4234 release_mac_id:
4235         rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwvif->mac_id);
4236
4237         return ret;
4238 }
4239
4240 int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
4241 {
4242         int ret;
4243
4244         ret = rtw89_mac_vif_deinit(rtwdev, rtwvif);
4245         rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwvif->mac_id);
4246
4247         return ret;
4248 }
4249
4250 static void
4251 rtw89_mac_c2h_macid_pause(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
4252 {
4253 }
4254
4255 static bool rtw89_is_op_chan(struct rtw89_dev *rtwdev, u8 band, u8 channel)
4256 {
4257         const struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
4258
4259         return band == op->band_type && channel == op->primary_channel;
4260 }
4261
4262 static void
4263 rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
4264                            u32 len)
4265 {
4266         struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
4267         struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
4268         struct rtw89_chan new;
4269         u8 reason, status, tx_fail, band, actual_period;
4270         u32 last_chan = rtwdev->scan_info.last_chan_idx;
4271         u16 chan;
4272         int ret;
4273
4274         if (!rtwvif)
4275                 return;
4276
4277         tx_fail = RTW89_GET_MAC_C2H_SCANOFLD_TX_FAIL(c2h->data);
4278         status = RTW89_GET_MAC_C2H_SCANOFLD_STATUS(c2h->data);
4279         chan = RTW89_GET_MAC_C2H_SCANOFLD_PRI_CH(c2h->data);
4280         reason = RTW89_GET_MAC_C2H_SCANOFLD_RSP(c2h->data);
4281         band = RTW89_GET_MAC_C2H_SCANOFLD_BAND(c2h->data);
4282         actual_period = RTW89_GET_MAC_C2H_ACTUAL_PERIOD(c2h->data);
4283
4284         if (!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))
4285                 band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
4286
4287         rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
4288                     "band: %d, chan: %d, reason: %d, status: %d, tx_fail: %d, actual: %d\n",
4289                     band, chan, reason, status, tx_fail, actual_period);
4290
4291         switch (reason) {
4292         case RTW89_SCAN_LEAVE_CH_NOTIFY:
4293                 if (rtw89_is_op_chan(rtwdev, band, chan))
4294                         ieee80211_stop_queues(rtwdev->hw);
4295                 return;
4296         case RTW89_SCAN_END_SCAN_NOTIFY:
4297                 if (rtwvif && rtwvif->scan_req &&
4298                     last_chan < rtwvif->scan_req->n_channels) {
4299                         ret = rtw89_hw_scan_offload(rtwdev, vif, true);
4300                         if (ret) {
4301                                 rtw89_hw_scan_abort(rtwdev, vif);
4302                                 rtw89_warn(rtwdev, "HW scan failed: %d\n", ret);
4303                         }
4304                 } else {
4305                         rtw89_hw_scan_complete(rtwdev, vif, false);
4306                 }
4307                 break;
4308         case RTW89_SCAN_ENTER_CH_NOTIFY:
4309                 if (rtw89_is_op_chan(rtwdev, band, chan)) {
4310                         rtw89_assign_entity_chan(rtwdev, rtwvif->sub_entity_idx,
4311                                                  &rtwdev->scan_info.op_chan);
4312                         ieee80211_wake_queues(rtwdev->hw);
4313                 } else {
4314                         rtw89_chan_create(&new, chan, chan, band,
4315                                           RTW89_CHANNEL_WIDTH_20);
4316                         rtw89_assign_entity_chan(rtwdev, rtwvif->sub_entity_idx,
4317                                                  &new);
4318                 }
4319                 break;
4320         default:
4321                 return;
4322         }
4323 }
4324
4325 static void
4326 rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
4327                        struct sk_buff *skb)
4328 {
4329         struct ieee80211_vif *vif = rtwvif_to_vif_safe(rtwvif);
4330         enum nl80211_cqm_rssi_threshold_event nl_event;
4331         const struct rtw89_c2h_mac_bcnfltr_rpt *c2h =
4332                 (const struct rtw89_c2h_mac_bcnfltr_rpt *)skb->data;
4333         u8 type, event, mac_id;
4334         s8 sig;
4335
4336         type = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_TYPE);
4337         sig = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MA) - MAX_RSSI;
4338         event = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_EVENT);
4339         mac_id = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MACID);
4340
4341         if (mac_id != rtwvif->mac_id)
4342                 return;
4343
4344         rtw89_debug(rtwdev, RTW89_DBG_FW,
4345                     "C2H bcnfltr rpt macid: %d, type: %d, ma: %d, event: %d\n",
4346                     mac_id, type, sig, event);
4347
4348         switch (type) {
4349         case RTW89_BCN_FLTR_BEACON_LOSS:
4350                 if (!rtwdev->scanning && !rtwvif->offchan)
4351                         ieee80211_connection_loss(vif);
4352                 else
4353                         rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
4354                 return;
4355         case RTW89_BCN_FLTR_NOTIFY:
4356                 nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
4357                 break;
4358         case RTW89_BCN_FLTR_RSSI:
4359                 if (event == RTW89_BCN_FLTR_RSSI_LOW)
4360                         nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
4361                 else if (event == RTW89_BCN_FLTR_RSSI_HIGH)
4362                         nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
4363                 else
4364                         return;
4365                 break;
4366         default:
4367                 return;
4368         }
4369
4370         ieee80211_cqm_rssi_notify(vif, nl_event, sig, GFP_KERNEL);
4371 }
4372
4373 static void
4374 rtw89_mac_c2h_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
4375                            u32 len)
4376 {
4377         struct rtw89_vif *rtwvif;
4378
4379         rtw89_for_each_rtwvif(rtwdev, rtwvif)
4380                 rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif, c2h);
4381 }
4382
4383 static void
4384 rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
4385 {
4386         /* N.B. This will run in interrupt context. */
4387
4388         rtw89_debug(rtwdev, RTW89_DBG_FW,
4389                     "C2H rev ack recv, cat: %d, class: %d, func: %d, seq : %d\n",
4390                     RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h->data),
4391                     RTW89_GET_MAC_C2H_REV_ACK_CLASS(c2h->data),
4392                     RTW89_GET_MAC_C2H_REV_ACK_FUNC(c2h->data),
4393                     RTW89_GET_MAC_C2H_REV_ACK_H2C_SEQ(c2h->data));
4394 }
4395
4396 static void
4397 rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len)
4398 {
4399         /* N.B. This will run in interrupt context. */
4400         struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait;
4401         const struct rtw89_c2h_done_ack *c2h =
4402                 (const struct rtw89_c2h_done_ack *)skb_c2h->data;
4403         u8 h2c_cat = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CAT);
4404         u8 h2c_class = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CLASS);
4405         u8 h2c_func = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_FUNC);
4406         u8 h2c_return = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_H2C_RETURN);
4407         u8 h2c_seq = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_H2C_SEQ);
4408         struct rtw89_completion_data data = {};
4409         unsigned int cond;
4410
4411         rtw89_debug(rtwdev, RTW89_DBG_FW,
4412                     "C2H done ack recv, cat: %d, class: %d, func: %d, ret: %d, seq : %d\n",
4413                     h2c_cat, h2c_class, h2c_func, h2c_return, h2c_seq);
4414
4415         if (h2c_cat != H2C_CAT_MAC)
4416                 return;
4417
4418         switch (h2c_class) {
4419         default:
4420                 return;
4421         case H2C_CL_MAC_FW_OFLD:
4422                 switch (h2c_func) {
4423                 default:
4424                         return;
4425                 case H2C_FUNC_ADD_SCANOFLD_CH:
4426                 case H2C_FUNC_SCANOFLD:
4427                         cond = RTW89_FW_OFLD_WAIT_COND(0, h2c_func);
4428                         break;
4429                 }
4430
4431                 data.err = !!h2c_return;
4432                 rtw89_complete_cond(fw_ofld_wait, cond, &data);
4433                 return;
4434         }
4435 }
4436
4437 static void
4438 rtw89_mac_c2h_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
4439 {
4440         rtw89_info(rtwdev, "%*s", RTW89_GET_C2H_LOG_LEN(len),
4441                    RTW89_GET_C2H_LOG_SRT_PRT(c2h->data));
4442 }
4443
4444 static void
4445 rtw89_mac_c2h_bcn_cnt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
4446 {
4447 }
4448
4449 static void
4450 rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h,
4451                            u32 len)
4452 {
4453         struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
4454         const struct rtw89_c2h_pkt_ofld_rsp *c2h =
4455                 (const struct rtw89_c2h_pkt_ofld_rsp *)skb_c2h->data;
4456         u16 pkt_len = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN);
4457         u8 pkt_id = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_ID);
4458         u8 pkt_op = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP);
4459         struct rtw89_completion_data data = {};
4460         unsigned int cond;
4461
4462         rtw89_debug(rtwdev, RTW89_DBG_FW, "pkt ofld rsp: id %d op %d len %d\n",
4463                     pkt_id, pkt_op, pkt_len);
4464
4465         data.err = !pkt_len;
4466         cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(pkt_id, pkt_op);
4467
4468         rtw89_complete_cond(wait, cond, &data);
4469 }
4470
4471 static void
4472 rtw89_mac_c2h_tsf32_toggle_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
4473                                u32 len)
4474 {
4475 }
4476
4477 static void
4478 rtw89_mac_c2h_mcc_rcv_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
4479 {
4480         u8 group = RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h->data);
4481         u8 func = RTW89_GET_MAC_C2H_MCC_RCV_ACK_H2C_FUNC(c2h->data);
4482
4483         switch (func) {
4484         case H2C_FUNC_ADD_MCC:
4485         case H2C_FUNC_START_MCC:
4486         case H2C_FUNC_STOP_MCC:
4487         case H2C_FUNC_DEL_MCC_GROUP:
4488         case H2C_FUNC_RESET_MCC_GROUP:
4489         case H2C_FUNC_MCC_REQ_TSF:
4490         case H2C_FUNC_MCC_MACID_BITMAP:
4491         case H2C_FUNC_MCC_SYNC:
4492         case H2C_FUNC_MCC_SET_DURATION:
4493                 break;
4494         default:
4495                 rtw89_debug(rtwdev, RTW89_DBG_CHAN,
4496                             "invalid MCC C2H RCV ACK: func %d\n", func);
4497                 return;
4498         }
4499
4500         rtw89_debug(rtwdev, RTW89_DBG_CHAN,
4501                     "MCC C2H RCV ACK: group %d, func %d\n", group, func);
4502 }
4503
4504 static void
4505 rtw89_mac_c2h_mcc_req_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
4506 {
4507         u8 group = RTW89_GET_MAC_C2H_MCC_REQ_ACK_GROUP(c2h->data);
4508         u8 func = RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h->data);
4509         u8 retcode = RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_RETURN(c2h->data);
4510         struct rtw89_completion_data data = {};
4511         unsigned int cond;
4512         bool next = false;
4513
4514         switch (func) {
4515         case H2C_FUNC_MCC_REQ_TSF:
4516                 next = true;
4517                 break;
4518         case H2C_FUNC_MCC_MACID_BITMAP:
4519         case H2C_FUNC_MCC_SYNC:
4520         case H2C_FUNC_MCC_SET_DURATION:
4521                 break;
4522         case H2C_FUNC_ADD_MCC:
4523         case H2C_FUNC_START_MCC:
4524         case H2C_FUNC_STOP_MCC:
4525         case H2C_FUNC_DEL_MCC_GROUP:
4526         case H2C_FUNC_RESET_MCC_GROUP:
4527         default:
4528                 rtw89_debug(rtwdev, RTW89_DBG_CHAN,
4529                             "invalid MCC C2H REQ ACK: func %d\n", func);
4530                 return;
4531         }
4532
4533         rtw89_debug(rtwdev, RTW89_DBG_CHAN,
4534                     "MCC C2H REQ ACK: group %d, func %d, return code %d\n",
4535                     group, func, retcode);
4536
4537         if (!retcode && next)
4538                 return;
4539
4540         data.err = !!retcode;
4541         cond = RTW89_MCC_WAIT_COND(group, func);
4542         rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data);
4543 }
4544
4545 static void
4546 rtw89_mac_c2h_mcc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
4547 {
4548         u8 group = RTW89_GET_MAC_C2H_MCC_TSF_RPT_GROUP(c2h->data);
4549         struct rtw89_completion_data data = {};
4550         struct rtw89_mac_mcc_tsf_rpt *rpt;
4551         unsigned int cond;
4552
4553         rpt = (struct rtw89_mac_mcc_tsf_rpt *)data.buf;
4554         rpt->macid_x = RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_X(c2h->data);
4555         rpt->macid_y = RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_Y(c2h->data);
4556         rpt->tsf_x_low = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_X(c2h->data);
4557         rpt->tsf_x_high = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_X(c2h->data);
4558         rpt->tsf_y_low = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h->data);
4559         rpt->tsf_y_high = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h->data);
4560
4561         rtw89_debug(rtwdev, RTW89_DBG_CHAN,
4562                     "MCC C2H TSF RPT: macid %d> %llu, macid %d> %llu\n",
4563                     rpt->macid_x, (u64)rpt->tsf_x_high << 32 | rpt->tsf_x_low,
4564                     rpt->macid_y, (u64)rpt->tsf_y_high << 32 | rpt->tsf_y_low);
4565
4566         cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_REQ_TSF);
4567         rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data);
4568 }
4569
4570 static void
4571 rtw89_mac_c2h_mcc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
4572 {
4573         u8 group = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_GROUP(c2h->data);
4574         u8 macid = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_MACID(c2h->data);
4575         u8 status = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_STATUS(c2h->data);
4576         u32 tsf_low = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_LOW(c2h->data);
4577         u32 tsf_high = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h->data);
4578         struct rtw89_completion_data data = {};
4579         unsigned int cond;
4580         bool rsp = true;
4581         bool err;
4582         u8 func;
4583
4584         switch (status) {
4585         case RTW89_MAC_MCC_ADD_ROLE_OK:
4586         case RTW89_MAC_MCC_ADD_ROLE_FAIL:
4587                 func = H2C_FUNC_ADD_MCC;
4588                 err = status == RTW89_MAC_MCC_ADD_ROLE_FAIL;
4589                 break;
4590         case RTW89_MAC_MCC_START_GROUP_OK:
4591         case RTW89_MAC_MCC_START_GROUP_FAIL:
4592                 func = H2C_FUNC_START_MCC;
4593                 err = status == RTW89_MAC_MCC_START_GROUP_FAIL;
4594                 break;
4595         case RTW89_MAC_MCC_STOP_GROUP_OK:
4596         case RTW89_MAC_MCC_STOP_GROUP_FAIL:
4597                 func = H2C_FUNC_STOP_MCC;
4598                 err = status == RTW89_MAC_MCC_STOP_GROUP_FAIL;
4599                 break;
4600         case RTW89_MAC_MCC_DEL_GROUP_OK:
4601         case RTW89_MAC_MCC_DEL_GROUP_FAIL:
4602                 func = H2C_FUNC_DEL_MCC_GROUP;
4603                 err = status == RTW89_MAC_MCC_DEL_GROUP_FAIL;
4604                 break;
4605         case RTW89_MAC_MCC_RESET_GROUP_OK:
4606         case RTW89_MAC_MCC_RESET_GROUP_FAIL:
4607                 func = H2C_FUNC_RESET_MCC_GROUP;
4608                 err = status == RTW89_MAC_MCC_RESET_GROUP_FAIL;
4609                 break;
4610         case RTW89_MAC_MCC_SWITCH_CH_OK:
4611         case RTW89_MAC_MCC_SWITCH_CH_FAIL:
4612         case RTW89_MAC_MCC_TXNULL0_OK:
4613         case RTW89_MAC_MCC_TXNULL0_FAIL:
4614         case RTW89_MAC_MCC_TXNULL1_OK:
4615         case RTW89_MAC_MCC_TXNULL1_FAIL:
4616         case RTW89_MAC_MCC_SWITCH_EARLY:
4617         case RTW89_MAC_MCC_TBTT:
4618         case RTW89_MAC_MCC_DURATION_START:
4619         case RTW89_MAC_MCC_DURATION_END:
4620                 rsp = false;
4621                 break;
4622         default:
4623                 rtw89_debug(rtwdev, RTW89_DBG_CHAN,
4624                             "invalid MCC C2H STS RPT: status %d\n", status);
4625                 return;
4626         }
4627
4628         rtw89_debug(rtwdev, RTW89_DBG_CHAN,
4629                     "MCC C2H STS RPT: group %d, macid %d, status %d, tsf %llu\n",
4630                      group, macid, status, (u64)tsf_high << 32 | tsf_low);
4631
4632         if (!rsp)
4633                 return;
4634
4635         data.err = err;
4636         cond = RTW89_MCC_WAIT_COND(group, func);
4637         rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data);
4638 }
4639
4640 static
4641 void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev,
4642                                             struct sk_buff *c2h, u32 len) = {
4643         [RTW89_MAC_C2H_FUNC_EFUSE_DUMP] = NULL,
4644         [RTW89_MAC_C2H_FUNC_READ_RSP] = NULL,
4645         [RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP] = rtw89_mac_c2h_pkt_ofld_rsp,
4646         [RTW89_MAC_C2H_FUNC_BCN_RESEND] = NULL,
4647         [RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause,
4648         [RTW89_MAC_C2H_FUNC_SCANOFLD_RSP] = rtw89_mac_c2h_scanofld_rsp,
4649         [RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT] = rtw89_mac_c2h_tsf32_toggle_rpt,
4650         [RTW89_MAC_C2H_FUNC_BCNFLTR_RPT] = rtw89_mac_c2h_bcn_fltr_rpt,
4651 };
4652
4653 static
4654 void (* const rtw89_mac_c2h_info_handler[])(struct rtw89_dev *rtwdev,
4655                                             struct sk_buff *c2h, u32 len) = {
4656         [RTW89_MAC_C2H_FUNC_REC_ACK] = rtw89_mac_c2h_rec_ack,
4657         [RTW89_MAC_C2H_FUNC_DONE_ACK] = rtw89_mac_c2h_done_ack,
4658         [RTW89_MAC_C2H_FUNC_C2H_LOG] = rtw89_mac_c2h_log,
4659         [RTW89_MAC_C2H_FUNC_BCN_CNT] = rtw89_mac_c2h_bcn_cnt,
4660 };
4661
4662 static
4663 void (* const rtw89_mac_c2h_mcc_handler[])(struct rtw89_dev *rtwdev,
4664                                            struct sk_buff *c2h, u32 len) = {
4665         [RTW89_MAC_C2H_FUNC_MCC_RCV_ACK] = rtw89_mac_c2h_mcc_rcv_ack,
4666         [RTW89_MAC_C2H_FUNC_MCC_REQ_ACK] = rtw89_mac_c2h_mcc_req_ack,
4667         [RTW89_MAC_C2H_FUNC_MCC_TSF_RPT] = rtw89_mac_c2h_mcc_tsf_rpt,
4668         [RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT] = rtw89_mac_c2h_mcc_status_rpt,
4669 };
4670
4671 bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func)
4672 {
4673         switch (class) {
4674         default:
4675                 return false;
4676         case RTW89_MAC_C2H_CLASS_INFO:
4677                 switch (func) {
4678                 default:
4679                         return false;
4680                 case RTW89_MAC_C2H_FUNC_REC_ACK:
4681                 case RTW89_MAC_C2H_FUNC_DONE_ACK:
4682                         return true;
4683                 }
4684         case RTW89_MAC_C2H_CLASS_OFLD:
4685                 switch (func) {
4686                 default:
4687                         return false;
4688                 case RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP:
4689                         return true;
4690                 }
4691         case RTW89_MAC_C2H_CLASS_MCC:
4692                 return true;
4693         }
4694 }
4695
4696 void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
4697                           u32 len, u8 class, u8 func)
4698 {
4699         void (*handler)(struct rtw89_dev *rtwdev,
4700                         struct sk_buff *c2h, u32 len) = NULL;
4701
4702         switch (class) {
4703         case RTW89_MAC_C2H_CLASS_INFO:
4704                 if (func < RTW89_MAC_C2H_FUNC_INFO_MAX)
4705                         handler = rtw89_mac_c2h_info_handler[func];
4706                 break;
4707         case RTW89_MAC_C2H_CLASS_OFLD:
4708                 if (func < RTW89_MAC_C2H_FUNC_OFLD_MAX)
4709                         handler = rtw89_mac_c2h_ofld_handler[func];
4710                 break;
4711         case RTW89_MAC_C2H_CLASS_MCC:
4712                 if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MCC)
4713                         handler = rtw89_mac_c2h_mcc_handler[func];
4714                 break;
4715         case RTW89_MAC_C2H_CLASS_FWDBG:
4716                 return;
4717         default:
4718                 rtw89_info(rtwdev, "c2h class %d not support\n", class);
4719                 return;
4720         }
4721         if (!handler) {
4722                 rtw89_info(rtwdev, "c2h class %d func %d not support\n", class,
4723                            func);
4724                 return;
4725         }
4726         handler(rtwdev, skb, len);
4727 }
4728
4729 bool rtw89_mac_get_txpwr_cr(struct rtw89_dev *rtwdev,
4730                             enum rtw89_phy_idx phy_idx,
4731                             u32 reg_base, u32 *cr)
4732 {
4733         const struct rtw89_dle_mem *dle_mem = rtwdev->chip->dle_mem;
4734         enum rtw89_qta_mode mode = dle_mem->mode;
4735         u32 addr = rtw89_mac_reg_by_idx(reg_base, phy_idx);
4736
4737         if (addr < R_AX_PWR_RATE_CTRL || addr > CMAC1_END_ADDR) {
4738                 rtw89_err(rtwdev, "[TXPWR] addr=0x%x exceed txpwr cr\n",
4739                           addr);
4740                 goto error;
4741         }
4742
4743         if (addr >= CMAC1_START_ADDR && addr <= CMAC1_END_ADDR)
4744                 if (mode == RTW89_QTA_SCC) {
4745                         rtw89_err(rtwdev,
4746                                   "[TXPWR] addr=0x%x but hw not enable\n",
4747                                   addr);
4748                         goto error;
4749                 }
4750
4751         *cr = addr;
4752         return true;
4753
4754 error:
4755         rtw89_err(rtwdev, "[TXPWR] check txpwr cr 0x%x(phy%d) fail\n",
4756                   addr, phy_idx);
4757
4758         return false;
4759 }
4760 EXPORT_SYMBOL(rtw89_mac_get_txpwr_cr);
4761
4762 int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
4763 {
4764         u32 reg = rtw89_mac_reg_by_idx(R_AX_PPDU_STAT, mac_idx);
4765         int ret;
4766
4767         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
4768         if (ret)
4769                 return ret;
4770
4771         if (!enable) {
4772                 rtw89_write32_clr(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN);
4773                 return 0;
4774         }
4775
4776         rtw89_write32(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN |
4777                                    B_AX_APP_MAC_INFO_RPT |
4778                                    B_AX_APP_RX_CNT_RPT | B_AX_APP_PLCP_HDR_RPT |
4779                                    B_AX_PPDU_STAT_RPT_CRC32);
4780         rtw89_write32_mask(rtwdev, R_AX_HW_RPT_FWD, B_AX_FWD_PPDU_STAT_MASK,
4781                            RTW89_PRPT_DEST_HOST);
4782
4783         return 0;
4784 }
4785 EXPORT_SYMBOL(rtw89_mac_cfg_ppdu_status);
4786
4787 void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx)
4788 {
4789 #define MAC_AX_TIME_TH_SH  5
4790 #define MAC_AX_LEN_TH_SH   4
4791 #define MAC_AX_TIME_TH_MAX 255
4792 #define MAC_AX_LEN_TH_MAX  255
4793 #define MAC_AX_TIME_TH_DEF 88
4794 #define MAC_AX_LEN_TH_DEF  4080
4795         struct ieee80211_hw *hw = rtwdev->hw;
4796         u32 rts_threshold = hw->wiphy->rts_threshold;
4797         u32 time_th, len_th;
4798         u32 reg;
4799
4800         if (rts_threshold == (u32)-1) {
4801                 time_th = MAC_AX_TIME_TH_DEF;
4802                 len_th = MAC_AX_LEN_TH_DEF;
4803         } else {
4804                 time_th = MAC_AX_TIME_TH_MAX << MAC_AX_TIME_TH_SH;
4805                 len_th = rts_threshold;
4806         }
4807
4808         time_th = min_t(u32, time_th >> MAC_AX_TIME_TH_SH, MAC_AX_TIME_TH_MAX);
4809         len_th = min_t(u32, len_th >> MAC_AX_LEN_TH_SH, MAC_AX_LEN_TH_MAX);
4810
4811         reg = rtw89_mac_reg_by_idx(R_AX_AGG_LEN_HT_0, mac_idx);
4812         rtw89_write16_mask(rtwdev, reg, B_AX_RTS_TXTIME_TH_MASK, time_th);
4813         rtw89_write16_mask(rtwdev, reg, B_AX_RTS_LEN_TH_MASK, len_th);
4814 }
4815
4816 void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop)
4817 {
4818         bool empty;
4819         int ret;
4820
4821         if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
4822                 return;
4823
4824         ret = read_poll_timeout(dle_is_txq_empty, empty, empty,
4825                                 10000, 200000, false, rtwdev);
4826         if (ret && !drop && (rtwdev->total_sta_assoc || rtwdev->scanning))
4827                 rtw89_info(rtwdev, "timed out to flush queues\n");
4828 }
4829
4830 int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex)
4831 {
4832         u8 val;
4833         u16 val16;
4834         u32 val32;
4835         int ret;
4836
4837         rtw89_write8_set(rtwdev, R_AX_GPIO_MUXCFG, B_AX_ENBT);
4838         if (rtwdev->chip->chip_id != RTL8851B)
4839                 rtw89_write8_set(rtwdev, R_AX_BTC_FUNC_EN, B_AX_PTA_WL_TX_EN);
4840         rtw89_write8_set(rtwdev, R_AX_BT_COEX_CFG_2 + 1, B_AX_GNT_BT_POLARITY >> 8);
4841         rtw89_write8_set(rtwdev, R_AX_CSR_MODE, B_AX_STATIS_BT_EN | B_AX_WL_ACT_MSK);
4842         rtw89_write8_set(rtwdev, R_AX_CSR_MODE + 2, B_AX_BT_CNT_RST >> 16);
4843         if (rtwdev->chip->chip_id != RTL8851B)
4844                 rtw89_write8_clr(rtwdev, R_AX_TRXPTCL_RESP_0 + 3, B_AX_RSP_CHK_BTCCA >> 24);
4845
4846         val16 = rtw89_read16(rtwdev, R_AX_CCA_CFG_0);
4847         val16 = (val16 | B_AX_BTCCA_EN) & ~B_AX_BTCCA_BRK_TXOP_EN;
4848         rtw89_write16(rtwdev, R_AX_CCA_CFG_0, val16);
4849
4850         ret = rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_2, &val32);
4851         if (ret) {
4852                 rtw89_err(rtwdev, "Read R_AX_LTE_SW_CFG_2 fail!\n");
4853                 return ret;
4854         }
4855         val32 = val32 & B_AX_WL_RX_CTRL;
4856         ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_2, val32);
4857         if (ret) {
4858                 rtw89_err(rtwdev, "Write R_AX_LTE_SW_CFG_2 fail!\n");
4859                 return ret;
4860         }
4861
4862         switch (coex->pta_mode) {
4863         case RTW89_MAC_AX_COEX_RTK_MODE:
4864                 val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG);
4865                 val &= ~B_AX_BTMODE_MASK;
4866                 val |= FIELD_PREP(B_AX_BTMODE_MASK, MAC_AX_BT_MODE_0_3);
4867                 rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG, val);
4868
4869                 val = rtw89_read8(rtwdev, R_AX_TDMA_MODE);
4870                 rtw89_write8(rtwdev, R_AX_TDMA_MODE, val | B_AX_RTK_BT_ENABLE);
4871
4872                 val = rtw89_read8(rtwdev, R_AX_BT_COEX_CFG_5);
4873                 val &= ~B_AX_BT_RPT_SAMPLE_RATE_MASK;
4874                 val |= FIELD_PREP(B_AX_BT_RPT_SAMPLE_RATE_MASK, MAC_AX_RTK_RATE);
4875                 rtw89_write8(rtwdev, R_AX_BT_COEX_CFG_5, val);
4876                 break;
4877         case RTW89_MAC_AX_COEX_CSR_MODE:
4878                 val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG);
4879                 val &= ~B_AX_BTMODE_MASK;
4880                 val |= FIELD_PREP(B_AX_BTMODE_MASK, MAC_AX_BT_MODE_2);
4881                 rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG, val);
4882
4883                 val16 = rtw89_read16(rtwdev, R_AX_CSR_MODE);
4884                 val16 &= ~B_AX_BT_PRI_DETECT_TO_MASK;
4885                 val16 |= FIELD_PREP(B_AX_BT_PRI_DETECT_TO_MASK, MAC_AX_CSR_PRI_TO);
4886                 val16 &= ~B_AX_BT_TRX_INIT_DETECT_MASK;
4887                 val16 |= FIELD_PREP(B_AX_BT_TRX_INIT_DETECT_MASK, MAC_AX_CSR_TRX_TO);
4888                 val16 &= ~B_AX_BT_STAT_DELAY_MASK;
4889                 val16 |= FIELD_PREP(B_AX_BT_STAT_DELAY_MASK, MAC_AX_CSR_DELAY);
4890                 val16 |= B_AX_ENHANCED_BT;
4891                 rtw89_write16(rtwdev, R_AX_CSR_MODE, val16);
4892
4893                 rtw89_write8(rtwdev, R_AX_BT_COEX_CFG_2, MAC_AX_CSR_RATE);
4894                 break;
4895         default:
4896                 return -EINVAL;
4897         }
4898
4899         switch (coex->direction) {
4900         case RTW89_MAC_AX_COEX_INNER:
4901                 val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1);
4902                 val = (val & ~BIT(2)) | BIT(1);
4903                 rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val);
4904                 break;
4905         case RTW89_MAC_AX_COEX_OUTPUT:
4906                 val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1);
4907                 val = val | BIT(1) | BIT(0);
4908                 rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val);
4909                 break;
4910         case RTW89_MAC_AX_COEX_INPUT:
4911                 val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1);
4912                 val = val & ~(BIT(2) | BIT(1));
4913                 rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val);
4914                 break;
4915         default:
4916                 return -EINVAL;
4917         }
4918
4919         return 0;
4920 }
4921 EXPORT_SYMBOL(rtw89_mac_coex_init);
4922
4923 int rtw89_mac_coex_init_v1(struct rtw89_dev *rtwdev,
4924                            const struct rtw89_mac_ax_coex *coex)
4925 {
4926         rtw89_write32_set(rtwdev, R_AX_BTC_CFG,
4927                           B_AX_BTC_EN | B_AX_BTG_LNA1_GAIN_SEL);
4928         rtw89_write32_set(rtwdev, R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN);
4929         rtw89_write16_set(rtwdev, R_AX_CCA_CFG_0, B_AX_BTCCA_EN);
4930         rtw89_write16_clr(rtwdev, R_AX_CCA_CFG_0, B_AX_BTCCA_BRK_TXOP_EN);
4931
4932         switch (coex->pta_mode) {
4933         case RTW89_MAC_AX_COEX_RTK_MODE:
4934                 rtw89_write32_mask(rtwdev, R_AX_BTC_CFG, B_AX_BTC_MODE_MASK,
4935                                    MAC_AX_RTK_MODE);
4936                 rtw89_write32_mask(rtwdev, R_AX_RTK_MODE_CFG_V1,
4937                                    B_AX_SAMPLE_CLK_MASK, MAC_AX_RTK_RATE);
4938                 break;
4939         case RTW89_MAC_AX_COEX_CSR_MODE:
4940                 rtw89_write32_mask(rtwdev, R_AX_BTC_CFG, B_AX_BTC_MODE_MASK,
4941                                    MAC_AX_CSR_MODE);
4942                 break;
4943         default:
4944                 return -EINVAL;
4945         }
4946
4947         return 0;
4948 }
4949 EXPORT_SYMBOL(rtw89_mac_coex_init_v1);
4950
4951 int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev,
4952                       const struct rtw89_mac_ax_coex_gnt *gnt_cfg)
4953 {
4954         u32 val = 0, ret;
4955
4956         if (gnt_cfg->band[0].gnt_bt)
4957                 val |= B_AX_GNT_BT_RFC_S0_SW_VAL | B_AX_GNT_BT_BB_S0_SW_VAL;
4958
4959         if (gnt_cfg->band[0].gnt_bt_sw_en)
4960                 val |= B_AX_GNT_BT_RFC_S0_SW_CTRL | B_AX_GNT_BT_BB_S0_SW_CTRL;
4961
4962         if (gnt_cfg->band[0].gnt_wl)
4963                 val |= B_AX_GNT_WL_RFC_S0_SW_VAL | B_AX_GNT_WL_BB_S0_SW_VAL;
4964
4965         if (gnt_cfg->band[0].gnt_wl_sw_en)
4966                 val |= B_AX_GNT_WL_RFC_S0_SW_CTRL | B_AX_GNT_WL_BB_S0_SW_CTRL;
4967
4968         if (gnt_cfg->band[1].gnt_bt)
4969                 val |= B_AX_GNT_BT_RFC_S1_SW_VAL | B_AX_GNT_BT_BB_S1_SW_VAL;
4970
4971         if (gnt_cfg->band[1].gnt_bt_sw_en)
4972                 val |= B_AX_GNT_BT_RFC_S1_SW_CTRL | B_AX_GNT_BT_BB_S1_SW_CTRL;
4973
4974         if (gnt_cfg->band[1].gnt_wl)
4975                 val |= B_AX_GNT_WL_RFC_S1_SW_VAL | B_AX_GNT_WL_BB_S1_SW_VAL;
4976
4977         if (gnt_cfg->band[1].gnt_wl_sw_en)
4978                 val |= B_AX_GNT_WL_RFC_S1_SW_CTRL | B_AX_GNT_WL_BB_S1_SW_CTRL;
4979
4980         ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_1, val);
4981         if (ret) {
4982                 rtw89_err(rtwdev, "Write LTE fail!\n");
4983                 return ret;
4984         }
4985
4986         return 0;
4987 }
4988 EXPORT_SYMBOL(rtw89_mac_cfg_gnt);
4989
4990 int rtw89_mac_cfg_gnt_v1(struct rtw89_dev *rtwdev,
4991                          const struct rtw89_mac_ax_coex_gnt *gnt_cfg)
4992 {
4993         u32 val = 0;
4994
4995         if (gnt_cfg->band[0].gnt_bt)
4996                 val |= B_AX_GNT_BT_RFC_S0_VAL | B_AX_GNT_BT_RX_VAL |
4997                        B_AX_GNT_BT_TX_VAL;
4998         else
4999                 val |= B_AX_WL_ACT_VAL;
5000
5001         if (gnt_cfg->band[0].gnt_bt_sw_en)
5002                 val |= B_AX_GNT_BT_RFC_S0_SWCTRL | B_AX_GNT_BT_RX_SWCTRL |
5003                        B_AX_GNT_BT_TX_SWCTRL | B_AX_WL_ACT_SWCTRL;
5004
5005         if (gnt_cfg->band[0].gnt_wl)
5006                 val |= B_AX_GNT_WL_RFC_S0_VAL | B_AX_GNT_WL_RX_VAL |
5007                        B_AX_GNT_WL_TX_VAL | B_AX_GNT_WL_BB_VAL;
5008
5009         if (gnt_cfg->band[0].gnt_wl_sw_en)
5010                 val |= B_AX_GNT_WL_RFC_S0_SWCTRL | B_AX_GNT_WL_RX_SWCTRL |
5011                        B_AX_GNT_WL_TX_SWCTRL | B_AX_GNT_WL_BB_SWCTRL;
5012
5013         if (gnt_cfg->band[1].gnt_bt)
5014                 val |= B_AX_GNT_BT_RFC_S1_VAL | B_AX_GNT_BT_RX_VAL |
5015                        B_AX_GNT_BT_TX_VAL;
5016         else
5017                 val |= B_AX_WL_ACT_VAL;
5018
5019         if (gnt_cfg->band[1].gnt_bt_sw_en)
5020                 val |= B_AX_GNT_BT_RFC_S1_SWCTRL | B_AX_GNT_BT_RX_SWCTRL |
5021                        B_AX_GNT_BT_TX_SWCTRL | B_AX_WL_ACT_SWCTRL;
5022
5023         if (gnt_cfg->band[1].gnt_wl)
5024                 val |= B_AX_GNT_WL_RFC_S1_VAL | B_AX_GNT_WL_RX_VAL |
5025                        B_AX_GNT_WL_TX_VAL | B_AX_GNT_WL_BB_VAL;
5026
5027         if (gnt_cfg->band[1].gnt_wl_sw_en)
5028                 val |= B_AX_GNT_WL_RFC_S1_SWCTRL | B_AX_GNT_WL_RX_SWCTRL |
5029                        B_AX_GNT_WL_TX_SWCTRL | B_AX_GNT_WL_BB_SWCTRL;
5030
5031         rtw89_write32(rtwdev, R_AX_GNT_SW_CTRL, val);
5032
5033         return 0;
5034 }
5035 EXPORT_SYMBOL(rtw89_mac_cfg_gnt_v1);
5036
5037 int rtw89_mac_cfg_plt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt)
5038 {
5039         u32 reg;
5040         u16 val;
5041         int ret;
5042
5043         ret = rtw89_mac_check_mac_en(rtwdev, plt->band, RTW89_CMAC_SEL);
5044         if (ret)
5045                 return ret;
5046
5047         reg = rtw89_mac_reg_by_idx(R_AX_BT_PLT, plt->band);
5048         val = (plt->tx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_TX_PLT_GNT_LTE_RX : 0) |
5049               (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_TX_PLT_GNT_BT_TX : 0) |
5050               (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_TX_PLT_GNT_BT_RX : 0) |
5051               (plt->tx & RTW89_MAC_AX_PLT_GNT_WL ? B_AX_TX_PLT_GNT_WL : 0) |
5052               (plt->rx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_RX_PLT_GNT_LTE_RX : 0) |
5053               (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_RX_PLT_GNT_BT_TX : 0) |
5054               (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_RX_PLT_GNT_BT_RX : 0) |
5055               (plt->rx & RTW89_MAC_AX_PLT_GNT_WL ? B_AX_RX_PLT_GNT_WL : 0) |
5056               B_AX_PLT_EN;
5057         rtw89_write16(rtwdev, reg, val);
5058
5059         return 0;
5060 }
5061
5062 void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val)
5063 {
5064         u32 fw_sb;
5065
5066         fw_sb = rtw89_read32(rtwdev, R_AX_SCOREBOARD);
5067         fw_sb = FIELD_GET(B_MAC_AX_SB_FW_MASK, fw_sb);
5068         fw_sb = fw_sb & ~B_MAC_AX_BTGS1_NOTIFY;
5069         if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
5070                 fw_sb = fw_sb | MAC_AX_NOTIFY_PWR_MAJOR;
5071         else
5072                 fw_sb = fw_sb | MAC_AX_NOTIFY_TP_MAJOR;
5073         val = FIELD_GET(B_MAC_AX_SB_DRV_MASK, val);
5074         val = B_AX_TOGGLE |
5075               FIELD_PREP(B_MAC_AX_SB_DRV_MASK, val) |
5076               FIELD_PREP(B_MAC_AX_SB_FW_MASK, fw_sb);
5077         rtw89_write32(rtwdev, R_AX_SCOREBOARD, val);
5078         fsleep(1000); /* avoid BT FW loss information */
5079 }
5080
5081 u32 rtw89_mac_get_sb(struct rtw89_dev *rtwdev)
5082 {
5083         return rtw89_read32(rtwdev, R_AX_SCOREBOARD);
5084 }
5085
5086 int rtw89_mac_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl)
5087 {
5088         u8 val = rtw89_read8(rtwdev, R_AX_SYS_SDIO_CTRL + 3);
5089
5090         val = wl ? val | BIT(2) : val & ~BIT(2);
5091         rtw89_write8(rtwdev, R_AX_SYS_SDIO_CTRL + 3, val);
5092
5093         return 0;
5094 }
5095 EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path);
5096
5097 int rtw89_mac_cfg_ctrl_path_v1(struct rtw89_dev *rtwdev, bool wl)
5098 {
5099         struct rtw89_btc *btc = &rtwdev->btc;
5100         struct rtw89_btc_dm *dm = &btc->dm;
5101         struct rtw89_mac_ax_gnt *g = dm->gnt.band;
5102         int i;
5103
5104         if (wl)
5105                 return 0;
5106
5107         for (i = 0; i < RTW89_PHY_MAX; i++) {
5108                 g[i].gnt_bt_sw_en = 1;
5109                 g[i].gnt_bt = 1;
5110                 g[i].gnt_wl_sw_en = 1;
5111                 g[i].gnt_wl = 0;
5112         }
5113
5114         return rtw89_mac_cfg_gnt_v1(rtwdev, &dm->gnt);
5115 }
5116 EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v1);
5117
5118 bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev)
5119 {
5120         const struct rtw89_chip_info *chip = rtwdev->chip;
5121         u8 val = 0;
5122
5123         if (chip->chip_id == RTL8852C)
5124                 return false;
5125         else if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B)
5126                 val = rtw89_read8_mask(rtwdev, R_AX_SYS_SDIO_CTRL + 3,
5127                                        B_AX_LTE_MUX_CTRL_PATH >> 24);
5128
5129         return !!val;
5130 }
5131
5132 u16 rtw89_mac_get_plt_cnt(struct rtw89_dev *rtwdev, u8 band)
5133 {
5134         u32 reg;
5135         u16 cnt;
5136
5137         reg = rtw89_mac_reg_by_idx(R_AX_BT_PLT, band);
5138         cnt = rtw89_read32_mask(rtwdev, reg, B_AX_BT_PLT_PKT_CNT_MASK);
5139         rtw89_write16_set(rtwdev, reg, B_AX_BT_PLT_RST);
5140
5141         return cnt;
5142 }
5143
5144 static void rtw89_mac_bfee_standby_timer(struct rtw89_dev *rtwdev, u8 mac_idx,
5145                                          bool keep)
5146 {
5147         u32 reg;
5148
5149         rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee standby_timer to %d\n", keep);
5150         reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx);
5151         if (keep) {
5152                 set_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags);
5153                 rtw89_write32_mask(rtwdev, reg, B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK,
5154                                    BFRP_RX_STANDBY_TIMER_KEEP);
5155         } else {
5156                 clear_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags);
5157                 rtw89_write32_mask(rtwdev, reg, B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK,
5158                                    BFRP_RX_STANDBY_TIMER_RELEASE);
5159         }
5160 }
5161
5162 static void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
5163 {
5164         u32 reg;
5165         u32 mask = B_AX_BFMEE_HT_NDPA_EN | B_AX_BFMEE_VHT_NDPA_EN |
5166                    B_AX_BFMEE_HE_NDPA_EN;
5167
5168         rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee ndpa_en to %d\n", en);
5169         reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx);
5170         if (en) {
5171                 set_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags);
5172                 rtw89_write32_set(rtwdev, reg, mask);
5173         } else {
5174                 clear_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags);
5175                 rtw89_write32_clr(rtwdev, reg, mask);
5176         }
5177 }
5178
5179 static int rtw89_mac_init_bfee(struct rtw89_dev *rtwdev, u8 mac_idx)
5180 {
5181         u32 reg;
5182         u32 val32;
5183         int ret;
5184
5185         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
5186         if (ret)
5187                 return ret;
5188
5189         /* AP mode set tx gid to 63 */
5190         /* STA mode set tx gid to 0(default) */
5191         reg = rtw89_mac_reg_by_idx(R_AX_BFMER_CTRL_0, mac_idx);
5192         rtw89_write32_set(rtwdev, reg, B_AX_BFMER_NDP_BFEN);
5193
5194         reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx);
5195         rtw89_write32(rtwdev, reg, CSI_RRSC_BMAP);
5196
5197         reg = rtw89_mac_reg_by_idx(R_AX_BFMEE_RESP_OPTION, mac_idx);
5198         val32 = FIELD_PREP(B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK, NDP_RX_STANDBY_TIMER);
5199         rtw89_write32(rtwdev, reg, val32);
5200         rtw89_mac_bfee_standby_timer(rtwdev, mac_idx, true);
5201         rtw89_mac_bfee_ctrl(rtwdev, mac_idx, true);
5202
5203         reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
5204         rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL |
5205                                        B_AX_BFMEE_USE_NSTS |
5206                                        B_AX_BFMEE_CSI_GID_SEL |
5207                                        B_AX_BFMEE_CSI_FORCE_RETE_EN);
5208         reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RATE, mac_idx);
5209         rtw89_write32(rtwdev, reg,
5210                       u32_encode_bits(CSI_INIT_RATE_HT, B_AX_BFMEE_HT_CSI_RATE_MASK) |
5211                       u32_encode_bits(CSI_INIT_RATE_VHT, B_AX_BFMEE_VHT_CSI_RATE_MASK) |
5212                       u32_encode_bits(CSI_INIT_RATE_HE, B_AX_BFMEE_HE_CSI_RATE_MASK));
5213
5214         reg = rtw89_mac_reg_by_idx(R_AX_CSIRPT_OPTION, mac_idx);
5215         rtw89_write32_set(rtwdev, reg,
5216                           B_AX_CSIPRT_VHTSU_AID_EN | B_AX_CSIPRT_HESU_AID_EN);
5217
5218         return 0;
5219 }
5220
5221 static int rtw89_mac_set_csi_para_reg(struct rtw89_dev *rtwdev,
5222                                       struct ieee80211_vif *vif,
5223                                       struct ieee80211_sta *sta)
5224 {
5225         struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
5226         u8 mac_idx = rtwvif->mac_idx;
5227         u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1;
5228         u8 port_sel = rtwvif->port;
5229         u8 sound_dim = 3, t;
5230         u8 *phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info;
5231         u32 reg;
5232         u16 val;
5233         int ret;
5234
5235         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
5236         if (ret)
5237                 return ret;
5238
5239         if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
5240             (phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) {
5241                 ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD);
5242                 stbc_en &= !!(phy_cap[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ);
5243                 t = FIELD_GET(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,
5244                               phy_cap[5]);
5245                 sound_dim = min(sound_dim, t);
5246         }
5247         if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
5248             (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
5249                 ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
5250                 stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
5251                 t = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
5252                               sta->deflink.vht_cap.cap);
5253                 sound_dim = min(sound_dim, t);
5254         }
5255         nc = min(nc, sound_dim);
5256         nr = min(nr, sound_dim);
5257
5258         reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
5259         rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL);
5260
5261         val = FIELD_PREP(B_AX_BFMEE_CSIINFO0_NC_MASK, nc) |
5262               FIELD_PREP(B_AX_BFMEE_CSIINFO0_NR_MASK, nr) |
5263               FIELD_PREP(B_AX_BFMEE_CSIINFO0_NG_MASK, ng) |
5264               FIELD_PREP(B_AX_BFMEE_CSIINFO0_CB_MASK, cb) |
5265               FIELD_PREP(B_AX_BFMEE_CSIINFO0_CS_MASK, cs) |
5266               FIELD_PREP(B_AX_BFMEE_CSIINFO0_LDPC_EN, ldpc_en) |
5267               FIELD_PREP(B_AX_BFMEE_CSIINFO0_STBC_EN, stbc_en);
5268
5269         if (port_sel == 0)
5270                 reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
5271         else
5272                 reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_1, mac_idx);
5273
5274         rtw89_write16(rtwdev, reg, val);
5275
5276         return 0;
5277 }
5278
5279 static int rtw89_mac_csi_rrsc(struct rtw89_dev *rtwdev,
5280                               struct ieee80211_vif *vif,
5281                               struct ieee80211_sta *sta)
5282 {
5283         struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
5284         u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M);
5285         u32 reg;
5286         u8 mac_idx = rtwvif->mac_idx;
5287         int ret;
5288
5289         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
5290         if (ret)
5291                 return ret;
5292
5293         if (sta->deflink.he_cap.has_he) {
5294                 rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) |
5295                          BIT(RTW89_MAC_BF_RRSC_HE_MSC3) |
5296                          BIT(RTW89_MAC_BF_RRSC_HE_MSC5));
5297         }
5298         if (sta->deflink.vht_cap.vht_supported) {
5299                 rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) |
5300                          BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) |
5301                          BIT(RTW89_MAC_BF_RRSC_VHT_MSC5));
5302         }
5303         if (sta->deflink.ht_cap.ht_supported) {
5304                 rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) |
5305                          BIT(RTW89_MAC_BF_RRSC_HT_MSC3) |
5306                          BIT(RTW89_MAC_BF_RRSC_HT_MSC5));
5307         }
5308         reg = rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
5309         rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL);
5310         rtw89_write32_clr(rtwdev, reg, B_AX_BFMEE_CSI_FORCE_RETE_EN);
5311         rtw89_write32(rtwdev,
5312                       rtw89_mac_reg_by_idx(R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx),
5313                       rrsc);
5314
5315         return 0;
5316 }
5317
5318 void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
5319                         struct ieee80211_sta *sta)
5320 {
5321         struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
5322
5323         if (rtw89_sta_has_beamformer_cap(sta)) {
5324                 rtw89_debug(rtwdev, RTW89_DBG_BF,
5325                             "initialize bfee for new association\n");
5326                 rtw89_mac_init_bfee(rtwdev, rtwvif->mac_idx);
5327                 rtw89_mac_set_csi_para_reg(rtwdev, vif, sta);
5328                 rtw89_mac_csi_rrsc(rtwdev, vif, sta);
5329         }
5330 }
5331
5332 void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
5333                            struct ieee80211_sta *sta)
5334 {
5335         struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
5336
5337         rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, false);
5338 }
5339
5340 void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
5341                                 struct ieee80211_bss_conf *conf)
5342 {
5343         struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
5344         u8 mac_idx = rtwvif->mac_idx;
5345         __le32 *p;
5346
5347         rtw89_debug(rtwdev, RTW89_DBG_BF, "update bf GID table\n");
5348
5349         p = (__le32 *)conf->mu_group.membership;
5350         rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION_EN0, mac_idx),
5351                       le32_to_cpu(p[0]));
5352         rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION_EN1, mac_idx),
5353                       le32_to_cpu(p[1]));
5354
5355         p = (__le32 *)conf->mu_group.position;
5356         rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION0, mac_idx),
5357                       le32_to_cpu(p[0]));
5358         rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION1, mac_idx),
5359                       le32_to_cpu(p[1]));
5360         rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION2, mac_idx),
5361                       le32_to_cpu(p[2]));
5362         rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(R_AX_GID_POSITION3, mac_idx),
5363                       le32_to_cpu(p[3]));
5364 }
5365
5366 struct rtw89_mac_bf_monitor_iter_data {
5367         struct rtw89_dev *rtwdev;
5368         struct ieee80211_sta *down_sta;
5369         int count;
5370 };
5371
5372 static
5373 void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta)
5374 {
5375         struct rtw89_mac_bf_monitor_iter_data *iter_data =
5376                                 (struct rtw89_mac_bf_monitor_iter_data *)data;
5377         struct ieee80211_sta *down_sta = iter_data->down_sta;
5378         int *count = &iter_data->count;
5379
5380         if (down_sta == sta)
5381                 return;
5382
5383         if (rtw89_sta_has_beamformer_cap(sta))
5384                 (*count)++;
5385 }
5386
5387 void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev,
5388                                struct ieee80211_sta *sta, bool disconnect)
5389 {
5390         struct rtw89_mac_bf_monitor_iter_data data;
5391
5392         data.rtwdev = rtwdev;
5393         data.down_sta = disconnect ? sta : NULL;
5394         data.count = 0;
5395         ieee80211_iterate_stations_atomic(rtwdev->hw,
5396                                           rtw89_mac_bf_monitor_calc_iter,
5397                                           &data);
5398
5399         rtw89_debug(rtwdev, RTW89_DBG_BF, "bfee STA count=%d\n", data.count);
5400         if (data.count)
5401                 set_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags);
5402         else
5403                 clear_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags);
5404 }
5405
5406 void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
5407 {
5408         struct rtw89_traffic_stats *stats = &rtwdev->stats;
5409         struct rtw89_vif *rtwvif;
5410         bool en = stats->tx_tfc_lv <= stats->rx_tfc_lv;
5411         bool old = test_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags);
5412         bool keep_timer = true;
5413         bool old_keep_timer;
5414
5415         old_keep_timer = test_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags);
5416
5417         if (stats->tx_tfc_lv <= RTW89_TFC_LOW && stats->rx_tfc_lv <= RTW89_TFC_LOW)
5418                 keep_timer = false;
5419
5420         if (keep_timer != old_keep_timer) {
5421                 rtw89_for_each_rtwvif(rtwdev, rtwvif)
5422                         rtw89_mac_bfee_standby_timer(rtwdev, rtwvif->mac_idx,
5423                                                      keep_timer);
5424         }
5425
5426         if (en == old)
5427                 return;
5428
5429         rtw89_for_each_rtwvif(rtwdev, rtwvif)
5430                 rtw89_mac_bfee_ctrl(rtwdev, rtwvif->mac_idx, en);
5431 }
5432
5433 static int
5434 __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
5435                         u32 tx_time)
5436 {
5437 #define MAC_AX_DFLT_TX_TIME 5280
5438         u8 mac_idx = rtwsta->rtwvif->mac_idx;
5439         u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time;
5440         u32 reg;
5441         int ret = 0;
5442
5443         if (rtwsta->cctl_tx_time) {
5444                 rtwsta->ampdu_max_time = (max_tx_time - 512) >> 9;
5445                 ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta);
5446         } else {
5447                 ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
5448                 if (ret) {
5449                         rtw89_warn(rtwdev, "failed to check cmac in set txtime\n");
5450                         return ret;
5451                 }
5452
5453                 reg = rtw89_mac_reg_by_idx(R_AX_AMPDU_AGG_LIMIT, mac_idx);
5454                 rtw89_write32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK,
5455                                    max_tx_time >> 5);
5456         }
5457
5458         return ret;
5459 }
5460
5461 int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
5462                           bool resume, u32 tx_time)
5463 {
5464         int ret = 0;
5465
5466         if (!resume) {
5467                 rtwsta->cctl_tx_time = true;
5468                 ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time);
5469         } else {
5470                 ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta, tx_time);
5471                 rtwsta->cctl_tx_time = false;
5472         }
5473
5474         return ret;
5475 }
5476
5477 int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
5478                           u32 *tx_time)
5479 {
5480         u8 mac_idx = rtwsta->rtwvif->mac_idx;
5481         u32 reg;
5482         int ret = 0;
5483
5484         if (rtwsta->cctl_tx_time) {
5485                 *tx_time = (rtwsta->ampdu_max_time + 1) << 9;
5486         } else {
5487                 ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
5488                 if (ret) {
5489                         rtw89_warn(rtwdev, "failed to check cmac in tx_time\n");
5490                         return ret;
5491                 }
5492
5493                 reg = rtw89_mac_reg_by_idx(R_AX_AMPDU_AGG_LIMIT, mac_idx);
5494                 *tx_time = rtw89_read32_mask(rtwdev, reg, B_AX_AMPDU_MAX_TIME_MASK) << 5;
5495         }
5496
5497         return ret;
5498 }
5499
5500 int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
5501                                  struct rtw89_sta *rtwsta,
5502                                  bool resume, u8 tx_retry)
5503 {
5504         int ret = 0;
5505
5506         rtwsta->data_tx_cnt_lmt = tx_retry;
5507
5508         if (!resume) {
5509                 rtwsta->cctl_tx_retry_limit = true;
5510                 ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta);
5511         } else {
5512                 ret = rtw89_fw_h2c_txtime_cmac_tbl(rtwdev, rtwsta);
5513                 rtwsta->cctl_tx_retry_limit = false;
5514         }
5515
5516         return ret;
5517 }
5518
5519 int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
5520                                  struct rtw89_sta *rtwsta, u8 *tx_retry)
5521 {
5522         u8 mac_idx = rtwsta->rtwvif->mac_idx;
5523         u32 reg;
5524         int ret = 0;
5525
5526         if (rtwsta->cctl_tx_retry_limit) {
5527                 *tx_retry = rtwsta->data_tx_cnt_lmt;
5528         } else {
5529                 ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
5530                 if (ret) {
5531                         rtw89_warn(rtwdev, "failed to check cmac in rty_lmt\n");
5532                         return ret;
5533                 }
5534
5535                 reg = rtw89_mac_reg_by_idx(R_AX_TXCNT, mac_idx);
5536                 *tx_retry = rtw89_read32_mask(rtwdev, reg, B_AX_L_TXCNT_LMT_MASK);
5537         }
5538
5539         return ret;
5540 }
5541
5542 int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
5543                                  struct rtw89_vif *rtwvif, bool en)
5544 {
5545         u8 mac_idx = rtwvif->mac_idx;
5546         u16 set = B_AX_MUEDCA_EN_0 | B_AX_SET_MUEDCATIMER_TF_0;
5547         u32 reg;
5548         u32 ret;
5549
5550         ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
5551         if (ret)
5552                 return ret;
5553
5554         reg = rtw89_mac_reg_by_idx(R_AX_MUEDCA_EN, mac_idx);
5555         if (en)
5556                 rtw89_write16_set(rtwdev, reg, set);
5557         else
5558                 rtw89_write16_clr(rtwdev, reg, set);
5559
5560         return 0;
5561 }
5562
5563 int rtw89_mac_write_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask)
5564 {
5565         u32 val32;
5566         int ret;
5567
5568         val32 = FIELD_PREP(B_AX_WL_XTAL_SI_ADDR_MASK, offset) |
5569                 FIELD_PREP(B_AX_WL_XTAL_SI_DATA_MASK, val) |
5570                 FIELD_PREP(B_AX_WL_XTAL_SI_BITMASK_MASK, mask) |
5571                 FIELD_PREP(B_AX_WL_XTAL_SI_MODE_MASK, XTAL_SI_NORMAL_WRITE) |
5572                 FIELD_PREP(B_AX_WL_XTAL_SI_CMD_POLL, 1);
5573         rtw89_write32(rtwdev, R_AX_WLAN_XTAL_SI_CTRL, val32);
5574
5575         ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_WL_XTAL_SI_CMD_POLL),
5576                                 50, 50000, false, rtwdev, R_AX_WLAN_XTAL_SI_CTRL);
5577         if (ret) {
5578                 rtw89_warn(rtwdev, "xtal si not ready(W): offset=%x val=%x mask=%x\n",
5579                            offset, val, mask);
5580                 return ret;
5581         }
5582
5583         return 0;
5584 }
5585 EXPORT_SYMBOL(rtw89_mac_write_xtal_si);
5586
5587 int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
5588 {
5589         u32 val32;
5590         int ret;
5591
5592         val32 = FIELD_PREP(B_AX_WL_XTAL_SI_ADDR_MASK, offset) |
5593                 FIELD_PREP(B_AX_WL_XTAL_SI_DATA_MASK, 0x00) |
5594                 FIELD_PREP(B_AX_WL_XTAL_SI_BITMASK_MASK, 0x00) |
5595                 FIELD_PREP(B_AX_WL_XTAL_SI_MODE_MASK, XTAL_SI_NORMAL_READ) |
5596                 FIELD_PREP(B_AX_WL_XTAL_SI_CMD_POLL, 1);
5597         rtw89_write32(rtwdev, R_AX_WLAN_XTAL_SI_CTRL, val32);
5598
5599         ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_WL_XTAL_SI_CMD_POLL),
5600                                 50, 50000, false, rtwdev, R_AX_WLAN_XTAL_SI_CTRL);
5601         if (ret) {
5602                 rtw89_warn(rtwdev, "xtal si not ready(R): offset=%x\n", offset);
5603                 return ret;
5604         }
5605
5606         *val = rtw89_read8(rtwdev, R_AX_WLAN_XTAL_SI_CTRL + 1);
5607
5608         return 0;
5609 }
5610 EXPORT_SYMBOL(rtw89_mac_read_xtal_si);
5611
5612 static
5613 void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
5614 {
5615         static const enum rtw89_pkt_drop_sel sels[] = {
5616                 RTW89_PKT_DROP_SEL_MACID_BE_ONCE,
5617                 RTW89_PKT_DROP_SEL_MACID_BK_ONCE,
5618                 RTW89_PKT_DROP_SEL_MACID_VI_ONCE,
5619                 RTW89_PKT_DROP_SEL_MACID_VO_ONCE,
5620         };
5621         struct rtw89_vif *rtwvif = rtwsta->rtwvif;
5622         struct rtw89_pkt_drop_params params = {0};
5623         int i;
5624
5625         params.mac_band = RTW89_MAC_0;
5626         params.macid = rtwsta->mac_id;
5627         params.port = rtwvif->port;
5628         params.mbssid = 0;
5629         params.tf_trs = rtwvif->trigger;
5630
5631         for (i = 0; i < ARRAY_SIZE(sels); i++) {
5632                 params.sel = sels[i];
5633                 rtw89_fw_h2c_pkt_drop(rtwdev, &params);
5634         }
5635 }
5636
5637 static void rtw89_mac_pkt_drop_vif_iter(void *data, struct ieee80211_sta *sta)
5638 {
5639         struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
5640         struct rtw89_vif *rtwvif = rtwsta->rtwvif;
5641         struct rtw89_dev *rtwdev = rtwvif->rtwdev;
5642         struct rtw89_vif *target = data;
5643
5644         if (rtwvif != target)
5645                 return;
5646
5647         rtw89_mac_pkt_drop_sta(rtwdev, rtwsta);
5648 }
5649
5650 void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
5651 {
5652         ieee80211_iterate_stations_atomic(rtwdev->hw,
5653                                           rtw89_mac_pkt_drop_vif_iter,
5654                                           rtwvif);
5655 }
5656
5657 int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
5658                                         enum rtw89_mac_idx band)
5659 {
5660         struct rtw89_pkt_drop_params params = {0};
5661         bool empty;
5662         int i, ret = 0, try_cnt = 3;
5663
5664         params.mac_band = band;
5665         params.sel = RTW89_PKT_DROP_SEL_BAND_ONCE;
5666
5667         for (i = 0; i < try_cnt; i++) {
5668                 ret = read_poll_timeout(mac_is_txq_empty, empty, empty, 50,
5669                                         50000, false, rtwdev);
5670                 if (ret && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw))
5671                         rtw89_fw_h2c_pkt_drop(rtwdev, &params);
5672                 else
5673                         return 0;
5674         }
5675         return ret;
5676 }