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 "efuse.h" 7 #include "mac.h" 8 #include "reg.h" 9 10 #define EFUSE_B1_MSSDEVTYPE_MASK GENMASK(3, 0) 11 #define EFUSE_B1_MSSCUSTIDX0_MASK GENMASK(7, 4) 12 #define EFUSE_B2_MSSKEYNUM_MASK GENMASK(3, 0) 13 #define EFUSE_B2_MSSCUSTIDX1_MASK BIT(6) 14 15 #define EFUSE_EXTERNALPN_ADDR_AX 0x5EC 16 #define EFUSE_CUSTOMER_ADDR_AX 0x5ED 17 #define EFUSE_SERIALNUM_ADDR_AX 0x5ED 18 19 #define EFUSE_B1_EXTERNALPN_MASK GENMASK(7, 0) 20 #define EFUSE_B2_CUSTOMER_MASK GENMASK(3, 0) 21 #define EFUSE_B2_SERIALNUM_MASK GENMASK(6, 4) 22 23 #define OTP_KEY_INFO_NUM 2 24 25 static const u8 otp_key_info_externalPN[OTP_KEY_INFO_NUM] = {0x0, 0x0}; 26 static const u8 otp_key_info_customer[OTP_KEY_INFO_NUM] = {0x0, 0x1}; 27 static const u8 otp_key_info_serialNum[OTP_KEY_INFO_NUM] = {0x0, 0x1}; 28 29 enum rtw89_efuse_bank { 30 RTW89_EFUSE_BANK_WIFI, 31 RTW89_EFUSE_BANK_BT, 32 }; 33 34 enum rtw89_efuse_mss_dev_type { 35 MSS_DEV_TYPE_FWSEC_DEF = 0xF, 36 MSS_DEV_TYPE_FWSEC_WINLIN_INBOX = 0xC, 37 MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB = 0xA, 38 MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB = 0x9, 39 MSS_DEV_TYPE_FWSEC_NONWIN_INBOX = 0x6, 40 }; 41 42 static int rtw89_switch_efuse_bank(struct rtw89_dev *rtwdev, 43 enum rtw89_efuse_bank bank) 44 { 45 u8 val; 46 47 if (rtwdev->chip->chip_id != RTL8852A) 48 return 0; 49 50 val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1, 51 B_AX_EF_CELL_SEL_MASK); 52 if (bank == val) 53 return 0; 54 55 rtw89_write32_mask(rtwdev, R_AX_EFUSE_CTRL_1, B_AX_EF_CELL_SEL_MASK, 56 bank); 57 58 val = rtw89_read32_mask(rtwdev, R_AX_EFUSE_CTRL_1, 59 B_AX_EF_CELL_SEL_MASK); 60 if (bank == val) 61 return 0; 62 63 return -EBUSY; 64 } 65 66 static void rtw89_enable_otp_burst_mode(struct rtw89_dev *rtwdev, bool en) 67 { 68 if (en) 69 rtw89_write32_set(rtwdev, R_AX_EFUSE_CTRL_1_V1, B_AX_EF_BURST); 70 else 71 rtw89_write32_clr(rtwdev, R_AX_EFUSE_CTRL_1_V1, B_AX_EF_BURST); 72 } 73 74 static void rtw89_enable_efuse_pwr_cut_ddv(struct rtw89_dev *rtwdev) 75 { 76 enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; 77 struct rtw89_hal *hal = &rtwdev->hal; 78 79 if (chip_id == RTL8852A) 80 return; 81 82 rtw89_write8_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); 83 rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); 84 85 fsleep(1000); 86 87 rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15); 88 rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE); 89 if (chip_id == RTL8852B && hal->cv == CHIP_CAV) 90 rtw89_enable_otp_burst_mode(rtwdev, true); 91 } 92 93 static void rtw89_disable_efuse_pwr_cut_ddv(struct rtw89_dev *rtwdev) 94 { 95 enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; 96 struct rtw89_hal *hal = &rtwdev->hal; 97 98 if (chip_id == RTL8852A) 99 return; 100 101 if (chip_id == RTL8852B && hal->cv == CHIP_CAV) 102 rtw89_enable_otp_burst_mode(rtwdev, false); 103 104 rtw89_write16_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE); 105 rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15); 106 107 fsleep(1000); 108 109 rtw89_write16_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); 110 rtw89_write8_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); 111 } 112 113 static int rtw89_dump_physical_efuse_map_ddv(struct rtw89_dev *rtwdev, u8 *map, 114 u32 dump_addr, u32 dump_size) 115 { 116 u32 efuse_ctl; 117 u32 addr; 118 int ret; 119 120 rtw89_enable_efuse_pwr_cut_ddv(rtwdev); 121 122 for (addr = dump_addr; addr < dump_addr + dump_size; addr++) { 123 efuse_ctl = u32_encode_bits(addr, B_AX_EF_ADDR_MASK); 124 rtw89_write32(rtwdev, R_AX_EFUSE_CTRL, efuse_ctl & ~B_AX_EF_RDY); 125 126 ret = read_poll_timeout_atomic(rtw89_read32, efuse_ctl, 127 efuse_ctl & B_AX_EF_RDY, 1, 1000000, 128 true, rtwdev, R_AX_EFUSE_CTRL); 129 if (ret) 130 return -EBUSY; 131 132 *map++ = (u8)(efuse_ctl & 0xff); 133 } 134 135 rtw89_disable_efuse_pwr_cut_ddv(rtwdev); 136 137 return 0; 138 } 139 140 int rtw89_cnv_efuse_state_ax(struct rtw89_dev *rtwdev, bool idle) 141 { 142 return 0; 143 } 144 145 static int rtw89_dump_physical_efuse_map_dav(struct rtw89_dev *rtwdev, u8 *map, 146 u32 dump_addr, u32 dump_size) 147 { 148 u32 addr; 149 u8 val8; 150 int err; 151 int ret; 152 153 for (addr = dump_addr; addr < dump_addr + dump_size; addr++) { 154 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0x40, FULL_BIT_MASK); 155 if (ret) 156 return ret; 157 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_LOW_ADDR, 158 addr & 0xff, XTAL_SI_LOW_ADDR_MASK); 159 if (ret) 160 return ret; 161 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, addr >> 8, 162 XTAL_SI_HIGH_ADDR_MASK); 163 if (ret) 164 return ret; 165 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_CTRL, 0, 166 XTAL_SI_MODE_SEL_MASK); 167 if (ret) 168 return ret; 169 170 ret = read_poll_timeout_atomic(rtw89_mac_read_xtal_si, err, 171 !err && (val8 & XTAL_SI_RDY), 172 1, 10000, false, 173 rtwdev, XTAL_SI_CTRL, &val8); 174 if (ret) { 175 rtw89_warn(rtwdev, "failed to read dav efuse\n"); 176 return ret; 177 } 178 179 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_READ_VAL, &val8); 180 if (ret) 181 return ret; 182 *map++ = val8; 183 } 184 185 return 0; 186 } 187 188 static int rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map, 189 u32 dump_addr, u32 dump_size, bool dav) 190 { 191 int ret; 192 193 if (!map || dump_size == 0) 194 return 0; 195 196 rtw89_switch_efuse_bank(rtwdev, RTW89_EFUSE_BANK_WIFI); 197 198 if (dav) { 199 ret = rtw89_dump_physical_efuse_map_dav(rtwdev, map, dump_addr, dump_size); 200 if (ret) 201 return ret; 202 } else { 203 ret = rtw89_dump_physical_efuse_map_ddv(rtwdev, map, dump_addr, dump_size); 204 if (ret) 205 return ret; 206 } 207 208 return 0; 209 } 210 211 #define invalid_efuse_header(hdr1, hdr2) \ 212 ((hdr1) == 0xff || (hdr2) == 0xff) 213 #define invalid_efuse_content(word_en, i) \ 214 (((word_en) & BIT(i)) != 0x0) 215 #define get_efuse_blk_idx(hdr1, hdr2) \ 216 ((((hdr2) & 0xf0) >> 4) | (((hdr1) & 0x0f) << 4)) 217 #define block_idx_to_logical_idx(blk_idx, i) \ 218 (((blk_idx) << 3) + ((i) << 1)) 219 static int rtw89_dump_logical_efuse_map(struct rtw89_dev *rtwdev, u8 *phy_map, 220 u8 *log_map) 221 { 222 u32 physical_size = rtwdev->chip->physical_efuse_size; 223 u32 logical_size = rtwdev->chip->logical_efuse_size; 224 u8 sec_ctrl_size = rtwdev->chip->sec_ctrl_efuse_size; 225 u32 phy_idx = sec_ctrl_size; 226 u32 log_idx; 227 u8 hdr1, hdr2; 228 u8 blk_idx; 229 u8 word_en; 230 int i; 231 232 if (!phy_map) 233 return 0; 234 235 while (phy_idx < physical_size - sec_ctrl_size) { 236 hdr1 = phy_map[phy_idx]; 237 hdr2 = phy_map[phy_idx + 1]; 238 if (invalid_efuse_header(hdr1, hdr2)) 239 break; 240 241 blk_idx = get_efuse_blk_idx(hdr1, hdr2); 242 word_en = hdr2 & 0xf; 243 phy_idx += 2; 244 245 for (i = 0; i < 4; i++) { 246 if (invalid_efuse_content(word_en, i)) 247 continue; 248 249 log_idx = block_idx_to_logical_idx(blk_idx, i); 250 if (phy_idx + 1 > physical_size - sec_ctrl_size - 1 || 251 log_idx + 1 > logical_size) 252 return -EINVAL; 253 254 log_map[log_idx] = phy_map[phy_idx]; 255 log_map[log_idx + 1] = phy_map[phy_idx + 1]; 256 phy_idx += 2; 257 } 258 } 259 return 0; 260 } 261 262 int rtw89_parse_efuse_map_ax(struct rtw89_dev *rtwdev) 263 { 264 u32 phy_size = rtwdev->chip->physical_efuse_size; 265 u32 log_size = rtwdev->chip->logical_efuse_size; 266 u32 dav_phy_size = rtwdev->chip->dav_phy_efuse_size; 267 u32 dav_log_size = rtwdev->chip->dav_log_efuse_size; 268 u32 full_log_size = log_size + dav_log_size; 269 u8 *phy_map = NULL; 270 u8 *log_map = NULL; 271 u8 *dav_phy_map = NULL; 272 u8 *dav_log_map = NULL; 273 int ret; 274 275 if (rtw89_read16(rtwdev, R_AX_SYS_WL_EFUSE_CTRL) & B_AX_AUTOLOAD_SUS) 276 rtwdev->efuse.valid = true; 277 else 278 rtw89_warn(rtwdev, "failed to check efuse autoload\n"); 279 280 phy_map = kmalloc(phy_size, GFP_KERNEL); 281 log_map = kmalloc(full_log_size, GFP_KERNEL); 282 if (dav_phy_size && dav_log_size) { 283 dav_phy_map = kmalloc(dav_phy_size, GFP_KERNEL); 284 dav_log_map = log_map + log_size; 285 } 286 287 if (!phy_map || !log_map || (dav_phy_size && !dav_phy_map)) { 288 ret = -ENOMEM; 289 goto out_free; 290 } 291 292 ret = rtw89_dump_physical_efuse_map(rtwdev, phy_map, 0, phy_size, false); 293 if (ret) { 294 rtw89_warn(rtwdev, "failed to dump efuse physical map\n"); 295 goto out_free; 296 } 297 ret = rtw89_dump_physical_efuse_map(rtwdev, dav_phy_map, 0, dav_phy_size, true); 298 if (ret) { 299 rtw89_warn(rtwdev, "failed to dump efuse dav physical map\n"); 300 goto out_free; 301 } 302 303 memset(log_map, 0xff, full_log_size); 304 ret = rtw89_dump_logical_efuse_map(rtwdev, phy_map, log_map); 305 if (ret) { 306 rtw89_warn(rtwdev, "failed to dump efuse logical map\n"); 307 goto out_free; 308 } 309 ret = rtw89_dump_logical_efuse_map(rtwdev, dav_phy_map, dav_log_map); 310 if (ret) { 311 rtw89_warn(rtwdev, "failed to dump efuse dav logical map\n"); 312 goto out_free; 313 } 314 315 rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, full_log_size); 316 317 ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map, RTW89_EFUSE_BLOCK_IGNORE); 318 if (ret) { 319 rtw89_warn(rtwdev, "failed to read efuse map\n"); 320 goto out_free; 321 } 322 323 out_free: 324 kfree(dav_phy_map); 325 kfree(log_map); 326 kfree(phy_map); 327 328 return ret; 329 } 330 331 int rtw89_parse_phycap_map_ax(struct rtw89_dev *rtwdev) 332 { 333 u32 phycap_addr = rtwdev->chip->phycap_addr; 334 u32 phycap_size = rtwdev->chip->phycap_size; 335 u8 *phycap_map = NULL; 336 int ret = 0; 337 338 if (!phycap_size) 339 return 0; 340 341 phycap_map = kmalloc(phycap_size, GFP_KERNEL); 342 if (!phycap_map) 343 return -ENOMEM; 344 345 ret = rtw89_dump_physical_efuse_map(rtwdev, phycap_map, 346 phycap_addr, phycap_size, false); 347 if (ret) { 348 rtw89_warn(rtwdev, "failed to dump phycap map\n"); 349 goto out_free; 350 } 351 352 ret = rtwdev->chip->ops->read_phycap(rtwdev, phycap_map); 353 if (ret) { 354 rtw89_warn(rtwdev, "failed to read phycap map\n"); 355 goto out_free; 356 } 357 358 out_free: 359 kfree(phycap_map); 360 361 return ret; 362 } 363 364 int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv) 365 { 366 int ret; 367 u8 val; 368 369 ret = rtw89_dump_physical_efuse_map(rtwdev, &val, EF_FV_OFSET, 1, false); 370 if (ret) 371 return ret; 372 373 *ecv = u8_get_bits(val, EF_CV_MASK); 374 if (*ecv == EF_CV_INV) 375 return -ENOENT; 376 377 return 0; 378 } 379 EXPORT_SYMBOL(rtw89_read_efuse_ver); 380 381 static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type) 382 { 383 switch (mss_dev_type) { 384 case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX: 385 mss_dev_type = 0x0; 386 break; 387 case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB: 388 mss_dev_type = 0x1; 389 break; 390 case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB: 391 mss_dev_type = 0x2; 392 break; 393 case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX: 394 mss_dev_type = 0x3; 395 break; 396 case MSS_DEV_TYPE_FWSEC_DEF: 397 mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF; 398 break; 399 default: 400 rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type); 401 mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV; 402 break; 403 } 404 405 return mss_dev_type; 406 } 407 408 int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2) 409 { 410 const struct rtw89_chip_info *chip = rtwdev->chip; 411 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 412 u8 mss_dev_type; 413 414 if (chip->chip_id == RTL8852B && b1 == 0xFF && b2 == 0x6E) { 415 mss_dev_type = MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB; 416 sec->mss_cust_idx = 0; 417 sec->mss_key_num = 0; 418 419 goto mss_dev_type; 420 } 421 422 mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK); 423 sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) | 424 u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4); 425 sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK); 426 427 mss_dev_type: 428 sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type); 429 if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) { 430 rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type); 431 return -ENOENT; 432 } 433 434 sec->can_mss_v1 = true; 435 436 return 0; 437 } 438 439 static 440 int rtw89_efuse_recognize_mss_index_v0(struct rtw89_dev *rtwdev, u8 b1, u8 b2) 441 { 442 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 443 u8 externalPN; 444 u8 serialNum; 445 u8 customer; 446 u8 i; 447 448 externalPN = 0xFF - u8_get_bits(b1, EFUSE_B1_EXTERNALPN_MASK); 449 customer = 0xF - u8_get_bits(b2, EFUSE_B2_CUSTOMER_MASK); 450 serialNum = 0x7 - u8_get_bits(b2, EFUSE_B2_SERIALNUM_MASK); 451 452 for (i = 0; i < OTP_KEY_INFO_NUM; i++) { 453 if (externalPN == otp_key_info_externalPN[i] && 454 customer == otp_key_info_customer[i] && 455 serialNum == otp_key_info_serialNum[i]) { 456 sec->mss_idx = i; 457 sec->can_mss_v0 = true; 458 return 0; 459 } 460 } 461 462 return -ENOENT; 463 } 464 465 int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev) 466 { 467 struct rtw89_fw_secure *sec = &rtwdev->fw.sec; 468 u32 sec_addr = EFUSE_EXTERNALPN_ADDR_AX; 469 u32 sec_size = 2; 470 u8 sec_map[2]; 471 u8 b1, b2; 472 int ret; 473 474 ret = rtw89_dump_physical_efuse_map(rtwdev, sec_map, 475 sec_addr, sec_size, false); 476 if (ret) { 477 rtw89_warn(rtwdev, "failed to dump secsel map\n"); 478 return ret; 479 } 480 481 b1 = sec_map[0]; 482 b2 = sec_map[1]; 483 484 if (b1 == 0xFF && b2 == 0xFF) 485 return 0; 486 487 rtw89_efuse_recognize_mss_index_v0(rtwdev, b1, b2); 488 rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2); 489 if (!sec->can_mss_v1 && !sec->can_mss_v0) 490 goto out; 491 492 sec->secure_boot = true; 493 494 out: 495 rtw89_debug(rtwdev, RTW89_DBG_FW, 496 "MSS secure_boot=%d(%d/%d) dev_type=%d cust_idx=%d key_num=%d mss_index=%d\n", 497 sec->secure_boot, sec->can_mss_v0, sec->can_mss_v1, 498 sec->mss_dev_type, sec->mss_cust_idx, 499 sec->mss_key_num, sec->mss_idx); 500 501 return 0; 502 } 503