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