1/* 2 ************************************************************************* 3 * Ralink Tech Inc. 4 * 5F., No.36, Taiyuan St., Jhubei City, 5 * Hsinchu County 302, 6 * Taiwan, R.O.C. 7 * 8 * (c) Copyright 2002-2007, Ralink Technology, Inc. 9 * 10 * This program is free software; you can redistribute it and/or modify * 11 * it under the terms of the GNU General Public License as published by * 12 * the Free Software Foundation; either version 2 of the License, or * 13 * (at your option) any later version. * 14 * * 15 * This program is distributed in the hope that it will be useful, * 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 * GNU General Public License for more details. * 19 * * 20 * You should have received a copy of the GNU General Public License * 21 * along with this program; if not, write to the * 22 * Free Software Foundation, Inc., * 23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 24 * * 25 ************************************************************************* 26 27 Module Name: 28 cmm_asic.c 29 30 Abstract: 31 Functions used to communicate with ASIC 32 33 Revision History: 34 Who When What 35 -------- ---------- ---------------------------------------------- 36*/ 37 38#include "../rt_config.h" 39 40/* Reset the RFIC setting to new series */ 41struct rt_rtmp_rf_regs RF2850RegTable[] = { 42/* ch R1 R2 R3(TX0~4=0) R4 */ 43 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b} 44 , 45 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f} 46 , 47 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b} 48 , 49 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f} 50 , 51 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b} 52 , 53 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f} 54 , 55 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b} 56 , 57 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f} 58 , 59 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b} 60 , 61 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f} 62 , 63 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b} 64 , 65 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f} 66 , 67 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b} 68 , 69 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193} 70 , 71 72 /* 802.11 UNI / HyperLan 2 */ 73 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3} 74 , 75 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193} 76 , 77 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183} 78 , 79 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3} 80 , 81 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b} 82 , 83 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b} 84 , 85 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193} 86 , 87 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3} 88 , 89 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b} 90 , 91 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183} 92 , 93 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193} 94 , 95 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3} 96 , /* Plugfest#4, Day4, change RFR3 left4th 9->5. */ 97 98 /* 802.11 HyperLan 2 */ 99 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783} 100 , 101 102 /* 2008.04.30 modified */ 103 /* The system team has AN to improve the EVM value */ 104 /* for channel 102 to 108 for the RT2850/RT2750 dual band solution. */ 105 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793} 106 , 107 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3} 108 , 109 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193} 110 , 111 112 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183} 113 , 114 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b} 115 , 116 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3} 117 , 118 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193} 119 , 120 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183} 121 , 122 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193} 123 , 124 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b} 125 , /* 0x980ed1bb->0x980ed15b required by Rory 20070927 */ 126 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3} 127 , 128 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b} 129 , 130 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193} 131 , 132 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b} 133 , 134 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183} 135 , 136 137 /* 802.11 UNII */ 138 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7} 139 , 140 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187} 141 , 142 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f} 143 , 144 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f} 145 , 146 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7} 147 , 148 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187} 149 , 150 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197} 151 , 152 {167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f} 153 , 154 {169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327} 155 , 156 {171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307} 157 , 158 {173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f} 159 , 160 161 /* Japan */ 162 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b} 163 , 164 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13} 165 , 166 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b} 167 , 168 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23} 169 , 170 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13} 171 , 172 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b} 173 , 174 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23} 175 , 176 177 /* still lack of MMAC(Japan) ch 34,38,42,46 */ 178}; 179 180u8 NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(struct rt_rtmp_rf_regs)); 181 182struct rt_frequency_item FreqItems3020[] = { 183 /**************************************************/ 184 /* ISM : 2.4 to 2.483 GHz // */ 185 /**************************************************/ 186 /* 11g */ 187 /**************************************************/ 188 /*-CH---N-------R---K----------- */ 189 {1, 241, 2, 2} 190 , 191 {2, 241, 2, 7} 192 , 193 {3, 242, 2, 2} 194 , 195 {4, 242, 2, 7} 196 , 197 {5, 243, 2, 2} 198 , 199 {6, 243, 2, 7} 200 , 201 {7, 244, 2, 2} 202 , 203 {8, 244, 2, 7} 204 , 205 {9, 245, 2, 2} 206 , 207 {10, 245, 2, 7} 208 , 209 {11, 246, 2, 2} 210 , 211 {12, 246, 2, 7} 212 , 213 {13, 247, 2, 2} 214 , 215 {14, 248, 2, 4} 216 , 217}; 218 219u8 NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(struct rt_frequency_item)); 220 221void AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter *pAd, u8 *pRateTable) 222{ 223 u8 i; 224 HT_FBK_CFG0_STRUC HtCfg0; 225 HT_FBK_CFG1_STRUC HtCfg1; 226 LG_FBK_CFG0_STRUC LgCfg0; 227 LG_FBK_CFG1_STRUC LgCfg1; 228 struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate; 229 230 /* set to initial value */ 231 HtCfg0.word = 0x65432100; 232 HtCfg1.word = 0xedcba988; 233 LgCfg0.word = 0xedcba988; 234 LgCfg1.word = 0x00002100; 235 236 pNextTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1; 237 for (i = 1; i < *((u8 *)pRateTable); i++) { 238 pCurrTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1 + i; 239 switch (pCurrTxRate->Mode) { 240 case 0: /*CCK */ 241 break; 242 case 1: /*OFDM */ 243 { 244 switch (pCurrTxRate->CurrMCS) { 245 case 0: 246 LgCfg0.field.OFDMMCS0FBK = 247 (pNextTxRate->Mode == 248 MODE_OFDM) ? (pNextTxRate-> 249 CurrMCS + 250 8) : pNextTxRate-> 251 CurrMCS; 252 break; 253 case 1: 254 LgCfg0.field.OFDMMCS1FBK = 255 (pNextTxRate->Mode == 256 MODE_OFDM) ? (pNextTxRate-> 257 CurrMCS + 258 8) : pNextTxRate-> 259 CurrMCS; 260 break; 261 case 2: 262 LgCfg0.field.OFDMMCS2FBK = 263 (pNextTxRate->Mode == 264 MODE_OFDM) ? (pNextTxRate-> 265 CurrMCS + 266 8) : pNextTxRate-> 267 CurrMCS; 268 break; 269 case 3: 270 LgCfg0.field.OFDMMCS3FBK = 271 (pNextTxRate->Mode == 272 MODE_OFDM) ? (pNextTxRate-> 273 CurrMCS + 274 8) : pNextTxRate-> 275 CurrMCS; 276 break; 277 case 4: 278 LgCfg0.field.OFDMMCS4FBK = 279 (pNextTxRate->Mode == 280 MODE_OFDM) ? (pNextTxRate-> 281 CurrMCS + 282 8) : pNextTxRate-> 283 CurrMCS; 284 break; 285 case 5: 286 LgCfg0.field.OFDMMCS5FBK = 287 (pNextTxRate->Mode == 288 MODE_OFDM) ? (pNextTxRate-> 289 CurrMCS + 290 8) : pNextTxRate-> 291 CurrMCS; 292 break; 293 case 6: 294 LgCfg0.field.OFDMMCS6FBK = 295 (pNextTxRate->Mode == 296 MODE_OFDM) ? (pNextTxRate-> 297 CurrMCS + 298 8) : pNextTxRate-> 299 CurrMCS; 300 break; 301 case 7: 302 LgCfg0.field.OFDMMCS7FBK = 303 (pNextTxRate->Mode == 304 MODE_OFDM) ? (pNextTxRate-> 305 CurrMCS + 306 8) : pNextTxRate-> 307 CurrMCS; 308 break; 309 } 310 } 311 break; 312 case 2: /*HT-MIX */ 313 case 3: /*HT-GF */ 314 { 315 if ((pNextTxRate->Mode >= MODE_HTMIX) 316 && (pCurrTxRate->CurrMCS != 317 pNextTxRate->CurrMCS)) { 318 switch (pCurrTxRate->CurrMCS) { 319 case 0: 320 HtCfg0.field.HTMCS0FBK = 321 pNextTxRate->CurrMCS; 322 break; 323 case 1: 324 HtCfg0.field.HTMCS1FBK = 325 pNextTxRate->CurrMCS; 326 break; 327 case 2: 328 HtCfg0.field.HTMCS2FBK = 329 pNextTxRate->CurrMCS; 330 break; 331 case 3: 332 HtCfg0.field.HTMCS3FBK = 333 pNextTxRate->CurrMCS; 334 break; 335 case 4: 336 HtCfg0.field.HTMCS4FBK = 337 pNextTxRate->CurrMCS; 338 break; 339 case 5: 340 HtCfg0.field.HTMCS5FBK = 341 pNextTxRate->CurrMCS; 342 break; 343 case 6: 344 HtCfg0.field.HTMCS6FBK = 345 pNextTxRate->CurrMCS; 346 break; 347 case 7: 348 HtCfg0.field.HTMCS7FBK = 349 pNextTxRate->CurrMCS; 350 break; 351 case 8: 352 HtCfg1.field.HTMCS8FBK = 353 pNextTxRate->CurrMCS; 354 break; 355 case 9: 356 HtCfg1.field.HTMCS9FBK = 357 pNextTxRate->CurrMCS; 358 break; 359 case 10: 360 HtCfg1.field.HTMCS10FBK = 361 pNextTxRate->CurrMCS; 362 break; 363 case 11: 364 HtCfg1.field.HTMCS11FBK = 365 pNextTxRate->CurrMCS; 366 break; 367 case 12: 368 HtCfg1.field.HTMCS12FBK = 369 pNextTxRate->CurrMCS; 370 break; 371 case 13: 372 HtCfg1.field.HTMCS13FBK = 373 pNextTxRate->CurrMCS; 374 break; 375 case 14: 376 HtCfg1.field.HTMCS14FBK = 377 pNextTxRate->CurrMCS; 378 break; 379 case 15: 380 HtCfg1.field.HTMCS15FBK = 381 pNextTxRate->CurrMCS; 382 break; 383 default: 384 DBGPRINT(RT_DEBUG_ERROR, 385 ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", 386 pCurrTxRate-> 387 CurrMCS)); 388 } 389 } 390 } 391 break; 392 } 393 394 pNextTxRate = pCurrTxRate; 395 } 396 397 RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word); 398 RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word); 399 RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word); 400 RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word); 401} 402 403/* 404 ======================================================================== 405 406 Routine Description: 407 Set MAC register value according operation mode. 408 OperationMode AND bNonGFExist are for MM and GF Proteciton. 409 If MM or GF mask is not set, those passing argument doesn't not take effect. 410 411 Operation mode meaning: 412 = 0 : Pure HT, no preotection. 413 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS. 414 = 0x10: No Transmission in 40M is protected. 415 = 0x11: Transmission in both 40M and 20M shall be protected 416 if (bNonGFExist) 417 we should choose not to use GF. But still set correct ASIC registers. 418 ======================================================================== 419*/ 420void AsicUpdateProtect(struct rt_rtmp_adapter *pAd, 421 u16 OperationMode, 422 u8 SetMask, 423 IN BOOLEAN bDisableBGProtect, IN BOOLEAN bNonGFExist) 424{ 425 PROT_CFG_STRUC ProtCfg, ProtCfg4; 426 u32 Protect[6]; 427 u16 offset; 428 u8 i; 429 u32 MacReg = 0; 430 431 if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8)) { 432 return; 433 } 434 435 if (pAd->BATable.numDoneOriginator) { 436 /* */ 437 /* enable the RTS/CTS to avoid channel collision */ 438 /* */ 439 SetMask = ALLN_SETPROTECT; 440 OperationMode = 8; 441 } 442 /* Config ASIC RTS threshold register */ 443 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg); 444 MacReg &= 0xFF0000FF; 445 /* If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096 */ 446 if (((pAd->CommonCfg.BACapability.field.AmsduEnable) || 447 (pAd->CommonCfg.bAggregationCapable == TRUE)) 448 && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD) { 449 MacReg |= (0x1000 << 8); 450 } else { 451 MacReg |= (pAd->CommonCfg.RtsThreshold << 8); 452 } 453 454 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg); 455 456 /* Initial common protection settings */ 457 RTMPZeroMemory(Protect, sizeof(Protect)); 458 ProtCfg4.word = 0; 459 ProtCfg.word = 0; 460 ProtCfg.field.TxopAllowGF40 = 1; 461 ProtCfg.field.TxopAllowGF20 = 1; 462 ProtCfg.field.TxopAllowMM40 = 1; 463 ProtCfg.field.TxopAllowMM20 = 1; 464 ProtCfg.field.TxopAllowOfdm = 1; 465 ProtCfg.field.TxopAllowCck = 1; 466 ProtCfg.field.RTSThEn = 1; 467 ProtCfg.field.ProtectNav = ASIC_SHORTNAV; 468 469 /* update PHY mode and rate */ 470 if (pAd->CommonCfg.Channel > 14) 471 ProtCfg.field.ProtectRate = 0x4000; 472 ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate; 473 474 /* Handle legacy(B/G) protection */ 475 if (bDisableBGProtect) { 476 /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */ 477 ProtCfg.field.ProtectCtrl = 0; 478 Protect[0] = ProtCfg.word; 479 Protect[1] = ProtCfg.word; 480 pAd->FlgCtsEnabled = 0; /* CTS-self is not used */ 481 } else { 482 /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */ 483 ProtCfg.field.ProtectCtrl = 0; /* CCK do not need to be protected */ 484 Protect[0] = ProtCfg.word; 485 ProtCfg.field.ProtectCtrl = ASIC_CTS; /* OFDM needs using CCK to protect */ 486 Protect[1] = ProtCfg.word; 487 pAd->FlgCtsEnabled = 1; /* CTS-self is used */ 488 } 489 490 /* Decide HT frame protection. */ 491 if ((SetMask & ALLN_SETPROTECT) != 0) { 492 switch (OperationMode) { 493 case 0x0: 494 /* NO PROTECT */ 495 /* 1.All STAs in the BSS are 20/40 MHz HT */ 496 /* 2. in ai 20/40MHz BSS */ 497 /* 3. all STAs are 20MHz in a 20MHz BSS */ 498 /* Pure HT. no protection. */ 499 500 /* MM20_PROT_CFG */ 501 /* Reserved (31:27) */ 502 /* PROT_TXOP(25:20) -- 010111 */ 503 /* PROT_NAV(19:18) -- 01 (Short NAV protection) */ 504 /* PROT_CTRL(17:16) -- 00 (None) */ 505 /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M) */ 506 Protect[2] = 0x01744004; 507 508 /* MM40_PROT_CFG */ 509 /* Reserved (31:27) */ 510 /* PROT_TXOP(25:20) -- 111111 */ 511 /* PROT_NAV(19:18) -- 01 (Short NAV protection) */ 512 /* PROT_CTRL(17:16) -- 00 (None) */ 513 /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M) */ 514 Protect[3] = 0x03f44084; 515 516 /* CF20_PROT_CFG */ 517 /* Reserved (31:27) */ 518 /* PROT_TXOP(25:20) -- 010111 */ 519 /* PROT_NAV(19:18) -- 01 (Short NAV protection) */ 520 /* PROT_CTRL(17:16) -- 00 (None) */ 521 /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M) */ 522 Protect[4] = 0x01744004; 523 524 /* CF40_PROT_CFG */ 525 /* Reserved (31:27) */ 526 /* PROT_TXOP(25:20) -- 111111 */ 527 /* PROT_NAV(19:18) -- 01 (Short NAV protection) */ 528 /* PROT_CTRL(17:16) -- 00 (None) */ 529 /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M) */ 530 Protect[5] = 0x03f44084; 531 532 if (bNonGFExist) { 533 /* PROT_NAV(19:18) -- 01 (Short NAV protectiion) */ 534 /* PROT_CTRL(17:16) -- 01 (RTS/CTS) */ 535 Protect[4] = 0x01754004; 536 Protect[5] = 0x03f54084; 537 } 538 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; 539 break; 540 541 case 1: 542 /* This is "HT non-member protection mode." */ 543 /* If there may be non-HT STAs my BSS */ 544 ProtCfg.word = 0x01744004; /* PROT_CTRL(17:16) : 0 (None) */ 545 ProtCfg4.word = 0x03f44084; /* duplicaet legacy 24M. BW set 1. */ 546 if (OPSTATUS_TEST_FLAG 547 (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) { 548 ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18.. */ 549 ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */ 550 } 551 /*Assign Protection method for 20&40 MHz packets */ 552 ProtCfg.field.ProtectCtrl = ASIC_RTS; 553 ProtCfg.field.ProtectNav = ASIC_SHORTNAV; 554 ProtCfg4.field.ProtectCtrl = ASIC_RTS; 555 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; 556 Protect[2] = ProtCfg.word; 557 Protect[3] = ProtCfg4.word; 558 Protect[4] = ProtCfg.word; 559 Protect[5] = ProtCfg4.word; 560 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; 561 break; 562 563 case 2: 564 /* If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets */ 565 ProtCfg.word = 0x01744004; /* PROT_CTRL(17:16) : 0 (None) */ 566 ProtCfg4.word = 0x03f44084; /* duplicaet legacy 24M. BW set 1. */ 567 568 /*Assign Protection method for 40MHz packets */ 569 ProtCfg4.field.ProtectCtrl = ASIC_RTS; 570 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; 571 Protect[2] = ProtCfg.word; 572 Protect[3] = ProtCfg4.word; 573 if (bNonGFExist) { 574 ProtCfg.field.ProtectCtrl = ASIC_RTS; 575 ProtCfg.field.ProtectNav = ASIC_SHORTNAV; 576 } 577 Protect[4] = ProtCfg.word; 578 Protect[5] = ProtCfg4.word; 579 580 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; 581 break; 582 583 case 3: 584 /* HT mixed mode. PROTECT ALL! */ 585 /* Assign Rate */ 586 ProtCfg.word = 0x01744004; /*duplicaet legacy 24M. BW set 1. */ 587 ProtCfg4.word = 0x03f44084; 588 /* both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the */ 589 if (OPSTATUS_TEST_FLAG 590 (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) { 591 ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18.. */ 592 ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083 */ 593 } 594 /*Assign Protection method for 20&40 MHz packets */ 595 ProtCfg.field.ProtectCtrl = ASIC_RTS; 596 ProtCfg.field.ProtectNav = ASIC_SHORTNAV; 597 ProtCfg4.field.ProtectCtrl = ASIC_RTS; 598 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; 599 Protect[2] = ProtCfg.word; 600 Protect[3] = ProtCfg4.word; 601 Protect[4] = ProtCfg.word; 602 Protect[5] = ProtCfg4.word; 603 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; 604 break; 605 606 case 8: 607 /* Special on for Atheros problem n chip. */ 608 Protect[2] = 0x01754004; 609 Protect[3] = 0x03f54084; 610 Protect[4] = 0x01754004; 611 Protect[5] = 0x03f54084; 612 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; 613 break; 614 } 615 } 616 617 offset = CCK_PROT_CFG; 618 for (i = 0; i < 6; i++) { 619 if ((SetMask & (1 << i))) { 620 RTMP_IO_WRITE32(pAd, offset + i * 4, Protect[i]); 621 } 622 } 623} 624 625/* 626 ========================================================================== 627 Description: 628 629 IRQL = PASSIVE_LEVEL 630 IRQL = DISPATCH_LEVEL 631 632 ========================================================================== 633 */ 634void AsicSwitchChannel(struct rt_rtmp_adapter *pAd, u8 Channel, IN BOOLEAN bScan) 635{ 636 unsigned long R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0; 637 char TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; /*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER; */ 638 u8 index; 639 u32 Value = 0; /*BbpReg, Value; */ 640 struct rt_rtmp_rf_regs *RFRegTable; 641 u8 RFValue; 642 643 RFValue = 0; 644 /* Search Tx power value */ 645 /* We can't use ChannelList to search channel, since some central channl's txpowr doesn't list */ 646 /* in ChannelList, so use TxPower array instead. */ 647 /* */ 648 for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) { 649 if (Channel == pAd->TxPower[index].Channel) { 650 TxPwer = pAd->TxPower[index].Power; 651 TxPwer2 = pAd->TxPower[index].Power2; 652 break; 653 } 654 } 655 656 if (index == MAX_NUM_OF_CHANNELS) { 657 DBGPRINT(RT_DEBUG_ERROR, 658 ("AsicSwitchChannel: Can't find the Channel#%d \n", 659 Channel)); 660 } 661#ifdef RT30xx 662 /* The RF programming sequence is difference between 3xxx and 2xxx */ 663 if ((IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd)) 664 && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) 665 || (pAd->RfIcType == RFIC_3021) 666 || (pAd->RfIcType == RFIC_3022))) { 667 /* modify by WY for Read RF Reg. error */ 668 669 for (index = 0; index < NUM_OF_3020_CHNL; index++) { 670 if (Channel == FreqItems3020[index].Channel) { 671 /* Programming channel parameters */ 672 RT30xxWriteRFRegister(pAd, RF_R02, 673 FreqItems3020[index].N); 674 RT30xxWriteRFRegister(pAd, RF_R03, 675 FreqItems3020[index].K); 676 RT30xxReadRFRegister(pAd, RF_R06, &RFValue); 677 RFValue = 678 (RFValue & 0xFC) | FreqItems3020[index].R; 679 RT30xxWriteRFRegister(pAd, RF_R06, RFValue); 680 681 /* Set Tx0 Power */ 682 RT30xxReadRFRegister(pAd, RF_R12, &RFValue); 683 RFValue = (RFValue & 0xE0) | TxPwer; 684 RT30xxWriteRFRegister(pAd, RF_R12, RFValue); 685 686 /* Set Tx1 Power */ 687 RT30xxReadRFRegister(pAd, RF_R13, &RFValue); 688 RFValue = (RFValue & 0xE0) | TxPwer2; 689 RT30xxWriteRFRegister(pAd, RF_R13, RFValue); 690 691 /* Tx/Rx Stream setting */ 692 RT30xxReadRFRegister(pAd, RF_R01, &RFValue); 693 /*if (IS_RT3090(pAd)) */ 694 /* RFValue |= 0x01; // Enable RF block. */ 695 RFValue &= 0x03; /*clear bit[7~2] */ 696 if (pAd->Antenna.field.TxPath == 1) 697 RFValue |= 0xA0; 698 else if (pAd->Antenna.field.TxPath == 2) 699 RFValue |= 0x80; 700 if (pAd->Antenna.field.RxPath == 1) 701 RFValue |= 0x50; 702 else if (pAd->Antenna.field.RxPath == 2) 703 RFValue |= 0x40; 704 RT30xxWriteRFRegister(pAd, RF_R01, RFValue); 705 706 /* Set RF offset */ 707 RT30xxReadRFRegister(pAd, RF_R23, &RFValue); 708 RFValue = (RFValue & 0x80) | pAd->RfFreqOffset; 709 RT30xxWriteRFRegister(pAd, RF_R23, RFValue); 710 711 /* Set BW */ 712 if (!bScan 713 && (pAd->CommonCfg.BBPCurrentBW == BW_40)) { 714 RFValue = pAd->Mlme.CaliBW40RfR24; 715 /*DISABLE_11N_CHECK(pAd); */ 716 } else { 717 RFValue = pAd->Mlme.CaliBW20RfR24; 718 } 719 RT30xxWriteRFRegister(pAd, RF_R24, RFValue); 720 RT30xxWriteRFRegister(pAd, RF_R31, RFValue); 721 722 /* Enable RF tuning */ 723 RT30xxReadRFRegister(pAd, RF_R07, &RFValue); 724 RFValue = RFValue | 0x1; 725 RT30xxWriteRFRegister(pAd, RF_R07, RFValue); 726 727 /* latch channel for future usage. */ 728 pAd->LatchRfRegs.Channel = Channel; 729 730 DBGPRINT(RT_DEBUG_TRACE, 731 ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", 732 Channel, pAd->RfIcType, TxPwer, 733 TxPwer2, pAd->Antenna.field.TxPath, 734 FreqItems3020[index].N, 735 FreqItems3020[index].K, 736 FreqItems3020[index].R)); 737 738 break; 739 } 740 } 741 } else 742#endif /* RT30xx // */ 743 { 744 RFRegTable = RF2850RegTable; 745 switch (pAd->RfIcType) { 746 case RFIC_2820: 747 case RFIC_2850: 748 case RFIC_2720: 749 case RFIC_2750: 750 751 for (index = 0; index < NUM_OF_2850_CHNL; index++) { 752 if (Channel == RFRegTable[index].Channel) { 753 R2 = RFRegTable[index].R2; 754 if (pAd->Antenna.field.TxPath == 1) { 755 R2 |= 0x4000; /* If TXpath is 1, bit 14 = 1; */ 756 } 757 758 if (pAd->Antenna.field.RxPath == 2) { 759 R2 |= 0x40; /* write 1 to off Rxpath. */ 760 } else if (pAd->Antenna.field.RxPath == 761 1) { 762 R2 |= 0x20040; /* write 1 to off RxPath */ 763 } 764 765 if (Channel > 14) { 766 /* initialize R3, R4 */ 767 R3 = (RFRegTable[index]. 768 R3 & 0xffffc1ff); 769 R4 = (RFRegTable[index]. 770 R4 & (~0x001f87c0)) | 771 (pAd->RfFreqOffset << 15); 772 773 /* 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB */ 774 /* R3 */ 775 if ((TxPwer >= -7) 776 && (TxPwer < 0)) { 777 TxPwer = (7 + TxPwer); 778 TxPwer = 779 (TxPwer > 780 0xF) ? (0xF) 781 : (TxPwer); 782 R3 |= (TxPwer << 10); 783 DBGPRINT(RT_DEBUG_ERROR, 784 ("AsicSwitchChannel: TxPwer=%d \n", 785 TxPwer)); 786 } else { 787 TxPwer = 788 (TxPwer > 789 0xF) ? (0xF) 790 : (TxPwer); 791 R3 |= 792 (TxPwer << 10) | (1 793 << 794 9); 795 } 796 797 /* R4 */ 798 if ((TxPwer2 >= -7) 799 && (TxPwer2 < 0)) { 800 TxPwer2 = (7 + TxPwer2); 801 TxPwer2 = 802 (TxPwer2 > 803 0xF) ? (0xF) 804 : (TxPwer2); 805 R4 |= (TxPwer2 << 7); 806 DBGPRINT(RT_DEBUG_ERROR, 807 ("AsicSwitchChannel: TxPwer2=%d \n", 808 TxPwer2)); 809 } else { 810 TxPwer2 = 811 (TxPwer2 > 812 0xF) ? (0xF) 813 : (TxPwer2); 814 R4 |= 815 (TxPwer2 << 7) | (1 816 << 817 6); 818 } 819 } else { 820 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); /* set TX power0 */ 821 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 << 6); /* Set freq Offset & TxPwr1 */ 822 } 823 824 /* Based on BBP current mode before changing RF channel. */ 825 if (!bScan 826 && (pAd->CommonCfg.BBPCurrentBW == 827 BW_40)) { 828 R4 |= 0x200000; 829 } 830 /* Update variables */ 831 pAd->LatchRfRegs.Channel = Channel; 832 pAd->LatchRfRegs.R1 = 833 RFRegTable[index].R1; 834 pAd->LatchRfRegs.R2 = R2; 835 pAd->LatchRfRegs.R3 = R3; 836 pAd->LatchRfRegs.R4 = R4; 837 838 /* Set RF value 1's set R3[bit2] = [0] */ 839 RTMP_RF_IO_WRITE32(pAd, 840 pAd->LatchRfRegs.R1); 841 RTMP_RF_IO_WRITE32(pAd, 842 pAd->LatchRfRegs.R2); 843 RTMP_RF_IO_WRITE32(pAd, 844 (pAd->LatchRfRegs. 845 R3 & (~0x04))); 846 RTMP_RF_IO_WRITE32(pAd, 847 pAd->LatchRfRegs.R4); 848 849 RTMPusecDelay(200); 850 851 /* Set RF value 2's set R3[bit2] = [1] */ 852 RTMP_RF_IO_WRITE32(pAd, 853 pAd->LatchRfRegs.R1); 854 RTMP_RF_IO_WRITE32(pAd, 855 pAd->LatchRfRegs.R2); 856 RTMP_RF_IO_WRITE32(pAd, 857 (pAd->LatchRfRegs. 858 R3 | 0x04)); 859 RTMP_RF_IO_WRITE32(pAd, 860 pAd->LatchRfRegs.R4); 861 862 RTMPusecDelay(200); 863 864 /* Set RF value 3's set R3[bit2] = [0] */ 865 RTMP_RF_IO_WRITE32(pAd, 866 pAd->LatchRfRegs.R1); 867 RTMP_RF_IO_WRITE32(pAd, 868 pAd->LatchRfRegs.R2); 869 RTMP_RF_IO_WRITE32(pAd, 870 (pAd->LatchRfRegs. 871 R3 & (~0x04))); 872 RTMP_RF_IO_WRITE32(pAd, 873 pAd->LatchRfRegs.R4); 874 875 break; 876 } 877 } 878 break; 879 880 default: 881 break; 882 } 883 884 DBGPRINT(RT_DEBUG_TRACE, 885 ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n", 886 Channel, pAd->RfIcType, (R3 & 0x00003e00) >> 9, 887 (R4 & 0x000007c0) >> 6, pAd->Antenna.field.TxPath, 888 pAd->LatchRfRegs.R1, pAd->LatchRfRegs.R2, 889 pAd->LatchRfRegs.R3, pAd->LatchRfRegs.R4)); 890 } 891 892 /* Change BBP setting during siwtch from a->g, g->a */ 893 if (Channel <= 14) { 894 unsigned long TxPinCfg = 0x00050F0A; /*Gary 2007/08/09 0x050A0A */ 895 896 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, 897 (0x37 - GET_LNA_GAIN(pAd))); 898 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, 899 (0x37 - GET_LNA_GAIN(pAd))); 900 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, 901 (0x37 - GET_LNA_GAIN(pAd))); 902 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0); /*(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue. */ 903 /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); */ 904 905 /* Rx High power VGA offset for LNA select */ 906 if (pAd->NicConfig2.field.ExternalLNAForG) { 907 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); 908 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); 909 } else { 910 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84); 911 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); 912 } 913 914 /* 5G band selection PIN, bit1 and bit2 are complement */ 915 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); 916 Value &= (~0x6); 917 Value |= (0x04); 918 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); 919 920 /* Turn off unused PA or LNA when only 1T or 1R */ 921 if (pAd->Antenna.field.TxPath == 1) { 922 TxPinCfg &= 0xFFFFFFF3; 923 } 924 if (pAd->Antenna.field.RxPath == 1) { 925 TxPinCfg &= 0xFFFFF3FF; 926 } 927 928 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); 929 930#if defined(RT3090) || defined(RT3390) 931 /* PCIe PHY Transmit attenuation adjustment */ 932 if (IS_RT3090A(pAd) || IS_RT3390(pAd)) { 933 TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = { 934 .word = 0}; 935 936 RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, 937 &TxAttenuationCtrl.word); 938 939 if (Channel == 14) /* Channel #14 */ 940 { 941 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1; /* Enable PCIe PHY Tx attenuation */ 942 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4; /* 9/16 full drive level */ 943 } else /* Channel #1~#13 */ 944 { 945 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0; /* Disable PCIe PHY Tx attenuation */ 946 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0; /* n/a */ 947 } 948 949 RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, 950 TxAttenuationCtrl.word); 951 } 952#endif 953 } else { 954 unsigned long TxPinCfg = 0x00050F05; /*Gary 2007/8/9 0x050505 */ 955 956 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, 957 (0x37 - GET_LNA_GAIN(pAd))); 958 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, 959 (0x37 - GET_LNA_GAIN(pAd))); 960 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, 961 (0x37 - GET_LNA_GAIN(pAd))); 962 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0); /*(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue. */ 963 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2); 964 965 /* Rx High power VGA offset for LNA select */ 966 if (pAd->NicConfig2.field.ExternalLNAForA) { 967 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); 968 } else { 969 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); 970 } 971 972 /* 5G band selection PIN, bit1 and bit2 are complement */ 973 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); 974 Value &= (~0x6); 975 Value |= (0x02); 976 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); 977 978 /* Turn off unused PA or LNA when only 1T or 1R */ 979 if (pAd->Antenna.field.TxPath == 1) { 980 TxPinCfg &= 0xFFFFFFF3; 981 } 982 if (pAd->Antenna.field.RxPath == 1) { 983 TxPinCfg &= 0xFFFFF3FF; 984 } 985 986 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); 987 988 } 989 990 /* R66 should be set according to Channel and use 20MHz when scanning */ 991 /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd))); */ 992 if (bScan) 993 RTMPSetAGCInitValue(pAd, BW_20); 994 else 995 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); 996 997 /* */ 998 /* On 11A, We should delay and wait RF/BBP to be stable */ 999 /* and the appropriate time should be 1000 micro seconds */ 1000 /* 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. */ 1001 /* */ 1002 RTMPusecDelay(1000); 1003} 1004 1005void AsicResetBBPAgent(struct rt_rtmp_adapter *pAd) 1006{ 1007 BBP_CSR_CFG_STRUC BbpCsr; 1008 DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit!\n")); 1009 /* Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first. */ 1010 RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word); 1011 BbpCsr.field.Busy = 0; 1012 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word); 1013} 1014 1015/* 1016 ========================================================================== 1017 Description: 1018 This function is required for 2421 only, and should not be used during 1019 site survey. It's only required after NIC decided to stay at a channel 1020 for a longer period. 1021 When this function is called, it's always after AsicSwitchChannel(). 1022 1023 IRQL = PASSIVE_LEVEL 1024 IRQL = DISPATCH_LEVEL 1025 1026 ========================================================================== 1027 */ 1028void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel) 1029{ 1030} 1031 1032void AsicRfTuningExec(void *SystemSpecific1, 1033 void *FunctionContext, 1034 void *SystemSpecific2, void *SystemSpecific3) 1035{ 1036} 1037 1038/* 1039 ========================================================================== 1040 Description: 1041 Gives CCK TX rate 2 more dB TX power. 1042 This routine works only in LINK UP in INFRASTRUCTURE mode. 1043 1044 calculate desired Tx power in RF R3.Tx0~5, should consider - 1045 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment) 1046 1. TxPowerPercentage 1047 2. auto calibration based on TSSI feedback 1048 3. extra 2 db for CCK 1049 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP 1050 1051 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment), 1052 it should be called AFTER MlmeDynamicTxRatSwitching() 1053 ========================================================================== 1054 */ 1055void AsicAdjustTxPower(struct rt_rtmp_adapter *pAd) 1056{ 1057 int i, j; 1058 char DeltaPwr = 0; 1059 BOOLEAN bAutoTxAgc = FALSE; 1060 u8 TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep; 1061 u8 BbpR1 = 0, BbpR49 = 0, idx; 1062 char *pTxAgcCompensate; 1063 unsigned long TxPwr[5]; 1064 char Value; 1065 char Rssi = -127; 1066 1067 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) || 1068#ifdef RTMP_MAC_PCI 1069 (pAd->bPCIclkOff == TRUE) || 1070#endif /* RTMP_MAC_PCI // */ 1071 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) || 1072 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) 1073 return; 1074 1075 Rssi = RTMPMaxRssi(pAd, 1076 pAd->StaCfg.RssiSample.AvgRssi0, 1077 pAd->StaCfg.RssiSample.AvgRssi1, 1078 pAd->StaCfg.RssiSample.AvgRssi2); 1079 1080 if (pAd->CommonCfg.BBPCurrentBW == BW_40) { 1081 if (pAd->CommonCfg.CentralChannel > 14) { 1082 TxPwr[0] = pAd->Tx40MPwrCfgABand[0]; 1083 TxPwr[1] = pAd->Tx40MPwrCfgABand[1]; 1084 TxPwr[2] = pAd->Tx40MPwrCfgABand[2]; 1085 TxPwr[3] = pAd->Tx40MPwrCfgABand[3]; 1086 TxPwr[4] = pAd->Tx40MPwrCfgABand[4]; 1087 } else { 1088 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0]; 1089 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1]; 1090 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2]; 1091 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3]; 1092 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4]; 1093 } 1094 } else { 1095 if (pAd->CommonCfg.Channel > 14) { 1096 TxPwr[0] = pAd->Tx20MPwrCfgABand[0]; 1097 TxPwr[1] = pAd->Tx20MPwrCfgABand[1]; 1098 TxPwr[2] = pAd->Tx20MPwrCfgABand[2]; 1099 TxPwr[3] = pAd->Tx20MPwrCfgABand[3]; 1100 TxPwr[4] = pAd->Tx20MPwrCfgABand[4]; 1101 } else { 1102 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0]; 1103 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1]; 1104 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2]; 1105 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3]; 1106 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4]; 1107 } 1108 } 1109 1110 /* TX power compensation for temperature variation based on TSSI. try every 4 second */ 1111 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) { 1112 if (pAd->CommonCfg.Channel <= 14) { 1113 /* bg channel */ 1114 bAutoTxAgc = pAd->bAutoTxAgcG; 1115 TssiRef = pAd->TssiRefG; 1116 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0]; 1117 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0]; 1118 TxAgcStep = pAd->TxAgcStepG; 1119 pTxAgcCompensate = &pAd->TxAgcCompensateG; 1120 } else { 1121 /* a channel */ 1122 bAutoTxAgc = pAd->bAutoTxAgcA; 1123 TssiRef = pAd->TssiRefA; 1124 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0]; 1125 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0]; 1126 TxAgcStep = pAd->TxAgcStepA; 1127 pTxAgcCompensate = &pAd->TxAgcCompensateA; 1128 } 1129 1130 if (bAutoTxAgc) { 1131 /* BbpR1 is unsigned char */ 1132 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); 1133 1134 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */ 1135 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */ 1136 /* step value is defined in pAd->TxAgcStepG for tx power value */ 1137 1138 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */ 1139 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0 1140 above value are examined in mass factory production */ 1141 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */ 1142 1143 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */ 1144 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */ 1145 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */ 1146 1147 if (BbpR49 > pTssiMinusBoundary[1]) { 1148 /* Reading is larger than the reference value */ 1149 /* check for how large we need to decrease the Tx power */ 1150 for (idx = 1; idx < 5; idx++) { 1151 if (BbpR49 <= pTssiMinusBoundary[idx]) /* Found the range */ 1152 break; 1153 } 1154 /* The index is the step we should decrease, idx = 0 means there is nothing to compensate */ 1155/* if (R3 > (unsigned long)(TxAgcStep * (idx-1))) */ 1156 *pTxAgcCompensate = -(TxAgcStep * (idx - 1)); 1157/* else */ 1158/* *pTxAgcCompensate = -((u8)R3); */ 1159 1160 DeltaPwr += (*pTxAgcCompensate); 1161 DBGPRINT(RT_DEBUG_TRACE, 1162 ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n", 1163 BbpR49, TssiRef, TxAgcStep, idx - 1)); 1164 } else if (BbpR49 < pTssiPlusBoundary[1]) { 1165 /* Reading is smaller than the reference value */ 1166 /* check for how large we need to increase the Tx power */ 1167 for (idx = 1; idx < 5; idx++) { 1168 if (BbpR49 >= pTssiPlusBoundary[idx]) /* Found the range */ 1169 break; 1170 } 1171 /* The index is the step we should increase, idx = 0 means there is nothing to compensate */ 1172 *pTxAgcCompensate = TxAgcStep * (idx - 1); 1173 DeltaPwr += (*pTxAgcCompensate); 1174 DBGPRINT(RT_DEBUG_TRACE, 1175 ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", 1176 BbpR49, TssiRef, TxAgcStep, idx - 1)); 1177 } else { 1178 *pTxAgcCompensate = 0; 1179 DBGPRINT(RT_DEBUG_TRACE, 1180 (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", 1181 BbpR49, TssiRef, TxAgcStep, 0)); 1182 } 1183 } 1184 } else { 1185 if (pAd->CommonCfg.Channel <= 14) { 1186 bAutoTxAgc = pAd->bAutoTxAgcG; 1187 pTxAgcCompensate = &pAd->TxAgcCompensateG; 1188 } else { 1189 bAutoTxAgc = pAd->bAutoTxAgcA; 1190 pTxAgcCompensate = &pAd->TxAgcCompensateA; 1191 } 1192 1193 if (bAutoTxAgc) 1194 DeltaPwr += (*pTxAgcCompensate); 1195 } 1196 1197 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1); 1198 BbpR1 &= 0xFC; 1199 1200 /* calculate delta power based on the percentage specified from UI */ 1201 /* E2PROM setting is calibrated for maximum TX power (i.e. 100%) */ 1202 /* We lower TX power here according to the percentage specified from UI */ 1203 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) /* AUTO TX POWER control */ 1204 { 1205 { 1206 /* to patch high power issue with some APs, like Belkin N1. */ 1207 if (Rssi > -35) { 1208 BbpR1 |= 0x02; /* DeltaPwr -= 12; */ 1209 } else if (Rssi > -40) { 1210 BbpR1 |= 0x01; /* DeltaPwr -= 6; */ 1211 } else; 1212 } 1213 } else if (pAd->CommonCfg.TxPowerPercentage > 90) /* 91 ~ 100% & AUTO, treat as 100% in terms of mW */ 1214 ; 1215 else if (pAd->CommonCfg.TxPowerPercentage > 60) /* 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1; */ 1216 { 1217 DeltaPwr -= 1; 1218 } else if (pAd->CommonCfg.TxPowerPercentage > 30) /* 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3; */ 1219 { 1220 DeltaPwr -= 3; 1221 } else if (pAd->CommonCfg.TxPowerPercentage > 15) /* 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6; */ 1222 { 1223 BbpR1 |= 0x01; 1224 } else if (pAd->CommonCfg.TxPowerPercentage > 9) /* 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9; */ 1225 { 1226 BbpR1 |= 0x01; 1227 DeltaPwr -= 3; 1228 } else /* 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12; */ 1229 { 1230 BbpR1 |= 0x02; 1231 } 1232 1233 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1); 1234 1235 /* reset different new tx power for different TX rate */ 1236 for (i = 0; i < 5; i++) { 1237 if (TxPwr[i] != 0xffffffff) { 1238 for (j = 0; j < 8; j++) { 1239 Value = (char)((TxPwr[i] >> j * 4) & 0x0F); /* 0 ~ 15 */ 1240 1241 if ((Value + DeltaPwr) < 0) { 1242 Value = 0; /* min */ 1243 } else if ((Value + DeltaPwr) > 0xF) { 1244 Value = 0xF; /* max */ 1245 } else { 1246 Value += DeltaPwr; /* temperature compensation */ 1247 } 1248 1249 /* fill new value to CSR offset */ 1250 TxPwr[i] = 1251 (TxPwr[i] & ~(0x0000000F << j * 4)) | (Value 1252 << j 1253 * 4); 1254 } 1255 1256 /* write tx power value to CSR */ 1257 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M 1258 TX power for OFDM 6M/9M 1259 TX power for CCK5.5M/11M 1260 TX power for CCK1M/2M */ 1261 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */ 1262 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, TxPwr[i]); 1263 } 1264 } 1265 1266} 1267 1268/* 1269 ========================================================================== 1270 Description: 1271 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup 1272 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after 1273 the wakeup timer timeout. Driver has to issue a separate command to wake 1274 PHY up. 1275 1276 IRQL = DISPATCH_LEVEL 1277 1278 ========================================================================== 1279 */ 1280void AsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd, 1281 u16 TbttNumToNextWakeUp) 1282{ 1283 RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp); 1284} 1285 1286/* 1287 ========================================================================== 1288 Description: 1289 AsicForceWakeup() is used whenever manual wakeup is required 1290 AsicForceSleep() should only be used when not in INFRA BSS. When 1291 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead. 1292 ========================================================================== 1293 */ 1294void AsicForceSleep(struct rt_rtmp_adapter *pAd) 1295{ 1296 1297} 1298 1299/* 1300 ========================================================================== 1301 Description: 1302 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup) 1303 expired. 1304 1305 IRQL = PASSIVE_LEVEL 1306 IRQL = DISPATCH_LEVEL 1307 ========================================================================== 1308 */ 1309void AsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx) 1310{ 1311 DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n")); 1312 RTMP_STA_FORCE_WAKEUP(pAd, bFromTx); 1313} 1314 1315/* 1316 ========================================================================== 1317 Description: 1318 Set My BSSID 1319 1320 IRQL = DISPATCH_LEVEL 1321 1322 ========================================================================== 1323 */ 1324void AsicSetBssid(struct rt_rtmp_adapter *pAd, u8 *pBssid) 1325{ 1326 unsigned long Addr4; 1327 DBGPRINT(RT_DEBUG_TRACE, 1328 ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n", pBssid[0], 1329 pBssid[1], pBssid[2], pBssid[3], pBssid[4], pBssid[5])); 1330 1331 Addr4 = (unsigned long)(pBssid[0]) | 1332 (unsigned long)(pBssid[1] << 8) | 1333 (unsigned long)(pBssid[2] << 16) | (unsigned long)(pBssid[3] << 24); 1334 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4); 1335 1336 Addr4 = 0; 1337 /* always one BSSID in STA mode */ 1338 Addr4 = (unsigned long)(pBssid[4]) | (unsigned long)(pBssid[5] << 8); 1339 1340 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4); 1341} 1342 1343void AsicSetMcastWC(struct rt_rtmp_adapter *pAd) 1344{ 1345 struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[MCAST_WCID]; 1346 u16 offset; 1347 1348 pEntry->Sst = SST_ASSOC; 1349 pEntry->Aid = MCAST_WCID; /* Softap supports 1 BSSID and use WCID=0 as multicast Wcid index */ 1350 pEntry->PsMode = PWR_ACTIVE; 1351 pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate; 1352 offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE; 1353} 1354 1355/* 1356 ========================================================================== 1357 Description: 1358 1359 IRQL = DISPATCH_LEVEL 1360 1361 ========================================================================== 1362 */ 1363void AsicDelWcidTab(struct rt_rtmp_adapter *pAd, u8 Wcid) 1364{ 1365 unsigned long Addr0 = 0x0, Addr1 = 0x0; 1366 unsigned long offset; 1367 1368 DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n", Wcid)); 1369 offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE; 1370 RTMP_IO_WRITE32(pAd, offset, Addr0); 1371 offset += 4; 1372 RTMP_IO_WRITE32(pAd, offset, Addr1); 1373} 1374 1375/* 1376 ========================================================================== 1377 Description: 1378 1379 IRQL = DISPATCH_LEVEL 1380 1381 ========================================================================== 1382 */ 1383void AsicEnableRDG(struct rt_rtmp_adapter *pAd) 1384{ 1385 TX_LINK_CFG_STRUC TxLinkCfg; 1386 u32 Data = 0; 1387 1388 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); 1389 TxLinkCfg.field.TxRDGEn = 1; 1390 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); 1391 1392 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); 1393 Data &= 0xFFFFFF00; 1394 Data |= 0x80; 1395 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); 1396 1397 /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); */ 1398} 1399 1400/* 1401 ========================================================================== 1402 Description: 1403 1404 IRQL = DISPATCH_LEVEL 1405 1406 ========================================================================== 1407 */ 1408void AsicDisableRDG(struct rt_rtmp_adapter *pAd) 1409{ 1410 TX_LINK_CFG_STRUC TxLinkCfg; 1411 u32 Data = 0; 1412 1413 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); 1414 TxLinkCfg.field.TxRDGEn = 0; 1415 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); 1416 1417 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); 1418 1419 Data &= 0xFFFFFF00; 1420 /*Data |= 0x20; */ 1421#ifndef WIFI_TEST 1422 /*if ( pAd->CommonCfg.bEnableTxBurst ) */ 1423 /* Data |= 0x60; // for performance issue not set the TXOP to 0 */ 1424#endif 1425 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE) 1426 && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE) 1427 ) { 1428 /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */ 1429 if (pAd->CommonCfg.bEnableTxBurst) 1430 Data |= 0x20; 1431 } 1432 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); 1433} 1434 1435/* 1436 ========================================================================== 1437 Description: 1438 1439 IRQL = PASSIVE_LEVEL 1440 IRQL = DISPATCH_LEVEL 1441 1442 ========================================================================== 1443 */ 1444void AsicDisableSync(struct rt_rtmp_adapter *pAd) 1445{ 1446 BCN_TIME_CFG_STRUC csr; 1447 1448 DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n")); 1449 1450 /* 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect */ 1451 /* that NIC will never wakes up because TSF stops and no more */ 1452 /* TBTT interrupts */ 1453 pAd->TbttTickCount = 0; 1454 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); 1455 csr.field.bBeaconGen = 0; 1456 csr.field.bTBTTEnable = 0; 1457 csr.field.TsfSyncMode = 0; 1458 csr.field.bTsfTicking = 0; 1459 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); 1460 1461} 1462 1463/* 1464 ========================================================================== 1465 Description: 1466 1467 IRQL = DISPATCH_LEVEL 1468 1469 ========================================================================== 1470 */ 1471void AsicEnableBssSync(struct rt_rtmp_adapter *pAd) 1472{ 1473 BCN_TIME_CFG_STRUC csr; 1474 1475 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n")); 1476 1477 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); 1478/* RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000); */ 1479 { 1480 csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU */ 1481 csr.field.bTsfTicking = 1; 1482 csr.field.TsfSyncMode = 1; /* sync TSF in INFRASTRUCTURE mode */ 1483 csr.field.bBeaconGen = 0; /* do NOT generate BEACON */ 1484 csr.field.bTBTTEnable = 1; 1485 } 1486 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); 1487} 1488 1489/* 1490 ========================================================================== 1491 Description: 1492 Note: 1493 BEACON frame in shared memory should be built ok before this routine 1494 can be called. Otherwise, a garbage frame maybe transmitted out every 1495 Beacon period. 1496 1497 IRQL = DISPATCH_LEVEL 1498 1499 ========================================================================== 1500 */ 1501void AsicEnableIbssSync(struct rt_rtmp_adapter *pAd) 1502{ 1503 BCN_TIME_CFG_STRUC csr9; 1504 u8 *ptr; 1505 u32 i; 1506 1507 DBGPRINT(RT_DEBUG_TRACE, 1508 ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", 1509 pAd->BeaconTxWI.MPDUtotalByteCount)); 1510 1511 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word); 1512 csr9.field.bBeaconGen = 0; 1513 csr9.field.bTBTTEnable = 0; 1514 csr9.field.bTsfTicking = 0; 1515 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word); 1516 1517#ifdef RTMP_MAC_PCI 1518 /* move BEACON TXD and frame content to on-chip memory */ 1519 ptr = (u8 *)& pAd->BeaconTxWI; 1520 for (i = 0; i < TXWI_SIZE; i += 4) /* 16-byte TXWI field */ 1521 { 1522 u32 longptr = 1523 *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) + 1524 (*(ptr + 3) << 24); 1525 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr); 1526 ptr += 4; 1527 } 1528 1529 /* start right after the 16-byte TXWI field */ 1530 ptr = pAd->BeaconBuf; 1531 for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 4) { 1532 u32 longptr = 1533 *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) + 1534 (*(ptr + 3) << 24); 1535 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); 1536 ptr += 4; 1537 } 1538#endif /* RTMP_MAC_PCI // */ 1539#ifdef RTMP_MAC_USB 1540 /* move BEACON TXD and frame content to on-chip memory */ 1541 ptr = (u8 *)& pAd->BeaconTxWI; 1542 for (i = 0; i < TXWI_SIZE; i += 2) /* 16-byte TXWI field */ 1543 { 1544 /*u32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */ 1545 /*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr); */ 1546 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2); 1547 ptr += 2; 1548 } 1549 1550 /* start right after the 16-byte TXWI field */ 1551 ptr = pAd->BeaconBuf; 1552 for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 2) { 1553 /*u32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */ 1554 /*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); */ 1555 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2); 1556 ptr += 2; 1557 } 1558#endif /* RTMP_MAC_USB // */ 1559 1560 /* */ 1561 /* For Wi-Fi faily generated beacons between participating stations. */ 1562 /* Set TBTT phase adaptive adjustment step to 8us (default 16us) */ 1563 /* don't change settings 2006-5- by Jerry */ 1564 /*RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010); */ 1565 1566 /* start sending BEACON */ 1567 csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU */ 1568 csr9.field.bTsfTicking = 1; 1569 csr9.field.TsfSyncMode = 2; /* sync TSF in IBSS mode */ 1570 csr9.field.bTBTTEnable = 1; 1571 csr9.field.bBeaconGen = 1; 1572 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word); 1573} 1574 1575/* 1576 ========================================================================== 1577 Description: 1578 1579 IRQL = PASSIVE_LEVEL 1580 IRQL = DISPATCH_LEVEL 1581 1582 ========================================================================== 1583 */ 1584void AsicSetEdcaParm(struct rt_rtmp_adapter *pAd, struct rt_edca_parm *pEdcaParm) 1585{ 1586 EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg; 1587 AC_TXOP_CSR0_STRUC csr0; 1588 AC_TXOP_CSR1_STRUC csr1; 1589 AIFSN_CSR_STRUC AifsnCsr; 1590 CWMIN_CSR_STRUC CwminCsr; 1591 CWMAX_CSR_STRUC CwmaxCsr; 1592 int i; 1593 1594 Ac0Cfg.word = 0; 1595 Ac1Cfg.word = 0; 1596 Ac2Cfg.word = 0; 1597 Ac3Cfg.word = 0; 1598 if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE)) { 1599 DBGPRINT(RT_DEBUG_TRACE, ("AsicSetEdcaParm\n")); 1600 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED); 1601 for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { 1602 if (pAd->MacTab.Content[i].ValidAsCLI 1603 || pAd->MacTab.Content[i].ValidAsApCli) 1604 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab. 1605 Content[i], 1606 fCLIENT_STATUS_WMM_CAPABLE); 1607 } 1608 1609 /*======================================================== */ 1610 /* MAC Register has a copy . */ 1611 /*======================================================== */ 1612/*#ifndef WIFI_TEST */ 1613 if (pAd->CommonCfg.bEnableTxBurst) { 1614 /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */ 1615 Ac0Cfg.field.AcTxop = 0x20; /* Suggest by John for TxBurst in HT Mode */ 1616 } else 1617 Ac0Cfg.field.AcTxop = 0; /* QID_AC_BE */ 1618/*#else */ 1619/* Ac0Cfg.field.AcTxop = 0; // QID_AC_BE */ 1620/*#endif */ 1621 Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS; 1622 Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS; 1623 Ac0Cfg.field.Aifsn = 2; 1624 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); 1625 1626 Ac1Cfg.field.AcTxop = 0; /* QID_AC_BK */ 1627 Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS; 1628 Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS; 1629 Ac1Cfg.field.Aifsn = 2; 1630 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); 1631 1632 if (pAd->CommonCfg.PhyMode == PHY_11B) { 1633 Ac2Cfg.field.AcTxop = 192; /* AC_VI: 192*32us ~= 6ms */ 1634 Ac3Cfg.field.AcTxop = 96; /* AC_VO: 96*32us ~= 3ms */ 1635 } else { 1636 Ac2Cfg.field.AcTxop = 96; /* AC_VI: 96*32us ~= 3ms */ 1637 Ac3Cfg.field.AcTxop = 48; /* AC_VO: 48*32us ~= 1.5ms */ 1638 } 1639 Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS; 1640 Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS; 1641 Ac2Cfg.field.Aifsn = 2; 1642 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word); 1643 Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS; 1644 Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS; 1645 Ac3Cfg.field.Aifsn = 2; 1646 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word); 1647 1648 /*======================================================== */ 1649 /* DMA Register has a copy too. */ 1650 /*======================================================== */ 1651 csr0.field.Ac0Txop = 0; /* QID_AC_BE */ 1652 csr0.field.Ac1Txop = 0; /* QID_AC_BK */ 1653 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); 1654 if (pAd->CommonCfg.PhyMode == PHY_11B) { 1655 csr1.field.Ac2Txop = 192; /* AC_VI: 192*32us ~= 6ms */ 1656 csr1.field.Ac3Txop = 96; /* AC_VO: 96*32us ~= 3ms */ 1657 } else { 1658 csr1.field.Ac2Txop = 96; /* AC_VI: 96*32us ~= 3ms */ 1659 csr1.field.Ac3Txop = 48; /* AC_VO: 48*32us ~= 1.5ms */ 1660 } 1661 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word); 1662 1663 CwminCsr.word = 0; 1664 CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS; 1665 CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS; 1666 CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS; 1667 CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS; 1668 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word); 1669 1670 CwmaxCsr.word = 0; 1671 CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS; 1672 CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS; 1673 CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS; 1674 CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS; 1675 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word); 1676 1677 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222); 1678 1679 NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(struct rt_edca_parm)); 1680 } else { 1681 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED); 1682 /*======================================================== */ 1683 /* MAC Register has a copy. */ 1684 /*======================================================== */ 1685 /* */ 1686 /* Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27 */ 1687 /* To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue. */ 1688 /* */ 1689 /*pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this */ 1690 1691 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE]; 1692 Ac0Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BE]; 1693 Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE]; 1694 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; /*+1; */ 1695 1696 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK]; 1697 Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; /*+2; */ 1698 Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK]; 1699 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; /*+1; */ 1700 1701 Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10; 1702 if (pAd->Antenna.field.TxPath == 1) { 1703 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1; 1704 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1; 1705 } else { 1706 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI]; 1707 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI]; 1708 } 1709 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1; 1710#ifdef RTMP_MAC_USB 1711 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3; 1712#endif /* RTMP_MAC_USB // */ 1713 1714 { 1715 /* Tuning for Wi-Fi WMM S06 */ 1716 if (pAd->CommonCfg.bWiFiTest && 1717 pEdcaParm->Aifsn[QID_AC_VI] == 10) 1718 Ac2Cfg.field.Aifsn -= 1; 1719 1720 /* Tuning for TGn Wi-Fi 5.2.32 */ 1721 /* STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta */ 1722 if (STA_TGN_WIFI_ON(pAd) && 1723 pEdcaParm->Aifsn[QID_AC_VI] == 10) { 1724 Ac0Cfg.field.Aifsn = 3; 1725 Ac2Cfg.field.AcTxop = 5; 1726 } 1727#ifdef RT30xx 1728 if (pAd->RfIcType == RFIC_3020 1729 || pAd->RfIcType == RFIC_2020) { 1730 /* Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta. */ 1731 Ac2Cfg.field.Aifsn = 5; 1732 } 1733#endif /* RT30xx // */ 1734 } 1735 1736 Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO]; 1737 Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO]; 1738 Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO]; 1739 Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO]; 1740 1741/*#ifdef WIFI_TEST */ 1742 if (pAd->CommonCfg.bWiFiTest) { 1743 if (Ac3Cfg.field.AcTxop == 102) { 1744 Ac0Cfg.field.AcTxop = 1745 pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm-> 1746 Txop[QID_AC_BE] : 10; 1747 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE] - 1; /* AIFSN must >= 1 */ 1748 Ac1Cfg.field.AcTxop = 1749 pEdcaParm->Txop[QID_AC_BK]; 1750 Ac1Cfg.field.Aifsn = 1751 pEdcaParm->Aifsn[QID_AC_BK]; 1752 Ac2Cfg.field.AcTxop = 1753 pEdcaParm->Txop[QID_AC_VI]; 1754 } /* End of if */ 1755 } 1756/*#endif // WIFI_TEST // */ 1757 1758 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); 1759 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); 1760 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word); 1761 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word); 1762 1763 /*======================================================== */ 1764 /* DMA Register has a copy too. */ 1765 /*======================================================== */ 1766 csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop; 1767 csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop; 1768 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); 1769 1770 csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop; 1771 csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop; 1772 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word); 1773 1774 CwminCsr.word = 0; 1775 CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE]; 1776 CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK]; 1777 CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI]; 1778 CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; /*for TGn wifi test */ 1779 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word); 1780 1781 CwmaxCsr.word = 0; 1782 CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE]; 1783 CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK]; 1784 CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI]; 1785 CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO]; 1786 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word); 1787 1788 AifsnCsr.word = 0; 1789 AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_BE]; */ 1790 AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_BK]; */ 1791 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_VI]; */ 1792 1793 { 1794 /* Tuning for Wi-Fi WMM S06 */ 1795 if (pAd->CommonCfg.bWiFiTest && 1796 pEdcaParm->Aifsn[QID_AC_VI] == 10) 1797 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4; 1798 1799 /* Tuning for TGn Wi-Fi 5.2.32 */ 1800 /* STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta */ 1801 if (STA_TGN_WIFI_ON(pAd) && 1802 pEdcaParm->Aifsn[QID_AC_VI] == 10) { 1803 AifsnCsr.field.Aifsn0 = 3; 1804 AifsnCsr.field.Aifsn2 = 7; 1805 } 1806 1807 if (INFRA_ON(pAd)) 1808 CLIENT_STATUS_SET_FLAG(&pAd->MacTab. 1809 Content[BSSID_WCID], 1810 fCLIENT_STATUS_WMM_CAPABLE); 1811 } 1812 1813 { 1814 AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; /*pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test */ 1815#ifdef RT30xx 1816 /* TODO: Shiang, this modification also suitable for RT3052/RT3050 ??? */ 1817 if (pAd->RfIcType == RFIC_3020 1818 || pAd->RfIcType == RFIC_2020) { 1819 AifsnCsr.field.Aifsn2 = 0x2; /*pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04. */ 1820 } 1821#endif /* RT30xx // */ 1822 } 1823 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word); 1824 1825 NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, 1826 sizeof(struct rt_edca_parm)); 1827 if (!ADHOC_ON(pAd)) { 1828 DBGPRINT(RT_DEBUG_TRACE, 1829 ("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", 1830 pEdcaParm->EdcaUpdateCount)); 1831 DBGPRINT(RT_DEBUG_TRACE, 1832 (" AC_BE %2d %2d %2d %4d %d\n", 1833 pEdcaParm->Aifsn[0], pEdcaParm->Cwmin[0], 1834 pEdcaParm->Cwmax[0], pEdcaParm->Txop[0] << 5, 1835 pEdcaParm->bACM[0])); 1836 DBGPRINT(RT_DEBUG_TRACE, 1837 (" AC_BK %2d %2d %2d %4d %d\n", 1838 pEdcaParm->Aifsn[1], pEdcaParm->Cwmin[1], 1839 pEdcaParm->Cwmax[1], pEdcaParm->Txop[1] << 5, 1840 pEdcaParm->bACM[1])); 1841 DBGPRINT(RT_DEBUG_TRACE, 1842 (" AC_VI %2d %2d %2d %4d %d\n", 1843 pEdcaParm->Aifsn[2], pEdcaParm->Cwmin[2], 1844 pEdcaParm->Cwmax[2], pEdcaParm->Txop[2] << 5, 1845 pEdcaParm->bACM[2])); 1846 DBGPRINT(RT_DEBUG_TRACE, 1847 (" AC_VO %2d %2d %2d %4d %d\n", 1848 pEdcaParm->Aifsn[3], pEdcaParm->Cwmin[3], 1849 pEdcaParm->Cwmax[3], pEdcaParm->Txop[3] << 5, 1850 pEdcaParm->bACM[3])); 1851 } 1852 } 1853 1854} 1855 1856/* 1857 ========================================================================== 1858 Description: 1859 1860 IRQL = PASSIVE_LEVEL 1861 IRQL = DISPATCH_LEVEL 1862 1863 ========================================================================== 1864 */ 1865void AsicSetSlotTime(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUseShortSlotTime) 1866{ 1867 unsigned long SlotTime; 1868 u32 RegValue = 0; 1869 1870 if (pAd->CommonCfg.Channel > 14) 1871 bUseShortSlotTime = TRUE; 1872 1873 if (bUseShortSlotTime 1874 && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)) 1875 return; 1876 else if ((!bUseShortSlotTime) 1877 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))) 1878 return; 1879 1880 if (bUseShortSlotTime) 1881 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); 1882 else 1883 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); 1884 1885 SlotTime = (bUseShortSlotTime) ? 9 : 20; 1886 1887 { 1888 /* force using short SLOT time for FAE to demo performance when TxBurst is ON */ 1889 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) 1890 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))) 1891 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) 1892 && (pAd->CommonCfg.BACapability.field.Policy == 1893 BA_NOTUSE)) 1894 ) { 1895 /* In this case, we will think it is doing Wi-Fi test */ 1896 /* And we will not set to short slot when bEnableTxBurst is TRUE. */ 1897 } else if (pAd->CommonCfg.bEnableTxBurst) { 1898 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); 1899 SlotTime = 9; 1900 } 1901 } 1902 1903 /* */ 1904 /* For some reasons, always set it to short slot time. */ 1905 /* */ 1906 /* ToDo: Should consider capability with 11B */ 1907 /* */ 1908 { 1909 if (pAd->StaCfg.BssType == BSS_ADHOC) { 1910 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); 1911 SlotTime = 20; 1912 } 1913 } 1914 1915 RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue); 1916 RegValue = RegValue & 0xFFFFFF00; 1917 1918 RegValue |= SlotTime; 1919 1920 RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue); 1921} 1922 1923/* 1924 ======================================================================== 1925 Description: 1926 Add Shared key information into ASIC. 1927 Update shared key, TxMic and RxMic to Asic Shared key table 1928 Update its cipherAlg to Asic Shared key Mode. 1929 1930 Return: 1931 ======================================================================== 1932*/ 1933void AsicAddSharedKeyEntry(struct rt_rtmp_adapter *pAd, 1934 u8 BssIndex, 1935 u8 KeyIdx, 1936 u8 CipherAlg, 1937 u8 *pKey, u8 *pTxMic, u8 *pRxMic) 1938{ 1939 unsigned long offset; /*, csr0; */ 1940 SHAREDKEY_MODE_STRUC csr1; 1941#ifdef RTMP_MAC_PCI 1942 int i; 1943#endif /* RTMP_MAC_PCI // */ 1944 1945 DBGPRINT(RT_DEBUG_TRACE, 1946 ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex, 1947 KeyIdx)); 1948/*============================================================================================ */ 1949 1950 DBGPRINT(RT_DEBUG_TRACE, 1951 ("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], 1952 BssIndex * 4 + KeyIdx)); 1953 DBGPRINT_RAW(RT_DEBUG_TRACE, 1954 (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 1955 pKey[0], pKey[1], pKey[2], pKey[3], pKey[4], 1956 pKey[5], pKey[6], pKey[7], pKey[8], pKey[9], 1957 pKey[10], pKey[11], pKey[12], pKey[13], pKey[14], 1958 pKey[15])); 1959 if (pRxMic) { 1960 DBGPRINT_RAW(RT_DEBUG_TRACE, 1961 (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 1962 pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3], 1963 pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7])); 1964 } 1965 if (pTxMic) { 1966 DBGPRINT_RAW(RT_DEBUG_TRACE, 1967 (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 1968 pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3], 1969 pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7])); 1970 } 1971/*============================================================================================ */ 1972 /* */ 1973 /* fill key material - key + TX MIC + RX MIC */ 1974 /* */ 1975#ifdef RTMP_MAC_PCI 1976 offset = 1977 SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE; 1978 for (i = 0; i < MAX_LEN_OF_SHARE_KEY; i++) { 1979 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]); 1980 } 1981 1982 offset += MAX_LEN_OF_SHARE_KEY; 1983 if (pTxMic) { 1984 for (i = 0; i < 8; i++) { 1985 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]); 1986 } 1987 } 1988 1989 offset += 8; 1990 if (pRxMic) { 1991 for (i = 0; i < 8; i++) { 1992 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]); 1993 } 1994 } 1995#endif /* RTMP_MAC_PCI // */ 1996#ifdef RTMP_MAC_USB 1997 { 1998 offset = 1999 SHARED_KEY_TABLE_BASE + (4 * BssIndex + 2000 KeyIdx) * HW_KEY_ENTRY_SIZE; 2001 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY); 2002 2003 offset += MAX_LEN_OF_SHARE_KEY; 2004 if (pTxMic) { 2005 RTUSBMultiWrite(pAd, offset, pTxMic, 8); 2006 } 2007 2008 offset += 8; 2009 if (pRxMic) { 2010 RTUSBMultiWrite(pAd, offset, pRxMic, 8); 2011 } 2012 } 2013#endif /* RTMP_MAC_USB // */ 2014 2015 /* */ 2016 /* Update cipher algorithm. WSTA always use BSS0 */ 2017 /* */ 2018 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), 2019 &csr1.word); 2020 DBGPRINT(RT_DEBUG_TRACE, 2021 ("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", 2022 BssIndex, KeyIdx, csr1.word)); 2023 if ((BssIndex % 2) == 0) { 2024 if (KeyIdx == 0) 2025 csr1.field.Bss0Key0CipherAlg = CipherAlg; 2026 else if (KeyIdx == 1) 2027 csr1.field.Bss0Key1CipherAlg = CipherAlg; 2028 else if (KeyIdx == 2) 2029 csr1.field.Bss0Key2CipherAlg = CipherAlg; 2030 else 2031 csr1.field.Bss0Key3CipherAlg = CipherAlg; 2032 } else { 2033 if (KeyIdx == 0) 2034 csr1.field.Bss1Key0CipherAlg = CipherAlg; 2035 else if (KeyIdx == 1) 2036 csr1.field.Bss1Key1CipherAlg = CipherAlg; 2037 else if (KeyIdx == 2) 2038 csr1.field.Bss1Key2CipherAlg = CipherAlg; 2039 else 2040 csr1.field.Bss1Key3CipherAlg = CipherAlg; 2041 } 2042 DBGPRINT(RT_DEBUG_TRACE, 2043 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", 2044 BssIndex, csr1.word)); 2045 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), 2046 csr1.word); 2047 2048} 2049 2050/* IRQL = DISPATCH_LEVEL */ 2051void AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter *pAd, 2052 u8 BssIndex, u8 KeyIdx) 2053{ 2054 /*unsigned long SecCsr0; */ 2055 SHAREDKEY_MODE_STRUC csr1; 2056 2057 DBGPRINT(RT_DEBUG_TRACE, 2058 ("AsicRemoveSharedKeyEntry: #%d \n", BssIndex * 4 + KeyIdx)); 2059 2060 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), 2061 &csr1.word); 2062 if ((BssIndex % 2) == 0) { 2063 if (KeyIdx == 0) 2064 csr1.field.Bss0Key0CipherAlg = 0; 2065 else if (KeyIdx == 1) 2066 csr1.field.Bss0Key1CipherAlg = 0; 2067 else if (KeyIdx == 2) 2068 csr1.field.Bss0Key2CipherAlg = 0; 2069 else 2070 csr1.field.Bss0Key3CipherAlg = 0; 2071 } else { 2072 if (KeyIdx == 0) 2073 csr1.field.Bss1Key0CipherAlg = 0; 2074 else if (KeyIdx == 1) 2075 csr1.field.Bss1Key1CipherAlg = 0; 2076 else if (KeyIdx == 2) 2077 csr1.field.Bss1Key2CipherAlg = 0; 2078 else 2079 csr1.field.Bss1Key3CipherAlg = 0; 2080 } 2081 DBGPRINT(RT_DEBUG_TRACE, 2082 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", 2083 BssIndex, csr1.word)); 2084 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), 2085 csr1.word); 2086 ASSERT(BssIndex < 4); 2087 ASSERT(KeyIdx < 4); 2088 2089} 2090 2091void AsicUpdateWCIDAttribute(struct rt_rtmp_adapter *pAd, 2092 u16 WCID, 2093 u8 BssIndex, 2094 u8 CipherAlg, 2095 IN BOOLEAN bUsePairewiseKeyTable) 2096{ 2097 unsigned long WCIDAttri = 0, offset; 2098 2099 /* */ 2100 /* Update WCID attribute. */ 2101 /* Only TxKey could update WCID attribute. */ 2102 /* */ 2103 offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE); 2104 WCIDAttri = 2105 (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable); 2106 RTMP_IO_WRITE32(pAd, offset, WCIDAttri); 2107} 2108 2109void AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter *pAd, 2110 u16 WCID, unsigned long uIV, unsigned long uEIV) 2111{ 2112 unsigned long offset; 2113 2114 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE); 2115 2116 RTMP_IO_WRITE32(pAd, offset, uIV); 2117 RTMP_IO_WRITE32(pAd, offset + 4, uEIV); 2118} 2119 2120void AsicUpdateRxWCIDTable(struct rt_rtmp_adapter *pAd, 2121 u16 WCID, u8 *pAddr) 2122{ 2123 unsigned long offset; 2124 unsigned long Addr; 2125 2126 offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE); 2127 Addr = pAddr[0] + (pAddr[1] << 8) + (pAddr[2] << 16) + (pAddr[3] << 24); 2128 RTMP_IO_WRITE32(pAd, offset, Addr); 2129 Addr = pAddr[4] + (pAddr[5] << 8); 2130 RTMP_IO_WRITE32(pAd, offset + 4, Addr); 2131} 2132 2133/* 2134 ======================================================================== 2135 2136 Routine Description: 2137 Set Cipher Key, Cipher algorithm, IV/EIV to Asic 2138 2139 Arguments: 2140 pAd Pointer to our adapter 2141 WCID WCID Entry number. 2142 BssIndex BSSID index, station or none multiple BSSID support 2143 this value should be 0. 2144 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled 2145 pCipherKey Pointer to Cipher Key. 2146 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table, 2147 otherwise PairewiseKey table 2148 bTxKey This is the transmit key if enabled. 2149 2150 Return Value: 2151 None 2152 2153 Note: 2154 This routine will set the relative key stuff to Asic including WCID attribute, 2155 Cipher Key, Cipher algorithm and IV/EIV. 2156 2157 IV/EIV will be update if this CipherKey is the transmission key because 2158 ASIC will base on IV's KeyID value to select Cipher Key. 2159 2160 If bTxKey sets to FALSE, this is not the TX key, but it could be 2161 RX key 2162 2163 For AP mode bTxKey must be always set to TRUE. 2164 ======================================================================== 2165*/ 2166void AsicAddKeyEntry(struct rt_rtmp_adapter *pAd, 2167 u16 WCID, 2168 u8 BssIndex, 2169 u8 KeyIdx, 2170 struct rt_cipher_key *pCipherKey, 2171 IN BOOLEAN bUsePairewiseKeyTable, IN BOOLEAN bTxKey) 2172{ 2173 unsigned long offset; 2174/* unsigned long WCIDAttri = 0; */ 2175 u8 IV4 = 0; 2176 u8 *pKey = pCipherKey->Key; 2177/* unsigned long KeyLen = pCipherKey->KeyLen; */ 2178 u8 *pTxMic = pCipherKey->TxMic; 2179 u8 *pRxMic = pCipherKey->RxMic; 2180 u8 *pTxtsc = pCipherKey->TxTsc; 2181 u8 CipherAlg = pCipherKey->CipherAlg; 2182 SHAREDKEY_MODE_STRUC csr1; 2183#ifdef RTMP_MAC_PCI 2184 u8 i; 2185#endif /* RTMP_MAC_PCI // */ 2186 2187/* ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY); */ 2188 2189 DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n")); 2190 /* */ 2191 /* 1.) decide key table offset */ 2192 /* */ 2193 if (bUsePairewiseKeyTable) 2194 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE); 2195 else 2196 offset = 2197 SHARED_KEY_TABLE_BASE + (4 * BssIndex + 2198 KeyIdx) * HW_KEY_ENTRY_SIZE; 2199 2200 /* */ 2201 /* 2.) Set Key to Asic */ 2202 /* */ 2203 /*for (i = 0; i < KeyLen; i++) */ 2204#ifdef RTMP_MAC_PCI 2205 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) { 2206 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]); 2207 } 2208 offset += MAX_LEN_OF_PEER_KEY; 2209 2210 /* */ 2211 /* 3.) Set MIC key if available */ 2212 /* */ 2213 if (pTxMic) { 2214 for (i = 0; i < 8; i++) { 2215 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]); 2216 } 2217 } 2218 offset += LEN_TKIP_TXMICK; 2219 2220 if (pRxMic) { 2221 for (i = 0; i < 8; i++) { 2222 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]); 2223 } 2224 } 2225#endif /* RTMP_MAC_PCI // */ 2226#ifdef RTMP_MAC_USB 2227 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY); 2228 offset += MAX_LEN_OF_PEER_KEY; 2229 2230 /* */ 2231 /* 3.) Set MIC key if available */ 2232 /* */ 2233 if (pTxMic) { 2234 RTUSBMultiWrite(pAd, offset, pTxMic, 8); 2235 } 2236 offset += LEN_TKIP_TXMICK; 2237 2238 if (pRxMic) { 2239 RTUSBMultiWrite(pAd, offset, pRxMic, 8); 2240 } 2241#endif /* RTMP_MAC_USB // */ 2242 2243 /* */ 2244 /* 4.) Modify IV/EIV if needs */ 2245 /* This will force Asic to use this key ID by setting IV. */ 2246 /* */ 2247 if (bTxKey) { 2248#ifdef RTMP_MAC_PCI 2249 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE); 2250 /* */ 2251 /* Write IV */ 2252 /* */ 2253 RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]); 2254 RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f)); 2255 RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]); 2256 2257 IV4 = (KeyIdx << 6); 2258 if ((CipherAlg == CIPHER_TKIP) 2259 || (CipherAlg == CIPHER_TKIP_NO_MIC) 2260 || (CipherAlg == CIPHER_AES)) 2261 IV4 |= 0x20; /* turn on extension bit means EIV existence */ 2262 2263 RTMP_IO_WRITE8(pAd, offset + 3, IV4); 2264 2265 /* */ 2266 /* Write EIV */ 2267 /* */ 2268 offset += 4; 2269 for (i = 0; i < 4; i++) { 2270 RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]); 2271 } 2272#endif /* RTMP_MAC_PCI // */ 2273#ifdef RTMP_MAC_USB 2274 u32 tmpVal; 2275 2276 /* */ 2277 /* Write IV */ 2278 /* */ 2279 IV4 = (KeyIdx << 6); 2280 if ((CipherAlg == CIPHER_TKIP) 2281 || (CipherAlg == CIPHER_TKIP_NO_MIC) 2282 || (CipherAlg == CIPHER_AES)) 2283 IV4 |= 0x20; /* turn on extension bit means EIV existence */ 2284 2285 tmpVal = 2286 pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + 2287 (pTxtsc[0] << 16) + (IV4 << 24); 2288 RTMP_IO_WRITE32(pAd, offset, tmpVal); 2289 2290 /* */ 2291 /* Write EIV */ 2292 /* */ 2293 offset += 4; 2294 RTMP_IO_WRITE32(pAd, offset, *(u32 *)& pCipherKey->TxTsc[2]); 2295#endif /* RTMP_MAC_USB // */ 2296 2297 AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, 2298 bUsePairewiseKeyTable); 2299 } 2300 2301 if (!bUsePairewiseKeyTable) { 2302 /* */ 2303 /* Only update the shared key security mode */ 2304 /* */ 2305 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), 2306 &csr1.word); 2307 if ((BssIndex % 2) == 0) { 2308 if (KeyIdx == 0) 2309 csr1.field.Bss0Key0CipherAlg = CipherAlg; 2310 else if (KeyIdx == 1) 2311 csr1.field.Bss0Key1CipherAlg = CipherAlg; 2312 else if (KeyIdx == 2) 2313 csr1.field.Bss0Key2CipherAlg = CipherAlg; 2314 else 2315 csr1.field.Bss0Key3CipherAlg = CipherAlg; 2316 } else { 2317 if (KeyIdx == 0) 2318 csr1.field.Bss1Key0CipherAlg = CipherAlg; 2319 else if (KeyIdx == 1) 2320 csr1.field.Bss1Key1CipherAlg = CipherAlg; 2321 else if (KeyIdx == 2) 2322 csr1.field.Bss1Key2CipherAlg = CipherAlg; 2323 else 2324 csr1.field.Bss1Key3CipherAlg = CipherAlg; 2325 } 2326 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), 2327 csr1.word); 2328 } 2329 2330 DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n")); 2331} 2332 2333/* 2334 ======================================================================== 2335 Description: 2336 Add Pair-wise key material into ASIC. 2337 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table 2338 2339 Return: 2340 ======================================================================== 2341*/ 2342void AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter *pAd, 2343 u8 *pAddr, 2344 u8 WCID, struct rt_cipher_key *pCipherKey) 2345{ 2346 int i; 2347 unsigned long offset; 2348 u8 *pKey = pCipherKey->Key; 2349 u8 *pTxMic = pCipherKey->TxMic; 2350 u8 *pRxMic = pCipherKey->RxMic; 2351#ifdef DBG 2352 u8 CipherAlg = pCipherKey->CipherAlg; 2353#endif /* DBG // */ 2354 2355 /* EKEY */ 2356 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE); 2357#ifdef RTMP_MAC_PCI 2358 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) { 2359 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]); 2360 } 2361#endif /* RTMP_MAC_PCI // */ 2362#ifdef RTMP_MAC_USB 2363 RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY); 2364#endif /* RTMP_MAC_USB // */ 2365 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i += 4) { 2366 u32 Value; 2367 RTMP_IO_READ32(pAd, offset + i, &Value); 2368 } 2369 2370 offset += MAX_LEN_OF_PEER_KEY; 2371 2372 /* MIC KEY */ 2373 if (pTxMic) { 2374#ifdef RTMP_MAC_PCI 2375 for (i = 0; i < 8; i++) { 2376 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]); 2377 } 2378#endif /* RTMP_MAC_PCI // */ 2379#ifdef RTMP_MAC_USB 2380 RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8); 2381#endif /* RTMP_MAC_USB // */ 2382 } 2383 offset += 8; 2384 if (pRxMic) { 2385#ifdef RTMP_MAC_PCI 2386 for (i = 0; i < 8; i++) { 2387 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]); 2388 } 2389#endif /* RTMP_MAC_PCI // */ 2390#ifdef RTMP_MAC_USB 2391 RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8); 2392#endif /* RTMP_MAC_USB // */ 2393 } 2394 2395 DBGPRINT(RT_DEBUG_TRACE, 2396 ("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n", WCID, 2397 CipherName[CipherAlg])); 2398 DBGPRINT(RT_DEBUG_TRACE, 2399 (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 2400 pKey[0], pKey[1], pKey[2], pKey[3], pKey[4], pKey[5], 2401 pKey[6], pKey[7], pKey[8], pKey[9], pKey[10], pKey[11], 2402 pKey[12], pKey[13], pKey[14], pKey[15])); 2403 if (pRxMic) { 2404 DBGPRINT(RT_DEBUG_TRACE, 2405 (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 2406 pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3], 2407 pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7])); 2408 } 2409 if (pTxMic) { 2410 DBGPRINT(RT_DEBUG_TRACE, 2411 (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 2412 pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3], 2413 pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7])); 2414 } 2415} 2416 2417/* 2418 ======================================================================== 2419 Description: 2420 Remove Pair-wise key material from ASIC. 2421 2422 Return: 2423 ======================================================================== 2424*/ 2425void AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter *pAd, 2426 u8 BssIdx, u8 Wcid) 2427{ 2428 unsigned long WCIDAttri; 2429 u16 offset; 2430 2431 /* re-set the entry's WCID attribute as OPEN-NONE. */ 2432 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE); 2433 WCIDAttri = (BssIdx << 4) | PAIRWISEKEYTABLE; 2434 RTMP_IO_WRITE32(pAd, offset, WCIDAttri); 2435} 2436 2437BOOLEAN AsicSendCommandToMcu(struct rt_rtmp_adapter *pAd, 2438 u8 Command, 2439 u8 Token, u8 Arg0, u8 Arg1) 2440{ 2441 2442 if (pAd->chipOps.sendCommandToMcu) 2443 pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1); 2444 2445 return TRUE; 2446} 2447 2448void AsicSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant) 2449{ 2450#ifdef RT30xx 2451 /* RT3572 ATE need not to do this. */ 2452 RT30xxSetRxAnt(pAd, Ant); 2453#endif /* RT30xx // */ 2454} 2455 2456void AsicTurnOffRFClk(struct rt_rtmp_adapter *pAd, u8 Channel) 2457{ 2458 if (pAd->chipOps.AsicRfTurnOff) { 2459 pAd->chipOps.AsicRfTurnOff(pAd); 2460 } else { 2461 /* RF R2 bit 18 = 0 */ 2462 u32 R1 = 0, R2 = 0, R3 = 0; 2463 u8 index; 2464 struct rt_rtmp_rf_regs *RFRegTable; 2465 2466 RFRegTable = RF2850RegTable; 2467 2468 switch (pAd->RfIcType) { 2469 case RFIC_2820: 2470 case RFIC_2850: 2471 case RFIC_2720: 2472 case RFIC_2750: 2473 2474 for (index = 0; index < NUM_OF_2850_CHNL; index++) { 2475 if (Channel == RFRegTable[index].Channel) { 2476 R1 = RFRegTable[index].R1 & 0xffffdfff; 2477 R2 = RFRegTable[index].R2 & 0xfffbffff; 2478 R3 = RFRegTable[index].R3 & 0xfff3ffff; 2479 2480 RTMP_RF_IO_WRITE32(pAd, R1); 2481 RTMP_RF_IO_WRITE32(pAd, R2); 2482 2483 /* Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. */ 2484 /* Set RF R2 bit18=0, R3 bit[18:19]=0 */ 2485 /*if (pAd->StaCfg.bRadio == FALSE) */ 2486 if (1) { 2487 RTMP_RF_IO_WRITE32(pAd, R3); 2488 2489 DBGPRINT(RT_DEBUG_TRACE, 2490 ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n", 2491 Channel, 2492 pAd->RfIcType, R2, 2493 R3)); 2494 } else 2495 DBGPRINT(RT_DEBUG_TRACE, 2496 ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n", 2497 Channel, 2498 pAd->RfIcType, R2)); 2499 break; 2500 } 2501 } 2502 break; 2503 2504 default: 2505 break; 2506 } 2507 } 2508} 2509 2510void AsicTurnOnRFClk(struct rt_rtmp_adapter *pAd, u8 Channel) 2511{ 2512 /* RF R2 bit 18 = 0 */ 2513 u32 R1 = 0, R2 = 0, R3 = 0; 2514 u8 index; 2515 struct rt_rtmp_rf_regs *RFRegTable; 2516 2517#ifdef PCIE_PS_SUPPORT 2518 /* The RF programming sequence is difference between 3xxx and 2xxx */ 2519 if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) { 2520 return; 2521 } 2522#endif /* PCIE_PS_SUPPORT // */ 2523 2524 RFRegTable = RF2850RegTable; 2525 2526 switch (pAd->RfIcType) { 2527 case RFIC_2820: 2528 case RFIC_2850: 2529 case RFIC_2720: 2530 case RFIC_2750: 2531 2532 for (index = 0; index < NUM_OF_2850_CHNL; index++) { 2533 if (Channel == RFRegTable[index].Channel) { 2534 R3 = pAd->LatchRfRegs.R3; 2535 R3 &= 0xfff3ffff; 2536 R3 |= 0x00080000; 2537 RTMP_RF_IO_WRITE32(pAd, R3); 2538 2539 R1 = RFRegTable[index].R1; 2540 RTMP_RF_IO_WRITE32(pAd, R1); 2541 2542 R2 = RFRegTable[index].R2; 2543 if (pAd->Antenna.field.TxPath == 1) { 2544 R2 |= 0x4000; /* If TXpath is 1, bit 14 = 1; */ 2545 } 2546 2547 if (pAd->Antenna.field.RxPath == 2) { 2548 R2 |= 0x40; /* write 1 to off Rxpath. */ 2549 } else if (pAd->Antenna.field.RxPath == 1) { 2550 R2 |= 0x20040; /* write 1 to off RxPath */ 2551 } 2552 RTMP_RF_IO_WRITE32(pAd, R2); 2553 2554 break; 2555 } 2556 } 2557 break; 2558 2559 default: 2560 break; 2561 } 2562 2563 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n", 2564 Channel, pAd->RfIcType, R2)); 2565} 2566