xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8723bu/hal/rtl8723b/rtl8723b_hal_init.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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