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