net: wireless: rockchip_wlan: add rtl8188eu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / hal / rtl8188e / 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 <drv_types.h>
23 #include <rtl8188e_hal.h>
24
25
26 #if defined(CONFIG_IOL)
27 static void iol_mode_enable(PADAPTER padapter, u8 enable)
28 {
29         u8 reg_0xf0 = 0;
30         
31         if(enable)
32         {
33                 //Enable initial offload
34                 reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
35                 //DBG_871X("%s reg_0xf0:0x%02x, write 0x%02x\n", __FUNCTION__, reg_0xf0, reg_0xf0|SW_OFFLOAD_EN);
36                 rtw_write8(padapter, REG_SYS_CFG, reg_0xf0|SW_OFFLOAD_EN);
37                 
38                 if(padapter->bFWReady == _FALSE)
39                 {
40                         printk("bFWReady == _FALSE call reset 8051...\n");
41                         _8051Reset88E(padapter);
42                 }               
43                         
44         }
45         else
46         {
47                 //disable initial offload
48                 reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
49                 //DBG_871X("%s reg_0xf0:0x%02x, write 0x%02x\n", __FUNCTION__, reg_0xf0, reg_0xf0& ~SW_OFFLOAD_EN);
50                 rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
51         }
52 }
53
54 static s32 iol_execute(PADAPTER padapter, u8 control)
55 {
56         s32 status = _FAIL;
57         u8 reg_0x88 = 0,reg_1c7=0;
58         u32 start = 0, passing_time = 0;
59         
60         u32 t1,t2;
61         control = control&0x0f;
62         reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
63         //DBG_871X("%s reg_0x88:0x%02x, write 0x%02x\n", __FUNCTION__, reg_0x88, reg_0x88|control);
64         rtw_write8(padapter, REG_HMEBOX_E0,  reg_0x88|control);
65
66         t1 = start = rtw_get_current_time();
67         while(
68                 //(reg_1c7 = rtw_read8(padapter, 0x1c7) >1) &&
69                 (reg_0x88=rtw_read8(padapter, REG_HMEBOX_E0)) & control
70                 && (passing_time=rtw_get_passing_time_ms(start))<1000
71         ) {
72                 //DBG_871X("%s polling reg_0x88:0x%02x,reg_0x1c7:0x%02x\n", __FUNCTION__, reg_0x88,rtw_read8(padapter, 0x1c7) );
73                 //rtw_udelay_os(100);
74         }
75
76         reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
77         status = (reg_0x88 & control)?_FAIL:_SUCCESS;
78         if(reg_0x88 & control<<4)
79                 status = _FAIL;
80         t2= rtw_get_current_time();
81         //printk("==> step iol_execute :  %5u reg-0x1c0= 0x%02x\n",rtw_get_time_interval_ms(t1,t2),rtw_read8(padapter, 0x1c0));
82         //DBG_871X("%s in %u ms, reg_0x88:0x%02x\n", __FUNCTION__, passing_time, reg_0x88);
83         
84         return status;
85 }
86
87 static s32 iol_InitLLTTable(
88         PADAPTER padapter,
89         u8 txpktbuf_bndy
90         )
91 {
92         s32 rst = _SUCCESS; 
93         iol_mode_enable(padapter, 1);
94         //DBG_871X("%s txpktbuf_bndy:%u\n", __FUNCTION__, txpktbuf_bndy);
95         rtw_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
96         rst = iol_execute(padapter, CMD_INIT_LLT);
97         iol_mode_enable(padapter, 0);
98         return rst;
99 }
100
101 static VOID
102 efuse_phymap_to_logical(u8 * phymap, u16 _offset, u16 _size_byte, u8  *pbuf)
103 {
104         u8      *efuseTbl = NULL;
105         u8      rtemp8;
106         u16     eFuse_Addr = 0;
107         u8      offset, wren;
108         u16     i, j;
109         u16     **eFuseWord = NULL;
110         u16     efuse_utilized = 0;
111         u8      efuse_usage = 0;
112         u8      u1temp = 0;
113
114
115         efuseTbl = (u8*)rtw_zmalloc(EFUSE_MAP_LEN_88E);
116         if(efuseTbl == NULL)
117         {
118                 DBG_871X("%s: alloc efuseTbl fail!\n", __FUNCTION__);
119                 goto exit;
120         }
121
122         eFuseWord= (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, 2);
123         if(eFuseWord == NULL)
124         {
125                 DBG_871X("%s: alloc eFuseWord fail!\n", __FUNCTION__);
126                 goto exit;
127         }
128
129         // 0. Refresh efuse init map as all oxFF.
130         for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
131                 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
132                         eFuseWord[i][j] = 0xFFFF;
133
134         //
135         // 1. Read the first byte to check if efuse is empty!!!
136         // 
137         //
138         rtemp8 = *(phymap+eFuse_Addr);
139         if(rtemp8 != 0xFF)
140         {
141                 efuse_utilized++;
142                 //printk("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8);
143                 eFuse_Addr++;
144         }
145         else
146         {
147                 DBG_871X("EFUSE is empty efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, rtemp8);
148                 goto exit;
149         }
150
151
152         //
153         // 2. Read real efuse content. Filter PG header and every section data.
154         //
155         while((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
156         {
157                 //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr-1, *rtemp8));
158         
159                 // Check PG header for section num.
160                 if((rtemp8 & 0x1F ) == 0x0F)            //extended header
161                 {                       
162                         u1temp =( (rtemp8 & 0xE0) >> 5);
163                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x *rtemp&0xE0 0x%x\n", u1temp, *rtemp8 & 0xE0));
164
165                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x \n", u1temp));
166
167                         rtemp8 = *(phymap+eFuse_Addr);
168
169                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8));     
170                         
171                         if((rtemp8 & 0x0F) == 0x0F)
172                         {
173                                 eFuse_Addr++;                   
174                                 rtemp8 = *(phymap+eFuse_Addr);
175                                 
176                                 if(rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
177                                 {
178                                         eFuse_Addr++;                           
179                                 }                               
180                                 continue;
181                         }
182                         else
183                         {
184                                 offset = ((rtemp8 & 0xF0) >> 1) | u1temp;
185                                 wren = (rtemp8 & 0x0F);
186                                 eFuse_Addr++;                           
187                         }
188                 }
189                 else
190                 {
191                         offset = ((rtemp8 >> 4) & 0x0f);
192                         wren = (rtemp8 & 0x0f);                 
193                 }
194                 
195                 if(offset < EFUSE_MAX_SECTION_88E)
196                 {
197                         // Get word enable value from PG header
198                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Offset-%d Worden=%x\n", offset, wren));
199
200                         for(i=0; i<EFUSE_MAX_WORD_UNIT; i++)
201                         {
202                                 // Check word enable condition in the section                           
203                                 if(!(wren & 0x01))
204                                 {
205                                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d \n", eFuse_Addr));
206                                         rtemp8 = *(phymap+eFuse_Addr);
207                                         eFuse_Addr++;
208                                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8));                           
209                                         efuse_utilized++;
210                                         eFuseWord[offset][i] = (rtemp8 & 0xff);
211                                         
212
213                                         if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) 
214                                                 break;
215
216                                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d", eFuse_Addr));
217                                         rtemp8 = *(phymap+eFuse_Addr);
218                                         eFuse_Addr++;
219                                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8));                           
220                                         
221                                         efuse_utilized++;
222                                         eFuseWord[offset][i] |= (((u2Byte)rtemp8 << 8) & 0xff00);
223
224                                         if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) 
225                                                 break;
226                                 }
227                                 
228                                 wren >>= 1;
229                                 
230                         }
231                 }
232
233                 // Read next PG header
234                 rtemp8 = *(phymap+eFuse_Addr);
235                 //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d rtemp 0x%x\n", eFuse_Addr, *rtemp8));
236                 
237                 if(rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
238                 {
239                         efuse_utilized++;
240                         eFuse_Addr++;
241                 }
242         }
243
244         //
245         // 3. Collect 16 sections and 4 word unit into Efuse map.
246         //
247         for(i=0; i<EFUSE_MAX_SECTION_88E; i++)
248         {
249                 for(j=0; j<EFUSE_MAX_WORD_UNIT; j++)
250                 {
251                         efuseTbl[(i*8)+(j*2)]=(eFuseWord[i][j] & 0xff);
252                         efuseTbl[(i*8)+((j*2)+1)]=((eFuseWord[i][j] >> 8) & 0xff);
253                 }
254         }
255
256
257         //
258         // 4. Copy from Efuse map to output pointer memory!!!
259         //
260         for(i=0; i<_size_byte; i++)
261         {               
262                 pbuf[i] = efuseTbl[_offset+i];
263         }
264
265         //
266         // 5. Calculate Efuse utilization.
267         //
268         efuse_usage = (u1Byte)((efuse_utilized*100)/EFUSE_REAL_CONTENT_LEN_88E);
269         //rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_utilized);
270
271 exit:
272         if(efuseTbl)
273                 rtw_mfree(efuseTbl, EFUSE_MAP_LEN_88E);
274
275         if(eFuseWord)
276                 rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
277 }
278
279 void efuse_read_phymap_from_txpktbuf(
280         ADAPTER *adapter,
281         int bcnhead,    //beacon head, where FW store len(2-byte) and efuse physical map.
282         u8 *content,    //buffer to store efuse physical map
283         u16 *size       //for efuse content: the max byte to read. will update to byte read
284         )
285 {
286         u16 dbg_addr = 0;
287         u32 start  = 0, passing_time = 0;
288         u8 reg_0x143 = 0;
289         u8 reg_0x106 = 0;
290         u32 lo32 = 0, hi32 = 0;
291         u16 len = 0, count = 0;
292         int i = 0;
293         u16 limit = *size;
294
295         u8 *pos = content;
296         
297         if(bcnhead<0) //if not valid
298                 bcnhead = rtw_read8(adapter, REG_TDECTRL+1);
299
300         DBG_871X("%s bcnhead:%d\n", __FUNCTION__, bcnhead);
301
302         //reg_0x106 = rtw_read8(adapter, REG_PKT_BUFF_ACCESS_CTRL);
303         //DBG_871X("%s reg_0x106:0x%02x, write 0x%02x\n", __FUNCTION__, reg_0x106, 0x69);
304         rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
305         //DBG_871X("%s reg_0x106:0x%02x\n", __FUNCTION__, rtw_read8(adapter, 0x106));
306
307         dbg_addr = bcnhead*128/8; //8-bytes addressing
308
309         while(1)
310         {
311                 //DBG_871X("%s dbg_addr:0x%x\n", __FUNCTION__, dbg_addr+i);
312                 rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr+i);
313
314                 //DBG_871X("%s write reg_0x143:0x00\n", __FUNCTION__);
315                 rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
316                 start = rtw_get_current_time();
317                 while(!(reg_0x143=rtw_read8(adapter, REG_TXPKTBUF_DBG))//dbg
318                 //while(rtw_read8(adapter, REG_TXPKTBUF_DBG) & BIT0
319                         && (passing_time=rtw_get_passing_time_ms(start))<1000
320                 ) {
321                         DBG_871X("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __FUNCTION__, reg_0x143, rtw_read8(adapter, 0x106));
322                         rtw_usleep_os(100);
323                 }
324
325
326                 lo32 = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
327                 hi32 = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
328
329                 #if 0
330                 DBG_871X("%s lo32:0x%08x, %02x %02x %02x %02x\n", __FUNCTION__, lo32
331                         , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L)
332                         , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L+1)
333                         , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L+2)
334                         , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L+3)
335                 );
336                 DBG_871X("%s hi32:0x%08x, %02x %02x %02x %02x\n", __FUNCTION__, hi32
337                         , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_H)
338                         , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_H+1)
339                         , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_H+2)
340                         , rtw_read8(adapter, REG_PKTBUF_DBG_DATA_H+3)
341                 );
342                 #endif
343
344                 if(i==0)
345                 {
346                         #if 1 //for debug
347                         u8 lenc[2];
348                         u16 lenbak, aaabak;
349                         u16 aaa;
350                         lenc[0] = rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L);
351                         lenc[1] = rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L+1);
352
353                         aaabak = le16_to_cpup((u16*)lenc);
354                         lenbak = le16_to_cpu(*((u16*)lenc));
355                         aaa = le16_to_cpup((u16*)&lo32);
356                         #endif
357                         len = le16_to_cpu(*((u16*)&lo32));
358
359                         limit = (len-2<limit)?len-2:limit;
360
361                         DBG_871X("%s len:%u, lenbak:%u, aaa:%u, aaabak:%u\n", __FUNCTION__, len, lenbak, aaa, aaabak);
362
363                         _rtw_memcpy(pos, ((u8*)&lo32)+2, (limit>=count+2)?2:limit-count);
364                         count+= (limit>=count+2)?2:limit-count;
365                         pos=content+count;
366                         
367                 }
368                 else
369                 {
370                         _rtw_memcpy(pos, ((u8*)&lo32), (limit>=count+4)?4:limit-count);
371                         count+=(limit>=count+4)?4:limit-count;
372                         pos=content+count;
373                         
374
375                 }
376
377                 if(limit>count && len-2>count) {
378                         _rtw_memcpy(pos, (u8*)&hi32, (limit>=count+4)?4:limit-count);
379                         count+=(limit>=count+4)?4:limit-count;
380                         pos=content+count;
381                 }
382
383                 if(limit<=count || len-2<=count)
384                         break;
385
386                 i++;
387         }
388
389         rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
390         
391         DBG_871X("%s read count:%u\n", __FUNCTION__, count);
392         *size = count;
393
394 }
395
396
397 static s32 iol_read_efuse(
398         PADAPTER padapter,
399         u8 txpktbuf_bndy,
400         u16 offset,
401         u16 size_byte,
402         u8 *logical_map
403         )
404 {
405         s32 status = _FAIL;
406         u8 reg_0x106 = 0;
407         u8 physical_map[512];
408         u16 size = 512;
409         int i;
410
411
412         rtw_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
413         _rtw_memset(physical_map, 0xFF, 512);
414         
415         ///reg_0x106 = rtw_read8(padapter, REG_PKT_BUFF_ACCESS_CTRL);
416         //DBG_871X("%s reg_0x106:0x%02x, write 0x%02x\n", __FUNCTION__, reg_0x106, 0x69);
417         rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
418         //DBG_871X("%s reg_0x106:0x%02x\n", __FUNCTION__, rtw_read8(padapter, 0x106));
419
420         status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
421
422         if(status == _SUCCESS)
423                 efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size);
424
425         #if 0
426         DBG_871X_LEVEL(_drv_always_, "%s physical map\n", __FUNCTION__);
427         for(i=0;i<size;i++)
428         {
429                 if (i%16==0)
430                         DBG_871X_LEVEL(_drv_always_, "%02x", physical_map[i]);
431                 else
432                         _DBG_871X_LEVEL(_drv_always_, "%02x", physical_map[i]);
433
434                 if (i%16==7)
435                         _DBG_871X_LEVEL(_drv_always_, "    ");
436                 else if (i%16==15)
437                         _DBG_871X_LEVEL(_drv_always_, "\n");
438                 else
439                         _DBG_871X_LEVEL(_drv_always_, " ");
440         }
441         _DBG_871X_LEVEL(_drv_always_, "\n");
442         #endif
443
444         efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map);
445
446         return status;
447 }
448
449 s32 rtl8188e_iol_efuse_patch(PADAPTER padapter)
450 {
451         s32     result = _SUCCESS;
452         printk("==> %s \n",__FUNCTION__);
453         
454         if(rtw_IOL_applied(padapter)){
455                 iol_mode_enable(padapter, 1);
456                 result = iol_execute(padapter, CMD_READ_EFUSE_MAP);
457                 if(result == _SUCCESS)                  
458                         result = iol_execute(padapter, CMD_EFUSE_PATCH);
459                 
460                 iol_mode_enable(padapter, 0);
461         }
462         return result;
463 }
464
465 static s32 iol_ioconfig(
466         PADAPTER padapter,
467         u8 iocfg_bndy
468         )
469 {
470         s32 rst = _SUCCESS; 
471         
472         //DBG_871X("%s iocfg_bndy:%u\n", __FUNCTION__, iocfg_bndy);
473         rtw_write8(padapter, REG_TDECTRL+1, iocfg_bndy);
474         rst = iol_execute(padapter, CMD_IOCONFIG);
475         
476         return rst;
477 }
478
479 int rtl8188e_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms,u32 bndy_cnt)
480 {
481         
482         u32 start_time = rtw_get_current_time();
483         u32 passing_time_ms;
484         u8 polling_ret,i;
485         int ret = _FAIL;
486         u32 t1,t2;
487         
488         //printk("===> %s ,bndy_cnt = %d \n",__FUNCTION__,bndy_cnt);
489         if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
490                 goto exit;
491 #ifdef CONFIG_USB_HCI
492         {
493                 struct pkt_attrib       *pattrib = &xmit_frame->attrib;         
494                 if(rtw_usb_bulk_size_boundary(adapter,TXDESC_SIZE+pattrib->last_txcmdsz))
495                 {
496                         if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
497                                 goto exit;
498                 }                       
499         }
500 #endif //CONFIG_USB_HCI
501         
502         //rtw_IOL_cmd_buf_dump(adapter,xmit_frame->attrib.pktlen+TXDESC_OFFSET,xmit_frame->buf_addr);
503         //rtw_hal_mgnt_xmit(adapter, xmit_frame);
504         //rtw_dump_xframe_sync(adapter, xmit_frame);
505         
506         dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms);
507         
508         t1=     rtw_get_current_time();
509         iol_mode_enable(adapter, 1);
510         for(i=0;i<bndy_cnt;i++){
511                 u8 page_no = 0;
512                 page_no = i*2 ;
513                 //printk(" i = %d, page_no = %d \n",i,page_no); 
514                 if( (ret = iol_ioconfig(adapter, page_no)) != _SUCCESS)
515                 {
516                         break;
517                 }
518         }
519         iol_mode_enable(adapter, 0);
520         t2 = rtw_get_current_time();
521         //printk("==> %s :  %5u\n",__FUNCTION__,rtw_get_time_interval_ms(t1,t2));
522 exit:
523         //restore BCN_HEAD
524         rtw_write8(adapter, REG_TDECTRL+1, 0);  
525         return ret;
526 }
527
528 void rtw_IOL_cmd_tx_pkt_buf_dump(ADAPTER *Adapter,int data_len)
529 {
530         u32 fifo_data,reg_140;
531         u32 addr,rstatus,loop=0;
532
533         u16 data_cnts = (data_len/8)+1;                         
534         u8 *pbuf =rtw_zvmalloc(data_len+10);
535         printk("###### %s ######\n",__FUNCTION__);
536         
537         rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
538         if(pbuf){
539                 for(addr=0;addr< data_cnts;addr++){
540                         //printk("==> addr:0x%02x\n",addr);
541                         rtw_write32(Adapter,0x140,addr);
542                         rtw_usleep_os(2);
543                         loop=0;
544                         do{
545                                 rstatus=(reg_140=rtw_read32(Adapter,REG_PKTBUF_DBG_CTRL)&BIT24);        
546                                 //printk("rstatus = %02x, reg_140:0x%08x\n",rstatus,reg_140);
547                                 if(rstatus){
548                                         fifo_data = rtw_read32(Adapter,REG_PKTBUF_DBG_DATA_L);
549                                         //printk("fifo_data_144:0x%08x\n",fifo_data);                                   
550                                         _rtw_memcpy(pbuf+(addr*8),&fifo_data , 4);  
551                                         
552                                         fifo_data = rtw_read32(Adapter,REG_PKTBUF_DBG_DATA_H);
553                                         //printk("fifo_data_148:0x%08x\n",fifo_data);                                   
554                                         _rtw_memcpy(pbuf+(addr*8+4), &fifo_data, 4); 
555                                         
556                                 }
557                                 rtw_usleep_os(2);
558                         }while( !rstatus && (loop++ <10));
559                 }
560                 rtw_IOL_cmd_buf_dump(Adapter,data_len,pbuf);
561                 rtw_vmfree(pbuf, data_len+10);  
562                 
563         }                                       
564         printk("###### %s ######\n",__FUNCTION__);
565 }
566
567 #endif /* defined(CONFIG_IOL) */
568
569
570 static VOID
571 _FWDownloadEnable_8188E(
572         IN      PADAPTER                padapter,
573         IN      BOOLEAN                 enable
574         )
575 {
576         u8      tmp;
577
578         if(enable)
579         {
580                 // MCU firmware download enable.
581                 tmp = rtw_read8(padapter, REG_MCUFWDL);
582                 rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
583
584                 // 8051 reset
585                 tmp = rtw_read8(padapter, REG_MCUFWDL+2);
586                 rtw_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
587         }
588         else
589         {               
590                 
591                 // MCU firmware download disable.
592                 tmp = rtw_read8(padapter, REG_MCUFWDL);
593                 rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
594
595                 // Reserved for fw extension.
596                 rtw_write8(padapter, REG_MCUFWDL+1, 0x00);
597         }
598 }
599 #define MAX_REG_BOLCK_SIZE      196 
600 static int
601 _BlockWrite(
602         IN              PADAPTER                padapter,
603         IN              PVOID           buffer,
604         IN              u32                     buffSize
605         )
606 {
607         int ret = _SUCCESS;
608
609         u32                     blockSize_p1 = 4;       // (Default) Phase #1 : PCI muse use 4-byte write to download FW
610         u32                     blockSize_p2 = 8;       // Phase #2 : Use 8-byte, if Phase#1 use big size to write FW.
611         u32                     blockSize_p3 = 1;       // Phase #3 : Use 1-byte, the remnant of FW image.
612         u32                     blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
613         u32                     remainSize_p1 = 0, remainSize_p2 = 0;
614         u8                      *bufferPtr      = (u8*)buffer;
615         u32                     i=0, offset=0;
616 #ifdef CONFIG_PCI_HCI
617         u8                      remainFW[4] = {0, 0, 0, 0};
618         u8                      *p = NULL;
619 #endif
620
621 #ifdef CONFIG_USB_HCI
622         blockSize_p1 = MAX_REG_BOLCK_SIZE;
623 #endif
624
625         //3 Phase #1
626         blockCount_p1 = buffSize / blockSize_p1;
627         remainSize_p1 = buffSize % blockSize_p1;
628
629         if (blockCount_p1) {
630                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
631                                 ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) blockCount_p1(%d) remainSize_p1(%d)\n",
632                                 buffSize, blockSize_p1, blockCount_p1, remainSize_p1));
633         }
634
635         for (i = 0; i < blockCount_p1; i++)
636         {
637 #ifdef CONFIG_USB_HCI
638                 ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
639 #else
640                 ret = rtw_write32(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32*)(bufferPtr + i * blockSize_p1))));
641 #endif
642
643                 if(ret == _FAIL)
644                         goto exit;
645         }
646
647 #ifdef CONFIG_PCI_HCI
648         p = (u8*)((u32*)(bufferPtr + blockCount_p1 * blockSize_p1));
649         if (remainSize_p1) {
650                 switch (remainSize_p1) {
651                 case 0:
652                         break;
653                 case 3:
654                         remainFW[2]=*(p+2);
655                 case 2:         
656                         remainFW[1]=*(p+1);
657                 case 1:         
658                         remainFW[0]=*(p);
659                         ret = rtw_write32(padapter, (FW_8188E_START_ADDRESS + blockCount_p1 * blockSize_p1), 
660                                  le32_to_cpu(*(u32*)remainFW)); 
661                 }
662                 return ret;
663         }
664 #endif
665
666         //3 Phase #2
667         if (remainSize_p1)
668         {
669                 offset = blockCount_p1 * blockSize_p1;
670
671                 blockCount_p2 = remainSize_p1/blockSize_p2;
672                 remainSize_p2 = remainSize_p1%blockSize_p2;
673
674                 if (blockCount_p2) {
675                                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
676                                                 ("_BlockWrite: [P2] buffSize_p2(%d) blockSize_p2(%d) blockCount_p2(%d) remainSize_p2(%d)\n",
677                                                 (buffSize-offset), blockSize_p2 ,blockCount_p2, remainSize_p2));
678                 }
679
680 #ifdef CONFIG_USB_HCI
681                 for (i = 0; i < blockCount_p2; i++) {
682                         ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
683                         
684                         if(ret == _FAIL)
685                                 goto exit;
686                 }
687 #endif
688         }
689
690         //3 Phase #3
691         if (remainSize_p2)
692         {
693                 offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
694
695                 blockCount_p3 = remainSize_p2 / blockSize_p3;
696
697                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
698                                 ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) blockCount_p3(%d)\n",
699                                 (buffSize-offset), blockSize_p3, blockCount_p3));
700
701                 for(i = 0 ; i < blockCount_p3 ; i++){
702                         ret =rtw_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
703                         
704                         if(ret == _FAIL)
705                                 goto exit;
706                 }
707         }
708
709 exit:
710         return ret;
711 }
712
713 static int
714 _PageWrite(
715         IN              PADAPTER        padapter,
716         IN              u32                     page,
717         IN              PVOID           buffer,
718         IN              u32                     size
719         )
720 {
721         u8 value8;
722         u8 u8Page = (u8) (page & 0x07) ;
723
724         value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page ;
725         rtw_write8(padapter, REG_MCUFWDL+2,value8);
726
727         return _BlockWrite(padapter,buffer,size);
728 }
729
730 static VOID
731 _FillDummy(
732         u8*             pFwBuf,
733         u32*    pFwLen
734         )
735 {
736         u32     FwLen = *pFwLen;
737         u8      remain = (u8)(FwLen%4);
738         remain = (remain==0)?0:(4-remain);
739
740         while(remain>0)
741         {
742                 pFwBuf[FwLen] = 0;
743                 FwLen++;
744                 remain--;
745         }
746
747         *pFwLen = FwLen;
748 }
749
750 static int
751 _WriteFW(
752         IN              PADAPTER                padapter,
753         IN              PVOID                   buffer,
754         IN              u32                     size
755         )
756 {
757         // Since we need dynamic decide method of dwonload fw, so we call this function to get chip version.
758         int ret = _SUCCESS;
759         u32     pageNums,remainSize ;
760         u32     page, offset;
761         u8              *bufferPtr = (u8*)buffer;
762
763 #ifdef CONFIG_PCI_HCI
764         // 20100120 Joseph: Add for 88CE normal chip.
765         // Fill in zero to make firmware image to dword alignment.
766 //              _FillDummy(bufferPtr, &size);
767 #endif
768
769         pageNums = size / MAX_DLFW_PAGE_SIZE ;
770         //RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4 \n"));
771         remainSize = size % MAX_DLFW_PAGE_SIZE;
772
773         for (page = 0; page < pageNums; page++) {
774                 offset = page * MAX_DLFW_PAGE_SIZE;
775                 ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_DLFW_PAGE_SIZE);
776                 
777                 if(ret == _FAIL)
778                         goto exit;
779         }
780         if (remainSize) {
781                 offset = pageNums * MAX_DLFW_PAGE_SIZE;
782                 page = pageNums;
783                 ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize);
784                 
785                 if(ret == _FAIL)
786                         goto exit;
787
788         }
789         RT_TRACE(_module_hal_init_c_, _drv_info_, ("_WriteFW Done- for Normal chip.\n"));
790
791 exit:
792         return ret;
793 }
794
795 void _MCUIO_Reset88E(PADAPTER padapter,u8 bReset)
796 {
797         u8 u1bTmp;
798
799         if(bReset==_TRUE){
800                 u1bTmp = rtw_read8(padapter, REG_RSV_CTRL);
801                 rtw_write8(padapter,REG_RSV_CTRL, (u1bTmp&(~BIT1)));
802                 // Reset MCU IO Wrapper- sugggest by SD1-Gimmy
803                 u1bTmp = rtw_read8(padapter, REG_RSV_CTRL+1);
804                 rtw_write8(padapter,REG_RSV_CTRL+1, (u1bTmp&(~BIT3)));
805         }else{
806                 u1bTmp = rtw_read8(padapter, REG_RSV_CTRL);
807                 rtw_write8(padapter,REG_RSV_CTRL, (u1bTmp&(~BIT1)));
808                 // Enable MCU IO Wrapper
809                 u1bTmp = rtw_read8(padapter, REG_RSV_CTRL+1);
810                 rtw_write8(padapter, REG_RSV_CTRL+1, u1bTmp|BIT3);
811         }
812
813 }
814
815 void _8051Reset88E(PADAPTER padapter)
816 {
817         u8 u1bTmp;
818         
819         _MCUIO_Reset88E(padapter,_TRUE);
820         u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
821         rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
822         _MCUIO_Reset88E(padapter,_FALSE);
823         rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp|(BIT2));
824         
825         DBG_871X("=====> _8051Reset88E(): 8051 reset success .\n");
826 }
827
828 static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
829 {
830         s32 ret = _FAIL;
831         u32 value32;
832         u32 start = rtw_get_current_time();
833         u32 cnt = 0;
834
835         /* polling CheckSum report */
836         do {
837                 cnt++;
838                 value32 = rtw_read32(adapter, REG_MCUFWDL);
839                 if (value32 & FWDL_ChkSum_rpt || RTW_CANNOT_IO(adapter))
840                         break;
841                 rtw_yield_os();
842         } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
843
844         if (!(value32 & FWDL_ChkSum_rpt)) {
845                 goto exit;
846         }
847
848         if (rtw_fwdl_test_trigger_chksum_fail())
849                 goto exit;
850
851         ret = _SUCCESS;
852
853 exit:
854         DBG_871X("%s: Checksum report %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
855         , (ret==_SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), value32);
856
857         return ret;
858 }
859
860 static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
861 {
862         s32 ret = _FAIL;
863         u32     value32;
864         u32 start = rtw_get_current_time();
865         u32 cnt = 0;
866
867         value32 = rtw_read32(adapter, REG_MCUFWDL);
868         value32 |= MCUFWDL_RDY;
869         value32 &= ~WINTINI_RDY;
870         rtw_write32(adapter, REG_MCUFWDL, value32);
871
872         _8051Reset88E(adapter);
873
874         /*  polling for FW ready */
875         do {
876                 cnt++;
877                 value32 = rtw_read32(adapter, REG_MCUFWDL);
878                 if (value32 & WINTINI_RDY || RTW_CANNOT_IO(adapter))
879                         break;
880                 rtw_yield_os();
881         } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
882
883         if (!(value32 & WINTINI_RDY)) {
884                 goto exit;
885         }
886
887         if (rtw_fwdl_test_trigger_wintint_rdy_fail())
888                 goto exit;
889
890         ret = _SUCCESS;
891
892 exit:
893         DBG_871X("%s: Polling FW ready %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
894                 , (ret==_SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), value32);
895         return ret;
896 }
897
898 #define IS_FW_81xxC(padapter)   (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
899
900
901 #ifdef CONFIG_FILE_FWIMG
902 extern char *rtw_fw_file_path;
903 extern char *rtw_fw_wow_file_path;
904 u8      FwBuffer8188E[FW_8188E_SIZE];
905 #endif //CONFIG_FILE_FWIMG
906
907 //
908 //      Description:
909 //              Download 8192C firmware code.
910 //
911 //
912 s32 rtl8188e_FirmwareDownload(PADAPTER padapter, BOOLEAN  bUsedWoWLANFw)
913 {
914         s32     rtStatus = _SUCCESS;
915         u8 write_fw = 0;
916         u32 fwdl_start_time;
917         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);      
918
919         PRT_FIRMWARE_8188E      pFirmware = NULL;
920         PRT_8188E_FIRMWARE_HDR          pFwHdr = NULL;
921         
922         u8                      *pFirmwareBuf;
923         u32                     FirmwareLen,tmp_fw_len=0;
924 #ifdef CONFIG_FILE_FWIMG
925         u8 *fwfilepath;
926 #endif // CONFIG_FILE_FWIMG
927
928 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
929         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
930 #endif
931
932         RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __FUNCTION__));
933         pFirmware = (PRT_FIRMWARE_8188E)rtw_zmalloc(sizeof(RT_FIRMWARE_8188E));
934         if(!pFirmware)
935         {
936                 rtStatus = _FAIL;
937                 goto exit;
938         }
939
940
941 //      RT_TRACE(_module_hal_init_c_, _drv_err_, ("%s: %s\n",__FUNCTION__, pFwImageFileName));
942
943 #ifdef CONFIG_FILE_FWIMG
944 #ifdef CONFIG_WOWLAN
945                 if (bUsedWoWLANFw)
946                 {
947                         fwfilepath = rtw_fw_wow_file_path;
948                 }
949                 else
950 #endif // CONFIG_WOWLAN
951                 {
952                         fwfilepath = rtw_fw_file_path;
953                 }
954 #endif // CONFIG_FILE_FWIMG
955
956 #ifdef CONFIG_FILE_FWIMG
957         if(rtw_is_file_readable(fwfilepath) == _TRUE)
958         {
959                 DBG_871X("%s accquire FW from file:%s\n", __FUNCTION__, fwfilepath);
960                 pFirmware->eFWSource = FW_SOURCE_IMG_FILE;
961         }
962         else
963 #endif //CONFIG_FILE_FWIMG
964         {
965                 pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
966         }
967
968         switch(pFirmware->eFWSource)
969         {
970                 case FW_SOURCE_IMG_FILE:
971                         #ifdef CONFIG_FILE_FWIMG
972                         rtStatus = rtw_retrieve_from_file(fwfilepath, FwBuffer8188E, FW_8188E_SIZE);
973                         pFirmware->ulFwLength = rtStatus>=0?rtStatus:0;
974                         pFirmware->szFwBuffer = FwBuffer8188E;
975                         #endif //CONFIG_FILE_FWIMG
976                         break;
977                 case FW_SOURCE_HEADER_FILE:
978 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
979                         if(bUsedWoWLANFw) {
980                                 #ifdef CONFIG_SFW_SUPPORTED
981                                 if (IS_VENDOR_8188E_I_CUT_SERIES(padapter)) {
982                                         ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, CONFIG_FW_WoWLAN_2, 
983                                                 (u8 *)&(pFirmware->szFwBuffer), &(pFirmware->ulFwLength));
984                                 } else  
985                                 #endif  
986                                 {       
987                                     if (!pwrpriv->wowlan_ap_mode) {
988                                                 ODM_ConfigFWWithHeaderFile(
989                                                             &pHalData->odmpriv,
990                                                             CONFIG_FW_WoWLAN,
991                                                             (u8 *)&(pFirmware->szFwBuffer),
992                                                             &(pFirmware->ulFwLength));
993                                         DBG_871X("%s fw:%s, size: %d\n", __func__,
994                                                         "WoWLAN", pFirmware->ulFwLength);
995                                     } else {
996                                             ODM_ConfigFWWithHeaderFile(
997                                                             &pHalData->odmpriv,
998                                                             CONFIG_FW_AP,
999                                                             (u8 *)&(pFirmware->szFwBuffer),
1000                                                             &(pFirmware->ulFwLength));
1001                                         DBG_871X("%s fw: %s, size: %d\n", __func__,
1002                                                         "AP_WoWLAN", pFirmware->ulFwLength);
1003                                     }
1004                                 }
1005
1006                         }else
1007 #endif //CONFIG_WOWLAN
1008                         {
1009                                 #ifdef CONFIG_SFW_SUPPORTED
1010                                 if(IS_VENDOR_8188E_I_CUT_SERIES(padapter))
1011                                         ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, CONFIG_FW_NIC_2, 
1012                                         (u8 *)&(pFirmware->szFwBuffer), &(pFirmware->ulFwLength));
1013                                 else                            
1014                                 #endif  
1015                                         ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, CONFIG_FW_NIC, 
1016                                         (u8 *)&(pFirmware->szFwBuffer), &(pFirmware->ulFwLength));
1017                                 DBG_871X("%s fw:%s, size: %d\n", __FUNCTION__, "NIC", pFirmware->ulFwLength);
1018                         }
1019                         break;
1020         }
1021
1022         tmp_fw_len = IS_VENDOR_8188E_I_CUT_SERIES(padapter)?FW_8188E_SIZE_2:FW_8188E_SIZE;
1023                 
1024         if (pFirmware->ulFwLength > tmp_fw_len) {
1025                 rtStatus = _FAIL;
1026                 DBG_871X_LEVEL(_drv_emerg_, "Firmware size:%u exceed %u\n", pFirmware->ulFwLength, tmp_fw_len);
1027                 goto exit;
1028         }
1029         
1030         pFirmwareBuf = pFirmware->szFwBuffer;
1031         FirmwareLen = pFirmware->ulFwLength;
1032
1033         // To Check Fw header. Added by tynli. 2009.12.04.
1034         pFwHdr = (PRT_8188E_FIRMWARE_HDR)pFirmwareBuf;
1035
1036         pHalData->FirmwareVersion =  le16_to_cpu(pFwHdr->Version);
1037         pHalData->FirmwareSubVersion = pFwHdr->Subversion;
1038         pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
1039
1040         DBG_871X("%s: fw_ver=%x fw_subver=%04x sig=0x%x, Month=%02x, Date=%02x, Hour=%02x, Minute=%02x\n",
1041                   __FUNCTION__, pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, pHalData->FirmwareSignature
1042                   ,pFwHdr->Month,pFwHdr->Date,pFwHdr->Hour,pFwHdr->Minute);
1043                 
1044         if (IS_FW_HEADER_EXIST_88E(pFwHdr))
1045         {
1046                 // Shift 32 bytes for FW header
1047                 pFirmwareBuf = pFirmwareBuf + 32;
1048                 FirmwareLen = FirmwareLen - 32;
1049         }
1050
1051         // Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself,
1052         // or it will cause download Fw fail. 2010.02.01. by tynli.
1053         if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) //8051 RAM code
1054         {
1055                 rtw_write8(padapter, REG_MCUFWDL, 0x00);
1056                 _8051Reset88E(padapter);                
1057         }
1058
1059         _FWDownloadEnable_8188E(padapter, _TRUE);
1060         fwdl_start_time = rtw_get_current_time();
1061         while (!RTW_CANNOT_IO(padapter)
1062                         && (write_fw++ < 3 || rtw_get_passing_time_ms(fwdl_start_time) < 500))
1063         {
1064                 /* reset FWDL chksum */
1065                 rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL)|FWDL_ChkSum_rpt);
1066                 
1067                 rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
1068                 if (rtStatus != _SUCCESS)
1069                         continue;
1070
1071                 rtStatus = polling_fwdl_chksum(padapter, 5, 50);
1072                 if (rtStatus == _SUCCESS)
1073                         break;
1074         }
1075         _FWDownloadEnable_8188E(padapter, _FALSE);
1076         if(_SUCCESS != rtStatus)
1077                 goto fwdl_stat;
1078
1079         rtStatus = _FWFreeToGo(padapter, 10, 200);
1080         if (_SUCCESS != rtStatus)
1081                 goto fwdl_stat;
1082
1083 fwdl_stat:
1084         DBG_871X("FWDL %s. write_fw:%u, %dms\n"
1085                 , (rtStatus == _SUCCESS)?"success":"fail"
1086                 , write_fw
1087                 , rtw_get_passing_time_ms(fwdl_start_time)
1088         );
1089
1090 exit:
1091         if (pFirmware)
1092                 rtw_mfree((u8*)pFirmware, sizeof(RT_FIRMWARE_8188E));
1093
1094         rtl8188e_InitializeFirmwareVars(padapter);
1095
1096         return rtStatus;
1097 }
1098
1099 void rtl8188e_InitializeFirmwareVars(PADAPTER padapter)
1100 {
1101         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1102         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1103
1104         // Init Fw LPS related.
1105         pwrpriv->bFwCurrentInPSMode = _FALSE;
1106
1107         //Init H2C cmd.
1108         rtw_write8(padapter, REG_HMETFR, 0x0f);
1109
1110         // Init H2C counter. by tynli. 2009.12.09.
1111         pHalData->LastHMEBoxNum = 0;
1112 }
1113
1114 //===========================================================
1115 //                              Efuse related code
1116 //===========================================================
1117 enum{
1118                 VOLTAGE_V25                                             = 0x03,
1119                 LDOE25_SHIFT                                            = 28 ,
1120         };
1121
1122 static BOOLEAN
1123 hal_EfusePgPacketWrite2ByteHeader(
1124         IN      PADAPTER                pAdapter,
1125         IN      u8                              efuseType,
1126         IN      u16                             *pAddr,
1127         IN      PPGPKT_STRUCT   pTargetPkt,
1128         IN      BOOLEAN                 bPseudoTest);
1129 static BOOLEAN
1130 hal_EfusePgPacketWrite1ByteHeader(
1131         IN      PADAPTER                pAdapter,
1132         IN      u8                              efuseType,
1133         IN      u16                             *pAddr,
1134         IN      PPGPKT_STRUCT   pTargetPkt,
1135         IN      BOOLEAN                 bPseudoTest);
1136 static BOOLEAN
1137 hal_EfusePgPacketWriteData(
1138         IN      PADAPTER                pAdapter,
1139         IN      u8                              efuseType,
1140         IN      u16                             *pAddr,
1141         IN      PPGPKT_STRUCT   pTargetPkt,
1142         IN      BOOLEAN                 bPseudoTest);
1143
1144 static VOID
1145 hal_EfusePowerSwitch_RTL8188E(
1146         IN      PADAPTER        pAdapter,
1147         IN      u8              bWrite,
1148         IN      u8              PwrState)
1149 {
1150         u8      tempval;
1151         u16     tmpV16;
1152
1153         if (PwrState == _TRUE)
1154         {
1155                 rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
1156 #if 0
1157                 // 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid
1158                 tmpV16 = rtw_read16(pAdapter,REG_SYS_ISO_CTRL);
1159                 if( ! (tmpV16 & PWC_EV12V ) ){
1160                         tmpV16 |= PWC_EV12V ;
1161                          rtw_write16(pAdapter,REG_SYS_ISO_CTRL,tmpV16);
1162                 }
1163 #endif          
1164                 // Reset: 0x0000h[28], default valid
1165                 tmpV16 =  rtw_read16(pAdapter,REG_SYS_FUNC_EN);
1166                 if( !(tmpV16 & FEN_ELDR) ){
1167                         tmpV16 |= FEN_ELDR ;
1168                         rtw_write16(pAdapter,REG_SYS_FUNC_EN,tmpV16);
1169                 }
1170
1171                 // Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid
1172                 tmpV16 = rtw_read16(pAdapter,REG_SYS_CLKR);
1173                 if( (!(tmpV16 & LOADER_CLK_EN) )  ||(!(tmpV16 & ANA8M) ) ){
1174                         tmpV16 |= (LOADER_CLK_EN |ANA8M ) ;
1175                         rtw_write16(pAdapter,REG_SYS_CLKR,tmpV16);
1176                 }
1177
1178                 if(bWrite == _TRUE)
1179                 {
1180                         // Enable LDO 2.5V before read/write action
1181                         tempval = rtw_read8(pAdapter, EFUSE_TEST+3);
1182                         if(IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)){
1183                                 tempval &= 0x87;
1184                                 tempval |= 0x38; // 0x34[30:27] = 0b'0111,  Use LDO 2.25V, Suggested by SD1 Pisa
1185                         }
1186                         else{                           
1187                                 tempval &= 0x0F;
1188                                 tempval |= (VOLTAGE_V25 << 4);
1189                         }
1190                         rtw_write8(pAdapter, EFUSE_TEST+3, (tempval | 0x80));
1191                 }
1192         }
1193         else
1194         {
1195                 rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
1196
1197                 if(bWrite == _TRUE){
1198                         // Disable LDO 2.5V after read/write action
1199                         tempval = rtw_read8(pAdapter, EFUSE_TEST+3);
1200                         rtw_write8(pAdapter, EFUSE_TEST+3, (tempval & 0x7F));
1201                 }
1202         }
1203 }
1204
1205 static VOID
1206 rtl8188e_EfusePowerSwitch(
1207         IN      PADAPTER        pAdapter,
1208         IN      u8              bWrite,
1209         IN      u8              PwrState)
1210 {
1211         hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);      
1212 }
1213
1214
1215
1216 static bool efuse_read_phymap(
1217         PADAPTER        Adapter,
1218         u8                      *pbuf,  //buffer to store efuse physical map
1219         u16                     *size   //the max byte to read. will update to byte read
1220         )
1221 {
1222         u8 *pos = pbuf;
1223         u16 limit = *size;
1224         u16 addr = 0;
1225         bool reach_end = _FALSE;
1226
1227         //
1228         // Refresh efuse init map as all 0xFF.
1229         //
1230         _rtw_memset(pbuf, 0xFF, limit);
1231                 
1232         
1233         //
1234         // Read physical efuse content.
1235         //
1236         while(addr < limit)
1237         {
1238                 ReadEFuseByte(Adapter, addr, pos, _FALSE);
1239                 if(*pos != 0xFF)
1240                 {
1241                         pos++;
1242                         addr++;
1243                 }
1244                 else
1245                 {
1246                         reach_end = _TRUE;
1247                         break;
1248                 }
1249         }
1250
1251         *size = addr;
1252
1253         return reach_end;
1254
1255 }
1256
1257 static VOID
1258 Hal_EfuseReadEFuse88E(
1259         PADAPTER                Adapter,
1260         u16                     _offset,
1261         u16                     _size_byte,
1262         u8                      *pbuf,
1263         IN      BOOLEAN bPseudoTest
1264         )
1265 {
1266         //u8    efuseTbl[EFUSE_MAP_LEN_88E];
1267         u8      *efuseTbl = NULL;
1268         u8      rtemp8[1];
1269         u16     eFuse_Addr = 0;
1270         u8      offset, wren;
1271         u16     i, j;
1272         //u16   eFuseWord[EFUSE_MAX_SECTION_88E][EFUSE_MAX_WORD_UNIT];
1273         u16     **eFuseWord = NULL;
1274         u16     efuse_utilized = 0;
1275         u8      efuse_usage = 0;
1276         u8      u1temp = 0;
1277
1278         //
1279         // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
1280         //
1281         if((_offset + _size_byte)>EFUSE_MAP_LEN_88E)
1282         {// total E-Fuse table is 512bytes
1283                 DBG_8192C("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n",_offset, _size_byte);
1284                 goto exit;
1285         }
1286
1287         efuseTbl = (u8*)rtw_zmalloc(EFUSE_MAP_LEN_88E);
1288         if(efuseTbl == NULL)
1289         {
1290                 DBG_871X("%s: alloc efuseTbl fail!\n", __FUNCTION__);
1291                 goto exit;
1292         }
1293
1294         eFuseWord= (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, 2);
1295         if(eFuseWord == NULL)
1296         {
1297                 DBG_871X("%s: alloc eFuseWord fail!\n", __FUNCTION__);
1298                 goto exit;
1299         }
1300
1301         // 0. Refresh efuse init map as all oxFF.
1302         for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
1303                 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
1304                         eFuseWord[i][j] = 0xFFFF;
1305
1306         //
1307         // 1. Read the first byte to check if efuse is empty!!!
1308         // 
1309         //
1310         ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);        
1311         if(*rtemp8 != 0xFF)
1312         {
1313                 efuse_utilized++;
1314                 //DBG_8192C("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8);
1315                 eFuse_Addr++;
1316         }
1317         else
1318         {
1319                 DBG_871X("EFUSE is empty efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8);
1320                 goto exit;
1321         }
1322
1323
1324         //
1325         // 2. Read real efuse content. Filter PG header and every section data.
1326         //
1327         while((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
1328         {
1329                 //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr-1, *rtemp8));
1330         
1331                 // Check PG header for section num.
1332                 if((*rtemp8 & 0x1F ) == 0x0F)           //extended header
1333                 {                       
1334                         u1temp =( (*rtemp8 & 0xE0) >> 5);
1335                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x *rtemp&0xE0 0x%x\n", u1temp, *rtemp8 & 0xE0));
1336
1337                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x \n", u1temp));
1338                         
1339                         ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);        
1340
1341                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8));     
1342                         
1343                         if((*rtemp8 & 0x0F) == 0x0F)
1344                         {
1345                                 eFuse_Addr++;                   
1346                                 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); 
1347                                 
1348                                 if(*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
1349                                 {
1350                                         eFuse_Addr++;                           
1351                                 }                               
1352                                 continue;
1353                         }
1354                         else
1355                         {
1356                                 offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
1357                                 wren = (*rtemp8 & 0x0F);
1358                                 eFuse_Addr++;                           
1359                         }
1360                 }
1361                 else
1362                 {
1363                         offset = ((*rtemp8 >> 4) & 0x0f);
1364                         wren = (*rtemp8 & 0x0f);                        
1365                 }
1366                 
1367                 if(offset < EFUSE_MAX_SECTION_88E)
1368                 {
1369                         // Get word enable value from PG header
1370                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Offset-%d Worden=%x\n", offset, wren));
1371
1372                         for(i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1373                         {
1374                                 // Check word enable condition in the section                           
1375                                 if(!(wren & 0x01))
1376                                 {
1377                                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d \n", eFuse_Addr));
1378                                         ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);        
1379                                         eFuse_Addr++;
1380                                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8));                           
1381                                         efuse_utilized++;
1382                                         eFuseWord[offset][i] = (*rtemp8 & 0xff);
1383                                         
1384
1385                                         if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) 
1386                                                 break;
1387
1388                                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d", eFuse_Addr));
1389                                         ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);        
1390                                         eFuse_Addr++;
1391                                         //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8));                           
1392                                         
1393                                         efuse_utilized++;
1394                                         eFuseWord[offset][i] |= (((u2Byte)*rtemp8 << 8) & 0xff00);
1395
1396                                         if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) 
1397                                                 break;
1398                                 }
1399                                 
1400                                 wren >>= 1;
1401                                 
1402                         }
1403                 }
1404                 else{//deal with error offset,skip error data           
1405                         DBG_871X_LEVEL(_drv_always_, "invalid offset:0x%02x \n",offset);
1406                         for(i=0; i<EFUSE_MAX_WORD_UNIT; i++){
1407                                 // Check word enable condition in the section                           
1408                                 if(!(wren & 0x01)){
1409                                         eFuse_Addr++;
1410                                         efuse_utilized++;
1411                                         if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) 
1412                                                 break;
1413                                         eFuse_Addr++;
1414                                         efuse_utilized++;
1415                                         if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) 
1416                                                 break;
1417                                 }
1418                         }
1419                 }
1420                 // Read next PG header
1421                 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);        
1422                 //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d rtemp 0x%x\n", eFuse_Addr, *rtemp8));
1423                 
1424                 if(*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
1425                 {
1426                         efuse_utilized++;
1427                         eFuse_Addr++;
1428                 }
1429         }
1430
1431         //
1432         // 3. Collect 16 sections and 4 word unit into Efuse map.
1433         //
1434         for(i=0; i<EFUSE_MAX_SECTION_88E; i++)
1435         {
1436                 for(j=0; j<EFUSE_MAX_WORD_UNIT; j++)
1437                 {
1438                         efuseTbl[(i*8)+(j*2)]=(eFuseWord[i][j] & 0xff);
1439                         efuseTbl[(i*8)+((j*2)+1)]=((eFuseWord[i][j] >> 8) & 0xff);
1440                 }
1441         }
1442
1443
1444         //
1445         // 4. Copy from Efuse map to output pointer memory!!!
1446         //
1447         for(i=0; i<_size_byte; i++)
1448         {               
1449                 pbuf[i] = efuseTbl[_offset+i];
1450         }
1451
1452         //
1453         // 5. Calculate Efuse utilization.
1454         //
1455         efuse_usage = (u1Byte)((eFuse_Addr*100)/EFUSE_REAL_CONTENT_LEN_88E);
1456         rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&eFuse_Addr);
1457
1458 exit:
1459         if(efuseTbl)
1460                 rtw_mfree(efuseTbl, EFUSE_MAP_LEN_88E);
1461
1462         if(eFuseWord)
1463                 rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
1464 }
1465
1466
1467 static BOOLEAN
1468 Hal_EfuseSwitchToBank(
1469         IN              PADAPTER        pAdapter,
1470         IN              u8                      bank,
1471         IN              BOOLEAN         bPseudoTest
1472         )
1473 {
1474         BOOLEAN         bRet = _FALSE;
1475         u32             value32=0;
1476
1477         //RTPRINT(FEEPROM, EFUSE_PG, ("Efuse switch bank to %d\n", bank));
1478         if(bPseudoTest)
1479         {
1480                 fakeEfuseBank = bank;
1481                 bRet = _TRUE;
1482         }
1483         else
1484         {
1485                 bRet = _TRUE;
1486         }
1487         return bRet;
1488 }
1489
1490
1491
1492 static VOID
1493 ReadEFuseByIC(
1494         PADAPTER        Adapter,
1495         u8              efuseType,
1496         u16              _offset,
1497         u16             _size_byte,
1498         u8              *pbuf,
1499         IN BOOLEAN      bPseudoTest
1500         )
1501 {
1502         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1503 #ifdef DBG_IOL_READ_EFUSE_MAP
1504         u8 logical_map[512];
1505 #endif
1506
1507 #ifdef CONFIG_IOL_READ_EFUSE_MAP
1508         if(!bPseudoTest )//&& rtw_IOL_applied(Adapter))
1509         {
1510                 int ret = _FAIL;
1511                 if(rtw_IOL_applied(Adapter))
1512                 {
1513                         rtw_hal_power_on(Adapter);
1514                         
1515                         iol_mode_enable(Adapter, 1);
1516                         #ifdef DBG_IOL_READ_EFUSE_MAP
1517                         iol_read_efuse(Adapter, 0, _offset, _size_byte, logical_map);
1518                         #else
1519                         ret = iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf);
1520                         #endif
1521                         iol_mode_enable(Adapter, 0);    
1522                         
1523                         if(_SUCCESS == ret) 
1524                                 goto exit;
1525                 }
1526         }
1527 #endif
1528         Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
1529
1530 exit:
1531         
1532 #ifdef DBG_IOL_READ_EFUSE_MAP
1533         if(_rtw_memcmp(logical_map, pHalData->efuse_eeprom_data, 0x130) == _FALSE)
1534         {
1535                 int i;
1536                 DBG_871X("%s compare first 0x130 byte fail\n", __FUNCTION__);
1537                 for(i=0;i<512;i++)
1538                 {
1539                         if(i%16==0)
1540                                 DBG_871X("0x%03x: ", i);
1541                         DBG_871X("%02x ", logical_map[i]);
1542                         if(i%16==15)
1543                                 DBG_871X("\n");
1544                 }
1545                 DBG_871X("\n");
1546         }
1547 #endif
1548
1549         return; 
1550 }
1551
1552 static VOID
1553 ReadEFuse_Pseudo(
1554         PADAPTER        Adapter,
1555         u8              efuseType,
1556         u16              _offset,
1557         u16             _size_byte,
1558         u8              *pbuf,
1559         IN BOOLEAN      bPseudoTest
1560         )
1561 {
1562         Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
1563 }
1564
1565 static VOID
1566 rtl8188e_ReadEFuse(
1567         PADAPTER        Adapter,
1568         u8              efuseType,
1569         u16             _offset,
1570         u16             _size_byte,
1571         u8              *pbuf,
1572         IN      BOOLEAN bPseudoTest
1573         )
1574 {
1575         if(bPseudoTest)
1576         {
1577                 ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
1578         }
1579         else
1580         {
1581                 ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
1582         }
1583 }
1584
1585 //Do not support BT
1586 VOID
1587 Hal_EFUSEGetEfuseDefinition88E(
1588         IN              PADAPTER        pAdapter,
1589         IN              u1Byte          efuseType,
1590         IN              u1Byte          type,
1591         OUT             PVOID           pOut
1592         )
1593 {
1594         switch(type)
1595         {
1596                 case TYPE_EFUSE_MAX_SECTION:
1597                         {
1598                                 u8*     pMax_section;
1599                                 pMax_section = (u8*)pOut;
1600                                 *pMax_section = EFUSE_MAX_SECTION_88E;
1601                         }
1602                         break;
1603                 case TYPE_EFUSE_REAL_CONTENT_LEN:
1604                         {
1605                                 u16* pu2Tmp;
1606                                 pu2Tmp = (u16*)pOut;
1607                                 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1608                         }
1609                         break;
1610                 case TYPE_EFUSE_CONTENT_LEN_BANK:
1611                         {
1612                                 u16* pu2Tmp;
1613                                 pu2Tmp = (u16*)pOut;
1614                                 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1615                         }
1616                         break;
1617                 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
1618                         {
1619                                 u16* pu2Tmp;
1620                                 pu2Tmp = (u16*)pOut;
1621                                 *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1622                         }
1623                         break;
1624                 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
1625                         {
1626                                 u16* pu2Tmp;
1627                                 pu2Tmp = (u16*)pOut;
1628                                 *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1629                         }
1630                         break;
1631                 case TYPE_EFUSE_MAP_LEN:
1632                         {
1633                                 u16* pu2Tmp;
1634                                 pu2Tmp = (u16*)pOut;
1635                                 *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
1636                         }
1637                         break;
1638                 case TYPE_EFUSE_PROTECT_BYTES_BANK:
1639                         {
1640                                 u8* pu1Tmp;
1641                                 pu1Tmp = (u8*)pOut;
1642                                 *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
1643                         }
1644                         break;
1645                 default:
1646                         {
1647                                 u8* pu1Tmp;
1648                                 pu1Tmp = (u8*)pOut;
1649                                 *pu1Tmp = 0;
1650                         }
1651                         break;
1652         }
1653 }
1654 VOID
1655 Hal_EFUSEGetEfuseDefinition_Pseudo88E(
1656         IN              PADAPTER        pAdapter,
1657         IN              u8                      efuseType,
1658         IN              u8                      type,
1659         OUT             PVOID           pOut
1660         )
1661 {
1662         switch(type)
1663         {
1664                 case TYPE_EFUSE_MAX_SECTION:
1665                         {
1666                                 u8*             pMax_section;
1667                                 pMax_section = (pu1Byte)pOut;
1668                                 *pMax_section = EFUSE_MAX_SECTION_88E;
1669                         }
1670                         break;
1671                 case TYPE_EFUSE_REAL_CONTENT_LEN:
1672                         {
1673                                 u16* pu2Tmp;
1674                                 pu2Tmp = (pu2Byte)pOut;
1675                                 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1676                         }
1677                         break;
1678                 case TYPE_EFUSE_CONTENT_LEN_BANK:
1679                         {
1680                                 u16* pu2Tmp;
1681                                 pu2Tmp = (pu2Byte)pOut;
1682                                 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1683                         }
1684                         break;
1685                 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
1686                         {
1687                                 u16* pu2Tmp;
1688                                 pu2Tmp = (pu2Byte)pOut;
1689                                 *pu2Tmp = (u2Byte)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1690                         }
1691                         break;
1692                 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
1693                         {
1694                                 u16* pu2Tmp;
1695                                 pu2Tmp = (pu2Byte)pOut;
1696                                 *pu2Tmp = (u2Byte)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
1697                         }
1698                         break;
1699                 case TYPE_EFUSE_MAP_LEN:
1700                         {
1701                                 u16* pu2Tmp;
1702                                 pu2Tmp = (pu2Byte)pOut;
1703                                 *pu2Tmp = (u2Byte)EFUSE_MAP_LEN_88E;
1704                         }
1705                         break;
1706                 case TYPE_EFUSE_PROTECT_BYTES_BANK:
1707                         {
1708                                 u8* pu1Tmp;
1709                                 pu1Tmp = (u8*)pOut;
1710                                 *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
1711                         }
1712                         break;
1713                 default:
1714                         {
1715                                 u8* pu1Tmp;
1716                                 pu1Tmp = (u8*)pOut;
1717                                 *pu1Tmp = 0;
1718                         }
1719                         break;
1720         }
1721 }
1722
1723
1724 static VOID
1725 rtl8188e_EFUSE_GetEfuseDefinition(
1726         IN              PADAPTER        pAdapter,
1727         IN              u8              efuseType,
1728         IN              u8              type,
1729         OUT             void            *pOut,
1730         IN              BOOLEAN         bPseudoTest
1731         )
1732 {
1733         if(bPseudoTest)
1734         {
1735                 Hal_EFUSEGetEfuseDefinition_Pseudo88E(pAdapter, efuseType, type, pOut);
1736         }
1737         else
1738         {
1739                 Hal_EFUSEGetEfuseDefinition88E(pAdapter, efuseType, type, pOut);
1740         }
1741 }
1742
1743 static u8
1744 Hal_EfuseWordEnableDataWrite(   IN      PADAPTER        pAdapter,
1745                                                         IN      u16             efuse_addr,
1746                                                         IN      u8              word_en,
1747                                                         IN      u8              *data,
1748                                                         IN      BOOLEAN         bPseudoTest)
1749 {
1750         u16     tmpaddr = 0;
1751         u16     start_addr = efuse_addr;
1752         u8      badworden = 0x0F;
1753         u8      tmpdata[8];
1754
1755         _rtw_memset((PVOID)tmpdata, 0xff, PGPKT_DATA_SIZE);
1756         //RT_TRACE(COMP_EFUSE, DBG_LOUD, ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr));
1757
1758         if(!(word_en&BIT0))
1759         {
1760                 tmpaddr = start_addr;
1761                 efuse_OneByteWrite(pAdapter,start_addr++, data[0], bPseudoTest);
1762                 efuse_OneByteWrite(pAdapter,start_addr++, data[1], bPseudoTest);
1763
1764                 efuse_OneByteRead(pAdapter,tmpaddr, &tmpdata[0], bPseudoTest);
1765                 efuse_OneByteRead(pAdapter,tmpaddr+1, &tmpdata[1], bPseudoTest);
1766                 if((data[0]!=tmpdata[0])||(data[1]!=tmpdata[1])){
1767                         badworden &= (~BIT0);
1768                 }
1769         }
1770         if(!(word_en&BIT1))
1771         {
1772                 tmpaddr = start_addr;
1773                 efuse_OneByteWrite(pAdapter,start_addr++, data[2], bPseudoTest);
1774                 efuse_OneByteWrite(pAdapter,start_addr++, data[3], bPseudoTest);
1775
1776                 efuse_OneByteRead(pAdapter,tmpaddr    , &tmpdata[2], bPseudoTest);
1777                 efuse_OneByteRead(pAdapter,tmpaddr+1, &tmpdata[3], bPseudoTest);
1778                 if((data[2]!=tmpdata[2])||(data[3]!=tmpdata[3])){
1779                         badworden &=( ~BIT1);
1780                 }
1781         }
1782         if(!(word_en&BIT2))
1783         {
1784                 tmpaddr = start_addr;
1785                 efuse_OneByteWrite(pAdapter,start_addr++, data[4], bPseudoTest);
1786                 efuse_OneByteWrite(pAdapter,start_addr++, data[5], bPseudoTest);
1787
1788                 efuse_OneByteRead(pAdapter,tmpaddr, &tmpdata[4], bPseudoTest);
1789                 efuse_OneByteRead(pAdapter,tmpaddr+1, &tmpdata[5], bPseudoTest);
1790                 if((data[4]!=tmpdata[4])||(data[5]!=tmpdata[5])){
1791                         badworden &=( ~BIT2);
1792                 }
1793         }
1794         if(!(word_en&BIT3))
1795         {
1796                 tmpaddr = start_addr;
1797                 efuse_OneByteWrite(pAdapter,start_addr++, data[6], bPseudoTest);
1798                 efuse_OneByteWrite(pAdapter,start_addr++, data[7], bPseudoTest);
1799
1800                 efuse_OneByteRead(pAdapter,tmpaddr, &tmpdata[6], bPseudoTest);
1801                 efuse_OneByteRead(pAdapter,tmpaddr+1, &tmpdata[7], bPseudoTest);
1802                 if((data[6]!=tmpdata[6])||(data[7]!=tmpdata[7])){
1803                         badworden &=( ~BIT3);
1804                 }
1805         }
1806         return badworden;
1807 }
1808
1809 static u8
1810 Hal_EfuseWordEnableDataWrite_Pseudo(    IN      PADAPTER        pAdapter,
1811                                                         IN      u16             efuse_addr,
1812                                                         IN      u8              word_en,
1813                                                         IN      u8              *data,
1814                                                         IN      BOOLEAN         bPseudoTest)
1815 {
1816         u8      ret=0;
1817
1818         ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1819
1820         return ret;
1821 }
1822
1823 static u8
1824 rtl8188e_Efuse_WordEnableDataWrite(     IN      PADAPTER        pAdapter,
1825                                                         IN      u16             efuse_addr,
1826                                                         IN      u8              word_en,
1827                                                         IN      u8              *data,
1828                                                         IN      BOOLEAN         bPseudoTest)
1829 {
1830         u8      ret=0;
1831
1832         if(bPseudoTest)
1833         {
1834                 ret = Hal_EfuseWordEnableDataWrite_Pseudo(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1835         }
1836         else
1837         {
1838                 ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1839         }
1840
1841         return ret;
1842 }
1843
1844
1845 static u16
1846 hal_EfuseGetCurrentSize_8188e(IN        PADAPTER        pAdapter,
1847                 IN              BOOLEAN                 bPseudoTest)
1848 {
1849         int     bContinual = _TRUE;
1850
1851         u16     efuse_addr = 0;
1852         u8      hoffset=0,hworden=0;
1853         u8      efuse_data,word_cnts=0;
1854
1855         if(bPseudoTest)
1856         {
1857                 efuse_addr = (u16)(fakeEfuseUsedBytes);
1858         }
1859         else
1860         {
1861                 rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1862         }
1863         //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723A(), start_efuse_addr = %d\n", efuse_addr));
1864
1865         while ( bContinual &&
1866                         efuse_OneByteRead(pAdapter, efuse_addr ,&efuse_data, bPseudoTest) &&
1867                         AVAILABLE_EFUSE_ADDR(efuse_addr))
1868         {
1869                 if(efuse_data!=0xFF)
1870                 {
1871                         if((efuse_data&0x1F) == 0x0F)           //extended header
1872                         {
1873                                 hoffset = efuse_data;
1874                                 efuse_addr++;
1875                                 efuse_OneByteRead(pAdapter, efuse_addr ,&efuse_data, bPseudoTest);
1876                                 if((efuse_data & 0x0F) == 0x0F)
1877                                 {
1878                                         efuse_addr++;
1879                                         continue;
1880                                 }
1881                                 else
1882                                 {
1883                                         hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1884                                         hworden = efuse_data & 0x0F;
1885                                 }
1886                         }
1887                         else
1888                         {
1889                                 hoffset = (efuse_data>>4) & 0x0F;
1890                                 hworden =  efuse_data & 0x0F;
1891                         }
1892                         word_cnts = Efuse_CalculateWordCnts(hworden);
1893                         //read next header
1894                         efuse_addr = efuse_addr + (word_cnts*2)+1;
1895                 }
1896                 else
1897                 {
1898                         bContinual = _FALSE ;
1899                 }
1900         }
1901
1902         if(bPseudoTest)
1903         {
1904                 fakeEfuseUsedBytes = efuse_addr;
1905                 //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723A(), return %d\n", fakeEfuseUsedBytes));
1906         }
1907         else
1908         {
1909                 rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1910                 //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723A(), return %d\n", efuse_addr));
1911         }
1912
1913         return efuse_addr;
1914 }
1915
1916 static u16
1917 Hal_EfuseGetCurrentSize_Pseudo(IN       PADAPTER        pAdapter,
1918                 IN              BOOLEAN                 bPseudoTest)
1919 {
1920         u16     ret=0;
1921
1922         ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
1923
1924         return ret;
1925 }
1926
1927
1928 static u16
1929 rtl8188e_EfuseGetCurrentSize(
1930         IN      PADAPTER        pAdapter,
1931         IN      u8                      efuseType,
1932         IN      BOOLEAN         bPseudoTest)
1933 {
1934         u16     ret=0;
1935
1936         if(bPseudoTest)
1937         {
1938                 ret = Hal_EfuseGetCurrentSize_Pseudo(pAdapter, bPseudoTest);
1939         }
1940         else
1941         {
1942                 ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
1943                 
1944         }
1945
1946         return ret;
1947 }
1948
1949
1950 static int
1951 hal_EfusePgPacketRead_8188e(
1952         IN      PADAPTER        pAdapter,
1953         IN      u8                      offset,
1954         IN      u8                      *data,
1955         IN      BOOLEAN         bPseudoTest)
1956 {
1957         u8      ReadState = PG_STATE_HEADER;
1958
1959         int     bContinual = _TRUE;
1960         int     bDataEmpty = _TRUE ;
1961
1962         u8      efuse_data,word_cnts = 0;
1963         u16     efuse_addr = 0;
1964         u8      hoffset = 0,hworden = 0;
1965         u8      tmpidx = 0;
1966         u8      tmpdata[8];
1967         u8      max_section = 0;
1968         u8      tmp_header = 0;
1969
1970         EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (PVOID)&max_section, bPseudoTest);
1971
1972         if(data==NULL)
1973                 return _FALSE;
1974         if(offset>max_section)
1975                 return _FALSE;
1976
1977         _rtw_memset((PVOID)data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
1978         _rtw_memset((PVOID)tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
1979
1980
1981         //
1982         // <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP.
1983         // Skip dummy parts to prevent unexpected data read from Efuse.
1984         // By pass right now. 2009.02.19.
1985         //
1986         while(bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr) )
1987         {
1988                 //-------  Header Read -------------
1989                 if(ReadState & PG_STATE_HEADER)
1990                 {
1991                         if(efuse_OneByteRead(pAdapter, efuse_addr ,&efuse_data, bPseudoTest)&&(efuse_data!=0xFF))
1992                         {
1993                                 if(EXT_HEADER(efuse_data))
1994                                 {
1995                                         tmp_header = efuse_data;
1996                                         efuse_addr++;
1997                                         efuse_OneByteRead(pAdapter, efuse_addr ,&efuse_data, bPseudoTest);
1998                                         if(!ALL_WORDS_DISABLED(efuse_data))
1999                                         {
2000                                                 hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2001                                                 hworden = efuse_data & 0x0F;
2002                                         }
2003                                         else
2004                                         {
2005                                                 DBG_8192C("Error, All words disabled\n");
2006                                                 efuse_addr++;
2007                                                 continue;
2008                                         }
2009                                 }
2010                                 else
2011                                 {
2012                                         hoffset = (efuse_data>>4) & 0x0F;
2013                                         hworden =  efuse_data & 0x0F;
2014                                 }
2015                                 word_cnts = Efuse_CalculateWordCnts(hworden);
2016                                 bDataEmpty = _TRUE ;
2017
2018                                 if(hoffset==offset)
2019                                 {
2020                                         for(tmpidx = 0;tmpidx< word_cnts*2 ;tmpidx++)
2021                                         {
2022                                                 if(efuse_OneByteRead(pAdapter, efuse_addr+1+tmpidx ,&efuse_data, bPseudoTest) )
2023                                                 {
2024                                                         tmpdata[tmpidx] = efuse_data;
2025                                                         if(efuse_data!=0xff)
2026                                                         {
2027                                                                 bDataEmpty = _FALSE;
2028                                                         }
2029                                                 }
2030                                         }
2031                                         if(bDataEmpty==_FALSE){
2032                                                 ReadState = PG_STATE_DATA;
2033                                         }else{//read next header
2034                                                 efuse_addr = efuse_addr + (word_cnts*2)+1;
2035                                                 ReadState = PG_STATE_HEADER;
2036                                         }
2037                                 }
2038                                 else{//read next header
2039                                         efuse_addr = efuse_addr + (word_cnts*2)+1;
2040                                         ReadState = PG_STATE_HEADER;
2041                                 }
2042
2043                         }
2044                         else{
2045                                 bContinual = _FALSE ;
2046                         }
2047                 }
2048                 //-------  Data section Read -------------
2049                 else if(ReadState & PG_STATE_DATA)
2050                 {
2051                         efuse_WordEnableDataRead(hworden,tmpdata,data);
2052                         efuse_addr = efuse_addr + (word_cnts*2)+1;
2053                         ReadState = PG_STATE_HEADER;
2054                 }
2055
2056         }
2057
2058         if(     (data[0]==0xff) &&(data[1]==0xff) && (data[2]==0xff)  && (data[3]==0xff) &&
2059                 (data[4]==0xff) &&(data[5]==0xff) && (data[6]==0xff)  && (data[7]==0xff))
2060                 return _FALSE;
2061         else
2062                 return _TRUE;
2063
2064 }
2065
2066 static int
2067 Hal_EfusePgPacketRead(  IN      PADAPTER        pAdapter,
2068                                         IN      u8                      offset,
2069                                         IN      u8                      *data,
2070                                         IN      BOOLEAN                 bPseudoTest)
2071 {
2072         int     ret=0;
2073
2074         ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
2075         
2076
2077         return ret;
2078 }
2079
2080 static int
2081 Hal_EfusePgPacketRead_Pseudo(   IN      PADAPTER        pAdapter,
2082                                         IN      u8                      offset,
2083                                         IN      u8                      *data,
2084                                         IN      BOOLEAN         bPseudoTest)
2085 {
2086         int     ret=0;
2087
2088         ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
2089
2090         return ret;
2091 }
2092
2093 static int
2094 rtl8188e_Efuse_PgPacketRead(    IN      PADAPTER        pAdapter,
2095                                         IN      u8                      offset,
2096                                         IN      u8                      *data,
2097                                         IN      BOOLEAN         bPseudoTest)
2098 {
2099         int     ret=0;
2100
2101         if(bPseudoTest)
2102         {
2103                 ret = Hal_EfusePgPacketRead_Pseudo(pAdapter, offset, data, bPseudoTest);
2104         }
2105         else
2106         {
2107                 ret = Hal_EfusePgPacketRead(pAdapter, offset, data, bPseudoTest);
2108         }
2109
2110         return ret;
2111 }
2112
2113 static BOOLEAN
2114 hal_EfuseFixHeaderProcess(
2115         IN              PADAPTER                        pAdapter,
2116         IN              u8                                      efuseType,
2117         IN              PPGPKT_STRUCT           pFixPkt,
2118         IN              u16                                     *pAddr,
2119         IN              BOOLEAN                         bPseudoTest
2120 )
2121 {
2122         u8      originaldata[8], badworden=0;
2123         u16     efuse_addr=*pAddr;
2124         u32     PgWriteSuccess=0;
2125
2126         _rtw_memset((PVOID)originaldata, 0xff, 8);
2127
2128         if(Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest))
2129         {       //check if data exist
2130                 badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pFixPkt->word_en, originaldata, bPseudoTest);
2131
2132                 if(badworden != 0xf)    // write fail
2133                 {                       
2134                         PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest);
2135
2136                         if(!PgWriteSuccess)
2137                                 return _FALSE;
2138                         else
2139                                 efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
2140                 }
2141                 else
2142                 {
2143                         efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) +1;
2144                 }
2145         }
2146         else
2147         {
2148                 efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) +1;
2149         }
2150         *pAddr = efuse_addr;
2151         return _TRUE;
2152 }
2153
2154 static BOOLEAN
2155 hal_EfusePgPacketWrite2ByteHeader(
2156         IN                      PADAPTER                pAdapter,
2157         IN                      u8                              efuseType,
2158         IN                      u16                             *pAddr,
2159         IN                      PPGPKT_STRUCT   pTargetPkt,
2160         IN                      BOOLEAN                 bPseudoTest)
2161 {
2162         BOOLEAN         bRet=_FALSE, bContinual=_TRUE;
2163         u16     efuse_addr=*pAddr, efuse_max_available_len=0;
2164         u8      pg_header=0, tmp_header=0, pg_header_temp=0;
2165         u8      repeatcnt=0;
2166
2167         //RTPRINT(FEEPROM, EFUSE_PG, ("Wirte 2byte header\n"));
2168         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (PVOID)&efuse_max_available_len, bPseudoTest);
2169
2170         while(efuse_addr < efuse_max_available_len)
2171         {
2172                 pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
2173                 //RTPRINT(FEEPROM, EFUSE_PG, ("pg_header = 0x%x\n", pg_header));
2174                 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2175                 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2176
2177                 while(tmp_header == 0xFF)
2178                 {
2179                         if(repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2180                         {
2181                                 //RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for pg_header!!\n"));
2182                                 return _FALSE;
2183                         }
2184
2185                         efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2186                         efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2187                 }
2188
2189                 //to write ext_header
2190                 if(tmp_header == pg_header)
2191                 {
2192                         efuse_addr++;
2193                         pg_header_temp = pg_header;
2194                         pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
2195
2196                         efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2197                         efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2198
2199                         while(tmp_header == 0xFF)
2200                         {
2201                                 if(repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2202                                 {
2203                                         //RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for ext_header!!\n"));
2204                                         return _FALSE;
2205                                 }
2206
2207                                 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2208                                 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2209                         }
2210
2211                         if((tmp_header & 0x0F) == 0x0F) //word_en PG fail
2212                         {
2213                                 if(repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2214                                 {
2215                                         //RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for word_en!!\n"));
2216                                         return _FALSE;
2217                                 }
2218                                 else
2219                                 {
2220                                         efuse_addr++;
2221                                         continue;
2222                                 }
2223                         }
2224                         else if(pg_header != tmp_header)        //offset PG fail
2225                         {
2226                                 PGPKT_STRUCT    fixPkt;
2227                                 //RTPRINT(FEEPROM, EFUSE_PG, ("Error condition for offset PG fail, need to cover the existed data\n"));
2228                                 fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
2229                                 fixPkt.word_en = tmp_header & 0x0F;
2230                                 fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
2231                                 if(!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
2232                                         return _FALSE;
2233                         }
2234                         else
2235                         {
2236                                 bRet = _TRUE;
2237                                 break;
2238                         }
2239                 }
2240                 else if ((tmp_header & 0x1F) == 0x0F)           //wrong extended header
2241                 {
2242                         efuse_addr+=2;
2243                         continue;
2244                 }
2245         }
2246
2247         *pAddr = efuse_addr;
2248         return bRet;
2249 }
2250
2251 static BOOLEAN
2252 hal_EfusePgPacketWrite1ByteHeader(
2253         IN                      PADAPTER                pAdapter,
2254         IN                      u8                              efuseType,
2255         IN                      u16                             *pAddr,
2256         IN                      PPGPKT_STRUCT   pTargetPkt,
2257         IN                      BOOLEAN                 bPseudoTest)
2258 {
2259         BOOLEAN         bRet=_FALSE;
2260         u8      pg_header=0, tmp_header=0;
2261         u16     efuse_addr=*pAddr;
2262         u8      repeatcnt=0;
2263
2264         //RTPRINT(FEEPROM, EFUSE_PG, ("Wirte 1byte header\n"));
2265         pg_header = ((pTargetPkt->offset << 4) & 0xf0) |pTargetPkt->word_en;
2266
2267         efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2268         efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2269
2270         while(tmp_header == 0xFF)
2271         {
2272                 if(repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2273                 {
2274                         return _FALSE;
2275                 }
2276                 efuse_OneByteWrite(pAdapter,efuse_addr, pg_header, bPseudoTest);
2277                 efuse_OneByteRead(pAdapter,efuse_addr, &tmp_header, bPseudoTest);
2278         }
2279
2280         if(pg_header == tmp_header)
2281         {
2282                 bRet = _TRUE;
2283         }
2284         else
2285         {
2286                 PGPKT_STRUCT    fixPkt;
2287                 //RTPRINT(FEEPROM, EFUSE_PG, ("Error condition for fixed PG packet, need to cover the existed data\n"));
2288                 fixPkt.offset = (tmp_header>>4) & 0x0F;
2289                 fixPkt.word_en = tmp_header & 0x0F;
2290                 fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
2291                 if(!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
2292                         return _FALSE;
2293         }
2294
2295         *pAddr = efuse_addr;
2296         return bRet;
2297 }
2298
2299 static BOOLEAN
2300 hal_EfusePgPacketWriteData(
2301         IN                      PADAPTER                pAdapter,
2302         IN                      u8                              efuseType,
2303         IN                      u16                             *pAddr,
2304         IN                      PPGPKT_STRUCT   pTargetPkt,
2305         IN                      BOOLEAN                 bPseudoTest)
2306 {
2307         BOOLEAN bRet=_FALSE;
2308         u16     efuse_addr=*pAddr;
2309         u8      badworden=0;
2310         u32     PgWriteSuccess=0;
2311
2312         badworden = 0x0f;
2313         badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
2314         if(badworden == 0x0F)
2315         {
2316                 // write ok
2317                 //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgPacketWriteData ok!!\n"));
2318                 return _TRUE;
2319         }
2320         else
2321         {
2322                 //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgPacketWriteData Fail!!\n"));
2323                 //reorganize other pg packet
2324                 
2325                 PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2326                 
2327                 if(!PgWriteSuccess)
2328                         return _FALSE;
2329                 else
2330                         return _TRUE;
2331         }
2332
2333         return bRet;
2334 }
2335
2336 static BOOLEAN
2337 hal_EfusePgPacketWriteHeader(
2338         IN                      PADAPTER                pAdapter,
2339         IN                      u8                              efuseType,
2340         IN                      u16                             *pAddr,
2341         IN                      PPGPKT_STRUCT   pTargetPkt,
2342         IN                      BOOLEAN                 bPseudoTest)
2343 {
2344         BOOLEAN         bRet=_FALSE;
2345
2346         if(pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
2347         {
2348                 bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2349         }
2350         else
2351         {
2352                 bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2353         }
2354
2355         return bRet;
2356 }
2357
2358 static BOOLEAN
2359 wordEnMatched(
2360         IN      PPGPKT_STRUCT   pTargetPkt,
2361         IN      PPGPKT_STRUCT   pCurPkt,
2362         IN      u8                              *pWden
2363 )
2364 {
2365         u8      match_word_en = 0x0F;   // default all words are disabled
2366         u8      i;
2367
2368         // check if the same words are enabled both target and current PG packet
2369         if( ((pTargetPkt->word_en & BIT0) == 0) &&
2370                 ((pCurPkt->word_en & BIT0) == 0) )
2371         {
2372                 match_word_en &= ~BIT0;                         // enable word 0
2373         }
2374         if( ((pTargetPkt->word_en & BIT1) == 0) &&
2375                 ((pCurPkt->word_en & BIT1) == 0) )
2376         {
2377                 match_word_en &= ~BIT1;                         // enable word 1
2378         }
2379         if( ((pTargetPkt->word_en & BIT2) == 0) &&
2380                 ((pCurPkt->word_en & BIT2) == 0) )
2381         {
2382                 match_word_en &= ~BIT2;                         // enable word 2
2383         }
2384         if( ((pTargetPkt->word_en & BIT3) == 0) &&
2385                 ((pCurPkt->word_en & BIT3) == 0) )
2386         {
2387                 match_word_en &= ~BIT3;                         // enable word 3
2388         }
2389
2390         *pWden = match_word_en;
2391
2392         if(match_word_en != 0xf)
2393                 return _TRUE;
2394         else
2395                 return _FALSE;
2396 }
2397
2398 static BOOLEAN
2399 hal_EfuseCheckIfDatafollowed(
2400         IN              PADAPTER                pAdapter,
2401         IN              u8                              word_cnts,
2402         IN              u16                             startAddr,
2403         IN              BOOLEAN                 bPseudoTest
2404         )
2405 {
2406         BOOLEAN         bRet=_FALSE;
2407         u8      i, efuse_data;
2408
2409         for(i=0; i<(word_cnts*2) ; i++)
2410         {
2411                 if(efuse_OneByteRead(pAdapter, (startAddr+i) ,&efuse_data, bPseudoTest)&&(efuse_data != 0xFF))
2412                         bRet = _TRUE;
2413         }
2414
2415         return bRet;
2416 }
2417
2418 static BOOLEAN
2419 hal_EfusePartialWriteCheck(
2420                                         IN      PADAPTER                pAdapter,
2421                                         IN      u8                              efuseType,
2422                                         IN      u16                             *pAddr,
2423                                         IN      PPGPKT_STRUCT   pTargetPkt,
2424                                         IN      BOOLEAN                 bPseudoTest
2425                                         )
2426 {
2427         BOOLEAN         bRet=_FALSE;
2428         u8      i, efuse_data=0, cur_header=0;
2429         u8      new_wden=0, matched_wden=0, badworden=0;
2430         u16     startAddr=0, efuse_max_available_len=0, efuse_max=0;
2431         PGPKT_STRUCT    curPkt;
2432
2433         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (PVOID)&efuse_max_available_len, bPseudoTest);
2434         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&efuse_max, bPseudoTest);
2435
2436         if(efuseType == EFUSE_WIFI)
2437         {
2438                 if(bPseudoTest)
2439                 {
2440                         startAddr = (u16)(fakeEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN);
2441                 }
2442                 else
2443                 {
2444                         rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
2445                         startAddr%=EFUSE_REAL_CONTENT_LEN;
2446                 }
2447         }
2448         else
2449         {
2450                 if(bPseudoTest)
2451                 {
2452                         startAddr = (u16)(fakeBTEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN);
2453                 }
2454                 else
2455                 {
2456                         startAddr = (u16)(BTEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN);
2457                 }
2458         }
2459         //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePartialWriteCheck(), startAddr=%d\n", startAddr));
2460
2461         while(1)
2462         {
2463                 if(startAddr >= efuse_max_available_len)
2464                 {
2465                         bRet = _FALSE;
2466                         break;
2467                 }
2468
2469                 if(efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data!=0xFF))
2470                 {
2471                         if(EXT_HEADER(efuse_data))
2472                         {
2473                                 cur_header = efuse_data;
2474                                 startAddr++;
2475                                 efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest);
2476                                 if(ALL_WORDS_DISABLED(efuse_data))
2477                                 {
2478                                         //RTPRINT(FEEPROM, EFUSE_PG, ("Error condition, all words disabled"));
2479                                         bRet = _FALSE;
2480                                         break;
2481                                 }
2482                                 else
2483                                 {
2484                                         curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2485                                         curPkt.word_en = efuse_data & 0x0F;
2486                                 }
2487                         }
2488                         else
2489                         {
2490                                 cur_header  =  efuse_data;
2491                                 curPkt.offset = (cur_header>>4) & 0x0F;
2492                                 curPkt.word_en = cur_header & 0x0F;
2493                         }
2494
2495                         curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
2496                         // if same header is found but no data followed
2497                         // write some part of data followed by the header.
2498                         if( (curPkt.offset == pTargetPkt->offset) &&
2499                                 (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr+1, bPseudoTest)) &&
2500                                 wordEnMatched(pTargetPkt, &curPkt, &matched_wden) )
2501                         {
2502                                 //RTPRINT(FEEPROM, EFUSE_PG, ("Need to partial write data by the previous wrote header\n"));
2503                                 // Here to write partial data
2504                                 badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest);
2505                                 if(badworden != 0x0F)
2506                                 {
2507                                         u32     PgWriteSuccess=0;
2508                                         // if write fail on some words, write these bad words again
2509                                         
2510                                         PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2511                                         
2512                                         if(!PgWriteSuccess)
2513                                         {
2514                                                 bRet = _FALSE;  // write fail, return
2515                                                 break;
2516                                         }
2517                                 }
2518                                 // partial write ok, update the target packet for later use
2519                                 for(i=0; i<4; i++)
2520                                 {
2521                                         if((matched_wden & (0x1<<i)) == 0)      // this word has been written
2522                                         {
2523                                                 pTargetPkt->word_en |= (0x1<<i);        // disable the word
2524                                         }
2525                                 }
2526                                 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2527                         }
2528                         // read from next header
2529                         startAddr = startAddr + (curPkt.word_cnts*2) +1;
2530                 }
2531                 else
2532                 {
2533                         // not used header, 0xff
2534                         *pAddr = startAddr;
2535                         //RTPRINT(FEEPROM, EFUSE_PG, ("Started from unused header offset=%d\n", startAddr));
2536                         bRet = _TRUE;
2537                         break;
2538                 }
2539         }
2540         return bRet;
2541 }
2542
2543 static BOOLEAN
2544 hal_EfusePgCheckAvailableAddr(
2545         IN      PADAPTER        pAdapter,
2546         IN      u8                      efuseType,
2547         IN      BOOLEAN         bPseudoTest
2548         )
2549 {
2550         u16     efuse_max_available_len=0;
2551
2552         //Change to check TYPE_EFUSE_MAP_LEN ,beacuse 8188E raw 256,logic map over 256.
2553         EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&efuse_max_available_len, _FALSE);
2554         
2555         //EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&efuse_max_available_len, bPseudoTest);
2556         //RTPRINT(FEEPROM, EFUSE_PG, ("efuse_max_available_len = %d\n", efuse_max_available_len));
2557
2558         if(Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len)
2559         {
2560                 //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgCheckAvailableAddr error!!\n"));
2561                 return _FALSE;
2562         }
2563         return _TRUE;
2564 }
2565
2566 static VOID
2567 hal_EfuseConstructPGPkt(
2568                                         IN      u8                              offset,
2569                                         IN      u8                              word_en,
2570                                         IN      u8                              *pData,
2571                                         IN      PPGPKT_STRUCT   pTargetPkt
2572
2573 )
2574 {
2575         _rtw_memset((PVOID)pTargetPkt->data, 0xFF, sizeof(u8)*8);
2576         pTargetPkt->offset = offset;
2577         pTargetPkt->word_en= word_en;
2578         efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
2579         pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2580
2581         //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseConstructPGPkt(), targetPkt, offset=%d, word_en=0x%x, word_cnts=%d\n", pTargetPkt->offset, pTargetPkt->word_en, pTargetPkt->word_cnts));
2582 }
2583
2584 static BOOLEAN
2585 hal_EfusePgPacketWrite_BT(
2586                                         IN      PADAPTER        pAdapter,
2587                                         IN      u8                      offset,
2588                                         IN      u8                      word_en,
2589                                         IN      u8                      *pData,
2590                                         IN      BOOLEAN         bPseudoTest
2591                                         )
2592 {
2593         PGPKT_STRUCT    targetPkt;
2594         u16     startAddr=0;
2595         u8      efuseType=EFUSE_BT;
2596
2597         if(!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
2598                 return _FALSE;
2599
2600         hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2601
2602         if(!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2603                 return _FALSE;
2604
2605         if(!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2606                 return _FALSE;
2607
2608         if(!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2609                 return _FALSE;
2610
2611         return _TRUE;
2612 }
2613
2614 static BOOLEAN
2615 hal_EfusePgPacketWrite_8188e(
2616                                         IN      PADAPTER                pAdapter,
2617                                         IN      u8                      offset,
2618                                         IN      u8                      word_en,
2619                                         IN      u8                      *pData,
2620                                         IN      BOOLEAN         bPseudoTest
2621                                         )
2622 {
2623         PGPKT_STRUCT    targetPkt;
2624         u16                     startAddr=0;
2625         u8                      efuseType=EFUSE_WIFI;
2626
2627         if(!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
2628                 return _FALSE;
2629
2630         hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2631
2632         if(!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2633                 return _FALSE;
2634
2635         if(!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2636                 return _FALSE;
2637
2638         if(!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2639                 return _FALSE;
2640
2641         return _TRUE;
2642 }
2643
2644
2645 static int
2646 Hal_EfusePgPacketWrite_Pseudo(IN        PADAPTER        pAdapter,
2647                                         IN      u8                      offset,
2648                                         IN      u8                      word_en,
2649                                         IN      u8                      *data,
2650                                         IN      BOOLEAN         bPseudoTest)
2651 {
2652         int ret;
2653
2654         ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
2655
2656         return ret;
2657 }
2658
2659 static int
2660 Hal_EfusePgPacketWrite(IN       PADAPTER        pAdapter,
2661                                         IN      u8                      offset,
2662                                         IN      u8                      word_en,
2663                                         IN      u8                      *data,
2664                                         IN      BOOLEAN         bPseudoTest)
2665 {
2666         int     ret=0;
2667         ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
2668         
2669
2670         return ret;
2671 }
2672
2673 static int
2674 rtl8188e_Efuse_PgPacketWrite(IN PADAPTER        pAdapter,
2675                                         IN      u8                      offset,
2676                                         IN      u8                      word_en,
2677                                         IN      u8                      *data,
2678                                         IN      BOOLEAN         bPseudoTest)
2679 {
2680         int     ret;
2681
2682         if(bPseudoTest)
2683         {
2684                 ret = Hal_EfusePgPacketWrite_Pseudo(pAdapter, offset, word_en, data, bPseudoTest);
2685         }
2686         else
2687         {
2688                 ret = Hal_EfusePgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);
2689         }
2690         return ret;
2691 }
2692
2693 static void read_chip_version_8188e(PADAPTER padapter)
2694 {
2695         u32                             value32;
2696         HAL_DATA_TYPE   *pHalData;
2697
2698         pHalData = GET_HAL_DATA(padapter);
2699
2700         value32 = rtw_read32(padapter, REG_SYS_CFG);
2701         pHalData->VersionID.ICType = CHIP_8188E ;
2702         pHalData->VersionID.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
2703
2704         pHalData->VersionID.RFType = RF_TYPE_1T1R;
2705         pHalData->VersionID.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
2706         pHalData->VersionID.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; // IC version (CUT)
2707
2708         // For regulator mode. by tynli. 2011.01.14
2709         pHalData->RegulatorMode = ((value32 & TRP_BT_EN) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
2710
2711         pHalData->VersionID.ROMVer = 0; // ROM code version.    
2712         pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
2713         
2714         rtw_hal_config_rftype(padapter);
2715
2716 #if 1   
2717         dump_chip_info(pHalData->VersionID);
2718 #endif
2719
2720 }
2721
2722 void rtl8188e_start_thread(_adapter *padapter)
2723 {
2724 #if defined(CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)
2725 #ifndef CONFIG_SDIO_TX_TASKLET
2726         struct xmit_priv *xmitpriv = &padapter->xmitpriv;
2727
2728         xmitpriv->SdioXmitThread = kthread_run(rtl8188es_xmit_thread, padapter, "RTWHALXT");
2729         if (IS_ERR(xmitpriv->SdioXmitThread))
2730         {
2731                 RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: start rtl8188es_xmit_thread FAIL!!\n", __FUNCTION__));
2732         }
2733 #endif
2734 #endif
2735 }
2736
2737 void rtl8188e_stop_thread(_adapter *padapter)
2738 {
2739 #if defined(CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI)
2740 #ifndef CONFIG_SDIO_TX_TASKLET
2741         struct xmit_priv *xmitpriv = &padapter->xmitpriv;
2742
2743         // stop xmit_buf_thread
2744         if (xmitpriv->SdioXmitThread ) {
2745                 _rtw_up_sema(&xmitpriv->SdioXmitSema);
2746                 _rtw_down_sema(&xmitpriv->SdioXmitTerminateSema);
2747                 xmitpriv->SdioXmitThread = 0;
2748         }
2749 #endif
2750 #endif
2751 }
2752 void hal_notch_filter_8188e(_adapter *adapter, bool enable)
2753 {
2754         if (enable) {
2755                 DBG_871X("Enable notch filter\n");
2756                 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
2757         } else {
2758                 DBG_871X("Disable notch filter\n");
2759                 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
2760         }
2761 }
2762
2763 void UpdateHalRAMask8188E(PADAPTER padapter, u32 mac_id, u8 rssi_level)
2764 {
2765         u32     mask,rate_bitmap;
2766         u8      shortGIrate = _FALSE;
2767         struct sta_info *psta = NULL;
2768         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
2769         struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl;
2770
2771         if (mac_id < macid_ctl->num)
2772                 psta = macid_ctl->sta[mac_id];
2773         if (psta == NULL) {
2774                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" macid:%u, sta is NULL\n"
2775                         , FUNC_ADPT_ARG(padapter), mac_id);
2776                 return;
2777         }
2778
2779         shortGIrate = query_ra_short_GI(psta);
2780
2781         mask = psta->ra_mask;
2782
2783         rate_bitmap = 0xffffffff;                                       
2784         rate_bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv,mac_id,mask,rssi_level);
2785
2786         
2787         DBG_871X("%s => mac_id:%d, rate_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
2788                         __FUNCTION__,mac_id,psta->raid,psta->wireless_mode,mask,rssi_level,rate_bitmap);
2789
2790         mask &= rate_bitmap;
2791         
2792         if(pHalData->fw_ractrl == _TRUE)
2793         {
2794                 u8 arg[4] ={0};
2795
2796                 arg[0] = mac_id;//MACID
2797                 arg[1] = psta->raid;
2798                 arg[2] = shortGIrate;
2799                 arg[3] =  psta->init_rate;
2800                 rtl8188e_set_raid_cmd(padapter, mask,arg);
2801         }
2802         else
2803         {       
2804
2805 #if(RATE_ADAPTIVE_SUPPORT == 1) 
2806
2807                 ODM_RA_UpdateRateInfo_8188E(
2808                                 &(pHalData->odmpriv),
2809                                 mac_id,
2810                                 psta->raid, 
2811                                 mask,
2812                                 shortGIrate
2813                                 );
2814
2815 #endif          
2816         }
2817 }
2818
2819 void init_hal_spec_8188e(_adapter *adapter)
2820 {
2821         struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2822
2823         hal_spec->macid_num = MACID_NUM_88E;
2824         hal_spec->sec_cam_ent_num = SEC_CAM_ENT_NUM_88E;
2825         hal_spec->sec_cap = 0;
2826         hal_spec->nss_num = NSS_NUM_88E;
2827         hal_spec->band_cap = BAND_CAP_88E;
2828         hal_spec->bw_cap = BW_CAP_88E;
2829         hal_spec->proto_cap = PROTO_CAP_88E;
2830
2831         hal_spec->wl_func = 0
2832                                                 | WL_FUNC_P2P
2833                                                 | WL_FUNC_MIRACAST
2834                                                 | WL_FUNC_TDLS
2835                                                 ;
2836 }
2837
2838 void rtl8188e_init_default_value(_adapter *adapter)
2839 {
2840         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2841
2842         adapter->registrypriv.wireless_mode = WIRELESS_11BG_24N;
2843 }
2844
2845 void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
2846 {
2847         pHalFunc->dm_init = &rtl8188e_init_dm_priv;
2848         pHalFunc->dm_deinit = &rtl8188e_deinit_dm_priv;
2849
2850         pHalFunc->read_chip_version = read_chip_version_8188e;
2851
2852         pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8188E;
2853         pHalFunc->set_bwmode_handler = &PHY_SetBWMode8188E;
2854         pHalFunc->set_channel_handler = &PHY_SwChnl8188E;
2855         pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8188E;
2856
2857         pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8188E;
2858         pHalFunc->get_tx_power_level_handler = &PHY_GetTxPowerLevel8188E;
2859
2860         pHalFunc->hal_dm_watchdog = &rtl8188e_HalDmWatchDog;
2861
2862         pHalFunc->Add_RateATid = &rtl8188e_Add_RateATid;
2863
2864         pHalFunc->run_thread= &rtl8188e_start_thread;
2865         pHalFunc->cancel_thread= &rtl8188e_stop_thread;
2866
2867         pHalFunc->read_bbreg = &PHY_QueryBBReg8188E;
2868         pHalFunc->write_bbreg = &PHY_SetBBReg8188E;
2869         pHalFunc->read_rfreg = &PHY_QueryRFReg8188E;
2870         pHalFunc->write_rfreg = &PHY_SetRFReg8188E;
2871
2872
2873         // Efuse related function
2874         pHalFunc->EfusePowerSwitch = &rtl8188e_EfusePowerSwitch;
2875         pHalFunc->ReadEFuse = &rtl8188e_ReadEFuse;
2876         pHalFunc->EFUSEGetEfuseDefinition = &rtl8188e_EFUSE_GetEfuseDefinition;
2877         pHalFunc->EfuseGetCurrentSize = &rtl8188e_EfuseGetCurrentSize;
2878         pHalFunc->Efuse_PgPacketRead = &rtl8188e_Efuse_PgPacketRead;
2879         pHalFunc->Efuse_PgPacketWrite = &rtl8188e_Efuse_PgPacketWrite;
2880         pHalFunc->Efuse_WordEnableDataWrite = &rtl8188e_Efuse_WordEnableDataWrite;
2881
2882 #ifdef DBG_CONFIG_ERROR_DETECT
2883         pHalFunc->sreset_init_value = &sreset_init_value;
2884         pHalFunc->sreset_reset_value = &sreset_reset_value;
2885         pHalFunc->silentreset = &sreset_reset;
2886         pHalFunc->sreset_xmit_status_check = &rtl8188e_sreset_xmit_status_check;
2887         pHalFunc->sreset_linked_status_check  = &rtl8188e_sreset_linked_status_check;
2888         pHalFunc->sreset_get_wifi_status  = &sreset_get_wifi_status;
2889         pHalFunc->sreset_inprogress= &sreset_inprogress;
2890 #endif //DBG_CONFIG_ERROR_DETECT
2891
2892         pHalFunc->GetHalODMVarHandler = GetHalODMVar;
2893         pHalFunc->SetHalODMVarHandler = SetHalODMVar;
2894
2895 #ifdef CONFIG_IOL
2896         pHalFunc->IOL_exec_cmds_sync = &rtl8188e_IOL_exec_cmds_sync;
2897 #endif
2898
2899         pHalFunc->hal_notch_filter = &hal_notch_filter_8188e;
2900         pHalFunc->fill_h2c_cmd = &FillH2CCmd_88E;
2901         pHalFunc->fill_fake_txdesc = &rtl8188e_fill_fake_txdesc;
2902         pHalFunc->fw_dl = &rtl8188e_FirmwareDownload;
2903         pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8188E;
2904 }
2905
2906 u8 GetEEPROMSize8188E(PADAPTER padapter)
2907 {
2908         u8 size = 0;
2909         u32     cr;
2910
2911         cr = rtw_read16(padapter, REG_9346CR);
2912         // 6: EEPROM used is 93C46, 4: boot from E-Fuse.
2913         size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
2914
2915         MSG_8192C("EEPROM type is %s\n", size==4 ? "E-FUSE" : "93C46");
2916
2917         return size;
2918 }
2919
2920 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_PCI_HCI) || defined(CONFIG_GSPI_HCI)
2921 //-------------------------------------------------------------------------
2922 //
2923 // LLT R/W/Init function
2924 //
2925 //-------------------------------------------------------------------------
2926 s32 _LLTWrite(PADAPTER padapter, u32 address, u32 data)
2927 {
2928         s32     status = _SUCCESS;
2929         s8      count = POLLING_LLT_THRESHOLD;
2930         u32     value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
2931         
2932         rtw_write32(padapter, REG_LLT_INIT, value);
2933
2934         //polling
2935         do {
2936                 value = rtw_read32(padapter, REG_LLT_INIT);
2937                 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) {
2938                         break;
2939                 }
2940         } while (--count);
2941
2942         if(count<=0){
2943                 DBG_871X("Failed to polling write LLT done at address %d!\n", address);
2944                 status = _FAIL;
2945         }
2946
2947         return status;
2948 }
2949
2950 u8 _LLTRead(PADAPTER padapter, u32 address)
2951 {
2952         s32     count = POLLING_LLT_THRESHOLD;
2953         u32     value = _LLT_INIT_ADDR(address) | _LLT_OP(_LLT_READ_ACCESS);
2954         u16     LLTReg = REG_LLT_INIT;
2955
2956
2957         rtw_write32(padapter, LLTReg, value);
2958
2959         //polling and get value
2960         do {
2961                 value = rtw_read32(padapter, LLTReg);
2962                 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) {
2963                         return (u8)value;
2964                 }
2965         } while (--count);
2966         
2967         if (count <=0 ) {
2968                 RT_TRACE(_module_hal_init_c_, _drv_err_, ("Failed to polling read LLT done at address %d!\n", address));                
2969         }
2970         
2971
2972         return 0xFF;
2973 }
2974
2975 s32 InitLLTTable(PADAPTER padapter, u8 txpktbuf_bndy)
2976 {
2977         s32     status = _FAIL;
2978         u32     i;
2979         u32     Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER_8188E(padapter);// 176, 22k
2980         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2981
2982 #if defined(CONFIG_IOL_LLT)
2983         if(rtw_IOL_applied(padapter))
2984         {               
2985                 status = iol_InitLLTTable(padapter, txpktbuf_bndy);                     
2986         }
2987         else
2988 #endif
2989         {
2990                 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
2991                         status = _LLTWrite(padapter, i, i + 1);
2992                         if (_SUCCESS != status) {
2993                                 return status;
2994                         }
2995                 }
2996
2997                 // end of list
2998                 status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
2999                 if (_SUCCESS != status) {
3000                         return status;
3001                 }
3002
3003                 // Make the other pages as ring buffer
3004                 // This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer.
3005                 // Otherwise used as local loopback buffer.
3006                 for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
3007                         status = _LLTWrite(padapter, i, (i + 1));
3008                         if (_SUCCESS != status) {
3009                                 return status;
3010                         }
3011                 }
3012
3013                 // Let last entry point to the start entry of ring buffer
3014                 status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
3015                 if (_SUCCESS != status) {
3016                         return status;
3017                 }
3018         }
3019
3020         return status;
3021 }
3022 #endif
3023
3024
3025 void
3026 Hal_InitPGData88E(PADAPTER      padapter)
3027 {
3028
3029         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3030         u32                     i;
3031         u16                     value16;
3032
3033         if(_FALSE == pHalData->bautoload_fail_flag)
3034         { // autoload OK.
3035                 if (is_boot_from_eeprom(padapter))
3036                 {
3037                         // Read all Content from EEPROM or EFUSE.
3038                         for(i = 0; i < HWSET_MAX_SIZE; i += 2)
3039                         {
3040 //                              value16 = EF2Byte(ReadEEprom(pAdapter, (u2Byte) (i>>1)));
3041 //                              *((u16*)(&PROMContent[i])) = value16;
3042                         }
3043                 }
3044                 else
3045                 {
3046                         // Read EFUSE real map to shadow.
3047                         EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
3048                 }
3049         }
3050         else
3051         {//autoload fail
3052                 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n"));
3053 //              pHalData->AutoloadFailFlag = _TRUE;
3054                 //update to default value 0xFF
3055                 if (!is_boot_from_eeprom(padapter))
3056                         EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
3057         }
3058
3059 #ifdef CONFIG_EFUSE_CONFIG_FILE
3060         if (check_phy_efuse_tx_power_info_valid(padapter) == _FALSE) {
3061                 if (Hal_readPGDataFromConfigFile(padapter) != _SUCCESS)
3062                         DBG_871X_LEVEL(_drv_err_, "invalid phy efuse and read from file fail, will use driver default!!\n");
3063         }
3064 #endif
3065 }
3066
3067 void
3068 Hal_EfuseParseIDCode88E(
3069         IN      PADAPTER        padapter,
3070         IN      u8                      *hwinfo
3071         )
3072 {
3073         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3074         u16                     EEPROMId;
3075
3076
3077         // Checl 0x8129 again for making sure autoload status!!
3078         EEPROMId = le16_to_cpu(*((u16*)hwinfo));
3079         if (EEPROMId != RTL_EEPROM_ID)
3080         {
3081                 DBG_8192C("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
3082                 pHalData->bautoload_fail_flag = _TRUE;
3083         }
3084         else
3085         {
3086                 pHalData->bautoload_fail_flag = _FALSE;
3087         }
3088
3089         DBG_871X("EEPROM ID=0x%04x\n", EEPROMId);
3090 }
3091
3092 static void
3093 Hal_ReadPowerValueFromPROM_8188E(
3094         IN      PADAPTER                padapter,
3095         IN      PTxPowerInfo24G pwrInfo24G,
3096         IN      u8*                             PROMContent,
3097         IN      BOOLEAN                 AutoLoadFail
3098         )
3099 {
3100         u32 rfPath, eeAddr=EEPROM_TX_PWR_INX_88E, group,TxCount=0;
3101         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3102         
3103         _rtw_memset(pwrInfo24G, 0, sizeof(TxPowerInfo24G));
3104
3105         if(AutoLoadFail)
3106         {       
3107                 for(rfPath = 0 ; rfPath < pHalData->NumTotalRFPath ; rfPath++)
3108                 {
3109                         //2.4G default value
3110                         for(group = 0 ; group < MAX_CHNL_GROUP_24G; group++)
3111                         {
3112                                 pwrInfo24G->IndexCCK_Base[rfPath][group] =      EEPROM_DEFAULT_24G_INDEX;
3113                                 pwrInfo24G->IndexBW40_Base[rfPath][group] =     EEPROM_DEFAULT_24G_INDEX;
3114                         }
3115                         for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
3116                         {
3117                                 if(TxCount==0)
3118                                 {
3119                                         pwrInfo24G->BW20_Diff[rfPath][0] =      EEPROM_DEFAULT_24G_HT20_DIFF;
3120                                         pwrInfo24G->OFDM_Diff[rfPath][0] =      EEPROM_DEFAULT_24G_OFDM_DIFF;
3121                                 }
3122                                 else
3123                                 {
3124                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
3125                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
3126                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
3127                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
3128                                 }
3129                         }       
3130                         
3131                         
3132                 }
3133                 
3134                 //pHalData->bNOPG = TRUE;                               
3135                 return;
3136         }       
3137
3138         for(rfPath = 0 ; rfPath < pHalData->NumTotalRFPath ; rfPath++)
3139         {
3140                 //2.4G default value
3141                 for(group = 0 ; group < MAX_CHNL_GROUP_24G; group++)
3142                 {
3143                         //printk(" IndexCCK_Base rfPath:%d group:%d,eeAddr:0x%02x ",rfPath,group,eeAddr);
3144                         pwrInfo24G->IndexCCK_Base[rfPath][group] =      PROMContent[eeAddr++];
3145                         //printk(" IndexCCK_Base:%02x \n",pwrInfo24G->IndexCCK_Base[rfPath][group] );
3146                         if(pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
3147                         {
3148                                 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
3149 //                              pHalData->bNOPG = TRUE;                                                         
3150                         }
3151                 }
3152                 for(group = 0 ; group < MAX_CHNL_GROUP_24G-1; group++)
3153                 {
3154                         //printk(" IndexBW40_Base rfPath:%d group:%d,eeAddr:0x%02x ",rfPath,group,eeAddr);
3155                         pwrInfo24G->IndexBW40_Base[rfPath][group] =     PROMContent[eeAddr++];
3156                         //printk(" IndexBW40_Base: %02x \n",pwrInfo24G->IndexBW40_Base[rfPath][group]  );
3157                         if(pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
3158                                 pwrInfo24G->IndexBW40_Base[rfPath][group] =     EEPROM_DEFAULT_24G_INDEX;
3159                 }                       
3160                 for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++)
3161                 {
3162                         if(TxCount==0)
3163                         {
3164                                 pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
3165                                 pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
3166                                 if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)              /*4bit sign number to 8 bit sign number*/
3167                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
3168
3169                                 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
3170                                 if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)              /*4bit sign number to 8 bit sign number*/
3171                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
3172                 
3173                                 pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
3174                                 eeAddr++;
3175                         } else{
3176                                 pwrInfo24G->BW40_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
3177                                 if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT3)              /*4bit sign number to 8 bit sign number*/
3178                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
3179
3180
3181                                 pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);                            
3182                                 if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)              /*4bit sign number to 8 bit sign number*/
3183                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
3184                                 eeAddr++;
3185                                 
3186                                 pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0xf0)>>4;
3187                                 if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)              /*4bit sign number to 8 bit sign number*/
3188                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
3189
3190                                 pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
3191                                 if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT3)               /*4bit sign number to 8 bit sign number*/
3192                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
3193
3194                                 eeAddr++;
3195                         }
3196                 }
3197
3198         }
3199
3200
3201 }
3202
3203 static u8
3204 Hal_GetChnlGroup(
3205         IN      u8 chnl
3206         )
3207 {
3208         u8      group=0;
3209
3210         if (chnl < 3)                   // Cjanel 1-3
3211                 group = 0;
3212         else if (chnl < 9)              // Channel 4-9
3213                 group = 1;
3214         else                                    // Channel 10-14
3215                 group = 2;
3216
3217         return group;
3218 }
3219 static u8 
3220 Hal_GetChnlGroup88E(
3221         IN      u8      chnl,
3222         OUT u8* pGroup
3223         )
3224 {
3225         u8 bIn24G=_TRUE;
3226
3227         if(chnl<=14)
3228         {
3229                 bIn24G=_TRUE;
3230
3231                 if (chnl < 3)                   // Chanel 1-2
3232                         *pGroup = 0;
3233                 else if (chnl < 6)              // Channel 3-5
3234                         *pGroup = 1;
3235                 else     if(chnl <9)            // Channel 6-8
3236                         *pGroup = 2;
3237                 else if(chnl <12)               // Channel 9-11
3238                         *pGroup = 3;
3239                 else if(chnl <14)               // Channel 12-13
3240                         *pGroup = 4;
3241                 else if(chnl ==14)              // Channel 14
3242                         *pGroup = 5;    
3243                 else
3244                 {
3245                         //RT_TRACE(COMP_EFUSE,DBG_LOUD,("==>Hal_GetChnlGroup88E in 2.4 G, but Channel %d in Group not found \n",chnl));
3246                 }
3247         }
3248         else
3249         {
3250                 bIn24G=_FALSE;
3251                 
3252                 if (chnl <=40)  
3253                         *pGroup = 0;
3254                 else if (chnl <=48)
3255                         *pGroup = 1;
3256                 else     if(chnl <=56)  
3257                         *pGroup = 2;
3258                 else if(chnl <=64)      
3259                         *pGroup = 3;
3260                 else if(chnl <=104)
3261                         *pGroup = 4;
3262                 else if(chnl <=112)
3263                         *pGroup = 5;    
3264                 else if(chnl <=120)
3265                         *pGroup = 5;    
3266                 else if(chnl <=128)
3267                         *pGroup = 6;            
3268                 else if(chnl <=136)
3269                         *pGroup = 7;            
3270                 else if(chnl <=144)
3271                         *pGroup = 8;            
3272                 else if(chnl <=153)
3273                         *pGroup = 9;            
3274                 else if(chnl <=161)
3275                         *pGroup = 10;           
3276                 else if(chnl <=177)
3277                         *pGroup = 11;   
3278                 else
3279                 {
3280                         //RT_TRACE(COMP_EFUSE,DBG_LOUD,("==>Hal_GetChnlGroup88E in 5G, but Channel %d in Group not found \n",chnl));
3281                 }
3282
3283         }
3284         //RT_TRACE(COMP_EFUSE,DBG_LOUD,("<==Hal_GetChnlGroup88E,  Channel = %d, bIn24G =%d,\n",chnl,bIn24G));
3285         return bIn24G;
3286 }
3287
3288 void Hal_ReadPowerSavingMode88E(
3289         PADAPTER                padapter,
3290         IN      u8*                     hwinfo,
3291         IN      BOOLEAN                 AutoLoadFail
3292         )
3293 {
3294         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3295         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
3296         u8 tmpvalue;
3297
3298         if(AutoLoadFail){
3299                 pwrctl->bHWPowerdown = _FALSE;
3300                 pwrctl->bSupportRemoteWakeup = _FALSE;
3301         }
3302         else    {               
3303
3304                 //hw power down mode selection , 0:rf-off / 1:power down
3305
3306                 if(padapter->registrypriv.hwpdn_mode==2)
3307                         pwrctl->bHWPowerdown = (hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & BIT4);
3308                 else
3309                         pwrctl->bHWPowerdown = padapter->registrypriv.hwpdn_mode;
3310                                 
3311                 // decide hw if support remote wakeup function
3312                 // if hw supported, 8051 (SIE) will generate WeakUP signal( D+/D- toggle) when autoresume
3313 #ifdef CONFIG_USB_HCI
3314                 pwrctl->bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT1)?_TRUE :_FALSE;
3315 #endif //CONFIG_USB_HCI
3316         
3317                 DBG_8192C("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) ,bSupportRemoteWakeup(%x)\n",__FUNCTION__,
3318                         pwrctl->bHWPwrPindetect, pwrctl->bHWPowerdown, pwrctl->bSupportRemoteWakeup);
3319
3320                 DBG_8192C("### PS params=>  power_mgnt(%x),usbss_enable(%x) ###\n",padapter->registrypriv.power_mgnt,padapter->registrypriv.usbss_enable);
3321         
3322         }
3323
3324 }
3325
3326 void
3327 Hal_ReadTxPowerInfo88E(
3328         IN      PADAPTER                padapter,
3329         IN      u8*                             PROMContent,
3330         IN      BOOLEAN                 AutoLoadFail
3331         )
3332 {       
3333         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3334         TxPowerInfo24G          pwrInfo24G;
3335         u8                      rfPath, ch, group=0, rfPathMax=1;
3336         u8                      pwr, diff,bIn24G,TxCount;
3337
3338
3339         Hal_ReadPowerValueFromPROM_8188E(padapter, &pwrInfo24G, PROMContent, AutoLoadFail);
3340
3341         if(!AutoLoadFail)
3342                 pHalData->bTXPowerDataReadFromEEPORM = TRUE;            
3343
3344         //for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
3345         for(rfPath = 0 ; rfPath < pHalData->NumTotalRFPath ; rfPath++)
3346         {
3347                 for (ch = 0; ch < CENTER_CH_2G_NUM; ch++) {
3348                         bIn24G = Hal_GetChnlGroup88E(ch+1,&group);
3349                         if(bIn24G)
3350                         {
3351
3352                                 pHalData->Index24G_CCK_Base[rfPath][ch]=pwrInfo24G.IndexCCK_Base[rfPath][group];
3353
3354                                 if(ch==(14-1))
3355                                         pHalData->Index24G_BW40_Base[rfPath][ch]=pwrInfo24G.IndexBW40_Base[rfPath][4];
3356                                 else
3357                                         pHalData->Index24G_BW40_Base[rfPath][ch]=pwrInfo24G.IndexBW40_Base[rfPath][group];
3358                         }
3359                         
3360                         if(bIn24G)
3361                         {
3362                                 DBG_871X("======= Path %d, Channel %d =======\n",rfPath,ch+1 );                 
3363                                 DBG_871X("Index24G_CCK_Base[%d][%d] = 0x%x\n",rfPath,ch+1 ,pHalData->Index24G_CCK_Base[rfPath][ch]);
3364                                 DBG_871X("Index24G_BW40_Base[%d][%d] = 0x%x\n",rfPath,ch+1 ,pHalData->Index24G_BW40_Base[rfPath][ch]);                  
3365                         }                       
3366                 }       
3367
3368                 for(TxCount=0;TxCount<MAX_TX_COUNT_8188E;TxCount++)
3369                 {
3370                         pHalData->CCK_24G_Diff[rfPath][TxCount]=pwrInfo24G.CCK_Diff[rfPath][TxCount];
3371                         pHalData->OFDM_24G_Diff[rfPath][TxCount]=pwrInfo24G.OFDM_Diff[rfPath][TxCount];
3372                         pHalData->BW20_24G_Diff[rfPath][TxCount]=pwrInfo24G.BW20_Diff[rfPath][TxCount];
3373                         pHalData->BW40_24G_Diff[rfPath][TxCount]=pwrInfo24G.BW40_Diff[rfPath][TxCount];
3374 #if DBG                 
3375                         DBG_871X("======= TxCount %d =======\n",TxCount );      
3376                         DBG_871X("CCK_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->CCK_24G_Diff[rfPath][TxCount]);
3377                         DBG_871X("OFDM_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->OFDM_24G_Diff[rfPath][TxCount]);
3378                         DBG_871X("BW20_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->BW20_24G_Diff[rfPath][TxCount]);
3379                         DBG_871X("BW40_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->BW40_24G_Diff[rfPath][TxCount]);
3380 #endif                                                  
3381                 }
3382         }
3383
3384         
3385         // 2010/10/19 MH Add Regulator recognize for EU.
3386         if(!AutoLoadFail)
3387         {
3388                 struct registry_priv  *registry_par = &padapter->registrypriv;
3389                 
3390                 if(PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
3391                         pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION&0x7); //bit0~2
3392                 else
3393                         pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E]&0x7);     //bit0~2
3394                 
3395         }
3396         else
3397         {
3398                 pHalData->EEPROMRegulatory = 0;
3399         }
3400         DBG_871X("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory);
3401
3402 }
3403
3404
3405 VOID
3406 Hal_EfuseParseXtal_8188E(
3407         IN      PADAPTER                pAdapter,
3408         IN      u8*                     hwinfo,
3409         IN      BOOLEAN         AutoLoadFail
3410         )
3411 {
3412         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
3413
3414         if(!AutoLoadFail)
3415         {
3416                 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_88E];
3417                 if(pHalData->CrystalCap == 0xFF)
3418                         pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;   
3419         }
3420         else
3421         {
3422                 pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
3423         }
3424         DBG_871X("CrystalCap: 0x%2x\n", pHalData->CrystalCap);
3425 }
3426
3427 void
3428 Hal_EfuseParseBoardType88E(
3429         IN      PADAPTER                pAdapter,
3430         IN      u8*                             hwinfo,
3431         IN      BOOLEAN                 AutoLoadFail
3432         )
3433 {
3434         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
3435
3436         if (!AutoLoadFail) {
3437                 pHalData->InterfaceSel = ((hwinfo[EEPROM_RF_BOARD_OPTION_88E]&0xE0)>>5);
3438                 if(hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
3439                         pHalData->InterfaceSel = (EEPROM_DEFAULT_BOARD_OPTION&0xE0)>>5;
3440         }
3441         else {
3442                 pHalData->InterfaceSel = 0;
3443         }
3444         DBG_871X("Board Type: 0x%2x\n", pHalData->InterfaceSel);
3445 }
3446
3447 void
3448 Hal_EfuseParseEEPROMVer88E(
3449         IN      PADAPTER                padapter,
3450         IN      u8*                     hwinfo,
3451         IN      BOOLEAN                 AutoLoadFail
3452         )
3453 {
3454         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3455
3456         if(!AutoLoadFail){              
3457                 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_88E];
3458                 if(pHalData->EEPROMVersion == 0xFF)
3459                         pHalData->EEPROMVersion = EEPROM_Default_Version;                               
3460         }
3461         else{
3462                 pHalData->EEPROMVersion = 1;
3463         }
3464         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
3465                 pHalData->EEPROMVersion));
3466 }
3467
3468 void
3469 rtl8188e_EfuseParseChnlPlan(
3470         IN      PADAPTER                padapter,
3471         IN      u8*                     hwinfo,
3472         IN      BOOLEAN                 AutoLoadFail
3473         )
3474 {
3475         padapter->mlmepriv.ChannelPlan = hal_com_config_channel_plan(
3476                 padapter
3477                 , hwinfo ? &hwinfo[EEPROM_COUNTRY_CODE_88E] : NULL
3478                 , hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF
3479                 , padapter->registrypriv.alpha2
3480                 , padapter->registrypriv.channel_plan
3481                 , RTW_CHPLAN_WORLD_NULL
3482                 , AutoLoadFail
3483         );
3484 }
3485
3486 void
3487 Hal_EfuseParseCustomerID88E(
3488         IN      PADAPTER                padapter,
3489         IN      u8*                     hwinfo,
3490         IN      BOOLEAN                 AutoLoadFail
3491         )
3492 {
3493         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3494
3495         if (!AutoLoadFail)
3496         {
3497                 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_88E];
3498                 //pHalData->EEPROMSubCustomerID = hwinfo[EEPROM_CustomID_88E];
3499         }
3500         else
3501         {
3502                 pHalData->EEPROMCustomerID = 0;
3503                 pHalData->EEPROMSubCustomerID = 0;
3504         }
3505         DBG_871X("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID);
3506         //DBG_871X("EEPROM SubCustomer ID: 0x%02x\n", pHalData->EEPROMSubCustomerID);
3507 }
3508
3509
3510 void
3511 Hal_ReadAntennaDiversity88E(
3512         IN      PADAPTER                pAdapter,
3513         IN      u8*                             PROMContent,
3514         IN      BOOLEAN                 AutoLoadFail
3515         )
3516 {
3517         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
3518         struct registry_priv    *registry_par = &pAdapter->registrypriv;        
3519
3520         if(!AutoLoadFail)
3521         {       
3522                 // Antenna Diversity setting.
3523                 if(registry_par->antdiv_cfg == 2)// 2:By EFUSE
3524                 {
3525                         pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E]&0x18)>>3;
3526                         if(PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)                     
3527                                 pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION&0x18)>>3;
3528                 }
3529                 else
3530                 {
3531                         pHalData->AntDivCfg = registry_par->antdiv_cfg ;  // 0:OFF , 1:ON, 2:By EFUSE
3532                 }
3533
3534                 if(registry_par->antdiv_type == 0)// If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead.
3535                 {
3536                         pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E];
3537                         if (pHalData->TRxAntDivType == 0xFF)
3538                                 pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; // For 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port)
3539                 }
3540                 else{
3541                         pHalData->TRxAntDivType = registry_par->antdiv_type ;
3542                 }
3543                         
3544                 if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV)
3545                         pHalData->AntDivCfg = 1; // 0xC1[3] is ignored.
3546         }
3547         else
3548         {
3549                 pHalData->AntDivCfg = 0;
3550         }
3551         
3552         DBG_871X("EEPROM : AntDivCfg = %x, TRxAntDivType = %x\n",pHalData->AntDivCfg, pHalData->TRxAntDivType);
3553
3554
3555 }
3556
3557 void
3558 Hal_ReadThermalMeter_88E(
3559         IN      PADAPTER        Adapter,        
3560         IN      u8*                     PROMContent,
3561         IN      BOOLEAN         AutoloadFail
3562         )
3563 {
3564         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
3565         u1Byte                  tempval;
3566
3567         //
3568         // ThermalMeter from EEPROM
3569         //
3570         if(!AutoloadFail)       
3571                 pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_88E];
3572         else
3573                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
3574 //      pHalData->EEPROMThermalMeter = (tempval&0x1f);  //[4:0]
3575
3576         if(pHalData->EEPROMThermalMeter == 0xff || AutoloadFail)
3577         {
3578                 pHalData->odmpriv.RFCalibrateInfo.bAPKThermalMeterIgnore = _TRUE;
3579                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;         
3580         }
3581
3582         //pHalData->ThermalMeter[0] = pHalData->EEPROMThermalMeter;     
3583         DBG_871X("ThermalMeter = 0x%x\n", pHalData->EEPROMThermalMeter);        
3584
3585 }
3586
3587 #ifdef CONFIG_RF_POWER_TRIM
3588 void Hal_ReadRFGainOffset(
3589         IN              PADAPTER        Adapter,
3590         IN              u8*             PROMContent,
3591         IN              BOOLEAN         AutoloadFail)
3592 {
3593         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
3594         u8 thermal_offset=0;
3595         //
3596         // BB_RF Gain Offset from EEPROM
3597         //
3598
3599         if (!AutoloadFail) {
3600                 pHalData->EEPROMRFGainOffset =PROMContent[EEPROM_RF_GAIN_OFFSET];
3601
3602                 if((pHalData->EEPROMRFGainOffset  != 0xFF) && 
3603                         (pHalData->EEPROMRFGainOffset & BIT4)){
3604                         pHalData->EEPROMRFGainVal = EFUSE_Read1Byte(Adapter, EEPROM_RF_GAIN_VAL);
3605                 }else{
3606                         pHalData->EEPROMRFGainOffset = 0;
3607                         pHalData->EEPROMRFGainVal = 0;                  
3608                 }
3609                 
3610                 DBG_871X("pHalData->EEPROMRFGainVal=%x\n", pHalData->EEPROMRFGainVal);
3611         } else {
3612                 pHalData->EEPROMRFGainVal=EFUSE_Read1Byte(Adapter,EEPROM_RF_GAIN_VAL);
3613                 
3614                 if(pHalData->EEPROMRFGainVal != 0xFF)
3615                         pHalData->EEPROMRFGainOffset = BIT4;
3616                 else
3617                         pHalData->EEPROMRFGainOffset = 0;
3618                 DBG_871X("else AutoloadFail =%x,\n", AutoloadFail);
3619         }
3620
3621         if (Adapter->registrypriv.RegPwrTrimEnable == 1) {
3622                         pHalData->EEPROMRFGainVal = EFUSE_Read1Byte(Adapter, EEPROM_RF_GAIN_VAL);
3623                         DBG_871X("pHalData->EEPROMRFGainVal=%x\n", pHalData->EEPROMRFGainVal);
3624
3625         }
3626         //
3627         // BB_RF Thermal Offset from EEPROM
3628         //
3629         if (((pHalData->EEPROMRFGainOffset != 0xFF) && (pHalData->EEPROMRFGainOffset & BIT4)) || (Adapter->registrypriv.RegPwrTrimEnable == 1)) {
3630
3631                 thermal_offset = EFUSE_Read1Byte(Adapter, EEPROM_THERMAL_OFFSET);
3632                 if (thermal_offset != 0xFF) {
3633                         if (thermal_offset & BIT0)
3634                                 pHalData->EEPROMThermalMeter += ((thermal_offset>>1) & 0x0F);
3635                         else
3636                                 pHalData->EEPROMThermalMeter -= ((thermal_offset>>1) & 0x0F);
3637
3638                         DBG_871X("%s =>thermal_offset:0x%02x pHalData->EEPROMThermalMeter=0x%02x\n",__FUNCTION__ ,thermal_offset,pHalData->EEPROMThermalMeter);
3639                 }               
3640         }       
3641
3642         DBG_871X("%s => EEPRORFGainOffset = 0x%02x,EEPROMRFGainVal=0x%02x,thermal_offset:0x%02x \n",
3643                 __FUNCTION__, pHalData->EEPROMRFGainOffset,pHalData->EEPROMRFGainVal,thermal_offset);
3644         
3645 }
3646
3647 #endif /*CONFIG_RF_POWER_TRIM*/
3648
3649 BOOLEAN HalDetectPwrDownMode88E(PADAPTER Adapter)
3650 {
3651         u8 tmpvalue = 0;
3652         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3653         struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(Adapter);
3654
3655         EFUSE_ShadowRead(Adapter, 1, EEPROM_RF_FEATURE_OPTION_88E, (u32 *)&tmpvalue);
3656
3657         // 2010/08/25 MH INF priority > PDN Efuse value.
3658         if(tmpvalue & BIT(4) && pwrctrlpriv->reg_pdnmode)
3659         {
3660                 pHalData->pwrdown = _TRUE;
3661         }
3662         else
3663         {
3664                 pHalData->pwrdown = _FALSE;
3665         }
3666
3667         DBG_8192C("HalDetectPwrDownMode(): PDN=%d\n", pHalData->pwrdown);
3668
3669         return pHalData->pwrdown;
3670 }       // HalDetectPwrDownMode
3671
3672 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
3673 void Hal_DetectWoWMode(PADAPTER pAdapter)
3674 {
3675         adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = _TRUE;
3676 }
3677 #endif
3678
3679 //====================================================================================
3680 //
3681 // 20100209 Joseph:
3682 // This function is used only for 92C to set REG_BCN_CTRL(0x550) register.
3683 // We just reserve the value of the register in variable pHalData->RegBcnCtrlVal and then operate
3684 // the value of the register via atomic operation.
3685 // This prevents from race condition when setting this register.
3686 // The value of pHalData->RegBcnCtrlVal is initialized in HwConfigureRTL8192CE() function.
3687 //
3688 void SetBcnCtrlReg(
3689         PADAPTER        padapter,
3690         u8              SetBits,
3691         u8              ClearBits)
3692 {
3693         PHAL_DATA_TYPE pHalData;
3694
3695
3696         pHalData = GET_HAL_DATA(padapter);
3697
3698         pHalData->RegBcnCtrlVal |= SetBits;
3699         pHalData->RegBcnCtrlVal &= ~ClearBits;
3700
3701 #if 0
3702 //#ifdef CONFIG_SDIO_HCI
3703         if (pHalData->sdio_himr & (SDIO_HIMR_TXBCNOK_MSK | SDIO_HIMR_TXBCNERR_MSK))
3704                 pHalData->RegBcnCtrlVal |= EN_TXBCN_RPT;
3705 #endif
3706
3707         rtw_write8(padapter, REG_BCN_CTRL, (u8)pHalData->RegBcnCtrlVal);
3708 }
3709
3710 void _InitTransferPageSize(PADAPTER padapter)
3711 {
3712         // Tx page size is always 128.
3713
3714         u8 value8;
3715         value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
3716         rtw_write8(padapter, REG_PBP, value8);
3717 }
3718
3719 void ResumeTxBeacon(PADAPTER padapter)
3720 {
3721         HAL_DATA_TYPE*  pHalData = GET_HAL_DATA(padapter);
3722
3723         // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
3724         // which should be read from register to a global variable.
3725
3726         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
3727
3728         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl) | BIT6);
3729         pHalData->RegFwHwTxQCtrl |= BIT6;
3730         rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0xff);
3731         pHalData->RegReg542 |= BIT0;
3732         rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
3733 }
3734
3735 void StopTxBeacon(PADAPTER padapter)
3736 {
3737         HAL_DATA_TYPE*  pHalData = GET_HAL_DATA(padapter);
3738
3739         // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
3740         // which should be read from register to a global variable.
3741
3742         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
3743
3744         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl) & (~BIT6));
3745         pHalData->RegFwHwTxQCtrl &= (~BIT6);
3746         rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64);
3747         pHalData->RegReg542 &= ~(BIT0);
3748         rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
3749
3750         CheckFwRsvdPageContent(padapter);  // 2010.06.23. Added by tynli.
3751 }
3752
3753 static void hw_var_set_monitor(PADAPTER Adapter, u8 variable, u8 *val)
3754 {
3755         u32     value_rcr, rcr_bits;
3756         u16     value_rxfltmap2;
3757         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3758         struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
3759
3760         if (*((u8 *)val) == _HW_STATE_MONITOR_) {
3761
3762                 /* Leave IPS */
3763                 rtw_pm_set_ips(Adapter, IPS_NONE);
3764                 LeaveAllPowerSaveMode(Adapter);
3765
3766                 /* Receive all type */
3767                 rcr_bits = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_ACF | RCR_AMF | RCR_APP_PHYST_RXFF;
3768
3769                 /* Append FCS */
3770                 rcr_bits |= RCR_APPFCS;
3771
3772                 #if 0
3773                 /* 
3774                    CRC and ICV packet will drop in recvbuf2recvframe()
3775                    We no turn on it.
3776                  */
3777                 rcr_bits |= (RCR_ACRC32 | RCR_AICV);
3778                 #endif
3779
3780                 /* Receive all data frames */
3781                 value_rxfltmap2 = 0xFFFF;
3782
3783                 value_rcr = rcr_bits;
3784                 rtw_write32(Adapter, REG_RCR, value_rcr);
3785
3786                 rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2);
3787
3788                 #if 0
3789                 /* tx pause */
3790                 rtw_write8(padapter, REG_TXPAUSE, 0xFF);
3791                 #endif
3792         } else {
3793                 /* do nothing */
3794         }
3795
3796 }
3797
3798 static void hw_var_set_opmode(PADAPTER Adapter, u8 variable, u8* val)
3799 {
3800         u8      val8;
3801         u8      mode = *((u8 *)val);
3802         static u8 isMonitor = _FALSE;
3803
3804         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3805
3806         if (isMonitor == _TRUE) {
3807                 /* reset RCR */
3808                 rtw_write32(Adapter, REG_RCR, pHalData->ReceiveConfig);
3809                 isMonitor = _FALSE;
3810         }
3811
3812         DBG_871X( ADPT_FMT "Port-%d  set opmode = %d\n",ADPT_ARG(Adapter),
3813                 get_iface_type(Adapter), mode);
3814         
3815         if (mode == _HW_STATE_MONITOR_) {
3816                 isMonitor = _TRUE;
3817                 /* set net_type */
3818                 Set_MSR(Adapter, _HW_STATE_NOLINK_);
3819
3820                 hw_var_set_monitor(Adapter, variable, val);
3821                 return;
3822         }
3823
3824 #ifdef CONFIG_CONCURRENT_MODE
3825         if(Adapter->iface_type == IFACE_PORT1)
3826         {
3827                 // disable Port1 TSF update
3828                 rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(4));
3829                 
3830                 // set net_type         
3831                 Set_MSR(Adapter, mode);
3832
3833                 if((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
3834                 {
3835                         if(!check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE))                      
3836                         {
3837                                 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
3838                                 #ifdef  CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT  
3839                                 rtw_write8(Adapter, REG_DRVERLYINT, 0x05);//restore early int time to 5ms
3840
3841                                 #if defined(CONFIG_USB_HCI)
3842                                 UpdateInterruptMask8188EU(Adapter,_TRUE, 0, IMR_BCNDMAINT0_88E);        
3843                                 #elif defined(CONFIG_SDIO_HCI)
3844                                 UpdateInterruptMask8188ESdio(Adapter, 0, SDIO_HIMR_BCNERLY_INT_MSK);                            
3845                                 #endif 
3846                                 
3847                                 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3848                                 
3849                                 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
3850                                 #if defined(CONFIG_USB_HCI)
3851                                 UpdateInterruptMask8188EU(Adapter,_TRUE ,0, (IMR_TBDER_88E|IMR_TBDOK_88E));
3852                                 #elif defined(CONFIG_SDIO_HCI)
3853                                 UpdateInterruptMask8188ESdio(Adapter, 0, (SDIO_HIMR_TXBCNOK_MSK|SDIO_HIMR_TXBCNERR_MSK));                               
3854                                 #endif
3855                                 
3856                                 #endif// CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
3857                                 #endif //CONFIG_INTERRUPT_BASED_TXBCN           
3858
3859                                 StopTxBeacon(Adapter);
3860                                 #if defined(CONFIG_PCI_HCI)
3861                                 UpdateInterruptMask8188EE( Adapter, 0, 0, RT_BCN_INT_MASKS, 0);
3862                                 #endif
3863                         }
3864                         
3865                         rtw_write8(Adapter,REG_BCN_CTRL_1, 0x11);//disable atim wnd and disable beacon function
3866                         //rtw_write8(Adapter,REG_BCN_CTRL_1, 0x18);
3867                 }
3868                 else if((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
3869                 {       
3870                         //Beacon is polled to TXBUF
3871                         rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR)|BIT(8));
3872                         
3873                         ResumeTxBeacon(Adapter);
3874                         rtw_write8(Adapter,REG_BCN_CTRL_1, 0x1a);
3875                         //BIT4 - If set 0, hw will clr bcnq when tx becon ok/fail or port 1
3876                         rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM)|BIT(3)|BIT(4));
3877                 }
3878                 else if(mode == _HW_STATE_AP_)
3879                 {
3880                         #ifdef CONFIG_INTERRUPT_BASED_TXBCN                     
3881                         #ifdef  CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3882                         #if defined(CONFIG_USB_HCI)
3883                         UpdateInterruptMask8188EU(Adapter,_TRUE ,IMR_BCNDMAINT0_88E, 0);
3884                         #elif defined(CONFIG_SDIO_HCI)
3885                         UpdateInterruptMask8188ESdio(Adapter, SDIO_HIMR_BCNERLY_INT_MSK, 0);
3886                         #endif
3887                         #endif//CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3888
3889                         #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR  
3890                         #if defined(CONFIG_USB_HCI)
3891                         UpdateInterruptMask8188EU(Adapter,_TRUE ,(IMR_TBDER_88E|IMR_TBDOK_88E), 0);
3892                         #elif defined(CONFIG_SDIO_HCI)
3893                         UpdateInterruptMask8188ESdio(Adapter, (SDIO_HIMR_TXBCNOK_MSK|SDIO_HIMR_TXBCNERR_MSK), 0);
3894                         #endif
3895                         #endif//CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
3896                                         
3897                         #endif //CONFIG_INTERRUPT_BASED_TXBCN
3898
3899                         ResumeTxBeacon(Adapter);
3900                                         
3901                         rtw_write8(Adapter, REG_BCN_CTRL_1, 0x12);
3902
3903                         //Beacon is polled to TXBUF
3904                         rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR)|BIT(8));
3905
3906                         //Set RCR
3907                         //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
3908                         rtw_write32(Adapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,Reject ICV_ERROR packets
3909                         
3910                         //enable to rx data frame                               
3911                         rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
3912                         //enable to rx ps-poll
3913                         rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400);
3914
3915                         //Beacon Control related register for first time 
3916                         rtw_write8(Adapter, REG_BCNDMATIM, 0x02); // 2ms                
3917                         rtw_write8(Adapter, REG_DRVERLYINT, 0x05);// 5ms
3918                         //rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);
3919                         rtw_write8(Adapter, REG_ATIMWND_1, 0x0a); // 10ms for port1
3920                         rtw_write16(Adapter, REG_BCNTCFG, 0x00);
3921                         rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
3922                         rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
3923         
3924                         //reset TSF2    
3925                         rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1));
3926
3927
3928                         //BIT4 - If set 0, hw will clr bcnq when tx becon ok/fail or port 1
3929                         rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM)|BIT(3)|BIT(4));
3930                         //enable BCN1 Function for if2
3931                         //don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received)
3932                         rtw_write8(Adapter, REG_BCN_CTRL_1, (DIS_TSF_UDT0_NORMAL_CHIP|EN_BCN_FUNCTION | EN_TXBCN_RPT|BIT(1)));
3933
3934 #ifdef CONFIG_CONCURRENT_MODE
3935                         if(check_buddy_fwstate(Adapter, WIFI_FW_NULL_STATE))
3936                                 rtw_write8(Adapter, REG_BCN_CTRL, 
3937                                         rtw_read8(Adapter, REG_BCN_CTRL) & ~EN_BCN_FUNCTION);
3938 #endif
3939                     //BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked
3940                         //rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(5));
3941                         //rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(3));
3942                                         
3943                         //dis BCN0 ATIM  WND if if1 is station
3944                         rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(0));
3945
3946 #ifdef CONFIG_TSF_RESET_OFFLOAD
3947                         // Reset TSF for STA+AP concurrent mode
3948                         if ( check_buddy_fwstate(Adapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)) ) {
3949                                 if (reset_tsf(Adapter, IFACE_PORT1) == _FALSE)
3950                                         DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
3951                                                 __FUNCTION__, __LINE__);
3952                         }
3953 #endif  // CONFIG_TSF_RESET_OFFLOAD
3954 #if defined(CONFIG_PCI_HCI) 
3955                         UpdateInterruptMask8188EE( Adapter, RT_BCN_INT_MASKS, 0, 0, 0);
3956 #endif  
3957                 }
3958         }
3959         else    // (Adapter->iface_type == IFACE_PORT1)
3960 #endif //CONFIG_CONCURRENT_MODE
3961         {
3962                 // disable Port0 TSF update
3963                 rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
3964                 
3965                 // set net_type
3966                 Set_MSR(Adapter, mode);
3967                 
3968                 if((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
3969                 {
3970 #ifdef CONFIG_CONCURRENT_MODE
3971                         if(!check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE))              
3972 #endif //CONFIG_CONCURRENT_MODE
3973                         {
3974                                 #ifdef CONFIG_INTERRUPT_BASED_TXBCN     
3975                                 #ifdef  CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3976                                 rtw_write8(Adapter, REG_DRVERLYINT, 0x05);//restore early int time to 5ms       
3977                                 #if defined(CONFIG_USB_HCI)
3978                                 UpdateInterruptMask8188EU(Adapter,_TRUE, 0, IMR_BCNDMAINT0_88E);
3979                                 #elif defined(CONFIG_SDIO_HCI)
3980                                 UpdateInterruptMask8188ESdio(Adapter, 0, SDIO_HIMR_BCNERLY_INT_MSK);    
3981                                 #endif
3982                                 #endif//CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3983                                 
3984                                 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR          
3985                                 #if defined(CONFIG_USB_HCI)
3986                                 UpdateInterruptMask8188EU(Adapter,_TRUE ,0, (IMR_TBDER_88E|IMR_TBDOK_88E));
3987                                 #elif defined(CONFIG_SDIO_HCI)
3988                                 UpdateInterruptMask8188ESdio(Adapter, 0, (SDIO_HIMR_TXBCNOK_MSK|SDIO_HIMR_TXBCNERR_MSK));       
3989                                 #endif
3990                                 #endif //CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
3991                                         
3992                                 #endif //CONFIG_INTERRUPT_BASED_TXBCN           
3993                                 StopTxBeacon(Adapter);
3994                                 #if defined(CONFIG_PCI_HCI) 
3995                                 UpdateInterruptMask8188EE(Adapter, 0, 0, RT_BCN_INT_MASKS, 0);
3996                                 #endif
3997                         }
3998                         
3999                         rtw_write8(Adapter,REG_BCN_CTRL, 0x19);//disable atim wnd
4000                         //rtw_write8(Adapter,REG_BCN_CTRL, 0x18);
4001                 }
4002                 else if((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
4003                 {
4004                         //Beacon is polled to TXBUF
4005                         rtw_write16(Adapter, REG_CR, rtw_read16(Adapter, REG_CR)|BIT(8));
4006
4007                         ResumeTxBeacon(Adapter);
4008                         rtw_write8(Adapter,REG_BCN_CTRL, 0x1a);
4009                         //BIT3 - If set 0, hw will clr bcnq when tx becon ok/fail or port 0
4010                         rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM)|BIT(3)|BIT(4));
4011                 }
4012                 else if(mode == _HW_STATE_AP_)
4013                 {
4014                         #ifdef CONFIG_INTERRUPT_BASED_TXBCN                     
4015                         #ifdef  CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4016                         #if defined(CONFIG_USB_HCI)
4017                         UpdateInterruptMask8188EU(Adapter,_TRUE ,IMR_BCNDMAINT0_88E, 0);
4018                         #elif defined(CONFIG_SDIO_HCI)
4019                         UpdateInterruptMask8188ESdio(Adapter, SDIO_HIMR_BCNERLY_INT_MSK, 0);
4020                         #endif
4021                         #endif//CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4022
4023                         #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR  
4024                         #if defined(CONFIG_USB_HCI)
4025                         UpdateInterruptMask8188EU(Adapter,_TRUE ,(IMR_TBDER_88E|IMR_TBDOK_88E), 0);
4026                         #elif defined(CONFIG_SDIO_HCI)
4027                         UpdateInterruptMask8188ESdio(Adapter, (SDIO_HIMR_TXBCNOK_MSK|SDIO_HIMR_TXBCNERR_MSK), 0);
4028                         #endif
4029                         #endif//CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
4030                                         
4031                         #endif //CONFIG_INTERRUPT_BASED_TXBCN
4032
4033                         ResumeTxBeacon(Adapter);
4034
4035                         rtw_write8(Adapter, REG_BCN_CTRL, 0x12);                
4036                         
4037                         //Beacon is polled to TXBUF
4038                         rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR)|BIT(8));
4039                         
4040                         //Set RCR
4041                         //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
4042                         rtw_write32(Adapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,reject ICV_ERR packet
4043                         //enable to rx data frame
4044                         rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
4045                         //enable to rx ps-poll
4046                         rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400);
4047
4048                         //Beacon Control related register for first time
4049                         rtw_write8(Adapter, REG_BCNDMATIM, 0x02); // 2ms                        
4050                         rtw_write8(Adapter, REG_DRVERLYINT, 0x05);// 5ms
4051                         //rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);
4052                         rtw_write8(Adapter, REG_ATIMWND, 0x0a); // 10ms
4053                         rtw_write16(Adapter, REG_BCNTCFG, 0x00);
4054                         rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
4055                         rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
4056
4057                         //reset TSF
4058                         rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
4059
4060                         //BIT3 - If set 0, hw will clr bcnq when tx becon ok/fail or port 0
4061                         rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM)|BIT(3)|BIT(4));
4062         
4063                         //enable BCN0 Function for if1
4064                         //don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received)
4065                         #if defined(CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR)
4066                         rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP|EN_BCN_FUNCTION | EN_TXBCN_RPT|BIT(1)));
4067                         #else
4068                         rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP|EN_BCN_FUNCTION |BIT(1)));
4069                         #endif
4070
4071 #ifdef CONFIG_CONCURRENT_MODE
4072                         if(check_buddy_fwstate(Adapter, WIFI_FW_NULL_STATE))
4073                                 rtw_write8(Adapter, REG_BCN_CTRL_1, 
4074                                         rtw_read8(Adapter, REG_BCN_CTRL_1) & ~EN_BCN_FUNCTION);
4075 #endif
4076
4077                         //dis BCN1 ATIM  WND if if2 is station
4078                         rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(0)); 
4079 #ifdef CONFIG_TSF_RESET_OFFLOAD
4080                         // Reset TSF for STA+AP concurrent mode
4081                         if ( check_buddy_fwstate(Adapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)) ) {
4082                                 if (reset_tsf(Adapter, IFACE_PORT0) == _FALSE)
4083                                         DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
4084                                                 __FUNCTION__, __LINE__);
4085                         }
4086 #endif  // CONFIG_TSF_RESET_OFFLOAD
4087 #if defined(CONFIG_PCI_HCI) 
4088                         UpdateInterruptMask8188EE( Adapter, RT_BCN_INT_MASKS, 0, 0, 0);
4089 #endif
4090                 }
4091         }
4092 }
4093 static void hw_var_set_macaddr(PADAPTER Adapter, u8 variable, u8* val)
4094 {
4095         u8 idx = 0;
4096         u32 reg_macid;
4097
4098 #ifdef CONFIG_CONCURRENT_MODE
4099         if(Adapter->iface_type == IFACE_PORT1)
4100         {
4101                 reg_macid = REG_MACID1;
4102         }
4103         else
4104 #endif
4105         {
4106                 reg_macid = REG_MACID;
4107         }
4108
4109         for(idx = 0 ; idx < 6; idx++)
4110         {
4111                 rtw_write8(GET_PRIMARY_ADAPTER(Adapter), (reg_macid+idx), val[idx]);
4112         }
4113         
4114 }
4115
4116 static void hw_var_set_bssid(PADAPTER Adapter, u8 variable, u8* val)
4117 {
4118         u8      idx = 0;
4119         u32 reg_bssid;
4120
4121 #ifdef CONFIG_CONCURRENT_MODE
4122         if(Adapter->iface_type == IFACE_PORT1)
4123         {
4124                 reg_bssid = REG_BSSID1;
4125         }
4126         else
4127 #endif
4128         {
4129                 reg_bssid = REG_BSSID;
4130         }
4131
4132         for(idx = 0 ; idx < 6; idx++)
4133         {
4134                 rtw_write8(Adapter, (reg_bssid+idx), val[idx]);
4135         }
4136
4137 }
4138
4139 static void hw_var_set_bcn_func(PADAPTER Adapter, u8 variable, u8* val)
4140 {
4141         u32 bcn_ctrl_reg;
4142
4143 #ifdef CONFIG_CONCURRENT_MODE
4144         if(Adapter->iface_type == IFACE_PORT1)
4145         {
4146                 bcn_ctrl_reg = REG_BCN_CTRL_1;
4147         }       
4148         else
4149 #endif          
4150         {               
4151                 bcn_ctrl_reg = REG_BCN_CTRL;
4152         }
4153
4154         if(*((u8 *)val))
4155         {
4156                 rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
4157         }
4158         else
4159         {
4160                 rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg)&(~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
4161         }
4162         
4163
4164 }
4165
4166 static void hw_var_set_correct_tsf(PADAPTER Adapter, u8 variable, u8* val)
4167 {
4168 #ifdef CONFIG_CONCURRENT_MODE
4169         u64     tsf;
4170         struct mlme_ext_priv    *pmlmeext = &Adapter->mlmeextpriv;
4171         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4172         PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter;
4173
4174         //tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue % (pmlmeinfo->bcn_interval*1024)) -1024; //us
4175         tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) -1024; //us
4176
4177         if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
4178         {                               
4179                 //pHalData->RegTxPause |= STOP_BCNQ;BIT(6)
4180                 //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)|BIT(6)));
4181                 StopTxBeacon(Adapter);
4182         }
4183
4184         if(Adapter->iface_type == IFACE_PORT1)
4185         {
4186                 //disable related TSF function
4187                 rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(3)));
4188                                                         
4189                 rtw_write32(Adapter, REG_TSFTR1, tsf);
4190                 rtw_write32(Adapter, REG_TSFTR1+4, tsf>>32);
4191
4192
4193                 //enable related TSF function
4194                 rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(3)); 
4195
4196                 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
4197                 if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
4198                         && check_buddy_fwstate(Adapter, WIFI_AP_STATE)
4199                 ) { 
4200                         //disable related TSF function
4201                         rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(3)));
4202
4203                         rtw_write32(Adapter, REG_TSFTR, tsf);
4204                         rtw_write32(Adapter, REG_TSFTR+4, tsf>>32);
4205
4206                         //enable related TSF function
4207                         rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(3));
4208 #ifdef CONFIG_TSF_RESET_OFFLOAD
4209                 // Update buddy port's TSF(TBTT) if it is SoftAP for beacon TX issue!
4210                         if (reset_tsf(Adapter, IFACE_PORT0) == _FALSE)
4211                                 DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
4212                                         __FUNCTION__, __LINE__);
4213
4214 #endif  // CONFIG_TSF_RESET_OFFLOAD     
4215                 }               
4216                 
4217         }
4218         else
4219         {
4220                 //disable related TSF function
4221                 rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(3)));
4222                                                         
4223                 rtw_write32(Adapter, REG_TSFTR, tsf);
4224                 rtw_write32(Adapter, REG_TSFTR+4, tsf>>32);
4225
4226                 //enable related TSF function
4227                 rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(3));
4228                 
4229                 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
4230                 if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
4231                         && check_buddy_fwstate(Adapter, WIFI_AP_STATE)
4232                 ) { 
4233                         //disable related TSF function
4234                         rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(3)));
4235
4236                         rtw_write32(Adapter, REG_TSFTR1, tsf);
4237                         rtw_write32(Adapter, REG_TSFTR1+4, tsf>>32);
4238
4239                         //enable related TSF function
4240                         rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(3));
4241 #ifdef CONFIG_TSF_RESET_OFFLOAD
4242                 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
4243                         if (reset_tsf(Adapter, IFACE_PORT1) == _FALSE)
4244                                 DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
4245                                         __FUNCTION__, __LINE__);
4246 #endif  // CONFIG_TSF_RESET_OFFLOAD
4247                 }               
4248
4249         }
4250                                 
4251                                                         
4252         if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
4253         {
4254                 //pHalData->RegTxPause  &= (~STOP_BCNQ);
4255                 //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)&(~BIT(6))));
4256                 ResumeTxBeacon(Adapter);
4257         }
4258 #endif
4259 }
4260
4261 static void hw_var_set_mlme_disconnect(PADAPTER Adapter, u8 variable, u8* val)
4262 {
4263 #ifdef CONFIG_CONCURRENT_MODE
4264         //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4265         PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter;
4266                         
4267                                 
4268         if(check_buddy_mlmeinfo_state(Adapter, _HW_STATE_NOLINK_))      
4269                 rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
4270         
4271
4272         if(Adapter->iface_type == IFACE_PORT1)
4273         {
4274                 //reset TSF1
4275                 rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1));
4276
4277                 //disable update TSF1
4278                 rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(4));
4279
4280                 // disable Port1's beacon function
4281                 rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(3)));
4282         }
4283         else
4284         {
4285                 //reset TSF
4286                 rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
4287
4288                 //disable update TSF
4289                 rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
4290         }
4291 #endif
4292 }
4293
4294 static void hw_var_set_mlme_sitesurvey(PADAPTER Adapter, u8 variable, u8* val)
4295 {       
4296 #ifdef CONFIG_CONCURRENT_MODE
4297         struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
4298         struct mlme_priv *pmlmepriv=&(Adapter->mlmepriv);
4299         struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
4300         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4301         u32     value_rcr, rcr_clear_bit, value_rxfltmap2;
4302         u8 ap_num;
4303
4304         rtw_dev_iface_status(Adapter, NULL, NULL, NULL, &ap_num, NULL);
4305
4306 #ifdef CONFIG_FIND_BEST_CHANNEL
4307
4308         rcr_clear_bit = (RCR_CBSSID_BCN | RCR_CBSSID_DATA);
4309
4310         /* Receive all data frames */
4311          value_rxfltmap2 = 0xFFFF;
4312         
4313 #else /* CONFIG_FIND_BEST_CHANNEL */
4314         
4315         rcr_clear_bit = RCR_CBSSID_BCN;
4316
4317         //config RCR to receive different BSSID & not to receive data frame
4318         value_rxfltmap2 = 0;
4319
4320 #endif /* CONFIG_FIND_BEST_CHANNEL */
4321
4322         if( (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
4323                 #ifdef CONFIG_CONCURRENT_MODE
4324                 || (check_buddy_fwstate(Adapter, WIFI_AP_STATE) == _TRUE)
4325                 #endif
4326         ){
4327                 rcr_clear_bit = RCR_CBSSID_BCN;
4328         }
4329 #ifdef CONFIG_TDLS
4330         // TDLS will clear RCR_CBSSID_DATA bit for connection.
4331         else if (Adapter->tdlsinfo.link_established == _TRUE)
4332         {
4333                 rcr_clear_bit = RCR_CBSSID_BCN;
4334         }
4335 #endif // CONFIG_TDLS
4336
4337         value_rcr = rtw_read32(Adapter, REG_RCR);
4338         if(*((u8 *)val))//under sitesurvey
4339         {
4340
4341              /*
4342                 * 1. configure REG_RXFLTMAP2
4343                 * 2. disable TSF update &  buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
4344                 * 3. config RCR to receive different BSSID BCN or probe rsp
4345                 */
4346
4347                 /* not to receive data frame */
4348                 rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2);
4349
4350                 /* disable update TSF */
4351                 if (rtw_linked_check(Adapter) &&
4352                         check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) {
4353
4354                         if(Adapter->iface_type == IFACE_PORT1)
4355                                 rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(4));
4356                         else
4357                                 rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
4358
4359                         pmlmeext->en_hw_update_tsf = _FALSE;
4360                 }
4361
4362
4363                 if (rtw_linked_check(Adapter->pbuddy_adapter) &&
4364                         check_fwstate(&Adapter->pbuddy_adapter->mlmepriv, WIFI_AP_STATE) != _TRUE) {
4365
4366                         if (Adapter->pbuddy_adapter->iface_type == IFACE_PORT1)
4367                                 rtw_write8(Adapter->pbuddy_adapter, REG_BCN_CTRL_1,
4368                                         rtw_read8(Adapter->pbuddy_adapter, REG_BCN_CTRL_1)|BIT(4));
4369                         else
4370                                 rtw_write8(Adapter->pbuddy_adapter, REG_BCN_CTRL,
4371                                         rtw_read8(Adapter->pbuddy_adapter, REG_BCN_CTRL)|BIT(4));
4372
4373                         Adapter->pbuddy_adapter->mlmeextpriv.en_hw_update_tsf = _FALSE;
4374                 }
4375
4376                 /* config RCR to receive different BSSID  */
4377                 value_rcr &= ~(rcr_clear_bit);
4378                 rtw_write32(Adapter, REG_RCR, value_rcr);
4379
4380                 if (ap_num)             
4381                         StopTxBeacon(Adapter);
4382
4383         }
4384         else//sitesurvey done
4385         {
4386              /*
4387                 * 1. enable rx data frame
4388                 * 2. config RCR not to receive different BSSID BCN or probe rsp
4389                 * 3. doesn't enable TSF update &  buddy TSF right now to avoid HW conflict
4390                 *        so, we enable TSF update when rx first BCN after sitesurvey done
4391                 */
4392
4393                 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))
4394                         || check_buddy_fwstate(Adapter, (_FW_LINKED|WIFI_AP_STATE)))
4395                         rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
4396
4397                 value_rcr |= rcr_clear_bit;
4398                 rtw_write32(Adapter, REG_RCR, value_rcr);
4399
4400                 /* enable update TSF */
4401                 if (rtw_linked_check(Adapter) &&
4402                         check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
4403                         pmlmeext->en_hw_update_tsf = _TRUE;
4404
4405                 if (rtw_linked_check(Adapter->pbuddy_adapter) &&
4406                         check_fwstate(&Adapter->pbuddy_adapter->mlmepriv, WIFI_AP_STATE) != _TRUE)
4407                         Adapter->pbuddy_adapter->mlmeextpriv.en_hw_update_tsf = _TRUE;
4408
4409
4410                 if (ap_num) {
4411                         int i;
4412                         _adapter *iface;
4413
4414                         ResumeTxBeacon(Adapter);
4415                         for (i = 0; i < dvobj->iface_nums; i++) {
4416                                 iface = dvobj->padapters[i];
4417                                 if (!iface)
4418                                         continue;
4419
4420                                 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE
4421                                         && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4422                                 ) {
4423                                         iface->mlmepriv.update_bcn = _TRUE;
4424                                         #ifndef CONFIG_INTERRUPT_BASED_TXBCN
4425                                         #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4426                                         tx_beacon_hdl(iface, NULL);
4427                                         #endif
4428                                         #endif
4429                                 }
4430                         }
4431                 }
4432         }
4433 #endif                  
4434 }
4435
4436 static void hw_var_set_mlme_join(PADAPTER Adapter, u8 variable, u8* val)
4437 {
4438 #ifdef CONFIG_CONCURRENT_MODE
4439         u8      RetryLimit = 0x30;
4440         u8      type = *((u8 *)val);
4441         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4442         struct mlme_priv        *pmlmepriv = &Adapter->mlmepriv;
4443
4444         if(type == 0) // prepare to join
4445         {               
4446                 if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) &&
4447                         check_buddy_fwstate(Adapter, _FW_LINKED))               
4448                 {
4449                         StopTxBeacon(Adapter);
4450                 }
4451         
4452                 //enable to rx data frame.Accept all data frame
4453                 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
4454                 rtw_write16(Adapter, REG_RXFLTMAP2,0xFFFF);
4455
4456                 if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE))
4457                         rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
4458                 else
4459                         rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
4460
4461                 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
4462                 {
4463                         RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
4464                 }
4465                 else // Ad-hoc Mode
4466                 {
4467                         RetryLimit = 0x7;
4468                 }
4469         }
4470         else if(type == 1) //joinbss_event call back when join res < 0
4471         {               
4472                 if(check_buddy_mlmeinfo_state(Adapter, _HW_STATE_NOLINK_))              
4473                         rtw_write16(Adapter, REG_RXFLTMAP2,0x00);
4474
4475                 if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) &&
4476                         check_buddy_fwstate(Adapter, _FW_LINKED))
4477                 {
4478                         ResumeTxBeacon(Adapter);                        
4479                         
4480                         //reset TSF 1/2 after ResumeTxBeacon
4481                         rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));   
4482                         
4483                 }
4484         }
4485         else if(type == 2) //sta add event call back
4486         {
4487          
4488                 //enable update TSF
4489                 if(Adapter->iface_type == IFACE_PORT1)
4490                         rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(4)));
4491                 else
4492                         rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
4493                  
4494         
4495                 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
4496                 {
4497                         //fixed beacon issue for 8191su...........
4498                         rtw_write8(Adapter,0x542 ,0x02);
4499                         RetryLimit = 0x7;
4500                 }
4501
4502
4503                 if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) &&
4504                         check_buddy_fwstate(Adapter, _FW_LINKED))
4505                 {
4506                         ResumeTxBeacon(Adapter);                        
4507                         
4508                         //reset TSF 1/2 after ResumeTxBeacon
4509                         rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
4510                 }
4511                 
4512         }
4513
4514         rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
4515         
4516 #endif
4517 }
4518
4519
4520 static void hw_var_set_hw_update_tsf(PADAPTER padapter)
4521 {
4522
4523         u16 reg_bcn_ctl;
4524         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4525         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4526
4527 #ifdef CONFIG_CONCURRENT_MODE
4528         if (padapter->iface_type == IFACE_PORT1)
4529                 reg_bcn_ctl = REG_BCN_CTRL_1;
4530         else
4531                 reg_bcn_ctl = REG_BCN_CTRL;
4532 #else
4533         reg_bcn_ctl = REG_BCN_CTRL;
4534 #endif
4535
4536         if (!pmlmeext->en_hw_update_tsf)
4537                 return;
4538
4539         /* check REG_RCR bit is set */
4540         if (!(rtw_read32(padapter, REG_RCR) & RCR_CBSSID_BCN)) {
4541                 pmlmeext->en_hw_update_tsf = _FALSE;
4542                 return;
4543         }
4544
4545
4546         /* enable hw update tsf function for non-AP */
4547         if (rtw_linked_check(padapter) &&
4548                 check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
4549                 /* enable update buddy TSF */
4550                 rtw_write8(padapter, reg_bcn_ctl, rtw_read8(padapter, reg_bcn_ctl)&(~DIS_TSF_UDT));
4551
4552         pmlmeext->en_hw_update_tsf = _FALSE;
4553 }
4554
4555 void SetHwReg8188E(_adapter *adapter, u8 variable, u8 *val)
4556 {
4557         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
4558         DM_ODM_T                *podmpriv = &pHalData->odmpriv;
4559 _func_enter_;
4560
4561         switch (variable) {
4562                 case HW_VAR_MEDIA_STATUS:
4563                         {
4564                                 u8 val8;
4565
4566                                 val8 = rtw_read8(adapter, MSR)&0x0c;
4567                                 val8 |= *((u8 *)val);
4568                                 rtw_write8(adapter, MSR, val8);
4569                         }
4570                         break;
4571                 case HW_VAR_MEDIA_STATUS1:
4572                         {
4573                                 u8 val8;
4574                                 
4575                                 val8 = rtw_read8(adapter, MSR)&0x03;
4576                                 val8 |= *((u8 *)val) <<2;
4577                                 rtw_write8(adapter, MSR, val8);
4578                         }
4579                         break;
4580                 case HW_VAR_SET_OPMODE:
4581                         hw_var_set_opmode(adapter, variable, val);
4582                         break;
4583                 case HW_VAR_MAC_ADDR:
4584                         hw_var_set_macaddr(adapter, variable, val);                     
4585                         break;
4586                 case HW_VAR_BSSID:
4587                         hw_var_set_bssid(adapter, variable, val);
4588                         break;
4589                 case HW_VAR_BASIC_RATE:
4590                 {
4591                         struct mlme_ext_info *mlmext_info = &adapter->mlmeextpriv.mlmext_info;
4592                         u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
4593                         u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
4594                         u16 rrsr_2g_allow_mask = (RRSR_24M|RRSR_12M|RRSR_6M|RRSR_CCK_RATES);
4595
4596                         HalSetBrateCfg(adapter, val, &BrateCfg);
4597                         input_b = BrateCfg;
4598
4599                         /* apply force and allow mask */
4600                         BrateCfg |= rrsr_2g_force_mask;
4601                         BrateCfg &= rrsr_2g_allow_mask;
4602                         masked = BrateCfg;
4603
4604                         /* IOT consideration */
4605                         if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
4606                                 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
4607                                 if((BrateCfg & (RRSR_24M|RRSR_12M|RRSR_6M)) == 0)
4608                                         BrateCfg |= RRSR_6M;
4609                         }
4610                         ioted = BrateCfg;
4611
4612                         pHalData->BasicRateSet = BrateCfg;
4613
4614                         DBG_8192C("HW_VAR_BASIC_RATE: %#x -> %#x -> %#x\n", input_b, masked, ioted);
4615
4616                         // Set RRSR rate table.
4617                         rtw_write16(adapter, REG_RRSR, BrateCfg);
4618                         rtw_write8(adapter, REG_RRSR+2, rtw_read8(adapter, REG_RRSR+2)&0xf0);
4619
4620                         rtw_hal_set_hwreg(adapter, HW_VAR_INIT_RTS_RATE, (u8*)&BrateCfg);
4621                 }
4622                         break;
4623                 case HW_VAR_TXPAUSE:
4624                         rtw_write8(adapter, REG_TXPAUSE, *((u8 *)val)); 
4625                         break;
4626                 case HW_VAR_BCN_FUNC:
4627                         hw_var_set_bcn_func(adapter, variable, val);
4628                         break;
4629                         
4630                 case HW_VAR_CORRECT_TSF:
4631 #ifdef CONFIG_CONCURRENT_MODE
4632                         hw_var_set_correct_tsf(adapter, variable, val);
4633 #else
4634                         {
4635                                 u64     tsf;
4636                                 struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
4637                                 struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4638
4639                                 //tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue % (pmlmeinfo->bcn_interval*1024)) -1024; //us
4640                                 tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) -1024; //us
4641
4642                                 if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
4643                                 {                               
4644                                         //pHalData->RegTxPause |= STOP_BCNQ;BIT(6)
4645                                         //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)|BIT(6)));
4646                                         StopTxBeacon(adapter);
4647                                 }
4648
4649                                 //disable related TSF function
4650                                 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)&(~BIT(3)));
4651                                                         
4652                                 rtw_write32(adapter, REG_TSFTR, tsf);
4653                                 rtw_write32(adapter, REG_TSFTR+4, tsf>>32);
4654
4655                                 //enable related TSF function
4656                                 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)|BIT(3));
4657                                 
4658                                                         
4659                                 if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
4660                                 {
4661                                         //pHalData->RegTxPause  &= (~STOP_BCNQ);
4662                                         //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)&(~BIT(6))));
4663                                         ResumeTxBeacon(adapter);
4664                                 }
4665                         }
4666 #endif
4667                         break;
4668
4669                 case HW_VAR_CHECK_BSSID:
4670                         if(*((u8 *)val))
4671                         {
4672                                 rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
4673                         }
4674                         else
4675                         {
4676                                 u32     val32;
4677
4678                                 val32 = rtw_read32(adapter, REG_RCR);
4679
4680                                 val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
4681
4682                                 rtw_write32(adapter, REG_RCR, val32);
4683                         }
4684                         break;
4685
4686                 case HW_VAR_MLME_DISCONNECT:
4687 #ifdef CONFIG_CONCURRENT_MODE
4688                         hw_var_set_mlme_disconnect(adapter, variable, val);
4689 #else
4690                         {
4691                                 //Set RCR to not to receive data frame when NO LINK state
4692                                 //rtw_write32(Adapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF);
4693                                 //reject all data frames
4694                                 rtw_write16(adapter, REG_RXFLTMAP2,0x00);
4695
4696                                 //reset TSF
4697                                 rtw_write8(adapter, REG_DUAL_TSF_RST, (BIT(0)|BIT(1)));
4698
4699                                 //disable update TSF
4700                                 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)|BIT(4));     
4701                         }
4702 #endif
4703                         break;
4704
4705                 case HW_VAR_MLME_SITESURVEY:
4706 #ifdef CONFIG_CONCURRENT_MODE
4707                         hw_var_set_mlme_sitesurvey(adapter, variable,  val);
4708 #else
4709                         {
4710                                 u32     value_rcr, rcr_clear_bit, value_rxfltmap2;
4711                                 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4712
4713         #ifdef CONFIG_FIND_BEST_CHANNEL
4714
4715                                 rcr_clear_bit = (RCR_CBSSID_BCN | RCR_CBSSID_DATA);
4716
4717                                 /* Receive all data frames */
4718                                 value_rxfltmap2 = 0xFFFF;
4719                 
4720         #else /* CONFIG_FIND_BEST_CHANNEL */
4721                 
4722                                 rcr_clear_bit = RCR_CBSSID_BCN;
4723
4724                                 //config RCR to receive different BSSID & not to receive data frame
4725                                 value_rxfltmap2 = 0;
4726
4727         #endif /* CONFIG_FIND_BEST_CHANNEL */
4728
4729                                 if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
4730                                         rcr_clear_bit = RCR_CBSSID_BCN;
4731                                 }
4732                                 #ifdef CONFIG_TDLS
4733                                 // TDLS will clear RCR_CBSSID_DATA bit for connection.
4734                                 else if (adapter->tdlsinfo.link_established == _TRUE) {
4735                                         rcr_clear_bit = RCR_CBSSID_BCN;
4736                                 }
4737                                 #endif // CONFIG_TDLS
4738
4739                                 value_rcr = rtw_read32(adapter, REG_RCR);
4740                                 if(*((u8 *)val))//under sitesurvey
4741                                 {
4742                                         /* disable update TSF */
4743                                         rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)|BIT(4));
4744
4745                                         /* config RCR to receive different BSSID & not to receive data frame */
4746                                         value_rcr &= ~(rcr_clear_bit);
4747                                         rtw_write32(adapter, REG_RCR, value_rcr);
4748                                         rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
4749
4750                                         pmlmeext->en_hw_update_tsf = _FALSE;
4751                                 }
4752                                 else//sitesurvey done
4753                                 {
4754                                         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
4755                                         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4756
4757                                         value_rcr |= rcr_clear_bit;
4758                                         if (((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) && (adapter->in_cta_test)) {
4759                                                 u32 v = rtw_read32(adapter, REG_RCR);
4760                                                 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN );//| RCR_ADF
4761                                                 rtw_write32(adapter, REG_RCR, v);
4762                                         } else {
4763                                                 rtw_write32(adapter, REG_RCR, value_rcr);       
4764                                         }
4765
4766                                         if ((is_client_associated_to_ap(adapter) == _TRUE) ||
4767                                                 ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)) {
4768
4769                                                 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
4770                                                 pmlmeext->en_hw_update_tsf = _TRUE;
4771                                         } else if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
4772                                                 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
4773
4774                                 }
4775                         }
4776 #endif                  
4777                         break;
4778
4779                 case HW_VAR_MLME_JOIN:
4780 #ifdef CONFIG_CONCURRENT_MODE
4781                         hw_var_set_mlme_join(adapter, variable,  val);
4782 #else
4783                         {
4784                                 u8      RetryLimit = 0x30;
4785                                 u8      type = *((u8 *)val);
4786                                 struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
4787                                 
4788                                 if(type == 0) // prepare to join
4789                                 {
4790                                         //enable to rx data frame.Accept all data frame
4791                                         //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
4792                                         rtw_write16(adapter, REG_RXFLTMAP2,0xFFFF);
4793
4794                                         if(adapter->in_cta_test)
4795                                         {
4796                                                 u32 v = rtw_read32(adapter, REG_RCR);
4797                                                 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN );//| RCR_ADF
4798                                                 rtw_write32(adapter, REG_RCR, v);
4799                                         }
4800                                         else
4801                                         {
4802                                                 rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
4803                                         }
4804
4805                                         if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
4806                                         {
4807                                                 RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
4808                                         }
4809                                         else // Ad-hoc Mode
4810                                         {
4811                                                 RetryLimit = 0x7;
4812                                         }
4813                                 }
4814                                 else if(type == 1) //joinbss_event call back when join res < 0
4815                                 {
4816                                         rtw_write16(adapter, REG_RXFLTMAP2,0x00);
4817                                 }
4818                                 else if(type == 2) //sta add event call back
4819                                 {
4820                                         //enable update TSF
4821                                         rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)&(~BIT(4)));
4822
4823                                         if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
4824                                         {
4825                                                 RetryLimit = 0x7;
4826                                         }
4827                                 }
4828
4829                                 rtw_write16(adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
4830                         }
4831 #endif
4832                         break;
4833
4834                 case HW_VAR_ON_RCR_AM:
4835                         rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR)|RCR_AM);
4836                         DBG_871X("%s, %d, RCR= %x \n", __FUNCTION__,__LINE__, rtw_read32(adapter, REG_RCR));
4837                         break;
4838               case HW_VAR_OFF_RCR_AM:
4839                         rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR)& (~RCR_AM));
4840                         DBG_871X("%s, %d, RCR= %x \n", __FUNCTION__,__LINE__, rtw_read32(adapter, REG_RCR));
4841                         break;
4842                 case HW_VAR_BEACON_INTERVAL:
4843                         rtw_write16(adapter, REG_BCN_INTERVAL, *((u16 *)val));
4844 #ifdef  CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4845                         {
4846                                 struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
4847                                 struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4848                                 u16 bcn_interval =      *((u16 *)val);
4849                                 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE){
4850                                         DBG_8192C("%s==> bcn_interval:%d, eraly_int:%d \n",__FUNCTION__,bcn_interval,bcn_interval>>1);
4851                                         rtw_write8(adapter, REG_DRVERLYINT, bcn_interval>>1);// 50ms for sdio 
4852                                 }                       
4853                         }
4854 #endif//CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4855
4856                         break;
4857                 case HW_VAR_SLOT_TIME:
4858                         {
4859                                 rtw_write8(adapter, REG_SLOT, val[0]);
4860                         }
4861                         break;
4862                 case HW_VAR_ACK_PREAMBLE:
4863                         {
4864                                 u8      regTmp;
4865                                 u8      bShortPreamble = *( (PBOOLEAN)val );
4866                                 // Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily)
4867                                 regTmp = (pHalData->nCur40MhzPrimeSC)<<5;
4868                                 rtw_write8(adapter, REG_RRSR+2, regTmp);
4869
4870                                 regTmp = rtw_read8(adapter,REG_WMAC_TRXPTCL_CTL+2);
4871                                 if(bShortPreamble)              
4872                                         regTmp |= BIT1;
4873                                 else
4874                                         regTmp &= (~BIT1);
4875                                 rtw_write8(adapter,REG_WMAC_TRXPTCL_CTL+2,regTmp);                              
4876                         }
4877                         break;
4878                 case HW_VAR_CAM_EMPTY_ENTRY:
4879                         {
4880                                 u8      ucIndex = *((u8 *)val);
4881                                 u8      i;
4882                                 u32     ulCommand=0;
4883                                 u32     ulContent=0;
4884                                 u32     ulEncAlgo=CAM_AES;
4885
4886                                 for(i=0;i<CAM_CONTENT_COUNT;i++)
4887                                 {
4888                                         // filled id in CAM config 2 byte
4889                                         if( i == 0)
4890                                         {
4891                                                 ulContent |=(ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2);
4892                                                 //ulContent |= CAM_VALID;
4893                                         }
4894                                         else
4895                                         {
4896                                                 ulContent = 0;
4897                                         }
4898                                         // polling bit, and No Write enable, and address
4899                                         ulCommand= CAM_CONTENT_COUNT*ucIndex+i;
4900                                         ulCommand= ulCommand | CAM_POLLINIG|CAM_WRITE;
4901                                         // write content 0 is equall to mark invalid
4902                                         rtw_write32(adapter, WCAMI, ulContent);  //delay_ms(40);
4903                                         //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %lx \n",ulContent));
4904                                         rtw_write32(adapter, RWCAM, ulCommand);  //delay_ms(40);
4905                                         //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %lx \n",ulCommand));
4906                                 }
4907                         }
4908                         break;
4909                 case HW_VAR_CAM_INVALID_ALL:
4910                         rtw_write32(adapter, RWCAM, BIT(31)|BIT(30));
4911                         break;
4912                 case HW_VAR_AC_PARAM_VO:
4913                         rtw_write32(adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]);
4914                         break;
4915                 case HW_VAR_AC_PARAM_VI:
4916                         rtw_write32(adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]);
4917                         break;
4918                 case HW_VAR_AC_PARAM_BE:
4919                         pHalData->AcParam_BE = ((u32 *)(val))[0];
4920                         rtw_write32(adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]);
4921                         break;
4922                 case HW_VAR_AC_PARAM_BK:
4923                         rtw_write32(adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]);
4924                         break;
4925                 case HW_VAR_ACM_CTRL:
4926                         {
4927                                 u8      acm_ctrl = *((u8 *)val);
4928                                 u8      AcmCtrl = rtw_read8( adapter, REG_ACMHWCTRL);
4929
4930                                 if(acm_ctrl > 1)
4931                                         AcmCtrl = AcmCtrl | 0x1;
4932
4933                                 if(acm_ctrl & BIT(3))
4934                                         AcmCtrl |= AcmHw_VoqEn;
4935                                 else
4936                                         AcmCtrl &= (~AcmHw_VoqEn);
4937
4938                                 if(acm_ctrl & BIT(2))
4939                                         AcmCtrl |= AcmHw_ViqEn;
4940                                 else
4941                                         AcmCtrl &= (~AcmHw_ViqEn);
4942
4943                                 if(acm_ctrl & BIT(1))
4944                                         AcmCtrl |= AcmHw_BeqEn;
4945                                 else
4946                                         AcmCtrl &= (~AcmHw_BeqEn);
4947
4948                                 DBG_871X("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl );
4949                                 rtw_write8(adapter, REG_ACMHWCTRL, AcmCtrl );
4950                         }
4951                         break;
4952                 case HW_VAR_AMPDU_FACTOR:
4953                         {
4954                                 u8      RegToSet_Normal[4]={0x41,0xa8,0x72, 0xb9};
4955                                 u8      RegToSet_BT[4]={0x31,0x74,0x42, 0x97};
4956                                 u8      FactorToSet;
4957                                 u8      *pRegToSet;
4958                                 u8      index = 0;
4959
4960 #ifdef CONFIG_BT_COEXIST
4961                                 if(     (pHalData->bt_coexist.BT_Coexist) &&
4962                                         (pHalData->bt_coexist.BT_CoexistType == BT_CSR_BC4) )
4963                                         pRegToSet = RegToSet_BT; // 0x97427431;
4964                                 else
4965 #endif
4966                                         pRegToSet = RegToSet_Normal; // 0xb972a841;
4967
4968                                 FactorToSet = *((u8 *)val);
4969                                 if(FactorToSet <= 3)
4970                                 {
4971                                         FactorToSet = (1<<(FactorToSet + 2));
4972                                         if(FactorToSet>0xf)
4973                                                 FactorToSet = 0xf;
4974
4975                                         for(index=0; index<4; index++)
4976                                         {
4977                                                 if((pRegToSet[index] & 0xf0) > (FactorToSet<<4))
4978                                                         pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet<<4);
4979                                         
4980                                                 if((pRegToSet[index] & 0x0f) > FactorToSet)
4981                                                         pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
4982                                                 
4983                                                 rtw_write8(adapter, (REG_AGGLEN_LMT+index), pRegToSet[index]);
4984                                         }
4985
4986                                         //RT_TRACE(COMP_MLME, DBG_LOUD, ("Set HW_VAR_AMPDU_FACTOR: %#x\n", FactorToSet));
4987                                 }
4988                         }
4989                         break;          
4990                 case HW_VAR_H2C_FW_PWRMODE:
4991                         {
4992                                 u8      psmode = (*(u8 *)val);
4993                         
4994                                 // Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power
4995                                 // saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang.
4996                                 if (psmode != PS_MODE_ACTIVE)
4997                                 {
4998                                         ODM_RF_Saving(podmpriv, _TRUE);
4999                                 }
5000                                 rtl8188e_set_FwPwrMode_cmd(adapter, psmode);
5001                         }
5002                         break;
5003                 case HW_VAR_H2C_FW_JOINBSSRPT:
5004                     {
5005                                 u8      mstatus = (*(u8 *)val);
5006                                 rtl8188e_set_FwJoinBssReport_cmd(adapter, mstatus);
5007                         }
5008                         break;
5009 #ifdef CONFIG_P2P_PS
5010                 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
5011                         {
5012                                 u8      p2p_ps_state = (*(u8 *)val);
5013                                 rtl8188e_set_p2p_ps_offload_cmd(adapter, p2p_ps_state);
5014                         }
5015                         break;
5016 #endif //CONFIG_P2P_PS
5017 #ifdef CONFIG_TDLS
5018                 case HW_VAR_TDLS_WRCR:
5019                         rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR)&(~RCR_CBSSID_DATA ));
5020                         break;
5021                 case HW_VAR_TDLS_RS_RCR:
5022                         rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR)|(RCR_CBSSID_DATA));
5023                         break;
5024 #endif //CONFIG_TDLS
5025 #ifdef CONFIG_BT_COEXIST
5026                 case HW_VAR_BT_SET_COEXIST:
5027                         {
5028                                 u8      bStart = (*(u8 *)val);
5029                                 rtl8192c_set_dm_bt_coexist(adapter, bStart);
5030                         }
5031                         break;
5032                 case HW_VAR_BT_ISSUE_DELBA:
5033                         {
5034                                 u8      dir = (*(u8 *)val);
5035                                 rtl8192c_issue_delete_ba(adapter, dir);
5036                         }
5037                         break;
5038 #endif
5039 #if (RATE_ADAPTIVE_SUPPORT==1)
5040                 case HW_VAR_RPT_TIMER_SETTING:
5041                         {
5042                                 u16     min_rpt_time = (*(u16 *)val);
5043                                 
5044                                 ODM_RA_Set_TxRPT_Time(podmpriv,min_rpt_time);   
5045                         }
5046                         break;
5047 #endif
5048
5049                 case HW_VAR_EFUSE_BYTES: // To set EFUE total used bytes, added by Roger, 2008.12.22.
5050                         pHalData->EfuseUsedBytes = *((u16 *)val);                       
5051                         break;
5052                 case HW_VAR_FIFO_CLEARN_UP:
5053                         {                               
5054                                 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
5055                                 u8 trycnt = 100;        
5056                                 
5057                                 //pause tx
5058                                 rtw_write8(adapter,REG_TXPAUSE,0xff);
5059                         
5060                                 //keep sn
5061                                 adapter->xmitpriv.nqos_ssn = rtw_read16(adapter,REG_NQOS_SEQ);
5062
5063                                 if(pwrpriv->bkeepfwalive != _TRUE)
5064                                 {
5065                                         //RX DMA stop
5066                                         rtw_write32(adapter,REG_RXPKT_NUM,(rtw_read32(adapter,REG_RXPKT_NUM)|RW_RELEASE_EN));
5067                                         do{
5068                                                 if(!(rtw_read32(adapter,REG_RXPKT_NUM)&RXDMA_IDLE))
5069                                                         break;
5070                                         }while(trycnt--);
5071                                         if(trycnt ==0)
5072                                                 DBG_8192C("Stop RX DMA failed...... \n");
5073
5074                                         //RQPN Load 0
5075                                         rtw_write16(adapter,REG_RQPN_NPQ,0x0);
5076                                         rtw_write32(adapter,REG_RQPN,0x80000000);
5077                                         rtw_mdelay_os(10);
5078                                 }
5079                         }
5080                         break;
5081
5082                 case HW_VAR_RESTORE_HW_SEQ:
5083                         /* restore Sequence No. */
5084                         rtw_write8(adapter, 0x4dc, adapter->xmitpriv.nqos_ssn);
5085                         break;
5086
5087                 case HW_VAR_APFM_ON_MAC:
5088                         pHalData->bMacPwrCtrlOn = *val;
5089                         DBG_871X("%s: bMacPwrCtrlOn=%d\n", __func__, pHalData->bMacPwrCtrlOn);
5090                         break;
5091 #if (RATE_ADAPTIVE_SUPPORT == 1)
5092                 case HW_VAR_TX_RPT_MAX_MACID:
5093                 {
5094                         u8 maxMacid = *val;
5095
5096                         DBG_871X("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid + 1);
5097                         rtw_write8(adapter, REG_TX_RPT_CTRL + 1, maxMacid + 1);
5098                 }
5099                         break;
5100 #endif /* (RATE_ADAPTIVE_SUPPORT == 1) */
5101
5102                 case HW_VAR_BCN_VALID:
5103                         //BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw
5104                         rtw_write8(adapter, REG_TDECTRL+2, rtw_read8(adapter, REG_TDECTRL+2) | BIT0); 
5105                         break;
5106                         
5107                         
5108                 case HW_VAR_CHECK_TXBUF:
5109                         {
5110                                 u8 retry_limit;
5111                                 u16 val16;
5112                                 u32 reg_200 = 0, reg_204 = 0;
5113                                 u32 init_reg_200 = 0, init_reg_204 = 0;
5114                                 u32 start = rtw_get_current_time();
5115                                 u32 pass_ms;
5116                                 int i = 0;
5117
5118                                 retry_limit = 0x01;
5119
5120                                 val16 = retry_limit << RETRY_LIMIT_SHORT_SHIFT | retry_limit << RETRY_LIMIT_LONG_SHIFT;
5121                                 rtw_write16(adapter, REG_RL, val16);
5122
5123                                 while (rtw_get_passing_time_ms(start) < 2000
5124                                         && !RTW_CANNOT_RUN(adapter)
5125                                 ) {
5126                                         reg_200 = rtw_read32(adapter, 0x200);
5127                                         reg_204 = rtw_read32(adapter, 0x204);
5128
5129                                         if (i == 0) {
5130                                                 init_reg_200 = reg_200;
5131                                                 init_reg_204 = reg_204;
5132                                         }
5133
5134                                         i++;
5135                                         if ((reg_200 & 0x00ffffff) != (reg_204 & 0x00ffffff)) {
5136                                                 //DBG_871X("%s: (HW_VAR_CHECK_TXBUF)TXBUF NOT empty - 0x204=0x%x, 0x200=0x%x (%d)\n", __FUNCTION__, reg_204, reg_200, i);
5137                                                 rtw_msleep_os(10);
5138                                         } else {
5139                                                 break;
5140                                         }
5141                                 }
5142
5143                                 pass_ms = rtw_get_passing_time_ms(start);
5144
5145                                 if (RTW_CANNOT_RUN(adapter))
5146                                         ;
5147                                 else if (pass_ms >= 2000 || (reg_200 & 0x00ffffff) != (reg_204 & 0x00ffffff)) {
5148                                         DBG_871X_LEVEL(_drv_always_, "%s:(HW_VAR_CHECK_TXBUF)NOT empty(%d) in %d ms\n", __FUNCTION__, i, pass_ms);
5149                                         DBG_871X_LEVEL(_drv_always_, "%s:(HW_VAR_CHECK_TXBUF)0x200=0x%08x, 0x204=0x%08x (0x%08x, 0x%08x)\n",
5150                                                 __FUNCTION__, reg_200, reg_204, init_reg_200, init_reg_204);
5151                                         //rtw_warn_on(1);
5152                                 } else {
5153                                         DBG_871X("%s:(HW_VAR_CHECK_TXBUF)TXBUF Empty(%d) in %d ms\n", __FUNCTION__, i, pass_ms);
5154                                 }
5155
5156                                 retry_limit = 0x30;
5157                                 val16 = retry_limit << RETRY_LIMIT_SHORT_SHIFT | retry_limit << RETRY_LIMIT_LONG_SHIFT;
5158                                 rtw_write16(adapter, REG_RL, val16);
5159                         }
5160                         break;
5161                 case HW_VAR_RESP_SIFS:
5162                         {
5163                                 struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
5164
5165                                 if((pmlmeext->cur_wireless_mode==WIRELESS_11G) ||
5166                                 (pmlmeext->cur_wireless_mode==WIRELESS_11BG))//WIRELESS_MODE_G){
5167                                 {
5168                                         val[0] = 0x0a;
5169                                         val[1] = 0x0a;
5170                                 } else {
5171                                         val[0] = 0x0e;
5172                                         val[1] = 0x0e;
5173                                 }
5174
5175                                 // SIFS for OFDM Data ACK
5176                                 rtw_write8(adapter, REG_SIFS_CTX+1, val[0]);
5177                                 // SIFS for OFDM consecutive tx like CTS data!
5178                                 rtw_write8(adapter, REG_SIFS_TRX+1, val[1]);
5179
5180                                 rtw_write8(adapter, REG_SPEC_SIFS+1, val[0]);
5181                                 rtw_write8(adapter, REG_MAC_SPEC_SIFS+1, val[0]);
5182                                                 
5183                                 //RESP_SIFS for OFDM
5184                                 rtw_write8(adapter, REG_RESP_SIFS_OFDM, val[0]);
5185                                 rtw_write8(adapter, REG_RESP_SIFS_OFDM+1, val[0]);
5186                         }
5187                         break;
5188
5189                 case HW_VAR_MACID_LINK:
5190                 {
5191                         u32 reg_macid_no_link;
5192                         u8 bit_shift;
5193                         u8 id = *(u8 *)val;
5194                         u32 val32;
5195
5196                         if (id < 32) {
5197                                 reg_macid_no_link = REG_MACID_NO_LINK_0;
5198                                 bit_shift = id;
5199                         } else if (id < 64) {
5200                                 reg_macid_no_link = REG_MACID_NO_LINK_1;
5201                                 bit_shift = id - 32;
5202                         } else {
5203                                 rtw_warn_on(1);
5204                                 break;
5205                         }
5206
5207                         val32 = rtw_read32(adapter, reg_macid_no_link);
5208                         if (!(val32 & BIT(bit_shift)))
5209                                 break;
5210
5211                         val32 &= ~BIT(bit_shift);
5212                         rtw_write32(adapter, reg_macid_no_link, val32);
5213                 }
5214                         break;
5215
5216                 case HW_VAR_MACID_NOLINK:
5217                 {
5218                         u32 reg_macid_no_link;
5219                         u8 bit_shift;
5220                         u8 id = *(u8 *)val;
5221                         u32 val32;
5222
5223                         if (id < 32) {
5224                                 reg_macid_no_link = REG_MACID_NO_LINK_0;
5225                                 bit_shift = id;
5226                         } else if (id < 64) {
5227                                 reg_macid_no_link = REG_MACID_NO_LINK_1;
5228                                 bit_shift = id - 32;
5229                         } else {
5230                                 rtw_warn_on(1);
5231                                 break;
5232                         }
5233
5234                         val32 = rtw_read32(adapter, reg_macid_no_link);
5235                         if (val32 & BIT(bit_shift))
5236                                 break;
5237
5238                         val32 |= BIT(bit_shift);
5239                         rtw_write32(adapter, reg_macid_no_link, val32);
5240                 }
5241                         break;
5242
5243                 case HW_VAR_MACID_SLEEP:
5244                 {
5245                         u32 reg_macid_sleep;
5246                         u8 bit_shift;
5247                         u8 id = *(u8*)val;
5248                         u32 val32;
5249
5250                         if (id < 32){
5251                                 reg_macid_sleep = REG_MACID_PAUSE_0;
5252                                 bit_shift = id;
5253                         } else if (id < 64) {
5254                                 reg_macid_sleep = REG_MACID_PAUSE_1;
5255                                 bit_shift = id-32;
5256                         } else {
5257                                 rtw_warn_on(1);
5258                                 break;
5259                         }
5260
5261                         val32 = rtw_read32(adapter, reg_macid_sleep);
5262                         DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_SLEEP] macid=%d, org reg_0x%03x=0x%08X\n",
5263                                 FUNC_ADPT_ARG(adapter), id, reg_macid_sleep, val32);
5264
5265                         if (val32 & BIT(bit_shift))
5266                                 break;
5267
5268                         val32 |= BIT(bit_shift);
5269                         rtw_write32(adapter, reg_macid_sleep, val32);
5270                 }
5271                         break;
5272
5273                 case HW_VAR_MACID_WAKEUP:
5274                 {
5275                         u32 reg_macid_sleep;
5276                         u8 bit_shift;
5277                         u8 id = *(u8*)val;
5278                         u32 val32;
5279
5280                         if (id < 32){
5281                                 reg_macid_sleep = REG_MACID_PAUSE_0;
5282                                 bit_shift = id;
5283                         } else if (id < 64) {
5284                                 reg_macid_sleep = REG_MACID_PAUSE_1;
5285                                 bit_shift = id-32;
5286                         } else {
5287                                 rtw_warn_on(1);
5288                                 break;
5289                         }
5290
5291                         val32 = rtw_read32(adapter, reg_macid_sleep);
5292                         DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_WAKEUP] macid=%d, org reg_0x%03x=0x%08X\n",
5293                                 FUNC_ADPT_ARG(adapter), id, reg_macid_sleep, val32);
5294
5295                         if (!(val32 & BIT(bit_shift)))
5296                                 break;
5297
5298                         val32 &= ~BIT(bit_shift);
5299                         rtw_write32(adapter, reg_macid_sleep, val32);
5300                 }
5301                         break;
5302
5303                 case HW_VAR_EN_HW_UPDATE_TSF:
5304                         hw_var_set_hw_update_tsf(adapter);
5305                         break;
5306
5307                 default:
5308                         SetHwReg(adapter, variable, val);
5309                         break;
5310         }
5311
5312 _func_exit_;
5313 }
5314
5315 struct qinfo_88e {
5316         u32 head:8;
5317         u32 pkt_num:8;
5318         u32 tail:8;
5319         u32 ac:2;
5320         u32 macid:6;
5321 };
5322
5323 struct bcn_qinfo_88e {
5324         u16 head:8;
5325         u16 pkt_num:8;
5326 };
5327
5328 void dump_qinfo_88e(void *sel, struct qinfo_88e *info, const char *tag)
5329 {
5330         //if (info->pkt_num)
5331         DBG_871X_SEL_NL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n"
5332                 , tag ? tag : "", info->head, info->tail, info->pkt_num, info->macid, info->ac
5333         );
5334 }
5335
5336 void dump_bcn_qinfo_88e(void *sel, struct bcn_qinfo_88e *info, const char *tag)
5337 {
5338         //if (info->pkt_num)
5339         DBG_871X_SEL_NL(sel, "%shead:0x%02x, pkt_num:%u\n"
5340                 , tag ? tag : "", info->head, info->pkt_num
5341         );
5342 }
5343
5344 void dump_mac_qinfo_88e(void *sel, _adapter *adapter)
5345 {
5346         u32 q0_info;
5347         u32 q1_info;
5348         u32 q2_info;
5349         u32 q3_info;
5350         /*
5351         u32 q4_info;
5352         u32 q5_info;
5353         u32 q6_info;
5354         u32 q7_info;
5355         */
5356         u32 mg_q_info;
5357         u32 hi_q_info;
5358         u16 bcn_q_info;
5359
5360         q0_info = rtw_read32(adapter, REG_Q0_INFO);
5361         q1_info = rtw_read32(adapter, REG_Q1_INFO);
5362         q2_info = rtw_read32(adapter, REG_Q2_INFO);
5363         q3_info = rtw_read32(adapter, REG_Q3_INFO);
5364         /*
5365         q4_info = rtw_read32(adapter, REG_Q4_INFO);
5366         q5_info = rtw_read32(adapter, REG_Q5_INFO);
5367         q6_info = rtw_read32(adapter, REG_Q6_INFO);
5368         q7_info = rtw_read32(adapter, REG_Q7_INFO);
5369         */
5370         mg_q_info = rtw_read32(adapter, REG_MGQ_INFO);
5371         hi_q_info = rtw_read32(adapter, REG_HGQ_INFO);
5372         bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO);
5373
5374         dump_qinfo_88e(sel, (struct qinfo_88e *)&q0_info, "Q0 ");
5375         dump_qinfo_88e(sel, (struct qinfo_88e *)&q1_info, "Q1 ");
5376         dump_qinfo_88e(sel, (struct qinfo_88e *)&q2_info, "Q2 ");
5377         dump_qinfo_88e(sel, (struct qinfo_88e *)&q3_info, "Q3 ");
5378         /*
5379         dump_qinfo_88e(sel, (struct qinfo_88e *)&q4_info, "Q4 ");
5380         dump_qinfo_88e(sel, (struct qinfo_88e *)&q5_info, "Q5 ");
5381         dump_qinfo_88e(sel, (struct qinfo_88e *)&q6_info, "Q6 ");
5382         dump_qinfo_88e(sel, (struct qinfo_88e *)&q7_info, "Q7 ");
5383         */
5384         dump_qinfo_88e(sel, (struct qinfo_88e *)&mg_q_info, "MG ");
5385         dump_qinfo_88e(sel, (struct qinfo_88e *)&hi_q_info, "HI ");
5386         dump_bcn_qinfo_88e(sel, (struct bcn_qinfo_88e *)&bcn_q_info, "BCN ");
5387 }
5388
5389 void GetHwReg8188E(_adapter *adapter, u8 variable, u8 *val)
5390 {
5391         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
5392
5393 _func_enter_;
5394
5395         switch (variable) {
5396                 case HW_VAR_SYS_CLKR:
5397                         *val = rtw_read8(adapter, REG_SYS_CLKR);
5398                         break;
5399
5400                 case HW_VAR_TXPAUSE:
5401                         val[0] = rtw_read8(adapter, REG_TXPAUSE);
5402                         break;
5403                 case HW_VAR_BCN_VALID:
5404                         //BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2
5405                         val[0] = (BIT0 & rtw_read8(adapter, REG_TDECTRL+2))?_TRUE:_FALSE;
5406                         break;
5407                 case HW_VAR_FWLPS_RF_ON:
5408                         {
5409                                 //When we halt NIC, we should check if FW LPS is leave.
5410                                 if(adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
5411                                 {
5412                                         // If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave,
5413                                         // because Fw is unload.
5414                                         val[0] = _TRUE;
5415                                 }
5416                                 else
5417                                 {
5418                                         u32 valRCR;
5419                                         valRCR = rtw_read32(adapter, REG_RCR);
5420                                         valRCR &= 0x00070000;
5421                                         if(valRCR)
5422                                                 val[0] = _FALSE;
5423                                         else
5424                                                 val[0] = _TRUE;
5425                                 }
5426                         }
5427                         break;
5428                 case HW_VAR_EFUSE_BYTES: // To get EFUE total used bytes, added by Roger, 2008.12.22.
5429                         *((u16 *)(val)) = pHalData->EfuseUsedBytes;     
5430                         break;
5431                 case HW_VAR_APFM_ON_MAC:
5432                         *val = pHalData->bMacPwrCtrlOn;
5433                         break;
5434                 case HW_VAR_CHK_HI_QUEUE_EMPTY:
5435                         *val = ((rtw_read32(adapter, REG_HGQ_INFO)&0x0000ff00)==0) ? _TRUE:_FALSE;
5436                         break;
5437                 case HW_VAR_DUMP_MAC_QUEUE_INFO:
5438                         dump_mac_qinfo_88e(val, adapter);
5439                         break;
5440                 default:
5441                         GetHwReg(adapter, variable, val);
5442                         break;
5443         }
5444
5445 _func_exit_;
5446 }
5447 void hal_ra_info_dump(_adapter *padapter , void *sel)
5448 {
5449         int i;
5450         u8 mac_id;
5451         u8 bLinked = _FALSE;
5452         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
5453         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
5454         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
5455
5456 #ifdef CONFIG_CONCURRENT_MODE
5457                 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
5458 #endif /*CONFIG_CONCURRENT_MODE*/
5459
5460         for (i = 0; i < macid_ctl->num; i++) {
5461
5462                 if (rtw_macid_is_used(macid_ctl, i) && !rtw_macid_is_bmc(macid_ctl, i)) {
5463
5464                         mac_id = (u8) i;
5465                         if (rtw_linked_check(padapter))
5466                                 bLinked = _TRUE;
5467
5468 #ifdef CONFIG_CONCURRENT_MODE
5469                         if (pbuddy_adapter && rtw_linked_check(pbuddy_adapter))
5470                                 bLinked = _TRUE;
5471 #endif
5472
5473                         if (bLinked) {
5474                                 DBG_871X_SEL(sel , "============ RA status - Mac_id:%d ===================\n", mac_id);
5475                                 if (pHalData->fw_ractrl == _FALSE) {
5476                                         #if (RATE_ADAPTIVE_SUPPORT == 1)
5477                                                 DBG_871X_SEL(sel , "Mac_id:%d ,RSSI:%d(%%)\n", mac_id, pHalData->odmpriv.RAInfo[mac_id].RssiStaRA);
5478
5479                                                 DBG_871X_SEL(sel , "RateSGI = %d, DecisionRate = %s\n", pHalData->odmpriv.RAInfo[mac_id].RateSGI, HDATA_RATE(pHalData->odmpriv.RAInfo[mac_id].DecisionRate));
5480
5481                                                 DBG_871X_SEL(sel , "PTStage = %d\n", pHalData->odmpriv.RAInfo[mac_id].PTStage);
5482
5483                                                 DBG_871X_SEL(sel , "RateID = %d,RAUseRate = 0x%08x\n", pHalData->odmpriv.RAInfo[mac_id].RateID, pHalData->odmpriv.RAInfo[mac_id].RAUseRate);
5484
5485                                         #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
5486                                 } else{
5487                                         u8 cur_rate = rtw_read8(padapter, REG_ADAPTIVE_DATA_RATE_0+mac_id);
5488                                         u8 sgi = (cur_rate & BIT7)?_TRUE:_FALSE;
5489
5490                                         cur_rate &= 0x7f;
5491
5492                                         DBG_871X_SEL(sel , "Mac_id:%d ,SGI:%d ,Rate:%s\n", mac_id, sgi, HDATA_RATE(cur_rate));
5493                                 }
5494                         }
5495                 }
5496         }
5497 }
5498
5499 u8
5500 GetHalDefVar8188E(
5501         IN      PADAPTER                                Adapter,
5502         IN      HAL_DEF_VARIABLE                eVariable,
5503         IN      PVOID                                   pValue
5504         )
5505 {
5506         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);      
5507         u8                      bResult = _SUCCESS;
5508
5509         switch(eVariable)
5510         {
5511                 case HAL_DEF_IS_SUPPORT_ANT_DIV:
5512 #ifdef CONFIG_ANTENNA_DIVERSITY
5513                         *((u8 *)pValue) = (pHalData->AntDivCfg==0)?_FALSE:_TRUE;
5514                         #endif
5515 break;
5516                 case HAL_DEF_DRVINFO_SZ:
5517                         *(( u32*)pValue) = DRVINFO_SZ;
5518                         break;  
5519                 case HAL_DEF_MAX_RECVBUF_SZ:
5520 #ifdef CONFIG_SDIO_HCI
5521                         *((u32 *)pValue) = MAX_RX_DMA_BUFFER_SIZE_88E(Adapter);
5522 #else
5523                         *((u32 *)pValue) = MAX_RECVBUF_SZ;
5524 #endif
5525                         break;
5526                 case HAL_DEF_RX_PACKET_OFFSET:
5527                         *(( u32*)pValue) = RXDESC_SIZE + DRVINFO_SZ;
5528                         break;                  
5529 #if (RATE_ADAPTIVE_SUPPORT == 1)
5530                 case HAL_DEF_RA_DECISION_RATE:
5531                         {
5532                                 u8 MacID = *((u8*)pValue);
5533                                 *((u8*)pValue) = ODM_RA_GetDecisionRate_8188E(&(pHalData->odmpriv), MacID);
5534                         }
5535                         break;
5536                 
5537                 case HAL_DEF_RA_SGI:
5538                         {
5539                                 u8 MacID = *((u8*)pValue);
5540                                 *((u8*)pValue) = ODM_RA_GetShortGI_8188E(&(pHalData->odmpriv), MacID);
5541                         }
5542                         break;          
5543 #endif
5544
5545
5546                 case HAL_DEF_PT_PWR_STATUS:
5547 #if(POWER_TRAINING_ACTIVE==1)   
5548                         {
5549                                 u8 MacID = *((u8*)pValue);
5550                                 *((u8*)pValue) = ODM_RA_GetHwPwrStatus_8188E(&(pHalData->odmpriv), MacID);
5551                         }
5552 #endif //(POWER_TRAINING_ACTIVE==1)
5553                         break;          
5554                 case HAL_DEF_EXPLICIT_BEAMFORMEE:
5555                 case HAL_DEF_EXPLICIT_BEAMFORMER:
5556                         *((u8 *)pValue) = _FALSE;
5557                         break;
5558
5559                 case HW_DEF_RA_INFO_DUMP:
5560                         hal_ra_info_dump(Adapter, pValue);
5561                         break;
5562
5563                 case HAL_DEF_TX_PAGE_SIZE:
5564                          *(( u32*)pValue) = PAGE_SIZE_128;
5565                         break;
5566                 case HAL_DEF_TX_PAGE_BOUNDARY:
5567                         if (!Adapter->registrypriv.wifi_spec)
5568                                 *(u8*)pValue = TX_PAGE_BOUNDARY_88E(Adapter);
5569                         else
5570                                 *(u8*)pValue = WMM_NORMAL_TX_PAGE_BOUNDARY_88E(Adapter);
5571                         break;
5572                 case HAL_DEF_MACID_SLEEP:
5573                         *(u8*)pValue = _TRUE; // support macid sleep
5574                         break;
5575                 case HAL_DEF_RX_DMA_SZ_WOW:
5576                         *(u32 *)pValue = RX_DMA_SIZE_88E(Adapter) - RESV_FMWF;
5577                         break;
5578                 case HAL_DEF_RX_DMA_SZ:
5579                         *(u32 *)pValue = MAX_RX_DMA_BUFFER_SIZE_88E(Adapter);
5580                         break;
5581                 case HAL_DEF_RX_PAGE_SIZE:
5582                         *(u32 *)pValue = PAGE_SIZE_128;
5583                         break;
5584                 case HW_VAR_BEST_AMPDU_DENSITY:
5585                         *((u32 *)pValue) = AMPDU_DENSITY_VALUE_7;
5586                         break;
5587                 default:
5588                         bResult = GetHalDefVar(Adapter, eVariable, pValue);
5589                         break;
5590         }
5591
5592         return bResult;
5593 }
5594