37cb5cc5fb662fff7479d2717c5b1cc1834f262f
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bs / hal / rtl8723b / rtl8723b_hal_init.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2013 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 <rtl8723b_hal.h>
23 #include "rtw_bt_mp.h"
24 #include "hal_com_h2c.h"
25
26 static VOID
27 _FWDownloadEnable(
28         IN      PADAPTER                padapter,
29         IN      BOOLEAN                 enable
30         )
31 {
32         u8      tmp, count = 0;
33
34         if(enable)
35         {
36                 // 8051 enable
37                 tmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
38                 rtw_write8(padapter, REG_SYS_FUNC_EN+1, tmp|0x04);
39
40                 tmp = rtw_read8(padapter, REG_MCUFWDL);
41                 rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
42
43                 do{
44                         tmp = rtw_read8(padapter, REG_MCUFWDL);
45                         if(tmp & 0x01)
46                                 break;
47                         rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
48                         rtw_msleep_os(1);
49                 }while(count++<100);
50                 if(count > 0)
51                         DBG_871X("%s: !!!!!!!!Write 0x80 Fail!: count = %d\n", __func__, count);
52
53                 // 8051 reset
54                 tmp = rtw_read8(padapter, REG_MCUFWDL+2);
55                 rtw_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
56         }
57         else
58         {
59                 // MCU firmware download disable.
60                 tmp = rtw_read8(padapter, REG_MCUFWDL);
61                 rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
62         }
63 }
64
65 static int
66 _BlockWrite(
67         IN              PADAPTER                padapter,
68         IN              PVOID           buffer,
69         IN              u32                     buffSize
70         )
71 {
72         int ret = _SUCCESS;
73
74         u32                     blockSize_p1 = 4;       // (Default) Phase #1 : PCI muse use 4-byte write to download FW
75         u32                     blockSize_p2 = 8;       // Phase #2 : Use 8-byte, if Phase#1 use big size to write FW.
76         u32                     blockSize_p3 = 1;       // Phase #3 : Use 1-byte, the remnant of FW image.
77         u32                     blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
78         u32                     remainSize_p1 = 0, remainSize_p2 = 0;
79         u8                      *bufferPtr      = (u8*)buffer;
80         u32                     i=0, offset=0;
81 #ifdef CONFIG_PCI_HCI
82         u8                      remainFW[4] = {0, 0, 0, 0};
83         u8                      *p = NULL;
84 #endif
85
86 #ifdef CONFIG_USB_HCI
87         blockSize_p1 = 254;
88 #endif
89
90 //      printk("====>%s %d\n", __func__, __LINE__);
91
92         //3 Phase #1
93         blockCount_p1 = buffSize / blockSize_p1;
94         remainSize_p1 = buffSize % blockSize_p1;
95
96         if (blockCount_p1) {
97                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
98                                 ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) blockCount_p1(%d) remainSize_p1(%d)\n",
99                                 buffSize, blockSize_p1, blockCount_p1, remainSize_p1));
100         }
101
102         for (i = 0; i < blockCount_p1; i++)
103         {
104 #ifdef CONFIG_USB_HCI
105                 ret = rtw_writeN(padapter, (FW_8723B_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
106 #else
107                 ret = rtw_write32(padapter, (FW_8723B_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32*)(bufferPtr + i * blockSize_p1))));
108 #endif
109                 if(ret == _FAIL) {
110                         printk("====>%s %d i:%d\n", __func__, __LINE__, i);
111                         goto exit;
112                 }
113         }
114
115 #ifdef CONFIG_PCI_HCI
116         p = (u8*)((u32*)(bufferPtr + blockCount_p1 * blockSize_p1));
117         if (remainSize_p1) {
118                 switch (remainSize_p1) {
119                 case 0:
120                         break;
121                 case 3:
122                         remainFW[2]=*(p+2);
123                 case 2:         
124                         remainFW[1]=*(p+1);
125                 case 1:         
126                         remainFW[0]=*(p);
127                         ret = rtw_write32(padapter, (FW_8723B_START_ADDRESS + blockCount_p1 * blockSize_p1), 
128                                  le32_to_cpu(*(u32*)remainFW)); 
129                 }
130                 return ret;
131         }
132 #endif
133
134         //3 Phase #2
135         if (remainSize_p1)
136         {
137                 offset = blockCount_p1 * blockSize_p1;
138
139                 blockCount_p2 = remainSize_p1/blockSize_p2;
140                 remainSize_p2 = remainSize_p1%blockSize_p2;
141
142                 if (blockCount_p2) {
143                                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
144                                                 ("_BlockWrite: [P2] buffSize_p2(%d) blockSize_p2(%d) blockCount_p2(%d) remainSize_p2(%d)\n",
145                                                 (buffSize-offset), blockSize_p2 ,blockCount_p2, remainSize_p2));
146                 }
147
148 #ifdef CONFIG_USB_HCI
149                 for (i = 0; i < blockCount_p2; i++) {
150                         ret = rtw_writeN(padapter, (FW_8723B_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
151
152                         if(ret == _FAIL)
153                                 goto exit;
154                 }
155 #endif
156         }
157
158         //3 Phase #3
159         if (remainSize_p2)
160         {
161                 offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
162
163                 blockCount_p3 = remainSize_p2 / blockSize_p3;
164
165                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
166                                 ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) blockCount_p3(%d)\n",
167                                 (buffSize-offset), blockSize_p3, blockCount_p3));
168
169                 for(i = 0 ; i < blockCount_p3 ; i++){
170                         ret = rtw_write8(padapter, (FW_8723B_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
171
172                         if(ret == _FAIL) {
173                                 printk("====>%s %d i:%d\n", __func__, __LINE__, i);
174                                 goto exit;
175                         }
176                 }
177         }
178 exit:
179         return ret;
180 }
181
182 static int
183 _PageWrite(
184         IN              PADAPTER        padapter,
185         IN              u32                     page,
186         IN              PVOID           buffer,
187         IN              u32                     size
188         )
189 {
190         u8 value8;
191         u8 u8Page = (u8) (page & 0x07) ;
192
193         value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page ;
194         rtw_write8(padapter, REG_MCUFWDL+2,value8);
195
196         return _BlockWrite(padapter,buffer,size);
197 }
198
199 static VOID
200 _FillDummy(
201         u8*             pFwBuf,
202         u32*    pFwLen
203         )
204 {
205         u32     FwLen = *pFwLen;
206         u8      remain = (u8)(FwLen%4);
207         remain = (remain==0)?0:(4-remain);
208
209         while(remain>0)
210         {
211                 pFwBuf[FwLen] = 0;
212                 FwLen++;
213                 remain--;
214         }
215
216         *pFwLen = FwLen;
217 }
218
219 static int
220 _WriteFW(
221         IN              PADAPTER                padapter,
222         IN              PVOID                   buffer,
223         IN              u32                     size
224         )
225 {
226         // Since we need dynamic decide method of dwonload fw, so we call this function to get chip version.
227         // We can remove _ReadChipVersion from ReadpadapterInfo8192C later.
228         int ret = _SUCCESS;
229         u32     pageNums,remainSize ;
230         u32     page, offset;
231         u8              *bufferPtr = (u8*)buffer;
232
233 #ifdef CONFIG_PCI_HCI
234         // 20100120 Joseph: Add for 88CE normal chip.
235         // Fill in zero to make firmware image to dword alignment.
236         _FillDummy(bufferPtr, &size);
237 #endif
238
239         pageNums = size / MAX_DLFW_PAGE_SIZE ;
240         //RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4 \n"));
241         remainSize = size % MAX_DLFW_PAGE_SIZE;
242
243         for (page = 0; page < pageNums; page++) {
244                 offset = page * MAX_DLFW_PAGE_SIZE;
245                 ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_DLFW_PAGE_SIZE);
246
247                 if(ret == _FAIL) {
248                         printk("====>%s %d\n", __func__, __LINE__);
249                         goto exit;
250                 }
251         }
252         if (remainSize) {
253                 offset = pageNums * MAX_DLFW_PAGE_SIZE;
254                 page = pageNums;
255                 ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize);
256
257                 if(ret == _FAIL) {
258                         printk("====>%s %d\n", __func__, __LINE__);
259                         goto exit;
260                 }
261         }
262         RT_TRACE(_module_hal_init_c_, _drv_info_, ("_WriteFW Done- for Normal chip.\n"));
263
264 exit:
265         return ret;
266 }
267
268 void _8051Reset8723(PADAPTER padapter)
269 {
270         u8 cpu_rst;
271         u8 io_rst;
272
273         io_rst = rtw_read8(padapter, REG_RSV_CTRL);
274         rtw_write8(padapter, REG_RSV_CTRL, io_rst&(~BIT1));
275         // Reset 8051(WLMCU) IO wrapper
276         // 0x1c[8] = 0
277         // Suggested by Isaac@SD1 and Gimmy@SD1, coding by Lucas@20130624
278         io_rst = rtw_read8(padapter, REG_RSV_CTRL+1);
279         io_rst &= ~BIT(0);
280         rtw_write8(padapter, REG_RSV_CTRL+1, io_rst);
281
282         cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
283         cpu_rst &= ~BIT(2);
284         rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst);
285
286         io_rst = rtw_read8(padapter, REG_RSV_CTRL);
287         rtw_write8(padapter, REG_RSV_CTRL, io_rst&(~BIT1));
288         // Enable 8051 IO wrapper       
289         // 0x1c[8] = 1
290         io_rst = rtw_read8(padapter, REG_RSV_CTRL+1);
291         io_rst |= BIT(0);
292         rtw_write8(padapter, REG_RSV_CTRL+1, io_rst);
293
294         cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
295         cpu_rst |= BIT(2);
296         rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst);
297
298         DBG_8192C("%s: Finish\n", __FUNCTION__);
299 }
300
301 static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
302 {
303         s32 ret = _FAIL;
304         u32 value32;
305         u32 start = rtw_get_current_time();
306         u32 cnt = 0;
307
308         /* polling CheckSum report */
309         do {
310                 cnt++;
311                 value32 = rtw_read32(adapter, REG_MCUFWDL);
312                 if (value32 & FWDL_ChkSum_rpt || adapter->bSurpriseRemoved || adapter->bDriverStopped)
313                         break;
314                 rtw_yield_os();
315         } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
316
317         if (!(value32 & FWDL_ChkSum_rpt)) {
318                 goto exit;
319         }
320
321         if (rtw_fwdl_test_trigger_chksum_fail())
322                 goto exit;
323
324         ret = _SUCCESS;
325
326 exit:
327         DBG_871X("%s: Checksum report %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
328         , (ret==_SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), value32);
329
330         return ret;
331 }
332
333 static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
334 {
335         s32 ret = _FAIL;
336         u32     value32;
337         u32 start = rtw_get_current_time();
338         u32 cnt = 0;
339
340         value32 = rtw_read32(adapter, REG_MCUFWDL);
341         value32 |= MCUFWDL_RDY;
342         value32 &= ~WINTINI_RDY;
343         rtw_write32(adapter, REG_MCUFWDL, value32);
344
345         _8051Reset8723(adapter);
346
347         /*  polling for FW ready */
348         do {
349                 cnt++;
350                 value32 = rtw_read32(adapter, REG_MCUFWDL);
351                 if (value32 & WINTINI_RDY || adapter->bSurpriseRemoved || adapter->bDriverStopped)
352                         break;
353                 rtw_yield_os();
354         } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
355
356         if (!(value32 & WINTINI_RDY)) {
357                 goto exit;
358         }
359
360         if (rtw_fwdl_test_trigger_wintint_rdy_fail())
361                 goto exit;
362
363         ret = _SUCCESS;
364
365 exit:
366         DBG_871X("%s: Polling FW ready %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
367                 , (ret==_SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), value32);
368
369         return ret;
370 }
371
372 #define IS_FW_81xxC(padapter)   (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
373
374 void rtl8723b_FirmwareSelfReset(PADAPTER padapter)
375 {
376         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
377         u8      u1bTmp;
378         u8      Delay = 100;
379
380         if (!(IS_FW_81xxC(padapter) &&
381                   ((pHalData->FirmwareVersion < 0x21) ||
382                    (pHalData->FirmwareVersion == 0x21 &&
383                     pHalData->FirmwareSubVersion < 0x01)))) // after 88C Fw v33.1
384         {
385                 //0x1cf=0x20. Inform 8051 to reset. 2009.12.25. tynli_test
386                 rtw_write8(padapter, REG_HMETFR+3, 0x20);
387
388                 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
389                 while (u1bTmp & BIT2)
390                 {
391                         Delay--;
392                         if(Delay == 0)
393                                 break;
394                         rtw_udelay_os(50);
395                         u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
396                 }
397                 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("-%s: 8051 reset success (%d)\n", __FUNCTION__, Delay));
398
399                 if (Delay == 0)
400                 {
401                         RT_TRACE(_module_hal_init_c_, _drv_notice_, ("%s: Force 8051 reset!!!\n", __FUNCTION__));
402                         //force firmware reset
403                         u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
404                         rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
405                 }
406         }
407 }
408
409 #ifdef CONFIG_FILE_FWIMG
410 extern char *rtw_fw_file_path;
411 extern char *rtw_fw_wow_file_path;
412 #ifdef CONFIG_MP_INCLUDED
413 extern char *rtw_fw_mp_bt_file_path;
414 #endif // CONFIG_MP_INCLUDED
415 u8 FwBuffer[FW_8723B_SIZE];
416 #endif // CONFIG_FILE_FWIMG
417
418 #ifdef CONFIG_MP_INCLUDED
419 int _WriteBTFWtoTxPktBuf8723B(
420         IN              PADAPTER                Adapter,
421         IN              PVOID                   buffer,
422         IN              u4Byte                  FwBufLen,
423         IN              u1Byte                  times
424         )
425 {
426         int                     rtStatus = _SUCCESS;
427         //u4Byte                                value32;
428         //u1Byte                                numHQ, numLQ, numPubQ;//, txpktbuf_bndy;
429         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(Adapter);
430         //PMGNT_INFO            pMgntInfo = &(Adapter->MgntInfo);
431         u1Byte                          BcnValidReg;
432         u1Byte                          count=0, DLBcnCount=0;
433         pu1Byte                         FwbufferPtr = (pu1Byte)buffer;
434         //PRT_TCB                       pTcb, ptempTcb;
435         //PRT_TX_LOCAL_BUFFER pBuf;
436         BOOLEAN                         bRecover=_FALSE;
437         pu1Byte                         ReservedPagePacket = NULL;
438         pu1Byte                         pGenBufReservedPagePacket = NULL;
439         u4Byte                          TotalPktLen,txpktbuf_bndy;
440         //u1Byte                                tmpReg422;
441         //u1Byte                                u1bTmp;
442         u8                      *pframe;
443         struct xmit_priv        *pxmitpriv = &(Adapter->xmitpriv);
444         struct xmit_frame       *pmgntframe;
445         struct pkt_attrib       *pattrib;
446         u8                      txdesc_offset = TXDESC_OFFSET;
447         u8                      val8;
448 #if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
449         u8                      u1bTmp;
450 #endif
451
452 #if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
453         TotalPktLen = FwBufLen;
454 #else
455         TotalPktLen = FwBufLen+pHalData->HWDescHeadLength;
456 #endif
457
458         if((TotalPktLen+TXDESC_OFFSET) > MAX_CMDBUF_SZ)
459         {
460                 DBG_871X(" WARNING %s => Total packet len = %d > MAX_CMDBUF_SZ:%d \n"
461                         ,__FUNCTION__,(TotalPktLen+TXDESC_OFFSET),MAX_CMDBUF_SZ);
462                 return _FAIL;
463         }
464
465         pGenBufReservedPagePacket = rtw_zmalloc(TotalPktLen);//GetGenTempBuffer (Adapter, TotalPktLen);
466         if (!pGenBufReservedPagePacket)
467                 return _FAIL;
468
469         ReservedPagePacket = (u1Byte *)pGenBufReservedPagePacket;
470
471         _rtw_memset(ReservedPagePacket, 0, TotalPktLen);
472
473 #if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
474         _rtw_memcpy(ReservedPagePacket, FwbufferPtr, FwBufLen);
475
476 #else
477         PlatformMoveMemory(ReservedPagePacket+Adapter->HWDescHeadLength , FwbufferPtr, FwBufLen);
478 #endif
479
480         //---------------------------------------------------------
481         // 1. Pause BCN
482         //---------------------------------------------------------
483         //Set REG_CR bit 8. DMA beacon by SW.
484 #if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
485         u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR+1);
486         PlatformEFIOWrite1Byte(Adapter,  REG_CR+1, (u1bTmp|BIT0));
487 #else
488         // Remove for temparaily because of the code on v2002 is not sync to MERGE_TMEP for USB/SDIO.
489         // De not remove this part on MERGE_TEMP. by tynli.
490         //pHalData->RegCR_1 |= (BIT0);
491         //PlatformEFIOWrite1Byte(Adapter,  REG_CR+1, pHalData->RegCR_1);
492 #endif
493
494         // Disable Hw protection for a time which revserd for Hw sending beacon.
495         // Fix download reserved page packet fail that access collision with the protection time.
496         // 2010.05.11. Added by tynli.
497         val8 = rtw_read8(Adapter, REG_BCN_CTRL);
498         val8 &= ~EN_BCN_FUNCTION;
499         val8 |= DIS_TSF_UDT;
500         rtw_write8(Adapter, REG_BCN_CTRL, val8);
501
502 #if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
503         tmpReg422 = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL+2);
504         if( tmpReg422&BIT6)
505                 bRecover = TRUE;
506         PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2,  tmpReg422&(~BIT6));
507 #else
508         // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
509         if(pHalData->RegFwHwTxQCtrl & BIT(6))
510                 bRecover=_TRUE;
511         PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl&(~BIT(6))));
512         pHalData->RegFwHwTxQCtrl &= (~ BIT(6));
513 #endif
514
515         //---------------------------------------------------------
516         // 2. Adjust LLT table to an even boundary.
517         //---------------------------------------------------------
518 #if 0//(DEV_BUS_TYPE == RT_SDIO_INTERFACE)
519         txpktbuf_bndy = 10; // rsvd page start address should be an even value.                                                                                                                 
520         rtStatus =      InitLLTTable8723BS(Adapter, txpktbuf_bndy);
521         if(RT_STATUS_SUCCESS != rtStatus){
522                 DBG_8192C("_CheckWLANFwPatchBTFwReady_8723B(): Failed to init LLT!\n");
523                 return RT_STATUS_FAILURE;
524         }
525         
526         // Init Tx boundary.
527         PlatformEFIOWrite1Byte(Adapter, REG_DWBCN0_CTRL_8723B+1, (u1Byte)txpktbuf_bndy);        
528 #endif
529
530
531         //---------------------------------------------------------
532         // 3. Write Fw to Tx packet buffer by reseverd page.
533         //---------------------------------------------------------
534         do
535         {
536                 // download rsvd page.
537                 // Clear beacon valid check bit.
538                 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
539                 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+2, BcnValidReg&(~BIT(0)));
540
541                 //BT patch is big, we should set 0x209 < 0x40 suggested from Gimmy
542                 RT_TRACE(_module_mp_, _drv_info_,("0x209:%x\n",
543                                         PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1)));//209 < 0x40
544
545                 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+1, (0x90-0x20*(times-1)));
546                 DBG_871X("0x209:0x%x\n", PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1));
547                 RT_TRACE(_module_mp_, _drv_info_,("0x209:%x\n",
548                                         PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1)));
549
550 #if 0
551                 // Acquice TX spin lock before GetFwBuf and send the packet to prevent system deadlock.
552                 // Advertised by Roger. Added by tynli. 2010.02.22.
553                 PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
554                 if(MgntGetFWBuffer(Adapter, &pTcb, &pBuf))
555                 {
556                         PlatformMoveMemory(pBuf->Buffer.VirtualAddress, ReservedPagePacket, TotalPktLen);
557                         CmdSendPacket(Adapter, pTcb, pBuf, TotalPktLen, DESC_PACKET_TYPE_NORMAL, FALSE);
558                 }
559                 else
560                         dbgdump("SetFwRsvdPagePkt(): MgntGetFWBuffer FAIL!!!!!!!!.\n");
561                 PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
562 #else
563                 /*---------------------------------------------------------
564                 tx reserved_page_packet
565                 ----------------------------------------------------------*/
566                         if ((pmgntframe = rtw_alloc_cmdxmitframe(pxmitpriv)) == NULL) {
567                                         rtStatus = _FAIL;
568                                         goto exit;
569                         }
570                         //update attribute
571                         pattrib = &pmgntframe->attrib;
572                         update_mgntframe_attrib(Adapter, pattrib);
573
574                         pattrib->qsel = QSLT_BEACON;
575                         pattrib->pktlen = pattrib->last_txcmdsz = FwBufLen ;
576
577                         //_rtw_memset(pmgntframe->buf_addr, 0, TotalPktLen+txdesc_size);
578                         //pmgntframe->buf_addr = ReservedPagePacket ;
579
580                         _rtw_memcpy( (u8*) (pmgntframe->buf_addr + txdesc_offset), ReservedPagePacket, FwBufLen);
581                         DBG_871X("[%d]===>TotalPktLen + TXDESC_OFFSET TotalPacketLen:%d \n", DLBcnCount, (FwBufLen + txdesc_offset));
582                         
583 #ifdef CONFIG_PCI_HCI
584                         dump_mgntframe(Adapter, pmgntframe);
585 #else
586                         dump_mgntframe_and_wait(Adapter, pmgntframe, 100);
587 #endif
588
589 #endif
590 #if 1
591                 // check rsvd page download OK.
592                 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
593                 while(!(BcnValidReg & BIT(0)) && count <200)
594                 {
595                         count++;
596                         //PlatformSleepUs(10);
597                         rtw_msleep_os(1);
598                         BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
599                         RT_TRACE(_module_mp_, _drv_notice_,("Poll 0x20A = %x\n", BcnValidReg));
600                 }
601                 DLBcnCount++;
602                 //DBG_871X("##0x208:%08x,0x210=%08x\n",PlatformEFIORead4Byte(Adapter, REG_TDECTRL),PlatformEFIORead4Byte(Adapter, 0x210));
603
604                 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+2,BcnValidReg);
605                 
606         }while((!(BcnValidReg&BIT(0))) && DLBcnCount<5);
607
608
609 #endif
610         if(DLBcnCount >=5){
611                 DBG_871X(" check rsvd page download OK DLBcnCount =%d  \n",DLBcnCount);
612                 rtStatus = _FAIL;
613                 goto exit;
614         }
615
616         if(!(BcnValidReg&BIT(0)))
617         {
618                 DBG_871X("_WriteFWtoTxPktBuf(): 1 Download RSVD page failed!\n");
619                 rtStatus = _FAIL;
620                 goto exit;
621         }
622
623         //---------------------------------------------------------
624         // 4. Set Tx boundary to the initial value
625         //---------------------------------------------------------
626
627
628         //---------------------------------------------------------
629         // 5. Reset beacon setting to the initial value.
630         //       After _CheckWLANFwPatchBTFwReady().
631         //---------------------------------------------------------
632
633 exit:
634
635         if(pGenBufReservedPagePacket)
636         {
637                 DBG_871X("_WriteBTFWtoTxPktBuf8723B => rtw_mfree pGenBufReservedPagePacket!\n");
638                 rtw_mfree((u8*)pGenBufReservedPagePacket, TotalPktLen);
639                 }
640         return rtStatus;
641 }
642
643
644
645 //
646 // Description: Determine the contents of H2C BT_FW_PATCH Command sent to FW.
647 // 2011.10.20 by tynli
648 //
649 void
650 SetFwBTFwPatchCmd(
651         IN PADAPTER     Adapter,
652         IN u16          FwSize
653         )
654 {
655         u8 u1BTFwPatchParm[H2C_BT_FW_PATCH_LEN]={0};
656         u8 addr0 = 0;
657         u8 addr1 = 0xa0;
658         u8 addr2 = 0x10;
659         u8 addr3 = 0x80;
660         
661         RT_TRACE(_module_mp_, _drv_notice_,("SetFwBTFwPatchCmd(): FwSize = %d\n", FwSize));
662
663         SET_8723B_H2CCMD_BT_FW_PATCH_SIZE(u1BTFwPatchParm, FwSize);
664         SET_8723B_H2CCMD_BT_FW_PATCH_ADDR0(u1BTFwPatchParm, addr0);
665         SET_8723B_H2CCMD_BT_FW_PATCH_ADDR1(u1BTFwPatchParm, addr1);
666         SET_8723B_H2CCMD_BT_FW_PATCH_ADDR2(u1BTFwPatchParm, addr2);
667         SET_8723B_H2CCMD_BT_FW_PATCH_ADDR3(u1BTFwPatchParm, addr3);
668
669         FillH2CCmd8723B(Adapter, H2C_8723B_BT_FW_PATCH, H2C_BT_FW_PATCH_LEN, u1BTFwPatchParm);
670
671         RT_TRACE(_module_mp_, _drv_notice_,("<----SetFwBTFwPatchCmd(): FwSize = %d \n", FwSize));
672 }
673
674 void
675 SetFwBTPwrCmd(
676         IN PADAPTER     Adapter,
677         IN u1Byte       PwrIdx
678         )
679 {
680         u1Byte          u1BTPwrIdxParm[H2C_FORCE_BT_TXPWR_LEN]={0};
681
682         RT_TRACE(_module_mp_, _drv_info_,("SetFwBTPwrCmd(): idx = %d\n", PwrIdx));
683         SET_8723B_H2CCMD_BT_PWR_IDX(u1BTPwrIdxParm, PwrIdx);
684
685         RT_TRACE(_module_mp_, _drv_info_,("SetFwBTPwrCmd(): %x %x %x\n",
686                 u1BTPwrIdxParm[0],u1BTPwrIdxParm[1],u1BTPwrIdxParm[2]));
687
688         FillH2CCmd8723B(Adapter, H2C_8723B_FORCE_BT_TXPWR, H2C_FORCE_BT_TXPWR_LEN, u1BTPwrIdxParm);
689 }
690
691 //
692 // Description: WLAN Fw will write BT Fw to BT XRAM and signal driver.
693 //
694 // 2011.10.20. by tynli.
695 //
696 int
697 _CheckWLANFwPatchBTFwReady(
698         IN      PADAPTER                        Adapter
699 )
700 {
701         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
702         u4Byte  count=0;
703         u1Byte  u1bTmp;
704         int ret = _FAIL;
705
706         //---------------------------------------------------------
707         // Check if BT FW patch procedure is ready.
708         //---------------------------------------------------------
709         do{
710                 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_HMEBOX_DBG_0_8723B);
711                 if((u1bTmp&BIT6) || (u1bTmp&BIT7))
712                 {
713                         ret = _SUCCESS;
714                         break;
715                 }
716
717                 count++;
718                 RT_TRACE(_module_mp_, _drv_info_,("0x88=%x, wait for 50 ms (%d) times.\n",
719                                         u1bTmp, count));
720                 rtw_msleep_os(50); // 50ms
721         }while(!((u1bTmp&BIT6) || (u1bTmp&BIT7)) && count < 50);
722
723         RT_TRACE(_module_mp_, _drv_notice_,("_CheckWLANFwPatchBTFwReady():"
724                                 " Polling ready bit 0x88[7] for %d times.\n", count));
725
726         if(count >= 50)
727         {
728                 RT_TRACE(_module_mp_, _drv_notice_,("_CheckWLANFwPatchBTFwReady():"
729                                 " Polling ready bit 0x88[7] FAIL!!\n"));
730         }
731
732         //---------------------------------------------------------
733         // Reset beacon setting to the initial value.
734         //---------------------------------------------------------
735 #if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
736         if(LLT_table_init(Adapter, FALSE, 0) == RT_STATUS_FAILURE)
737         {
738                 dbgdump("Init self define for BT Fw patch LLT table fail.\n");
739                 //return RT_STATUS_FAILURE;
740         }
741 #endif
742         u1bTmp = rtw_read8(Adapter, REG_BCN_CTRL);
743         u1bTmp |= EN_BCN_FUNCTION;
744         u1bTmp &= ~DIS_TSF_UDT;
745         rtw_write8(Adapter, REG_BCN_CTRL, u1bTmp);
746
747         // To make sure that if there exists an adapter which would like to send beacon.
748         // If exists, the origianl value of 0x422[6] will be 1, we should check this to
749         // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
750         // the beacon cannot be sent by HW.
751         // 2010.06.23. Added by tynli.
752 #if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
753         u1bTmp = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL+2);
754         PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (u1bTmp|BIT6));
755 #else
756         PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl|BIT(6)));
757         pHalData->RegFwHwTxQCtrl |= BIT(6);
758 #endif
759
760         // Clear CR[8] or beacon packet will not be send to TxBuf anymore.
761         u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR_8723B+1);
762         PlatformEFIOWrite1Byte(Adapter, REG_CR_8723B+1, (u1bTmp&(~BIT0)));
763
764         return ret;
765 }
766
767 int ReservedPage_Compare(PADAPTER Adapter,PRT_MP_FIRMWARE pFirmware,u32 BTPatchSize)
768 {
769         u8 temp,ret,lastBTsz;
770         u32 u1bTmp=0,address_start=0,count=0,i=0;
771         u8      *myBTFwBuffer = NULL;
772
773         myBTFwBuffer = rtw_zmalloc(BTPatchSize);
774         if (myBTFwBuffer == NULL)
775         {
776                 DBG_871X("%s can't be executed due to the failed malloc.\n", __FUNCTION__);
777                 Adapter->mppriv.bTxBufCkFail=_TRUE;
778                 return _FALSE;
779         }
780         
781         temp=rtw_read8(Adapter,0x209);
782         
783         address_start=(temp*128)/8;
784         
785         rtw_write32(Adapter,0x140,0x00000000);
786         rtw_write32(Adapter,0x144,0x00000000);
787         rtw_write32(Adapter,0x148,0x00000000);
788
789         rtw_write8(Adapter,0x106,0x69);
790         
791         for(i=0;i<(BTPatchSize/8);i++)
792         {
793                 rtw_write32(Adapter,0x140,address_start+5+i) ;            
794                         
795                 //polling until reg 0x140[23]=1;
796                 do{
797                         u1bTmp = rtw_read32(Adapter, 0x140);
798                         if(u1bTmp&BIT(23))
799                         {
800                                 ret = _SUCCESS;
801                                 break;
802                         }
803                         count++;
804                         DBG_871X("0x140=%x, wait for 10 ms (%d) times.\n",u1bTmp, count);
805                         rtw_msleep_os(10); // 10ms
806                 }while(!(u1bTmp&BIT(23)) && count < 50);
807                 
808                         myBTFwBuffer[i*8+0]=rtw_read8(Adapter, 0x144);
809                         myBTFwBuffer[i*8+1]=rtw_read8(Adapter, 0x145);
810                         myBTFwBuffer[i*8+2]=rtw_read8(Adapter, 0x146); 
811                         myBTFwBuffer[i*8+3]=rtw_read8(Adapter, 0x147);
812                         myBTFwBuffer[i*8+4]=rtw_read8(Adapter, 0x148);
813                         myBTFwBuffer[i*8+5]=rtw_read8(Adapter, 0x149);
814                         myBTFwBuffer[i*8+6]=rtw_read8(Adapter, 0x14a);
815                         myBTFwBuffer[i*8+7]=rtw_read8(Adapter, 0x14b);
816         }
817         
818         rtw_write32(Adapter,0x140,address_start+5+BTPatchSize/8) ;                        
819
820         lastBTsz=BTPatchSize%8;
821         
822         //polling until reg 0x140[23]=1;
823         u1bTmp=0;
824         count=0;
825         do{
826                         u1bTmp = rtw_read32(Adapter, 0x140);
827                         if(u1bTmp&BIT(23))
828                         {
829                                 ret = _SUCCESS;
830                                 break;
831                         }
832                         count++;
833                         DBG_871X("0x140=%x, wait for 10 ms (%d) times.\n",u1bTmp, count);
834                         rtw_msleep_os(10); // 10ms
835         }while(!(u1bTmp&BIT(23)) && count < 50);
836
837         for(i=0;i<lastBTsz;i++)
838         {
839                 myBTFwBuffer[(BTPatchSize/8)*8+i] = rtw_read8(Adapter, (0x144+i));
840
841         }
842
843         for(i=0;i<BTPatchSize;i++)
844         {
845                 if(myBTFwBuffer[i]!= pFirmware->szFwBuffer[i])
846                 {
847                         DBG_871X(" In direct myBTFwBuffer[%d]=%x , pFirmware->szFwBuffer=%x\n",i, myBTFwBuffer[i],pFirmware->szFwBuffer[i]);
848                         Adapter->mppriv.bTxBufCkFail=_TRUE;
849                         break;
850                 }
851         }
852
853         if (myBTFwBuffer != NULL)
854         {
855                 rtw_mfree(myBTFwBuffer, BTPatchSize);
856         }
857
858         return _TRUE;
859 }
860
861 /* As the size of bt firmware is more than 16k which is too big for some platforms, we divide it
862  * into four parts to transfer. The last parameter of _WriteBTFWtoTxPktBuf8723B is used to indicate
863  * the location of every part. We call the first 4096 byte of bt firmware as part 1, the second 4096
864  * part as part 2, the third 4096 part as part 3, the remain as part 4. First we transform the part
865  * 4 and set the register 0x209 to 0x90, then the 32 bytes description are added to the head of part
866  * 4, and those bytes are putted at the location 0x90. Second we transform the part 3 and set the 
867  * register 0x209 to 0x70. The 32 bytes description and part 3(4196 bytes) are putted at the location
868  * 0x70. It can contain 4196 bytes between 0x70 and 0x90. So the last 32 bytes os part 3 will cover the
869  * 32 bytes description of part4. Using this method, we can put the whole bt firmware to 0x30 and only
870  * has 32 bytes descrption at the head of part 1.    
871 */
872 s32 FirmwareDownloadBT(PADAPTER padapter, PRT_MP_FIRMWARE pFirmware)
873 {
874         s32 rtStatus;
875         u8 *pBTFirmwareBuf;
876         u32 BTFirmwareLen;
877         u8 download_time;
878         s8 i;
879
880
881         rtStatus = _SUCCESS;
882         pBTFirmwareBuf = NULL;
883         BTFirmwareLen = 0;
884
885         //
886         // Patch BT Fw. Download BT RAM code to Tx packet buffer.
887         //
888         if (padapter->bBTFWReady) {
889                 DBG_8192C("%s: BT Firmware is ready!!\n", __FUNCTION__);
890                 return _FAIL;
891         }
892
893 #ifdef CONFIG_FILE_FWIMG
894         if (rtw_is_file_readable(rtw_fw_mp_bt_file_path) == _TRUE)
895         {
896                 DBG_8192C("%s: accquire MP BT FW from file:%s\n", __FUNCTION__, rtw_fw_mp_bt_file_path);
897
898                 rtStatus = rtw_retrive_from_file(rtw_fw_mp_bt_file_path, FwBuffer, FW_8723B_SIZE);
899                 BTFirmwareLen = rtStatus>=0?rtStatus:0;
900                 pBTFirmwareBuf = FwBuffer;
901         }
902         else
903 #endif // CONFIG_FILE_FWIMG
904         {
905 #ifdef CONFIG_EMBEDDED_FWIMG
906                 DBG_8192C("%s: Download MP BT FW from header\n", __FUNCTION__);
907
908                 pBTFirmwareBuf = (u8*)Rtl8723BFwBTImgArray;
909                 BTFirmwareLen = Rtl8723BFwBTImgArrayLength;
910                 pFirmware->szFwBuffer = pBTFirmwareBuf;
911                 pFirmware->ulFwLength = BTFirmwareLen;
912 #endif // CONFIG_EMBEDDED_FWIMG
913         }
914
915         DBG_8192C("%s: MP BT Firmware size=%d\n", __FUNCTION__, BTFirmwareLen);
916
917         // for h2c cam here should be set to  true
918         padapter->bFWReady = _TRUE;
919
920         download_time = (BTFirmwareLen + 4095) / 4096;
921         DBG_8192C("%s: download_time is %d\n", __FUNCTION__, download_time);
922
923         // Download BT patch Fw.
924         for (i = (download_time-1); i >= 0; i--)
925         {
926                 if (i == (download_time - 1))
927                 {
928                         rtStatus = _WriteBTFWtoTxPktBuf8723B(padapter, pBTFirmwareBuf+(4096*i), (BTFirmwareLen-(4096*i)), 1);
929                         DBG_8192C("%s: start %d, len %d, time 1\n", __FUNCTION__, 4096*i, BTFirmwareLen-(4096*i));
930                 }
931                 else
932                 {
933                         rtStatus = _WriteBTFWtoTxPktBuf8723B(padapter, pBTFirmwareBuf+(4096*i), 4096, (download_time-i));
934                         DBG_8192C("%s: start %d, len 4096, time %d\n", __FUNCTION__, 4096*i, download_time-i);
935                 }
936
937                 if (rtStatus != _SUCCESS)
938                 {
939                         DBG_8192C("%s: BT Firmware download to Tx packet buffer fail!\n", __FUNCTION__);
940                         padapter->bBTFWReady = _FALSE;
941                         return rtStatus;
942                 }
943         }
944
945         ReservedPage_Compare(padapter,pFirmware,BTFirmwareLen);
946
947         padapter->bBTFWReady = _TRUE;
948         SetFwBTFwPatchCmd(padapter, (u16)BTFirmwareLen);
949         rtStatus = _CheckWLANFwPatchBTFwReady(padapter);
950
951         DBG_8192C("<===%s: return %s!\n", __FUNCTION__, rtStatus==_SUCCESS?"SUCCESS":"FAIL");
952         return rtStatus;
953 }
954 #endif // CONFIG_MP_INCLUDED
955
956 //
957 //      Description:
958 //              Download 8192C firmware code.
959 //
960 //
961 s32 rtl8723b_FirmwareDownload(PADAPTER padapter, BOOLEAN  bUsedWoWLANFw)
962 {
963         s32     rtStatus = _SUCCESS;
964         u8 write_fw = 0;
965         u32 fwdl_start_time;
966         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
967         s8                      R8723BFwImageFileName[] ={RTL8723B_FW_IMG};
968         u8                      *FwImage;
969         u32                     FwImageLen;
970         u8                      *pFwImageFileName;
971 #ifdef CONFIG_WOWLAN
972         u8                      *FwImageWoWLAN;
973         u32                     FwImageWoWLANLen;
974 #endif  
975         u8                      *pucMappedFile = NULL;
976         PRT_FIRMWARE_8723B      pFirmware = NULL;
977         PRT_FIRMWARE_8723B      pBTFirmware = NULL;
978         PRT_8723B_FIRMWARE_HDR          pFwHdr = NULL;
979         u8                      *pFirmwareBuf;
980         u32                     FirmwareLen;
981 #ifdef CONFIG_FILE_FWIMG
982         u8 *fwfilepath;
983 #endif // CONFIG_FILE_FWIMG
984         struct dvobj_priv *psdpriv = padapter->dvobj;
985         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
986         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
987
988         RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __FUNCTION__));
989 #ifdef CONFIG_WOWLAN
990         RT_TRACE(_module_hal_init_c_, _drv_notice_, ("+%s, bUsedWoWLANFw:%d\n", __FUNCTION__,bUsedWoWLANFw));
991 #endif
992         pFirmware = (PRT_FIRMWARE_8723B)rtw_zmalloc(sizeof(RT_FIRMWARE_8723B));
993
994         if(!pFirmware)
995         {
996                 rtStatus = _FAIL;
997                 goto exit;
998         }
999
1000         {
1001                         u8 tmp_ps=0, tmp_rf=0;
1002                         tmp_ps=rtw_read8(padapter,0xa3);
1003                         tmp_ps&=0xf8;
1004                         tmp_ps|=0x02;
1005                         //1. write 0xA3[:2:0] = 3b'010
1006                         rtw_write8(padapter, 0xa3, tmp_ps);
1007                         //2. read power_state = 0xA0[1:0]
1008                         tmp_ps=rtw_read8(padapter,0xa0);
1009                         tmp_ps&=0x03;
1010                         if(tmp_ps != 0x01)
1011                         {
1012                                 DBG_871X(FUNC_ADPT_FMT" tmp_ps=%x \n",FUNC_ADPT_ARG(padapter), tmp_ps);
1013                                 pdbgpriv->dbg_downloadfw_pwr_state_cnt++;
1014                         }
1015         }
1016
1017         rtw_btcoex_PreLoadFirmware(padapter);
1018         
1019 #ifdef CONFIG_FILE_FWIMG
1020 #ifdef CONFIG_WOWLAN
1021         if (bUsedWoWLANFw)
1022         {
1023                 fwfilepath = rtw_fw_wow_file_path;
1024         }
1025         else
1026 #endif // CONFIG_WOWLAN
1027         {
1028                 fwfilepath = rtw_fw_file_path;
1029         }
1030 #endif // CONFIG_FILE_FWIMG
1031
1032 #ifdef CONFIG_FILE_FWIMG
1033         if (rtw_is_file_readable(fwfilepath) == _TRUE)
1034         {
1035                 DBG_8192C("%s accquire FW from file:%s\n", __FUNCTION__, fwfilepath);
1036                 pFirmware->eFWSource = FW_SOURCE_IMG_FILE;
1037         }
1038         else
1039 #endif // CONFIG_FILE_FWIMG
1040         {
1041 #ifdef CONFIG_EMBEDDED_FWIMG
1042                 pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
1043 #else // !CONFIG_EMBEDDED_FWIMG
1044                 pFirmware->eFWSource = FW_SOURCE_IMG_FILE; // We should decided by Reg.
1045 #endif // !CONFIG_EMBEDDED_FWIMG
1046         }
1047
1048         switch(pFirmware->eFWSource)
1049         {
1050                 case FW_SOURCE_IMG_FILE:
1051 #ifdef CONFIG_FILE_FWIMG
1052                         rtStatus = rtw_retrive_from_file(fwfilepath, FwBuffer, FW_8723B_SIZE);
1053                         pFirmware->ulFwLength = rtStatus>=0?rtStatus:0;
1054                         pFirmware->szFwBuffer = FwBuffer;
1055 #endif // CONFIG_FILE_FWIMG
1056                         break;
1057
1058                 case FW_SOURCE_HEADER_FILE:
1059 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1060                 if (bUsedWoWLANFw) {
1061                         if (!pwrpriv->wowlan_ap_mode) {
1062                                 ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv,
1063                                                 CONFIG_FW_WoWLAN,
1064                                                 (u8*)&pFirmware->szFwBuffer,
1065                                                 &pFirmware->ulFwLength);
1066
1067                                 DBG_8192C(" ===> %s fw: %s, size: %d\n",
1068                                                 __FUNCTION__, "WoWLAN",
1069                                                 pFirmware->ulFwLength);
1070                         } else {
1071                                 ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv,
1072                                                 CONFIG_FW_AP_WoWLAN,
1073                                                 (u8*)&pFirmware->szFwBuffer,
1074                                                 &pFirmware->ulFwLength);
1075
1076                                 DBG_8192C(" ===> %s fw: %s, size: %d\n",
1077                                                 __FUNCTION__, "AP_WoWLAN",
1078                                                 pFirmware->ulFwLength);
1079                         }
1080                 } else
1081 #endif // CONFIG_WOWLAN
1082                         {
1083                                 if(padapter->registrypriv.mp_mode ==0)
1084                                 {
1085                                         ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, CONFIG_FW_NIC,
1086                                                 (u8*)&pFirmware->szFwBuffer, &pFirmware->ulFwLength);
1087                                         DBG_8192C("%s fw: %s, size: %d\n", __FUNCTION__, "FW_NIC", pFirmware->ulFwLength);
1088                                 }
1089                                 else
1090                                 {
1091                                         ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, CONFIG_FW_MP,
1092                                                 (u8*)&pFirmware->szFwBuffer, &pFirmware->ulFwLength);
1093                                         DBG_8192C("%s fw: %s, size: %d\n", __FUNCTION__, "FW_MP", pFirmware->ulFwLength);
1094                                 }
1095                         }
1096                         break;
1097         }
1098
1099         if (pFirmware->ulFwLength > FW_8723B_SIZE) {
1100                 rtStatus = _FAIL;
1101                 DBG_871X_LEVEL(_drv_emerg_, "Firmware size:%u exceed %u\n", pFirmware->ulFwLength, FW_8723B_SIZE);
1102                 goto exit;
1103         }
1104
1105         pFirmwareBuf = pFirmware->szFwBuffer;
1106         FirmwareLen = pFirmware->ulFwLength;
1107
1108         // To Check Fw header. Added by tynli. 2009.12.04.
1109         pFwHdr = (PRT_8723B_FIRMWARE_HDR)pFirmwareBuf;
1110
1111         pHalData->FirmwareVersion =  le16_to_cpu(pFwHdr->Version);
1112         pHalData->FirmwareSubVersion = le16_to_cpu(pFwHdr->Subversion);
1113         pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
1114
1115         DBG_871X("%s: fw_ver=%x fw_subver=%04x sig=0x%x, Month=%02x, Date=%02x, Hour=%02x, Minute=%02x\n",
1116                   __FUNCTION__, pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, pHalData->FirmwareSignature
1117                   ,pFwHdr->Month,pFwHdr->Date,pFwHdr->Hour,pFwHdr->Minute);
1118
1119         if (IS_FW_HEADER_EXIST_8723B(pFwHdr))
1120         {
1121                 DBG_871X("%s(): Shift for fw header!\n", __func__);
1122                 // Shift 32 bytes for FW header
1123                 pFirmwareBuf = pFirmwareBuf + 32;
1124                 FirmwareLen = FirmwareLen - 32;
1125         }
1126
1127         // Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself,
1128         // or it will cause download Fw fail. 2010.02.01. by tynli.
1129         if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) //8051 RAM code
1130         {
1131                 rtw_write8(padapter, REG_MCUFWDL, 0x00);
1132                 rtl8723b_FirmwareSelfReset(padapter);
1133         }
1134
1135         _FWDownloadEnable(padapter, _TRUE);
1136         fwdl_start_time = rtw_get_current_time();
1137         while(!padapter->bDriverStopped && !padapter->bSurpriseRemoved
1138                         && (write_fw++ < 3 || rtw_get_passing_time_ms(fwdl_start_time) < 500))
1139         {
1140                 /* reset FWDL chksum */
1141                 rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL)|FWDL_ChkSum_rpt);
1142
1143                 rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
1144                 if (rtStatus != _SUCCESS)
1145                         continue;
1146
1147                 rtStatus = polling_fwdl_chksum(padapter, 5, 50);
1148                 if (rtStatus == _SUCCESS)
1149                         break;
1150         }
1151         _FWDownloadEnable(padapter, _FALSE);
1152         if(_SUCCESS != rtStatus)
1153                 goto fwdl_stat;
1154
1155         rtStatus = _FWFreeToGo(padapter, 10, 200);
1156         if (_SUCCESS != rtStatus)
1157                 goto fwdl_stat;
1158
1159 #ifdef CONFIG_MP_INCLUDED//BT_MP
1160         if (padapter->registrypriv.mp_mode == 1)
1161         {
1162                 //rtw_write8(padapter, 0x81, rtw_read8(padapter, 0x81)|BIT0);
1163                 DBG_871X("rtl8723b_FirmwareDownload go to FirmwareDownloadBT !\n");
1164                 pBTFirmware = (PRT_FIRMWARE_8723B)rtw_zmalloc(sizeof(RT_FIRMWARE_8723B));
1165                 if(!pBTFirmware)
1166                 {
1167                         rtStatus = _FAIL;
1168                         goto exit;
1169                 }
1170                 FirmwareDownloadBT(padapter, (PRT_MP_FIRMWARE)pBTFirmware);
1171         }
1172 #endif
1173
1174 fwdl_stat:
1175         DBG_871X("FWDL %s. write_fw:%u, %dms\n"
1176                 , (rtStatus == _SUCCESS)?"success":"fail"
1177                 , write_fw
1178                 , rtw_get_passing_time_ms(fwdl_start_time)
1179         );
1180
1181 exit:
1182         if (pFirmware)
1183                 rtw_mfree((u8*)pFirmware, sizeof(RT_FIRMWARE_8723B));
1184         if (pBTFirmware)
1185                 rtw_mfree((u8*)pBTFirmware, sizeof(RT_FIRMWARE_8723B));
1186         DBG_871X(" <=== rtl8723b_FirmwareDownload()\n");
1187         return rtStatus;
1188 }
1189
1190 void rtl8723b_InitializeFirmwareVars(PADAPTER padapter)
1191 {
1192         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1193
1194         // Init Fw LPS related.
1195         adapter_to_pwrctl(padapter)->bFwCurrentInPSMode = _FALSE;
1196
1197         //Init H2C cmd.
1198         rtw_write8(padapter, REG_HMETFR, 0x0f);
1199         
1200         // Init H2C counter. by tynli. 2009.12.09.
1201         pHalData->LastHMEBoxNum = 0;
1202 //      pHalData->H2CQueueHead = 0;
1203 //      pHalData->H2CQueueTail = 0;
1204 //      pHalData->H2CStopInsertQueue = _FALSE;
1205 }
1206
1207 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1208 //===========================================
1209
1210 //
1211 // Description: Prepare some information to Fw for WoWLAN.
1212 //                                      (1) Download wowlan Fw.
1213 //                                      (2) Download RSVD page packets.
1214 //                                      (3) Enable AP offload if needed.
1215 //
1216 // 2011.04.12 by tynli.
1217 //
1218 VOID
1219 SetFwRelatedForWoWLAN8723b(
1220                 IN              PADAPTER                        padapter,
1221                 IN              u8                                      bHostIsGoingtoSleep
1222 )
1223 {
1224                 int                             status=_FAIL;
1225                 HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
1226                 u8                              bRecover = _FALSE;
1227         //
1228         // 1. Before WoWLAN we need to re-download WoWLAN Fw.
1229         //
1230         status = rtl8723b_FirmwareDownload(padapter, bHostIsGoingtoSleep);
1231         if(status != _SUCCESS) {
1232                 DBG_871X("SetFwRelatedForWoWLAN8723b(): Re-Download Firmware failed!!\n");
1233                 return;
1234         } else {
1235                 DBG_871X("SetFwRelatedForWoWLAN8723b(): Re-Download Firmware Success !!\n");
1236         }
1237         //
1238         // 2. Re-Init the variables about Fw related setting.
1239         //
1240         rtl8723b_InitializeFirmwareVars(padapter);
1241 }
1242 #endif //CONFIG_WOWLAN
1243
1244 static void rtl8723b_free_hal_data(PADAPTER padapter)
1245 {
1246 _func_enter_;
1247
1248 _func_exit_;
1249 }
1250
1251 //===========================================================
1252 //                              Efuse related code
1253 //===========================================================
1254 static u8
1255 hal_EfuseSwitchToBank(
1256         PADAPTER        padapter,
1257         u8                      bank,
1258         u8                      bPseudoTest)
1259 {
1260         u8 bRet = _FALSE;
1261         u32 value32 = 0;
1262 #ifdef HAL_EFUSE_MEMORY
1263         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1264         PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1265 #endif
1266
1267
1268         DBG_8192C("%s: Efuse switch bank to %d\n", __FUNCTION__, bank);
1269         if (bPseudoTest)
1270         {
1271 #ifdef HAL_EFUSE_MEMORY
1272                 pEfuseHal->fakeEfuseBank = bank;
1273 #else
1274                 fakeEfuseBank = bank;
1275 #endif
1276                 bRet = _TRUE;
1277         }
1278         else
1279         {
1280                 value32 = rtw_read32(padapter, EFUSE_TEST);
1281                 bRet = _TRUE;
1282                 switch (bank)
1283                 {
1284                         case 0:
1285                                 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1286                                 break;
1287                         case 1:
1288                                 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
1289                                 break;
1290                         case 2:
1291                                 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
1292                                 break;
1293                         case 3:
1294                                 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
1295                                 break;
1296                         default:
1297                                 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1298                                 bRet = _FALSE;
1299                                 break;
1300                 }
1301                 rtw_write32(padapter, EFUSE_TEST, value32);
1302         }
1303
1304         return bRet;
1305 }
1306
1307 static void
1308 Hal_GetEfuseDefinition(
1309         PADAPTER        padapter,
1310         u8                      efuseType,
1311         u8                      type,
1312         void            *pOut,
1313         u8                      bPseudoTest)
1314 {
1315         switch (type)
1316         {
1317                 case TYPE_EFUSE_MAX_SECTION:
1318                         {
1319                                 u8 *pMax_section;
1320                                 pMax_section = (u8*)pOut;
1321
1322                                 if (efuseType == EFUSE_WIFI)
1323                                         *pMax_section = EFUSE_MAX_SECTION_8723B;
1324                                 else
1325                                         *pMax_section = EFUSE_BT_MAX_SECTION;
1326                         }
1327                         break;
1328
1329                 case TYPE_EFUSE_REAL_CONTENT_LEN:
1330                         {
1331                                 u16 *pu2Tmp;
1332                                 pu2Tmp = (u16*)pOut;
1333
1334                                 if (efuseType == EFUSE_WIFI)
1335                                         *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
1336                                 else
1337                                         *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
1338                         }
1339                         break;
1340
1341                 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
1342                         {
1343                                 u16     *pu2Tmp;
1344                                 pu2Tmp = (u16*)pOut;
1345
1346                                 if (efuseType == EFUSE_WIFI)
1347                                         *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
1348                                 else
1349                                         *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN-EFUSE_PROTECT_BYTES_BANK);
1350                         }
1351                         break;
1352
1353                 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
1354                         {
1355                                 u16 *pu2Tmp;
1356                                 pu2Tmp = (u16*)pOut;
1357
1358                                 if (efuseType == EFUSE_WIFI)
1359                                         *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
1360                                 else
1361                                         *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN-(EFUSE_PROTECT_BYTES_BANK*3));
1362                         }
1363                         break;
1364
1365                 case TYPE_EFUSE_MAP_LEN:
1366                         {
1367                                 u16 *pu2Tmp;
1368                                 pu2Tmp = (u16*)pOut;
1369
1370                                 if (efuseType == EFUSE_WIFI)
1371                                         *pu2Tmp = EFUSE_MAX_MAP_LEN;
1372                                 else
1373                                         *pu2Tmp = EFUSE_BT_MAP_LEN;
1374                         }
1375                         break;
1376
1377                 case TYPE_EFUSE_PROTECT_BYTES_BANK:
1378                         {
1379                                 u8 *pu1Tmp;
1380                                 pu1Tmp = (u8*)pOut;
1381
1382                                 if (efuseType == EFUSE_WIFI)
1383                                         *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
1384                                 else
1385                                         *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
1386                         }
1387                         break;
1388
1389                 case TYPE_EFUSE_CONTENT_LEN_BANK:
1390                         {
1391                                 u16 *pu2Tmp;
1392                                 pu2Tmp = (u16*)pOut;
1393
1394                                 if (efuseType == EFUSE_WIFI)
1395                                         *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
1396                                 else
1397                                         *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
1398                         }
1399                         break;
1400
1401                 default:
1402                         {
1403                                 u8 *pu1Tmp;
1404                                 pu1Tmp = (u8*)pOut;
1405                                 *pu1Tmp = 0;
1406                         }
1407                         break;
1408         }
1409 }
1410
1411 #define VOLTAGE_V25             0x03
1412 #define LDOE25_SHIFT    28
1413
1414 //=================================================================
1415 //      The following is for compile ok
1416 //      That should be merged with the original in the future
1417 //=================================================================
1418 #define EFUSE_ACCESS_ON_8723                    0x69    // For RTL8723 only.
1419 #define EFUSE_ACCESS_OFF_8723                   0x00    // For RTL8723 only.
1420 #define REG_EFUSE_ACCESS_8723                   0x00CF  // Efuse access protection for RTL8723
1421
1422 //=================================================================
1423 static void Hal_BT_EfusePowerSwitch(
1424         PADAPTER        padapter,
1425         u8                      bWrite,
1426         u8                      PwrState)
1427 {
1428         u8 tempval;
1429         if (PwrState == _TRUE)
1430         {
1431                 // enable BT power cut
1432                 // 0x6A[14] = 1
1433                 tempval = rtw_read8(padapter, 0x6B);
1434                 tempval |= BIT(6);
1435                 rtw_write8(padapter, 0x6B, tempval);
1436                 
1437                 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
1438                 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
1439                 rtw_usleep_os(100);
1440                 // disable BT output isolation
1441                 // 0x6A[15] = 0
1442                 tempval = rtw_read8(padapter, 0x6B);
1443                 tempval &= ~BIT(7);
1444                 rtw_write8(padapter, 0x6B, tempval);
1445         }
1446         else
1447         {
1448                 // enable BT output isolation
1449                 // 0x6A[15] = 1
1450                 tempval = rtw_read8(padapter, 0x6B);
1451                 tempval |= BIT(7);
1452                 rtw_write8(padapter, 0x6B, tempval);
1453
1454                 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
1455                 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
1456
1457                 // disable BT power cut
1458                 // 0x6A[14] = 1
1459                 tempval = rtw_read8(padapter, 0x6B);
1460                 tempval &= ~BIT(6);
1461                 rtw_write8(padapter, 0x6B, tempval);
1462         }
1463
1464 }
1465 static void
1466 Hal_EfusePowerSwitch(
1467         PADAPTER        padapter,
1468         u8                      bWrite,
1469         u8                      PwrState)
1470 {
1471         u8      tempval;
1472         u16     tmpV16;
1473
1474
1475         if (PwrState == _TRUE)
1476         {
1477 #ifdef CONFIG_SDIO_HCI
1478                 // To avoid cannot access efuse regsiters after disable/enable several times during DTM test. 
1479                 // Suggested by SD1 IsaacHsu. 2013.07.08, added by tynli. 
1480                 tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
1481                 if (tempval & BIT(0)) // SDIO local register is suspend
1482                 {
1483                         u8 count = 0;
1484
1485
1486                         tempval &= ~BIT(0);
1487                         rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL, tempval);
1488
1489                         // check 0x86[1:0]=10'2h, wait power state to leave suspend
1490                         do {
1491                                 tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
1492                                 tempval &= 0x3;
1493                                 if (tempval == 0x02)
1494                                         break;
1495
1496                                 count++;
1497                                 if (count >= 100)
1498                                         break;
1499
1500                                 rtw_mdelay_os(10);
1501                         } while (1);
1502
1503                         if (count >= 100)
1504                         {
1505                                 DBG_8192C(FUNC_ADPT_FMT ": Leave SDIO local register suspend fail! Local 0x86=%#X\n",
1506                                         FUNC_ADPT_ARG(padapter), tempval);
1507                         }
1508                         else
1509                         {
1510                                 DBG_8192C(FUNC_ADPT_FMT ": Leave SDIO local register suspend OK! Local 0x86=%#X\n",
1511                                         FUNC_ADPT_ARG(padapter), tempval);
1512                 }
1513                 }
1514 #endif // CONFIG_SDIO_HCI
1515
1516                 rtw_write8(padapter, REG_EFUSE_ACCESS_8723, EFUSE_ACCESS_ON_8723);      
1517
1518                 // Reset: 0x0000h[28], default valid
1519                 tmpV16 =  rtw_read16(padapter, REG_SYS_FUNC_EN);
1520                 if (!(tmpV16 & FEN_ELDR)) {
1521                         tmpV16 |= FEN_ELDR ;
1522                         rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
1523                 }
1524
1525                 // Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid
1526                 tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
1527                 if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
1528                         tmpV16 |= (LOADER_CLK_EN | ANA8M) ;
1529                         rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
1530                 }
1531
1532                 if (bWrite == _TRUE)
1533                 {
1534                         // Enable LDO 2.5V before read/write action
1535                         tempval = rtw_read8(padapter, EFUSE_TEST+3);
1536                         tempval &= 0x0F;
1537                         tempval |= (VOLTAGE_V25 << 4);
1538                         rtw_write8(padapter, EFUSE_TEST+3, (tempval | 0x80));
1539
1540                         //rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
1541                 }
1542         }
1543         else
1544         {
1545                 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
1546
1547                 if (bWrite == _TRUE) {
1548                         // Disable LDO 2.5V after read/write action
1549                         tempval = rtw_read8(padapter, EFUSE_TEST+3);
1550                         rtw_write8(padapter, EFUSE_TEST+3, (tempval & 0x7F));
1551                 }
1552
1553         }
1554 }
1555
1556 static void
1557 hal_ReadEFuse_WiFi(
1558         PADAPTER        padapter,
1559         u16                     _offset,
1560         u16                     _size_byte,
1561         u8                      *pbuf,
1562         u8                      bPseudoTest)
1563 {
1564 #ifdef HAL_EFUSE_MEMORY
1565         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
1566         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
1567 #endif
1568         u8      *efuseTbl = NULL;
1569         u16     eFuse_Addr=0;
1570         u8      offset, wden;
1571         u8      efuseHeader, efuseExtHdr, efuseData;
1572         u16     i, total, used;
1573         u8      efuse_usage = 0;
1574
1575         //DBG_871X("YJ: ====>%s():_offset=%d _size_byte=%d bPseudoTest=%d\n", __func__, _offset, _size_byte, bPseudoTest);
1576         //
1577         // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
1578         //
1579         if ((_offset+_size_byte) > EFUSE_MAX_MAP_LEN)
1580         {
1581                 DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1582                 return;
1583         }
1584
1585         efuseTbl = (u8*)rtw_malloc(EFUSE_MAX_MAP_LEN);
1586         if (efuseTbl == NULL)
1587         {
1588                 DBG_8192C("%s: alloc efuseTbl fail!\n", __FUNCTION__);
1589                 return;
1590         }
1591         // 0xff will be efuse default value instead of 0x00.
1592         _rtw_memset(efuseTbl, 0xFF, EFUSE_MAX_MAP_LEN);
1593
1594
1595 #ifdef CONFIG_DEBUG
1596 if(0)
1597 {
1598         for(i=0; i<256; i++)
1599                 //ReadEFuseByte(padapter, i, &efuseTbl[i], _FALSE);
1600                 efuse_OneByteRead(padapter, i, &efuseTbl[i], _FALSE);
1601         DBG_871X("Efuse Content:\n");
1602         for(i=0; i<256; i++)
1603         {
1604                 if (i % 16 == 0)
1605                         printk("\n");
1606                 printk("%02X ", efuseTbl[i]);
1607         }
1608         printk("\n");
1609 }
1610 #endif
1611
1612
1613         // switch bank back to bank 0 for later BT and wifi use.
1614         hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1615
1616         while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
1617         {
1618                 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1619                 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1620                 if (efuseHeader == 0xFF)
1621                 {
1622                         DBG_8192C("%s: data end at address=%#x\n", __FUNCTION__, eFuse_Addr-1);
1623                         break;
1624                 }
1625                 //DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseHeader);
1626
1627                 // Check PG header for section num.
1628                 if (EXT_HEADER(efuseHeader))            //extended header
1629                 {
1630                         offset = GET_HDR_OFFSET_2_0(efuseHeader);
1631                         //DBG_8192C("%s: extended header offset=0x%X\n", __FUNCTION__, offset);
1632
1633                         //ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1634                         efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1635                         //DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseExtHdr);
1636                         if (ALL_WORDS_DISABLED(efuseExtHdr))
1637                         {
1638                                 continue;
1639                         }
1640
1641                         offset |= ((efuseExtHdr & 0xF0) >> 1);
1642                         wden = (efuseExtHdr & 0x0F);
1643                 }
1644                 else
1645                 {
1646                         offset = ((efuseHeader >> 4) & 0x0f);
1647                         wden = (efuseHeader & 0x0f);
1648                 }
1649                 //DBG_8192C("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden);
1650
1651                 if (offset < EFUSE_MAX_SECTION_8723B)
1652                 {
1653                         u16 addr;
1654                         // Get word enable value from PG header
1655 //                      DBG_8192C("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden);
1656
1657                         addr = offset * PGPKT_DATA_SIZE;
1658                         for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1659                         {
1660                                 // Check word enable condition in the section
1661                                 if (!(wden & (0x01<<i)))
1662                                 {
1663                                         //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1664                                         efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1665 //                                      DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1666                                         efuseTbl[addr] = efuseData;
1667
1668                                         //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1669                                         efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1670 //                                      DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1671                                         efuseTbl[addr+1] = efuseData;
1672                                 }
1673                                 addr += 2;
1674                         }
1675                 }
1676                 else
1677                 {
1678                         DBG_8192C(KERN_ERR "%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1679                         eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
1680                 }
1681         }
1682
1683         // Copy from Efuse map to output pointer memory!!!
1684         for (i=0; i<_size_byte; i++)
1685                 pbuf[i] = efuseTbl[_offset+i];
1686
1687 #ifdef CONFIG_DEBUG
1688 if(1)
1689 {
1690         DBG_871X("Efuse Realmap:\n");
1691         for(i=0; i<_size_byte; i++)
1692         {
1693                 if (i % 16 == 0)
1694                         printk("\n");
1695                 printk("%02X ", pbuf[i]);
1696         }
1697         printk("\n");
1698 }
1699 #endif
1700         // Calculate Efuse utilization
1701         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1702         used = eFuse_Addr - 1;
1703         efuse_usage = (u8)((used*100)/total);
1704         if (bPseudoTest)
1705         {
1706 #ifdef HAL_EFUSE_MEMORY
1707                 pEfuseHal->fakeEfuseUsedBytes = used;
1708 #else
1709                 fakeEfuseUsedBytes = used;
1710 #endif
1711         }
1712         else
1713         {
1714                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&used);
1715                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8*)&efuse_usage);
1716         }
1717
1718         if (efuseTbl)
1719                 rtw_mfree(efuseTbl, EFUSE_MAX_MAP_LEN);
1720 }
1721
1722 static VOID
1723 hal_ReadEFuse_BT(
1724         PADAPTER        padapter,
1725         u16                     _offset,
1726         u16                     _size_byte,
1727         u8                      *pbuf,
1728         u8                      bPseudoTest
1729         )
1730 {
1731 #ifdef HAL_EFUSE_MEMORY
1732         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
1733         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
1734 #endif
1735         u8      *efuseTbl;
1736         u8      bank;
1737         u16     eFuse_Addr;
1738         u8      efuseHeader, efuseExtHdr, efuseData;
1739         u8      offset, wden;
1740         u16     i, total, used;
1741         u8      efuse_usage;
1742
1743
1744         //
1745         // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
1746         //
1747         if ((_offset+_size_byte) > EFUSE_BT_MAP_LEN)
1748         {
1749                 DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1750                 return;
1751         }
1752
1753         efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);
1754         if (efuseTbl == NULL) {
1755                 DBG_8192C("%s: efuseTbl malloc fail!\n", __FUNCTION__);
1756                 return;
1757         }
1758         // 0xff will be efuse default value instead of 0x00.
1759         _rtw_memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
1760
1761         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total, bPseudoTest);
1762
1763         for (bank=1; bank<3; bank++) // 8723b Max bake 0~2
1764         {
1765                 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE)
1766                 {
1767                         DBG_8192C("%s: hal_EfuseSwitchToBank Fail!!\n", __FUNCTION__);
1768                         goto exit;
1769                 }
1770
1771                 eFuse_Addr = 0;
1772
1773                 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
1774                 {
1775                         //ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1776                         efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1777                         if (efuseHeader == 0xFF) break;
1778                         DBG_8192C("%s: efuse[%#X]=0x%02x (header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN_8723B)+eFuse_Addr-1), efuseHeader);
1779
1780                         // Check PG header for section num.
1781                         if (EXT_HEADER(efuseHeader))            //extended header
1782                         {
1783                                 offset = GET_HDR_OFFSET_2_0(efuseHeader);
1784                                 DBG_8192C("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset);
1785
1786                                 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1787                                 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1788                                 DBG_8192C("%s: efuse[%#X]=0x%02x (ext header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN_8723B)+eFuse_Addr-1), efuseExtHdr);
1789                                 if (ALL_WORDS_DISABLED(efuseExtHdr))
1790                                 {
1791                                         continue;
1792                                 }
1793
1794                                 offset |= ((efuseExtHdr & 0xF0) >> 1);
1795                                 wden = (efuseExtHdr & 0x0F);
1796                         }
1797                         else
1798                         {
1799                                 offset = ((efuseHeader >> 4) & 0x0f);
1800                                 wden = (efuseHeader & 0x0f);
1801                         }
1802
1803                         if (offset < EFUSE_BT_MAX_SECTION)
1804                         {
1805                                 u16 addr;
1806
1807                                 // Get word enable value from PG header
1808                                 DBG_8192C("%s: Offset=%d Worden=%#X\n", __FUNCTION__, offset, wden);
1809
1810                                 addr = offset * PGPKT_DATA_SIZE;
1811                                 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1812                                 {
1813                                         // Check word enable condition in the section
1814                                         if (!(wden & (0x01<<i)))
1815                                         {
1816                                                 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1817                                                 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1818                                                 DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1819                                                 efuseTbl[addr] = efuseData;
1820
1821                                                 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1822                                                 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1823                                                 DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1824                                                 efuseTbl[addr+1] = efuseData;
1825                                         }
1826                                         addr += 2;
1827                                 }
1828                         }
1829                         else
1830                         {
1831                                 DBG_8192C("%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1832                                 eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
1833                         }
1834                 }
1835
1836                 if ((eFuse_Addr-1) < total)
1837                 {
1838                         DBG_8192C("%s: bank(%d) data end at %#x\n", __FUNCTION__, bank, eFuse_Addr-1);
1839                         break;
1840                 }
1841         }
1842
1843         // switch bank back to bank 0 for later BT and wifi use.
1844         hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1845
1846         // Copy from Efuse map to output pointer memory!!!
1847         for (i=0; i<_size_byte; i++)
1848                 pbuf[i] = efuseTbl[_offset+i];
1849
1850         //
1851         // Calculate Efuse utilization.
1852         //
1853         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1854         used = (EFUSE_BT_REAL_BANK_CONTENT_LEN*(bank-1)) + eFuse_Addr - 1;
1855         DBG_8192C("%s: bank(%d) data end at %#x ,used =%d\n", __FUNCTION__, bank, eFuse_Addr-1,used);
1856         efuse_usage = (u8)((used*100)/total);
1857         if (bPseudoTest)
1858         {
1859 #ifdef HAL_EFUSE_MEMORY
1860                 pEfuseHal->fakeBTEfuseUsedBytes = used;
1861 #else
1862                 fakeBTEfuseUsedBytes = used;
1863 #endif
1864         }
1865         else
1866         {
1867                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&used);
1868                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8*)&efuse_usage);
1869         }
1870
1871 exit:
1872         if (efuseTbl)
1873                 rtw_mfree(efuseTbl, EFUSE_BT_MAP_LEN);
1874 }
1875
1876 static void
1877 Hal_ReadEFuse(
1878         PADAPTER        padapter,
1879         u8                      efuseType,
1880         u16                     _offset,
1881         u16                     _size_byte,
1882         u8                      *pbuf,
1883         u8                      bPseudoTest)
1884 {
1885         if (efuseType == EFUSE_WIFI)
1886                 hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1887         else
1888                 hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1889 }
1890
1891 static u16
1892 hal_EfuseGetCurrentSize_WiFi(
1893         PADAPTER        padapter,
1894         u8                      bPseudoTest)
1895 {
1896 #ifdef HAL_EFUSE_MEMORY
1897         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
1898         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
1899 #endif
1900         u16     efuse_addr=0;
1901         u16 start_addr = 0; // for debug
1902         u8      hoffset=0, hworden=0;
1903         u8      efuse_data, word_cnts=0;
1904         u32 count = 0; // for debug
1905
1906
1907         if (bPseudoTest)
1908         {
1909 #ifdef HAL_EFUSE_MEMORY
1910                 efuse_addr = (u16)pEfuseHal->fakeEfuseUsedBytes;
1911 #else
1912                 efuse_addr = (u16)fakeEfuseUsedBytes;
1913 #endif
1914         }
1915         else
1916         {
1917                 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
1918         }
1919         start_addr = efuse_addr;
1920         DBG_8192C("%s: start_efuse_addr=0x%X\n", __FUNCTION__, efuse_addr);
1921
1922         // switch bank back to bank 0 for later BT and wifi use.
1923         hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1924
1925 #if 0 // for debug test
1926         efuse_OneByteRead(padapter, 0x1FF, &efuse_data, bPseudoTest);
1927         DBG_8192C(FUNC_ADPT_FMT ": efuse raw 0x1FF=0x%02X\n",
1928                 FUNC_ADPT_ARG(padapter), efuse_data);
1929         efuse_data = 0xFF;
1930 #endif // for debug test
1931
1932         count = 0;
1933         while (AVAILABLE_EFUSE_ADDR(efuse_addr))
1934         {
1935 #if 1
1936                 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE)
1937                 {
1938                         DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
1939                         goto error;
1940                 }
1941 #else
1942                 ReadEFuseByte(padapter, efuse_addr, &efuse_data, bPseudoTest);
1943 #endif
1944
1945                 if (efuse_data == 0xFF) break;
1946
1947                 if ((start_addr != 0) && (efuse_addr == start_addr))
1948                 {
1949                         count++;
1950                         DBG_8192C(FUNC_ADPT_FMT ": [WARNING] efuse raw 0x%X=0x%02X not 0xFF!!(%d times)\n",
1951                                 FUNC_ADPT_ARG(padapter), efuse_addr, efuse_data, count);
1952
1953                         efuse_data = 0xFF;
1954                         if (count < 4)
1955                         {
1956                                 // try again!
1957
1958                                 if (count > 2)
1959                                 {
1960                                         // try again form address 0
1961                                         efuse_addr = 0;
1962                                         start_addr = 0;
1963                                 }
1964
1965                                 continue;
1966                         }
1967
1968                         goto error;
1969                 }
1970
1971                 if (EXT_HEADER(efuse_data))
1972                 {
1973                         hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1974                         efuse_addr++;
1975                         efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1976                         if (ALL_WORDS_DISABLED(efuse_data))
1977                         {
1978                                 continue;
1979                         }
1980
1981                         hoffset |= ((efuse_data & 0xF0) >> 1);
1982                         hworden = efuse_data & 0x0F;
1983                 }
1984                 else
1985                 {
1986                         hoffset = (efuse_data>>4) & 0x0F;
1987                         hworden = efuse_data & 0x0F;
1988                 }
1989
1990                 word_cnts = Efuse_CalculateWordCnts(hworden);
1991                 efuse_addr += (word_cnts*2)+1;
1992         }
1993
1994         if (bPseudoTest)
1995         {
1996 #ifdef HAL_EFUSE_MEMORY
1997                 pEfuseHal->fakeEfuseUsedBytes = efuse_addr;
1998 #else
1999                 fakeEfuseUsedBytes = efuse_addr;
2000 #endif
2001         }
2002         else
2003         {
2004                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
2005         }
2006         
2007         goto exit;
2008
2009 error:
2010         // report max size to prevent wirte efuse
2011         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_addr, bPseudoTest);
2012
2013 exit:
2014         DBG_8192C("%s: CurrentSize=%d\n", __FUNCTION__, efuse_addr);
2015
2016         return efuse_addr;
2017 }
2018
2019 static u16
2020 hal_EfuseGetCurrentSize_BT(
2021         PADAPTER        padapter,
2022         u8                      bPseudoTest)
2023 {
2024 #ifdef HAL_EFUSE_MEMORY
2025         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
2026         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
2027 #endif
2028         u16 btusedbytes;
2029         u16     efuse_addr;
2030         u8      bank, startBank;
2031         u8      hoffset=0, hworden=0;
2032         u8      efuse_data, word_cnts=0;
2033         u16     retU2=0;
2034         u8 bContinual = _TRUE;
2035
2036
2037         if (bPseudoTest)
2038         {
2039 #ifdef HAL_EFUSE_MEMORY
2040                 btusedbytes = pEfuseHal->fakeBTEfuseUsedBytes;
2041 #else
2042                 btusedbytes = fakeBTEfuseUsedBytes;
2043 #endif
2044         }
2045         else
2046         {
2047                 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&btusedbytes);
2048         }
2049         efuse_addr = (u16)((btusedbytes%EFUSE_BT_REAL_BANK_CONTENT_LEN));
2050         startBank = (u8)(1+(btusedbytes/EFUSE_BT_REAL_BANK_CONTENT_LEN));
2051
2052         DBG_8192C("%s: start from bank=%d addr=0x%X\n", __FUNCTION__, startBank, efuse_addr);
2053
2054         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2, bPseudoTest);
2055
2056         for (bank=startBank; bank<3; bank++)
2057         {
2058                 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE)
2059                 {
2060                         DBG_8192C(KERN_ERR "%s: switch bank(%d) Fail!!\n", __FUNCTION__, bank);
2061                         //bank = EFUSE_MAX_BANK;
2062                         break;
2063                 }
2064
2065                 // only when bank is switched we have to reset the efuse_addr.
2066                 if (bank != startBank)
2067                         efuse_addr = 0;
2068 #if 1
2069
2070                 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
2071                 {
2072                         if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE)
2073                         {
2074                                 DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
2075                                 //bank = EFUSE_MAX_BANK;
2076                                 break;
2077                         }
2078                         DBG_8192C("%s: efuse_OneByteRead ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr,efuse_data,bank);
2079
2080                         if (efuse_data == 0xFF) break;
2081
2082                         if (EXT_HEADER(efuse_data))
2083                         {
2084                                 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
2085                                 efuse_addr++;
2086                                 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
2087                                 DBG_8192C("%s: efuse_OneByteRead EXT_HEADER ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr,efuse_data,bank);
2088                         
2089                                 if (ALL_WORDS_DISABLED(efuse_data))
2090                                 {
2091                                         efuse_addr++;
2092                                         continue;
2093                                 }
2094
2095 //                              hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2096                                 hoffset |= ((efuse_data & 0xF0) >> 1);
2097                                 hworden = efuse_data & 0x0F;
2098                         }
2099                         else
2100                         {
2101                                 hoffset = (efuse_data>>4) & 0x0F;
2102                                 hworden =  efuse_data & 0x0F;
2103                         }
2104
2105                         DBG_8192C(FUNC_ADPT_FMT": Offset=%d Worden=%#X\n",
2106                                 FUNC_ADPT_ARG(padapter), hoffset, hworden);
2107
2108                         word_cnts = Efuse_CalculateWordCnts(hworden);
2109                         //read next header
2110                         efuse_addr += (word_cnts*2)+1;
2111                 }
2112 #else   
2113         while ( bContinual && 
2114                         efuse_OneByteRead(padapter, efuse_addr ,&efuse_data, bPseudoTest) && 
2115                         AVAILABLE_EFUSE_ADDR(efuse_addr))
2116                 {       
2117                         if(efuse_data!=0xFF)
2118                         {
2119                                 if((efuse_data&0x1F) == 0x0F)           //extended header
2120                                 {
2121                                         hoffset = efuse_data;
2122                                         efuse_addr++;
2123                                         efuse_OneByteRead(padapter, efuse_addr ,&efuse_data, bPseudoTest);
2124                                         if((efuse_data & 0x0F) == 0x0F)
2125                                         {
2126                                                 efuse_addr++;
2127                                                 continue;
2128                                         }
2129                                         else
2130                                         {
2131                                                 hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2132                                                 hworden = efuse_data & 0x0F;
2133                                         }
2134                                 }               
2135                                 else
2136                                 {
2137                                         hoffset = (efuse_data>>4) & 0x0F;
2138                                         hworden =  efuse_data & 0x0F;                                                                   
2139                                 }
2140                                 word_cnts = Efuse_CalculateWordCnts(hworden);
2141                                 //read next header                                                      
2142                                 efuse_addr = efuse_addr + (word_cnts*2)+1;                                              
2143                         }
2144                         else
2145                         {
2146                                 bContinual = _FALSE ;                   
2147                         }
2148                 }
2149 #endif                  
2150         
2151
2152                 // Check if we need to check next bank efuse
2153                 if (efuse_addr < retU2)
2154                 {
2155                         break;// don't need to check next bank.
2156                 }
2157         }
2158 #if 0
2159         retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
2160         if (bPseudoTest)
2161         {
2162 #ifdef HAL_EFUSE_MEMORY
2163                 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
2164 #else
2165                 fakeBTEfuseUsedBytes = retU2;
2166 #endif
2167         }
2168         else
2169         {
2170                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&retU2);
2171         }
2172 #else
2173         retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN)+efuse_addr;
2174         if(bPseudoTest)
2175         {
2176                 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
2177                 //RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->fakeBTEfuseUsedBytes));
2178         }
2179         else
2180         {
2181                 pEfuseHal->BTEfuseUsedBytes = retU2;
2182                 //RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->BTEfuseUsedBytes));
2183         }
2184 #endif
2185
2186         DBG_8192C("%s: CurrentSize=%d\n", __FUNCTION__, retU2);
2187         return retU2;
2188 }
2189
2190 static u16
2191 Hal_EfuseGetCurrentSize(
2192         PADAPTER        pAdapter,
2193         u8                      efuseType,
2194         u8                      bPseudoTest)
2195 {
2196         u16     ret = 0;
2197
2198         if (efuseType == EFUSE_WIFI)
2199                 ret = hal_EfuseGetCurrentSize_WiFi(pAdapter, bPseudoTest);
2200         else
2201                 ret = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest);
2202
2203         return ret;
2204 }
2205
2206 static u8
2207 Hal_EfuseWordEnableDataWrite(
2208         PADAPTER        padapter,
2209         u16                     efuse_addr,
2210         u8                      word_en,
2211         u8                      *data,
2212         u8                      bPseudoTest)
2213 {
2214         u16     tmpaddr = 0;
2215         u16     start_addr = efuse_addr;
2216         u8      badworden = 0x0F;
2217         u8      tmpdata[PGPKT_DATA_SIZE];
2218
2219
2220 //      DBG_8192C("%s: efuse_addr=%#x word_en=%#x\n", __FUNCTION__, efuse_addr, word_en);
2221         _rtw_memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
2222
2223         if (!(word_en & BIT(0)))
2224         {
2225                 tmpaddr = start_addr;
2226                 efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest);
2227                 efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest);
2228
2229                 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest);
2230                 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[1], bPseudoTest);
2231                 if ((data[0]!=tmpdata[0]) || (data[1]!=tmpdata[1])) {
2232                         badworden &= (~BIT(0));
2233                 }
2234         }
2235         if (!(word_en & BIT(1)))
2236         {
2237                 tmpaddr = start_addr;
2238                 efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest);
2239                 efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest);
2240
2241                 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest);
2242                 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[3], bPseudoTest);
2243                 if ((data[2]!=tmpdata[2]) || (data[3]!=tmpdata[3])) {
2244                         badworden &= (~BIT(1));
2245                 }
2246         }
2247         if (!(word_en & BIT(2)))
2248         {
2249                 tmpaddr = start_addr;
2250                 efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest);
2251                 efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest);
2252
2253                 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest);
2254                 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[5], bPseudoTest);
2255                 if ((data[4]!=tmpdata[4]) || (data[5]!=tmpdata[5])) {
2256                         badworden &= (~BIT(2));
2257                 }
2258         }
2259         if (!(word_en & BIT(3)))
2260         {
2261                 tmpaddr = start_addr;
2262                 efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest);
2263                 efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest);
2264
2265                 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest);
2266                 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[7], bPseudoTest);
2267                 if ((data[6]!=tmpdata[6]) || (data[7]!=tmpdata[7])) {
2268                         badworden &= (~BIT(3));
2269                 }
2270         }
2271
2272         return badworden;
2273 }
2274
2275 static s32
2276 Hal_EfusePgPacketRead(
2277         PADAPTER        padapter,
2278         u8                      offset,
2279         u8                      *data,
2280         u8                      bPseudoTest)
2281 {
2282         u8      bDataEmpty = _TRUE;
2283         u8      efuse_data, word_cnts=0;
2284         u16     efuse_addr=0;
2285         u8      hoffset=0, hworden=0;
2286         u8      i;
2287         u8      max_section = 0;
2288         s32     ret;
2289
2290
2291         if (data == NULL)
2292                 return _FALSE;
2293
2294         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest);
2295         if (offset > max_section)
2296         {
2297                 DBG_8192C("%s: Packet offset(%d) is illegal(>%d)!\n", __FUNCTION__, offset, max_section);
2298                 return _FALSE;
2299         }
2300
2301         _rtw_memset(data, 0xFF, PGPKT_DATA_SIZE);
2302         ret = _TRUE;
2303
2304         //
2305         // <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP.
2306         // Skip dummy parts to prevent unexpected data read from Efuse.
2307         // By pass right now. 2009.02.19.
2308         //
2309         while (AVAILABLE_EFUSE_ADDR(efuse_addr))
2310         {
2311                 if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == _FALSE)
2312                 {
2313                         ret = _FALSE;
2314                         break;
2315                 }
2316
2317                 if (efuse_data == 0xFF) break;
2318
2319                 if (EXT_HEADER(efuse_data))
2320                 {
2321                         hoffset = GET_HDR_OFFSET_2_0(efuse_data);
2322                         efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2323                         if (ALL_WORDS_DISABLED(efuse_data))
2324                         {
2325                                 DBG_8192C("%s: Error!! All words disabled!\n", __FUNCTION__);
2326                                 continue;
2327                         }
2328
2329                         hoffset |= ((efuse_data & 0xF0) >> 1);
2330                         hworden = efuse_data & 0x0F;
2331                 }
2332                 else
2333                 {
2334                         hoffset = (efuse_data>>4) & 0x0F;
2335                         hworden =  efuse_data & 0x0F;
2336                 }
2337
2338                 if (hoffset == offset)
2339                 {
2340                         for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
2341                         {
2342                                 // Check word enable condition in the section
2343                                 if (!(hworden & (0x01<<i)))
2344                                 {
2345                                         //ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2346                                         efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2347 //                                      DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
2348                                         data[i*2] = efuse_data;
2349
2350                                         //ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2351                                         efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2352 //                                      DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
2353                                         data[(i*2)+1] = efuse_data;
2354                                 }
2355                         }
2356                 }
2357                 else
2358                 {
2359                         word_cnts = Efuse_CalculateWordCnts(hworden);
2360                         efuse_addr += word_cnts*2;
2361                 }
2362         }
2363
2364         return ret;
2365 }
2366
2367 static u8
2368 hal_EfusePgCheckAvailableAddr(
2369         PADAPTER        pAdapter,
2370         u8                      efuseType,
2371         u8              bPseudoTest)
2372 {
2373         u16     max_available=0;
2374         u16 current_size;
2375
2376
2377         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &max_available, bPseudoTest);
2378 //      DBG_8192C("%s: max_available=%d\n", __FUNCTION__, max_available);
2379
2380         current_size = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
2381         if (current_size >= max_available)
2382         {
2383                 DBG_8192C("%s: Error!! current_size(%d)>max_available(%d)\n", __FUNCTION__, current_size, max_available);
2384                 return _FALSE;
2385         }
2386         return _TRUE;
2387 }
2388
2389 static void
2390 hal_EfuseConstructPGPkt(
2391         u8                              offset,
2392         u8                              word_en,
2393         u8                              *pData,
2394         PPGPKT_STRUCT   pTargetPkt)
2395 {
2396         _rtw_memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
2397         pTargetPkt->offset = offset;
2398         pTargetPkt->word_en = word_en;
2399         efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
2400         pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2401 }
2402
2403 #if 0
2404 static u8
2405 wordEnMatched(
2406         PPGPKT_STRUCT   pTargetPkt,
2407         PPGPKT_STRUCT   pCurPkt,
2408         u8                              *pWden)
2409 {
2410         u8      match_word_en = 0x0F;   // default all words are disabled
2411         u8      i;
2412
2413         // check if the same words are enabled both target and current PG packet
2414         if (((pTargetPkt->word_en & BIT(0)) == 0) &&
2415                 ((pCurPkt->word_en & BIT(0)) == 0))
2416         {
2417                 match_word_en &= ~BIT(0);                               // enable word 0
2418         }
2419         if (((pTargetPkt->word_en & BIT(1)) == 0) &&
2420                 ((pCurPkt->word_en & BIT(1)) == 0))
2421         {
2422                 match_word_en &= ~BIT(1);                               // enable word 1
2423         }
2424         if (((pTargetPkt->word_en & BIT(2)) == 0) &&
2425                 ((pCurPkt->word_en & BIT(2)) == 0))
2426         {
2427                 match_word_en &= ~BIT(2);                               // enable word 2
2428         }
2429         if (((pTargetPkt->word_en & BIT(3)) == 0) &&
2430                 ((pCurPkt->word_en & BIT(3)) == 0))
2431         {
2432                 match_word_en &= ~BIT(3);                               // enable word 3
2433         }
2434
2435         *pWden = match_word_en;
2436
2437         if (match_word_en != 0xf)
2438                 return _TRUE;
2439         else
2440                 return _FALSE;
2441 }
2442
2443 static u8
2444 hal_EfuseCheckIfDatafollowed(
2445         PADAPTER                pAdapter,
2446         u8                              word_cnts,
2447         u16                             startAddr,
2448         u8                              bPseudoTest)
2449 {
2450         u8 bRet=_FALSE;
2451         u8 i, efuse_data;
2452
2453         for (i=0; i<(word_cnts*2); i++)
2454         {
2455                 if (efuse_OneByteRead(pAdapter, (startAddr+i) ,&efuse_data, bPseudoTest) == _FALSE)
2456                 {
2457                         DBG_8192C("%s: efuse_OneByteRead FAIL!!\n", __FUNCTION__);
2458                         bRet = _TRUE;
2459                         break;
2460                 }
2461
2462                 if (efuse_data != 0xFF)
2463                 {
2464                         bRet = _TRUE;
2465                         break;
2466                 }
2467         }
2468
2469         return bRet;
2470 }
2471 #endif
2472
2473 static u8
2474 hal_EfusePartialWriteCheck(
2475         PADAPTER                padapter,
2476         u8                              efuseType,
2477         u16                             *pAddr,
2478         PPGPKT_STRUCT   pTargetPkt,
2479         u8                              bPseudoTest)
2480 {
2481         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
2482         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
2483         u8      bRet=_FALSE;
2484         u16     startAddr=0, efuse_max_available_len=0, efuse_max=0;
2485         u8      efuse_data=0;
2486 #if 0
2487         u8      i, cur_header=0;
2488         u8      new_wden=0, matched_wden=0, badworden=0;
2489         PGPKT_STRUCT    curPkt;
2490 #endif
2491
2492
2493         EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest);
2494         EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest);
2495
2496         if (efuseType == EFUSE_WIFI)
2497         {
2498                 if (bPseudoTest)
2499                 {
2500 #ifdef HAL_EFUSE_MEMORY
2501                         startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes;
2502 #else
2503                         startAddr = (u16)fakeEfuseUsedBytes;
2504 #endif
2505                 }
2506                 else
2507                 {
2508                         rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&startAddr);
2509                 }
2510         }
2511         else
2512         {
2513                 if (bPseudoTest)
2514                 {
2515 #ifdef HAL_EFUSE_MEMORY
2516                         startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes;
2517 #else
2518                         startAddr = (u16)fakeBTEfuseUsedBytes;
2519 #endif
2520                 }
2521                 else
2522                 {
2523                         rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&startAddr);
2524                 }
2525         }
2526         startAddr %= efuse_max;
2527         DBG_8192C("%s: startAddr=%#X\n", __FUNCTION__, startAddr);
2528
2529         while (1)
2530         {
2531                 if (startAddr >= efuse_max_available_len)
2532                 {
2533                         bRet = _FALSE;
2534                         DBG_8192C("%s: startAddr(%d) >= efuse_max_available_len(%d)\n",
2535                                 __FUNCTION__, startAddr, efuse_max_available_len);
2536                         break;
2537                 }
2538
2539                 if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data!=0xFF))
2540                 {
2541 #if 1
2542                         bRet = _FALSE;
2543                         DBG_8192C("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n",
2544                                 __FUNCTION__, startAddr, efuse_data);
2545                         break;
2546 #else
2547                         if (EXT_HEADER(efuse_data))
2548                         {
2549                                 cur_header = efuse_data;
2550                                 startAddr++;
2551                                 efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest);
2552                                 if (ALL_WORDS_DISABLED(efuse_data))
2553                                 {
2554                                         DBG_8192C("%s: Error condition, all words disabled!", __FUNCTION__);
2555                                         bRet = _FALSE;
2556                                         break;
2557                                 }
2558                                 else
2559                                 {
2560                                         curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2561                                         curPkt.word_en = efuse_data & 0x0F;
2562                                 }
2563                         }
2564                         else
2565                         {
2566                                 cur_header  =  efuse_data;
2567                                 curPkt.offset = (cur_header>>4) & 0x0F;
2568                                 curPkt.word_en = cur_header & 0x0F;
2569                         }
2570
2571                         curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
2572                         // if same header is found but no data followed
2573                         // write some part of data followed by the header.
2574                         if ((curPkt.offset == pTargetPkt->offset) &&
2575                                 (hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr+1, bPseudoTest) == _FALSE) &&
2576                                 wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == _TRUE)
2577                         {
2578                                 DBG_8192C("%s: Need to partial write data by the previous wrote header\n", __FUNCTION__);
2579                                 // Here to write partial data
2580                                 badworden = Efuse_WordEnableDataWrite(padapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest);
2581                                 if (badworden != 0x0F)
2582                                 {
2583                                         u32     PgWriteSuccess=0;
2584                                         // if write fail on some words, write these bad words again
2585                                         if (efuseType == EFUSE_WIFI)
2586                                                 PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2587                                         else
2588                                                 PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2589
2590                                         if (!PgWriteSuccess)
2591                                         {
2592                                                 bRet = _FALSE;  // write fail, return
2593                                                 break;
2594                                         }
2595                                 }
2596                                 // partial write ok, update the target packet for later use
2597                                 for (i=0; i<4; i++)
2598                                 {
2599                                         if ((matched_wden & (0x1<<i)) == 0)     // this word has been written
2600                                         {
2601                                                 pTargetPkt->word_en |= (0x1<<i);        // disable the word
2602                                         }
2603                                 }
2604                                 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2605                         }
2606                         // read from next header
2607                         startAddr = startAddr + (curPkt.word_cnts*2) + 1;
2608 #endif
2609                 }
2610                 else
2611                 {
2612                         // not used header, 0xff
2613                         *pAddr = startAddr;
2614 //                      DBG_8192C("%s: Started from unused header offset=%d\n", __FUNCTION__, startAddr));
2615                         bRet = _TRUE;
2616                         break;
2617                 }
2618         }
2619
2620         return bRet;
2621 }
2622
2623 static u8
2624 hal_EfusePgPacketWrite1ByteHeader(
2625         PADAPTER                pAdapter,
2626         u8                              efuseType,
2627         u16                             *pAddr,
2628         PPGPKT_STRUCT   pTargetPkt,
2629         u8                              bPseudoTest)
2630 {
2631         u8      bRet=_FALSE;
2632         u8      pg_header=0, tmp_header=0;
2633         u16     efuse_addr=*pAddr;
2634         u8      repeatcnt=0;
2635
2636
2637 //      DBG_8192C("%s\n", __FUNCTION__);
2638         pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
2639
2640         do {
2641                 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2642                 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2643                 if (tmp_header != 0xFF) break;
2644                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2645                 {
2646                         DBG_8192C("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
2647                         return _FALSE;
2648                 }
2649         } while (1);
2650
2651         if (tmp_header != pg_header)
2652         {
2653                 DBG_8192C(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
2654                 return _FALSE;
2655         }
2656
2657         *pAddr = efuse_addr;
2658
2659         return _TRUE;
2660 }
2661
2662 static u8
2663 hal_EfusePgPacketWrite2ByteHeader(
2664         PADAPTER                padapter,
2665         u8                              efuseType,
2666         u16                             *pAddr,
2667         PPGPKT_STRUCT   pTargetPkt,
2668         u8                              bPseudoTest)
2669 {
2670         u16     efuse_addr, efuse_max_available_len=0;
2671         u8      pg_header=0, tmp_header=0;
2672         u8      repeatcnt=0;
2673
2674
2675 //      DBG_8192C("%s\n", __FUNCTION__);
2676         EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest);
2677
2678         efuse_addr = *pAddr;
2679         if (efuse_addr >= efuse_max_available_len)
2680         {
2681                 DBG_8192C("%s: addr(%d) over avaliable(%d)!!\n", __FUNCTION__, efuse_addr, efuse_max_available_len);
2682                 return _FALSE;
2683         }
2684
2685         pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
2686 //      DBG_8192C("%s: pg_header=0x%x\n", __FUNCTION__, pg_header);
2687
2688         do {
2689                 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2690                 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2691                 if (tmp_header != 0xFF) break;
2692                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2693                 {
2694                         DBG_8192C("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
2695                         return _FALSE;
2696                 }
2697         } while (1);
2698
2699         if (tmp_header != pg_header)
2700         {
2701                 DBG_8192C(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
2702                 return _FALSE;
2703         }
2704
2705         // to write ext_header
2706         efuse_addr++;
2707         pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
2708
2709         do {
2710                 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2711                 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2712                 if (tmp_header != 0xFF) break;
2713                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2714                 {
2715                         DBG_8192C("%s: Repeat over limit for ext_header!!\n", __FUNCTION__);
2716                         return _FALSE;
2717                 }
2718         } while (1);
2719
2720         if (tmp_header != pg_header)    //offset PG fail
2721         {
2722                 DBG_8192C(KERN_ERR "%s: PG EXT Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
2723                 return _FALSE;
2724         }
2725
2726         *pAddr = efuse_addr;
2727
2728         return _TRUE;
2729 }
2730
2731 static u8
2732 hal_EfusePgPacketWriteHeader(
2733         PADAPTER                padapter,
2734         u8                              efuseType,
2735         u16                             *pAddr,
2736         PPGPKT_STRUCT   pTargetPkt,
2737         u8                              bPseudoTest)
2738 {
2739         u8 bRet=_FALSE;
2740
2741         if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
2742         {
2743                 bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2744         }
2745         else
2746         {
2747                 bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2748         }
2749
2750         return bRet;
2751 }
2752
2753 static u8
2754 hal_EfusePgPacketWriteData(
2755         PADAPTER                pAdapter,
2756         u8                              efuseType,
2757         u16                             *pAddr,
2758         PPGPKT_STRUCT   pTargetPkt,
2759         u8                              bPseudoTest)
2760 {
2761         u16     efuse_addr;
2762         u8      badworden;
2763
2764
2765         efuse_addr = *pAddr;
2766         badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
2767         if (badworden != 0x0F)
2768         {
2769                 DBG_8192C("%s: Fail!!\n", __FUNCTION__);
2770                 return _FALSE;
2771         }
2772
2773 //      DBG_8192C("%s: ok\n", __FUNCTION__);
2774         return _TRUE;
2775 }
2776
2777 static s32
2778 Hal_EfusePgPacketWrite(
2779         PADAPTER        padapter,
2780         u8                      offset,
2781         u8                      word_en,
2782         u8                      *pData,
2783         u8                      bPseudoTest)
2784 {
2785         PGPKT_STRUCT targetPkt;
2786         u16 startAddr=0;
2787         u8 efuseType=EFUSE_WIFI;
2788
2789         if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest))
2790                 return _FALSE;
2791
2792         hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2793
2794         if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2795                 return _FALSE;
2796
2797         if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2798                 return _FALSE;
2799
2800         if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2801                 return _FALSE;
2802
2803         return _TRUE;
2804 }
2805
2806 static u8
2807 Hal_EfusePgPacketWrite_BT(
2808         PADAPTER        pAdapter,
2809         u8                      offset,
2810         u8                      word_en,
2811         u8                      *pData,
2812         u8                      bPseudoTest)
2813 {
2814         PGPKT_STRUCT targetPkt;
2815         u16 startAddr=0;
2816         u8 efuseType=EFUSE_BT;
2817
2818         if(!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
2819                 return _FALSE;
2820
2821         hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2822
2823         if(!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2824                 return _FALSE;
2825
2826         if(!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2827                 return _FALSE;
2828
2829         if(!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2830                 return _FALSE;
2831
2832         return _TRUE;
2833 }
2834
2835 static HAL_VERSION
2836 ReadChipVersion8723B(
2837         IN      PADAPTER        padapter
2838         )
2839 {
2840         u32                             value32;
2841         HAL_VERSION             ChipVersion;
2842         HAL_DATA_TYPE   *pHalData;
2843
2844 //YJ,TODO, move read chip type here
2845         pHalData = GET_HAL_DATA(padapter);
2846
2847         value32 = rtw_read32(padapter, REG_SYS_CFG);
2848         ChipVersion.ICType = CHIP_8723B;
2849         ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
2850         ChipVersion.RFType = RF_TYPE_1T1R ;
2851         ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
2852         ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; // IC version (CUT)
2853
2854         // For regulator mode. by tynli. 2011.01.14
2855         pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
2856
2857         value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
2858         ChipVersion.ROMVer = ((value32 & RF_RL_ID) >> 20);      // ROM code version.
2859
2860         // For multi-function consideration. Added by Roger, 2010.10.06.
2861         pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
2862         value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
2863         pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
2864         pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
2865         pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
2866         pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT);
2867 //#if DBG
2868 #if 1
2869         dump_chip_info(ChipVersion);
2870 #endif
2871         pHalData->VersionID = ChipVersion;
2872 /*      // mark for chage to use efuse
2873         if( IS_B_CUT(ChipVersion) || IS_C_CUT(ChipVersion))
2874         {
2875                 MSG_8192C(" IS_B/C_CUT SWR up 1 level !!!!!!!!!!!!!!!!!\n");
2876                 PHY_SetMacReg(padapter, 0x14, BIT23|BIT22|BIT21|BIT20, 0x5); //MAC reg 0x14[23:20] = 4b'0101 (SWR 1.220V)
2877         }else if ( IS_D_CUT(ChipVersion))
2878         {
2879                 MSG_8192C(" IS_D_CUT SKIP SWR !!!!!!!!!!!!!!!!!\n");
2880         }
2881 */
2882         if (IS_1T2R(ChipVersion))
2883                 pHalData->rf_type = RF_1T2R;
2884         else if (IS_2T2R(ChipVersion))
2885                 pHalData->rf_type = RF_2T2R;
2886         else
2887                 pHalData->rf_type = RF_1T1R;
2888
2889         MSG_8192C("RF_Type is %x!!\n", pHalData->rf_type);
2890
2891         return ChipVersion;
2892 }
2893
2894
2895 static void rtl8723b_read_chip_version(PADAPTER padapter)
2896 {
2897         ReadChipVersion8723B(padapter);
2898 }
2899
2900 void rtl8723b_InitBeaconParameters(PADAPTER padapter)
2901 {
2902         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2903         u16 val16;
2904         u8 val8;
2905
2906
2907         val8 = DIS_TSF_UDT;
2908         val16 = val8 | (val8 << 8); // port0 and port1
2909 #ifdef CONFIG_BT_COEXIST
2910         // Enable prot0 beacon function for PSTDMA
2911         val16 |= EN_BCN_FUNCTION;
2912 #endif
2913         rtw_write16(padapter, REG_BCN_CTRL, val16);
2914
2915         // TODO: Remove these magic number
2916         rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);// ms
2917         // Firmware will control REG_DRVERLYINT when power saving is enable,
2918         // so don't set this register on STA mode.
2919         if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _FALSE)
2920                 rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8723B); // 5ms
2921         rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8723B); // 2ms
2922
2923         // Suggested by designer timchen. Change beacon AIFS to the largest number
2924         // beacause test chip does not contension before sending beacon. by tynli. 2009.11.03
2925         rtw_write16(padapter, REG_BCNTCFG, 0x660F);
2926         
2927         pHalData->RegBcnCtrlVal = rtw_read8(padapter, REG_BCN_CTRL);
2928         pHalData->RegTxPause = rtw_read8(padapter, REG_TXPAUSE); 
2929         pHalData->RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL+2);
2930         pHalData->RegReg542 = rtw_read8(padapter, REG_TBTT_PROHIBIT+2);
2931         pHalData->RegCR_1 = rtw_read8(padapter, REG_CR+1);
2932 }
2933
2934 void rtl8723b_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode)
2935 {
2936 #ifdef RTL8192CU_ADHOC_WORKAROUND_SETTING
2937         rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
2938 #else
2939         //rtw_write8(Adapter, REG_BCN_MAX_ERR, (InfraMode ? 0xFF : 0x10));
2940 #endif
2941 }
2942
2943 void    _InitBurstPktLen_8723BS(PADAPTER Adapter)
2944 {
2945         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(Adapter);
2946
2947         rtw_write8(Adapter, 0x4c7,rtw_read8(Adapter, 0x4c7)|BIT(7)); //enable single pkt ampdu
2948         rtw_write8(Adapter, REG_RX_PKT_LIMIT_8723B, 0x18);              //for VHT packet length 11K
2949         rtw_write8(Adapter, REG_MAX_AGGR_NUM_8723B, 0x1F);
2950         rtw_write8(Adapter, REG_PIFS_8723B, 0x00);
2951         rtw_write8(Adapter, REG_FWHW_TXQ_CTRL_8723B, rtw_read8(Adapter, REG_FWHW_TXQ_CTRL)&(~BIT(7)));
2952         if(pHalData->AMPDUBurstMode)
2953         {
2954                 rtw_write8(Adapter,REG_AMPDU_BURST_MODE_8723B,  0x5F);
2955         }
2956         rtw_write8(Adapter, REG_AMPDU_MAX_TIME_8723B, 0x70);
2957
2958         // ARFB table 9 for 11ac 5G 2SS
2959         rtw_write32(Adapter, REG_ARFR0_8723B, 0x00000010);
2960         if(IS_NORMAL_CHIP(pHalData->VersionID))
2961                 rtw_write32(Adapter, REG_ARFR0_8723B+4, 0xfffff000);
2962         else
2963                 rtw_write32(Adapter, REG_ARFR0_8723B+4, 0x3e0ff000);
2964
2965         // ARFB table 10 for 11ac 5G 1SS
2966         rtw_write32(Adapter, REG_ARFR1_8723B, 0x00000010);
2967         rtw_write32(Adapter, REG_ARFR1_8723B+4, 0x003ff000);
2968 }
2969
2970 static void ResumeTxBeacon(PADAPTER padapter)
2971 {
2972         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2973
2974
2975         // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
2976         // which should be read from register to a global variable.
2977
2978         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
2979
2980         pHalData->RegFwHwTxQCtrl |= BIT(6);
2981         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
2982         rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0xff);
2983         pHalData->RegReg542 |= BIT(0);
2984         rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
2985 }
2986
2987 static void StopTxBeacon(PADAPTER padapter)
2988 {
2989         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2990
2991
2992         // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
2993         // which should be read from register to a global variable.
2994
2995         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
2996
2997         pHalData->RegFwHwTxQCtrl &= ~BIT(6);
2998         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
2999         rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64);
3000         pHalData->RegReg542 &= ~BIT(0);
3001         rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
3002
3003         CheckFwRsvdPageContent(padapter);  // 2010.06.23. Added by tynli.
3004 }
3005
3006 static void _BeaconFunctionEnable(PADAPTER padapter, u8 Enable, u8 Linked)
3007 {
3008         rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
3009         rtw_write8(padapter, REG_RD_CTRL+1, 0x6F);
3010 }
3011
3012 static void rtl8723b_SetBeaconRelatedRegisters(PADAPTER padapter)
3013 {
3014         u8 val8;
3015         u32 value32;
3016         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3017         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3018         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3019         u32 bcn_ctrl_reg;
3020
3021         //reset TSF, enable update TSF, correcting TSF On Beacon
3022
3023         //REG_BCN_INTERVAL
3024         //REG_BCNDMATIM
3025         //REG_ATIMWND
3026         //REG_TBTT_PROHIBIT
3027         //REG_DRVERLYINT
3028         //REG_BCN_MAX_ERR
3029         //REG_BCNTCFG //(0x510)
3030         //REG_DUAL_TSF_RST
3031         //REG_BCN_CTRL //(0x550)
3032
3033
3034         bcn_ctrl_reg = REG_BCN_CTRL;
3035 #ifdef CONFIG_CONCURRENT_MODE
3036         if (padapter->iface_type == IFACE_PORT1)
3037                 bcn_ctrl_reg = REG_BCN_CTRL_1;
3038 #endif
3039
3040         //
3041         // ATIM window
3042         //
3043         rtw_write16(padapter, REG_ATIMWND, 2);
3044
3045         //
3046         // Beacon interval (in unit of TU).
3047         //
3048         rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
3049
3050         rtl8723b_InitBeaconParameters(padapter);
3051
3052         rtw_write8(padapter, REG_SLOT, 0x09);
3053
3054         //
3055         // Reset TSF Timer to zero, added by Roger. 2008.06.24
3056         //
3057         value32 = rtw_read32(padapter, REG_TCR);
3058         value32 &= ~TSFRST;
3059         rtw_write32(padapter, REG_TCR, value32);
3060
3061         value32 |= TSFRST;
3062         rtw_write32(padapter, REG_TCR, value32);
3063
3064         // NOTE: Fix test chip's bug (about contention windows's randomness)
3065         if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == _TRUE)
3066         {
3067                 rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
3068                 rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
3069         }
3070
3071         _BeaconFunctionEnable(padapter, _TRUE, _TRUE);
3072
3073         ResumeTxBeacon(padapter);
3074         val8 = rtw_read8(padapter, bcn_ctrl_reg);
3075         val8 |= DIS_BCNQ_SUB;
3076         rtw_write8(padapter, bcn_ctrl_reg, val8);
3077 }
3078
3079 void rtl8723b_GetHalODMVar(
3080         PADAPTER                                Adapter,
3081         HAL_ODM_VARIABLE                eVariable,
3082         PVOID                                   pValue1,
3083         PVOID                                   pValue2)
3084 {
3085         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
3086         PDM_ODM_T podmpriv = &pHalData->odmpriv;
3087         switch(eVariable){
3088                 default:
3089                         GetHalODMVar(Adapter,eVariable,pValue1,pValue2);
3090                         break;
3091         }
3092 }
3093
3094 void rtl8723b_SetHalODMVar(
3095         PADAPTER                                Adapter,
3096         HAL_ODM_VARIABLE                eVariable,
3097         PVOID                                   pValue1,
3098         BOOLEAN                                 bSet)
3099 {
3100         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
3101         PDM_ODM_T podmpriv = &pHalData->odmpriv;
3102         switch(eVariable){              
3103                 default:
3104                         SetHalODMVar(Adapter,eVariable,pValue1,bSet);
3105                         break;
3106         }
3107 }
3108 void hal_notch_filter_8723b(_adapter *adapter, bool enable)
3109 {
3110         if (enable) {
3111                 DBG_871X("Enable notch filter\n");
3112                 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
3113         } else {
3114                 DBG_871X("Disable notch filter\n");
3115                 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
3116         }
3117 }
3118
3119 u8 rtl8723b_MRateIdxToARFRId(PADAPTER padapter, u8 rate_idx)
3120 {
3121         u8 ret = 0;
3122         RT_RF_TYPE_DEF_E rftype = (RT_RF_TYPE_DEF_E)GET_RF_TYPE(padapter);
3123         switch(rate_idx){
3124
3125         case RATR_INX_WIRELESS_NGB:
3126                 if(rftype == RF_1T1R)
3127                         ret = 1;
3128                 else 
3129                         ret = 0;
3130                 break;
3131
3132         case RATR_INX_WIRELESS_N:
3133         case RATR_INX_WIRELESS_NG:
3134                 if(rftype == RF_1T1R)
3135                         ret = 5;
3136                 else
3137                         ret = 4;
3138                 break;
3139
3140         case RATR_INX_WIRELESS_NB:
3141                 if(rftype == RF_1T1R)
3142                         ret = 3;
3143                 else 
3144                         ret = 2;
3145                 break;
3146
3147         case RATR_INX_WIRELESS_GB:
3148                 ret = 6;
3149                 break;
3150
3151         case RATR_INX_WIRELESS_G:
3152                 ret = 7;
3153                 break;  
3154
3155         case RATR_INX_WIRELESS_B:
3156                 ret = 8;
3157                 break;
3158
3159         case RATR_INX_WIRELESS_MC:
3160                 if(padapter->mlmeextpriv.cur_wireless_mode & WIRELESS_11BG_24N)
3161                         ret = 6;
3162                 else
3163                         ret = 7;
3164                 break;
3165         case RATR_INX_WIRELESS_AC_N:
3166                 if(rftype == RF_1T1R)// || padapter->MgntInfo.VHTHighestOperaRate <= MGN_VHT1SS_MCS9)
3167                         ret = 10;
3168                 else
3169                         ret = 9;
3170                 break;
3171
3172         default:
3173                 ret = 0;
3174                 break;
3175         }       
3176
3177         return ret;
3178 }
3179
3180 void UpdateHalRAMask8723B(PADAPTER padapter, u32 mac_id, u8 rssi_level)
3181 {
3182         u32     mask,rate_bitmap;
3183         u8      shortGIrate = _FALSE;
3184         struct sta_info *psta;
3185         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3186         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
3187         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3188         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3189
3190         DBG_871X("%s(): mac_id=%d rssi_level=%d\n", __func__, mac_id, rssi_level);
3191
3192         if (mac_id >= NUM_STA) //CAM_SIZE
3193         {
3194                 return;
3195         }
3196
3197         psta = pmlmeinfo->FW_sta_info[mac_id].psta;
3198         if(psta == NULL)
3199         {
3200                 return;
3201         }
3202
3203         shortGIrate = query_ra_short_GI(psta);
3204
3205         mask = psta->ra_mask;
3206
3207         rate_bitmap = 0xffffffff;                                       
3208         rate_bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv,mac_id,mask,rssi_level);
3209         DBG_871X("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
3210                         __FUNCTION__,mac_id,psta->wireless_mode,mask,rssi_level,rate_bitmap);
3211
3212         mask &= rate_bitmap;
3213
3214 #ifdef CONFIG_BT_COEXIST
3215         rate_bitmap = rtw_btcoex_GetRaMask(padapter);
3216         mask &= ~rate_bitmap;
3217 #endif // CONFIG_BT_COEXIST
3218
3219 #ifdef CONFIG_CMCC_TEST
3220 #ifdef CONFIG_BT_COEXIST
3221         if(pmlmeext->cur_wireless_mode & WIRELESS_11G) {
3222                 if (mac_id == 0) {
3223                         DBG_871X("CMCC_BT update raid entry, mask=0x%x\n", mask);
3224                         //mask &=0xffffffc0; //disable CCK & <12M OFDM rate for 11G mode for CMCC
3225                         mask &=0xffffff00; //disable CCK & <24M OFDM rate for 11G mode for CMCC
3226                         DBG_871X("CMCC_BT update raid entry, mask=0x%x\n", mask);
3227                 }
3228         }
3229 #endif
3230 #endif
3231
3232         if(pHalData->fw_ractrl == _TRUE)
3233         {
3234                 rtl8723b_set_FwMacIdConfig_cmd(padapter, mac_id, psta->raid, psta->bw_mode, shortGIrate, mask);
3235         }
3236
3237         //set correct initial date rate for each mac_id
3238         pdmpriv->INIDATA_RATE[mac_id] = psta->init_rate;
3239         DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x init_rate=0x%x\n", __func__, mac_id, psta->raid, psta->bw_mode, mask, psta->init_rate);
3240 }
3241
3242 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3243 void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc)
3244 {
3245         u16     *usPtr = (u16*)ptxdesc;
3246         u32 count;
3247         u32 index;
3248         u16 checksum = 0;
3249
3250
3251         // Clear first
3252         ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
3253
3254         // checksume is always calculated by first 32 bytes,
3255         // and it doesn't depend on TX DESC length.
3256         // Thomas,Lucas@SD4,20130515
3257         count = 16;
3258
3259         for (index = 0; index < count; index++) {
3260                 checksum ^= le16_to_cpu(*(usPtr + index));
3261         }
3262
3263         ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
3264 }
3265 #endif
3266
3267 void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc)
3268 {
3269         pHalFunc->free_hal_data = &rtl8723b_free_hal_data;
3270
3271         pHalFunc->dm_init = &rtl8723b_init_dm_priv;
3272         pHalFunc->dm_deinit = &rtl8723b_deinit_dm_priv;
3273
3274         pHalFunc->read_chip_version = &rtl8723b_read_chip_version;
3275
3276         pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8723B;
3277
3278         pHalFunc->set_bwmode_handler = &PHY_SetBWMode8723B;
3279         pHalFunc->set_channel_handler = &PHY_SwChnl8723B;
3280         pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8723B;
3281
3282         pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8723B;
3283         pHalFunc->get_tx_power_level_handler = &PHY_GetTxPowerLevel8723B;
3284
3285         pHalFunc->hal_dm_watchdog = &rtl8723b_HalDmWatchDog;
3286         pHalFunc->hal_dm_watchdog_in_lps = &rtl8723b_HalDmWatchDog_in_LPS;
3287
3288 #ifdef CONFIG_C2H_PACKET_EN
3289         pHalFunc->SetHwRegHandlerWithBuf = &SetHwRegWithBuf8723B;
3290 #endif // CONFIG_C2H_PACKET_EN
3291         
3292         pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8723b_SetBeaconRelatedRegisters;
3293
3294         pHalFunc->Add_RateATid = &rtl8723b_Add_RateATid;
3295
3296         pHalFunc->run_thread= &rtl8723b_start_thread;
3297         pHalFunc->cancel_thread= &rtl8723b_stop_thread;
3298
3299         pHalFunc->read_bbreg = &PHY_QueryBBReg_8723B;
3300         pHalFunc->write_bbreg = &PHY_SetBBReg_8723B;
3301         pHalFunc->read_rfreg = &PHY_QueryRFReg_8723B;
3302         pHalFunc->write_rfreg = &PHY_SetRFReg_8723B;
3303
3304         // Efuse related function
3305         pHalFunc->BTEfusePowerSwitch = &Hal_BT_EfusePowerSwitch;
3306         pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch;
3307         pHalFunc->ReadEFuse = &Hal_ReadEFuse;
3308         pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition;
3309         pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize;
3310         pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead;
3311         pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite;
3312         pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite;
3313         pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT;
3314
3315 #ifdef DBG_CONFIG_ERROR_DETECT
3316         pHalFunc->sreset_init_value = &sreset_init_value;
3317         pHalFunc->sreset_reset_value = &sreset_reset_value;
3318         pHalFunc->silentreset = &sreset_reset;
3319         pHalFunc->sreset_xmit_status_check = &rtl8723b_sreset_xmit_status_check;
3320         pHalFunc->sreset_linked_status_check  = &rtl8723b_sreset_linked_status_check;
3321         pHalFunc->sreset_get_wifi_status  = &sreset_get_wifi_status;
3322         pHalFunc->sreset_inprogress= &sreset_inprogress;
3323 #endif
3324         pHalFunc->GetHalODMVarHandler = &rtl8723b_GetHalODMVar;
3325         pHalFunc->SetHalODMVarHandler = &rtl8723b_SetHalODMVar;
3326
3327 #ifdef CONFIG_XMIT_THREAD_MODE
3328         pHalFunc->xmit_thread_handler = &hal_xmit_handler;
3329 #endif
3330         pHalFunc->hal_notch_filter = &hal_notch_filter_8723b;
3331
3332         pHalFunc->c2h_handler = c2h_handler_8723b;
3333         pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8723b;
3334
3335         pHalFunc->fill_h2c_cmd = &FillH2CCmd8723B;
3336 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3337         pHalFunc->hal_cal_txdesc_chksum = &rtl8723b_cal_txdesc_chksum;
3338 #endif
3339 #ifdef CONFIG_WOWLAN
3340         pHalFunc->hal_set_wowlan_fw = &SetFwRelatedForWoWLAN8723b;
3341 #endif
3342         pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8723B;
3343 }
3344
3345 void rtl8723b_InitAntenna_Selection(PADAPTER padapter)
3346 {
3347         PHAL_DATA_TYPE pHalData;
3348         u8 val;
3349
3350
3351         pHalData = GET_HAL_DATA(padapter);
3352
3353         val = rtw_read8(padapter, REG_LEDCFG2);
3354         // Let 8051 take control antenna settting
3355         val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
3356         rtw_write8(padapter, REG_LEDCFG2, val);
3357 }
3358
3359 void rtl8723b_CheckAntenna_Selection(PADAPTER padapter)
3360 {
3361         PHAL_DATA_TYPE pHalData;
3362         u8 val;
3363
3364
3365         pHalData = GET_HAL_DATA(padapter);
3366
3367         val = rtw_read8(padapter, REG_LEDCFG2);
3368         // Let 8051 take control antenna settting
3369         if(!(val &BIT(7))){
3370                 val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
3371                 rtw_write8(padapter, REG_LEDCFG2, val);
3372         }
3373 }
3374 void rtl8723b_DeinitAntenna_Selection(PADAPTER padapter)
3375 {
3376         PHAL_DATA_TYPE pHalData;
3377         u8 val;
3378
3379
3380         pHalData = GET_HAL_DATA(padapter);
3381         val = rtw_read8(padapter, REG_LEDCFG2);
3382         // Let 8051 take control antenna settting
3383         val &= ~BIT(7); // DPDT_SEL_EN, clear 0x4C[23]
3384         rtw_write8(padapter, REG_LEDCFG2, val);
3385
3386 }
3387
3388 void rtl8723b_init_default_value(PADAPTER padapter)
3389 {
3390         PHAL_DATA_TYPE pHalData;
3391         struct dm_priv *pdmpriv;
3392         u8 i;
3393
3394
3395         pHalData = GET_HAL_DATA(padapter);
3396         pdmpriv = &pHalData->dmpriv;
3397
3398         padapter->registrypriv.wireless_mode = WIRELESS_11BG_24N;
3399
3400         // init default value
3401         pHalData->fw_ractrl = _FALSE;
3402         pHalData->bIQKInitialized = _FALSE;
3403         if (!adapter_to_pwrctl(padapter)->bkeepfwalive)
3404                 pHalData->LastHMEBoxNum = 0;
3405
3406         /* hal capability values */
3407         pHalData->macid_num = MACID_NUM_8723B;
3408         pHalData->cam_entry_num = CAM_ENTRY_NUM_8723B;
3409
3410         // init dm default value
3411         pdmpriv->TM_Trigger = 0;//for IQK
3412 //      pdmpriv->binitialized = _FALSE;
3413 //      pdmpriv->prv_traffic_idx = 3;
3414 //      pdmpriv->initialize = 0;
3415
3416         pdmpriv->ThermalValue_HP_index = 0;
3417         for (i=0; i<HP_THERMAL_NUM; i++)
3418                 pdmpriv->ThermalValue_HP[i] = 0;
3419
3420         // init Efuse variables
3421         pHalData->EfuseUsedBytes = 0;
3422         pHalData->EfuseUsedPercentage = 0;
3423 #ifdef HAL_EFUSE_MEMORY
3424         pHalData->EfuseHal.fakeEfuseBank = 0;
3425         pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
3426         _rtw_memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
3427         _rtw_memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
3428         _rtw_memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
3429         pHalData->EfuseHal.BTEfuseUsedBytes = 0;
3430         pHalData->EfuseHal.BTEfuseUsedPercentage = 0;
3431         _rtw_memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
3432         _rtw_memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3433         _rtw_memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3434         pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0;
3435         _rtw_memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
3436         _rtw_memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3437         _rtw_memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3438 #endif
3439 }
3440
3441 u8 GetEEPROMSize8723B(PADAPTER padapter)
3442 {
3443         u8 size = 0;
3444         u32     cr;
3445
3446         cr = rtw_read16(padapter, REG_9346CR);
3447         // 6: EEPROM used is 93C46, 4: boot from E-Fuse.
3448         size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
3449
3450         MSG_8192C("EEPROM type is %s\n", size==4 ? "E-FUSE" : "93C46");
3451
3452         return size;
3453 }
3454
3455 //-------------------------------------------------------------------------
3456 //
3457 // LLT R/W/Init function
3458 //
3459 //-------------------------------------------------------------------------
3460 s32 rtl8723b_InitLLTTable(PADAPTER padapter)
3461 {
3462         u32 start, passing_time;
3463         u32 val32;
3464         s32 ret;
3465
3466
3467         ret = _FAIL;
3468
3469         val32 = rtw_read32(padapter, REG_AUTO_LLT);
3470         val32 |= BIT_AUTO_INIT_LLT;
3471         rtw_write32(padapter, REG_AUTO_LLT, val32);
3472
3473         start = rtw_get_current_time();
3474
3475         do {
3476                 val32 = rtw_read32(padapter, REG_AUTO_LLT);
3477                 if (!(val32 & BIT_AUTO_INIT_LLT))
3478                 {
3479                         ret = _SUCCESS;
3480                         break;
3481                 }
3482
3483                 passing_time = rtw_get_passing_time_ms(start);
3484                 if (passing_time > 1000)
3485                 {
3486                         DBG_8192C("%s: FAIL!! REG_AUTO_LLT(0x%X)=%08x\n",
3487                                 __FUNCTION__, REG_AUTO_LLT, val32);
3488                         break;
3489                 }
3490
3491                 rtw_usleep_os(2);
3492         } while(1);
3493
3494         return ret;
3495 }
3496
3497 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3498 void _DisableGPIO(PADAPTER      padapter)
3499 {
3500 /***************************************
3501 j. GPIO_PIN_CTRL 0x44[31:0]=0x000               //
3502 k.Value = GPIO_PIN_CTRL[7:0]
3503 l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); //write external PIN level
3504 m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
3505 n. LEDCFG 0x4C[15:0] = 0x8080
3506 ***************************************/
3507         u8      value8;
3508         u16     value16;
3509         u32     value32;
3510         u32     u4bTmp;
3511
3512
3513         //1. Disable GPIO[7:0]
3514         rtw_write16(padapter, REG_GPIO_PIN_CTRL+2, 0x0000);
3515         value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
3516         u4bTmp = value32 & 0x000000FF;
3517         value32 |= ((u4bTmp<<8) | 0x00FF0000);
3518         rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32);
3519
3520         if (IS_HARDWARE_TYPE_8723AU(padapter) ||
3521                 IS_HARDWARE_TYPE_8723AS(padapter))
3522         {
3523                 //
3524                 // <Roger_Notes> For RTL8723u multi-function configuration which was autoload from Efuse offset 0x0a and 0x0b,
3525                 // WLAN HW GPIO[9], GPS HW GPIO[10] and BT HW GPIO[11].
3526                 // Added by Roger, 2010.10.07.
3527                 //
3528                 //2. Disable GPIO[8] and GPIO[12]
3529                 rtw_write16(padapter, REG_GPIO_IO_SEL_2, 0x0000); // Configure all pins as input mode.
3530                 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL_2) & 0xFFFF001F;
3531                 u4bTmp = value32 & 0x0000001F;
3532 //              if( IS_MULTI_FUNC_CHIP(padapter) )
3533 //                      value32 |= ((u4bTmp<<8) | 0x00110000); // Set pin 8 and pin 12 to output mode.
3534 //              else
3535                         value32 |= ((u4bTmp<<8) | 0x001D0000); // Set pin 8, 10, 11 and pin 12 to output mode.
3536                 rtw_write32(padapter, REG_GPIO_PIN_CTRL_2, value32);
3537         }
3538         else
3539         {
3540                 //2. Disable GPIO[10:8]
3541                 rtw_write8(padapter, REG_MAC_PINMUX_CFG, 0x00);
3542                 value16 = rtw_read16(padapter, REG_GPIO_IO_SEL) & 0xFF0F;
3543                 value8 = (u8) (value16&0x000F);
3544                 value16 |= ((value8<<4) | 0x0780);
3545                 rtw_write16(padapter, REG_GPIO_IO_SEL, value16);
3546         }
3547
3548         //3. Disable LED0 & 1
3549         if(IS_HARDWARE_TYPE_8192DU(padapter))
3550         {
3551                 rtw_write16(padapter, REG_LEDCFG0, 0x8888);
3552         }
3553         else
3554         {
3555                 rtw_write16(padapter, REG_LEDCFG0, 0x8080);
3556         }
3557 //      RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable GPIO and LED.\n"));
3558 } //end of _DisableGPIO()
3559
3560 void _DisableRFAFEAndResetBB8192C(PADAPTER padapter)
3561 {
3562 /**************************************
3563 a.      TXPAUSE 0x522[7:0] = 0xFF             //Pause MAC TX queue
3564 b.      RF path 0 offset 0x00 = 0x00            // disable RF
3565 c.      APSD_CTRL 0x600[7:0] = 0x40
3566 d.      SYS_FUNC_EN 0x02[7:0] = 0x16            //reset BB state machine
3567 e.      SYS_FUNC_EN 0x02[7:0] = 0x14            //reset BB state machine
3568 ***************************************/
3569         u8 eRFPath = 0, value8 = 0;
3570
3571         rtw_write8(padapter, REG_TXPAUSE, 0xFF);
3572
3573         PHY_SetRFReg(padapter, (RF_PATH)eRFPath, 0x0, bMaskByte0, 0x0);
3574
3575         value8 |= APSDOFF;
3576         rtw_write8(padapter, REG_APSD_CTRL, value8);//0x40
3577
3578         // Set BB reset at first
3579         value8 = 0 ;
3580         value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
3581         rtw_write8(padapter, REG_SYS_FUNC_EN, value8 );//0x16
3582
3583         // Set global reset.
3584         value8 &= ~FEN_BB_GLB_RSTn;
3585         rtw_write8(padapter, REG_SYS_FUNC_EN, value8); //0x14
3586
3587         // 2010/08/12 MH We need to set BB/GLBAL reset to save power for SS mode.
3588
3589 //      RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n"));
3590 }
3591
3592 void _DisableRFAFEAndResetBB(PADAPTER padapter)
3593 {
3594 #if 0
3595         if (IS_HARDWARE_TYPE_8192D(padapter))
3596                 _DisableRFAFEAndResetBB8192D(padapter);
3597         else
3598 #endif
3599                 _DisableRFAFEAndResetBB8192C(padapter);
3600 }
3601
3602 void _ResetDigitalProcedure1_92C(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3603 {
3604         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3605
3606         if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20))
3607         {
3608                 #if 0
3609 /*****************************
3610                 f.      SYS_FUNC_EN 0x03[7:0]=0x54              // reset MAC register, DCORE
3611                 g.      MCUFWDL 0x80[7:0]=0                             // reset MCU ready status
3612 ******************************/
3613         u32     value32 = 0;
3614                 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x54);
3615                 rtw_write8(padapter, REG_MCUFWDL, 0);
3616                 #else
3617                 /*****************************
3618                 f.      MCUFWDL 0x80[7:0]=0                             // reset MCU ready status
3619                 g.      SYS_FUNC_EN 0x02[10]= 0                 // reset MCU register, (8051 reset)
3620                 h.      SYS_FUNC_EN 0x02[15-12]= 5              // reset MAC register, DCORE
3621                 i.     SYS_FUNC_EN 0x02[10]= 1                  // enable MCU register, (8051 enable)
3622                 ******************************/
3623                         u16 valu16 = 0;
3624                         rtw_write8(padapter, REG_MCUFWDL, 0);
3625
3626                         valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
3627                         rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));//reset MCU ,8051
3628
3629                         valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN)&0x0FFF;
3630                         rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 |(FEN_HWPDN|FEN_ELDR)));//reset MAC
3631
3632                         valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
3633                         rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));//enable MCU ,8051
3634                 #endif
3635         }
3636         else
3637         {
3638                 u8 retry_cnts = 0;
3639
3640                 // 2010/08/12 MH For USB SS, we can not stop 8051 when we are trying to
3641                 // enter IPS/HW&SW radio off. For S3/S4/S5/Disable, we can stop 8051 because
3642                 // we will init FW when power on again.
3643                 //if(!pDevice->RegUsbSS)
3644                 {       // If we want to SS mode, we can not reset 8051.
3645                         if(rtw_read8(padapter, REG_MCUFWDL) & BIT1)
3646                         { //IF fw in RAM code, do reset
3647
3648
3649                                 if(padapter->bFWReady)
3650                                 {
3651                                         // 2010/08/25 MH Accordign to RD alfred's suggestion, we need to disable other
3652                                         // HRCV INT to influence 8051 reset.
3653                                         rtw_write8(padapter, REG_FWIMR, 0x20);
3654                                         // 2011/02/15 MH According to Alex's suggestion, close mask to prevent incorrect FW write operation.
3655                                         rtw_write8(padapter, REG_FTIMR, 0x00);
3656                                         rtw_write8(padapter, REG_FSIMR, 0x00);
3657
3658                                         rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
3659
3660                                         while( (retry_cnts++ <100) && (FEN_CPUEN &rtw_read16(padapter, REG_SYS_FUNC_EN)))
3661                                         {
3662                                                 rtw_udelay_os(50);//us
3663                                                 // 2010/08/25 For test only We keep on reset 5051 to prevent fail.
3664                                                 //rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
3665                                         }
3666 //                                      RT_ASSERT((retry_cnts < 100), ("8051 reset failed!\n"));
3667
3668                                         if (retry_cnts >= 100)
3669                                         {
3670                                                 // if 8051 reset fail we trigger GPIO 0 for LA
3671                                                 //rtw_write32(  padapter,
3672                                                 //                                              REG_GPIO_PIN_CTRL,
3673                                                 //                                              0x00010100);
3674                                                 // 2010/08/31 MH According to Filen's info, if 8051 reset fail, reset MAC directly.
3675                                                 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x50);  //Reset MAC and Enable 8051
3676                                                 rtw_mdelay_os(10);
3677                                         }
3678 //                                      else
3679 //                                      RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 reset success (%d) .\n",retry_cnts));
3680                                 }
3681                         }
3682 //                      else
3683 //                      {
3684 //                              RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 in ROM.\n"));
3685 //                      }
3686                         rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x54);  //Reset MAC and Enable 8051
3687                         rtw_write8(padapter, REG_MCUFWDL, 0);
3688                 }
3689         }
3690
3691         //if(pDevice->RegUsbSS)
3692                 //bWithoutHWSM = TRUE;  // Sugest by Filen and Issau.
3693
3694         if(bWithoutHWSM)
3695         {
3696                 //HAL_DATA_TYPE         *pHalData       = GET_HAL_DATA(padapter);
3697         /*****************************
3698                 Without HW auto state machine
3699         g.      SYS_CLKR 0x08[15:0] = 0x30A3                    //disable MAC clock
3700         h.      AFE_PLL_CTRL 0x28[7:0] = 0x80                   //disable AFE PLL
3701         i.      AFE_XTAL_CTRL 0x24[15:0] = 0x880F               //gated AFE DIG_CLOCK
3702         j.      SYS_ISO_CTRL 0x00[7:0] = 0xF9                   // isolated digital to PON
3703         ******************************/
3704                 //rtw_write16(padapter, REG_SYS_CLKR, 0x30A3);
3705                 //if(!pDevice->RegUsbSS)
3706                 // 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug.
3707                 //if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
3708                         //rtw_write16(padapter, REG_SYS_CLKR, (0x70A3|BIT6));  //modify to 0x70A3 by Scott.
3709                 //else
3710                         rtw_write16(padapter, REG_SYS_CLKR, 0x70A3);  //modify to 0x70A3 by Scott.
3711                 rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
3712                 rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
3713                 //if(!pDevice->RegUsbSS)
3714                         rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
3715         }
3716         else
3717         {
3718                 // Disable all RF/BB power
3719                 rtw_write8(padapter, REG_RF_CTRL, 0x00);
3720         }
3721 //      RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Reset Digital.\n"));
3722
3723 }
3724
3725 void _ResetDigitalProcedure1(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3726 {
3727 #if 0
3728         if(IS_HARDWARE_TYPE_8192D(padapter))
3729                 _ResetDigitalProcedure1_92D(padapter, bWithoutHWSM);
3730         else
3731 #endif
3732                 _ResetDigitalProcedure1_92C(padapter, bWithoutHWSM);
3733 }
3734
3735 void _ResetDigitalProcedure2(PADAPTER padapter)
3736 {
3737         //HAL_DATA_TYPE         *pHalData       = GET_HAL_DATA(padapter);
3738 /*****************************
3739 k.      SYS_FUNC_EN 0x03[7:0] = 0x44                    // disable ELDR runction
3740 l.      SYS_CLKR 0x08[15:0] = 0x3083                    // disable ELDR clock
3741 m.      SYS_ISO_CTRL 0x01[7:0] = 0x83                   // isolated ELDR to PON
3742 ******************************/
3743         //rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x44); //marked by Scott.
3744         // 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug.
3745         //if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
3746                 //rtw_write16(padapter, REG_SYS_CLKR, 0x70a3|BIT6);
3747         //else
3748                 rtw_write16(padapter, REG_SYS_CLKR, 0x70a3); //modify to 0x70a3 by Scott.
3749         rtw_write8(padapter, REG_SYS_ISO_CTRL+1, 0x82); //modify to 0x82 by Scott.
3750 }
3751
3752 void _DisableAnalog(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3753 {
3754         HAL_DATA_TYPE   *pHalData       = GET_HAL_DATA(padapter);
3755         u16 value16 = 0;
3756         u8 value8 = 0;
3757
3758
3759         if (bWithoutHWSM)
3760         {
3761                 /*****************************
3762                 n.      LDOA15_CTRL 0x20[7:0] = 0x04            // disable A15 power
3763                 o.      LDOV12D_CTRL 0x21[7:0] = 0x54           // disable digital core power
3764                 r.      When driver call disable, the ASIC will turn off remaining clock automatically
3765                 ******************************/
3766
3767                 rtw_write8(padapter, REG_LDOA15_CTRL, 0x04);
3768                 //rtw_write8(padapter, REG_LDOV12D_CTRL, 0x54);
3769
3770                 value8 = rtw_read8(padapter, REG_LDOV12D_CTRL);
3771                 value8 &= (~LDV12_EN);
3772                 rtw_write8(padapter, REG_LDOV12D_CTRL, value8);
3773 //              RT_TRACE(COMP_INIT, DBG_LOUD, (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",value8));
3774         }
3775
3776         /*****************************
3777         h.      SPS0_CTRL 0x11[7:0] = 0x23                      //enter PFM mode
3778         i.      APS_FSMCO 0x04[15:0] = 0x4802           // set USB suspend
3779         ******************************/
3780         value8 = 0x23;
3781         if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
3782                 value8 |= BIT3;
3783
3784         rtw_write8(padapter, REG_SPS0_CTRL, value8);
3785
3786         if(bWithoutHWSM)
3787         {
3788                 //value16 |= (APDM_HOST | /*AFSM_HSUS |*/PFM_ALDN);
3789                 // 2010/08/31 According to Filen description, we need to use HW to shut down 8051 automatically.
3790                 // Becasue suspend operatione need the asistance of 8051 to wait for 3ms.
3791                 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
3792         }
3793         else
3794         {
3795                 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
3796         }
3797
3798         rtw_write16(padapter, REG_APS_FSMCO, value16);//0x4802
3799
3800         rtw_write8(padapter, REG_RSV_CTRL, 0x0e);
3801
3802 #if 0
3803         //tynli_test for suspend mode.
3804         if(!bWithoutHWSM){
3805                 rtw_write8(padapter, 0xfe10, 0x19);
3806         }
3807 #endif
3808
3809 //      RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable Analog Reg0x04:0x%04x.\n",value16));
3810 }
3811
3812 // HW Auto state machine
3813 s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU)
3814 {
3815         int rtStatus = _SUCCESS;
3816
3817
3818         if (padapter->bSurpriseRemoved){
3819                 return rtStatus;
3820         }
3821         //==== RF Off Sequence ====
3822         _DisableRFAFEAndResetBB(padapter);
3823
3824         //  ==== Reset digital sequence   ======
3825         _ResetDigitalProcedure1(padapter, _FALSE);
3826
3827         //  ==== Pull GPIO PIN to balance level and LED control ======
3828         _DisableGPIO(padapter);
3829
3830         //  ==== Disable analog sequence ===
3831         _DisableAnalog(padapter, _FALSE);
3832
3833         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======> Card disable finished.\n"));
3834
3835         return rtStatus;
3836 }
3837
3838 // without HW Auto state machine
3839 s32 CardDisableWithoutHWSM(PADAPTER padapter)
3840 {
3841         s32 rtStatus = _SUCCESS;
3842
3843
3844         //RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Card Disable Without HWSM .\n"));
3845         if (padapter->bSurpriseRemoved) {
3846                 return rtStatus;
3847         }
3848
3849         //==== RF Off Sequence ====
3850         _DisableRFAFEAndResetBB(padapter);
3851
3852         //  ==== Reset digital sequence   ======
3853         _ResetDigitalProcedure1(padapter, _TRUE);
3854
3855         //  ==== Pull GPIO PIN to balance level and LED control ======
3856         _DisableGPIO(padapter);
3857
3858         //  ==== Reset digital sequence   ======
3859         _ResetDigitalProcedure2(padapter);
3860
3861         //  ==== Disable analog sequence ===
3862         _DisableAnalog(padapter, _TRUE);
3863
3864         //RT_TRACE(COMP_INIT, DBG_LOUD, ("<====== Card Disable Without HWSM .\n"));
3865         return rtStatus;
3866 }
3867 #endif // CONFIG_USB_HCI || CONFIG_SDIO_HCI || CONFIG_GSPI_HCI
3868
3869 BOOLEAN 
3870 Hal_GetChnlGroup8723B(
3871         IN      u8 Channel,
3872         OUT u8 *pGroup
3873         )
3874 {
3875         BOOLEAN bIn24G=TRUE;
3876
3877         if(Channel <= 14)
3878         {
3879                 bIn24G=TRUE;
3880
3881                 if      (1  <= Channel && Channel <= 2 )   *pGroup = 0;
3882                 else if (3  <= Channel && Channel <= 5 )   *pGroup = 1;
3883                 else if (6  <= Channel && Channel <= 8 )   *pGroup = 2;
3884                 else if (9  <= Channel && Channel <= 11)   *pGroup = 3;
3885                 else if (12 <= Channel && Channel <= 14)   *pGroup = 4;
3886                 else
3887                 {
3888                         RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,("==>Hal_GetChnlGroup8723B in 2.4 G, but Channel %d in Group not found \n", Channel));
3889                 }
3890         }
3891         else
3892         {
3893                 bIn24G=FALSE;
3894
3895                 if      (36   <= Channel && Channel <=  42)   *pGroup = 0;
3896                 else if (44   <= Channel && Channel <=  48)   *pGroup = 1;
3897                 else if (50   <= Channel && Channel <=  58)   *pGroup = 2;
3898                 else if (60   <= Channel && Channel <=  64)   *pGroup = 3;
3899                 else if (100  <= Channel && Channel <= 106)   *pGroup = 4;
3900                 else if (108  <= Channel && Channel <= 114)   *pGroup = 5;
3901                 else if (116  <= Channel && Channel <= 122)   *pGroup = 6;
3902                 else if (124  <= Channel && Channel <= 130)   *pGroup = 7;
3903                 else if (132  <= Channel && Channel <= 138)   *pGroup = 8;
3904                 else if (140  <= Channel && Channel <= 144)   *pGroup = 9;
3905                 else if (149  <= Channel && Channel <= 155)   *pGroup = 10;
3906                 else if (157  <= Channel && Channel <= 161)   *pGroup = 11;
3907                 else if (165  <= Channel && Channel <= 171)   *pGroup = 12;
3908                 else if (173  <= Channel && Channel <= 177)   *pGroup = 13;
3909                 else
3910                 {
3911                         RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,("==>Hal_GetChnlGroup8723B in 5G, but Channel %d in Group not found \n",Channel));
3912                 }
3913
3914         }
3915         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("<==Hal_GetChnlGroup8723B,  (%s) Channel = %d, Group =%d,\n", 
3916                                   (bIn24G) ? "2.4G" : "5G", Channel, *pGroup));
3917         return bIn24G;
3918 }
3919
3920 void
3921 Hal_InitPGData(
3922         PADAPTER        padapter,
3923         u8                      *PROMContent)
3924 {
3925         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
3926 //      HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3927         u32                     i;
3928         u16                     value16;
3929
3930         if(_FALSE == pEEPROM->bautoload_fail_flag)
3931         { // autoload OK.
3932 //              if (IS_BOOT_FROM_EEPROM(padapter))
3933                 if (_TRUE == pEEPROM->EepromOrEfuse)
3934                 {
3935                         // Read all Content from EEPROM or EFUSE.
3936                         for(i = 0; i < HWSET_MAX_SIZE_8723B; i += 2)
3937                         {
3938 //                              value16 = EF2Byte(ReadEEprom(pAdapter, (u2Byte) (i>>1)));
3939 //                              *((u16*)(&PROMContent[i])) = value16;
3940                         }
3941                 }
3942                 else
3943                 {
3944                         // Read EFUSE real map to shadow.
3945                         EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
3946                         _rtw_memcpy((void*)PROMContent, (void*)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE_8723B);
3947                 }
3948         }
3949         else
3950         {//autoload fail
3951                 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n"));
3952 //              pHalData->AutoloadFailFlag = _TRUE;
3953                 //update to default value 0xFF
3954                 if (_FALSE == pEEPROM->EepromOrEfuse)
3955                         EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
3956                 _rtw_memcpy((void*)PROMContent, (void*)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE_8723B);
3957         }
3958 }
3959
3960 void
3961 Hal_EfuseParseIDCode(
3962         IN      PADAPTER        padapter,
3963         IN      u8                      *hwinfo
3964         )
3965 {
3966         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
3967 //      HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3968         u16                     EEPROMId;
3969
3970
3971         // Checl 0x8129 again for making sure autoload status!!
3972         EEPROMId = le16_to_cpu(*((u16*)hwinfo));
3973         if (EEPROMId != RTL_EEPROM_ID)
3974         {
3975                 DBG_8192C("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
3976                 pEEPROM->bautoload_fail_flag = _TRUE;
3977         }
3978         else
3979         {
3980                 pEEPROM->bautoload_fail_flag = _FALSE;
3981         }
3982
3983         RT_TRACE(_module_hal_init_c_, _drv_notice_, ("EEPROM ID=0x%04x\n", EEPROMId));
3984 }
3985
3986 static void
3987 Hal_EEValueCheck(
3988         IN              u8              EEType,
3989         IN              PVOID           pInValue,
3990         OUT             PVOID           pOutValue
3991         )
3992 {
3993         switch(EEType)
3994         {
3995                 case EETYPE_TX_PWR:
3996                         {
3997                                 u8      *pIn, *pOut;
3998                                 pIn = (u8*)pInValue;
3999                                 pOut = (u8*)pOutValue;
4000                                 if(*pIn <= 63)
4001                                 {
4002                                         *pOut = *pIn;
4003                                 }
4004                                 else
4005                                 {
4006                                         RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("EETYPE_TX_PWR, value=%d is invalid, set to default=0x%x\n",
4007                                                 *pIn, EEPROM_Default_TxPowerLevel));
4008                                         *pOut = EEPROM_Default_TxPowerLevel;
4009                                 }
4010                         }
4011                         break;
4012                 default:
4013                         break;
4014         }
4015 }
4016
4017 static u8
4018 Hal_GetChnlGroup(
4019         IN      u8 chnl
4020         )
4021 {
4022         u8      group=0;
4023
4024         if (chnl < 3)                   // Cjanel 1-3
4025                 group = 0;
4026         else if (chnl < 9)              // Channel 4-9
4027                 group = 1;
4028         else                                    // Channel 10-14
4029                 group = 2;
4030
4031         return group;
4032 }
4033
4034 void 
4035 Hal_ReadPowerValueFromPROM_8723B(
4036         IN      PADAPTER                Adapter,
4037         IN      PTxPowerInfo24G pwrInfo24G,
4038         IN      u8                              * PROMContent,
4039         IN      BOOLEAN                 AutoLoadFail
4040         )
4041 {
4042         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
4043         u4Byte rfPath, eeAddr=EEPROM_TX_PWR_INX_8723B, group,TxCount=0;
4044
4045         _rtw_memset(pwrInfo24G, 0, sizeof(TxPowerInfo24G));     
4046
4047         if(0xFF == PROMContent[eeAddr+1])  
4048                 AutoLoadFail = TRUE;
4049         
4050         if(AutoLoadFail)
4051         {       
4052                 DBG_871X("%s(): Use Default value!\n", __func__);
4053                 for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
4054                 {
4055                         //2.4G default value
4056                         for(group = 0 ; group < MAX_CHNL_GROUP_24G; group++)
4057                         {
4058                                 pwrInfo24G->IndexCCK_Base[rfPath][group] =      EEPROM_DEFAULT_24G_INDEX;
4059                                 pwrInfo24G->IndexBW40_Base[rfPath][group] =     EEPROM_DEFAULT_24G_INDEX;
4060                         }
4061                         for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
4062                         {
4063                                 if(TxCount==0)
4064                                 {
4065                                         pwrInfo24G->BW20_Diff[rfPath][0] =      EEPROM_DEFAULT_24G_HT20_DIFF;
4066                                         pwrInfo24G->OFDM_Diff[rfPath][0] =      EEPROM_DEFAULT_24G_OFDM_DIFF;
4067                                 }
4068                                 else
4069                                 {
4070                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
4071                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
4072                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4073                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
4074                                 }
4075                         }
4076                 }
4077                 
4078                 return;
4079         }       
4080
4081         pHalData->bTXPowerDataReadFromEEPORM = TRUE;            //YJ,move,120316
4082         
4083         for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
4084         {
4085                 //2 2.4G default value
4086                 for(group = 0 ; group < MAX_CHNL_GROUP_24G; group++)
4087                 {
4088                         pwrInfo24G->IndexCCK_Base[rfPath][group] =      PROMContent[eeAddr++];
4089                         if(pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
4090                         {
4091                                 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
4092                         }
4093                 }
4094                 for(group = 0 ; group < MAX_CHNL_GROUP_24G-1; group++)
4095                 {
4096                         pwrInfo24G->IndexBW40_Base[rfPath][group] =     PROMContent[eeAddr++];
4097                         if(pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
4098                                 pwrInfo24G->IndexBW40_Base[rfPath][group] =     EEPROM_DEFAULT_24G_INDEX;
4099                 }                       
4100                 for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
4101                 {
4102                         if(TxCount==0)
4103                         {
4104                                 pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
4105                                 if(PROMContent[eeAddr] == 0xFF)
4106                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_24G_HT20_DIFF;
4107                                 else
4108                                 {
4109                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0xf0)>>4;                          
4110                                         if(pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)               //4bit sign number to 8 bit sign number
4111                                                 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
4112                                 }
4113
4114                                 if(PROMContent[eeAddr] == 0xFF)
4115                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_24G_OFDM_DIFF;                           
4116                                 else 
4117                                 {
4118                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0x0f);                                     
4119                                         if(pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)               //4bit sign number to 8 bit sign number
4120                                                 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
4121                                 }               
4122                                 pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
4123                                 eeAddr++;
4124                         }
4125                         else
4126                         {                               
4127                                 if(PROMContent[eeAddr] == 0xFF)
4128                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;                                                            
4129                                 else 
4130                                 {
4131                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0xf0)>>4;                          
4132                                         if(pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT3)               //4bit sign number to 8 bit sign number
4133                                                 pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
4134                                 }
4135                                 
4136                                 if(PROMContent[eeAddr] == 0xFF)
4137                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;                            
4138                                 else 
4139                                 {
4140                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0x0f);                             
4141                                         if(pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)               //4bit sign number to 8 bit sign number
4142                                                 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
4143                                 }
4144                                 eeAddr++;
4145                                 
4146                                 if(PROMContent[eeAddr] == 0xFF)
4147                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;                                                            
4148                                 else 
4149                                 {
4150                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0xf0)>>4;                          
4151                                         if(pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)               //4bit sign number to 8 bit sign number
4152                                                 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
4153                                 }
4154                         
4155                                 if(PROMContent[eeAddr] == 0xFF)
4156                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;                                                                                            
4157                                 else 
4158                                 {
4159                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);                             
4160                                         if(pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT3)                //4bit sign number to 8 bit sign number
4161                                                 pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
4162                                 }
4163                                 eeAddr++;
4164                         }
4165                 }
4166
4167                 /* Ignore the unnecessary 5G parameters parsing, but still consider the efuse address offset */
4168                 #define TX_PWR_DIFF_OFFSET_5G   10
4169                 eeAddr += (MAX_CHNL_GROUP_5G + TX_PWR_DIFF_OFFSET_5G);
4170         }
4171 }
4172
4173
4174 void
4175 Hal_EfuseParseTxPowerInfo_8723B(
4176         IN      PADAPTER                padapter,
4177         IN      u8*                     PROMContent,
4178         IN      BOOLEAN                 AutoLoadFail
4179         )
4180 {
4181         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
4182         TxPowerInfo24G  pwrInfo24G;
4183         u8                      rfPath, ch, group, TxCount=1;
4184
4185 //      RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4186         Hal_ReadPowerValueFromPROM_8723B(padapter, &pwrInfo24G, PROMContent, AutoLoadFail);
4187         for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
4188         {
4189                 for(ch = 0 ; ch < CHANNEL_MAX_NUMBER; ch++)
4190                 {
4191                         Hal_GetChnlGroup8723B(ch+1, &group);
4192                         
4193                         if(ch == 14-1) 
4194                         {
4195                                 pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][5];
4196                                 pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
4197                         }
4198                         else
4199                         {
4200                                 pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group];
4201                                 pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
4202                         }
4203 #ifdef CONFIG_DEBUG
4204                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======= Path %d, ChannelIndex %d, Group %d=======\n",rfPath,ch, group));                        
4205                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Index24G_CCK_Base[%d][%d] = 0x%x\n",rfPath,ch ,pHalData->Index24G_CCK_Base[rfPath][ch]));
4206                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Index24G_BW40_Base[%d][%d] = 0x%x\n",rfPath,ch,pHalData->Index24G_BW40_Base[rfPath][ch]));                      
4207 #endif                                                  
4208                 }
4209                 
4210                 for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
4211                 {
4212                         pHalData->CCK_24G_Diff[rfPath][TxCount]=pwrInfo24G.CCK_Diff[rfPath][TxCount];
4213                         pHalData->OFDM_24G_Diff[rfPath][TxCount]=pwrInfo24G.OFDM_Diff[rfPath][TxCount];
4214                         pHalData->BW20_24G_Diff[rfPath][TxCount]=pwrInfo24G.BW20_Diff[rfPath][TxCount];
4215                         pHalData->BW40_24G_Diff[rfPath][TxCount]=pwrInfo24G.BW40_Diff[rfPath][TxCount];
4216                         
4217 #ifdef CONFIG_DEBUG
4218                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("--------------------------------------- 2.4G ---------------------------------------\n"));
4219                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("CCK_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->CCK_24G_Diff[rfPath][TxCount]));
4220                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("OFDM_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->OFDM_24G_Diff[rfPath][TxCount]));
4221                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("BW20_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->BW20_24G_Diff[rfPath][TxCount]));
4222                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("BW40_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->BW40_24G_Diff[rfPath][TxCount]));
4223 #endif                                                  
4224                 }
4225         }
4226
4227         // 2010/10/19 MH Add Regulator recognize for CU.
4228         if(!AutoLoadFail)
4229         {
4230                 pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_8723B]&0x7);   //bit0~2
4231                 if(PROMContent[EEPROM_RF_BOARD_OPTION_8723B] == 0xFF)
4232                         pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION&0x7); //bit0~2
4233         }
4234         else
4235         {
4236                 pHalData->EEPROMRegulatory = 0;
4237         }
4238         RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory));
4239 }
4240
4241 VOID
4242 Hal_EfuseParseBTCoexistInfo_8723B(
4243         IN PADAPTER                     padapter,
4244         IN u8*                  hwinfo,
4245         IN BOOLEAN                      AutoLoadFail
4246         )
4247 {
4248         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
4249         u8                      tempval;
4250         u32                     tmpu4;
4251
4252 //      RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4253         if (!AutoLoadFail)
4254         {
4255                 tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
4256                 if (tmpu4 & BT_FUNC_EN)
4257                         pHalData->EEPROMBluetoothCoexist = _TRUE;
4258                 else
4259                         pHalData->EEPROMBluetoothCoexist = _FALSE;
4260
4261                 pHalData->EEPROMBluetoothType = BT_RTL8723B;
4262
4263                 tempval = hwinfo[EEPROM_RF_BT_SETTING_8723B];
4264                 if(tempval !=0xFF){
4265                         pHalData->EEPROMBluetoothAntNum = tempval & BIT(0);
4266                         #ifdef CONFIG_USB_HCI
4267                         //if(padapter->interface_type == RTW_USB)
4268                         pHalData->ant_path =ODM_RF_PATH_B;//s0
4269                         #else //SDIO or PCIE
4270                         // EFUSE_0xC3[6] == 0, S1(Main)-ODM_RF_PATH_A;
4271                         // EFUSE_0xC3[6] == 1, S0(Aux)-ODM_RF_PATH_B
4272                         pHalData->ant_path = (tempval & BIT(6))?ODM_RF_PATH_B:ODM_RF_PATH_A;
4273                         #endif
4274                 }
4275                 else{
4276                         pHalData->EEPROMBluetoothAntNum = Ant_x1;
4277                         #ifdef CONFIG_USB_HCI
4278                         pHalData->ant_path = ODM_RF_PATH_B;//s0
4279                         #else
4280                         pHalData->ant_path = ODM_RF_PATH_A;
4281                         #endif                  
4282                 }
4283         }
4284         else
4285         {
4286                 pHalData->EEPROMBluetoothCoexist = _FALSE;
4287                 pHalData->EEPROMBluetoothType = BT_RTL8723B;
4288                 pHalData->EEPROMBluetoothAntNum = Ant_x1;
4289                 #ifdef CONFIG_USB_HCI
4290                 pHalData->ant_path = ODM_RF_PATH_B;//s0
4291                 #else
4292                 pHalData->ant_path = ODM_RF_PATH_A;
4293                 #endif
4294         }
4295
4296 #ifdef CONFIG_FOR_RTL8723BS_VQ0
4297         pHalData->ant_path = ODM_RF_PATH_B;//s0
4298 #endif
4299
4300 #ifdef CONFIG_BT_COEXIST
4301         if (padapter->registrypriv.ant_num > 0) {
4302                 DBG_8192C("%s: Apply driver defined antenna number(%d) to replace origin(%d)\n",
4303                         __FUNCTION__,
4304                         padapter->registrypriv.ant_num,
4305                         pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1);
4306
4307                 switch (padapter->registrypriv.ant_num) {
4308                 case 1:
4309                         pHalData->EEPROMBluetoothAntNum = Ant_x1;
4310                         break;
4311                 case 2:
4312                         pHalData->EEPROMBluetoothAntNum = Ant_x2;
4313                         break;
4314                 default:
4315                         DBG_8192C("%s: Discard invalid driver defined antenna number(%d)!\n",
4316                                 __FUNCTION__, padapter->registrypriv.ant_num);
4317                         break;
4318                 }
4319         }
4320
4321         rtw_btcoex_SetBTCoexist(padapter, pHalData->EEPROMBluetoothCoexist);
4322         rtw_btcoex_SetChipType(padapter, pHalData->EEPROMBluetoothType);
4323         rtw_btcoex_SetPGAntNum(padapter, pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1); 
4324         if (pHalData->EEPROMBluetoothAntNum == Ant_x1)
4325         {
4326                 rtw_btcoex_SetSingleAntPath(padapter, pHalData->ant_path);
4327         }
4328 #endif // CONFIG_BT_COEXIST
4329
4330         DBG_8192C("%s: %s BT-coex, ant_num=%d\n",
4331                 __FUNCTION__,
4332                 pHalData->EEPROMBluetoothCoexist==_TRUE?"Enable":"Disable",
4333                 pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1);
4334 }
4335
4336 VOID
4337 Hal_EfuseParseEEPROMVer_8723B(
4338         IN      PADAPTER                padapter,
4339         IN      u8*                     hwinfo,
4340         IN      BOOLEAN                 AutoLoadFail
4341         )
4342 {
4343         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
4344
4345 //      RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4346         if(!AutoLoadFail)
4347                 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723B];
4348         else
4349                 pHalData->EEPROMVersion = 1;
4350         RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
4351                 pHalData->EEPROMVersion));
4352 }
4353
4354
4355
4356 VOID
4357 Hal_EfuseParsePackageType_8723B(
4358         IN      PADAPTER                pAdapter,
4359         IN      u8*                             hwinfo,
4360         IN      BOOLEAN         AutoLoadFail
4361         ) 
4362 {
4363         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
4364         u1Byte                  package;
4365         u8 efuseContent;
4366         
4367         Efuse_PowerSwitch(pAdapter, _FALSE, _TRUE);
4368         efuse_OneByteRead(pAdapter, 0x1FB, &efuseContent, FALSE);
4369         DBG_871X("%s phy efuse read 0x1FB =%x \n",__func__,efuseContent);
4370         Efuse_PowerSwitch(pAdapter, _FALSE, _FALSE);
4371         
4372         package = efuseContent & 0x7;
4373         switch (package) 
4374         {
4375                 case 0x4:
4376                         pHalData->PackageType = PACKAGE_TFBGA79;
4377                         break;
4378                 case 0x5:
4379                         pHalData->PackageType = PACKAGE_TFBGA90;
4380                         break;
4381                 case 0x6:
4382                         pHalData->PackageType = PACKAGE_QFN68;
4383                         break;
4384                 case 0x7:
4385                         pHalData->PackageType = PACKAGE_TFBGA80;
4386                         break;
4387
4388                 default:
4389                         pHalData->PackageType = PACKAGE_DEFAULT;
4390                         break;
4391         }
4392
4393         DBG_871X("PackageType = 0x%X\n", pHalData->PackageType);
4394 }
4395
4396
4397 VOID
4398 Hal_EfuseParseVoltage_8723B(
4399         IN      PADAPTER                pAdapter,
4400         IN      u8*                     hwinfo,
4401         IN      BOOLEAN         AutoLoadFail
4402         ) 
4403 {
4404         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
4405         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
4406
4407         //_rtw_memcpy(pEEPROM->adjuseVoltageVal, &hwinfo[EEPROM_Voltage_ADDR_8723B], 1);
4408         DBG_871X("%s hwinfo[EEPROM_Voltage_ADDR_8723B] =%02x \n",__func__, hwinfo[EEPROM_Voltage_ADDR_8723B]);
4409         pEEPROM->adjuseVoltageVal = (hwinfo[EEPROM_Voltage_ADDR_8723B] & 0xf0) >> 4 ;
4410         DBG_871X("%s pEEPROM->adjuseVoltageVal =%x \n",__func__,pEEPROM->adjuseVoltageVal);
4411 }
4412
4413 VOID
4414 Hal_EfuseParseChnlPlan_8723B(
4415         IN      PADAPTER                padapter,
4416         IN      u8*                     hwinfo,
4417         IN      BOOLEAN                 AutoLoadFail
4418         )
4419 {
4420         padapter->mlmepriv.ChannelPlan = hal_com_config_channel_plan(
4421                 padapter
4422                 , hwinfo?hwinfo[EEPROM_ChannelPlan_8723B]:0xFF
4423                 , padapter->registrypriv.channel_plan
4424                 , RT_CHANNEL_DOMAIN_WORLD_NULL
4425                 , AutoLoadFail
4426         );
4427
4428         RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM ChannelPlan=0x%02x\n", padapter->mlmepriv.ChannelPlan));
4429 }
4430
4431 VOID
4432 Hal_EfuseParseCustomerID_8723B(
4433         IN      PADAPTER                padapter,
4434         IN      u8*                     hwinfo,
4435         IN      BOOLEAN                 AutoLoadFail
4436         )
4437 {
4438         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
4439
4440 //      RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4441         if (!AutoLoadFail)
4442         {
4443                 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723B];
4444         }
4445         else
4446         {
4447                 pHalData->EEPROMCustomerID = 0;
4448         }
4449         RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID));
4450 }
4451
4452 VOID
4453 Hal_EfuseParseAntennaDiversity_8723B(
4454         IN      PADAPTER                pAdapter,
4455         IN      u8                              * hwinfo,
4456         IN      BOOLEAN                 AutoLoadFail
4457         )
4458 {
4459 #ifdef CONFIG_ANTENNA_DIVERSITY
4460         PHAL_DATA_TYPE          pHalData = GET_HAL_DATA(pAdapter);
4461         struct registry_priv    *registry_par = &pAdapter->registrypriv;
4462
4463         if (pHalData->EEPROMBluetoothAntNum == Ant_x1){
4464                 pHalData->AntDivCfg = 0;
4465         }
4466         else{
4467                 if(registry_par->antdiv_cfg == 2)// 0:OFF , 1:ON, 2:By EFUSE
4468                         pHalData->AntDivCfg = 1;
4469                 else
4470                         pHalData->AntDivCfg = registry_par->antdiv_cfg;
4471         }
4472
4473         // If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead.
4474         if(registry_par->antdiv_type == 0) {
4475                 pHalData->TRxAntDivType = hwinfo[EEPROM_RFE_OPTION_8723B];
4476                 if (pHalData->TRxAntDivType == 0xFF)
4477                         pHalData->TRxAntDivType = S0S1_SW_ANTDIV;//GetRegAntDivType(pAdapter);
4478                 else if (pHalData->TRxAntDivType == 0x10)
4479                         pHalData->TRxAntDivType = S0S1_SW_ANTDIV; //intrnal switch S0S1
4480                 else if (pHalData->TRxAntDivType == 0x11)
4481                         pHalData->TRxAntDivType = S0S1_SW_ANTDIV; //intrnal switch S0S1
4482                 else
4483                         DBG_8192C("%s: efuse[0x%x]=0x%02x is unknown type\n",
4484                                 __FUNCTION__, EEPROM_RFE_OPTION_8723B, pHalData->TRxAntDivType);
4485         }
4486         else{
4487                 pHalData->TRxAntDivType = registry_par->antdiv_type ;//GetRegAntDivType(pAdapter);
4488         }
4489
4490         DBG_8192C("%s: AntDivCfg=%d, AntDivType=%d\n",
4491                 __FUNCTION__, pHalData->AntDivCfg, pHalData->TRxAntDivType);
4492 #endif
4493 }
4494
4495 VOID
4496 Hal_EfuseParseXtal_8723B(
4497         IN      PADAPTER                pAdapter,
4498         IN      u8                      * hwinfo,
4499         IN      BOOLEAN         AutoLoadFail
4500         )
4501 {
4502         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
4503
4504 //      RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4505         if(!AutoLoadFail)
4506         {
4507                 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_8723B];
4508                 if(pHalData->CrystalCap == 0xFF)
4509                         pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723B;    //what value should 8812 set?
4510         }
4511         else
4512         {
4513                 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723B;
4514         }
4515         RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM CrystalCap: 0x%2x\n", pHalData->CrystalCap));
4516 }
4517
4518
4519 void
4520 Hal_EfuseParseThermalMeter_8723B(
4521         PADAPTER        padapter,
4522         u8                      *PROMContent,
4523         u8                      AutoLoadFail
4524         )
4525 {
4526         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
4527
4528 //      RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4529         //
4530         // ThermalMeter from EEPROM
4531         //
4532         if (_FALSE == AutoLoadFail)
4533                 pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8723B];
4534         else
4535                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8723B;
4536
4537         if ((pHalData->EEPROMThermalMeter == 0xff) || (_TRUE == AutoLoadFail))
4538         {
4539                 pHalData->bAPKThermalMeterIgnore = _TRUE;
4540                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8723B;
4541         }
4542
4543         RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM ThermalMeter=0x%x\n", pHalData->EEPROMThermalMeter));
4544 }
4545
4546
4547 #ifdef CONFIG_RF_GAIN_OFFSET
4548 void Hal_ReadRFGainOffset(
4549         IN              PADAPTER                Adapter,
4550         IN              u8*                     PROMContent,
4551         IN              BOOLEAN                 AutoloadFail)
4552 {
4553         //
4554         // BB_RF Gain Offset from EEPROM
4555         //
4556
4557         if(!AutoloadFail ){
4558                 Adapter->eeprompriv.EEPROMRFGainOffset =PROMContent[EEPROM_RF_GAIN_OFFSET];
4559                 DBG_871X("AutoloadFail =%x,\n", AutoloadFail);
4560                 Adapter->eeprompriv.EEPROMRFGainVal=EFUSE_Read1Byte(Adapter, EEPROM_RF_GAIN_VAL);
4561                 DBG_871X("Adapter->eeprompriv.EEPROMRFGainVal=%x\n", Adapter->eeprompriv.EEPROMRFGainVal);
4562         }
4563         else{
4564                 Adapter->eeprompriv.EEPROMRFGainOffset = 0;
4565                 Adapter->eeprompriv.EEPROMRFGainVal=0xFF;
4566                 DBG_871X("else AutoloadFail =%x,\n", AutoloadFail);
4567         }
4568         DBG_871X("EEPRORFGainOffset = 0x%02x\n", Adapter->eeprompriv.EEPROMRFGainOffset);
4569 }
4570 #endif //CONFIG_RF_GAIN_OFFSET
4571
4572 u8 
4573 BWMapping_8723B(
4574         IN      PADAPTER                Adapter,
4575         IN      struct pkt_attrib       *pattrib
4576 )
4577 {
4578         u8      BWSettingOfDesc = 0;
4579         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(Adapter);
4580
4581         //DBG_871X("BWMapping pHalData->CurrentChannelBW %d, pattrib->bwmode %d \n",pHalData->CurrentChannelBW,pattrib->bwmode);
4582
4583         if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_80)
4584         {
4585                 if(pattrib->bwmode == CHANNEL_WIDTH_80)
4586                         BWSettingOfDesc= 2;
4587                 else if(pattrib->bwmode == CHANNEL_WIDTH_40)
4588                         BWSettingOfDesc = 1;
4589                 else
4590                         BWSettingOfDesc = 0;
4591         }
4592         else if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_40)
4593         {
4594                 if((pattrib->bwmode == CHANNEL_WIDTH_40) || (pattrib->bwmode == CHANNEL_WIDTH_80))
4595                         BWSettingOfDesc = 1;
4596                 else
4597                         BWSettingOfDesc = 0;
4598         }
4599         else
4600                 BWSettingOfDesc = 0;
4601
4602         //if(pTcb->bBTTxPacket)
4603         //      BWSettingOfDesc = 0;
4604
4605         return BWSettingOfDesc;
4606 }
4607
4608 u8      SCMapping_8723B(PADAPTER Adapter, struct pkt_attrib *pattrib)
4609 {
4610         u8      SCSettingOfDesc = 0;
4611         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(Adapter);
4612
4613         //DBG_871X("SCMapping: pHalData->CurrentChannelBW %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur80MhzPrimeSC,pHalData->nCur40MhzPrimeSC);
4614         
4615         if(pHalData->CurrentChannelBW == CHANNEL_WIDTH_80)
4616         {
4617                 if(pattrib->bwmode == CHANNEL_WIDTH_80)
4618                 {
4619                         SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4620                 }
4621                 else if(pattrib->bwmode == CHANNEL_WIDTH_40)
4622                 {
4623                         if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
4624                                 SCSettingOfDesc = VHT_DATA_SC_40_LOWER_OF_80MHZ;
4625                         else if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
4626                                 SCSettingOfDesc = VHT_DATA_SC_40_UPPER_OF_80MHZ;
4627                         else
4628                                 DBG_871X("SCMapping: Not Correct Primary40MHz Setting \n");
4629                 }
4630                 else
4631                 {
4632                         if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
4633                                 SCSettingOfDesc = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
4634                         else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
4635                                 SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
4636                         else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
4637                                 SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
4638                         else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
4639                                 SCSettingOfDesc = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
4640                         else
4641                                 DBG_871X("SCMapping: Not Correct Primary40MHz Setting \n");
4642                 }
4643         }
4644         else if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_40)
4645         {
4646                 //DBG_871X("SCMapping: HT Case: pHalData->CurrentChannelBW %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur40MhzPrimeSC);
4647
4648                 if(pattrib->bwmode == CHANNEL_WIDTH_40)
4649                 {
4650                         SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4651                 }
4652                 else if(pattrib->bwmode == CHANNEL_WIDTH_20)
4653                 {
4654                         if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
4655                         {
4656                                 SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
4657                         }
4658                         else if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
4659                         {
4660                                 SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
4661                         }
4662                         else
4663                         {
4664                                 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4665                         }
4666                 }
4667         }
4668         else
4669         {
4670                 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4671         }
4672
4673         return SCSettingOfDesc;
4674 }
4675
4676
4677 static u8 fill_txdesc_sectype(struct pkt_attrib *pattrib)
4678 {
4679         u8 sectype = 0;
4680         if ((pattrib->encrypt > 0) && !pattrib->bswenc)
4681         {
4682                 switch (pattrib->encrypt)
4683                 {
4684                         // SEC_TYPE
4685                         case _WEP40_:
4686                         case _WEP104_:
4687                         case _TKIP_:
4688                         case _TKIP_WTMIC_:
4689                                 sectype = 1;
4690                                 break;
4691
4692 #ifdef CONFIG_WAPI_SUPPORT
4693                         case _SMS4_:
4694                                 sectype = 2;
4695                                 break;
4696 #endif
4697                         case _AES_:
4698                                 sectype = 3;
4699                                 break;
4700
4701                         case _NO_PRIVACY_:
4702                         default:
4703                                         break;
4704                 }
4705         }
4706         return sectype;
4707 }
4708
4709 static void fill_txdesc_vcs_8723b(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
4710 {
4711         //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
4712
4713         if (pattrib->vcs_mode) {
4714                 switch (pattrib->vcs_mode) {
4715                 case RTS_CTS:
4716                         SET_TX_DESC_RTS_ENABLE_8723B(ptxdesc, 1);
4717                         SET_TX_DESC_HW_RTS_ENABLE_8723B(ptxdesc, 1);
4718                         break;
4719
4720                 case CTS_TO_SELF:
4721                         SET_TX_DESC_CTS2SELF_8723B(ptxdesc, 1);
4722                         break;
4723
4724                 case NONE_VCS:
4725                 default:
4726                         break;
4727                 }
4728
4729                 SET_TX_DESC_RTS_RATE_8723B(ptxdesc, 8); // RTS Rate=24M
4730                 SET_TX_DESC_RTS_RATE_FB_LIMIT_8723B(ptxdesc, 0xF);
4731
4732                 if (padapter->mlmeextpriv.mlmext_info.preamble_mode == PREAMBLE_SHORT) {
4733                         SET_TX_DESC_RTS_SHORT_8723B(ptxdesc, 1);
4734                 }
4735
4736                 // Set RTS BW
4737                 if (pattrib->ht_en) {
4738                         SET_TX_DESC_RTS_SC_8723B(ptxdesc, SCMapping_8723B(padapter, pattrib));
4739                 }
4740         }
4741 }
4742
4743 static void fill_txdesc_phy_8723b(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
4744 {
4745         //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
4746
4747         if (pattrib->ht_en) {
4748                 SET_TX_DESC_DATA_BW_8723B(ptxdesc, BWMapping_8723B(padapter, pattrib));
4749                 SET_TX_DESC_DATA_SC_8723B(ptxdesc, SCMapping_8723B(padapter, pattrib));
4750         }
4751 }
4752
4753 static void rtl8723b_fill_default_txdesc(
4754         struct xmit_frame *pxmitframe,
4755         u8 *pbuf)
4756 {
4757         PADAPTER padapter;
4758         HAL_DATA_TYPE *pHalData;
4759         struct dm_priv *pdmpriv;
4760         struct mlme_ext_priv *pmlmeext;
4761         struct mlme_ext_info *pmlmeinfo;
4762         struct pkt_attrib *pattrib;
4763         s32 bmcst;
4764
4765         _rtw_memset(pbuf, 0, TXDESC_SIZE);
4766
4767         padapter = pxmitframe->padapter;
4768         pHalData = GET_HAL_DATA(padapter);
4769         pdmpriv = &pHalData->dmpriv;
4770         pmlmeext = &padapter->mlmeextpriv;
4771         pmlmeinfo = &(pmlmeext->mlmext_info);
4772
4773         pattrib = &pxmitframe->attrib;
4774         bmcst = IS_MCAST(pattrib->ra);
4775
4776         if (pxmitframe->frame_tag == DATA_FRAMETAG)
4777         {
4778                 u8 drv_userate = 0;
4779
4780                 SET_TX_DESC_MACID_8723B(pbuf, pattrib->mac_id);
4781                 SET_TX_DESC_RATE_ID_8723B(pbuf, pattrib->raid);
4782                 SET_TX_DESC_QUEUE_SEL_8723B(pbuf, pattrib->qsel);
4783                 SET_TX_DESC_SEQ_8723B(pbuf, pattrib->seqnum);
4784
4785                 SET_TX_DESC_SEC_TYPE_8723B(pbuf, fill_txdesc_sectype(pattrib));
4786                 fill_txdesc_vcs_8723b(padapter, pattrib, pbuf);
4787
4788                 if(pattrib->icmp_pkt ==1 && padapter->registrypriv.wifi_spec==1)
4789                         drv_userate = 1;
4790
4791                 if ((pattrib->ether_type != 0x888e) &&
4792                         (pattrib->ether_type != 0x0806) &&
4793                         (pattrib->ether_type != 0x88B4) &&
4794                         (pattrib->dhcp_pkt != 1) &&
4795                         (drv_userate != 1)
4796 #ifdef CONFIG_AUTO_AP_MODE
4797                     && (pattrib->pctrl != _TRUE)
4798 #endif
4799                         )
4800                 {
4801                         // Non EAP & ARP & DHCP type data packet
4802
4803                         if (pattrib->ampdu_en == _TRUE) {
4804                                 SET_TX_DESC_AGG_ENABLE_8723B(pbuf, 1);
4805                                 SET_TX_DESC_MAX_AGG_NUM_8723B(pbuf, 0x1F);
4806                                 SET_TX_DESC_AMPDU_DENSITY_8723B(pbuf, pattrib->ampdu_spacing);
4807                         }
4808                         else {
4809                                 SET_TX_DESC_AGG_BREAK_8723B(pbuf, 1);
4810                         }
4811
4812                         fill_txdesc_phy_8723b(padapter, pattrib, pbuf);
4813
4814                         SET_TX_DESC_DATA_RATE_FB_LIMIT_8723B(pbuf, 0x1F);
4815
4816                         if (pHalData->fw_ractrl == _FALSE) {
4817                                 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4818
4819                                 if (pHalData->dmpriv.INIDATA_RATE[pattrib->mac_id] & BIT(7)) {
4820                                         SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1);
4821                                 }
4822
4823                                 SET_TX_DESC_TX_RATE_8723B(pbuf, pHalData->dmpriv.INIDATA_RATE[pattrib->mac_id] & 0x7F);
4824                         }
4825
4826                         // modify data rate by iwpriv
4827                         if (padapter->fix_rate != 0xFF) {
4828                                 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4829                                 if (padapter->fix_rate & BIT(7)) {
4830                                         SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1);
4831                                 }
4832                                 SET_TX_DESC_TX_RATE_8723B(pbuf, padapter->fix_rate & 0x7F);
4833                                 if (!padapter->data_fb) {
4834                                         SET_TX_DESC_DISABLE_FB_8723B(pbuf, 1);
4835                                 }
4836                         }
4837
4838                         if (pattrib->ldpc) {
4839                                 SET_TX_DESC_DATA_LDPC_8723B(pbuf, 1);
4840                         }
4841
4842                         if (pattrib->stbc) {
4843                                 SET_TX_DESC_DATA_STBC_8723B(pbuf, 1);
4844                         }
4845
4846 #ifdef CONFIG_CMCC_TEST
4847                         SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1); /* use cck short premble */
4848 #endif
4849                 }
4850                 else
4851                 {
4852                         // EAP data packet and ARP packet.
4853                         // Use the 1M data rate to send the EAP/ARP packet.
4854                         // This will maybe make the handshake smooth.
4855
4856                         SET_TX_DESC_AGG_BREAK_8723B(pbuf, 1);
4857                         SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4858                         if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) {
4859                                 SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1);
4860                         }
4861                         SET_TX_DESC_TX_RATE_8723B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4862
4863                         DBG_8192C(FUNC_ADPT_FMT ": SP Packet(0x%04X) rate=0x%x\n",
4864                                 FUNC_ADPT_ARG(padapter), pattrib->ether_type, MRateToHwRate(pmlmeext->tx_rate));
4865                 }
4866
4867 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4868                 SET_TX_DESC_USB_TXAGG_NUM_8723B(pbuf, pxmitframe->agg_num);
4869 #endif
4870         }
4871         else if (pxmitframe->frame_tag == MGNT_FRAMETAG)
4872         {
4873 //              RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MGNT_FRAMETAG\n", __FUNCTION__));
4874
4875                 SET_TX_DESC_MACID_8723B(pbuf, pattrib->mac_id);
4876                 SET_TX_DESC_QUEUE_SEL_8723B(pbuf, pattrib->qsel);
4877                 SET_TX_DESC_RATE_ID_8723B(pbuf, pattrib->raid);
4878                 SET_TX_DESC_SEQ_8723B(pbuf, pattrib->seqnum);
4879                 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4880
4881                 SET_TX_DESC_MBSSID_8723B(pbuf, pattrib->mbssid & 0xF);
4882
4883                 SET_TX_DESC_RETRY_LIMIT_ENABLE_8723B(pbuf, 1);
4884                 if (pattrib->retry_ctrl == _TRUE) {
4885                         SET_TX_DESC_DATA_RETRY_LIMIT_8723B(pbuf, 6);
4886                 } else {
4887                         SET_TX_DESC_DATA_RETRY_LIMIT_8723B(pbuf, 12);
4888                 }
4889
4890 #ifdef CONFIG_INTEL_PROXIM
4891                 if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
4892                         DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
4893                         SET_TX_DESC_TX_RATE_8723B(pbuf, pattrib->rate);
4894                 }
4895                 else
4896 #endif
4897                 {
4898                         SET_TX_DESC_TX_RATE_8723B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4899                 }
4900
4901 #ifdef CONFIG_XMIT_ACK
4902                 // CCX-TXRPT ack for xmit mgmt frames.
4903                 if (pxmitframe->ack_report) {
4904                         #ifdef DBG_CCX
4905                         DBG_8192C("%s set spe_rpt\n", __FUNCTION__);
4906                         #endif
4907                         SET_TX_DESC_SPE_RPT_8723B(pbuf, 1);
4908                         SET_TX_DESC_SW_DEFINE_8723B(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no));
4909                 }
4910 #endif // CONFIG_XMIT_ACK
4911         }
4912         else if (pxmitframe->frame_tag == TXAGG_FRAMETAG)
4913         {
4914                 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: TXAGG_FRAMETAG\n", __FUNCTION__));
4915         }
4916 #ifdef CONFIG_MP_INCLUDED
4917         else if (pxmitframe->frame_tag == MP_FRAMETAG)
4918         {
4919                 RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MP_FRAMETAG\n", __FUNCTION__));
4920                 fill_txdesc_for_mp(padapter, pbuf);
4921         }
4922 #endif
4923         else
4924         {
4925                 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: frame_tag=0x%x\n", __FUNCTION__, pxmitframe->frame_tag));
4926
4927                 SET_TX_DESC_MACID_8723B(pbuf, pattrib->mac_id);
4928                 SET_TX_DESC_RATE_ID_8723B(pbuf, pattrib->raid);
4929                 SET_TX_DESC_QUEUE_SEL_8723B(pbuf, pattrib->qsel);
4930                 SET_TX_DESC_SEQ_8723B(pbuf, pattrib->seqnum);
4931                 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4932                 SET_TX_DESC_TX_RATE_8723B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4933         }
4934
4935         SET_TX_DESC_PKT_SIZE_8723B(pbuf, pattrib->last_txcmdsz);
4936
4937         {
4938                 u8 pkt_offset, offset;
4939
4940                 pkt_offset = 0;
4941                 offset = TXDESC_SIZE;
4942 #ifdef CONFIG_USB_HCI
4943                 pkt_offset = pxmitframe->pkt_offset;
4944                 offset += (pxmitframe->pkt_offset >> 3);
4945 #endif // CONFIG_USB_HCI
4946
4947 #ifdef CONFIG_TX_EARLY_MODE
4948                 if (pxmitframe->frame_tag == DATA_FRAMETAG) {
4949                         pkt_offset = 1;
4950                         offset += EARLY_MODE_INFO_SIZE;
4951                 }
4952 #endif // CONFIG_TX_EARLY_MODE
4953
4954                 SET_TX_DESC_PKT_OFFSET_8723B(pbuf, pkt_offset);
4955                 SET_TX_DESC_OFFSET_8723B(pbuf, offset);
4956         }
4957
4958         if (bmcst) {
4959                 SET_TX_DESC_BMC_8723B(pbuf, 1);
4960         }
4961
4962         // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
4963         // (1) The sequence number of each non-Qos frame / broadcast / multicast /
4964         // mgnt frame should be controled by Hw because Fw will also send null data
4965         // which we cannot control when Fw LPS enable.
4966         // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
4967         // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
4968         // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
4969         // 2010.06.23. Added by tynli.
4970         if (!pattrib->qos_en) {
4971                 SET_TX_DESC_HWSEQ_EN_8723B(pbuf, 1);
4972         }
4973 }
4974
4975 /*
4976  *      Description:
4977  *
4978  *      Parameters:
4979  *              pxmitframe      xmitframe
4980  *              pbuf            where to fill tx desc
4981  */
4982 void rtl8723b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
4983 {
4984         rtl8723b_fill_default_txdesc(pxmitframe, pbuf);
4985
4986 #ifdef CONFIG_ANTENNA_DIVERSITY
4987         ODM_SetTxAntByTxInfo(&GET_HAL_DATA(padapter)->odmpriv, pbuf, pxmitframe->attrib.mac_id);
4988 #endif // CONFIG_ANTENNA_DIVERSITY
4989
4990 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4991         rtl8723b_cal_txdesc_chksum((struct tx_desc*)pbuf);
4992 #endif
4993 }
4994
4995 //
4996 // Description: In normal chip, we should send some packet to Hw which will be used by Fw
4997 //                      in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
4998 //                      Fw can tell Hw to send these packet derectly.
4999 // Added by tynli. 2009.10.15.
5000 //
5001 //type1:pspoll, type2:null
5002 void rtl8723b_fill_fake_txdesc(
5003         PADAPTER        padapter,
5004         u8*                     pDesc,
5005         u32                     BufferLen,
5006         u8                      IsPsPoll,
5007         u8                      IsBTQosNull,
5008         u8                      bDataFrame)
5009 {
5010         // Clear all status
5011         _rtw_memset(pDesc, 0, TXDESC_SIZE);
5012
5013         SET_TX_DESC_FIRST_SEG_8723B(pDesc, 1); //bFirstSeg;
5014         SET_TX_DESC_LAST_SEG_8723B(pDesc, 1); //bLastSeg;
5015
5016         SET_TX_DESC_OFFSET_8723B(pDesc, 0x28); // Offset = 32
5017
5018         SET_TX_DESC_PKT_SIZE_8723B(pDesc, BufferLen); // Buffer size + command header
5019         SET_TX_DESC_QUEUE_SEL_8723B(pDesc, QSLT_MGNT); // Fixed queue of Mgnt queue
5020
5021         // Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
5022         if (_TRUE == IsPsPoll)
5023         {
5024                 SET_TX_DESC_NAV_USE_HDR_8723B(pDesc, 1);
5025         }
5026         else
5027         {
5028                 SET_TX_DESC_HWSEQ_EN_8723B(pDesc, 1); // Hw set sequence number
5029                 SET_TX_DESC_HWSEQ_SEL_8723B(pDesc, 0);
5030         }
5031
5032         if (_TRUE ==IsBTQosNull)
5033         {
5034                 SET_TX_DESC_BT_INT_8723B(pDesc, 1);
5035         }
5036
5037         SET_TX_DESC_USE_RATE_8723B(pDesc, 1); // use data rate which is set by Sw
5038         SET_TX_DESC_OWN_8723B((pu1Byte)pDesc, 1);
5039
5040         SET_TX_DESC_TX_RATE_8723B(pDesc, DESC8723B_RATE1M);
5041
5042         //
5043         // Encrypt the data frame if under security mode excepct null data. Suggested by CCW.
5044         //
5045         if (_TRUE ==bDataFrame)
5046         {
5047                 u32 EncAlg;
5048
5049                 EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
5050                 switch (EncAlg)
5051                 {
5052                         case _NO_PRIVACY_:
5053                                 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0); 
5054                                 break;
5055                         case _WEP40_:
5056                         case _WEP104_:
5057                         case _TKIP_:
5058                                 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x1); 
5059                                 break;
5060                         case _SMS4_:
5061                                 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x2); 
5062                                 break;
5063                         case _AES_:
5064                                 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x3);
5065                                 break;
5066                         default:
5067                                 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0); 
5068                                 break;   
5069                 }
5070         }
5071
5072 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5073         // USB interface drop packet if the checksum of descriptor isn't correct.
5074         // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
5075         rtl8723b_cal_txdesc_chksum((struct tx_desc*)pDesc);
5076 #endif
5077 }
5078
5079 #ifdef CONFIG_TSF_RESET_OFFLOAD
5080 int reset_tsf(PADAPTER Adapter, u8 reset_port )
5081 {
5082         u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
5083         u32 reg_reset_tsf_cnt = (IFACE_PORT0==reset_port) ?
5084                                 REG_FW_RESET_TSF_CNT_0:REG_FW_RESET_TSF_CNT_1;
5085
5086         rtw_scan_abort(Adapter->pbuddy_adapter);        /*      site survey will cause reset_tsf fail   */
5087         reset_cnt_after = reset_cnt_before = rtw_read8(Adapter,reg_reset_tsf_cnt);
5088         rtl8723b_reset_tsf(Adapter, reset_port);
5089
5090         while ((reset_cnt_after == reset_cnt_before ) && (loop_cnt < 10)) {
5091                 rtw_msleep_os(100);
5092                 loop_cnt++;
5093                 reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt);
5094         }
5095
5096         return(loop_cnt >= 10) ? _FAIL : _TRUE;
5097 }
5098 #endif // CONFIG_TSF_RESET_OFFLOAD
5099
5100 static void hw_var_set_opmode(PADAPTER padapter, u8 variable, u8* val)
5101 {
5102         u8 val8;
5103         u8 mode = *((u8 *)val);
5104
5105 #ifdef CONFIG_CONCURRENT_MODE
5106         if (padapter->iface_type == IFACE_PORT1)
5107         {
5108                 // disable Port1 TSF update
5109                 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5110                 val8 |= DIS_TSF_UDT;
5111                 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5112                 
5113                 Set_MSR(padapter, mode);
5114                 
5115                 DBG_871X("#### %s()-%d iface_type(%d) mode=%d ####\n",
5116                         __FUNCTION__, __LINE__, padapter->iface_type, mode);
5117
5118                 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
5119                 {
5120                         if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
5121                         {
5122                                 StopTxBeacon(padapter);
5123 #ifdef CONFIG_PCI_HCI
5124                                 UpdateInterruptMask8723BE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
5125 #else // !CONFIG_PCI_HCI
5126 #ifdef CONFIG_INTERRUPT_BASED_TXBCN     
5127
5128 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT   
5129                                 rtw_write8(padapter, REG_DRVERLYINT, 0x05);//restore early int time to 5ms
5130                                 UpdateInterruptMask8723BU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8723B);
5131 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5132
5133 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5134                                 UpdateInterruptMask8723BU(padapter, _TRUE ,0, (IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B));
5135 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5136
5137 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5138 #endif // !CONFIG_PCI_HCI
5139                         }
5140
5141                         // disable atim wnd and disable beacon function
5142                         rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|DIS_ATIM);
5143                 }
5144                 else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
5145                 {
5146                         ResumeTxBeacon(padapter);
5147                         rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
5148                 }
5149                 else if (mode == _HW_STATE_AP_)
5150                 {
5151 #ifdef CONFIG_PCI_HCI
5152                         UpdateInterruptMask8723BE(padapter, RT_BCN_INT_MASKS, 0, 0, 0);
5153 #else // !CONFIG_PCI_HCI
5154 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5155
5156 #ifdef  CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5157                         UpdateInterruptMask8723BU(padapter, _TRUE, IMR_BCNDMAINT0_8723B, 0);
5158 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5159
5160 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR  
5161                         UpdateInterruptMask8723BU(padapter, _TRUE, (IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B), 0);
5162 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5163
5164 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5165 #endif // !CONFIG_PCI_HCI
5166
5167                         ResumeTxBeacon(padapter);
5168
5169                         rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|DIS_BCNQ_SUB);
5170
5171                         // Set RCR
5172                         //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
5173                         //rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0
5174                         rtw_write32(padapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,reject ICV_ERR packet
5175                         // enable to rx data frame                              
5176                         rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5177                         // enable to rx ps-poll
5178                         rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
5179
5180                         // Beacon Control related register for first time 
5181                         rtw_write8(padapter, REG_BCNDMATIM, 0x02); // 2ms               
5182
5183                         //rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
5184                         rtw_write8(padapter, REG_ATIMWND_1, 0x0a); // 10ms for port1
5185                         rtw_write16(padapter, REG_BCNTCFG, 0x00);
5186                         rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
5187                         rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
5188         
5189                         // reset TSF2   
5190                         rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
5191
5192                         // enable BCN1 Function for if2
5193                         // don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received)
5194                         rtw_write8(padapter, REG_BCN_CTRL_1, (DIS_TSF_UDT|EN_BCN_FUNCTION | EN_TXBCN_RPT|DIS_BCNQ_SUB));
5195
5196                         //SW_BCN_SEL - Port1
5197                         //rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2)|BIT4);
5198                         rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
5199                         
5200                         // select BCN on port 1
5201                         rtw_write8(padapter, REG_CCK_CHECK_8723B,
5202                                 (rtw_read8(padapter, REG_CCK_CHECK_8723B)|BIT_BCN_PORT_SEL));
5203                         
5204                         if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
5205                         {
5206                                 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5207                                 val8 &= ~EN_BCN_FUNCTION;
5208                                 rtw_write8(padapter, REG_BCN_CTRL, val8);
5209                         }
5210
5211                         //BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked
5212                         //rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1)|BIT(5));
5213                         //rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(3));
5214                                         
5215                         //dis BCN0 ATIM  WND if if1 is station
5216                         rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|DIS_ATIM);
5217
5218 #ifdef CONFIG_TSF_RESET_OFFLOAD
5219                         // Reset TSF for STA+AP concurrent mode
5220                         if (check_buddy_fwstate(padapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)))
5221                         {
5222                                 if (reset_tsf(padapter, IFACE_PORT1) == _FALSE)
5223                                         DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
5224                                                 __FUNCTION__, __LINE__);
5225                         }
5226 #endif // CONFIG_TSF_RESET_OFFLOAD
5227                 }
5228         }
5229         else //else for port0
5230 #endif // CONFIG_CONCURRENT_MODE
5231         {
5232                 // disable Port0 TSF update
5233                 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5234                 val8 |= DIS_TSF_UDT;
5235                 rtw_write8(padapter, REG_BCN_CTRL, val8);
5236
5237                 // set net_type
5238                 Set_MSR(padapter, mode);
5239                 DBG_871X("#### %s() -%d iface_type(0) mode = %d ####\n", __FUNCTION__, __LINE__, mode);
5240
5241                 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
5242                 {
5243 #ifdef CONFIG_CONCURRENT_MODE
5244                         if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))            
5245 #endif // CONFIG_CONCURRENT_MODE
5246                         {
5247                                 StopTxBeacon(padapter);
5248 #ifdef CONFIG_PCI_HCI
5249                                 UpdateInterruptMask8723BE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
5250 #else // !CONFIG_PCI_HCI
5251 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5252 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5253                                 rtw_write8(padapter, REG_DRVERLYINT, 0x05); // restore early int time to 5ms
5254                                 UpdateInterruptMask8812AU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8723B);
5255 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5256
5257 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5258                                 UpdateInterruptMask8812AU(padapter,_TRUE ,0, (IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B));
5259 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5260
5261 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5262 #endif // !CONFIG_PCI_HCI
5263                         }
5264
5265                         // disable atim wnd
5266                         rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_ATIM);
5267                         //rtw_write8(padapter,REG_BCN_CTRL, 0x18);
5268                 }
5269                 else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
5270                 {
5271                         ResumeTxBeacon(padapter);
5272                         rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
5273                 }
5274                 else if (mode == _HW_STATE_AP_)
5275                 {
5276 #ifdef CONFIG_PCI_HCI
5277                         UpdateInterruptMask8723BE( padapter, RT_BCN_INT_MASKS, 0, 0, 0);
5278 #else // !CONFIG_PCI_HCI
5279 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5280 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5281                         UpdateInterruptMask8723BU(padapter, _TRUE ,IMR_BCNDMAINT0_8723B, 0);
5282 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5283
5284 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5285                         UpdateInterruptMask8723BU(padapter,_TRUE ,(IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B), 0);
5286 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5287
5288 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5289 #endif
5290
5291                         ResumeTxBeacon(padapter);
5292
5293                         rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|DIS_BCNQ_SUB);
5294
5295                         //Set RCR
5296                         //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
5297                         //rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0
5298                         rtw_write32(padapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,reject ICV_ERR packet
5299                         //enable to rx data frame
5300                         rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5301                         //enable to rx ps-poll
5302                         rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
5303
5304                         //Beacon Control related register for first time
5305                         rtw_write8(padapter, REG_BCNDMATIM, 0x02); // 2ms                       
5306                         
5307                         //rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
5308                         rtw_write8(padapter, REG_ATIMWND, 0x0a); // 10ms
5309                         rtw_write16(padapter, REG_BCNTCFG, 0x00);
5310                         rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
5311                         rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
5312
5313                         //reset TSF
5314                         rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
5315         
5316                         //enable BCN0 Function for if1
5317                         //don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received)
5318                         rtw_write8(padapter, REG_BCN_CTRL, (DIS_TSF_UDT|EN_BCN_FUNCTION|EN_TXBCN_RPT|DIS_BCNQ_SUB));
5319                 
5320                         //SW_BCN_SEL - Port0
5321                         //rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2) & ~BIT4);
5322                         rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
5323                         
5324                         // select BCN on port 0
5325                         rtw_write8(padapter, REG_CCK_CHECK_8723B,
5326                                 (rtw_read8(padapter, REG_CCK_CHECK_8723B)& ~BIT_BCN_PORT_SEL));                         
5327
5328 #ifdef CONFIG_CONCURRENT_MODE
5329                         if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
5330                         {
5331                                 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5332                                 val8 &= ~EN_BCN_FUNCTION;
5333                                 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5334                         }
5335 #endif // CONFIG_CONCURRENT_MODE
5336
5337                         // dis BCN1 ATIM  WND if if2 is station
5338                         val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5339                         val8 |= DIS_ATIM;
5340                         rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5341 #ifdef CONFIG_TSF_RESET_OFFLOAD
5342                         // Reset TSF for STA+AP concurrent mode
5343                         if (check_buddy_fwstate(padapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)))
5344                         {
5345                                 if (reset_tsf(padapter, IFACE_PORT0) == _FALSE)
5346                                         DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
5347                                                 __FUNCTION__, __LINE__);
5348                         }
5349 #endif  // CONFIG_TSF_RESET_OFFLOAD
5350                 }
5351         }
5352 }
5353
5354 static void hw_var_set_macaddr(PADAPTER padapter, u8 variable, u8 *val)
5355 {
5356         u8 idx = 0;
5357         u32 reg_macid;
5358
5359 #ifdef CONFIG_CONCURRENT_MODE
5360         if (padapter->iface_type == IFACE_PORT1)
5361         {
5362                 reg_macid = REG_MACID1;
5363         }
5364         else
5365 #endif
5366         {
5367                 reg_macid = REG_MACID;
5368         }
5369
5370         for (idx = 0 ; idx < 6; idx++)
5371         {
5372                 rtw_write8(GET_PRIMARY_ADAPTER(padapter), (reg_macid+idx), val[idx]);
5373         }
5374 }
5375
5376 static void hw_var_set_bssid(PADAPTER padapter, u8 variable, u8 *val)
5377 {
5378         u8      idx = 0;
5379         u32 reg_bssid;
5380
5381 #ifdef CONFIG_CONCURRENT_MODE
5382         if (padapter->iface_type == IFACE_PORT1)
5383         {
5384                 reg_bssid = REG_BSSID1;
5385         }
5386         else
5387 #endif
5388         {
5389                 reg_bssid = REG_BSSID;
5390         }
5391
5392         for (idx = 0 ; idx < 6; idx++)
5393         {
5394                 rtw_write8(padapter, (reg_bssid+idx), val[idx]);
5395         }
5396 }
5397
5398 static void hw_var_set_bcn_func(PADAPTER padapter, u8 variable, u8 *val)
5399 {
5400         u32 bcn_ctrl_reg;
5401
5402 #ifdef CONFIG_CONCURRENT_MODE
5403         if (padapter->iface_type == IFACE_PORT1)
5404         {
5405                 bcn_ctrl_reg = REG_BCN_CTRL_1;
5406         }
5407         else
5408 #endif
5409         {
5410                 bcn_ctrl_reg = REG_BCN_CTRL;
5411         }
5412
5413         if (*(u8*)val)
5414         {
5415                 rtw_write8(padapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
5416         }
5417         else
5418         {
5419                 u8 val8;
5420                 val8 = rtw_read8(padapter, bcn_ctrl_reg);
5421                 val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
5422 #ifdef CONFIG_BT_COEXIST
5423                 // Always enable port0 beacon function for PSTDMA
5424                 if (REG_BCN_CTRL == bcn_ctrl_reg)
5425                         val8 |= EN_BCN_FUNCTION;
5426 #endif
5427                 rtw_write8(padapter, bcn_ctrl_reg, val8);
5428         }
5429 }
5430
5431 static void hw_var_set_correct_tsf(PADAPTER padapter, u8 variable, u8* val)
5432 {
5433         u8 val8;
5434         u64     tsf;
5435         struct mlme_ext_priv *pmlmeext;
5436         struct mlme_ext_info *pmlmeinfo;
5437
5438
5439         pmlmeext = &padapter->mlmeextpriv;
5440         pmlmeinfo = &pmlmeext->mlmext_info;
5441         
5442         tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) -1024; //us
5443
5444         if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
5445                 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
5446         {
5447                 StopTxBeacon(padapter);
5448         }
5449
5450 #ifdef CONFIG_CONCURRENT_MODE
5451         if (padapter->iface_type == IFACE_PORT1)
5452         {
5453                 // disable related TSF function
5454                 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5455                 val8 &= ~EN_BCN_FUNCTION;
5456                 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5457
5458                 rtw_write32(padapter, REG_TSFTR1, tsf);
5459                 rtw_write32(padapter, REG_TSFTR1+4, tsf>>32);
5460
5461
5462                 // enable related TSF function
5463                 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5464                 val8 |= EN_BCN_FUNCTION;
5465                 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5466
5467                 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
5468                 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
5469                         && check_buddy_fwstate(padapter, WIFI_AP_STATE)
5470                         )
5471                 {
5472                         // disable related TSF function
5473                         val8 = rtw_read8(padapter, REG_BCN_CTRL);
5474                         val8 &= ~EN_BCN_FUNCTION;
5475                         rtw_write8(padapter, REG_BCN_CTRL, val8);
5476
5477                         rtw_write32(padapter, REG_TSFTR, tsf);
5478                         rtw_write32(padapter, REG_TSFTR+4, tsf>>32);
5479
5480                         // enable related TSF function
5481                         val8 = rtw_read8(padapter, REG_BCN_CTRL);
5482                         val8 |= EN_BCN_FUNCTION;
5483                         rtw_write8(padapter, REG_BCN_CTRL, val8);
5484 #ifdef CONFIG_TSF_RESET_OFFLOAD
5485                         // Update buddy port's TSF(TBTT) if it is SoftAP for beacon TX issue!
5486                         if (reset_tsf(padapter, IFACE_PORT0) == _FALSE)
5487                                 DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
5488                                         __FUNCTION__, __LINE__);
5489
5490 #endif // CONFIG_TSF_RESET_OFFLOAD
5491                 }
5492         }
5493         else
5494 #endif // CONFIG_CONCURRENT_MODE
5495         {
5496                 // disable related TSF function
5497                 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5498                 val8 &= ~EN_BCN_FUNCTION;
5499                 rtw_write8(padapter, REG_BCN_CTRL, val8);
5500
5501                 rtw_write32(padapter, REG_TSFTR, tsf);
5502                 rtw_write32(padapter, REG_TSFTR+4, tsf>>32);
5503
5504                 // enable related TSF function
5505                 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5506                 val8 |= EN_BCN_FUNCTION;
5507                 rtw_write8(padapter, REG_BCN_CTRL, val8);
5508
5509 #ifdef CONFIG_CONCURRENT_MODE
5510                 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
5511                 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
5512                         && check_buddy_fwstate(padapter, WIFI_AP_STATE))
5513                 {
5514                         // disable related TSF function
5515                         val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5516                         val8 &= ~EN_BCN_FUNCTION;
5517                         rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5518
5519                         rtw_write32(padapter, REG_TSFTR1, tsf);
5520                         rtw_write32(padapter, REG_TSFTR1+4, tsf>>32);
5521
5522                         // enable related TSF function
5523                         val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5524                         val8 |= EN_BCN_FUNCTION;
5525                         rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5526
5527 #ifdef CONFIG_TSF_RESET_OFFLOAD
5528                         // Update buddy port's TSF if it is SoftAP for beacon TX issue!
5529                         if (reset_tsf(padapter, IFACE_PORT1) == _FALSE)
5530                         {
5531                                 DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
5532                                         __FUNCTION__, __LINE__);
5533                         }
5534 #endif // CONFIG_TSF_RESET_OFFLOAD
5535                 }
5536 #endif // CONFIG_CONCURRENT_MODE
5537         }
5538
5539         if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5540                 || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
5541         {
5542                 ResumeTxBeacon(padapter);
5543         }
5544 }
5545
5546 static void hw_var_set_mlme_disconnect(PADAPTER padapter, u8 variable, u8 *val)
5547 {
5548         u8 val8;
5549
5550 #ifdef CONFIG_CONCURRENT_MODE
5551         if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
5552 #endif
5553         {
5554                 // Set RCR to not to receive data frame when NO LINK state
5555                 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF);
5556                 // reject all data frames
5557                 rtw_write16(padapter, REG_RXFLTMAP2, 0);
5558         }
5559
5560 #ifdef CONFIG_CONCURRENT_MODE
5561         if (padapter->iface_type == IFACE_PORT1)
5562         {
5563                 // reset TSF1
5564                 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
5565
5566                 // disable update TSF1
5567                 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5568                 val8 |= DIS_TSF_UDT;
5569                 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5570                 
5571                 // disable Port1's beacon function
5572                 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5573                 val8 &= ~EN_BCN_FUNCTION;
5574                 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5575         }
5576         else
5577 #endif
5578         {
5579                 // reset TSF
5580                 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
5581
5582                 // disable update TSF
5583                 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5584                 val8 |= DIS_TSF_UDT;
5585                 rtw_write8(padapter, REG_BCN_CTRL, val8);
5586         }
5587 }
5588
5589 static void hw_var_set_mlme_sitesurvey(PADAPTER padapter, u8 variable, u8* val)
5590 {
5591         u32     value_rcr, rcr_clear_bit, reg_bcn_ctl;
5592         u16     value_rxfltmap2;
5593         u8 val8;
5594         PHAL_DATA_TYPE pHalData;
5595         struct mlme_priv *pmlmepriv;
5596
5597
5598         pHalData = GET_HAL_DATA(padapter);
5599         pmlmepriv = &padapter->mlmepriv;
5600
5601 #ifdef CONFIG_CONCURRENT_MODE
5602         if (padapter->iface_type == IFACE_PORT1)
5603                 reg_bcn_ctl = REG_BCN_CTRL_1;
5604         else
5605 #endif
5606                 reg_bcn_ctl = REG_BCN_CTRL;
5607
5608 #ifdef CONFIG_FIND_BEST_CHANNEL
5609         rcr_clear_bit = (RCR_CBSSID_BCN | RCR_CBSSID_DATA);
5610
5611         // Recieve all data frames
5612         value_rxfltmap2 = 0xFFFF;
5613 #else // CONFIG_FIND_BEST_CHANNEL
5614
5615         rcr_clear_bit = RCR_CBSSID_BCN;
5616
5617         // config RCR to receive different BSSID & not to receive data frame
5618         value_rxfltmap2 = 0;
5619
5620 #endif // CONFIG_FIND_BEST_CHANNEL
5621
5622         if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
5623 #ifdef CONFIG_CONCURRENT_MODE
5624                 || (check_buddy_fwstate(padapter, WIFI_AP_STATE) == _TRUE)
5625 #endif
5626                 )
5627         {
5628                 rcr_clear_bit = RCR_CBSSID_BCN;
5629         }
5630 #ifdef CONFIG_TDLS
5631         // TDLS will clear RCR_CBSSID_DATA bit for connection.
5632         else if (padapter->tdlsinfo.link_established == _TRUE)
5633         {
5634                 rcr_clear_bit = RCR_CBSSID_BCN;
5635         }
5636 #endif // CONFIG_TDLS
5637
5638         value_rcr = rtw_read32(padapter, REG_RCR);
5639
5640         if (*((u8*)val))
5641         {
5642                 // under sitesurvey
5643                 value_rcr &= ~(rcr_clear_bit);
5644                 rtw_write32(padapter, REG_RCR, value_rcr);
5645
5646                 rtw_write16(padapter, REG_RXFLTMAP2, value_rxfltmap2);
5647
5648                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
5649                 {
5650                         // disable update TSF
5651                         val8 = rtw_read8(padapter, reg_bcn_ctl);
5652                         val8 |= DIS_TSF_UDT;
5653                         rtw_write8(padapter, reg_bcn_ctl, val8);
5654                 }
5655
5656                 // Save orignal RRSR setting.
5657                 pHalData->RegRRSR = rtw_read16(padapter, REG_RRSR);
5658
5659 #ifdef CONFIG_CONCURRENT_MODE
5660                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5661                         check_buddy_fwstate(padapter, _FW_LINKED))
5662                 {
5663                         StopTxBeacon(padapter);
5664                 }
5665 #endif
5666         }
5667         else
5668         {
5669                 // sitesurvey done
5670                 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))
5671 #ifdef CONFIG_CONCURRENT_MODE
5672                         || check_buddy_fwstate(padapter, (_FW_LINKED|WIFI_AP_STATE))
5673 #endif
5674                         )
5675                 {
5676                         // enable to rx data frame
5677                         rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5678                 }
5679
5680                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
5681                 {
5682                         // enable update TSF
5683                         val8 = rtw_read8(padapter, reg_bcn_ctl);
5684                         val8 &= ~DIS_TSF_UDT;
5685                         rtw_write8(padapter, reg_bcn_ctl, val8);
5686                 }
5687
5688                 value_rcr |= rcr_clear_bit;
5689                 rtw_write32(padapter, REG_RCR, value_rcr);
5690
5691                 // Restore orignal RRSR setting.
5692                 rtw_write16(padapter, REG_RRSR, pHalData->RegRRSR);
5693
5694 #ifdef CONFIG_CONCURRENT_MODE
5695                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5696                         check_buddy_fwstate(padapter, _FW_LINKED))
5697                 {
5698                         ResumeTxBeacon(padapter);
5699                 }
5700 #endif
5701         }
5702 }
5703
5704 static void hw_var_set_mlme_join(PADAPTER padapter, u8 variable, u8 *val)
5705 {
5706         u8 val8;
5707         u16 val16;
5708         u32 val32;
5709         u8 RetryLimit;
5710         u8 type;
5711         PHAL_DATA_TYPE pHalData;
5712         struct mlme_priv *pmlmepriv;
5713         EEPROM_EFUSE_PRIV *pEEPROM;
5714
5715
5716         RetryLimit = 0x30;
5717         type = *(u8*)val;
5718         pHalData = GET_HAL_DATA(padapter);
5719         pmlmepriv = &padapter->mlmepriv;
5720         pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
5721
5722 #ifdef CONFIG_CONCURRENT_MODE
5723         if (type == 0)
5724         {
5725                 // prepare to join
5726                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5727                         check_buddy_fwstate(padapter, _FW_LINKED))
5728                 {
5729                         StopTxBeacon(padapter);
5730                 }
5731
5732                 // enable to rx data frame.Accept all data frame
5733                 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5734
5735                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
5736                 {
5737                         val32 = rtw_read32(padapter, REG_RCR);
5738                         val32 |= RCR_CBSSID_BCN;
5739                         rtw_write32(padapter, REG_RCR, val32);
5740                 }
5741                 else
5742                 {
5743                         val32 = rtw_read32(padapter, REG_RCR);
5744                         val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
5745                         rtw_write32(padapter, REG_RCR, val32);
5746                 }
5747
5748                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
5749                 {
5750                         RetryLimit = (pEEPROM->CustomerID == RT_CID_CCX) ? 7 : 48;
5751                 }
5752                 else // Ad-hoc Mode
5753                 {
5754                         RetryLimit = 0x7;
5755                 }
5756         }
5757         else if (type == 1)
5758         {
5759                 // joinbss_event call back when join res < 0
5760                 if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
5761                         rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
5762
5763                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5764                         check_buddy_fwstate(padapter, _FW_LINKED))
5765                 {
5766                         ResumeTxBeacon(padapter);
5767
5768                         // reset TSF 1/2 after ResumeTxBeacon
5769                         rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
5770                 }
5771         }
5772         else if (type == 2)
5773         {
5774                 // sta add event call back
5775
5776                 // enable update TSF
5777                 if (padapter->iface_type == IFACE_PORT1)
5778                 {
5779                         val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5780                         val8 &= ~DIS_TSF_UDT;
5781                         rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5782                 }
5783                 else
5784                 {
5785                         val8 = rtw_read8(padapter, REG_BCN_CTRL);
5786                         val8 &= ~DIS_TSF_UDT;
5787                         rtw_write8(padapter, REG_BCN_CTRL, val8);
5788                 }
5789
5790                 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
5791                 {
5792                         rtw_write8(padapter, 0x542 ,0x02);
5793                         RetryLimit = 0x7;
5794                 }
5795
5796                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5797                         check_buddy_fwstate(padapter, _FW_LINKED))
5798                 {
5799                         ResumeTxBeacon(padapter);
5800
5801                         // reset TSF 1/2 after ResumeTxBeacon
5802                         rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
5803                 }
5804         }
5805
5806         val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
5807         rtw_write16(padapter, REG_RL, val16);
5808 #else // !CONFIG_CONCURRENT_MODE
5809         if (type == 0) // prepare to join
5810         {
5811                 //enable to rx data frame.Accept all data frame
5812                 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
5813                 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5814
5815                 val32 = rtw_read32(padapter, REG_RCR);
5816                 if (padapter->in_cta_test)
5817                         val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);//| RCR_ADF
5818                 else
5819                         val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
5820                 rtw_write32(padapter, REG_RCR, val32);
5821
5822                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
5823                 {
5824                         RetryLimit = (pEEPROM->CustomerID == RT_CID_CCX) ? 7 : 48;
5825                 }
5826                 else // Ad-hoc Mode
5827                 {
5828                         RetryLimit = 0x7;
5829                 }
5830         }
5831         else if (type == 1) //joinbss_event call back when join res < 0
5832         {
5833                 rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
5834         }
5835         else if (type == 2) //sta add event call back
5836         {
5837                 //enable update TSF
5838                 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5839                 val8 &= ~DIS_TSF_UDT;
5840                 rtw_write8(padapter, REG_BCN_CTRL, val8);
5841
5842                 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
5843                 {
5844                         RetryLimit = 0x7;
5845                 }
5846         }
5847
5848         val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
5849         rtw_write16(padapter, REG_RL, val16);
5850 #endif // !CONFIG_CONCURRENT_MODE
5851 }
5852
5853 void CCX_FwC2HTxRpt_8723b(PADAPTER padapter, u8 *pdata, u8 len)
5854 {
5855         u8 seq_no;
5856         
5857 #define GET_8723B_C2H_TX_RPT_LIFE_TIME_OVER(_Header)    LE_BITS_TO_1BYTE((_Header + 0), 6, 1)
5858 #define GET_8723B_C2H_TX_RPT_RETRY_OVER(_Header)        LE_BITS_TO_1BYTE((_Header + 0), 7, 1)
5859
5860         //DBG_871X("%s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", __func__, 
5861         //              *pdata, *(pdata+1), *(pdata+2), *(pdata+3), *(pdata+4), *(pdata+5), *(pdata+6), *(pdata+7));
5862
5863         seq_no = *(pdata+6);
5864
5865 #ifdef CONFIG_XMIT_ACK
5866         if (GET_8723B_C2H_TX_RPT_RETRY_OVER(pdata) | GET_8723B_C2H_TX_RPT_LIFE_TIME_OVER(pdata)) {
5867                 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
5868         }
5869 /*      
5870         else if(seq_no != padapter->xmitpriv.seq_no) {
5871                 DBG_871X("tx_seq_no=%d, rpt_seq_no=%d\n", padapter->xmitpriv.seq_no, seq_no);
5872                 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
5873         } 
5874 */      
5875         else {
5876                 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);
5877         }
5878 #endif
5879 }
5880
5881 #ifdef CONFIG_FW_C2H_DEBUG
5882 /*
5883  * C2H RX package original is 128.
5884  * If enable CONFIG_FW_C2H_DEBUG, it should increase to 256. 
5885  * C2H FW debug message:
5886  * without aggregate:
5887  * {C2H CmdID, Seq, SubID, Len, Content[0~n]}
5888  * Content[0~n] = { 'a' , 'b' , 'c' ,..., 'z' , '\n'}
5889  *
5890  * with aggregate:
5891  * {C2H CmdID, Seq, SubID, Len, Content[0~n]}
5892  * Content[0~n] = { 'a' , 'b' , 'c' ,..., 'z', '\n' , Extend C2H pkt 2...}
5893  * Extend C2H pkt 2 = {C2H CmdID, Seq, SubID, Len, Content = { 'a' , 'b' , 'c' ,..., 'z' , '\n'}}
5894  *
5895  * Author: Isaac
5896  */
5897 void Debug_FwC2H_8723b(PADAPTER padapter, u8 *pdata, u8 len)
5898 {
5899         int i = 0;
5900         int cnt = 0, total_length = 0;
5901         u8 buf[128]={0};
5902         u8 more_data = _FALSE;
5903         u8 *nextdata = NULL;
5904         u8 test = 0;
5905
5906         u8 data_len;
5907         u8 seq_no;
5908
5909         nextdata = pdata;
5910 #if 0
5911         for (i = 0 ; i < len ; i++) {
5912                 printk("%02x ", pdata[i]);
5913                 if ((i + 1)%8 == 0)
5914                         printk("\n");
5915         }
5916         printk("\n");
5917 #endif
5918         do {
5919                 data_len = *(nextdata + 1);
5920                 seq_no = *(nextdata + 2);
5921
5922                 for (i = 0 ; i < data_len - 2 ; i++) {
5923                         cnt += sprintf((buf+cnt), "%c", nextdata[3 + i]);
5924
5925                         if (nextdata[3 + i] == 0x0a && nextdata[4 + i] == 0xff) {
5926                                 more_data = _TRUE;
5927                         } else if (nextdata[3 + i] == 0x0a && nextdata[4 + i] != 0xff) {
5928                                 more_data = _FALSE;
5929                         }
5930                 }
5931
5932                 DBG_871X("[RTKFW, SEQ=%d]: %s", seq_no, buf);
5933                 data_len += 3;
5934                 total_length += data_len;
5935
5936                 if (more_data == _TRUE) {
5937                         _rtw_memset(buf, '\0', 128);
5938                         cnt = 0;
5939                         nextdata = (pdata + total_length);
5940                 }
5941         } while (more_data == _TRUE);
5942 }
5943 #endif //CONFIG_FW_C2H_DEBUG
5944
5945 s32 c2h_id_filter_ccx_8723b(u8 *buf)
5946 {
5947         struct c2h_evt_hdr_88xx *c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
5948         s32 ret = _FALSE;
5949         if (c2h_evt->id == C2H_CCX_TX_RPT)
5950                 ret = _TRUE;
5951         
5952         return ret;
5953 }
5954
5955
5956 s32 c2h_handler_8723b(PADAPTER padapter, u8 *buf)
5957 {
5958         struct c2h_evt_hdr_88xx *pC2hEvent = (struct c2h_evt_hdr_88xx *)buf;
5959         PHAL_DATA_TYPE  pHalData=GET_HAL_DATA(padapter);
5960         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
5961         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
5962         s32 ret = _SUCCESS;
5963         u8 index = 0;
5964
5965         if (pC2hEvent == NULL) {
5966                 DBG_8192C("%s(): pC2hEventis NULL\n",__FUNCTION__);
5967                 ret = _FAIL;
5968                 goto exit;
5969         }
5970
5971         switch (pC2hEvent->id)
5972         {
5973                 case C2H_AP_RPT_RSP:
5974                         {
5975 //YJ,TODO,130407
5976 #if 0
5977                                 u4Byte c2h_ap_keeplink = _TRUE;
5978                                 if (c2hBuf[2] == 0 && c2hBuf[3] == 0)
5979                                         c2h_ap_keeplink = _FALSE;
5980                                 else
5981                                         c2h_ap_keeplink = _TRUE;
5982
5983                                 if (_TRUE == pmlmeext->try_ap_c2h_wait) {
5984                                         if (_FALSE == c2h_ap_keeplink) {
5985                                                 pmlmeext->try_ap_c2h_wait = _FALSE;
5986                                                 RT_TRACE(_module_hal_init_c_, _drv_err_,("fw tell us link is off\n"));
5987                                                 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 65535);
5988                                         } else  {
5989                                                 RT_TRACE(_module_hal_init_c_, _drv_err_,("fw tell us link is on\n"));
5990                                         }
5991                                 } else {
5992                                         RT_TRACE(_module_hal_init_c_, _drv_err_,("we don't need this C2H\n"));
5993                                 }
5994                                 pmlmeext->check_ap_processing = _FALSE;
5995 #endif                          
5996                         }
5997                         break;
5998                 case C2H_DBG:
5999                         {
6000                                 RT_TRACE(_module_hal_init_c_, _drv_info_, ("c2h_handler_8723b: %s\n", pC2hEvent->payload));
6001                         }
6002                         break;
6003
6004                 case C2H_CCX_TX_RPT:
6005 //                      CCX_FwC2HTxRpt(padapter, QueueID, pC2hEvent->payload);
6006                         break;
6007
6008 #ifdef CONFIG_BT_COEXIST
6009 #ifdef CONFIG_PCI_HCI
6010                 case C2H_BT_RSSI:
6011 //                      fwc2h_ODM(padapter, tmpBuf, &C2hEvent);
6012                         //BT_FwC2hBtRssi(padapter, pC2hEvent->payload);
6013                         break;
6014 #endif
6015 #endif
6016
6017                 case C2H_EXT_RA_RPT:
6018 //                      C2HExtRaRptHandler(padapter, pC2hEvent->payload, C2hEvent.CmdLen);
6019                         break;
6020
6021                 case C2H_HW_INFO_EXCH:
6022                         RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], C2H_HW_INFO_EXCH\n"));
6023                         for (index = 0; index < pC2hEvent->plen; index++)
6024                         {
6025                                 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], tmpBuf[%d]=0x%x\n", index, pC2hEvent->payload[index]));
6026                         }
6027                         break;
6028
6029 #ifdef CONFIG_BT_COEXIST
6030                 case C2H_8723B_BT_INFO:
6031                         rtw_btcoex_BtInfoNotify(padapter, pC2hEvent->plen, pC2hEvent->payload);
6032                         break;
6033 #endif
6034
6035 #ifdef CONFIG_MP_INCLUDED
6036                 case C2H_8723B_BT_MP_INFO:
6037                         DBG_8192C(" %s, C2H_8723B_BT_MP_INFO pC2hEvent->plen=%d\n",__func__,pC2hEvent->plen);
6038                         MPTBT_FwC2hBtMpCtrl(padapter, pC2hEvent->payload, pC2hEvent->plen);
6039                         break;
6040 #endif
6041                 default:
6042                         break;
6043         }
6044
6045         // Clear event to notify FW we have read the command.
6046         // Note:
6047         //      If this field isn't clear, the FW won't update the next command message.
6048 //      rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
6049 exit:
6050         return ret;
6051 }
6052
6053 static void process_c2h_event(PADAPTER padapter, PC2H_EVT_HDR pC2hEvent, u8 *c2hBuf)
6054 {
6055         u8                              index = 0;
6056         PHAL_DATA_TYPE  pHalData=GET_HAL_DATA(padapter);
6057         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
6058         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
6059
6060         if (c2hBuf == NULL) {
6061                 DBG_8192C("%s c2hbuff is NULL\n",__FUNCTION__);
6062                 return;
6063         }
6064
6065         switch (pC2hEvent->CmdID)
6066         {
6067                 case C2H_AP_RPT_RSP:
6068                         #if 0
6069                         {
6070                         
6071                                 u4Byte c2h_ap_keeplink = _TRUE;
6072                                 if (c2hBuf[2] == 0 && c2hBuf[3] == 0)
6073                                         c2h_ap_keeplink = _FALSE;
6074                                 else
6075                                         c2h_ap_keeplink = _TRUE;
6076
6077                                 if (_TRUE == pmlmeext->try_ap_c2h_wait) {
6078                                         if (_FALSE == c2h_ap_keeplink) {
6079                                                 pmlmeext->try_ap_c2h_wait = _FALSE;
6080                                                 RT_TRACE(_module_hal_init_c_, _drv_err_,("fw tell us link is off\n"));
6081                                                 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 65535);
6082                                         } else  {
6083                                                 RT_TRACE(_module_hal_init_c_, _drv_err_,("fw tell us link is on\n"));
6084                                         }
6085                                 } else {
6086                                         RT_TRACE(_module_hal_init_c_, _drv_err_,("we don't need this C2H\n"));
6087                                 }
6088                                 pmlmeext->check_ap_processing = _FALSE;
6089                         }
6090                         #endif
6091                         break;
6092                 case C2H_DBG:
6093                         {
6094                                 RT_TRACE(_module_hal_init_c_, _drv_info_, ("C2HCommandHandler: %s\n", c2hBuf));
6095                         }
6096                         break;
6097
6098                 case C2H_CCX_TX_RPT:
6099                         CCX_FwC2HTxRpt_8723b(padapter, c2hBuf, pC2hEvent->CmdLen);
6100                         break;
6101
6102 #ifdef CONFIG_BT_COEXIST
6103 #ifdef CONFIG_PCI_HCI
6104                 case C2H_BT_RSSI:
6105 //                      fwc2h_ODM(padapter, tmpBuf, &C2hEvent);
6106                         //BT_FwC2hBtRssi(padapter, c2hBuf);
6107                         break;
6108 #endif
6109 #endif
6110
6111                 case C2H_EXT_RA_RPT:
6112 //                      C2HExtRaRptHandler(padapter, tmpBuf, C2hEvent.CmdLen);
6113                         break;
6114
6115                 case C2H_HW_INFO_EXCH:
6116                         RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], C2H_HW_INFO_EXCH\n"));
6117                         for (index = 0; index < pC2hEvent->CmdLen; index++)
6118                         {
6119                                 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], tmpBuf[%d]=0x%x\n", index, c2hBuf[index]));
6120                         }
6121                         break;
6122
6123 #ifdef CONFIG_BT_COEXIST
6124                 case C2H_8723B_BT_INFO:
6125                         rtw_btcoex_BtInfoNotify(padapter, pC2hEvent->CmdLen, c2hBuf);
6126                         break;
6127 #endif
6128
6129 #ifdef CONFIG_MP_INCLUDED
6130                 case C2H_8723B_BT_MP_INFO:
6131                         MPTBT_FwC2hBtMpCtrl(padapter, c2hBuf, pC2hEvent->CmdLen);
6132                         break;
6133 #endif
6134
6135 #ifdef CONFIG_FW_C2H_DEBUG
6136                 case C2H_8723B_FW_DEBUG:
6137                         Debug_FwC2H_8723b(padapter, c2hBuf, pC2hEvent->CmdLen);
6138                         break;
6139 #endif // CONFIG_FW_C2H_DEBUG
6140
6141                 default:
6142                         break;
6143         }
6144
6145 #ifndef CONFIG_C2H_PACKET_EN
6146         // Clear event to notify FW we have read the command.
6147         // Note:
6148         //      If this field isn't clear, the FW won't update the next command message.
6149         rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
6150 #endif
6151 }
6152
6153 #ifdef CONFIG_C2H_PACKET_EN
6154
6155 static void C2HPacketHandler_8723B(PADAPTER padapter, u8 *pbuffer, u16 length)
6156 {
6157         C2H_EVT_HDR     C2hEvent;
6158         u8 *tmpBuf=NULL;
6159 #ifdef CONFIG_WOWLAN
6160         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6161         
6162         if(pwrpriv->wowlan_mode == _TRUE)
6163         {
6164                 DBG_871X("%s(): return because wowolan_mode==TRUE! CMDID=%d\n", __func__, pbuffer[0]);
6165                 return;
6166         }
6167 #endif
6168         C2hEvent.CmdID = pbuffer[0];
6169         C2hEvent.CmdSeq = pbuffer[1];
6170         C2hEvent.CmdLen = length - 2;
6171         tmpBuf = pbuffer + 2;
6172
6173         //DBG_871X("%s C2hEvent.CmdID:%x C2hEvent.CmdLen:%x C2hEvent.CmdSeq:%x\n",
6174         //              __func__, C2hEvent.CmdID, C2hEvent.CmdLen, C2hEvent.CmdSeq);
6175         RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "C2HPacketHandler_8723B(): Command Content:\n", tmpBuf, C2hEvent.CmdLen);
6176         
6177         process_c2h_event(padapter, &C2hEvent, tmpBuf);
6178         //c2h_handler_8723b(padapter,&C2hEvent);
6179         return;
6180 }
6181
6182 void rtl8723b_c2h_packet_handler(PADAPTER padapter, u8 *pbuf, u16 length)
6183 {
6184         C2H_EVT_HDR C2hEvent;
6185         u8 *pdata;
6186
6187
6188         if (length == 0)
6189                 return;
6190
6191         C2hEvent.CmdID = pbuf[0];
6192         C2hEvent.CmdSeq = pbuf[1];
6193         C2hEvent.CmdLen = length - 2;
6194         pdata = pbuf + 2;
6195
6196         DBG_8192C("%s: C2H, ID=%d seq=%d len=%d\n",
6197                 __FUNCTION__, C2hEvent.CmdID, C2hEvent.CmdSeq, C2hEvent.CmdLen);
6198
6199         switch (C2hEvent.CmdID) {
6200         case C2H_CCX_TX_RPT:
6201 #ifdef CONFIG_FW_C2H_DEBUG
6202         case C2H_8723B_FW_DEBUG:
6203 #endif // CONFIG_FW_C2H_DEBUG
6204                 process_c2h_event(padapter, &C2hEvent, pdata);
6205                 break;
6206
6207         default:
6208                 pdata = rtw_zmalloc(length);
6209                 if (pdata == NULL)
6210                         break;
6211                 _rtw_memcpy(pdata, pbuf, length);
6212                 if (rtw_c2h_packet_wk_cmd(padapter, pdata, length) == _FAIL)
6213                         rtw_mfree(pdata, length);
6214                 break;
6215         }
6216 }
6217
6218 #else // !CONFIG_C2H_PACKET_EN
6219 //
6220 //C2H event format:
6221 // Field         TRIGGER                CONTENT    CMD_SEQ      CMD_LEN          CMD_ID
6222 // BITS  [127:120]      [119:16]          [15:8]                  [7:4]            [3:0]
6223 //2009.10.08. by tynli.
6224 static void C2HCommandHandler(PADAPTER padapter)
6225 {
6226         C2H_EVT_HDR     C2hEvent;
6227 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6228
6229         u8                              *tmpBuf = NULL;
6230         u8                              index = 0;
6231         u8                              bCmdMsgReady = _FALSE;
6232         u8                              U1bTmp = 0;
6233 //      u8                              QueueID = 0;
6234
6235         _rtw_memset(&C2hEvent, 0, sizeof(C2H_EVT_HDR));
6236
6237         C2hEvent.CmdID = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8723B);
6238         C2hEvent.CmdLen = rtw_read8(padapter, REG_C2HEVT_CMD_LEN_8723B);
6239         C2hEvent.CmdSeq = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8723B + 1);
6240
6241         RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "C2HCommandHandler(): ",
6242                 &C2hEvent , sizeof(C2hEvent));
6243
6244         U1bTmp = rtw_read8(padapter, REG_C2HEVT_CLEAR);
6245         DBG_871X("%s C2hEvent.CmdID:%x C2hEvent.CmdLen:%x C2hEvent.CmdSeq:%x\n",
6246                         __func__, C2hEvent.CmdID, C2hEvent.CmdLen, C2hEvent.CmdSeq);
6247
6248         if (U1bTmp == C2H_EVT_HOST_CLOSE)
6249         {
6250                 // Not ready.
6251                 return;
6252         }
6253         else if (U1bTmp == C2H_EVT_FW_CLOSE)
6254         {
6255                 bCmdMsgReady = _TRUE;
6256         }
6257         else
6258         {
6259                 // Not a valid value, reset the clear event.
6260                 goto exit;
6261         }
6262
6263         if(C2hEvent.CmdLen == 0)
6264                 goto exit;
6265         tmpBuf = rtw_zmalloc(C2hEvent.CmdLen);
6266         if (tmpBuf == NULL)
6267                 goto exit;
6268
6269         // Read the content
6270         for (index = 0; index < C2hEvent.CmdLen; index++)
6271         {
6272                 tmpBuf[index] = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8723B + 2 + index);
6273         }
6274
6275         RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "C2HCommandHandler(): Command Content:\n", tmpBuf, C2hEvent.CmdLen);
6276
6277         //process_c2h_event(padapter,&C2hEvent, tmpBuf);
6278         c2h_handler_8723b(padapter,&C2hEvent);
6279         if (tmpBuf)
6280                 rtw_mfree(tmpBuf, C2hEvent.CmdLen);
6281 #endif // CONFIG_SDIO_HCI || CONFIG_GSPI_HCI
6282
6283 #ifdef CONFIG_USB_HCI
6284         HAL_DATA_TYPE   *pHalData=GET_HAL_DATA(padapter);
6285
6286         _rtw_memset(&C2hEvent, 0, sizeof(C2H_EVT_HDR));
6287         C2hEvent.CmdID = pHalData->C2hArray[USB_C2H_CMDID_OFFSET] & 0xF;
6288         C2hEvent.CmdLen = (pHalData->C2hArray[USB_C2H_CMDID_OFFSET] & 0xF0) >> 4;
6289         C2hEvent.CmdSeq =pHalData->C2hArray[USB_C2H_SEQ_OFFSET];
6290         c2h_handler_8723b(padapter,(u8 *)&C2hEvent);
6291         //process_c2h_event(padapter,&C2hEvent,&pHalData->C2hArray[USB_C2H_EVENT_OFFSET]);
6292 #endif // CONFIG_USB_HCI
6293
6294         //REG_C2HEVT_CLEAR have done in process_c2h_event
6295         return;
6296 exit:
6297         rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
6298         return;
6299 }
6300
6301 #endif // !CONFIG_C2H_PACKET_EN
6302
6303 void SetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val)
6304 {
6305         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
6306         u8 val8;
6307         u16 val16;
6308         u32 val32;
6309
6310 _func_enter_;
6311
6312         switch (variable)
6313         {
6314                 case HW_VAR_MEDIA_STATUS:
6315                         val8 = rtw_read8(padapter, MSR) & 0x0c;
6316                         val8 |= *val;
6317                         rtw_write8(padapter, MSR, val8);
6318                         break;
6319
6320                 case HW_VAR_MEDIA_STATUS1:
6321                         val8 = rtw_read8(padapter, MSR) & 0x03;
6322                         val8 |= *val << 2;
6323                         rtw_write8(padapter, MSR, val8);
6324                         break;
6325
6326                 case HW_VAR_SET_OPMODE:
6327                         hw_var_set_opmode(padapter, variable, val);
6328                         break;
6329
6330                 case HW_VAR_MAC_ADDR:
6331                         hw_var_set_macaddr(padapter, variable, val);
6332                         break;
6333
6334                 case HW_VAR_BSSID:
6335                         hw_var_set_bssid(padapter, variable, val);
6336                         break;
6337
6338                 case HW_VAR_BASIC_RATE:
6339                 {
6340                         struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
6341                         u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
6342                         u16 rrsr_2g_force_mask = (RRSR_11M|RRSR_5_5M|RRSR_1M);
6343                         u16 rrsr_2g_allow_mask = (RRSR_24M|RRSR_12M|RRSR_6M|RRSR_CCK_RATES);
6344
6345                         HalSetBrateCfg(padapter, val, &BrateCfg);
6346                         input_b = BrateCfg;
6347
6348                         /* apply force and allow mask */
6349                         BrateCfg |= rrsr_2g_force_mask;
6350                         BrateCfg &= rrsr_2g_allow_mask;
6351                         masked = BrateCfg;
6352
6353                         #ifdef CONFIG_CMCC_TEST
6354                         BrateCfg |= (RRSR_11M|RRSR_5_5M|RRSR_1M); /* use 11M to send ACK */
6355                         BrateCfg |= (RRSR_24M|RRSR_18M|RRSR_12M); //CMCC_OFDM_ACK 12/18/24M
6356                         #endif
6357
6358                         /* IOT consideration */
6359                         if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
6360                                 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
6361                                 if((BrateCfg & (RRSR_24M|RRSR_12M|RRSR_6M)) == 0)
6362                                         BrateCfg |= RRSR_6M;
6363                         }
6364                         ioted = BrateCfg;
6365
6366                         pHalData->BasicRateSet = BrateCfg;
6367
6368                         DBG_8192C("HW_VAR_BASIC_RATE: %#x -> %#x -> %#x\n", input_b, masked, ioted);
6369
6370                         // Set RRSR rate table.
6371                         rtw_write16(padapter, REG_RRSR, BrateCfg);
6372                         rtw_write8(padapter, REG_RRSR+2, rtw_read8(padapter, REG_RRSR+2)&0xf0);
6373                 }
6374                         break;
6375
6376                 case HW_VAR_TXPAUSE:
6377                         rtw_write8(padapter, REG_TXPAUSE, *val);
6378                         break;
6379
6380                 case HW_VAR_BCN_FUNC:
6381                         hw_var_set_bcn_func(padapter, variable, val);
6382                         break;
6383
6384                 case HW_VAR_CORRECT_TSF:
6385                         hw_var_set_correct_tsf(padapter, variable, val);
6386                         break;
6387
6388                 case HW_VAR_CHECK_BSSID:
6389                         {
6390                                 u32 val32;
6391                                 val32 = rtw_read32(padapter, REG_RCR);
6392                                 if (*val)
6393                                         val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
6394                                 else
6395                                         val32 &= ~(RCR_CBSSID_DATA|RCR_CBSSID_BCN);
6396                                 rtw_write32(padapter, REG_RCR, val32);
6397                         }
6398                         break;
6399
6400                 case HW_VAR_MLME_DISCONNECT:
6401                         hw_var_set_mlme_disconnect(padapter, variable, val);
6402                         break;
6403
6404                 case HW_VAR_MLME_SITESURVEY:
6405                         hw_var_set_mlme_sitesurvey(padapter, variable,  val);
6406
6407 #ifdef CONFIG_BT_COEXIST
6408                         rtw_btcoex_ScanNotify(padapter, *val?_TRUE:_FALSE);
6409 #endif // CONFIG_BT_COEXIST
6410                         break;
6411
6412                 case HW_VAR_MLME_JOIN:
6413                         hw_var_set_mlme_join(padapter, variable, val);
6414
6415 #ifdef CONFIG_BT_COEXIST
6416                         switch (*val)
6417                         {
6418                                 case 0:
6419                                         // prepare to join
6420                                         rtw_btcoex_ConnectNotify(padapter, _TRUE);
6421                                         break;
6422                                 case 1:
6423                                         // joinbss_event callback when join res < 0
6424                                         rtw_btcoex_ConnectNotify(padapter, _FALSE);
6425                                         break;
6426                                 case 2:
6427                                         // sta add event callback
6428 //                                      rtw_btcoex_MediaStatusNotify(padapter, RT_MEDIA_CONNECT);
6429                                         break;
6430                         }
6431 #endif // CONFIG_BT_COEXIST
6432                         break;
6433
6434                 case HW_VAR_ON_RCR_AM:
6435                         val32 = rtw_read32(padapter, REG_RCR);
6436                         val32 |= RCR_AM;
6437                         rtw_write32(padapter, REG_RCR, val32);
6438                         DBG_8192C("%s, %d, RCR= %x\n", __FUNCTION__, __LINE__, rtw_read32(padapter, REG_RCR));
6439                         break;
6440
6441                 case HW_VAR_OFF_RCR_AM:
6442                         val32 = rtw_read32(padapter, REG_RCR);
6443                         val32 &= ~RCR_AM;
6444                         rtw_write32(padapter, REG_RCR, val32);
6445                         DBG_8192C("%s, %d, RCR= %x\n", __FUNCTION__, __LINE__, rtw_read32(padapter, REG_RCR));
6446                         break;
6447
6448                 case HW_VAR_BEACON_INTERVAL:
6449                         rtw_write16(padapter, REG_BCN_INTERVAL, *((u16*)val));
6450                         break;
6451
6452                 case HW_VAR_SLOT_TIME:
6453                         rtw_write8(padapter, REG_SLOT, *val);
6454                         break;
6455
6456                 case HW_VAR_RESP_SIFS:
6457 #if 0
6458                         // SIFS for OFDM Data ACK
6459                         rtw_write8(padapter, REG_SIFS_CTX+1, val[0]);
6460                         // SIFS for OFDM consecutive tx like CTS data!
6461                         rtw_write8(padapter, REG_SIFS_TRX+1, val[1]);
6462
6463                         rtw_write8(padapter, REG_SPEC_SIFS+1, val[0]);
6464                         rtw_write8(padapter, REG_MAC_SPEC_SIFS+1, val[0]);
6465
6466                         // 20100719 Joseph: Revise SIFS setting due to Hardware register definition change.
6467                         rtw_write8(padapter, REG_R2T_SIFS+1, val[0]);
6468                         rtw_write8(padapter, REG_T2T_SIFS+1, val[0]);
6469
6470 #else
6471                         //SIFS_Timer = 0x0a0a0808;
6472                         //RESP_SIFS for CCK
6473                         rtw_write8(padapter, REG_RESP_SIFS_CCK, val[0]); // SIFS_T2T_CCK (0x08)
6474                         rtw_write8(padapter, REG_RESP_SIFS_CCK+1, val[1]); //SIFS_R2T_CCK(0x08)
6475                         //RESP_SIFS for OFDM
6476                         rtw_write8(padapter, REG_RESP_SIFS_OFDM, val[2]); //SIFS_T2T_OFDM (0x0a)
6477                         rtw_write8(padapter, REG_RESP_SIFS_OFDM+1, val[3]); //SIFS_R2T_OFDM(0x0a)
6478 #endif
6479                         break;
6480
6481                 case HW_VAR_ACK_PREAMBLE:
6482                         {
6483                                 u8 regTmp;
6484                                 u8 bShortPreamble = *val;
6485
6486                                 // Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily)
6487                                 //regTmp = (pHalData->nCur40MhzPrimeSC)<<5;
6488                                 regTmp = 0;
6489                                 if (bShortPreamble) regTmp |= 0x80;
6490                                 rtw_write8(padapter, REG_RRSR+2, regTmp);
6491                         }
6492                         break;
6493
6494                 case HW_VAR_CAM_EMPTY_ENTRY:
6495                         {
6496                                 u8      ucIndex = *val;
6497                                 u8      i;
6498                                 u32     ulCommand = 0;
6499                                 u32     ulContent = 0;
6500                                 u32     ulEncAlgo = CAM_AES;
6501
6502                                 for (i=0; i<CAM_CONTENT_COUNT; i++)
6503                                 {
6504                                         // filled id in CAM config 2 byte
6505                                         if (i == 0)
6506                                         {
6507                                                 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2);
6508                                                 //ulContent |= CAM_VALID;
6509                                         }
6510                                         else
6511                                         {
6512                                                 ulContent = 0;
6513                                         }
6514                                         // polling bit, and No Write enable, and address
6515                                         ulCommand = CAM_CONTENT_COUNT*ucIndex+i;
6516                                         ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
6517                                         // write content 0 is equall to mark invalid
6518                                         rtw_write32(padapter, WCAMI, ulContent);  //delay_ms(40);
6519                                         //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %lx \n",ulContent));
6520                                         rtw_write32(padapter, RWCAM, ulCommand);  //delay_ms(40);
6521                                         //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %lx \n",ulCommand));
6522                                 }
6523                         }
6524                         break;
6525
6526                 case HW_VAR_CAM_INVALID_ALL:
6527                         rtw_write32(padapter, RWCAM, BIT(31)|BIT(30));
6528                         break;
6529
6530                 case HW_VAR_CAM_WRITE:
6531                         {
6532                                 u32 cmd;
6533                                 u32 *cam_val = (u32*)val;
6534
6535                                 rtw_write32(padapter, WCAMI, cam_val[0]);
6536
6537                                 cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
6538                                 rtw_write32(padapter, RWCAM, cmd);
6539                         }
6540                         break;
6541
6542                 case HW_VAR_AC_PARAM_VO:
6543                         rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32*)val));
6544                         break;
6545
6546                 case HW_VAR_AC_PARAM_VI:
6547                         rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32*)val));
6548                         break;
6549
6550                 case HW_VAR_AC_PARAM_BE:
6551                         pHalData->AcParam_BE = ((u32*)(val))[0];
6552                         rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32*)val));
6553                         break;
6554
6555                 case HW_VAR_AC_PARAM_BK:
6556                         rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32*)val));
6557                         break;
6558
6559                 case HW_VAR_ACM_CTRL:
6560                         {
6561                                 u8 ctrl = *((u8*)val);
6562                                 u8 hwctrl = 0;
6563
6564                                 if (ctrl != 0)
6565                                 {
6566                                         hwctrl |= AcmHw_HwEn;
6567
6568                                         if (ctrl & BIT(1)) // BE
6569                                                 hwctrl |= AcmHw_BeqEn;
6570
6571                                         if (ctrl & BIT(2)) // VI
6572                                                 hwctrl |= AcmHw_ViqEn;
6573
6574                                         if (ctrl & BIT(3)) // VO
6575                                                 hwctrl |= AcmHw_VoqEn;
6576                                 }
6577
6578                                 DBG_8192C("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
6579                                 rtw_write8(padapter, REG_ACMHWCTRL, hwctrl);
6580                         }
6581                         break;
6582
6583                 case HW_VAR_AMPDU_FACTOR:
6584                         {
6585                                 u32     AMPDULen =  (*((u8 *)val));
6586
6587                                 if(AMPDULen < HT_AGG_SIZE_32K)
6588                                         AMPDULen = (0x2000 << (*((u8 *)val))) -1;
6589                                 else
6590                                         AMPDULen = 0x7fff;
6591
6592                                 rtw_write32(padapter, REG_AMPDU_MAX_LENGTH_8723B, AMPDULen);
6593                         }
6594                         break;
6595
6596 #if 0
6597                 case HW_VAR_RXDMA_AGG_PG_TH:
6598                         rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, *val);
6599                         break;
6600 #endif
6601
6602                 case HW_VAR_H2C_FW_PWRMODE:
6603                         {
6604                                 u8 psmode = *val;
6605
6606                                 // Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power
6607                                 // saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang.
6608                                 if ((psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(pHalData->VersionID)))
6609                                 {
6610                                         ODM_RF_Saving(&pHalData->odmpriv, _TRUE);
6611                                 }
6612
6613                                 //if (psmode != PS_MODE_ACTIVE) {
6614                                 //      rtl8723b_set_lowpwr_lps_cmd(padapter, _TRUE);
6615                                 //} else {
6616                                 //      rtl8723b_set_lowpwr_lps_cmd(padapter, _FALSE);
6617                                 //}
6618                                 rtl8723b_set_FwPwrMode_cmd(padapter, psmode);
6619                         }
6620                         break;
6621                 case HW_VAR_H2C_PS_TUNE_PARAM:
6622                         rtl8723b_set_FwPsTuneParam_cmd(padapter);
6623                         break;
6624                         
6625                 case HW_VAR_H2C_FW_JOINBSSRPT:
6626                         rtl8723b_set_FwJoinBssRpt_cmd(padapter, *val);
6627                         break;
6628
6629 #ifdef CONFIG_P2P
6630                 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
6631                         rtl8723b_set_p2p_ps_offload_cmd(padapter, *val);
6632                         break;
6633 #endif //CONFIG_P2P
6634 #ifdef CONFIG_TDLS
6635                 case HW_VAR_TDLS_WRCR:
6636                         rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)&(~RCR_CBSSID_DATA ));
6637                         break;
6638                 case HW_VAR_TDLS_INIT_CH_SEN:
6639                         {
6640                                 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)&(~ RCR_CBSSID_DATA )&(~RCR_CBSSID_BCN ));
6641                                 rtw_write16(padapter, REG_RXFLTMAP2,0xffff);
6642
6643                                 //disable update TSF
6644                                 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|DIS_TSF_UDT);
6645                         }
6646                         break;
6647                 case HW_VAR_TDLS_DONE_CH_SEN:
6648                         {
6649                                 //enable update TSF
6650                                 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~ DIS_TSF_UDT));
6651                                 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|(RCR_CBSSID_BCN ));
6652                         }
6653                         break;
6654                 case HW_VAR_TDLS_RS_RCR:
6655                         rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|(RCR_CBSSID_DATA));
6656                         break;
6657 #endif //CONFIG_TDLS
6658 #ifdef CONFIG_SW_ANTENNA_DIVERSITY
6659                 case HW_VAR_ANTENNA_DIVERSITY_LINK:
6660                         //SwAntDivRestAfterLink8192C(padapter);
6661                         ODM_SwAntDivRestAfterLink(&pHalData->odmpriv);
6662                         break;
6663
6664                 case HW_VAR_ANTENNA_DIVERSITY_SELECT:
6665                         {
6666                                 u8 Optimum_antenna = *val;
6667
6668                                 //DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");
6669
6670                                 //PHY_SetBBReg(padapter, rFPGA0_XA_RFInterfaceOE, 0x300, Optimum_antenna);
6671                                 ODM_SetAntenna(&pHalData->odmpriv, Optimum_antenna);
6672                         }
6673                         break;
6674 #endif
6675
6676                 case HW_VAR_EFUSE_USAGE:
6677                         pHalData->EfuseUsedPercentage = *val;
6678                         break;
6679
6680                 case HW_VAR_EFUSE_BYTES:
6681                         pHalData->EfuseUsedBytes = *((u16*)val);
6682                         break;
6683
6684                 case HW_VAR_EFUSE_BT_USAGE:
6685 #ifdef HAL_EFUSE_MEMORY
6686                         pHalData->EfuseHal.BTEfuseUsedPercentage = *val;
6687 #endif
6688                         break;
6689
6690                 case HW_VAR_EFUSE_BT_BYTES:
6691 #ifdef HAL_EFUSE_MEMORY
6692                         pHalData->EfuseHal.BTEfuseUsedBytes = *((u16*)val);
6693 #else
6694                         BTEfuseUsedBytes = *((u16*)val);
6695 #endif
6696                         break;
6697
6698                 case HW_VAR_FIFO_CLEARN_UP:
6699                         {
6700                                 #define RW_RELEASE_EN           BIT(18)
6701                                 #define RXDMA_IDLE                      BIT(17)
6702
6703                                 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6704                                 u8 trycnt = 100;
6705
6706                                 // pause tx
6707                                 rtw_write8(padapter, REG_TXPAUSE, 0xff);
6708
6709                                 // keep sn
6710                                 padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ);
6711
6712                                 if (pwrpriv->bkeepfwalive != _TRUE)
6713                                 {
6714                                         /* RX DMA stop */
6715                                         val32 = rtw_read32(padapter, REG_RXPKT_NUM);
6716                                         val32 |= RW_RELEASE_EN;
6717                                         rtw_write32(padapter, REG_RXPKT_NUM, val32);
6718                                         do {
6719                                                 val32 = rtw_read32(padapter, REG_RXPKT_NUM);
6720                                                 val32 &= RXDMA_IDLE;
6721                                                 if (val32)
6722                                                         break;
6723
6724                                                 DBG_871X("%s: [HW_VAR_FIFO_CLEARN_UP] val=%x times:%d\n", __FUNCTION__, val32, trycnt);
6725                                         } while (--trycnt);
6726                                         if (trycnt == 0) {
6727                                                 DBG_8192C("[HW_VAR_FIFO_CLEARN_UP] Stop RX DMA failed......\n");
6728                                         }
6729
6730                                         // RQPN Load 0
6731                                         rtw_write16(padapter, REG_RQPN_NPQ, 0);
6732                                         rtw_write32(padapter, REG_RQPN, 0x80000000);
6733                                         rtw_mdelay_os(2);
6734                                 }
6735                         }
6736                         break;
6737
6738 #ifdef CONFIG_CONCURRENT_MODE
6739                 case HW_VAR_CHECK_TXBUF:
6740                         {
6741                                 u32 i;
6742                                 u8 RetryLimit = 0x01;
6743                                 u32 reg_200, reg_204;
6744
6745                                 val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
6746                                 rtw_write16(padapter, REG_RL, val16);
6747
6748                                 for (i=0; i<200; i++) // polling 200x10=2000 msec  
6749                                 {
6750                                         reg_200 = rtw_read32(padapter, 0x200);
6751                                         reg_204 = rtw_read32(padapter, 0x204);
6752                                         if (reg_200 != reg_204)
6753                                         {
6754                                                 //DBG_871X("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(padapter, 0x204), rtw_read32(padapter, 0x200), i);
6755                                                 rtw_msleep_os(10);
6756                                         }
6757                                         else
6758                                         {
6759                                                 DBG_871X("[HW_VAR_CHECK_TXBUF] no packet in tx packet buffer (%d)\n", i);
6760                                                 break;
6761                                         }
6762                                 }
6763
6764                                 if (reg_200 != reg_204)
6765                                         DBG_871X("packets in tx buffer - 0x204=%x, 0x200=%x\n", reg_204, reg_200);
6766                                 
6767                                 RetryLimit = 0x30;
6768                                 val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
6769                                 rtw_write16(padapter, REG_RL, val16);
6770                         }
6771                         break;
6772 #endif // CONFIG_CONCURRENT_MODE
6773
6774                 case HW_VAR_APFM_ON_MAC:
6775                         pHalData->bMacPwrCtrlOn = *val;
6776 #ifdef PLATFORM_LINUX
6777                         DBG_8192C("%s: bMacPwrCtrlOn=%d\n", __func__, pHalData->bMacPwrCtrlOn);
6778 #endif
6779                         break;
6780
6781                 case HW_VAR_NAV_UPPER:
6782                         {
6783                                 u32 usNavUpper = *((u32*)val);
6784
6785                                 if (usNavUpper > HAL_NAV_UPPER_UNIT_8723B * 0xFF)
6786                                 {
6787                                         RT_TRACE(_module_hal_init_c_, _drv_notice_, ("The setting value (0x%08X us) of NAV_UPPER is larger than (%d * 0xFF)!!!\n", usNavUpper, HAL_NAV_UPPER_UNIT_8723B));
6788                                         break;
6789                                 }
6790
6791                                 // The value of ((usNavUpper + HAL_NAV_UPPER_UNIT_8723B - 1) / HAL_NAV_UPPER_UNIT_8723B)
6792                                 // is getting the upper integer.
6793                                 usNavUpper = (usNavUpper + HAL_NAV_UPPER_UNIT_8723B - 1) / HAL_NAV_UPPER_UNIT_8723B;
6794                                 rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);
6795                         }
6796                         break;
6797
6798 #ifndef CONFIG_C2H_PACKET_EN
6799                 case HW_VAR_C2H_HANDLE:
6800                         C2HCommandHandler(padapter);
6801                         break;
6802 #endif
6803
6804                 case HW_VAR_H2C_MEDIA_STATUS_RPT:
6805                         {
6806                                 u16     mstatus_rpt = (*(u16 *)val);
6807                                 u8      mstatus, macId;
6808
6809                                 mstatus = (u8) (mstatus_rpt & 0xFF);
6810                                 macId = (u8)(mstatus_rpt >> 8)  ;
6811                                 rtl8723b_set_FwMediaStatusRpt_cmd(padapter , mstatus, macId);
6812                         }
6813                         break;
6814                 case HW_VAR_BCN_VALID:
6815 #ifdef CONFIG_CONCURRENT_MODE
6816                         if (padapter->iface_type == IFACE_PORT1)
6817                         {
6818                                 val8 = rtw_read8(padapter,  REG_DWBCN1_CTRL_8723B+2);
6819                                 val8 |= BIT(0);
6820                                 rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8); 
6821                         }
6822                         else
6823 #endif // CONFIG_CONCURRENT_MODE
6824                         {
6825                                 // BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw
6826                                 val8 = rtw_read8(padapter, REG_TDECTRL+2);
6827                                 val8 |= BIT(0);
6828                                 rtw_write8(padapter, REG_TDECTRL+2, val8);
6829                         }
6830                         break;
6831
6832                 case HW_VAR_DL_BCN_SEL:
6833 #ifdef CONFIG_CONCURRENT_MODE
6834                         if (padapter->iface_type == IFACE_PORT1)
6835                         {
6836                                 // SW_BCN_SEL - Port1
6837                                 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
6838                                 val8 |= BIT(4);
6839                                 rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8);
6840                         }
6841                         else
6842 #endif // CONFIG_CONCURRENT_MODE
6843                         {
6844                                 // SW_BCN_SEL - Port0
6845                                 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
6846                                 val8 &= ~BIT(4);
6847                                 rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8);    
6848                         }
6849                         break;
6850
6851                 case HW_VAR_DO_IQK:
6852                         pHalData->bNeedIQK = _TRUE;
6853                         break;
6854
6855                 case HW_VAR_DL_RSVD_PAGE:
6856 #ifdef CONFIG_BT_COEXIST
6857                         if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6858                         {
6859                                 rtl8723b_download_BTCoex_AP_mode_rsvd_page(padapter);
6860                         }
6861                         else
6862 #endif // CONFIG_BT_COEXIST
6863                         {
6864                                 rtl8723b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
6865                         }
6866                         break;
6867
6868                 case HW_VAR_MACID_SLEEP:
6869                 {
6870                         u32 reg_macid_sleep;
6871                         u8 bit_shift;
6872                         u8 id = *(u8*)val;
6873
6874                         if (id < 32) {
6875                                 reg_macid_sleep = REG_MACID_SLEEP;
6876                                 bit_shift = id;
6877                         } else if (id < 64) {
6878                                 reg_macid_sleep = REG_MACID_SLEEP_1;
6879                                 bit_shift = id-32;
6880                         } else if (id < 96) {
6881                                 reg_macid_sleep = REG_MACID_SLEEP_2;
6882                                 bit_shift = id-64;
6883                         } else if (id < 128) {
6884                                 reg_macid_sleep = REG_MACID_SLEEP_3;
6885                                 bit_shift = id-96;
6886                         } else {
6887                                 rtw_warn_on(1);
6888                                 break;
6889                         }
6890
6891                         val32 = rtw_read32(padapter, reg_macid_sleep);
6892                         DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_SLEEP] macid=%d, org reg_0x%03x=0x%08X\n",
6893                                 FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32);
6894
6895                         if (val32 & BIT(bit_shift))
6896                                 break;
6897
6898                         val32 |= BIT(bit_shift);
6899                         rtw_write32(padapter, reg_macid_sleep, val32);
6900                 }
6901                         break;
6902
6903                 case HW_VAR_MACID_WAKEUP:
6904                 {
6905                         u32 reg_macid_sleep;
6906                         u8 bit_shift;
6907                         u8 id = *(u8*)val;
6908
6909                         if (id < 32) {
6910                                 reg_macid_sleep = REG_MACID_SLEEP;
6911                                 bit_shift = id;
6912                         } else if (id < 64) {
6913                                 reg_macid_sleep = REG_MACID_SLEEP_1;
6914                                 bit_shift = id-32;
6915                         } else if (id < 96) {
6916                                 reg_macid_sleep = REG_MACID_SLEEP_2;
6917                                 bit_shift = id-64;
6918                         } else if (id < 128) {
6919                                 reg_macid_sleep = REG_MACID_SLEEP_3;
6920                                 bit_shift = id-96;
6921                         } else {
6922                                 rtw_warn_on(1);
6923                                 break;
6924                         }
6925
6926                         val32 = rtw_read32(padapter, reg_macid_sleep);
6927                         DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_WAKEUP] macid=%d, org reg_0x%03x=0x%08X\n",
6928                                 FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32);
6929
6930                         if (!(val32 & BIT(bit_shift)))
6931                                 break;
6932
6933                         val32 &= ~BIT(bit_shift);
6934                         rtw_write32(padapter, reg_macid_sleep, val32);
6935                 }
6936                         break;
6937
6938                 default:
6939                         SetHwReg(padapter, variable, val);
6940                         break;
6941         }
6942
6943 _func_exit_;
6944 }
6945
6946 struct qinfo_8723b {
6947         u32 head:8;
6948         u32 pkt_num:7;
6949         u32 tail:8;
6950         u32 ac:2;
6951         u32 macid:7;
6952 };
6953
6954 struct bcn_qinfo_8723b {
6955         u16 head:8;
6956         u16 pkt_num:8;
6957 };
6958
6959 void dump_qinfo_8723b(void *sel, struct qinfo_8723b *info, const char *tag)
6960 {
6961         //if (info->pkt_num)
6962         DBG_871X_SEL_NL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n"
6963                 , tag ? tag : "", info->head, info->tail, info->pkt_num, info->macid, info->ac
6964         );
6965 }
6966
6967 void dump_bcn_qinfo_8723b(void *sel, struct bcn_qinfo_8723b *info, const char *tag)
6968 {
6969         //if (info->pkt_num)
6970         DBG_871X_SEL_NL(sel, "%shead:0x%02x, pkt_num:%u\n"
6971                 , tag ? tag : "", info->head, info->pkt_num
6972         );
6973 }
6974
6975 void dump_mac_qinfo_8723b(void *sel, _adapter *adapter)
6976 {
6977         u32 q0_info;
6978         u32 q1_info;
6979         u32 q2_info;
6980         u32 q3_info;
6981         u32 q4_info;
6982         u32 q5_info;
6983         u32 q6_info;
6984         u32 q7_info;
6985         u32 mg_q_info;
6986         u32 hi_q_info;
6987         u16 bcn_q_info;
6988
6989         q0_info = rtw_read32(adapter, REG_Q0_INFO);
6990         q1_info = rtw_read32(adapter, REG_Q1_INFO);
6991         q2_info = rtw_read32(adapter, REG_Q2_INFO);
6992         q3_info = rtw_read32(adapter, REG_Q3_INFO);
6993         q4_info = rtw_read32(adapter, REG_Q4_INFO);
6994         q5_info = rtw_read32(adapter, REG_Q5_INFO);
6995         q6_info = rtw_read32(adapter, REG_Q6_INFO);
6996         q7_info = rtw_read32(adapter, REG_Q7_INFO);
6997         mg_q_info = rtw_read32(adapter, REG_MGQ_INFO);
6998         hi_q_info = rtw_read32(adapter, REG_HGQ_INFO);
6999         bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO);
7000
7001         dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q0_info, "Q0 ");
7002         dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q1_info, "Q1 ");
7003         dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q2_info, "Q2 ");
7004         dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q3_info, "Q3 ");
7005         dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q4_info, "Q4 ");
7006         dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q5_info, "Q5 ");
7007         dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q6_info, "Q6 ");
7008         dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q7_info, "Q7 ");
7009         dump_qinfo_8723b(sel, (struct qinfo_8723b *)&mg_q_info, "MG ");
7010         dump_qinfo_8723b(sel, (struct qinfo_8723b *)&hi_q_info, "HI ");
7011         dump_bcn_qinfo_8723b(sel, (struct bcn_qinfo_8723b *)&bcn_q_info, "BCN ");
7012 }
7013
7014 void GetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val)
7015 {
7016         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
7017         u8 val8;
7018         u16 val16;
7019         u32 val32;
7020
7021
7022         switch (variable)
7023         {
7024                 case HW_VAR_TXPAUSE:
7025                         *val = rtw_read8(padapter, REG_TXPAUSE);
7026                         break;
7027
7028                 case HW_VAR_BCN_VALID:
7029 #ifdef CONFIG_CONCURRENT_MODE
7030                         if (padapter->iface_type == IFACE_PORT1)
7031                         {
7032                                 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
7033                                 *val = (BIT(0) & val8) ? _TRUE:_FALSE;
7034                         }
7035                         else
7036 #endif
7037                         {
7038                                 // BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2
7039                                 val8 = rtw_read8(padapter, REG_TDECTRL+2);
7040                                 *val = (BIT(0) & val8) ? _TRUE:_FALSE;
7041                         }
7042                         break;
7043
7044                 case HW_VAR_FWLPS_RF_ON:
7045                         {
7046                                 // When we halt NIC, we should check if FW LPS is leave.
7047                                 u32 valRCR;
7048
7049                                 if ((padapter->bSurpriseRemoved == _TRUE) ||
7050                                         (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off))
7051                                 {
7052                                         // If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave,
7053                                         // because Fw is unload.
7054                                         *val = _TRUE;
7055                                 }
7056                                 else
7057                                 {
7058                                         valRCR = rtw_read32(padapter, REG_RCR);
7059                                         valRCR &= 0x00070000;
7060                                         if(valRCR)
7061                                                 *val = _FALSE;
7062                                         else
7063                                                 *val = _TRUE;
7064                                 }
7065                         }
7066                         break;
7067
7068 #ifdef CONFIG_ANTENNA_DIVERSITY
7069                 case HW_VAR_CURRENT_ANTENNA:
7070                         *val = pHalData->CurAntenna;
7071                         break;
7072 #endif
7073
7074                 case HW_VAR_EFUSE_USAGE:
7075                         *val = pHalData->EfuseUsedPercentage;
7076                         break;
7077
7078                 case HW_VAR_EFUSE_BYTES:
7079                         *((u16*)val) = pHalData->EfuseUsedBytes;
7080                         break;
7081
7082                 case HW_VAR_EFUSE_BT_USAGE:
7083 #ifdef HAL_EFUSE_MEMORY
7084                         *val = pHalData->EfuseHal.BTEfuseUsedPercentage;
7085 #endif
7086                         break;
7087
7088                 case HW_VAR_EFUSE_BT_BYTES:
7089 #ifdef HAL_EFUSE_MEMORY
7090                         *((u16*)val) = pHalData->EfuseHal.BTEfuseUsedBytes;
7091 #else
7092                         *((u16*)val) = BTEfuseUsedBytes;
7093 #endif
7094                         break;
7095
7096                 case HW_VAR_APFM_ON_MAC:
7097                         *val = pHalData->bMacPwrCtrlOn;
7098                         break;
7099                 case HW_VAR_CHK_HI_QUEUE_EMPTY:
7100                         val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);
7101                         *val = (val16 & BIT(10)) ? _TRUE:_FALSE;
7102                         break;
7103 #ifdef CONFIG_WOWLAN
7104                 case HW_VAR_RPWM_TOG:
7105                         *val = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1) & BIT7;
7106                         break;
7107                 case HW_VAR_WAKEUP_REASON:
7108                         *val = rtw_read8(padapter, REG_WOWLAN_WAKE_REASON);
7109                         if(*val == 0xEA)
7110                                 *val = 0;
7111                         break;
7112                 case HW_VAR_SYS_CLKR:
7113                         *val = rtw_read8(padapter, REG_SYS_CLKR);
7114                         break;
7115 #endif
7116                 case HW_VAR_DUMP_MAC_QUEUE_INFO:
7117                         dump_mac_qinfo_8723b(val, padapter);
7118                         break;
7119                 default:
7120                         GetHwReg(padapter, variable, val);
7121                         break;
7122         }
7123 }
7124
7125 /*
7126  *      Description:
7127  *              Change default setting of specified variable.
7128  */
7129 u8 SetHalDefVar8723B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
7130 {
7131         PHAL_DATA_TYPE pHalData;
7132         u8 bResult;
7133
7134
7135         pHalData = GET_HAL_DATA(padapter);
7136         bResult = _SUCCESS;
7137
7138         switch (variable)
7139         {
7140                 default:
7141                         bResult = SetHalDefVar(padapter, variable, pval);
7142                         break;
7143         }
7144
7145         return bResult;
7146 }
7147
7148 #ifdef CONFIG_C2H_PACKET_EN
7149 void SetHwRegWithBuf8723B(PADAPTER padapter, u8 variable, u8 *pbuf, int len)
7150 {
7151         PHAL_DATA_TYPE pHalData;
7152
7153 _func_enter_;
7154
7155         pHalData = GET_HAL_DATA(padapter);
7156
7157         switch (variable) {
7158         case HW_VAR_C2H_HANDLE:
7159                 C2HPacketHandler_8723B(padapter, pbuf, len);
7160                 break;
7161
7162         default:
7163                 break;
7164         }
7165 _func_exit_;
7166 }
7167 #endif // CONFIG_C2H_PACKET_EN
7168
7169 /*
7170  *      Description: 
7171  *              Query setting of specified variable.
7172  */
7173 u8 GetHalDefVar8723B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
7174 {
7175         PHAL_DATA_TYPE pHalData;
7176         u8 bResult;
7177
7178
7179         pHalData = GET_HAL_DATA(padapter);
7180         bResult = _SUCCESS;
7181
7182         switch (variable)
7183         {
7184                 case HAL_DEF_MAX_RECVBUF_SZ:
7185                         *((u32*)pval) = MAX_RECVBUF_SZ;
7186                         break;
7187
7188                 case HAL_DEF_RX_PACKET_OFFSET:
7189                         *((u32*)pval) = RXDESC_SIZE + DRVINFO_SZ*8;
7190                         break;
7191
7192                 case HW_VAR_MAX_RX_AMPDU_FACTOR:
7193                         // Stanley@BB.SD3 suggests 16K can get stable performance
7194                         // The experiment was done on SDIO interface
7195                         // coding by Lucas@20130730
7196                         *(HT_CAP_AMPDU_FACTOR*)pval = MAX_AMPDU_FACTOR_16K;
7197                         break;
7198                 case HAL_DEF_TX_LDPC:
7199                 case HAL_DEF_RX_LDPC:
7200                         *((u8 *)pval) = _FALSE;
7201                         break;
7202                 case HAL_DEF_TX_STBC:
7203                         *((u8 *)pval) = 0;
7204                         break;
7205                 case HAL_DEF_RX_STBC:
7206                         *((u8 *)pval) = 1;
7207                         break;
7208                 case HAL_DEF_EXPLICIT_BEAMFORMER:
7209                 case HAL_DEF_EXPLICIT_BEAMFORMEE:
7210                         *((u8 *)pval) = _FALSE;
7211                         break;
7212
7213                 case HW_DEF_RA_INFO_DUMP:
7214                         {
7215                                 u8 mac_id = *(u8*)pval;
7216                                 u32 cmd;
7217                                 u32 ra_info1, ra_info2;
7218                                 u32 rate_mask1, rate_mask2;
7219                                 u8 curr_tx_rate,curr_tx_sgi,hight_rate,lowest_rate;                     
7220                                 
7221                                 DBG_8192C("============ RA status check  Mac_id:%d ===================\n", mac_id);
7222
7223                                 cmd = 0x40000100 | mac_id;
7224                                 rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B, cmd);
7225                                 rtw_msleep_os(10);
7226                                 ra_info1 = rtw_read32(padapter, 0x2F0);
7227                                 curr_tx_rate = ra_info1&0x7F;
7228                                 curr_tx_sgi = (ra_info1>>7)&0x01;
7229                                 DBG_8192C("[ ra_info1:0x%08x ] =>cur_tx_rate= %s,cur_sgi:%d, PWRSTS = 0x%02x  \n",
7230                                         ra_info1,                                               
7231                                         HDATA_RATE(curr_tx_rate),
7232                                         curr_tx_sgi,
7233                                         (ra_info1>>8)  & 0x07);
7234
7235                                 cmd = 0x40000400 | mac_id;
7236                                 rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B,cmd);
7237                                 rtw_msleep_os(10);
7238                                 ra_info1 = rtw_read32(padapter, 0x2F0);
7239                                 ra_info2 = rtw_read32(padapter, 0x2F4);
7240                                 rate_mask1 = rtw_read32(padapter, 0x2F8);
7241                                 rate_mask2 = rtw_read32(padapter, 0x2FC);
7242                                 hight_rate = ra_info2&0xFF;
7243                                 lowest_rate = (ra_info2>>8)  & 0xFF;
7244                                         
7245                                 DBG_8192C("[ ra_info1:0x%08x ] =>RSSI=%d, BW_setting=0x%02x, DISRA=0x%02x, VHT_EN=0x%02x\n",
7246                                         ra_info1,
7247                                         ra_info1&0xFF,
7248                                         (ra_info1>>8)  & 0xFF,
7249                                         (ra_info1>>16) & 0xFF,
7250                                         (ra_info1>>24) & 0xFF);
7251                                         
7252                                 DBG_8192C("[ ra_info2:0x%08x ] =>hight_rate=%s, lowest_rate=%s, SGI=0x%02x, RateID=%d\n",
7253                                         ra_info2,
7254                                         HDATA_RATE(hight_rate),
7255                                         HDATA_RATE(lowest_rate),
7256                                         (ra_info2>>16) & 0xFF,
7257                                         (ra_info2>>24) & 0xFF);
7258
7259                                 DBG_8192C("rate_mask2=0x%08x, rate_mask1=0x%08x\n", rate_mask2, rate_mask1);
7260                                 
7261                         }
7262                         break;
7263
7264                 case HAL_DEF_TX_PAGE_BOUNDARY:
7265                         if (!padapter->registrypriv.wifi_spec)
7266                         {
7267                                 *(u8*)pval = TX_PAGE_BOUNDARY_8723B;
7268                         }
7269                         else
7270                         {
7271                                 *(u8*)pval = WMM_NORMAL_TX_PAGE_BOUNDARY_8723B;
7272                         }
7273                         break;
7274
7275                 case HAL_DEF_MACID_SLEEP:
7276                         *(u8*)pval = _TRUE; // support macid sleep
7277                         break;
7278                 case HAL_DEF_TX_PAGE_SIZE:
7279                          *(( u32*)pval) = PAGE_SIZE_128;
7280                         break;
7281                 default:
7282                         bResult = GetHalDefVar(padapter, variable, pval);
7283                         break;
7284         }
7285
7286         return bResult;
7287 }
7288
7289 #ifdef CONFIG_WOWLAN
7290 void Hal_DetectWoWMode(PADAPTER pAdapter)
7291 {
7292         adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = _TRUE;
7293         DBG_871X("%s\n", __func__);
7294 }
7295 #endif //CONFIG_WOWLAN
7296
7297 void rtl8723b_start_thread(_adapter *padapter)
7298 {
7299 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
7300 #ifndef CONFIG_SDIO_TX_TASKLET
7301         struct xmit_priv *xmitpriv = &padapter->xmitpriv;
7302
7303         xmitpriv->SdioXmitThread = kthread_run(rtl8723bs_xmit_thread, padapter, "RTWHALXT");
7304         if (IS_ERR(xmitpriv->SdioXmitThread))
7305         {
7306                 RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: start rtl8723bs_xmit_thread FAIL!!\n", __FUNCTION__));
7307         }
7308 #endif
7309 #endif
7310 }
7311
7312 void rtl8723b_stop_thread(_adapter *padapter)
7313 {
7314 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
7315 #ifndef CONFIG_SDIO_TX_TASKLET
7316         struct xmit_priv *xmitpriv = &padapter->xmitpriv;
7317
7318         // stop xmit_buf_thread
7319         if (xmitpriv->SdioXmitThread ) {
7320                 _rtw_up_sema(&xmitpriv->SdioXmitSema);
7321                 _rtw_down_sema(&xmitpriv->SdioXmitTerminateSema);
7322                 xmitpriv->SdioXmitThread = 0;
7323         }
7324 #endif
7325 #endif
7326 }
7327
7328 #if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
7329 extern void check_bt_status_work(void *data);
7330 void rtl8723bs_init_checkbthang_workqueue(_adapter * adapter)
7331 {
7332 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
7333         adapter->priv_checkbt_wq = alloc_workqueue("sdio_wq", 0, 0);
7334 #else
7335         adapter->priv_checkbt_wq = create_workqueue("sdio_wq");
7336 #endif
7337         INIT_DELAYED_WORK(&adapter->checkbt_work, (void*)check_bt_status_work);
7338 }
7339
7340 void rtl8723bs_free_checkbthang_workqueue(_adapter * adapter)
7341 {
7342         if (adapter->priv_checkbt_wq) {
7343                 cancel_delayed_work_sync(&adapter->checkbt_work);
7344                 flush_workqueue(adapter->priv_checkbt_wq);
7345                 destroy_workqueue(adapter->priv_checkbt_wq);
7346                 adapter->priv_checkbt_wq = NULL;
7347         } 
7348 }
7349
7350 void rtl8723bs_cancle_checkbthang_workqueue(_adapter * adapter)
7351 {
7352         if (adapter->priv_checkbt_wq) {
7353                 cancel_delayed_work_sync(&adapter->checkbt_work);
7354         }
7355 }
7356
7357 void rtl8723bs_hal_check_bt_hang(_adapter * adapter)
7358 {
7359         if (adapter->priv_checkbt_wq)
7360                 queue_delayed_work(adapter->priv_checkbt_wq, &(adapter->checkbt_work), 0);
7361 }
7362 #endif
7363
7364
7365