1
2
3
4
5
6
7
8
9
10
11
12
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
23static void _FWDownloadEnable(struct rtw_adapter *padapter, bool enable)
24{
25 u8 tmp;
26
27 if (enable) {
28
29 tmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
30 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, tmp | 0x04);
31
32
33 tmp = rtw_read8(padapter, REG_MCUFWDL);
34 rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
35
36
37 tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
38 rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
39 } else {
40
41 tmp = rtw_read8(padapter, REG_MCUFWDL);
42 rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
43
44
45 rtw_write8(padapter, REG_MCUFWDL + 1, 0x00);
46 }
47}
48
49static int _BlockWrite(struct rtw_adapter *padapter, void *buffer, u32 buffSize)
50{
51 int ret = _SUCCESS;
52
53 u32 blockSize_p1 = 4;
54
55 u32 blockSize_p2 = 8;
56
57 u32 blockSize_p3 = 1;
58 u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
59 u32 remainSize_p1 = 0, remainSize_p2 = 0;
60 u8 *bufferPtr = (u8 *) buffer;
61 u32 i = 0, offset = 0;
62
63 blockSize_p1 = 254;
64
65
66 blockCount_p1 = buffSize / blockSize_p1;
67 remainSize_p1 = buffSize % blockSize_p1;
68
69 if (blockCount_p1) {
70 RT_TRACE(_module_hal_init_c_, _drv_notice_,
71 ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) "
72 "blockCount_p1(%d) remainSize_p1(%d)\n",
73 buffSize, blockSize_p1, blockCount_p1,
74 remainSize_p1));
75 }
76
77 for (i = 0; i < blockCount_p1; i++) {
78 ret = rtw_writeN(padapter,
79 (FW_8723A_START_ADDRESS + i * blockSize_p1),
80 blockSize_p1, (bufferPtr + i * blockSize_p1));
81 if (ret == _FAIL)
82 goto exit;
83 }
84
85
86 if (remainSize_p1) {
87 offset = blockCount_p1 * blockSize_p1;
88
89 blockCount_p2 = remainSize_p1 / blockSize_p2;
90 remainSize_p2 = remainSize_p1 % blockSize_p2;
91
92 if (blockCount_p2) {
93 RT_TRACE(_module_hal_init_c_, _drv_notice_,
94 ("_BlockWrite: [P2] buffSize_p2(%d) "
95 "blockSize_p2(%d) blockCount_p2(%d) "
96 "remainSize_p2(%d)\n",
97 (buffSize - offset), blockSize_p2,
98 blockCount_p2, remainSize_p2));
99 }
100
101 for (i = 0; i < blockCount_p2; i++) {
102 ret = rtw_writeN(padapter,
103 (FW_8723A_START_ADDRESS + offset +
104 i * blockSize_p2), blockSize_p2,
105 (bufferPtr + offset +
106 i * blockSize_p2));
107
108 if (ret == _FAIL)
109 goto exit;
110 }
111 }
112
113
114 if (remainSize_p2) {
115 offset = (blockCount_p1 * blockSize_p1) +
116 (blockCount_p2 * blockSize_p2);
117
118 blockCount_p3 = remainSize_p2 / blockSize_p3;
119
120 RT_TRACE(_module_hal_init_c_, _drv_notice_,
121 ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) "
122 "blockCount_p3(%d)\n",
123 (buffSize - offset), blockSize_p3, blockCount_p3));
124
125 for (i = 0; i < blockCount_p3; i++) {
126 ret = rtw_write8(padapter,
127 (FW_8723A_START_ADDRESS + offset + i),
128 *(bufferPtr + offset + i));
129
130 if (ret == _FAIL)
131 goto exit;
132 }
133 }
134
135exit:
136 return ret;
137}
138
139static int
140_PageWrite(struct rtw_adapter *padapter, u32 page, void *buffer, u32 size)
141{
142 u8 value8;
143 u8 u8Page = (u8) (page & 0x07);
144
145 value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
146 rtw_write8(padapter, REG_MCUFWDL + 2, value8);
147
148 return _BlockWrite(padapter, buffer, size);
149}
150
151static int _WriteFW(struct rtw_adapter *padapter, void *buffer, u32 size)
152{
153
154
155
156 int ret = _SUCCESS;
157 u32 pageNums, remainSize;
158 u32 page, offset;
159 u8 *bufferPtr = (u8 *) buffer;
160
161 pageNums = size / MAX_PAGE_SIZE;
162
163
164 remainSize = size % MAX_PAGE_SIZE;
165
166 for (page = 0; page < pageNums; page++) {
167 offset = page * MAX_PAGE_SIZE;
168 ret = _PageWrite(padapter, page, bufferPtr + offset,
169 MAX_PAGE_SIZE);
170
171 if (ret == _FAIL)
172 goto exit;
173 }
174 if (remainSize) {
175 offset = pageNums * MAX_PAGE_SIZE;
176 page = pageNums;
177 ret = _PageWrite(padapter, page, bufferPtr + offset,
178 remainSize);
179
180 if (ret == _FAIL)
181 goto exit;
182 }
183 RT_TRACE(_module_hal_init_c_, _drv_info_,
184 ("_WriteFW Done- for Normal chip.\n"));
185
186exit:
187 return ret;
188}
189
190static s32 _FWFreeToGo(struct rtw_adapter *padapter)
191{
192 u32 counter = 0;
193 u32 value32;
194
195
196 do {
197 value32 = rtw_read32(padapter, REG_MCUFWDL);
198 if (value32 & FWDL_ChkSum_rpt)
199 break;
200 } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
201
202 if (counter >= POLLING_READY_TIMEOUT_COUNT) {
203 RT_TRACE(_module_hal_init_c_, _drv_err_,
204 ("%s: chksum report fail! REG_MCUFWDL:0x%08x\n",
205 __func__, value32));
206 return _FAIL;
207 }
208 RT_TRACE(_module_hal_init_c_, _drv_info_,
209 ("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__,
210 value32));
211
212 value32 = rtw_read32(padapter, REG_MCUFWDL);
213 value32 |= MCUFWDL_RDY;
214 value32 &= ~WINTINI_RDY;
215 rtw_write32(padapter, REG_MCUFWDL, value32);
216
217
218 counter = 0;
219 do {
220 value32 = rtw_read32(padapter, REG_MCUFWDL);
221 if (value32 & WINTINI_RDY) {
222 RT_TRACE(_module_hal_init_c_, _drv_info_,
223 ("%s: Polling FW ready success!! "
224 "REG_MCUFWDL:0x%08x\n",
225 __func__, value32));
226 return _SUCCESS;
227 }
228 udelay(5);
229 } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
230
231 RT_TRACE(_module_hal_init_c_, _drv_err_,
232 ("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n",
233 __func__, value32));
234 return _FAIL;
235}
236
237#define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
238
239void rtl8723a_FirmwareSelfReset(struct rtw_adapter *padapter)
240{
241 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
242 u8 u1bTmp;
243 u8 Delay = 100;
244
245 if (!(IS_FW_81xxC(padapter) &&
246 ((pHalData->FirmwareVersion < 0x21) ||
247 (pHalData->FirmwareVersion == 0x21 &&
248 pHalData->FirmwareSubVersion < 0x01)))) {
249
250
251 rtw_write8(padapter, REG_HMETFR + 3, 0x20);
252
253 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
254 while (u1bTmp & BIT2) {
255 Delay--;
256 if (Delay == 0)
257 break;
258 udelay(50);
259 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
260 }
261 RT_TRACE(_module_hal_init_c_, _drv_info_,
262 ("-%s: 8051 reset success (%d)\n", __func__,
263 Delay));
264
265 if ((Delay == 0)) {
266
267 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
268 rtw_write8(padapter, REG_SYS_FUNC_EN + 1,
269 u1bTmp & (~BIT2));
270 }
271 }
272}
273
274
275
276
277
278
279s32 rtl8723a_FirmwareDownload(struct rtw_adapter *padapter)
280{
281 s32 rtStatus = _SUCCESS;
282 u8 writeFW_retry = 0;
283 unsigned long fwdl_start_time;
284 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
285 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
286 struct device *device = dvobj_to_dev(dvobj);
287 struct rt_8723a_firmware_hdr *pFwHdr = NULL;
288 const struct firmware *fw;
289 char *fw_name;
290 u8 *firmware_buf = NULL;
291 u8 *buf;
292 int fw_size;
293 static int log_version;
294
295 RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__));
296
297 if (IS_8723A_A_CUT(pHalData->VersionID)) {
298 fw_name = "rtlwifi/rtl8723aufw.bin";
299 RT_TRACE(_module_hal_init_c_, _drv_info_,
300 ("rtl8723a_FirmwareDownload: R8723FwImageArray_UMC "
301 "for RTL8723A A CUT\n"));
302 } else if (IS_8723A_B_CUT(pHalData->VersionID)) {
303
304 if (padapter->registrypriv.wifi_spec == 1) {
305 fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin";
306 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithoutBT for "
307 "RTL8723A B CUT\n");
308 } else {
309#ifdef CONFIG_8723AU_BT_COEXIST
310 fw_name = "rtlwifi/rtl8723aufw_B.bin";
311 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithBT for "
312 "RTL8723A B CUT\n");
313#else
314 fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin";
315 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithoutBT for "
316 "RTL8723A B CUT\n");
317#endif
318 }
319 } else {
320
321
322 RT_TRACE(_module_hal_init_c_, _drv_err_,
323 ("%s: unknow version!\n", __func__));
324 rtStatus = _FAIL;
325 goto Exit;
326 }
327
328 pr_info("rtl8723au: Loading firmware %s\n", fw_name);
329 if (request_firmware(&fw, fw_name, device)) {
330 pr_err("rtl8723au: request_firmware load failed\n");
331 rtStatus = _FAIL;
332 goto Exit;
333 }
334 if (!fw) {
335 pr_err("rtl8723au: Firmware %s not available\n", fw_name);
336 rtStatus = _FAIL;
337 goto Exit;
338 }
339 firmware_buf = kzalloc(fw->size, GFP_KERNEL);
340 if (!firmware_buf) {
341 rtStatus = _FAIL;
342 goto Exit;
343 }
344 memcpy(firmware_buf, fw->data, fw->size);
345 buf = firmware_buf;
346 fw_size = fw->size;
347 release_firmware(fw);
348
349
350 pFwHdr = (struct rt_8723a_firmware_hdr *)firmware_buf;
351
352 pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version);
353 pHalData->FirmwareSubVersion = pFwHdr->Subversion;
354 pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
355
356 DBG_8723A("%s: fw_ver =%d fw_subver =%d sig = 0x%x\n",
357 __func__, pHalData->FirmwareVersion,
358 pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
359
360 if (!log_version++)
361 pr_info("%sFirmware Version %d, SubVersion %d, Signature "
362 "0x%x\n", DRIVER_PREFIX, pHalData->FirmwareVersion,
363 pHalData->FirmwareSubVersion,
364 pHalData->FirmwareSignature);
365
366 if (IS_FW_HEADER_EXIST(pFwHdr)) {
367
368 buf = buf + 32;
369 fw_size = fw_size - 32;
370 }
371
372
373
374
375 if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) {
376
377 rtl8723a_FirmwareSelfReset(padapter);
378 rtw_write8(padapter, REG_MCUFWDL, 0x00);
379 }
380
381 _FWDownloadEnable(padapter, true);
382 fwdl_start_time = jiffies;
383 while (1) {
384
385 rtw_write8(padapter, REG_MCUFWDL,
386 rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
387
388 rtStatus = _WriteFW(padapter, buf, fw_size);
389
390 if (rtStatus == _SUCCESS ||
391 (jiffies_to_msecs(jiffies - fwdl_start_time) > 500 &&
392 writeFW_retry++ >= 3))
393 break;
394
395 DBG_8723A("%s writeFW_retry:%u, time after fwdl_start_time:"
396 "%ums\n", __func__, writeFW_retry,
397 jiffies_to_msecs(jiffies - fwdl_start_time));
398 }
399 _FWDownloadEnable(padapter, false);
400 if (_SUCCESS != rtStatus) {
401 DBG_8723A("DL Firmware failed!\n");
402 goto Exit;
403 }
404
405 rtStatus = _FWFreeToGo(padapter);
406 if (_SUCCESS != rtStatus) {
407 RT_TRACE(_module_hal_init_c_, _drv_err_,
408 ("DL Firmware failed!\n"));
409 goto Exit;
410 }
411 RT_TRACE(_module_hal_init_c_, _drv_info_,
412 ("Firmware is ready to run!\n"));
413
414Exit:
415 kfree(firmware_buf);
416 return rtStatus;
417}
418
419void rtl8723a_InitializeFirmwareVars(struct rtw_adapter *padapter)
420{
421 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
422
423
424 padapter->pwrctrlpriv.bFwCurrentInPSMode = false;
425
426
427 pHalData->LastHMEBoxNum = 0;
428}
429
430static void rtl8723a_free_hal_data(struct rtw_adapter *padapter)
431{
432
433 kfree(padapter->HalData);
434 padapter->HalData = NULL;
435
436}
437
438
439
440
441static u8
442hal_EfuseSwitchToBank(struct rtw_adapter *padapter, u8 bank)
443{
444 u8 bRet = false;
445 u32 value32 = 0;
446
447 DBG_8723A("%s: Efuse switch bank to %d\n", __func__, bank);
448 value32 = rtw_read32(padapter, EFUSE_TEST);
449 bRet = true;
450 switch (bank) {
451 case 0:
452 value32 = (value32 & ~EFUSE_SEL_MASK) |
453 EFUSE_SEL(EFUSE_WIFI_SEL_0);
454 break;
455 case 1:
456 value32 = (value32 & ~EFUSE_SEL_MASK) |
457 EFUSE_SEL(EFUSE_BT_SEL_0);
458 break;
459 case 2:
460 value32 = (value32 & ~EFUSE_SEL_MASK) |
461 EFUSE_SEL(EFUSE_BT_SEL_1);
462 break;
463 case 3:
464 value32 = (value32 & ~EFUSE_SEL_MASK) |
465 EFUSE_SEL(EFUSE_BT_SEL_2);
466 break;
467 default:
468 value32 = (value32 & ~EFUSE_SEL_MASK) |
469 EFUSE_SEL(EFUSE_WIFI_SEL_0);
470 bRet = false;
471 break;
472 }
473 rtw_write32(padapter, EFUSE_TEST, value32);
474
475 return bRet;
476}
477
478static void
479Hal_GetEfuseDefinition(struct rtw_adapter *padapter,
480 u8 efuseType, u8 type, void *pOut)
481{
482 u8 *pu1Tmp;
483 u16 *pu2Tmp;
484 u8 *pMax_section;
485
486 switch (type) {
487 case TYPE_EFUSE_MAX_SECTION:
488 pMax_section = (u8 *) pOut;
489
490 if (efuseType == EFUSE_WIFI)
491 *pMax_section = EFUSE_MAX_SECTION_8723A;
492 else
493 *pMax_section = EFUSE_BT_MAX_SECTION;
494 break;
495
496 case TYPE_EFUSE_REAL_CONTENT_LEN:
497 pu2Tmp = (u16 *) pOut;
498
499 if (efuseType == EFUSE_WIFI)
500 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
501 else
502 *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
503 break;
504
505 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
506 pu2Tmp = (u16 *) pOut;
507
508 if (efuseType == EFUSE_WIFI)
509 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A -
510 EFUSE_OOB_PROTECT_BYTES);
511 else
512 *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN -
513 EFUSE_PROTECT_BYTES_BANK);
514 break;
515
516 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
517 pu2Tmp = (u16 *) pOut;
518
519 if (efuseType == EFUSE_WIFI)
520 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A -
521 EFUSE_OOB_PROTECT_BYTES);
522 else
523 *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN -
524 (EFUSE_PROTECT_BYTES_BANK * 3));
525 break;
526
527 case TYPE_EFUSE_MAP_LEN:
528 pu2Tmp = (u16 *) pOut;
529
530 if (efuseType == EFUSE_WIFI)
531 *pu2Tmp = EFUSE_MAP_LEN_8723A;
532 else
533 *pu2Tmp = EFUSE_BT_MAP_LEN;
534 break;
535
536 case TYPE_EFUSE_PROTECT_BYTES_BANK:
537 pu1Tmp = (u8 *) pOut;
538
539 if (efuseType == EFUSE_WIFI)
540 *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
541 else
542 *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
543 break;
544
545 case TYPE_EFUSE_CONTENT_LEN_BANK:
546 pu2Tmp = (u16 *) pOut;
547
548 if (efuseType == EFUSE_WIFI)
549 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
550 else
551 *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
552 break;
553
554 default:
555 pu1Tmp = (u8 *) pOut;
556 *pu1Tmp = 0;
557 break;
558 }
559}
560
561#define VOLTAGE_V25 0x03
562#define LDOE25_SHIFT 28
563
564static void
565Hal_EfusePowerSwitch(struct rtw_adapter *padapter, u8 bWrite, u8 PwrState)
566{
567 u8 tempval;
568 u16 tmpV16;
569
570 if (PwrState == true) {
571 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
572
573
574
575 tmpV16 = rtw_read16(padapter, REG_SYS_ISO_CTRL);
576 if (!(tmpV16 & PWC_EV12V)) {
577 tmpV16 |= PWC_EV12V;
578 rtw_write16(padapter, REG_SYS_ISO_CTRL, tmpV16);
579 }
580
581 tmpV16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
582 if (!(tmpV16 & FEN_ELDR)) {
583 tmpV16 |= FEN_ELDR;
584 rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
585 }
586
587
588
589 tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
590 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
591 tmpV16 |= (LOADER_CLK_EN | ANA8M);
592 rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
593 }
594
595 if (bWrite == true) {
596
597 tempval = rtw_read8(padapter, EFUSE_TEST + 3);
598 tempval &= 0x0F;
599 tempval |= (VOLTAGE_V25 << 4);
600 rtw_write8(padapter, EFUSE_TEST + 3, (tempval | 0x80));
601 }
602 } else {
603 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
604
605 if (bWrite == true) {
606
607 tempval = rtw_read8(padapter, EFUSE_TEST + 3);
608 rtw_write8(padapter, EFUSE_TEST + 3, (tempval & 0x7F));
609 }
610 }
611}
612
613static void
614hal_ReadEFuse_WiFi(struct rtw_adapter *padapter,
615 u16 _offset, u16 _size_byte, u8 *pbuf)
616{
617 u8 *efuseTbl = NULL;
618 u16 eFuse_Addr = 0;
619 u8 offset, wden;
620 u8 efuseHeader, efuseExtHdr, efuseData;
621 u16 i, total, used;
622
623
624
625 if ((_offset + _size_byte) > EFUSE_MAP_LEN_8723A) {
626 DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n",
627 __func__, _offset, _size_byte);
628 return;
629 }
630
631 efuseTbl = (u8 *) kmalloc(EFUSE_MAP_LEN_8723A, GFP_KERNEL);
632 if (efuseTbl == NULL) {
633 DBG_8723A("%s: alloc efuseTbl fail!\n", __func__);
634 return;
635 }
636
637 memset(efuseTbl, 0xFF, EFUSE_MAP_LEN_8723A);
638
639
640 hal_EfuseSwitchToBank(padapter, 0);
641
642 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
643 ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseHeader);
644 if (efuseHeader == 0xFF) {
645 DBG_8723A("%s: data end at address =%#x\n", __func__,
646 eFuse_Addr);
647 break;
648 }
649
650
651 if (EXT_HEADER(efuseHeader)) {
652 offset = GET_HDR_OFFSET_2_0(efuseHeader);
653
654 ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseExtHdr);
655 if (ALL_WORDS_DISABLED(efuseExtHdr)) {
656 continue;
657 }
658
659 offset |= ((efuseExtHdr & 0xF0) >> 1);
660 wden = (efuseExtHdr & 0x0F);
661 } else {
662 offset = ((efuseHeader >> 4) & 0x0f);
663 wden = (efuseHeader & 0x0f);
664 }
665
666 if (offset < EFUSE_MAX_SECTION_8723A) {
667 u16 addr;
668
669
670 addr = offset * PGPKT_DATA_SIZE;
671 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
672
673 if (!(wden & (0x01 << i))) {
674 ReadEFuseByte23a(padapter, eFuse_Addr++,
675 &efuseData);
676 efuseTbl[addr] = efuseData;
677
678 ReadEFuseByte23a(padapter, eFuse_Addr++,
679 &efuseData);
680 efuseTbl[addr + 1] = efuseData;
681 }
682 addr += 2;
683 }
684 } else {
685 DBG_8723A(KERN_ERR "%s: offset(%d) is illegal!!\n",
686 __func__, offset);
687 eFuse_Addr += Efuse_CalculateWordCnts23a(wden) * 2;
688 }
689 }
690
691
692 for (i = 0; i < _size_byte; i++)
693 pbuf[i] = efuseTbl[_offset + i];
694
695
696 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
697 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
698 used = eFuse_Addr - 1;
699 rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&used);
700
701 kfree(efuseTbl);
702}
703
704static void
705hal_ReadEFuse_BT(struct rtw_adapter *padapter,
706 u16 _offset, u16 _size_byte, u8 *pbuf)
707{
708 u8 *efuseTbl;
709 u8 bank;
710 u16 eFuse_Addr;
711 u8 efuseHeader, efuseExtHdr, efuseData;
712 u8 offset, wden;
713 u16 i, total, used;
714
715
716
717 if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) {
718 DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n",
719 __func__, _offset, _size_byte);
720 return;
721 }
722
723 efuseTbl = kmalloc(EFUSE_BT_MAP_LEN, GFP_KERNEL);
724 if (efuseTbl == NULL) {
725 DBG_8723A("%s: efuseTbl malloc fail!\n", __func__);
726 return;
727 }
728
729 memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
730
731 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
732 TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total);
733
734 for (bank = 1; bank < EFUSE_MAX_BANK; bank++) {
735 if (hal_EfuseSwitchToBank(padapter, bank) == false) {
736 DBG_8723A("%s: hal_EfuseSwitchToBank Fail!!\n",
737 __func__);
738 goto exit;
739 }
740
741 eFuse_Addr = 0;
742
743 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
744 ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseHeader);
745 if (efuseHeader == 0xFF)
746 break;
747
748
749 if (EXT_HEADER(efuseHeader)) {
750 offset = GET_HDR_OFFSET_2_0(efuseHeader);
751
752 ReadEFuseByte23a(padapter, eFuse_Addr++,
753 &efuseExtHdr);
754 if (ALL_WORDS_DISABLED(efuseExtHdr)) {
755 continue;
756 }
757
758 offset |= ((efuseExtHdr & 0xF0) >> 1);
759 wden = (efuseExtHdr & 0x0F);
760 } else {
761 offset = ((efuseHeader >> 4) & 0x0f);
762 wden = (efuseHeader & 0x0f);
763 }
764
765 if (offset < EFUSE_BT_MAX_SECTION) {
766 u16 addr;
767
768
769
770 addr = offset * PGPKT_DATA_SIZE;
771 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
772
773
774 if (!(wden & (0x01 << i))) {
775 ReadEFuseByte23a(padapter,
776 eFuse_Addr++,
777 &efuseData);
778 efuseTbl[addr] = efuseData;
779
780 ReadEFuseByte23a(padapter,
781 eFuse_Addr++,
782 &efuseData);
783 efuseTbl[addr + 1] = efuseData;
784 }
785 addr += 2;
786 }
787 } else {
788 DBG_8723A(KERN_ERR
789 "%s: offset(%d) is illegal!!\n",
790 __func__, offset);
791 eFuse_Addr += Efuse_CalculateWordCnts23a(wden) * 2;
792 }
793 }
794
795 if ((eFuse_Addr - 1) < total) {
796 DBG_8723A("%s: bank(%d) data end at %#x\n",
797 __func__, bank, eFuse_Addr - 1);
798 break;
799 }
800 }
801
802
803 hal_EfuseSwitchToBank(padapter, 0);
804
805
806 for (i = 0; i < _size_byte; i++)
807 pbuf[i] = efuseTbl[_offset + i];
808
809
810
811
812 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
813 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
814 used = (EFUSE_BT_REAL_BANK_CONTENT_LEN * (bank - 1)) + eFuse_Addr - 1;
815 rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *) &used);
816
817exit:
818 kfree(efuseTbl);
819}
820
821static void
822Hal_ReadEFuse(struct rtw_adapter *padapter,
823 u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf)
824{
825 if (efuseType == EFUSE_WIFI)
826 hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf);
827 else
828 hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf);
829}
830
831static u16
832hal_EfuseGetCurrentSize_WiFi(struct rtw_adapter *padapter)
833{
834 u16 efuse_addr = 0;
835 u8 hoffset = 0, hworden = 0;
836 u8 efuse_data, word_cnts = 0;
837
838 rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *) &efuse_addr);
839
840 DBG_8723A("%s: start_efuse_addr = 0x%X\n", __func__, efuse_addr);
841
842
843 hal_EfuseSwitchToBank(padapter, 0);
844
845 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
846 if (efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data) ==
847 false) {
848 DBG_8723A(KERN_ERR "%s: efuse_OneByteRead23a Fail! "
849 "addr = 0x%X !!\n", __func__, efuse_addr);
850 break;
851 }
852
853 if (efuse_data == 0xFF)
854 break;
855
856 if (EXT_HEADER(efuse_data)) {
857 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
858 efuse_addr++;
859 efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data);
860 if (ALL_WORDS_DISABLED(efuse_data)) {
861 continue;
862 }
863
864 hoffset |= ((efuse_data & 0xF0) >> 1);
865 hworden = efuse_data & 0x0F;
866 } else {
867 hoffset = (efuse_data >> 4) & 0x0F;
868 hworden = efuse_data & 0x0F;
869 }
870
871 word_cnts = Efuse_CalculateWordCnts23a(hworden);
872 efuse_addr += (word_cnts * 2) + 1;
873 }
874
875 rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BYTES, (u8 *) &efuse_addr);
876
877 DBG_8723A("%s: CurrentSize =%d\n", __func__, efuse_addr);
878
879 return efuse_addr;
880}
881
882static u16
883hal_EfuseGetCurrentSize_BT(struct rtw_adapter *padapter)
884{
885 u16 btusedbytes;
886 u16 efuse_addr;
887 u8 bank, startBank;
888 u8 hoffset = 0, hworden = 0;
889 u8 efuse_data, word_cnts = 0;
890 u16 retU2 = 0;
891
892 rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *) &btusedbytes);
893
894 efuse_addr = (u16) ((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN));
895 startBank = (u8) (1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN));
896
897 DBG_8723A("%s: start from bank =%d addr = 0x%X\n", __func__, startBank,
898 efuse_addr);
899
900 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
901 TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2);
902
903 for (bank = startBank; bank < EFUSE_MAX_BANK; bank++) {
904 if (hal_EfuseSwitchToBank(padapter, bank) == false) {
905 DBG_8723A(KERN_ERR "%s: switch bank(%d) Fail!!\n",
906 __func__, bank);
907 bank = EFUSE_MAX_BANK;
908 break;
909 }
910
911
912
913 if (bank != startBank)
914 efuse_addr = 0;
915
916 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
917 if (efuse_OneByteRead23a(padapter, efuse_addr,
918 &efuse_data) == false) {
919 DBG_8723A(KERN_ERR "%s: efuse_OneByteRead23a Fail!"
920 " addr = 0x%X !!\n",
921 __func__, efuse_addr);
922 bank = EFUSE_MAX_BANK;
923 break;
924 }
925
926 if (efuse_data == 0xFF)
927 break;
928
929 if (EXT_HEADER(efuse_data)) {
930 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
931 efuse_addr++;
932 efuse_OneByteRead23a(padapter, efuse_addr,
933 &efuse_data);
934 if (ALL_WORDS_DISABLED(efuse_data)) {
935 efuse_addr++;
936 continue;
937 }
938
939 hoffset |= ((efuse_data & 0xF0) >> 1);
940 hworden = efuse_data & 0x0F;
941 } else {
942 hoffset = (efuse_data >> 4) & 0x0F;
943 hworden = efuse_data & 0x0F;
944 }
945 word_cnts = Efuse_CalculateWordCnts23a(hworden);
946
947 efuse_addr += (word_cnts * 2) + 1;
948 }
949
950
951 if (efuse_addr < retU2) {
952 break;
953 }
954 }
955
956 retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
957 rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&retU2);
958
959 DBG_8723A("%s: CurrentSize =%d\n", __func__, retU2);
960 return retU2;
961}
962
963static u16
964Hal_EfuseGetCurrentSize(struct rtw_adapter *pAdapter, u8 efuseType)
965{
966 u16 ret = 0;
967
968 if (efuseType == EFUSE_WIFI)
969 ret = hal_EfuseGetCurrentSize_WiFi(pAdapter);
970 else
971 ret = hal_EfuseGetCurrentSize_BT(pAdapter);
972
973 return ret;
974}
975
976static u8
977Hal_EfuseWordEnableDataWrite(struct rtw_adapter *padapter,
978 u16 efuse_addr, u8 word_en, u8 *data)
979{
980 u16 tmpaddr = 0;
981 u16 start_addr = efuse_addr;
982 u8 badworden = 0x0F;
983 u8 tmpdata[PGPKT_DATA_SIZE];
984
985 memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
986
987 if (!(word_en & BIT(0))) {
988 tmpaddr = start_addr;
989 efuse_OneByteWrite23a(padapter, start_addr++, data[0]);
990 efuse_OneByteWrite23a(padapter, start_addr++, data[1]);
991
992 efuse_OneByteRead23a(padapter, tmpaddr, &tmpdata[0]);
993 efuse_OneByteRead23a(padapter, tmpaddr + 1, &tmpdata[1]);
994 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) {
995 badworden &= (~BIT(0));
996 }
997 }
998 if (!(word_en & BIT(1))) {
999 tmpaddr = start_addr;
1000 efuse_OneByteWrite23a(padapter, start_addr++, data[2]);
1001 efuse_OneByteWrite23a(padapter, start_addr++, data[3]);
1002
1003 efuse_OneByteRead23a(padapter, tmpaddr, &tmpdata[2]);
1004 efuse_OneByteRead23a(padapter, tmpaddr + 1, &tmpdata[3]);
1005 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) {
1006 badworden &= (~BIT(1));
1007 }
1008 }
1009 if (!(word_en & BIT(2))) {
1010 tmpaddr = start_addr;
1011 efuse_OneByteWrite23a(padapter, start_addr++, data[4]);
1012 efuse_OneByteWrite23a(padapter, start_addr++, data[5]);
1013
1014 efuse_OneByteRead23a(padapter, tmpaddr, &tmpdata[4]);
1015 efuse_OneByteRead23a(padapter, tmpaddr + 1, &tmpdata[5]);
1016 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) {
1017 badworden &= (~BIT(2));
1018 }
1019 }
1020 if (!(word_en & BIT(3))) {
1021 tmpaddr = start_addr;
1022 efuse_OneByteWrite23a(padapter, start_addr++, data[6]);
1023 efuse_OneByteWrite23a(padapter, start_addr++, data[7]);
1024
1025 efuse_OneByteRead23a(padapter, tmpaddr, &tmpdata[6]);
1026 efuse_OneByteRead23a(padapter, tmpaddr + 1, &tmpdata[7]);
1027 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) {
1028 badworden &= (~BIT(3));
1029 }
1030 }
1031
1032 return badworden;
1033}
1034
1035static s32
1036Hal_EfusePgPacketRead(struct rtw_adapter *padapter, u8 offset, u8 *data)
1037{
1038 u8 efuse_data, word_cnts = 0;
1039 u16 efuse_addr = 0;
1040 u8 hoffset = 0, hworden = 0;
1041 u8 i;
1042 u8 max_section = 0;
1043 s32 ret;
1044
1045 if (data == NULL)
1046 return false;
1047
1048 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION,
1049 &max_section);
1050 if (offset > max_section) {
1051 DBG_8723A("%s: Packet offset(%d) is illegal(>%d)!\n",
1052 __func__, offset, max_section);
1053 return false;
1054 }
1055
1056 memset(data, 0xFF, PGPKT_DATA_SIZE);
1057 ret = true;
1058
1059
1060
1061
1062
1063
1064
1065 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1066 if (efuse_OneByteRead23a(padapter, efuse_addr++, &efuse_data) ==
1067 false) {
1068 ret = false;
1069 break;
1070 }
1071
1072 if (efuse_data == 0xFF)
1073 break;
1074
1075 if (EXT_HEADER(efuse_data)) {
1076 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1077 efuse_OneByteRead23a(padapter, efuse_addr++, &efuse_data);
1078 if (ALL_WORDS_DISABLED(efuse_data)) {
1079 DBG_8723A("%s: Error!! All words disabled!\n",
1080 __func__);
1081 continue;
1082 }
1083
1084 hoffset |= ((efuse_data & 0xF0) >> 1);
1085 hworden = efuse_data & 0x0F;
1086 } else {
1087 hoffset = (efuse_data >> 4) & 0x0F;
1088 hworden = efuse_data & 0x0F;
1089 }
1090
1091 if (hoffset == offset) {
1092 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
1093
1094 if (!(hworden & (0x01 << i))) {
1095 ReadEFuseByte23a(padapter, efuse_addr++,
1096 &efuse_data);
1097 data[i * 2] = efuse_data;
1098
1099 ReadEFuseByte23a(padapter, efuse_addr++,
1100 &efuse_data);
1101 data[(i * 2) + 1] = efuse_data;
1102 }
1103 }
1104 } else {
1105 word_cnts = Efuse_CalculateWordCnts23a(hworden);
1106 efuse_addr += word_cnts * 2;
1107 }
1108 }
1109
1110 return ret;
1111}
1112
1113static u8
1114hal_EfusePgCheckAvailableAddr(struct rtw_adapter *pAdapter, u8 efuseType)
1115{
1116 u16 max_available = 0;
1117 u16 current_size;
1118
1119 EFUSE_GetEfuseDefinition23a(pAdapter, efuseType,
1120 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
1121 &max_available);
1122
1123 current_size = Efuse_GetCurrentSize23a(pAdapter, efuseType);
1124 if (current_size >= max_available) {
1125 DBG_8723A("%s: Error!! current_size(%d)>max_available(%d)\n",
1126 __func__, current_size, max_available);
1127 return false;
1128 }
1129 return true;
1130}
1131
1132static void
1133hal_EfuseConstructPGPkt(u8 offset, u8 word_en, u8 *pData,
1134 struct pg_pkt_struct *pTargetPkt)
1135{
1136 memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
1137 pTargetPkt->offset = offset;
1138 pTargetPkt->word_en = word_en;
1139 efuse_WordEnableDataRead23a(word_en, pData, pTargetPkt->data);
1140 pTargetPkt->word_cnts = Efuse_CalculateWordCnts23a(pTargetPkt->word_en);
1141}
1142
1143static u8
1144hal_EfusePartialWriteCheck(struct rtw_adapter *padapter, u8 efuseType,
1145 u16 *pAddr, struct pg_pkt_struct *pTargetPkt)
1146{
1147 u8 bRet = false;
1148 u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
1149 u8 efuse_data = 0;
1150
1151 EFUSE_GetEfuseDefinition23a(padapter, efuseType,
1152 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
1153 &efuse_max_available_len);
1154 EFUSE_GetEfuseDefinition23a(padapter, efuseType,
1155 TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max);
1156
1157 if (efuseType == EFUSE_WIFI) {
1158 rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES,
1159 (u8 *) &startAddr);
1160 } else {
1161 rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES,
1162 (u8 *) &startAddr);
1163 }
1164 startAddr %= efuse_max;
1165
1166 while (1) {
1167 if (startAddr >= efuse_max_available_len) {
1168 bRet = false;
1169 DBG_8723A("%s: startAddr(%d) >= efuse_max_available_"
1170 "len(%d)\n", __func__, startAddr,
1171 efuse_max_available_len);
1172 break;
1173 }
1174
1175 if (efuse_OneByteRead23a(padapter, startAddr, &efuse_data) &&
1176 (efuse_data != 0xFF)) {
1177 bRet = false;
1178 DBG_8723A("%s: Something Wrong! last bytes(%#X = 0x%02X) "
1179 "is not 0xFF\n", __func__,
1180 startAddr, efuse_data);
1181 break;
1182 } else {
1183
1184 *pAddr = startAddr;
1185 bRet = true;
1186 break;
1187 }
1188 }
1189
1190 return bRet;
1191}
1192
1193static u8
1194hal_EfusePgPacketWrite1ByteHeader(struct rtw_adapter *pAdapter, u8 efuseType,
1195 u16 *pAddr, struct pg_pkt_struct *pTargetPkt)
1196{
1197 u8 pg_header = 0, tmp_header = 0;
1198 u16 efuse_addr = *pAddr;
1199 u8 repeatcnt = 0;
1200
1201 pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
1202
1203 do {
1204 efuse_OneByteWrite23a(pAdapter, efuse_addr, pg_header);
1205 efuse_OneByteRead23a(pAdapter, efuse_addr, &tmp_header);
1206 if (tmp_header != 0xFF)
1207 break;
1208 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1209 DBG_8723A("%s: Repeat over limit for pg_header!!\n",
1210 __func__);
1211 return false;
1212 }
1213 } while (1);
1214
1215 if (tmp_header != pg_header) {
1216 DBG_8723A(KERN_ERR "%s: PG Header Fail!!(pg = 0x%02X "
1217 "read = 0x%02X)\n", __func__,
1218 pg_header, tmp_header);
1219 return false;
1220 }
1221
1222 *pAddr = efuse_addr;
1223
1224 return true;
1225}
1226
1227static u8
1228hal_EfusePgPacketWrite2ByteHeader(struct rtw_adapter *padapter, u8 efuseType,
1229 u16 *pAddr, struct pg_pkt_struct *pTargetPkt)
1230{
1231 u16 efuse_addr, efuse_max_available_len = 0;
1232 u8 pg_header = 0, tmp_header = 0;
1233 u8 repeatcnt = 0;
1234
1235 EFUSE_GetEfuseDefinition23a(padapter, efuseType,
1236 TYPE_AVAILABLE_EFUSE_BYTES_BANK,
1237 &efuse_max_available_len);
1238
1239 efuse_addr = *pAddr;
1240 if (efuse_addr >= efuse_max_available_len) {
1241 DBG_8723A("%s: addr(%d) over avaliable(%d)!!\n", __func__,
1242 efuse_addr, efuse_max_available_len);
1243 return false;
1244 }
1245
1246 pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
1247
1248 do {
1249 efuse_OneByteWrite23a(padapter, efuse_addr, pg_header);
1250 efuse_OneByteRead23a(padapter, efuse_addr, &tmp_header);
1251 if (tmp_header != 0xFF)
1252 break;
1253 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1254 DBG_8723A("%s: Repeat over limit for pg_header!!\n",
1255 __func__);
1256 return false;
1257 }
1258 } while (1);
1259
1260 if (tmp_header != pg_header) {
1261 DBG_8723A(KERN_ERR
1262 "%s: PG Header Fail!!(pg = 0x%02X read = 0x%02X)\n",
1263 __func__, pg_header, tmp_header);
1264 return false;
1265 }
1266
1267
1268 efuse_addr++;
1269 pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
1270
1271 do {
1272 efuse_OneByteWrite23a(padapter, efuse_addr, pg_header);
1273 efuse_OneByteRead23a(padapter, efuse_addr, &tmp_header);
1274 if (tmp_header != 0xFF)
1275 break;
1276 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1277 DBG_8723A("%s: Repeat over limit for ext_header!!\n",
1278 __func__);
1279 return false;
1280 }
1281 } while (1);
1282
1283 if (tmp_header != pg_header) {
1284 DBG_8723A(KERN_ERR
1285 "%s: PG EXT Header Fail!!(pg = 0x%02X read = 0x%02X)\n",
1286 __func__, pg_header, tmp_header);
1287 return false;
1288 }
1289
1290 *pAddr = efuse_addr;
1291
1292 return true;
1293}
1294
1295static u8
1296hal_EfusePgPacketWriteHeader(struct rtw_adapter *padapter, u8 efuseType,
1297 u16 *pAddr, struct pg_pkt_struct *pTargetPkt)
1298{
1299 u8 bRet = false;
1300
1301 if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE) {
1302 bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType,
1303 pAddr, pTargetPkt);
1304 } else {
1305 bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType,
1306 pAddr, pTargetPkt);
1307 }
1308
1309 return bRet;
1310}
1311
1312static u8
1313hal_EfusePgPacketWriteData(struct rtw_adapter *pAdapter, u8 efuseType,
1314 u16 *pAddr, struct pg_pkt_struct *pTargetPkt)
1315{
1316 u16 efuse_addr;
1317 u8 badworden;
1318
1319 efuse_addr = *pAddr;
1320 badworden =
1321 Efuse_WordEnableDataWrite23a(pAdapter, efuse_addr + 1,
1322 pTargetPkt->word_en, pTargetPkt->data);
1323 if (badworden != 0x0F) {
1324 DBG_8723A("%s: Fail!!\n", __func__);
1325 return false;
1326 }
1327
1328 return true;
1329}
1330
1331static s32
1332Hal_EfusePgPacketWrite(struct rtw_adapter *padapter,
1333 u8 offset, u8 word_en, u8 *pData)
1334{
1335 struct pg_pkt_struct targetPkt;
1336 u16 startAddr = 0;
1337 u8 efuseType = EFUSE_WIFI;
1338
1339 if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType))
1340 return false;
1341
1342 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
1343
1344 if (!hal_EfusePartialWriteCheck(padapter, efuseType,
1345 &startAddr, &targetPkt))
1346 return false;
1347
1348 if (!hal_EfusePgPacketWriteHeader(padapter, efuseType,
1349 &startAddr, &targetPkt))
1350 return false;
1351
1352 if (!hal_EfusePgPacketWriteData(padapter, efuseType,
1353 &startAddr, &targetPkt))
1354 return false;
1355
1356 return true;
1357}
1358
1359static bool
1360Hal_EfusePgPacketWrite_BT(struct rtw_adapter *pAdapter,
1361 u8 offset, u8 word_en, u8 *pData)
1362{
1363 struct pg_pkt_struct targetPkt;
1364 u16 startAddr = 0;
1365 u8 efuseType = EFUSE_BT;
1366
1367 if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType))
1368 return false;
1369
1370 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
1371
1372 if (!hal_EfusePartialWriteCheck(pAdapter, efuseType,
1373 &startAddr, &targetPkt))
1374 return false;
1375
1376 if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType,
1377 &startAddr, &targetPkt))
1378 return false;
1379
1380 if (!hal_EfusePgPacketWriteData(pAdapter, efuseType,
1381 &startAddr, &targetPkt))
1382 return false;
1383
1384 return true;
1385}
1386
1387static struct hal_version ReadChipVersion8723A(struct rtw_adapter *padapter)
1388{
1389 u32 value32;
1390 struct hal_version ChipVersion;
1391 struct hal_data_8723a *pHalData;
1392
1393 pHalData = GET_HAL_DATA(padapter);
1394
1395 value32 = rtw_read32(padapter, REG_SYS_CFG);
1396 ChipVersion.ICType = CHIP_8723A;
1397 ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
1398 ChipVersion.RFType = RF_TYPE_1T1R;
1399 ChipVersion.VendorType =
1400 ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
1401 ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT;
1402
1403
1404 pHalData->RegulatorMode = ((value32 & SPS_SEL) ?
1405 RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
1406
1407 value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
1408
1409 ChipVersion.ROMVer = ((value32 & RF_RL_ID) >> 20);
1410
1411
1412 pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
1413 value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
1414 pHalData->MultiFunc |=
1415 ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
1416 pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
1417 pHalData->MultiFunc |=
1418 ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
1419 pHalData->PolarityCtl =
1420 ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT :
1421 RT_POLARITY_LOW_ACT);
1422 dump_chip_info23a(ChipVersion);
1423 pHalData->VersionID = ChipVersion;
1424
1425 if (IS_1T2R(ChipVersion))
1426 pHalData->rf_type = RF_1T2R;
1427 else if (IS_2T2R(ChipVersion))
1428 pHalData->rf_type = RF_2T2R;
1429 else
1430 pHalData->rf_type = RF_1T1R;
1431
1432 MSG_8723A("RF_Type is %x!!\n", pHalData->rf_type);
1433
1434 return ChipVersion;
1435}
1436
1437static void rtl8723a_read_chip_version(struct rtw_adapter *padapter)
1438{
1439 ReadChipVersion8723A(padapter);
1440}
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453void SetBcnCtrlReg23a(struct rtw_adapter *padapter, u8 SetBits, u8 ClearBits)
1454{
1455 struct hal_data_8723a *pHalData;
1456 u32 addr;
1457 u8 *pRegBcnCtrlVal;
1458
1459 pHalData = GET_HAL_DATA(padapter);
1460 pRegBcnCtrlVal = (u8 *)&pHalData->RegBcnCtrlVal;
1461
1462 addr = REG_BCN_CTRL;
1463
1464 *pRegBcnCtrlVal = rtw_read8(padapter, addr);
1465 *pRegBcnCtrlVal |= SetBits;
1466 *pRegBcnCtrlVal &= ~ClearBits;
1467
1468 rtw_write8(padapter, addr, *pRegBcnCtrlVal);
1469}
1470
1471void rtl8723a_InitBeaconParameters(struct rtw_adapter *padapter)
1472{
1473 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1474
1475 rtw_write16(padapter, REG_BCN_CTRL, 0x1010);
1476 pHalData->RegBcnCtrlVal = 0x1010;
1477
1478
1479 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);
1480
1481
1482 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == false)
1483 rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);
1484
1485 rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
1486
1487
1488
1489
1490 rtw_write16(padapter, REG_BCNTCFG, 0x660F);
1491}
1492
1493static void ResumeTxBeacon(struct rtw_adapter *padapter)
1494{
1495 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1496
1497
1498
1499
1500
1501 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
1502
1503 pHalData->RegFwHwTxQCtrl |= BIT(6);
1504 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl);
1505 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xff);
1506 pHalData->RegReg542 |= BIT(0);
1507 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
1508}
1509
1510static void StopTxBeacon(struct rtw_adapter *padapter)
1511{
1512 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1513
1514
1515
1516
1517
1518 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
1519
1520 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
1521 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl);
1522 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64);
1523 pHalData->RegReg542 &= ~BIT(0);
1524 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
1525
1526 CheckFwRsvdPageContent23a(padapter);
1527}
1528
1529static void _BeaconFunctionEnable(struct rtw_adapter *padapter, u8 Enable,
1530 u8 Linked)
1531{
1532 SetBcnCtrlReg23a(padapter, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB,
1533 0);
1534 rtw_write8(padapter, REG_RD_CTRL + 1, 0x6F);
1535}
1536
1537static void rtl8723a_SetBeaconRelatedRegisters(struct rtw_adapter *padapter)
1538{
1539 u32 value32;
1540 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1541 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558 rtw_write16(padapter, REG_ATIMWND, 2);
1559
1560
1561
1562
1563 rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
1564
1565 rtl8723a_InitBeaconParameters(padapter);
1566
1567 rtw_write8(padapter, REG_SLOT, 0x09);
1568
1569
1570
1571
1572 value32 = rtw_read32(padapter, REG_TCR);
1573 value32 &= ~TSFRST;
1574 rtw_write32(padapter, REG_TCR, value32);
1575
1576 value32 |= TSFRST;
1577 rtw_write32(padapter, REG_TCR, value32);
1578
1579
1580 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE |
1581 WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE) == true) {
1582 rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
1583 rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
1584 }
1585
1586 _BeaconFunctionEnable(padapter, true, true);
1587
1588 ResumeTxBeacon(padapter);
1589 SetBcnCtrlReg23a(padapter, DIS_BCNQ_SUB, 0);
1590}
1591
1592static void rtl8723a_GetHalODMVar(struct rtw_adapter *Adapter,
1593 enum hal_odm_variable eVariable,
1594 void *pValue1, bool bSet)
1595{
1596 switch (eVariable) {
1597 case HAL_ODM_STA_INFO:
1598 break;
1599 default:
1600 break;
1601 }
1602}
1603
1604static void rtl8723a_SetHalODMVar(struct rtw_adapter *Adapter,
1605 enum hal_odm_variable eVariable,
1606 void *pValue1, bool bSet)
1607{
1608 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1609 struct dm_odm_t *podmpriv = &pHalData->odmpriv;
1610 switch (eVariable) {
1611 case HAL_ODM_STA_INFO:
1612 {
1613 struct sta_info *psta = (struct sta_info *)pValue1;
1614
1615 if (bSet) {
1616 DBG_8723A("Set STA_(%d) info\n", psta->mac_id);
1617 ODM_CmnInfoPtrArrayHook23a(podmpriv,
1618 ODM_CMNINFO_STA_STATUS,
1619 psta->mac_id, psta);
1620 } else {
1621 DBG_8723A("Clean STA_(%d) info\n", psta->mac_id);
1622 ODM_CmnInfoPtrArrayHook23a(podmpriv,
1623 ODM_CMNINFO_STA_STATUS,
1624 psta->mac_id, NULL);
1625 }
1626 }
1627 break;
1628 case HAL_ODM_P2P_STATE:
1629 ODM_CmnInfoUpdate23a(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
1630 break;
1631 case HAL_ODM_WIFI_DISPLAY_STATE:
1632 ODM_CmnInfoUpdate23a(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
1633 break;
1634 default:
1635 break;
1636 }
1637}
1638
1639static void hal_notch_filter_8723a(struct rtw_adapter *adapter, bool enable)
1640{
1641 if (enable) {
1642 DBG_8723A("Enable notch filter\n");
1643 rtw_write8(adapter, rOFDM0_RxDSP + 1,
1644 rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT1);
1645 } else {
1646 DBG_8723A("Disable notch filter\n");
1647 rtw_write8(adapter, rOFDM0_RxDSP + 1,
1648 rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT1);
1649 }
1650}
1651
1652s32 c2h_id_filter_ccx_8723a(u8 id)
1653{
1654 s32 ret = false;
1655 if (id == C2H_CCX_TX_RPT)
1656 ret = true;
1657
1658 return ret;
1659}
1660
1661static s32 c2h_handler_8723a(struct rtw_adapter *padapter,
1662 struct c2h_evt_hdr *c2h_evt)
1663{
1664 s32 ret = _SUCCESS;
1665 u8 i = 0;
1666
1667 if (c2h_evt == NULL) {
1668 DBG_8723A("%s c2h_evt is NULL\n", __func__);
1669 ret = _FAIL;
1670 goto exit;
1671 }
1672
1673 switch (c2h_evt->id) {
1674 case C2H_DBG:
1675 RT_TRACE(_module_hal_init_c_, _drv_info_,
1676 ("C2HCommandHandler: %s\n", c2h_evt->payload));
1677 break;
1678
1679 case C2H_CCX_TX_RPT:
1680 handle_txrpt_ccx_8723a(padapter, c2h_evt->payload);
1681 break;
1682 case C2H_EXT_RA_RPT:
1683 break;
1684 case C2H_HW_INFO_EXCH:
1685 RT_TRACE(_module_hal_init_c_, _drv_info_,
1686 ("[BT], C2H_HW_INFO_EXCH\n"));
1687 for (i = 0; i < c2h_evt->plen; i++) {
1688 RT_TRACE(_module_hal_init_c_, _drv_info_,
1689 ("[BT], tmpBuf[%d]= 0x%x\n", i,
1690 c2h_evt->payload[i]));
1691 }
1692 break;
1693
1694 case C2H_C2H_H2C_TEST:
1695 RT_TRACE(_module_hal_init_c_, _drv_info_,
1696 ("[BT], C2H_H2C_TEST\n"));
1697 RT_TRACE(_module_hal_init_c_, _drv_info_,
1698 ("[BT], tmpBuf[0]/[1]/[2]/[3]/[4]= 0x%x/ 0x%x/ "
1699 "0x%x/ 0x%x/ 0x%x\n", c2h_evt->payload[0],
1700 c2h_evt->payload[1], c2h_evt->payload[2],
1701 c2h_evt->payload[3], c2h_evt->payload[4]));
1702 break;
1703
1704#ifdef CONFIG_8723AU_BT_COEXIST
1705 case C2H_BT_INFO:
1706 DBG_8723A("%s , Got C2H_BT_INFO \n", __func__);
1707 BT_FwC2hBtInfo(padapter, c2h_evt->payload, c2h_evt->plen);
1708 break;
1709#endif
1710
1711 default:
1712 ret = _FAIL;
1713 break;
1714 }
1715
1716exit:
1717 return ret;
1718}
1719
1720void rtl8723a_set_hal_ops(struct hal_ops *pHalFunc)
1721{
1722 pHalFunc->free_hal_data = &rtl8723a_free_hal_data;
1723
1724 pHalFunc->dm_init = &rtl8723a_init_dm_priv;
1725 pHalFunc->dm_deinit = &rtl8723a_deinit_dm_priv;
1726
1727 pHalFunc->read_chip_version = &rtl8723a_read_chip_version;
1728
1729 pHalFunc->set_bwmode_handler = &PHY_SetBWMode23a8723A;
1730 pHalFunc->set_channel_handler = &PHY_SwChnl8723A;
1731
1732 pHalFunc->hal_dm_watchdog = &rtl8723a_HalDmWatchDog;
1733
1734 pHalFunc->SetBeaconRelatedRegistersHandler =
1735 &rtl8723a_SetBeaconRelatedRegisters;
1736
1737 pHalFunc->Add_RateATid = &rtl8723a_add_rateatid;
1738 pHalFunc->run_thread = &rtl8723a_start_thread;
1739 pHalFunc->cancel_thread = &rtl8723a_stop_thread;
1740
1741 pHalFunc->read_bbreg = &PHY_QueryBBReg;
1742 pHalFunc->write_bbreg = &PHY_SetBBReg;
1743 pHalFunc->read_rfreg = &PHY_QueryRFReg;
1744 pHalFunc->write_rfreg = &PHY_SetRFReg;
1745
1746
1747 pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch;
1748 pHalFunc->ReadEFuse = &Hal_ReadEFuse;
1749 pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition;
1750 pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize;
1751 pHalFunc->Efuse_PgPacketRead23a = &Hal_EfusePgPacketRead;
1752 pHalFunc->Efuse_PgPacketWrite23a = &Hal_EfusePgPacketWrite;
1753 pHalFunc->Efuse_WordEnableDataWrite23a = &Hal_EfuseWordEnableDataWrite;
1754 pHalFunc->Efuse_PgPacketWrite23a_BT = &Hal_EfusePgPacketWrite_BT;
1755
1756 pHalFunc->sreset_init_value23a = &sreset_init_value23a;
1757 pHalFunc->sreset_reset_value23a = &sreset_reset_value23a;
1758 pHalFunc->silentreset = &sreset_reset;
1759 pHalFunc->sreset_xmit_status_check = &rtl8723a_sreset_xmit_status_check;
1760 pHalFunc->sreset_linked_status_check =
1761 &rtl8723a_sreset_linked_status_check;
1762 pHalFunc->sreset_get_wifi_status23a = &sreset_get_wifi_status23a;
1763 pHalFunc->sreset_inprogress = &sreset_inprogress;
1764 pHalFunc->GetHalODMVarHandler = &rtl8723a_GetHalODMVar;
1765 pHalFunc->SetHalODMVarHandler = &rtl8723a_SetHalODMVar;
1766
1767 pHalFunc->hal_notch_filter = &hal_notch_filter_8723a;
1768
1769 pHalFunc->c2h_handler = c2h_handler_8723a;
1770 pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8723a;
1771}
1772
1773void rtl8723a_InitAntenna_Selection(struct rtw_adapter *padapter)
1774{
1775 struct hal_data_8723a *pHalData;
1776 u8 val;
1777
1778 pHalData = GET_HAL_DATA(padapter);
1779
1780 val = rtw_read8(padapter, REG_LEDCFG2);
1781
1782 val |= BIT(7);
1783 rtw_write8(padapter, REG_LEDCFG2, val);
1784}
1785
1786void rtl8723a_CheckAntenna_Selection(struct rtw_adapter *padapter)
1787{
1788 struct hal_data_8723a *pHalData;
1789 u8 val;
1790
1791 pHalData = GET_HAL_DATA(padapter);
1792
1793 val = rtw_read8(padapter, REG_LEDCFG2);
1794
1795 if (!(val & BIT(7))) {
1796 val |= BIT(7);
1797 rtw_write8(padapter, REG_LEDCFG2, val);
1798 }
1799}
1800
1801void rtl8723a_DeinitAntenna_Selection(struct rtw_adapter *padapter)
1802{
1803 struct hal_data_8723a *pHalData;
1804 u8 val;
1805
1806 pHalData = GET_HAL_DATA(padapter);
1807 val = rtw_read8(padapter, REG_LEDCFG2);
1808
1809 val &= ~BIT(7);
1810 rtw_write8(padapter, REG_LEDCFG2, val);
1811}
1812
1813void rtl8723a_init_default_value(struct rtw_adapter *padapter)
1814{
1815 struct hal_data_8723a *pHalData;
1816 struct dm_priv *pdmpriv;
1817 u8 i;
1818
1819 pHalData = GET_HAL_DATA(padapter);
1820 pdmpriv = &pHalData->dmpriv;
1821
1822
1823 pHalData->fw_ractrl = false;
1824 pHalData->bIQKInitialized = false;
1825 if (!padapter->pwrctrlpriv.bkeepfwalive)
1826 pHalData->LastHMEBoxNum = 0;
1827
1828 pHalData->bIQKInitialized = false;
1829
1830
1831 pdmpriv->TM_Trigger = 0;
1832
1833
1834
1835
1836 pdmpriv->ThermalValue_HP_index = 0;
1837 for (i = 0; i < HP_THERMAL_NUM; i++)
1838 pdmpriv->ThermalValue_HP[i] = 0;
1839
1840
1841 pHalData->EfuseUsedBytes = 0;
1842 pHalData->BTEfuseUsedBytes = 0;
1843}
1844
1845u8 GetEEPROMSize8723A(struct rtw_adapter *padapter)
1846{
1847 u8 size = 0;
1848 u32 cr;
1849
1850 cr = rtw_read16(padapter, REG_9346CR);
1851
1852 size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
1853
1854 MSG_8723A("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
1855
1856 return size;
1857}
1858
1859
1860
1861
1862
1863
1864static s32 _LLTWrite(struct rtw_adapter *padapter, u32 address, u32 data)
1865{
1866 s32 status = _SUCCESS;
1867 s32 count = 0;
1868 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
1869 _LLT_OP(_LLT_WRITE_ACCESS);
1870 u16 LLTReg = REG_LLT_INIT;
1871
1872 rtw_write32(padapter, LLTReg, value);
1873
1874
1875 do {
1876 value = rtw_read32(padapter, LLTReg);
1877 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) {
1878 break;
1879 }
1880
1881 if (count > POLLING_LLT_THRESHOLD) {
1882 RT_TRACE(_module_hal_init_c_, _drv_err_,
1883 ("Failed to polling write LLT done at "
1884 "address %d!\n", address));
1885 status = _FAIL;
1886 break;
1887 }
1888 } while (count++);
1889
1890 return status;
1891}
1892
1893s32 InitLLTTable23a(struct rtw_adapter *padapter, u32 boundary)
1894{
1895 s32 status = _SUCCESS;
1896 u32 i;
1897 u32 txpktbuf_bndy = boundary;
1898 u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;
1899
1900 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
1901 status = _LLTWrite(padapter, i, i + 1);
1902 if (_SUCCESS != status) {
1903 return status;
1904 }
1905 }
1906
1907
1908 status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
1909 if (_SUCCESS != status) {
1910 return status;
1911 }
1912
1913
1914
1915
1916
1917 for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
1918 status = _LLTWrite(padapter, i, (i + 1));
1919 if (_SUCCESS != status) {
1920 return status;
1921 }
1922 }
1923
1924
1925 status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
1926 if (_SUCCESS != status) {
1927 return status;
1928 }
1929
1930 return status;
1931}
1932
1933static void _DisableGPIO(struct rtw_adapter *padapter)
1934{
1935
1936
1937
1938
1939
1940
1941
1942 u32 value32;
1943 u32 u4bTmp;
1944
1945
1946 rtw_write16(padapter, REG_GPIO_PIN_CTRL + 2, 0x0000);
1947 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
1948 u4bTmp = value32 & 0x000000FF;
1949 value32 |= ((u4bTmp << 8) | 0x00FF0000);
1950 rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32);
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961 rtw_write16(padapter, REG_GPIO_IO_SEL_2, 0x0000);
1962 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL_2) & 0xFFFF001F;
1963 u4bTmp = value32 & 0x0000001F;
1964
1965 value32 |= ((u4bTmp << 8) | 0x001D0000);
1966 rtw_write32(padapter, REG_GPIO_PIN_CTRL_2, value32);
1967
1968
1969 rtw_write16(padapter, REG_LEDCFG0, 0x8080);
1970}
1971
1972static void _DisableRFAFEAndResetBB8192C(struct rtw_adapter *padapter)
1973{
1974
1975
1976
1977
1978
1979
1980
1981 u8 eRFPath = 0, value8 = 0;
1982
1983 rtw_write8(padapter, REG_TXPAUSE, 0xFF);
1984
1985 PHY_SetRFReg(padapter, (enum RF_RADIO_PATH) eRFPath, 0x0, bMaskByte0, 0x0);
1986
1987 value8 |= APSDOFF;
1988 rtw_write8(padapter, REG_APSD_CTRL, value8);
1989
1990
1991 value8 = 0;
1992 value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
1993 rtw_write8(padapter, REG_SYS_FUNC_EN, value8);
1994
1995
1996 value8 &= ~FEN_BB_GLB_RSTn;
1997 rtw_write8(padapter, REG_SYS_FUNC_EN, value8);
1998
1999
2000
2001
2002
2003}
2004
2005static void _DisableRFAFEAndResetBB(struct rtw_adapter *padapter)
2006{
2007 _DisableRFAFEAndResetBB8192C(padapter);
2008}
2009
2010static void _ResetDigitalProcedure1_92C(struct rtw_adapter *padapter,
2011 bool bWithoutHWSM)
2012{
2013 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
2014
2015 if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20)) {
2016
2017
2018
2019
2020
2021
2022
2023 u16 valu16 = 0;
2024 rtw_write8(padapter, REG_MCUFWDL, 0);
2025
2026 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
2027
2028 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));
2029
2030 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN) & 0x0FFF;
2031 rtw_write16(padapter, REG_SYS_FUNC_EN,
2032 (valu16 | (FEN_HWPDN | FEN_ELDR)));
2033
2034 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
2035
2036 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));
2037 } else {
2038 u8 retry_cnts = 0;
2039
2040
2041
2042
2043
2044
2045
2046 if (rtw_read8(padapter, REG_MCUFWDL) & BIT1) {
2047
2048 if (padapter->bFWReady) {
2049
2050
2051
2052 rtw_write8(padapter, REG_FWIMR, 0x20);
2053
2054
2055
2056 rtw_write8(padapter, REG_FTIMR, 0x00);
2057 rtw_write8(padapter, REG_FSIMR, 0x00);
2058
2059
2060 rtw_write8(padapter, REG_HMETFR + 3, 0x20);
2061
2062 while ((retry_cnts++ < 100) &&
2063 (FEN_CPUEN &
2064 rtw_read16(padapter, REG_SYS_FUNC_EN))) {
2065 udelay(50);
2066 }
2067
2068 if (retry_cnts >= 100) {
2069
2070 rtw_write8(padapter,
2071 REG_SYS_FUNC_EN + 1, 0x50);
2072 mdelay(10);
2073 }
2074 }
2075 }
2076
2077 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54);
2078 rtw_write8(padapter, REG_MCUFWDL, 0);
2079 }
2080
2081 if (bWithoutHWSM) {
2082
2083
2084
2085
2086
2087
2088
2089
2090 rtw_write16(padapter, REG_SYS_CLKR, 0x70A3);
2091 rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
2092 rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
2093 rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
2094 } else {
2095
2096 rtw_write8(padapter, REG_RF_CTRL, 0x00);
2097 }
2098}
2099
2100static void _ResetDigitalProcedure1(struct rtw_adapter *padapter,
2101 bool bWithoutHWSM)
2102{
2103 _ResetDigitalProcedure1_92C(padapter, bWithoutHWSM);
2104}
2105
2106static void _ResetDigitalProcedure2(struct rtw_adapter *padapter)
2107{
2108
2109
2110
2111
2112
2113
2114 rtw_write16(padapter, REG_SYS_CLKR, 0x70a3);
2115
2116 rtw_write8(padapter, REG_SYS_ISO_CTRL + 1, 0x82);
2117}
2118
2119static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM)
2120{
2121 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
2122 u16 value16 = 0;
2123 u8 value8 = 0;
2124
2125 if (bWithoutHWSM) {
2126
2127
2128
2129
2130
2131
2132
2133 rtw_write8(padapter, REG_LDOA15_CTRL, 0x04);
2134
2135
2136 value8 = rtw_read8(padapter, REG_LDOV12D_CTRL);
2137 value8 &= (~LDV12_EN);
2138 rtw_write8(padapter, REG_LDOV12D_CTRL, value8);
2139
2140
2141 }
2142
2143
2144
2145
2146
2147 value8 = 0x23;
2148 if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
2149 value8 |= BIT3;
2150
2151 rtw_write8(padapter, REG_SPS0_CTRL, value8);
2152
2153 if (bWithoutHWSM) {
2154
2155
2156
2157
2158
2159 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
2160 } else {
2161 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
2162 }
2163
2164 rtw_write16(padapter, REG_APS_FSMCO, value16);
2165
2166 rtw_write8(padapter, REG_RSV_CTRL, 0x0e);
2167}
2168
2169
2170s32 CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU)
2171{
2172 int rtStatus = _SUCCESS;
2173
2174 if (padapter->bSurpriseRemoved) {
2175 return rtStatus;
2176 }
2177
2178 _DisableRFAFEAndResetBB(padapter);
2179
2180
2181 _ResetDigitalProcedure1(padapter, false);
2182
2183
2184 _DisableGPIO(padapter);
2185
2186
2187 _DisableAnalog(padapter, false);
2188
2189 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2190 ("======> Card disable finished.\n"));
2191
2192 return rtStatus;
2193}
2194
2195
2196s32 CardDisableWithoutHWSM(struct rtw_adapter *padapter)
2197{
2198 s32 rtStatus = _SUCCESS;
2199
2200
2201
2202 if (padapter->bSurpriseRemoved) {
2203 return rtStatus;
2204 }
2205
2206
2207 _DisableRFAFEAndResetBB(padapter);
2208
2209
2210 _ResetDigitalProcedure1(padapter, true);
2211
2212
2213 _DisableGPIO(padapter);
2214
2215
2216 _ResetDigitalProcedure2(padapter);
2217
2218
2219 _DisableAnalog(padapter, true);
2220
2221
2222
2223 return rtStatus;
2224}
2225
2226void Hal_InitPGData(struct rtw_adapter *padapter, u8 *PROMContent)
2227{
2228 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
2229
2230 if (false == pEEPROM->bautoload_fail_flag) {
2231 if (!pEEPROM->EepromOrEfuse) {
2232
2233 EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI);
2234 memcpy((void *)PROMContent,
2235 (void *)pEEPROM->efuse_eeprom_data,
2236 HWSET_MAX_SIZE);
2237 }
2238 } else {
2239 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,
2240 ("AutoLoad Fail reported from CR9346!!\n"));
2241
2242
2243 if (false == pEEPROM->EepromOrEfuse)
2244 EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI);
2245 memcpy((void *)PROMContent, (void *)pEEPROM->efuse_eeprom_data,
2246 HWSET_MAX_SIZE);
2247 }
2248}
2249
2250void Hal_EfuseParseIDCode(struct rtw_adapter *padapter, u8 *hwinfo)
2251{
2252 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
2253
2254 u16 EEPROMId;
2255
2256
2257 EEPROMId = le16_to_cpu(*((u16 *) hwinfo));
2258 if (EEPROMId != RTL_EEPROM_ID) {
2259 DBG_8723A("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
2260 pEEPROM->bautoload_fail_flag = true;
2261 } else {
2262 pEEPROM->bautoload_fail_flag = false;
2263 }
2264
2265 RT_TRACE(_module_hal_init_c_, _drv_info_,
2266 ("EEPROM ID = 0x%04x\n", EEPROMId));
2267}
2268
2269static void Hal_EEValueCheck(u8 EEType, void *pInValue, void *pOutValue)
2270{
2271 switch (EEType) {
2272 case EETYPE_TX_PWR:
2273 {
2274 u8 *pIn, *pOut;
2275 pIn = (u8 *) pInValue;
2276 pOut = (u8 *) pOutValue;
2277 if (*pIn >= 0 && *pIn <= 63) {
2278 *pOut = *pIn;
2279 } else {
2280 RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
2281 ("EETYPE_TX_PWR, value =%d is invalid, set "
2282 "to default = 0x%x\n",
2283 *pIn, EEPROM_Default_TxPowerLevel));
2284 *pOut = EEPROM_Default_TxPowerLevel;
2285 }
2286 }
2287 break;
2288 default:
2289 break;
2290 }
2291}
2292
2293static void
2294Hal_ReadPowerValueFromPROM_8723A(struct txpowerinfo *pwrInfo,
2295 u8 *PROMContent, bool AutoLoadFail)
2296{
2297 u32 rfPath, eeAddr, group, rfPathMax = 1;
2298
2299 memset(pwrInfo, 0, sizeof(*pwrInfo));
2300
2301 if (AutoLoadFail) {
2302 for (group = 0; group < MAX_CHNL_GROUP; group++) {
2303 for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
2304 pwrInfo->CCKIndex[rfPath][group] =
2305 EEPROM_Default_TxPowerLevel;
2306 pwrInfo->HT40_1SIndex[rfPath][group] =
2307 EEPROM_Default_TxPowerLevel;
2308 pwrInfo->HT40_2SIndexDiff[rfPath][group] =
2309 EEPROM_Default_HT40_2SDiff;
2310 pwrInfo->HT20IndexDiff[rfPath][group] =
2311 EEPROM_Default_HT20_Diff;
2312 pwrInfo->OFDMIndexDiff[rfPath][group] =
2313 EEPROM_Default_LegacyHTTxPowerDiff;
2314 pwrInfo->HT40MaxOffset[rfPath][group] =
2315 EEPROM_Default_HT40_PwrMaxOffset;
2316 pwrInfo->HT20MaxOffset[rfPath][group] =
2317 EEPROM_Default_HT20_PwrMaxOffset;
2318 }
2319 }
2320 pwrInfo->TSSI_A[0] = EEPROM_Default_TSSI;
2321 return;
2322 }
2323
2324 for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
2325 for (group = 0; group < MAX_CHNL_GROUP; group++) {
2326 eeAddr =
2327 EEPROM_CCK_TX_PWR_INX_8723A + (rfPath * 3) + group;
2328
2329
2330 Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr],
2331 &pwrInfo->CCKIndex[rfPath][group]);
2332 eeAddr = EEPROM_HT40_1S_TX_PWR_INX_8723A +
2333 (rfPath * 3) + group;
2334
2335
2336 Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr],
2337 &pwrInfo->HT40_1SIndex[rfPath][group]);
2338 }
2339 }
2340
2341 for (group = 0; group < MAX_CHNL_GROUP; group++) {
2342 for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
2343 pwrInfo->HT40_2SIndexDiff[rfPath][group] = 0;
2344 pwrInfo->HT20IndexDiff[rfPath][group] =
2345 (PROMContent
2346 [EEPROM_HT20_TX_PWR_INX_DIFF_8723A +
2347 group] >> (rfPath * 4)) & 0xF;
2348
2349 if (pwrInfo->HT20IndexDiff[rfPath][group] & BIT3)
2350 pwrInfo->HT20IndexDiff[rfPath][group] |= 0xF0;
2351
2352 pwrInfo->OFDMIndexDiff[rfPath][group] =
2353 (PROMContent[EEPROM_OFDM_TX_PWR_INX_DIFF_8723A +
2354 group] >> (rfPath * 4)) & 0xF;
2355
2356 pwrInfo->HT40MaxOffset[rfPath][group] =
2357 (PROMContent[EEPROM_HT40_MAX_PWR_OFFSET_8723A +
2358 group] >> (rfPath * 4)) & 0xF;
2359
2360 pwrInfo->HT20MaxOffset[rfPath][group] =
2361 (PROMContent[EEPROM_HT20_MAX_PWR_OFFSET_8723A +
2362 group] >> (rfPath * 4)) & 0xF;
2363 }
2364 }
2365
2366 pwrInfo->TSSI_A[0] = PROMContent[EEPROM_TSSI_A_8723A];
2367}
2368
2369static u8 Hal_GetChnlGroup(u8 chnl)
2370{
2371 u8 group = 0;
2372
2373 if (chnl < 3)
2374 group = 0;
2375 else if (chnl < 9)
2376 group = 1;
2377 else
2378 group = 2;
2379
2380 return group;
2381}
2382
2383void
2384Hal_EfuseParsetxpowerinfo_8723A(struct rtw_adapter *padapter,
2385 u8 *PROMContent, bool AutoLoadFail)
2386{
2387 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
2388 struct txpowerinfo pwrInfo;
2389 u8 rfPath, ch, group, rfPathMax = 1;
2390 u8 pwr, diff;
2391
2392 Hal_ReadPowerValueFromPROM_8723A(&pwrInfo, PROMContent, AutoLoadFail);
2393 for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
2394 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
2395 group = Hal_GetChnlGroup(ch);
2396
2397 pHalData->TxPwrLevelCck[rfPath][ch] =
2398 pwrInfo.CCKIndex[rfPath][group];
2399 pHalData->TxPwrLevelHT40_1S[rfPath][ch] =
2400 pwrInfo.HT40_1SIndex[rfPath][group];
2401
2402 pHalData->TxPwrHt20Diff[rfPath][ch] =
2403 pwrInfo.HT20IndexDiff[rfPath][group];
2404 pHalData->TxPwrLegacyHtDiff[rfPath][ch] =
2405 pwrInfo.OFDMIndexDiff[rfPath][group];
2406 pHalData->PwrGroupHT20[rfPath][ch] =
2407 pwrInfo.HT20MaxOffset[rfPath][group];
2408 pHalData->PwrGroupHT40[rfPath][ch] =
2409 pwrInfo.HT40MaxOffset[rfPath][group];
2410
2411 pwr = pwrInfo.HT40_1SIndex[rfPath][group];
2412 diff = pwrInfo.HT40_2SIndexDiff[rfPath][group];
2413
2414 pHalData->TxPwrLevelHT40_2S[rfPath][ch] =
2415 (pwr > diff) ? (pwr - diff) : 0;
2416 }
2417 }
2418 for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
2419 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
2420 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2421 ("RF(%u)-Ch(%u) [CCK / HT40_1S / HT40_2S] = "
2422 "[0x%x / 0x%x / 0x%x]\n",
2423 rfPath, ch,
2424 pHalData->TxPwrLevelCck[rfPath][ch],
2425 pHalData->TxPwrLevelHT40_1S[rfPath][ch],
2426 pHalData->TxPwrLevelHT40_2S[rfPath][ch]));
2427
2428 }
2429 }
2430 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
2431 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2432 ("RF-A Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
2433 pHalData->TxPwrHt20Diff[RF_PATH_A][ch],
2434 pHalData->TxPwrHt20Diff[RF_PATH_A][ch]));
2435 }
2436 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++)
2437 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2438 ("RF-A Legacy to Ht40 Diff[%u] = 0x%x\n", ch,
2439 pHalData->TxPwrLegacyHtDiff[RF_PATH_A][ch]));
2440 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
2441 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2442 ("RF-B Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
2443 pHalData->TxPwrHt20Diff[RF_PATH_B][ch],
2444 pHalData->TxPwrHt20Diff[RF_PATH_B][ch]));
2445 }
2446 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++)
2447 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2448 ("RF-B Legacy to HT40 Diff[%u] = 0x%x\n", ch,
2449 pHalData->TxPwrLegacyHtDiff[RF_PATH_B][ch]));
2450 if (!AutoLoadFail) {
2451 struct registry_priv *registry_par = &padapter->registrypriv;
2452 if (registry_par->regulatory_tid == 0xff) {
2453 if (PROMContent[RF_OPTION1_8723A] == 0xff)
2454 pHalData->EEPROMRegulatory = 0;
2455 else
2456 pHalData->EEPROMRegulatory =
2457 PROMContent[RF_OPTION1_8723A] & 0x7;
2458 } else {
2459 pHalData->EEPROMRegulatory =
2460 registry_par->regulatory_tid;
2461 }
2462 } else {
2463 pHalData->EEPROMRegulatory = 0;
2464 }
2465 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2466 ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory));
2467
2468 if (!AutoLoadFail)
2469 pHalData->bTXPowerDataReadFromEEPORM = true;
2470}
2471
2472void
2473Hal_EfuseParseBTCoexistInfo_8723A(struct rtw_adapter *padapter,
2474 u8 *hwinfo, bool AutoLoadFail)
2475{
2476 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
2477 u8 tempval;
2478 u32 tmpu4;
2479
2480 if (!AutoLoadFail) {
2481 tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
2482 if (tmpu4 & BT_FUNC_EN)
2483 pHalData->EEPROMBluetoothCoexist = 1;
2484 else
2485 pHalData->EEPROMBluetoothCoexist = 0;
2486 pHalData->EEPROMBluetoothType = BT_RTL8723A;
2487
2488
2489
2490 tempval = hwinfo[RF_OPTION4_8723A];
2491 pHalData->EEPROMBluetoothAntNum = (tempval & 0x1);
2492 pHalData->EEPROMBluetoothAntIsolation = ((tempval & 0x10) >> 4);
2493 pHalData->EEPROMBluetoothRadioShared = ((tempval & 0x20) >> 5);
2494 } else {
2495 pHalData->EEPROMBluetoothCoexist = 0;
2496 pHalData->EEPROMBluetoothType = BT_RTL8723A;
2497 pHalData->EEPROMBluetoothAntNum = Ant_x2;
2498 pHalData->EEPROMBluetoothAntIsolation = 0;
2499 pHalData->EEPROMBluetoothRadioShared = BT_Radio_Shared;
2500 }
2501#ifdef CONFIG_8723AU_BT_COEXIST
2502 BT_InitHalVars(padapter);
2503#endif
2504}
2505
2506void
2507Hal_EfuseParseEEPROMVer(struct rtw_adapter *padapter,
2508 u8 *hwinfo, bool AutoLoadFail)
2509{
2510 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
2511
2512 if (!AutoLoadFail)
2513 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723A];
2514 else
2515 pHalData->EEPROMVersion = 1;
2516 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2517 ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
2518 pHalData->EEPROMVersion));
2519}
2520
2521void
2522rtl8723a_EfuseParseChnlPlan(struct rtw_adapter *padapter,
2523 u8 *hwinfo, bool AutoLoadFail)
2524{
2525 padapter->mlmepriv.ChannelPlan =
2526 hal_com_get_channel_plan23a(padapter, hwinfo ?
2527 hwinfo[EEPROM_ChannelPlan_8723A]:0xFF,
2528 padapter->registrypriv.channel_plan,
2529 RT_CHANNEL_DOMAIN_WORLD_WIDE_13,
2530 AutoLoadFail);
2531
2532 DBG_8723A("mlmepriv.ChannelPlan = 0x%02x\n",
2533 padapter->mlmepriv.ChannelPlan);
2534}
2535
2536void
2537Hal_EfuseParseCustomerID(struct rtw_adapter *padapter,
2538 u8 *hwinfo, bool AutoLoadFail)
2539{
2540 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
2541
2542 if (!AutoLoadFail) {
2543 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723A];
2544 pHalData->EEPROMSubCustomerID =
2545 hwinfo[EEPROM_SubCustomID_8723A];
2546 } else {
2547 pHalData->EEPROMCustomerID = 0;
2548 pHalData->EEPROMSubCustomerID = 0;
2549 }
2550 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2551 ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID));
2552 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2553 ("EEPROM SubCustomer ID: 0x%02x\n",
2554 pHalData->EEPROMSubCustomerID));
2555}
2556
2557void
2558Hal_EfuseParseAntennaDiversity(struct rtw_adapter *padapter,
2559 u8 *hwinfo, bool AutoLoadFail)
2560{
2561}
2562
2563void
2564Hal_EfuseParseRateIndicationOption(struct rtw_adapter *padapter,
2565 u8 *hwinfo, bool AutoLoadFail)
2566{
2567}
2568
2569void
2570Hal_EfuseParseXtal_8723A(struct rtw_adapter *pAdapter,
2571 u8 *hwinfo, u8 AutoLoadFail)
2572{
2573 struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
2574
2575 if (!AutoLoadFail) {
2576 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_K_8723A];
2577 if (pHalData->CrystalCap == 0xFF)
2578 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
2579 } else {
2580 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
2581 }
2582 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
2583 ("%s: CrystalCap = 0x%2x\n", __func__,
2584 pHalData->CrystalCap));
2585}
2586
2587void
2588Hal_EfuseParseThermalMeter_8723A(struct rtw_adapter *padapter,
2589 u8 *PROMContent, u8 AutoloadFail)
2590{
2591 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
2592
2593
2594
2595
2596 if (false == AutoloadFail)
2597 pHalData->EEPROMThermalMeter =
2598 PROMContent[EEPROM_THERMAL_METER_8723A];
2599 else
2600 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2601
2602 if ((pHalData->EEPROMThermalMeter == 0xff) || (true == AutoloadFail)) {
2603 pHalData->bAPKThermalMeterIgnore = true;
2604 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2605 }
2606
2607 DBG_8723A("%s: ThermalMeter = 0x%x\n", __func__,
2608 pHalData->EEPROMThermalMeter);
2609}
2610
2611void Hal_InitChannelPlan23a(struct rtw_adapter *padapter)
2612{
2613}
2614
2615static void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc)
2616{
2617 u16 *usPtr = (u16 *) ptxdesc;
2618 u32 count = 16;
2619 u32 index;
2620 u16 checksum = 0;
2621
2622
2623 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
2624
2625 for (index = 0; index < count; index++) {
2626 checksum ^= le16_to_cpu(*(usPtr + index));
2627 }
2628
2629 ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
2630}
2631
2632static void fill_txdesc_sectype(struct pkt_attrib *pattrib,
2633 struct txdesc_8723a *ptxdesc)
2634{
2635 if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
2636 switch (pattrib->encrypt) {
2637
2638 case _WEP40_:
2639 case _WEP104_:
2640 case _TKIP_:
2641 case _TKIP_WTMIC_:
2642 ptxdesc->sectype = 1;
2643 break;
2644
2645 case _AES_:
2646 ptxdesc->sectype = 3;
2647 break;
2648
2649 case _NO_PRIVACY_:
2650 default:
2651 break;
2652 }
2653 }
2654}
2655
2656static void fill_txdesc_vcs(struct pkt_attrib *pattrib,
2657 struct txdesc_8723a *ptxdesc)
2658{
2659
2660
2661 switch (pattrib->vcs_mode) {
2662 case RTS_CTS:
2663 ptxdesc->rtsen = 1;
2664 break;
2665
2666 case CTS_TO_SELF:
2667 ptxdesc->cts2self = 1;
2668 break;
2669
2670 case NONE_VCS:
2671 default:
2672 break;
2673 }
2674
2675 if (pattrib->vcs_mode) {
2676 ptxdesc->hw_rts_en = 1;
2677
2678
2679 if (pattrib->ht_en) {
2680 if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
2681 ptxdesc->rts_bw = 1;
2682
2683 switch (pattrib->ch_offset) {
2684 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
2685 ptxdesc->rts_sc = 0;
2686 break;
2687
2688 case HAL_PRIME_CHNL_OFFSET_LOWER:
2689 ptxdesc->rts_sc = 1;
2690 break;
2691
2692 case HAL_PRIME_CHNL_OFFSET_UPPER:
2693 ptxdesc->rts_sc = 2;
2694 break;
2695
2696 default:
2697 ptxdesc->rts_sc = 3;
2698 break;
2699 }
2700 }
2701 }
2702}
2703
2704static void fill_txdesc_phy(struct pkt_attrib *pattrib,
2705 struct txdesc_8723a *ptxdesc)
2706{
2707 if (pattrib->ht_en) {
2708 if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
2709 ptxdesc->data_bw = 1;
2710
2711 switch (pattrib->ch_offset) {
2712 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
2713 ptxdesc->data_sc = 0;
2714 break;
2715
2716 case HAL_PRIME_CHNL_OFFSET_LOWER:
2717 ptxdesc->data_sc = 1;
2718 break;
2719
2720 case HAL_PRIME_CHNL_OFFSET_UPPER:
2721 ptxdesc->data_sc = 2;
2722 break;
2723
2724 default:
2725 ptxdesc->data_sc = 3;
2726 break;
2727 }
2728 }
2729}
2730
2731static void rtl8723a_fill_default_txdesc(struct xmit_frame *pxmitframe,
2732 u8 *pbuf)
2733{
2734 struct rtw_adapter *padapter;
2735 struct hal_data_8723a *pHalData;
2736 struct dm_priv *pdmpriv;
2737 struct mlme_ext_priv *pmlmeext;
2738 struct mlme_ext_info *pmlmeinfo;
2739 struct pkt_attrib *pattrib;
2740 struct txdesc_8723a *ptxdesc;
2741 s32 bmcst;
2742
2743 padapter = pxmitframe->padapter;
2744 pHalData = GET_HAL_DATA(padapter);
2745 pdmpriv = &pHalData->dmpriv;
2746 pmlmeext = &padapter->mlmeextpriv;
2747 pmlmeinfo = &pmlmeext->mlmext_info;
2748
2749 pattrib = &pxmitframe->attrib;
2750 bmcst = is_multicast_ether_addr(pattrib->ra);
2751
2752 ptxdesc = (struct txdesc_8723a *)pbuf;
2753
2754 if (pxmitframe->frame_tag == DATA_FRAMETAG) {
2755 ptxdesc->macid = pattrib->mac_id;
2756
2757 if (pattrib->ampdu_en == true)
2758 ptxdesc->agg_en = 1;
2759 else
2760 ptxdesc->bk = 1;
2761
2762 ptxdesc->qsel = pattrib->qsel;
2763 ptxdesc->rate_id = pattrib->raid;
2764
2765 fill_txdesc_sectype(pattrib, ptxdesc);
2766
2767 ptxdesc->seq = pattrib->seqnum;
2768
2769 if ((pattrib->ether_type != 0x888e) &&
2770 (pattrib->ether_type != 0x0806) &&
2771 (pattrib->dhcp_pkt != 1)) {
2772
2773
2774 fill_txdesc_vcs(pattrib, ptxdesc);
2775 fill_txdesc_phy(pattrib, ptxdesc);
2776
2777 ptxdesc->rtsrate = 8;
2778 ptxdesc->data_ratefb_lmt = 0x1F;
2779 ptxdesc->rts_ratefb_lmt = 0xF;
2780
2781
2782 ptxdesc->datarate =
2783 pdmpriv->INIDATA_RATE[pattrib->mac_id];
2784
2785 } else {
2786
2787
2788
2789
2790 ptxdesc->bk = 1;
2791 ptxdesc->userate = 1;
2792 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
2793 ptxdesc->data_short = 1;
2794 ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate);
2795 }
2796 } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) {
2797
2798
2799
2800 ptxdesc->macid = pattrib->mac_id;
2801 ptxdesc->qsel = pattrib->qsel;
2802 ptxdesc->rate_id = pattrib->raid;
2803 ptxdesc->seq = pattrib->seqnum;
2804 ptxdesc->userate = 1;
2805 ptxdesc->rty_lmt_en = 1;
2806 ptxdesc->data_rt_lmt = 6;
2807
2808
2809 if (pxmitframe->ack_report)
2810 ptxdesc->ccx = 1;
2811
2812 ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate);
2813 } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) {
2814 RT_TRACE(_module_hal_xmit_c_, _drv_warning_,
2815 ("%s: TXAGG_FRAMETAG\n", __func__));
2816 } else {
2817 RT_TRACE(_module_hal_xmit_c_, _drv_warning_,
2818 ("%s: frame_tag = 0x%x\n", __func__,
2819 pxmitframe->frame_tag));
2820
2821 ptxdesc->macid = 4;
2822 ptxdesc->rate_id = 6;
2823 ptxdesc->seq = pattrib->seqnum;
2824 ptxdesc->userate = 1;
2825 ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate);
2826 }
2827
2828 ptxdesc->pktlen = pattrib->last_txcmdsz;
2829 ptxdesc->offset = TXDESC_SIZE + OFFSET_SZ;
2830 if (bmcst)
2831 ptxdesc->bmc = 1;
2832 ptxdesc->ls = 1;
2833 ptxdesc->fs = 1;
2834 ptxdesc->own = 1;
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847 if (!pattrib->qos_en) {
2848
2849 ptxdesc->hwseq_en = 1;
2850 ptxdesc->hwseq_sel = 0;
2851 }
2852}
2853
2854
2855
2856
2857
2858
2859
2860
2861void rtl8723a_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
2862{
2863 struct tx_desc *pdesc;
2864
2865 pdesc = (struct tx_desc *)pbuf;
2866 memset(pdesc, 0, sizeof(struct tx_desc));
2867
2868 rtl8723a_fill_default_txdesc(pxmitframe, pbuf);
2869
2870 pdesc->txdw0 = cpu_to_le32(pdesc->txdw0);
2871 pdesc->txdw1 = cpu_to_le32(pdesc->txdw1);
2872 pdesc->txdw2 = cpu_to_le32(pdesc->txdw2);
2873 pdesc->txdw3 = cpu_to_le32(pdesc->txdw3);
2874 pdesc->txdw4 = cpu_to_le32(pdesc->txdw4);
2875 pdesc->txdw5 = cpu_to_le32(pdesc->txdw5);
2876 pdesc->txdw6 = cpu_to_le32(pdesc->txdw6);
2877 pdesc->txdw7 = cpu_to_le32(pdesc->txdw7);
2878 rtl8723a_cal_txdesc_chksum(pdesc);
2879}
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889void rtl8723a_fill_fake_txdesc(struct rtw_adapter *padapter, u8 *pDesc,
2890 u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull)
2891{
2892 struct tx_desc *ptxdesc;
2893
2894
2895 ptxdesc = (struct tx_desc *)pDesc;
2896 memset(pDesc, 0, TXDESC_SIZE);
2897
2898
2899
2900 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
2901
2902
2903 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) <<
2904 OFFSET_SHT) & 0x00ff0000);
2905
2906
2907 ptxdesc->txdw0 |= cpu_to_le32(BufferLen & 0x0000ffff);
2908
2909
2910
2911 ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT << QSEL_SHT) & 0x00001f00);
2912
2913
2914
2915 if (IsPsPoll) {
2916 ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
2917 } else {
2918
2919 ptxdesc->txdw4 |= cpu_to_le32(BIT(7));
2920
2921 ptxdesc->txdw3 |= cpu_to_le32((8 << 28));
2922 }
2923
2924 if (true == IsBTQosNull) {
2925 ptxdesc->txdw2 |= cpu_to_le32(BIT(23));
2926 }
2927
2928
2929 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));
2930
2931
2932
2933
2934
2935 rtl8723a_cal_txdesc_chksum(ptxdesc);
2936}
2937
2938static void hw_var_set_opmode(struct rtw_adapter *padapter, u8 mode)
2939{
2940 u8 val8;
2941
2942 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
2943 StopTxBeacon(padapter);
2944
2945
2946 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM;
2947 SetBcnCtrlReg23a(padapter, val8, ~val8);
2948 } else if ((mode == _HW_STATE_ADHOC_) ) {
2949 ResumeTxBeacon(padapter);
2950
2951 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB;
2952 SetBcnCtrlReg23a(padapter, val8, ~val8);
2953 } else if (mode == _HW_STATE_AP_) {
2954#ifdef CONFIG_8723AU_BT_COEXIST
2955
2956 rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(padapter);
2957#endif
2958
2959 ResumeTxBeacon(padapter);
2960
2961 val8 = DIS_TSF_UDT | DIS_BCNQ_SUB;
2962 SetBcnCtrlReg23a(padapter, val8, ~val8);
2963
2964
2965
2966
2967
2968 rtw_write32(padapter, REG_RCR, 0x7000228e);
2969
2970 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
2971
2972 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
2973
2974
2975 rtw_write8(padapter, REG_BCNDMATIM, 0x02);
2976 rtw_write8(padapter, REG_DRVERLYINT, 0x05);
2977 rtw_write8(padapter, REG_ATIMWND, 0x0a);
2978 rtw_write16(padapter, REG_BCNTCFG, 0x00);
2979 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
2980
2981 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);
2982
2983
2984 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
2985
2986
2987
2988
2989 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION |
2990 EN_TXBCN_RPT | DIS_BCNQ_SUB;
2991 SetBcnCtrlReg23a(padapter, val8, ~val8);
2992 }
2993
2994 val8 = rtw_read8(padapter, MSR);
2995 val8 = (val8 & 0xC) | mode;
2996 rtw_write8(padapter, MSR, val8);
2997}
2998
2999static void hw_var_set_macaddr(struct rtw_adapter *padapter, u8 *val)
3000{
3001 u8 idx = 0;
3002 u32 reg_macid;
3003
3004 reg_macid = REG_MACID;
3005
3006 for (idx = 0; idx < 6; idx++)
3007 rtw_write8(padapter, (reg_macid + idx), val[idx]);
3008}
3009
3010static void hw_var_set_bssid(struct rtw_adapter *padapter, u8 *val)
3011{
3012 u8 idx = 0;
3013 u32 reg_bssid;
3014
3015 reg_bssid = REG_BSSID;
3016
3017 for (idx = 0; idx < 6; idx++)
3018 rtw_write8(padapter, (reg_bssid + idx), val[idx]);
3019}
3020
3021static void hw_var_set_correct_tsf(struct rtw_adapter *padapter)
3022{
3023 u64 tsf;
3024 u32 reg_tsftr;
3025 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3026 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3027
3028
3029
3030 tsf = pmlmeext->TSFValue -
3031 rtw_modular6423a(pmlmeext->TSFValue,
3032 (pmlmeinfo->bcn_interval * 1024)) - 1024;
3033
3034 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
3035 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
3036
3037
3038
3039 StopTxBeacon(padapter);
3040 }
3041
3042 reg_tsftr = REG_TSFTR;
3043
3044
3045 SetBcnCtrlReg23a(padapter, 0, EN_BCN_FUNCTION);
3046
3047 rtw_write32(padapter, reg_tsftr, tsf);
3048 rtw_write32(padapter, reg_tsftr + 4, tsf >> 32);
3049
3050
3051 SetBcnCtrlReg23a(padapter, EN_BCN_FUNCTION, 0);
3052
3053 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
3054 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
3055 ResumeTxBeacon(padapter);
3056}
3057
3058static void hw_var_set_mlme_disconnect(struct rtw_adapter *padapter)
3059{
3060
3061 rtw_write16(padapter, REG_RXFLTMAP2, 0);
3062
3063
3064 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
3065
3066
3067 SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0);
3068}
3069
3070static void hw_var_set_mlme_join(struct rtw_adapter *padapter, u8 type)
3071{
3072 u8 RetryLimit = 0x30;
3073
3074 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
3075 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3076
3077 if (type == 0) {
3078 u32 v32;
3079
3080
3081
3082
3083 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
3084
3085 v32 = rtw_read32(padapter, REG_RCR);
3086 v32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
3087 rtw_write32(padapter, REG_RCR, v32);
3088
3089 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
3090 RetryLimit =
3091 (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
3092 else
3093 RetryLimit = 0x7;
3094 } else if (type == 1) {
3095
3096
3097 rtw_write16(padapter, REG_RXFLTMAP2, 0);
3098 } else if (type == 2) {
3099
3100 SetBcnCtrlReg23a(padapter, 0, DIS_TSF_UDT);
3101
3102 if (check_fwstate(pmlmepriv,
3103 WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
3104
3105 rtw_write8(padapter, 0x542, 0x02);
3106 RetryLimit = 0x7;
3107 }
3108 }
3109
3110 rtw_write16(padapter, REG_RL,
3111 RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit <<
3112 RETRY_LIMIT_LONG_SHIFT);
3113
3114#ifdef CONFIG_8723AU_BT_COEXIST
3115 switch (type) {
3116 case 0:
3117
3118 BT_WifiAssociateNotify(padapter, true);
3119 break;
3120 case 1:
3121
3122 BT_WifiAssociateNotify(padapter, false);
3123 break;
3124 case 2:
3125
3126
3127 break;
3128 }
3129#endif
3130}
3131
3132void SetHwReg8723A(struct rtw_adapter *padapter, u8 variable, u8 *val)
3133{
3134 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
3135 u32 *val32 = (u32 *)val;
3136
3137 switch (variable) {
3138 case HW_VAR_MEDIA_STATUS:
3139 rtl8723a_set_media_status(padapter, *val);
3140 break;
3141
3142 case HW_VAR_MEDIA_STATUS1:
3143 rtl8723a_set_media_status1(padapter, *val);
3144 break;
3145
3146 case HW_VAR_SET_OPMODE:
3147 hw_var_set_opmode(padapter, *val);
3148 break;
3149
3150 case HW_VAR_MAC_ADDR:
3151 hw_var_set_macaddr(padapter, val);
3152 break;
3153
3154 case HW_VAR_BSSID:
3155 hw_var_set_bssid(padapter, val);
3156 break;
3157
3158 case HW_VAR_BASIC_RATE:
3159 HalSetBrateCfg23a(padapter, val);
3160 break;
3161
3162 case HW_VAR_TXPAUSE:
3163 rtl8723a_set_tx_pause(padapter, *val);
3164 break;
3165
3166 case HW_VAR_BCN_FUNC:
3167 rtl8723a_set_bcn_func(padapter, *val);
3168 break;
3169
3170 case HW_VAR_CORRECT_TSF:
3171 hw_var_set_correct_tsf(padapter);
3172 break;
3173
3174 case HW_VAR_CHECK_BSSID:
3175 rtl8723a_check_bssid(padapter, *val);
3176 break;
3177
3178 case HW_VAR_MLME_DISCONNECT:
3179 hw_var_set_mlme_disconnect(padapter);
3180 break;
3181
3182 case HW_VAR_MLME_SITESURVEY:
3183 rtl8723a_mlme_sitesurvey(padapter, *val);
3184 break;
3185
3186 case HW_VAR_MLME_JOIN:
3187 hw_var_set_mlme_join(padapter, *val);
3188 break;
3189
3190 case HW_VAR_ON_RCR_AM:
3191 rtl8723a_on_rcr_am(padapter);
3192 break;
3193
3194 case HW_VAR_OFF_RCR_AM:
3195 rtl8723a_off_rcr_am(padapter);
3196 break;
3197
3198 case HW_VAR_BEACON_INTERVAL:
3199 rtl8723a_set_beacon_interval(padapter, *((u16 *) val));
3200 break;
3201
3202 case HW_VAR_SLOT_TIME:
3203 rtl8723a_set_slot_time(padapter, *val);
3204 break;
3205
3206 case HW_VAR_RESP_SIFS:
3207 rtl8723a_set_resp_sifs(padapter, val[0], val[1],
3208 val[2], val[3]);
3209 break;
3210
3211 case HW_VAR_ACK_PREAMBLE:
3212 rtl8723a_ack_preamble(padapter, *val);
3213 break;
3214
3215 case HW_VAR_SEC_CFG:
3216 rtl8723a_set_sec_cfg(padapter, *val);
3217 break;
3218
3219 case HW_VAR_DM_FLAG:
3220 rtl8723a_odm_support_ability_write(padapter, *val32);
3221 break;
3222 case HW_VAR_DM_FUNC_OP:
3223 rtl8723a_odm_support_ability_backup(padapter, *val);
3224 break;
3225 case HW_VAR_DM_FUNC_SET:
3226 rtl8723a_odm_support_ability_set(padapter, *val32);
3227 break;
3228
3229 case HW_VAR_DM_FUNC_CLR:
3230 rtl8723a_odm_support_ability_clr(padapter, *val32);
3231 break;
3232
3233 case HW_VAR_CAM_EMPTY_ENTRY:
3234 rtl8723a_cam_empty_entry(padapter, *val);
3235 break;
3236
3237 case HW_VAR_CAM_INVALID_ALL:
3238 rtl8723a_cam_invalid_all(padapter);
3239 break;
3240
3241 case HW_VAR_CAM_WRITE:
3242 rtl8723a_cam_write(padapter, val32[0], val32[1]);
3243 break;
3244
3245 case HW_VAR_AC_PARAM_VO:
3246 rtl8723a_set_ac_param_vo(padapter, *val32);
3247 break;
3248
3249 case HW_VAR_AC_PARAM_VI:
3250 rtl8723a_set_ac_param_vi(padapter, *val32);
3251 break;
3252
3253 case HW_VAR_AC_PARAM_BE:
3254 rtl8723a_set_ac_param_be(padapter, *val32);
3255 break;
3256
3257 case HW_VAR_AC_PARAM_BK:
3258 rtl8723a_set_ac_param_bk(padapter, *val32);
3259 break;
3260
3261 case HW_VAR_ACM_CTRL:
3262 rtl8723a_set_acm_ctrl(padapter, *val);
3263 break;
3264
3265 case HW_VAR_AMPDU_MIN_SPACE:
3266 rtl8723a_set_ampdu_min_space(padapter, *val);
3267 break;
3268
3269 case HW_VAR_AMPDU_FACTOR:
3270 rtl8723a_set_ampdu_factor(padapter, *val);
3271 break;
3272
3273 case HW_VAR_RXDMA_AGG_PG_TH:
3274 rtl8723a_set_rxdma_agg_pg_th(padapter, *val);
3275 break;
3276
3277 case HW_VAR_H2C_FW_PWRMODE:
3278 rtl8723a_set_FwPwrMode_cmd(padapter, *val);
3279 break;
3280
3281 case HW_VAR_H2C_FW_JOINBSSRPT:
3282 rtl8723a_set_FwJoinBssReport_cmd(padapter, *val);
3283 break;
3284
3285#ifdef CONFIG_8723AU_P2P
3286 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
3287 rtl8723a_set_p2p_ps_offload_cmd(padapter, *val);
3288 break;
3289#endif
3290
3291 case HW_VAR_INITIAL_GAIN:
3292 rtl8723a_set_initial_gain(padapter, *val32);
3293 break;
3294 case HW_VAR_EFUSE_BYTES:
3295 pHalData->EfuseUsedBytes = *((u16 *) val);
3296 break;
3297 case HW_VAR_EFUSE_BT_BYTES:
3298 pHalData->BTEfuseUsedBytes = *((u16 *) val);
3299 break;
3300 case HW_VAR_FIFO_CLEARN_UP:
3301 rtl8723a_fifo_cleanup(padapter);
3302 break;
3303 case HW_VAR_CHECK_TXBUF:
3304 break;
3305 case HW_VAR_APFM_ON_MAC:
3306 rtl8723a_set_apfm_on_mac(padapter, *val);
3307 break;
3308
3309 case HW_VAR_NAV_UPPER:
3310 rtl8723a_set_nav_upper(padapter, *val32);
3311 break;
3312 case HW_VAR_BCN_VALID:
3313 rtl8723a_bcn_valid(padapter);
3314 break;
3315 default:
3316 break;
3317 }
3318
3319}
3320
3321void GetHwReg8723A(struct rtw_adapter *padapter, u8 variable, u8 *val)
3322{
3323 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
3324
3325 switch (variable) {
3326 case HW_VAR_BASIC_RATE:
3327 *((u16 *) val) = pHalData->BasicRateSet;
3328 break;
3329
3330 case HW_VAR_TXPAUSE:
3331 *val = rtw_read8(padapter, REG_TXPAUSE);
3332 break;
3333
3334 case HW_VAR_BCN_VALID:
3335
3336 val[0] = (BIT0 & rtw_read8(padapter, REG_TDECTRL + 2)) ? true :
3337 false;
3338 break;
3339
3340 case HW_VAR_RF_TYPE:
3341 *val = pHalData->rf_type;
3342 break;
3343
3344 case HW_VAR_DM_FLAG:
3345 {
3346 struct dm_odm_t *podmpriv = &pHalData->odmpriv;
3347 *((u32 *) val) = podmpriv->SupportAbility;
3348 }
3349 break;
3350
3351 case HW_VAR_FWLPS_RF_ON:
3352 {
3353
3354 u32 valRCR;
3355
3356 if ((padapter->bSurpriseRemoved == true) ||
3357 (padapter->pwrctrlpriv.rf_pwrstate == rf_off)) {
3358
3359
3360 *val = true;
3361 } else {
3362 valRCR = rtw_read32(padapter, REG_RCR);
3363 valRCR &= 0x00070000;
3364 if (valRCR)
3365 *val = false;
3366 else
3367 *val = true;
3368 }
3369 }
3370 break;
3371 case HW_VAR_EFUSE_BYTES:
3372 *((u16 *) val) = pHalData->EfuseUsedBytes;
3373 break;
3374
3375 case HW_VAR_EFUSE_BT_BYTES:
3376 *((u16 *) val) = pHalData->BTEfuseUsedBytes;
3377 break;
3378
3379 case HW_VAR_APFM_ON_MAC:
3380 *val = pHalData->bMacPwrCtrlOn;
3381 break;
3382 case HW_VAR_CHK_HI_QUEUE_EMPTY:
3383 *val =
3384 ((rtw_read32(padapter, REG_HGQ_INFORMATION) & 0x0000ff00) ==
3385 0) ? true : false;
3386 break;
3387 }
3388}
3389
3390#ifdef CONFIG_8723AU_BT_COEXIST
3391
3392void rtl8723a_SingleDualAntennaDetection(struct rtw_adapter *padapter)
3393{
3394 struct hal_data_8723a *pHalData;
3395 struct dm_odm_t *pDM_Odm;
3396 struct sw_ant_sw *pDM_SWAT_Table;
3397 u8 i;
3398
3399 pHalData = GET_HAL_DATA(padapter);
3400 pDM_Odm = &pHalData->odmpriv;
3401 pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
3402
3403
3404
3405
3406
3407
3408
3409
3410 if (!pHalData->bAntennaDetected) {
3411 u8 btAntNum = BT_GetPGAntNum(padapter);
3412
3413
3414 if (btAntNum == Ant_x2)
3415 pDM_SWAT_Table->ANTB_ON = true;
3416 else if (btAntNum == Ant_x1)
3417 pDM_SWAT_Table->ANTB_ON = false;
3418 else
3419 pDM_SWAT_Table->ANTB_ON = true;
3420
3421 if (pHalData->CustomerID != RT_CID_TOSHIBA) {
3422 for (i = 0; i < MAX_ANTENNA_DETECTION_CNT; i++) {
3423 if (ODM_SingleDualAntennaDetection
3424 (&pHalData->odmpriv, ANTTESTALL) == true)
3425 break;
3426 }
3427
3428
3429 if (btAntNum == Ant_x2)
3430 BT_SetBtCoexCurrAntNum(padapter,
3431 pDM_SWAT_Table->
3432 ANTB_ON ? 2 : 1);
3433 }
3434 pHalData->bAntennaDetected = true;
3435 }
3436}
3437#endif
3438
3439void rtl8723a_clone_haldata(struct rtw_adapter *dst_adapter,
3440 struct rtw_adapter *src_adapter)
3441{
3442 memcpy(dst_adapter->HalData, src_adapter->HalData,
3443 dst_adapter->hal_data_sz);
3444}
3445
3446void rtl8723a_start_thread(struct rtw_adapter *padapter)
3447{
3448}
3449
3450void rtl8723a_stop_thread(struct rtw_adapter *padapter)
3451{
3452}
3453