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