blob: ebe33392c8d9e69f219a3936a36b8df2ef537757 [file] [log] [blame]
Larry Fingerf7c92d22014-03-28 21:37:39 -05001/******************************************************************************
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>
Jes Sorensen050abc42014-05-16 10:05:08 +020022#include <usb_ops_linux.h>
Larry Fingerf7c92d22014-03-28 21:37:39 -050023
24static void _FWDownloadEnable(struct rtw_adapter *padapter, bool enable)
25{
26 u8 tmp;
27
28 if (enable) {
29 /* 8051 enable */
Jes Sorensen050abc42014-05-16 10:05:08 +020030 tmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
Jes Sorensenedbfd672014-05-16 10:05:09 +020031 rtl8723au_write8(padapter, REG_SYS_FUNC_EN + 1, tmp | 0x04);
Larry Fingerf7c92d22014-03-28 21:37:39 -050032
33 /* MCU firmware download enable. */
Jes Sorensen050abc42014-05-16 10:05:08 +020034 tmp = rtl8723au_read8(padapter, REG_MCUFWDL);
Jes Sorensenedbfd672014-05-16 10:05:09 +020035 rtl8723au_write8(padapter, REG_MCUFWDL, tmp | 0x01);
Larry Fingerf7c92d22014-03-28 21:37:39 -050036
37 /* 8051 reset */
Jes Sorensen050abc42014-05-16 10:05:08 +020038 tmp = rtl8723au_read8(padapter, REG_MCUFWDL + 2);
Jes Sorensenedbfd672014-05-16 10:05:09 +020039 rtl8723au_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
Larry Fingerf7c92d22014-03-28 21:37:39 -050040 } else {
41 /* MCU firmware download disable. */
Jes Sorensen050abc42014-05-16 10:05:08 +020042 tmp = rtl8723au_read8(padapter, REG_MCUFWDL);
Jes Sorensenedbfd672014-05-16 10:05:09 +020043 rtl8723au_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
Larry Fingerf7c92d22014-03-28 21:37:39 -050044
45 /* Reserved for fw extension. */
Jes Sorensenedbfd672014-05-16 10:05:09 +020046 rtl8723au_write8(padapter, REG_MCUFWDL + 1, 0x00);
Larry Fingerf7c92d22014-03-28 21:37:39 -050047 }
48}
49
Larry Fingerf7c92d22014-03-28 21:37:39 -050050static int
51_PageWrite(struct rtw_adapter *padapter, u32 page, void *buffer, u32 size)
52{
53 u8 value8;
54 u8 u8Page = (u8) (page & 0x07);
55
Jes Sorensen7b78bdc2014-11-30 16:05:12 -050056 if (size > MAX_PAGE_SIZE)
57 return _FAIL;
58
Jes Sorensen050abc42014-05-16 10:05:08 +020059 value8 = (rtl8723au_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
Jes Sorensenedbfd672014-05-16 10:05:09 +020060 rtl8723au_write8(padapter, REG_MCUFWDL + 2, value8);
Larry Fingerf7c92d22014-03-28 21:37:39 -050061
Jes Sorensen7b78bdc2014-11-30 16:05:12 -050062 return rtl8723au_writeN(padapter, FW_8723A_START_ADDRESS, size, buffer);
Larry Fingerf7c92d22014-03-28 21:37:39 -050063}
64
65static int _WriteFW(struct rtw_adapter *padapter, void *buffer, u32 size)
66{
67 /* Since we need dynamic decide method of dwonload fw, so we
68 call this function to get chip version. */
69 /* We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */
70 int ret = _SUCCESS;
71 u32 pageNums, remainSize;
72 u32 page, offset;
73 u8 *bufferPtr = (u8 *) buffer;
74
75 pageNums = size / MAX_PAGE_SIZE;
76 /* RT_ASSERT((pageNums <= 4),
77 ("Page numbers should not greater then 4 \n")); */
78 remainSize = size % MAX_PAGE_SIZE;
79
80 for (page = 0; page < pageNums; page++) {
81 offset = page * MAX_PAGE_SIZE;
82 ret = _PageWrite(padapter, page, bufferPtr + offset,
83 MAX_PAGE_SIZE);
84
85 if (ret == _FAIL)
86 goto exit;
87 }
88 if (remainSize) {
89 offset = pageNums * MAX_PAGE_SIZE;
90 page = pageNums;
91 ret = _PageWrite(padapter, page, bufferPtr + offset,
92 remainSize);
93
94 if (ret == _FAIL)
95 goto exit;
96 }
97 RT_TRACE(_module_hal_init_c_, _drv_info_,
98 ("_WriteFW Done- for Normal chip.\n"));
99
100exit:
101 return ret;
102}
103
Jes Sorensena5681f92014-05-16 10:04:48 +0200104static int _FWFreeToGo(struct rtw_adapter *padapter)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500105{
106 u32 counter = 0;
107 u32 value32;
108
109 /* polling CheckSum report */
110 do {
Jes Sorensen050abc42014-05-16 10:05:08 +0200111 value32 = rtl8723au_read32(padapter, REG_MCUFWDL);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500112 if (value32 & FWDL_ChkSum_rpt)
113 break;
114 } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
115
116 if (counter >= POLLING_READY_TIMEOUT_COUNT) {
117 RT_TRACE(_module_hal_init_c_, _drv_err_,
118 ("%s: chksum report fail! REG_MCUFWDL:0x%08x\n",
119 __func__, value32));
120 return _FAIL;
121 }
122 RT_TRACE(_module_hal_init_c_, _drv_info_,
123 ("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__,
124 value32));
125
Jes Sorensen050abc42014-05-16 10:05:08 +0200126 value32 = rtl8723au_read32(padapter, REG_MCUFWDL);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500127 value32 |= MCUFWDL_RDY;
128 value32 &= ~WINTINI_RDY;
Jes Sorensenedbfd672014-05-16 10:05:09 +0200129 rtl8723au_write32(padapter, REG_MCUFWDL, value32);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500130
131 /* polling for FW ready */
132 counter = 0;
133 do {
Jes Sorensen050abc42014-05-16 10:05:08 +0200134 value32 = rtl8723au_read32(padapter, REG_MCUFWDL);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500135 if (value32 & WINTINI_RDY) {
136 RT_TRACE(_module_hal_init_c_, _drv_info_,
137 ("%s: Polling FW ready success!! "
138 "REG_MCUFWDL:0x%08x\n",
139 __func__, value32));
140 return _SUCCESS;
141 }
142 udelay(5);
143 } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
144
145 RT_TRACE(_module_hal_init_c_, _drv_err_,
146 ("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n",
147 __func__, value32));
148 return _FAIL;
149}
150
151#define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
152
153void rtl8723a_FirmwareSelfReset(struct rtw_adapter *padapter)
154{
155 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
156 u8 u1bTmp;
157 u8 Delay = 100;
158
159 if (!(IS_FW_81xxC(padapter) &&
160 ((pHalData->FirmwareVersion < 0x21) ||
161 (pHalData->FirmwareVersion == 0x21 &&
162 pHalData->FirmwareSubVersion < 0x01)))) {
163 /* after 88C Fw v33.1 */
164 /* 0x1cf = 0x20. Inform 8051 to reset. 2009.12.25. tynli_test */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200165 rtl8723au_write8(padapter, REG_HMETFR + 3, 0x20);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500166
Jes Sorensen050abc42014-05-16 10:05:08 +0200167 u1bTmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
Jes Sorensenbc0d10c2014-05-16 10:03:49 +0200168 while (u1bTmp & BIT(2)) {
Larry Fingerf7c92d22014-03-28 21:37:39 -0500169 Delay--;
170 if (Delay == 0)
171 break;
172 udelay(50);
Jes Sorensen050abc42014-05-16 10:05:08 +0200173 u1bTmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500174 }
175 RT_TRACE(_module_hal_init_c_, _drv_info_,
176 ("-%s: 8051 reset success (%d)\n", __func__,
177 Delay));
178
179 if ((Delay == 0)) {
180 /* force firmware reset */
Jes Sorensen050abc42014-05-16 10:05:08 +0200181 u1bTmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200182 rtl8723au_write8(padapter, REG_SYS_FUNC_EN + 1,
183 u1bTmp & ~BIT(2));
Larry Fingerf7c92d22014-03-28 21:37:39 -0500184 }
185 }
186}
187
188/* */
189/* Description: */
190/* Download 8192C firmware code. */
191/* */
192/* */
Jes Sorensena5681f92014-05-16 10:04:48 +0200193int rtl8723a_FirmwareDownload(struct rtw_adapter *padapter)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500194{
Jes Sorensena5681f92014-05-16 10:04:48 +0200195 int rtStatus = _SUCCESS;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500196 u8 writeFW_retry = 0;
197 unsigned long fwdl_start_time;
198 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
199 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
200 struct device *device = dvobj_to_dev(dvobj);
201 struct rt_8723a_firmware_hdr *pFwHdr = NULL;
202 const struct firmware *fw;
203 char *fw_name;
204 u8 *firmware_buf = NULL;
205 u8 *buf;
206 int fw_size;
207 static int log_version;
208
209 RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__));
210
211 if (IS_8723A_A_CUT(pHalData->VersionID)) {
Jes Sorensen6601e312014-06-09 15:16:11 +0200212 fw_name = "rtlwifi/rtl8723aufw_A.bin";
Larry Fingerf7c92d22014-03-28 21:37:39 -0500213 RT_TRACE(_module_hal_init_c_, _drv_info_,
214 ("rtl8723a_FirmwareDownload: R8723FwImageArray_UMC "
215 "for RTL8723A A CUT\n"));
216 } else if (IS_8723A_B_CUT(pHalData->VersionID)) {
217 /* WLAN Fw. */
218 if (padapter->registrypriv.wifi_spec == 1) {
219 fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin";
220 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithoutBT for "
221 "RTL8723A B CUT\n");
222 } else {
Jes Sorensen900a3262014-05-25 22:43:41 +0200223 if (rtl8723a_BT_coexist(padapter)) {
224 fw_name = "rtlwifi/rtl8723aufw_B.bin";
225 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithBT "
226 "for RTL8723A B CUT\n");
227 } else {
228 fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin";
229 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithout "
230 "BT for RTL8723A B CUT\n");
231 }
Larry Fingerf7c92d22014-03-28 21:37:39 -0500232 }
233 } else {
234 /* <Roger_TODO> We should download proper RAM Code here
235 to match the ROM code. */
236 RT_TRACE(_module_hal_init_c_, _drv_err_,
237 ("%s: unknow version!\n", __func__));
238 rtStatus = _FAIL;
239 goto Exit;
240 }
241
242 pr_info("rtl8723au: Loading firmware %s\n", fw_name);
243 if (request_firmware(&fw, fw_name, device)) {
244 pr_err("rtl8723au: request_firmware load failed\n");
245 rtStatus = _FAIL;
246 goto Exit;
247 }
248 if (!fw) {
249 pr_err("rtl8723au: Firmware %s not available\n", fw_name);
250 rtStatus = _FAIL;
251 goto Exit;
252 }
Benoit Taine4a6eea42014-05-22 15:08:33 +0200253 firmware_buf = kmemdup(fw->data, fw->size, GFP_KERNEL);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500254 if (!firmware_buf) {
255 rtStatus = _FAIL;
256 goto Exit;
257 }
Larry Fingerf7c92d22014-03-28 21:37:39 -0500258 buf = firmware_buf;
259 fw_size = fw->size;
260 release_firmware(fw);
261
262 /* To Check Fw header. Added by tynli. 2009.12.04. */
263 pFwHdr = (struct rt_8723a_firmware_hdr *)firmware_buf;
264
265 pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version);
266 pHalData->FirmwareSubVersion = pFwHdr->Subversion;
267 pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
268
269 DBG_8723A("%s: fw_ver =%d fw_subver =%d sig = 0x%x\n",
270 __func__, pHalData->FirmwareVersion,
271 pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
272
273 if (!log_version++)
274 pr_info("%sFirmware Version %d, SubVersion %d, Signature "
275 "0x%x\n", DRIVER_PREFIX, pHalData->FirmwareVersion,
276 pHalData->FirmwareSubVersion,
277 pHalData->FirmwareSignature);
278
279 if (IS_FW_HEADER_EXIST(pFwHdr)) {
280 /* Shift 32 bytes for FW header */
281 buf = buf + 32;
282 fw_size = fw_size - 32;
283 }
284
285 /* Suggested by Filen. If 8051 is running in RAM code, driver should
286 inform Fw to reset by itself, */
287 /* or it will cause download Fw fail. 2010.02.01. by tynli. */
Jes Sorensen050abc42014-05-16 10:05:08 +0200288 if (rtl8723au_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) {
Larry Fingerf7c92d22014-03-28 21:37:39 -0500289 /* 8051 RAM code */
290 rtl8723a_FirmwareSelfReset(padapter);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200291 rtl8723au_write8(padapter, REG_MCUFWDL, 0x00);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500292 }
293
294 _FWDownloadEnable(padapter, true);
295 fwdl_start_time = jiffies;
296 while (1) {
297 /* reset the FWDL chksum */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200298 rtl8723au_write8(padapter, REG_MCUFWDL,
299 rtl8723au_read8(padapter, REG_MCUFWDL) |
300 FWDL_ChkSum_rpt);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500301
302 rtStatus = _WriteFW(padapter, buf, fw_size);
303
304 if (rtStatus == _SUCCESS ||
Larry Fingerc17416e2014-03-28 21:37:42 -0500305 (jiffies_to_msecs(jiffies - fwdl_start_time) > 500 &&
Larry Fingerf7c92d22014-03-28 21:37:39 -0500306 writeFW_retry++ >= 3))
307 break;
308
309 DBG_8723A("%s writeFW_retry:%u, time after fwdl_start_time:"
310 "%ums\n", __func__, writeFW_retry,
311 jiffies_to_msecs(jiffies - fwdl_start_time));
312 }
313 _FWDownloadEnable(padapter, false);
314 if (_SUCCESS != rtStatus) {
315 DBG_8723A("DL Firmware failed!\n");
316 goto Exit;
317 }
318
319 rtStatus = _FWFreeToGo(padapter);
320 if (_SUCCESS != rtStatus) {
321 RT_TRACE(_module_hal_init_c_, _drv_err_,
322 ("DL Firmware failed!\n"));
323 goto Exit;
324 }
325 RT_TRACE(_module_hal_init_c_, _drv_info_,
326 ("Firmware is ready to run!\n"));
327
328Exit:
329 kfree(firmware_buf);
330 return rtStatus;
331}
332
333void rtl8723a_InitializeFirmwareVars(struct rtw_adapter *padapter)
334{
335 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
336
337 /* Init Fw LPS related. */
338 padapter->pwrctrlpriv.bFwCurrentInPSMode = false;
339
340 /* Init H2C counter. by tynli. 2009.12.09. */
341 pHalData->LastHMEBoxNum = 0;
342}
343
Larry Fingerf7c92d22014-03-28 21:37:39 -0500344/* */
345/* Efuse related code */
346/* */
347static u8
348hal_EfuseSwitchToBank(struct rtw_adapter *padapter, u8 bank)
349{
350 u8 bRet = false;
351 u32 value32 = 0;
352
353 DBG_8723A("%s: Efuse switch bank to %d\n", __func__, bank);
Jes Sorensen050abc42014-05-16 10:05:08 +0200354 value32 = rtl8723au_read32(padapter, EFUSE_TEST);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500355 bRet = true;
356 switch (bank) {
357 case 0:
358 value32 = (value32 & ~EFUSE_SEL_MASK) |
359 EFUSE_SEL(EFUSE_WIFI_SEL_0);
360 break;
361 case 1:
362 value32 = (value32 & ~EFUSE_SEL_MASK) |
363 EFUSE_SEL(EFUSE_BT_SEL_0);
364 break;
365 case 2:
366 value32 = (value32 & ~EFUSE_SEL_MASK) |
367 EFUSE_SEL(EFUSE_BT_SEL_1);
368 break;
369 case 3:
370 value32 = (value32 & ~EFUSE_SEL_MASK) |
371 EFUSE_SEL(EFUSE_BT_SEL_2);
372 break;
373 default:
374 value32 = (value32 & ~EFUSE_SEL_MASK) |
375 EFUSE_SEL(EFUSE_WIFI_SEL_0);
376 bRet = false;
377 break;
378 }
Jes Sorensenedbfd672014-05-16 10:05:09 +0200379 rtl8723au_write32(padapter, EFUSE_TEST, value32);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500380
381 return bRet;
382}
383
384static void
Larry Fingerf7c92d22014-03-28 21:37:39 -0500385hal_ReadEFuse_WiFi(struct rtw_adapter *padapter,
386 u16 _offset, u16 _size_byte, u8 *pbuf)
387{
388 u8 *efuseTbl = NULL;
389 u16 eFuse_Addr = 0;
390 u8 offset, wden;
391 u8 efuseHeader, efuseExtHdr, efuseData;
392 u16 i, total, used;
Jes Sorensena2342292014-04-09 23:20:46 +0200393 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500394
395 /* Do NOT excess total size of EFuse table.
396 Added by Roger, 2008.11.10. */
397 if ((_offset + _size_byte) > EFUSE_MAP_LEN_8723A) {
398 DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n",
399 __func__, _offset, _size_byte);
400 return;
401 }
402
Sachin Kamat2e697592014-05-28 17:36:29 +0530403 efuseTbl = kmalloc(EFUSE_MAP_LEN_8723A, GFP_KERNEL);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500404 if (efuseTbl == NULL) {
405 DBG_8723A("%s: alloc efuseTbl fail!\n", __func__);
406 return;
407 }
408 /* 0xff will be efuse default value instead of 0x00. */
409 memset(efuseTbl, 0xFF, EFUSE_MAP_LEN_8723A);
410
411 /* switch bank back to bank 0 for later BT and wifi use. */
412 hal_EfuseSwitchToBank(padapter, 0);
413
414 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
415 ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseHeader);
416 if (efuseHeader == 0xFF) {
417 DBG_8723A("%s: data end at address =%#x\n", __func__,
418 eFuse_Addr);
419 break;
420 }
421
422 /* Check PG header for section num. */
423 if (EXT_HEADER(efuseHeader)) { /* extended header */
424 offset = GET_HDR_OFFSET_2_0(efuseHeader);
425
426 ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseExtHdr);
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +0100427 if (ALL_WORDS_DISABLED(efuseExtHdr))
Larry Fingerf7c92d22014-03-28 21:37:39 -0500428 continue;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500429
430 offset |= ((efuseExtHdr & 0xF0) >> 1);
431 wden = (efuseExtHdr & 0x0F);
432 } else {
433 offset = ((efuseHeader >> 4) & 0x0f);
434 wden = (efuseHeader & 0x0f);
435 }
436
437 if (offset < EFUSE_MAX_SECTION_8723A) {
438 u16 addr;
439 /* Get word enable value from PG header */
440
441 addr = offset * PGPKT_DATA_SIZE;
442 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
443 /* Check word enable condition in the section */
444 if (!(wden & (0x01 << i))) {
445 ReadEFuseByte23a(padapter, eFuse_Addr++,
446 &efuseData);
447 efuseTbl[addr] = efuseData;
448
449 ReadEFuseByte23a(padapter, eFuse_Addr++,
450 &efuseData);
451 efuseTbl[addr + 1] = efuseData;
452 }
453 addr += 2;
454 }
455 } else {
456 DBG_8723A(KERN_ERR "%s: offset(%d) is illegal!!\n",
457 __func__, offset);
458 eFuse_Addr += Efuse_CalculateWordCnts23a(wden) * 2;
459 }
460 }
461
462 /* Copy from Efuse map to output pointer memory!!! */
463 for (i = 0; i < _size_byte; i++)
464 pbuf[i] = efuseTbl[_offset + i];
465
466 /* Calculate Efuse utilization */
467 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
468 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
469 used = eFuse_Addr - 1;
Jes Sorensena2342292014-04-09 23:20:46 +0200470 pHalData->EfuseUsedBytes = used;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500471
472 kfree(efuseTbl);
473}
474
475static void
476hal_ReadEFuse_BT(struct rtw_adapter *padapter,
477 u16 _offset, u16 _size_byte, u8 *pbuf)
478{
479 u8 *efuseTbl;
480 u8 bank;
481 u16 eFuse_Addr;
482 u8 efuseHeader, efuseExtHdr, efuseData;
483 u8 offset, wden;
484 u16 i, total, used;
Jes Sorensena2342292014-04-09 23:20:46 +0200485 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500486
487 /* Do NOT excess total size of EFuse table.
488 Added by Roger, 2008.11.10. */
489 if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) {
490 DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n",
491 __func__, _offset, _size_byte);
492 return;
493 }
494
495 efuseTbl = kmalloc(EFUSE_BT_MAP_LEN, GFP_KERNEL);
496 if (efuseTbl == NULL) {
497 DBG_8723A("%s: efuseTbl malloc fail!\n", __func__);
498 return;
499 }
500 /* 0xff will be efuse default value instead of 0x00. */
501 memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
502
503 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
504 TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total);
505
506 for (bank = 1; bank < EFUSE_MAX_BANK; bank++) {
507 if (hal_EfuseSwitchToBank(padapter, bank) == false) {
508 DBG_8723A("%s: hal_EfuseSwitchToBank Fail!!\n",
509 __func__);
510 goto exit;
511 }
512
513 eFuse_Addr = 0;
514
515 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
516 ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseHeader);
517 if (efuseHeader == 0xFF)
518 break;
519
520 /* Check PG header for section num. */
521 if (EXT_HEADER(efuseHeader)) { /* extended header */
522 offset = GET_HDR_OFFSET_2_0(efuseHeader);
523
524 ReadEFuseByte23a(padapter, eFuse_Addr++,
525 &efuseExtHdr);
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +0100526 if (ALL_WORDS_DISABLED(efuseExtHdr))
Larry Fingerf7c92d22014-03-28 21:37:39 -0500527 continue;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500528
529 offset |= ((efuseExtHdr & 0xF0) >> 1);
530 wden = (efuseExtHdr & 0x0F);
531 } else {
532 offset = ((efuseHeader >> 4) & 0x0f);
533 wden = (efuseHeader & 0x0f);
534 }
535
536 if (offset < EFUSE_BT_MAX_SECTION) {
537 u16 addr;
538
539 /* Get word enable value from PG header */
540
541 addr = offset * PGPKT_DATA_SIZE;
542 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
543 /* Check word enable condition in
544 the section */
545 if (!(wden & (0x01 << i))) {
546 ReadEFuseByte23a(padapter,
547 eFuse_Addr++,
548 &efuseData);
549 efuseTbl[addr] = efuseData;
550
551 ReadEFuseByte23a(padapter,
552 eFuse_Addr++,
553 &efuseData);
554 efuseTbl[addr + 1] = efuseData;
555 }
556 addr += 2;
557 }
558 } else {
559 DBG_8723A(KERN_ERR
560 "%s: offset(%d) is illegal!!\n",
561 __func__, offset);
562 eFuse_Addr += Efuse_CalculateWordCnts23a(wden) * 2;
563 }
564 }
565
566 if ((eFuse_Addr - 1) < total) {
567 DBG_8723A("%s: bank(%d) data end at %#x\n",
568 __func__, bank, eFuse_Addr - 1);
569 break;
570 }
571 }
572
573 /* switch bank back to bank 0 for later BT and wifi use. */
574 hal_EfuseSwitchToBank(padapter, 0);
575
576 /* Copy from Efuse map to output pointer memory!!! */
577 for (i = 0; i < _size_byte; i++)
578 pbuf[i] = efuseTbl[_offset + i];
579
580 /* */
581 /* Calculate Efuse utilization. */
582 /* */
583 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
584 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
585 used = (EFUSE_BT_REAL_BANK_CONTENT_LEN * (bank - 1)) + eFuse_Addr - 1;
Jes Sorensena2342292014-04-09 23:20:46 +0200586 pHalData->BTEfuseUsedBytes = used;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500587
588exit:
589 kfree(efuseTbl);
590}
591
Jes Sorensenb2e68042014-05-16 10:04:14 +0200592void
593rtl8723a_readefuse(struct rtw_adapter *padapter,
594 u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500595{
596 if (efuseType == EFUSE_WIFI)
597 hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf);
598 else
599 hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf);
600}
601
Jes Sorensenb2e68042014-05-16 10:04:14 +0200602u16 rtl8723a_EfuseGetCurrentSize_WiFi(struct rtw_adapter *padapter)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500603{
604 u16 efuse_addr = 0;
605 u8 hoffset = 0, hworden = 0;
606 u8 efuse_data, word_cnts = 0;
Jes Sorensena2342292014-04-09 23:20:46 +0200607 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500608
Jes Sorensena2342292014-04-09 23:20:46 +0200609 efuse_addr = pHalData->EfuseUsedBytes;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500610
611 DBG_8723A("%s: start_efuse_addr = 0x%X\n", __func__, efuse_addr);
612
613 /* switch bank back to bank 0 for later BT and wifi use. */
614 hal_EfuseSwitchToBank(padapter, 0);
615
616 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
617 if (efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data) ==
Jes Sorensen44f3f162014-05-16 10:04:29 +0200618 _FAIL) {
Larry Fingerf7c92d22014-03-28 21:37:39 -0500619 DBG_8723A(KERN_ERR "%s: efuse_OneByteRead23a Fail! "
620 "addr = 0x%X !!\n", __func__, efuse_addr);
621 break;
622 }
623
624 if (efuse_data == 0xFF)
625 break;
626
627 if (EXT_HEADER(efuse_data)) {
628 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
629 efuse_addr++;
630 efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data);
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +0100631 if (ALL_WORDS_DISABLED(efuse_data))
Larry Fingerf7c92d22014-03-28 21:37:39 -0500632 continue;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500633
634 hoffset |= ((efuse_data & 0xF0) >> 1);
635 hworden = efuse_data & 0x0F;
636 } else {
637 hoffset = (efuse_data >> 4) & 0x0F;
638 hworden = efuse_data & 0x0F;
639 }
640
641 word_cnts = Efuse_CalculateWordCnts23a(hworden);
642 efuse_addr += (word_cnts * 2) + 1;
643 }
644
Jes Sorensena2342292014-04-09 23:20:46 +0200645 pHalData->EfuseUsedBytes = efuse_addr;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500646
647 DBG_8723A("%s: CurrentSize =%d\n", __func__, efuse_addr);
648
649 return efuse_addr;
650}
651
Jes Sorensenb2e68042014-05-16 10:04:14 +0200652u16 rtl8723a_EfuseGetCurrentSize_BT(struct rtw_adapter *padapter)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500653{
654 u16 btusedbytes;
655 u16 efuse_addr;
656 u8 bank, startBank;
657 u8 hoffset = 0, hworden = 0;
658 u8 efuse_data, word_cnts = 0;
659 u16 retU2 = 0;
Jes Sorensena2342292014-04-09 23:20:46 +0200660 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500661
Jes Sorensena2342292014-04-09 23:20:46 +0200662 btusedbytes = pHalData->BTEfuseUsedBytes;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500663
664 efuse_addr = (u16) ((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN));
665 startBank = (u8) (1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN));
666
667 DBG_8723A("%s: start from bank =%d addr = 0x%X\n", __func__, startBank,
668 efuse_addr);
669
670 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
671 TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2);
672
673 for (bank = startBank; bank < EFUSE_MAX_BANK; bank++) {
674 if (hal_EfuseSwitchToBank(padapter, bank) == false) {
675 DBG_8723A(KERN_ERR "%s: switch bank(%d) Fail!!\n",
676 __func__, bank);
677 bank = EFUSE_MAX_BANK;
678 break;
679 }
680
681 /* only when bank is switched we have to reset
682 the efuse_addr. */
683 if (bank != startBank)
684 efuse_addr = 0;
685
686 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
687 if (efuse_OneByteRead23a(padapter, efuse_addr,
Jes Sorensen44f3f162014-05-16 10:04:29 +0200688 &efuse_data) == _FAIL) {
Larry Fingerf7c92d22014-03-28 21:37:39 -0500689 DBG_8723A(KERN_ERR "%s: efuse_OneByteRead23a Fail!"
690 " addr = 0x%X !!\n",
691 __func__, efuse_addr);
692 bank = EFUSE_MAX_BANK;
693 break;
694 }
695
696 if (efuse_data == 0xFF)
697 break;
698
699 if (EXT_HEADER(efuse_data)) {
700 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
701 efuse_addr++;
702 efuse_OneByteRead23a(padapter, efuse_addr,
703 &efuse_data);
704 if (ALL_WORDS_DISABLED(efuse_data)) {
705 efuse_addr++;
706 continue;
707 }
708
709 hoffset |= ((efuse_data & 0xF0) >> 1);
710 hworden = efuse_data & 0x0F;
711 } else {
712 hoffset = (efuse_data >> 4) & 0x0F;
713 hworden = efuse_data & 0x0F;
714 }
715 word_cnts = Efuse_CalculateWordCnts23a(hworden);
716 /* read next header */
717 efuse_addr += (word_cnts * 2) + 1;
718 }
719
720 /* Check if we need to check next bank efuse */
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +0100721 if (efuse_addr < retU2)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500722 break; /* don't need to check next bank. */
Larry Fingerf7c92d22014-03-28 21:37:39 -0500723 }
724
725 retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
Jes Sorensena2342292014-04-09 23:20:46 +0200726 pHalData->BTEfuseUsedBytes = retU2;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500727
728 DBG_8723A("%s: CurrentSize =%d\n", __func__, retU2);
729 return retU2;
730}
731
Jes Sorensen44e621c2014-05-16 10:04:04 +0200732void rtl8723a_read_chip_version(struct rtw_adapter *padapter)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500733{
734 u32 value32;
735 struct hal_version ChipVersion;
736 struct hal_data_8723a *pHalData;
737
738 pHalData = GET_HAL_DATA(padapter);
739
Jes Sorensen050abc42014-05-16 10:05:08 +0200740 value32 = rtl8723au_read32(padapter, REG_SYS_CFG);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500741 ChipVersion.ICType = CHIP_8723A;
742 ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
Jes Sorensen277c7222015-02-27 15:45:32 -0500743 pHalData->rf_type = RF_1T1R;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500744 ChipVersion.VendorType =
745 ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
746 ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */
747
748 /* For regulator mode. by tynli. 2011.01.14 */
749 pHalData->RegulatorMode = ((value32 & SPS_SEL) ?
750 RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
751
Jes Sorensen050abc42014-05-16 10:05:08 +0200752 value32 = rtl8723au_read32(padapter, REG_GPIO_OUTSTS);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500753 /* ROM code version. */
Aya Mahfouze1bc88f2015-03-04 07:34:07 +0200754 ChipVersion.ROMVer = (value32 & RF_RL_ID) >> 20;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500755
756 /* For multi-function consideration. Added by Roger, 2010.10.06. */
757 pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
Jes Sorensen050abc42014-05-16 10:05:08 +0200758 value32 = rtl8723au_read32(padapter, REG_MULTI_FUNC_CTRL);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500759 pHalData->MultiFunc |=
760 ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
761 pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
762 pHalData->MultiFunc |=
763 ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
764 pHalData->PolarityCtl =
765 ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT :
766 RT_POLARITY_LOW_ACT);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500767 pHalData->VersionID = ChipVersion;
768
Larry Fingerf7c92d22014-03-28 21:37:39 -0500769 MSG_8723A("RF_Type is %x!!\n", pHalData->rf_type);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500770}
771
772/* */
773/* */
774/* 20100209 Joseph: */
775/* This function is used only for 92C to set REG_BCN_CTRL(0x550) register. */
776/* We just reserve the value of the register in variable
777 pHalData->RegBcnCtrlVal and then operate */
778/* the value of the register via atomic operation. */
779/* This prevents from race condition when setting this register. */
780/* The value of pHalData->RegBcnCtrlVal is initialized in
781 HwConfigureRTL8192CE() function. */
782/* */
783void SetBcnCtrlReg23a(struct rtw_adapter *padapter, u8 SetBits, u8 ClearBits)
784{
Jes Sorensene4d480b2014-07-17 22:59:52 +0200785 u8 val8;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500786
Jes Sorensene4d480b2014-07-17 22:59:52 +0200787 val8 = rtl8723au_read8(padapter, REG_BCN_CTRL);
788 val8 |= SetBits;
789 val8 &= ~ClearBits;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500790
Jes Sorensene4d480b2014-07-17 22:59:52 +0200791 rtl8723au_write8(padapter, REG_BCN_CTRL, val8);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500792}
793
794void rtl8723a_InitBeaconParameters(struct rtw_adapter *padapter)
795{
Jes Sorensenedbfd672014-05-16 10:05:09 +0200796 rtl8723au_write16(padapter, REG_BCN_CTRL, 0x1010);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500797
798 /* TODO: Remove these magic number */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200799 rtl8723au_write16(padapter, REG_TBTT_PROHIBIT, 0x6404); /* ms */
Larry Fingerf7c92d22014-03-28 21:37:39 -0500800 /* Firmware will control REG_DRVERLYINT when power saving is enable, */
801 /* so don't set this register on STA mode. */
802 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == false)
Jes Sorensenedbfd672014-05-16 10:05:09 +0200803 rtl8723au_write8(padapter, REG_DRVERLYINT,
804 DRIVER_EARLY_INT_TIME);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500805 /* 2ms */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200806 rtl8723au_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500807
808 /* Suggested by designer timchen. Change beacon AIFS to the
809 largest number beacause test chip does not contension before
810 sending beacon. by tynli. 2009.11.03 */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200811 rtl8723au_write16(padapter, REG_BCNTCFG, 0x660F);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500812}
813
814static void ResumeTxBeacon(struct rtw_adapter *padapter)
815{
816 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
817
818 /* 2010.03.01. Marked by tynli. No need to call workitem beacause
819 we record the value */
820 /* which should be read from register to a global variable. */
821
822 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
823
824 pHalData->RegFwHwTxQCtrl |= BIT(6);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200825 rtl8723au_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
826 pHalData->RegFwHwTxQCtrl);
827 rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xff);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500828 pHalData->RegReg542 |= BIT(0);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200829 rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500830}
831
832static void StopTxBeacon(struct rtw_adapter *padapter)
833{
834 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
835
836 /* 2010.03.01. Marked by tynli. No need to call workitem beacause
837 we record the value */
838 /* which should be read from register to a global variable. */
839
840 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
841
842 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200843 rtl8723au_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
844 pHalData->RegFwHwTxQCtrl);
845 rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500846 pHalData->RegReg542 &= ~BIT(0);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200847 rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500848}
849
850static void _BeaconFunctionEnable(struct rtw_adapter *padapter, u8 Enable,
851 u8 Linked)
852{
853 SetBcnCtrlReg23a(padapter, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB,
854 0);
Jes Sorensenedbfd672014-05-16 10:05:09 +0200855 rtl8723au_write8(padapter, REG_RD_CTRL + 1, 0x6F);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500856}
857
Jes Sorensen88715bc2014-05-16 10:04:10 +0200858void rtl8723a_SetBeaconRelatedRegisters(struct rtw_adapter *padapter)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500859{
860 u32 value32;
861 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
862 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
863
864 /* reset TSF, enable update TSF, correcting TSF On Beacon */
865
866 /* REG_BCN_INTERVAL */
867 /* REG_BCNDMATIM */
868 /* REG_ATIMWND */
869 /* REG_TBTT_PROHIBIT */
870 /* REG_DRVERLYINT */
871 /* REG_BCN_MAX_ERR */
872 /* REG_BCNTCFG (0x510) */
873 /* REG_DUAL_TSF_RST */
874 /* REG_BCN_CTRL (0x550) */
875
876 /* */
877 /* ATIM window */
878 /* */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200879 rtl8723au_write16(padapter, REG_ATIMWND, 2);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500880
881 /* */
882 /* Beacon interval (in unit of TU). */
883 /* */
Jes Sorensenedbfd672014-05-16 10:05:09 +0200884 rtl8723au_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500885
886 rtl8723a_InitBeaconParameters(padapter);
887
Jes Sorensenedbfd672014-05-16 10:05:09 +0200888 rtl8723au_write8(padapter, REG_SLOT, 0x09);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500889
890 /* */
891 /* Reset TSF Timer to zero, added by Roger. 2008.06.24 */
892 /* */
Jes Sorensen050abc42014-05-16 10:05:08 +0200893 value32 = rtl8723au_read32(padapter, REG_TCR);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500894 value32 &= ~TSFRST;
Jes Sorensenedbfd672014-05-16 10:05:09 +0200895 rtl8723au_write32(padapter, REG_TCR, value32);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500896
897 value32 |= TSFRST;
Jes Sorensenedbfd672014-05-16 10:05:09 +0200898 rtl8723au_write32(padapter, REG_TCR, value32);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500899
900 /* NOTE: Fix test chip's bug (about contention windows's randomness) */
901 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE |
902 WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE) == true) {
Jes Sorensenedbfd672014-05-16 10:05:09 +0200903 rtl8723au_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
904 rtl8723au_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
Larry Fingerf7c92d22014-03-28 21:37:39 -0500905 }
906
907 _BeaconFunctionEnable(padapter, true, true);
908
909 ResumeTxBeacon(padapter);
910 SetBcnCtrlReg23a(padapter, DIS_BCNQ_SUB, 0);
911}
912
Jes Sorensendbe98492014-05-16 10:04:13 +0200913void rtl8723a_SetHalODMVar(struct rtw_adapter *Adapter,
914 enum hal_odm_variable eVariable,
915 void *pValue1, bool bSet)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500916{
917 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
918 struct dm_odm_t *podmpriv = &pHalData->odmpriv;
919 switch (eVariable) {
920 case HAL_ODM_STA_INFO:
921 {
922 struct sta_info *psta = (struct sta_info *)pValue1;
923
924 if (bSet) {
925 DBG_8723A("Set STA_(%d) info\n", psta->mac_id);
926 ODM_CmnInfoPtrArrayHook23a(podmpriv,
927 ODM_CMNINFO_STA_STATUS,
928 psta->mac_id, psta);
929 } else {
930 DBG_8723A("Clean STA_(%d) info\n", psta->mac_id);
931 ODM_CmnInfoPtrArrayHook23a(podmpriv,
932 ODM_CMNINFO_STA_STATUS,
933 psta->mac_id, NULL);
934 }
935 }
936 break;
937 case HAL_ODM_P2P_STATE:
938 ODM_CmnInfoUpdate23a(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
939 break;
940 case HAL_ODM_WIFI_DISPLAY_STATE:
941 ODM_CmnInfoUpdate23a(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
942 break;
943 default:
944 break;
945 }
946}
947
Jes Sorensen369074f2014-05-16 10:04:02 +0200948void rtl8723a_notch_filter(struct rtw_adapter *adapter, bool enable)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500949{
950 if (enable) {
951 DBG_8723A("Enable notch filter\n");
Jes Sorensenedbfd672014-05-16 10:05:09 +0200952 rtl8723au_write8(adapter, rOFDM0_RxDSP + 1,
953 rtl8723au_read8(adapter, rOFDM0_RxDSP + 1) |
954 BIT(1));
Larry Fingerf7c92d22014-03-28 21:37:39 -0500955 } else {
956 DBG_8723A("Disable notch filter\n");
Jes Sorensenedbfd672014-05-16 10:05:09 +0200957 rtl8723au_write8(adapter, rOFDM0_RxDSP + 1,
958 rtl8723au_read8(adapter, rOFDM0_RxDSP + 1) &
959 ~BIT(1));
Larry Fingerf7c92d22014-03-28 21:37:39 -0500960 }
961}
962
Jes Sorensena5681f92014-05-16 10:04:48 +0200963bool c2h_id_filter_ccx_8723a(u8 id)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500964{
Jes Sorensena5681f92014-05-16 10:04:48 +0200965 bool ret = false;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500966 if (id == C2H_CCX_TX_RPT)
967 ret = true;
968
969 return ret;
970}
971
Jes Sorensena5681f92014-05-16 10:04:48 +0200972int c2h_handler_8723a(struct rtw_adapter *padapter, struct c2h_evt_hdr *c2h_evt)
Larry Fingerf7c92d22014-03-28 21:37:39 -0500973{
Jes Sorensena5681f92014-05-16 10:04:48 +0200974 int ret = _SUCCESS;
Larry Fingerf7c92d22014-03-28 21:37:39 -0500975 u8 i = 0;
976
977 if (c2h_evt == NULL) {
978 DBG_8723A("%s c2h_evt is NULL\n", __func__);
979 ret = _FAIL;
980 goto exit;
981 }
982
983 switch (c2h_evt->id) {
984 case C2H_DBG:
985 RT_TRACE(_module_hal_init_c_, _drv_info_,
986 ("C2HCommandHandler: %s\n", c2h_evt->payload));
987 break;
988
989 case C2H_CCX_TX_RPT:
990 handle_txrpt_ccx_8723a(padapter, c2h_evt->payload);
991 break;
992 case C2H_EXT_RA_RPT:
993 break;
994 case C2H_HW_INFO_EXCH:
995 RT_TRACE(_module_hal_init_c_, _drv_info_,
996 ("[BT], C2H_HW_INFO_EXCH\n"));
997 for (i = 0; i < c2h_evt->plen; i++) {
998 RT_TRACE(_module_hal_init_c_, _drv_info_,
999 ("[BT], tmpBuf[%d]= 0x%x\n", i,
1000 c2h_evt->payload[i]));
1001 }
1002 break;
1003
1004 case C2H_C2H_H2C_TEST:
1005 RT_TRACE(_module_hal_init_c_, _drv_info_,
1006 ("[BT], C2H_H2C_TEST\n"));
1007 RT_TRACE(_module_hal_init_c_, _drv_info_,
1008 ("[BT], tmpBuf[0]/[1]/[2]/[3]/[4]= 0x%x/ 0x%x/ "
1009 "0x%x/ 0x%x/ 0x%x\n", c2h_evt->payload[0],
1010 c2h_evt->payload[1], c2h_evt->payload[2],
1011 c2h_evt->payload[3], c2h_evt->payload[4]));
1012 break;
1013
Larry Fingerf7c92d22014-03-28 21:37:39 -05001014 case C2H_BT_INFO:
1015 DBG_8723A("%s , Got C2H_BT_INFO \n", __func__);
Jes Sorensen1d599de2014-05-25 22:43:46 +02001016 rtl8723a_fw_c2h_BT_info(padapter,
1017 c2h_evt->payload, c2h_evt->plen);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001018 break;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001019
1020 default:
1021 ret = _FAIL;
1022 break;
1023 }
1024
1025exit:
1026 return ret;
1027}
1028
Jes Sorensen116bf142014-11-30 16:04:56 -05001029void handle_txrpt_ccx_8723a(struct rtw_adapter *adapter, void *buf)
1030{
1031 struct txrpt_ccx_8723a *txrpt_ccx = buf;
1032 struct submit_ctx *pack_tx_ops = &adapter->xmitpriv.ack_tx_ops;
1033
1034 if (txrpt_ccx->int_ccx && adapter->xmitpriv.ack_tx) {
1035 if (txrpt_ccx->pkt_ok)
1036 rtw23a_sctx_done_err(&pack_tx_ops,
1037 RTW_SCTX_DONE_SUCCESS);
1038 else
1039 rtw23a_sctx_done_err(&pack_tx_ops,
1040 RTW_SCTX_DONE_CCX_PKT_FAIL);
1041 }
1042}
1043
Larry Fingerf7c92d22014-03-28 21:37:39 -05001044void rtl8723a_InitAntenna_Selection(struct rtw_adapter *padapter)
1045{
Larry Fingerf7c92d22014-03-28 21:37:39 -05001046 u8 val;
1047
Jes Sorensen050abc42014-05-16 10:05:08 +02001048 val = rtl8723au_read8(padapter, REG_LEDCFG2);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001049 /* Let 8051 take control antenna settting */
1050 val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001051 rtl8723au_write8(padapter, REG_LEDCFG2, val);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001052}
1053
1054void rtl8723a_CheckAntenna_Selection(struct rtw_adapter *padapter)
1055{
Larry Fingerf7c92d22014-03-28 21:37:39 -05001056 u8 val;
1057
Jes Sorensen050abc42014-05-16 10:05:08 +02001058 val = rtl8723au_read8(padapter, REG_LEDCFG2);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001059 /* Let 8051 take control antenna settting */
1060 if (!(val & BIT(7))) {
1061 val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001062 rtl8723au_write8(padapter, REG_LEDCFG2, val);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001063 }
1064}
1065
1066void rtl8723a_DeinitAntenna_Selection(struct rtw_adapter *padapter)
1067{
Larry Fingerf7c92d22014-03-28 21:37:39 -05001068 u8 val;
1069
Jes Sorensen050abc42014-05-16 10:05:08 +02001070 val = rtl8723au_read8(padapter, REG_LEDCFG2);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001071 /* Let 8051 take control antenna settting */
1072 val &= ~BIT(7); /* DPDT_SEL_EN, clear 0x4C[23] */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001073 rtl8723au_write8(padapter, REG_LEDCFG2, val);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001074}
1075
1076void rtl8723a_init_default_value(struct rtw_adapter *padapter)
1077{
1078 struct hal_data_8723a *pHalData;
1079 struct dm_priv *pdmpriv;
1080 u8 i;
1081
1082 pHalData = GET_HAL_DATA(padapter);
1083 pdmpriv = &pHalData->dmpriv;
1084
1085 /* init default value */
Larry Fingerf7c92d22014-03-28 21:37:39 -05001086 pHalData->bIQKInitialized = false;
1087 if (!padapter->pwrctrlpriv.bkeepfwalive)
1088 pHalData->LastHMEBoxNum = 0;
1089
1090 pHalData->bIQKInitialized = false;
1091
1092 /* init dm default value */
1093 pdmpriv->TM_Trigger = 0; /* for IQK */
1094/* pdmpriv->binitialized = false; */
1095/* pdmpriv->prv_traffic_idx = 3; */
1096/* pdmpriv->initialize = 0; */
1097
1098 pdmpriv->ThermalValue_HP_index = 0;
1099 for (i = 0; i < HP_THERMAL_NUM; i++)
1100 pdmpriv->ThermalValue_HP[i] = 0;
1101
1102 /* init Efuse variables */
1103 pHalData->EfuseUsedBytes = 0;
1104 pHalData->BTEfuseUsedBytes = 0;
1105}
1106
1107u8 GetEEPROMSize8723A(struct rtw_adapter *padapter)
1108{
1109 u8 size = 0;
1110 u32 cr;
1111
Jes Sorensen050abc42014-05-16 10:05:08 +02001112 cr = rtl8723au_read16(padapter, REG_9346CR);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001113 /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
1114 size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
1115
1116 MSG_8723A("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
1117
1118 return size;
1119}
1120
1121/* */
1122/* */
1123/* LLT R/W/Init function */
1124/* */
1125/* */
Jes Sorensena5681f92014-05-16 10:04:48 +02001126static int _LLTWrite(struct rtw_adapter *padapter, u32 address, u32 data)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001127{
Jes Sorensena5681f92014-05-16 10:04:48 +02001128 int status = _SUCCESS;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001129 s32 count = 0;
1130 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
1131 _LLT_OP(_LLT_WRITE_ACCESS);
1132 u16 LLTReg = REG_LLT_INIT;
1133
Jes Sorensenedbfd672014-05-16 10:05:09 +02001134 rtl8723au_write32(padapter, LLTReg, value);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001135
1136 /* polling */
1137 do {
Jes Sorensen050abc42014-05-16 10:05:08 +02001138 value = rtl8723au_read32(padapter, LLTReg);
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +01001139 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
Larry Fingerf7c92d22014-03-28 21:37:39 -05001140 break;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001141
1142 if (count > POLLING_LLT_THRESHOLD) {
1143 RT_TRACE(_module_hal_init_c_, _drv_err_,
1144 ("Failed to polling write LLT done at "
1145 "address %d!\n", address));
1146 status = _FAIL;
1147 break;
1148 }
1149 } while (count++);
1150
1151 return status;
1152}
1153
Jes Sorensena5681f92014-05-16 10:04:48 +02001154int InitLLTTable23a(struct rtw_adapter *padapter, u32 boundary)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001155{
Jes Sorensena5681f92014-05-16 10:04:48 +02001156 int status = _SUCCESS;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001157 u32 i;
1158 u32 txpktbuf_bndy = boundary;
1159 u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;
1160
1161 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
1162 status = _LLTWrite(padapter, i, i + 1);
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +01001163 if (status != _SUCCESS)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001164 return status;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001165 }
1166
1167 /* end of list */
1168 status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +01001169 if (status != _SUCCESS)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001170 return status;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001171
1172 /* Make the other pages as ring buffer */
1173 /* This ring buffer is used as beacon buffer if we config this
1174 MAC as two MAC transfer. */
1175 /* Otherwise used as local loopback buffer. */
1176 for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
1177 status = _LLTWrite(padapter, i, (i + 1));
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +01001178 if (_SUCCESS != status)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001179 return status;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001180 }
1181
1182 /* Let last entry point to the start entry of ring buffer */
1183 status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +01001184 if (status != _SUCCESS)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001185 return status;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001186
1187 return status;
1188}
1189
1190static void _DisableGPIO(struct rtw_adapter *padapter)
1191{
1192/***************************************
1193j. GPIO_PIN_CTRL 0x44[31:0]= 0x000
1194k.Value = GPIO_PIN_CTRL[7:0]
1195l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write external PIN level
1196m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
1197n. LEDCFG 0x4C[15:0] = 0x8080
1198***************************************/
1199 u32 value32;
1200 u32 u4bTmp;
1201
1202 /* 1. Disable GPIO[7:0] */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001203 rtl8723au_write16(padapter, REG_GPIO_PIN_CTRL + 2, 0x0000);
Jes Sorensen050abc42014-05-16 10:05:08 +02001204 value32 = rtl8723au_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001205 u4bTmp = value32 & 0x000000FF;
1206 value32 |= ((u4bTmp << 8) | 0x00FF0000);
Jes Sorensenedbfd672014-05-16 10:05:09 +02001207 rtl8723au_write32(padapter, REG_GPIO_PIN_CTRL, value32);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001208
1209 /* */
1210 /* <Roger_Notes> For RTL8723u multi-function configuration which
1211 was autoload from Efuse offset 0x0a and 0x0b, */
1212 /* WLAN HW GPIO[9], GPS HW GPIO[10] and BT HW GPIO[11]. */
1213 /* Added by Roger, 2010.10.07. */
1214 /* */
1215 /* 2. Disable GPIO[8] and GPIO[12] */
1216
1217 /* Configure all pins as input mode. */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001218 rtl8723au_write16(padapter, REG_GPIO_IO_SEL_2, 0x0000);
Jes Sorensen050abc42014-05-16 10:05:08 +02001219 value32 = rtl8723au_read32(padapter, REG_GPIO_PIN_CTRL_2) & 0xFFFF001F;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001220 u4bTmp = value32 & 0x0000001F;
1221 /* Set pin 8, 10, 11 and pin 12 to output mode. */
1222 value32 |= ((u4bTmp << 8) | 0x001D0000);
Jes Sorensenedbfd672014-05-16 10:05:09 +02001223 rtl8723au_write32(padapter, REG_GPIO_PIN_CTRL_2, value32);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001224
1225 /* 3. Disable LED0 & 1 */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001226 rtl8723au_write16(padapter, REG_LEDCFG0, 0x8080);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001227} /* end of _DisableGPIO() */
1228
1229static void _DisableRFAFEAndResetBB8192C(struct rtw_adapter *padapter)
1230{
1231/**************************************
1232a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue
1233b. RF path 0 offset 0x00 = 0x00 disable RF
1234c. APSD_CTRL 0x600[7:0] = 0x40
1235d. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine
1236e. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine
1237***************************************/
Jes Sorensenaba3eb12014-11-30 16:05:14 -05001238 u8 value8;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001239
Jes Sorensenedbfd672014-05-16 10:05:09 +02001240 rtl8723au_write8(padapter, REG_TXPAUSE, 0xFF);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001241
Jes Sorensenb1e111d2014-11-30 16:05:13 -05001242 PHY_SetRFReg(padapter, RF_PATH_A, 0x0, bMaskByte0, 0x0);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001243
Jes Sorensenaba3eb12014-11-30 16:05:14 -05001244 value8 = APSDOFF;
Jes Sorensenedbfd672014-05-16 10:05:09 +02001245 rtl8723au_write8(padapter, REG_APSD_CTRL, value8); /* 0x40 */
Larry Fingerf7c92d22014-03-28 21:37:39 -05001246
1247 /* Set BB reset at first */
Jes Sorensenaba3eb12014-11-30 16:05:14 -05001248 value8 = FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn;
Jes Sorensenedbfd672014-05-16 10:05:09 +02001249 rtl8723au_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x16 */
Larry Fingerf7c92d22014-03-28 21:37:39 -05001250
1251 /* Set global reset. */
1252 value8 &= ~FEN_BB_GLB_RSTn;
Jes Sorensenedbfd672014-05-16 10:05:09 +02001253 rtl8723au_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x14 */
Larry Fingerf7c92d22014-03-28 21:37:39 -05001254
1255 /* 2010/08/12 MH We need to set BB/GLBAL reset to save power
1256 for SS mode. */
1257
1258/* RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n")); */
1259}
1260
Larry Fingerf7c92d22014-03-28 21:37:39 -05001261static void _ResetDigitalProcedure1_92C(struct rtw_adapter *padapter,
1262 bool bWithoutHWSM)
1263{
1264 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1265
1266 if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20)) {
1267 /*****************************
1268 f. MCUFWDL 0x80[7:0]= 0 reset MCU ready status
1269 g. SYS_FUNC_EN 0x02[10]= 0 reset MCU register, (8051 reset)
1270 h. SYS_FUNC_EN 0x02[15-12]= 5 reset MAC register, DCORE
1271 i. SYS_FUNC_EN 0x02[10]= 1 enable MCU register,
1272 (8051 enable)
1273 ******************************/
Jes Sorensen31b7e842014-11-30 16:05:16 -05001274 u16 valu16;
Jes Sorensenedbfd672014-05-16 10:05:09 +02001275 rtl8723au_write8(padapter, REG_MCUFWDL, 0);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001276
Jes Sorensen050abc42014-05-16 10:05:08 +02001277 valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001278 /* reset MCU , 8051 */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001279 rtl8723au_write16(padapter, REG_SYS_FUNC_EN,
Jes Sorensen31b7e842014-11-30 16:05:16 -05001280 valu16 & ~FEN_CPUEN);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001281
Jes Sorensen050abc42014-05-16 10:05:08 +02001282 valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN) & 0x0FFF;
Jes Sorensenedbfd672014-05-16 10:05:09 +02001283 /* reset MAC */
1284 rtl8723au_write16(padapter, REG_SYS_FUNC_EN,
Jes Sorensen31b7e842014-11-30 16:05:16 -05001285 valu16 | FEN_HWPDN | FEN_ELDR);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001286
Jes Sorensen050abc42014-05-16 10:05:08 +02001287 valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001288 /* enable MCU , 8051 */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001289 rtl8723au_write16(padapter, REG_SYS_FUNC_EN,
1290 valu16 | FEN_CPUEN);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001291 } else {
1292 u8 retry_cnts = 0;
Jes Sorensen31b7e842014-11-30 16:05:16 -05001293 u8 val8;
1294
1295 val8 = rtl8723au_read8(padapter, REG_MCUFWDL);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001296
1297 /* 2010/08/12 MH For USB SS, we can not stop 8051 when we
1298 are trying to enter IPS/HW&SW radio off. For
1299 S3/S4/S5/Disable, we can stop 8051 because */
1300 /* we will init FW when power on again. */
Larry Fingerf7c92d22014-03-28 21:37:39 -05001301 /* If we want to SS mode, we can not reset 8051. */
Jes Sorensen31b7e842014-11-30 16:05:16 -05001302 if ((val8 & BIT(1)) && padapter->bFWReady) {
Larry Fingerf7c92d22014-03-28 21:37:39 -05001303 /* IF fw in RAM code, do reset */
Jes Sorensen31b7e842014-11-30 16:05:16 -05001304 /* 2010/08/25 MH Accordign to RD alfred's
1305 suggestion, we need to disable other */
1306 /* HRCV INT to influence 8051 reset. */
1307 rtl8723au_write8(padapter, REG_FWIMR, 0x20);
1308 /* 2011/02/15 MH According to Alex's
1309 suggestion, close mask to prevent
1310 incorrect FW write operation. */
1311 rtl8723au_write8(padapter, REG_FTIMR, 0x00);
1312 rtl8723au_write8(padapter, REG_FSIMR, 0x00);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001313
Jes Sorensen31b7e842014-11-30 16:05:16 -05001314 /* 8051 reset by self */
1315 rtl8723au_write8(padapter, REG_HMETFR + 3, 0x20);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001316
Jes Sorensen31b7e842014-11-30 16:05:16 -05001317 while ((retry_cnts++ < 100) &&
1318 (rtl8723au_read16(padapter, REG_SYS_FUNC_EN) &
1319 FEN_CPUEN)) {
1320 udelay(50); /* us */
1321 }
Larry Fingerf7c92d22014-03-28 21:37:39 -05001322
Jes Sorensen31b7e842014-11-30 16:05:16 -05001323 if (retry_cnts >= 100) {
1324 /* Reset MAC and Enable 8051 */
1325 rtl8723au_write8(padapter,
1326 REG_SYS_FUNC_EN + 1, 0x50);
1327 mdelay(10);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001328 }
1329 }
1330 /* Reset MAC and Enable 8051 */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001331 rtl8723au_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54);
1332 rtl8723au_write8(padapter, REG_MCUFWDL, 0);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001333 }
1334
1335 if (bWithoutHWSM) {
1336 /*****************************
1337 Without HW auto state machine
1338 g. SYS_CLKR 0x08[15:0] = 0x30A3 disable MAC clock
1339 h. AFE_PLL_CTRL 0x28[7:0] = 0x80 disable AFE PLL
1340 i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F gated AFE DIG_CLOCK
1341 j. SYS_ISO_CTRL 0x00[7:0] = 0xF9 isolated digital to PON
1342 ******************************/
1343 /* modify to 0x70A3 by Scott. */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001344 rtl8723au_write16(padapter, REG_SYS_CLKR, 0x70A3);
1345 rtl8723au_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
1346 rtl8723au_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
1347 rtl8723au_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001348 } else {
1349 /* Disable all RF/BB power */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001350 rtl8723au_write8(padapter, REG_RF_CTRL, 0x00);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001351 }
1352}
1353
Larry Fingerf7c92d22014-03-28 21:37:39 -05001354static void _ResetDigitalProcedure2(struct rtw_adapter *padapter)
1355{
1356/*****************************
1357k. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction
1358l. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock
1359m. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON
1360******************************/
1361 /* modify to 0x70a3 by Scott. */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001362 rtl8723au_write16(padapter, REG_SYS_CLKR, 0x70a3);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001363 /* modify to 0x82 by Scott. */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001364 rtl8723au_write8(padapter, REG_SYS_ISO_CTRL + 1, 0x82);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001365}
1366
1367static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM)
1368{
1369 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
Jes Sorensencffca682014-11-30 16:05:18 -05001370 u16 value16;
1371 u8 value8;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001372
1373 if (bWithoutHWSM) {
1374 /*****************************
1375 n. LDOA15_CTRL 0x20[7:0] = 0x04 disable A15 power
1376 o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power
1377 r. When driver call disable, the ASIC will turn off remaining
1378 clock automatically
1379 ******************************/
1380
Jes Sorensenedbfd672014-05-16 10:05:09 +02001381 rtl8723au_write8(padapter, REG_LDOA15_CTRL, 0x04);
1382 /* rtl8723au_write8(padapter, REG_LDOV12D_CTRL, 0x54); */
Larry Fingerf7c92d22014-03-28 21:37:39 -05001383
Jes Sorensen050abc42014-05-16 10:05:08 +02001384 value8 = rtl8723au_read8(padapter, REG_LDOV12D_CTRL);
Jes Sorensencffca682014-11-30 16:05:18 -05001385 value8 &= ~LDV12_EN;
Jes Sorensenedbfd672014-05-16 10:05:09 +02001386 rtl8723au_write8(padapter, REG_LDOV12D_CTRL, value8);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001387/* RT_TRACE(COMP_INIT, DBG_LOUD,
1388 (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n", value8)); */
1389 }
1390
1391 /*****************************
1392 h. SPS0_CTRL 0x11[7:0] = 0x23 enter PFM mode
1393 i. APS_FSMCO 0x04[15:0] = 0x4802 set USB suspend
1394 ******************************/
1395 value8 = 0x23;
1396 if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
Jes Sorensenbc0d10c2014-05-16 10:03:49 +02001397 value8 |= BIT(3);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001398
Jes Sorensenedbfd672014-05-16 10:05:09 +02001399 rtl8723au_write8(padapter, REG_SPS0_CTRL, value8);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001400
1401 if (bWithoutHWSM) {
1402 /* value16 |= (APDM_HOST | FSM_HSUS |/PFM_ALDN); */
1403 /* 2010/08/31 According to Filen description, we need to
1404 use HW to shut down 8051 automatically. */
1405 /* Becasue suspend operatione need the asistance of 8051
1406 to wait for 3ms. */
Jes Sorensencffca682014-11-30 16:05:18 -05001407 value16 = APDM_HOST | AFSM_HSUS | PFM_ALDN;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001408 } else {
Jes Sorensencffca682014-11-30 16:05:18 -05001409 value16 = APDM_HOST | AFSM_HSUS | PFM_ALDN;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001410 }
1411
Jes Sorensenedbfd672014-05-16 10:05:09 +02001412 rtl8723au_write16(padapter, REG_APS_FSMCO, value16); /* 0x4802 */
Larry Fingerf7c92d22014-03-28 21:37:39 -05001413
Jes Sorensenedbfd672014-05-16 10:05:09 +02001414 rtl8723au_write8(padapter, REG_RSV_CTRL, 0x0e);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001415}
1416
1417/* HW Auto state machine */
Jes Sorensena5681f92014-05-16 10:04:48 +02001418int CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001419{
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +01001420 if (padapter->bSurpriseRemoved)
Roberta Dobrescu147e45d2014-10-26 23:30:07 +02001421 return _SUCCESS;
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +01001422
Larry Fingerf7c92d22014-03-28 21:37:39 -05001423 /* RF Off Sequence ==== */
Jes Sorensen38f36d82014-11-30 16:05:15 -05001424 _DisableRFAFEAndResetBB8192C(padapter);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001425
1426 /* ==== Reset digital sequence ====== */
Jes Sorensen441272e2014-11-30 16:05:17 -05001427 _ResetDigitalProcedure1_92C(padapter, false);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001428
1429 /* ==== Pull GPIO PIN to balance level and LED control ====== */
1430 _DisableGPIO(padapter);
1431
1432 /* ==== Disable analog sequence === */
1433 _DisableAnalog(padapter, false);
1434
1435 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1436 ("======> Card disable finished.\n"));
1437
Roberta Dobrescu147e45d2014-10-26 23:30:07 +02001438 return _SUCCESS;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001439}
1440
1441/* without HW Auto state machine */
Jes Sorensena5681f92014-05-16 10:04:48 +02001442int CardDisableWithoutHWSM(struct rtw_adapter *padapter)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001443{
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +01001444 if (padapter->bSurpriseRemoved)
Roberta Dobrescu147e45d2014-10-26 23:30:07 +02001445 return _SUCCESS;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001446
1447 /* RF Off Sequence ==== */
Jes Sorensen38f36d82014-11-30 16:05:15 -05001448 _DisableRFAFEAndResetBB8192C(padapter);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001449
1450 /* ==== Reset digital sequence ====== */
Jes Sorensen441272e2014-11-30 16:05:17 -05001451 _ResetDigitalProcedure1_92C(padapter, true);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001452
1453 /* ==== Pull GPIO PIN to balance level and LED control ====== */
1454 _DisableGPIO(padapter);
1455
1456 /* ==== Reset digital sequence ====== */
1457 _ResetDigitalProcedure2(padapter);
1458
1459 /* ==== Disable analog sequence === */
1460 _DisableAnalog(padapter, true);
1461
1462 /* RT_TRACE(COMP_INIT, DBG_LOUD,
1463 ("<====== Card Disable Without HWSM .\n")); */
Roberta Dobrescu147e45d2014-10-26 23:30:07 +02001464 return _SUCCESS;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001465}
1466
1467void Hal_InitPGData(struct rtw_adapter *padapter, u8 *PROMContent)
1468{
1469 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1470
Jes Sorensen315f9a22014-11-30 16:05:19 -05001471 if (!pEEPROM->bautoload_fail_flag) { /* autoload OK. */
Larry Fingerf7c92d22014-03-28 21:37:39 -05001472 if (!pEEPROM->EepromOrEfuse) {
1473 /* Read EFUSE real map to shadow. */
1474 EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI);
Jes Sorensen315f9a22014-11-30 16:05:19 -05001475 memcpy(PROMContent, pEEPROM->efuse_eeprom_data,
Larry Fingerf7c92d22014-03-28 21:37:39 -05001476 HWSET_MAX_SIZE);
1477 }
Jes Sorensen315f9a22014-11-30 16:05:19 -05001478 } else {
Larry Fingerf7c92d22014-03-28 21:37:39 -05001479 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,
1480 ("AutoLoad Fail reported from CR9346!!\n"));
Larry Fingerf7c92d22014-03-28 21:37:39 -05001481 /* update to default value 0xFF */
Jes Sorensen315f9a22014-11-30 16:05:19 -05001482 if (!pEEPROM->EepromOrEfuse)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001483 EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI);
Jes Sorensen315f9a22014-11-30 16:05:19 -05001484 memcpy(PROMContent, pEEPROM->efuse_eeprom_data,
Larry Fingerf7c92d22014-03-28 21:37:39 -05001485 HWSET_MAX_SIZE);
1486 }
1487}
1488
1489void Hal_EfuseParseIDCode(struct rtw_adapter *padapter, u8 *hwinfo)
1490{
1491 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1492/* struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); */
1493 u16 EEPROMId;
1494
1495 /* Checl 0x8129 again for making sure autoload status!! */
1496 EEPROMId = le16_to_cpu(*((u16 *) hwinfo));
1497 if (EEPROMId != RTL_EEPROM_ID) {
1498 DBG_8723A("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
1499 pEEPROM->bautoload_fail_flag = true;
1500 } else {
1501 pEEPROM->bautoload_fail_flag = false;
1502 }
1503
1504 RT_TRACE(_module_hal_init_c_, _drv_info_,
1505 ("EEPROM ID = 0x%04x\n", EEPROMId));
1506}
1507
1508static void Hal_EEValueCheck(u8 EEType, void *pInValue, void *pOutValue)
1509{
1510 switch (EEType) {
1511 case EETYPE_TX_PWR:
1512 {
1513 u8 *pIn, *pOut;
1514 pIn = (u8 *) pInValue;
1515 pOut = (u8 *) pOutValue;
Jes Sorensen3e3a1ad2014-05-21 09:37:28 +02001516 if (*pIn <= 63)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001517 *pOut = *pIn;
Jes Sorensen3e3a1ad2014-05-21 09:37:28 +02001518 else {
Larry Fingerf7c92d22014-03-28 21:37:39 -05001519 RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
1520 ("EETYPE_TX_PWR, value =%d is invalid, set "
1521 "to default = 0x%x\n",
1522 *pIn, EEPROM_Default_TxPowerLevel));
1523 *pOut = EEPROM_Default_TxPowerLevel;
1524 }
1525 }
1526 break;
1527 default:
1528 break;
1529 }
1530}
1531
1532static void
1533Hal_ReadPowerValueFromPROM_8723A(struct txpowerinfo *pwrInfo,
1534 u8 *PROMContent, bool AutoLoadFail)
1535{
1536 u32 rfPath, eeAddr, group, rfPathMax = 1;
1537
1538 memset(pwrInfo, 0, sizeof(*pwrInfo));
1539
1540 if (AutoLoadFail) {
1541 for (group = 0; group < MAX_CHNL_GROUP; group++) {
1542 for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
1543 pwrInfo->CCKIndex[rfPath][group] =
1544 EEPROM_Default_TxPowerLevel;
1545 pwrInfo->HT40_1SIndex[rfPath][group] =
1546 EEPROM_Default_TxPowerLevel;
1547 pwrInfo->HT40_2SIndexDiff[rfPath][group] =
1548 EEPROM_Default_HT40_2SDiff;
1549 pwrInfo->HT20IndexDiff[rfPath][group] =
1550 EEPROM_Default_HT20_Diff;
1551 pwrInfo->OFDMIndexDiff[rfPath][group] =
1552 EEPROM_Default_LegacyHTTxPowerDiff;
1553 pwrInfo->HT40MaxOffset[rfPath][group] =
1554 EEPROM_Default_HT40_PwrMaxOffset;
1555 pwrInfo->HT20MaxOffset[rfPath][group] =
1556 EEPROM_Default_HT20_PwrMaxOffset;
1557 }
1558 }
1559 pwrInfo->TSSI_A[0] = EEPROM_Default_TSSI;
1560 return;
1561 }
1562
1563 for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
1564 for (group = 0; group < MAX_CHNL_GROUP; group++) {
1565 eeAddr =
1566 EEPROM_CCK_TX_PWR_INX_8723A + (rfPath * 3) + group;
1567 /* pwrInfo->CCKIndex[rfPath][group] =
1568 PROMContent[eeAddr]; */
1569 Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr],
1570 &pwrInfo->CCKIndex[rfPath][group]);
1571 eeAddr = EEPROM_HT40_1S_TX_PWR_INX_8723A +
1572 (rfPath * 3) + group;
1573 /* pwrInfo->HT40_1SIndex[rfPath][group] =
1574 PROMContent[eeAddr]; */
1575 Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr],
1576 &pwrInfo->HT40_1SIndex[rfPath][group]);
1577 }
1578 }
1579
1580 for (group = 0; group < MAX_CHNL_GROUP; group++) {
1581 for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
1582 pwrInfo->HT40_2SIndexDiff[rfPath][group] = 0;
1583 pwrInfo->HT20IndexDiff[rfPath][group] =
1584 (PROMContent
1585 [EEPROM_HT20_TX_PWR_INX_DIFF_8723A +
1586 group] >> (rfPath * 4)) & 0xF;
1587 /* 4bit sign number to 8 bit sign number */
Jes Sorensenbc0d10c2014-05-16 10:03:49 +02001588 if (pwrInfo->HT20IndexDiff[rfPath][group] & BIT(3))
Larry Fingerf7c92d22014-03-28 21:37:39 -05001589 pwrInfo->HT20IndexDiff[rfPath][group] |= 0xF0;
1590
1591 pwrInfo->OFDMIndexDiff[rfPath][group] =
1592 (PROMContent[EEPROM_OFDM_TX_PWR_INX_DIFF_8723A +
1593 group] >> (rfPath * 4)) & 0xF;
1594
1595 pwrInfo->HT40MaxOffset[rfPath][group] =
1596 (PROMContent[EEPROM_HT40_MAX_PWR_OFFSET_8723A +
1597 group] >> (rfPath * 4)) & 0xF;
1598
1599 pwrInfo->HT20MaxOffset[rfPath][group] =
1600 (PROMContent[EEPROM_HT20_MAX_PWR_OFFSET_8723A +
1601 group] >> (rfPath * 4)) & 0xF;
1602 }
1603 }
1604
1605 pwrInfo->TSSI_A[0] = PROMContent[EEPROM_TSSI_A_8723A];
1606}
1607
1608static u8 Hal_GetChnlGroup(u8 chnl)
1609{
1610 u8 group = 0;
1611
1612 if (chnl < 3) /* Cjanel 1-3 */
1613 group = 0;
1614 else if (chnl < 9) /* Channel 4-9 */
1615 group = 1;
1616 else /* Channel 10-14 */
1617 group = 2;
1618
1619 return group;
1620}
1621
1622void
1623Hal_EfuseParsetxpowerinfo_8723A(struct rtw_adapter *padapter,
1624 u8 *PROMContent, bool AutoLoadFail)
1625{
1626 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1627 struct txpowerinfo pwrInfo;
1628 u8 rfPath, ch, group, rfPathMax = 1;
1629 u8 pwr, diff;
1630
1631 Hal_ReadPowerValueFromPROM_8723A(&pwrInfo, PROMContent, AutoLoadFail);
1632 for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
1633 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
1634 group = Hal_GetChnlGroup(ch);
1635
1636 pHalData->TxPwrLevelCck[rfPath][ch] =
1637 pwrInfo.CCKIndex[rfPath][group];
1638 pHalData->TxPwrLevelHT40_1S[rfPath][ch] =
1639 pwrInfo.HT40_1SIndex[rfPath][group];
1640
1641 pHalData->TxPwrHt20Diff[rfPath][ch] =
1642 pwrInfo.HT20IndexDiff[rfPath][group];
1643 pHalData->TxPwrLegacyHtDiff[rfPath][ch] =
1644 pwrInfo.OFDMIndexDiff[rfPath][group];
1645 pHalData->PwrGroupHT20[rfPath][ch] =
1646 pwrInfo.HT20MaxOffset[rfPath][group];
1647 pHalData->PwrGroupHT40[rfPath][ch] =
1648 pwrInfo.HT40MaxOffset[rfPath][group];
1649
1650 pwr = pwrInfo.HT40_1SIndex[rfPath][group];
1651 diff = pwrInfo.HT40_2SIndexDiff[rfPath][group];
1652
1653 pHalData->TxPwrLevelHT40_2S[rfPath][ch] =
1654 (pwr > diff) ? (pwr - diff) : 0;
1655 }
1656 }
1657 for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
1658 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
1659 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1660 ("RF(%u)-Ch(%u) [CCK / HT40_1S / HT40_2S] = "
1661 "[0x%x / 0x%x / 0x%x]\n",
1662 rfPath, ch,
1663 pHalData->TxPwrLevelCck[rfPath][ch],
1664 pHalData->TxPwrLevelHT40_1S[rfPath][ch],
1665 pHalData->TxPwrLevelHT40_2S[rfPath][ch]));
1666
1667 }
1668 }
1669 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
1670 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1671 ("RF-A Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
1672 pHalData->TxPwrHt20Diff[RF_PATH_A][ch],
1673 pHalData->TxPwrHt20Diff[RF_PATH_A][ch]));
1674 }
1675 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++)
1676 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1677 ("RF-A Legacy to Ht40 Diff[%u] = 0x%x\n", ch,
1678 pHalData->TxPwrLegacyHtDiff[RF_PATH_A][ch]));
1679 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
1680 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1681 ("RF-B Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
1682 pHalData->TxPwrHt20Diff[RF_PATH_B][ch],
1683 pHalData->TxPwrHt20Diff[RF_PATH_B][ch]));
1684 }
1685 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++)
1686 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1687 ("RF-B Legacy to HT40 Diff[%u] = 0x%x\n", ch,
1688 pHalData->TxPwrLegacyHtDiff[RF_PATH_B][ch]));
1689 if (!AutoLoadFail) {
1690 struct registry_priv *registry_par = &padapter->registrypriv;
1691 if (registry_par->regulatory_tid == 0xff) {
1692 if (PROMContent[RF_OPTION1_8723A] == 0xff)
1693 pHalData->EEPROMRegulatory = 0;
1694 else
1695 pHalData->EEPROMRegulatory =
1696 PROMContent[RF_OPTION1_8723A] & 0x7;
1697 } else {
1698 pHalData->EEPROMRegulatory =
1699 registry_par->regulatory_tid;
1700 }
1701 } else {
1702 pHalData->EEPROMRegulatory = 0;
1703 }
1704 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1705 ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory));
1706
1707 if (!AutoLoadFail)
1708 pHalData->bTXPowerDataReadFromEEPORM = true;
1709}
1710
1711void
1712Hal_EfuseParseBTCoexistInfo_8723A(struct rtw_adapter *padapter,
1713 u8 *hwinfo, bool AutoLoadFail)
1714{
1715 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1716 u8 tempval;
1717 u32 tmpu4;
1718
1719 if (!AutoLoadFail) {
Jes Sorensen050abc42014-05-16 10:05:08 +02001720 tmpu4 = rtl8723au_read32(padapter, REG_MULTI_FUNC_CTRL);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001721 if (tmpu4 & BT_FUNC_EN)
1722 pHalData->EEPROMBluetoothCoexist = 1;
1723 else
1724 pHalData->EEPROMBluetoothCoexist = 0;
1725 pHalData->EEPROMBluetoothType = BT_RTL8723A;
1726
1727 /* The following need to be checked with newer version of */
1728 /* eeprom spec */
1729 tempval = hwinfo[RF_OPTION4_8723A];
1730 pHalData->EEPROMBluetoothAntNum = (tempval & 0x1);
Aya Mahfouze1bc88f2015-03-04 07:34:07 +02001731 pHalData->EEPROMBluetoothAntIsolation = (tempval & 0x10) >> 4;
1732 pHalData->EEPROMBluetoothRadioShared = (tempval & 0x20) >> 5;
Larry Fingerf7c92d22014-03-28 21:37:39 -05001733 } else {
1734 pHalData->EEPROMBluetoothCoexist = 0;
1735 pHalData->EEPROMBluetoothType = BT_RTL8723A;
1736 pHalData->EEPROMBluetoothAntNum = Ant_x2;
1737 pHalData->EEPROMBluetoothAntIsolation = 0;
1738 pHalData->EEPROMBluetoothRadioShared = BT_Radio_Shared;
1739 }
Jes Sorensen9b2d4ae2014-05-25 22:43:44 +02001740
1741 rtl8723a_BT_init_hal_vars(padapter);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001742}
1743
1744void
1745Hal_EfuseParseEEPROMVer(struct rtw_adapter *padapter,
1746 u8 *hwinfo, bool AutoLoadFail)
1747{
1748 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1749
1750 if (!AutoLoadFail)
1751 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723A];
1752 else
1753 pHalData->EEPROMVersion = 1;
1754 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1755 ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
1756 pHalData->EEPROMVersion));
1757}
1758
1759void
1760rtl8723a_EfuseParseChnlPlan(struct rtw_adapter *padapter,
1761 u8 *hwinfo, bool AutoLoadFail)
1762{
1763 padapter->mlmepriv.ChannelPlan =
1764 hal_com_get_channel_plan23a(padapter, hwinfo ?
1765 hwinfo[EEPROM_ChannelPlan_8723A]:0xFF,
1766 padapter->registrypriv.channel_plan,
1767 RT_CHANNEL_DOMAIN_WORLD_WIDE_13,
1768 AutoLoadFail);
1769
1770 DBG_8723A("mlmepriv.ChannelPlan = 0x%02x\n",
1771 padapter->mlmepriv.ChannelPlan);
1772}
1773
1774void
1775Hal_EfuseParseCustomerID(struct rtw_adapter *padapter,
1776 u8 *hwinfo, bool AutoLoadFail)
1777{
1778 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1779
1780 if (!AutoLoadFail) {
1781 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723A];
1782 pHalData->EEPROMSubCustomerID =
1783 hwinfo[EEPROM_SubCustomID_8723A];
1784 } else {
1785 pHalData->EEPROMCustomerID = 0;
1786 pHalData->EEPROMSubCustomerID = 0;
1787 }
1788 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1789 ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID));
1790 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1791 ("EEPROM SubCustomer ID: 0x%02x\n",
1792 pHalData->EEPROMSubCustomerID));
1793}
1794
1795void
1796Hal_EfuseParseAntennaDiversity(struct rtw_adapter *padapter,
1797 u8 *hwinfo, bool AutoLoadFail)
1798{
1799}
1800
1801void
1802Hal_EfuseParseRateIndicationOption(struct rtw_adapter *padapter,
1803 u8 *hwinfo, bool AutoLoadFail)
1804{
1805}
1806
1807void
1808Hal_EfuseParseXtal_8723A(struct rtw_adapter *pAdapter,
1809 u8 *hwinfo, u8 AutoLoadFail)
1810{
1811 struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
1812
1813 if (!AutoLoadFail) {
1814 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_K_8723A];
1815 if (pHalData->CrystalCap == 0xFF)
1816 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
1817 } else {
1818 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
1819 }
1820 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1821 ("%s: CrystalCap = 0x%2x\n", __func__,
1822 pHalData->CrystalCap));
1823}
1824
1825void
1826Hal_EfuseParseThermalMeter_8723A(struct rtw_adapter *padapter,
Jes Sorensena5681f92014-05-16 10:04:48 +02001827 u8 *PROMContent, bool AutoloadFail)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001828{
1829 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1830
1831 /* */
1832 /* ThermalMeter from EEPROM */
1833 /* */
Roberta Dobrescu08551cb2014-10-26 23:30:05 +02001834 if (!AutoloadFail)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001835 pHalData->EEPROMThermalMeter =
1836 PROMContent[EEPROM_THERMAL_METER_8723A];
1837 else
1838 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
1839
Roberta Dobrescu08551cb2014-10-26 23:30:05 +02001840 if ((pHalData->EEPROMThermalMeter == 0xff) || AutoloadFail) {
Larry Fingerf7c92d22014-03-28 21:37:39 -05001841 pHalData->bAPKThermalMeterIgnore = true;
1842 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
1843 }
1844
1845 DBG_8723A("%s: ThermalMeter = 0x%x\n", __func__,
1846 pHalData->EEPROMThermalMeter);
1847}
1848
Larry Fingerf7c92d22014-03-28 21:37:39 -05001849static void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc)
1850{
1851 u16 *usPtr = (u16 *) ptxdesc;
1852 u32 count = 16; /* (32 bytes / 2 bytes per XOR) => 16 times */
1853 u32 index;
1854 u16 checksum = 0;
1855
1856 /* Clear first */
1857 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
1858
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +01001859 for (index = 0; index < count; index++)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001860 checksum ^= le16_to_cpu(*(usPtr + index));
Larry Fingerf7c92d22014-03-28 21:37:39 -05001861
1862 ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
1863}
1864
Larry Fingerf7c92d22014-03-28 21:37:39 -05001865/*
1866 * Description: In normal chip, we should send some packet to Hw which
1867 * will be used by Fw in FW LPS mode. The function is to fill the Tx
1868 * descriptor of this packets, then
1869 */
1870/* Fw can tell Hw to send these packet derectly. */
1871/* Added by tynli. 2009.10.15. */
1872/* */
1873void rtl8723a_fill_fake_txdesc(struct rtw_adapter *padapter, u8 *pDesc,
1874 u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull)
1875{
1876 struct tx_desc *ptxdesc;
1877
1878 /* Clear all status */
1879 ptxdesc = (struct tx_desc *)pDesc;
1880 memset(pDesc, 0, TXDESC_SIZE);
1881
1882 /* offset 0 */
1883 /* own, bFirstSeg, bLastSeg; */
1884 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
1885
1886 /* 32 bytes for TX Desc */
1887 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) <<
1888 OFFSET_SHT) & 0x00ff0000);
1889
1890 /* Buffer size + command header */
1891 ptxdesc->txdw0 |= cpu_to_le32(BufferLen & 0x0000ffff);
1892
1893 /* offset 4 */
1894 /* Fixed queue of Mgnt queue */
1895 ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT << QSEL_SHT) & 0x00001f00);
1896
1897 /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed
1898 to error vlaue by Hw. */
1899 if (IsPsPoll) {
1900 ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
1901 } else {
1902 /* Hw set sequence number */
1903 ptxdesc->txdw4 |= cpu_to_le32(BIT(7));
1904 /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
1905 ptxdesc->txdw3 |= cpu_to_le32((8 << 28));
1906 }
1907
Daniele Alessandrellidd03eed2015-02-22 20:28:44 +01001908 if (true == IsBTQosNull)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001909 ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /* BT NULL */
Larry Fingerf7c92d22014-03-28 21:37:39 -05001910
1911 /* offset 16 */
1912 ptxdesc->txdw4 |= cpu_to_le32(BIT(8)); /* driver uses rate */
1913
1914 /* USB interface drop packet if the checksum of descriptor isn't
1915 correct. */
1916 /* Using this checksum can let hardware recovery from packet bulk
1917 out error (e.g. Cancel URC, Bulk out error.). */
1918 rtl8723a_cal_txdesc_chksum(ptxdesc);
1919}
1920
Jes Sorensendbdcd362014-04-09 23:20:17 +02001921void hw_var_set_opmode(struct rtw_adapter *padapter, u8 mode)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001922{
1923 u8 val8;
1924
Jes Sorensen6ec26272014-07-17 22:59:46 +02001925 if (mode == MSR_INFRA || mode == MSR_NOLINK) {
Larry Fingerf7c92d22014-03-28 21:37:39 -05001926 StopTxBeacon(padapter);
1927
1928 /* disable atim wnd */
1929 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM;
1930 SetBcnCtrlReg23a(padapter, val8, ~val8);
Jes Sorensen6ec26272014-07-17 22:59:46 +02001931 } else if (mode == MSR_ADHOC) {
Larry Fingerf7c92d22014-03-28 21:37:39 -05001932 ResumeTxBeacon(padapter);
1933
1934 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB;
1935 SetBcnCtrlReg23a(padapter, val8, ~val8);
Jes Sorensen6ec26272014-07-17 22:59:46 +02001936 } else if (mode == MSR_AP) {
Larry Fingerf7c92d22014-03-28 21:37:39 -05001937 /* add NULL Data and BT NULL Data Packets to FW RSVD Page */
1938 rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(padapter);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001939
1940 ResumeTxBeacon(padapter);
1941
1942 val8 = DIS_TSF_UDT | DIS_BCNQ_SUB;
1943 SetBcnCtrlReg23a(padapter, val8, ~val8);
1944
1945 /* Set RCR */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001946 /* rtl8723au_write32(padapter, REG_RCR, 0x70002a8e);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001947 CBSSID_DATA must set to 0 */
1948 /* CBSSID_DATA must set to 0 */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001949 rtl8723au_write32(padapter, REG_RCR, 0x7000228e);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001950 /* enable to rx data frame */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001951 rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001952 /* enable to rx ps-poll */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001953 rtl8723au_write16(padapter, REG_RXFLTMAP1, 0x0400);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001954
1955 /* Beacon Control related register for first time */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001956 /* 2ms */
1957 rtl8723au_write8(padapter, REG_BCNDMATIM, 0x02);
1958 /* 5ms */
1959 rtl8723au_write8(padapter, REG_DRVERLYINT, 0x05);
1960 /* 10ms for port0 */
1961 rtl8723au_write8(padapter, REG_ATIMWND, 0x0a);
1962 rtl8723au_write16(padapter, REG_BCNTCFG, 0x00);
1963 rtl8723au_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001964 /* +32767 (~32ms) */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001965 rtl8723au_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001966
1967 /* reset TSF */
Jes Sorensenedbfd672014-05-16 10:05:09 +02001968 rtl8723au_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
Larry Fingerf7c92d22014-03-28 21:37:39 -05001969
1970 /* enable BCN Function */
1971 /* don't enable update TSF (due to TSF update when
1972 beacon/probe rsp are received) */
1973 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION |
1974 EN_TXBCN_RPT | DIS_BCNQ_SUB;
1975 SetBcnCtrlReg23a(padapter, val8, ~val8);
1976 }
1977
Jes Sorensen050abc42014-05-16 10:05:08 +02001978 val8 = rtl8723au_read8(padapter, MSR);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001979 val8 = (val8 & 0xC) | mode;
Jes Sorensenedbfd672014-05-16 10:05:09 +02001980 rtl8723au_write8(padapter, MSR, val8);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001981}
1982
Jes Sorensen3c5660e2014-04-09 23:20:19 +02001983void hw_var_set_macaddr(struct rtw_adapter *padapter, u8 *val)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001984{
1985 u8 idx = 0;
1986 u32 reg_macid;
1987
1988 reg_macid = REG_MACID;
1989
1990 for (idx = 0; idx < 6; idx++)
Jes Sorensenedbfd672014-05-16 10:05:09 +02001991 rtl8723au_write8(padapter, (reg_macid + idx), val[idx]);
Larry Fingerf7c92d22014-03-28 21:37:39 -05001992}
1993
Jes Sorensen38dd10b2014-04-09 23:20:20 +02001994void hw_var_set_bssid(struct rtw_adapter *padapter, u8 *val)
Larry Fingerf7c92d22014-03-28 21:37:39 -05001995{
1996 u8 idx = 0;
1997 u32 reg_bssid;
1998
1999 reg_bssid = REG_BSSID;
2000
2001 for (idx = 0; idx < 6; idx++)
Jes Sorensenedbfd672014-05-16 10:05:09 +02002002 rtl8723au_write8(padapter, (reg_bssid + idx), val[idx]);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002003}
2004
Jes Sorensen763b4242014-04-09 23:20:14 +02002005void hw_var_set_correct_tsf(struct rtw_adapter *padapter)
Larry Fingerf7c92d22014-03-28 21:37:39 -05002006{
2007 u64 tsf;
2008 u32 reg_tsftr;
2009 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2010 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2011
2012 /* tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue %
2013 (pmlmeinfo->bcn_interval*1024)) - 1024; us */
2014 tsf = pmlmeext->TSFValue -
Jes Sorensenf4337aa2014-04-09 23:21:19 +02002015 do_div(pmlmeext->TSFValue,
2016 (pmlmeinfo->bcn_interval * 1024)) - 1024; /* us */
Larry Fingerf7c92d22014-03-28 21:37:39 -05002017
Jes Sorensen6ec26272014-07-17 22:59:46 +02002018 if (((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
2019 ((pmlmeinfo->state & 0x03) == MSR_AP)) {
Larry Fingerf7c92d22014-03-28 21:37:39 -05002020 /* pHalData->RegTxPause |= STOP_BCNQ;BIT(6) */
Jes Sorensenedbfd672014-05-16 10:05:09 +02002021 /* rtl8723au_write8(padapter, REG_TXPAUSE,
Jes Sorensen050abc42014-05-16 10:05:08 +02002022 (rtl8723au_read8(Adapter, REG_TXPAUSE)|BIT(6))); */
Larry Fingerf7c92d22014-03-28 21:37:39 -05002023 StopTxBeacon(padapter);
2024 }
2025
2026 reg_tsftr = REG_TSFTR;
2027
2028 /* disable related TSF function */
2029 SetBcnCtrlReg23a(padapter, 0, EN_BCN_FUNCTION);
2030
Jes Sorensenedbfd672014-05-16 10:05:09 +02002031 rtl8723au_write32(padapter, reg_tsftr, tsf);
2032 rtl8723au_write32(padapter, reg_tsftr + 4, tsf >> 32);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002033
2034 /* enable related TSF function */
2035 SetBcnCtrlReg23a(padapter, EN_BCN_FUNCTION, 0);
2036
Jes Sorensen6ec26272014-07-17 22:59:46 +02002037 if (((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
2038 ((pmlmeinfo->state & 0x03) == MSR_AP))
Larry Fingerf7c92d22014-03-28 21:37:39 -05002039 ResumeTxBeacon(padapter);
2040}
2041
Jes Sorensen763b4242014-04-09 23:20:14 +02002042void hw_var_set_mlme_disconnect(struct rtw_adapter *padapter)
Larry Fingerf7c92d22014-03-28 21:37:39 -05002043{
2044 /* reject all data frames */
Jes Sorensenedbfd672014-05-16 10:05:09 +02002045 rtl8723au_write16(padapter, REG_RXFLTMAP2, 0);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002046
2047 /* reset TSF */
Jes Sorensenedbfd672014-05-16 10:05:09 +02002048 rtl8723au_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
Larry Fingerf7c92d22014-03-28 21:37:39 -05002049
2050 /* disable update TSF */
2051 SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0);
2052}
2053
Jes Sorensenea0cd732014-04-09 23:20:22 +02002054void hw_var_set_mlme_join(struct rtw_adapter *padapter, u8 type)
Larry Fingerf7c92d22014-03-28 21:37:39 -05002055{
2056 u8 RetryLimit = 0x30;
2057
2058 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
2059 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2060
2061 if (type == 0) { /* prepare to join */
2062 u32 v32;
2063
2064 /* enable to rx data frame.Accept all data frame */
Jes Sorensenedbfd672014-05-16 10:05:09 +02002065 /* rtl8723au_write32(padapter, REG_RCR,
Jes Sorensen050abc42014-05-16 10:05:08 +02002066 rtl8723au_read32(padapter, REG_RCR)|RCR_ADF); */
Jes Sorensenedbfd672014-05-16 10:05:09 +02002067 rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002068
Jes Sorensen050abc42014-05-16 10:05:08 +02002069 v32 = rtl8723au_read32(padapter, REG_RCR);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002070 v32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
Jes Sorensenedbfd672014-05-16 10:05:09 +02002071 rtl8723au_write32(padapter, REG_RCR, v32);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002072
2073 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
2074 RetryLimit =
2075 (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
2076 else /* Ad-hoc Mode */
2077 RetryLimit = 0x7;
2078 } else if (type == 1) { /* joinbss_event callback when join res < 0 */
2079 /* config RCR to receive different BSSID & not to
2080 receive data frame during linking */
Jes Sorensenedbfd672014-05-16 10:05:09 +02002081 rtl8723au_write16(padapter, REG_RXFLTMAP2, 0);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002082 } else if (type == 2) { /* sta add event callback */
2083 /* enable update TSF */
2084 SetBcnCtrlReg23a(padapter, 0, DIS_TSF_UDT);
2085
2086 if (check_fwstate(pmlmepriv,
2087 WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
2088 /* fixed beacon issue for 8191su........... */
Jes Sorensenedbfd672014-05-16 10:05:09 +02002089 rtl8723au_write8(padapter, 0x542, 0x02);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002090 RetryLimit = 0x7;
2091 }
2092 }
2093
Jes Sorensenedbfd672014-05-16 10:05:09 +02002094 rtl8723au_write16(padapter, REG_RL,
2095 RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit <<
2096 RETRY_LIMIT_LONG_SHIFT);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002097
Larry Fingerf7c92d22014-03-28 21:37:39 -05002098 switch (type) {
2099 case 0:
2100 /* prepare to join */
Jes Sorensenc814d4d2014-05-25 22:43:42 +02002101 rtl8723a_BT_wifiassociate_notify(padapter, true);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002102 break;
2103 case 1:
2104 /* joinbss_event callback when join res < 0 */
Jes Sorensenc814d4d2014-05-25 22:43:42 +02002105 rtl8723a_BT_wifiassociate_notify(padapter, false);
Larry Fingerf7c92d22014-03-28 21:37:39 -05002106 break;
2107 case 2:
2108 /* sta add event callback */
2109/* BT_WifiMediaStatusNotify(padapter, RT_MEDIA_CONNECT); */
2110 break;
2111 }
Larry Fingerf7c92d22014-03-28 21:37:39 -05002112}