Merge branch 'opw-next' into staging-next
[linux-2.6-microblaze.git] / drivers / staging / rtl8188eu / hal / rtl8188e_hal_init.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _HAL_INIT_C_
21
22 #include <linux/firmware.h>
23 #include <drv_types.h>
24 #include <rtw_efuse.h>
25
26 #include <rtl8188e_hal.h>
27
28 #include <rtw_iol.h>
29
30 #include <usb_ops.h>
31
32 static void iol_mode_enable(struct adapter *padapter, u8 enable)
33 {
34         u8 reg_0xf0 = 0;
35
36         if (enable) {
37                 /* Enable initial offload */
38                 reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
39                 rtw_write8(padapter, REG_SYS_CFG, reg_0xf0|SW_OFFLOAD_EN);
40
41                 if (!padapter->bFWReady) {
42                         DBG_88E("bFWReady == false call reset 8051...\n");
43                         _8051Reset88E(padapter);
44                 }
45
46         } else {
47                 /* disable initial offload */
48                 reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
49                 rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
50         }
51 }
52
53 static s32 iol_execute(struct adapter *padapter, u8 control)
54 {
55         s32 status = _FAIL;
56         u8 reg_0x88 = 0;
57         u32 start = 0, passing_time = 0;
58
59         control = control&0x0f;
60         reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
61         rtw_write8(padapter, REG_HMEBOX_E0,  reg_0x88|control);
62
63         start = rtw_get_current_time();
64         while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control &&
65                (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
66                 ;
67         }
68
69         reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
70         status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
71         if (reg_0x88 & control<<4)
72                 status = _FAIL;
73         return status;
74 }
75
76 static s32 iol_InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
77 {
78         s32 rst = _SUCCESS;
79         iol_mode_enable(padapter, 1);
80         rtw_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
81         rst = iol_execute(padapter, CMD_INIT_LLT);
82         iol_mode_enable(padapter, 0);
83         return rst;
84 }
85
86 static void
87 efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8  *pbuf)
88 {
89         u8 *efuseTbl = NULL;
90         u8 rtemp8;
91         u16     eFuse_Addr = 0;
92         u8 offset, wren;
93         u16     i, j;
94         u16     **eFuseWord = NULL;
95         u16     efuse_utilized = 0;
96         u8 u1temp = 0;
97
98         efuseTbl = (u8 *)rtw_zmalloc(EFUSE_MAP_LEN_88E);
99         if (efuseTbl == NULL) {
100                 DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
101                 goto exit;
102         }
103
104         eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
105         if (eFuseWord == NULL) {
106                 DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
107                 goto exit;
108         }
109
110         /*  0. Refresh efuse init map as all oxFF. */
111         for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
112                 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
113                         eFuseWord[i][j] = 0xFFFF;
114
115         /*  */
116         /*  1. Read the first byte to check if efuse is empty!!! */
117         /*  */
118         /*  */
119         rtemp8 = *(phymap+eFuse_Addr);
120         if (rtemp8 != 0xFF) {
121                 efuse_utilized++;
122                 eFuse_Addr++;
123         } else {
124                 DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, rtemp8);
125                 goto exit;
126         }
127
128         /*  */
129         /*  2. Read real efuse content. Filter PG header and every section data. */
130         /*  */
131         while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
132                 /*  Check PG header for section num. */
133                 if ((rtemp8 & 0x1F) == 0x0F) {          /* extended header */
134                         u1temp = ((rtemp8 & 0xE0) >> 5);
135                         rtemp8 = *(phymap+eFuse_Addr);
136                         if ((rtemp8 & 0x0F) == 0x0F) {
137                                 eFuse_Addr++;
138                                 rtemp8 = *(phymap+eFuse_Addr);
139
140                                 if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
141                                         eFuse_Addr++;
142                                 continue;
143                         } else {
144                                 offset = ((rtemp8 & 0xF0) >> 1) | u1temp;
145                                 wren = (rtemp8 & 0x0F);
146                                 eFuse_Addr++;
147                         }
148                 } else {
149                         offset = ((rtemp8 >> 4) & 0x0f);
150                         wren = (rtemp8 & 0x0f);
151                 }
152
153                 if (offset < EFUSE_MAX_SECTION_88E) {
154                         /*  Get word enable value from PG header */
155                         for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
156                                 /*  Check word enable condition in the section */
157                                 if (!(wren & 0x01)) {
158                                         rtemp8 = *(phymap+eFuse_Addr);
159                                         eFuse_Addr++;
160                                         efuse_utilized++;
161                                         eFuseWord[offset][i] = (rtemp8 & 0xff);
162                                         if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
163                                                 break;
164                                         rtemp8 = *(phymap+eFuse_Addr);
165                                         eFuse_Addr++;
166                                         efuse_utilized++;
167                                         eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);
168
169                                         if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
170                                                 break;
171                                 }
172                                 wren >>= 1;
173                         }
174                 }
175                 /*  Read next PG header */
176                 rtemp8 = *(phymap+eFuse_Addr);
177
178                 if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
179                         efuse_utilized++;
180                         eFuse_Addr++;
181                 }
182         }
183
184         /*  */
185         /*  3. Collect 16 sections and 4 word unit into Efuse map. */
186         /*  */
187         for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
188                 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
189                         efuseTbl[(i*8)+(j*2)] = (eFuseWord[i][j] & 0xff);
190                         efuseTbl[(i*8)+((j*2)+1)] = ((eFuseWord[i][j] >> 8) & 0xff);
191                 }
192         }
193
194         /*  */
195         /*  4. Copy from Efuse map to output pointer memory!!! */
196         /*  */
197         for (i = 0; i < _size_byte; i++)
198                 pbuf[i] = efuseTbl[_offset+i];
199
200         /*  */
201         /*  5. Calculate Efuse utilization. */
202         /*  */
203
204 exit:
205         kfree(efuseTbl);
206
207         if (eFuseWord)
208                 rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
209 }
210
211 static void efuse_read_phymap_from_txpktbuf(
212         struct adapter  *adapter,
213         int bcnhead,    /* beacon head, where FW store len(2-byte) and efuse physical map. */
214         u8 *content,    /* buffer to store efuse physical map */
215         u16 *size       /* for efuse content: the max byte to read. will update to byte read */
216         )
217 {
218         u16 dbg_addr = 0;
219         u32 start  = 0, passing_time = 0;
220         u8 reg_0x143 = 0;
221         u32 lo32 = 0, hi32 = 0;
222         u16 len = 0, count = 0;
223         int i = 0;
224         u16 limit = *size;
225
226         u8 *pos = content;
227
228         if (bcnhead < 0) /* if not valid */
229                 bcnhead = rtw_read8(adapter, REG_TDECTRL+1);
230
231         DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);
232
233         rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
234
235         dbg_addr = bcnhead*128/8; /* 8-bytes addressing */
236
237         while (1) {
238                 rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr+i);
239
240                 rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
241                 start = rtw_get_current_time();
242                 while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) &&
243                        (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
244                         DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106));
245                         rtw_usleep_os(100);
246                 }
247
248                 lo32 = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
249                 hi32 = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
250
251                 if (i == 0) {
252                         u8 lenc[2];
253                         u16 lenbak, aaabak;
254                         u16 aaa;
255                         lenc[0] = rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L);
256                         lenc[1] = rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L+1);
257
258                         aaabak = le16_to_cpup((__le16 *)lenc);
259                         lenbak = le16_to_cpu(*((__le16 *)lenc));
260                         aaa = le16_to_cpup((__le16 *)&lo32);
261                         len = le16_to_cpu(*((__le16 *)&lo32));
262
263                         limit = (len-2 < limit) ? len-2 : limit;
264
265                         DBG_88E("%s len:%u, lenbak:%u, aaa:%u, aaabak:%u\n", __func__, len, lenbak, aaa, aaabak);
266
267                         memcpy(pos, ((u8 *)&lo32)+2, (limit >= count+2) ? 2 : limit-count);
268                         count += (limit >= count+2) ? 2 : limit-count;
269                         pos = content+count;
270
271                 } else {
272                         memcpy(pos, ((u8 *)&lo32), (limit >= count+4) ? 4 : limit-count);
273                         count += (limit >= count+4) ? 4 : limit-count;
274                         pos = content+count;
275                 }
276
277                 if (limit > count && len-2 > count) {
278                         memcpy(pos, (u8 *)&hi32, (limit >= count+4) ? 4 : limit-count);
279                         count += (limit >= count+4) ? 4 : limit-count;
280                         pos = content+count;
281                 }
282
283                 if (limit <= count || len-2 <= count)
284                         break;
285                 i++;
286         }
287         rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
288         DBG_88E("%s read count:%u\n", __func__, count);
289         *size = count;
290 }
291
292 static s32 iol_read_efuse(struct adapter *padapter, u8 txpktbuf_bndy, u16 offset, u16 size_byte, u8 *logical_map)
293 {
294         s32 status = _FAIL;
295         u8 physical_map[512];
296         u16 size = 512;
297
298         rtw_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
299         _rtw_memset(physical_map, 0xFF, 512);
300         rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
301         status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
302         if (status == _SUCCESS)
303                 efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size);
304         efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map);
305         return status;
306 }
307
308 s32 rtl8188e_iol_efuse_patch(struct adapter *padapter)
309 {
310         s32     result = _SUCCESS;
311
312         DBG_88E("==> %s\n", __func__);
313         if (rtw_IOL_applied(padapter)) {
314                 iol_mode_enable(padapter, 1);
315                 result = iol_execute(padapter, CMD_READ_EFUSE_MAP);
316                 if (result == _SUCCESS)
317                         result = iol_execute(padapter, CMD_EFUSE_PATCH);
318
319                 iol_mode_enable(padapter, 0);
320         }
321         return result;
322 }
323
324 static s32 iol_ioconfig(struct adapter *padapter, u8 iocfg_bndy)
325 {
326         s32 rst = _SUCCESS;
327
328         rtw_write8(padapter, REG_TDECTRL+1, iocfg_bndy);
329         rst = iol_execute(padapter, CMD_IOCONFIG);
330         return rst;
331 }
332
333 static int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
334 {
335         struct pkt_attrib *pattrib = &xmit_frame->attrib;
336         u8 i;
337         int ret = _FAIL;
338
339         if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
340                 goto exit;
341         if (rtw_usb_bulk_size_boundary(adapter, TXDESC_SIZE+pattrib->last_txcmdsz)) {
342                 if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
343                         goto exit;
344         }
345
346         dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms);
347
348         iol_mode_enable(adapter, 1);
349         for (i = 0; i < bndy_cnt; i++) {
350                 u8 page_no = 0;
351                 page_no = i*2;
352                 ret = iol_ioconfig(adapter, page_no);
353                 if (ret != _SUCCESS)
354                         break;
355         }
356         iol_mode_enable(adapter, 0);
357 exit:
358         /* restore BCN_HEAD */
359         rtw_write8(adapter, REG_TDECTRL+1, 0);
360         return ret;
361 }
362
363 void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
364 {
365         u32 fifo_data, reg_140;
366         u32 addr, rstatus, loop = 0;
367         u16 data_cnts = (data_len/8)+1;
368         u8 *pbuf = rtw_zvmalloc(data_len+10);
369         DBG_88E("###### %s ######\n", __func__);
370
371         rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
372         if (pbuf) {
373                 for (addr = 0; addr < data_cnts; addr++) {
374                         rtw_write32(Adapter, 0x140, addr);
375                         rtw_usleep_os(2);
376                         loop = 0;
377                         do {
378                                 rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL)&BIT24);
379                                 if (rstatus) {
380                                         fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
381                                         memcpy(pbuf+(addr*8), &fifo_data, 4);
382
383                                         fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
384                                         memcpy(pbuf+(addr*8+4), &fifo_data, 4);
385                                 }
386                                 rtw_usleep_os(2);
387                         } while (!rstatus && (loop++ < 10));
388                 }
389                 rtw_IOL_cmd_buf_dump(Adapter, data_len, pbuf);
390                 rtw_vmfree(pbuf, data_len+10);
391         }
392         DBG_88E("###### %s ######\n", __func__);
393 }
394
395 static void _FWDownloadEnable(struct adapter *padapter, bool enable)
396 {
397         u8 tmp;
398
399         if (enable) {
400                 /*  MCU firmware download enable. */
401                 tmp = rtw_read8(padapter, REG_MCUFWDL);
402                 rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
403
404                 /*  8051 reset */
405                 tmp = rtw_read8(padapter, REG_MCUFWDL+2);
406                 rtw_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
407         } else {
408                 /*  MCU firmware download disable. */
409                 tmp = rtw_read8(padapter, REG_MCUFWDL);
410                 rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
411
412                 /*  Reserved for fw extension. */
413                 rtw_write8(padapter, REG_MCUFWDL+1, 0x00);
414         }
415 }
416
417 #define MAX_REG_BOLCK_SIZE      196
418
419 static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize)
420 {
421         int ret = _SUCCESS;
422         u32     blockSize_p1 = 4;       /*  (Default) Phase #1 : PCI muse use 4-byte write to download FW */
423         u32     blockSize_p2 = 8;       /*  Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */
424         u32     blockSize_p3 = 1;       /*  Phase #3 : Use 1-byte, the remnant of FW image. */
425         u32     blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
426         u32     remainSize_p1 = 0, remainSize_p2 = 0;
427         u8 *bufferPtr   = (u8 *)buffer;
428         u32     i = 0, offset = 0;
429
430         blockSize_p1 = MAX_REG_BOLCK_SIZE;
431
432         /* 3 Phase #1 */
433         blockCount_p1 = buffSize / blockSize_p1;
434         remainSize_p1 = buffSize % blockSize_p1;
435
436         if (blockCount_p1) {
437                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
438                          ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) blockCount_p1(%d) remainSize_p1(%d)\n",
439                          buffSize, blockSize_p1, blockCount_p1, remainSize_p1));
440         }
441
442         for (i = 0; i < blockCount_p1; i++) {
443                 ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
444                 if (ret == _FAIL)
445                         goto exit;
446         }
447
448         /* 3 Phase #2 */
449         if (remainSize_p1) {
450                 offset = blockCount_p1 * blockSize_p1;
451
452                 blockCount_p2 = remainSize_p1/blockSize_p2;
453                 remainSize_p2 = remainSize_p1%blockSize_p2;
454
455                 if (blockCount_p2) {
456                                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
457                                          ("_BlockWrite: [P2] buffSize_p2(%d) blockSize_p2(%d) blockCount_p2(%d) remainSize_p2(%d)\n",
458                                          (buffSize-offset), blockSize_p2 , blockCount_p2, remainSize_p2));
459                 }
460
461                 for (i = 0; i < blockCount_p2; i++) {
462                         ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
463
464                         if (ret == _FAIL)
465                                 goto exit;
466                 }
467         }
468
469         /* 3 Phase #3 */
470         if (remainSize_p2) {
471                 offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
472
473                 blockCount_p3 = remainSize_p2 / blockSize_p3;
474
475                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
476                          ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) blockCount_p3(%d)\n",
477                          (buffSize-offset), blockSize_p3, blockCount_p3));
478
479                 for (i = 0; i < blockCount_p3; i++) {
480                         ret = rtw_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
481
482                         if (ret == _FAIL)
483                                 goto exit;
484                 }
485         }
486
487 exit:
488         return ret;
489 }
490
491 static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size)
492 {
493         u8 value8;
494         u8 u8Page = (u8)(page & 0x07);
495
496         value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page;
497         rtw_write8(padapter, REG_MCUFWDL+2, value8);
498
499         return _BlockWrite(padapter, buffer, size);
500 }
501
502 static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
503 {
504         /*  Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */
505         /*  We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */
506         int ret = _SUCCESS;
507         u32     pageNums, remainSize;
508         u32     page, offset;
509         u8 *bufferPtr = (u8 *)buffer;
510
511         pageNums = size / MAX_PAGE_SIZE;
512         remainSize = size % MAX_PAGE_SIZE;
513
514         for (page = 0; page < pageNums; page++) {
515                 offset = page * MAX_PAGE_SIZE;
516                 ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_PAGE_SIZE);
517
518                 if (ret == _FAIL)
519                         goto exit;
520         }
521         if (remainSize) {
522                 offset = pageNums * MAX_PAGE_SIZE;
523                 page = pageNums;
524                 ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize);
525
526                 if (ret == _FAIL)
527                         goto exit;
528         }
529         RT_TRACE(_module_hal_init_c_, _drv_info_, ("_WriteFW Done- for Normal chip.\n"));
530 exit:
531         return ret;
532 }
533
534 void _8051Reset88E(struct adapter *padapter)
535 {
536         u8 u1bTmp;
537
538         u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
539         rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
540         rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp|(BIT2));
541         DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n");
542 }
543
544 static s32 _FWFreeToGo(struct adapter *padapter)
545 {
546         u32     counter = 0;
547         u32     value32;
548
549         /*  polling CheckSum report */
550         do {
551                 value32 = rtw_read32(padapter, REG_MCUFWDL);
552                 if (value32 & FWDL_ChkSum_rpt)
553                         break;
554         } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
555
556         if (counter >= POLLING_READY_TIMEOUT_COUNT) {
557                 DBG_88E("%s: chksum report fail! REG_MCUFWDL:0x%08x\n", __func__, value32);
558                 return _FAIL;
559         }
560         DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32);
561
562         value32 = rtw_read32(padapter, REG_MCUFWDL);
563         value32 |= MCUFWDL_RDY;
564         value32 &= ~WINTINI_RDY;
565         rtw_write32(padapter, REG_MCUFWDL, value32);
566
567         _8051Reset88E(padapter);
568
569         /*  polling for FW ready */
570         counter = 0;
571         do {
572                 value32 = rtw_read32(padapter, REG_MCUFWDL);
573                 if (value32 & WINTINI_RDY) {
574                         DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32);
575                         return _SUCCESS;
576                 }
577                 rtw_udelay_os(5);
578         } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
579
580         DBG_88E("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", __func__, value32);
581         return _FAIL;
582 }
583
584 #define IS_FW_81xxC(padapter)   (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
585
586 s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
587 {
588         s32     rtStatus = _SUCCESS;
589         u8 writeFW_retry = 0;
590         u32 fwdl_start_time;
591         struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
592         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
593         struct device *device = dvobj_to_dev(dvobj);
594         struct rt_firmware *pFirmware = NULL;
595         const struct firmware *fw;
596         struct rt_firmware_hdr *pFwHdr = NULL;
597         u8 *pFirmwareBuf;
598         u32 FirmwareLen;
599         char fw_name[] = "rtlwifi/rtl8188eufw.bin";
600         static int log_version;
601
602         RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__));
603         pFirmware = (struct rt_firmware *)rtw_zmalloc(sizeof(struct rt_firmware));
604         if (!pFirmware) {
605                 rtStatus = _FAIL;
606                 goto Exit;
607         }
608
609         if (request_firmware(&fw, fw_name, device)) {
610                 rtStatus = _FAIL;
611                 goto Exit;
612         }
613         if (!fw) {
614                 pr_err("Firmware %s not available\n", fw_name);
615                 rtStatus = _FAIL;
616                 goto Exit;
617         }
618         if (fw->size > FW_8188E_SIZE) {
619                 rtStatus = _FAIL;
620                 RT_TRACE(_module_hal_init_c_, _drv_err_, ("Firmware size exceed 0x%X. Check it.\n", FW_8188E_SIZE));
621                 goto Exit;
622         }
623
624         pFirmware->szFwBuffer = kzalloc(FW_8188E_SIZE, GFP_KERNEL);
625         if (!pFirmware->szFwBuffer) {
626                 rtStatus = _FAIL;
627                 goto Exit;
628         }
629         memcpy(pFirmware->szFwBuffer, fw->data, fw->size);
630         pFirmware->ulFwLength = fw->size;
631         pFirmwareBuf = pFirmware->szFwBuffer;
632         FirmwareLen = pFirmware->ulFwLength;
633         release_firmware(fw);
634
635         DBG_88E_LEVEL(_drv_info_, "+%s: !bUsedWoWLANFw, FmrmwareLen:%d+\n", __func__, FirmwareLen);
636
637         /*  To Check Fw header. Added by tynli. 2009.12.04. */
638         pFwHdr = (struct rt_firmware_hdr *)pFirmware->szFwBuffer;
639
640         pHalData->FirmwareVersion =  le16_to_cpu(pFwHdr->Version);
641         pHalData->FirmwareSubVersion = pFwHdr->Subversion;
642         pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
643
644         if (!log_version++)
645                 pr_info("%sFirmware Version %d, SubVersion %d, Signature 0x%x\n",
646                         DRIVER_PREFIX, pHalData->FirmwareVersion,
647                         pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
648
649         if (IS_FW_HEADER_EXIST(pFwHdr)) {
650                 /*  Shift 32 bytes for FW header */
651                 pFirmwareBuf = pFirmwareBuf + 32;
652                 FirmwareLen = FirmwareLen - 32;
653         }
654
655         /*  Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
656         /*  or it will cause download Fw fail. 2010.02.01. by tynli. */
657         if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
658                 rtw_write8(padapter, REG_MCUFWDL, 0x00);
659                 _8051Reset88E(padapter);
660         }
661
662         _FWDownloadEnable(padapter, true);
663         fwdl_start_time = rtw_get_current_time();
664         while (1) {
665                 /* reset the FWDL chksum */
666                 rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
667
668                 rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
669
670                 if (rtStatus == _SUCCESS ||
671                     (rtw_get_passing_time_ms(fwdl_start_time) > 500 && writeFW_retry++ >= 3))
672                         break;
673
674                 DBG_88E("%s writeFW_retry:%u, time after fwdl_start_time:%ums\n",
675                         __func__, writeFW_retry, rtw_get_passing_time_ms(fwdl_start_time)
676                 );
677         }
678         _FWDownloadEnable(padapter, false);
679         if (_SUCCESS != rtStatus) {
680                 DBG_88E("DL Firmware failed!\n");
681                 goto Exit;
682         }
683
684         rtStatus = _FWFreeToGo(padapter);
685         if (_SUCCESS != rtStatus) {
686                 DBG_88E("DL Firmware failed!\n");
687                 goto Exit;
688         }
689         RT_TRACE(_module_hal_init_c_, _drv_info_, ("Firmware is ready to run!\n"));
690         kfree(pFirmware->szFwBuffer);
691 Exit:
692
693         kfree(pFirmware);
694         return rtStatus;
695 }
696
697 void rtl8188e_InitializeFirmwareVars(struct adapter *padapter)
698 {
699         struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
700
701         /*  Init Fw LPS related. */
702         padapter->pwrctrlpriv.bFwCurrentInPSMode = false;
703
704         /*  Init H2C counter. by tynli. 2009.12.09. */
705         pHalData->LastHMEBoxNum = 0;
706 }
707
708 static void rtl8188e_free_hal_data(struct adapter *padapter)
709 {
710 _func_enter_;
711         kfree(padapter->HalData);
712         padapter->HalData = NULL;
713 _func_exit_;
714 }
715
716 /*  */
717 /*                      Efuse related code */
718 /*  */
719 enum{
720                 VOLTAGE_V25                                             = 0x03,
721                 LDOE25_SHIFT                                            = 28 ,
722         };
723
724 static bool
725 hal_EfusePgPacketWrite2ByteHeader(
726                 struct adapter *pAdapter,
727                 u8 efuseType,
728                 u16                             *pAddr,
729                 struct pgpkt *pTargetPkt,
730                 bool bPseudoTest);
731 static bool
732 hal_EfusePgPacketWrite1ByteHeader(
733                 struct adapter *pAdapter,
734                 u8 efuseType,
735                 u16                             *pAddr,
736                 struct pgpkt *pTargetPkt,
737                 bool bPseudoTest);
738 static bool
739 hal_EfusePgPacketWriteData(
740                 struct adapter *pAdapter,
741                 u8 efuseType,
742                 u16                             *pAddr,
743                 struct pgpkt *pTargetPkt,
744                 bool bPseudoTest);
745
746 static void
747 hal_EfusePowerSwitch_RTL8188E(
748                 struct adapter *pAdapter,
749                 u8 bWrite,
750                 u8 PwrState)
751 {
752         u8 tempval;
753         u16     tmpV16;
754
755         if (PwrState) {
756                 rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
757
758                 /*  1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
759                 tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
760                 if (!(tmpV16 & PWC_EV12V)) {
761                         tmpV16 |= PWC_EV12V;
762                          rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
763                 }
764                 /*  Reset: 0x0000h[28], default valid */
765                 tmpV16 =  rtw_read16(pAdapter, REG_SYS_FUNC_EN);
766                 if (!(tmpV16 & FEN_ELDR)) {
767                         tmpV16 |= FEN_ELDR;
768                         rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
769                 }
770
771                 /*  Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
772                 tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
773                 if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
774                         tmpV16 |= (LOADER_CLK_EN | ANA8M);
775                         rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
776                 }
777
778                 if (bWrite) {
779                         /*  Enable LDO 2.5V before read/write action */
780                         tempval = rtw_read8(pAdapter, EFUSE_TEST+3);
781                         tempval &= 0x0F;
782                         tempval |= (VOLTAGE_V25 << 4);
783                         rtw_write8(pAdapter, EFUSE_TEST+3, (tempval | 0x80));
784                 }
785         } else {
786                 rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
787
788                 if (bWrite) {
789                         /*  Disable LDO 2.5V after read/write action */
790                         tempval = rtw_read8(pAdapter, EFUSE_TEST+3);
791                         rtw_write8(pAdapter, EFUSE_TEST+3, (tempval & 0x7F));
792                 }
793         }
794 }
795
796 static void
797 rtl8188e_EfusePowerSwitch(
798                 struct adapter *pAdapter,
799                 u8 bWrite,
800                 u8 PwrState)
801 {
802         hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
803 }
804
805
806 static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
807         u16                     _offset,
808         u16                     _size_byte,
809         u8 *pbuf,
810                 bool bPseudoTest
811         )
812 {
813         u8 *efuseTbl = NULL;
814         u8 rtemp8[1];
815         u16     eFuse_Addr = 0;
816         u8 offset, wren;
817         u16     i, j;
818         u16     **eFuseWord = NULL;
819         u16     efuse_utilized = 0;
820         u8 u1temp = 0;
821
822         /*  */
823         /*  Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
824         /*  */
825         if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {/*  total E-Fuse table is 512bytes */
826                 DBG_88E("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte);
827                 goto exit;
828         }
829
830         efuseTbl = (u8 *)rtw_zmalloc(EFUSE_MAP_LEN_88E);
831         if (efuseTbl == NULL) {
832                 DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
833                 goto exit;
834         }
835
836         eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
837         if (eFuseWord == NULL) {
838                 DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
839                 goto exit;
840         }
841
842         /*  0. Refresh efuse init map as all oxFF. */
843         for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
844                 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
845                         eFuseWord[i][j] = 0xFFFF;
846
847         /*  */
848         /*  1. Read the first byte to check if efuse is empty!!! */
849         /*  */
850         /*  */
851         ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
852         if (*rtemp8 != 0xFF) {
853                 efuse_utilized++;
854                 eFuse_Addr++;
855         } else {
856                 DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8);
857                 goto exit;
858         }
859
860         /*  */
861         /*  2. Read real efuse content. Filter PG header and every section data. */
862         /*  */
863         while ((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
864                 /*  Check PG header for section num. */
865                 if ((*rtemp8 & 0x1F) == 0x0F) {         /* extended header */
866                         u1temp = ((*rtemp8 & 0xE0) >> 5);
867
868                         ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
869
870                         if ((*rtemp8 & 0x0F) == 0x0F) {
871                                 eFuse_Addr++;
872                                 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
873
874                                 if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
875                                         eFuse_Addr++;
876                                 continue;
877                         } else {
878                                 offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
879                                 wren = (*rtemp8 & 0x0F);
880                                 eFuse_Addr++;
881                         }
882                 } else {
883                         offset = ((*rtemp8 >> 4) & 0x0f);
884                         wren = (*rtemp8 & 0x0f);
885                 }
886
887                 if (offset < EFUSE_MAX_SECTION_88E) {
888                         /*  Get word enable value from PG header */
889
890                         for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
891                                 /*  Check word enable condition in the section */
892                                 if (!(wren & 0x01)) {
893                                         ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
894                                         eFuse_Addr++;
895                                         efuse_utilized++;
896                                         eFuseWord[offset][i] = (*rtemp8 & 0xff);
897                                         if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
898                                                 break;
899                                         ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
900                                         eFuse_Addr++;
901                                         efuse_utilized++;
902                                         eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
903                                         if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
904                                                 break;
905                                 }
906                                 wren >>= 1;
907                         }
908                 }
909
910                 /*  Read next PG header */
911                 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
912
913                 if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
914                         efuse_utilized++;
915                         eFuse_Addr++;
916                 }
917         }
918
919         /*  3. Collect 16 sections and 4 word unit into Efuse map. */
920         for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
921                 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
922                         efuseTbl[(i*8)+(j*2)] = (eFuseWord[i][j] & 0xff);
923                         efuseTbl[(i*8)+((j*2)+1)] = ((eFuseWord[i][j] >> 8) & 0xff);
924                 }
925         }
926
927         /*  4. Copy from Efuse map to output pointer memory!!! */
928         for (i = 0; i < _size_byte; i++)
929                 pbuf[i] = efuseTbl[_offset+i];
930
931         /*  5. Calculate Efuse utilization. */
932         rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&eFuse_Addr);
933
934 exit:
935         kfree(efuseTbl);
936
937         if (eFuseWord)
938                 rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
939 }
940
941 static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
942 {
943         if (!bPseudoTest) {
944                 int ret = _FAIL;
945                 if (rtw_IOL_applied(Adapter)) {
946                         rtw_hal_power_on(Adapter);
947
948                         iol_mode_enable(Adapter, 1);
949                         ret = iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf);
950                         iol_mode_enable(Adapter, 0);
951
952                         if (_SUCCESS == ret)
953                                 goto exit;
954                 }
955         }
956         Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
957
958 exit:
959         return;
960 }
961
962 static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
963 {
964         Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
965 }
966
967 static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
968                                u16 _offset, u16 _size_byte, u8 *pbuf,
969                                bool bPseudoTest)
970 {
971         if (bPseudoTest)
972                 ReadEFuse_Pseudo (Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
973         else
974                 ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
975 }
976
977 /* Do not support BT */
978 static void Hal_EFUSEGetEfuseDefinition88E(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut)
979 {
980         switch (type) {
981         case TYPE_EFUSE_MAX_SECTION:
982                 {
983                         u8 *pMax_section;
984                         pMax_section = (u8 *)pOut;
985                         *pMax_section = EFUSE_MAX_SECTION_88E;
986                 }
987                 break;
988         case TYPE_EFUSE_REAL_CONTENT_LEN:
989                 {
990                         u16 *pu2Tmp;
991                         pu2Tmp = (u16 *)pOut;
992                         *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
993                 }
994                 break;
995         case TYPE_EFUSE_CONTENT_LEN_BANK:
996                 {
997                         u16 *pu2Tmp;
998                         pu2Tmp = (u16 *)pOut;
999                         *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1000                 }
1001                 break;
1002         case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
1003                 {
1004                         u16 *pu2Tmp;
1005                         pu2Tmp = (u16 *)pOut;
1006                         *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1007                 }
1008                 break;
1009         case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
1010                 {
1011                         u16 *pu2Tmp;
1012                         pu2Tmp = (u16 *)pOut;
1013                         *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1014                 }
1015                 break;
1016         case TYPE_EFUSE_MAP_LEN:
1017                 {
1018                         u16 *pu2Tmp;
1019                         pu2Tmp = (u16 *)pOut;
1020                         *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
1021                 }
1022                 break;
1023         case TYPE_EFUSE_PROTECT_BYTES_BANK:
1024                 {
1025                         u8 *pu1Tmp;
1026                         pu1Tmp = (u8 *)pOut;
1027                         *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
1028                 }
1029                 break;
1030         default:
1031                 {
1032                         u8 *pu1Tmp;
1033                         pu1Tmp = (u8 *)pOut;
1034                         *pu1Tmp = 0;
1035                 }
1036                 break;
1037         }
1038 }
1039
1040 static void Hal_EFUSEGetEfuseDefinition_Pseudo88E(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut)
1041 {
1042         switch (type) {
1043         case TYPE_EFUSE_MAX_SECTION:
1044                 {
1045                         u8 *pMax_section;
1046                         pMax_section = (u8 *)pOut;
1047                         *pMax_section = EFUSE_MAX_SECTION_88E;
1048                 }
1049                 break;
1050         case TYPE_EFUSE_REAL_CONTENT_LEN:
1051                 {
1052                         u16 *pu2Tmp;
1053                         pu2Tmp = (u16 *)pOut;
1054                         *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1055                 }
1056                 break;
1057         case TYPE_EFUSE_CONTENT_LEN_BANK:
1058                 {
1059                         u16 *pu2Tmp;
1060                         pu2Tmp = (u16 *)pOut;
1061                         *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1062                 }
1063                 break;
1064         case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
1065                 {
1066                         u16 *pu2Tmp;
1067                         pu2Tmp = (u16 *)pOut;
1068                         *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1069                 }
1070                 break;
1071         case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
1072                 {
1073                         u16 *pu2Tmp;
1074                         pu2Tmp = (u16 *)pOut;
1075                         *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1076                 }
1077                 break;
1078         case TYPE_EFUSE_MAP_LEN:
1079                 {
1080                         u16 *pu2Tmp;
1081                         pu2Tmp = (u16 *)pOut;
1082                         *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
1083                 }
1084                 break;
1085         case TYPE_EFUSE_PROTECT_BYTES_BANK:
1086                 {
1087                         u8 *pu1Tmp;
1088                         pu1Tmp = (u8 *)pOut;
1089                         *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
1090                 }
1091                 break;
1092         default:
1093                 {
1094                         u8 *pu1Tmp;
1095                         pu1Tmp = (u8 *)pOut;
1096                         *pu1Tmp = 0;
1097                 }
1098                 break;
1099         }
1100 }
1101
1102 static void rtl8188e_EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool bPseudoTest)
1103 {
1104         if (bPseudoTest)
1105                 Hal_EFUSEGetEfuseDefinition_Pseudo88E(pAdapter, efuseType, type, pOut);
1106         else
1107                 Hal_EFUSEGetEfuseDefinition88E(pAdapter, efuseType, type, pOut);
1108 }
1109
1110 static u8 Hal_EfuseWordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest)
1111 {
1112         u16     tmpaddr = 0;
1113         u16     start_addr = efuse_addr;
1114         u8 badworden = 0x0F;
1115         u8 tmpdata[8];
1116
1117         _rtw_memset((void *)tmpdata, 0xff, PGPKT_DATA_SIZE);
1118
1119         if (!(word_en&BIT0)) {
1120                 tmpaddr = start_addr;
1121                 efuse_OneByteWrite(pAdapter, start_addr++, data[0], bPseudoTest);
1122                 efuse_OneByteWrite(pAdapter, start_addr++, data[1], bPseudoTest);
1123
1124                 efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[0], bPseudoTest);
1125                 efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[1], bPseudoTest);
1126                 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
1127                         badworden &= (~BIT0);
1128         }
1129         if (!(word_en&BIT1)) {
1130                 tmpaddr = start_addr;
1131                 efuse_OneByteWrite(pAdapter, start_addr++, data[2], bPseudoTest);
1132                 efuse_OneByteWrite(pAdapter, start_addr++, data[3], bPseudoTest);
1133
1134                 efuse_OneByteRead(pAdapter, tmpaddr    , &tmpdata[2], bPseudoTest);
1135                 efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[3], bPseudoTest);
1136                 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
1137                         badworden &= (~BIT1);
1138         }
1139         if (!(word_en&BIT2)) {
1140                 tmpaddr = start_addr;
1141                 efuse_OneByteWrite(pAdapter, start_addr++, data[4], bPseudoTest);
1142                 efuse_OneByteWrite(pAdapter, start_addr++, data[5], bPseudoTest);
1143
1144                 efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[4], bPseudoTest);
1145                 efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[5], bPseudoTest);
1146                 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
1147                         badworden &= (~BIT2);
1148         }
1149         if (!(word_en&BIT3)) {
1150                 tmpaddr = start_addr;
1151                 efuse_OneByteWrite(pAdapter, start_addr++, data[6], bPseudoTest);
1152                 efuse_OneByteWrite(pAdapter, start_addr++, data[7], bPseudoTest);
1153
1154                 efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[6], bPseudoTest);
1155                 efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[7], bPseudoTest);
1156                 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
1157                         badworden &= (~BIT3);
1158         }
1159         return badworden;
1160 }
1161
1162 static u8 Hal_EfuseWordEnableDataWrite_Pseudo(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest)
1163 {
1164         u8 ret;
1165
1166         ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1167         return ret;
1168 }
1169
1170 static u8 rtl8188e_Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest)
1171 {
1172         u8 ret = 0;
1173
1174         if (bPseudoTest)
1175                 ret = Hal_EfuseWordEnableDataWrite_Pseudo (pAdapter, efuse_addr, word_en, data, bPseudoTest);
1176         else
1177                 ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1178         return ret;
1179 }
1180
1181 static u16 hal_EfuseGetCurrentSize_8188e(struct adapter *pAdapter, bool bPseudoTest)
1182 {
1183         int     bContinual = true;
1184         u16     efuse_addr = 0;
1185         u8 hoffset = 0, hworden = 0;
1186         u8 efuse_data, word_cnts = 0;
1187
1188         if (bPseudoTest)
1189                 efuse_addr = (u16)(fakeEfuseUsedBytes);
1190         else
1191                 rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1192
1193         while (bContinual &&
1194                efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest) &&
1195                AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1196                 if (efuse_data != 0xFF) {
1197                         if ((efuse_data&0x1F) == 0x0F) {                /* extended header */
1198                                 hoffset = efuse_data;
1199                                 efuse_addr++;
1200                                 efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest);
1201                                 if ((efuse_data & 0x0F) == 0x0F) {
1202                                         efuse_addr++;
1203                                         continue;
1204                                 } else {
1205                                         hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1206                                         hworden = efuse_data & 0x0F;
1207                                 }
1208                         } else {
1209                                 hoffset = (efuse_data>>4) & 0x0F;
1210                                 hworden =  efuse_data & 0x0F;
1211                         }
1212                         word_cnts = Efuse_CalculateWordCnts(hworden);
1213                         /* read next header */
1214                         efuse_addr = efuse_addr + (word_cnts*2)+1;
1215                 } else {
1216                         bContinual = false;
1217                 }
1218         }
1219
1220         if (bPseudoTest)
1221                 fakeEfuseUsedBytes = efuse_addr;
1222         else
1223                 rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1224
1225         return efuse_addr;
1226 }
1227
1228 static u16 Hal_EfuseGetCurrentSize_Pseudo(struct adapter *pAdapter, bool bPseudoTest)
1229 {
1230         u16     ret = 0;
1231
1232         ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
1233         return ret;
1234 }
1235
1236 static u16 rtl8188e_EfuseGetCurrentSize(struct adapter *pAdapter, u8 efuseType, bool bPseudoTest)
1237 {
1238         u16     ret = 0;
1239
1240         if (bPseudoTest)
1241                 ret = Hal_EfuseGetCurrentSize_Pseudo(pAdapter, bPseudoTest);
1242         else
1243                 ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
1244         return ret;
1245 }
1246
1247 static int hal_EfusePgPacketRead_8188e(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
1248 {
1249         u8 ReadState = PG_STATE_HEADER;
1250         int     bContinual = true;
1251         int     bDataEmpty = true;
1252         u8 efuse_data, word_cnts = 0;
1253         u16     efuse_addr = 0;
1254         u8 hoffset = 0, hworden = 0;
1255         u8 tmpidx = 0;
1256         u8 tmpdata[8];
1257         u8 max_section = 0;
1258         u8 tmp_header = 0;
1259
1260         EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (void *)&max_section, bPseudoTest);
1261
1262         if (data == NULL)
1263                 return false;
1264         if (offset > max_section)
1265                 return false;
1266
1267         _rtw_memset((void *)data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
1268         _rtw_memset((void *)tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
1269
1270         /*  <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */
1271         /*  Skip dummy parts to prevent unexpected data read from Efuse. */
1272         /*  By pass right now. 2009.02.19. */
1273         while (bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1274                 /*   Header Read ------------- */
1275                 if (ReadState & PG_STATE_HEADER) {
1276                         if (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
1277                                 if (EXT_HEADER(efuse_data)) {
1278                                         tmp_header = efuse_data;
1279                                         efuse_addr++;
1280                                         efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest);
1281                                         if (!ALL_WORDS_DISABLED(efuse_data)) {
1282                                                 hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1283                                                 hworden = efuse_data & 0x0F;
1284                                         } else {
1285                                                 DBG_88E("Error, All words disabled\n");
1286                                                 efuse_addr++;
1287                                                 continue;
1288                                         }
1289                                 } else {
1290                                         hoffset = (efuse_data>>4) & 0x0F;
1291                                         hworden =  efuse_data & 0x0F;
1292                                 }
1293                                 word_cnts = Efuse_CalculateWordCnts(hworden);
1294                                 bDataEmpty = true;
1295
1296                                 if (hoffset == offset) {
1297                                         for (tmpidx = 0; tmpidx < word_cnts*2; tmpidx++) {
1298                                                 if (efuse_OneByteRead(pAdapter, efuse_addr+1+tmpidx, &efuse_data, bPseudoTest)) {
1299                                                         tmpdata[tmpidx] = efuse_data;
1300                                                         if (efuse_data != 0xff)
1301                                                                 bDataEmpty = false;
1302                                                 }
1303                                         }
1304                                         if (bDataEmpty == false) {
1305                                                 ReadState = PG_STATE_DATA;
1306                                         } else {/* read next header */
1307                                                 efuse_addr = efuse_addr + (word_cnts*2)+1;
1308                                                 ReadState = PG_STATE_HEADER;
1309                                         }
1310                                 } else {/* read next header */
1311                                         efuse_addr = efuse_addr + (word_cnts*2)+1;
1312                                         ReadState = PG_STATE_HEADER;
1313                                 }
1314                         } else {
1315                                 bContinual = false;
1316                         }
1317                 } else if (ReadState & PG_STATE_DATA) {
1318                 /*   Data section Read ------------- */
1319                         efuse_WordEnableDataRead(hworden, tmpdata, data);
1320                         efuse_addr = efuse_addr + (word_cnts*2)+1;
1321                         ReadState = PG_STATE_HEADER;
1322                 }
1323
1324         }
1325
1326         if ((data[0] == 0xff) && (data[1] == 0xff) && (data[2] == 0xff)  && (data[3] == 0xff) &&
1327             (data[4] == 0xff) && (data[5] == 0xff) && (data[6] == 0xff)  && (data[7] == 0xff))
1328                 return false;
1329         else
1330                 return true;
1331 }
1332
1333 static int Hal_EfusePgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
1334 {
1335         int     ret;
1336
1337         ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
1338         return ret;
1339 }
1340
1341 static int Hal_EfusePgPacketRead_Pseudo(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
1342 {
1343         int     ret;
1344
1345         ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
1346         return ret;
1347 }
1348
1349 static int rtl8188e_Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
1350 {
1351         int     ret;
1352
1353         if (bPseudoTest)
1354                 ret = Hal_EfusePgPacketRead_Pseudo (pAdapter, offset, data, bPseudoTest);
1355         else
1356                 ret = Hal_EfusePgPacketRead(pAdapter, offset, data, bPseudoTest);
1357         return ret;
1358 }
1359
1360 static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, struct pgpkt *pFixPkt, u16 *pAddr, bool bPseudoTest)
1361 {
1362         u8 originaldata[8], badworden = 0;
1363         u16     efuse_addr = *pAddr;
1364         u32     PgWriteSuccess = 0;
1365
1366         _rtw_memset((void *)originaldata, 0xff, 8);
1367
1368         if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) {
1369                 /* check if data exist */
1370                 badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pFixPkt->word_en, originaldata, bPseudoTest);
1371
1372                 if (badworden != 0xf) { /*  write fail */
1373                         PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest);
1374
1375                         if (!PgWriteSuccess)
1376                                 return false;
1377                         else
1378                                 efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
1379                 } else {
1380                         efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) + 1;
1381                 }
1382         } else {
1383                 efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) + 1;
1384         }
1385         *pAddr = efuse_addr;
1386         return true;
1387 }
1388
1389 static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
1390 {
1391         bool bRet = false;
1392         u16     efuse_addr = *pAddr, efuse_max_available_len = 0;
1393         u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0;
1394         u8 repeatcnt = 0;
1395
1396         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest);
1397
1398         while (efuse_addr < efuse_max_available_len) {
1399                 pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
1400                 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1401                 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1402
1403                 while (tmp_header == 0xFF) {
1404                         if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1405                                 return false;
1406
1407                         efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1408                         efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1409                 }
1410
1411                 /* to write ext_header */
1412                 if (tmp_header == pg_header) {
1413                         efuse_addr++;
1414                         pg_header_temp = pg_header;
1415                         pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
1416
1417                         efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1418                         efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1419
1420                         while (tmp_header == 0xFF) {
1421                                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1422                                         return false;
1423
1424                                 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1425                                 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1426                         }
1427
1428                         if ((tmp_header & 0x0F) == 0x0F) {      /* word_en PG fail */
1429                                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1430                                         return false;
1431                                 } else {
1432                                         efuse_addr++;
1433                                         continue;
1434                                 }
1435                         } else if (pg_header != tmp_header) {   /* offset PG fail */
1436                                 struct pgpkt    fixPkt;
1437                                 fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
1438                                 fixPkt.word_en = tmp_header & 0x0F;
1439                                 fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
1440                                 if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
1441                                         return false;
1442                         } else {
1443                                 bRet = true;
1444                                 break;
1445                         }
1446                 } else if ((tmp_header & 0x1F) == 0x0F) {               /* wrong extended header */
1447                         efuse_addr += 2;
1448                         continue;
1449                 }
1450         }
1451
1452         *pAddr = efuse_addr;
1453         return bRet;
1454 }
1455
1456 static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
1457 {
1458         bool bRet = false;
1459         u8 pg_header = 0, tmp_header = 0;
1460         u16     efuse_addr = *pAddr;
1461         u8 repeatcnt = 0;
1462
1463         pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
1464
1465         efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1466         efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1467
1468         while (tmp_header == 0xFF) {
1469                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1470                         return false;
1471                 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1472                 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1473         }
1474
1475         if (pg_header == tmp_header) {
1476                 bRet = true;
1477         } else {
1478                 struct pgpkt    fixPkt;
1479                 fixPkt.offset = (tmp_header>>4) & 0x0F;
1480                 fixPkt.word_en = tmp_header & 0x0F;
1481                 fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
1482                 if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
1483                         return false;
1484         }
1485
1486         *pAddr = efuse_addr;
1487         return bRet;
1488 }
1489
1490 static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
1491 {
1492         u16     efuse_addr = *pAddr;
1493         u8 badworden = 0;
1494         u32     PgWriteSuccess = 0;
1495
1496         badworden = 0x0f;
1497         badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
1498         if (badworden == 0x0F) {
1499                 /*  write ok */
1500                 return true;
1501         } else {
1502                 /* reorganize other pg packet */
1503                 PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
1504                 if (!PgWriteSuccess)
1505                         return false;
1506                 else
1507                         return true;
1508         }
1509 }
1510
1511 static bool
1512 hal_EfusePgPacketWriteHeader(
1513                                 struct adapter *pAdapter,
1514                                 u8 efuseType,
1515                                 u16                             *pAddr,
1516                                 struct pgpkt *pTargetPkt,
1517                                 bool bPseudoTest)
1518 {
1519         bool bRet = false;
1520
1521         if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
1522                 bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
1523         else
1524                 bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
1525
1526         return bRet;
1527 }
1528
1529 static bool wordEnMatched(struct pgpkt *pTargetPkt, struct pgpkt *pCurPkt,
1530                           u8 *pWden)
1531 {
1532         u8 match_word_en = 0x0F;        /*  default all words are disabled */
1533
1534         /*  check if the same words are enabled both target and current PG packet */
1535         if (((pTargetPkt->word_en & BIT0) == 0) &&
1536             ((pCurPkt->word_en & BIT0) == 0))
1537                 match_word_en &= ~BIT0;                         /*  enable word 0 */
1538         if (((pTargetPkt->word_en & BIT1) == 0) &&
1539             ((pCurPkt->word_en & BIT1) == 0))
1540                 match_word_en &= ~BIT1;                         /*  enable word 1 */
1541         if (((pTargetPkt->word_en & BIT2) == 0) &&
1542             ((pCurPkt->word_en & BIT2) == 0))
1543                 match_word_en &= ~BIT2;                         /*  enable word 2 */
1544         if (((pTargetPkt->word_en & BIT3) == 0) &&
1545             ((pCurPkt->word_en & BIT3) == 0))
1546                 match_word_en &= ~BIT3;                         /*  enable word 3 */
1547
1548         *pWden = match_word_en;
1549
1550         if (match_word_en != 0xf)
1551                 return true;
1552         else
1553                 return false;
1554 }
1555
1556 static bool hal_EfuseCheckIfDatafollowed(struct adapter *pAdapter, u8 word_cnts, u16 startAddr, bool bPseudoTest)
1557 {
1558         bool bRet = false;
1559         u8 i, efuse_data;
1560
1561         for (i = 0; i < (word_cnts*2); i++) {
1562                 if (efuse_OneByteRead(pAdapter, (startAddr+i), &efuse_data, bPseudoTest) && (efuse_data != 0xFF))
1563                         bRet = true;
1564         }
1565         return bRet;
1566 }
1567
1568 static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
1569 {
1570         bool bRet = false;
1571         u8 i, efuse_data = 0, cur_header = 0;
1572         u8 matched_wden = 0, badworden = 0;
1573         u16     startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
1574         struct pgpkt curPkt;
1575
1576         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest);
1577         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&efuse_max, bPseudoTest);
1578
1579         if (efuseType == EFUSE_WIFI) {
1580                 if (bPseudoTest) {
1581                         startAddr = (u16)(fakeEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN);
1582                 } else {
1583                         rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
1584                         startAddr %= EFUSE_REAL_CONTENT_LEN;
1585                 }
1586         } else {
1587                 if (bPseudoTest)
1588                         startAddr = (u16)(fakeBTEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN);
1589                 else
1590                         startAddr = (u16)(BTEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN);
1591         }
1592
1593         while (1) {
1594                 if (startAddr >= efuse_max_available_len) {
1595                         bRet = false;
1596                         break;
1597                 }
1598
1599                 if (efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
1600                         if (EXT_HEADER(efuse_data)) {
1601                                 cur_header = efuse_data;
1602                                 startAddr++;
1603                                 efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest);
1604                                 if (ALL_WORDS_DISABLED(efuse_data)) {
1605                                         bRet = false;
1606                                         break;
1607                                 } else {
1608                                         curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1609                                         curPkt.word_en = efuse_data & 0x0F;
1610                                 }
1611                         } else {
1612                                 cur_header  =  efuse_data;
1613                                 curPkt.offset = (cur_header>>4) & 0x0F;
1614                                 curPkt.word_en = cur_header & 0x0F;
1615                         }
1616
1617                         curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
1618                         /*  if same header is found but no data followed */
1619                         /*  write some part of data followed by the header. */
1620                         if ((curPkt.offset == pTargetPkt->offset) &&
1621                             (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr+1, bPseudoTest)) &&
1622                             wordEnMatched(pTargetPkt, &curPkt, &matched_wden)) {
1623                                 /*  Here to write partial data */
1624                                 badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest);
1625                                 if (badworden != 0x0F) {
1626                                         u32     PgWriteSuccess = 0;
1627                                         /*  if write fail on some words, write these bad words again */
1628
1629                                         PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
1630
1631                                         if (!PgWriteSuccess) {
1632                                                 bRet = false;   /*  write fail, return */
1633                                                 break;
1634                                         }
1635                                 }
1636                                 /*  partial write ok, update the target packet for later use */
1637                                 for (i = 0; i < 4; i++) {
1638                                         if ((matched_wden & (0x1<<i)) == 0)     /*  this word has been written */
1639                                                 pTargetPkt->word_en |= (0x1<<i);        /*  disable the word */
1640                                 }
1641                                 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1642                         }
1643                         /*  read from next header */
1644                         startAddr = startAddr + (curPkt.word_cnts*2) + 1;
1645                 } else {
1646                         /*  not used header, 0xff */
1647                         *pAddr = startAddr;
1648                         bRet = true;
1649                         break;
1650                 }
1651         }
1652         return bRet;
1653 }
1654
1655 static bool
1656 hal_EfusePgCheckAvailableAddr(
1657                 struct adapter *pAdapter,
1658                 u8 efuseType,
1659                 bool bPseudoTest
1660         )
1661 {
1662         u16     efuse_max_available_len = 0;
1663
1664         /* Change to check TYPE_EFUSE_MAP_LEN , because 8188E raw 256, logic map over 256. */
1665         EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len, false);
1666
1667         if (Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len)
1668                 return false;
1669         return true;
1670 }
1671
1672 static void hal_EfuseConstructPGPkt(u8 offset, u8 word_en, u8 *pData, struct pgpkt *pTargetPkt)
1673 {
1674         _rtw_memset((void *)pTargetPkt->data, 0xFF, sizeof(u8)*8);
1675         pTargetPkt->offset = offset;
1676         pTargetPkt->word_en = word_en;
1677         efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
1678         pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1679 }
1680
1681 static bool hal_EfusePgPacketWrite_8188e(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *pData, bool bPseudoTest)
1682 {
1683         struct pgpkt    targetPkt;
1684         u16                     startAddr = 0;
1685         u8 efuseType = EFUSE_WIFI;
1686
1687         if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
1688                 return false;
1689
1690         hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
1691
1692         if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1693                 return false;
1694
1695         if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1696                 return false;
1697
1698         if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1699                 return false;
1700
1701         return true;
1702 }
1703
1704 static int Hal_EfusePgPacketWrite_Pseudo(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest)
1705 {
1706         int ret;
1707
1708         ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
1709         return ret;
1710 }
1711
1712 static int Hal_EfusePgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest)
1713 {
1714         int     ret = 0;
1715         ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
1716
1717         return ret;
1718 }
1719
1720 static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest)
1721 {
1722         int     ret;
1723
1724         if (bPseudoTest)
1725                 ret = Hal_EfusePgPacketWrite_Pseudo (pAdapter, offset, word_en, data, bPseudoTest);
1726         else
1727                 ret = Hal_EfusePgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);
1728         return ret;
1729 }
1730
1731 static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
1732 {
1733         u32                             value32;
1734         struct HAL_VERSION              ChipVersion;
1735         struct hal_data_8188e   *pHalData;
1736
1737         pHalData = GET_HAL_DATA(padapter);
1738
1739         value32 = rtw_read32(padapter, REG_SYS_CFG);
1740         ChipVersion.ICType = CHIP_8188E;
1741         ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
1742
1743         ChipVersion.RFType = RF_TYPE_1T1R;
1744         ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
1745         ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; /*  IC version (CUT) */
1746
1747         /*  For regulator mode. by tynli. 2011.01.14 */
1748         pHalData->RegulatorMode = ((value32 & TRP_BT_EN) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
1749
1750         ChipVersion.ROMVer = 0; /*  ROM code version. */
1751         pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
1752
1753         dump_chip_info(ChipVersion);
1754
1755         pHalData->VersionID = ChipVersion;
1756
1757         if (IS_1T2R(ChipVersion)) {
1758                 pHalData->rf_type = RF_1T2R;
1759                 pHalData->NumTotalRFPath = 2;
1760         } else if (IS_2T2R(ChipVersion)) {
1761                 pHalData->rf_type = RF_2T2R;
1762                 pHalData->NumTotalRFPath = 2;
1763         } else{
1764                 pHalData->rf_type = RF_1T1R;
1765                 pHalData->NumTotalRFPath = 1;
1766         }
1767
1768         MSG_88E("RF_Type is %x!!\n", pHalData->rf_type);
1769
1770         return ChipVersion;
1771 }
1772
1773 static void rtl8188e_read_chip_version(struct adapter *padapter)
1774 {
1775         ReadChipVersion8188E(padapter);
1776 }
1777
1778 static void rtl8188e_GetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet)
1779 {
1780 }
1781
1782 static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet)
1783 {
1784         struct hal_data_8188e   *pHalData = GET_HAL_DATA(Adapter);
1785         struct odm_dm_struct *podmpriv = &pHalData->odmpriv;
1786         switch (eVariable) {
1787         case HAL_ODM_STA_INFO:
1788                 {
1789                         struct sta_info *psta = (struct sta_info *)pValue1;
1790                         if (bSet) {
1791                                 DBG_88E("### Set STA_(%d) info\n", psta->mac_id);
1792                                 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta);
1793                                 ODM_RAInfo_Init(podmpriv, psta->mac_id);
1794                         } else {
1795                                 DBG_88E("### Clean STA_(%d) info\n", psta->mac_id);
1796                                 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL);
1797                        }
1798                 }
1799                 break;
1800         case HAL_ODM_P2P_STATE:
1801                         ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
1802                 break;
1803         case HAL_ODM_WIFI_DISPLAY_STATE:
1804                         ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
1805                 break;
1806         default:
1807                 break;
1808         }
1809 }
1810
1811 void rtl8188e_clone_haldata(struct adapter *dst_adapter, struct adapter *src_adapter)
1812 {
1813         memcpy(dst_adapter->HalData, src_adapter->HalData, dst_adapter->hal_data_sz);
1814 }
1815
1816 void rtl8188e_start_thread(struct adapter *padapter)
1817 {
1818 }
1819
1820 void rtl8188e_stop_thread(struct adapter *padapter)
1821 {
1822 }
1823
1824 static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
1825 {
1826         if (enable) {
1827                 DBG_88E("Enable notch filter\n");
1828                 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
1829         } else {
1830                 DBG_88E("Disable notch filter\n");
1831                 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
1832         }
1833 }
1834 void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
1835 {
1836         pHalFunc->free_hal_data = &rtl8188e_free_hal_data;
1837
1838         pHalFunc->dm_init = &rtl8188e_init_dm_priv;
1839         pHalFunc->dm_deinit = &rtl8188e_deinit_dm_priv;
1840
1841         pHalFunc->read_chip_version = &rtl8188e_read_chip_version;
1842
1843         pHalFunc->set_bwmode_handler = &PHY_SetBWMode8188E;
1844         pHalFunc->set_channel_handler = &PHY_SwChnl8188E;
1845
1846         pHalFunc->hal_dm_watchdog = &rtl8188e_HalDmWatchDog;
1847
1848         pHalFunc->Add_RateATid = &rtl8188e_Add_RateATid;
1849         pHalFunc->run_thread = &rtl8188e_start_thread;
1850         pHalFunc->cancel_thread = &rtl8188e_stop_thread;
1851
1852         pHalFunc->AntDivBeforeLinkHandler = &AntDivBeforeLink8188E;
1853         pHalFunc->AntDivCompareHandler = &AntDivCompare8188E;
1854         pHalFunc->read_bbreg = &rtl8188e_PHY_QueryBBReg;
1855         pHalFunc->write_bbreg = &rtl8188e_PHY_SetBBReg;
1856         pHalFunc->read_rfreg = &rtl8188e_PHY_QueryRFReg;
1857         pHalFunc->write_rfreg = &rtl8188e_PHY_SetRFReg;
1858
1859         /*  Efuse related function */
1860         pHalFunc->EfusePowerSwitch = &rtl8188e_EfusePowerSwitch;
1861         pHalFunc->ReadEFuse = &rtl8188e_ReadEFuse;
1862         pHalFunc->EFUSEGetEfuseDefinition = &rtl8188e_EFUSE_GetEfuseDefinition;
1863         pHalFunc->EfuseGetCurrentSize = &rtl8188e_EfuseGetCurrentSize;
1864         pHalFunc->Efuse_PgPacketRead = &rtl8188e_Efuse_PgPacketRead;
1865         pHalFunc->Efuse_PgPacketWrite = &rtl8188e_Efuse_PgPacketWrite;
1866         pHalFunc->Efuse_WordEnableDataWrite = &rtl8188e_Efuse_WordEnableDataWrite;
1867
1868         pHalFunc->sreset_init_value = &sreset_init_value;
1869         pHalFunc->sreset_reset_value = &sreset_reset_value;
1870         pHalFunc->silentreset = &rtl8188e_silentreset_for_specific_platform;
1871         pHalFunc->sreset_xmit_status_check = &rtl8188e_sreset_xmit_status_check;
1872         pHalFunc->sreset_linked_status_check  = &rtl8188e_sreset_linked_status_check;
1873         pHalFunc->sreset_get_wifi_status  = &sreset_get_wifi_status;
1874
1875         pHalFunc->GetHalODMVarHandler = &rtl8188e_GetHalODMVar;
1876         pHalFunc->SetHalODMVarHandler = &rtl8188e_SetHalODMVar;
1877
1878         pHalFunc->IOL_exec_cmds_sync = &rtl8188e_IOL_exec_cmds_sync;
1879
1880         pHalFunc->hal_notch_filter = &hal_notch_filter_8188e;
1881 }
1882
1883 u8 GetEEPROMSize8188E(struct adapter *padapter)
1884 {
1885         u8 size = 0;
1886         u32     cr;
1887
1888         cr = rtw_read16(padapter, REG_9346CR);
1889         /*  6: EEPROM used is 93C46, 4: boot from E-Fuse. */
1890         size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
1891
1892         MSG_88E("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
1893
1894         return size;
1895 }
1896
1897 /*  */
1898 /*  */
1899 /*  LLT R/W/Init function */
1900 /*  */
1901 /*  */
1902 static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
1903 {
1904         s32     status = _SUCCESS;
1905         s32     count = 0;
1906         u32     value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
1907         u16     LLTReg = REG_LLT_INIT;
1908
1909         rtw_write32(padapter, LLTReg, value);
1910
1911         /* polling */
1912         do {
1913                 value = rtw_read32(padapter, LLTReg);
1914                 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
1915                         break;
1916
1917                 if (count > POLLING_LLT_THRESHOLD) {
1918                         RT_TRACE(_module_hal_init_c_, _drv_err_, ("Failed to polling write LLT done at address %d!\n", address));
1919                         status = _FAIL;
1920                         break;
1921                 }
1922         } while (count++);
1923
1924         return status;
1925 }
1926
1927 s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
1928 {
1929         s32     status = _FAIL;
1930         u32     i;
1931         u32     Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;/*  176, 22k */
1932
1933         if (rtw_IOL_applied(padapter)) {
1934                 status = iol_InitLLTTable(padapter, txpktbuf_bndy);
1935         } else {
1936                 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
1937                         status = _LLTWrite(padapter, i, i + 1);
1938                         if (_SUCCESS != status)
1939                                 return status;
1940                 }
1941
1942                 /*  end of list */
1943                 status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
1944                 if (_SUCCESS != status)
1945                         return status;
1946
1947                 /*  Make the other pages as ring buffer */
1948                 /*  This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer. */
1949                 /*  Otherwise used as local loopback buffer. */
1950                 for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
1951                         status = _LLTWrite(padapter, i, (i + 1));
1952                         if (_SUCCESS != status)
1953                                 return status;
1954                 }
1955
1956                 /*  Let last entry point to the start entry of ring buffer */
1957                 status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
1958                 if (_SUCCESS != status) {
1959                         return status;
1960                 }
1961         }
1962
1963         return status;
1964 }
1965
1966 void
1967 Hal_InitPGData88E(struct adapter *padapter)
1968 {
1969         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1970
1971         if (!pEEPROM->bautoload_fail_flag) { /*  autoload OK. */
1972                 if (!is_boot_from_eeprom(padapter)) {
1973                         /*  Read EFUSE real map to shadow. */
1974                         EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
1975                 }
1976         } else {/* autoload fail */
1977                 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n"));
1978                 /* update to default value 0xFF */
1979                 if (!is_boot_from_eeprom(padapter))
1980                         EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
1981         }
1982 }
1983
1984 void
1985 Hal_EfuseParseIDCode88E(
1986                 struct adapter *padapter,
1987                 u8 *hwinfo
1988         )
1989 {
1990         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1991         u16                     EEPROMId;
1992
1993         /*  Checl 0x8129 again for making sure autoload status!! */
1994         EEPROMId = le16_to_cpu(*((__le16 *)hwinfo));
1995         if (EEPROMId != RTL_EEPROM_ID) {
1996                 DBG_88E("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
1997                 pEEPROM->bautoload_fail_flag = true;
1998         } else {
1999                 pEEPROM->bautoload_fail_flag = false;
2000         }
2001
2002         DBG_88E("EEPROM ID = 0x%04x\n", EEPROMId);
2003 }
2004
2005 static void Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g *pwrInfo24G, u8 *PROMContent, bool AutoLoadFail)
2006 {
2007         u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_88E, group, TxCount = 0;
2008
2009         _rtw_memset(pwrInfo24G, 0, sizeof(struct txpowerinfo24g));
2010
2011         if (AutoLoadFail) {
2012                 for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) {
2013                         /* 2.4G default value */
2014                         for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
2015                                 pwrInfo24G->IndexCCK_Base[rfPath][group] =      EEPROM_DEFAULT_24G_INDEX;
2016                                 pwrInfo24G->IndexBW40_Base[rfPath][group] =     EEPROM_DEFAULT_24G_INDEX;
2017                         }
2018                         for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
2019                                 if (TxCount == 0) {
2020                                         pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF;
2021                                         pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF;
2022                                 } else {
2023                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2024                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2025                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2026                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2027                                 }
2028                         }
2029                 }
2030                 return;
2031         }
2032
2033         for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) {
2034                 /* 2.4G default value */
2035                 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
2036                         pwrInfo24G->IndexCCK_Base[rfPath][group] =      PROMContent[eeAddr++];
2037                         if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
2038                                 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
2039                 }
2040                 for (group = 0; group < MAX_CHNL_GROUP_24G-1; group++) {
2041                         pwrInfo24G->IndexBW40_Base[rfPath][group] =     PROMContent[eeAddr++];
2042                         if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
2043                                 pwrInfo24G->IndexBW40_Base[rfPath][group] =     EEPROM_DEFAULT_24G_INDEX;
2044                 }
2045                 for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
2046                         if (TxCount == 0) {
2047                                 pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
2048                                 if (PROMContent[eeAddr] == 0xFF) {
2049                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_HT20_DIFF;
2050                                 } else {
2051                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
2052                                         if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)              /* 4bit sign number to 8 bit sign number */
2053                                                 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
2054                                 }
2055
2056                                 if (PROMContent[eeAddr] == 0xFF) {
2057                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_24G_OFDM_DIFF;
2058                                 } else {
2059                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0x0f);
2060                                         if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)              /* 4bit sign number to 8 bit sign number */
2061                                                 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
2062                                 }
2063                                 pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
2064                                 eeAddr++;
2065                         } else {
2066                                 if (PROMContent[eeAddr] == 0xFF) {
2067                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
2068                                 } else {
2069                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0xf0)>>4;
2070                                         if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT3)              /* 4bit sign number to 8 bit sign number */
2071                                                 pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
2072                                 }
2073
2074                                 if (PROMContent[eeAddr] == 0xFF) {
2075                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
2076                                 } else {
2077                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0x0f);
2078                                         if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)              /* 4bit sign number to 8 bit sign number */
2079                                                 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
2080                                 }
2081                                 eeAddr++;
2082
2083                                 if (PROMContent[eeAddr] == 0xFF) {
2084                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2085                                 } else {
2086                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0xf0)>>4;
2087                                         if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)              /* 4bit sign number to 8 bit sign number */
2088                                                 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
2089                                 }
2090
2091                                 if (PROMContent[eeAddr] == 0xFF) {
2092                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2093                                 } else {
2094                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
2095                                         if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT3)               /* 4bit sign number to 8 bit sign number */
2096                                                 pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
2097                                 }
2098                                 eeAddr++;
2099                         }
2100                 }
2101         }
2102 }
2103
2104 static u8 Hal_GetChnlGroup88E(u8 chnl, u8 *pGroup)
2105 {
2106         u8 bIn24G = true;
2107
2108         if (chnl <= 14) {
2109                 bIn24G = true;
2110
2111                 if (chnl < 3)                   /*  Channel 1-2 */
2112                         *pGroup = 0;
2113                 else if (chnl < 6)              /*  Channel 3-5 */
2114                         *pGroup = 1;
2115                 else     if (chnl < 9)          /*  Channel 6-8 */
2116                         *pGroup = 2;
2117                 else if (chnl < 12)             /*  Channel 9-11 */
2118                         *pGroup = 3;
2119                 else if (chnl < 14)             /*  Channel 12-13 */
2120                         *pGroup = 4;
2121                 else if (chnl == 14)            /*  Channel 14 */
2122                         *pGroup = 5;
2123         } else {
2124                 bIn24G = false;
2125
2126                 if (chnl <= 40)
2127                         *pGroup = 0;
2128                 else if (chnl <= 48)
2129                         *pGroup = 1;
2130                 else     if (chnl <= 56)
2131                         *pGroup = 2;
2132                 else if (chnl <= 64)
2133                         *pGroup = 3;
2134                 else if (chnl <= 104)
2135                         *pGroup = 4;
2136                 else if (chnl <= 112)
2137                         *pGroup = 5;
2138                 else if (chnl <= 120)
2139                         *pGroup = 5;
2140                 else if (chnl <= 128)
2141                         *pGroup = 6;
2142                 else if (chnl <= 136)
2143                         *pGroup = 7;
2144                 else if (chnl <= 144)
2145                         *pGroup = 8;
2146                 else if (chnl <= 153)
2147                         *pGroup = 9;
2148                 else if (chnl <= 161)
2149                         *pGroup = 10;
2150                 else if (chnl <= 177)
2151                         *pGroup = 11;
2152         }
2153         return bIn24G;
2154 }
2155
2156 void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
2157 {
2158         if (AutoLoadFail) {
2159                 padapter->pwrctrlpriv.bHWPowerdown = false;
2160                 padapter->pwrctrlpriv.bSupportRemoteWakeup = false;
2161         } else {
2162                 /* hw power down mode selection , 0:rf-off / 1:power down */
2163
2164                 if (padapter->registrypriv.hwpdn_mode == 2)
2165                         padapter->pwrctrlpriv.bHWPowerdown = (hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & BIT4);
2166                 else
2167                         padapter->pwrctrlpriv.bHWPowerdown = padapter->registrypriv.hwpdn_mode;
2168
2169                 /*  decide hw if support remote wakeup function */
2170                 /*  if hw supported, 8051 (SIE) will generate WeakUP signal(D+/D- toggle) when autoresume */
2171                 padapter->pwrctrlpriv.bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT1) ? true : false;
2172
2173                 DBG_88E("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) , bSupportRemoteWakeup(%x)\n", __func__,
2174                 padapter->pwrctrlpriv.bHWPwrPindetect, padapter->pwrctrlpriv.bHWPowerdown , padapter->pwrctrlpriv.bSupportRemoteWakeup);
2175
2176                 DBG_88E("### PS params =>  power_mgnt(%x), usbss_enable(%x) ###\n", padapter->registrypriv.power_mgnt, padapter->registrypriv.usbss_enable);
2177         }
2178 }
2179
2180 void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail)
2181 {
2182         struct hal_data_8188e   *pHalData = GET_HAL_DATA(padapter);
2183         struct txpowerinfo24g pwrInfo24G;
2184         u8 rfPath, ch, group;
2185         u8 bIn24G, TxCount;
2186
2187         Hal_ReadPowerValueFromPROM_8188E(&pwrInfo24G, PROMContent, AutoLoadFail);
2188
2189         if (!AutoLoadFail)
2190                 pHalData->bTXPowerDataReadFromEEPORM = true;
2191
2192         for (rfPath = 0; rfPath < pHalData->NumTotalRFPath; rfPath++) {
2193                 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
2194                         bIn24G = Hal_GetChnlGroup88E(ch, &group);
2195                         if (bIn24G) {
2196                                 pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group];
2197                                 if (ch == 14)
2198                                         pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][4];
2199                                 else
2200                                         pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
2201                         }
2202                         if (bIn24G) {
2203                                 DBG_88E("======= Path %d, Channel %d =======\n", rfPath, ch);
2204                                 DBG_88E("Index24G_CCK_Base[%d][%d] = 0x%x\n", rfPath, ch , pHalData->Index24G_CCK_Base[rfPath][ch]);
2205                                 DBG_88E("Index24G_BW40_Base[%d][%d] = 0x%x\n", rfPath, ch , pHalData->Index24G_BW40_Base[rfPath][ch]);
2206                         }
2207                 }
2208                 for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
2209                         pHalData->CCK_24G_Diff[rfPath][TxCount] = pwrInfo24G.CCK_Diff[rfPath][TxCount];
2210                         pHalData->OFDM_24G_Diff[rfPath][TxCount] = pwrInfo24G.OFDM_Diff[rfPath][TxCount];
2211                         pHalData->BW20_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW20_Diff[rfPath][TxCount];
2212                         pHalData->BW40_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW40_Diff[rfPath][TxCount];
2213                         DBG_88E("======= TxCount %d =======\n", TxCount);
2214                         DBG_88E("CCK_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->CCK_24G_Diff[rfPath][TxCount]);
2215                         DBG_88E("OFDM_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->OFDM_24G_Diff[rfPath][TxCount]);
2216                         DBG_88E("BW20_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->BW20_24G_Diff[rfPath][TxCount]);
2217                         DBG_88E("BW40_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->BW40_24G_Diff[rfPath][TxCount]);
2218                 }
2219         }
2220
2221         /*  2010/10/19 MH Add Regulator recognize for CU. */
2222         if (!AutoLoadFail) {
2223                 pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E]&0x7);     /* bit0~2 */
2224                 if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2225                         pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION&0x7); /* bit0~2 */
2226         } else {
2227                 pHalData->EEPROMRegulatory = 0;
2228         }
2229         DBG_88E("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory);
2230 }
2231
2232 void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
2233 {
2234         struct hal_data_8188e   *pHalData = GET_HAL_DATA(pAdapter);
2235
2236         if (!AutoLoadFail) {
2237                 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_88E];
2238                 if (pHalData->CrystalCap == 0xFF)
2239                         pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
2240         } else {
2241                 pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
2242         }
2243         DBG_88E("CrystalCap: 0x%2x\n", pHalData->CrystalCap);
2244 }
2245
2246 void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
2247 {
2248         struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
2249
2250         if (!AutoLoadFail)
2251                 pHalData->BoardType = ((hwinfo[EEPROM_RF_BOARD_OPTION_88E]&0xE0)>>5);
2252         else
2253                 pHalData->BoardType = 0;
2254         DBG_88E("Board Type: 0x%2x\n", pHalData->BoardType);
2255 }
2256
2257 void Hal_EfuseParseEEPROMVer88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
2258 {
2259         struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
2260
2261         if (!AutoLoadFail) {
2262                 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_88E];
2263                 if (pHalData->EEPROMVersion == 0xFF)
2264                         pHalData->EEPROMVersion = EEPROM_Default_Version;
2265         } else {
2266                 pHalData->EEPROMVersion = 1;
2267         }
2268         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2269                  ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
2270                  pHalData->EEPROMVersion));
2271 }
2272
2273 void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
2274 {
2275         padapter->mlmepriv.ChannelPlan =
2276                  hal_com_get_channel_plan(padapter,
2277                                           hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF,
2278                                           padapter->registrypriv.channel_plan,
2279                                           RT_CHANNEL_DOMAIN_WORLD_WIDE_13, AutoLoadFail);
2280
2281         DBG_88E("mlmepriv.ChannelPlan = 0x%02x\n", padapter->mlmepriv.ChannelPlan);
2282 }
2283
2284 void Hal_EfuseParseCustomerID88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
2285 {
2286         struct hal_data_8188e   *pHalData = GET_HAL_DATA(padapter);
2287
2288         if (!AutoLoadFail) {
2289                 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CUSTOMERID_88E];
2290         } else {
2291                 pHalData->EEPROMCustomerID = 0;
2292                 pHalData->EEPROMSubCustomerID = 0;
2293         }
2294         DBG_88E("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID);
2295 }
2296
2297 void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail)
2298 {
2299         struct hal_data_8188e   *pHalData = GET_HAL_DATA(pAdapter);
2300         struct registry_priv    *registry_par = &pAdapter->registrypriv;
2301
2302         if (!AutoLoadFail) {
2303                 /*  Antenna Diversity setting. */
2304                 if (registry_par->antdiv_cfg == 2) { /*  2:By EFUSE */
2305                         pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E]&0x18)>>3;
2306                         if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2307                                 pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION&0x18)>>3;
2308                 } else {
2309                         pHalData->AntDivCfg = registry_par->antdiv_cfg;  /*  0:OFF , 1:ON, 2:By EFUSE */
2310                 }
2311
2312                 if (registry_par->antdiv_type == 0) {
2313                         /* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */
2314                         pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E];
2315                         if (pHalData->TRxAntDivType == 0xFF)
2316                                 pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; /*  For 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */
2317                 } else {
2318                         pHalData->TRxAntDivType = registry_par->antdiv_type;
2319                 }
2320
2321                 if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV)
2322                         pHalData->AntDivCfg = 1; /*  0xC1[3] is ignored. */
2323         } else {
2324                 pHalData->AntDivCfg = 0;
2325                 pHalData->TRxAntDivType = pHalData->TRxAntDivType; /*  The value in the driver setting of device manager. */
2326         }
2327         DBG_88E("EEPROM : AntDivCfg = %x, TRxAntDivType = %x\n", pHalData->AntDivCfg, pHalData->TRxAntDivType);
2328 }
2329
2330 void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail)
2331 {
2332         struct hal_data_8188e   *pHalData = GET_HAL_DATA(Adapter);
2333
2334         /*  ThermalMeter from EEPROM */
2335         if (!AutoloadFail)
2336                 pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_88E];
2337         else
2338                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
2339
2340         if (pHalData->EEPROMThermalMeter == 0xff || AutoloadFail) {
2341                 pHalData->bAPKThermalMeterIgnore = true;
2342                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
2343         }
2344         DBG_88E("ThermalMeter = 0x%x\n", pHalData->EEPROMThermalMeter);
2345 }
2346
2347 void Hal_InitChannelPlan(struct adapter *padapter)
2348 {
2349 }
2350
2351 bool HalDetectPwrDownMode88E(struct adapter *Adapter)
2352 {
2353         u8 tmpvalue = 0;
2354         struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
2355         struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
2356
2357         EFUSE_ShadowRead(Adapter, 1, EEPROM_RF_FEATURE_OPTION_88E, (u32 *)&tmpvalue);
2358
2359         /*  2010/08/25 MH INF priority > PDN Efuse value. */
2360         if (tmpvalue & BIT(4) && pwrctrlpriv->reg_pdnmode)
2361                 pHalData->pwrdown = true;
2362         else
2363                 pHalData->pwrdown = false;
2364
2365         DBG_88E("HalDetectPwrDownMode(): PDN =%d\n", pHalData->pwrdown);
2366
2367         return pHalData->pwrdown;
2368 }       /*  HalDetectPwrDownMode */
2369
2370 /*  This function is used only for 92C to set REG_BCN_CTRL(0x550) register. */
2371 /*  We just reserve the value of the register in variable pHalData->RegBcnCtrlVal and then operate */
2372 /*  the value of the register via atomic operation. */
2373 /*  This prevents from race condition when setting this register. */
2374 /*  The value of pHalData->RegBcnCtrlVal is initialized in HwConfigureRTL8192CE() function. */
2375
2376 void SetBcnCtrlReg(struct adapter *padapter, u8 SetBits, u8 ClearBits)
2377 {
2378         struct hal_data_8188e *pHalData;
2379
2380         pHalData = GET_HAL_DATA(padapter);
2381
2382         pHalData->RegBcnCtrlVal |= SetBits;
2383         pHalData->RegBcnCtrlVal &= ~ClearBits;
2384
2385         rtw_write8(padapter, REG_BCN_CTRL, (u8)pHalData->RegBcnCtrlVal);
2386 }