OSDN Git Service

Make certain that if, for, while, do, and switch have a space before an open paren
[android-x86/external-modules-rtl8723au.git] / hal / rtl8723a_hal_init.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _HAL_INIT_C_
21
22 #include <drv_types.h>
23 #include <rtw_byteorder.h>
24 #include <rtw_efuse.h>
25
26 #include <rtl8723a_hal.h>
27 #include "rtw_bt_mp.h"
28
29
30 static void
31 _FWDownloadEnable(
32         IN      PADAPTER                padapter,
33         IN      bool                    enable
34         )
35 {
36         u8      tmp;
37
38         if (enable)
39         {
40                 // 8051 enable
41                 tmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
42                 rtw_write8(padapter, REG_SYS_FUNC_EN+1, tmp|0x04);
43
44                 // MCU firmware download enable.
45                 tmp = rtw_read8(padapter, REG_MCUFWDL);
46                 rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
47
48                 // 8051 reset
49                 tmp = rtw_read8(padapter, REG_MCUFWDL+2);
50                 rtw_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
51         }
52         else
53         {
54                 // MCU firmware download disable.
55                 tmp = rtw_read8(padapter, REG_MCUFWDL);
56                 rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
57
58                 // Reserved for fw extension.
59                 rtw_write8(padapter, REG_MCUFWDL+1, 0x00);
60         }
61 }
62
63 static int
64 _BlockWrite(
65         IN              PADAPTER                padapter,
66         IN              void *          buffer,
67         IN              u32                     buffSize
68         )
69 {
70         int ret = _SUCCESS;
71         u32                     blockSize_p1 = 4;       // (Default) Phase #1 : PCI muse use 4-byte write to download FW
72         u32                     blockSize_p2 = 8;       // Phase #2 : Use 8-byte, if Phase#1 use big size to write FW.
73         u32                     blockSize_p3 = 1;       // Phase #3 : Use 1-byte, the remnant of FW image.
74         u32                     blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
75         u32                     remainSize_p1 = 0, remainSize_p2 = 0;
76         u8                      *bufferPtr      = (u8*)buffer;
77         u32                     i=0, offset=0;
78
79         blockSize_p1 = 254;
80
81         //3 Phase #1
82         blockCount_p1 = buffSize / blockSize_p1;
83         remainSize_p1 = buffSize % blockSize_p1;
84
85         if (blockCount_p1) {
86                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
87                                 ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) blockCount_p1(%d) remainSize_p1(%d)\n",
88                                 buffSize, blockSize_p1, blockCount_p1, remainSize_p1));
89         }
90
91         for (i = 0; i < blockCount_p1; i++)
92         {
93                 ret = rtw_writeN(padapter, (FW_8723A_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
94                 if (ret == _FAIL)
95                         goto exit;
96         }
97
98         //3 Phase #2
99         if (remainSize_p1)
100         {
101                 offset = blockCount_p1 * blockSize_p1;
102
103                 blockCount_p2 = remainSize_p1/blockSize_p2;
104                 remainSize_p2 = remainSize_p1%blockSize_p2;
105
106                 if (blockCount_p2) {
107                                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
108                                                 ("_BlockWrite: [P2] buffSize_p2(%d) blockSize_p2(%d) blockCount_p2(%d) remainSize_p2(%d)\n",
109                                                 (buffSize-offset), blockSize_p2 ,blockCount_p2, remainSize_p2));
110                 }
111
112                 for (i = 0; i < blockCount_p2; i++) {
113                         ret = rtw_writeN(padapter, (FW_8723A_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
114
115                         if (ret == _FAIL)
116                                 goto exit;
117                 }
118         }
119
120         //3 Phase #3
121         if (remainSize_p2)
122         {
123                 offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
124
125                 blockCount_p3 = remainSize_p2 / blockSize_p3;
126
127                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
128                                 ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) blockCount_p3(%d)\n",
129                                 (buffSize-offset), blockSize_p3, blockCount_p3));
130
131                 for (i = 0 ; i < blockCount_p3 ; i++){
132                         ret = rtw_write8(padapter, (FW_8723A_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
133
134                         if (ret == _FAIL)
135                                 goto exit;
136                 }
137         }
138
139 exit:
140         return ret;
141 }
142
143 static int
144 _PageWrite(
145         IN              PADAPTER        padapter,
146         IN              u32                     page,
147         IN              void *          buffer,
148         IN              u32                     size
149         )
150 {
151         u8 value8;
152         u8 u8Page = (u8) (page & 0x07) ;
153
154         value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page ;
155         rtw_write8(padapter, REG_MCUFWDL+2,value8);
156
157         return _BlockWrite(padapter,buffer,size);
158 }
159
160 static void
161 _FillDummy(
162         u8*             pFwBuf,
163         u32*    pFwLen
164         )
165 {
166         u32     FwLen = *pFwLen;
167         u8      remain = (u8)(FwLen%4);
168         remain = (remain==0)?0:(4-remain);
169
170         while (remain>0)
171         {
172                 pFwBuf[FwLen] = 0;
173                 FwLen++;
174                 remain--;
175         }
176
177         *pFwLen = FwLen;
178 }
179
180 static int
181 _WriteFW(
182         IN              PADAPTER                padapter,
183         IN              void *                  buffer,
184         IN              u32                     size
185         )
186 {
187         // Since we need dynamic decide method of dwonload fw, so we call this function to get chip version.
188         // We can remove _ReadChipVersion from ReadpadapterInfo8192C later.
189         int ret = _SUCCESS;
190         u32     pageNums,remainSize ;
191         u32     page, offset;
192         u8              *bufferPtr = (u8*)buffer;
193
194         pageNums = size / MAX_PAGE_SIZE ;
195         //RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4\n"));
196         remainSize = size % MAX_PAGE_SIZE;
197
198         for (page = 0; page < pageNums; page++) {
199                 offset = page * MAX_PAGE_SIZE;
200                 ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_PAGE_SIZE);
201
202                 if (ret == _FAIL)
203                         goto exit;
204         }
205         if (remainSize) {
206                 offset = pageNums * MAX_PAGE_SIZE;
207                 page = pageNums;
208                 ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize);
209
210                 if (ret == _FAIL)
211                         goto exit;
212         }
213         RT_TRACE(_module_hal_init_c_, _drv_info_, ("_WriteFW Done- for Normal chip.\n"));
214
215 exit:
216         return ret;
217 }
218
219 static s32 _FWFreeToGo(PADAPTER padapter)
220 {
221         u32     counter = 0;
222         u32     value32;
223
224         // polling CheckSum report
225         do {
226                 value32 = rtw_read32(padapter, REG_MCUFWDL);
227                 if (value32 & FWDL_ChkSum_rpt) break;
228         } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
229
230         if (counter >= POLLING_READY_TIMEOUT_COUNT) {
231                 RT_TRACE(_module_hal_init_c_, _drv_err_, ("%s: chksum report fail! REG_MCUFWDL:0x%08x\n", __FUNCTION__, value32));
232                 return _FAIL;
233         }
234         RT_TRACE(_module_hal_init_c_, _drv_info_, ("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __FUNCTION__, value32));
235
236         value32 = rtw_read32(padapter, REG_MCUFWDL);
237         value32 |= MCUFWDL_RDY;
238         value32 &= ~WINTINI_RDY;
239         rtw_write32(padapter, REG_MCUFWDL, value32);
240
241         // polling for FW ready
242         counter = 0;
243         do {
244                 value32 = rtw_read32(padapter, REG_MCUFWDL);
245                 if (value32 & WINTINI_RDY) {
246                         RT_TRACE(_module_hal_init_c_, _drv_info_, ("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __FUNCTION__, value32));
247                         return _SUCCESS;
248                 }
249                 rtw_udelay_os(5);
250         } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
251
252         RT_TRACE(_module_hal_init_c_, _drv_err_, ("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", __FUNCTION__, value32));
253         return _FAIL;
254 }
255
256 #define IS_FW_81xxC(padapter)   (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
257
258 void rtl8723a_FirmwareSelfReset(PADAPTER padapter)
259 {
260         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
261         u8      u1bTmp;
262         u8      Delay = 100;
263
264
265         if (!(IS_FW_81xxC(padapter) &&
266                   ((pHalData->FirmwareVersion < 0x21) ||
267                    (pHalData->FirmwareVersion == 0x21 &&
268                     pHalData->FirmwareSubVersion < 0x01)))) // after 88C Fw v33.1
269         {
270                 //0x1cf=0x20. Inform 8051 to reset. 2009.12.25. tynli_test
271                 rtw_write8(padapter, REG_HMETFR+3, 0x20);
272
273                 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
274                 while (u1bTmp & BIT2)
275                 {
276                         Delay--;
277                         if (Delay == 0)
278                                 break;
279                         rtw_udelay_os(50);
280                         u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
281                 }
282                 RT_TRACE(_module_hal_init_c_, _drv_info_, ("-%s: 8051 reset success (%d)\n", __FUNCTION__, Delay));
283
284                 if ((Delay == 0) && IS_HARDWARE_TYPE_8723AU(padapter))
285                 {
286                         //force firmware reset
287                         u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
288                         rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
289                 }
290         }
291 }
292
293 //
294 #ifdef CONFIG_MP_INCLUDED
295
296 int _WriteBTFWtoTxPktBuf8723A(
297         IN              PADAPTER                Adapter,
298         IN              void *                  buffer,
299         IN              u4Byte                  FwBufLen
300         )
301 {
302         int                     rtStatus = _SUCCESS;
303         //u4Byte                                value32;
304         //u1Byte                                numHQ, numLQ, numPubQ;//, txpktbuf_bndy;
305         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(Adapter);
306         //PMGNT_INFO            pMgntInfo = &(Adapter->MgntInfo);
307         u1Byte                          BcnValidReg;
308         u1Byte                          count=0, DLBcnCount=0;
309         pu1Byte                         FwbufferPtr = (pu1Byte)buffer;
310         //PRT_TCB                       pTcb, ptempTcb;
311         //PRT_TX_LOCAL_BUFFER pBuf;
312         bool                            bRecover=false;
313         pu1Byte                         ReservedPagePacket = NULL;
314         pu1Byte                         pGenBufReservedPagePacket = NULL;
315         u4Byte                          TotalPktLen;
316         //u1Byte                                tmpReg422;
317         //u1Byte                                u1bTmp;
318         u8                      *pframe;
319         struct xmit_priv        *pxmitpriv = &(Adapter->xmitpriv);
320         struct xmit_frame       *pmgntframe;
321         struct pkt_attrib       *pattrib;
322
323 #if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
324         TotalPktLen = FwBufLen;
325 #else
326         TotalPktLen = FwBufLen+pHalData->HWDescHeadLength;
327 #endif
328         pGenBufReservedPagePacket = rtw_zmalloc(TotalPktLen);//GetGenTempBuffer (Adapter, TotalPktLen);
329         if (!pGenBufReservedPagePacket)
330                 return _FAIL;
331
332         ReservedPagePacket = (u1Byte *)pGenBufReservedPagePacket;
333
334         memset(ReservedPagePacket, 0, TotalPktLen);
335
336 #if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
337         memcpy(ReservedPagePacket, FwbufferPtr, FwBufLen);
338
339 #else
340         PlatformMoveMemory(ReservedPagePacket+Adapter->HWDescHeadLength , FwbufferPtr, FwBufLen);
341 #endif
342
343         //---------------------------------------------------------
344         // 1. Pause BCN
345         //---------------------------------------------------------
346         //Set REG_CR bit 8. DMA beacon by SW.
347         // Remove for temparaily because of the code on v2002 is not sync to MERGE_TMEP for USB/SDIO.
348         // De not remove this part on MERGE_TEMP. by tynli.
349         //pHalData->RegCR_1 |= (BIT0);
350         //PlatformEFIOWrite1Byte(Adapter,  REG_CR+1, pHalData->RegCR_1);
351
352         // Disable Hw protection for a time which revserd for Hw sending beacon.
353         // Fix download reserved page packet fail that access collision with the protection time.
354         // 2010.05.11. Added by tynli.
355         SetBcnCtrlReg(Adapter, 0, BIT(3));
356         SetBcnCtrlReg(Adapter, BIT(4), 0);
357
358         // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
359         if (pHalData->RegFwHwTxQCtrl & BIT(6))
360                 bRecover=true;
361         PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl&( ~BIT(6))));
362         pHalData->RegFwHwTxQCtrl &= (~BIT(6));
363
364         //---------------------------------------------------------
365         // 2. Adjust LLT table to an even boundary.
366         //---------------------------------------------------------
367
368         //---------------------------------------------------------
369         // 3. Write Fw to Tx packet buffer by reseverd page.
370         //---------------------------------------------------------
371         do
372         {
373                 // download rsvd page.
374                 // Clear beacon valid check bit.
375                 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
376                 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+2, BcnValidReg&(~BIT(0)));
377
378                 //BT patch is big, we should set 0x209 < 0x40 suggested from Gimmy
379                 RT_TRACE(_module_mp_, _drv_info_,("0x209:%x\n",
380                                         PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1)));//209 < 0x40
381                 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+1, 0x30);
382                 RT_TRACE(_module_mp_, _drv_info_,("0x209:%x\n",
383                                         PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1)));
384
385                 /*---------------------------------------------------------
386                 tx reserved_page_packet
387                 ----------------------------------------------------------*/
388                         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) {
389                                                 rtStatus = _FAIL;
390                                                 goto exit;
391                         }
392                         //update attribute
393                         pattrib = &pmgntframe->attrib;
394                         update_mgntframe_attrib(Adapter, pattrib);
395
396                         pattrib->qsel = QSLT_BEACON;
397                         pattrib->pktlen = pattrib->last_txcmdsz = FwBufLen ;
398
399                         //memset(pmgntframe->buf_addr, 0, TotalPktLen+TXDESC_SIZE);
400                         //pmgntframe->buf_addr = ReservedPagePacket ;
401
402                         memcpy( (u8*) (pmgntframe->buf_addr + TXDESC_OFFSET), ReservedPagePacket, FwBufLen);
403                         DBG_871X("===>TotalPktLen + TXDESC_OFFSET TotalPacketLen:%d ", (FwBufLen + TXDESC_OFFSET));
404
405                         dump_mgntframe(Adapter, pmgntframe);
406
407                 // check rsvd page download OK.
408                 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
409                 while (!(BcnValidReg & BIT(0)) && count <200)
410                 {
411                         count++;
412                         //PlatformSleepUs(10);
413                         rtw_msleep_os(1);
414                         BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
415                         RT_TRACE(_module_mp_, _drv_info_,("Poll 0x20A = %x\n", BcnValidReg));
416                 }
417                 DLBcnCount++;
418                 DBG_871X("##0x208:%08x,0x210=%08x\n",PlatformEFIORead4Byte(Adapter, REG_TDECTRL),PlatformEFIORead4Byte(Adapter, 0x210));
419         }while ((!(BcnValidReg&BIT(0))) && DLBcnCount<5);
420
421
422         if (DLBcnCount >=5){
423                 DBG_871X(" check rsvd page download OK DLBcnCount =%d \n",DLBcnCount);
424                 rtStatus = _FAIL;
425                 goto exit;
426         }
427
428         if (!(BcnValidReg&BIT(0)))
429         {
430                 DBG_871X("_WriteFWtoTxPktBuf(): 1 Download RSVD page failed!\n");
431                 rtStatus = _FAIL;
432                 goto exit;
433         }
434
435         //---------------------------------------------------------
436         // 4. Set Tx boundary to the initial value
437         //---------------------------------------------------------
438
439
440         //---------------------------------------------------------
441         // 5. Reset beacon setting to the initial value.
442         //       After _CheckWLANFwPatchBTFwReady().
443         //---------------------------------------------------------
444
445 exit:
446
447         if (pGenBufReservedPagePacket)
448         {
449                 DBG_871X("_WriteBTFWtoTxPktBuf8723A => rtw_mfree pGenBufReservedPagePacket!\n");
450                 rtw_mfree((u8*)pGenBufReservedPagePacket, TotalPktLen);
451                 }
452         return rtStatus;
453 }
454
455
456 extern s32 FillH2CCmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer);
457
458 //
459 // Description: Determine the contents of H2C BT_FW_PATCH Command sent to FW.
460 // 2011.10.20 by tynli
461 //
462 void
463 SetFwBTFwPatchCmd(
464         IN PADAPTER     Adapter,
465         IN u2Byte               FwSize
466         )
467 {
468         u1Byte          u1BTFwPatchParm[H2C_BT_FW_PATCH_LEN]={0};
469
470         RT_TRACE(_module_mp_, _drv_notice_,("SetFwBTFwPatchCmd(): FwSize = %d\n", FwSize));
471
472         //bit1: 1---24k, 0----16k
473         //SET_H2CCMD_BT_FW_PATCH_ENABLE(u1BTFwPatchParm, 0x03);
474
475         SET_H2CCMD_BT_FW_PATCH_ENABLE(u1BTFwPatchParm, 1);
476
477         SET_H2CCMD_BT_FW_PATCH_SIZE(u1BTFwPatchParm, FwSize);
478
479         u1BTFwPatchParm[0]  |= BIT1;
480
481         FillH2CCmd(Adapter, H2C_BT_FW_PATCH, H2C_BT_FW_PATCH_LEN, u1BTFwPatchParm);
482
483         RT_TRACE(_module_mp_, _drv_notice_,("<----SetFwBTFwPatchCmd(): FwSize = %d\n", FwSize));
484 }
485
486 void
487 SetFwBTPwrCmd(
488         IN PADAPTER     Adapter,
489         IN u1Byte       PwrIdx
490         )
491 {
492         u1Byte          u1BTPwrIdxParm[H2C_BT_PWR_FORCE_LEN]={0};
493
494         RT_TRACE(_module_mp_, _drv_info_,("SetFwBTPwrCmd(): idx = %d\n", PwrIdx));
495         SET_H2CCMD_BT_PWR_IDX(u1BTPwrIdxParm, PwrIdx);
496
497         RT_TRACE(_module_mp_, _drv_info_,("SetFwBTPwrCmd(): %x %x %x\n",
498                 u1BTPwrIdxParm[0],u1BTPwrIdxParm[1],u1BTPwrIdxParm[2]));
499
500         FillH2CCmd(Adapter, FORCE_BT_TX_PWR_EID, H2C_BT_PWR_FORCE_LEN, u1BTPwrIdxParm);
501 }
502
503 //
504 // Description: WLAN Fw will write BT Fw to BT XRAM and signal driver.
505 //
506 // 2011.10.20. by tynli.
507 //
508 void
509 _CheckWLANFwPatchBTFwReady(
510         IN      PADAPTER                        Adapter
511 )
512 {
513         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
514         u4Byte  count=0;
515         u1Byte  u1bTmp;
516
517         //---------------------------------------------------------
518         // Check if BT FW patch procedure is ready.
519         //---------------------------------------------------------
520         do{
521                 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_MCUFWDL+1);
522                 if (u1bTmp&BIT(7))
523                         break;
524
525                 count++;
526                 RT_TRACE(_module_mp_, _drv_info_,("0x81=%x, wait for 50 ms (%d) times.\n",
527                                         u1bTmp, count));
528                 rtw_msleep_os(50); // 50ms
529         }while (!(u1bTmp&BIT(7)) && count < 50);
530
531         RT_TRACE(_module_mp_, _drv_notice_,("_CheckWLANFwPatchBTFwReady():"
532                                 " Polling ready bit 0x81[7] for %d times.\n", count));
533
534         if (count >= 50)
535         {
536                 RT_TRACE(_module_mp_, _drv_notice_,("_CheckWLANFwPatchBTFwReady():"
537                                 " Polling ready bit 0x81[7] FAIL!!\n"));
538         }
539
540         //---------------------------------------------------------
541         // Reset beacon setting to the initial value.
542         //---------------------------------------------------------
543         SetBcnCtrlReg(Adapter, BIT(3), 0);
544         SetBcnCtrlReg(Adapter, 0, BIT(4));
545
546         // To make sure that if there exists an adapter which would like to send beacon.
547         // If exists, the origianl value of 0x422[6] will be 1, we should check this to
548         // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
549         // the beacon cannot be sent by HW.
550         // 2010.06.23. Added by tynli.
551         PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl|BIT(6)));
552         pHalData->RegFwHwTxQCtrl |= BIT(6);
553
554 }
555
556 int
557 FirmwareDownloadBT(IN PADAPTER Adapter, PRT_FIRMWARE_8723A pFirmware)
558 {
559         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(Adapter);
560         int rtStatus = _SUCCESS;
561
562         // BT pacth
563         u1Byte          *BTFwImage;
564         u4Byte          BTFwImageLen;
565
566         u1Byte          *pBTFirmwareBuf;
567         u4Byte          BTFirmwareLen;
568         //
569         // Patch BT Fw. Download BT RAM code to Tx packet buffer. Added by tynli. 2011.10.
570         // Only for 8723AE for Toshiba. Suggested by SD1 Jackie.
571         //
572         if ( !(IS_HARDWARE_TYPE_8723A(Adapter)) && IS_8723A_B_CUT(pHalData->VersionID))
573                         return _FAIL ; //&& (Adapter->registrypriv.bBtFwSupport)))
574
575         if (Adapter->bBTFWReady){
576                 DBG_871X("BT Firmware is ready!!\n");
577                 return _FAIL;
578         }
579         BTFwImage = (pu1Byte)Rtl8723EFwBTImgArray;
580         BTFwImageLen = Rtl8723EBTImgArrayLength;
581                 DBG_871X("BT Firmware is size= %zu!!\n",sizeof(Rtl8723EFwBTImgArray));
582
583         // Download BT patch Fw.
584         RT_TRACE(_module_mp_, _drv_info_,("Download BT Fw (patch version) from header.\n"));
585         DBG_871X("Download BT Fw (patch version) from header.\n");
586
587 #ifdef CONFIG_EMBEDDED_FWIMG
588                 pFirmware->szBTFwBuffer = BTFwImage;
589                 DBG_871X("CONFIG_EMBEDDED_FWIMG pFirmware->szBTFwBuffer = BTFwImage;\n");
590 #else
591                 DBG_871X("memcpy BTFwImage to pFirmware->szBTFwBuffer.\n");
592                 memcpy(pFirmware->szBTFwBuffer, (void *)BTFwImage, BTFwImageLen);
593 #endif
594         pFirmware->ulBTFwLength = BTFwImageLen;
595                 RT_TRACE(_module_mp_, _drv_notice_,("Download BT Fw (patch version) from header "
596                         "pFirmware->ulBTFwLength:%d.\n", pFirmware->ulBTFwLength));
597
598         // BT FW
599         pBTFirmwareBuf = pFirmware->szBTFwBuffer;
600         BTFirmwareLen = pFirmware->ulBTFwLength;
601
602         //for h2c cam here should be set to  true
603         Adapter->bFWReady = true;
604         DBG_871X("FirmwareDownloadBT to _WriteBTFWtoTxPktBuf8723A !\n");
605         rtStatus = _WriteBTFWtoTxPktBuf8723A(Adapter, pBTFirmwareBuf, BTFirmwareLen);
606         if (rtStatus != _SUCCESS) {
607                 RT_TRACE(_module_mp_, _drv_info_,("BT Firmware download to Tx packet buffer fail!\n"));
608                 DBG_871X("BT Firmware download to Tx packet buffer fail!\n");
609         } else {
610                 Adapter->bBTFWReady = true;
611                 SetFwBTFwPatchCmd(Adapter, (u2Byte)BTFirmwareLen);
612                 _CheckWLANFwPatchBTFwReady(Adapter);
613         }
614         DBG_871X("<===FirmwareDownloadBT(),return %s!\n",rtStatus?"SUCCESS":"FAIL");
615         return rtStatus;
616 }
617
618 #endif
619
620 #ifdef CONFIG_FILE_FWIMG
621 extern char *rtw_fw_file_path;
622 u8      fw_buffer_8723a[FW_8723A_SIZE];
623 #endif //CONFIG_FILE_FWIMG
624 //
625 //      Description:
626 //              Download 8192C firmware code.
627 //
628 //
629 s32 rtl8723a_FirmwareDownload(PADAPTER padapter)
630 {
631         s32     rtStatus = _SUCCESS;
632         u8 writeFW_retry = 0;
633         u32 fwdl_start_time;
634         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
635         s8                      R8723FwImageFileName_UMC[] ={RTL8723_FW_UMC_IMG};
636         s8                      R8723FwImageFileName_UMC_B[] ={RTL8723_FW_UMC_B_IMG};
637         u8                      *FwImage;
638         u32                     FwImageLen;
639         u8                      *pFwImageFileName;
640         u8                      *pucMappedFile = NULL;
641         PRT_FIRMWARE_8723A      pFirmware = NULL;
642         PRT_FIRMWARE_8723A      pBTFirmware = NULL;
643         PRT_8723A_FIRMWARE_HDR          pFwHdr = NULL;
644         u8                      *pFirmwareBuf;
645         u32                     FirmwareLen;
646
647
648         RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __FUNCTION__));
649         pFirmware = (PRT_FIRMWARE_8723A)rtw_zmalloc(sizeof(RT_FIRMWARE_8723A));
650         pBTFirmware = (PRT_FIRMWARE_8723A)rtw_zmalloc(sizeof(RT_FIRMWARE_8723A));
651
652         if (!pFirmware||!pBTFirmware)
653         {
654                 rtStatus = _FAIL;
655                 goto Exit;
656         }
657
658         if (IS_HARDWARE_TYPE_8723A(padapter))
659         {
660                 if (IS_8723A_A_CUT(pHalData->VersionID))
661                 {
662                         pFwImageFileName = R8723FwImageFileName_UMC;
663                         FwImage = (u8*)Rtl8723_FwImageArray;
664                         FwImageLen = Rtl8723_ImgArrayLength;
665                         RT_TRACE(_module_hal_init_c_, _drv_info_, ("rtl8723a_FirmwareDownload: R8723FwImageArray_UMC for RTL8723A A CUT\n"));
666                 }
667                 else if (IS_8723A_B_CUT(pHalData->VersionID))
668                 {
669                         if (padapter->registrypriv.mp_mode == 1)
670                         {
671                         FwImage = (u8*)Rtl8723_FwUMCBCutMPImageArray;
672                         FwImageLen = Rtl8723_UMCBCutMPImgArrayLength;
673                         DBG_871X(" Rtl8723_FwUMCBCutMPImageArray for RTL8723A B CUT\n");
674                         }
675                         else
676                         {
677                         // WLAN Fw.
678                         FwImage = (u8*)Rtl8723_FwUMCBCutImageArray;
679                         FwImageLen = Rtl8723_UMCBCutImgArrayLength;
680                         DBG_871X(" Rtl8723_FwUMCBCutImageArray for RTL8723A B CUT\n");
681                         }
682                         pFwImageFileName = R8723FwImageFileName_UMC_B;
683                 }
684                 else
685                 {
686                         // <Roger_TODO> We should download proper RAM Code here  to match the ROM code.
687                         RT_TRACE(_module_hal_init_c_, _drv_err_, ("%s: unknow version!\n", __FUNCTION__));
688 //                      return RT_STATUS_FAILURE;
689                         rtStatus = _FAIL;
690                         goto Exit;
691                 }
692         }
693         else
694         {
695                 RT_TRACE(_module_hal_init_c_, _drv_err_, ("%s: unknow chip!\n", __FUNCTION__));
696                 rtStatus = _FAIL;
697                 goto Exit;
698         }
699
700 //      RT_TRACE(_module_hal_init_c_, _drv_err_, ("rtl8723a_FirmwareDownload: %s\n", pFwImageFileName));
701
702         #ifdef CONFIG_FILE_FWIMG
703         if (rtw_is_file_readable(rtw_fw_file_path) == true)
704         {
705                 DBG_871X("%s accquire FW from file:%s\n", __FUNCTION__, rtw_fw_file_path);
706                 pFirmware->eFWSource = FW_SOURCE_IMG_FILE; // We should decided by Reg.
707         }
708         else
709         #endif //CONFIG_FILE_FWIMG
710         {
711                 DBG_871X("%s accquire FW from embedded image\n", __FUNCTION__);
712                 pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
713         }
714
715         switch (pFirmware->eFWSource)
716         {
717                 case FW_SOURCE_IMG_FILE:
718                         #ifdef CONFIG_FILE_FWIMG
719                         rtStatus = rtw_retrive_from_file(rtw_fw_file_path, fw_buffer_8723a, FW_8723A_SIZE);
720                         pFirmware->ulFwLength = rtStatus>=0?rtStatus:0;
721                         pFirmware->szFwBuffer = fw_buffer_8723a;
722                         #endif //CONFIG_FILE_FWIMG
723
724                         if (pFirmware->ulFwLength <= 0)
725                         {
726                                 rtStatus = _FAIL;
727                                 goto Exit;
728                         }
729                         break;
730                 case FW_SOURCE_HEADER_FILE:
731                         if (FwImageLen > FW_8723A_SIZE) {
732                                 rtStatus = _FAIL;
733                                 RT_TRACE(_module_hal_init_c_, _drv_err_, ("Firmware size exceed 0x%X. Check it.\n", FW_8723A_SIZE) );
734                                 goto Exit;
735                         }
736
737                         pFirmware->szFwBuffer = FwImage;
738                         pFirmware->ulFwLength = FwImageLen;
739                         break;
740         }
741
742         #ifdef DBG_FW_STORE_FILE_PATH //used to store firmware to file...
743         if (pFirmware->ulFwLength > 0)
744         {
745                 rtw_store_to_file(DBG_FW_STORE_FILE_PATH, pFirmware->szFwBuffer, pFirmware->ulFwLength);
746         }
747         #endif
748
749         pFirmwareBuf = pFirmware->szFwBuffer;
750         FirmwareLen = pFirmware->ulFwLength;
751
752         // To Check Fw header. Added by tynli. 2009.12.04.
753         pFwHdr = (PRT_8723A_FIRMWARE_HDR)pFirmware->szFwBuffer;
754
755         pHalData->FirmwareVersion =  le16_to_cpu(pFwHdr->Version);
756         pHalData->FirmwareSubVersion = pFwHdr->Subversion;
757         pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
758
759         DBG_871X("%s: fw_ver=%d fw_subver=%d sig=0x%x\n",
760                   __FUNCTION__, pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
761
762         if (IS_FW_HEADER_EXIST(pFwHdr))
763         {
764                 // Shift 32 bytes for FW header
765                 pFirmwareBuf = pFirmwareBuf + 32;
766                 FirmwareLen = FirmwareLen - 32;
767         }
768
769         // Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself,
770         // or it will cause download Fw fail. 2010.02.01. by tynli.
771         if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) //8051 RAM code
772         {
773                 rtl8723a_FirmwareSelfReset(padapter);
774                 rtw_write8(padapter, REG_MCUFWDL, 0x00);
775         }
776
777         _FWDownloadEnable(padapter, true);
778         fwdl_start_time = rtw_get_current_time();
779         while (1) {
780                 //reset the FWDL chksum
781                 rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL)|FWDL_ChkSum_rpt);
782
783                 rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
784
785                 if (rtStatus == _SUCCESS
786                         ||(rtw_get_passing_time_ms(fwdl_start_time) > 500 && writeFW_retry++ >= 3)
787                 )
788                         break;
789
790                 DBG_871X("%s writeFW_retry:%u, time after fwdl_start_time:%ums\n", __FUNCTION__
791                         , writeFW_retry
792                         , rtw_get_passing_time_ms(fwdl_start_time)
793                 );
794         }
795         _FWDownloadEnable(padapter, false);
796         if (_SUCCESS != rtStatus){
797                 DBG_871X("DL Firmware failed!\n");
798                 goto Exit;
799         }
800
801         rtStatus = _FWFreeToGo(padapter);
802         if (_SUCCESS != rtStatus) {
803                 RT_TRACE(_module_hal_init_c_, _drv_err_, ("DL Firmware failed!\n"));
804                 goto Exit;
805         }
806         RT_TRACE(_module_hal_init_c_, _drv_info_, ("Firmware is ready to run!\n"));
807
808 #ifdef CONFIG_MP_INCLUDED//BT_MP
809         if (padapter->registrypriv.mp_mode == 1)
810         {
811                 DBG_871X("rtl8723a_FirmwareDownload go to FirmwareDownloadBT !\n");
812                 FirmwareDownloadBT(padapter, pBTFirmware);
813         }
814 #endif
815
816 Exit:
817         DBG_871X("rtl8723a_FirmwareDownload Exit rtw_mfree pFirmware !\n");
818         if (pFirmware)
819                 rtw_mfree((u8*)pFirmware, sizeof(RT_FIRMWARE_8723A));
820         DBG_871X("rtl8723a_FirmwareDownload Exit rtw_mfree pBTFirmware !\n");
821         if (pBTFirmware)
822                 rtw_mfree((u8*)pBTFirmware, sizeof(RT_FIRMWARE_8723A));
823         //RT_TRACE(COMP_INIT, DBG_LOUD, (" <=== FirmwareDownload91C()\n"));
824         return rtStatus;
825 }
826
827 void rtl8723a_InitializeFirmwareVars(PADAPTER padapter)
828 {
829         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
830
831         // Init Fw LPS related.
832         padapter->pwrctrlpriv.bFwCurrentInPSMode = false;
833
834         // Init H2C counter. by tynli. 2009.12.09.
835         pHalData->LastHMEBoxNum = 0;
836 //      pHalData->H2CQueueHead = 0;
837 //      pHalData->H2CQueueTail = 0;
838 //      pHalData->H2CStopInsertQueue = false;
839 }
840
841 static void rtl8723a_free_hal_data(PADAPTER padapter)
842 {
843 _func_enter_;
844         if (padapter->HalData) {
845                 rtw_mfree(padapter->HalData, sizeof(HAL_DATA_TYPE));
846                 padapter->HalData = NULL;
847         }
848 _func_exit_;
849 }
850
851 //===========================================================
852 //                              Efuse related code
853 //===========================================================
854 static u8
855 hal_EfuseSwitchToBank(
856         PADAPTER        padapter,
857         u8                      bank,
858         u8                      bPseudoTest)
859 {
860         u8 bRet = false;
861         u32 value32 = 0;
862 #ifdef HAL_EFUSE_MEMORY
863         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
864         PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
865 #endif
866
867
868         DBG_8192C("%s: Efuse switch bank to %d\n", __FUNCTION__, bank);
869         if (bPseudoTest)
870         {
871 #ifdef HAL_EFUSE_MEMORY
872                 pEfuseHal->fakeEfuseBank = bank;
873 #else
874                 fakeEfuseBank = bank;
875 #endif
876                 bRet = true;
877         }
878         else
879         {
880                 value32 = rtw_read32(padapter, EFUSE_TEST);
881                 bRet = true;
882                 switch (bank)
883                 {
884                         case 0:
885                                 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
886                                 break;
887                         case 1:
888                                 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
889                                 break;
890                         case 2:
891                                 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
892                                 break;
893                         case 3:
894                                 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
895                                 break;
896                         default:
897                                 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
898                                 bRet = false;
899                                 break;
900                 }
901                 rtw_write32(padapter, EFUSE_TEST, value32);
902         }
903
904         return bRet;
905 }
906
907 static void
908 Hal_GetEfuseDefinition(
909         PADAPTER        padapter,
910         u8                      efuseType,
911         u8                      type,
912         void            *pOut,
913         bool                    bPseudoTest)
914 {
915         switch (type)
916         {
917                 case TYPE_EFUSE_MAX_SECTION:
918                         {
919                                 u8 *pMax_section;
920                                 pMax_section = (u8*)pOut;
921
922                                 if (efuseType == EFUSE_WIFI)
923                                         *pMax_section = EFUSE_MAX_SECTION_8723A;
924                                 else
925                                         *pMax_section = EFUSE_BT_MAX_SECTION;
926                         }
927                         break;
928
929                 case TYPE_EFUSE_REAL_CONTENT_LEN:
930                         {
931                                 u16 *pu2Tmp;
932                                 pu2Tmp = (u16*)pOut;
933
934                                 if (efuseType == EFUSE_WIFI)
935                                         *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
936                                 else
937                                         *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
938                         }
939                         break;
940
941                 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
942                         {
943                                 u16     *pu2Tmp;
944                                 pu2Tmp = (u16*)pOut;
945
946                                 if (efuseType == EFUSE_WIFI)
947                                         *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A-EFUSE_OOB_PROTECT_BYTES);
948                                 else
949                                         *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN-EFUSE_PROTECT_BYTES_BANK);
950                         }
951                         break;
952
953                 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
954                         {
955                                 u16 *pu2Tmp;
956                                 pu2Tmp = (u16*)pOut;
957
958                                 if (efuseType == EFUSE_WIFI)
959                                         *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A-EFUSE_OOB_PROTECT_BYTES);
960                                 else
961                                         *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN-(EFUSE_PROTECT_BYTES_BANK*3));
962                         }
963                         break;
964
965                 case TYPE_EFUSE_MAP_LEN:
966                         {
967                                 u16 *pu2Tmp;
968                                 pu2Tmp = (u16*)pOut;
969
970                                 if (efuseType == EFUSE_WIFI)
971                                         *pu2Tmp = EFUSE_MAP_LEN_8723A;
972                                 else
973                                         *pu2Tmp = EFUSE_BT_MAP_LEN;
974                         }
975                         break;
976
977                 case TYPE_EFUSE_PROTECT_BYTES_BANK:
978                         {
979                                 u8 *pu1Tmp;
980                                 pu1Tmp = (u8*)pOut;
981
982                                 if (efuseType == EFUSE_WIFI)
983                                         *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
984                                 else
985                                         *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
986                         }
987                         break;
988
989                 case TYPE_EFUSE_CONTENT_LEN_BANK:
990                         {
991                                 u16 *pu2Tmp;
992                                 pu2Tmp = (u16*)pOut;
993
994                                 if (efuseType == EFUSE_WIFI)
995                                         *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
996                                 else
997                                         *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
998                         }
999                         break;
1000
1001                 default:
1002                         {
1003                                 u8 *pu1Tmp;
1004                                 pu1Tmp = (u8*)pOut;
1005                                 *pu1Tmp = 0;
1006                         }
1007                         break;
1008         }
1009 }
1010
1011 #define VOLTAGE_V25             0x03
1012 #define LDOE25_SHIFT    28
1013
1014 static void
1015 Hal_EfusePowerSwitch(
1016         PADAPTER        padapter,
1017         u8                      bWrite,
1018         u8                      PwrState)
1019 {
1020         u8      tempval;
1021         u16     tmpV16;
1022
1023         if (PwrState == true)
1024         {
1025                 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
1026
1027                 // 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid
1028                 tmpV16 = rtw_read16(padapter, REG_SYS_ISO_CTRL);
1029                 if (!(tmpV16 & PWC_EV12V)) {
1030                         tmpV16 |= PWC_EV12V ;
1031                         rtw_write16(padapter, REG_SYS_ISO_CTRL, tmpV16);
1032                 }
1033                 // Reset: 0x0000h[28], default valid
1034                 tmpV16 =  rtw_read16(padapter, REG_SYS_FUNC_EN);
1035                 if (!(tmpV16 & FEN_ELDR)) {
1036                         tmpV16 |= FEN_ELDR ;
1037                         rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
1038                 }
1039
1040                 // Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid
1041                 tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
1042                 if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
1043                         tmpV16 |= (LOADER_CLK_EN | ANA8M) ;
1044                         rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
1045                 }
1046
1047                 if (bWrite == true)
1048                 {
1049                         // Enable LDO 2.5V before read/write action
1050                         tempval = rtw_read8(padapter, EFUSE_TEST+3);
1051                         tempval &= 0x0F;
1052                         tempval |= (VOLTAGE_V25 << 4);
1053                         rtw_write8(padapter, EFUSE_TEST+3, (tempval | 0x80));
1054                 }
1055         }
1056         else
1057         {
1058                 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
1059
1060                 if (bWrite == true) {
1061                         // Disable LDO 2.5V after read/write action
1062                         tempval = rtw_read8(padapter, EFUSE_TEST+3);
1063                         rtw_write8(padapter, EFUSE_TEST+3, (tempval & 0x7F));
1064                 }
1065         }
1066 }
1067
1068 static void
1069 hal_ReadEFuse_WiFi(
1070         PADAPTER        padapter,
1071         u16                     _offset,
1072         u16                     _size_byte,
1073         u8                      *pbuf,
1074         bool                    bPseudoTest)
1075 {
1076 #ifdef HAL_EFUSE_MEMORY
1077         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
1078         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
1079 #endif
1080         u8      *efuseTbl = NULL;
1081         u16     eFuse_Addr=0;
1082         u8      offset, wden;
1083         u8      efuseHeader, efuseExtHdr, efuseData;
1084         u16     i, total, used;
1085         u8      efuse_usage = 0;
1086
1087
1088         //
1089         // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
1090         //
1091         if ((_offset+_size_byte) > EFUSE_MAP_LEN_8723A)
1092         {
1093                 DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1094                 return;
1095         }
1096
1097         efuseTbl = (u8*)rtw_malloc(EFUSE_MAP_LEN_8723A);
1098         if (efuseTbl == NULL)
1099         {
1100                 DBG_8192C("%s: alloc efuseTbl fail!\n", __FUNCTION__);
1101                 return;
1102         }
1103         // 0xff will be efuse default value instead of 0x00.
1104         memset(efuseTbl, 0xFF, EFUSE_MAP_LEN_8723A);
1105
1106         // switch bank back to bank 0 for later BT and wifi use.
1107         hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1108
1109         while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
1110         {
1111                 ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1112                 if (efuseHeader == 0xFF)
1113                 {
1114                         DBG_8192C("%s: data end at address=%#x\n", __FUNCTION__, eFuse_Addr);
1115                         break;
1116                 }
1117 //              DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseHeader);
1118
1119                 // Check PG header for section num.
1120                 if (EXT_HEADER(efuseHeader))            //extended header
1121                 {
1122                         offset = GET_HDR_OFFSET_2_0(efuseHeader);
1123 //                      DBG_8192C("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset_2_0);
1124
1125                         ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1126 //                      DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseExtHdr);
1127                         if (ALL_WORDS_DISABLED(efuseExtHdr))
1128                         {
1129                                 continue;
1130                         }
1131
1132                         offset |= ((efuseExtHdr & 0xF0) >> 1);
1133                         wden = (efuseExtHdr & 0x0F);
1134                 }
1135                 else
1136                 {
1137                         offset = ((efuseHeader >> 4) & 0x0f);
1138                         wden = (efuseHeader & 0x0f);
1139                 }
1140
1141                 if (offset < EFUSE_MAX_SECTION_8723A)
1142                 {
1143                         u16 addr;
1144                         // Get word enable value from PG header
1145 //                      DBG_8192C("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden);
1146
1147                         addr = offset * PGPKT_DATA_SIZE;
1148                         for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1149                         {
1150                                 // Check word enable condition in the section
1151                                 if (!(wden & (0x01<<i)))
1152                                 {
1153                                         ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1154 //                                      DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1155                                         efuseTbl[addr] = efuseData;
1156
1157                                         ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1158 //                                      DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1159                                         efuseTbl[addr+1] = efuseData;
1160                                 }
1161                                 addr += 2;
1162                         }
1163                 }
1164                 else
1165                 {
1166                         DBG_8192C(KERN_ERR "%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1167                         eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
1168                 }
1169         }
1170
1171         // Copy from Efuse map to output pointer memory!!!
1172         for (i=0; i<_size_byte; i++)
1173                 pbuf[i] = efuseTbl[_offset+i];
1174
1175         // Calculate Efuse utilization
1176         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1177         used = eFuse_Addr - 1;
1178         efuse_usage = (u8)((used*100)/total);
1179         if (bPseudoTest)
1180         {
1181 #ifdef HAL_EFUSE_MEMORY
1182                 pEfuseHal->fakeEfuseUsedBytes = used;
1183 #else
1184                 fakeEfuseUsedBytes = used;
1185 #endif
1186         }
1187         else
1188         {
1189                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&used);
1190                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8*)&efuse_usage);
1191         }
1192
1193         if (efuseTbl)
1194                 rtw_mfree(efuseTbl, EFUSE_MAP_LEN_8723A);
1195 }
1196
1197 static void
1198 hal_ReadEFuse_BT(
1199         PADAPTER        padapter,
1200         u16                     _offset,
1201         u16                     _size_byte,
1202         u8                      *pbuf,
1203         u8                      bPseudoTest
1204         )
1205 {
1206 #ifdef HAL_EFUSE_MEMORY
1207         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
1208         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
1209 #endif
1210         u8      *efuseTbl;
1211         u8      bank;
1212         u16     eFuse_Addr;
1213         u8      efuseHeader, efuseExtHdr, efuseData;
1214         u8      offset, wden;
1215         u16     i, total, used;
1216         u8      efuse_usage;
1217
1218
1219         //
1220         // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
1221         //
1222         if ((_offset+_size_byte) > EFUSE_BT_MAP_LEN)
1223         {
1224                 DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1225                 return;
1226         }
1227
1228         efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);
1229         if (efuseTbl == NULL) {
1230                 DBG_8192C("%s: efuseTbl malloc fail!\n", __FUNCTION__);
1231                 return;
1232         }
1233         // 0xff will be efuse default value instead of 0x00.
1234         memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
1235
1236         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total, bPseudoTest);
1237
1238         for (bank=1; bank<EFUSE_MAX_BANK; bank++)
1239         {
1240                 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == false)
1241                 {
1242                         DBG_8192C("%s: hal_EfuseSwitchToBank Fail!!\n", __FUNCTION__);
1243                         goto exit;
1244                 }
1245
1246                 eFuse_Addr = 0;
1247
1248                 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
1249                 {
1250                         ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1251                         if (efuseHeader == 0xFF) break;
1252 //                      DBG_8192C("%s: efuse[%#X]=0x%02x (header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN)+eFuse_Addr-1), efuseHeader);
1253
1254                         // Check PG header for section num.
1255                         if (EXT_HEADER(efuseHeader))            //extended header
1256                         {
1257                                 offset = GET_HDR_OFFSET_2_0(efuseHeader);
1258 //                              DBG_8192C("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset_2_0);
1259
1260                                 ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1261 //                              DBG_8192C("%s: efuse[%#X]=0x%02x (ext header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN)+eFuse_Addr-1), efuseExtHdr);
1262                                 if (ALL_WORDS_DISABLED(efuseExtHdr))
1263                                 {
1264                                         continue;
1265                                 }
1266
1267                                 offset |= ((efuseExtHdr & 0xF0) >> 1);
1268                                 wden = (efuseExtHdr & 0x0F);
1269                         }
1270                         else
1271                         {
1272                                 offset = ((efuseHeader >> 4) & 0x0f);
1273                                 wden = (efuseHeader & 0x0f);
1274                         }
1275
1276                         if (offset < EFUSE_BT_MAX_SECTION)
1277                         {
1278                                 u16 addr;
1279
1280                                 // Get word enable value from PG header
1281 //                              DBG_8192C("%s: Offset=%d Worden=%#X\n", __FUNCTION__, offset, wden);
1282
1283                                 addr = offset * PGPKT_DATA_SIZE;
1284                                 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1285                                 {
1286                                         // Check word enable condition in the section
1287                                         if (!(wden & (0x01<<i)))
1288                                         {
1289                                                 ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1290 //                                              DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1291                                                 efuseTbl[addr] = efuseData;
1292
1293                                                 ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1294 //                                              DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1295                                                 efuseTbl[addr+1] = efuseData;
1296                                         }
1297                                         addr += 2;
1298                                 }
1299                         }
1300                         else
1301                         {
1302                                 DBG_8192C(KERN_ERR "%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1303                                 eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
1304                         }
1305                 }
1306
1307                 if ((eFuse_Addr-1) < total)
1308                 {
1309                         DBG_8192C("%s: bank(%d) data end at %#x\n", __FUNCTION__, bank, eFuse_Addr-1);
1310                         break;
1311                 }
1312         }
1313
1314         // switch bank back to bank 0 for later BT and wifi use.
1315         hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1316
1317         // Copy from Efuse map to output pointer memory!!!
1318         for (i=0; i<_size_byte; i++)
1319                 pbuf[i] = efuseTbl[_offset+i];
1320
1321         //
1322         // Calculate Efuse utilization.
1323         //
1324         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1325         used = (EFUSE_BT_REAL_BANK_CONTENT_LEN*(bank-1)) + eFuse_Addr - 1;
1326         efuse_usage = (u8)((used*100)/total);
1327         if (bPseudoTest)
1328         {
1329 #ifdef HAL_EFUSE_MEMORY
1330                 pEfuseHal->fakeBTEfuseUsedBytes = used;
1331 #else
1332                 fakeBTEfuseUsedBytes = used;
1333 #endif
1334         }
1335         else
1336         {
1337                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&used);
1338                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8*)&efuse_usage);
1339         }
1340
1341 exit:
1342         if (efuseTbl)
1343                 rtw_mfree(efuseTbl, EFUSE_BT_MAP_LEN);
1344 }
1345
1346 static void
1347 Hal_ReadEFuse(
1348         PADAPTER        padapter,
1349         u8                      efuseType,
1350         u16                     _offset,
1351         u16                     _size_byte,
1352         u8                      *pbuf,
1353         bool                    bPseudoTest)
1354 {
1355         if (efuseType == EFUSE_WIFI)
1356                 hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1357         else
1358                 hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1359 }
1360
1361 static u16
1362 hal_EfuseGetCurrentSize_WiFi(
1363         PADAPTER        padapter,
1364         u8                      bPseudoTest)
1365 {
1366 #ifdef HAL_EFUSE_MEMORY
1367         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
1368         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
1369 #endif
1370         u16     efuse_addr=0;
1371         u8      hoffset=0, hworden=0;
1372         u8      efuse_data, word_cnts=0;
1373
1374
1375         if (bPseudoTest)
1376         {
1377 #ifdef HAL_EFUSE_MEMORY
1378                 efuse_addr = (u16)pEfuseHal->fakeEfuseUsedBytes;
1379 #else
1380                 efuse_addr = (u16)fakeEfuseUsedBytes;
1381 #endif
1382         }
1383         else
1384         {
1385                 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
1386         }
1387         DBG_8192C("%s: start_efuse_addr=0x%X\n", __FUNCTION__, efuse_addr);
1388
1389         // switch bank back to bank 0 for later BT and wifi use.
1390         hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1391
1392         while (AVAILABLE_EFUSE_ADDR(efuse_addr))
1393         {
1394                 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == false)
1395                 {
1396                         DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
1397                         break;
1398                 }
1399
1400                 if (efuse_data == 0xFF) break;
1401
1402                 if (EXT_HEADER(efuse_data))
1403                 {
1404                         hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1405                         efuse_addr++;
1406                         efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1407                         if (ALL_WORDS_DISABLED(efuse_data))
1408                         {
1409                                 continue;
1410                         }
1411
1412                         hoffset |= ((efuse_data & 0xF0) >> 1);
1413                         hworden = efuse_data & 0x0F;
1414                 }
1415                 else
1416                 {
1417                         hoffset = (efuse_data>>4) & 0x0F;
1418                         hworden = efuse_data & 0x0F;
1419                 }
1420
1421                 word_cnts = Efuse_CalculateWordCnts(hworden);
1422                 efuse_addr += (word_cnts*2)+1;
1423         }
1424
1425         if (bPseudoTest)
1426         {
1427 #ifdef HAL_EFUSE_MEMORY
1428                 pEfuseHal->fakeEfuseUsedBytes = efuse_addr;
1429 #else
1430                 fakeEfuseUsedBytes = efuse_addr;
1431 #endif
1432         }
1433         else
1434         {
1435                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
1436         }
1437         DBG_8192C("%s: CurrentSize=%d\n", __FUNCTION__, efuse_addr);
1438
1439         return efuse_addr;
1440 }
1441
1442 static u16
1443 hal_EfuseGetCurrentSize_BT(
1444         PADAPTER        padapter,
1445         u8                      bPseudoTest)
1446 {
1447 #ifdef HAL_EFUSE_MEMORY
1448         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
1449         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
1450 #endif
1451         u16 btusedbytes;
1452         u16     efuse_addr;
1453         u8      bank, startBank;
1454         u8      hoffset=0, hworden=0;
1455         u8      efuse_data, word_cnts=0;
1456         u16     retU2=0;
1457
1458
1459         if (bPseudoTest)
1460         {
1461 #ifdef HAL_EFUSE_MEMORY
1462                 btusedbytes = pEfuseHal->fakeBTEfuseUsedBytes;
1463 #else
1464                 btusedbytes = fakeBTEfuseUsedBytes;
1465 #endif
1466         }
1467         else
1468         {
1469                 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&btusedbytes);
1470         }
1471         efuse_addr = (u16)((btusedbytes%EFUSE_BT_REAL_BANK_CONTENT_LEN));
1472         startBank = (u8)(1+(btusedbytes/EFUSE_BT_REAL_BANK_CONTENT_LEN));
1473
1474         DBG_8192C("%s: start from bank=%d addr=0x%X\n", __FUNCTION__, startBank, efuse_addr);
1475
1476         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2, bPseudoTest);
1477
1478         for (bank=startBank; bank<EFUSE_MAX_BANK; bank++)
1479         {
1480                 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == false)
1481                 {
1482                         DBG_8192C(KERN_ERR "%s: switch bank(%d) Fail!!\n", __FUNCTION__, bank);
1483                         bank = EFUSE_MAX_BANK;
1484                         break;
1485                 }
1486
1487                 // only when bank is switched we have to reset the efuse_addr.
1488                 if (bank != startBank)
1489                         efuse_addr = 0;
1490
1491                 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
1492                 {
1493                         if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == false)
1494                         {
1495                                 DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
1496                                 bank = EFUSE_MAX_BANK;
1497                                 break;
1498                         }
1499
1500                         if (efuse_data == 0xFF) break;
1501
1502                         if (EXT_HEADER(efuse_data))
1503                         {
1504                                 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1505                                 efuse_addr++;
1506                                 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1507                                 if (ALL_WORDS_DISABLED(efuse_data))
1508                                 {
1509                                         efuse_addr++;
1510                                         continue;
1511                                 }
1512
1513                                 hoffset |= ((efuse_data & 0xF0) >> 1);
1514                                 hworden = efuse_data & 0x0F;
1515                         }
1516                         else
1517                         {
1518                                 hoffset = (efuse_data>>4) & 0x0F;
1519                                 hworden =  efuse_data & 0x0F;
1520                         }
1521                         word_cnts = Efuse_CalculateWordCnts(hworden);
1522                         //read next header
1523                         efuse_addr += (word_cnts*2)+1;
1524                 }
1525
1526                 // Check if we need to check next bank efuse
1527                 if (efuse_addr < retU2)
1528                 {
1529                         break;// don't need to check next bank.
1530                 }
1531         }
1532
1533         retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
1534         if (bPseudoTest)
1535         {
1536 #ifdef HAL_EFUSE_MEMORY
1537                 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
1538 #else
1539                 fakeBTEfuseUsedBytes = retU2;
1540 #endif
1541         }
1542         else
1543         {
1544                 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&retU2);
1545         }
1546
1547         DBG_8192C("%s: CurrentSize=%d\n", __FUNCTION__, retU2);
1548         return retU2;
1549 }
1550
1551 static u16
1552 Hal_EfuseGetCurrentSize(
1553         PADAPTER        pAdapter,
1554         u8                      efuseType,
1555         bool                    bPseudoTest)
1556 {
1557         u16     ret = 0;
1558
1559         if (efuseType == EFUSE_WIFI)
1560                 ret = hal_EfuseGetCurrentSize_WiFi(pAdapter, bPseudoTest);
1561         else
1562                 ret = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest);
1563
1564         return ret;
1565 }
1566
1567 static u8
1568 Hal_EfuseWordEnableDataWrite(
1569         PADAPTER        padapter,
1570         u16                     efuse_addr,
1571         u8                      word_en,
1572         u8                      *data,
1573         bool                    bPseudoTest)
1574 {
1575         u16     tmpaddr = 0;
1576         u16     start_addr = efuse_addr;
1577         u8      badworden = 0x0F;
1578         u8      tmpdata[PGPKT_DATA_SIZE];
1579
1580
1581 //      DBG_8192C("%s: efuse_addr=%#x word_en=%#x\n", __FUNCTION__, efuse_addr, word_en);
1582         memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
1583
1584         if (!(word_en & BIT(0)))
1585         {
1586                 tmpaddr = start_addr;
1587                 efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest);
1588                 efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest);
1589
1590                 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest);
1591                 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[1], bPseudoTest);
1592                 if ((data[0]!=tmpdata[0]) || (data[1]!=tmpdata[1])) {
1593                         badworden &= (~BIT(0));
1594                 }
1595         }
1596         if (!(word_en & BIT(1)))
1597         {
1598                 tmpaddr = start_addr;
1599                 efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest);
1600                 efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest);
1601
1602                 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest);
1603                 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[3], bPseudoTest);
1604                 if ((data[2]!=tmpdata[2]) || (data[3]!=tmpdata[3])) {
1605                         badworden &= (~BIT(1));
1606                 }
1607         }
1608         if (!(word_en & BIT(2)))
1609         {
1610                 tmpaddr = start_addr;
1611                 efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest);
1612                 efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest);
1613
1614                 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest);
1615                 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[5], bPseudoTest);
1616                 if ((data[4]!=tmpdata[4]) || (data[5]!=tmpdata[5])) {
1617                         badworden &= (~BIT(2));
1618                 }
1619         }
1620         if (!(word_en & BIT(3)))
1621         {
1622                 tmpaddr = start_addr;
1623                 efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest);
1624                 efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest);
1625
1626                 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest);
1627                 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[7], bPseudoTest);
1628                 if ((data[6]!=tmpdata[6]) || (data[7]!=tmpdata[7])) {
1629                         badworden &= (~BIT(3));
1630                 }
1631         }
1632
1633         return badworden;
1634 }
1635
1636 static s32
1637 Hal_EfusePgPacketRead(
1638         PADAPTER        padapter,
1639         u8                      offset,
1640         u8                      *data,
1641         bool                    bPseudoTest)
1642 {
1643         u8      bDataEmpty = true;
1644         u8      efuse_data, word_cnts=0;
1645         u16     efuse_addr=0;
1646         u8      hoffset=0, hworden=0;
1647         u8      i;
1648         u8      max_section = 0;
1649         s32     ret;
1650
1651
1652         if (data == NULL)
1653                 return false;
1654
1655         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest);
1656         if (offset > max_section)
1657         {
1658                 DBG_8192C("%s: Packet offset(%d) is illegal(>%d)!\n", __FUNCTION__, offset, max_section);
1659                 return false;
1660         }
1661
1662         memset(data, 0xFF, PGPKT_DATA_SIZE);
1663         ret = true;
1664
1665         //
1666         // <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP.
1667         // Skip dummy parts to prevent unexpected data read from Efuse.
1668         // By pass right now. 2009.02.19.
1669         //
1670         while (AVAILABLE_EFUSE_ADDR(efuse_addr))
1671         {
1672                 if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == false)
1673                 {
1674                         ret = false;
1675                         break;
1676                 }
1677
1678                 if (efuse_data == 0xFF) break;
1679
1680                 if (EXT_HEADER(efuse_data))
1681                 {
1682                         hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1683                         efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
1684                         if (ALL_WORDS_DISABLED(efuse_data))
1685                         {
1686                                 DBG_8192C("%s: Error!! All words disabled!\n", __FUNCTION__);
1687                                 continue;
1688                         }
1689
1690                         hoffset |= ((efuse_data & 0xF0) >> 1);
1691                         hworden = efuse_data & 0x0F;
1692                 }
1693                 else
1694                 {
1695                         hoffset = (efuse_data>>4) & 0x0F;
1696                         hworden =  efuse_data & 0x0F;
1697                 }
1698
1699                 if (hoffset == offset)
1700                 {
1701                         for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1702                         {
1703                                 // Check word enable condition in the section
1704                                 if (!(hworden & (0x01<<i)))
1705                                 {
1706                                         ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
1707 //                                      DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
1708                                         data[i*2] = efuse_data;
1709
1710                                         ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
1711 //                                      DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
1712                                         data[(i*2)+1] = efuse_data;
1713                                 }
1714                         }
1715                 }
1716                 else
1717                 {
1718                         word_cnts = Efuse_CalculateWordCnts(hworden);
1719                         efuse_addr += word_cnts*2;
1720                 }
1721         }
1722
1723         return ret;
1724 }
1725
1726 static u8
1727 hal_EfusePgCheckAvailableAddr(
1728         PADAPTER        pAdapter,
1729         u8                      efuseType,
1730         u8              bPseudoTest)
1731 {
1732         u16     max_available=0;
1733         u16 current_size;
1734
1735
1736         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &max_available, bPseudoTest);
1737 //      DBG_8192C("%s: max_available=%d\n", __FUNCTION__, max_available);
1738
1739         current_size = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
1740         if (current_size >= max_available)
1741         {
1742                 DBG_8192C("%s: Error!! current_size(%d)>max_available(%d)\n", __FUNCTION__, current_size, max_available);
1743                 return false;
1744         }
1745         return true;
1746 }
1747
1748 static void
1749 hal_EfuseConstructPGPkt(
1750         u8                              offset,
1751         u8                              word_en,
1752         u8                              *pData,
1753         PPGPKT_STRUCT   pTargetPkt)
1754 {
1755         memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
1756         pTargetPkt->offset = offset;
1757         pTargetPkt->word_en = word_en;
1758         efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
1759         pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1760 }
1761
1762 static u8
1763 hal_EfusePartialWriteCheck(
1764         PADAPTER                padapter,
1765         u8                              efuseType,
1766         u16                             *pAddr,
1767         PPGPKT_STRUCT   pTargetPkt,
1768         u8                              bPseudoTest)
1769 {
1770         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
1771         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
1772         u8      bRet=false;
1773         u16     startAddr=0, efuse_max_available_len=0, efuse_max=0;
1774         u8      efuse_data=0;
1775         EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest);
1776         EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest);
1777
1778         if (efuseType == EFUSE_WIFI)
1779         {
1780                 if (bPseudoTest)
1781                 {
1782 #ifdef HAL_EFUSE_MEMORY
1783                         startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes;
1784 #else
1785                         startAddr = (u16)fakeEfuseUsedBytes;
1786 #endif
1787                 }
1788                 else
1789                 {
1790                         rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&startAddr);
1791                 }
1792         }
1793         else
1794         {
1795                 if (bPseudoTest)
1796                 {
1797 #ifdef HAL_EFUSE_MEMORY
1798                         startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes;
1799 #else
1800                         startAddr = (u16)fakeBTEfuseUsedBytes;
1801 #endif
1802                 }
1803                 else
1804                 {
1805                         rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&startAddr);
1806                 }
1807         }
1808         startAddr %= efuse_max;
1809 //      DBG_8192C("%s: startAddr=%#X\n", __FUNCTION__, startAddr);
1810
1811         while (1)
1812         {
1813                 if (startAddr >= efuse_max_available_len)
1814                 {
1815                         bRet = false;
1816                         DBG_8192C("%s: startAddr(%d) >= efuse_max_available_len(%d)\n",
1817                                 __FUNCTION__, startAddr, efuse_max_available_len);
1818                         break;
1819                 }
1820
1821                 if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data!=0xFF))
1822                 {
1823 #if 1
1824                         bRet = false;
1825                         DBG_8192C("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n",
1826                                 __FUNCTION__, startAddr, efuse_data);
1827                         break;
1828 #else
1829                         if (EXT_HEADER(efuse_data))
1830                         {
1831                                 cur_header = efuse_data;
1832                                 startAddr++;
1833                                 efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest);
1834                                 if (ALL_WORDS_DISABLED(efuse_data))
1835                                 {
1836                                         DBG_8192C("%s: Error condition, all words disabled!", __FUNCTION__);
1837                                         bRet = false;
1838                                         break;
1839                                 }
1840                                 else
1841                                 {
1842                                         curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1843                                         curPkt.word_en = efuse_data & 0x0F;
1844                                 }
1845                         }
1846                         else
1847                         {
1848                                 cur_header  =  efuse_data;
1849                                 curPkt.offset = (cur_header>>4) & 0x0F;
1850                                 curPkt.word_en = cur_header & 0x0F;
1851                         }
1852
1853                         curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
1854                         // if same header is found but no data followed
1855                         // write some part of data followed by the header.
1856                         if ((curPkt.offset == pTargetPkt->offset) &&
1857                                 (hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr+1, bPseudoTest) == false) &&
1858                                 wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == true)
1859                         {
1860                                 DBG_8192C("%s: Need to partial write data by the previous wrote header\n", __FUNCTION__);
1861                                 // Here to write partial data
1862                                 badworden = Efuse_WordEnableDataWrite(padapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest);
1863                                 if (badworden != 0x0F)
1864                                 {
1865                                         u32     PgWriteSuccess=0;
1866                                         // if write fail on some words, write these bad words again
1867                                         if (efuseType == EFUSE_WIFI)
1868                                                 PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
1869                                         else
1870                                                 PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
1871
1872                                         if (!PgWriteSuccess)
1873                                         {
1874                                                 bRet = false;   // write fail, return
1875                                                 break;
1876                                         }
1877                                 }
1878                                 // partial write ok, update the target packet for later use
1879                                 for (i=0; i<4; i++)
1880                                 {
1881                                         if ((matched_wden & (0x1<<i)) == 0)     // this word has been written
1882                                         {
1883                                                 pTargetPkt->word_en |= (0x1<<i);        // disable the word
1884                                         }
1885                                 }
1886                                 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1887                         }
1888                         // read from next header
1889                         startAddr = startAddr + (curPkt.word_cnts*2) + 1;
1890 #endif
1891                 }
1892                 else
1893                 {
1894                         // not used header, 0xff
1895                         *pAddr = startAddr;
1896 //                      DBG_8192C("%s: Started from unused header offset=%d\n", __FUNCTION__, startAddr));
1897                         bRet = true;
1898                         break;
1899                 }
1900         }
1901
1902         return bRet;
1903 }
1904
1905 static u8
1906 hal_EfusePgPacketWrite1ByteHeader(
1907         PADAPTER                pAdapter,
1908         u8                              efuseType,
1909         u16                             *pAddr,
1910         PPGPKT_STRUCT   pTargetPkt,
1911         u8                              bPseudoTest)
1912 {
1913         u8      bRet=false;
1914         u8      pg_header=0, tmp_header=0;
1915         u16     efuse_addr=*pAddr;
1916         u8      repeatcnt=0;
1917
1918
1919 //      DBG_8192C("%s\n", __FUNCTION__);
1920         pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
1921
1922         do {
1923                 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1924                 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1925                 if (tmp_header != 0xFF) break;
1926                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1927                 {
1928                         DBG_8192C("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
1929                         return false;
1930                 }
1931         } while (1);
1932
1933         if (tmp_header != pg_header)
1934         {
1935                 DBG_8192C(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
1936                 return false;
1937         }
1938
1939         *pAddr = efuse_addr;
1940
1941         return true;
1942 }
1943
1944 static u8
1945 hal_EfusePgPacketWrite2ByteHeader(
1946         PADAPTER                padapter,
1947         u8                              efuseType,
1948         u16                             *pAddr,
1949         PPGPKT_STRUCT   pTargetPkt,
1950         u8                              bPseudoTest)
1951 {
1952         u16     efuse_addr, efuse_max_available_len=0;
1953         u8      pg_header=0, tmp_header=0;
1954         u8      repeatcnt=0;
1955
1956
1957 //      DBG_8192C("%s\n", __FUNCTION__);
1958         EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest);
1959
1960         efuse_addr = *pAddr;
1961         if (efuse_addr >= efuse_max_available_len)
1962         {
1963                 DBG_8192C("%s: addr(%d) over avaliable(%d)!!\n", __FUNCTION__, efuse_addr, efuse_max_available_len);
1964                 return false;
1965         }
1966
1967         pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
1968 //      DBG_8192C("%s: pg_header=0x%x\n", __FUNCTION__, pg_header);
1969
1970         do {
1971                 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
1972                 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
1973                 if (tmp_header != 0xFF) break;
1974                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1975                 {
1976                         DBG_8192C("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
1977                         return false;
1978                 }
1979         } while (1);
1980
1981         if (tmp_header != pg_header)
1982         {
1983                 DBG_8192C(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
1984                 return false;
1985         }
1986
1987         // to write ext_header
1988         efuse_addr++;
1989         pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
1990
1991         do {
1992                 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
1993                 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
1994                 if (tmp_header != 0xFF) break;
1995                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1996                 {
1997                         DBG_8192C("%s: Repeat over limit for ext_header!!\n", __FUNCTION__);
1998                         return false;
1999                 }
2000         } while (1);
2001
2002         if (tmp_header != pg_header)    //offset PG fail
2003         {
2004                 DBG_8192C(KERN_ERR "%s: PG EXT Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
2005                 return false;
2006         }
2007
2008         *pAddr = efuse_addr;
2009
2010         return true;
2011 }
2012
2013 static u8
2014 hal_EfusePgPacketWriteHeader(
2015         PADAPTER                padapter,
2016         u8                              efuseType,
2017         u16                             *pAddr,
2018         PPGPKT_STRUCT   pTargetPkt,
2019         u8                              bPseudoTest)
2020 {
2021         u8 bRet=false;
2022
2023         if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
2024         {
2025                 bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2026         }
2027         else
2028         {
2029                 bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2030         }
2031
2032         return bRet;
2033 }
2034
2035 static u8
2036 hal_EfusePgPacketWriteData(
2037         PADAPTER                pAdapter,
2038         u8                              efuseType,
2039         u16                             *pAddr,
2040         PPGPKT_STRUCT   pTargetPkt,
2041         u8                              bPseudoTest)
2042 {
2043         u16     efuse_addr;
2044         u8      badworden;
2045
2046
2047         efuse_addr = *pAddr;
2048         badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
2049         if (badworden != 0x0F)
2050         {
2051                 DBG_8192C("%s: Fail!!\n", __FUNCTION__);
2052                 return false;
2053         }
2054
2055 //      DBG_8192C("%s: ok\n", __FUNCTION__);
2056         return true;
2057 }
2058
2059 static s32
2060 Hal_EfusePgPacketWrite(
2061         PADAPTER        padapter,
2062         u8                      offset,
2063         u8                      word_en,
2064         u8                      *pData,
2065         bool                    bPseudoTest)
2066 {
2067         PGPKT_STRUCT targetPkt;
2068         u16 startAddr=0;
2069         u8 efuseType=EFUSE_WIFI;
2070
2071         if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest))
2072                 return false;
2073
2074         hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2075
2076         if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2077                 return false;
2078
2079         if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2080                 return false;
2081
2082         if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2083                 return false;
2084
2085         return true;
2086 }
2087
2088 static bool
2089 Hal_EfusePgPacketWrite_BT(
2090         PADAPTER        pAdapter,
2091         u8                      offset,
2092         u8                      word_en,
2093         u8                      *pData,
2094         bool                    bPseudoTest)
2095 {
2096         PGPKT_STRUCT targetPkt;
2097         u16 startAddr=0;
2098         u8 efuseType=EFUSE_BT;
2099
2100         if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
2101                 return false;
2102
2103         hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2104
2105         if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2106                 return false;
2107
2108         if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2109                 return false;
2110
2111         if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2112                 return false;
2113
2114         return true;
2115 }
2116
2117 static HAL_VERSION
2118 ReadChipVersion8723A(
2119         IN      PADAPTER        padapter
2120         )
2121 {
2122         u32                             value32;
2123         HAL_VERSION             ChipVersion;
2124         HAL_DATA_TYPE   *pHalData;
2125
2126
2127         pHalData = GET_HAL_DATA(padapter);
2128
2129         value32 = rtw_read32(padapter, REG_SYS_CFG);
2130         ChipVersion.ICType = CHIP_8723A;
2131         ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
2132         ChipVersion.RFType = RF_TYPE_1T1R ;
2133         ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
2134         ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; // IC version (CUT)
2135
2136         // For regulator mode. by tynli. 2011.01.14
2137         pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
2138
2139         value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
2140         ChipVersion.ROMVer = ((value32 & RF_RL_ID) >> 20);      // ROM code version.
2141
2142         // For multi-function consideration. Added by Roger, 2010.10.06.
2143         pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
2144         value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
2145         pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
2146         pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
2147         pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
2148         pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT);
2149 //#if DBG
2150 #if 1
2151         dump_chip_info(ChipVersion);
2152 #endif
2153         pHalData->VersionID = ChipVersion;
2154
2155         if (IS_1T2R(ChipVersion))
2156                 pHalData->rf_type = RF_1T2R;
2157         else if (IS_2T2R(ChipVersion))
2158                 pHalData->rf_type = RF_2T2R;
2159         else
2160                 pHalData->rf_type = RF_1T1R;
2161
2162         MSG_8192C("RF_Type is %x!!\n", pHalData->rf_type);
2163
2164         return ChipVersion;
2165 }
2166
2167
2168 static void rtl8723a_read_chip_version(PADAPTER padapter)
2169 {
2170         ReadChipVersion8723A(padapter);
2171 }
2172
2173 //====================================================================================
2174 //
2175 // 20100209 Joseph:
2176 // This function is used only for 92C to set REG_BCN_CTRL(0x550) register.
2177 // We just reserve the value of the register in variable pHalData->RegBcnCtrlVal and then operate
2178 // the value of the register via atomic operation.
2179 // This prevents from race condition when setting this register.
2180 // The value of pHalData->RegBcnCtrlVal is initialized in HwConfigureRTL8192CE() function.
2181 //
2182 void SetBcnCtrlReg(PADAPTER padapter, u8 SetBits, u8 ClearBits)
2183 {
2184         PHAL_DATA_TYPE pHalData;
2185         u32 addr;
2186         u8 *pRegBcnCtrlVal;
2187
2188
2189         pHalData = GET_HAL_DATA(padapter);
2190         pRegBcnCtrlVal = (u8*)&pHalData->RegBcnCtrlVal;
2191
2192 #ifdef CONFIG_CONCURRENT_MODE
2193         if (padapter->iface_type == IFACE_PORT1)
2194         {
2195                 addr = REG_BCN_CTRL_1;
2196                 pRegBcnCtrlVal++;
2197         }
2198         else
2199 #endif
2200         {
2201                 addr = REG_BCN_CTRL;
2202         }
2203
2204         *pRegBcnCtrlVal = rtw_read8(padapter, addr);
2205         *pRegBcnCtrlVal |= SetBits;
2206         *pRegBcnCtrlVal &= ~ClearBits;
2207
2208         rtw_write8(padapter, addr, *pRegBcnCtrlVal);
2209 }
2210
2211 void rtl8723a_InitBeaconParameters(PADAPTER padapter)
2212 {
2213         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2214
2215
2216         rtw_write16(padapter, REG_BCN_CTRL, 0x1010);
2217         pHalData->RegBcnCtrlVal = 0x1010;
2218
2219         // TODO: Remove these magic number
2220         rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);// ms
2221         // Firmware will control REG_DRVERLYINT when power saving is enable,
2222         // so don't set this register on STA mode.
2223         if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == false)
2224                 rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME); // 5ms
2225         rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); // 2ms
2226
2227         // Suggested by designer timchen. Change beacon AIFS to the largest number
2228         // beacause test chip does not contension before sending beacon. by tynli. 2009.11.03
2229         rtw_write16(padapter, REG_BCNTCFG, 0x660F);
2230 }
2231
2232 void rtl8723a_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode)
2233 {
2234 #ifdef RTL8192CU_ADHOC_WORKAROUND_SETTING
2235         rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
2236 #else
2237         //rtw_write8(Adapter, REG_BCN_MAX_ERR, (InfraMode ? 0xFF : 0x10));
2238 #endif
2239 }
2240
2241 static void ResumeTxBeacon(PADAPTER padapter)
2242 {
2243         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2244
2245
2246         // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
2247         // which should be read from register to a global variable.
2248
2249         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
2250
2251         pHalData->RegFwHwTxQCtrl |= BIT(6);
2252         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
2253         rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0xff);
2254         pHalData->RegReg542 |= BIT(0);
2255         rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
2256 }
2257
2258 static void StopTxBeacon(PADAPTER padapter)
2259 {
2260         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2261
2262
2263         // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
2264         // which should be read from register to a global variable.
2265
2266         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
2267
2268         pHalData->RegFwHwTxQCtrl &= ~BIT(6);
2269         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
2270         rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64);
2271         pHalData->RegReg542 &= ~BIT(0);
2272         rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
2273
2274         CheckFwRsvdPageContent(padapter);  // 2010.06.23. Added by tynli.
2275 }
2276
2277 static void _BeaconFunctionEnable(PADAPTER padapter, u8 Enable, u8 Linked)
2278 {
2279         SetBcnCtrlReg(padapter, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB, 0);
2280         rtw_write8(padapter, REG_RD_CTRL+1, 0x6F);
2281 }
2282
2283 static void rtl8723a_SetBeaconRelatedRegisters(PADAPTER padapter)
2284 {
2285         u32 value32;
2286         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2287         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2288         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2289
2290
2291         //reset TSF, enable update TSF, correcting TSF On Beacon
2292
2293         //REG_BCN_INTERVAL
2294         //REG_BCNDMATIM
2295         //REG_ATIMWND
2296         //REG_TBTT_PROHIBIT
2297         //REG_DRVERLYINT
2298         //REG_BCN_MAX_ERR
2299         //REG_BCNTCFG //(0x510)
2300         //REG_DUAL_TSF_RST
2301         //REG_BCN_CTRL //(0x550)
2302
2303         //
2304         // ATIM window
2305         //
2306         rtw_write16(padapter, REG_ATIMWND, 2);
2307
2308         //
2309         // Beacon interval (in unit of TU).
2310         //
2311         rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
2312
2313         rtl8723a_InitBeaconParameters(padapter);
2314
2315         rtw_write8(padapter, REG_SLOT, 0x09);
2316
2317         //
2318         // Reset TSF Timer to zero, added by Roger. 2008.06.24
2319         //
2320         value32 = rtw_read32(padapter, REG_TCR);
2321         value32 &= ~TSFRST;
2322         rtw_write32(padapter, REG_TCR, value32);
2323
2324         value32 |= TSFRST;
2325         rtw_write32(padapter, REG_TCR, value32);
2326
2327         // NOTE: Fix test chip's bug (about contention windows's randomness)
2328         if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == true)
2329         {
2330                 rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
2331                 rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
2332         }
2333
2334         _BeaconFunctionEnable(padapter, true, true);
2335
2336         ResumeTxBeacon(padapter);
2337         SetBcnCtrlReg(padapter, DIS_BCNQ_SUB, 0);
2338 }
2339
2340 void rtl8723a_GetHalODMVar(
2341         PADAPTER                                Adapter,
2342         HAL_ODM_VARIABLE                eVariable,
2343         void *                                  pValue1,
2344         bool                                    bSet)
2345 {
2346         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
2347         PDM_ODM_T podmpriv = &pHalData->odmpriv;
2348         switch (eVariable){
2349                 case HAL_ODM_STA_INFO:
2350                         break;
2351                 default:
2352                         break;
2353         }
2354 }
2355
2356 void rtl8723a_SetHalODMVar(
2357         PADAPTER                                Adapter,
2358         HAL_ODM_VARIABLE                eVariable,
2359         void *                                  pValue1,
2360         bool                                    bSet)
2361 {
2362         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
2363         PDM_ODM_T podmpriv = &pHalData->odmpriv;
2364         switch (eVariable){
2365                 case HAL_ODM_STA_INFO:
2366                         {
2367                                 struct sta_info *psta = (struct sta_info *)pValue1;
2368                                 #ifdef CONFIG_CONCURRENT_MODE
2369                                 //get Primary adapter's odmpriv
2370                                 if (Adapter->adapter_type > PRIMARY_ADAPTER && Adapter->pbuddy_adapter){
2371                                         pHalData = GET_HAL_DATA(Adapter->pbuddy_adapter);
2372                                         podmpriv = &pHalData->odmpriv;
2373                                 }
2374                                 #endif
2375
2376                                 if (bSet){
2377                                         DBG_8192C("Set STA_(%d) info\n",psta->mac_id);
2378                                         ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS,psta->mac_id,psta);
2379                                 }
2380                                 else{
2381                                         DBG_8192C("Clean STA_(%d) info\n",psta->mac_id);
2382                                         ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS,psta->mac_id,NULL);
2383                                 }
2384                         }
2385                         break;
2386                 case HAL_ODM_P2P_STATE:
2387                                 ODM_CmnInfoUpdate(podmpriv,ODM_CMNINFO_WIFI_DIRECT,bSet);
2388                         break;
2389                 case HAL_ODM_WIFI_DISPLAY_STATE:
2390                                 ODM_CmnInfoUpdate(podmpriv,ODM_CMNINFO_WIFI_DISPLAY,bSet);
2391                         break;
2392                 default:
2393                         break;
2394         }
2395 }
2396 void hal_notch_filter_8723a(_adapter *adapter, bool enable)
2397 {
2398         if (enable) {
2399                 DBG_871X("Enable notch filter\n");
2400                 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
2401         } else {
2402                 DBG_871X("Disable notch filter\n");
2403                 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
2404         }
2405 }
2406
2407 static s32 c2h_handler_8723a(_adapter *padapter, struct c2h_evt_hdr *c2h_evt)
2408 {
2409         s32 ret = _SUCCESS;
2410         u8 i = 0;
2411
2412         if (c2h_evt == NULL) {
2413                 DBG_8192C("%s c2h_evt is NULL\n",__FUNCTION__);
2414                 ret = _FAIL;
2415                 goto exit;
2416         }
2417
2418         switch (c2h_evt->id) {
2419         case C2H_DBG:
2420                 RT_TRACE(_module_hal_init_c_, _drv_info_, ("C2HCommandHandler: %s\n", c2h_evt->payload));
2421                 break;
2422         case C2H_CCX_TX_RPT:
2423                 handle_txrpt_ccx_8723a(padapter, c2h_evt->payload);
2424                 break;
2425         case C2H_EXT_RA_RPT:
2426                 break;
2427         case C2H_HW_INFO_EXCH:
2428                 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], C2H_HW_INFO_EXCH\n"));
2429                 for (i = 0; i < c2h_evt->plen; i++)
2430                         RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], tmpBuf[%d]=0x%x\n", i, c2h_evt->payload[i]));
2431                 break;
2432         case C2H_C2H_H2C_TEST:
2433                 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], C2H_H2C_TEST\n"));
2434                 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], tmpBuf[0]/[1]/[2]/[3]/[4]=0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x\n",
2435                         c2h_evt->payload[0], c2h_evt->payload[1], c2h_evt->payload[2], c2h_evt->payload[3], c2h_evt->payload[4]));
2436                 break;
2437 #ifdef CONFIG_BT_COEXIST
2438         case C2H_BT_INFO:
2439                 BT_FwC2hBtInfo(padapter, c2h_evt->payload, c2h_evt->plen);
2440                 break;
2441 #endif
2442 #ifdef CONFIG_MP_INCLUDED
2443         case C2H_BT_MP_INFO:
2444                 DBG_8192C("%s ,  Got  C2H_BT_MP_INFO\n",__FUNCTION__);
2445                 MPTBT_FwC2hBtMpCtrl(padapter, c2h_evt->payload, c2h_evt->plen);
2446                 break;
2447 #endif
2448         default:
2449                 ret = _FAIL;
2450                 break;
2451         }
2452
2453 exit:
2454         return ret;
2455 }
2456
2457 void rtl8723a_set_hal_ops(struct hal_ops *pHalFunc)
2458 {
2459         pHalFunc->free_hal_data = &rtl8723a_free_hal_data;
2460
2461         pHalFunc->dm_init = &rtl8723a_init_dm_priv;
2462         pHalFunc->dm_deinit = &rtl8723a_deinit_dm_priv;
2463
2464         pHalFunc->read_chip_version = &rtl8723a_read_chip_version;
2465
2466         pHalFunc->set_bwmode_handler = &PHY_SetBWMode8192C;
2467         pHalFunc->set_channel_handler = &PHY_SwChnl8192C;
2468
2469         pHalFunc->hal_dm_watchdog = &rtl8723a_HalDmWatchDog;
2470
2471         pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8723a_SetBeaconRelatedRegisters;
2472
2473         pHalFunc->Add_RateATid = &rtl8192c_Add_RateATid;
2474 #ifdef CONFIG_CONCURRENT_MODE
2475         pHalFunc->clone_haldata = &rtl8723a_clone_haldata;
2476 #endif
2477         pHalFunc->run_thread= &rtl8723a_start_thread;
2478         pHalFunc->cancel_thread= &rtl8723a_stop_thread;
2479
2480 #ifdef CONFIG_ANTENNA_DIVERSITY
2481         pHalFunc->AntDivBeforeLinkHandler = &AntDivBeforeLink8192C;
2482         pHalFunc->AntDivCompareHandler = &AntDivCompare8192C;
2483 #endif
2484
2485         pHalFunc->read_bbreg = &rtl8192c_PHY_QueryBBReg;
2486         pHalFunc->write_bbreg = &rtl8192c_PHY_SetBBReg;
2487         pHalFunc->read_rfreg = &rtl8192c_PHY_QueryRFReg;
2488         pHalFunc->write_rfreg = &rtl8192c_PHY_SetRFReg;
2489
2490         // Efuse related function
2491         pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch;
2492         pHalFunc->ReadEFuse = &Hal_ReadEFuse;
2493         pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition;
2494         pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize;
2495         pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead;
2496         pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite;
2497         pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite;
2498         pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT;
2499
2500 #ifdef DBG_CONFIG_ERROR_DETECT
2501         pHalFunc->sreset_init_value = &sreset_init_value;
2502         pHalFunc->sreset_reset_value = &sreset_reset_value;
2503         pHalFunc->silentreset = &rtl8723a_silentreset_for_specific_platform;
2504         pHalFunc->sreset_xmit_status_check = &rtl8723a_sreset_xmit_status_check;
2505         pHalFunc->sreset_linked_status_check  = &rtl8723a_sreset_linked_status_check;
2506         pHalFunc->sreset_get_wifi_status  = &sreset_get_wifi_status;
2507 #endif
2508         pHalFunc->GetHalODMVarHandler = &rtl8723a_GetHalODMVar;
2509         pHalFunc->SetHalODMVarHandler = &rtl8723a_SetHalODMVar;
2510
2511 #ifdef CONFIG_XMIT_THREAD_MODE
2512         pHalFunc->xmit_thread_handler = &hal_xmit_handler;
2513 #endif
2514         pHalFunc->hal_notch_filter = &hal_notch_filter_8723a;
2515
2516         pHalFunc->c2h_handler = c2h_handler_8723a;
2517 }
2518
2519 void rtl8723a_InitAntenna_Selection(PADAPTER padapter)
2520 {
2521         PHAL_DATA_TYPE pHalData;
2522         u8 val;
2523
2524
2525         pHalData = GET_HAL_DATA(padapter);
2526
2527         val = rtw_read8(padapter, REG_LEDCFG2);
2528         // Let 8051 take control antenna settting
2529         val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
2530         rtw_write8(padapter, REG_LEDCFG2, val);
2531 }
2532
2533 void rtl8723a_CheckAntenna_Selection(PADAPTER padapter)
2534 {
2535         PHAL_DATA_TYPE pHalData;
2536         u8 val;
2537
2538
2539         pHalData = GET_HAL_DATA(padapter);
2540
2541         val = rtw_read8(padapter, REG_LEDCFG2);
2542         // Let 8051 take control antenna settting
2543         if (!(val &BIT(7))){
2544                 val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
2545                 rtw_write8(padapter, REG_LEDCFG2, val);
2546         }
2547 }
2548 void rtl8723a_DeinitAntenna_Selection(PADAPTER padapter)
2549 {
2550         PHAL_DATA_TYPE pHalData;
2551         u8 val;
2552
2553
2554         pHalData = GET_HAL_DATA(padapter);
2555         val = rtw_read8(padapter, REG_LEDCFG2);
2556         // Let 8051 take control antenna settting
2557         val &= ~BIT(7); // DPDT_SEL_EN, clear 0x4C[23]
2558         rtw_write8(padapter, REG_LEDCFG2, val);
2559
2560 }
2561
2562 void rtl8723a_init_default_value(PADAPTER padapter)
2563 {
2564         PHAL_DATA_TYPE pHalData;
2565         struct dm_priv *pdmpriv;
2566         u8 i;
2567
2568
2569         pHalData = GET_HAL_DATA(padapter);
2570         pdmpriv = &pHalData->dmpriv;
2571
2572         // init default value
2573         pHalData->fw_ractrl = false;
2574         pHalData->bIQKInitialized = false;
2575         if (!padapter->pwrctrlpriv.bkeepfwalive)
2576                 pHalData->LastHMEBoxNum = 0;
2577
2578         pHalData->bIQKInitialized = false;
2579
2580         // init dm default value
2581         pdmpriv->TM_Trigger = 0;//for IQK
2582 //      pdmpriv->binitialized = false;
2583 //      pdmpriv->prv_traffic_idx = 3;
2584 //      pdmpriv->initialize = 0;
2585
2586         pdmpriv->ThermalValue_HP_index = 0;
2587         for (i=0; i<HP_THERMAL_NUM; i++)
2588                 pdmpriv->ThermalValue_HP[i] = 0;
2589
2590         // init Efuse variables
2591         pHalData->EfuseUsedBytes = 0;
2592         pHalData->EfuseUsedPercentage = 0;
2593 #ifdef HAL_EFUSE_MEMORY
2594         pHalData->EfuseHal.fakeEfuseBank = 0;
2595         pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
2596         memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
2597         memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
2598         memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
2599         pHalData->EfuseHal.BTEfuseUsedBytes = 0;
2600         pHalData->EfuseHal.BTEfuseUsedPercentage = 0;
2601         memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
2602         memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2603         memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2604         pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0;
2605         memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
2606         memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2607         memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2608 #endif
2609 }
2610
2611 u8 GetEEPROMSize8723A(PADAPTER padapter)
2612 {
2613         u8 size = 0;
2614         u32     cr;
2615
2616         cr = rtw_read16(padapter, REG_9346CR);
2617         // 6: EEPROM used is 93C46, 4: boot from E-Fuse.
2618         size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
2619
2620         MSG_8192C("EEPROM type is %s\n", size==4 ? "E-FUSE" : "93C46");
2621
2622         return size;
2623 }
2624
2625 //-------------------------------------------------------------------------
2626 //
2627 // LLT R/W/Init function
2628 //
2629 //-------------------------------------------------------------------------
2630 s32 _LLTWrite(PADAPTER padapter, u32 address, u32 data)
2631 {
2632         s32     status = _SUCCESS;
2633         s32     count = 0;
2634         u32     value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
2635         u16     LLTReg = REG_LLT_INIT;
2636
2637
2638         rtw_write32(padapter, LLTReg, value);
2639
2640         //polling
2641         do {
2642                 value = rtw_read32(padapter, LLTReg);
2643                 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) {
2644                         break;
2645                 }
2646
2647                 if (count > POLLING_LLT_THRESHOLD) {
2648                         RT_TRACE(_module_hal_init_c_, _drv_err_, ("Failed to polling write LLT done at address %d!\n", address));
2649                         status = _FAIL;
2650                         break;
2651                 }
2652         } while (count++);
2653
2654         return status;
2655 }
2656
2657 u8 _LLTRead(PADAPTER padapter, u32 address)
2658 {
2659         s32     count = 0;
2660         u32     value = _LLT_INIT_ADDR(address) | _LLT_OP(_LLT_READ_ACCESS);
2661         u16     LLTReg = REG_LLT_INIT;
2662
2663
2664         rtw_write32(padapter, LLTReg, value);
2665
2666         //polling and get value
2667         do {
2668                 value = rtw_read32(padapter, LLTReg);
2669                 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) {
2670                         return (u8)value;
2671                 }
2672
2673                 if (count > POLLING_LLT_THRESHOLD) {
2674                         RT_TRACE(_module_hal_init_c_, _drv_err_, ("Failed to polling read LLT done at address %d!\n", address));
2675                         break;
2676                 }
2677         } while (count++);
2678
2679         return 0xFF;
2680 }
2681
2682 s32 InitLLTTable(PADAPTER padapter, u32 boundary)
2683 {
2684         s32     status = _SUCCESS;
2685         u32     i;
2686         u32     txpktbuf_bndy = boundary;
2687         u32     Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;
2688         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2689
2690         for (i = 0; i < (txpktbuf_bndy - 1); i++) {
2691                 status = _LLTWrite(padapter, i, i + 1);
2692                 if (_SUCCESS != status) {
2693                         return status;
2694                 }
2695         }
2696
2697         // end of list
2698         status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
2699         if (_SUCCESS != status) {
2700                 return status;
2701         }
2702
2703         // Make the other pages as ring buffer
2704         // This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer.
2705         // Otherwise used as local loopback buffer.
2706         for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
2707                 status = _LLTWrite(padapter, i, (i + 1));
2708                 if (_SUCCESS != status) {
2709                         return status;
2710                 }
2711         }
2712
2713         // Let last entry point to the start entry of ring buffer
2714         status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
2715         if (_SUCCESS != status) {
2716                 return status;
2717         }
2718
2719         return status;
2720 }
2721
2722 void _DisableGPIO(PADAPTER      padapter)
2723 {
2724 /***************************************
2725 j. GPIO_PIN_CTRL 0x44[31:0]=0x000               //
2726 k.Value = GPIO_PIN_CTRL[7:0]
2727 l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); //write external PIN level
2728 m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
2729 n. LEDCFG 0x4C[15:0] = 0x8080
2730 ***************************************/
2731         u8      value8;
2732         u16     value16;
2733         u32     value32;
2734         u32     u4bTmp;
2735
2736
2737         //1. Disable GPIO[7:0]
2738         rtw_write16(padapter, REG_GPIO_PIN_CTRL+2, 0x0000);
2739         value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
2740         u4bTmp = value32 & 0x000000FF;
2741         value32 |= ((u4bTmp<<8) | 0x00FF0000);
2742         rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32);
2743
2744         if (IS_HARDWARE_TYPE_8723AU(padapter) ||
2745                 IS_HARDWARE_TYPE_8723AS(padapter))
2746         {
2747                 //
2748                 // <Roger_Notes> For RTL8723u multi-function configuration which was autoload from Efuse offset 0x0a and 0x0b,
2749                 // WLAN HW GPIO[9], GPS HW GPIO[10] and BT HW GPIO[11].
2750                 // Added by Roger, 2010.10.07.
2751                 //
2752                 //2. Disable GPIO[8] and GPIO[12]
2753                 rtw_write16(padapter, REG_GPIO_IO_SEL_2, 0x0000); // Configure all pins as input mode.
2754                 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL_2) & 0xFFFF001F;
2755                 u4bTmp = value32 & 0x0000001F;
2756 //              if ( IS_MULTI_FUNC_CHIP(padapter) )
2757 //                      value32 |= ((u4bTmp<<8) | 0x00110000); // Set pin 8 and pin 12 to output mode.
2758 //              else
2759                         value32 |= ((u4bTmp<<8) | 0x001D0000); // Set pin 8, 10, 11 and pin 12 to output mode.
2760                 rtw_write32(padapter, REG_GPIO_PIN_CTRL_2, value32);
2761         }
2762         else
2763         {
2764                 //2. Disable GPIO[10:8]
2765                 rtw_write8(padapter, REG_MAC_PINMUX_CFG, 0x00);
2766                 value16 = rtw_read16(padapter, REG_GPIO_IO_SEL) & 0xFF0F;
2767                 value8 = (u8) (value16&0x000F);
2768                 value16 |= ((value8<<4) | 0x0780);
2769                 rtw_write16(padapter, REG_GPIO_IO_SEL, value16);
2770         }
2771
2772         //3. Disable LED0 & 1
2773         if (IS_HARDWARE_TYPE_8192DU(padapter))
2774         {
2775                 rtw_write16(padapter, REG_LEDCFG0, 0x8888);
2776         }
2777         else
2778         {
2779                 rtw_write16(padapter, REG_LEDCFG0, 0x8080);
2780         }
2781 //      RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable GPIO and LED.\n"));
2782 } //end of _DisableGPIO()
2783
2784 void _DisableRFAFEAndResetBB8192C(PADAPTER padapter)
2785 {
2786 /**************************************
2787 a.      TXPAUSE 0x522[7:0] = 0xFF             //Pause MAC TX queue
2788 b.      RF path 0 offset 0x00 = 0x00            // disable RF
2789 c.      APSD_CTRL 0x600[7:0] = 0x40
2790 d.      SYS_FUNC_EN 0x02[7:0] = 0x16            //reset BB state machine
2791 e.      SYS_FUNC_EN 0x02[7:0] = 0x14            //reset BB state machine
2792 ***************************************/
2793         u8 eRFPath = 0, value8 = 0;
2794
2795         rtw_write8(padapter, REG_TXPAUSE, 0xFF);
2796
2797         PHY_SetRFReg(padapter, (RF_RADIO_PATH_E)eRFPath, 0x0, bMaskByte0, 0x0);
2798
2799         value8 |= APSDOFF;
2800         rtw_write8(padapter, REG_APSD_CTRL, value8);//0x40
2801
2802         // Set BB reset at first
2803         value8 = 0 ;
2804         value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
2805         rtw_write8(padapter, REG_SYS_FUNC_EN, value8 );//0x16
2806
2807         // Set global reset.
2808         value8 &= ~FEN_BB_GLB_RSTn;
2809         rtw_write8(padapter, REG_SYS_FUNC_EN, value8); //0x14
2810
2811         // 2010/08/12 MH We need to set BB/GLBAL reset to save power for SS mode.
2812
2813 //      RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n"));
2814 }
2815
2816 void _DisableRFAFEAndResetBB(PADAPTER padapter)
2817 {
2818                 _DisableRFAFEAndResetBB8192C(padapter);
2819 }
2820
2821 void _ResetDigitalProcedure1_92C(PADAPTER padapter, bool bWithoutHWSM)
2822 {
2823         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
2824
2825         if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20))
2826         {
2827                 /*****************************
2828                 f.      MCUFWDL 0x80[7:0]=0                             // reset MCU ready status
2829                 g.      SYS_FUNC_EN 0x02[10]= 0                 // reset MCU register, (8051 reset)
2830                 h.      SYS_FUNC_EN 0x02[15-12]= 5              // reset MAC register, DCORE
2831                 i.     SYS_FUNC_EN 0x02[10]= 1                  // enable MCU register, (8051 enable)
2832                 ******************************/
2833                 u16 valu16 = 0;
2834                 rtw_write8(padapter, REG_MCUFWDL, 0);
2835
2836                 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
2837                 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));//reset MCU ,8051
2838
2839                 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN)&0x0FFF;
2840                 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 |(FEN_HWPDN|FEN_ELDR)));//reset MAC
2841
2842                 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
2843                 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));//enable MCU ,8051
2844         } else {
2845                 u8 retry_cnts = 0;
2846
2847                 // 2010/08/12 MH For USB SS, we can not stop 8051 when we are trying to
2848                 // enter IPS/HW&SW radio off. For S3/S4/S5/Disable, we can stop 8051 because
2849                 // we will init FW when power on again.
2850                 {       // If we want to SS mode, we can not reset 8051.
2851                         if (rtw_read8(padapter, REG_MCUFWDL) & BIT1)
2852                         { //IF fw in RAM code, do reset
2853
2854
2855                                 if (padapter->bFWReady)
2856                                 {
2857                                         // 2010/08/25 MH Accordign to RD alfred's suggestion, we need to disable other
2858                                         // HRCV INT to influence 8051 reset.
2859                                         rtw_write8(padapter, REG_FWIMR, 0x20);
2860                                         // 2011/02/15 MH According to Alex's suggestion, close mask to prevent incorrect FW write operation.
2861                                         rtw_write8(padapter, REG_FTIMR, 0x00);
2862                                         rtw_write8(padapter, REG_FSIMR, 0x00);
2863
2864                                         rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
2865
2866                                         while ( (retry_cnts++ <100) && (FEN_CPUEN &rtw_read16(padapter, REG_SYS_FUNC_EN)))
2867                                         {
2868                                                 rtw_udelay_os(50);//us
2869                                         }
2870
2871                                         if (retry_cnts >= 100)
2872                                         {
2873                                                 // if 8051 reset fail we trigger GPIO 0 for LA
2874                                                 //rtw_write32(  padapter,
2875                                                 //                                              REG_GPIO_PIN_CTRL,
2876                                                 //                                              0x00010100);
2877                                                 // 2010/08/31 MH According to Filen's info, if 8051 reset fail, reset MAC directly.
2878                                                 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x50);  //Reset MAC and Enable 8051
2879                                                 rtw_mdelay_os(10);
2880                                         }
2881                                 }
2882                         }
2883                         rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x54);  //Reset MAC and Enable 8051
2884                         rtw_write8(padapter, REG_MCUFWDL, 0);
2885                 }
2886         }
2887
2888         if (bWithoutHWSM) {
2889         /*****************************
2890                 Without HW auto state machine
2891         g.      SYS_CLKR 0x08[15:0] = 0x30A3                    //disable MAC clock
2892         h.      AFE_PLL_CTRL 0x28[7:0] = 0x80                   //disable AFE PLL
2893         i.      AFE_XTAL_CTRL 0x24[15:0] = 0x880F               //gated AFE DIG_CLOCK
2894         j.      SYS_ISO_CTRL 0x00[7:0] = 0xF9                   // isolated digital to PON
2895         ******************************/
2896                 rtw_write16(padapter, REG_SYS_CLKR, 0x70A3);  //modify to 0x70A3 by Scott.
2897                 rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
2898                 rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
2899                 rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
2900         } else {
2901                 // Disable all RF/BB power
2902                 rtw_write8(padapter, REG_RF_CTRL, 0x00);
2903         }
2904 }
2905
2906 void _ResetDigitalProcedure1(PADAPTER padapter, bool bWithoutHWSM)
2907 {
2908         _ResetDigitalProcedure1_92C(padapter, bWithoutHWSM);
2909 }
2910
2911 void _ResetDigitalProcedure2(PADAPTER padapter)
2912 {
2913 /*****************************
2914 k.      SYS_FUNC_EN 0x03[7:0] = 0x44                    // disable ELDR runction
2915 l.      SYS_CLKR 0x08[15:0] = 0x3083                    // disable ELDR clock
2916 m.      SYS_ISO_CTRL 0x01[7:0] = 0x83                   // isolated ELDR to PON
2917 ******************************/
2918         rtw_write16(padapter, REG_SYS_CLKR, 0x70a3); //modify to 0x70a3 by Scott.
2919         rtw_write8(padapter, REG_SYS_ISO_CTRL+1, 0x82); //modify to 0x82 by Scott.
2920 }
2921
2922 void _DisableAnalog(PADAPTER padapter, bool bWithoutHWSM)
2923 {
2924         HAL_DATA_TYPE   *pHalData       = GET_HAL_DATA(padapter);
2925         u16 value16 = 0;
2926         u8 value8 = 0;
2927
2928
2929         if (bWithoutHWSM)
2930         {
2931                 /*****************************
2932                 n.      LDOA15_CTRL 0x20[7:0] = 0x04            // disable A15 power
2933                 o.      LDOV12D_CTRL 0x21[7:0] = 0x54           // disable digital core power
2934                 r.      When driver call disable, the ASIC will turn off remaining clock automatically
2935                 ******************************/
2936
2937                 rtw_write8(padapter, REG_LDOA15_CTRL, 0x04);
2938                 //rtw_write8(padapter, REG_LDOV12D_CTRL, 0x54);
2939
2940                 value8 = rtw_read8(padapter, REG_LDOV12D_CTRL);
2941                 value8 &= (~LDV12_EN);
2942                 rtw_write8(padapter, REG_LDOV12D_CTRL, value8);
2943 //              RT_TRACE(COMP_INIT, DBG_LOUD, (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",value8));
2944         }
2945
2946         /*****************************
2947         h.      SPS0_CTRL 0x11[7:0] = 0x23                      //enter PFM mode
2948         i.      APS_FSMCO 0x04[15:0] = 0x4802           // set USB suspend
2949         ******************************/
2950         value8 = 0x23;
2951         if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
2952                 value8 |= BIT3;
2953
2954         rtw_write8(padapter, REG_SPS0_CTRL, value8);
2955
2956         if (bWithoutHWSM)
2957         {
2958                 //value16 |= (APDM_HOST | /*AFSM_HSUS |*/PFM_ALDN);
2959                 // 2010/08/31 According to Filen description, we need to use HW to shut down 8051 automatically.
2960                 // Becasue suspend operatione need the asistance of 8051 to wait for 3ms.
2961                 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
2962         }
2963         else
2964         {
2965                 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
2966         }
2967
2968         rtw_write16(padapter, REG_APS_FSMCO, value16);//0x4802
2969
2970         rtw_write8(padapter, REG_RSV_CTRL, 0x0e);
2971
2972 }
2973
2974 // HW Auto state machine
2975 s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU)
2976 {
2977         int rtStatus = _SUCCESS;
2978
2979
2980         if (padapter->bSurpriseRemoved){
2981                 return rtStatus;
2982         }
2983         //==== RF Off Sequence ====
2984         _DisableRFAFEAndResetBB(padapter);
2985
2986         //  ==== Reset digital sequence   ======
2987         _ResetDigitalProcedure1(padapter, false);
2988
2989         //  ==== Pull GPIO PIN to balance level and LED control ======
2990         _DisableGPIO(padapter);
2991
2992         //  ==== Disable analog sequence ===
2993         _DisableAnalog(padapter, false);
2994
2995         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======> Card disable finished.\n"));
2996
2997         return rtStatus;
2998 }
2999
3000 // without HW Auto state machine
3001 s32 CardDisableWithoutHWSM(PADAPTER padapter)
3002 {
3003         s32 rtStatus = _SUCCESS;
3004
3005
3006         if (padapter->bSurpriseRemoved)
3007                 return rtStatus;
3008
3009         //==== RF Off Sequence ====
3010         _DisableRFAFEAndResetBB(padapter);
3011
3012         //  ==== Reset digital sequence   ======
3013         _ResetDigitalProcedure1(padapter, true);
3014
3015         //  ==== Pull GPIO PIN to balance level and LED control ======
3016         _DisableGPIO(padapter);
3017
3018         //  ==== Reset digital sequence   ======
3019         _ResetDigitalProcedure2(padapter);
3020
3021         //  ==== Disable analog sequence ===
3022         _DisableAnalog(padapter, true);
3023
3024         //RT_TRACE(COMP_INIT, DBG_LOUD, ("<====== Card Disable Without HWSM .\n"));
3025         return rtStatus;
3026 }
3027
3028 void
3029 Hal_InitPGData(
3030         PADAPTER        padapter,
3031         u8                      *PROMContent)
3032 {
3033         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
3034 //      HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3035         u32                     i;
3036         u16                     value16;
3037
3038         if (false == pEEPROM->bautoload_fail_flag)
3039         { // autoload OK.
3040 //              if (IS_BOOT_FROM_EEPROM(padapter))
3041                 if (true == pEEPROM->EepromOrEfuse)
3042                 {
3043                         // Read all Content from EEPROM or EFUSE.
3044                         for (i = 0; i < HWSET_MAX_SIZE; i += 2)
3045                         {
3046 //                              value16 = EF2Byte(ReadEEprom(pAdapter, (u2Byte) (i>>1)));
3047 //                              *((u16*)(&PROMContent[i])) = value16;
3048                         }
3049                 }
3050                 else
3051                 {
3052                         // Read EFUSE real map to shadow.
3053                         EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
3054                         memcpy((void*)PROMContent, (void*)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE);
3055                 }
3056         }
3057         else
3058         {//autoload fail
3059                 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n"));
3060 //              pHalData->AutoloadFailFlag = true;
3061                 //update to default value 0xFF
3062                 if (false == pEEPROM->EepromOrEfuse)
3063                         EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
3064                 memcpy((void*)PROMContent, (void*)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE);
3065         }
3066 }
3067
3068 void
3069 Hal_EfuseParseIDCode(
3070         IN      PADAPTER        padapter,
3071         IN      u8                      *hwinfo
3072         )
3073 {
3074         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
3075 //      HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3076         u16                     EEPROMId;
3077
3078
3079         // Checl 0x8129 again for making sure autoload status!!
3080         EEPROMId = le16_to_cpu(*((u16*)hwinfo));
3081         if (EEPROMId != RTL_EEPROM_ID)
3082         {
3083                 DBG_8192C("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
3084                 pEEPROM->bautoload_fail_flag = true;
3085         }
3086         else
3087         {
3088                 pEEPROM->bautoload_fail_flag = false;
3089         }
3090
3091         RT_TRACE(_module_hal_init_c_, _drv_info_, ("EEPROM ID=0x%04x\n", EEPROMId));
3092 }
3093
3094 static void
3095 Hal_EEValueCheck(
3096         IN              u8              EEType,
3097         IN              void *          pInValue,
3098         OUT             void *          pOutValue
3099         )
3100 {
3101         switch (EEType)
3102         {
3103                 case EETYPE_TX_PWR:
3104                         {
3105                                 u8      *pIn, *pOut;
3106                                 pIn = (u8*)pInValue;
3107                                 pOut = (u8*)pOutValue;
3108                                 if (*pIn >= 0 && *pIn <= 63)
3109                                 {
3110                                         *pOut = *pIn;
3111                                 }
3112                                 else
3113                                 {
3114                                         RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("EETYPE_TX_PWR, value=%d is invalid, set to default=0x%x\n",
3115                                                 *pIn, EEPROM_Default_TxPowerLevel));
3116                                         *pOut = EEPROM_Default_TxPowerLevel;
3117                                 }
3118                         }
3119                         break;
3120                 default:
3121                         break;
3122         }
3123 }
3124
3125 static void
3126 Hal_ReadPowerValueFromPROM_8723A(
3127         IN      PTxPowerInfo    pwrInfo,
3128         IN      u8*                     PROMContent,
3129         IN      bool                    AutoLoadFail
3130         )
3131 {
3132         u32 rfPath, eeAddr, group, rfPathMax=1;
3133
3134         memset(pwrInfo, 0, sizeof(TxPowerInfo));
3135
3136         if (AutoLoadFail)
3137         {
3138                 for (group = 0; group < MAX_CHNL_GROUP; group++)
3139                 {
3140                         for (rfPath = 0 ; rfPath < rfPathMax ; rfPath++)
3141                         {
3142                                 pwrInfo->CCKIndex[rfPath][group]                = EEPROM_Default_TxPowerLevel;
3143                                 pwrInfo->HT40_1SIndex[rfPath][group]    = EEPROM_Default_TxPowerLevel;
3144                                 pwrInfo->HT40_2SIndexDiff[rfPath][group]= EEPROM_Default_HT40_2SDiff;
3145                                 pwrInfo->HT20IndexDiff[rfPath][group]   = EEPROM_Default_HT20_Diff;
3146                                 pwrInfo->OFDMIndexDiff[rfPath][group]   = EEPROM_Default_LegacyHTTxPowerDiff;
3147                                 pwrInfo->HT40MaxOffset[rfPath][group]   = EEPROM_Default_HT40_PwrMaxOffset;
3148                                 pwrInfo->HT20MaxOffset[rfPath][group]   = EEPROM_Default_HT20_PwrMaxOffset;
3149                         }
3150                 }
3151                 pwrInfo->TSSI_A[0] = EEPROM_Default_TSSI;
3152                 return;
3153         }
3154
3155         for (rfPath = 0 ; rfPath < rfPathMax ; rfPath++)
3156         {
3157                 for (group = 0; group < MAX_CHNL_GROUP; group++)
3158                 {
3159                         eeAddr = EEPROM_CCK_TX_PWR_INX_8723A + (rfPath * 3) + group;
3160                         //pwrInfo->CCKIndex[rfPath][group] = PROMContent[eeAddr];
3161                         Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr], &pwrInfo->CCKIndex[rfPath][group]);
3162                         eeAddr = EEPROM_HT40_1S_TX_PWR_INX_8723A + (rfPath * 3) + group;
3163                         //pwrInfo->HT40_1SIndex[rfPath][group] = PROMContent[eeAddr];
3164                         Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr], &pwrInfo->HT40_1SIndex[rfPath][group]);
3165                 }
3166         }
3167
3168         for (group = 0; group < MAX_CHNL_GROUP; group++)
3169         {
3170                 for (rfPath = 0 ; rfPath < rfPathMax ; rfPath++)
3171                 {
3172                         pwrInfo->HT40_2SIndexDiff[rfPath][group] = 0;
3173                         pwrInfo->HT20IndexDiff[rfPath][group] =
3174                         (PROMContent[EEPROM_HT20_TX_PWR_INX_DIFF_8723A + group] >> (rfPath * 4)) & 0xF;
3175                         if (pwrInfo->HT20IndexDiff[rfPath][group] & BIT3)       //4bit sign number to 8 bit sign number
3176                                 pwrInfo->HT20IndexDiff[rfPath][group] |= 0xF0;
3177
3178                         pwrInfo->OFDMIndexDiff[rfPath][group] =
3179                         (PROMContent[EEPROM_OFDM_TX_PWR_INX_DIFF_8723A + group] >> (rfPath * 4)) & 0xF;
3180
3181                         pwrInfo->HT40MaxOffset[rfPath][group] =
3182                         (PROMContent[EEPROM_HT40_MAX_PWR_OFFSET_8723A + group] >> (rfPath * 4)) & 0xF;
3183
3184                         pwrInfo->HT20MaxOffset[rfPath][group] =
3185                         (PROMContent[EEPROM_HT20_MAX_PWR_OFFSET_8723A + group] >> (rfPath * 4)) & 0xF;
3186                 }
3187         }
3188
3189         pwrInfo->TSSI_A[0] = PROMContent[EEPROM_TSSI_A_8723A];
3190 }
3191
3192 static u8
3193 Hal_GetChnlGroup(
3194         IN      u8 chnl
3195         )
3196 {
3197         u8      group=0;
3198
3199         if (chnl < 3)                   // Cjanel 1-3
3200                 group = 0;
3201         else if (chnl < 9)              // Channel 4-9
3202                 group = 1;
3203         else                                    // Channel 10-14
3204                 group = 2;
3205
3206         return group;
3207 }
3208
3209 void
3210 Hal_EfuseParseTxPowerInfo_8723A(
3211         IN      PADAPTER                padapter,
3212         IN      u8*                     PROMContent,
3213         IN      bool                    AutoLoadFail
3214         )
3215 {
3216         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3217         TxPowerInfo             pwrInfo;
3218         u8                      rfPath, ch, group, rfPathMax=1;
3219         u8                      pwr, diff;
3220
3221         Hal_ReadPowerValueFromPROM_8723A(&pwrInfo, PROMContent, AutoLoadFail);
3222         for (rfPath = 0 ; rfPath < rfPathMax ; rfPath++)
3223         {
3224                 for (ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3225                 {
3226                         group = Hal_GetChnlGroup(ch);
3227
3228                         pHalData->TxPwrLevelCck[rfPath][ch] = pwrInfo.CCKIndex[rfPath][group];
3229                         pHalData->TxPwrLevelHT40_1S[rfPath][ch] = pwrInfo.HT40_1SIndex[rfPath][group];
3230
3231                         pHalData->TxPwrHt20Diff[rfPath][ch] = pwrInfo.HT20IndexDiff[rfPath][group];
3232                         pHalData->TxPwrLegacyHtDiff[rfPath][ch] = pwrInfo.OFDMIndexDiff[rfPath][group];
3233                         pHalData->PwrGroupHT20[rfPath][ch] = pwrInfo.HT20MaxOffset[rfPath][group];
3234                         pHalData->PwrGroupHT40[rfPath][ch] = pwrInfo.HT40MaxOffset[rfPath][group];
3235
3236                         pwr     = pwrInfo.HT40_1SIndex[rfPath][group];
3237                         diff    = pwrInfo.HT40_2SIndexDiff[rfPath][group];
3238
3239                         pHalData->TxPwrLevelHT40_2S[rfPath][ch] = (pwr > diff) ? (pwr - diff) : 0;
3240                 }
3241         }
3242 #if 1
3243         for (rfPath = 0 ; rfPath < RF_PATH_MAX ; rfPath++)
3244         {
3245                 for (ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3246                 {
3247                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
3248                                 ("RF(%u)-Ch(%u) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
3249                                 rfPath, ch, pHalData->TxPwrLevelCck[rfPath][ch],
3250                                 pHalData->TxPwrLevelHT40_1S[rfPath][ch],
3251                                 pHalData->TxPwrLevelHT40_2S[rfPath][ch]));
3252
3253                 }
3254         }
3255         for (ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3256         {
3257                 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("RF-A Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
3258                         pHalData->TxPwrHt20Diff[RF_PATH_A][ch], pHalData->TxPwrHt20Diff[RF_PATH_A][ch]));
3259         }
3260         for (ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3261         {
3262                 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("RF-A Legacy to Ht40 Diff[%u] = 0x%x\n", ch, pHalData->TxPwrLegacyHtDiff[RF_PATH_A][ch]));
3263         }
3264         for (ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3265         {
3266                 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("RF-B Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
3267                         pHalData->TxPwrHt20Diff[RF_PATH_B][ch], pHalData->TxPwrHt20Diff[RF_PATH_B][ch]));
3268         }
3269         for (ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3270         {
3271                 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("RF-B Legacy to HT40 Diff[%u] = 0x%x\n", ch, pHalData->TxPwrLegacyHtDiff[RF_PATH_B][ch]));
3272         }
3273 #endif
3274         if (!AutoLoadFail)
3275         {
3276                 pHalData->EEPROMRegulatory = PROMContent[RF_OPTION1_8723A]&0x7; //bit0~2
3277         }
3278         else
3279         {
3280                 pHalData->EEPROMRegulatory = 0;
3281         }
3282         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory));
3283
3284         if (!AutoLoadFail)
3285                 pHalData->bTXPowerDataReadFromEEPORM = true;
3286 }
3287
3288 void
3289 Hal_EfuseParseBTCoexistInfo_8723A(
3290         IN PADAPTER                     padapter,
3291         IN u8*                  hwinfo,
3292         IN bool                 AutoLoadFail
3293         )
3294 {
3295         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
3296         u8                      tempval;
3297         u32                     tmpu4;
3298
3299         if (!AutoLoadFail)
3300         {
3301                 tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
3302                 if (tmpu4 & BT_FUNC_EN)
3303                         pHalData->EEPROMBluetoothCoexist = 1;
3304                 else
3305                         pHalData->EEPROMBluetoothCoexist = 0;
3306                 pHalData->EEPROMBluetoothType = BT_RTL8723A;
3307
3308                 // The following need to be checked with newer version of
3309                 // eeprom spec
3310                 tempval = hwinfo[RF_OPTION4_8723A];
3311                 pHalData->EEPROMBluetoothAntNum = (tempval&0x1);                                        // bit [0]
3312                 pHalData->EEPROMBluetoothAntIsolation = ((tempval&0x10)>>4);                    // bit [4]
3313                 pHalData->EEPROMBluetoothRadioShared = ((tempval&0x20)>>5);             // bit [5]
3314         }
3315         else
3316         {
3317                 pHalData->EEPROMBluetoothCoexist = 0;
3318                 pHalData->EEPROMBluetoothType = BT_RTL8723A;
3319                 pHalData->EEPROMBluetoothAntNum = Ant_x2;
3320                 pHalData->EEPROMBluetoothAntIsolation = 0;
3321                 pHalData->EEPROMBluetoothRadioShared = BT_Radio_Shared;
3322         }
3323 #ifdef CONFIG_BT_COEXIST
3324         BT_InitHalVars(padapter);
3325 #endif
3326 }
3327
3328 void
3329 Hal_EfuseParseEEPROMVer(
3330         IN      PADAPTER                padapter,
3331         IN      u8*                     hwinfo,
3332         IN      bool                    AutoLoadFail
3333         )
3334 {
3335         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3336
3337         if (!AutoLoadFail)
3338                 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723A];
3339         else
3340                 pHalData->EEPROMVersion = 1;
3341         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
3342                 pHalData->EEPROMVersion));
3343 }
3344
3345 void
3346 rtl8723a_EfuseParseChnlPlan(
3347         IN      PADAPTER                padapter,
3348         IN      u8*                     hwinfo,
3349         IN      bool                    AutoLoadFail
3350         )
3351 {
3352         padapter->mlmepriv.ChannelPlan = hal_com_get_channel_plan(
3353                 padapter
3354                 , hwinfo?hwinfo[EEPROM_ChannelPlan_8723A]:0xFF
3355                 , padapter->registrypriv.channel_plan
3356                 , RT_CHANNEL_DOMAIN_WORLD_WIDE_13
3357                 , AutoLoadFail
3358         );
3359
3360         DBG_871X("mlmepriv.ChannelPlan=0x%02x\n", padapter->mlmepriv.ChannelPlan);
3361 }
3362
3363 void
3364 Hal_EfuseParseCustomerID(
3365         IN      PADAPTER                padapter,
3366         IN      u8*                     hwinfo,
3367         IN      bool                    AutoLoadFail
3368         )
3369 {
3370         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
3371
3372         if (!AutoLoadFail)
3373         {
3374                 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723A];
3375                 pHalData->EEPROMSubCustomerID = hwinfo[EEPROM_SubCustomID_8723A];
3376         }
3377         else
3378         {
3379                 pHalData->EEPROMCustomerID = 0;
3380                 pHalData->EEPROMSubCustomerID = 0;
3381         }
3382         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID));
3383         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("EEPROM SubCustomer ID: 0x%02x\n", pHalData->EEPROMSubCustomerID));
3384 }
3385
3386 void
3387 Hal_EfuseParseAntennaDiversity(
3388         IN      PADAPTER                padapter,
3389         IN      u8*                     hwinfo,
3390         IN      bool                    AutoLoadFail
3391         )
3392 {
3393 }
3394
3395 void
3396 Hal_EfuseParseRateIndicationOption(
3397         IN      PADAPTER                padapter,
3398         IN      u8*                     hwinfo,
3399         IN      bool                    AutoLoadFail
3400         )
3401 {
3402 }
3403
3404 void
3405 Hal_EfuseParseXtal_8723A(
3406         PADAPTER                pAdapter,
3407         u8                      *hwinfo,
3408         u8                      AutoLoadFail
3409         )
3410 {
3411         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(pAdapter);
3412
3413         if (!AutoLoadFail){
3414                 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_K_8723A];
3415                 if (pHalData->CrystalCap == 0xFF)
3416                         pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
3417         }
3418         else{
3419                 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
3420         }
3421         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("%s: CrystalCap=0x%2x\n", __FUNCTION__, pHalData->CrystalCap));
3422 }
3423
3424 void
3425 Hal_EfuseParseThermalMeter_8723A(
3426         PADAPTER        padapter,
3427         u8                      *PROMContent,
3428         u8                      AutoloadFail
3429         )
3430 {
3431         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
3432
3433
3434         //
3435         // ThermalMeter from EEPROM
3436         //
3437         if (false == AutoloadFail)
3438                 pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8723A];
3439         else
3440                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3441
3442         if ((pHalData->EEPROMThermalMeter == 0xff) || (true == AutoloadFail))
3443         {
3444                 pHalData->bAPKThermalMeterIgnore = true;
3445                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3446         }
3447
3448         DBG_8192C("%s: ThermalMeter=0x%x\n", __FUNCTION__, pHalData->EEPROMThermalMeter);
3449 }
3450
3451 void Hal_InitChannelPlan(IN             PADAPTER        padapter)
3452 {
3453 }
3454
3455 void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc)
3456 {
3457         u16     *usPtr = (u16*)ptxdesc;
3458         u32 count = 16;         // (32 bytes / 2 bytes per XOR) => 16 times
3459         u32 index;
3460         u16 checksum = 0;
3461
3462
3463         // Clear first
3464         ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
3465
3466         for (index = 0; index < count; index++) {
3467                 checksum ^= le16_to_cpu(*(usPtr + index));
3468         }
3469
3470         ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
3471 }
3472
3473 static void fill_txdesc_sectype(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
3474 {
3475         if ((pattrib->encrypt > 0) && !pattrib->bswenc)
3476         {
3477                 switch (pattrib->encrypt)
3478                 {
3479                         // SEC_TYPE
3480                         case _WEP40_:
3481                         case _WEP104_:
3482                         case _TKIP_:
3483                         case _TKIP_WTMIC_:
3484                                 ptxdesc->sectype = 1;
3485                                 break;
3486
3487 #ifdef CONFIG_WAPI_SUPPORT
3488                         case _SMS4_:
3489                                 ptxdesc->sectype = 2;
3490                                 break;
3491 #endif
3492                         case _AES_:
3493                                 ptxdesc->sectype = 3;
3494                                 break;
3495
3496                         case _NO_PRIVACY_:
3497                         default:
3498                                         break;
3499                 }
3500         }
3501 }
3502
3503 static void fill_txdesc_vcs(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
3504 {
3505         //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
3506
3507         switch (pattrib->vcs_mode)
3508         {
3509                 case RTS_CTS:
3510                         ptxdesc->rtsen = 1;
3511                         break;
3512
3513                 case CTS_TO_SELF:
3514                         ptxdesc->cts2self = 1;
3515                         break;
3516
3517                 case NONE_VCS:
3518                 default:
3519                         break;
3520         }
3521
3522         if (pattrib->vcs_mode) {
3523                 ptxdesc->hw_rts_en = 1; // ENABLE HW RTS
3524
3525                 // Set RTS BW
3526                 if (pattrib->ht_en)
3527                 {
3528                         if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
3529                                 ptxdesc->rts_bw = 1;
3530
3531                         switch (pattrib->ch_offset)
3532                         {
3533                                 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
3534                                         ptxdesc->rts_sc = 0;
3535                                         break;
3536
3537                                 case HAL_PRIME_CHNL_OFFSET_LOWER:
3538                                         ptxdesc->rts_sc = 1;
3539                                         break;
3540
3541                                 case HAL_PRIME_CHNL_OFFSET_UPPER:
3542                                         ptxdesc->rts_sc = 2;
3543                                         break;
3544
3545                                 default:
3546                                         ptxdesc->rts_sc = 3; // Duplicate
3547                                         break;
3548                         }
3549                 }
3550         }
3551 }
3552
3553 static void fill_txdesc_phy(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
3554 {
3555         //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
3556
3557         if (pattrib->ht_en)
3558         {
3559                 if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
3560                         ptxdesc->data_bw = 1;
3561
3562                 switch (pattrib->ch_offset)
3563                 {
3564                         case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
3565                                 ptxdesc->data_sc = 0;
3566                                 break;
3567
3568                         case HAL_PRIME_CHNL_OFFSET_LOWER:
3569                                 ptxdesc->data_sc = 1;
3570                                 break;
3571
3572                         case HAL_PRIME_CHNL_OFFSET_UPPER:
3573                                 ptxdesc->data_sc = 2;
3574                                 break;
3575
3576                         default:
3577                                 ptxdesc->data_sc = 3; // Duplicate
3578                                 break;
3579                 }
3580         }
3581 }
3582
3583 void rtl8723a_fill_default_txdesc(
3584         struct xmit_frame *pxmitframe,
3585         u8 *pbuf)
3586 {
3587         PADAPTER padapter;
3588         HAL_DATA_TYPE *pHalData;
3589         struct dm_priv *pdmpriv;
3590         struct mlme_ext_priv *pmlmeext;
3591         struct mlme_ext_info *pmlmeinfo;
3592         struct pkt_attrib *pattrib;
3593         PTXDESC ptxdesc;
3594         s32 bmcst;
3595
3596
3597         padapter = pxmitframe->padapter;
3598         pHalData = GET_HAL_DATA(padapter);
3599         pdmpriv = &pHalData->dmpriv;
3600         pmlmeext = &padapter->mlmeextpriv;
3601         pmlmeinfo = &(pmlmeext->mlmext_info);
3602
3603         pattrib = &pxmitframe->attrib;
3604         bmcst = IS_MCAST(pattrib->ra);
3605
3606         ptxdesc = (PTXDESC)pbuf;
3607
3608         if (pxmitframe->frame_tag == DATA_FRAMETAG)
3609         {
3610                 ptxdesc->macid = pattrib->mac_id; // CAM_ID(MAC_ID)
3611
3612                 if (pattrib->ampdu_en == true)
3613                         ptxdesc->agg_en = 1; // AGG EN
3614                 else
3615                         ptxdesc->bk = 1; // AGG BK
3616
3617                 ptxdesc->qsel = pattrib->qsel;
3618                 ptxdesc->rate_id = pattrib->raid;
3619
3620                 fill_txdesc_sectype(pattrib, ptxdesc);
3621
3622                 ptxdesc->seq = pattrib->seqnum;
3623
3624                 if ((pattrib->ether_type != 0x888e) &&
3625                         (pattrib->ether_type != 0x0806) &&
3626                         (pattrib->dhcp_pkt != 1))
3627                 {
3628                         // Non EAP & ARP & DHCP type data packet
3629
3630                         fill_txdesc_vcs(pattrib, ptxdesc);
3631                         fill_txdesc_phy(pattrib, ptxdesc);
3632
3633                         ptxdesc->rtsrate = 8; // RTS Rate=24M
3634                         ptxdesc->data_ratefb_lmt = 0x1F;
3635                         ptxdesc->rts_ratefb_lmt = 0xF;
3636
3637                         // use REG_INIDATA_RATE_SEL value
3638                         ptxdesc->datarate = pdmpriv->INIDATA_RATE[pattrib->mac_id];
3639
3640                 } else {
3641                         // EAP data packet and ARP packet.
3642                         // Use the 1M data rate to send the EAP/ARP packet.
3643                         // This will maybe make the handshake smooth.
3644
3645                         ptxdesc->bk = 1; // AGG BK
3646                         ptxdesc->userate = 1; // driver uses rate
3647                         if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
3648                                 ptxdesc->data_short = 1;// DATA_SHORT
3649                         ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
3650                 }
3651 #if defined(CONFIG_USB_TX_AGGREGATION)
3652                 ptxdesc->usb_txagg_num = pxmitframe->agg_num;
3653 #endif
3654         } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) {
3655                 ptxdesc->macid = pattrib->mac_id; // CAM_ID(MAC_ID)
3656                 ptxdesc->qsel = pattrib->qsel;
3657                 ptxdesc->rate_id = pattrib->raid; // Rate ID
3658                 ptxdesc->seq = pattrib->seqnum;
3659                 ptxdesc->userate = 1; // driver uses rate, 1M
3660                 ptxdesc->rty_lmt_en = 1; // retry limit enable
3661                 ptxdesc->data_rt_lmt = 6; // retry limit = 6
3662
3663 #ifdef CONFIG_XMIT_ACK
3664                 //CCX-TXRPT ack for xmit mgmt frames.
3665                 if (pxmitframe->ack_report) {
3666                         ptxdesc->ccx = 1;
3667                 }
3668 #endif //CONFIG_XMIT_ACK
3669
3670 #ifdef CONFIG_INTEL_PROXIM
3671                 if ((padapter->proximity.proxim_on==true)&&(pattrib->intel_proxim==true)){
3672                         DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
3673                         ptxdesc->datarate = pattrib->rate;
3674                 }
3675                 else
3676 #endif
3677                 {
3678                         ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
3679                 }
3680         }
3681         else if (pxmitframe->frame_tag == TXAGG_FRAMETAG)
3682         {
3683                 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: TXAGG_FRAMETAG\n", __FUNCTION__));
3684         }
3685 #ifdef CONFIG_MP_INCLUDED
3686         else if (pxmitframe->frame_tag == MP_FRAMETAG)
3687         {
3688                 struct tx_desc *pdesc;
3689
3690                 pdesc = (struct tx_desc*)ptxdesc;
3691                 RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MP_FRAMETAG\n", __FUNCTION__));
3692                 fill_txdesc_for_mp(padapter, pdesc);
3693
3694                 pdesc->txdw0 = le32_to_cpu(pdesc->txdw0);
3695                 pdesc->txdw1 = le32_to_cpu(pdesc->txdw1);
3696                 pdesc->txdw2 = le32_to_cpu(pdesc->txdw2);
3697                 pdesc->txdw3 = le32_to_cpu(pdesc->txdw3);
3698                 pdesc->txdw4 = le32_to_cpu(pdesc->txdw4);
3699                 pdesc->txdw5 = le32_to_cpu(pdesc->txdw5);
3700                 pdesc->txdw6 = le32_to_cpu(pdesc->txdw6);
3701                 pdesc->txdw7 = le32_to_cpu(pdesc->txdw7);
3702         }
3703 #endif
3704         else
3705         {
3706                 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: frame_tag=0x%x\n", __FUNCTION__, pxmitframe->frame_tag));
3707
3708                 ptxdesc->macid = 4; // CAM_ID(MAC_ID)
3709                 ptxdesc->rate_id = 6; // Rate ID
3710                 ptxdesc->seq = pattrib->seqnum;
3711                 ptxdesc->userate = 1; // driver uses rate
3712                 ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
3713         }
3714
3715         ptxdesc->pktlen = pattrib->last_txcmdsz;
3716         ptxdesc->offset = TXDESC_SIZE + OFFSET_SZ;
3717         if (bmcst) ptxdesc->bmc = 1;
3718         ptxdesc->ls = 1;
3719         ptxdesc->fs = 1;
3720         ptxdesc->own = 1;
3721
3722         // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
3723         // (1) The sequence number of each non-Qos frame / broadcast / multicast /
3724         // mgnt frame should be controled by Hw because Fw will also send null data
3725         // which we cannot control when Fw LPS enable.
3726         // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
3727         // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
3728         // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
3729         // 2010.06.23. Added by tynli.
3730         if (!pattrib->qos_en)
3731         {
3732                 // Hw set sequence number
3733                 ptxdesc->hwseq_en = 1; // HWSEQ_EN
3734                 ptxdesc->hwseq_sel = 0; // HWSEQ_SEL
3735         }
3736 }
3737
3738 /*
3739  *      Description:
3740  *
3741  *      Parameters:
3742  *              pxmitframe      xmitframe
3743  *              pbuf            where to fill tx desc
3744  */
3745 void rtl8723a_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
3746 {
3747         struct tx_desc *pdesc;
3748
3749
3750         pdesc = (struct tx_desc*)pbuf;
3751         memset(pdesc, 0, sizeof(struct tx_desc));
3752
3753         rtl8723a_fill_default_txdesc(pxmitframe, pbuf);
3754
3755         pdesc->txdw0 = cpu_to_le32(pdesc->txdw0);
3756         pdesc->txdw1 = cpu_to_le32(pdesc->txdw1);
3757         pdesc->txdw2 = cpu_to_le32(pdesc->txdw2);
3758         pdesc->txdw3 = cpu_to_le32(pdesc->txdw3);
3759         pdesc->txdw4 = cpu_to_le32(pdesc->txdw4);
3760         pdesc->txdw5 = cpu_to_le32(pdesc->txdw5);
3761         pdesc->txdw6 = cpu_to_le32(pdesc->txdw6);
3762         pdesc->txdw7 = cpu_to_le32(pdesc->txdw7);
3763
3764         rtl8723a_cal_txdesc_chksum(pdesc);
3765 }
3766
3767 //
3768 // Description: In normal chip, we should send some packet to Hw which will be used by Fw
3769 //                      in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
3770 //                      Fw can tell Hw to send these packet derectly.
3771 // Added by tynli. 2009.10.15.
3772 //
3773 void rtl8723a_fill_fake_txdesc(
3774         PADAPTER        padapter,
3775         u8*                     pDesc,
3776         u32                     BufferLen,
3777         u8                      IsPsPoll,
3778         u8                      IsBTQosNull)
3779 {
3780         struct tx_desc *ptxdesc;
3781
3782
3783         // Clear all status
3784         ptxdesc = (struct tx_desc*)pDesc;
3785         memset(pDesc, 0, TXDESC_SIZE);
3786
3787         //offset 0
3788         ptxdesc->txdw0 |= cpu_to_le32( OWN | FSG | LSG); //own, bFirstSeg, bLastSeg;
3789
3790         ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000); //32 bytes for TX Desc
3791
3792         ptxdesc->txdw0 |= cpu_to_le32(BufferLen&0x0000ffff); // Buffer size + command header
3793
3794         //offset 4
3795         ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT<<QSEL_SHT)&0x00001f00); // Fixed queue of Mgnt queue
3796
3797         //Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
3798         if (IsPsPoll)
3799         {
3800                 ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
3801         }
3802         else
3803         {
3804                 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
3805                 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
3806         }
3807
3808         if (true == IsBTQosNull)
3809         {
3810                 ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); // BT NULL
3811         }
3812
3813         //offset 16
3814         ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
3815
3816         // USB interface drop packet if the checksum of descriptor isn't correct.
3817         // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
3818         rtl8723a_cal_txdesc_chksum(ptxdesc);
3819 }
3820
3821 #ifdef CONFIG_CONCURRENT_MODE
3822 int reset_tsf(PADAPTER Adapter, u8 reset_port )
3823 {
3824         u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
3825         u32 reg_reset_tsf_cnt = (IFACE_PORT0==reset_port) ?
3826                                 REG_FW_RESET_TSF_CNT_0:REG_FW_RESET_TSF_CNT_1;
3827
3828         rtw_scan_abort(Adapter->pbuddy_adapter);        /*      site survey will cause reset_tsf fail   */
3829         reset_cnt_after = reset_cnt_before = rtw_read8(Adapter,reg_reset_tsf_cnt);
3830         rtl8723c_reset_tsf(Adapter, reset_port);
3831
3832         while ((reset_cnt_after == reset_cnt_before ) && (loop_cnt < 10)) {
3833                 rtw_msleep_os(100);
3834                 loop_cnt++;
3835                 reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt);
3836         }
3837
3838         return(loop_cnt >= 10) ? _FAIL : true;
3839 }
3840 #endif
3841
3842 static void hw_var_set_opmode(PADAPTER padapter, u8 variable, u8 *val)
3843 {
3844         u8 val8;
3845         u8 mode = *val;
3846         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3847
3848
3849         if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
3850         {
3851 #ifdef CONFIG_CONCURRENT_MODE
3852                 if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
3853 #endif
3854                 {
3855                         StopTxBeacon(padapter);
3856                 }
3857
3858                 // disable atim wnd
3859                 val8 = DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_ATIM;
3860                 SetBcnCtrlReg(padapter, val8, ~val8);
3861         }
3862         else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
3863         {
3864                 ResumeTxBeacon(padapter);
3865
3866                 val8 = DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB;
3867                 SetBcnCtrlReg(padapter, val8, ~val8);
3868         }
3869         else if (mode == _HW_STATE_AP_)
3870         {
3871 #ifdef CONFIG_BT_COEXIST
3872                 // add NULL Data and BT NULL Data Packets to FW RSVD Page
3873                 rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(padapter);
3874 #endif
3875
3876                 ResumeTxBeacon(padapter);
3877
3878                 val8 = DIS_TSF_UDT|DIS_BCNQ_SUB;
3879                 SetBcnCtrlReg(padapter, val8, ~val8);
3880
3881                 // Set RCR
3882                 //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
3883                 rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0
3884                 // enable to rx data frame
3885                 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
3886                 // enable to rx ps-poll
3887                 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
3888
3889                 // Beacon Control related register for first time
3890                 rtw_write8(padapter, REG_BCNDMATIM, 0x02); // 2ms
3891                 rtw_write8(padapter, REG_DRVERLYINT, 0x05); // 5ms
3892                 //rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
3893 #ifdef CONFIG_CONCURRENT_MODE
3894                 if (padapter->iface_type == IFACE_PORT1)
3895                         rtw_write8(padapter, REG_ATIMWND_1, 0x0a); // 10ms for port1
3896                 else
3897 #endif
3898                 {
3899                         rtw_write8(padapter, REG_ATIMWND, 0x0a); // 10ms for port0
3900                 }
3901                 rtw_write16(padapter, REG_BCNTCFG, 0x00);
3902                 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
3903                 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
3904
3905                 // reset TSF
3906 #ifdef CONFIG_CONCURRENT_MODE
3907                 if (padapter->iface_type == IFACE_PORT1)
3908                         rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
3909                 else
3910 #endif
3911                 {
3912                         rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
3913                 }
3914
3915                 // enable BCN Function
3916                 // don't enable update TSF (due to TSF update when beacon/probe rsp are received)
3917                 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB;
3918                 SetBcnCtrlReg(padapter, val8, ~val8);
3919
3920                 // dis BCN ATIM WND of another port if it is station
3921 #ifdef CONFIG_CONCURRENT_MODE
3922                 if (padapter->iface_type == IFACE_PORT1) {
3923                         if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
3924                                 rtw_write8(padapter, REG_BCN_CTRL,
3925                                         rtw_read8(padapter, REG_BCN_CTRL) & ~EN_BCN_FUNCTION);
3926                 } else {
3927                         if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
3928                                 rtw_write8(padapter, REG_BCN_CTRL_1,
3929                                         rtw_read8(padapter, REG_BCN_CTRL_1) & ~EN_BCN_FUNCTION);
3930                 }
3931
3932                 if (padapter->pbuddy_adapter)
3933                         SetBcnCtrlReg(padapter->pbuddy_adapter, DIS_ATIM, 0);
3934 #else
3935 //              val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
3936 //              val8 |= DIS_ATIM;
3937 //              rtw_write8(padapter, REG_BCN_CTRL_1, val8);
3938 #endif
3939
3940 #ifdef CONFIG_TSF_RESET_OFFLOAD
3941                 // Reset TSF for STA+AP concurrent mode
3942                 if ( check_buddy_fwstate(padapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)) ) {
3943                         if (reset_tsf(padapter, padapter->iface_type) == false)
3944                                 DBG_871X("ERROR! %s()-%d: Reset port%d TSF fail\n",
3945                                         __FUNCTION__, __LINE__,
3946                                         (padapter->iface_type==IFACE_PORT1)? 1 : 0);
3947                 }
3948 #endif  // CONFIG_TSF_RESET_OFFLOAD
3949         }
3950
3951         val8 = rtw_read8(padapter, MSR);
3952 #ifdef CONFIG_CONCURRENT_MODE
3953         if (padapter->iface_type == IFACE_PORT1)
3954                 val8 = (val8 & 0x3) | (mode << 2);
3955         else
3956 #endif
3957         {
3958                 val8 = (val8 & 0xC) | mode;
3959         }
3960         rtw_write8(padapter, MSR, val8);
3961 }
3962
3963 static void hw_var_set_macaddr(PADAPTER padapter, u8 variable, u8 *val)
3964 {
3965         u8 idx = 0;
3966         u32 reg_macid;
3967
3968 #ifdef CONFIG_CONCURRENT_MODE
3969         if (padapter->iface_type == IFACE_PORT1)
3970         {
3971                 reg_macid = REG_MACID1;
3972         }
3973         else
3974 #endif
3975         {
3976                 reg_macid = REG_MACID;
3977         }
3978
3979         for (idx = 0 ; idx < 6; idx++)
3980         {
3981                 rtw_write8(padapter, (reg_macid+idx), val[idx]);
3982         }
3983 }
3984
3985 static void hw_var_set_bssid(PADAPTER padapter, u8 variable, u8 *val)
3986 {
3987         u8      idx = 0;
3988         u32 reg_bssid;
3989
3990 #ifdef CONFIG_CONCURRENT_MODE
3991         if (padapter->iface_type == IFACE_PORT1)
3992         {
3993                 reg_bssid = REG_BSSID1;
3994         }
3995         else
3996 #endif
3997         {
3998                 reg_bssid = REG_BSSID;
3999         }
4000
4001         for (idx = 0 ; idx < 6; idx++)
4002         {
4003                 rtw_write8(padapter, (reg_bssid+idx), val[idx]);
4004         }
4005 }
4006
4007 static void hw_var_set_correct_tsf(PADAPTER padapter, u8 variable, u8 *val)
4008 {
4009         u64 tsf;
4010         u32 reg_tsftr;
4011         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4012         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4013
4014
4015         //tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue % (pmlmeinfo->bcn_interval*1024)) - 1024; //us
4016         tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) - 1024; //us
4017
4018         if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
4019                 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
4020         {
4021                 //pHalData->RegTxPause |= STOP_BCNQ;BIT(6)
4022                 //rtw_write8(padapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)|BIT(6)));
4023                 StopTxBeacon(padapter);
4024         }
4025
4026 #ifdef CONFIG_CONCURRENT_MODE
4027         if (padapter->iface_type == IFACE_PORT1)
4028         {
4029                 reg_tsftr = REG_TSFTR1;
4030         }
4031         else
4032 #endif
4033         {
4034                 reg_tsftr = REG_TSFTR;
4035         }
4036
4037         // disable related TSF function
4038         SetBcnCtrlReg(padapter, 0, EN_BCN_FUNCTION);
4039
4040         rtw_write32(padapter, reg_tsftr, tsf);
4041         rtw_write32(padapter, reg_tsftr+4, tsf>>32);
4042
4043 #ifdef CONFIG_CONCURRENT_MODE
4044
4045         // Update buddy port's TSF if it is SoftAP for beacon TX issue!
4046         if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
4047                 && check_buddy_fwstate(padapter, WIFI_AP_STATE)
4048         ) {
4049                 //disable related TSF function
4050                 if (padapter->pbuddy_adapter)
4051                         SetBcnCtrlReg(padapter->pbuddy_adapter, 0, EN_BCN_FUNCTION);
4052                 if (padapter->iface_type == IFACE_PORT1)
4053                 {
4054                         reg_tsftr = REG_TSFTR;
4055                 }
4056                 else
4057                 {
4058                         reg_tsftr = REG_TSFTR1;
4059                 }
4060
4061                 rtw_write32(padapter, reg_tsftr, tsf);
4062                 rtw_write32(padapter, reg_tsftr+4, tsf>>32);
4063
4064                 //enable related TSF function
4065                 if (padapter->pbuddy_adapter)
4066                         SetBcnCtrlReg(padapter->pbuddy_adapter,  EN_BCN_FUNCTION,0);
4067         }
4068 #endif
4069         //enable related TSF function
4070         SetBcnCtrlReg(padapter, EN_BCN_FUNCTION, 0);
4071
4072 #ifdef CONFIG_TSF_RESET_OFFLOAD
4073         // Reset TSF for STA+AP concurrent mode
4074         if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
4075                         && check_buddy_fwstate(padapter, WIFI_AP_STATE) ) {
4076                 if (padapter->iface_type == IFACE_PORT1) {
4077                         if (reset_tsf(padapter, IFACE_PORT0) == false)
4078                                 DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
4079                                 __FUNCTION__, __LINE__);
4080                 } else {
4081                         if (reset_tsf(padapter, IFACE_PORT1) == false)
4082                                 DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
4083                                 __FUNCTION__, __LINE__);
4084                 }
4085         }
4086 #endif  // CONFIG_TSF_RESET_OFFLOAD
4087
4088         if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
4089                 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
4090         {
4091                 //pHalData->RegTxPause &= (~STOP_BCNQ);
4092                 //rtw_write8(padapter, REG_TXPAUSE, (rtw_read8(padapter, REG_TXPAUSE)&(~BIT(6))));
4093                 ResumeTxBeacon(padapter);
4094         }
4095 }
4096
4097 static void hw_var_set_mlme_disconnect(PADAPTER padapter, u8 variable, u8 *val)
4098 {
4099         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4100 #ifdef CONFIG_CONCURRENT_MODE
4101         if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
4102 #endif
4103         {
4104                 // Set RCR to not to receive data frame when NO LINK state
4105                 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF);
4106                 // reject all data frames
4107                 rtw_write16(padapter, REG_RXFLTMAP2, 0);
4108         }
4109
4110 #ifdef CONFIG_CONCURRENT_MODE
4111         if (padapter->iface_type == IFACE_PORT1)
4112         {
4113                 // reset TSF1
4114                 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
4115
4116                 // disable update TSF1
4117                 SetBcnCtrlReg(padapter, DIS_TSF_UDT, 0);
4118         }
4119         else
4120 #endif
4121         {
4122                 // reset TSF
4123                 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
4124
4125                 // disable update TSF
4126                 SetBcnCtrlReg(padapter, DIS_TSF_UDT, 0);
4127         }
4128 }
4129
4130 #ifdef CONFIG_CONCURRENT_MODE
4131 static void hw_var_set_mlme_sitesurvey(PADAPTER padapter, u8 variable, u8 *val)
4132 {
4133         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4134
4135         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4136         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4137         u32 v32;
4138
4139
4140         if (*val)//under sitesurvey
4141         {
4142                 // config RCR to receive different BSSID & not to receive data frame
4143                 v32 = rtw_read32(padapter, REG_RCR);
4144                 v32 &= ~(RCR_CBSSID_BCN);
4145                 rtw_write32(padapter, REG_RCR, v32);
4146
4147                 // disable update TSF
4148                 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
4149                         SetBcnCtrlReg(padapter, DIS_TSF_UDT, 0);
4150
4151                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
4152                         (check_buddy_fwstate(padapter, _FW_LINKED) == true))
4153                 {
4154                         StopTxBeacon(padapter);
4155                 }
4156         }
4157         else//sitesurvey done
4158         {
4159                 // enable to rx data frame
4160                 //write32(padapter, REG_RCR, read32(padapter, REG_RCR)|RCR_ADF);
4161                 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
4162
4163                 // enable update TSF
4164                 SetBcnCtrlReg(padapter, 0, DIS_TSF_UDT);
4165
4166                 v32 = rtw_read32(padapter, REG_RCR);
4167                 v32 |= RCR_CBSSID_BCN;
4168                 rtw_write32(padapter, REG_RCR, v32);
4169
4170                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
4171                         (check_buddy_fwstate(padapter, _FW_LINKED) == true))
4172                         ResumeTxBeacon(padapter);
4173         }
4174 }
4175 #endif
4176
4177 static void hw_var_set_mlme_join(PADAPTER padapter, u8 variable, u8 *val)
4178 {
4179         u8 RetryLimit = 0x30;
4180         u8 type = *val;
4181
4182         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4183         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4184
4185         if (type == 0) // prepare to join
4186         {
4187                 u32 v32;
4188
4189 #ifdef CONFIG_CONCURRENT_MODE
4190                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
4191                         (check_buddy_fwstate(padapter, _FW_LINKED) == true))
4192                 {
4193                         StopTxBeacon(padapter);
4194                 }
4195 #endif
4196
4197                 // enable to rx data frame.Accept all data frame
4198                 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
4199                 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
4200
4201                 v32 = rtw_read32(padapter, REG_RCR);
4202 #ifdef CONFIG_CONCURRENT_MODE
4203                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
4204                         v32 |= RCR_CBSSID_BCN;
4205                 else
4206 #endif
4207                 {
4208                         v32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
4209                 }
4210                 rtw_write32(padapter, REG_RCR, v32);
4211
4212                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
4213                         RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
4214                 else // Ad-hoc Mode
4215                         RetryLimit = 0x7;
4216         }
4217         else if (type == 1) // joinbss_event callback when join res < 0
4218         {
4219 #ifdef CONFIG_CONCURRENT_MODE
4220                 if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
4221                         rtw_write16(padapter, REG_RXFLTMAP2, 0);
4222
4223                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
4224                         (check_buddy_fwstate(padapter, _FW_LINKED) == true))
4225                 {
4226                         ResumeTxBeacon(padapter);
4227
4228                         // reset TSF 1/2 after ResumeTxBeacon
4229                         rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
4230                 }
4231 #else
4232                 // config RCR to receive different BSSID & not to receive data frame during linking
4233                 //v32 = rtw_read32(padapter, REG_RCR);
4234                 //v32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);//| RCR_ADF
4235                 //rtw_write32(padapter, REG_RCR, v32);
4236                 rtw_write16(padapter, REG_RXFLTMAP2, 0);
4237 #endif
4238         }
4239         else if (type == 2) // sta add event callback
4240         {
4241                 // enable update TSF
4242                 SetBcnCtrlReg(padapter, 0, DIS_TSF_UDT);
4243
4244                 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == true)
4245                 {
4246                         // fixed beacon issue for 8191su...........
4247                         rtw_write8(padapter, 0x542, 0x02);
4248                         RetryLimit = 0x7;
4249                 }
4250
4251 #ifdef CONFIG_CONCURRENT_MODE
4252                 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
4253                         (check_buddy_fwstate(padapter, _FW_LINKED) == true))
4254                 {
4255                         ResumeTxBeacon(padapter);
4256
4257                         // reset TSF 1/2 after ResumeTxBeacon
4258                         rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
4259                 }
4260 #endif
4261         }
4262
4263         rtw_write16(padapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
4264 }
4265
4266 void SetHwReg8723A(PADAPTER padapter, u8 variable, u8 *val)
4267 {
4268         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
4269
4270 _func_enter_;
4271
4272         switch (variable) {
4273         case HW_VAR_MEDIA_STATUS:
4274                 {
4275                         u8 val8;
4276
4277                         val8 = rtw_read8(padapter, MSR) & 0x0c;
4278                         val8 |= *val;
4279                         rtw_write8(padapter, MSR, val8);
4280                 }
4281                 break;
4282         case HW_VAR_MEDIA_STATUS1:
4283                 {
4284                         u8 val8;
4285
4286                         val8 = rtw_read8(padapter, MSR) & 0x03;
4287                         val8 |= *val << 2;
4288                         rtw_write8(padapter, MSR, val8);
4289                 }
4290                 break;
4291         case HW_VAR_SET_OPMODE:
4292                 hw_var_set_opmode(padapter, variable, val);
4293                 break;
4294         case HW_VAR_MAC_ADDR:
4295                 hw_var_set_macaddr(padapter, variable, val);
4296                 break;
4297         case HW_VAR_BSSID:
4298                 hw_var_set_bssid(padapter, variable, val);
4299                 break;
4300         case HW_VAR_BASIC_RATE:
4301                 {
4302                         u16                     BrateCfg = 0;
4303                         u8                      RateIndex = 0;
4304                                 // 2007.01.16, by Emily
4305                         // Select RRSR (in Legacy-OFDM and CCK)
4306                         // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
4307                         // We do not use other rates.
4308                         HalSetBrateCfg(padapter, val, &BrateCfg);
4309                                 //2011.03.30 add by Luke Lee
4310                         //CCK 2M ACK should be disabled for some BCM and Atheros AP IOT
4311                         //because CCK 2M has poor TXEVM
4312                         //CCK 5.5M & 11M ACK should be enabled for better performance
4313                                 pHalData->BasicRateSet = BrateCfg = (BrateCfg |0xd) & 0x15d;
4314                         BrateCfg |= 0x01; // default enable 1M ACK rate
4315                         DBG_8192C("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg);
4316                                 // Set RRSR rate table.
4317                         rtw_write8(padapter, REG_RRSR, BrateCfg&0xff);
4318                         rtw_write8(padapter, REG_RRSR+1, (BrateCfg>>8)&0xff);
4319                         rtw_write8(padapter, REG_RRSR+2, rtw_read8(padapter, REG_RRSR+2)&0xf0);
4320                                 // Set RTS initial rate
4321                         while (BrateCfg > 0x1)
4322                         {
4323                                 BrateCfg = (BrateCfg >> 1);
4324                                 RateIndex++;
4325                         }
4326                         // Ziv - Check
4327                         rtw_write8(padapter, REG_INIRTS_RATE_SEL, RateIndex);
4328                 }
4329                 break;
4330         case HW_VAR_TXPAUSE:
4331                 rtw_write8(padapter, REG_TXPAUSE, *val);
4332                 break;
4333         case HW_VAR_BCN_FUNC:
4334                 if (*val)
4335                         SetBcnCtrlReg(padapter, EN_BCN_FUNCTION | EN_TXBCN_RPT, 0);
4336                 else
4337                         SetBcnCtrlReg(padapter, 0, EN_BCN_FUNCTION | EN_TXBCN_RPT);
4338                 break;
4339         case HW_VAR_CORRECT_TSF:
4340                 hw_var_set_correct_tsf(padapter, variable, val);
4341                 break;
4342         case HW_VAR_CHECK_BSSID:
4343                 {
4344                         u32 val32;
4345                         val32 = rtw_read32(padapter, REG_RCR);
4346                         if (*val)
4347                                 val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
4348                         else
4349                                 val32 &= ~(RCR_CBSSID_DATA|RCR_CBSSID_BCN);
4350                         rtw_write32(padapter, REG_RCR, val32);
4351                 }
4352                 break;
4353         case HW_VAR_MLME_DISCONNECT:
4354                 hw_var_set_mlme_disconnect(padapter, variable, val);
4355                 break;
4356         case HW_VAR_MLME_SITESURVEY:
4357 #ifdef CONFIG_CONCURRENT_MODE
4358                 hw_var_set_mlme_sitesurvey(padapter, variable,  val);
4359 #else
4360                 if (*val)//under sitesurvey
4361                 {
4362                         u32 v32;
4363
4364                         // config RCR to receive different BSSID & not to receive data frame
4365                         v32 = rtw_read32(padapter, REG_RCR);
4366                         v32 &= ~(RCR_CBSSID_BCN);
4367                         rtw_write32(padapter, REG_RCR, v32);
4368                         // reject all data frame
4369                         rtw_write16(padapter, REG_RXFLTMAP2, 0);
4370
4371                         // disable update TSF
4372                         SetBcnCtrlReg(padapter, DIS_TSF_UDT, 0);
4373                 }
4374                 else//sitesurvey done
4375                 {
4376                         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4377                         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4378                         u32 v32;
4379
4380                         if ((is_client_associated_to_ap(padapter) == true) ||
4381                                 ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
4382                                 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
4383                         {
4384                                 // enable to rx data frame
4385                                 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
4386
4387                                 // enable update TSF
4388                                 SetBcnCtrlReg(padapter, 0, DIS_TSF_UDT);
4389                         }
4390
4391                         v32 = rtw_read32(padapter, REG_RCR);
4392                         v32 |= RCR_CBSSID_BCN;
4393                         rtw_write32(padapter, REG_RCR, v32);
4394                 }
4395 #endif
4396
4397 #ifdef CONFIG_BT_COEXIST
4398                         BT_WifiScanNotify(padapter, *val?true:false);
4399 #endif
4400                         break;
4401
4402                 case HW_VAR_MLME_JOIN:
4403                         hw_var_set_mlme_join(padapter, variable,  val);
4404
4405 #ifdef CONFIG_BT_COEXIST
4406                         switch (*val) {
4407                                 case 0:
4408                                         // prepare to join
4409                                         BT_WifiAssociateNotify(padapter, true);
4410                                         break;
4411                                 case 1:
4412                                         // joinbss_event callback when join res < 0
4413                                         BT_WifiAssociateNotify(padapter, false);
4414                                         break;
4415                                 case 2:
4416                                         // sta add event callback
4417 //                                      BT_WifiMediaStatusNotify(padapter, RT_MEDIA_CONNECT);
4418                                         break;
4419                         }
4420 #endif
4421                         break;
4422
4423                 case HW_VAR_BEACON_INTERVAL:
4424                         rtw_write16(padapter, REG_BCN_INTERVAL, *((u16*)val));
4425                         break;
4426
4427                 case HW_VAR_SLOT_TIME:
4428                         {
4429                                 u8 u1bAIFS, aSifsTime;
4430                                 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4431                                 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4432
4433                                 rtw_write8(padapter, REG_SLOT, *val);
4434
4435                                 if (pmlmeinfo->WMM_enable == 0)
4436                                 {
4437                                         if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
4438                                                 aSifsTime = 10;
4439                                         else
4440                                                 aSifsTime = 16;
4441
4442                                         u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
4443
4444                                         // <Roger_EXP> Temporary removed, 2008.06.20.
4445                                         rtw_write8(padapter, REG_EDCA_VO_PARAM, u1bAIFS);
4446                                         rtw_write8(padapter, REG_EDCA_VI_PARAM, u1bAIFS);
4447                                         rtw_write8(padapter, REG_EDCA_BE_PARAM, u1bAIFS);
4448                                         rtw_write8(padapter, REG_EDCA_BK_PARAM, u1bAIFS);
4449                                 }
4450                         }
4451                         break;
4452
4453                 case HW_VAR_RESP_SIFS:
4454                         //SIFS_Timer = 0x0a0a0808;
4455                         //RESP_SIFS for CCK
4456                         rtw_write8(padapter, REG_R2T_SIFS, val[0]); // SIFS_T2T_CCK (0x08)
4457                         rtw_write8(padapter, REG_R2T_SIFS+1, val[1]); //SIFS_R2T_CCK(0x08)
4458                         //RESP_SIFS for OFDM
4459                         rtw_write8(padapter, REG_T2T_SIFS, val[2]); //SIFS_T2T_OFDM (0x0a)
4460                         rtw_write8(padapter, REG_T2T_SIFS+1, val[3]); //SIFS_R2T_OFDM(0x0a)
4461                         break;
4462
4463                 case HW_VAR_ACK_PREAMBLE:
4464                         {
4465                                 u8 regTmp;
4466                                 u8 bShortPreamble = *val;
4467
4468                                 // Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily)
4469                                 regTmp = (pHalData->nCur40MhzPrimeSC)<<5;
4470                                 //regTmp = 0;
4471                                 if (bShortPreamble) regTmp |= 0x80;
4472                                         rtw_write8(padapter, REG_RRSR+2, regTmp);
4473                         }
4474                         break;
4475
4476                 case HW_VAR_SEC_CFG:
4477 #ifdef CONFIG_CONCURRENT_MODE
4478                         rtw_write8(padapter, REG_SECCFG, 0x0c|BIT(5));// enable tx enc and rx dec engine, and no key search for MC/BC
4479 #else
4480                         rtw_write8(padapter, REG_SECCFG, *val);
4481 #endif
4482                         break;
4483
4484                 case HW_VAR_DM_FLAG:
4485                         pHalData->odmpriv.SupportAbility = *((u32*)val);
4486                         break;
4487
4488                 case HW_VAR_DM_FUNC_OP:
4489                         if (*val) // save dm flag
4490                                 pHalData->odmpriv.BK_SupportAbility = pHalData->odmpriv.SupportAbility;
4491                         else // restore dm flag
4492                                 pHalData->odmpriv.SupportAbility = pHalData->odmpriv.BK_SupportAbility;
4493                         break;
4494
4495                 case HW_VAR_DM_FUNC_SET:
4496                         if (*((u32*)val) == DYNAMIC_ALL_FUNC_ENABLE) {
4497                                 pHalData->dmpriv.DMFlag = pHalData->dmpriv.InitDMFlag;
4498                                 pHalData->odmpriv.SupportAbility = pHalData->dmpriv.InitODMFlag;
4499                         } else {
4500                                 pHalData->odmpriv.SupportAbility |= *((u32*)val);
4501                         }
4502                         break;
4503
4504                 case HW_VAR_DM_FUNC_CLR:
4505                         pHalData->odmpriv.SupportAbility &= *((u32*)val);
4506                         break;
4507
4508                 case HW_VAR_CAM_EMPTY_ENTRY:
4509                         {
4510                                 u8      ucIndex = *val;
4511                                 u8      i;
4512                                 u32     ulCommand = 0;
4513                                 u32     ulContent = 0;
4514                                 u32     ulEncAlgo = CAM_AES;
4515
4516                                 for (i=0; i<CAM_CONTENT_COUNT; i++)
4517                                 {
4518                                         // filled id in CAM config 2 byte
4519                                         if (i == 0)
4520                                         {
4521                                                 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2);
4522                                                 //ulContent |= CAM_VALID;
4523                                         }
4524                                         else
4525                                         {
4526                                                 ulContent = 0;
4527                                         }
4528                                         // polling bit, and No Write enable, and address
4529                                         ulCommand = CAM_CONTENT_COUNT*ucIndex+i;
4530                                         ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
4531                                         // write content 0 is equall to mark invalid
4532                                         rtw_write32(padapter, WCAMI, ulContent);  //delay_ms(40);
4533                                         //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %lx\n",ulContent));
4534                                         rtw_write32(padapter, RWCAM, ulCommand);  //delay_ms(40);
4535                                         //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %lx\n",ulCommand));
4536                                 }
4537                         }
4538                         break;
4539
4540                 case HW_VAR_CAM_INVALID_ALL:
4541                         rtw_write32(padapter, RWCAM, BIT(31)|BIT(30));
4542                         break;
4543
4544                 case HW_VAR_CAM_WRITE:
4545                         {
4546                                 u32 cmd;
4547                                 u32 *cam_val = (u32*)val;
4548
4549                                 rtw_write32(padapter, WCAMI, cam_val[0]);
4550
4551                                 cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
4552                                 rtw_write32(padapter, RWCAM, cmd);
4553                         }
4554                         break;
4555
4556                 case HW_VAR_AC_PARAM_VO:
4557                         rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32*)val));
4558                         break;
4559
4560                 case HW_VAR_AC_PARAM_VI:
4561                         rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32*)val));
4562                         break;
4563
4564                 case HW_VAR_AC_PARAM_BE:
4565                         pHalData->AcParam_BE = ((u32*)(val))[0];
4566                         rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32*)val));
4567                         break;
4568
4569                 case HW_VAR_AC_PARAM_BK:
4570                         rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32*)val));
4571                         break;
4572
4573                 case HW_VAR_ACM_CTRL:
4574                         {
4575                                 u8 ctrl = *((u8*)val);
4576                                 u8 hwctrl = 0;
4577
4578                                 if (ctrl != 0)
4579                                 {
4580                                         hwctrl |= AcmHw_HwEn;
4581
4582                                         if (ctrl & BIT(1)) // BE
4583                                                 hwctrl |= AcmHw_BeqEn;
4584
4585                                         if (ctrl & BIT(2)) // VI
4586                                                 hwctrl |= AcmHw_ViqEn;
4587
4588                                         if (ctrl & BIT(3)) // VO
4589                                                 hwctrl |= AcmHw_VoqEn;
4590                                 }
4591
4592                                 DBG_8192C("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
4593                                 rtw_write8(padapter, REG_ACMHWCTRL, hwctrl);
4594                         }
4595                         break;
4596
4597                 case HW_VAR_AMPDU_MIN_SPACE:
4598                         {
4599                                 u8      MinSpacingToSet;
4600                                 u8      SecMinSpace;
4601
4602                                 MinSpacingToSet = *val;
4603                                 if (MinSpacingToSet <= 7)
4604                                 {
4605                                         switch (padapter->securitypriv.dot11PrivacyAlgrthm)
4606                                         {
4607                                                 case _NO_PRIVACY_:
4608                                                 case _AES_:
4609                                                         SecMinSpace = 0;
4610                                                         break;
4611
4612                                                 case _WEP40_:
4613                                                 case _WEP104_:
4614                                                 case _TKIP_:
4615                                                 case _TKIP_WTMIC_:
4616                                                         SecMinSpace = 6;
4617                                                         break;
4618                                                 default:
4619                                                         SecMinSpace = 7;
4620                                                         break;
4621                                         }
4622
4623                                         if (MinSpacingToSet < SecMinSpace)
4624                                                 MinSpacingToSet = SecMinSpace;
4625
4626                                         //RT_TRACE(COMP_MLME, DBG_LOUD, ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", padapter->MgntInfo.MinSpaceCfg));
4627                                         MinSpacingToSet |= rtw_read8(padapter, REG_AMPDU_MIN_SPACE) & 0xf8;
4628                                         rtw_write8(padapter, REG_AMPDU_MIN_SPACE, MinSpacingToSet);
4629                                 }
4630                         }
4631                         break;
4632
4633                 case HW_VAR_AMPDU_FACTOR:
4634                         {
4635                                 u8 RegToSet_Normal[4] = {0x41,0xa8,0x72, 0xb9};
4636                                 u8 MaxAggNum;
4637                                 u8 FactorToSet;
4638                                 u8 *pRegToSet;
4639                                 u8 index = 0;
4640
4641                                 pRegToSet = RegToSet_Normal; // 0xb972a841;
4642 #ifdef CONFIG_BT_COEXIST
4643                                 if ((BT_IsBtDisabled(padapter) == false) &&
4644                                         (BT_1Ant(padapter) == true))
4645                                 {
4646                                         MaxAggNum = 0x8;
4647                                 }
4648                                 else
4649 #endif // CONFIG_BT_COEXIST
4650                                 {
4651                                         MaxAggNum = 0xF;
4652                                 }
4653
4654                                 FactorToSet = *val;
4655                                 if (FactorToSet <= 3)
4656                                 {
4657                                         FactorToSet = (1 << (FactorToSet + 2));
4658                                         if (FactorToSet > MaxAggNum)
4659                                                 FactorToSet = MaxAggNum;
4660
4661                                         for (index=0; index<4; index++)
4662                                         {
4663                                                 if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
4664                                                         pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4);
4665
4666                                                 if ((pRegToSet[index] & 0x0f) > FactorToSet)
4667                                                         pRegToSet[index] = (pRegToSet[index] & 0xf0) | FactorToSet;
4668
4669                                                 rtw_write8(padapter, REG_AGGLEN_LMT+index, pRegToSet[index]);
4670                                         }
4671
4672                                         //RT_TRACE(COMP_MLME, DBG_LOUD, ("Set HW_VAR_AMPDU_FACTOR: %#x\n", FactorToSet));
4673                                 }
4674                         }
4675                         break;
4676
4677                 case HW_VAR_RXDMA_AGG_PG_TH:
4678                         rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, *val);
4679                         break;
4680
4681                 case HW_VAR_H2C_FW_PWRMODE:
4682                         {
4683                                 u8 psmode = *val;
4684
4685                                 // Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power
4686                                 // saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang.
4687                                 if ((psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(pHalData->VersionID)))
4688                                 {
4689                                         ODM_RF_Saving(&pHalData->odmpriv, true);
4690                                 }
4691                                 rtl8723a_set_FwPwrMode_cmd(padapter, psmode);
4692                         }
4693                         break;
4694
4695                 case HW_VAR_H2C_FW_JOINBSSRPT:
4696                         rtl8723a_set_FwJoinBssReport_cmd(padapter, *val);
4697                         break;
4698
4699 #ifdef CONFIG_P2P
4700                 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
4701                         rtl8192c_set_p2p_ps_offload_cmd(padapter, *val);
4702                         break;
4703 #endif //CONFIG_P2P
4704
4705                 case HW_VAR_INITIAL_GAIN:
4706                         {
4707                                 DIG_T *pDigTable = &pHalData->odmpriv.DM_DigTable;
4708                                 u32 rx_gain = *(u32*)val;
4709
4710                                 if (rx_gain == 0xff) {//restore rx gain
4711                                         ODM_Write_DIG(&pHalData->odmpriv, pDigTable->BackupIGValue);
4712                                 } else {
4713                                         pDigTable->BackupIGValue = pDigTable->CurIGValue;
4714                                         ODM_Write_DIG(&pHalData->odmpriv, rx_gain);
4715                                 }
4716                         }
4717                         break;
4718
4719 #ifdef CONFIG_SW_ANTENNA_DIVERSITY
4720                 case HW_VAR_ANTENNA_DIVERSITY_LINK:
4721                         //SwAntDivRestAfterLink8192C(padapter);
4722                         ODM_SwAntDivRestAfterLink(&pHalData->odmpriv);
4723                         break;
4724
4725                 case HW_VAR_ANTENNA_DIVERSITY_SELECT:
4726                         {
4727                                 u8 Optimum_antenna = *val;
4728
4729                                 //DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");
4730
4731                                 //PHY_SetBBReg(padapter, rFPGA0_XA_RFInterfaceOE, 0x300, Optimum_antenna);
4732                                 ODM_SetAntenna(&pHalData->odmpriv, Optimum_antenna);
4733                         }
4734                         break;
4735 #endif
4736
4737                 case HW_VAR_EFUSE_USAGE:
4738                         pHalData->EfuseUsedPercentage = *val;
4739                         break;
4740
4741                 case HW_VAR_EFUSE_BYTES:
4742                         pHalData->EfuseUsedBytes = *((u16*)val);
4743                         break;
4744
4745                 case HW_VAR_EFUSE_BT_USAGE:
4746 #ifdef HAL_EFUSE_MEMORY
4747                         pHalData->EfuseHal.BTEfuseUsedPercentage = *val;
4748 #endif
4749                         break;
4750
4751                 case HW_VAR_EFUSE_BT_BYTES:
4752 #ifdef HAL_EFUSE_MEMORY
4753                         pHalData->EfuseHal.BTEfuseUsedBytes = *((u16*)val);
4754 #else
4755                         BTEfuseUsedBytes = *((u16*)val);
4756 #endif
4757                         break;
4758
4759                 case HW_VAR_FIFO_CLEARN_UP:
4760                         {
4761                                 #define RW_RELEASE_EN           BIT(18)
4762                                 #define RXDMA_IDLE                      BIT(17)
4763
4764                                 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
4765                                 u8 trycnt = 100;
4766
4767                                 // pause tx
4768                                 rtw_write8(padapter, REG_TXPAUSE, 0xff);
4769
4770                                 // keep sn
4771                                 padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ);
4772
4773                                 if (pwrpriv->bkeepfwalive != true)
4774                                 {
4775                                         u32 v32;
4776
4777                                         // RX DMA stop
4778                                         v32 = rtw_read32(padapter, REG_RXPKT_NUM);
4779                                         v32 |= RW_RELEASE_EN;
4780                                         rtw_write32(padapter, REG_RXPKT_NUM, v32);
4781                                         do {
4782                                                 v32 = rtw_read32(padapter, REG_RXPKT_NUM) & RXDMA_IDLE;
4783                                                 if (!v32) break;
4784                                         } while (trycnt--);
4785                                         if (trycnt == 0) {
4786                                                 DBG_8192C("Stop RX DMA failed......\n");
4787                                         }
4788
4789                                         // RQPN Load 0
4790                                         rtw_write16(padapter, REG_RQPN_NPQ, 0);
4791                                         rtw_write32(padapter, REG_RQPN, 0x80000000);
4792                                         rtw_mdelay_os(10);
4793                                 }
4794                         }
4795                         break;
4796
4797                 case HW_VAR_CHECK_TXBUF:
4798 #ifdef CONFIG_CONCURRENT_MODE
4799                         {
4800                                 u16 v16;
4801                                 u32 i;
4802                                 u8 RetryLimit = 0x01;
4803
4804                                 //rtw_write16(padapter, REG_RL,0x0101);
4805                                 v16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
4806                                 rtw_write16(padapter, REG_RL, v16);
4807
4808                                 for (i=0; i<1000; i++)
4809                                 {
4810                                         if (rtw_read32(padapter, 0x200) != rtw_read32(padapter, 0x204))
4811                                         {
4812                                                 //DBG_871X("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(padapter, 0x204), rtw_read32(padapter, 0x200), i);
4813                                                 rtw_msleep_os(10);
4814                                         }
4815                                         else
4816                                         {
4817                                                 DBG_871X("no packet in tx packet buffer (%d)\n", i);
4818                                                 break;
4819                                         }
4820                                 }
4821
4822                                 RetryLimit = 0x30;
4823                                 v16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
4824                                 rtw_write16(padapter, REG_RL, v16);
4825                         }
4826 #endif
4827                         break;
4828
4829                 case HW_VAR_APFM_ON_MAC:
4830                         pHalData->bMacPwrCtrlOn = *val;
4831                         DBG_8192C("%s: bMacPwrCtrlOn=%d\n", __func__, pHalData->bMacPwrCtrlOn);
4832                         break;
4833                 case HW_VAR_NAV_UPPER:
4834                         {
4835                                 u32 usNavUpper = *((u32*)val);
4836
4837                                 if (usNavUpper > HAL_8723A_NAV_UPPER_UNIT * 0xFF)
4838                                 {
4839                                         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_8723A_NAV_UPPER_UNIT));
4840                                         break;
4841                                 }
4842
4843                                 // The value of ((usNavUpper + HAL_8723A_NAV_UPPER_UNIT - 1) / HAL_8723A_NAV_UPPER_UNIT)
4844                                 // is getting the upper integer.
4845                                 usNavUpper = (usNavUpper + HAL_8723A_NAV_UPPER_UNIT - 1) / HAL_8723A_NAV_UPPER_UNIT;
4846                                 rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);
4847                         }
4848                         break;
4849                 case HW_VAR_BCN_VALID:
4850                         //BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw
4851                         rtw_write8(padapter, REG_TDECTRL+2, rtw_read8(padapter, REG_TDECTRL+2) | BIT0);
4852                         break;
4853                 default:
4854                         break;
4855         }
4856
4857 _func_exit_;
4858 }
4859
4860 void GetHwReg8723A(PADAPTER padapter, u8 variable, u8 *val)
4861 {
4862         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4863
4864
4865         switch (variable)
4866         {
4867                 case HW_VAR_BASIC_RATE:
4868                         *((u16*)val) = pHalData->BasicRateSet;
4869                         break;
4870
4871                 case HW_VAR_TXPAUSE:
4872                         *val = rtw_read8(padapter, REG_TXPAUSE);
4873                         break;
4874
4875                 case HW_VAR_BCN_VALID:
4876                         //BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2
4877                         val[0] = (BIT0 & rtw_read8(padapter, REG_TDECTRL+2))?true:false;
4878                         break;
4879
4880                 case HW_VAR_RF_TYPE:
4881                         *val = pHalData->rf_type;
4882                         break;
4883
4884                 case HW_VAR_DM_FLAG:
4885                         {
4886                                 PDM_ODM_T podmpriv = &pHalData->odmpriv;
4887                                 *((u32*)val) = podmpriv->SupportAbility;
4888                         }
4889                         break;
4890
4891                 case HW_VAR_FWLPS_RF_ON:
4892                         {
4893                                 // When we halt NIC, we should check if FW LPS is leave.
4894                                 u32 valRCR;
4895
4896                                 if ((padapter->bSurpriseRemoved == true) ||
4897                                         (padapter->pwrctrlpriv.rf_pwrstate == rf_off))
4898                                 {
4899                                         // If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave,
4900                                         // because Fw is unload.
4901                                         *val = true;
4902                                 }
4903                                 else
4904                                 {
4905                                         valRCR = rtw_read32(padapter, REG_RCR);
4906                                         valRCR &= 0x00070000;
4907                                         if (valRCR)
4908                                                 *val = false;
4909                                         else
4910                                                 *val = true;
4911                                 }
4912                         }
4913                         break;
4914
4915 #ifdef CONFIG_ANTENNA_DIVERSITY
4916                 case HW_VAR_CURRENT_ANTENNA:
4917                         *val = pHalData->CurAntenna;
4918                         break;
4919 #endif
4920
4921                 case HW_VAR_EFUSE_USAGE:
4922                         *val = pHalData->EfuseUsedPercentage;
4923                         break;
4924
4925                 case HW_VAR_EFUSE_BYTES:
4926                         *((u16*)val) = pHalData->EfuseUsedBytes;
4927                         break;
4928
4929                 case HW_VAR_EFUSE_BT_USAGE:
4930 #ifdef HAL_EFUSE_MEMORY
4931                         *val = pHalData->EfuseHal.BTEfuseUsedPercentage;
4932 #endif
4933                         break;
4934
4935                 case HW_VAR_EFUSE_BT_BYTES:
4936 #ifdef HAL_EFUSE_MEMORY
4937                         *((u16*)val) = pHalData->EfuseHal.BTEfuseUsedBytes;
4938 #else
4939                         *((u16*)val) = BTEfuseUsedBytes;
4940 #endif
4941                         break;
4942
4943                 case HW_VAR_APFM_ON_MAC:
4944                         *val = pHalData->bMacPwrCtrlOn;
4945                         break;
4946                 case HW_VAR_CHK_HI_QUEUE_EMPTY:
4947                         *val = ((rtw_read32(padapter, REG_HGQ_INFORMATION)&0x0000ff00)==0) ? true:false;
4948                         break;
4949         }
4950 }
4951
4952 #ifdef CONFIG_BT_COEXIST
4953
4954 void rtl8723a_SingleDualAntennaDetection(PADAPTER padapter)
4955 {
4956         PHAL_DATA_TYPE pHalData;
4957         PDM_ODM_T pDM_Odm;
4958         pSWAT_T pDM_SWAT_Table;
4959         u8 btAntNum;
4960         u8 i;
4961
4962
4963         pHalData = GET_HAL_DATA(padapter);
4964         pDM_Odm = &pHalData->odmpriv;
4965         pDM_SWAT_Table= &pDM_Odm->DM_SWAT_Table;
4966
4967         //
4968         // <Roger_Notes> RTL8723A Single and Dual antenna dynamic detection mechanism when RF power state is on.
4969         // We should take power tracking, IQK, LCK, RCK RF read/write operation into consideration.
4970         // 2011.12.15.
4971         //
4972         if (IS_HARDWARE_TYPE_8723A(padapter) && !pHalData->bAntennaDetected)
4973         {
4974                 u8 btAntNum = BT_GetPGAntNum(padapter);
4975
4976                 // Set default antenna B status
4977                 if (btAntNum == Ant_x2)
4978                         pDM_SWAT_Table->ANTB_ON = true;
4979                 else if (btAntNum == Ant_x1)
4980                         pDM_SWAT_Table->ANTB_ON = false;
4981                 else
4982                         pDM_SWAT_Table->ANTB_ON = true;
4983
4984                 if (pHalData->CustomerID != RT_CID_TOSHIBA )
4985                 {
4986                         for (i=0; i<MAX_ANTENNA_DETECTION_CNT; i++)
4987                         {
4988                                 if (ODM_SingleDualAntennaDetection(&pHalData->odmpriv, ANTTESTALL) == true)
4989                                         break;
4990                         }
4991
4992                         // Set default antenna number for BT coexistence
4993                         if (btAntNum == Ant_x2)
4994                                 BT_SetBtCoexCurrAntNum(padapter, pDM_SWAT_Table->ANTB_ON ? 2 : 1);
4995                 }
4996                 pHalData->bAntennaDetected = true;
4997         }
4998 }
4999 #endif // CONFIG_BT_COEXIST
5000
5001 void rtl8723a_clone_haldata(_adapter* dst_adapter, _adapter* src_adapter)
5002 {
5003         memcpy(dst_adapter->HalData, src_adapter->HalData, dst_adapter->hal_data_sz);
5004 }
5005
5006 void rtl8723a_start_thread(_adapter *padapter)
5007 {
5008 }
5009
5010 void rtl8723a_stop_thread(_adapter *padapter)
5011 {
5012 }