1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 *
19 ******************************************************************************/
20 #define _HAL_INIT_C_
21
22 #include <rtl8723b_hal.h>
23 #include "rtw_bt_mp.h"
24 #include "hal_com_h2c.h"
25 #include <hal_com.h>
26
27 static VOID
_FWDownloadEnable(IN PADAPTER padapter,IN BOOLEAN enable)28 _FWDownloadEnable(
29 IN PADAPTER padapter,
30 IN BOOLEAN enable
31 )
32 {
33 u8 tmp, count = 0;
34
35 if(enable)
36 {
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 DBG_871X("%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 }
58 else
59 {
60 // MCU firmware download disable.
61 tmp = rtw_read8(padapter, REG_MCUFWDL);
62 rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
63 }
64 }
65
66 static int
_BlockWrite(IN PADAPTER padapter,IN PVOID buffer,IN u32 buffSize)67 _BlockWrite(
68 IN PADAPTER padapter,
69 IN PVOID buffer,
70 IN u32 buffSize
71 )
72 {
73 int ret = _SUCCESS;
74
75 u32 blockSize_p1 = 4; // (Default) Phase #1 : PCI muse use 4-byte write to download FW
76 u32 blockSize_p2 = 8; // Phase #2 : Use 8-byte, if Phase#1 use big size to write FW.
77 u32 blockSize_p3 = 1; // Phase #3 : Use 1-byte, the remnant of FW image.
78 u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
79 u32 remainSize_p1 = 0, remainSize_p2 = 0;
80 u8 *bufferPtr = (u8*)buffer;
81 u32 i=0, offset=0;
82 #ifdef CONFIG_PCI_HCI
83 u8 remainFW[4] = {0, 0, 0, 0};
84 u8 *p = NULL;
85 #endif
86
87 #ifdef CONFIG_USB_HCI
88 blockSize_p1 = 254;
89 #endif
90
91 // printk("====>%s %d\n", __func__, __LINE__);
92
93 //3 Phase #1
94 blockCount_p1 = buffSize / blockSize_p1;
95 remainSize_p1 = buffSize % blockSize_p1;
96
97 if (blockCount_p1) {
98 RT_TRACE(_module_hal_init_c_, _drv_notice_,
99 ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) blockCount_p1(%d) remainSize_p1(%d)\n",
100 buffSize, blockSize_p1, blockCount_p1, remainSize_p1));
101 }
102
103 for (i = 0; i < blockCount_p1; i++)
104 {
105 #ifdef CONFIG_USB_HCI
106 ret = rtw_writeN(padapter, (FW_8723B_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
107 #else
108 ret = rtw_write32(padapter, (FW_8723B_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32*)(bufferPtr + i * blockSize_p1))));
109 #endif
110 if(ret == _FAIL) {
111 printk("====>%s %d i:%d\n", __func__, __LINE__, i);
112 goto exit;
113 }
114 }
115
116 #ifdef CONFIG_PCI_HCI
117 p = (u8*)((u32*)(bufferPtr + blockCount_p1 * blockSize_p1));
118 if (remainSize_p1) {
119 switch (remainSize_p1) {
120 case 0:
121 break;
122 case 3:
123 remainFW[2]=*(p+2);
124 case 2:
125 remainFW[1]=*(p+1);
126 case 1:
127 remainFW[0]=*(p);
128 ret = rtw_write32(padapter, (FW_8723B_START_ADDRESS + blockCount_p1 * blockSize_p1),
129 le32_to_cpu(*(u32*)remainFW));
130 }
131 return ret;
132 }
133 #endif
134
135 //3 Phase #2
136 if (remainSize_p1)
137 {
138 offset = blockCount_p1 * blockSize_p1;
139
140 blockCount_p2 = remainSize_p1/blockSize_p2;
141 remainSize_p2 = remainSize_p1%blockSize_p2;
142
143 if (blockCount_p2) {
144 RT_TRACE(_module_hal_init_c_, _drv_notice_,
145 ("_BlockWrite: [P2] buffSize_p2(%d) blockSize_p2(%d) blockCount_p2(%d) remainSize_p2(%d)\n",
146 (buffSize-offset), blockSize_p2 ,blockCount_p2, remainSize_p2));
147 }
148
149 #ifdef CONFIG_USB_HCI
150 for (i = 0; i < blockCount_p2; i++) {
151 ret = rtw_writeN(padapter, (FW_8723B_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
152
153 if(ret == _FAIL)
154 goto exit;
155 }
156 #endif
157 }
158
159 //3 Phase #3
160 if (remainSize_p2)
161 {
162 offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
163
164 blockCount_p3 = remainSize_p2 / blockSize_p3;
165
166 RT_TRACE(_module_hal_init_c_, _drv_notice_,
167 ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) blockCount_p3(%d)\n",
168 (buffSize-offset), blockSize_p3, blockCount_p3));
169
170 for(i = 0 ; i < blockCount_p3 ; i++){
171 ret = rtw_write8(padapter, (FW_8723B_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
172
173 if(ret == _FAIL) {
174 printk("====>%s %d i:%d\n", __func__, __LINE__, i);
175 goto exit;
176 }
177 }
178 }
179 exit:
180 return ret;
181 }
182
183 static int
_PageWrite(IN PADAPTER padapter,IN u32 page,IN PVOID buffer,IN u32 size)184 _PageWrite(
185 IN PADAPTER padapter,
186 IN u32 page,
187 IN PVOID buffer,
188 IN u32 size
189 )
190 {
191 u8 value8;
192 u8 u8Page = (u8) (page & 0x07) ;
193
194 value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page ;
195 rtw_write8(padapter, REG_MCUFWDL+2,value8);
196
197 return _BlockWrite(padapter,buffer,size);
198 }
199
200 static VOID
_FillDummy(u8 * pFwBuf,u32 * pFwLen)201 _FillDummy(
202 u8* pFwBuf,
203 u32* pFwLen
204 )
205 {
206 u32 FwLen = *pFwLen;
207 u8 remain = (u8)(FwLen%4);
208 remain = (remain==0)?0:(4-remain);
209
210 while(remain>0)
211 {
212 pFwBuf[FwLen] = 0;
213 FwLen++;
214 remain--;
215 }
216
217 *pFwLen = FwLen;
218 }
219
220 static int
_WriteFW(IN PADAPTER padapter,IN PVOID buffer,IN u32 size)221 _WriteFW(
222 IN PADAPTER padapter,
223 IN PVOID buffer,
224 IN u32 size
225 )
226 {
227 // Since we need dynamic decide method of dwonload fw, so we call this function to get chip version.
228 int ret = _SUCCESS;
229 u32 pageNums,remainSize ;
230 u32 page, offset;
231 u8 *bufferPtr = (u8*)buffer;
232
233 #ifdef CONFIG_PCI_HCI
234 // 20100120 Joseph: Add for 88CE normal chip.
235 // Fill in zero to make firmware image to dword alignment.
236 _FillDummy(bufferPtr, &size);
237 #endif
238
239 pageNums = size / MAX_DLFW_PAGE_SIZE ;
240 //RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4 \n"));
241 remainSize = size % MAX_DLFW_PAGE_SIZE;
242
243 for (page = 0; page < pageNums; page++) {
244 offset = page * MAX_DLFW_PAGE_SIZE;
245 ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_DLFW_PAGE_SIZE);
246
247 if(ret == _FAIL) {
248 printk("====>%s %d\n", __func__, __LINE__);
249 goto exit;
250 }
251 }
252 if (remainSize) {
253 offset = pageNums * MAX_DLFW_PAGE_SIZE;
254 page = pageNums;
255 ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize);
256
257 if(ret == _FAIL) {
258 printk("====>%s %d\n", __func__, __LINE__);
259 goto exit;
260 }
261 }
262 RT_TRACE(_module_hal_init_c_, _drv_info_, ("_WriteFW Done- for Normal chip.\n"));
263
264 exit:
265 return ret;
266 }
267
_8051Reset8723(PADAPTER padapter)268 void _8051Reset8723(PADAPTER padapter)
269 {
270 u8 cpu_rst;
271 u8 io_rst;
272
273 io_rst = rtw_read8(padapter, REG_RSV_CTRL);
274 rtw_write8(padapter, REG_RSV_CTRL, io_rst&(~BIT1));
275 // Reset 8051(WLMCU) IO wrapper
276 // 0x1c[8] = 0
277 // Suggested by Isaac@SD1 and Gimmy@SD1, coding by Lucas@20130624
278 io_rst = rtw_read8(padapter, REG_RSV_CTRL+1);
279 io_rst &= ~BIT(0);
280 rtw_write8(padapter, REG_RSV_CTRL+1, io_rst);
281
282 cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
283 cpu_rst &= ~BIT(2);
284 rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst);
285
286 io_rst = rtw_read8(padapter, REG_RSV_CTRL);
287 rtw_write8(padapter, REG_RSV_CTRL, io_rst&(~BIT1));
288 // Enable 8051 IO wrapper
289 // 0x1c[8] = 1
290 io_rst = rtw_read8(padapter, REG_RSV_CTRL+1);
291 io_rst |= BIT(0);
292 rtw_write8(padapter, REG_RSV_CTRL+1, io_rst);
293
294 cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
295 cpu_rst |= BIT(2);
296 rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst);
297
298 DBG_8192C("%s: Finish\n", __FUNCTION__);
299 }
300
polling_fwdl_chksum(_adapter * adapter,u32 min_cnt,u32 timeout_ms)301 static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
302 {
303 s32 ret = _FAIL;
304 u32 value32;
305 u32 start = rtw_get_current_time();
306 u32 cnt = 0;
307
308 /* polling CheckSum report */
309 do {
310 cnt++;
311 value32 = rtw_read32(adapter, REG_MCUFWDL);
312 if (value32 & FWDL_ChkSum_rpt || RTW_CANNOT_IO(adapter))
313 break;
314 rtw_yield_os();
315 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
316
317 if (!(value32 & FWDL_ChkSum_rpt)) {
318 goto exit;
319 }
320
321 if (rtw_fwdl_test_trigger_chksum_fail())
322 goto exit;
323
324 ret = _SUCCESS;
325
326 exit:
327 DBG_871X("%s: Checksum report %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
328 , (ret==_SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), value32);
329
330 return ret;
331 }
332
_FWFreeToGo(_adapter * adapter,u32 min_cnt,u32 timeout_ms)333 static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
334 {
335 s32 ret = _FAIL;
336 u32 value32;
337 u32 start = rtw_get_current_time();
338 u32 cnt = 0;
339
340 value32 = rtw_read32(adapter, REG_MCUFWDL);
341 value32 |= MCUFWDL_RDY;
342 value32 &= ~WINTINI_RDY;
343 rtw_write32(adapter, REG_MCUFWDL, value32);
344
345 _8051Reset8723(adapter);
346
347 /* polling for FW ready */
348 do {
349 cnt++;
350 value32 = rtw_read32(adapter, REG_MCUFWDL);
351 if (value32 & WINTINI_RDY || RTW_CANNOT_IO(adapter))
352 break;
353 rtw_yield_os();
354 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
355
356 if (!(value32 & WINTINI_RDY)) {
357 goto exit;
358 }
359
360 if (rtw_fwdl_test_trigger_wintint_rdy_fail())
361 goto exit;
362
363 ret = _SUCCESS;
364
365 exit:
366 DBG_871X("%s: Polling FW ready %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
367 , (ret==_SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), value32);
368
369 return ret;
370 }
371
372 #define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
373
rtl8723b_FirmwareSelfReset(PADAPTER padapter)374 void rtl8723b_FirmwareSelfReset(PADAPTER padapter)
375 {
376 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
377 u8 u1bTmp;
378 u8 Delay = 100;
379
380 if (!(IS_FW_81xxC(padapter) &&
381 ((pHalData->FirmwareVersion < 0x21) ||
382 (pHalData->FirmwareVersion == 0x21 &&
383 pHalData->FirmwareSubVersion < 0x01)))) // after 88C Fw v33.1
384 {
385 //0x1cf=0x20. Inform 8051 to reset. 2009.12.25. tynli_test
386 rtw_write8(padapter, REG_HMETFR+3, 0x20);
387
388 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
389 while (u1bTmp & BIT2)
390 {
391 Delay--;
392 if(Delay == 0)
393 break;
394 rtw_udelay_os(50);
395 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
396 }
397 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("-%s: 8051 reset success (%d)\n", __FUNCTION__, Delay));
398
399 if (Delay == 0)
400 {
401 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("%s: Force 8051 reset!!!\n", __FUNCTION__));
402 //force firmware reset
403 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
404 rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
405 }
406 }
407 }
408
409 #ifdef CONFIG_FILE_FWIMG
410 extern char *rtw_fw_file_path;
411 extern char *rtw_fw_wow_file_path;
412 #ifdef CONFIG_MP_INCLUDED
413 extern char *rtw_fw_mp_bt_file_path;
414 #endif // CONFIG_MP_INCLUDED
415 u8 FwBuffer[FW_8723B_SIZE];
416 #endif // CONFIG_FILE_FWIMG
417
418 #ifdef CONFIG_MP_INCLUDED
_WriteBTFWtoTxPktBuf8723B(IN PADAPTER Adapter,IN PVOID buffer,IN u4Byte FwBufLen,IN u1Byte times)419 int _WriteBTFWtoTxPktBuf8723B(
420 IN PADAPTER Adapter,
421 IN PVOID buffer,
422 IN u4Byte FwBufLen,
423 IN u1Byte times
424 )
425 {
426 int rtStatus = _SUCCESS;
427 //u4Byte value32;
428 //u1Byte numHQ, numLQ, numPubQ;//, txpktbuf_bndy;
429 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
430 //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
431 u1Byte BcnValidReg;
432 u1Byte count=0, DLBcnCount=0;
433 pu1Byte FwbufferPtr = (pu1Byte)buffer;
434 //PRT_TCB pTcb, ptempTcb;
435 //PRT_TX_LOCAL_BUFFER pBuf;
436 BOOLEAN bRecover=_FALSE;
437 pu1Byte ReservedPagePacket = NULL;
438 pu1Byte pGenBufReservedPagePacket = NULL;
439 u4Byte TotalPktLen,txpktbuf_bndy;
440 //u1Byte tmpReg422;
441 //u1Byte u1bTmp;
442 u8 *pframe;
443 struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv);
444 struct xmit_frame *pmgntframe;
445 struct pkt_attrib *pattrib;
446 u8 txdesc_offset = TXDESC_OFFSET;
447 u8 val8;
448 #if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
449 u8 u1bTmp;
450 #endif
451
452 #if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
453 TotalPktLen = FwBufLen;
454 #else
455 TotalPktLen = FwBufLen+pHalData->HWDescHeadLength;
456 #endif
457
458 if((TotalPktLen+TXDESC_OFFSET) > MAX_CMDBUF_SZ)
459 {
460 DBG_871X(" WARNING %s => Total packet len = %d > MAX_CMDBUF_SZ:%d \n"
461 ,__FUNCTION__,(TotalPktLen+TXDESC_OFFSET),MAX_CMDBUF_SZ);
462 return _FAIL;
463 }
464
465 pGenBufReservedPagePacket = rtw_zmalloc(TotalPktLen);//GetGenTempBuffer (Adapter, TotalPktLen);
466 if (!pGenBufReservedPagePacket)
467 return _FAIL;
468
469 ReservedPagePacket = (u1Byte *)pGenBufReservedPagePacket;
470
471 _rtw_memset(ReservedPagePacket, 0, TotalPktLen);
472
473 #if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
474 _rtw_memcpy(ReservedPagePacket, FwbufferPtr, FwBufLen);
475
476 #else
477 PlatformMoveMemory(ReservedPagePacket+Adapter->HWDescHeadLength , FwbufferPtr, FwBufLen);
478 #endif
479
480 //---------------------------------------------------------
481 // 1. Pause BCN
482 //---------------------------------------------------------
483 //Set REG_CR bit 8. DMA beacon by SW.
484 #if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
485 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR+1);
486 PlatformEFIOWrite1Byte(Adapter, REG_CR+1, (u1bTmp|BIT0));
487 #else
488 // Remove for temparaily because of the code on v2002 is not sync to MERGE_TMEP for USB/SDIO.
489 // De not remove this part on MERGE_TEMP. by tynli.
490 //pHalData->RegCR_1 |= (BIT0);
491 //PlatformEFIOWrite1Byte(Adapter, REG_CR+1, pHalData->RegCR_1);
492 #endif
493
494 // Disable Hw protection for a time which revserd for Hw sending beacon.
495 // Fix download reserved page packet fail that access collision with the protection time.
496 // 2010.05.11. Added by tynli.
497 val8 = rtw_read8(Adapter, REG_BCN_CTRL);
498 val8 &= ~EN_BCN_FUNCTION;
499 val8 |= DIS_TSF_UDT;
500 rtw_write8(Adapter, REG_BCN_CTRL, val8);
501
502 #if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
503 tmpReg422 = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL+2);
504 if( tmpReg422&BIT6)
505 bRecover = TRUE;
506 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, tmpReg422&(~BIT6));
507 #else
508 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
509 if(pHalData->RegFwHwTxQCtrl & BIT(6))
510 bRecover=_TRUE;
511 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl&(~BIT(6))));
512 pHalData->RegFwHwTxQCtrl &= (~ BIT(6));
513 #endif
514
515 //---------------------------------------------------------
516 // 2. Adjust LLT table to an even boundary.
517 //---------------------------------------------------------
518 #if 0//(DEV_BUS_TYPE == RT_SDIO_INTERFACE)
519 txpktbuf_bndy = 10; // rsvd page start address should be an even value.
520 rtStatus = InitLLTTable8723BS(Adapter, txpktbuf_bndy);
521 if(RT_STATUS_SUCCESS != rtStatus){
522 DBG_8192C("_CheckWLANFwPatchBTFwReady_8723B(): Failed to init LLT!\n");
523 return RT_STATUS_FAILURE;
524 }
525
526 // Init Tx boundary.
527 PlatformEFIOWrite1Byte(Adapter, REG_DWBCN0_CTRL_8723B+1, (u1Byte)txpktbuf_bndy);
528 #endif
529
530
531 //---------------------------------------------------------
532 // 3. Write Fw to Tx packet buffer by reseverd page.
533 //---------------------------------------------------------
534 do
535 {
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 RT_TRACE(_module_mp_, _drv_info_,("0x209:%x\n",
543 PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1)));//209 < 0x40
544
545 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+1, (0x90-0x20*(times-1)));
546 DBG_871X("0x209:0x%x\n", PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1));
547 RT_TRACE(_module_mp_, _drv_info_,("0x209:%x\n",
548 PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1)));
549
550 #if 0
551 // Acquice TX spin lock before GetFwBuf and send the packet to prevent system deadlock.
552 // Advertised by Roger. Added by tynli. 2010.02.22.
553 PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
554 if(MgntGetFWBuffer(Adapter, &pTcb, &pBuf))
555 {
556 PlatformMoveMemory(pBuf->Buffer.VirtualAddress, ReservedPagePacket, TotalPktLen);
557 CmdSendPacket(Adapter, pTcb, pBuf, TotalPktLen, DESC_PACKET_TYPE_NORMAL, FALSE);
558 }
559 else
560 dbgdump("SetFwRsvdPagePkt(): MgntGetFWBuffer FAIL!!!!!!!!.\n");
561 PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
562 #else
563 /*---------------------------------------------------------
564 tx reserved_page_packet
565 ----------------------------------------------------------*/
566 if ((pmgntframe = rtw_alloc_cmdxmitframe(pxmitpriv)) == NULL) {
567 rtStatus = _FAIL;
568 goto exit;
569 }
570 //update attribute
571 pattrib = &pmgntframe->attrib;
572 update_mgntframe_attrib(Adapter, pattrib);
573
574 pattrib->qsel = QSLT_BEACON;
575 pattrib->pktlen = pattrib->last_txcmdsz = FwBufLen ;
576
577 //_rtw_memset(pmgntframe->buf_addr, 0, TotalPktLen+txdesc_size);
578 //pmgntframe->buf_addr = ReservedPagePacket ;
579
580 _rtw_memcpy( (u8*) (pmgntframe->buf_addr + txdesc_offset), ReservedPagePacket, FwBufLen);
581 DBG_871X("[%d]===>TotalPktLen + TXDESC_OFFSET TotalPacketLen:%d \n", DLBcnCount, (FwBufLen + txdesc_offset));
582
583 #ifdef CONFIG_PCI_HCI
584 dump_mgntframe(Adapter, pmgntframe);
585 #else
586 dump_mgntframe_and_wait(Adapter, pmgntframe, 100);
587 #endif
588
589 #endif
590 #if 1
591 // check rsvd page download OK.
592 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
593 while(!(BcnValidReg & BIT(0)) && count <200)
594 {
595 count++;
596 //PlatformSleepUs(10);
597 rtw_msleep_os(1);
598 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
599 RT_TRACE(_module_mp_, _drv_notice_,("Poll 0x20A = %x\n", BcnValidReg));
600 }
601 DLBcnCount++;
602 //DBG_871X("##0x208:%08x,0x210=%08x\n",PlatformEFIORead4Byte(Adapter, REG_TDECTRL),PlatformEFIORead4Byte(Adapter, 0x210));
603
604 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+2,BcnValidReg);
605
606 }while((!(BcnValidReg&BIT(0))) && DLBcnCount<5);
607
608
609 #endif
610 if(DLBcnCount >=5){
611 DBG_871X(" check rsvd page download OK DLBcnCount =%d \n",DLBcnCount);
612 rtStatus = _FAIL;
613 goto exit;
614 }
615
616 if(!(BcnValidReg&BIT(0)))
617 {
618 DBG_871X("_WriteFWtoTxPktBuf(): 1 Download RSVD page failed!\n");
619 rtStatus = _FAIL;
620 goto exit;
621 }
622
623 //---------------------------------------------------------
624 // 4. Set Tx boundary to the initial value
625 //---------------------------------------------------------
626
627
628 //---------------------------------------------------------
629 // 5. Reset beacon setting to the initial value.
630 // After _CheckWLANFwPatchBTFwReady().
631 //---------------------------------------------------------
632
633 exit:
634
635 if(pGenBufReservedPagePacket)
636 {
637 DBG_871X("_WriteBTFWtoTxPktBuf8723B => rtw_mfree pGenBufReservedPagePacket!\n");
638 rtw_mfree((u8*)pGenBufReservedPagePacket, TotalPktLen);
639 }
640 return rtStatus;
641 }
642
643
644
645 //
646 // Description: Determine the contents of H2C BT_FW_PATCH Command sent to FW.
647 // 2011.10.20 by tynli
648 //
649 void
SetFwBTFwPatchCmd(IN PADAPTER Adapter,IN u16 FwSize)650 SetFwBTFwPatchCmd(
651 IN PADAPTER Adapter,
652 IN u16 FwSize
653 )
654 {
655 u8 u1BTFwPatchParm[H2C_BT_FW_PATCH_LEN]={0};
656 u8 addr0 = 0;
657 u8 addr1 = 0xa0;
658 u8 addr2 = 0x10;
659 u8 addr3 = 0x80;
660
661 RT_TRACE(_module_mp_, _drv_notice_,("SetFwBTFwPatchCmd(): FwSize = %d\n", FwSize));
662
663 SET_8723B_H2CCMD_BT_FW_PATCH_SIZE(u1BTFwPatchParm, FwSize);
664 SET_8723B_H2CCMD_BT_FW_PATCH_ADDR0(u1BTFwPatchParm, addr0);
665 SET_8723B_H2CCMD_BT_FW_PATCH_ADDR1(u1BTFwPatchParm, addr1);
666 SET_8723B_H2CCMD_BT_FW_PATCH_ADDR2(u1BTFwPatchParm, addr2);
667 SET_8723B_H2CCMD_BT_FW_PATCH_ADDR3(u1BTFwPatchParm, addr3);
668
669 FillH2CCmd8723B(Adapter, H2C_8723B_BT_FW_PATCH, H2C_BT_FW_PATCH_LEN, u1BTFwPatchParm);
670
671 RT_TRACE(_module_mp_, _drv_notice_,("<----SetFwBTFwPatchCmd(): FwSize = %d \n", FwSize));
672 }
673
674 void
SetFwBTPwrCmd(IN PADAPTER Adapter,IN u1Byte PwrIdx)675 SetFwBTPwrCmd(
676 IN PADAPTER Adapter,
677 IN u1Byte PwrIdx
678 )
679 {
680 u1Byte u1BTPwrIdxParm[H2C_FORCE_BT_TXPWR_LEN]={0};
681
682 RT_TRACE(_module_mp_, _drv_info_,("SetFwBTPwrCmd(): idx = %d\n", PwrIdx));
683 SET_8723B_H2CCMD_BT_PWR_IDX(u1BTPwrIdxParm, PwrIdx);
684
685 RT_TRACE(_module_mp_, _drv_info_,("SetFwBTPwrCmd(): %x %x %x\n",
686 u1BTPwrIdxParm[0],u1BTPwrIdxParm[1],u1BTPwrIdxParm[2]));
687
688 FillH2CCmd8723B(Adapter, H2C_8723B_FORCE_BT_TXPWR, H2C_FORCE_BT_TXPWR_LEN, u1BTPwrIdxParm);
689 }
690
691 //
692 // Description: WLAN Fw will write BT Fw to BT XRAM and signal driver.
693 //
694 // 2011.10.20. by tynli.
695 //
696 int
_CheckWLANFwPatchBTFwReady(IN PADAPTER Adapter)697 _CheckWLANFwPatchBTFwReady(
698 IN PADAPTER Adapter
699 )
700 {
701 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
702 u4Byte count=0;
703 u1Byte u1bTmp;
704 int ret = _FAIL;
705
706 //---------------------------------------------------------
707 // Check if BT FW patch procedure is ready.
708 //---------------------------------------------------------
709 do{
710 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_HMEBOX_DBG_0_8723B);
711 if((u1bTmp&BIT6) || (u1bTmp&BIT7))
712 {
713 ret = _SUCCESS;
714 break;
715 }
716
717 count++;
718 RT_TRACE(_module_mp_, _drv_info_,("0x88=%x, wait for 50 ms (%d) times.\n",
719 u1bTmp, count));
720 rtw_msleep_os(50); // 50ms
721 }while(!((u1bTmp&BIT6) || (u1bTmp&BIT7)) && count < 50);
722
723 RT_TRACE(_module_mp_, _drv_notice_,("_CheckWLANFwPatchBTFwReady():"
724 " Polling ready bit 0x88[7] for %d times.\n", count));
725
726 if(count >= 50)
727 {
728 RT_TRACE(_module_mp_, _drv_notice_,("_CheckWLANFwPatchBTFwReady():"
729 " Polling ready bit 0x88[7] FAIL!!\n"));
730 }
731
732 //---------------------------------------------------------
733 // Reset beacon setting to the initial value.
734 //---------------------------------------------------------
735 #if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
736 if(LLT_table_init(Adapter, FALSE, 0) == RT_STATUS_FAILURE)
737 {
738 dbgdump("Init self define for BT Fw patch LLT table fail.\n");
739 //return RT_STATUS_FAILURE;
740 }
741 #endif
742 u1bTmp = rtw_read8(Adapter, REG_BCN_CTRL);
743 u1bTmp |= EN_BCN_FUNCTION;
744 u1bTmp &= ~DIS_TSF_UDT;
745 rtw_write8(Adapter, REG_BCN_CTRL, u1bTmp);
746
747 // To make sure that if there exists an adapter which would like to send beacon.
748 // If exists, the origianl value of 0x422[6] will be 1, we should check this to
749 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
750 // the beacon cannot be sent by HW.
751 // 2010.06.23. Added by tynli.
752 #if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
753 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL+2);
754 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (u1bTmp|BIT6));
755 #else
756 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl|BIT(6)));
757 pHalData->RegFwHwTxQCtrl |= BIT(6);
758 #endif
759
760 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.
761 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR_8723B+1);
762 PlatformEFIOWrite1Byte(Adapter, REG_CR_8723B+1, (u1bTmp&(~BIT0)));
763
764 return ret;
765 }
766
ReservedPage_Compare(PADAPTER Adapter,PRT_MP_FIRMWARE pFirmware,u32 BTPatchSize)767 int ReservedPage_Compare(PADAPTER Adapter,PRT_MP_FIRMWARE pFirmware,u32 BTPatchSize)
768 {
769 u8 temp,ret,lastBTsz;
770 u32 u1bTmp=0,address_start=0,count=0,i=0;
771 u8 *myBTFwBuffer = NULL;
772
773 myBTFwBuffer = rtw_zmalloc(BTPatchSize);
774 if (myBTFwBuffer == NULL)
775 {
776 DBG_871X("%s can't be executed due to the failed malloc.\n", __FUNCTION__);
777 Adapter->mppriv.bTxBufCkFail=_TRUE;
778 return _FALSE;
779 }
780
781 temp=rtw_read8(Adapter,0x209);
782
783 address_start=(temp*128)/8;
784
785 rtw_write32(Adapter,0x140,0x00000000);
786 rtw_write32(Adapter,0x144,0x00000000);
787 rtw_write32(Adapter,0x148,0x00000000);
788
789 rtw_write8(Adapter,0x106,0x69);
790
791 for(i=0;i<(BTPatchSize/8);i++)
792 {
793 rtw_write32(Adapter,0x140,address_start+5+i) ;
794
795 //polling until reg 0x140[23]=1;
796 do{
797 u1bTmp = rtw_read32(Adapter, 0x140);
798 if(u1bTmp&BIT(23))
799 {
800 ret = _SUCCESS;
801 break;
802 }
803 count++;
804 DBG_871X("0x140=%x, wait for 10 ms (%d) times.\n",u1bTmp, count);
805 rtw_msleep_os(10); // 10ms
806 }while(!(u1bTmp&BIT(23)) && count < 50);
807
808 myBTFwBuffer[i*8+0]=rtw_read8(Adapter, 0x144);
809 myBTFwBuffer[i*8+1]=rtw_read8(Adapter, 0x145);
810 myBTFwBuffer[i*8+2]=rtw_read8(Adapter, 0x146);
811 myBTFwBuffer[i*8+3]=rtw_read8(Adapter, 0x147);
812 myBTFwBuffer[i*8+4]=rtw_read8(Adapter, 0x148);
813 myBTFwBuffer[i*8+5]=rtw_read8(Adapter, 0x149);
814 myBTFwBuffer[i*8+6]=rtw_read8(Adapter, 0x14a);
815 myBTFwBuffer[i*8+7]=rtw_read8(Adapter, 0x14b);
816 }
817
818 rtw_write32(Adapter,0x140,address_start+5+BTPatchSize/8) ;
819
820 lastBTsz=BTPatchSize%8;
821
822 //polling until reg 0x140[23]=1;
823 u1bTmp=0;
824 count=0;
825 do{
826 u1bTmp = rtw_read32(Adapter, 0x140);
827 if(u1bTmp&BIT(23))
828 {
829 ret = _SUCCESS;
830 break;
831 }
832 count++;
833 DBG_871X("0x140=%x, wait for 10 ms (%d) times.\n",u1bTmp, count);
834 rtw_msleep_os(10); // 10ms
835 }while(!(u1bTmp&BIT(23)) && count < 50);
836
837 for(i=0;i<lastBTsz;i++)
838 {
839 myBTFwBuffer[(BTPatchSize/8)*8+i] = rtw_read8(Adapter, (0x144+i));
840
841 }
842
843 for(i=0;i<BTPatchSize;i++)
844 {
845 if(myBTFwBuffer[i]!= pFirmware->szFwBuffer[i])
846 {
847 DBG_871X(" In direct myBTFwBuffer[%d]=%x , pFirmware->szFwBuffer=%x\n",i, myBTFwBuffer[i],pFirmware->szFwBuffer[i]);
848 Adapter->mppriv.bTxBufCkFail=_TRUE;
849 break;
850 }
851 }
852
853 if (myBTFwBuffer != NULL)
854 {
855 rtw_mfree(myBTFwBuffer, BTPatchSize);
856 }
857
858 return _TRUE;
859 }
860
861 /* As the size of bt firmware is more than 16k which is too big for some platforms, we divide it
862 * into four parts to transfer. The last parameter of _WriteBTFWtoTxPktBuf8723B is used to indicate
863 * the location of every part. We call the first 4096 byte of bt firmware as part 1, the second 4096
864 * part as part 2, the third 4096 part as part 3, the remain as part 4. First we transform the part
865 * 4 and set the register 0x209 to 0x90, then the 32 bytes description are added to the head of part
866 * 4, and those bytes are putted at the location 0x90. Second we transform the part 3 and set the
867 * register 0x209 to 0x70. The 32 bytes description and part 3(4196 bytes) are putted at the location
868 * 0x70. It can contain 4196 bytes between 0x70 and 0x90. So the last 32 bytes os part 3 will cover the
869 * 32 bytes description of part4. Using this method, we can put the whole bt firmware to 0x30 and only
870 * has 32 bytes descrption at the head of part 1.
871 */
FirmwareDownloadBT(PADAPTER padapter,PRT_MP_FIRMWARE pFirmware)872 s32 FirmwareDownloadBT(PADAPTER padapter, PRT_MP_FIRMWARE pFirmware)
873 {
874 s32 rtStatus;
875 u8 *pBTFirmwareBuf;
876 u32 BTFirmwareLen;
877 u8 download_time;
878 s8 i;
879
880
881 rtStatus = _SUCCESS;
882 pBTFirmwareBuf = NULL;
883 BTFirmwareLen = 0;
884
885 //
886 // Patch BT Fw. Download BT RAM code to Tx packet buffer.
887 //
888 if (padapter->bBTFWReady) {
889 DBG_8192C("%s: BT Firmware is ready!!\n", __FUNCTION__);
890 return _FAIL;
891 }
892
893 #ifdef CONFIG_FILE_FWIMG
894 if (rtw_is_file_readable(rtw_fw_mp_bt_file_path) == _TRUE)
895 {
896 DBG_8192C("%s: accquire MP BT FW from file:%s\n", __FUNCTION__, rtw_fw_mp_bt_file_path);
897
898 rtStatus = rtw_retrieve_from_file(rtw_fw_mp_bt_file_path, FwBuffer, FW_8723B_SIZE);
899 BTFirmwareLen = rtStatus>=0?rtStatus:0;
900 pBTFirmwareBuf = FwBuffer;
901 }
902 else
903 #endif // CONFIG_FILE_FWIMG
904 {
905 #ifdef CONFIG_EMBEDDED_FWIMG
906 DBG_8192C("%s: Download MP BT FW from header\n", __FUNCTION__);
907
908 pBTFirmwareBuf = (u8*)Rtl8723BFwBTImgArray;
909 BTFirmwareLen = Rtl8723BFwBTImgArrayLength;
910 pFirmware->szFwBuffer = pBTFirmwareBuf;
911 pFirmware->ulFwLength = BTFirmwareLen;
912 #endif // CONFIG_EMBEDDED_FWIMG
913 }
914
915 DBG_8192C("%s: MP BT Firmware size=%d\n", __FUNCTION__, BTFirmwareLen);
916
917 // for h2c cam here should be set to true
918 padapter->bFWReady = _TRUE;
919
920 download_time = (BTFirmwareLen + 4095) / 4096;
921 DBG_8192C("%s: download_time is %d\n", __FUNCTION__, download_time);
922
923 // Download BT patch Fw.
924 for (i = (download_time-1); i >= 0; i--)
925 {
926 if (i == (download_time - 1))
927 {
928 rtStatus = _WriteBTFWtoTxPktBuf8723B(padapter, pBTFirmwareBuf+(4096*i), (BTFirmwareLen-(4096*i)), 1);
929 DBG_8192C("%s: start %d, len %d, time 1\n", __FUNCTION__, 4096*i, BTFirmwareLen-(4096*i));
930 }
931 else
932 {
933 rtStatus = _WriteBTFWtoTxPktBuf8723B(padapter, pBTFirmwareBuf+(4096*i), 4096, (download_time-i));
934 DBG_8192C("%s: start %d, len 4096, time %d\n", __FUNCTION__, 4096*i, download_time-i);
935 }
936
937 if (rtStatus != _SUCCESS)
938 {
939 DBG_8192C("%s: BT Firmware download to Tx packet buffer fail!\n", __FUNCTION__);
940 padapter->bBTFWReady = _FALSE;
941 return rtStatus;
942 }
943 }
944
945 ReservedPage_Compare(padapter,pFirmware,BTFirmwareLen);
946
947 padapter->bBTFWReady = _TRUE;
948 SetFwBTFwPatchCmd(padapter, (u16)BTFirmwareLen);
949 rtStatus = _CheckWLANFwPatchBTFwReady(padapter);
950
951 DBG_8192C("<===%s: return %s!\n", __FUNCTION__, rtStatus==_SUCCESS?"SUCCESS":"FAIL");
952 return rtStatus;
953 }
954 #endif // CONFIG_MP_INCLUDED
955
956 //
957 // Description:
958 // Download 8192C firmware code.
959 //
960 //
rtl8723b_FirmwareDownload(PADAPTER padapter,BOOLEAN bUsedWoWLANFw)961 s32 rtl8723b_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw)
962 {
963 s32 rtStatus = _SUCCESS;
964 u8 write_fw = 0;
965 u32 fwdl_start_time;
966 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
967 s8 R8723BFwImageFileName[] ={RTL8723B_FW_IMG};
968 u8 *FwImage;
969 u32 FwImageLen;
970 u8 *pFwImageFileName;
971 #ifdef CONFIG_WOWLAN
972 u8 *FwImageWoWLAN;
973 u32 FwImageWoWLANLen;
974 #endif
975 u8 *pucMappedFile = NULL;
976 PRT_FIRMWARE_8723B pFirmware = NULL;
977 PRT_FIRMWARE_8723B pBTFirmware = NULL;
978 PRT_8723B_FIRMWARE_HDR pFwHdr = NULL;
979 u8 *pFirmwareBuf;
980 u32 FirmwareLen;
981 #ifdef CONFIG_FILE_FWIMG
982 u8 *fwfilepath;
983 #endif // CONFIG_FILE_FWIMG
984 struct dvobj_priv *psdpriv = padapter->dvobj;
985 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
986 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
987
988 RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __FUNCTION__));
989 #ifdef CONFIG_WOWLAN
990 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("+%s, bUsedWoWLANFw:%d\n", __FUNCTION__,bUsedWoWLANFw));
991 #endif
992 pFirmware = (PRT_FIRMWARE_8723B)rtw_zmalloc(sizeof(RT_FIRMWARE_8723B));
993
994 if(!pFirmware)
995 {
996 rtStatus = _FAIL;
997 goto exit;
998 }
999
1000 {
1001 u8 tmp_ps=0, tmp_rf=0;
1002 tmp_ps=rtw_read8(padapter,0xa3);
1003 tmp_ps&=0xf8;
1004 tmp_ps|=0x02;
1005 //1. write 0xA3[:2:0] = 3b'010
1006 rtw_write8(padapter, 0xa3, tmp_ps);
1007 //2. read power_state = 0xA0[1:0]
1008 tmp_ps=rtw_read8(padapter,0xa0);
1009 tmp_ps&=0x03;
1010 if(tmp_ps != 0x01)
1011 {
1012 DBG_871X(FUNC_ADPT_FMT" tmp_ps=%x \n",FUNC_ADPT_ARG(padapter), tmp_ps);
1013 pdbgpriv->dbg_downloadfw_pwr_state_cnt++;
1014 }
1015 }
1016
1017 rtw_btcoex_PreLoadFirmware(padapter);
1018
1019 #ifdef CONFIG_FILE_FWIMG
1020 #ifdef CONFIG_WOWLAN
1021 if (bUsedWoWLANFw)
1022 {
1023 fwfilepath = rtw_fw_wow_file_path;
1024 }
1025 else
1026 #endif // CONFIG_WOWLAN
1027 {
1028 fwfilepath = rtw_fw_file_path;
1029 }
1030 #endif // CONFIG_FILE_FWIMG
1031
1032 #ifdef CONFIG_FILE_FWIMG
1033 if (rtw_is_file_readable(fwfilepath) == _TRUE)
1034 {
1035 DBG_8192C("%s accquire FW from file:%s\n", __FUNCTION__, fwfilepath);
1036 pFirmware->eFWSource = FW_SOURCE_IMG_FILE;
1037 }
1038 else
1039 #endif // CONFIG_FILE_FWIMG
1040 {
1041 #ifdef CONFIG_EMBEDDED_FWIMG
1042 pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
1043 #else // !CONFIG_EMBEDDED_FWIMG
1044 pFirmware->eFWSource = FW_SOURCE_IMG_FILE; // We should decided by Reg.
1045 #endif // !CONFIG_EMBEDDED_FWIMG
1046 }
1047
1048 switch(pFirmware->eFWSource)
1049 {
1050 case FW_SOURCE_IMG_FILE:
1051 #ifdef CONFIG_FILE_FWIMG
1052 rtStatus = rtw_retrieve_from_file(fwfilepath, FwBuffer, FW_8723B_SIZE);
1053 pFirmware->ulFwLength = rtStatus>=0?rtStatus:0;
1054 pFirmware->szFwBuffer = FwBuffer;
1055 #endif // CONFIG_FILE_FWIMG
1056 break;
1057
1058 case FW_SOURCE_HEADER_FILE:
1059 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1060 if (bUsedWoWLANFw) {
1061 if (!pwrpriv->wowlan_ap_mode) {
1062 ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv,
1063 CONFIG_FW_WoWLAN,
1064 (u8*)&pFirmware->szFwBuffer,
1065 &pFirmware->ulFwLength);
1066
1067 DBG_8192C(" ===> %s fw: %s, size: %d\n",
1068 __FUNCTION__, "WoWLAN",
1069 pFirmware->ulFwLength);
1070 } else {
1071 ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv,
1072 CONFIG_FW_AP_WoWLAN,
1073 (u8*)&pFirmware->szFwBuffer,
1074 &pFirmware->ulFwLength);
1075
1076 DBG_8192C(" ===> %s fw: %s, size: %d\n",
1077 __FUNCTION__, "AP_WoWLAN",
1078 pFirmware->ulFwLength);
1079 }
1080 } else
1081 #endif // CONFIG_WOWLAN
1082 {
1083 if(padapter->registrypriv.mp_mode ==0)
1084 {
1085 ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, CONFIG_FW_NIC,
1086 (u8*)&pFirmware->szFwBuffer, &pFirmware->ulFwLength);
1087 DBG_8192C("%s fw: %s, size: %d\n", __FUNCTION__, "FW_NIC", pFirmware->ulFwLength);
1088 }
1089 else
1090 {
1091 ODM_ReadFirmware_MP_8723B_FW_MP(&pHalData->odmpriv, (u8 *)&pFirmware->szFwBuffer, &pFirmware->ulFwLength);
1092 DBG_8192C("%s fw: %s, size: %d\n", __FUNCTION__, "FW_MP", pFirmware->ulFwLength);
1093 }
1094 }
1095 break;
1096 }
1097
1098 if (pFirmware->ulFwLength > FW_8723B_SIZE) {
1099 rtStatus = _FAIL;
1100 DBG_871X_LEVEL(_drv_emerg_, "Firmware size:%u exceed %u\n", pFirmware->ulFwLength, FW_8723B_SIZE);
1101 goto exit;
1102 }
1103
1104 pFirmwareBuf = pFirmware->szFwBuffer;
1105 FirmwareLen = pFirmware->ulFwLength;
1106
1107 // To Check Fw header. Added by tynli. 2009.12.04.
1108 pFwHdr = (PRT_8723B_FIRMWARE_HDR)pFirmwareBuf;
1109
1110 pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version);
1111 pHalData->FirmwareSubVersion = le16_to_cpu(pFwHdr->Subversion);
1112 pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
1113
1114 DBG_871X("%s: fw_ver=%x fw_subver=%04x sig=0x%x, Month=%02x, Date=%02x, Hour=%02x, Minute=%02x\n",
1115 __FUNCTION__, pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, pHalData->FirmwareSignature
1116 ,pFwHdr->Month,pFwHdr->Date,pFwHdr->Hour,pFwHdr->Minute);
1117
1118 if (IS_FW_HEADER_EXIST_8723B(pFwHdr))
1119 {
1120 DBG_871X("%s(): Shift for fw header!\n", __func__);
1121 // Shift 32 bytes for FW header
1122 pFirmwareBuf = pFirmwareBuf + 32;
1123 FirmwareLen = FirmwareLen - 32;
1124 }
1125
1126 // Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself,
1127 // or it will cause download Fw fail. 2010.02.01. by tynli.
1128 if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) //8051 RAM code
1129 {
1130 rtw_write8(padapter, REG_MCUFWDL, 0x00);
1131 rtl8723b_FirmwareSelfReset(padapter);
1132 }
1133
1134 _FWDownloadEnable(padapter, _TRUE);
1135 fwdl_start_time = rtw_get_current_time();
1136 while (!RTW_CANNOT_IO(padapter)
1137 && (write_fw++ < 3 || rtw_get_passing_time_ms(fwdl_start_time) < 500))
1138 {
1139 /* reset FWDL chksum */
1140 rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL)|FWDL_ChkSum_rpt);
1141
1142 rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
1143 if (rtStatus != _SUCCESS)
1144 continue;
1145
1146 rtStatus = polling_fwdl_chksum(padapter, 5, 50);
1147 if (rtStatus == _SUCCESS)
1148 break;
1149 }
1150 _FWDownloadEnable(padapter, _FALSE);
1151 if(_SUCCESS != rtStatus)
1152 goto fwdl_stat;
1153
1154 rtStatus = _FWFreeToGo(padapter, 10, 200);
1155 if (_SUCCESS != rtStatus)
1156 goto fwdl_stat;
1157
1158 #ifdef CONFIG_MP_INCLUDED//BT_MP
1159 if (padapter->registrypriv.mp_mode == 1)
1160 {
1161 //rtw_write8(padapter, 0x81, rtw_read8(padapter, 0x81)|BIT0);
1162 DBG_871X("rtl8723b_FirmwareDownload go to FirmwareDownloadBT !\n");
1163 pBTFirmware = (PRT_FIRMWARE_8723B)rtw_zmalloc(sizeof(RT_FIRMWARE_8723B));
1164 if(!pBTFirmware)
1165 {
1166 rtStatus = _FAIL;
1167 goto exit;
1168 }
1169 FirmwareDownloadBT(padapter, (PRT_MP_FIRMWARE)pBTFirmware);
1170 }
1171 #endif
1172
1173 fwdl_stat:
1174 DBG_871X("FWDL %s. write_fw:%u, %dms\n"
1175 , (rtStatus == _SUCCESS)?"success":"fail"
1176 , write_fw
1177 , rtw_get_passing_time_ms(fwdl_start_time)
1178 );
1179
1180 exit:
1181 if (pFirmware)
1182 rtw_mfree((u8*)pFirmware, sizeof(RT_FIRMWARE_8723B));
1183 if (pBTFirmware)
1184 rtw_mfree((u8*)pBTFirmware, sizeof(RT_FIRMWARE_8723B));
1185
1186 rtl8723b_InitializeFirmwareVars(padapter);
1187
1188 DBG_871X(" <=== rtl8723b_FirmwareDownload()\n");
1189 return rtStatus;
1190 }
1191
rtl8723b_InitializeFirmwareVars(PADAPTER padapter)1192 void rtl8723b_InitializeFirmwareVars(PADAPTER padapter)
1193 {
1194 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1195
1196 // Init Fw LPS related.
1197 adapter_to_pwrctl(padapter)->bFwCurrentInPSMode = _FALSE;
1198
1199 //Init H2C cmd.
1200 rtw_write8(padapter, REG_HMETFR, 0x0f);
1201
1202 // Init H2C counter. by tynli. 2009.12.09.
1203 pHalData->LastHMEBoxNum = 0;
1204 // pHalData->H2CQueueHead = 0;
1205 // pHalData->H2CQueueTail = 0;
1206 // pHalData->H2CStopInsertQueue = _FALSE;
1207 }
1208
1209 //===========================================================
1210 // Efuse related code
1211 //===========================================================
1212 static u8
hal_EfuseSwitchToBank(PADAPTER padapter,u8 bank,u8 bPseudoTest)1213 hal_EfuseSwitchToBank(
1214 PADAPTER padapter,
1215 u8 bank,
1216 u8 bPseudoTest)
1217 {
1218 u8 bRet = _FALSE;
1219 u32 value32 = 0;
1220 #ifdef HAL_EFUSE_MEMORY
1221 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1222 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1223 #endif
1224
1225
1226 DBG_8192C("%s: Efuse switch bank to %d\n", __FUNCTION__, bank);
1227 if (bPseudoTest)
1228 {
1229 #ifdef HAL_EFUSE_MEMORY
1230 pEfuseHal->fakeEfuseBank = bank;
1231 #else
1232 fakeEfuseBank = bank;
1233 #endif
1234 bRet = _TRUE;
1235 }
1236 else
1237 {
1238 value32 = rtw_read32(padapter, EFUSE_TEST);
1239 bRet = _TRUE;
1240 switch (bank)
1241 {
1242 case 0:
1243 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1244 break;
1245 case 1:
1246 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
1247 break;
1248 case 2:
1249 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
1250 break;
1251 case 3:
1252 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
1253 break;
1254 default:
1255 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1256 bRet = _FALSE;
1257 break;
1258 }
1259 rtw_write32(padapter, EFUSE_TEST, value32);
1260 }
1261
1262 return bRet;
1263 }
1264
1265 static void
Hal_GetEfuseDefinition(PADAPTER padapter,u8 efuseType,u8 type,void * pOut,u8 bPseudoTest)1266 Hal_GetEfuseDefinition(
1267 PADAPTER padapter,
1268 u8 efuseType,
1269 u8 type,
1270 void *pOut,
1271 u8 bPseudoTest)
1272 {
1273 switch (type)
1274 {
1275 case TYPE_EFUSE_MAX_SECTION:
1276 {
1277 u8 *pMax_section;
1278 pMax_section = (u8*)pOut;
1279
1280 if (efuseType == EFUSE_WIFI)
1281 *pMax_section = EFUSE_MAX_SECTION_8723B;
1282 else
1283 *pMax_section = EFUSE_BT_MAX_SECTION;
1284 }
1285 break;
1286
1287 case TYPE_EFUSE_REAL_CONTENT_LEN:
1288 {
1289 u16 *pu2Tmp;
1290 pu2Tmp = (u16*)pOut;
1291
1292 if (efuseType == EFUSE_WIFI)
1293 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
1294 else
1295 *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
1296 }
1297 break;
1298
1299 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
1300 {
1301 u16 *pu2Tmp;
1302 pu2Tmp = (u16*)pOut;
1303
1304 if (efuseType == EFUSE_WIFI)
1305 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
1306 else
1307 *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN-EFUSE_PROTECT_BYTES_BANK);
1308 }
1309 break;
1310
1311 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
1312 {
1313 u16 *pu2Tmp;
1314 pu2Tmp = (u16*)pOut;
1315
1316 if (efuseType == EFUSE_WIFI)
1317 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
1318 else
1319 *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN-(EFUSE_PROTECT_BYTES_BANK*3));
1320 }
1321 break;
1322
1323 case TYPE_EFUSE_MAP_LEN:
1324 {
1325 u16 *pu2Tmp;
1326 pu2Tmp = (u16*)pOut;
1327
1328 if (efuseType == EFUSE_WIFI)
1329 *pu2Tmp = EFUSE_MAX_MAP_LEN;
1330 else
1331 *pu2Tmp = EFUSE_BT_MAP_LEN;
1332 }
1333 break;
1334
1335 case TYPE_EFUSE_PROTECT_BYTES_BANK:
1336 {
1337 u8 *pu1Tmp;
1338 pu1Tmp = (u8*)pOut;
1339
1340 if (efuseType == EFUSE_WIFI)
1341 *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
1342 else
1343 *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
1344 }
1345 break;
1346
1347 case TYPE_EFUSE_CONTENT_LEN_BANK:
1348 {
1349 u16 *pu2Tmp;
1350 pu2Tmp = (u16*)pOut;
1351
1352 if (efuseType == EFUSE_WIFI)
1353 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
1354 else
1355 *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
1356 }
1357 break;
1358
1359 default:
1360 {
1361 u8 *pu1Tmp;
1362 pu1Tmp = (u8*)pOut;
1363 *pu1Tmp = 0;
1364 }
1365 break;
1366 }
1367 }
1368
1369 #define VOLTAGE_V25 0x03
1370 #define LDOE25_SHIFT 28
1371
1372 //=================================================================
1373 // The following is for compile ok
1374 // That should be merged with the original in the future
1375 //=================================================================
1376 #define EFUSE_ACCESS_ON_8723 0x69 // For RTL8723 only.
1377 #define EFUSE_ACCESS_OFF_8723 0x00 // For RTL8723 only.
1378 #define REG_EFUSE_ACCESS_8723 0x00CF // Efuse access protection for RTL8723
1379
1380 //=================================================================
Hal_BT_EfusePowerSwitch(PADAPTER padapter,u8 bWrite,u8 PwrState)1381 static void Hal_BT_EfusePowerSwitch(
1382 PADAPTER padapter,
1383 u8 bWrite,
1384 u8 PwrState)
1385 {
1386 u8 tempval;
1387 if (PwrState == _TRUE)
1388 {
1389 // enable BT power cut
1390 // 0x6A[14] = 1
1391 tempval = rtw_read8(padapter, 0x6B);
1392 tempval |= BIT(6);
1393 rtw_write8(padapter, 0x6B, tempval);
1394
1395 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
1396 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
1397 rtw_usleep_os(100);
1398 // disable BT output isolation
1399 // 0x6A[15] = 0
1400 tempval = rtw_read8(padapter, 0x6B);
1401 tempval &= ~BIT(7);
1402 rtw_write8(padapter, 0x6B, tempval);
1403 }
1404 else
1405 {
1406 // enable BT output isolation
1407 // 0x6A[15] = 1
1408 tempval = rtw_read8(padapter, 0x6B);
1409 tempval |= BIT(7);
1410 rtw_write8(padapter, 0x6B, tempval);
1411
1412 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
1413 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
1414
1415 // disable BT power cut
1416 // 0x6A[14] = 1
1417 tempval = rtw_read8(padapter, 0x6B);
1418 tempval &= ~BIT(6);
1419 rtw_write8(padapter, 0x6B, tempval);
1420 }
1421
1422 }
1423 static void
Hal_EfusePowerSwitch(PADAPTER padapter,u8 bWrite,u8 PwrState)1424 Hal_EfusePowerSwitch(
1425 PADAPTER padapter,
1426 u8 bWrite,
1427 u8 PwrState)
1428 {
1429 u8 tempval;
1430 u16 tmpV16;
1431
1432
1433 if (PwrState == _TRUE)
1434 {
1435 /* enable BT power cut 0x6A[14] = 1*/
1436 tempval = rtw_read8(padapter, 0x6B);
1437 tempval |= BIT(6);
1438 rtw_write8(padapter, 0x6B, tempval);
1439 #ifdef CONFIG_SDIO_HCI
1440 // To avoid cannot access efuse regsiters after disable/enable several times during DTM test.
1441 // Suggested by SD1 IsaacHsu. 2013.07.08, added by tynli.
1442 tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
1443 if (tempval & BIT(0)) // SDIO local register is suspend
1444 {
1445 u8 count = 0;
1446
1447
1448 tempval &= ~BIT(0);
1449 rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL, tempval);
1450
1451 // check 0x86[1:0]=10'2h, wait power state to leave suspend
1452 do {
1453 tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
1454 tempval &= 0x3;
1455 if (tempval == 0x02)
1456 break;
1457
1458 count++;
1459 if (count >= 100)
1460 break;
1461
1462 rtw_mdelay_os(10);
1463 } while (1);
1464
1465 if (count >= 100)
1466 {
1467 DBG_8192C(FUNC_ADPT_FMT ": Leave SDIO local register suspend fail! Local 0x86=%#X\n",
1468 FUNC_ADPT_ARG(padapter), tempval);
1469 }
1470 else
1471 {
1472 DBG_8192C(FUNC_ADPT_FMT ": Leave SDIO local register suspend OK! Local 0x86=%#X\n",
1473 FUNC_ADPT_ARG(padapter), tempval);
1474 }
1475 }
1476 #endif // CONFIG_SDIO_HCI
1477
1478 rtw_write8(padapter, REG_EFUSE_ACCESS_8723, EFUSE_ACCESS_ON_8723);
1479
1480 // Reset: 0x0000h[28], default valid
1481 tmpV16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
1482 if (!(tmpV16 & FEN_ELDR)) {
1483 tmpV16 |= FEN_ELDR ;
1484 rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
1485 }
1486
1487 // Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid
1488 tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
1489 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
1490 tmpV16 |= (LOADER_CLK_EN | ANA8M) ;
1491 rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
1492 }
1493
1494 if (bWrite == _TRUE)
1495 {
1496 // Enable LDO 2.5V before read/write action
1497 tempval = rtw_read8(padapter, EFUSE_TEST+3);
1498 tempval &= 0x0F;
1499 /*tempval |= (VOLTAGE_V25 << 4);*/
1500 tempval |= 0x70; /* 0x34[30:28] = 0b'111, Use LDO 2.25V, Suggested by SD1 Morris & Victor*/
1501 rtw_write8(padapter, EFUSE_TEST+3, (tempval | 0x80));
1502
1503 //rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
1504 }
1505 }
1506 else
1507 {
1508 /*enable BT output isolation 0x6A[15] = 1 */
1509 tempval = rtw_read8(padapter, 0x6B);
1510 tempval |= BIT(7);
1511 rtw_write8(padapter, 0x6B, tempval);
1512
1513 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
1514
1515 if (bWrite == _TRUE) {
1516 // Disable LDO 2.5V after read/write action
1517 tempval = rtw_read8(padapter, EFUSE_TEST+3);
1518 rtw_write8(padapter, EFUSE_TEST+3, (tempval & 0x7F));
1519 }
1520
1521 }
1522 }
1523
1524 static void
hal_ReadEFuse_WiFi(PADAPTER padapter,u16 _offset,u16 _size_byte,u8 * pbuf,u8 bPseudoTest)1525 hal_ReadEFuse_WiFi(
1526 PADAPTER padapter,
1527 u16 _offset,
1528 u16 _size_byte,
1529 u8 *pbuf,
1530 u8 bPseudoTest)
1531 {
1532 #ifdef HAL_EFUSE_MEMORY
1533 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1534 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1535 #endif
1536 u8 *efuseTbl = NULL;
1537 u16 eFuse_Addr=0;
1538 u8 offset, wden;
1539 u8 efuseHeader, efuseExtHdr, efuseData;
1540 u16 i, total, used;
1541 u8 efuse_usage = 0;
1542
1543 //DBG_871X("YJ: ====>%s():_offset=%d _size_byte=%d bPseudoTest=%d\n", __func__, _offset, _size_byte, bPseudoTest);
1544 //
1545 // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
1546 //
1547 if ((_offset+_size_byte) > EFUSE_MAX_MAP_LEN)
1548 {
1549 DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1550 return;
1551 }
1552
1553 efuseTbl = (u8*)rtw_malloc(EFUSE_MAX_MAP_LEN);
1554 if (efuseTbl == NULL)
1555 {
1556 DBG_8192C("%s: alloc efuseTbl fail!\n", __FUNCTION__);
1557 return;
1558 }
1559 // 0xff will be efuse default value instead of 0x00.
1560 _rtw_memset(efuseTbl, 0xFF, EFUSE_MAX_MAP_LEN);
1561
1562
1563 #ifdef CONFIG_DEBUG
1564 if(0)
1565 {
1566 for(i=0; i<256; i++)
1567 //ReadEFuseByte(padapter, i, &efuseTbl[i], _FALSE);
1568 efuse_OneByteRead(padapter, i, &efuseTbl[i], _FALSE);
1569 DBG_871X("Efuse Content:\n");
1570 for(i=0; i<256; i++)
1571 {
1572 if (i % 16 == 0)
1573 printk("\n");
1574 printk("%02X ", efuseTbl[i]);
1575 }
1576 printk("\n");
1577 }
1578 #endif
1579
1580
1581 // switch bank back to bank 0 for later BT and wifi use.
1582 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1583
1584 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
1585 {
1586 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1587 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1588 if (efuseHeader == 0xFF)
1589 {
1590 DBG_8192C("%s: data end at address=%#x\n", __FUNCTION__, eFuse_Addr-1);
1591 break;
1592 }
1593 //DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseHeader);
1594
1595 // Check PG header for section num.
1596 if (EXT_HEADER(efuseHeader)) //extended header
1597 {
1598 offset = GET_HDR_OFFSET_2_0(efuseHeader);
1599 //DBG_8192C("%s: extended header offset=0x%X\n", __FUNCTION__, offset);
1600
1601 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1602 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1603 //DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseExtHdr);
1604 if (ALL_WORDS_DISABLED(efuseExtHdr))
1605 {
1606 continue;
1607 }
1608
1609 offset |= ((efuseExtHdr & 0xF0) >> 1);
1610 wden = (efuseExtHdr & 0x0F);
1611 }
1612 else
1613 {
1614 offset = ((efuseHeader >> 4) & 0x0f);
1615 wden = (efuseHeader & 0x0f);
1616 }
1617 //DBG_8192C("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden);
1618
1619 if (offset < EFUSE_MAX_SECTION_8723B)
1620 {
1621 u16 addr;
1622 // Get word enable value from PG header
1623 // DBG_8192C("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden);
1624
1625 addr = offset * PGPKT_DATA_SIZE;
1626 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1627 {
1628 // Check word enable condition in the section
1629 if (!(wden & (0x01<<i)))
1630 {
1631 efuseData = 0;
1632 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1633 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1634 // DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1635 efuseTbl[addr] = efuseData;
1636
1637 efuseData = 0;
1638 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1639 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1640 // DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1641 efuseTbl[addr+1] = efuseData;
1642 }
1643 addr += 2;
1644 }
1645 }
1646 else
1647 {
1648 DBG_8192C(KERN_ERR "%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1649 eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
1650 }
1651 }
1652
1653 // Copy from Efuse map to output pointer memory!!!
1654 for (i=0; i<_size_byte; i++)
1655 pbuf[i] = efuseTbl[_offset+i];
1656
1657 #ifdef CONFIG_DEBUG
1658 if(1)
1659 {
1660 DBG_871X("Efuse Realmap:\n");
1661 for(i=0; i<_size_byte; i++)
1662 {
1663 if (i % 16 == 0)
1664 printk("\n");
1665 printk("%02X ", pbuf[i]);
1666 }
1667 printk("\n");
1668 }
1669 #endif
1670 // Calculate Efuse utilization
1671 total = 0;
1672 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1673 used = eFuse_Addr - 1;
1674 if (total)
1675 efuse_usage = (u8)((used*100)/total);
1676 else
1677 efuse_usage = 100;
1678 if (bPseudoTest)
1679 {
1680 #ifdef HAL_EFUSE_MEMORY
1681 pEfuseHal->fakeEfuseUsedBytes = used;
1682 #else
1683 fakeEfuseUsedBytes = used;
1684 #endif
1685 }
1686 else
1687 {
1688 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&used);
1689 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8*)&efuse_usage);
1690 }
1691
1692 if (efuseTbl)
1693 rtw_mfree(efuseTbl, EFUSE_MAX_MAP_LEN);
1694 }
1695
1696 static VOID
hal_ReadEFuse_BT(PADAPTER padapter,u16 _offset,u16 _size_byte,u8 * pbuf,u8 bPseudoTest)1697 hal_ReadEFuse_BT(
1698 PADAPTER padapter,
1699 u16 _offset,
1700 u16 _size_byte,
1701 u8 *pbuf,
1702 u8 bPseudoTest
1703 )
1704 {
1705 #ifdef HAL_EFUSE_MEMORY
1706 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1707 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1708 #endif
1709 u8 *efuseTbl;
1710 u8 bank;
1711 u16 eFuse_Addr;
1712 u8 efuseHeader, efuseExtHdr, efuseData;
1713 u8 offset, wden;
1714 u16 i, total, used;
1715 u8 efuse_usage;
1716
1717
1718 //
1719 // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
1720 //
1721 if ((_offset+_size_byte) > EFUSE_BT_MAP_LEN)
1722 {
1723 DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1724 return;
1725 }
1726
1727 efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);
1728 if (efuseTbl == NULL) {
1729 DBG_8192C("%s: efuseTbl malloc fail!\n", __FUNCTION__);
1730 return;
1731 }
1732 // 0xff will be efuse default value instead of 0x00.
1733 _rtw_memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
1734
1735 total = 0;
1736 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total, bPseudoTest);
1737
1738 for (bank=1; bank<3; bank++) // 8723b Max bake 0~2
1739 {
1740 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE)
1741 {
1742 DBG_8192C("%s: hal_EfuseSwitchToBank Fail!!\n", __FUNCTION__);
1743 goto exit;
1744 }
1745
1746 eFuse_Addr = 0;
1747
1748 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
1749 {
1750 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1751 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1752 if (efuseHeader == 0xFF) break;
1753 DBG_8192C("%s: efuse[%#X]=0x%02x (header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN_8723B)+eFuse_Addr-1), efuseHeader);
1754
1755 // Check PG header for section num.
1756 if (EXT_HEADER(efuseHeader)) //extended header
1757 {
1758 offset = GET_HDR_OFFSET_2_0(efuseHeader);
1759 DBG_8192C("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset);
1760
1761 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1762 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1763 DBG_8192C("%s: efuse[%#X]=0x%02x (ext header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN_8723B)+eFuse_Addr-1), efuseExtHdr);
1764 if (ALL_WORDS_DISABLED(efuseExtHdr))
1765 {
1766 continue;
1767 }
1768
1769 offset |= ((efuseExtHdr & 0xF0) >> 1);
1770 wden = (efuseExtHdr & 0x0F);
1771 }
1772 else
1773 {
1774 offset = ((efuseHeader >> 4) & 0x0f);
1775 wden = (efuseHeader & 0x0f);
1776 }
1777
1778 if (offset < EFUSE_BT_MAX_SECTION)
1779 {
1780 u16 addr;
1781
1782 // Get word enable value from PG header
1783 DBG_8192C("%s: Offset=%d Worden=%#X\n", __FUNCTION__, offset, wden);
1784
1785 addr = offset * PGPKT_DATA_SIZE;
1786 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1787 {
1788 // Check word enable condition in the section
1789 if (!(wden & (0x01<<i)))
1790 {
1791 efuseData = 0;
1792 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1793 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1794 DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1795 efuseTbl[addr] = efuseData;
1796
1797 efuseData = 0;
1798 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1799 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1800 DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1801 efuseTbl[addr+1] = efuseData;
1802 }
1803 addr += 2;
1804 }
1805 }
1806 else
1807 {
1808 DBG_8192C("%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1809 eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
1810 }
1811 }
1812
1813 if ((eFuse_Addr-1) < total)
1814 {
1815 DBG_8192C("%s: bank(%d) data end at %#x\n", __FUNCTION__, bank, eFuse_Addr-1);
1816 break;
1817 }
1818 }
1819
1820 // switch bank back to bank 0 for later BT and wifi use.
1821 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1822
1823 // Copy from Efuse map to output pointer memory!!!
1824 for (i=0; i<_size_byte; i++)
1825 pbuf[i] = efuseTbl[_offset+i];
1826
1827 //
1828 // Calculate Efuse utilization.
1829 //
1830 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1831 used = (EFUSE_BT_REAL_BANK_CONTENT_LEN*(bank-1)) + eFuse_Addr - 1;
1832 DBG_8192C("%s: bank(%d) data end at %#x ,used =%d\n", __FUNCTION__, bank, eFuse_Addr-1,used);
1833 if (total)
1834 efuse_usage = (u8)((used*100)/total);
1835 else
1836 efuse_usage = 100;
1837 if (bPseudoTest)
1838 {
1839 #ifdef HAL_EFUSE_MEMORY
1840 pEfuseHal->fakeBTEfuseUsedBytes = used;
1841 #else
1842 fakeBTEfuseUsedBytes = used;
1843 #endif
1844 }
1845 else
1846 {
1847 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&used);
1848 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8*)&efuse_usage);
1849 }
1850
1851 exit:
1852 if (efuseTbl)
1853 rtw_mfree(efuseTbl, EFUSE_BT_MAP_LEN);
1854 }
1855
1856 static void
Hal_ReadEFuse(PADAPTER padapter,u8 efuseType,u16 _offset,u16 _size_byte,u8 * pbuf,u8 bPseudoTest)1857 Hal_ReadEFuse(
1858 PADAPTER padapter,
1859 u8 efuseType,
1860 u16 _offset,
1861 u16 _size_byte,
1862 u8 *pbuf,
1863 u8 bPseudoTest)
1864 {
1865 if (efuseType == EFUSE_WIFI)
1866 hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1867 else
1868 hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1869 }
1870
1871 static u16
hal_EfuseGetCurrentSize_WiFi(PADAPTER padapter,u8 bPseudoTest)1872 hal_EfuseGetCurrentSize_WiFi(
1873 PADAPTER padapter,
1874 u8 bPseudoTest)
1875 {
1876 #ifdef HAL_EFUSE_MEMORY
1877 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1878 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1879 #endif
1880 u16 efuse_addr=0;
1881 u16 start_addr = 0; // for debug
1882 u8 hoffset=0, hworden=0;
1883 u8 efuse_data, word_cnts=0;
1884 u32 count = 0; // for debug
1885
1886
1887 if (bPseudoTest)
1888 {
1889 #ifdef HAL_EFUSE_MEMORY
1890 efuse_addr = (u16)pEfuseHal->fakeEfuseUsedBytes;
1891 #else
1892 efuse_addr = (u16)fakeEfuseUsedBytes;
1893 #endif
1894 }
1895 else
1896 {
1897 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
1898 }
1899 start_addr = efuse_addr;
1900 DBG_8192C("%s: start_efuse_addr=0x%X\n", __FUNCTION__, efuse_addr);
1901
1902 // switch bank back to bank 0 for later BT and wifi use.
1903 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1904
1905 #if 0 // for debug test
1906 efuse_OneByteRead(padapter, 0x1FF, &efuse_data, bPseudoTest);
1907 DBG_8192C(FUNC_ADPT_FMT ": efuse raw 0x1FF=0x%02X\n",
1908 FUNC_ADPT_ARG(padapter), efuse_data);
1909 efuse_data = 0xFF;
1910 #endif // for debug test
1911
1912 count = 0;
1913 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
1914 {
1915 #if 1
1916 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE)
1917 {
1918 DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
1919 goto error;
1920 }
1921 #else
1922 ReadEFuseByte(padapter, efuse_addr, &efuse_data, bPseudoTest);
1923 #endif
1924
1925 if (efuse_data == 0xFF) break;
1926
1927 if ((start_addr != 0) && (efuse_addr == start_addr))
1928 {
1929 count++;
1930 DBG_8192C(FUNC_ADPT_FMT ": [WARNING] efuse raw 0x%X=0x%02X not 0xFF!!(%d times)\n",
1931 FUNC_ADPT_ARG(padapter), efuse_addr, efuse_data, count);
1932
1933 efuse_data = 0xFF;
1934 if (count < 4)
1935 {
1936 // try again!
1937
1938 if (count > 2)
1939 {
1940 // try again form address 0
1941 efuse_addr = 0;
1942 start_addr = 0;
1943 }
1944
1945 continue;
1946 }
1947
1948 goto error;
1949 }
1950
1951 if (EXT_HEADER(efuse_data))
1952 {
1953 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1954 efuse_addr++;
1955 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1956 if (ALL_WORDS_DISABLED(efuse_data))
1957 {
1958 continue;
1959 }
1960
1961 hoffset |= ((efuse_data & 0xF0) >> 1);
1962 hworden = efuse_data & 0x0F;
1963 }
1964 else
1965 {
1966 hoffset = (efuse_data>>4) & 0x0F;
1967 hworden = efuse_data & 0x0F;
1968 }
1969
1970 word_cnts = Efuse_CalculateWordCnts(hworden);
1971 efuse_addr += (word_cnts*2)+1;
1972 }
1973
1974 if (bPseudoTest)
1975 {
1976 #ifdef HAL_EFUSE_MEMORY
1977 pEfuseHal->fakeEfuseUsedBytes = efuse_addr;
1978 #else
1979 fakeEfuseUsedBytes = efuse_addr;
1980 #endif
1981 }
1982 else
1983 {
1984 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
1985 }
1986
1987 goto exit;
1988
1989 error:
1990 // report max size to prevent wirte efuse
1991 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_addr, bPseudoTest);
1992
1993 exit:
1994 DBG_8192C("%s: CurrentSize=%d\n", __FUNCTION__, efuse_addr);
1995
1996 return efuse_addr;
1997 }
1998
1999 static u16
hal_EfuseGetCurrentSize_BT(PADAPTER padapter,u8 bPseudoTest)2000 hal_EfuseGetCurrentSize_BT(
2001 PADAPTER padapter,
2002 u8 bPseudoTest)
2003 {
2004 #ifdef HAL_EFUSE_MEMORY
2005 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2006 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
2007 #endif
2008 u16 btusedbytes;
2009 u16 efuse_addr;
2010 u8 bank, startBank;
2011 u8 hoffset=0, hworden=0;
2012 u8 efuse_data, word_cnts=0;
2013 u16 retU2=0;
2014 u8 bContinual = _TRUE;
2015
2016
2017 if (bPseudoTest)
2018 {
2019 #ifdef HAL_EFUSE_MEMORY
2020 btusedbytes = pEfuseHal->fakeBTEfuseUsedBytes;
2021 #else
2022 btusedbytes = fakeBTEfuseUsedBytes;
2023 #endif
2024 }
2025 else
2026 {
2027 btusedbytes = 0;
2028 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&btusedbytes);
2029 }
2030 efuse_addr = (u16)((btusedbytes%EFUSE_BT_REAL_BANK_CONTENT_LEN));
2031 startBank = (u8)(1+(btusedbytes/EFUSE_BT_REAL_BANK_CONTENT_LEN));
2032
2033 DBG_8192C("%s: start from bank=%d addr=0x%X\n", __FUNCTION__, startBank, efuse_addr);
2034
2035 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2, bPseudoTest);
2036
2037 for (bank=startBank; bank<3; bank++)
2038 {
2039 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE)
2040 {
2041 DBG_8192C(KERN_ERR "%s: switch bank(%d) Fail!!\n", __FUNCTION__, bank);
2042 //bank = EFUSE_MAX_BANK;
2043 break;
2044 }
2045
2046 // only when bank is switched we have to reset the efuse_addr.
2047 if (bank != startBank)
2048 efuse_addr = 0;
2049 #if 1
2050
2051 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
2052 {
2053 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE)
2054 {
2055 DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
2056 //bank = EFUSE_MAX_BANK;
2057 break;
2058 }
2059 DBG_8192C("%s: efuse_OneByteRead ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr,efuse_data,bank);
2060
2061 if (efuse_data == 0xFF) break;
2062
2063 if (EXT_HEADER(efuse_data))
2064 {
2065 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
2066 efuse_addr++;
2067 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
2068 DBG_8192C("%s: efuse_OneByteRead EXT_HEADER ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr,efuse_data,bank);
2069
2070 if (ALL_WORDS_DISABLED(efuse_data))
2071 {
2072 efuse_addr++;
2073 continue;
2074 }
2075
2076 // hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2077 hoffset |= ((efuse_data & 0xF0) >> 1);
2078 hworden = efuse_data & 0x0F;
2079 }
2080 else
2081 {
2082 hoffset = (efuse_data>>4) & 0x0F;
2083 hworden = efuse_data & 0x0F;
2084 }
2085
2086 DBG_8192C(FUNC_ADPT_FMT": Offset=%d Worden=%#X\n",
2087 FUNC_ADPT_ARG(padapter), hoffset, hworden);
2088
2089 word_cnts = Efuse_CalculateWordCnts(hworden);
2090 //read next header
2091 efuse_addr += (word_cnts*2)+1;
2092 }
2093 #else
2094 while ( bContinual &&
2095 efuse_OneByteRead(padapter, efuse_addr ,&efuse_data, bPseudoTest) &&
2096 AVAILABLE_EFUSE_ADDR(efuse_addr))
2097 {
2098 if(efuse_data!=0xFF)
2099 {
2100 if((efuse_data&0x1F) == 0x0F) //extended header
2101 {
2102 hoffset = efuse_data;
2103 efuse_addr++;
2104 efuse_OneByteRead(padapter, efuse_addr ,&efuse_data, bPseudoTest);
2105 if((efuse_data & 0x0F) == 0x0F)
2106 {
2107 efuse_addr++;
2108 continue;
2109 }
2110 else
2111 {
2112 hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2113 hworden = efuse_data & 0x0F;
2114 }
2115 }
2116 else
2117 {
2118 hoffset = (efuse_data>>4) & 0x0F;
2119 hworden = efuse_data & 0x0F;
2120 }
2121 word_cnts = Efuse_CalculateWordCnts(hworden);
2122 //read next header
2123 efuse_addr = efuse_addr + (word_cnts*2)+1;
2124 }
2125 else
2126 {
2127 bContinual = _FALSE ;
2128 }
2129 }
2130 #endif
2131
2132
2133 // Check if we need to check next bank efuse
2134 if (efuse_addr < retU2)
2135 {
2136 break;// don't need to check next bank.
2137 }
2138 }
2139 #if 0
2140 retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
2141 if (bPseudoTest)
2142 {
2143 #ifdef HAL_EFUSE_MEMORY
2144 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
2145 #else
2146 fakeBTEfuseUsedBytes = retU2;
2147 #endif
2148 }
2149 else
2150 {
2151 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&retU2);
2152 }
2153 #else
2154 retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN)+efuse_addr;
2155 if(bPseudoTest)
2156 {
2157 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
2158 //RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->fakeBTEfuseUsedBytes));
2159 }
2160 else
2161 {
2162 pEfuseHal->BTEfuseUsedBytes = retU2;
2163 //RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->BTEfuseUsedBytes));
2164 }
2165 #endif
2166
2167 DBG_8192C("%s: CurrentSize=%d\n", __FUNCTION__, retU2);
2168 return retU2;
2169 }
2170
2171 static u16
Hal_EfuseGetCurrentSize(PADAPTER pAdapter,u8 efuseType,u8 bPseudoTest)2172 Hal_EfuseGetCurrentSize(
2173 PADAPTER pAdapter,
2174 u8 efuseType,
2175 u8 bPseudoTest)
2176 {
2177 u16 ret = 0;
2178
2179 if (efuseType == EFUSE_WIFI)
2180 ret = hal_EfuseGetCurrentSize_WiFi(pAdapter, bPseudoTest);
2181 else
2182 ret = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest);
2183
2184 return ret;
2185 }
2186
2187 static u8
Hal_EfuseWordEnableDataWrite(PADAPTER padapter,u16 efuse_addr,u8 word_en,u8 * data,u8 bPseudoTest)2188 Hal_EfuseWordEnableDataWrite(
2189 PADAPTER padapter,
2190 u16 efuse_addr,
2191 u8 word_en,
2192 u8 *data,
2193 u8 bPseudoTest)
2194 {
2195 u16 tmpaddr = 0;
2196 u16 start_addr = efuse_addr;
2197 u8 badworden = 0x0F;
2198 u8 tmpdata[PGPKT_DATA_SIZE];
2199
2200
2201 // DBG_8192C("%s: efuse_addr=%#x word_en=%#x\n", __FUNCTION__, efuse_addr, word_en);
2202 _rtw_memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
2203
2204 if (!(word_en & BIT(0)))
2205 {
2206 tmpaddr = start_addr;
2207 efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest);
2208 efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest);
2209 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 0);
2210 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest);
2211 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[1], bPseudoTest);
2212 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 1);
2213 if ((data[0]!=tmpdata[0]) || (data[1]!=tmpdata[1])) {
2214 badworden &= (~BIT(0));
2215 }
2216 }
2217 if (!(word_en & BIT(1)))
2218 {
2219 tmpaddr = start_addr;
2220 efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest);
2221 efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest);
2222 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 0);
2223 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest);
2224 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[3], bPseudoTest);
2225 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 1);
2226 if ((data[2]!=tmpdata[2]) || (data[3]!=tmpdata[3])) {
2227 badworden &= (~BIT(1));
2228 }
2229 }
2230 if (!(word_en & BIT(2)))
2231 {
2232 tmpaddr = start_addr;
2233 efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest);
2234 efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest);
2235 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 0);
2236 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest);
2237 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[5], bPseudoTest);
2238 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 1);
2239 if ((data[4]!=tmpdata[4]) || (data[5]!=tmpdata[5])) {
2240 badworden &= (~BIT(2));
2241 }
2242 }
2243 if (!(word_en & BIT(3)))
2244 {
2245 tmpaddr = start_addr;
2246 efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest);
2247 efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest);
2248 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 0);
2249 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest);
2250 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[7], bPseudoTest);
2251 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 1);
2252 if ((data[6]!=tmpdata[6]) || (data[7]!=tmpdata[7])) {
2253 badworden &= (~BIT(3));
2254 }
2255 }
2256
2257 return badworden;
2258 }
2259
2260 static s32
Hal_EfusePgPacketRead(PADAPTER padapter,u8 offset,u8 * data,u8 bPseudoTest)2261 Hal_EfusePgPacketRead(
2262 PADAPTER padapter,
2263 u8 offset,
2264 u8 *data,
2265 u8 bPseudoTest)
2266 {
2267 u8 bDataEmpty = _TRUE;
2268 u8 efuse_data, word_cnts=0;
2269 u16 efuse_addr=0;
2270 u8 hoffset=0, hworden=0;
2271 u8 i;
2272 u8 max_section = 0;
2273 s32 ret;
2274
2275
2276 if (data == NULL)
2277 return _FALSE;
2278
2279 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest);
2280 if (offset > max_section)
2281 {
2282 DBG_8192C("%s: Packet offset(%d) is illegal(>%d)!\n", __FUNCTION__, offset, max_section);
2283 return _FALSE;
2284 }
2285
2286 _rtw_memset(data, 0xFF, PGPKT_DATA_SIZE);
2287 ret = _TRUE;
2288
2289 //
2290 // <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP.
2291 // Skip dummy parts to prevent unexpected data read from Efuse.
2292 // By pass right now. 2009.02.19.
2293 //
2294 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
2295 {
2296 if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == _FALSE)
2297 {
2298 ret = _FALSE;
2299 break;
2300 }
2301
2302 if (efuse_data == 0xFF) break;
2303
2304 if (EXT_HEADER(efuse_data))
2305 {
2306 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
2307 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2308 if (ALL_WORDS_DISABLED(efuse_data))
2309 {
2310 DBG_8192C("%s: Error!! All words disabled!\n", __FUNCTION__);
2311 continue;
2312 }
2313
2314 hoffset |= ((efuse_data & 0xF0) >> 1);
2315 hworden = efuse_data & 0x0F;
2316 }
2317 else
2318 {
2319 hoffset = (efuse_data>>4) & 0x0F;
2320 hworden = efuse_data & 0x0F;
2321 }
2322
2323 if (hoffset == offset)
2324 {
2325 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
2326 {
2327 // Check word enable condition in the section
2328 if (!(hworden & (0x01<<i)))
2329 {
2330 //ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2331 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2332 // DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
2333 data[i*2] = efuse_data;
2334
2335 //ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2336 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2337 // DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
2338 data[(i*2)+1] = efuse_data;
2339 }
2340 }
2341 }
2342 else
2343 {
2344 word_cnts = Efuse_CalculateWordCnts(hworden);
2345 efuse_addr += word_cnts*2;
2346 }
2347 }
2348
2349 return ret;
2350 }
2351
2352 static u8
hal_EfusePgCheckAvailableAddr(PADAPTER pAdapter,u8 efuseType,u8 bPseudoTest)2353 hal_EfusePgCheckAvailableAddr(
2354 PADAPTER pAdapter,
2355 u8 efuseType,
2356 u8 bPseudoTest)
2357 {
2358 u16 max_available=0;
2359 u16 current_size;
2360
2361
2362 EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &max_available, bPseudoTest);
2363 // DBG_8192C("%s: max_available=%d\n", __FUNCTION__, max_available);
2364
2365 current_size = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
2366 if (current_size >= max_available)
2367 {
2368 DBG_8192C("%s: Error!! current_size(%d)>max_available(%d)\n", __FUNCTION__, current_size, max_available);
2369 return _FALSE;
2370 }
2371 return _TRUE;
2372 }
2373
2374 static void
hal_EfuseConstructPGPkt(u8 offset,u8 word_en,u8 * pData,PPGPKT_STRUCT pTargetPkt)2375 hal_EfuseConstructPGPkt(
2376 u8 offset,
2377 u8 word_en,
2378 u8 *pData,
2379 PPGPKT_STRUCT pTargetPkt)
2380 {
2381 _rtw_memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
2382 pTargetPkt->offset = offset;
2383 pTargetPkt->word_en = word_en;
2384 efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
2385 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2386 }
2387
2388 #if 0
2389 static u8
2390 wordEnMatched(
2391 PPGPKT_STRUCT pTargetPkt,
2392 PPGPKT_STRUCT pCurPkt,
2393 u8 *pWden)
2394 {
2395 u8 match_word_en = 0x0F; // default all words are disabled
2396 u8 i;
2397
2398 // check if the same words are enabled both target and current PG packet
2399 if (((pTargetPkt->word_en & BIT(0)) == 0) &&
2400 ((pCurPkt->word_en & BIT(0)) == 0))
2401 {
2402 match_word_en &= ~BIT(0); // enable word 0
2403 }
2404 if (((pTargetPkt->word_en & BIT(1)) == 0) &&
2405 ((pCurPkt->word_en & BIT(1)) == 0))
2406 {
2407 match_word_en &= ~BIT(1); // enable word 1
2408 }
2409 if (((pTargetPkt->word_en & BIT(2)) == 0) &&
2410 ((pCurPkt->word_en & BIT(2)) == 0))
2411 {
2412 match_word_en &= ~BIT(2); // enable word 2
2413 }
2414 if (((pTargetPkt->word_en & BIT(3)) == 0) &&
2415 ((pCurPkt->word_en & BIT(3)) == 0))
2416 {
2417 match_word_en &= ~BIT(3); // enable word 3
2418 }
2419
2420 *pWden = match_word_en;
2421
2422 if (match_word_en != 0xf)
2423 return _TRUE;
2424 else
2425 return _FALSE;
2426 }
2427
2428 static u8
2429 hal_EfuseCheckIfDatafollowed(
2430 PADAPTER pAdapter,
2431 u8 word_cnts,
2432 u16 startAddr,
2433 u8 bPseudoTest)
2434 {
2435 u8 bRet=_FALSE;
2436 u8 i, efuse_data;
2437
2438 for (i=0; i<(word_cnts*2); i++)
2439 {
2440 if (efuse_OneByteRead(pAdapter, (startAddr+i) ,&efuse_data, bPseudoTest) == _FALSE)
2441 {
2442 DBG_8192C("%s: efuse_OneByteRead FAIL!!\n", __FUNCTION__);
2443 bRet = _TRUE;
2444 break;
2445 }
2446
2447 if (efuse_data != 0xFF)
2448 {
2449 bRet = _TRUE;
2450 break;
2451 }
2452 }
2453
2454 return bRet;
2455 }
2456 #endif
2457
2458 static u8
hal_EfusePartialWriteCheck(PADAPTER padapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,u8 bPseudoTest)2459 hal_EfusePartialWriteCheck(
2460 PADAPTER padapter,
2461 u8 efuseType,
2462 u16 *pAddr,
2463 PPGPKT_STRUCT pTargetPkt,
2464 u8 bPseudoTest)
2465 {
2466 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2467 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
2468 u8 bRet=_FALSE;
2469 u16 startAddr=0, efuse_max_available_len=0, efuse_max=0;
2470 u8 efuse_data=0;
2471 #if 0
2472 u8 i, cur_header=0;
2473 u8 new_wden=0, matched_wden=0, badworden=0;
2474 PGPKT_STRUCT curPkt;
2475 #endif
2476
2477
2478 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest);
2479 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest);
2480
2481 if (efuseType == EFUSE_WIFI)
2482 {
2483 if (bPseudoTest)
2484 {
2485 #ifdef HAL_EFUSE_MEMORY
2486 startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes;
2487 #else
2488 startAddr = (u16)fakeEfuseUsedBytes;
2489 #endif
2490 }
2491 else
2492 {
2493 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&startAddr);
2494 }
2495 }
2496 else
2497 {
2498 if (bPseudoTest)
2499 {
2500 #ifdef HAL_EFUSE_MEMORY
2501 startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes;
2502 #else
2503 startAddr = (u16)fakeBTEfuseUsedBytes;
2504 #endif
2505 }
2506 else
2507 {
2508 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&startAddr);
2509 }
2510 }
2511 startAddr %= efuse_max;
2512 DBG_8192C("%s: startAddr=%#X\n", __FUNCTION__, startAddr);
2513
2514 while (1)
2515 {
2516 if (startAddr >= efuse_max_available_len)
2517 {
2518 bRet = _FALSE;
2519 DBG_8192C("%s: startAddr(%d) >= efuse_max_available_len(%d)\n",
2520 __FUNCTION__, startAddr, efuse_max_available_len);
2521 break;
2522 }
2523
2524 if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data!=0xFF))
2525 {
2526 #if 1
2527 bRet = _FALSE;
2528 DBG_8192C("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n",
2529 __FUNCTION__, startAddr, efuse_data);
2530 break;
2531 #else
2532 if (EXT_HEADER(efuse_data))
2533 {
2534 cur_header = efuse_data;
2535 startAddr++;
2536 efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest);
2537 if (ALL_WORDS_DISABLED(efuse_data))
2538 {
2539 DBG_8192C("%s: Error condition, all words disabled!", __FUNCTION__);
2540 bRet = _FALSE;
2541 break;
2542 }
2543 else
2544 {
2545 curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2546 curPkt.word_en = efuse_data & 0x0F;
2547 }
2548 }
2549 else
2550 {
2551 cur_header = efuse_data;
2552 curPkt.offset = (cur_header>>4) & 0x0F;
2553 curPkt.word_en = cur_header & 0x0F;
2554 }
2555
2556 curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
2557 // if same header is found but no data followed
2558 // write some part of data followed by the header.
2559 if ((curPkt.offset == pTargetPkt->offset) &&
2560 (hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr+1, bPseudoTest) == _FALSE) &&
2561 wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == _TRUE)
2562 {
2563 DBG_8192C("%s: Need to partial write data by the previous wrote header\n", __FUNCTION__);
2564 // Here to write partial data
2565 badworden = Efuse_WordEnableDataWrite(padapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest);
2566 if (badworden != 0x0F)
2567 {
2568 u32 PgWriteSuccess=0;
2569 // if write fail on some words, write these bad words again
2570 if (efuseType == EFUSE_WIFI)
2571 PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2572 else
2573 PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2574
2575 if (!PgWriteSuccess)
2576 {
2577 bRet = _FALSE; // write fail, return
2578 break;
2579 }
2580 }
2581 // partial write ok, update the target packet for later use
2582 for (i=0; i<4; i++)
2583 {
2584 if ((matched_wden & (0x1<<i)) == 0) // this word has been written
2585 {
2586 pTargetPkt->word_en |= (0x1<<i); // disable the word
2587 }
2588 }
2589 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2590 }
2591 // read from next header
2592 startAddr = startAddr + (curPkt.word_cnts*2) + 1;
2593 #endif
2594 }
2595 else
2596 {
2597 // not used header, 0xff
2598 *pAddr = startAddr;
2599 // DBG_8192C("%s: Started from unused header offset=%d\n", __FUNCTION__, startAddr));
2600 bRet = _TRUE;
2601 break;
2602 }
2603 }
2604
2605 return bRet;
2606 }
2607
2608 BOOLEAN
hal_EfuseFixHeaderProcess(IN PADAPTER pAdapter,IN u1Byte efuseType,IN PPGPKT_STRUCT pFixPkt,IN pu2Byte pAddr,IN BOOLEAN bPseudoTest)2609 hal_EfuseFixHeaderProcess(
2610 IN PADAPTER pAdapter,
2611 IN u1Byte efuseType,
2612 IN PPGPKT_STRUCT pFixPkt,
2613 IN pu2Byte pAddr,
2614 IN BOOLEAN bPseudoTest
2615 )
2616 {
2617 u1Byte originaldata[8], badworden=0;
2618 u2Byte efuse_addr=*pAddr;
2619 u4Byte PgWriteSuccess=0;
2620
2621 _rtw_memset((PVOID)originaldata, 8, 0xff);
2622
2623 if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) {
2624 badworden = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr+1, pFixPkt->word_en, originaldata, bPseudoTest);
2625
2626 if (badworden != 0xf) {
2627
2628 PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest);
2629 if (!PgWriteSuccess)
2630 return FALSE;
2631 else
2632 efuse_addr = Hal_EfuseGetCurrentSize(pAdapter, efuseType, bPseudoTest);
2633 } else {
2634 efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) +1;
2635 }
2636 } else {
2637 efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) +1;
2638 }
2639
2640 *pAddr = efuse_addr;
2641 return TRUE;
2642 }
2643
2644 static u8
hal_EfusePgPacketWrite1ByteHeader(PADAPTER pAdapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,u8 bPseudoTest)2645 hal_EfusePgPacketWrite1ByteHeader(
2646 PADAPTER pAdapter,
2647 u8 efuseType,
2648 u16 *pAddr,
2649 PPGPKT_STRUCT pTargetPkt,
2650 u8 bPseudoTest)
2651 {
2652 u8 bRet=_FALSE;
2653 u8 pg_header=0, tmp_header=0;
2654 u16 efuse_addr=*pAddr;
2655 u8 repeatcnt=0;
2656
2657
2658 /* RTW_INFO("%s\n", __FUNCTION__); */
2659 pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
2660 if (IS_HARDWARE_TYPE_8723BE(pAdapter))
2661 efuse_OneByteWrite(pAdapter, 0x1FF, 00, FALSE); /* increase current */
2662
2663 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2664
2665 PHY_SetMacReg(pAdapter, EFUSE_TEST, BIT26, 0);
2666
2667 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2668
2669 PHY_SetMacReg(pAdapter, EFUSE_TEST, BIT26, 1);
2670
2671 while (tmp_header == 0xFF || pg_header != tmp_header) {
2672 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2673 DBG_871X("retry %d times fail!!\n", repeatcnt);
2674 return _FALSE;
2675 }
2676 efuse_OneByteWrite(pAdapter,efuse_addr, pg_header, bPseudoTest);
2677 efuse_OneByteRead(pAdapter,efuse_addr, &tmp_header, bPseudoTest);
2678 DBG_871X("===>%s: Keep %d-th retrying,pg_header = 0x%X tmp_header = 0x%X\n", __FUNCTION__,repeatcnt, pg_header, tmp_header);
2679 }
2680
2681 if (pg_header == tmp_header)
2682 bRet = _TRUE;
2683 else {
2684 PGPKT_STRUCT fixPkt;
2685
2686 DBG_871X(" pg_header(0x%X) != tmp_header(0x%X)\n", pg_header, tmp_header);
2687 DBG_871X("Error condition for fixed PG packet, need to cover the existed data: (Addr, Data) = (0x%X, 0x%X)\n",
2688 efuse_addr, tmp_header);
2689 fixPkt.offset = (tmp_header>>4) & 0x0F;
2690 fixPkt.word_en = tmp_header & 0x0F;
2691 fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
2692 if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
2693 return _FALSE;
2694 }
2695
2696 *pAddr = efuse_addr;
2697
2698 return _TRUE;
2699 }
2700
2701 static u8
hal_EfusePgPacketWrite2ByteHeader(PADAPTER padapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,u8 bPseudoTest)2702 hal_EfusePgPacketWrite2ByteHeader(
2703 PADAPTER padapter,
2704 u8 efuseType,
2705 u16 *pAddr,
2706 PPGPKT_STRUCT pTargetPkt,
2707 u8 bPseudoTest)
2708 {
2709 u16 efuse_addr, efuse_max_available_len=0;
2710 u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0;
2711 u8 repeatcnt=0;
2712
2713
2714 /* RTW_INFO("%s\n", __FUNCTION__); */
2715 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest);
2716
2717 efuse_addr = *pAddr;
2718
2719 if (efuse_addr >= efuse_max_available_len) {
2720 DBG_871X("%s: addr(%d) over avaliable(%d)!!\n", __FUNCTION__, efuse_addr, efuse_max_available_len);
2721 return _FALSE;
2722 }
2723
2724 while (efuse_addr < efuse_max_available_len) {
2725 pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
2726 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2727 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 0);
2728 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2729 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 1);
2730
2731 while (tmp_header == 0xFF || pg_header != tmp_header) {
2732 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2733 DBG_871X("%s, Repeat over limit for pg_header!!\n", __FUNCTION__);
2734 return _FALSE;
2735 }
2736
2737 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2738 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2739 }
2740
2741 /*to write ext_header*/
2742 if (tmp_header == pg_header) {
2743 efuse_addr++;
2744 pg_header_temp = pg_header;
2745 pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
2746
2747 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2748 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 0);
2749 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2750 PHY_SetMacReg(padapter, EFUSE_TEST, BIT26, 1);
2751
2752 while (tmp_header == 0xFF || pg_header != tmp_header) {
2753 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2754 DBG_871X("%s, Repeat over limit for ext_header!!\n", __FUNCTION__);
2755 return _FALSE;
2756 }
2757
2758 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2759 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2760 }
2761
2762 if ((tmp_header & 0x0F) == 0x0F) {
2763 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2764 DBG_871X("Repeat over limit for word_en!!\n");
2765 return _FALSE;
2766 } else {
2767 efuse_addr++;
2768 continue;
2769 }
2770 } else if (pg_header != tmp_header) {
2771 PGPKT_STRUCT fixPkt;
2772 DBG_871X("Error, efuse_PgPacketWrite2ByteHeader(), offset PG fail, need to cover the existed data!!\n");
2773 DBG_871X("Error condition for offset PG fail, need to cover the existed data\n");
2774 fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
2775 fixPkt.word_en = tmp_header & 0x0F;
2776 fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
2777 if (!hal_EfuseFixHeaderProcess(padapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
2778 return _FALSE;
2779 } else
2780 break;
2781 } else if ((tmp_header & 0x1F) == 0x0F) {/*wrong extended header*/
2782 efuse_addr += 2;
2783 continue;
2784 }
2785 }
2786
2787 *pAddr = efuse_addr;
2788
2789 return _TRUE;
2790 }
2791
2792 static u8
hal_EfusePgPacketWriteHeader(PADAPTER padapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,u8 bPseudoTest)2793 hal_EfusePgPacketWriteHeader(
2794 PADAPTER padapter,
2795 u8 efuseType,
2796 u16 *pAddr,
2797 PPGPKT_STRUCT pTargetPkt,
2798 u8 bPseudoTest)
2799 {
2800 u8 bRet=_FALSE;
2801
2802 if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
2803 {
2804 bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2805 }
2806 else
2807 {
2808 bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2809 }
2810
2811 return bRet;
2812 }
2813
2814 static u8
hal_EfusePgPacketWriteData(PADAPTER pAdapter,u8 efuseType,u16 * pAddr,PPGPKT_STRUCT pTargetPkt,u8 bPseudoTest)2815 hal_EfusePgPacketWriteData(
2816 PADAPTER pAdapter,
2817 u8 efuseType,
2818 u16 *pAddr,
2819 PPGPKT_STRUCT pTargetPkt,
2820 u8 bPseudoTest)
2821 {
2822 u16 efuse_addr;
2823 u8 badworden;
2824 u8 PgWriteSuccess = 0;
2825
2826
2827 efuse_addr = *pAddr;
2828 badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
2829 if (badworden == 0x0F) {
2830 DBG_871X("%s: Fail!!\n", __FUNCTION__);
2831 return _TRUE;
2832 } else { /* Reorganize other pg packet */
2833 DBG_871X ("Error, efuse_PgPacketWriteData(), wirte data fail!!\n");
2834 DBG_871X ("efuse_PgPacketWriteData Fail!!\n");
2835 PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2836 if (!PgWriteSuccess)
2837 return FALSE;
2838 else
2839 return TRUE;
2840 }
2841
2842 return _TRUE;
2843 }
2844
2845 static s32
Hal_EfusePgPacketWrite(PADAPTER padapter,u8 offset,u8 word_en,u8 * pData,u8 bPseudoTest)2846 Hal_EfusePgPacketWrite(
2847 PADAPTER padapter,
2848 u8 offset,
2849 u8 word_en,
2850 u8 *pData,
2851 u8 bPseudoTest)
2852 {
2853 PGPKT_STRUCT targetPkt;
2854 u16 startAddr=0;
2855 u8 efuseType=EFUSE_WIFI;
2856
2857 if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest))
2858 return _FALSE;
2859
2860 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2861
2862 if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2863 return _FALSE;
2864
2865 if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2866 return _FALSE;
2867
2868 if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2869 return _FALSE;
2870
2871 return _TRUE;
2872 }
2873
2874 static u8
Hal_EfusePgPacketWrite_BT(PADAPTER pAdapter,u8 offset,u8 word_en,u8 * pData,u8 bPseudoTest)2875 Hal_EfusePgPacketWrite_BT(
2876 PADAPTER pAdapter,
2877 u8 offset,
2878 u8 word_en,
2879 u8 *pData,
2880 u8 bPseudoTest)
2881 {
2882 PGPKT_STRUCT targetPkt;
2883 u16 startAddr=0;
2884 u8 efuseType=EFUSE_BT;
2885
2886 if(!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
2887 return _FALSE;
2888
2889 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2890
2891 if(!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2892 return _FALSE;
2893
2894 if(!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2895 return _FALSE;
2896
2897 if(!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2898 return _FALSE;
2899
2900 return _TRUE;
2901 }
2902
2903
read_chip_version_8723b(PADAPTER padapter)2904 static void read_chip_version_8723b(PADAPTER padapter)
2905 {
2906 u32 value32;
2907 HAL_DATA_TYPE *pHalData;
2908 pHalData = GET_HAL_DATA(padapter);
2909
2910 value32 = rtw_read32(padapter, REG_SYS_CFG);
2911 pHalData->VersionID.ICType = CHIP_8723B;
2912 pHalData->VersionID.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
2913 pHalData->VersionID.RFType = RF_TYPE_1T1R ;
2914 pHalData->VersionID.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
2915 pHalData->VersionID.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; // IC version (CUT)
2916
2917 // For regulator mode. by tynli. 2011.01.14
2918 pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
2919
2920 value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
2921 pHalData->VersionID.ROMVer = ((value32 & RF_RL_ID) >> 20); // ROM code version.
2922
2923 // For multi-function consideration. Added by Roger, 2010.10.06.
2924 pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
2925 value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
2926 pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
2927 pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
2928 pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
2929 pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT);
2930
2931 rtw_hal_config_rftype(padapter);
2932
2933 /* // mark for chage to use efuse
2934 if( IS_B_CUT(pHalData->VersionID) || IS_C_CUT(pHalData->VersionID))
2935 {
2936 MSG_8192C(" IS_B/C_CUT SWR up 1 level !!!!!!!!!!!!!!!!!\n");
2937 PHY_SetMacReg(padapter, 0x14, BIT23|BIT22|BIT21|BIT20, 0x5); //MAC reg 0x14[23:20] = 4b'0101 (SWR 1.220V)
2938 }else if ( IS_D_CUT(pHalData->VersionID))
2939 {
2940 MSG_8192C(" IS_D_CUT SKIP SWR !!!!!!!!!!!!!!!!!\n");
2941 }
2942 */
2943
2944 #if 1
2945 dump_chip_info(pHalData->VersionID);
2946 #endif
2947
2948 }
2949
2950
rtl8723b_InitBeaconParameters(PADAPTER padapter)2951 void rtl8723b_InitBeaconParameters(PADAPTER padapter)
2952 {
2953 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2954 u16 val16;
2955 u8 val8;
2956
2957
2958 val8 = DIS_TSF_UDT;
2959 val16 = val8 | (val8 << 8); // port0 and port1
2960 #ifdef CONFIG_BT_COEXIST
2961 // Enable prot0 beacon function for PSTDMA
2962 val16 |= EN_BCN_FUNCTION;
2963 #endif
2964 rtw_write16(padapter, REG_BCN_CTRL, val16);
2965
2966 // TODO: Remove these magic number
2967 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);// ms
2968 // Firmware will control REG_DRVERLYINT when power saving is enable,
2969 // so don't set this register on STA mode.
2970 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _FALSE)
2971 rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8723B); // 5ms
2972 rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8723B); // 2ms
2973
2974 // Suggested by designer timchen. Change beacon AIFS to the largest number
2975 // beacause test chip does not contension before sending beacon. by tynli. 2009.11.03
2976 rtw_write16(padapter, REG_BCNTCFG, 0x660F);
2977
2978 pHalData->RegBcnCtrlVal = rtw_read8(padapter, REG_BCN_CTRL);
2979 pHalData->RegTxPause = rtw_read8(padapter, REG_TXPAUSE);
2980 pHalData->RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL+2);
2981 pHalData->RegReg542 = rtw_read8(padapter, REG_TBTT_PROHIBIT+2);
2982 pHalData->RegCR_1 = rtw_read8(padapter, REG_CR+1);
2983 }
2984
rtl8723b_InitBeaconMaxError(PADAPTER padapter,u8 InfraMode)2985 void rtl8723b_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode)
2986 {
2987 #ifdef CONFIG_ADHOC_WORKAROUND_SETTING
2988 rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
2989 #else
2990 //rtw_write8(Adapter, REG_BCN_MAX_ERR, (InfraMode ? 0xFF : 0x10));
2991 #endif
2992 }
2993
_InitBurstPktLen_8723BS(PADAPTER Adapter)2994 void _InitBurstPktLen_8723BS(PADAPTER Adapter)
2995 {
2996 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
2997
2998 rtw_write8(Adapter, 0x4c7,rtw_read8(Adapter, 0x4c7)|BIT(7)); //enable single pkt ampdu
2999 rtw_write8(Adapter, REG_RX_PKT_LIMIT_8723B, 0x18); //for VHT packet length 11K
3000 rtw_write8(Adapter, REG_MAX_AGGR_NUM_8723B, 0x1F);
3001 rtw_write8(Adapter, REG_PIFS_8723B, 0x00);
3002 rtw_write8(Adapter, REG_FWHW_TXQ_CTRL_8723B, rtw_read8(Adapter, REG_FWHW_TXQ_CTRL)&(~BIT(7)));
3003 if(pHalData->AMPDUBurstMode)
3004 {
3005 rtw_write8(Adapter,REG_AMPDU_BURST_MODE_8723B, 0x5F);
3006 }
3007 rtw_write8(Adapter, REG_AMPDU_MAX_TIME_8723B, 0x70);
3008
3009 // ARFB table 9 for 11ac 5G 2SS
3010 rtw_write32(Adapter, REG_ARFR0_8723B, 0x00000010);
3011 if(IS_NORMAL_CHIP(pHalData->VersionID))
3012 rtw_write32(Adapter, REG_ARFR0_8723B+4, 0xfffff000);
3013 else
3014 rtw_write32(Adapter, REG_ARFR0_8723B+4, 0x3e0ff000);
3015
3016 // ARFB table 10 for 11ac 5G 1SS
3017 rtw_write32(Adapter, REG_ARFR1_8723B, 0x00000010);
3018 rtw_write32(Adapter, REG_ARFR1_8723B+4, 0x003ff000);
3019 }
3020
ResumeTxBeacon(PADAPTER padapter)3021 static void ResumeTxBeacon(PADAPTER padapter)
3022 {
3023 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3024
3025
3026 // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
3027 // which should be read from register to a global variable.
3028
3029 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
3030
3031 pHalData->RegFwHwTxQCtrl |= BIT(6);
3032 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
3033 rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0xff);
3034 pHalData->RegReg542 |= BIT(0);
3035 rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
3036 }
3037
StopTxBeacon(PADAPTER padapter)3038 static void StopTxBeacon(PADAPTER padapter)
3039 {
3040 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3041
3042
3043 // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
3044 // which should be read from register to a global variable.
3045
3046 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
3047
3048 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
3049 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
3050 rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64);
3051 pHalData->RegReg542 &= ~BIT(0);
3052 rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
3053
3054 CheckFwRsvdPageContent(padapter); // 2010.06.23. Added by tynli.
3055 }
3056
_BeaconFunctionEnable(PADAPTER padapter,u8 Enable,u8 Linked)3057 static void _BeaconFunctionEnable(PADAPTER padapter, u8 Enable, u8 Linked)
3058 {
3059 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
3060 rtw_write8(padapter, REG_RD_CTRL+1, 0x6F);
3061 }
3062
rtl8723b_SetBeaconRelatedRegisters(PADAPTER padapter)3063 static void rtl8723b_SetBeaconRelatedRegisters(PADAPTER padapter)
3064 {
3065 u8 val8;
3066 u32 value32;
3067 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3068 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3069 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3070 u32 bcn_ctrl_reg;
3071
3072 //reset TSF, enable update TSF, correcting TSF On Beacon
3073
3074 //REG_BCN_INTERVAL
3075 //REG_BCNDMATIM
3076 //REG_ATIMWND
3077 //REG_TBTT_PROHIBIT
3078 //REG_DRVERLYINT
3079 //REG_BCN_MAX_ERR
3080 //REG_BCNTCFG //(0x510)
3081 //REG_DUAL_TSF_RST
3082 //REG_BCN_CTRL //(0x550)
3083
3084
3085 bcn_ctrl_reg = REG_BCN_CTRL;
3086 #ifdef CONFIG_CONCURRENT_MODE
3087 if (padapter->iface_type == IFACE_PORT1)
3088 bcn_ctrl_reg = REG_BCN_CTRL_1;
3089 #endif
3090
3091 //
3092 // ATIM window
3093 //
3094 rtw_write16(padapter, REG_ATIMWND, 2);
3095
3096 //
3097 // Beacon interval (in unit of TU).
3098 //
3099 rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
3100
3101 rtl8723b_InitBeaconParameters(padapter);
3102
3103 rtw_write8(padapter, REG_SLOT, 0x09);
3104
3105 //
3106 // Reset TSF Timer to zero, added by Roger. 2008.06.24
3107 //
3108 value32 = rtw_read32(padapter, REG_TCR);
3109 value32 &= ~TSFRST;
3110 rtw_write32(padapter, REG_TCR, value32);
3111
3112 value32 |= TSFRST;
3113 rtw_write32(padapter, REG_TCR, value32);
3114
3115 // NOTE: Fix test chip's bug (about contention windows's randomness)
3116 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == _TRUE)
3117 {
3118 rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
3119 rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
3120 }
3121
3122 _BeaconFunctionEnable(padapter, _TRUE, _TRUE);
3123
3124 ResumeTxBeacon(padapter);
3125 val8 = rtw_read8(padapter, bcn_ctrl_reg);
3126 val8 |= DIS_BCNQ_SUB;
3127 rtw_write8(padapter, bcn_ctrl_reg, val8);
3128 }
3129
hal_notch_filter_8723b(_adapter * adapter,bool enable)3130 void hal_notch_filter_8723b(_adapter *adapter, bool enable)
3131 {
3132 if (enable) {
3133 DBG_871X("Enable notch filter\n");
3134 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
3135 } else {
3136 DBG_871X("Disable notch filter\n");
3137 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
3138 }
3139 }
3140
rtl8723b_MRateIdxToARFRId(PADAPTER padapter,u8 rate_idx)3141 u8 rtl8723b_MRateIdxToARFRId(PADAPTER padapter, u8 rate_idx)
3142 {
3143 u8 ret = 0;
3144 RT_RF_TYPE_DEF_E rftype = (RT_RF_TYPE_DEF_E)GET_RF_TYPE(padapter);
3145 switch(rate_idx){
3146
3147 case RATR_INX_WIRELESS_NGB:
3148 if(rftype == RF_1T1R)
3149 ret = 1;
3150 else
3151 ret = 0;
3152 break;
3153
3154 case RATR_INX_WIRELESS_N:
3155 case RATR_INX_WIRELESS_NG:
3156 if(rftype == RF_1T1R)
3157 ret = 5;
3158 else
3159 ret = 4;
3160 break;
3161
3162 case RATR_INX_WIRELESS_NB:
3163 if(rftype == RF_1T1R)
3164 ret = 3;
3165 else
3166 ret = 2;
3167 break;
3168
3169 case RATR_INX_WIRELESS_GB:
3170 ret = 6;
3171 break;
3172
3173 case RATR_INX_WIRELESS_G:
3174 ret = 7;
3175 break;
3176
3177 case RATR_INX_WIRELESS_B:
3178 ret = 8;
3179 break;
3180
3181 case RATR_INX_WIRELESS_MC:
3182 if(padapter->mlmeextpriv.cur_wireless_mode & WIRELESS_11BG_24N)
3183 ret = 6;
3184 else
3185 ret = 7;
3186 break;
3187 case RATR_INX_WIRELESS_AC_N:
3188 if(rftype == RF_1T1R)// || padapter->MgntInfo.VHTHighestOperaRate <= MGN_VHT1SS_MCS9)
3189 ret = 10;
3190 else
3191 ret = 9;
3192 break;
3193
3194 default:
3195 ret = 0;
3196 break;
3197 }
3198
3199 return ret;
3200 }
3201
UpdateHalRAMask8723B(PADAPTER padapter,u32 mac_id,u8 rssi_level)3202 void UpdateHalRAMask8723B(PADAPTER padapter, u32 mac_id, u8 rssi_level)
3203 {
3204 u32 mask,rate_bitmap;
3205 u8 shortGIrate = _FALSE;
3206 struct sta_info *psta = NULL;
3207 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3208 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3209 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3210 struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl;
3211
3212 if (mac_id < macid_ctl->num)
3213 psta = macid_ctl->sta[mac_id];
3214 if (psta == NULL) {
3215 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" macid:%u, sta is NULL\n"
3216 , FUNC_ADPT_ARG(padapter), mac_id);
3217 return;
3218 }
3219
3220 shortGIrate = query_ra_short_GI(psta);
3221
3222 mask = psta->ra_mask;
3223
3224 rate_bitmap = 0xffffffff;
3225 rate_bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv,mac_id,mask,rssi_level);
3226 DBG_871X("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
3227 __FUNCTION__,mac_id,psta->wireless_mode,mask,rssi_level,rate_bitmap);
3228
3229 mask &= rate_bitmap;
3230
3231 #ifdef CONFIG_BT_COEXIST
3232 rate_bitmap = rtw_btcoex_GetRaMask(padapter);
3233 mask &= ~rate_bitmap;
3234 #endif // CONFIG_BT_COEXIST
3235
3236 #ifdef CONFIG_CMCC_TEST
3237 #ifdef CONFIG_BT_COEXIST
3238 if(pmlmeext->cur_wireless_mode & WIRELESS_11G) {
3239 if (mac_id == 0) {
3240 DBG_871X("CMCC_BT update raid entry, mask=0x%x\n", mask);
3241 //mask &=0xffffffc0; //disable CCK & <12M OFDM rate for 11G mode for CMCC
3242 mask &=0xffffff00; //disable CCK & <24M OFDM rate for 11G mode for CMCC
3243 DBG_871X("CMCC_BT update raid entry, mask=0x%x\n", mask);
3244 }
3245 }
3246 #endif
3247 #endif
3248
3249 if(pHalData->fw_ractrl == _TRUE)
3250 {
3251 rtl8723b_set_FwMacIdConfig_cmd(padapter, mac_id, psta->raid, psta->bw_mode, shortGIrate, mask);
3252 }
3253
3254 //set correct initial date rate for each mac_id
3255 pHalData->INIDATA_RATE[mac_id] = psta->init_rate;
3256 DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x init_rate=0x%x\n", __func__, mac_id, psta->raid, psta->bw_mode, mask, psta->init_rate);
3257 }
3258
3259 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
rtl8723b_cal_txdesc_chksum(struct tx_desc * ptxdesc)3260 void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc)
3261 {
3262 u16 *usPtr = (u16*)ptxdesc;
3263 u32 count;
3264 u32 index;
3265 u16 checksum = 0;
3266
3267
3268 // Clear first
3269 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
3270
3271 // checksume is always calculated by first 32 bytes,
3272 // and it doesn't depend on TX DESC length.
3273 // Thomas,Lucas@SD4,20130515
3274 count = 16;
3275
3276 for (index = 0; index < count; index++) {
3277 checksum ^= le16_to_cpu(*(usPtr + index));
3278 }
3279
3280 ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
3281 }
3282 #endif
3283
3284
3285 //
3286 // Description: In normal chip, we should send some packet to Hw which will be used by Fw
3287 // in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
3288 // Fw can tell Hw to send these packet derectly.
3289 // Added by tynli. 2009.10.15.
3290 //
3291 //type1:pspoll, type2:null
rtl8723b_fill_fake_txdesc(PADAPTER padapter,u8 * pDesc,u32 BufferLen,u8 IsPsPoll,u8 IsBTQosNull,u8 bDataFrame)3292 void rtl8723b_fill_fake_txdesc(
3293 PADAPTER padapter,
3294 u8* pDesc,
3295 u32 BufferLen,
3296 u8 IsPsPoll,
3297 u8 IsBTQosNull,
3298 u8 bDataFrame)
3299 {
3300 // Clear all status
3301 _rtw_memset(pDesc, 0, TXDESC_SIZE);
3302
3303 SET_TX_DESC_FIRST_SEG_8723B(pDesc, 1); //bFirstSeg;
3304 SET_TX_DESC_LAST_SEG_8723B(pDesc, 1); //bLastSeg;
3305
3306 SET_TX_DESC_OFFSET_8723B(pDesc, 0x28); // Offset = 32
3307
3308 SET_TX_DESC_PKT_SIZE_8723B(pDesc, BufferLen); // Buffer size + command header
3309 SET_TX_DESC_QUEUE_SEL_8723B(pDesc, QSLT_MGNT); // Fixed queue of Mgnt queue
3310
3311 // Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
3312 if (_TRUE == IsPsPoll)
3313 {
3314 SET_TX_DESC_NAV_USE_HDR_8723B(pDesc, 1);
3315 }
3316 else
3317 {
3318 SET_TX_DESC_HWSEQ_EN_8723B(pDesc, 1); // Hw set sequence number
3319 SET_TX_DESC_HWSEQ_SEL_8723B(pDesc, 0);
3320 }
3321
3322 if (_TRUE ==IsBTQosNull)
3323 {
3324 SET_TX_DESC_BT_INT_8723B(pDesc, 1);
3325 }
3326
3327 SET_TX_DESC_USE_RATE_8723B(pDesc, 1); // use data rate which is set by Sw
3328 SET_TX_DESC_OWN_8723B((pu1Byte)pDesc, 1);
3329
3330 SET_TX_DESC_TX_RATE_8723B(pDesc, DESC8723B_RATE1M);
3331
3332 //
3333 // Encrypt the data frame if under security mode excepct null data. Suggested by CCW.
3334 //
3335 if (_TRUE ==bDataFrame)
3336 {
3337 u32 EncAlg;
3338
3339 EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
3340 switch (EncAlg)
3341 {
3342 case _NO_PRIVACY_:
3343 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0);
3344 break;
3345 case _WEP40_:
3346 case _WEP104_:
3347 case _TKIP_:
3348 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x1);
3349 break;
3350 case _SMS4_:
3351 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x2);
3352 break;
3353 case _AES_:
3354 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x3);
3355 break;
3356 default:
3357 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0);
3358 break;
3359 }
3360 }
3361
3362 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3363 // USB interface drop packet if the checksum of descriptor isn't correct.
3364 // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
3365 rtl8723b_cal_txdesc_chksum((struct tx_desc*)pDesc);
3366 #endif
3367 }
3368
rtl8723b_set_hal_ops(struct hal_ops * pHalFunc)3369 void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc)
3370 {
3371 pHalFunc->dm_init = &rtl8723b_init_dm_priv;
3372 pHalFunc->dm_deinit = &rtl8723b_deinit_dm_priv;
3373
3374 pHalFunc->read_chip_version = read_chip_version_8723b;
3375
3376 pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8723B;
3377 pHalFunc->set_bwmode_handler = &PHY_SetBWMode8723B;
3378 pHalFunc->set_channel_handler = &PHY_SwChnl8723B;
3379 pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8723B;
3380
3381 pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8723B;
3382 pHalFunc->get_tx_power_level_handler = &PHY_GetTxPowerLevel8723B;
3383
3384 pHalFunc->hal_dm_watchdog = &rtl8723b_HalDmWatchDog;
3385 #ifdef CONFIG_LPS_LCLK_WD_TIMER
3386 pHalFunc->hal_dm_watchdog_in_lps = &rtl8723b_HalDmWatchDog_in_LPS;
3387 #endif
3388
3389 #ifdef CONFIG_C2H_PACKET_EN
3390 pHalFunc->SetHwRegHandlerWithBuf = &SetHwRegWithBuf8723B;
3391 #endif // CONFIG_C2H_PACKET_EN
3392
3393 pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8723b_SetBeaconRelatedRegisters;
3394
3395 pHalFunc->Add_RateATid = &rtl8723b_Add_RateATid;
3396
3397 pHalFunc->run_thread= &rtl8723b_start_thread;
3398 pHalFunc->cancel_thread= &rtl8723b_stop_thread;
3399
3400 pHalFunc->read_bbreg = &PHY_QueryBBReg_8723B;
3401 pHalFunc->write_bbreg = &PHY_SetBBReg_8723B;
3402 pHalFunc->read_rfreg = &PHY_QueryRFReg_8723B;
3403 pHalFunc->write_rfreg = &PHY_SetRFReg_8723B;
3404
3405 // Efuse related function
3406 pHalFunc->BTEfusePowerSwitch = &Hal_BT_EfusePowerSwitch;
3407 pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch;
3408 pHalFunc->ReadEFuse = &Hal_ReadEFuse;
3409 pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition;
3410 pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize;
3411 pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead;
3412 pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite;
3413 pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite;
3414 pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT;
3415
3416 #ifdef DBG_CONFIG_ERROR_DETECT
3417 pHalFunc->sreset_init_value = &sreset_init_value;
3418 pHalFunc->sreset_reset_value = &sreset_reset_value;
3419 pHalFunc->silentreset = &sreset_reset;
3420 pHalFunc->sreset_xmit_status_check = &rtl8723b_sreset_xmit_status_check;
3421 pHalFunc->sreset_linked_status_check = &rtl8723b_sreset_linked_status_check;
3422 pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status;
3423 pHalFunc->sreset_inprogress= &sreset_inprogress;
3424 #endif
3425 pHalFunc->GetHalODMVarHandler = GetHalODMVar;
3426 pHalFunc->SetHalODMVarHandler = SetHalODMVar;
3427
3428 #ifdef CONFIG_XMIT_THREAD_MODE
3429 pHalFunc->xmit_thread_handler = &hal_xmit_handler;
3430 #endif
3431 pHalFunc->hal_notch_filter = &hal_notch_filter_8723b;
3432
3433 pHalFunc->c2h_handler = c2h_handler_8723b;
3434 pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8723b;
3435
3436 pHalFunc->fill_h2c_cmd = &FillH2CCmd8723B;
3437 pHalFunc->fill_fake_txdesc = &rtl8723b_fill_fake_txdesc;
3438 pHalFunc->fw_dl = &rtl8723b_FirmwareDownload;
3439 pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8723B;
3440 #ifdef CONFIG_GPIO_API
3441 pHalFunc->hal_gpio_func_check = &rtl8723b_GpioFuncCheck;
3442 pHalFunc->hal_gpio_multi_func_reset = &rtl8723b_GpioMultiFuncReset;
3443 #endif
3444
3445 }
3446
rtl8723b_InitAntenna_Selection(PADAPTER padapter)3447 void rtl8723b_InitAntenna_Selection(PADAPTER padapter)
3448 {
3449 PHAL_DATA_TYPE pHalData;
3450 u8 val;
3451
3452
3453 pHalData = GET_HAL_DATA(padapter);
3454
3455 val = rtw_read8(padapter, REG_LEDCFG2);
3456 // Let 8051 take control antenna settting
3457 val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
3458 rtw_write8(padapter, REG_LEDCFG2, val);
3459 }
3460
rtl8723b_CheckAntenna_Selection(PADAPTER padapter)3461 void rtl8723b_CheckAntenna_Selection(PADAPTER padapter)
3462 {
3463 PHAL_DATA_TYPE pHalData;
3464 u8 val;
3465
3466
3467 pHalData = GET_HAL_DATA(padapter);
3468
3469 val = rtw_read8(padapter, REG_LEDCFG2);
3470 // Let 8051 take control antenna settting
3471 if(!(val &BIT(7))){
3472 val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
3473 rtw_write8(padapter, REG_LEDCFG2, val);
3474 }
3475 }
rtl8723b_DeinitAntenna_Selection(PADAPTER padapter)3476 void rtl8723b_DeinitAntenna_Selection(PADAPTER padapter)
3477 {
3478 PHAL_DATA_TYPE pHalData;
3479 u8 val;
3480
3481
3482 pHalData = GET_HAL_DATA(padapter);
3483 val = rtw_read8(padapter, REG_LEDCFG2);
3484 // Let 8051 take control antenna settting
3485 val &= ~BIT(7); // DPDT_SEL_EN, clear 0x4C[23]
3486 rtw_write8(padapter, REG_LEDCFG2, val);
3487
3488 }
3489
init_hal_spec_8723b(_adapter * adapter)3490 void init_hal_spec_8723b(_adapter *adapter)
3491 {
3492 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3493
3494 hal_spec->macid_num = MACID_NUM_8723B;
3495 hal_spec->sec_cam_ent_num = SEC_CAM_ENT_NUM_8723B;
3496 hal_spec->sec_cap = 0;
3497 hal_spec->nss_num = NSS_NUM_8723B;
3498 hal_spec->band_cap = BAND_CAP_8723B;
3499 hal_spec->bw_cap = BW_CAP_8723B;
3500 hal_spec->proto_cap = PROTO_CAP_8723B;
3501
3502 hal_spec->wl_func = 0
3503 | WL_FUNC_P2P
3504 | WL_FUNC_MIRACAST
3505 | WL_FUNC_TDLS
3506 ;
3507 }
3508
rtl8723b_init_default_value(PADAPTER padapter)3509 void rtl8723b_init_default_value(PADAPTER padapter)
3510 {
3511 PHAL_DATA_TYPE pHalData;
3512 u8 i;
3513 pHalData = GET_HAL_DATA(padapter);
3514
3515 padapter->registrypriv.wireless_mode = WIRELESS_11BG_24N;
3516
3517 // init default value
3518 pHalData->fw_ractrl = _FALSE;
3519 if (!adapter_to_pwrctl(padapter)->bkeepfwalive)
3520 pHalData->LastHMEBoxNum = 0;
3521
3522 //init phydm default value
3523 pHalData->bIQKInitialized = _FALSE;
3524 pHalData->odmpriv.RFCalibrateInfo.TM_Trigger = 0;//for IQK
3525 pHalData->odmpriv.RFCalibrateInfo.ThermalValue_HP_index = 0;
3526 for(i = 0; i < HP_THERMAL_NUM; i++)
3527 pHalData->odmpriv.RFCalibrateInfo.ThermalValue_HP[i] = 0;
3528
3529 // init Efuse variables
3530 pHalData->EfuseUsedBytes = 0;
3531 pHalData->EfuseUsedPercentage = 0;
3532 #ifdef HAL_EFUSE_MEMORY
3533 pHalData->EfuseHal.fakeEfuseBank = 0;
3534 pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
3535 _rtw_memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
3536 _rtw_memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
3537 _rtw_memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
3538 pHalData->EfuseHal.BTEfuseUsedBytes = 0;
3539 pHalData->EfuseHal.BTEfuseUsedPercentage = 0;
3540 _rtw_memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
3541 _rtw_memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3542 _rtw_memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3543 pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0;
3544 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
3545 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3546 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3547 #endif
3548 }
3549
GetEEPROMSize8723B(PADAPTER padapter)3550 u8 GetEEPROMSize8723B(PADAPTER padapter)
3551 {
3552 u8 size = 0;
3553 u32 cr;
3554
3555 cr = rtw_read16(padapter, REG_9346CR);
3556 // 6: EEPROM used is 93C46, 4: boot from E-Fuse.
3557 size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
3558
3559 MSG_8192C("EEPROM type is %s\n", size==4 ? "E-FUSE" : "93C46");
3560
3561 return size;
3562 }
3563
3564 //-------------------------------------------------------------------------
3565 //
3566 // LLT R/W/Init function
3567 //
3568 //-------------------------------------------------------------------------
rtl8723b_InitLLTTable(PADAPTER padapter)3569 s32 rtl8723b_InitLLTTable(PADAPTER padapter)
3570 {
3571 u32 start, passing_time;
3572 u32 val32;
3573 s32 ret;
3574
3575
3576 ret = _FAIL;
3577
3578 val32 = rtw_read32(padapter, REG_AUTO_LLT);
3579 val32 |= BIT_AUTO_INIT_LLT;
3580 rtw_write32(padapter, REG_AUTO_LLT, val32);
3581
3582 start = rtw_get_current_time();
3583
3584 do {
3585 val32 = rtw_read32(padapter, REG_AUTO_LLT);
3586 if (!(val32 & BIT_AUTO_INIT_LLT))
3587 {
3588 ret = _SUCCESS;
3589 break;
3590 }
3591
3592 passing_time = rtw_get_passing_time_ms(start);
3593 if (passing_time > 1000)
3594 {
3595 DBG_8192C("%s: FAIL!! REG_AUTO_LLT(0x%X)=%08x\n",
3596 __FUNCTION__, REG_AUTO_LLT, val32);
3597 break;
3598 }
3599
3600 rtw_usleep_os(2);
3601 } while(1);
3602
3603 return ret;
3604 }
3605
3606 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
_DisableGPIO(PADAPTER padapter)3607 void _DisableGPIO(PADAPTER padapter)
3608 {
3609 /***************************************
3610 j. GPIO_PIN_CTRL 0x44[31:0]=0x000 //
3611 k.Value = GPIO_PIN_CTRL[7:0]
3612 l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); //write external PIN level
3613 m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
3614 n. LEDCFG 0x4C[15:0] = 0x8080
3615 ***************************************/
3616 u8 value8;
3617 u16 value16;
3618 u32 value32;
3619 u32 u4bTmp;
3620
3621
3622 //1. Disable GPIO[7:0]
3623 rtw_write16(padapter, REG_GPIO_PIN_CTRL+2, 0x0000);
3624 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
3625 u4bTmp = value32 & 0x000000FF;
3626 value32 |= ((u4bTmp<<8) | 0x00FF0000);
3627 rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32);
3628
3629
3630 //2. Disable GPIO[10:8]
3631 rtw_write8(padapter, REG_MAC_PINMUX_CFG, 0x00);
3632 value16 = rtw_read16(padapter, REG_GPIO_IO_SEL) & 0xFF0F;
3633 value8 = (u8) (value16&0x000F);
3634 value16 |= ((value8<<4) | 0x0780);
3635 rtw_write16(padapter, REG_GPIO_IO_SEL, value16);
3636
3637
3638 //3. Disable LED0 & 1
3639 rtw_write16(padapter, REG_LEDCFG0, 0x8080);
3640
3641 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable GPIO and LED.\n"));
3642 } //end of _DisableGPIO()
3643
_DisableRFAFEAndResetBB8723B(PADAPTER padapter)3644 void _DisableRFAFEAndResetBB8723B(PADAPTER padapter)
3645 {
3646 /**************************************
3647 a. TXPAUSE 0x522[7:0] = 0xFF //Pause MAC TX queue
3648 b. RF path 0 offset 0x00 = 0x00 // disable RF
3649 c. APSD_CTRL 0x600[7:0] = 0x40
3650 d. SYS_FUNC_EN 0x02[7:0] = 0x16 //reset BB state machine
3651 e. SYS_FUNC_EN 0x02[7:0] = 0x14 //reset BB state machine
3652 ***************************************/
3653 u8 eRFPath = 0, value8 = 0;
3654
3655 rtw_write8(padapter, REG_TXPAUSE, 0xFF);
3656
3657 PHY_SetRFReg(padapter, (RF_PATH)eRFPath, 0x0, bMaskByte0, 0x0);
3658
3659 value8 |= APSDOFF;
3660 rtw_write8(padapter, REG_APSD_CTRL, value8);//0x40
3661
3662 // Set BB reset at first
3663 value8 = 0 ;
3664 value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
3665 rtw_write8(padapter, REG_SYS_FUNC_EN, value8 );//0x16
3666
3667 // Set global reset.
3668 value8 &= ~FEN_BB_GLB_RSTn;
3669 rtw_write8(padapter, REG_SYS_FUNC_EN, value8); //0x14
3670
3671 // 2010/08/12 MH We need to set BB/GLBAL reset to save power for SS mode.
3672
3673 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n"));
3674 }
3675
_DisableRFAFEAndResetBB(PADAPTER padapter)3676 void _DisableRFAFEAndResetBB(PADAPTER padapter)
3677 {
3678 _DisableRFAFEAndResetBB8723B(padapter);
3679 }
3680
_ResetDigitalProcedure1_8723B(PADAPTER padapter,BOOLEAN bWithoutHWSM)3681 void _ResetDigitalProcedure1_8723B(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3682 {
3683 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3684
3685 if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20))
3686 {
3687 #if 0
3688 /*****************************
3689 f. SYS_FUNC_EN 0x03[7:0]=0x54 // reset MAC register, DCORE
3690 g. MCUFWDL 0x80[7:0]=0 // reset MCU ready status
3691 ******************************/
3692 u32 value32 = 0;
3693 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x54);
3694 rtw_write8(padapter, REG_MCUFWDL, 0);
3695 #else
3696 /*****************************
3697 f. MCUFWDL 0x80[7:0]=0 // reset MCU ready status
3698 g. SYS_FUNC_EN 0x02[10]= 0 // reset MCU register, (8051 reset)
3699 h. SYS_FUNC_EN 0x02[15-12]= 5 // reset MAC register, DCORE
3700 i. SYS_FUNC_EN 0x02[10]= 1 // enable MCU register, (8051 enable)
3701 ******************************/
3702 u16 valu16 = 0;
3703 rtw_write8(padapter, REG_MCUFWDL, 0);
3704
3705 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
3706 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));//reset MCU ,8051
3707
3708 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN)&0x0FFF;
3709 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 |(FEN_HWPDN|FEN_ELDR)));//reset MAC
3710
3711 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
3712 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));//enable MCU ,8051
3713 #endif
3714 }
3715 else
3716 {
3717 u8 retry_cnts = 0;
3718
3719 // 2010/08/12 MH For USB SS, we can not stop 8051 when we are trying to
3720 // enter IPS/HW&SW radio off. For S3/S4/S5/Disable, we can stop 8051 because
3721 // we will init FW when power on again.
3722 //if(!pDevice->RegUsbSS)
3723 { // If we want to SS mode, we can not reset 8051.
3724 if(rtw_read8(padapter, REG_MCUFWDL) & BIT1)
3725 { //IF fw in RAM code, do reset
3726
3727
3728 if(padapter->bFWReady)
3729 {
3730 // 2010/08/25 MH Accordign to RD alfred's suggestion, we need to disable other
3731 // HRCV INT to influence 8051 reset.
3732 rtw_write8(padapter, REG_FWIMR, 0x20);
3733 // 2011/02/15 MH According to Alex's suggestion, close mask to prevent incorrect FW write operation.
3734 rtw_write8(padapter, REG_FTIMR, 0x00);
3735 rtw_write8(padapter, REG_FSIMR, 0x00);
3736
3737 rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
3738
3739 while( (retry_cnts++ <100) && (FEN_CPUEN &rtw_read16(padapter, REG_SYS_FUNC_EN)))
3740 {
3741 rtw_udelay_os(50);//us
3742 // 2010/08/25 For test only We keep on reset 5051 to prevent fail.
3743 //rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
3744 }
3745 // RT_ASSERT((retry_cnts < 100), ("8051 reset failed!\n"));
3746
3747 if (retry_cnts >= 100)
3748 {
3749 // if 8051 reset fail we trigger GPIO 0 for LA
3750 //rtw_write32( padapter,
3751 // REG_GPIO_PIN_CTRL,
3752 // 0x00010100);
3753 // 2010/08/31 MH According to Filen's info, if 8051 reset fail, reset MAC directly.
3754 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x50); //Reset MAC and Enable 8051
3755 rtw_mdelay_os(10);
3756 }
3757 // else
3758 // RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 reset success (%d) .\n",retry_cnts));
3759 }
3760 }
3761 // else
3762 // {
3763 // RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 in ROM.\n"));
3764 // }
3765 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x54); //Reset MAC and Enable 8051
3766 rtw_write8(padapter, REG_MCUFWDL, 0);
3767 }
3768 }
3769
3770 //if(pDevice->RegUsbSS)
3771 //bWithoutHWSM = TRUE; // Sugest by Filen and Issau.
3772
3773 if(bWithoutHWSM)
3774 {
3775 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3776 /*****************************
3777 Without HW auto state machine
3778 g. SYS_CLKR 0x08[15:0] = 0x30A3 //disable MAC clock
3779 h. AFE_PLL_CTRL 0x28[7:0] = 0x80 //disable AFE PLL
3780 i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F //gated AFE DIG_CLOCK
3781 j. SYS_ISO_CTRL 0x00[7:0] = 0xF9 // isolated digital to PON
3782 ******************************/
3783 //rtw_write16(padapter, REG_SYS_CLKR, 0x30A3);
3784 //if(!pDevice->RegUsbSS)
3785 // 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug.
3786 rtw_write16(padapter, REG_SYS_CLKR, 0x70A3); //modify to 0x70A3 by Scott.
3787 rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
3788 rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
3789 //if(!pDevice->RegUsbSS)
3790 rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
3791 }
3792 else
3793 {
3794 // Disable all RF/BB power
3795 rtw_write8(padapter, REG_RF_CTRL, 0x00);
3796 }
3797 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Reset Digital.\n"));
3798
3799 }
3800
_ResetDigitalProcedure1(PADAPTER padapter,BOOLEAN bWithoutHWSM)3801 void _ResetDigitalProcedure1(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3802 {
3803 _ResetDigitalProcedure1_8723B(padapter, bWithoutHWSM);
3804 }
3805
_ResetDigitalProcedure2(PADAPTER padapter)3806 void _ResetDigitalProcedure2(PADAPTER padapter)
3807 {
3808 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3809 /*****************************
3810 k. SYS_FUNC_EN 0x03[7:0] = 0x44 // disable ELDR runction
3811 l. SYS_CLKR 0x08[15:0] = 0x3083 // disable ELDR clock
3812 m. SYS_ISO_CTRL 0x01[7:0] = 0x83 // isolated ELDR to PON
3813 ******************************/
3814 //rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x44); //marked by Scott.
3815 // 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug.
3816 rtw_write16(padapter, REG_SYS_CLKR, 0x70a3); //modify to 0x70a3 by Scott.
3817 rtw_write8(padapter, REG_SYS_ISO_CTRL+1, 0x82); //modify to 0x82 by Scott.
3818 }
3819
_DisableAnalog(PADAPTER padapter,BOOLEAN bWithoutHWSM)3820 void _DisableAnalog(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3821 {
3822 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3823 u16 value16 = 0;
3824 u8 value8 = 0;
3825
3826
3827 if (bWithoutHWSM)
3828 {
3829 /*****************************
3830 n. LDOA15_CTRL 0x20[7:0] = 0x04 // disable A15 power
3831 o. LDOV12D_CTRL 0x21[7:0] = 0x54 // disable digital core power
3832 r. When driver call disable, the ASIC will turn off remaining clock automatically
3833 ******************************/
3834
3835 rtw_write8(padapter, REG_LDOA15_CTRL, 0x04);
3836 //rtw_write8(padapter, REG_LDOV12D_CTRL, 0x54);
3837
3838 value8 = rtw_read8(padapter, REG_LDOV12D_CTRL);
3839 value8 &= (~LDV12_EN);
3840 rtw_write8(padapter, REG_LDOV12D_CTRL, value8);
3841 // RT_TRACE(COMP_INIT, DBG_LOUD, (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",value8));
3842 }
3843
3844 /*****************************
3845 h. SPS0_CTRL 0x11[7:0] = 0x23 //enter PFM mode
3846 i. APS_FSMCO 0x04[15:0] = 0x4802 // set USB suspend
3847 ******************************/
3848 value8 = 0x23;
3849
3850 rtw_write8(padapter, REG_SPS0_CTRL, value8);
3851
3852 if(bWithoutHWSM)
3853 {
3854 //value16 |= (APDM_HOST | /*AFSM_HSUS |*/PFM_ALDN);
3855 // 2010/08/31 According to Filen description, we need to use HW to shut down 8051 automatically.
3856 // Becasue suspend operatione need the asistance of 8051 to wait for 3ms.
3857 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
3858 }
3859 else
3860 {
3861 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
3862 }
3863
3864 rtw_write16(padapter, REG_APS_FSMCO, value16);//0x4802
3865
3866 rtw_write8(padapter, REG_RSV_CTRL, 0x0e);
3867
3868 #if 0
3869 //tynli_test for suspend mode.
3870 if(!bWithoutHWSM){
3871 rtw_write8(padapter, 0xfe10, 0x19);
3872 }
3873 #endif
3874
3875 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable Analog Reg0x04:0x%04x.\n",value16));
3876 }
3877
3878 // HW Auto state machine
CardDisableHWSM(PADAPTER padapter,u8 resetMCU)3879 s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU)
3880 {
3881 int rtStatus = _SUCCESS;
3882
3883
3884 if (RTW_CANNOT_RUN(padapter))
3885 return rtStatus;
3886
3887 //==== RF Off Sequence ====
3888 _DisableRFAFEAndResetBB(padapter);
3889
3890 // ==== Reset digital sequence ======
3891 _ResetDigitalProcedure1(padapter, _FALSE);
3892
3893 // ==== Pull GPIO PIN to balance level and LED control ======
3894 _DisableGPIO(padapter);
3895
3896 // ==== Disable analog sequence ===
3897 _DisableAnalog(padapter, _FALSE);
3898
3899 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======> Card disable finished.\n"));
3900
3901 return rtStatus;
3902 }
3903
3904 // without HW Auto state machine
CardDisableWithoutHWSM(PADAPTER padapter)3905 s32 CardDisableWithoutHWSM(PADAPTER padapter)
3906 {
3907 s32 rtStatus = _SUCCESS;
3908
3909
3910 //RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Card Disable Without HWSM .\n"));
3911 if (RTW_CANNOT_RUN(padapter))
3912 return rtStatus;
3913
3914
3915 //==== RF Off Sequence ====
3916 _DisableRFAFEAndResetBB(padapter);
3917
3918 // ==== Reset digital sequence ======
3919 _ResetDigitalProcedure1(padapter, _TRUE);
3920
3921 // ==== Pull GPIO PIN to balance level and LED control ======
3922 _DisableGPIO(padapter);
3923
3924 // ==== Reset digital sequence ======
3925 _ResetDigitalProcedure2(padapter);
3926
3927 // ==== Disable analog sequence ===
3928 _DisableAnalog(padapter, _TRUE);
3929
3930 //RT_TRACE(COMP_INIT, DBG_LOUD, ("<====== Card Disable Without HWSM .\n"));
3931 return rtStatus;
3932 }
3933 #endif // CONFIG_USB_HCI || CONFIG_SDIO_HCI || CONFIG_GSPI_HCI
3934
3935 BOOLEAN
Hal_GetChnlGroup8723B(IN u8 Channel,OUT u8 * pGroup)3936 Hal_GetChnlGroup8723B(
3937 IN u8 Channel,
3938 OUT u8 *pGroup
3939 )
3940 {
3941 BOOLEAN bIn24G=TRUE;
3942
3943 if(Channel <= 14)
3944 {
3945 bIn24G=TRUE;
3946
3947 if (1 <= Channel && Channel <= 2 ) *pGroup = 0;
3948 else if (3 <= Channel && Channel <= 5 ) *pGroup = 1;
3949 else if (6 <= Channel && Channel <= 8 ) *pGroup = 2;
3950 else if (9 <= Channel && Channel <= 11) *pGroup = 3;
3951 else if (12 <= Channel && Channel <= 14) *pGroup = 4;
3952 else
3953 {
3954 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,("==>Hal_GetChnlGroup8723B in 2.4 G, but Channel %d in Group not found \n", Channel));
3955 }
3956 }
3957 else
3958 {
3959 bIn24G=FALSE;
3960
3961 if (36 <= Channel && Channel <= 42) *pGroup = 0;
3962 else if (44 <= Channel && Channel <= 48) *pGroup = 1;
3963 else if (50 <= Channel && Channel <= 58) *pGroup = 2;
3964 else if (60 <= Channel && Channel <= 64) *pGroup = 3;
3965 else if (100 <= Channel && Channel <= 106) *pGroup = 4;
3966 else if (108 <= Channel && Channel <= 114) *pGroup = 5;
3967 else if (116 <= Channel && Channel <= 122) *pGroup = 6;
3968 else if (124 <= Channel && Channel <= 130) *pGroup = 7;
3969 else if (132 <= Channel && Channel <= 138) *pGroup = 8;
3970 else if (140 <= Channel && Channel <= 144) *pGroup = 9;
3971 else if (149 <= Channel && Channel <= 155) *pGroup = 10;
3972 else if (157 <= Channel && Channel <= 161) *pGroup = 11;
3973 else if (165 <= Channel && Channel <= 171) *pGroup = 12;
3974 else if (173 <= Channel && Channel <= 177) *pGroup = 13;
3975 else
3976 {
3977 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,("==>Hal_GetChnlGroup8723B in 5G, but Channel %d in Group not found \n",Channel));
3978 }
3979
3980 }
3981 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("<==Hal_GetChnlGroup8723B, (%s) Channel = %d, Group =%d,\n",
3982 (bIn24G) ? "2.4G" : "5G", Channel, *pGroup));
3983 return bIn24G;
3984 }
3985
3986 void
Hal_InitPGData(PADAPTER padapter,u8 * PROMContent)3987 Hal_InitPGData(
3988 PADAPTER padapter,
3989 u8 *PROMContent)
3990 {
3991
3992 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3993 u32 i;
3994 u16 value16;
3995
3996 if(_FALSE == pHalData->bautoload_fail_flag)
3997 { // autoload OK.
3998 // if (IS_BOOT_FROM_EEPROM(padapter))
3999 if (_TRUE == pHalData->EepromOrEfuse)
4000 {
4001 // Read all Content from EEPROM or EFUSE.
4002 for(i = 0; i < HWSET_MAX_SIZE_8723B; i += 2)
4003 {
4004 // value16 = EF2Byte(ReadEEprom(pAdapter, (u2Byte) (i>>1)));
4005 // *((u16*)(&PROMContent[i])) = value16;
4006 }
4007 }
4008 else
4009 {
4010 // Read EFUSE real map to shadow.
4011 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
4012 _rtw_memcpy((void*)PROMContent, (void*)pHalData->efuse_eeprom_data, HWSET_MAX_SIZE_8723B);
4013 }
4014 }
4015 else
4016 {//autoload fail
4017 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n"));
4018 // pHalData->AutoloadFailFlag = _TRUE;
4019 //update to default value 0xFF
4020 if (_FALSE == pHalData->EepromOrEfuse)
4021 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
4022 _rtw_memcpy((void*)PROMContent, (void*)pHalData->efuse_eeprom_data, HWSET_MAX_SIZE_8723B);
4023 }
4024
4025 #ifdef CONFIG_EFUSE_CONFIG_FILE
4026 if (check_phy_efuse_tx_power_info_valid(padapter) == _FALSE) {
4027 if (Hal_readPGDataFromConfigFile(padapter) != _SUCCESS)
4028 DBG_871X_LEVEL(_drv_err_, "invalid phy efuse and read from file fail, will use driver default!!\n");
4029 }
4030 #endif
4031 }
4032
4033 void
Hal_EfuseParseIDCode(IN PADAPTER padapter,IN u8 * hwinfo)4034 Hal_EfuseParseIDCode(
4035 IN PADAPTER padapter,
4036 IN u8 *hwinfo
4037 )
4038 {
4039 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4040 u16 EEPROMId;
4041
4042
4043 // Checl 0x8129 again for making sure autoload status!!
4044 EEPROMId = le16_to_cpu(*((u16*)hwinfo));
4045 if (EEPROMId != RTL_EEPROM_ID)
4046 {
4047 DBG_8192C("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
4048 pHalData->bautoload_fail_flag = _TRUE;
4049 }
4050 else
4051 {
4052 pHalData->bautoload_fail_flag = _FALSE;
4053 }
4054
4055 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("EEPROM ID=0x%04x\n", EEPROMId));
4056 }
4057
4058 static void
Hal_EEValueCheck(IN u8 EEType,IN PVOID pInValue,OUT PVOID pOutValue)4059 Hal_EEValueCheck(
4060 IN u8 EEType,
4061 IN PVOID pInValue,
4062 OUT PVOID pOutValue
4063 )
4064 {
4065 switch(EEType)
4066 {
4067 case EETYPE_TX_PWR:
4068 {
4069 u8 *pIn, *pOut;
4070 pIn = (u8*)pInValue;
4071 pOut = (u8*)pOutValue;
4072 if(*pIn <= 63)
4073 {
4074 *pOut = *pIn;
4075 }
4076 else
4077 {
4078 RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("EETYPE_TX_PWR, value=%d is invalid, set to default=0x%x\n",
4079 *pIn, EEPROM_Default_TxPowerLevel));
4080 *pOut = EEPROM_Default_TxPowerLevel;
4081 }
4082 }
4083 break;
4084 default:
4085 break;
4086 }
4087 }
4088
4089 static u8
Hal_GetChnlGroup(IN u8 chnl)4090 Hal_GetChnlGroup(
4091 IN u8 chnl
4092 )
4093 {
4094 u8 group=0;
4095
4096 if (chnl < 3) // Cjanel 1-3
4097 group = 0;
4098 else if (chnl < 9) // Channel 4-9
4099 group = 1;
4100 else // Channel 10-14
4101 group = 2;
4102
4103 return group;
4104 }
4105
4106 void
Hal_ReadPowerValueFromPROM_8723B(IN PADAPTER Adapter,IN PTxPowerInfo24G pwrInfo24G,IN u8 * PROMContent,IN BOOLEAN AutoLoadFail)4107 Hal_ReadPowerValueFromPROM_8723B(
4108 IN PADAPTER Adapter,
4109 IN PTxPowerInfo24G pwrInfo24G,
4110 IN u8 * PROMContent,
4111 IN BOOLEAN AutoLoadFail
4112 )
4113 {
4114 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4115 u4Byte rfPath, eeAddr=EEPROM_TX_PWR_INX_8723B, group,TxCount=0;
4116
4117 _rtw_memset(pwrInfo24G, 0, sizeof(TxPowerInfo24G));
4118
4119 if(0xFF == PROMContent[eeAddr+1])
4120 AutoLoadFail = TRUE;
4121
4122 if(AutoLoadFail)
4123 {
4124 DBG_871X("%s(): Use Default value!\n", __func__);
4125 for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
4126 {
4127 //2.4G default value
4128 for(group = 0 ; group < MAX_CHNL_GROUP_24G; group++)
4129 {
4130 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
4131 pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
4132 }
4133 for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
4134 {
4135 if(TxCount==0)
4136 {
4137 pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF;
4138 pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF;
4139 }
4140 else
4141 {
4142 pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4143 pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4144 pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4145 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4146 }
4147 }
4148 }
4149
4150 return;
4151 }
4152
4153 pHalData->bTXPowerDataReadFromEEPORM = TRUE; //YJ,move,120316
4154
4155 for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
4156 {
4157 //2 2.4G default value
4158 for(group = 0 ; group < MAX_CHNL_GROUP_24G; group++)
4159 {
4160 pwrInfo24G->IndexCCK_Base[rfPath][group] = PROMContent[eeAddr++];
4161 if(pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
4162 {
4163 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
4164 }
4165 }
4166 for(group = 0 ; group < MAX_CHNL_GROUP_24G-1; group++)
4167 {
4168 pwrInfo24G->IndexBW40_Base[rfPath][group] = PROMContent[eeAddr++];
4169 if(pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
4170 pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
4171 }
4172 for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
4173 {
4174 if(TxCount==0)
4175 {
4176 pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
4177 pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
4178 if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/
4179 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
4180
4181 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
4182 if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/
4183 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
4184
4185 pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
4186 eeAddr++;
4187 } else{
4188 pwrInfo24G->BW40_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
4189 if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/
4190 pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
4191
4192 pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
4193 if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/
4194 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
4195
4196 eeAddr++;
4197
4198 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
4199 if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/
4200 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
4201
4202
4203 pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
4204 if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/
4205 pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
4206
4207 eeAddr++;
4208 }
4209 }
4210
4211 /* Ignore the unnecessary 5G parameters parsing, but still consider the efuse address offset */
4212 #define TX_PWR_DIFF_OFFSET_5G 10
4213 eeAddr += (MAX_CHNL_GROUP_5G + TX_PWR_DIFF_OFFSET_5G);
4214 }
4215 }
4216
4217
4218 void
Hal_EfuseParseTxPowerInfo_8723B(IN PADAPTER padapter,IN u8 * PROMContent,IN BOOLEAN AutoLoadFail)4219 Hal_EfuseParseTxPowerInfo_8723B(
4220 IN PADAPTER padapter,
4221 IN u8* PROMContent,
4222 IN BOOLEAN AutoLoadFail
4223 )
4224 {
4225 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4226 TxPowerInfo24G pwrInfo24G;
4227 u8 rfPath, ch, group, TxCount=1;
4228
4229 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4230 Hal_ReadPowerValueFromPROM_8723B(padapter, &pwrInfo24G, PROMContent, AutoLoadFail);
4231 for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
4232 {
4233 for (ch = 0 ; ch < CENTER_CH_2G_NUM; ch++) {
4234 Hal_GetChnlGroup8723B(ch+1, &group);
4235
4236 if(ch == 14-1)
4237 {
4238 pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][5];
4239 pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
4240 }
4241 else
4242 {
4243 pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group];
4244 pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
4245 }
4246 #ifdef CONFIG_DEBUG
4247 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======= Path %d, ChannelIndex %d, Group %d=======\n",rfPath,ch, group));
4248 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Index24G_CCK_Base[%d][%d] = 0x%x\n",rfPath,ch ,pHalData->Index24G_CCK_Base[rfPath][ch]));
4249 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Index24G_BW40_Base[%d][%d] = 0x%x\n",rfPath,ch,pHalData->Index24G_BW40_Base[rfPath][ch]));
4250 #endif
4251 }
4252
4253 for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
4254 {
4255 pHalData->CCK_24G_Diff[rfPath][TxCount]=pwrInfo24G.CCK_Diff[rfPath][TxCount];
4256 pHalData->OFDM_24G_Diff[rfPath][TxCount]=pwrInfo24G.OFDM_Diff[rfPath][TxCount];
4257 pHalData->BW20_24G_Diff[rfPath][TxCount]=pwrInfo24G.BW20_Diff[rfPath][TxCount];
4258 pHalData->BW40_24G_Diff[rfPath][TxCount]=pwrInfo24G.BW40_Diff[rfPath][TxCount];
4259
4260 #ifdef CONFIG_DEBUG
4261 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("--------------------------------------- 2.4G ---------------------------------------\n"));
4262 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("CCK_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->CCK_24G_Diff[rfPath][TxCount]));
4263 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("OFDM_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->OFDM_24G_Diff[rfPath][TxCount]));
4264 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("BW20_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->BW20_24G_Diff[rfPath][TxCount]));
4265 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("BW40_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->BW40_24G_Diff[rfPath][TxCount]));
4266 #endif
4267 }
4268 }
4269
4270 // 2010/10/19 MH Add Regulator recognize for CU.
4271 if(!AutoLoadFail)
4272 {
4273 pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_8723B]&0x7); //bit0~2
4274 if(PROMContent[EEPROM_RF_BOARD_OPTION_8723B] == 0xFF)
4275 pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION&0x7); //bit0~2
4276 }
4277 else
4278 {
4279 pHalData->EEPROMRegulatory = 0;
4280 }
4281 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory));
4282 }
4283
4284 VOID
Hal_EfuseParseBoardType_8723B(IN PADAPTER Adapter,IN u8 * PROMContent,IN BOOLEAN AutoloadFail)4285 Hal_EfuseParseBoardType_8723B(
4286 IN PADAPTER Adapter,
4287 IN u8* PROMContent,
4288 IN BOOLEAN AutoloadFail
4289 )
4290 {
4291
4292
4293 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4294
4295 if(!AutoloadFail)
4296 {
4297 pHalData->InterfaceSel = (PROMContent[EEPROM_RF_BOARD_OPTION_8723B]&0xE0)>>5;
4298 if(PROMContent[EEPROM_RF_BOARD_OPTION_8723B] == 0xFF)
4299 pHalData->InterfaceSel = (EEPROM_DEFAULT_BOARD_OPTION&0xE0)>>5;
4300 }
4301 else
4302 {
4303 pHalData->InterfaceSel = 0;
4304 }
4305 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("Board Type: 0x%2x\n", pHalData->InterfaceSel));
4306
4307 }
4308
4309 VOID
Hal_EfuseParseBTCoexistInfo_8723B(IN PADAPTER padapter,IN u8 * hwinfo,IN BOOLEAN AutoLoadFail)4310 Hal_EfuseParseBTCoexistInfo_8723B(
4311 IN PADAPTER padapter,
4312 IN u8* hwinfo,
4313 IN BOOLEAN AutoLoadFail
4314 )
4315 {
4316 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4317 u8 tempval;
4318 u32 tmpu4;
4319
4320 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4321 if (!AutoLoadFail)
4322 {
4323 tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
4324 if (tmpu4 & BT_FUNC_EN)
4325 pHalData->EEPROMBluetoothCoexist = _TRUE;
4326 else
4327 pHalData->EEPROMBluetoothCoexist = _FALSE;
4328
4329 pHalData->EEPROMBluetoothType = BT_RTL8723B;
4330
4331 tempval = hwinfo[EEPROM_RF_BT_SETTING_8723B];
4332 if(tempval !=0xFF){
4333 pHalData->EEPROMBluetoothAntNum = tempval & BIT(0);
4334 #ifdef CONFIG_USB_HCI
4335 /*
4336 * Note. default BT antenna is s0 for USB,
4337 * but the efuse 0xC3[6] is 0, it mean Single antenna use s1 (default).
4338 */
4339 if (pHalData->EEPROMBluetoothAntNum == Ant_x2)
4340 pHalData->ant_path = ODM_RF_PATH_A; /* s1 */
4341 else
4342 pHalData->ant_path = ODM_RF_PATH_B; /* s0 */
4343 #else //SDIO or PCIE
4344 // EFUSE_0xC3[6] == 0, S1(Main)-ODM_RF_PATH_A;
4345 // EFUSE_0xC3[6] == 1, S0(Aux)-ODM_RF_PATH_B
4346 pHalData->ant_path = (tempval & BIT(6))?ODM_RF_PATH_B:ODM_RF_PATH_A;
4347 #endif
4348 }
4349 else{
4350 pHalData->EEPROMBluetoothAntNum = Ant_x1;
4351 #ifdef CONFIG_USB_HCI
4352 pHalData->ant_path = ODM_RF_PATH_B;//s0
4353 #else
4354 pHalData->ant_path = ODM_RF_PATH_A;
4355 #endif
4356 }
4357 }
4358 else
4359 {
4360 pHalData->EEPROMBluetoothCoexist = _FALSE;
4361 pHalData->EEPROMBluetoothType = BT_RTL8723B;
4362 pHalData->EEPROMBluetoothAntNum = Ant_x1;
4363 #ifdef CONFIG_USB_HCI
4364 pHalData->ant_path = ODM_RF_PATH_B;//s0
4365 #else
4366 pHalData->ant_path = ODM_RF_PATH_A;
4367 #endif
4368 }
4369
4370 #ifdef CONFIG_FOR_RTL8723BS_VQ0
4371 pHalData->ant_path = ODM_RF_PATH_B;//s0
4372 #endif
4373
4374 #ifdef CONFIG_BT_COEXIST
4375 if (padapter->registrypriv.ant_num > 0) {
4376 DBG_8192C("%s: Apply driver defined antenna number(%d) to replace origin(%d)\n",
4377 __FUNCTION__,
4378 padapter->registrypriv.ant_num,
4379 pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1);
4380
4381 switch (padapter->registrypriv.ant_num) {
4382 case 1:
4383 pHalData->EEPROMBluetoothAntNum = Ant_x1;
4384 break;
4385 case 2:
4386 pHalData->EEPROMBluetoothAntNum = Ant_x2;
4387 break;
4388 default:
4389 DBG_8192C("%s: Discard invalid driver defined antenna number(%d)!\n",
4390 __FUNCTION__, padapter->registrypriv.ant_num);
4391 break;
4392 }
4393 }
4394
4395 rtw_btcoex_SetBTCoexist(padapter, pHalData->EEPROMBluetoothCoexist);
4396 rtw_btcoex_SetChipType(padapter, pHalData->EEPROMBluetoothType);
4397 rtw_btcoex_SetPGAntNum(padapter, pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1);
4398 if (pHalData->EEPROMBluetoothAntNum == Ant_x1)
4399 {
4400 rtw_btcoex_SetSingleAntPath(padapter, pHalData->ant_path);
4401 }
4402 #endif // CONFIG_BT_COEXIST
4403
4404 DBG_8192C("%s: %s BT-coex, ant_num=%d\n",
4405 __FUNCTION__,
4406 pHalData->EEPROMBluetoothCoexist==_TRUE?"Enable":"Disable",
4407 pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1);
4408 }
4409
4410 VOID
Hal_EfuseParseEEPROMVer_8723B(IN PADAPTER padapter,IN u8 * hwinfo,IN BOOLEAN AutoLoadFail)4411 Hal_EfuseParseEEPROMVer_8723B(
4412 IN PADAPTER padapter,
4413 IN u8* hwinfo,
4414 IN BOOLEAN AutoLoadFail
4415 )
4416 {
4417 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4418
4419 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4420 if(!AutoLoadFail)
4421 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723B];
4422 else
4423 pHalData->EEPROMVersion = 1;
4424 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
4425 pHalData->EEPROMVersion));
4426 }
4427
4428
4429
4430 VOID
Hal_EfuseParsePackageType_8723B(IN PADAPTER pAdapter,IN u8 * hwinfo,IN BOOLEAN AutoLoadFail)4431 Hal_EfuseParsePackageType_8723B(
4432 IN PADAPTER pAdapter,
4433 IN u8* hwinfo,
4434 IN BOOLEAN AutoLoadFail
4435 )
4436 {
4437 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
4438 u1Byte package;
4439 u8 efuseContent;
4440
4441 Efuse_PowerSwitch(pAdapter, _FALSE, _TRUE);
4442 efuse_OneByteRead(pAdapter, 0x1FB, &efuseContent, FALSE);
4443 DBG_871X("%s phy efuse read 0x1FB =%x \n",__func__,efuseContent);
4444 Efuse_PowerSwitch(pAdapter, _FALSE, _FALSE);
4445
4446 package = efuseContent & 0x7;
4447 switch (package)
4448 {
4449 case 0x4:
4450 pHalData->PackageType = PACKAGE_TFBGA79;
4451 break;
4452 case 0x5:
4453 pHalData->PackageType = PACKAGE_TFBGA90;
4454 break;
4455 case 0x6:
4456 pHalData->PackageType = PACKAGE_QFN68;
4457 break;
4458 case 0x7:
4459 pHalData->PackageType = PACKAGE_TFBGA80;
4460 break;
4461
4462 default:
4463 pHalData->PackageType = PACKAGE_DEFAULT;
4464 break;
4465 }
4466
4467 DBG_871X("PackageType = 0x%X\n", pHalData->PackageType);
4468
4469 #ifdef CONFIG_SDIO_HCI
4470 /* RTL8703AS: 0x1FB[5:4] 2b'10 */
4471 /* RTL8723BS: 0x1FB[5:4] 2b'11 */
4472 if ((efuseContent & 0x30) == 0x20) {
4473 pAdapter->registrypriv.bw_mode &= 0xF0;
4474 DBG_871X("This is the case of 8703AS\n");
4475 }
4476 #endif
4477 }
4478
4479
4480 VOID
Hal_EfuseParseVoltage_8723B(IN PADAPTER pAdapter,IN u8 * hwinfo,IN BOOLEAN AutoLoadFail)4481 Hal_EfuseParseVoltage_8723B(
4482 IN PADAPTER pAdapter,
4483 IN u8* hwinfo,
4484 IN BOOLEAN AutoLoadFail
4485 )
4486 {
4487 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
4488
4489 //_rtw_memcpy(pHalData->adjuseVoltageVal, &hwinfo[EEPROM_Voltage_ADDR_8723B], 1);
4490 DBG_871X("%s hwinfo[EEPROM_Voltage_ADDR_8723B] =%02x \n",__func__, hwinfo[EEPROM_Voltage_ADDR_8723B]);
4491 pHalData->adjuseVoltageVal = (hwinfo[EEPROM_Voltage_ADDR_8723B] & 0xf0) >> 4 ;
4492 DBG_871X("%s pHalData->adjuseVoltageVal =%x \n",__func__,pHalData->adjuseVoltageVal);
4493 }
4494
4495 VOID
Hal_EfuseParseChnlPlan_8723B(IN PADAPTER padapter,IN u8 * hwinfo,IN BOOLEAN AutoLoadFail)4496 Hal_EfuseParseChnlPlan_8723B(
4497 IN PADAPTER padapter,
4498 IN u8* hwinfo,
4499 IN BOOLEAN AutoLoadFail
4500 )
4501 {
4502 padapter->mlmepriv.ChannelPlan = hal_com_config_channel_plan(
4503 padapter
4504 , hwinfo ? &hwinfo[EEPROM_COUNTRY_CODE_8723B] : NULL
4505 , hwinfo ? hwinfo[EEPROM_ChannelPlan_8723B] : 0xFF
4506 , padapter->registrypriv.alpha2
4507 , padapter->registrypriv.channel_plan
4508 , RTW_CHPLAN_WORLD_NULL
4509 , AutoLoadFail
4510 );
4511 }
4512
4513 VOID
Hal_EfuseParseCustomerID_8723B(IN PADAPTER padapter,IN u8 * hwinfo,IN BOOLEAN AutoLoadFail)4514 Hal_EfuseParseCustomerID_8723B(
4515 IN PADAPTER padapter,
4516 IN u8* hwinfo,
4517 IN BOOLEAN AutoLoadFail
4518 )
4519 {
4520 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4521
4522 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4523 if (!AutoLoadFail)
4524 {
4525 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723B];
4526 }
4527 else
4528 {
4529 pHalData->EEPROMCustomerID = 0;
4530 }
4531 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID));
4532 }
4533
4534 VOID
Hal_EfuseParseAntennaDiversity_8723B(IN PADAPTER pAdapter,IN u8 * hwinfo,IN BOOLEAN AutoLoadFail)4535 Hal_EfuseParseAntennaDiversity_8723B(
4536 IN PADAPTER pAdapter,
4537 IN u8 * hwinfo,
4538 IN BOOLEAN AutoLoadFail
4539 )
4540 {
4541 #ifdef CONFIG_ANTENNA_DIVERSITY
4542 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
4543 struct registry_priv *registry_par = &pAdapter->registrypriv;
4544
4545 if (pHalData->EEPROMBluetoothAntNum == Ant_x1){
4546 pHalData->AntDivCfg = 0;
4547 }
4548 else{
4549 if(registry_par->antdiv_cfg == 2)// 0:OFF , 1:ON, 2:By EFUSE
4550 pHalData->AntDivCfg = 1;
4551 else
4552 pHalData->AntDivCfg = registry_par->antdiv_cfg;
4553 }
4554
4555 // If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead.
4556 if(registry_par->antdiv_type == 0) {
4557 pHalData->TRxAntDivType = hwinfo[EEPROM_RFE_OPTION_8723B];
4558 if (pHalData->TRxAntDivType == 0xFF)
4559 pHalData->TRxAntDivType = S0S1_SW_ANTDIV;//GetRegAntDivType(pAdapter);
4560 else if (pHalData->TRxAntDivType == 0x10)
4561 pHalData->TRxAntDivType = S0S1_SW_ANTDIV; //intrnal switch S0S1
4562 else if (pHalData->TRxAntDivType == 0x11)
4563 pHalData->TRxAntDivType = S0S1_SW_ANTDIV; //intrnal switch S0S1
4564 else
4565 DBG_8192C("%s: efuse[0x%x]=0x%02x is unknown type\n",
4566 __FUNCTION__, EEPROM_RFE_OPTION_8723B, pHalData->TRxAntDivType);
4567 }
4568 else{
4569 pHalData->TRxAntDivType = registry_par->antdiv_type ;//GetRegAntDivType(pAdapter);
4570 }
4571
4572 DBG_8192C("%s: AntDivCfg=%d, AntDivType=%d\n",
4573 __FUNCTION__, pHalData->AntDivCfg, pHalData->TRxAntDivType);
4574 #endif
4575 }
4576
4577 VOID
Hal_EfuseParseXtal_8723B(IN PADAPTER pAdapter,IN u8 * hwinfo,IN BOOLEAN AutoLoadFail)4578 Hal_EfuseParseXtal_8723B(
4579 IN PADAPTER pAdapter,
4580 IN u8 * hwinfo,
4581 IN BOOLEAN AutoLoadFail
4582 )
4583 {
4584 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
4585
4586 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4587 if(!AutoLoadFail)
4588 {
4589 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_8723B];
4590 if(pHalData->CrystalCap == 0xFF)
4591 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723B; //what value should 8812 set?
4592 }
4593 else
4594 {
4595 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723B;
4596 }
4597 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM CrystalCap: 0x%2x\n", pHalData->CrystalCap));
4598 }
4599
4600
4601 void
Hal_EfuseParseThermalMeter_8723B(PADAPTER padapter,u8 * PROMContent,u8 AutoLoadFail)4602 Hal_EfuseParseThermalMeter_8723B(
4603 PADAPTER padapter,
4604 u8 *PROMContent,
4605 u8 AutoLoadFail
4606 )
4607 {
4608 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4609
4610 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4611 //
4612 // ThermalMeter from EEPROM
4613 //
4614 if (_FALSE == AutoLoadFail)
4615 pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8723B];
4616 else
4617 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8723B;
4618
4619 if ((pHalData->EEPROMThermalMeter == 0xff) || (_TRUE == AutoLoadFail))
4620 {
4621 pHalData->odmpriv.RFCalibrateInfo.bAPKThermalMeterIgnore = _TRUE;
4622 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8723B;
4623 }
4624
4625 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM ThermalMeter=0x%x\n", pHalData->EEPROMThermalMeter));
4626 }
4627
4628
4629 #ifdef CONFIG_RF_GAIN_OFFSET
Hal_ReadRFGainOffset(IN PADAPTER Adapter,IN u8 * PROMContent,IN BOOLEAN AutoloadFail)4630 void Hal_ReadRFGainOffset(
4631 IN PADAPTER Adapter,
4632 IN u8* PROMContent,
4633 IN BOOLEAN AutoloadFail)
4634 {
4635 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4636 //
4637 // BB_RF Gain Offset from EEPROM
4638 //
4639
4640 if (!AutoloadFail || (Adapter->registrypriv.RegRfKFreeEnable == 1)) {
4641 pHalData->EEPROMRFGainOffset =PROMContent[EEPROM_RF_GAIN_OFFSET];
4642 DBG_871X("AutoloadFail =%x,\n", AutoloadFail);
4643 pHalData->EEPROMRFGainVal=EFUSE_Read1Byte(Adapter, EEPROM_RF_GAIN_VAL);
4644 DBG_871X("pHalData->EEPROMRFGainVal=%x\n", pHalData->EEPROMRFGainVal);
4645 }
4646 else{
4647 pHalData->EEPROMRFGainOffset = 0;
4648 pHalData->EEPROMRFGainVal=0xFF;
4649 DBG_871X("else AutoloadFail =%x,\n", AutoloadFail);
4650 }
4651 DBG_871X("EEPRORFGainOffset = 0x%02x\n", pHalData->EEPROMRFGainOffset);
4652 }
4653 #endif //CONFIG_RF_GAIN_OFFSET
4654
4655 u8
BWMapping_8723B(IN PADAPTER Adapter,IN struct pkt_attrib * pattrib)4656 BWMapping_8723B(
4657 IN PADAPTER Adapter,
4658 IN struct pkt_attrib *pattrib
4659 )
4660 {
4661 u8 BWSettingOfDesc = 0;
4662 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
4663
4664 //DBG_871X("BWMapping pHalData->CurrentChannelBW %d, pattrib->bwmode %d \n",pHalData->CurrentChannelBW,pattrib->bwmode);
4665
4666 if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_80)
4667 {
4668 if(pattrib->bwmode == CHANNEL_WIDTH_80)
4669 BWSettingOfDesc= 2;
4670 else if(pattrib->bwmode == CHANNEL_WIDTH_40)
4671 BWSettingOfDesc = 1;
4672 else
4673 BWSettingOfDesc = 0;
4674 }
4675 else if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_40)
4676 {
4677 if((pattrib->bwmode == CHANNEL_WIDTH_40) || (pattrib->bwmode == CHANNEL_WIDTH_80))
4678 BWSettingOfDesc = 1;
4679 else
4680 BWSettingOfDesc = 0;
4681 }
4682 else
4683 BWSettingOfDesc = 0;
4684
4685 //if(pTcb->bBTTxPacket)
4686 // BWSettingOfDesc = 0;
4687
4688 return BWSettingOfDesc;
4689 }
4690
SCMapping_8723B(PADAPTER Adapter,struct pkt_attrib * pattrib)4691 u8 SCMapping_8723B(PADAPTER Adapter, struct pkt_attrib *pattrib)
4692 {
4693 u8 SCSettingOfDesc = 0;
4694 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
4695
4696 //DBG_871X("SCMapping: pHalData->CurrentChannelBW %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur80MhzPrimeSC,pHalData->nCur40MhzPrimeSC);
4697
4698 if(pHalData->CurrentChannelBW == CHANNEL_WIDTH_80)
4699 {
4700 if(pattrib->bwmode == CHANNEL_WIDTH_80)
4701 {
4702 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4703 }
4704 else if(pattrib->bwmode == CHANNEL_WIDTH_40)
4705 {
4706 if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
4707 SCSettingOfDesc = VHT_DATA_SC_40_LOWER_OF_80MHZ;
4708 else if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
4709 SCSettingOfDesc = VHT_DATA_SC_40_UPPER_OF_80MHZ;
4710 else
4711 DBG_871X("SCMapping: DONOT CARE Mode Setting\n");
4712 }
4713 else
4714 {
4715 if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
4716 SCSettingOfDesc = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
4717 else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
4718 SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
4719 else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
4720 SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
4721 else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
4722 SCSettingOfDesc = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
4723 else
4724 DBG_871X("SCMapping: DONOT CARE Mode Setting\n");
4725 }
4726 }
4727 else if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_40)
4728 {
4729 //DBG_871X("SCMapping: HT Case: pHalData->CurrentChannelBW %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur40MhzPrimeSC);
4730
4731 if(pattrib->bwmode == CHANNEL_WIDTH_40)
4732 {
4733 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4734 }
4735 else if(pattrib->bwmode == CHANNEL_WIDTH_20)
4736 {
4737 if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
4738 {
4739 SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
4740 }
4741 else if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
4742 {
4743 SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
4744 }
4745 else
4746 {
4747 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4748 }
4749 }
4750 }
4751 else
4752 {
4753 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4754 }
4755
4756 return SCSettingOfDesc;
4757 }
4758
4759
fill_txdesc_sectype(struct pkt_attrib * pattrib)4760 static u8 fill_txdesc_sectype(struct pkt_attrib *pattrib)
4761 {
4762 u8 sectype = 0;
4763 if ((pattrib->encrypt > 0) && !pattrib->bswenc)
4764 {
4765 switch (pattrib->encrypt)
4766 {
4767 // SEC_TYPE
4768 case _WEP40_:
4769 case _WEP104_:
4770 case _TKIP_:
4771 case _TKIP_WTMIC_:
4772 sectype = 1;
4773 break;
4774
4775 #ifdef CONFIG_WAPI_SUPPORT
4776 case _SMS4_:
4777 sectype = 2;
4778 break;
4779 #endif
4780 case _AES_:
4781 sectype = 3;
4782 break;
4783
4784 case _NO_PRIVACY_:
4785 default:
4786 break;
4787 }
4788 }
4789 return sectype;
4790 }
4791
fill_txdesc_vcs_8723b(PADAPTER padapter,struct pkt_attrib * pattrib,u8 * ptxdesc)4792 static void fill_txdesc_vcs_8723b(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
4793 {
4794 //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
4795
4796 if (pattrib->vcs_mode) {
4797 switch (pattrib->vcs_mode) {
4798 case RTS_CTS:
4799 SET_TX_DESC_RTS_ENABLE_8723B(ptxdesc, 1);
4800 SET_TX_DESC_HW_RTS_ENABLE_8723B(ptxdesc, 1);
4801 break;
4802
4803 case CTS_TO_SELF:
4804 SET_TX_DESC_CTS2SELF_8723B(ptxdesc, 1);
4805 break;
4806
4807 case NONE_VCS:
4808 default:
4809 break;
4810 }
4811
4812 SET_TX_DESC_RTS_RATE_8723B(ptxdesc, 8); // RTS Rate=24M
4813 SET_TX_DESC_RTS_RATE_FB_LIMIT_8723B(ptxdesc, 0xF);
4814
4815 if (padapter->mlmeextpriv.mlmext_info.preamble_mode == PREAMBLE_SHORT) {
4816 SET_TX_DESC_RTS_SHORT_8723B(ptxdesc, 1);
4817 }
4818
4819 // Set RTS BW
4820 if (pattrib->ht_en) {
4821 SET_TX_DESC_RTS_SC_8723B(ptxdesc, SCMapping_8723B(padapter, pattrib));
4822 }
4823 }
4824 }
4825
fill_txdesc_phy_8723b(PADAPTER padapter,struct pkt_attrib * pattrib,u8 * ptxdesc)4826 static void fill_txdesc_phy_8723b(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
4827 {
4828 //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
4829
4830 if (pattrib->ht_en) {
4831 SET_TX_DESC_DATA_BW_8723B(ptxdesc, BWMapping_8723B(padapter, pattrib));
4832 SET_TX_DESC_DATA_SC_8723B(ptxdesc, SCMapping_8723B(padapter, pattrib));
4833 }
4834 }
4835
rtl8723b_fill_default_txdesc(struct xmit_frame * pxmitframe,u8 * pbuf)4836 static void rtl8723b_fill_default_txdesc(
4837 struct xmit_frame *pxmitframe,
4838 u8 *pbuf)
4839 {
4840 PADAPTER padapter;
4841 HAL_DATA_TYPE *pHalData;
4842 struct mlme_ext_priv *pmlmeext;
4843 struct mlme_ext_info *pmlmeinfo;
4844 struct pkt_attrib *pattrib;
4845 s32 bmcst;
4846
4847 _rtw_memset(pbuf, 0, TXDESC_SIZE);
4848
4849 padapter = pxmitframe->padapter;
4850 pHalData = GET_HAL_DATA(padapter);
4851 pmlmeext = &padapter->mlmeextpriv;
4852 pmlmeinfo = &(pmlmeext->mlmext_info);
4853
4854 pattrib = &pxmitframe->attrib;
4855 bmcst = IS_MCAST(pattrib->ra);
4856
4857 if (pxmitframe->frame_tag == DATA_FRAMETAG)
4858 {
4859 u8 drv_userate = 0;
4860
4861 SET_TX_DESC_MACID_8723B(pbuf, pattrib->mac_id);
4862 SET_TX_DESC_RATE_ID_8723B(pbuf, pattrib->raid);
4863 SET_TX_DESC_QUEUE_SEL_8723B(pbuf, pattrib->qsel);
4864 SET_TX_DESC_SEQ_8723B(pbuf, pattrib->seqnum);
4865
4866 SET_TX_DESC_SEC_TYPE_8723B(pbuf, fill_txdesc_sectype(pattrib));
4867 fill_txdesc_vcs_8723b(padapter, pattrib, pbuf);
4868
4869 #ifdef CONFIG_P2P
4870 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
4871 if (pattrib->icmp_pkt == 1 && padapter->registrypriv.wifi_spec == 1)
4872 drv_userate = 1;
4873 }
4874 #endif
4875
4876 if ((pattrib->ether_type != 0x888e) &&
4877 (pattrib->ether_type != 0x0806) &&
4878 (pattrib->ether_type != 0x88B4) &&
4879 (pattrib->dhcp_pkt != 1) &&
4880 (drv_userate != 1)
4881 #ifdef CONFIG_AUTO_AP_MODE
4882 && (pattrib->pctrl != _TRUE)
4883 #endif
4884 )
4885 {
4886 // Non EAP & ARP & DHCP type data packet
4887
4888 if (pattrib->ampdu_en == _TRUE) {
4889 SET_TX_DESC_AGG_ENABLE_8723B(pbuf, 1);
4890 SET_TX_DESC_MAX_AGG_NUM_8723B(pbuf, 0x1F);
4891 SET_TX_DESC_AMPDU_DENSITY_8723B(pbuf, pattrib->ampdu_spacing);
4892 }
4893 else {
4894 SET_TX_DESC_AGG_BREAK_8723B(pbuf, 1);
4895 }
4896
4897 fill_txdesc_phy_8723b(padapter, pattrib, pbuf);
4898
4899 SET_TX_DESC_DATA_RATE_FB_LIMIT_8723B(pbuf, 0x1F);
4900
4901 if (pHalData->fw_ractrl == _FALSE) {
4902 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4903
4904 if (pHalData->INIDATA_RATE[pattrib->mac_id] & BIT(7)) {
4905 SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1);
4906 }
4907
4908 SET_TX_DESC_TX_RATE_8723B(pbuf, pHalData->INIDATA_RATE[pattrib->mac_id] & 0x7F);
4909 }
4910
4911 // modify data rate by iwpriv
4912 if (padapter->fix_rate != 0xFF) {
4913 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4914 if (padapter->fix_rate & BIT(7)) {
4915 SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1);
4916 }
4917 SET_TX_DESC_TX_RATE_8723B(pbuf, padapter->fix_rate & 0x7F);
4918 if (!padapter->data_fb) {
4919 SET_TX_DESC_DISABLE_FB_8723B(pbuf, 1);
4920 }
4921 }
4922
4923 if (pattrib->ldpc) {
4924 SET_TX_DESC_DATA_LDPC_8723B(pbuf, 1);
4925 }
4926
4927 if (pattrib->stbc) {
4928 SET_TX_DESC_DATA_STBC_8723B(pbuf, 1);
4929 }
4930
4931 #ifdef CONFIG_CMCC_TEST
4932 SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1); /* use cck short premble */
4933 #endif
4934 }
4935 else
4936 {
4937 // EAP data packet and ARP packet.
4938 // Use the 1M data rate to send the EAP/ARP packet.
4939 // This will maybe make the handshake smooth.
4940
4941 SET_TX_DESC_AGG_BREAK_8723B(pbuf, 1);
4942 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4943 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) {
4944 SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1);
4945 }
4946 SET_TX_DESC_TX_RATE_8723B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4947
4948 DBG_8192C(FUNC_ADPT_FMT ": SP Packet(0x%04X) rate=0x%x\n",
4949 FUNC_ADPT_ARG(padapter), pattrib->ether_type, MRateToHwRate(pmlmeext->tx_rate));
4950 }
4951
4952 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4953 SET_TX_DESC_USB_TXAGG_NUM_8723B(pbuf, pxmitframe->agg_num);
4954 #endif
4955
4956 #ifdef CONFIG_TDLS
4957 #ifdef CONFIG_XMIT_ACK
4958 /* CCX-TXRPT ack for xmit mgmt frames. */
4959 if (pxmitframe->ack_report) {
4960 #ifdef DBG_CCX
4961 DBG_8192C("%s set spe_rpt\n", __func__);
4962 #endif
4963 SET_TX_DESC_SPE_RPT_8723B(pbuf, 1);
4964 SET_TX_DESC_SW_DEFINE_8723B(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no));
4965 }
4966 #endif /* CONFIG_XMIT_ACK */
4967 #endif
4968 }
4969 else if (pxmitframe->frame_tag == MGNT_FRAMETAG)
4970 {
4971 // RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MGNT_FRAMETAG\n", __FUNCTION__));
4972
4973 SET_TX_DESC_MACID_8723B(pbuf, pattrib->mac_id);
4974 SET_TX_DESC_QUEUE_SEL_8723B(pbuf, pattrib->qsel);
4975 SET_TX_DESC_RATE_ID_8723B(pbuf, pattrib->raid);
4976 SET_TX_DESC_SEQ_8723B(pbuf, pattrib->seqnum);
4977 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4978
4979 SET_TX_DESC_MBSSID_8723B(pbuf, pattrib->mbssid & 0xF);
4980
4981 SET_TX_DESC_RETRY_LIMIT_ENABLE_8723B(pbuf, 1);
4982 if (pattrib->retry_ctrl == _TRUE) {
4983 SET_TX_DESC_DATA_RETRY_LIMIT_8723B(pbuf, 6);
4984 } else {
4985 SET_TX_DESC_DATA_RETRY_LIMIT_8723B(pbuf, 12);
4986 }
4987
4988 #ifdef CONFIG_INTEL_PROXIM
4989 if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
4990 DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
4991 SET_TX_DESC_TX_RATE_8723B(pbuf, pattrib->rate);
4992 }
4993 else
4994 #endif
4995 {
4996 SET_TX_DESC_TX_RATE_8723B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4997 }
4998
4999 #ifdef CONFIG_XMIT_ACK
5000 // CCX-TXRPT ack for xmit mgmt frames.
5001 if (pxmitframe->ack_report) {
5002 #ifdef DBG_CCX
5003 DBG_8192C("%s set spe_rpt\n", __FUNCTION__);
5004 #endif
5005 SET_TX_DESC_SPE_RPT_8723B(pbuf, 1);
5006 SET_TX_DESC_SW_DEFINE_8723B(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no));
5007 }
5008 #endif // CONFIG_XMIT_ACK
5009 }
5010 else if (pxmitframe->frame_tag == TXAGG_FRAMETAG)
5011 {
5012 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: TXAGG_FRAMETAG\n", __FUNCTION__));
5013 }
5014 #ifdef CONFIG_MP_INCLUDED
5015 else if (pxmitframe->frame_tag == MP_FRAMETAG)
5016 {
5017 RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MP_FRAMETAG\n", __FUNCTION__));
5018 fill_txdesc_for_mp(padapter, pbuf);
5019 }
5020 #endif
5021 else
5022 {
5023 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: frame_tag=0x%x\n", __FUNCTION__, pxmitframe->frame_tag));
5024
5025 SET_TX_DESC_MACID_8723B(pbuf, pattrib->mac_id);
5026 SET_TX_DESC_RATE_ID_8723B(pbuf, pattrib->raid);
5027 SET_TX_DESC_QUEUE_SEL_8723B(pbuf, pattrib->qsel);
5028 SET_TX_DESC_SEQ_8723B(pbuf, pattrib->seqnum);
5029 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
5030 SET_TX_DESC_TX_RATE_8723B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
5031 }
5032
5033 SET_TX_DESC_PKT_SIZE_8723B(pbuf, pattrib->last_txcmdsz);
5034
5035 {
5036 u8 pkt_offset, offset;
5037
5038 pkt_offset = 0;
5039 offset = TXDESC_SIZE;
5040 #ifdef CONFIG_USB_HCI
5041 pkt_offset = pxmitframe->pkt_offset;
5042 offset += (pxmitframe->pkt_offset >> 3);
5043 #endif // CONFIG_USB_HCI
5044
5045 #ifdef CONFIG_TX_EARLY_MODE
5046 if (pxmitframe->frame_tag == DATA_FRAMETAG) {
5047 pkt_offset = 1;
5048 offset += EARLY_MODE_INFO_SIZE;
5049 }
5050 #endif // CONFIG_TX_EARLY_MODE
5051
5052 SET_TX_DESC_PKT_OFFSET_8723B(pbuf, pkt_offset);
5053 SET_TX_DESC_OFFSET_8723B(pbuf, offset);
5054 }
5055
5056 if (bmcst) {
5057 SET_TX_DESC_BMC_8723B(pbuf, 1);
5058 }
5059
5060 // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
5061 // (1) The sequence number of each non-Qos frame / broadcast / multicast /
5062 // mgnt frame should be controled by Hw because Fw will also send null data
5063 // which we cannot control when Fw LPS enable.
5064 // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
5065 // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
5066 // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
5067 // 2010.06.23. Added by tynli.
5068 if (!pattrib->qos_en) {
5069 SET_TX_DESC_HWSEQ_EN_8723B(pbuf, 1);
5070 }
5071 }
5072
5073 /*
5074 * Description:
5075 *
5076 * Parameters:
5077 * pxmitframe xmitframe
5078 * pbuf where to fill tx desc
5079 */
rtl8723b_update_txdesc(struct xmit_frame * pxmitframe,u8 * pbuf)5080 void rtl8723b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
5081 {
5082 PADAPTER padapter = pxmitframe->padapter;
5083 rtl8723b_fill_default_txdesc(pxmitframe, pbuf);
5084
5085 #ifdef CONFIG_ANTENNA_DIVERSITY
5086 ODM_SetTxAntByTxInfo(&GET_HAL_DATA(padapter)->odmpriv, pbuf, pxmitframe->attrib.mac_id);
5087 #endif // CONFIG_ANTENNA_DIVERSITY
5088
5089 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5090 rtl8723b_cal_txdesc_chksum((struct tx_desc*)pbuf);
5091 #endif
5092 }
5093
5094 #ifdef CONFIG_TSF_RESET_OFFLOAD
reset_tsf(PADAPTER Adapter,u8 reset_port)5095 int reset_tsf(PADAPTER Adapter, u8 reset_port )
5096 {
5097 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
5098 u32 reg_reset_tsf_cnt = (IFACE_PORT0==reset_port) ?
5099 REG_FW_RESET_TSF_CNT_0:REG_FW_RESET_TSF_CNT_1;
5100
5101 rtw_scan_abort(Adapter->pbuddy_adapter); /* site survey will cause reset_tsf fail */
5102 reset_cnt_after = reset_cnt_before = rtw_read8(Adapter,reg_reset_tsf_cnt);
5103 rtl8723b_reset_tsf(Adapter, reset_port);
5104
5105 while ((reset_cnt_after == reset_cnt_before ) && (loop_cnt < 10)) {
5106 rtw_msleep_os(100);
5107 loop_cnt++;
5108 reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt);
5109 }
5110
5111 return(loop_cnt >= 10) ? _FAIL : _TRUE;
5112 }
5113 #endif // CONFIG_TSF_RESET_OFFLOAD
5114
hw_var_set_monitor(PADAPTER Adapter,u8 variable,u8 * val)5115 static void hw_var_set_monitor(PADAPTER Adapter, u8 variable, u8 *val)
5116 {
5117 u32 value_rcr, rcr_bits;
5118 u16 value_rxfltmap2;
5119 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
5120 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
5121
5122 if (*((u8 *)val) == _HW_STATE_MONITOR_) {
5123
5124 /* Leave IPS */
5125 rtw_pm_set_ips(Adapter, IPS_NONE);
5126 LeaveAllPowerSaveMode(Adapter);
5127
5128 /* Receive all type */
5129 rcr_bits = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_ACF | RCR_AMF | RCR_APP_PHYST_RXFF;
5130
5131 /* Append FCS */
5132 rcr_bits |= RCR_APPFCS;
5133
5134 #if 0
5135 /*
5136 CRC and ICV packet will drop in recvbuf2recvframe()
5137 We no turn on it.
5138 */
5139 rcr_bits |= (RCR_ACRC32 | RCR_AICV);
5140 #endif
5141
5142 /* Receive all data frames */
5143 value_rxfltmap2 = 0xFFFF;
5144
5145 value_rcr = rcr_bits;
5146 rtw_write32(Adapter, REG_RCR, value_rcr);
5147
5148 rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2);
5149
5150 #if 0
5151 /* tx pause */
5152 rtw_write8(padapter, REG_TXPAUSE, 0xFF);
5153 #endif
5154 } else {
5155 /* do nothing */
5156 }
5157
5158 }
5159
hw_var_set_opmode(PADAPTER padapter,u8 variable,u8 * val)5160 static void hw_var_set_opmode(PADAPTER padapter, u8 variable, u8* val)
5161 {
5162 u8 val8;
5163 u8 mode = *((u8 *)val);
5164 static u8 isMonitor = _FALSE;
5165
5166 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
5167
5168 if (isMonitor == _TRUE) {
5169 /* reset RCR */
5170 rtw_write32(padapter, REG_RCR, pHalData->ReceiveConfig);
5171 isMonitor = _FALSE;
5172 }
5173
5174 if (mode == _HW_STATE_MONITOR_) {
5175 isMonitor = _TRUE;
5176 /* set net_type */
5177 Set_MSR(padapter, _HW_STATE_NOLINK_);
5178
5179 hw_var_set_monitor(padapter, variable, val);
5180 return;
5181 }
5182
5183 #ifdef CONFIG_CONCURRENT_MODE
5184 if (padapter->iface_type == IFACE_PORT1)
5185 {
5186 // disable Port1 TSF update
5187 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5188 val8 |= DIS_TSF_UDT;
5189 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5190
5191 Set_MSR(padapter, mode);
5192
5193 DBG_871X("#### %s()-%d iface_type(%d) mode=%d ####\n",
5194 __FUNCTION__, __LINE__, padapter->iface_type, mode);
5195
5196 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
5197 {
5198 if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
5199 {
5200 StopTxBeacon(padapter);
5201 #ifdef CONFIG_PCI_HCI
5202 UpdateInterruptMask8723BE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
5203 #else // !CONFIG_PCI_HCI
5204 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5205
5206 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5207 rtw_write8(padapter, REG_DRVERLYINT, 0x05);//restore early int time to 5ms
5208 UpdateInterruptMask8723BU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8723B);
5209 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5210
5211 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5212 UpdateInterruptMask8723BU(padapter, _TRUE ,0, (IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B));
5213 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5214
5215 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5216 #endif // !CONFIG_PCI_HCI
5217 }
5218
5219 // disable atim wnd and disable beacon function
5220 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|DIS_ATIM);
5221 }
5222 else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
5223 {
5224 ResumeTxBeacon(padapter);
5225 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
5226 }
5227 else if (mode == _HW_STATE_AP_)
5228 {
5229 #ifdef CONFIG_PCI_HCI
5230 UpdateInterruptMask8723BE(padapter, RT_BCN_INT_MASKS, 0, 0, 0);
5231 #else // !CONFIG_PCI_HCI
5232 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5233
5234 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5235 UpdateInterruptMask8723BU(padapter, _TRUE, IMR_BCNDMAINT0_8723B, 0);
5236 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5237
5238 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5239 UpdateInterruptMask8723BU(padapter, _TRUE, (IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B), 0);
5240 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5241
5242 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5243 #endif // !CONFIG_PCI_HCI
5244
5245 ResumeTxBeacon(padapter);
5246
5247 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|DIS_BCNQ_SUB);
5248
5249 // Set RCR
5250 //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
5251 //rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0
5252 rtw_write32(padapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,reject ICV_ERR packet
5253 // enable to rx data frame
5254 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5255 // enable to rx ps-poll
5256 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
5257
5258 // Beacon Control related register for first time
5259 rtw_write8(padapter, REG_BCNDMATIM, 0x02); // 2ms
5260
5261 //rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
5262 rtw_write8(padapter, REG_ATIMWND_1, 0x0a); // 10ms for port1
5263 rtw_write16(padapter, REG_BCNTCFG, 0x00);
5264 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
5265 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
5266
5267 // reset TSF2
5268 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
5269
5270 // enable BCN1 Function for if2
5271 // don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received)
5272 rtw_write8(padapter, REG_BCN_CTRL_1, (DIS_TSF_UDT|EN_BCN_FUNCTION | EN_TXBCN_RPT|DIS_BCNQ_SUB));
5273
5274 //SW_BCN_SEL - Port1
5275 //rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2)|BIT4);
5276 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
5277
5278 // select BCN on port 1
5279 rtw_write8(padapter, REG_CCK_CHECK_8723B,
5280 (rtw_read8(padapter, REG_CCK_CHECK_8723B)|BIT_BCN_PORT_SEL));
5281
5282 if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
5283 {
5284 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5285 val8 &= ~EN_BCN_FUNCTION;
5286 rtw_write8(padapter, REG_BCN_CTRL, val8);
5287 }
5288
5289 //BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked
5290 //rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1)|BIT(5));
5291 //rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(3));
5292
5293 //dis BCN0 ATIM WND if if1 is station
5294 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|DIS_ATIM);
5295
5296 #ifdef CONFIG_TSF_RESET_OFFLOAD
5297 // Reset TSF for STA+AP concurrent mode
5298 if (check_buddy_fwstate(padapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)))
5299 {
5300 if (reset_tsf(padapter, IFACE_PORT1) == _FALSE)
5301 DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
5302 __FUNCTION__, __LINE__);
5303 }
5304 #endif // CONFIG_TSF_RESET_OFFLOAD
5305 }
5306 }
5307 else //else for port0
5308 #endif // CONFIG_CONCURRENT_MODE
5309 {
5310 // disable Port0 TSF update
5311 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5312 val8 |= DIS_TSF_UDT;
5313 rtw_write8(padapter, REG_BCN_CTRL, val8);
5314
5315 // set net_type
5316 Set_MSR(padapter, mode);
5317 DBG_871X("#### %s() -%d iface_type(0) mode = %d ####\n", __FUNCTION__, __LINE__, mode);
5318
5319 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
5320 {
5321 #ifdef CONFIG_CONCURRENT_MODE
5322 if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
5323 #endif // CONFIG_CONCURRENT_MODE
5324 {
5325 StopTxBeacon(padapter);
5326 #ifdef CONFIG_PCI_HCI
5327 UpdateInterruptMask8723BE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
5328 #else // !CONFIG_PCI_HCI
5329 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5330 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5331 rtw_write8(padapter, REG_DRVERLYINT, 0x05); // restore early int time to 5ms
5332 UpdateInterruptMask8812AU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8723B);
5333 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5334
5335 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5336 UpdateInterruptMask8812AU(padapter,_TRUE ,0, (IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B));
5337 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5338
5339 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5340 #endif // !CONFIG_PCI_HCI
5341 }
5342
5343 // disable atim wnd
5344 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_ATIM);
5345 //rtw_write8(padapter,REG_BCN_CTRL, 0x18);
5346 }
5347 else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
5348 {
5349 ResumeTxBeacon(padapter);
5350 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
5351 }
5352 else if (mode == _HW_STATE_AP_)
5353 {
5354 #ifdef CONFIG_PCI_HCI
5355 UpdateInterruptMask8723BE( padapter, RT_BCN_INT_MASKS, 0, 0, 0);
5356 #else // !CONFIG_PCI_HCI
5357 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5358 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5359 UpdateInterruptMask8723BU(padapter, _TRUE ,IMR_BCNDMAINT0_8723B, 0);
5360 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5361
5362 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5363 UpdateInterruptMask8723BU(padapter,_TRUE ,(IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B), 0);
5364 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5365
5366 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5367 #endif
5368
5369 ResumeTxBeacon(padapter);
5370
5371 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|DIS_BCNQ_SUB);
5372
5373 //Set RCR
5374 //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
5375 //rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0
5376 rtw_write32(padapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,reject ICV_ERR packet
5377 //enable to rx data frame
5378 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5379 //enable to rx ps-poll
5380 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
5381
5382 //Beacon Control related register for first time
5383 rtw_write8(padapter, REG_BCNDMATIM, 0x02); // 2ms
5384
5385 //rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
5386 rtw_write8(padapter, REG_ATIMWND, 0x0a); // 10ms
5387 rtw_write16(padapter, REG_BCNTCFG, 0x00);
5388 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
5389 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
5390
5391 //reset TSF
5392 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
5393
5394 //enable BCN0 Function for if1
5395 //don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received)
5396 rtw_write8(padapter, REG_BCN_CTRL, (DIS_TSF_UDT|EN_BCN_FUNCTION|EN_TXBCN_RPT|DIS_BCNQ_SUB));
5397
5398 //SW_BCN_SEL - Port0
5399 //rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2) & ~BIT4);
5400 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
5401
5402 // select BCN on port 0
5403 rtw_write8(padapter, REG_CCK_CHECK_8723B,
5404 (rtw_read8(padapter, REG_CCK_CHECK_8723B)& ~BIT_BCN_PORT_SEL));
5405
5406 #ifdef CONFIG_CONCURRENT_MODE
5407 if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
5408 {
5409 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5410 val8 &= ~EN_BCN_FUNCTION;
5411 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5412 }
5413 #endif // CONFIG_CONCURRENT_MODE
5414
5415 // dis BCN1 ATIM WND if if2 is station
5416 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5417 val8 |= DIS_ATIM;
5418 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5419 #ifdef CONFIG_TSF_RESET_OFFLOAD
5420 // Reset TSF for STA+AP concurrent mode
5421 if (check_buddy_fwstate(padapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)))
5422 {
5423 if (reset_tsf(padapter, IFACE_PORT0) == _FALSE)
5424 DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
5425 __FUNCTION__, __LINE__);
5426 }
5427 #endif // CONFIG_TSF_RESET_OFFLOAD
5428 }
5429 }
5430 }
5431
hw_var_set_macaddr(PADAPTER padapter,u8 variable,u8 * val)5432 static void hw_var_set_macaddr(PADAPTER padapter, u8 variable, u8 *val)
5433 {
5434 u8 idx = 0;
5435 u32 reg_macid;
5436
5437 #ifdef CONFIG_CONCURRENT_MODE
5438 if (padapter->iface_type == IFACE_PORT1)
5439 {
5440 reg_macid = REG_MACID1;
5441 }
5442 else
5443 #endif
5444 {
5445 reg_macid = REG_MACID;
5446 }
5447
5448 for (idx = 0 ; idx < 6; idx++)
5449 {
5450 rtw_write8(GET_PRIMARY_ADAPTER(padapter), (reg_macid+idx), val[idx]);
5451 }
5452 }
5453
hw_var_set_bssid(PADAPTER padapter,u8 variable,u8 * val)5454 static void hw_var_set_bssid(PADAPTER padapter, u8 variable, u8 *val)
5455 {
5456 u8 idx = 0;
5457 u32 reg_bssid;
5458
5459 #ifdef CONFIG_CONCURRENT_MODE
5460 if (padapter->iface_type == IFACE_PORT1)
5461 {
5462 reg_bssid = REG_BSSID1;
5463 }
5464 else
5465 #endif
5466 {
5467 reg_bssid = REG_BSSID;
5468 }
5469
5470 for (idx = 0 ; idx < 6; idx++)
5471 {
5472 rtw_write8(padapter, (reg_bssid+idx), val[idx]);
5473 }
5474 }
5475
hw_var_set_bcn_func(PADAPTER padapter,u8 variable,u8 * val)5476 static void hw_var_set_bcn_func(PADAPTER padapter, u8 variable, u8 *val)
5477 {
5478 u32 bcn_ctrl_reg;
5479
5480 #ifdef CONFIG_CONCURRENT_MODE
5481 if (padapter->iface_type == IFACE_PORT1)
5482 {
5483 bcn_ctrl_reg = REG_BCN_CTRL_1;
5484 }
5485 else
5486 #endif
5487 {
5488 bcn_ctrl_reg = REG_BCN_CTRL;
5489 }
5490
5491 if (*(u8*)val)
5492 {
5493 rtw_write8(padapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
5494 }
5495 else
5496 {
5497 u8 val8;
5498 val8 = rtw_read8(padapter, bcn_ctrl_reg);
5499 val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
5500 #ifdef CONFIG_BT_COEXIST
5501 // Always enable port0 beacon function for PSTDMA
5502 if (REG_BCN_CTRL == bcn_ctrl_reg)
5503 val8 |= EN_BCN_FUNCTION;
5504 #endif
5505 rtw_write8(padapter, bcn_ctrl_reg, val8);
5506 }
5507 }
5508
hw_var_set_correct_tsf(PADAPTER padapter,u8 variable,u8 * val)5509 static void hw_var_set_correct_tsf(PADAPTER padapter, u8 variable, u8* val)
5510 {
5511 u8 val8;
5512 u64 tsf;
5513 struct mlme_ext_priv *pmlmeext;
5514 struct mlme_ext_info *pmlmeinfo;
5515
5516
5517 pmlmeext = &padapter->mlmeextpriv;
5518 pmlmeinfo = &pmlmeext->mlmext_info;
5519
5520 tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) -1024; //us
5521
5522 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
5523 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
5524 {
5525 StopTxBeacon(padapter);
5526 }
5527
5528 #ifdef CONFIG_CONCURRENT_MODE
5529 if (padapter->iface_type == IFACE_PORT1)
5530 {
5531 // disable related TSF function
5532 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5533 val8 &= ~EN_BCN_FUNCTION;
5534 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5535
5536 rtw_write32(padapter, REG_TSFTR1, tsf);
5537 rtw_write32(padapter, REG_TSFTR1+4, tsf>>32);
5538
5539
5540 // enable related TSF function
5541 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5542 val8 |= EN_BCN_FUNCTION;
5543 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5544
5545 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
5546 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
5547 && check_buddy_fwstate(padapter, WIFI_AP_STATE)
5548 )
5549 {
5550 // disable related TSF function
5551 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5552 val8 &= ~EN_BCN_FUNCTION;
5553 rtw_write8(padapter, REG_BCN_CTRL, val8);
5554
5555 rtw_write32(padapter, REG_TSFTR, tsf);
5556 rtw_write32(padapter, REG_TSFTR+4, tsf>>32);
5557
5558 // enable related TSF function
5559 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5560 val8 |= EN_BCN_FUNCTION;
5561 rtw_write8(padapter, REG_BCN_CTRL, val8);
5562 #ifdef CONFIG_TSF_RESET_OFFLOAD
5563 // Update buddy port's TSF(TBTT) if it is SoftAP for beacon TX issue!
5564 if (reset_tsf(padapter, IFACE_PORT0) == _FALSE)
5565 DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
5566 __FUNCTION__, __LINE__);
5567
5568 #endif // CONFIG_TSF_RESET_OFFLOAD
5569 }
5570 }
5571 else
5572 #endif // CONFIG_CONCURRENT_MODE
5573 {
5574 // disable related TSF function
5575 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5576 val8 &= ~EN_BCN_FUNCTION;
5577 rtw_write8(padapter, REG_BCN_CTRL, val8);
5578
5579 rtw_write32(padapter, REG_TSFTR, tsf);
5580 rtw_write32(padapter, REG_TSFTR+4, tsf>>32);
5581
5582 // enable related TSF function
5583 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5584 val8 |= EN_BCN_FUNCTION;
5585 rtw_write8(padapter, REG_BCN_CTRL, val8);
5586
5587 #ifdef CONFIG_CONCURRENT_MODE
5588 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
5589 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
5590 && check_buddy_fwstate(padapter, WIFI_AP_STATE))
5591 {
5592 // disable related TSF function
5593 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5594 val8 &= ~EN_BCN_FUNCTION;
5595 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5596
5597 rtw_write32(padapter, REG_TSFTR1, tsf);
5598 rtw_write32(padapter, REG_TSFTR1+4, tsf>>32);
5599
5600 // enable related TSF function
5601 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5602 val8 |= EN_BCN_FUNCTION;
5603 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5604
5605 #ifdef CONFIG_TSF_RESET_OFFLOAD
5606 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
5607 if (reset_tsf(padapter, IFACE_PORT1) == _FALSE)
5608 {
5609 DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
5610 __FUNCTION__, __LINE__);
5611 }
5612 #endif // CONFIG_TSF_RESET_OFFLOAD
5613 }
5614 #endif // CONFIG_CONCURRENT_MODE
5615 }
5616
5617 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5618 || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
5619 {
5620 ResumeTxBeacon(padapter);
5621 }
5622 }
5623
hw_var_set_mlme_disconnect(PADAPTER padapter,u8 variable,u8 * val)5624 static void hw_var_set_mlme_disconnect(PADAPTER padapter, u8 variable, u8 *val)
5625 {
5626 u8 val8;
5627
5628 #ifdef CONFIG_CONCURRENT_MODE
5629 if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
5630 #endif
5631 {
5632 // Set RCR to not to receive data frame when NO LINK state
5633 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF);
5634 // reject all data frames
5635 rtw_write16(padapter, REG_RXFLTMAP2, 0);
5636 }
5637
5638 #ifdef CONFIG_CONCURRENT_MODE
5639 if (padapter->iface_type == IFACE_PORT1)
5640 {
5641 // reset TSF1
5642 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
5643
5644 // disable update TSF1
5645 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5646 val8 |= DIS_TSF_UDT;
5647 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5648
5649 // disable Port1's beacon function
5650 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5651 val8 &= ~EN_BCN_FUNCTION;
5652 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5653 }
5654 else
5655 #endif
5656 {
5657 // reset TSF
5658 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
5659
5660 // disable update TSF
5661 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5662 val8 |= DIS_TSF_UDT;
5663 rtw_write8(padapter, REG_BCN_CTRL, val8);
5664 }
5665 }
5666
hw_var_set_mlme_sitesurvey(PADAPTER padapter,u8 variable,u8 * val)5667 static void hw_var_set_mlme_sitesurvey(PADAPTER padapter, u8 variable, u8* val)
5668 {
5669 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
5670 u32 value_rcr, rcr_clear_bit, reg_bcn_ctl;
5671 #ifdef CONFIG_CONCURRENT_MODE
5672 u32 buddy_reg_bcn_ctl;
5673 #endif
5674 u16 value_rxfltmap2;
5675 u8 val8;
5676 PHAL_DATA_TYPE pHalData;
5677 struct mlme_priv *pmlmepriv;
5678 u8 ap_num;
5679
5680 pHalData = GET_HAL_DATA(padapter);
5681 pmlmepriv = &padapter->mlmepriv;
5682
5683 #ifdef CONFIG_CONCURRENT_MODE
5684 if (padapter->iface_type == IFACE_PORT1) {
5685 reg_bcn_ctl = REG_BCN_CTRL_1;
5686 buddy_reg_bcn_ctl = REG_BCN_CTRL;
5687 } else {
5688 reg_bcn_ctl = REG_BCN_CTRL;
5689 buddy_reg_bcn_ctl = REG_BCN_CTRL_1;
5690 }
5691 #else
5692 reg_bcn_ctl = REG_BCN_CTRL;
5693 #endif
5694
5695 rtw_dev_iface_status(padapter, NULL, NULL, NULL, &ap_num, NULL);
5696
5697 #ifdef CONFIG_FIND_BEST_CHANNEL
5698 rcr_clear_bit = (RCR_CBSSID_BCN | RCR_CBSSID_DATA);
5699
5700 /* Receive all data frames */
5701 value_rxfltmap2 = 0xFFFF;
5702 #else // CONFIG_FIND_BEST_CHANNEL
5703
5704 rcr_clear_bit = RCR_CBSSID_BCN;
5705
5706 // config RCR to receive different BSSID & not to receive data frame
5707 value_rxfltmap2 = 0;
5708
5709 #endif // CONFIG_FIND_BEST_CHANNEL
5710
5711 if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
5712 #ifdef CONFIG_CONCURRENT_MODE
5713 || (check_buddy_fwstate(padapter, WIFI_AP_STATE) == _TRUE)
5714 #endif
5715 )
5716 {
5717 rcr_clear_bit = RCR_CBSSID_BCN;
5718 }
5719 #ifdef CONFIG_TDLS
5720 // TDLS will clear RCR_CBSSID_DATA bit for connection.
5721 else if (padapter->tdlsinfo.link_established == _TRUE)
5722 {
5723 rcr_clear_bit = RCR_CBSSID_BCN;
5724 }
5725 #endif // CONFIG_TDLS
5726
5727 value_rcr = rtw_read32(padapter, REG_RCR);
5728
5729 if (*((u8*)val))
5730 {
5731 /*
5732 * 1. configure REG_RXFLTMAP2
5733 * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
5734 * 3. config RCR to receive different BSSID BCN or probe rsp
5735 */
5736
5737 rtw_write16(padapter, REG_RXFLTMAP2, value_rxfltmap2);
5738
5739 if (rtw_linked_check(padapter) &&
5740 check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) {
5741 /* disable update TSF */
5742 rtw_write8(padapter, reg_bcn_ctl, rtw_read8(padapter, reg_bcn_ctl)|DIS_TSF_UDT);
5743 padapter->mlmeextpriv.en_hw_update_tsf = _FALSE;
5744 }
5745
5746 #ifdef CONFIG_CONCURRENT_MODE
5747 if (rtw_linked_check(padapter->pbuddy_adapter) &&
5748 check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_AP_STATE) != _TRUE) {
5749 /* disable update buddy TSF to avoid updating wrong TSF due to clear RCR_CBSSID_BCN */
5750 rtw_write8(padapter->pbuddy_adapter, buddy_reg_bcn_ctl,
5751 rtw_read8(padapter->pbuddy_adapter, buddy_reg_bcn_ctl)|DIS_TSF_UDT);
5752 padapter->pbuddy_adapter->mlmeextpriv.en_hw_update_tsf = _FALSE;
5753 }
5754 #endif
5755 value_rcr &= ~(rcr_clear_bit);
5756 rtw_write32(padapter, REG_RCR, value_rcr);
5757
5758 // Save orignal RRSR setting.
5759 pHalData->RegRRSR = rtw_read16(padapter, REG_RRSR);
5760
5761 if (ap_num)
5762 StopTxBeacon(padapter);
5763 }
5764 else
5765 {
5766 /*
5767 * 1. enable rx data frame
5768 * 2. config RCR not to receive different BSSID BCN or probe rsp
5769 * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
5770 * so, we enable TSF update when rx first BCN after sitesurvey done
5771 */
5772 // sitesurvey done
5773 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))
5774 #ifdef CONFIG_CONCURRENT_MODE
5775 || check_buddy_fwstate(padapter, (_FW_LINKED|WIFI_AP_STATE))
5776 #endif
5777 )
5778 {
5779 // enable to rx data frame
5780 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5781 }
5782
5783 value_rcr |= rcr_clear_bit;
5784 rtw_write32(padapter, REG_RCR, value_rcr);
5785
5786 if (rtw_linked_check(padapter) &&
5787 check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
5788 padapter->mlmeextpriv.en_hw_update_tsf = _TRUE;
5789
5790 #ifdef CONFIG_CONCURRENT_MODE
5791 if (rtw_linked_check(padapter->pbuddy_adapter) &&
5792 check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_AP_STATE) != _TRUE)
5793 /* disable update buddy TSF to avoid updating wrong TSF due to clear RCR_CBSSID_BCN */
5794 padapter->pbuddy_adapter->mlmeextpriv.en_hw_update_tsf = _TRUE;
5795 #endif
5796
5797 // Restore orignal RRSR setting.
5798 rtw_write16(padapter, REG_RRSR, pHalData->RegRRSR);
5799
5800 if (ap_num) {
5801 int i;
5802 _adapter *iface;
5803
5804 ResumeTxBeacon(padapter);
5805 for (i = 0; i < dvobj->iface_nums; i++) {
5806 iface = dvobj->padapters[i];
5807 if (!iface)
5808 continue;
5809
5810 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE
5811 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
5812 ) {
5813 iface->mlmepriv.update_bcn = _TRUE;
5814 #ifndef CONFIG_INTERRUPT_BASED_TXBCN
5815 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5816 tx_beacon_hdl(iface, NULL);
5817 #endif
5818 #endif
5819 }
5820 }
5821 }
5822 }
5823 }
5824
hw_var_set_mlme_join(PADAPTER padapter,u8 variable,u8 * val)5825 static void hw_var_set_mlme_join(PADAPTER padapter, u8 variable, u8 *val)
5826 {
5827 u8 val8;
5828 u16 val16;
5829 u32 val32;
5830 u8 RetryLimit;
5831 u8 type;
5832 PHAL_DATA_TYPE pHalData;
5833 struct mlme_priv *pmlmepriv;
5834
5835 RetryLimit = 0x30;
5836 type = *(u8*)val;
5837 pHalData = GET_HAL_DATA(padapter);
5838 pmlmepriv = &padapter->mlmepriv;
5839
5840 #ifdef CONFIG_CONCURRENT_MODE
5841 if (type == 0)
5842 {
5843 // prepare to join
5844 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5845 check_buddy_fwstate(padapter, _FW_LINKED))
5846 {
5847 StopTxBeacon(padapter);
5848 }
5849
5850 // enable to rx data frame.Accept all data frame
5851 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5852
5853 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
5854 {
5855 val32 = rtw_read32(padapter, REG_RCR);
5856 val32 |= RCR_CBSSID_BCN;
5857 rtw_write32(padapter, REG_RCR, val32);
5858 }
5859 else
5860 {
5861 val32 = rtw_read32(padapter, REG_RCR);
5862 val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
5863 rtw_write32(padapter, REG_RCR, val32);
5864 }
5865
5866 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
5867 {
5868 RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
5869 }
5870 else // Ad-hoc Mode
5871 {
5872 RetryLimit = 0x7;
5873 }
5874 }
5875 else if (type == 1)
5876 {
5877 // joinbss_event call back when join res < 0
5878 if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
5879 rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
5880
5881 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5882 check_buddy_fwstate(padapter, _FW_LINKED))
5883 {
5884 ResumeTxBeacon(padapter);
5885
5886 // reset TSF 1/2 after ResumeTxBeacon
5887 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
5888 }
5889 }
5890 else if (type == 2)
5891 {
5892 // sta add event call back
5893
5894 // enable update TSF
5895 if (padapter->iface_type == IFACE_PORT1)
5896 {
5897 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5898 val8 &= ~DIS_TSF_UDT;
5899 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5900 }
5901 else
5902 {
5903 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5904 val8 &= ~DIS_TSF_UDT;
5905 rtw_write8(padapter, REG_BCN_CTRL, val8);
5906 }
5907
5908 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
5909 {
5910 rtw_write8(padapter, 0x542 ,0x02);
5911 RetryLimit = 0x7;
5912 }
5913
5914 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5915 check_buddy_fwstate(padapter, _FW_LINKED))
5916 {
5917 ResumeTxBeacon(padapter);
5918
5919 // reset TSF 1/2 after ResumeTxBeacon
5920 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
5921 }
5922 }
5923
5924 val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
5925 rtw_write16(padapter, REG_RL, val16);
5926 #else // !CONFIG_CONCURRENT_MODE
5927 if (type == 0) // prepare to join
5928 {
5929 //enable to rx data frame.Accept all data frame
5930 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
5931 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5932
5933 val32 = rtw_read32(padapter, REG_RCR);
5934 if (padapter->in_cta_test)
5935 val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);//| RCR_ADF
5936 else
5937 val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
5938 rtw_write32(padapter, REG_RCR, val32);
5939
5940 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
5941 {
5942 RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
5943 }
5944 else // Ad-hoc Mode
5945 {
5946 RetryLimit = 0x7;
5947 }
5948 }
5949 else if (type == 1) //joinbss_event call back when join res < 0
5950 {
5951 rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
5952 }
5953 else if (type == 2) //sta add event call back
5954 {
5955 //enable update TSF
5956 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5957 val8 &= ~DIS_TSF_UDT;
5958 rtw_write8(padapter, REG_BCN_CTRL, val8);
5959
5960 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
5961 {
5962 RetryLimit = 0x7;
5963 }
5964 }
5965
5966 val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
5967 rtw_write16(padapter, REG_RL, val16);
5968 #endif // !CONFIG_CONCURRENT_MODE
5969 }
5970
hw_var_set_hw_update_tsf(PADAPTER padapter)5971 static void hw_var_set_hw_update_tsf(PADAPTER padapter)
5972 {
5973
5974 u16 reg_bcn_ctl;
5975 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5976 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5977
5978 #ifdef CONFIG_CONCURRENT_MODE
5979 if (padapter->iface_type == IFACE_PORT1)
5980 reg_bcn_ctl = REG_BCN_CTRL_1;
5981 else
5982 reg_bcn_ctl = REG_BCN_CTRL;
5983 #else
5984 reg_bcn_ctl = REG_BCN_CTRL;
5985 #endif
5986
5987 if (!pmlmeext->en_hw_update_tsf)
5988 return;
5989
5990 /* check REG_RCR bit is set */
5991 if (!(rtw_read32(padapter, REG_RCR) & RCR_CBSSID_BCN)) {
5992 pmlmeext->en_hw_update_tsf = _FALSE;
5993 return;
5994 }
5995
5996 /* enable hw update tsf function for non-AP */
5997 if (rtw_linked_check(padapter) &&
5998 check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
5999 /* enable update buddy TSF */
6000 rtw_write8(padapter, reg_bcn_ctl, rtw_read8(padapter, reg_bcn_ctl)&(~DIS_TSF_UDT));
6001
6002 pmlmeext->en_hw_update_tsf = _FALSE;
6003 }
6004
CCX_FwC2HTxRpt_8723b(PADAPTER padapter,u8 * pdata,u8 len)6005 void CCX_FwC2HTxRpt_8723b(PADAPTER padapter, u8 *pdata, u8 len)
6006 {
6007 u8 seq_no;
6008
6009 #define GET_8723B_C2H_TX_RPT_LIFE_TIME_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 6, 1)
6010 #define GET_8723B_C2H_TX_RPT_RETRY_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 7, 1)
6011
6012 //DBG_871X("%s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", __func__,
6013 // *pdata, *(pdata+1), *(pdata+2), *(pdata+3), *(pdata+4), *(pdata+5), *(pdata+6), *(pdata+7));
6014
6015 seq_no = *(pdata+6);
6016
6017 #ifdef CONFIG_XMIT_ACK
6018 if (GET_8723B_C2H_TX_RPT_RETRY_OVER(pdata) | GET_8723B_C2H_TX_RPT_LIFE_TIME_OVER(pdata)) {
6019 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
6020 }
6021 /*
6022 else if(seq_no != padapter->xmitpriv.seq_no) {
6023 DBG_871X("tx_seq_no=%d, rpt_seq_no=%d\n", padapter->xmitpriv.seq_no, seq_no);
6024 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
6025 }
6026 */
6027 else {
6028 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);
6029 }
6030 #endif
6031 }
6032
c2h_id_filter_ccx_8723b(u8 * buf)6033 s32 c2h_id_filter_ccx_8723b(u8 *buf)
6034 {
6035 struct c2h_evt_hdr_88xx *c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
6036 s32 ret = _FALSE;
6037 if (c2h_evt->id == C2H_CCX_TX_RPT)
6038 ret = _TRUE;
6039
6040 return ret;
6041 }
6042
6043
c2h_handler_8723b(PADAPTER padapter,u8 * buf)6044 s32 c2h_handler_8723b(PADAPTER padapter, u8 *buf)
6045 {
6046 struct c2h_evt_hdr_88xx *pC2hEvent = (struct c2h_evt_hdr_88xx *)buf;
6047 PHAL_DATA_TYPE pHalData=GET_HAL_DATA(padapter);
6048 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6049 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6050 s32 ret = _SUCCESS;
6051 u8 index = 0;
6052
6053 if (pC2hEvent == NULL) {
6054 DBG_8192C("%s(): pC2hEventis NULL\n",__FUNCTION__);
6055 ret = _FAIL;
6056 goto exit;
6057 }
6058
6059 switch (pC2hEvent->id) {
6060 case C2H_DBG:
6061 RT_TRACE(_module_hal_init_c_, _drv_info_, ("c2h_handler_8723b: %s\n", pC2hEvent->payload));
6062 break;
6063
6064 case C2H_CCX_TX_RPT:
6065 /* CCX_FwC2HTxRpt(padapter, QueueID, pC2hEvent->payload); */
6066 break;
6067
6068 #ifdef CONFIG_BT_COEXIST
6069 case C2H_BT_INFO:
6070 rtw_btcoex_BtInfoNotify(padapter, pC2hEvent->plen, pC2hEvent->payload);
6071 break;
6072 #endif
6073
6074 case C2H_BT_MP_INFO:
6075 DBG_8192C("%s: [C2H_BT_MP_INFO] pC2hEvent->plen=%d\n", __FUNCTION__, pC2hEvent->plen);
6076 #ifdef CONFIG_MP_INCLUDED
6077 MPTBT_FwC2hBtMpCtrl(padapter, pC2hEvent->payload, pC2hEvent->plen);
6078 #endif /* CONFIG_MP_INCLUDED */
6079 #ifdef CONFIG_BT_COEXIST
6080 rtw_btcoex_BtMpRptNotify(padapter, pC2hEvent->plen, pC2hEvent->payload);
6081 #endif /* CONFIG_BT_COEXIST */
6082 break;
6083
6084 default:
6085 break;
6086 }
6087
6088 // Clear event to notify FW we have read the command.
6089 // Note:
6090 // If this field isn't clear, the FW won't update the next command message.
6091 // rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
6092 exit:
6093 return ret;
6094 }
6095
process_c2h_event(PADAPTER padapter,PC2H_EVT_HDR pC2hEvent,u8 * c2hBuf)6096 static void process_c2h_event(PADAPTER padapter, PC2H_EVT_HDR pC2hEvent, u8 *c2hBuf)
6097 {
6098 u8 index = 0;
6099 PHAL_DATA_TYPE pHalData=GET_HAL_DATA(padapter);
6100 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6101 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6102 PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
6103
6104 if (c2hBuf == NULL) {
6105 DBG_8192C("%s c2hbuff is NULL\n",__FUNCTION__);
6106 return;
6107 }
6108
6109 switch (pC2hEvent->CmdID) {
6110 case C2H_CCX_TX_RPT:
6111 CCX_FwC2HTxRpt_8723b(padapter, c2hBuf, pC2hEvent->CmdLen);
6112 break;
6113
6114 #ifdef CONFIG_FW_C2H_DEBUG
6115 case C2H_EXTEND:
6116 Debug_FwC2H(padapter, c2hBuf, pC2hEvent->CmdLen);
6117 break;
6118 #endif /* CONFIG_FW_C2H_DEBUG*/
6119
6120 #ifdef CONFIG_BT_COEXIST
6121 case C2H_BT_INFO:
6122 rtw_btcoex_BtInfoNotify(padapter, pC2hEvent->CmdLen, c2hBuf);
6123 break;
6124 #endif
6125
6126 case C2H_BT_MP_INFO:
6127 #ifdef CONFIG_MP_INCLUDED
6128 MPTBT_FwC2hBtMpCtrl(padapter, c2hBuf, pC2hEvent->CmdLen);
6129 #endif /* CONFIG_MP_INCLUDED */
6130 #ifdef CONFIG_BT_COEXIST
6131 rtw_btcoex_BtMpRptNotify(padapter, pC2hEvent->CmdLen, c2hBuf);
6132 #endif /* CONFIG_BT_COEXIST */
6133 break;
6134
6135 default:
6136 if (!(phydm_c2H_content_parsing(pDM_Odm, pC2hEvent->CmdID, pC2hEvent->CmdLen, c2hBuf)))
6137 RT_TRACE(_module_hal_init_c_, _drv_info_, ("%s: [WARNING] unknown C2H(0x%02x)\n", __func__, c2hCmdId));
6138
6139 break;
6140 }
6141
6142 #ifndef CONFIG_C2H_PACKET_EN
6143 // Clear event to notify FW we have read the command.
6144 // Note:
6145 // If this field isn't clear, the FW won't update the next command message.
6146 rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
6147 #endif
6148 }
6149
6150 #ifdef CONFIG_C2H_PACKET_EN
6151
C2HPacketHandler_8723B(PADAPTER padapter,u8 * pbuffer,u16 length)6152 static void C2HPacketHandler_8723B(PADAPTER padapter, u8 *pbuffer, u16 length)
6153 {
6154 C2H_EVT_HDR C2hEvent;
6155 u8 *tmpBuf=NULL;
6156 #ifdef CONFIG_WOWLAN
6157 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6158
6159 if(pwrpriv->wowlan_mode == _TRUE)
6160 {
6161 DBG_871X("%s(): return because wowolan_mode==TRUE! CMDID=%d\n", __func__, pbuffer[0]);
6162 return;
6163 }
6164 #endif
6165 C2hEvent.CmdID = pbuffer[0];
6166 C2hEvent.CmdSeq = pbuffer[1];
6167 C2hEvent.CmdLen = length - 2;
6168 tmpBuf = pbuffer + 2;
6169
6170 //DBG_871X("%s C2hEvent.CmdID:%x C2hEvent.CmdLen:%x C2hEvent.CmdSeq:%x\n",
6171 // __func__, C2hEvent.CmdID, C2hEvent.CmdLen, C2hEvent.CmdSeq);
6172 RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "C2HPacketHandler_8723B(): Command Content:\n", tmpBuf, C2hEvent.CmdLen);
6173
6174 process_c2h_event(padapter, &C2hEvent, tmpBuf);
6175 //c2h_handler_8723b(padapter,&C2hEvent);
6176 return;
6177 }
6178
rtl8723b_c2h_packet_handler(PADAPTER padapter,u8 * pbuf,u16 length)6179 void rtl8723b_c2h_packet_handler(PADAPTER padapter, u8 *pbuf, u16 length)
6180 {
6181 C2H_EVT_HDR C2hEvent;
6182 u8 *pdata;
6183
6184
6185 if (length == 0)
6186 return;
6187
6188 C2hEvent.CmdID = pbuf[0];
6189 C2hEvent.CmdSeq = pbuf[1];
6190 C2hEvent.CmdLen = length - 2;
6191 pdata = pbuf + 2;
6192
6193 DBG_8192C("%s: C2H, ID=%d seq=%d len=%d\n",
6194 __FUNCTION__, C2hEvent.CmdID, C2hEvent.CmdSeq, C2hEvent.CmdLen);
6195
6196 switch (C2hEvent.CmdID) {
6197 case C2H_CCX_TX_RPT:
6198 #ifdef CONFIG_BT_COEXIST
6199 case C2H_BT_MP_INFO:
6200 #endif /* CONFIG_BT_COEXIST */
6201 #ifdef CONFIG_FW_C2H_DEBUG
6202 case C2H_EXTEND:
6203 #endif // CONFIG_FW_C2H_DEBUG
6204 process_c2h_event(padapter, &C2hEvent, pdata);
6205 break;
6206
6207 case C2H_BCN_EARLY_RPT:
6208 #ifdef CONFIG_TDLS
6209 #ifdef CONFIG_TDLS_CH_SW
6210 rtw_tdls_ch_sw_back_to_base_chnl(padapter);
6211 #endif
6212 #endif
6213 break;
6214
6215 case C2H_FW_CHNL_SWITCH_COMPLETE:
6216 #ifdef CONFIG_TDLS
6217 #ifdef CONFIG_TDLS_CH_SW
6218 rtw_tdls_chsw_oper_done(padapter);
6219 #endif
6220 #endif
6221 break;
6222
6223 default:
6224 rtw_c2h_packet_wk_cmd(padapter, pbuf, length);
6225 break;
6226 }
6227 }
6228
6229 #else // !CONFIG_C2H_PACKET_EN
6230 //
6231 //C2H event format:
6232 // Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID
6233 // BITS [127:120] [119:16] [15:8] [7:4] [3:0]
6234 //2009.10.08. by tynli.
C2HCommandHandler(PADAPTER padapter)6235 static void C2HCommandHandler(PADAPTER padapter)
6236 {
6237 C2H_EVT_HDR C2hEvent;
6238 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6239
6240 u8 *tmpBuf = NULL;
6241 u8 index = 0;
6242 u8 bCmdMsgReady = _FALSE;
6243 u8 U1bTmp = 0;
6244 // u8 QueueID = 0;
6245
6246 _rtw_memset(&C2hEvent, 0, sizeof(C2H_EVT_HDR));
6247
6248 C2hEvent.CmdID = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8723B);
6249 C2hEvent.CmdLen = rtw_read8(padapter, REG_C2HEVT_CMD_LEN_8723B);
6250 C2hEvent.CmdSeq = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8723B + 1);
6251
6252 RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "C2HCommandHandler(): ",
6253 &C2hEvent , sizeof(C2hEvent));
6254
6255 U1bTmp = rtw_read8(padapter, REG_C2HEVT_CLEAR);
6256 DBG_871X("%s C2hEvent.CmdID:%x C2hEvent.CmdLen:%x C2hEvent.CmdSeq:%x\n",
6257 __func__, C2hEvent.CmdID, C2hEvent.CmdLen, C2hEvent.CmdSeq);
6258
6259 if (U1bTmp == C2H_EVT_HOST_CLOSE)
6260 {
6261 // Not ready.
6262 return;
6263 }
6264 else if (U1bTmp == C2H_EVT_FW_CLOSE)
6265 {
6266 bCmdMsgReady = _TRUE;
6267 }
6268 else
6269 {
6270 // Not a valid value, reset the clear event.
6271 goto exit;
6272 }
6273
6274 if(C2hEvent.CmdLen == 0)
6275 goto exit;
6276 tmpBuf = rtw_zmalloc(C2hEvent.CmdLen);
6277 if (tmpBuf == NULL)
6278 goto exit;
6279
6280 // Read the content
6281 for (index = 0; index < C2hEvent.CmdLen; index++)
6282 {
6283 tmpBuf[index] = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8723B + 2 + index);
6284 }
6285
6286 RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "C2HCommandHandler(): Command Content:\n", tmpBuf, C2hEvent.CmdLen);
6287
6288 //process_c2h_event(padapter,&C2hEvent, tmpBuf);
6289 c2h_handler_8723b(padapter,&C2hEvent);
6290 if (tmpBuf)
6291 rtw_mfree(tmpBuf, C2hEvent.CmdLen);
6292 #endif // CONFIG_SDIO_HCI || CONFIG_GSPI_HCI
6293
6294 #ifdef CONFIG_USB_HCI
6295 HAL_DATA_TYPE *pHalData=GET_HAL_DATA(padapter);
6296
6297 _rtw_memset(&C2hEvent, 0, sizeof(C2H_EVT_HDR));
6298 C2hEvent.CmdID = pHalData->C2hArray[USB_C2H_CMDID_OFFSET] & 0xF;
6299 C2hEvent.CmdLen = (pHalData->C2hArray[USB_C2H_CMDID_OFFSET] & 0xF0) >> 4;
6300 C2hEvent.CmdSeq =pHalData->C2hArray[USB_C2H_SEQ_OFFSET];
6301 c2h_handler_8723b(padapter,(u8 *)&C2hEvent);
6302 //process_c2h_event(padapter,&C2hEvent,&pHalData->C2hArray[USB_C2H_EVENT_OFFSET]);
6303 #endif // CONFIG_USB_HCI
6304
6305 //REG_C2HEVT_CLEAR have done in process_c2h_event
6306 return;
6307 exit:
6308 rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
6309 return;
6310 }
6311
6312 #endif // !CONFIG_C2H_PACKET_EN
6313
SetHwReg8723B(PADAPTER padapter,u8 variable,u8 * val)6314 void SetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val)
6315 {
6316 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6317 u8 val8;
6318 u16 val16;
6319 u32 val32;
6320
6321 _func_enter_;
6322
6323 switch (variable)
6324 {
6325 case HW_VAR_MEDIA_STATUS:
6326 val8 = rtw_read8(padapter, MSR) & 0x0c;
6327 val8 |= *val;
6328 rtw_write8(padapter, MSR, val8);
6329 break;
6330
6331 case HW_VAR_MEDIA_STATUS1:
6332 val8 = rtw_read8(padapter, MSR) & 0x03;
6333 val8 |= *val << 2;
6334 rtw_write8(padapter, MSR, val8);
6335 break;
6336
6337 case HW_VAR_SET_OPMODE:
6338 hw_var_set_opmode(padapter, variable, val);
6339 break;
6340
6341 case HW_VAR_MAC_ADDR:
6342 hw_var_set_macaddr(padapter, variable, val);
6343 break;
6344
6345 case HW_VAR_BSSID:
6346 hw_var_set_bssid(padapter, variable, val);
6347 break;
6348
6349 case HW_VAR_BASIC_RATE:
6350 {
6351 struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
6352 u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
6353 u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
6354 u16 rrsr_2g_allow_mask = (RRSR_24M|RRSR_12M|RRSR_6M|RRSR_CCK_RATES);
6355
6356 HalSetBrateCfg(padapter, val, &BrateCfg);
6357 input_b = BrateCfg;
6358
6359 /* apply force and allow mask */
6360 BrateCfg |= rrsr_2g_force_mask;
6361 BrateCfg &= rrsr_2g_allow_mask;
6362 masked = BrateCfg;
6363
6364 #ifdef CONFIG_CMCC_TEST
6365 BrateCfg |= (RRSR_11M|RRSR_5_5M|RRSR_1M); /* use 11M to send ACK */
6366 BrateCfg |= (RRSR_24M|RRSR_18M|RRSR_12M); //CMCC_OFDM_ACK 12/18/24M
6367 #endif
6368
6369 /* IOT consideration */
6370 if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
6371 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
6372 if((BrateCfg & (RRSR_24M|RRSR_12M|RRSR_6M)) == 0)
6373 BrateCfg |= RRSR_6M;
6374 }
6375 ioted = BrateCfg;
6376
6377 pHalData->BasicRateSet = BrateCfg;
6378
6379 DBG_8192C("HW_VAR_BASIC_RATE: %#x -> %#x -> %#x\n", input_b, masked, ioted);
6380
6381 // Set RRSR rate table.
6382 rtw_write16(padapter, REG_RRSR, BrateCfg);
6383 rtw_write8(padapter, REG_RRSR+2, rtw_read8(padapter, REG_RRSR+2)&0xf0);
6384 }
6385 break;
6386
6387 case HW_VAR_TXPAUSE:
6388 rtw_write8(padapter, REG_TXPAUSE, *val);
6389 break;
6390
6391 case HW_VAR_BCN_FUNC:
6392 hw_var_set_bcn_func(padapter, variable, val);
6393 break;
6394
6395 case HW_VAR_CORRECT_TSF:
6396 hw_var_set_correct_tsf(padapter, variable, val);
6397 break;
6398
6399 case HW_VAR_CHECK_BSSID:
6400 {
6401 u32 val32;
6402 val32 = rtw_read32(padapter, REG_RCR);
6403 if (*val)
6404 val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
6405 else
6406 val32 &= ~(RCR_CBSSID_DATA|RCR_CBSSID_BCN);
6407 rtw_write32(padapter, REG_RCR, val32);
6408 }
6409 break;
6410
6411 case HW_VAR_MLME_DISCONNECT:
6412 hw_var_set_mlme_disconnect(padapter, variable, val);
6413 break;
6414
6415 case HW_VAR_MLME_SITESURVEY:
6416 hw_var_set_mlme_sitesurvey(padapter, variable, val);
6417
6418 #ifdef CONFIG_BT_COEXIST
6419 rtw_btcoex_ScanNotify(padapter, *val?_TRUE:_FALSE);
6420 #endif // CONFIG_BT_COEXIST
6421 break;
6422
6423 case HW_VAR_MLME_JOIN:
6424 hw_var_set_mlme_join(padapter, variable, val);
6425
6426 #ifdef CONFIG_BT_COEXIST
6427 switch (*val)
6428 {
6429 case 0:
6430 // prepare to join
6431 rtw_btcoex_ConnectNotify(padapter, _TRUE);
6432 break;
6433 case 1:
6434 // joinbss_event callback when join res < 0
6435 rtw_btcoex_ConnectNotify(padapter, _FALSE);
6436 break;
6437 case 2:
6438 // sta add event callback
6439 // rtw_btcoex_MediaStatusNotify(padapter, RT_MEDIA_CONNECT);
6440 break;
6441 }
6442 #endif // CONFIG_BT_COEXIST
6443 break;
6444
6445 case HW_VAR_ON_RCR_AM:
6446 val32 = rtw_read32(padapter, REG_RCR);
6447 val32 |= RCR_AM;
6448 rtw_write32(padapter, REG_RCR, val32);
6449 DBG_8192C("%s, %d, RCR= %x\n", __FUNCTION__, __LINE__, rtw_read32(padapter, REG_RCR));
6450 break;
6451
6452 case HW_VAR_OFF_RCR_AM:
6453 val32 = rtw_read32(padapter, REG_RCR);
6454 val32 &= ~RCR_AM;
6455 rtw_write32(padapter, REG_RCR, val32);
6456 DBG_8192C("%s, %d, RCR= %x\n", __FUNCTION__, __LINE__, rtw_read32(padapter, REG_RCR));
6457 break;
6458
6459 case HW_VAR_BEACON_INTERVAL:
6460 rtw_write16(padapter, REG_BCN_INTERVAL, *((u16*)val));
6461 break;
6462
6463 case HW_VAR_SLOT_TIME:
6464 rtw_write8(padapter, REG_SLOT, *val);
6465 break;
6466
6467 case HW_VAR_RESP_SIFS:
6468 #if 0
6469 // SIFS for OFDM Data ACK
6470 rtw_write8(padapter, REG_SIFS_CTX+1, val[0]);
6471 // SIFS for OFDM consecutive tx like CTS data!
6472 rtw_write8(padapter, REG_SIFS_TRX+1, val[1]);
6473
6474 rtw_write8(padapter, REG_SPEC_SIFS+1, val[0]);
6475 rtw_write8(padapter, REG_MAC_SPEC_SIFS+1, val[0]);
6476
6477 // 20100719 Joseph: Revise SIFS setting due to Hardware register definition change.
6478 rtw_write8(padapter, REG_R2T_SIFS+1, val[0]);
6479 rtw_write8(padapter, REG_T2T_SIFS+1, val[0]);
6480
6481 #else
6482 //SIFS_Timer = 0x0a0a0808;
6483 //RESP_SIFS for CCK
6484 rtw_write8(padapter, REG_RESP_SIFS_CCK, val[0]); // SIFS_T2T_CCK (0x08)
6485 rtw_write8(padapter, REG_RESP_SIFS_CCK+1, val[1]); //SIFS_R2T_CCK(0x08)
6486 //RESP_SIFS for OFDM
6487 rtw_write8(padapter, REG_RESP_SIFS_OFDM, val[2]); //SIFS_T2T_OFDM (0x0a)
6488 rtw_write8(padapter, REG_RESP_SIFS_OFDM+1, val[3]); //SIFS_R2T_OFDM(0x0a)
6489 #endif
6490 break;
6491
6492 case HW_VAR_ACK_PREAMBLE:
6493 {
6494 u8 regTmp;
6495 u8 bShortPreamble = *val;
6496
6497 // Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily)
6498 //regTmp = (pHalData->nCur40MhzPrimeSC)<<5;
6499 regTmp = 0;
6500 if (bShortPreamble) regTmp |= 0x80;
6501 rtw_write8(padapter, REG_RRSR+2, regTmp);
6502 }
6503 break;
6504
6505 case HW_VAR_CAM_EMPTY_ENTRY:
6506 {
6507 u8 ucIndex = *val;
6508 u8 i;
6509 u32 ulCommand = 0;
6510 u32 ulContent = 0;
6511 u32 ulEncAlgo = CAM_AES;
6512
6513 for (i=0; i<CAM_CONTENT_COUNT; i++)
6514 {
6515 // filled id in CAM config 2 byte
6516 if (i == 0)
6517 {
6518 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2);
6519 //ulContent |= CAM_VALID;
6520 }
6521 else
6522 {
6523 ulContent = 0;
6524 }
6525 // polling bit, and No Write enable, and address
6526 ulCommand = CAM_CONTENT_COUNT*ucIndex+i;
6527 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
6528 // write content 0 is equall to mark invalid
6529 rtw_write32(padapter, WCAMI, ulContent); //delay_ms(40);
6530 //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %lx \n",ulContent));
6531 rtw_write32(padapter, RWCAM, ulCommand); //delay_ms(40);
6532 //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %lx \n",ulCommand));
6533 }
6534 }
6535 break;
6536
6537 case HW_VAR_CAM_INVALID_ALL:
6538 rtw_write32(padapter, RWCAM, BIT(31)|BIT(30));
6539 break;
6540
6541 case HW_VAR_AC_PARAM_VO:
6542 rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32*)val));
6543 break;
6544
6545 case HW_VAR_AC_PARAM_VI:
6546 rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32*)val));
6547 break;
6548
6549 case HW_VAR_AC_PARAM_BE:
6550 pHalData->AcParam_BE = ((u32*)(val))[0];
6551 rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32*)val));
6552 break;
6553
6554 case HW_VAR_AC_PARAM_BK:
6555 rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32*)val));
6556 break;
6557
6558 case HW_VAR_ACM_CTRL:
6559 {
6560 u8 ctrl = *((u8*)val);
6561 u8 hwctrl = 0;
6562
6563 if (ctrl != 0)
6564 {
6565 hwctrl |= AcmHw_HwEn;
6566
6567 if (ctrl & BIT(1)) // BE
6568 hwctrl |= AcmHw_BeqEn;
6569
6570 if (ctrl & BIT(2)) // VI
6571 hwctrl |= AcmHw_ViqEn;
6572
6573 if (ctrl & BIT(3)) // VO
6574 hwctrl |= AcmHw_VoqEn;
6575 }
6576
6577 DBG_8192C("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
6578 rtw_write8(padapter, REG_ACMHWCTRL, hwctrl);
6579 }
6580 break;
6581
6582 case HW_VAR_AMPDU_FACTOR:
6583 {
6584 u32 AMPDULen = (*((u8 *)val));
6585
6586 if(AMPDULen < HT_AGG_SIZE_32K)
6587 AMPDULen = (0x2000 << (*((u8 *)val))) -1;
6588 else
6589 AMPDULen = 0x7fff;
6590
6591 rtw_write32(padapter, REG_AMPDU_MAX_LENGTH_8723B, AMPDULen);
6592 }
6593 break;
6594
6595 #if 0
6596 case HW_VAR_RXDMA_AGG_PG_TH:
6597 rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, *val);
6598 break;
6599 #endif
6600
6601 case HW_VAR_H2C_FW_PWRMODE:
6602 {
6603 u8 psmode = *val;
6604
6605 // Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power
6606 // saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang.
6607 if (psmode != PS_MODE_ACTIVE)
6608 {
6609 ODM_RF_Saving(&pHalData->odmpriv, _TRUE);
6610 }
6611
6612 //if (psmode != PS_MODE_ACTIVE) {
6613 // rtl8723b_set_lowpwr_lps_cmd(padapter, _TRUE);
6614 //} else {
6615 // rtl8723b_set_lowpwr_lps_cmd(padapter, _FALSE);
6616 //}
6617 rtl8723b_set_FwPwrMode_cmd(padapter, psmode);
6618 }
6619 break;
6620 case HW_VAR_H2C_PS_TUNE_PARAM:
6621 rtl8723b_set_FwPsTuneParam_cmd(padapter);
6622 break;
6623
6624 case HW_VAR_H2C_FW_JOINBSSRPT:
6625 rtl8723b_set_FwJoinBssRpt_cmd(padapter, *val);
6626 break;
6627
6628 #ifdef CONFIG_P2P
6629 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
6630 rtl8723b_set_p2p_ps_offload_cmd(padapter, *val);
6631 break;
6632 #endif //CONFIG_P2P
6633 #ifdef CONFIG_TDLS
6634 case HW_VAR_TDLS_WRCR:
6635 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)&(~RCR_CBSSID_DATA ));
6636 break;
6637 case HW_VAR_TDLS_RS_RCR:
6638 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|(RCR_CBSSID_DATA));
6639 break;
6640 #endif //CONFIG_TDLS
6641
6642 case HW_VAR_EFUSE_USAGE:
6643 pHalData->EfuseUsedPercentage = *val;
6644 break;
6645
6646 case HW_VAR_EFUSE_BYTES:
6647 pHalData->EfuseUsedBytes = *((u16*)val);
6648 break;
6649
6650 case HW_VAR_EFUSE_BT_USAGE:
6651 #ifdef HAL_EFUSE_MEMORY
6652 pHalData->EfuseHal.BTEfuseUsedPercentage = *val;
6653 #endif
6654 break;
6655
6656 case HW_VAR_EFUSE_BT_BYTES:
6657 #ifdef HAL_EFUSE_MEMORY
6658 pHalData->EfuseHal.BTEfuseUsedBytes = *((u16*)val);
6659 #else
6660 BTEfuseUsedBytes = *((u16*)val);
6661 #endif
6662 break;
6663
6664 case HW_VAR_FIFO_CLEARN_UP:
6665 {
6666 #define RW_RELEASE_EN BIT(18)
6667 #define RXDMA_IDLE BIT(17)
6668
6669 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6670 u8 trycnt = 100;
6671
6672 // pause tx
6673 rtw_write8(padapter, REG_TXPAUSE, 0xff);
6674
6675 // keep sn
6676 padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ);
6677
6678 if (pwrpriv->bkeepfwalive != _TRUE)
6679 {
6680 /* RX DMA stop */
6681 val32 = rtw_read32(padapter, REG_RXPKT_NUM);
6682 val32 |= RW_RELEASE_EN;
6683 rtw_write32(padapter, REG_RXPKT_NUM, val32);
6684 do {
6685 val32 = rtw_read32(padapter, REG_RXPKT_NUM);
6686 val32 &= RXDMA_IDLE;
6687 if (val32)
6688 break;
6689
6690 DBG_871X("%s: [HW_VAR_FIFO_CLEARN_UP] val=%x times:%d\n", __FUNCTION__, val32, trycnt);
6691 } while (--trycnt);
6692 if (trycnt == 0) {
6693 DBG_8192C("[HW_VAR_FIFO_CLEARN_UP] Stop RX DMA failed......\n");
6694 }
6695
6696 // RQPN Load 0
6697 rtw_write16(padapter, REG_RQPN_NPQ, 0);
6698 rtw_write32(padapter, REG_RQPN, 0x80000000);
6699 rtw_mdelay_os(2);
6700 }
6701 }
6702 break;
6703 case HW_VAR_RESTORE_HW_SEQ:
6704 /* restore Sequence No. */
6705 rtw_write8(padapter, 0x4dc, padapter->xmitpriv.nqos_ssn);
6706 break;
6707 #ifdef CONFIG_CONCURRENT_MODE
6708 case HW_VAR_CHECK_TXBUF:
6709 {
6710 u32 i;
6711 u8 RetryLimit = 0x01;
6712 u32 reg_200, reg_204;
6713
6714 val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
6715 rtw_write16(padapter, REG_RL, val16);
6716
6717 for (i=0; i<200; i++) // polling 200x10=2000 msec
6718 {
6719 reg_200 = rtw_read32(padapter, 0x200);
6720 reg_204 = rtw_read32(padapter, 0x204);
6721 if (reg_200 != reg_204)
6722 {
6723 //DBG_871X("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(padapter, 0x204), rtw_read32(padapter, 0x200), i);
6724 rtw_msleep_os(10);
6725 }
6726 else
6727 {
6728 DBG_871X("[HW_VAR_CHECK_TXBUF] no packet in tx packet buffer (%d)\n", i);
6729 break;
6730 }
6731 }
6732
6733 if (reg_200 != reg_204)
6734 DBG_871X("packets in tx buffer - 0x204=%x, 0x200=%x\n", reg_204, reg_200);
6735
6736 RetryLimit = 0x30;
6737 val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
6738 rtw_write16(padapter, REG_RL, val16);
6739 }
6740 break;
6741 #endif // CONFIG_CONCURRENT_MODE
6742
6743 case HW_VAR_APFM_ON_MAC:
6744 pHalData->bMacPwrCtrlOn = *val;
6745 #ifdef PLATFORM_LINUX
6746 DBG_8192C("%s: bMacPwrCtrlOn=%d\n", __func__, pHalData->bMacPwrCtrlOn);
6747 #endif
6748 break;
6749
6750 case HW_VAR_NAV_UPPER:
6751 {
6752 u32 usNavUpper = *((u32*)val);
6753
6754 if (usNavUpper > HAL_NAV_UPPER_UNIT_8723B * 0xFF)
6755 {
6756 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("The setting value (0x%08X us) of NAV_UPPER is larger than (%d * 0xFF)!!!\n", usNavUpper, HAL_NAV_UPPER_UNIT_8723B));
6757 break;
6758 }
6759
6760 // The value of ((usNavUpper + HAL_NAV_UPPER_UNIT_8723B - 1) / HAL_NAV_UPPER_UNIT_8723B)
6761 // is getting the upper integer.
6762 usNavUpper = (usNavUpper + HAL_NAV_UPPER_UNIT_8723B - 1) / HAL_NAV_UPPER_UNIT_8723B;
6763 rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);
6764 }
6765 break;
6766
6767 #ifndef CONFIG_C2H_PACKET_EN
6768 case HW_VAR_C2H_HANDLE:
6769 C2HCommandHandler(padapter);
6770 break;
6771 #endif
6772
6773 case HW_VAR_BCN_VALID:
6774 #ifdef CONFIG_CONCURRENT_MODE
6775 if (padapter->iface_type == IFACE_PORT1)
6776 {
6777 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
6778 val8 |= BIT(0);
6779 rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8);
6780 }
6781 else
6782 #endif // CONFIG_CONCURRENT_MODE
6783 {
6784 // BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw
6785 val8 = rtw_read8(padapter, REG_TDECTRL+2);
6786 val8 |= BIT(0);
6787 rtw_write8(padapter, REG_TDECTRL+2, val8);
6788 }
6789 break;
6790
6791 case HW_VAR_DL_BCN_SEL:
6792 #ifdef CONFIG_CONCURRENT_MODE
6793 if (padapter->iface_type == IFACE_PORT1)
6794 {
6795 // SW_BCN_SEL - Port1
6796 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
6797 val8 |= BIT(4);
6798 rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8);
6799 }
6800 else
6801 #endif // CONFIG_CONCURRENT_MODE
6802 {
6803 // SW_BCN_SEL - Port0
6804 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
6805 val8 &= ~BIT(4);
6806 rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8);
6807 }
6808 break;
6809
6810 case HW_VAR_DO_IQK:
6811 if (*val)
6812 pHalData->bNeedIQK = _TRUE;
6813 else
6814 pHalData->bNeedIQK = _FALSE;
6815 break;
6816
6817 case HW_VAR_DL_RSVD_PAGE:
6818 #ifdef CONFIG_BT_COEXIST
6819 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6820 {
6821 rtl8723b_download_BTCoex_AP_mode_rsvd_page(padapter);
6822 }
6823 else
6824 #endif // CONFIG_BT_COEXIST
6825 {
6826 rtl8723b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
6827 }
6828 break;
6829
6830 case HW_VAR_MACID_SLEEP:
6831 {
6832 u32 reg_macid_sleep;
6833 u8 bit_shift;
6834 u8 id = *(u8*)val;
6835
6836 if (id < 32) {
6837 reg_macid_sleep = REG_MACID_SLEEP;
6838 bit_shift = id;
6839 } else if (id < 64) {
6840 reg_macid_sleep = REG_MACID_SLEEP_1;
6841 bit_shift = id-32;
6842 } else if (id < 96) {
6843 reg_macid_sleep = REG_MACID_SLEEP_2;
6844 bit_shift = id-64;
6845 } else if (id < 128) {
6846 reg_macid_sleep = REG_MACID_SLEEP_3;
6847 bit_shift = id-96;
6848 } else {
6849 rtw_warn_on(1);
6850 break;
6851 }
6852
6853 val32 = rtw_read32(padapter, reg_macid_sleep);
6854 DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_SLEEP] macid=%d, org reg_0x%03x=0x%08X\n",
6855 FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32);
6856
6857 if (val32 & BIT(bit_shift))
6858 break;
6859
6860 val32 |= BIT(bit_shift);
6861 rtw_write32(padapter, reg_macid_sleep, val32);
6862 }
6863 break;
6864
6865 case HW_VAR_MACID_WAKEUP:
6866 {
6867 u32 reg_macid_sleep;
6868 u8 bit_shift;
6869 u8 id = *(u8*)val;
6870
6871 if (id < 32) {
6872 reg_macid_sleep = REG_MACID_SLEEP;
6873 bit_shift = id;
6874 } else if (id < 64) {
6875 reg_macid_sleep = REG_MACID_SLEEP_1;
6876 bit_shift = id-32;
6877 } else if (id < 96) {
6878 reg_macid_sleep = REG_MACID_SLEEP_2;
6879 bit_shift = id-64;
6880 } else if (id < 128) {
6881 reg_macid_sleep = REG_MACID_SLEEP_3;
6882 bit_shift = id-96;
6883 } else {
6884 rtw_warn_on(1);
6885 break;
6886 }
6887
6888 val32 = rtw_read32(padapter, reg_macid_sleep);
6889 DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_WAKEUP] macid=%d, org reg_0x%03x=0x%08X\n",
6890 FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32);
6891
6892 if (!(val32 & BIT(bit_shift)))
6893 break;
6894
6895 val32 &= ~BIT(bit_shift);
6896 rtw_write32(padapter, reg_macid_sleep, val32);
6897 }
6898 break;
6899 #ifdef CONFIG_GPIO_WAKEUP
6900 case HW_SET_GPIO_WL_CTRL:
6901 {
6902 u8 enable = *val;
6903 u8 value = rtw_read8(padapter, 0x4e);
6904 if (enable && (value & BIT(6))) {
6905 value &= ~BIT(6);
6906 rtw_write8(padapter, 0x4e, value);
6907 } else if (enable == _FALSE){
6908 value |= BIT(6);
6909 rtw_write8(padapter, 0x4e, value);
6910 }
6911 DBG_871X("%s: set WL control, 0x4E=0x%02X\n",
6912 __func__, rtw_read8(padapter, 0x4e));
6913 }
6914 break;
6915 #endif
6916 case HW_VAR_EN_HW_UPDATE_TSF:
6917 hw_var_set_hw_update_tsf(padapter);
6918 break;
6919 #if defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)
6920 case HW_VAR_TDLS_BCN_EARLY_C2H_RPT:
6921 rtl8723b_set_BcnEarly_C2H_Rpt_cmd(padapter, *val);
6922 break;
6923 #endif
6924 default:
6925 SetHwReg(padapter, variable, val);
6926 break;
6927 }
6928
6929 _func_exit_;
6930 }
6931
6932 struct qinfo_8723b {
6933 u32 head:8;
6934 u32 pkt_num:7;
6935 u32 tail:8;
6936 u32 ac:2;
6937 u32 macid:7;
6938 };
6939
6940 struct bcn_qinfo_8723b {
6941 u16 head:8;
6942 u16 pkt_num:8;
6943 };
6944
dump_qinfo_8723b(void * sel,struct qinfo_8723b * info,const char * tag)6945 void dump_qinfo_8723b(void *sel, struct qinfo_8723b *info, const char *tag)
6946 {
6947 //if (info->pkt_num)
6948 DBG_871X_SEL_NL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n"
6949 , tag ? tag : "", info->head, info->tail, info->pkt_num, info->macid, info->ac
6950 );
6951 }
6952
dump_bcn_qinfo_8723b(void * sel,struct bcn_qinfo_8723b * info,const char * tag)6953 void dump_bcn_qinfo_8723b(void *sel, struct bcn_qinfo_8723b *info, const char *tag)
6954 {
6955 //if (info->pkt_num)
6956 DBG_871X_SEL_NL(sel, "%shead:0x%02x, pkt_num:%u\n"
6957 , tag ? tag : "", info->head, info->pkt_num
6958 );
6959 }
6960
dump_mac_qinfo_8723b(void * sel,_adapter * adapter)6961 void dump_mac_qinfo_8723b(void *sel, _adapter *adapter)
6962 {
6963 u32 q0_info;
6964 u32 q1_info;
6965 u32 q2_info;
6966 u32 q3_info;
6967 u32 q4_info;
6968 u32 q5_info;
6969 u32 q6_info;
6970 u32 q7_info;
6971 u32 mg_q_info;
6972 u32 hi_q_info;
6973 u16 bcn_q_info;
6974
6975 q0_info = rtw_read32(adapter, REG_Q0_INFO);
6976 q1_info = rtw_read32(adapter, REG_Q1_INFO);
6977 q2_info = rtw_read32(adapter, REG_Q2_INFO);
6978 q3_info = rtw_read32(adapter, REG_Q3_INFO);
6979 q4_info = rtw_read32(adapter, REG_Q4_INFO);
6980 q5_info = rtw_read32(adapter, REG_Q5_INFO);
6981 q6_info = rtw_read32(adapter, REG_Q6_INFO);
6982 q7_info = rtw_read32(adapter, REG_Q7_INFO);
6983 mg_q_info = rtw_read32(adapter, REG_MGQ_INFO);
6984 hi_q_info = rtw_read32(adapter, REG_HGQ_INFO);
6985 bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO);
6986
6987 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q0_info, "Q0 ");
6988 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q1_info, "Q1 ");
6989 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q2_info, "Q2 ");
6990 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q3_info, "Q3 ");
6991 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q4_info, "Q4 ");
6992 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q5_info, "Q5 ");
6993 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q6_info, "Q6 ");
6994 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q7_info, "Q7 ");
6995 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&mg_q_info, "MG ");
6996 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&hi_q_info, "HI ");
6997 dump_bcn_qinfo_8723b(sel, (struct bcn_qinfo_8723b *)&bcn_q_info, "BCN ");
6998 }
6999
GetHwReg8723B(PADAPTER padapter,u8 variable,u8 * val)7000 void GetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val)
7001 {
7002 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
7003 u8 val8;
7004 u16 val16;
7005 u32 val32;
7006
7007
7008 switch (variable)
7009 {
7010 case HW_VAR_TXPAUSE:
7011 *val = rtw_read8(padapter, REG_TXPAUSE);
7012 break;
7013
7014 case HW_VAR_BCN_VALID:
7015 #ifdef CONFIG_CONCURRENT_MODE
7016 if (padapter->iface_type == IFACE_PORT1)
7017 {
7018 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
7019 *val = (BIT(0) & val8) ? _TRUE:_FALSE;
7020 }
7021 else
7022 #endif
7023 {
7024 // BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2
7025 val8 = rtw_read8(padapter, REG_TDECTRL+2);
7026 *val = (BIT(0) & val8) ? _TRUE:_FALSE;
7027 }
7028 break;
7029
7030 case HW_VAR_FWLPS_RF_ON:
7031 {
7032 // When we halt NIC, we should check if FW LPS is leave.
7033 u32 valRCR;
7034
7035 if (rtw_is_surprise_removed(padapter) ||
7036 (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off))
7037 {
7038 // If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave,
7039 // because Fw is unload.
7040 *val = _TRUE;
7041 }
7042 else
7043 {
7044 valRCR = rtw_read32(padapter, REG_RCR);
7045 valRCR &= 0x00070000;
7046 if(valRCR)
7047 *val = _FALSE;
7048 else
7049 *val = _TRUE;
7050 }
7051 }
7052 break;
7053
7054 case HW_VAR_EFUSE_USAGE:
7055 *val = pHalData->EfuseUsedPercentage;
7056 break;
7057
7058 case HW_VAR_EFUSE_BYTES:
7059 *((u16*)val) = pHalData->EfuseUsedBytes;
7060 break;
7061
7062 case HW_VAR_EFUSE_BT_USAGE:
7063 #ifdef HAL_EFUSE_MEMORY
7064 *val = pHalData->EfuseHal.BTEfuseUsedPercentage;
7065 #endif
7066 break;
7067
7068 case HW_VAR_EFUSE_BT_BYTES:
7069 #ifdef HAL_EFUSE_MEMORY
7070 *((u16*)val) = pHalData->EfuseHal.BTEfuseUsedBytes;
7071 #else
7072 *((u16*)val) = BTEfuseUsedBytes;
7073 #endif
7074 break;
7075
7076 case HW_VAR_APFM_ON_MAC:
7077 *val = pHalData->bMacPwrCtrlOn;
7078 break;
7079 case HW_VAR_CHK_HI_QUEUE_EMPTY:
7080 val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);
7081 *val = (val16 & BIT(10)) ? _TRUE:_FALSE;
7082 break;
7083 #ifdef CONFIG_WOWLAN
7084 case HW_VAR_RPWM_TOG:
7085 *val = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1) & BIT7;
7086 break;
7087 case HW_VAR_WAKEUP_REASON:
7088 *val = rtw_read8(padapter, REG_WOWLAN_WAKE_REASON);
7089 if(*val == 0xEA)
7090 *val = 0;
7091 break;
7092 case HW_VAR_SYS_CLKR:
7093 *val = rtw_read8(padapter, REG_SYS_CLKR);
7094 break;
7095 #endif
7096 case HW_VAR_DUMP_MAC_QUEUE_INFO:
7097 dump_mac_qinfo_8723b(val, padapter);
7098 break;
7099 default:
7100 GetHwReg(padapter, variable, val);
7101 break;
7102 }
7103 }
7104
7105 /*
7106 * Description:
7107 * Change default setting of specified variable.
7108 */
SetHalDefVar8723B(PADAPTER padapter,HAL_DEF_VARIABLE variable,void * pval)7109 u8 SetHalDefVar8723B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
7110 {
7111 PHAL_DATA_TYPE pHalData;
7112 u8 bResult;
7113
7114
7115 pHalData = GET_HAL_DATA(padapter);
7116 bResult = _SUCCESS;
7117
7118 switch (variable)
7119 {
7120 default:
7121 bResult = SetHalDefVar(padapter, variable, pval);
7122 break;
7123 }
7124
7125 return bResult;
7126 }
7127
7128 #ifdef CONFIG_C2H_PACKET_EN
SetHwRegWithBuf8723B(PADAPTER padapter,u8 variable,u8 * pbuf,int len)7129 void SetHwRegWithBuf8723B(PADAPTER padapter, u8 variable, u8 *pbuf, int len)
7130 {
7131 PHAL_DATA_TYPE pHalData;
7132
7133 _func_enter_;
7134
7135 pHalData = GET_HAL_DATA(padapter);
7136
7137 switch (variable) {
7138 case HW_VAR_C2H_HANDLE:
7139 C2HPacketHandler_8723B(padapter, pbuf, len);
7140 break;
7141
7142 default:
7143 break;
7144 }
7145 _func_exit_;
7146 }
7147 #endif // CONFIG_C2H_PACKET_EN
7148
hal_ra_info_dump(_adapter * padapter,void * sel)7149 void hal_ra_info_dump(_adapter *padapter , void *sel)
7150 {
7151 int i;
7152 u8 mac_id;
7153 u32 cmd;
7154 u32 ra_info1, ra_info2, bw_set;
7155 u32 rate_mask1, rate_mask2;
7156 u8 curr_tx_rate, curr_tx_sgi, hight_rate, lowest_rate;
7157 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
7158 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
7159 HAL_DATA_TYPE *HalData = GET_HAL_DATA(padapter);
7160
7161 for (i = 0; i < macid_ctl->num; i++) {
7162
7163 if (rtw_macid_is_used(macid_ctl, i) && !rtw_macid_is_bmc(macid_ctl, i)) {
7164
7165 mac_id = (u8) i;
7166 DBG_871X_SEL(sel , "============ RA status check Mac_id:%d ===================\n", mac_id);
7167
7168 cmd = 0x40000100 | mac_id;
7169 rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B, cmd);
7170 rtw_msleep_os(10);
7171 ra_info1 = rtw_read32(padapter, 0x2F0);
7172 curr_tx_rate = ra_info1&0x7F;
7173 curr_tx_sgi = (ra_info1>>7)&0x01;
7174
7175 DBG_871X_SEL(sel , "[ ra_info1:0x%08x ] =>cur_tx_rate= %s,cur_sgi:%d\n", ra_info1, HDATA_RATE(curr_tx_rate), curr_tx_sgi);
7176 DBG_871X_SEL(sel , "[ ra_info1:0x%08x ] =>PWRSTS = 0x%02x\n", ra_info1, (ra_info1>>8) & 0x07);
7177
7178 cmd = 0x40000400 | mac_id;
7179 rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B, cmd);
7180 rtw_msleep_os(10);
7181 ra_info1 = rtw_read32(padapter, 0x2F0);
7182 ra_info2 = rtw_read32(padapter, 0x2F4);
7183 rate_mask1 = rtw_read32(padapter, 0x2F8);
7184 rate_mask2 = rtw_read32(padapter, 0x2FC);
7185 hight_rate = ra_info2 & 0xFF;
7186 lowest_rate = (ra_info2>>8) & 0xFF;
7187 bw_set = (ra_info1 >> 8) & 0xFF;
7188
7189 DBG_871X_SEL(sel , "[ ra_info1:0x%08x ] => VHT_EN=0x%02x, ", ra_info1, (ra_info1>>24) & 0xFF);
7190
7191 switch (bw_set) {
7192
7193 case CHANNEL_WIDTH_20:
7194 DBG_871X_SEL(sel , "BW_setting=20M\n");
7195 break;
7196
7197 case CHANNEL_WIDTH_40:
7198 DBG_871X_SEL(sel , "BW_setting=40M\n ");
7199 break;
7200
7201 case CHANNEL_WIDTH_80:
7202 DBG_871X_SEL(sel , "BW_setting=80M\n");
7203 break;
7204
7205 case CHANNEL_WIDTH_160:
7206 DBG_871X_SEL(sel , "BW_setting=160M\n");
7207 break;
7208
7209 default:
7210 DBG_871X_SEL(sel , "BW_setting=0x%02x\n", bw_set);
7211 break;
7212
7213 }
7214
7215 DBG_871X_SEL(sel , "[ ra_info1:0x%08x ] =>RSSI=%d, DISRA=0x%02x\n", ra_info1, ra_info1&0xFF, (ra_info1>>16) & 0xFF);
7216
7217 DBG_871X_SEL(sel , "[ ra_info2:0x%08x ] =>hight_rate=%s, lowest_rate=%s, SGI=0x%02x, RateID=%d\n",
7218 ra_info2,
7219 HDATA_RATE(hight_rate),
7220 HDATA_RATE(lowest_rate),
7221 (ra_info2>>16) & 0xFF,
7222 (ra_info2>>24) & 0xFF);
7223
7224 DBG_871X_SEL(sel , "rate_mask2=0x%08x, rate_mask1=0x%08x\n", rate_mask2, rate_mask1);
7225
7226 }
7227 }
7228 }
7229
7230
7231 /*
7232 * Description:
7233 * Query setting of specified variable.
7234 */
GetHalDefVar8723B(PADAPTER padapter,HAL_DEF_VARIABLE variable,void * pval)7235 u8 GetHalDefVar8723B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
7236 {
7237 PHAL_DATA_TYPE pHalData;
7238 u8 bResult;
7239
7240
7241 pHalData = GET_HAL_DATA(padapter);
7242 bResult = _SUCCESS;
7243
7244 switch (variable)
7245 {
7246 case HAL_DEF_MAX_RECVBUF_SZ:
7247 *((u32*)pval) = MAX_RECVBUF_SZ;
7248 break;
7249
7250 case HAL_DEF_RX_PACKET_OFFSET:
7251 *((u32*)pval) = RXDESC_SIZE + DRVINFO_SZ*8;
7252 break;
7253
7254 case HW_VAR_MAX_RX_AMPDU_FACTOR:
7255 // Stanley@BB.SD3 suggests 16K can get stable performance
7256 // The experiment was done on SDIO interface
7257 // coding by Lucas@20130730
7258 *(HT_CAP_AMPDU_FACTOR*)pval = MAX_AMPDU_FACTOR_16K;
7259 break;
7260 case HW_VAR_BEST_AMPDU_DENSITY:
7261 *((u32 *)pval) = AMPDU_DENSITY_VALUE_7;
7262 break;
7263 case HAL_DEF_TX_LDPC:
7264 case HAL_DEF_RX_LDPC:
7265 *((u8 *)pval) = _FALSE;
7266 break;
7267 case HAL_DEF_TX_STBC:
7268 *((u8 *)pval) = 0;
7269 break;
7270 case HAL_DEF_RX_STBC:
7271 *((u8 *)pval) = 1;
7272 break;
7273 case HAL_DEF_EXPLICIT_BEAMFORMER:
7274 case HAL_DEF_EXPLICIT_BEAMFORMEE:
7275 *((u8 *)pval) = _FALSE;
7276 break;
7277
7278 case HW_DEF_RA_INFO_DUMP:
7279 hal_ra_info_dump(padapter, pval);
7280 break;
7281
7282 case HAL_DEF_TX_PAGE_BOUNDARY:
7283 if (!padapter->registrypriv.wifi_spec)
7284 {
7285 *(u8*)pval = TX_PAGE_BOUNDARY_8723B;
7286 }
7287 else
7288 {
7289 *(u8*)pval = WMM_NORMAL_TX_PAGE_BOUNDARY_8723B;
7290 }
7291 break;
7292
7293 case HAL_DEF_MACID_SLEEP:
7294 *(u8*)pval = _TRUE; // support macid sleep
7295 break;
7296 case HAL_DEF_TX_PAGE_SIZE:
7297 *(( u32*)pval) = PAGE_SIZE_128;
7298 break;
7299 case HAL_DEF_RX_DMA_SZ_WOW:
7300 *(u32 *)pval = RX_DMA_SIZE_8723B - RESV_FMWF;
7301 break;
7302 case HAL_DEF_RX_DMA_SZ:
7303 *(u32 *)pval = RX_DMA_BOUNDARY_8723B + 1;
7304 break;
7305 case HAL_DEF_RX_PAGE_SIZE:
7306 *((u32 *)pval) = 8;
7307 break;
7308 default:
7309 bResult = GetHalDefVar(padapter, variable, pval);
7310 break;
7311 }
7312
7313 return bResult;
7314 }
7315
7316 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
Hal_DetectWoWMode(PADAPTER pAdapter)7317 void Hal_DetectWoWMode(PADAPTER pAdapter)
7318 {
7319 adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = _TRUE;
7320 }
7321 #endif //CONFIG_WOWLAN
7322
rtl8723b_start_thread(_adapter * padapter)7323 void rtl8723b_start_thread(_adapter *padapter)
7324 {
7325 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
7326 #ifndef CONFIG_SDIO_TX_TASKLET
7327 struct xmit_priv *xmitpriv = &padapter->xmitpriv;
7328
7329 xmitpriv->SdioXmitThread = kthread_run(rtl8723bs_xmit_thread, padapter, "RTWHALXT");
7330 if (IS_ERR(xmitpriv->SdioXmitThread))
7331 {
7332 RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: start rtl8723bs_xmit_thread FAIL!!\n", __FUNCTION__));
7333 }
7334 #endif
7335 #endif
7336 }
7337
rtl8723b_stop_thread(_adapter * padapter)7338 void rtl8723b_stop_thread(_adapter *padapter)
7339 {
7340 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
7341 #ifndef CONFIG_SDIO_TX_TASKLET
7342 struct xmit_priv *xmitpriv = &padapter->xmitpriv;
7343
7344 // stop xmit_buf_thread
7345 if (xmitpriv->SdioXmitThread ) {
7346 _rtw_up_sema(&xmitpriv->SdioXmitSema);
7347 _rtw_down_sema(&xmitpriv->SdioXmitTerminateSema);
7348 xmitpriv->SdioXmitThread = 0;
7349 }
7350 #endif
7351 #endif
7352 }
7353
7354 #if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
7355 extern void check_bt_status_work(void *data);
rtl8723bs_init_checkbthang_workqueue(_adapter * adapter)7356 void rtl8723bs_init_checkbthang_workqueue(_adapter * adapter)
7357 {
7358 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
7359 adapter->priv_checkbt_wq = alloc_workqueue("sdio_wq", 0, 0);
7360 #else
7361 adapter->priv_checkbt_wq = create_workqueue("sdio_wq");
7362 #endif
7363 INIT_DELAYED_WORK(&adapter->checkbt_work, (void*)check_bt_status_work);
7364 }
7365
rtl8723bs_free_checkbthang_workqueue(_adapter * adapter)7366 void rtl8723bs_free_checkbthang_workqueue(_adapter * adapter)
7367 {
7368 if (adapter->priv_checkbt_wq) {
7369 cancel_delayed_work_sync(&adapter->checkbt_work);
7370 flush_workqueue(adapter->priv_checkbt_wq);
7371 destroy_workqueue(adapter->priv_checkbt_wq);
7372 adapter->priv_checkbt_wq = NULL;
7373 }
7374 }
7375
rtl8723bs_cancle_checkbthang_workqueue(_adapter * adapter)7376 void rtl8723bs_cancle_checkbthang_workqueue(_adapter * adapter)
7377 {
7378 if (adapter->priv_checkbt_wq) {
7379 cancel_delayed_work_sync(&adapter->checkbt_work);
7380 }
7381 }
7382
rtl8723bs_hal_check_bt_hang(_adapter * adapter)7383 void rtl8723bs_hal_check_bt_hang(_adapter * adapter)
7384 {
7385 if (adapter->priv_checkbt_wq)
7386 queue_delayed_work(adapter->priv_checkbt_wq, &(adapter->checkbt_work), 0);
7387 }
7388 #endif
7389
7390 #ifdef CONFIG_GPIO_API
rtl8723b_GpioFuncCheck(PADAPTER adapter,u8 gpio_num)7391 int rtl8723b_GpioFuncCheck(PADAPTER adapter, u8 gpio_num)
7392 {
7393 int ret = _SUCCESS;
7394
7395 if (IS_HARDWARE_TYPE_8723B(adapter) == _FAIL) {
7396 if((gpio_num > 15) || (gpio_num < 4)) {
7397 DBG_871X("%s The gpio number does not included 4~5.\n",__FUNCTION__);
7398 ret = _FAIL;
7399 }
7400 }
7401
7402 return ret;
7403 }
7404
rtl8723b_GpioMultiFuncReset(PADAPTER adapter,u8 gpio_num)7405 VOID rtl8723b_GpioMultiFuncReset(PADAPTER adapter, u8 gpio_num)
7406 {
7407 u8 value8 = 0;
7408 u16 value16 = 0;
7409 u32 value32 = 0;
7410
7411 if (IS_HARDWARE_TYPE_8723B(adapter) == _FAIL)
7412 return ;
7413
7414 switch (gpio_num) {
7415 case 6:
7416 /* check 0x66[4] */
7417 value8 = rtw_read8(adapter, 0x66);
7418 if (value8 & BIT4)
7419 rtw_write8(adapter, 0x66, value8 & ~BIT4);
7420
7421 /* check 0x40[4] */
7422 value8 = rtw_read8(adapter, REG_GPIO_MUXCFG);
7423 if (value8 & BIT4)
7424 rtw_write8(adapter, REG_GPIO_MUXCFG, value8 & ~BIT4);
7425
7426 /* check 0x66[8] */
7427 value16 = rtw_read16(adapter, 0x66);
7428 if (value16 & BIT8)
7429 rtw_write16(adapter, 0x66, value16 & ~BIT8);
7430
7431 /* check 0x8[8] */
7432 value16 = rtw_read16(adapter, REG_SYS_CLKR);
7433 if (value16 & BIT8)
7434 rtw_write16(adapter, REG_SYS_CLKR, value16 & ~BIT8);
7435
7436 /* check 0x64[26] */
7437 value32 = rtw_read32(adapter, 0x64);
7438 if (value32 & BIT26)
7439 rtw_write32(adapter, 0x64, value32 & ~BIT26);
7440
7441 /* check 0x40[8] */
7442 value16 = rtw_read16(adapter, REG_GPIO_MUXCFG);
7443 if (value16 & BIT8)
7444 rtw_write16(adapter, REG_GPIO_MUXCFG, value16 & ~BIT8);
7445 break;
7446 case 8:
7447 /* check 0x48[16] */
7448 value32 = rtw_read32(adapter, REG_GPIO_INTM);
7449 if (value32 & BIT16)
7450 rtw_write32(adapter, REG_GPIO_INTM, value32 & ~BIT16);
7451
7452 /* check 0x4C[21] */
7453 value32 = rtw_read32(adapter, REG_LEDCFG0);
7454 if (value32 & BIT21)
7455 rtw_write32(adapter, REG_LEDCFG0, value32 & ~BIT21);
7456
7457 /* check 0x68[2] */
7458 value8 = rtw_read8(adapter, REG_MULTI_FUNC_CTRL);
7459 if (!(value8 & BIT2))
7460 rtw_write8(adapter, REG_MULTI_FUNC_CTRL, value8 | BIT2);
7461 break;
7462 case 12:
7463 /* check 0x48[18] */
7464 value32 = rtw_read32(adapter, REG_GPIO_INTM);
7465 if (value32 & BIT18)
7466 rtw_write32(adapter, REG_GPIO_INTM, value32 & ~BIT18);
7467
7468 /* check 0x4C[22] */
7469 value32 = rtw_read32(adapter, REG_LEDCFG0);
7470 if (value32 & BIT22)
7471 rtw_write32(adapter, REG_LEDCFG0, value32 & ~BIT22);
7472
7473 /* check 0x66[6] */
7474 value8 = rtw_read8(adapter, 0x66);
7475 if (value8 & BIT6)
7476 rtw_write8(adapter, 0x66, value8 & ~BIT6);
7477 break;
7478 default:
7479 DBG_871X("%s: Invalid GPIO num\n", __FUNCTION__);
7480 break;
7481 }
7482
7483 }
7484 #endif
7485
7486