OSDN Git Service

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