1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #define _HAL_INIT_C_
8 
9 #include <linux/firmware.h>
10 #include <linux/slab.h>
11 #include <drv_types.h>
12 #include <rtw_debug.h>
13 #include <rtl8723b_hal.h>
14 #include "hal_com_h2c.h"
15 
16 static void _FWDownloadEnable(struct adapter *padapter, bool enable)
17 {
18 	u8 tmp, count = 0;
19 
20 	if (enable) {
21 		/*  8051 enable */
22 		tmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
23 		rtw_write8(padapter, REG_SYS_FUNC_EN+1, tmp|0x04);
24 
25 		tmp = rtw_read8(padapter, REG_MCUFWDL);
26 		rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
27 
28 		do {
29 			tmp = rtw_read8(padapter, REG_MCUFWDL);
30 			if (tmp & 0x01)
31 				break;
32 			rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
33 			msleep(1);
34 		} while (count++ < 100);
35 
36 		/*  8051 reset */
37 		tmp = rtw_read8(padapter, REG_MCUFWDL+2);
38 		rtw_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
39 	} else {
40 		/*  MCU firmware download disable. */
41 		tmp = rtw_read8(padapter, REG_MCUFWDL);
42 		rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
43 	}
44 }
45 
46 static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize)
47 {
48 	int ret = _SUCCESS;
49 
50 	u32 blockSize_p1 = 4; /*  (Default) Phase #1 : PCI muse use 4-byte write to download FW */
51 	u32 blockSize_p2 = 8; /*  Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */
52 	u32 blockSize_p3 = 1; /*  Phase #3 : Use 1-byte, the remnant of FW image. */
53 	u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
54 	u32 remainSize_p1 = 0, remainSize_p2 = 0;
55 	u8 *bufferPtr = buffer;
56 	u32 i = 0, offset = 0;
57 
58 /* 	printk("====>%s %d\n", __func__, __LINE__); */
59 
60 	/* 3 Phase #1 */
61 	blockCount_p1 = buffSize / blockSize_p1;
62 	remainSize_p1 = buffSize % blockSize_p1;
63 
64 	for (i = 0; i < blockCount_p1; i++) {
65 		ret = rtw_write32(padapter, (FW_8723B_START_ADDRESS + i * blockSize_p1), *((u32 *)(bufferPtr + i * blockSize_p1)));
66 		if (ret == _FAIL) {
67 			printk("====>%s %d i:%d\n", __func__, __LINE__, i);
68 			goto exit;
69 		}
70 	}
71 
72 	/* 3 Phase #2 */
73 	if (remainSize_p1) {
74 		offset = blockCount_p1 * blockSize_p1;
75 
76 		blockCount_p2 = remainSize_p1/blockSize_p2;
77 		remainSize_p2 = remainSize_p1%blockSize_p2;
78 	}
79 
80 	/* 3 Phase #3 */
81 	if (remainSize_p2) {
82 		offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
83 
84 		blockCount_p3 = remainSize_p2 / blockSize_p3;
85 
86 		for (i = 0; i < blockCount_p3; i++) {
87 			ret = rtw_write8(padapter, (FW_8723B_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
88 
89 			if (ret == _FAIL) {
90 				printk("====>%s %d i:%d\n", __func__, __LINE__, i);
91 				goto exit;
92 			}
93 		}
94 	}
95 exit:
96 	return ret;
97 }
98 
99 static int _PageWrite(
100 	struct adapter *padapter,
101 	u32 page,
102 	void *buffer,
103 	u32 size
104 )
105 {
106 	u8 value8;
107 	u8 u8Page = (u8) (page & 0x07);
108 
109 	value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page;
110 	rtw_write8(padapter, REG_MCUFWDL+2, value8);
111 
112 	return _BlockWrite(padapter, buffer, size);
113 }
114 
115 static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
116 {
117 	/*  Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */
118 	/*  We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */
119 	int ret = _SUCCESS;
120 	u32 pageNums, remainSize;
121 	u32 page, offset;
122 	u8 *bufferPtr = buffer;
123 
124 	pageNums = size / MAX_DLFW_PAGE_SIZE;
125 	remainSize = size % MAX_DLFW_PAGE_SIZE;
126 
127 	for (page = 0; page < pageNums; page++) {
128 		offset = page * MAX_DLFW_PAGE_SIZE;
129 		ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_DLFW_PAGE_SIZE);
130 
131 		if (ret == _FAIL) {
132 			printk("====>%s %d\n", __func__, __LINE__);
133 			goto exit;
134 		}
135 	}
136 
137 	if (remainSize) {
138 		offset = pageNums * MAX_DLFW_PAGE_SIZE;
139 		page = pageNums;
140 		ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize);
141 
142 		if (ret == _FAIL) {
143 			printk("====>%s %d\n", __func__, __LINE__);
144 			goto exit;
145 		}
146 	}
147 
148 exit:
149 	return ret;
150 }
151 
152 void _8051Reset8723(struct adapter *padapter)
153 {
154 	u8 cpu_rst;
155 	u8 io_rst;
156 
157 
158 	/*  Reset 8051(WLMCU) IO wrapper */
159 	/*  0x1c[8] = 0 */
160 	/*  Suggested by Isaac@SD1 and Gimmy@SD1, coding by Lucas@20130624 */
161 	io_rst = rtw_read8(padapter, REG_RSV_CTRL+1);
162 	io_rst &= ~BIT(0);
163 	rtw_write8(padapter, REG_RSV_CTRL+1, io_rst);
164 
165 	cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
166 	cpu_rst &= ~BIT(2);
167 	rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst);
168 
169 	/*  Enable 8051 IO wrapper */
170 	/*  0x1c[8] = 1 */
171 	io_rst = rtw_read8(padapter, REG_RSV_CTRL+1);
172 	io_rst |= BIT(0);
173 	rtw_write8(padapter, REG_RSV_CTRL+1, io_rst);
174 
175 	cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
176 	cpu_rst |= BIT(2);
177 	rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst);
178 }
179 
180 u8 g_fwdl_chksum_fail;
181 
182 static s32 polling_fwdl_chksum(
183 	struct adapter *adapter, u32 min_cnt, u32 timeout_ms
184 )
185 {
186 	s32 ret = _FAIL;
187 	u32 value32;
188 	unsigned long start = jiffies;
189 	u32 cnt = 0;
190 
191 	/* polling CheckSum report */
192 	do {
193 		cnt++;
194 		value32 = rtw_read32(adapter, REG_MCUFWDL);
195 		if (value32 & FWDL_ChkSum_rpt || adapter->bSurpriseRemoved || adapter->bDriverStopped)
196 			break;
197 		yield();
198 	} while (jiffies_to_msecs(jiffies-start) < timeout_ms || cnt < min_cnt);
199 
200 	if (!(value32 & FWDL_ChkSum_rpt)) {
201 		goto exit;
202 	}
203 
204 	if (g_fwdl_chksum_fail) {
205 		g_fwdl_chksum_fail--;
206 		goto exit;
207 	}
208 
209 	ret = _SUCCESS;
210 
211 exit:
212 
213 	return ret;
214 }
215 
216 u8 g_fwdl_wintint_rdy_fail;
217 
218 static s32 _FWFreeToGo(struct adapter *adapter, u32 min_cnt, u32 timeout_ms)
219 {
220 	s32 ret = _FAIL;
221 	u32 value32;
222 	unsigned long start = jiffies;
223 	u32 cnt = 0;
224 
225 	value32 = rtw_read32(adapter, REG_MCUFWDL);
226 	value32 |= MCUFWDL_RDY;
227 	value32 &= ~WINTINI_RDY;
228 	rtw_write32(adapter, REG_MCUFWDL, value32);
229 
230 	_8051Reset8723(adapter);
231 
232 	/*  polling for FW ready */
233 	do {
234 		cnt++;
235 		value32 = rtw_read32(adapter, REG_MCUFWDL);
236 		if (value32 & WINTINI_RDY || adapter->bSurpriseRemoved || adapter->bDriverStopped)
237 			break;
238 		yield();
239 	} while (jiffies_to_msecs(jiffies - start) < timeout_ms || cnt < min_cnt);
240 
241 	if (!(value32 & WINTINI_RDY)) {
242 		goto exit;
243 	}
244 
245 	if (g_fwdl_wintint_rdy_fail) {
246 		g_fwdl_wintint_rdy_fail--;
247 		goto exit;
248 	}
249 
250 	ret = _SUCCESS;
251 
252 exit:
253 
254 	return ret;
255 }
256 
257 #define IS_FW_81xxC(padapter)	(((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
258 
259 void rtl8723b_FirmwareSelfReset(struct adapter *padapter)
260 {
261 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
262 	u8 u1bTmp;
263 	u8 Delay = 100;
264 
265 	if (
266 		!(IS_FW_81xxC(padapter) && ((pHalData->FirmwareVersion < 0x21) || (pHalData->FirmwareVersion == 0x21 && pHalData->FirmwareSubVersion < 0x01)))
267 	) { /*  after 88C Fw v33.1 */
268 		/* 0x1cf = 0x20. Inform 8051 to reset. 2009.12.25. tynli_test */
269 		rtw_write8(padapter, REG_HMETFR+3, 0x20);
270 
271 		u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
272 		while (u1bTmp & BIT2) {
273 			Delay--;
274 			if (Delay == 0)
275 				break;
276 			udelay(50);
277 			u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
278 		}
279 
280 		if (Delay == 0) {
281 			/* force firmware reset */
282 			u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
283 			rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
284 		}
285 	}
286 }
287 
288 /*  */
289 /* 	Description: */
290 /* 		Download 8192C firmware code. */
291 /*  */
292 /*  */
293 s32 rtl8723b_FirmwareDownload(struct adapter *padapter, bool  bUsedWoWLANFw)
294 {
295 	s32 rtStatus = _SUCCESS;
296 	u8 write_fw = 0;
297 	unsigned long fwdl_start_time;
298 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
299 	struct rt_firmware *pFirmware;
300 	struct rt_firmware *pBTFirmware;
301 	struct rt_firmware_hdr *pFwHdr = NULL;
302 	u8 *pFirmwareBuf;
303 	u32 FirmwareLen;
304 	const struct firmware *fw;
305 	struct device *device = dvobj_to_dev(padapter->dvobj);
306 	u8 *fwfilepath;
307 	struct dvobj_priv *psdpriv = padapter->dvobj;
308 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
309 	u8 tmp_ps;
310 
311 	pFirmware = kzalloc(sizeof(struct rt_firmware), GFP_KERNEL);
312 	if (!pFirmware)
313 		return _FAIL;
314 	pBTFirmware = kzalloc(sizeof(struct rt_firmware), GFP_KERNEL);
315 	if (!pBTFirmware) {
316 		kfree(pFirmware);
317 		return _FAIL;
318 	}
319 	tmp_ps = rtw_read8(padapter, 0xa3);
320 	tmp_ps &= 0xf8;
321 	tmp_ps |= 0x02;
322 	/* 1. write 0xA3[:2:0] = 3b'010 */
323 	rtw_write8(padapter, 0xa3, tmp_ps);
324 	/* 2. read power_state = 0xA0[1:0] */
325 	tmp_ps = rtw_read8(padapter, 0xa0);
326 	tmp_ps &= 0x03;
327 	if (tmp_ps != 0x01)
328 		pdbgpriv->dbg_downloadfw_pwr_state_cnt++;
329 
330 	fwfilepath = "rtlwifi/rtl8723bs_nic.bin";
331 
332 	pr_info("rtl8723bs: acquire FW from file:%s\n", fwfilepath);
333 
334 	rtStatus = request_firmware(&fw, fwfilepath, device);
335 	if (rtStatus) {
336 		pr_err("Request firmware failed with error 0x%x\n", rtStatus);
337 		rtStatus = _FAIL;
338 		goto exit;
339 	}
340 
341 	if (!fw) {
342 		pr_err("Firmware %s not available\n", fwfilepath);
343 		rtStatus = _FAIL;
344 		goto exit;
345 	}
346 
347 	if (fw->size > FW_8723B_SIZE) {
348 		rtStatus = _FAIL;
349 		goto exit;
350 	}
351 
352 	pFirmware->fw_buffer_sz = kmemdup(fw->data, fw->size, GFP_KERNEL);
353 	if (!pFirmware->fw_buffer_sz) {
354 		rtStatus = _FAIL;
355 		goto exit;
356 	}
357 
358 	pFirmware->fw_length = fw->size;
359 	release_firmware(fw);
360 	if (pFirmware->fw_length > FW_8723B_SIZE) {
361 		rtStatus = _FAIL;
362 		netdev_emerg(padapter->pnetdev,
363 			     "Firmware size:%u exceed %u\n",
364 			     pFirmware->fw_length, FW_8723B_SIZE);
365 		goto release_fw1;
366 	}
367 
368 	pFirmwareBuf = pFirmware->fw_buffer_sz;
369 	FirmwareLen = pFirmware->fw_length;
370 
371 	/*  To Check Fw header. Added by tynli. 2009.12.04. */
372 	pFwHdr = (struct rt_firmware_hdr *)pFirmwareBuf;
373 
374 	pHalData->FirmwareVersion =  le16_to_cpu(pFwHdr->version);
375 	pHalData->FirmwareSubVersion = le16_to_cpu(pFwHdr->subversion);
376 	pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->signature);
377 
378 	if (IS_FW_HEADER_EXIST_8723B(pFwHdr)) {
379 		/*  Shift 32 bytes for FW header */
380 		pFirmwareBuf = pFirmwareBuf + 32;
381 		FirmwareLen = FirmwareLen - 32;
382 	}
383 
384 	/*  Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
385 	/*  or it will cause download Fw fail. 2010.02.01. by tynli. */
386 	if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
387 		rtw_write8(padapter, REG_MCUFWDL, 0x00);
388 		rtl8723b_FirmwareSelfReset(padapter);
389 	}
390 
391 	_FWDownloadEnable(padapter, true);
392 	fwdl_start_time = jiffies;
393 	while (
394 		!padapter->bDriverStopped &&
395 		!padapter->bSurpriseRemoved &&
396 		(write_fw++ < 3 || jiffies_to_msecs(jiffies - fwdl_start_time) < 500)
397 	) {
398 		/* reset FWDL chksum */
399 		rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL)|FWDL_ChkSum_rpt);
400 
401 		rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
402 		if (rtStatus != _SUCCESS)
403 			continue;
404 
405 		rtStatus = polling_fwdl_chksum(padapter, 5, 50);
406 		if (rtStatus == _SUCCESS)
407 			break;
408 	}
409 	_FWDownloadEnable(padapter, false);
410 	if (_SUCCESS != rtStatus)
411 		goto fwdl_stat;
412 
413 	rtStatus = _FWFreeToGo(padapter, 10, 200);
414 	if (_SUCCESS != rtStatus)
415 		goto fwdl_stat;
416 
417 fwdl_stat:
418 
419 exit:
420 	kfree(pFirmware->fw_buffer_sz);
421 	kfree(pFirmware);
422 release_fw1:
423 	kfree(pBTFirmware);
424 	return rtStatus;
425 }
426 
427 void rtl8723b_InitializeFirmwareVars(struct adapter *padapter)
428 {
429 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
430 
431 	/*  Init Fw LPS related. */
432 	adapter_to_pwrctl(padapter)->fw_current_in_ps_mode = false;
433 
434 	/* Init H2C cmd. */
435 	rtw_write8(padapter, REG_HMETFR, 0x0f);
436 
437 	/*  Init H2C counter. by tynli. 2009.12.09. */
438 	pHalData->LastHMEBoxNum = 0;
439 /* pHalData->H2CQueueHead = 0; */
440 /* pHalData->H2CQueueTail = 0; */
441 /* pHalData->H2CStopInsertQueue = false; */
442 }
443 
444 static void rtl8723b_free_hal_data(struct adapter *padapter)
445 {
446 }
447 
448 /*  */
449 /* 				Efuse related code */
450 /*  */
451 static u8 hal_EfuseSwitchToBank(
452 	struct adapter *padapter, u8 bank, bool bPseudoTest
453 )
454 {
455 	u8 bRet = false;
456 	u32 value32 = 0;
457 #ifdef HAL_EFUSE_MEMORY
458 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
459 	struct efuse_hal *pEfuseHal = &pHalData->EfuseHal;
460 #endif
461 
462 
463 	if (bPseudoTest) {
464 #ifdef HAL_EFUSE_MEMORY
465 		pEfuseHal->fakeEfuseBank = bank;
466 #else
467 		fakeEfuseBank = bank;
468 #endif
469 		bRet = true;
470 	} else {
471 		value32 = rtw_read32(padapter, EFUSE_TEST);
472 		bRet = true;
473 		switch (bank) {
474 		case 0:
475 			value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
476 			break;
477 		case 1:
478 			value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
479 			break;
480 		case 2:
481 			value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
482 			break;
483 		case 3:
484 			value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
485 			break;
486 		default:
487 			value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
488 			bRet = false;
489 			break;
490 		}
491 		rtw_write32(padapter, EFUSE_TEST, value32);
492 	}
493 
494 	return bRet;
495 }
496 
497 static void Hal_GetEfuseDefinition(
498 	struct adapter *padapter,
499 	u8 efuseType,
500 	u8 type,
501 	void *pOut,
502 	bool bPseudoTest
503 )
504 {
505 	switch (type) {
506 	case TYPE_EFUSE_MAX_SECTION:
507 		{
508 			u8 *pMax_section;
509 			pMax_section = pOut;
510 
511 			if (efuseType == EFUSE_WIFI)
512 				*pMax_section = EFUSE_MAX_SECTION_8723B;
513 			else
514 				*pMax_section = EFUSE_BT_MAX_SECTION;
515 		}
516 		break;
517 
518 	case TYPE_EFUSE_REAL_CONTENT_LEN:
519 		{
520 			u16 *pu2Tmp;
521 			pu2Tmp = pOut;
522 
523 			if (efuseType == EFUSE_WIFI)
524 				*pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
525 			else
526 				*pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
527 		}
528 		break;
529 
530 	case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
531 		{
532 			u16 *pu2Tmp;
533 			pu2Tmp = pOut;
534 
535 			if (efuseType == EFUSE_WIFI)
536 				*pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
537 			else
538 				*pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN-EFUSE_PROTECT_BYTES_BANK);
539 		}
540 		break;
541 
542 	case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
543 		{
544 			u16 *pu2Tmp;
545 			pu2Tmp = pOut;
546 
547 			if (efuseType == EFUSE_WIFI)
548 				*pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
549 			else
550 				*pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN-(EFUSE_PROTECT_BYTES_BANK*3));
551 		}
552 		break;
553 
554 	case TYPE_EFUSE_MAP_LEN:
555 		{
556 			u16 *pu2Tmp;
557 			pu2Tmp = pOut;
558 
559 			if (efuseType == EFUSE_WIFI)
560 				*pu2Tmp = EFUSE_MAX_MAP_LEN;
561 			else
562 				*pu2Tmp = EFUSE_BT_MAP_LEN;
563 		}
564 		break;
565 
566 	case TYPE_EFUSE_PROTECT_BYTES_BANK:
567 		{
568 			u8 *pu1Tmp;
569 			pu1Tmp = pOut;
570 
571 			if (efuseType == EFUSE_WIFI)
572 				*pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
573 			else
574 				*pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
575 		}
576 		break;
577 
578 	case TYPE_EFUSE_CONTENT_LEN_BANK:
579 		{
580 			u16 *pu2Tmp;
581 			pu2Tmp = pOut;
582 
583 			if (efuseType == EFUSE_WIFI)
584 				*pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
585 			else
586 				*pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
587 		}
588 		break;
589 
590 	default:
591 		{
592 			u8 *pu1Tmp;
593 			pu1Tmp = pOut;
594 			*pu1Tmp = 0;
595 		}
596 		break;
597 	}
598 }
599 
600 #define VOLTAGE_V25		0x03
601 #define LDOE25_SHIFT	28
602 
603 /*  */
604 /* 	The following is for compile ok */
605 /* 	That should be merged with the original in the future */
606 /*  */
607 #define EFUSE_ACCESS_ON_8723			0x69	/*  For RTL8723 only. */
608 #define EFUSE_ACCESS_OFF_8723			0x00	/*  For RTL8723 only. */
609 #define REG_EFUSE_ACCESS_8723			0x00CF	/*  Efuse access protection for RTL8723 */
610 
611 /*  */
612 static void Hal_BT_EfusePowerSwitch(
613 	struct adapter *padapter, u8 bWrite, u8 PwrState
614 )
615 {
616 	u8 tempval;
617 	if (PwrState) {
618 		/*  enable BT power cut */
619 		/*  0x6A[14] = 1 */
620 		tempval = rtw_read8(padapter, 0x6B);
621 		tempval |= BIT(6);
622 		rtw_write8(padapter, 0x6B, tempval);
623 
624 		/*  Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */
625 		/*  So don't write 0x6A[14]= 1 and 0x6A[15]= 0 together! */
626 		msleep(1);
627 		/*  disable BT output isolation */
628 		/*  0x6A[15] = 0 */
629 		tempval = rtw_read8(padapter, 0x6B);
630 		tempval &= ~BIT(7);
631 		rtw_write8(padapter, 0x6B, tempval);
632 	} else {
633 		/*  enable BT output isolation */
634 		/*  0x6A[15] = 1 */
635 		tempval = rtw_read8(padapter, 0x6B);
636 		tempval |= BIT(7);
637 		rtw_write8(padapter, 0x6B, tempval);
638 
639 		/*  Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */
640 		/*  So don't write 0x6A[14]= 1 and 0x6A[15]= 0 together! */
641 
642 		/*  disable BT power cut */
643 		/*  0x6A[14] = 1 */
644 		tempval = rtw_read8(padapter, 0x6B);
645 		tempval &= ~BIT(6);
646 		rtw_write8(padapter, 0x6B, tempval);
647 	}
648 
649 }
650 static void Hal_EfusePowerSwitch(
651 	struct adapter *padapter, u8 bWrite, u8 PwrState
652 )
653 {
654 	u8 tempval;
655 	u16 tmpV16;
656 
657 
658 	if (PwrState) {
659 		/*  To avoid cannot access efuse regsiters after disable/enable several times during DTM test. */
660 		/*  Suggested by SD1 IsaacHsu. 2013.07.08, added by tynli. */
661 		tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
662 		if (tempval & BIT(0)) { /*  SDIO local register is suspend */
663 			u8 count = 0;
664 
665 
666 			tempval &= ~BIT(0);
667 			rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL, tempval);
668 
669 			/*  check 0x86[1:0]= 10'2h, wait power state to leave suspend */
670 			do {
671 				tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
672 				tempval &= 0x3;
673 				if (tempval == 0x02)
674 					break;
675 
676 				count++;
677 				if (count >= 100)
678 					break;
679 
680 				mdelay(10);
681 			} while (1);
682 		}
683 
684 		rtw_write8(padapter, REG_EFUSE_ACCESS_8723, EFUSE_ACCESS_ON_8723);
685 
686 		/*  Reset: 0x0000h[28], default valid */
687 		tmpV16 =  rtw_read16(padapter, REG_SYS_FUNC_EN);
688 		if (!(tmpV16 & FEN_ELDR)) {
689 			tmpV16 |= FEN_ELDR;
690 			rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
691 		}
692 
693 		/*  Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
694 		tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
695 		if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
696 			tmpV16 |= (LOADER_CLK_EN | ANA8M);
697 			rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
698 		}
699 
700 		if (bWrite) {
701 			/*  Enable LDO 2.5V before read/write action */
702 			tempval = rtw_read8(padapter, EFUSE_TEST+3);
703 			tempval &= 0x0F;
704 			tempval |= (VOLTAGE_V25 << 4);
705 			rtw_write8(padapter, EFUSE_TEST+3, (tempval | 0x80));
706 
707 			/* rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); */
708 		}
709 	} else {
710 		rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
711 
712 		if (bWrite) {
713 			/*  Disable LDO 2.5V after read/write action */
714 			tempval = rtw_read8(padapter, EFUSE_TEST+3);
715 			rtw_write8(padapter, EFUSE_TEST+3, (tempval & 0x7F));
716 		}
717 
718 	}
719 }
720 
721 static void hal_ReadEFuse_WiFi(
722 	struct adapter *padapter,
723 	u16 _offset,
724 	u16 _size_byte,
725 	u8 *pbuf,
726 	bool bPseudoTest
727 )
728 {
729 #ifdef HAL_EFUSE_MEMORY
730 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
731 	struct efuse_hal *pEfuseHal = &pHalData->EfuseHal;
732 #endif
733 	u8 *efuseTbl = NULL;
734 	u16 eFuse_Addr = 0;
735 	u8 offset, wden;
736 	u8 efuseHeader, efuseExtHdr, efuseData;
737 	u16 i, total, used;
738 	u8 efuse_usage = 0;
739 
740 	/*  */
741 	/*  Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
742 	/*  */
743 	if ((_offset + _size_byte) > EFUSE_MAX_MAP_LEN)
744 		return;
745 
746 	efuseTbl = rtw_malloc(EFUSE_MAX_MAP_LEN);
747 	if (!efuseTbl)
748 		return;
749 
750 	/*  0xff will be efuse default value instead of 0x00. */
751 	memset(efuseTbl, 0xFF, EFUSE_MAX_MAP_LEN);
752 
753 	/*  switch bank back to bank 0 for later BT and wifi use. */
754 	hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
755 
756 	while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
757 		efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
758 		if (efuseHeader == 0xFF)
759 			break;
760 
761 		/*  Check PG header for section num. */
762 		if (EXT_HEADER(efuseHeader)) { /* extended header */
763 			offset = GET_HDR_OFFSET_2_0(efuseHeader);
764 
765 			efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
766 			if (ALL_WORDS_DISABLED(efuseExtHdr))
767 				continue;
768 
769 			offset |= ((efuseExtHdr & 0xF0) >> 1);
770 			wden = (efuseExtHdr & 0x0F);
771 		} else {
772 			offset = ((efuseHeader >> 4) & 0x0f);
773 			wden = (efuseHeader & 0x0f);
774 		}
775 
776 		if (offset < EFUSE_MAX_SECTION_8723B) {
777 			u16 addr;
778 			/*  Get word enable value from PG header */
779 
780 			addr = offset * PGPKT_DATA_SIZE;
781 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
782 				/*  Check word enable condition in the section */
783 				if (!(wden & (0x01<<i))) {
784 					efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
785 					efuseTbl[addr] = efuseData;
786 
787 					efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
788 					efuseTbl[addr+1] = efuseData;
789 				}
790 				addr += 2;
791 			}
792 		} else {
793 			eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
794 		}
795 	}
796 
797 	/*  Copy from Efuse map to output pointer memory!!! */
798 	for (i = 0; i < _size_byte; i++)
799 		pbuf[i] = efuseTbl[_offset+i];
800 
801 	/*  Calculate Efuse utilization */
802 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
803 	used = eFuse_Addr - 1;
804 	efuse_usage = (u8)((used*100)/total);
805 	if (bPseudoTest) {
806 #ifdef HAL_EFUSE_MEMORY
807 		pEfuseHal->fakeEfuseUsedBytes = used;
808 #else
809 		fakeEfuseUsedBytes = used;
810 #endif
811 	} else {
812 		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&used);
813 		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8 *)&efuse_usage);
814 	}
815 
816 	kfree(efuseTbl);
817 }
818 
819 static void hal_ReadEFuse_BT(
820 	struct adapter *padapter,
821 	u16 _offset,
822 	u16 _size_byte,
823 	u8 *pbuf,
824 	bool bPseudoTest
825 )
826 {
827 #ifdef HAL_EFUSE_MEMORY
828 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
829 	struct efuse_hal *pEfuseHal = &pHalData->EfuseHal;
830 #endif
831 	u8 *efuseTbl;
832 	u8 bank;
833 	u16 eFuse_Addr;
834 	u8 efuseHeader, efuseExtHdr, efuseData;
835 	u8 offset, wden;
836 	u16 i, total, used;
837 	u8 efuse_usage;
838 
839 
840 	/*  */
841 	/*  Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
842 	/*  */
843 	if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN)
844 		return;
845 
846 	efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);
847 	if (!efuseTbl)
848 		return;
849 
850 	/*  0xff will be efuse default value instead of 0x00. */
851 	memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
852 
853 	EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total, bPseudoTest);
854 
855 	for (bank = 1; bank < 3; bank++) { /*  8723b Max bake 0~2 */
856 		if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == false)
857 			goto exit;
858 
859 		eFuse_Addr = 0;
860 
861 		while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
862 			efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
863 			if (efuseHeader == 0xFF)
864 				break;
865 
866 			/*  Check PG header for section num. */
867 			if (EXT_HEADER(efuseHeader)) { /* extended header */
868 				offset = GET_HDR_OFFSET_2_0(efuseHeader);
869 
870 				efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
871 				if (ALL_WORDS_DISABLED(efuseExtHdr))
872 					continue;
873 
874 
875 				offset |= ((efuseExtHdr & 0xF0) >> 1);
876 				wden = (efuseExtHdr & 0x0F);
877 			} else {
878 				offset = ((efuseHeader >> 4) & 0x0f);
879 				wden = (efuseHeader & 0x0f);
880 			}
881 
882 			if (offset < EFUSE_BT_MAX_SECTION) {
883 				u16 addr;
884 
885 				addr = offset * PGPKT_DATA_SIZE;
886 				for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
887 					/*  Check word enable condition in the section */
888 					if (!(wden & (0x01<<i))) {
889 						efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
890 						efuseTbl[addr] = efuseData;
891 
892 						efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
893 						efuseTbl[addr+1] = efuseData;
894 					}
895 					addr += 2;
896 				}
897 			} else {
898 				eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
899 			}
900 		}
901 
902 		if ((eFuse_Addr - 1) < total)
903 			break;
904 
905 	}
906 
907 	/*  switch bank back to bank 0 for later BT and wifi use. */
908 	hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
909 
910 	/*  Copy from Efuse map to output pointer memory!!! */
911 	for (i = 0; i < _size_byte; i++)
912 		pbuf[i] = efuseTbl[_offset+i];
913 
914 	/*  */
915 	/*  Calculate Efuse utilization. */
916 	/*  */
917 	EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
918 	used = (EFUSE_BT_REAL_BANK_CONTENT_LEN*(bank-1)) + eFuse_Addr - 1;
919 	efuse_usage = (u8)((used*100)/total);
920 	if (bPseudoTest) {
921 #ifdef HAL_EFUSE_MEMORY
922 		pEfuseHal->fakeBTEfuseUsedBytes = used;
923 #else
924 		fakeBTEfuseUsedBytes = used;
925 #endif
926 	} else {
927 		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&used);
928 		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8 *)&efuse_usage);
929 	}
930 
931 exit:
932 	kfree(efuseTbl);
933 }
934 
935 static void Hal_ReadEFuse(
936 	struct adapter *padapter,
937 	u8 efuseType,
938 	u16 _offset,
939 	u16 _size_byte,
940 	u8 *pbuf,
941 	bool bPseudoTest
942 )
943 {
944 	if (efuseType == EFUSE_WIFI)
945 		hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf, bPseudoTest);
946 	else
947 		hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf, bPseudoTest);
948 }
949 
950 static u16 hal_EfuseGetCurrentSize_WiFi(
951 	struct adapter *padapter, bool bPseudoTest
952 )
953 {
954 #ifdef HAL_EFUSE_MEMORY
955 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
956 	struct efuse_hal *pEfuseHal = &pHalData->EfuseHal;
957 #endif
958 	u16 efuse_addr = 0;
959 	u16 start_addr = 0; /*  for debug */
960 	u8 hoffset = 0, hworden = 0;
961 	u8 efuse_data, word_cnts = 0;
962 	u32 count = 0; /*  for debug */
963 
964 
965 	if (bPseudoTest) {
966 #ifdef HAL_EFUSE_MEMORY
967 		efuse_addr = (u16)pEfuseHal->fakeEfuseUsedBytes;
968 #else
969 		efuse_addr = (u16)fakeEfuseUsedBytes;
970 #endif
971 	} else
972 		rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
973 
974 	start_addr = efuse_addr;
975 
976 	/*  switch bank back to bank 0 for later BT and wifi use. */
977 	hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
978 
979 	count = 0;
980 	while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
981 		if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == false)
982 			goto error;
983 
984 		if (efuse_data == 0xFF)
985 			break;
986 
987 		if ((start_addr != 0) && (efuse_addr == start_addr)) {
988 			count++;
989 
990 			efuse_data = 0xFF;
991 			if (count < 4) {
992 				/*  try again! */
993 
994 				if (count > 2) {
995 					/*  try again form address 0 */
996 					efuse_addr = 0;
997 					start_addr = 0;
998 				}
999 
1000 				continue;
1001 			}
1002 
1003 			goto error;
1004 		}
1005 
1006 		if (EXT_HEADER(efuse_data)) {
1007 			hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1008 			efuse_addr++;
1009 			efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1010 			if (ALL_WORDS_DISABLED(efuse_data))
1011 				continue;
1012 
1013 			hoffset |= ((efuse_data & 0xF0) >> 1);
1014 			hworden = efuse_data & 0x0F;
1015 		} else {
1016 			hoffset = (efuse_data>>4) & 0x0F;
1017 			hworden = efuse_data & 0x0F;
1018 		}
1019 
1020 		word_cnts = Efuse_CalculateWordCnts(hworden);
1021 		efuse_addr += (word_cnts*2)+1;
1022 	}
1023 
1024 	if (bPseudoTest) {
1025 #ifdef HAL_EFUSE_MEMORY
1026 		pEfuseHal->fakeEfuseUsedBytes = efuse_addr;
1027 #else
1028 		fakeEfuseUsedBytes = efuse_addr;
1029 #endif
1030 	} else
1031 		rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1032 
1033 	goto exit;
1034 
1035 error:
1036 	/*  report max size to prevent write efuse */
1037 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_addr, bPseudoTest);
1038 
1039 exit:
1040 
1041 	return efuse_addr;
1042 }
1043 
1044 static u16 hal_EfuseGetCurrentSize_BT(struct adapter *padapter, u8 bPseudoTest)
1045 {
1046 #ifdef HAL_EFUSE_MEMORY
1047 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1048 	struct efuse_hal *pEfuseHal = &pHalData->EfuseHal;
1049 #endif
1050 	u16 btusedbytes;
1051 	u16 efuse_addr;
1052 	u8 bank, startBank;
1053 	u8 hoffset = 0, hworden = 0;
1054 	u8 efuse_data, word_cnts = 0;
1055 	u16 retU2 = 0;
1056 
1057 	if (bPseudoTest) {
1058 #ifdef HAL_EFUSE_MEMORY
1059 		btusedbytes = pEfuseHal->fakeBTEfuseUsedBytes;
1060 #else
1061 		btusedbytes = fakeBTEfuseUsedBytes;
1062 #endif
1063 	} else
1064 		rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&btusedbytes);
1065 
1066 	efuse_addr = (u16)((btusedbytes%EFUSE_BT_REAL_BANK_CONTENT_LEN));
1067 	startBank = (u8)(1+(btusedbytes/EFUSE_BT_REAL_BANK_CONTENT_LEN));
1068 
1069 	EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2, bPseudoTest);
1070 
1071 	for (bank = startBank; bank < 3; bank++) {
1072 		if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == false)
1073 			/* bank = EFUSE_MAX_BANK; */
1074 			break;
1075 
1076 		/*  only when bank is switched we have to reset the efuse_addr. */
1077 		if (bank != startBank)
1078 			efuse_addr = 0;
1079 #if 1
1080 
1081 		while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1082 			if (efuse_OneByteRead(padapter, efuse_addr,
1083 					      &efuse_data, bPseudoTest) == false)
1084 				/* bank = EFUSE_MAX_BANK; */
1085 				break;
1086 
1087 			if (efuse_data == 0xFF)
1088 				break;
1089 
1090 			if (EXT_HEADER(efuse_data)) {
1091 				hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1092 				efuse_addr++;
1093 				efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1094 
1095 				if (ALL_WORDS_DISABLED(efuse_data)) {
1096 					efuse_addr++;
1097 					continue;
1098 				}
1099 
1100 /* 				hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); */
1101 				hoffset |= ((efuse_data & 0xF0) >> 1);
1102 				hworden = efuse_data & 0x0F;
1103 			} else {
1104 				hoffset = (efuse_data>>4) & 0x0F;
1105 				hworden =  efuse_data & 0x0F;
1106 			}
1107 
1108 			word_cnts = Efuse_CalculateWordCnts(hworden);
1109 			/* read next header */
1110 			efuse_addr += (word_cnts*2)+1;
1111 		}
1112 #else
1113 	while (
1114 		bContinual &&
1115 		efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) &&
1116 		AVAILABLE_EFUSE_ADDR(efuse_addr)
1117 	) {
1118 			if (efuse_data != 0xFF) {
1119 				if ((efuse_data&0x1F) == 0x0F) { /* extended header */
1120 					hoffset = efuse_data;
1121 					efuse_addr++;
1122 					efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1123 					if ((efuse_data & 0x0F) == 0x0F) {
1124 						efuse_addr++;
1125 						continue;
1126 					} else {
1127 						hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1128 						hworden = efuse_data & 0x0F;
1129 					}
1130 				} else {
1131 					hoffset = (efuse_data>>4) & 0x0F;
1132 					hworden =  efuse_data & 0x0F;
1133 				}
1134 				word_cnts = Efuse_CalculateWordCnts(hworden);
1135 				/* read next header */
1136 				efuse_addr = efuse_addr + (word_cnts*2)+1;
1137 			} else
1138 				bContinual = false;
1139 		}
1140 #endif
1141 
1142 
1143 		/*  Check if we need to check next bank efuse */
1144 		if (efuse_addr < retU2)
1145 			break; /*  don't need to check next bank. */
1146 	}
1147 
1148 	retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN)+efuse_addr;
1149 	if (bPseudoTest) {
1150 		pEfuseHal->fakeBTEfuseUsedBytes = retU2;
1151 	} else {
1152 		pEfuseHal->BTEfuseUsedBytes = retU2;
1153 	}
1154 
1155 	return retU2;
1156 }
1157 
1158 static u16 Hal_EfuseGetCurrentSize(
1159 	struct adapter *padapter, u8 efuseType, bool bPseudoTest
1160 )
1161 {
1162 	u16 ret = 0;
1163 
1164 	if (efuseType == EFUSE_WIFI)
1165 		ret = hal_EfuseGetCurrentSize_WiFi(padapter, bPseudoTest);
1166 	else
1167 		ret = hal_EfuseGetCurrentSize_BT(padapter, bPseudoTest);
1168 
1169 	return ret;
1170 }
1171 
1172 static u8 Hal_EfuseWordEnableDataWrite(
1173 	struct adapter *padapter,
1174 	u16 efuse_addr,
1175 	u8 word_en,
1176 	u8 *data,
1177 	bool bPseudoTest
1178 )
1179 {
1180 	u16 tmpaddr = 0;
1181 	u16 start_addr = efuse_addr;
1182 	u8 badworden = 0x0F;
1183 	u8 tmpdata[PGPKT_DATA_SIZE];
1184 
1185 	memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
1186 
1187 	if (!(word_en & BIT(0))) {
1188 		tmpaddr = start_addr;
1189 		efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest);
1190 		efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest);
1191 
1192 		efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest);
1193 		efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[1], bPseudoTest);
1194 		if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) {
1195 			badworden &= (~BIT(0));
1196 		}
1197 	}
1198 	if (!(word_en & BIT(1))) {
1199 		tmpaddr = start_addr;
1200 		efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest);
1201 		efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest);
1202 
1203 		efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest);
1204 		efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[3], bPseudoTest);
1205 		if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) {
1206 			badworden &= (~BIT(1));
1207 		}
1208 	}
1209 
1210 	if (!(word_en & BIT(2))) {
1211 		tmpaddr = start_addr;
1212 		efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest);
1213 		efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest);
1214 
1215 		efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest);
1216 		efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[5], bPseudoTest);
1217 		if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) {
1218 			badworden &= (~BIT(2));
1219 		}
1220 	}
1221 
1222 	if (!(word_en & BIT(3))) {
1223 		tmpaddr = start_addr;
1224 		efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest);
1225 		efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest);
1226 
1227 		efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest);
1228 		efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[7], bPseudoTest);
1229 		if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) {
1230 			badworden &= (~BIT(3));
1231 		}
1232 	}
1233 
1234 	return badworden;
1235 }
1236 
1237 static s32 Hal_EfusePgPacketRead(
1238 	struct adapter *padapter,
1239 	u8 offset,
1240 	u8 *data,
1241 	bool bPseudoTest
1242 )
1243 {
1244 	u8 efuse_data, word_cnts = 0;
1245 	u16 efuse_addr = 0;
1246 	u8 hoffset = 0, hworden = 0;
1247 	u8 i;
1248 	u8 max_section = 0;
1249 	s32	ret;
1250 
1251 
1252 	if (!data)
1253 		return false;
1254 
1255 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest);
1256 	if (offset > max_section)
1257 		return false;
1258 
1259 	memset(data, 0xFF, PGPKT_DATA_SIZE);
1260 	ret = true;
1261 
1262 	/*  */
1263 	/*  <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */
1264 	/*  Skip dummy parts to prevent unexpected data read from Efuse. */
1265 	/*  By pass right now. 2009.02.19. */
1266 	/*  */
1267 	while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1268 		if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == false) {
1269 			ret = false;
1270 			break;
1271 		}
1272 
1273 		if (efuse_data == 0xFF)
1274 			break;
1275 
1276 		if (EXT_HEADER(efuse_data)) {
1277 			hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1278 			efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
1279 			if (ALL_WORDS_DISABLED(efuse_data))
1280 				continue;
1281 
1282 			hoffset |= ((efuse_data & 0xF0) >> 1);
1283 			hworden = efuse_data & 0x0F;
1284 		} else {
1285 			hoffset = (efuse_data>>4) & 0x0F;
1286 			hworden =  efuse_data & 0x0F;
1287 		}
1288 
1289 		if (hoffset == offset) {
1290 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
1291 				/*  Check word enable condition in the section */
1292 				if (!(hworden & (0x01<<i))) {
1293 					efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
1294 					data[i*2] = efuse_data;
1295 
1296 					efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
1297 					data[(i*2)+1] = efuse_data;
1298 				}
1299 			}
1300 		} else {
1301 			word_cnts = Efuse_CalculateWordCnts(hworden);
1302 			efuse_addr += word_cnts*2;
1303 		}
1304 	}
1305 
1306 	return ret;
1307 }
1308 
1309 static u8 hal_EfusePgCheckAvailableAddr(
1310 	struct adapter *padapter, u8 efuseType, u8 bPseudoTest
1311 )
1312 {
1313 	u16 max_available = 0;
1314 	u16 current_size;
1315 
1316 
1317 	EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &max_available, bPseudoTest);
1318 
1319 	current_size = Efuse_GetCurrentSize(padapter, efuseType, bPseudoTest);
1320 	if (current_size >= max_available)
1321 		return false;
1322 
1323 	return true;
1324 }
1325 
1326 static void hal_EfuseConstructPGPkt(
1327 	u8 offset,
1328 	u8 word_en,
1329 	u8 *pData,
1330 	struct pgpkt_struct *pTargetPkt
1331 )
1332 {
1333 	memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
1334 	pTargetPkt->offset = offset;
1335 	pTargetPkt->word_en = word_en;
1336 	efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
1337 	pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1338 }
1339 
1340 static u8 hal_EfusePartialWriteCheck(
1341 	struct adapter *padapter,
1342 	u8 efuseType,
1343 	u16 *pAddr,
1344 	struct pgpkt_struct *pTargetPkt,
1345 	u8 bPseudoTest
1346 )
1347 {
1348 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1349 	struct efuse_hal *pEfuseHal = &pHalData->EfuseHal;
1350 	u8 bRet = false;
1351 	u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
1352 	u8 efuse_data = 0;
1353 
1354 	EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest);
1355 	EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest);
1356 
1357 	if (efuseType == EFUSE_WIFI) {
1358 		if (bPseudoTest) {
1359 #ifdef HAL_EFUSE_MEMORY
1360 			startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes;
1361 #else
1362 			startAddr = (u16)fakeEfuseUsedBytes;
1363 #endif
1364 		} else
1365 			rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
1366 	} else {
1367 		if (bPseudoTest) {
1368 #ifdef HAL_EFUSE_MEMORY
1369 			startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes;
1370 #else
1371 			startAddr = (u16)fakeBTEfuseUsedBytes;
1372 #endif
1373 		} else
1374 			rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&startAddr);
1375 	}
1376 	startAddr %= efuse_max;
1377 
1378 	while (1) {
1379 		if (startAddr >= efuse_max_available_len) {
1380 			bRet = false;
1381 			break;
1382 		}
1383 
1384 		if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
1385 #if 1
1386 			bRet = false;
1387 			break;
1388 #else
1389 			if (EXT_HEADER(efuse_data)) {
1390 				cur_header = efuse_data;
1391 				startAddr++;
1392 				efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest);
1393 				if (ALL_WORDS_DISABLED(efuse_data)) {
1394 					bRet = false;
1395 					break;
1396 				} else {
1397 					curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1398 					curPkt.word_en = efuse_data & 0x0F;
1399 				}
1400 			} else {
1401 				cur_header  =  efuse_data;
1402 				curPkt.offset = (cur_header>>4) & 0x0F;
1403 				curPkt.word_en = cur_header & 0x0F;
1404 			}
1405 
1406 			curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
1407 			/*  if same header is found but no data followed */
1408 			/*  write some part of data followed by the header. */
1409 			if (
1410 				(curPkt.offset == pTargetPkt->offset) &&
1411 				(hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr+1, bPseudoTest) == false) &&
1412 				wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == true
1413 			) {
1414 				/*  Here to write partial data */
1415 				badworden = Efuse_WordEnableDataWrite(padapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest);
1416 				if (badworden != 0x0F) {
1417 					u32 PgWriteSuccess = 0;
1418 					/*  if write fail on some words, write these bad words again */
1419 					if (efuseType == EFUSE_WIFI)
1420 						PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
1421 					else
1422 						PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
1423 
1424 					if (!PgWriteSuccess) {
1425 						bRet = false;	/*  write fail, return */
1426 						break;
1427 					}
1428 				}
1429 				/*  partial write ok, update the target packet for later use */
1430 				for (i = 0; i < 4; i++) {
1431 					if ((matched_wden & (0x1<<i)) == 0) { /*  this word has been written */
1432 						pTargetPkt->word_en |= (0x1<<i);	/*  disable the word */
1433 					}
1434 				}
1435 				pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1436 			}
1437 			/*  read from next header */
1438 			startAddr = startAddr + (curPkt.word_cnts*2) + 1;
1439 #endif
1440 		} else {
1441 			/*  not used header, 0xff */
1442 			*pAddr = startAddr;
1443 			bRet = true;
1444 			break;
1445 		}
1446 	}
1447 
1448 	return bRet;
1449 }
1450 
1451 static u8 hal_EfusePgPacketWrite1ByteHeader(
1452 	struct adapter *padapter,
1453 	u8 efuseType,
1454 	u16 *pAddr,
1455 	struct pgpkt_struct *pTargetPkt,
1456 	u8 bPseudoTest
1457 )
1458 {
1459 	u8 pg_header = 0, tmp_header = 0;
1460 	u16 efuse_addr = *pAddr;
1461 	u8 repeatcnt = 0;
1462 
1463 	pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
1464 
1465 	do {
1466 		efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
1467 		efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
1468 		if (tmp_header != 0xFF)
1469 			break;
1470 		if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1471 			return false;
1472 
1473 	} while (1);
1474 
1475 	if (tmp_header != pg_header)
1476 		return false;
1477 
1478 	*pAddr = efuse_addr;
1479 
1480 	return true;
1481 }
1482 
1483 static u8 hal_EfusePgPacketWrite2ByteHeader(
1484 	struct adapter *padapter,
1485 	u8 efuseType,
1486 	u16 *pAddr,
1487 	struct pgpkt_struct *pTargetPkt,
1488 	u8 bPseudoTest
1489 )
1490 {
1491 	u16 efuse_addr, efuse_max_available_len = 0;
1492 	u8 pg_header = 0, tmp_header = 0;
1493 	u8 repeatcnt = 0;
1494 
1495 	EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest);
1496 
1497 	efuse_addr = *pAddr;
1498 	if (efuse_addr >= efuse_max_available_len)
1499 		return false;
1500 
1501 	pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
1502 
1503 	do {
1504 		efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
1505 		efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
1506 		if (tmp_header != 0xFF)
1507 			break;
1508 		if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1509 			return false;
1510 
1511 	} while (1);
1512 
1513 	if (tmp_header != pg_header)
1514 		return false;
1515 
1516 	/*  to write ext_header */
1517 	efuse_addr++;
1518 	pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
1519 
1520 	do {
1521 		efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
1522 		efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
1523 		if (tmp_header != 0xFF)
1524 			break;
1525 		if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1526 			return false;
1527 
1528 	} while (1);
1529 
1530 	if (tmp_header != pg_header) /* offset PG fail */
1531 		return false;
1532 
1533 	*pAddr = efuse_addr;
1534 
1535 	return true;
1536 }
1537 
1538 static u8 hal_EfusePgPacketWriteHeader(
1539 	struct adapter *padapter,
1540 	u8 efuseType,
1541 	u16 *pAddr,
1542 	struct pgpkt_struct *pTargetPkt,
1543 	u8 bPseudoTest
1544 )
1545 {
1546 	u8 bRet = false;
1547 
1548 	if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
1549 		bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
1550 	else
1551 		bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
1552 
1553 	return bRet;
1554 }
1555 
1556 static u8 hal_EfusePgPacketWriteData(
1557 	struct adapter *padapter,
1558 	u8 efuseType,
1559 	u16 *pAddr,
1560 	struct pgpkt_struct *pTargetPkt,
1561 	u8 bPseudoTest
1562 )
1563 {
1564 	u16 efuse_addr;
1565 	u8 badworden;
1566 
1567 
1568 	efuse_addr = *pAddr;
1569 	badworden = Efuse_WordEnableDataWrite(padapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
1570 	if (badworden != 0x0F)
1571 		return false;
1572 
1573 	return true;
1574 }
1575 
1576 static s32 Hal_EfusePgPacketWrite(
1577 	struct adapter *padapter,
1578 	u8 offset,
1579 	u8 word_en,
1580 	u8 *pData,
1581 	bool bPseudoTest
1582 )
1583 {
1584 	struct pgpkt_struct targetPkt;
1585 	u16 startAddr = 0;
1586 	u8 efuseType = EFUSE_WIFI;
1587 
1588 	if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest))
1589 		return false;
1590 
1591 	hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
1592 
1593 	if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1594 		return false;
1595 
1596 	if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1597 		return false;
1598 
1599 	if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1600 		return false;
1601 
1602 	return true;
1603 }
1604 
1605 static bool Hal_EfusePgPacketWrite_BT(
1606 	struct adapter *padapter,
1607 	u8 offset,
1608 	u8 word_en,
1609 	u8 *pData,
1610 	bool bPseudoTest
1611 )
1612 {
1613 	struct pgpkt_struct targetPkt;
1614 	u16 startAddr = 0;
1615 	u8 efuseType = EFUSE_BT;
1616 
1617 	if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest))
1618 		return false;
1619 
1620 	hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
1621 
1622 	if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1623 		return false;
1624 
1625 	if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1626 		return false;
1627 
1628 	if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1629 		return false;
1630 
1631 	return true;
1632 }
1633 
1634 static struct hal_version ReadChipVersion8723B(struct adapter *padapter)
1635 {
1636 	u32 value32;
1637 	struct hal_version ChipVersion;
1638 	struct hal_com_data *pHalData;
1639 
1640 /* YJ, TODO, move read chip type here */
1641 	pHalData = GET_HAL_DATA(padapter);
1642 
1643 	value32 = rtw_read32(padapter, REG_SYS_CFG);
1644 	ChipVersion.ICType = CHIP_8723B;
1645 	ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
1646 	ChipVersion.RFType = RF_TYPE_1T1R;
1647 	ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
1648 	ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; /*  IC version (CUT) */
1649 
1650 	/*  For regulator mode. by tynli. 2011.01.14 */
1651 	pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
1652 
1653 	value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
1654 	ChipVersion.ROMVer = ((value32 & RF_RL_ID) >> 20);	/*  ROM code version. */
1655 
1656 	/*  For multi-function consideration. Added by Roger, 2010.10.06. */
1657 	pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
1658 	value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
1659 	pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
1660 	pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
1661 	pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
1662 	pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT);
1663 #if 1
1664 	dump_chip_info(ChipVersion);
1665 #endif
1666 	pHalData->VersionID = ChipVersion;
1667 	if (IS_1T2R(ChipVersion))
1668 		pHalData->rf_type = RF_1T2R;
1669 	else if (IS_2T2R(ChipVersion))
1670 		pHalData->rf_type = RF_2T2R;
1671 	else
1672 		pHalData->rf_type = RF_1T1R;
1673 
1674 	return ChipVersion;
1675 }
1676 
1677 static void rtl8723b_read_chip_version(struct adapter *padapter)
1678 {
1679 	ReadChipVersion8723B(padapter);
1680 }
1681 
1682 void rtl8723b_InitBeaconParameters(struct adapter *padapter)
1683 {
1684 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1685 	u16 val16;
1686 	u8 val8;
1687 
1688 
1689 	val8 = DIS_TSF_UDT;
1690 	val16 = val8 | (val8 << 8); /*  port0 and port1 */
1691 
1692 	/*  Enable prot0 beacon function for PSTDMA */
1693 	val16 |= EN_BCN_FUNCTION;
1694 
1695 	rtw_write16(padapter, REG_BCN_CTRL, val16);
1696 
1697 	/*  TODO: Remove these magic number */
1698 	rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);/*  ms */
1699 	/*  Firmware will control REG_DRVERLYINT when power saving is enable, */
1700 	/*  so don't set this register on STA mode. */
1701 	if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == false)
1702 		rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8723B); /*  5ms */
1703 	rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8723B); /*  2ms */
1704 
1705 	/*  Suggested by designer timchen. Change beacon AIFS to the largest number */
1706 	/*  beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
1707 	rtw_write16(padapter, REG_BCNTCFG, 0x660F);
1708 
1709 	pHalData->RegBcnCtrlVal = rtw_read8(padapter, REG_BCN_CTRL);
1710 	pHalData->RegTxPause = rtw_read8(padapter, REG_TXPAUSE);
1711 	pHalData->RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL+2);
1712 	pHalData->RegReg542 = rtw_read8(padapter, REG_TBTT_PROHIBIT+2);
1713 	pHalData->RegCR_1 = rtw_read8(padapter, REG_CR+1);
1714 }
1715 
1716 void _InitBurstPktLen_8723BS(struct adapter *Adapter)
1717 {
1718 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
1719 
1720 	rtw_write8(Adapter, 0x4c7, rtw_read8(Adapter, 0x4c7)|BIT(7)); /* enable single pkt ampdu */
1721 	rtw_write8(Adapter, REG_RX_PKT_LIMIT_8723B, 0x18);		/* for VHT packet length 11K */
1722 	rtw_write8(Adapter, REG_MAX_AGGR_NUM_8723B, 0x1F);
1723 	rtw_write8(Adapter, REG_PIFS_8723B, 0x00);
1724 	rtw_write8(Adapter, REG_FWHW_TXQ_CTRL_8723B, rtw_read8(Adapter, REG_FWHW_TXQ_CTRL)&(~BIT(7)));
1725 	if (pHalData->AMPDUBurstMode)
1726 		rtw_write8(Adapter, REG_AMPDU_BURST_MODE_8723B,  0x5F);
1727 	rtw_write8(Adapter, REG_AMPDU_MAX_TIME_8723B, 0x70);
1728 
1729 	/*  ARFB table 9 for 11ac 5G 2SS */
1730 	rtw_write32(Adapter, REG_ARFR0_8723B, 0x00000010);
1731 	if (IS_NORMAL_CHIP(pHalData->VersionID))
1732 		rtw_write32(Adapter, REG_ARFR0_8723B+4, 0xfffff000);
1733 	else
1734 		rtw_write32(Adapter, REG_ARFR0_8723B+4, 0x3e0ff000);
1735 
1736 	/*  ARFB table 10 for 11ac 5G 1SS */
1737 	rtw_write32(Adapter, REG_ARFR1_8723B, 0x00000010);
1738 	rtw_write32(Adapter, REG_ARFR1_8723B+4, 0x003ff000);
1739 }
1740 
1741 static void ResumeTxBeacon(struct adapter *padapter)
1742 {
1743 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1744 
1745 	pHalData->RegFwHwTxQCtrl |= BIT(6);
1746 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
1747 	rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0xff);
1748 	pHalData->RegReg542 |= BIT(0);
1749 	rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
1750 }
1751 
1752 static void StopTxBeacon(struct adapter *padapter)
1753 {
1754 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1755 
1756 	pHalData->RegFwHwTxQCtrl &= ~BIT(6);
1757 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
1758 	rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64);
1759 	pHalData->RegReg542 &= ~BIT(0);
1760 	rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
1761 
1762 	CheckFwRsvdPageContent(padapter);  /*  2010.06.23. Added by tynli. */
1763 }
1764 
1765 static void _BeaconFunctionEnable(struct adapter *padapter, u8 Enable, u8 Linked)
1766 {
1767 	rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
1768 	rtw_write8(padapter, REG_RD_CTRL+1, 0x6F);
1769 }
1770 
1771 static void rtl8723b_SetBeaconRelatedRegisters(struct adapter *padapter)
1772 {
1773 	u8 val8;
1774 	u32 value32;
1775 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1776 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1777 	u32 bcn_ctrl_reg;
1778 
1779 	/* reset TSF, enable update TSF, correcting TSF On Beacon */
1780 
1781 	/* REG_BCN_INTERVAL */
1782 	/* REG_BCNDMATIM */
1783 	/* REG_ATIMWND */
1784 	/* REG_TBTT_PROHIBIT */
1785 	/* REG_DRVERLYINT */
1786 	/* REG_BCN_MAX_ERR */
1787 	/* REG_BCNTCFG (0x510) */
1788 	/* REG_DUAL_TSF_RST */
1789 	/* REG_BCN_CTRL (0x550) */
1790 
1791 
1792 	bcn_ctrl_reg = REG_BCN_CTRL;
1793 
1794 	/*  */
1795 	/*  ATIM window */
1796 	/*  */
1797 	rtw_write16(padapter, REG_ATIMWND, 2);
1798 
1799 	/*  */
1800 	/*  Beacon interval (in unit of TU). */
1801 	/*  */
1802 	rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
1803 
1804 	rtl8723b_InitBeaconParameters(padapter);
1805 
1806 	rtw_write8(padapter, REG_SLOT, 0x09);
1807 
1808 	/*  */
1809 	/*  Reset TSF Timer to zero, added by Roger. 2008.06.24 */
1810 	/*  */
1811 	value32 = rtw_read32(padapter, REG_TCR);
1812 	value32 &= ~TSFRST;
1813 	rtw_write32(padapter, REG_TCR, value32);
1814 
1815 	value32 |= TSFRST;
1816 	rtw_write32(padapter, REG_TCR, value32);
1817 
1818 	/*  NOTE: Fix test chip's bug (about contention windows's randomness) */
1819 	if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == true) {
1820 		rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
1821 		rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
1822 	}
1823 
1824 	_BeaconFunctionEnable(padapter, true, true);
1825 
1826 	ResumeTxBeacon(padapter);
1827 	val8 = rtw_read8(padapter, bcn_ctrl_reg);
1828 	val8 |= DIS_BCNQ_SUB;
1829 	rtw_write8(padapter, bcn_ctrl_reg, val8);
1830 }
1831 
1832 static void rtl8723b_GetHalODMVar(
1833 	struct adapter *Adapter,
1834 	enum hal_odm_variable eVariable,
1835 	void *pValue1,
1836 	void *pValue2
1837 )
1838 {
1839 	GetHalODMVar(Adapter, eVariable, pValue1, pValue2);
1840 }
1841 
1842 static void rtl8723b_SetHalODMVar(
1843 	struct adapter *Adapter,
1844 	enum hal_odm_variable eVariable,
1845 	void *pValue1,
1846 	bool bSet
1847 )
1848 {
1849 	SetHalODMVar(Adapter, eVariable, pValue1, bSet);
1850 }
1851 
1852 static void hal_notch_filter_8723b(struct adapter *adapter, bool enable)
1853 {
1854 	if (enable)
1855 		rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
1856 	else
1857 		rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
1858 }
1859 
1860 static void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_level)
1861 {
1862 	u32 mask, rate_bitmap;
1863 	u8 shortGIrate = false;
1864 	struct sta_info *psta;
1865 	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
1866 	struct dm_priv *pdmpriv = &pHalData->dmpriv;
1867 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1868 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1869 
1870 	if (mac_id >= NUM_STA) /* CAM_SIZE */
1871 		return;
1872 
1873 	psta = pmlmeinfo->FW_sta_info[mac_id].psta;
1874 	if (!psta)
1875 		return;
1876 
1877 	shortGIrate = query_ra_short_GI(psta);
1878 
1879 	mask = psta->ra_mask;
1880 
1881 	rate_bitmap = 0xffffffff;
1882 	rate_bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv, mac_id, mask, rssi_level);
1883 
1884 	mask &= rate_bitmap;
1885 
1886 	rate_bitmap = hal_btcoex_GetRaMask(padapter);
1887 	mask &= ~rate_bitmap;
1888 
1889 	if (pHalData->fw_ractrl) {
1890 		rtl8723b_set_FwMacIdConfig_cmd(padapter, mac_id, psta->raid, psta->bw_mode, shortGIrate, mask);
1891 	}
1892 
1893 	/* set correct initial date rate for each mac_id */
1894 	pdmpriv->INIDATA_RATE[mac_id] = psta->init_rate;
1895 }
1896 
1897 
1898 void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc)
1899 {
1900 	pHalFunc->free_hal_data = &rtl8723b_free_hal_data;
1901 
1902 	pHalFunc->dm_init = &rtl8723b_init_dm_priv;
1903 
1904 	pHalFunc->read_chip_version = &rtl8723b_read_chip_version;
1905 
1906 	pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8723B;
1907 
1908 	pHalFunc->set_bwmode_handler = &PHY_SetBWMode8723B;
1909 	pHalFunc->set_channel_handler = &PHY_SwChnl8723B;
1910 	pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8723B;
1911 
1912 	pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8723B;
1913 	pHalFunc->get_tx_power_level_handler = &PHY_GetTxPowerLevel8723B;
1914 
1915 	pHalFunc->hal_dm_watchdog = &rtl8723b_HalDmWatchDog;
1916 	pHalFunc->hal_dm_watchdog_in_lps = &rtl8723b_HalDmWatchDog_in_LPS;
1917 
1918 
1919 	pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8723b_SetBeaconRelatedRegisters;
1920 
1921 	pHalFunc->Add_RateATid = &rtl8723b_Add_RateATid;
1922 
1923 	pHalFunc->run_thread = &rtl8723b_start_thread;
1924 	pHalFunc->cancel_thread = &rtl8723b_stop_thread;
1925 
1926 	pHalFunc->read_bbreg = &PHY_QueryBBReg_8723B;
1927 	pHalFunc->write_bbreg = &PHY_SetBBReg_8723B;
1928 	pHalFunc->read_rfreg = &PHY_QueryRFReg_8723B;
1929 	pHalFunc->write_rfreg = &PHY_SetRFReg_8723B;
1930 
1931 	/*  Efuse related function */
1932 	pHalFunc->BTEfusePowerSwitch = &Hal_BT_EfusePowerSwitch;
1933 	pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch;
1934 	pHalFunc->ReadEFuse = &Hal_ReadEFuse;
1935 	pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition;
1936 	pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize;
1937 	pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead;
1938 	pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite;
1939 	pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite;
1940 	pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT;
1941 
1942 	pHalFunc->GetHalODMVarHandler = &rtl8723b_GetHalODMVar;
1943 	pHalFunc->SetHalODMVarHandler = &rtl8723b_SetHalODMVar;
1944 
1945 	pHalFunc->xmit_thread_handler = &hal_xmit_handler;
1946 	pHalFunc->hal_notch_filter = &hal_notch_filter_8723b;
1947 
1948 	pHalFunc->c2h_handler = c2h_handler_8723b;
1949 	pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8723b;
1950 
1951 	pHalFunc->fill_h2c_cmd = &FillH2CCmd8723B;
1952 }
1953 
1954 void rtl8723b_InitAntenna_Selection(struct adapter *padapter)
1955 {
1956 	u8 val;
1957 
1958 	val = rtw_read8(padapter, REG_LEDCFG2);
1959 	/*  Let 8051 take control antenna setting */
1960 	val |= BIT(7); /*  DPDT_SEL_EN, 0x4C[23] */
1961 	rtw_write8(padapter, REG_LEDCFG2, val);
1962 }
1963 
1964 void rtl8723b_init_default_value(struct adapter *padapter)
1965 {
1966 	struct hal_com_data *pHalData;
1967 	struct dm_priv *pdmpriv;
1968 	u8 i;
1969 
1970 
1971 	pHalData = GET_HAL_DATA(padapter);
1972 	pdmpriv = &pHalData->dmpriv;
1973 
1974 	padapter->registrypriv.wireless_mode = WIRELESS_11BG_24N;
1975 
1976 	/*  init default value */
1977 	pHalData->fw_ractrl = false;
1978 	pHalData->bIQKInitialized = false;
1979 	if (!adapter_to_pwrctl(padapter)->bkeepfwalive)
1980 		pHalData->LastHMEBoxNum = 0;
1981 
1982 	pHalData->bIQKInitialized = false;
1983 
1984 	/*  init dm default value */
1985 	pdmpriv->TM_Trigger = 0;/* for IQK */
1986 /* 	pdmpriv->binitialized = false; */
1987 /* 	pdmpriv->prv_traffic_idx = 3; */
1988 /* 	pdmpriv->initialize = 0; */
1989 
1990 	pdmpriv->ThermalValue_HP_index = 0;
1991 	for (i = 0; i < HP_THERMAL_NUM; i++)
1992 		pdmpriv->ThermalValue_HP[i] = 0;
1993 
1994 	/*  init Efuse variables */
1995 	pHalData->EfuseUsedBytes = 0;
1996 	pHalData->EfuseUsedPercentage = 0;
1997 #ifdef HAL_EFUSE_MEMORY
1998 	pHalData->EfuseHal.fakeEfuseBank = 0;
1999 	pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
2000 	memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
2001 	memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
2002 	memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
2003 	pHalData->EfuseHal.BTEfuseUsedBytes = 0;
2004 	pHalData->EfuseHal.BTEfuseUsedPercentage = 0;
2005 	memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
2006 	memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2007 	memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2008 	pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0;
2009 	memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
2010 	memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2011 	memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2012 #endif
2013 }
2014 
2015 u8 GetEEPROMSize8723B(struct adapter *padapter)
2016 {
2017 	u8 size = 0;
2018 	u32 cr;
2019 
2020 	cr = rtw_read16(padapter, REG_9346CR);
2021 	/*  6: EEPROM used is 93C46, 4: boot from E-Fuse. */
2022 	size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
2023 
2024 	return size;
2025 }
2026 
2027 /*  */
2028 /*  */
2029 /*  LLT R/W/Init function */
2030 /*  */
2031 /*  */
2032 s32 rtl8723b_InitLLTTable(struct adapter *padapter)
2033 {
2034 	unsigned long start, passing_time;
2035 	u32 val32;
2036 	s32 ret;
2037 
2038 
2039 	ret = _FAIL;
2040 
2041 	val32 = rtw_read32(padapter, REG_AUTO_LLT);
2042 	val32 |= BIT_AUTO_INIT_LLT;
2043 	rtw_write32(padapter, REG_AUTO_LLT, val32);
2044 
2045 	start = jiffies;
2046 
2047 	do {
2048 		val32 = rtw_read32(padapter, REG_AUTO_LLT);
2049 		if (!(val32 & BIT_AUTO_INIT_LLT)) {
2050 			ret = _SUCCESS;
2051 			break;
2052 		}
2053 
2054 		passing_time = jiffies_to_msecs(jiffies - start);
2055 		if (passing_time > 1000)
2056 			break;
2057 
2058 		msleep(1);
2059 	} while (1);
2060 
2061 	return ret;
2062 }
2063 
2064 static bool Hal_GetChnlGroup8723B(u8 Channel, u8 *pGroup)
2065 {
2066 	bool bIn24G = true;
2067 
2068 	if (Channel <= 14) {
2069 		bIn24G = true;
2070 
2071 		if (1  <= Channel && Channel <= 2)
2072 			*pGroup = 0;
2073 		else if (3  <= Channel && Channel <= 5)
2074 			*pGroup = 1;
2075 		else if (6  <= Channel && Channel <= 8)
2076 			*pGroup = 2;
2077 		else if (9  <= Channel && Channel <= 11)
2078 			*pGroup = 3;
2079 		else if (12 <= Channel && Channel <= 14)
2080 			*pGroup = 4;
2081 	} else {
2082 		bIn24G = false;
2083 
2084 		if (36   <= Channel && Channel <=  42)
2085 			*pGroup = 0;
2086 		else if (44   <= Channel && Channel <=  48)
2087 			*pGroup = 1;
2088 		else if (50   <= Channel && Channel <=  58)
2089 			*pGroup = 2;
2090 		else if (60   <= Channel && Channel <=  64)
2091 			*pGroup = 3;
2092 		else if (100  <= Channel && Channel <= 106)
2093 			*pGroup = 4;
2094 		else if (108  <= Channel && Channel <= 114)
2095 			*pGroup = 5;
2096 		else if (116  <= Channel && Channel <= 122)
2097 			*pGroup = 6;
2098 		else if (124  <= Channel && Channel <= 130)
2099 			*pGroup = 7;
2100 		else if (132  <= Channel && Channel <= 138)
2101 			*pGroup = 8;
2102 		else if (140  <= Channel && Channel <= 144)
2103 			*pGroup = 9;
2104 		else if (149  <= Channel && Channel <= 155)
2105 			*pGroup = 10;
2106 		else if (157  <= Channel && Channel <= 161)
2107 			*pGroup = 11;
2108 		else if (165  <= Channel && Channel <= 171)
2109 			*pGroup = 12;
2110 		else if (173  <= Channel && Channel <= 177)
2111 			*pGroup = 13;
2112 	}
2113 	return bIn24G;
2114 }
2115 
2116 void Hal_InitPGData(struct adapter *padapter, u8 *PROMContent)
2117 {
2118 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
2119 
2120 	if (!pEEPROM->bautoload_fail_flag) { /*  autoload OK. */
2121 		if (!pEEPROM->EepromOrEfuse) {
2122 			/*  Read EFUSE real map to shadow. */
2123 			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
2124 			memcpy((void *)PROMContent, (void *)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE_8723B);
2125 		}
2126 	} else {/* autoload fail */
2127 		if (!pEEPROM->EepromOrEfuse)
2128 			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
2129 		memcpy((void *)PROMContent, (void *)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE_8723B);
2130 	}
2131 }
2132 
2133 void Hal_EfuseParseIDCode(struct adapter *padapter, u8 *hwinfo)
2134 {
2135 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
2136 /* 	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter); */
2137 	u16 EEPROMId;
2138 
2139 
2140 	/*  Checl 0x8129 again for making sure autoload status!! */
2141 	EEPROMId = le16_to_cpu(*((__le16 *)hwinfo));
2142 	if (EEPROMId != RTL_EEPROM_ID) {
2143 		pEEPROM->bautoload_fail_flag = true;
2144 	} else
2145 		pEEPROM->bautoload_fail_flag = false;
2146 }
2147 
2148 static void Hal_ReadPowerValueFromPROM_8723B(
2149 	struct adapter *Adapter,
2150 	struct TxPowerInfo24G *pwrInfo24G,
2151 	u8 *PROMContent,
2152 	bool AutoLoadFail
2153 )
2154 {
2155 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
2156 	u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_8723B, group, TxCount = 0;
2157 
2158 	memset(pwrInfo24G, 0, sizeof(struct TxPowerInfo24G));
2159 
2160 	if (0xFF == PROMContent[eeAddr+1])
2161 		AutoLoadFail = true;
2162 
2163 	if (AutoLoadFail) {
2164 		for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) {
2165 			/* 2.4G default value */
2166 			for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
2167 				pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
2168 				pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
2169 			}
2170 
2171 			for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
2172 				if (TxCount == 0) {
2173 					pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF;
2174 					pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF;
2175 				} else {
2176 					pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2177 					pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2178 					pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2179 					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2180 				}
2181 			}
2182 		}
2183 
2184 		return;
2185 	}
2186 
2187 	pHalData->bTXPowerDataReadFromEEPORM = true;		/* YJ, move, 120316 */
2188 
2189 	for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) {
2190 		/* 2 2.4G default value */
2191 		for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
2192 			pwrInfo24G->IndexCCK_Base[rfPath][group] =	PROMContent[eeAddr++];
2193 			if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
2194 				pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
2195 		}
2196 
2197 		for (group = 0; group < MAX_CHNL_GROUP_24G-1; group++) {
2198 			pwrInfo24G->IndexBW40_Base[rfPath][group] =	PROMContent[eeAddr++];
2199 			if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
2200 				pwrInfo24G->IndexBW40_Base[rfPath][group] =	EEPROM_DEFAULT_24G_INDEX;
2201 		}
2202 
2203 		for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
2204 			if (TxCount == 0) {
2205 				pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
2206 				if (PROMContent[eeAddr] == 0xFF)
2207 					pwrInfo24G->BW20_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_24G_HT20_DIFF;
2208 				else {
2209 					pwrInfo24G->BW20_Diff[rfPath][TxCount] =	(PROMContent[eeAddr]&0xf0)>>4;
2210 					if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
2211 						pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
2212 				}
2213 
2214 				if (PROMContent[eeAddr] == 0xFF)
2215 					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_OFDM_DIFF;
2216 				else {
2217 					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
2218 					if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
2219 						pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
2220 				}
2221 				pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
2222 				eeAddr++;
2223 			} else {
2224 				if (PROMContent[eeAddr] == 0xFF)
2225 					pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2226 				else {
2227 					pwrInfo24G->BW40_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
2228 					if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
2229 						pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
2230 				}
2231 
2232 				if (PROMContent[eeAddr] == 0xFF)
2233 					pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2234 				else {
2235 					pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
2236 					if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
2237 						pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
2238 				}
2239 				eeAddr++;
2240 
2241 				if (PROMContent[eeAddr] == 0xFF)
2242 					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2243 				else {
2244 					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
2245 					if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
2246 						pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
2247 				}
2248 
2249 				if (PROMContent[eeAddr] == 0xFF)
2250 					pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2251 				else {
2252 					pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
2253 					if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
2254 						pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
2255 				}
2256 				eeAddr++;
2257 			}
2258 		}
2259 	}
2260 }
2261 
2262 
2263 void Hal_EfuseParseTxPowerInfo_8723B(
2264 	struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail
2265 )
2266 {
2267 	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
2268 	struct TxPowerInfo24G	pwrInfo24G;
2269 	u8 	rfPath, ch, TxCount = 1;
2270 
2271 	Hal_ReadPowerValueFromPROM_8723B(padapter, &pwrInfo24G, PROMContent, AutoLoadFail);
2272 	for (rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++) {
2273 		for (ch = 0 ; ch < CHANNEL_MAX_NUMBER; ch++) {
2274 			u8 group = 0;
2275 
2276 			Hal_GetChnlGroup8723B(ch+1, &group);
2277 
2278 			if (ch == 14-1) {
2279 				pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][5];
2280 				pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
2281 			} else {
2282 				pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group];
2283 				pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
2284 			}
2285 		}
2286 
2287 		for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
2288 			pHalData->CCK_24G_Diff[rfPath][TxCount] = pwrInfo24G.CCK_Diff[rfPath][TxCount];
2289 			pHalData->OFDM_24G_Diff[rfPath][TxCount] = pwrInfo24G.OFDM_Diff[rfPath][TxCount];
2290 			pHalData->BW20_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW20_Diff[rfPath][TxCount];
2291 			pHalData->BW40_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW40_Diff[rfPath][TxCount];
2292 		}
2293 	}
2294 
2295 	/*  2010/10/19 MH Add Regulator recognize for CU. */
2296 	if (!AutoLoadFail) {
2297 		pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_8723B]&0x7);	/* bit0~2 */
2298 		if (PROMContent[EEPROM_RF_BOARD_OPTION_8723B] == 0xFF)
2299 			pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION&0x7);	/* bit0~2 */
2300 	} else
2301 		pHalData->EEPROMRegulatory = 0;
2302 }
2303 
2304 void Hal_EfuseParseBTCoexistInfo_8723B(
2305 	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
2306 )
2307 {
2308 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
2309 	u8 tempval;
2310 	u32 tmpu4;
2311 
2312 	if (!AutoLoadFail) {
2313 		tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
2314 		if (tmpu4 & BT_FUNC_EN)
2315 			pHalData->EEPROMBluetoothCoexist = true;
2316 		else
2317 			pHalData->EEPROMBluetoothCoexist = false;
2318 
2319 		pHalData->EEPROMBluetoothType = BT_RTL8723B;
2320 
2321 		tempval = hwinfo[EEPROM_RF_BT_SETTING_8723B];
2322 		if (tempval != 0xFF) {
2323 			pHalData->EEPROMBluetoothAntNum = tempval & BIT(0);
2324 			/*  EFUSE_0xC3[6] == 0, S1(Main)-ODM_RF_PATH_A; */
2325 			/*  EFUSE_0xC3[6] == 1, S0(Aux)-ODM_RF_PATH_B */
2326 			pHalData->ant_path = (tempval & BIT(6))?ODM_RF_PATH_B:ODM_RF_PATH_A;
2327 		} else {
2328 			pHalData->EEPROMBluetoothAntNum = Ant_x1;
2329 			if (pHalData->PackageType == PACKAGE_QFN68)
2330 				pHalData->ant_path = ODM_RF_PATH_B;
2331 			else
2332 				pHalData->ant_path = ODM_RF_PATH_A;
2333 		}
2334 	} else {
2335 		pHalData->EEPROMBluetoothCoexist = false;
2336 		pHalData->EEPROMBluetoothType = BT_RTL8723B;
2337 		pHalData->EEPROMBluetoothAntNum = Ant_x1;
2338 		pHalData->ant_path = ODM_RF_PATH_A;
2339 	}
2340 
2341 	if (padapter->registrypriv.ant_num > 0) {
2342 		switch (padapter->registrypriv.ant_num) {
2343 		case 1:
2344 			pHalData->EEPROMBluetoothAntNum = Ant_x1;
2345 			break;
2346 		case 2:
2347 			pHalData->EEPROMBluetoothAntNum = Ant_x2;
2348 			break;
2349 		default:
2350 			break;
2351 		}
2352 	}
2353 
2354 	hal_btcoex_SetBTCoexist(padapter, pHalData->EEPROMBluetoothCoexist);
2355 	hal_btcoex_SetChipType(padapter, pHalData->EEPROMBluetoothType);
2356 	hal_btcoex_SetPgAntNum(padapter, pHalData->EEPROMBluetoothAntNum == Ant_x2 ? 2 : 1);
2357 	if (pHalData->EEPROMBluetoothAntNum == Ant_x1)
2358 		hal_btcoex_SetSingleAntPath(padapter, pHalData->ant_path);
2359 }
2360 
2361 void Hal_EfuseParseEEPROMVer_8723B(
2362 	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
2363 )
2364 {
2365 	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
2366 
2367 	if (!AutoLoadFail)
2368 		pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723B];
2369 	else
2370 		pHalData->EEPROMVersion = 1;
2371 }
2372 
2373 
2374 
2375 void Hal_EfuseParsePackageType_8723B(
2376 	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
2377 )
2378 {
2379 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
2380 	u8 package;
2381 	u8 efuseContent;
2382 
2383 	Efuse_PowerSwitch(padapter, false, true);
2384 	efuse_OneByteRead(padapter, 0x1FB, &efuseContent, false);
2385 	Efuse_PowerSwitch(padapter, false, false);
2386 
2387 	package = efuseContent & 0x7;
2388 	switch (package) {
2389 	case 0x4:
2390 		pHalData->PackageType = PACKAGE_TFBGA79;
2391 		break;
2392 	case 0x5:
2393 		pHalData->PackageType = PACKAGE_TFBGA90;
2394 		break;
2395 	case 0x6:
2396 		pHalData->PackageType = PACKAGE_QFN68;
2397 		break;
2398 	case 0x7:
2399 		pHalData->PackageType = PACKAGE_TFBGA80;
2400 		break;
2401 
2402 	default:
2403 		pHalData->PackageType = PACKAGE_DEFAULT;
2404 		break;
2405 	}
2406 }
2407 
2408 
2409 void Hal_EfuseParseVoltage_8723B(
2410 	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
2411 )
2412 {
2413 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
2414 
2415 	/* memcpy(pEEPROM->adjuseVoltageVal, &hwinfo[EEPROM_Voltage_ADDR_8723B], 1); */
2416 	pEEPROM->adjuseVoltageVal = (hwinfo[EEPROM_Voltage_ADDR_8723B] & 0xf0) >> 4;
2417 }
2418 
2419 void Hal_EfuseParseChnlPlan_8723B(
2420 	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
2421 )
2422 {
2423 	padapter->mlmepriv.ChannelPlan = hal_com_config_channel_plan(
2424 		padapter,
2425 		hwinfo ? hwinfo[EEPROM_ChannelPlan_8723B] : 0xFF,
2426 		padapter->registrypriv.channel_plan,
2427 		RT_CHANNEL_DOMAIN_WORLD_NULL,
2428 		AutoLoadFail
2429 	);
2430 
2431 	Hal_ChannelPlanToRegulation(padapter, padapter->mlmepriv.ChannelPlan);
2432 }
2433 
2434 void Hal_EfuseParseCustomerID_8723B(
2435 	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
2436 )
2437 {
2438 	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
2439 
2440 	if (!AutoLoadFail)
2441 		pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723B];
2442 	else
2443 		pHalData->EEPROMCustomerID = 0;
2444 }
2445 
2446 void Hal_EfuseParseAntennaDiversity_8723B(
2447 	struct adapter *padapter,
2448 	u8 *hwinfo,
2449 	bool AutoLoadFail
2450 )
2451 {
2452 }
2453 
2454 void Hal_EfuseParseXtal_8723B(
2455 	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
2456 )
2457 {
2458 	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
2459 
2460 	if (!AutoLoadFail) {
2461 		pHalData->CrystalCap = hwinfo[EEPROM_XTAL_8723B];
2462 		if (pHalData->CrystalCap == 0xFF)
2463 			pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723B;	   /* what value should 8812 set? */
2464 	} else
2465 		pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723B;
2466 }
2467 
2468 
2469 void Hal_EfuseParseThermalMeter_8723B(
2470 	struct adapter *padapter, u8 *PROMContent, u8 AutoLoadFail
2471 )
2472 {
2473 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
2474 
2475 	/*  */
2476 	/*  ThermalMeter from EEPROM */
2477 	/*  */
2478 	if (!AutoLoadFail)
2479 		pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8723B];
2480 	else
2481 		pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8723B;
2482 
2483 	if ((pHalData->EEPROMThermalMeter == 0xff) || AutoLoadFail) {
2484 		pHalData->bAPKThermalMeterIgnore = true;
2485 		pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8723B;
2486 	}
2487 }
2488 
2489 
2490 void Hal_ReadRFGainOffset(
2491 	struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail
2492 )
2493 {
2494 	/*  */
2495 	/*  BB_RF Gain Offset from EEPROM */
2496 	/*  */
2497 
2498 	if (!AutoloadFail) {
2499 		Adapter->eeprompriv.EEPROMRFGainOffset = PROMContent[EEPROM_RF_GAIN_OFFSET];
2500 		Adapter->eeprompriv.EEPROMRFGainVal = EFUSE_Read1Byte(Adapter, EEPROM_RF_GAIN_VAL);
2501 	} else {
2502 		Adapter->eeprompriv.EEPROMRFGainOffset = 0;
2503 		Adapter->eeprompriv.EEPROMRFGainVal = 0xFF;
2504 	}
2505 }
2506 
2507 u8 BWMapping_8723B(struct adapter *Adapter, struct pkt_attrib *pattrib)
2508 {
2509 	u8 BWSettingOfDesc = 0;
2510 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
2511 
2512 	if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) {
2513 		if (pattrib->bwmode == CHANNEL_WIDTH_40)
2514 			BWSettingOfDesc = 1;
2515 		else
2516 			BWSettingOfDesc = 0;
2517 	} else
2518 		BWSettingOfDesc = 0;
2519 
2520 	/* if (pTcb->bBTTxPacket) */
2521 	/* 	BWSettingOfDesc = 0; */
2522 
2523 	return BWSettingOfDesc;
2524 }
2525 
2526 u8 SCMapping_8723B(struct adapter *Adapter, struct pkt_attrib *pattrib)
2527 {
2528 	u8 SCSettingOfDesc = 0;
2529 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
2530 
2531 	if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) {
2532 		if (pattrib->bwmode == CHANNEL_WIDTH_40) {
2533 			SCSettingOfDesc = HT_DATA_SC_DONOT_CARE;
2534 		} else if (pattrib->bwmode == CHANNEL_WIDTH_20) {
2535 			if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) {
2536 				SCSettingOfDesc = HT_DATA_SC_20_UPPER_OF_40MHZ;
2537 			} else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) {
2538 				SCSettingOfDesc = HT_DATA_SC_20_LOWER_OF_40MHZ;
2539 			} else {
2540 				SCSettingOfDesc = HT_DATA_SC_DONOT_CARE;
2541 			}
2542 		}
2543 	} else {
2544 		SCSettingOfDesc = HT_DATA_SC_DONOT_CARE;
2545 	}
2546 
2547 	return SCSettingOfDesc;
2548 }
2549 
2550 static void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc)
2551 {
2552 	u16 *usPtr = (u16 *)ptxdesc;
2553 	u32 count;
2554 	u32 index;
2555 	u16 checksum = 0;
2556 
2557 
2558 	/*  Clear first */
2559 	ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
2560 
2561 	/*  checksume is always calculated by first 32 bytes, */
2562 	/*  and it doesn't depend on TX DESC length. */
2563 	/*  Thomas, Lucas@SD4, 20130515 */
2564 	count = 16;
2565 
2566 	for (index = 0; index < count; index++) {
2567 		checksum |= le16_to_cpu(*(__le16 *)(usPtr + index));
2568 	}
2569 
2570 	ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
2571 }
2572 
2573 static u8 fill_txdesc_sectype(struct pkt_attrib *pattrib)
2574 {
2575 	u8 sectype = 0;
2576 	if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
2577 		switch (pattrib->encrypt) {
2578 		/*  SEC_TYPE */
2579 		case _WEP40_:
2580 		case _WEP104_:
2581 		case _TKIP_:
2582 		case _TKIP_WTMIC_:
2583 			sectype = 1;
2584 			break;
2585 
2586 		case _AES_:
2587 			sectype = 3;
2588 			break;
2589 
2590 		case _NO_PRIVACY_:
2591 		default:
2592 			break;
2593 		}
2594 	}
2595 	return sectype;
2596 }
2597 
2598 static void fill_txdesc_vcs_8723b(struct adapter *padapter, struct pkt_attrib *pattrib, struct txdesc_8723b *ptxdesc)
2599 {
2600 	if (pattrib->vcs_mode) {
2601 		switch (pattrib->vcs_mode) {
2602 		case RTS_CTS:
2603 			ptxdesc->rtsen = 1;
2604 			/*  ENABLE HW RTS */
2605 			ptxdesc->hw_rts_en = 1;
2606 			break;
2607 
2608 		case CTS_TO_SELF:
2609 			ptxdesc->cts2self = 1;
2610 			break;
2611 
2612 		case NONE_VCS:
2613 		default:
2614 			break;
2615 		}
2616 
2617 		ptxdesc->rtsrate = 8; /*  RTS Rate =24M */
2618 		ptxdesc->rts_ratefb_lmt = 0xF;
2619 
2620 		if (padapter->mlmeextpriv.mlmext_info.preamble_mode == PREAMBLE_SHORT)
2621 			ptxdesc->rts_short = 1;
2622 
2623 		/*  Set RTS BW */
2624 		if (pattrib->ht_en)
2625 			ptxdesc->rts_sc = SCMapping_8723B(padapter, pattrib);
2626 	}
2627 }
2628 
2629 static void fill_txdesc_phy_8723b(struct adapter *padapter, struct pkt_attrib *pattrib, struct txdesc_8723b *ptxdesc)
2630 {
2631 	if (pattrib->ht_en) {
2632 		ptxdesc->data_bw = BWMapping_8723B(padapter, pattrib);
2633 
2634 		ptxdesc->data_sc = SCMapping_8723B(padapter, pattrib);
2635 	}
2636 }
2637 
2638 static void rtl8723b_fill_default_txdesc(
2639 	struct xmit_frame *pxmitframe, u8 *pbuf
2640 )
2641 {
2642 	struct adapter *padapter;
2643 	struct hal_com_data *pHalData;
2644 	struct mlme_ext_priv *pmlmeext;
2645 	struct mlme_ext_info *pmlmeinfo;
2646 	struct pkt_attrib *pattrib;
2647 	struct txdesc_8723b *ptxdesc;
2648 	s32 bmcst;
2649 
2650 	memset(pbuf, 0, TXDESC_SIZE);
2651 
2652 	padapter = pxmitframe->padapter;
2653 	pHalData = GET_HAL_DATA(padapter);
2654 	pmlmeext = &padapter->mlmeextpriv;
2655 	pmlmeinfo = &(pmlmeext->mlmext_info);
2656 
2657 	pattrib = &pxmitframe->attrib;
2658 	bmcst = IS_MCAST(pattrib->ra);
2659 
2660 	ptxdesc = (struct txdesc_8723b *)pbuf;
2661 
2662 	if (pxmitframe->frame_tag == DATA_FRAMETAG) {
2663 		u8 drv_userate = 0;
2664 
2665 		ptxdesc->macid = pattrib->mac_id; /*  CAM_ID(MAC_ID) */
2666 		ptxdesc->rate_id = pattrib->raid;
2667 		ptxdesc->qsel = pattrib->qsel;
2668 		ptxdesc->seq = pattrib->seqnum;
2669 
2670 		ptxdesc->sectype = fill_txdesc_sectype(pattrib);
2671 		fill_txdesc_vcs_8723b(padapter, pattrib, ptxdesc);
2672 
2673 		if (pattrib->icmp_pkt == 1 && padapter->registrypriv.wifi_spec == 1)
2674 			drv_userate = 1;
2675 
2676 		if (
2677 			(pattrib->ether_type != 0x888e) &&
2678 			(pattrib->ether_type != 0x0806) &&
2679 			(pattrib->ether_type != 0x88B4) &&
2680 			(pattrib->dhcp_pkt != 1) &&
2681 			(drv_userate != 1)
2682 		) {
2683 			/*  Non EAP & ARP & DHCP type data packet */
2684 
2685 			if (pattrib->ampdu_en) {
2686 				ptxdesc->agg_en = 1; /*  AGG EN */
2687 				ptxdesc->max_agg_num = 0x1f;
2688 				ptxdesc->ampdu_density = pattrib->ampdu_spacing;
2689 			} else
2690 				ptxdesc->bk = 1; /*  AGG BK */
2691 
2692 			fill_txdesc_phy_8723b(padapter, pattrib, ptxdesc);
2693 
2694 			ptxdesc->data_ratefb_lmt = 0x1F;
2695 
2696 			if (!pHalData->fw_ractrl) {
2697 				ptxdesc->userate = 1;
2698 
2699 				if (pHalData->dmpriv.INIDATA_RATE[pattrib->mac_id] & BIT(7))
2700 					ptxdesc->data_short = 1;
2701 
2702 				ptxdesc->datarate = pHalData->dmpriv.INIDATA_RATE[pattrib->mac_id] & 0x7F;
2703 			}
2704 
2705 			if (padapter->fix_rate != 0xFF) { /*  modify data rate by iwpriv */
2706 				ptxdesc->userate = 1;
2707 				if (padapter->fix_rate & BIT(7))
2708 					ptxdesc->data_short = 1;
2709 
2710 				ptxdesc->datarate = (padapter->fix_rate & 0x7F);
2711 				ptxdesc->disdatafb = 1;
2712 			}
2713 
2714 			if (pattrib->ldpc)
2715 				ptxdesc->data_ldpc = 1;
2716 			if (pattrib->stbc)
2717 				ptxdesc->data_stbc = 1;
2718 		} else {
2719 			/*  EAP data packet and ARP packet. */
2720 			/*  Use the 1M data rate to send the EAP/ARP packet. */
2721 			/*  This will maybe make the handshake smooth. */
2722 
2723 			ptxdesc->bk = 1; /*  AGG BK */
2724 			ptxdesc->userate = 1; /*  driver uses rate */
2725 			if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
2726 				ptxdesc->data_short = 1;/*  DATA_SHORT */
2727 			ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
2728 		}
2729 
2730 		ptxdesc->usb_txagg_num = pxmitframe->agg_num;
2731 	} else if (pxmitframe->frame_tag == MGNT_FRAMETAG) {
2732 		ptxdesc->macid = pattrib->mac_id; /*  CAM_ID(MAC_ID) */
2733 		ptxdesc->qsel = pattrib->qsel;
2734 		ptxdesc->rate_id = pattrib->raid; /*  Rate ID */
2735 		ptxdesc->seq = pattrib->seqnum;
2736 		ptxdesc->userate = 1; /*  driver uses rate, 1M */
2737 
2738 		ptxdesc->mbssid = pattrib->mbssid & 0xF;
2739 
2740 		ptxdesc->rty_lmt_en = 1; /*  retry limit enable */
2741 		if (pattrib->retry_ctrl) {
2742 			ptxdesc->data_rt_lmt = 6;
2743 		} else {
2744 			ptxdesc->data_rt_lmt = 12;
2745 		}
2746 
2747 		ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
2748 
2749 		/*  CCX-TXRPT ack for xmit mgmt frames. */
2750 		if (pxmitframe->ack_report) {
2751 			ptxdesc->spe_rpt = 1;
2752 			ptxdesc->sw_define = (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no);
2753 		}
2754 	} else {
2755 		ptxdesc->macid = pattrib->mac_id; /*  CAM_ID(MAC_ID) */
2756 		ptxdesc->rate_id = pattrib->raid; /*  Rate ID */
2757 		ptxdesc->qsel = pattrib->qsel;
2758 		ptxdesc->seq = pattrib->seqnum;
2759 		ptxdesc->userate = 1; /*  driver uses rate */
2760 		ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
2761 	}
2762 
2763 	ptxdesc->pktlen = pattrib->last_txcmdsz;
2764 	ptxdesc->offset = TXDESC_SIZE + OFFSET_SZ;
2765 
2766 	if (bmcst)
2767 		ptxdesc->bmc = 1;
2768 
2769 	/* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
2770 	 * (1) The sequence number of each non-Qos frame / broadcast /
2771 	 * multicast / mgnt frame should be controlled by Hw because Fw
2772 	 * will also send null data which we cannot control when Fw LPS
2773 	 * enable.
2774 	 * --> default enable non-Qos data sequense number. 2010.06.23.
2775 	 * by tynli.
2776 	 * (2) Enable HW SEQ control for beacon packet, because we use
2777 	 * Hw beacon.
2778 	 * (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos
2779 	 * packets.
2780 	 * 2010.06.23. Added by tynli.
2781 	 */
2782 	if (!pattrib->qos_en) /*  Hw set sequence number */
2783 		ptxdesc->en_hwseq = 1; /*  HWSEQ_EN */
2784 }
2785 
2786 /* Description:
2787  *
2788  * Parameters:
2789  *	pxmitframe	xmitframe
2790  *	pbuf		where to fill tx desc
2791  */
2792 void rtl8723b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
2793 {
2794 	struct tx_desc *pdesc;
2795 
2796 	rtl8723b_fill_default_txdesc(pxmitframe, pbuf);
2797 
2798 	pdesc = (struct tx_desc *)pbuf;
2799 	pdesc->txdw0 = pdesc->txdw0;
2800 	pdesc->txdw1 = pdesc->txdw1;
2801 	pdesc->txdw2 = pdesc->txdw2;
2802 	pdesc->txdw3 = pdesc->txdw3;
2803 	pdesc->txdw4 = pdesc->txdw4;
2804 	pdesc->txdw5 = pdesc->txdw5;
2805 	pdesc->txdw6 = pdesc->txdw6;
2806 	pdesc->txdw7 = pdesc->txdw7;
2807 	pdesc->txdw8 = pdesc->txdw8;
2808 	pdesc->txdw9 = pdesc->txdw9;
2809 
2810 	rtl8723b_cal_txdesc_chksum(pdesc);
2811 }
2812 
2813 /*  */
2814 /*  Description: In normal chip, we should send some packet to Hw which will be used by Fw */
2815 /* 			in FW LPS mode. The function is to fill the Tx descriptor of this packets, then */
2816 /* 			Fw can tell Hw to send these packet derectly. */
2817 /*  Added by tynli. 2009.10.15. */
2818 /*  */
2819 /* type1:pspoll, type2:null */
2820 void rtl8723b_fill_fake_txdesc(
2821 	struct adapter *padapter,
2822 	u8 *pDesc,
2823 	u32 BufferLen,
2824 	u8 IsPsPoll,
2825 	u8 IsBTQosNull,
2826 	u8 bDataFrame
2827 )
2828 {
2829 	/*  Clear all status */
2830 	memset(pDesc, 0, TXDESC_SIZE);
2831 
2832 	SET_TX_DESC_FIRST_SEG_8723B(pDesc, 1); /* bFirstSeg; */
2833 	SET_TX_DESC_LAST_SEG_8723B(pDesc, 1); /* bLastSeg; */
2834 
2835 	SET_TX_DESC_OFFSET_8723B(pDesc, 0x28); /*  Offset = 32 */
2836 
2837 	SET_TX_DESC_PKT_SIZE_8723B(pDesc, BufferLen); /*  Buffer size + command header */
2838 	SET_TX_DESC_QUEUE_SEL_8723B(pDesc, QSLT_MGNT); /*  Fixed queue of Mgnt queue */
2839 
2840 	/*  Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. */
2841 	if (IsPsPoll) {
2842 		SET_TX_DESC_NAV_USE_HDR_8723B(pDesc, 1);
2843 	} else {
2844 		SET_TX_DESC_HWSEQ_EN_8723B(pDesc, 1); /*  Hw set sequence number */
2845 		SET_TX_DESC_HWSEQ_SEL_8723B(pDesc, 0);
2846 	}
2847 
2848 	if (IsBTQosNull) {
2849 		SET_TX_DESC_BT_INT_8723B(pDesc, 1);
2850 	}
2851 
2852 	SET_TX_DESC_USE_RATE_8723B(pDesc, 1); /*  use data rate which is set by Sw */
2853 	SET_TX_DESC_OWN_8723B((u8 *)pDesc, 1);
2854 
2855 	SET_TX_DESC_TX_RATE_8723B(pDesc, DESC8723B_RATE1M);
2856 
2857 	/*  */
2858 	/*  Encrypt the data frame if under security mode excepct null data. Suggested by CCW. */
2859 	/*  */
2860 	if (bDataFrame) {
2861 		u32 EncAlg;
2862 
2863 		EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
2864 		switch (EncAlg) {
2865 		case _NO_PRIVACY_:
2866 			SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0);
2867 			break;
2868 		case _WEP40_:
2869 		case _WEP104_:
2870 		case _TKIP_:
2871 			SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x1);
2872 			break;
2873 		case _SMS4_:
2874 			SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x2);
2875 			break;
2876 		case _AES_:
2877 			SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x3);
2878 			break;
2879 		default:
2880 			SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0);
2881 			break;
2882 		}
2883 	}
2884 
2885 	/*  USB interface drop packet if the checksum of descriptor isn't correct. */
2886 	/*  Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). */
2887 	rtl8723b_cal_txdesc_chksum((struct tx_desc *)pDesc);
2888 }
2889 
2890 static void hw_var_set_opmode(struct adapter *padapter, u8 variable, u8 *val)
2891 {
2892 	u8 val8;
2893 	u8 mode = *((u8 *)val);
2894 
2895 	{
2896 		/*  disable Port0 TSF update */
2897 		val8 = rtw_read8(padapter, REG_BCN_CTRL);
2898 		val8 |= DIS_TSF_UDT;
2899 		rtw_write8(padapter, REG_BCN_CTRL, val8);
2900 
2901 		/*  set net_type */
2902 		Set_MSR(padapter, mode);
2903 
2904 		if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
2905 			{
2906 				StopTxBeacon(padapter);
2907 			}
2908 
2909 			/*  disable atim wnd */
2910 			rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_ATIM);
2911 			/* rtw_write8(padapter, REG_BCN_CTRL, 0x18); */
2912 		} else if (mode == _HW_STATE_ADHOC_) {
2913 			ResumeTxBeacon(padapter);
2914 			rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
2915 		} else if (mode == _HW_STATE_AP_) {
2916 
2917 			ResumeTxBeacon(padapter);
2918 
2919 			rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|DIS_BCNQ_SUB);
2920 
2921 			/* Set RCR */
2922 			rtw_write32(padapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0, reject ICV_ERR packet */
2923 			/* enable to rx data frame */
2924 			rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
2925 			/* enable to rx ps-poll */
2926 			rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
2927 
2928 			/* Beacon Control related register for first time */
2929 			rtw_write8(padapter, REG_BCNDMATIM, 0x02); /*  2ms */
2930 
2931 			/* rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF); */
2932 			rtw_write8(padapter, REG_ATIMWND, 0x0a); /*  10ms */
2933 			rtw_write16(padapter, REG_BCNTCFG, 0x00);
2934 			rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
2935 			rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/*  +32767 (~32ms) */
2936 
2937 			/* reset TSF */
2938 			rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
2939 
2940 			/* enable BCN0 Function for if1 */
2941 			/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
2942 			rtw_write8(padapter, REG_BCN_CTRL, (DIS_TSF_UDT|EN_BCN_FUNCTION|EN_TXBCN_RPT|DIS_BCNQ_SUB));
2943 
2944 			/* SW_BCN_SEL - Port0 */
2945 			/* rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2) & ~BIT4); */
2946 			rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
2947 
2948 			/*  select BCN on port 0 */
2949 			rtw_write8(
2950 				padapter,
2951 				REG_CCK_CHECK_8723B,
2952 				(rtw_read8(padapter, REG_CCK_CHECK_8723B)&~BIT_BCN_PORT_SEL)
2953 			);
2954 
2955 			/*  dis BCN1 ATIM  WND if if2 is station */
2956 			val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
2957 			val8 |= DIS_ATIM;
2958 			rtw_write8(padapter, REG_BCN_CTRL_1, val8);
2959 		}
2960 	}
2961 }
2962 
2963 static void hw_var_set_macaddr(struct adapter *padapter, u8 variable, u8 *val)
2964 {
2965 	u8 idx = 0;
2966 	u32 reg_macid;
2967 
2968 	reg_macid = REG_MACID;
2969 
2970 	for (idx = 0 ; idx < 6; idx++)
2971 		rtw_write8(GET_PRIMARY_ADAPTER(padapter), (reg_macid+idx), val[idx]);
2972 }
2973 
2974 static void hw_var_set_bssid(struct adapter *padapter, u8 variable, u8 *val)
2975 {
2976 	u8 idx = 0;
2977 	u32 reg_bssid;
2978 
2979 	reg_bssid = REG_BSSID;
2980 
2981 	for (idx = 0 ; idx < 6; idx++)
2982 		rtw_write8(padapter, (reg_bssid+idx), val[idx]);
2983 }
2984 
2985 static void hw_var_set_bcn_func(struct adapter *padapter, u8 variable, u8 *val)
2986 {
2987 	u32 bcn_ctrl_reg;
2988 
2989 	bcn_ctrl_reg = REG_BCN_CTRL;
2990 
2991 	if (*(u8 *)val)
2992 		rtw_write8(padapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
2993 	else {
2994 		u8 val8;
2995 		val8 = rtw_read8(padapter, bcn_ctrl_reg);
2996 		val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
2997 
2998 		/*  Always enable port0 beacon function for PSTDMA */
2999 		if (REG_BCN_CTRL == bcn_ctrl_reg)
3000 			val8 |= EN_BCN_FUNCTION;
3001 
3002 		rtw_write8(padapter, bcn_ctrl_reg, val8);
3003 	}
3004 }
3005 
3006 static void hw_var_set_correct_tsf(struct adapter *padapter, u8 variable, u8 *val)
3007 {
3008 	u8 val8;
3009 	u64 tsf;
3010 	struct mlme_ext_priv *pmlmeext;
3011 	struct mlme_ext_info *pmlmeinfo;
3012 
3013 
3014 	pmlmeext = &padapter->mlmeextpriv;
3015 	pmlmeinfo = &pmlmeext->mlmext_info;
3016 
3017 	tsf = pmlmeext->TSFValue-do_div(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024))-1024; /* us */
3018 
3019 	if (
3020 		((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
3021 		((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3022 	)
3023 		StopTxBeacon(padapter);
3024 
3025 	{
3026 		/*  disable related TSF function */
3027 		val8 = rtw_read8(padapter, REG_BCN_CTRL);
3028 		val8 &= ~EN_BCN_FUNCTION;
3029 		rtw_write8(padapter, REG_BCN_CTRL, val8);
3030 
3031 		rtw_write32(padapter, REG_TSFTR, tsf);
3032 		rtw_write32(padapter, REG_TSFTR+4, tsf>>32);
3033 
3034 		/*  enable related TSF function */
3035 		val8 = rtw_read8(padapter, REG_BCN_CTRL);
3036 		val8 |= EN_BCN_FUNCTION;
3037 		rtw_write8(padapter, REG_BCN_CTRL, val8);
3038 	}
3039 
3040 	if (
3041 		((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
3042 		((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3043 	)
3044 		ResumeTxBeacon(padapter);
3045 }
3046 
3047 static void hw_var_set_mlme_disconnect(struct adapter *padapter, u8 variable, u8 *val)
3048 {
3049 	u8 val8;
3050 
3051 	/*  Set RCR to not to receive data frame when NO LINK state */
3052 	/* rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF); */
3053 	/*  reject all data frames */
3054 	rtw_write16(padapter, REG_RXFLTMAP2, 0);
3055 
3056 	/*  reset TSF */
3057 	rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
3058 
3059 	/*  disable update TSF */
3060 	val8 = rtw_read8(padapter, REG_BCN_CTRL);
3061 	val8 |= DIS_TSF_UDT;
3062 	rtw_write8(padapter, REG_BCN_CTRL, val8);
3063 }
3064 
3065 static void hw_var_set_mlme_sitesurvey(struct adapter *padapter, u8 variable, u8 *val)
3066 {
3067 	u32 value_rcr, rcr_clear_bit, reg_bcn_ctl;
3068 	u16 value_rxfltmap2;
3069 	u8 val8;
3070 	struct hal_com_data *pHalData;
3071 	struct mlme_priv *pmlmepriv;
3072 
3073 
3074 	pHalData = GET_HAL_DATA(padapter);
3075 	pmlmepriv = &padapter->mlmepriv;
3076 
3077 	reg_bcn_ctl = REG_BCN_CTRL;
3078 
3079 	rcr_clear_bit = RCR_CBSSID_BCN;
3080 
3081 	/*  config RCR to receive different BSSID & not to receive data frame */
3082 	value_rxfltmap2 = 0;
3083 
3084 	if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == true))
3085 		rcr_clear_bit = RCR_CBSSID_BCN;
3086 
3087 	value_rcr = rtw_read32(padapter, REG_RCR);
3088 
3089 	if (*((u8 *)val)) {
3090 		/*  under sitesurvey */
3091 		value_rcr &= ~(rcr_clear_bit);
3092 		rtw_write32(padapter, REG_RCR, value_rcr);
3093 
3094 		rtw_write16(padapter, REG_RXFLTMAP2, value_rxfltmap2);
3095 
3096 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
3097 			/*  disable update TSF */
3098 			val8 = rtw_read8(padapter, reg_bcn_ctl);
3099 			val8 |= DIS_TSF_UDT;
3100 			rtw_write8(padapter, reg_bcn_ctl, val8);
3101 		}
3102 
3103 		/*  Save original RRSR setting. */
3104 		pHalData->RegRRSR = rtw_read16(padapter, REG_RRSR);
3105 	} else {
3106 		/*  sitesurvey done */
3107 		if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)))
3108 			/*  enable to rx data frame */
3109 			rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
3110 
3111 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
3112 			/*  enable update TSF */
3113 			val8 = rtw_read8(padapter, reg_bcn_ctl);
3114 			val8 &= ~DIS_TSF_UDT;
3115 			rtw_write8(padapter, reg_bcn_ctl, val8);
3116 		}
3117 
3118 		value_rcr |= rcr_clear_bit;
3119 		rtw_write32(padapter, REG_RCR, value_rcr);
3120 
3121 		/*  Restore original RRSR setting. */
3122 		rtw_write16(padapter, REG_RRSR, pHalData->RegRRSR);
3123 	}
3124 }
3125 
3126 static void hw_var_set_mlme_join(struct adapter *padapter, u8 variable, u8 *val)
3127 {
3128 	u8 val8;
3129 	u16 val16;
3130 	u32 val32;
3131 	u8 RetryLimit;
3132 	u8 type;
3133 	struct mlme_priv *pmlmepriv;
3134 	struct eeprom_priv *pEEPROM;
3135 
3136 
3137 	RetryLimit = 0x30;
3138 	type = *(u8 *)val;
3139 	pmlmepriv = &padapter->mlmepriv;
3140 	pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
3141 
3142 	if (type == 0) { /*  prepare to join */
3143 		/* enable to rx data frame.Accept all data frame */
3144 		/* rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF); */
3145 		rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
3146 
3147 		val32 = rtw_read32(padapter, REG_RCR);
3148 		if (padapter->in_cta_test)
3149 			val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
3150 		else
3151 			val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
3152 		rtw_write32(padapter, REG_RCR, val32);
3153 
3154 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
3155 			RetryLimit = (pEEPROM->CustomerID == RT_CID_CCX) ? 7 : 48;
3156 		else /*  Ad-hoc Mode */
3157 			RetryLimit = 0x7;
3158 	} else if (type == 1) /* joinbss_event call back when join res < 0 */
3159 		rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
3160 	else if (type == 2) { /* sta add event call back */
3161 		/* enable update TSF */
3162 		val8 = rtw_read8(padapter, REG_BCN_CTRL);
3163 		val8 &= ~DIS_TSF_UDT;
3164 		rtw_write8(padapter, REG_BCN_CTRL, val8);
3165 
3166 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
3167 			RetryLimit = 0x7;
3168 	}
3169 
3170 	val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
3171 	rtw_write16(padapter, REG_RL, val16);
3172 }
3173 
3174 void CCX_FwC2HTxRpt_8723b(struct adapter *padapter, u8 *pdata, u8 len)
3175 {
3176 
3177 #define	GET_8723B_C2H_TX_RPT_LIFE_TIME_OVER(_Header)	LE_BITS_TO_1BYTE((_Header + 0), 6, 1)
3178 #define	GET_8723B_C2H_TX_RPT_RETRY_OVER(_Header)	LE_BITS_TO_1BYTE((_Header + 0), 7, 1)
3179 
3180 	if (GET_8723B_C2H_TX_RPT_RETRY_OVER(pdata) | GET_8723B_C2H_TX_RPT_LIFE_TIME_OVER(pdata)) {
3181 		rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
3182 	}
3183 /*
3184 	else if (seq_no != padapter->xmitpriv.seq_no) {
3185 		rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
3186 	}
3187 */
3188 	else
3189 		rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);
3190 }
3191 
3192 s32 c2h_id_filter_ccx_8723b(u8 *buf)
3193 {
3194 	struct c2h_evt_hdr_88xx *c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
3195 	s32 ret = false;
3196 	if (c2h_evt->id == C2H_CCX_TX_RPT)
3197 		ret = true;
3198 
3199 	return ret;
3200 }
3201 
3202 
3203 s32 c2h_handler_8723b(struct adapter *padapter, u8 *buf)
3204 {
3205 	struct c2h_evt_hdr_88xx *pC2hEvent = (struct c2h_evt_hdr_88xx *)buf;
3206 	s32 ret = _SUCCESS;
3207 
3208 	if (!pC2hEvent) {
3209 		ret = _FAIL;
3210 		goto exit;
3211 	}
3212 
3213 	switch (pC2hEvent->id) {
3214 	case C2H_AP_RPT_RSP:
3215 		break;
3216 	case C2H_DBG:
3217 		{
3218 		}
3219 		break;
3220 
3221 	case C2H_CCX_TX_RPT:
3222 /* 			CCX_FwC2HTxRpt(padapter, QueueID, pC2hEvent->payload); */
3223 		break;
3224 
3225 	case C2H_EXT_RA_RPT:
3226 /* 			C2HExtRaRptHandler(padapter, pC2hEvent->payload, C2hEvent.CmdLen); */
3227 		break;
3228 
3229 	case C2H_HW_INFO_EXCH:
3230 		break;
3231 
3232 	case C2H_8723B_BT_INFO:
3233 		hal_btcoex_BtInfoNotify(padapter, pC2hEvent->plen, pC2hEvent->payload);
3234 		break;
3235 
3236 	default:
3237 		break;
3238 	}
3239 
3240 	/*  Clear event to notify FW we have read the command. */
3241 	/*  Note: */
3242 	/* 	If this field isn't clear, the FW won't update the next command message. */
3243 /* 	rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); */
3244 exit:
3245 	return ret;
3246 }
3247 
3248 static void process_c2h_event(struct adapter *padapter, struct c2h_evt_hdr_t *pC2hEvent, u8 *c2hBuf)
3249 {
3250 	if (!c2hBuf)
3251 		return;
3252 
3253 	switch (pC2hEvent->CmdID) {
3254 	case C2H_AP_RPT_RSP:
3255 		break;
3256 	case C2H_DBG:
3257 		{
3258 		}
3259 		break;
3260 
3261 	case C2H_CCX_TX_RPT:
3262 /* 			CCX_FwC2HTxRpt(padapter, QueueID, tmpBuf); */
3263 		break;
3264 
3265 	case C2H_EXT_RA_RPT:
3266 /* 			C2HExtRaRptHandler(padapter, tmpBuf, C2hEvent.CmdLen); */
3267 		break;
3268 
3269 	case C2H_HW_INFO_EXCH:
3270 		break;
3271 
3272 	case C2H_8723B_BT_INFO:
3273 		hal_btcoex_BtInfoNotify(padapter, pC2hEvent->CmdLen, c2hBuf);
3274 		break;
3275 
3276 	default:
3277 		break;
3278 	}
3279 }
3280 
3281 void C2HPacketHandler_8723B(struct adapter *padapter, u8 *pbuffer, u16 length)
3282 {
3283 	struct c2h_evt_hdr_t	C2hEvent;
3284 	u8 *tmpBuf = NULL;
3285 	C2hEvent.CmdID = pbuffer[0];
3286 	C2hEvent.CmdSeq = pbuffer[1];
3287 	C2hEvent.CmdLen = length-2;
3288 	tmpBuf = pbuffer+2;
3289 
3290 	process_c2h_event(padapter, &C2hEvent, tmpBuf);
3291 	/* c2h_handler_8723b(padapter,&C2hEvent); */
3292 }
3293 
3294 void SetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val)
3295 {
3296 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
3297 	u8 val8;
3298 	u32 val32;
3299 
3300 	switch (variable) {
3301 	case HW_VAR_MEDIA_STATUS:
3302 		val8 = rtw_read8(padapter, MSR) & 0x0c;
3303 		val8 |= *val;
3304 		rtw_write8(padapter, MSR, val8);
3305 		break;
3306 
3307 	case HW_VAR_MEDIA_STATUS1:
3308 		val8 = rtw_read8(padapter, MSR) & 0x03;
3309 		val8 |= *val << 2;
3310 		rtw_write8(padapter, MSR, val8);
3311 		break;
3312 
3313 	case HW_VAR_SET_OPMODE:
3314 		hw_var_set_opmode(padapter, variable, val);
3315 		break;
3316 
3317 	case HW_VAR_MAC_ADDR:
3318 		hw_var_set_macaddr(padapter, variable, val);
3319 		break;
3320 
3321 	case HW_VAR_BSSID:
3322 		hw_var_set_bssid(padapter, variable, val);
3323 		break;
3324 
3325 	case HW_VAR_BASIC_RATE:
3326 	{
3327 		struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
3328 		u16 BrateCfg = 0;
3329 		u16 rrsr_2g_force_mask = (RRSR_11M|RRSR_5_5M|RRSR_1M);
3330 		u16 rrsr_2g_allow_mask = (RRSR_24M|RRSR_12M|RRSR_6M|RRSR_CCK_RATES);
3331 
3332 		HalSetBrateCfg(padapter, val, &BrateCfg);
3333 
3334 		/* apply force and allow mask */
3335 		BrateCfg |= rrsr_2g_force_mask;
3336 		BrateCfg &= rrsr_2g_allow_mask;
3337 
3338 		/* IOT consideration */
3339 		if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
3340 			/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
3341 			if ((BrateCfg & (RRSR_24M|RRSR_12M|RRSR_6M)) == 0)
3342 				BrateCfg |= RRSR_6M;
3343 		}
3344 
3345 		pHalData->BasicRateSet = BrateCfg;
3346 
3347 		/*  Set RRSR rate table. */
3348 		rtw_write16(padapter, REG_RRSR, BrateCfg);
3349 		rtw_write8(padapter, REG_RRSR+2, rtw_read8(padapter, REG_RRSR+2)&0xf0);
3350 	}
3351 		break;
3352 
3353 	case HW_VAR_TXPAUSE:
3354 		rtw_write8(padapter, REG_TXPAUSE, *val);
3355 		break;
3356 
3357 	case HW_VAR_BCN_FUNC:
3358 		hw_var_set_bcn_func(padapter, variable, val);
3359 		break;
3360 
3361 	case HW_VAR_CORRECT_TSF:
3362 		hw_var_set_correct_tsf(padapter, variable, val);
3363 		break;
3364 
3365 	case HW_VAR_CHECK_BSSID:
3366 		{
3367 			u32 val32;
3368 			val32 = rtw_read32(padapter, REG_RCR);
3369 			if (*val)
3370 				val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
3371 			else
3372 				val32 &= ~(RCR_CBSSID_DATA|RCR_CBSSID_BCN);
3373 			rtw_write32(padapter, REG_RCR, val32);
3374 		}
3375 		break;
3376 
3377 	case HW_VAR_MLME_DISCONNECT:
3378 		hw_var_set_mlme_disconnect(padapter, variable, val);
3379 		break;
3380 
3381 	case HW_VAR_MLME_SITESURVEY:
3382 		hw_var_set_mlme_sitesurvey(padapter, variable,  val);
3383 
3384 		hal_btcoex_ScanNotify(padapter, *val?true:false);
3385 		break;
3386 
3387 	case HW_VAR_MLME_JOIN:
3388 		hw_var_set_mlme_join(padapter, variable, val);
3389 
3390 		switch (*val) {
3391 		case 0:
3392 			/*  prepare to join */
3393 			hal_btcoex_ConnectNotify(padapter, true);
3394 			break;
3395 		case 1:
3396 			/*  joinbss_event callback when join res < 0 */
3397 			hal_btcoex_ConnectNotify(padapter, false);
3398 			break;
3399 		case 2:
3400 			/*  sta add event callback */
3401 /* 				rtw_btcoex_MediaStatusNotify(padapter, RT_MEDIA_CONNECT); */
3402 			break;
3403 		}
3404 		break;
3405 
3406 	case HW_VAR_ON_RCR_AM:
3407 		val32 = rtw_read32(padapter, REG_RCR);
3408 		val32 |= RCR_AM;
3409 		rtw_write32(padapter, REG_RCR, val32);
3410 		break;
3411 
3412 	case HW_VAR_OFF_RCR_AM:
3413 		val32 = rtw_read32(padapter, REG_RCR);
3414 		val32 &= ~RCR_AM;
3415 		rtw_write32(padapter, REG_RCR, val32);
3416 		break;
3417 
3418 	case HW_VAR_BEACON_INTERVAL:
3419 		rtw_write16(padapter, REG_BCN_INTERVAL, *((u16 *)val));
3420 		break;
3421 
3422 	case HW_VAR_SLOT_TIME:
3423 		rtw_write8(padapter, REG_SLOT, *val);
3424 		break;
3425 
3426 	case HW_VAR_RESP_SIFS:
3427 		/* SIFS_Timer = 0x0a0a0808; */
3428 		/* RESP_SIFS for CCK */
3429 		rtw_write8(padapter, REG_RESP_SIFS_CCK, val[0]); /*  SIFS_T2T_CCK (0x08) */
3430 		rtw_write8(padapter, REG_RESP_SIFS_CCK+1, val[1]); /* SIFS_R2T_CCK(0x08) */
3431 		/* RESP_SIFS for OFDM */
3432 		rtw_write8(padapter, REG_RESP_SIFS_OFDM, val[2]); /* SIFS_T2T_OFDM (0x0a) */
3433 		rtw_write8(padapter, REG_RESP_SIFS_OFDM+1, val[3]); /* SIFS_R2T_OFDM(0x0a) */
3434 		break;
3435 
3436 	case HW_VAR_ACK_PREAMBLE:
3437 		{
3438 			u8 regTmp;
3439 			u8 bShortPreamble = *val;
3440 
3441 			/*  Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
3442 			/* regTmp = (pHalData->nCur40MhzPrimeSC)<<5; */
3443 			regTmp = 0;
3444 			if (bShortPreamble)
3445 				regTmp |= 0x80;
3446 			rtw_write8(padapter, REG_RRSR+2, regTmp);
3447 		}
3448 		break;
3449 
3450 	case HW_VAR_CAM_EMPTY_ENTRY:
3451 		{
3452 			u8 ucIndex = *val;
3453 			u8 i;
3454 			u32 ulCommand = 0;
3455 			u32 ulContent = 0;
3456 			u32 ulEncAlgo = CAM_AES;
3457 
3458 			for (i = 0; i < CAM_CONTENT_COUNT; i++) {
3459 				/*  filled id in CAM config 2 byte */
3460 				if (i == 0) {
3461 					ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2);
3462 					/* ulContent |= CAM_VALID; */
3463 				} else
3464 					ulContent = 0;
3465 
3466 				/*  polling bit, and No Write enable, and address */
3467 				ulCommand = CAM_CONTENT_COUNT*ucIndex+i;
3468 				ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
3469 				/*  write content 0 is equall to mark invalid */
3470 				rtw_write32(padapter, WCAMI, ulContent);  /* mdelay(40); */
3471 				rtw_write32(padapter, RWCAM, ulCommand);  /* mdelay(40); */
3472 			}
3473 		}
3474 		break;
3475 
3476 	case HW_VAR_CAM_INVALID_ALL:
3477 		rtw_write32(padapter, RWCAM, BIT(31)|BIT(30));
3478 		break;
3479 
3480 	case HW_VAR_CAM_WRITE:
3481 		{
3482 			u32 cmd;
3483 			u32 *cam_val = (u32 *)val;
3484 
3485 			rtw_write32(padapter, WCAMI, cam_val[0]);
3486 
3487 			cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
3488 			rtw_write32(padapter, RWCAM, cmd);
3489 		}
3490 		break;
3491 
3492 	case HW_VAR_AC_PARAM_VO:
3493 		rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32 *)val));
3494 		break;
3495 
3496 	case HW_VAR_AC_PARAM_VI:
3497 		rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32 *)val));
3498 		break;
3499 
3500 	case HW_VAR_AC_PARAM_BE:
3501 		pHalData->AcParam_BE = ((u32 *)(val))[0];
3502 		rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32 *)val));
3503 		break;
3504 
3505 	case HW_VAR_AC_PARAM_BK:
3506 		rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32 *)val));
3507 		break;
3508 
3509 	case HW_VAR_ACM_CTRL:
3510 		{
3511 			u8 ctrl = *((u8 *)val);
3512 			u8 hwctrl = 0;
3513 
3514 			if (ctrl != 0) {
3515 				hwctrl |= AcmHw_HwEn;
3516 
3517 				if (ctrl & BIT(1)) /*  BE */
3518 					hwctrl |= AcmHw_BeqEn;
3519 
3520 				if (ctrl & BIT(2)) /*  VI */
3521 					hwctrl |= AcmHw_ViqEn;
3522 
3523 				if (ctrl & BIT(3)) /*  VO */
3524 					hwctrl |= AcmHw_VoqEn;
3525 			}
3526 
3527 			rtw_write8(padapter, REG_ACMHWCTRL, hwctrl);
3528 		}
3529 		break;
3530 
3531 	case HW_VAR_AMPDU_FACTOR:
3532 		{
3533 			u32 AMPDULen =  (*((u8 *)val));
3534 
3535 			if (AMPDULen < HT_AGG_SIZE_32K)
3536 				AMPDULen = (0x2000 << (*((u8 *)val)))-1;
3537 			else
3538 				AMPDULen = 0x7fff;
3539 
3540 			rtw_write32(padapter, REG_AMPDU_MAX_LENGTH_8723B, AMPDULen);
3541 		}
3542 		break;
3543 
3544 	case HW_VAR_H2C_FW_PWRMODE:
3545 		{
3546 			u8 psmode = *val;
3547 
3548 			/*  Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */
3549 			/*  saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */
3550 			if (psmode != PS_MODE_ACTIVE) {
3551 				ODM_RF_Saving(&pHalData->odmpriv, true);
3552 			}
3553 
3554 			/* if (psmode != PS_MODE_ACTIVE)	{ */
3555 			/* 	rtl8723b_set_lowpwr_lps_cmd(padapter, true); */
3556 			/*  else { */
3557 			/* 	rtl8723b_set_lowpwr_lps_cmd(padapter, false); */
3558 			/*  */
3559 			rtl8723b_set_FwPwrMode_cmd(padapter, psmode);
3560 		}
3561 		break;
3562 	case HW_VAR_H2C_PS_TUNE_PARAM:
3563 		rtl8723b_set_FwPsTuneParam_cmd(padapter);
3564 		break;
3565 
3566 	case HW_VAR_H2C_FW_JOINBSSRPT:
3567 		rtl8723b_set_FwJoinBssRpt_cmd(padapter, *val);
3568 		break;
3569 
3570 	case HW_VAR_INITIAL_GAIN:
3571 		{
3572 			struct dig_t *pDigTable = &pHalData->odmpriv.DM_DigTable;
3573 			u32 rx_gain = *(u32 *)val;
3574 
3575 			if (rx_gain == 0xff) {/* restore rx gain */
3576 				ODM_Write_DIG(&pHalData->odmpriv, pDigTable->BackupIGValue);
3577 			} else {
3578 				pDigTable->BackupIGValue = pDigTable->CurIGValue;
3579 				ODM_Write_DIG(&pHalData->odmpriv, rx_gain);
3580 			}
3581 		}
3582 		break;
3583 
3584 	case HW_VAR_EFUSE_USAGE:
3585 		pHalData->EfuseUsedPercentage = *val;
3586 		break;
3587 
3588 	case HW_VAR_EFUSE_BYTES:
3589 		pHalData->EfuseUsedBytes = *((u16 *)val);
3590 		break;
3591 
3592 	case HW_VAR_EFUSE_BT_USAGE:
3593 #ifdef HAL_EFUSE_MEMORY
3594 		pHalData->EfuseHal.BTEfuseUsedPercentage = *val;
3595 #endif
3596 		break;
3597 
3598 	case HW_VAR_EFUSE_BT_BYTES:
3599 #ifdef HAL_EFUSE_MEMORY
3600 		pHalData->EfuseHal.BTEfuseUsedBytes = *((u16 *)val);
3601 #else
3602 		BTEfuseUsedBytes = *((u16 *)val);
3603 #endif
3604 		break;
3605 
3606 	case HW_VAR_FIFO_CLEARN_UP:
3607 		{
3608 			#define RW_RELEASE_EN		BIT(18)
3609 			#define RXDMA_IDLE			BIT(17)
3610 
3611 			struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
3612 			u8 trycnt = 100;
3613 
3614 			/*  pause tx */
3615 			rtw_write8(padapter, REG_TXPAUSE, 0xff);
3616 
3617 			/*  keep sn */
3618 			padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ);
3619 
3620 			if (!pwrpriv->bkeepfwalive) {
3621 				/* RX DMA stop */
3622 				val32 = rtw_read32(padapter, REG_RXPKT_NUM);
3623 				val32 |= RW_RELEASE_EN;
3624 				rtw_write32(padapter, REG_RXPKT_NUM, val32);
3625 				do {
3626 					val32 = rtw_read32(padapter, REG_RXPKT_NUM);
3627 					val32 &= RXDMA_IDLE;
3628 					if (val32)
3629 						break;
3630 				} while (--trycnt);
3631 
3632 				/*  RQPN Load 0 */
3633 				rtw_write16(padapter, REG_RQPN_NPQ, 0);
3634 				rtw_write32(padapter, REG_RQPN, 0x80000000);
3635 				mdelay(2);
3636 			}
3637 		}
3638 		break;
3639 
3640 	case HW_VAR_APFM_ON_MAC:
3641 		pHalData->bMacPwrCtrlOn = *val;
3642 		break;
3643 
3644 	case HW_VAR_NAV_UPPER:
3645 		{
3646 			u32 usNavUpper = *((u32 *)val);
3647 
3648 			if (usNavUpper > HAL_NAV_UPPER_UNIT_8723B * 0xFF)
3649 				break;
3650 
3651 			usNavUpper = DIV_ROUND_UP(usNavUpper,
3652 						  HAL_NAV_UPPER_UNIT_8723B);
3653 			rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);
3654 		}
3655 		break;
3656 
3657 	case HW_VAR_H2C_MEDIA_STATUS_RPT:
3658 		{
3659 			u16 mstatus_rpt = (*(u16 *)val);
3660 			u8 mstatus, macId;
3661 
3662 			mstatus = (u8) (mstatus_rpt & 0xFF);
3663 			macId = (u8)(mstatus_rpt >> 8);
3664 			rtl8723b_set_FwMediaStatusRpt_cmd(padapter, mstatus, macId);
3665 		}
3666 		break;
3667 	case HW_VAR_BCN_VALID:
3668 		{
3669 			/*  BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw */
3670 			val8 = rtw_read8(padapter, REG_TDECTRL+2);
3671 			val8 |= BIT(0);
3672 			rtw_write8(padapter, REG_TDECTRL+2, val8);
3673 		}
3674 		break;
3675 
3676 	case HW_VAR_DL_BCN_SEL:
3677 		{
3678 			/*  SW_BCN_SEL - Port0 */
3679 			val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
3680 			val8 &= ~BIT(4);
3681 			rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8);
3682 		}
3683 		break;
3684 
3685 	case HW_VAR_DO_IQK:
3686 		pHalData->bNeedIQK = true;
3687 		break;
3688 
3689 	case HW_VAR_DL_RSVD_PAGE:
3690 		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)
3691 			rtl8723b_download_BTCoex_AP_mode_rsvd_page(padapter);
3692 		else
3693 			rtl8723b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
3694 		break;
3695 
3696 	case HW_VAR_MACID_SLEEP:
3697 		/*  Input is MACID */
3698 		val32 = *(u32 *)val;
3699 		if (val32 > 31)
3700 			break;
3701 
3702 		val8 = (u8)val32; /*  macid is between 0~31 */
3703 
3704 		val32 = rtw_read32(padapter, REG_MACID_SLEEP);
3705 		if (val32 & BIT(val8))
3706 			break;
3707 		val32 |= BIT(val8);
3708 		rtw_write32(padapter, REG_MACID_SLEEP, val32);
3709 		break;
3710 
3711 	case HW_VAR_MACID_WAKEUP:
3712 		/*  Input is MACID */
3713 		val32 = *(u32 *)val;
3714 		if (val32 > 31)
3715 			break;
3716 
3717 		val8 = (u8)val32; /*  macid is between 0~31 */
3718 
3719 		val32 = rtw_read32(padapter, REG_MACID_SLEEP);
3720 		if (!(val32 & BIT(val8)))
3721 			break;
3722 		val32 &= ~BIT(val8);
3723 		rtw_write32(padapter, REG_MACID_SLEEP, val32);
3724 		break;
3725 
3726 	default:
3727 		SetHwReg(padapter, variable, val);
3728 		break;
3729 	}
3730 }
3731 
3732 void GetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val)
3733 {
3734 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
3735 	u8 val8;
3736 	u16 val16;
3737 
3738 	switch (variable) {
3739 	case HW_VAR_TXPAUSE:
3740 		*val = rtw_read8(padapter, REG_TXPAUSE);
3741 		break;
3742 
3743 	case HW_VAR_BCN_VALID:
3744 		{
3745 			/*  BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */
3746 			val8 = rtw_read8(padapter, REG_TDECTRL+2);
3747 			*val = (BIT(0) & val8) ? true : false;
3748 		}
3749 		break;
3750 
3751 	case HW_VAR_FWLPS_RF_ON:
3752 		{
3753 			/*  When we halt NIC, we should check if FW LPS is leave. */
3754 			u32 valRCR;
3755 
3756 			if (
3757 				padapter->bSurpriseRemoved  ||
3758 				(adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off)
3759 			) {
3760 				/*  If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */
3761 				/*  because Fw is unload. */
3762 				*val = true;
3763 			} else {
3764 				valRCR = rtw_read32(padapter, REG_RCR);
3765 				valRCR &= 0x00070000;
3766 				if (valRCR)
3767 					*val = false;
3768 				else
3769 					*val = true;
3770 			}
3771 		}
3772 		break;
3773 
3774 	case HW_VAR_EFUSE_USAGE:
3775 		*val = pHalData->EfuseUsedPercentage;
3776 		break;
3777 
3778 	case HW_VAR_EFUSE_BYTES:
3779 		*((u16 *)val) = pHalData->EfuseUsedBytes;
3780 		break;
3781 
3782 	case HW_VAR_EFUSE_BT_USAGE:
3783 #ifdef HAL_EFUSE_MEMORY
3784 		*val = pHalData->EfuseHal.BTEfuseUsedPercentage;
3785 #endif
3786 		break;
3787 
3788 	case HW_VAR_EFUSE_BT_BYTES:
3789 #ifdef HAL_EFUSE_MEMORY
3790 		*((u16 *)val) = pHalData->EfuseHal.BTEfuseUsedBytes;
3791 #else
3792 		*((u16 *)val) = BTEfuseUsedBytes;
3793 #endif
3794 		break;
3795 
3796 	case HW_VAR_APFM_ON_MAC:
3797 		*val = pHalData->bMacPwrCtrlOn;
3798 		break;
3799 	case HW_VAR_CHK_HI_QUEUE_EMPTY:
3800 		val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);
3801 		*val = (val16 & BIT(10)) ? true:false;
3802 		break;
3803 	default:
3804 		GetHwReg(padapter, variable, val);
3805 		break;
3806 	}
3807 }
3808 
3809 /* Description:
3810  *	Change default setting of specified variable.
3811  */
3812 u8 SetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, void *pval)
3813 {
3814 	u8 bResult;
3815 
3816 	bResult = _SUCCESS;
3817 
3818 	switch (variable) {
3819 	default:
3820 		bResult = SetHalDefVar(padapter, variable, pval);
3821 		break;
3822 	}
3823 
3824 	return bResult;
3825 }
3826 
3827 /* Description:
3828  *	Query setting of specified variable.
3829  */
3830 u8 GetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, void *pval)
3831 {
3832 	u8 bResult;
3833 
3834 	bResult = _SUCCESS;
3835 
3836 	switch (variable) {
3837 	case HAL_DEF_MAX_RECVBUF_SZ:
3838 		*((u32 *)pval) = MAX_RECVBUF_SZ;
3839 		break;
3840 
3841 	case HAL_DEF_RX_PACKET_OFFSET:
3842 		*((u32 *)pval) = RXDESC_SIZE + DRVINFO_SZ*8;
3843 		break;
3844 
3845 	case HW_VAR_MAX_RX_AMPDU_FACTOR:
3846 		/*  Stanley@BB.SD3 suggests 16K can get stable performance */
3847 		/*  The experiment was done on SDIO interface */
3848 		/*  coding by Lucas@20130730 */
3849 		*(u32 *)pval = IEEE80211_HT_MAX_AMPDU_16K;
3850 		break;
3851 	case HAL_DEF_TX_LDPC:
3852 	case HAL_DEF_RX_LDPC:
3853 		*((u8 *)pval) = false;
3854 		break;
3855 	case HAL_DEF_TX_STBC:
3856 		*((u8 *)pval) = 0;
3857 		break;
3858 	case HAL_DEF_RX_STBC:
3859 		*((u8 *)pval) = 1;
3860 		break;
3861 	case HAL_DEF_EXPLICIT_BEAMFORMER:
3862 	case HAL_DEF_EXPLICIT_BEAMFORMEE:
3863 		*((u8 *)pval) = false;
3864 		break;
3865 
3866 	case HW_DEF_RA_INFO_DUMP:
3867 		{
3868 			u8 mac_id = *(u8 *)pval;
3869 			u32 cmd;
3870 
3871 			cmd = 0x40000100 | mac_id;
3872 			rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B, cmd);
3873 			msleep(10);
3874 			rtw_read32(padapter, 0x2F0);	// info 1
3875 
3876 			cmd = 0x40000400 | mac_id;
3877 			rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B, cmd);
3878 			msleep(10);
3879 			rtw_read32(padapter, 0x2F0);	// info 1
3880 			rtw_read32(padapter, 0x2F4);	// info 2
3881 			rtw_read32(padapter, 0x2F8);	// rate mask 1
3882 			rtw_read32(padapter, 0x2FC);	// rate mask 2
3883 		}
3884 		break;
3885 
3886 	case HAL_DEF_TX_PAGE_BOUNDARY:
3887 		if (!padapter->registrypriv.wifi_spec) {
3888 			*(u8 *)pval = TX_PAGE_BOUNDARY_8723B;
3889 		} else {
3890 			*(u8 *)pval = WMM_NORMAL_TX_PAGE_BOUNDARY_8723B;
3891 		}
3892 		break;
3893 
3894 	case HAL_DEF_MACID_SLEEP:
3895 		*(u8 *)pval = true; /*  support macid sleep */
3896 		break;
3897 
3898 	default:
3899 		bResult = GetHalDefVar(padapter, variable, pval);
3900 		break;
3901 	}
3902 
3903 	return bResult;
3904 }
3905 
3906 void rtl8723b_start_thread(struct adapter *padapter)
3907 {
3908 	struct xmit_priv *xmitpriv = &padapter->xmitpriv;
3909 
3910 	xmitpriv->SdioXmitThread = kthread_run(rtl8723bs_xmit_thread, padapter, "RTWHALXT");
3911 }
3912 
3913 void rtl8723b_stop_thread(struct adapter *padapter)
3914 {
3915 	struct xmit_priv *xmitpriv = &padapter->xmitpriv;
3916 
3917 	/*  stop xmit_buf_thread */
3918 	if (xmitpriv->SdioXmitThread) {
3919 		complete(&xmitpriv->SdioXmitStart);
3920 		wait_for_completion(&xmitpriv->SdioXmitTerminate);
3921 		xmitpriv->SdioXmitThread = NULL;
3922 	}
3923 }
3924