2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
31 Functions used to communicate with ASIC
35 -------- ---------- ----------------------------------------------
38 #include "../rt_config.h"
41 // Reset the RFIC setting to new series
42 RTMP_RF_REGS RF2850RegTable[] = {
43 // ch R1 R2 R3(TX0~4=0) R4
44 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
45 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
46 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
47 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
48 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
49 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
50 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
51 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
52 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
53 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
54 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
55 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
56 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
57 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
59 // 802.11 UNI / HyperLan 2
60 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
61 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
62 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
63 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
64 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
65 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
66 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
67 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
68 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
69 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
70 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
71 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
74 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
76 // 2008.04.30 modified
77 // The system team has AN to improve the EVM value
78 // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
79 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
80 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
81 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
83 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
84 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
85 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
86 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
87 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
88 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
89 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
90 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
91 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
92 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
93 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
94 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
97 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
98 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
99 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
100 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
101 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
102 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
103 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
104 {167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f},
105 {169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327},
106 {171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307},
107 {173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f},
110 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
111 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
112 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
113 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
114 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
115 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
116 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
118 // still lack of MMAC(Japan) ch 34,38,42,46
120 UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
122 FREQUENCY_ITEM FreqItems3020[] =
124 /**************************************************/
125 // ISM : 2.4 to 2.483 GHz //
126 /**************************************************/
128 /**************************************************/
129 //-CH---N-------R---K-----------
145 UCHAR NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
148 VOID AsicUpdateAutoFallBackTable(
149 IN PRTMP_ADAPTER pAd,
150 IN PUCHAR pRateTable)
153 HT_FBK_CFG0_STRUC HtCfg0;
154 HT_FBK_CFG1_STRUC HtCfg1;
155 LG_FBK_CFG0_STRUC LgCfg0;
156 LG_FBK_CFG1_STRUC LgCfg1;
157 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate;
159 // set to initial value
160 HtCfg0.word = 0x65432100;
161 HtCfg1.word = 0xedcba988;
162 LgCfg0.word = 0xedcba988;
163 LgCfg1.word = 0x00002100;
165 pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
166 for (i = 1; i < *((PUCHAR) pRateTable); i++)
168 pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
169 switch (pCurrTxRate->Mode)
175 switch(pCurrTxRate->CurrMCS)
178 LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
181 LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
184 LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
187 LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
190 LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
193 LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
196 LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
199 LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
207 if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
209 switch(pCurrTxRate->CurrMCS)
212 HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
215 HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
218 HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
221 HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
224 HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
227 HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
230 HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
233 HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
236 HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
239 HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
242 HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
245 HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
248 HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
251 HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
254 HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
257 HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
260 DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
267 pNextTxRate = pCurrTxRate;
270 RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
271 RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
272 RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
273 RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
277 ========================================================================
280 Set MAC register value according operation mode.
281 OperationMode AND bNonGFExist are for MM and GF Proteciton.
282 If MM or GF mask is not set, those passing argument doesn't not take effect.
284 Operation mode meaning:
285 = 0 : Pure HT, no preotection.
286 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
287 = 0x10: No Transmission in 40M is protected.
288 = 0x11: Transmission in both 40M and 20M shall be protected
290 we should choose not to use GF. But still set correct ASIC registers.
291 ========================================================================
293 VOID AsicUpdateProtect(
294 IN PRTMP_ADAPTER pAd,
295 IN USHORT OperationMode,
297 IN BOOLEAN bDisableBGProtect,
298 IN BOOLEAN bNonGFExist)
300 PROT_CFG_STRUC ProtCfg, ProtCfg4;
307 if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
312 if (pAd->BATable.numDoneOriginator)
315 // enable the RTS/CTS to avoid channel collision
317 SetMask = ALLN_SETPROTECT;
321 // Config ASIC RTS threshold register
322 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
323 MacReg &= 0xFF0000FF;
324 // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
326 (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
327 (pAd->CommonCfg.bAggregationCapable == TRUE))
328 && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
330 MacReg |= (0x1000 << 8);
334 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
337 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
339 // Initial common protection settings
340 RTMPZeroMemory(Protect, sizeof(Protect));
343 ProtCfg.field.TxopAllowGF40 = 1;
344 ProtCfg.field.TxopAllowGF20 = 1;
345 ProtCfg.field.TxopAllowMM40 = 1;
346 ProtCfg.field.TxopAllowMM20 = 1;
347 ProtCfg.field.TxopAllowOfdm = 1;
348 ProtCfg.field.TxopAllowCck = 1;
349 ProtCfg.field.RTSThEn = 1;
350 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
352 // update PHY mode and rate
353 if (pAd->CommonCfg.Channel > 14)
354 ProtCfg.field.ProtectRate = 0x4000;
355 ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
357 // Handle legacy(B/G) protection
358 if (bDisableBGProtect)
360 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
361 ProtCfg.field.ProtectCtrl = 0;
362 Protect[0] = ProtCfg.word;
363 Protect[1] = ProtCfg.word;
364 pAd->FlgCtsEnabled = 0; /* CTS-self is not used */
368 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
369 ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected
370 Protect[0] = ProtCfg.word;
371 ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect
372 Protect[1] = ProtCfg.word;
373 pAd->FlgCtsEnabled = 1; /* CTS-self is used */
376 // Decide HT frame protection.
377 if ((SetMask & ALLN_SETPROTECT) != 0)
379 switch(OperationMode)
383 // 1.All STAs in the BSS are 20/40 MHz HT
384 // 2. in ai 20/40MHz BSS
385 // 3. all STAs are 20MHz in a 20MHz BSS
386 // Pure HT. no protection.
390 // PROT_TXOP(25:20) -- 010111
391 // PROT_NAV(19:18) -- 01 (Short NAV protection)
392 // PROT_CTRL(17:16) -- 00 (None)
393 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
394 Protect[2] = 0x01744004;
398 // PROT_TXOP(25:20) -- 111111
399 // PROT_NAV(19:18) -- 01 (Short NAV protection)
400 // PROT_CTRL(17:16) -- 00 (None)
401 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
402 Protect[3] = 0x03f44084;
406 // PROT_TXOP(25:20) -- 010111
407 // PROT_NAV(19:18) -- 01 (Short NAV protection)
408 // PROT_CTRL(17:16) -- 00 (None)
409 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
410 Protect[4] = 0x01744004;
414 // PROT_TXOP(25:20) -- 111111
415 // PROT_NAV(19:18) -- 01 (Short NAV protection)
416 // PROT_CTRL(17:16) -- 00 (None)
417 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
418 Protect[5] = 0x03f44084;
422 // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
423 // PROT_CTRL(17:16) -- 01 (RTS/CTS)
424 Protect[4] = 0x01754004;
425 Protect[5] = 0x03f54084;
427 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
431 // This is "HT non-member protection mode."
432 // If there may be non-HT STAs my BSS
433 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
434 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
435 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
437 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
438 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
440 //Assign Protection method for 20&40 MHz packets
441 ProtCfg.field.ProtectCtrl = ASIC_RTS;
442 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
443 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
444 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
445 Protect[2] = ProtCfg.word;
446 Protect[3] = ProtCfg4.word;
447 Protect[4] = ProtCfg.word;
448 Protect[5] = ProtCfg4.word;
449 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
453 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
454 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
455 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
457 //Assign Protection method for 40MHz packets
458 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
459 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
460 Protect[2] = ProtCfg.word;
461 Protect[3] = ProtCfg4.word;
464 ProtCfg.field.ProtectCtrl = ASIC_RTS;
465 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
467 Protect[4] = ProtCfg.word;
468 Protect[5] = ProtCfg4.word;
470 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
474 // HT mixed mode. PROTECT ALL!
476 ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1.
477 ProtCfg4.word = 0x03f44084;
478 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
479 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
481 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
482 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
484 //Assign Protection method for 20&40 MHz packets
485 ProtCfg.field.ProtectCtrl = ASIC_RTS;
486 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
487 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
488 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
489 Protect[2] = ProtCfg.word;
490 Protect[3] = ProtCfg4.word;
491 Protect[4] = ProtCfg.word;
492 Protect[5] = ProtCfg4.word;
493 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
497 // Special on for Atheros problem n chip.
498 Protect[2] = 0x01754004;
499 Protect[3] = 0x03f54084;
500 Protect[4] = 0x01754004;
501 Protect[5] = 0x03f54084;
502 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
507 offset = CCK_PROT_CFG;
508 for (i = 0;i < 6;i++)
510 if ((SetMask & (1<< i)))
512 RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
519 ==========================================================================
523 IRQL = DISPATCH_LEVEL
525 ==========================================================================
527 VOID AsicSwitchChannel(
528 IN PRTMP_ADAPTER pAd,
532 ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
533 CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
535 UINT32 Value = 0; //BbpReg, Value;
536 RTMP_RF_REGS *RFRegTable;
540 // Search Tx power value
541 // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
542 // in ChannelList, so use TxPower array instead.
544 for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
546 if (Channel == pAd->TxPower[index].Channel)
548 TxPwer = pAd->TxPower[index].Power;
549 TxPwer2 = pAd->TxPower[index].Power2;
554 if (index == MAX_NUM_OF_CHANNELS)
556 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
560 // The RF programming sequence is difference between 3xxx and 2xxx
561 if ((IS_RT3070(pAd) || IS_RT3090(pAd)||IS_RT3390(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
562 (pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
564 /* modify by WY for Read RF Reg. error */
566 for (index = 0; index < NUM_OF_3020_CHNL; index++)
568 if (Channel == FreqItems3020[index].Channel)
570 // Programming channel parameters
571 RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
572 RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
573 RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
574 RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
575 RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
578 RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
579 RFValue = (RFValue & 0xE0) | TxPwer;
580 RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
583 RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
584 RFValue = (RFValue & 0xE0) | TxPwer2;
585 RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
587 // Tx/Rx Stream setting
588 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
589 //if (IS_RT3090(pAd))
590 // RFValue |= 0x01; // Enable RF block.
591 RFValue &= 0x03; //clear bit[7~2]
592 if (pAd->Antenna.field.TxPath == 1)
594 else if (pAd->Antenna.field.TxPath == 2)
596 if (pAd->Antenna.field.RxPath == 1)
598 else if (pAd->Antenna.field.RxPath == 2)
600 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
603 RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
604 RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
605 RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
608 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
610 RFValue = pAd->Mlme.CaliBW40RfR24;
611 //DISABLE_11N_CHECK(pAd);
615 RFValue = pAd->Mlme.CaliBW20RfR24;
617 RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
618 RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
621 RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
622 RFValue = RFValue | 0x1;
623 RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
625 // latch channel for future usage.
626 pAd->LatchRfRegs.Channel = Channel;
628 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
633 pAd->Antenna.field.TxPath,
634 FreqItems3020[index].N,
635 FreqItems3020[index].K,
636 FreqItems3020[index].R));
645 RFRegTable = RF2850RegTable;
646 switch (pAd->RfIcType)
653 for (index = 0; index < NUM_OF_2850_CHNL; index++)
655 if (Channel == RFRegTable[index].Channel)
657 R2 = RFRegTable[index].R2;
658 if (pAd->Antenna.field.TxPath == 1)
660 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
663 if (pAd->Antenna.field.RxPath == 2)
665 R2 |= 0x40; // write 1 to off Rxpath.
667 else if (pAd->Antenna.field.RxPath == 1)
669 R2 |= 0x20040; // write 1 to off RxPath
675 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
676 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
678 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
680 if ((TxPwer >= -7) && (TxPwer < 0))
683 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
684 R3 |= (TxPwer << 10);
685 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
689 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
690 R3 |= (TxPwer << 10) | (1 << 9);
694 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
696 TxPwer2 = (7+TxPwer2);
697 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
698 R4 |= (TxPwer2 << 7);
699 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
703 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
704 R4 |= (TxPwer2 << 7) | (1 << 6);
709 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
710 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
713 // Based on BBP current mode before changing RF channel.
714 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
720 pAd->LatchRfRegs.Channel = Channel;
721 pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
722 pAd->LatchRfRegs.R2 = R2;
723 pAd->LatchRfRegs.R3 = R3;
724 pAd->LatchRfRegs.R4 = R4;
726 // Set RF value 1's set R3[bit2] = [0]
727 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
728 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
729 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
730 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
734 // Set RF value 2's set R3[bit2] = [1]
735 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
736 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
737 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
738 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
742 // Set RF value 3's set R3[bit2] = [0]
743 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
744 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
745 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
746 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
757 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
760 (R3 & 0x00003e00) >> 9,
761 (R4 & 0x000007c0) >> 6,
762 pAd->Antenna.field.TxPath,
766 pAd->LatchRfRegs.R4));
769 // Change BBP setting during siwtch from a->g, g->a
772 ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
774 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
775 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
776 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
777 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.
778 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
780 // Rx High power VGA offset for LNA select
781 if (pAd->NicConfig2.field.ExternalLNAForG)
783 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
784 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
788 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
789 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
792 // 5G band selection PIN, bit1 and bit2 are complement
793 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
796 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
798 // Turn off unused PA or LNA when only 1T or 1R
799 if (pAd->Antenna.field.TxPath == 1)
801 TxPinCfg &= 0xFFFFFFF3;
803 if (pAd->Antenna.field.RxPath == 1)
805 TxPinCfg &= 0xFFFFF3FF;
809 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
811 #if defined(RT3090) || defined(RT3390)
812 // PCIe PHY Transmit attenuation adjustment
813 if (IS_RT3090A(pAd) || IS_RT3390(pAd)) {
814 TX_ATTENUATION_CTRL_STRUC
815 TxAttenuationCtrl = { .word = 0 };
817 RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, &TxAttenuationCtrl.word);
819 if (Channel == 14) // Channel #14
821 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1; // Enable PCIe PHY Tx attenuation
822 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4; // 9/16 full drive level
824 else // Channel #1~#13
826 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0; // Disable PCIe PHY Tx attenuation
827 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0; // n/a
830 RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, TxAttenuationCtrl.word);
836 ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
838 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
839 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
840 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
841 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.
842 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
844 // Rx High power VGA offset for LNA select
845 if (pAd->NicConfig2.field.ExternalLNAForA)
847 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
851 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
854 // 5G band selection PIN, bit1 and bit2 are complement
855 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
858 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
860 // Turn off unused PA or LNA when only 1T or 1R
861 if (pAd->Antenna.field.TxPath == 1)
863 TxPinCfg &= 0xFFFFFFF3;
865 if (pAd->Antenna.field.RxPath == 1)
867 TxPinCfg &= 0xFFFFF3FF;
871 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
875 // R66 should be set according to Channel and use 20MHz when scanning
876 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
878 RTMPSetAGCInitValue(pAd, BW_20);
880 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
883 // On 11A, We should delay and wait RF/BBP to be stable
884 // and the appropriate time should be 1000 micro seconds
885 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
890 VOID AsicResetBBPAgent(
891 IN PRTMP_ADAPTER pAd)
893 BBP_CSR_CFG_STRUC BbpCsr;
894 DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit.!! \n"));
895 // Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first.
896 RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
897 BbpCsr.field.Busy = 0;
898 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
902 ==========================================================================
904 This function is required for 2421 only, and should not be used during
905 site survey. It's only required after NIC decided to stay at a channel
907 When this function is called, it's always after AsicSwitchChannel().
910 IRQL = DISPATCH_LEVEL
912 ==========================================================================
914 VOID AsicLockChannel(
915 IN PRTMP_ADAPTER pAd,
920 VOID AsicRfTuningExec(
921 IN PVOID SystemSpecific1,
922 IN PVOID FunctionContext,
923 IN PVOID SystemSpecific2,
924 IN PVOID SystemSpecific3)
929 ==========================================================================
931 Gives CCK TX rate 2 more dB TX power.
932 This routine works only in LINK UP in INFRASTRUCTURE mode.
934 calculate desired Tx power in RF R3.Tx0~5, should consider -
935 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
937 2. auto calibration based on TSSI feedback
938 3. extra 2 db for CCK
939 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
941 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
942 it should be called AFTER MlmeDynamicTxRatSwitching()
943 ==========================================================================
945 VOID AsicAdjustTxPower(
946 IN PRTMP_ADAPTER pAd)
950 BOOLEAN bAutoTxAgc = FALSE;
951 UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
952 UCHAR BbpR1 = 0, BbpR49 = 0, idx;
953 PCHAR pTxAgcCompensate;
960 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
962 (pAd->bPCIclkOff == TRUE) ||
963 #endif // RTMP_MAC_PCI //
964 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) ||
965 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
968 Rssi = RTMPMaxRssi(pAd,
969 pAd->StaCfg.RssiSample.AvgRssi0,
970 pAd->StaCfg.RssiSample.AvgRssi1,
971 pAd->StaCfg.RssiSample.AvgRssi2);
973 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
975 if (pAd->CommonCfg.CentralChannel > 14)
977 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
978 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
979 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
980 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
981 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
985 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
986 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
987 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
988 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
989 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
994 if (pAd->CommonCfg.Channel > 14)
996 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
997 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
998 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
999 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
1000 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
1004 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
1005 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
1006 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
1007 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
1008 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
1012 // TX power compensation for temperature variation based on TSSI. try every 4 second
1013 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
1015 if (pAd->CommonCfg.Channel <= 14)
1018 bAutoTxAgc = pAd->bAutoTxAgcG;
1019 TssiRef = pAd->TssiRefG;
1020 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
1021 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
1022 TxAgcStep = pAd->TxAgcStepG;
1023 pTxAgcCompensate = &pAd->TxAgcCompensateG;
1028 bAutoTxAgc = pAd->bAutoTxAgcA;
1029 TssiRef = pAd->TssiRefA;
1030 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
1031 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
1032 TxAgcStep = pAd->TxAgcStepA;
1033 pTxAgcCompensate = &pAd->TxAgcCompensateA;
1038 /* BbpR1 is unsigned char */
1039 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
1041 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
1042 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
1043 /* step value is defined in pAd->TxAgcStepG for tx power value */
1045 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
1046 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
1047 above value are examined in mass factory production */
1048 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
1050 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
1051 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
1052 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
1054 if (BbpR49 > pTssiMinusBoundary[1])
1056 // Reading is larger than the reference value
1057 // check for how large we need to decrease the Tx power
1058 for (idx = 1; idx < 5; idx++)
1060 if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
1063 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
1064 // if (R3 > (ULONG) (TxAgcStep * (idx-1)))
1065 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
1067 // *pTxAgcCompensate = -((UCHAR)R3);
1069 DeltaPwr += (*pTxAgcCompensate);
1070 DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
1071 BbpR49, TssiRef, TxAgcStep, idx-1));
1073 else if (BbpR49 < pTssiPlusBoundary[1])
1075 // Reading is smaller than the reference value
1076 // check for how large we need to increase the Tx power
1077 for (idx = 1; idx < 5; idx++)
1079 if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
1082 // The index is the step we should increase, idx = 0 means there is nothing to compensate
1083 *pTxAgcCompensate = TxAgcStep * (idx-1);
1084 DeltaPwr += (*pTxAgcCompensate);
1085 DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
1086 BbpR49, TssiRef, TxAgcStep, idx-1));
1090 *pTxAgcCompensate = 0;
1091 DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
1092 BbpR49, TssiRef, TxAgcStep, 0));
1098 if (pAd->CommonCfg.Channel <= 14)
1100 bAutoTxAgc = pAd->bAutoTxAgcG;
1101 pTxAgcCompensate = &pAd->TxAgcCompensateG;
1105 bAutoTxAgc = pAd->bAutoTxAgcA;
1106 pTxAgcCompensate = &pAd->TxAgcCompensateA;
1110 DeltaPwr += (*pTxAgcCompensate);
1113 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
1117 /* calculate delta power based on the percentage specified from UI */
1118 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
1119 // We lower TX power here according to the percentage specified from UI
1120 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
1123 // to patch high power issue with some APs, like Belkin N1.
1126 BbpR1 |= 0x02; // DeltaPwr -= 12;
1128 else if (Rssi > -40)
1130 BbpR1 |= 0x01; // DeltaPwr -= 6;
1136 else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
1138 else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
1142 else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
1146 else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
1150 else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
1155 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
1160 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
1162 /* reset different new tx power for different TX rate */
1165 if (TxPwr[i] != 0xffffffff)
1169 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
1171 if ((Value + DeltaPwr) < 0)
1173 Value = 0; /* min */
1175 else if ((Value + DeltaPwr) > 0xF)
1177 Value = 0xF; /* max */
1181 Value += DeltaPwr; /* temperature compensation */
1184 /* fill new value to CSR offset */
1185 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
1188 /* write tx power value to CSR */
1189 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
1190 TX power for OFDM 6M/9M
1191 TX power for CCK5.5M/11M
1192 TX power for CCK1M/2M */
1193 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
1194 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
1203 ==========================================================================
1205 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
1206 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
1207 the wakeup timer timeout. Driver has to issue a separate command to wake
1210 IRQL = DISPATCH_LEVEL
1212 ==========================================================================
1214 VOID AsicSleepThenAutoWakeup(
1215 IN PRTMP_ADAPTER pAd,
1216 IN USHORT TbttNumToNextWakeUp)
1218 RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
1222 ==========================================================================
1224 AsicForceWakeup() is used whenever manual wakeup is required
1225 AsicForceSleep() should only be used when not in INFRA BSS. When
1226 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
1227 ==========================================================================
1229 VOID AsicForceSleep(
1230 IN PRTMP_ADAPTER pAd)
1236 ==========================================================================
1238 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
1241 IRQL = PASSIVE_LEVEL
1242 IRQL = DISPATCH_LEVEL
1243 ==========================================================================
1245 VOID AsicForceWakeup(
1246 IN PRTMP_ADAPTER pAd,
1249 DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n"));
1250 RTMP_STA_FORCE_WAKEUP(pAd, bFromTx);
1255 ==========================================================================
1259 IRQL = DISPATCH_LEVEL
1261 ==========================================================================
1264 IN PRTMP_ADAPTER pAd,
1268 DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
1269 pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
1271 Addr4 = (ULONG)(pBssid[0]) |
1272 (ULONG)(pBssid[1] << 8) |
1273 (ULONG)(pBssid[2] << 16) |
1274 (ULONG)(pBssid[3] << 24);
1275 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
1278 // always one BSSID in STA mode
1279 Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
1281 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
1284 VOID AsicSetMcastWC(
1285 IN PRTMP_ADAPTER pAd)
1287 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
1290 pEntry->Sst = SST_ASSOC;
1291 pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
1292 pEntry->PsMode = PWR_ACTIVE;
1293 pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
1294 offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
1298 ==========================================================================
1301 IRQL = DISPATCH_LEVEL
1303 ==========================================================================
1305 VOID AsicDelWcidTab(
1306 IN PRTMP_ADAPTER pAd,
1309 ULONG Addr0 = 0x0, Addr1 = 0x0;
1312 DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
1313 offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
1314 RTMP_IO_WRITE32(pAd, offset, Addr0);
1316 RTMP_IO_WRITE32(pAd, offset, Addr1);
1320 ==========================================================================
1323 IRQL = DISPATCH_LEVEL
1325 ==========================================================================
1328 IN PRTMP_ADAPTER pAd)
1330 TX_LINK_CFG_STRUC TxLinkCfg;
1333 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
1334 TxLinkCfg.field.TxRDGEn = 1;
1335 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
1337 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1340 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1342 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1346 ==========================================================================
1349 IRQL = DISPATCH_LEVEL
1351 ==========================================================================
1353 VOID AsicDisableRDG(
1354 IN PRTMP_ADAPTER pAd)
1356 TX_LINK_CFG_STRUC TxLinkCfg;
1360 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
1361 TxLinkCfg.field.TxRDGEn = 0;
1362 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
1364 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1369 //if ( pAd->CommonCfg.bEnableTxBurst )
1370 // Data |= 0x60; // for performance issue not set the TXOP to 0
1372 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
1373 && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
1376 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
1377 if (pAd->CommonCfg.bEnableTxBurst)
1380 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1384 ==========================================================================
1387 IRQL = PASSIVE_LEVEL
1388 IRQL = DISPATCH_LEVEL
1390 ==========================================================================
1392 VOID AsicDisableSync(
1393 IN PRTMP_ADAPTER pAd)
1395 BCN_TIME_CFG_STRUC csr;
1397 DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
1399 // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
1400 // that NIC will never wakes up because TSF stops and no more
1402 pAd->TbttTickCount = 0;
1403 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
1404 csr.field.bBeaconGen = 0;
1405 csr.field.bTBTTEnable = 0;
1406 csr.field.TsfSyncMode = 0;
1407 csr.field.bTsfTicking = 0;
1408 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
1413 ==========================================================================
1416 IRQL = DISPATCH_LEVEL
1418 ==========================================================================
1420 VOID AsicEnableBssSync(
1421 IN PRTMP_ADAPTER pAd)
1423 BCN_TIME_CFG_STRUC csr;
1425 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
1427 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
1428 // RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);
1430 csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
1431 csr.field.bTsfTicking = 1;
1432 csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
1433 csr.field.bBeaconGen = 0; // do NOT generate BEACON
1434 csr.field.bTBTTEnable = 1;
1436 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
1440 ==========================================================================
1443 BEACON frame in shared memory should be built ok before this routine
1444 can be called. Otherwise, a garbage frame maybe transmitted out every
1447 IRQL = DISPATCH_LEVEL
1449 ==========================================================================
1451 VOID AsicEnableIbssSync(
1452 IN PRTMP_ADAPTER pAd)
1454 BCN_TIME_CFG_STRUC csr9;
1458 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
1460 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
1461 csr9.field.bBeaconGen = 0;
1462 csr9.field.bTBTTEnable = 0;
1463 csr9.field.bTsfTicking = 0;
1464 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
1467 // move BEACON TXD and frame content to on-chip memory
1468 ptr = (PUCHAR)&pAd->BeaconTxWI;
1469 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
1471 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1472 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
1476 // start right after the 16-byte TXWI field
1477 ptr = pAd->BeaconBuf;
1478 for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
1480 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1481 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
1484 #endif // RTMP_MAC_PCI //
1486 // move BEACON TXD and frame content to on-chip memory
1487 ptr = (PUCHAR)&pAd->BeaconTxWI;
1488 for (i=0; i<TXWI_SIZE; i+=2) // 16-byte TXWI field
1490 //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1491 //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
1492 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
1496 // start right after the 16-byte TXWI field
1497 ptr = pAd->BeaconBuf;
1498 for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
1500 //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1501 //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
1502 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
1505 #endif // RTMP_MAC_USB //
1508 // For Wi-Fi faily generated beacons between participating stations.
1509 // Set TBTT phase adaptive adjustment step to 8us (default 16us)
1510 // don't change settings 2006-5- by Jerry
1511 //RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);
1513 // start sending BEACON
1514 csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
1515 csr9.field.bTsfTicking = 1;
1516 csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
1517 csr9.field.bTBTTEnable = 1;
1518 csr9.field.bBeaconGen = 1;
1519 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
1523 ==========================================================================
1526 IRQL = PASSIVE_LEVEL
1527 IRQL = DISPATCH_LEVEL
1529 ==========================================================================
1531 VOID AsicSetEdcaParm(
1532 IN PRTMP_ADAPTER pAd,
1533 IN PEDCA_PARM pEdcaParm)
1535 EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
1536 AC_TXOP_CSR0_STRUC csr0;
1537 AC_TXOP_CSR1_STRUC csr1;
1538 AIFSN_CSR_STRUC AifsnCsr;
1539 CWMIN_CSR_STRUC CwminCsr;
1540 CWMAX_CSR_STRUC CwmaxCsr;
1547 if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
1549 DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
1550 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
1551 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
1553 if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
1554 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
1557 //========================================================
1558 // MAC Register has a copy .
1559 //========================================================
1561 if( pAd->CommonCfg.bEnableTxBurst )
1563 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
1564 Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
1567 Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
1569 // Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
1571 Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
1572 Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
1573 Ac0Cfg.field.Aifsn = 2;
1574 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
1576 Ac1Cfg.field.AcTxop = 0; // QID_AC_BK
1577 Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
1578 Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
1579 Ac1Cfg.field.Aifsn = 2;
1580 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
1582 if (pAd->CommonCfg.PhyMode == PHY_11B)
1584 Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms
1585 Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms
1589 Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms
1590 Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms
1592 Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
1593 Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
1594 Ac2Cfg.field.Aifsn = 2;
1595 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
1596 Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
1597 Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
1598 Ac3Cfg.field.Aifsn = 2;
1599 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
1601 //========================================================
1602 // DMA Register has a copy too.
1603 //========================================================
1604 csr0.field.Ac0Txop = 0; // QID_AC_BE
1605 csr0.field.Ac1Txop = 0; // QID_AC_BK
1606 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1607 if (pAd->CommonCfg.PhyMode == PHY_11B)
1609 csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms
1610 csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms
1614 csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms
1615 csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms
1617 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
1620 CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
1621 CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
1622 CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
1623 CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
1624 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
1627 CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
1628 CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
1629 CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
1630 CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
1631 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
1633 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
1635 NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
1639 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
1640 //========================================================
1641 // MAC Register has a copy.
1642 //========================================================
1644 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
1645 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
1647 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
1649 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
1650 Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
1651 Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
1652 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
1654 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
1655 Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
1656 Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
1657 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
1659 Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
1660 if(pAd->Antenna.field.TxPath == 1)
1662 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1;
1663 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1;
1667 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
1668 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
1670 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;
1672 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3;
1673 #endif // RTMP_MAC_USB //
1676 // Tuning for Wi-Fi WMM S06
1677 if (pAd->CommonCfg.bWiFiTest &&
1678 pEdcaParm->Aifsn[QID_AC_VI] == 10)
1679 Ac2Cfg.field.Aifsn -= 1;
1681 // Tuning for TGn Wi-Fi 5.2.32
1682 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
1683 if (STA_TGN_WIFI_ON(pAd) &&
1684 pEdcaParm->Aifsn[QID_AC_VI] == 10)
1686 Ac0Cfg.field.Aifsn = 3;
1687 Ac2Cfg.field.AcTxop = 5;
1690 if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
1692 // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
1693 Ac2Cfg.field.Aifsn = 5;
1698 Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
1699 Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
1700 Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
1701 Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
1704 if (pAd->CommonCfg.bWiFiTest)
1706 if (Ac3Cfg.field.AcTxop == 102)
1708 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
1709 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
1710 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
1711 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
1712 Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
1715 //#endif // WIFI_TEST //
1717 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
1718 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
1719 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
1720 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
1723 //========================================================
1724 // DMA Register has a copy too.
1725 //========================================================
1726 csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
1727 csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
1728 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1730 csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
1731 csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
1732 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
1735 CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
1736 CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
1737 CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
1738 CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
1739 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
1742 CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
1743 CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
1744 CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
1745 CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
1746 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
1749 AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
1750 AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
1751 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
1754 // Tuning for Wi-Fi WMM S06
1755 if (pAd->CommonCfg.bWiFiTest &&
1756 pEdcaParm->Aifsn[QID_AC_VI] == 10)
1757 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
1759 // Tuning for TGn Wi-Fi 5.2.32
1760 // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
1761 if (STA_TGN_WIFI_ON(pAd) &&
1762 pEdcaParm->Aifsn[QID_AC_VI] == 10)
1764 AifsnCsr.field.Aifsn0 = 3;
1765 AifsnCsr.field.Aifsn2 = 7;
1769 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
1773 AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
1775 // TODO: Shiang, this modification also suitable for RT3052/RT3050 ???
1776 if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
1778 AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
1782 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
1784 NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
1787 DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
1788 DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
1789 pEdcaParm->Aifsn[0],
1790 pEdcaParm->Cwmin[0],
1791 pEdcaParm->Cwmax[0],
1792 pEdcaParm->Txop[0]<<5,
1793 pEdcaParm->bACM[0]));
1794 DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
1795 pEdcaParm->Aifsn[1],
1796 pEdcaParm->Cwmin[1],
1797 pEdcaParm->Cwmax[1],
1798 pEdcaParm->Txop[1]<<5,
1799 pEdcaParm->bACM[1]));
1800 DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
1801 pEdcaParm->Aifsn[2],
1802 pEdcaParm->Cwmin[2],
1803 pEdcaParm->Cwmax[2],
1804 pEdcaParm->Txop[2]<<5,
1805 pEdcaParm->bACM[2]));
1806 DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
1807 pEdcaParm->Aifsn[3],
1808 pEdcaParm->Cwmin[3],
1809 pEdcaParm->Cwmax[3],
1810 pEdcaParm->Txop[3]<<5,
1811 pEdcaParm->bACM[3]));
1818 ==========================================================================
1821 IRQL = PASSIVE_LEVEL
1822 IRQL = DISPATCH_LEVEL
1824 ==========================================================================
1826 VOID AsicSetSlotTime(
1827 IN PRTMP_ADAPTER pAd,
1828 IN BOOLEAN bUseShortSlotTime)
1831 UINT32 RegValue = 0;
1833 if (pAd->CommonCfg.Channel > 14)
1834 bUseShortSlotTime = TRUE;
1836 if (bUseShortSlotTime && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1838 else if ((!bUseShortSlotTime) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
1841 if (bUseShortSlotTime)
1842 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1844 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1846 SlotTime = (bUseShortSlotTime)? 9 : 20;
1849 // force using short SLOT time for FAE to demo performance when TxBurst is ON
1850 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1851 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
1854 // In this case, we will think it is doing Wi-Fi test
1855 // And we will not set to short slot when bEnableTxBurst is TRUE.
1857 else if (pAd->CommonCfg.bEnableTxBurst)
1859 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1865 // For some reasons, always set it to short slot time.
1867 // ToDo: Should consider capability with 11B
1870 if (pAd->StaCfg.BssType == BSS_ADHOC)
1872 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1877 RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
1878 RegValue = RegValue & 0xFFFFFF00;
1880 RegValue |= SlotTime;
1882 RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
1886 ========================================================================
1888 Add Shared key information into ASIC.
1889 Update shared key, TxMic and RxMic to Asic Shared key table
1890 Update its cipherAlg to Asic Shared key Mode.
1893 ========================================================================
1895 VOID AsicAddSharedKeyEntry(
1896 IN PRTMP_ADAPTER pAd,
1904 ULONG offset; //, csr0;
1905 SHAREDKEY_MODE_STRUC csr1;
1908 #endif // RTMP_MAC_PCI //
1910 DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
1911 //============================================================================================
1913 DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
1914 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1915 pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
1918 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1919 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
1923 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1924 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
1926 //============================================================================================
1928 // fill key material - key + TX MIC + RX MIC
1931 offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
1932 for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
1934 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
1937 offset += MAX_LEN_OF_SHARE_KEY;
1942 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
1951 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
1954 #endif // RTMP_MAC_PCI //
1957 offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
1958 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
1960 offset += MAX_LEN_OF_SHARE_KEY;
1963 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
1969 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
1972 #endif // RTMP_MAC_USB //
1975 // Update cipher algorithm. WSTA always use BSS0
1977 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
1978 DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
1979 if ((BssIndex%2) == 0)
1982 csr1.field.Bss0Key0CipherAlg = CipherAlg;
1983 else if (KeyIdx == 1)
1984 csr1.field.Bss0Key1CipherAlg = CipherAlg;
1985 else if (KeyIdx == 2)
1986 csr1.field.Bss0Key2CipherAlg = CipherAlg;
1988 csr1.field.Bss0Key3CipherAlg = CipherAlg;
1993 csr1.field.Bss1Key0CipherAlg = CipherAlg;
1994 else if (KeyIdx == 1)
1995 csr1.field.Bss1Key1CipherAlg = CipherAlg;
1996 else if (KeyIdx == 2)
1997 csr1.field.Bss1Key2CipherAlg = CipherAlg;
1999 csr1.field.Bss1Key3CipherAlg = CipherAlg;
2001 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
2002 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
2006 // IRQL = DISPATCH_LEVEL
2007 VOID AsicRemoveSharedKeyEntry(
2008 IN PRTMP_ADAPTER pAd,
2013 SHAREDKEY_MODE_STRUC csr1;
2015 DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
2017 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
2018 if ((BssIndex%2) == 0)
2021 csr1.field.Bss0Key0CipherAlg = 0;
2022 else if (KeyIdx == 1)
2023 csr1.field.Bss0Key1CipherAlg = 0;
2024 else if (KeyIdx == 2)
2025 csr1.field.Bss0Key2CipherAlg = 0;
2027 csr1.field.Bss0Key3CipherAlg = 0;
2032 csr1.field.Bss1Key0CipherAlg = 0;
2033 else if (KeyIdx == 1)
2034 csr1.field.Bss1Key1CipherAlg = 0;
2035 else if (KeyIdx == 2)
2036 csr1.field.Bss1Key2CipherAlg = 0;
2038 csr1.field.Bss1Key3CipherAlg = 0;
2040 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
2041 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
2042 ASSERT(BssIndex < 4);
2048 VOID AsicUpdateWCIDAttribute(
2049 IN PRTMP_ADAPTER pAd,
2053 IN BOOLEAN bUsePairewiseKeyTable)
2055 ULONG WCIDAttri = 0, offset;
2058 // Update WCID attribute.
2059 // Only TxKey could update WCID attribute.
2061 offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
2062 WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
2063 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2066 VOID AsicUpdateWCIDIVEIV(
2067 IN PRTMP_ADAPTER pAd,
2074 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
2076 RTMP_IO_WRITE32(pAd, offset, uIV);
2077 RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
2080 VOID AsicUpdateRxWCIDTable(
2081 IN PRTMP_ADAPTER pAd,
2088 offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
2089 Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
2090 RTMP_IO_WRITE32(pAd, offset, Addr);
2091 Addr = pAddr[4] + (pAddr[5] << 8);
2092 RTMP_IO_WRITE32(pAd, offset + 4, Addr);
2097 ========================================================================
2099 Routine Description:
2100 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
2103 pAd Pointer to our adapter
2104 WCID WCID Entry number.
2105 BssIndex BSSID index, station or none multiple BSSID support
2106 this value should be 0.
2107 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
2108 pCipherKey Pointer to Cipher Key.
2109 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
2110 otherwise PairewiseKey table
2111 bTxKey This is the transmit key if enabled.
2117 This routine will set the relative key stuff to Asic including WCID attribute,
2118 Cipher Key, Cipher algorithm and IV/EIV.
2120 IV/EIV will be update if this CipherKey is the transmission key because
2121 ASIC will base on IV's KeyID value to select Cipher Key.
2123 If bTxKey sets to FALSE, this is not the TX key, but it could be
2126 For AP mode bTxKey must be always set to TRUE.
2127 ========================================================================
2129 VOID AsicAddKeyEntry(
2130 IN PRTMP_ADAPTER pAd,
2134 IN PCIPHER_KEY pCipherKey,
2135 IN BOOLEAN bUsePairewiseKeyTable,
2139 // ULONG WCIDAttri = 0;
2141 PUCHAR pKey = pCipherKey->Key;
2142 // ULONG KeyLen = pCipherKey->KeyLen;
2143 PUCHAR pTxMic = pCipherKey->TxMic;
2144 PUCHAR pRxMic = pCipherKey->RxMic;
2145 PUCHAR pTxtsc = pCipherKey->TxTsc;
2146 UCHAR CipherAlg = pCipherKey->CipherAlg;
2147 SHAREDKEY_MODE_STRUC csr1;
2150 #endif // RTMP_MAC_PCI //
2152 // ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY);
2154 DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
2156 // 1.) decide key table offset
2158 if (bUsePairewiseKeyTable)
2159 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
2161 offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
2164 // 2.) Set Key to Asic
2166 //for (i = 0; i < KeyLen; i++)
2168 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
2170 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
2172 offset += MAX_LEN_OF_PEER_KEY;
2175 // 3.) Set MIC key if available
2179 for (i = 0; i < 8; i++)
2181 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
2184 offset += LEN_TKIP_TXMICK;
2188 for (i = 0; i < 8; i++)
2190 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
2193 #endif // RTMP_MAC_PCI //
2195 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
2196 offset += MAX_LEN_OF_PEER_KEY;
2199 // 3.) Set MIC key if available
2203 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
2205 offset += LEN_TKIP_TXMICK;
2209 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
2211 #endif // RTMP_MAC_USB //
2214 // 4.) Modify IV/EIV if needs
2215 // This will force Asic to use this key ID by setting IV.
2220 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
2224 RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
2225 RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
2226 RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
2228 IV4 = (KeyIdx << 6);
2229 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
2230 IV4 |= 0x20; // turn on extension bit means EIV existence
2232 RTMP_IO_WRITE8(pAd, offset + 3, IV4);
2238 for (i = 0; i < 4; i++)
2240 RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
2242 #endif // RTMP_MAC_PCI //
2249 IV4 = (KeyIdx << 6);
2250 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
2251 IV4 |= 0x20; // turn on extension bit means EIV existence
2253 tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
2254 RTMP_IO_WRITE32(pAd, offset, tmpVal);
2260 RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
2261 #endif // RTMP_MAC_USB //
2263 AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
2266 if (!bUsePairewiseKeyTable)
2269 // Only update the shared key security mode
2271 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
2272 if ((BssIndex % 2) == 0)
2275 csr1.field.Bss0Key0CipherAlg = CipherAlg;
2276 else if (KeyIdx == 1)
2277 csr1.field.Bss0Key1CipherAlg = CipherAlg;
2278 else if (KeyIdx == 2)
2279 csr1.field.Bss0Key2CipherAlg = CipherAlg;
2281 csr1.field.Bss0Key3CipherAlg = CipherAlg;
2286 csr1.field.Bss1Key0CipherAlg = CipherAlg;
2287 else if (KeyIdx == 1)
2288 csr1.field.Bss1Key1CipherAlg = CipherAlg;
2289 else if (KeyIdx == 2)
2290 csr1.field.Bss1Key2CipherAlg = CipherAlg;
2292 csr1.field.Bss1Key3CipherAlg = CipherAlg;
2294 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
2297 DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
2302 ========================================================================
2304 Add Pair-wise key material into ASIC.
2305 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
2308 ========================================================================
2310 VOID AsicAddPairwiseKeyEntry(
2311 IN PRTMP_ADAPTER pAd,
2314 IN CIPHER_KEY *pCipherKey)
2318 PUCHAR pKey = pCipherKey->Key;
2319 PUCHAR pTxMic = pCipherKey->TxMic;
2320 PUCHAR pRxMic = pCipherKey->RxMic;
2322 UCHAR CipherAlg = pCipherKey->CipherAlg;
2326 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
2328 for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
2330 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
2332 #endif // RTMP_MAC_PCI //
2334 RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
2335 #endif // RTMP_MAC_USB //
2336 for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
2339 RTMP_IO_READ32(pAd, offset + i, &Value);
2342 offset += MAX_LEN_OF_PEER_KEY;
2350 RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
2352 #endif // RTMP_MAC_PCI //
2354 RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
2355 #endif // RTMP_MAC_USB //
2363 RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
2365 #endif // RTMP_MAC_PCI //
2367 RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
2368 #endif // RTMP_MAC_USB //
2371 DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
2372 DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2373 pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
2376 DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2377 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
2381 DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2382 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
2386 ========================================================================
2388 Remove Pair-wise key material from ASIC.
2391 ========================================================================
2393 VOID AsicRemovePairwiseKeyEntry(
2394 IN PRTMP_ADAPTER pAd,
2401 // re-set the entry's WCID attribute as OPEN-NONE.
2402 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
2403 WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
2404 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2407 BOOLEAN AsicSendCommandToMcu(
2408 IN PRTMP_ADAPTER pAd,
2415 if (pAd->chipOps.sendCommandToMcu)
2416 pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1);
2423 IN PRTMP_ADAPTER pAd,
2427 /* RT3572 ATE need not to do this. */
2428 RT30xxSetRxAnt(pAd, Ant);
2433 VOID AsicTurnOffRFClk(
2434 IN PRTMP_ADAPTER pAd,
2437 if (pAd->chipOps.AsicRfTurnOff)
2439 pAd->chipOps.AsicRfTurnOff(pAd);
2444 UINT32 R1 = 0, R2 = 0, R3 = 0;
2446 RTMP_RF_REGS *RFRegTable;
2448 RFRegTable = RF2850RegTable;
2450 switch (pAd->RfIcType)
2457 for (index = 0; index < NUM_OF_2850_CHNL; index++)
2459 if (Channel == RFRegTable[index].Channel)
2461 R1 = RFRegTable[index].R1 & 0xffffdfff;
2462 R2 = RFRegTable[index].R2 & 0xfffbffff;
2463 R3 = RFRegTable[index].R3 & 0xfff3ffff;
2465 RTMP_RF_IO_WRITE32(pAd, R1);
2466 RTMP_RF_IO_WRITE32(pAd, R2);
2468 // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
2469 // Set RF R2 bit18=0, R3 bit[18:19]=0
2470 //if (pAd->StaCfg.bRadio == FALSE)
2473 RTMP_RF_IO_WRITE32(pAd, R3);
2475 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
2476 Channel, pAd->RfIcType, R2, R3));
2479 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
2480 Channel, pAd->RfIcType, R2));
2493 VOID AsicTurnOnRFClk(
2494 IN PRTMP_ADAPTER pAd,
2498 UINT32 R1 = 0, R2 = 0, R3 = 0;
2500 RTMP_RF_REGS *RFRegTable;
2502 #ifdef PCIE_PS_SUPPORT
2503 // The RF programming sequence is difference between 3xxx and 2xxx
2504 if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
2508 #endif // PCIE_PS_SUPPORT //
2510 RFRegTable = RF2850RegTable;
2512 switch (pAd->RfIcType)
2519 for (index = 0; index < NUM_OF_2850_CHNL; index++)
2521 if (Channel == RFRegTable[index].Channel)
2523 R3 = pAd->LatchRfRegs.R3;
2526 RTMP_RF_IO_WRITE32(pAd, R3);
2528 R1 = RFRegTable[index].R1;
2529 RTMP_RF_IO_WRITE32(pAd, R1);
2531 R2 = RFRegTable[index].R2;
2532 if (pAd->Antenna.field.TxPath == 1)
2534 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
2537 if (pAd->Antenna.field.RxPath == 2)
2539 R2 |= 0x40; // write 1 to off Rxpath.
2541 else if (pAd->Antenna.field.RxPath == 1)
2543 R2 |= 0x20040; // write 1 to off RxPath
2545 RTMP_RF_IO_WRITE32(pAd, R2);
2556 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",