FILE
rtl8723b_hal_init.c
File preview with syntax highlighting.
linux-6.19.14/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.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.