1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3 
4 #define _HAL_INIT_C_
5 
6 #include "../include/drv_types.h"
7 #include "../include/rtw_efuse.h"
8 #include "../include/rtl8188e_hal.h"
9 #include "../include/rtw_iol.h"
10 #include "../include/usb_ops.h"
11 #include "../include/rtw_fw.h"
12 
iol_mode_enable(struct adapter * padapter,u8 enable)13 static void iol_mode_enable(struct adapter *padapter, u8 enable)
14 {
15 	u8 reg_0xf0 = 0;
16 	int res;
17 
18 	if (enable) {
19 		/* Enable initial offload */
20 		res = rtw_read8(padapter, REG_SYS_CFG, &reg_0xf0);
21 		if (res)
22 			return;
23 
24 		rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
25 
26 		if (!padapter->bFWReady)
27 			rtw_reset_8051(padapter);
28 
29 	} else {
30 		/* disable initial offload */
31 		res = rtw_read8(padapter, REG_SYS_CFG, &reg_0xf0);
32 		if (res)
33 			return;
34 
35 		rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
36 	}
37 }
38 
iol_execute(struct adapter * padapter,u8 control)39 static s32 iol_execute(struct adapter *padapter, u8 control)
40 {
41 	s32 status = _FAIL;
42 	u8 reg_0x88 = 0;
43 	unsigned long timeout;
44 	int res;
45 
46 	control = control & 0x0f;
47 	res = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
48 	if (res)
49 		return _FAIL;
50 
51 	rtw_write8(padapter, REG_HMEBOX_E0,  reg_0x88 | control);
52 
53 	timeout = jiffies + msecs_to_jiffies(1000);
54 
55 	do {
56 		res = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
57 		if (res)
58 			continue;
59 
60 		if (!(reg_0x88 & control))
61 			break;
62 
63 	} while (time_before(jiffies, timeout));
64 
65 	res = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
66 	if (res)
67 		return _FAIL;
68 
69 	status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
70 	if (reg_0x88 & control << 4)
71 		status = _FAIL;
72 	return status;
73 }
74 
iol_InitLLTTable(struct adapter * padapter,u8 txpktbuf_bndy)75 static s32 iol_InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
76 {
77 	s32 rst = _SUCCESS;
78 	iol_mode_enable(padapter, 1);
79 	rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
80 	rst = iol_execute(padapter, CMD_INIT_LLT);
81 	iol_mode_enable(padapter, 0);
82 	return rst;
83 }
84 
85 static void
efuse_phymap_to_logical(u8 * phymap,u16 _size_byte,u8 * pbuf)86 efuse_phymap_to_logical(u8 *phymap, u16 _size_byte, u8  *pbuf)
87 {
88 	u8 *efuseTbl = NULL;
89 	u8 rtemp8;
90 	u16	eFuse_Addr = 0;
91 	u8 offset, wren;
92 	u16	i, j;
93 	u16	**eFuseWord = NULL;
94 	u8 u1temp = 0;
95 
96 	efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
97 	if (!efuseTbl)
98 		goto exit;
99 
100 	eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
101 	if (!eFuseWord)
102 		goto exit;
103 
104 	/*  0. Refresh efuse init map as all oxFF. */
105 	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
106 		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
107 			eFuseWord[i][j] = 0xFFFF;
108 
109 	/*  */
110 	/*  1. Read the first byte to check if efuse is empty!!! */
111 	/*  */
112 	/*  */
113 	rtemp8 = *(phymap + eFuse_Addr);
114 	if (rtemp8 != 0xFF) {
115 		eFuse_Addr++;
116 	} else {
117 		goto exit;
118 	}
119 
120 	/*  */
121 	/*  2. Read real efuse content. Filter PG header and every section data. */
122 	/*  */
123 	while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
124 		/*  Check PG header for section num. */
125 		if ((rtemp8 & 0x1F) == 0x0F) {		/* extended header */
126 			u1temp = ((rtemp8 & 0xE0) >> 5);
127 			rtemp8 = *(phymap + eFuse_Addr);
128 			if ((rtemp8 & 0x0F) == 0x0F) {
129 				eFuse_Addr++;
130 				rtemp8 = *(phymap + eFuse_Addr);
131 
132 				if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
133 					eFuse_Addr++;
134 				continue;
135 			} else {
136 				offset = ((rtemp8 & 0xF0) >> 1) | u1temp;
137 				wren = (rtemp8 & 0x0F);
138 				eFuse_Addr++;
139 			}
140 		} else {
141 			offset = ((rtemp8 >> 4) & 0x0f);
142 			wren = (rtemp8 & 0x0f);
143 		}
144 
145 		if (offset < EFUSE_MAX_SECTION_88E) {
146 			/*  Get word enable value from PG header */
147 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
148 				/*  Check word enable condition in the section */
149 				if (!(wren & 0x01)) {
150 					rtemp8 = *(phymap + eFuse_Addr);
151 					eFuse_Addr++;
152 					eFuseWord[offset][i] = (rtemp8 & 0xff);
153 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
154 						break;
155 					rtemp8 = *(phymap + eFuse_Addr);
156 					eFuse_Addr++;
157 					eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);
158 
159 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
160 						break;
161 				}
162 				wren >>= 1;
163 			}
164 		}
165 		/*  Read next PG header */
166 		rtemp8 = *(phymap + eFuse_Addr);
167 
168 		if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
169 			eFuse_Addr++;
170 		}
171 	}
172 
173 	/*  */
174 	/*  3. Collect 16 sections and 4 word unit into Efuse map. */
175 	/*  */
176 	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
177 		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
178 			efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
179 			efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
180 		}
181 	}
182 
183 	/*  */
184 	/*  4. Copy from Efuse map to output pointer memory!!! */
185 	/*  */
186 	memcpy(pbuf, efuseTbl, _size_byte);
187 
188 exit:
189 	kfree(efuseTbl);
190 	kfree(eFuseWord);
191 }
192 
193 /* FIXME: add error handling in callers */
efuse_read_phymap_from_txpktbuf(struct adapter * adapter,u8 * content,u16 * size)194 static int efuse_read_phymap_from_txpktbuf(
195 	struct adapter  *adapter,
196 	u8 *content,	/* buffer to store efuse physical map */
197 	u16 *size	/* for efuse content: the max byte to read. will update to byte read */
198 	)
199 {
200 	unsigned long timeout;
201 	__le32 lo32 = 0, hi32 = 0;
202 	u16 len = 0, count = 0;
203 	int i = 0, res;
204 	u16 limit = *size;
205 	u8 reg;
206 	u8 *pos = content;
207 	u32 reg32;
208 
209 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
210 
211 	while (1) {
212 		rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, i);
213 
214 		rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
215 		timeout = jiffies + msecs_to_jiffies(1000);
216 		do {
217 			res = rtw_read8(adapter, REG_TXPKTBUF_DBG, &reg);
218 			if (res)
219 				continue;
220 
221 			if (reg)
222 				break;
223 
224 			msleep(1);
225 		} while (time_before(jiffies, timeout));
226 
227 		/* data from EEPROM needs to be in LE */
228 		res = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, &reg32);
229 		if (res)
230 			return res;
231 
232 		lo32 = cpu_to_le32(reg32);
233 
234 		res = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, &reg32);
235 		if (res)
236 			return res;
237 
238 		hi32 = cpu_to_le32(reg32);
239 
240 		if (i == 0) {
241 			u16 reg;
242 
243 			/* Although lenc is only used in a debug statement,
244 			 * do not remove it as the rtw_read16() call consumes
245 			 * 2 bytes from the EEPROM source.
246 			 */
247 			res = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, &reg);
248 			if (res)
249 				return res;
250 
251 			len = le32_to_cpu(lo32) & 0x0000ffff;
252 
253 			limit = (len - 2 < limit) ? len - 2 : limit;
254 
255 			memcpy(pos, ((u8 *)&lo32) + 2, (limit >= count + 2) ? 2 : limit - count);
256 			count += (limit >= count + 2) ? 2 : limit - count;
257 			pos = content + count;
258 		} else {
259 			memcpy(pos, ((u8 *)&lo32), (limit >= count + 4) ? 4 : limit - count);
260 			count += (limit >= count + 4) ? 4 : limit - count;
261 			pos = content + count;
262 		}
263 
264 		if (limit > count && len - 2 > count) {
265 			memcpy(pos, (u8 *)&hi32, (limit >= count + 4) ? 4 : limit - count);
266 			count += (limit >= count + 4) ? 4 : limit - count;
267 			pos = content + count;
268 		}
269 
270 		if (limit <= count || len - 2 <= count)
271 			break;
272 		i++;
273 	}
274 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
275 	*size = count;
276 
277 	return 0;
278 }
279 
iol_read_efuse(struct adapter * padapter,u16 size_byte,u8 * logical_map)280 static s32 iol_read_efuse(struct adapter *padapter, u16 size_byte, u8 *logical_map)
281 {
282 	s32 status = _FAIL;
283 	u8 physical_map[512];
284 	u16 size = 512;
285 
286 	rtw_write8(padapter, REG_TDECTRL + 1, 0);
287 	memset(physical_map, 0xFF, 512);
288 	rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
289 	status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
290 	if (status == _SUCCESS)
291 		efuse_read_phymap_from_txpktbuf(padapter, physical_map, &size);
292 	efuse_phymap_to_logical(physical_map, size_byte, logical_map);
293 	return status;
294 }
295 
rtl8188e_iol_efuse_patch(struct adapter * padapter)296 s32 rtl8188e_iol_efuse_patch(struct adapter *padapter)
297 {
298 	s32	result = _SUCCESS;
299 
300 	if (rtw_IOL_applied(padapter)) {
301 		iol_mode_enable(padapter, 1);
302 		result = iol_execute(padapter, CMD_READ_EFUSE_MAP);
303 		if (result == _SUCCESS)
304 			result = iol_execute(padapter, CMD_EFUSE_PATCH);
305 
306 		iol_mode_enable(padapter, 0);
307 	}
308 	return result;
309 }
310 
iol_ioconfig(struct adapter * padapter,u8 iocfg_bndy)311 static s32 iol_ioconfig(struct adapter *padapter, u8 iocfg_bndy)
312 {
313 	s32 rst = _SUCCESS;
314 
315 	rtw_write8(padapter, REG_TDECTRL + 1, iocfg_bndy);
316 	rst = iol_execute(padapter, CMD_IOCONFIG);
317 	return rst;
318 }
319 
rtl8188e_IOL_exec_cmds_sync(struct adapter * adapter,struct xmit_frame * xmit_frame,u32 max_wating_ms,u32 bndy_cnt)320 int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
321 {
322 	struct pkt_attrib *pattrib = &xmit_frame->attrib;
323 	u8 i;
324 	int ret = _FAIL;
325 
326 	if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
327 		goto exit;
328 	if (rtw_usb_bulk_size_boundary(adapter, TXDESC_SIZE + pattrib->last_txcmdsz)) {
329 		if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
330 			goto exit;
331 	}
332 
333 	dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms);
334 
335 	iol_mode_enable(adapter, 1);
336 	for (i = 0; i < bndy_cnt; i++) {
337 		u8 page_no = 0;
338 		page_no = i * 2;
339 		ret = iol_ioconfig(adapter, page_no);
340 		if (ret != _SUCCESS)
341 			break;
342 	}
343 	iol_mode_enable(adapter, 0);
344 exit:
345 	/* restore BCN_HEAD */
346 	rtw_write8(adapter, REG_TDECTRL + 1, 0);
347 	return ret;
348 }
349 
rtl8188e_EfusePowerSwitch(struct adapter * pAdapter,u8 PwrState)350 void rtl8188e_EfusePowerSwitch(struct adapter *pAdapter, u8 PwrState)
351 {
352 	u16	tmpV16;
353 	int res;
354 
355 	if (PwrState) {
356 		rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
357 
358 		/*  1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
359 		res = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16);
360 		if (res)
361 			return;
362 
363 		if (!(tmpV16 & PWC_EV12V)) {
364 			tmpV16 |= PWC_EV12V;
365 			rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
366 		}
367 		/*  Reset: 0x0000h[28], default valid */
368 		res = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &tmpV16);
369 		if (res)
370 			return;
371 
372 		if (!(tmpV16 & FEN_ELDR)) {
373 			tmpV16 |= FEN_ELDR;
374 			rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
375 		}
376 
377 		/*  Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
378 		res = rtw_read16(pAdapter, REG_SYS_CLKR, &tmpV16);
379 		if (res)
380 			return;
381 
382 		if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
383 			tmpV16 |= (LOADER_CLK_EN | ANA8M);
384 			rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
385 		}
386 	} else {
387 		rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
388 	}
389 }
390 
Hal_EfuseReadEFuse88E(struct adapter * Adapter,u16 _offset,u16 _size_byte,u8 * pbuf)391 static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
392 	u16			_offset,
393 	u16			_size_byte,
394 	u8 *pbuf)
395 {
396 	u8 *efuseTbl = NULL;
397 	u8 rtemp8[1];
398 	u16	eFuse_Addr = 0;
399 	u8 offset, wren;
400 	u16	i, j;
401 	u16	**eFuseWord = NULL;
402 	u16	efuse_utilized = 0;
403 	u8 u1temp = 0;
404 
405 	/*  */
406 	/*  Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
407 	/*  */
408 	if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) /*  total E-Fuse table is 512bytes */
409 		goto exit;
410 
411 	efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
412 	if (!efuseTbl)
413 		goto exit;
414 
415 	eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
416 	if (!eFuseWord)
417 		goto exit;
418 
419 	/*  0. Refresh efuse init map as all oxFF. */
420 	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
421 		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
422 			eFuseWord[i][j] = 0xFFFF;
423 
424 	/*  */
425 	/*  1. Read the first byte to check if efuse is empty!!! */
426 	/*  */
427 	/*  */
428 	ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
429 	if (*rtemp8 != 0xFF) {
430 		efuse_utilized++;
431 		eFuse_Addr++;
432 	} else {
433 		goto exit;
434 	}
435 
436 	/*  */
437 	/*  2. Read real efuse content. Filter PG header and every section data. */
438 	/*  */
439 	while ((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
440 		/*  Check PG header for section num. */
441 		if ((*rtemp8 & 0x1F) == 0x0F) {		/* extended header */
442 			u1temp = ((*rtemp8 & 0xE0) >> 5);
443 
444 			ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
445 
446 			if ((*rtemp8 & 0x0F) == 0x0F) {
447 				eFuse_Addr++;
448 				ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
449 
450 				if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
451 					eFuse_Addr++;
452 				continue;
453 			} else {
454 				offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
455 				wren = (*rtemp8 & 0x0F);
456 				eFuse_Addr++;
457 			}
458 		} else {
459 			offset = ((*rtemp8 >> 4) & 0x0f);
460 			wren = (*rtemp8 & 0x0f);
461 		}
462 
463 		if (offset < EFUSE_MAX_SECTION_88E) {
464 			/*  Get word enable value from PG header */
465 
466 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
467 				/*  Check word enable condition in the section */
468 				if (!(wren & 0x01)) {
469 					ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
470 					eFuse_Addr++;
471 					efuse_utilized++;
472 					eFuseWord[offset][i] = (*rtemp8 & 0xff);
473 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
474 						break;
475 					ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
476 					eFuse_Addr++;
477 					efuse_utilized++;
478 					eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
479 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
480 						break;
481 				}
482 				wren >>= 1;
483 			}
484 		}
485 
486 		/*  Read next PG header */
487 		ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
488 
489 		if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
490 			efuse_utilized++;
491 			eFuse_Addr++;
492 		}
493 	}
494 
495 	/*  3. Collect 16 sections and 4 word unit into Efuse map. */
496 	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
497 		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
498 			efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
499 			efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
500 		}
501 	}
502 
503 	/*  4. Copy from Efuse map to output pointer memory!!! */
504 	for (i = 0; i < _size_byte; i++)
505 		pbuf[i] = efuseTbl[_offset + i];
506 
507 exit:
508 	kfree(efuseTbl);
509 	kfree(eFuseWord);
510 }
511 
rtl8188e_ReadEFuse(struct adapter * Adapter,u16 _size_byte,u8 * pbuf)512 void rtl8188e_ReadEFuse(struct adapter *Adapter, u16 _size_byte, u8 *pbuf)
513 {
514 	int ret = _FAIL;
515 	if (rtw_IOL_applied(Adapter)) {
516 		rtl8188eu_InitPowerOn(Adapter);
517 
518 		iol_mode_enable(Adapter, 1);
519 		ret = iol_read_efuse(Adapter, _size_byte, pbuf);
520 		iol_mode_enable(Adapter, 0);
521 
522 		if (_SUCCESS == ret)
523 			return;
524 	}
525 
526 	Hal_EfuseReadEFuse88E(Adapter, 0, _size_byte, pbuf);
527 }
528 
dump_chip_info(struct adapter * adapter,struct HAL_VERSION chip_vers)529 static void dump_chip_info(struct adapter *adapter, struct HAL_VERSION chip_vers)
530 {
531 	struct net_device *netdev = adapter->pnetdev;
532 	char *cut = NULL;
533 	char buf[25];
534 
535 	switch (chip_vers.CUTVersion) {
536 	case A_CUT_VERSION:
537 		cut = "A_CUT";
538 		break;
539 	case B_CUT_VERSION:
540 		cut = "B_CUT";
541 		break;
542 	case C_CUT_VERSION:
543 		cut = "C_CUT";
544 		break;
545 	case D_CUT_VERSION:
546 		cut = "D_CUT";
547 		break;
548 	case E_CUT_VERSION:
549 		cut = "E_CUT";
550 		break;
551 	default:
552 		snprintf(buf, sizeof(buf), "UNKNOWN_CUT(%d)", chip_vers.CUTVersion);
553 		cut = buf;
554 		break;
555 	}
556 
557 	netdev_dbg(netdev, "Chip Version Info: CHIP_8188E_%s_%s_%s_1T1R_RomVer(%d)\n",
558 		   IS_NORMAL_CHIP(chip_vers) ? "Normal_Chip" : "Test_Chip",
559 		   IS_CHIP_VENDOR_TSMC(chip_vers) ? "TSMC" : "UMC",
560 		   cut, 0);
561 }
562 
rtl8188e_read_chip_version(struct adapter * padapter)563 void rtl8188e_read_chip_version(struct adapter *padapter)
564 {
565 	u32				value32;
566 	struct HAL_VERSION		ChipVersion;
567 	struct hal_data_8188e *pHalData = &padapter->haldata;
568 	int res;
569 
570 	res = rtw_read32(padapter, REG_SYS_CFG, &value32);
571 	if (res)
572 		return;
573 
574 	ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
575 
576 	ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
577 	ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /*  IC version (CUT) */
578 
579 	dump_chip_info(padapter, ChipVersion);
580 
581 	pHalData->VersionID = ChipVersion;
582 }
583 
rtl8188e_SetHalODMVar(struct adapter * Adapter,void * pValue1,bool bSet)584 void rtl8188e_SetHalODMVar(struct adapter *Adapter, void *pValue1, bool bSet)
585 {
586 	struct hal_data_8188e *pHalData = &Adapter->haldata;
587 	struct odm_dm_struct *podmpriv = &pHalData->odmpriv;
588 	struct sta_info *psta = (struct sta_info *)pValue1;
589 
590 	if (bSet) {
591 		podmpriv->pODM_StaInfo[psta->mac_id] = psta;
592 		ODM_RAInfo_Init(podmpriv, psta->mac_id);
593 	} else {
594 		podmpriv->pODM_StaInfo[psta->mac_id] = NULL;
595 	}
596 }
597 
hal_notch_filter_8188e(struct adapter * adapter,bool enable)598 void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
599 {
600 	int res;
601 	u8 reg;
602 
603 	res = rtw_read8(adapter, rOFDM0_RxDSP + 1, &reg);
604 	if (res)
605 		return;
606 
607 	if (enable)
608 		rtw_write8(adapter, rOFDM0_RxDSP + 1, reg | BIT(1));
609 	else
610 		rtw_write8(adapter, rOFDM0_RxDSP + 1, reg & ~BIT(1));
611 }
612 
613 /*  */
614 /*  */
615 /*  LLT R/W/Init function */
616 /*  */
617 /*  */
_LLTWrite(struct adapter * padapter,u32 address,u32 data)618 static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
619 {
620 	s32	count;
621 	u32	value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
622 	u16	LLTReg = REG_LLT_INIT;
623 	int res;
624 
625 	rtw_write32(padapter, LLTReg, value);
626 
627 	/* polling */
628 	for (count = 0; count <= POLLING_LLT_THRESHOLD; count++) {
629 		res = rtw_read32(padapter, LLTReg, &value);
630 		if (res)
631 			continue;
632 
633 		if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
634 			break;
635 	}
636 
637 	return count > POLLING_LLT_THRESHOLD ? _FAIL : _SUCCESS;
638 }
639 
InitLLTTable(struct adapter * padapter,u8 txpktbuf_bndy)640 s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
641 {
642 	s32	status = _FAIL;
643 	u32	i;
644 	u32	Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;/*  176, 22k */
645 
646 	if (rtw_IOL_applied(padapter)) {
647 		status = iol_InitLLTTable(padapter, txpktbuf_bndy);
648 	} else {
649 		for (i = 0; i < (txpktbuf_bndy - 1); i++) {
650 			status = _LLTWrite(padapter, i, i + 1);
651 			if (_SUCCESS != status)
652 				return status;
653 		}
654 
655 		/*  end of list */
656 		status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
657 		if (_SUCCESS != status)
658 			return status;
659 
660 		/*  Make the other pages as ring buffer */
661 		/*  This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer. */
662 		/*  Otherwise used as local loopback buffer. */
663 		for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
664 			status = _LLTWrite(padapter, i, (i + 1));
665 			if (_SUCCESS != status)
666 				return status;
667 		}
668 
669 		/*  Let last entry point to the start entry of ring buffer */
670 		status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
671 		if (_SUCCESS != status) {
672 			return status;
673 		}
674 	}
675 
676 	return status;
677 }
678 
679 void
Hal_EfuseParseIDCode88E(struct adapter * padapter,u8 * hwinfo)680 Hal_EfuseParseIDCode88E(
681 		struct adapter *padapter,
682 		u8 *hwinfo
683 	)
684 {
685 	struct eeprom_priv *pEEPROM = &padapter->eeprompriv;
686 	struct net_device *netdev = padapter->pnetdev;
687 	u16			EEPROMId;
688 
689 	/*  Check 0x8129 again for making sure autoload status!! */
690 	EEPROMId = le16_to_cpu(*((__le16 *)hwinfo));
691 	if (EEPROMId != RTL_EEPROM_ID) {
692 		pr_err("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
693 		pEEPROM->bautoload_fail_flag = true;
694 	} else {
695 		pEEPROM->bautoload_fail_flag = false;
696 	}
697 
698 	netdev_dbg(netdev, "EEPROM ID = 0x%04x\n", EEPROMId);
699 }
700 
Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g * pwrInfo24G,u8 * PROMContent,bool AutoLoadFail)701 static void Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g *pwrInfo24G, u8 *PROMContent, bool AutoLoadFail)
702 {
703 	u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_88E, group, TxCount = 0;
704 
705 	memset(pwrInfo24G, 0, sizeof(struct txpowerinfo24g));
706 
707 	if (AutoLoadFail) {
708 		for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
709 			/* 2.4G default value */
710 			for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
711 				pwrInfo24G->IndexCCK_Base[rfPath][group] =	EEPROM_DEFAULT_24G_INDEX;
712 				pwrInfo24G->IndexBW40_Base[rfPath][group] =	EEPROM_DEFAULT_24G_INDEX;
713 			}
714 			for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
715 				if (TxCount == 0) {
716 					pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF;
717 					pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF;
718 				} else {
719 					pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
720 					pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
721 					pwrInfo24G->CCK_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_DIFF;
722 					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
723 				}
724 			}
725 		}
726 		return;
727 	}
728 
729 	for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
730 		/* 2.4G default value */
731 		for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
732 			pwrInfo24G->IndexCCK_Base[rfPath][group] =	PROMContent[eeAddr++];
733 			if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
734 				pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
735 		}
736 		for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
737 			pwrInfo24G->IndexBW40_Base[rfPath][group] =	PROMContent[eeAddr++];
738 			if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
739 				pwrInfo24G->IndexBW40_Base[rfPath][group] =	EEPROM_DEFAULT_24G_INDEX;
740 		}
741 		for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
742 			if (TxCount == 0) {
743 				pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
744 				if (PROMContent[eeAddr] == 0xFF) {
745 					pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_HT20_DIFF;
746 				} else {
747 					pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4;
748 					if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3))		/* 4bit sign number to 8 bit sign number */
749 						pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
750 				}
751 
752 				if (PROMContent[eeAddr] == 0xFF) {
753 					pwrInfo24G->OFDM_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_24G_OFDM_DIFF;
754 				} else {
755 					pwrInfo24G->OFDM_Diff[rfPath][TxCount] =	(PROMContent[eeAddr] & 0x0f);
756 					if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3))		/* 4bit sign number to 8 bit sign number */
757 						pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
758 				}
759 				pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
760 				eeAddr++;
761 			} else {
762 				if (PROMContent[eeAddr] == 0xFF) {
763 					pwrInfo24G->BW40_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_DIFF;
764 				} else {
765 					pwrInfo24G->BW40_Diff[rfPath][TxCount] =	(PROMContent[eeAddr] & 0xf0) >> 4;
766 					if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT(3))		/* 4bit sign number to 8 bit sign number */
767 						pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
768 				}
769 
770 				if (PROMContent[eeAddr] == 0xFF) {
771 					pwrInfo24G->BW20_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_DIFF;
772 				} else {
773 					pwrInfo24G->BW20_Diff[rfPath][TxCount] =	(PROMContent[eeAddr] & 0x0f);
774 					if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3))		/* 4bit sign number to 8 bit sign number */
775 						pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
776 				}
777 				eeAddr++;
778 
779 				if (PROMContent[eeAddr] == 0xFF) {
780 					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
781 				} else {
782 					pwrInfo24G->OFDM_Diff[rfPath][TxCount] =	(PROMContent[eeAddr] & 0xf0) >> 4;
783 					if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3))		/* 4bit sign number to 8 bit sign number */
784 						pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
785 				}
786 
787 				if (PROMContent[eeAddr] == 0xFF) {
788 					pwrInfo24G->CCK_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_DIFF;
789 				} else {
790 					pwrInfo24G->CCK_Diff[rfPath][TxCount] =	(PROMContent[eeAddr] & 0x0f);
791 					if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT(3))		/* 4bit sign number to 8 bit sign number */
792 						pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
793 				}
794 				eeAddr++;
795 			}
796 		}
797 	}
798 }
799 
hal_get_chnl_group_88e(u8 chnl,u8 * group)800 static void hal_get_chnl_group_88e(u8 chnl, u8 *group)
801 {
802 	if (chnl < 3)			/*  Channel 1-2 */
803 		*group = 0;
804 	else if (chnl < 6)		/*  Channel 3-5 */
805 		*group = 1;
806 	else if (chnl < 9)		/*  Channel 6-8 */
807 		*group = 2;
808 	else if (chnl < 12)		/*  Channel 9-11 */
809 		*group = 3;
810 	else if (chnl < 14)		/*  Channel 12-13 */
811 		*group = 4;
812 	else if (chnl == 14)		/*  Channel 14 */
813 		*group = 5;
814 }
815 
Hal_ReadPowerSavingMode88E(struct adapter * padapter,u8 * hwinfo,bool AutoLoadFail)816 void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
817 {
818 	if (AutoLoadFail)
819 		padapter->pwrctrlpriv.bSupportRemoteWakeup = false;
820 	else
821 		/* hw power down mode selection , 0:rf-off / 1:power down */
822 
823 		/*  decide hw if support remote wakeup function */
824 		/*  if hw supported, 8051 (SIE) will generate WeakUP signal(D+/D- toggle) when autoresume */
825 		padapter->pwrctrlpriv.bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT(1)) ? true : false;
826 }
827 
Hal_ReadTxPowerInfo88E(struct adapter * padapter,u8 * PROMContent,bool AutoLoadFail)828 void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail)
829 {
830 	struct hal_data_8188e *pHalData = &padapter->haldata;
831 	struct txpowerinfo24g pwrInfo24G;
832 	u8 ch, group;
833 	u8 TxCount;
834 
835 	Hal_ReadPowerValueFromPROM_8188E(&pwrInfo24G, PROMContent, AutoLoadFail);
836 
837 	for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
838 		hal_get_chnl_group_88e(ch, &group);
839 
840 		pHalData->Index24G_CCK_Base[ch] = pwrInfo24G.IndexCCK_Base[0][group];
841 		if (ch == 14)
842 			pHalData->Index24G_BW40_Base[ch] = pwrInfo24G.IndexBW40_Base[0][4];
843 		else
844 			pHalData->Index24G_BW40_Base[ch] = pwrInfo24G.IndexBW40_Base[0][group];
845 	}
846 	for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
847 		pHalData->OFDM_24G_Diff[TxCount] = pwrInfo24G.OFDM_Diff[0][TxCount];
848 		pHalData->BW20_24G_Diff[TxCount] = pwrInfo24G.BW20_Diff[0][TxCount];
849 	}
850 
851 	/*  2010/10/19 MH Add Regulator recognize for CU. */
852 	if (!AutoLoadFail) {
853 		pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x7);	/* bit0~2 */
854 		if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
855 			pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7);	/* bit0~2 */
856 	} else {
857 		pHalData->EEPROMRegulatory = 0;
858 	}
859 }
860 
Hal_EfuseParseXtal_8188E(struct adapter * pAdapter,u8 * hwinfo,bool AutoLoadFail)861 void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
862 {
863 	struct hal_data_8188e *pHalData = &pAdapter->haldata;
864 
865 	if (!AutoLoadFail) {
866 		pHalData->CrystalCap = hwinfo[EEPROM_XTAL_88E];
867 		if (pHalData->CrystalCap == 0xFF)
868 			pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
869 	} else {
870 		pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
871 	}
872 }
873 
rtl8188e_EfuseParseChnlPlan(struct adapter * padapter,u8 * hwinfo,bool AutoLoadFail)874 void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
875 {
876 	padapter->mlmepriv.ChannelPlan =
877 		 hal_com_get_channel_plan(padapter,
878 					  hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF,
879 					  padapter->registrypriv.channel_plan,
880 					  RT_CHANNEL_DOMAIN_WORLD_WIDE_13, AutoLoadFail);
881 }
882 
Hal_ReadAntennaDiversity88E(struct adapter * pAdapter,u8 * PROMContent,bool AutoLoadFail)883 void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail)
884 {
885 	struct hal_data_8188e *pHalData = &pAdapter->haldata;
886 	struct registry_priv	*registry_par = &pAdapter->registrypriv;
887 
888 	if (!AutoLoadFail) {
889 		/*  Antenna Diversity setting. */
890 		if (registry_par->antdiv_cfg == 2) { /*  2:By EFUSE */
891 			pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x18) >> 3;
892 			if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
893 				pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION & 0x18) >> 3;
894 		} else {
895 			pHalData->AntDivCfg = registry_par->antdiv_cfg;  /*  0:OFF , 1:ON, 2:By EFUSE */
896 		}
897 
898 		if (registry_par->antdiv_type == 0) {
899 			/* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */
900 			pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E];
901 			if (pHalData->TRxAntDivType == 0xFF)
902 				pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; /*  For 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */
903 		} else {
904 			pHalData->TRxAntDivType = registry_par->antdiv_type;
905 		}
906 
907 		if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV)
908 			pHalData->AntDivCfg = 1; /*  0xC1[3] is ignored. */
909 	} else {
910 		pHalData->AntDivCfg = 0;
911 	}
912 }
913 
Hal_ReadThermalMeter_88E(struct adapter * Adapter,u8 * PROMContent,bool AutoloadFail)914 void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail)
915 {
916 	struct hal_data_8188e *pHalData = &Adapter->haldata;
917 
918 	/*  ThermalMeter from EEPROM */
919 	if (!AutoloadFail)
920 		pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_88E];
921 	else
922 		pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
923 
924 	if (pHalData->EEPROMThermalMeter == 0xff || AutoloadFail)
925 		pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
926 }
927