1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2017 Realtek Corporation.
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 <rtl8723d_hal.h>
18 #include "hal_com_h2c.h"
19 #include <hal_com.h>
20 #include "hal8723d_fw.h"
21
22 #ifndef CONFIG_DLFW_TXPKT
23 #define DL_FW_MAX 15
24 #else
25 #define FW_DOWNLOAD_SIZE_8723D 8192
26 #endif
27
28 static void
_FWDownloadEnable(PADAPTER padapter,BOOLEAN enable)29 _FWDownloadEnable(
30 PADAPTER padapter,
31 BOOLEAN enable
32 )
33 {
34 u8 tmp, count = 0;
35
36 if (enable) {
37 /* 8051 enable */
38 tmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
39 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, tmp | 0x04);
40
41 tmp = rtw_read8(padapter, REG_MCUFWDL);
42 rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
43
44 do {
45 tmp = rtw_read8(padapter, REG_MCUFWDL);
46 if (tmp & 0x01)
47 break;
48 rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
49 rtw_msleep_os(1);
50 } while (count++ < 100);
51 if (count > 0)
52 RTW_INFO("%s: !!!!!!!!Write 0x80 Fail!: count = %d\n", __func__, count);
53
54 /* 8051 reset */
55 tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
56 rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
57 } else {
58 /* MCU firmware download disable. */
59 tmp = rtw_read8(padapter, REG_MCUFWDL);
60 rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
61 }
62 }
63
64 #ifdef CONFIG_USB_HCI
_BlockWrite(struct _ADAPTER * padapter,void * buffer,u32 buffSize)65 static int _BlockWrite(struct _ADAPTER *padapter, void *buffer, u32 buffSize)
66 {
67 int ret = _SUCCESS;
68
69 u32 blockSize_p1 = 254; /* Phase #1 */
70 u32 blockSize_p2 = 8; /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */
71 u32 blockSize_p3 = 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */
72 u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
73 u32 remainSize_p1 = 0, remainSize_p2 = 0;
74 u8 *bufferPtr = (u8 *)buffer;
75 u32 i = 0, offset = 0;
76
77
78 /* Phase #1 */
79 blockCount_p1 = buffSize / blockSize_p1;
80 remainSize_p1 = buffSize % blockSize_p1;
81
82 for (i = 0; i < blockCount_p1; i++) {
83 ret = rtw_writeN(padapter,
84 (FW_8723D_START_ADDRESS + i * blockSize_p1),
85 blockSize_p1, (bufferPtr + i * blockSize_p1));
86 if (ret == _FAIL) {
87 RTW_ERR("====>%s %d i:%d\n", __func__, __LINE__, i);
88 goto exit;
89 }
90 }
91
92 /* Phase #2 */
93 if (remainSize_p1) {
94 offset = blockCount_p1 * blockSize_p1;
95
96 blockCount_p2 = remainSize_p1 / blockSize_p2;
97 remainSize_p2 = remainSize_p1 % blockSize_p2;
98
99 for (i = 0; i < blockCount_p2; i++) {
100 ret = rtw_writeN(padapter,
101 (FW_8723D_START_ADDRESS + offset + i * blockSize_p2),
102 blockSize_p2,
103 (bufferPtr + offset + i * blockSize_p2));
104 if (ret == _FAIL)
105 goto exit;
106 }
107 }
108
109 /* Phase #3 */
110 if (remainSize_p2) {
111 offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
112
113 blockCount_p3 = remainSize_p2 / blockSize_p3;
114
115 for (i = 0 ; i < blockCount_p3 ; i++) {
116 ret = rtw_write8(padapter, (FW_8723D_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
117 if (ret == _FAIL) {
118 RTW_ERR("====>%s %d i:%d\n", __func__, __LINE__, i);
119 goto exit;
120 }
121 }
122 }
123
124 exit:
125 return ret;
126 }
127 #else /* !CONFIG_USB_HCI */
_BlockWrite(struct _ADAPTER * padapter,void * buffer,u32 buffSize)128 static int _BlockWrite(struct _ADAPTER *padapter, void *buffer, u32 buffSize)
129 {
130 int ret = _SUCCESS;
131
132 u32 blockSize_p1 = 4; /* Phase #1 : PCI muse use 4-byte write to download FW */
133 /* Phase #2 : write the remnant of FW image. */
134 u32 blockCount_p1 = 0;
135 u32 remainSize_p1 = 0;
136 u8 *bufferPtr = (u8 *)buffer;
137 u32 i = 0, offset = 0;
138 #ifdef CONFIG_PCI_HCI
139 u8 remainFW[4] = {0, 0, 0, 0};
140 #endif
141
142
143 /* Phase #1 */
144 blockCount_p1 = buffSize / blockSize_p1;
145 remainSize_p1 = buffSize % blockSize_p1;
146
147 for (i = 0; i < blockCount_p1; i++) {
148 ret = rtw_write32(padapter,
149 (FW_8723D_START_ADDRESS + i * blockSize_p1),
150 le32_to_cpu(*((u32 *)(bufferPtr + i * blockSize_p1))));
151 if (ret == _FAIL) {
152 RTW_ERR("====>%s %d i:%d\n", __func__, __LINE__, i);
153 goto exit;
154 }
155 }
156
157 /* Phase #2 */
158 if (remainSize_p1) {
159 offset = (blockCount_p1 * blockSize_p1);
160 bufferPtr += offset;
161 #ifdef CONFIG_PCI_HCI
162 switch (remainSize_p1) {
163 case 3:
164 remainFW[2] = *(bufferPtr + 2);
165 case 2:
166 remainFW[1] = *(bufferPtr + 1);
167 case 1:
168 remainFW[0] = *(bufferPtr);
169 ret = rtw_write32(padapter,
170 (FW_8723D_START_ADDRESS + offset),
171 le32_to_cpu(*(u32 *)remainFW));
172 }
173 #else /* !CONFIG_PCI_HCI */
174 for (i = 0; i < remainSize_p1; i++) {
175 ret = rtw_write8(padapter,
176 (FW_8723D_START_ADDRESS + offset + i),
177 *(bufferPtr + i));
178 if (ret == _FAIL) {
179 RTW_ERR("====>%s %d i:%d\n", __func__, __LINE__, i);
180 goto exit;
181 }
182 }
183 #endif /* !CONFIG_PCI_HCI */
184 }
185
186 exit:
187 return ret;
188 }
189 #endif /* !CONFIG_USB_HCI */
190
191 static int
_PageWrite(PADAPTER padapter,u32 page,void * buffer,u32 size)192 _PageWrite(
193 PADAPTER padapter,
194 u32 page,
195 void *buffer,
196 u32 size
197 )
198 {
199 u8 value8;
200 u8 u8Page = (u8)(page & 0x07);
201
202 value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
203 rtw_write8(padapter, REG_MCUFWDL + 2, value8);
204
205 return _BlockWrite(padapter, buffer, size);
206 }
207 #ifdef CONFIG_PCI_HCI
208 static void
_FillDummy(u8 * pFwBuf,u32 * pFwLen)209 _FillDummy(
210 u8 *pFwBuf,
211 u32 *pFwLen
212 )
213 {
214 u32 FwLen = *pFwLen;
215 u8 remain = (u8)(FwLen % 4);
216
217 remain = (remain == 0) ? 0 : (4 - remain);
218
219 while (remain > 0) {
220 pFwBuf[FwLen] = 0;
221 FwLen++;
222 remain--;
223 }
224
225 *pFwLen = FwLen;
226 }
227 #endif
228 static int
_WriteFW(PADAPTER padapter,void * buffer,u32 size)229 _WriteFW(
230 PADAPTER padapter,
231 void *buffer,
232 u32 size
233 )
234 {
235 /* Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */
236 int ret = _SUCCESS;
237 u32 pageNums, remainSize;
238 u32 page, offset;
239 u8 *bufferPtr = (u8 *)buffer;
240
241 #ifdef CONFIG_PCI_HCI
242 /* 20100120 Joseph: Add for 88CE normal chip. */
243 /* Fill in zero to make firmware image to dword alignment. */
244 _FillDummy(bufferPtr, &size);
245 #endif
246
247 pageNums = size / MAX_DLFW_PAGE_SIZE;
248 /* RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4\n")); */
249 remainSize = size % MAX_DLFW_PAGE_SIZE;
250
251 for (page = 0; page < pageNums; page++) {
252 offset = page * MAX_DLFW_PAGE_SIZE;
253 ret = _PageWrite(padapter, page, bufferPtr + offset, MAX_DLFW_PAGE_SIZE);
254
255 if (ret == _FAIL) {
256 printk(KERN_ERR "====>%s %d\n", __func__, __LINE__);
257 goto exit;
258 }
259 }
260 if (remainSize) {
261 offset = pageNums * MAX_DLFW_PAGE_SIZE;
262 page = pageNums;
263 ret = _PageWrite(padapter, page, bufferPtr + offset, remainSize);
264
265 if (ret == _FAIL) {
266 printk(KERN_ERR "====>%s %d\n", __func__, __LINE__);
267 goto exit;
268 }
269 }
270
271 exit:
272 return ret;
273 }
274
_8051Reset8723(PADAPTER padapter)275 void _8051Reset8723(PADAPTER padapter)
276 {
277 u8 cpu_rst;
278 u8 io_rst;
279
280 #if 0
281 io_rst = rtw_read8(padapter, REG_RSV_CTRL);
282 rtw_write8(padapter, REG_RSV_CTRL, io_rst & (~BIT(1)));
283 #endif
284
285 /* Reset 8051(WLMCU) IO wrapper */
286 /* 0x1c[8] = 0 */
287 /* Suggested by Isaac@SD1 and Gimmy@SD1, coding by Lucas@20130624 */
288 io_rst = rtw_read8(padapter, REG_RSV_CTRL + 1);
289 io_rst &= ~BIT(0);
290 rtw_write8(padapter, REG_RSV_CTRL + 1, io_rst);
291
292 cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
293 cpu_rst &= ~BIT(2);
294 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, cpu_rst);
295
296 #if 0
297 io_rst = rtw_read8(padapter, REG_RSV_CTRL);
298 rtw_write8(padapter, REG_RSV_CTRL, io_rst & (~BIT(1)));
299 #endif
300
301 /* Enable 8051 IO wrapper */
302 /* 0x1c[8] = 1 */
303 io_rst = rtw_read8(padapter, REG_RSV_CTRL + 1);
304 io_rst |= BIT(0);
305 rtw_write8(padapter, REG_RSV_CTRL + 1, io_rst);
306
307 cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
308 cpu_rst |= BIT(2);
309 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, cpu_rst);
310
311 RTW_INFO("%s: Finish\n", __FUNCTION__);
312 }
313
polling_fwdl_chksum(_adapter * adapter,u32 min_cnt,u32 timeout_ms)314 static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
315 {
316 s32 ret = _FAIL;
317 u32 value32;
318 systime start = rtw_get_current_time();
319 u32 cnt = 0;
320
321 /* polling CheckSum report */
322 do {
323 cnt++;
324 value32 = rtw_read32(adapter, REG_MCUFWDL);
325 if (value32 & FWDL_ChkSum_rpt || RTW_CANNOT_IO(adapter))
326 break;
327 rtw_yield_os();
328 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
329
330 if (!(value32 & FWDL_ChkSum_rpt))
331 goto exit;
332
333 if (rtw_fwdl_test_trigger_chksum_fail())
334 goto exit;
335
336 ret = _SUCCESS;
337
338 exit:
339 RTW_INFO("%s: Checksum report %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
340 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), value32);
341
342 return ret;
343 }
344
_FWFreeToGo(_adapter * adapter,u32 min_cnt,u32 timeout_ms)345 static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
346 {
347 s32 ret = _FAIL;
348 u32 value32;
349 systime start = rtw_get_current_time();
350 u32 cnt = 0;
351 u32 value_to_check = 0;
352 u32 value_expected = (MCUFWDL_RDY | FWDL_ChkSum_rpt | WINTINI_RDY | RAM_DL_SEL);
353
354 value32 = rtw_read32(adapter, REG_MCUFWDL);
355 value32 |= MCUFWDL_RDY;
356 value32 &= ~WINTINI_RDY;
357 rtw_write32(adapter, REG_MCUFWDL, value32);
358
359 _8051Reset8723(adapter);
360
361 /* polling for FW ready */
362 do {
363 cnt++;
364 value32 = rtw_read32(adapter, REG_MCUFWDL);
365 value_to_check = value32 & value_expected;
366 if ((value_to_check == value_expected) || RTW_CANNOT_IO(adapter))
367 break;
368 rtw_yield_os();
369 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
370
371 if (value_to_check != value_expected)
372 goto exit;
373
374 if (rtw_fwdl_test_trigger_wintint_rdy_fail())
375 goto exit;
376
377 ret = _SUCCESS;
378
379 exit:
380 RTW_INFO("%s: Polling FW ready %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
381 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), value32);
382
383 return ret;
384 }
385
386 #define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
387
rtl8723d_FirmwareSelfReset(PADAPTER padapter)388 void rtl8723d_FirmwareSelfReset(PADAPTER padapter)
389 {
390 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
391 u8 u1bTmp;
392 u8 Delay = 100;
393
394 if (!(IS_FW_81xxC(padapter) &&
395 ((pHalData->firmware_version < 0x21) ||
396 (pHalData->firmware_version == 0x21 &&
397 pHalData->firmware_sub_version < 0x01)))) { /* after 88C Fw v33.1 */
398 /* 0x1cf=0x20. Inform 8051 to reset. 2009.12.25. tynli_test */
399 rtw_write8(padapter, REG_HMETFR + 3, 0x20);
400
401 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
402 while (u1bTmp & BIT(2)) {
403 Delay--;
404 if (Delay == 0)
405 break;
406 rtw_udelay_os(50);
407 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
408 }
409
410 if (Delay == 0) {
411 /* force firmware reset */
412 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
413 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2)));
414 }
415 }
416 }
417
418 #ifdef CONFIG_FILE_FWIMG
419 u8 FwBuffer[FW_8723D_SIZE];
420 #endif /* CONFIG_FILE_FWIMG */
421
422 #ifdef CONFIG_MP_INCLUDED
_WriteBTFWtoTxPktBuf8723D(PADAPTER Adapter,void * buffer,u32 FwBufLen,u8 times)423 int _WriteBTFWtoTxPktBuf8723D(
424 PADAPTER Adapter,
425 void *buffer,
426 u32 FwBufLen,
427 u8 times
428 )
429 {
430 int rtStatus = _SUCCESS;
431 /* u32 value32; */
432 /* u8 numHQ, numLQ, numPubQ;//, txpktbuf_bndy; */
433 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
434 /* PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); */
435 u8 BcnValidReg;
436 u8 count = 0, DLBcnCount = 0;
437 u8 *FwbufferPtr = (u8 *)buffer;
438 /* PRT_TCB pTcb, ptempTcb; */
439 /* PRT_TX_LOCAL_BUFFER pBuf; */
440
441 u8 *ReservedPagePacket = NULL;
442 u8 *pGenBufReservedPagePacket = NULL;
443 u32 TotalPktLen, txpktbuf_bndy;
444 /* u8 tmpReg422; */
445 /* u8 u1bTmp; */
446 u8 *pframe;
447 struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv);
448 struct xmit_frame *pmgntframe;
449 struct pkt_attrib *pattrib;
450 u8 txdesc_offset = TXDESC_OFFSET;
451 u8 val8, RegFwHwTxQCtrl;
452 #ifdef CONFIG_PCI_HCI
453 u8 u1bTmp;
454 #endif
455
456 #if 1/* #ifdef CONFIG_PCI_HCI */
457 TotalPktLen = FwBufLen;
458 #else
459 TotalPktLen = FwBufLen + pHalData->HWDescHeadLength;
460 #endif
461
462 if ((TotalPktLen + TXDESC_OFFSET) > MAX_CMDBUF_SZ) {
463 RTW_INFO(" WARNING %s => Total packet len = %d > MAX_CMDBUF_SZ:%d\n"
464 , __FUNCTION__, (TotalPktLen + TXDESC_OFFSET), MAX_CMDBUF_SZ);
465 return _FAIL;
466 }
467
468 pGenBufReservedPagePacket = rtw_zmalloc(TotalPktLen);/* GetGenTempBuffer (Adapter, TotalPktLen); */
469 if (!pGenBufReservedPagePacket)
470 return _FAIL;
471
472 ReservedPagePacket = (u8 *)pGenBufReservedPagePacket;
473
474 _rtw_memset(ReservedPagePacket, 0, TotalPktLen);
475
476 #if 1/* #ifdef CONFIG_PCI_HCI */
477 _rtw_memcpy(ReservedPagePacket, FwbufferPtr, FwBufLen);
478
479 #else
480 PlatformMoveMemory(ReservedPagePacket + Adapter->HWDescHeadLength , FwbufferPtr, FwBufLen);
481 #endif
482
483 /* --------------------------------------------------------- */
484 /* 1. Pause BCN */
485 /* --------------------------------------------------------- */
486 /* Set REG_CR bit 8. DMA beacon by SW. */
487 #ifdef CONFIG_PCI_HCI
488 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR + 1);
489 PlatformEFIOWrite1Byte(Adapter, REG_CR + 1, (u1bTmp | BIT(0)));
490 #else
491 /* Remove for temparaily because of the code on v2002 is not sync to MERGE_TMEP for USB/SDIO. */
492 /* De not remove this part on MERGE_TEMP. by tynli. */
493 #endif
494
495 /* Disable Hw protection for a time which revserd for Hw sending beacon. */
496 /* Fix download reserved page packet fail that access collision with the protection time. */
497 /* 2010.05.11. Added by tynli. */
498 val8 = rtw_read8(Adapter, REG_BCN_CTRL);
499 val8 &= ~EN_BCN_FUNCTION;
500 val8 |= DIS_TSF_UDT;
501 rtw_write8(Adapter, REG_BCN_CTRL, val8);
502
503 #if 0/* #ifdef CONFIG_PCI_HCI */
504 tmpReg422 = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2);
505 if (tmpReg422 & BIT(6))
506 bRecover = TRUE;
507 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, tmpReg422 & (~BIT(6)));
508 #else
509 /* Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. */
510 RegFwHwTxQCtrl = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2);
511
512 RegFwHwTxQCtrl &= (~BIT(6));
513 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, RegFwHwTxQCtrl);
514 #endif
515
516 /* --------------------------------------------------------- */
517 /* 2. Adjust LLT table to an even boundary. */
518 /* --------------------------------------------------------- */
519 #if 0/* #ifdef CONFIG_SDIO_HCI */
520 txpktbuf_bndy = 10; /* rsvd page start address should be an even value. */
521 rtStatus = InitLLTTable8723DS(Adapter, txpktbuf_bndy);
522 if (RT_STATUS_SUCCESS != rtStatus) {
523 RTW_INFO("_CheckWLANFwPatchBTFwReady_8723D(): Failed to init LLT!\n");
524 return RT_STATUS_FAILURE;
525 }
526
527 /* Init Tx boundary. */
528 PlatformEFIOWrite1Byte(Adapter, REG_DWBCN0_CTRL_8723D + 1, (u8)txpktbuf_bndy);
529 #endif
530
531
532 /* --------------------------------------------------------- */
533 /* 3. Write Fw to Tx packet buffer by reseverd page. */
534 /* --------------------------------------------------------- */
535 do {
536 /* download rsvd page. */
537 /* Clear beacon valid check bit. */
538 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 2);
539 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL + 2, BcnValidReg & (~BIT(0)));
540
541 /* BT patch is big, we should set 0x209 < 0x40 suggested from Gimmy */
542
543 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL + 1, (0x90 - 0x20 * (times - 1)));
544 RTW_INFO("0x209:0x%x\n", PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 1));
545
546 #if 0
547 /* Acquice TX spin lock before GetFwBuf and send the packet to prevent system deadlock. */
548 /* Advertised by Roger. Added by tynli. 2010.02.22. */
549 PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
550 if (MgntGetFWBuffer(Adapter, &pTcb, &pBuf)) {
551 PlatformMoveMemory(pBuf->Buffer.VirtualAddress, ReservedPagePacket, TotalPktLen);
552 CmdSendPacket(Adapter, pTcb, pBuf, TotalPktLen, DESC_PACKET_TYPE_NORMAL, FALSE);
553 } else
554 dbgdump("SetFwRsvdPagePkt(): MgntGetFWBuffer FAIL!!!!!!!!.\n");
555 PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
556 #else
557 /*---------------------------------------------------------
558 tx reserved_page_packet
559 ----------------------------------------------------------*/
560 pmgntframe = rtw_alloc_cmdxmitframe(pxmitpriv);
561 if (pmgntframe == NULL) {
562 rtStatus = _FAIL;
563 goto exit;
564 }
565 /* update attribute */
566 pattrib = &pmgntframe->attrib;
567 update_mgntframe_attrib(Adapter, pattrib);
568
569 pattrib->qsel = QSLT_BEACON;
570 pattrib->pktlen = pattrib->last_txcmdsz = FwBufLen;
571
572 /* _rtw_memset(pmgntframe->buf_addr, 0, TotalPktLen+txdesc_size); */
573 /* pmgntframe->buf_addr = ReservedPagePacket ; */
574
575 _rtw_memcpy((u8 *)(pmgntframe->buf_addr + txdesc_offset), ReservedPagePacket, FwBufLen);
576 RTW_INFO("[%d]===>TotalPktLen + TXDESC_OFFSET TotalPacketLen:%d\n", DLBcnCount, (FwBufLen + txdesc_offset));
577
578 #ifdef CONFIG_PCI_HCI
579 dump_mgntframe(Adapter, pmgntframe);
580 #else
581 dump_mgntframe_and_wait(Adapter, pmgntframe, 100);
582 #endif
583
584 #endif
585 #if 1
586 /* check rsvd page download OK. */
587 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 2);
588 while (!(BcnValidReg & BIT(0)) && count < 200) {
589 count++;
590 /* PlatformSleepUs(10); */
591 rtw_msleep_os(1);
592 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 2);
593 }
594 DLBcnCount++;
595 /* RTW_INFO("##0x208:%08x,0x210=%08x\n",PlatformEFIORead4Byte(Adapter, REG_TDECTRL),PlatformEFIORead4Byte(Adapter, 0x210)); */
596
597 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL + 2, BcnValidReg);
598
599 } while ((!(BcnValidReg & BIT(0))) && DLBcnCount < 5);
600
601
602 #endif
603 if (DLBcnCount >= 5) {
604 RTW_INFO(" check rsvd page download OK DLBcnCount =%d\n", DLBcnCount);
605 rtStatus = _FAIL;
606 goto exit;
607 }
608
609 if (!(BcnValidReg & BIT(0))) {
610 RTW_INFO("_WriteFWtoTxPktBuf(): 1 Download RSVD page failed!\n");
611 rtStatus = _FAIL;
612 goto exit;
613 }
614
615 /* --------------------------------------------------------- */
616 /* 4. Set Tx boundary to the initial value */
617 /* --------------------------------------------------------- */
618
619
620 /* --------------------------------------------------------- */
621 /* 5. Reset beacon setting to the initial value. */
622 /* After _CheckWLANFwPatchBTFwReady(). */
623 /* --------------------------------------------------------- */
624
625 exit:
626
627 if (pGenBufReservedPagePacket) {
628 RTW_INFO("_WriteBTFWtoTxPktBuf8723D => rtw_mfree pGenBufReservedPagePacket!\n");
629 rtw_mfree((u8 *)pGenBufReservedPagePacket, TotalPktLen);
630 }
631 return rtStatus;
632 }
633
634
635
636 /*
637 * Description: Determine the contents of H2C BT_FW_PATCH Command sent to FW.
638 * 2011.10.20 by tynli
639 * */
640 void
SetFwBTFwPatchCmd(PADAPTER Adapter,u16 FwSize)641 SetFwBTFwPatchCmd(
642 PADAPTER Adapter,
643 u16 FwSize
644 )
645 {
646 u8 u1BTFwPatchParm[H2C_BT_FW_PATCH_LEN] = {0};
647 u8 addr0 = 0;
648 u8 addr1 = 0xa0;
649 u8 addr2 = 0x10;
650 u8 addr3 = 0x80;
651
652
653 SET_8723D_H2CCMD_BT_FW_PATCH_SIZE(u1BTFwPatchParm, FwSize);
654 SET_8723D_H2CCMD_BT_FW_PATCH_ADDR0(u1BTFwPatchParm, addr0);
655 SET_8723D_H2CCMD_BT_FW_PATCH_ADDR1(u1BTFwPatchParm, addr1);
656 SET_8723D_H2CCMD_BT_FW_PATCH_ADDR2(u1BTFwPatchParm, addr2);
657 SET_8723D_H2CCMD_BT_FW_PATCH_ADDR3(u1BTFwPatchParm, addr3);
658
659 FillH2CCmd8723D(Adapter, H2C_8723D_BT_FW_PATCH, H2C_BT_FW_PATCH_LEN, u1BTFwPatchParm);
660
661 }
662
663 void
SetFwBTPwrCmd(PADAPTER Adapter,u8 PwrIdx)664 SetFwBTPwrCmd(
665 PADAPTER Adapter,
666 u8 PwrIdx
667 )
668 {
669 u8 u1BTPwrIdxParm[H2C_FORCE_BT_TXPWR_LEN] = {0};
670
671 SET_8723D_H2CCMD_BT_PWR_IDX(u1BTPwrIdxParm, PwrIdx);
672
673
674 FillH2CCmd8723D(Adapter, H2C_8723D_FORCE_BT_TXPWR, H2C_FORCE_BT_TXPWR_LEN, u1BTPwrIdxParm);
675 }
676
677 /*
678 * Description: WLAN Fw will write BT Fw to BT XRAM and signal driver.
679 *
680 * 2011.10.20. by tynli.
681 * */
682 int
_CheckWLANFwPatchBTFwReady(PADAPTER Adapter,BOOLEAN bRecover)683 _CheckWLANFwPatchBTFwReady(
684 PADAPTER Adapter,
685 BOOLEAN bRecover
686 )
687 {
688 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
689 u32 count = 0;
690 u8 u1bTmp;
691 int ret = _FAIL;
692
693 /* --------------------------------------------------------- */
694 /* Check if BT FW patch procedure is ready. */
695 /* --------------------------------------------------------- */
696 do {
697 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_HMEBOX_DBG_0_8723D);
698 if ((u1bTmp & BIT(6)) || (u1bTmp & BIT(7))) {
699 ret = _SUCCESS;
700 break;
701 }
702
703 count++;
704 rtw_msleep_os(50); /* 50ms */
705 } while (!((u1bTmp & BIT(6)) || (u1bTmp & BIT(7))) && count < 50);
706
707
708
709
710 /* --------------------------------------------------------- */
711 /* Reset beacon setting to the initial value. */
712 /* --------------------------------------------------------- */
713 #if 0/* #ifdef CONFIG_PCI_HCI */
714 if (LLT_table_init(Adapter, FALSE, 0) == RT_STATUS_FAILURE) {
715 dbgdump("Init self define for BT Fw patch LLT table fail.\n");
716 /* return RT_STATUS_FAILURE; */
717 }
718 #endif
719 u1bTmp = rtw_read8(Adapter, REG_BCN_CTRL);
720 u1bTmp |= EN_BCN_FUNCTION;
721 u1bTmp &= ~DIS_TSF_UDT;
722 rtw_write8(Adapter, REG_BCN_CTRL, u1bTmp);
723
724 /* To make sure that if there exists an adapter which would like to send beacon. */
725 /* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
726 /* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */
727 /* the beacon cannot be sent by HW. */
728 /* 2010.06.23. Added by tynli. */
729 if (bRecover) {
730 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2);
731 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, (u1bTmp | BIT(6)));
732 }
733
734 /* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */
735 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR + 1);
736 PlatformEFIOWrite1Byte(Adapter, REG_CR + 1, (u1bTmp & (~BIT(0))));
737
738 return ret;
739 }
740
ReservedPage_Compare(PADAPTER Adapter,PRT_MP_FIRMWARE pFirmware,u32 BTPatchSize)741 int ReservedPage_Compare(PADAPTER Adapter, PRT_MP_FIRMWARE pFirmware, u32 BTPatchSize)
742 {
743 u8 temp, ret, lastBTsz;
744 u32 u1bTmp = 0, address_start = 0, count = 0, i = 0;
745 u8 *myBTFwBuffer = NULL;
746
747 myBTFwBuffer = rtw_zmalloc(BTPatchSize);
748 if (myBTFwBuffer == NULL) {
749 RTW_INFO("%s can't be executed due to the failed malloc.\n", __FUNCTION__);
750 Adapter->mppriv.bTxBufCkFail = _TRUE;
751 return _FALSE;
752 }
753
754 temp = rtw_read8(Adapter, 0x209);
755
756 address_start = (temp * 128) / 8;
757
758 rtw_write32(Adapter, 0x140, 0x00000000);
759 rtw_write32(Adapter, 0x144, 0x00000000);
760 rtw_write32(Adapter, 0x148, 0x00000000);
761
762 rtw_write8(Adapter, 0x106, 0x69);
763
764 for (i = 0; i < (BTPatchSize / 8); i++) {
765 rtw_write32(Adapter, 0x140, address_start + 5 + i);
766
767 /* polling until reg 0x140[23]=1; */
768 do {
769 u1bTmp = rtw_read32(Adapter, 0x140);
770 if (u1bTmp & BIT(23)) {
771 ret = _SUCCESS;
772 break;
773 }
774 count++;
775 RTW_INFO("0x140=%x, wait for 10 ms (%d) times.\n", u1bTmp, count);
776 rtw_msleep_os(10); /* 10ms */
777 } while (!(u1bTmp & BIT(23)) && count < 50);
778
779 myBTFwBuffer[i * 8 + 0] = rtw_read8(Adapter, 0x144);
780 myBTFwBuffer[i * 8 + 1] = rtw_read8(Adapter, 0x145);
781 myBTFwBuffer[i * 8 + 2] = rtw_read8(Adapter, 0x146);
782 myBTFwBuffer[i * 8 + 3] = rtw_read8(Adapter, 0x147);
783 myBTFwBuffer[i * 8 + 4] = rtw_read8(Adapter, 0x148);
784 myBTFwBuffer[i * 8 + 5] = rtw_read8(Adapter, 0x149);
785 myBTFwBuffer[i * 8 + 6] = rtw_read8(Adapter, 0x14a);
786 myBTFwBuffer[i * 8 + 7] = rtw_read8(Adapter, 0x14b);
787 }
788
789 rtw_write32(Adapter, 0x140, address_start + 5 + BTPatchSize / 8);
790
791 lastBTsz = BTPatchSize % 8;
792
793 /* polling until reg 0x140[23]=1; */
794 u1bTmp = 0;
795 count = 0;
796 do {
797 u1bTmp = rtw_read32(Adapter, 0x140);
798 if (u1bTmp & BIT(23)) {
799 ret = _SUCCESS;
800 break;
801 }
802 count++;
803 RTW_INFO("0x140=%x, wait for 10 ms (%d) times.\n", u1bTmp, count);
804 rtw_msleep_os(10); /* 10ms */
805 } while (!(u1bTmp & BIT(23)) && count < 50);
806
807 for (i = 0; i < lastBTsz; i++)
808 myBTFwBuffer[(BTPatchSize / 8) * 8 + i] = rtw_read8(Adapter, (0x144 + i));
809
810
811 for (i = 0; i < BTPatchSize; i++) {
812 if (myBTFwBuffer[i] != pFirmware->szFwBuffer[i]) {
813 RTW_INFO(" In direct myBTFwBuffer[%d]=%x , pFirmware->szFwBuffer=%x\n", i, myBTFwBuffer[i], pFirmware->szFwBuffer[i]);
814 Adapter->mppriv.bTxBufCkFail = _TRUE;
815 break;
816 }
817 }
818
819 if (myBTFwBuffer != NULL)
820 rtw_mfree(myBTFwBuffer, BTPatchSize);
821
822 return _TRUE;
823 }
824
825 /* As the size of bt firmware is more than 16k which is too big for some platforms, we divide it
826 * into four parts to transfer. The last parameter of _WriteBTFWtoTxPktBuf8723D is used to indicate
827 * the location of every part. We call the first 4096 byte of bt firmware as part 1, the second 4096
828 * part as part 2, the third 4096 part as part 3, the remain as part 4. First we transform the part
829 * 4 and set the register 0x209 to 0x90, then the 32 bytes description are added to the head of part
830 * 4, and those bytes are putted at the location 0x90. Second we transform the part 3 and set the
831 * register 0x209 to 0x70. The 32 bytes description and part 3(4196 bytes) are putted at the location
832 * 0x70. It can contain 4196 bytes between 0x70 and 0x90. So the last 32 bytes os part 3 will cover the
833 * 32 bytes description of part4. Using this method, we can put the whole bt firmware to 0x30 and only
834 * has 32 bytes descrption at the head of part 1.
835 */
FirmwareDownloadBT(PADAPTER padapter,PRT_MP_FIRMWARE pFirmware)836 s32 FirmwareDownloadBT(PADAPTER padapter, PRT_MP_FIRMWARE pFirmware)
837 {
838 s32 rtStatus;
839 u8 *pBTFirmwareBuf;
840 u32 BTFirmwareLen;
841 u8 download_time;
842 s8 i;
843 BOOLEAN bRecover = _FALSE;
844 u8 RegFwHwTxQCtrl;
845
846 rtStatus = _SUCCESS;
847 pBTFirmwareBuf = NULL;
848 BTFirmwareLen = 0;
849
850 #if 0
851 /* */
852 /* Patch BT Fw. Download BT RAM code to Tx packet buffer. */
853 /* */
854 if (GET_HAL_DATA(padapter)->bBTFWReady) {
855 RTW_INFO("%s: BT Firmware is ready!!\n", __FUNCTION__);
856 return _FAIL;
857 }
858
859 #ifdef CONFIG_FILE_FWIMG
860 if (rtw_is_file_readable(rtw_fw_mp_bt_file_path) == _TRUE) {
861 RTW_INFO("%s: acquire MP BT FW from file:%s\n", __FUNCTION__, rtw_fw_mp_bt_file_path);
862
863 rtStatus = rtw_retrieve_from_file(rtw_fw_mp_bt_file_path, FwBuffer, FW_8723D_SIZE);
864 BTFirmwareLen = rtStatus >= 0 ? rtStatus : 0;
865 pBTFirmwareBuf = FwBuffer;
866 } else
867 #endif /* CONFIG_FILE_FWIMG */
868 {
869 #ifdef CONFIG_EMBEDDED_FWIMG
870 RTW_INFO("%s: Download MP BT FW from header\n", __FUNCTION__);
871
872 pBTFirmwareBuf = (u8 *)Rtl8723DFwBTImgArray;
873 BTFirmwareLen = Rtl8723DFwBTImgArrayLength;
874 pFirmware->szFwBuffer = pBTFirmwareBuf;
875 pFirmware->ulFwLength = BTFirmwareLen;
876 #endif /* CONFIG_EMBEDDED_FWIMG */
877 }
878
879 RTW_INFO("%s: MP BT Firmware size=%d\n", __FUNCTION__, BTFirmwareLen);
880
881 /* for h2c cam here should be set to true */
882 GET_HAL_DATA(padapter)->bFWReady = _TRUE;
883
884 download_time = (BTFirmwareLen + 4095) / 4096;
885 RTW_INFO("%s: download_time is %d\n", __FUNCTION__, download_time);
886 RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2);
887
888 if (RegFwHwTxQCtrl & BIT(6))
889 bRecover = _TRUE;
890
891 /* Download BT patch Fw. */
892 for (i = (download_time - 1); i >= 0; i--) {
893 if (i == (download_time - 1)) {
894 rtStatus = _WriteBTFWtoTxPktBuf8723D(padapter, pBTFirmwareBuf + (4096 * i), (BTFirmwareLen - (4096 * i)), 1);
895 RTW_INFO("%s: start %d, len %d, time 1\n", __FUNCTION__, 4096 * i, BTFirmwareLen - (4096 * i));
896 } else {
897 rtStatus = _WriteBTFWtoTxPktBuf8723D(padapter, pBTFirmwareBuf + (4096 * i), 4096, (download_time - i));
898 RTW_INFO("%s: start %d, len 4096, time %d\n", __FUNCTION__, 4096 * i, download_time - i);
899 }
900
901 if (rtStatus != _SUCCESS) {
902 RTW_INFO("%s: BT Firmware download to Tx packet buffer fail!\n", __FUNCTION__);
903 GET_HAL_DATA(padapter)->bBTFWReady = _FALSE;
904 return rtStatus;
905 }
906 }
907
908 ReservedPage_Compare(padapter, pFirmware, BTFirmwareLen);
909
910 GET_HAL_DATA(padapter)->bBTFWReady = _TRUE;
911 SetFwBTFwPatchCmd(padapter, (u16)BTFirmwareLen);
912 rtStatus = _CheckWLANFwPatchBTFwReady(padapter, bRecover);
913
914 RTW_INFO("<===%s: return %s!\n", __FUNCTION__, rtStatus == _SUCCESS ? "SUCCESS" : "FAIL");
915 #endif
916
917 return rtStatus;
918 }
919 #endif /* CONFIG_MP_INCLUDED */
920
921 #if defined(CONFIG_SDIO_HCI) && defined(CONFIG_DLFW_TXPKT)
send_fw_packet(PADAPTER padapter,u8 * pRam_code,u32 length)922 u8 send_fw_packet(PADAPTER padapter, u8 *pRam_code, u32 length)
923 {
924 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
925 struct xmit_buf xmit_buf_tmp;
926 struct submit_ctx sctx_tmp;
927 u8 *pTx_data_buffer = NULL;
928 u8 *pTmp_buffer = NULL;
929 u8 bRet = 0, value8 = 0, res = _FAIL;
930 u32 modify_ram_size = 0;
931 u32 tmp_size = 0, tmp_value = 0;
932 u32 i = 0, counter = 0;
933 u32 dwDataLength = 0, writeLength = 0;
934
935 /* Due to SDIO can not send 32K packet */
936 if (FW_DOWNLOAD_SIZE_8723D == length)
937 length--;
938
939 modify_ram_size = length << 2;
940
941 pTx_data_buffer = rtw_zmalloc(modify_ram_size);
942
943 if (NULL == pTx_data_buffer) {
944 RTW_INFO("Allocate buffer fail!!\n");
945 return _FALSE;
946 }
947
948 _rtw_memset(pTx_data_buffer, 0, modify_ram_size);
949
950 /* Transfer to new format */
951 tmp_size = length >> 1;
952 for (i = 0; i <= tmp_size; i++) {
953 *(pTx_data_buffer + i * 8) = *(pRam_code + i * 2);
954 *(pTx_data_buffer + i * 8 + 1) = *(pRam_code + i * 2 + 1);
955 }
956
957 /* Gen TX_DESC */
958 _rtw_memset(pTx_data_buffer, 0, TXDESC_SIZE);
959 pTmp_buffer = pTx_data_buffer;
960 SET_TX_DESC_QUEUE_SEL_8723D(pTmp_buffer, QSLT_BEACON);
961 SET_TX_DESC_PKT_SIZE_8723D(pTmp_buffer, modify_ram_size - TXDESC_SIZE);
962 SET_TX_DESC_OFFSET_8723D(pTmp_buffer, TXDESC_SIZE);
963
964 /* Send packet */
965 xmit_buf_tmp.pdata = pTx_data_buffer;
966 xmit_buf_tmp.len = modify_ram_size;
967 rtw_sctx_init(&sctx_tmp, 10);
968 xmit_buf_tmp.sctx = &sctx_tmp;
969
970 res = rtw_write_port(padapter,
971 pdvobjpriv->Queue2Pipe[BCN_QUEUE_INX],
972 xmit_buf_tmp.len,
973 (u8 *)&xmit_buf_tmp);
974 if (res == _FAIL) {
975 RTW_INFO("rtw_write_port fail\n");
976 return _FAIL;
977 }
978
979 /* check if DMA is OK */
980 counter = 100;
981 do {
982 if (0 == counter) {
983 RTW_INFO("DMA time out!!\n");
984 return _FALSE;
985 }
986 value8 = rtw_read8(padapter, REG_DWBCN0_CTRL_8723D + 2);
987 counter--;
988 } while (0 == (value8 & BIT(0)));
989
990 rtw_write8(padapter, REG_DWBCN0_CTRL_8723D + 2, value8);
991
992 /* Modify ram code by IO method */
993 tmp_value = rtw_read8(padapter, REG_MCUFWDL + 1);
994 /* Disable DMA */
995 rtw_write8(padapter, REG_MCUFWDL + 1, (u8)tmp_value & ~(BIT(5)));
996 tmp_value = (tmp_value >> 6) << 1;
997 /* Set page start address */
998 rtw_write8(padapter, REG_MCUFWDL + 2,
999 (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | tmp_value);
1000 tmp_size = TXDESC_SIZE >> 2; /* 10bytes */
1001
1002 _BlockWrite(padapter, pRam_code, tmp_size);
1003
1004 if (pTmp_buffer != NULL)
1005 rtw_mfree((u8 *)pTmp_buffer, modify_ram_size);
1006
1007 return _TRUE;
1008 }
1009 #endif /* CONFIG_SDIO_HCI */
1010
1011 /*
1012 * Description:
1013 * Download 8192C firmware code.
1014 *
1015 * */
rtl8723d_FirmwareDownload(PADAPTER padapter,BOOLEAN bUsedWoWLANFw)1016 s32 rtl8723d_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw)
1017 {
1018 s32 rtStatus = _SUCCESS;
1019 u8 write_fw = 0;
1020 systime fwdl_start_time;
1021 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1022 u8 *FwImage;
1023 u32 FwImageLen;
1024 u8 *pFwImageFileName;
1025 #ifdef CONFIG_WOWLAN
1026 u8 *FwImageWoWLAN;
1027 u32 FwImageWoWLANLen;
1028 #endif
1029 u8 *pucMappedFile = NULL;
1030 PRT_FIRMWARE_8723D pFirmware = NULL;
1031 PRT_8723D_FIRMWARE_HDR pFwHdr = NULL;
1032 u8 *pFirmwareBuf;
1033 u32 FirmwareLen;
1034 #ifdef CONFIG_FILE_FWIMG
1035 u8 *fwfilepath;
1036 #endif /* CONFIG_FILE_FWIMG */
1037 u8 value8;
1038 u16 value16;
1039 u32 value32;
1040 u8 dma_iram_sel;
1041 u16 new_chk_sum = 0;
1042 u32 send_pkt_size, pkt_size_tmp;
1043 u32 mem_offset;
1044 u32 counter;
1045 struct dvobj_priv *psdpriv = padapter->dvobj;
1046 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1047 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1048
1049
1050 pFirmware = (PRT_FIRMWARE_8723D)rtw_zmalloc(sizeof(RT_FIRMWARE_8723D));
1051
1052 if (!pFirmware) {
1053 rtStatus = _FAIL;
1054 goto exit;
1055 }
1056
1057 {
1058 u8 tmp_ps = 0, tmp_rf = 0;
1059
1060 tmp_ps = rtw_read8(padapter, 0xa3);
1061 tmp_ps &= 0xf8;
1062 tmp_ps |= 0x02;
1063 /* 1. write 0xA3[:2:0] = 3b'010 */
1064 rtw_write8(padapter, 0xa3, tmp_ps);
1065 /* 2. read power_state = 0xA0[1:0] */
1066 tmp_ps = rtw_read8(padapter, 0xa0);
1067 tmp_ps &= 0x03;
1068 if (tmp_ps != 0x01) {
1069 RTW_INFO(FUNC_ADPT_FMT" tmp_ps=%x\n",
1070 FUNC_ADPT_ARG(padapter), tmp_ps);
1071 pdbgpriv->dbg_downloadfw_pwr_state_cnt++;
1072 }
1073 }
1074
1075 #ifdef CONFIG_BT_COEXIST
1076 rtw_btcoex_PreLoadFirmware(padapter);
1077 #endif /* CONFIG_BT_COEXIST */
1078
1079 #ifdef CONFIG_FILE_FWIMG
1080 #ifdef CONFIG_WOWLAN
1081 if (bUsedWoWLANFw)
1082 fwfilepath = rtw_fw_wow_file_path;
1083 else
1084 #endif /* CONFIG_WOWLAN */
1085 {
1086 fwfilepath = rtw_fw_file_path;
1087 }
1088 #endif /* CONFIG_FILE_FWIMG */
1089
1090 #ifdef CONFIG_FILE_FWIMG
1091 if (rtw_is_file_readable(fwfilepath) == _TRUE) {
1092 RTW_INFO("%s acquire FW from file:%s\n", __FUNCTION__, fwfilepath);
1093 pFirmware->eFWSource = FW_SOURCE_IMG_FILE;
1094 } else
1095 #endif /* CONFIG_FILE_FWIMG */
1096 {
1097 #ifdef CONFIG_EMBEDDED_FWIMG
1098 pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
1099 #else /* !CONFIG_EMBEDDED_FWIMG */
1100 pFirmware->eFWSource = FW_SOURCE_IMG_FILE; /* We should decided by Reg. */
1101 #endif /* !CONFIG_EMBEDDED_FWIMG */
1102 }
1103
1104 switch (pFirmware->eFWSource) {
1105 case FW_SOURCE_IMG_FILE:
1106 #ifdef CONFIG_FILE_FWIMG
1107 rtStatus = rtw_retrieve_from_file(fwfilepath, FwBuffer, FW_8723D_SIZE);
1108 pFirmware->ulFwLength = rtStatus >= 0 ? rtStatus : 0;
1109 pFirmware->szFwBuffer = FwBuffer;
1110 #endif /* CONFIG_FILE_FWIMG */
1111 break;
1112
1113 case FW_SOURCE_HEADER_FILE:
1114 if (bUsedWoWLANFw) {
1115 #ifdef CONFIG_WOWLAN
1116 if (pwrpriv->wowlan_mode) {
1117 pFirmware->szFwBuffer = array_mp_8723d_fw_wowlan;
1118 pFirmware->ulFwLength = array_length_mp_8723d_fw_wowlan;
1119 RTW_INFO(" ===> %s fw: %s, size: %d\n",
1120 __FUNCTION__, "WoWLAN", pFirmware->ulFwLength);
1121 }
1122 #endif /* CONFIG_WOWLAN */
1123
1124 #ifdef CONFIG_AP_WOWLAN
1125 if (pwrpriv->wowlan_ap_mode) {
1126 pFirmware->szFwBuffer = array_mp_8723d_fw_ap;
1127 pFirmware->ulFwLength = array_length_mp_8723d_fw_ap;
1128 RTW_INFO(" ===> %s fw: %s, size: %d\n",
1129 __FUNCTION__, "AP_WoWLAN", pFirmware->ulFwLength);
1130 }
1131 #endif /* CONFIG_AP_WOWLAN */
1132 } else {
1133 pFirmware->szFwBuffer = array_mp_8723d_fw_nic;
1134 pFirmware->ulFwLength = array_length_mp_8723d_fw_nic;
1135 RTW_INFO("%s fw: %s, size: %d\n", __FUNCTION__, "FW_NIC", pFirmware->ulFwLength);
1136 }
1137 break;
1138 }
1139
1140 if ((pFirmware->ulFwLength - 32) > FW_8723D_SIZE) {
1141 rtStatus = _FAIL;
1142 RTW_ERR("Firmware size:%u exceed %u\n",
1143 pFirmware->ulFwLength, FW_8723D_SIZE);
1144 goto exit;
1145 }
1146
1147 pFirmwareBuf = pFirmware->szFwBuffer;
1148 FirmwareLen = pFirmware->ulFwLength;
1149
1150 /* To Check Fw header. Added by tynli. 2009.12.04. */
1151 pFwHdr = (PRT_8723D_FIRMWARE_HDR)pFirmwareBuf;
1152
1153 pHalData->firmware_version = le16_to_cpu(pFwHdr->Version);
1154 pHalData->firmware_sub_version = le16_to_cpu(pFwHdr->Subversion);
1155 pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
1156
1157 RTW_INFO("%s: fw_ver=%x fw_subver=%04x sig=0x%x, Month=%02x, Date=%02x, Hour=%02x, Minute=%02x\n",
1158 __func__, pHalData->firmware_version,
1159 pHalData->firmware_sub_version, pHalData->FirmwareSignature
1160 , pFwHdr->Month, pFwHdr->Date, pFwHdr->Hour, pFwHdr->Minute);
1161
1162 if (IS_FW_HEADER_EXIST_8723D(pFwHdr)) {
1163 RTW_INFO("%s(): Shift for fw header!\n", __FUNCTION__);
1164 /* Shift 32 bytes for FW header */
1165 pFirmwareBuf = pFirmwareBuf + 32;
1166 FirmwareLen = FirmwareLen - 32;
1167 }
1168
1169 fwdl_start_time = rtw_get_current_time();
1170
1171 /* To check if FW already exists before download FW */
1172 if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) {
1173 RTW_INFO("%s: FW exists before download FW\n", __func__);
1174 rtw_write8(padapter, REG_MCUFWDL, 0x00);
1175 _8051Reset8723(padapter);
1176 }
1177
1178 #ifndef CONFIG_DLFW_TXPKT
1179 RTW_INFO("%s by IO write!\n", __func__);
1180
1181 _FWDownloadEnable(padapter, _TRUE);
1182
1183 while (!RTW_CANNOT_IO(padapter) &&
1184 (write_fw++ < DL_FW_MAX ||
1185 rtw_get_passing_time_ms(fwdl_start_time) < 500)) {
1186 /* reset FWDL chksum */
1187 rtw_write8(padapter, REG_MCUFWDL,
1188 rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
1189
1190 rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
1191 if (rtStatus != _SUCCESS)
1192 continue;
1193
1194 rtStatus = polling_fwdl_chksum(padapter, 2, 10);
1195 if (rtStatus == _SUCCESS) {
1196 RTW_INFO("%s: download FW count:%d\n", __func__,
1197 write_fw);
1198 break;
1199 } else {
1200 rtw_mdelay_os(10);
1201 }
1202 }
1203 #else
1204 RTW_INFO("%s by Tx pkt write!\n", __func__);
1205
1206 if ((rtw_read8(padapter, REG_MCUFWDL) & MCUFWDL_RDY) == 0) {
1207 /*
1208 * SDIO DMA condition:
1209 * all queue must be 256 (0x100 = 0x20 + 0xE0)
1210 */
1211
1212 value32 = 0x802000E0;
1213 rtw_write32(padapter, REG_RQPN, value32);
1214
1215 /* Set beacon boundary to TXFIFO header */
1216 rtw_write8(padapter, REG_BCNQ_BDNY, 0);
1217 rtw_write16(padapter, REG_DWBCN0_CTRL_8723D + 1, BIT(8));
1218
1219 /* SDIO need read this register before send packet */
1220 rtw_read32(padapter, 0x10250020);
1221
1222 _FWDownloadEnable(padapter, _TRUE);
1223
1224 /* Get original check sum */
1225 new_chk_sum = *(pFirmwareBuf + FirmwareLen - 2) |
1226 ((u16)*(pFirmwareBuf + FirmwareLen - 1) << 8);
1227
1228 /* Send ram code flow */
1229 dma_iram_sel = 0;
1230 mem_offset = 0;
1231 pkt_size_tmp = FirmwareLen;
1232 while (0 != pkt_size_tmp) {
1233 if (pkt_size_tmp >= FW_DOWNLOAD_SIZE_8723D) {
1234 send_pkt_size = FW_DOWNLOAD_SIZE_8723D;
1235 /* Modify check sum value */
1236 new_chk_sum = (u16)(new_chk_sum ^ (((send_pkt_size - 1) << 2) - TXDESC_SIZE));
1237 } else {
1238 send_pkt_size = pkt_size_tmp;
1239 new_chk_sum = (u16)(new_chk_sum ^ ((send_pkt_size << 2) - TXDESC_SIZE));
1240
1241 }
1242
1243 if (send_pkt_size == pkt_size_tmp) {
1244 /* last partition packet, write new check sum to ram code file */
1245 *(pFirmwareBuf + FirmwareLen - 2) = new_chk_sum & 0xFF;
1246 *(pFirmwareBuf + FirmwareLen - 1) = (new_chk_sum & 0xFF00) >> 8;
1247 }
1248
1249 /* IRAM select */
1250 rtw_write8(padapter, REG_MCUFWDL + 1,
1251 (rtw_read8(padapter, REG_MCUFWDL + 1) & 0x3F) | (dma_iram_sel << 6));
1252 /* Enable DMA */
1253 rtw_write8(padapter, REG_MCUFWDL + 1,
1254 rtw_read8(padapter, REG_MCUFWDL + 1) | BIT(5));
1255
1256 if (_FALSE == send_fw_packet(padapter, pFirmwareBuf + mem_offset, send_pkt_size)) {
1257 RTW_INFO("%s: Send FW fail !\n", __FUNCTION__);
1258 rtStatus = _FAIL;
1259 goto DLFW_FAIL;
1260 }
1261
1262 dma_iram_sel++;
1263 mem_offset += send_pkt_size;
1264 pkt_size_tmp -= send_pkt_size;
1265 }
1266 } else {
1267 RTW_INFO("%s: Download FW fail since MCUFWDL_RDY is not set!\n", __FUNCTION__);
1268 rtStatus = _FAIL;
1269 goto DLFW_FAIL;
1270 }
1271 #endif
1272
1273 _FWDownloadEnable(padapter, _FALSE);
1274
1275 if (rtStatus == _SUCCESS)
1276 rtStatus = _FWFreeToGo(padapter, 10, 200);
1277 else
1278 goto DLFW_FAIL;
1279
1280 if (_SUCCESS != rtStatus)
1281 goto DLFW_FAIL;
1282
1283 DLFW_FAIL:
1284 if (rtStatus == _FAIL) {
1285 /* Disable FWDL_EN */
1286 value8 = rtw_read8(padapter, REG_MCUFWDL);
1287 value8 = (value8 & ~(BIT(0)) & ~(BIT(1)));
1288 rtw_write8(padapter, REG_MCUFWDL, value8);
1289 }
1290
1291 RTW_INFO("%s %s. write_fw:%u, %dms\n"
1292 , __FUNCTION__, (rtStatus == _SUCCESS) ? "success" : "fail"
1293 , write_fw
1294 , rtw_get_passing_time_ms(fwdl_start_time)
1295 );
1296
1297 exit:
1298 if (pFirmware)
1299 rtw_mfree((u8 *)pFirmware, sizeof(RT_FIRMWARE_8723D));
1300
1301 rtl8723d_InitializeFirmwareVars(padapter);
1302
1303 RTW_INFO(" <=== %s()\n", __FUNCTION__);
1304
1305 return rtStatus;
1306 }
1307
rtl8723d_InitializeFirmwareVars(PADAPTER padapter)1308 void rtl8723d_InitializeFirmwareVars(PADAPTER padapter)
1309 {
1310 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1311
1312 /* Init Fw LPS related. */
1313 adapter_to_pwrctl(padapter)->bFwCurrentInPSMode = _FALSE;
1314
1315 /* Init H2C cmd. */
1316 rtw_write8(padapter, REG_HMETFR, 0x0f);
1317
1318 /* Init H2C counter. by tynli. 2009.12.09. */
1319 pHalData->LastHMEBoxNum = 0;
1320 /* pHalData->H2CQueueHead = 0;
1321 * pHalData->H2CQueueTail = 0;
1322 * pHalData->H2CStopInsertQueue = _FALSE; */
1323 }
1324
1325 /* ***********************************************************
1326 * Efuse related code
1327 * *********************************************************** */
1328 static u8
hal_EfuseSwitchToBank(PADAPTER padapter,u8 bank,u8 bPseudoTest)1329 hal_EfuseSwitchToBank(
1330 PADAPTER padapter,
1331 u8 bank,
1332 u8 bPseudoTest)
1333 {
1334 u8 bRet = _FALSE;
1335 u32 value32 = 0;
1336 #ifdef HAL_EFUSE_MEMORY
1337 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1338 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1339 #endif
1340
1341
1342 RTW_INFO("%s: Efuse switch bank to %d\n", __FUNCTION__, bank);
1343 if (bPseudoTest) {
1344 #ifdef HAL_EFUSE_MEMORY
1345 pEfuseHal->fakeEfuseBank = bank;
1346 #else
1347 fakeEfuseBank = bank;
1348 #endif
1349 bRet = _TRUE;
1350 } else {
1351 value32 = rtw_read32(padapter, EFUSE_TEST);
1352 bRet = _TRUE;
1353 switch (bank) {
1354 case 0:
1355 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1356 break;
1357 case 1:
1358 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
1359 break;
1360 case 2:
1361 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
1362 break;
1363 case 3:
1364 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
1365 break;
1366 default:
1367 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1368 bRet = _FALSE;
1369 break;
1370 }
1371 rtw_write32(padapter, EFUSE_TEST, value32);
1372 }
1373
1374 return bRet;
1375 }
1376
1377 static void
Hal_GetEfuseDefinition(PADAPTER padapter,u8 efuseType,u8 type,void * pOut,u8 bPseudoTest)1378 Hal_GetEfuseDefinition(
1379 PADAPTER padapter,
1380 u8 efuseType,
1381 u8 type,
1382 void *pOut,
1383 u8 bPseudoTest)
1384 {
1385 switch (type) {
1386 case TYPE_EFUSE_MAX_SECTION: {
1387 u8 *pMax_section;
1388
1389 pMax_section = (u8 *)pOut;
1390
1391 if (efuseType == EFUSE_WIFI)
1392 *pMax_section = EFUSE_MAX_SECTION_8723D;
1393 else
1394 *pMax_section = EFUSE_BT_MAX_SECTION;
1395 }
1396 break;
1397
1398 case TYPE_EFUSE_REAL_CONTENT_LEN: {
1399 u16 *pu2Tmp;
1400
1401 pu2Tmp = (u16 *)pOut;
1402
1403 if (efuseType == EFUSE_WIFI)
1404 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723D;
1405 else
1406 *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
1407 }
1408 break;
1409
1410 case TYPE_AVAILABLE_EFUSE_BYTES_BANK: {
1411 u16 *pu2Tmp;
1412
1413 pu2Tmp = (u16 *)pOut;
1414
1415 if (efuseType == EFUSE_WIFI)
1416 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723D - EFUSE_OOB_PROTECT_BYTES);
1417 else
1418 *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK);
1419 }
1420 break;
1421
1422 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: {
1423 u16 *pu2Tmp;
1424
1425 pu2Tmp = (u16 *)pOut;
1426
1427 if (efuseType == EFUSE_WIFI)
1428 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723D - EFUSE_OOB_PROTECT_BYTES);
1429 else
1430 *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN - (EFUSE_PROTECT_BYTES_BANK * 3));
1431 }
1432 break;
1433
1434 case TYPE_EFUSE_MAP_LEN: {
1435 u16 *pu2Tmp;
1436
1437 pu2Tmp = (u16 *)pOut;
1438
1439 if (efuseType == EFUSE_WIFI)
1440 *pu2Tmp = EFUSE_MAP_LEN_8723D;
1441 else
1442 *pu2Tmp = EFUSE_BT_MAP_LEN;
1443 }
1444 break;
1445
1446 case TYPE_EFUSE_PROTECT_BYTES_BANK: {
1447 u8 *pu1Tmp;
1448
1449 pu1Tmp = (u8 *)pOut;
1450
1451 if (efuseType == EFUSE_WIFI)
1452 *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
1453 else
1454 *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
1455 }
1456 break;
1457
1458 case TYPE_EFUSE_CONTENT_LEN_BANK: {
1459 u16 *pu2Tmp;
1460
1461 pu2Tmp = (u16 *)pOut;
1462
1463 if (efuseType == EFUSE_WIFI)
1464 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723D;
1465 else
1466 *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
1467 }
1468 break;
1469
1470 default: {
1471 u8 *pu1Tmp;
1472
1473 pu1Tmp = (u8 *)pOut;
1474 *pu1Tmp = 0;
1475 }
1476 break;
1477 }
1478 }
1479
1480 #define VOLTAGE_V25 0x03
1481 #define LDOE25_SHIFT 28
1482
1483 /* *****************************************************************
1484 * The following is for compile ok
1485 * That should be merged with the original in the future
1486 * ***************************************************************** */
1487 #define EFUSE_ACCESS_ON_8723 0x69 /* For RTL8723 only. */
1488 #define EFUSE_ACCESS_OFF_8723 0x00 /* For RTL8723 only. */
1489 #define REG_EFUSE_ACCESS_8723 0x00CF /* Efuse access protection for RTL8723 */
1490
1491 /* ***************************************************************** */
Hal_BT_EfusePowerSwitch(PADAPTER padapter,u8 bWrite,u8 PwrState)1492 static void Hal_BT_EfusePowerSwitch(
1493 PADAPTER padapter,
1494 u8 bWrite,
1495 u8 PwrState)
1496 {
1497 u8 tempval;
1498
1499 if (PwrState == _TRUE) {
1500 /* enable BT power cut */
1501 /* 0x6A[14] = 1 */
1502 tempval = rtw_read8(padapter, 0x6B);
1503 tempval |= BIT(6);
1504 rtw_write8(padapter, 0x6B, tempval);
1505
1506 /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */
1507 /* So don't write 0x6A[14]=1 and 0x6A[15]=0 together! */
1508 rtw_usleep_os(100);
1509 /* disable BT output isolation */
1510 /* 0x6A[15] = 0 */
1511 tempval = rtw_read8(padapter, 0x6B);
1512 tempval &= ~BIT(7);
1513 rtw_write8(padapter, 0x6B, tempval);
1514 } else {
1515 /* enable BT output isolation */
1516 /* 0x6A[15] = 1 */
1517 tempval = rtw_read8(padapter, 0x6B);
1518 tempval |= BIT(7);
1519 rtw_write8(padapter, 0x6B, tempval);
1520
1521 /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */
1522 /* So don't write 0x6A[14]=1 and 0x6A[15]=0 together! */
1523
1524 /* disable BT power cut */
1525 /* 0x6A[14] = 1 */
1526 tempval = rtw_read8(padapter, 0x6B);
1527 tempval &= ~BIT(6);
1528 rtw_write8(padapter, 0x6B, tempval);
1529 }
1530
1531 }
1532 static void
Hal_EfusePowerSwitch(PADAPTER padapter,u8 bWrite,u8 PwrState)1533 Hal_EfusePowerSwitch(
1534 PADAPTER padapter,
1535 u8 bWrite,
1536 u8 PwrState)
1537 {
1538 u8 tempval;
1539 u16 tmpV16;
1540
1541
1542 if (PwrState == _TRUE) {
1543 #ifdef CONFIG_SDIO_HCI
1544 /* To avoid cannot access efuse regsiters after disable/enable several times during DTM test. */
1545 /* Suggested by SD1 IsaacHsu. 2013.07.08, added by tynli. */
1546 tempval = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HSUS_CTRL);
1547 if (tempval & BIT(0)) { /* SDIO local register is suspend */
1548 u8 count = 0;
1549
1550
1551 tempval &= ~BIT(0);
1552 rtw_write8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HSUS_CTRL, tempval);
1553
1554 /* check 0x86[1:0]=10'2h, wait power state to leave suspend */
1555 do {
1556 tempval = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HSUS_CTRL);
1557 tempval &= 0x3;
1558 if (tempval == 0x02)
1559 break;
1560
1561 count++;
1562 if (count >= 100)
1563 break;
1564
1565 rtw_mdelay_os(10);
1566 } while (1);
1567
1568 if (count >= 100) {
1569 RTW_INFO(FUNC_ADPT_FMT ": Leave SDIO local register suspend fail! Local 0x86=%#X\n",
1570 FUNC_ADPT_ARG(padapter), tempval);
1571 } else {
1572 RTW_INFO(FUNC_ADPT_FMT ": Leave SDIO local register suspend OK! Local 0x86=%#X\n",
1573 FUNC_ADPT_ARG(padapter), tempval);
1574 }
1575 }
1576 #endif /* CONFIG_SDIO_HCI */
1577
1578 rtw_write8(padapter, REG_EFUSE_ACCESS_8723, EFUSE_ACCESS_ON_8723);
1579
1580 /* Reset: 0x0000h[28], default valid */
1581 tmpV16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
1582 if (!(tmpV16 & FEN_ELDR)) {
1583 tmpV16 |= FEN_ELDR;
1584 rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
1585 }
1586
1587 /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
1588 tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
1589 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
1590 tmpV16 |= (LOADER_CLK_EN | ANA8M);
1591 rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
1592 }
1593
1594 if (bWrite == _TRUE) {
1595 /* Enable LDO 2.5V before read/write action */
1596 tempval = rtw_read8(padapter, EFUSE_TEST + 3);
1597 tempval &= 0x0F;
1598 tempval |= (VOLTAGE_V25 << 4);
1599 rtw_write8(padapter, EFUSE_TEST + 3, (tempval | 0x80));
1600
1601 /* rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); */
1602 }
1603 } else {
1604 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
1605
1606 if (bWrite == _TRUE) {
1607 /* Disable LDO 2.5V after read/write action */
1608 tempval = rtw_read8(padapter, EFUSE_TEST + 3);
1609 rtw_write8(padapter, EFUSE_TEST + 3, (tempval & 0x7F));
1610 }
1611
1612 }
1613 }
1614
1615 static void
hal_ReadEFuse_WiFi(PADAPTER padapter,u16 _offset,u16 _size_byte,u8 * pbuf,u8 bPseudoTest)1616 hal_ReadEFuse_WiFi(
1617 PADAPTER padapter,
1618 u16 _offset,
1619 u16 _size_byte,
1620 u8 *pbuf,
1621 u8 bPseudoTest)
1622 {
1623 #ifdef HAL_EFUSE_MEMORY
1624 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1625 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1626 #endif
1627 u8 *efuseTbl = NULL;
1628 u16 eFuse_Addr = 0;
1629 u8 offset, wden;
1630 u8 efuseHeader, efuseExtHdr, efuseData;
1631 u16 i, total, used;
1632 u8 efuse_usage = 0;
1633
1634 /* RTW_INFO("YJ: ====>%s():_offset=%d _size_byte=%d bPseudoTest=%d\n", __func__, _offset, _size_byte, bPseudoTest); */
1635 /* */
1636 /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
1637 /* */
1638 if ((_offset + _size_byte) > EFUSE_MAX_MAP_LEN) {
1639 RTW_INFO("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1640 return;
1641 }
1642
1643 efuseTbl = (u8 *)rtw_malloc(EFUSE_MAX_MAP_LEN);
1644 if (efuseTbl == NULL) {
1645 RTW_INFO("%s: alloc efuseTbl fail!\n", __FUNCTION__);
1646 return;
1647 }
1648 /* 0xff will be efuse default value instead of 0x00. */
1649 _rtw_memset(efuseTbl, 0xFF, EFUSE_MAX_MAP_LEN);
1650
1651
1652 #ifdef CONFIG_DEBUG
1653 if (0) {
1654 for (i = 0; i < 256; i++)
1655 /* ReadEFuseByte(padapter, i, &efuseTbl[i], _FALSE); */
1656 efuse_OneByteRead(padapter, i, &efuseTbl[i], _FALSE);
1657 RTW_INFO("Efuse Content:\n");
1658 for (i = 0; i < 256; i++) {
1659 if (i % 16 == 0)
1660 printk(KERN_ERR"\n");
1661 printk(KERN_ERR"%02X ", efuseTbl[i]);
1662 }
1663 printk(KERN_ERR"\n");
1664 }
1665 #endif
1666
1667
1668 /* switch bank back to bank 0 for later BT and wifi use. */
1669 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1670
1671 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
1672 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest); */
1673 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1674 if (efuseHeader == 0xFF) {
1675 RTW_INFO("%s: data end at address=%#x\n", __FUNCTION__, eFuse_Addr - 1);
1676 break;
1677 }
1678 /* RTW_INFO("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseHeader); */
1679
1680 /* Check PG header for section num. */
1681 if (EXT_HEADER(efuseHeader)) { /* extended header */
1682 offset = GET_HDR_OFFSET_2_0(efuseHeader);
1683 /* RTW_INFO("%s: extended header offset=0x%X\n", __FUNCTION__, offset); */
1684
1685 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); */
1686 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1687 /* RTW_INFO("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseExtHdr); */
1688 if (ALL_WORDS_DISABLED(efuseExtHdr))
1689 continue;
1690
1691 offset |= ((efuseExtHdr & 0xF0) >> 1);
1692 wden = (efuseExtHdr & 0x0F);
1693 } else {
1694 offset = ((efuseHeader >> 4) & 0x0f);
1695 wden = (efuseHeader & 0x0f);
1696 }
1697 /* RTW_INFO("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden); */
1698
1699 if (offset < EFUSE_MAX_SECTION_8723D) {
1700 u16 addr;
1701 /* Get word enable value from PG header
1702 * RTW_INFO("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden); */
1703
1704 addr = offset * PGPKT_DATA_SIZE;
1705 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
1706 /* Check word enable condition in the section */
1707 if (!(wden & (0x01 << i))) {
1708 efuseData = 0;
1709 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */
1710 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1711 /* RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData); */
1712 efuseTbl[addr] = efuseData;
1713
1714 efuseData = 0;
1715 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */
1716 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1717 /* RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData); */
1718 efuseTbl[addr + 1] = efuseData;
1719 }
1720 addr += 2;
1721 }
1722 } else {
1723 RTW_INFO(KERN_ERR "%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1724 eFuse_Addr += Efuse_CalculateWordCnts(wden) * 2;
1725 }
1726 }
1727
1728 /* Copy from Efuse map to output pointer memory!!! */
1729 for (i = 0; i < _size_byte; i++)
1730 pbuf[i] = efuseTbl[_offset + i];
1731
1732 /* Calculate Efuse utilization */
1733 total = 0;
1734 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1735 used = eFuse_Addr - 1;
1736 if (total)
1737 efuse_usage = (u8)((used * 100) / total);
1738 else
1739 efuse_usage = 100;
1740 if (bPseudoTest) {
1741 #ifdef HAL_EFUSE_MEMORY
1742 pEfuseHal->fakeEfuseUsedBytes = used;
1743 #else
1744 fakeEfuseUsedBytes = used;
1745 #endif
1746 } else {
1747 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&used);
1748 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8 *)&efuse_usage);
1749 }
1750
1751 if (efuseTbl)
1752 rtw_mfree(efuseTbl, EFUSE_MAX_MAP_LEN);
1753 }
1754
1755 static void
hal_ReadEFuse_BT(PADAPTER padapter,u16 _offset,u16 _size_byte,u8 * pbuf,u8 bPseudoTest)1756 hal_ReadEFuse_BT(
1757 PADAPTER padapter,
1758 u16 _offset,
1759 u16 _size_byte,
1760 u8 *pbuf,
1761 u8 bPseudoTest
1762 )
1763 {
1764 #ifdef HAL_EFUSE_MEMORY
1765 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1766 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1767 #endif
1768 u8 *efuseTbl;
1769 u8 bank;
1770 u16 eFuse_Addr;
1771 u8 efuseHeader, efuseExtHdr, efuseData;
1772 u8 offset, wden;
1773 u16 i, total, used;
1774 u8 efuse_usage;
1775
1776
1777 /* */
1778 /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
1779 /* */
1780 if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) {
1781 RTW_INFO("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1782 return;
1783 }
1784
1785 efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);
1786 if (efuseTbl == NULL) {
1787 RTW_INFO("%s: efuseTbl malloc fail!\n", __FUNCTION__);
1788 return;
1789 }
1790 /* 0xff will be efuse default value instead of 0x00. */
1791 _rtw_memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
1792
1793 total = 0;
1794 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total, bPseudoTest);
1795
1796 for (bank = 1; bank < 3; bank++) { /* 8723d Max bake 0~2 */
1797 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE) {
1798 RTW_INFO("%s: hal_EfuseSwitchToBank Fail!!\n", __FUNCTION__);
1799 goto exit;
1800 }
1801
1802 eFuse_Addr = 0;
1803
1804 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
1805 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest); */
1806 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1807 if (efuseHeader == 0xFF)
1808 break;
1809 RTW_INFO("%s: efuse[%#X]=0x%02x (header)\n", __FUNCTION__, (((bank - 1) * EFUSE_REAL_CONTENT_LEN_8723D) + eFuse_Addr - 1), efuseHeader);
1810
1811 /* Check PG header for section num. */
1812 if (EXT_HEADER(efuseHeader)) { /* extended header */
1813 offset = GET_HDR_OFFSET_2_0(efuseHeader);
1814 RTW_INFO("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset);
1815
1816 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); */
1817 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1818 RTW_INFO("%s: efuse[%#X]=0x%02x (ext header)\n", __FUNCTION__, (((bank - 1) * EFUSE_REAL_CONTENT_LEN_8723D) + eFuse_Addr - 1), efuseExtHdr);
1819 if (ALL_WORDS_DISABLED(efuseExtHdr))
1820 continue;
1821
1822 offset |= ((efuseExtHdr & 0xF0) >> 1);
1823 wden = (efuseExtHdr & 0x0F);
1824 } else {
1825 offset = ((efuseHeader >> 4) & 0x0f);
1826 wden = (efuseHeader & 0x0f);
1827 }
1828
1829 if (offset < EFUSE_BT_MAX_SECTION) {
1830 u16 addr;
1831
1832 /* Get word enable value from PG header */
1833 RTW_INFO("%s: Offset=%d Worden=%#X\n", __FUNCTION__, offset, wden);
1834
1835 addr = offset * PGPKT_DATA_SIZE;
1836 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
1837 /* Check word enable condition in the section */
1838 if (!(wden & (0x01 << i))) {
1839 efuseData = 0;
1840 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */
1841 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1842 RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr - 1, efuseData);
1843 efuseTbl[addr] = efuseData;
1844
1845 efuseData = 0;
1846 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */
1847 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1848 RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr - 1, efuseData);
1849 efuseTbl[addr + 1] = efuseData;
1850 }
1851 addr += 2;
1852 }
1853 } else {
1854 RTW_INFO("%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1855 eFuse_Addr += Efuse_CalculateWordCnts(wden) * 2;
1856 }
1857 }
1858
1859 if ((eFuse_Addr - 1) < total) {
1860 RTW_INFO("%s: bank(%d) data end at %#x\n", __FUNCTION__, bank, eFuse_Addr - 1);
1861 break;
1862 }
1863 }
1864
1865 /* switch bank back to bank 0 for later BT and wifi use. */
1866 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1867
1868 /* Copy from Efuse map to output pointer memory!!! */
1869 for (i = 0; i < _size_byte; i++)
1870 pbuf[i] = efuseTbl[_offset + i];
1871
1872 /* */
1873 /* Calculate Efuse utilization. */
1874 /* */
1875 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1876 used = (EFUSE_BT_REAL_BANK_CONTENT_LEN * (bank - 1)) + eFuse_Addr - 1;
1877 RTW_INFO("%s: bank(%d) data end at %#x ,used =%d\n", __FUNCTION__, bank, eFuse_Addr - 1, used);
1878 efuse_usage = (u8)((used * 100) / total);
1879 if (bPseudoTest) {
1880 #ifdef HAL_EFUSE_MEMORY
1881 pEfuseHal->fakeBTEfuseUsedBytes = used;
1882 #else
1883 fakeBTEfuseUsedBytes = used;
1884 #endif
1885 } else {
1886 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&used);
1887 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8 *)&efuse_usage);
1888 }
1889
1890 exit:
1891 if (efuseTbl)
1892 rtw_mfree(efuseTbl, EFUSE_BT_MAP_LEN);
1893 }
1894
1895 static void
Hal_ReadEFuse(PADAPTER padapter,u8 efuseType,u16 _offset,u16 _size_byte,u8 * pbuf,u8 bPseudoTest)1896 Hal_ReadEFuse(
1897 PADAPTER padapter,
1898 u8 efuseType,
1899 u16 _offset,
1900 u16 _size_byte,
1901 u8 *pbuf,
1902 u8 bPseudoTest)
1903 {
1904 if (efuseType == EFUSE_WIFI)
1905 hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1906 else
1907 hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1908 }
1909
1910 static u16
hal_EfuseGetCurrentSize_WiFi(PADAPTER padapter,u8 bPseudoTest)1911 hal_EfuseGetCurrentSize_WiFi(
1912 PADAPTER padapter,
1913 u8 bPseudoTest)
1914 {
1915 #ifdef HAL_EFUSE_MEMORY
1916 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1917 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1918 #endif
1919 u16 efuse_addr = 0;
1920 u16 start_addr = 0; /* for debug */
1921 u8 hoffset = 0, hworden = 0;
1922 u8 efuse_data, word_cnts = 0;
1923 u32 count = 0; /* for debug */
1924
1925
1926 if (bPseudoTest) {
1927 #ifdef HAL_EFUSE_MEMORY
1928 efuse_addr = (u16)pEfuseHal->fakeEfuseUsedBytes;
1929 #else
1930 efuse_addr = (u16)fakeEfuseUsedBytes;
1931 #endif
1932 } else
1933 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1934 start_addr = efuse_addr;
1935 RTW_INFO("%s: start_efuse_addr=0x%X\n", __FUNCTION__, efuse_addr);
1936
1937 /* switch bank back to bank 0 for later BT and wifi use. */
1938 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1939
1940 #if 0 /* for debug test */
1941 efuse_OneByteRead(padapter, 0x1FF, &efuse_data, bPseudoTest);
1942 RTW_INFO(FUNC_ADPT_FMT ": efuse raw 0x1FF=0x%02X\n",
1943 FUNC_ADPT_ARG(padapter), efuse_data);
1944 efuse_data = 0xFF;
1945 #endif /* for debug test */
1946
1947 count = 0;
1948 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1949 #if 1
1950 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE) {
1951 RTW_INFO(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
1952 goto error;
1953 }
1954 #else
1955 ReadEFuseByte(padapter, efuse_addr, &efuse_data, bPseudoTest);
1956 #endif
1957
1958 if (efuse_data == 0xFF)
1959 break;
1960
1961 if ((start_addr != 0) && (efuse_addr == start_addr)) {
1962 count++;
1963 RTW_INFO(FUNC_ADPT_FMT ": [WARNING] efuse raw 0x%X=0x%02X not 0xFF!!(%d times)\n",
1964 FUNC_ADPT_ARG(padapter), efuse_addr, efuse_data, count);
1965
1966 efuse_data = 0xFF;
1967 if (count < 4) {
1968 /* try again! */
1969
1970 if (count > 2) {
1971 /* try again form address 0 */
1972 efuse_addr = 0;
1973 start_addr = 0;
1974 }
1975
1976 continue;
1977 }
1978
1979 goto error;
1980 }
1981
1982 if (EXT_HEADER(efuse_data)) {
1983 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1984 efuse_addr++;
1985 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1986 if (ALL_WORDS_DISABLED(efuse_data))
1987 continue;
1988
1989 hoffset |= ((efuse_data & 0xF0) >> 1);
1990 hworden = efuse_data & 0x0F;
1991 } else {
1992 hoffset = (efuse_data >> 4) & 0x0F;
1993 hworden = efuse_data & 0x0F;
1994 }
1995
1996 word_cnts = Efuse_CalculateWordCnts(hworden);
1997 efuse_addr += (word_cnts * 2) + 1;
1998 }
1999
2000 if (bPseudoTest) {
2001 #ifdef HAL_EFUSE_MEMORY
2002 pEfuseHal->fakeEfuseUsedBytes = efuse_addr;
2003 #else
2004 fakeEfuseUsedBytes = efuse_addr;
2005 #endif
2006 } else
2007 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
2008
2009 goto exit;
2010
2011 error:
2012 /* report max size to prevent write efuse */
2013 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_addr, bPseudoTest);
2014
2015 exit:
2016 RTW_INFO("%s: CurrentSize=%d\n", __FUNCTION__, efuse_addr);
2017
2018 return efuse_addr;
2019 }
2020
2021 static u16
hal_EfuseGetCurrentSize_BT(PADAPTER padapter,u8 bPseudoTest)2022 hal_EfuseGetCurrentSize_BT(
2023 PADAPTER padapter,
2024 u8 bPseudoTest)
2025 {
2026 #ifdef HAL_EFUSE_MEMORY
2027 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2028 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
2029 #endif
2030 u16 btusedbytes;
2031 u16 efuse_addr;
2032 u8 bank, startBank;
2033 u8 hoffset = 0, hworden = 0;
2034 u8 efuse_data, word_cnts = 0;
2035 u16 retU2 = 0;
2036 u8 bContinual = _TRUE;
2037
2038
2039 if (bPseudoTest) {
2040 #ifdef HAL_EFUSE_MEMORY
2041 btusedbytes = pEfuseHal->fakeBTEfuseUsedBytes;
2042 #else
2043 btusedbytes = fakeBTEfuseUsedBytes;
2044 #endif
2045 } else {
2046 btusedbytes = 0;
2047 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&btusedbytes);
2048 }
2049 efuse_addr = (u16)((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN));
2050 startBank = (u8)(1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN));
2051
2052 RTW_INFO("%s: start from bank=%d addr=0x%X\n", __FUNCTION__, startBank, efuse_addr);
2053
2054 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2, bPseudoTest);
2055
2056 for (bank = startBank; bank < 3; bank++) {
2057 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE) {
2058 RTW_INFO(KERN_ERR "%s: switch bank(%d) Fail!!\n", __FUNCTION__, bank);
2059 /* bank = EFUSE_MAX_BANK; */
2060 break;
2061 }
2062
2063 /* only when bank is switched we have to reset the efuse_addr. */
2064 if (bank != startBank)
2065 efuse_addr = 0;
2066 #if 1
2067
2068 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
2069 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE) {
2070 RTW_INFO(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
2071 /* bank = EFUSE_MAX_BANK; */
2072 break;
2073 }
2074 RTW_INFO("%s: efuse_OneByteRead ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr, efuse_data, bank);
2075
2076 if (efuse_data == 0xFF)
2077 break;
2078
2079 if (EXT_HEADER(efuse_data)) {
2080 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
2081 efuse_addr++;
2082 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
2083 RTW_INFO("%s: efuse_OneByteRead EXT_HEADER ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr, efuse_data, bank);
2084
2085 if (ALL_WORDS_DISABLED(efuse_data)) {
2086 efuse_addr++;
2087 continue;
2088 }
2089
2090 /* hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); */
2091 hoffset |= ((efuse_data & 0xF0) >> 1);
2092 hworden = efuse_data & 0x0F;
2093 } else {
2094 hoffset = (efuse_data >> 4) & 0x0F;
2095 hworden = efuse_data & 0x0F;
2096 }
2097
2098 RTW_INFO(FUNC_ADPT_FMT": Offset=%d Worden=%#X\n",
2099 FUNC_ADPT_ARG(padapter), hoffset, hworden);
2100
2101 word_cnts = Efuse_CalculateWordCnts(hworden);
2102 /* read next header */
2103 efuse_addr += (word_cnts * 2) + 1;
2104 }
2105 #else
2106 while (bContinual &&
2107 efuse_OneByteRead(padapter, efuse_addr , &efuse_data, bPseudoTest) &&
2108 AVAILABLE_EFUSE_ADDR(efuse_addr)) {
2109 if (efuse_data != 0xFF) {
2110 if ((efuse_data & 0x1F) == 0x0F) { /* extended header */
2111 hoffset = efuse_data;
2112 efuse_addr++;
2113 efuse_OneByteRead(padapter, efuse_addr , &efuse_data, bPseudoTest);
2114 if ((efuse_data & 0x0F) == 0x0F) {
2115 efuse_addr++;
2116 continue;
2117 } else {
2118 hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2119 hworden = efuse_data & 0x0F;
2120 }
2121 } else {
2122 hoffset = (efuse_data >> 4) & 0x0F;
2123 hworden = efuse_data & 0x0F;
2124 }
2125 word_cnts = Efuse_CalculateWordCnts(hworden);
2126 /* read next header */
2127 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
2128 } else
2129 bContinual = _FALSE;
2130 }
2131 #endif
2132
2133
2134 /* Check if we need to check next bank efuse */
2135 if (efuse_addr < retU2)
2136 break;/* don't need to check next bank. */
2137 }
2138 #if 0
2139 retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
2140 if (bPseudoTest) {
2141 #ifdef HAL_EFUSE_MEMORY
2142 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
2143 #else
2144 fakeBTEfuseUsedBytes = retU2;
2145 #endif
2146 } else
2147 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&retU2);
2148 #else
2149 retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
2150 if (bPseudoTest) {
2151 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
2152 /* RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->fakeBTEfuseUsedBytes)); */
2153 } else {
2154 pEfuseHal->BTEfuseUsedBytes = retU2;
2155 /* RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->BTEfuseUsedBytes)); */
2156 }
2157 #endif
2158
2159 RTW_INFO("%s: CurrentSize=%d\n", __FUNCTION__, retU2);
2160 return retU2;
2161 }
2162
2163 static u16
Hal_EfuseGetCurrentSize(PADAPTER pAdapter,u8 efuseType,u8 bPseudoTest)2164 Hal_EfuseGetCurrentSize(
2165 PADAPTER pAdapter,
2166 u8 efuseType,
2167 u8 bPseudoTest)
2168 {
2169 u16 ret = 0;
2170
2171 if (efuseType == EFUSE_WIFI)
2172 ret = hal_EfuseGetCurrentSize_WiFi(pAdapter, bPseudoTest);
2173 else
2174 ret = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest);
2175
2176 return ret;
2177 }
2178
2179 static u8
Hal_EfuseWordEnableDataWrite(PADAPTER padapter,u16 efuse_addr,u8 word_en,u8 * data,u8 bPseudoTest)2180 Hal_EfuseWordEnableDataWrite(
2181 PADAPTER padapter,
2182 u16 efuse_addr,
2183 u8 word_en,
2184 u8 *data,
2185 u8 bPseudoTest)
2186 {
2187 u16 tmpaddr = 0;
2188 u16 start_addr = efuse_addr;
2189 u8 badworden = 0x0F;
2190 u8 tmpdata[PGPKT_DATA_SIZE];
2191
2192
2193 /* RTW_INFO("%s: efuse_addr=%#x word_en=%#x\n", __FUNCTION__, efuse_addr, word_en); */
2194 _rtw_memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
2195
2196 if (!(word_en & BIT(0))) {
2197 tmpaddr = start_addr;
2198 efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest);
2199 efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest);
2200
2201 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest);
2202 efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[1], bPseudoTest);
2203 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
2204 badworden &= (~BIT(0));
2205 }
2206 if (!(word_en & BIT(1))) {
2207 tmpaddr = start_addr;
2208 efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest);
2209 efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest);
2210
2211 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest);
2212 efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[3], bPseudoTest);
2213 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
2214 badworden &= (~BIT(1));
2215 }
2216 if (!(word_en & BIT(2))) {
2217 tmpaddr = start_addr;
2218 efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest);
2219 efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest);
2220
2221 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest);
2222 efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[5], bPseudoTest);
2223 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
2224 badworden &= (~BIT(2));
2225 }
2226 if (!(word_en & BIT(3))) {
2227 tmpaddr = start_addr;
2228 efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest);
2229 efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest);
2230
2231 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest);
2232 efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[7], bPseudoTest);
2233 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
2234 badworden &= (~BIT(3));
2235 }
2236
2237 return badworden;
2238 }
2239
2240 static s32
Hal_EfusePgPacketRead(PADAPTER padapter,u8 offset,u8 * data,u8 bPseudoTest)2241 Hal_EfusePgPacketRead(
2242 PADAPTER padapter,
2243 u8 offset,
2244 u8 *data,
2245 u8 bPseudoTest)
2246 {
2247 u8 bDataEmpty = _TRUE;
2248 u8 efuse_data, word_cnts = 0;
2249 u16 efuse_addr = 0;
2250 u8 hoffset = 0, hworden = 0;
2251 u8 i;
2252 u8 max_section = 0;
2253 s32 ret;
2254
2255
2256 if (data == NULL)
2257 return _FALSE;
2258
2259 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest);
2260 if (offset > max_section) {
2261 RTW_INFO("%s: Packet offset(%d) is illegal(>%d)!\n", __FUNCTION__, offset, max_section);
2262 return _FALSE;
2263 }
2264
2265 _rtw_memset(data, 0xFF, PGPKT_DATA_SIZE);
2266 ret = _TRUE;
2267
2268 /* */
2269 /* <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */
2270 /* Skip dummy parts to prevent unexpected data read from Efuse. */
2271 /* By pass right now. 2009.02.19. */
2272 /* */
2273 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
2274 if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == _FALSE) {
2275 ret = _FALSE;
2276 break;
2277 }
2278
2279 if (efuse_data == 0xFF)
2280 break;
2281
2282 if (EXT_HEADER(efuse_data)) {
2283 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
2284 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2285 if (ALL_WORDS_DISABLED(efuse_data)) {
2286 RTW_INFO("%s: Error!! All words disabled!\n", __FUNCTION__);
2287 continue;
2288 }
2289
2290 hoffset |= ((efuse_data & 0xF0) >> 1);
2291 hworden = efuse_data & 0x0F;
2292 } else {
2293 hoffset = (efuse_data >> 4) & 0x0F;
2294 hworden = efuse_data & 0x0F;
2295 }
2296
2297 if (hoffset == offset) {
2298 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
2299 /* Check word enable condition in the section */
2300 if (!(hworden & (0x01 << i))) {
2301 /* ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest); */
2302 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2303 /* RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data); */
2304 data[i * 2] = efuse_data;
2305
2306 /* ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest); */
2307 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2308 /* RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data); */
2309 data[(i * 2) + 1] = efuse_data;
2310 }
2311 }
2312 } else {
2313 word_cnts = Efuse_CalculateWordCnts(hworden);
2314 efuse_addr += word_cnts * 2;
2315 }
2316 }
2317
2318 return ret;
2319 }
2320
2321 static u8
hal_EfusePgCheckAvailableAddr(PADAPTER pAdapter,u8 efuseType,u8 bPseudoTest)2322 hal_EfusePgCheckAvailableAddr(
2323 PADAPTER pAdapter,
2324 u8 efuseType,
2325 u8 bPseudoTest)
2326 {
2327 u16 max_available = 0;
2328 u16 current_size;
2329
2330
2331 EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &max_available, bPseudoTest);
2332 /* RTW_INFO("%s: max_available=%d\n", __FUNCTION__, max_available); */
2333
2334 current_size = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
2335 if (current_size >= max_available) {
2336 RTW_INFO("%s: Error!! current_size(%d)>max_available(%d)\n", __FUNCTION__, current_size, max_available);
2337 return _FALSE;
2338 }
2339 return _TRUE;
2340 }
2341
2342 static void
hal_EfuseConstructPGPkt(u8 offset,u8 word_en,u8 * pData,PPGPKT_STRUCT pTargetPkt)2343 hal_EfuseConstructPGPkt(
2344 u8 offset,
2345 u8 word_en,
2346 u8 *pData,
2347 PPGPKT_STRUCT pTargetPkt)
2348 {
2349 _rtw_memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
2350 pTargetPkt->offset = offset;
2351 pTargetPkt->word_en = word_en;
2352 efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
2353 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2354 }
2355
2356 #if 0
2357 static u8
2358 wordEnMatched(
2359 PPGPKT_STRUCT pTargetPkt,
2360 PPGPKT_STRUCT pCurPkt,
2361 u8 *pWden)
2362 {
2363 u8 match_word_en = 0x0F; /* default all words are disabled */
2364 u8 i;
2365
2366 /* check if the same words are enabled both target and current PG packet */
2367 if (((pTargetPkt->word_en & BIT(0)) == 0) &&
2368 ((pCurPkt->word_en & BIT(0)) == 0)) {
2369 match_word_en &= ~BIT(0); /* enable word 0 */
2370 }
2371 if (((pTargetPkt->word_en & BIT(1)) == 0) &&
2372 ((pCurPkt->word_en & BIT(1)) == 0)) {
2373 match_word_en &= ~BIT(1); /* enable word 1 */
2374 }
2375 if (((pTargetPkt->word_en & BIT(2)) == 0) &&
2376 ((pCurPkt->word_en & BIT(2)) == 0)) {
2377 match_word_en &= ~BIT(2); /* enable word 2 */
2378 }
2379 if (((pTargetPkt->word_en & BIT(3)) == 0) &&
2380 ((pCurPkt->word_en & BIT(3)) == 0)) {
2381 match_word_en &= ~BIT(3); /* enable word 3 */
2382 }
2383
2384 *pWden = match_word_en;
2385
2386 if (match_word_en != 0xf)
2387 return _TRUE;
2388 else
2389 return _FALSE;
2390 }
2391
2392 static u8
2393 hal_EfuseCheckIfDatafollowed(
2394 PADAPTER pAdapter,
2395 u8 word_cnts,
2396 u16 startAddr,
2397 u8 bPseudoTest)
2398 {
2399 u8 bRet = _FALSE;
2400 u8 i, efuse_data;
2401
2402 for (i = 0; i < (word_cnts * 2); i++) {
2403 if (efuse_OneByteRead(pAdapter, (startAddr + i) , &efuse_data, bPseudoTest) == _FALSE) {
2404 RTW_INFO("%s: efuse_OneByteRead FAIL!!\n", __FUNCTION__);
2405 bRet = _TRUE;
2406 break;
2407 }
2408
2409 if (efuse_data != 0xFF) {
2410 bRet = _TRUE;
2411 break;
2412 }
2413 }
2414
2415 return bRet;
2416 }
2417 #endif
2418
2419 static u8
hal_EfusePartialWriteCheck(PADAPTER padapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,u8 bPseudoTest)2420 hal_EfusePartialWriteCheck(
2421 PADAPTER padapter,
2422 u8 efuseType,
2423 u16 *pAddr,
2424 PPGPKT_STRUCT pTargetPkt,
2425 u8 bPseudoTest)
2426 {
2427 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2428 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
2429 u8 bRet = _FALSE;
2430 u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
2431 u8 efuse_data = 0;
2432 #if 0
2433 u8 i, cur_header = 0;
2434 u8 new_wden = 0, matched_wden = 0, badworden = 0;
2435 PGPKT_STRUCT curPkt;
2436 #endif
2437
2438
2439 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest);
2440 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest);
2441
2442 if (efuseType == EFUSE_WIFI) {
2443 if (bPseudoTest) {
2444 #ifdef HAL_EFUSE_MEMORY
2445 startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes;
2446 #else
2447 startAddr = (u16)fakeEfuseUsedBytes;
2448 #endif
2449 } else
2450 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
2451 } else {
2452 if (bPseudoTest) {
2453 #ifdef HAL_EFUSE_MEMORY
2454 startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes;
2455 #else
2456 startAddr = (u16)fakeBTEfuseUsedBytes;
2457 #endif
2458 } else
2459 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&startAddr);
2460 }
2461 startAddr %= efuse_max;
2462 RTW_INFO("%s: startAddr=%#X\n", __FUNCTION__, startAddr);
2463
2464 while (1) {
2465 if (startAddr >= efuse_max_available_len) {
2466 bRet = _FALSE;
2467 RTW_INFO("%s: startAddr(%d) >= efuse_max_available_len(%d)\n",
2468 __FUNCTION__, startAddr, efuse_max_available_len);
2469 break;
2470 }
2471
2472 if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
2473 #if 1
2474 bRet = _FALSE;
2475 RTW_INFO("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n",
2476 __FUNCTION__, startAddr, efuse_data);
2477 break;
2478 #else
2479 if (EXT_HEADER(efuse_data)) {
2480 cur_header = efuse_data;
2481 startAddr++;
2482 efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest);
2483 if (ALL_WORDS_DISABLED(efuse_data)) {
2484 RTW_INFO("%s: Error condition, all words disabled!", __FUNCTION__);
2485 bRet = _FALSE;
2486 break;
2487 } /*else*/
2488 {
2489 curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2490 curPkt.word_en = efuse_data & 0x0F;
2491 }
2492 } else {
2493 cur_header = efuse_data;
2494 curPkt.offset = (cur_header >> 4) & 0x0F;
2495 curPkt.word_en = cur_header & 0x0F;
2496 }
2497
2498 curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
2499 /* if same header is found but no data followed */
2500 /* write some part of data followed by the header. */
2501 if ((curPkt.offset == pTargetPkt->offset) &&
2502 (hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr + 1, bPseudoTest) == _FALSE) &&
2503 wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == _TRUE) {
2504 RTW_INFO("%s: Need to partial write data by the previous wrote header\n", __FUNCTION__);
2505 /* Here to write partial data */
2506 badworden = Efuse_WordEnableDataWrite(padapter, startAddr + 1, matched_wden, pTargetPkt->data, bPseudoTest);
2507 if (badworden != 0x0F) {
2508 u32 PgWriteSuccess = 0;
2509 /* if write fail on some words, write these bad words again */
2510 if (efuseType == EFUSE_WIFI)
2511 PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2512 else
2513 PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2514
2515 if (!PgWriteSuccess) {
2516 bRet = _FALSE; /* write fail, return */
2517 break;
2518 }
2519 }
2520 /* partial write ok, update the target packet for later use */
2521 for (i = 0; i < 4; i++) {
2522 if ((matched_wden & (0x1 << i)) == 0) { /* this word has been written */
2523 pTargetPkt->word_en |= (0x1 << i); /* disable the word */
2524 }
2525 }
2526 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2527 }
2528 /* read from next header */
2529 startAddr = startAddr + (curPkt.word_cnts * 2) + 1;
2530 #endif
2531 } else {
2532 /* not used header, 0xff */
2533 *pAddr = startAddr;
2534 /* RTW_INFO("%s: Started from unused header offset=%d\n", __FUNCTION__, startAddr)); */
2535 bRet = _TRUE;
2536 break;
2537 }
2538 }
2539
2540 return bRet;
2541 }
2542
2543 static u8
hal_EfusePgPacketWrite1ByteHeader(PADAPTER pAdapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,u8 bPseudoTest)2544 hal_EfusePgPacketWrite1ByteHeader(
2545 PADAPTER pAdapter,
2546 u8 efuseType,
2547 u16 *pAddr,
2548 PPGPKT_STRUCT pTargetPkt,
2549 u8 bPseudoTest)
2550 {
2551 u8 bRet = _FALSE;
2552 u8 pg_header = 0, tmp_header = 0;
2553 u16 efuse_addr = *pAddr;
2554 u8 repeatcnt = 0;
2555
2556
2557 /* RTW_INFO("%s\n", __FUNCTION__); */
2558 pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
2559
2560 do {
2561 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2562 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2563 if (tmp_header != 0xFF)
2564 break;
2565 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2566 RTW_INFO("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
2567 return _FALSE;
2568 }
2569 } while (1);
2570
2571 if (tmp_header != pg_header) {
2572 RTW_INFO(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
2573 return _FALSE;
2574 }
2575
2576 *pAddr = efuse_addr;
2577
2578 return _TRUE;
2579 }
2580
2581 static u8
hal_EfusePgPacketWrite2ByteHeader(PADAPTER padapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,u8 bPseudoTest)2582 hal_EfusePgPacketWrite2ByteHeader(
2583 PADAPTER padapter,
2584 u8 efuseType,
2585 u16 *pAddr,
2586 PPGPKT_STRUCT pTargetPkt,
2587 u8 bPseudoTest)
2588 {
2589 u16 efuse_addr, efuse_max_available_len = 0;
2590 u8 pg_header = 0, tmp_header = 0;
2591 u8 repeatcnt = 0;
2592
2593
2594 /* RTW_INFO("%s\n", __FUNCTION__); */
2595 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest);
2596
2597 efuse_addr = *pAddr;
2598 if (efuse_addr >= efuse_max_available_len) {
2599 RTW_INFO("%s: addr(%d) over available(%d)!!\n", __FUNCTION__, efuse_addr, efuse_max_available_len);
2600 return _FALSE;
2601 }
2602
2603 pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
2604 /* RTW_INFO("%s: pg_header=0x%x\n", __FUNCTION__, pg_header); */
2605
2606 do {
2607 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2608 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2609 if (tmp_header != 0xFF)
2610 break;
2611 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2612 RTW_INFO("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
2613 return _FALSE;
2614 }
2615 } while (1);
2616
2617 if (tmp_header != pg_header) {
2618 RTW_INFO(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
2619 return _FALSE;
2620 }
2621
2622 /* to write ext_header */
2623 efuse_addr++;
2624 pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
2625
2626 do {
2627 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2628 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2629 if (tmp_header != 0xFF)
2630 break;
2631 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2632 RTW_INFO("%s: Repeat over limit for ext_header!!\n", __FUNCTION__);
2633 return _FALSE;
2634 }
2635 } while (1);
2636
2637 if (tmp_header != pg_header) { /* offset PG fail */
2638 RTW_INFO(KERN_ERR "%s: PG EXT Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
2639 return _FALSE;
2640 }
2641
2642 *pAddr = efuse_addr;
2643
2644 return _TRUE;
2645 }
2646
2647 static u8
hal_EfusePgPacketWriteHeader(PADAPTER padapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,u8 bPseudoTest)2648 hal_EfusePgPacketWriteHeader(
2649 PADAPTER padapter,
2650 u8 efuseType,
2651 u16 *pAddr,
2652 PPGPKT_STRUCT pTargetPkt,
2653 u8 bPseudoTest)
2654 {
2655 u8 bRet = _FALSE;
2656
2657 if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
2658 bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2659 else
2660 bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2661
2662 return bRet;
2663 }
2664
2665 static u8
hal_EfusePgPacketWriteData(PADAPTER pAdapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,u8 bPseudoTest)2666 hal_EfusePgPacketWriteData(
2667 PADAPTER pAdapter,
2668 u8 efuseType,
2669 u16 *pAddr,
2670 PPGPKT_STRUCT pTargetPkt,
2671 u8 bPseudoTest)
2672 {
2673 u16 efuse_addr;
2674 u8 badworden;
2675
2676
2677 efuse_addr = *pAddr;
2678 badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
2679 if (badworden != 0x0F) {
2680 RTW_INFO("%s: Fail!!\n", __FUNCTION__);
2681 return _FALSE;
2682 }
2683
2684 /* RTW_INFO("%s: ok\n", __FUNCTION__); */
2685 return _TRUE;
2686 }
2687
2688 static s32
Hal_EfusePgPacketWrite(PADAPTER padapter,u8 offset,u8 word_en,u8 * pData,u8 bPseudoTest)2689 Hal_EfusePgPacketWrite(
2690 PADAPTER padapter,
2691 u8 offset,
2692 u8 word_en,
2693 u8 *pData,
2694 u8 bPseudoTest)
2695 {
2696 PGPKT_STRUCT targetPkt;
2697 u16 startAddr = 0;
2698 u8 efuseType = EFUSE_WIFI;
2699
2700 if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest))
2701 return _FALSE;
2702
2703 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2704
2705 if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2706 return _FALSE;
2707
2708 if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2709 return _FALSE;
2710
2711 if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2712 return _FALSE;
2713
2714 return _TRUE;
2715 }
2716
2717 static u8
Hal_EfusePgPacketWrite_BT(PADAPTER pAdapter,u8 offset,u8 word_en,u8 * pData,u8 bPseudoTest)2718 Hal_EfusePgPacketWrite_BT(
2719 PADAPTER pAdapter,
2720 u8 offset,
2721 u8 word_en,
2722 u8 *pData,
2723 u8 bPseudoTest)
2724 {
2725 PGPKT_STRUCT targetPkt;
2726 u16 startAddr = 0;
2727 u8 efuseType = EFUSE_BT;
2728
2729 if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
2730 return _FALSE;
2731
2732 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2733
2734 if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2735 return _FALSE;
2736
2737 if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2738 return _FALSE;
2739
2740 if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2741 return _FALSE;
2742
2743 return _TRUE;
2744 }
2745
2746
read_chip_version_8723d(PADAPTER padapter)2747 static void read_chip_version_8723d(PADAPTER padapter)
2748 {
2749 u32 value32;
2750 HAL_DATA_TYPE *pHalData;
2751
2752 pHalData = GET_HAL_DATA(padapter);
2753
2754 value32 = rtw_read32(padapter, REG_SYS_CFG);
2755 pHalData->version_id.ICType = CHIP_8723D;
2756 pHalData->version_id.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
2757 pHalData->version_id.RFType = RF_TYPE_1T1R;
2758 pHalData->version_id.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
2759 pHalData->version_id.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */
2760
2761 /* For regulator mode. by tynli. 2011.01.14 */
2762 pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
2763
2764 value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
2765 pHalData->version_id.ROMVer = ((value32 & RF_RL_ID) >> 20); /* ROM code version. */
2766
2767 /* For multi-function consideration. Added by Roger, 2010.10.06. */
2768 pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
2769 value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
2770 pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
2771 pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
2772 pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
2773 pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT);
2774
2775 /*
2776 if( IS_B_CUT(pHalData->version_id) || IS_C_CUT(pHalData->version_id))
2777 {
2778 RTW_INFO(" IS_B/C_CUT SWR up 1 level !!!!!!!!!!!!!!!!!\n");
2779 phy_set_mac_reg(padapter, 0x14, BIT(23)|BIT(22)|BIT(21)|BIT(20), 0x5);
2780 }else if ( IS_D_CUT(pHalData->version_id))
2781 {
2782 RTW_INFO(" IS_D_CUT SKIP SWR !!!!!!!!!!!!!!!!!\n");
2783 }
2784 */
2785
2786 #if 1
2787 dump_chip_info(pHalData->version_id);
2788 #endif
2789
2790 }
2791
2792
rtl8723d_InitBeaconParameters(PADAPTER padapter)2793 void rtl8723d_InitBeaconParameters(PADAPTER padapter)
2794 {
2795 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2796 u16 val16;
2797 u8 val8;
2798
2799
2800 val8 = DIS_TSF_UDT;
2801 val16 = val8 | (val8 << 8); /* port0 and port1 */
2802 #ifdef CONFIG_BT_COEXIST
2803 /* Enable prot0 beacon function for PSTDMA */
2804 val16 |= EN_BCN_FUNCTION;
2805 #endif
2806
2807 #ifdef CONFIG_CONCURRENT_MODE
2808 val16 |= (EN_BCN_FUNCTION << 8);
2809 #endif
2810 rtw_write16(padapter, REG_BCN_CTRL, val16);
2811
2812 /* TBTT setup time */
2813 rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
2814
2815 /* TBTT hold time: 0x540[19:8] */
2816 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
2817 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
2818 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
2819
2820 /* Firmware will control REG_DRVERLYINT when power saving is enable, */
2821 /* so don't set this register on STA mode. */
2822 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _FALSE)
2823 rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8723D); /* 5ms */
2824 rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8723D); /* 2ms */
2825
2826 /* Suggested by designer timchen. Change beacon AIFS to the largest number */
2827 /* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
2828 rtw_write16(padapter, REG_BCNTCFG, 0x4413);
2829
2830 }
2831
rtl8723d_InitBeaconMaxError(PADAPTER padapter,u8 InfraMode)2832 void rtl8723d_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode)
2833 {
2834 #ifdef CONFIG_ADHOC_WORKAROUND_SETTING
2835 rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
2836 #else
2837 /* rtw_write8(Adapter, REG_BCN_MAX_ERR, (InfraMode ? 0xFF : 0x10)); */
2838 #endif
2839 }
2840
_InitMacAPLLSetting_8723D(PADAPTER Adapter)2841 void _InitMacAPLLSetting_8723D(PADAPTER Adapter)
2842 {
2843
2844 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
2845 u16 RegValue;
2846 u8 afe;
2847
2848 RegValue = rtw_read16(Adapter, REG_AFE_CTRL_4_8723D);
2849 RegValue |= BIT(4);
2850 RegValue |= BIT(15);
2851 rtw_write16(Adapter, REG_AFE_CTRL_4_8723D, RegValue);
2852
2853 /*
2854 * 8723D with 24MHz xtal has VCO noise issue
2855 * This will cause some TRx test fail
2856 * Therefore, set MAC GM parameter for 24MHz xtal
2857 * AFE[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ] =
2858 * [ 40M 25M 13M 19.2M 20M 26M 38.4M 17.664M 16M 14.318M 12M 52M 48M 27M 24M ]
2859 */
2860 afe = (pHalData->efuse_eeprom_data[4] >>4);
2861 if( afe == 14) {
2862 rtw_write32(Adapter, 0x2c, (rtw_read32(Adapter, 0x2c) | BIT28));
2863 rtw_write32(Adapter, 0x24, (rtw_read32(Adapter, 0x24) & 0xFFFFFF0F));
2864 rtw_write32(Adapter, 0x7c, ((rtw_read32(Adapter, 0x7c) | BIT29) & (~BIT28)));
2865 }
2866
2867 }
2868
_BeaconFunctionEnable(PADAPTER padapter,u8 Enable,u8 Linked)2869 static void _BeaconFunctionEnable(PADAPTER padapter, u8 Enable, u8 Linked)
2870 {
2871 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
2872 rtw_write8(padapter, REG_RD_CTRL + 1, 0x6F);
2873 }
2874
rtl8723d_SetBeaconRelatedRegisters(PADAPTER padapter)2875 static void rtl8723d_SetBeaconRelatedRegisters(PADAPTER padapter)
2876 {
2877 u8 val8;
2878 u32 value32;
2879 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2880 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2881 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2882 u32 bcn_ctrl_reg;
2883
2884 /* reset TSF, enable update TSF, correcting TSF On Beacon */
2885
2886 /* REG_MBSSID_BCN_SPACE */
2887 /* REG_BCNDMATIM */
2888 /* REG_ATIMWND */
2889 /* REG_TBTT_PROHIBIT */
2890 /* REG_DRVERLYINT */
2891 /* REG_BCN_MAX_ERR */
2892 /* REG_BCNTCFG //(0x510) */
2893 /* REG_DUAL_TSF_RST */
2894 /* REG_BCN_CTRL //(0x550) */
2895
2896
2897 bcn_ctrl_reg = REG_BCN_CTRL;
2898 #ifdef CONFIG_CONCURRENT_MODE
2899 if (padapter->hw_port == HW_PORT1)
2900 bcn_ctrl_reg = REG_BCN_CTRL_1;
2901 #endif
2902
2903 /* */
2904 /* ATIM window */
2905 /* */
2906 rtw_write16(padapter, REG_ATIMWND, 2);
2907
2908 /* */
2909 /* Beacon interval (in unit of TU). */
2910 /* */
2911 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)&pmlmeinfo->bcn_interval);
2912
2913 rtl8723d_InitBeaconParameters(padapter);
2914
2915 rtw_write8(padapter, REG_SLOT, 0x09);
2916
2917 /* */
2918 /* Reset TSF Timer to zero, added by Roger. 2008.06.24 */
2919 /* */
2920 value32 = rtw_read32(padapter, REG_TCR);
2921 value32 &= ~TSFRST;
2922 rtw_write32(padapter, REG_TCR, value32);
2923
2924 value32 |= TSFRST;
2925 rtw_write32(padapter, REG_TCR, value32);
2926
2927 /* NOTE: Fix test chip's bug (about contention windows's randomness) */
2928 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE | WIFI_MESH_STATE) == _TRUE) {
2929 rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
2930 rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
2931 }
2932
2933 _BeaconFunctionEnable(padapter, _TRUE, _TRUE);
2934
2935 ResumeTxBeacon(padapter);
2936 val8 = rtw_read8(padapter, bcn_ctrl_reg);
2937 val8 |= DIS_BCNQ_SUB;
2938 rtw_write8(padapter, bcn_ctrl_reg, val8);
2939 }
2940
hal_notch_filter_8723d(_adapter * adapter,bool enable)2941 void hal_notch_filter_8723d(_adapter *adapter, bool enable)
2942 {
2943 if (enable) {
2944 RTW_INFO("Enable notch filter\n");
2945 rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1));
2946 } else {
2947 RTW_INFO("Disable notch filter\n");
2948 rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1));
2949 }
2950 }
2951
2952 /*
2953 * Description: In normal chip, we should send some packet to Hw which will be used by Fw
2954 * in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
2955 * Fw can tell Hw to send these packet derectly.
2956 * Added by tynli. 2009.10.15.
2957 *
2958 * type1:pspoll, type2:null */
rtl8723d_fill_fake_txdesc(PADAPTER padapter,u8 * pDesc,u32 BufferLen,u8 IsPsPoll,u8 IsBTQosNull,u8 bDataFrame)2959 void rtl8723d_fill_fake_txdesc(
2960 PADAPTER padapter,
2961 u8 *pDesc,
2962 u32 BufferLen,
2963 u8 IsPsPoll,
2964 u8 IsBTQosNull,
2965 u8 bDataFrame)
2966 {
2967 /* Clear all status */
2968 _rtw_memset(pDesc, 0, TXDESC_SIZE);
2969
2970 SET_TX_DESC_OFFSET_8723D(pDesc, 0x28); /* Offset = 32 */
2971
2972 SET_TX_DESC_PKT_SIZE_8723D(pDesc, BufferLen); /* Buffer size + command header */
2973 SET_TX_DESC_QUEUE_SEL_8723D(pDesc, QSLT_MGNT); /* Fixed queue of Mgnt queue */
2974
2975 /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. */
2976 if (_TRUE == IsPsPoll)
2977 SET_TX_DESC_NAV_USE_HDR_8723D(pDesc, 1);
2978 else {
2979 SET_TX_DESC_HWSEQ_EN_8723D(pDesc, 1); /* Hw set sequence number */
2980 SET_TX_DESC_HWSEQ_SEL_8723D(pDesc, 0);
2981 }
2982
2983 if (_TRUE == IsBTQosNull)
2984 SET_TX_DESC_BT_INT_8723D(pDesc, 1);
2985
2986 SET_TX_DESC_USE_RATE_8723D(pDesc, 1); /* use data rate which is set by Sw */
2987
2988 SET_TX_DESC_TX_RATE_8723D(pDesc, DESC8723D_RATE1M);
2989
2990 /* */
2991 /* Encrypt the data frame if under security mode excepct null data. Suggested by CCW. */
2992 /* */
2993 if (_TRUE == bDataFrame) {
2994 u32 EncAlg;
2995
2996 EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
2997 switch (EncAlg) {
2998 case _NO_PRIVACY_:
2999 SET_TX_DESC_SEC_TYPE_8723D(pDesc, 0x0);
3000 break;
3001 case _WEP40_:
3002 case _WEP104_:
3003 case _TKIP_:
3004 SET_TX_DESC_SEC_TYPE_8723D(pDesc, 0x1);
3005 break;
3006 case _SMS4_:
3007 SET_TX_DESC_SEC_TYPE_8723D(pDesc, 0x2);
3008 break;
3009 case _AES_:
3010 SET_TX_DESC_SEC_TYPE_8723D(pDesc, 0x3);
3011 break;
3012 default:
3013 SET_TX_DESC_SEC_TYPE_8723D(pDesc, 0x0);
3014 break;
3015 }
3016 }
3017
3018 #if defined(CONFIG_USB_HCI)
3019 /*
3020 * USB interface drop packet if the checksum of descriptor isn't correct.
3021 * Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
3022 */
3023 rtl8723d_cal_txdesc_chksum((struct tx_desc *)pDesc);
3024 #endif
3025 }
3026
rtl8723d_InitAntenna_Selection(PADAPTER padapter)3027 void rtl8723d_InitAntenna_Selection(PADAPTER padapter)
3028 {
3029 rtw_write8(padapter, REG_LEDCFG2, 0x82);
3030 }
3031
rtl8723d_CheckAntenna_Selection(PADAPTER padapter)3032 void rtl8723d_CheckAntenna_Selection(PADAPTER padapter)
3033 {
3034 #if 0
3035 PHAL_DATA_TYPE pHalData;
3036 u8 val;
3037
3038
3039 pHalData = GET_HAL_DATA(padapter);
3040
3041 val = rtw_read8(padapter, REG_LEDCFG2);
3042 /* Let 8051 take control antenna setting */
3043 if (!(val & BIT(7))) {
3044 val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */
3045 rtw_write8(padapter, REG_LEDCFG2, val);
3046 }
3047 #endif
3048 }
rtl8723d_DeinitAntenna_Selection(PADAPTER padapter)3049 void rtl8723d_DeinitAntenna_Selection(PADAPTER padapter)
3050 {
3051 #if 0
3052 PHAL_DATA_TYPE pHalData;
3053 u8 val;
3054
3055
3056 pHalData = GET_HAL_DATA(padapter);
3057 val = rtw_read8(padapter, REG_LEDCFG2);
3058 /* Let 8051 take control antenna setting */
3059 val &= ~BIT(7); /* DPDT_SEL_EN, clear 0x4C[23] */
3060 rtw_write8(padapter, REG_LEDCFG2, val);
3061 #endif
3062 }
3063
init_hal_spec_8723d(_adapter * adapter)3064 void init_hal_spec_8723d(_adapter *adapter)
3065 {
3066 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3067
3068 hal_spec->ic_name = "rtl8723d";
3069 hal_spec->macid_num = 16;
3070 hal_spec->sec_cam_ent_num = 32;
3071 hal_spec->sec_cap = SEC_CAP_CHK_BMC;
3072 hal_spec->macid_cap = MACID_DROP_INDIRECT;
3073 hal_spec->macid_txrpt = 0x8100;
3074 hal_spec->macid_txrpt_pgsz = 16;
3075
3076 hal_spec->rfpath_num_2g = 2;
3077 hal_spec->rfpath_num_5g = 0;
3078 hal_spec->rf_reg_path_num = hal_spec->rf_reg_path_avail_num = 1;
3079 hal_spec->rf_reg_trx_path_bmp = 0x11;
3080 hal_spec->max_tx_cnt = 1;
3081
3082 hal_spec->tx_nss_num = 1;
3083 hal_spec->rx_nss_num = 1;
3084 hal_spec->band_cap = BAND_CAP_2G;
3085 hal_spec->bw_cap = BW_CAP_20M | BW_CAP_40M;
3086 hal_spec->port_num = 3;
3087 hal_spec->proto_cap = PROTO_CAP_11B | PROTO_CAP_11G | PROTO_CAP_11N;
3088
3089 hal_spec->txgi_max = 63;
3090 hal_spec->txgi_pdbm = 2;
3091
3092 hal_spec->wl_func = 0
3093 | WL_FUNC_P2P
3094 | WL_FUNC_MIRACAST
3095 | WL_FUNC_TDLS
3096 ;
3097
3098 hal_spec->tx_aclt_unit_factor = 8;
3099
3100 hal_spec->pg_txpwr_saddr = 0x10;
3101 hal_spec->pg_txgi_diff_factor = 1;
3102
3103 rtw_macid_ctl_init_sleep_reg(adapter_to_macidctl(adapter)
3104 , REG_MACID_SLEEP, 0, 0, 0);
3105 }
3106
rtl8723d_init_default_value(PADAPTER padapter)3107 void rtl8723d_init_default_value(PADAPTER padapter)
3108 {
3109 PHAL_DATA_TYPE pHalData;
3110 u8 i;
3111
3112 pHalData = GET_HAL_DATA(padapter);
3113
3114 /* init default value */
3115 pHalData->fw_ractrl = _FALSE;
3116 if (!adapter_to_pwrctl(padapter)->bkeepfwalive)
3117 pHalData->LastHMEBoxNum = 0;
3118
3119 /* init phydm default value */
3120 pHalData->bIQKInitialized = _FALSE;
3121
3122 /* init Efuse variables */
3123 pHalData->EfuseUsedBytes = 0;
3124 pHalData->EfuseUsedPercentage = 0;
3125 #ifdef HAL_EFUSE_MEMORY
3126 pHalData->EfuseHal.fakeEfuseBank = 0;
3127 pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
3128 _rtw_memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
3129 _rtw_memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
3130 _rtw_memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
3131 pHalData->EfuseHal.BTEfuseUsedBytes = 0;
3132 pHalData->EfuseHal.BTEfuseUsedPercentage = 0;
3133 _rtw_memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK * EFUSE_MAX_HW_SIZE);
3134 _rtw_memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3135 _rtw_memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3136 pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0;
3137 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK * EFUSE_MAX_HW_SIZE);
3138 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3139 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3140 #endif
3141 pHalData->need_restore = _FALSE;
3142 }
3143
GetEEPROMSize8723D(PADAPTER padapter)3144 u8 GetEEPROMSize8723D(PADAPTER padapter)
3145 {
3146 u8 size = 0;
3147 u32 cr;
3148
3149 cr = rtw_read16(padapter, REG_9346CR);
3150 /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
3151 size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
3152
3153 RTW_INFO("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
3154
3155 return size;
3156 }
3157
3158 /* -------------------------------------------------------------------------
3159 *
3160 * LLT R/W/Init function
3161 *
3162 * ------------------------------------------------------------------------- */
rtl8723d_InitLLTTable(PADAPTER padapter)3163 s32 rtl8723d_InitLLTTable(PADAPTER padapter)
3164 {
3165 systime start;
3166 u32 passing_time;
3167 u32 val32;
3168 s32 ret;
3169
3170
3171 ret = _FAIL;
3172
3173 val32 = rtw_read32(padapter, REG_AUTO_LLT);
3174 val32 |= BIT_AUTO_INIT_LLT;
3175 rtw_write32(padapter, REG_AUTO_LLT, val32);
3176
3177 start = rtw_get_current_time();
3178
3179 do {
3180 val32 = rtw_read32(padapter, REG_AUTO_LLT);
3181 if (!(val32 & BIT_AUTO_INIT_LLT)) {
3182 ret = _SUCCESS;
3183 break;
3184 }
3185
3186 passing_time = rtw_get_passing_time_ms(start);
3187 if (passing_time > 1000) {
3188 RTW_INFO("%s: FAIL!! REG_AUTO_LLT(0x%X)=%08x\n",
3189 __FUNCTION__, REG_AUTO_LLT, val32);
3190 break;
3191 }
3192
3193 rtw_usleep_os(2);
3194 } while (1);
3195
3196 return ret;
3197 }
3198
3199 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
_DisableGPIO(PADAPTER padapter)3200 void _DisableGPIO(PADAPTER padapter)
3201 {
3202 /***************************************
3203 j. GPIO_PIN_CTRL 0x44[31:0]=0x000
3204 k.Value = GPIO_PIN_CTRL[7:0]
3205 l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8);
3206 m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
3207 n. LEDCFG 0x4C[15:0] = 0x8080
3208 ***************************************/
3209 u8 value8;
3210 u16 value16;
3211 u32 value32;
3212 u32 u4bTmp;
3213
3214
3215 /* 1. Disable GPIO[7:0] */
3216 rtw_write16(padapter, REG_GPIO_PIN_CTRL + 2, 0x0000);
3217 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
3218 u4bTmp = value32 & 0x000000FF;
3219 value32 |= ((u4bTmp << 8) | 0x00FF0000);
3220 rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32);
3221
3222
3223 /* 2. Disable GPIO[10:8] */
3224 rtw_write8(padapter, REG_MAC_PINMUX_CFG, 0x00);
3225 value16 = rtw_read16(padapter, REG_GPIO_IO_SEL) & 0xFF0F;
3226 value8 = (u8)(value16 & 0x000F);
3227 value16 |= ((value8 << 4) | 0x0780);
3228 rtw_write16(padapter, REG_GPIO_IO_SEL, value16);
3229
3230
3231 /* 3. Disable LED0 & 1 */
3232 rtw_write16(padapter, REG_LEDCFG0, 0x8080);
3233
3234 } /* end of _DisableGPIO() */
3235
_DisableRFAFEAndResetBB8723D(PADAPTER padapter)3236 void _DisableRFAFEAndResetBB8723D(PADAPTER padapter)
3237 {
3238 /**************************************
3239 a. TXPAUSE 0x522[7:0] = 0xFF
3240 b. RF path 0 offset 0x00 = 0x00
3241 c. APSD_CTRL 0x600[7:0] = 0x40
3242 d. SYS_FUNC_EN 0x02[7:0] = 0x16
3243 e. SYS_FUNC_EN 0x02[7:0] = 0x14
3244 ***************************************/
3245 enum rf_path eRFPath = RF_PATH_A, value8 = 0;
3246
3247 rtw_write8(padapter, REG_TXPAUSE, 0xFF);
3248
3249 phy_set_rf_reg(padapter, eRFPath, 0x0, bMaskByte0, 0x0);
3250
3251 value8 |= APSDOFF;
3252 rtw_write8(padapter, REG_APSD_CTRL, value8);/* 0x40 */
3253
3254 /* Set BB reset at first */
3255 value8 = 0;
3256 value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
3257 rtw_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x16 */
3258
3259 /* Set global reset. */
3260 value8 &= ~FEN_BB_GLB_RSTn;
3261 rtw_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x14 */
3262
3263 /* 2010/08/12 MH We need to set BB/GLBAL reset to save power for SS mode. */
3264
3265 }
3266
_DisableRFAFEAndResetBB(PADAPTER padapter)3267 void _DisableRFAFEAndResetBB(PADAPTER padapter)
3268 {
3269 _DisableRFAFEAndResetBB8723D(padapter);
3270 }
3271
_ResetDigitalProcedure1_8723D(PADAPTER padapter,BOOLEAN bWithoutHWSM)3272 void _ResetDigitalProcedure1_8723D(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3273 {
3274 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3275
3276 if (IS_FW_81xxC(padapter) && (pHalData->firmware_version <= 0x20)) {
3277 #if 0
3278 /*****************************
3279 f. SYS_FUNC_EN 0x03[7:0]=0x54
3280 g. MCUFWDL 0x80[7:0]=0
3281 ******************************/
3282 u32 value32 = 0;
3283
3284 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54);
3285 rtw_write8(padapter, REG_MCUFWDL, 0);
3286 #else
3287 /*****************************
3288 f. MCUFWDL 0x80[7:0]=0
3289 g. SYS_FUNC_EN 0x02[10]= 0
3290 h. SYS_FUNC_EN 0x02[15-12]= 5
3291 i. SYS_FUNC_EN 0x02[10]= 1
3292 ******************************/
3293 u16 valu16 = 0;
3294
3295 rtw_write8(padapter, REG_MCUFWDL, 0);
3296
3297 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
3298 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));/* reset MCU ,8051 */
3299
3300 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN) & 0x0FFF;
3301 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | (FEN_HWPDN | FEN_ELDR))); /* reset MAC */
3302
3303 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
3304 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));/* enable MCU ,8051 */
3305 #endif
3306 } else {
3307 u8 retry_cnts = 0;
3308
3309 /* 2010/08/12 MH For USB SS, we can not stop 8051 when we are trying to */
3310 /* enter IPS/HW&SW radio off. For S3/S4/S5/Disable, we can stop 8051 because */
3311 /* we will init FW when power on again. */
3312 /* if(!pDevice->RegUsbSS) */
3313 { /* If we want to SS mode, we can not reset 8051. */
3314 if (rtw_read8(padapter, REG_MCUFWDL) & BIT(1)) {
3315 /* IF fw in RAM code, do reset */
3316
3317
3318 if (pHalData->bFWReady) {
3319 /* 2010/08/25 MH According to RD alfred's suggestion, we need to disable other */
3320 /* HRCV INT to influence 8051 reset. */
3321 rtw_write8(padapter, REG_FWIMR, 0x20);
3322 /* 2011/02/15 MH According to Alex's suggestion, close mask to prevent incorrect FW write operation. */
3323 rtw_write8(padapter, REG_FTIMR, 0x00);
3324 rtw_write8(padapter, REG_FSIMR, 0x00);
3325
3326 rtw_write8(padapter, REG_HMETFR + 3, 0x20); /* 8051 reset by self */
3327
3328 while ((retry_cnts++ < 100) && (FEN_CPUEN & rtw_read16(padapter, REG_SYS_FUNC_EN))) {
3329 rtw_udelay_os(50);/* us */
3330 /* 2010/08/25 For test only We keep on reset 5051 to prevent fail. */
3331 /* rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self */
3332 }
3333 /* RT_ASSERT((retry_cnts < 100), ("8051 reset failed!\n")); */
3334
3335 if (retry_cnts >= 100) {
3336 /* if 8051 reset fail we trigger GPIO 0 for LA */
3337 /* rtw_write32( padapter, */
3338 /* REG_GPIO_PIN_CTRL, */
3339 /* 0x00010100); */
3340 /* 2010/08/31 MH According to Filen's info, if 8051 reset fail, reset MAC directly. */
3341 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x50); /* Reset MAC and Enable 8051 */
3342 rtw_mdelay_os(10);
3343 }
3344
3345 }
3346 }
3347
3348 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54); /* Reset MAC and Enable 8051 */
3349 rtw_write8(padapter, REG_MCUFWDL, 0);
3350 }
3351 }
3352
3353 /* if(pDevice->RegUsbSS) */
3354 /* bWithoutHWSM = TRUE; // Sugest by Filen and Issau. */
3355
3356 if (bWithoutHWSM) {
3357 /* HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); */
3358 /*****************************
3359 Without HW auto state machine
3360 g. SYS_CLKR 0x08[15:0] = 0x30A3
3361 h. AFE_PLL_CTRL 0x28[7:0] = 0x80
3362 i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F
3363 j. SYS_ISO_CTRL 0x00[7:0] = 0xF9
3364 ******************************/
3365 /* rtw_write16(padapter, REG_SYS_CLKR, 0x30A3); */
3366 /* if(!pDevice->RegUsbSS) */
3367 /* 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug. */
3368 rtw_write16(padapter, REG_SYS_CLKR, 0x70A3); /* modify to 0x70A3 by Scott. */
3369 rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
3370 rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
3371 /* if(!pDevice->RegUsbSS) */
3372 rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
3373 } else {
3374 /* Disable all RF/BB power */
3375 rtw_write8(padapter, REG_RF_CTRL, 0x00);
3376 }
3377
3378 }
3379
_ResetDigitalProcedure1(PADAPTER padapter,BOOLEAN bWithoutHWSM)3380 void _ResetDigitalProcedure1(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3381 {
3382 _ResetDigitalProcedure1_8723D(padapter, bWithoutHWSM);
3383 }
3384
_ResetDigitalProcedure2(PADAPTER padapter)3385 void _ResetDigitalProcedure2(PADAPTER padapter)
3386 {
3387 /* HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3388 *****************************
3389 k. SYS_FUNC_EN 0x03[7:0] = 0x44
3390 l. SYS_CLKR 0x08[15:0] = 0x3083
3391 m. SYS_ISO_CTRL 0x01[7:0] = 0x83
3392 ******************************/
3393 /* rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x44); //marked by Scott. */
3394 /* 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug. */
3395 rtw_write16(padapter, REG_SYS_CLKR, 0x70a3); /* modify to 0x70a3 by Scott. */
3396 rtw_write8(padapter, REG_SYS_ISO_CTRL + 1, 0x82); /* modify to 0x82 by Scott. */
3397 }
3398
_DisableAnalog(PADAPTER padapter,BOOLEAN bWithoutHWSM)3399 void _DisableAnalog(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3400 {
3401 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3402 u16 value16 = 0;
3403 u8 value8 = 0;
3404
3405
3406 if (bWithoutHWSM) {
3407 /*****************************
3408 n. LDOA15_CTRL 0x20[7:0] = 0x04
3409 o. LDOV12D_CTRL 0x21[7:0] = 0x54
3410 r. When driver call disable, the ASIC will turn off remaining clock automatically
3411 ******************************/
3412
3413 rtw_write8(padapter, REG_LDOA15_CTRL, 0x04);
3414 /* rtw_write8(padapter, REG_LDOV12D_CTRL, 0x54); */
3415
3416 value8 = rtw_read8(padapter, REG_LDOV12D_CTRL);
3417 value8 &= (~LDV12_EN);
3418 rtw_write8(padapter, REG_LDOV12D_CTRL, value8);
3419 }
3420
3421 /*****************************
3422 h. SPS0_CTRL 0x11[7:0] = 0x23
3423 i. APS_FSMCO 0x04[15:0] = 0x4802
3424 ******************************/
3425 value8 = 0x23;
3426
3427 rtw_write8(padapter, REG_SPS0_CTRL, value8);
3428
3429 if (bWithoutHWSM) {
3430 /* value16 |= (APDM_HOST | AFSM_HSUS |PFM_ALDN); */
3431 /* 2010/08/31 According to Filen description, we need to use HW to shut down 8051 automatically. */
3432 /* Because suspend operation need the asistance of 8051 to wait for 3ms. */
3433 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
3434 } else
3435 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
3436
3437 rtw_write16(padapter, REG_APS_FSMCO, value16);/* 0x4802 */
3438
3439 rtw_write8(padapter, REG_RSV_CTRL, 0x0e);
3440
3441 #if 0
3442 /* tynli_test for suspend mode. */
3443 if (!bWithoutHWSM)
3444 rtw_write8(padapter, 0xfe10, 0x19);
3445 #endif
3446
3447 }
3448
3449 /* HW Auto state machine */
CardDisableHWSM(PADAPTER padapter,u8 resetMCU)3450 s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU)
3451 {
3452 int rtStatus = _SUCCESS;
3453
3454
3455 if (RTW_CANNOT_RUN(padapter))
3456 return rtStatus;
3457
3458 /* ==== RF Off Sequence ==== */
3459 _DisableRFAFEAndResetBB(padapter);
3460
3461 /* ==== Reset digital sequence ====== */
3462 _ResetDigitalProcedure1(padapter, _FALSE);
3463
3464 /* ==== Pull GPIO PIN to balance level and LED control ====== */
3465 _DisableGPIO(padapter);
3466
3467 /* ==== Disable analog sequence === */
3468 _DisableAnalog(padapter, _FALSE);
3469
3470
3471 return rtStatus;
3472 }
3473
3474 /* without HW Auto state machine */
CardDisableWithoutHWSM(PADAPTER padapter)3475 s32 CardDisableWithoutHWSM(PADAPTER padapter)
3476 {
3477 s32 rtStatus = _SUCCESS;
3478
3479
3480 if (RTW_CANNOT_RUN(padapter))
3481 return rtStatus;
3482
3483
3484 /* ==== RF Off Sequence ==== */
3485 _DisableRFAFEAndResetBB(padapter);
3486
3487 /* ==== Reset digital sequence ====== */
3488 _ResetDigitalProcedure1(padapter, _TRUE);
3489
3490 /* ==== Pull GPIO PIN to balance level and LED control ====== */
3491 _DisableGPIO(padapter);
3492
3493 /* ==== Reset digital sequence ====== */
3494 _ResetDigitalProcedure2(padapter);
3495
3496 /* ==== Disable analog sequence === */
3497 _DisableAnalog(padapter, _TRUE);
3498
3499 return rtStatus;
3500 }
3501 #endif /* CONFIG_USB_HCI || CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
3502
3503 void
Hal_InitPGData(PADAPTER padapter,u8 * PROMContent)3504 Hal_InitPGData(
3505 PADAPTER padapter,
3506 u8 *PROMContent)
3507 {
3508
3509 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3510 u32 i;
3511 u16 value16;
3512
3513 if (_FALSE == pHalData->bautoload_fail_flag) {
3514 /* autoload OK.
3515 * if (IS_BOOT_FROM_EEPROM(padapter)) */
3516 if (_TRUE == pHalData->EepromOrEfuse) {
3517 /* Read all Content from EEPROM or EFUSE. */
3518 for (i = 0; i < HWSET_MAX_SIZE_8723D; i += 2) {
3519 /* value16 = EF2Byte(ReadEEprom(pAdapter, (u16) (i>>1)));
3520 * *((u16*)(&PROMContent[i])) = value16; */
3521 }
3522 } else {
3523 /* Read EFUSE real map to shadow. */
3524 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
3525 }
3526 } else {
3527 /* autoload fail */
3528 /* pHalData->AutoloadFailFlag = _TRUE; */
3529 /* update to default value 0xFF */
3530 if (_FALSE == pHalData->EepromOrEfuse)
3531 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
3532 }
3533
3534 #ifdef CONFIG_EFUSE_CONFIG_FILE
3535 if (check_phy_efuse_tx_power_info_valid(padapter) == _FALSE) {
3536 if (Hal_readPGDataFromConfigFile(padapter) != _SUCCESS)
3537 RTW_ERR("invalid phy efuse and read from file fail, will use driver default!!\n");
3538 }
3539 #endif
3540 }
3541
3542 void
Hal_EfuseParseIDCode(PADAPTER padapter,u8 * hwinfo)3543 Hal_EfuseParseIDCode(
3544 PADAPTER padapter,
3545 u8 *hwinfo
3546 )
3547 {
3548 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3549 u16 EEPROMId;
3550
3551
3552 /* Checl 0x8129 again for making sure autoload status!! */
3553 EEPROMId = le16_to_cpu(*((u16 *)hwinfo));
3554 if (EEPROMId != RTL_EEPROM_ID) {
3555 RTW_INFO("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
3556 pHalData->bautoload_fail_flag = _TRUE;
3557 } else
3558 pHalData->bautoload_fail_flag = _FALSE;
3559
3560 }
3561 void
Hal_EfuseParseTxPowerInfo_8723D(PADAPTER padapter,u8 * PROMContent,BOOLEAN AutoLoadFail)3562 Hal_EfuseParseTxPowerInfo_8723D(
3563 PADAPTER padapter,
3564 u8 *PROMContent,
3565 BOOLEAN AutoLoadFail
3566 )
3567 {
3568 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3569
3570 pHalData->txpwr_pg_mode = TXPWR_PG_WITH_PWR_IDX;
3571
3572 /* 2010/10/19 MH Add Regulator recognize for CU. */
3573 if (!AutoLoadFail) {
3574 pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_8723D] & 0x7); /* bit0~2 */
3575 if (PROMContent[EEPROM_RF_BOARD_OPTION_8723D] == 0xFF)
3576 pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7); /* bit0~2 */
3577 } else
3578 pHalData->EEPROMRegulatory = 0;
3579 }
3580
3581 void
Hal_EfuseParseBoardType_8723D(PADAPTER Adapter,u8 * PROMContent,BOOLEAN AutoloadFail)3582 Hal_EfuseParseBoardType_8723D(
3583 PADAPTER Adapter,
3584 u8 *PROMContent,
3585 BOOLEAN AutoloadFail
3586 )
3587 {
3588
3589
3590 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3591
3592 if (!AutoloadFail) {
3593 pHalData->InterfaceSel = (PROMContent[EEPROM_RF_BOARD_OPTION_8723D] & 0xE0) >> 5;
3594 if (PROMContent[EEPROM_RF_BOARD_OPTION_8723D] == 0xFF)
3595 pHalData->InterfaceSel = (EEPROM_DEFAULT_BOARD_OPTION & 0xE0) >> 5;
3596 } else
3597 pHalData->InterfaceSel = 0;
3598
3599 }
3600
3601 void
Hal_EfuseParseBTCoexistInfo_8723D(PADAPTER padapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3602 Hal_EfuseParseBTCoexistInfo_8723D(
3603 PADAPTER padapter,
3604 u8 *hwinfo,
3605 BOOLEAN AutoLoadFail
3606 )
3607 {
3608 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3609 u8 tempval;
3610 u32 tmpu4;
3611
3612 if (!AutoLoadFail) {
3613 tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
3614 if (tmpu4 & BT_FUNC_EN)
3615 pHalData->EEPROMBluetoothCoexist = _TRUE;
3616 else
3617 pHalData->EEPROMBluetoothCoexist = _FALSE;
3618
3619 pHalData->EEPROMBluetoothType = BT_RTL8723D;
3620
3621 tempval = hwinfo[EEPROM_RF_BT_SETTING_8723D];
3622 if (tempval != 0xFF) {
3623 /* 0:Ant_x2, 1:Ant_x1 */
3624 pHalData->EEPROMBluetoothAntNum = tempval & BIT(0);
3625 /*
3626 * EFUSE_0xC3[6] == 0, Wi-Fi at BTGS1(Main, Ant2) - RF_PATH_A (default)
3627 * EFUSE_0xC3[6] == 1, Wi-Fi at BTGS0( Aux, Ant1) - RF_PATH_B
3628 */
3629 pHalData->ant_path = (tempval & BIT(6)) ? RF_PATH_B : RF_PATH_A;
3630 } else {
3631 pHalData->EEPROMBluetoothAntNum = Ant_x1;
3632 pHalData->ant_path = RF_PATH_A;
3633 }
3634 } else {
3635 if (padapter->registrypriv.mp_mode == 1)
3636 pHalData->EEPROMBluetoothCoexist = _TRUE;
3637 else
3638 pHalData->EEPROMBluetoothCoexist = _FALSE;
3639
3640 pHalData->EEPROMBluetoothType = BT_RTL8723D;
3641 pHalData->EEPROMBluetoothAntNum = Ant_x1;
3642 pHalData->ant_path = RF_PATH_A;
3643 }
3644
3645 #ifdef CONFIG_BT_COEXIST
3646 if (padapter->registrypriv.ant_num > 0) {
3647 RTW_INFO("%s: Apply driver defined antenna number(%d) to replace origin(%d)\n"
3648 , __func__
3649 , padapter->registrypriv.ant_num
3650 , pHalData->EEPROMBluetoothAntNum == Ant_x2 ? 2 : 1);
3651
3652 switch (padapter->registrypriv.ant_num) {
3653 case 1:
3654 pHalData->EEPROMBluetoothAntNum = Ant_x1;
3655 break;
3656 case 2:
3657 pHalData->EEPROMBluetoothAntNum = Ant_x2;
3658 break;
3659 default:
3660 RTW_INFO("%s: Discard invalid driver defined antenna number(%d)!\n"
3661 , __func__, padapter->registrypriv.ant_num);
3662 break;
3663 }
3664 }
3665 #endif /* CONFIG_BT_COEXIST */
3666
3667 RTW_INFO("%s: %s BT-coex, ant_num=%d\n"
3668 , __func__
3669 , pHalData->EEPROMBluetoothCoexist == _TRUE ? "Enable" : "Disable"
3670 , pHalData->EEPROMBluetoothAntNum == Ant_x2 ? 2 : 1);
3671 }
3672
3673 void
Hal_EfuseParseEEPROMVer_8723D(PADAPTER padapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3674 Hal_EfuseParseEEPROMVer_8723D(
3675 PADAPTER padapter,
3676 u8 *hwinfo,
3677 BOOLEAN AutoLoadFail
3678 )
3679 {
3680 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3681
3682 if (!AutoLoadFail)
3683 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723D];
3684 else
3685 pHalData->EEPROMVersion = 1;
3686 }
3687
3688 void
Hal_EfuseParseVoltage_8723D(PADAPTER pAdapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3689 Hal_EfuseParseVoltage_8723D(
3690 PADAPTER pAdapter,
3691 u8 *hwinfo,
3692 BOOLEAN AutoLoadFail
3693 )
3694 {
3695 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
3696
3697 /* _rtw_memcpy(pHalData->adjuseVoltageVal, &hwinfo[EEPROM_Voltage_ADDR_8723D], 1); */
3698 RTW_INFO("%s hwinfo[EEPROM_Voltage_ADDR_8723D] =%02x\n", __func__, hwinfo[EEPROM_Voltage_ADDR_8723D]);
3699 pHalData->adjuseVoltageVal = (hwinfo[EEPROM_Voltage_ADDR_8723D] & 0xf0) >> 4;
3700 RTW_INFO("%s pHalData->adjuseVoltageVal =%x\n", __func__, pHalData->adjuseVoltageVal);
3701 }
3702
3703 void
Hal_EfuseParseChnlPlan_8723D(PADAPTER padapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3704 Hal_EfuseParseChnlPlan_8723D(
3705 PADAPTER padapter,
3706 u8 *hwinfo,
3707 BOOLEAN AutoLoadFail
3708 )
3709 {
3710 hal_com_config_channel_plan(
3711 padapter
3712 , hwinfo ? &hwinfo[EEPROM_COUNTRY_CODE_8723D] : NULL
3713 , hwinfo ? hwinfo[EEPROM_ChannelPlan_8723D] : 0xFF
3714 , padapter->registrypriv.alpha2
3715 , padapter->registrypriv.channel_plan
3716 , AutoLoadFail
3717 );
3718 }
3719
3720 void
Hal_EfuseParseCustomerID_8723D(PADAPTER padapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3721 Hal_EfuseParseCustomerID_8723D(
3722 PADAPTER padapter,
3723 u8 *hwinfo,
3724 BOOLEAN AutoLoadFail
3725 )
3726 {
3727 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3728
3729 if (!AutoLoadFail)
3730 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723D];
3731 else
3732 pHalData->EEPROMCustomerID = 0;
3733 }
3734
3735 void
Hal_EfuseParseAntennaDiversity_8723D(PADAPTER pAdapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3736 Hal_EfuseParseAntennaDiversity_8723D(
3737 PADAPTER pAdapter,
3738 u8 *hwinfo,
3739 BOOLEAN AutoLoadFail
3740 )
3741 {
3742 #ifdef CONFIG_ANTENNA_DIVERSITY
3743 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
3744 struct registry_priv *registry_par = &pAdapter->registrypriv;
3745 u8 get_efuse_div_type;
3746
3747 if (pHalData->EEPROMBluetoothAntNum == Ant_x1)
3748 pHalData->AntDivCfg = 0;
3749 else {
3750 if (registry_par->antdiv_cfg == 2) /* 0:OFF , 1:ON, 2:By EFUSE */
3751 pHalData->AntDivCfg = 1;
3752 else
3753 pHalData->AntDivCfg = registry_par->antdiv_cfg;
3754 }
3755
3756 pHalData->TRxAntDivType = S0S1_TRX_HW_ANTDIV; /* it's the only diversity-type for 8723D*/
3757 pHalData->with_extenal_ant_switch = ((hwinfo[EEPROM_RF_BT_SETTING_8723D] & BIT7) >> 7);
3758
3759 if (pHalData->AntDivCfg != 0) {
3760
3761 get_efuse_div_type = hwinfo[EEPROM_RFE_OPTION_8723D];
3762
3763 if (get_efuse_div_type == 0x11) {
3764 pHalData->b_fix_tx_ant = NO_FIX_TX_ANT;
3765 } else if (get_efuse_div_type == 0x13) {
3766 pHalData->b_fix_tx_ant = FIX_TX_AT_MAIN;/* RX diversity only*/
3767 } else
3768 pHalData->AntDivCfg = FALSE;
3769 }
3770
3771 RTW_INFO("%s: AntDivCfg=%d, AntDivType=%d\n",
3772 __FUNCTION__, pHalData->AntDivCfg, pHalData->TRxAntDivType);
3773 #endif
3774 }
3775
3776 void
Hal_EfuseParseXtal_8723D(PADAPTER pAdapter,u8 * hwinfo,BOOLEAN AutoLoadFail)3777 Hal_EfuseParseXtal_8723D(
3778 PADAPTER pAdapter,
3779 u8 *hwinfo,
3780 BOOLEAN AutoLoadFail
3781 )
3782 {
3783 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
3784
3785 if (!AutoLoadFail) {
3786 pHalData->crystal_cap = hwinfo[EEPROM_XTAL_8723D];
3787 if (pHalData->crystal_cap == 0xFF)
3788 pHalData->crystal_cap = EEPROM_Default_CrystalCap_8723D; /* what value should 8812 set? */
3789 } else
3790 pHalData->crystal_cap = EEPROM_Default_CrystalCap_8723D;
3791 }
3792
3793
3794 void
Hal_EfuseParseThermalMeter_8723D(PADAPTER padapter,u8 * PROMContent,u8 AutoLoadFail)3795 Hal_EfuseParseThermalMeter_8723D(
3796 PADAPTER padapter,
3797 u8 *PROMContent,
3798 u8 AutoLoadFail
3799 )
3800 {
3801 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3802
3803 /* */
3804 /* ThermalMeter from EEPROM */
3805 /* */
3806 if (_FALSE == AutoLoadFail)
3807 pHalData->eeprom_thermal_meter = PROMContent[EEPROM_THERMAL_METER_8723D];
3808 else
3809 pHalData->eeprom_thermal_meter = EEPROM_Default_ThermalMeter_8723D;
3810
3811 if ((pHalData->eeprom_thermal_meter == 0xff) || (_TRUE == AutoLoadFail)) {
3812 pHalData->odmpriv.rf_calibrate_info.is_apk_thermal_meter_ignore = _TRUE;
3813 pHalData->eeprom_thermal_meter = EEPROM_Default_ThermalMeter_8723D;
3814 }
3815
3816 }
3817
3818
Hal_ReadRFGainOffset(PADAPTER Adapter,u8 * PROMContent,BOOLEAN AutoloadFail)3819 void Hal_ReadRFGainOffset(
3820 PADAPTER Adapter,
3821 u8 *PROMContent,
3822 BOOLEAN AutoloadFail)
3823 {
3824 #ifdef CONFIG_RF_POWER_TRIM
3825 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3826 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
3827 u8 pg_pwrtrim = 0xFF, pg_therm = 0xFF;
3828
3829 efuse_OneByteRead(Adapter,
3830 PPG_BB_GAIN_2G_TX_OFFSET_8723D, &pg_pwrtrim, _FALSE);
3831 efuse_OneByteRead(Adapter,
3832 PPG_THERMAL_OFFSET_8723D, &pg_therm, _FALSE);
3833
3834 if (pg_pwrtrim != 0xFF) {
3835 kfree_data->bb_gain[BB_GAIN_2G][PPG_8723D_S1]
3836 = KFREE_BB_GAIN_2G_TX_OFFSET(pg_pwrtrim & PPG_BB_GAIN_2G_TX_OFFSET_MASK);
3837 kfree_data->bb_gain[BB_GAIN_2G][PPG_8723D_S0]
3838 = KFREE_BB_GAIN_2G_TXB_OFFSET(pg_pwrtrim & PPG_BB_GAIN_2G_TXB_OFFSET_MASK);
3839 kfree_data->flag |= KFREE_FLAG_ON;
3840 }
3841
3842 if (pg_therm != 0xFF) {
3843 kfree_data->thermal
3844 = KFREE_THERMAL_OFFSET(pg_therm & PPG_THERMAL_OFFSET_MASK);
3845 /* kfree_data->flag |= KFREE_FLAG_THERMAL_K_ON; */ /* Default disable thermel kfree by realsil Alan 20160428 */
3846 }
3847
3848 if (kfree_data->flag & KFREE_FLAG_THERMAL_K_ON)
3849 pHalData->eeprom_thermal_meter += kfree_data->thermal;
3850
3851 RTW_INFO("kfree Pwr Trim flag:%u\n", kfree_data->flag);
3852 if (kfree_data->flag & KFREE_FLAG_ON) {
3853 RTW_INFO("bb_gain(S1):%d\n", kfree_data->bb_gain[BB_GAIN_2G][PPG_8723D_S1]);
3854 RTW_INFO("bb_gain(S0):%d\n", kfree_data->bb_gain[BB_GAIN_2G][PPG_8723D_S0]);
3855 }
3856 if (kfree_data->flag & KFREE_FLAG_THERMAL_K_ON)
3857 RTW_INFO("thermal:%d\n", kfree_data->thermal);
3858 #endif /*CONFIG_RF_POWER_TRIM */
3859 }
3860
3861 u8
BWMapping_8723D(PADAPTER Adapter,struct pkt_attrib * pattrib)3862 BWMapping_8723D(
3863 PADAPTER Adapter,
3864 struct pkt_attrib *pattrib
3865 )
3866 {
3867 u8 BWSettingOfDesc = 0;
3868 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
3869
3870 /* RTW_INFO("BWMapping pHalData->current_channel_bw %d, pattrib->bwmode %d\n",pHalData->current_channel_bw,pattrib->bwmode); */
3871
3872 if (pHalData->current_channel_bw == CHANNEL_WIDTH_80) {
3873 if (pattrib->bwmode == CHANNEL_WIDTH_80)
3874 BWSettingOfDesc = 2;
3875 else if (pattrib->bwmode == CHANNEL_WIDTH_40)
3876 BWSettingOfDesc = 1;
3877 else
3878 BWSettingOfDesc = 0;
3879 } else if (pHalData->current_channel_bw == CHANNEL_WIDTH_40) {
3880 if ((pattrib->bwmode == CHANNEL_WIDTH_40) || (pattrib->bwmode == CHANNEL_WIDTH_80))
3881 BWSettingOfDesc = 1;
3882 else
3883 BWSettingOfDesc = 0;
3884 } else
3885 BWSettingOfDesc = 0;
3886
3887 /* if(pTcb->bBTTxPacket) */
3888 /* BWSettingOfDesc = 0; */
3889
3890 return BWSettingOfDesc;
3891 }
3892
SCMapping_8723D(PADAPTER Adapter,struct pkt_attrib * pattrib)3893 u8 SCMapping_8723D(PADAPTER Adapter, struct pkt_attrib *pattrib)
3894 {
3895 u8 SCSettingOfDesc = 0;
3896 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
3897
3898 /* RTW_INFO("SCMapping: pHalData->current_channel_bw %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d\n",pHalData->current_channel_bw,pHalData->nCur80MhzPrimeSC,pHalData->nCur40MhzPrimeSC); */
3899
3900 if (pHalData->current_channel_bw == CHANNEL_WIDTH_80) {
3901 if (pattrib->bwmode == CHANNEL_WIDTH_80)
3902 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
3903 else if (pattrib->bwmode == CHANNEL_WIDTH_40) {
3904 if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
3905 SCSettingOfDesc = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3906 else if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
3907 SCSettingOfDesc = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3908 else
3909 RTW_INFO("SCMapping: DONOT CARE Mode Setting\n");
3910 } else {
3911 if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
3912 SCSettingOfDesc = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3913 else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
3914 SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3915 else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
3916 SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3917 else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
3918 SCSettingOfDesc = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3919 else
3920 RTW_INFO("SCMapping: DONOT CARE Mode Setting\n");
3921 }
3922 } else if (pHalData->current_channel_bw == CHANNEL_WIDTH_40) {
3923 /* RTW_INFO("SCMapping: HT Case: pHalData->current_channel_bw %d, pHalData->nCur40MhzPrimeSC %d\n",pHalData->current_channel_bw,pHalData->nCur40MhzPrimeSC); */
3924
3925 if (pattrib->bwmode == CHANNEL_WIDTH_40)
3926 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
3927 else if (pattrib->bwmode == CHANNEL_WIDTH_20) {
3928 if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
3929 SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3930 else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
3931 SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3932 else
3933 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
3934 }
3935 } else
3936 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
3937
3938 return SCSettingOfDesc;
3939 }
3940
fill_txdesc_force_bmc_camid(struct pkt_attrib * pattrib,u8 * ptxdesc)3941 void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc)
3942 {
3943 if ((pattrib->encrypt > 0) && (!pattrib->bswenc)
3944 && (pattrib->bmc_camid != INVALID_SEC_MAC_CAM_ID)) {
3945
3946 SET_TX_DESC_EN_DESC_ID_8723D(ptxdesc, 1);
3947 SET_TX_DESC_MACID_8723D(ptxdesc, pattrib->bmc_camid);
3948 }
3949 }
3950
fill_txdesc_bmc_tx_rate(struct pkt_attrib * pattrib,u8 * ptxdesc)3951 void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc)
3952 {
3953 SET_TX_DESC_USE_RATE_8723D(ptxdesc, 1);
3954 SET_TX_DESC_TX_RATE_8723D(ptxdesc, MRateToHwRate(pattrib->rate));
3955 SET_TX_DESC_DISABLE_FB_8723D(ptxdesc, 1);
3956 }
3957
fill_txdesc_sectype(struct pkt_attrib * pattrib)3958 static u8 fill_txdesc_sectype(struct pkt_attrib *pattrib)
3959 {
3960 u8 sectype = 0;
3961
3962 if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
3963 switch (pattrib->encrypt) {
3964 /* SEC_TYPE */
3965 case _WEP40_:
3966 case _WEP104_:
3967 case _TKIP_:
3968 case _TKIP_WTMIC_:
3969 sectype = 1;
3970 break;
3971
3972 #ifdef CONFIG_WAPI_SUPPORT
3973 case _SMS4_:
3974 sectype = 2;
3975 break;
3976 #endif
3977 case _AES_:
3978 sectype = 3;
3979 break;
3980
3981 case _NO_PRIVACY_:
3982 default:
3983 break;
3984 }
3985 }
3986 return sectype;
3987 }
3988
fill_txdesc_vcs_8723d(PADAPTER padapter,struct pkt_attrib * pattrib,u8 * ptxdesc)3989 static void fill_txdesc_vcs_8723d(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
3990 {
3991 /* RTW_INFO("cvs_mode=%d\n", pattrib->vcs_mode); */
3992
3993 if (pattrib->vcs_mode) {
3994 switch (pattrib->vcs_mode) {
3995 case RTS_CTS:
3996 SET_TX_DESC_RTS_ENABLE_8723D(ptxdesc, 1);
3997 SET_TX_DESC_HW_RTS_ENABLE_8723D(ptxdesc, 1);
3998 break;
3999
4000 case CTS_TO_SELF:
4001 SET_TX_DESC_CTS2SELF_8723D(ptxdesc, 1);
4002 break;
4003
4004 case NONE_VCS:
4005 default:
4006 break;
4007 }
4008
4009 SET_TX_DESC_RTS_RATE_8723D(ptxdesc, 8); /* RTS Rate=24M */
4010 SET_TX_DESC_RTS_RATE_FB_LIMIT_8723D(ptxdesc, 0xF);
4011
4012 if (padapter->mlmeextpriv.mlmext_info.preamble_mode == PREAMBLE_SHORT)
4013 SET_TX_DESC_RTS_SHORT_8723D(ptxdesc, 1);
4014
4015 /* Set RTS BW */
4016 if (pattrib->ht_en)
4017 SET_TX_DESC_RTS_SC_8723D(ptxdesc, SCMapping_8723D(padapter, pattrib));
4018 }
4019 }
4020
fill_txdesc_phy_8723d(PADAPTER padapter,struct pkt_attrib * pattrib,u8 * ptxdesc)4021 static void fill_txdesc_phy_8723d(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
4022 {
4023 /* RTW_INFO("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset); */
4024
4025 if (pattrib->ht_en) {
4026 SET_TX_DESC_DATA_BW_8723D(ptxdesc, BWMapping_8723D(padapter, pattrib));
4027 SET_TX_DESC_DATA_SC_8723D(ptxdesc, SCMapping_8723D(padapter, pattrib));
4028 }
4029 }
4030
rtl8723d_fill_default_txdesc(struct xmit_frame * pxmitframe,u8 * pbuf)4031 static void rtl8723d_fill_default_txdesc(
4032 struct xmit_frame *pxmitframe,
4033 u8 *pbuf)
4034 {
4035 PADAPTER padapter;
4036 HAL_DATA_TYPE *pHalData;
4037 struct mlme_ext_priv *pmlmeext;
4038 struct mlme_ext_info *pmlmeinfo;
4039 struct pkt_attrib *pattrib;
4040 s32 bmcst;
4041
4042 _rtw_memset(pbuf, 0, TXDESC_SIZE);
4043
4044 padapter = pxmitframe->padapter;
4045 pHalData = GET_HAL_DATA(padapter);
4046 pmlmeext = &padapter->mlmeextpriv;
4047 pmlmeinfo = &(pmlmeext->mlmext_info);
4048
4049 pattrib = &pxmitframe->attrib;
4050 bmcst = IS_MCAST(pattrib->ra);
4051
4052 if (pHalData->rf_type == RF_1T1R)
4053 SET_TX_DESC_PATH_A_EN_8723D(pbuf, 1);
4054
4055 if (pxmitframe->frame_tag == DATA_FRAMETAG) {
4056 u8 drv_userate = 0;
4057
4058 SET_TX_DESC_MACID_8723D(pbuf, pattrib->mac_id);
4059 SET_TX_DESC_RATE_ID_8723D(pbuf, pattrib->raid);
4060 SET_TX_DESC_QUEUE_SEL_8723D(pbuf, pattrib->qsel);
4061 SET_TX_DESC_SEQ_8723D(pbuf, pattrib->seqnum);
4062
4063 SET_TX_DESC_SEC_TYPE_8723D(pbuf, fill_txdesc_sectype(pattrib));
4064
4065 if (bmcst)
4066 fill_txdesc_force_bmc_camid(pattrib, pbuf);
4067
4068 fill_txdesc_vcs_8723d(padapter, pattrib, pbuf);
4069
4070 #ifdef CONFIG_P2P
4071 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
4072 if (pattrib->icmp_pkt == 1 && padapter->registrypriv.wifi_spec == 1)
4073 drv_userate = 1;
4074 }
4075 #endif
4076
4077 if ((pattrib->ether_type != 0x888e) &&
4078 (pattrib->ether_type != 0x0806) &&
4079 (pattrib->ether_type != 0x88B4) &&
4080 (pattrib->dhcp_pkt != 1) &&
4081 (drv_userate != 1)
4082 #ifdef CONFIG_AUTO_AP_MODE
4083 && (pattrib->pctrl != _TRUE)
4084 #endif
4085 ) {
4086 /* Non EAP & ARP & DHCP type data packet */
4087
4088 if (pattrib->ampdu_en == _TRUE) {
4089 SET_TX_DESC_AGG_ENABLE_8723D(pbuf, 1);
4090 SET_TX_DESC_MAX_AGG_NUM_8723D(pbuf, 0x1F);
4091 SET_TX_DESC_AMPDU_DENSITY_8723D(pbuf, pattrib->ampdu_spacing);
4092 } else
4093 SET_TX_DESC_BK_8723D(pbuf, 1);
4094
4095 fill_txdesc_phy_8723d(padapter, pattrib, pbuf);
4096
4097 SET_TX_DESC_DATA_RATE_FB_LIMIT_8723D(pbuf, 0x1F);
4098
4099 if (pHalData->fw_ractrl == _FALSE) {
4100 SET_TX_DESC_USE_RATE_8723D(pbuf, 1);
4101
4102 if (pHalData->INIDATA_RATE[pattrib->mac_id] & BIT(7))
4103 SET_TX_DESC_DATA_SHORT_8723D(pbuf, 1);
4104
4105 SET_TX_DESC_TX_RATE_8723D(pbuf, pHalData->INIDATA_RATE[pattrib->mac_id] & 0x7F);
4106 }
4107 if (bmcst)
4108 fill_txdesc_bmc_tx_rate(pattrib, pbuf);
4109
4110 /* modify data rate by iwpriv */
4111 if (padapter->fix_rate != 0xFF) {
4112 SET_TX_DESC_USE_RATE_8723D(pbuf, 1);
4113 if (padapter->fix_rate & BIT(7))
4114 SET_TX_DESC_DATA_SHORT_8723D(pbuf, 1);
4115 SET_TX_DESC_TX_RATE_8723D(pbuf, padapter->fix_rate & 0x7F);
4116 if (!padapter->data_fb)
4117 SET_TX_DESC_DISABLE_FB_8723D(pbuf, 1);
4118 }
4119
4120 if (pattrib->stbc)
4121 SET_TX_DESC_DATA_STBC_8723D(pbuf, 1);
4122
4123 #ifdef CONFIG_CMCC_TEST
4124 SET_TX_DESC_DATA_SHORT_8723D(pbuf, 1); /* use cck short premble */
4125 #endif
4126 } else {
4127 /* EAP data packet and ARP packet. */
4128 /* Use the 1M data rate to send the EAP/ARP packet. */
4129 /* This will maybe make the handshake smooth. */
4130
4131 SET_TX_DESC_BK_8723D(pbuf, 1);
4132 SET_TX_DESC_USE_RATE_8723D(pbuf, 1);
4133 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
4134 SET_TX_DESC_DATA_SHORT_8723D(pbuf, 1);
4135 #ifdef CONFIG_IP_R_MONITOR
4136 if((pattrib->ether_type == ETH_P_ARP) &&
4137 (IsSupportedTxOFDM(padapter->registrypriv.wireless_mode)))
4138 SET_TX_DESC_TX_RATE_8723D(pbuf, MRateToHwRate(IEEE80211_OFDM_RATE_6MB));
4139 else
4140 #endif/*CONFIG_IP_R_MONITOR*/
4141 SET_TX_DESC_TX_RATE_8723D(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4142
4143 RTW_INFO(FUNC_ADPT_FMT ": SP Packet(0x%04X) rate=0x%x SeqNum = %d\n",
4144 FUNC_ADPT_ARG(padapter), pattrib->ether_type, MRateToHwRate(pmlmeext->tx_rate), pattrib->seqnum);
4145 }
4146
4147 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4148 SET_TX_DESC_USB_TXAGG_NUM_8723D(pbuf, pxmitframe->agg_num);
4149 #endif
4150
4151 #ifdef CONFIG_TDLS
4152 #ifdef CONFIG_XMIT_ACK
4153 /* CCX-TXRPT ack for xmit mgmt frames. */
4154 if (pxmitframe->ack_report) {
4155 #ifdef DBG_CCX
4156 RTW_INFO("%s set spe_rpt\n", __func__);
4157 #endif
4158 SET_TX_DESC_CCX_8723D(pbuf, 1);
4159 SET_TX_DESC_SW_DEFINE_8723D(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no));
4160 }
4161 #endif /* CONFIG_XMIT_ACK */
4162 #endif
4163 } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) {
4164
4165 SET_TX_DESC_MACID_8723D(pbuf, pattrib->mac_id);
4166 SET_TX_DESC_QUEUE_SEL_8723D(pbuf, pattrib->qsel);
4167 SET_TX_DESC_RATE_ID_8723D(pbuf, pattrib->raid);
4168 SET_TX_DESC_SEQ_8723D(pbuf, pattrib->seqnum);
4169 SET_TX_DESC_USE_RATE_8723D(pbuf, 1);
4170
4171 SET_TX_DESC_MBSSID_8723D(pbuf, pattrib->mbssid & 0xF);
4172
4173 SET_TX_DESC_RETRY_LIMIT_ENABLE_8723D(pbuf, 1);
4174 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
4175 SET_TX_DESC_DATA_RETRY_LIMIT_8723D(pbuf, 48);
4176 #else
4177 if (pattrib->retry_ctrl == _TRUE)
4178 SET_TX_DESC_DATA_RETRY_LIMIT_8723D(pbuf, 6);
4179 else
4180 SET_TX_DESC_DATA_RETRY_LIMIT_8723D(pbuf, 12);
4181 #endif
4182 SET_TX_DESC_TX_RATE_8723D(pbuf, MRateToHwRate(pattrib->rate));
4183
4184 #ifdef CONFIG_XMIT_ACK
4185 /* CCX-TXRPT ack for xmit mgmt frames. */
4186 if (pxmitframe->ack_report) {
4187 #ifdef DBG_CCX
4188 RTW_INFO("%s set spe_rpt\n", __FUNCTION__);
4189 #endif
4190 SET_TX_DESC_CCX_8723D(pbuf, 1);
4191 SET_TX_DESC_SW_DEFINE_8723D(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no));
4192 }
4193 #endif /* CONFIG_XMIT_ACK */
4194 } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) {
4195 }
4196 #ifdef CONFIG_MP_INCLUDED
4197 else if (pxmitframe->frame_tag == MP_FRAMETAG) {
4198 fill_txdesc_for_mp(padapter, pbuf);
4199 }
4200 #endif
4201 else {
4202
4203 SET_TX_DESC_MACID_8723D(pbuf, pattrib->mac_id);
4204 SET_TX_DESC_RATE_ID_8723D(pbuf, pattrib->raid);
4205 SET_TX_DESC_QUEUE_SEL_8723D(pbuf, pattrib->qsel);
4206 SET_TX_DESC_SEQ_8723D(pbuf, pattrib->seqnum);
4207 SET_TX_DESC_USE_RATE_8723D(pbuf, 1);
4208 SET_TX_DESC_TX_RATE_8723D(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4209 }
4210
4211 SET_TX_DESC_PKT_SIZE_8723D(pbuf, pattrib->last_txcmdsz);
4212
4213 {
4214 u8 pkt_offset, offset;
4215
4216 pkt_offset = 0;
4217 offset = TXDESC_SIZE;
4218 #ifdef CONFIG_USB_HCI
4219 pkt_offset = pxmitframe->pkt_offset;
4220 offset += (pxmitframe->pkt_offset >> 3);
4221 #endif /* CONFIG_USB_HCI */
4222
4223 #ifdef CONFIG_TX_EARLY_MODE
4224 if (pxmitframe->frame_tag == DATA_FRAMETAG) {
4225 pkt_offset = 1;
4226 offset += EARLY_MODE_INFO_SIZE;
4227 }
4228 #endif /* CONFIG_TX_EARLY_MODE */
4229
4230 SET_TX_DESC_PKT_OFFSET_8723D(pbuf, pkt_offset);
4231 SET_TX_DESC_OFFSET_8723D(pbuf, offset);
4232 }
4233
4234 if (bmcst)
4235 SET_TX_DESC_BMC_8723D(pbuf, 1);
4236
4237 /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */
4238 /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */
4239 /* mgnt frame should be controlled by Hw because Fw will also send null data */
4240 /* which we cannot control when Fw LPS enable. */
4241 /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */
4242 /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */
4243 /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */
4244 /* 2010.06.23. Added by tynli. */
4245 if (!pattrib->qos_en)
4246 SET_TX_DESC_HWSEQ_EN_8723D(pbuf, 1);
4247
4248 #ifdef CONFIG_ANTENNA_DIVERSITY
4249 if (!bmcst && pattrib->psta)
4250 odm_set_tx_ant_by_tx_info(adapter_to_phydm(padapter), pbuf, pattrib->psta->cmn.mac_id);
4251 #endif
4252 }
4253
4254 /*
4255 * Description:
4256 *
4257 * Parameters:
4258 * pxmitframe xmitframe
4259 * pbuf where to fill tx desc
4260 */
rtl8723d_update_txdesc(struct xmit_frame * pxmitframe,u8 * pbuf)4261 void rtl8723d_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
4262 {
4263 rtl8723d_fill_default_txdesc(pxmitframe, pbuf);
4264
4265 #if defined(CONFIG_USB_HCI)
4266 rtl8723d_cal_txdesc_chksum((struct tx_desc *)pbuf);
4267 #endif
4268 }
4269
hw_var_set_monitor(PADAPTER adapter,u8 variable,u8 * val)4270 static void hw_var_set_monitor(PADAPTER adapter, u8 variable, u8 *val)
4271 {
4272 #ifdef CONFIG_WIFI_MONITOR
4273 u32 tmp_32bit;
4274 struct net_device *ndev = adapter->pnetdev;
4275 struct mon_reg_backup *mon = &GET_HAL_DATA(adapter)->mon_backup;
4276
4277 mon->known_rcr = 1;
4278 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)& mon->rcr);
4279
4280 /* Receive all type */
4281 tmp_32bit = RCR_AAP | RCR_APP_PHYST_RXFF;
4282
4283 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) {
4284 /* Append FCS */
4285 tmp_32bit |= RCR_APPFCS;
4286 }
4287
4288 rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)& tmp_32bit);
4289
4290 /* Receive all data frames */
4291 mon->known_rxfilter = 1;
4292 mon->rxfilter0 = rtw_read16(adapter, REG_RXFLTMAP0_8723D);
4293 mon->rxfilter1 = rtw_read16(adapter, REG_RXFLTMAP1_8723D);
4294 mon->rxfilter2 = rtw_read16(adapter, REG_RXFLTMAP2_8723D);
4295 rtw_write16(adapter, REG_RXFLTMAP0_8723D, 0xFFFF);
4296 rtw_write16(adapter, REG_RXFLTMAP1_8723D, 0xFFFF);
4297 rtw_write16(adapter, REG_RXFLTMAP2_8723D, 0xFFFF);
4298 #endif /* CONFIG_WIFI_MONITOR */
4299 }
4300
hw_var_set_opmode(PADAPTER padapter,u8 variable,u8 * val)4301 static void hw_var_set_opmode(PADAPTER padapter, u8 variable, u8 *val)
4302 {
4303 u8 val8;
4304 u8 mode = *((u8 *)val);
4305 static u8 isMonitor = _FALSE;
4306
4307 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4308
4309 if (isMonitor == _TRUE) {
4310 #ifdef CONFIG_WIFI_MONITOR
4311 struct mon_reg_backup *backup = &GET_HAL_DATA(padapter)->mon_backup;
4312
4313 if (backup->known_rcr) {
4314 backup->known_rcr = 0;
4315 rtw_hal_set_hwreg(padapter, HW_VAR_RCR, (u8 *)&backup->rcr);
4316 rtw_hal_rcr_set_chk_bssid(padapter, MLME_ACTION_NONE);
4317 }
4318 if (backup->known_rxfilter) {
4319 backup->known_rxfilter = 0;
4320 rtw_write16(padapter, REG_RXFLTMAP0_8723D, backup->rxfilter0);
4321 rtw_write16(padapter, REG_RXFLTMAP1_8723D, backup->rxfilter1);
4322 rtw_write16(padapter, REG_RXFLTMAP2_8723D, backup->rxfilter2);
4323 }
4324 #endif /* CONFIG_WIFI_MONITOR */
4325 isMonitor = _FALSE;
4326 }
4327
4328 if (mode == _HW_STATE_MONITOR_) {
4329 isMonitor = _TRUE;
4330 /* set net_type */
4331 Set_MSR(padapter, _HW_STATE_NOLINK_);
4332
4333 hw_var_set_monitor(padapter, variable, val);
4334 return;
4335 }
4336 /* set mac addr to mac register */
4337 rtw_hal_set_hwreg(padapter, HW_VAR_MAC_ADDR,
4338 adapter_mac_addr(padapter));
4339
4340 #ifdef CONFIG_CONCURRENT_MODE
4341 if (padapter->hw_port == HW_PORT1) {
4342 /* disable Port1 TSF update */
4343 rtw_iface_disable_tsf_update(padapter);
4344
4345 Set_MSR(padapter, mode);
4346
4347 RTW_INFO("#### %s()-%d hw_port(%d) mode=%d ####\n",
4348 __func__, __LINE__, padapter->hw_port, mode);
4349
4350 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
4351 if (!rtw_mi_get_ap_num(padapter) && !rtw_mi_get_mesh_num(padapter)) {
4352 StopTxBeacon(padapter);
4353 #ifdef CONFIG_PCI_HCI
4354 UpdateInterruptMask8723DE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
4355 #else /* !CONFIG_PCI_HCI */
4356 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
4357
4358 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4359 rtw_write8(padapter, REG_DRVERLYINT, 0x05);/* restore early int time to 5ms */
4360 UpdateInterruptMask8723DU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8723D);
4361 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
4362
4363 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
4364 UpdateInterruptMask8723DU(padapter, _TRUE , 0, (IMR_TXBCN0ERR_8723D | IMR_TXBCN0OK_8723D));
4365 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
4366
4367 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
4368 #endif /* !CONFIG_PCI_HCI */
4369 }
4370
4371 /* disable atim wnd */
4372 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT | DIS_ATIM | EN_BCN_FUNCTION);
4373 } else if (mode == _HW_STATE_ADHOC_) {
4374 ResumeTxBeacon(padapter);
4375 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
4376 } else if (mode == _HW_STATE_AP_) {
4377 #ifdef CONFIG_PCI_HCI
4378 UpdateInterruptMask8723DE(padapter, RT_BCN_INT_MASKS, 0, 0, 0);
4379 #else /* !CONFIG_PCI_HCI */
4380 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
4381
4382 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4383 UpdateInterruptMask8723DU(padapter, _TRUE, IMR_BCNDMAINT0_8723D, 0);
4384 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
4385
4386 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
4387 UpdateInterruptMask8723DU(padapter, _TRUE, (IMR_TXBCN0ERR_8723D | IMR_TXBCN0OK_8723D), 0);
4388 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
4389
4390 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
4391 #endif /* !CONFIG_PCI_HCI */
4392
4393 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT | DIS_BCNQ_SUB);
4394
4395 /* enable to rx data frame*/
4396 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
4397 /* enable to rx ps-poll */
4398 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
4399
4400 /* Beacon Control related register for first time */
4401 rtw_write8(padapter, REG_BCNDMATIM, 0x02); /* 2ms */
4402
4403 /* rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF); */
4404 rtw_write8(padapter, REG_ATIMWND_1, 0x0c); /* 13ms for port1 */
4405
4406 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
4407
4408 /* reset TSF2 */
4409 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
4410
4411 /* enable BCN1 Function for if2 */
4412 /* don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received) */
4413 rtw_write8(padapter, REG_BCN_CTRL_1, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
4414
4415 /* SW_BCN_SEL - Port1 */
4416 /* rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2)|BIT4); */
4417 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
4418
4419 /* select BCN on port 1 */
4420 rtw_write8(padapter, REG_CCK_CHECK_8723D,
4421 (rtw_read8(padapter, REG_CCK_CHECK_8723D) | BIT_BCN_PORT_SEL));
4422
4423 /* BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked */
4424 /* rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1)|BIT(5)); */
4425 /* rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(3)); */
4426
4427 /* dis BCN0 ATIM WND if if1 is station */
4428 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | DIS_ATIM);
4429
4430 #ifdef CONFIG_TSF_RESET_OFFLOAD
4431 /* Reset TSF for STA+AP concurrent mode */
4432 if (DEV_STA_LD_NUM(adapter_to_dvobj(padapter))) {
4433 if (rtw_hal_reset_tsf(padapter, HW_PORT1) == _FAIL)
4434 RTW_INFO("ERROR! %s()-%d: Reset port1 TSF fail\n",
4435 __FUNCTION__, __LINE__);
4436 }
4437 #endif /* CONFIG_TSF_RESET_OFFLOAD */
4438 }
4439 } else /* else for port0 */
4440 #endif /* CONFIG_CONCURRENT_MODE */
4441 {
4442 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*For Port0 - MBSS CAM*/
4443 hw_var_set_opmode_mbid(padapter, mode);
4444 #else
4445 /* disable Port0 TSF update */
4446 rtw_iface_disable_tsf_update(padapter);
4447
4448 /* set net_type */
4449 Set_MSR(padapter, mode);
4450 RTW_INFO("#### %s() -%d hw_port(0) mode = %d ####\n",
4451 __func__, __LINE__, mode);
4452
4453 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
4454 #ifdef CONFIG_CONCURRENT_MODE
4455 if (!rtw_mi_get_ap_num(padapter) && !rtw_mi_get_mesh_num(padapter)) {
4456 #else
4457 {
4458 #endif /* CONFIG_CONCURRENT_MODE */
4459 StopTxBeacon(padapter);
4460 #ifdef CONFIG_PCI_HCI
4461 UpdateInterruptMask8723DE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
4462 #else /* !CONFIG_PCI_HCI */
4463 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
4464 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4465 rtw_write8(padapter, REG_DRVERLYINT, 0x05); /* restore early int time to 5ms */
4466 UpdateInterruptMask8812AU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8723D);
4467 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
4468
4469 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
4470 UpdateInterruptMask8812AU(padapter, _TRUE , 0, (IMR_TXBCN0ERR_8723D | IMR_TXBCN0OK_8723D));
4471 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
4472
4473 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
4474 #endif /* !CONFIG_PCI_HCI */
4475 }
4476
4477 /* disable atim wnd */
4478 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM);
4479 /* rtw_write8(padapter,REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION); */
4480 } else if (mode == _HW_STATE_ADHOC_) {
4481 ResumeTxBeacon(padapter);
4482 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
4483 } else if (mode == _HW_STATE_AP_) {
4484 #ifdef CONFIG_PCI_HCI
4485 UpdateInterruptMask8723DE(padapter, RT_BCN_INT_MASKS, 0, 0, 0);
4486 #else /* !CONFIG_PCI_HCI */
4487 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
4488 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4489 UpdateInterruptMask8723DU(padapter, _TRUE , IMR_BCNDMAINT0_8723D, 0);
4490 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
4491
4492 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
4493 UpdateInterruptMask8723DU(padapter, _TRUE , (IMR_TXBCN0ERR_8723D | IMR_TXBCN0OK_8723D), 0);
4494 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
4495
4496 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
4497 #endif
4498
4499 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
4500
4501 /* enable to rx data frame */
4502 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
4503 /* enable to rx ps-poll */
4504 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
4505
4506 /* Beacon Control related register for first time */
4507 rtw_write8(padapter, REG_BCNDMATIM, 0x02); /* 2ms */
4508
4509 /* rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF); */
4510 rtw_write8(padapter, REG_ATIMWND, 0x0c); /* 13ms */
4511
4512 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
4513
4514 /* reset TSF */
4515 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
4516
4517 /* enable BCN0 Function for if1 */
4518 /* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
4519 rtw_write8(padapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
4520
4521 /* SW_BCN_SEL - Port0 */
4522 /* rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2) & ~BIT4); */
4523 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
4524
4525 /* select BCN on port 0 */
4526 rtw_write8(padapter, REG_CCK_CHECK_8723D,
4527 (rtw_read8(padapter, REG_CCK_CHECK_8723D) & ~BIT_BCN_PORT_SEL));
4528
4529 /* dis BCN1 ATIM WND if if2 is station */
4530 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
4531 val8 |= DIS_ATIM;
4532 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
4533 #ifdef CONFIG_TSF_RESET_OFFLOAD
4534 /* Reset TSF for STA+AP concurrent mode */
4535 if (DEV_STA_LD_NUM(adapter_to_dvobj(padapter))) {
4536 if (rtw_hal_reset_tsf(padapter, HW_PORT0) == _FAIL)
4537 RTW_INFO("ERROR! %s()-%d: Reset port0 TSF fail\n",
4538 __FUNCTION__, __LINE__);
4539 }
4540 #endif /* CONFIG_TSF_RESET_OFFLOAD */
4541 }
4542 #endif /* !CONFIG_MI_WITH_MBSSID_CAM */
4543 }
4544 }
4545
4546 void CCX_FwC2HTxRpt_8723d(PADAPTER padapter, u8 *pdata, u8 len)
4547 {
4548 u8 seq_no;
4549
4550 #define GET_8723D_C2H_TX_RPT_LIFE_TIME_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 6, 1)
4551 #define GET_8723D_C2H_TX_RPT_RETRY_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 7, 1)
4552
4553 /* RTW_INFO("%s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", __func__, */
4554 /**pdata, *(pdata+1), *(pdata+2), *(pdata+3), *(pdata+4), *(pdata+5), *(pdata+6), *(pdata+7)); */
4555
4556 seq_no = *(pdata + 6);
4557
4558 #ifdef CONFIG_XMIT_ACK
4559 if (GET_8723D_C2H_TX_RPT_RETRY_OVER(pdata) | GET_8723D_C2H_TX_RPT_LIFE_TIME_OVER(pdata))
4560 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
4561 /*
4562 else if(seq_no != padapter->xmitpriv.seq_no) {
4563 RTW_INFO("tx_seq_no=%d, rpt_seq_no=%d\n", padapter->xmitpriv.seq_no, seq_no);
4564 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
4565 }
4566 */
4567 else
4568 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);
4569 #endif
4570 }
4571
4572 s32 c2h_handler_8723d(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload)
4573 {
4574 s32 ret = _SUCCESS;
4575
4576 switch (id) {
4577 case C2H_CCX_TX_RPT:
4578 CCX_FwC2HTxRpt_8723d(adapter, payload, plen);
4579 break;
4580 default:
4581 ret = _FAIL;
4582 break;
4583 }
4584
4585 return ret;
4586 }
4587
4588 u8 SetHwReg8723D(PADAPTER padapter, u8 variable, u8 *val)
4589 {
4590 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4591 u8 ret = _SUCCESS;
4592 u8 val8;
4593 u16 val16;
4594 u32 val32;
4595
4596
4597 switch (variable) {
4598 case HW_VAR_SET_OPMODE:
4599 hw_var_set_opmode(padapter, variable, val);
4600 break;
4601
4602 case HW_VAR_BASIC_RATE:
4603 rtw_var_set_basic_rate(padapter, val);
4604 break;
4605
4606 case HW_VAR_TXPAUSE:
4607 rtw_write8(padapter, REG_TXPAUSE, *val);
4608 break;
4609
4610 case HW_VAR_SLOT_TIME:
4611 rtw_write8(padapter, REG_SLOT, *val);
4612 break;
4613
4614 case HW_VAR_RESP_SIFS:
4615 #if 0
4616 /* SIFS for OFDM Data ACK */
4617 rtw_write8(padapter, REG_SIFS_CTX + 1, val[0]);
4618 /* SIFS for OFDM consecutive tx like CTS data! */
4619 rtw_write8(padapter, REG_SIFS_TRX + 1, val[1]);
4620
4621 rtw_write8(padapter, REG_SPEC_SIFS + 1, val[0]);
4622 rtw_write8(padapter, REG_MAC_SPEC_SIFS + 1, val[0]);
4623
4624 /* 20100719 Joseph: Revise SIFS setting due to Hardware register definition change. */
4625 rtw_write8(padapter, REG_R2T_SIFS + 1, val[0]);
4626 rtw_write8(padapter, REG_T2T_SIFS + 1, val[0]);
4627
4628 #else
4629 /* SIFS_Timer = 0x0a0a0808; */
4630 /* RESP_SIFS for CCK */
4631 rtw_write8(padapter, REG_RESP_SIFS_CCK, val[0]); /* SIFS_T2T_CCK (0x08) */
4632 rtw_write8(padapter, REG_RESP_SIFS_CCK + 1, val[1]); /* SIFS_R2T_CCK(0x08) */
4633 /* RESP_SIFS for OFDM */
4634 rtw_write8(padapter, REG_RESP_SIFS_OFDM, val[2]); /* SIFS_T2T_OFDM (0x0a) */
4635 rtw_write8(padapter, REG_RESP_SIFS_OFDM + 1, val[3]); /* SIFS_R2T_OFDM(0x0a) */
4636 #endif
4637 break;
4638
4639 case HW_VAR_ACK_PREAMBLE: {
4640 u8 regTmp;
4641 u8 bShortPreamble = *val;
4642
4643 /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
4644 /* regTmp = (pHalData->nCur40MhzPrimeSC)<<5; */
4645 regTmp = rtw_read8(padapter, REG_WMAC_TRXPTCL_CTL + 2);
4646 if (bShortPreamble) {
4647 regTmp |= BIT(1);/*668[17]*/
4648 } else {
4649 regTmp &= ~BIT(1);
4650 }
4651 rtw_write8(padapter, REG_WMAC_TRXPTCL_CTL + 2, regTmp);
4652 }
4653 break;
4654
4655 case HW_VAR_CAM_INVALID_ALL:
4656 rtw_write32(padapter, REG_CAMCMD, BIT(31) | BIT(30));
4657 break;
4658
4659 case HW_VAR_AC_PARAM_VO:
4660 rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32 *)val));
4661 break;
4662
4663 case HW_VAR_AC_PARAM_VI:
4664 rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32 *)val));
4665 break;
4666
4667 case HW_VAR_AC_PARAM_BE:
4668 pHalData->ac_param_be = ((u32 *)(val))[0];
4669 rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32 *)val));
4670 break;
4671
4672 case HW_VAR_AC_PARAM_BK:
4673 rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32 *)val));
4674 break;
4675
4676 case HW_VAR_ACM_CTRL: {
4677 u8 ctrl = *((u8 *)val);
4678 u8 hwctrl = 0;
4679
4680 if (ctrl != 0) {
4681 hwctrl |= AcmHw_HwEn;
4682
4683 if (ctrl & BIT(3)) /* BE */
4684 hwctrl |= AcmHw_BeqEn;
4685
4686 if (ctrl & BIT(2)) /* VI */
4687 hwctrl |= AcmHw_ViqEn;
4688
4689 if (ctrl & BIT(1)) /* VO */
4690 hwctrl |= AcmHw_VoqEn;
4691 }
4692
4693 RTW_INFO("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
4694 rtw_write8(padapter, REG_ACMHWCTRL, hwctrl);
4695 }
4696 break;
4697 #ifdef CONFIG_80211N_HT
4698 case HW_VAR_AMPDU_FACTOR: {
4699 u32 AMPDULen = (*((u8 *)val));
4700
4701 if (AMPDULen < HT_AGG_SIZE_32K)
4702 AMPDULen = (0x2000 << (*((u8 *)val))) - 1;
4703 else
4704 AMPDULen = 0x7fff;
4705
4706 rtw_write32(padapter, REG_AMPDU_MAX_LENGTH_8723D, AMPDULen);
4707 }
4708 break;
4709 #endif /* CONFIG_80211N_HT */
4710 case HW_VAR_H2C_FW_PWRMODE: {
4711 u8 psmode = *val;
4712
4713 /* if (psmode != PS_MODE_ACTIVE) { */
4714 /*rtl8723d_set_lowpwr_lps_cmd(padapter, _TRUE); */
4715 /* } else { */
4716 /* rtl8723d_set_lowpwr_lps_cmd(padapter, _FALSE); */
4717 /* } */
4718 rtl8723d_set_FwPwrMode_cmd(padapter, psmode);
4719 }
4720 break;
4721 case HW_VAR_H2C_PS_TUNE_PARAM:
4722 rtl8723d_set_FwPsTuneParam_cmd(padapter);
4723 break;
4724
4725 case HW_VAR_H2C_FW_JOINBSSRPT:
4726 rtl8723d_set_FwJoinBssRpt_cmd(padapter, *val);
4727 #ifdef CONFIG_LPS_POFF
4728 rtl8723d_lps_poff_h2c_ctrl(padapter, *val);
4729 #endif
4730 break;
4731
4732 case HW_VAR_DL_RSVD_PAGE:
4733 #ifdef CONFIG_BT_COEXIST
4734 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
4735 rtl8723d_download_BTCoex_AP_mode_rsvd_page(padapter);
4736 else
4737 #endif /* CONFIG_BT_COEXIST */
4738 {
4739 rtl8723d_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
4740 }
4741 break;
4742
4743 #ifdef CONFIG_P2P
4744 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
4745 rtl8723d_set_p2p_ps_offload_cmd(padapter, *val);
4746 break;
4747 #endif /* CONFIG_P2P */
4748 #ifdef CONFIG_LPS_POFF
4749 case HW_VAR_LPS_POFF_INIT:
4750 rtl8723d_lps_poff_init(padapter);
4751 break;
4752 case HW_VAR_LPS_POFF_DEINIT:
4753 rtl8723d_lps_poff_deinit(padapter);
4754 break;
4755 case HW_VAR_LPS_POFF_SET_MODE:
4756 rtl8723d_lps_poff_set_ps_mode(padapter, *val);
4757 break;
4758 case HW_VAR_LPS_POFF_WOW_EN:
4759 rtl8723d_lps_poff_h2c_ctrl(padapter, *val);
4760 break;
4761 #endif /*CONFIG_LPS_POFF*/
4762
4763 case HW_VAR_EFUSE_USAGE:
4764 pHalData->EfuseUsedPercentage = *val;
4765 break;
4766
4767 case HW_VAR_EFUSE_BYTES:
4768 pHalData->EfuseUsedBytes = *((u16 *)val);
4769 break;
4770
4771 case HW_VAR_EFUSE_BT_USAGE:
4772 #ifdef HAL_EFUSE_MEMORY
4773 pHalData->EfuseHal.BTEfuseUsedPercentage = *val;
4774 #endif
4775 break;
4776
4777 case HW_VAR_EFUSE_BT_BYTES:
4778 #ifdef HAL_EFUSE_MEMORY
4779 pHalData->EfuseHal.BTEfuseUsedBytes = *((u16 *)val);
4780 #else
4781 BTEfuseUsedBytes = *((u16 *)val);
4782 #endif
4783 break;
4784
4785 case HW_VAR_FIFO_CLEARN_UP: {
4786 #define RW_RELEASE_EN BIT(18)
4787 #define RXDMA_IDLE BIT(17)
4788
4789 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4790 u8 trycnt = 100;
4791
4792 /* pause tx */
4793 rtw_write8(padapter, REG_TXPAUSE, 0xff);
4794
4795 /* keep sn */
4796 padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ);
4797
4798 if (pwrpriv->bkeepfwalive != _TRUE) {
4799 /* RX DMA stop */
4800 val32 = rtw_read32(padapter, REG_RXPKT_NUM);
4801 val32 |= RW_RELEASE_EN;
4802 rtw_write32(padapter, REG_RXPKT_NUM, val32);
4803 do {
4804 val32 = rtw_read32(padapter, REG_RXPKT_NUM);
4805 val32 &= RXDMA_IDLE;
4806 if (val32)
4807 break;
4808
4809 RTW_INFO("%s: [HW_VAR_FIFO_CLEARN_UP] val=%x times:%d\n", __FUNCTION__, val32, trycnt);
4810 } while (--trycnt);
4811 if (trycnt == 0)
4812 RTW_INFO("[HW_VAR_FIFO_CLEARN_UP] Stop RX DMA failed......\n");
4813
4814 /* RQPN Load 0 */
4815 rtw_write16(padapter, REG_RQPN_NPQ, 0);
4816 rtw_write32(padapter, REG_RQPN, 0x80000000);
4817 rtw_mdelay_os(2);
4818 }
4819 }
4820 break;
4821
4822 case HW_VAR_RESTORE_HW_SEQ:
4823 /* restore Sequence No. */
4824 rtw_write8(padapter, 0x4dc, padapter->xmitpriv.nqos_ssn);
4825 break;
4826
4827 #ifdef CONFIG_CONCURRENT_MODE
4828 case HW_VAR_CHECK_TXBUF: {
4829 u32 i;
4830 u8 RetryLimit = 0x01;
4831 u32 reg_200, reg_204;
4832
4833 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
4834 rtw_write16(padapter, REG_RETRY_LIMIT, val16);
4835
4836 for (i = 0; i < 200; i++) { /* polling 200x10=2000 msec */
4837 reg_200 = rtw_read32(padapter, 0x200);
4838 reg_204 = rtw_read32(padapter, 0x204);
4839 if (reg_200 != reg_204) {
4840 /* RTW_INFO("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(padapter, 0x204), rtw_read32(padapter, 0x200), i); */
4841 rtw_msleep_os(10);
4842 } else {
4843 RTW_INFO("[HW_VAR_CHECK_TXBUF] no packet in tx packet buffer (%d)\n", i);
4844 break;
4845 }
4846 }
4847
4848 if (reg_200 != reg_204)
4849 RTW_INFO("packets in tx buffer - 0x204=%x, 0x200=%x\n", reg_204, reg_200);
4850
4851 RetryLimit = RL_VAL_STA;
4852 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
4853 rtw_write16(padapter, REG_RETRY_LIMIT, val16);
4854 }
4855 break;
4856 #endif /* CONFIG_CONCURRENT_MODE */
4857
4858 case HW_VAR_NAV_UPPER: {
4859 u32 usNavUpper = *((u32 *)val);
4860
4861 if (usNavUpper > HAL_NAV_UPPER_UNIT_8723D * 0xFF) {
4862 break;
4863 }
4864
4865 /* The value of ((usNavUpper + HAL_NAV_UPPER_UNIT_8723D - 1) / HAL_NAV_UPPER_UNIT_8723D) */
4866 /* is getting the upper integer. */
4867 usNavUpper = (usNavUpper + HAL_NAV_UPPER_UNIT_8723D - 1) / HAL_NAV_UPPER_UNIT_8723D;
4868 rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);
4869 }
4870 break;
4871
4872 case HW_VAR_BCN_VALID:
4873 #ifdef CONFIG_CONCURRENT_MODE
4874 if (padapter->hw_port == HW_PORT1) {
4875 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723D + 2);
4876 val8 |= BIT(0);
4877 rtw_write8(padapter, REG_DWBCN1_CTRL_8723D + 2, val8);
4878 } else
4879 #endif /* CONFIG_CONCURRENT_MODE */
4880 {
4881 /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw */
4882 val8 = rtw_read8(padapter, REG_TDECTRL + 2);
4883 val8 |= BIT(0);
4884 rtw_write8(padapter, REG_TDECTRL + 2, val8);
4885 }
4886 break;
4887 case HW_VAR_DL_BCN_SEL:
4888 #ifdef CONFIG_CONCURRENT_MODE
4889 if (padapter->hw_port == HW_PORT1) {
4890 /* SW_BCN_SEL - Port1 */
4891 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723D + 2);
4892 val8 |= BIT(4);
4893 rtw_write8(padapter, REG_DWBCN1_CTRL_8723D + 2, val8);
4894 } else
4895 #endif /* CONFIG_CONCURRENT_MODE */
4896 {
4897 /* SW_BCN_SEL - Port0 */
4898 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723D + 2);
4899 val8 &= ~BIT(4);
4900 rtw_write8(padapter, REG_DWBCN1_CTRL_8723D + 2, val8);
4901 }
4902 break;
4903
4904 default:
4905 ret = SetHwReg(padapter, variable, val);
4906 break;
4907 }
4908
4909 return ret;
4910 }
4911
4912 #ifdef CONFIG_PROC_DEBUG
4913 struct qinfo_8723d {
4914 u32 head:8;
4915 u32 pkt_num:7;
4916 u32 tail:8;
4917 u32 ac:2;
4918 u32 macid:7;
4919 };
4920
4921 struct bcn_qinfo_8723d {
4922 u16 head:8;
4923 u16 pkt_num:8;
4924 };
4925
4926 void dump_qinfo_8723d(void *sel, struct qinfo_8723d *info, const char *tag)
4927 {
4928 /* if (info->pkt_num) */
4929 RTW_PRINT_SEL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n"
4930 , tag ? tag : "", info->head, info->tail,
4931 info->pkt_num, info->macid, info->ac);
4932 }
4933
4934 void dump_bcn_qinfo_8723d(void *sel, struct bcn_qinfo_8723d *info, const char *tag)
4935 {
4936 /* if (info->pkt_num) */
4937 RTW_PRINT_SEL(sel, "%shead:0x%02x, pkt_num:%u\n"
4938 , tag ? tag : "", info->head, info->pkt_num);
4939 }
4940
4941 void dump_mac_qinfo_8723d(void *sel, _adapter *adapter)
4942 {
4943 u32 q0_info;
4944 u32 q1_info;
4945 u32 q2_info;
4946 u32 q3_info;
4947 u32 q4_info;
4948 u32 q5_info;
4949 u32 q6_info;
4950 u32 q7_info;
4951 u32 mg_q_info;
4952 u32 hi_q_info;
4953 u16 bcn_q_info;
4954
4955 q0_info = rtw_read32(adapter, REG_Q0_INFO);
4956 q1_info = rtw_read32(adapter, REG_Q1_INFO);
4957 q2_info = rtw_read32(adapter, REG_Q2_INFO);
4958 q3_info = rtw_read32(adapter, REG_Q3_INFO);
4959 q4_info = rtw_read32(adapter, REG_Q4_INFO);
4960 q5_info = rtw_read32(adapter, REG_Q5_INFO);
4961 q6_info = rtw_read32(adapter, REG_Q6_INFO);
4962 q7_info = rtw_read32(adapter, REG_Q7_INFO);
4963 mg_q_info = rtw_read32(adapter, REG_MGQ_INFO);
4964 hi_q_info = rtw_read32(adapter, REG_HGQ_INFO);
4965 bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO);
4966
4967 dump_qinfo_8723d(sel, (struct qinfo_8723d *)&q0_info, "Q0 ");
4968 dump_qinfo_8723d(sel, (struct qinfo_8723d *)&q1_info, "Q1 ");
4969 dump_qinfo_8723d(sel, (struct qinfo_8723d *)&q2_info, "Q2 ");
4970 dump_qinfo_8723d(sel, (struct qinfo_8723d *)&q3_info, "Q3 ");
4971 dump_qinfo_8723d(sel, (struct qinfo_8723d *)&q4_info, "Q4 ");
4972 dump_qinfo_8723d(sel, (struct qinfo_8723d *)&q5_info, "Q5 ");
4973 dump_qinfo_8723d(sel, (struct qinfo_8723d *)&q6_info, "Q6 ");
4974 dump_qinfo_8723d(sel, (struct qinfo_8723d *)&q7_info, "Q7 ");
4975 dump_qinfo_8723d(sel, (struct qinfo_8723d *)&mg_q_info, "MG ");
4976 dump_qinfo_8723d(sel, (struct qinfo_8723d *)&hi_q_info, "HI ");
4977 dump_bcn_qinfo_8723d(sel, (struct bcn_qinfo_8723d *)&bcn_q_info, "BCN ");
4978 }
4979
4980 static void dump_mac_txfifo_8723d(void *sel, _adapter *adapter)
4981 {
4982 u32 rqpn, rqpn_npq;
4983 u32 hpq, lpq, npq, epq, pubq;
4984
4985 rqpn = rtw_read32(adapter, REG_FIFOPAGE);
4986 rqpn_npq = rtw_read32(adapter, REG_RQPN_NPQ);
4987
4988 hpq = (rqpn & 0xFF);
4989 lpq = ((rqpn & 0xFF00)>>8);
4990 pubq = ((rqpn & 0xFF0000)>>16);
4991 npq = ((rqpn_npq & 0xFF00)>>8);
4992 epq = ((rqpn_npq & 0xFF000000)>>24);
4993
4994 RTW_PRINT_SEL(sel, "Tx: available page num: ");
4995 if ((hpq == 0xEA) && (hpq == lpq) && (hpq == pubq))
4996 RTW_PRINT_SEL(sel, "N/A (reg val = 0xea)\n");
4997 else
4998 RTW_PRINT_SEL(sel, "HPQ: %d, LPQ: %d, NPQ: %d, EPQ: %d, PUBQ: %d\n"
4999 , hpq, lpq, npq, epq, pubq);
5000 }
5001 #endif
5002
5003 void rtl8723d_read_wmmedca_reg(PADAPTER adapter, u16 *vo_params, u16 *vi_params, u16 *be_params, u16 *bk_params)
5004 {
5005 u8 vo_reg_params[4];
5006 u8 vi_reg_params[4];
5007 u8 be_reg_params[4];
5008 u8 bk_reg_params[4];
5009
5010 GetHwReg8723D(adapter, HW_VAR_AC_PARAM_VO, vo_reg_params);
5011 GetHwReg8723D(adapter, HW_VAR_AC_PARAM_VI, vi_reg_params);
5012 GetHwReg8723D(adapter, HW_VAR_AC_PARAM_BE, be_reg_params);
5013 GetHwReg8723D(adapter, HW_VAR_AC_PARAM_BK, bk_reg_params);
5014
5015 vo_params[0] = vo_reg_params[0];
5016 vo_params[1] = vo_reg_params[1] & 0x0F;
5017 vo_params[2] = (vo_reg_params[1] & 0xF0) >> 4;
5018 vo_params[3] = ((vo_reg_params[3] << 8) | (vo_reg_params[2])) * 32;
5019
5020 vi_params[0] = vi_reg_params[0];
5021 vi_params[1] = vi_reg_params[1] & 0x0F;
5022 vi_params[2] = (vi_reg_params[1] & 0xF0) >> 4;
5023 vi_params[3] = ((vi_reg_params[3] << 8) | (vi_reg_params[2])) * 32;
5024
5025 be_params[0] = be_reg_params[0];
5026 be_params[1] = be_reg_params[1] & 0x0F;
5027 be_params[2] = (be_reg_params[1] & 0xF0) >> 4;
5028 be_params[3] = ((be_reg_params[3] << 8) | (be_reg_params[2])) * 32;
5029
5030 bk_params[0] = bk_reg_params[0];
5031 bk_params[1] = bk_reg_params[1] & 0x0F;
5032 bk_params[2] = (bk_reg_params[1] & 0xF0) >> 4;
5033 bk_params[3] = ((bk_reg_params[3] << 8) | (bk_reg_params[2])) * 32;
5034
5035 vo_params[1] = (1 << vo_params[1]) - 1;
5036 vo_params[2] = (1 << vo_params[2]) - 1;
5037 vi_params[1] = (1 << vi_params[1]) - 1;
5038 vi_params[2] = (1 << vi_params[2]) - 1;
5039 be_params[1] = (1 << be_params[1]) - 1;
5040 be_params[2] = (1 << be_params[2]) - 1;
5041 bk_params[1] = (1 << bk_params[1]) - 1;
5042 bk_params[2] = (1 << bk_params[2]) - 1;
5043 }
5044
5045 void GetHwReg8723D(PADAPTER padapter, u8 variable, u8 *val)
5046 {
5047 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
5048 u8 val8;
5049 u16 val16;
5050 u32 val32;
5051
5052 switch (variable) {
5053 case HW_VAR_TXPAUSE:
5054 *val = rtw_read8(padapter, REG_TXPAUSE);
5055 break;
5056
5057 case HW_VAR_BCN_VALID:
5058 #ifdef CONFIG_CONCURRENT_MODE
5059 if (padapter->hw_port == HW_PORT1) {
5060 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723D + 2);
5061 *val = (BIT(0) & val8) ? _TRUE : _FALSE;
5062 } else
5063 #endif
5064 {
5065 /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */
5066 val8 = rtw_read8(padapter, REG_TDECTRL + 2);
5067 *val = (BIT(0) & val8) ? _TRUE : _FALSE;
5068 }
5069 break;
5070
5071 case HW_VAR_AC_PARAM_VO:
5072 val32 = rtw_read32(padapter, REG_EDCA_VO_PARAM);
5073 val[0] = val32 & 0xFF;
5074 val[1] = (val32 >> 8) & 0xFF;
5075 val[2] = (val32 >> 16) & 0xFF;
5076 val[3] = (val32 >> 24) & 0x07;
5077 break;
5078
5079 case HW_VAR_AC_PARAM_VI:
5080 val32 = rtw_read32(padapter, REG_EDCA_VI_PARAM);
5081 val[0] = val32 & 0xFF;
5082 val[1] = (val32 >> 8) & 0xFF;
5083 val[2] = (val32 >> 16) & 0xFF;
5084 val[3] = (val32 >> 24) & 0x07;
5085 break;
5086
5087 case HW_VAR_AC_PARAM_BE:
5088 val32 = rtw_read32(padapter, REG_EDCA_BE_PARAM);
5089 val[0] = val32 & 0xFF;
5090 val[1] = (val32 >> 8) & 0xFF;
5091 val[2] = (val32 >> 16) & 0xFF;
5092 val[3] = (val32 >> 24) & 0x07;
5093 break;
5094
5095 case HW_VAR_AC_PARAM_BK:
5096 val32 = rtw_read32(padapter, REG_EDCA_BK_PARAM);
5097 val[0] = val32 & 0xFF;
5098 val[1] = (val32 >> 8) & 0xFF;
5099 val[2] = (val32 >> 16) & 0xFF;
5100 val[3] = (val32 >> 24) & 0x07;
5101 break;
5102
5103 case HW_VAR_EFUSE_USAGE:
5104 *val = pHalData->EfuseUsedPercentage;
5105 break;
5106
5107 case HW_VAR_EFUSE_BYTES:
5108 *((u16 *)val) = pHalData->EfuseUsedBytes;
5109 break;
5110
5111 case HW_VAR_EFUSE_BT_USAGE:
5112 #ifdef HAL_EFUSE_MEMORY
5113 *val = pHalData->EfuseHal.BTEfuseUsedPercentage;
5114 #endif
5115 break;
5116
5117 case HW_VAR_EFUSE_BT_BYTES:
5118 #ifdef HAL_EFUSE_MEMORY
5119 *((u16 *)val) = pHalData->EfuseHal.BTEfuseUsedBytes;
5120 #else
5121 *((u16 *)val) = BTEfuseUsedBytes;
5122 #endif
5123 break;
5124
5125 case HW_VAR_CHK_HI_QUEUE_EMPTY:
5126 val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);
5127 *val = (val16 & BIT(10)) ? _TRUE : _FALSE;
5128 break;
5129 case HW_VAR_CHK_MGQ_CPU_EMPTY:
5130 val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);
5131 *val = (val16 & BIT(8)) ? _TRUE : _FALSE;
5132 break;
5133 #ifdef CONFIG_WOWLAN
5134 case HW_VAR_RPWM_TOG:
5135 *val = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HRPWM1) & BIT(7);
5136 break;
5137 case HW_VAR_WAKEUP_REASON:
5138 *val = rtw_read8(padapter, REG_WOWLAN_WAKE_REASON);
5139 if (*val == 0xEA)
5140 *val = 0;
5141 break;
5142 case HW_VAR_SYS_CLKR:
5143 *val = rtw_read8(padapter, REG_SYS_CLKR);
5144 break;
5145 #endif
5146 #ifdef CONFIG_PROC_DEBUG
5147 case HW_VAR_DUMP_MAC_QUEUE_INFO:
5148 dump_mac_qinfo_8723d(val, padapter);
5149 break;
5150 case HW_VAR_DUMP_MAC_TXFIFO:
5151 dump_mac_txfifo_8723d(val, padapter);
5152 break;
5153 #endif
5154 default:
5155 GetHwReg(padapter, variable, val);
5156 break;
5157 }
5158 }
5159
5160 /*
5161 * Description:
5162 * Change default setting of specified variable.
5163 */
5164 u8 SetHalDefVar8723D(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
5165 {
5166 PHAL_DATA_TYPE pHalData;
5167 u8 bResult;
5168
5169 bResult = _SUCCESS;
5170
5171 switch (variable) {
5172 default:
5173 bResult = SetHalDefVar(padapter, variable, pval);
5174 break;
5175 }
5176
5177 return bResult;
5178 }
5179
5180 void hal_ra_info_dump(_adapter *padapter , void *sel)
5181 {
5182 int i;
5183 u8 mac_id;
5184 u32 cmd;
5185 u32 ra_info1, ra_info2, bw_set;
5186 u32 rate_mask1, rate_mask2;
5187 u8 curr_tx_rate, curr_tx_sgi, hight_rate, lowest_rate;
5188 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
5189 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
5190 HAL_DATA_TYPE *HalData = GET_HAL_DATA(padapter);
5191
5192 for (i = 0; i < macid_ctl->num; i++) {
5193
5194 if (rtw_macid_is_used(macid_ctl, i) && !rtw_macid_is_bmc(macid_ctl, i)) {
5195
5196 mac_id = (u8) i;
5197 _RTW_PRINT_SEL(sel , "============ RA status check Mac_id:%d ===================\n", mac_id);
5198
5199 cmd = 0x40000100 | mac_id;
5200 rtw_write32(padapter, REG_HMEBOX_DBG_2_8723D, cmd);
5201 rtw_msleep_os(10);
5202 ra_info1 = rtw_read32(padapter, 0x2F0);
5203 curr_tx_sgi = rtw_get_current_tx_sgi(padapter, macid_ctl->sta[mac_id]);
5204 curr_tx_rate = rtw_get_current_tx_rate(padapter, macid_ctl->sta[mac_id]);
5205
5206 _RTW_PRINT_SEL(sel , "[ ra_info1:0x%08x ] =>cur_tx_rate= %s,cur_sgi:%d\n", ra_info1, HDATA_RATE(curr_tx_rate), curr_tx_sgi);
5207 _RTW_PRINT_SEL(sel , "[ ra_info1:0x%08x ] => PWRSTS = 0x%02x\n", ra_info1, (ra_info1 >> 8) & 0x07);
5208
5209 cmd = 0x40000400 | mac_id;
5210 rtw_write32(padapter, REG_HMEBOX_DBG_2_8723D, cmd);
5211 rtw_msleep_os(10);
5212 ra_info1 = rtw_read32(padapter, 0x2F0);
5213 ra_info2 = rtw_read32(padapter, 0x2F4);
5214 rate_mask1 = rtw_read32(padapter, 0x2F8);
5215 rate_mask2 = rtw_read32(padapter, 0x2FC);
5216 hight_rate = ra_info2 & 0xFF;
5217 lowest_rate = (ra_info2 >> 8) & 0xFF;
5218 bw_set = (ra_info1 >> 8) & 0xFF;
5219
5220 _RTW_PRINT_SEL(sel , "[ ra_info1:0x%08x ] => VHT_EN=0x%02x, ", ra_info1, (ra_info1 >> 24) & 0xFF);
5221
5222
5223 switch (bw_set) {
5224
5225 case CHANNEL_WIDTH_20:
5226 _RTW_PRINT_SEL(sel , "BW_setting=20M\n");
5227 break;
5228
5229 case CHANNEL_WIDTH_40:
5230 _RTW_PRINT_SEL(sel , "BW_setting=40M\n");
5231 break;
5232
5233 case CHANNEL_WIDTH_80:
5234 _RTW_PRINT_SEL(sel , "BW_setting=80M\n");
5235 break;
5236
5237 case CHANNEL_WIDTH_160:
5238 _RTW_PRINT_SEL(sel , "BW_setting=160M\n");
5239 break;
5240
5241 default:
5242 _RTW_PRINT_SEL(sel , "BW_setting=0x%02x\n", bw_set);
5243 break;
5244
5245 }
5246
5247 _RTW_PRINT_SEL(sel , "[ ra_info1:0x%08x ] =>RSSI=%d, DISRA=0x%02x\n",
5248 ra_info1,
5249 ra_info1 & 0xFF,
5250 (ra_info1 >> 16) & 0xFF);
5251
5252 _RTW_PRINT_SEL(sel , "[ ra_info2:0x%08x ] =>hight_rate=%s, lowest_rate=%s, SGI=0x%02x, RateID=%d\n",
5253 ra_info2,
5254 HDATA_RATE(hight_rate),
5255 HDATA_RATE(lowest_rate),
5256 (ra_info2 >> 16) & 0xFF,
5257 (ra_info2 >> 24) & 0xFF);
5258
5259 _RTW_PRINT_SEL(sel , "rate_mask2=0x%08x, rate_mask1=0x%08x\n", rate_mask2, rate_mask1);
5260
5261 }
5262 }
5263 }
5264
5265 /*
5266 * Description:
5267 * Query setting of specified variable.
5268 */
5269 u8 GetHalDefVar8723D(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
5270 {
5271 PHAL_DATA_TYPE pHalData;
5272 u8 bResult;
5273
5274 pHalData = GET_HAL_DATA(padapter);
5275 bResult = _SUCCESS;
5276
5277 switch (variable) {
5278 case HAL_DEF_MAX_RECVBUF_SZ:
5279 *((u32 *)pval) = MAX_RECVBUF_SZ;
5280 break;
5281 case HAL_DEF_RX_PACKET_OFFSET:
5282 #ifdef CONFIG_TRX_BD_ARCH
5283 *((u32 *)pval) = RX_WIFI_INFO_SIZE + DRVINFO_SZ * 8;
5284 #else
5285 *((u32 *)pval) = RXDESC_SIZE + DRVINFO_SZ * 8;
5286 #endif
5287 break;
5288
5289 case HW_VAR_MAX_RX_AMPDU_FACTOR:
5290 /* Stanley@BB.SD3 suggests 16K can get stable performance */
5291 /* The experiment was done on SDIO interface */
5292 /* coding by Lucas@20130730 */
5293 *(HT_CAP_AMPDU_FACTOR *)pval = MAX_AMPDU_FACTOR_16K;
5294 break;
5295 case HW_VAR_BEST_AMPDU_DENSITY:
5296 *((u32 *)pval) = AMPDU_DENSITY_VALUE_7;
5297 break;
5298 case HAL_DEF_TX_LDPC:
5299 case HAL_DEF_RX_LDPC:
5300 *((u8 *)pval) = _FALSE;
5301 break;
5302 case HAL_DEF_RX_STBC:
5303 *((u8 *)pval) = 1;
5304 break;
5305 case HAL_DEF_EXPLICIT_BEAMFORMER:
5306 case HAL_DEF_EXPLICIT_BEAMFORMEE:
5307 *((u8 *)pval) = _FALSE;
5308 break;
5309
5310 case HW_DEF_RA_INFO_DUMP:
5311 hal_ra_info_dump(padapter, pval);
5312 break;
5313
5314 case HAL_DEF_TX_PAGE_BOUNDARY:
5315 if (!padapter->registrypriv.wifi_spec)
5316 *(u8 *)pval = TX_PAGE_BOUNDARY_8723D;
5317 else
5318 *(u8 *)pval = WMM_NORMAL_TX_PAGE_BOUNDARY_8723D;
5319 break;
5320 case HAL_DEF_TX_PAGE_SIZE:
5321 *((u32 *)pval) = PAGE_SIZE_128;
5322 break;
5323 case HAL_DEF_RX_DMA_SZ_WOW:
5324 *(u32 *)pval = RX_DMA_SIZE_8723D - RESV_FMWF;
5325 break;
5326 case HAL_DEF_RX_DMA_SZ:
5327 *(u32 *)pval = RX_DMA_BOUNDARY_8723D + 1;
5328 break;
5329 case HAL_DEF_RX_PAGE_SIZE:
5330 *((u32 *)pval) = 8;
5331 break;
5332 default:
5333 bResult = GetHalDefVar(padapter, variable, pval);
5334 break;
5335 }
5336
5337 return bResult;
5338 }
5339
5340 #ifdef CONFIG_WOWLAN
5341 void Hal_DetectWoWMode(PADAPTER pAdapter)
5342 {
5343 adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = _TRUE;
5344 RTW_INFO("%s\n", __func__);
5345 }
5346 #endif /* CONFIG_WOWLAN */
5347
5348 void rtl8723d_start_thread(_adapter *padapter)
5349 {
5350 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
5351 #ifndef CONFIG_SDIO_TX_TASKLET
5352 struct xmit_priv *xmitpriv = &padapter->xmitpriv;
5353
5354 if (xmitpriv->SdioXmitThread == NULL) {
5355 RTW_INFO(FUNC_ADPT_FMT " start RTWHALXT\n", FUNC_ADPT_ARG(padapter));
5356 xmitpriv->SdioXmitThread = kthread_run(rtl8723ds_xmit_thread, padapter, "RTWHALXT");
5357 if (IS_ERR(xmitpriv->SdioXmitThread)) {
5358 RTW_ERR("%s: start rtl8723ds_xmit_thread FAIL!!\n", __func__);
5359 xmitpriv->SdioXmitThread = NULL;
5360 }
5361 }
5362 #endif
5363 #endif
5364 }
5365
5366 void rtl8723d_stop_thread(_adapter *padapter)
5367 {
5368 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
5369 #ifndef CONFIG_SDIO_TX_TASKLET
5370 struct xmit_priv *xmitpriv = &padapter->xmitpriv;
5371
5372 /* stop xmit_buf_thread */
5373 if (xmitpriv->SdioXmitThread) {
5374 _rtw_up_sema(&xmitpriv->SdioXmitSema);
5375 #ifdef SDIO_FREE_XMIT_BUF_SEMA
5376 rtw_sdio_free_xmitbuf_sema_up(xmitpriv);
5377 rtw_sdio_free_xmitbuf_sema_down(xmitpriv);
5378 #endif
5379 rtw_thread_stop(xmitpriv->SdioXmitThread);
5380 xmitpriv->SdioXmitThread = NULL;
5381 }
5382 #endif
5383 #endif
5384 }
5385
5386 #if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
5387 void rtl8723ds_init_checkbthang_workqueue(_adapter *adapter)
5388 {
5389 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
5390 adapter->priv_checkbt_wq = alloc_workqueue("sdio_wq", 0, 0);
5391 #else
5392 adapter->priv_checkbt_wq = create_workqueue("sdio_wq");
5393 #endif
5394 INIT_DELAYED_WORK(&adapter->checkbt_work, (void *)check_bt_status_work);
5395 }
5396
5397 void rtl8723ds_free_checkbthang_workqueue(_adapter *adapter)
5398 {
5399 if (adapter->priv_checkbt_wq) {
5400 cancel_delayed_work_sync(&adapter->checkbt_work);
5401 flush_workqueue(adapter->priv_checkbt_wq);
5402 destroy_workqueue(adapter->priv_checkbt_wq);
5403 adapter->priv_checkbt_wq = NULL;
5404 }
5405 }
5406
5407 void rtl8723ds_cancle_checkbthang_workqueue(_adapter *adapter)
5408 {
5409 if (adapter->priv_checkbt_wq)
5410 cancel_delayed_work_sync(&adapter->checkbt_work);
5411 }
5412
5413 void rtl8723ds_hal_check_bt_hang(_adapter *adapter)
5414 {
5415 if (adapter->priv_checkbt_wq)
5416 queue_delayed_work(adapter->priv_checkbt_wq, &(adapter->checkbt_work), 0);
5417 }
5418 #endif
5419
5420 void rtl8723d_set_hal_ops(struct hal_ops *pHalFunc)
5421 {
5422 pHalFunc->dm_init = &rtl8723d_init_dm_priv;
5423 pHalFunc->dm_deinit = &rtl8723d_deinit_dm_priv;
5424 pHalFunc->read_chip_version = read_chip_version_8723d;
5425 pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8723D;
5426 pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8723D;
5427 pHalFunc->set_tx_power_index_handler = PHY_SetTxPowerIndex_8723D;
5428 pHalFunc->get_tx_power_index_handler = hal_com_get_txpwr_idx;
5429 pHalFunc->hal_dm_watchdog = &rtl8723d_HalDmWatchDog;
5430
5431 pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8723d_SetBeaconRelatedRegisters;
5432 pHalFunc->run_thread = &rtl8723d_start_thread;
5433 pHalFunc->cancel_thread = &rtl8723d_stop_thread;
5434 pHalFunc->read_bbreg = &PHY_QueryBBReg_8723D;
5435 pHalFunc->write_bbreg = &PHY_SetBBReg_8723D;
5436 pHalFunc->read_rfreg = &PHY_QueryRFReg_8723D;
5437 pHalFunc->write_rfreg = &PHY_SetRFReg_8723D;
5438 pHalFunc->read_wmmedca_reg = &rtl8723d_read_wmmedca_reg;
5439
5440 /* Efuse related function */
5441 pHalFunc->BTEfusePowerSwitch = &Hal_BT_EfusePowerSwitch;
5442 pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch;
5443 pHalFunc->ReadEFuse = &Hal_ReadEFuse;
5444 pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition;
5445 pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize;
5446 pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead;
5447 pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite;
5448 pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite;
5449 pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT;
5450
5451 #ifdef DBG_CONFIG_ERROR_DETECT
5452 pHalFunc->sreset_init_value = &sreset_init_value;
5453 pHalFunc->sreset_reset_value = &sreset_reset_value;
5454 pHalFunc->silentreset = &sreset_reset;
5455 pHalFunc->sreset_xmit_status_check = &rtl8723d_sreset_xmit_status_check;
5456 pHalFunc->sreset_linked_status_check = &rtl8723d_sreset_linked_status_check;
5457 pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status;
5458 pHalFunc->sreset_inprogress = &sreset_inprogress;
5459 #endif
5460 pHalFunc->GetHalODMVarHandler = GetHalODMVar;
5461 pHalFunc->SetHalODMVarHandler = SetHalODMVar;
5462
5463 #ifdef CONFIG_XMIT_THREAD_MODE
5464 pHalFunc->xmit_thread_handler = &hal_xmit_handler;
5465 #endif
5466 pHalFunc->hal_notch_filter = &hal_notch_filter_8723d;
5467 pHalFunc->c2h_handler = c2h_handler_8723d;
5468 pHalFunc->fill_h2c_cmd = &FillH2CCmd8723D;
5469 pHalFunc->fill_fake_txdesc = &rtl8723d_fill_fake_txdesc;
5470 pHalFunc->fw_dl = &rtl8723d_FirmwareDownload;
5471 pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8723D;
5472 }
5473
5474