1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* Copyright(c) 2023 Realtek Corporation 3 */ 4 5 #include "debug.h" 6 #include "efuse.h" 7 #include "mac.h" 8 #include "reg.h" 9 10 #define EFUSE_EXTERNALPN_ADDR_BE 0x1580 11 #define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0) 12 #define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4) 13 #define EFUSE_SERIALNUM_ADDR_BE 0x1581 14 #define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0) 15 #define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6) 16 #define EFUSE_SB_CRYP_SEL_ADDR 0x1582 17 #define EFUSE_SB_CRYP_SEL_SIZE 2 18 #define EFUSE_SB_CRYP_SEL_DEFAULT 0xFFFF 19 #define SB_SEL_MGN_MAX_SIZE 2 20 #define EFUSE_SEC_BE_START 0x1580 21 #define EFUSE_SEC_BE_SIZE 4 22 23 enum rtw89_efuse_mss_dev_type { 24 MSS_DEV_TYPE_FWSEC_DEF = 0xF, 25 MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC, 26 MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA, 27 MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9, 28 MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6, 29 }; 30 31 static const u32 sb_sel_mgn[SB_SEL_MGN_MAX_SIZE] = { 32 0x8000100, 0xC000180 33 }; 34 35 static void rtw89_enable_efuse_pwr_cut_ddv_be(struct rtw89_dev *rtwdev) 36 { 37 const struct rtw89_chip_info *chip = rtwdev->chip; 38 struct rtw89_hal *hal = &rtwdev->hal; 39 bool aphy_patch = true; 40 41 if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV) 42 aphy_patch = false; 43 44 rtw89_write8_set(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK); 45 46 if (aphy_patch) { 47 rtw89_write16_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S); 48 mdelay(1); 49 rtw89_write16_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B); 50 rtw89_write16_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE); 51 } 52 53 rtw89_write32_set(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_EF_BURST); 54 } 55 56 static void rtw89_disable_efuse_pwr_cut_ddv_be(struct rtw89_dev *rtwdev) 57 { 58 const struct rtw89_chip_info *chip = rtwdev->chip; 59 struct rtw89_hal *hal = &rtwdev->hal; 60 bool aphy_patch = true; 61 62 if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV) 63 aphy_patch = false; 64 65 if (aphy_patch) { 66 rtw89_write16_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE); 67 rtw89_write16_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B); 68 mdelay(1); 69 rtw89_write16_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S); 70 } 71 72 rtw89_write8_clr(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK); 73 rtw89_write32_clr(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_EF_BURST); 74 } 75 76 static int rtw89_dump_physical_efuse_map_ddv_be(struct rtw89_dev *rtwdev, u8 *map, 77 u32 dump_addr, u32 dump_size) 78 { 79 u32 efuse_ctl; 80 u32 addr; 81 u32 data; 82 int ret; 83 84 if (!IS_ALIGNED(dump_addr, 4) || !IS_ALIGNED(dump_size, 4)) { 85 rtw89_err(rtwdev, "Efuse addr 0x%x or size 0x%x not aligned\n", 86 dump_addr, dump_size); 87 return -EINVAL; 88 } 89 90 rtw89_enable_efuse_pwr_cut_ddv_be(rtwdev); 91 92 for (addr = dump_addr; addr < dump_addr + dump_size; addr += 4, map += 4) { 93 efuse_ctl = u32_encode_bits(addr, B_BE_EF_ADDR_MASK); 94 rtw89_write32(rtwdev, R_BE_EFUSE_CTRL, efuse_ctl & ~B_BE_EF_RDY); 95 96 ret = read_poll_timeout_atomic(rtw89_read32, efuse_ctl, 97 efuse_ctl & B_BE_EF_RDY, 1, 1000000, 98 true, rtwdev, R_BE_EFUSE_CTRL); 99 if (ret) 100 return -EBUSY; 101 102 data = rtw89_read32(rtwdev, R_BE_EFUSE_CTRL_1_V1); 103 *((__le32 *)map) = cpu_to_le32(data); 104 } 105 106 rtw89_disable_efuse_pwr_cut_ddv_be(rtwdev); 107 108 return 0; 109 } 110 111 static int rtw89_dump_physical_efuse_map_dav_be(struct rtw89_dev *rtwdev, u8 *map, 112 u32 dump_addr, u32 dump_size) 113 { 114 u32 addr; 115 u8 val8; 116 int err; 117 int ret; 118 119 for (addr = dump_addr; addr < dump_addr + dump_size; addr++) { 120 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0x40, 121 FULL_BIT_MASK); 122 if (ret) 123 return ret; 124 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_LOW_ADDR, addr & 0xff, 125 XTAL_SI_LOW_ADDR_MASK); 126 if (ret) 127 return ret; 128 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, addr >> 8, 129 XTAL_SI_HIGH_ADDR_MASK); 130 if (ret) 131 return ret; 132 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0, 133 XTAL_SI_MODE_SEL_MASK); 134 if (ret) 135 return ret; 136 137 ret = read_poll_timeout_atomic(rtw89_mac_read_xtal_si, err, 138 !err && (val8 & XTAL_SI_RDY), 139 1, 10000, false, 140 rtwdev, XTAL_SI_CTRL, &val8); 141 if (ret) { 142 rtw89_warn(rtwdev, "failed to read dav efuse\n"); 143 return ret; 144 } 145 146 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_READ_VAL, &val8); 147 if (ret) 148 return ret; 149 *map++ = val8; 150 } 151 152 return 0; 153 } 154 155 int rtw89_cnv_efuse_state_be(struct rtw89_dev *rtwdev, bool idle) 156 { 157 u32 val; 158 int ret = 0; 159 160 if (idle) { 161 rtw89_write32_set(rtwdev, R_BE_WL_BT_PWR_CTRL, B_BE_BT_DISN_EN); 162 } else { 163 rtw89_write32_clr(rtwdev, R_BE_WL_BT_PWR_CTRL, B_BE_BT_DISN_EN); 164 165 ret = read_poll_timeout(rtw89_read32_mask, val, 166 val == MAC_AX_SYS_ACT, 50, 5000, 167 false, rtwdev, R_BE_IC_PWR_STATE, 168 B_BE_WHOLE_SYS_PWR_STE_MASK); 169 if (ret) 170 rtw89_warn(rtwdev, "failed to convert efuse state\n"); 171 } 172 173 return ret; 174 } 175 176 static int rtw89_dump_physical_efuse_map_be(struct rtw89_dev *rtwdev, u8 *map, 177 u32 dump_addr, u32 dump_size, bool dav) 178 { 179 int ret; 180 181 if (!map || dump_size == 0) 182 return 0; 183 184 rtw89_cnv_efuse_state_be(rtwdev, false); 185 186 if (dav) { 187 ret = rtw89_dump_physical_efuse_map_dav_be(rtwdev, map, 188 dump_addr, dump_size); 189 if (ret) 190 return ret; 191 192 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "phy_map dav: ", map, dump_size); 193 } else { 194 ret = rtw89_dump_physical_efuse_map_ddv_be(rtwdev, map, 195 dump_addr, dump_size); 196 if (ret) 197 return ret; 198 199 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "phy_map ddv: ", map, dump_size); 200 } 201 202 rtw89_cnv_efuse_state_be(rtwdev, true); 203 204 return 0; 205 } 206 207 #define EFUSE_HDR_CONST_MASK GENMASK(23, 20) 208 #define EFUSE_HDR_PAGE_MASK GENMASK(19, 17) 209 #define EFUSE_HDR_OFFSET_MASK GENMASK(16, 4) 210 #define EFUSE_HDR_OFFSET_DAV_MASK GENMASK(11, 4) 211 #define EFUSE_HDR_WORD_EN_MASK GENMASK(3, 0) 212 213 #define invalid_efuse_header_be(hdr1, hdr2, hdr3) \ 214 ((hdr1) == 0xff || (hdr2) == 0xff || (hdr3) == 0xff) 215 #define invalid_efuse_content_be(word_en, i) \ 216 (((word_en) & BIT(i)) != 0x0) 217 #define get_efuse_blk_idx_be(hdr1, hdr2, hdr3) \ 218 (((hdr1) << 16) | ((hdr2) << 8) | (hdr3)) 219 #define block_idx_to_logical_idx_be(blk_idx, i) \ 220 (((blk_idx) << 3) + ((i) << 1)) 221 222 #define invalid_efuse_header_dav_be(hdr1, hdr2) \ 223 ((hdr1) == 0xff || (hdr2) == 0xff) 224 #define get_efuse_blk_idx_dav_be(hdr1, hdr2) \ 225 (((hdr1) << 8) | (hdr2)) 226 227 static int rtw89_eeprom_parser_be(struct rtw89_dev *rtwdev, 228 const u8 *phy_map, u32 phy_size, u8 *log_map, 229 const struct rtw89_efuse_block_cfg *efuse_block) 230 { 231 const struct rtw89_chip_info *chip = rtwdev->chip; 232 enum rtw89_efuse_block blk_page, page; 233 u32 size = efuse_block->size; 234 u32 phy_idx, log_idx; 235 u32 hdr, page_offset; 236 u8 hdr1, hdr2, hdr3; 237 u8 i, val0, val1; 238 u32 min, max; 239 u16 blk_idx; 240 u8 word_en; 241 242 page = u32_get_bits(efuse_block->offset, RTW89_EFUSE_BLOCK_ID_MASK); 243 page_offset = u32_get_bits(efuse_block->offset, RTW89_EFUSE_BLOCK_SIZE_MASK); 244 245 min = ALIGN_DOWN(page_offset, 2); 246 max = ALIGN(page_offset + size, 2); 247 248 memset(log_map, 0xff, size); 249 250 phy_idx = chip->sec_ctrl_efuse_size; 251 252 do { 253 if (page == RTW89_EFUSE_BLOCK_ADIE) { 254 hdr1 = phy_map[phy_idx]; 255 hdr2 = phy_map[phy_idx + 1]; 256 if (invalid_efuse_header_dav_be(hdr1, hdr2)) 257 break; 258 259 phy_idx += 2; 260 261 hdr = get_efuse_blk_idx_dav_be(hdr1, hdr2); 262 263 blk_page = RTW89_EFUSE_BLOCK_ADIE; 264 blk_idx = u32_get_bits(hdr, EFUSE_HDR_OFFSET_DAV_MASK); 265 word_en = u32_get_bits(hdr, EFUSE_HDR_WORD_EN_MASK); 266 } else { 267 hdr1 = phy_map[phy_idx]; 268 hdr2 = phy_map[phy_idx + 1]; 269 hdr3 = phy_map[phy_idx + 2]; 270 if (invalid_efuse_header_be(hdr1, hdr2, hdr3)) 271 break; 272 273 phy_idx += 3; 274 275 hdr = get_efuse_blk_idx_be(hdr1, hdr2, hdr3); 276 277 blk_page = u32_get_bits(hdr, EFUSE_HDR_PAGE_MASK); 278 blk_idx = u32_get_bits(hdr, EFUSE_HDR_OFFSET_MASK); 279 word_en = u32_get_bits(hdr, EFUSE_HDR_WORD_EN_MASK); 280 } 281 282 if (blk_idx >= RTW89_EFUSE_MAX_BLOCK_SIZE >> 3) { 283 rtw89_err(rtwdev, "[ERR]efuse idx:0x%X\n", phy_idx - 3); 284 rtw89_err(rtwdev, "[ERR]read hdr:0x%X\n", hdr); 285 return -EINVAL; 286 } 287 288 for (i = 0; i < 4; i++) { 289 if (invalid_efuse_content_be(word_en, i)) 290 continue; 291 292 if (phy_idx >= phy_size - 1) 293 return -EINVAL; 294 295 log_idx = block_idx_to_logical_idx_be(blk_idx, i); 296 297 if (blk_page == page && log_idx >= min && log_idx < max) { 298 val0 = phy_map[phy_idx]; 299 val1 = phy_map[phy_idx + 1]; 300 301 if (log_idx == min && page_offset > min) { 302 log_map[log_idx - page_offset + 1] = val1; 303 } else if (log_idx + 2 == max && 304 page_offset + size < max) { 305 log_map[log_idx - page_offset] = val0; 306 } else { 307 log_map[log_idx - page_offset] = val0; 308 log_map[log_idx - page_offset + 1] = val1; 309 } 310 } 311 phy_idx += 2; 312 } 313 } while (phy_idx < phy_size); 314 315 return 0; 316 } 317 318 static int rtw89_parse_logical_efuse_block_be(struct rtw89_dev *rtwdev, 319 const u8 *phy_map, u32 phy_size, 320 enum rtw89_efuse_block block) 321 { 322 const struct rtw89_chip_info *chip = rtwdev->chip; 323 const struct rtw89_efuse_block_cfg *efuse_block; 324 u8 *log_map; 325 int ret; 326 327 efuse_block = &chip->efuse_blocks[block]; 328 329 log_map = kmalloc(efuse_block->size, GFP_KERNEL); 330 if (!log_map) 331 return -ENOMEM; 332 333 ret = rtw89_eeprom_parser_be(rtwdev, phy_map, phy_size, log_map, efuse_block); 334 if (ret) { 335 rtw89_warn(rtwdev, "failed to dump efuse logical block %d\n", block); 336 goto out_free; 337 } 338 339 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, efuse_block->size); 340 341 ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map, block); 342 if (ret) { 343 rtw89_warn(rtwdev, "failed to read efuse map\n"); 344 goto out_free; 345 } 346 347 out_free: 348 kfree(log_map); 349 350 return ret; 351 } 352 353 int rtw89_parse_efuse_map_be(struct rtw89_dev *rtwdev) 354 { 355 u32 phy_size = rtwdev->chip->physical_efuse_size; 356 u32 dav_phy_size = rtwdev->chip->dav_phy_efuse_size; 357 enum rtw89_efuse_block block; 358 u8 *phy_map = NULL; 359 u8 *dav_phy_map = NULL; 360 int ret; 361 362 if (rtw89_read16(rtwdev, R_BE_SYS_WL_EFUSE_CTRL) & B_BE_AUTOLOAD_SUS) 363 rtwdev->efuse.valid = true; 364 else 365 rtw89_warn(rtwdev, "failed to check efuse autoload\n"); 366 367 phy_map = kmalloc(phy_size, GFP_KERNEL); 368 if (dav_phy_size) 369 dav_phy_map = kmalloc(dav_phy_size, GFP_KERNEL); 370 371 if (!phy_map || (dav_phy_size && !dav_phy_map)) { 372 ret = -ENOMEM; 373 goto out_free; 374 } 375 376 ret = rtw89_dump_physical_efuse_map_be(rtwdev, phy_map, 0, phy_size, false); 377 if (ret) { 378 rtw89_warn(rtwdev, "failed to dump efuse physical map\n"); 379 goto out_free; 380 } 381 ret = rtw89_dump_physical_efuse_map_be(rtwdev, dav_phy_map, 0, dav_phy_size, true); 382 if (ret) { 383 rtw89_warn(rtwdev, "failed to dump efuse dav physical map\n"); 384 goto out_free; 385 } 386 387 if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) 388 block = RTW89_EFUSE_BLOCK_HCI_DIG_USB; 389 else 390 block = RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO; 391 392 ret = rtw89_parse_logical_efuse_block_be(rtwdev, phy_map, phy_size, block); 393 if (ret) { 394 rtw89_warn(rtwdev, "failed to parse efuse logic block %d\n", 395 RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO); 396 goto out_free; 397 } 398 399 ret = rtw89_parse_logical_efuse_block_be(rtwdev, phy_map, phy_size, 400 RTW89_EFUSE_BLOCK_RF); 401 if (ret) { 402 rtw89_warn(rtwdev, "failed to parse efuse logic block %d\n", 403 RTW89_EFUSE_BLOCK_RF); 404 goto out_free; 405 } 406 407 out_free: 408 kfree(dav_phy_map); 409 kfree(phy_map); 410 411 return ret; 412 } 413 414 int rtw89_parse_phycap_map_be(struct rtw89_dev *rtwdev) 415 { 416 u32 phycap_addr = rtwdev->chip->phycap_addr; 417 u32 phycap_size = rtwdev->chip->phycap_size; 418 u8 *phycap_map = NULL; 419 int ret = 0; 420 421 if (!phycap_size) 422 return 0; 423 424 phycap_map = kmalloc(phycap_size, GFP_KERNEL); 425 if (!phycap_map) 426 return -ENOMEM; 427 428 ret = rtw89_dump_physical_efuse_map_be(rtwdev, phycap_map, 429 phycap_addr, phycap_size, false); 430 if (ret) { 431 rtw89_warn(rtwdev, "failed to dump phycap map\n"); 432 goto out_free; 433 } 434 435 ret = rtwdev->chip->ops->read_phycap(rtwdev, phycap_map); 436 if (ret) { 437 rtw89_warn(rtwdev, "failed to read phycap map\n"); 438 goto out_free; 439 } 440 441 out_free: 442 kfree(phycap_map); 443 444 return ret; 445 } 446 447 static u16 get_sb_cryp_sel_idx(u16 sb_cryp_sel) 448 { 449 u8 low_bit, high_bit, cnt_zero = 0; 450 u8 idx, sel_form_v, sel_idx_v; 451 u16 sb_cryp_sel_v = 0x0; 452 453 sel_form_v = u16_get_bits(sb_cryp_sel, MASKBYTE0); 454 sel_idx_v = u16_get_bits(sb_cryp_sel, MASKBYTE1); 455 456 for (idx = 0; idx < 4; idx++) { 457 low_bit = !!(sel_form_v & BIT(idx)); 458 high_bit = !!(sel_form_v & BIT(7 - idx)); 459 if (low_bit != high_bit) 460 return U16_MAX; 461 if (low_bit) 462 continue; 463 464 cnt_zero++; 465 if (cnt_zero == 1) 466 sb_cryp_sel_v = idx * 16; 467 else if (cnt_zero > 1) 468 return U16_MAX; 469 } 470 471 low_bit = u8_get_bits(sel_idx_v, 0x0F); 472 high_bit = u8_get_bits(sel_idx_v, 0xF0); 473 474 if ((low_bit ^ high_bit) != 0xF) 475 return U16_MAX; 476 477 return sb_cryp_sel_v + low_bit; 478 } 479 480 static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type) 481 { 482 switch (mss_dev_type) { 483 case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX: 484 mss_dev_type = 0x0; 485 break; 486 case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB: 487 mss_dev_type = 0x1; 488 break; 489 case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB: 490 mss_dev_type = 0x2; 491 break; 492 case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX: 493 mss_dev_type = 0x3; 494 break; 495 case MSS_DEV_TYPE_FWSEC_DEF: 496 mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF; 497 break; 498 default: 499 rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type); 500 mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV; 501 break; 502 } 503 504 return mss_dev_type; 505 } 506 507 int rtw89_efuse_read_fw_secure_be(struct rtw89_dev *rtwdev) 508 { 509 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 510 u32 sec_addr = EFUSE_SEC_BE_START; 511 u32 sec_size = EFUSE_SEC_BE_SIZE; 512 u16 sb_cryp_sel, sb_cryp_sel_idx; 513 u8 sec_map[EFUSE_SEC_BE_SIZE]; 514 u8 mss_dev_type; 515 u8 b1, b2; 516 int ret; 517 518 ret = rtw89_dump_physical_efuse_map_be(rtwdev, sec_map, 519 sec_addr, sec_size, false); 520 if (ret) { 521 rtw89_warn(rtwdev, "failed to dump secsel map\n"); 522 return ret; 523 } 524 525 sb_cryp_sel = sec_map[EFUSE_SB_CRYP_SEL_ADDR - sec_addr] | 526 sec_map[EFUSE_SB_CRYP_SEL_ADDR - sec_addr + 1] << 8; 527 if (sb_cryp_sel == EFUSE_SB_CRYP_SEL_DEFAULT) 528 goto out; 529 530 sb_cryp_sel_idx = get_sb_cryp_sel_idx(sb_cryp_sel); 531 if (sb_cryp_sel_idx >= SB_SEL_MGN_MAX_SIZE) { 532 rtw89_warn(rtwdev, "invalid SB cryp sel idx %d\n", sb_cryp_sel_idx); 533 goto out; 534 } 535 536 sec->sb_sel_mgn = sb_sel_mgn[sb_cryp_sel_idx]; 537 538 b1 = sec_map[EFUSE_EXTERNALPN_ADDR_BE - sec_addr]; 539 b2 = sec_map[EFUSE_SERIALNUM_ADDR_BE - sec_addr]; 540 541 mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK); 542 sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) | 543 u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4); 544 sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK); 545 546 sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type); 547 if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) { 548 rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type); 549 goto out; 550 } 551 552 sec->secure_boot = true; 553 554 out: 555 rtw89_debug(rtwdev, RTW89_DBG_FW, 556 "MSS secure_boot=%d dev_type=%d cust_idx=%d key_num=%d\n", 557 sec->secure_boot, sec->mss_dev_type, sec->mss_cust_idx, 558 sec->mss_key_num); 559 560 return 0; 561 } 562 EXPORT_SYMBOL(rtw89_efuse_read_fw_secure_be); 563