1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* Copyright(c) 2019-2020 Realtek Corporation 3 */ 4 5 #include "debug.h" 6 #include "fw.h" 7 #include "mac.h" 8 #include "reg.h" 9 10 static const u32 rtw89_mac_mem_base_addrs_be[RTW89_MAC_MEM_NUM] = { 11 [RTW89_MAC_MEM_AXIDMA] = AXIDMA_BASE_ADDR_BE, 12 [RTW89_MAC_MEM_SHARED_BUF] = SHARED_BUF_BASE_ADDR_BE, 13 [RTW89_MAC_MEM_DMAC_TBL] = DMAC_TBL_BASE_ADDR_BE, 14 [RTW89_MAC_MEM_SHCUT_MACHDR] = SHCUT_MACHDR_BASE_ADDR_BE, 15 [RTW89_MAC_MEM_STA_SCHED] = STA_SCHED_BASE_ADDR_BE, 16 [RTW89_MAC_MEM_RXPLD_FLTR_CAM] = RXPLD_FLTR_CAM_BASE_ADDR_BE, 17 [RTW89_MAC_MEM_SECURITY_CAM] = SEC_CAM_BASE_ADDR_BE, 18 [RTW89_MAC_MEM_WOW_CAM] = WOW_CAM_BASE_ADDR_BE, 19 [RTW89_MAC_MEM_CMAC_TBL] = CMAC_TBL_BASE_ADDR_BE, 20 [RTW89_MAC_MEM_ADDR_CAM] = ADDR_CAM_BASE_ADDR_BE, 21 [RTW89_MAC_MEM_BA_CAM] = BA_CAM_BASE_ADDR_BE, 22 [RTW89_MAC_MEM_BCN_IE_CAM0] = BCN_IE_CAM0_BASE_ADDR_BE, 23 [RTW89_MAC_MEM_BCN_IE_CAM1] = BCN_IE_CAM1_BASE_ADDR_BE, 24 [RTW89_MAC_MEM_TXD_FIFO_0] = TXD_FIFO_0_BASE_ADDR_BE, 25 [RTW89_MAC_MEM_TXD_FIFO_1] = TXD_FIFO_1_BASE_ADDR_BE, 26 [RTW89_MAC_MEM_TXDATA_FIFO_0] = TXDATA_FIFO_0_BASE_ADDR_BE, 27 [RTW89_MAC_MEM_TXDATA_FIFO_1] = TXDATA_FIFO_1_BASE_ADDR_BE, 28 [RTW89_MAC_MEM_CPU_LOCAL] = CPU_LOCAL_BASE_ADDR_BE, 29 [RTW89_MAC_MEM_BSSID_CAM] = BSSID_CAM_BASE_ADDR_BE, 30 [RTW89_MAC_MEM_WD_PAGE] = WD_PAGE_BASE_ADDR_BE, 31 }; 32 33 static const struct rtw89_port_reg rtw89_port_base_be = { 34 .port_cfg = R_BE_PORT_CFG_P0, 35 .tbtt_prohib = R_BE_TBTT_PROHIB_P0, 36 .bcn_area = R_BE_BCN_AREA_P0, 37 .bcn_early = R_BE_BCNERLYINT_CFG_P0, 38 .tbtt_early = R_BE_TBTTERLYINT_CFG_P0, 39 .tbtt_agg = R_BE_TBTT_AGG_P0, 40 .bcn_space = R_BE_BCN_SPACE_CFG_P0, 41 .bcn_forcetx = R_BE_BCN_FORCETX_P0, 42 .bcn_err_cnt = R_BE_BCN_ERR_CNT_P0, 43 .bcn_err_flag = R_BE_BCN_ERR_FLAG_P0, 44 .dtim_ctrl = R_BE_DTIM_CTRL_P0, 45 .tbtt_shift = R_BE_TBTT_SHIFT_P0, 46 .bcn_cnt_tmr = R_BE_BCN_CNT_TMR_P0, 47 .tsftr_l = R_BE_TSFTR_LOW_P0, 48 .tsftr_h = R_BE_TSFTR_HIGH_P0, 49 .md_tsft = R_BE_WMTX_MOREDATA_TSFT_STMP_CTL, 50 .bss_color = R_BE_PTCL_BSS_COLOR_0, 51 .mbssid = R_BE_MBSSID_CTRL, 52 .mbssid_drop = R_BE_MBSSID_DROP_0, 53 .tsf_sync = R_BE_PORT_0_TSF_SYNC, 54 .hiq_win = {R_BE_P0MB_HGQ_WINDOW_CFG_0, R_BE_PORT_HGQ_WINDOW_CFG, 55 R_BE_PORT_HGQ_WINDOW_CFG + 1, R_BE_PORT_HGQ_WINDOW_CFG + 2, 56 R_BE_PORT_HGQ_WINDOW_CFG + 3}, 57 }; 58 59 static void rtw89_mac_disable_cpu_be(struct rtw89_dev *rtwdev) 60 { 61 u32 val32; 62 63 clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); 64 65 rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN); 66 rtw89_write32_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_HOLD_AFTER_RESET); 67 rtw89_write32_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN); 68 69 val32 = rtw89_read32(rtwdev, R_BE_WCPU_FW_CTRL); 70 val32 &= B_BE_RUN_ENV_MASK; 71 rtw89_write32(rtwdev, R_BE_WCPU_FW_CTRL, val32); 72 73 rtw89_write32_set(rtwdev, R_BE_DCPU_PLATFORM_ENABLE, B_BE_DCPU_PLATFORM_EN); 74 75 rtw89_write32(rtwdev, R_BE_UDM0, 0); 76 rtw89_write32(rtwdev, R_BE_HALT_C2H, 0); 77 rtw89_write32(rtwdev, R_BE_UDM2, 0); 78 } 79 80 static void set_cpu_en(struct rtw89_dev *rtwdev, bool include_bb) 81 { 82 u32 set = B_BE_WLANCPU_FWDL_EN; 83 84 if (include_bb) 85 set |= B_BE_BBMCU0_FWDL_EN; 86 87 rtw89_write32_set(rtwdev, R_BE_WCPU_FW_CTRL, set); 88 } 89 90 static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw) 91 { 92 u32 val32; 93 int ret; 94 95 rtw89_write32_set(rtwdev, R_BE_UDM0, B_BE_UDM0_DBG_MODE_CTRL); 96 97 val32 = rtw89_read32(rtwdev, R_BE_HALT_C2H); 98 if (val32) { 99 rtw89_warn(rtwdev, "[SER] AON L2 Debug register not empty before Boot.\n"); 100 rtw89_warn(rtwdev, "[SER] %s: R_BE_HALT_C2H = 0x%x\n", __func__, val32); 101 } 102 val32 = rtw89_read32(rtwdev, R_BE_UDM1); 103 if (val32) { 104 rtw89_warn(rtwdev, "[SER] AON L2 Debug register not empty before Boot.\n"); 105 rtw89_warn(rtwdev, "[SER] %s: R_BE_UDM1 = 0x%x\n", __func__, val32); 106 } 107 val32 = rtw89_read32(rtwdev, R_BE_UDM2); 108 if (val32) { 109 rtw89_warn(rtwdev, "[SER] AON L2 Debug register not empty before Boot.\n"); 110 rtw89_warn(rtwdev, "[SER] %s: R_BE_UDM2 = 0x%x\n", __func__, val32); 111 } 112 113 rtw89_write32(rtwdev, R_BE_UDM1, 0); 114 rtw89_write32(rtwdev, R_BE_UDM2, 0); 115 rtw89_write32(rtwdev, R_BE_HALT_H2C, 0); 116 rtw89_write32(rtwdev, R_BE_HALT_C2H, 0); 117 rtw89_write32(rtwdev, R_BE_HALT_H2C_CTRL, 0); 118 rtw89_write32(rtwdev, R_BE_HALT_C2H_CTRL, 0); 119 120 rtw89_write32_set(rtwdev, R_BE_SYS_CLK_CTRL, B_BE_CPU_CLK_EN); 121 rtw89_write32_clr(rtwdev, R_BE_SYS_CFG5, 122 B_BE_WDT_WAKE_PCIE_EN | B_BE_WDT_WAKE_USB_EN); 123 rtw89_write32_clr(rtwdev, R_BE_WCPU_FW_CTRL, 124 B_BE_WDT_PLT_RST_EN | B_BE_WCPU_ROM_CUT_GET); 125 126 rtw89_write16_mask(rtwdev, R_BE_BOOT_REASON, B_BE_BOOT_REASON_MASK, boot_reason); 127 rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN); 128 rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_HOLD_AFTER_RESET); 129 rtw89_write32_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN); 130 131 if (!dlfw) { 132 ret = rtw89_fw_check_rdy(rtwdev, RTW89_FWDL_CHECK_FREERTOS_DONE); 133 if (ret) 134 return ret; 135 } 136 137 return 0; 138 } 139 140 static int rtw89_mac_fwdl_enable_wcpu_be(struct rtw89_dev *rtwdev, 141 u8 boot_reason, bool dlfw, 142 bool include_bb) 143 { 144 set_cpu_en(rtwdev, include_bb); 145 146 return wcpu_on(rtwdev, boot_reason, dlfw); 147 } 148 149 static const u8 fwdl_status_map[] = { 150 [0] = RTW89_FWDL_INITIAL_STATE, 151 [1] = RTW89_FWDL_FWDL_ONGOING, 152 [4] = RTW89_FWDL_CHECKSUM_FAIL, 153 [5] = RTW89_FWDL_SECURITY_FAIL, 154 [6] = RTW89_FWDL_SECURITY_FAIL, 155 [7] = RTW89_FWDL_CV_NOT_MATCH, 156 [8] = RTW89_FWDL_RSVD0, 157 [2] = RTW89_FWDL_WCPU_FWDL_RDY, 158 [3] = RTW89_FWDL_WCPU_FW_INIT_RDY, 159 [9] = RTW89_FWDL_RSVD0, 160 }; 161 162 static u8 fwdl_get_status_be(struct rtw89_dev *rtwdev, enum rtw89_fwdl_check_type type) 163 { 164 bool check_pass = false; 165 u32 val32; 166 u8 st; 167 168 val32 = rtw89_read32(rtwdev, R_BE_WCPU_FW_CTRL); 169 170 switch (type) { 171 case RTW89_FWDL_CHECK_WCPU_FWDL_DONE: 172 check_pass = !(val32 & B_BE_WLANCPU_FWDL_EN); 173 break; 174 case RTW89_FWDL_CHECK_DCPU_FWDL_DONE: 175 check_pass = !(val32 & B_BE_DATACPU_FWDL_EN); 176 break; 177 case RTW89_FWDL_CHECK_BB0_FWDL_DONE: 178 check_pass = !(val32 & B_BE_BBMCU0_FWDL_EN); 179 break; 180 case RTW89_FWDL_CHECK_BB1_FWDL_DONE: 181 check_pass = !(val32 & B_BE_BBMCU1_FWDL_EN); 182 break; 183 default: 184 break; 185 } 186 187 if (check_pass) 188 return RTW89_FWDL_WCPU_FW_INIT_RDY; 189 190 st = u32_get_bits(val32, B_BE_WCPU_FWDL_STATUS_MASK); 191 if (st < ARRAY_SIZE(fwdl_status_map)) 192 return fwdl_status_map[st]; 193 194 return st; 195 } 196 197 static int rtw89_fwdl_check_path_ready_be(struct rtw89_dev *rtwdev, 198 bool h2c_or_fwdl) 199 { 200 u32 check = h2c_or_fwdl ? B_BE_H2C_PATH_RDY : B_BE_DLFW_PATH_RDY; 201 u32 val; 202 203 return read_poll_timeout_atomic(rtw89_read32, val, val & check, 204 1, 1000000, false, 205 rtwdev, R_BE_WCPU_FW_CTRL); 206 } 207 208 static bool rtw89_mac_get_txpwr_cr_be(struct rtw89_dev *rtwdev, 209 enum rtw89_phy_idx phy_idx, 210 u32 reg_base, u32 *cr) 211 { 212 const struct rtw89_dle_mem *dle_mem = rtwdev->chip->dle_mem; 213 enum rtw89_qta_mode mode = dle_mem->mode; 214 int ret; 215 216 ret = rtw89_mac_check_mac_en(rtwdev, (enum rtw89_mac_idx)phy_idx, 217 RTW89_CMAC_SEL); 218 if (ret) { 219 if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) 220 return false; 221 222 rtw89_err(rtwdev, "[TXPWR] check mac enable failed\n"); 223 return false; 224 } 225 226 if (reg_base < R_BE_PWR_MODULE || reg_base > R_BE_CMAC_FUNC_EN_C1) { 227 rtw89_err(rtwdev, "[TXPWR] reg_base=0x%x exceed txpwr cr\n", 228 reg_base); 229 return false; 230 } 231 232 *cr = rtw89_mac_reg_by_idx(rtwdev, reg_base, phy_idx); 233 234 if (*cr >= CMAC1_START_ADDR_BE && *cr <= CMAC1_END_ADDR_BE) { 235 if (mode == RTW89_QTA_SCC) { 236 rtw89_err(rtwdev, 237 "[TXPWR] addr=0x%x but hw not enable\n", 238 *cr); 239 return false; 240 } 241 } 242 243 return true; 244 } 245 246 static int rtw89_mac_init_bfee_be(struct rtw89_dev *rtwdev, u8 mac_idx) 247 { 248 u32 reg; 249 u32 val; 250 int ret; 251 252 ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); 253 if (ret) 254 return ret; 255 256 rtw89_mac_bfee_ctrl(rtwdev, mac_idx, true); 257 258 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); 259 rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL | 260 B_BE_BFMEE_USE_NSTS | 261 B_BE_BFMEE_CSI_GID_SEL | 262 B_BE_BFMEE_CSI_FORCE_RETE_EN); 263 rtw89_write32_mask(rtwdev, reg, B_BE_BFMEE_CSI_RSC_MASK, CSI_RX_BW_CFG); 264 265 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CSIRPT_OPTION, mac_idx); 266 rtw89_write32_set(rtwdev, reg, B_BE_CSIPRT_VHTSU_AID_EN | 267 B_BE_CSIPRT_HESU_AID_EN | 268 B_BE_CSIPRT_EHTSU_AID_EN); 269 270 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_RRSC, mac_idx); 271 rtw89_write32(rtwdev, reg, CSI_RRSC_BMAP_BE); 272 273 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_1, mac_idx); 274 rtw89_write32_mask(rtwdev, reg, B_BE_BFMEE_BE_CSI_RRSC_BITMAP_MASK, 275 CSI_RRSC_BITMAP_CFG); 276 277 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_RATE, mac_idx); 278 val = u32_encode_bits(CSI_INIT_RATE_HT, B_BE_BFMEE_HT_CSI_RATE_MASK) | 279 u32_encode_bits(CSI_INIT_RATE_VHT, B_BE_BFMEE_VHT_CSI_RATE_MASK) | 280 u32_encode_bits(CSI_INIT_RATE_HE, B_BE_BFMEE_HE_CSI_RATE_MASK) | 281 u32_encode_bits(CSI_INIT_RATE_EHT, B_BE_BFMEE_EHT_CSI_RATE_MASK); 282 283 rtw89_write32(rtwdev, reg, val); 284 285 return 0; 286 } 287 288 static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev, 289 struct ieee80211_vif *vif, 290 struct ieee80211_sta *sta) 291 { 292 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 293 u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1; 294 u8 mac_idx = rtwvif->mac_idx; 295 u8 port_sel = rtwvif->port; 296 u8 sound_dim = 3, t; 297 u8 *phy_cap; 298 u32 reg; 299 u16 val; 300 int ret; 301 302 ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); 303 if (ret) 304 return ret; 305 306 phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info; 307 308 if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) || 309 (phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) { 310 ldpc_en &= !!(phy_cap[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD); 311 stbc_en &= !!(phy_cap[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ); 312 t = u8_get_bits(phy_cap[5], 313 IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK); 314 sound_dim = min(sound_dim, t); 315 } 316 317 if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) || 318 (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { 319 ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); 320 stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK); 321 t = u32_get_bits(sta->deflink.vht_cap.cap, 322 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK); 323 sound_dim = min(sound_dim, t); 324 } 325 326 nc = min(nc, sound_dim); 327 nr = min(nr, sound_dim); 328 329 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); 330 rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL); 331 332 val = u16_encode_bits(nc, B_BE_BFMEE_CSIINFO0_NC_MASK) | 333 u16_encode_bits(nr, B_BE_BFMEE_CSIINFO0_NR_MASK) | 334 u16_encode_bits(ng, B_BE_BFMEE_CSIINFO0_NG_MASK) | 335 u16_encode_bits(cb, B_BE_BFMEE_CSIINFO0_CB_MASK) | 336 u16_encode_bits(cs, B_BE_BFMEE_CSIINFO0_CS_MASK) | 337 u16_encode_bits(ldpc_en, B_BE_BFMEE_CSIINFO0_LDPC_EN) | 338 u16_encode_bits(stbc_en, B_BE_BFMEE_CSIINFO0_STBC_EN); 339 340 if (port_sel == 0) 341 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, 342 mac_idx); 343 else 344 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_1, 345 mac_idx); 346 347 rtw89_write16(rtwdev, reg, val); 348 349 return 0; 350 } 351 352 static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev, 353 struct ieee80211_vif *vif, 354 struct ieee80211_sta *sta) 355 { 356 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 357 u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M); 358 u8 mac_idx = rtwvif->mac_idx; 359 int ret; 360 u32 reg; 361 362 ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); 363 if (ret) 364 return ret; 365 366 if (sta->deflink.he_cap.has_he) { 367 rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) | 368 BIT(RTW89_MAC_BF_RRSC_HE_MSC3) | 369 BIT(RTW89_MAC_BF_RRSC_HE_MSC5)); 370 } 371 if (sta->deflink.vht_cap.vht_supported) { 372 rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) | 373 BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) | 374 BIT(RTW89_MAC_BF_RRSC_VHT_MSC5)); 375 } 376 if (sta->deflink.ht_cap.ht_supported) { 377 rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) | 378 BIT(RTW89_MAC_BF_RRSC_HT_MSC3) | 379 BIT(RTW89_MAC_BF_RRSC_HT_MSC5)); 380 } 381 382 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx); 383 rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL); 384 rtw89_write32_clr(rtwdev, reg, B_BE_BFMEE_CSI_FORCE_RETE_EN); 385 386 reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_RRSC, mac_idx); 387 rtw89_write32(rtwdev, reg, rrsc); 388 389 return 0; 390 } 391 392 static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev, 393 struct ieee80211_vif *vif, 394 struct ieee80211_sta *sta) 395 { 396 struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; 397 398 if (rtw89_sta_has_beamformer_cap(sta)) { 399 rtw89_debug(rtwdev, RTW89_DBG_BF, 400 "initialize bfee for new association\n"); 401 rtw89_mac_init_bfee_be(rtwdev, rtwvif->mac_idx); 402 rtw89_mac_set_csi_para_reg_be(rtwdev, vif, sta); 403 rtw89_mac_csi_rrsc_be(rtwdev, vif, sta); 404 } 405 } 406 407 const struct rtw89_mac_gen_def rtw89_mac_gen_be = { 408 .band1_offset = RTW89_MAC_BE_BAND_REG_OFFSET, 409 .filter_model_addr = R_BE_FILTER_MODEL_ADDR, 410 .indir_access_addr = R_BE_INDIR_ACCESS_ENTRY, 411 .mem_base_addrs = rtw89_mac_mem_base_addrs_be, 412 .rx_fltr = R_BE_RX_FLTR_OPT, 413 .port_base = &rtw89_port_base_be, 414 .agg_len_ht = R_BE_AGG_LEN_HT_0, 415 416 .muedca_ctrl = { 417 .addr = R_BE_MUEDCA_EN, 418 .mask = B_BE_MUEDCA_EN_0 | B_BE_SET_MUEDCATIMER_TF_0, 419 }, 420 .bfee_ctrl = { 421 .addr = R_BE_BFMEE_RESP_OPTION, 422 .mask = B_BE_BFMEE_HT_NDPA_EN | B_BE_BFMEE_VHT_NDPA_EN | 423 B_BE_BFMEE_HE_NDPA_EN | B_BE_BFMEE_EHT_NDPA_EN, 424 }, 425 426 .bf_assoc = rtw89_mac_bf_assoc_be, 427 428 .disable_cpu = rtw89_mac_disable_cpu_be, 429 .fwdl_enable_wcpu = rtw89_mac_fwdl_enable_wcpu_be, 430 .fwdl_get_status = fwdl_get_status_be, 431 .fwdl_check_path_ready = rtw89_fwdl_check_path_ready_be, 432 433 .get_txpwr_cr = rtw89_mac_get_txpwr_cr_be, 434 }; 435 EXPORT_SYMBOL(rtw89_mac_gen_be); 436