The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/rtw89/mac.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 3d461dbd8c43cdf1aa8b8e8ab263c51f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.