1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 8 #include <linux/kernel.h> 9 #include <drv_types.h> 10 #include <rtw_debug.h> 11 #include "hal_com_h2c.h" 12 13 #include "odm_precomp.h" 14 15 u8 rtw_hal_data_init(struct adapter *padapter) 16 { 17 if (is_primary_adapter(padapter)) { /* if (padapter->isprimary) */ 18 padapter->hal_data_sz = sizeof(struct hal_com_data); 19 padapter->HalData = vzalloc(padapter->hal_data_sz); 20 if (!padapter->HalData) 21 return _FAIL; 22 } 23 return _SUCCESS; 24 } 25 26 void rtw_hal_data_deinit(struct adapter *padapter) 27 { 28 if (is_primary_adapter(padapter)) { /* if (padapter->isprimary) */ 29 if (padapter->HalData) { 30 vfree(padapter->HalData); 31 padapter->HalData = NULL; 32 padapter->hal_data_sz = 0; 33 } 34 } 35 } 36 37 38 void dump_chip_info(struct hal_version ChipVersion) 39 { 40 char buf[128]; 41 size_t cnt = 0; 42 43 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "Chip Version Info: CHIP_8723B_%s_", 44 IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip"); 45 46 if (IS_CHIP_VENDOR_TSMC(ChipVersion)) 47 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "TSMC_"); 48 else if (IS_CHIP_VENDOR_UMC(ChipVersion)) 49 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "UMC_"); 50 else if (IS_CHIP_VENDOR_SMIC(ChipVersion)) 51 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "SMIC_"); 52 53 if (IS_A_CUT(ChipVersion)) 54 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "A_CUT_"); 55 else if (IS_B_CUT(ChipVersion)) 56 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "B_CUT_"); 57 else if (IS_C_CUT(ChipVersion)) 58 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "C_CUT_"); 59 else if (IS_D_CUT(ChipVersion)) 60 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "D_CUT_"); 61 else if (IS_E_CUT(ChipVersion)) 62 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "E_CUT_"); 63 else if (IS_I_CUT(ChipVersion)) 64 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "I_CUT_"); 65 else if (IS_J_CUT(ChipVersion)) 66 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "J_CUT_"); 67 else if (IS_K_CUT(ChipVersion)) 68 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "K_CUT_"); 69 else 70 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, 71 "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion); 72 73 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "1T1R_"); 74 75 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "RomVer(%d)\n", ChipVersion.ROMVer); 76 } 77 78 79 #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 80 81 /* 82 * Description: 83 *Use hardware(efuse), driver parameter(registry) and default channel plan 84 *to decide which one should be used. 85 * 86 * Parameters: 87 *padapter pointer of adapter 88 *hw_channel_plan channel plan from HW (efuse/eeprom) 89 * BIT[7] software configure mode; 0:Enable, 1:disable 90 * BIT[6:0] Channel Plan 91 *sw_channel_plan channel plan from SW (registry/module param) 92 *def_channel_plan channel plan used when HW/SW both invalid 93 *AutoLoadFail efuse autoload fail or not 94 * 95 * Return: 96 *Final channel plan decision 97 * 98 */ 99 u8 hal_com_config_channel_plan( 100 struct adapter *padapter, 101 u8 hw_channel_plan, 102 u8 sw_channel_plan, 103 u8 def_channel_plan, 104 bool AutoLoadFail 105 ) 106 { 107 struct hal_com_data *pHalData; 108 u8 chnlPlan; 109 110 pHalData = GET_HAL_DATA(padapter); 111 pHalData->bDisableSWChannelPlan = false; 112 chnlPlan = def_channel_plan; 113 114 if (0xFF == hw_channel_plan) 115 AutoLoadFail = true; 116 117 if (!AutoLoadFail) { 118 u8 hw_chnlPlan; 119 120 hw_chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK); 121 if (rtw_is_channel_plan_valid(hw_chnlPlan)) { 122 if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) 123 pHalData->bDisableSWChannelPlan = true; 124 125 chnlPlan = hw_chnlPlan; 126 } 127 } 128 129 if ( 130 (false == pHalData->bDisableSWChannelPlan) && 131 rtw_is_channel_plan_valid(sw_channel_plan) 132 ) 133 chnlPlan = sw_channel_plan; 134 135 return chnlPlan; 136 } 137 138 bool HAL_IsLegalChannel(struct adapter *adapter, u32 Channel) 139 { 140 bool bLegalChannel = true; 141 142 if ((Channel <= 14) && (Channel >= 1)) { 143 if (is_supported_24g(adapter->registrypriv.wireless_mode) == false) 144 bLegalChannel = false; 145 } else { 146 bLegalChannel = false; 147 } 148 149 return bLegalChannel; 150 } 151 152 u8 MRateToHwRate(u8 rate) 153 { 154 u8 ret = DESC_RATE1M; 155 156 switch (rate) { 157 case MGN_1M: 158 ret = DESC_RATE1M; 159 break; 160 case MGN_2M: 161 ret = DESC_RATE2M; 162 break; 163 case MGN_5_5M: 164 ret = DESC_RATE5_5M; 165 break; 166 case MGN_11M: 167 ret = DESC_RATE11M; 168 break; 169 case MGN_6M: 170 ret = DESC_RATE6M; 171 break; 172 case MGN_9M: 173 ret = DESC_RATE9M; 174 break; 175 case MGN_12M: 176 ret = DESC_RATE12M; 177 break; 178 case MGN_18M: 179 ret = DESC_RATE18M; 180 break; 181 case MGN_24M: 182 ret = DESC_RATE24M; 183 break; 184 case MGN_36M: 185 ret = DESC_RATE36M; 186 break; 187 case MGN_48M: 188 ret = DESC_RATE48M; 189 break; 190 case MGN_54M: 191 ret = DESC_RATE54M; 192 break; 193 case MGN_MCS0: 194 ret = DESC_RATEMCS0; 195 break; 196 case MGN_MCS1: 197 ret = DESC_RATEMCS1; 198 break; 199 case MGN_MCS2: 200 ret = DESC_RATEMCS2; 201 break; 202 case MGN_MCS3: 203 ret = DESC_RATEMCS3; 204 break; 205 case MGN_MCS4: 206 ret = DESC_RATEMCS4; 207 break; 208 case MGN_MCS5: 209 ret = DESC_RATEMCS5; 210 break; 211 case MGN_MCS6: 212 ret = DESC_RATEMCS6; 213 break; 214 case MGN_MCS7: 215 ret = DESC_RATEMCS7; 216 break; 217 default: 218 break; 219 } 220 221 return ret; 222 } 223 224 u8 HwRateToMRate(u8 rate) 225 { 226 u8 ret_rate = MGN_1M; 227 228 switch (rate) { 229 case DESC_RATE1M: 230 ret_rate = MGN_1M; 231 break; 232 case DESC_RATE2M: 233 ret_rate = MGN_2M; 234 break; 235 case DESC_RATE5_5M: 236 ret_rate = MGN_5_5M; 237 break; 238 case DESC_RATE11M: 239 ret_rate = MGN_11M; 240 break; 241 case DESC_RATE6M: 242 ret_rate = MGN_6M; 243 break; 244 case DESC_RATE9M: 245 ret_rate = MGN_9M; 246 break; 247 case DESC_RATE12M: 248 ret_rate = MGN_12M; 249 break; 250 case DESC_RATE18M: 251 ret_rate = MGN_18M; 252 break; 253 case DESC_RATE24M: 254 ret_rate = MGN_24M; 255 break; 256 case DESC_RATE36M: 257 ret_rate = MGN_36M; 258 break; 259 case DESC_RATE48M: 260 ret_rate = MGN_48M; 261 break; 262 case DESC_RATE54M: 263 ret_rate = MGN_54M; 264 break; 265 case DESC_RATEMCS0: 266 ret_rate = MGN_MCS0; 267 break; 268 case DESC_RATEMCS1: 269 ret_rate = MGN_MCS1; 270 break; 271 case DESC_RATEMCS2: 272 ret_rate = MGN_MCS2; 273 break; 274 case DESC_RATEMCS3: 275 ret_rate = MGN_MCS3; 276 break; 277 case DESC_RATEMCS4: 278 ret_rate = MGN_MCS4; 279 break; 280 case DESC_RATEMCS5: 281 ret_rate = MGN_MCS5; 282 break; 283 case DESC_RATEMCS6: 284 ret_rate = MGN_MCS6; 285 break; 286 case DESC_RATEMCS7: 287 ret_rate = MGN_MCS7; 288 break; 289 default: 290 break; 291 } 292 293 return ret_rate; 294 } 295 296 void HalSetBrateCfg(struct adapter *Adapter, u8 *mBratesOS, u16 *pBrateCfg) 297 { 298 u8 i, is_brate, brate; 299 300 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { 301 302 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK; 303 brate = mBratesOS[i] & 0x7f; 304 305 if (is_brate) { 306 switch (brate) { 307 case IEEE80211_CCK_RATE_1MB: 308 *pBrateCfg |= RATE_1M; 309 break; 310 case IEEE80211_CCK_RATE_2MB: 311 *pBrateCfg |= RATE_2M; 312 break; 313 case IEEE80211_CCK_RATE_5MB: 314 *pBrateCfg |= RATE_5_5M; 315 break; 316 case IEEE80211_CCK_RATE_11MB: 317 *pBrateCfg |= RATE_11M; 318 break; 319 case IEEE80211_OFDM_RATE_6MB: 320 *pBrateCfg |= RATE_6M; 321 break; 322 case IEEE80211_OFDM_RATE_9MB: 323 *pBrateCfg |= RATE_9M; 324 break; 325 case IEEE80211_OFDM_RATE_12MB: 326 *pBrateCfg |= RATE_12M; 327 break; 328 case IEEE80211_OFDM_RATE_18MB: 329 *pBrateCfg |= RATE_18M; 330 break; 331 case IEEE80211_OFDM_RATE_24MB: 332 *pBrateCfg |= RATE_24M; 333 break; 334 case IEEE80211_OFDM_RATE_36MB: 335 *pBrateCfg |= RATE_36M; 336 break; 337 case IEEE80211_OFDM_RATE_48MB: 338 *pBrateCfg |= RATE_48M; 339 break; 340 case IEEE80211_OFDM_RATE_54MB: 341 *pBrateCfg |= RATE_54M; 342 break; 343 } 344 } 345 } 346 } 347 348 static void _OneOutPipeMapping(struct adapter *padapter) 349 { 350 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); 351 352 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ 353 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ 354 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */ 355 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */ 356 357 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ 358 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ 359 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ 360 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ 361 } 362 363 static void _TwoOutPipeMapping(struct adapter *padapter, bool bWIFICfg) 364 { 365 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); 366 367 if (bWIFICfg) { /* WMM */ 368 369 /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ 370 /* 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */ 371 /* 0:ep_0 num, 1:ep_1 num */ 372 373 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */ 374 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ 375 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */ 376 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */ 377 378 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ 379 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ 380 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ 381 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ 382 383 } else { /* typical setting */ 384 385 386 /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ 387 /* 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */ 388 /* 0:ep_0 num, 1:ep_1 num */ 389 390 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ 391 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */ 392 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */ 393 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */ 394 395 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ 396 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ 397 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ 398 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ 399 400 } 401 402 } 403 404 static void _ThreeOutPipeMapping(struct adapter *padapter, bool bWIFICfg) 405 { 406 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); 407 408 if (bWIFICfg) { /* for WMM */ 409 410 /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ 411 /* 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */ 412 /* 0:H, 1:N, 2:L */ 413 414 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ 415 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */ 416 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */ 417 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */ 418 419 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ 420 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ 421 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ 422 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ 423 424 } else { /* typical setting */ 425 426 427 /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ 428 /* 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */ 429 /* 0:H, 1:N, 2:L */ 430 431 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */ 432 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */ 433 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */ 434 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */ 435 436 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */ 437 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */ 438 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */ 439 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */ 440 } 441 442 } 443 444 bool Hal_MappingOutPipe(struct adapter *padapter, u8 NumOutPipe) 445 { 446 struct registry_priv *pregistrypriv = &padapter->registrypriv; 447 448 bool bWIFICfg = (pregistrypriv->wifi_spec) ? true : false; 449 450 bool result = true; 451 452 switch (NumOutPipe) { 453 case 2: 454 _TwoOutPipeMapping(padapter, bWIFICfg); 455 break; 456 case 3: 457 case 4: 458 _ThreeOutPipeMapping(padapter, bWIFICfg); 459 break; 460 case 1: 461 _OneOutPipeMapping(padapter); 462 break; 463 default: 464 result = false; 465 break; 466 } 467 468 return result; 469 470 } 471 472 void hal_init_macaddr(struct adapter *adapter) 473 { 474 rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, adapter->eeprompriv.mac_addr); 475 } 476 477 void rtw_init_hal_com_default_value(struct adapter *Adapter) 478 { 479 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); 480 481 pHalData->AntDetection = 1; 482 } 483 484 /* 485 * C2H event format: 486 * Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID 487 * BITS [127:120] [119:16] [15:8] [7:4] [3:0] 488 */ 489 490 void c2h_evt_clear(struct adapter *adapter) 491 { 492 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); 493 } 494 495 /* 496 * C2H event format: 497 * Field TRIGGER CMD_LEN CONTENT CMD_SEQ CMD_ID 498 * BITS [127:120] [119:112] [111:16] [15:8] [7:0] 499 */ 500 s32 c2h_evt_read_88xx(struct adapter *adapter, u8 *buf) 501 { 502 s32 ret = _FAIL; 503 struct c2h_evt_hdr_88xx *c2h_evt; 504 int i; 505 u8 trigger; 506 507 if (!buf) 508 goto exit; 509 510 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR); 511 512 if (trigger == C2H_EVT_HOST_CLOSE) 513 goto exit; /* Not ready */ 514 else if (trigger != C2H_EVT_FW_CLOSE) 515 goto clear_evt; /* Not a valid value */ 516 517 c2h_evt = (struct c2h_evt_hdr_88xx *)buf; 518 519 memset(c2h_evt, 0, 16); 520 521 c2h_evt->id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL); 522 c2h_evt->seq = rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX); 523 c2h_evt->plen = rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX); 524 525 /* Read the content */ 526 for (i = 0; i < c2h_evt->plen; i++) 527 c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i); 528 529 ret = _SUCCESS; 530 531 clear_evt: 532 /* 533 * Clear event to notify FW we have read the command. 534 * If this field isn't clear, the FW won't update the next command message. 535 */ 536 c2h_evt_clear(adapter); 537 exit: 538 return ret; 539 } 540 541 u8 rtw_get_mgntframe_raid(struct adapter *adapter, unsigned char network_type) 542 { 543 return (network_type & WIRELESS_11B) ? RATEID_IDX_B : RATEID_IDX_G; 544 } 545 546 void rtw_hal_update_sta_rate_mask(struct adapter *padapter, struct sta_info *psta) 547 { 548 u8 i, limit; 549 u32 tx_ra_bitmap; 550 551 if (!psta) 552 return; 553 554 tx_ra_bitmap = 0; 555 556 /* b/g mode ra_bitmap */ 557 for (i = 0; i < sizeof(psta->bssrateset); i++) { 558 if (psta->bssrateset[i]) 559 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f); 560 } 561 562 /* n mode ra_bitmap */ 563 if (psta->htpriv.ht_option) { 564 limit = 8; /* 1R */ 565 566 for (i = 0; i < limit; i++) { 567 if (psta->htpriv.ht_cap.mcs.rx_mask[i/8] & BIT(i%8)) 568 tx_ra_bitmap |= BIT(i+12); 569 } 570 } 571 572 psta->ra_mask = tx_ra_bitmap; 573 psta->init_rate = get_highest_rate_idx(tx_ra_bitmap)&0x3f; 574 } 575 576 void hw_var_port_switch(struct adapter *adapter) 577 { 578 } 579 580 void SetHwReg(struct adapter *adapter, u8 variable, u8 *val) 581 { 582 struct hal_com_data *hal_data = GET_HAL_DATA(adapter); 583 struct dm_odm_t *odm = &(hal_data->odmpriv); 584 585 switch (variable) { 586 case HW_VAR_PORT_SWITCH: 587 hw_var_port_switch(adapter); 588 break; 589 case HW_VAR_INIT_RTS_RATE: 590 rtw_warn_on(1); 591 break; 592 case HW_VAR_SEC_CFG: 593 { 594 u16 reg_scr; 595 596 reg_scr = rtw_read16(adapter, REG_SECCFG); 597 rtw_write16(adapter, REG_SECCFG, reg_scr|SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable); 598 } 599 break; 600 case HW_VAR_SEC_DK_CFG: 601 { 602 struct security_priv *sec = &adapter->securitypriv; 603 u8 reg_scr = rtw_read8(adapter, REG_SECCFG); 604 605 if (val) { /* Enable default key related setting */ 606 reg_scr |= SCR_TXBCUSEDK; 607 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X) 608 reg_scr |= (SCR_RxUseDK|SCR_TxUseDK); 609 } else /* Disable default key related setting */ 610 reg_scr &= ~(SCR_RXBCUSEDK|SCR_TXBCUSEDK|SCR_RxUseDK|SCR_TxUseDK); 611 612 rtw_write8(adapter, REG_SECCFG, reg_scr); 613 } 614 break; 615 case HW_VAR_DM_FLAG: 616 odm->SupportAbility = *((u32 *)val); 617 break; 618 case HW_VAR_DM_FUNC_OP: 619 if (*((u8 *)val) == true) { 620 /* save dm flag */ 621 odm->BK_SupportAbility = odm->SupportAbility; 622 } else { 623 /* restore dm flag */ 624 odm->SupportAbility = odm->BK_SupportAbility; 625 } 626 break; 627 case HW_VAR_DM_FUNC_SET: 628 if (*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE) { 629 struct dm_priv *dm = &hal_data->dmpriv; 630 dm->DMFlag = dm->InitDMFlag; 631 odm->SupportAbility = dm->InitODMFlag; 632 } else { 633 odm->SupportAbility |= *((u32 *)val); 634 } 635 break; 636 case HW_VAR_DM_FUNC_CLR: 637 /* 638 * input is already a mask to clear function 639 * don't invert it again! George, Lucas@20130513 640 */ 641 odm->SupportAbility &= *((u32 *)val); 642 break; 643 case HW_VAR_AMPDU_MIN_SPACE: 644 /* TODO - Is something needed here? */ 645 break; 646 case HW_VAR_WIRELESS_MODE: 647 /* TODO - Is something needed here? */ 648 break; 649 default: 650 netdev_dbg(adapter->pnetdev, 651 FUNC_ADPT_FMT " variable(%d) not defined!\n", 652 FUNC_ADPT_ARG(adapter), variable); 653 break; 654 } 655 } 656 657 void GetHwReg(struct adapter *adapter, u8 variable, u8 *val) 658 { 659 struct hal_com_data *hal_data = GET_HAL_DATA(adapter); 660 struct dm_odm_t *odm = &(hal_data->odmpriv); 661 662 switch (variable) { 663 case HW_VAR_BASIC_RATE: 664 *((u16 *)val) = hal_data->BasicRateSet; 665 break; 666 case HW_VAR_DM_FLAG: 667 *((u32 *)val) = odm->SupportAbility; 668 break; 669 default: 670 netdev_dbg(adapter->pnetdev, 671 FUNC_ADPT_FMT " variable(%d) not defined!\n", 672 FUNC_ADPT_ARG(adapter), variable); 673 break; 674 } 675 } 676 677 678 679 680 u8 SetHalDefVar( 681 struct adapter *adapter, enum hal_def_variable variable, void *value 682 ) 683 { 684 struct hal_com_data *hal_data = GET_HAL_DATA(adapter); 685 struct dm_odm_t *odm = &(hal_data->odmpriv); 686 u8 bResult = _SUCCESS; 687 688 switch (variable) { 689 case HAL_DEF_DBG_RX_INFO_DUMP: 690 691 if (odm->bLinked) { 692 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA 693 rtw_dump_raw_rssi_info(adapter); 694 #endif 695 } 696 break; 697 case HW_DEF_ODM_DBG_FLAG: 698 ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_COMP, *((u64 *)value)); 699 break; 700 case HW_DEF_ODM_DBG_LEVEL: 701 ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_LEVEL, *((u32 *)value)); 702 break; 703 case HAL_DEF_DBG_DM_FUNC: 704 { 705 u8 dm_func = *((u8 *)value); 706 struct dm_priv *dm = &hal_data->dmpriv; 707 708 if (dm_func == 0) { /* disable all dynamic func */ 709 odm->SupportAbility = DYNAMIC_FUNC_DISABLE; 710 } else if (dm_func == 1) {/* disable DIG */ 711 odm->SupportAbility &= (~DYNAMIC_BB_DIG); 712 } else if (dm_func == 2) {/* disable High power */ 713 odm->SupportAbility &= (~DYNAMIC_BB_DYNAMIC_TXPWR); 714 } else if (dm_func == 3) {/* disable tx power tracking */ 715 odm->SupportAbility &= (~DYNAMIC_RF_CALIBRATION); 716 } else if (dm_func == 4) {/* disable BT coexistence */ 717 dm->DMFlag &= (~DYNAMIC_FUNC_BT); 718 } else if (dm_func == 5) {/* disable antenna diversity */ 719 odm->SupportAbility &= (~DYNAMIC_BB_ANT_DIV); 720 } else if (dm_func == 6) {/* turn on all dynamic func */ 721 if (!(odm->SupportAbility & DYNAMIC_BB_DIG)) { 722 struct dig_t *pDigTable = &odm->DM_DigTable; 723 pDigTable->CurIGValue = rtw_read8(adapter, 0xc50); 724 } 725 dm->DMFlag |= DYNAMIC_FUNC_BT; 726 odm->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE; 727 } 728 } 729 break; 730 case HAL_DEF_DBG_DUMP_RXPKT: 731 hal_data->bDumpRxPkt = *((u8 *)value); 732 break; 733 case HAL_DEF_DBG_DUMP_TXPKT: 734 hal_data->bDumpTxPkt = *((u8 *)value); 735 break; 736 case HAL_DEF_ANT_DETECT: 737 hal_data->AntDetection = *((u8 *)value); 738 break; 739 default: 740 netdev_dbg(adapter->pnetdev, 741 "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", 742 __func__, variable); 743 bResult = _FAIL; 744 break; 745 } 746 747 return bResult; 748 } 749 750 u8 GetHalDefVar( 751 struct adapter *adapter, enum hal_def_variable variable, void *value 752 ) 753 { 754 struct hal_com_data *hal_data = GET_HAL_DATA(adapter); 755 u8 bResult = _SUCCESS; 756 757 switch (variable) { 758 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: 759 { 760 struct mlme_priv *pmlmepriv; 761 struct sta_priv *pstapriv; 762 struct sta_info *psta; 763 764 pmlmepriv = &adapter->mlmepriv; 765 pstapriv = &adapter->stapriv; 766 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.mac_address); 767 if (psta) 768 *((int *)value) = psta->rssi_stat.UndecoratedSmoothedPWDB; 769 } 770 break; 771 case HAL_DEF_DBG_DM_FUNC: 772 *((u32 *)value) = hal_data->odmpriv.SupportAbility; 773 break; 774 case HAL_DEF_DBG_DUMP_RXPKT: 775 *((u8 *)value) = hal_data->bDumpRxPkt; 776 break; 777 case HAL_DEF_DBG_DUMP_TXPKT: 778 *((u8 *)value) = hal_data->bDumpTxPkt; 779 break; 780 case HAL_DEF_ANT_DETECT: 781 *((u8 *)value) = hal_data->AntDetection; 782 break; 783 case HAL_DEF_MACID_SLEEP: 784 *(u8 *)value = false; 785 break; 786 case HAL_DEF_TX_PAGE_SIZE: 787 *((u32 *)value) = PAGE_SIZE_128; 788 break; 789 default: 790 netdev_dbg(adapter->pnetdev, 791 "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", 792 __func__, variable); 793 bResult = _FAIL; 794 break; 795 } 796 797 return bResult; 798 } 799 800 void GetHalODMVar( 801 struct adapter *Adapter, 802 enum hal_odm_variable eVariable, 803 void *pValue1, 804 void *pValue2 805 ) 806 { 807 switch (eVariable) { 808 default: 809 break; 810 } 811 } 812 813 void SetHalODMVar( 814 struct adapter *Adapter, 815 enum hal_odm_variable eVariable, 816 void *pValue1, 817 bool bSet 818 ) 819 { 820 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); 821 struct dm_odm_t *podmpriv = &pHalData->odmpriv; 822 /* _irqL irqL; */ 823 switch (eVariable) { 824 case HAL_ODM_STA_INFO: 825 { 826 struct sta_info *psta = pValue1; 827 if (bSet) { 828 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta); 829 } else { 830 /* spin_lock_bh(&pHalData->odm_stainfo_lock); */ 831 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL); 832 833 /* spin_unlock_bh(&pHalData->odm_stainfo_lock); */ 834 } 835 } 836 break; 837 case HAL_ODM_P2P_STATE: 838 ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet); 839 break; 840 case HAL_ODM_WIFI_DISPLAY_STATE: 841 ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet); 842 break; 843 844 default: 845 break; 846 } 847 } 848 849 850 bool eqNByte(u8 *str1, u8 *str2, u32 num) 851 { 852 if (num == 0) 853 return false; 854 while (num > 0) { 855 num--; 856 if (str1[num] != str2[num]) 857 return false; 858 } 859 return true; 860 } 861 862 /* */ 863 /* Description: */ 864 /* Return true if chTmp is represent for hex digit and */ 865 /* false otherwise. */ 866 /* */ 867 /* */ 868 bool IsHexDigit(char chTmp) 869 { 870 if ( 871 (chTmp >= '0' && chTmp <= '9') || 872 (chTmp >= 'a' && chTmp <= 'f') || 873 (chTmp >= 'A' && chTmp <= 'F') 874 ) 875 return true; 876 else 877 return false; 878 } 879 880 881 /* */ 882 /* Description: */ 883 /* Translate a character to hex digit. */ 884 /* */ 885 u32 MapCharToHexDigit(char chTmp) 886 { 887 if (chTmp >= '0' && chTmp <= '9') 888 return chTmp - '0'; 889 else if (chTmp >= 'a' && chTmp <= 'f') 890 return 10 + (chTmp - 'a'); 891 else if (chTmp >= 'A' && chTmp <= 'F') 892 return 10 + (chTmp - 'A'); 893 else 894 return 0; 895 } 896 897 898 899 /* Description: */ 900 /* Parse hex number from the string pucStr. */ 901 bool GetHexValueFromString(char *szStr, u32 *pu4bVal, u32 *pu4bMove) 902 { 903 char *szScan = szStr; 904 905 /* Check input parameter. */ 906 if (!szStr || !pu4bVal || !pu4bMove) 907 return false; 908 909 /* Initialize output. */ 910 *pu4bMove = 0; 911 *pu4bVal = 0; 912 913 /* Skip leading space. */ 914 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) { 915 szScan++; 916 (*pu4bMove)++; 917 } 918 919 /* Skip leading '0x' or '0X'. */ 920 if (*szScan == '0' && (*(szScan+1) == 'x' || *(szScan+1) == 'X')) { 921 szScan += 2; 922 (*pu4bMove) += 2; 923 } 924 925 /* Check if szScan is now pointer to a character for hex digit, */ 926 /* if not, it means this is not a valid hex number. */ 927 if (!IsHexDigit(*szScan)) 928 return false; 929 930 /* Parse each digit. */ 931 do { 932 (*pu4bVal) <<= 4; 933 *pu4bVal += MapCharToHexDigit(*szScan); 934 935 szScan++; 936 (*pu4bMove)++; 937 } while (IsHexDigit(*szScan)); 938 939 return true; 940 } 941 942 bool GetFractionValueFromString( 943 char *szStr, u8 *pInteger, u8 *pFraction, u32 *pu4bMove 944 ) 945 { 946 char *szScan = szStr; 947 948 /* Initialize output. */ 949 *pu4bMove = 0; 950 *pInteger = 0; 951 *pFraction = 0; 952 953 /* Skip leading space. */ 954 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) { 955 ++szScan; 956 ++(*pu4bMove); 957 } 958 959 /* Parse each digit. */ 960 do { 961 (*pInteger) *= 10; 962 *pInteger += (*szScan - '0'); 963 964 ++szScan; 965 ++(*pu4bMove); 966 967 if (*szScan == '.') { 968 ++szScan; 969 ++(*pu4bMove); 970 971 if (*szScan < '0' || *szScan > '9') 972 return false; 973 else { 974 *pFraction = *szScan - '0'; 975 ++szScan; 976 ++(*pu4bMove); 977 return true; 978 } 979 } 980 } while (*szScan >= '0' && *szScan <= '9'); 981 982 return true; 983 } 984 985 /* */ 986 /* Description: */ 987 /* Return true if szStr is comment out with leading "//". */ 988 /* */ 989 bool IsCommentString(char *szStr) 990 { 991 if (*szStr == '/' && *(szStr+1) == '/') 992 return true; 993 else 994 return false; 995 } 996 997 bool GetU1ByteIntegerFromStringInDecimal(char *Str, u8 *pInt) 998 { 999 u16 i = 0; 1000 *pInt = 0; 1001 1002 while (Str[i] != '\0') { 1003 if (Str[i] >= '0' && Str[i] <= '9') { 1004 *pInt *= 10; 1005 *pInt += (Str[i] - '0'); 1006 } else 1007 return false; 1008 1009 ++i; 1010 } 1011 1012 return true; 1013 } 1014 1015 /* <20121004, Kordan> For example, 1016 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from 1017 * a string "Hello [Kordan]". 1018 * If RightQualifier does not exist, it will hang in the while loop 1019 */ 1020 bool ParseQualifiedString( 1021 char *In, u32 *Start, char *Out, char LeftQualifier, char RightQualifier 1022 ) 1023 { 1024 u32 i = 0, j = 0; 1025 char c = In[(*Start)++]; 1026 1027 if (c != LeftQualifier) 1028 return false; 1029 1030 i = (*Start); 1031 while ((c = In[(*Start)++]) != RightQualifier) 1032 ; /* find ']' */ 1033 j = (*Start) - 2; 1034 strncpy((char *)Out, (const char *)(In+i), j-i+1); 1035 1036 return true; 1037 } 1038 1039 bool isAllSpaceOrTab(u8 *data, u8 size) 1040 { 1041 u8 cnt = 0, NumOfSpaceAndTab = 0; 1042 1043 while (size > cnt) { 1044 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0') 1045 ++NumOfSpaceAndTab; 1046 1047 ++cnt; 1048 } 1049 1050 return size == NumOfSpaceAndTab; 1051 } 1052 1053 1054 void rtw_hal_check_rxfifo_full(struct adapter *adapter) 1055 { 1056 struct dvobj_priv *psdpriv = adapter->dvobj; 1057 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 1058 int save_cnt = false; 1059 1060 /* switch counter to RX fifo */ 1061 /* printk("8723b or 8192e , MAC_667 set 0xf0\n"); */ 1062 rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xf0); 1063 save_cnt = true; 1064 /* todo: other chips */ 1065 1066 if (save_cnt) { 1067 /* rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0); */ 1068 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow; 1069 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT); 1070 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow-pdbgpriv->dbg_rx_fifo_last_overflow; 1071 } 1072 } 1073 1074 void linked_info_dump(struct adapter *padapter, u8 benable) 1075 { 1076 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); 1077 1078 if (padapter->bLinkInfoDump == benable) 1079 return; 1080 1081 if (benable) { 1082 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */ 1083 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); 1084 1085 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */ 1086 rtw_pm_set_ips(padapter, IPS_NONE); 1087 } else { 1088 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode); 1089 1090 rtw_pm_set_lps(padapter, pwrctrlpriv->ips_org_mode); 1091 } 1092 padapter->bLinkInfoDump = benable; 1093 } 1094 1095 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA 1096 void rtw_get_raw_rssi_info(void *sel, struct adapter *padapter) 1097 { 1098 u8 isCCKrate, rf_path; 1099 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 1100 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; 1101 1102 netdev_dbg(padapter->pnetdev, 1103 "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", 1104 HDATA_RATE(psample_pkt_rssi->data_rate), 1105 psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all); 1106 1107 isCCKrate = psample_pkt_rssi->data_rate <= DESC_RATE11M; 1108 1109 if (isCCKrate) 1110 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball; 1111 1112 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { 1113 netdev_dbg(padapter->pnetdev, 1114 "RF_PATH_%d =>signal_strength:%d(%%), signal_quality:%d(%%)\n", 1115 rf_path, 1116 psample_pkt_rssi->mimo_signal_strength[rf_path], 1117 psample_pkt_rssi->mimo_signal_quality[rf_path]); 1118 1119 if (!isCCKrate) { 1120 netdev_dbg(padapter->pnetdev, 1121 "\trx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n", 1122 psample_pkt_rssi->ofdm_pwr[rf_path], 1123 psample_pkt_rssi->ofdm_snr[rf_path]); 1124 } 1125 } 1126 } 1127 1128 void rtw_dump_raw_rssi_info(struct adapter *padapter) 1129 { 1130 u8 isCCKrate, rf_path; 1131 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 1132 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; 1133 1134 isCCKrate = psample_pkt_rssi->data_rate <= DESC_RATE11M; 1135 1136 if (isCCKrate) 1137 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball; 1138 1139 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { 1140 if (!isCCKrate) { 1141 printk(", rx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n", 1142 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]); 1143 } else { 1144 printk("\n"); 1145 } 1146 } 1147 } 1148 1149 void rtw_store_phy_info(struct adapter *padapter, union recv_frame *prframe) 1150 { 1151 u8 isCCKrate, rf_path; 1152 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 1153 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; 1154 1155 struct odm_phy_info *pPhyInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info); 1156 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; 1157 1158 psample_pkt_rssi->data_rate = pattrib->data_rate; 1159 isCCKrate = pattrib->data_rate <= DESC_RATE11M; 1160 1161 psample_pkt_rssi->pwdball = pPhyInfo->rx_pwd_ba11; 1162 psample_pkt_rssi->pwr_all = pPhyInfo->recv_signal_power; 1163 1164 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) { 1165 psample_pkt_rssi->mimo_signal_strength[rf_path] = pPhyInfo->rx_mimo_signal_strength[rf_path]; 1166 psample_pkt_rssi->mimo_signal_quality[rf_path] = pPhyInfo->rx_mimo_signal_quality[rf_path]; 1167 if (!isCCKrate) { 1168 psample_pkt_rssi->ofdm_pwr[rf_path] = pPhyInfo->RxPwr[rf_path]; 1169 psample_pkt_rssi->ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path]; 1170 } 1171 } 1172 } 1173 #endif 1174 1175 static u32 Array_kfreemap[] = { 1176 0xf8, 0xe, 1177 0xf6, 0xc, 1178 0xf4, 0xa, 1179 0xf2, 0x8, 1180 0xf0, 0x6, 1181 0xf3, 0x4, 1182 0xf5, 0x2, 1183 0xf7, 0x0, 1184 0xf9, 0x0, 1185 0xfc, 0x0, 1186 }; 1187 1188 void rtw_bb_rf_gain_offset(struct adapter *padapter) 1189 { 1190 u8 value = padapter->eeprompriv.EEPROMRFGainOffset; 1191 u32 res, i = 0; 1192 u32 *Array = Array_kfreemap; 1193 u32 v1 = 0, v2 = 0, target = 0; 1194 1195 if (value & BIT4) { 1196 if (padapter->eeprompriv.EEPROMRFGainVal != 0xff) { 1197 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff); 1198 res &= 0xfff87fff; 1199 /* res &= 0xfff87fff; */ 1200 for (i = 0; i < ARRAY_SIZE(Array_kfreemap); i += 2) { 1201 v1 = Array[i]; 1202 v2 = Array[i+1]; 1203 if (v1 == padapter->eeprompriv.EEPROMRFGainVal) { 1204 target = v2; 1205 break; 1206 } 1207 } 1208 PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target); 1209 1210 /* res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f)<< 15; */ 1211 /* rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, RF_GAIN_OFFSET_MASK, res); */ 1212 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff); 1213 } 1214 } 1215 } 1216