File Index
Files and directories
Sign in
FILE

rtl8723b_hal_init.c

File preview with syntax highlighting.

linux-6.19.14/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
   5 *
   6 ******************************************************************************/
   7
   8#include <linux/firmware.h>
   9#include <linux/slab.h>
  10#include <drv_types.h>
  11#include <rtl8723b_hal.h>
  12#include "hal_com_h2c.h"
  13
  14static void _FWDownloadEnable(struct adapter *padapter, bool enable)
  15{
  16	u8 tmp, count = 0;
  17
  18	if (enable) {
  19		/*  8051 enable */
  20		tmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
  21		rtw_write8(padapter, REG_SYS_FUNC_EN+1, tmp|0x04);
  22
  23		tmp = rtw_read8(padapter, REG_MCUFWDL);
  24		rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
  25
  26		do {
  27			tmp = rtw_read8(padapter, REG_MCUFWDL);
  28			if (tmp & 0x01)
  29				break;
  30			rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
  31			msleep(1);
  32		} while (count++ < 100);
  33
  34		/*  8051 reset */
  35		tmp = rtw_read8(padapter, REG_MCUFWDL+2);
  36		rtw_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
  37	} else {
  38		/*  MCU firmware download disable. */
  39		tmp = rtw_read8(padapter, REG_MCUFWDL);
  40		rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
  41	}
  42}
  43
  44static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize)
  45{
  46	int ret = _SUCCESS;
  47
  48	u32 blockSize_p1 = 4; /*  (Default) Phase #1 : PCI muse use 4-byte write to download FW */
  49	u32 blockSize_p2 = 8; /*  Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */
  50	u32 blockSize_p3 = 1; /*  Phase #3 : Use 1-byte, the remnant of FW image. */
  51	u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
  52	u32 remainSize_p1 = 0, remainSize_p2 = 0;
  53	u8 *bufferPtr = buffer;
  54	u32 i = 0, offset = 0;
  55
  56	/* 3 Phase #1 */
  57	blockCount_p1 = buffSize / blockSize_p1;
  58	remainSize_p1 = buffSize % blockSize_p1;
  59
  60	for (i = 0; i < blockCount_p1; i++) {
  61		ret = rtw_write32(padapter, (FW_8723B_START_ADDRESS + i * blockSize_p1), *((u32 *)(bufferPtr + i * blockSize_p1)));
  62		if (ret == _FAIL) {
  63			netdev_dbg(padapter->pnetdev, "write failed at %s %d, block:%d\n",
  64				   __func__, __LINE__, i);
  65			goto exit;
  66		}
  67	}
  68
  69	/* 3 Phase #2 */
  70	if (remainSize_p1) {
  71		offset = blockCount_p1 * blockSize_p1;
  72
  73		blockCount_p2 = remainSize_p1/blockSize_p2;
  74		remainSize_p2 = remainSize_p1%blockSize_p2;
  75	}
  76
  77	/* 3 Phase #3 */
  78	if (remainSize_p2) {
  79		offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
  80
  81		blockCount_p3 = remainSize_p2 / blockSize_p3;
  82
  83		for (i = 0; i < blockCount_p3; i++) {
  84			ret = rtw_write8(padapter, (FW_8723B_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
  85
  86			if (ret == _FAIL) {
  87				netdev_dbg(padapter->pnetdev, "write failed at %s %d, block:%d\n",
  88					   __func__, __LINE__, i);
  89				goto exit;
  90			}
  91		}
  92	}
  93exit:
  94	return ret;
  95}
  96
  97static int _PageWrite(
  98	struct adapter *padapter,
  99	u32 page,
 100	void *buffer,
 101	u32 size
 102)
 103{
 104	u8 value8;
 105	u8 u8Page = (u8) (page & 0x07);
 106
 107	value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page;
 108	rtw_write8(padapter, REG_MCUFWDL+2, value8);
 109
 110	return _BlockWrite(padapter, buffer, size);
 111}
 112
 113static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
 114{
 115	/*  Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */
 116	/*  We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */
 117	int ret = _SUCCESS;
 118	u32 pageNums, remainSize;
 119	u32 page, offset;
 120	u8 *bufferPtr = buffer;
 121
 122	pageNums = size / MAX_DLFW_PAGE_SIZE;
 123	remainSize = size % MAX_DLFW_PAGE_SIZE;
 124
 125	for (page = 0; page < pageNums; page++) {
 126		offset = page * MAX_DLFW_PAGE_SIZE;
 127		ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_DLFW_PAGE_SIZE);
 128
 129		if (ret == _FAIL) {
 130			netdev_dbg(padapter->pnetdev, "page write failed at %s %d\n",
 131				   __func__, __LINE__);
 132			goto exit;
 133		}
 134	}
 135
 136	if (remainSize) {
 137		offset = pageNums * MAX_DLFW_PAGE_SIZE;
 138		page = pageNums;
 139		ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize);
 140
 141		if (ret == _FAIL) {
 142			netdev_dbg(padapter->pnetdev, "remaining page write failed at %s %d\n",
 143				   __func__, __LINE__);
 144			goto exit;
 145		}
 146	}
 147
 148exit:
 149	return ret;
 150}
 151
 152void _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
 180u8 g_fwdl_chksum_fail;
 181
 182static 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
 211exit:
 212
 213	return ret;
 214}
 215
 216u8 g_fwdl_wintint_rdy_fail;
 217
 218static 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
 252exit:
 253
 254	return ret;
 255}
 256
 257#define IS_FW_81xxC(padapter)	(((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
 258
 259void 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/*  */
 293s32 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
 417fwdl_stat:
 418
 419exit:
 420	kfree(pFirmware->fw_buffer_sz);
 421	kfree(pFirmware);
 422release_fw1:
 423	kfree(pBTFirmware);
 424	return rtStatus;
 425}
 426
 427void 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/*  */
 445/* 				Efuse related code */
 446/*  */
 447static u8 hal_EfuseSwitchToBank(
 448	struct adapter *padapter, u8 bank
 449)
 450{
 451	u8 bRet = true;
 452	u32 value32 = rtw_read32(padapter, EFUSE_TEST);
 453
 454	switch (bank) {
 455	case 0:
 456		value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
 457		break;
 458	case 1:
 459		value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
 460		break;
 461	case 2:
 462		value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
 463		break;
 464	case 3:
 465		value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
 466		break;
 467	default:
 468		value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
 469		bRet = false;
 470		break;
 471	}
 472	rtw_write32(padapter, EFUSE_TEST, value32);
 473
 474	return bRet;
 475}
 476
 477void Hal_GetEfuseDefinition(
 478	struct adapter *padapter,
 479	u8 efuseType,
 480	u8 type,
 481	void *pOut
 482)
 483{
 484	switch (type) {
 485	case TYPE_EFUSE_MAX_SECTION:
 486		{
 487			u8 *pMax_section = pOut;
 488
 489			if (efuseType == EFUSE_WIFI)
 490				*pMax_section = EFUSE_MAX_SECTION_8723B;
 491			else
 492				*pMax_section = EFUSE_BT_MAX_SECTION;
 493		}
 494		break;
 495
 496	case TYPE_EFUSE_REAL_CONTENT_LEN:
 497		{
 498			u16 *pu2Tmp = pOut;
 499
 500			if (efuseType == EFUSE_WIFI)
 501				*pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
 502			else
 503				*pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
 504		}
 505		break;
 506
 507	case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
 508		{
 509			u16 *pu2Tmp = pOut;
 510
 511			if (efuseType == EFUSE_WIFI)
 512				*pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
 513			else
 514				*pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN-EFUSE_PROTECT_BYTES_BANK);
 515		}
 516		break;
 517
 518	case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
 519		{
 520			u16 *pu2Tmp = pOut;
 521
 522			if (efuseType == EFUSE_WIFI)
 523				*pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
 524			else
 525				*pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN-(EFUSE_PROTECT_BYTES_BANK*3));
 526		}
 527		break;
 528
 529	case TYPE_EFUSE_MAP_LEN:
 530		{
 531			u16 *pu2Tmp = pOut;
 532
 533			if (efuseType == EFUSE_WIFI)
 534				*pu2Tmp = EFUSE_MAX_MAP_LEN;
 535			else
 536				*pu2Tmp = EFUSE_BT_MAP_LEN;
 537		}
 538		break;
 539
 540	case TYPE_EFUSE_PROTECT_BYTES_BANK:
 541		{
 542			u8 *pu1Tmp = pOut;
 543
 544			if (efuseType == EFUSE_WIFI)
 545				*pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
 546			else
 547				*pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
 548		}
 549		break;
 550
 551	case TYPE_EFUSE_CONTENT_LEN_BANK:
 552		{
 553			u16 *pu2Tmp = pOut;
 554
 555			if (efuseType == EFUSE_WIFI)
 556				*pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
 557			else
 558				*pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
 559		}
 560		break;
 561
 562	default:
 563		{
 564			u8 *pu1Tmp = pOut;
 565			*pu1Tmp = 0;
 566		}
 567		break;
 568	}
 569}
 570
 571void Hal_EfusePowerSwitch(
 572	struct adapter *padapter, u8 PwrState
 573)
 574{
 575	u8 tempval;
 576	u16 tmpV16;
 577
 578
 579	if (PwrState) {
 580		/*  To avoid cannot access efuse registers after disable/enable several times during DTM test. */
 581		/*  Suggested by SD1 IsaacHsu. 2013.07.08, added by tynli. */
 582		tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
 583		if (tempval & BIT(0)) { /*  SDIO local register is suspend */
 584			u8 count = 0;
 585
 586
 587			tempval &= ~BIT(0);
 588			rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL, tempval);
 589
 590			/*  check 0x86[1:0]= 10'2h, wait power state to leave suspend */
 591			do {
 592				tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
 593				tempval &= 0x3;
 594				if (tempval == 0x02)
 595					break;
 596
 597				count++;
 598				if (count >= 100)
 599					break;
 600
 601				mdelay(10);
 602			} while (1);
 603		}
 604
 605		rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
 606
 607		/*  Reset: 0x0000h[28], default valid */
 608		tmpV16 =  rtw_read16(padapter, REG_SYS_FUNC_EN);
 609		if (!(tmpV16 & FEN_ELDR)) {
 610			tmpV16 |= FEN_ELDR;
 611			rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
 612		}
 613
 614		/*  Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
 615		tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
 616		if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
 617			tmpV16 |= (LOADER_CLK_EN | ANA8M);
 618			rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
 619		}
 620	} else {
 621		rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
 622	}
 623}
 624
 625static void hal_ReadEFuse_WiFi(
 626	struct adapter *padapter,
 627	u16 _offset,
 628	u16 _size_byte,
 629	u8 *pbuf
 630)
 631{
 632	u8 *efuseTbl = NULL;
 633	u16 eFuse_Addr = 0;
 634	u8 offset, wden;
 635	u8 efuseHeader, efuseExtHdr, efuseData;
 636	u16 i, total, used;
 637	u8 efuse_usage = 0;
 638
 639	/*  */
 640	/*  Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
 641	/*  */
 642	if ((_offset + _size_byte) > EFUSE_MAX_MAP_LEN)
 643		return;
 644
 645	efuseTbl = rtw_malloc(EFUSE_MAX_MAP_LEN);
 646	if (!efuseTbl)
 647		return;
 648
 649	/*  0xff will be efuse default value instead of 0x00. */
 650	memset(efuseTbl, 0xFF, EFUSE_MAX_MAP_LEN);
 651
 652	/*  switch bank back to bank 0 for later BT and wifi use. */
 653	hal_EfuseSwitchToBank(padapter, 0);
 654
 655	while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
 656		efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader);
 657		if (efuseHeader == 0xFF)
 658			break;
 659
 660		/*  Check PG header for section num. */
 661		if (EXT_HEADER(efuseHeader)) { /* extended header */
 662			offset = GET_HDR_OFFSET_2_0(efuseHeader);
 663
 664			efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr);
 665			if (ALL_WORDS_DISABLED(efuseExtHdr))
 666				continue;
 667
 668			offset |= ((efuseExtHdr & 0xF0) >> 1);
 669			wden = (efuseExtHdr & 0x0F);
 670		} else {
 671			offset = ((efuseHeader >> 4) & 0x0f);
 672			wden = (efuseHeader & 0x0f);
 673		}
 674
 675		if (offset < EFUSE_MAX_SECTION_8723B) {
 676			u16 addr;
 677			/*  Get word enable value from PG header */
 678
 679			addr = offset * PGPKT_DATA_SIZE;
 680			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
 681				/*  Check word enable condition in the section */
 682				if (!(wden & (0x01<<i))) {
 683					efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData);
 684					efuseTbl[addr] = efuseData;
 685
 686					efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData);
 687					efuseTbl[addr+1] = efuseData;
 688				}
 689				addr += 2;
 690			}
 691		} else {
 692			eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
 693		}
 694	}
 695
 696	/*  Copy from Efuse map to output pointer memory!!! */
 697	for (i = 0; i < _size_byte; i++)
 698		pbuf[i] = efuseTbl[_offset+i];
 699
 700	/*  Calculate Efuse utilization */
 701	Hal_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
 702	used = eFuse_Addr - 1;
 703	efuse_usage = (u8)((used*100)/total);
 704
 705	rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&used);
 706	rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8 *)&efuse_usage);
 707
 708	kfree(efuseTbl);
 709}
 710
 711static void hal_ReadEFuse_BT(
 712	struct adapter *padapter,
 713	u16 _offset,
 714	u16 _size_byte,
 715	u8 *pbuf
 716)
 717{
 718	u8 *efuseTbl;
 719	u8 bank;
 720	u16 eFuse_Addr;
 721	u8 efuseHeader, efuseExtHdr, efuseData;
 722	u8 offset, wden;
 723	u16 i, total, used;
 724	u8 efuse_usage;
 725
 726
 727	/*  */
 728	/*  Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
 729	/*  */
 730	if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN)
 731		return;
 732
 733	efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);
 734	if (!efuseTbl)
 735		return;
 736
 737	/*  0xff will be efuse default value instead of 0x00. */
 738	memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
 739
 740	Hal_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total);
 741
 742	for (bank = 1; bank < 3; bank++) { /*  8723b Max bake 0~2 */
 743		if (hal_EfuseSwitchToBank(padapter, bank) == false)
 744			goto exit;
 745
 746		eFuse_Addr = 0;
 747
 748		while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
 749			efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader);
 750			if (efuseHeader == 0xFF)
 751				break;
 752
 753			/*  Check PG header for section num. */
 754			if (EXT_HEADER(efuseHeader)) { /* extended header */
 755				offset = GET_HDR_OFFSET_2_0(efuseHeader);
 756
 757				efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr);
 758				if (ALL_WORDS_DISABLED(efuseExtHdr))
 759					continue;
 760
 761
 762				offset |= ((efuseExtHdr & 0xF0) >> 1);
 763				wden = (efuseExtHdr & 0x0F);
 764			} else {
 765				offset = ((efuseHeader >> 4) & 0x0f);
 766				wden = (efuseHeader & 0x0f);
 767			}
 768
 769			if (offset < EFUSE_BT_MAX_SECTION) {
 770				u16 addr = offset * PGPKT_DATA_SIZE;
 771
 772				for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
 773					/*  Check word enable condition in the section */
 774					if (!(wden & (0x01<<i))) {
 775						efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData);
 776						efuseTbl[addr] = efuseData;
 777
 778						efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData);
 779						efuseTbl[addr+1] = efuseData;
 780					}
 781					addr += 2;
 782				}
 783			} else {
 784				eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
 785			}
 786		}
 787
 788		if ((eFuse_Addr - 1) < total)
 789			break;
 790
 791	}
 792
 793	/*  switch bank back to bank 0 for later BT and wifi use. */
 794	hal_EfuseSwitchToBank(padapter, 0);
 795
 796	/*  Copy from Efuse map to output pointer memory!!! */
 797	for (i = 0; i < _size_byte; i++)
 798		pbuf[i] = efuseTbl[_offset+i];
 799
 800	/*  */
 801	/*  Calculate Efuse utilization. */
 802	/*  */
 803	Hal_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
 804	used = (EFUSE_BT_REAL_BANK_CONTENT_LEN*(bank-1)) + eFuse_Addr - 1;
 805	efuse_usage = (u8)((used*100)/total);
 806
 807	rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&used);
 808	rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8 *)&efuse_usage);
 809
 810exit:
 811	kfree(efuseTbl);
 812}
 813
 814void Hal_ReadEFuse(
 815	struct adapter *padapter,
 816	u8 efuseType,
 817	u16 _offset,
 818	u16 _size_byte,
 819	u8 *pbuf
 820)
 821{
 822	if (efuseType == EFUSE_WIFI)
 823		hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf);
 824	else
 825		hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf);
 826}
 827
 828static struct hal_version ReadChipVersion8723B(struct adapter *padapter)
 829{
 830	u32 value32;
 831	struct hal_version ChipVersion;
 832	struct hal_com_data *pHalData;
 833
 834/* YJ, TODO, move read chip type here */
 835	pHalData = GET_HAL_DATA(padapter);
 836
 837	value32 = rtw_read32(padapter, REG_SYS_CFG);
 838	ChipVersion.ICType = CHIP_8723B;
 839	ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
 840	ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
 841	ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; /*  IC version (CUT) */
 842
 843	/*  For regulator mode. by tynli. 2011.01.14 */
 844	pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
 845
 846	value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
 847	ChipVersion.ROMVer = ((value32 & RF_RL_ID) >> 20);	/*  ROM code version. */
 848
 849	/*  For multi-function consideration. Added by Roger, 2010.10.06. */
 850	pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
 851	value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
 852	pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
 853	pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
 854	pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
 855	pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT);
 856
 857	dump_chip_info(ChipVersion);
 858
 859	pHalData->VersionID = ChipVersion;
 860
 861	return ChipVersion;
 862}
 863
 864void rtl8723b_read_chip_version(struct adapter *padapter)
 865{
 866	ReadChipVersion8723B(padapter);
 867}
 868
 869void rtl8723b_InitBeaconParameters(struct adapter *padapter)
 870{
 871	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
 872	u16 val16;
 873	u8 val8 = DIS_TSF_UDT;
 874
 875
 876	val16 = val8 | (val8 << 8); /*  port0 and port1 */
 877
 878	/*  Enable prot0 beacon function for PSTDMA */
 879	val16 |= EN_BCN_FUNCTION;
 880
 881	rtw_write16(padapter, REG_BCN_CTRL, val16);
 882
 883	/*  TODO: Remove these magic number */
 884	rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);/*  ms */
 885	/*  Firmware will control REG_DRVERLYINT when power saving is enable, */
 886	/*  so don't set this register on STA mode. */
 887	if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == false)
 888		rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8723B); /*  5ms */
 889	rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8723B); /*  2ms */
 890
 891	/*  Suggested by designer timchen. Change beacon AIFS to the largest number */
 892	/*  because test chip does not contension before sending beacon. by tynli. 2009.11.03 */
 893	rtw_write16(padapter, REG_BCNTCFG, 0x660F);
 894
 895	pHalData->RegBcnCtrlVal = rtw_read8(padapter, REG_BCN_CTRL);
 896	pHalData->RegTxPause = rtw_read8(padapter, REG_TXPAUSE);
 897	pHalData->RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL+2);
 898	pHalData->RegReg542 = rtw_read8(padapter, REG_TBTT_PROHIBIT+2);
 899	pHalData->RegCR_1 = rtw_read8(padapter, REG_CR+1);
 900}
 901
 902void _InitBurstPktLen_8723BS(struct adapter *Adapter)
 903{
 904	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
 905
 906	rtw_write8(Adapter, 0x4c7, rtw_read8(Adapter, 0x4c7)|BIT(7)); /* enable single pkt ampdu */
 907	rtw_write8(Adapter, REG_RX_PKT_LIMIT_8723B, 0x18);		/* for VHT packet length 11K */
 908	rtw_write8(Adapter, REG_MAX_AGGR_NUM_8723B, 0x1F);
 909	rtw_write8(Adapter, REG_PIFS_8723B, 0x00);
 910	rtw_write8(Adapter, REG_FWHW_TXQ_CTRL_8723B, rtw_read8(Adapter, REG_FWHW_TXQ_CTRL)&(~BIT(7)));
 911	if (pHalData->AMPDUBurstMode)
 912		rtw_write8(Adapter, REG_AMPDU_BURST_MODE_8723B,  0x5F);
 913	rtw_write8(Adapter, REG_AMPDU_MAX_TIME_8723B, 0x70);
 914
 915	/*  ARFB table 9 for 11ac 5G 2SS */
 916	rtw_write32(Adapter, REG_ARFR0_8723B, 0x00000010);
 917	if (IS_NORMAL_CHIP(pHalData->VersionID))
 918		rtw_write32(Adapter, REG_ARFR0_8723B+4, 0xfffff000);
 919	else
 920		rtw_write32(Adapter, REG_ARFR0_8723B+4, 0x3e0ff000);
 921
 922	/*  ARFB table 10 for 11ac 5G 1SS */
 923	rtw_write32(Adapter, REG_ARFR1_8723B, 0x00000010);
 924	rtw_write32(Adapter, REG_ARFR1_8723B+4, 0x003ff000);
 925}
 926
 927static void ResumeTxBeacon(struct adapter *padapter)
 928{
 929	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
 930
 931	pHalData->RegFwHwTxQCtrl |= BIT(6);
 932	rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
 933	rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0xff);
 934	pHalData->RegReg542 |= BIT(0);
 935	rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
 936}
 937
 938static void StopTxBeacon(struct adapter *padapter)
 939{
 940	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
 941
 942	pHalData->RegFwHwTxQCtrl &= ~BIT(6);
 943	rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
 944	rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64);
 945	pHalData->RegReg542 &= ~BIT(0);
 946	rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
 947}
 948
 949static void _BeaconFunctionEnable(struct adapter *padapter, u8 Enable, u8 Linked)
 950{
 951	rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
 952	rtw_write8(padapter, REG_RD_CTRL+1, 0x6F);
 953}
 954
 955void rtl8723b_SetBeaconRelatedRegisters(struct adapter *padapter)
 956{
 957	u8 val8;
 958	u32 value32;
 959	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 960	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 961	u32 bcn_ctrl_reg;
 962
 963	/* reset TSF, enable update TSF, correcting TSF On Beacon */
 964
 965	/* REG_BCN_INTERVAL */
 966	/* REG_BCNDMATIM */
 967	/* REG_ATIMWND */
 968	/* REG_TBTT_PROHIBIT */
 969	/* REG_DRVERLYINT */
 970	/* REG_BCN_MAX_ERR */
 971	/* REG_BCNTCFG (0x510) */
 972	/* REG_DUAL_TSF_RST */
 973	/* REG_BCN_CTRL (0x550) */
 974
 975
 976	bcn_ctrl_reg = REG_BCN_CTRL;
 977
 978	/*  */
 979	/*  ATIM window */
 980	/*  */
 981	rtw_write16(padapter, REG_ATIMWND, 2);
 982
 983	/*  */
 984	/*  Beacon interval (in unit of TU). */
 985	/*  */
 986	rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
 987
 988	rtl8723b_InitBeaconParameters(padapter);
 989
 990	rtw_write8(padapter, REG_SLOT, 0x09);
 991
 992	/*  */
 993	/*  Reset TSF Timer to zero, added by Roger. 2008.06.24 */
 994	/*  */
 995	value32 = rtw_read32(padapter, REG_TCR);
 996	value32 &= ~TSFRST;
 997	rtw_write32(padapter, REG_TCR, value32);
 998
 999	value32 |= TSFRST;
1000	rtw_write32(padapter, REG_TCR, value32);
1001
1002	/*  NOTE: Fix test chip's bug (about contention windows's randomness) */
1003	if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == true) {
1004		rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
1005		rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
1006	}
1007
1008	_BeaconFunctionEnable(padapter, true, true);
1009
1010	ResumeTxBeacon(padapter);
1011	val8 = rtw_read8(padapter, bcn_ctrl_reg);
1012	val8 |= DIS_BCNQ_SUB;
1013	rtw_write8(padapter, bcn_ctrl_reg, val8);
1014}
1015
1016void hal_notch_filter_8723b(struct adapter *adapter, bool enable)
1017{
1018	if (enable)
1019		rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
1020	else
1021		rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
1022}
1023
1024void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_level)
1025{
1026	u32 mask, rate_bitmap;
1027	u8 shortGIrate = false;
1028	struct sta_info *psta;
1029	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
1030	struct dm_priv *pdmpriv = &pHalData->dmpriv;
1031	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1032	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1033
1034	if (mac_id >= NUM_STA) /* CAM_SIZE */
1035		return;
1036
1037	psta = pmlmeinfo->FW_sta_info[mac_id].psta;
1038	if (!psta)
1039		return;
1040
1041	shortGIrate = query_ra_short_GI(psta);
1042
1043	mask = psta->ra_mask;
1044
1045	rate_bitmap = 0xffffffff;
1046	rate_bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv, mac_id, mask, rssi_level);
1047
1048	mask &= rate_bitmap;
1049
1050	rate_bitmap = hal_btcoex_GetRaMask(padapter);
1051	mask &= ~rate_bitmap;
1052
1053	if (pHalData->fw_ractrl) {
1054		rtl8723b_set_FwMacIdConfig_cmd(padapter, mac_id, psta->raid, psta->bw_mode, shortGIrate, mask);
1055	}
1056
1057	/* set correct initial date rate for each mac_id */
1058	pdmpriv->INIDATA_RATE[mac_id] = psta->init_rate;
1059}
1060
1061void rtl8723b_InitAntenna_Selection(struct adapter *padapter)
1062{
1063	u8 val;
1064
1065	val = rtw_read8(padapter, REG_LEDCFG2);
1066	/*  Let 8051 take control antenna setting */
1067	val |= BIT(7); /*  DPDT_SEL_EN, 0x4C[23] */
1068	rtw_write8(padapter, REG_LEDCFG2, val);
1069}
1070
1071void rtl8723b_init_default_value(struct adapter *padapter)
1072{
1073	struct hal_com_data *pHalData;
1074	struct dm_priv *pdmpriv;
1075	u8 i;
1076
1077
1078	pHalData = GET_HAL_DATA(padapter);
1079	pdmpriv = &pHalData->dmpriv;
1080
1081	padapter->registrypriv.wireless_mode = WIRELESS_11BG_24N;
1082
1083	/*  init default value */
1084	pHalData->fw_ractrl = false;
1085	pHalData->bIQKInitialized = false;
1086	if (!adapter_to_pwrctl(padapter)->bkeepfwalive)
1087		pHalData->LastHMEBoxNum = 0;
1088
1089	pHalData->bIQKInitialized = false;
1090
1091	/*  init dm default value */
1092	pdmpriv->TM_Trigger = 0;/* for IQK */
1093/* 	pdmpriv->binitialized = false; */
1094/* 	pdmpriv->prv_traffic_idx = 3; */
1095/* 	pdmpriv->initialize = 0; */
1096
1097	pdmpriv->ThermalValue_HP_index = 0;
1098	for (i = 0; i < HP_THERMAL_NUM; i++)
1099		pdmpriv->ThermalValue_HP[i] = 0;
1100
1101	/*  init Efuse variables */
1102	pHalData->EfuseUsedBytes = 0;
1103	pHalData->EfuseUsedPercentage = 0;
1104#ifdef HAL_EFUSE_MEMORY
1105	pHalData->EfuseHal.fakeEfuseBank = 0;
1106	pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
1107	memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
1108	memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
1109	memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
1110	pHalData->EfuseHal.BTEfuseUsedBytes = 0;
1111	pHalData->EfuseHal.BTEfuseUsedPercentage = 0;
1112	memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
1113	memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
1114	memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
1115	pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0;
1116	memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
1117	memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
1118	memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
1119#endif
1120}
1121
1122u8 GetEEPROMSize8723B(struct adapter *padapter)
1123{
1124	u8 size = 0;
1125	u32 cr;
1126
1127	cr = rtw_read16(padapter, REG_9346CR);
1128	/*  6: EEPROM used is 93C46, 4: boot from E-Fuse. */
1129	size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
1130
1131	return size;
1132}
1133
1134/*  */
1135/*  */
1136/*  LLT R/W/Init function */
1137/*  */
1138/*  */
1139s32 rtl8723b_InitLLTTable(struct adapter *padapter)
1140{
1141	unsigned long start, passing_time;
1142	u32 val32;
1143	s32 ret = _FAIL;
1144
1145	val32 = rtw_read32(padapter, REG_AUTO_LLT);
1146	val32 |= BIT_AUTO_INIT_LLT;
1147	rtw_write32(padapter, REG_AUTO_LLT, val32);
1148
1149	start = jiffies;
1150
1151	do {
1152		val32 = rtw_read32(padapter, REG_AUTO_LLT);
1153		if (!(val32 & BIT_AUTO_INIT_LLT)) {
1154			ret = _SUCCESS;
1155			break;
1156		}
1157
1158		passing_time = jiffies_to_msecs(jiffies - start);
1159		if (passing_time > 1000)
1160			break;
1161
1162		msleep(1);
1163	} while (1);
1164
1165	return ret;
1166}
1167
1168static void hal_get_chnl_group_8723b(u8 channel, u8 *group)
1169{
1170	if (1  <= channel && channel <= 2)
1171		*group = 0;
1172	else if (3  <= channel && channel <= 5)
1173		*group = 1;
1174	else if (6  <= channel && channel <= 8)
1175		*group = 2;
1176	else if (9  <= channel && channel <= 11)
1177		*group = 3;
1178	else if (12 <= channel && channel <= 14)
1179		*group = 4;
1180}
1181
1182void Hal_InitPGData(struct adapter *padapter, u8 *PROMContent)
1183{
1184	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1185
1186	if (!pEEPROM->bautoload_fail_flag) { /*  autoload OK. */
1187		if (!pEEPROM->EepromOrEfuse) {
1188			/*  Read EFUSE real map to shadow. */
1189			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI);
1190			memcpy((void *)PROMContent, (void *)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE_8723B);
1191		}
1192	} else {/* autoload fail */
1193		if (!pEEPROM->EepromOrEfuse)
1194			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI);
1195		memcpy((void *)PROMContent, (void *)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE_8723B);
1196	}
1197}
1198
1199void Hal_EfuseParseIDCode(struct adapter *padapter, u8 *hwinfo)
1200{
1201	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1202/* 	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter); */
1203	u16 EEPROMId;
1204
1205
1206	/*  Check 0x8129 again for making sure autoload status!! */
1207	EEPROMId = le16_to_cpu(*((__le16 *)hwinfo));
1208	if (EEPROMId != RTL_EEPROM_ID) {
1209		pEEPROM->bautoload_fail_flag = true;
1210	} else
1211		pEEPROM->bautoload_fail_flag = false;
1212}
1213
1214static void Hal_ReadPowerValueFromPROM_8723B(
1215	struct adapter *Adapter,
1216	struct TxPowerInfo24G *pwrInfo24G,
1217	u8 *PROMContent,
1218	bool AutoLoadFail
1219)
1220{
1221	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
1222	u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_8723B, group, TxCount = 0;
1223
1224	memset(pwrInfo24G, 0, sizeof(struct TxPowerInfo24G));
1225
1226	if (0xFF == PROMContent[eeAddr+1])
1227		AutoLoadFail = true;
1228
1229	if (AutoLoadFail) {
1230		for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) {
1231			/* 2.4G default value */
1232			for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1233				pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
1234				pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
1235			}
1236
1237			for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
1238				if (TxCount == 0) {
1239					pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF;
1240					pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF;
1241				} else {
1242					pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1243					pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1244					pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1245					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1246				}
1247			}
1248		}
1249
1250		return;
1251	}
1252
1253	pHalData->bTXPowerDataReadFromEEPORM = true;		/* YJ, move, 120316 */
1254
1255	for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) {
1256		/* 2 2.4G default value */
1257		for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1258			pwrInfo24G->IndexCCK_Base[rfPath][group] =	PROMContent[eeAddr++];
1259			if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
1260				pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
1261		}
1262
1263		for (group = 0; group < MAX_CHNL_GROUP_24G-1; group++) {
1264			pwrInfo24G->IndexBW40_Base[rfPath][group] =	PROMContent[eeAddr++];
1265			if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
1266				pwrInfo24G->IndexBW40_Base[rfPath][group] =	EEPROM_DEFAULT_24G_INDEX;
1267		}
1268
1269		for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
1270			if (TxCount == 0) {
1271				pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
1272				if (PROMContent[eeAddr] == 0xFF)
1273					pwrInfo24G->BW20_Diff[rfPath][TxCount] =	EEPROM_DEFAULT_24G_HT20_DIFF;
1274				else {
1275					pwrInfo24G->BW20_Diff[rfPath][TxCount] =	(PROMContent[eeAddr]&0xf0)>>4;
1276					if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
1277						pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
1278				}
1279
1280				if (PROMContent[eeAddr] == 0xFF)
1281					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_OFDM_DIFF;
1282				else {
1283					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
1284					if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
1285						pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
1286				}
1287				pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
1288				eeAddr++;
1289			} else {
1290				if (PROMContent[eeAddr] == 0xFF)
1291					pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1292				else {
1293					pwrInfo24G->BW40_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
1294					if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
1295						pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
1296				}
1297
1298				if (PROMContent[eeAddr] == 0xFF)
1299					pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1300				else {
1301					pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
1302					if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
1303						pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
1304				}
1305				eeAddr++;
1306
1307				if (PROMContent[eeAddr] == 0xFF)
1308					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1309				else {
1310					pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
1311					if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
1312						pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
1313				}
1314
1315				if (PROMContent[eeAddr] == 0xFF)
1316					pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1317				else {
1318					pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
1319					if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT3)		/* 4bit sign number to 8 bit sign number */
1320						pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
1321				}
1322				eeAddr++;
1323			}
1324		}
1325	}
1326}
1327
1328
1329void Hal_EfuseParseTxPowerInfo_8723B(
1330	struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail
1331)
1332{
1333	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
1334	struct TxPowerInfo24G	pwrInfo24G;
1335	u8 	rfPath, ch, TxCount = 1;
1336
1337	Hal_ReadPowerValueFromPROM_8723B(padapter, &pwrInfo24G, PROMContent, AutoLoadFail);
1338	for (rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++) {
1339		for (ch = 0 ; ch < CHANNEL_MAX_NUMBER; ch++) {
1340			u8 group = 0;
1341
1342			hal_get_chnl_group_8723b(ch + 1, &group);
1343
1344			if (ch == 14-1) {
1345				pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][5];
1346				pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
1347			} else {
1348				pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group];
1349				pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
1350			}
1351		}
1352
1353		for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
1354			pHalData->CCK_24G_Diff[rfPath][TxCount] = pwrInfo24G.CCK_Diff[rfPath][TxCount];
1355			pHalData->OFDM_24G_Diff[rfPath][TxCount] = pwrInfo24G.OFDM_Diff[rfPath][TxCount];
1356			pHalData->BW20_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW20_Diff[rfPath][TxCount];
1357			pHalData->BW40_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW40_Diff[rfPath][TxCount];
1358		}
1359	}
1360
1361	/*  2010/10/19 MH Add Regulator recognize for CU. */
1362	if (!AutoLoadFail) {
1363		pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_8723B]&0x7);	/* bit0~2 */
1364		if (PROMContent[EEPROM_RF_BOARD_OPTION_8723B] == 0xFF)
1365			pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION&0x7);	/* bit0~2 */
1366	} else
1367		pHalData->EEPROMRegulatory = 0;
1368}
1369
1370void Hal_EfuseParseBTCoexistInfo_8723B(
1371	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
1372)
1373{
1374	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1375	u8 tempval;
1376	u32 tmpu4;
1377
1378	if (!AutoLoadFail) {
1379		tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
1380		if (tmpu4 & BT_FUNC_EN)
1381			pHalData->EEPROMBluetoothCoexist = true;
1382		else
1383			pHalData->EEPROMBluetoothCoexist = false;
1384
1385		pHalData->EEPROMBluetoothType = BT_RTL8723B;
1386
1387		tempval = hwinfo[EEPROM_RF_BT_SETTING_8723B];
1388		if (tempval != 0xFF) {
1389			pHalData->EEPROMBluetoothAntNum = tempval & BIT(0);
1390			/*  EFUSE_0xC3[6] == 0, S1(Main)-RF_PATH_A; */
1391			/*  EFUSE_0xC3[6] == 1, S0(Aux)-RF_PATH_B */
1392			if (tempval & BIT(6))
1393				pHalData->ant_path = RF_PATH_B;
1394			else
1395				pHalData->ant_path = RF_PATH_A;
1396		} else {
1397			pHalData->EEPROMBluetoothAntNum = Ant_x1;
1398			if (pHalData->PackageType == PACKAGE_QFN68)
1399				pHalData->ant_path = RF_PATH_B;
1400			else
1401				pHalData->ant_path = RF_PATH_A;
1402		}
1403	} else {
1404		pHalData->EEPROMBluetoothCoexist = false;
1405		pHalData->EEPROMBluetoothType = BT_RTL8723B;
1406		pHalData->EEPROMBluetoothAntNum = Ant_x1;
1407		pHalData->ant_path = RF_PATH_A;
1408	}
1409
1410	if (padapter->registrypriv.ant_num > 0) {
1411		switch (padapter->registrypriv.ant_num) {
1412		case 1:
1413			pHalData->EEPROMBluetoothAntNum = Ant_x1;
1414			break;
1415		case 2:
1416			pHalData->EEPROMBluetoothAntNum = Ant_x2;
1417			break;
1418		default:
1419			break;
1420		}
1421	}
1422
1423	hal_btcoex_SetBTCoexist(padapter, pHalData->EEPROMBluetoothCoexist);
1424	hal_btcoex_SetPgAntNum(padapter, pHalData->EEPROMBluetoothAntNum == Ant_x2 ? 2 : 1);
1425	if (pHalData->EEPROMBluetoothAntNum == Ant_x1)
1426		hal_btcoex_SetSingleAntPath(padapter, pHalData->ant_path);
1427}
1428
1429void Hal_EfuseParseEEPROMVer_8723B(
1430	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
1431)
1432{
1433	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
1434
1435	if (!AutoLoadFail)
1436		pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723B];
1437	else
1438		pHalData->EEPROMVersion = 1;
1439}
1440
1441
1442
1443void Hal_EfuseParsePackageType_8723B(
1444	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
1445)
1446{
1447	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1448	u8 package;
1449	u8 efuseContent;
1450
1451	Hal_EfusePowerSwitch(padapter, true);
1452	efuse_OneByteRead(padapter, 0x1FB, &efuseContent);
1453	Hal_EfusePowerSwitch(padapter, false);
1454
1455	package = efuseContent & 0x7;
1456	switch (package) {
1457	case 0x4:
1458		pHalData->PackageType = PACKAGE_TFBGA79;
1459		break;
1460	case 0x5:
1461		pHalData->PackageType = PACKAGE_TFBGA90;
1462		break;
1463	case 0x6:
1464		pHalData->PackageType = PACKAGE_QFN68;
1465		break;
1466	case 0x7:
1467		pHalData->PackageType = PACKAGE_TFBGA80;
1468		break;
1469
1470	default:
1471		pHalData->PackageType = PACKAGE_DEFAULT;
1472		break;
1473	}
1474}
1475
1476
1477void Hal_EfuseParseVoltage_8723B(
1478	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
1479)
1480{
1481	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1482
1483	/* memcpy(pEEPROM->adjuseVoltageVal, &hwinfo[EEPROM_Voltage_ADDR_8723B], 1); */
1484	pEEPROM->adjuseVoltageVal = (hwinfo[EEPROM_Voltage_ADDR_8723B] & 0xf0) >> 4;
1485}
1486
1487void Hal_EfuseParseChnlPlan_8723B(
1488	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
1489)
1490{
1491	padapter->mlmepriv.ChannelPlan = hal_com_config_channel_plan(
1492		padapter,
1493		hwinfo ? hwinfo[EEPROM_ChannelPlan_8723B] : 0xFF,
1494		padapter->registrypriv.channel_plan,
1495		RT_CHANNEL_DOMAIN_WORLD_NULL,
1496		AutoLoadFail
1497	);
1498
1499	Hal_ChannelPlanToRegulation(padapter, padapter->mlmepriv.ChannelPlan);
1500}
1501
1502void Hal_EfuseParseCustomerID_8723B(
1503	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
1504)
1505{
1506	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
1507
1508	if (!AutoLoadFail)
1509		pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723B];
1510	else
1511		pHalData->EEPROMCustomerID = 0;
1512}
1513
1514void Hal_EfuseParseXtal_8723B(
1515	struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
1516)
1517{
1518	struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
1519
1520	if (!AutoLoadFail) {
1521		pHalData->CrystalCap = hwinfo[EEPROM_XTAL_8723B];
1522		if (pHalData->CrystalCap == 0xFF)
1523			pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723B;	   /* what value should 8812 set? */
1524	} else
1525		pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723B;
1526}
1527
1528
1529void Hal_EfuseParseThermalMeter_8723B(
1530	struct adapter *padapter, u8 *PROMContent, u8 AutoLoadFail
1531)
1532{
1533	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1534
1535	/*  */
1536	/*  ThermalMeter from EEPROM */
1537	/*  */
1538	if (!AutoLoadFail)
1539		pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8723B];
1540	else
1541		pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8723B;
1542
1543	if ((pHalData->EEPROMThermalMeter == 0xff) || AutoLoadFail) {
1544		pHalData->bAPKThermalMeterIgnore = true;
1545		pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8723B;
1546	}
1547}
1548
1549
1550void Hal_ReadRFGainOffset(
1551	struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail
1552)
1553{
1554	/*  */
1555	/*  BB_RF Gain Offset from EEPROM */
1556	/*  */
1557
1558	if (!AutoloadFail) {
1559		Adapter->eeprompriv.EEPROMRFGainOffset = PROMContent[EEPROM_RF_GAIN_OFFSET];
1560		Adapter->eeprompriv.EEPROMRFGainVal = EFUSE_Read1Byte(Adapter, EEPROM_RF_GAIN_VAL);
1561	} else {
1562		Adapter->eeprompriv.EEPROMRFGainOffset = 0;
1563		Adapter->eeprompriv.EEPROMRFGainVal = 0xFF;
1564	}
1565}
1566
1567u8 BWMapping_8723B(struct adapter *Adapter, struct pkt_attrib *pattrib)
1568{
1569	u8 BWSettingOfDesc = 0;
1570	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
1571
1572	if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) {
1573		if (pattrib->bwmode == CHANNEL_WIDTH_40)
1574			BWSettingOfDesc = 1;
1575		else
1576			BWSettingOfDesc = 0;
1577	} else
1578		BWSettingOfDesc = 0;
1579
1580	/* if (pTcb->bBTTxPacket) */
1581	/* 	BWSettingOfDesc = 0; */
1582
1583	return BWSettingOfDesc;
1584}
1585
1586u8 SCMapping_8723B(struct adapter *Adapter, struct pkt_attrib *pattrib)
1587{
1588	u8 SCSettingOfDesc = 0;
1589	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
1590
1591	if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) {
1592		if (pattrib->bwmode == CHANNEL_WIDTH_40) {
1593			SCSettingOfDesc = HT_DATA_SC_DONOT_CARE;
1594		} else if (pattrib->bwmode == CHANNEL_WIDTH_20) {
1595			if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) {
1596				SCSettingOfDesc = HT_DATA_SC_20_UPPER_OF_40MHZ;
1597			} else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) {
1598				SCSettingOfDesc = HT_DATA_SC_20_LOWER_OF_40MHZ;
1599			} else {
1600				SCSettingOfDesc = HT_DATA_SC_DONOT_CARE;
1601			}
1602		}
1603	} else {
1604		SCSettingOfDesc = HT_DATA_SC_DONOT_CARE;
1605	}
1606
1607	return SCSettingOfDesc;
1608}
1609
1610static void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc)
1611{
1612	u16 *usPtr = (u16 *)ptxdesc;
1613	u32 count;
1614	u32 index;
1615	u16 checksum = 0;
1616
1617
1618	/*  Clear first */
1619	ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
1620
1621	/*  checksum is always calculated by first 32 bytes, */
1622	/*  and it doesn't depend on TX DESC length. */
1623	/*  Thomas, Lucas@SD4, 20130515 */
1624	count = 16;
1625
1626	for (index = 0; index < count; index++) {
1627		checksum |= le16_to_cpu(*(__le16 *)(usPtr + index));
1628	}
1629
1630	ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
1631}
1632
1633static u8 fill_txdesc_sectype(struct pkt_attrib *pattrib)
1634{
1635	u8 sectype = 0;
1636	if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
1637		switch (pattrib->encrypt) {
1638		/*  SEC_TYPE */
1639		case _WEP40_:
1640		case _WEP104_:
1641		case _TKIP_:
1642		case _TKIP_WTMIC_:
1643			sectype = 1;
1644			break;
1645
1646		case _AES_:
1647			sectype = 3;
1648			break;
1649
1650		case _NO_PRIVACY_:
1651		default:
1652			break;
1653		}
1654	}
1655	return sectype;
1656}
1657
1658static void fill_txdesc_vcs_8723b(struct adapter *padapter, struct pkt_attrib *pattrib, struct txdesc_8723b *ptxdesc)
1659{
1660	if (pattrib->vcs_mode) {
1661		switch (pattrib->vcs_mode) {
1662		case RTS_CTS:
1663			ptxdesc->rtsen = 1;
1664			/*  ENABLE HW RTS */
1665			ptxdesc->hw_rts_en = 1;
1666			break;
1667
1668		case CTS_TO_SELF:
1669			ptxdesc->cts2self = 1;
1670			break;
1671
1672		case NONE_VCS:
1673		default:
1674			break;
1675		}
1676
1677		ptxdesc->rtsrate = 8; /*  RTS Rate =24M */
1678		ptxdesc->rts_ratefb_lmt = 0xF;
1679
1680		if (padapter->mlmeextpriv.mlmext_info.preamble_mode == PREAMBLE_SHORT)
1681			ptxdesc->rts_short = 1;
1682
1683		/*  Set RTS BW */
1684		if (pattrib->ht_en)
1685			ptxdesc->rts_sc = SCMapping_8723B(padapter, pattrib);
1686	}
1687}
1688
1689static void fill_txdesc_phy_8723b(struct adapter *padapter, struct pkt_attrib *pattrib, struct txdesc_8723b *ptxdesc)
1690{
1691	if (pattrib->ht_en) {
1692		ptxdesc->data_bw = BWMapping_8723B(padapter, pattrib);
1693
1694		ptxdesc->data_sc = SCMapping_8723B(padapter, pattrib);
1695	}
1696}
1697
1698static void rtl8723b_fill_default_txdesc(
1699	struct xmit_frame *pxmitframe, u8 *pbuf
1700)
1701{
1702	struct adapter *padapter;
1703	struct hal_com_data *pHalData;
1704	struct mlme_ext_priv *pmlmeext;
1705	struct mlme_ext_info *pmlmeinfo;
1706	struct pkt_attrib *pattrib;
1707	struct txdesc_8723b *ptxdesc;
1708	s32 bmcst;
1709
1710	memset(pbuf, 0, TXDESC_SIZE);
1711
1712	padapter = pxmitframe->padapter;
1713	pHalData = GET_HAL_DATA(padapter);
1714	pmlmeext = &padapter->mlmeextpriv;
1715	pmlmeinfo = &(pmlmeext->mlmext_info);
1716
1717	pattrib = &pxmitframe->attrib;
1718	bmcst = is_multicast_ether_addr(pattrib->ra);
1719
1720	ptxdesc = (struct txdesc_8723b *)pbuf;
1721
1722	if (pxmitframe->frame_tag == DATA_FRAMETAG) {
1723		u8 drv_userate = 0;
1724
1725		ptxdesc->macid = pattrib->mac_id; /*  CAM_ID(MAC_ID) */
1726		ptxdesc->rate_id = pattrib->raid;
1727		ptxdesc->qsel = pattrib->qsel;
1728		ptxdesc->seq = pattrib->seqnum;
1729
1730		ptxdesc->sectype = fill_txdesc_sectype(pattrib);
1731		fill_txdesc_vcs_8723b(padapter, pattrib, ptxdesc);
1732
1733		if (pattrib->icmp_pkt == 1 && padapter->registrypriv.wifi_spec == 1)
1734			drv_userate = 1;
1735
1736		if (
1737			(pattrib->ether_type != 0x888e) &&
1738			(pattrib->ether_type != 0x0806) &&
1739			(pattrib->ether_type != 0x88B4) &&
1740			(pattrib->dhcp_pkt != 1) &&
1741			(drv_userate != 1)
1742		) {
1743			/*  Non EAP & ARP & DHCP type data packet */
1744
1745			if (pattrib->ampdu_en) {
1746				ptxdesc->agg_en = 1; /*  AGG EN */
1747				ptxdesc->max_agg_num = 0x1f;
1748				ptxdesc->ampdu_density = pattrib->ampdu_spacing;
1749			} else
1750				ptxdesc->bk = 1; /*  AGG BK */
1751
1752			fill_txdesc_phy_8723b(padapter, pattrib, ptxdesc);
1753
1754			ptxdesc->data_ratefb_lmt = 0x1F;
1755
1756			if (!pHalData->fw_ractrl) {
1757				ptxdesc->userate = 1;
1758
1759				if (pHalData->dmpriv.INIDATA_RATE[pattrib->mac_id] & BIT(7))
1760					ptxdesc->data_short = 1;
1761
1762				ptxdesc->datarate = pHalData->dmpriv.INIDATA_RATE[pattrib->mac_id] & 0x7F;
1763			}
1764
1765			if (padapter->fix_rate != 0xFF) { /*  modify data rate by iwpriv */
1766				ptxdesc->userate = 1;
1767				if (padapter->fix_rate & BIT(7))
1768					ptxdesc->data_short = 1;
1769
1770				ptxdesc->datarate = (padapter->fix_rate & 0x7F);
1771				ptxdesc->disdatafb = 1;
1772			}
1773
1774			if (pattrib->ldpc)
1775				ptxdesc->data_ldpc = 1;
1776			if (pattrib->stbc)
1777				ptxdesc->data_stbc = 1;
1778		} else {
1779			/*  EAP data packet and ARP packet. */
1780			/*  Use the 1M data rate to send the EAP/ARP packet. */
1781			/*  This will maybe make the handshake smooth. */
1782
1783			ptxdesc->bk = 1; /*  AGG BK */
1784			ptxdesc->userate = 1; /*  driver uses rate */
1785			if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
1786				ptxdesc->data_short = 1;/*  DATA_SHORT */
1787			ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
1788		}
1789
1790		ptxdesc->usb_txagg_num = pxmitframe->agg_num;
1791	} else if (pxmitframe->frame_tag == MGNT_FRAMETAG) {
1792		ptxdesc->macid = pattrib->mac_id; /*  CAM_ID(MAC_ID) */
1793		ptxdesc->qsel = pattrib->qsel;
1794		ptxdesc->rate_id = pattrib->raid; /*  Rate ID */
1795		ptxdesc->seq = pattrib->seqnum;
1796		ptxdesc->userate = 1; /*  driver uses rate, 1M */
1797
1798		ptxdesc->mbssid = pattrib->mbssid & 0xF;
1799
1800		ptxdesc->rty_lmt_en = 1; /*  retry limit enable */
1801		if (pattrib->retry_ctrl) {
1802			ptxdesc->data_rt_lmt = 6;
1803		} else {
1804			ptxdesc->data_rt_lmt = 12;
1805		}
1806
1807		ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
1808
1809		/*  CCX-TXRPT ack for xmit mgmt frames. */
1810		if (pxmitframe->ack_report) {
1811			ptxdesc->spe_rpt = 1;
1812			ptxdesc->sw_define = (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no);
1813		}
1814	} else {
1815		ptxdesc->macid = pattrib->mac_id; /*  CAM_ID(MAC_ID) */
1816		ptxdesc->rate_id = pattrib->raid; /*  Rate ID */
1817		ptxdesc->qsel = pattrib->qsel;
1818		ptxdesc->seq = pattrib->seqnum;
1819		ptxdesc->userate = 1; /*  driver uses rate */
1820		ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
1821	}
1822
1823	ptxdesc->pktlen = pattrib->last_txcmdsz;
1824	ptxdesc->offset = TXDESC_SIZE + OFFSET_SZ;
1825
1826	if (bmcst)
1827		ptxdesc->bmc = 1;
1828
1829	/* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
1830	 * (1) The sequence number of each non-Qos frame / broadcast /
1831	 * multicast / mgnt frame should be controlled by Hw because Fw
1832	 * will also send null data which we cannot control when Fw LPS
1833	 * enable.
1834	 * --> default enable non-Qos data sequence number. 2010.06.23.
1835	 * by tynli.
1836	 * (2) Enable HW SEQ control for beacon packet, because we use
1837	 * Hw beacon.
1838	 * (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos
1839	 * packets.
1840	 * 2010.06.23. Added by tynli.
1841	 */
1842	if (!pattrib->qos_en) /*  Hw set sequence number */
1843		ptxdesc->en_hwseq = 1; /*  HWSEQ_EN */
1844}
1845
1846/* Description:
1847 *
1848 * Parameters:
1849 *	pxmitframe	xmitframe
1850 *	pbuf		where to fill tx desc
1851 */
1852void rtl8723b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
1853{
1854	struct tx_desc *pdesc;
1855
1856	rtl8723b_fill_default_txdesc(pxmitframe, pbuf);
1857	pdesc = (struct tx_desc *)pbuf;
1858	rtl8723b_cal_txdesc_chksum(pdesc);
1859}
1860
1861/*  */
1862/*  Description: In normal chip, we should send some packet to Hw which will be used by Fw */
1863/* 			in FW LPS mode. The function is to fill the Tx descriptor of this packets, then */
1864/* 			Fw can tell Hw to send these packet derectly. */
1865/*  Added by tynli. 2009.10.15. */
1866/*  */
1867/* type1:pspoll, type2:null */
1868void rtl8723b_fill_fake_txdesc(
1869	struct adapter *padapter,
1870	u8 *pDesc,
1871	u32 BufferLen,
1872	u8 IsPsPoll,
1873	u8 IsBTQosNull,
1874	u8 bDataFrame
1875)
1876{
1877	/*  Clear all status */
1878	memset(pDesc, 0, TXDESC_SIZE);
1879
1880	SET_TX_DESC_FIRST_SEG_8723B(pDesc, 1); /* bFirstSeg; */
1881	SET_TX_DESC_LAST_SEG_8723B(pDesc, 1); /* bLastSeg; */
1882
1883	SET_TX_DESC_OFFSET_8723B(pDesc, 0x28); /*  Offset = 32 */
1884
1885	SET_TX_DESC_PKT_SIZE_8723B(pDesc, BufferLen); /*  Buffer size + command header */
1886	SET_TX_DESC_QUEUE_SEL_8723B(pDesc, QSLT_MGNT); /*  Fixed queue of Mgnt queue */
1887
1888	/*  Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error value by Hw. */
1889	if (IsPsPoll) {
1890		SET_TX_DESC_NAV_USE_HDR_8723B(pDesc, 1);
1891	} else {
1892		SET_TX_DESC_HWSEQ_EN_8723B(pDesc, 1); /*  Hw set sequence number */
1893		SET_TX_DESC_HWSEQ_SEL_8723B(pDesc, 0);
1894	}
1895
1896	if (IsBTQosNull) {
1897		SET_TX_DESC_BT_INT_8723B(pDesc, 1);
1898	}
1899
1900	SET_TX_DESC_USE_RATE_8723B(pDesc, 1); /*  use data rate which is set by Sw */
1901	SET_TX_DESC_OWN_8723B((u8 *)pDesc, 1);
1902
1903	SET_TX_DESC_TX_RATE_8723B(pDesc, DESC8723B_RATE1M);
1904
1905	/*  */
1906	/*  Encrypt the data frame if under security mode excepct null data. Suggested by CCW. */
1907	/*  */
1908	if (bDataFrame) {
1909		u32 EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
1910
1911		switch (EncAlg) {
1912		case _NO_PRIVACY_:
1913			SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0);
1914			break;
1915		case _WEP40_:
1916		case _WEP104_:
1917		case _TKIP_:
1918			SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x1);
1919			break;
1920		case _SMS4_:
1921			SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x2);
1922			break;
1923		case _AES_:
1924			SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x3);
1925			break;
1926		default:
1927			SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0);
1928			break;
1929		}
1930	}
1931
1932	/*  USB interface drop packet if the checksum of descriptor isn't correct. */
1933	/*  Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). */
1934	rtl8723b_cal_txdesc_chksum((struct tx_desc *)pDesc);
1935}
1936
1937static void hw_var_set_opmode(struct adapter *padapter, u8 variable, u8 *val)
1938{
1939	u8 val8;
1940	u8 mode = *((u8 *)val);
1941
1942	{
1943		/*  disable Port0 TSF update */
1944		val8 = rtw_read8(padapter, REG_BCN_CTRL);
1945		val8 |= DIS_TSF_UDT;
1946		rtw_write8(padapter, REG_BCN_CTRL, val8);
1947
1948		/*  set net_type */
1949		Set_MSR(padapter, mode);
1950
1951		if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
1952			{
1953				StopTxBeacon(padapter);
1954			}
1955
1956			/*  disable atim wnd */
1957			rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_ATIM);
1958			/* rtw_write8(padapter, REG_BCN_CTRL, 0x18); */
1959		} else if (mode == _HW_STATE_ADHOC_) {
1960			ResumeTxBeacon(padapter);
1961			rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
1962		} else if (mode == _HW_STATE_AP_) {
1963
1964			ResumeTxBeacon(padapter);
1965
1966			rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|DIS_BCNQ_SUB);
1967
1968			/* Set RCR */
1969			rtw_write32(padapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0, reject ICV_ERR packet */
1970			/* enable to rx data frame */
1971			rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
1972			/* enable to rx ps-poll */
1973			rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
1974
1975			/* Beacon Control related register for first time */
1976			rtw_write8(padapter, REG_BCNDMATIM, 0x02); /*  2ms */
1977
1978			/* rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF); */
1979			rtw_write8(padapter, REG_ATIMWND, 0x0a); /*  10ms */
1980			rtw_write16(padapter, REG_BCNTCFG, 0x00);
1981			rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
1982			rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/*  +32767 (~32ms) */
1983
1984			/* reset TSF */
1985			rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
1986
1987			/* enable BCN0 Function for if1 */
1988			/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
1989			rtw_write8(padapter, REG_BCN_CTRL, (DIS_TSF_UDT|EN_BCN_FUNCTION|EN_TXBCN_RPT|DIS_BCNQ_SUB));
1990
1991			/* SW_BCN_SEL - Port0 */
1992			/* rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2) & ~BIT4); */
1993			rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
1994
1995			/*  select BCN on port 0 */
1996			rtw_write8(
1997				padapter,
1998				REG_CCK_CHECK_8723B,
1999				(rtw_read8(padapter, REG_CCK_CHECK_8723B)&~BIT_BCN_PORT_SEL)
2000			);
2001
2002			/*  dis BCN1 ATIM  WND if if2 is station */
2003			val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
2004			val8 |= DIS_ATIM;
2005			rtw_write8(padapter, REG_BCN_CTRL_1, val8);
2006		}
2007	}
2008}
2009
2010static void hw_var_set_macaddr(struct adapter *padapter, u8 variable, u8 *val)
2011{
2012	u8 idx = 0;
2013	u32 reg_macid = REG_MACID;
2014
2015	for (idx = 0 ; idx < 6; idx++)
2016		rtw_write8(GET_PRIMARY_ADAPTER(padapter), (reg_macid+idx), val[idx]);
2017}
2018
2019static void hw_var_set_bssid(struct adapter *padapter, u8 variable, u8 *val)
2020{
2021	u8 idx = 0;
2022	u32 reg_bssid = REG_BSSID;
2023
2024	for (idx = 0 ; idx < 6; idx++)
2025		rtw_write8(padapter, (reg_bssid+idx), val[idx]);
2026}
2027
2028static void hw_var_set_bcn_func(struct adapter *padapter, u8 variable, u8 *val)
2029{
2030	u32 bcn_ctrl_reg = REG_BCN_CTRL;
2031
2032	if (*(u8 *)val)
2033		rtw_write8(padapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
2034	else {
2035		u8 val8;
2036		val8 = rtw_read8(padapter, bcn_ctrl_reg);
2037		val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
2038
2039		/*  Always enable port0 beacon function for PSTDMA */
2040		if (REG_BCN_CTRL == bcn_ctrl_reg)
2041			val8 |= EN_BCN_FUNCTION;
2042
2043		rtw_write8(padapter, bcn_ctrl_reg, val8);
2044	}
2045}
2046
2047static void hw_var_set_correct_tsf(struct adapter *padapter, u8 variable, u8 *val)
2048{
2049	u8 val8;
2050	u64 tsf;
2051	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2052	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2053
2054	tsf = pmlmeext->TSFValue-do_div(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024))-1024; /* us */
2055
2056	if (
2057		((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
2058		((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
2059	)
2060		StopTxBeacon(padapter);
2061
2062	{
2063		/*  disable related TSF function */
2064		val8 = rtw_read8(padapter, REG_BCN_CTRL);
2065		val8 &= ~EN_BCN_FUNCTION;
2066		rtw_write8(padapter, REG_BCN_CTRL, val8);
2067
2068		rtw_write32(padapter, REG_TSFTR, tsf);
2069		rtw_write32(padapter, REG_TSFTR+4, tsf>>32);
2070
2071		/*  enable related TSF function */
2072		val8 = rtw_read8(padapter, REG_BCN_CTRL);
2073		val8 |= EN_BCN_FUNCTION;
2074		rtw_write8(padapter, REG_BCN_CTRL, val8);
2075	}
2076
2077	if (
2078		((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
2079		((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
2080	)
2081		ResumeTxBeacon(padapter);
2082}
2083
2084static void hw_var_set_mlme_disconnect(struct adapter *padapter, u8 variable, u8 *val)
2085{
2086	u8 val8;
2087
2088	/*  Set RCR to not to receive data frame when NO LINK state */
2089	/* rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF); */
2090	/*  reject all data frames */
2091	rtw_write16(padapter, REG_RXFLTMAP2, 0);
2092
2093	/*  reset TSF */
2094	rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
2095
2096	/*  disable update TSF */
2097	val8 = rtw_read8(padapter, REG_BCN_CTRL);
2098	val8 |= DIS_TSF_UDT;
2099	rtw_write8(padapter, REG_BCN_CTRL, val8);
2100}
2101
2102static void hw_var_set_mlme_sitesurvey(struct adapter *padapter, u8 variable, u8 *val)
2103{
2104	u32 value_rcr, rcr_clear_bit, reg_bcn_ctl;
2105	u16 value_rxfltmap2;
2106	u8 val8;
2107	struct hal_com_data *pHalData;
2108	struct mlme_priv *pmlmepriv;
2109
2110
2111	pHalData = GET_HAL_DATA(padapter);
2112	pmlmepriv = &padapter->mlmepriv;
2113
2114	reg_bcn_ctl = REG_BCN_CTRL;
2115
2116	rcr_clear_bit = RCR_CBSSID_BCN;
2117
2118	/*  config RCR to receive different BSSID & not to receive data frame */
2119	value_rxfltmap2 = 0;
2120
2121	if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == true))
2122		rcr_clear_bit = RCR_CBSSID_BCN;
2123
2124	value_rcr = rtw_read32(padapter, REG_RCR);
2125
2126	if (*((u8 *)val)) {
2127		/*  under sitesurvey */
2128		value_rcr &= ~(rcr_clear_bit);
2129		rtw_write32(padapter, REG_RCR, value_rcr);
2130
2131		rtw_write16(padapter, REG_RXFLTMAP2, value_rxfltmap2);
2132
2133		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
2134			/*  disable update TSF */
2135			val8 = rtw_read8(padapter, reg_bcn_ctl);
2136			val8 |= DIS_TSF_UDT;
2137			rtw_write8(padapter, reg_bcn_ctl, val8);
2138		}
2139
2140		/*  Save original RRSR setting. */
2141		pHalData->RegRRSR = rtw_read16(padapter, REG_RRSR);
2142	} else {
2143		/*  sitesurvey done */
2144		if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)))
2145			/*  enable to rx data frame */
2146			rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
2147
2148		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
2149			/*  enable update TSF */
2150			val8 = rtw_read8(padapter, reg_bcn_ctl);
2151			val8 &= ~DIS_TSF_UDT;
2152			rtw_write8(padapter, reg_bcn_ctl, val8);
2153		}
2154
2155		value_rcr |= rcr_clear_bit;
2156		rtw_write32(padapter, REG_RCR, value_rcr);
2157
2158		/*  Restore original RRSR setting. */
2159		rtw_write16(padapter, REG_RRSR, pHalData->RegRRSR);
2160	}
2161}
2162
2163static void hw_var_set_mlme_join(struct adapter *padapter, u8 variable, u8 *val)
2164{
2165	u8 val8;
2166	u16 val16;
2167	u32 val32;
2168	u8 RetryLimit = 0x30;
2169	u8 type = *(u8 *)val;
2170	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2171	struct eeprom_priv *pEEPROM;
2172
2173
2174	pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
2175
2176	if (type == 0) { /*  prepare to join */
2177		/* enable to rx data frame.Accept all data frame */
2178		/* rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF); */
2179		rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
2180
2181		val32 = rtw_read32(padapter, REG_RCR);
2182		if (padapter->in_cta_test)
2183			val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
2184		else
2185			val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
2186		rtw_write32(padapter, REG_RCR, val32);
2187
2188		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
2189			RetryLimit = (pEEPROM->CustomerID == RT_CID_CCX) ? 7 : 48;
2190		else /*  Ad-hoc Mode */
2191			RetryLimit = 0x7;
2192	} else if (type == 1) /* joinbss_event call back when join res < 0 */
2193		rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
2194	else if (type == 2) { /* sta add event call back */
2195		/* enable update TSF */
2196		val8 = rtw_read8(padapter, REG_BCN_CTRL);
2197		val8 &= ~DIS_TSF_UDT;
2198		rtw_write8(padapter, REG_BCN_CTRL, val8);
2199
2200		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
2201			RetryLimit = 0x7;
2202	}
2203
2204	val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
2205	rtw_write16(padapter, REG_RL, val16);
2206}
2207
2208void CCX_FwC2HTxRpt_8723b(struct adapter *padapter, u8 *pdata, u8 len)
2209{
2210
2211#define	GET_8723B_C2H_TX_RPT_LIFE_TIME_OVER(_Header)	LE_BITS_TO_1BYTE((_Header + 0), 6, 1)
2212#define	GET_8723B_C2H_TX_RPT_RETRY_OVER(_Header)	LE_BITS_TO_1BYTE((_Header + 0), 7, 1)
2213
2214	if (GET_8723B_C2H_TX_RPT_RETRY_OVER(pdata) | GET_8723B_C2H_TX_RPT_LIFE_TIME_OVER(pdata)) {
2215		rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
2216	}
2217/*
2218	else if (seq_no != padapter->xmitpriv.seq_no) {
2219		rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
2220	}
2221*/
2222	else
2223		rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);
2224}
2225
2226s32 c2h_id_filter_ccx_8723b(u8 *buf)
2227{
2228	struct c2h_evt_hdr_88xx *c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
2229	s32 ret = false;
2230	if (c2h_evt->id == C2H_CCX_TX_RPT)
2231		ret = true;
2232
2233	return ret;
2234}
2235
2236
2237s32 c2h_handler_8723b(struct adapter *padapter, u8 *buf)
2238{
2239	struct c2h_evt_hdr_88xx *pC2hEvent = (struct c2h_evt_hdr_88xx *)buf;
2240	s32 ret = _SUCCESS;
2241
2242	if (!pC2hEvent) {
2243		ret = _FAIL;
2244		goto exit;
2245	}
2246
2247	switch (pC2hEvent->id) {
2248	case C2H_AP_RPT_RSP:
2249		break;
2250	case C2H_DBG:
2251		{
2252		}
2253		break;
2254
2255	case C2H_CCX_TX_RPT:
2256/* 			CCX_FwC2HTxRpt(padapter, QueueID, pC2hEvent->payload); */
2257		break;
2258
2259	case C2H_EXT_RA_RPT:
2260/* 			C2HExtRaRptHandler(padapter, pC2hEvent->payload, C2hEvent.CmdLen); */
2261		break;
2262
2263	case C2H_HW_INFO_EXCH:
2264		break;
2265
2266	case C2H_8723B_BT_INFO:
2267		hal_btcoex_BtInfoNotify(padapter, pC2hEvent->plen, pC2hEvent->payload);
2268		break;
2269
2270	default:
2271		break;
2272	}
2273
2274	/*  Clear event to notify FW we have read the command. */
2275	/*  Note: */
2276	/* 	If this field isn't clear, the FW won't update the next command message. */
2277/* 	rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); */
2278exit:
2279	return ret;
2280}
2281
2282static void process_c2h_event(struct adapter *padapter, struct c2h_evt_hdr_t *pC2hEvent, u8 *c2hBuf)
2283{
2284	if (!c2hBuf)
2285		return;
2286
2287	switch (pC2hEvent->CmdID) {
2288	case C2H_AP_RPT_RSP:
2289		break;
2290	case C2H_DBG:
2291		{
2292		}
2293		break;
2294
2295	case C2H_CCX_TX_RPT:
2296/* 			CCX_FwC2HTxRpt(padapter, QueueID, tmpBuf); */
2297		break;
2298
2299	case C2H_EXT_RA_RPT:
2300/* 			C2HExtRaRptHandler(padapter, tmpBuf, C2hEvent.CmdLen); */
2301		break;
2302
2303	case C2H_HW_INFO_EXCH:
2304		break;
2305
2306	case C2H_8723B_BT_INFO:
2307		hal_btcoex_BtInfoNotify(padapter, pC2hEvent->CmdLen, c2hBuf);
2308		break;
2309
2310	default:
2311		break;
2312	}
2313}
2314
2315void C2HPacketHandler_8723B(struct adapter *padapter, u8 *pbuffer, u16 length)
2316{
2317	struct c2h_evt_hdr_t	C2hEvent;
2318	u8 *tmpBuf = NULL;
2319	C2hEvent.CmdID = pbuffer[0];
2320	C2hEvent.CmdSeq = pbuffer[1];
2321	C2hEvent.CmdLen = length-2;
2322	tmpBuf = pbuffer+2;
2323
2324	process_c2h_event(padapter, &C2hEvent, tmpBuf);
2325	/* c2h_handler_8723b(padapter,&C2hEvent); */
2326}
2327
2328void SetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val)
2329{
2330	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
2331	u8 val8;
2332	u32 val32;
2333
2334	switch (variable) {
2335	case HW_VAR_MEDIA_STATUS:
2336		val8 = rtw_read8(padapter, MSR) & 0x0c;
2337		val8 |= *val;
2338		rtw_write8(padapter, MSR, val8);
2339		break;
2340
2341	case HW_VAR_MEDIA_STATUS1:
2342		val8 = rtw_read8(padapter, MSR) & 0x03;
2343		val8 |= *val << 2;
2344		rtw_write8(padapter, MSR, val8);
2345		break;
2346
2347	case HW_VAR_SET_OPMODE:
2348		hw_var_set_opmode(padapter, variable, val);
2349		break;
2350
2351	case HW_VAR_MAC_ADDR:
2352		hw_var_set_macaddr(padapter, variable, val);
2353		break;
2354
2355	case HW_VAR_BSSID:
2356		hw_var_set_bssid(padapter, variable, val);
2357		break;
2358
2359	case HW_VAR_BASIC_RATE:
2360	{
2361		struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
2362		u16 BrateCfg = 0;
2363		u16 rrsr_2g_force_mask = (RRSR_11M|RRSR_5_5M|RRSR_1M);
2364		u16 rrsr_2g_allow_mask = (RRSR_24M|RRSR_12M|RRSR_6M|RRSR_CCK_RATES);
2365
2366		HalSetBrateCfg(padapter, val, &BrateCfg);
2367
2368		/* apply force and allow mask */
2369		BrateCfg |= rrsr_2g_force_mask;
2370		BrateCfg &= rrsr_2g_allow_mask;
2371
2372		/* IOT consideration */
2373		if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
2374			/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
2375			if ((BrateCfg & (RRSR_24M|RRSR_12M|RRSR_6M)) == 0)
2376				BrateCfg |= RRSR_6M;
2377		}
2378
2379		pHalData->BasicRateSet = BrateCfg;
2380
2381		/*  Set RRSR rate table. */
2382		rtw_write16(padapter, REG_RRSR, BrateCfg);
2383		rtw_write8(padapter, REG_RRSR+2, rtw_read8(padapter, REG_RRSR+2)&0xf0);
2384	}
2385		break;
2386
2387	case HW_VAR_TXPAUSE:
2388		rtw_write8(padapter, REG_TXPAUSE, *val);
2389		break;
2390
2391	case HW_VAR_BCN_FUNC:
2392		hw_var_set_bcn_func(padapter, variable, val);
2393		break;
2394
2395	case HW_VAR_CORRECT_TSF:
2396		hw_var_set_correct_tsf(padapter, variable, val);
2397		break;
2398
2399	case HW_VAR_CHECK_BSSID:
2400		{
2401			u32 val32;
2402			val32 = rtw_read32(padapter, REG_RCR);
2403			if (*val)
2404				val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
2405			else
2406				val32 &= ~(RCR_CBSSID_DATA|RCR_CBSSID_BCN);
2407			rtw_write32(padapter, REG_RCR, val32);
2408		}
2409		break;
2410
2411	case HW_VAR_MLME_DISCONNECT:
2412		hw_var_set_mlme_disconnect(padapter, variable, val);
2413		break;
2414
2415	case HW_VAR_MLME_SITESURVEY:
2416		hw_var_set_mlme_sitesurvey(padapter, variable,  val);
2417
2418		hal_btcoex_ScanNotify(padapter, *val?true:false);
2419		break;
2420
2421	case HW_VAR_MLME_JOIN:
2422		hw_var_set_mlme_join(padapter, variable, val);
2423
2424		switch (*val) {
2425		case 0:
2426			/*  prepare to join */
2427			hal_btcoex_ConnectNotify(padapter, true);
2428			break;
2429		case 1:
2430			/*  joinbss_event callback when join res < 0 */
2431			hal_btcoex_ConnectNotify(padapter, false);
2432			break;
2433		case 2:
2434			/*  sta add event callback */
2435/* 				rtw_btcoex_MediaStatusNotify(padapter, RT_MEDIA_CONNECT); */
2436			break;
2437		}
2438		break;
2439
2440	case HW_VAR_ON_RCR_AM:
2441		val32 = rtw_read32(padapter, REG_RCR);
2442		val32 |= RCR_AM;
2443		rtw_write32(padapter, REG_RCR, val32);
2444		break;
2445
2446	case HW_VAR_OFF_RCR_AM:
2447		val32 = rtw_read32(padapter, REG_RCR);
2448		val32 &= ~RCR_AM;
2449		rtw_write32(padapter, REG_RCR, val32);
2450		break;
2451
2452	case HW_VAR_BEACON_INTERVAL:
2453		rtw_write16(padapter, REG_BCN_INTERVAL, *((u16 *)val));
2454		break;
2455
2456	case HW_VAR_SLOT_TIME:
2457		rtw_write8(padapter, REG_SLOT, *val);
2458		break;
2459
2460	case HW_VAR_RESP_SIFS:
2461		/* SIFS_Timer = 0x0a0a0808; */
2462		/* RESP_SIFS for CCK */
2463		rtw_write8(padapter, REG_RESP_SIFS_CCK, val[0]); /*  SIFS_T2T_CCK (0x08) */
2464		rtw_write8(padapter, REG_RESP_SIFS_CCK+1, val[1]); /* SIFS_R2T_CCK(0x08) */
2465		/* RESP_SIFS for OFDM */
2466		rtw_write8(padapter, REG_RESP_SIFS_OFDM, val[2]); /* SIFS_T2T_OFDM (0x0a) */
2467		rtw_write8(padapter, REG_RESP_SIFS_OFDM+1, val[3]); /* SIFS_R2T_OFDM(0x0a) */
2468		break;
2469
2470	case HW_VAR_ACK_PREAMBLE:
2471		{
2472			u8 regTmp = 0;
2473			u8 bShortPreamble = *val;
2474
2475			/*  Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
2476			/* regTmp = (pHalData->nCur40MhzPrimeSC)<<5; */
2477			if (bShortPreamble)
2478				regTmp |= 0x80;
2479			rtw_write8(padapter, REG_RRSR+2, regTmp);
2480		}
2481		break;
2482
2483	case HW_VAR_CAM_EMPTY_ENTRY:
2484		{
2485			u8 ucIndex = *val;
2486			u8 i;
2487			u32 ulCommand = 0;
2488			u32 ulContent = 0;
2489			u32 ulEncAlgo = CAM_AES;
2490
2491			for (i = 0; i < CAM_CONTENT_COUNT; i++) {
2492				/*  filled id in CAM config 2 byte */
2493				if (i == 0) {
2494					ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2);
2495					/* ulContent |= CAM_VALID; */
2496				} else
2497					ulContent = 0;
2498
2499				/*  polling bit, and No Write enable, and address */
2500				ulCommand = CAM_CONTENT_COUNT*ucIndex+i;
2501				ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
2502				/*  write content 0 is equal to mark as invalid */
2503				rtw_write32(padapter, WCAMI, ulContent);  /* mdelay(40); */
2504				rtw_write32(padapter, RWCAM, ulCommand);  /* mdelay(40); */
2505			}
2506		}
2507		break;
2508
2509	case HW_VAR_CAM_INVALID_ALL:
2510		rtw_write32(padapter, RWCAM, BIT(31)|BIT(30));
2511		break;
2512
2513	case HW_VAR_CAM_WRITE:
2514		{
2515			u32 cmd;
2516			u32 *cam_val = (u32 *)val;
2517
2518			rtw_write32(padapter, WCAMI, cam_val[0]);
2519
2520			cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
2521			rtw_write32(padapter, RWCAM, cmd);
2522		}
2523		break;
2524
2525	case HW_VAR_AC_PARAM_VO:
2526		rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32 *)val));
2527		break;
2528
2529	case HW_VAR_AC_PARAM_VI:
2530		rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32 *)val));
2531		break;
2532
2533	case HW_VAR_AC_PARAM_BE:
2534		pHalData->AcParam_BE = ((u32 *)(val))[0];
2535		rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32 *)val));
2536		break;
2537
2538	case HW_VAR_AC_PARAM_BK:
2539		rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32 *)val));
2540		break;
2541
2542	case HW_VAR_ACM_CTRL:
2543		{
2544			u8 ctrl = *((u8 *)val);
2545			u8 hwctrl = 0;
2546
2547			if (ctrl != 0) {
2548				hwctrl |= AcmHw_HwEn;
2549
2550				if (ctrl & BIT(1)) /*  BE */
2551					hwctrl |= AcmHw_BeqEn;
2552
2553				if (ctrl & BIT(2)) /*  VI */
2554					hwctrl |= AcmHw_ViqEn;
2555
2556				if (ctrl & BIT(3)) /*  VO */
2557					hwctrl |= AcmHw_VoqEn;
2558			}
2559
2560			rtw_write8(padapter, REG_ACMHWCTRL, hwctrl);
2561		}
2562		break;
2563
2564	case HW_VAR_AMPDU_FACTOR:
2565		{
2566			u32 AMPDULen =  (*((u8 *)val));
2567
2568			if (AMPDULen < HT_AGG_SIZE_32K)
2569				AMPDULen = (0x2000 << (*((u8 *)val)))-1;
2570			else
2571				AMPDULen = 0x7fff;
2572
2573			rtw_write32(padapter, REG_AMPDU_MAX_LENGTH_8723B, AMPDULen);
2574		}
2575		break;
2576
2577	case HW_VAR_H2C_FW_PWRMODE:
2578		{
2579			u8 psmode = *val;
2580
2581			/*  Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */
2582			/*  saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */
2583			if (psmode != PS_MODE_ACTIVE) {
2584				ODM_RF_Saving(&pHalData->odmpriv, true);
2585			}
2586
2587			/* if (psmode != PS_MODE_ACTIVE)	{ */
2588			/* 	rtl8723b_set_lowpwr_lps_cmd(padapter, true); */
2589			/*  else { */
2590			/* 	rtl8723b_set_lowpwr_lps_cmd(padapter, false); */
2591			/*  */
2592			rtl8723b_set_FwPwrMode_cmd(padapter, psmode);
2593		}
2594		break;
2595	case HW_VAR_H2C_PS_TUNE_PARAM:
2596		rtl8723b_set_FwPsTuneParam_cmd(padapter);
2597		break;
2598
2599	case HW_VAR_H2C_FW_JOINBSSRPT:
2600		rtl8723b_set_FwJoinBssRpt_cmd(padapter, *val);
2601		break;
2602
2603	case HW_VAR_INITIAL_GAIN:
2604		{
2605			struct dig_t *pDigTable = &pHalData->odmpriv.DM_DigTable;
2606			u32 rx_gain = *(u32 *)val;
2607
2608			if (rx_gain == 0xff) {/* restore rx gain */
2609				ODM_Write_DIG(&pHalData->odmpriv, pDigTable->BackupIGValue);
2610			} else {
2611				pDigTable->BackupIGValue = pDigTable->CurIGValue;
2612				ODM_Write_DIG(&pHalData->odmpriv, rx_gain);
2613			}
2614		}
2615		break;
2616
2617	case HW_VAR_EFUSE_USAGE:
2618		pHalData->EfuseUsedPercentage = *val;
2619		break;
2620
2621	case HW_VAR_EFUSE_BYTES:
2622		pHalData->EfuseUsedBytes = *((u16 *)val);
2623		break;
2624
2625	case HW_VAR_EFUSE_BT_USAGE:
2626#ifdef HAL_EFUSE_MEMORY
2627		pHalData->EfuseHal.BTEfuseUsedPercentage = *val;
2628#endif
2629		break;
2630
2631	case HW_VAR_EFUSE_BT_BYTES:
2632#ifdef HAL_EFUSE_MEMORY
2633		pHalData->EfuseHal.BTEfuseUsedBytes = *((u16 *)val);
2634#else
2635		BTEfuseUsedBytes = *((u16 *)val);
2636#endif
2637		break;
2638
2639	case HW_VAR_FIFO_CLEARN_UP:
2640		{
2641			#define RW_RELEASE_EN		BIT(18)
2642			#define RXDMA_IDLE			BIT(17)
2643
2644			struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2645			u8 trycnt = 100;
2646
2647			/*  pause tx */
2648			rtw_write8(padapter, REG_TXPAUSE, 0xff);
2649
2650			/*  keep sn */
2651			padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ);
2652
2653			if (!pwrpriv->bkeepfwalive) {
2654				/* RX DMA stop */
2655				val32 = rtw_read32(padapter, REG_RXPKT_NUM);
2656				val32 |= RW_RELEASE_EN;
2657				rtw_write32(padapter, REG_RXPKT_NUM, val32);
2658				do {
2659					val32 = rtw_read32(padapter, REG_RXPKT_NUM);
2660					val32 &= RXDMA_IDLE;
2661					if (val32)
2662						break;
2663				} while (--trycnt);
2664
2665				/*  RQPN Load 0 */
2666				rtw_write16(padapter, REG_RQPN_NPQ, 0);
2667				rtw_write32(padapter, REG_RQPN, 0x80000000);
2668				mdelay(2);
2669			}
2670		}
2671		break;
2672
2673	case HW_VAR_APFM_ON_MAC:
2674		pHalData->bMacPwrCtrlOn = *val;
2675		break;
2676
2677	case HW_VAR_NAV_UPPER:
2678		{
2679			u32 usNavUpper = *((u32 *)val);
2680
2681			if (usNavUpper > HAL_NAV_UPPER_UNIT_8723B * 0xFF)
2682				break;
2683
2684			usNavUpper = DIV_ROUND_UP(usNavUpper,
2685						  HAL_NAV_UPPER_UNIT_8723B);
2686			rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);
2687		}
2688		break;
2689
2690	case HW_VAR_H2C_MEDIA_STATUS_RPT:
2691		{
2692			u16 mstatus_rpt = (*(u16 *)val);
2693			u8 mstatus, macId;
2694
2695			mstatus = (u8) (mstatus_rpt & 0xFF);
2696			macId = (u8)(mstatus_rpt >> 8);
2697			rtl8723b_set_FwMediaStatusRpt_cmd(padapter, mstatus, macId);
2698		}
2699		break;
2700	case HW_VAR_BCN_VALID:
2701		{
2702			/*  BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw */
2703			val8 = rtw_read8(padapter, REG_TDECTRL+2);
2704			val8 |= BIT(0);
2705			rtw_write8(padapter, REG_TDECTRL+2, val8);
2706		}
2707		break;
2708
2709	case HW_VAR_DL_BCN_SEL:
2710		{
2711			/*  SW_BCN_SEL - Port0 */
2712			val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
2713			val8 &= ~BIT(4);
2714			rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8);
2715		}
2716		break;
2717
2718	case HW_VAR_DO_IQK:
2719		pHalData->bNeedIQK = true;
2720		break;
2721
2722	case HW_VAR_DL_RSVD_PAGE:
2723		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)
2724			rtl8723b_download_BTCoex_AP_mode_rsvd_page(padapter);
2725		else
2726			rtl8723b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
2727		break;
2728
2729	case HW_VAR_MACID_SLEEP:
2730		/*  Input is MACID */
2731		val32 = *(u32 *)val;
2732		if (val32 > 31)
2733			break;
2734
2735		val8 = (u8)val32; /*  macid is between 0~31 */
2736
2737		val32 = rtw_read32(padapter, REG_MACID_SLEEP);
2738		if (val32 & BIT(val8))
2739			break;
2740		val32 |= BIT(val8);
2741		rtw_write32(padapter, REG_MACID_SLEEP, val32);
2742		break;
2743
2744	case HW_VAR_MACID_WAKEUP:
2745		/*  Input is MACID */
2746		val32 = *(u32 *)val;
2747		if (val32 > 31)
2748			break;
2749
2750		val8 = (u8)val32; /*  macid is between 0~31 */
2751
2752		val32 = rtw_read32(padapter, REG_MACID_SLEEP);
2753		if (!(val32 & BIT(val8)))
2754			break;
2755		val32 &= ~BIT(val8);
2756		rtw_write32(padapter, REG_MACID_SLEEP, val32);
2757		break;
2758
2759	default:
2760		SetHwReg(padapter, variable, val);
2761		break;
2762	}
2763}
2764
2765void GetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val)
2766{
2767	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
2768	u8 val8;
2769	u16 val16;
2770
2771	switch (variable) {
2772	case HW_VAR_TXPAUSE:
2773		*val = rtw_read8(padapter, REG_TXPAUSE);
2774		break;
2775
2776	case HW_VAR_BCN_VALID:
2777		{
2778			/*  BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */
2779			val8 = rtw_read8(padapter, REG_TDECTRL+2);
2780			*val = (BIT(0) & val8) ? true : false;
2781		}
2782		break;
2783
2784	case HW_VAR_FWLPS_RF_ON:
2785		{
2786			/*  When we halt NIC, we should check if FW LPS is leave. */
2787			u32 valRCR;
2788
2789			if (
2790				padapter->bSurpriseRemoved  ||
2791				(adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off)
2792			) {
2793				/*  If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */
2794				/*  because Fw is unload. */
2795				*val = true;
2796			} else {
2797				valRCR = rtw_read32(padapter, REG_RCR);
2798				valRCR &= 0x00070000;
2799				if (valRCR)
2800					*val = false;
2801				else
2802					*val = true;
2803			}
2804		}
2805		break;
2806
2807	case HW_VAR_EFUSE_USAGE:
2808		*val = pHalData->EfuseUsedPercentage;
2809		break;
2810
2811	case HW_VAR_EFUSE_BYTES:
2812		*((u16 *)val) = pHalData->EfuseUsedBytes;
2813		break;
2814
2815	case HW_VAR_EFUSE_BT_USAGE:
2816#ifdef HAL_EFUSE_MEMORY
2817		*val = pHalData->EfuseHal.BTEfuseUsedPercentage;
2818#endif
2819		break;
2820
2821	case HW_VAR_EFUSE_BT_BYTES:
2822#ifdef HAL_EFUSE_MEMORY
2823		*((u16 *)val) = pHalData->EfuseHal.BTEfuseUsedBytes;
2824#else
2825		*((u16 *)val) = BTEfuseUsedBytes;
2826#endif
2827		break;
2828
2829	case HW_VAR_APFM_ON_MAC:
2830		*val = pHalData->bMacPwrCtrlOn;
2831		break;
2832	case HW_VAR_CHK_HI_QUEUE_EMPTY:
2833		val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);
2834		*val = (val16 & BIT(10)) ? true : false;
2835		break;
2836	default:
2837		GetHwReg(padapter, variable, val);
2838		break;
2839	}
2840}
2841
2842/* Description:
2843 *	Query setting of specified variable.
2844 */
2845u8 GetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, void *pval)
2846{
2847	u8 bResult = _SUCCESS;
2848
2849	switch (variable) {
2850	case HAL_DEF_MAX_RECVBUF_SZ:
2851		*((u32 *)pval) = MAX_RECVBUF_SZ;
2852		break;
2853
2854	case HAL_DEF_RX_PACKET_OFFSET:
2855		*((u32 *)pval) = RXDESC_SIZE + DRVINFO_SZ*8;
2856		break;
2857
2858	case HW_VAR_MAX_RX_AMPDU_FACTOR:
2859		/*  Stanley@BB.SD3 suggests 16K can get stable performance */
2860		/*  The experiment was done on SDIO interface */
2861		/*  coding by Lucas@20130730 */
2862		*(u32 *)pval = IEEE80211_HT_MAX_AMPDU_16K;
2863		break;
2864	case HAL_DEF_TX_LDPC:
2865	case HAL_DEF_RX_LDPC:
2866		*((u8 *)pval) = false;
2867		break;
2868	case HAL_DEF_TX_STBC:
2869		*((u8 *)pval) = 0;
2870		break;
2871	case HAL_DEF_RX_STBC:
2872		*((u8 *)pval) = 1;
2873		break;
2874	case HAL_DEF_EXPLICIT_BEAMFORMER:
2875	case HAL_DEF_EXPLICIT_BEAMFORMEE:
2876		*((u8 *)pval) = false;
2877		break;
2878
2879	case HW_DEF_RA_INFO_DUMP:
2880		{
2881			u8 mac_id = *(u8 *)pval;
2882			u32 cmd = 0x40000100 | mac_id;
2883
2884			rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B, cmd);
2885			msleep(10);
2886			rtw_read32(padapter, 0x2F0);	// info 1
2887
2888			cmd = 0x40000400 | mac_id;
2889			rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B, cmd);
2890			msleep(10);
2891			rtw_read32(padapter, 0x2F0);	// info 1
2892			rtw_read32(padapter, 0x2F4);	// info 2
2893			rtw_read32(padapter, 0x2F8);	// rate mask 1
2894			rtw_read32(padapter, 0x2FC);	// rate mask 2
2895		}
2896		break;
2897
2898	case HAL_DEF_TX_PAGE_BOUNDARY:
2899		if (!padapter->registrypriv.wifi_spec) {
2900			*(u8 *)pval = TX_PAGE_BOUNDARY_8723B;
2901		} else {
2902			*(u8 *)pval = WMM_NORMAL_TX_PAGE_BOUNDARY_8723B;
2903		}
2904		break;
2905
2906	case HAL_DEF_MACID_SLEEP:
2907		*(u8 *)pval = true; /*  support macid sleep */
2908		break;
2909
2910	default:
2911		bResult = GetHalDefVar(padapter, variable, pval);
2912		break;
2913	}
2914
2915	return bResult;
2916}
2917
2918void rtl8723b_start_thread(struct adapter *padapter)
2919{
2920	struct xmit_priv *xmitpriv = &padapter->xmitpriv;
2921
2922	xmitpriv->SdioXmitThread = kthread_run(rtl8723bs_xmit_thread, padapter, "RTWHALXT");
2923}
2924
2925void rtl8723b_stop_thread(struct adapter *padapter)
2926{
2927	struct xmit_priv *xmitpriv = &padapter->xmitpriv;
2928
2929	/*  stop xmit_buf_thread */
2930	if (xmitpriv->SdioXmitThread) {
2931		complete(&xmitpriv->SdioXmitStart);
2932		wait_for_completion(&xmitpriv->SdioXmitTerminate);
2933		xmitpriv->SdioXmitThread = NULL;
2934	}
2935}
~/ Read-only file preview.