xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8188eu/hal/rtl8188e/rtl8188e_hal_init.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2017 Realtek Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of version 2 of the GNU General Public License as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  *****************************************************************************/
16 #define _HAL_INIT_C_
17 
18 #include <drv_types.h>
19 #include <rtl8188e_hal.h>
20 #ifdef CONFIG_SFW_SUPPORTED
21 #include "hal8188e_s_fw.h"
22 #endif
23 #include "hal8188e_t_fw.h"
24 
25 
26 #if defined(CONFIG_IOL)
iol_mode_enable(PADAPTER padapter,u8 enable)27 static void iol_mode_enable(PADAPTER padapter, u8 enable)
28 {
29 	u8 reg_0xf0 = 0;
30 
31 	if (enable) {
32 		/* Enable initial offload */
33 		reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
34 		/* RTW_INFO("%s reg_0xf0:0x%02x, write 0x%02x\n", __FUNCTION__, reg_0xf0, reg_0xf0|SW_OFFLOAD_EN); */
35 		rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
36 
37 		if (GET_HAL_DATA(padapter)->bFWReady == _FALSE) {
38 			printk("bFWReady == _FALSE call reset 8051...\n");
39 			_8051Reset88E(padapter);
40 		}
41 
42 	} else {
43 		/* disable initial offload */
44 		reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
45 		/* RTW_INFO("%s reg_0xf0:0x%02x, write 0x%02x\n", __FUNCTION__, reg_0xf0, reg_0xf0& ~SW_OFFLOAD_EN); */
46 		rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
47 	}
48 }
49 
iol_execute(PADAPTER padapter,u8 control)50 static s32 iol_execute(PADAPTER padapter, u8 control)
51 {
52 	s32 status = _FAIL;
53 	u8 reg_0x88 = 0, reg_1c7 = 0;
54 	systime start = 0;
55 	u32 passing_time = 0;
56 
57 	systime t1, t2;
58 	control = control & 0x0f;
59 	reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
60 	/* RTW_INFO("%s reg_0x88:0x%02x, write 0x%02x\n", __FUNCTION__, reg_0x88, reg_0x88|control); */
61 	rtw_write8(padapter, REG_HMEBOX_E0,  reg_0x88 | control);
62 
63 	t1 = start = rtw_get_current_time();
64 	while (
65 		/* (reg_1c7 = rtw_read8(padapter, 0x1c7) >1) && */
66 		(reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control
67 		&& (passing_time = rtw_get_passing_time_ms(start)) < 1000
68 	) {
69 		/* RTW_INFO("%s polling reg_0x88:0x%02x,reg_0x1c7:0x%02x\n", __FUNCTION__, reg_0x88,rtw_read8(padapter, 0x1c7) ); */
70 		/* rtw_udelay_os(100); */
71 	}
72 
73 	reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
74 	status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
75 	if (reg_0x88 & control << 4)
76 		status = _FAIL;
77 	t2 = rtw_get_current_time();
78 	/* printk("==> step iol_execute :  %5u reg-0x1c0= 0x%02x\n",rtw_get_time_interval_ms(t1,t2),rtw_read8(padapter, 0x1c0)); */
79 	/* RTW_INFO("%s in %u ms, reg_0x88:0x%02x\n", __FUNCTION__, passing_time, reg_0x88); */
80 
81 	return status;
82 }
83 
84 #ifdef CONFIG_IOL_LLT
iol_InitLLTTable(PADAPTER padapter,u8 txpktbuf_bndy)85 static s32 iol_InitLLTTable(
86 	PADAPTER padapter,
87 	u8 txpktbuf_bndy
88 )
89 {
90 	s32 rst = _SUCCESS;
91 	iol_mode_enable(padapter, 1);
92 	/* RTW_INFO("%s txpktbuf_bndy:%u\n", __FUNCTION__, txpktbuf_bndy); */
93 	rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
94 	rst = iol_execute(padapter, CMD_INIT_LLT);
95 	iol_mode_enable(padapter, 0);
96 	return rst;
97 }
98 #endif /*CONFIG_IOL_LLT*/
99 
100 static void
efuse_phymap_to_logical(u8 * phymap,u16 _offset,u16 _size_byte,u8 * pbuf)101 efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8  *pbuf)
102 {
103 	u8	*efuseTbl = NULL;
104 	u8	rtemp8;
105 	u16	eFuse_Addr = 0;
106 	u8	offset, wren;
107 	u16	i, j;
108 	u16	**eFuseWord = NULL;
109 	u16	efuse_utilized = 0;
110 	u8	efuse_usage = 0;
111 	u8	u1temp = 0;
112 
113 
114 	efuseTbl = (u8 *)rtw_zmalloc(EFUSE_MAP_LEN_88E);
115 	if (efuseTbl == NULL) {
116 		RTW_INFO("%s: alloc efuseTbl fail!\n", __FUNCTION__);
117 		goto exit;
118 	}
119 
120 	eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, 2);
121 	if (eFuseWord == NULL) {
122 		RTW_INFO("%s: alloc eFuseWord fail!\n", __FUNCTION__);
123 		goto exit;
124 	}
125 
126 	/* 0. Refresh efuse init map as all oxFF. */
127 	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
128 		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
129 			eFuseWord[i][j] = 0xFFFF;
130 
131 	/*  */
132 	/* 1. Read the first byte to check if efuse is empty!!! */
133 	/*  */
134 	/*  */
135 	rtemp8 = *(phymap + eFuse_Addr);
136 	if (rtemp8 != 0xFF) {
137 		efuse_utilized++;
138 		/* printk("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8); */
139 		eFuse_Addr++;
140 	} else {
141 		RTW_INFO("EFUSE is empty efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, rtemp8);
142 		goto exit;
143 	}
144 
145 
146 	/*  */
147 	/* 2. Read real efuse content. Filter PG header and every section data. */
148 	/*  */
149 	while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
150 		/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr-1, *rtemp8)); */
151 
152 		/* Check PG header for section num. */
153 		if ((rtemp8 & 0x1F) == 0x0F) {	/* extended header */
154 			u1temp = ((rtemp8 & 0xE0) >> 5);
155 			/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x *rtemp&0xE0 0x%x\n", u1temp, *rtemp8 & 0xE0)); */
156 
157 			/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x\n", u1temp)); */
158 
159 			rtemp8 = *(phymap + eFuse_Addr);
160 
161 			/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8));	 */
162 
163 			if ((rtemp8 & 0x0F) == 0x0F) {
164 				eFuse_Addr++;
165 				rtemp8 = *(phymap + eFuse_Addr);
166 
167 				if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
168 					eFuse_Addr++;
169 				continue;
170 			} else {
171 				offset = ((rtemp8 & 0xF0) >> 1) | u1temp;
172 				wren = (rtemp8 & 0x0F);
173 				eFuse_Addr++;
174 			}
175 		} else {
176 			offset = ((rtemp8 >> 4) & 0x0f);
177 			wren = (rtemp8 & 0x0f);
178 		}
179 
180 		if (offset < EFUSE_MAX_SECTION_88E) {
181 			/* Get word enable value from PG header */
182 			/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Offset-%d Worden=%x\n", offset, wren)); */
183 
184 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
185 				/* Check word enable condition in the section				 */
186 				if (!(wren & 0x01)) {
187 					/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d\n", eFuse_Addr)); */
188 					rtemp8 = *(phymap + eFuse_Addr);
189 					eFuse_Addr++;
190 					/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8)); 				 */
191 					efuse_utilized++;
192 					eFuseWord[offset][i] = (rtemp8 & 0xff);
193 
194 
195 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
196 						break;
197 
198 					/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d", eFuse_Addr)); */
199 					rtemp8 = *(phymap + eFuse_Addr);
200 					eFuse_Addr++;
201 					/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8)); 				 */
202 
203 					efuse_utilized++;
204 					eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);
205 
206 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
207 						break;
208 				}
209 
210 				wren >>= 1;
211 
212 			}
213 		}
214 
215 		/* Read next PG header */
216 		rtemp8 = *(phymap + eFuse_Addr);
217 		/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d rtemp 0x%x\n", eFuse_Addr, *rtemp8)); */
218 
219 		if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
220 			efuse_utilized++;
221 			eFuse_Addr++;
222 		}
223 	}
224 
225 	/*  */
226 	/* 3. Collect 16 sections and 4 word unit into Efuse map. */
227 	/*  */
228 	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
229 		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
230 			efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
231 			efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
232 		}
233 	}
234 
235 
236 	/*  */
237 	/* 4. Copy from Efuse map to output pointer memory!!! */
238 	/*  */
239 	for (i = 0; i < _size_byte; i++)
240 		pbuf[i] = efuseTbl[_offset + i];
241 
242 	/*  */
243 	/* 5. Calculate Efuse utilization. */
244 	/*  */
245 	efuse_usage = (u8)((efuse_utilized * 100) / EFUSE_REAL_CONTENT_LEN_88E);
246 	/* rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_utilized); */
247 
248 exit:
249 	if (efuseTbl)
250 		rtw_mfree(efuseTbl, EFUSE_MAP_LEN_88E);
251 
252 	if (eFuseWord)
253 		rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
254 }
255 
efuse_read_phymap_from_txpktbuf(ADAPTER * adapter,int bcnhead,u8 * content,u16 * size)256 void efuse_read_phymap_from_txpktbuf(
257 	ADAPTER *adapter,
258 	int bcnhead,	/* beacon head, where FW store len(2-byte) and efuse physical map. */
259 	u8 *content,	/* buffer to store efuse physical map */
260 	u16 *size	/* for efuse content: the max byte to read. will update to byte read */
261 )
262 {
263 	u16 dbg_addr = 0;
264 	systime start = 0;
265 	u32 passing_time = 0;
266 	u8 reg_0x143 = 0;
267 	u8 reg_0x106 = 0;
268 	u32 lo32 = 0, hi32 = 0;
269 	u16 len = 0, count = 0;
270 	int i = 0;
271 	u16 limit = *size;
272 
273 	u8 *pos = content;
274 
275 	if (bcnhead < 0) /* if not valid */
276 		bcnhead = rtw_read8(adapter, REG_TDECTRL + 1);
277 
278 	RTW_INFO("%s bcnhead:%d\n", __FUNCTION__, bcnhead);
279 
280 	/* reg_0x106 = rtw_read8(adapter, REG_PKT_BUFF_ACCESS_CTRL); */
281 	/* RTW_INFO("%s reg_0x106:0x%02x, write 0x%02x\n", __FUNCTION__, reg_0x106, 0x69); */
282 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
283 	/* RTW_INFO("%s reg_0x106:0x%02x\n", __FUNCTION__, rtw_read8(adapter, 0x106)); */
284 
285 	dbg_addr = bcnhead * 128 / 8; /* 8-bytes addressing */
286 
287 	while (1) {
288 		/* RTW_INFO("%s dbg_addr:0x%x\n", __FUNCTION__, dbg_addr+i); */
289 		rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr + i);
290 
291 		/* RTW_INFO("%s write reg_0x143:0x00\n", __FUNCTION__); */
292 		rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
293 		start = rtw_get_current_time();
294 		while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) /* dbg */
295 		       /* while(rtw_read8(adapter, REG_TXPKTBUF_DBG) & BIT0 */
296 		       && (passing_time = rtw_get_passing_time_ms(start)) < 1000
297 		      ) {
298 			RTW_INFO("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __FUNCTION__, reg_0x143, rtw_read8(adapter, 0x106));
299 			rtw_usleep_os(100);
300 		}
301 
302 
303 		lo32 = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
304 		hi32 = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
305 
306 #if 0
307 		RTW_INFO("%s lo32:0x%08x, %02x %02x %02x %02x\n", __FUNCTION__, lo32
308 			 , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L)
309 			 , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L + 1)
310 			 , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L + 2)
311 			 , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L + 3)
312 			);
313 		RTW_INFO("%s hi32:0x%08x, %02x %02x %02x %02x\n", __FUNCTION__, hi32
314 			 , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_H)
315 			 , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_H + 1)
316 			 , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_H + 2)
317 			 , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_H + 3)
318 			);
319 #endif
320 
321 		if (i == 0) {
322 #if 1 /* for debug */
323 			u8 lenc[2];
324 			u16 lenbak, aaabak;
325 			u16 aaa;
326 			lenc[0] = rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L);
327 			lenc[1] = rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L + 1);
328 
329 			aaabak = le16_to_cpup((u16 *)lenc);
330 			lenbak = le16_to_cpu(*((u16 *)lenc));
331 			aaa = le16_to_cpup((u16 *)&lo32);
332 #endif
333 			len = le16_to_cpu(*((u16 *)&lo32));
334 
335 			limit = (len - 2 < limit) ? len - 2 : limit;
336 
337 			RTW_INFO("%s len:%u, lenbak:%u, aaa:%u, aaabak:%u\n", __FUNCTION__, len, lenbak, aaa, aaabak);
338 
339 			_rtw_memcpy(pos, ((u8 *)&lo32) + 2, (limit >= count + 2) ? 2 : limit - count);
340 			count += (limit >= count + 2) ? 2 : limit - count;
341 			pos = content + count;
342 
343 		} else {
344 			_rtw_memcpy(pos, ((u8 *)&lo32), (limit >= count + 4) ? 4 : limit - count);
345 			count += (limit >= count + 4) ? 4 : limit - count;
346 			pos = content + count;
347 
348 
349 		}
350 
351 		if (limit > count && len - 2 > count) {
352 			_rtw_memcpy(pos, (u8 *)&hi32, (limit >= count + 4) ? 4 : limit - count);
353 			count += (limit >= count + 4) ? 4 : limit - count;
354 			pos = content + count;
355 		}
356 
357 		if (limit <= count || len - 2 <= count)
358 			break;
359 
360 		i++;
361 	}
362 
363 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
364 
365 	RTW_INFO("%s read count:%u\n", __FUNCTION__, count);
366 	*size = count;
367 
368 }
369 
370 
iol_read_efuse(PADAPTER padapter,u8 txpktbuf_bndy,u16 offset,u16 size_byte,u8 * logical_map)371 static s32 iol_read_efuse(
372 	PADAPTER padapter,
373 	u8 txpktbuf_bndy,
374 	u16 offset,
375 	u16 size_byte,
376 	u8 *logical_map
377 )
378 {
379 	s32 status = _FAIL;
380 	u8 reg_0x106 = 0;
381 	u8 physical_map[512];
382 	u16 size = 512;
383 	int i;
384 
385 
386 	rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
387 	_rtw_memset(physical_map, 0xFF, 512);
388 
389 	/* /reg_0x106 = rtw_read8(padapter, REG_PKT_BUFF_ACCESS_CTRL); */
390 	/* RTW_INFO("%s reg_0x106:0x%02x, write 0x%02x\n", __FUNCTION__, reg_0x106, 0x69); */
391 	rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
392 	/* RTW_INFO("%s reg_0x106:0x%02x\n", __FUNCTION__, rtw_read8(padapter, 0x106)); */
393 
394 	status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
395 
396 	if (status == _SUCCESS)
397 		efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size);
398 
399 #if 0
400 	RTW_PRINT("%s physical map\n", __FUNCTION__);
401 	for (i = 0; i < size; i++) {
402 		if (i % 16 == 0)
403 			RTW_PRINT("%02x", physical_map[i]);
404 		else
405 			_RTW_PRINT("%02x", physical_map[i]);
406 
407 		if (i % 16 == 7)
408 			_RTW_PRINT("    ");
409 		else if (i % 16 == 15)
410 			_RTW_PRINT("\n");
411 		else
412 			_RTW_PRINT(" ");
413 	}
414 	_RTW_PRINT("\n");
415 #endif
416 
417 	efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map);
418 
419 	return status;
420 }
421 
rtl8188e_iol_efuse_patch(PADAPTER padapter)422 s32 rtl8188e_iol_efuse_patch(PADAPTER padapter)
423 {
424 	s32	result = _SUCCESS;
425 	printk("==> %s\n", __FUNCTION__);
426 
427 	if (rtw_IOL_applied(padapter)) {
428 		iol_mode_enable(padapter, 1);
429 		result = iol_execute(padapter, CMD_READ_EFUSE_MAP);
430 		if (result == _SUCCESS)
431 			result = iol_execute(padapter, CMD_EFUSE_PATCH);
432 
433 		iol_mode_enable(padapter, 0);
434 	}
435 	return result;
436 }
437 
iol_ioconfig(PADAPTER padapter,u8 iocfg_bndy)438 static s32 iol_ioconfig(
439 	PADAPTER padapter,
440 	u8 iocfg_bndy
441 )
442 {
443 	s32 rst = _SUCCESS;
444 
445 	/* RTW_INFO("%s iocfg_bndy:%u\n", __FUNCTION__, iocfg_bndy); */
446 	rtw_write8(padapter, REG_TDECTRL + 1, iocfg_bndy);
447 	rst = iol_execute(padapter, CMD_IOCONFIG);
448 
449 	return rst;
450 }
451 
rtl8188e_IOL_exec_cmds_sync(ADAPTER * adapter,struct xmit_frame * xmit_frame,u32 max_wating_ms,u32 bndy_cnt)452 int rtl8188e_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
453 {
454 
455 	systime start_time = rtw_get_current_time();
456 	u32 passing_time_ms;
457 	u8 polling_ret, i;
458 	int ret = _FAIL;
459 	systime t1, t2;
460 
461 	/* printk("===> %s ,bndy_cnt = %d\n",__FUNCTION__,bndy_cnt); */
462 	if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
463 		goto exit;
464 #ifdef CONFIG_USB_HCI
465 	{
466 		struct pkt_attrib	*pattrib = &xmit_frame->attrib;
467 		if (rtw_usb_bulk_size_boundary(adapter, TXDESC_SIZE + pattrib->last_txcmdsz)) {
468 			if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
469 				goto exit;
470 		}
471 	}
472 #endif /* CONFIG_USB_HCI */
473 
474 	/* rtw_IOL_cmd_buf_dump(adapter,xmit_frame->attrib.pktlen+TXDESC_OFFSET,xmit_frame->buf_addr); */
475 	/* rtw_hal_mgnt_xmit(adapter, xmit_frame); */
476 	/* rtw_dump_xframe_sync(adapter, xmit_frame); */
477 
478 	dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms);
479 
480 	t1 =	rtw_get_current_time();
481 	iol_mode_enable(adapter, 1);
482 	for (i = 0; i < bndy_cnt; i++) {
483 		u8 page_no = 0;
484 		page_no = i * 2 ;
485 		/* printk(" i = %d, page_no = %d\n",i,page_no);	 */
486 		ret = iol_ioconfig(adapter, page_no);
487 		if (ret != _SUCCESS)
488 			break;
489 	}
490 	iol_mode_enable(adapter, 0);
491 	t2 = rtw_get_current_time();
492 	/* printk("==> %s :  %5u\n",__FUNCTION__,rtw_get_time_interval_ms(t1,t2)); */
493 exit:
494 	/* restore BCN_HEAD */
495 	rtw_write8(adapter, REG_TDECTRL + 1, 0);
496 	return ret;
497 }
498 
rtw_IOL_cmd_tx_pkt_buf_dump(ADAPTER * Adapter,int data_len)499 void rtw_IOL_cmd_tx_pkt_buf_dump(ADAPTER *Adapter, int data_len)
500 {
501 	u32 fifo_data, reg_140;
502 	u32 addr, rstatus, loop = 0;
503 
504 	u16 data_cnts = (data_len / 8) + 1;
505 	u8 *pbuf = rtw_zvmalloc(data_len + 10);
506 	printk("###### %s ######\n", __FUNCTION__);
507 
508 	rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
509 	if (pbuf) {
510 		for (addr = 0; addr < data_cnts; addr++) {
511 			/* printk("==> addr:0x%02x\n",addr); */
512 			rtw_write32(Adapter, 0x140, addr);
513 			rtw_usleep_os(2);
514 			loop = 0;
515 			do {
516 				rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT24);
517 				/* printk("rstatus = %02x, reg_140:0x%08x\n",rstatus,reg_140); */
518 				if (rstatus) {
519 					fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
520 					/* printk("fifo_data_144:0x%08x\n",fifo_data);					 */
521 					_rtw_memcpy(pbuf + (addr * 8), &fifo_data , 4);
522 
523 					fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
524 					/* printk("fifo_data_148:0x%08x\n",fifo_data);					 */
525 					_rtw_memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4);
526 
527 				}
528 				rtw_usleep_os(2);
529 			} while (!rstatus && (loop++ < 10));
530 		}
531 		rtw_IOL_cmd_buf_dump(Adapter, data_len, pbuf);
532 		rtw_vmfree(pbuf, data_len + 10);
533 
534 	}
535 	printk("###### %s ######\n", __FUNCTION__);
536 }
537 
538 #endif /* defined(CONFIG_IOL) */
539 
540 
541 static void
_FWDownloadEnable_8188E(PADAPTER padapter,BOOLEAN enable)542 _FWDownloadEnable_8188E(
543 		PADAPTER		padapter,
544 		BOOLEAN			enable
545 )
546 {
547 	u8	tmp;
548 
549 	if (enable) {
550 		/* MCU firmware download enable. */
551 		tmp = rtw_read8(padapter, REG_MCUFWDL);
552 		rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
553 
554 		/* 8051 reset */
555 		tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
556 		rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
557 	} else {
558 
559 		/* MCU firmware download disable. */
560 		tmp = rtw_read8(padapter, REG_MCUFWDL);
561 		rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
562 
563 		/* Reserved for fw extension. */
564 		rtw_write8(padapter, REG_MCUFWDL + 1, 0x00);
565 	}
566 }
567 #define MAX_REG_BOLCK_SIZE	196
568 static int
_BlockWrite(PADAPTER padapter,void * buffer,u32 buffSize)569 _BlockWrite(
570 			PADAPTER	padapter,
571 			void			*buffer,
572 			u32			buffSize
573 )
574 {
575 	int ret = _SUCCESS;
576 
577 	u32			blockSize_p1 = 4;	/* (Default) Phase #1 : PCI muse use 4-byte write to download FW */
578 	u32			blockSize_p2 = 8;	/* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */
579 	u32			blockSize_p3 = 1;	/* Phase #3 : Use 1-byte, the remnant of FW image. */
580 	u32			blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
581 	u32			remainSize_p1 = 0, remainSize_p2 = 0;
582 	u8			*bufferPtr	= (u8 *)buffer;
583 	u32			i = 0, offset = 0;
584 #ifdef CONFIG_PCI_HCI
585 	u8			remainFW[4] = {0, 0, 0, 0};
586 	u8			*p = NULL;
587 #endif
588 
589 #ifdef CONFIG_USB_HCI
590 	blockSize_p1 = MAX_REG_BOLCK_SIZE;
591 #endif
592 
593 	/* 3 Phase #1 */
594 	blockCount_p1 = buffSize / blockSize_p1;
595 	remainSize_p1 = buffSize % blockSize_p1;
596 
597 
598 
599 	for (i = 0; i < blockCount_p1; i++) {
600 #ifdef CONFIG_USB_HCI
601 		ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
602 #else
603 		ret = rtw_write32(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32 *)(bufferPtr + i * blockSize_p1))));
604 #endif
605 
606 		if (ret == _FAIL)
607 			goto exit;
608 	}
609 
610 #ifdef CONFIG_PCI_HCI
611 	p = (u8 *)((u32 *)(bufferPtr + blockCount_p1 * blockSize_p1));
612 	if (remainSize_p1) {
613 		switch (remainSize_p1) {
614 		case 0:
615 			break;
616 		case 3:
617 			remainFW[2] = *(p + 2);
618 		case 2:
619 			remainFW[1] = *(p + 1);
620 		case 1:
621 			remainFW[0] = *(p);
622 			ret = rtw_write32(padapter, (FW_8188E_START_ADDRESS + blockCount_p1 * blockSize_p1),
623 					  le32_to_cpu(*(u32 *)remainFW));
624 		}
625 		return ret;
626 	}
627 #endif
628 
629 	/* 3 Phase #2 */
630 	if (remainSize_p1) {
631 		offset = blockCount_p1 * blockSize_p1;
632 
633 		blockCount_p2 = remainSize_p1 / blockSize_p2;
634 		remainSize_p2 = remainSize_p1 % blockSize_p2;
635 
636 
637 
638 #ifdef CONFIG_USB_HCI
639 		for (i = 0; i < blockCount_p2; i++) {
640 			ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i * blockSize_p2), blockSize_p2, (bufferPtr + offset + i * blockSize_p2));
641 
642 			if (ret == _FAIL)
643 				goto exit;
644 		}
645 #endif
646 	}
647 
648 	/* 3 Phase #3 */
649 	if (remainSize_p2) {
650 		offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
651 
652 		blockCount_p3 = remainSize_p2 / blockSize_p3;
653 
654 
655 		for (i = 0 ; i < blockCount_p3 ; i++) {
656 			ret = rtw_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
657 
658 			if (ret == _FAIL)
659 				goto exit;
660 		}
661 	}
662 
663 exit:
664 	return ret;
665 }
666 
667 static int
_PageWrite(PADAPTER padapter,u32 page,void * buffer,u32 size)668 _PageWrite(
669 			PADAPTER	padapter,
670 			u32			page,
671 			void			*buffer,
672 			u32			size
673 )
674 {
675 	u8 value8;
676 	u8 u8Page = (u8)(page & 0x07) ;
677 
678 	value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page ;
679 	rtw_write8(padapter, REG_MCUFWDL + 2, value8);
680 
681 	return _BlockWrite(padapter, buffer, size);
682 }
683 /*
684 #ifdef CONFIG_PCI_HCI
685 static void
686 _FillDummy(
687 	u8		*pFwBuf,
688 	u32	*pFwLen
689 )
690 {
691 	u32	FwLen = *pFwLen;
692 	u8	remain = (u8)(FwLen % 4);
693 	remain = (remain == 0) ? 0 : (4 - remain);
694 
695 	while (remain > 0) {
696 		pFwBuf[FwLen] = 0;
697 		FwLen++;
698 		remain--;
699 	}
700 
701 	*pFwLen = FwLen;
702 }
703 #endif
704 */
705 static int
_WriteFW(PADAPTER padapter,void * buffer,u32 size)706 _WriteFW(
707 			PADAPTER	padapter,
708 			void			*buffer,
709 			u32			size
710 )
711 {
712 	/* Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */
713 	int ret = _SUCCESS;
714 	u32	pageNums, remainSize ;
715 	u32	page, offset;
716 	u8		*bufferPtr = (u8 *)buffer;
717 
718 #ifdef CONFIG_PCI_HCI
719 	/* 20100120 Joseph: Add for 88CE normal chip. */
720 	/* Fill in zero to make firmware image to dword alignment.
721 	*		_FillDummy(bufferPtr, &size); */
722 #endif
723 
724 	pageNums = size / MAX_DLFW_PAGE_SIZE ;
725 	/* RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4\n")); */
726 	remainSize = size % MAX_DLFW_PAGE_SIZE;
727 
728 	for (page = 0; page < pageNums; page++) {
729 		offset = page * MAX_DLFW_PAGE_SIZE;
730 		ret = _PageWrite(padapter, page, bufferPtr + offset, MAX_DLFW_PAGE_SIZE);
731 
732 		if (ret == _FAIL)
733 			goto exit;
734 	}
735 	if (remainSize) {
736 		offset = pageNums * MAX_DLFW_PAGE_SIZE;
737 		page = pageNums;
738 		ret = _PageWrite(padapter, page, bufferPtr + offset, remainSize);
739 
740 		if (ret == _FAIL)
741 			goto exit;
742 
743 	}
744 
745 exit:
746 	return ret;
747 }
748 
_MCUIO_Reset88E(PADAPTER padapter,u8 bReset)749 void _MCUIO_Reset88E(PADAPTER padapter, u8 bReset)
750 {
751 	u8 u1bTmp;
752 
753 	if (bReset == _TRUE) {
754 		u1bTmp = rtw_read8(padapter, REG_RSV_CTRL);
755 		rtw_write8(padapter, REG_RSV_CTRL, (u1bTmp & (~BIT1)));
756 		/* Reset MCU IO Wrapper- sugggest by SD1-Gimmy */
757 		u1bTmp = rtw_read8(padapter, REG_RSV_CTRL + 1);
758 		rtw_write8(padapter, REG_RSV_CTRL + 1, (u1bTmp & (~BIT3)));
759 	} else {
760 		u1bTmp = rtw_read8(padapter, REG_RSV_CTRL);
761 		rtw_write8(padapter, REG_RSV_CTRL, (u1bTmp & (~BIT1)));
762 		/* Enable MCU IO Wrapper */
763 		u1bTmp = rtw_read8(padapter, REG_RSV_CTRL + 1);
764 		rtw_write8(padapter, REG_RSV_CTRL + 1, u1bTmp | BIT3);
765 	}
766 
767 }
768 
_8051Reset88E(PADAPTER padapter)769 void _8051Reset88E(PADAPTER padapter)
770 {
771 	u8 u1bTmp;
772 
773 	_MCUIO_Reset88E(padapter, _TRUE);
774 	u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
775 	rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT2));
776 	_MCUIO_Reset88E(padapter, _FALSE);
777 	rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT2));
778 
779 	RTW_INFO("=====> _8051Reset88E(): 8051 reset success .\n");
780 }
781 
polling_fwdl_chksum(_adapter * adapter,u32 min_cnt,u32 timeout_ms)782 static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
783 {
784 	s32 ret = _FAIL;
785 	u32 value32;
786 	systime start = rtw_get_current_time();
787 	u32 cnt = 0;
788 
789 	/* polling CheckSum report */
790 	do {
791 		cnt++;
792 		value32 = rtw_read32(adapter, REG_MCUFWDL);
793 		if (value32 & FWDL_ChkSum_rpt || RTW_CANNOT_IO(adapter))
794 			break;
795 		rtw_yield_os();
796 	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
797 
798 	if (!(value32 & FWDL_ChkSum_rpt))
799 		goto exit;
800 
801 	if (rtw_fwdl_test_trigger_chksum_fail())
802 		goto exit;
803 
804 	ret = _SUCCESS;
805 
806 exit:
807 	RTW_INFO("%s: Checksum report %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
808 		, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), value32);
809 
810 	return ret;
811 }
812 
_FWFreeToGo(_adapter * adapter,u32 min_cnt,u32 timeout_ms)813 static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
814 {
815 	s32 ret = _FAIL;
816 	u32	value32;
817 	systime start = rtw_get_current_time();
818 	u32 cnt = 0;
819 
820 	value32 = rtw_read32(adapter, REG_MCUFWDL);
821 	value32 |= MCUFWDL_RDY;
822 	value32 &= ~WINTINI_RDY;
823 	rtw_write32(adapter, REG_MCUFWDL, value32);
824 
825 	_8051Reset88E(adapter);
826 
827 	/*  polling for FW ready */
828 	do {
829 		cnt++;
830 		value32 = rtw_read32(adapter, REG_MCUFWDL);
831 		if (value32 & WINTINI_RDY || RTW_CANNOT_IO(adapter))
832 			break;
833 		rtw_yield_os();
834 	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
835 
836 	if (!(value32 & WINTINI_RDY))
837 		goto exit;
838 
839 	if (rtw_fwdl_test_trigger_wintint_rdy_fail())
840 		goto exit;
841 
842 	ret = _SUCCESS;
843 
844 exit:
845 	RTW_INFO("%s: Polling FW ready %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
846 		, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), value32);
847 	return ret;
848 }
849 
850 #define IS_FW_81xxC(padapter)	(((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
851 
852 
853 #ifdef CONFIG_FILE_FWIMG
854 	extern char *rtw_fw_file_path;
855 	extern char *rtw_fw_wow_file_path;
856 	u8	FwBuffer8188E[FW_8188E_SIZE];
857 #endif /* CONFIG_FILE_FWIMG */
858 
859 /*
860  *	Description:
861  *		Download 8192C firmware code.
862  *
863  *   */
rtl8188e_FirmwareDownload(PADAPTER padapter,BOOLEAN bUsedWoWLANFw)864 s32 rtl8188e_FirmwareDownload(PADAPTER padapter, BOOLEAN  bUsedWoWLANFw)
865 {
866 	s32	rtStatus = _SUCCESS;
867 	u8 write_fw = 0;
868 	systime fwdl_start_time;
869 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
870 
871 	PRT_FIRMWARE_8188E	pFirmware = NULL;
872 	PRT_8188E_FIRMWARE_HDR		pFwHdr = NULL;
873 
874 	u8			*pFirmwareBuf;
875 	u32			FirmwareLen, tmp_fw_len = 0;
876 #ifdef CONFIG_FILE_FWIMG
877 	u8 *fwfilepath;
878 #endif /* CONFIG_FILE_FWIMG */
879 
880 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
881 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
882 #endif
883 
884 	pFirmware = (PRT_FIRMWARE_8188E)rtw_zmalloc(sizeof(RT_FIRMWARE_8188E));
885 	if (!pFirmware) {
886 		rtStatus = _FAIL;
887 		goto exit;
888 	}
889 
890 
891 
892 #ifdef CONFIG_FILE_FWIMG
893 #ifdef CONFIG_WOWLAN
894 	if (bUsedWoWLANFw)
895 		fwfilepath = rtw_fw_wow_file_path;
896 	else
897 #endif /* CONFIG_WOWLAN */
898 	{
899 		fwfilepath = rtw_fw_file_path;
900 	}
901 #endif /* CONFIG_FILE_FWIMG */
902 
903 #ifdef CONFIG_FILE_FWIMG
904 	if (rtw_is_file_readable(fwfilepath) == _TRUE) {
905 		RTW_INFO("%s accquire FW from file:%s\n", __FUNCTION__, fwfilepath);
906 		pFirmware->eFWSource = FW_SOURCE_IMG_FILE;
907 	} else
908 #endif /* CONFIG_FILE_FWIMG */
909 	{
910 		pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
911 	}
912 
913 	switch (pFirmware->eFWSource) {
914 	case FW_SOURCE_IMG_FILE:
915 #ifdef CONFIG_FILE_FWIMG
916 		rtStatus = rtw_retrieve_from_file(fwfilepath, FwBuffer8188E, FW_8188E_SIZE);
917 		pFirmware->ulFwLength = rtStatus >= 0 ? rtStatus : 0;
918 		pFirmware->szFwBuffer = FwBuffer8188E;
919 #endif /* CONFIG_FILE_FWIMG */
920 		break;
921 	case FW_SOURCE_HEADER_FILE:
922 		if (bUsedWoWLANFw) {
923 #ifdef CONFIG_WOWLAN
924 			if (pwrpriv->wowlan_mode) {
925 	#ifdef CONFIG_SFW_SUPPORTED
926 				if (IS_VENDOR_8188E_I_CUT_SERIES(padapter)) {
927 					pFirmware->szFwBuffer = array_mp_8188e_s_fw_wowlan;
928 					pFirmware->ulFwLength = array_length_mp_8188e_s_fw_wowlan;
929 				} else
930 	#endif
931 				{
932 					pFirmware->szFwBuffer = array_mp_8188e_t_fw_wowlan;
933 					pFirmware->ulFwLength = array_length_mp_8188e_t_fw_wowlan;
934 				}
935 				RTW_INFO("%s fw:%s, size: %d\n", __func__,
936 						"WoWLAN", pFirmware->ulFwLength);
937 			}
938 #endif /*CONFIG_WOWLAN*/
939 
940 #ifdef CONFIG_AP_WOWLAN
941 			if (pwrpriv->wowlan_ap_mode) {
942 					pFirmware->szFwBuffer = array_mp_8188e_t_fw_ap;
943 					pFirmware->ulFwLength = array_length_mp_8188e_t_fw_ap;
944 
945 					RTW_INFO("%s fw: %s, size: %d\n", __func__,
946 						"AP_WoWLAN", pFirmware->ulFwLength);
947 			}
948 #endif /*CONFIG_AP_WOWLAN*/
949 		} else {
950 #ifdef CONFIG_SFW_SUPPORTED
951 			if (IS_VENDOR_8188E_I_CUT_SERIES(padapter)) {
952 				pFirmware->szFwBuffer = array_mp_8188e_s_fw_nic;
953 				pFirmware->ulFwLength = array_length_mp_8188e_s_fw_nic;
954 			} else
955 #endif
956 			{
957 				pFirmware->szFwBuffer = array_mp_8188e_t_fw_nic;
958 				pFirmware->ulFwLength = array_length_mp_8188e_t_fw_nic;
959 			}
960 			RTW_INFO("%s fw:%s, size: %d\n", __FUNCTION__, "NIC", pFirmware->ulFwLength);
961 		}
962 		break;
963 	}
964 
965 	tmp_fw_len = IS_VENDOR_8188E_I_CUT_SERIES(padapter) ? FW_8188E_SIZE_2 : FW_8188E_SIZE;
966 
967 	if ((pFirmware->ulFwLength - 32) > tmp_fw_len) {
968 		rtStatus = _FAIL;
969 		RTW_ERR("Firmware size:%u exceed %u\n", pFirmware->ulFwLength, tmp_fw_len);
970 		goto exit;
971 	}
972 
973 	pFirmwareBuf = pFirmware->szFwBuffer;
974 	FirmwareLen = pFirmware->ulFwLength;
975 
976 	/* To Check Fw header. Added by tynli. 2009.12.04. */
977 	pFwHdr = (PRT_8188E_FIRMWARE_HDR)pFirmwareBuf;
978 
979 	pHalData->firmware_version =  le16_to_cpu(pFwHdr->Version);
980 	pHalData->firmware_sub_version = pFwHdr->Subversion;
981 	pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
982 
983 	RTW_INFO("%s: fw_ver=%x fw_subver=%04x sig=0x%x, Month=%02x, Date=%02x, Hour=%02x, Minute=%02x\n",
984 		__FUNCTION__, pHalData->firmware_version, pHalData->firmware_sub_version, pHalData->FirmwareSignature
985 		 , pFwHdr->Month, pFwHdr->Date, pFwHdr->Hour, pFwHdr->Minute);
986 
987 	if (IS_FW_HEADER_EXIST_88E(pFwHdr)) {
988 		/* Shift 32 bytes for FW header */
989 		pFirmwareBuf = pFirmwareBuf + 32;
990 		FirmwareLen = FirmwareLen - 32;
991 	}
992 
993 	/* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
994 	/* or it will cause download Fw fail. 2010.02.01. by tynli. */
995 	if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
996 		rtw_write8(padapter, REG_MCUFWDL, 0x00);
997 		_8051Reset88E(padapter);
998 	}
999 
1000 	_FWDownloadEnable_8188E(padapter, _TRUE);
1001 	fwdl_start_time = rtw_get_current_time();
1002 	while (!RTW_CANNOT_IO(padapter)
1003 	       && (write_fw++ < 3 || rtw_get_passing_time_ms(fwdl_start_time) < 500)) {
1004 		/* reset FWDL chksum */
1005 		rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
1006 
1007 		rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
1008 		if (rtStatus != _SUCCESS)
1009 			continue;
1010 
1011 		rtStatus = polling_fwdl_chksum(padapter, 5, 50);
1012 		if (rtStatus == _SUCCESS)
1013 			break;
1014 	}
1015 	_FWDownloadEnable_8188E(padapter, _FALSE);
1016 	if (_SUCCESS != rtStatus)
1017 		goto fwdl_stat;
1018 
1019 	rtStatus = _FWFreeToGo(padapter, 10, 200);
1020 	if (_SUCCESS != rtStatus)
1021 		goto fwdl_stat;
1022 
1023 fwdl_stat:
1024 	RTW_INFO("FWDL %s. write_fw:%u, %dms\n"
1025 		 , (rtStatus == _SUCCESS) ? "success" : "fail"
1026 		 , write_fw
1027 		 , rtw_get_passing_time_ms(fwdl_start_time)
1028 		);
1029 
1030 exit:
1031 	if (pFirmware)
1032 		rtw_mfree((u8 *)pFirmware, sizeof(RT_FIRMWARE_8188E));
1033 
1034 	rtl8188e_InitializeFirmwareVars(padapter);
1035 
1036 	return rtStatus;
1037 }
1038 
rtl8188e_InitializeFirmwareVars(PADAPTER padapter)1039 void rtl8188e_InitializeFirmwareVars(PADAPTER padapter)
1040 {
1041 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1042 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1043 
1044 	/* Init Fw LPS related. */
1045 	pwrpriv->bFwCurrentInPSMode = _FALSE;
1046 
1047 	/* Init H2C cmd. */
1048 	rtw_write8(padapter, REG_HMETFR, 0x0f);
1049 
1050 	/* Init H2C counter. by tynli. 2009.12.09. */
1051 	pHalData->LastHMEBoxNum = 0;
1052 }
1053 
1054 /* ***********************************************************
1055  *				Efuse related code
1056  * *********************************************************** */
1057 enum {
1058 	VOLTAGE_V25						= 0x03,
1059 	LDOE25_SHIFT						= 28 ,
1060 };
1061 
1062 static BOOLEAN
1063 hal_EfusePgPacketWrite2ByteHeader(
1064 		PADAPTER		pAdapter,
1065 		u8				efuseType,
1066 		u16				*pAddr,
1067 		PPGPKT_STRUCT	pTargetPkt,
1068 		BOOLEAN			bPseudoTest);
1069 static BOOLEAN
1070 hal_EfusePgPacketWrite1ByteHeader(
1071 		PADAPTER		pAdapter,
1072 		u8				efuseType,
1073 		u16				*pAddr,
1074 		PPGPKT_STRUCT	pTargetPkt,
1075 		BOOLEAN			bPseudoTest);
1076 static BOOLEAN
1077 hal_EfusePgPacketWriteData(
1078 		PADAPTER		pAdapter,
1079 		u8				efuseType,
1080 		u16				*pAddr,
1081 		PPGPKT_STRUCT	pTargetPkt,
1082 		BOOLEAN			bPseudoTest);
1083 
1084 static void
hal_EfusePowerSwitch_RTL8188E(PADAPTER pAdapter,u8 bWrite,u8 PwrState)1085 hal_EfusePowerSwitch_RTL8188E(
1086 		PADAPTER	pAdapter,
1087 		u8		bWrite,
1088 		u8		PwrState)
1089 {
1090 	u8	tempval;
1091 	u16	tmpV16;
1092 
1093 	if (PwrState == _TRUE) {
1094 		rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
1095 #if 0
1096 		/* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
1097 		tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
1098 		if (!(tmpV16 & PWC_EV12V)) {
1099 			tmpV16 |= PWC_EV12V ;
1100 			rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
1101 		}
1102 #endif
1103 		/* Reset: 0x0000h[28], default valid */
1104 		tmpV16 =  rtw_read16(pAdapter, REG_SYS_FUNC_EN);
1105 		if (!(tmpV16 & FEN_ELDR)) {
1106 			tmpV16 |= FEN_ELDR ;
1107 			rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
1108 		}
1109 
1110 		/* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
1111 		tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
1112 		if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
1113 			tmpV16 |= (LOADER_CLK_EN | ANA8M) ;
1114 			rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
1115 		}
1116 
1117 		if (bWrite == _TRUE) {
1118 			/* Enable LDO 2.5V before read/write action */
1119 			tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
1120 			if (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) {
1121 				tempval &= 0x87;
1122 				tempval |= 0x38; /* 0x34[30:27] = 0b'0111,  Use LDO 2.25V, Suggested by SD1 Pisa */
1123 			} else {
1124 				tempval &= 0x0F;
1125 				tempval |= (VOLTAGE_V25 << 4);
1126 			}
1127 			rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));
1128 		}
1129 	} else {
1130 		rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
1131 
1132 		if (bWrite == _TRUE) {
1133 			/* Disable LDO 2.5V after read/write action */
1134 			tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
1135 			rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));
1136 		}
1137 	}
1138 }
1139 
1140 static void
rtl8188e_EfusePowerSwitch(PADAPTER pAdapter,u8 bWrite,u8 PwrState)1141 rtl8188e_EfusePowerSwitch(
1142 		PADAPTER	pAdapter,
1143 		u8		bWrite,
1144 		u8		PwrState)
1145 {
1146 	hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
1147 }
1148 
1149 static void
Hal_EfuseReadEFuse88E(PADAPTER Adapter,u16 _offset,u16 _size_byte,u8 * pbuf,BOOLEAN bPseudoTest)1150 Hal_EfuseReadEFuse88E(
1151 	PADAPTER		Adapter,
1152 	u16			_offset,
1153 	u16			_size_byte,
1154 	u8		*pbuf,
1155 		BOOLEAN	bPseudoTest
1156 )
1157 {
1158 	/* u8	efuseTbl[EFUSE_MAP_LEN_88E]; */
1159 	u8	*efuseTbl = NULL;
1160 	u8	rtemp8[1];
1161 	u16	eFuse_Addr = 0;
1162 	u8	offset, wren;
1163 	u16	i, j;
1164 	/* u16	eFuseWord[EFUSE_MAX_SECTION_88E][EFUSE_MAX_WORD_UNIT]; */
1165 	u16	**eFuseWord = NULL;
1166 	u16	efuse_utilized = 0;
1167 	u8	efuse_usage = 0;
1168 	u8	u1temp = 0;
1169 
1170 	/*  */
1171 	/* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
1172 	/*  */
1173 	if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {
1174 		/* total E-Fuse table is 512bytes */
1175 		RTW_INFO("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte);
1176 		goto exit;
1177 	}
1178 
1179 	efuseTbl = (u8 *)rtw_zmalloc(EFUSE_MAP_LEN_88E);
1180 	if (efuseTbl == NULL) {
1181 		RTW_INFO("%s: alloc efuseTbl fail!\n", __FUNCTION__);
1182 		goto exit;
1183 	}
1184 
1185 	eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, 2);
1186 	if (eFuseWord == NULL) {
1187 		RTW_INFO("%s: alloc eFuseWord fail!\n", __FUNCTION__);
1188 		goto exit;
1189 	}
1190 
1191 	/* 0. Refresh efuse init map as all oxFF. */
1192 	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
1193 		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
1194 			eFuseWord[i][j] = 0xFFFF;
1195 
1196 	/*  */
1197 	/* 1. Read the first byte to check if efuse is empty!!! */
1198 	/*  */
1199 	/*  */
1200 	ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
1201 	if (*rtemp8 != 0xFF) {
1202 		efuse_utilized++;
1203 		/* RTW_INFO("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8); */
1204 		eFuse_Addr++;
1205 	} else {
1206 		RTW_INFO("EFUSE is empty efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8);
1207 		goto exit;
1208 	}
1209 
1210 
1211 	/*  */
1212 	/* 2. Read real efuse content. Filter PG header and every section data. */
1213 	/*  */
1214 	while ((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
1215 		/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr-1, *rtemp8)); */
1216 
1217 		/* Check PG header for section num. */
1218 		if ((*rtemp8 & 0x1F) == 0x0F) {	/* extended header */
1219 			u1temp = ((*rtemp8 & 0xE0) >> 5);
1220 			/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x *rtemp&0xE0 0x%x\n", u1temp, *rtemp8 & 0xE0)); */
1221 
1222 			/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x\n", u1temp)); */
1223 
1224 			ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
1225 
1226 			/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8));	 */
1227 
1228 			if ((*rtemp8 & 0x0F) == 0x0F) {
1229 				eFuse_Addr++;
1230 				ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
1231 
1232 				if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
1233 					eFuse_Addr++;
1234 				continue;
1235 			} else {
1236 				offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
1237 				wren = (*rtemp8 & 0x0F);
1238 				eFuse_Addr++;
1239 			}
1240 		} else {
1241 			offset = ((*rtemp8 >> 4) & 0x0f);
1242 			wren = (*rtemp8 & 0x0f);
1243 		}
1244 
1245 		if (offset < EFUSE_MAX_SECTION_88E) {
1246 			/* Get word enable value from PG header */
1247 			/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Offset-%d Worden=%x\n", offset, wren)); */
1248 
1249 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
1250 				/* Check word enable condition in the section				 */
1251 				if (!(wren & 0x01)) {
1252 					/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d\n", eFuse_Addr)); */
1253 					ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
1254 					eFuse_Addr++;
1255 					/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8)); 				 */
1256 					efuse_utilized++;
1257 					eFuseWord[offset][i] = (*rtemp8 & 0xff);
1258 
1259 
1260 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
1261 						break;
1262 
1263 					/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d", eFuse_Addr)); */
1264 					ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
1265 					eFuse_Addr++;
1266 					/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8)); 				 */
1267 
1268 					efuse_utilized++;
1269 					eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
1270 
1271 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
1272 						break;
1273 				}
1274 
1275 				wren >>= 1;
1276 
1277 			}
1278 		} else { /* deal with error offset,skip error data		 */
1279 			RTW_PRINT("invalid offset:0x%02x\n", offset);
1280 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
1281 				/* Check word enable condition in the section				 */
1282 				if (!(wren & 0x01)) {
1283 					eFuse_Addr++;
1284 					efuse_utilized++;
1285 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
1286 						break;
1287 					eFuse_Addr++;
1288 					efuse_utilized++;
1289 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
1290 						break;
1291 				}
1292 			}
1293 		}
1294 		/* Read next PG header */
1295 		ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
1296 		/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d rtemp 0x%x\n", eFuse_Addr, *rtemp8)); */
1297 
1298 		if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
1299 			efuse_utilized++;
1300 			eFuse_Addr++;
1301 		}
1302 	}
1303 
1304 	/*  */
1305 	/* 3. Collect 16 sections and 4 word unit into Efuse map. */
1306 	/*  */
1307 	for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
1308 		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
1309 			efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
1310 			efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
1311 		}
1312 	}
1313 
1314 
1315 	/*  */
1316 	/* 4. Copy from Efuse map to output pointer memory!!! */
1317 	/*  */
1318 	for (i = 0; i < _size_byte; i++)
1319 		pbuf[i] = efuseTbl[_offset + i];
1320 
1321 	/*  */
1322 	/* 5. Calculate Efuse utilization. */
1323 	/*  */
1324 	efuse_usage = (u8)((eFuse_Addr * 100) / EFUSE_REAL_CONTENT_LEN_88E);
1325 	rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&eFuse_Addr);
1326 
1327 exit:
1328 	if (efuseTbl)
1329 		rtw_mfree(efuseTbl, EFUSE_MAP_LEN_88E);
1330 
1331 	if (eFuseWord)
1332 		rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
1333 }
1334 
1335 static void
ReadEFuseByIC(PADAPTER Adapter,u8 efuseType,u16 _offset,u16 _size_byte,u8 * pbuf,BOOLEAN bPseudoTest)1336 ReadEFuseByIC(
1337 	PADAPTER	Adapter,
1338 	u8		efuseType,
1339 	u16		 _offset,
1340 	u16		_size_byte,
1341 	u8	*pbuf,
1342 	BOOLEAN	bPseudoTest
1343 )
1344 {
1345 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1346 #ifdef DBG_IOL_READ_EFUSE_MAP
1347 	u8 logical_map[512];
1348 #endif
1349 
1350 #ifdef CONFIG_IOL_READ_EFUSE_MAP
1351 	if (!bPseudoTest && Adapter->registrypriv.mp_mode == 0) { /* && rtw_IOL_applied(Adapter)) */
1352 		int ret = _FAIL;
1353 		if (rtw_IOL_applied(Adapter)) {
1354 			rtw_hal_power_on(Adapter);
1355 
1356 			iol_mode_enable(Adapter, 1);
1357 #ifdef DBG_IOL_READ_EFUSE_MAP
1358 			iol_read_efuse(Adapter, 0, _offset, _size_byte, logical_map);
1359 #else
1360 			ret = iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf);
1361 #endif
1362 			iol_mode_enable(Adapter, 0);
1363 
1364 			if (_SUCCESS == ret)
1365 				goto exit;
1366 		}
1367 	}
1368 #endif
1369 	Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
1370 
1371 exit:
1372 
1373 #ifdef DBG_IOL_READ_EFUSE_MAP
1374 	if (_rtw_memcmp(logical_map, pHalData->efuse_eeprom_data, 0x130) == _FALSE) {
1375 		int i;
1376 		RTW_INFO("%s compare first 0x130 byte fail\n", __FUNCTION__);
1377 		for (i = 0; i < 512; i++) {
1378 			if (i % 16 == 0)
1379 				RTW_INFO("0x%03x: ", i);
1380 			RTW_INFO("%02x ", logical_map[i]);
1381 			if (i % 16 == 15)
1382 				RTW_INFO("\n");
1383 		}
1384 		RTW_INFO("\n");
1385 	}
1386 #endif
1387 
1388 	return;
1389 }
1390 
1391 static void
ReadEFuse_Pseudo(PADAPTER Adapter,u8 efuseType,u16 _offset,u16 _size_byte,u8 * pbuf,BOOLEAN bPseudoTest)1392 ReadEFuse_Pseudo(
1393 	PADAPTER	Adapter,
1394 	u8		efuseType,
1395 	u16		 _offset,
1396 	u16		_size_byte,
1397 	u8	*pbuf,
1398 	BOOLEAN	bPseudoTest
1399 )
1400 {
1401 	Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
1402 }
1403 
1404 static void
rtl8188e_ReadEFuse(PADAPTER Adapter,u8 efuseType,u16 _offset,u16 _size_byte,u8 * pbuf,BOOLEAN bPseudoTest)1405 rtl8188e_ReadEFuse(
1406 	PADAPTER	Adapter,
1407 	u8		efuseType,
1408 	u16		_offset,
1409 	u16		_size_byte,
1410 	u8	*pbuf,
1411 	BOOLEAN	bPseudoTest
1412 )
1413 {
1414 	if (bPseudoTest)
1415 		ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
1416 	else
1417 		ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
1418 }
1419 
1420 /* Do not support BT */
1421 void
Hal_EFUSEGetEfuseDefinition88E(PADAPTER pAdapter,u8 efuseType,u8 type,void * pOut)1422 Hal_EFUSEGetEfuseDefinition88E(
1423 			PADAPTER	pAdapter,
1424 			u8		efuseType,
1425 			u8		type,
1426 			void		*pOut
1427 )
1428 {
1429 	switch (type) {
1430 	case TYPE_EFUSE_MAX_SECTION: {
1431 		u8	*pMax_section;
1432 		pMax_section = (u8 *)pOut;
1433 		*pMax_section = EFUSE_MAX_SECTION_88E;
1434 	}
1435 	break;
1436 	case TYPE_EFUSE_REAL_CONTENT_LEN: {
1437 		u16 *pu2Tmp;
1438 		pu2Tmp = (u16 *)pOut;
1439 		*pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1440 	}
1441 	break;
1442 	case TYPE_EFUSE_CONTENT_LEN_BANK: {
1443 		u16 *pu2Tmp;
1444 		pu2Tmp = (u16 *)pOut;
1445 		*pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1446 	}
1447 	break;
1448 	case TYPE_AVAILABLE_EFUSE_BYTES_BANK: {
1449 		u16 *pu2Tmp;
1450 		pu2Tmp = (u16 *)pOut;
1451 		*pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1452 	}
1453 	break;
1454 	case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: {
1455 		u16 *pu2Tmp;
1456 		pu2Tmp = (u16 *)pOut;
1457 		*pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1458 	}
1459 	break;
1460 	case TYPE_EFUSE_MAP_LEN: {
1461 		u16 *pu2Tmp;
1462 		pu2Tmp = (u16 *)pOut;
1463 		*pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
1464 	}
1465 	break;
1466 	case TYPE_EFUSE_PROTECT_BYTES_BANK: {
1467 		u8 *pu1Tmp;
1468 		pu1Tmp = (u8 *)pOut;
1469 		*pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
1470 	}
1471 	break;
1472 	default: {
1473 		u8 *pu1Tmp;
1474 		pu1Tmp = (u8 *)pOut;
1475 		*pu1Tmp = 0;
1476 	}
1477 	break;
1478 	}
1479 }
1480 void
Hal_EFUSEGetEfuseDefinition_Pseudo88E(PADAPTER pAdapter,u8 efuseType,u8 type,void * pOut)1481 Hal_EFUSEGetEfuseDefinition_Pseudo88E(
1482 			PADAPTER	pAdapter,
1483 			u8			efuseType,
1484 			u8			type,
1485 			void			*pOut
1486 )
1487 {
1488 	switch (type) {
1489 	case TYPE_EFUSE_MAX_SECTION: {
1490 		u8		*pMax_section;
1491 		pMax_section = (u8 *)pOut;
1492 		*pMax_section = EFUSE_MAX_SECTION_88E;
1493 	}
1494 	break;
1495 	case TYPE_EFUSE_REAL_CONTENT_LEN: {
1496 		u16 *pu2Tmp;
1497 		pu2Tmp = (u16 *)pOut;
1498 		*pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1499 	}
1500 	break;
1501 	case TYPE_EFUSE_CONTENT_LEN_BANK: {
1502 		u16 *pu2Tmp;
1503 		pu2Tmp = (u16 *)pOut;
1504 		*pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1505 	}
1506 	break;
1507 	case TYPE_AVAILABLE_EFUSE_BYTES_BANK: {
1508 		u16 *pu2Tmp;
1509 		pu2Tmp = (u16 *)pOut;
1510 		*pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1511 	}
1512 	break;
1513 	case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: {
1514 		u16 *pu2Tmp;
1515 		pu2Tmp = (u16 *)pOut;
1516 		*pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1517 	}
1518 	break;
1519 	case TYPE_EFUSE_MAP_LEN: {
1520 		u16 *pu2Tmp;
1521 		pu2Tmp = (u16 *)pOut;
1522 		*pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
1523 	}
1524 	break;
1525 	case TYPE_EFUSE_PROTECT_BYTES_BANK: {
1526 		u8 *pu1Tmp;
1527 		pu1Tmp = (u8 *)pOut;
1528 		*pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
1529 	}
1530 	break;
1531 	default: {
1532 		u8 *pu1Tmp;
1533 		pu1Tmp = (u8 *)pOut;
1534 		*pu1Tmp = 0;
1535 	}
1536 	break;
1537 	}
1538 }
1539 
1540 
1541 static void
rtl8188e_EFUSE_GetEfuseDefinition(PADAPTER pAdapter,u8 efuseType,u8 type,void * pOut,BOOLEAN bPseudoTest)1542 rtl8188e_EFUSE_GetEfuseDefinition(
1543 			PADAPTER	pAdapter,
1544 			u8		efuseType,
1545 			u8		type,
1546 			void		*pOut,
1547 			BOOLEAN		bPseudoTest
1548 )
1549 {
1550 	if (bPseudoTest)
1551 		Hal_EFUSEGetEfuseDefinition_Pseudo88E(pAdapter, efuseType, type, pOut);
1552 	else
1553 		Hal_EFUSEGetEfuseDefinition88E(pAdapter, efuseType, type, pOut);
1554 }
1555 
1556 static u8
Hal_EfuseWordEnableDataWrite(PADAPTER pAdapter,u16 efuse_addr,u8 word_en,u8 * data,BOOLEAN bPseudoTest)1557 Hal_EfuseWordEnableDataWrite(PADAPTER	pAdapter,
1558 					u16		efuse_addr,
1559 					u8		word_en,
1560 					u8		*data,
1561 					BOOLEAN		bPseudoTest)
1562 {
1563 	u16	tmpaddr = 0;
1564 	u16	start_addr = efuse_addr;
1565 	u8	badworden = 0x0F;
1566 	u8	tmpdata[8];
1567 
1568 	_rtw_memset((void *)tmpdata, 0xff, PGPKT_DATA_SIZE);
1569 
1570 	if (!(word_en & BIT0)) {
1571 		tmpaddr = start_addr;
1572 		efuse_OneByteWrite(pAdapter, start_addr++, data[0], bPseudoTest);
1573 		efuse_OneByteWrite(pAdapter, start_addr++, data[1], bPseudoTest);
1574 		phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
1575 
1576 		efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[0], bPseudoTest);
1577 		efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[1], bPseudoTest);
1578 		phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
1579 
1580 		if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
1581 			badworden &= (~BIT0);
1582 	}
1583 	if (!(word_en & BIT1)) {
1584 		tmpaddr = start_addr;
1585 		efuse_OneByteWrite(pAdapter, start_addr++, data[2], bPseudoTest);
1586 		efuse_OneByteWrite(pAdapter, start_addr++, data[3], bPseudoTest);
1587 		phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
1588 
1589 		efuse_OneByteRead(pAdapter, tmpaddr    , &tmpdata[2], bPseudoTest);
1590 		efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[3], bPseudoTest);
1591 		phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
1592 
1593 		if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
1594 			badworden &= (~BIT1);
1595 	}
1596 	if (!(word_en & BIT2)) {
1597 		tmpaddr = start_addr;
1598 		efuse_OneByteWrite(pAdapter, start_addr++, data[4], bPseudoTest);
1599 		efuse_OneByteWrite(pAdapter, start_addr++, data[5], bPseudoTest);
1600 		phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
1601 
1602 		efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[4], bPseudoTest);
1603 		efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[5], bPseudoTest);
1604 		phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
1605 
1606 		if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
1607 			badworden &= (~BIT2);
1608 	}
1609 	if (!(word_en & BIT3)) {
1610 		tmpaddr = start_addr;
1611 		efuse_OneByteWrite(pAdapter, start_addr++, data[6], bPseudoTest);
1612 		efuse_OneByteWrite(pAdapter, start_addr++, data[7], bPseudoTest);
1613 		phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
1614 
1615 		efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[6], bPseudoTest);
1616 		efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[7], bPseudoTest);
1617 		phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
1618 
1619 		if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
1620 			badworden &= (~BIT3);
1621 	}
1622 	return badworden;
1623 }
1624 
1625 static u8
Hal_EfuseWordEnableDataWrite_Pseudo(PADAPTER pAdapter,u16 efuse_addr,u8 word_en,u8 * data,BOOLEAN bPseudoTest)1626 Hal_EfuseWordEnableDataWrite_Pseudo(PADAPTER	pAdapter,
1627 						u16		efuse_addr,
1628 						u8		word_en,
1629 						u8		*data,
1630 						BOOLEAN		bPseudoTest)
1631 {
1632 	u8	ret = 0;
1633 
1634 	ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1635 
1636 	return ret;
1637 }
1638 
1639 static u8
rtl8188e_Efuse_WordEnableDataWrite(PADAPTER pAdapter,u16 efuse_addr,u8 word_en,u8 * data,BOOLEAN bPseudoTest)1640 rtl8188e_Efuse_WordEnableDataWrite(PADAPTER	pAdapter,
1641 					u16		efuse_addr,
1642 					u8		word_en,
1643 					u8		*data,
1644 					BOOLEAN		bPseudoTest)
1645 {
1646 	u8	ret = 0;
1647 
1648 	if (bPseudoTest)
1649 		ret = Hal_EfuseWordEnableDataWrite_Pseudo(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1650 	else
1651 		ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1652 
1653 	return ret;
1654 }
1655 
1656 
1657 static u16
hal_EfuseGetCurrentSize_8188e(PADAPTER pAdapter,BOOLEAN bPseudoTest)1658 hal_EfuseGetCurrentSize_8188e(PADAPTER	pAdapter,
1659 						BOOLEAN			bPseudoTest)
1660 {
1661 	int	bContinual = _TRUE;
1662 
1663 	u16	efuse_addr = 0;
1664 	u8	hoffset = 0, hworden = 0;
1665 	u8	efuse_data, word_cnts = 0;
1666 
1667 	if (bPseudoTest)
1668 		efuse_addr = (u16)(fakeEfuseUsedBytes);
1669 	else
1670 		rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1671 	/* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723A(), start_efuse_addr = %d\n", efuse_addr)); */
1672 
1673 	while (bContinual &&
1674 	       efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest) &&
1675 	       AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1676 		if (efuse_data != 0xFF) {
1677 			if ((efuse_data & 0x1F) == 0x0F) {	/* extended header */
1678 				hoffset = efuse_data;
1679 				efuse_addr++;
1680 				efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest);
1681 				if ((efuse_data & 0x0F) == 0x0F) {
1682 					efuse_addr++;
1683 					continue;
1684 				} else {
1685 					hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1686 					hworden = efuse_data & 0x0F;
1687 				}
1688 			} else {
1689 				hoffset = (efuse_data >> 4) & 0x0F;
1690 				hworden =  efuse_data & 0x0F;
1691 			}
1692 			word_cnts = Efuse_CalculateWordCnts(hworden);
1693 			/* read next header */
1694 			efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1695 		} else
1696 			bContinual = _FALSE ;
1697 	}
1698 
1699 	if (bPseudoTest) {
1700 		fakeEfuseUsedBytes = efuse_addr;
1701 		/* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723A(), return %d\n", fakeEfuseUsedBytes)); */
1702 	} else {
1703 		rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1704 		/* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723A(), return %d\n", efuse_addr)); */
1705 	}
1706 
1707 	return efuse_addr;
1708 }
1709 
1710 static u16
Hal_EfuseGetCurrentSize_Pseudo(PADAPTER pAdapter,BOOLEAN bPseudoTest)1711 Hal_EfuseGetCurrentSize_Pseudo(PADAPTER	pAdapter,
1712 						BOOLEAN			bPseudoTest)
1713 {
1714 	u16	ret = 0;
1715 
1716 	ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
1717 
1718 	return ret;
1719 }
1720 
1721 
1722 static u16
rtl8188e_EfuseGetCurrentSize(PADAPTER pAdapter,u8 efuseType,BOOLEAN bPseudoTest)1723 rtl8188e_EfuseGetCurrentSize(
1724 		PADAPTER	pAdapter,
1725 		u8			efuseType,
1726 		BOOLEAN		bPseudoTest)
1727 {
1728 	u16	ret = 0;
1729 
1730 	if (bPseudoTest)
1731 		ret = Hal_EfuseGetCurrentSize_Pseudo(pAdapter, bPseudoTest);
1732 	else
1733 		ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
1734 
1735 
1736 	return ret;
1737 }
1738 
1739 
1740 static int
hal_EfusePgPacketRead_8188e(PADAPTER pAdapter,u8 offset,u8 * data,BOOLEAN bPseudoTest)1741 hal_EfusePgPacketRead_8188e(
1742 		PADAPTER	pAdapter,
1743 		u8			offset,
1744 		u8			*data,
1745 		BOOLEAN		bPseudoTest)
1746 {
1747 	u8	ReadState = PG_STATE_HEADER;
1748 
1749 	int	bContinual = _TRUE;
1750 	int	bDataEmpty = _TRUE ;
1751 
1752 	u8	efuse_data, word_cnts = 0;
1753 	u16	efuse_addr = 0;
1754 	u8	hoffset = 0, hworden = 0;
1755 	u8	tmpidx = 0;
1756 	u8	tmpdata[8];
1757 	u8	max_section = 0;
1758 	u8	tmp_header = 0;
1759 
1760 	EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (void *)&max_section, bPseudoTest);
1761 
1762 	if (data == NULL)
1763 		return _FALSE;
1764 	if (offset > max_section)
1765 		return _FALSE;
1766 
1767 	_rtw_memset((void *)data, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);
1768 	_rtw_memset((void *)tmpdata, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);
1769 
1770 
1771 	/*  */
1772 	/* <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */
1773 	/* Skip dummy parts to prevent unexpected data read from Efuse. */
1774 	/* By pass right now. 2009.02.19. */
1775 	/*  */
1776 	while (bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1777 		/* -------  Header Read ------------- */
1778 		if (ReadState & PG_STATE_HEADER) {
1779 			if (efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
1780 				if (EXT_HEADER(efuse_data)) {
1781 					tmp_header = efuse_data;
1782 					efuse_addr++;
1783 					efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest);
1784 					if (!ALL_WORDS_DISABLED(efuse_data)) {
1785 						hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1786 						hworden = efuse_data & 0x0F;
1787 					} else {
1788 						RTW_INFO("Error, All words disabled\n");
1789 						efuse_addr++;
1790 						continue;
1791 					}
1792 				} else {
1793 					hoffset = (efuse_data >> 4) & 0x0F;
1794 					hworden =  efuse_data & 0x0F;
1795 				}
1796 				word_cnts = Efuse_CalculateWordCnts(hworden);
1797 				bDataEmpty = _TRUE ;
1798 
1799 				if (hoffset == offset) {
1800 					for (tmpidx = 0; tmpidx < word_cnts * 2 ; tmpidx++) {
1801 						if (efuse_OneByteRead(pAdapter, efuse_addr + 1 + tmpidx , &efuse_data, bPseudoTest)) {
1802 							tmpdata[tmpidx] = efuse_data;
1803 							if (efuse_data != 0xff)
1804 								bDataEmpty = _FALSE;
1805 						}
1806 					}
1807 					if (bDataEmpty == _FALSE)
1808 						ReadState = PG_STATE_DATA;
1809 					else { /* read next header */
1810 						efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1811 						ReadState = PG_STATE_HEADER;
1812 					}
1813 				} else { /* read next header */
1814 					efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1815 					ReadState = PG_STATE_HEADER;
1816 				}
1817 
1818 			} else
1819 				bContinual = _FALSE ;
1820 		}
1821 		/* -------  Data section Read ------------- */
1822 		else if (ReadState & PG_STATE_DATA) {
1823 			efuse_WordEnableDataRead(hworden, tmpdata, data);
1824 			efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1825 			ReadState = PG_STATE_HEADER;
1826 		}
1827 
1828 	}
1829 
1830 	if ((data[0] == 0xff) && (data[1] == 0xff) && (data[2] == 0xff)  && (data[3] == 0xff) &&
1831 	    (data[4] == 0xff) && (data[5] == 0xff) && (data[6] == 0xff)  && (data[7] == 0xff))
1832 		return _FALSE;
1833 	else
1834 		return _TRUE;
1835 
1836 }
1837 
1838 static int
Hal_EfusePgPacketRead(PADAPTER pAdapter,u8 offset,u8 * data,BOOLEAN bPseudoTest)1839 Hal_EfusePgPacketRead(PADAPTER	pAdapter,
1840 				u8			offset,
1841 				u8			*data,
1842 				BOOLEAN			bPseudoTest)
1843 {
1844 	int	ret = 0;
1845 
1846 	ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
1847 
1848 
1849 	return ret;
1850 }
1851 
1852 static int
Hal_EfusePgPacketRead_Pseudo(PADAPTER pAdapter,u8 offset,u8 * data,BOOLEAN bPseudoTest)1853 Hal_EfusePgPacketRead_Pseudo(PADAPTER	pAdapter,
1854 					u8			offset,
1855 					u8			*data,
1856 					BOOLEAN		bPseudoTest)
1857 {
1858 	int	ret = 0;
1859 
1860 	ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
1861 
1862 	return ret;
1863 }
1864 
1865 static int
rtl8188e_Efuse_PgPacketRead(PADAPTER pAdapter,u8 offset,u8 * data,BOOLEAN bPseudoTest)1866 rtl8188e_Efuse_PgPacketRead(PADAPTER	pAdapter,
1867 					u8			offset,
1868 					u8			*data,
1869 					BOOLEAN		bPseudoTest)
1870 {
1871 	int	ret = 0;
1872 
1873 	if (bPseudoTest)
1874 		ret = Hal_EfusePgPacketRead_Pseudo(pAdapter, offset, data, bPseudoTest);
1875 	else
1876 		ret = Hal_EfusePgPacketRead(pAdapter, offset, data, bPseudoTest);
1877 
1878 	return ret;
1879 }
1880 
1881 static BOOLEAN
hal_EfuseFixHeaderProcess(PADAPTER pAdapter,u8 efuseType,PPGPKT_STRUCT pFixPkt,u16 * pAddr,BOOLEAN bPseudoTest)1882 hal_EfuseFixHeaderProcess(
1883 			PADAPTER			pAdapter,
1884 			u8					efuseType,
1885 			PPGPKT_STRUCT		pFixPkt,
1886 			u16					*pAddr,
1887 			BOOLEAN				bPseudoTest
1888 )
1889 {
1890 	u8	originaldata[8], badworden = 0;
1891 	u16	efuse_addr = *pAddr;
1892 	u32	PgWriteSuccess = 0;
1893 
1894 	_rtw_memset((void *)originaldata, 0xff, 8);
1895 
1896 	if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) {
1897 		/* check if data exist */
1898 		badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pFixPkt->word_en, originaldata, bPseudoTest);
1899 
1900 		if (badworden != 0xf) {	/* write fail */
1901 			PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest);
1902 
1903 			if (!PgWriteSuccess)
1904 				return _FALSE;
1905 			else
1906 				efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
1907 		} else
1908 			efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;
1909 	} else
1910 		efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;
1911 	*pAddr = efuse_addr;
1912 	return _TRUE;
1913 }
1914 
1915 static BOOLEAN
hal_EfusePgPacketWrite2ByteHeader(PADAPTER pAdapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,BOOLEAN bPseudoTest)1916 hal_EfusePgPacketWrite2ByteHeader(
1917 				PADAPTER		pAdapter,
1918 				u8				efuseType,
1919 				u16				*pAddr,
1920 				PPGPKT_STRUCT	pTargetPkt,
1921 				BOOLEAN			bPseudoTest)
1922 {
1923 	BOOLEAN		bRet = _FALSE, bContinual = _TRUE;
1924 	u16	efuse_addr = *pAddr, efuse_max_available_len = 0;
1925 	u8	pg_header = 0, tmp_header = 0, pg_header_temp = 0;
1926 	u8	repeatcnt = 0;
1927 
1928 	/* RTPRINT(FEEPROM, EFUSE_PG, ("Wirte 2byte header\n")); */
1929 	EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest);
1930 
1931 	while (efuse_addr < efuse_max_available_len) {
1932 		pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
1933 		/* RTPRINT(FEEPROM, EFUSE_PG, ("pg_header = 0x%x\n", pg_header)); */
1934 		efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1935 		phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
1936 		efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1937 		phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
1938 		while (tmp_header == 0xFF || pg_header != tmp_header) {
1939 			if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1940 				/* RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for pg_header!!\n")); */
1941 				return _FALSE;
1942 			}
1943 
1944 			efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1945 			efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1946 		}
1947 
1948 		/* to write ext_header */
1949 		if (tmp_header == pg_header) {
1950 			efuse_addr++;
1951 			pg_header_temp = pg_header;
1952 			pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
1953 
1954 			efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1955 			phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
1956 			efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1957 			phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
1958 			while (tmp_header == 0xFF || pg_header != tmp_header) {
1959 				if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1960 					/* RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for ext_header!!\n")); */
1961 					return _FALSE;
1962 				}
1963 
1964 				efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1965 				efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1966 			}
1967 
1968 			if ((tmp_header & 0x0F) == 0x0F) {	/* word_en PG fail */
1969 				if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1970 					/* RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for word_en!!\n")); */
1971 					return _FALSE;
1972 				} else {
1973 					efuse_addr++;
1974 					continue;
1975 				}
1976 			} else if (pg_header != tmp_header) {	/* offset PG fail */
1977 				PGPKT_STRUCT	fixPkt;
1978 				/* RTPRINT(FEEPROM, EFUSE_PG, ("Error condition for offset PG fail, need to cover the existed data\n")); */
1979 				fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
1980 				fixPkt.word_en = tmp_header & 0x0F;
1981 				fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
1982 				if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
1983 					return _FALSE;
1984 			} else {
1985 				bRet = _TRUE;
1986 				break;
1987 			}
1988 		} else if ((tmp_header & 0x1F) == 0x0F) {	/* wrong extended header */
1989 			efuse_addr += 2;
1990 			continue;
1991 		}
1992 	}
1993 
1994 	*pAddr = efuse_addr;
1995 	return bRet;
1996 }
1997 
1998 static BOOLEAN
hal_EfusePgPacketWrite1ByteHeader(PADAPTER pAdapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,BOOLEAN bPseudoTest)1999 hal_EfusePgPacketWrite1ByteHeader(
2000 				PADAPTER		pAdapter,
2001 				u8				efuseType,
2002 				u16				*pAddr,
2003 				PPGPKT_STRUCT	pTargetPkt,
2004 				BOOLEAN			bPseudoTest)
2005 {
2006 	BOOLEAN		bRet = _FALSE;
2007 	u8	pg_header = 0, tmp_header = 0;
2008 	u16	efuse_addr = *pAddr;
2009 	u8	repeatcnt = 0;
2010 
2011 	/* RTPRINT(FEEPROM, EFUSE_PG, ("Wirte 1byte header\n")); */
2012 	pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
2013 
2014 	efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2015 	phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
2016 
2017 	efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2018 
2019 	phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
2020 
2021 	while (tmp_header == 0xFF || pg_header != tmp_header) {
2022 		if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2023 			return _FALSE;
2024 		efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2025 		efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2026 	}
2027 
2028 	if (pg_header == tmp_header)
2029 		bRet = _TRUE;
2030 	else {
2031 		PGPKT_STRUCT	fixPkt;
2032 		/* RTPRINT(FEEPROM, EFUSE_PG, ("Error condition for fixed PG packet, need to cover the existed data\n")); */
2033 		fixPkt.offset = (tmp_header >> 4) & 0x0F;
2034 		fixPkt.word_en = tmp_header & 0x0F;
2035 		fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
2036 		if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
2037 			return _FALSE;
2038 	}
2039 
2040 	*pAddr = efuse_addr;
2041 	return bRet;
2042 }
2043 
2044 static BOOLEAN
hal_EfusePgPacketWriteData(PADAPTER pAdapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,BOOLEAN bPseudoTest)2045 hal_EfusePgPacketWriteData(
2046 				PADAPTER		pAdapter,
2047 				u8				efuseType,
2048 				u16				*pAddr,
2049 				PPGPKT_STRUCT	pTargetPkt,
2050 				BOOLEAN			bPseudoTest)
2051 {
2052 	BOOLEAN	bRet = _FALSE;
2053 	u16	efuse_addr = *pAddr;
2054 	u8	badworden = 0;
2055 	u32	PgWriteSuccess = 0;
2056 
2057 	badworden = 0x0f;
2058 	badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
2059 	if (badworden == 0x0F) {
2060 		/* write ok */
2061 		/* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgPacketWriteData ok!!\n")); */
2062 		return _TRUE;
2063 	} else {
2064 		/* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgPacketWriteData Fail!!\n")); */
2065 		/* reorganize other pg packet */
2066 
2067 		PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2068 
2069 		if (!PgWriteSuccess)
2070 			return _FALSE;
2071 		else
2072 			return _TRUE;
2073 	}
2074 
2075 	return bRet;
2076 }
2077 
2078 static BOOLEAN
hal_EfusePgPacketWriteHeader(PADAPTER pAdapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,BOOLEAN bPseudoTest)2079 hal_EfusePgPacketWriteHeader(
2080 				PADAPTER		pAdapter,
2081 				u8				efuseType,
2082 				u16				*pAddr,
2083 				PPGPKT_STRUCT	pTargetPkt,
2084 				BOOLEAN			bPseudoTest)
2085 {
2086 	BOOLEAN		bRet = _FALSE;
2087 
2088 	if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
2089 		bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2090 	else
2091 		bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2092 
2093 	return bRet;
2094 }
2095 
2096 static BOOLEAN
wordEnMatched(PPGPKT_STRUCT pTargetPkt,PPGPKT_STRUCT pCurPkt,u8 * pWden)2097 wordEnMatched(
2098 		PPGPKT_STRUCT	pTargetPkt,
2099 		PPGPKT_STRUCT	pCurPkt,
2100 		u8				*pWden
2101 )
2102 {
2103 	u8	match_word_en = 0x0F;	/* default all words are disabled */
2104 	u8	i;
2105 
2106 	/* check if the same words are enabled both target and current PG packet */
2107 	if (((pTargetPkt->word_en & BIT0) == 0) &&
2108 	    ((pCurPkt->word_en & BIT0) == 0)) {
2109 		match_word_en &= ~BIT0;				/* enable word 0 */
2110 	}
2111 	if (((pTargetPkt->word_en & BIT1) == 0) &&
2112 	    ((pCurPkt->word_en & BIT1) == 0)) {
2113 		match_word_en &= ~BIT1;				/* enable word 1 */
2114 	}
2115 	if (((pTargetPkt->word_en & BIT2) == 0) &&
2116 	    ((pCurPkt->word_en & BIT2) == 0)) {
2117 		match_word_en &= ~BIT2;				/* enable word 2 */
2118 	}
2119 	if (((pTargetPkt->word_en & BIT3) == 0) &&
2120 	    ((pCurPkt->word_en & BIT3) == 0)) {
2121 		match_word_en &= ~BIT3;				/* enable word 3 */
2122 	}
2123 
2124 	*pWden = match_word_en;
2125 
2126 	if (match_word_en != 0xf)
2127 		return _TRUE;
2128 	else
2129 		return _FALSE;
2130 }
2131 
2132 static BOOLEAN
hal_EfuseCheckIfDatafollowed(PADAPTER pAdapter,u8 word_cnts,u16 startAddr,BOOLEAN bPseudoTest)2133 hal_EfuseCheckIfDatafollowed(
2134 			PADAPTER		pAdapter,
2135 			u8				word_cnts,
2136 			u16				startAddr,
2137 			BOOLEAN			bPseudoTest
2138 )
2139 {
2140 	BOOLEAN		bRet = _FALSE;
2141 	u8	i, efuse_data;
2142 
2143 	for (i = 0; i < (word_cnts * 2) ; i++) {
2144 		if (efuse_OneByteRead(pAdapter, (startAddr + i) , &efuse_data, bPseudoTest) && (efuse_data != 0xFF))
2145 			bRet = _TRUE;
2146 	}
2147 
2148 	return bRet;
2149 }
2150 
2151 static BOOLEAN
hal_EfusePartialWriteCheck(PADAPTER pAdapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,BOOLEAN bPseudoTest)2152 hal_EfusePartialWriteCheck(
2153 		PADAPTER		pAdapter,
2154 		u8				efuseType,
2155 		u16				*pAddr,
2156 		PPGPKT_STRUCT	pTargetPkt,
2157 		BOOLEAN			bPseudoTest
2158 )
2159 {
2160 	BOOLEAN		bRet = _FALSE;
2161 	u8	i, efuse_data = 0, cur_header = 0;
2162 	u8	new_wden = 0, matched_wden = 0, badworden = 0;
2163 	u16	startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
2164 	PGPKT_STRUCT	curPkt;
2165 
2166 	EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest);
2167 	EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&efuse_max, bPseudoTest);
2168 
2169 	if (efuseType == EFUSE_WIFI) {
2170 		if (bPseudoTest)
2171 			startAddr = (u16)(fakeEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN);
2172 		else {
2173 			rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
2174 			startAddr %= EFUSE_REAL_CONTENT_LEN;
2175 		}
2176 	} else {
2177 		if (bPseudoTest)
2178 			startAddr = (u16)(fakeBTEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN);
2179 		else
2180 			startAddr = (u16)(BTEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN);
2181 	}
2182 	/* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePartialWriteCheck(), startAddr=%d\n", startAddr)); */
2183 
2184 	while (1) {
2185 		if (startAddr >= efuse_max_available_len) {
2186 			bRet = _FALSE;
2187 			break;
2188 		}
2189 
2190 		if (efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
2191 			if (EXT_HEADER(efuse_data)) {
2192 				cur_header = efuse_data;
2193 				startAddr++;
2194 				efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest);
2195 				if (ALL_WORDS_DISABLED(efuse_data)) {
2196 					/* RTPRINT(FEEPROM, EFUSE_PG, ("Error condition, all words disabled")); */
2197 					bRet = _FALSE;
2198 					break;
2199 				} else {
2200 					curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2201 					curPkt.word_en = efuse_data & 0x0F;
2202 				}
2203 			} else {
2204 				cur_header  =  efuse_data;
2205 				curPkt.offset = (cur_header >> 4) & 0x0F;
2206 				curPkt.word_en = cur_header & 0x0F;
2207 			}
2208 
2209 			curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
2210 			/* if same header is found but no data followed */
2211 			/* write some part of data followed by the header. */
2212 			if ((curPkt.offset == pTargetPkt->offset) &&
2213 			    (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr + 1, bPseudoTest)) &&
2214 			    wordEnMatched(pTargetPkt, &curPkt, &matched_wden)) {
2215 				/* RTPRINT(FEEPROM, EFUSE_PG, ("Need to partial write data by the previous wrote header\n")); */
2216 				/* Here to write partial data */
2217 				badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr + 1, matched_wden, pTargetPkt->data, bPseudoTest);
2218 				if (badworden != 0x0F) {
2219 					u32	PgWriteSuccess = 0;
2220 					/* if write fail on some words, write these bad words again */
2221 
2222 					PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2223 
2224 					if (!PgWriteSuccess) {
2225 						bRet = _FALSE;	/* write fail, return */
2226 						break;
2227 					}
2228 				}
2229 				/* partial write ok, update the target packet for later use */
2230 				for (i = 0; i < 4; i++) {
2231 					if ((matched_wden & (0x1 << i)) == 0) {	/* this word has been written */
2232 						pTargetPkt->word_en |= (0x1 << i);	/* disable the word */
2233 					}
2234 				}
2235 				pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2236 			}
2237 			/* read from next header */
2238 			startAddr = startAddr + (curPkt.word_cnts * 2) + 1;
2239 		} else {
2240 			/* not used header, 0xff */
2241 			*pAddr = startAddr;
2242 			/* RTPRINT(FEEPROM, EFUSE_PG, ("Started from unused header offset=%d\n", startAddr)); */
2243 			bRet = _TRUE;
2244 			break;
2245 		}
2246 	}
2247 	return bRet;
2248 }
2249 
2250 static BOOLEAN
hal_EfusePgCheckAvailableAddr(PADAPTER pAdapter,u8 efuseType,BOOLEAN bPseudoTest)2251 hal_EfusePgCheckAvailableAddr(
2252 		PADAPTER	pAdapter,
2253 		u8			efuseType,
2254 		BOOLEAN		bPseudoTest
2255 )
2256 {
2257 	u16	efuse_max_available_len = 0;
2258 
2259 	/* Change to check TYPE_EFUSE_MAP_LEN ,beacuse 8188E raw 256,logic map over 256. */
2260 	EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len, _FALSE);
2261 
2262 	/* EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&efuse_max_available_len, bPseudoTest); */
2263 	/* RTPRINT(FEEPROM, EFUSE_PG, ("efuse_max_available_len = %d\n", efuse_max_available_len)); */
2264 
2265 	if (Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len) {
2266 		/* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgCheckAvailableAddr error!!\n")); */
2267 		return _FALSE;
2268 	}
2269 	return _TRUE;
2270 }
2271 
2272 static void
hal_EfuseConstructPGPkt(u8 offset,u8 word_en,u8 * pData,PPGPKT_STRUCT pTargetPkt)2273 hal_EfuseConstructPGPkt(
2274 		u8				offset,
2275 		u8				word_en,
2276 		u8				*pData,
2277 		PPGPKT_STRUCT	pTargetPkt
2278 
2279 )
2280 {
2281 	_rtw_memset((void *)pTargetPkt->data, 0xFF, sizeof(u8) * 8);
2282 	pTargetPkt->offset = offset;
2283 	pTargetPkt->word_en = word_en;
2284 	efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
2285 	pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2286 
2287 	/* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseConstructPGPkt(), targetPkt, offset=%d, word_en=0x%x, word_cnts=%d\n", pTargetPkt->offset, pTargetPkt->word_en, pTargetPkt->word_cnts)); */
2288 }
2289 
2290 
2291 
2292 static BOOLEAN
hal_EfusePgPacketWrite_8188e(PADAPTER pAdapter,u8 offset,u8 word_en,u8 * pData,BOOLEAN bPseudoTest)2293 hal_EfusePgPacketWrite_8188e(
2294 		PADAPTER		pAdapter,
2295 		u8			offset,
2296 		u8			word_en,
2297 		u8			*pData,
2298 		BOOLEAN		bPseudoTest
2299 )
2300 {
2301 	PGPKT_STRUCT	targetPkt;
2302 	u16			startAddr = 0;
2303 	u8			efuseType = EFUSE_WIFI;
2304 
2305 	if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
2306 		return _FALSE;
2307 
2308 	hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2309 
2310 	if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2311 		return _FALSE;
2312 
2313 	if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2314 		return _FALSE;
2315 
2316 	if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2317 		return _FALSE;
2318 
2319 	return _TRUE;
2320 }
2321 
2322 
2323 static int
Hal_EfusePgPacketWrite_Pseudo(PADAPTER pAdapter,u8 offset,u8 word_en,u8 * data,BOOLEAN bPseudoTest)2324 Hal_EfusePgPacketWrite_Pseudo(PADAPTER	pAdapter,
2325 					u8			offset,
2326 					u8			word_en,
2327 					u8			*data,
2328 					BOOLEAN		bPseudoTest)
2329 {
2330 	int ret;
2331 
2332 	ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
2333 
2334 	return ret;
2335 }
2336 
2337 static int
Hal_EfusePgPacketWrite(PADAPTER pAdapter,u8 offset,u8 word_en,u8 * data,BOOLEAN bPseudoTest)2338 Hal_EfusePgPacketWrite(PADAPTER	pAdapter,
2339 				u8			offset,
2340 				u8			word_en,
2341 				u8			*data,
2342 				BOOLEAN		bPseudoTest)
2343 {
2344 	int	ret = 0;
2345 	ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
2346 
2347 
2348 	return ret;
2349 }
2350 
2351 static int
rtl8188e_Efuse_PgPacketWrite(PADAPTER pAdapter,u8 offset,u8 word_en,u8 * data,BOOLEAN bPseudoTest)2352 rtl8188e_Efuse_PgPacketWrite(PADAPTER	pAdapter,
2353 					u8			offset,
2354 					u8			word_en,
2355 					u8			*data,
2356 					BOOLEAN		bPseudoTest)
2357 {
2358 	int	ret;
2359 
2360 	if (bPseudoTest)
2361 		ret = Hal_EfusePgPacketWrite_Pseudo(pAdapter, offset, word_en, data, bPseudoTest);
2362 	else
2363 		ret = Hal_EfusePgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);
2364 	return ret;
2365 }
2366 
read_chip_version_8188e(PADAPTER padapter)2367 static void read_chip_version_8188e(PADAPTER padapter)
2368 {
2369 	u32				value32;
2370 	HAL_DATA_TYPE	*pHalData;
2371 
2372 	pHalData = GET_HAL_DATA(padapter);
2373 
2374 	value32 = rtw_read32(padapter, REG_SYS_CFG);
2375 	pHalData->version_id.ICType = CHIP_8188E;
2376 	pHalData->version_id.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
2377 
2378 	pHalData->version_id.RFType = RF_TYPE_1T1R;
2379 	pHalData->version_id.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
2380 	pHalData->version_id.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */
2381 
2382 	/* For regulator mode. by tynli. 2011.01.14 */
2383 	pHalData->RegulatorMode = ((value32 & TRP_BT_EN) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
2384 
2385 	pHalData->version_id.ROMVer = 0;	/* ROM code version.	 */
2386 	pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
2387 
2388 	rtw_hal_config_rftype(padapter);
2389 
2390 #if 1
2391 	dump_chip_info(pHalData->version_id);
2392 #endif
2393 
2394 }
2395 
rtl8188e_start_thread(_adapter * padapter)2396 void rtl8188e_start_thread(_adapter *padapter)
2397 {
2398 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2399 #ifndef CONFIG_SDIO_TX_TASKLET
2400 	struct xmit_priv *xmitpriv = &padapter->xmitpriv;
2401 
2402 	if (xmitpriv->SdioXmitThread == NULL) {
2403 		RTW_INFO(FUNC_ADPT_FMT " start RTWHALXT\n", FUNC_ADPT_ARG(padapter));
2404 		xmitpriv->SdioXmitThread = kthread_run(rtl8188es_xmit_thread, padapter, "RTWHALXT");
2405 		if (IS_ERR(xmitpriv->SdioXmitThread)) {
2406 			RTW_ERR("%s: start rtl8188es_xmit_thread FAIL!!\n", __func__);
2407 			xmitpriv->SdioXmitThread = NULL;
2408 		}
2409 	}
2410 #endif
2411 #endif
2412 }
2413 
rtl8188e_stop_thread(_adapter * padapter)2414 void rtl8188e_stop_thread(_adapter *padapter)
2415 {
2416 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2417 #ifndef CONFIG_SDIO_TX_TASKLET
2418 	struct xmit_priv *xmitpriv = &padapter->xmitpriv;
2419 
2420 	/* stop xmit_buf_thread */
2421 	if (xmitpriv->SdioXmitThread) {
2422 		_rtw_up_sema(&xmitpriv->SdioXmitSema);
2423 		rtw_thread_stop(xmitpriv->SdioXmitThread);
2424 		xmitpriv->SdioXmitThread = NULL;
2425 	}
2426 #endif
2427 #endif
2428 }
hal_notch_filter_8188e(_adapter * adapter,bool enable)2429 void hal_notch_filter_8188e(_adapter *adapter, bool enable)
2430 {
2431 	if (enable) {
2432 		RTW_INFO("Enable notch filter\n");
2433 		rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT1);
2434 	} else {
2435 		RTW_INFO("Disable notch filter\n");
2436 		rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT1);
2437 	}
2438 }
2439 
init_hal_spec_8188e(_adapter * adapter)2440 void init_hal_spec_8188e(_adapter *adapter)
2441 {
2442 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2443 
2444 	hal_spec->ic_name = "rtl8188e";
2445 	hal_spec->macid_num = 64;
2446 	hal_spec->sec_cam_ent_num = 32;
2447 	hal_spec->sec_cap = 0;
2448 	hal_spec->macid_cap = MACID_DROP;
2449 
2450 	hal_spec->rfpath_num_2g = 1;
2451 	hal_spec->rfpath_num_5g = 0;
2452 	hal_spec->txgi_max = 63;
2453 	hal_spec->txgi_pdbm = 2;
2454 	hal_spec->max_tx_cnt = 1;
2455 	hal_spec->tx_nss_num = 1;
2456 	hal_spec->rx_nss_num = 1;
2457 	hal_spec->band_cap = BAND_CAP_2G;
2458 	hal_spec->bw_cap = BW_CAP_20M | BW_CAP_40M;
2459 	hal_spec->port_num = 2;
2460 	hal_spec->proto_cap = PROTO_CAP_11B | PROTO_CAP_11G | PROTO_CAP_11N;
2461 	hal_spec->wl_func = 0
2462 			    | WL_FUNC_P2P
2463 			    | WL_FUNC_MIRACAST
2464 			    | WL_FUNC_TDLS
2465 			    ;
2466 
2467 #if CONFIG_TX_AC_LIFETIME
2468 	hal_spec->tx_aclt_unit_factor = 1;
2469 #endif
2470 
2471 	hal_spec->pg_txpwr_saddr = 0x10;
2472 	hal_spec->pg_txgi_diff_factor = 1;
2473 
2474 	rtw_macid_ctl_init_sleep_reg(adapter_to_macidctl(adapter)
2475 		, REG_MACID_PAUSE_0
2476 		, REG_MACID_PAUSE_1, 0, 0);
2477 	rtw_macid_ctl_init_drop_reg(adapter_to_macidctl(adapter)
2478 		, REG_MACID_NO_LINK_0
2479 		, REG_MACID_NO_LINK_1
2480 		, 0, 0);
2481 
2482 }
2483 
2484 #ifdef CONFIG_RFKILL_POLL
rtl8188e_gpio_radio_on_off_check(_adapter * adapter,u8 * valid)2485 bool rtl8188e_gpio_radio_on_off_check(_adapter *adapter, u8 *valid)
2486 {
2487 	u32 tmp32;
2488 	bool ret;
2489 
2490 #ifdef CONFIG_PCI_HCI
2491 #if 1
2492 	*valid = 0;
2493 	return _FALSE; /* unblock */
2494 #else
2495 	tmp32  = rtw_read32(adapter, REG_GSSR);
2496 	ret = (tmp32 & BIT(31)) ? _FALSE : _TRUE;	/* Power down pin output value, low active */
2497 	*valid = 1;
2498 
2499 	return ret;
2500 #endif
2501 #else
2502 	*valid = 0;
2503 	return _FALSE; /* unblock */
2504 #endif
2505 }
2506 #endif
2507 
2508 
InitBeaconParameters_8188e(_adapter * adapter)2509 void InitBeaconParameters_8188e(_adapter *adapter)
2510 {
2511 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
2512 
2513 	rtw_write16(adapter, REG_BCN_CTRL, (DIS_TSF_UDT << 8) | DIS_TSF_UDT);
2514 
2515 	/* TBTT setup time */
2516 	rtw_write8(adapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
2517 
2518 	/* TBTT hold time: 0x540[19:8] */
2519 	rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
2520 	rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
2521 		(rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
2522 
2523 	rtw_write8(adapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8188E); /* 5ms */
2524 	rtw_write8(adapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8188E); /* 2ms */
2525 
2526 	/* Suggested by designer timchen. Change beacon AIFS to the largest number */
2527 	/* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
2528 	rtw_write16(adapter, REG_BCNTCFG, 0x4413);
2529 
2530 }
2531 
2532 static void
_BeaconFunctionEnable(PADAPTER padapter,BOOLEAN Enable,BOOLEAN Linked)2533 _BeaconFunctionEnable(
2534 		PADAPTER		padapter,
2535 		BOOLEAN			Enable,
2536 		BOOLEAN			Linked
2537 )
2538 {
2539 	rtw_write8(padapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB));
2540 
2541 	rtw_write8(padapter, REG_RD_CTRL + 1, 0x6F);
2542 }
2543 
SetBeaconRelatedRegisters8188E(PADAPTER padapter)2544 void SetBeaconRelatedRegisters8188E(PADAPTER padapter)
2545 {
2546 	u32	value32;
2547 	/* HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter); */
2548 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
2549 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
2550 	u32 bcn_ctrl_reg		= REG_BCN_CTRL;
2551 	/* reset TSF, enable update TSF, correcting TSF On Beacon */
2552 
2553 	/* REG_MBSSID_BCN_SPACE */
2554 	/* REG_BCNDMATIM */
2555 	/* REG_ATIMWND */
2556 	/* REG_TBTT_PROHIBIT */
2557 	/* REG_DRVERLYINT */
2558 	/* REG_BCN_MAX_ERR */
2559 	/* REG_BCNTCFG */ /* (0x510) */
2560 	/* REG_DUAL_TSF_RST */
2561 	/* REG_BCN_CTRL */ /* (0x550) */
2562 
2563 
2564 #ifdef CONFIG_CONCURRENT_MODE
2565 	if (padapter->hw_port == HW_PORT1)
2566 		bcn_ctrl_reg = REG_BCN_CTRL_1;
2567 #endif
2568 	/*  */
2569 	/* ATIM window */
2570 	/*  */
2571 	rtw_write16(padapter, REG_ATIMWND, 2);
2572 
2573 	/*  */
2574 	/* Beacon interval (in unit of TU). */
2575 	/*  */
2576 	rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)&pmlmeinfo->bcn_interval);
2577 
2578 	InitBeaconParameters_8188e(padapter);
2579 
2580 	rtw_write8(padapter, REG_SLOT, 0x09);
2581 
2582 	/*  */
2583 	/* Force beacon frame transmission even after receiving beacon frame from other ad hoc STA */
2584 	/*  */
2585 	/* PlatformEFIOWrite1Byte(Adapter, BCN_ERR_THRESH, 0x0a); */ /* We force beacon sent to prevent unexpect disconnect status in Ad hoc mode */
2586 
2587 	/*  */
2588 	/* Reset TSF Timer to zero, added by Roger. 2008.06.24 */
2589 	/*  */
2590 	value32 = rtw_read32(padapter, REG_TCR);
2591 	value32 &= ~TSFRST;
2592 	rtw_write32(padapter,  REG_TCR, value32);
2593 
2594 	value32 |= TSFRST;
2595 	rtw_write32(padapter, REG_TCR, value32);
2596 
2597 	/* TODO: Modify later (Find the right parameters) */
2598 	/* NOTE: Fix test chip's bug (about contention windows's randomness) */
2599 	if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE) == _TRUE) {
2600 		rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
2601 		rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
2602 	}
2603 
2604 	_BeaconFunctionEnable(padapter, _TRUE, _TRUE);
2605 
2606 	ResumeTxBeacon(padapter);
2607 	rtw_write8(padapter, bcn_ctrl_reg, rtw_read8(padapter, bcn_ctrl_reg) | DIS_BCNQ_SUB);
2608 }
2609 
rtl8188e_read_wmmedca_reg(PADAPTER adapter,u16 * vo_params,u16 * vi_params,u16 * be_params,u16 * bk_params)2610 void rtl8188e_read_wmmedca_reg(PADAPTER adapter, u16 *vo_params, u16 *vi_params, u16 *be_params, u16 *bk_params)
2611 {
2612 	u8 vo_reg_params[4];
2613 	u8 vi_reg_params[4];
2614 	u8 be_reg_params[4];
2615 	u8 bk_reg_params[4];
2616 
2617 	GetHwReg8188E(adapter, HW_VAR_AC_PARAM_VO, vo_reg_params);
2618 	GetHwReg8188E(adapter, HW_VAR_AC_PARAM_VI, vi_reg_params);
2619 	GetHwReg8188E(adapter, HW_VAR_AC_PARAM_BE, be_reg_params);
2620 	GetHwReg8188E(adapter, HW_VAR_AC_PARAM_BK, bk_reg_params);
2621 
2622 	vo_params[0] = vo_reg_params[0];
2623 	vo_params[1] = vo_reg_params[1] & 0x0F;
2624 	vo_params[2] = (vo_reg_params[1] & 0xF0) >> 4;
2625 	vo_params[3] = ((vo_reg_params[3] << 8) | (vo_reg_params[2])) * 32;
2626 
2627 	vi_params[0] = vi_reg_params[0];
2628 	vi_params[1] = vi_reg_params[1] & 0x0F;
2629 	vi_params[2] = (vi_reg_params[1] & 0xF0) >> 4;
2630 	vi_params[3] = ((vi_reg_params[3] << 8) | (vi_reg_params[2])) * 32;
2631 
2632 	be_params[0] = be_reg_params[0];
2633 	be_params[1] = be_reg_params[1] & 0x0F;
2634 	be_params[2] = (be_reg_params[1] & 0xF0) >> 4;
2635 	be_params[3] = ((be_reg_params[3] << 8) | (be_reg_params[2])) * 32;
2636 
2637 	bk_params[0] = bk_reg_params[0];
2638 	bk_params[1] = bk_reg_params[1] & 0x0F;
2639 	bk_params[2] = (bk_reg_params[1] & 0xF0) >> 4;
2640 	bk_params[3] = ((bk_reg_params[3] << 8) | (bk_reg_params[2])) * 32;
2641 
2642 	vo_params[1] = (1 << vo_params[1]) - 1;
2643 	vo_params[2] = (1 << vo_params[2]) - 1;
2644 	vi_params[1] = (1 << vi_params[1]) - 1;
2645 	vi_params[2] = (1 << vi_params[2]) - 1;
2646 	be_params[1] = (1 << be_params[1]) - 1;
2647 	be_params[2] = (1 << be_params[2]) - 1;
2648 	bk_params[1] = (1 << bk_params[1]) - 1;
2649 	bk_params[2] = (1 << bk_params[2]) - 1;
2650 }
2651 
rtl8188e_set_hal_ops(struct hal_ops * pHalFunc)2652 void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
2653 {
2654 	pHalFunc->dm_init = &rtl8188e_init_dm_priv;
2655 	pHalFunc->dm_deinit = &rtl8188e_deinit_dm_priv;
2656 
2657 	pHalFunc->read_chip_version = read_chip_version_8188e;
2658 
2659 	pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8188E;
2660 
2661 	pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8188E;
2662 	pHalFunc->set_tx_power_index_handler = PHY_SetTxPowerIndex_8188E;
2663 	pHalFunc->get_tx_power_index_handler = &PHY_GetTxPowerIndex_8188E;
2664 
2665 	pHalFunc->hal_dm_watchdog = &rtl8188e_HalDmWatchDog;
2666 
2667 	pHalFunc->run_thread = &rtl8188e_start_thread;
2668 	pHalFunc->cancel_thread = &rtl8188e_stop_thread;
2669 
2670 	pHalFunc->read_bbreg = &PHY_QueryBBReg8188E;
2671 	pHalFunc->write_bbreg = &PHY_SetBBReg8188E;
2672 	pHalFunc->read_rfreg = &PHY_QueryRFReg8188E;
2673 	pHalFunc->write_rfreg = &PHY_SetRFReg8188E;
2674 
2675 	pHalFunc->read_wmmedca_reg = &rtl8188e_read_wmmedca_reg;
2676 
2677 	/* Efuse related function */
2678 	pHalFunc->EfusePowerSwitch = &rtl8188e_EfusePowerSwitch;
2679 	pHalFunc->ReadEFuse = &rtl8188e_ReadEFuse;
2680 	pHalFunc->EFUSEGetEfuseDefinition = &rtl8188e_EFUSE_GetEfuseDefinition;
2681 	pHalFunc->EfuseGetCurrentSize = &rtl8188e_EfuseGetCurrentSize;
2682 	pHalFunc->Efuse_PgPacketRead = &rtl8188e_Efuse_PgPacketRead;
2683 	pHalFunc->Efuse_PgPacketWrite = &rtl8188e_Efuse_PgPacketWrite;
2684 	pHalFunc->Efuse_WordEnableDataWrite = &rtl8188e_Efuse_WordEnableDataWrite;
2685 
2686 #ifdef DBG_CONFIG_ERROR_DETECT
2687 	pHalFunc->sreset_init_value = &sreset_init_value;
2688 	pHalFunc->sreset_reset_value = &sreset_reset_value;
2689 	pHalFunc->silentreset = &sreset_reset;
2690 	pHalFunc->sreset_xmit_status_check = &rtl8188e_sreset_xmit_status_check;
2691 	pHalFunc->sreset_linked_status_check  = &rtl8188e_sreset_linked_status_check;
2692 	pHalFunc->sreset_get_wifi_status  = &sreset_get_wifi_status;
2693 	pHalFunc->sreset_inprogress = &sreset_inprogress;
2694 #endif /* DBG_CONFIG_ERROR_DETECT */
2695 
2696 	pHalFunc->GetHalODMVarHandler = GetHalODMVar;
2697 	pHalFunc->SetHalODMVarHandler = SetHalODMVar;
2698 
2699 #ifdef CONFIG_IOL
2700 	pHalFunc->IOL_exec_cmds_sync = &rtl8188e_IOL_exec_cmds_sync;
2701 #endif
2702 
2703 	pHalFunc->hal_notch_filter = &hal_notch_filter_8188e;
2704 	pHalFunc->fill_h2c_cmd = &FillH2CCmd_88E;
2705 	pHalFunc->fill_fake_txdesc = &rtl8188e_fill_fake_txdesc;
2706 	pHalFunc->fw_dl = &rtl8188e_FirmwareDownload;
2707 	pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8188E;
2708 
2709 #ifdef CONFIG_GPIO_API
2710         pHalFunc->hal_gpio_func_check = &rtl8188e_GpioFuncCheck;
2711 #endif
2712 #ifdef CONFIG_RFKILL_POLL
2713 	pHalFunc->hal_radio_onoff_check = rtl8188e_gpio_radio_on_off_check;
2714 #endif
2715 }
2716 
GetEEPROMSize8188E(PADAPTER padapter)2717 u8 GetEEPROMSize8188E(PADAPTER padapter)
2718 {
2719 	u8 size = 0;
2720 	u32	cr;
2721 
2722 	cr = rtw_read16(padapter, REG_9346CR);
2723 	/* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
2724 	size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
2725 
2726 	RTW_INFO("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
2727 
2728 	return size;
2729 }
2730 
2731 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_PCI_HCI) || defined(CONFIG_GSPI_HCI)
2732 /* -------------------------------------------------------------------------
2733  *
2734  * LLT R/W/Init function
2735  *
2736  * ------------------------------------------------------------------------- */
_LLTWrite(PADAPTER padapter,u32 address,u32 data)2737 s32 _LLTWrite(PADAPTER padapter, u32 address, u32 data)
2738 {
2739 	s32	status = _SUCCESS;
2740 	s8	count = POLLING_LLT_THRESHOLD;
2741 	u32	value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
2742 
2743 	rtw_write32(padapter, REG_LLT_INIT, value);
2744 
2745 	/* polling */
2746 	do {
2747 		value = rtw_read32(padapter, REG_LLT_INIT);
2748 		if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
2749 			break;
2750 	} while (--count);
2751 
2752 	if (count <= 0) {
2753 		RTW_INFO("Failed to polling write LLT done at address %d!\n", address);
2754 		status = _FAIL;
2755 	}
2756 
2757 	return status;
2758 }
2759 
_LLTRead(PADAPTER padapter,u32 address)2760 u8 _LLTRead(PADAPTER padapter, u32 address)
2761 {
2762 	s32	count = POLLING_LLT_THRESHOLD;
2763 	u32	value = _LLT_INIT_ADDR(address) | _LLT_OP(_LLT_READ_ACCESS);
2764 	u16	LLTReg = REG_LLT_INIT;
2765 
2766 
2767 	rtw_write32(padapter, LLTReg, value);
2768 
2769 	/* polling and get value */
2770 	do {
2771 		value = rtw_read32(padapter, LLTReg);
2772 		if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
2773 			return (u8)value;
2774 	} while (--count);
2775 
2776 
2777 
2778 
2779 	return 0xFF;
2780 }
2781 
InitLLTTable(PADAPTER padapter,u8 txpktbuf_bndy)2782 s32 InitLLTTable(PADAPTER padapter, u8 txpktbuf_bndy)
2783 {
2784 	s32	status = _FAIL;
2785 	u32	i;
2786 	u32	Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER_8188E(padapter);/* 176, 22k */
2787 	HAL_DATA_TYPE *pHalData	= GET_HAL_DATA(padapter);
2788 
2789 #if defined(CONFIG_IOL_LLT)
2790 	if (rtw_IOL_applied(padapter))
2791 		status = iol_InitLLTTable(padapter, txpktbuf_bndy);
2792 	else
2793 #endif
2794 	{
2795 		for (i = 0; i < (txpktbuf_bndy - 1); i++) {
2796 			status = _LLTWrite(padapter, i, i + 1);
2797 			if (_SUCCESS != status)
2798 				return status;
2799 		}
2800 
2801 		/* end of list */
2802 		status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
2803 		if (_SUCCESS != status)
2804 			return status;
2805 
2806 		/* Make the other pages as ring buffer */
2807 		/* This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer. */
2808 		/* Otherwise used as local loopback buffer. */
2809 		for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
2810 			status = _LLTWrite(padapter, i, (i + 1));
2811 			if (_SUCCESS != status)
2812 				return status;
2813 		}
2814 
2815 		/* Let last entry point to the start entry of ring buffer */
2816 		status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
2817 		if (_SUCCESS != status)
2818 			return status;
2819 	}
2820 
2821 	return status;
2822 }
2823 #endif
2824 
2825 
2826 void
Hal_InitPGData88E(PADAPTER padapter)2827 Hal_InitPGData88E(PADAPTER	padapter)
2828 {
2829 
2830 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2831 	u32			i;
2832 	u16			value16;
2833 
2834 	if (_FALSE == pHalData->bautoload_fail_flag) {
2835 		/* autoload OK. */
2836 		if (is_boot_from_eeprom(padapter)) {
2837 			/* Read all Content from EEPROM or EFUSE. */
2838 			for (i = 0; i < HWSET_MAX_SIZE; i += 2) {
2839 				/*				value16 = EF2Byte(ReadEEprom(pAdapter, (u16) (i>>1)));
2840 				 *				*((u16*)(&PROMContent[i])) = value16; */
2841 			}
2842 		} else {
2843 			/* Read EFUSE real map to shadow. */
2844 			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
2845 		}
2846 	} else {
2847 		/* autoload fail */
2848 		/*		pHalData->AutoloadFailFlag = _TRUE; */
2849 		/* update to default value 0xFF */
2850 		if (!is_boot_from_eeprom(padapter))
2851 			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
2852 	}
2853 
2854 #ifdef CONFIG_EFUSE_CONFIG_FILE
2855 	if (check_phy_efuse_tx_power_info_valid(padapter) == _FALSE) {
2856 		if (Hal_readPGDataFromConfigFile(padapter) != _SUCCESS)
2857 			RTW_ERR("invalid phy efuse and read from file fail, will use driver default!!\n");
2858 	}
2859 #endif
2860 }
2861 
2862 void
Hal_EfuseParseIDCode88E(PADAPTER padapter,u8 * hwinfo)2863 Hal_EfuseParseIDCode88E(
2864 		PADAPTER	padapter,
2865 		u8			*hwinfo
2866 )
2867 {
2868 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2869 	u16			EEPROMId;
2870 
2871 
2872 	/* Checl 0x8129 again for making sure autoload status!! */
2873 	EEPROMId = le16_to_cpu(*((u16 *)hwinfo));
2874 	if (EEPROMId != RTL_EEPROM_ID) {
2875 		RTW_INFO("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
2876 		pHalData->bautoload_fail_flag = _TRUE;
2877 	} else
2878 		pHalData->bautoload_fail_flag = _FALSE;
2879 
2880 	RTW_INFO("EEPROM ID=0x%04x\n", EEPROMId);
2881 }
2882 
Hal_ReadPowerSavingMode88E(PADAPTER padapter,u8 * hwinfo,BOOLEAN AutoLoadFail)2883 void Hal_ReadPowerSavingMode88E(
2884 	PADAPTER		padapter,
2885 		u8			*hwinfo,
2886 		BOOLEAN			AutoLoadFail
2887 )
2888 {
2889 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2890 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
2891 	u8 tmpvalue;
2892 
2893 	if (AutoLoadFail) {
2894 		pwrctl->bHWPowerdown = _FALSE;
2895 		pwrctl->bSupportRemoteWakeup = _FALSE;
2896 	} else	{
2897 
2898 		/* hw power down mode selection , 0:rf-off / 1:power down */
2899 
2900 		if (padapter->registrypriv.hwpdn_mode == 2)
2901 			pwrctl->bHWPowerdown = (hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & BIT4);
2902 		else
2903 			pwrctl->bHWPowerdown = padapter->registrypriv.hwpdn_mode;
2904 
2905 		/* decide hw if support remote wakeup function */
2906 		/* if hw supported, 8051 (SIE) will generate WeakUP signal( D+/D- toggle) when autoresume */
2907 #ifdef CONFIG_USB_HCI
2908 		pwrctl->bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT1) ? _TRUE : _FALSE;
2909 #endif /* CONFIG_USB_HCI */
2910 
2911 		RTW_INFO("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) ,bSupportRemoteWakeup(%x)\n", __FUNCTION__,
2912 			pwrctl->bHWPwrPindetect, pwrctl->bHWPowerdown, pwrctl->bSupportRemoteWakeup);
2913 
2914 		RTW_INFO("### PS params=>  power_mgnt(%x),usbss_enable(%x) ###\n", padapter->registrypriv.power_mgnt, padapter->registrypriv.usbss_enable);
2915 
2916 	}
2917 
2918 }
2919 
2920 void
Hal_ReadTxPowerInfo88E(PADAPTER padapter,u8 * PROMContent,BOOLEAN AutoLoadFail)2921 Hal_ReadTxPowerInfo88E(
2922 		PADAPTER		padapter,
2923 		u8				*PROMContent,
2924 		BOOLEAN			AutoLoadFail
2925 )
2926 {
2927 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2928 	TxPowerInfo24G pwrInfo24G;
2929 
2930 	hal_load_txpwr_info(padapter, &pwrInfo24G, NULL, PROMContent);
2931 
2932 	/* 2010/10/19 MH Add Regulator recognize for EU. */
2933 	if (!AutoLoadFail) {
2934 		struct registry_priv  *registry_par = &padapter->registrypriv;
2935 
2936 		if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2937 			pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7);	/* bit0~2 */
2938 		else
2939 			pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x7);	/* bit0~2 */
2940 
2941 	} else
2942 		pHalData->EEPROMRegulatory = 0;
2943 	RTW_INFO("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory);
2944 
2945 }
2946 
2947 
2948 void
Hal_EfuseParseXtal_8188E(PADAPTER pAdapter,u8 * hwinfo,BOOLEAN AutoLoadFail)2949 Hal_EfuseParseXtal_8188E(
2950 		PADAPTER		pAdapter,
2951 		u8			*hwinfo,
2952 		BOOLEAN		AutoLoadFail
2953 )
2954 {
2955 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
2956 
2957 	if (!AutoLoadFail) {
2958 		pHalData->crystal_cap = hwinfo[EEPROM_XTAL_88E];
2959 		if (pHalData->crystal_cap == 0xFF)
2960 			pHalData->crystal_cap = EEPROM_Default_CrystalCap_88E;
2961 	} else
2962 		pHalData->crystal_cap = EEPROM_Default_CrystalCap_88E;
2963 	RTW_INFO("crystal_cap: 0x%2x\n", pHalData->crystal_cap);
2964 }
2965 
2966 void
Hal_ReadPAType_8188E(PADAPTER Adapter,u8 * PROMContent,BOOLEAN AutoloadFail)2967 Hal_ReadPAType_8188E(
2968 		PADAPTER	Adapter,
2969 		u8			*PROMContent,
2970 		BOOLEAN		AutoloadFail
2971 )
2972 {
2973 	HAL_DATA_TYPE		*pHalData = GET_HAL_DATA(Adapter);
2974 	u8			PA_LNAType_2G = 0;
2975 
2976 	if (!AutoloadFail) {
2977 		if (GetRegAmplifierType2G(Adapter) == 0) { /* AUTO*/
2978 
2979 			/* PA & LNA Type */
2980 			PA_LNAType_2G = LE_BITS_TO_1BYTE(&PROMContent[EEPROM_RFE_OPTION_8188E], 2, 2); /* 0xCA[3:2] */
2981 			/*
2982 				ePA/eLNA sel.(ePA+eLNA=0x0, ePA+iLNA enable = 0x1, iPA+eLNA enable =0x2, iPA+iLNA=0x3)
2983 			*/
2984 			switch (PA_LNAType_2G) {
2985 			case 0:
2986 				pHalData->ExternalPA_2G  = 1;
2987 				pHalData->ExternalLNA_2G = 1;
2988 				break;
2989 			case 1:
2990 				pHalData->ExternalPA_2G  = 1;
2991 				pHalData->ExternalLNA_2G = 0;
2992 				break;
2993 			case 2:
2994 				pHalData->ExternalPA_2G  = 0;
2995 				pHalData->ExternalLNA_2G = 1;
2996 				break;
2997 			case 3:
2998 			default:
2999 				pHalData->ExternalPA_2G  = 0;
3000 				pHalData->ExternalLNA_2G = 0;
3001 				break;
3002 			}
3003 		} else {
3004 			pHalData->ExternalPA_2G  = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_PA)  ? 1 : 0;
3005 			pHalData->ExternalLNA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_LNA) ? 1 : 0;
3006 		}
3007 #if 0
3008 		if (GetRegAmplifierType5G(Adapter) == 0) { /*  AUTO */
3009 			pHalData->external_pa_5g = ((pHalData->PAType_5G & BIT1) && (pHalData->PAType_5G & BIT0)) ? 1 : 0;
3010 			pHalData->external_lna_5g = ((pHalData->LNAType_5G & BIT7) && (pHalData->LNAType_5G & BIT3)) ? 1 : 0;	/*  5G only now. */
3011 		} else {
3012 			pHalData->external_pa_5g	= (GetRegAmplifierType5G(Adapter) & ODM_BOARD_EXT_PA_5G)	? 1 : 0;
3013 			pHalData->external_lna_5g = (GetRegAmplifierType5G(Adapter) & ODM_BOARD_EXT_LNA_5G) ? 1 : 0;
3014 		}
3015 #endif
3016 	} else {
3017 		pHalData->ExternalPA_2G  = EEPROM_Default_PAType;
3018 		pHalData->external_pa_5g  = EEPROM_Default_PAType;
3019 		pHalData->ExternalLNA_2G = EEPROM_Default_LNAType;
3020 		pHalData->external_lna_5g = EEPROM_Default_LNAType;
3021 
3022 		if (GetRegAmplifierType2G(Adapter) == 0) {
3023 			/* AUTO*/
3024 			pHalData->ExternalPA_2G  = EEPROM_Default_PAType;
3025 			pHalData->ExternalLNA_2G = EEPROM_Default_LNAType;
3026 		} else {
3027 			pHalData->ExternalPA_2G  = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_PA)  ? 1 : 0;
3028 			pHalData->ExternalLNA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_LNA) ? 1 : 0;
3029 		}
3030 #if 0
3031 		if (GetRegAmplifierType5G(Adapter) == 0) {
3032 			/*  AUTO */
3033 			pHalData->external_pa_5g  = 0;
3034 			pHalData->external_lna_5g = 0;
3035 		} else {
3036 			pHalData->external_pa_5g  = (GetRegAmplifierType5G(Adapter) & ODM_BOARD_EXT_PA_5G)  ? 1 : 0;
3037 			pHalData->external_lna_5g = (GetRegAmplifierType5G(Adapter) & ODM_BOARD_EXT_LNA_5G) ? 1 : 0;
3038 		}
3039 #endif
3040 	}
3041 	RTW_INFO("pHalData->ExternalPA_2G = %d , pHalData->ExternalLNA_2G = %d\n",  pHalData->ExternalPA_2G, pHalData->ExternalLNA_2G);
3042 }
3043 
3044 void
Hal_ReadAmplifierType_8188E(PADAPTER Adapter,u8 * PROMContent,BOOLEAN AutoloadFail)3045 Hal_ReadAmplifierType_8188E(
3046 		PADAPTER	Adapter,
3047 		u8			*PROMContent,
3048 		BOOLEAN		AutoloadFail
3049 )
3050 {
3051 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
3052 	u8	GLNA_type = 0;
3053 
3054 	if (!AutoloadFail) {
3055 		if (GetRegGLNAType(Adapter) == 0) /* AUTO */
3056 			GLNA_type = LE_BITS_TO_1BYTE(&PROMContent[EEPROM_RFE_OPTION_8188E], 4, 3); /* 0xCA[6:4] */
3057 		else
3058 			GLNA_type  = GetRegGLNAType(Adapter) & 0x7;
3059 	} else {
3060 		if (GetRegGLNAType(Adapter) == 0) /* AUTO */
3061 			GLNA_type = 0;
3062 		else
3063 			GLNA_type  = GetRegGLNAType(Adapter) & 0x7;
3064 	}
3065 	/*
3066 		Ext-LNA Gain sel.(form 10dB to 24dB, 1table/2dB,ext: 000=10dB, 001=12dB...)
3067 	*/
3068 	switch (GLNA_type) {
3069 	case 0:
3070 		pHalData->TypeGLNA = 0x1; /* (10dB) */
3071 		break;
3072 	case 2:
3073 		pHalData->TypeGLNA = 0x2; /* (14dB) */
3074 		break;
3075 	default:
3076 		pHalData->TypeGLNA = 0x0; /* (others not support) */
3077 		break;
3078 	}
3079 	RTW_INFO("pHalData->TypeGLNA is 0x%x\n", pHalData->TypeGLNA);
3080 }
3081 
3082 void
Hal_ReadRFEType_8188E(PADAPTER Adapter,u8 * PROMContent,BOOLEAN AutoloadFail)3083 Hal_ReadRFEType_8188E(
3084 		PADAPTER	Adapter,
3085 		u8			*PROMContent,
3086 		BOOLEAN		AutoloadFail
3087 )
3088 {
3089 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
3090 	/* Keep the same flow as 8192EU to be extensible */
3091 	const u8 RFETypeMaxVal = 1, RFETypeMask = 0x1;
3092 
3093 	if (!AutoloadFail) {
3094 		if (GetRegRFEType(Adapter) != 64) {
3095 			pHalData->rfe_type = GetRegRFEType(Adapter);
3096 			/*
3097 				Above 1, rfe_type is filled the default value.
3098 			*/
3099 			if (pHalData->rfe_type > RFETypeMaxVal)
3100 				pHalData->rfe_type = EEPROM_DEFAULT_RFE_OPTION_8188E;
3101 
3102 		} else if ((0xFF == PROMContent[EEPROM_RFE_OPTION_8188E]) ||
3103 			((pHalData->ExternalPA_2G == 0) && (pHalData->ExternalLNA_2G == 0)))
3104 			pHalData->rfe_type = EEPROM_DEFAULT_RFE_OPTION_8188E;
3105 		else {
3106 			/*
3107 				type 0:0x00 for 88EE/ER_HP RFE control
3108 			*/
3109 			pHalData->rfe_type = PROMContent[EEPROM_RFE_OPTION_8188E] & RFETypeMask; /* 0xCA[1:0] */
3110 		}
3111 	} else {
3112 		if (GetRegRFEType(Adapter) != 64) {
3113 			pHalData->rfe_type = GetRegRFEType(Adapter);
3114 			/*
3115 				 Above 3, rfe_type is filled the default value.
3116 			*/
3117 			if (pHalData->rfe_type > RFETypeMaxVal)
3118 				pHalData->rfe_type = EEPROM_DEFAULT_RFE_OPTION_8188E;
3119 
3120 		} else
3121 			pHalData->rfe_type = EEPROM_DEFAULT_RFE_OPTION_8188E;
3122 
3123 	}
3124 
3125 	RTW_INFO("pHalData->rfe_type is 0x%x\n", pHalData->rfe_type);
3126 }
3127 
3128 void
Hal_EfuseParseBoardType88E(PADAPTER pAdapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3129 Hal_EfuseParseBoardType88E(
3130 		PADAPTER		pAdapter,
3131 		u8				*hwinfo,
3132 		BOOLEAN			AutoLoadFail
3133 )
3134 {
3135 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
3136 
3137 	if (!AutoLoadFail) {
3138 		pHalData->InterfaceSel = ((hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0xE0) >> 5);
3139 		if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
3140 			pHalData->InterfaceSel = (EEPROM_DEFAULT_BOARD_OPTION & 0xE0) >> 5;
3141 	} else
3142 		pHalData->InterfaceSel = 0;
3143 	RTW_INFO("Board Type: 0x%2x\n", pHalData->InterfaceSel);
3144 }
3145 
3146 void
Hal_EfuseParseEEPROMVer88E(PADAPTER padapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3147 Hal_EfuseParseEEPROMVer88E(
3148 		PADAPTER		padapter,
3149 		u8			*hwinfo,
3150 		BOOLEAN			AutoLoadFail
3151 )
3152 {
3153 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
3154 
3155 	if (!AutoLoadFail) {
3156 		pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_88E];
3157 		if (pHalData->EEPROMVersion == 0xFF)
3158 			pHalData->EEPROMVersion = EEPROM_Default_Version;
3159 	} else
3160 		pHalData->EEPROMVersion = 1;
3161 }
3162 
3163 void
rtl8188e_EfuseParseChnlPlan(PADAPTER padapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3164 rtl8188e_EfuseParseChnlPlan(
3165 		PADAPTER		padapter,
3166 		u8			*hwinfo,
3167 		BOOLEAN			AutoLoadFail
3168 )
3169 {
3170 	hal_com_config_channel_plan(
3171 		padapter
3172 		, hwinfo ? &hwinfo[EEPROM_COUNTRY_CODE_88E] : NULL
3173 		, hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF
3174 		, padapter->registrypriv.alpha2
3175 		, padapter->registrypriv.channel_plan
3176 		, RTW_CHPLAN_WORLD_NULL
3177 		, AutoLoadFail
3178 	);
3179 }
3180 
3181 void
Hal_EfuseParseCustomerID88E(PADAPTER padapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3182 Hal_EfuseParseCustomerID88E(
3183 		PADAPTER		padapter,
3184 		u8			*hwinfo,
3185 		BOOLEAN			AutoLoadFail
3186 )
3187 {
3188 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
3189 
3190 	if (!AutoLoadFail) {
3191 		pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_88E];
3192 		/* pHalData->EEPROMSubCustomerID = hwinfo[EEPROM_CustomID_88E]; */
3193 	} else {
3194 		pHalData->EEPROMCustomerID = 0;
3195 		pHalData->EEPROMSubCustomerID = 0;
3196 	}
3197 	RTW_INFO("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID);
3198 	/* RTW_INFO("EEPROM SubCustomer ID: 0x%02x\n", pHalData->EEPROMSubCustomerID); */
3199 }
3200 
3201 
3202 void
Hal_ReadAntennaDiversity88E(PADAPTER pAdapter,u8 * PROMContent,BOOLEAN AutoLoadFail)3203 Hal_ReadAntennaDiversity88E(
3204 		PADAPTER		pAdapter,
3205 		u8				*PROMContent,
3206 		BOOLEAN			AutoLoadFail
3207 )
3208 {
3209 #ifdef CONFIG_ANTENNA_DIVERSITY
3210 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(pAdapter);
3211 	struct registry_priv	*registry_par = &pAdapter->registrypriv;
3212 
3213 	if (!AutoLoadFail) {
3214 		/* Antenna Diversity setting. */
3215 		if (registry_par->antdiv_cfg == 2) { /* 2:By EFUSE */
3216 			pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x18) >> 3;
3217 			if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
3218 				pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION & 0x18) >> 3;
3219 		} else {
3220 			pHalData->AntDivCfg = registry_par->antdiv_cfg ;  /* 0:OFF , 1:ON, 2:By EFUSE */
3221 		}
3222 
3223 		if (registry_par->antdiv_type == 0) { /* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */
3224 			pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E];
3225 			if (pHalData->TRxAntDivType == 0xFF)
3226 				pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; /* For 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */
3227 		} else
3228 			pHalData->TRxAntDivType = registry_par->antdiv_type ;
3229 
3230 		if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV)
3231 			pHalData->AntDivCfg = 1; /* 0xC1[3] is ignored. */
3232 	} else
3233 		pHalData->AntDivCfg = 0;
3234 
3235 	RTW_INFO("EEPROM : AntDivCfg = %x, TRxAntDivType = %x\n", pHalData->AntDivCfg, pHalData->TRxAntDivType);
3236 #endif
3237 }
3238 
3239 void
Hal_ReadThermalMeter_88E(PADAPTER Adapter,u8 * PROMContent,BOOLEAN AutoloadFail)3240 Hal_ReadThermalMeter_88E(
3241 		PADAPTER	Adapter,
3242 		u8			*PROMContent,
3243 		BOOLEAN	AutoloadFail
3244 )
3245 {
3246 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
3247 	u8			tempval;
3248 
3249 	/*  */
3250 	/* ThermalMeter from EEPROM */
3251 	/*  */
3252 	if (!AutoloadFail)
3253 		pHalData->eeprom_thermal_meter = PROMContent[EEPROM_THERMAL_METER_88E];
3254 	else
3255 		pHalData->eeprom_thermal_meter = EEPROM_Default_ThermalMeter_88E;
3256 	/* pHalData->eeprom_thermal_meter = (tempval&0x1f);	 */ /* [4:0] */
3257 
3258 	if (pHalData->eeprom_thermal_meter == 0xff || AutoloadFail) {
3259 		pHalData->odmpriv.rf_calibrate_info.is_apk_thermal_meter_ignore = _TRUE;
3260 		pHalData->eeprom_thermal_meter = EEPROM_Default_ThermalMeter_88E;
3261 	}
3262 
3263 	/* pHalData->ThermalMeter[0] = pHalData->eeprom_thermal_meter;	 */
3264 	RTW_INFO("ThermalMeter = 0x%x\n", pHalData->eeprom_thermal_meter);
3265 
3266 }
3267 
3268 #ifdef CONFIG_RF_POWER_TRIM
Hal_ReadRFGainOffset(PADAPTER Adapter,u8 * PROMContent,BOOLEAN AutoloadFail)3269 void Hal_ReadRFGainOffset(
3270 			PADAPTER	Adapter,
3271 			u8		*PROMContent,
3272 			BOOLEAN		AutoloadFail)
3273 {
3274 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
3275 	u8 thermal_offset = 0;
3276 	/*  */
3277 	/* BB_RF Gain Offset from EEPROM */
3278 	/*  */
3279 
3280 	if (!AutoloadFail) {
3281 		pHalData->EEPROMRFGainOffset = PROMContent[EEPROM_RF_GAIN_OFFSET];
3282 
3283 		if ((pHalData->EEPROMRFGainOffset  != 0xFF) &&
3284 		    (pHalData->EEPROMRFGainOffset & BIT4))
3285 			efuse_OneByteRead(Adapter, EEPROM_RF_GAIN_VAL, &pHalData->EEPROMRFGainVal, _FALSE);
3286 		else {
3287 			pHalData->EEPROMRFGainOffset = 0;
3288 			pHalData->EEPROMRFGainVal = 0;
3289 		}
3290 
3291 		RTW_INFO("pHalData->EEPROMRFGainVal=%x\n", pHalData->EEPROMRFGainVal);
3292 	} else {
3293 		efuse_OneByteRead(Adapter, EEPROM_RF_GAIN_VAL, &pHalData->EEPROMRFGainVal, _FALSE);
3294 
3295 		if (pHalData->EEPROMRFGainVal != 0xFF)
3296 			pHalData->EEPROMRFGainOffset = BIT4;
3297 		else
3298 			pHalData->EEPROMRFGainOffset = 0;
3299 		RTW_INFO("else AutoloadFail =%x,\n", AutoloadFail);
3300 	}
3301 
3302 	if (Adapter->registrypriv.RegPwrTrimEnable == 1) {
3303 		efuse_OneByteRead(Adapter, EEPROM_RF_GAIN_VAL, &pHalData->EEPROMRFGainVal, _FALSE);
3304 		RTW_INFO("pHalData->EEPROMRFGainVal=%x\n", pHalData->EEPROMRFGainVal);
3305 
3306 	}
3307 	/*  */
3308 	/* BB_RF Thermal Offset from EEPROM */
3309 	/*  */
3310 	if (((pHalData->EEPROMRFGainOffset != 0xFF) && (pHalData->EEPROMRFGainOffset & BIT4)) || (Adapter->registrypriv.RegPwrTrimEnable == 1)) {
3311 
3312 		efuse_OneByteRead(Adapter, EEPROM_THERMAL_OFFSET, &thermal_offset, _FALSE);
3313 		if (thermal_offset != 0xFF) {
3314 			if (thermal_offset & BIT0)
3315 				pHalData->eeprom_thermal_meter += ((thermal_offset >> 1) & 0x0F);
3316 			else
3317 				pHalData->eeprom_thermal_meter -= ((thermal_offset >> 1) & 0x0F);
3318 
3319 			RTW_INFO("%s =>thermal_offset:0x%02x pHalData->eeprom_thermal_meter=0x%02x\n", __FUNCTION__ , thermal_offset, pHalData->eeprom_thermal_meter);
3320 		}
3321 	}
3322 
3323 	RTW_INFO("%s => EEPRORFGainOffset = 0x%02x,EEPROMRFGainVal=0x%02x,thermal_offset:0x%02x\n",
3324 		__FUNCTION__, pHalData->EEPROMRFGainOffset, pHalData->EEPROMRFGainVal, thermal_offset);
3325 
3326 }
3327 
3328 #endif /*CONFIG_RF_POWER_TRIM*/
3329 
HalDetectPwrDownMode88E(PADAPTER Adapter)3330 BOOLEAN HalDetectPwrDownMode88E(PADAPTER Adapter)
3331 {
3332 	u8 tmpvalue = 0;
3333 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3334 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(Adapter);
3335 
3336 	EFUSE_ShadowRead(Adapter, 1, EEPROM_RF_FEATURE_OPTION_88E, (u32 *)&tmpvalue);
3337 
3338 	/* 2010/08/25 MH INF priority > PDN Efuse value. */
3339 	if (tmpvalue & BIT(4) && pwrctrlpriv->reg_pdnmode)
3340 		pHalData->pwrdown = _TRUE;
3341 	else
3342 		pHalData->pwrdown = _FALSE;
3343 
3344 	RTW_INFO("HalDetectPwrDownMode(): PDN=%d\n", pHalData->pwrdown);
3345 
3346 	return pHalData->pwrdown;
3347 }	/* HalDetectPwrDownMode */
3348 
3349 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
Hal_DetectWoWMode(PADAPTER pAdapter)3350 void Hal_DetectWoWMode(PADAPTER pAdapter)
3351 {
3352 	adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = _TRUE;
3353 }
3354 #endif
3355 
_InitTransferPageSize(PADAPTER padapter)3356 void _InitTransferPageSize(PADAPTER padapter)
3357 {
3358 	/* Tx page size is always 128. */
3359 
3360 	u8 value8;
3361 	value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
3362 	rtw_write8(padapter, REG_PBP, value8);
3363 }
3364 
3365 
hw_var_set_monitor(PADAPTER Adapter,u8 variable,u8 * val)3366 static void hw_var_set_monitor(PADAPTER Adapter, u8 variable, u8 *val)
3367 {
3368 	u32	rcr_bits;
3369 	u16	value_rxfltmap2;
3370 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3371 	struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
3372 
3373 	if (*((u8 *)val) == _HW_STATE_MONITOR_) {
3374 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3375 		rcr_bits = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_AMF | RCR_APP_PHYST_RXFF;
3376 #else
3377 		/* Receive all type */
3378 		rcr_bits = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_ACF | RCR_AMF | RCR_APP_PHYST_RXFF;
3379 
3380 		/* Append FCS */
3381 		rcr_bits |= RCR_APPFCS;
3382 #endif
3383 #if 0
3384 		/*
3385 		   CRC and ICV packet will drop in recvbuf2recvframe()
3386 		   We no turn on it.
3387 		 */
3388 		rcr_bits |= (RCR_ACRC32 | RCR_AICV);
3389 #endif
3390 
3391 		rtw_hal_get_hwreg(Adapter, HW_VAR_RCR, (u8 *)&pHalData->rcr_backup);
3392 		rtw_hal_set_hwreg(Adapter, HW_VAR_RCR, (u8 *)&rcr_bits);
3393 
3394 		/* Receive all data frames */
3395 		value_rxfltmap2 = 0xFFFF;
3396 		rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2);
3397 
3398 #if 0
3399 		/* tx pause */
3400 		rtw_write8(padapter, REG_TXPAUSE, 0xFF);
3401 #endif
3402 	} else {
3403 		/* do nothing */
3404 	}
3405 
3406 }
3407 
hw_var_set_opmode(PADAPTER Adapter,u8 variable,u8 * val)3408 static void hw_var_set_opmode(PADAPTER Adapter, u8 variable, u8 *val)
3409 {
3410 	u8	val8;
3411 	u8	mode = *((u8 *)val);
3412 	static u8 isMonitor = _FALSE;
3413 
3414 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3415 
3416 	if (isMonitor == _TRUE) {
3417 		/* reset RCR from backup */
3418 		rtw_hal_set_hwreg(Adapter, HW_VAR_RCR, (u8 *)&pHalData->rcr_backup);
3419 		rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
3420 		isMonitor = _FALSE;
3421 	}
3422 
3423 	RTW_INFO(ADPT_FMT "- Port-%d  set opmode = %d\n", ADPT_ARG(Adapter),
3424 		 get_hw_port(Adapter), mode);
3425 
3426 	if (mode == _HW_STATE_MONITOR_) {
3427 		isMonitor = _TRUE;
3428 		/* set net_type */
3429 		Set_MSR(Adapter, _HW_STATE_NOLINK_);
3430 
3431 		hw_var_set_monitor(Adapter, variable, val);
3432 		return;
3433 	}
3434 
3435 	rtw_hal_set_hwreg(Adapter, HW_VAR_MAC_ADDR, adapter_mac_addr(Adapter)); /* set mac addr to mac register */
3436 
3437 #ifdef CONFIG_CONCURRENT_MODE
3438 	if (Adapter->hw_port == HW_PORT1) {
3439 		/* disable Port1 TSF update */
3440 		rtw_iface_disable_tsf_update(Adapter);
3441 
3442 		/* set net_type		 */
3443 		Set_MSR(Adapter, mode);
3444 
3445 		if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
3446 			if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter)) {
3447 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
3448 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3449 				rtw_write8(Adapter, REG_DRVERLYINT, 0x05);/* restore early int time to 5ms */
3450 
3451 #if defined(CONFIG_USB_HCI)
3452 				UpdateInterruptMask8188EU(Adapter, _TRUE, 0, IMR_BCNDMAINT0_88E);
3453 #elif defined(CONFIG_SDIO_HCI)
3454 				UpdateInterruptMask8188ESdio(Adapter, 0, SDIO_HIMR_BCNERLY_INT_MSK);
3455 #endif
3456 
3457 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
3458 
3459 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
3460 #if defined(CONFIG_USB_HCI)
3461 				UpdateInterruptMask8188EU(Adapter, _TRUE , 0, (IMR_TBDER_88E | IMR_TBDOK_88E));
3462 #elif defined(CONFIG_SDIO_HCI)
3463 				UpdateInterruptMask8188ESdio(Adapter, 0, (SDIO_HIMR_TXBCNOK_MSK | SDIO_HIMR_TXBCNERR_MSK));
3464 #endif
3465 
3466 #endif/* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
3467 #endif /* CONFIG_INTERRUPT_BASED_TXBCN		 */
3468 
3469 				StopTxBeacon(Adapter);
3470 #if defined(CONFIG_PCI_HCI)
3471 				UpdateInterruptMask8188EE(Adapter, 0, 0, RT_BCN_INT_MASKS, 0);
3472 #endif
3473 			}
3474 
3475 			rtw_write8(Adapter, REG_BCN_CTRL_1, DIS_TSF_UDT | DIS_ATIM); /* disable atim wnd and disable beacon function */
3476 			/* rtw_write8(Adapter,REG_BCN_CTRL_1, DIS_TSF_UDT | EN_BCN_FUNCTION); */
3477 		} else if (mode == _HW_STATE_ADHOC_) {
3478 			/* Beacon is polled to TXBUF */
3479 			rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR) | BIT(8));
3480 
3481 			ResumeTxBeacon(Adapter);
3482 			rtw_write8(Adapter, REG_BCN_CTRL_1, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
3483 			/* BIT4 - If set 0, hw will clr bcnq when tx becon ok/fail or port 1 */
3484 			rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
3485 		} else if (mode == _HW_STATE_AP_) {
3486 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
3487 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3488 #if defined(CONFIG_USB_HCI)
3489 			UpdateInterruptMask8188EU(Adapter, _TRUE , IMR_BCNDMAINT0_88E, 0);
3490 #elif defined(CONFIG_SDIO_HCI)
3491 			UpdateInterruptMask8188ESdio(Adapter, SDIO_HIMR_BCNERLY_INT_MSK, 0);
3492 #endif
3493 #endif/* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
3494 
3495 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
3496 #if defined(CONFIG_USB_HCI)
3497 			UpdateInterruptMask8188EU(Adapter, _TRUE , (IMR_TBDER_88E | IMR_TBDOK_88E), 0);
3498 #elif defined(CONFIG_SDIO_HCI)
3499 			UpdateInterruptMask8188ESdio(Adapter, (SDIO_HIMR_TXBCNOK_MSK | SDIO_HIMR_TXBCNERR_MSK), 0);
3500 #endif
3501 #endif/* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
3502 
3503 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
3504 
3505 			rtw_write8(Adapter, REG_BCN_CTRL_1, DIS_TSF_UDT | DIS_BCNQ_SUB);
3506 
3507 			/* Beacon is polled to TXBUF */
3508 			rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR) | BIT(8));
3509 
3510 			/* enable to rx data frame				 */
3511 			rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
3512 			/* enable to rx ps-poll */
3513 			rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400);
3514 
3515 			/* Beacon Control related register for first time */
3516 			rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms		 */
3517 			rtw_write8(Adapter, REG_DRVERLYINT, 0x05);/* 5ms */
3518 			/* rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF); */
3519 			rtw_write8(Adapter, REG_ATIMWND_1, 0x0c); /* 13ms for port1 */
3520 
3521 			rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3522 
3523 			/* reset TSF2	 */
3524 			rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1));
3525 
3526 
3527 			/* BIT4 - If set 0, hw will clr bcnq when tx becon ok/fail or port 1 */
3528 			rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
3529 			/* enable BCN1 Function for if2 */
3530 			/* don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received) */
3531 			rtw_write8(Adapter, REG_BCN_CTRL_1, (DIS_TSF_UDT| EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3532 
3533 			if (!rtw_mi_buddy_check_mlmeinfo_state(Adapter, WIFI_FW_ASSOC_SUCCESS))
3534 				rtw_write8(Adapter, REG_BCN_CTRL,
3535 					rtw_read8(Adapter, REG_BCN_CTRL) & ~EN_BCN_FUNCTION);
3536 
3537 			/* BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked */
3538 			/* rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(5)); */
3539 			/* rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(3)); */
3540 
3541 			/* dis BCN0 ATIM  WND if if1 is station */
3542 			rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | DIS_ATIM);
3543 
3544 #ifdef CONFIG_TSF_RESET_OFFLOAD
3545 			/* Reset TSF for STA+AP concurrent mode */
3546 			if (DEV_STA_LD_NUM(adapter_to_dvobj(Adapter))) {
3547 				if (rtw_hal_reset_tsf(Adapter, HW_PORT1) == _FAIL)
3548 					RTW_INFO("ERROR! %s()-%d: Reset port1 TSF fail\n",
3549 						 __FUNCTION__, __LINE__);
3550 			}
3551 #endif /* CONFIG_TSF_RESET_OFFLOAD */
3552 #if defined(CONFIG_PCI_HCI)
3553 			UpdateInterruptMask8188EE(Adapter, RT_BCN_INT_MASKS, 0, 0, 0);
3554 #endif
3555 		}
3556 	} else	/* (Adapter->hw_port == HW_PORT1)*/
3557 #endif /* CONFIG_CONCURRENT_MODE */
3558 	{
3559 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*For Port0 - MBSS CAM*/
3560 		hw_var_set_opmode_mbid(Adapter, mode);
3561 #else
3562 		/* disable Port0 TSF update */
3563 		rtw_iface_disable_tsf_update(Adapter);
3564 
3565 		/* set net_type */
3566 		Set_MSR(Adapter, mode);
3567 
3568 		if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
3569 #ifdef CONFIG_CONCURRENT_MODE
3570 			if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
3571 #endif /*CONFIG_CONCURRENT_MODE*/
3572 			{
3573 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
3574 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3575 				rtw_write8(Adapter, REG_DRVERLYINT, 0x05);/* restore early int time to 5ms	 */
3576 #if defined(CONFIG_USB_HCI)
3577 				UpdateInterruptMask8188EU(Adapter, _TRUE, 0, IMR_BCNDMAINT0_88E);
3578 #elif defined(CONFIG_SDIO_HCI)
3579 				UpdateInterruptMask8188ESdio(Adapter, 0, SDIO_HIMR_BCNERLY_INT_MSK);
3580 #endif
3581 #endif/* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
3582 
3583 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
3584 #if defined(CONFIG_USB_HCI)
3585 				UpdateInterruptMask8188EU(Adapter, _TRUE , 0, (IMR_TBDER_88E | IMR_TBDOK_88E));
3586 #elif defined(CONFIG_SDIO_HCI)
3587 				UpdateInterruptMask8188ESdio(Adapter, 0, (SDIO_HIMR_TXBCNOK_MSK | SDIO_HIMR_TXBCNERR_MSK));
3588 #endif
3589 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
3590 
3591 #endif /* CONFIG_INTERRUPT_BASED_TXBCN		 */
3592 				StopTxBeacon(Adapter);
3593 #if defined(CONFIG_PCI_HCI)
3594 				UpdateInterruptMask8188EE(Adapter, 0, 0, RT_BCN_INT_MASKS, 0);
3595 #endif
3596 			}
3597 
3598 			rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM); /* disable atim wnd */
3599 			/* rtw_write8(Adapter,REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION); */
3600 		} else if (mode == _HW_STATE_ADHOC_) {
3601 			/* Beacon is polled to TXBUF */
3602 			rtw_write16(Adapter, REG_CR, rtw_read16(Adapter, REG_CR) | BIT(8));
3603 
3604 			ResumeTxBeacon(Adapter);
3605 			rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
3606 			/* BIT3 - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
3607 			rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
3608 		} else if (mode == _HW_STATE_AP_) {
3609 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
3610 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3611 #if defined(CONFIG_USB_HCI)
3612 			UpdateInterruptMask8188EU(Adapter, _TRUE , IMR_BCNDMAINT0_88E, 0);
3613 #elif defined(CONFIG_SDIO_HCI)
3614 			UpdateInterruptMask8188ESdio(Adapter, SDIO_HIMR_BCNERLY_INT_MSK, 0);
3615 #endif
3616 #endif/* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
3617 
3618 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
3619 #if defined(CONFIG_USB_HCI)
3620 			UpdateInterruptMask8188EU(Adapter, _TRUE , (IMR_TBDER_88E | IMR_TBDOK_88E), 0);
3621 #elif defined(CONFIG_SDIO_HCI)
3622 			UpdateInterruptMask8188ESdio(Adapter, (SDIO_HIMR_TXBCNOK_MSK | SDIO_HIMR_TXBCNERR_MSK), 0);
3623 #endif
3624 #endif/* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
3625 
3626 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
3627 
3628 			rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3629 
3630 			/* Beacon is polled to TXBUF */
3631 			rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR) | BIT(8));
3632 
3633 			/* enable to rx data frame */
3634 			rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
3635 			/* enable to rx ps-poll */
3636 			rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400);
3637 
3638 			/* Beacon Control related register for first time */
3639 			rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms			 */
3640 			rtw_write8(Adapter, REG_DRVERLYINT, 0x05);/* 5ms */
3641 			/* rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF); */
3642 			rtw_write8(Adapter, REG_ATIMWND, 0x0c); /* 13ms */
3643 
3644 			rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3645 
3646 			/* reset TSF */
3647 			rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
3648 
3649 			/* BIT3 - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
3650 			rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
3651 
3652 			/* enable BCN0 Function for if1 */
3653 			/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
3654 #if defined(CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR)
3655 			rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT| EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3656 #else
3657 			rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB));
3658 #endif
3659 
3660 #ifdef CONFIG_CONCURRENT_MODE
3661 			if (!rtw_mi_buddy_check_mlmeinfo_state(Adapter, WIFI_FW_ASSOC_SUCCESS))
3662 				rtw_write8(Adapter, REG_BCN_CTRL_1,
3663 					rtw_read8(Adapter, REG_BCN_CTRL_1) & ~EN_BCN_FUNCTION);
3664 #endif
3665 
3666 			/* dis BCN1 ATIM  WND if if2 is station */
3667 			rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | DIS_ATIM);
3668 #ifdef CONFIG_TSF_RESET_OFFLOAD
3669 			/* Reset TSF for STA+AP concurrent mode */
3670 			if (DEV_STA_LD_NUM(adapter_to_dvobj(Adapter))) {
3671 				if (rtw_hal_reset_tsf(Adapter, HW_PORT0) == _FAIL)
3672 					RTW_INFO("ERROR! %s()-%d: Reset port0 TSF fail\n",
3673 						 __FUNCTION__, __LINE__);
3674 			}
3675 #endif /* CONFIG_TSF_RESET_OFFLOAD */
3676 #if defined(CONFIG_PCI_HCI)
3677 			UpdateInterruptMask8188EE(Adapter, RT_BCN_INT_MASKS, 0, 0, 0);
3678 #endif
3679 		}
3680 #endif
3681 	}
3682 }
3683 
SetHwReg8188E(_adapter * adapter,u8 variable,u8 * val)3684 u8 SetHwReg8188E(_adapter *adapter, u8 variable, u8 *val)
3685 {
3686 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
3687 	struct dm_struct		*podmpriv = &pHalData->odmpriv;
3688 	u8 ret = _SUCCESS;
3689 
3690 	switch (variable) {
3691 
3692 	case HW_VAR_SET_OPMODE:
3693 		hw_var_set_opmode(adapter, variable, val);
3694 		break;
3695 	case HW_VAR_BASIC_RATE:
3696 		rtw_var_set_basic_rate(adapter, val);
3697 	break;
3698 	case HW_VAR_TXPAUSE:
3699 		rtw_write8(adapter, REG_TXPAUSE, *((u8 *)val));
3700 		break;
3701 
3702 	case HW_VAR_SLOT_TIME: {
3703 		rtw_write8(adapter, REG_SLOT, val[0]);
3704 	}
3705 	break;
3706 	case HW_VAR_ACK_PREAMBLE: {
3707 		u8	regTmp;
3708 		u8	bShortPreamble = *((PBOOLEAN)val);
3709 		/* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
3710 		regTmp = (pHalData->nCur40MhzPrimeSC) << 5;
3711 		rtw_write8(adapter, REG_RRSR + 2, regTmp);
3712 
3713 		regTmp = rtw_read8(adapter, REG_WMAC_TRXPTCL_CTL + 2);
3714 		if (bShortPreamble)
3715 			regTmp |= BIT1;
3716 		else
3717 			regTmp &= (~BIT1);
3718 		rtw_write8(adapter, REG_WMAC_TRXPTCL_CTL + 2, regTmp);
3719 	}
3720 	break;
3721 	case HW_VAR_CAM_INVALID_ALL:
3722 		rtw_write32(adapter, REG_CAMCMD, BIT(31) | BIT(30));
3723 		break;
3724 	case HW_VAR_AC_PARAM_VO:
3725 		rtw_write32(adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]);
3726 		break;
3727 	case HW_VAR_AC_PARAM_VI:
3728 		rtw_write32(adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]);
3729 		break;
3730 	case HW_VAR_AC_PARAM_BE:
3731 		pHalData->ac_param_be = ((u32 *)(val))[0];
3732 		rtw_write32(adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]);
3733 		break;
3734 	case HW_VAR_AC_PARAM_BK:
3735 		rtw_write32(adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]);
3736 		break;
3737 	case HW_VAR_ACM_CTRL: {
3738 		u8	acm_ctrl = *((u8 *)val);
3739 		u8	AcmCtrl = rtw_read8(adapter, REG_ACMHWCTRL);
3740 
3741 		if (acm_ctrl > 1)
3742 			AcmCtrl = AcmCtrl | 0x1;
3743 
3744 		if (acm_ctrl & BIT(1))
3745 			AcmCtrl |= AcmHw_VoqEn;
3746 		else
3747 			AcmCtrl &= (~AcmHw_VoqEn);
3748 
3749 		if (acm_ctrl & BIT(2))
3750 			AcmCtrl |= AcmHw_ViqEn;
3751 		else
3752 			AcmCtrl &= (~AcmHw_ViqEn);
3753 
3754 		if (acm_ctrl & BIT(3))
3755 			AcmCtrl |= AcmHw_BeqEn;
3756 		else
3757 			AcmCtrl &= (~AcmHw_BeqEn);
3758 
3759 		RTW_INFO("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
3760 		rtw_write8(adapter, REG_ACMHWCTRL, AcmCtrl);
3761 	}
3762 	break;
3763 #ifdef CONFIG_80211N_HT
3764 	case HW_VAR_AMPDU_FACTOR: {
3765 		u8	RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9};
3766 		u8	RegToSet_BT[4] = {0x31, 0x74, 0x42, 0x97};
3767 		u8	FactorToSet;
3768 		u8	*pRegToSet;
3769 		u8	index = 0;
3770 
3771 #ifdef CONFIG_BT_COEXIST
3772 		if ((pHalData->bt_coexist.BT_Coexist) &&
3773 		    (pHalData->bt_coexist.BT_CoexistType == BT_CSR_BC4))
3774 			pRegToSet = RegToSet_BT; /* 0x97427431; */
3775 		else
3776 #endif
3777 			pRegToSet = RegToSet_Normal; /* 0xb972a841; */
3778 
3779 		FactorToSet = *((u8 *)val);
3780 		if (FactorToSet <= 3) {
3781 			FactorToSet = (1 << (FactorToSet + 2));
3782 			if (FactorToSet > 0xf)
3783 				FactorToSet = 0xf;
3784 
3785 			for (index = 0; index < 4; index++) {
3786 				if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
3787 					pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4);
3788 
3789 				if ((pRegToSet[index] & 0x0f) > FactorToSet)
3790 					pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
3791 
3792 				rtw_write8(adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]);
3793 			}
3794 
3795 		}
3796 	}
3797 	break;
3798 #endif /* CONFIG_80211N_HT */
3799 	case HW_VAR_H2C_FW_PWRMODE: {
3800 		u8	psmode = (*(u8 *)val);
3801 
3802 		rtl8188e_set_FwPwrMode_cmd(adapter, psmode);
3803 	}
3804 	break;
3805 	case HW_VAR_H2C_FW_JOINBSSRPT: {
3806 		u8	mstatus = (*(u8 *)val);
3807 		rtl8188e_set_FwJoinBssReport_cmd(adapter, mstatus);
3808 	}
3809 	break;
3810 #ifdef CONFIG_P2P_PS
3811 	case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: {
3812 		u8	p2p_ps_state = (*(u8 *)val);
3813 		rtl8188e_set_p2p_ps_offload_cmd(adapter, p2p_ps_state);
3814 	}
3815 	break;
3816 #endif /* CONFIG_P2P_PS */
3817 #ifdef CONFIG_BT_COEXIST
3818 	case HW_VAR_BT_SET_COEXIST: {
3819 		u8	bStart = (*(u8 *)val);
3820 		rtl8192c_set_dm_bt_coexist(adapter, bStart);
3821 	}
3822 	break;
3823 	case HW_VAR_BT_ISSUE_DELBA: {
3824 		u8	dir = (*(u8 *)val);
3825 		rtl8192c_issue_delete_ba(adapter, dir);
3826 	}
3827 	break;
3828 #endif
3829 #if (RATE_ADAPTIVE_SUPPORT == 1)
3830 	case HW_VAR_RPT_TIMER_SETTING: {
3831 		u16	min_rpt_time = (*(u16 *)val);
3832 
3833 		odm_ra_set_tx_rpt_time(podmpriv, min_rpt_time);
3834 	}
3835 	break;
3836 #endif
3837 
3838 	case HW_VAR_EFUSE_BYTES: /* To set EFUE total used bytes, added by Roger, 2008.12.22. */
3839 		pHalData->EfuseUsedBytes = *((u16 *)val);
3840 		break;
3841 	case HW_VAR_FIFO_CLEARN_UP: {
3842 		struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
3843 		u8 trycnt = 100;
3844 
3845 		/* pause tx */
3846 		rtw_write8(adapter, REG_TXPAUSE, 0xff);
3847 
3848 		/* keep sn */
3849 		adapter->xmitpriv.nqos_ssn = rtw_read16(adapter, REG_NQOS_SEQ);
3850 
3851 		if (pwrpriv->bkeepfwalive != _TRUE) {
3852 			/* RX DMA stop */
3853 			rtw_write32(adapter, REG_RXPKT_NUM, (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
3854 			do {
3855 				if (!(rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
3856 					break;
3857 			} while (trycnt--);
3858 			if (trycnt == 0)
3859 				RTW_INFO("Stop RX DMA failed......\n");
3860 
3861 			/* RQPN Load 0 */
3862 			rtw_write16(adapter, REG_RQPN_NPQ, 0x0);
3863 			rtw_write32(adapter, REG_RQPN, 0x80000000);
3864 			rtw_mdelay_os(10);
3865 		}
3866 	}
3867 	break;
3868 
3869 	case HW_VAR_RESTORE_HW_SEQ:
3870 		/* restore Sequence No. */
3871 		rtw_write8(adapter, 0x4dc, adapter->xmitpriv.nqos_ssn);
3872 		break;
3873 
3874 #if (RATE_ADAPTIVE_SUPPORT == 1)
3875 	case HW_VAR_TX_RPT_MAX_MACID: {
3876 		u8 maxMacid = *val;
3877 
3878 		RTW_INFO("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid + 1);
3879 		rtw_write8(adapter, REG_TX_RPT_CTRL + 1, maxMacid + 1);
3880 	}
3881 	break;
3882 #endif /* (RATE_ADAPTIVE_SUPPORT == 1) */
3883 
3884 	case HW_VAR_BCN_VALID:
3885 		/* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw */
3886 		rtw_write8(adapter, REG_TDECTRL + 2, rtw_read8(adapter, REG_TDECTRL + 2) | BIT0);
3887 		break;
3888 
3889 
3890 	case HW_VAR_CHECK_TXBUF: {
3891 		u8 retry_limit;
3892 		u16 val16;
3893 		u32 reg_200 = 0, reg_204 = 0;
3894 		u32 init_reg_200 = 0, init_reg_204 = 0;
3895 		systime start = rtw_get_current_time();
3896 		u32 pass_ms;
3897 		int i = 0;
3898 
3899 		retry_limit = 0x01;
3900 
3901 		val16 = BIT_SRL(retry_limit) | BIT_LRL(retry_limit);
3902 		rtw_write16(adapter, REG_RETRY_LIMIT, val16);
3903 
3904 		while (rtw_get_passing_time_ms(start) < 2000
3905 		       && !RTW_CANNOT_RUN(adapter)
3906 		      ) {
3907 			reg_200 = rtw_read32(adapter, 0x200);
3908 			reg_204 = rtw_read32(adapter, 0x204);
3909 
3910 			if (i == 0) {
3911 				init_reg_200 = reg_200;
3912 				init_reg_204 = reg_204;
3913 			}
3914 
3915 			i++;
3916 			if ((reg_200 & 0x00ffffff) != (reg_204 & 0x00ffffff)) {
3917 				/* RTW_INFO("%s: (HW_VAR_CHECK_TXBUF)TXBUF NOT empty - 0x204=0x%x, 0x200=0x%x (%d)\n", __FUNCTION__, reg_204, reg_200, i); */
3918 				rtw_msleep_os(10);
3919 			} else
3920 				break;
3921 		}
3922 
3923 		pass_ms = rtw_get_passing_time_ms(start);
3924 
3925 		if (RTW_CANNOT_RUN(adapter))
3926 			;
3927 		else if (pass_ms >= 2000 || (reg_200 & 0x00ffffff) != (reg_204 & 0x00ffffff)) {
3928 			RTW_PRINT("%s:(HW_VAR_CHECK_TXBUF)NOT empty(%d) in %d ms\n", __FUNCTION__, i, pass_ms);
3929 			RTW_PRINT("%s:(HW_VAR_CHECK_TXBUF)0x200=0x%08x, 0x204=0x%08x (0x%08x, 0x%08x)\n",
3930 				__FUNCTION__, reg_200, reg_204, init_reg_200, init_reg_204);
3931 			/* rtw_warn_on(1); */
3932 		} else
3933 			RTW_INFO("%s:(HW_VAR_CHECK_TXBUF)TXBUF Empty(%d) in %d ms\n", __FUNCTION__, i, pass_ms);
3934 
3935 		retry_limit = RL_VAL_STA;
3936 		val16 = BIT_SRL(retry_limit) | BIT_LRL(retry_limit);
3937 		rtw_write16(adapter, REG_RETRY_LIMIT, val16);
3938 	}
3939 	break;
3940 	case HW_VAR_RESP_SIFS: {
3941 		struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
3942 
3943 		if ((pmlmeext->cur_wireless_mode == WIRELESS_11G) ||
3944 		    (pmlmeext->cur_wireless_mode == WIRELESS_11BG)) { /* WIRELESS_MODE_G){ */
3945 			val[0] = 0x0a;
3946 			val[1] = 0x0a;
3947 		} else {
3948 			val[0] = 0x0e;
3949 			val[1] = 0x0e;
3950 		}
3951 
3952 		/* SIFS for OFDM Data ACK */
3953 		rtw_write8(adapter, REG_SIFS_CTX + 1, val[0]);
3954 		/* SIFS for OFDM consecutive tx like CTS data! */
3955 		rtw_write8(adapter, REG_SIFS_TRX + 1, val[1]);
3956 
3957 		rtw_write8(adapter, REG_SPEC_SIFS + 1, val[0]);
3958 		rtw_write8(adapter, REG_MAC_SPEC_SIFS + 1, val[0]);
3959 
3960 		/* RESP_SIFS for OFDM */
3961 		rtw_write8(adapter, REG_RESP_SIFS_OFDM, val[0]);
3962 		rtw_write8(adapter, REG_RESP_SIFS_OFDM + 1, val[0]);
3963 	}
3964 	break;
3965 
3966 	case HW_VAR_MACID_LINK: {
3967 		u32 reg_macid_no_link;
3968 		u8 bit_shift;
3969 		u8 id = *(u8 *)val;
3970 		u32 val32;
3971 
3972 		if (id < 32) {
3973 			reg_macid_no_link = REG_MACID_NO_LINK_0;
3974 			bit_shift = id;
3975 		} else if (id < 64) {
3976 			reg_macid_no_link = REG_MACID_NO_LINK_1;
3977 			bit_shift = id - 32;
3978 		} else {
3979 			rtw_warn_on(1);
3980 			break;
3981 		}
3982 
3983 		val32 = rtw_read32(adapter, reg_macid_no_link);
3984 		if (!(val32 & BIT(bit_shift)))
3985 			break;
3986 
3987 		val32 &= ~BIT(bit_shift);
3988 		rtw_write32(adapter, reg_macid_no_link, val32);
3989 	}
3990 	break;
3991 
3992 	case HW_VAR_MACID_NOLINK: {
3993 		u32 reg_macid_no_link;
3994 		u8 bit_shift;
3995 		u8 id = *(u8 *)val;
3996 		u32 val32;
3997 
3998 		if (id < 32) {
3999 			reg_macid_no_link = REG_MACID_NO_LINK_0;
4000 			bit_shift = id;
4001 		} else if (id < 64) {
4002 			reg_macid_no_link = REG_MACID_NO_LINK_1;
4003 			bit_shift = id - 32;
4004 		} else {
4005 			rtw_warn_on(1);
4006 			break;
4007 		}
4008 
4009 		val32 = rtw_read32(adapter, reg_macid_no_link);
4010 		if (val32 & BIT(bit_shift))
4011 			break;
4012 
4013 		val32 |= BIT(bit_shift);
4014 		rtw_write32(adapter, reg_macid_no_link, val32);
4015 	}
4016 	break;
4017 
4018 	default:
4019 		ret = SetHwReg(adapter, variable, val);
4020 		break;
4021 	}
4022 
4023 	return ret;
4024 }
4025 
4026 struct qinfo_88e {
4027 	u32 head:8;
4028 	u32 pkt_num:8;
4029 	u32 tail:8;
4030 	u32 ac:2;
4031 	u32 macid:6;
4032 };
4033 
4034 struct bcn_qinfo_88e {
4035 	u16 head:8;
4036 	u16 pkt_num:8;
4037 };
4038 
dump_qinfo_88e(void * sel,struct qinfo_88e * info,const char * tag)4039 void dump_qinfo_88e(void *sel, struct qinfo_88e *info, const char *tag)
4040 {
4041 	/* if (info->pkt_num) */
4042 	RTW_PRINT_SEL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n"
4043 		, tag ? tag : "", info->head, info->tail, info->pkt_num, info->macid, info->ac
4044 		     );
4045 }
4046 
dump_bcn_qinfo_88e(void * sel,struct bcn_qinfo_88e * info,const char * tag)4047 void dump_bcn_qinfo_88e(void *sel, struct bcn_qinfo_88e *info, const char *tag)
4048 {
4049 	/* if (info->pkt_num) */
4050 	RTW_PRINT_SEL(sel, "%shead:0x%02x, pkt_num:%u\n"
4051 		      , tag ? tag : "", info->head, info->pkt_num
4052 		     );
4053 }
4054 
dump_mac_qinfo_88e(void * sel,_adapter * adapter)4055 void dump_mac_qinfo_88e(void *sel, _adapter *adapter)
4056 {
4057 	u32 q0_info;
4058 	u32 q1_info;
4059 	u32 q2_info;
4060 	u32 q3_info;
4061 	/*
4062 	u32 q4_info;
4063 	u32 q5_info;
4064 	u32 q6_info;
4065 	u32 q7_info;
4066 	*/
4067 	u32 mg_q_info;
4068 	u32 hi_q_info;
4069 	u16 bcn_q_info;
4070 
4071 	q0_info = rtw_read32(adapter, REG_Q0_INFO);
4072 	q1_info = rtw_read32(adapter, REG_Q1_INFO);
4073 	q2_info = rtw_read32(adapter, REG_Q2_INFO);
4074 	q3_info = rtw_read32(adapter, REG_Q3_INFO);
4075 	/*
4076 	q4_info = rtw_read32(adapter, REG_Q4_INFO);
4077 	q5_info = rtw_read32(adapter, REG_Q5_INFO);
4078 	q6_info = rtw_read32(adapter, REG_Q6_INFO);
4079 	q7_info = rtw_read32(adapter, REG_Q7_INFO);
4080 	*/
4081 	mg_q_info = rtw_read32(adapter, REG_MGQ_INFO);
4082 	hi_q_info = rtw_read32(adapter, REG_HGQ_INFO);
4083 	bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO);
4084 
4085 	dump_qinfo_88e(sel, (struct qinfo_88e *)&q0_info, "Q0 ");
4086 	dump_qinfo_88e(sel, (struct qinfo_88e *)&q1_info, "Q1 ");
4087 	dump_qinfo_88e(sel, (struct qinfo_88e *)&q2_info, "Q2 ");
4088 	dump_qinfo_88e(sel, (struct qinfo_88e *)&q3_info, "Q3 ");
4089 	/*
4090 	dump_qinfo_88e(sel, (struct qinfo_88e *)&q4_info, "Q4 ");
4091 	dump_qinfo_88e(sel, (struct qinfo_88e *)&q5_info, "Q5 ");
4092 	dump_qinfo_88e(sel, (struct qinfo_88e *)&q6_info, "Q6 ");
4093 	dump_qinfo_88e(sel, (struct qinfo_88e *)&q7_info, "Q7 ");
4094 	*/
4095 	dump_qinfo_88e(sel, (struct qinfo_88e *)&mg_q_info, "MG ");
4096 	dump_qinfo_88e(sel, (struct qinfo_88e *)&hi_q_info, "HI ");
4097 	dump_bcn_qinfo_88e(sel, (struct bcn_qinfo_88e *)&bcn_q_info, "BCN ");
4098 }
4099 
dump_mac_txfifo_88e(void * sel,_adapter * adapter)4100 static void dump_mac_txfifo_88e(void *sel, _adapter *adapter)
4101 {
4102 	u32 rqpn, rqpn_npq;
4103 	u32 hpq, lpq, npq, pubq;
4104 
4105 	rqpn = rtw_read32(adapter, REG_FIFOPAGE);
4106 	rqpn_npq = rtw_read32(adapter, REG_RQPN_NPQ);
4107 
4108 	hpq = (rqpn & 0xFF);
4109 	lpq = ((rqpn & 0xFF00)>>8);
4110 	pubq = ((rqpn & 0xFF0000)>>16);
4111 	npq = ((rqpn_npq & 0xFF00)>>8);
4112 
4113 	RTW_PRINT_SEL(sel, "Tx: available page num: ");
4114 	if ((hpq == 0xEA) && (hpq == lpq) && (hpq == pubq))
4115 		RTW_PRINT_SEL(sel, "N/A (reg val = 0xea)\n");
4116 	else
4117 		RTW_PRINT_SEL(sel, "HPQ: %d, LPQ: %d, NPQ: %d, PUBQ: %d\n"
4118 			, hpq, lpq, npq, pubq);
4119 }
4120 
GetHwReg8188E(_adapter * adapter,u8 variable,u8 * val)4121 void GetHwReg8188E(_adapter *adapter, u8 variable, u8 *val)
4122 {
4123 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
4124 	u32 val32;
4125 
4126 	switch (variable) {
4127 	case HW_VAR_SYS_CLKR:
4128 		*val = rtw_read8(adapter, REG_SYS_CLKR);
4129 		break;
4130 
4131 	case HW_VAR_TXPAUSE:
4132 		val[0] = rtw_read8(adapter, REG_TXPAUSE);
4133 		break;
4134 
4135 	case HW_VAR_BCN_VALID:
4136 		/* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */
4137 		val[0] = (BIT0 & rtw_read8(adapter, REG_TDECTRL + 2)) ? _TRUE : _FALSE;
4138 		break;
4139 
4140 	case HW_VAR_AC_PARAM_VO:
4141 		val32 = rtw_read32(adapter, REG_EDCA_VO_PARAM);
4142 		val[0] = val32 & 0xFF;
4143 		val[1] = (val32 >> 8) & 0xFF;
4144 		val[2] = (val32 >> 16) & 0xFF;
4145 		val[3] = (val32 >> 24) & 0x07;
4146 		break;
4147 
4148 	case HW_VAR_AC_PARAM_VI:
4149 		val32 = rtw_read32(adapter, REG_EDCA_VI_PARAM);
4150 		val[0] = val32 & 0xFF;
4151 		val[1] = (val32 >> 8) & 0xFF;
4152 		val[2] = (val32 >> 16) & 0xFF;
4153 		val[3] = (val32 >> 24) & 0x07;
4154 		break;
4155 
4156 	case HW_VAR_AC_PARAM_BE:
4157 		val32 = rtw_read32(adapter, REG_EDCA_BE_PARAM);
4158 		val[0] = val32 & 0xFF;
4159 		val[1] = (val32 >> 8) & 0xFF;
4160 		val[2] = (val32 >> 16) & 0xFF;
4161 		val[3] = (val32 >> 24) & 0x07;
4162 		break;
4163 
4164 	case HW_VAR_AC_PARAM_BK:
4165 		val32 = rtw_read32(adapter, REG_EDCA_BK_PARAM);
4166 		val[0] = val32 & 0xFF;
4167 		val[1] = (val32 >> 8) & 0xFF;
4168 		val[2] = (val32 >> 16) & 0xFF;
4169 		val[3] = (val32 >> 24) & 0x07;
4170 		break;
4171 
4172 	case HW_VAR_EFUSE_BYTES: /* To get EFUE total used bytes, added by Roger, 2008.12.22. */
4173 		*((u16 *)(val)) = pHalData->EfuseUsedBytes;
4174 		break;
4175 	case HW_VAR_CHK_HI_QUEUE_EMPTY:
4176 		*val = ((rtw_read32(adapter, REG_HGQ_INFO) & 0x0000ff00) == 0) ? _TRUE : _FALSE;
4177 		break;
4178 	case HW_VAR_CHK_MGQ_CPU_EMPTY:
4179 		*val = (rtw_read16(adapter, REG_TXPKT_EMPTY) & BIT8) ? _TRUE : _FALSE;
4180 		break;
4181 	case HW_VAR_DUMP_MAC_QUEUE_INFO:
4182 		dump_mac_qinfo_88e(val, adapter);
4183 		break;
4184 	case HW_VAR_DUMP_MAC_TXFIFO:
4185 		dump_mac_txfifo_88e(val, adapter);
4186 		break;
4187 	default:
4188 		GetHwReg(adapter, variable, val);
4189 		break;
4190 	}
4191 
4192 }
hal_ra_info_dump(_adapter * padapter,void * sel)4193 void hal_ra_info_dump(_adapter *padapter , void *sel)
4194 {
4195 	int i;
4196 	u8 mac_id;
4197 	u8 bLinked = _FALSE;
4198 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
4199 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
4200 	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
4201 	_adapter *iface;
4202 
4203 	for (i = 0; i < dvobj->iface_nums; i++) {
4204 		iface = dvobj->padapters[i];
4205 		if ((iface) && rtw_is_adapter_up(iface)) {
4206 			if (rtw_linked_check(iface)) {
4207 				bLinked = _TRUE;
4208 				break;
4209 			}
4210 		}
4211 	}
4212 
4213 	for (i = 0; i < macid_ctl->num; i++) {
4214 
4215 		if (rtw_macid_is_used(macid_ctl, i) && !rtw_macid_is_bmc(macid_ctl, i)) {
4216 
4217 			mac_id = (u8) i;
4218 
4219 			if (bLinked) {
4220 				RTW_PRINT_SEL(sel , "============ RA status - Mac_id:%d ===================\n", mac_id);
4221 				if (pHalData->fw_ractrl == _FALSE) {
4222 #if (RATE_ADAPTIVE_SUPPORT == 1)
4223 					RTW_PRINT_SEL(sel , "Mac_id:%d ,RSSI:%d(%%)\n", mac_id, pHalData->odmpriv.ra_info[mac_id].rssi_sta_ra);
4224 
4225 					RTW_PRINT_SEL(sel , "rate_sgi = %d, decision_rate = %s\n", rtw_get_current_tx_sgi(padapter, macid_ctl->sta[mac_id]),
4226 						HDATA_RATE(rtw_get_current_tx_rate(padapter, macid_ctl->sta[mac_id])));
4227 
4228 					RTW_PRINT_SEL(sel , "pt_stage = %d\n", pHalData->odmpriv.ra_info[mac_id].pt_stage);
4229 
4230 					RTW_PRINT_SEL(sel , "rate_id = %d,ra_use_rate = 0x%08x\n", pHalData->odmpriv.ra_info[mac_id].rate_id, pHalData->odmpriv.ra_info[mac_id].ra_use_rate);
4231 
4232 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
4233 				} else {
4234 					u8 cur_rate = 0;
4235 					u8 sgi = 0;
4236 
4237 					if (padapter->fix_rate == 0xff) {
4238 						cur_rate = rtw_read8(padapter, REG_ADAPTIVE_DATA_RATE_0 + mac_id) & 0x7f;
4239 						sgi = (cur_rate & BIT7) ? _TRUE : _FALSE;
4240 					} else {
4241 						cur_rate = padapter->fix_rate & 0x7f;
4242 						sgi = ((padapter->fix_rate) & 0x80) >> 7;
4243 					}
4244 
4245 					RTW_PRINT_SEL(sel , "Mac_id:%d ,SGI:%d ,Rate:%s\n", mac_id, sgi, HDATA_RATE(cur_rate));
4246 				}
4247 			}
4248 		}
4249 	}
4250 }
4251 
4252 u8
GetHalDefVar8188E(PADAPTER Adapter,HAL_DEF_VARIABLE eVariable,void * pValue)4253 GetHalDefVar8188E(
4254 		PADAPTER				Adapter,
4255 		HAL_DEF_VARIABLE		eVariable,
4256 		void						*pValue
4257 )
4258 {
4259 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
4260 	u8			bResult = _SUCCESS;
4261 
4262 	switch (eVariable) {
4263 	case HAL_DEF_IS_SUPPORT_ANT_DIV:
4264 #ifdef CONFIG_ANTENNA_DIVERSITY
4265 		*((u8 *)pValue) = (pHalData->AntDivCfg == 0) ? _FALSE : _TRUE;
4266 #endif
4267 		break;
4268 	case HAL_DEF_DRVINFO_SZ:
4269 		*((u32 *)pValue) = DRVINFO_SZ;
4270 		break;
4271 	case HAL_DEF_MAX_RECVBUF_SZ:
4272 #ifdef CONFIG_SDIO_HCI
4273 		*((u32 *)pValue) = MAX_RX_DMA_BUFFER_SIZE_88E(Adapter);
4274 #else
4275 		*((u32 *)pValue) = MAX_RECVBUF_SZ;
4276 #endif
4277 		break;
4278 	case HAL_DEF_RX_PACKET_OFFSET:
4279 		*((u32 *)pValue) = RXDESC_SIZE + DRVINFO_SZ * 8;
4280 		break;
4281 #if (RATE_ADAPTIVE_SUPPORT == 1)
4282 	case HAL_DEF_RA_DECISION_RATE: {
4283 		u8 MacID = *((u8 *)pValue);
4284 		*((u8 *)pValue) = odm_ra_get_decision_rate_8188e(&(pHalData->odmpriv), MacID);
4285 	}
4286 	break;
4287 
4288 	case HAL_DEF_RA_SGI: {
4289 		u8 MacID = *((u8 *)pValue);
4290 		*((u8 *)pValue) = odm_ra_get_sgi_8188e(&(pHalData->odmpriv), MacID);
4291 	}
4292 	break;
4293 #endif
4294 
4295 
4296 	case HAL_DEF_PT_PWR_STATUS:
4297 #if (POWER_TRAINING_ACTIVE == 1)
4298 		{
4299 			u8 MacID = *((u8 *)pValue);
4300 			*((u8 *)pValue) = odm_ra_get_hw_pwr_status_8188e(&(pHalData->odmpriv), MacID);
4301 		}
4302 #endif /* (POWER_TRAINING_ACTIVE==1) */
4303 		break;
4304 	case HAL_DEF_EXPLICIT_BEAMFORMEE:
4305 	case HAL_DEF_EXPLICIT_BEAMFORMER:
4306 		*((u8 *)pValue) = _FALSE;
4307 		break;
4308 
4309 	case HW_DEF_RA_INFO_DUMP:
4310 		hal_ra_info_dump(Adapter, pValue);
4311 		break;
4312 
4313 	case HAL_DEF_TX_PAGE_SIZE:
4314 		*((u32 *)pValue) = PAGE_SIZE_128;
4315 		break;
4316 	case HAL_DEF_TX_PAGE_BOUNDARY:
4317 		if (!Adapter->registrypriv.wifi_spec)
4318 			*(u8 *)pValue = TX_PAGE_BOUNDARY_88E(Adapter);
4319 		else
4320 			*(u8 *)pValue = WMM_NORMAL_TX_PAGE_BOUNDARY_88E(Adapter);
4321 		break;
4322 	case HAL_DEF_RX_DMA_SZ_WOW:
4323 		*(u32 *)pValue = RX_DMA_SIZE_88E(Adapter) - RESV_FMWF;
4324 		break;
4325 	case HAL_DEF_RX_DMA_SZ:
4326 		*(u32 *)pValue = MAX_RX_DMA_BUFFER_SIZE_88E(Adapter);
4327 		break;
4328 	case HAL_DEF_RX_PAGE_SIZE:
4329 		*(u32 *)pValue = PAGE_SIZE_128;
4330 		break;
4331 	case HW_VAR_BEST_AMPDU_DENSITY:
4332 		*((u32 *)pValue) = AMPDU_DENSITY_VALUE_7;
4333 		break;
4334 	default:
4335 		bResult = GetHalDefVar(Adapter, eVariable, pValue);
4336 		break;
4337 	}
4338 
4339 	return bResult;
4340 }
4341 
4342 #ifdef CONFIG_GPIO_API
rtl8188e_GpioFuncCheck(PADAPTER adapter,u8 gpio_num)4343 int rtl8188e_GpioFuncCheck(PADAPTER adapter, u8 gpio_num)
4344 {
4345         int ret = _SUCCESS;
4346 
4347         if (IS_HARDWARE_TYPE_8188E(adapter) == _FAIL) {
4348                 if ((gpio_num > 7) || (gpio_num < 4)) {
4349                         RTW_INFO("%s The gpio number does not included 4~7.\n",__FUNCTION__);
4350                         ret = _FAIL;
4351                 }
4352         }
4353 
4354         return ret;
4355 }
4356 #endif
4357