File Index
Files and directories
Sign in
FILE

mac.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/realtek/rtw89/mac.c C
   1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
   2/* Copyright(c) 2019-2020  Realtek Corporation
   3 */
   4
   5#include "cam.h"
   6#include "chan.h"
   7#include "debug.h"
   8#include "efuse.h"
   9#include "fw.h"
  10#include "mac.h"
  11#include "pci.h"
  12#include "phy.h"
  13#include "ps.h"
  14#include "reg.h"
  15#include "ser.h"
  16#include "util.h"
  17
  18static const u32 rtw89_mac_mem_base_addrs_ax[RTW89_MAC_MEM_NUM] = {
  19	[RTW89_MAC_MEM_AXIDMA]	        = AXIDMA_BASE_ADDR,
  20	[RTW89_MAC_MEM_SHARED_BUF]	= SHARED_BUF_BASE_ADDR,
  21	[RTW89_MAC_MEM_DMAC_TBL]	= DMAC_TBL_BASE_ADDR,
  22	[RTW89_MAC_MEM_SHCUT_MACHDR]	= SHCUT_MACHDR_BASE_ADDR,
  23	[RTW89_MAC_MEM_STA_SCHED]	= STA_SCHED_BASE_ADDR,
  24	[RTW89_MAC_MEM_RXPLD_FLTR_CAM]	= RXPLD_FLTR_CAM_BASE_ADDR,
  25	[RTW89_MAC_MEM_SECURITY_CAM]	= SECURITY_CAM_BASE_ADDR,
  26	[RTW89_MAC_MEM_WOW_CAM]		= WOW_CAM_BASE_ADDR,
  27	[RTW89_MAC_MEM_CMAC_TBL]	= CMAC_TBL_BASE_ADDR,
  28	[RTW89_MAC_MEM_ADDR_CAM]	= ADDR_CAM_BASE_ADDR,
  29	[RTW89_MAC_MEM_BA_CAM]		= BA_CAM_BASE_ADDR,
  30	[RTW89_MAC_MEM_BCN_IE_CAM0]	= BCN_IE_CAM0_BASE_ADDR,
  31	[RTW89_MAC_MEM_BCN_IE_CAM1]	= BCN_IE_CAM1_BASE_ADDR,
  32	[RTW89_MAC_MEM_TXD_FIFO_0]	= TXD_FIFO_0_BASE_ADDR,
  33	[RTW89_MAC_MEM_TXD_FIFO_1]	= TXD_FIFO_1_BASE_ADDR,
  34	[RTW89_MAC_MEM_TXDATA_FIFO_0]	= TXDATA_FIFO_0_BASE_ADDR,
  35	[RTW89_MAC_MEM_TXDATA_FIFO_1]	= TXDATA_FIFO_1_BASE_ADDR,
  36	[RTW89_MAC_MEM_CPU_LOCAL]	= CPU_LOCAL_BASE_ADDR,
  37	[RTW89_MAC_MEM_BSSID_CAM]	= BSSID_CAM_BASE_ADDR,
  38	[RTW89_MAC_MEM_TXD_FIFO_0_V1]	= TXD_FIFO_0_BASE_ADDR_V1,
  39	[RTW89_MAC_MEM_TXD_FIFO_1_V1]	= TXD_FIFO_1_BASE_ADDR_V1,
  40};
  41
  42static void rtw89_mac_mem_write(struct rtw89_dev *rtwdev, u32 offset,
  43				u32 val, enum rtw89_mac_mem_sel sel)
  44{
  45	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
  46	u32 addr = mac->mem_base_addrs[sel] + offset;
  47
  48	rtw89_write32(rtwdev, mac->filter_model_addr, addr);
  49	rtw89_write32(rtwdev, mac->indir_access_addr, val);
  50}
  51
  52static u32 rtw89_mac_mem_read(struct rtw89_dev *rtwdev, u32 offset,
  53			      enum rtw89_mac_mem_sel sel)
  54{
  55	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
  56	u32 addr = mac->mem_base_addrs[sel] + offset;
  57
  58	rtw89_write32(rtwdev, mac->filter_model_addr, addr);
  59	return rtw89_read32(rtwdev, mac->indir_access_addr);
  60}
  61
  62static int rtw89_mac_check_mac_en_ax(struct rtw89_dev *rtwdev, u8 mac_idx,
  63				     enum rtw89_mac_hwmod_sel sel)
  64{
  65	u32 val, r_val;
  66
  67	if (sel == RTW89_DMAC_SEL) {
  68		r_val = rtw89_read32(rtwdev, R_AX_DMAC_FUNC_EN);
  69		val = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN);
  70	} else if (sel == RTW89_CMAC_SEL && mac_idx == 0) {
  71		r_val = rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN);
  72		val = B_AX_CMAC_EN;
  73	} else if (sel == RTW89_CMAC_SEL && mac_idx == 1) {
  74		r_val = rtw89_read32(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND);
  75		val = B_AX_CMAC1_FEN;
  76	} else {
  77		return -EINVAL;
  78	}
  79	if (r_val == RTW89_R32_EA || r_val == RTW89_R32_DEAD ||
  80	    (val & r_val) != val)
  81		return -EFAULT;
  82
  83	return 0;
  84}
  85
  86int rtw89_mac_write_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 val)
  87{
  88	u8 lte_ctrl;
  89	int ret;
  90
  91	ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0,
  92				50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3);
  93	if (ret && !test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
  94		rtw89_err(rtwdev, "[ERR]lte not ready(W)\n");
  95
  96	rtw89_write32(rtwdev, R_AX_LTE_WDATA, val);
  97	rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0xC00F0000 | offset);
  98
  99	return ret;
 100}
 101
 102int rtw89_mac_read_lte(struct rtw89_dev *rtwdev, const u32 offset, u32 *val)
 103{
 104	u8 lte_ctrl;
 105	int ret;
 106
 107	ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0,
 108				50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3);
 109	if (ret && !test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
 110		rtw89_err(rtwdev, "[ERR]lte not ready(W)\n");
 111
 112	rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0x800F0000 | offset);
 113	*val = rtw89_read32(rtwdev, R_AX_LTE_RDATA);
 114
 115	return ret;
 116}
 117
 118int rtw89_mac_dle_dfi_cfg(struct rtw89_dev *rtwdev, struct rtw89_mac_dle_dfi_ctrl *ctrl)
 119{
 120	u32 ctrl_reg, data_reg, ctrl_data;
 121	u32 val;
 122	int ret;
 123
 124	switch (ctrl->type) {
 125	case DLE_CTRL_TYPE_WDE:
 126		ctrl_reg = R_AX_WDE_DBG_FUN_INTF_CTL;
 127		data_reg = R_AX_WDE_DBG_FUN_INTF_DATA;
 128		ctrl_data = FIELD_PREP(B_AX_WDE_DFI_TRGSEL_MASK, ctrl->target) |
 129			    FIELD_PREP(B_AX_WDE_DFI_ADDR_MASK, ctrl->addr) |
 130			    B_AX_WDE_DFI_ACTIVE;
 131		break;
 132	case DLE_CTRL_TYPE_PLE:
 133		ctrl_reg = R_AX_PLE_DBG_FUN_INTF_CTL;
 134		data_reg = R_AX_PLE_DBG_FUN_INTF_DATA;
 135		ctrl_data = FIELD_PREP(B_AX_PLE_DFI_TRGSEL_MASK, ctrl->target) |
 136			    FIELD_PREP(B_AX_PLE_DFI_ADDR_MASK, ctrl->addr) |
 137			    B_AX_PLE_DFI_ACTIVE;
 138		break;
 139	default:
 140		rtw89_warn(rtwdev, "[ERR] dfi ctrl type %d\n", ctrl->type);
 141		return -EINVAL;
 142	}
 143
 144	rtw89_write32(rtwdev, ctrl_reg, ctrl_data);
 145
 146	ret = read_poll_timeout_atomic(rtw89_read32, val, !(val & B_AX_WDE_DFI_ACTIVE),
 147				       1, 1000, false, rtwdev, ctrl_reg);
 148	if (ret) {
 149		rtw89_warn(rtwdev, "[ERR] dle dfi ctrl 0x%X set 0x%X timeout\n",
 150			   ctrl_reg, ctrl_data);
 151		return ret;
 152	}
 153
 154	ctrl->out_data = rtw89_read32(rtwdev, data_reg);
 155	return 0;
 156}
 157
 158int rtw89_mac_dle_dfi_quota_cfg(struct rtw89_dev *rtwdev,
 159				struct rtw89_mac_dle_dfi_quota *quota)
 160{
 161	struct rtw89_mac_dle_dfi_ctrl ctrl;
 162	int ret;
 163
 164	ctrl.type = quota->dle_type;
 165	ctrl.target = DLE_DFI_TYPE_QUOTA;
 166	ctrl.addr = quota->qtaid;
 167	ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl);
 168	if (ret) {
 169		rtw89_warn(rtwdev, "[ERR] dle dfi quota %d\n", ret);
 170		return ret;
 171	}
 172
 173	quota->rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, ctrl.out_data);
 174	quota->use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, ctrl.out_data);
 175	return 0;
 176}
 177
 178int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev,
 179				 struct rtw89_mac_dle_dfi_qempty *qempty)
 180{
 181	struct rtw89_mac_dle_dfi_ctrl ctrl;
 182	int ret;
 183
 184	ctrl.type = qempty->dle_type;
 185	ctrl.target = DLE_DFI_TYPE_QEMPTY;
 186	ctrl.addr = qempty->grpsel;
 187	ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl);
 188	if (ret) {
 189		rtw89_warn(rtwdev, "[ERR] dle dfi qempty %d\n", ret);
 190		return ret;
 191	}
 192
 193	qempty->qempty = FIELD_GET(B_AX_DLE_QEMPTY_GRP, ctrl.out_data);
 194	return 0;
 195}
 196
 197static void dump_err_status_dispatcher_ax(struct rtw89_dev *rtwdev)
 198{
 199	rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_IMR=0x%08x ",
 200		   rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
 201	rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ALWAYS_ISR=0x%08x\n",
 202		   rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR));
 203	rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ALWAYS_IMR=0x%08x ",
 204		   rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR));
 205	rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ALWAYS_ISR=0x%08x\n",
 206		   rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR));
 207	rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ALWAYS_IMR=0x%08x ",
 208		   rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR));
 209	rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ALWAYS_ISR=0x%08x\n",
 210		   rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
 211}
 212
 213static void rtw89_mac_dump_qta_lost_ax(struct rtw89_dev *rtwdev)
 214{
 215	struct rtw89_mac_dle_dfi_qempty qempty;
 216	struct rtw89_mac_dle_dfi_quota quota;
 217	struct rtw89_mac_dle_dfi_ctrl ctrl;
 218	u32 val, not_empty, i;
 219	int ret;
 220
 221	qempty.dle_type = DLE_CTRL_TYPE_PLE;
 222	qempty.grpsel = 0;
 223	qempty.qempty = ~(u32)0;
 224	ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
 225	if (ret)
 226		rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
 227	else
 228		rtw89_info(rtwdev, "DLE group0 empty: 0x%x\n", qempty.qempty);
 229
 230	for (not_empty = ~qempty.qempty, i = 0; not_empty != 0; not_empty >>= 1, i++) {
 231		if (!(not_empty & BIT(0)))
 232			continue;
 233		ctrl.type = DLE_CTRL_TYPE_PLE;
 234		ctrl.target = DLE_DFI_TYPE_QLNKTBL;
 235		ctrl.addr = (QLNKTBL_ADDR_INFO_SEL_0 ? QLNKTBL_ADDR_INFO_SEL : 0) |
 236			    u32_encode_bits(i, QLNKTBL_ADDR_TBL_IDX_MASK);
 237		ret = rtw89_mac_dle_dfi_cfg(rtwdev, &ctrl);
 238		if (ret)
 239			rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
 240		else
 241			rtw89_info(rtwdev, "qidx%d pktcnt = %d\n", i,
 242				   u32_get_bits(ctrl.out_data,
 243						QLNKTBL_DATA_SEL1_PKT_CNT_MASK));
 244	}
 245
 246	quota.dle_type = DLE_CTRL_TYPE_PLE;
 247	quota.qtaid = 6;
 248	ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, &quota);
 249	if (ret)
 250		rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
 251	else
 252		rtw89_info(rtwdev, "quota6 rsv/use: 0x%x/0x%x\n",
 253			   quota.rsv_pgnum, quota.use_pgnum);
 254
 255	val = rtw89_read32(rtwdev, R_AX_PLE_QTA6_CFG);
 256	rtw89_info(rtwdev, "[PLE][CMAC0_RX]min_pgnum=0x%x\n",
 257		   u32_get_bits(val, B_AX_PLE_Q6_MIN_SIZE_MASK));
 258	rtw89_info(rtwdev, "[PLE][CMAC0_RX]max_pgnum=0x%x\n",
 259		   u32_get_bits(val, B_AX_PLE_Q6_MAX_SIZE_MASK));
 260	val = rtw89_read32(rtwdev, R_AX_RX_FLTR_OPT);
 261	rtw89_info(rtwdev, "[PLE][CMAC0_RX]B_AX_RX_MPDU_MAX_LEN=0x%x\n",
 262		   u32_get_bits(val, B_AX_RX_MPDU_MAX_LEN_MASK));
 263	rtw89_info(rtwdev, "R_AX_RSP_CHK_SIG=0x%08x\n",
 264		   rtw89_read32(rtwdev, R_AX_RSP_CHK_SIG));
 265	rtw89_info(rtwdev, "R_AX_TRXPTCL_RESP_0=0x%08x\n",
 266		   rtw89_read32(rtwdev, R_AX_TRXPTCL_RESP_0));
 267	rtw89_info(rtwdev, "R_AX_CCA_CONTROL=0x%08x\n",
 268		   rtw89_read32(rtwdev, R_AX_CCA_CONTROL));
 269
 270	if (!rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL)) {
 271		quota.dle_type = DLE_CTRL_TYPE_PLE;
 272		quota.qtaid = 7;
 273		ret = rtw89_mac_dle_dfi_quota_cfg(rtwdev, &quota);
 274		if (ret)
 275			rtw89_warn(rtwdev, "%s: query DLE fail\n", __func__);
 276		else
 277			rtw89_info(rtwdev, "quota7 rsv/use: 0x%x/0x%x\n",
 278				   quota.rsv_pgnum, quota.use_pgnum);
 279
 280		val = rtw89_read32(rtwdev, R_AX_PLE_QTA7_CFG);
 281		rtw89_info(rtwdev, "[PLE][CMAC1_RX]min_pgnum=0x%x\n",
 282			   u32_get_bits(val, B_AX_PLE_Q7_MIN_SIZE_MASK));
 283		rtw89_info(rtwdev, "[PLE][CMAC1_RX]max_pgnum=0x%x\n",
 284			   u32_get_bits(val, B_AX_PLE_Q7_MAX_SIZE_MASK));
 285		val = rtw89_read32(rtwdev, R_AX_RX_FLTR_OPT_C1);
 286		rtw89_info(rtwdev, "[PLE][CMAC1_RX]B_AX_RX_MPDU_MAX_LEN=0x%x\n",
 287			   u32_get_bits(val, B_AX_RX_MPDU_MAX_LEN_MASK));
 288		rtw89_info(rtwdev, "R_AX_RSP_CHK_SIG_C1=0x%08x\n",
 289			   rtw89_read32(rtwdev, R_AX_RSP_CHK_SIG_C1));
 290		rtw89_info(rtwdev, "R_AX_TRXPTCL_RESP_0_C1=0x%08x\n",
 291			   rtw89_read32(rtwdev, R_AX_TRXPTCL_RESP_0_C1));
 292		rtw89_info(rtwdev, "R_AX_CCA_CONTROL_C1=0x%08x\n",
 293			   rtw89_read32(rtwdev, R_AX_CCA_CONTROL_C1));
 294	}
 295
 296	rtw89_info(rtwdev, "R_AX_DLE_EMPTY0=0x%08x\n",
 297		   rtw89_read32(rtwdev, R_AX_DLE_EMPTY0));
 298	rtw89_info(rtwdev, "R_AX_DLE_EMPTY1=0x%08x\n",
 299		   rtw89_read32(rtwdev, R_AX_DLE_EMPTY1));
 300
 301	dump_err_status_dispatcher_ax(rtwdev);
 302}
 303
 304void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev,
 305			     enum mac_ax_err_info err)
 306{
 307	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
 308	u32 dbg, event;
 309
 310	dbg = rtw89_read32(rtwdev, R_AX_SER_DBG_INFO);
 311	event = u32_get_bits(dbg, B_AX_L0_TO_L1_EVENT_MASK);
 312
 313	switch (event) {
 314	case MAC_AX_L0_TO_L1_RX_QTA_LOST:
 315		rtw89_info(rtwdev, "quota lost!\n");
 316		mac->dump_qta_lost(rtwdev);
 317		break;
 318	default:
 319		break;
 320	}
 321}
 322
 323void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev)
 324{
 325	const struct rtw89_chip_info *chip = rtwdev->chip;
 326	u32 dmac_err;
 327	int i, ret;
 328
 329	ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);
 330	if (ret) {
 331		rtw89_warn(rtwdev, "[DMAC] : DMAC not enabled\n");
 332		return;
 333	}
 334
 335	dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR);
 336	rtw89_info(rtwdev, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err);
 337	rtw89_info(rtwdev, "R_AX_DMAC_ERR_IMR=0x%08x\n",
 338		   rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR));
 339
 340	if (dmac_err) {
 341		rtw89_info(rtwdev, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n",
 342			   rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1));
 343		rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n",
 344			   rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1));
 345		if (chip->chip_id == RTL8852C) {
 346			rtw89_info(rtwdev, "R_AX_PLE_ERRFLAG_MSG=0x%08x\n",
 347				   rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG));
 348			rtw89_info(rtwdev, "R_AX_WDE_ERRFLAG_MSG=0x%08x\n",
 349				   rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG));
 350			rtw89_info(rtwdev, "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n",
 351				   rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN));
 352			rtw89_info(rtwdev, "R_AX_PLE_DBGERR_STS=0x%08x\n",
 353				   rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS));
 354		}
 355	}
 356
 357	if (dmac_err & B_AX_WDRLS_ERR_FLAG) {
 358		rtw89_info(rtwdev, "R_AX_WDRLS_ERR_IMR=0x%08x\n",
 359			   rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR));
 360		rtw89_info(rtwdev, "R_AX_WDRLS_ERR_ISR=0x%08x\n",
 361			   rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR));
 362		if (chip->chip_id == RTL8852C)
 363			rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX=0x%08x\n",
 364				   rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1));
 365		else
 366			rtw89_info(rtwdev, "R_AX_RPQ_RXBD_IDX=0x%08x\n",
 367				   rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX));
 368	}
 369
 370	if (dmac_err & B_AX_WSEC_ERR_FLAG) {
 371		if (chip->chip_id == RTL8852C) {
 372			rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR=0x%08x\n",
 373				   rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR));
 374			rtw89_info(rtwdev, "R_AX_SEC_ERR_ISR=0x%08x\n",
 375				   rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG));
 376			rtw89_info(rtwdev, "R_AX_SEC_ENG_CTRL=0x%08x\n",
 377				   rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
 378			rtw89_info(rtwdev, "R_AX_SEC_MPDU_PROC=0x%08x\n",
 379				   rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
 380			rtw89_info(rtwdev, "R_AX_SEC_CAM_ACCESS=0x%08x\n",
 381				   rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
 382			rtw89_info(rtwdev, "R_AX_SEC_CAM_RDATA=0x%08x\n",
 383				   rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
 384			rtw89_info(rtwdev, "R_AX_SEC_DEBUG1=0x%08x\n",
 385				   rtw89_read32(rtwdev, R_AX_SEC_DEBUG1));
 386			rtw89_info(rtwdev, "R_AX_SEC_TX_DEBUG=0x%08x\n",
 387				   rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
 388			rtw89_info(rtwdev, "R_AX_SEC_RX_DEBUG=0x%08x\n",
 389				   rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
 390
 391			rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
 392					   B_AX_DBG_SEL0, 0x8B);
 393			rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
 394					   B_AX_DBG_SEL1, 0x8B);
 395			rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1,
 396					   B_AX_SEL_0XC0_MASK, 1);
 397			for (i = 0; i < 0x10; i++) {
 398				rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL,
 399						   B_AX_SEC_DBG_PORT_FIELD_MASK, i);
 400				rtw89_info(rtwdev, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n",
 401					   i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2));
 402			}
 403		} else if (chip->chip_id == RTL8922A) {
 404			rtw89_info(rtwdev, "R_BE_SEC_ERROR_FLAG=0x%08x\n",
 405				   rtw89_read32(rtwdev, R_BE_SEC_ERROR_FLAG));
 406			rtw89_info(rtwdev, "R_BE_SEC_ERROR_IMR=0x%08x\n",
 407				   rtw89_read32(rtwdev, R_BE_SEC_ERROR_IMR));
 408			rtw89_info(rtwdev, "R_BE_SEC_ENG_CTRL=0x%08x\n",
 409				   rtw89_read32(rtwdev, R_BE_SEC_ENG_CTRL));
 410			rtw89_info(rtwdev, "R_BE_SEC_MPDU_PROC=0x%08x\n",
 411				   rtw89_read32(rtwdev, R_BE_SEC_MPDU_PROC));
 412			rtw89_info(rtwdev, "R_BE_SEC_CAM_ACCESS=0x%08x\n",
 413				   rtw89_read32(rtwdev, R_BE_SEC_CAM_ACCESS));
 414			rtw89_info(rtwdev, "R_BE_SEC_CAM_RDATA=0x%08x\n",
 415				   rtw89_read32(rtwdev, R_BE_SEC_CAM_RDATA));
 416			rtw89_info(rtwdev, "R_BE_SEC_DEBUG2=0x%08x\n",
 417				   rtw89_read32(rtwdev, R_BE_SEC_DEBUG2));
 418		} else {
 419			rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n",
 420				   rtw89_read32(rtwdev, R_AX_SEC_DEBUG));
 421			rtw89_info(rtwdev, "R_AX_SEC_ENG_CTRL=0x%08x\n",
 422				   rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
 423			rtw89_info(rtwdev, "R_AX_SEC_MPDU_PROC=0x%08x\n",
 424				   rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
 425			rtw89_info(rtwdev, "R_AX_SEC_CAM_ACCESS=0x%08x\n",
 426				   rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
 427			rtw89_info(rtwdev, "R_AX_SEC_CAM_RDATA=0x%08x\n",
 428				   rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
 429			rtw89_info(rtwdev, "R_AX_SEC_CAM_WDATA=0x%08x\n",
 430				   rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA));
 431			rtw89_info(rtwdev, "R_AX_SEC_TX_DEBUG=0x%08x\n",
 432				   rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
 433			rtw89_info(rtwdev, "R_AX_SEC_RX_DEBUG=0x%08x\n",
 434				   rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
 435			rtw89_info(rtwdev, "R_AX_SEC_TRX_PKT_CNT=0x%08x\n",
 436				   rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT));
 437			rtw89_info(rtwdev, "R_AX_SEC_TRX_BLK_CNT=0x%08x\n",
 438				   rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT));
 439		}
 440	}
 441
 442	if (dmac_err & B_AX_MPDU_ERR_FLAG) {
 443		rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n",
 444			   rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR));
 445		rtw89_info(rtwdev, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n",
 446			   rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR));
 447		rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n",
 448			   rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR));
 449		rtw89_info(rtwdev, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n",
 450			   rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR));
 451	}
 452
 453	if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) {
 454		if (chip->chip_id == RTL8922A) {
 455			rtw89_info(rtwdev, "R_BE_INTERRUPT_MASK_REG=0x%08x\n",
 456				   rtw89_read32(rtwdev, R_BE_INTERRUPT_MASK_REG));
 457			rtw89_info(rtwdev, "R_BE_INTERRUPT_STS_REG=0x%08x\n",
 458				   rtw89_read32(rtwdev, R_BE_INTERRUPT_STS_REG));
 459		} else {
 460			rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n",
 461				   rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR));
 462			rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n",
 463				   rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR));
 464		}
 465	}
 466
 467	if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) {
 468		rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x\n",
 469			   rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
 470		rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n",
 471			   rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
 472		rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x\n",
 473			   rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
 474		rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
 475			   rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
 476	}
 477
 478	if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) {
 479		if (chip->chip_id == RTL8852C || chip->chip_id == RTL8922A) {
 480			rtw89_info(rtwdev, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n",
 481				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR));
 482			rtw89_info(rtwdev, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n",
 483				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR));
 484			rtw89_info(rtwdev, "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n",
 485				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR));
 486			rtw89_info(rtwdev, "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n",
 487				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR));
 488		} else {
 489			rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n",
 490				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR));
 491			rtw89_info(rtwdev, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n",
 492				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1));
 493		}
 494	}
 495
 496	if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) {
 497		rtw89_info(rtwdev, "R_AX_WDE_ERR_IMR=0x%08x\n",
 498			   rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
 499		rtw89_info(rtwdev, "R_AX_WDE_ERR_ISR=0x%08x\n",
 500			   rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
 501		rtw89_info(rtwdev, "R_AX_PLE_ERR_IMR=0x%08x\n",
 502			   rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
 503		rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
 504			   rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
 505		rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_0=0x%08x\n",
 506			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0));
 507		rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_1=0x%08x\n",
 508			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1));
 509		rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_2=0x%08x\n",
 510			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2));
 511		rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_0=0x%08x\n",
 512			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0));
 513		rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_1=0x%08x\n",
 514			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1));
 515		rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_2=0x%08x\n",
 516			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2));
 517		if (chip->chip_id == RTL8922A) {
 518			rtw89_info(rtwdev, "R_BE_WD_CPUQ_OP_3=0x%08x\n",
 519				   rtw89_read32(rtwdev, R_BE_WD_CPUQ_OP_3));
 520			rtw89_info(rtwdev, "R_BE_WD_CPUQ_OP_STATUS=0x%08x\n",
 521				   rtw89_read32(rtwdev, R_BE_WD_CPUQ_OP_STATUS));
 522			rtw89_info(rtwdev, "R_BE_PLE_CPUQ_OP_3=0x%08x\n",
 523				   rtw89_read32(rtwdev, R_BE_PL_CPUQ_OP_3));
 524			rtw89_info(rtwdev, "R_BE_PL_CPUQ_OP_STATUS=0x%08x\n",
 525				   rtw89_read32(rtwdev, R_BE_PL_CPUQ_OP_STATUS));
 526		} else {
 527			rtw89_info(rtwdev, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n",
 528				   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS));
 529			rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n",
 530				   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS));
 531			if (chip->chip_id == RTL8852C) {
 532				rtw89_info(rtwdev, "R_AX_RX_CTRL0=0x%08x\n",
 533					   rtw89_read32(rtwdev, R_AX_RX_CTRL0));
 534				rtw89_info(rtwdev, "R_AX_RX_CTRL1=0x%08x\n",
 535					   rtw89_read32(rtwdev, R_AX_RX_CTRL1));
 536				rtw89_info(rtwdev, "R_AX_RX_CTRL2=0x%08x\n",
 537					   rtw89_read32(rtwdev, R_AX_RX_CTRL2));
 538			} else {
 539				rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n",
 540					   rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0));
 541				rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n",
 542					   rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1));
 543				rtw89_info(rtwdev, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n",
 544					   rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2));
 545			}
 546		}
 547	}
 548
 549	if (dmac_err & B_AX_PKTIN_ERR_FLAG) {
 550		rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR=0x%08x\n",
 551			   rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR));
 552		rtw89_info(rtwdev, "R_AX_PKTIN_ERR_ISR=0x%08x\n",
 553			   rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR));
 554	}
 555
 556	if (dmac_err & B_AX_DISPATCH_ERR_FLAG) {
 557		if (chip->chip_id == RTL8922A) {
 558			rtw89_info(rtwdev, "R_BE_DISP_HOST_IMR=0x%08x\n",
 559				   rtw89_read32(rtwdev, R_BE_DISP_HOST_IMR));
 560			rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR1=0x%08x\n",
 561				   rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR1));
 562			rtw89_info(rtwdev, "R_BE_DISP_CPU_IMR=0x%08x\n",
 563				   rtw89_read32(rtwdev, R_BE_DISP_CPU_IMR));
 564			rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR2=0x%08x\n",
 565				   rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR2));
 566			rtw89_info(rtwdev, "R_BE_DISP_OTHER_IMR=0x%08x\n",
 567				   rtw89_read32(rtwdev, R_BE_DISP_OTHER_IMR));
 568			rtw89_info(rtwdev, "R_BE_DISP_ERROR_ISR0=0x%08x\n",
 569				   rtw89_read32(rtwdev, R_BE_DISP_ERROR_ISR0));
 570		} else {
 571			rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n",
 572				   rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
 573			rtw89_info(rtwdev, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n",
 574				   rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR));
 575			rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n",
 576				   rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR));
 577			rtw89_info(rtwdev, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n",
 578				   rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR));
 579			rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n",
 580				   rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR));
 581			rtw89_info(rtwdev, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n",
 582				   rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
 583		}
 584	}
 585
 586	if (dmac_err & B_AX_BBRPT_ERR_FLAG) {
 587		if (chip->chip_id == RTL8852C || chip->chip_id == RTL8922A) {
 588			rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n",
 589				   rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR));
 590			rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n",
 591				   rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR));
 592			rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
 593				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
 594			rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
 595				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
 596			rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
 597				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
 598			rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
 599				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
 600		} else {
 601			rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n",
 602				   rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR));
 603			rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
 604				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
 605			rtw89_info(rtwdev, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
 606				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
 607			rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
 608				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
 609			rtw89_info(rtwdev, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
 610				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
 611		}
 612		if (chip->chip_id == RTL8922A) {
 613			rtw89_info(rtwdev, "R_BE_LA_ERRFLAG_IMR=0x%08x\n",
 614				   rtw89_read32(rtwdev, R_BE_LA_ERRFLAG_IMR));
 615			rtw89_info(rtwdev, "R_BE_LA_ERRFLAG_ISR=0x%08x\n",
 616				   rtw89_read32(rtwdev, R_BE_LA_ERRFLAG_ISR));
 617		}
 618	}
 619
 620	if (dmac_err & B_AX_HAXIDMA_ERR_FLAG) {
 621		if (chip->chip_id == RTL8922A) {
 622			rtw89_info(rtwdev, "R_BE_HAXI_IDCT_MSK=0x%08x\n",
 623				   rtw89_read32(rtwdev, R_BE_HAXI_IDCT_MSK));
 624			rtw89_info(rtwdev, "R_BE_HAXI_IDCT=0x%08x\n",
 625				   rtw89_read32(rtwdev, R_BE_HAXI_IDCT));
 626		} else if (chip->chip_id == RTL8852C) {
 627			rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n",
 628				   rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK));
 629			rtw89_info(rtwdev, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n",
 630				   rtw89_read32(rtwdev, R_AX_HAXI_IDCT));
 631		}
 632	}
 633
 634	if (dmac_err & B_BE_P_AXIDMA_ERR_INT) {
 635		rtw89_info(rtwdev, "R_BE_PL_AXIDMA_IDCT_MSK=0x%08x\n",
 636			   rtw89_mac_mem_read(rtwdev, R_BE_PL_AXIDMA_IDCT_MSK,
 637					      RTW89_MAC_MEM_AXIDMA));
 638		rtw89_info(rtwdev, "R_BE_PL_AXIDMA_IDCT=0x%08x\n",
 639			   rtw89_mac_mem_read(rtwdev, R_BE_PL_AXIDMA_IDCT,
 640					      RTW89_MAC_MEM_AXIDMA));
 641	}
 642
 643	if (dmac_err & B_BE_MLO_ERR_INT) {
 644		rtw89_info(rtwdev, "R_BE_MLO_ERR_IDCT_IMR=0x%08x\n",
 645			   rtw89_read32(rtwdev, R_BE_MLO_ERR_IDCT_IMR));
 646		rtw89_info(rtwdev, "R_BE_PKTIN_ERR_ISR=0x%08x\n",
 647			   rtw89_read32(rtwdev, R_BE_MLO_ERR_IDCT_ISR));
 648	}
 649
 650	if (dmac_err & B_BE_PLRLS_ERR_INT) {
 651		rtw89_info(rtwdev, "R_BE_PLRLS_ERR_IMR=0x%08x\n",
 652			   rtw89_read32(rtwdev, R_BE_PLRLS_ERR_IMR));
 653		rtw89_info(rtwdev, "R_BE_PLRLS_ERR_ISR=0x%08x\n",
 654			   rtw89_read32(rtwdev, R_BE_PLRLS_ERR_ISR));
 655	}
 656}
 657
 658static void rtw89_mac_dump_cmac_err_status_ax(struct rtw89_dev *rtwdev,
 659					      u8 band)
 660{
 661	const struct rtw89_chip_info *chip = rtwdev->chip;
 662	u32 offset = 0;
 663	u32 cmac_err;
 664	int ret;
 665
 666	ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL);
 667	if (ret) {
 668		if (band)
 669			rtw89_warn(rtwdev, "[CMAC] : CMAC1 not enabled\n");
 670		else
 671			rtw89_warn(rtwdev, "[CMAC] : CMAC0 not enabled\n");
 672		return;
 673	}
 674
 675	if (band)
 676		offset = RTW89_MAC_AX_BAND_REG_OFFSET;
 677
 678	cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset);
 679	rtw89_info(rtwdev, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band,
 680		   rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset));
 681	rtw89_info(rtwdev, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band,
 682		   rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset));
 683	rtw89_info(rtwdev, "R_AX_CK_EN [%d]=0x%08x\n", band,
 684		   rtw89_read32(rtwdev, R_AX_CK_EN + offset));
 685
 686	if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) {
 687		rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band,
 688			   rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset));
 689		rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band,
 690			   rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset));
 691	}
 692
 693	if (cmac_err & B_AX_PTCL_TOP_ERR_IND) {
 694		rtw89_info(rtwdev, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", band,
 695			   rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset));
 696		rtw89_info(rtwdev, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", band,
 697			   rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset));
 698	}
 699
 700	if (cmac_err & B_AX_DMA_TOP_ERR_IND) {
 701		if (chip->chip_id == RTL8852C) {
 702			rtw89_info(rtwdev, "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band,
 703				   rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset));
 704			rtw89_info(rtwdev, "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", band,
 705				   rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset));
 706		} else {
 707			rtw89_info(rtwdev, "R_AX_DLE_CTRL [%d]=0x%08x\n", band,
 708				   rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset));
 709		}
 710	}
 711
 712	if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) {
 713		if (chip->chip_id == RTL8852C) {
 714			rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", band,
 715				   rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset));
 716			rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band,
 717				   rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
 718		} else {
 719			rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band,
 720				   rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
 721		}
 722	}
 723
 724	if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) {
 725		rtw89_info(rtwdev, "R_AX_TXPWR_IMR [%d]=0x%08x\n", band,
 726			   rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset));
 727		rtw89_info(rtwdev, "R_AX_TXPWR_ISR [%d]=0x%08x\n", band,
 728			   rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset));
 729	}
 730
 731	if (cmac_err & B_AX_WMAC_TX_ERR_IND) {
 732		if (chip->chip_id == RTL8852C) {
 733			rtw89_info(rtwdev, "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band,
 734				   rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA + offset));
 735			rtw89_info(rtwdev, "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band,
 736				   rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA_MASK + offset));
 737		} else {
 738			rtw89_info(rtwdev, "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", band,
 739				   rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR + offset));
 740		}
 741		rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band,
 742			   rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset));
 743	}
 744
 745	rtw89_info(rtwdev, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band,
 746		   rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset));
 747}
 748
 749static void rtw89_mac_dump_err_status_ax(struct rtw89_dev *rtwdev,
 750					 enum mac_ax_err_info err)
 751{
 752	if (err != MAC_AX_ERR_L1_ERR_DMAC &&
 753	    err != MAC_AX_ERR_L0_PROMOTE_TO_L1 &&
 754	    err != MAC_AX_ERR_L0_ERR_CMAC0 &&
 755	    err != MAC_AX_ERR_L0_ERR_CMAC1 &&
 756	    err != MAC_AX_ERR_RXI300)
 757		return;
 758
 759	rtw89_info(rtwdev, "--->\nerr=0x%x\n", err);
 760	rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n",
 761		   rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
 762	rtw89_info(rtwdev, "R_AX_SER_DBG_INFO =0x%08x\n",
 763		   rtw89_read32(rtwdev, R_AX_SER_DBG_INFO));
 764	rtw89_info(rtwdev, "DBG Counter 1 (R_AX_DRV_FW_HSK_4)=0x%08x\n",
 765		   rtw89_read32(rtwdev, R_AX_DRV_FW_HSK_4));
 766	rtw89_info(rtwdev, "DBG Counter 2 (R_AX_DRV_FW_HSK_5)=0x%08x\n",
 767		   rtw89_read32(rtwdev, R_AX_DRV_FW_HSK_5));
 768
 769	rtw89_mac_dump_dmac_err_status(rtwdev);
 770	rtw89_mac_dump_cmac_err_status_ax(rtwdev, RTW89_MAC_0);
 771	rtw89_mac_dump_cmac_err_status_ax(rtwdev, RTW89_MAC_1);
 772
 773	rtwdev->hci.ops->dump_err_status(rtwdev);
 774
 775	if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1)
 776		rtw89_mac_dump_l0_to_l1(rtwdev, err);
 777
 778	rtw89_info(rtwdev, "<---\n");
 779}
 780
 781static bool rtw89_mac_suppress_log(struct rtw89_dev *rtwdev, u32 err)
 782{
 783	struct rtw89_ser *ser = &rtwdev->ser;
 784	u32 dmac_err, imr, isr;
 785	int ret;
 786
 787	if (rtwdev->chip->chip_id == RTL8852C) {
 788		ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);
 789		if (ret)
 790			return true;
 791
 792		if (err == MAC_AX_ERR_L1_ERR_DMAC) {
 793			dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR);
 794			imr = rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR);
 795			isr = rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR);
 796
 797			if ((dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) &&
 798			    ((isr & imr) & B_AX_B0_ISR_ERR_CMDPSR_FRZTO)) {
 799				set_bit(RTW89_SER_SUPPRESS_LOG, ser->flags);
 800				return true;
 801			}
 802		} else if (err == MAC_AX_ERR_L1_RESET_DISABLE_DMAC_DONE) {
 803			if (test_bit(RTW89_SER_SUPPRESS_LOG, ser->flags))
 804				return true;
 805		} else if (err == MAC_AX_ERR_L1_RESET_RECOVERY_DONE) {
 806			if (test_and_clear_bit(RTW89_SER_SUPPRESS_LOG, ser->flags))
 807				return true;
 808		}
 809	}
 810
 811	return false;
 812}
 813
 814u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev)
 815{
 816	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
 817	u32 err, err_scnr;
 818	int ret;
 819
 820	ret = read_poll_timeout(rtw89_read32, err, (err != 0), 1000, 100000,
 821				false, rtwdev, R_AX_HALT_C2H_CTRL);
 822	if (ret) {
 823		rtw89_warn(rtwdev, "Polling FW err status fail\n");
 824		return ret;
 825	}
 826
 827	err = rtw89_read32(rtwdev, R_AX_HALT_C2H);
 828	rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0);
 829
 830	err_scnr = RTW89_ERROR_SCENARIO(err);
 831	if (err_scnr == RTW89_WCPU_CPU_EXCEPTION)
 832		err = MAC_AX_ERR_CPU_EXCEPTION;
 833	else if (err_scnr == RTW89_WCPU_ASSERTION)
 834		err = MAC_AX_ERR_ASSERTION;
 835	else if (err_scnr == RTW89_RXI300_ERROR)
 836		err = MAC_AX_ERR_RXI300;
 837
 838	if (rtw89_mac_suppress_log(rtwdev, err))
 839		return err;
 840
 841	rtw89_fw_st_dbg_dump(rtwdev);
 842	mac->dump_err_status(rtwdev, err);
 843
 844	return err;
 845}
 846EXPORT_SYMBOL(rtw89_mac_get_err_status);
 847
 848int rtw89_mac_set_err_status(struct rtw89_dev *rtwdev, u32 err)
 849{
 850	struct rtw89_ser *ser = &rtwdev->ser;
 851	u32 halt;
 852	int ret = 0;
 853
 854	if (err > MAC_AX_SET_ERR_MAX) {
 855		rtw89_err(rtwdev, "Bad set-err-status value 0x%08x\n", err);
 856		return -EINVAL;
 857	}
 858
 859	ret = read_poll_timeout(rtw89_read32, halt, (halt == 0x0), 1000,
 860				100000, false, rtwdev, R_AX_HALT_H2C_CTRL);
 861	if (ret) {
 862		rtw89_err(rtwdev, "FW doesn't receive previous msg\n");
 863		return -EFAULT;
 864	}
 865
 866	rtw89_write32(rtwdev, R_AX_HALT_H2C, err);
 867
 868	if (ser->prehandle_l1 &&
 869	    (err == MAC_AX_ERR_L1_DISABLE_EN || err == MAC_AX_ERR_L1_RCVY_EN))
 870		return 0;
 871
 872	rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, B_AX_HALT_H2C_TRIGGER);
 873
 874	return 0;
 875}
 876EXPORT_SYMBOL(rtw89_mac_set_err_status);
 877
 878static int hfc_reset_param(struct rtw89_dev *rtwdev)
 879{
 880	const struct rtw89_hfc_param_ini *param_ini, *param_inis;
 881	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
 882	u8 qta_mode = rtwdev->mac.dle_info.qta_mode;
 883
 884	param_inis = rtwdev->chip->hfc_param_ini[rtwdev->hci.type];
 885	if (!param_inis)
 886		return -EINVAL;
 887
 888	param_ini = &param_inis[qta_mode];
 889
 890	param->en = 0;
 891
 892	if (param_ini->pub_cfg)
 893		param->pub_cfg = *param_ini->pub_cfg;
 894
 895	if (param_ini->prec_cfg)
 896		param->prec_cfg = *param_ini->prec_cfg;
 897
 898	if (param_ini->ch_cfg)
 899		param->ch_cfg = param_ini->ch_cfg;
 900
 901	memset(&param->ch_info, 0, sizeof(param->ch_info));
 902	memset(&param->pub_info, 0, sizeof(param->pub_info));
 903	param->mode = param_ini->mode;
 904
 905	return 0;
 906}
 907
 908static int hfc_ch_cfg_chk(struct rtw89_dev *rtwdev, u8 ch)
 909{
 910	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
 911	const struct rtw89_hfc_ch_cfg *ch_cfg = param->ch_cfg;
 912	const struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
 913	const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
 914
 915	if (ch >= RTW89_DMA_CH_NUM)
 916		return -EINVAL;
 917
 918	if ((ch_cfg[ch].min && ch_cfg[ch].min < prec_cfg->ch011_prec) ||
 919	    ch_cfg[ch].max > pub_cfg->pub_max)
 920		return -EINVAL;
 921	if (ch_cfg[ch].grp >= grp_num)
 922		return -EINVAL;
 923
 924	return 0;
 925}
 926
 927static int hfc_pub_info_chk(struct rtw89_dev *rtwdev)
 928{
 929	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
 930	const struct rtw89_hfc_pub_cfg *cfg = &param->pub_cfg;
 931	struct rtw89_hfc_pub_info *info = &param->pub_info;
 932
 933	if (info->g0_used + info->g1_used + info->pub_aval != cfg->pub_max) {
 934		if (rtwdev->chip->chip_id == RTL8852A)
 935			return 0;
 936		else
 937			return -EFAULT;
 938	}
 939
 940	return 0;
 941}
 942
 943static int hfc_pub_cfg_chk(struct rtw89_dev *rtwdev)
 944{
 945	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
 946	const struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
 947
 948	if (pub_cfg->grp0 + pub_cfg->grp1 != pub_cfg->pub_max)
 949		return -EFAULT;
 950
 951	return 0;
 952}
 953
 954static int hfc_ch_ctrl(struct rtw89_dev *rtwdev, u8 ch)
 955{
 956	const struct rtw89_chip_info *chip = rtwdev->chip;
 957	const struct rtw89_page_regs *regs = chip->page_regs;
 958	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
 959	const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg;
 960	int ret = 0;
 961	u32 val = 0;
 962
 963	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
 964	if (ret)
 965		return ret;
 966
 967	ret = hfc_ch_cfg_chk(rtwdev, ch);
 968	if (ret)
 969		return ret;
 970
 971	if (ch > RTW89_DMA_B1HI)
 972		return -EINVAL;
 973
 974	val = u32_encode_bits(cfg[ch].min, B_AX_MIN_PG_MASK) |
 975	      u32_encode_bits(cfg[ch].max, B_AX_MAX_PG_MASK) |
 976	      (cfg[ch].grp ? B_AX_GRP : 0);
 977	rtw89_write32(rtwdev, regs->ach_page_ctrl + ch * 4, val);
 978
 979	return 0;
 980}
 981
 982static int hfc_upd_ch_info(struct rtw89_dev *rtwdev, u8 ch)
 983{
 984	const struct rtw89_chip_info *chip = rtwdev->chip;
 985	const struct rtw89_page_regs *regs = chip->page_regs;
 986	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
 987	struct rtw89_hfc_ch_info *info = param->ch_info;
 988	const struct rtw89_hfc_ch_cfg *cfg = param->ch_cfg;
 989	u32 val;
 990	int ret;
 991
 992	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
 993	if (ret)
 994		return ret;
 995
 996	if (ch > RTW89_DMA_H2C)
 997		return -EINVAL;
 998
 999	val = rtw89_read32(rtwdev, regs->ach_page_info + ch * 4);
1000	info[ch].aval = u32_get_bits(val, B_AX_AVAL_PG_MASK);
1001	if (ch < RTW89_DMA_H2C)
1002		info[ch].used = u32_get_bits(val, B_AX_USE_PG_MASK);
1003	else
1004		info[ch].used = cfg[ch].min - info[ch].aval;
1005
1006	return 0;
1007}
1008
1009static int hfc_pub_ctrl(struct rtw89_dev *rtwdev)
1010{
1011	const struct rtw89_chip_info *chip = rtwdev->chip;
1012	const struct rtw89_page_regs *regs = chip->page_regs;
1013	const struct rtw89_hfc_pub_cfg *cfg = &rtwdev->mac.hfc_param.pub_cfg;
1014	u32 val;
1015	int ret;
1016
1017	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
1018	if (ret)
1019		return ret;
1020
1021	ret = hfc_pub_cfg_chk(rtwdev);
1022	if (ret)
1023		return ret;
1024
1025	val = u32_encode_bits(cfg->grp0, B_AX_PUBPG_G0_MASK) |
1026	      u32_encode_bits(cfg->grp1, B_AX_PUBPG_G1_MASK);
1027	rtw89_write32(rtwdev, regs->pub_page_ctrl1, val);
1028
1029	val = u32_encode_bits(cfg->wp_thrd, B_AX_WP_THRD_MASK);
1030	rtw89_write32(rtwdev, regs->wp_page_ctrl2, val);
1031
1032	return 0;
1033}
1034
1035static void hfc_get_mix_info_ax(struct rtw89_dev *rtwdev)
1036{
1037	const struct rtw89_chip_info *chip = rtwdev->chip;
1038	const struct rtw89_page_regs *regs = chip->page_regs;
1039	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
1040	struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
1041	struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
1042	struct rtw89_hfc_pub_info *info = &param->pub_info;
1043	u32 val;
1044
1045	val = rtw89_read32(rtwdev, regs->pub_page_info1);
1046	info->g0_used = u32_get_bits(val, B_AX_G0_USE_PG_MASK);
1047	info->g1_used = u32_get_bits(val, B_AX_G1_USE_PG_MASK);
1048	val = rtw89_read32(rtwdev, regs->pub_page_info3);
1049	info->g0_aval = u32_get_bits(val, B_AX_G0_AVAL_PG_MASK);
1050	info->g1_aval = u32_get_bits(val, B_AX_G1_AVAL_PG_MASK);
1051	info->pub_aval =
1052		u32_get_bits(rtw89_read32(rtwdev, regs->pub_page_info2),
1053			     B_AX_PUB_AVAL_PG_MASK);
1054	info->wp_aval =
1055		u32_get_bits(rtw89_read32(rtwdev, regs->wp_page_info1),
1056			     B_AX_WP_AVAL_PG_MASK);
1057
1058	val = rtw89_read32(rtwdev, regs->hci_fc_ctrl);
1059	param->en = val & B_AX_HCI_FC_EN ? 1 : 0;
1060	param->h2c_en = val & B_AX_HCI_FC_CH12_EN ? 1 : 0;
1061	param->mode = u32_get_bits(val, B_AX_HCI_FC_MODE_MASK);
1062	prec_cfg->ch011_full_cond =
1063		u32_get_bits(val, B_AX_HCI_FC_WD_FULL_COND_MASK);
1064	prec_cfg->h2c_full_cond =
1065		u32_get_bits(val, B_AX_HCI_FC_CH12_FULL_COND_MASK);
1066	prec_cfg->wp_ch07_full_cond =
1067		u32_get_bits(val, B_AX_HCI_FC_WP_CH07_FULL_COND_MASK);
1068	prec_cfg->wp_ch811_full_cond =
1069		u32_get_bits(val, B_AX_HCI_FC_WP_CH811_FULL_COND_MASK);
1070
1071	val = rtw89_read32(rtwdev, regs->ch_page_ctrl);
1072	prec_cfg->ch011_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH011_MASK);
1073	prec_cfg->h2c_prec = u32_get_bits(val, B_AX_PREC_PAGE_CH12_MASK);
1074
1075	val = rtw89_read32(rtwdev, regs->pub_page_ctrl2);
1076	pub_cfg->pub_max = u32_get_bits(val, B_AX_PUBPG_ALL_MASK);
1077
1078	val = rtw89_read32(rtwdev, regs->wp_page_ctrl1);
1079	prec_cfg->wp_ch07_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH07_MASK);
1080	prec_cfg->wp_ch811_prec = u32_get_bits(val, B_AX_PREC_PAGE_WP_CH811_MASK);
1081
1082	val = rtw89_read32(rtwdev, regs->wp_page_ctrl2);
1083	pub_cfg->wp_thrd = u32_get_bits(val, B_AX_WP_THRD_MASK);
1084
1085	val = rtw89_read32(rtwdev, regs->pub_page_ctrl1);
1086	pub_cfg->grp0 = u32_get_bits(val, B_AX_PUBPG_G0_MASK);
1087	pub_cfg->grp1 = u32_get_bits(val, B_AX_PUBPG_G1_MASK);
1088}
1089
1090static int hfc_upd_mix_info(struct rtw89_dev *rtwdev)
1091{
1092	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1093	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
1094	int ret;
1095
1096	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
1097	if (ret)
1098		return ret;
1099
1100	mac->hfc_get_mix_info(rtwdev);
1101
1102	ret = hfc_pub_info_chk(rtwdev);
1103	if (param->en && ret)
1104		return ret;
1105
1106	return 0;
1107}
1108
1109static void hfc_h2c_cfg_ax(struct rtw89_dev *rtwdev)
1110{
1111	const struct rtw89_chip_info *chip = rtwdev->chip;
1112	const struct rtw89_page_regs *regs = chip->page_regs;
1113	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
1114	const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
1115	u32 val;
1116
1117	val = u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK);
1118	rtw89_write32(rtwdev, regs->ch_page_ctrl, val);
1119
1120	rtw89_write32_mask(rtwdev, regs->hci_fc_ctrl,
1121			   B_AX_HCI_FC_CH12_FULL_COND_MASK,
1122			   prec_cfg->h2c_full_cond);
1123}
1124
1125static void hfc_mix_cfg_ax(struct rtw89_dev *rtwdev)
1126{
1127	const struct rtw89_chip_info *chip = rtwdev->chip;
1128	const struct rtw89_page_regs *regs = chip->page_regs;
1129	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
1130	const struct rtw89_hfc_pub_cfg *pub_cfg = &param->pub_cfg;
1131	const struct rtw89_hfc_prec_cfg *prec_cfg = &param->prec_cfg;
1132	u32 val;
1133
1134	val = u32_encode_bits(prec_cfg->ch011_prec, B_AX_PREC_PAGE_CH011_MASK) |
1135	      u32_encode_bits(prec_cfg->h2c_prec, B_AX_PREC_PAGE_CH12_MASK);
1136	rtw89_write32(rtwdev, regs->ch_page_ctrl, val);
1137
1138	val = u32_encode_bits(pub_cfg->pub_max, B_AX_PUBPG_ALL_MASK);
1139	rtw89_write32(rtwdev, regs->pub_page_ctrl2, val);
1140
1141	val = u32_encode_bits(prec_cfg->wp_ch07_prec,
1142			      B_AX_PREC_PAGE_WP_CH07_MASK) |
1143	      u32_encode_bits(prec_cfg->wp_ch811_prec,
1144			      B_AX_PREC_PAGE_WP_CH811_MASK);
1145	rtw89_write32(rtwdev, regs->wp_page_ctrl1, val);
1146
1147	val = u32_replace_bits(rtw89_read32(rtwdev, regs->hci_fc_ctrl),
1148			       param->mode, B_AX_HCI_FC_MODE_MASK);
1149	val = u32_replace_bits(val, prec_cfg->ch011_full_cond,
1150			       B_AX_HCI_FC_WD_FULL_COND_MASK);
1151	val = u32_replace_bits(val, prec_cfg->h2c_full_cond,
1152			       B_AX_HCI_FC_CH12_FULL_COND_MASK);
1153	val = u32_replace_bits(val, prec_cfg->wp_ch07_full_cond,
1154			       B_AX_HCI_FC_WP_CH07_FULL_COND_MASK);
1155	val = u32_replace_bits(val, prec_cfg->wp_ch811_full_cond,
1156			       B_AX_HCI_FC_WP_CH811_FULL_COND_MASK);
1157	rtw89_write32(rtwdev, regs->hci_fc_ctrl, val);
1158}
1159
1160static void hfc_func_en_ax(struct rtw89_dev *rtwdev, bool en, bool h2c_en)
1161{
1162	const struct rtw89_chip_info *chip = rtwdev->chip;
1163	const struct rtw89_page_regs *regs = chip->page_regs;
1164	struct rtw89_hfc_param *param = &rtwdev->mac.hfc_param;
1165	u32 val;
1166
1167	val = rtw89_read32(rtwdev, regs->hci_fc_ctrl);
1168	param->en = en;
1169	param->h2c_en = h2c_en;
1170	val = en ? (val | B_AX_HCI_FC_EN) : (val & ~B_AX_HCI_FC_EN);
1171	val = h2c_en ? (val | B_AX_HCI_FC_CH12_EN) :
1172			 (val & ~B_AX_HCI_FC_CH12_EN);
1173	rtw89_write32(rtwdev, regs->hci_fc_ctrl, val);
1174}
1175
1176int rtw89_mac_hfc_init(struct rtw89_dev *rtwdev, bool reset, bool en, bool h2c_en)
1177{
1178	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1179	const struct rtw89_chip_info *chip = rtwdev->chip;
1180	u32 dma_ch_mask = chip->dma_ch_mask;
1181	int ret = 0;
1182	u8 ch;
1183
1184	if (reset)
1185		ret = hfc_reset_param(rtwdev);
1186	if (ret)
1187		return ret;
1188
1189	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
1190	if (ret)
1191		return ret;
1192
1193	mac->hfc_func_en(rtwdev, false, false);
1194
1195	if (!en && h2c_en) {
1196		mac->hfc_h2c_cfg(rtwdev);
1197		mac->hfc_func_en(rtwdev, en, h2c_en);
1198		return 0;
1199	}
1200
1201	for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) {
1202		if (dma_ch_mask & BIT(ch))
1203			continue;
1204		ret = hfc_ch_ctrl(rtwdev, ch);
1205		if (ret)
1206			return ret;
1207	}
1208
1209	ret = hfc_pub_ctrl(rtwdev);
1210	if (ret)
1211		return ret;
1212
1213	mac->hfc_mix_cfg(rtwdev);
1214	if (en || h2c_en) {
1215		mac->hfc_func_en(rtwdev, en, h2c_en);
1216		udelay(10);
1217	}
1218	for (ch = RTW89_DMA_ACH0; ch < RTW89_DMA_H2C; ch++) {
1219		if (dma_ch_mask & BIT(ch))
1220			continue;
1221		ret = hfc_upd_ch_info(rtwdev, ch);
1222		if (ret)
1223			return ret;
1224	}
1225	ret = hfc_upd_mix_info(rtwdev);
1226
1227	return ret;
1228}
1229
1230#define PWR_POLL_CNT	2000
1231static int pwr_cmd_poll(struct rtw89_dev *rtwdev,
1232			const struct rtw89_pwr_cfg *cfg)
1233{
1234	u8 val = 0;
1235	int ret;
1236	u32 addr = cfg->base == PWR_INTF_MSK_SDIO ?
1237		   cfg->addr | SDIO_LOCAL_BASE_ADDR : cfg->addr;
1238
1239	ret = read_poll_timeout(rtw89_read8, val, !((val ^ cfg->val) & cfg->msk),
1240				1000, 1000 * PWR_POLL_CNT, false, rtwdev, addr);
1241
1242	if (!ret)
1243		return 0;
1244
1245	rtw89_warn(rtwdev, "[ERR] Polling timeout\n");
1246	rtw89_warn(rtwdev, "[ERR] addr: %X, %X\n", addr, cfg->addr);
1247	rtw89_warn(rtwdev, "[ERR] val: %X, %X\n", val, cfg->val);
1248
1249	return -EBUSY;
1250}
1251
1252static int rtw89_mac_sub_pwr_seq(struct rtw89_dev *rtwdev, u8 cv_msk,
1253				 u8 intf_msk, const struct rtw89_pwr_cfg *cfg)
1254{
1255	const struct rtw89_pwr_cfg *cur_cfg;
1256	u32 addr;
1257	u8 val;
1258
1259	for (cur_cfg = cfg; cur_cfg->cmd != PWR_CMD_END; cur_cfg++) {
1260		if (!(cur_cfg->intf_msk & intf_msk) ||
1261		    !(cur_cfg->cv_msk & cv_msk))
1262			continue;
1263
1264		switch (cur_cfg->cmd) {
1265		case PWR_CMD_WRITE:
1266			addr = cur_cfg->addr;
1267
1268			if (cur_cfg->base == PWR_BASE_SDIO)
1269				addr |= SDIO_LOCAL_BASE_ADDR;
1270
1271			val = rtw89_read8(rtwdev, addr);
1272			val &= ~(cur_cfg->msk);
1273			val |= (cur_cfg->val & cur_cfg->msk);
1274
1275			rtw89_write8(rtwdev, addr, val);
1276			break;
1277		case PWR_CMD_POLL:
1278			if (pwr_cmd_poll(rtwdev, cur_cfg))
1279				return -EBUSY;
1280			break;
1281		case PWR_CMD_DELAY:
1282			if (cur_cfg->val == PWR_DELAY_US)
1283				udelay(cur_cfg->addr);
1284			else
1285				fsleep(cur_cfg->addr * 1000);
1286			break;
1287		default:
1288			return -EINVAL;
1289		}
1290	}
1291
1292	return 0;
1293}
1294
1295static int rtw89_mac_pwr_seq(struct rtw89_dev *rtwdev,
1296			     const struct rtw89_pwr_cfg * const *cfg_seq)
1297{
1298	u8 intf_msk;
1299	int ret;
1300
1301	switch (rtwdev->hci.type) {
1302	case RTW89_HCI_TYPE_PCIE:
1303		intf_msk = PWR_INTF_MSK_PCIE;
1304		break;
1305	case RTW89_HCI_TYPE_USB:
1306		intf_msk = PWR_INTF_MSK_USB;
1307		break;
1308	case RTW89_HCI_TYPE_SDIO:
1309		intf_msk = PWR_INTF_MSK_SDIO;
1310		break;
1311	default:
1312		return -EOPNOTSUPP;
1313	}
1314
1315	for (; *cfg_seq; cfg_seq++) {
1316		ret = rtw89_mac_sub_pwr_seq(rtwdev, BIT(rtwdev->hal.cv),
1317					    intf_msk, *cfg_seq);
1318		if (ret)
1319			return -EBUSY;
1320	}
1321
1322	return 0;
1323}
1324
1325static enum rtw89_rpwm_req_pwr_state
1326rtw89_mac_get_req_pwr_state(struct rtw89_dev *rtwdev)
1327{
1328	enum rtw89_rpwm_req_pwr_state state;
1329
1330	switch (rtwdev->ps_mode) {
1331	case RTW89_PS_MODE_RFOFF:
1332		state = RTW89_MAC_RPWM_REQ_PWR_STATE_BAND0_RFOFF;
1333		break;
1334	case RTW89_PS_MODE_CLK_GATED:
1335		state = RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED;
1336		break;
1337	case RTW89_PS_MODE_PWR_GATED:
1338		state = RTW89_MAC_RPWM_REQ_PWR_STATE_PWR_GATED;
1339		break;
1340	default:
1341		state = RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE;
1342		break;
1343	}
1344	return state;
1345}
1346
1347static void rtw89_mac_send_rpwm(struct rtw89_dev *rtwdev,
1348				enum rtw89_rpwm_req_pwr_state req_pwr_state,
1349				bool notify_wake)
1350{
1351	u16 request;
1352
1353	spin_lock_bh(&rtwdev->rpwm_lock);
1354
1355	request = rtw89_read16(rtwdev, R_AX_RPWM);
1356	request ^= request | PS_RPWM_TOGGLE;
1357	request |= req_pwr_state;
1358
1359	if (notify_wake) {
1360		request |= PS_RPWM_NOTIFY_WAKE;
1361	} else {
1362		rtwdev->mac.rpwm_seq_num = (rtwdev->mac.rpwm_seq_num + 1) &
1363					    RPWM_SEQ_NUM_MAX;
1364		request |= FIELD_PREP(PS_RPWM_SEQ_NUM,
1365				      rtwdev->mac.rpwm_seq_num);
1366
1367		if (req_pwr_state < RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED)
1368			request |= PS_RPWM_ACK;
1369	}
1370	rtw89_write16(rtwdev, rtwdev->hci.rpwm_addr, request);
1371
1372	spin_unlock_bh(&rtwdev->rpwm_lock);
1373}
1374
1375static int rtw89_mac_check_cpwm_state(struct rtw89_dev *rtwdev,
1376				      enum rtw89_rpwm_req_pwr_state req_pwr_state)
1377{
1378	bool request_deep_mode;
1379	bool in_deep_mode;
1380	u8 rpwm_req_num;
1381	u8 cpwm_rsp_seq;
1382	u8 cpwm_seq;
1383	u8 cpwm_status;
1384
1385	if (req_pwr_state >= RTW89_MAC_RPWM_REQ_PWR_STATE_CLK_GATED)
1386		request_deep_mode = true;
1387	else
1388		request_deep_mode = false;
1389
1390	if (rtw89_read32_mask(rtwdev, R_AX_LDM, B_AX_EN_32K))
1391		in_deep_mode = true;
1392	else
1393		in_deep_mode = false;
1394
1395	if (request_deep_mode != in_deep_mode)
1396		return -EPERM;
1397
1398	if (request_deep_mode)
1399		return 0;
1400
1401	rpwm_req_num = rtwdev->mac.rpwm_seq_num;
1402	cpwm_rsp_seq = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr,
1403					 PS_CPWM_RSP_SEQ_NUM);
1404
1405	if (rpwm_req_num != cpwm_rsp_seq)
1406		return -EPERM;
1407
1408	rtwdev->mac.cpwm_seq_num = (rtwdev->mac.cpwm_seq_num + 1) &
1409				    CPWM_SEQ_NUM_MAX;
1410
1411	cpwm_seq = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr, PS_CPWM_SEQ_NUM);
1412	if (cpwm_seq != rtwdev->mac.cpwm_seq_num)
1413		return -EPERM;
1414
1415	cpwm_status = rtw89_read16_mask(rtwdev, rtwdev->hci.cpwm_addr, PS_CPWM_STATE);
1416	if (cpwm_status != req_pwr_state)
1417		return -EPERM;
1418
1419	return 0;
1420}
1421
1422void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
1423{
1424	enum rtw89_rpwm_req_pwr_state state;
1425	unsigned long delay = enter ? 10 : 150;
1426	int ret;
1427	int i;
1428
1429	if (enter)
1430		state = rtw89_mac_get_req_pwr_state(rtwdev);
1431	else
1432		state = RTW89_MAC_RPWM_REQ_PWR_STATE_ACTIVE;
1433
1434	for (i = 0; i < RPWM_TRY_CNT; i++) {
1435		rtw89_mac_send_rpwm(rtwdev, state, false);
1436		ret = read_poll_timeout_atomic(rtw89_mac_check_cpwm_state, ret,
1437					       !ret, delay, 15000, false,
1438					       rtwdev, state);
1439		if (!ret)
1440			break;
1441
1442		if (i == RPWM_TRY_CNT - 1) {
1443			rtw89_err(rtwdev, "firmware failed to ack for %s ps mode\n",
1444				  enter ? "entering" : "leaving");
1445			rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
1446		} else {
1447			rtw89_debug(rtwdev, RTW89_DBG_UNEXP,
1448				    "%d time firmware failed to ack for %s ps mode\n",
1449				    i + 1, enter ? "entering" : "leaving");
1450		}
1451	}
1452}
1453
1454void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev)
1455{
1456	enum rtw89_rpwm_req_pwr_state state;
1457
1458	state = rtw89_mac_get_req_pwr_state(rtwdev);
1459	rtw89_mac_send_rpwm(rtwdev, state, true);
1460}
1461
1462static void rtw89_mac_power_switch_boot_mode(struct rtw89_dev *rtwdev)
1463{
1464	u32 boot_mode;
1465
1466	if (rtwdev->hci.type != RTW89_HCI_TYPE_USB)
1467		return;
1468
1469	boot_mode = rtw89_read32_mask(rtwdev, R_AX_GPIO_MUXCFG, B_AX_BOOT_MODE);
1470	if (!boot_mode)
1471		return;
1472
1473	rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC);
1474	rtw89_write32_clr(rtwdev, R_AX_SYS_STATUS1, B_AX_AUTO_WLPON);
1475	rtw89_write32_clr(rtwdev, R_AX_GPIO_MUXCFG, B_AX_BOOT_MODE);
1476	rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST);
1477}
1478
1479static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
1480{
1481#define PWR_ACT 1
1482	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1483	const struct rtw89_chip_info *chip = rtwdev->chip;
1484	const struct rtw89_pwr_cfg * const *cfg_seq;
1485	int (*cfg_func)(struct rtw89_dev *rtwdev);
1486	int ret;
1487	u8 val;
1488
1489	rtw89_mac_power_switch_boot_mode(rtwdev);
1490
1491	if (on) {
1492		cfg_seq = chip->pwr_on_seq;
1493		cfg_func = chip->ops->pwr_on_func;
1494	} else {
1495		cfg_seq = chip->pwr_off_seq;
1496		cfg_func = chip->ops->pwr_off_func;
1497	}
1498
1499	if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags))
1500		__rtw89_leave_ps_mode(rtwdev);
1501
1502	val = rtw89_read32_mask(rtwdev, R_AX_IC_PWR_STATE, B_AX_WLMAC_PWR_STE_MASK);
1503	if (on && val == PWR_ACT) {
1504		rtw89_err(rtwdev, "MAC has already powered on\n");
1505		return -EBUSY;
1506	}
1507
1508	ret = cfg_func ? cfg_func(rtwdev) : rtw89_mac_pwr_seq(rtwdev, cfg_seq);
1509	if (ret)
1510		return ret;
1511
1512	if (on) {
1513		if (!test_bit(RTW89_FLAG_PROBE_DONE, rtwdev->flags))
1514			mac->efuse_read_fw_secure(rtwdev);
1515
1516		set_bit(RTW89_FLAG_POWERON, rtwdev->flags);
1517		set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
1518		set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
1519		rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_TP_MAJOR);
1520	} else {
1521		clear_bit(RTW89_FLAG_POWERON, rtwdev->flags);
1522		clear_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
1523		clear_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
1524		clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags);
1525		clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
1526		rtw89_write8(rtwdev, R_AX_SCOREBOARD + 3, MAC_AX_NOTIFY_PWR_MAJOR);
1527		rtw89_set_entity_state(rtwdev, RTW89_PHY_0, false);
1528		rtw89_set_entity_state(rtwdev, RTW89_PHY_1, false);
1529	}
1530
1531	return 0;
1532#undef PWR_ACT
1533}
1534
1535int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev)
1536{
1537	int ret;
1538
1539	ret = rtw89_mac_power_switch(rtwdev, true);
1540	if (ret) {
1541		rtw89_mac_power_switch(rtwdev, false);
1542		ret = rtw89_mac_power_switch(rtwdev, true);
1543		if (ret)
1544			return ret;
1545	}
1546
1547	return 0;
1548}
1549
1550void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev)
1551{
1552	rtw89_mac_power_switch(rtwdev, false);
1553}
1554
1555static int cmac_func_en_ax(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
1556{
1557	u32 func_en = 0;
1558	u32 ck_en = 0;
1559	u32 c1pc_en = 0;
1560	u32 addrl_func_en[] = {R_AX_CMAC_FUNC_EN, R_AX_CMAC_FUNC_EN_C1};
1561	u32 addrl_ck_en[] = {R_AX_CK_EN, R_AX_CK_EN_C1};
1562
1563	func_en = B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN |
1564			B_AX_PHYINTF_EN | B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN |
1565			B_AX_SCHEDULER_EN | B_AX_TMAC_EN | B_AX_RMAC_EN |
1566			B_AX_CMAC_CRPRT;
1567	ck_en = B_AX_CMAC_CKEN | B_AX_PHYINTF_CKEN | B_AX_CMAC_DMA_CKEN |
1568		      B_AX_PTCLTOP_CKEN | B_AX_SCHEDULER_CKEN | B_AX_TMAC_CKEN |
1569		      B_AX_RMAC_CKEN;
1570	c1pc_en = B_AX_R_SYM_WLCMAC1_PC_EN |
1571			B_AX_R_SYM_WLCMAC1_P1_PC_EN |
1572			B_AX_R_SYM_WLCMAC1_P2_PC_EN |
1573			B_AX_R_SYM_WLCMAC1_P3_PC_EN |
1574			B_AX_R_SYM_WLCMAC1_P4_PC_EN;
1575
1576	if (en) {
1577		if (mac_idx == RTW89_MAC_1) {
1578			rtw89_write32_set(rtwdev, R_AX_AFE_CTRL1, c1pc_en);
1579			rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
1580					  B_AX_R_SYM_ISO_CMAC12PP);
1581			rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
1582					  B_AX_CMAC1_FEN);
1583		}
1584		rtw89_write32_set(rtwdev, addrl_ck_en[mac_idx], ck_en);
1585		rtw89_write32_set(rtwdev, addrl_func_en[mac_idx], func_en);
1586	} else {
1587		rtw89_write32_clr(rtwdev, addrl_func_en[mac_idx], func_en);
1588		rtw89_write32_clr(rtwdev, addrl_ck_en[mac_idx], ck_en);
1589		if (mac_idx == RTW89_MAC_1) {
1590			rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
1591					  B_AX_CMAC1_FEN);
1592			rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
1593					  B_AX_R_SYM_ISO_CMAC12PP);
1594			rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, c1pc_en);
1595		}
1596	}
1597
1598	return 0;
1599}
1600
1601static int dmac_func_en_ax(struct rtw89_dev *rtwdev)
1602{
1603	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
1604	u32 val32;
1605
1606	if (chip_id == RTL8852C)
1607		val32 = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN |
1608			 B_AX_MAC_SEC_EN | B_AX_DISPATCHER_EN |
1609			 B_AX_DLE_CPUIO_EN | B_AX_PKT_IN_EN |
1610			 B_AX_DMAC_TBL_EN | B_AX_PKT_BUF_EN |
1611			 B_AX_STA_SCH_EN | B_AX_TXPKT_CTRL_EN |
1612			 B_AX_WD_RLS_EN | B_AX_MPDU_PROC_EN |
1613			 B_AX_DMAC_CRPRT | B_AX_H_AXIDMA_EN);
1614	else
1615		val32 = (B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN |
1616			 B_AX_MAC_SEC_EN | B_AX_DISPATCHER_EN |
1617			 B_AX_DLE_CPUIO_EN | B_AX_PKT_IN_EN |
1618			 B_AX_DMAC_TBL_EN | B_AX_PKT_BUF_EN |
1619			 B_AX_STA_SCH_EN | B_AX_TXPKT_CTRL_EN |
1620			 B_AX_WD_RLS_EN | B_AX_MPDU_PROC_EN |
1621			 B_AX_DMAC_CRPRT);
1622	rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val32);
1623
1624	val32 = (B_AX_MAC_SEC_CLK_EN | B_AX_DISPATCHER_CLK_EN |
1625		 B_AX_DLE_CPUIO_CLK_EN | B_AX_PKT_IN_CLK_EN |
1626		 B_AX_STA_SCH_CLK_EN | B_AX_TXPKT_CTRL_CLK_EN |
1627		 B_AX_WD_RLS_CLK_EN | B_AX_BBRPT_CLK_EN);
1628	if (chip_id == RTL8852BT)
1629		val32 |= B_AX_AXIDMA_CLK_EN;
1630	rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val32);
1631
1632	return 0;
1633}
1634
1635static int chip_func_en_ax(struct rtw89_dev *rtwdev)
1636{
1637	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
1638
1639	if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
1640		rtw89_write32_set(rtwdev, R_AX_SPS_DIG_ON_CTRL0,
1641				  B_AX_OCP_L1_MASK);
1642
1643	return 0;
1644}
1645
1646static int sys_init_ax(struct rtw89_dev *rtwdev)
1647{
1648	int ret;
1649
1650	ret = dmac_func_en_ax(rtwdev);
1651	if (ret)
1652		return ret;
1653
1654	ret = cmac_func_en_ax(rtwdev, 0, true);
1655	if (ret)
1656		return ret;
1657
1658	ret = chip_func_en_ax(rtwdev);
1659	if (ret)
1660		return ret;
1661
1662	return ret;
1663}
1664
1665const struct rtw89_mac_size_set rtw89_mac_size = {
1666	.hfc_preccfg_pcie = {2, 40, 0, 0, 1, 0, 0, 0},
1667	.hfc_prec_cfg_c0 = {2, 32, 0, 0, 0, 0, 0, 0},
1668	.hfc_prec_cfg_c2 = {0, 256, 0, 0, 0, 0, 0, 0},
1669	/* PCIE 64 */
1670	.wde_size0 = {RTW89_WDE_PG_64, 4095, 1,},
1671	.wde_size0_v1 = {RTW89_WDE_PG_64, 3328, 0, 0,},
1672	/* 8852A USB */
1673	.wde_size1 = {RTW89_WDE_PG_64, 768, 0,},
1674	/* DLFW */
1675	.wde_size4 = {RTW89_WDE_PG_64, 0, 4096,},
1676	.wde_size4_v1 = {RTW89_WDE_PG_64, 0, 3328, 0,},
1677	/* PCIE 64 */
1678	.wde_size6 = {RTW89_WDE_PG_64, 512, 0,},
1679	/* 8852B PCIE SCC */
1680	.wde_size7 = {RTW89_WDE_PG_64, 510, 2,},
1681	/* DLFW */
1682	.wde_size9 = {RTW89_WDE_PG_64, 0, 1024,},
1683	/* 8852C USB3.0 */
1684	.wde_size17 = {RTW89_WDE_PG_64, 354, 30,},
1685	/* 8852C DLFW */
1686	.wde_size18 = {RTW89_WDE_PG_64, 0, 2048,},
1687	/* 8852C PCIE SCC */
1688	.wde_size19 = {RTW89_WDE_PG_64, 3328, 0,},
1689	.wde_size23 = {RTW89_WDE_PG_64, 1022, 2,},
1690	/* 8852B USB2.0/USB3.0 SCC */
1691	.wde_size25 = {RTW89_WDE_PG_64, 162, 94,},
1692	/* 8852C USB2.0 */
1693	.wde_size31 = {RTW89_WDE_PG_64, 384, 0,},
1694	/* PCIE */
1695	.ple_size0 = {RTW89_PLE_PG_128, 1520, 16,},
1696	.ple_size0_v1 = {RTW89_PLE_PG_128, 2688, 240, 212992,},
1697	/* 8852A USB */
1698	.ple_size1 = {RTW89_PLE_PG_128, 3184, 16,},
1699	.ple_size3_v1 = {RTW89_PLE_PG_128, 2928, 0, 212992,},
1700	/* DLFW */
1701	.ple_size4 = {RTW89_PLE_PG_128, 64, 1472,},
1702	/* PCIE 64 */
1703	.ple_size6 = {RTW89_PLE_PG_128, 496, 16,},
1704	/* DLFW */
1705	.ple_size8 = {RTW89_PLE_PG_128, 64, 960,},
1706	.ple_size9 = {RTW89_PLE_PG_128, 2288, 16,},
1707	/* 8852C USB */
1708	.ple_size17 = {RTW89_PLE_PG_128, 3368, 24,},
1709	/* 8852C DLFW */
1710	.ple_size18 = {RTW89_PLE_PG_128, 2544, 16,},
1711	/* 8852C PCIE SCC */
1712	.ple_size19 = {RTW89_PLE_PG_128, 1904, 16,},
1713	/* 8852B USB2.0 SCC */
1714	.ple_size32 = {RTW89_PLE_PG_128, 620, 20,},
1715	/* 8852B USB3.0 SCC */
1716	.ple_size33 = {RTW89_PLE_PG_128, 632, 8,},
1717	/* 8852C USB2.0 */
1718	.ple_size34 = {RTW89_PLE_PG_128, 3374, 18,},
1719	/* PCIE 64 */
1720	.wde_qt0 = {3792, 196, 0, 107,},
1721	.wde_qt0_v1 = {3302, 6, 0, 20,},
1722	/* 8852A USB */
1723	.wde_qt1 = {512, 196, 0, 60,},
1724	/* DLFW */
1725	.wde_qt4 = {0, 0, 0, 0,},
1726	/* PCIE 64 */
1727	.wde_qt6 = {448, 48, 0, 16,},
1728	/* 8852B PCIE SCC */
1729	.wde_qt7 = {446, 48, 0, 16,},
1730	/* 8852C USB3.0 */
1731	.wde_qt16 = {344, 2, 0, 8,},
1732	/* 8852C DLFW */
1733	.wde_qt17 = {0, 0, 0,  0,},
1734	/* 8852C PCIE SCC */
1735	.wde_qt18 = {3228, 60, 0, 40,},
1736	.wde_qt23 = {958, 48, 0, 16,},
1737	/* 8852B USB2.0/USB3.0 SCC */
1738	.wde_qt25 = {152, 2, 0, 8,},
1739	/* 8852C USB2.0 */
1740	.wde_qt31 = {338, 6, 0, 40,},
1741	.ple_qt0 = {320, 320, 32, 16, 13, 13, 292, 292, 64, 18, 1, 4, 0,},
1742	.ple_qt1 = {320, 320, 32, 16, 1316, 1316, 1595, 1595, 1367, 1321, 1, 1307, 0,},
1743	/* PCIE SCC */
1744	.ple_qt4 = {264, 0, 16, 20, 26, 13, 356, 0, 32, 40, 8,},
1745	/* PCIE SCC */
1746	.ple_qt5 = {264, 0, 32, 20, 64, 13, 1101, 0, 64, 128, 120,},
1747	.ple_qt9 = {0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 1, 0, 0,},
1748	/* DLFW */
1749	.ple_qt13 = {0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0,},
1750	/* PCIE 64 */
1751	.ple_qt18 = {147, 0, 16, 20, 17, 13, 89, 0, 32, 14, 8, 0,},
1752	/* 8852A USB SCC */
1753	.ple_qt25 = {1536, 0, 16, 48, 13, 13, 360, 0, 32, 40, 8, 0,},
1754	.ple_qt26 = {2654, 0, 1134, 48, 64, 13, 1478, 0, 64, 128, 120, 0,},
1755	/* USB 52C USB3.0 */
1756	.ple_qt42 = {1068, 0, 16, 48, 4, 13, 178, 0, 16, 1, 8, 16, 0,},
1757	/* USB 52C USB3.0 */
1758	.ple_qt43 = {3068, 0, 32, 48, 4, 13, 178, 0, 16, 1, 8, 16, 0,},
1759	/* DLFW 52C */
1760	.ple_qt44 = {0, 0, 16, 256, 0, 0, 0, 0, 0, 0, 0, 0,},
1761	/* DLFW 52C */
1762	.ple_qt45 = {0, 0, 32, 256, 0, 0, 0, 0, 0, 0, 0, 0,},
1763	/* 8852C PCIE SCC */
1764	.ple_qt46 = {525, 0, 16, 20, 13, 13, 178, 0, 32, 62, 8, 16,},
1765	/* 8852C PCIE SCC */
1766	.ple_qt47 = {525, 0, 32, 20, 1034, 13, 1199, 0, 1053, 62, 160, 1037,},
1767	.ple_qt57 = {147, 0, 16, 20, 13, 13, 178, 0, 32, 14, 8, 0,},
1768	/* PCIE 64 */
1769	.ple_qt58 = {147, 0, 16, 20, 157, 13, 229, 0, 172, 14, 24, 0,},
1770	.ple_qt59 = {147, 0, 32, 20, 1860, 13, 2025, 0, 1879, 14, 24, 0,},
1771	/* USB2.0 52B SCC */
1772	.ple_qt72 = {130, 0, 16, 48, 4, 13, 322, 0, 32, 14, 8, 0, 0,},
1773	/* USB2.0 52B 92K */
1774	.ple_qt73 = {130, 0, 32, 48, 37, 13, 355, 0, 65, 14, 24, 0, 0,},
1775	/* USB3.0 52B 92K */
1776	.ple_qt74 = {286, 0, 16, 48, 4, 13, 178, 0, 32, 14, 8, 0, 0,},
1777	.ple_qt75 = {286, 0, 32, 48, 37, 13, 211, 0, 65, 14, 24, 0, 0,},
1778	/* USB2.0 52C */
1779	.ple_qt78 = {1560, 0, 16, 48, 13, 13, 390, 0, 32, 38, 8, 16, 0,},
1780	/* USB2.0 52C */
1781	.ple_qt79 = {1560, 0, 32, 48, 1253, 13, 1630, 0, 1272, 38, 120, 1256, 0,},
1782	/* 8852A PCIE WOW */
1783	.ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,},
1784	/* 8852B PCIE WOW */
1785	.ple_qt_52b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,},
1786	/* 8852BT PCIE WOW */
1787	.ple_qt_52bt_wow = {147, 0, 32, 20, 1860, 13, 1929, 0, 1879, 14, 24, 0,},
1788	/* 8851B PCIE WOW */
1789	.ple_qt_51b_wow = {147, 0, 16, 20, 157, 13, 133, 0, 172, 14, 24, 0,},
1790	.ple_rsvd_qt0 = {2, 107, 107, 6, 6, 6, 6, 0, 0, 0,},
1791	.ple_rsvd_qt1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
1792	.rsvd0_size0 = {212992, 0,},
1793	.rsvd1_size0 = {587776, 2048,},
1794};
1795EXPORT_SYMBOL(rtw89_mac_size);
1796
1797static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev,
1798						   enum rtw89_qta_mode mode)
1799{
1800	struct rtw89_mac_info *mac = &rtwdev->mac;
1801	const struct rtw89_dle_mem *cfg, *cfgs;
1802
1803	cfgs = rtwdev->chip->dle_mem[rtwdev->hci.dle_type];
1804	if (!cfgs)
1805		return NULL;
1806
1807	cfg = &cfgs[mode];
1808	if (cfg->mode != mode) {
1809		rtw89_warn(rtwdev, "qta mode unmatch!\n");
1810		return NULL;
1811	}
1812
1813	mac->dle_info.rsvd_qt = cfg->rsvd_qt;
1814	mac->dle_info.ple_pg_size = cfg->ple_size->pge_size;
1815	mac->dle_info.ple_free_pg = cfg->ple_size->lnk_pge_num;
1816	mac->dle_info.qta_mode = mode;
1817	mac->dle_info.c0_rx_qta = cfg->ple_min_qt->cma0_dma;
1818	mac->dle_info.c1_rx_qta = cfg->ple_min_qt->cma1_dma;
1819
1820	return cfg;
1821}
1822
1823int rtw89_mac_get_dle_rsvd_qt_cfg(struct rtw89_dev *rtwdev,
1824				  enum rtw89_mac_dle_rsvd_qt_type type,
1825				  struct rtw89_mac_dle_rsvd_qt_cfg *cfg)
1826{
1827	struct rtw89_dle_info *dle_info = &rtwdev->mac.dle_info;
1828	const struct rtw89_rsvd_quota *rsvd_qt = dle_info->rsvd_qt;
1829
1830	switch (type) {
1831	case DLE_RSVD_QT_MPDU_INFO:
1832		cfg->pktid = dle_info->ple_free_pg;
1833		cfg->pg_num = rsvd_qt->mpdu_info_tbl;
1834		break;
1835	case DLE_RSVD_QT_B0_CSI:
1836		cfg->pktid = dle_info->ple_free_pg + rsvd_qt->mpdu_info_tbl;
1837		cfg->pg_num = rsvd_qt->b0_csi;
1838		break;
1839	case DLE_RSVD_QT_B1_CSI:
1840		cfg->pktid = dle_info->ple_free_pg +
1841			     rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi;
1842		cfg->pg_num = rsvd_qt->b1_csi;
1843		break;
1844	case DLE_RSVD_QT_B0_LMR:
1845		cfg->pktid = dle_info->ple_free_pg +
1846			     rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi;
1847		cfg->pg_num = rsvd_qt->b0_lmr;
1848		break;
1849	case DLE_RSVD_QT_B1_LMR:
1850		cfg->pktid = dle_info->ple_free_pg +
1851			     rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi +
1852			     rsvd_qt->b0_lmr;
1853		cfg->pg_num = rsvd_qt->b1_lmr;
1854		break;
1855	case DLE_RSVD_QT_B0_FTM:
1856		cfg->pktid = dle_info->ple_free_pg +
1857			     rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi +
1858			     rsvd_qt->b0_lmr + rsvd_qt->b1_lmr;
1859		cfg->pg_num = rsvd_qt->b0_ftm;
1860		break;
1861	case DLE_RSVD_QT_B1_FTM:
1862		cfg->pktid = dle_info->ple_free_pg +
1863			     rsvd_qt->mpdu_info_tbl + rsvd_qt->b0_csi + rsvd_qt->b1_csi +
1864			     rsvd_qt->b0_lmr + rsvd_qt->b1_lmr + rsvd_qt->b0_ftm;
1865		cfg->pg_num = rsvd_qt->b1_ftm;
1866		break;
1867	default:
1868		return -EINVAL;
1869	}
1870
1871	cfg->size = (u32)cfg->pg_num * dle_info->ple_pg_size;
1872
1873	return 0;
1874}
1875
1876static bool mac_is_txq_empty_ax(struct rtw89_dev *rtwdev)
1877{
1878	struct rtw89_mac_dle_dfi_qempty qempty;
1879	u32 grpnum, qtmp, val32, msk32;
1880	int i, j, ret;
1881
1882	grpnum = rtwdev->chip->wde_qempty_acq_grpnum;
1883	qempty.dle_type = DLE_CTRL_TYPE_WDE;
1884
1885	for (i = 0; i < grpnum; i++) {
1886		qempty.grpsel = i;
1887		ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
1888		if (ret) {
1889			rtw89_warn(rtwdev, "dle dfi acq empty %d\n", ret);
1890			return false;
1891		}
1892		qtmp = qempty.qempty;
1893		for (j = 0 ; j < QEMP_ACQ_GRP_MACID_NUM; j++) {
1894			val32 = u32_get_bits(qtmp, QEMP_ACQ_GRP_QSEL_MASK);
1895			if (val32 != QEMP_ACQ_GRP_QSEL_MASK)
1896				return false;
1897			qtmp >>= QEMP_ACQ_GRP_QSEL_SH;
1898		}
1899	}
1900
1901	qempty.grpsel = rtwdev->chip->wde_qempty_mgq_grpsel;
1902	ret = rtw89_mac_dle_dfi_qempty_cfg(rtwdev, &qempty);
1903	if (ret) {
1904		rtw89_warn(rtwdev, "dle dfi mgq empty %d\n", ret);
1905		return false;
1906	}
1907	msk32 = B_CMAC0_MGQ_NORMAL | B_CMAC0_MGQ_NO_PWRSAV | B_CMAC0_CPUMGQ;
1908	if ((qempty.qempty & msk32) != msk32)
1909		return false;
1910
1911	if (rtwdev->dbcc_en) {
1912		msk32 |= B_CMAC1_MGQ_NORMAL | B_CMAC1_MGQ_NO_PWRSAV | B_CMAC1_CPUMGQ;
1913		if ((qempty.qempty & msk32) != msk32)
1914			return false;
1915	}
1916
1917	msk32 = B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU | B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU |
1918		B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU | B_AX_PLE_EMPTY_QTA_DMAC_H2C |
1919		B_AX_WDE_EMPTY_QUE_OTHERS | B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX |
1920		B_AX_WDE_EMPTY_QTA_DMAC_CPUIO | B_AX_PLE_EMPTY_QTA_DMAC_CPUIO |
1921		B_AX_WDE_EMPTY_QUE_DMAC_PKTIN | B_AX_WDE_EMPTY_QTA_DMAC_HIF |
1922		B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX | B_AX_WDE_EMPTY_QTA_DMAC_PKTIN |
1923		B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL | B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL |
1924		B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX;
1925	val32 = rtw89_read32(rtwdev, R_AX_DLE_EMPTY0);
1926
1927	return (val32 & msk32) == msk32;
1928}
1929
1930static inline u32 dle_used_size(const struct rtw89_dle_mem *cfg)
1931{
1932	const struct rtw89_dle_size *wde = cfg->wde_size;
1933	const struct rtw89_dle_size *ple = cfg->ple_size;
1934	u32 used;
1935
1936	used = wde->pge_size * (wde->lnk_pge_num + wde->unlnk_pge_num) +
1937	       ple->pge_size * (ple->lnk_pge_num + ple->unlnk_pge_num);
1938
1939	if (cfg->rsvd0_size && cfg->rsvd1_size) {
1940		used += cfg->rsvd0_size->size;
1941		used += cfg->rsvd1_size->size;
1942	}
1943
1944	return used;
1945}
1946
1947static u32 dle_expected_used_size(struct rtw89_dev *rtwdev,
1948				  enum rtw89_qta_mode mode)
1949{
1950	u32 size = rtwdev->chip->fifo_size;
1951
1952	if (mode == RTW89_QTA_SCC)
1953		size -= rtwdev->chip->dle_scc_rsvd_size;
1954
1955	return size;
1956}
1957
1958static void dle_func_en_ax(struct rtw89_dev *rtwdev, bool enable)
1959{
1960	if (enable)
1961		rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN,
1962				  B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN);
1963	else
1964		rtw89_write32_clr(rtwdev, R_AX_DMAC_FUNC_EN,
1965				  B_AX_DLE_WDE_EN | B_AX_DLE_PLE_EN);
1966}
1967
1968static void dle_clk_en_ax(struct rtw89_dev *rtwdev, bool enable)
1969{
1970	u32 val = B_AX_DLE_WDE_CLK_EN | B_AX_DLE_PLE_CLK_EN;
1971
1972	if (enable) {
1973		if (rtwdev->chip->chip_id == RTL8851B)
1974			val |= B_AX_AXIDMA_CLK_EN;
1975		rtw89_write32_set(rtwdev, R_AX_DMAC_CLK_EN, val);
1976	} else {
1977		rtw89_write32_clr(rtwdev, R_AX_DMAC_CLK_EN, val);
1978	}
1979}
1980
1981static int dle_mix_cfg_ax(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg)
1982{
1983	const struct rtw89_dle_size *size_cfg;
1984	u32 val;
1985	u8 bound = 0;
1986
1987	val = rtw89_read32(rtwdev, R_AX_WDE_PKTBUF_CFG);
1988	size_cfg = cfg->wde_size;
1989
1990	switch (size_cfg->pge_size) {
1991	default:
1992	case RTW89_WDE_PG_64:
1993		val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_64,
1994				       B_AX_WDE_PAGE_SEL_MASK);
1995		break;
1996	case RTW89_WDE_PG_128:
1997		val = u32_replace_bits(val, S_AX_WDE_PAGE_SEL_128,
1998				       B_AX_WDE_PAGE_SEL_MASK);
1999		break;
2000	case RTW89_WDE_PG_256:
2001		rtw89_err(rtwdev, "[ERR]WDE DLE doesn't support 256 byte!\n");
2002		return -EINVAL;
2003	}
2004
2005	val = u32_replace_bits(val, bound, B_AX_WDE_START_BOUND_MASK);
2006	val = u32_replace_bits(val, size_cfg->lnk_pge_num,
2007			       B_AX_WDE_FREE_PAGE_NUM_MASK);
2008	rtw89_write32(rtwdev, R_AX_WDE_PKTBUF_CFG, val);
2009
2010	val = rtw89_read32(rtwdev, R_AX_PLE_PKTBUF_CFG);
2011	bound = (size_cfg->lnk_pge_num + size_cfg->unlnk_pge_num)
2012				* size_cfg->pge_size / DLE_BOUND_UNIT;
2013	size_cfg = cfg->ple_size;
2014
2015	switch (size_cfg->pge_size) {
2016	default:
2017	case RTW89_PLE_PG_64:
2018		rtw89_err(rtwdev, "[ERR]PLE DLE doesn't support 64 byte!\n");
2019		return -EINVAL;
2020	case RTW89_PLE_PG_128:
2021		val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_128,
2022				       B_AX_PLE_PAGE_SEL_MASK);
2023		break;
2024	case RTW89_PLE_PG_256:
2025		val = u32_replace_bits(val, S_AX_PLE_PAGE_SEL_256,
2026				       B_AX_PLE_PAGE_SEL_MASK);
2027		break;
2028	}
2029
2030	val = u32_replace_bits(val, bound, B_AX_PLE_START_BOUND_MASK);
2031	val = u32_replace_bits(val, size_cfg->lnk_pge_num,
2032			       B_AX_PLE_FREE_PAGE_NUM_MASK);
2033	rtw89_write32(rtwdev, R_AX_PLE_PKTBUF_CFG, val);
2034
2035	return 0;
2036}
2037
2038static int chk_dle_rdy_ax(struct rtw89_dev *rtwdev, bool wde_or_ple)
2039{
2040	u32 reg, mask;
2041	u32 ini;
2042
2043	if (wde_or_ple) {
2044		reg = R_AX_WDE_INI_STATUS;
2045		mask = WDE_MGN_INI_RDY;
2046	} else {
2047		reg = R_AX_PLE_INI_STATUS;
2048		mask = PLE_MGN_INI_RDY;
2049	}
2050
2051	return read_poll_timeout(rtw89_read32, ini, (ini & mask) == mask, 1,
2052				2000, false, rtwdev, reg);
2053}
2054
2055#define INVALID_QT_WCPU U16_MAX
2056#define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx)			\
2057	do {								\
2058		val = u32_encode_bits(_min_x, B_AX_ ## _module ## _MIN_SIZE_MASK) | \
2059		      u32_encode_bits(_max_x, B_AX_ ## _module ## _MAX_SIZE_MASK);  \
2060		rtw89_write32(rtwdev,					\
2061			      R_AX_ ## _module ## _QTA ## _idx ## _CFG,	\
2062			      val);					\
2063	} while (0)
2064#define SET_QUOTA(_x, _module, _idx)					\
2065	SET_QUOTA_VAL(min_cfg->_x, max_cfg->_x, _module, _idx)
2066
2067static void wde_quota_cfg_ax(struct rtw89_dev *rtwdev,
2068			     const struct rtw89_wde_quota *min_cfg,
2069			     const struct rtw89_wde_quota *max_cfg,
2070			     u16 ext_wde_min_qt_wcpu)
2071{
2072	u16 min_qt_wcpu = ext_wde_min_qt_wcpu != INVALID_QT_WCPU ?
2073			  ext_wde_min_qt_wcpu : min_cfg->wcpu;
2074	u32 val;
2075
2076	SET_QUOTA(hif, WDE, 0);
2077	SET_QUOTA_VAL(min_qt_wcpu, max_cfg->wcpu, WDE, 1);
2078	SET_QUOTA(pkt_in, WDE, 3);
2079	SET_QUOTA(cpu_io, WDE, 4);
2080}
2081
2082static void ple_quota_cfg_ax(struct rtw89_dev *rtwdev,
2083			     const struct rtw89_ple_quota *min_cfg,
2084			     const struct rtw89_ple_quota *max_cfg)
2085{
2086	u32 val;
2087
2088	SET_QUOTA(cma0_tx, PLE, 0);
2089	SET_QUOTA(cma1_tx, PLE, 1);
2090	SET_QUOTA(c2h, PLE, 2);
2091	SET_QUOTA(h2c, PLE, 3);
2092	SET_QUOTA(wcpu, PLE, 4);
2093	SET_QUOTA(mpdu_proc, PLE, 5);
2094	SET_QUOTA(cma0_dma, PLE, 6);
2095	SET_QUOTA(cma1_dma, PLE, 7);
2096	SET_QUOTA(bb_rpt, PLE, 8);
2097	SET_QUOTA(wd_rel, PLE, 9);
2098	SET_QUOTA(cpu_io, PLE, 10);
2099	if (rtwdev->chip->chip_id == RTL8852C)
2100		SET_QUOTA(tx_rpt, PLE, 11);
2101}
2102
2103int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow)
2104{
2105	const struct rtw89_ple_quota *min_cfg, *max_cfg;
2106	const struct rtw89_dle_mem *cfg;
2107	u32 val;
2108
2109	if (rtwdev->chip->chip_id == RTL8852C)
2110		return 0;
2111
2112	if (rtwdev->mac.qta_mode != RTW89_QTA_SCC) {
2113		rtw89_err(rtwdev, "[ERR]support SCC mode only\n");
2114		return -EINVAL;
2115	}
2116
2117	if (wow)
2118		cfg = get_dle_mem_cfg(rtwdev, RTW89_QTA_WOW);
2119	else
2120		cfg = get_dle_mem_cfg(rtwdev, RTW89_QTA_SCC);
2121	if (!cfg) {
2122		rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n");
2123		return -EINVAL;
2124	}
2125
2126	min_cfg = cfg->ple_min_qt;
2127	max_cfg = cfg->ple_max_qt;
2128	SET_QUOTA(cma0_dma, PLE, 6);
2129	SET_QUOTA(cma1_dma, PLE, 7);
2130
2131	return 0;
2132}
2133#undef SET_QUOTA
2134
2135void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool enable)
2136{
2137	const struct rtw89_chip_info *chip = rtwdev->chip;
2138	u32 msk32 = B_AX_UC_MGNT_DEC | B_AX_BMC_MGNT_DEC;
2139
2140	if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
2141		return;
2142
2143	/* 8852C enable B_AX_UC_MGNT_DEC by default */
2144	if (chip->chip_id == RTL8852C)
2145		msk32 = B_AX_BMC_MGNT_DEC;
2146
2147	if (enable)
2148		rtw89_write32_set(rtwdev, R_AX_SEC_ENG_CTRL, msk32);
2149	else
2150		rtw89_write32_clr(rtwdev, R_AX_SEC_ENG_CTRL, msk32);
2151}
2152
2153static void dle_quota_cfg(struct rtw89_dev *rtwdev,
2154			  const struct rtw89_dle_mem *cfg,
2155			  u16 ext_wde_min_qt_wcpu)
2156{
2157	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
2158
2159	mac->wde_quota_cfg(rtwdev, cfg->wde_min_qt, cfg->wde_max_qt, ext_wde_min_qt_wcpu);
2160	mac->ple_quota_cfg(rtwdev, cfg->ple_min_qt, cfg->ple_max_qt);
2161}
2162
2163int rtw89_mac_dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
2164		       enum rtw89_qta_mode ext_mode)
2165{
2166	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
2167	const struct rtw89_dle_mem *cfg, *ext_cfg;
2168	u16 ext_wde_min_qt_wcpu = INVALID_QT_WCPU;
2169	int ret;
2170
2171	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
2172	if (ret)
2173		return ret;
2174
2175	cfg = get_dle_mem_cfg(rtwdev, mode);
2176	if (!cfg) {
2177		rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n");
2178		ret = -EINVAL;
2179		goto error;
2180	}
2181
2182	if (mode == RTW89_QTA_DLFW) {
2183		ext_cfg = get_dle_mem_cfg(rtwdev, ext_mode);
2184		if (!ext_cfg) {
2185			rtw89_err(rtwdev, "[ERR]get_dle_ext_mem_cfg %d\n",
2186				  ext_mode);
2187			ret = -EINVAL;
2188			goto error;
2189		}
2190		ext_wde_min_qt_wcpu = ext_cfg->wde_min_qt->wcpu;
2191	}
2192
2193	if (dle_used_size(cfg) != dle_expected_used_size(rtwdev, mode)) {
2194		rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n");
2195		ret = -EINVAL;
2196		goto error;
2197	}
2198
2199	mac->dle_func_en(rtwdev, false);
2200	mac->dle_clk_en(rtwdev, true);
2201
2202	ret = mac->dle_mix_cfg(rtwdev, cfg);
2203	if (ret) {
2204		rtw89_err(rtwdev, "[ERR] dle mix cfg\n");
2205		goto error;
2206	}
2207	dle_quota_cfg(rtwdev, cfg, ext_wde_min_qt_wcpu);
2208
2209	mac->dle_func_en(rtwdev, true);
2210
2211	ret = mac->chk_dle_rdy(rtwdev, true);
2212	if (ret) {
2213		rtw89_err(rtwdev, "[ERR]WDE cfg ready\n");
2214		return ret;
2215	}
2216
2217	ret = mac->chk_dle_rdy(rtwdev, false);
2218	if (ret) {
2219		rtw89_err(rtwdev, "[ERR]PLE cfg ready\n");
2220		return ret;
2221	}
2222
2223	return 0;
2224error:
2225	mac->dle_func_en(rtwdev, false);
2226	rtw89_err(rtwdev, "[ERR]trxcfg wde 0x8900 = %x\n",
2227		  rtw89_read32(rtwdev, R_AX_WDE_INI_STATUS));
2228	rtw89_err(rtwdev, "[ERR]trxcfg ple 0x8D00 = %x\n",
2229		  rtw89_read32(rtwdev, R_AX_PLE_INI_STATUS));
2230
2231	return ret;
2232}
2233
2234static int preload_init_set(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx,
2235			    enum rtw89_qta_mode mode)
2236{
2237	u32 reg, max_preld_size, min_rsvd_size;
2238
2239	max_preld_size = (mac_idx == RTW89_MAC_0 ?
2240			  PRELD_B0_ENT_NUM : PRELD_B1_ENT_NUM) * PRELD_AMSDU_SIZE;
2241	reg = mac_idx == RTW89_MAC_0 ?
2242	      R_AX_TXPKTCTL_B0_PRELD_CFG0 : R_AX_TXPKTCTL_B1_PRELD_CFG0;
2243	rtw89_write32_mask(rtwdev, reg, B_AX_B0_PRELD_USEMAXSZ_MASK, max_preld_size);
2244	rtw89_write32_set(rtwdev, reg, B_AX_B0_PRELD_FEN);
2245
2246	min_rsvd_size = PRELD_AMSDU_SIZE;
2247	reg = mac_idx == RTW89_MAC_0 ?
2248	      R_AX_TXPKTCTL_B0_PRELD_CFG1 : R_AX_TXPKTCTL_B1_PRELD_CFG1;
2249	rtw89_write32_mask(rtwdev, reg, B_AX_B0_PRELD_NXT_TXENDWIN_MASK, PRELD_NEXT_WND);
2250	rtw89_write32_mask(rtwdev, reg, B_AX_B0_PRELD_NXT_RSVMINSZ_MASK, min_rsvd_size);
2251
2252	return 0;
2253}
2254
2255static bool is_qta_poh(struct rtw89_dev *rtwdev)
2256{
2257	return rtwdev->hci.type == RTW89_HCI_TYPE_PCIE;
2258}
2259
2260int rtw89_mac_preload_init(struct rtw89_dev *rtwdev, enum rtw89_mac_idx mac_idx,
2261			   enum rtw89_qta_mode mode)
2262{
2263	const struct rtw89_chip_info *chip = rtwdev->chip;
2264
2265	if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev) ||
2266	    !is_qta_poh(rtwdev))
2267		return 0;
2268
2269	return preload_init_set(rtwdev, mac_idx, mode);
2270}
2271
2272static bool dle_is_txq_empty(struct rtw89_dev *rtwdev)
2273{
2274	u32 msk32;
2275	u32 val32;
2276
2277	msk32 = B_AX_WDE_EMPTY_QUE_CMAC0_ALL_AC | B_AX_WDE_EMPTY_QUE_CMAC0_MBH |
2278		B_AX_WDE_EMPTY_QUE_CMAC1_MBH | B_AX_WDE_EMPTY_QUE_CMAC0_WMM0 |
2279		B_AX_WDE_EMPTY_QUE_CMAC0_WMM1 | B_AX_WDE_EMPTY_QUE_OTHERS |
2280		B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX | B_AX_PLE_EMPTY_QTA_DMAC_H2C |
2281		B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX | B_AX_WDE_EMPTY_QUE_DMAC_PKTIN |
2282		B_AX_WDE_EMPTY_QTA_DMAC_HIF | B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU |
2283		B_AX_WDE_EMPTY_QTA_DMAC_PKTIN | B_AX_WDE_EMPTY_QTA_DMAC_CPUIO |
2284		B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL |
2285		B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL |
2286		B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX |
2287		B_AX_PLE_EMPTY_QTA_DMAC_CPUIO |
2288		B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU |
2289		B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU;
2290	val32 = rtw89_read32(rtwdev, R_AX_DLE_EMPTY0);
2291
2292	if ((val32 & msk32) == msk32)
2293		return true;
2294
2295	return false;
2296}
2297
2298static void _patch_ss2f_path(struct rtw89_dev *rtwdev)
2299{
2300	const struct rtw89_chip_info *chip = rtwdev->chip;
2301
2302	if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
2303		return;
2304
2305	rtw89_write32_mask(rtwdev, R_AX_SS2FINFO_PATH, B_AX_SS_DEST_QUEUE_MASK,
2306			   SS2F_PATH_WLCPU);
2307}
2308
2309static int sta_sch_init_ax(struct rtw89_dev *rtwdev)
2310{
2311	u32 p_val;
2312	u8 val;
2313	int ret;
2314
2315	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
2316	if (ret)
2317		return ret;
2318
2319	val = rtw89_read8(rtwdev, R_AX_SS_CTRL);
2320	val |= B_AX_SS_EN;
2321	rtw89_write8(rtwdev, R_AX_SS_CTRL, val);
2322
2323	ret = read_poll_timeout(rtw89_read32, p_val, p_val & B_AX_SS_INIT_DONE_1,
2324				1, TRXCFG_WAIT_CNT, false, rtwdev, R_AX_SS_CTRL);
2325	if (ret) {
2326		rtw89_err(rtwdev, "[ERR]STA scheduler init\n");
2327		return ret;
2328	}
2329
2330	rtw89_write32_set(rtwdev, R_AX_SS_CTRL, B_AX_SS_WARM_INIT_FLG);
2331	rtw89_write32_clr(rtwdev, R_AX_SS_CTRL, B_AX_SS_NONEMPTY_SS2FINFO_EN);
2332
2333	_patch_ss2f_path(rtwdev);
2334
2335	return 0;
2336}
2337
2338static int mpdu_proc_init_ax(struct rtw89_dev *rtwdev)
2339{
2340	int ret;
2341
2342	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
2343	if (ret)
2344		return ret;
2345
2346	rtw89_write32(rtwdev, R_AX_ACTION_FWD0, TRXCFG_MPDU_PROC_ACT_FRWD);
2347	rtw89_write32(rtwdev, R_AX_TF_FWD, TRXCFG_MPDU_PROC_TF_FRWD);
2348	rtw89_write32_set(rtwdev, R_AX_MPDU_PROC,
2349			  B_AX_APPEND_FCS | B_AX_A_ICV_ERR);
2350	rtw89_write32(rtwdev, R_AX_CUT_AMSDU_CTRL, TRXCFG_MPDU_PROC_CUT_CTRL);
2351
2352	return 0;
2353}
2354
2355static int sec_eng_init_ax(struct rtw89_dev *rtwdev)
2356{
2357	const struct rtw89_chip_info *chip = rtwdev->chip;
2358	u32 val = 0;
2359	int ret;
2360
2361	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
2362	if (ret)
2363		return ret;
2364
2365	val = rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL);
2366	/* init clock */
2367	val |= (B_AX_CLK_EN_CGCMP | B_AX_CLK_EN_WAPI | B_AX_CLK_EN_WEP_TKIP);
2368	/* init TX encryption */
2369	val |= (B_AX_SEC_TX_ENC | B_AX_SEC_RX_DEC);
2370	val |= (B_AX_MC_DEC | B_AX_BC_DEC);
2371	if (chip->chip_id == RTL8852C)
2372		val |= B_AX_UC_MGNT_DEC;
2373	if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
2374	    chip->chip_id == RTL8851B ||
2375	    (chip->chip_id == RTL8852C && rtwdev->hci.type == RTW89_HCI_TYPE_USB))
2376		val &= ~B_AX_TX_PARTIAL_MODE;
2377	rtw89_write32(rtwdev, R_AX_SEC_ENG_CTRL, val);
2378
2379	/* init MIC ICV append */
2380	val = rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC);
2381	val |= (B_AX_APPEND_ICV | B_AX_APPEND_MIC);
2382
2383	/* option init */
2384	rtw89_write32(rtwdev, R_AX_SEC_MPDU_PROC, val);
2385
2386	if (chip->chip_id == RTL8852C)
2387		rtw89_write32_mask(rtwdev, R_AX_SEC_DEBUG1,
2388				   B_AX_TX_TIMEOUT_SEL_MASK, AX_TX_TO_VAL);
2389
2390	return 0;
2391}
2392
2393static int dmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2394{
2395	int ret;
2396
2397	ret = rtw89_mac_dle_init(rtwdev, rtwdev->mac.qta_mode, RTW89_QTA_INVALID);
2398	if (ret) {
2399		rtw89_err(rtwdev, "[ERR]DLE init %d\n", ret);
2400		return ret;
2401	}
2402
2403	ret = rtw89_mac_preload_init(rtwdev, RTW89_MAC_0, rtwdev->mac.qta_mode);
2404	if (ret) {
2405		rtw89_err(rtwdev, "[ERR]preload init %d\n", ret);
2406		return ret;
2407	}
2408
2409	ret = rtw89_mac_hfc_init(rtwdev, true, true, true);
2410	if (ret) {
2411		rtw89_err(rtwdev, "[ERR]HCI FC init %d\n", ret);
2412		return ret;
2413	}
2414
2415	ret = sta_sch_init_ax(rtwdev);
2416	if (ret) {
2417		rtw89_err(rtwdev, "[ERR]STA SCH init %d\n", ret);
2418		return ret;
2419	}
2420
2421	ret = mpdu_proc_init_ax(rtwdev);
2422	if (ret) {
2423		rtw89_err(rtwdev, "[ERR]MPDU Proc init %d\n", ret);
2424		return ret;
2425	}
2426
2427	ret = sec_eng_init_ax(rtwdev);
2428	if (ret) {
2429		rtw89_err(rtwdev, "[ERR]Security Engine init %d\n", ret);
2430		return ret;
2431	}
2432
2433	return ret;
2434}
2435
2436static int addr_cam_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2437{
2438	u32 val, reg;
2439	u16 p_val;
2440	int ret;
2441
2442	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2443	if (ret)
2444		return ret;
2445
2446	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_ADDR_CAM_CTRL, mac_idx);
2447
2448	val = rtw89_read32(rtwdev, reg);
2449	val |= u32_encode_bits(0x7f, B_AX_ADDR_CAM_RANGE_MASK) |
2450	       B_AX_ADDR_CAM_CLR | B_AX_ADDR_CAM_EN;
2451	rtw89_write32(rtwdev, reg, val);
2452
2453	ret = read_poll_timeout(rtw89_read16, p_val, !(p_val & B_AX_ADDR_CAM_CLR),
2454				1, TRXCFG_WAIT_CNT, false, rtwdev, reg);
2455	if (ret) {
2456		rtw89_err(rtwdev, "[ERR]ADDR_CAM reset\n");
2457		return ret;
2458	}
2459
2460	return 0;
2461}
2462
2463static int scheduler_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2464{
2465	int ret;
2466	u32 reg;
2467	u32 val;
2468
2469	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2470	if (ret)
2471		return ret;
2472
2473	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PREBKF_CFG_1, mac_idx);
2474	if (rtwdev->chip->chip_id == RTL8852C)
2475		rtw89_write32_mask(rtwdev, reg, B_AX_SIFS_MACTXEN_T1_MASK,
2476				   SIFS_MACTXEN_T1_V1);
2477	else
2478		rtw89_write32_mask(rtwdev, reg, B_AX_SIFS_MACTXEN_T1_MASK,
2479				   SIFS_MACTXEN_T1);
2480
2481	if (rtw89_is_rtl885xb(rtwdev)) {
2482		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_SCH_EXT_CTRL, mac_idx);
2483		rtw89_write32_set(rtwdev, reg, B_AX_PORT_RST_TSF_ADV);
2484	}
2485
2486	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CCA_CFG_0, mac_idx);
2487	rtw89_write32_clr(rtwdev, reg, B_AX_BTCCA_EN);
2488
2489	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PREBKF_CFG_0, mac_idx);
2490	if (rtwdev->chip->chip_id == RTL8852C) {
2491		val = rtw89_read32_mask(rtwdev, R_AX_SEC_ENG_CTRL,
2492					B_AX_TX_PARTIAL_MODE);
2493		if (!val)
2494			rtw89_write32_mask(rtwdev, reg, B_AX_PREBKF_TIME_MASK,
2495					   SCH_PREBKF_24US);
2496	} else {
2497		rtw89_write32_mask(rtwdev, reg, B_AX_PREBKF_TIME_MASK,
2498				   SCH_PREBKF_24US);
2499	}
2500
2501	return 0;
2502}
2503
2504static int rtw89_mac_typ_fltr_opt_ax(struct rtw89_dev *rtwdev,
2505				     enum rtw89_machdr_frame_type type,
2506				     enum rtw89_mac_fwd_target fwd_target,
2507				     u8 mac_idx)
2508{
2509	u32 reg;
2510	u32 val;
2511
2512	switch (fwd_target) {
2513	case RTW89_FWD_DONT_CARE:
2514		val = RX_FLTR_FRAME_DROP;
2515		break;
2516	case RTW89_FWD_TO_HOST:
2517		val = RX_FLTR_FRAME_TO_HOST;
2518		break;
2519	case RTW89_FWD_TO_WLAN_CPU:
2520		val = RX_FLTR_FRAME_TO_WLCPU;
2521		break;
2522	default:
2523		rtw89_err(rtwdev, "[ERR]set rx filter fwd target err\n");
2524		return -EINVAL;
2525	}
2526
2527	switch (type) {
2528	case RTW89_MGNT:
2529		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_MGNT_FLTR, mac_idx);
2530		break;
2531	case RTW89_CTRL:
2532		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CTRL_FLTR, mac_idx);
2533		break;
2534	case RTW89_DATA:
2535		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_DATA_FLTR, mac_idx);
2536		break;
2537	default:
2538		rtw89_err(rtwdev, "[ERR]set rx filter type err\n");
2539		return -EINVAL;
2540	}
2541	rtw89_write32(rtwdev, reg, val);
2542
2543	return 0;
2544}
2545
2546void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr)
2547{
2548	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
2549	u32 reg;
2550	u32 val;
2551
2552	reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, mac_idx);
2553
2554	val = rtw89_read32(rtwdev, reg);
2555	/* B_AX_RX_FLTR_CFG_MASK is not a consecutive bit mask */
2556	val = (val & ~B_AX_RX_FLTR_CFG_MASK) | (rx_fltr & B_AX_RX_FLTR_CFG_MASK);
2557	rtw89_write32(rtwdev, reg, val);
2558}
2559
2560static int rx_fltr_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2561{
2562	int ret, i;
2563	u32 mac_ftlr, plcp_ftlr;
2564
2565	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2566	if (ret)
2567		return ret;
2568
2569	for (i = RTW89_MGNT; i <= RTW89_DATA; i++) {
2570		ret = rtw89_mac_typ_fltr_opt_ax(rtwdev, i, RTW89_FWD_TO_HOST,
2571						mac_idx);
2572		if (ret)
2573			return ret;
2574	}
2575	mac_ftlr = rtwdev->hal.rx_fltr;
2576	plcp_ftlr = B_AX_CCK_CRC_CHK | B_AX_CCK_SIG_CHK |
2577		    B_AX_LSIG_PARITY_CHK_EN | B_AX_SIGA_CRC_CHK |
2578		    B_AX_VHT_SU_SIGB_CRC_CHK | B_AX_VHT_MU_SIGB_CRC_CHK |
2579		    B_AX_HE_SIGB_CRC_CHK;
2580	rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_RX_FLTR_OPT, mac_idx),
2581		      mac_ftlr);
2582	rtw89_write16(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_PLCP_HDR_FLTR, mac_idx),
2583		      plcp_ftlr);
2584
2585	return 0;
2586}
2587
2588static void _patch_dis_resp_chk(struct rtw89_dev *rtwdev, u8 mac_idx)
2589{
2590	u32 reg, val32;
2591	u32 b_rsp_chk_nav, b_rsp_chk_cca;
2592
2593	b_rsp_chk_nav = B_AX_RSP_CHK_TXNAV | B_AX_RSP_CHK_INTRA_NAV |
2594			B_AX_RSP_CHK_BASIC_NAV;
2595	b_rsp_chk_cca = B_AX_RSP_CHK_SEC_CCA_80 | B_AX_RSP_CHK_SEC_CCA_40 |
2596			B_AX_RSP_CHK_SEC_CCA_20 | B_AX_RSP_CHK_BTCCA |
2597			B_AX_RSP_CHK_EDCCA | B_AX_RSP_CHK_CCA;
2598
2599	switch (rtwdev->chip->chip_id) {
2600	case RTL8852A:
2601	case RTL8852B:
2602		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RSP_CHK_SIG, mac_idx);
2603		val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_nav;
2604		rtw89_write32(rtwdev, reg, val32);
2605
2606		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_0, mac_idx);
2607		val32 = rtw89_read32(rtwdev, reg) & ~b_rsp_chk_cca;
2608		rtw89_write32(rtwdev, reg, val32);
2609		break;
2610	default:
2611		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RSP_CHK_SIG, mac_idx);
2612		val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_nav;
2613		rtw89_write32(rtwdev, reg, val32);
2614
2615		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_0, mac_idx);
2616		val32 = rtw89_read32(rtwdev, reg) | b_rsp_chk_cca;
2617		rtw89_write32(rtwdev, reg, val32);
2618		break;
2619	}
2620}
2621
2622static int cca_ctrl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2623{
2624	u32 val, reg;
2625	int ret;
2626
2627	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2628	if (ret)
2629		return ret;
2630
2631	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CCA_CONTROL, mac_idx);
2632	val = rtw89_read32(rtwdev, reg);
2633	val |= (B_AX_TB_CHK_BASIC_NAV | B_AX_TB_CHK_BTCCA |
2634		B_AX_TB_CHK_EDCCA | B_AX_TB_CHK_CCA_P20 |
2635		B_AX_SIFS_CHK_BTCCA | B_AX_SIFS_CHK_CCA_P20 |
2636		B_AX_CTN_CHK_INTRA_NAV |
2637		B_AX_CTN_CHK_BASIC_NAV | B_AX_CTN_CHK_BTCCA |
2638		B_AX_CTN_CHK_EDCCA | B_AX_CTN_CHK_CCA_S80 |
2639		B_AX_CTN_CHK_CCA_S40 | B_AX_CTN_CHK_CCA_S20 |
2640		B_AX_CTN_CHK_CCA_P20);
2641	val &= ~(B_AX_TB_CHK_TX_NAV | B_AX_TB_CHK_CCA_S80 |
2642		 B_AX_TB_CHK_CCA_S40 | B_AX_TB_CHK_CCA_S20 |
2643		 B_AX_SIFS_CHK_CCA_S80 | B_AX_SIFS_CHK_CCA_S40 |
2644		 B_AX_SIFS_CHK_CCA_S20 | B_AX_CTN_CHK_TXNAV |
2645		 B_AX_SIFS_CHK_EDCCA);
2646
2647	rtw89_write32(rtwdev, reg, val);
2648
2649	_patch_dis_resp_chk(rtwdev, mac_idx);
2650
2651	return 0;
2652}
2653
2654static int nav_ctrl_init_ax(struct rtw89_dev *rtwdev)
2655{
2656	rtw89_write32_set(rtwdev, R_AX_WMAC_NAV_CTL, B_AX_WMAC_PLCP_UP_NAV_EN |
2657						     B_AX_WMAC_TF_UP_NAV_EN |
2658						     B_AX_WMAC_NAV_UPPER_EN);
2659	rtw89_write32_mask(rtwdev, R_AX_WMAC_NAV_CTL, B_AX_WMAC_NAV_UPPER_MASK, NAV_25MS);
2660
2661	return 0;
2662}
2663
2664static int spatial_reuse_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2665{
2666	u32 reg;
2667	int ret;
2668
2669	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2670	if (ret)
2671		return ret;
2672	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RX_SR_CTRL, mac_idx);
2673	rtw89_write8_clr(rtwdev, reg, B_AX_SR_EN);
2674
2675	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BSSID_SRC_CTRL, mac_idx);
2676	rtw89_write8_set(rtwdev, reg, B_AX_PLCP_SRC_EN);
2677
2678	return 0;
2679}
2680
2681static int tmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2682{
2683	u32 reg;
2684	int ret;
2685
2686	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2687	if (ret)
2688		return ret;
2689
2690	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_MAC_LOOPBACK, mac_idx);
2691	rtw89_write32_clr(rtwdev, reg, B_AX_MACLBK_EN);
2692
2693	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TCR0, mac_idx);
2694	rtw89_write32_mask(rtwdev, reg, B_AX_TCR_UDF_THSD_MASK, TCR_UDF_THSD);
2695
2696	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TXD_FIFO_CTRL, mac_idx);
2697	rtw89_write32_mask(rtwdev, reg, B_AX_TXDFIFO_HIGH_MCS_THRE_MASK, TXDFIFO_HIGH_MCS_THRE);
2698	rtw89_write32_mask(rtwdev, reg, B_AX_TXDFIFO_LOW_MCS_THRE_MASK, TXDFIFO_LOW_MCS_THRE);
2699
2700	return 0;
2701}
2702
2703static int trxptcl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2704{
2705	const struct rtw89_chip_info *chip = rtwdev->chip;
2706	const struct rtw89_rrsr_cfgs *rrsr = chip->rrsr_cfgs;
2707	u32 reg, val, sifs;
2708	int ret;
2709
2710	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2711	if (ret)
2712		return ret;
2713
2714	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_0, mac_idx);
2715	val = rtw89_read32(rtwdev, reg);
2716	val &= ~B_AX_WMAC_SPEC_SIFS_CCK_MASK;
2717	val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_CCK_MASK, WMAC_SPEC_SIFS_CCK);
2718
2719	switch (rtwdev->chip->chip_id) {
2720	case RTL8852A:
2721		sifs = WMAC_SPEC_SIFS_OFDM_52A;
2722		break;
2723	case RTL8851B:
2724	case RTL8852B:
2725	case RTL8852BT:
2726		sifs = WMAC_SPEC_SIFS_OFDM_52B;
2727		break;
2728	default:
2729		sifs = WMAC_SPEC_SIFS_OFDM_52C;
2730		break;
2731	}
2732	val &= ~B_AX_WMAC_SPEC_SIFS_OFDM_MASK;
2733	val |= FIELD_PREP(B_AX_WMAC_SPEC_SIFS_OFDM_MASK, sifs);
2734	rtw89_write32(rtwdev, reg, val);
2735
2736	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RXTRIG_TEST_USER_2, mac_idx);
2737	rtw89_write32_set(rtwdev, reg, B_AX_RXTRIG_FCSCHK_EN);
2738
2739	reg = rtw89_mac_reg_by_idx(rtwdev, rrsr->ref_rate.addr, mac_idx);
2740	rtw89_write32_mask(rtwdev, reg, rrsr->ref_rate.mask, rrsr->ref_rate.data);
2741	reg = rtw89_mac_reg_by_idx(rtwdev, rrsr->rsc.addr, mac_idx);
2742	rtw89_write32_mask(rtwdev, reg, rrsr->rsc.mask, rrsr->rsc.data);
2743
2744	return 0;
2745}
2746
2747static void rst_bacam(struct rtw89_dev *rtwdev)
2748{
2749	u32 val32;
2750	int ret;
2751
2752	rtw89_write32_mask(rtwdev, R_AX_RESPBA_CAM_CTRL, B_AX_BACAM_RST_MASK,
2753			   S_AX_BACAM_RST_ALL);
2754
2755	ret = read_poll_timeout_atomic(rtw89_read32_mask, val32, val32 == 0,
2756				       1, 1000, false,
2757				       rtwdev, R_AX_RESPBA_CAM_CTRL, B_AX_BACAM_RST_MASK);
2758	if (ret)
2759		rtw89_warn(rtwdev, "failed to reset BA CAM\n");
2760}
2761
2762static int rmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2763{
2764#define TRXCFG_RMAC_CCA_TO	32
2765#define TRXCFG_RMAC_DATA_TO	15
2766#define RX_MAX_LEN_UNIT 512
2767#define PLD_RLS_MAX_PG 127
2768#define RX_SPEC_MAX_LEN (11454 + RX_MAX_LEN_UNIT)
2769	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
2770	int ret;
2771	u32 reg, rx_max_len, rx_qta;
2772	u16 val;
2773
2774	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2775	if (ret)
2776		return ret;
2777
2778	if (mac_idx == RTW89_MAC_0)
2779		rst_bacam(rtwdev);
2780
2781	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RESPBA_CAM_CTRL, mac_idx);
2782	rtw89_write8_set(rtwdev, reg, B_AX_SSN_SEL);
2783
2784	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_DLK_PROTECT_CTL, mac_idx);
2785	val = rtw89_read16(rtwdev, reg);
2786	val = u16_replace_bits(val, TRXCFG_RMAC_DATA_TO,
2787			       B_AX_RX_DLK_DATA_TIME_MASK);
2788	val = u16_replace_bits(val, TRXCFG_RMAC_CCA_TO,
2789			       B_AX_RX_DLK_CCA_TIME_MASK);
2790	if (chip_id == RTL8852BT)
2791		val |= B_AX_RX_DLK_RST_EN;
2792	rtw89_write16(rtwdev, reg, val);
2793
2794	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RCR, mac_idx);
2795	rtw89_write8_mask(rtwdev, reg, B_AX_CH_EN_MASK, 0x1);
2796
2797	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RX_FLTR_OPT, mac_idx);
2798	if (mac_idx == RTW89_MAC_0)
2799		rx_qta = rtwdev->mac.dle_info.c0_rx_qta;
2800	else
2801		rx_qta = rtwdev->mac.dle_info.c1_rx_qta;
2802	rx_qta = min_t(u32, rx_qta, PLD_RLS_MAX_PG);
2803	rx_max_len = rx_qta * rtwdev->mac.dle_info.ple_pg_size;
2804	rx_max_len = min_t(u32, rx_max_len, RX_SPEC_MAX_LEN);
2805	rx_max_len /= RX_MAX_LEN_UNIT;
2806	rtw89_write32_mask(rtwdev, reg, B_AX_RX_MPDU_MAX_LEN_MASK, rx_max_len);
2807
2808	if (chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV) {
2809		rtw89_write16_mask(rtwdev,
2810				   rtw89_mac_reg_by_idx(rtwdev, R_AX_DLK_PROTECT_CTL, mac_idx),
2811				   B_AX_RX_DLK_CCA_TIME_MASK, 0);
2812		rtw89_write16_set(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_RCR, mac_idx),
2813				  BIT(12));
2814	}
2815
2816	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PLCP_HDR_FLTR, mac_idx);
2817	rtw89_write8_clr(rtwdev, reg, B_AX_VHT_SU_SIGB_CRC_CHK);
2818
2819	return ret;
2820}
2821
2822static int cmac_com_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2823{
2824	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
2825	u32 val, reg;
2826	int ret;
2827
2828	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2829	if (ret)
2830		return ret;
2831
2832	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TX_SUB_CARRIER_VALUE, mac_idx);
2833	val = rtw89_read32(rtwdev, reg);
2834	val = u32_replace_bits(val, 0, B_AX_TXSC_20M_MASK);
2835	val = u32_replace_bits(val, 0, B_AX_TXSC_40M_MASK);
2836	val = u32_replace_bits(val, 0, B_AX_TXSC_80M_MASK);
2837	rtw89_write32(rtwdev, reg, val);
2838
2839	if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
2840		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_RRSR1, mac_idx);
2841		rtw89_write32_mask(rtwdev, reg, B_AX_RRSR_RATE_EN_MASK, RRSR_OFDM_CCK_EN);
2842	}
2843
2844	return 0;
2845}
2846
2847bool rtw89_mac_is_qta_dbcc(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode)
2848{
2849	const struct rtw89_dle_mem *cfg;
2850
2851	cfg = get_dle_mem_cfg(rtwdev, mode);
2852	if (!cfg) {
2853		rtw89_err(rtwdev, "[ERR]get_dle_mem_cfg\n");
2854		return false;
2855	}
2856
2857	return (cfg->ple_min_qt->cma1_dma && cfg->ple_max_qt->cma1_dma);
2858}
2859
2860static int ptcl_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2861{
2862	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
2863	u32 val, reg;
2864	int ret;
2865
2866	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2867	if (ret)
2868		return ret;
2869
2870	if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) {
2871		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_SIFS_SETTING, mac_idx);
2872		val = rtw89_read32(rtwdev, reg);
2873		val = u32_replace_bits(val, S_AX_CTS2S_TH_1K,
2874				       B_AX_HW_CTS2SELF_PKT_LEN_TH_MASK);
2875		val = u32_replace_bits(val, S_AX_CTS2S_TH_SEC_256B,
2876				       B_AX_HW_CTS2SELF_PKT_LEN_TH_TWW_MASK);
2877		val |= B_AX_HW_CTS2SELF_EN;
2878		rtw89_write32(rtwdev, reg, val);
2879
2880		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_FSM_MON, mac_idx);
2881		val = rtw89_read32(rtwdev, reg);
2882		val = u32_replace_bits(val, S_AX_PTCL_TO_2MS, B_AX_PTCL_TX_ARB_TO_THR_MASK);
2883		val &= ~B_AX_PTCL_TX_ARB_TO_MODE;
2884		rtw89_write32(rtwdev, reg, val);
2885	}
2886
2887	if (mac_idx == RTW89_MAC_0) {
2888		rtw89_write8_set(rtwdev, R_AX_PTCL_COMMON_SETTING_0,
2889				 B_AX_CMAC_TX_MODE_0 | B_AX_CMAC_TX_MODE_1);
2890		rtw89_write8_clr(rtwdev, R_AX_PTCL_COMMON_SETTING_0,
2891				 B_AX_PTCL_TRIGGER_SS_EN_0 |
2892				 B_AX_PTCL_TRIGGER_SS_EN_1 |
2893				 B_AX_PTCL_TRIGGER_SS_EN_UL);
2894		rtw89_write8_mask(rtwdev, R_AX_PTCLRPT_FULL_HDL,
2895				  B_AX_SPE_RPT_PATH_MASK, FWD_TO_WLCPU);
2896	} else if (mac_idx == RTW89_MAC_1) {
2897		rtw89_write8_mask(rtwdev, R_AX_PTCLRPT_FULL_HDL_C1,
2898				  B_AX_SPE_RPT_PATH_MASK, FWD_TO_WLCPU);
2899	}
2900
2901	if (chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)) {
2902		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_AGG_LEN_VHT_0, mac_idx);
2903		rtw89_write32_mask(rtwdev, reg,
2904				   B_AX_AMPDU_MAX_LEN_VHT_MASK, 0x3FF80);
2905	}
2906
2907	return 0;
2908}
2909
2910static int cmac_dma_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2911{
2912	u32 reg;
2913	int ret;
2914
2915	if (!rtw89_is_rtl885xb(rtwdev))
2916		return 0;
2917
2918	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
2919	if (ret)
2920		return ret;
2921
2922	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_RXDMA_CTRL_0, mac_idx);
2923	rtw89_write8_clr(rtwdev, reg, RX_FULL_MODE);
2924
2925	return 0;
2926}
2927
2928static int cmac_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
2929{
2930	int ret;
2931
2932	ret = scheduler_init_ax(rtwdev, mac_idx);
2933	if (ret) {
2934		rtw89_err(rtwdev, "[ERR]CMAC%d SCH init %d\n", mac_idx, ret);
2935		return ret;
2936	}
2937
2938	ret = addr_cam_init_ax(rtwdev, mac_idx);
2939	if (ret) {
2940		rtw89_err(rtwdev, "[ERR]CMAC%d ADDR_CAM reset %d\n", mac_idx,
2941			  ret);
2942		return ret;
2943	}
2944
2945	ret = rx_fltr_init_ax(rtwdev, mac_idx);
2946	if (ret) {
2947		rtw89_err(rtwdev, "[ERR]CMAC%d RX filter init %d\n", mac_idx,
2948			  ret);
2949		return ret;
2950	}
2951
2952	ret = cca_ctrl_init_ax(rtwdev, mac_idx);
2953	if (ret) {
2954		rtw89_err(rtwdev, "[ERR]CMAC%d CCA CTRL init %d\n", mac_idx,
2955			  ret);
2956		return ret;
2957	}
2958
2959	ret = nav_ctrl_init_ax(rtwdev);
2960	if (ret) {
2961		rtw89_err(rtwdev, "[ERR]CMAC%d NAV CTRL init %d\n", mac_idx,
2962			  ret);
2963		return ret;
2964	}
2965
2966	ret = spatial_reuse_init_ax(rtwdev, mac_idx);
2967	if (ret) {
2968		rtw89_err(rtwdev, "[ERR]CMAC%d Spatial Reuse init %d\n",
2969			  mac_idx, ret);
2970		return ret;
2971	}
2972
2973	ret = tmac_init_ax(rtwdev, mac_idx);
2974	if (ret) {
2975		rtw89_err(rtwdev, "[ERR]CMAC%d TMAC init %d\n", mac_idx, ret);
2976		return ret;
2977	}
2978
2979	ret = trxptcl_init_ax(rtwdev, mac_idx);
2980	if (ret) {
2981		rtw89_err(rtwdev, "[ERR]CMAC%d TRXPTCL init %d\n", mac_idx, ret);
2982		return ret;
2983	}
2984
2985	ret = rmac_init_ax(rtwdev, mac_idx);
2986	if (ret) {
2987		rtw89_err(rtwdev, "[ERR]CMAC%d RMAC init %d\n", mac_idx, ret);
2988		return ret;
2989	}
2990
2991	ret = cmac_com_init_ax(rtwdev, mac_idx);
2992	if (ret) {
2993		rtw89_err(rtwdev, "[ERR]CMAC%d Com init %d\n", mac_idx, ret);
2994		return ret;
2995	}
2996
2997	ret = ptcl_init_ax(rtwdev, mac_idx);
2998	if (ret) {
2999		rtw89_err(rtwdev, "[ERR]CMAC%d PTCL init %d\n", mac_idx, ret);
3000		return ret;
3001	}
3002
3003	ret = cmac_dma_init_ax(rtwdev, mac_idx);
3004	if (ret) {
3005		rtw89_err(rtwdev, "[ERR]CMAC%d DMA init %d\n", mac_idx, ret);
3006		return ret;
3007	}
3008
3009	return ret;
3010}
3011
3012static int rtw89_mac_read_phycap(struct rtw89_dev *rtwdev,
3013				 struct rtw89_mac_c2h_info *c2h_info, u8 part_num)
3014{
3015	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
3016	const struct rtw89_chip_info *chip = rtwdev->chip;
3017	struct rtw89_mac_h2c_info h2c_info = {};
3018	enum rtw89_mac_c2h_type c2h_type;
3019	u8 content_len;
3020	int ret;
3021
3022	if (chip->chip_gen == RTW89_CHIP_AX)
3023		content_len = 0;
3024	else
3025		content_len = 2;
3026
3027	switch (part_num) {
3028	case 0:
3029		c2h_type = RTW89_FWCMD_C2HREG_FUNC_PHY_CAP;
3030		break;
3031	case 1:
3032		c2h_type = RTW89_FWCMD_C2HREG_FUNC_PHY_CAP_PART1;
3033		break;
3034	default:
3035		return -EINVAL;
3036	}
3037
3038	mac->cnv_efuse_state(rtwdev, false);
3039
3040	h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE;
3041	h2c_info.content_len = content_len;
3042	h2c_info.u.hdr.w0 = u32_encode_bits(part_num, RTW89_H2CREG_GET_FEATURE_PART_NUM);
3043
3044	ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, c2h_info);
3045	if (ret)
3046		goto out;
3047
3048	if (c2h_info->id != c2h_type)
3049		ret = -EINVAL;
3050
3051out:
3052	mac->cnv_efuse_state(rtwdev, true);
3053
3054	return ret;
3055}
3056
3057static int rtw89_mac_setup_phycap_part0(struct rtw89_dev *rtwdev)
3058{
3059	const struct rtw89_chip_info *chip = rtwdev->chip;
3060	const struct rtw89_c2hreg_phycap *phycap;
3061	struct rtw89_efuse *efuse = &rtwdev->efuse;
3062	struct rtw89_mac_c2h_info c2h_info = {};
3063	struct rtw89_hal *hal = &rtwdev->hal;
3064	u8 protocol;
3065	u8 tx_nss;
3066	u8 rx_nss;
3067	u8 tx_ant;
3068	u8 rx_ant;
3069	int ret;
3070
3071	ret = rtw89_mac_read_phycap(rtwdev, &c2h_info, 0);
3072	if (ret)
3073		return ret;
3074
3075	phycap = &c2h_info.u.phycap;
3076
3077	tx_nss = u32_get_bits(phycap->w1, RTW89_C2HREG_PHYCAP_W1_TX_NSS);
3078	rx_nss = u32_get_bits(phycap->w0, RTW89_C2HREG_PHYCAP_W0_RX_NSS);
3079	tx_ant = u32_get_bits(phycap->w3, RTW89_C2HREG_PHYCAP_W3_ANT_TX_NUM);
3080	rx_ant = u32_get_bits(phycap->w3, RTW89_C2HREG_PHYCAP_W3_ANT_RX_NUM);
3081
3082	hal->tx_nss = tx_nss ? min_t(u8, tx_nss, chip->tx_nss) : chip->tx_nss;
3083	hal->rx_nss = rx_nss ? min_t(u8, rx_nss, chip->rx_nss) : chip->rx_nss;
3084
3085	if (tx_ant == 1)
3086		hal->antenna_tx = RF_B;
3087	if (rx_ant == 1)
3088		hal->antenna_rx = RF_B;
3089
3090	if (tx_nss == 1 && tx_ant == 2 && rx_ant == 2) {
3091		hal->antenna_tx = RF_B;
3092		hal->tx_path_diversity = true;
3093	}
3094
3095	if (chip->rf_path_num == 1) {
3096		hal->antenna_tx = RF_A;
3097		hal->antenna_rx = RF_A;
3098		if ((efuse->rfe_type % 3) == 2)
3099			hal->ant_diversity = true;
3100	}
3101
3102	rtw89_debug(rtwdev, RTW89_DBG_FW,
3103		    "phycap hal/phy/chip: tx_nss=0x%x/0x%x/0x%x rx_nss=0x%x/0x%x/0x%x\n",
3104		    hal->tx_nss, tx_nss, chip->tx_nss,
3105		    hal->rx_nss, rx_nss, chip->rx_nss);
3106	rtw89_debug(rtwdev, RTW89_DBG_FW,
3107		    "ant num/bitmap: tx=%d/0x%x rx=%d/0x%x\n",
3108		    tx_ant, hal->antenna_tx, rx_ant, hal->antenna_rx);
3109	rtw89_debug(rtwdev, RTW89_DBG_FW, "TX path diversity=%d\n", hal->tx_path_diversity);
3110	rtw89_debug(rtwdev, RTW89_DBG_FW, "Antenna diversity=%d\n", hal->ant_diversity);
3111
3112	protocol = u32_get_bits(phycap->w1, RTW89_C2HREG_PHYCAP_W1_PROT);
3113	if (protocol < RTW89_C2HREG_PHYCAP_W1_PROT_11BE)
3114		hal->no_eht = true;
3115
3116	return 0;
3117}
3118
3119static int rtw89_mac_setup_phycap_part1(struct rtw89_dev *rtwdev)
3120{
3121	const struct rtw89_chip_variant *variant = rtwdev->variant;
3122	const struct rtw89_c2hreg_phycap *phycap;
3123	struct rtw89_mac_c2h_info c2h_info = {};
3124	struct rtw89_hal *hal = &rtwdev->hal;
3125	u8 qam_raw, qam;
3126	int ret;
3127
3128	ret = rtw89_mac_read_phycap(rtwdev, &c2h_info, 1);
3129	if (ret)
3130		return ret;
3131
3132	phycap = &c2h_info.u.phycap;
3133
3134	qam_raw = u32_get_bits(phycap->w2, RTW89_C2HREG_PHYCAP_P1_W2_QAM);
3135
3136	switch (qam_raw) {
3137	case RTW89_C2HREG_PHYCAP_P1_W2_QAM_256:
3138	case RTW89_C2HREG_PHYCAP_P1_W2_QAM_1024:
3139	case RTW89_C2HREG_PHYCAP_P1_W2_QAM_4096:
3140		qam = qam_raw;
3141		break;
3142	default:
3143		qam = RTW89_C2HREG_PHYCAP_P1_W2_QAM_4096;
3144		break;
3145	}
3146
3147	if ((variant && variant->no_mcs_12_13) ||
3148	    qam <= RTW89_C2HREG_PHYCAP_P1_W2_QAM_1024)
3149		hal->no_mcs_12_13 = true;
3150
3151	rtw89_debug(rtwdev, RTW89_DBG_FW, "phycap qam=%d/%d no_mcs_12_13=%d\n",
3152		    qam_raw, qam, hal->no_mcs_12_13);
3153
3154	return 0;
3155}
3156
3157int rtw89_mac_setup_phycap(struct rtw89_dev *rtwdev)
3158{
3159	const struct rtw89_chip_info *chip = rtwdev->chip;
3160	int ret;
3161
3162	ret = rtw89_mac_setup_phycap_part0(rtwdev);
3163	if (ret)
3164		return ret;
3165
3166	if (chip->chip_gen == RTW89_CHIP_AX ||
3167	    RTW89_CHK_FW_FEATURE(NO_PHYCAP_P1, &rtwdev->fw))
3168		return 0;
3169
3170	return rtw89_mac_setup_phycap_part1(rtwdev);
3171}
3172
3173static int rtw89_hw_sch_tx_en_h2c(struct rtw89_dev *rtwdev, u8 band,
3174				  u16 tx_en_u16, u16 mask_u16)
3175{
3176	struct rtw89_mac_c2h_info c2h_info = {0};
3177	struct rtw89_mac_h2c_info h2c_info = {0};
3178	struct rtw89_h2creg_sch_tx_en *sch_tx_en = &h2c_info.u.sch_tx_en;
3179	int ret;
3180
3181	h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_SCH_TX_EN;
3182	h2c_info.content_len = sizeof(*sch_tx_en) - RTW89_H2CREG_HDR_LEN;
3183
3184	u32p_replace_bits(&sch_tx_en->w0, tx_en_u16, RTW89_H2CREG_SCH_TX_EN_W0_EN);
3185	u32p_replace_bits(&sch_tx_en->w1, mask_u16, RTW89_H2CREG_SCH_TX_EN_W1_MASK);
3186	u32p_replace_bits(&sch_tx_en->w1, band, RTW89_H2CREG_SCH_TX_EN_W1_BAND);
3187
3188	ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info);
3189	if (ret)
3190		return ret;
3191
3192	if (c2h_info.id != RTW89_FWCMD_C2HREG_FUNC_TX_PAUSE_RPT)
3193		return -EINVAL;
3194
3195	return 0;
3196}
3197
3198static int rtw89_set_hw_sch_tx_en(struct rtw89_dev *rtwdev, u8 mac_idx,
3199				  u16 tx_en, u16 tx_en_mask)
3200{
3201	u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_TXEN, mac_idx);
3202	u16 val;
3203	int ret;
3204
3205	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
3206	if (ret)
3207		return ret;
3208
3209	if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags))
3210		return rtw89_hw_sch_tx_en_h2c(rtwdev, mac_idx,
3211					      tx_en, tx_en_mask);
3212
3213	val = rtw89_read16(rtwdev, reg);
3214	val = (val & ~tx_en_mask) | (tx_en & tx_en_mask);
3215	rtw89_write16(rtwdev, reg, val);
3216
3217	return 0;
3218}
3219
3220static int rtw89_set_hw_sch_tx_en_v1(struct rtw89_dev *rtwdev, u8 mac_idx,
3221				     u32 tx_en, u32 tx_en_mask)
3222{
3223	u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_DRV_TXEN, mac_idx);
3224	u32 val;
3225	int ret;
3226
3227	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
3228	if (ret)
3229		return ret;
3230
3231	val = rtw89_read32(rtwdev, reg);
3232	val = (val & ~tx_en_mask) | (tx_en & tx_en_mask);
3233	rtw89_write32(rtwdev, reg, val);
3234
3235	return 0;
3236}
3237
3238int rtw89_mac_stop_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx,
3239			  u32 *tx_en, enum rtw89_sch_tx_sel sel)
3240{
3241	int ret;
3242
3243	*tx_en = rtw89_read16(rtwdev,
3244			      rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_TXEN, mac_idx));
3245
3246	switch (sel) {
3247	case RTW89_SCH_TX_SEL_ALL:
3248		ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, 0,
3249					     B_AX_CTN_TXEN_ALL_MASK);
3250		if (ret)
3251			return ret;
3252		break;
3253	case RTW89_SCH_TX_SEL_HIQ:
3254		ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx,
3255					     0, B_AX_CTN_TXEN_HGQ);
3256		if (ret)
3257			return ret;
3258		break;
3259	case RTW89_SCH_TX_SEL_MG0:
3260		ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx,
3261					     0, B_AX_CTN_TXEN_MGQ);
3262		if (ret)
3263			return ret;
3264		break;
3265	case RTW89_SCH_TX_SEL_MACID:
3266		ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, 0,
3267					     B_AX_CTN_TXEN_ALL_MASK);
3268		if (ret)
3269			return ret;
3270		break;
3271	default:
3272		return 0;
3273	}
3274
3275	return 0;
3276}
3277EXPORT_SYMBOL(rtw89_mac_stop_sch_tx);
3278
3279int rtw89_mac_stop_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx,
3280			     u32 *tx_en, enum rtw89_sch_tx_sel sel)
3281{
3282	int ret;
3283
3284	*tx_en = rtw89_read32(rtwdev,
3285			      rtw89_mac_reg_by_idx(rtwdev, R_AX_CTN_DRV_TXEN, mac_idx));
3286
3287	switch (sel) {
3288	case RTW89_SCH_TX_SEL_ALL:
3289		ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, 0,
3290						B_AX_CTN_TXEN_ALL_MASK_V1);
3291		if (ret)
3292			return ret;
3293		break;
3294	case RTW89_SCH_TX_SEL_HIQ:
3295		ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx,
3296						0, B_AX_CTN_TXEN_HGQ);
3297		if (ret)
3298			return ret;
3299		break;
3300	case RTW89_SCH_TX_SEL_MG0:
3301		ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx,
3302						0, B_AX_CTN_TXEN_MGQ);
3303		if (ret)
3304			return ret;
3305		break;
3306	case RTW89_SCH_TX_SEL_MACID:
3307		ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, 0,
3308						B_AX_CTN_TXEN_ALL_MASK_V1);
3309		if (ret)
3310			return ret;
3311		break;
3312	default:
3313		return 0;
3314	}
3315
3316	return 0;
3317}
3318EXPORT_SYMBOL(rtw89_mac_stop_sch_tx_v1);
3319
3320int rtw89_mac_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en)
3321{
3322	int ret;
3323
3324	ret = rtw89_set_hw_sch_tx_en(rtwdev, mac_idx, tx_en, B_AX_CTN_TXEN_ALL_MASK);
3325	if (ret)
3326		return ret;
3327
3328	return 0;
3329}
3330EXPORT_SYMBOL(rtw89_mac_resume_sch_tx);
3331
3332int rtw89_mac_resume_sch_tx_v1(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en)
3333{
3334	int ret;
3335
3336	ret = rtw89_set_hw_sch_tx_en_v1(rtwdev, mac_idx, tx_en,
3337					B_AX_CTN_TXEN_ALL_MASK_V1);
3338	if (ret)
3339		return ret;
3340
3341	return 0;
3342}
3343EXPORT_SYMBOL(rtw89_mac_resume_sch_tx_v1);
3344
3345static int dle_buf_req_ax(struct rtw89_dev *rtwdev, u16 buf_len, bool wd, u16 *pkt_id)
3346{
3347	u32 val, reg;
3348	int ret;
3349
3350	reg = wd ? R_AX_WD_BUF_REQ : R_AX_PL_BUF_REQ;
3351	val = buf_len;
3352	val |= B_AX_WD_BUF_REQ_EXEC;
3353	rtw89_write32(rtwdev, reg, val);
3354
3355	reg = wd ? R_AX_WD_BUF_STATUS : R_AX_PL_BUF_STATUS;
3356
3357	ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_BUF_STAT_DONE,
3358				1, 2000, false, rtwdev, reg);
3359	if (ret)
3360		return ret;
3361
3362	*pkt_id = FIELD_GET(B_AX_WD_BUF_STAT_PKTID_MASK, val);
3363	if (*pkt_id == S_WD_BUF_STAT_PKTID_INVALID)
3364		return -ENOENT;
3365
3366	return 0;
3367}
3368
3369static int set_cpuio_ax(struct rtw89_dev *rtwdev,
3370			struct rtw89_cpuio_ctrl *ctrl_para, bool wd)
3371{
3372	u32 val, cmd_type, reg;
3373	int ret;
3374
3375	cmd_type = ctrl_para->cmd_type;
3376
3377	reg = wd ? R_AX_WD_CPUQ_OP_2 : R_AX_PL_CPUQ_OP_2;
3378	val = 0;
3379	val = u32_replace_bits(val, ctrl_para->start_pktid,
3380			       B_AX_WD_CPUQ_OP_STRT_PKTID_MASK);
3381	val = u32_replace_bits(val, ctrl_para->end_pktid,
3382			       B_AX_WD_CPUQ_OP_END_PKTID_MASK);
3383	rtw89_write32(rtwdev, reg, val);
3384
3385	reg = wd ? R_AX_WD_CPUQ_OP_1 : R_AX_PL_CPUQ_OP_1;
3386	val = 0;
3387	val = u32_replace_bits(val, ctrl_para->src_pid,
3388			       B_AX_CPUQ_OP_SRC_PID_MASK);
3389	val = u32_replace_bits(val, ctrl_para->src_qid,
3390			       B_AX_CPUQ_OP_SRC_QID_MASK);
3391	val = u32_replace_bits(val, ctrl_para->dst_pid,
3392			       B_AX_CPUQ_OP_DST_PID_MASK);
3393	val = u32_replace_bits(val, ctrl_para->dst_qid,
3394			       B_AX_CPUQ_OP_DST_QID_MASK);
3395	rtw89_write32(rtwdev, reg, val);
3396
3397	reg = wd ? R_AX_WD_CPUQ_OP_0 : R_AX_PL_CPUQ_OP_0;
3398	val = 0;
3399	val = u32_replace_bits(val, cmd_type,
3400			       B_AX_CPUQ_OP_CMD_TYPE_MASK);
3401	val = u32_replace_bits(val, ctrl_para->macid,
3402			       B_AX_CPUQ_OP_MACID_MASK);
3403	val = u32_replace_bits(val, ctrl_para->pkt_num,
3404			       B_AX_CPUQ_OP_PKTNUM_MASK);
3405	val |= B_AX_WD_CPUQ_OP_EXEC;
3406	rtw89_write32(rtwdev, reg, val);
3407
3408	reg = wd ? R_AX_WD_CPUQ_OP_STATUS : R_AX_PL_CPUQ_OP_STATUS;
3409
3410	ret = read_poll_timeout(rtw89_read32, val, val & B_AX_WD_CPUQ_OP_STAT_DONE,
3411				1, 2000, false, rtwdev, reg);
3412	if (ret)
3413		return ret;
3414
3415	if (cmd_type == CPUIO_OP_CMD_GET_1ST_PID ||
3416	    cmd_type == CPUIO_OP_CMD_GET_NEXT_PID)
3417		ctrl_para->pktid = FIELD_GET(B_AX_WD_CPUQ_OP_PKTID_MASK, val);
3418
3419	return 0;
3420}
3421
3422int rtw89_mac_dle_quota_change(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
3423			       bool band1_en)
3424{
3425	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
3426	const struct rtw89_dle_mem *cfg;
3427
3428	cfg = get_dle_mem_cfg(rtwdev, mode);
3429	if (!cfg) {
3430		rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n");
3431		return -EINVAL;
3432	}
3433
3434	if (dle_used_size(cfg) != dle_expected_used_size(rtwdev, mode)) {
3435		rtw89_err(rtwdev, "[ERR]wd/dle mem cfg\n");
3436		return -EINVAL;
3437	}
3438
3439	dle_quota_cfg(rtwdev, cfg, INVALID_QT_WCPU);
3440
3441	return mac->dle_quota_change(rtwdev, band1_en);
3442}
3443
3444static int dle_quota_change_ax(struct rtw89_dev *rtwdev, bool band1_en)
3445{
3446	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
3447	struct rtw89_cpuio_ctrl ctrl_para = {0};
3448	u16 pkt_id;
3449	int ret;
3450
3451	ret = mac->dle_buf_req(rtwdev, 0x20, true, &pkt_id);
3452	if (ret) {
3453		rtw89_err(rtwdev, "[ERR]WDE DLE buf req\n");
3454		return ret;
3455	}
3456
3457	ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD;
3458	ctrl_para.start_pktid = pkt_id;
3459	ctrl_para.end_pktid = pkt_id;
3460	ctrl_para.pkt_num = 0;
3461	ctrl_para.dst_pid = WDE_DLE_PORT_ID_WDRLS;
3462	ctrl_para.dst_qid = WDE_DLE_QUEID_NO_REPORT;
3463	ret = mac->set_cpuio(rtwdev, &ctrl_para, true);
3464	if (ret) {
3465		rtw89_err(rtwdev, "[ERR]WDE DLE enqueue to head\n");
3466		return -EFAULT;
3467	}
3468
3469	ret = mac->dle_buf_req(rtwdev, 0x20, false, &pkt_id);
3470	if (ret) {
3471		rtw89_err(rtwdev, "[ERR]PLE DLE buf req\n");
3472		return ret;
3473	}
3474
3475	ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD;
3476	ctrl_para.start_pktid = pkt_id;
3477	ctrl_para.end_pktid = pkt_id;
3478	ctrl_para.pkt_num = 0;
3479	ctrl_para.dst_pid = PLE_DLE_PORT_ID_PLRLS;
3480	ctrl_para.dst_qid = PLE_DLE_QUEID_NO_REPORT;
3481	ret = mac->set_cpuio(rtwdev, &ctrl_para, false);
3482	if (ret) {
3483		rtw89_err(rtwdev, "[ERR]PLE DLE enqueue to head\n");
3484		return -EFAULT;
3485	}
3486
3487	return 0;
3488}
3489
3490static int band_idle_ck_b(struct rtw89_dev *rtwdev, u8 mac_idx)
3491{
3492	int ret;
3493	u32 reg;
3494	u8 val;
3495
3496	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
3497	if (ret)
3498		return ret;
3499
3500	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_TX_CTN_SEL, mac_idx);
3501
3502	ret = read_poll_timeout(rtw89_read8, val,
3503				(val & B_AX_PTCL_TX_ON_STAT) == 0,
3504				SW_CVR_DUR_US,
3505				SW_CVR_DUR_US * PTCL_IDLE_POLL_CNT,
3506				false, rtwdev, reg);
3507	if (ret)
3508		return ret;
3509
3510	return 0;
3511}
3512
3513static int band1_enable_ax(struct rtw89_dev *rtwdev)
3514{
3515	int ret, i;
3516	u32 sleep_bak[4] = {0};
3517	u32 pause_bak[4] = {0};
3518	u32 tx_en;
3519
3520	ret = rtw89_chip_stop_sch_tx(rtwdev, 0, &tx_en, RTW89_SCH_TX_SEL_ALL);
3521	if (ret) {
3522		rtw89_err(rtwdev, "[ERR]stop sch tx %d\n", ret);
3523		return ret;
3524	}
3525
3526	for (i = 0; i < 4; i++) {
3527		sleep_bak[i] = rtw89_read32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4);
3528		pause_bak[i] = rtw89_read32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4);
3529		rtw89_write32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4, U32_MAX);
3530		rtw89_write32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4, U32_MAX);
3531	}
3532
3533	ret = band_idle_ck_b(rtwdev, 0);
3534	if (ret) {
3535		rtw89_err(rtwdev, "[ERR]tx idle poll %d\n", ret);
3536		return ret;
3537	}
3538
3539	ret = rtw89_mac_dle_quota_change(rtwdev, rtwdev->mac.qta_mode, true);
3540	if (ret) {
3541		rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret);
3542		return ret;
3543	}
3544
3545	for (i = 0; i < 4; i++) {
3546		rtw89_write32(rtwdev, R_AX_MACID_SLEEP_0 + i * 4, sleep_bak[i]);
3547		rtw89_write32(rtwdev, R_AX_SS_MACID_PAUSE_0 + i * 4, pause_bak[i]);
3548	}
3549
3550	ret = rtw89_chip_resume_sch_tx(rtwdev, 0, tx_en);
3551	if (ret) {
3552		rtw89_err(rtwdev, "[ERR]CMAC1 resume sch tx %d\n", ret);
3553		return ret;
3554	}
3555
3556	ret = cmac_func_en_ax(rtwdev, 1, true);
3557	if (ret) {
3558		rtw89_err(rtwdev, "[ERR]CMAC1 func en %d\n", ret);
3559		return ret;
3560	}
3561
3562	ret = cmac_init_ax(rtwdev, 1);
3563	if (ret) {
3564		rtw89_err(rtwdev, "[ERR]CMAC1 init %d\n", ret);
3565		return ret;
3566	}
3567
3568	rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
3569			  B_AX_R_SYM_FEN_WLBBFUN_1 | B_AX_R_SYM_FEN_WLBBGLB_1);
3570
3571	return 0;
3572}
3573
3574static void rtw89_wdrls_imr_enable(struct rtw89_dev *rtwdev)
3575{
3576	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3577
3578	rtw89_write32_clr(rtwdev, R_AX_WDRLS_ERR_IMR, B_AX_WDRLS_IMR_EN_CLR);
3579	rtw89_write32_set(rtwdev, R_AX_WDRLS_ERR_IMR, imr->wdrls_imr_set);
3580}
3581
3582static void rtw89_wsec_imr_enable(struct rtw89_dev *rtwdev)
3583{
3584	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3585
3586	rtw89_write32_set(rtwdev, imr->wsec_imr_reg, imr->wsec_imr_set);
3587}
3588
3589static void rtw89_mpdu_trx_imr_enable(struct rtw89_dev *rtwdev)
3590{
3591	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
3592	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3593
3594	rtw89_write32_clr(rtwdev, R_AX_MPDU_TX_ERR_IMR,
3595			  B_AX_TX_GET_ERRPKTID_INT_EN |
3596			  B_AX_TX_NXT_ERRPKTID_INT_EN |
3597			  B_AX_TX_MPDU_SIZE_ZERO_INT_EN |
3598			  B_AX_TX_OFFSET_ERR_INT_EN |
3599			  B_AX_TX_HDR3_SIZE_ERR_INT_EN);
3600	if (chip_id == RTL8852C)
3601		rtw89_write32_clr(rtwdev, R_AX_MPDU_TX_ERR_IMR,
3602				  B_AX_TX_ETH_TYPE_ERR_EN |
3603				  B_AX_TX_LLC_PRE_ERR_EN |
3604				  B_AX_TX_NW_TYPE_ERR_EN |
3605				  B_AX_TX_KSRCH_ERR_EN);
3606	rtw89_write32_set(rtwdev, R_AX_MPDU_TX_ERR_IMR,
3607			  imr->mpdu_tx_imr_set);
3608
3609	rtw89_write32_clr(rtwdev, R_AX_MPDU_RX_ERR_IMR,
3610			  B_AX_GETPKTID_ERR_INT_EN |
3611			  B_AX_MHDRLEN_ERR_INT_EN |
3612			  B_AX_RPT_ERR_INT_EN);
3613	rtw89_write32_set(rtwdev, R_AX_MPDU_RX_ERR_IMR,
3614			  imr->mpdu_rx_imr_set);
3615}
3616
3617static void rtw89_sta_sch_imr_enable(struct rtw89_dev *rtwdev)
3618{
3619	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3620
3621	rtw89_write32_clr(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR,
3622			  B_AX_SEARCH_HANG_TIMEOUT_INT_EN |
3623			  B_AX_RPT_HANG_TIMEOUT_INT_EN |
3624			  B_AX_PLE_B_PKTID_ERR_INT_EN);
3625	rtw89_write32_set(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR,
3626			  imr->sta_sch_imr_set);
3627}
3628
3629static void rtw89_txpktctl_imr_enable(struct rtw89_dev *rtwdev)
3630{
3631	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3632
3633	rtw89_write32_clr(rtwdev, imr->txpktctl_imr_b0_reg,
3634			  imr->txpktctl_imr_b0_clr);
3635	rtw89_write32_set(rtwdev, imr->txpktctl_imr_b0_reg,
3636			  imr->txpktctl_imr_b0_set);
3637	rtw89_write32_clr(rtwdev, imr->txpktctl_imr_b1_reg,
3638			  imr->txpktctl_imr_b1_clr);
3639	rtw89_write32_set(rtwdev, imr->txpktctl_imr_b1_reg,
3640			  imr->txpktctl_imr_b1_set);
3641}
3642
3643static void rtw89_wde_imr_enable(struct rtw89_dev *rtwdev)
3644{
3645	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3646
3647	rtw89_write32_clr(rtwdev, R_AX_WDE_ERR_IMR, imr->wde_imr_clr);
3648	rtw89_write32_set(rtwdev, R_AX_WDE_ERR_IMR, imr->wde_imr_set);
3649}
3650
3651static void rtw89_ple_imr_enable(struct rtw89_dev *rtwdev)
3652{
3653	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3654
3655	rtw89_write32_clr(rtwdev, R_AX_PLE_ERR_IMR, imr->ple_imr_clr);
3656	rtw89_write32_set(rtwdev, R_AX_PLE_ERR_IMR, imr->ple_imr_set);
3657}
3658
3659static void rtw89_pktin_imr_enable(struct rtw89_dev *rtwdev)
3660{
3661	rtw89_write32_set(rtwdev, R_AX_PKTIN_ERR_IMR,
3662			  B_AX_PKTIN_GETPKTID_ERR_INT_EN);
3663}
3664
3665static void rtw89_dispatcher_imr_enable(struct rtw89_dev *rtwdev)
3666{
3667	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3668
3669	rtw89_write32_clr(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR,
3670			  imr->host_disp_imr_clr);
3671	rtw89_write32_set(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR,
3672			  imr->host_disp_imr_set);
3673	rtw89_write32_clr(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR,
3674			  imr->cpu_disp_imr_clr);
3675	rtw89_write32_set(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR,
3676			  imr->cpu_disp_imr_set);
3677	rtw89_write32_clr(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR,
3678			  imr->other_disp_imr_clr);
3679	rtw89_write32_set(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR,
3680			  imr->other_disp_imr_set);
3681}
3682
3683static void rtw89_cpuio_imr_enable(struct rtw89_dev *rtwdev)
3684{
3685	rtw89_write32_clr(rtwdev, R_AX_CPUIO_ERR_IMR, B_AX_CPUIO_IMR_CLR);
3686	rtw89_write32_set(rtwdev, R_AX_CPUIO_ERR_IMR, B_AX_CPUIO_IMR_SET);
3687}
3688
3689static void rtw89_bbrpt_imr_enable(struct rtw89_dev *rtwdev)
3690{
3691	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3692
3693	rtw89_write32_set(rtwdev, imr->bbrpt_com_err_imr_reg,
3694			  B_AX_BBRPT_COM_NULL_PLPKTID_ERR_INT_EN);
3695	rtw89_write32_clr(rtwdev, imr->bbrpt_chinfo_err_imr_reg,
3696			  B_AX_BBRPT_CHINFO_IMR_CLR);
3697	rtw89_write32_set(rtwdev, imr->bbrpt_chinfo_err_imr_reg,
3698			  imr->bbrpt_err_imr_set);
3699	rtw89_write32_set(rtwdev, imr->bbrpt_dfs_err_imr_reg,
3700			  B_AX_BBRPT_DFS_TO_ERR_INT_EN);
3701	rtw89_write32_set(rtwdev, R_AX_LA_ERRFLAG, B_AX_LA_IMR_DATA_LOSS_ERR);
3702}
3703
3704static void rtw89_scheduler_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3705{
3706	u32 reg;
3707
3708	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_SCHEDULE_ERR_IMR, mac_idx);
3709	rtw89_write32_clr(rtwdev, reg, B_AX_SORT_NON_IDLE_ERR_INT_EN |
3710				       B_AX_FSM_TIMEOUT_ERR_INT_EN);
3711	rtw89_write32_set(rtwdev, reg, B_AX_FSM_TIMEOUT_ERR_INT_EN);
3712}
3713
3714static void rtw89_ptcl_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3715{
3716	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3717	u32 reg;
3718
3719	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PTCL_IMR0, mac_idx);
3720	rtw89_write32_clr(rtwdev, reg, imr->ptcl_imr_clr);
3721	rtw89_write32_set(rtwdev, reg, imr->ptcl_imr_set);
3722}
3723
3724static void rtw89_cdma_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3725{
3726	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3727	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
3728	u32 reg;
3729
3730	reg = rtw89_mac_reg_by_idx(rtwdev, imr->cdma_imr_0_reg, mac_idx);
3731	rtw89_write32_clr(rtwdev, reg, imr->cdma_imr_0_clr);
3732	rtw89_write32_set(rtwdev, reg, imr->cdma_imr_0_set);
3733
3734	if (chip_id == RTL8852C) {
3735		reg = rtw89_mac_reg_by_idx(rtwdev, imr->cdma_imr_1_reg, mac_idx);
3736		rtw89_write32_clr(rtwdev, reg, imr->cdma_imr_1_clr);
3737		rtw89_write32_set(rtwdev, reg, imr->cdma_imr_1_set);
3738	}
3739}
3740
3741static void rtw89_phy_intf_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3742{
3743	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3744	u32 reg;
3745
3746	reg = rtw89_mac_reg_by_idx(rtwdev, imr->phy_intf_imr_reg, mac_idx);
3747	rtw89_write32_clr(rtwdev, reg, imr->phy_intf_imr_clr);
3748	rtw89_write32_set(rtwdev, reg, imr->phy_intf_imr_set);
3749}
3750
3751static void rtw89_rmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3752{
3753	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3754	u32 reg;
3755
3756	reg = rtw89_mac_reg_by_idx(rtwdev, imr->rmac_imr_reg, mac_idx);
3757	rtw89_write32_clr(rtwdev, reg, imr->rmac_imr_clr);
3758	rtw89_write32_set(rtwdev, reg, imr->rmac_imr_set);
3759}
3760
3761static void rtw89_tmac_imr_enable(struct rtw89_dev *rtwdev, u8 mac_idx)
3762{
3763	const struct rtw89_imr_info *imr = rtwdev->chip->imr_info;
3764	u32 reg;
3765
3766	reg = rtw89_mac_reg_by_idx(rtwdev, imr->tmac_imr_reg, mac_idx);
3767	rtw89_write32_clr(rtwdev, reg, imr->tmac_imr_clr);
3768	rtw89_write32_set(rtwdev, reg, imr->tmac_imr_set);
3769}
3770
3771static int enable_imr_ax(struct rtw89_dev *rtwdev, u8 mac_idx,
3772			 enum rtw89_mac_hwmod_sel sel)
3773{
3774	int ret;
3775
3776	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, sel);
3777	if (ret) {
3778		rtw89_err(rtwdev, "MAC%d mac_idx%d is not ready\n",
3779			  sel, mac_idx);
3780		return ret;
3781	}
3782
3783	if (sel == RTW89_DMAC_SEL) {
3784		rtw89_wdrls_imr_enable(rtwdev);
3785		rtw89_wsec_imr_enable(rtwdev);
3786		rtw89_mpdu_trx_imr_enable(rtwdev);
3787		rtw89_sta_sch_imr_enable(rtwdev);
3788		rtw89_txpktctl_imr_enable(rtwdev);
3789		rtw89_wde_imr_enable(rtwdev);
3790		rtw89_ple_imr_enable(rtwdev);
3791		rtw89_pktin_imr_enable(rtwdev);
3792		rtw89_dispatcher_imr_enable(rtwdev);
3793		rtw89_cpuio_imr_enable(rtwdev);
3794		rtw89_bbrpt_imr_enable(rtwdev);
3795	} else if (sel == RTW89_CMAC_SEL) {
3796		rtw89_scheduler_imr_enable(rtwdev, mac_idx);
3797		rtw89_ptcl_imr_enable(rtwdev, mac_idx);
3798		rtw89_cdma_imr_enable(rtwdev, mac_idx);
3799		rtw89_phy_intf_imr_enable(rtwdev, mac_idx);
3800		rtw89_rmac_imr_enable(rtwdev, mac_idx);
3801		rtw89_tmac_imr_enable(rtwdev, mac_idx);
3802	} else {
3803		return -EINVAL;
3804	}
3805
3806	return 0;
3807}
3808
3809static void err_imr_ctrl_ax(struct rtw89_dev *rtwdev, bool en)
3810{
3811	rtw89_write32(rtwdev, R_AX_DMAC_ERR_IMR,
3812		      en ? DMAC_ERR_IMR_EN : DMAC_ERR_IMR_DIS);
3813	rtw89_write32(rtwdev, R_AX_CMAC_ERR_IMR,
3814		      en ? CMAC0_ERR_IMR_EN : CMAC0_ERR_IMR_DIS);
3815	if (!rtw89_is_rtl885xb(rtwdev) && rtwdev->mac.dle_info.c1_rx_qta)
3816		rtw89_write32(rtwdev, R_AX_CMAC_ERR_IMR_C1,
3817			      en ? CMAC1_ERR_IMR_EN : CMAC1_ERR_IMR_DIS);
3818}
3819
3820static int dbcc_enable_ax(struct rtw89_dev *rtwdev, bool enable)
3821{
3822	int ret = 0;
3823
3824	if (enable) {
3825		ret = band1_enable_ax(rtwdev);
3826		if (ret) {
3827			rtw89_err(rtwdev, "[ERR] band1_enable %d\n", ret);
3828			return ret;
3829		}
3830
3831		ret = enable_imr_ax(rtwdev, RTW89_MAC_1, RTW89_CMAC_SEL);
3832		if (ret) {
3833			rtw89_err(rtwdev, "[ERR] enable CMAC1 IMR %d\n", ret);
3834			return ret;
3835		}
3836	} else {
3837		rtw89_err(rtwdev, "[ERR] disable dbcc is not implemented not\n");
3838		return -EINVAL;
3839	}
3840
3841	return 0;
3842}
3843
3844static int set_host_rpr_ax(struct rtw89_dev *rtwdev)
3845{
3846	if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) {
3847		rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG,
3848				   B_AX_WDRLS_MODE_MASK, RTW89_RPR_MODE_POH);
3849		rtw89_write32_set(rtwdev, R_AX_RLSRPT0_CFG0,
3850				  B_AX_RLSRPT0_FLTR_MAP_MASK);
3851	} else {
3852		rtw89_write32_mask(rtwdev, R_AX_WDRLS_CFG,
3853				   B_AX_WDRLS_MODE_MASK, RTW89_RPR_MODE_STF);
3854		rtw89_write32_clr(rtwdev, R_AX_RLSRPT0_CFG0,
3855				  B_AX_RLSRPT0_FLTR_MAP_MASK);
3856	}
3857
3858	rtw89_write32_mask(rtwdev, R_AX_RLSRPT0_CFG1, B_AX_RLSRPT0_AGGNUM_MASK, 30);
3859	rtw89_write32_mask(rtwdev, R_AX_RLSRPT0_CFG1, B_AX_RLSRPT0_TO_MASK, 255);
3860
3861	return 0;
3862}
3863
3864static int trx_init_ax(struct rtw89_dev *rtwdev)
3865{
3866	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
3867	enum rtw89_qta_mode qta_mode = rtwdev->mac.qta_mode;
3868	int ret;
3869
3870	ret = dmac_init_ax(rtwdev, 0);
3871	if (ret) {
3872		rtw89_err(rtwdev, "[ERR]DMAC init %d\n", ret);
3873		return ret;
3874	}
3875
3876	ret = cmac_init_ax(rtwdev, 0);
3877	if (ret) {
3878		rtw89_err(rtwdev, "[ERR]CMAC%d init %d\n", 0, ret);
3879		return ret;
3880	}
3881
3882	if (rtw89_mac_is_qta_dbcc(rtwdev, qta_mode)) {
3883		ret = dbcc_enable_ax(rtwdev, true);
3884		if (ret) {
3885			rtw89_err(rtwdev, "[ERR]dbcc_enable init %d\n", ret);
3886			return ret;
3887		}
3888	}
3889
3890	ret = enable_imr_ax(rtwdev, RTW89_MAC_0, RTW89_DMAC_SEL);
3891	if (ret) {
3892		rtw89_err(rtwdev, "[ERR] enable DMAC IMR %d\n", ret);
3893		return ret;
3894	}
3895
3896	ret = enable_imr_ax(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL);
3897	if (ret) {
3898		rtw89_err(rtwdev, "[ERR] to enable CMAC0 IMR %d\n", ret);
3899		return ret;
3900	}
3901
3902	err_imr_ctrl_ax(rtwdev, true);
3903
3904	ret = set_host_rpr_ax(rtwdev);
3905	if (ret) {
3906		rtw89_err(rtwdev, "[ERR] set host rpr %d\n", ret);
3907		return ret;
3908	}
3909
3910	if (chip_id == RTL8852C)
3911		rtw89_write32_clr(rtwdev, R_AX_RSP_CHK_SIG,
3912				  B_AX_RSP_STATIC_RTS_CHK_SERV_BW_EN);
3913
3914	return 0;
3915}
3916
3917static int rtw89_mac_feat_init(struct rtw89_dev *rtwdev)
3918{
3919#define BACAM_1024BMP_OCC_ENTRY 4
3920#define BACAM_MAX_RU_SUPPORT_B0_STA 1
3921#define BACAM_MAX_RU_SUPPORT_B1_STA 1
3922	const struct rtw89_chip_info *chip = rtwdev->chip;
3923	u8 users, offset;
3924
3925	if (chip->bacam_ver != RTW89_BACAM_V1)
3926		return 0;
3927
3928	offset = 0;
3929	users = BACAM_MAX_RU_SUPPORT_B0_STA;
3930	rtw89_fw_h2c_init_ba_cam_users(rtwdev, users, offset, RTW89_MAC_0);
3931
3932	offset += users * BACAM_1024BMP_OCC_ENTRY;
3933	users = BACAM_MAX_RU_SUPPORT_B1_STA;
3934	rtw89_fw_h2c_init_ba_cam_users(rtwdev, users, offset, RTW89_MAC_1);
3935
3936	return 0;
3937}
3938
3939static void rtw89_disable_fw_watchdog(struct rtw89_dev *rtwdev)
3940{
3941	u32 val32;
3942
3943	if (rtw89_is_rtl885xb(rtwdev)) {
3944		rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_APB_WRAP_EN);
3945		rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_APB_WRAP_EN);
3946		return;
3947	}
3948
3949	rtw89_mac_mem_write(rtwdev, R_AX_WDT_CTRL,
3950			    WDT_CTRL_ALL_DIS, RTW89_MAC_MEM_CPU_LOCAL);
3951
3952	val32 = rtw89_mac_mem_read(rtwdev, R_AX_WDT_STATUS, RTW89_MAC_MEM_CPU_LOCAL);
3953	val32 |= B_AX_FS_WDT_INT;
3954	val32 &= ~B_AX_FS_WDT_INT_MSK;
3955	rtw89_mac_mem_write(rtwdev, R_AX_WDT_STATUS, val32, RTW89_MAC_MEM_CPU_LOCAL);
3956}
3957
3958static void rtw89_mac_disable_cpu_ax(struct rtw89_dev *rtwdev)
3959{
3960	clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
3961
3962	rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN);
3963	rtw89_write32_clr(rtwdev, R_AX_WCPU_FW_CTRL, B_AX_WCPU_FWDL_EN |
3964			  B_AX_H2C_PATH_RDY | B_AX_FWDL_PATH_RDY);
3965	rtw89_write32_clr(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN);
3966
3967	rtw89_disable_fw_watchdog(rtwdev);
3968
3969	rtw89_write32_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
3970	rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
3971}
3972
3973static int rtw89_mac_enable_cpu_ax(struct rtw89_dev *rtwdev, u8 boot_reason,
3974				   bool dlfw, bool include_bb)
3975{
3976	u32 val;
3977	int ret;
3978
3979	if (rtw89_read32(rtwdev, R_AX_PLATFORM_ENABLE) & B_AX_WCPU_EN)
3980		return -EFAULT;
3981
3982	rtw89_write32(rtwdev, R_AX_UDM1, 0);
3983	rtw89_write32(rtwdev, R_AX_UDM2, 0);
3984	rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0);
3985	rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0);
3986	rtw89_write32(rtwdev, R_AX_HALT_H2C, 0);
3987	rtw89_write32(rtwdev, R_AX_HALT_C2H, 0);
3988
3989	rtw89_write32_set(rtwdev, R_AX_SYS_CLK_CTRL, B_AX_CPU_CLK_EN);
3990
3991	val = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL);
3992	val &= ~(B_AX_WCPU_FWDL_EN | B_AX_H2C_PATH_RDY | B_AX_FWDL_PATH_RDY);
3993	val = u32_replace_bits(val, RTW89_FWDL_INITIAL_STATE,
3994			       B_AX_WCPU_FWDL_STS_MASK);
3995
3996	if (dlfw)
3997		val |= B_AX_WCPU_FWDL_EN;
3998
3999	rtw89_write32(rtwdev, R_AX_WCPU_FW_CTRL, val);
4000
4001	if (rtw89_is_rtl885xb(rtwdev))
4002		rtw89_write32_mask(rtwdev, R_AX_SEC_CTRL,
4003				   B_AX_SEC_IDMEM_SIZE_CONFIG_MASK, 0x2);
4004
4005	rtw89_write16_mask(rtwdev, R_AX_BOOT_REASON, B_AX_BOOT_REASON_MASK,
4006			   boot_reason);
4007	rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_WCPU_EN);
4008
4009	if (!dlfw) {
4010		mdelay(5);
4011
4012		ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE);
4013		if (ret)
4014			return ret;
4015	}
4016
4017	return 0;
4018}
4019
4020static void rtw89_mac_hci_func_en_ax(struct rtw89_dev *rtwdev)
4021{
4022	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
4023	u32 val;
4024
4025	if (chip_id == RTL8852C)
4026		val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN |
4027		      B_AX_PKT_BUF_EN | B_AX_H_AXIDMA_EN;
4028	else
4029		val = B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_DISPATCHER_EN |
4030		      B_AX_PKT_BUF_EN;
4031	rtw89_write32(rtwdev, R_AX_DMAC_FUNC_EN, val);
4032}
4033
4034static void rtw89_mac_dmac_func_pre_en_ax(struct rtw89_dev *rtwdev)
4035{
4036	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
4037	u32 val;
4038
4039	if (chip_id == RTL8851B || chip_id == RTL8852BT)
4040		val = B_AX_DISPATCHER_CLK_EN | B_AX_AXIDMA_CLK_EN;
4041	else
4042		val = B_AX_DISPATCHER_CLK_EN;
4043	rtw89_write32(rtwdev, R_AX_DMAC_CLK_EN, val);
4044
4045	if (chip_id != RTL8852C)
4046		return;
4047
4048	val = rtw89_read32(rtwdev, R_AX_HAXI_INIT_CFG1);
4049	val &= ~(B_AX_DMA_MODE_MASK | B_AX_STOP_AXI_MST);
4050	val |= B_AX_TXHCI_EN_V1 | B_AX_RXHCI_EN_V1;
4051
4052	if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
4053		val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_PCIE_1B);
4054	else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
4055		val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_USB);
4056	else
4057		val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_SDIO);
4058
4059	rtw89_write32(rtwdev, R_AX_HAXI_INIT_CFG1, val);
4060
4061	rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP1,
4062			  B_AX_STOP_ACH0 | B_AX_STOP_ACH1 | B_AX_STOP_ACH3 |
4063			  B_AX_STOP_ACH4 | B_AX_STOP_ACH5 | B_AX_STOP_ACH6 |
4064			  B_AX_STOP_ACH7 | B_AX_STOP_CH8 | B_AX_STOP_CH9 |
4065			  B_AX_STOP_CH12 | B_AX_STOP_ACH2);
4066	rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP2, B_AX_STOP_CH10 | B_AX_STOP_CH11);
4067	rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_AXIDMA_EN);
4068}
4069
4070static int rtw89_mac_dmac_pre_init(struct rtw89_dev *rtwdev)
4071{
4072	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4073	int ret;
4074
4075	mac->hci_func_en(rtwdev);
4076	mac->dmac_func_pre_en(rtwdev);
4077
4078	ret = rtw89_mac_dle_init(rtwdev, RTW89_QTA_DLFW, rtwdev->mac.qta_mode);
4079	if (ret) {
4080		rtw89_err(rtwdev, "[ERR]DLE pre init %d\n", ret);
4081		return ret;
4082	}
4083
4084	ret = rtw89_mac_hfc_init(rtwdev, true, false, true);
4085	if (ret) {
4086		rtw89_err(rtwdev, "[ERR]HCI FC pre init %d\n", ret);
4087		return ret;
4088	}
4089
4090	return ret;
4091}
4092
4093int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
4094{
4095	rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN,
4096			 B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
4097	rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL,
4098			  B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 |
4099			  B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1);
4100	rtw89_write8_set(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE);
4101
4102	return 0;
4103}
4104EXPORT_SYMBOL(rtw89_mac_enable_bb_rf);
4105
4106int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
4107{
4108	rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
4109			 B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
4110	rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL,
4111			  B_AX_WLRF1_CTRL_7 | B_AX_WLRF1_CTRL_1 |
4112			  B_AX_WLRF_CTRL_7 | B_AX_WLRF_CTRL_1);
4113	rtw89_write8_clr(rtwdev, R_AX_PHYREG_SET, PHYREG_SET_ALL_CYCLE);
4114
4115	return 0;
4116}
4117EXPORT_SYMBOL(rtw89_mac_disable_bb_rf);
4118
4119int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb)
4120{
4121	int ret;
4122
4123	rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
4124
4125	if (include_bb) {
4126		/* Only call BB preinit including configuration of BB MCU for
4127		 * the chips which need to download BB MCU firmware. Otherwise,
4128		 * calling preinit later to prevent touching registers affecting
4129		 * download firmware.
4130		 */
4131		rtw89_chip_bb_preinit(rtwdev);
4132	}
4133
4134	ret = rtw89_mac_dmac_pre_init(rtwdev);
4135	if (ret)
4136		return ret;
4137
4138	if (rtwdev->hci.ops->mac_pre_init) {
4139		ret = rtwdev->hci.ops->mac_pre_init(rtwdev);
4140		if (ret)
4141			return ret;
4142	}
4143
4144	ret = rtw89_fw_download(rtwdev, RTW89_FW_NORMAL, include_bb);
4145	if (ret)
4146		return ret;
4147
4148	return 0;
4149}
4150
4151int rtw89_mac_preinit(struct rtw89_dev *rtwdev)
4152{
4153	int ret;
4154
4155	ret = rtw89_mac_pwr_on(rtwdev);
4156	if (ret)
4157		return ret;
4158
4159	return 0;
4160}
4161
4162int rtw89_mac_init(struct rtw89_dev *rtwdev)
4163{
4164	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4165	const struct rtw89_chip_info *chip = rtwdev->chip;
4166	bool include_bb = !!chip->bbmcu_nr;
4167	int ret;
4168
4169	ret = rtw89_mac_partial_init(rtwdev, include_bb);
4170	if (ret)
4171		goto fail;
4172
4173	ret = rtw89_chip_enable_bb_rf(rtwdev);
4174	if (ret)
4175		goto fail;
4176
4177	ret = mac->sys_init(rtwdev);
4178	if (ret)
4179		goto fail;
4180
4181	ret = mac->trx_init(rtwdev);
4182	if (ret)
4183		goto fail;
4184
4185	ret = rtw89_mac_feat_init(rtwdev);
4186	if (ret)
4187		goto fail;
4188
4189	if (rtwdev->hci.ops->mac_post_init) {
4190		ret = rtwdev->hci.ops->mac_post_init(rtwdev);
4191		if (ret)
4192			goto fail;
4193	}
4194
4195	rtw89_fw_send_all_early_h2c(rtwdev);
4196	rtw89_fw_h2c_set_ofld_cfg(rtwdev);
4197
4198	return ret;
4199fail:
4200	rtw89_mac_pwr_off(rtwdev);
4201
4202	return ret;
4203}
4204
4205static void rtw89_mac_dmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
4206{
4207	struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
4208	u8 i;
4209
4210	if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot)
4211		return;
4212
4213	for (i = 0; i < 4; i++) {
4214		rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
4215			      DMAC_TBL_BASE_ADDR + (macid << 4) + (i << 2));
4216		rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0);
4217	}
4218}
4219
4220static void rtw89_mac_cmac_tbl_init(struct rtw89_dev *rtwdev, u8 macid)
4221{
4222	struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
4223
4224	if (rtwdev->chip->chip_gen != RTW89_CHIP_AX || sec->secure_boot)
4225		return;
4226
4227	rtw89_write32(rtwdev, R_AX_FILTER_MODEL_ADDR,
4228		      CMAC_TBL_BASE_ADDR + macid * CCTL_INFO_SIZE);
4229	rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY, 0x4);
4230	rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 4, 0x400A0004);
4231	rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 8, 0);
4232	rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 12, 0);
4233	rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 16, 0);
4234	rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 20, 0xE43000B);
4235	rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 24, 0);
4236	rtw89_write32(rtwdev, R_AX_INDIR_ACCESS_ENTRY + 28, 0xB8109);
4237}
4238
4239int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause)
4240{
4241	u8 sh =  FIELD_GET(GENMASK(4, 0), macid);
4242	u8 grp = macid >> 5;
4243	int ret;
4244
4245	/* If this is called by change_interface() in the case of P2P, it could
4246	 * be power-off, so ignore this operation.
4247	 */
4248	if (test_bit(RTW89_FLAG_CHANGING_INTERFACE, rtwdev->flags) &&
4249	    !test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
4250		return 0;
4251
4252	ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL);
4253	if (ret)
4254		return ret;
4255
4256	rtw89_fw_h2c_macid_pause(rtwdev, sh, grp, pause);
4257
4258	return 0;
4259}
4260
4261static const struct rtw89_port_reg rtw89_port_base_ax = {
4262	.port_cfg = R_AX_PORT_CFG_P0,
4263	.tbtt_prohib = R_AX_TBTT_PROHIB_P0,
4264	.bcn_area = R_AX_BCN_AREA_P0,
4265	.bcn_early = R_AX_BCNERLYINT_CFG_P0,
4266	.tbtt_early = R_AX_TBTTERLYINT_CFG_P0,
4267	.tbtt_agg = R_AX_TBTT_AGG_P0,
4268	.bcn_space = R_AX_BCN_SPACE_CFG_P0,
4269	.bcn_forcetx = R_AX_BCN_FORCETX_P0,
4270	.bcn_err_cnt = R_AX_BCN_ERR_CNT_P0,
4271	.bcn_err_flag = R_AX_BCN_ERR_FLAG_P0,
4272	.dtim_ctrl = R_AX_DTIM_CTRL_P0,
4273	.tbtt_shift = R_AX_TBTT_SHIFT_P0,
4274	.bcn_cnt_tmr = R_AX_BCN_CNT_TMR_P0,
4275	.tsftr_l = R_AX_TSFTR_LOW_P0,
4276	.tsftr_h = R_AX_TSFTR_HIGH_P0,
4277	.md_tsft = R_AX_MD_TSFT_STMP_CTL,
4278	.bss_color = R_AX_PTCL_BSS_COLOR_0,
4279	.mbssid = R_AX_MBSSID_CTRL,
4280	.mbssid_drop = R_AX_MBSSID_DROP_0,
4281	.tsf_sync = R_AX_PORT0_TSF_SYNC,
4282	.ptcl_dbg = R_AX_PTCL_DBG,
4283	.ptcl_dbg_info = R_AX_PTCL_DBG_INFO,
4284	.bcn_drop_all = R_AX_BCN_DROP_ALL0,
4285	.bcn_psr_rpt = R_AX_BCN_PSR_RPT_P0,
4286	.hiq_win = {R_AX_P0MB_HGQ_WINDOW_CFG_0, R_AX_PORT_HGQ_WINDOW_CFG,
4287		    R_AX_PORT_HGQ_WINDOW_CFG + 1, R_AX_PORT_HGQ_WINDOW_CFG + 2,
4288		    R_AX_PORT_HGQ_WINDOW_CFG + 3},
4289};
4290
4291static void rtw89_mac_check_packet_ctrl(struct rtw89_dev *rtwdev,
4292					struct rtw89_vif_link *rtwvif_link, u8 type)
4293{
4294	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4295	const struct rtw89_port_reg *p = mac->port_base;
4296	u8 mask = B_AX_PTCL_DBG_INFO_MASK_BY_PORT(rtwvif_link->port);
4297	u32 reg_info, reg_ctrl;
4298	u32 val;
4299	int ret;
4300
4301	reg_info = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg_info, rtwvif_link->mac_idx);
4302	reg_ctrl = rtw89_mac_reg_by_idx(rtwdev, p->ptcl_dbg, rtwvif_link->mac_idx);
4303
4304	rtw89_write32_mask(rtwdev, reg_ctrl, B_AX_PTCL_DBG_SEL_MASK, type);
4305	rtw89_write32_set(rtwdev, reg_ctrl, B_AX_PTCL_DBG_EN);
4306	fsleep(100);
4307
4308	ret = read_poll_timeout(rtw89_read32_mask, val, val == 0, 1000, 100000,
4309				true, rtwdev, reg_info, mask);
4310	if (ret)
4311		rtw89_warn(rtwdev, "Polling beacon packet empty fail\n");
4312}
4313
4314static void rtw89_mac_bcn_drop(struct rtw89_dev *rtwdev,
4315			       struct rtw89_vif_link *rtwvif_link)
4316{
4317	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4318	const struct rtw89_port_reg *p = mac->port_base;
4319
4320	rtw89_write32_set(rtwdev, p->bcn_drop_all, BIT(rtwvif_link->port));
4321	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_SETUP_MASK,
4322				1);
4323	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_area, B_AX_BCN_MSK_AREA_MASK,
4324				0);
4325	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib, B_AX_TBTT_HOLD_MASK,
4326				0);
4327	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_early, B_AX_BCNERLY_MASK, 2);
4328	rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_early,
4329				B_AX_TBTTERLY_MASK, 1);
4330	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space,
4331				B_AX_BCN_SPACE_MASK, 1);
4332	rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN);
4333
4334	rtw89_mac_check_packet_ctrl(rtwdev, rtwvif_link, AX_PTCL_DBG_BCNQ_NUM0);
4335	if (rtwvif_link->port == RTW89_PORT_0)
4336		rtw89_mac_check_packet_ctrl(rtwdev, rtwvif_link, AX_PTCL_DBG_BCNQ_NUM1);
4337
4338	rtw89_write32_clr(rtwdev, p->bcn_drop_all, BIT(rtwvif_link->port));
4339	rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_TBTT_PROHIB_EN);
4340	fsleep(2000);
4341}
4342
4343#define BCN_INTERVAL 100
4344#define BCN_ERLY_DEF 160
4345#define BCN_SETUP_DEF 2
4346#define BCN_HOLD_DEF 200
4347#define BCN_MASK_DEF 0
4348#define TBTT_ERLY_DEF 5
4349#define TBTT_AGG_DEF 1
4350#define BCN_SET_UNIT 32
4351#define BCN_ERLY_SET_DLY (10 * 2)
4352
4353static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev,
4354				       struct rtw89_vif_link *rtwvif_link)
4355{
4356	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4357	const struct rtw89_port_reg *p = mac->port_base;
4358	const struct rtw89_chip_info *chip = rtwdev->chip;
4359	struct ieee80211_bss_conf *bss_conf;
4360	bool need_backup = false;
4361	u32 backup_val;
4362	u16 beacon_int;
4363
4364	if (!rtw89_read32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN))
4365		return;
4366
4367	if (chip->chip_id == RTL8852A && rtwvif_link->port != RTW89_PORT_0) {
4368		need_backup = true;
4369		backup_val = rtw89_read32_port(rtwdev, rtwvif_link, p->tbtt_prohib);
4370	}
4371
4372	if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
4373		rtw89_mac_bcn_drop(rtwdev, rtwvif_link);
4374
4375	if (chip->chip_id == RTL8852A) {
4376		rtw89_write32_port_clr(rtwdev, rtwvif_link, p->tbtt_prohib,
4377				       B_AX_TBTT_SETUP_MASK);
4378		rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib,
4379					B_AX_TBTT_HOLD_MASK, 1);
4380		rtw89_write16_port_clr(rtwdev, rtwvif_link, p->tbtt_early,
4381				       B_AX_TBTTERLY_MASK);
4382		rtw89_write16_port_clr(rtwdev, rtwvif_link, p->bcn_early,
4383				       B_AX_BCNERLY_MASK);
4384	}
4385
4386	rcu_read_lock();
4387
4388	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
4389	beacon_int = bss_conf->beacon_int;
4390
4391	rcu_read_unlock();
4392
4393	msleep(beacon_int + 1);
4394	rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN |
4395							    B_AX_BRK_SETUP);
4396	rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSFTR_RST);
4397	rtw89_write32_port(rtwdev, rtwvif_link, p->bcn_cnt_tmr, 0);
4398
4399	if (need_backup)
4400		rtw89_write32_port(rtwdev, rtwvif_link, p->tbtt_prohib, backup_val);
4401}
4402
4403static void rtw89_mac_port_cfg_tx_rpt(struct rtw89_dev *rtwdev,
4404				      struct rtw89_vif_link *rtwvif_link, bool en)
4405{
4406	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4407	const struct rtw89_port_reg *p = mac->port_base;
4408
4409	if (en)
4410		rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg,
4411				       B_AX_TXBCN_RPT_EN);
4412	else
4413		rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg,
4414				       B_AX_TXBCN_RPT_EN);
4415}
4416
4417static void rtw89_mac_port_cfg_rx_rpt(struct rtw89_dev *rtwdev,
4418				      struct rtw89_vif_link *rtwvif_link, bool en)
4419{
4420	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4421	const struct rtw89_port_reg *p = mac->port_base;
4422
4423	if (en)
4424		rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg,
4425				       B_AX_RXBCN_RPT_EN);
4426	else
4427		rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg,
4428				       B_AX_RXBCN_RPT_EN);
4429}
4430
4431static void rtw89_mac_port_cfg_net_type(struct rtw89_dev *rtwdev,
4432					struct rtw89_vif_link *rtwvif_link)
4433{
4434	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4435	const struct rtw89_port_reg *p = mac->port_base;
4436
4437	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_NET_TYPE_MASK,
4438				rtwvif_link->net_type);
4439}
4440
4441static void rtw89_mac_port_cfg_bcn_prct(struct rtw89_dev *rtwdev,
4442					struct rtw89_vif_link *rtwvif_link)
4443{
4444	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4445	const struct rtw89_port_reg *p = mac->port_base;
4446	bool en = rtwvif_link->net_type != RTW89_NET_TYPE_NO_LINK;
4447	u32 bits = B_AX_TBTT_PROHIB_EN | B_AX_BRK_SETUP;
4448
4449	if (en)
4450		rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, bits);
4451	else
4452		rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, bits);
4453}
4454
4455static void rtw89_mac_port_cfg_rx_sw(struct rtw89_dev *rtwdev,
4456				     struct rtw89_vif_link *rtwvif_link)
4457{
4458	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4459	const struct rtw89_port_reg *p = mac->port_base;
4460	bool en = rtwvif_link->net_type == RTW89_NET_TYPE_INFRA ||
4461		  rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC;
4462	u32 bit = B_AX_RX_BSSID_FIT_EN;
4463
4464	if (en)
4465		rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, bit);
4466	else
4467		rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, bit);
4468}
4469
4470void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
4471				struct rtw89_vif_link *rtwvif_link, bool en)
4472{
4473	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4474	const struct rtw89_port_reg *p = mac->port_base;
4475
4476	if (en)
4477		rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSF_UDT_EN);
4478	else
4479		rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSF_UDT_EN);
4480}
4481
4482static void rtw89_mac_port_cfg_rx_sync_by_nettype(struct rtw89_dev *rtwdev,
4483						  struct rtw89_vif_link *rtwvif_link)
4484{
4485	bool en = rtwvif_link->net_type == RTW89_NET_TYPE_INFRA ||
4486		  rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC;
4487
4488	rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif_link, en);
4489}
4490
4491static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev,
4492				     struct rtw89_vif_link *rtwvif_link, bool en)
4493{
4494	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4495	const struct rtw89_port_reg *p = mac->port_base;
4496
4497	if (en)
4498		rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN);
4499	else
4500		rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_BCNTX_EN);
4501}
4502
4503static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev,
4504						struct rtw89_vif_link *rtwvif_link)
4505{
4506	bool en = rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE ||
4507		  rtwvif_link->net_type == RTW89_NET_TYPE_AD_HOC;
4508
4509	rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en);
4510}
4511
4512static void rtw89_mac_enable_ap_bcn_by_chan(struct rtw89_dev *rtwdev,
4513					    struct rtw89_vif_link *rtwvif_link,
4514					    const struct rtw89_chan *to_match,
4515					    bool en)
4516{
4517	const struct rtw89_chan *chan;
4518
4519	if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE)
4520		return;
4521
4522	if (!to_match)
4523		goto doit;
4524
4525	/* @to_match may not be in the same domain as return of calling
4526	 * rtw89_chan_get(). So, cannot compare their addresses directly.
4527	 */
4528	chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
4529	if (chan->channel != to_match->channel)
4530		return;
4531
4532doit:
4533	rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif_link, en);
4534}
4535
4536static void rtw89_mac_enable_aps_bcn_by_chan(struct rtw89_dev *rtwdev,
4537					     const struct rtw89_chan *to_match,
4538					     bool en)
4539{
4540	struct rtw89_vif_link *rtwvif_link;
4541	struct rtw89_vif *rtwvif;
4542	unsigned int link_id;
4543
4544	rtw89_for_each_rtwvif(rtwdev, rtwvif)
4545		rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
4546			rtw89_mac_enable_ap_bcn_by_chan(rtwdev, rtwvif_link,
4547							to_match, en);
4548}
4549
4550void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en)
4551{
4552	rtw89_mac_enable_aps_bcn_by_chan(rtwdev, NULL, en);
4553}
4554
4555static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev,
4556					struct rtw89_vif_link *rtwvif_link)
4557{
4558	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4559	const struct rtw89_port_reg *p = mac->port_base;
4560	struct ieee80211_bss_conf *bss_conf;
4561	u16 bcn_int;
4562
4563	rcu_read_lock();
4564
4565	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
4566	if (bss_conf->beacon_int)
4567		bcn_int = bss_conf->beacon_int;
4568	else
4569		bcn_int = BCN_INTERVAL;
4570
4571	rcu_read_unlock();
4572
4573	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space, B_AX_BCN_SPACE_MASK,
4574				bcn_int);
4575}
4576
4577static void rtw89_mac_port_cfg_hiq_win(struct rtw89_dev *rtwdev,
4578				       struct rtw89_vif_link *rtwvif_link)
4579{
4580	u8 win = rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE ? 16 : 0;
4581	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4582	const struct rtw89_port_reg *p = mac->port_base;
4583	u8 port = rtwvif_link->port;
4584	u32 reg;
4585
4586	reg = rtw89_mac_reg_by_idx(rtwdev, p->hiq_win[port], rtwvif_link->mac_idx);
4587	rtw89_write8(rtwdev, reg, win);
4588}
4589
4590static void rtw89_mac_port_cfg_hiq_dtim(struct rtw89_dev *rtwdev,
4591					struct rtw89_vif_link *rtwvif_link)
4592{
4593	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4594	const struct rtw89_port_reg *p = mac->port_base;
4595	struct ieee80211_bss_conf *bss_conf;
4596	u8 dtim_period;
4597	u32 addr;
4598
4599	rcu_read_lock();
4600
4601	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
4602	dtim_period = bss_conf->dtim_period;
4603
4604	rcu_read_unlock();
4605
4606	addr = rtw89_mac_reg_by_idx(rtwdev, p->md_tsft, rtwvif_link->mac_idx);
4607	rtw89_write8_set(rtwdev, addr, B_AX_UPD_HGQMD | B_AX_UPD_TIMIE);
4608
4609	rtw89_write16_port_mask(rtwdev, rtwvif_link, p->dtim_ctrl, B_AX_DTIM_NUM_MASK,
4610				dtim_period);
4611}
4612
4613static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev,
4614					      struct rtw89_vif_link *rtwvif_link)
4615{
4616	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4617	const struct rtw89_port_reg *p = mac->port_base;
4618
4619	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib,
4620				B_AX_TBTT_SETUP_MASK, BCN_SETUP_DEF);
4621}
4622
4623static void rtw89_mac_port_cfg_bcn_hold_time(struct rtw89_dev *rtwdev,
4624					     struct rtw89_vif_link *rtwvif_link)
4625{
4626	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4627	const struct rtw89_port_reg *p = mac->port_base;
4628
4629	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->tbtt_prohib,
4630				B_AX_TBTT_HOLD_MASK, BCN_HOLD_DEF);
4631}
4632
4633static void rtw89_mac_port_cfg_bcn_mask_area(struct rtw89_dev *rtwdev,
4634					     struct rtw89_vif_link *rtwvif_link)
4635{
4636	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4637	const struct rtw89_port_reg *p = mac->port_base;
4638
4639	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_area,
4640				B_AX_BCN_MSK_AREA_MASK, BCN_MASK_DEF);
4641}
4642
4643static void rtw89_mac_port_cfg_tbtt_early(struct rtw89_dev *rtwdev,
4644					  struct rtw89_vif_link *rtwvif_link)
4645{
4646	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4647	const struct rtw89_port_reg *p = mac->port_base;
4648
4649	rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_early,
4650				B_AX_TBTTERLY_MASK, TBTT_ERLY_DEF);
4651}
4652
4653static void rtw89_mac_port_cfg_tbtt_agg(struct rtw89_dev *rtwdev,
4654					struct rtw89_vif_link *rtwvif_link)
4655{
4656	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4657	const struct rtw89_port_reg *p = mac->port_base;
4658
4659	rtw89_write16_port_mask(rtwdev, rtwvif_link, p->tbtt_agg,
4660				B_AX_TBTT_AGG_NUM_MASK, TBTT_AGG_DEF);
4661}
4662
4663static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev,
4664					 struct rtw89_vif_link *rtwvif_link)
4665{
4666	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4667	const struct rtw89_port_reg *p = mac->port_base;
4668	static const u32 masks[RTW89_PORT_NUM] = {
4669		B_AX_BSS_COLOB_AX_PORT_0_MASK, B_AX_BSS_COLOB_AX_PORT_1_MASK,
4670		B_AX_BSS_COLOB_AX_PORT_2_MASK, B_AX_BSS_COLOB_AX_PORT_3_MASK,
4671		B_AX_BSS_COLOB_AX_PORT_4_MASK,
4672	};
4673	struct ieee80211_bss_conf *bss_conf;
4674	u8 port = rtwvif_link->port;
4675	u32 reg_base;
4676	u32 reg;
4677	u8 bss_color;
4678
4679	rcu_read_lock();
4680
4681	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
4682	bss_color = bss_conf->he_bss_color.color;
4683
4684	rcu_read_unlock();
4685
4686	reg_base = port >= 4 ? p->bss_color + 4 : p->bss_color;
4687	reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif_link->mac_idx);
4688	rtw89_write32_mask(rtwdev, reg, masks[port], bss_color);
4689}
4690
4691static void rtw89_mac_port_cfg_mbssid(struct rtw89_dev *rtwdev,
4692				      struct rtw89_vif_link *rtwvif_link)
4693{
4694	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4695	const struct rtw89_port_reg *p = mac->port_base;
4696	u8 port = rtwvif_link->port;
4697	u32 reg;
4698
4699	if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
4700		return;
4701
4702	if (port == 0) {
4703		reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid, rtwvif_link->mac_idx);
4704		rtw89_write32_clr(rtwdev, reg, B_AX_P0MB_ALL_MASK);
4705	}
4706}
4707
4708static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev,
4709					struct rtw89_vif_link *rtwvif_link)
4710{
4711	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4712	const struct rtw89_port_reg *p = mac->port_base;
4713	u8 port = rtwvif_link->port;
4714	u32 reg;
4715	u32 val;
4716
4717	reg = rtw89_mac_reg_by_idx(rtwdev, p->mbssid_drop, rtwvif_link->mac_idx);
4718	val = rtw89_read32(rtwdev, reg);
4719	val &= ~FIELD_PREP(B_AX_PORT_DROP_4_0_MASK, BIT(port));
4720	if (port == 0)
4721		val &= ~BIT(0);
4722	rtw89_write32(rtwdev, reg, val);
4723}
4724
4725static void rtw89_mac_port_cfg_func_en(struct rtw89_dev *rtwdev,
4726				       struct rtw89_vif_link *rtwvif_link, bool enable)
4727{
4728	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4729	const struct rtw89_port_reg *p = mac->port_base;
4730
4731	if (enable)
4732		rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg,
4733				       B_AX_PORT_FUNC_EN);
4734	else
4735		rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg,
4736				       B_AX_PORT_FUNC_EN);
4737}
4738
4739static void rtw89_mac_port_cfg_bcn_early(struct rtw89_dev *rtwdev,
4740					 struct rtw89_vif_link *rtwvif_link)
4741{
4742	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4743	const struct rtw89_port_reg *p = mac->port_base;
4744
4745	rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_early, B_AX_BCNERLY_MASK,
4746				BCN_ERLY_DEF);
4747}
4748
4749static void rtw89_mac_port_cfg_bcn_psr_rpt(struct rtw89_dev *rtwdev,
4750					   struct rtw89_vif_link *rtwvif_link)
4751{
4752	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4753	const struct rtw89_port_reg *p = mac->port_base;
4754	struct ieee80211_bss_conf *bss_conf;
4755	u8 bssid_index;
4756	u32 reg;
4757
4758	rcu_read_lock();
4759
4760	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
4761	if (bss_conf->nontransmitted)
4762		bssid_index = bss_conf->bssid_index;
4763	else
4764		bssid_index = 0;
4765
4766	rcu_read_unlock();
4767
4768	reg = rtw89_mac_reg_by_idx(rtwdev, p->bcn_psr_rpt + rtwvif_link->port * 4,
4769				   rtwvif_link->mac_idx);
4770	rtw89_write32_mask(rtwdev, reg, B_AX_BCAID_P0_MASK, bssid_index);
4771}
4772
4773void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
4774			     struct rtw89_vif_link *rtwvif_link,
4775			     struct rtw89_vif_link *rtwvif_src,
4776			     u16 offset_tu)
4777{
4778	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4779	const struct rtw89_port_reg *p = mac->port_base;
4780	u32 val, reg;
4781
4782	val = RTW89_PORT_OFFSET_TU_TO_32US(offset_tu);
4783	reg = rtw89_mac_reg_by_idx(rtwdev, p->tsf_sync + rtwvif_link->port * 4,
4784				   rtwvif_link->mac_idx);
4785
4786	rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_SRC, rtwvif_src->port);
4787	rtw89_write32_mask(rtwdev, reg, B_AX_SYNC_PORT_OFFSET_VAL, val);
4788	rtw89_write32_set(rtwdev, reg, B_AX_SYNC_NOW);
4789}
4790
4791static void rtw89_mac_port_tsf_sync_rand(struct rtw89_dev *rtwdev,
4792					 struct rtw89_vif_link *rtwvif_link,
4793					 struct rtw89_vif_link *rtwvif_src,
4794					 u8 offset, int *n_offset)
4795{
4796	if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif_link == rtwvif_src)
4797		return;
4798
4799	if (rtwvif_link->rand_tsf_done)
4800		goto out;
4801
4802	/* adjust offset randomly to avoid beacon conflict */
4803	offset = offset - offset / 4 + get_random_u32() % (offset / 2);
4804	rtw89_mac_port_tsf_sync(rtwdev, rtwvif_link, rtwvif_src,
4805				(*n_offset) * offset);
4806
4807	rtwvif_link->rand_tsf_done = true;
4808
4809out:
4810	(*n_offset)++;
4811}
4812
4813static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev)
4814{
4815	struct rtw89_vif_link *src = NULL, *tmp;
4816	u8 offset = 100, vif_aps = 0;
4817	struct rtw89_vif *rtwvif;
4818	unsigned int link_id;
4819	int n_offset = 1;
4820
4821	rtw89_for_each_rtwvif(rtwdev, rtwvif) {
4822		rtw89_vif_for_each_link(rtwvif, tmp, link_id) {
4823			if (!src || tmp->net_type == RTW89_NET_TYPE_INFRA)
4824				src = tmp;
4825			if (tmp->net_type == RTW89_NET_TYPE_AP_MODE)
4826				vif_aps++;
4827		}
4828	}
4829
4830	if (vif_aps == 0)
4831		return;
4832
4833	offset /= (vif_aps + 1);
4834
4835	rtw89_for_each_rtwvif(rtwdev, rtwvif)
4836		rtw89_vif_for_each_link(rtwvif, tmp, link_id)
4837			rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset,
4838						     &n_offset);
4839}
4840
4841int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
4842{
4843	int ret;
4844
4845	ret = rtw89_mac_port_update(rtwdev, rtwvif_link);
4846	if (ret)
4847		return ret;
4848
4849	rtw89_mac_dmac_tbl_init(rtwdev, rtwvif_link->mac_id);
4850	rtw89_mac_cmac_tbl_init(rtwdev, rtwvif_link->mac_id);
4851
4852	ret = rtw89_mac_set_macid_pause(rtwdev, rtwvif_link->mac_id, false);
4853	if (ret)
4854		return ret;
4855
4856	ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_CREATE);
4857	if (ret)
4858		return ret;
4859
4860	ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true);
4861	if (ret)
4862		return ret;
4863
4864	ret = rtw89_cam_init(rtwdev, rtwvif_link);
4865	if (ret)
4866		return ret;
4867
4868	ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_CREATE);
4869	if (ret)
4870		return ret;
4871
4872	ret = rtw89_chip_h2c_default_cmac_tbl(rtwdev, rtwvif_link, NULL);
4873	if (ret)
4874		return ret;
4875
4876	ret = rtw89_chip_h2c_default_dmac_tbl(rtwdev, rtwvif_link, NULL);
4877	if (ret)
4878		return ret;
4879
4880	return 0;
4881}
4882
4883int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
4884{
4885	int ret;
4886
4887	ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_REMOVE);
4888	if (ret)
4889		return ret;
4890
4891	rtw89_cam_deinit(rtwdev, rtwvif_link);
4892
4893	ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_REMOVE);
4894	if (ret)
4895		return ret;
4896
4897	return 0;
4898}
4899
4900int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
4901{
4902	u8 port = rtwvif_link->port;
4903
4904	if (port >= RTW89_PORT_NUM)
4905		return -EINVAL;
4906
4907	rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link);
4908	rtw89_mac_port_cfg_tx_rpt(rtwdev, rtwvif_link, false);
4909	rtw89_mac_port_cfg_rx_rpt(rtwdev, rtwvif_link, false);
4910	rtw89_mac_port_cfg_net_type(rtwdev, rtwvif_link);
4911	rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif_link);
4912	rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif_link);
4913	rtw89_mac_port_cfg_rx_sync_by_nettype(rtwdev, rtwvif_link);
4914	rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif_link);
4915	rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif_link);
4916	rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif_link);
4917	rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif_link);
4918	rtw89_mac_port_cfg_hiq_drop(rtwdev, rtwvif_link);
4919	rtw89_mac_port_cfg_bcn_setup_time(rtwdev, rtwvif_link);
4920	rtw89_mac_port_cfg_bcn_hold_time(rtwdev, rtwvif_link);
4921	rtw89_mac_port_cfg_bcn_mask_area(rtwdev, rtwvif_link);
4922	rtw89_mac_port_cfg_tbtt_early(rtwdev, rtwvif_link);
4923	rtw89_mac_port_cfg_tbtt_agg(rtwdev, rtwvif_link);
4924	rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif_link);
4925	rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif_link);
4926	rtw89_mac_port_cfg_func_en(rtwdev, rtwvif_link, true);
4927	rtw89_mac_port_tsf_resync_all(rtwdev);
4928	fsleep(BCN_ERLY_SET_DLY);
4929	rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif_link);
4930	rtw89_mac_port_cfg_bcn_psr_rpt(rtwdev, rtwvif_link);
4931
4932	return 0;
4933}
4934
4935int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
4936			   u64 *tsf)
4937{
4938	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4939	const struct rtw89_port_reg *p = mac->port_base;
4940	u32 tsf_low, tsf_high;
4941	int ret;
4942
4943	ret = rtw89_mac_check_mac_en(rtwdev, rtwvif_link->mac_idx, RTW89_CMAC_SEL);
4944	if (ret)
4945		return ret;
4946
4947	tsf_low = rtw89_read32_port(rtwdev, rtwvif_link, p->tsftr_l);
4948	tsf_high = rtw89_read32_port(rtwdev, rtwvif_link, p->tsftr_h);
4949	*tsf = (u64)tsf_high << 32 | tsf_low;
4950
4951	return 0;
4952}
4953
4954static void rtw89_mac_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
4955						      struct cfg80211_bss *bss,
4956						      void *data)
4957{
4958	const struct cfg80211_bss_ies *ies;
4959	const struct element *elem;
4960	bool *tolerated = data;
4961
4962	rcu_read_lock();
4963	ies = rcu_dereference(bss->ies);
4964	elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data,
4965				  ies->len);
4966
4967	if (!elem || elem->datalen < 10 ||
4968	    !(elem->data[10] & WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT))
4969		*tolerated = false;
4970	rcu_read_unlock();
4971}
4972
4973void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
4974					struct rtw89_vif_link *rtwvif_link)
4975{
4976	struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
4977	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
4978	struct ieee80211_hw *hw = rtwdev->hw;
4979	struct ieee80211_bss_conf *bss_conf;
4980	struct cfg80211_chan_def oper;
4981	bool tolerated = true;
4982	u32 reg;
4983
4984	rcu_read_lock();
4985
4986	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
4987	if (!bss_conf->he_support || vif->type != NL80211_IFTYPE_STATION) {
4988		rcu_read_unlock();
4989		return;
4990	}
4991
4992	oper = bss_conf->chanreq.oper;
4993	if (!(oper.chan->flags & IEEE80211_CHAN_RADAR)) {
4994		rcu_read_unlock();
4995		return;
4996	}
4997
4998	rcu_read_unlock();
4999
5000	cfg80211_bss_iter(hw->wiphy, &oper,
5001			  rtw89_mac_check_he_obss_narrow_bw_ru_iter,
5002			  &tolerated);
5003
5004	reg = rtw89_mac_reg_by_idx(rtwdev, mac->narrow_bw_ru_dis.addr,
5005				   rtwvif_link->mac_idx);
5006	if (tolerated)
5007		rtw89_write32_clr(rtwdev, reg, mac->narrow_bw_ru_dis.mask);
5008	else
5009		rtw89_write32_set(rtwdev, reg, mac->narrow_bw_ru_dis.mask);
5010}
5011
5012void rtw89_mac_set_he_tb(struct rtw89_dev *rtwdev,
5013			 struct rtw89_vif_link *rtwvif_link)
5014{
5015	struct ieee80211_bss_conf *bss_conf;
5016	bool set;
5017	u32 reg;
5018
5019	if (rtwdev->chip->chip_gen != RTW89_CHIP_BE)
5020		return;
5021
5022	rcu_read_lock();
5023
5024	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
5025	set = bss_conf->he_support && !bss_conf->eht_support;
5026
5027	rcu_read_unlock();
5028
5029	reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CLIENT_OM_CTRL,
5030				   rtwvif_link->mac_idx);
5031
5032	if (set)
5033		rtw89_write32_set(rtwdev, reg, B_BE_TRIG_DIS_EHTTB);
5034	else
5035		rtw89_write32_clr(rtwdev, reg, B_BE_TRIG_DIS_EHTTB);
5036}
5037
5038void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
5039{
5040	rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link);
5041
5042	rtwvif_link->rand_tsf_done = false;
5043}
5044
5045int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
5046{
5047	return rtw89_mac_vif_init(rtwdev, rtwvif_link);
5048}
5049
5050int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
5051{
5052	return rtw89_mac_vif_deinit(rtwdev, rtwvif_link);
5053}
5054
5055static void
5056rtw89_mac_c2h_macid_pause(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5057{
5058}
5059
5060static const struct rtw89_chan *
5061rtw89_hw_scan_search_op_chan(struct rtw89_dev *rtwdev, u8 band, u8 channel)
5062{
5063	struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
5064	const struct rtw89_chan *op = &rtwdev->scan_info.op_chan;
5065
5066	if (band == op->band_type && channel == op->primary_channel)
5067		return op;
5068
5069	if (scan_info->extra_op.set) {
5070		op = &scan_info->extra_op.chan;
5071		if (band == op->band_type && channel == op->primary_channel)
5072			return op;
5073	}
5074
5075	return NULL;
5076}
5077
5078static void
5079rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb,
5080			   u32 len)
5081{
5082	const struct rtw89_c2h_scanofld *c2h =
5083		(const struct rtw89_c2h_scanofld *)skb->data;
5084	struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
5085	const struct rtw89_chan *op_chan;
5086	struct rtw89_vif *rtwvif;
5087	struct rtw89_chan new;
5088	u16 actual_period, expect_period;
5089	u8 reason, status, tx_fail, band;
5090	u8 mac_idx, sw_def, fw_def;
5091	u8 ver = U8_MAX;
5092	u32 report_tsf;
5093	u16 chan;
5094	int ret;
5095
5096	if (!rtwvif_link)
5097		return;
5098
5099	rtwvif = rtwvif_link->rtwvif;
5100
5101	if (RTW89_CHK_FW_FEATURE(CH_INFO_BE_V0, &rtwdev->fw))
5102		ver = 0;
5103
5104	tx_fail = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_TX_FAIL);
5105	status = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_STATUS);
5106	chan = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_PRI_CH);
5107	reason = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_RSN);
5108	band = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_BAND);
5109	actual_period = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_PERIOD);
5110	mac_idx = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_MAC_IDX);
5111
5112
5113	if (!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))
5114		band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
5115
5116	if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
5117		sw_def = le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_SW_DEF);
5118		fw_def = le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_FW_DEF);
5119		report_tsf = le32_get_bits(c2h->w7, RTW89_C2H_SCANOFLD_W7_REPORT_TSF);
5120		if (ver == 0) {
5121			expect_period =
5122				le32_get_bits(c2h->w6, RTW89_C2H_SCANOFLD_W6_EXPECT_PERIOD);
5123		} else {
5124			actual_period = le32_get_bits(c2h->w8, RTW89_C2H_SCANOFLD_W8_PERIOD_V1);
5125			expect_period =
5126				le32_get_bits(c2h->w8, RTW89_C2H_SCANOFLD_W8_EXPECT_PERIOD_V1);
5127		}
5128
5129		rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
5130			    "sw_def: %d, fw_def: %d, tsf: %x, expect: %d\n",
5131			    sw_def, fw_def, report_tsf, expect_period);
5132	}
5133
5134	rtw89_debug(rtwdev, RTW89_DBG_HW_SCAN,
5135		    "mac_idx[%d] band: %d, chan: %d, reason: %d, status: %d, tx_fail: %d, actual: %d\n",
5136		    mac_idx, band, chan, reason, status, tx_fail, actual_period);
5137
5138	switch (reason) {
5139	case RTW89_SCAN_LEAVE_OP_NOTIFY:
5140	case RTW89_SCAN_LEAVE_CH_NOTIFY:
5141		op_chan = rtw89_hw_scan_search_op_chan(rtwdev, band, chan);
5142		if (op_chan) {
5143			rtw89_mac_enable_aps_bcn_by_chan(rtwdev, op_chan, false);
5144			ieee80211_stop_queues(rtwdev->hw);
5145		} else {
5146			rtw89_phy_nhm_get_result(rtwdev, band, chan);
5147		}
5148		return;
5149	case RTW89_SCAN_END_SCAN_NOTIFY:
5150		if (rtwdev->scan_info.abort)
5151			return;
5152
5153		if (rtwvif_link && rtwvif->scan_req &&
5154		    !list_empty(&rtwdev->scan_info.chan_list)) {
5155			rtwdev->scan_info.delay = 0;
5156			ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true);
5157			if (ret) {
5158				rtw89_hw_scan_abort(rtwdev, rtwvif_link);
5159				rtw89_warn(rtwdev, "HW scan failed: %d\n", ret);
5160			}
5161		} else {
5162			rtw89_hw_scan_complete(rtwdev, rtwvif_link, false);
5163		}
5164		break;
5165	case RTW89_SCAN_ENTER_OP_NOTIFY:
5166	case RTW89_SCAN_ENTER_CH_NOTIFY:
5167		op_chan = rtw89_hw_scan_search_op_chan(rtwdev, band, chan);
5168		if (op_chan) {
5169			rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx, op_chan);
5170			rtw89_mac_enable_aps_bcn_by_chan(rtwdev, op_chan, true);
5171			ieee80211_wake_queues(rtwdev->hw);
5172		} else {
5173			rtw89_chan_create(&new, chan, chan, band,
5174					  RTW89_CHANNEL_WIDTH_20);
5175			rtw89_assign_entity_chan(rtwdev, rtwvif_link->chanctx_idx,
5176						 &new);
5177			rtw89_phy_nhm_trigger(rtwdev);
5178		}
5179		break;
5180	default:
5181		return;
5182	}
5183}
5184
5185static void
5186rtw89_mac_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
5187		       struct sk_buff *skb)
5188{
5189	struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
5190	struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
5191	enum nl80211_cqm_rssi_threshold_event nl_event;
5192	const struct rtw89_c2h_mac_bcnfltr_rpt *c2h =
5193		(const struct rtw89_c2h_mac_bcnfltr_rpt *)skb->data;
5194	u8 type, event, mac_id;
5195	bool start_detect;
5196	s8 sig;
5197
5198	type = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_TYPE);
5199	sig = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MA) - MAX_RSSI;
5200	event = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_EVENT);
5201	mac_id = le32_get_bits(c2h->w2, RTW89_C2H_MAC_BCNFLTR_RPT_W2_MACID);
5202
5203	if (mac_id != rtwvif_link->mac_id)
5204		return;
5205
5206	rtw89_debug(rtwdev, RTW89_DBG_FW,
5207		    "C2H bcnfltr rpt macid: %d, type: %d, ma: %d, event: %d\n",
5208		    mac_id, type, sig, event);
5209
5210	switch (type) {
5211	case RTW89_BCN_FLTR_BEACON_LOSS:
5212		if (!rtwdev->scanning && !rtwvif->offchan &&
5213		    !rtwvif_link->noa_once.in_duration) {
5214			start_detect = rtw89_mcc_detect_go_bcn(rtwdev, rtwvif_link);
5215			if (start_detect)
5216				return;
5217
5218			ieee80211_connection_loss(vif);
5219		} else {
5220			rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
5221		}
5222		return;
5223	case RTW89_BCN_FLTR_NOTIFY:
5224		nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
5225		break;
5226	case RTW89_BCN_FLTR_RSSI:
5227		if (event == RTW89_BCN_FLTR_RSSI_LOW)
5228			nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
5229		else if (event == RTW89_BCN_FLTR_RSSI_HIGH)
5230			nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
5231		else
5232			return;
5233		break;
5234	default:
5235		return;
5236	}
5237
5238	ieee80211_cqm_rssi_notify(vif, nl_event, sig, GFP_KERNEL);
5239}
5240
5241static void
5242rtw89_mac_c2h_bcn_fltr_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
5243			   u32 len)
5244{
5245	struct rtw89_vif_link *rtwvif_link;
5246	struct rtw89_vif *rtwvif;
5247	unsigned int link_id;
5248
5249	rtw89_for_each_rtwvif(rtwdev, rtwvif)
5250		rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
5251			rtw89_mac_bcn_fltr_rpt(rtwdev, rtwvif_link, c2h);
5252}
5253
5254static void
5255rtw89_mac_c2h_rec_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5256{
5257	/* N.B. This will run in interrupt context. */
5258
5259	rtw89_debug(rtwdev, RTW89_DBG_FW,
5260		    "C2H rev ack recv, cat: %d, class: %d, func: %d, seq : %d\n",
5261		    RTW89_GET_MAC_C2H_REV_ACK_CAT(c2h->data),
5262		    RTW89_GET_MAC_C2H_REV_ACK_CLASS(c2h->data),
5263		    RTW89_GET_MAC_C2H_REV_ACK_FUNC(c2h->data),
5264		    RTW89_GET_MAC_C2H_REV_ACK_H2C_SEQ(c2h->data));
5265}
5266
5267static void
5268rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len)
5269{
5270	/* N.B. This will run in interrupt context. */
5271	struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait;
5272	struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
5273	struct rtw89_wait_info *ps_wait = &rtwdev->mac.ps_wait;
5274	const struct rtw89_c2h_done_ack *c2h =
5275		(const struct rtw89_c2h_done_ack *)skb_c2h->data;
5276	u8 h2c_cat = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CAT);
5277	u8 h2c_class = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_CLASS);
5278	u8 h2c_func = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_FUNC);
5279	u8 h2c_return = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_H2C_RETURN);
5280	u8 h2c_seq = le32_get_bits(c2h->w2, RTW89_C2H_DONE_ACK_W2_H2C_SEQ);
5281	struct rtw89_completion_data data = {};
5282	unsigned int cond;
5283
5284	rtw89_debug(rtwdev, RTW89_DBG_FW,
5285		    "C2H done ack recv, cat: %d, class: %d, func: %d, ret: %d, seq : %d\n",
5286		    h2c_cat, h2c_class, h2c_func, h2c_return, h2c_seq);
5287
5288	if (h2c_cat != H2C_CAT_MAC)
5289		return;
5290
5291	switch (h2c_class) {
5292	default:
5293		return;
5294	case H2C_CL_MAC_PS:
5295		switch (h2c_func) {
5296		default:
5297			return;
5298		case H2C_FUNC_IPS_CFG:
5299			cond = RTW89_PS_WAIT_COND_IPS_CFG;
5300			break;
5301		}
5302
5303		data.err = !!h2c_return;
5304		rtw89_complete_cond(ps_wait, cond, &data);
5305		return;
5306	case H2C_CL_MAC_FW_OFLD:
5307		switch (h2c_func) {
5308		default:
5309			return;
5310		case H2C_FUNC_ADD_SCANOFLD_CH:
5311			cond = RTW89_SCANOFLD_WAIT_COND_ADD_CH;
5312			h2c_return &= RTW89_C2H_SCAN_DONE_ACK_RETURN;
5313			break;
5314		case H2C_FUNC_SCANOFLD:
5315			scan_info->seq++;
5316			cond = RTW89_SCANOFLD_WAIT_COND_START;
5317			break;
5318		case H2C_FUNC_SCANOFLD_BE:
5319			scan_info->seq++;
5320			cond = RTW89_SCANOFLD_BE_WAIT_COND_START;
5321			h2c_return &= RTW89_C2H_SCAN_DONE_ACK_RETURN;
5322			break;
5323		}
5324
5325		data.err = !!h2c_return;
5326		rtw89_complete_cond(fw_ofld_wait, cond, &data);
5327		return;
5328	}
5329}
5330
5331static void
5332rtw89_mac_c2h_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5333{
5334	rtw89_fw_log_dump(rtwdev, c2h->data, len);
5335}
5336
5337static void
5338rtw89_mac_c2h_bcn_cnt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5339{
5340}
5341
5342static void
5343rtw89_mac_c2h_bcn_upd_done(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len)
5344{
5345	const struct rtw89_c2h_bcn_upd_done *c2h =
5346		(const struct rtw89_c2h_bcn_upd_done *)skb_c2h->data;
5347	u8 band, port, mbssid;
5348
5349	port = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_PORT);
5350	mbssid = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_MBSSID);
5351	band = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_BAND_IDX);
5352
5353	rtw89_debug(rtwdev, RTW89_DBG_FW,
5354		    "BCN update done on port:%d mbssid:%d band:%d\n",
5355		    port, mbssid, band);
5356}
5357
5358static void
5359rtw89_mac_c2h_pkt_ofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h,
5360			   u32 len)
5361{
5362	struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait;
5363	const struct rtw89_c2h_pkt_ofld_rsp *c2h =
5364		(const struct rtw89_c2h_pkt_ofld_rsp *)skb_c2h->data;
5365	u16 pkt_len = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_LEN);
5366	u8 pkt_id = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_ID);
5367	u8 pkt_op = le32_get_bits(c2h->w2, RTW89_C2H_PKT_OFLD_RSP_W2_PTK_OP);
5368	struct rtw89_completion_data data = {};
5369	unsigned int cond;
5370
5371	rtw89_debug(rtwdev, RTW89_DBG_FW, "pkt ofld rsp: id %d op %d len %d\n",
5372		    pkt_id, pkt_op, pkt_len);
5373
5374	data.err = !pkt_len;
5375	cond = RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(pkt_id, pkt_op);
5376
5377	rtw89_complete_cond(wait, cond, &data);
5378}
5379
5380static void
5381rtw89_mac_c2h_bcn_resend(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5382{
5383}
5384
5385static void
5386rtw89_mac_c2h_tx_duty_rpt(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len)
5387{
5388	struct rtw89_c2h_tx_duty_rpt *c2h =
5389		(struct rtw89_c2h_tx_duty_rpt *)skb_c2h->data;
5390	u8 err;
5391
5392	err = le32_get_bits(c2h->w2, RTW89_C2H_TX_DUTY_RPT_W2_TIMER_ERR);
5393
5394	rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "C2H TX duty rpt with err=%d\n", err);
5395}
5396
5397static void
5398rtw89_mac_c2h_tsf32_toggle_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
5399			       u32 len)
5400{
5401	rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_TSF32_TOGGLE_CHANGE);
5402}
5403
5404static void
5405rtw89_mac_c2h_mcc_rcv_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5406{
5407	u8 group = RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h->data);
5408	u8 func = RTW89_GET_MAC_C2H_MCC_RCV_ACK_H2C_FUNC(c2h->data);
5409
5410	switch (func) {
5411	case H2C_FUNC_ADD_MCC:
5412	case H2C_FUNC_START_MCC:
5413	case H2C_FUNC_STOP_MCC:
5414	case H2C_FUNC_DEL_MCC_GROUP:
5415	case H2C_FUNC_RESET_MCC_GROUP:
5416	case H2C_FUNC_MCC_REQ_TSF:
5417	case H2C_FUNC_MCC_MACID_BITMAP:
5418	case H2C_FUNC_MCC_SYNC:
5419	case H2C_FUNC_MCC_SET_DURATION:
5420		break;
5421	default:
5422		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5423			    "invalid MCC C2H RCV ACK: func %d\n", func);
5424		return;
5425	}
5426
5427	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5428		    "MCC C2H RCV ACK: group %d, func %d\n", group, func);
5429}
5430
5431static void
5432rtw89_mac_c2h_mcc_req_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5433{
5434	u8 group = RTW89_GET_MAC_C2H_MCC_REQ_ACK_GROUP(c2h->data);
5435	u8 func = RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h->data);
5436	u8 retcode = RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_RETURN(c2h->data);
5437	struct rtw89_completion_data data = {};
5438	unsigned int cond;
5439	bool next = false;
5440
5441	switch (func) {
5442	case H2C_FUNC_MCC_REQ_TSF:
5443		next = true;
5444		break;
5445	case H2C_FUNC_MCC_MACID_BITMAP:
5446	case H2C_FUNC_MCC_SYNC:
5447	case H2C_FUNC_MCC_SET_DURATION:
5448		break;
5449	case H2C_FUNC_ADD_MCC:
5450	case H2C_FUNC_START_MCC:
5451	case H2C_FUNC_STOP_MCC:
5452	case H2C_FUNC_DEL_MCC_GROUP:
5453	case H2C_FUNC_RESET_MCC_GROUP:
5454	default:
5455		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5456			    "invalid MCC C2H REQ ACK: func %d\n", func);
5457		return;
5458	}
5459
5460	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5461		    "MCC C2H REQ ACK: group %d, func %d, return code %d\n",
5462		    group, func, retcode);
5463
5464	if (!retcode && next)
5465		return;
5466
5467	data.err = !!retcode;
5468	cond = RTW89_MCC_WAIT_COND(group, func);
5469	rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data);
5470}
5471
5472static void
5473rtw89_mac_c2h_mcc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5474{
5475	u8 group = RTW89_GET_MAC_C2H_MCC_TSF_RPT_GROUP(c2h->data);
5476	struct rtw89_completion_data data = {};
5477	struct rtw89_mac_mcc_tsf_rpt *rpt;
5478	unsigned int cond;
5479
5480	rpt = (struct rtw89_mac_mcc_tsf_rpt *)data.buf;
5481	rpt->macid_x = RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_X(c2h->data);
5482	rpt->macid_y = RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_Y(c2h->data);
5483	rpt->tsf_x_low = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_X(c2h->data);
5484	rpt->tsf_x_high = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_X(c2h->data);
5485	rpt->tsf_y_low = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h->data);
5486	rpt->tsf_y_high = RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h->data);
5487
5488	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5489		    "MCC C2H TSF RPT: macid %d> %llu, macid %d> %llu\n",
5490		    rpt->macid_x, (u64)rpt->tsf_x_high << 32 | rpt->tsf_x_low,
5491		    rpt->macid_y, (u64)rpt->tsf_y_high << 32 | rpt->tsf_y_low);
5492
5493	cond = RTW89_MCC_WAIT_COND(group, H2C_FUNC_MCC_REQ_TSF);
5494	rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data);
5495}
5496
5497static void
5498rtw89_mac_c2h_mcc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5499{
5500	u8 group = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_GROUP(c2h->data);
5501	u8 macid = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_MACID(c2h->data);
5502	u8 status = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_STATUS(c2h->data);
5503	u32 tsf_low = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_LOW(c2h->data);
5504	u32 tsf_high = RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h->data);
5505	struct rtw89_completion_data data = {};
5506	unsigned int cond;
5507	bool rsp = true;
5508	bool err;
5509	u8 func;
5510
5511	switch (status) {
5512	case RTW89_MAC_MCC_ADD_ROLE_OK:
5513	case RTW89_MAC_MCC_ADD_ROLE_FAIL:
5514		func = H2C_FUNC_ADD_MCC;
5515		err = status == RTW89_MAC_MCC_ADD_ROLE_FAIL;
5516		break;
5517	case RTW89_MAC_MCC_START_GROUP_OK:
5518	case RTW89_MAC_MCC_START_GROUP_FAIL:
5519		func = H2C_FUNC_START_MCC;
5520		err = status == RTW89_MAC_MCC_START_GROUP_FAIL;
5521		break;
5522	case RTW89_MAC_MCC_STOP_GROUP_OK:
5523	case RTW89_MAC_MCC_STOP_GROUP_FAIL:
5524		func = H2C_FUNC_STOP_MCC;
5525		err = status == RTW89_MAC_MCC_STOP_GROUP_FAIL;
5526		break;
5527	case RTW89_MAC_MCC_DEL_GROUP_OK:
5528	case RTW89_MAC_MCC_DEL_GROUP_FAIL:
5529		func = H2C_FUNC_DEL_MCC_GROUP;
5530		err = status == RTW89_MAC_MCC_DEL_GROUP_FAIL;
5531		break;
5532	case RTW89_MAC_MCC_RESET_GROUP_OK:
5533	case RTW89_MAC_MCC_RESET_GROUP_FAIL:
5534		func = H2C_FUNC_RESET_MCC_GROUP;
5535		err = status == RTW89_MAC_MCC_RESET_GROUP_FAIL;
5536		break;
5537	case RTW89_MAC_MCC_SWITCH_CH_OK:
5538	case RTW89_MAC_MCC_SWITCH_CH_FAIL:
5539	case RTW89_MAC_MCC_TXNULL0_OK:
5540	case RTW89_MAC_MCC_TXNULL0_FAIL:
5541	case RTW89_MAC_MCC_TXNULL1_OK:
5542	case RTW89_MAC_MCC_TXNULL1_FAIL:
5543	case RTW89_MAC_MCC_SWITCH_EARLY:
5544	case RTW89_MAC_MCC_TBTT:
5545	case RTW89_MAC_MCC_DURATION_START:
5546	case RTW89_MAC_MCC_DURATION_END:
5547		rsp = false;
5548		break;
5549	default:
5550		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5551			    "invalid MCC C2H STS RPT: status %d\n", status);
5552		return;
5553	}
5554
5555	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5556		    "MCC C2H STS RPT: group %d, macid %d, status %d, tsf %llu\n",
5557		     group, macid, status, (u64)tsf_high << 32 | tsf_low);
5558
5559	if (!rsp)
5560		return;
5561
5562	data.err = err;
5563	cond = RTW89_MCC_WAIT_COND(group, func);
5564	rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data);
5565}
5566
5567static void
5568rtw89_mac_c2h_tx_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5569{
5570	struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt;
5571	struct rtw89_tx_skb_data *skb_data;
5572	u8 sw_define, tx_status, txcnt;
5573	struct sk_buff *skb;
5574
5575	if (rtwdev->chip->chip_id == RTL8922A) {
5576		const struct rtw89_c2h_mac_tx_rpt_v2 *rpt_v2;
5577
5578		rpt_v2 = (const struct rtw89_c2h_mac_tx_rpt_v2 *)c2h->data;
5579		sw_define = le32_get_bits(rpt_v2->w12,
5580					  RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2);
5581		tx_status = le32_get_bits(rpt_v2->w12,
5582					  RTW89_C2H_MAC_TX_RPT_W12_TX_STATE_V2);
5583		txcnt = le32_get_bits(rpt_v2->w14,
5584				      RTW89_C2H_MAC_TX_RPT_W14_DATA_TX_CNT_V2);
5585	} else {
5586		const struct rtw89_c2h_mac_tx_rpt *rpt;
5587
5588		rpt = (const struct rtw89_c2h_mac_tx_rpt *)c2h->data;
5589		sw_define = le32_get_bits(rpt->w2, RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE);
5590		tx_status = le32_get_bits(rpt->w2, RTW89_C2H_MAC_TX_RPT_W2_TX_STATE);
5591		if (rtwdev->chip->chip_id == RTL8852C)
5592			txcnt = le32_get_bits(rpt->w5,
5593					      RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT_V1);
5594		else
5595			txcnt = le32_get_bits(rpt->w5,
5596					      RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT);
5597	}
5598
5599	rtw89_debug(rtwdev, RTW89_DBG_TXRX,
5600		    "C2H TX RPT: sn %d, tx_status %d, txcnt %d\n",
5601		    sw_define, tx_status, txcnt);
5602
5603	/* claim sw_define is not over size of tx_rpt->skbs[] */
5604	static_assert(hweight32(RTW89_MAX_TX_RPTS_MASK) ==
5605		      hweight32(RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2) &&
5606		      hweight32(RTW89_MAX_TX_RPTS_MASK) ==
5607		      hweight32(RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE));
5608
5609	scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) {
5610		skb = tx_rpt->skbs[sw_define];
5611
5612		/* skip if no skb (normally shouldn't happen) */
5613		if (!skb) {
5614			rtw89_debug(rtwdev, RTW89_DBG_TXRX,
5615				    "C2H TX RPT: no skb found in queue\n");
5616			return;
5617		}
5618
5619		skb_data = RTW89_TX_SKB_CB(skb);
5620
5621		/* skip if TX attempt has failed and retry limit has not been
5622		 * reached yet
5623		 */
5624		if (tx_status != RTW89_TX_DONE &&
5625		    txcnt != skb_data->tx_pkt_cnt_lmt)
5626			return;
5627
5628		tx_rpt->skbs[sw_define] = NULL;
5629		rtw89_tx_rpt_tx_status(rtwdev, skb, tx_status);
5630	}
5631}
5632
5633static void
5634rtw89_mac_c2h_mrc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5635{
5636	struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
5637	const struct rtw89_c2h_mrc_tsf_rpt *c2h_rpt;
5638	struct rtw89_completion_data data = {};
5639	struct rtw89_mac_mrc_tsf_rpt *rpt;
5640	unsigned int i;
5641
5642	c2h_rpt = (const struct rtw89_c2h_mrc_tsf_rpt *)c2h->data;
5643	rpt = (struct rtw89_mac_mrc_tsf_rpt *)data.buf;
5644	rpt->num = min_t(u8, RTW89_MAC_MRC_MAX_REQ_TSF_NUM,
5645			 le32_get_bits(c2h_rpt->w2,
5646				       RTW89_C2H_MRC_TSF_RPT_W2_REQ_TSF_NUM));
5647
5648	for (i = 0; i < rpt->num; i++) {
5649		u32 tsf_high = le32_to_cpu(c2h_rpt->infos[i].tsf_high);
5650		u32 tsf_low = le32_to_cpu(c2h_rpt->infos[i].tsf_low);
5651
5652		rpt->tsfs[i] = (u64)tsf_high << 32 | tsf_low;
5653
5654		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5655			    "MRC C2H TSF RPT: index %u> %llu\n",
5656			    i, rpt->tsfs[i]);
5657	}
5658
5659	rtw89_complete_cond(wait, RTW89_MRC_WAIT_COND_REQ_TSF, &data);
5660}
5661
5662static void
5663rtw89_mac_c2h_wow_aoac_rpt(struct rtw89_dev *rtwdev, struct sk_buff *skb, u32 len)
5664{
5665	struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
5666	struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
5667	struct rtw89_wait_info *wait = &rtw_wow->wait;
5668	const struct rtw89_c2h_wow_aoac_report *c2h =
5669		(const struct rtw89_c2h_wow_aoac_report *)skb->data;
5670	struct rtw89_completion_data data = {};
5671
5672	aoac_rpt->rpt_ver = c2h->rpt_ver;
5673	aoac_rpt->sec_type = c2h->sec_type;
5674	aoac_rpt->key_idx = c2h->key_idx;
5675	aoac_rpt->pattern_idx = c2h->pattern_idx;
5676	aoac_rpt->rekey_ok = u8_get_bits(c2h->rekey_ok,
5677					 RTW89_C2H_WOW_AOAC_RPT_REKEY_IDX);
5678	memcpy(aoac_rpt->ptk_tx_iv, c2h->ptk_tx_iv, sizeof(aoac_rpt->ptk_tx_iv));
5679	memcpy(aoac_rpt->eapol_key_replay_count, c2h->eapol_key_replay_count,
5680	       sizeof(aoac_rpt->eapol_key_replay_count));
5681	memcpy(aoac_rpt->gtk, c2h->gtk, sizeof(aoac_rpt->gtk));
5682	memcpy(aoac_rpt->ptk_rx_iv, c2h->ptk_rx_iv, sizeof(aoac_rpt->ptk_rx_iv));
5683	memcpy(aoac_rpt->gtk_rx_iv, c2h->gtk_rx_iv, sizeof(aoac_rpt->gtk_rx_iv));
5684	aoac_rpt->igtk_key_id = le64_to_cpu(c2h->igtk_key_id);
5685	aoac_rpt->igtk_ipn = le64_to_cpu(c2h->igtk_ipn);
5686	memcpy(aoac_rpt->igtk, c2h->igtk, sizeof(aoac_rpt->igtk));
5687
5688	rtw89_complete_cond(wait, RTW89_WOW_WAIT_COND_AOAC, &data);
5689}
5690
5691static void
5692rtw89_mac_c2h_mlo_link_cfg_stat(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5693{
5694	const struct rtw89_c2h_mlo_link_cfg_rpt *c2h_rpt;
5695	struct rtw89_wait_info *wait = &rtwdev->mlo.wait;
5696	struct rtw89_completion_data data = {};
5697	unsigned int cond;
5698	u16 mac_id;
5699	u8 status;
5700
5701	c2h_rpt = (const struct rtw89_c2h_mlo_link_cfg_rpt *)c2h->data;
5702
5703	mac_id = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MLO_LINK_CFG_RPT_W2_MACID);
5704	status = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MLO_LINK_CFG_RPT_W2_STATUS);
5705
5706	data.err = status == RTW89_C2H_MLO_LINK_CFG_ROLE_NOT_EXIST ||
5707		   status == RTW89_C2H_MLO_LINK_CFG_RUNNING;
5708	cond = RTW89_MLO_WAIT_COND(mac_id, H2C_FUNC_MLO_LINK_CFG);
5709	rtw89_complete_cond(wait, cond, &data);
5710}
5711
5712static void
5713rtw89_mac_c2h_mrc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
5714{
5715	struct rtw89_wait_info *wait = &rtwdev->mcc.wait;
5716	const struct rtw89_c2h_mrc_status_rpt *c2h_rpt;
5717	struct rtw89_completion_data data = {};
5718	enum rtw89_mac_mrc_status status;
5719	unsigned int cond;
5720	bool next = false;
5721	u32 tsf_high;
5722	u32 tsf_low;
5723	u8 sch_idx;
5724	u8 func;
5725
5726	c2h_rpt = (const struct rtw89_c2h_mrc_status_rpt *)c2h->data;
5727	sch_idx = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MRC_STATUS_RPT_W2_SCH_IDX);
5728	status = le32_get_bits(c2h_rpt->w2, RTW89_C2H_MRC_STATUS_RPT_W2_STATUS);
5729	tsf_high = le32_to_cpu(c2h_rpt->tsf_high);
5730	tsf_low = le32_to_cpu(c2h_rpt->tsf_low);
5731
5732	switch (status) {
5733	case RTW89_MAC_MRC_START_SCH_OK:
5734		func = H2C_FUNC_START_MRC;
5735		break;
5736	case RTW89_MAC_MRC_STOP_SCH_OK:
5737		/* H2C_FUNC_DEL_MRC without STOP_ONLY, so wait for DEL_SCH_OK */
5738		func = H2C_FUNC_DEL_MRC;
5739		next = true;
5740		break;
5741	case RTW89_MAC_MRC_DEL_SCH_OK:
5742		func = H2C_FUNC_DEL_MRC;
5743		break;
5744	case RTW89_MAC_MRC_EMPTY_SCH_FAIL:
5745		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5746			    "MRC C2H STS RPT: empty sch fail\n");
5747		return;
5748	case RTW89_MAC_MRC_ROLE_NOT_EXIST_FAIL:
5749		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5750			    "MRC C2H STS RPT: role not exist fail\n");
5751		return;
5752	case RTW89_MAC_MRC_DATA_NOT_FOUND_FAIL:
5753		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5754			    "MRC C2H STS RPT: data not found fail\n");
5755		return;
5756	case RTW89_MAC_MRC_GET_NEXT_SLOT_FAIL:
5757		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5758			    "MRC C2H STS RPT: get next slot fail\n");
5759		return;
5760	case RTW89_MAC_MRC_ALT_ROLE_FAIL:
5761		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5762			    "MRC C2H STS RPT: alt role fail\n");
5763		return;
5764	case RTW89_MAC_MRC_ADD_PSTIMER_FAIL:
5765		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5766			    "MRC C2H STS RPT: add ps timer fail\n");
5767		return;
5768	case RTW89_MAC_MRC_MALLOC_FAIL:
5769		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5770			    "MRC C2H STS RPT: malloc fail\n");
5771		return;
5772	case RTW89_MAC_MRC_SWITCH_CH_FAIL:
5773		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5774			    "MRC C2H STS RPT: switch ch fail\n");
5775		return;
5776	case RTW89_MAC_MRC_TXNULL0_FAIL:
5777		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5778			    "MRC C2H STS RPT: tx null-0 fail\n");
5779		return;
5780	case RTW89_MAC_MRC_PORT_FUNC_EN_FAIL:
5781		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5782			    "MRC C2H STS RPT: port func en fail\n");
5783		return;
5784	default:
5785		rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5786			    "invalid MRC C2H STS RPT: status %d\n", status);
5787		return;
5788	}
5789
5790	rtw89_debug(rtwdev, RTW89_DBG_CHAN,
5791		    "MRC C2H STS RPT: sch_idx %d, status %d, tsf %llu\n",
5792		    sch_idx, status, (u64)tsf_high << 32 | tsf_low);
5793
5794	if (next)
5795		return;
5796
5797	cond = RTW89_MRC_WAIT_COND(sch_idx, func);
5798	rtw89_complete_cond(wait, cond, &data);
5799}
5800
5801static void
5802rtw89_mac_c2h_pwr_int_notify(struct rtw89_dev *rtwdev, struct sk_buff *skb, u32 len)
5803{
5804	const struct rtw89_c2h_pwr_int_notify *c2h;
5805	struct rtw89_sta_link *rtwsta_link;
5806	struct ieee80211_sta *sta;
5807	struct rtw89_sta *rtwsta;
5808	u16 macid;
5809	bool ps;
5810
5811	c2h = (const struct rtw89_c2h_pwr_int_notify *)skb->data;
5812	macid = le32_get_bits(c2h->w2, RTW89_C2H_PWR_INT_NOTIFY_W2_MACID);
5813	ps = le32_get_bits(c2h->w2, RTW89_C2H_PWR_INT_NOTIFY_W2_PWR_STATUS);
5814
5815	rcu_read_lock();
5816
5817	rtwsta_link = rtw89_assoc_link_rcu_dereference(rtwdev, macid);
5818	if (unlikely(!rtwsta_link))
5819		goto out;
5820
5821	rtwsta = rtwsta_link->rtwsta;
5822	if (ps)
5823		set_bit(RTW89_REMOTE_STA_IN_PS, rtwsta->flags);
5824	else
5825		clear_bit(RTW89_REMOTE_STA_IN_PS, rtwsta->flags);
5826
5827	sta = rtwsta_to_sta(rtwsta);
5828	ieee80211_sta_ps_transition(sta, ps);
5829
5830out:
5831	rcu_read_unlock();
5832}
5833
5834static
5835void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev,
5836					    struct sk_buff *c2h, u32 len) = {
5837	[RTW89_MAC_C2H_FUNC_EFUSE_DUMP] = NULL,
5838	[RTW89_MAC_C2H_FUNC_READ_RSP] = NULL,
5839	[RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP] = rtw89_mac_c2h_pkt_ofld_rsp,
5840	[RTW89_MAC_C2H_FUNC_BCN_RESEND] = rtw89_mac_c2h_bcn_resend,
5841	[RTW89_MAC_C2H_FUNC_MACID_PAUSE] = rtw89_mac_c2h_macid_pause,
5842	[RTW89_MAC_C2H_FUNC_SCANOFLD_RSP] = rtw89_mac_c2h_scanofld_rsp,
5843	[RTW89_MAC_C2H_FUNC_TX_DUTY_RPT] = rtw89_mac_c2h_tx_duty_rpt,
5844	[RTW89_MAC_C2H_FUNC_TSF32_TOGL_RPT] = rtw89_mac_c2h_tsf32_toggle_rpt,
5845	[RTW89_MAC_C2H_FUNC_BCNFLTR_RPT] = rtw89_mac_c2h_bcn_fltr_rpt,
5846};
5847
5848static
5849void (* const rtw89_mac_c2h_info_handler[])(struct rtw89_dev *rtwdev,
5850					    struct sk_buff *c2h, u32 len) = {
5851	[RTW89_MAC_C2H_FUNC_REC_ACK] = rtw89_mac_c2h_rec_ack,
5852	[RTW89_MAC_C2H_FUNC_DONE_ACK] = rtw89_mac_c2h_done_ack,
5853	[RTW89_MAC_C2H_FUNC_C2H_LOG] = rtw89_mac_c2h_log,
5854	[RTW89_MAC_C2H_FUNC_BCN_CNT] = rtw89_mac_c2h_bcn_cnt,
5855	[RTW89_MAC_C2H_FUNC_BCN_UPD_DONE] = rtw89_mac_c2h_bcn_upd_done,
5856};
5857
5858static
5859void (* const rtw89_mac_c2h_mcc_handler[])(struct rtw89_dev *rtwdev,
5860					   struct sk_buff *c2h, u32 len) = {
5861	[RTW89_MAC_C2H_FUNC_MCC_RCV_ACK] = rtw89_mac_c2h_mcc_rcv_ack,
5862	[RTW89_MAC_C2H_FUNC_MCC_REQ_ACK] = rtw89_mac_c2h_mcc_req_ack,
5863	[RTW89_MAC_C2H_FUNC_MCC_TSF_RPT] = rtw89_mac_c2h_mcc_tsf_rpt,
5864	[RTW89_MAC_C2H_FUNC_MCC_STATUS_RPT] = rtw89_mac_c2h_mcc_status_rpt,
5865};
5866
5867static
5868void (* const rtw89_mac_c2h_misc_handler[])(struct rtw89_dev *rtwdev,
5869					    struct sk_buff *c2h, u32 len) = {
5870	[RTW89_MAC_C2H_FUNC_TX_REPORT] = rtw89_mac_c2h_tx_rpt,
5871};
5872
5873static
5874void (* const rtw89_mac_c2h_mlo_handler[])(struct rtw89_dev *rtwdev,
5875					   struct sk_buff *c2h, u32 len) = {
5876	[RTW89_MAC_C2H_FUNC_MLO_GET_TBL] = NULL,
5877	[RTW89_MAC_C2H_FUNC_MLO_EMLSR_TRANS_DONE] = NULL,
5878	[RTW89_MAC_C2H_FUNC_MLO_EMLSR_STA_CFG_DONE] = NULL,
5879	[RTW89_MAC_C2H_FUNC_MCMLO_RELINK_RPT] = NULL,
5880	[RTW89_MAC_C2H_FUNC_MCMLO_SN_SYNC_RPT] = NULL,
5881	[RTW89_MAC_C2H_FUNC_MLO_LINK_CFG_STAT] = rtw89_mac_c2h_mlo_link_cfg_stat,
5882	[RTW89_MAC_C2H_FUNC_MLO_DM_DBG_DUMP] = NULL,
5883};
5884
5885static
5886void (* const rtw89_mac_c2h_mrc_handler[])(struct rtw89_dev *rtwdev,
5887					   struct sk_buff *c2h, u32 len) = {
5888	[RTW89_MAC_C2H_FUNC_MRC_TSF_RPT] = rtw89_mac_c2h_mrc_tsf_rpt,
5889	[RTW89_MAC_C2H_FUNC_MRC_STATUS_RPT] = rtw89_mac_c2h_mrc_status_rpt,
5890};
5891
5892static
5893void (* const rtw89_mac_c2h_wow_handler[])(struct rtw89_dev *rtwdev,
5894					   struct sk_buff *c2h, u32 len) = {
5895	[RTW89_MAC_C2H_FUNC_AOAC_REPORT] = rtw89_mac_c2h_wow_aoac_rpt,
5896};
5897
5898static
5899void (* const rtw89_mac_c2h_ap_handler[])(struct rtw89_dev *rtwdev,
5900					  struct sk_buff *c2h, u32 len) = {
5901	[RTW89_MAC_C2H_FUNC_PWR_INT_NOTIFY] = rtw89_mac_c2h_pwr_int_notify,
5902};
5903
5904static void rtw89_mac_c2h_scanofld_rsp_atomic(struct rtw89_dev *rtwdev,
5905					      struct sk_buff *skb)
5906{
5907	const struct rtw89_c2h_scanofld *c2h =
5908		(const struct rtw89_c2h_scanofld *)skb->data;
5909	struct rtw89_wait_info *fw_ofld_wait = &rtwdev->mac.fw_ofld_wait;
5910	struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
5911	struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb);
5912	struct rtw89_completion_data data = {};
5913	unsigned int cond;
5914	u8 status, reason;
5915
5916	attr->is_scan_event = 1;
5917	attr->scan_seq = scan_info->seq;
5918
5919	status = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_STATUS);
5920	reason = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_RSN);
5921	data.err = status != RTW89_SCAN_STATUS_SUCCESS;
5922
5923	if (reason == RTW89_SCAN_END_SCAN_NOTIFY) {
5924		if (rtwdev->chip->chip_gen == RTW89_CHIP_BE)
5925			cond = RTW89_SCANOFLD_BE_WAIT_COND_STOP;
5926		else
5927			cond = RTW89_SCANOFLD_WAIT_COND_STOP;
5928
5929		rtw89_complete_cond(fw_ofld_wait, cond, &data);
5930	}
5931}
5932
5933bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
5934			      u8 class, u8 func)
5935{
5936	switch (class) {
5937	default:
5938		return false;
5939	case RTW89_MAC_C2H_CLASS_INFO:
5940		switch (func) {
5941		default:
5942			return false;
5943		case RTW89_MAC_C2H_FUNC_REC_ACK:
5944		case RTW89_MAC_C2H_FUNC_DONE_ACK:
5945			return true;
5946		}
5947	case RTW89_MAC_C2H_CLASS_OFLD:
5948		switch (func) {
5949		default:
5950			return false;
5951		case RTW89_MAC_C2H_FUNC_SCANOFLD_RSP:
5952			rtw89_mac_c2h_scanofld_rsp_atomic(rtwdev, c2h);
5953			return false;
5954		case RTW89_MAC_C2H_FUNC_PKT_OFLD_RSP:
5955			return true;
5956		}
5957	case RTW89_MAC_C2H_CLASS_MCC:
5958		return true;
5959	case RTW89_MAC_C2H_CLASS_MISC:
5960		return true;
5961	case RTW89_MAC_C2H_CLASS_MLO:
5962		return true;
5963	case RTW89_MAC_C2H_CLASS_MRC:
5964		return true;
5965	case RTW89_MAC_C2H_CLASS_WOW:
5966		return true;
5967	case RTW89_MAC_C2H_CLASS_AP:
5968		switch (func) {
5969		default:
5970			return false;
5971		case RTW89_MAC_C2H_FUNC_PWR_INT_NOTIFY:
5972			return true;
5973		}
5974	}
5975}
5976
5977void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
5978			  u32 len, u8 class, u8 func)
5979{
5980	void (*handler)(struct rtw89_dev *rtwdev,
5981			struct sk_buff *c2h, u32 len) = NULL;
5982
5983	switch (class) {
5984	case RTW89_MAC_C2H_CLASS_INFO:
5985		if (func < RTW89_MAC_C2H_FUNC_INFO_MAX)
5986			handler = rtw89_mac_c2h_info_handler[func];
5987		break;
5988	case RTW89_MAC_C2H_CLASS_OFLD:
5989		if (func < RTW89_MAC_C2H_FUNC_OFLD_MAX)
5990			handler = rtw89_mac_c2h_ofld_handler[func];
5991		break;
5992	case RTW89_MAC_C2H_CLASS_MCC:
5993		if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MCC)
5994			handler = rtw89_mac_c2h_mcc_handler[func];
5995		break;
5996	case RTW89_MAC_C2H_CLASS_MISC:
5997		if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MISC)
5998			handler = rtw89_mac_c2h_misc_handler[func];
5999		break;
6000	case RTW89_MAC_C2H_CLASS_MLO:
6001		if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MLO)
6002			handler = rtw89_mac_c2h_mlo_handler[func];
6003		break;
6004	case RTW89_MAC_C2H_CLASS_MRC:
6005		if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MRC)
6006			handler = rtw89_mac_c2h_mrc_handler[func];
6007		break;
6008	case RTW89_MAC_C2H_CLASS_WOW:
6009		if (func < NUM_OF_RTW89_MAC_C2H_FUNC_WOW)
6010			handler = rtw89_mac_c2h_wow_handler[func];
6011		break;
6012	case RTW89_MAC_C2H_CLASS_AP:
6013		if (func < NUM_OF_RTW89_MAC_C2H_FUNC_AP)
6014			handler = rtw89_mac_c2h_ap_handler[func];
6015		break;
6016	case RTW89_MAC_C2H_CLASS_FWDBG:
6017	case RTW89_MAC_C2H_CLASS_ROLE:
6018		return;
6019	default:
6020		break;
6021	}
6022	if (!handler) {
6023		rtw89_info_once(rtwdev, "MAC c2h class %d func %d not support\n",
6024				class, func);
6025		return;
6026	}
6027	handler(rtwdev, skb, len);
6028}
6029
6030static
6031bool rtw89_mac_get_txpwr_cr_ax(struct rtw89_dev *rtwdev,
6032			       enum rtw89_phy_idx phy_idx,
6033			       u32 reg_base, u32 *cr)
6034{
6035	enum rtw89_qta_mode mode = rtwdev->mac.qta_mode;
6036	u32 addr = rtw89_mac_reg_by_idx(rtwdev, reg_base, phy_idx);
6037
6038	if (addr < R_AX_PWR_RATE_CTRL || addr > CMAC1_END_ADDR_AX) {
6039		rtw89_err(rtwdev, "[TXPWR] addr=0x%x exceed txpwr cr\n",
6040			  addr);
6041		goto error;
6042	}
6043
6044	if (addr >= CMAC1_START_ADDR_AX && addr <= CMAC1_END_ADDR_AX)
6045		if (mode == RTW89_QTA_SCC) {
6046			rtw89_err(rtwdev,
6047				  "[TXPWR] addr=0x%x but hw not enable\n",
6048				  addr);
6049			goto error;
6050		}
6051
6052	*cr = addr;
6053	return true;
6054
6055error:
6056	rtw89_err(rtwdev, "[TXPWR] check txpwr cr 0x%x(phy%d) fail\n",
6057		  addr, phy_idx);
6058
6059	return false;
6060}
6061
6062static
6063int rtw89_mac_cfg_ppdu_status_ax(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
6064{
6065	u32 reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PPDU_STAT, mac_idx);
6066	int ret;
6067
6068	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
6069	if (ret)
6070		return ret;
6071
6072	if (!enable) {
6073		rtw89_write32_clr(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN);
6074		return 0;
6075	}
6076
6077	rtw89_write32(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN |
6078				   B_AX_APP_MAC_INFO_RPT |
6079				   B_AX_APP_PLCP_HDR_RPT |
6080				   B_AX_PPDU_STAT_RPT_CRC32);
6081	rtw89_write32_mask(rtwdev, R_AX_HW_RPT_FWD, B_AX_FWD_PPDU_STAT_MASK,
6082			   RTW89_PRPT_DEST_HOST);
6083
6084	return 0;
6085}
6086
6087static
6088void __rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx)
6089{
6090#define MAC_AX_TIME_TH_SH  5
6091#define MAC_AX_LEN_TH_SH   4
6092#define MAC_AX_TIME_TH_MAX 255
6093#define MAC_AX_LEN_TH_MAX  255
6094#define MAC_AX_TIME_TH_DEF 88
6095#define MAC_AX_LEN_TH_DEF  4080
6096	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
6097	struct ieee80211_hw *hw = rtwdev->hw;
6098	u32 rts_threshold = hw->wiphy->rts_threshold;
6099	u32 time_th, len_th;
6100	u32 reg;
6101
6102	if (rts_threshold == (u32)-1) {
6103		time_th = MAC_AX_TIME_TH_DEF;
6104		len_th = MAC_AX_LEN_TH_DEF;
6105	} else {
6106		time_th = MAC_AX_TIME_TH_MAX << MAC_AX_TIME_TH_SH;
6107		len_th = rts_threshold;
6108	}
6109
6110	time_th = min_t(u32, time_th >> MAC_AX_TIME_TH_SH, MAC_AX_TIME_TH_MAX);
6111	len_th = min_t(u32, len_th >> MAC_AX_LEN_TH_SH, MAC_AX_LEN_TH_MAX);
6112
6113	reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_len_ht, mac_idx);
6114	rtw89_write16_mask(rtwdev, reg, B_AX_RTS_TXTIME_TH_MASK, time_th);
6115	rtw89_write16_mask(rtwdev, reg, B_AX_RTS_LEN_TH_MASK, len_th);
6116}
6117
6118void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev)
6119{
6120	__rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
6121	if (rtwdev->dbcc_en)
6122		__rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_1);
6123}
6124
6125void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop)
6126{
6127	bool empty;
6128	int ret;
6129
6130	if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
6131		return;
6132
6133	ret = read_poll_timeout(dle_is_txq_empty, empty, empty,
6134				10000, 200000, false, rtwdev);
6135	if (ret && !drop && (rtwdev->total_sta_assoc || rtwdev->scanning))
6136		rtw89_info(rtwdev, "timed out to flush queues\n");
6137}
6138
6139int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex)
6140{
6141	enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
6142	u8 val;
6143	u16 val16;
6144	u32 val32;
6145	int ret;
6146
6147	rtw89_write8_set(rtwdev, R_AX_GPIO_MUXCFG, B_AX_ENBT);
6148	if (chip_id != RTL8851B && chip_id != RTL8852BT)
6149		rtw89_write8_set(rtwdev, R_AX_BTC_FUNC_EN, B_AX_PTA_WL_TX_EN);
6150	rtw89_write8_set(rtwdev, R_AX_BT_COEX_CFG_2 + 1, B_AX_GNT_BT_POLARITY >> 8);
6151	rtw89_write8_set(rtwdev, R_AX_CSR_MODE, B_AX_STATIS_BT_EN | B_AX_WL_ACT_MSK);
6152	rtw89_write8_set(rtwdev, R_AX_CSR_MODE + 2, B_AX_BT_CNT_RST >> 16);
6153	if (chip_id != RTL8851B && chip_id != RTL8852BT)
6154		rtw89_write8_clr(rtwdev, R_AX_TRXPTCL_RESP_0 + 3, B_AX_RSP_CHK_BTCCA >> 24);
6155
6156	val16 = rtw89_read16(rtwdev, R_AX_CCA_CFG_0);
6157	val16 = (val16 | B_AX_BTCCA_EN) & ~B_AX_BTCCA_BRK_TXOP_EN;
6158	rtw89_write16(rtwdev, R_AX_CCA_CFG_0, val16);
6159
6160	ret = rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_2, &val32);
6161	if (ret) {
6162		if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
6163			rtw89_err(rtwdev, "Read R_AX_LTE_SW_CFG_2 fail!\n");
6164		return ret;
6165	}
6166	val32 = val32 & B_AX_WL_RX_CTRL;
6167	ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_2, val32);
6168	if (ret) {
6169		if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
6170			rtw89_err(rtwdev, "Write R_AX_LTE_SW_CFG_2 fail!\n");
6171		return ret;
6172	}
6173
6174	switch (coex->pta_mode) {
6175	case RTW89_MAC_AX_COEX_RTK_MODE:
6176		val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG);
6177		val &= ~B_AX_BTMODE_MASK;
6178		val |= FIELD_PREP(B_AX_BTMODE_MASK, MAC_AX_BT_MODE_0_3);
6179		rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG, val);
6180
6181		val = rtw89_read8(rtwdev, R_AX_TDMA_MODE);
6182		rtw89_write8(rtwdev, R_AX_TDMA_MODE, val | B_AX_RTK_BT_ENABLE);
6183
6184		val = rtw89_read8(rtwdev, R_AX_BT_COEX_CFG_5);
6185		val &= ~B_AX_BT_RPT_SAMPLE_RATE_MASK;
6186		val |= FIELD_PREP(B_AX_BT_RPT_SAMPLE_RATE_MASK, MAC_AX_RTK_RATE);
6187		rtw89_write8(rtwdev, R_AX_BT_COEX_CFG_5, val);
6188		break;
6189	case RTW89_MAC_AX_COEX_CSR_MODE:
6190		val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG);
6191		val &= ~B_AX_BTMODE_MASK;
6192		val |= FIELD_PREP(B_AX_BTMODE_MASK, MAC_AX_BT_MODE_2);
6193		rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG, val);
6194
6195		val16 = rtw89_read16(rtwdev, R_AX_CSR_MODE);
6196		val16 &= ~B_AX_BT_PRI_DETECT_TO_MASK;
6197		val16 |= FIELD_PREP(B_AX_BT_PRI_DETECT_TO_MASK, MAC_AX_CSR_PRI_TO);
6198		val16 &= ~B_AX_BT_TRX_INIT_DETECT_MASK;
6199		val16 |= FIELD_PREP(B_AX_BT_TRX_INIT_DETECT_MASK, MAC_AX_CSR_TRX_TO);
6200		val16 &= ~B_AX_BT_STAT_DELAY_MASK;
6201		val16 |= FIELD_PREP(B_AX_BT_STAT_DELAY_MASK, MAC_AX_CSR_DELAY);
6202		val16 |= B_AX_ENHANCED_BT;
6203		rtw89_write16(rtwdev, R_AX_CSR_MODE, val16);
6204
6205		rtw89_write8(rtwdev, R_AX_BT_COEX_CFG_2, MAC_AX_CSR_RATE);
6206		break;
6207	default:
6208		return -EINVAL;
6209	}
6210
6211	switch (coex->direction) {
6212	case RTW89_MAC_AX_COEX_INNER:
6213		val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1);
6214		val = (val & ~BIT(2)) | BIT(1);
6215		rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val);
6216		break;
6217	case RTW89_MAC_AX_COEX_OUTPUT:
6218		val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1);
6219		val = val | BIT(1) | BIT(0);
6220		rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val);
6221		break;
6222	case RTW89_MAC_AX_COEX_INPUT:
6223		val = rtw89_read8(rtwdev, R_AX_GPIO_MUXCFG + 1);
6224		val = val & ~(BIT(2) | BIT(1));
6225		rtw89_write8(rtwdev, R_AX_GPIO_MUXCFG + 1, val);
6226		break;
6227	default:
6228		return -EINVAL;
6229	}
6230
6231	return 0;
6232}
6233EXPORT_SYMBOL(rtw89_mac_coex_init);
6234
6235int rtw89_mac_coex_init_v1(struct rtw89_dev *rtwdev,
6236			   const struct rtw89_mac_ax_coex *coex)
6237{
6238	rtw89_write32_set(rtwdev, R_AX_BTC_CFG,
6239			  B_AX_BTC_EN | B_AX_BTG_LNA1_GAIN_SEL);
6240	rtw89_write32_set(rtwdev, R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN);
6241	rtw89_write16_set(rtwdev, R_AX_CCA_CFG_0, B_AX_BTCCA_EN);
6242	rtw89_write16_clr(rtwdev, R_AX_CCA_CFG_0, B_AX_BTCCA_BRK_TXOP_EN);
6243
6244	switch (coex->pta_mode) {
6245	case RTW89_MAC_AX_COEX_RTK_MODE:
6246		rtw89_write32_mask(rtwdev, R_AX_BTC_CFG, B_AX_BTC_MODE_MASK,
6247				   MAC_AX_RTK_MODE);
6248		rtw89_write32_mask(rtwdev, R_AX_RTK_MODE_CFG_V1,
6249				   B_AX_SAMPLE_CLK_MASK, MAC_AX_RTK_RATE);
6250		break;
6251	case RTW89_MAC_AX_COEX_CSR_MODE:
6252		rtw89_write32_mask(rtwdev, R_AX_BTC_CFG, B_AX_BTC_MODE_MASK,
6253				   MAC_AX_CSR_MODE);
6254		break;
6255	default:
6256		return -EINVAL;
6257	}
6258
6259	return 0;
6260}
6261EXPORT_SYMBOL(rtw89_mac_coex_init_v1);
6262
6263int rtw89_mac_cfg_gnt(struct rtw89_dev *rtwdev,
6264		      const struct rtw89_mac_ax_coex_gnt *gnt_cfg)
6265{
6266	u32 val = 0, ret;
6267
6268	if (gnt_cfg->band[0].gnt_bt)
6269		val |= B_AX_GNT_BT_RFC_S0_SW_VAL | B_AX_GNT_BT_BB_S0_SW_VAL;
6270
6271	if (gnt_cfg->band[0].gnt_bt_sw_en)
6272		val |= B_AX_GNT_BT_RFC_S0_SW_CTRL | B_AX_GNT_BT_BB_S0_SW_CTRL;
6273
6274	if (gnt_cfg->band[0].gnt_wl)
6275		val |= B_AX_GNT_WL_RFC_S0_SW_VAL | B_AX_GNT_WL_BB_S0_SW_VAL;
6276
6277	if (gnt_cfg->band[0].gnt_wl_sw_en)
6278		val |= B_AX_GNT_WL_RFC_S0_SW_CTRL | B_AX_GNT_WL_BB_S0_SW_CTRL;
6279
6280	if (gnt_cfg->band[1].gnt_bt)
6281		val |= B_AX_GNT_BT_RFC_S1_SW_VAL | B_AX_GNT_BT_BB_S1_SW_VAL;
6282
6283	if (gnt_cfg->band[1].gnt_bt_sw_en)
6284		val |= B_AX_GNT_BT_RFC_S1_SW_CTRL | B_AX_GNT_BT_BB_S1_SW_CTRL;
6285
6286	if (gnt_cfg->band[1].gnt_wl)
6287		val |= B_AX_GNT_WL_RFC_S1_SW_VAL | B_AX_GNT_WL_BB_S1_SW_VAL;
6288
6289	if (gnt_cfg->band[1].gnt_wl_sw_en)
6290		val |= B_AX_GNT_WL_RFC_S1_SW_CTRL | B_AX_GNT_WL_BB_S1_SW_CTRL;
6291
6292	ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_1, val);
6293	if (ret) {
6294		if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
6295			rtw89_err(rtwdev, "Write LTE fail!\n");
6296		return ret;
6297	}
6298
6299	return 0;
6300}
6301EXPORT_SYMBOL(rtw89_mac_cfg_gnt);
6302
6303int rtw89_mac_cfg_gnt_v1(struct rtw89_dev *rtwdev,
6304			 const struct rtw89_mac_ax_coex_gnt *gnt_cfg)
6305{
6306	u32 val = 0;
6307
6308	if (gnt_cfg->band[0].gnt_bt)
6309		val |= B_AX_GNT_BT_RFC_S0_VAL | B_AX_GNT_BT_RX_VAL |
6310		       B_AX_GNT_BT_TX_VAL;
6311	else
6312		val |= B_AX_WL_ACT_VAL;
6313
6314	if (gnt_cfg->band[0].gnt_bt_sw_en)
6315		val |= B_AX_GNT_BT_RFC_S0_SWCTRL | B_AX_GNT_BT_RX_SWCTRL |
6316		       B_AX_GNT_BT_TX_SWCTRL | B_AX_WL_ACT_SWCTRL;
6317
6318	if (gnt_cfg->band[0].gnt_wl)
6319		val |= B_AX_GNT_WL_RFC_S0_VAL | B_AX_GNT_WL_RX_VAL |
6320		       B_AX_GNT_WL_TX_VAL | B_AX_GNT_WL_BB_VAL;
6321
6322	if (gnt_cfg->band[0].gnt_wl_sw_en)
6323		val |= B_AX_GNT_WL_RFC_S0_SWCTRL | B_AX_GNT_WL_RX_SWCTRL |
6324		       B_AX_GNT_WL_TX_SWCTRL | B_AX_GNT_WL_BB_SWCTRL;
6325
6326	if (gnt_cfg->band[1].gnt_bt)
6327		val |= B_AX_GNT_BT_RFC_S1_VAL | B_AX_GNT_BT_RX_VAL |
6328		       B_AX_GNT_BT_TX_VAL;
6329	else
6330		val |= B_AX_WL_ACT_VAL;
6331
6332	if (gnt_cfg->band[1].gnt_bt_sw_en)
6333		val |= B_AX_GNT_BT_RFC_S1_SWCTRL | B_AX_GNT_BT_RX_SWCTRL |
6334		       B_AX_GNT_BT_TX_SWCTRL | B_AX_WL_ACT_SWCTRL;
6335
6336	if (gnt_cfg->band[1].gnt_wl)
6337		val |= B_AX_GNT_WL_RFC_S1_VAL | B_AX_GNT_WL_RX_VAL |
6338		       B_AX_GNT_WL_TX_VAL | B_AX_GNT_WL_BB_VAL;
6339
6340	if (gnt_cfg->band[1].gnt_wl_sw_en)
6341		val |= B_AX_GNT_WL_RFC_S1_SWCTRL | B_AX_GNT_WL_RX_SWCTRL |
6342		       B_AX_GNT_WL_TX_SWCTRL | B_AX_GNT_WL_BB_SWCTRL;
6343
6344	rtw89_write32(rtwdev, R_AX_GNT_SW_CTRL, val);
6345
6346	return 0;
6347}
6348EXPORT_SYMBOL(rtw89_mac_cfg_gnt_v1);
6349
6350static
6351int rtw89_mac_cfg_plt_ax(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_plt *plt)
6352{
6353	u32 reg;
6354	u16 val;
6355	int ret;
6356
6357	ret = rtw89_mac_check_mac_en(rtwdev, plt->band, RTW89_CMAC_SEL);
6358	if (ret)
6359		return ret;
6360
6361	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BT_PLT, plt->band);
6362	val = (plt->tx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_TX_PLT_GNT_LTE_RX : 0) |
6363	      (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_TX_PLT_GNT_BT_TX : 0) |
6364	      (plt->tx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_TX_PLT_GNT_BT_RX : 0) |
6365	      (plt->tx & RTW89_MAC_AX_PLT_GNT_WL ? B_AX_TX_PLT_GNT_WL : 0) |
6366	      (plt->rx & RTW89_MAC_AX_PLT_LTE_RX ? B_AX_RX_PLT_GNT_LTE_RX : 0) |
6367	      (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_TX ? B_AX_RX_PLT_GNT_BT_TX : 0) |
6368	      (plt->rx & RTW89_MAC_AX_PLT_GNT_BT_RX ? B_AX_RX_PLT_GNT_BT_RX : 0) |
6369	      (plt->rx & RTW89_MAC_AX_PLT_GNT_WL ? B_AX_RX_PLT_GNT_WL : 0) |
6370	      B_AX_PLT_EN;
6371	rtw89_write16(rtwdev, reg, val);
6372
6373	return 0;
6374}
6375
6376void rtw89_mac_cfg_sb(struct rtw89_dev *rtwdev, u32 val)
6377{
6378	u32 fw_sb;
6379
6380	fw_sb = rtw89_read32(rtwdev, R_AX_SCOREBOARD);
6381	fw_sb = FIELD_GET(B_MAC_AX_SB_FW_MASK, fw_sb);
6382	fw_sb = fw_sb & ~B_MAC_AX_BTGS1_NOTIFY;
6383	if (!test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
6384		fw_sb = fw_sb | MAC_AX_NOTIFY_PWR_MAJOR;
6385	else
6386		fw_sb = fw_sb | MAC_AX_NOTIFY_TP_MAJOR;
6387	val = FIELD_GET(B_MAC_AX_SB_DRV_MASK, val);
6388	val = B_AX_TOGGLE |
6389	      FIELD_PREP(B_MAC_AX_SB_DRV_MASK, val) |
6390	      FIELD_PREP(B_MAC_AX_SB_FW_MASK, fw_sb);
6391	rtw89_write32(rtwdev, R_AX_SCOREBOARD, val);
6392	fsleep(1000); /* avoid BT FW loss information */
6393}
6394
6395u32 rtw89_mac_get_sb(struct rtw89_dev *rtwdev)
6396{
6397	return rtw89_read32(rtwdev, R_AX_SCOREBOARD);
6398}
6399
6400int rtw89_mac_cfg_ctrl_path(struct rtw89_dev *rtwdev, bool wl)
6401{
6402	u8 val = rtw89_read8(rtwdev, R_AX_SYS_SDIO_CTRL + 3);
6403
6404	val = wl ? val | BIT(2) : val & ~BIT(2);
6405	rtw89_write8(rtwdev, R_AX_SYS_SDIO_CTRL + 3, val);
6406
6407	return 0;
6408}
6409EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path);
6410
6411int rtw89_mac_cfg_ctrl_path_v1(struct rtw89_dev *rtwdev, bool wl)
6412{
6413	struct rtw89_btc *btc = &rtwdev->btc;
6414	struct rtw89_btc_dm *dm = &btc->dm;
6415	struct rtw89_mac_ax_gnt *g = dm->gnt.band;
6416	int i;
6417
6418	if (wl)
6419		return 0;
6420
6421	for (i = 0; i < RTW89_PHY_NUM; i++) {
6422		g[i].gnt_bt_sw_en = 1;
6423		g[i].gnt_bt = 1;
6424		g[i].gnt_wl_sw_en = 1;
6425		g[i].gnt_wl = 0;
6426	}
6427
6428	return rtw89_mac_cfg_gnt_v1(rtwdev, &dm->gnt);
6429}
6430EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v1);
6431
6432bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev)
6433{
6434	const struct rtw89_chip_info *chip = rtwdev->chip;
6435	u8 val = 0;
6436
6437	if (chip->chip_id == RTL8852C || chip->chip_id == RTL8922A)
6438		return false;
6439	else if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
6440		val = rtw89_read8_mask(rtwdev, R_AX_SYS_SDIO_CTRL + 3,
6441				       B_AX_LTE_MUX_CTRL_PATH >> 24);
6442
6443	return !!val;
6444}
6445
6446static u16 rtw89_mac_get_plt_cnt_ax(struct rtw89_dev *rtwdev, u8 band)
6447{
6448	u32 reg;
6449	u16 cnt;
6450
6451	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BT_PLT, band);
6452	cnt = rtw89_read32_mask(rtwdev, reg, B_AX_BT_PLT_PKT_CNT_MASK);
6453	rtw89_write16_set(rtwdev, reg, B_AX_BT_PLT_RST);
6454
6455	return cnt;
6456}
6457
6458static void rtw89_mac_bfee_standby_timer(struct rtw89_dev *rtwdev, u8 mac_idx,
6459					 bool keep)
6460{
6461	u32 reg;
6462
6463	if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
6464		return;
6465
6466	rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee standby_timer to %d\n", keep);
6467	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BFMEE_RESP_OPTION, mac_idx);
6468	if (keep) {
6469		set_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags);
6470		rtw89_write32_mask(rtwdev, reg, B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK,
6471				   BFRP_RX_STANDBY_TIMER_KEEP);
6472	} else {
6473		clear_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags);
6474		rtw89_write32_mask(rtwdev, reg, B_AX_BFMEE_BFRP_RX_STANDBY_TIMER_MASK,
6475				   BFRP_RX_STANDBY_TIMER_RELEASE);
6476	}
6477}
6478
6479void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
6480{
6481	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
6482	u32 reg;
6483	u32 mask = mac->bfee_ctrl.mask;
6484
6485	rtw89_debug(rtwdev, RTW89_DBG_BF, "set bfee ndpa_en to %d\n", en);
6486	reg = rtw89_mac_reg_by_idx(rtwdev, mac->bfee_ctrl.addr, mac_idx);
6487	if (en) {
6488		set_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags);
6489		rtw89_write32_set(rtwdev, reg, mask);
6490	} else {
6491		clear_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags);
6492		rtw89_write32_clr(rtwdev, reg, mask);
6493	}
6494}
6495
6496static int rtw89_mac_init_bfee_ax(struct rtw89_dev *rtwdev, u8 mac_idx)
6497{
6498	u32 reg;
6499	u32 val32;
6500	int ret;
6501
6502	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
6503	if (ret)
6504		return ret;
6505
6506	/* AP mode set tx gid to 63 */
6507	/* STA mode set tx gid to 0(default) */
6508	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BFMER_CTRL_0, mac_idx);
6509	rtw89_write32_set(rtwdev, reg, B_AX_BFMER_NDP_BFEN);
6510
6511	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx);
6512	rtw89_write32(rtwdev, reg, CSI_RRSC_BMAP);
6513
6514	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BFMEE_RESP_OPTION, mac_idx);
6515	val32 = FIELD_PREP(B_AX_BFMEE_NDP_RX_STANDBY_TIMER_MASK, NDP_RX_STANDBY_TIMER);
6516	rtw89_write32(rtwdev, reg, val32);
6517	rtw89_mac_bfee_standby_timer(rtwdev, mac_idx, true);
6518	rtw89_mac_bfee_ctrl(rtwdev, mac_idx, true);
6519
6520	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
6521	rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL |
6522				       B_AX_BFMEE_USE_NSTS |
6523				       B_AX_BFMEE_CSI_GID_SEL |
6524				       B_AX_BFMEE_CSI_FORCE_RETE_EN);
6525	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_RATE, mac_idx);
6526	rtw89_write32(rtwdev, reg,
6527		      u32_encode_bits(CSI_INIT_RATE_HT, B_AX_BFMEE_HT_CSI_RATE_MASK) |
6528		      u32_encode_bits(CSI_INIT_RATE_VHT, B_AX_BFMEE_VHT_CSI_RATE_MASK) |
6529		      u32_encode_bits(CSI_INIT_RATE_HE, B_AX_BFMEE_HE_CSI_RATE_MASK));
6530
6531	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_CSIRPT_OPTION, mac_idx);
6532	rtw89_write32_set(rtwdev, reg,
6533			  B_AX_CSIPRT_VHTSU_AID_EN | B_AX_CSIPRT_HESU_AID_EN);
6534
6535	return 0;
6536}
6537
6538static int rtw89_mac_set_csi_para_reg_ax(struct rtw89_dev *rtwdev,
6539					 struct rtw89_vif_link *rtwvif_link,
6540					 struct rtw89_sta_link *rtwsta_link)
6541{
6542	u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1;
6543	struct ieee80211_link_sta *link_sta;
6544	u8 mac_idx = rtwvif_link->mac_idx;
6545	u8 port_sel = rtwvif_link->port;
6546	u8 sound_dim = 3, t;
6547	u8 *phy_cap;
6548	u32 reg;
6549	u16 val;
6550	int ret;
6551
6552	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
6553	if (ret)
6554		return ret;
6555
6556	rcu_read_lock();
6557
6558	link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
6559	phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
6560
6561	if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
6562	    (phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) {
6563		ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD);
6564		stbc_en &= !!(phy_cap[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ);
6565		t = FIELD_GET(IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,
6566			      phy_cap[5]);
6567		sound_dim = min(sound_dim, t);
6568	}
6569	if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
6570	    (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
6571		ldpc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
6572		stbc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
6573		t = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
6574			      link_sta->vht_cap.cap);
6575		sound_dim = min(sound_dim, t);
6576	}
6577	nc = min(nc, sound_dim);
6578	nr = min(nr, sound_dim);
6579
6580	rcu_read_unlock();
6581
6582	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
6583	rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL);
6584
6585	val = FIELD_PREP(B_AX_BFMEE_CSIINFO0_NC_MASK, nc) |
6586	      FIELD_PREP(B_AX_BFMEE_CSIINFO0_NR_MASK, nr) |
6587	      FIELD_PREP(B_AX_BFMEE_CSIINFO0_NG_MASK, ng) |
6588	      FIELD_PREP(B_AX_BFMEE_CSIINFO0_CB_MASK, cb) |
6589	      FIELD_PREP(B_AX_BFMEE_CSIINFO0_CS_MASK, cs) |
6590	      FIELD_PREP(B_AX_BFMEE_CSIINFO0_LDPC_EN, ldpc_en) |
6591	      FIELD_PREP(B_AX_BFMEE_CSIINFO0_STBC_EN, stbc_en);
6592
6593	if (port_sel == 0)
6594		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
6595	else
6596		reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_1, mac_idx);
6597
6598	rtw89_write16(rtwdev, reg, val);
6599
6600	return 0;
6601}
6602
6603static int rtw89_mac_csi_rrsc_ax(struct rtw89_dev *rtwdev,
6604				 struct rtw89_vif_link *rtwvif_link,
6605				 struct rtw89_sta_link *rtwsta_link)
6606{
6607	u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M);
6608	struct ieee80211_link_sta *link_sta;
6609	u8 mac_idx = rtwvif_link->mac_idx;
6610	u32 reg;
6611	int ret;
6612
6613	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
6614	if (ret)
6615		return ret;
6616
6617	rcu_read_lock();
6618
6619	link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
6620
6621	if (link_sta->he_cap.has_he) {
6622		rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) |
6623			 BIT(RTW89_MAC_BF_RRSC_HE_MSC3) |
6624			 BIT(RTW89_MAC_BF_RRSC_HE_MSC5));
6625	}
6626	if (link_sta->vht_cap.vht_supported) {
6627		rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) |
6628			 BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) |
6629			 BIT(RTW89_MAC_BF_RRSC_VHT_MSC5));
6630	}
6631	if (link_sta->ht_cap.ht_supported) {
6632		rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) |
6633			 BIT(RTW89_MAC_BF_RRSC_HT_MSC3) |
6634			 BIT(RTW89_MAC_BF_RRSC_HT_MSC5));
6635	}
6636
6637	rcu_read_unlock();
6638
6639	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
6640	rtw89_write32_set(rtwdev, reg, B_AX_BFMEE_BFPARAM_SEL);
6641	rtw89_write32_clr(rtwdev, reg, B_AX_BFMEE_CSI_FORCE_RETE_EN);
6642	rtw89_write32(rtwdev,
6643		      rtw89_mac_reg_by_idx(rtwdev, R_AX_TRXPTCL_RESP_CSI_RRSC, mac_idx),
6644		      rrsc);
6645
6646	return 0;
6647}
6648
6649static void rtw89_mac_bf_assoc_ax(struct rtw89_dev *rtwdev,
6650				  struct rtw89_vif_link *rtwvif_link,
6651				  struct rtw89_sta_link *rtwsta_link)
6652{
6653	struct ieee80211_link_sta *link_sta;
6654	bool has_beamformer_cap;
6655
6656	rcu_read_lock();
6657
6658	link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
6659	has_beamformer_cap = rtw89_sta_has_beamformer_cap(link_sta);
6660
6661	rcu_read_unlock();
6662
6663	if (has_beamformer_cap) {
6664		rtw89_debug(rtwdev, RTW89_DBG_BF,
6665			    "initialize bfee for new association\n");
6666		rtw89_mac_init_bfee_ax(rtwdev, rtwvif_link->mac_idx);
6667		rtw89_mac_set_csi_para_reg_ax(rtwdev, rtwvif_link, rtwsta_link);
6668		rtw89_mac_csi_rrsc_ax(rtwdev, rtwvif_link, rtwsta_link);
6669	}
6670}
6671
6672void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev,
6673			   struct rtw89_vif_link *rtwvif_link,
6674			   struct rtw89_sta_link *rtwsta_link)
6675{
6676	rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, false);
6677}
6678
6679void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
6680				struct ieee80211_bss_conf *conf)
6681{
6682	struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
6683	struct rtw89_vif_link *rtwvif_link;
6684	u8 mac_idx;
6685	__le32 *p;
6686
6687	rtwvif_link = rtwvif->links[conf->link_id];
6688	if (unlikely(!rtwvif_link)) {
6689		rtw89_err(rtwdev,
6690			  "%s: rtwvif link (link_id %u) is not active\n",
6691			  __func__, conf->link_id);
6692		return;
6693	}
6694
6695	mac_idx = rtwvif_link->mac_idx;
6696
6697	rtw89_debug(rtwdev, RTW89_DBG_BF, "update bf GID table\n");
6698
6699	p = (__le32 *)conf->mu_group.membership;
6700	rtw89_write32(rtwdev,
6701		      rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION_EN0, mac_idx),
6702		      le32_to_cpu(p[0]));
6703	rtw89_write32(rtwdev,
6704		      rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION_EN1, mac_idx),
6705		      le32_to_cpu(p[1]));
6706
6707	p = (__le32 *)conf->mu_group.position;
6708	rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION0, mac_idx),
6709		      le32_to_cpu(p[0]));
6710	rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION1, mac_idx),
6711		      le32_to_cpu(p[1]));
6712	rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION2, mac_idx),
6713		      le32_to_cpu(p[2]));
6714	rtw89_write32(rtwdev, rtw89_mac_reg_by_idx(rtwdev, R_AX_GID_POSITION3, mac_idx),
6715		      le32_to_cpu(p[3]));
6716}
6717
6718struct rtw89_mac_bf_monitor_iter_data {
6719	struct rtw89_dev *rtwdev;
6720	struct rtw89_sta_link *down_rtwsta_link;
6721	int count;
6722};
6723
6724static
6725void rtw89_mac_bf_monitor_calc_iter(void *data, struct ieee80211_sta *sta)
6726{
6727	struct rtw89_mac_bf_monitor_iter_data *iter_data =
6728				(struct rtw89_mac_bf_monitor_iter_data *)data;
6729	struct rtw89_sta_link *down_rtwsta_link = iter_data->down_rtwsta_link;
6730	struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
6731	struct ieee80211_link_sta *link_sta;
6732	struct rtw89_sta_link *rtwsta_link;
6733	bool has_beamformer_cap = false;
6734	int *count = &iter_data->count;
6735	unsigned int link_id;
6736
6737	rcu_read_lock();
6738
6739	rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
6740		if (rtwsta_link == down_rtwsta_link)
6741			continue;
6742
6743		link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
6744		if (rtw89_sta_has_beamformer_cap(link_sta)) {
6745			has_beamformer_cap = true;
6746			break;
6747		}
6748	}
6749
6750	if (has_beamformer_cap)
6751		(*count)++;
6752
6753	rcu_read_unlock();
6754}
6755
6756void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev,
6757			       struct rtw89_sta_link *rtwsta_link,
6758			       bool disconnect)
6759{
6760	struct rtw89_mac_bf_monitor_iter_data data;
6761
6762	data.rtwdev = rtwdev;
6763	data.down_rtwsta_link = disconnect ? rtwsta_link : NULL;
6764	data.count = 0;
6765	ieee80211_iterate_stations_atomic(rtwdev->hw,
6766					  rtw89_mac_bf_monitor_calc_iter,
6767					  &data);
6768
6769	rtw89_debug(rtwdev, RTW89_DBG_BF, "bfee STA count=%d\n", data.count);
6770	if (data.count)
6771		set_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags);
6772	else
6773		clear_bit(RTW89_FLAG_BFEE_MON, rtwdev->flags);
6774}
6775
6776void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
6777{
6778	struct rtw89_traffic_stats *stats = &rtwdev->stats;
6779	struct rtw89_vif_link *rtwvif_link;
6780	bool en = stats->tx_tfc_lv <= stats->rx_tfc_lv;
6781	bool old = test_bit(RTW89_FLAG_BFEE_EN, rtwdev->flags);
6782	struct rtw89_vif *rtwvif;
6783	bool keep_timer = true;
6784	unsigned int link_id;
6785	bool old_keep_timer;
6786
6787	old_keep_timer = test_bit(RTW89_FLAG_BFEE_TIMER_KEEP, rtwdev->flags);
6788
6789	if (stats->tx_tfc_lv <= RTW89_TFC_LOW && stats->rx_tfc_lv <= RTW89_TFC_LOW)
6790		keep_timer = false;
6791
6792	if (keep_timer != old_keep_timer) {
6793		rtw89_for_each_rtwvif(rtwdev, rtwvif)
6794			rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
6795				rtw89_mac_bfee_standby_timer(rtwdev, rtwvif_link->mac_idx,
6796							     keep_timer);
6797	}
6798
6799	if (en == old)
6800		return;
6801
6802	rtw89_for_each_rtwvif(rtwdev, rtwvif)
6803		rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
6804			rtw89_mac_bfee_ctrl(rtwdev, rtwvif_link->mac_idx, en);
6805}
6806
6807static int
6808__rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
6809			u32 tx_time)
6810{
6811#define MAC_AX_DFLT_TX_TIME 5280
6812	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
6813	u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
6814	u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time;
6815	u32 reg;
6816	int ret = 0;
6817
6818	if (rtwsta_link->cctl_tx_time) {
6819		rtwsta_link->ampdu_max_time = (max_tx_time - 512) >> 9;
6820		ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
6821	} else {
6822		ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
6823		if (ret) {
6824			rtw89_warn(rtwdev, "failed to check cmac in set txtime\n");
6825			return ret;
6826		}
6827
6828		reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_limit.addr, mac_idx);
6829		rtw89_write32_mask(rtwdev, reg, mac->agg_limit.mask,
6830				   max_tx_time >> 5);
6831	}
6832
6833	return ret;
6834}
6835
6836int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
6837			  bool resume, u32 tx_time)
6838{
6839	int ret = 0;
6840
6841	if (!resume) {
6842		rtwsta_link->cctl_tx_time = true;
6843		ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta_link, tx_time);
6844	} else {
6845		ret = __rtw89_mac_set_tx_time(rtwdev, rtwsta_link, tx_time);
6846		rtwsta_link->cctl_tx_time = false;
6847	}
6848
6849	return ret;
6850}
6851
6852int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
6853			  u32 *tx_time)
6854{
6855	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
6856	u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
6857	u32 reg;
6858	int ret = 0;
6859
6860	if (rtwsta_link->cctl_tx_time) {
6861		*tx_time = (rtwsta_link->ampdu_max_time + 1) << 9;
6862	} else {
6863		ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
6864		if (ret) {
6865			rtw89_warn(rtwdev, "failed to check cmac in tx_time\n");
6866			return ret;
6867		}
6868
6869		reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_limit.addr, mac_idx);
6870		*tx_time = rtw89_read32_mask(rtwdev, reg, mac->agg_limit.mask) << 5;
6871	}
6872
6873	return ret;
6874}
6875
6876int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
6877				 struct rtw89_sta_link *rtwsta_link,
6878				 bool resume, u8 tx_retry)
6879{
6880	int ret = 0;
6881
6882	rtwsta_link->data_tx_cnt_lmt = tx_retry;
6883
6884	if (!resume) {
6885		rtwsta_link->cctl_tx_retry_limit = true;
6886		ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
6887	} else {
6888		ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
6889		rtwsta_link->cctl_tx_retry_limit = false;
6890	}
6891
6892	return ret;
6893}
6894
6895int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
6896				 struct rtw89_sta_link *rtwsta_link, u8 *tx_retry)
6897{
6898	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
6899	u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
6900	u32 reg;
6901	int ret = 0;
6902
6903	if (rtwsta_link->cctl_tx_retry_limit) {
6904		*tx_retry = rtwsta_link->data_tx_cnt_lmt;
6905	} else {
6906		ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
6907		if (ret) {
6908			rtw89_warn(rtwdev, "failed to check cmac in rty_lmt\n");
6909			return ret;
6910		}
6911
6912		reg = rtw89_mac_reg_by_idx(rtwdev, mac->txcnt_limit.addr, mac_idx);
6913		*tx_retry = rtw89_read32_mask(rtwdev, reg, mac->txcnt_limit.mask);
6914	}
6915
6916	return ret;
6917}
6918
6919int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
6920				 struct rtw89_vif_link *rtwvif_link, bool en)
6921{
6922	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
6923	u8 mac_idx = rtwvif_link->mac_idx;
6924	u16 set = mac->muedca_ctrl.mask;
6925	u32 reg;
6926	int ret;
6927
6928	ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL);
6929	if (ret)
6930		return ret;
6931
6932	reg = rtw89_mac_reg_by_idx(rtwdev, mac->muedca_ctrl.addr, mac_idx);
6933	if (en)
6934		rtw89_write16_set(rtwdev, reg, set);
6935	else
6936		rtw89_write16_clr(rtwdev, reg, set);
6937
6938	return 0;
6939}
6940
6941static
6942int rtw89_mac_write_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 mask)
6943{
6944	u32 val32;
6945	int ret;
6946
6947	val32 = FIELD_PREP(B_AX_WL_XTAL_SI_ADDR_MASK, offset) |
6948		FIELD_PREP(B_AX_WL_XTAL_SI_DATA_MASK, val) |
6949		FIELD_PREP(B_AX_WL_XTAL_SI_BITMASK_MASK, mask) |
6950		FIELD_PREP(B_AX_WL_XTAL_SI_MODE_MASK, XTAL_SI_NORMAL_WRITE) |
6951		FIELD_PREP(B_AX_WL_XTAL_SI_CMD_POLL, 1);
6952	rtw89_write32(rtwdev, R_AX_WLAN_XTAL_SI_CTRL, val32);
6953
6954	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_WL_XTAL_SI_CMD_POLL),
6955				50, 50000, false, rtwdev, R_AX_WLAN_XTAL_SI_CTRL);
6956	if (ret) {
6957		rtw89_warn(rtwdev, "xtal si not ready(W): offset=%x val=%x mask=%x\n",
6958			   offset, val, mask);
6959		return ret;
6960	}
6961
6962	return 0;
6963}
6964
6965static
6966int rtw89_mac_read_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
6967{
6968	u32 val32;
6969	int ret;
6970
6971	val32 = FIELD_PREP(B_AX_WL_XTAL_SI_ADDR_MASK, offset) |
6972		FIELD_PREP(B_AX_WL_XTAL_SI_DATA_MASK, 0x00) |
6973		FIELD_PREP(B_AX_WL_XTAL_SI_BITMASK_MASK, 0x00) |
6974		FIELD_PREP(B_AX_WL_XTAL_SI_MODE_MASK, XTAL_SI_NORMAL_READ) |
6975		FIELD_PREP(B_AX_WL_XTAL_SI_CMD_POLL, 1);
6976	rtw89_write32(rtwdev, R_AX_WLAN_XTAL_SI_CTRL, val32);
6977
6978	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_WL_XTAL_SI_CMD_POLL),
6979				50, 50000, false, rtwdev, R_AX_WLAN_XTAL_SI_CTRL);
6980	if (ret) {
6981		rtw89_warn(rtwdev, "xtal si not ready(R): offset=%x\n", offset);
6982		return ret;
6983	}
6984
6985	*val = rtw89_read8(rtwdev, R_AX_WLAN_XTAL_SI_CTRL + 1);
6986
6987	return 0;
6988}
6989
6990static
6991void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev,
6992			    struct rtw89_vif_link *rtwvif_link,
6993			    struct rtw89_sta_link *rtwsta_link)
6994{
6995	static const enum rtw89_pkt_drop_sel sels[] = {
6996		RTW89_PKT_DROP_SEL_MACID_BE_ONCE,
6997		RTW89_PKT_DROP_SEL_MACID_BK_ONCE,
6998		RTW89_PKT_DROP_SEL_MACID_VI_ONCE,
6999		RTW89_PKT_DROP_SEL_MACID_VO_ONCE,
7000	};
7001	struct rtw89_pkt_drop_params params = {0};
7002	int i;
7003
7004	params.mac_band = rtwvif_link->mac_idx;
7005	params.macid = rtwsta_link->mac_id;
7006	params.port = rtwvif_link->port;
7007	params.mbssid = 0;
7008	params.tf_trs = rtwvif_link->trigger;
7009
7010	for (i = 0; i < ARRAY_SIZE(sels); i++) {
7011		params.sel = sels[i];
7012		rtw89_fw_h2c_pkt_drop(rtwdev, &params);
7013	}
7014}
7015
7016static void rtw89_mac_pkt_drop_vif_iter(void *data, struct ieee80211_sta *sta)
7017{
7018	struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
7019	struct rtw89_vif *rtwvif = rtwsta->rtwvif;
7020	struct rtw89_dev *rtwdev = rtwsta->rtwdev;
7021	struct rtw89_vif_link *rtwvif_link;
7022	struct rtw89_sta_link *rtwsta_link;
7023	struct rtw89_vif *target = data;
7024	unsigned int link_id;
7025
7026	if (rtwvif != target)
7027		return;
7028
7029	rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
7030		rtwvif_link = rtwsta_link->rtwvif_link;
7031		rtw89_mac_pkt_drop_sta(rtwdev, rtwvif_link, rtwsta_link);
7032	}
7033}
7034
7035void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
7036{
7037	ieee80211_iterate_stations_atomic(rtwdev->hw,
7038					  rtw89_mac_pkt_drop_vif_iter,
7039					  rtwvif);
7040}
7041
7042int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
7043					enum rtw89_mac_idx band)
7044{
7045	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
7046	struct rtw89_pkt_drop_params params = {0};
7047	bool empty;
7048	int i, ret = 0, try_cnt = 3;
7049
7050	params.mac_band = band;
7051	params.sel = RTW89_PKT_DROP_SEL_BAND_ONCE;
7052
7053	for (i = 0; i < try_cnt; i++) {
7054		ret = read_poll_timeout(mac->is_txq_empty, empty, empty, 50,
7055					50000, false, rtwdev);
7056		if (ret && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw))
7057			rtw89_fw_h2c_pkt_drop(rtwdev, &params);
7058		else
7059			return 0;
7060	}
7061	return ret;
7062}
7063
7064int rtw89_mac_cpu_io_rx(struct rtw89_dev *rtwdev, bool wow_enable)
7065{
7066	struct rtw89_mac_h2c_info h2c_info = {};
7067	struct rtw89_mac_c2h_info c2h_info = {};
7068	int ret;
7069
7070	if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw))
7071		return 0;
7072
7073	h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL;
7074	h2c_info.content_len = sizeof(h2c_info.u.hdr);
7075	h2c_info.u.hdr.w0 = u32_encode_bits(wow_enable, RTW89_H2CREG_WOW_CPUIO_RX_CTRL_EN);
7076
7077	ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info);
7078	if (ret)
7079		return ret;
7080
7081	if (c2h_info.id != RTW89_FWCMD_C2HREG_FUNC_WOW_CPUIO_RX_ACK)
7082		ret = -EINVAL;
7083
7084	return ret;
7085}
7086
7087static int rtw89_wow_config_mac_ax(struct rtw89_dev *rtwdev, bool enable_wow)
7088{
7089	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
7090	const struct rtw89_chip_info *chip = rtwdev->chip;
7091	int ret;
7092
7093	if (enable_wow) {
7094		ret = rtw89_mac_resize_ple_rx_quota(rtwdev, true);
7095		if (ret) {
7096			rtw89_err(rtwdev, "[ERR]patch rx qta %d\n", ret);
7097			return ret;
7098		}
7099
7100		rtw89_write32_set(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP);
7101		rtw89_mac_cpu_io_rx(rtwdev, enable_wow);
7102		rtw89_write32_clr(rtwdev, mac->rx_fltr, B_AX_SNIFFER_MODE);
7103		rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false);
7104		rtw89_write32(rtwdev, R_AX_ACTION_FWD0, 0);
7105		rtw89_write32(rtwdev, R_AX_ACTION_FWD1, 0);
7106		rtw89_write32(rtwdev, R_AX_TF_FWD, 0);
7107		rtw89_write32(rtwdev, R_AX_HW_RPT_FWD, 0);
7108
7109		if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw))
7110			return 0;
7111
7112		if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
7113			rtw89_write8(rtwdev, R_BE_DBG_WOW_READY, WOWLAN_NOT_READY);
7114		else
7115			rtw89_write32_set(rtwdev, R_AX_DBG_WOW,
7116					  B_AX_DBG_WOW_CPU_IO_RX_EN);
7117	} else {
7118		ret = rtw89_mac_resize_ple_rx_quota(rtwdev, false);
7119		if (ret) {
7120			rtw89_err(rtwdev, "[ERR]patch rx qta %d\n", ret);
7121			return ret;
7122		}
7123
7124		rtw89_mac_cpu_io_rx(rtwdev, enable_wow);
7125		rtw89_write32_clr(rtwdev, R_AX_RX_FUNCTION_STOP, B_AX_HDR_RX_STOP);
7126		rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
7127		rtw89_write32(rtwdev, R_AX_ACTION_FWD0, TRXCFG_MPDU_PROC_ACT_FRWD);
7128		rtw89_write32(rtwdev, R_AX_TF_FWD, TRXCFG_MPDU_PROC_TF_FRWD);
7129	}
7130
7131	return 0;
7132}
7133
7134static u8 rtw89_fw_get_rdy_ax(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type)
7135{
7136	u8 val = rtw89_read8(rtwdev, R_AX_WCPU_FW_CTRL);
7137
7138	return FIELD_GET(B_AX_WCPU_FWDL_STS_MASK, val);
7139}
7140
7141static
7142int rtw89_fwdl_check_path_ready_ax(struct rtw89_dev *rtwdev,
7143				   bool h2c_or_fwdl)
7144{
7145	u8 check = h2c_or_fwdl ? B_AX_H2C_PATH_RDY : B_AX_FWDL_PATH_RDY;
7146	u32 timeout;
7147	u8 val;
7148
7149	if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
7150		timeout = FWDL_WAIT_CNT_USB;
7151	else
7152		timeout = FWDL_WAIT_CNT;
7153
7154	return read_poll_timeout_atomic(rtw89_read8, val, val & check,
7155					1, timeout, false,
7156					rtwdev, R_AX_WCPU_FW_CTRL);
7157}
7158
7159static
7160void rtw89_fwdl_secure_idmem_share_mode_ax(struct rtw89_dev *rtwdev, u8 mode)
7161{
7162	struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
7163
7164	if (!sec->secure_boot)
7165		return;
7166
7167	rtw89_write32_mask(rtwdev, R_AX_WCPU_FW_CTRL,
7168			   B_AX_IDMEM_SHARE_MODE_RECORD_MASK, mode);
7169	rtw89_write32_set(rtwdev, R_AX_WCPU_FW_CTRL,
7170			  B_AX_IDMEM_SHARE_MODE_RECORD_VALID);
7171}
7172
7173const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
7174	.band1_offset = RTW89_MAC_AX_BAND_REG_OFFSET,
7175	.filter_model_addr = R_AX_FILTER_MODEL_ADDR,
7176	.indir_access_addr = R_AX_INDIR_ACCESS_ENTRY,
7177	.mem_base_addrs = rtw89_mac_mem_base_addrs_ax,
7178	.mem_page_size = MAC_MEM_DUMP_PAGE_SIZE_AX,
7179	.rx_fltr = R_AX_RX_FLTR_OPT,
7180	.port_base = &rtw89_port_base_ax,
7181	.agg_len_ht = R_AX_AGG_LEN_HT_0,
7182	.ps_status = R_AX_PPWRBIT_SETTING,
7183
7184	.muedca_ctrl = {
7185		.addr = R_AX_MUEDCA_EN,
7186		.mask = B_AX_MUEDCA_EN_0 | B_AX_SET_MUEDCATIMER_TF_0,
7187	},
7188	.bfee_ctrl = {
7189		.addr = R_AX_BFMEE_RESP_OPTION,
7190		.mask = B_AX_BFMEE_HT_NDPA_EN | B_AX_BFMEE_VHT_NDPA_EN |
7191			B_AX_BFMEE_HE_NDPA_EN,
7192	},
7193	.narrow_bw_ru_dis = {
7194		.addr = R_AX_RXTRIG_TEST_USER_2,
7195		.mask = B_AX_RXTRIG_RU26_DIS,
7196	},
7197	.wow_ctrl = {.addr = R_AX_WOW_CTRL, .mask = B_AX_WOW_WOWEN,},
7198	.agg_limit = {.addr = R_AX_AMPDU_AGG_LIMIT, .mask = B_AX_AMPDU_MAX_TIME_MASK,},
7199	.txcnt_limit = {.addr = R_AX_TXCNT, .mask = B_AX_L_TXCNT_LMT_MASK,},
7200
7201	.check_mac_en = rtw89_mac_check_mac_en_ax,
7202	.sys_init = sys_init_ax,
7203	.trx_init = trx_init_ax,
7204	.err_imr_ctrl = err_imr_ctrl_ax,
7205	.hci_func_en = rtw89_mac_hci_func_en_ax,
7206	.dmac_func_pre_en = rtw89_mac_dmac_func_pre_en_ax,
7207	.dle_func_en = dle_func_en_ax,
7208	.dle_clk_en = dle_clk_en_ax,
7209	.bf_assoc = rtw89_mac_bf_assoc_ax,
7210
7211	.typ_fltr_opt = rtw89_mac_typ_fltr_opt_ax,
7212	.cfg_ppdu_status = rtw89_mac_cfg_ppdu_status_ax,
7213	.cfg_phy_rpt = NULL,
7214
7215	.dle_mix_cfg = dle_mix_cfg_ax,
7216	.chk_dle_rdy = chk_dle_rdy_ax,
7217	.dle_buf_req = dle_buf_req_ax,
7218	.hfc_func_en = hfc_func_en_ax,
7219	.hfc_h2c_cfg = hfc_h2c_cfg_ax,
7220	.hfc_mix_cfg = hfc_mix_cfg_ax,
7221	.hfc_get_mix_info = hfc_get_mix_info_ax,
7222	.wde_quota_cfg = wde_quota_cfg_ax,
7223	.ple_quota_cfg = ple_quota_cfg_ax,
7224	.set_cpuio = set_cpuio_ax,
7225	.dle_quota_change = dle_quota_change_ax,
7226
7227	.disable_cpu = rtw89_mac_disable_cpu_ax,
7228	.fwdl_enable_wcpu = rtw89_mac_enable_cpu_ax,
7229	.fwdl_get_status = rtw89_fw_get_rdy_ax,
7230	.fwdl_check_path_ready = rtw89_fwdl_check_path_ready_ax,
7231	.fwdl_secure_idmem_share_mode = rtw89_fwdl_secure_idmem_share_mode_ax,
7232	.parse_efuse_map = rtw89_parse_efuse_map_ax,
7233	.parse_phycap_map = rtw89_parse_phycap_map_ax,
7234	.cnv_efuse_state = rtw89_cnv_efuse_state_ax,
7235	.efuse_read_fw_secure = rtw89_efuse_read_fw_secure_ax,
7236
7237	.cfg_plt = rtw89_mac_cfg_plt_ax,
7238	.get_plt_cnt = rtw89_mac_get_plt_cnt_ax,
7239
7240	.get_txpwr_cr = rtw89_mac_get_txpwr_cr_ax,
7241
7242	.write_xtal_si = rtw89_mac_write_xtal_si_ax,
7243	.read_xtal_si = rtw89_mac_read_xtal_si_ax,
7244
7245	.dump_qta_lost = rtw89_mac_dump_qta_lost_ax,
7246	.dump_err_status = rtw89_mac_dump_err_status_ax,
7247
7248	.is_txq_empty = mac_is_txq_empty_ax,
7249
7250	.prep_chan_list = rtw89_hw_scan_prep_chan_list_ax,
7251	.free_chan_list = rtw89_hw_scan_free_chan_list_ax,
7252	.add_chan_list = rtw89_hw_scan_add_chan_list_ax,
7253	.add_chan_list_pno = rtw89_pno_scan_add_chan_list_ax,
7254	.scan_offload = rtw89_fw_h2c_scan_offload_ax,
7255
7256	.wow_config_mac = rtw89_wow_config_mac_ax,
7257};
7258EXPORT_SYMBOL(rtw89_mac_gen_ax);
~/ Read-only file preview.