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