summaryrefslogtreecommitdiff
path: root/cleopatre/devkit/rt5572drv/MODULE/common/cmm_asic.c
diff options
context:
space:
mode:
Diffstat (limited to 'cleopatre/devkit/rt5572drv/MODULE/common/cmm_asic.c')
-rw-r--r--cleopatre/devkit/rt5572drv/MODULE/common/cmm_asic.c2925
1 files changed, 2925 insertions, 0 deletions
diff --git a/cleopatre/devkit/rt5572drv/MODULE/common/cmm_asic.c b/cleopatre/devkit/rt5572drv/MODULE/common/cmm_asic.c
new file mode 100644
index 0000000000..fbc7610a38
--- /dev/null
+++ b/cleopatre/devkit/rt5572drv/MODULE/common/cmm_asic.c
@@ -0,0 +1,2925 @@
+/*
+ ***************************************************************************
+ * Ralink Tech Inc.
+ * 4F, No. 2 Technology 5th Rd.
+ * Science-based Industrial Park
+ * Hsin-chu, Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2004, Ralink Technology, Inc.
+ *
+ * All rights reserved. Ralink's source code is an unpublished work and the
+ * use of a copyright notice does not imply otherwise. This source code
+ * contains confidential trade secret material of Ralink Tech. Any attemp
+ * or participation in deciphering, decoding, reverse engineering or in any
+ * way altering the source code is stricitly prohibited, unless the prior
+ * written consent of Ralink Technology, Inc. is obtained.
+ ***************************************************************************
+
+ Module Name:
+ cmm_asic.c
+
+ Abstract:
+ Functions used to communicate with ASIC
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+*/
+
+#include "rt_config.h"
+
+
+#define MDSM_NORMAL_TX_POWER 0x00
+#define MDSM_DROP_TX_POWER_BY_6dBm 0x01
+#define MDSM_DROP_TX_POWER_BY_12dBm 0x02
+#define MDSM_ADD_TX_POWER_BY_6dBm 0x03
+#define MDSM_BBP_R1_STATIC_TX_POWER_CONTROL_MASK 0x03
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set MAC register value according operation mode.
+ OperationMode AND bNonGFExist are for MM and GF Proteciton.
+ If MM or GF mask is not set, those passing argument doesn't not take effect.
+
+ Operation mode meaning:
+ = 0 : Pure HT, no preotection.
+ = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
+ = 0x10: No Transmission in 40M is protected.
+ = 0x11: Transmission in both 40M and 20M shall be protected
+ if (bNonGFExist)
+ we should choose not to use GF. But still set correct ASIC registers.
+ ========================================================================
+*/
+VOID AsicUpdateProtect(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT OperationMode,
+ IN UCHAR SetMask,
+ IN BOOLEAN bDisableBGProtect,
+ IN BOOLEAN bNonGFExist)
+{
+ PROT_CFG_STRUC ProtCfg, ProtCfg4;
+ UINT32 Protect[6];
+ USHORT offset;
+ UCHAR i;
+ UINT32 MacReg = 0;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif /* RALINK_ATE */
+
+#ifdef DOT11_N_SUPPORT
+ if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
+ {
+ return;
+ }
+
+ if (pAd->BATable.numDoneOriginator)
+ {
+ /* */
+ /* enable the RTS/CTS to avoid channel collision*/
+ /* */
+ SetMask |= ALLN_SETPROTECT;
+ OperationMode = 8;
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ /* Config ASIC RTS threshold register*/
+ RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
+ MacReg &= 0xFF0000FF;
+ /* If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096*/
+ if ((
+#ifdef DOT11_N_SUPPORT
+ (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
+#endif /* DOT11_N_SUPPORT */
+ (pAd->CommonCfg.bAggregationCapable == TRUE))
+ && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
+ {
+ MacReg |= (0x1000 << 8);
+ }
+ else
+ {
+ MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
+
+ /* Initial common protection settings*/
+ RTMPZeroMemory(Protect, sizeof(Protect));
+ ProtCfg4.word = 0;
+ ProtCfg.word = 0;
+ ProtCfg.field.TxopAllowGF40 = 1;
+ ProtCfg.field.TxopAllowGF20 = 1;
+ ProtCfg.field.TxopAllowMM40 = 1;
+ ProtCfg.field.TxopAllowMM20 = 1;
+ ProtCfg.field.TxopAllowOfdm = 1;
+ ProtCfg.field.TxopAllowCck = 1;
+ ProtCfg.field.RTSThEn = 1;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+
+ /* update PHY mode and rate*/
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ /* update PHY mode and rate*/
+ if (pAd->CommonCfg.Channel > 14)
+ ProtCfg.field.ProtectRate = 0x4000;
+ ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
+ }
+ else if (pAd->OpMode == OPMODE_STA)
+ {
+ // Decide Protect Rate for Legacy packet
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ ProtCfg.field.ProtectRate = 0x4000; // OFDM 6Mbps
+ }
+ else
+ {
+ ProtCfg.field.ProtectRate = 0x0000; // CCK 1Mbps
+ if (pAd->CommonCfg.MinTxRate > RATE_11)
+ ProtCfg.field.ProtectRate |= 0x4000; // OFDM 6Mbps
+ }
+ }
+
+ /* Handle legacy(B/G) protection*/
+ if (bDisableBGProtect)
+ {
+ /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;*/
+ ProtCfg.field.ProtectCtrl = 0;
+ Protect[0] = ProtCfg.word;
+ Protect[1] = ProtCfg.word;
+ pAd->FlgCtsEnabled = 0; /* CTS-self is not used */
+ }
+ else
+ {
+ /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;*/
+ ProtCfg.field.ProtectCtrl = 0; /* CCK do not need to be protected*/
+ Protect[0] = ProtCfg.word;
+ ProtCfg.field.ProtectCtrl = ASIC_CTS; /* OFDM needs using CCK to protect*/
+ Protect[1] = ProtCfg.word;
+ pAd->FlgCtsEnabled = 1; /* CTS-self is used */
+ }
+
+#ifdef DOT11_N_SUPPORT
+ /* Decide HT frame protection.*/
+ if ((SetMask & ALLN_SETPROTECT) != 0)
+ {
+ switch(OperationMode)
+ {
+ case 0x0:
+ /* NO PROTECT */
+ /* 1.All STAs in the BSS are 20/40 MHz HT*/
+ /* 2. in ai 20/40MHz BSS*/
+ /* 3. all STAs are 20MHz in a 20MHz BSS*/
+ /* Pure HT. no protection.*/
+
+ /* MM20_PROT_CFG*/
+ /* Reserved (31:27)*/
+ /* PROT_TXOP(25:20) -- 010111*/
+ /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/
+ /* PROT_CTRL(17:16) -- 00 (None)*/
+ /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M)*/
+ Protect[2] = 0x01744004;
+
+ /* MM40_PROT_CFG*/
+ /* Reserved (31:27)*/
+ /* PROT_TXOP(25:20) -- 111111*/
+ /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/
+ /* PROT_CTRL(17:16) -- 00 (None) */
+ /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)*/
+ Protect[3] = 0x03f44084;
+
+ /* CF20_PROT_CFG*/
+ /* Reserved (31:27)*/
+ /* PROT_TXOP(25:20) -- 010111*/
+ /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/
+ /* PROT_CTRL(17:16) -- 00 (None)*/
+ /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M)*/
+ Protect[4] = 0x01744004;
+
+ /* CF40_PROT_CFG*/
+ /* Reserved (31:27)*/
+ /* PROT_TXOP(25:20) -- 111111*/
+ /* PROT_NAV(19:18) -- 01 (Short NAV protection)*/
+ /* PROT_CTRL(17:16) -- 00 (None)*/
+ /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)*/
+ Protect[5] = 0x03f44084;
+
+ if (bNonGFExist)
+ {
+ /* PROT_NAV(19:18) -- 01 (Short NAV protectiion)*/
+ /* PROT_CTRL(17:16) -- 01 (RTS/CTS)*/
+ Protect[4] = 0x01754004;
+ Protect[5] = 0x03f54084;
+ }
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+ break;
+
+ case 1:
+ /* This is "HT non-member protection mode."*/
+ /* If there may be non-HT STAs my BSS*/
+ ProtCfg.word = 0x01744004; /* PROT_CTRL(17:16) : 0 (None)*/
+ ProtCfg4.word = 0x03f44084; /* duplicaet legacy 24M. BW set 1.*/
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18..*/
+ ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */
+ }
+ /*Assign Protection method for 20&40 MHz packets*/
+ ProtCfg.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+ ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+ Protect[2] = ProtCfg.word;
+ Protect[3] = ProtCfg4.word;
+ Protect[4] = ProtCfg.word;
+ Protect[5] = ProtCfg4.word;
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+ break;
+
+ case 2:
+ /* If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets*/
+ ProtCfg.word = 0x01744004; /* PROT_CTRL(17:16) : 0 (None)*/
+ ProtCfg4.word = 0x03f44084; /* duplicaet legacy 24M. BW set 1.*/
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18..*/
+ ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */
+ }
+ /*Assign Protection method for 40MHz packets*/
+ ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+ Protect[2] = ProtCfg.word;
+ Protect[3] = ProtCfg4.word;
+ if (bNonGFExist)
+ {
+ ProtCfg.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+ }
+ Protect[4] = ProtCfg.word;
+ Protect[5] = ProtCfg4.word;
+
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+ break;
+
+ case 3:
+ /* HT mixed mode. PROTECT ALL!*/
+ /* Assign Rate*/
+ ProtCfg.word = 0x01744004; /*duplicaet legacy 24M. BW set 1.*/
+ ProtCfg4.word = 0x03f44084;
+ /* both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the*/
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18..*/
+ ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083*/
+ }
+ /*Assign Protection method for 20&40 MHz packets*/
+ ProtCfg.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+ ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+ Protect[2] = ProtCfg.word;
+ Protect[3] = ProtCfg4.word;
+ Protect[4] = ProtCfg.word;
+ Protect[5] = ProtCfg4.word;
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+ break;
+
+ case 8:
+ /* Special on for Atheros problem n chip.*/
+ ProtCfg.word = 0x01754004; /*duplicaet legacy 24M. BW set 1.*/
+ ProtCfg4.word = 0x03f54084;
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ ProtCfg.word = 0x01750003; /*ERP use Protection bit is set, use protection rate at Clause 18..*/
+ ProtCfg4.word = 0x03f50003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083*/
+ }
+
+ Protect[2] = ProtCfg.word; /*0x01754004;*/
+ Protect[3] = ProtCfg4.word; /*0x03f54084;*/
+ Protect[4] = ProtCfg.word; /*0x01754004;*/
+ Protect[5] = ProtCfg4.word; /*0x03f54084;*/
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+ break;
+ }
+ }
+#endif /* DOT11_N_SUPPORT */
+
+ offset = CCK_PROT_CFG;
+ for (i = 0;i < 6;i++)
+ {
+ if ((SetMask & (1<< i)))
+ {
+ RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+ }
+}
+}
+
+
+VOID AsicBBPAdjust(RTMP_ADAPTER *pAd)
+{
+ RTMP_CHIP_ASIC_BBP_ADJUST(pAd);
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel,
+ IN BOOLEAN bScan)
+{
+
+
+
+#ifdef CONFIG_AP_SUPPORT
+#ifdef AP_QLOAD_SUPPORT
+ /* clear all statistics count for QBSS Load */
+ QBSS_LoadStatusClear(pAd);
+#endif /* AP_QLOAD_SUPPORT */
+#endif /* CONFIG_AP_SUPPORT */
+
+ RTMP_CHIP_ASIC_SWITCH_CHANNEL(pAd, Channel, bScan);
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ This function is required for 2421 only, and should not be used during
+ site survey. It's only required after NIC decided to stay at a channel
+ for a longer period.
+ When this function is called, it's always after AsicSwitchChannel().
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicLockChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+
+VOID AsicGetTxPowerOffset(
+ IN PRTMP_ADAPTER pAd,
+ IN PULONG TxPwr)
+{
+ CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC CfgOfTxPwrCtrlOverMAC;
+ DBGPRINT(RT_DEBUG_INFO, ("-->AsicGetTxPowerOffset\n"));
+
+ NdisZeroMemory(&CfgOfTxPwrCtrlOverMAC, sizeof(CfgOfTxPwrCtrlOverMAC));
+
+ CfgOfTxPwrCtrlOverMAC.NumOfEntries = 5; /* MAC 0x1314, 0x1318, 0x131C, 0x1320 and 1324 */
+
+ if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+ {
+ if (pAd->CommonCfg.CentralChannel > 14)
+ {
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].MACRegisterOffset = TX_PWR_CFG_0;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue = pAd->Tx40MPwrCfgABand[0];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].MACRegisterOffset = TX_PWR_CFG_1;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].RegisterValue = pAd->Tx40MPwrCfgABand[1];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].MACRegisterOffset = TX_PWR_CFG_2;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].RegisterValue = pAd->Tx40MPwrCfgABand[2];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].MACRegisterOffset = TX_PWR_CFG_3;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].RegisterValue = pAd->Tx40MPwrCfgABand[3];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].MACRegisterOffset = TX_PWR_CFG_4;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].RegisterValue = pAd->Tx40MPwrCfgABand[4];
+ }
+ else
+ {
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].MACRegisterOffset = TX_PWR_CFG_0;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue = pAd->Tx40MPwrCfgGBand[0];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].MACRegisterOffset = TX_PWR_CFG_1;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].RegisterValue = pAd->Tx40MPwrCfgGBand[1];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].MACRegisterOffset = TX_PWR_CFG_2;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].RegisterValue = pAd->Tx40MPwrCfgGBand[2];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].MACRegisterOffset = TX_PWR_CFG_3;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].RegisterValue = pAd->Tx40MPwrCfgGBand[3];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].MACRegisterOffset = TX_PWR_CFG_4;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].RegisterValue = pAd->Tx40MPwrCfgGBand[4];
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.CentralChannel > 14)
+ {
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].MACRegisterOffset = TX_PWR_CFG_0;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue = pAd->Tx20MPwrCfgABand[0];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].MACRegisterOffset = TX_PWR_CFG_1;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].RegisterValue = pAd->Tx20MPwrCfgABand[1];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].MACRegisterOffset = TX_PWR_CFG_2;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].RegisterValue = pAd->Tx20MPwrCfgABand[2];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].MACRegisterOffset = TX_PWR_CFG_3;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].RegisterValue = pAd->Tx20MPwrCfgABand[3];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].MACRegisterOffset = TX_PWR_CFG_4;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].RegisterValue = pAd->Tx20MPwrCfgABand[4];
+ }
+ else
+ {
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].MACRegisterOffset = TX_PWR_CFG_0;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue = pAd->Tx20MPwrCfgGBand[0];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].MACRegisterOffset = TX_PWR_CFG_1;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[1].RegisterValue = pAd->Tx20MPwrCfgGBand[1];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].MACRegisterOffset = TX_PWR_CFG_2;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[2].RegisterValue = pAd->Tx20MPwrCfgGBand[2];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].MACRegisterOffset = TX_PWR_CFG_3;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[3].RegisterValue = pAd->Tx20MPwrCfgGBand[3];
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].MACRegisterOffset = TX_PWR_CFG_4;
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[4].RegisterValue = pAd->Tx20MPwrCfgGBand[4];
+ }
+ }
+
+ NdisCopyMemory(TxPwr, (UCHAR *)&CfgOfTxPwrCtrlOverMAC, sizeof(CfgOfTxPwrCtrlOverMAC));
+
+ DBGPRINT(RT_DEBUG_INFO, ("<--AsicGetTxPowerOffset\n"));
+}
+
+VOID AsicGetAutoAgcOffsetForExternalTxAlc(
+ IN PRTMP_ADAPTER pAd,
+ IN PCHAR pDeltaPwr,
+ IN PCHAR pTotalDeltaPwr,
+ IN PCHAR pAgcCompensate,
+ IN PCHAR pDeltaPowerByBbpR1)
+{
+ BBP_R49_STRUC BbpR49;
+ BOOLEAN bAutoTxAgc = FALSE;
+ UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep, idx;
+ PCHAR pTxAgcCompensate = NULL;
+ CHAR DeltaPwr = 0;
+
+ DBGPRINT(RT_DEBUG_INFO, ("-->%s\n", __FUNCTION__));
+
+ BbpR49.byte = 0;
+
+ /* TX power compensation for temperature variation based on TSSI. Try every 4 second */
+ if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+ {
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ /* bg channel */
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ TssiRef = pAd->TssiRefG;
+ pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
+ pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
+ TxAgcStep = pAd->TxAgcStepG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ /* a channel */
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ TssiRef = pAd->TssiRefA;
+ pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
+ pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
+ TxAgcStep = pAd->TxAgcStepA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49.byte);
+
+ /* TSSI representation */
+ if (IS_RT3071(pAd) || IS_RT3390(pAd) || IS_RT3090A(pAd) || IS_RT3572(pAd)) /* 5-bits */
+ {
+ BbpR49.byte = (BbpR49.byte & 0x1F);
+ }
+
+ /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
+ /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
+ /* step value is defined in pAd->TxAgcStepG for tx power value */
+
+ /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
+ /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+ above value are examined in mass factory production */
+ /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
+
+ /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
+ /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
+ /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
+
+ if (BbpR49.byte > pTssiMinusBoundary[1])
+ {
+ /* Reading is larger than the reference value */
+ /* Check for how large we need to decrease the Tx power */
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49.byte <= pTssiMinusBoundary[idx]) /* Found the range */
+ break;
+ }
+ /* The index is the step we should decrease, idx = 0 means there is nothing to compensate */
+
+ *pTxAgcCompensate = -(TxAgcStep * (idx-1));
+ DeltaPwr += (*pTxAgcCompensate);
+ DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
+ BbpR49.byte, TssiRef, TxAgcStep, idx-1));
+ }
+ else if (BbpR49.byte < pTssiPlusBoundary[1])
+ {
+ /* Reading is smaller than the reference value */
+ /* Check for how large we need to increase the Tx power */
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49.byte >= pTssiPlusBoundary[idx]) /* Found the range*/
+ break;
+ }
+
+ /* The index is the step we should increase, idx = 0 means there is nothing to compensate */
+ *pTxAgcCompensate = TxAgcStep * (idx-1);
+ DeltaPwr += (*pTxAgcCompensate);
+ DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49.byte, TssiRef, TxAgcStep, idx-1));
+ }
+ else
+ {
+ *pTxAgcCompensate = 0;
+ DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49.byte, TssiRef, TxAgcStep, 0));
+ }
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ DeltaPwr += (*pTxAgcCompensate);
+ }
+
+
+ *pDeltaPwr = DeltaPwr;
+ *pAgcCompensate = *pTxAgcCompensate;
+
+ DBGPRINT(RT_DEBUG_INFO, ("<--%s\n", __FUNCTION__));
+}
+
+#ifdef RTMP_TEMPERATURE_COMPENSATION
+VOID InitLookupTable(
+ IN PRTMP_ADAPTER pAd)
+{
+ int Idx, IdxTmp;
+ int i;
+ enum IEEE80211_BAND band;
+ int band_nums = 1;
+ const int Offset = 7;
+ EEPROM_WORD_STRUC WordStruct = {{0}};
+ UCHAR PlusStepNum[IEEE80211_BAND_NUMS][8] = {{0, 1, 3, 2, 3, 3, 3, 2}, {0, 1, 3, 2, 3, 3, 3, 2}};
+ UCHAR MinusStepNum[IEEE80211_BAND_NUMS][8] = {{1, 1, 1, 1, 1, 1, 0, 1}, {1, 1, 1, 1, 1, 1, 0, 1}};
+ UCHAR Step[IEEE80211_BAND_NUMS] = {10, 10};
+ UCHAR RFValue = 0, BbpValue = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> InitLookupTable\n"));
+
+ /* Read from EEPROM, as parameters for lookup table for G band */
+ RT28xx_EEPROM_READ16(pAd, 0x6e, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] EEPROM 6e = %x\n", WordStruct.word));
+ PlusStepNum[IEEE80211_BAND_2G][0] = (WordStruct.field.Byte0 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][1] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][2] = (WordStruct.field.Byte1 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][3] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0x70, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] EEPROM 70 = %x\n", WordStruct.word));
+ PlusStepNum[IEEE80211_BAND_2G][4] = (WordStruct.field.Byte0 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][5] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][6] = (WordStruct.field.Byte1 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_2G][7] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0x72, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] EEPROM 72 = %x\n", WordStruct.word));
+ MinusStepNum[IEEE80211_BAND_2G][0] = (WordStruct.field.Byte0 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][1] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][2] = (WordStruct.field.Byte1 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][3] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0x74, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4] EEPROM 74 = %x\n", WordStruct.word));
+ MinusStepNum[IEEE80211_BAND_2G][4] = (WordStruct.field.Byte0 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][5] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][6] = (WordStruct.field.Byte1 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_2G][7] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0x76, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] EEPROM 76 = %x\n", WordStruct.word));
+ pAd->TxPowerCtrl.TssiGain[IEEE80211_BAND_2G] = (WordStruct.field.Byte0 & 0x0F);
+ Step[IEEE80211_BAND_2G] = (WordStruct.field.Byte0 >> 4);
+ pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_2G] = (CHAR)WordStruct.field.Byte1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] Plus = %u %u %u %u %u %u %u %u\n",
+ PlusStepNum[IEEE80211_BAND_2G][0],
+ PlusStepNum[IEEE80211_BAND_2G][1],
+ PlusStepNum[IEEE80211_BAND_2G][2],
+ PlusStepNum[IEEE80211_BAND_2G][3],
+ PlusStepNum[IEEE80211_BAND_2G][4],
+ PlusStepNum[IEEE80211_BAND_2G][5],
+ PlusStepNum[IEEE80211_BAND_2G][6],
+ PlusStepNum[IEEE80211_BAND_2G][7]
+ ));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] Minus = %u %u %u %u %u %u %u %u\n",
+ MinusStepNum[IEEE80211_BAND_2G][0],
+ MinusStepNum[IEEE80211_BAND_2G][1],
+ MinusStepNum[IEEE80211_BAND_2G][2],
+ MinusStepNum[IEEE80211_BAND_2G][3],
+ MinusStepNum[IEEE80211_BAND_2G][4],
+ MinusStepNum[IEEE80211_BAND_2G][5],
+ MinusStepNum[IEEE80211_BAND_2G][6],
+ MinusStepNum[IEEE80211_BAND_2G][7]
+ ));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4G] tssi gain/step = %u\n", pAd->TxPowerCtrl.TssiGain[IEEE80211_BAND_2G]));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4] Step = %u\n", Step[IEEE80211_BAND_2G]));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 2.4] RefTemp_2G = %d\n", pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_2G]));
+
+#ifdef A_BAND_SUPPORT
+ if (RFIC_IS_5G_BAND(pAd))
+ {
+ /* Read from EEPROM, as parameters for lookup table for A band */
+ RT28xx_EEPROM_READ16(pAd, 0xd4, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] EEPROM d4 = %x\n", WordStruct.word));
+ PlusStepNum[IEEE80211_BAND_5G][0] = (WordStruct.field.Byte0 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][1] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][2] = (WordStruct.field.Byte1 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][3] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0xd6, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] EEPROM d6 = %x\n", WordStruct.word));
+ PlusStepNum[IEEE80211_BAND_5G][4] = (WordStruct.field.Byte0 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][5] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][6] = (WordStruct.field.Byte1 & 0x0F);
+ PlusStepNum[IEEE80211_BAND_5G][7] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0xd8, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] EEPROM d8 = %x\n", WordStruct.word));
+ MinusStepNum[IEEE80211_BAND_5G][0] = (WordStruct.field.Byte0 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][1] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][2] = (WordStruct.field.Byte1 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][3] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0xda, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] EEPROM da = %x\n", WordStruct.word));
+ MinusStepNum[IEEE80211_BAND_5G][4] = (WordStruct.field.Byte0 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][5] = (((WordStruct.field.Byte0 & 0xF0) >> 4) & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][6] = (WordStruct.field.Byte1 & 0x0F);
+ MinusStepNum[IEEE80211_BAND_5G][7] = (((WordStruct.field.Byte1 & 0xF0) >> 4) & 0x0F);
+
+ RT28xx_EEPROM_READ16(pAd, 0xdc, WordStruct.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] EEPROM dc = %x\n", WordStruct.word));
+ pAd->TxPowerCtrl.TssiGain[IEEE80211_BAND_5G] = (WordStruct.field.Byte0 & 0x0F);
+ Step[IEEE80211_BAND_5G] = (WordStruct.field.Byte0 >> 4);
+ pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_5G] = (CHAR)WordStruct.field.Byte1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] Plus = %u %u %u %u %u %u %u %u\n",
+ PlusStepNum[IEEE80211_BAND_5G][0],
+ PlusStepNum[IEEE80211_BAND_5G][1],
+ PlusStepNum[IEEE80211_BAND_5G][2],
+ PlusStepNum[IEEE80211_BAND_5G][3],
+ PlusStepNum[IEEE80211_BAND_5G][4],
+ PlusStepNum[IEEE80211_BAND_5G][5],
+ PlusStepNum[IEEE80211_BAND_5G][6],
+ PlusStepNum[IEEE80211_BAND_5G][7]
+ ));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] Minus = %u %u %u %u %u %u %u %u\n",
+ MinusStepNum[IEEE80211_BAND_5G][0],
+ MinusStepNum[IEEE80211_BAND_5G][1],
+ MinusStepNum[IEEE80211_BAND_5G][2],
+ MinusStepNum[IEEE80211_BAND_5G][3],
+ MinusStepNum[IEEE80211_BAND_5G][4],
+ MinusStepNum[IEEE80211_BAND_5G][5],
+ MinusStepNum[IEEE80211_BAND_5G][6],
+ MinusStepNum[IEEE80211_BAND_5G][7]
+ ));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] tssi gain/step = %u\n", pAd->TxPowerCtrl.TssiGain[IEEE80211_BAND_5G]));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] Step = %u\n", Step[IEEE80211_BAND_5G]));
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation 5G] RefTemp_2G = %d\n", pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_5G]));
+
+ band_nums = IEEE80211_BAND_NUMS;
+ }
+#endif /* A_BAND_SUPPORT */
+
+
+ for (band = IEEE80211_BAND_2G; band < band_nums; band++)
+ {
+ /* positive */
+ i = 0;
+ IdxTmp = 1;
+
+ pAd->TxPowerCtrl.LookupTable[band][1 + Offset] = Step[band] / 2;
+ pAd->TxPowerCtrl.LookupTable[band][0 + Offset] = pAd->TxPowerCtrl.LookupTable[band][1 + Offset] - Step[band];
+ for (Idx = 2; Idx < 26;)/* Idx++ )*/
+ {
+ if (PlusStepNum[band][i] != 0 || i >= 8)
+ {
+ if (Idx >= IdxTmp + PlusStepNum[band][i] && i < 8)
+ {
+ pAd->TxPowerCtrl.LookupTable[band][Idx + Offset] = pAd->TxPowerCtrl.LookupTable[band][Idx - 1 + Offset] + (Step[band] - (i+1) + 1);
+ IdxTmp = IdxTmp + PlusStepNum[band][i];
+ i += 1;
+ }
+ else
+ {
+ pAd->TxPowerCtrl.LookupTable[band][Idx + Offset] = pAd->TxPowerCtrl.LookupTable[band][Idx - 1 + Offset] + (Step[band] - (i+1) + 1);
+ }
+ Idx++;
+ }
+ else
+ {
+ i += 1;
+ }
+ }
+
+ /* negative */
+ i = 0;
+ IdxTmp = 1;
+ for (Idx = 1; Idx < 8;)/* Idx++ )*/
+ {
+ if (MinusStepNum[band][i] != 0 || i >= 8)
+ {
+ if ((Idx + 1) >= IdxTmp + MinusStepNum[band][i] && i < 8)
+ {
+ pAd->TxPowerCtrl.LookupTable[band][-Idx + Offset] = pAd->TxPowerCtrl.LookupTable[band][-Idx + 1 + Offset] - (Step[band] + (i+1) - 1);
+ IdxTmp = IdxTmp + MinusStepNum[band][i];
+ i += 1;
+ }
+ else
+ {
+ pAd->TxPowerCtrl.LookupTable[band][-Idx + Offset] = pAd->TxPowerCtrl.LookupTable[band][-Idx + 1 + Offset] - (Step[band] + (i+1) - 1);
+ }
+ Idx++;
+ }
+ else
+ {
+ i += 1;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Lookup table as below:\n"));
+ for (Idx = 0; Idx < 33; Idx++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation band(%d)] %d, %d\n", band, Idx - Offset, pAd->TxPowerCtrl.LookupTable[band][Idx]));
+ }
+ }
+
+ /* Set BBP_R47 */
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpValue);
+
+ /* bit3 = 0 */
+ BbpValue = (BbpValue & 0xf7);
+
+ /* bit7 = 1, bit4 = 0 */
+ BbpValue = (BbpValue | 0x80);
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpValue);
+
+ /* Set RF_R27 */
+ RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+
+ /* Set [7:6] to 01. For method 2, it is set at initialization. */
+ RFValue = (RFValue & 0x7f);
+ RFValue = (RFValue | 0x40);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("[temp. compensation] Set RF_R27 to 0x%x\n", RFValue));
+ RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+}
+
+VOID AsicGetAutoAgcOffsetForTemperatureSensor(
+ IN PRTMP_ADAPTER pAd,
+ IN PCHAR pDeltaPwr,
+ IN PCHAR pTotalDeltaPwr,
+ IN PCHAR pAgcCompensate,
+ IN PCHAR pDeltaPowerByBbpR1)
+{
+ RTMP_CHIP_CAP *pChipCap = &pAd->chipCap;
+ const TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTable;
+ TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTableEntry0 = NULL; /* Ant0 */
+ TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTableEntry1 = NULL; /* Ant1 */
+ BBP_R49_STRUC BbpR49;
+ BOOLEAN bAutoTxAgc = FALSE;
+ PCHAR pTxAgcCompensate = NULL;
+ UCHAR RFValue = 0;
+ CHAR TuningTableUpperBound = 0, TuningTableIndex0 = 0, TuningTableIndex1 = 0;
+ INT CurrentTemp = 0;
+ INT RefTemp;
+ INT *LookupTable;
+ INT LookupTableIndex = pAd->TxPowerCtrl.LookupTableIndex + TEMPERATURE_COMPENSATION_LOOKUP_TABLE_OFFSET;
+
+ DBGPRINT(RT_DEBUG_INFO, ("-->%s\n", __FUNCTION__));
+
+ BbpR49.byte = 0;
+ *pTotalDeltaPwr = 0;
+
+#ifdef A_BAND_SUPPORT
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ /* a band channel */
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ TxPowerTuningTable = pChipCap->TxPowerTuningTable_5G;
+ RefTemp = pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_5G];
+ LookupTable = &pAd->TxPowerCtrl.LookupTable[IEEE80211_BAND_5G][0];
+ TuningTableUpperBound = pChipCap->TxAlcTxPowerUpperBound_5G;
+ }
+ else
+#endif /* A_BAND_SUPPORT */
+ {
+ /* bg band channel */
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ TxPowerTuningTable = pChipCap->TxPowerTuningTable_2G;
+ RefTemp = pAd->TxPowerCtrl.RefTemp[IEEE80211_BAND_2G];
+ LookupTable = &pAd->TxPowerCtrl.LookupTable[IEEE80211_BAND_2G][0];
+ TuningTableUpperBound = pChipCap->TxAlcTxPowerUpperBound_2G;
+ }
+
+ /* AutoTxAgc in EEPROM means temperature compensation enabled/diablded. */
+ if (bAutoTxAgc)
+ {
+ /* Current temperature */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49.byte);
+ CurrentTemp = (CHAR)BbpR49.byte;
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] BBP_R49 = %02x, current temp = %d\n", BbpR49.byte, CurrentTemp));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] RefTemp = %d\n", RefTemp));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] index = %d\n", pAd->TxPowerCtrl.LookupTableIndex));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] f(%d)= %d\n", pAd->TxPowerCtrl.LookupTableIndex - 1, LookupTable[LookupTableIndex - 1]));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] f(%d)= %d\n", pAd->TxPowerCtrl.LookupTableIndex, LookupTable[LookupTableIndex]));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] f(%d)= %d\n", pAd->TxPowerCtrl.LookupTableIndex + 1, LookupTable[LookupTableIndex + 1]));
+ if (CurrentTemp > RefTemp + LookupTable[LookupTableIndex + 1] + ((LookupTable[LookupTableIndex + 1] - LookupTable[LookupTableIndex]) >> 2) &&
+ LookupTableIndex < 32)
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] ++\n"));
+ LookupTableIndex++;
+ pAd->TxPowerCtrl.LookupTableIndex++;
+ }
+ else if (CurrentTemp < RefTemp + LookupTable[LookupTableIndex] - ((LookupTable[LookupTableIndex] - LookupTable[LookupTableIndex - 1]) >> 2) &&
+ LookupTableIndex > 0)
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] --\n"));
+ LookupTableIndex--;
+ pAd->TxPowerCtrl.LookupTableIndex--;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] ==\n"));
+ }
+
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] idxTxPowerTable=%d, idxTxPowerTable2=%d, TuningTableUpperBound=%d\n",
+ pAd->TxPowerCtrl.idxTxPowerTable + pAd->TxPowerCtrl.LookupTableIndex,
+ pAd->TxPowerCtrl.idxTxPowerTable2 + pAd->TxPowerCtrl.LookupTableIndex,
+ TuningTableUpperBound));
+
+ TuningTableIndex0 = pAd->TxPowerCtrl.idxTxPowerTable
+ + pAd->TxPowerCtrl.LookupTableIndex
+#ifdef DOT11_N_SUPPORT
+ + pAd->TxPower[pAd->CommonCfg.CentralChannel-1].Power;
+#else
+ + pAd->TxPower[pAd->CommonCfg.Channel-1].Power;
+#endif /* DOT11_N_SUPPORT */
+ /* The boundary verification */
+ TuningTableIndex0 = (TuningTableIndex0 > TuningTableUpperBound) ? TuningTableUpperBound : TuningTableIndex0;
+ TuningTableIndex0 = (TuningTableIndex0 < LOWERBOUND_TX_POWER_TUNING_ENTRY) ?
+ LOWERBOUND_TX_POWER_TUNING_ENTRY : TuningTableIndex0;
+ TxPowerTuningTableEntry0 = &TxPowerTuningTable[TuningTableIndex0 + TX_POWER_TUNING_ENTRY_OFFSET];
+
+ TuningTableIndex1 = pAd->TxPowerCtrl.idxTxPowerTable2
+ + pAd->TxPowerCtrl.LookupTableIndex
+#ifdef DOT11_N_SUPPORT
+ + pAd->TxPower[pAd->CommonCfg.CentralChannel-1].Power2;
+#else
+ + pAd->TxPower[pAd->CommonCfg.Channel-1].Power2;
+#endif /* DOT11_N_SUPPORT */
+ /* The boundary verification */
+ TuningTableIndex1 = (TuningTableIndex1 > TuningTableUpperBound) ? TuningTableUpperBound : TuningTableIndex1;
+ TuningTableIndex1 = (TuningTableIndex1 < LOWERBOUND_TX_POWER_TUNING_ENTRY) ?
+ LOWERBOUND_TX_POWER_TUNING_ENTRY : TuningTableIndex1;
+ TxPowerTuningTableEntry1 = &TxPowerTuningTable[TuningTableIndex1 + TX_POWER_TUNING_ENTRY_OFFSET];
+
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] (tx0)RF_TX_ALC = %x, MAC_PowerDelta = %d, TuningTableIndex = %d\n",
+ TxPowerTuningTableEntry0->RF_TX_ALC, TxPowerTuningTableEntry0->MAC_PowerDelta, TuningTableIndex0));
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] (tx1)RF_TX_ALC = %x, MAC_PowerDelta = %d, TuningTableIndex = %d\n",
+ TxPowerTuningTableEntry1->RF_TX_ALC, TxPowerTuningTableEntry1->MAC_PowerDelta, TuningTableIndex1));
+
+ /* Update RF_R49 [0:5] */
+ RT30xxReadRFRegister(pAd, RF_R49, &RFValue);
+ RFValue = ((RFValue & ~0x3F) | TxPowerTuningTableEntry0->RF_TX_ALC);
+ if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x27 */
+ {
+ RFValue = ((RFValue & ~0x3F) | 0x27);
+ }
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] Update RF_R49[0:5] to 0x%x\n", TxPowerTuningTableEntry0->RF_TX_ALC));
+ RT30xxWriteRFRegister(pAd, RF_R49, RFValue);
+
+ /* Update RF_R50 [0:5] */
+ RT30xxReadRFRegister(pAd, RF_R50, &RFValue);
+ RFValue = ((RFValue & ~0x3F) | TxPowerTuningTableEntry1->RF_TX_ALC);
+ if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x27 */
+ {
+ RFValue = ((RFValue & ~0x3F) | 0x27);
+ }
+ DBGPRINT(RT_DEBUG_INFO, ("[temp. compensation] Update RF_R50[0:5] to 0x%x\n", TxPowerTuningTableEntry1->RF_TX_ALC));
+ RT30xxWriteRFRegister(pAd, RF_R50, RFValue);
+
+ *pTotalDeltaPwr = TxPowerTuningTableEntry0->MAC_PowerDelta;
+
+ }
+
+ *pAgcCompensate = *pTxAgcCompensate;
+ DBGPRINT(RT_DEBUG_INFO, ("<--%s\n", __FUNCTION__));
+}
+#endif /* RTMP_TEMPERATURE_COMPENSATION */
+
+#ifdef SINGLE_SKU
+VOID GetSingleSkuDeltaPower(
+ IN PRTMP_ADAPTER pAd,
+ IN PCHAR pTotalDeltaPower,
+ INOUT PULONG pSingleSKUTotalDeltaPwr,
+ INOUT PUCHAR pSingleSKUBbpR1Offset)
+{
+ INT i, j;
+ CHAR Value;
+ CHAR MinValue = 127;
+ UCHAR BbpR1 = 0;
+ UCHAR TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion;
+ UCHAR AdjustMaxTxPwr[(MAX_TX_PWR_CONTROL_OVER_MAC_REGISTERS * 8)];
+ CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC CfgOfTxPwrCtrlOverMAC = {0};
+
+ /* Get TX rate offset table which from EEPROM 0xDEh ~ 0xEFh */
+ RTMP_CHIP_ASIC_TX_POWER_OFFSET_GET(pAd, (PULONG)&CfgOfTxPwrCtrlOverMAC);
+
+ /* Handle regulatory max. TX power constraint */
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8); /* 5G band */
+ }
+ else
+ {
+ TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF); /* 2.4G band */
+ }
+
+ CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
+
+ /* Use OFDM 6M as the criterion */
+ criterion = (UCHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[0].RegisterValue & 0x000F0000) >> 16);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d\n",
+ __FUNCTION__, criterion, TxPwrInEEPROM, CountryTxPwr));
+
+ /* Adjust max. TX power according to the relationship of TX power in EEPROM */
+ for (i=0; i<CfgOfTxPwrCtrlOverMAC.NumOfEntries; i++)
+ {
+ if (i == 0)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> j*4) & 0x0F);
+
+ if (j < 4)
+ {
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4; /* CCK has 4dBm larger than OFDM */
+ }
+ else
+ {
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: offset = 0x%04X, i/j=%d/%d, (Default)Value=%d, %d\n",
+ __FUNCTION__,
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset,
+ i,
+ j,
+ Value,
+ AdjustMaxTxPwr[i*8+j]));
+ }
+ }
+ else
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> j*4) & 0x0F);
+
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: offset = 0x%04X, i/j=%d/%d, (Default)Value=%d, %d\n",
+ __FUNCTION__,
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset,
+ i,
+ j,
+ Value,
+ AdjustMaxTxPwr[i*8+j]));
+ }
+ }
+ }
+
+ /* Adjust TX power according to the relationship */
+ for (i=0; i<CfgOfTxPwrCtrlOverMAC.NumOfEntries; i++)
+ {
+ if (CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> j*4) & 0x0F);
+
+ /* The TX power is larger than the regulatory, the power should be restrained */
+ if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr)
+ {
+ Value = (AdjustMaxTxPwr[i*8+j] - CountryTxPwr);
+
+ if (Value > 0xF)
+ {
+ /* The output power is larger than Country Regulatory over 15dBm, the origianl design has overflow case */
+ DBGPRINT(RT_DEBUG_ERROR,("%s: Value overflow - %d\n", __FUNCTION__, Value));
+ }
+
+ *(pSingleSKUTotalDeltaPwr+i) = (*(pSingleSKUTotalDeltaPwr+i) & ~(0x0000000F << j*4)) | (Value << j*4);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: offset = 0x%04X, i/j=%d/%d, (Exceed)Value=%d, %d\n",
+ __FUNCTION__,
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset,
+ i,
+ j,
+ Value,
+ AdjustMaxTxPwr[i*8+j]));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: offset = 0x%04X, i/j=%d/%d, Value=%d, %d, no change\n",
+ __FUNCTION__,
+ CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].MACRegisterOffset,
+ i,
+ j,
+ Value,
+ AdjustMaxTxPwr[i*8+j]));
+ }
+ }
+ }
+ }
+
+ /* Calculate the min. TX power */
+ for(i=0; i<CfgOfTxPwrCtrlOverMAC.NumOfEntries; i++)
+ {
+ if (CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ CHAR PwrChange;
+ /*
+ After Single SKU, each data rate offset power value is saved in TotalDeltaPwr[].
+ PwrChange will add SingleSKUDeltaPwr and TotalDeltaPwr[] for each data rate to calculate
+ the final adjust output power value which is saved in MAC Reg. and BBP_R1.
+ */
+
+ /*
+ Value / TxPwr[] is get from eeprom 0xDEh ~ 0xEFh and increase or decrease the
+ 20/40 Bandwidth Delta Value in eeprom 0x50h.
+ */
+ Value = (CHAR)((CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i].RegisterValue >> j*4) & 0x0F); /* 0 ~ 15 */
+
+ /* Fix the corner case of Single SKU read eeprom offset 0xF0h ~ 0xFEh which for BBP Instruction configuration */
+ if (Value == 0xF)
+ continue;
+
+ /* Value_offset is current Pwr comapre with Country Regulation and need adjust delta value */
+ PwrChange = (CHAR)((*(pSingleSKUTotalDeltaPwr+i) >> j*4) & 0x0F); /* 0 ~ 15 */
+ PwrChange -= *pTotalDeltaPower;
+
+ Value -= PwrChange;
+
+ if (MinValue > Value)
+ MinValue = Value;
+ }
+ }
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
+ /* Depend on the min. TX power to adjust and prevent the value of MAC_TX_PWR_CFG less than 0 */
+ if ((MinValue < 0) && (MinValue >= -6))
+ {
+ BbpR1 |= MDSM_DROP_TX_POWER_BY_6dBm;
+ *pSingleSKUBbpR1Offset = 6;
+ }
+ else if ((MinValue < -6)&&(MinValue >= -12))
+ {
+ BbpR1 |= MDSM_DROP_TX_POWER_BY_12dBm;
+ *pSingleSKUBbpR1Offset = 12;
+ }
+ else if (MinValue < -12)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s: ASIC limit..\n", __FUNCTION__));
+ BbpR1 |= MDSM_DROP_TX_POWER_BY_12dBm;
+ *pSingleSKUBbpR1Offset = 12;
+ }
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: <After BBP R1> TotalDeltaPower = %d dBm, BbpR1 = 0x%02X \n", __FUNCTION__, *pTotalDeltaPower, BbpR1));
+}
+#endif /* SINGLE_SKU */
+
+VOID AsicPercentageDeltaPower(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ INOUT PCHAR pDeltaPwr,
+ INOUT PCHAR pDeltaPowerByBbpR1)
+{
+ /*
+ Calculate delta power based on the percentage specified from UI.
+ E2PROM setting is calibrated for maximum TX power (i.e. 100%).
+ We lower TX power here according to the percentage specified from UI.
+ */
+
+ if (pAd->CommonCfg.TxPowerPercentage >= 100) /* AUTO TX POWER control */
+ {
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 90) /* 91 ~ 100% & AUTO, treat as 100% in terms of mW */
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 60) /* 61 ~ 90%, treat as 75% in terms of mW DeltaPwr -= 1; */
+ {
+ *pDeltaPwr -= 1;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 30) /* 31 ~ 60%, treat as 50% in terms of mW DeltaPwr -= 3; */
+ {
+ *pDeltaPwr -= 3;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 15) /* 16 ~ 30%, treat as 25% in terms of mW DeltaPwr -= 6; */
+ {
+ *pDeltaPowerByBbpR1 -= 6; /* -6 dBm */
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 9) /* 10 ~ 15%, treat as 12.5% in terms of mW DeltaPwr -= 9; */
+ {
+ *pDeltaPowerByBbpR1 -= 6; /* -6 dBm */
+ *pDeltaPwr -= 3;
+ }
+ else /* 0 ~ 9 %, treat as MIN(~3%) in terms of mW DeltaPwr -= 12; */
+ {
+ *pDeltaPowerByBbpR1 -= 12; /* -12 dBm */
+ }
+}
+
+VOID AsicCompensatePowerViaBBP(
+ IN PRTMP_ADAPTER pAd,
+ INOUT PCHAR pTotalDeltaPower)
+{
+ UCHAR BbpR1 = 0;
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: <Before BBP R1> TotalDeltaPower = %d dBm\n", __FUNCTION__, *pTotalDeltaPower));
+
+ /* The BBP R1 controls the transmit power for all rates */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
+ BbpR1 &= ~MDSM_BBP_R1_STATIC_TX_POWER_CONTROL_MASK;
+
+ if (*pTotalDeltaPower <= -12)
+ {
+ *pTotalDeltaPower += 12;
+ BbpR1 |= MDSM_DROP_TX_POWER_BY_12dBm;
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: Drop the transmit power by 12 dBm (BBP R1)\n", __FUNCTION__));
+ }
+ else if ((*pTotalDeltaPower <= -6) && (*pTotalDeltaPower > -12))
+ {
+ *pTotalDeltaPower += 6;
+ BbpR1 |= MDSM_DROP_TX_POWER_BY_6dBm;
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: Drop the transmit power by 6 dBm (BBP R1)\n", __FUNCTION__));
+ }
+ else
+ {
+ /* Control the the transmit power by using the MAC only */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+ }
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: <After BBP R1> TotalDeltaPower = %d dBm, BbpR1 = 0x%02X \n", __FUNCTION__, *pTotalDeltaPower, BbpR1));
+}
+
+/*
+ ==========================================================================
+ Description:
+ Gives CCK TX rate 2 more dB TX power.
+ This routine works only in LINK UP in INFRASTRUCTURE mode.
+
+ calculate desired Tx power in RF R3.Tx0~5, should consider -
+ 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
+ 1. TxPowerPercentage
+ 2. auto calibration based on TSSI feedback
+ 3. extra 2 db for CCK
+ 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+ NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
+ it should be called AFTER MlmeDynamicTxRatSwitching()
+ ==========================================================================
+ */
+
+VOID AsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i, j;
+ CHAR Value;
+ CHAR Rssi = -127;
+ CHAR DeltaPwr = 0;
+ CHAR TxAgcCompensate = 0;
+ CHAR DeltaPowerByBbpR1 = 0;
+ CHAR TotalDeltaPower = 0; /* (non-positive number) including the transmit power controlled by the MAC and the BBP R1 */
+#ifdef RTMP_INTERNAL_TX_ALC
+#endif /* RTMP_INTERNAL_TX_ALC */
+ CONFIGURATION_OF_TX_POWER_CONTROL_OVER_MAC CfgOfTxPwrCtrlOverMAC = {0};
+#ifdef SINGLE_SKU
+ CHAR TotalDeltaPowerOri = 0;
+ UCHAR SingleSKUBbpR1Offset = 0;
+ ULONG SingleSKUTotalDeltaPwr[MAX_TXPOWER_ARRAY_SIZE] = {0};
+#endif /* SINGLE_SKU */
+
+
+
+ /* Get Tx rate offset table which from EEPROM 0xDEh ~ 0xEFh */
+ RTMP_CHIP_ASIC_TX_POWER_OFFSET_GET(pAd, (PULONG)&CfgOfTxPwrCtrlOverMAC);
+ /* Get temperature compensation delta power value */
+ RTMP_CHIP_ASIC_AUTO_AGC_OFFSET_GET(
+ pAd, &DeltaPwr, &TotalDeltaPower, &TxAgcCompensate, &DeltaPowerByBbpR1);
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: DeltaPwr=%d, TotalDeltaPower=%d, TxAgcCompensate=%d, DeltaPowerByBbpR1=%d\n",
+ __FUNCTION__,
+ DeltaPwr,
+ TotalDeltaPower,
+ TxAgcCompensate,
+ DeltaPowerByBbpR1));
+
+#ifdef RTMP_INTERNAL_TX_ALC
+#endif /* RTMP_INTERNAL_TX_ALC */
+ /* Get delta power based on the percentage specified from UI */
+ AsicPercentageDeltaPower(pAd, Rssi, &DeltaPwr,&DeltaPowerByBbpR1);
+
+ /* The transmit power controlled by the BBP */
+ TotalDeltaPower += DeltaPowerByBbpR1;
+ /* The transmit power controlled by the MAC */
+ TotalDeltaPower += DeltaPwr;
+
+#ifdef SINGLE_SKU
+ if (pAd->CommonCfg.bSKUMode == TRUE)
+ {
+ /* Re calculate delta power while enabling Single SKU */
+ GetSingleSkuDeltaPower(pAd, &TotalDeltaPower, (PULONG)&SingleSKUTotalDeltaPwr, &SingleSKUBbpR1Offset);
+
+ TotalDeltaPowerOri = TotalDeltaPower;
+ }
+ else
+#endif /* SINGLE_SKU */
+ {
+ AsicCompensatePowerViaBBP(pAd, &TotalDeltaPower);
+ }
+
+ /* Power will be updated each 4 sec. */
+ if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+ {
+/*****************************************************************************/
+ /* Set new Tx power for different Tx rates */
+ for (i=0; i < CfgOfTxPwrCtrlOverMAC.NumOfEntries; i++)
+ {
+ TX_POWER_CONTROL_OVER_MAC_ENTRY *pTxPwrEntry;
+ ULONG reg_val;
+
+ pTxPwrEntry = &CfgOfTxPwrCtrlOverMAC.TxPwrCtrlOverMAC[i];
+ reg_val = pTxPwrEntry->RegisterValue;
+ if (reg_val != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ CHAR _upbound, _lowbound, t_pwr;
+ BOOLEAN _bValid;
+
+ _lowbound = 0;
+ _bValid = TRUE;
+
+ Value = (CHAR)((reg_val >> j*4) & 0x0F);
+#ifdef SINGLE_SKU
+ if (pAd->CommonCfg.bSKUMode == TRUE)
+ {
+ TotalDeltaPower = SingleSKUBbpR1Offset + TotalDeltaPowerOri - (CHAR)((SingleSKUTotalDeltaPwr[i] >> j*4) & 0x0F);
+
+ DBGPRINT(RT_DEBUG_INFO, ("%s: BbpR1Offset(%d) + TX ALC(%d) - SingleSKU[%d/%d](%d) = TotalDeltaPower(%d)\n",
+ __FUNCTION__, SingleSKUBbpR1Offset,
+ TotalDeltaPowerOri, i, j,
+ (CHAR)((SingleSKUTotalDeltaPwr[i] >> j*4) & 0x0F),
+ TotalDeltaPower));
+ }
+#endif /* SINGLE_SKU */
+
+#if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION)
+ /* The upper bounds of MAC 0x1314 ~ 0x1324 are variable */
+ if ((pAd->TxPowerCtrl.bInternalTxALC == TRUE)^(pAd->chipCap.bTempCompTxALC == TRUE))
+ {
+ switch (0x1314 + (i * 4))
+ {
+ case 0x1314:
+ _upbound = 0xe;
+ break;
+
+ case 0x1318:
+ _upbound = (j <= 3) ? 0xc : 0xe;
+ break;
+
+ case 0x131C:
+ _upbound = ((j == 0) || (j == 2) || (j == 3)) ? 0xc : 0xe;
+ break;
+
+ case 0x1320:
+ _upbound = (j == 1) ? 0xe : 0xc;
+ break;
+
+ case 0x1324:
+ _upbound = 0xc;
+ break;
+
+ default:
+ {
+ /* do nothing */
+ _bValid = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknown register = 0x%x\n", __FUNCTION__, (0x1314 + (i * 4))));
+ }
+ break;
+ }
+ }
+ else
+#endif /* RTMP_INTERNAL_TX_ALC || RTMP_TEMPERATURE_COMPENSATION */
+ _upbound = 0xc;
+
+ if (_bValid)
+ {
+ t_pwr = Value + TotalDeltaPower;
+ if (t_pwr < _lowbound)
+ Value = _lowbound;
+ else if (t_pwr > _upbound)
+ Value = _upbound;
+ else
+ Value = t_pwr;
+ }
+
+ /* Fill new value into the corresponding MAC offset */
+ pTxPwrEntry->RegisterValue = (reg_val & ~(0x0000000F << j*4)) | (Value << j*4);
+ }
+
+ RTMP_IO_WRITE32(pAd, pTxPwrEntry->MACRegisterOffset, pTxPwrEntry->RegisterValue);
+
+ }
+ }
+ /* Extra set MAC registers to compensate Tx power if any */
+ RTMP_CHIP_ASIC_EXTRA_POWER_OVER_MAC(pAd);
+ }
+
+}
+
+
+VOID AsicResetBBPAgent(
+ IN PRTMP_ADAPTER pAd)
+{
+ RTMP_CHIP_ASIC_RESET_BBP_AGENT(pAd);
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Set My BSSID
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSetBssid(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid)
+{
+ ULONG Addr4;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
+ pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
+
+ Addr4 = (ULONG)(pBssid[0]) |
+ (ULONG)(pBssid[1] << 8) |
+ (ULONG)(pBssid[2] << 16) |
+ (ULONG)(pBssid[3] << 24);
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
+
+ Addr4 = 0;
+ /* always one BSSID in STA mode*/
+ Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
+
+
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
+}
+
+VOID AsicSetMcastWC(
+ IN PRTMP_ADAPTER pAd)
+{
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
+ USHORT offset;
+
+ pEntry->Sst = SST_ASSOC;
+ pEntry->Aid = MCAST_WCID; /* Softap supports 1 BSSID and use WCID=0 as multicast Wcid index*/
+ pEntry->PsMode = PWR_ACTIVE;
+ pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
+ offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDelWcidTab(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid)
+{
+ ULONG Addr0 = 0x0, Addr1 = 0x0;
+ ULONG offset;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
+ offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
+ RTMP_IO_WRITE32(pAd, offset, Addr0);
+ offset += 4;
+ RTMP_IO_WRITE32(pAd, offset, Addr1);
+}
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableRDG(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_LINK_CFG_STRUC TxLinkCfg;
+ UINT32 Data = 0;
+
+ RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+ TxLinkCfg.field.TxRDGEn = 1;
+ RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ Data &= 0xFFFFFF00;
+ Data |= 0x80;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+ /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);*/
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDisableRDG(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_LINK_CFG_STRUC TxLinkCfg;
+ UINT32 Data = 0;
+
+
+
+ RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+ TxLinkCfg.field.TxRDGEn = 0;
+ RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+
+ Data &= 0xFFFFFF00;
+ /*Data |= 0x20;*/
+#ifndef WIFI_TEST
+ /*if ( pAd->CommonCfg.bEnableTxBurst ) */
+ /* Data |= 0x60; for performance issue not set the TXOP to 0*/
+#endif
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
+#ifdef DOT11_N_SUPPORT
+ && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
+#endif /* DOT11_N_SUPPORT */
+ )
+ {
+ /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode*/
+ if (pAd->CommonCfg.bEnableTxBurst)
+ Data |= 0x20;
+ }
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+}
+#endif /* DOT11_N_SUPPORT */
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDisableSync(
+ IN PRTMP_ADAPTER pAd)
+{
+ BCN_TIME_CFG_STRUC csr;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
+
+ /* 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect*/
+ /* that NIC will never wakes up because TSF stops and no more */
+ /* TBTT interrupts*/
+ pAd->TbttTickCount = 0;
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+ csr.field.bBeaconGen = 0;
+ csr.field.bTBTTEnable = 0;
+ csr.field.TsfSyncMode = 0;
+ csr.field.bTsfTicking = 0;
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableBssSync(
+ IN PRTMP_ADAPTER pAd)
+{
+ BCN_TIME_CFG_STRUC csr;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
+
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+/* RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);*/
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU*/
+ csr.field.bTsfTicking = 1;
+ csr.field.TsfSyncMode = 3; /* sync TSF similar as in ADHOC mode?*/
+ csr.field.bBeaconGen = 1; /* AP should generate BEACON*/
+ csr.field.bTBTTEnable = 1;
+ }
+#endif /* CONFIG_AP_SUPPORT */
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Note:
+ BEACON frame in shared memory should be built ok before this routine
+ can be called. Otherwise, a garbage frame maybe transmitted out every
+ Beacon period.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableIbssSync(
+ IN PRTMP_ADAPTER pAd)
+{
+ BCN_TIME_CFG_STRUC csr9;
+ PUCHAR ptr;
+ UINT i;
+ ULONG beaconBaseLocation = 0;
+ USHORT beaconLen = (USHORT) pAd->BeaconTxWI.MPDUtotalByteCount;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+ UINT32 longptr;
+#ifdef RT_BIG_ENDIAN
+ TXWI_STRUC localTxWI;
+
+ NdisMoveMemory((PUCHAR)&localTxWI, (PUCHAR)&pAd->BeaconTxWI, TXWISize);
+ RTMPWIEndianChange(pAd, (PUCHAR)&localTxWI, TYPE_TXWI);
+ beaconLen = (USHORT) localTxWI.MPDUtotalByteCount;
+#endif /* RT_BIG_ENDIAN */
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(MPDUtotalByteCount=%d, beaconLen=%d)\n", pAd->BeaconTxWI.MPDUtotalByteCount, beaconLen));
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
+
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
+ csr9.field.bBeaconGen = 0;
+ csr9.field.bTBTTEnable = 0;
+ csr9.field.bTsfTicking = 0;
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+ beaconBaseLocation = HW_BEACON_BASE0(pAd);
+
+
+#ifdef RTMP_MAC_USB
+ /* move BEACON TXD and frame content to on-chip memory*/
+ ptr = (PUCHAR)&pAd->BeaconTxWI;
+ for (i=0; i < TXWISize; i+=2)
+ {
+ longptr = *ptr + (*(ptr+1)<<8);
+ RTMP_CHIP_UPDATE_BEACON(pAd, HW_BEACON_BASE0(pAd) + i, longptr, 2);
+ ptr += 2;
+ }
+
+ /* start right after the 16-byte TXWI field*/
+ ptr = pAd->BeaconBuf;
+ /*for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)*/
+ for (i=0; i< beaconLen; i+=2)
+ {
+ longptr = *ptr + (*(ptr+1)<<8);
+ RTMP_CHIP_UPDATE_BEACON(pAd, HW_BEACON_BASE0(pAd) + TXWISize + i, longptr, 2);
+ ptr +=2;
+ }
+#endif /* RTMP_MAC_USB */
+
+
+
+ /* For Wi-Fi faily generated beacons between participating stations. */
+ /* Set TBTT phase adaptive adjustment step to 8us (default 16us)*/
+ /* don't change settings 2006-5- by Jerry*/
+ /*RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);*/
+
+ /* start sending BEACON*/
+ csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU*/
+ csr9.field.bTsfTicking = 1;
+ /*
+ (STA ad-hoc mode) Upon the reception of BEACON frame from associated BSS,
+ local TSF is updated with remote TSF only if the remote TSF is greater than local TSF
+ */
+ csr9.field.TsfSyncMode = 2; /* sync TSF in IBSS mode*/
+ csr9.field.bTBTTEnable = 1;
+ csr9.field.bBeaconGen = 1;
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSetEdcaParm(
+ IN PRTMP_ADAPTER pAd,
+ IN PEDCA_PARM pEdcaParm)
+{
+ EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
+ AC_TXOP_CSR0_STRUC csr0;
+ AC_TXOP_CSR1_STRUC csr1;
+ AIFSN_CSR_STRUC AifsnCsr;
+ CWMIN_CSR_STRUC CwminCsr;
+ CWMAX_CSR_STRUC CwmaxCsr;
+ int i;
+
+ Ac0Cfg.word = 0;
+ Ac1Cfg.word = 0;
+ Ac2Cfg.word = 0;
+ Ac3Cfg.word = 0;
+ if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (IS_ENTRY_CLIENT(&pAd->MacTab.Content[i]) || IS_ENTRY_APCLI(&pAd->MacTab.Content[i]))
+ CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
+ }
+
+ /*========================================================*/
+ /* MAC Register has a copy .*/
+ /*========================================================*/
+/*#ifndef WIFI_TEST*/
+ if( pAd->CommonCfg.bEnableTxBurst )
+ {
+ /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode*/
+ Ac0Cfg.field.AcTxop = 0x20; /* Suggest by John for TxBurst in HT Mode*/
+ }
+ else
+ Ac0Cfg.field.AcTxop = 0; /* QID_AC_BE*/
+/*#else*/
+/* Ac0Cfg.field.AcTxop = 0; QID_AC_BE*/
+/*#endif */
+ Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac0Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+
+ Ac1Cfg.field.AcTxop = 0; /* QID_AC_BK*/
+ Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac1Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ {
+ Ac2Cfg.field.AcTxop = 192; /* AC_VI: 192*32us ~= 6ms*/
+ Ac3Cfg.field.AcTxop = 96; /* AC_VO: 96*32us ~= 3ms*/
+ }
+ else
+ {
+ Ac2Cfg.field.AcTxop = 96; /* AC_VI: 96*32us ~= 3ms*/
+ Ac3Cfg.field.AcTxop = 48; /* AC_VO: 48*32us ~= 1.5ms*/
+ }
+ Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac2Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+ Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac3Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+ /*========================================================*/
+ /* DMA Register has a copy too.*/
+ /*========================================================*/
+ csr0.field.Ac0Txop = 0; /* QID_AC_BE*/
+ csr0.field.Ac1Txop = 0; /* QID_AC_BK*/
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ {
+ csr1.field.Ac2Txop = 192; /* AC_VI: 192*32us ~= 6ms*/
+ csr1.field.Ac3Txop = 96; /* AC_VO: 96*32us ~= 3ms*/
+ }
+ else
+ {
+ csr1.field.Ac2Txop = 96; /* AC_VI: 96*32us ~= 3ms*/
+ csr1.field.Ac3Txop = 48; /* AC_VO: 48*32us ~= 1.5ms*/
+ }
+ RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+ CwminCsr.word = 0;
+ CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
+ CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
+ CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
+ CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
+ RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+ CwmaxCsr.word = 0;
+ CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
+ CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
+ CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
+ CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
+ RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+ RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
+
+ NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
+
+ }
+ else
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+ /*========================================================*/
+ /* MAC Register has a copy.*/
+ /*========================================================*/
+
+ /* Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27*/
+ /* To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.*/
+
+ /*pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; rt2860c need this */
+
+ Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
+ Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
+ Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
+ Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; /*+1;*/
+
+ Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
+ Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; /*+2; */
+ Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
+ Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; /*+1;*/
+
+
+ Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
+ {
+ Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
+ Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
+ }
+ /*sync with window 20110524*/
+ Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1; /* 5.2.27 T6 Pass Tx VI+BE, but will impack 5.2.27/28 T7. Tx VI*/
+
+#ifdef INF_AMAZON_SE
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ Ac2Cfg.field.Aifsn = 0x3; /*for WiFi WMM A1-T07.*/
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* INF_AMAZON_SE */
+
+
+ Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
+ Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
+ Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
+ Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
+
+/*#ifdef WIFI_TEST*/
+ if (pAd->CommonCfg.bWiFiTest)
+ {
+ if (Ac3Cfg.field.AcTxop == 102)
+ {
+ Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
+ Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
+ Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
+ Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
+ Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
+ } /* End of if */
+ }
+/*#endif WIFI_TEST */
+
+
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+
+ /*========================================================*/
+ /* DMA Register has a copy too.*/
+ /*========================================================*/
+ csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
+ csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+
+ csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
+ csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
+ RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+ CwminCsr.word = 0;
+ CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
+ CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
+ CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO];
+#endif /* CONFIG_AP_SUPPORT */
+ RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+ CwmaxCsr.word = 0;
+ CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
+ CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
+ CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
+ CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
+ RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+ AifsnCsr.word = 0;
+ AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_BE];*/
+ AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_BK];*/
+ AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_VI];*/
+#ifdef INF_AMAZON_SE
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ {
+ AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_VO]*/
+ AifsnCsr.field.Aifsn2 = 0x2; /*pEdcaParm->Aifsn[QID_AC_VI]; for WiFi WMM A1-T07.*/
+ }
+#endif /* CONFIG_AP_SUPPORT */
+#endif /* INF_AMAZON_SE */
+
+
+#ifdef CONFIG_AP_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_AP(pAd)
+ AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_VO]*/
+#endif /* CONFIG_AP_SUPPORT */
+ RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
+
+ NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+ if (!ADHOC_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[0],
+ pEdcaParm->Cwmin[0],
+ pEdcaParm->Cwmax[0],
+ pEdcaParm->Txop[0]<<5,
+ pEdcaParm->bACM[0]));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[1],
+ pEdcaParm->Cwmin[1],
+ pEdcaParm->Cwmax[1],
+ pEdcaParm->Txop[1]<<5,
+ pEdcaParm->bACM[1]));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[2],
+ pEdcaParm->Cwmin[2],
+ pEdcaParm->Cwmax[2],
+ pEdcaParm->Txop[2]<<5,
+ pEdcaParm->bACM[2]));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[3],
+ pEdcaParm->Cwmin[3],
+ pEdcaParm->Cwmax[3],
+ pEdcaParm->Txop[3]<<5,
+ pEdcaParm->bACM[3]));
+ }
+
+ }
+
+ pAd->CommonCfg.RestoreBurstMode = Ac0Cfg.word;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSetSlotTime(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bUseShortSlotTime)
+{
+ ULONG SlotTime;
+ UINT32 RegValue = 0;
+
+
+ if (bUseShortSlotTime && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
+ return;
+ else if ((!bUseShortSlotTime) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
+ return;
+
+ if (bUseShortSlotTime)
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+ else
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+
+ SlotTime = (bUseShortSlotTime)? 9 : 20;
+
+
+
+ /* For some reasons, always set it to short slot time.*/
+ /* ToDo: Should consider capability with 11B*/
+
+ RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
+ RegValue = RegValue & 0xFFFFFF00;
+
+ RegValue |= SlotTime;
+
+ RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
+}
+
+/*
+ ========================================================================
+ Description:
+ Add Shared key information into ASIC.
+ Update shared key, TxMic and RxMic to Asic Shared key table
+ Update its cipherAlg to Asic Shared key Mode.
+
+ Return:
+ ========================================================================
+*/
+VOID AsicAddSharedKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx,
+ IN PCIPHER_KEY pCipherKey)
+{
+ ULONG offset; /*, csr0;*/
+ SHAREDKEY_MODE_STRUC csr1;
+
+ PUCHAR pKey = pCipherKey->Key;
+ PUCHAR pTxMic = pCipherKey->TxMic;
+ PUCHAR pRxMic = pCipherKey->RxMic;
+ UCHAR CipherAlg = pCipherKey->CipherAlg;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
+/*============================================================================================*/
+
+ DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
+ DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ 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]));
+ if (pRxMic)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+ }
+ if (pTxMic)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+ }
+/*============================================================================================*/
+
+ /* fill key material - key + TX MIC + RX MIC*/
+
+
+#ifdef RTMP_MAC_USB
+{
+ offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
+ RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY, FALSE);
+
+ offset += MAX_LEN_OF_SHARE_KEY;
+ if (pTxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pTxMic, 8, FALSE);
+ }
+
+ offset += 8;
+ if (pRxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pRxMic, 8, FALSE);
+ }
+}
+#endif /* RTMP_MAC_USB */
+
+
+ /* Update cipher algorithm. WSTA always use BSS0*/
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
+ DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
+ if ((BssIndex%2) == 0)
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss0Key0CipherAlg = CipherAlg;
+ else if (KeyIdx == 1)
+ csr1.field.Bss0Key1CipherAlg = CipherAlg;
+ else if (KeyIdx == 2)
+ csr1.field.Bss0Key2CipherAlg = CipherAlg;
+ else
+ csr1.field.Bss0Key3CipherAlg = CipherAlg;
+ }
+ else
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss1Key0CipherAlg = CipherAlg;
+ else if (KeyIdx == 1)
+ csr1.field.Bss1Key1CipherAlg = CipherAlg;
+ else if (KeyIdx == 2)
+ csr1.field.Bss1Key2CipherAlg = CipherAlg;
+ else
+ csr1.field.Bss1Key3CipherAlg = CipherAlg;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+
+}
+
+/* IRQL = DISPATCH_LEVEL*/
+VOID AsicRemoveSharedKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx)
+{
+ /*ULONG SecCsr0;*/
+ SHAREDKEY_MODE_STRUC csr1;
+
+ DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
+
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
+ if ((BssIndex%2) == 0)
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss0Key0CipherAlg = 0;
+ else if (KeyIdx == 1)
+ csr1.field.Bss0Key1CipherAlg = 0;
+ else if (KeyIdx == 2)
+ csr1.field.Bss0Key2CipherAlg = 0;
+ else
+ csr1.field.Bss0Key3CipherAlg = 0;
+ }
+ else
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss1Key0CipherAlg = 0;
+ else if (KeyIdx == 1)
+ csr1.field.Bss1Key1CipherAlg = 0;
+ else if (KeyIdx == 2)
+ csr1.field.Bss1Key2CipherAlg = 0;
+ else
+ csr1.field.Bss1Key3CipherAlg = 0;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+ ASSERT(BssIndex < 4);
+ ASSERT(KeyIdx < 4);
+
+}
+
+VOID AsicUpdateWCIDIVEIV(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN ULONG uIV,
+ IN ULONG uEIV)
+{
+ ULONG offset;
+
+ offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+
+ RTMP_IO_WRITE32(pAd, offset, uIV);
+ RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: wcid(%d) 0x%08lx, 0x%08lx \n",
+ __FUNCTION__, WCID, uIV, uEIV));
+}
+
+VOID AsicUpdateRxWCIDTable(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN PUCHAR pAddr)
+{
+ ULONG offset;
+ ULONG Addr;
+
+ offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
+ Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
+ RTMP_IO_WRITE32(pAd, offset, Addr);
+ Addr = pAddr[4] + (pAddr[5] << 8);
+ RTMP_IO_WRITE32(pAd, offset + 4, Addr);
+}
+
+/*
+ ========================================================================
+ Description:
+ Add Client security information into ASIC WCID table and IVEIV table.
+ Return:
+
+ Note :
+ The key table selection rule :
+ 1. Wds-links and Mesh-links always use Pair-wise key table.
+ 2. When the CipherAlg is TKIP, AES, SMS4 or the dynamic WEP is enabled,
+ it needs to set key into Pair-wise Key Table.
+ 3. The pair-wise key security mode is set NONE, it means as no security.
+ 4. In STA Adhoc mode, it always use shared key table.
+ 5. Otherwise, use shared key table
+
+ ========================================================================
+*/
+VOID AsicUpdateWcidAttributeEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN UINT8 Wcid,
+ IN UINT8 KeyTabFlag)
+{
+ WCID_ATTRIBUTE_STRUC WCIDAttri;
+ USHORT offset;
+
+ /* Initialize the content of WCID Attribue */
+ WCIDAttri.word = 0;
+
+ /* The limitation of HW WCID table */
+ if (/*Wcid < 1 ||*/ Wcid > 254)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s: Wcid is invalid (%d). \n",
+ __FUNCTION__, Wcid));
+ return;
+ }
+
+ /* Update the pairwise key security mode.
+ Use bit10 and bit3~1 to indicate the pairwise cipher mode */
+ WCIDAttri.field.PairKeyModeExt = ((CipherAlg & 0x08) >> 3);
+ WCIDAttri.field.PairKeyMode = (CipherAlg & 0x07);
+
+ /* Update the MBSS index.
+ Use bit11 and bit6~4 to indicate the BSS index */
+ WCIDAttri.field.BSSIdxExt = ((BssIdx & 0x08) >> 3);
+ WCIDAttri.field.BSSIdx = (BssIdx & 0x07);
+
+#ifdef WAPI_SUPPORT
+ /* Update WAPI related information */
+ if (CipherAlg == CIPHER_SMS4)
+ {
+ if (KeyTabFlag == SHAREDKEYTABLE)
+ WCIDAttri.field.WAPI_MCBC = 1;
+ WCIDAttri.field.WAPIKeyIdx = ((KeyIdx == 0) ? 0 : 1);
+ }
+#endif /* WAPI_SUPPORT */
+
+ /* Assign Key Table selection */
+ WCIDAttri.field.KeyTab = KeyTabFlag;
+
+ /* Update related information to ASIC */
+ offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
+ RTMP_IO_WRITE32(pAd, offset, WCIDAttri.word);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : WCID #%d, KeyIndex #%d, Alg=%s\n", __FUNCTION__, Wcid, KeyIdx, CipherName[CipherAlg]));
+ DBGPRINT(RT_DEBUG_TRACE, (" WCIDAttri = 0x%x \n", WCIDAttri.word));
+
+}
+
+
+/*
+ ========================================================================
+ Description:
+ Add Pair-wise key material into ASIC.
+ Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
+
+ Return:
+ ========================================================================
+*/
+VOID AsicAddPairwiseKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR WCID,
+ IN PCIPHER_KEY pCipherKey)
+{
+ INT i;
+ ULONG offset;
+ PUCHAR pKey = pCipherKey->Key;
+ PUCHAR pTxMic = pCipherKey->TxMic;
+ PUCHAR pRxMic = pCipherKey->RxMic;
+ UCHAR CipherAlg = pCipherKey->CipherAlg;
+
+ /* EKEY*/
+ offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+#ifdef RTMP_MAC_USB
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY, FALSE);
+#endif /* RTMP_MAC_USB */
+ for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
+ {
+ UINT32 Value;
+ RTMP_IO_READ32(pAd, offset + i, &Value);
+ }
+
+ offset += MAX_LEN_OF_PEER_KEY;
+
+ /* MIC KEY*/
+ if (pTxMic)
+ {
+#ifdef RTMP_MAC_USB
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8, FALSE);
+#endif /* RTMP_MAC_USB */
+ }
+ offset += 8;
+ if (pRxMic)
+ {
+#ifdef RTMP_MAC_USB
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8, FALSE);
+#endif /* RTMP_MAC_USB */
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
+ DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ 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]));
+ if (pRxMic)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+ }
+ if (pTxMic)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+ }
+}
+
+/*
+ ========================================================================
+ Description:
+ Remove Pair-wise key material from ASIC.
+
+ Return:
+ ========================================================================
+*/
+VOID AsicRemovePairwiseKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid)
+{
+ /* Set the specific WCID attribute entry as OPEN-NONE */
+ AsicUpdateWcidAttributeEntry(pAd,
+ BSS0,
+ 0,
+ CIPHER_NONE,
+ Wcid,
+ PAIRWISEKEYTABLE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s : Wcid #%d \n", __FUNCTION__, Wcid));
+}
+
+BOOLEAN AsicSendCommandToMcu(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR Command,
+ IN UCHAR Token,
+ IN UCHAR Arg0,
+ IN UCHAR Arg1,
+ IN BOOLEAN in_atomic)
+{
+ if (pAd->chipOps.sendCommandToMcu)
+ return pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1, in_atomic);
+ else
+ return FALSE;
+}
+
+
+BOOLEAN AsicSendCommandToMcuBBP(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Command,
+ IN UCHAR Token,
+ IN UCHAR Arg0,
+ IN UCHAR Arg1,
+ IN BOOLEAN FlgIsNeedLocked)
+{
+ if (pAd->chipOps.sendCommandToMcu)
+ return pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1, FlgIsNeedLocked);
+ else
+ return FALSE;
+}
+
+/*
+ ========================================================================
+ Description:
+ For 1x1 chipset : 2070 / 3070 / 3090 / 3370 / 3390 / 5370 / 5390
+ Usage : 1. Set Default Antenna as initialize
+ 2. Antenna Diversity switching used
+ 3. iwpriv command switch Antenna
+
+ Return:
+ ========================================================================
+ */
+VOID AsicSetRxAnt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ant)
+{
+ if (pAd->chipOps.SetRxAnt)
+ pAd->chipOps.SetRxAnt(pAd, Ant);
+
+}
+
+
+VOID AsicTurnOffRFClk(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+ if (pAd->chipOps.AsicRfTurnOff)
+ {
+ pAd->chipOps.AsicRfTurnOff(pAd);
+ }
+ else
+ {
+#if defined(RT28xx) || defined(RT2880) || defined(RT2883)
+ /* RF R2 bit 18 = 0*/
+ UINT32 R1 = 0, R2 = 0, R3 = 0;
+ UCHAR index;
+ RTMP_RF_REGS *RFRegTable;
+
+ RFRegTable = RF2850RegTable;
+#endif /* defined(RT28xx) || defined(RT2880) || defined(RT2883) */
+
+ switch (pAd->RfIcType)
+ {
+#if defined(RT28xx) || defined(RT2880) || defined(RT2883)
+#if defined(RT28xx) || defined(RT2880)
+ case RFIC_2820:
+ case RFIC_2850:
+ case RFIC_2720:
+ case RFIC_2750:
+#endif /* defined(RT28xx) || defined(RT2880) */
+ for (index = 0; index < NUM_OF_2850_CHNL; index++)
+ {
+ if (Channel == RFRegTable[index].Channel)
+ {
+ R1 = RFRegTable[index].R1 & 0xffffdfff;
+ R2 = RFRegTable[index].R2 & 0xfffbffff;
+ R3 = RFRegTable[index].R3 & 0xfff3ffff;
+
+ RTMP_RF_IO_WRITE32(pAd, R1);
+ RTMP_RF_IO_WRITE32(pAd, R2);
+
+ /* Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. */
+ /* Set RF R2 bit18=0, R3 bit[18:19]=0*/
+ /*if (pAd->StaCfg.bRadio == FALSE)*/
+ if (1)
+ {
+ RTMP_RF_IO_WRITE32(pAd, R3);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
+ Channel, pAd->RfIcType, R2, R3));
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
+ Channel, pAd->RfIcType, R2));
+ break;
+ }
+ }
+ break;
+#endif /* defined(RT28xx) || defined(RT2880) || defined(RT2883) */
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d : Unkonwn RFIC=%d\n",
+ Channel, pAd->RfIcType));
+ break;
+ }
+ }
+}
+
+
+#ifdef WAPI_SUPPORT
+VOID AsicUpdateWAPIPN(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN ULONG pn_low,
+ IN ULONG pn_high)
+{
+ if (IS_HW_WAPI_SUPPORT(pAd))
+ {
+ ULONG offset;
+
+ offset = WAPI_PN_TABLE_BASE + (WCID * WAPI_PN_ENTRY_SIZE);
+
+ RTMP_IO_WRITE32(pAd, offset, pn_low);
+ RTMP_IO_WRITE32(pAd, offset + 4, pn_high);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("%s : Not support HW_WAPI_PN_TABLE\n",
+ __FUNCTION__));
+ }
+
+}
+#endif /* WAPI_SUPPORT */
+
+
+
+#ifdef VCORECAL_SUPPORT
+VOID AsicVCORecalibration(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR RFValue = 0;
+ UINT32 TxPinCfg = 0;
+ UINT8 mode = pAd->chipCap.FlgIsVcoReCalMode;
+
+ if (mode == VCO_CAL_DISABLE)
+ return;
+
+#ifdef RTMP_INTERNAL_TX_ALC
+#endif /* RTMP_INTERNAL_TX_ALC */
+
+ RTMP_IO_READ32(pAd, TX_PIN_CFG, &TxPinCfg);
+ TxPinCfg &= 0xFCFFFFF0;
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+
+ switch (mode)
+ {
+ case VCO_CAL_MODE_1:
+ RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue);
+ RFValue = RFValue | 0x01; /* bit 0=vcocal_en*/
+ RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue);
+ break;
+
+ case VCO_CAL_MODE_2:
+ RT30xxReadRFRegister(pAd, RF_R03, (PUCHAR)&RFValue);
+ RFValue = RFValue | 0x80; /* bit 7=vcocal_en*/
+ RT30xxWriteRFRegister(pAd, RF_R03, (UCHAR)RFValue);
+ break;
+
+ default:
+ return;
+ }
+
+ RtmpOsMsDelay(1);
+
+ RTMP_IO_READ32(pAd, TX_PIN_CFG, &TxPinCfg);
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ if (pAd->Antenna.field.TxPath == 1)
+ TxPinCfg |= 0x2;
+ else if (pAd->Antenna.field.TxPath == 2)
+ TxPinCfg |= 0xA;
+ else if (pAd->Antenna.field.TxPath == 3)
+ TxPinCfg |= 0x0200000A;
+ }
+ else
+ {
+ if (pAd->Antenna.field.TxPath == 1)
+ TxPinCfg |= 0x1;
+ else if (pAd->Antenna.field.TxPath == 2)
+ TxPinCfg |= 0x5;
+ else if (pAd->Antenna.field.TxPath == 3)
+ TxPinCfg |= 0x01000005;
+ }
+#ifdef RT5592
+#ifdef RT5592EP_SUPPORT
+ if (IS_RT5592(pAd) && IS_PCIE_INF(pAd))
+ {
+ /* For 5592EP, use PA_PE_A0/A1 instead of G0/G1 */
+ if (pAd->chipCap.Priv == RT5592_TYPE_EP && pAd->CommonCfg.Channel <= 14)
+ {
+ if (pAd->Antenna.field.TxPath == 1)
+ TxPinCfg |= 0x1;
+ else if (pAd->Antenna.field.TxPath == 2)
+ TxPinCfg |= 0x5;
+ }
+ }
+#endif /* RT5592EP_SUPPORT */
+#endif /* RT5592 */
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+
+#ifdef TXBF_SUPPORT
+ // Do a Divider Calibration and update BBP registers
+ if (pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn
+#ifdef DBG_CTRL_SUPPORT
+ && (pAd->CommonCfg.DebugFlags & DBF_DISABLE_CAL)==0
+#endif /* DBG_CTRL_SUPPORT */
+ )
+ {
+ ITxBFDividerCalibration(pAd, 2, 0, NULL);
+ }
+
+ if (pAd->CommonCfg.ETxBfEnCond)
+ {
+ INT idx;
+
+ for (idx = 1; idx < MAX_LEN_OF_MAC_TABLE; idx++)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+
+ pEntry = &pAd->MacTab.Content[idx];
+ if ((IS_ENTRY_CLIENT(pEntry)) && (pEntry->eTxBfEnCond))
+ {
+ BOOLEAN Cancelled;
+
+ RTMPCancelTimer(&pEntry->eTxBfProbeTimer, &Cancelled);
+
+ pEntry->bfState = READY_FOR_SNDG0;
+ eTxBFProbing(pAd, pEntry);
+ }
+ }
+ }
+#endif // TXBF_SUPPORT //
+}
+#endif /* VCORECAL_SUPPORT */
+
+
+#ifdef STREAM_MODE_SUPPORT
+// StreamModeRegVal - return MAC reg value for StreamMode setting
+UINT32 StreamModeRegVal(
+ IN RTMP_ADAPTER *pAd)
+{
+ UINT32 streamWord;
+
+ switch (pAd->CommonCfg.StreamMode)
+ {
+ case 1:
+ streamWord = 0x030000;
+ break;
+ case 2:
+ streamWord = 0x0c0000;
+ break;
+ case 3:
+ streamWord = 0x0f0000;
+ break;
+ default:
+ streamWord = 0x0;
+ break;
+ }
+
+ return streamWord;
+}
+
+
+/*
+ ========================================================================
+ Description:
+ configure the stream mode of specific MAC or all MAC and set to ASIC.
+
+ Prameters:
+ pAd ---
+ pMacAddr ---
+ bClear --- disable the stream mode for specific macAddr when
+ (pMacAddr!=NULL)
+
+ Return:
+ ========================================================================
+*/
+VOID AsicSetStreamMode(
+ IN RTMP_ADAPTER *pAd,
+ IN PUCHAR pMacAddr,
+ IN INT chainIdx,
+ IN BOOLEAN bEnabled)
+{
+ UINT32 streamWord;
+ UINT32 regAddr, regVal;
+
+
+ if (!pAd->chipCap.FlgHwStreamMode)
+ return;
+
+ streamWord = StreamModeRegVal(pAd);
+ if (!bEnabled)
+ streamWord = 0;
+
+ regAddr = TX_CHAIN_ADDR0_L + chainIdx * 4;
+ RTMP_IO_WRITE32(pAd, regAddr,
+ (UINT32)(pMacAddr[0]) |
+ (UINT32)(pMacAddr[1] << 8) |
+ (UINT32)(pMacAddr[2] << 16) |
+ (UINT32)(pMacAddr[3] << 24));
+
+ RTMP_IO_READ32(pAd, regAddr + 4, &regVal);
+ regVal &= (~0x000f0000);
+ RTMP_IO_WRITE32(pAd, regAddr + 4,
+ (regVal | streamWord) |
+ (UINT32)(pMacAddr[4]) |
+ (UINT32)(pMacAddr[5] << 8));
+
+}
+
+
+VOID RtmpStreamModeInit(
+ IN RTMP_ADAPTER *pAd)
+{
+ int chainIdx;
+ UCHAR *pMacAddr;
+
+ if (pAd->chipCap.FlgHwStreamMode == FALSE)
+ return;
+
+ for (chainIdx = 0; chainIdx < STREAM_MODE_STA_NUM; chainIdx++)
+ {
+ pMacAddr = &pAd->CommonCfg.StreamModeMac[chainIdx][0];
+ AsicSetStreamMode(pAd, pMacAddr, chainIdx, TRUE);
+ }
+}
+
+
+/* Enable the stream mode*/
+
+/* Parameters*/
+/* pAd: The adapter data structure*/
+
+/* Return Value:*/
+/* None*/
+
+VOID AsicEnableStreamMode(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_CHAIN_ADDR0_L_STRUC TxChainAddr0L = {{0}};
+ TX_CHAIN_ADDR0_H_STRUC TxChainAddr0H = {{0}};
+ TX_CHAIN_ADDR1_H_STRUC TxChainAddr1H = {{0}};
+ TX_CHAIN_ADDR2_H_STRUC TxChainAddr2H = {{0}};
+ TX_CHAIN_ADDR3_H_STRUC TxChainAddr3H = {{0}};
+
+ DBGPRINT(RT_DEBUG_INFO, ("---> %s\n", __FUNCTION__));
+
+ /* Chain #0 for broadcast*/
+ TxChainAddr0L.field.TxChainAddr0L_Byte3 = 0xFF;
+ TxChainAddr0L.field.TxChainAddr0L_Byte2 = 0xFF;
+ TxChainAddr0L.field.TxChainAddr0L_Byte1 = 0xFF;
+ TxChainAddr0L.field.TxChainAddr0L_Byte0 = 0xFF;
+ RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_L, TxChainAddr0L.word);
+
+ RTMP_IO_READ32(pAd, TX_CHAIN_ADDR0_H, &TxChainAddr0H.word);
+ TxChainAddr0H.field.TxChainAddr0H_Byte4 = 0xFF;
+ TxChainAddr0H.field.TxChainAddr0H_Byte5 = 0xFF;
+ TxChainAddr0H.field.TxChainSel0 = 0xF; /* Enable the stream mode for chain #0*/
+ RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_H, TxChainAddr0H.word);
+
+ RTMP_IO_READ32(pAd, TX_CHAIN_ADDR1_H, &TxChainAddr1H.word);
+ TxChainAddr1H.field.TxChainSel0 = 0xF; /* Enable the stream mode for chain #1*/
+ RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR1_H, TxChainAddr1H.word);
+
+ RTMP_IO_READ32(pAd, TX_CHAIN_ADDR2_H, &TxChainAddr2H.word);
+ TxChainAddr2H.field.TxChainSel0 = 0xF; /* Enable the stream mode for chain #2*/
+ RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR2_H, TxChainAddr2H.word);
+
+ RTMP_IO_READ32(pAd, TX_CHAIN_ADDR3_H, &TxChainAddr3H.word);
+ TxChainAddr3H.field.TxChainSel0 = 0xF; /* Enable the stream mode for chain #3*/
+ RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR3_H, TxChainAddr3H.word);
+
+ DBGPRINT(RT_DEBUG_INFO, ("<--- %s\n", __FUNCTION__));
+}
+
+
+/* Disable the stream mode*/
+
+/* Parameters*/
+/* pAd: The adapter data structure*/
+
+/* Return Value:*/
+/* None*/
+
+VOID AsicDisableStreamMode(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_CHAIN_ADDR0_L_STRUC TxChainAddr0L = {{0}};
+ TX_CHAIN_ADDR0_H_STRUC TxChainAddr0H = {{0}};
+ TX_CHAIN_ADDR1_H_STRUC TxChainAddr1H = {{0}};
+ TX_CHAIN_ADDR2_H_STRUC TxChainAddr2H = {{0}};
+ TX_CHAIN_ADDR3_H_STRUC TxChainAddr3H = {{0}};
+
+ DBGPRINT(RT_DEBUG_INFO, ("---> %s\n", __FUNCTION__));
+
+ /* Chain #0 for broadcast*/
+ TxChainAddr0L.field.TxChainAddr0L_Byte3 = 0xFF;
+ TxChainAddr0L.field.TxChainAddr0L_Byte2 = 0xFF;
+ TxChainAddr0L.field.TxChainAddr0L_Byte1 = 0xFF;
+ TxChainAddr0L.field.TxChainAddr0L_Byte0 = 0xFF;
+ RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_L, TxChainAddr0L.word);
+
+ RTMP_IO_READ32(pAd, TX_CHAIN_ADDR0_H, &TxChainAddr0H.word);
+ TxChainAddr0H.field.TxChainAddr0H_Byte4 = 0xFF;
+ TxChainAddr0H.field.TxChainAddr0H_Byte5 = 0xFF;
+ TxChainAddr0H.field.TxChainSel0 = 0x0; /* Disable the stream mode for chain #0*/
+ RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR0_H, TxChainAddr0H.word);
+
+ RTMP_IO_READ32(pAd, TX_CHAIN_ADDR1_H, &TxChainAddr1H.word);
+ TxChainAddr1H.field.TxChainSel0 = 0x0; /* Disable the stream mode for chain #1*/
+ RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR1_H, TxChainAddr1H.word);
+
+ RTMP_IO_READ32(pAd, TX_CHAIN_ADDR2_H, &TxChainAddr2H.word);
+ TxChainAddr2H.field.TxChainSel0 = 0x0; /* Disable the stream mode for chain #2*/
+ RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR2_H, TxChainAddr2H.word);
+
+ RTMP_IO_READ32(pAd, TX_CHAIN_ADDR3_H, &TxChainAddr3H.word);
+ TxChainAddr3H.field.TxChainSel0 = 0x0; /* Disable the stream mode for chain #3*/
+ RTMP_IO_WRITE32(pAd, TX_CHAIN_ADDR3_H, TxChainAddr3H.word);
+
+ DBGPRINT(RT_DEBUG_INFO, ("<--- %s\n", __FUNCTION__));
+}
+#endif // STREAM_MODE_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableRalinkBurstMode(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Data = 0;
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ pAd->CommonCfg.RestoreBurstMode = Data;
+ Data &= 0xFFF00000;
+ Data |= 0x86380;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDisableRalinkBurstMode(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Data = 0;
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+
+ Data = pAd->CommonCfg.RestoreBurstMode;
+ Data &= 0xFFFFFF00;
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
+#ifdef DOT11_N_SUPPORT
+ && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE))
+ Data |= 0x80;
+ else if (pAd->CommonCfg.bEnableTxBurst)
+ Data |= 0x20;
+ }
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+}
+#endif // DOT11_N_SUPPORT //
+
+
+VOID RtmpUpdateFilterCoefficientControl(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+ UCHAR BBPValue = 0;
+
+ if (Channel == 14)
+ {
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ {
+ /* when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1 */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue |= 0x20; /* set bit5=1 */
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ }
+ }
+}
+
+#ifdef WOW_SUPPORT
+#ifdef RTMP_MAC_USB
+
+/* switch firmware
+ a) before into WOW mode, switch firmware to WOW-enable firmware
+ b) exit from WOW mode, switch firmware to normal firmware
+*/
+VOID AsicLoadWOWFirmware(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN WOW)
+{
+ if (WOW)
+ pAd->WOW_Cfg.bWOWFirmware = TRUE;
+ else
+ pAd->WOW_Cfg.bWOWFirmware = FALSE;
+
+ RtmpAsicLoadFirmware(pAd);
+}
+
+/* In WOW mode, 8051 mcu will send null frame, and pick data from 0x7780
+ * the null frame includes TxWI and 802.11 header */
+VOID AsicWOWSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull)
+{
+
+ PTXWI_STRUC TxWI;
+ PUCHAR NullFrame;
+ UINT8 packet_len;
+ PUCHAR ptr;
+ USHORT offset;
+ UINT32 cipher = pAd->StaCfg.GroupCipher;
+ UINT32 Value;
+ UINT8 TXWISize = pAd->chipCap.TXWISize;
+
+
+ ComposeNullFrame(pAd);
+ TxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+ NullFrame = (PUCHAR)&pAd->NullFrame;
+ packet_len = TxWI->MPDUtotalByteCount;
+
+ DBGPRINT(RT_DEBUG_OFF, ("TxWI:\n"));
+ /* copy TxWI to MCU memory */
+ ptr = (PUCHAR)TxWI;
+ for (offset = 0; offset < TXWISize; offset += 4)
+ {
+ RTMPMoveMemory(&Value, ptr+offset, 4);
+ DBGPRINT(RT_DEBUG_OFF, ("offset: %02d %08x\n", offset, Value));
+ RTMP_IO_WRITE32(pAd, HW_NULL2_BASE + offset, Value);
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("802.11 header:\n"));
+ /* copy 802.11 header to memory */
+ ptr = (PUCHAR)NullFrame;
+ for (offset = 0; offset < packet_len; offset += 4)
+ {
+ RTMPMoveMemory(&Value, ptr+offset, 4);
+ DBGPRINT(RT_DEBUG_OFF, ("offset: %02d %08x\n", offset, Value));
+ RTMP_IO_WRITE32(pAd, HW_NULL2_BASE + TXWISize + offset, Value);
+ }
+
+ DBGPRINT(RT_DEBUG_OFF, ("Write GroupCipher Mode: %d\n", pAd->StaCfg.GroupCipher));
+
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &Value);
+
+ switch (cipher) /* don't care WEP, because it dosen't have re-key issue */
+ {
+ case Ndis802_11Encryption2Enabled: /* TKIP */
+ Value |= 0x0330;
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, Value);
+ break;
+ case Ndis802_11Encryption3Enabled: /* AES */
+ Value |= 0x0440;
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, Value);
+ break;
+ }
+}
+
+#endif /* RTMP_MAC_USB */
+#endif /* WOW_SUPPORT */