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