cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mac.c (131011B)


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