ARM: tegra: enable igb, stmpe, i2c chardev, lm95245, pwm leds
[cascardo/linux.git] / drivers / staging / rtl8723au / 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  ******************************************************************************/
15 #define _HAL_INIT_C_
16
17 #include <linux/firmware.h>
18 #include <drv_types.h>
19 #include <rtw_efuse.h>
20
21 #include <rtl8723a_hal.h>
22 #include <usb_ops_linux.h>
23
24 static void _FWDownloadEnable(struct rtw_adapter *padapter, bool enable)
25 {
26         u8 tmp;
27
28         if (enable) {
29                 /*  8051 enable */
30                 tmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
31                 rtl8723au_write8(padapter, REG_SYS_FUNC_EN + 1, tmp | 0x04);
32
33                 /*  MCU firmware download enable. */
34                 tmp = rtl8723au_read8(padapter, REG_MCUFWDL);
35                 rtl8723au_write8(padapter, REG_MCUFWDL, tmp | 0x01);
36
37                 /*  8051 reset */
38                 tmp = rtl8723au_read8(padapter, REG_MCUFWDL + 2);
39                 rtl8723au_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
40         } else {
41                 /*  MCU firmware download disable. */
42                 tmp = rtl8723au_read8(padapter, REG_MCUFWDL);
43                 rtl8723au_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
44
45                 /*  Reserved for fw extension. */
46                 rtl8723au_write8(padapter, REG_MCUFWDL + 1, 0x00);
47         }
48 }
49
50 static int _BlockWrite(struct rtw_adapter *padapter, void *buffer, u32 buffSize)
51 {
52         int ret = _SUCCESS;
53         /*  (Default) Phase #1 : PCI muse use 4-byte write to download FW */
54         u32 blockSize_p1 = 4;
55         /*  Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */
56         u32 blockSize_p2 = 8;
57         /*  Phase #3 : Use 1-byte, the remnant of FW image. */
58         u32 blockSize_p3 = 1;
59         u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
60         u32 remainSize_p1 = 0, remainSize_p2 = 0;
61         u8 *bufferPtr = (u8 *) buffer;
62         u32 i = 0, offset = 0;
63
64         blockSize_p1 = 254;
65
66         /* 3 Phase #1 */
67         blockCount_p1 = buffSize / blockSize_p1;
68         remainSize_p1 = buffSize % blockSize_p1;
69
70         if (blockCount_p1) {
71                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
72                          ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) "
73                           "blockCount_p1(%d) remainSize_p1(%d)\n",
74                           buffSize, blockSize_p1, blockCount_p1,
75                           remainSize_p1));
76         }
77
78         for (i = 0; i < blockCount_p1; i++) {
79                 ret = rtl8723au_writeN(padapter, (FW_8723A_START_ADDRESS +
80                                                   i * blockSize_p1),
81                                        blockSize_p1,
82                                        (bufferPtr + i * blockSize_p1));
83                 if (ret == _FAIL)
84                         goto exit;
85         }
86
87         /* 3 Phase #2 */
88         if (remainSize_p1) {
89                 offset = blockCount_p1 * blockSize_p1;
90
91                 blockCount_p2 = remainSize_p1 / blockSize_p2;
92                 remainSize_p2 = remainSize_p1 % blockSize_p2;
93
94                 if (blockCount_p2) {
95                         RT_TRACE(_module_hal_init_c_, _drv_notice_,
96                                  ("_BlockWrite: [P2] buffSize_p2(%d) "
97                                   "blockSize_p2(%d) blockCount_p2(%d) "
98                                   "remainSize_p2(%d)\n",
99                                   (buffSize - offset), blockSize_p2,
100                                   blockCount_p2, remainSize_p2));
101                 }
102
103                 for (i = 0; i < blockCount_p2; i++) {
104                         ret = rtl8723au_writeN(padapter,
105                                                (FW_8723A_START_ADDRESS +
106                                                 offset + i * blockSize_p2),
107                                                blockSize_p2,
108                                                (bufferPtr + offset +
109                                                 i * blockSize_p2));
110
111                         if (ret == _FAIL)
112                                 goto exit;
113                 }
114         }
115
116         /* 3 Phase #3 */
117         if (remainSize_p2) {
118                 offset = (blockCount_p1 * blockSize_p1) +
119                         (blockCount_p2 * blockSize_p2);
120
121                 blockCount_p3 = remainSize_p2 / blockSize_p3;
122
123                 RT_TRACE(_module_hal_init_c_, _drv_notice_,
124                          ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) "
125                           "blockCount_p3(%d)\n",
126                           (buffSize - offset), blockSize_p3, blockCount_p3));
127
128                 for (i = 0; i < blockCount_p3; i++) {
129                         ret = rtl8723au_write8(padapter,
130                                                (FW_8723A_START_ADDRESS + offset + i),
131                                                *(bufferPtr + offset + i));
132
133                         if (ret == _FAIL)
134                                 goto exit;
135                 }
136         }
137
138 exit:
139         return ret;
140 }
141
142 static int
143 _PageWrite(struct rtw_adapter *padapter, u32 page, void *buffer, u32 size)
144 {
145         u8 value8;
146         u8 u8Page = (u8) (page & 0x07);
147
148         value8 = (rtl8723au_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
149         rtl8723au_write8(padapter, REG_MCUFWDL + 2, value8);
150
151         return _BlockWrite(padapter, buffer, size);
152 }
153
154 static int _WriteFW(struct rtw_adapter *padapter, void *buffer, u32 size)
155 {
156         /*  Since we need dynamic decide method of dwonload fw, so we
157             call this function to get chip version. */
158         /*  We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */
159         int ret = _SUCCESS;
160         u32 pageNums, remainSize;
161         u32 page, offset;
162         u8 *bufferPtr = (u8 *) buffer;
163
164         pageNums = size / MAX_PAGE_SIZE;
165         /* RT_ASSERT((pageNums <= 4),
166            ("Page numbers should not greater then 4 \n")); */
167         remainSize = size % MAX_PAGE_SIZE;
168
169         for (page = 0; page < pageNums; page++) {
170                 offset = page * MAX_PAGE_SIZE;
171                 ret = _PageWrite(padapter, page, bufferPtr + offset,
172                                  MAX_PAGE_SIZE);
173
174                 if (ret == _FAIL)
175                         goto exit;
176         }
177         if (remainSize) {
178                 offset = pageNums * MAX_PAGE_SIZE;
179                 page = pageNums;
180                 ret = _PageWrite(padapter, page, bufferPtr + offset,
181                                  remainSize);
182
183                 if (ret == _FAIL)
184                         goto exit;
185         }
186         RT_TRACE(_module_hal_init_c_, _drv_info_,
187                  ("_WriteFW Done- for Normal chip.\n"));
188
189 exit:
190         return ret;
191 }
192
193 static int _FWFreeToGo(struct rtw_adapter *padapter)
194 {
195         u32 counter = 0;
196         u32 value32;
197
198         /*  polling CheckSum report */
199         do {
200                 value32 = rtl8723au_read32(padapter, REG_MCUFWDL);
201                 if (value32 & FWDL_ChkSum_rpt)
202                         break;
203         } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
204
205         if (counter >= POLLING_READY_TIMEOUT_COUNT) {
206                 RT_TRACE(_module_hal_init_c_, _drv_err_,
207                          ("%s: chksum report fail! REG_MCUFWDL:0x%08x\n",
208                           __func__, value32));
209                 return _FAIL;
210         }
211         RT_TRACE(_module_hal_init_c_, _drv_info_,
212                  ("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__,
213                   value32));
214
215         value32 = rtl8723au_read32(padapter, REG_MCUFWDL);
216         value32 |= MCUFWDL_RDY;
217         value32 &= ~WINTINI_RDY;
218         rtl8723au_write32(padapter, REG_MCUFWDL, value32);
219
220         /*  polling for FW ready */
221         counter = 0;
222         do {
223                 value32 = rtl8723au_read32(padapter, REG_MCUFWDL);
224                 if (value32 & WINTINI_RDY) {
225                         RT_TRACE(_module_hal_init_c_, _drv_info_,
226                                  ("%s: Polling FW ready success!! "
227                                   "REG_MCUFWDL:0x%08x\n",
228                                   __func__, value32));
229                         return _SUCCESS;
230                 }
231                 udelay(5);
232         } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
233
234         RT_TRACE(_module_hal_init_c_, _drv_err_,
235                  ("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n",
236                   __func__, value32));
237         return _FAIL;
238 }
239
240 #define IS_FW_81xxC(padapter)   (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
241
242 void rtl8723a_FirmwareSelfReset(struct rtw_adapter *padapter)
243 {
244         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
245         u8 u1bTmp;
246         u8 Delay = 100;
247
248         if (!(IS_FW_81xxC(padapter) &&
249               ((pHalData->FirmwareVersion < 0x21) ||
250                (pHalData->FirmwareVersion == 0x21 &&
251                 pHalData->FirmwareSubVersion < 0x01)))) {
252                 /*  after 88C Fw v33.1 */
253                 /* 0x1cf = 0x20. Inform 8051 to reset. 2009.12.25. tynli_test */
254                 rtl8723au_write8(padapter, REG_HMETFR + 3, 0x20);
255
256                 u1bTmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
257                 while (u1bTmp & BIT(2)) {
258                         Delay--;
259                         if (Delay == 0)
260                                 break;
261                         udelay(50);
262                         u1bTmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
263                 }
264                 RT_TRACE(_module_hal_init_c_, _drv_info_,
265                          ("-%s: 8051 reset success (%d)\n", __func__,
266                           Delay));
267
268                 if ((Delay == 0)) {
269                         /* force firmware reset */
270                         u1bTmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
271                         rtl8723au_write8(padapter, REG_SYS_FUNC_EN + 1,
272                                          u1bTmp & ~BIT(2));
273                 }
274         }
275 }
276
277 /*  */
278 /*      Description: */
279 /*              Download 8192C firmware code. */
280 /*  */
281 /*  */
282 int rtl8723a_FirmwareDownload(struct rtw_adapter *padapter)
283 {
284         int rtStatus = _SUCCESS;
285         u8 writeFW_retry = 0;
286         unsigned long fwdl_start_time;
287         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
288         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
289         struct device *device = dvobj_to_dev(dvobj);
290         struct rt_8723a_firmware_hdr *pFwHdr = NULL;
291         const struct firmware *fw;
292         char *fw_name;
293         u8 *firmware_buf = NULL;
294         u8 *buf;
295         int fw_size;
296         static int log_version;
297
298         RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__));
299
300         if (IS_8723A_A_CUT(pHalData->VersionID)) {
301                 fw_name = "rtlwifi/rtl8723aufw.bin";
302                 RT_TRACE(_module_hal_init_c_, _drv_info_,
303                          ("rtl8723a_FirmwareDownload: R8723FwImageArray_UMC "
304                           "for RTL8723A A CUT\n"));
305         } else if (IS_8723A_B_CUT(pHalData->VersionID)) {
306                 /*  WLAN Fw. */
307                 if (padapter->registrypriv.wifi_spec == 1) {
308                         fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin";
309                         DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithoutBT for "
310                                   "RTL8723A B CUT\n");
311                 } else {
312                         if (rtl8723a_BT_coexist(padapter)) {
313                                 fw_name = "rtlwifi/rtl8723aufw_B.bin";
314                                 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithBT "
315                                           "for RTL8723A B CUT\n");
316                         } else {
317                                 fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin";
318                                 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithout "
319                                           "BT for RTL8723A B CUT\n");
320                         }
321                 }
322         } else {
323                 /*  <Roger_TODO> We should download proper RAM Code here
324                     to match the ROM code. */
325                 RT_TRACE(_module_hal_init_c_, _drv_err_,
326                          ("%s: unknow version!\n", __func__));
327                 rtStatus = _FAIL;
328                 goto Exit;
329         }
330
331         pr_info("rtl8723au: Loading firmware %s\n", fw_name);
332         if (request_firmware(&fw, fw_name, device)) {
333                 pr_err("rtl8723au: request_firmware load failed\n");
334                 rtStatus = _FAIL;
335                 goto Exit;
336         }
337         if (!fw) {
338                 pr_err("rtl8723au: Firmware %s not available\n", fw_name);
339                 rtStatus = _FAIL;
340                 goto Exit;
341         }
342         firmware_buf = kmemdup(fw->data, fw->size, GFP_KERNEL);
343         if (!firmware_buf) {
344                 rtStatus = _FAIL;
345                 goto Exit;
346         }
347         buf = firmware_buf;
348         fw_size = fw->size;
349         release_firmware(fw);
350
351         /*  To Check Fw header. Added by tynli. 2009.12.04. */
352         pFwHdr = (struct rt_8723a_firmware_hdr *)firmware_buf;
353
354         pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version);
355         pHalData->FirmwareSubVersion = pFwHdr->Subversion;
356         pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
357
358         DBG_8723A("%s: fw_ver =%d fw_subver =%d sig = 0x%x\n",
359                   __func__, pHalData->FirmwareVersion,
360                   pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
361
362         if (!log_version++)
363                 pr_info("%sFirmware Version %d, SubVersion %d, Signature "
364                         "0x%x\n", DRIVER_PREFIX, pHalData->FirmwareVersion,
365                         pHalData->FirmwareSubVersion,
366                         pHalData->FirmwareSignature);
367
368         if (IS_FW_HEADER_EXIST(pFwHdr)) {
369                 /*  Shift 32 bytes for FW header */
370                 buf = buf + 32;
371                 fw_size = fw_size - 32;
372         }
373
374         /*  Suggested by Filen. If 8051 is running in RAM code, driver should
375             inform Fw to reset by itself, */
376         /*  or it will cause download Fw fail. 2010.02.01. by tynli. */
377         if (rtl8723au_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) {
378                 /* 8051 RAM code */
379                 rtl8723a_FirmwareSelfReset(padapter);
380                 rtl8723au_write8(padapter, REG_MCUFWDL, 0x00);
381         }
382
383         _FWDownloadEnable(padapter, true);
384         fwdl_start_time = jiffies;
385         while (1) {
386                 /* reset the FWDL chksum */
387                 rtl8723au_write8(padapter, REG_MCUFWDL,
388                                  rtl8723au_read8(padapter, REG_MCUFWDL) |
389                                  FWDL_ChkSum_rpt);
390
391                 rtStatus = _WriteFW(padapter, buf, fw_size);
392
393                 if (rtStatus == _SUCCESS ||
394                     (jiffies_to_msecs(jiffies - fwdl_start_time) > 500 &&
395                      writeFW_retry++ >= 3))
396                         break;
397
398                 DBG_8723A("%s writeFW_retry:%u, time after fwdl_start_time:"
399                           "%ums\n", __func__, writeFW_retry,
400                           jiffies_to_msecs(jiffies - fwdl_start_time));
401         }
402         _FWDownloadEnable(padapter, false);
403         if (_SUCCESS != rtStatus) {
404                 DBG_8723A("DL Firmware failed!\n");
405                 goto Exit;
406         }
407
408         rtStatus = _FWFreeToGo(padapter);
409         if (_SUCCESS != rtStatus) {
410                 RT_TRACE(_module_hal_init_c_, _drv_err_,
411                          ("DL Firmware failed!\n"));
412                 goto Exit;
413         }
414         RT_TRACE(_module_hal_init_c_, _drv_info_,
415                  ("Firmware is ready to run!\n"));
416
417 Exit:
418         kfree(firmware_buf);
419         return rtStatus;
420 }
421
422 void rtl8723a_InitializeFirmwareVars(struct rtw_adapter *padapter)
423 {
424         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
425
426         /*  Init Fw LPS related. */
427         padapter->pwrctrlpriv.bFwCurrentInPSMode = false;
428
429         /*  Init H2C counter. by tynli. 2009.12.09. */
430         pHalData->LastHMEBoxNum = 0;
431 }
432
433 /*  */
434 /*                              Efuse related code */
435 /*  */
436 static u8
437 hal_EfuseSwitchToBank(struct rtw_adapter *padapter, u8 bank)
438 {
439         u8 bRet = false;
440         u32 value32 = 0;
441
442         DBG_8723A("%s: Efuse switch bank to %d\n", __func__, bank);
443         value32 = rtl8723au_read32(padapter, EFUSE_TEST);
444         bRet = true;
445         switch (bank) {
446         case 0:
447                 value32 = (value32 & ~EFUSE_SEL_MASK) |
448                         EFUSE_SEL(EFUSE_WIFI_SEL_0);
449                 break;
450         case 1:
451                 value32 = (value32 & ~EFUSE_SEL_MASK) |
452                         EFUSE_SEL(EFUSE_BT_SEL_0);
453                 break;
454         case 2:
455                 value32 = (value32 & ~EFUSE_SEL_MASK) |
456                         EFUSE_SEL(EFUSE_BT_SEL_1);
457                 break;
458         case 3:
459                 value32 = (value32 & ~EFUSE_SEL_MASK) |
460                         EFUSE_SEL(EFUSE_BT_SEL_2);
461                 break;
462         default:
463                 value32 = (value32 & ~EFUSE_SEL_MASK) |
464                         EFUSE_SEL(EFUSE_WIFI_SEL_0);
465                 bRet = false;
466                 break;
467         }
468         rtl8723au_write32(padapter, EFUSE_TEST, value32);
469
470         return bRet;
471 }
472
473 static void
474 hal_ReadEFuse_WiFi(struct rtw_adapter *padapter,
475                    u16 _offset, u16 _size_byte, u8 *pbuf)
476 {
477         u8 *efuseTbl = NULL;
478         u16 eFuse_Addr = 0;
479         u8 offset, wden;
480         u8 efuseHeader, efuseExtHdr, efuseData;
481         u16 i, total, used;
482         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
483
484         /*  Do NOT excess total size of EFuse table.
485             Added by Roger, 2008.11.10. */
486         if ((_offset + _size_byte) > EFUSE_MAP_LEN_8723A) {
487                 DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n",
488                           __func__, _offset, _size_byte);
489                 return;
490         }
491
492         efuseTbl = kmalloc(EFUSE_MAP_LEN_8723A, GFP_KERNEL);
493         if (efuseTbl == NULL) {
494                 DBG_8723A("%s: alloc efuseTbl fail!\n", __func__);
495                 return;
496         }
497         /*  0xff will be efuse default value instead of 0x00. */
498         memset(efuseTbl, 0xFF, EFUSE_MAP_LEN_8723A);
499
500         /*  switch bank back to bank 0 for later BT and wifi use. */
501         hal_EfuseSwitchToBank(padapter, 0);
502
503         while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
504                 ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseHeader);
505                 if (efuseHeader == 0xFF) {
506                         DBG_8723A("%s: data end at address =%#x\n", __func__,
507                                   eFuse_Addr);
508                         break;
509                 }
510
511                 /*  Check PG header for section num. */
512                 if (EXT_HEADER(efuseHeader)) {  /* extended header */
513                         offset = GET_HDR_OFFSET_2_0(efuseHeader);
514
515                         ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseExtHdr);
516                         if (ALL_WORDS_DISABLED(efuseExtHdr)) {
517                                 continue;
518                         }
519
520                         offset |= ((efuseExtHdr & 0xF0) >> 1);
521                         wden = (efuseExtHdr & 0x0F);
522                 } else {
523                         offset = ((efuseHeader >> 4) & 0x0f);
524                         wden = (efuseHeader & 0x0f);
525                 }
526
527                 if (offset < EFUSE_MAX_SECTION_8723A) {
528                         u16 addr;
529                         /*  Get word enable value from PG header */
530
531                         addr = offset * PGPKT_DATA_SIZE;
532                         for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
533                                 /* Check word enable condition in the section */
534                                 if (!(wden & (0x01 << i))) {
535                                         ReadEFuseByte23a(padapter, eFuse_Addr++,
536                                                       &efuseData);
537                                         efuseTbl[addr] = efuseData;
538
539                                         ReadEFuseByte23a(padapter, eFuse_Addr++,
540                                                       &efuseData);
541                                         efuseTbl[addr + 1] = efuseData;
542                                 }
543                                 addr += 2;
544                         }
545                 } else {
546                         DBG_8723A(KERN_ERR "%s: offset(%d) is illegal!!\n",
547                                   __func__, offset);
548                         eFuse_Addr += Efuse_CalculateWordCnts23a(wden) * 2;
549                 }
550         }
551
552         /*  Copy from Efuse map to output pointer memory!!! */
553         for (i = 0; i < _size_byte; i++)
554                 pbuf[i] = efuseTbl[_offset + i];
555
556         /*  Calculate Efuse utilization */
557         EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
558                                  TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
559         used = eFuse_Addr - 1;
560         pHalData->EfuseUsedBytes = used;
561
562         kfree(efuseTbl);
563 }
564
565 static void
566 hal_ReadEFuse_BT(struct rtw_adapter *padapter,
567                  u16 _offset, u16 _size_byte, u8 *pbuf)
568 {
569         u8 *efuseTbl;
570         u8 bank;
571         u16 eFuse_Addr;
572         u8 efuseHeader, efuseExtHdr, efuseData;
573         u8 offset, wden;
574         u16 i, total, used;
575         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
576
577         /*  Do NOT excess total size of EFuse table.
578             Added by Roger, 2008.11.10. */
579         if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) {
580                 DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n",
581                           __func__, _offset, _size_byte);
582                 return;
583         }
584
585         efuseTbl = kmalloc(EFUSE_BT_MAP_LEN, GFP_KERNEL);
586         if (efuseTbl == NULL) {
587                 DBG_8723A("%s: efuseTbl malloc fail!\n", __func__);
588                 return;
589         }
590         /*  0xff will be efuse default value instead of 0x00. */
591         memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
592
593         EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
594                                  TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total);
595
596         for (bank = 1; bank < EFUSE_MAX_BANK; bank++) {
597                 if (hal_EfuseSwitchToBank(padapter, bank) == false) {
598                         DBG_8723A("%s: hal_EfuseSwitchToBank Fail!!\n",
599                                   __func__);
600                         goto exit;
601                 }
602
603                 eFuse_Addr = 0;
604
605                 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
606                         ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseHeader);
607                         if (efuseHeader == 0xFF)
608                                 break;
609
610                         /*  Check PG header for section num. */
611                         if (EXT_HEADER(efuseHeader)) {  /* extended header */
612                                 offset = GET_HDR_OFFSET_2_0(efuseHeader);
613
614                                 ReadEFuseByte23a(padapter, eFuse_Addr++,
615                                               &efuseExtHdr);
616                                 if (ALL_WORDS_DISABLED(efuseExtHdr)) {
617                                         continue;
618                                 }
619
620                                 offset |= ((efuseExtHdr & 0xF0) >> 1);
621                                 wden = (efuseExtHdr & 0x0F);
622                         } else {
623                                 offset = ((efuseHeader >> 4) & 0x0f);
624                                 wden = (efuseHeader & 0x0f);
625                         }
626
627                         if (offset < EFUSE_BT_MAX_SECTION) {
628                                 u16 addr;
629
630                                 /*  Get word enable value from PG header */
631
632                                 addr = offset * PGPKT_DATA_SIZE;
633                                 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
634                                         /*  Check word enable condition in
635                                             the section */
636                                         if (!(wden & (0x01 << i))) {
637                                                 ReadEFuseByte23a(padapter,
638                                                               eFuse_Addr++,
639                                                               &efuseData);
640                                                 efuseTbl[addr] = efuseData;
641
642                                                 ReadEFuseByte23a(padapter,
643                                                               eFuse_Addr++,
644                                                               &efuseData);
645                                                 efuseTbl[addr + 1] = efuseData;
646                                         }
647                                         addr += 2;
648                                 }
649                         } else {
650                                 DBG_8723A(KERN_ERR
651                                           "%s: offset(%d) is illegal!!\n",
652                                           __func__, offset);
653                                 eFuse_Addr += Efuse_CalculateWordCnts23a(wden) * 2;
654                         }
655                 }
656
657                 if ((eFuse_Addr - 1) < total) {
658                         DBG_8723A("%s: bank(%d) data end at %#x\n",
659                                   __func__, bank, eFuse_Addr - 1);
660                         break;
661                 }
662         }
663
664         /*  switch bank back to bank 0 for later BT and wifi use. */
665         hal_EfuseSwitchToBank(padapter, 0);
666
667         /*  Copy from Efuse map to output pointer memory!!! */
668         for (i = 0; i < _size_byte; i++)
669                 pbuf[i] = efuseTbl[_offset + i];
670
671         /*  */
672         /*  Calculate Efuse utilization. */
673         /*  */
674         EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
675                                  TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
676         used = (EFUSE_BT_REAL_BANK_CONTENT_LEN * (bank - 1)) + eFuse_Addr - 1;
677         pHalData->BTEfuseUsedBytes = used;
678
679 exit:
680         kfree(efuseTbl);
681 }
682
683 void
684 rtl8723a_readefuse(struct rtw_adapter *padapter,
685                    u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf)
686 {
687         if (efuseType == EFUSE_WIFI)
688                 hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf);
689         else
690                 hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf);
691 }
692
693 u16 rtl8723a_EfuseGetCurrentSize_WiFi(struct rtw_adapter *padapter)
694 {
695         u16 efuse_addr = 0;
696         u8 hoffset = 0, hworden = 0;
697         u8 efuse_data, word_cnts = 0;
698         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
699
700         efuse_addr = pHalData->EfuseUsedBytes;
701
702         DBG_8723A("%s: start_efuse_addr = 0x%X\n", __func__, efuse_addr);
703
704         /*  switch bank back to bank 0 for later BT and wifi use. */
705         hal_EfuseSwitchToBank(padapter, 0);
706
707         while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
708                 if (efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data) ==
709                     _FAIL) {
710                         DBG_8723A(KERN_ERR "%s: efuse_OneByteRead23a Fail! "
711                                   "addr = 0x%X !!\n", __func__, efuse_addr);
712                         break;
713                 }
714
715                 if (efuse_data == 0xFF)
716                         break;
717
718                 if (EXT_HEADER(efuse_data)) {
719                         hoffset = GET_HDR_OFFSET_2_0(efuse_data);
720                         efuse_addr++;
721                         efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data);
722                         if (ALL_WORDS_DISABLED(efuse_data)) {
723                                 continue;
724                         }
725
726                         hoffset |= ((efuse_data & 0xF0) >> 1);
727                         hworden = efuse_data & 0x0F;
728                 } else {
729                         hoffset = (efuse_data >> 4) & 0x0F;
730                         hworden = efuse_data & 0x0F;
731                 }
732
733                 word_cnts = Efuse_CalculateWordCnts23a(hworden);
734                 efuse_addr += (word_cnts * 2) + 1;
735         }
736
737         pHalData->EfuseUsedBytes = efuse_addr;
738
739         DBG_8723A("%s: CurrentSize =%d\n", __func__, efuse_addr);
740
741         return efuse_addr;
742 }
743
744 u16 rtl8723a_EfuseGetCurrentSize_BT(struct rtw_adapter *padapter)
745 {
746         u16 btusedbytes;
747         u16 efuse_addr;
748         u8 bank, startBank;
749         u8 hoffset = 0, hworden = 0;
750         u8 efuse_data, word_cnts = 0;
751         u16 retU2 = 0;
752         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
753
754         btusedbytes = pHalData->BTEfuseUsedBytes;
755
756         efuse_addr = (u16) ((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN));
757         startBank = (u8) (1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN));
758
759         DBG_8723A("%s: start from bank =%d addr = 0x%X\n", __func__, startBank,
760                   efuse_addr);
761
762         EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
763                                  TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2);
764
765         for (bank = startBank; bank < EFUSE_MAX_BANK; bank++) {
766                 if (hal_EfuseSwitchToBank(padapter, bank) == false) {
767                         DBG_8723A(KERN_ERR "%s: switch bank(%d) Fail!!\n",
768                                   __func__, bank);
769                         bank = EFUSE_MAX_BANK;
770                         break;
771                 }
772
773                 /*  only when bank is switched we have to reset
774                     the efuse_addr. */
775                 if (bank != startBank)
776                         efuse_addr = 0;
777
778                 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
779                         if (efuse_OneByteRead23a(padapter, efuse_addr,
780                                               &efuse_data) == _FAIL) {
781                                 DBG_8723A(KERN_ERR "%s: efuse_OneByteRead23a Fail!"
782                                           " addr = 0x%X !!\n",
783                                           __func__, efuse_addr);
784                                 bank = EFUSE_MAX_BANK;
785                                 break;
786                         }
787
788                         if (efuse_data == 0xFF)
789                                 break;
790
791                         if (EXT_HEADER(efuse_data)) {
792                                 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
793                                 efuse_addr++;
794                                 efuse_OneByteRead23a(padapter, efuse_addr,
795                                                   &efuse_data);
796                                 if (ALL_WORDS_DISABLED(efuse_data)) {
797                                         efuse_addr++;
798                                         continue;
799                                 }
800
801                                 hoffset |= ((efuse_data & 0xF0) >> 1);
802                                 hworden = efuse_data & 0x0F;
803                         } else {
804                                 hoffset = (efuse_data >> 4) & 0x0F;
805                                 hworden = efuse_data & 0x0F;
806                         }
807                         word_cnts = Efuse_CalculateWordCnts23a(hworden);
808                         /* read next header */
809                         efuse_addr += (word_cnts * 2) + 1;
810                 }
811
812                 /*  Check if we need to check next bank efuse */
813                 if (efuse_addr < retU2) {
814                         break;  /*  don't need to check next bank. */
815                 }
816         }
817
818         retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
819         pHalData->BTEfuseUsedBytes = retU2;
820
821         DBG_8723A("%s: CurrentSize =%d\n", __func__, retU2);
822         return retU2;
823 }
824
825 bool
826 rtl8723a_EfusePgPacketRead(struct rtw_adapter *padapter, u8 offset, u8 *data)
827 {
828         u8 efuse_data, word_cnts = 0;
829         u16 efuse_addr = 0;
830         u8 hoffset = 0, hworden = 0;
831         u8 i;
832         u8 max_section = 0;
833         s32 ret;
834
835         if (data == NULL)
836                 return false;
837
838         EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION,
839                                  &max_section);
840         if (offset > max_section) {
841                 DBG_8723A("%s: Packet offset(%d) is illegal(>%d)!\n",
842                           __func__, offset, max_section);
843                 return false;
844         }
845
846         memset(data, 0xFF, PGPKT_DATA_SIZE);
847         ret = true;
848
849         /*  */
850         /*  <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the
851             end of Efuse by CP. */
852         /*  Skip dummy parts to prevent unexpected data read from Efuse. */
853         /*  By pass right now. 2009.02.19. */
854         /*  */
855         while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
856                 if (efuse_OneByteRead23a(padapter, efuse_addr++, &efuse_data) ==
857                     _FAIL) {
858                         ret = false;
859                         break;
860                 }
861
862                 if (efuse_data == 0xFF)
863                         break;
864
865                 if (EXT_HEADER(efuse_data)) {
866                         hoffset = GET_HDR_OFFSET_2_0(efuse_data);
867                         efuse_OneByteRead23a(padapter, efuse_addr++, &efuse_data);
868                         if (ALL_WORDS_DISABLED(efuse_data)) {
869                                 DBG_8723A("%s: Error!! All words disabled!\n",
870                                           __func__);
871                                 continue;
872                         }
873
874                         hoffset |= ((efuse_data & 0xF0) >> 1);
875                         hworden = efuse_data & 0x0F;
876                 } else {
877                         hoffset = (efuse_data >> 4) & 0x0F;
878                         hworden = efuse_data & 0x0F;
879                 }
880
881                 if (hoffset == offset) {
882                         for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
883                                 /* Check word enable condition in the section */
884                                 if (!(hworden & (0x01 << i))) {
885                                         ReadEFuseByte23a(padapter, efuse_addr++,
886                                                       &efuse_data);
887                                         data[i * 2] = efuse_data;
888
889                                         ReadEFuseByte23a(padapter, efuse_addr++,
890                                                       &efuse_data);
891                                         data[(i * 2) + 1] = efuse_data;
892                                 }
893                         }
894                 } else {
895                         word_cnts = Efuse_CalculateWordCnts23a(hworden);
896                         efuse_addr += word_cnts * 2;
897                 }
898         }
899
900         return ret;
901 }
902
903 void rtl8723a_read_chip_version(struct rtw_adapter *padapter)
904 {
905         u32 value32;
906         struct hal_version ChipVersion;
907         struct hal_data_8723a *pHalData;
908
909         pHalData = GET_HAL_DATA(padapter);
910
911         value32 = rtl8723au_read32(padapter, REG_SYS_CFG);
912         ChipVersion.ICType = CHIP_8723A;
913         ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
914         ChipVersion.RFType = RF_TYPE_1T1R;
915         ChipVersion.VendorType =
916                 ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
917         ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT;   /*  IC version (CUT) */
918
919         /*  For regulator mode. by tynli. 2011.01.14 */
920         pHalData->RegulatorMode = ((value32 & SPS_SEL) ?
921                                    RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
922
923         value32 = rtl8723au_read32(padapter, REG_GPIO_OUTSTS);
924         /*  ROM code version. */
925         ChipVersion.ROMVer = ((value32 & RF_RL_ID) >> 20);
926
927         /*  For multi-function consideration. Added by Roger, 2010.10.06. */
928         pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
929         value32 = rtl8723au_read32(padapter, REG_MULTI_FUNC_CTRL);
930         pHalData->MultiFunc |=
931                 ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
932         pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
933         pHalData->MultiFunc |=
934                 ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
935         pHalData->PolarityCtl =
936                 ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT :
937                  RT_POLARITY_LOW_ACT);
938         dump_chip_info23a(ChipVersion);
939         pHalData->VersionID = ChipVersion;
940
941         if (IS_1T2R(ChipVersion))
942                 pHalData->rf_type = RF_1T2R;
943         else if (IS_2T2R(ChipVersion))
944                 pHalData->rf_type = RF_2T2R;
945         else
946                 pHalData->rf_type = RF_1T1R;
947
948         MSG_8723A("RF_Type is %x!!\n", pHalData->rf_type);
949 }
950
951 /*  */
952 /*  */
953 /*  20100209 Joseph: */
954 /*  This function is used only for 92C to set REG_BCN_CTRL(0x550) register. */
955 /*  We just reserve the value of the register in variable
956     pHalData->RegBcnCtrlVal and then operate */
957 /*  the value of the register via atomic operation. */
958 /*  This prevents from race condition when setting this register. */
959 /*  The value of pHalData->RegBcnCtrlVal is initialized in
960     HwConfigureRTL8192CE() function. */
961 /*  */
962 void SetBcnCtrlReg23a(struct rtw_adapter *padapter, u8 SetBits, u8 ClearBits)
963 {
964         struct hal_data_8723a *pHalData;
965         u32 addr;
966         u8 *pRegBcnCtrlVal;
967
968         pHalData = GET_HAL_DATA(padapter);
969         pRegBcnCtrlVal = (u8 *)&pHalData->RegBcnCtrlVal;
970
971         addr = REG_BCN_CTRL;
972
973         *pRegBcnCtrlVal = rtl8723au_read8(padapter, addr);
974         *pRegBcnCtrlVal |= SetBits;
975         *pRegBcnCtrlVal &= ~ClearBits;
976
977         rtl8723au_write8(padapter, addr, *pRegBcnCtrlVal);
978 }
979
980 void rtl8723a_InitBeaconParameters(struct rtw_adapter *padapter)
981 {
982         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
983
984         rtl8723au_write16(padapter, REG_BCN_CTRL, 0x1010);
985         pHalData->RegBcnCtrlVal = 0x1010;
986
987         /*  TODO: Remove these magic number */
988         rtl8723au_write16(padapter, REG_TBTT_PROHIBIT, 0x6404); /*  ms */
989         /*  Firmware will control REG_DRVERLYINT when power saving is enable, */
990         /*  so don't set this register on STA mode. */
991         if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == false)
992                 rtl8723au_write8(padapter, REG_DRVERLYINT,
993                                  DRIVER_EARLY_INT_TIME);
994         /*  2ms */
995         rtl8723au_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
996
997         /*  Suggested by designer timchen. Change beacon AIFS to the
998             largest number beacause test chip does not contension before
999             sending beacon. by tynli. 2009.11.03 */
1000         rtl8723au_write16(padapter, REG_BCNTCFG, 0x660F);
1001 }
1002
1003 static void ResumeTxBeacon(struct rtw_adapter *padapter)
1004 {
1005         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1006
1007         /*  2010.03.01. Marked by tynli. No need to call workitem beacause
1008             we record the value */
1009         /*  which should be read from register to a global variable. */
1010
1011         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
1012
1013         pHalData->RegFwHwTxQCtrl |= BIT(6);
1014         rtl8723au_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
1015                          pHalData->RegFwHwTxQCtrl);
1016         rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xff);
1017         pHalData->RegReg542 |= BIT(0);
1018         rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
1019 }
1020
1021 static void StopTxBeacon(struct rtw_adapter *padapter)
1022 {
1023         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1024
1025         /*  2010.03.01. Marked by tynli. No need to call workitem beacause
1026             we record the value */
1027         /*  which should be read from register to a global variable. */
1028
1029         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
1030
1031         pHalData->RegFwHwTxQCtrl &= ~BIT(6);
1032         rtl8723au_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
1033                          pHalData->RegFwHwTxQCtrl);
1034         rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64);
1035         pHalData->RegReg542 &= ~BIT(0);
1036         rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
1037
1038         CheckFwRsvdPageContent23a(padapter); /*  2010.06.23. Added by tynli. */
1039 }
1040
1041 static void _BeaconFunctionEnable(struct rtw_adapter *padapter, u8 Enable,
1042                                   u8 Linked)
1043 {
1044         SetBcnCtrlReg23a(padapter, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB,
1045                       0);
1046         rtl8723au_write8(padapter, REG_RD_CTRL + 1, 0x6F);
1047 }
1048
1049 void rtl8723a_SetBeaconRelatedRegisters(struct rtw_adapter *padapter)
1050 {
1051         u32 value32;
1052         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1053         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1054
1055         /* reset TSF, enable update TSF, correcting TSF On Beacon */
1056
1057         /* REG_BCN_INTERVAL */
1058         /* REG_BCNDMATIM */
1059         /* REG_ATIMWND */
1060         /* REG_TBTT_PROHIBIT */
1061         /* REG_DRVERLYINT */
1062         /* REG_BCN_MAX_ERR */
1063         /* REG_BCNTCFG (0x510) */
1064         /* REG_DUAL_TSF_RST */
1065         /* REG_BCN_CTRL (0x550) */
1066
1067         /*  */
1068         /*  ATIM window */
1069         /*  */
1070         rtl8723au_write16(padapter, REG_ATIMWND, 2);
1071
1072         /*  */
1073         /*  Beacon interval (in unit of TU). */
1074         /*  */
1075         rtl8723au_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
1076
1077         rtl8723a_InitBeaconParameters(padapter);
1078
1079         rtl8723au_write8(padapter, REG_SLOT, 0x09);
1080
1081         /*  */
1082         /*  Reset TSF Timer to zero, added by Roger. 2008.06.24 */
1083         /*  */
1084         value32 = rtl8723au_read32(padapter, REG_TCR);
1085         value32 &= ~TSFRST;
1086         rtl8723au_write32(padapter, REG_TCR, value32);
1087
1088         value32 |= TSFRST;
1089         rtl8723au_write32(padapter, REG_TCR, value32);
1090
1091         /*  NOTE: Fix test chip's bug (about contention windows's randomness) */
1092         if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE |
1093                           WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE) == true) {
1094                 rtl8723au_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
1095                 rtl8723au_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
1096         }
1097
1098         _BeaconFunctionEnable(padapter, true, true);
1099
1100         ResumeTxBeacon(padapter);
1101         SetBcnCtrlReg23a(padapter, DIS_BCNQ_SUB, 0);
1102 }
1103
1104 void rtl8723a_SetHalODMVar(struct rtw_adapter *Adapter,
1105                            enum hal_odm_variable eVariable,
1106                            void *pValue1, bool bSet)
1107 {
1108         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1109         struct dm_odm_t *podmpriv = &pHalData->odmpriv;
1110         switch (eVariable) {
1111         case HAL_ODM_STA_INFO:
1112         {
1113                 struct sta_info *psta = (struct sta_info *)pValue1;
1114
1115                 if (bSet) {
1116                         DBG_8723A("Set STA_(%d) info\n", psta->mac_id);
1117                         ODM_CmnInfoPtrArrayHook23a(podmpriv,
1118                                                 ODM_CMNINFO_STA_STATUS,
1119                                                 psta->mac_id, psta);
1120                 } else {
1121                         DBG_8723A("Clean STA_(%d) info\n", psta->mac_id);
1122                                 ODM_CmnInfoPtrArrayHook23a(podmpriv,
1123                                                         ODM_CMNINFO_STA_STATUS,
1124                                                         psta->mac_id, NULL);
1125                 }
1126         }
1127                 break;
1128         case HAL_ODM_P2P_STATE:
1129                 ODM_CmnInfoUpdate23a(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
1130                 break;
1131         case HAL_ODM_WIFI_DISPLAY_STATE:
1132                 ODM_CmnInfoUpdate23a(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
1133                 break;
1134         default:
1135                 break;
1136         }
1137 }
1138
1139 void rtl8723a_notch_filter(struct rtw_adapter *adapter, bool enable)
1140 {
1141         if (enable) {
1142                 DBG_8723A("Enable notch filter\n");
1143                 rtl8723au_write8(adapter, rOFDM0_RxDSP + 1,
1144                                  rtl8723au_read8(adapter, rOFDM0_RxDSP + 1) |
1145                                  BIT(1));
1146         } else {
1147                 DBG_8723A("Disable notch filter\n");
1148                 rtl8723au_write8(adapter, rOFDM0_RxDSP + 1,
1149                            rtl8723au_read8(adapter, rOFDM0_RxDSP + 1) &
1150                                  ~BIT(1));
1151         }
1152 }
1153
1154 bool c2h_id_filter_ccx_8723a(u8 id)
1155 {
1156         bool ret = false;
1157         if (id == C2H_CCX_TX_RPT)
1158                 ret = true;
1159
1160         return ret;
1161 }
1162
1163 int c2h_handler_8723a(struct rtw_adapter *padapter, struct c2h_evt_hdr *c2h_evt)
1164 {
1165         int ret = _SUCCESS;
1166         u8 i = 0;
1167
1168         if (c2h_evt == NULL) {
1169                 DBG_8723A("%s c2h_evt is NULL\n", __func__);
1170                 ret = _FAIL;
1171                 goto exit;
1172         }
1173
1174         switch (c2h_evt->id) {
1175         case C2H_DBG:
1176                 RT_TRACE(_module_hal_init_c_, _drv_info_,
1177                          ("C2HCommandHandler: %s\n", c2h_evt->payload));
1178                 break;
1179
1180         case C2H_CCX_TX_RPT:
1181                 handle_txrpt_ccx_8723a(padapter, c2h_evt->payload);
1182                 break;
1183         case C2H_EXT_RA_RPT:
1184                 break;
1185         case C2H_HW_INFO_EXCH:
1186                 RT_TRACE(_module_hal_init_c_, _drv_info_,
1187                          ("[BT], C2H_HW_INFO_EXCH\n"));
1188                 for (i = 0; i < c2h_evt->plen; i++) {
1189                         RT_TRACE(_module_hal_init_c_, _drv_info_,
1190                                  ("[BT], tmpBuf[%d]= 0x%x\n", i,
1191                                   c2h_evt->payload[i]));
1192                 }
1193                 break;
1194
1195         case C2H_C2H_H2C_TEST:
1196                 RT_TRACE(_module_hal_init_c_, _drv_info_,
1197                          ("[BT], C2H_H2C_TEST\n"));
1198                 RT_TRACE(_module_hal_init_c_, _drv_info_,
1199                          ("[BT], tmpBuf[0]/[1]/[2]/[3]/[4]= 0x%x/ 0x%x/ "
1200                           "0x%x/ 0x%x/ 0x%x\n", c2h_evt->payload[0],
1201                           c2h_evt->payload[1], c2h_evt->payload[2],
1202                           c2h_evt->payload[3], c2h_evt->payload[4]));
1203                 break;
1204
1205         case C2H_BT_INFO:
1206                 DBG_8723A("%s ,  Got  C2H_BT_INFO \n", __func__);
1207                 rtl8723a_fw_c2h_BT_info(padapter,
1208                                         c2h_evt->payload, c2h_evt->plen);
1209                 break;
1210
1211         default:
1212                 ret = _FAIL;
1213                 break;
1214         }
1215
1216 exit:
1217         return ret;
1218 }
1219
1220 void rtl8723a_InitAntenna_Selection(struct rtw_adapter *padapter)
1221 {
1222         u8 val;
1223
1224         val = rtl8723au_read8(padapter, REG_LEDCFG2);
1225         /*  Let 8051 take control antenna settting */
1226         val |= BIT(7);          /*  DPDT_SEL_EN, 0x4C[23] */
1227         rtl8723au_write8(padapter, REG_LEDCFG2, val);
1228 }
1229
1230 void rtl8723a_CheckAntenna_Selection(struct rtw_adapter *padapter)
1231 {
1232         u8 val;
1233
1234         val = rtl8723au_read8(padapter, REG_LEDCFG2);
1235         /*  Let 8051 take control antenna settting */
1236         if (!(val & BIT(7))) {
1237                 val |= BIT(7);  /*  DPDT_SEL_EN, 0x4C[23] */
1238                 rtl8723au_write8(padapter, REG_LEDCFG2, val);
1239         }
1240 }
1241
1242 void rtl8723a_DeinitAntenna_Selection(struct rtw_adapter *padapter)
1243 {
1244         u8 val;
1245
1246         val = rtl8723au_read8(padapter, REG_LEDCFG2);
1247         /*  Let 8051 take control antenna settting */
1248         val &= ~BIT(7);         /*  DPDT_SEL_EN, clear 0x4C[23] */
1249         rtl8723au_write8(padapter, REG_LEDCFG2, val);
1250 }
1251
1252 void rtl8723a_init_default_value(struct rtw_adapter *padapter)
1253 {
1254         struct hal_data_8723a *pHalData;
1255         struct dm_priv *pdmpriv;
1256         u8 i;
1257
1258         pHalData = GET_HAL_DATA(padapter);
1259         pdmpriv = &pHalData->dmpriv;
1260
1261         /*  init default value */
1262         pHalData->fw_ractrl = false;
1263         pHalData->bIQKInitialized = false;
1264         if (!padapter->pwrctrlpriv.bkeepfwalive)
1265                 pHalData->LastHMEBoxNum = 0;
1266
1267         pHalData->bIQKInitialized = false;
1268
1269         /*  init dm default value */
1270         pdmpriv->TM_Trigger = 0;        /* for IQK */
1271 /*      pdmpriv->binitialized = false; */
1272 /*      pdmpriv->prv_traffic_idx = 3; */
1273 /*      pdmpriv->initialize = 0; */
1274
1275         pdmpriv->ThermalValue_HP_index = 0;
1276         for (i = 0; i < HP_THERMAL_NUM; i++)
1277                 pdmpriv->ThermalValue_HP[i] = 0;
1278
1279         /*  init Efuse variables */
1280         pHalData->EfuseUsedBytes = 0;
1281         pHalData->BTEfuseUsedBytes = 0;
1282 }
1283
1284 u8 GetEEPROMSize8723A(struct rtw_adapter *padapter)
1285 {
1286         u8 size = 0;
1287         u32 cr;
1288
1289         cr = rtl8723au_read16(padapter, REG_9346CR);
1290         /*  6: EEPROM used is 93C46, 4: boot from E-Fuse. */
1291         size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
1292
1293         MSG_8723A("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
1294
1295         return size;
1296 }
1297
1298 /*  */
1299 /*  */
1300 /*  LLT R/W/Init function */
1301 /*  */
1302 /*  */
1303 static int _LLTWrite(struct rtw_adapter *padapter, u32 address, u32 data)
1304 {
1305         int status = _SUCCESS;
1306         s32 count = 0;
1307         u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
1308                     _LLT_OP(_LLT_WRITE_ACCESS);
1309         u16 LLTReg = REG_LLT_INIT;
1310
1311         rtl8723au_write32(padapter, LLTReg, value);
1312
1313         /* polling */
1314         do {
1315                 value = rtl8723au_read32(padapter, LLTReg);
1316                 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) {
1317                         break;
1318                 }
1319
1320                 if (count > POLLING_LLT_THRESHOLD) {
1321                         RT_TRACE(_module_hal_init_c_, _drv_err_,
1322                                  ("Failed to polling write LLT done at "
1323                                   "address %d!\n", address));
1324                         status = _FAIL;
1325                         break;
1326                 }
1327         } while (count++);
1328
1329         return status;
1330 }
1331
1332 int InitLLTTable23a(struct rtw_adapter *padapter, u32 boundary)
1333 {
1334         int status = _SUCCESS;
1335         u32 i;
1336         u32 txpktbuf_bndy = boundary;
1337         u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;
1338
1339         for (i = 0; i < (txpktbuf_bndy - 1); i++) {
1340                 status = _LLTWrite(padapter, i, i + 1);
1341                 if (status != _SUCCESS) {
1342                         return status;
1343                 }
1344         }
1345
1346         /*  end of list */
1347         status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
1348         if (status != _SUCCESS) {
1349                 return status;
1350         }
1351
1352         /*  Make the other pages as ring buffer */
1353         /*  This ring buffer is used as beacon buffer if we config this
1354             MAC as two MAC transfer. */
1355         /*  Otherwise used as local loopback buffer. */
1356         for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
1357                 status = _LLTWrite(padapter, i, (i + 1));
1358                 if (_SUCCESS != status) {
1359                         return status;
1360                 }
1361         }
1362
1363         /*  Let last entry point to the start entry of ring buffer */
1364         status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
1365         if (status != _SUCCESS) {
1366                 return status;
1367         }
1368
1369         return status;
1370 }
1371
1372 static void _DisableGPIO(struct rtw_adapter *padapter)
1373 {
1374 /***************************************
1375 j. GPIO_PIN_CTRL 0x44[31:0]= 0x000
1376 k.Value = GPIO_PIN_CTRL[7:0]
1377 l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write external PIN level
1378 m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
1379 n. LEDCFG 0x4C[15:0] = 0x8080
1380 ***************************************/
1381         u32 value32;
1382         u32 u4bTmp;
1383
1384         /* 1. Disable GPIO[7:0] */
1385         rtl8723au_write16(padapter, REG_GPIO_PIN_CTRL + 2, 0x0000);
1386         value32 = rtl8723au_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
1387         u4bTmp = value32 & 0x000000FF;
1388         value32 |= ((u4bTmp << 8) | 0x00FF0000);
1389         rtl8723au_write32(padapter, REG_GPIO_PIN_CTRL, value32);
1390
1391         /*  */
1392         /*  <Roger_Notes> For RTL8723u multi-function configuration which
1393             was autoload from Efuse offset 0x0a and 0x0b, */
1394         /*  WLAN HW GPIO[9], GPS HW GPIO[10] and BT HW GPIO[11]. */
1395         /*  Added by Roger, 2010.10.07. */
1396         /*  */
1397         /* 2. Disable GPIO[8] and GPIO[12] */
1398
1399         /*  Configure all pins as input mode. */
1400         rtl8723au_write16(padapter, REG_GPIO_IO_SEL_2, 0x0000);
1401         value32 = rtl8723au_read32(padapter, REG_GPIO_PIN_CTRL_2) & 0xFFFF001F;
1402         u4bTmp = value32 & 0x0000001F;
1403         /*  Set pin 8, 10, 11 and pin 12 to output mode. */
1404         value32 |= ((u4bTmp << 8) | 0x001D0000);
1405         rtl8723au_write32(padapter, REG_GPIO_PIN_CTRL_2, value32);
1406
1407         /* 3. Disable LED0 & 1 */
1408         rtl8723au_write16(padapter, REG_LEDCFG0, 0x8080);
1409 }                               /* end of _DisableGPIO() */
1410
1411 static void _DisableRFAFEAndResetBB8192C(struct rtw_adapter *padapter)
1412 {
1413 /**************************************
1414 a.      TXPAUSE 0x522[7:0] = 0xFF               Pause MAC TX queue
1415 b.      RF path 0 offset 0x00 = 0x00            disable RF
1416 c.      APSD_CTRL 0x600[7:0] = 0x40
1417 d.      SYS_FUNC_EN 0x02[7:0] = 0x16            reset BB state machine
1418 e.      SYS_FUNC_EN 0x02[7:0] = 0x14            reset BB state machine
1419 ***************************************/
1420         u8 eRFPath = 0, value8 = 0;
1421
1422         rtl8723au_write8(padapter, REG_TXPAUSE, 0xFF);
1423
1424         PHY_SetRFReg(padapter, (enum RF_RADIO_PATH) eRFPath, 0x0, bMaskByte0, 0x0);
1425
1426         value8 |= APSDOFF;
1427         rtl8723au_write8(padapter, REG_APSD_CTRL, value8);      /* 0x40 */
1428
1429         /*  Set BB reset at first */
1430         value8 = 0;
1431         value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
1432         rtl8723au_write8(padapter, REG_SYS_FUNC_EN, value8);    /* 0x16 */
1433
1434         /*  Set global reset. */
1435         value8 &= ~FEN_BB_GLB_RSTn;
1436         rtl8723au_write8(padapter, REG_SYS_FUNC_EN, value8);    /* 0x14 */
1437
1438         /*  2010/08/12 MH We need to set BB/GLBAL reset to save power
1439             for SS mode. */
1440
1441 /*      RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n")); */
1442 }
1443
1444 static void _DisableRFAFEAndResetBB(struct rtw_adapter *padapter)
1445 {
1446         _DisableRFAFEAndResetBB8192C(padapter);
1447 }
1448
1449 static void _ResetDigitalProcedure1_92C(struct rtw_adapter *padapter,
1450                                         bool bWithoutHWSM)
1451 {
1452         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1453
1454         if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20)) {
1455         /*****************************
1456         f.      MCUFWDL 0x80[7:0]= 0            reset MCU ready status
1457         g.      SYS_FUNC_EN 0x02[10]= 0         reset MCU register, (8051 reset)
1458         h.      SYS_FUNC_EN 0x02[15-12]= 5      reset MAC register, DCORE
1459         i.     SYS_FUNC_EN 0x02[10]= 1          enable MCU register,
1460                                                 (8051 enable)
1461         ******************************/
1462                 u16 valu16 = 0;
1463                 rtl8723au_write8(padapter, REG_MCUFWDL, 0);
1464
1465                 valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN);
1466                 /* reset MCU , 8051 */
1467                 rtl8723au_write16(padapter, REG_SYS_FUNC_EN,
1468                                   valu16 & (~FEN_CPUEN));
1469
1470                 valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN) & 0x0FFF;
1471                 /* reset MAC */
1472                 rtl8723au_write16(padapter, REG_SYS_FUNC_EN,
1473                                   valu16 | (FEN_HWPDN | FEN_ELDR));
1474
1475                 valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN);
1476                 /* enable MCU , 8051 */
1477                 rtl8723au_write16(padapter, REG_SYS_FUNC_EN,
1478                                   valu16 | FEN_CPUEN);
1479         } else {
1480                 u8 retry_cnts = 0;
1481
1482                 /*  2010/08/12 MH For USB SS, we can not stop 8051 when we
1483                     are trying to enter IPS/HW&SW radio off. For
1484                     S3/S4/S5/Disable, we can stop 8051 because */
1485                 /*  we will init FW when power on again. */
1486                 /*  If we want to SS mode, we can not reset 8051. */
1487                 if (rtl8723au_read8(padapter, REG_MCUFWDL) & BIT(1)) {
1488                         /* IF fw in RAM code, do reset */
1489                         if (padapter->bFWReady) {
1490                                 /*  2010/08/25 MH Accordign to RD alfred's
1491                                     suggestion, we need to disable other */
1492                                 /*  HRCV INT to influence 8051 reset. */
1493                                 rtl8723au_write8(padapter, REG_FWIMR, 0x20);
1494                                 /*  2011/02/15 MH According to Alex's
1495                                     suggestion, close mask to prevent
1496                                     incorrect FW write operation. */
1497                                 rtl8723au_write8(padapter, REG_FTIMR, 0x00);
1498                                 rtl8723au_write8(padapter, REG_FSIMR, 0x00);
1499
1500                                 /* 8051 reset by self */
1501                                 rtl8723au_write8(padapter, REG_HMETFR + 3,
1502                                                  0x20);
1503
1504                                 while ((retry_cnts++ < 100) &&
1505                                        (FEN_CPUEN &
1506                                         rtl8723au_read16(padapter,
1507                                                          REG_SYS_FUNC_EN))) {
1508                                         udelay(50);     /* us */
1509                                 }
1510
1511                                 if (retry_cnts >= 100) {
1512                                         /* Reset MAC and Enable 8051 */
1513                                         rtl8723au_write8(padapter,
1514                                                          REG_SYS_FUNC_EN + 1,
1515                                                          0x50);
1516                                         mdelay(10);
1517                                 }
1518                         }
1519                 }
1520                 /* Reset MAC and Enable 8051 */
1521                 rtl8723au_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54);
1522                 rtl8723au_write8(padapter, REG_MCUFWDL, 0);
1523         }
1524
1525         if (bWithoutHWSM) {
1526         /*****************************
1527                 Without HW auto state machine
1528         g.      SYS_CLKR 0x08[15:0] = 0x30A3            disable MAC clock
1529         h.      AFE_PLL_CTRL 0x28[7:0] = 0x80           disable AFE PLL
1530         i.      AFE_XTAL_CTRL 0x24[15:0] = 0x880F       gated AFE DIG_CLOCK
1531         j.      SYS_ISO_CTRL 0x00[7:0] = 0xF9           isolated digital to PON
1532         ******************************/
1533                 /* modify to 0x70A3 by Scott. */
1534                 rtl8723au_write16(padapter, REG_SYS_CLKR, 0x70A3);
1535                 rtl8723au_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
1536                 rtl8723au_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
1537                 rtl8723au_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
1538         } else {
1539                 /*  Disable all RF/BB power */
1540                 rtl8723au_write8(padapter, REG_RF_CTRL, 0x00);
1541         }
1542 }
1543
1544 static void _ResetDigitalProcedure1(struct rtw_adapter *padapter,
1545                                     bool bWithoutHWSM)
1546 {
1547         _ResetDigitalProcedure1_92C(padapter, bWithoutHWSM);
1548 }
1549
1550 static void _ResetDigitalProcedure2(struct rtw_adapter *padapter)
1551 {
1552 /*****************************
1553 k.      SYS_FUNC_EN 0x03[7:0] = 0x44            disable ELDR runction
1554 l.      SYS_CLKR 0x08[15:0] = 0x3083            disable ELDR clock
1555 m.      SYS_ISO_CTRL 0x01[7:0] = 0x83           isolated ELDR to PON
1556 ******************************/
1557         /* modify to 0x70a3 by Scott. */
1558         rtl8723au_write16(padapter, REG_SYS_CLKR, 0x70a3);
1559         /* modify to 0x82 by Scott. */
1560         rtl8723au_write8(padapter, REG_SYS_ISO_CTRL + 1, 0x82);
1561 }
1562
1563 static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM)
1564 {
1565         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1566         u16 value16 = 0;
1567         u8 value8 = 0;
1568
1569         if (bWithoutHWSM) {
1570         /*****************************
1571         n.      LDOA15_CTRL 0x20[7:0] = 0x04    disable A15 power
1572         o.      LDOV12D_CTRL 0x21[7:0] = 0x54   disable digital core power
1573         r.      When driver call disable, the ASIC will turn off remaining
1574                 clock automatically
1575         ******************************/
1576
1577                 rtl8723au_write8(padapter, REG_LDOA15_CTRL, 0x04);
1578                 /* rtl8723au_write8(padapter, REG_LDOV12D_CTRL, 0x54); */
1579
1580                 value8 = rtl8723au_read8(padapter, REG_LDOV12D_CTRL);
1581                 value8 &= (~LDV12_EN);
1582                 rtl8723au_write8(padapter, REG_LDOV12D_CTRL, value8);
1583 /*              RT_TRACE(COMP_INIT, DBG_LOUD,
1584                 (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n", value8)); */
1585         }
1586
1587         /*****************************
1588         h.      SPS0_CTRL 0x11[7:0] = 0x23              enter PFM mode
1589         i.      APS_FSMCO 0x04[15:0] = 0x4802           set USB suspend
1590         ******************************/
1591         value8 = 0x23;
1592         if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
1593                 value8 |= BIT(3);
1594
1595         rtl8723au_write8(padapter, REG_SPS0_CTRL, value8);
1596
1597         if (bWithoutHWSM) {
1598                 /* value16 |= (APDM_HOST | FSM_HSUS |/PFM_ALDN); */
1599                 /*  2010/08/31 According to Filen description, we need to
1600                     use HW to shut down 8051 automatically. */
1601                 /*  Becasue suspend operatione need the asistance of 8051
1602                     to wait for 3ms. */
1603                 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
1604         } else {
1605                 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
1606         }
1607
1608         rtl8723au_write16(padapter, REG_APS_FSMCO, value16);    /* 0x4802 */
1609
1610         rtl8723au_write8(padapter, REG_RSV_CTRL, 0x0e);
1611 }
1612
1613 /*  HW Auto state machine */
1614 int CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU)
1615 {
1616         int rtStatus = _SUCCESS;
1617
1618         if (padapter->bSurpriseRemoved) {
1619                 return rtStatus;
1620         }
1621         /*  RF Off Sequence ==== */
1622         _DisableRFAFEAndResetBB(padapter);
1623
1624         /*   ==== Reset digital sequence   ====== */
1625         _ResetDigitalProcedure1(padapter, false);
1626
1627         /*   ==== Pull GPIO PIN to balance level and LED control ====== */
1628         _DisableGPIO(padapter);
1629
1630         /*   ==== Disable analog sequence === */
1631         _DisableAnalog(padapter, false);
1632
1633         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1634                  ("======> Card disable finished.\n"));
1635
1636         return rtStatus;
1637 }
1638
1639 /*  without HW Auto state machine */
1640 int CardDisableWithoutHWSM(struct rtw_adapter *padapter)
1641 {
1642         int rtStatus = _SUCCESS;
1643
1644         /* RT_TRACE(COMP_INIT, DBG_LOUD,
1645            ("======> Card Disable Without HWSM .\n")); */
1646         if (padapter->bSurpriseRemoved) {
1647                 return rtStatus;
1648         }
1649
1650         /*  RF Off Sequence ==== */
1651         _DisableRFAFEAndResetBB(padapter);
1652
1653         /*   ==== Reset digital sequence   ====== */
1654         _ResetDigitalProcedure1(padapter, true);
1655
1656         /*   ==== Pull GPIO PIN to balance level and LED control ====== */
1657         _DisableGPIO(padapter);
1658
1659         /*   ==== Reset digital sequence   ====== */
1660         _ResetDigitalProcedure2(padapter);
1661
1662         /*   ==== Disable analog sequence === */
1663         _DisableAnalog(padapter, true);
1664
1665         /* RT_TRACE(COMP_INIT, DBG_LOUD,
1666            ("<====== Card Disable Without HWSM .\n")); */
1667         return rtStatus;
1668 }
1669
1670 void Hal_InitPGData(struct rtw_adapter *padapter, u8 *PROMContent)
1671 {
1672         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1673
1674         if (false == pEEPROM->bautoload_fail_flag) {    /*  autoload OK. */
1675                 if (!pEEPROM->EepromOrEfuse) {
1676                         /*  Read EFUSE real map to shadow. */
1677                         EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI);
1678                         memcpy((void *)PROMContent,
1679                                (void *)pEEPROM->efuse_eeprom_data,
1680                                HWSET_MAX_SIZE);
1681                 }
1682         } else {                /* autoload fail */
1683                 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,
1684                          ("AutoLoad Fail reported from CR9346!!\n"));
1685 /*              pHalData->AutoloadFailFlag = true; */
1686                 /* update to default value 0xFF */
1687                 if (false == pEEPROM->EepromOrEfuse)
1688                         EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI);
1689                 memcpy((void *)PROMContent, (void *)pEEPROM->efuse_eeprom_data,
1690                        HWSET_MAX_SIZE);
1691         }
1692 }
1693
1694 void Hal_EfuseParseIDCode(struct rtw_adapter *padapter, u8 *hwinfo)
1695 {
1696         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1697 /*      struct hal_data_8723a   *pHalData = GET_HAL_DATA(padapter); */
1698         u16 EEPROMId;
1699
1700         /*  Checl 0x8129 again for making sure autoload status!! */
1701         EEPROMId = le16_to_cpu(*((u16 *) hwinfo));
1702         if (EEPROMId != RTL_EEPROM_ID) {
1703                 DBG_8723A("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
1704                 pEEPROM->bautoload_fail_flag = true;
1705         } else {
1706                 pEEPROM->bautoload_fail_flag = false;
1707         }
1708
1709         RT_TRACE(_module_hal_init_c_, _drv_info_,
1710                  ("EEPROM ID = 0x%04x\n", EEPROMId));
1711 }
1712
1713 static void Hal_EEValueCheck(u8 EEType, void *pInValue, void *pOutValue)
1714 {
1715         switch (EEType) {
1716         case EETYPE_TX_PWR:
1717         {
1718                 u8 *pIn, *pOut;
1719                 pIn = (u8 *) pInValue;
1720                 pOut = (u8 *) pOutValue;
1721                 if (*pIn <= 63)
1722                         *pOut = *pIn;
1723                 else {
1724                         RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
1725                                  ("EETYPE_TX_PWR, value =%d is invalid, set "
1726                                   "to default = 0x%x\n",
1727                                   *pIn, EEPROM_Default_TxPowerLevel));
1728                         *pOut = EEPROM_Default_TxPowerLevel;
1729                 }
1730         }
1731                 break;
1732         default:
1733                 break;
1734         }
1735 }
1736
1737 static void
1738 Hal_ReadPowerValueFromPROM_8723A(struct txpowerinfo *pwrInfo,
1739                                  u8 *PROMContent, bool AutoLoadFail)
1740 {
1741         u32 rfPath, eeAddr, group, rfPathMax = 1;
1742
1743         memset(pwrInfo, 0, sizeof(*pwrInfo));
1744
1745         if (AutoLoadFail) {
1746                 for (group = 0; group < MAX_CHNL_GROUP; group++) {
1747                         for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
1748                                 pwrInfo->CCKIndex[rfPath][group] =
1749                                         EEPROM_Default_TxPowerLevel;
1750                                 pwrInfo->HT40_1SIndex[rfPath][group] =
1751                                         EEPROM_Default_TxPowerLevel;
1752                                 pwrInfo->HT40_2SIndexDiff[rfPath][group] =
1753                                         EEPROM_Default_HT40_2SDiff;
1754                                 pwrInfo->HT20IndexDiff[rfPath][group] =
1755                                         EEPROM_Default_HT20_Diff;
1756                                 pwrInfo->OFDMIndexDiff[rfPath][group] =
1757                                         EEPROM_Default_LegacyHTTxPowerDiff;
1758                                 pwrInfo->HT40MaxOffset[rfPath][group] =
1759                                         EEPROM_Default_HT40_PwrMaxOffset;
1760                                 pwrInfo->HT20MaxOffset[rfPath][group] =
1761                                         EEPROM_Default_HT20_PwrMaxOffset;
1762                         }
1763                 }
1764                 pwrInfo->TSSI_A[0] = EEPROM_Default_TSSI;
1765                 return;
1766         }
1767
1768         for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
1769                 for (group = 0; group < MAX_CHNL_GROUP; group++) {
1770                         eeAddr =
1771                             EEPROM_CCK_TX_PWR_INX_8723A + (rfPath * 3) + group;
1772                         /* pwrInfo->CCKIndex[rfPath][group] =
1773                            PROMContent[eeAddr]; */
1774                         Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr],
1775                                          &pwrInfo->CCKIndex[rfPath][group]);
1776                         eeAddr = EEPROM_HT40_1S_TX_PWR_INX_8723A +
1777                                 (rfPath * 3) + group;
1778                         /* pwrInfo->HT40_1SIndex[rfPath][group] =
1779                            PROMContent[eeAddr]; */
1780                         Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr],
1781                                          &pwrInfo->HT40_1SIndex[rfPath][group]);
1782                 }
1783         }
1784
1785         for (group = 0; group < MAX_CHNL_GROUP; group++) {
1786                 for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
1787                         pwrInfo->HT40_2SIndexDiff[rfPath][group] = 0;
1788                         pwrInfo->HT20IndexDiff[rfPath][group] =
1789                                 (PROMContent
1790                                  [EEPROM_HT20_TX_PWR_INX_DIFF_8723A +
1791                                   group] >> (rfPath * 4)) & 0xF;
1792                         /* 4bit sign number to 8 bit sign number */
1793                         if (pwrInfo->HT20IndexDiff[rfPath][group] & BIT(3))
1794                                 pwrInfo->HT20IndexDiff[rfPath][group] |= 0xF0;
1795
1796                         pwrInfo->OFDMIndexDiff[rfPath][group] =
1797                                 (PROMContent[EEPROM_OFDM_TX_PWR_INX_DIFF_8723A +
1798                                              group] >> (rfPath * 4)) & 0xF;
1799
1800                         pwrInfo->HT40MaxOffset[rfPath][group] =
1801                                 (PROMContent[EEPROM_HT40_MAX_PWR_OFFSET_8723A +
1802                                              group] >> (rfPath * 4)) & 0xF;
1803
1804                         pwrInfo->HT20MaxOffset[rfPath][group] =
1805                                 (PROMContent[EEPROM_HT20_MAX_PWR_OFFSET_8723A +
1806                                              group] >> (rfPath * 4)) & 0xF;
1807                 }
1808         }
1809
1810         pwrInfo->TSSI_A[0] = PROMContent[EEPROM_TSSI_A_8723A];
1811 }
1812
1813 static u8 Hal_GetChnlGroup(u8 chnl)
1814 {
1815         u8 group = 0;
1816
1817         if (chnl < 3)           /*  Cjanel 1-3 */
1818                 group = 0;
1819         else if (chnl < 9)      /*  Channel 4-9 */
1820                 group = 1;
1821         else                    /*  Channel 10-14 */
1822                 group = 2;
1823
1824         return group;
1825 }
1826
1827 void
1828 Hal_EfuseParsetxpowerinfo_8723A(struct rtw_adapter *padapter,
1829                                 u8 *PROMContent, bool AutoLoadFail)
1830 {
1831         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1832         struct txpowerinfo pwrInfo;
1833         u8 rfPath, ch, group, rfPathMax = 1;
1834         u8 pwr, diff;
1835
1836         Hal_ReadPowerValueFromPROM_8723A(&pwrInfo, PROMContent, AutoLoadFail);
1837         for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
1838                 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
1839                         group = Hal_GetChnlGroup(ch);
1840
1841                         pHalData->TxPwrLevelCck[rfPath][ch] =
1842                                 pwrInfo.CCKIndex[rfPath][group];
1843                         pHalData->TxPwrLevelHT40_1S[rfPath][ch] =
1844                                 pwrInfo.HT40_1SIndex[rfPath][group];
1845
1846                         pHalData->TxPwrHt20Diff[rfPath][ch] =
1847                                 pwrInfo.HT20IndexDiff[rfPath][group];
1848                         pHalData->TxPwrLegacyHtDiff[rfPath][ch] =
1849                                 pwrInfo.OFDMIndexDiff[rfPath][group];
1850                         pHalData->PwrGroupHT20[rfPath][ch] =
1851                                 pwrInfo.HT20MaxOffset[rfPath][group];
1852                         pHalData->PwrGroupHT40[rfPath][ch] =
1853                                 pwrInfo.HT40MaxOffset[rfPath][group];
1854
1855                         pwr = pwrInfo.HT40_1SIndex[rfPath][group];
1856                         diff = pwrInfo.HT40_2SIndexDiff[rfPath][group];
1857
1858                         pHalData->TxPwrLevelHT40_2S[rfPath][ch] =
1859                             (pwr > diff) ? (pwr - diff) : 0;
1860                 }
1861         }
1862         for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
1863                 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
1864                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1865                                  ("RF(%u)-Ch(%u) [CCK / HT40_1S / HT40_2S] = "
1866                                   "[0x%x / 0x%x / 0x%x]\n",
1867                                   rfPath, ch,
1868                                   pHalData->TxPwrLevelCck[rfPath][ch],
1869                                   pHalData->TxPwrLevelHT40_1S[rfPath][ch],
1870                                   pHalData->TxPwrLevelHT40_2S[rfPath][ch]));
1871
1872                 }
1873         }
1874         for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
1875                 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1876                          ("RF-A Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
1877                           pHalData->TxPwrHt20Diff[RF_PATH_A][ch],
1878                           pHalData->TxPwrHt20Diff[RF_PATH_A][ch]));
1879         }
1880         for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++)
1881                 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1882                          ("RF-A Legacy to Ht40 Diff[%u] = 0x%x\n", ch,
1883                           pHalData->TxPwrLegacyHtDiff[RF_PATH_A][ch]));
1884         for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
1885                 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1886                          ("RF-B Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
1887                           pHalData->TxPwrHt20Diff[RF_PATH_B][ch],
1888                           pHalData->TxPwrHt20Diff[RF_PATH_B][ch]));
1889         }
1890         for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++)
1891                 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1892                          ("RF-B Legacy to HT40 Diff[%u] = 0x%x\n", ch,
1893                           pHalData->TxPwrLegacyHtDiff[RF_PATH_B][ch]));
1894         if (!AutoLoadFail) {
1895                 struct registry_priv *registry_par = &padapter->registrypriv;
1896                 if (registry_par->regulatory_tid == 0xff) {
1897                         if (PROMContent[RF_OPTION1_8723A] == 0xff)
1898                                 pHalData->EEPROMRegulatory = 0;
1899                         else
1900                                 pHalData->EEPROMRegulatory =
1901                                         PROMContent[RF_OPTION1_8723A] & 0x7;
1902                 } else {
1903                         pHalData->EEPROMRegulatory =
1904                             registry_par->regulatory_tid;
1905                 }
1906         } else {
1907                 pHalData->EEPROMRegulatory = 0;
1908         }
1909         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1910                  ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory));
1911
1912         if (!AutoLoadFail)
1913                 pHalData->bTXPowerDataReadFromEEPORM = true;
1914 }
1915
1916 void
1917 Hal_EfuseParseBTCoexistInfo_8723A(struct rtw_adapter *padapter,
1918                                   u8 *hwinfo, bool AutoLoadFail)
1919 {
1920         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1921         u8 tempval;
1922         u32 tmpu4;
1923
1924         if (!AutoLoadFail) {
1925                 tmpu4 = rtl8723au_read32(padapter, REG_MULTI_FUNC_CTRL);
1926                 if (tmpu4 & BT_FUNC_EN)
1927                         pHalData->EEPROMBluetoothCoexist = 1;
1928                 else
1929                         pHalData->EEPROMBluetoothCoexist = 0;
1930                 pHalData->EEPROMBluetoothType = BT_RTL8723A;
1931
1932                 /*  The following need to be checked with newer version of */
1933                 /*  eeprom spec */
1934                 tempval = hwinfo[RF_OPTION4_8723A];
1935                 pHalData->EEPROMBluetoothAntNum = (tempval & 0x1);
1936                 pHalData->EEPROMBluetoothAntIsolation = ((tempval & 0x10) >> 4);
1937                 pHalData->EEPROMBluetoothRadioShared = ((tempval & 0x20) >> 5);
1938         } else {
1939                 pHalData->EEPROMBluetoothCoexist = 0;
1940                 pHalData->EEPROMBluetoothType = BT_RTL8723A;
1941                 pHalData->EEPROMBluetoothAntNum = Ant_x2;
1942                 pHalData->EEPROMBluetoothAntIsolation = 0;
1943                 pHalData->EEPROMBluetoothRadioShared = BT_Radio_Shared;
1944         }
1945
1946         rtl8723a_BT_init_hal_vars(padapter);
1947 }
1948
1949 void
1950 Hal_EfuseParseEEPROMVer(struct rtw_adapter *padapter,
1951                         u8 *hwinfo, bool AutoLoadFail)
1952 {
1953         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1954
1955         if (!AutoLoadFail)
1956                 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723A];
1957         else
1958                 pHalData->EEPROMVersion = 1;
1959         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1960                  ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
1961                   pHalData->EEPROMVersion));
1962 }
1963
1964 void
1965 rtl8723a_EfuseParseChnlPlan(struct rtw_adapter *padapter,
1966                             u8 *hwinfo, bool AutoLoadFail)
1967 {
1968         padapter->mlmepriv.ChannelPlan =
1969                 hal_com_get_channel_plan23a(padapter, hwinfo ?
1970                                          hwinfo[EEPROM_ChannelPlan_8723A]:0xFF,
1971                                          padapter->registrypriv.channel_plan,
1972                                          RT_CHANNEL_DOMAIN_WORLD_WIDE_13,
1973                                          AutoLoadFail);
1974
1975         DBG_8723A("mlmepriv.ChannelPlan = 0x%02x\n",
1976                   padapter->mlmepriv.ChannelPlan);
1977 }
1978
1979 void
1980 Hal_EfuseParseCustomerID(struct rtw_adapter *padapter,
1981                          u8 *hwinfo, bool AutoLoadFail)
1982 {
1983         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1984
1985         if (!AutoLoadFail) {
1986                 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723A];
1987                 pHalData->EEPROMSubCustomerID =
1988                     hwinfo[EEPROM_SubCustomID_8723A];
1989         } else {
1990                 pHalData->EEPROMCustomerID = 0;
1991                 pHalData->EEPROMSubCustomerID = 0;
1992         }
1993         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1994                  ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID));
1995         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1996                  ("EEPROM SubCustomer ID: 0x%02x\n",
1997                   pHalData->EEPROMSubCustomerID));
1998 }
1999
2000 void
2001 Hal_EfuseParseAntennaDiversity(struct rtw_adapter *padapter,
2002                                u8 *hwinfo, bool AutoLoadFail)
2003 {
2004 }
2005
2006 void
2007 Hal_EfuseParseRateIndicationOption(struct rtw_adapter *padapter,
2008                                    u8 *hwinfo, bool AutoLoadFail)
2009 {
2010 }
2011
2012 void
2013 Hal_EfuseParseXtal_8723A(struct rtw_adapter *pAdapter,
2014                          u8 *hwinfo, u8 AutoLoadFail)
2015 {
2016         struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
2017
2018         if (!AutoLoadFail) {
2019                 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_K_8723A];
2020                 if (pHalData->CrystalCap == 0xFF)
2021                         pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
2022         } else {
2023                 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
2024         }
2025         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2026                  ("%s: CrystalCap = 0x%2x\n", __func__,
2027                   pHalData->CrystalCap));
2028 }
2029
2030 void
2031 Hal_EfuseParseThermalMeter_8723A(struct rtw_adapter *padapter,
2032                                  u8 *PROMContent, bool AutoloadFail)
2033 {
2034         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
2035
2036         /*  */
2037         /*  ThermalMeter from EEPROM */
2038         /*  */
2039         if (AutoloadFail == false)
2040                 pHalData->EEPROMThermalMeter =
2041                     PROMContent[EEPROM_THERMAL_METER_8723A];
2042         else
2043                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2044
2045         if ((pHalData->EEPROMThermalMeter == 0xff) || (AutoloadFail == true)) {
2046                 pHalData->bAPKThermalMeterIgnore = true;
2047                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2048         }
2049
2050         DBG_8723A("%s: ThermalMeter = 0x%x\n", __func__,
2051                   pHalData->EEPROMThermalMeter);
2052 }
2053
2054 void Hal_InitChannelPlan23a(struct rtw_adapter *padapter)
2055 {
2056 }
2057
2058 static void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc)
2059 {
2060         u16 *usPtr = (u16 *) ptxdesc;
2061         u32 count = 16;         /*  (32 bytes / 2 bytes per XOR) => 16 times */
2062         u32 index;
2063         u16 checksum = 0;
2064
2065         /*  Clear first */
2066         ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
2067
2068         for (index = 0; index < count; index++) {
2069                 checksum ^= le16_to_cpu(*(usPtr + index));
2070         }
2071
2072         ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
2073 }
2074
2075 static void fill_txdesc_sectype(struct pkt_attrib *pattrib,
2076                                 struct txdesc_8723a *ptxdesc)
2077 {
2078         if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
2079                 switch (pattrib->encrypt) {
2080                         /*  SEC_TYPE */
2081                 case WLAN_CIPHER_SUITE_WEP40:
2082                 case WLAN_CIPHER_SUITE_WEP104:
2083                 case WLAN_CIPHER_SUITE_TKIP:
2084                         ptxdesc->sectype = 1;
2085                         break;
2086
2087                 case WLAN_CIPHER_SUITE_CCMP:
2088                         ptxdesc->sectype = 3;
2089                         break;
2090
2091                 case 0:
2092                 default:
2093                         break;
2094                 }
2095         }
2096 }
2097
2098 static void fill_txdesc_vcs(struct pkt_attrib *pattrib,
2099                             struct txdesc_8723a *ptxdesc)
2100 {
2101         /* DBG_8723A("cvs_mode =%d\n", pattrib->vcs_mode); */
2102
2103         switch (pattrib->vcs_mode) {
2104         case RTS_CTS:
2105                 ptxdesc->rtsen = 1;
2106                 break;
2107
2108         case CTS_TO_SELF:
2109                 ptxdesc->cts2self = 1;
2110                 break;
2111
2112         case NONE_VCS:
2113         default:
2114                 break;
2115         }
2116
2117         if (pattrib->vcs_mode) {
2118                 ptxdesc->hw_rts_en = 1; /*  ENABLE HW RTS */
2119
2120                 /*  Set RTS BW */
2121                 if (pattrib->ht_en) {
2122                         if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
2123                                 ptxdesc->rts_bw = 1;
2124
2125                         switch (pattrib->ch_offset) {
2126                         case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
2127                                 ptxdesc->rts_sc = 0;
2128                                 break;
2129
2130                         case HAL_PRIME_CHNL_OFFSET_LOWER:
2131                                 ptxdesc->rts_sc = 1;
2132                                 break;
2133
2134                         case HAL_PRIME_CHNL_OFFSET_UPPER:
2135                                 ptxdesc->rts_sc = 2;
2136                                 break;
2137
2138                         default:
2139                                 ptxdesc->rts_sc = 3;    /*  Duplicate */
2140                                 break;
2141                         }
2142                 }
2143         }
2144 }
2145
2146 static void fill_txdesc_phy(struct pkt_attrib *pattrib,
2147                             struct txdesc_8723a *ptxdesc)
2148 {
2149         if (pattrib->ht_en) {
2150                 if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
2151                         ptxdesc->data_bw = 1;
2152
2153                 switch (pattrib->ch_offset) {
2154                 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
2155                         ptxdesc->data_sc = 0;
2156                         break;
2157
2158                 case HAL_PRIME_CHNL_OFFSET_LOWER:
2159                         ptxdesc->data_sc = 1;
2160                         break;
2161
2162                 case HAL_PRIME_CHNL_OFFSET_UPPER:
2163                         ptxdesc->data_sc = 2;
2164                         break;
2165
2166                 default:
2167                         ptxdesc->data_sc = 3;   /*  Duplicate */
2168                         break;
2169                 }
2170         }
2171 }
2172
2173 static void rtl8723a_fill_default_txdesc(struct xmit_frame *pxmitframe,
2174                                          u8 *pbuf)
2175 {
2176         struct rtw_adapter *padapter;
2177         struct hal_data_8723a *pHalData;
2178         struct dm_priv *pdmpriv;
2179         struct mlme_ext_priv *pmlmeext;
2180         struct mlme_ext_info *pmlmeinfo;
2181         struct pkt_attrib *pattrib;
2182         struct txdesc_8723a *ptxdesc;
2183         s32 bmcst;
2184
2185         padapter = pxmitframe->padapter;
2186         pHalData = GET_HAL_DATA(padapter);
2187         pdmpriv = &pHalData->dmpriv;
2188         pmlmeext = &padapter->mlmeextpriv;
2189         pmlmeinfo = &pmlmeext->mlmext_info;
2190
2191         pattrib = &pxmitframe->attrib;
2192         bmcst = is_multicast_ether_addr(pattrib->ra);
2193
2194         ptxdesc = (struct txdesc_8723a *)pbuf;
2195
2196         if (pxmitframe->frame_tag == DATA_FRAMETAG) {
2197                 ptxdesc->macid = pattrib->mac_id;       /*  CAM_ID(MAC_ID) */
2198
2199                 if (pattrib->ampdu_en == true)
2200                         ptxdesc->agg_en = 1;    /*  AGG EN */
2201                 else
2202                         ptxdesc->bk = 1;        /*  AGG BK */
2203
2204                 ptxdesc->qsel = pattrib->qsel;
2205                 ptxdesc->rate_id = pattrib->raid;
2206
2207                 fill_txdesc_sectype(pattrib, ptxdesc);
2208
2209                 ptxdesc->seq = pattrib->seqnum;
2210
2211                 if ((pattrib->ether_type != 0x888e) &&
2212                     (pattrib->ether_type != 0x0806) &&
2213                     (pattrib->dhcp_pkt != 1)) {
2214                         /*  Non EAP & ARP & DHCP type data packet */
2215
2216                         fill_txdesc_vcs(pattrib, ptxdesc);
2217                         fill_txdesc_phy(pattrib, ptxdesc);
2218
2219                         ptxdesc->rtsrate = 8;   /*  RTS Rate = 24M */
2220                         ptxdesc->data_ratefb_lmt = 0x1F;
2221                         ptxdesc->rts_ratefb_lmt = 0xF;
2222
2223                         /*  use REG_INIDATA_RATE_SEL value */
2224                         ptxdesc->datarate =
2225                                 pdmpriv->INIDATA_RATE[pattrib->mac_id];
2226
2227                 } else {
2228                         /*  EAP data packet and ARP packet. */
2229                         /*  Use the 1M data rate to send the EAP/ARP packet. */
2230                         /*  This will maybe make the handshake smooth. */
2231
2232                         ptxdesc->bk = 1;        /*  AGG BK */
2233                         ptxdesc->userate = 1;   /*  driver uses rate */
2234                         if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
2235                                 ptxdesc->data_short = 1;
2236                         ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate);
2237                 }
2238         } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) {
2239 /*              RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
2240                 ("%s: MGNT_FRAMETAG\n", __func__)); */
2241
2242                 ptxdesc->macid = pattrib->mac_id;       /*  CAM_ID(MAC_ID) */
2243                 ptxdesc->qsel = pattrib->qsel;
2244                 ptxdesc->rate_id = pattrib->raid;       /*  Rate ID */
2245                 ptxdesc->seq = pattrib->seqnum;
2246                 ptxdesc->userate = 1;   /*  driver uses rate, 1M */
2247                 ptxdesc->rty_lmt_en = 1;        /*  retry limit enable */
2248                 ptxdesc->data_rt_lmt = 6;       /*  retry limit = 6 */
2249
2250                 /* CCX-TXRPT ack for xmit mgmt frames. */
2251                 if (pxmitframe->ack_report)
2252                         ptxdesc->ccx = 1;
2253
2254                 ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate);
2255         } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) {
2256                 RT_TRACE(_module_hal_xmit_c_, _drv_warning_,
2257                          ("%s: TXAGG_FRAMETAG\n", __func__));
2258         } else {
2259                 RT_TRACE(_module_hal_xmit_c_, _drv_warning_,
2260                          ("%s: frame_tag = 0x%x\n", __func__,
2261                           pxmitframe->frame_tag));
2262
2263                 ptxdesc->macid = 4;     /*  CAM_ID(MAC_ID) */
2264                 ptxdesc->rate_id = 6;   /*  Rate ID */
2265                 ptxdesc->seq = pattrib->seqnum;
2266                 ptxdesc->userate = 1;   /*  driver uses rate */
2267                 ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate);
2268         }
2269
2270         ptxdesc->pktlen = pattrib->last_txcmdsz;
2271         ptxdesc->offset = TXDESC_SIZE + OFFSET_SZ;
2272         if (bmcst)
2273                 ptxdesc->bmc = 1;
2274         ptxdesc->ls = 1;
2275         ptxdesc->fs = 1;
2276         ptxdesc->own = 1;
2277
2278         /*  2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */
2279         /*  (1) The sequence number of each non-Qos frame / broadcast /
2280          *   multicast / mgnt frame should be controled by Hw because Fw
2281          * will also send null data which we cannot control when Fw LPS enable.
2282          *  --> default enable non-Qos data sequense number.
2283          2010.06.23. by tynli. */
2284         /*  (2) Enable HW SEQ control for beacon packet,
2285          * because we use Hw beacon. */
2286         /*  (3) Use HW Qos SEQ to control the seq num of Ext port
2287          * non-Qos packets. */
2288         /*  2010.06.23. Added by tynli. */
2289         if (!pattrib->qos_en) {
2290                 /*  Hw set sequence number */
2291                 ptxdesc->hwseq_en = 1;  /*  HWSEQ_EN */
2292                 ptxdesc->hwseq_sel = 0; /*  HWSEQ_SEL */
2293         }
2294 }
2295
2296 /*
2297  *      Description:
2298  *
2299  *      Parameters:
2300  *              pxmitframe      xmitframe
2301  *              pbuf            where to fill tx desc
2302  */
2303 void rtl8723a_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
2304 {
2305         struct tx_desc *pdesc;
2306
2307         pdesc = (struct tx_desc *)pbuf;
2308         memset(pdesc, 0, sizeof(struct tx_desc));
2309
2310         rtl8723a_fill_default_txdesc(pxmitframe, pbuf);
2311
2312         pdesc->txdw0 = cpu_to_le32(pdesc->txdw0);
2313         pdesc->txdw1 = cpu_to_le32(pdesc->txdw1);
2314         pdesc->txdw2 = cpu_to_le32(pdesc->txdw2);
2315         pdesc->txdw3 = cpu_to_le32(pdesc->txdw3);
2316         pdesc->txdw4 = cpu_to_le32(pdesc->txdw4);
2317         pdesc->txdw5 = cpu_to_le32(pdesc->txdw5);
2318         pdesc->txdw6 = cpu_to_le32(pdesc->txdw6);
2319         pdesc->txdw7 = cpu_to_le32(pdesc->txdw7);
2320         rtl8723a_cal_txdesc_chksum(pdesc);
2321 }
2322
2323 /*
2324  *  Description: In normal chip, we should send some packet to Hw which
2325  *  will be used by Fw in FW LPS mode. The function is to fill the Tx
2326  * descriptor of this packets, then
2327  */
2328 /*                      Fw can tell Hw to send these packet derectly. */
2329 /*  Added by tynli. 2009.10.15. */
2330 /*  */
2331 void rtl8723a_fill_fake_txdesc(struct rtw_adapter *padapter, u8 *pDesc,
2332                                u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull)
2333 {
2334         struct tx_desc *ptxdesc;
2335
2336         /*  Clear all status */
2337         ptxdesc = (struct tx_desc *)pDesc;
2338         memset(pDesc, 0, TXDESC_SIZE);
2339
2340         /* offset 0 */
2341         /* own, bFirstSeg, bLastSeg; */
2342         ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
2343
2344         /* 32 bytes for TX Desc */
2345         ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) <<
2346                                        OFFSET_SHT) & 0x00ff0000);
2347
2348         /*  Buffer size + command header */
2349         ptxdesc->txdw0 |= cpu_to_le32(BufferLen & 0x0000ffff);
2350
2351         /* offset 4 */
2352         /*  Fixed queue of Mgnt queue */
2353         ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT << QSEL_SHT) & 0x00001f00);
2354
2355         /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed
2356            to error vlaue by Hw. */
2357         if (IsPsPoll) {
2358                 ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
2359         } else {
2360                 /*  Hw set sequence number */
2361                 ptxdesc->txdw4 |= cpu_to_le32(BIT(7));
2362                 /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
2363                 ptxdesc->txdw3 |= cpu_to_le32((8 << 28));
2364         }
2365
2366         if (true == IsBTQosNull) {
2367                 ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /*  BT NULL */
2368         }
2369
2370         /* offset 16 */
2371         ptxdesc->txdw4 |= cpu_to_le32(BIT(8));  /* driver uses rate */
2372
2373         /*  USB interface drop packet if the checksum of descriptor isn't
2374             correct. */
2375         /*  Using this checksum can let hardware recovery from packet bulk
2376             out error (e.g. Cancel URC, Bulk out error.). */
2377         rtl8723a_cal_txdesc_chksum(ptxdesc);
2378 }
2379
2380 void hw_var_set_opmode(struct rtw_adapter *padapter, u8 mode)
2381 {
2382         u8 val8;
2383
2384         if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
2385                 StopTxBeacon(padapter);
2386
2387                 /*  disable atim wnd */
2388                 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM;
2389                 SetBcnCtrlReg23a(padapter, val8, ~val8);
2390         } else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_) */) {
2391                 ResumeTxBeacon(padapter);
2392
2393                 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB;
2394                 SetBcnCtrlReg23a(padapter, val8, ~val8);
2395         } else if (mode == _HW_STATE_AP_) {
2396                 /*  add NULL Data and BT NULL Data Packets to FW RSVD Page */
2397                 rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(padapter);
2398
2399                 ResumeTxBeacon(padapter);
2400
2401                 val8 = DIS_TSF_UDT | DIS_BCNQ_SUB;
2402                 SetBcnCtrlReg23a(padapter, val8, ~val8);
2403
2404                 /*  Set RCR */
2405                 /* rtl8723au_write32(padapter, REG_RCR, 0x70002a8e);
2406                    CBSSID_DATA must set to 0 */
2407                 /* CBSSID_DATA must set to 0 */
2408                 rtl8723au_write32(padapter, REG_RCR, 0x7000228e);
2409                 /*  enable to rx data frame */
2410                 rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
2411                 /*  enable to rx ps-poll */
2412                 rtl8723au_write16(padapter, REG_RXFLTMAP1, 0x0400);
2413
2414                 /*  Beacon Control related register for first time */
2415                 /*  2ms */
2416                 rtl8723au_write8(padapter, REG_BCNDMATIM, 0x02);
2417                 /*  5ms */
2418                 rtl8723au_write8(padapter, REG_DRVERLYINT, 0x05);
2419                 /*  10ms for port0 */
2420                 rtl8723au_write8(padapter, REG_ATIMWND, 0x0a);
2421                 rtl8723au_write16(padapter, REG_BCNTCFG, 0x00);
2422                 rtl8723au_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
2423                 /*  +32767 (~32ms) */
2424                 rtl8723au_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);
2425
2426                 /*  reset TSF */
2427                 rtl8723au_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
2428
2429                 /*  enable BCN Function */
2430                 /*  don't enable update TSF (due to TSF update when
2431                     beacon/probe rsp are received) */
2432                 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION |
2433                        EN_TXBCN_RPT | DIS_BCNQ_SUB;
2434                 SetBcnCtrlReg23a(padapter, val8, ~val8);
2435         }
2436
2437         val8 = rtl8723au_read8(padapter, MSR);
2438         val8 = (val8 & 0xC) | mode;
2439         rtl8723au_write8(padapter, MSR, val8);
2440 }
2441
2442 void hw_var_set_macaddr(struct rtw_adapter *padapter, u8 *val)
2443 {
2444         u8 idx = 0;
2445         u32 reg_macid;
2446
2447         reg_macid = REG_MACID;
2448
2449         for (idx = 0; idx < 6; idx++)
2450                 rtl8723au_write8(padapter, (reg_macid + idx), val[idx]);
2451 }
2452
2453 void hw_var_set_bssid(struct rtw_adapter *padapter, u8 *val)
2454 {
2455         u8 idx = 0;
2456         u32 reg_bssid;
2457
2458         reg_bssid = REG_BSSID;
2459
2460         for (idx = 0; idx < 6; idx++)
2461                 rtl8723au_write8(padapter, (reg_bssid + idx), val[idx]);
2462 }
2463
2464 void hw_var_set_correct_tsf(struct rtw_adapter *padapter)
2465 {
2466         u64 tsf;
2467         u32 reg_tsftr;
2468         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2469         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2470
2471         /* tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue %
2472            (pmlmeinfo->bcn_interval*1024)) - 1024; us */
2473         tsf = pmlmeext->TSFValue -
2474                 do_div(pmlmeext->TSFValue,
2475                        (pmlmeinfo->bcn_interval * 1024)) - 1024;        /* us */
2476
2477         if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
2478             ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
2479                 /* pHalData->RegTxPause |= STOP_BCNQ;BIT(6) */
2480                 /* rtl8723au_write8(padapter, REG_TXPAUSE,
2481                    (rtl8723au_read8(Adapter, REG_TXPAUSE)|BIT(6))); */
2482                 StopTxBeacon(padapter);
2483         }
2484
2485         reg_tsftr = REG_TSFTR;
2486
2487         /*  disable related TSF function */
2488         SetBcnCtrlReg23a(padapter, 0, EN_BCN_FUNCTION);
2489
2490         rtl8723au_write32(padapter, reg_tsftr, tsf);
2491         rtl8723au_write32(padapter, reg_tsftr + 4, tsf >> 32);
2492
2493         /* enable related TSF function */
2494         SetBcnCtrlReg23a(padapter, EN_BCN_FUNCTION, 0);
2495
2496         if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
2497             ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
2498                 ResumeTxBeacon(padapter);
2499 }
2500
2501 void hw_var_set_mlme_disconnect(struct rtw_adapter *padapter)
2502 {
2503         /*  reject all data frames */
2504         rtl8723au_write16(padapter, REG_RXFLTMAP2, 0);
2505
2506         /*  reset TSF */
2507         rtl8723au_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
2508
2509         /*  disable update TSF */
2510         SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0);
2511 }
2512
2513 void hw_var_set_mlme_join(struct rtw_adapter *padapter, u8 type)
2514 {
2515         u8 RetryLimit = 0x30;
2516
2517         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
2518         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2519
2520         if (type == 0) {        /*  prepare to join */
2521                 u32 v32;
2522
2523                 /*  enable to rx data frame.Accept all data frame */
2524                 /* rtl8723au_write32(padapter, REG_RCR,
2525                    rtl8723au_read32(padapter, REG_RCR)|RCR_ADF); */
2526                 rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
2527
2528                 v32 = rtl8723au_read32(padapter, REG_RCR);
2529                 v32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
2530                 rtl8723au_write32(padapter, REG_RCR, v32);
2531
2532                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
2533                         RetryLimit =
2534                             (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
2535                 else            /*  Ad-hoc Mode */
2536                         RetryLimit = 0x7;
2537         } else if (type == 1) { /*  joinbss_event callback when join res < 0 */
2538                 /*  config RCR to receive different BSSID & not to
2539                     receive data frame during linking */
2540                 rtl8723au_write16(padapter, REG_RXFLTMAP2, 0);
2541         } else if (type == 2) { /*  sta add event callback */
2542                 /*  enable update TSF */
2543                 SetBcnCtrlReg23a(padapter, 0, DIS_TSF_UDT);
2544
2545                 if (check_fwstate(pmlmepriv,
2546                                   WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
2547                         /*  fixed beacon issue for 8191su........... */
2548                         rtl8723au_write8(padapter, 0x542, 0x02);
2549                         RetryLimit = 0x7;
2550                 }
2551         }
2552
2553         rtl8723au_write16(padapter, REG_RL,
2554                           RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit <<
2555                           RETRY_LIMIT_LONG_SHIFT);
2556
2557         switch (type) {
2558         case 0:
2559                 /*  prepare to join */
2560                 rtl8723a_BT_wifiassociate_notify(padapter, true);
2561                 break;
2562         case 1:
2563                 /*  joinbss_event callback when join res < 0 */
2564                 rtl8723a_BT_wifiassociate_notify(padapter, false);
2565                 break;
2566         case 2:
2567                 /*  sta add event callback */
2568 /*              BT_WifiMediaStatusNotify(padapter, RT_MEDIA_CONNECT); */
2569                 break;
2570         }
2571 }