xref: /linux/drivers/net/wireless/realtek/rtw89/efuse.c (revision c4dde411bc366f568dbe33366253bbfea049e8ea)
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 static int rtw89_dump_physical_efuse_map(struct rtw89_dev *rtwdev, u8 *map,
212 					 u32 dump_addr, u32 dump_size, bool dav)
213 {
214 	int retry;
215 	int ret;
216 
217 	for (retry = 0; retry < 5; retry++) {
218 		ret = __rtw89_dump_physical_efuse_map(rtwdev, map, dump_addr,
219 						      dump_size, dav);
220 		if (!ret)
221 			return 0;
222 
223 		rtw89_warn(rtwdev, "efuse dump (dav=%d) failed, retrying (%d)\n",
224 			   dav, retry);
225 	}
226 
227 	return ret;
228 }
229 
230 #define invalid_efuse_header(hdr1, hdr2) \
231 	((hdr1) == 0xff || (hdr2) == 0xff)
232 #define invalid_efuse_content(word_en, i) \
233 	(((word_en) & BIT(i)) != 0x0)
234 #define get_efuse_blk_idx(hdr1, hdr2) \
235 	((((hdr2) & 0xf0) >> 4) | (((hdr1) & 0x0f) << 4))
236 #define block_idx_to_logical_idx(blk_idx, i) \
237 	(((blk_idx) << 3) + ((i) << 1))
238 static int rtw89_dump_logical_efuse_map(struct rtw89_dev *rtwdev, u8 *phy_map,
239 					u8 *log_map)
240 {
241 	u32 physical_size = rtwdev->chip->physical_efuse_size;
242 	u32 logical_size = rtwdev->chip->logical_efuse_size;
243 	u8 sec_ctrl_size = rtwdev->chip->sec_ctrl_efuse_size;
244 	u32 phy_idx = sec_ctrl_size;
245 	u32 log_idx;
246 	u8 hdr1, hdr2;
247 	u8 blk_idx;
248 	u8 word_en;
249 	int i;
250 
251 	if (!phy_map)
252 		return 0;
253 
254 	while (phy_idx < physical_size - sec_ctrl_size) {
255 		hdr1 = phy_map[phy_idx];
256 		hdr2 = phy_map[phy_idx + 1];
257 		if (invalid_efuse_header(hdr1, hdr2))
258 			break;
259 
260 		blk_idx = get_efuse_blk_idx(hdr1, hdr2);
261 		word_en = hdr2 & 0xf;
262 		phy_idx += 2;
263 
264 		for (i = 0; i < 4; i++) {
265 			if (invalid_efuse_content(word_en, i))
266 				continue;
267 
268 			log_idx = block_idx_to_logical_idx(blk_idx, i);
269 			if (phy_idx + 1 > physical_size - sec_ctrl_size - 1 ||
270 			    log_idx + 1 > logical_size)
271 				return -EINVAL;
272 
273 			log_map[log_idx] = phy_map[phy_idx];
274 			log_map[log_idx + 1] = phy_map[phy_idx + 1];
275 			phy_idx += 2;
276 		}
277 	}
278 	return 0;
279 }
280 
281 int rtw89_parse_efuse_map_ax(struct rtw89_dev *rtwdev)
282 {
283 	u32 phy_size = rtwdev->chip->physical_efuse_size;
284 	u32 log_size = rtwdev->chip->logical_efuse_size;
285 	u32 dav_phy_size = rtwdev->chip->dav_phy_efuse_size;
286 	u32 dav_log_size = rtwdev->chip->dav_log_efuse_size;
287 	u32 full_log_size = log_size + dav_log_size;
288 	u8 *phy_map = NULL;
289 	u8 *log_map = NULL;
290 	u8 *dav_phy_map = NULL;
291 	u8 *dav_log_map = NULL;
292 	int ret;
293 
294 	if (rtw89_read16(rtwdev, R_AX_SYS_WL_EFUSE_CTRL) & B_AX_AUTOLOAD_SUS)
295 		rtwdev->efuse.valid = true;
296 	else
297 		rtw89_warn(rtwdev, "failed to check efuse autoload\n");
298 
299 	phy_map = kmalloc(phy_size, GFP_KERNEL);
300 	log_map = kmalloc(full_log_size, GFP_KERNEL);
301 	if (dav_phy_size && dav_log_size) {
302 		dav_phy_map = kmalloc(dav_phy_size, GFP_KERNEL);
303 		dav_log_map = log_map + log_size;
304 	}
305 
306 	if (!phy_map || !log_map || (dav_phy_size && !dav_phy_map)) {
307 		ret = -ENOMEM;
308 		goto out_free;
309 	}
310 
311 	ret = rtw89_dump_physical_efuse_map(rtwdev, phy_map, 0, phy_size, false);
312 	if (ret) {
313 		rtw89_warn(rtwdev, "failed to dump efuse physical map\n");
314 		goto out_free;
315 	}
316 	ret = rtw89_dump_physical_efuse_map(rtwdev, dav_phy_map, 0, dav_phy_size, true);
317 	if (ret) {
318 		rtw89_warn(rtwdev, "failed to dump efuse dav physical map\n");
319 		goto out_free;
320 	}
321 
322 	memset(log_map, 0xff, full_log_size);
323 	ret = rtw89_dump_logical_efuse_map(rtwdev, phy_map, log_map);
324 	if (ret) {
325 		rtw89_warn(rtwdev, "failed to dump efuse logical map\n");
326 		goto out_free;
327 	}
328 	ret = rtw89_dump_logical_efuse_map(rtwdev, dav_phy_map, dav_log_map);
329 	if (ret) {
330 		rtw89_warn(rtwdev, "failed to dump efuse dav logical map\n");
331 		goto out_free;
332 	}
333 
334 	rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "log_map: ", log_map, full_log_size);
335 
336 	ret = rtwdev->chip->ops->read_efuse(rtwdev, log_map, RTW89_EFUSE_BLOCK_IGNORE);
337 	if (ret) {
338 		rtw89_warn(rtwdev, "failed to read efuse map\n");
339 		goto out_free;
340 	}
341 
342 out_free:
343 	kfree(dav_phy_map);
344 	kfree(log_map);
345 	kfree(phy_map);
346 
347 	return ret;
348 }
349 
350 int rtw89_parse_phycap_map_ax(struct rtw89_dev *rtwdev)
351 {
352 	u32 phycap_addr = rtwdev->chip->phycap_addr;
353 	u32 phycap_size = rtwdev->chip->phycap_size;
354 	u8 *phycap_map = NULL;
355 	int ret = 0;
356 
357 	if (!phycap_size)
358 		return 0;
359 
360 	phycap_map = kmalloc(phycap_size, GFP_KERNEL);
361 	if (!phycap_map)
362 		return -ENOMEM;
363 
364 	ret = rtw89_dump_physical_efuse_map(rtwdev, phycap_map,
365 					    phycap_addr, phycap_size, false);
366 	if (ret) {
367 		rtw89_warn(rtwdev, "failed to dump phycap map\n");
368 		goto out_free;
369 	}
370 
371 	ret = rtwdev->chip->ops->read_phycap(rtwdev, phycap_map);
372 	if (ret) {
373 		rtw89_warn(rtwdev, "failed to read phycap map\n");
374 		goto out_free;
375 	}
376 
377 out_free:
378 	kfree(phycap_map);
379 
380 	return ret;
381 }
382 
383 int rtw89_read_efuse_ver(struct rtw89_dev *rtwdev, u8 *ecv)
384 {
385 	int ret;
386 	u8 val;
387 
388 	ret = rtw89_dump_physical_efuse_map(rtwdev, &val, EF_FV_OFSET, 1, false);
389 	if (ret)
390 		return ret;
391 
392 	*ecv = u8_get_bits(val, EF_CV_MASK);
393 	if (*ecv == EF_CV_INV)
394 		return -ENOENT;
395 
396 	return 0;
397 }
398 EXPORT_SYMBOL(rtw89_read_efuse_ver);
399 
400 static u8 get_mss_dev_type_idx(struct rtw89_dev *rtwdev, u8 mss_dev_type)
401 {
402 	switch (mss_dev_type) {
403 	case MSS_DEV_TYPE_FWSEC_WINLIN_INBOX:
404 		mss_dev_type = 0x0;
405 		break;
406 	case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB:
407 		mss_dev_type = 0x1;
408 		break;
409 	case MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_COB:
410 		mss_dev_type = 0x2;
411 		break;
412 	case MSS_DEV_TYPE_FWSEC_NONWIN_INBOX:
413 		mss_dev_type = 0x3;
414 		break;
415 	case MSS_DEV_TYPE_FWSEC_DEF:
416 		mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_DEF;
417 		break;
418 	default:
419 		rtw89_warn(rtwdev, "unknown mss_dev_type %d", mss_dev_type);
420 		mss_dev_type = RTW89_FW_MSS_DEV_TYPE_FWSEC_INV;
421 		break;
422 	}
423 
424 	return mss_dev_type;
425 }
426 
427 int rtw89_efuse_recognize_mss_info_v1(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
428 {
429 	const struct rtw89_chip_info *chip = rtwdev->chip;
430 	struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
431 	u8 mss_dev_type;
432 
433 	if (chip->chip_id == RTL8852B && b1 == 0xFF && b2 == 0x6E) {
434 		mss_dev_type = MSS_DEV_TYPE_FWSEC_NONLIN_INBOX_NON_COB;
435 		sec->mss_cust_idx = 0;
436 		sec->mss_key_num = 0;
437 
438 		goto mss_dev_type;
439 	}
440 
441 	mss_dev_type = u8_get_bits(b1, EFUSE_B1_MSSDEVTYPE_MASK);
442 	sec->mss_cust_idx = 0x1F - (u8_get_bits(b1, EFUSE_B1_MSSCUSTIDX0_MASK) |
443 				    u8_get_bits(b2, EFUSE_B2_MSSCUSTIDX1_MASK) << 4);
444 	sec->mss_key_num = 0xF - u8_get_bits(b2, EFUSE_B2_MSSKEYNUM_MASK);
445 
446 mss_dev_type:
447 	sec->mss_dev_type = get_mss_dev_type_idx(rtwdev, mss_dev_type);
448 	if (sec->mss_dev_type == RTW89_FW_MSS_DEV_TYPE_FWSEC_INV) {
449 		rtw89_warn(rtwdev, "invalid mss_dev_type %d\n", mss_dev_type);
450 		return -ENOENT;
451 	}
452 
453 	sec->can_mss_v1 = true;
454 
455 	return 0;
456 }
457 
458 static
459 int rtw89_efuse_recognize_mss_index_v0(struct rtw89_dev *rtwdev, u8 b1, u8 b2)
460 {
461 	struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
462 	u8 externalPN;
463 	u8 serialNum;
464 	u8 customer;
465 	u8 i;
466 
467 	externalPN = 0xFF - u8_get_bits(b1, EFUSE_B1_EXTERNALPN_MASK);
468 	customer = 0xF - u8_get_bits(b2, EFUSE_B2_CUSTOMER_MASK);
469 	serialNum = 0x7 - u8_get_bits(b2, EFUSE_B2_SERIALNUM_MASK);
470 
471 	for (i = 0; i < OTP_KEY_INFO_NUM; i++) {
472 		if (externalPN == otp_key_info_externalPN[i] &&
473 		    customer == otp_key_info_customer[i] &&
474 		    serialNum == otp_key_info_serialNum[i]) {
475 			sec->mss_idx = i;
476 			sec->can_mss_v0 = true;
477 			return 0;
478 		}
479 	}
480 
481 	return -ENOENT;
482 }
483 
484 int rtw89_efuse_read_fw_secure_ax(struct rtw89_dev *rtwdev)
485 {
486 	struct rtw89_fw_secure *sec = &rtwdev->fw.sec;
487 	u32 sec_addr = EFUSE_EXTERNALPN_ADDR_AX;
488 	u32 sec_size = 2;
489 	u8 sec_map[2];
490 	u8 b1, b2;
491 	int ret;
492 
493 	ret = rtw89_dump_physical_efuse_map(rtwdev, sec_map,
494 					    sec_addr, sec_size, false);
495 	if (ret) {
496 		rtw89_warn(rtwdev, "failed to dump secsel map\n");
497 		return ret;
498 	}
499 
500 	b1 = sec_map[0];
501 	b2 = sec_map[1];
502 
503 	if (b1 == 0xFF && b2 == 0xFF)
504 		return 0;
505 
506 	rtw89_efuse_recognize_mss_index_v0(rtwdev, b1, b2);
507 	rtw89_efuse_recognize_mss_info_v1(rtwdev, b1, b2);
508 	if (!sec->can_mss_v1 && !sec->can_mss_v0)
509 		goto out;
510 
511 	sec->secure_boot = true;
512 
513 out:
514 	rtw89_debug(rtwdev, RTW89_DBG_FW,
515 		    "MSS secure_boot=%d(%d/%d) dev_type=%d cust_idx=%d key_num=%d mss_index=%d\n",
516 		    sec->secure_boot, sec->can_mss_v0, sec->can_mss_v1,
517 		    sec->mss_dev_type, sec->mss_cust_idx,
518 		    sec->mss_key_num, sec->mss_idx);
519 
520 	return 0;
521 }
522