From: Bartlomiej Zolnierkiewicz Subject: [PATCH] Staging: rt2860: add RT3090 chipset support Add support for RT3090 chipset (based on 2009_0612_RT3090_Linux_STA_V2.1.0.0_DPO). Tested with RT2860. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/staging/rt2860/Kconfig | 5 drivers/staging/rt2860/Makefile | 7 drivers/staging/rt2860/chip/mac_pci.h | 12 drivers/staging/rt2860/chip/rt3090.h | 72 +++++ drivers/staging/rt2860/chip/rtmp_phy.h | 183 ++++++++++++ drivers/staging/rt2860/chips/rt3090.c | 123 ++++++++ drivers/staging/rt2860/chips/rt30xx.c | 12 drivers/staging/rt2860/common/cmm_asic.c | 29 ++ drivers/staging/rt2860/common/cmm_data_pci.c | 6 drivers/staging/rt2860/common/cmm_mac_pci.c | 255 ++++++++++++++--- drivers/staging/rt2860/common/cmm_profile.c | 43 +++ drivers/staging/rt2860/common/cmm_sync.c | 13 drivers/staging/rt2860/common/mlme.c | 112 +++++-- drivers/staging/rt2860/common/rt_rf.c | 8 drivers/staging/rt2860/common/rtmp_init.c | 73 ++++- drivers/staging/rt2860/common/rtmp_mcu.c | 98 ++++++ drivers/staging/rt2860/common/rtmp_timer.c | 4 drivers/staging/rt2860/iface/rtmp_pci.h | 2 drivers/staging/rt2860/pci_main_dev.c | 384 ++++++++++++++++++++++++--- drivers/staging/rt2860/rt_linux.c | 3 drivers/staging/rt2860/rt_linux.h | 13 drivers/staging/rt2860/rt_main_dev.c | 17 - drivers/staging/rt2860/rt_pci_rbus.c | 4 drivers/staging/rt2860/rtmp.h | 49 ++- drivers/staging/rt2860/rtmp_chip.h | 3 drivers/staging/rt2860/rtmp_def.h | 5 drivers/staging/rt2860/sta/assoc.c | 12 drivers/staging/rt2860/sta/auth_rsp.c | 4 drivers/staging/rt2860/sta/connect.c | 190 ++----------- drivers/staging/rt2860/sta/rtmp_data.c | 1 drivers/staging/rt2860/sta/sync.c | 26 + drivers/staging/rt2860/sta/wpa.c | 48 --- drivers/staging/rt2860/sta_ioctl.c | 7 drivers/staging/rt2860/wpa.h | 7 drivers/staging/rt3090/common/rtmp_mcu.c | 8 drivers/staging/rt3090/firmware.h | 2 36 files changed, 1416 insertions(+), 424 deletions(-) Index: b/drivers/staging/rt2860/Kconfig =================================================================== --- a/drivers/staging/rt2860/Kconfig +++ b/drivers/staging/rt2860/Kconfig @@ -1,5 +1,6 @@ config RT2860 - tristate "Ralink 2860 wireless support" + tristate "Ralink 2860/3090 wireless support" depends on PCI && X86 && WLAN_80211 ---help--- - This is an experimental driver for the Ralink 2860 wireless chip. + This is an experimental driver for the Ralink 2860 and 3090 + wireless chips. Index: b/drivers/staging/rt2860/Makefile =================================================================== --- a/drivers/staging/rt2860/Makefile +++ b/drivers/staging/rt2860/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_RT2860) += rt2860sta.o # TODO: all of these should be removed EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT EXTRA_CFLAGS += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT2860 +EXTRA_CFLAGS += -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRT30xx -DRT3090 EXTRA_CFLAGS += -DDBG rt2860sta-objs := \ @@ -46,4 +47,8 @@ rt2860sta-objs := \ common/cmm_mac_pci.o \ common/cmm_data_pci.o \ common/ee_prom.o \ - common/rtmp_mcu.o + common/rtmp_mcu.o \ + common/ee_efuse.o \ + chips/rt30xx.o \ + common/rt_rf.o \ + chips/rt3090.o Index: b/drivers/staging/rt2860/chip/mac_pci.h =================================================================== --- a/drivers/staging/rt2860/chip/mac_pci.h +++ b/drivers/staging/rt2860/chip/mac_pci.h @@ -133,6 +133,18 @@ typedef struct PACKED _RXD_STRUC{ UINT32 Rsv1:13; } RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC; +typedef union _TX_ATTENUATION_CTRL_STRUC { + struct + { + ULONG RF_ISOLATION_ENABLE:1; + ULONG Reserve2:7; + ULONG PCIE_PHY_TX_ATTEN_VALUE:3; + ULONG PCIE_PHY_TX_ATTEN_EN:1; + ULONG Reserve1:20; + } field; + + ULONG word; +} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC; /* ----------------- EEPROM Related MACRO ----------------- */ Index: b/drivers/staging/rt2860/chip/rt3090.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chip/rt3090.h @@ -0,0 +1,72 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rt3090.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __RT3090_H__ +#define __RT3090_H__ + +#ifdef RT3090 + +#ifndef RTMP_PCI_SUPPORT +#error "For RT3090, you should define the compile flag -DRTMP_PCI_SUPPORT" +#endif + +#ifndef RTMP_MAC_PCI +#error "For RT3090, you should define the compile flag -DRTMP_MAC_PCI" +#endif + +#ifndef RTMP_RF_RW_SUPPORT +#error "For RT3090, you should define the compile flag -DRTMP_RF_RW_SUPPORT" +#endif + +#ifndef RT30xx +#error "For RT3090, you should define the compile flag -DRT30xx" +#endif + +#define PCIE_PS_SUPPORT + +#include "mac_pci.h" +#include "rt30xx.h" + +// +// Device ID & Vendor ID, these values should match EEPROM value +// +#define NIC3090_PCIe_DEVICE_ID 0x3090 // 1T/1R miniCard +#define NIC3091_PCIe_DEVICE_ID 0x3091 // 1T/2R miniCard +#define NIC3092_PCIe_DEVICE_ID 0x3092 // 2T/2R miniCard + +#endif // RT3090 // + +#endif //__RT3090_H__ // Index: b/drivers/staging/rt2860/chip/rtmp_phy.h =================================================================== --- a/drivers/staging/rt2860/chip/rtmp_phy.h +++ b/drivers/staging/rt2860/chip/rtmp_phy.h @@ -278,6 +278,7 @@ But for some chipset which didn't have mcu (e.g., RBUS based chipset), we will use this function too and didn't access the bbp register via the MCU. */ +#if 0 #define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \ do{ \ if ((_A)->bPCIclkOff == FALSE) \ @@ -288,7 +289,99 @@ RTMP_BBP_IO_READ8((_A), (_I), (_pV), TRUE); \ } \ }while(0) - +#else +// Read BBP register by register's ID. Generate PER to test BA +#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \ +{ \ + BBP_CSR_CFG_STRUC BbpCsr; \ + int i, k; \ + BOOLEAN brc; \ + BbpCsr.field.Busy = IDLE; \ + if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ + && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \ + && ((_A)->bPCIclkOff == FALSE) \ + && ((_A)->brt30xxBanMcuCmd == FALSE)) \ + { \ + for (i=0; iStaCfg.PSControl.field.rt30xxPowerMode == 3) \ + && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \ + && ((_A)->bPCIclkOff == FALSE)) \ + { \ + for (i=0; ibrt30xxBanMcuCmd, (_I))); \ + *(_pV) = (_A)->BbpWriteLatch[_I]; \ + } \ + if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE)) \ + { \ + DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word)); \ + *(_pV) = (_A)->BbpWriteLatch[_I]; \ + } \ +} +#endif // 0 // /* basic marco for BBP write operation. @@ -348,6 +441,7 @@ But for some chipset which didn't have mcu (e.g., RBUS based chipset), we will use this function too and didn't access the bbp register via the MCU. */ +#if 0 #define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \ do{ \ if ((_A)->bPCIclkOff == FALSE) \ @@ -358,6 +452,93 @@ RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), TRUE); \ } \ }while(0) +#else +// Write BBP register by register's ID & value +#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \ +{ \ + BBP_CSR_CFG_STRUC BbpCsr; \ + INT BusyCnt = 0; \ + BOOLEAN brc; \ + if (_I < MAX_NUM_OF_BBP_LATCH) \ + { \ + if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ + && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \ + && ((_A)->bPCIclkOff == FALSE) \ + && ((_A)->brt30xxBanMcuCmd == FALSE)) \ + { \ + if (_A->AccessBBPFailCount > 20) \ + { \ + AsicResetBBPAgent(_A); \ + _A->AccessBBPFailCount = 0; \ + } \ + for (BusyCnt=0; BusyCntBbpWriteLatch[_I] = _V; \ + } \ + else \ + { \ + BbpCsr.field.Busy = 0; \ + RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ + } \ + break; \ + } \ + } \ + else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ + && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \ + && ((_A)->bPCIclkOff == FALSE)) \ + { \ + if (_A->AccessBBPFailCount > 20) \ + { \ + AsicResetBBPAgent(_A); \ + _A->AccessBBPFailCount = 0; \ + } \ + for (BusyCnt=0; BusyCntBbpWriteLatch[_I] = _V; \ + break; \ + } \ + } \ + else \ + { \ + DBGPRINT_ERR((" brt30xxBanMcuCmd = %d. Write BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \ + } \ + if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE)) \ + { \ + if (BusyCnt == MAX_BUSY_COUNT) \ + (_A)->AccessBBPFailCount++; \ + DBGPRINT_ERR(("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff )); \ + } \ + } \ + else \ + { \ + DBGPRINT_ERR(("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n")); \ + } \ +} +#endif // 0 // #endif // RTMP_MAC_PCI // #ifdef RTMP_MAC_USB Index: b/drivers/staging/rt2860/chips/rt3090.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chips/rt3090.c @@ -0,0 +1,123 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rt3090.c + + Abstract: + Specific funcitons and variables for RT3070 + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifdef RT3090 + +#include "../rt_config.h" + + +#ifndef RTMP_RF_RW_SUPPORT +#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip" +#endif // RTMP_RF_RW_SUPPORT // + + +VOID NICInitRT3090RFRegisters(IN PRTMP_ADAPTER pAd) +{ + INT i; + // Driver must read EEPROM to get RfIcType before initial RF registers + // Initialize RF register to default value + if (IS_RT3090(pAd)) + { + // Init RF calibration + // Driver should toggle RF R30 bit7 before init RF registers + UINT32 RfReg = 0, data; + + RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg); + RfReg |= 0x80; + RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg); + RTMPusecDelay(1000); + RfReg &= 0x7F; + RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg); + + // init R24, R31 + RT30xxWriteRFRegister(pAd, RF_R24, 0x0F); + RT30xxWriteRFRegister(pAd, RF_R31, 0x0F); + + // RT309x version E has fixed this issue + if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) + { + // patch tx EVM issue temporarily + RTMP_IO_READ32(pAd, LDO_CFG0, &data); + data = ((data & 0xE0FFFFFF) | 0x0D000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, data); + } + else + { + RTMP_IO_READ32(pAd, LDO_CFG0, &data); + data = ((data & 0xE0FFFFFF) | 0x01000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, data); + } + + // patch LNA_PE_G1 failed issue + RTMP_IO_READ32(pAd, GPIO_SWITCH, &data); + data &= ~(0x20); + RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data); + + // Initialize RF register to default value + for (i = 0; i < NUM_RF_REG_PARMS; i++) + { + RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value); + } + + // Driver should set RF R6 bit6 on before calibration + RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg); + RfReg |= 0x40; + RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg); + + //For RF filter Calibration + RTMPFilterCalibration(pAd); + + // Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() + if ((pAd->MACVersion & 0xffff) < 0x0211) + RT30xxWriteRFRegister(pAd, RF_R27, 0x3); + + // set led open drain enable + RTMP_IO_READ32(pAd, OPT_14, &data); + data |= 0x01; + RTMP_IO_WRITE32(pAd, OPT_14, data); + + // set default antenna as main + if (pAd->RfIcType == RFIC_3020) + AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); + + // add by johnli, RF power sequence setup, load RF normal operation-mode setup + RT30xxLoadRFNormalModeSetup(pAd); + } + +} + +#endif // RT3090 // Index: b/drivers/staging/rt2860/chips/rt30xx.c =================================================================== --- a/drivers/staging/rt2860/chips/rt30xx.c +++ b/drivers/staging/rt2860/chips/rt30xx.c @@ -101,7 +101,13 @@ VOID RT30xxSetRxAnt( if (Ant == 0) { // Main antenna +#ifdef RTMP_MAC_PCI + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x |= (EESK); + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); +#else AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0); +#endif // RTMP_MAC_PCI // RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); Value &= ~(0x0808); @@ -111,7 +117,13 @@ VOID RT30xxSetRxAnt( else { // Aux antenna +#ifdef RTMP_MAC_PCI + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EESK); + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); +#else AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0); +#endif // RTMP_MAC_PCI // RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); Value &= ~(0x0808); Value |= 0x08; Index: b/drivers/staging/rt2860/common/cmm_asic.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_asic.c +++ b/drivers/staging/rt2860/common/cmm_asic.c @@ -808,6 +808,28 @@ VOID AsicSwitchChannel( RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); +#if defined(RT3090) || defined(RT3390) + // PCIe PHY Transmit attenuation adjustment + if (IS_RT3090A(pAd) || IS_RT3390(pAd)) + { + TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = {0}; + + RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, &TxAttenuationCtrl.word); + + if (Channel == 14) // Channel #14 + { + TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1; // Enable PCIe PHY Tx attenuation + TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4; // 9/16 full drive level + } + else // Channel #1~#13 + { + TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0; // Disable PCIe PHY Tx attenuation + TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0; // n/a + } + + RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, TxAttenuationCtrl.word); + } +#endif } else { @@ -2477,6 +2499,13 @@ VOID AsicTurnOnRFClk( UCHAR index; RTMP_RF_REGS *RFRegTable; +#ifdef PCIE_PS_SUPPORT + // The RF programming sequence is difference between 3xxx and 2xxx + if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) + { + return; + } +#endif // PCIE_PS_SUPPORT // RFRegTable = RF2850RegTable; Index: b/drivers/staging/rt2860/common/cmm_data_pci.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_data_pci.c +++ b/drivers/staging/rt2860/common/cmm_data_pci.c @@ -638,9 +638,6 @@ BOOLEAN RTMPHandleTxRingDmaDoneInterrupt if (TxRingBitmap.field.Ac0DmaDone) bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE); - if (TxRingBitmap.field.HccaDmaDone) - bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA); - if (TxRingBitmap.field.Ac3DmaDone) bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO); @@ -791,7 +788,6 @@ VOID RTMPHandleRxCoherentInterrupt( RTMPRingCleanUp(pAd, QID_AC_BK); RTMPRingCleanUp(pAd, QID_AC_VI); RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_HCCA); RTMPRingCleanUp(pAd, QID_MGMT); RTMPRingCleanUp(pAd, QID_RX); @@ -1147,7 +1143,5 @@ VOID RTMPWriteTxDescriptor( pTxD->QSEL= (QueueSEL); //RT2860c?? fixed using EDCA queue for test... We doubt Queue1 has problem. 2006-09-26 Jan //pTxD->QSEL= FIFO_EDCA; - if (pAd->bGenOneHCCA == TRUE) - pTxD->QSEL= FIFO_HCCA; pTxD->DMADONE = 0; } Index: b/drivers/staging/rt2860/common/cmm_mac_pci.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_mac_pci.c +++ b/drivers/staging/rt2860/common/cmm_mac_pci.c @@ -414,7 +414,6 @@ VOID RTMPRingCleanUp( case QID_AC_BE: case QID_AC_VI: case QID_AC_VO: - case QID_HCCA: pTxRing = &pAd->TxRing[RingType]; @@ -860,11 +859,14 @@ VOID RT28xxPciStaAsicForceWakeup( OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW); -#ifdef RTMP_PCI_SUPPORT - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) + &&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) { // Support PCIe Advance Power Save - if (bFromTx == TRUE) + if (bFromTx == TRUE + &&(pAd->Mlme.bPsPollTimerRunning == TRUE)) { pAd->Mlme.bPsPollTimerRunning = FALSE; RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); @@ -877,6 +879,17 @@ VOID RT28xxPciStaAsicForceWakeup( if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE)) { +#ifdef PCIE_PS_SUPPORT + // add by johnli, RF power sequence setup, load RF normal operation-mode setup + if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) + { + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + + if (pChipOps->AsicReverseRfFromSleepMode) + pChipOps->AsicReverseRfFromSleepMode(pAd); + } + else +#endif // PCIE_PS_SUPPORT // { // end johnli // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. @@ -895,11 +908,24 @@ VOID RT28xxPciStaAsicForceWakeup( } } } +#ifdef PCIE_PS_SUPPORT + // 3090 MCU Wakeup command needs more time to be stable. + // Before stable, don't issue other MCU command to prevent from firmware error. + if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("<==RT28xxPciStaAsicForceWakeup::Release the MCU Lock(3090)\n")); + RTMP_SEM_LOCK(&pAd->McuCmdLock); + pAd->brt30xxBanMcuCmd = FALSE; + RTMP_SEM_UNLOCK(&pAd->McuCmdLock); + } +#endif // PCIE_PS_SUPPORT // } else -#endif // RTMP_PCI_SUPPORT // { // PCI, 2860-PCIe + DBGPRINT(RT_DEBUG_TRACE, ("<==RT28xxPciStaAsicForceWakeup::Original PCI Power Saving\n")); AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); AutoWakeupCfg.word = 0; RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); @@ -922,7 +948,8 @@ VOID RT28xxPciStaAsicSleepThenAutoWakeup OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); return; } - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) + &&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) { ULONG Now = 0; if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) @@ -972,7 +999,6 @@ VOID RT28xxPciStaAsicSleepThenAutoWakeup } -#ifdef RTMP_PCI_SUPPORT VOID PsPollWakeExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, @@ -990,6 +1016,17 @@ VOID PsPollWakeExec( } pAd->Mlme.bPsPollTimerRunning = FALSE; RTMP_INT_UNLOCK(&pAd->irq_lock, flags); +#ifdef PCIE_PS_SUPPORT + // For rt30xx power solution 3, Use software timer to wake up in psm. So call + // AsicForceWakeup here instead of handling twakeup interrupt. + if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) + { + DBGPRINT(RT_DEBUG_TRACE,("<--PsPollWakeExec::3090 calls AsicForceWakeup(pAd, DOT11POWERSAVE) in advance \n")); + AsicForceWakeup(pAd, DOT11POWERSAVE); + } +#endif // PCIE_PS_SUPPORT // } VOID RadioOnExec( @@ -1006,18 +1043,34 @@ VOID RadioOnExec( if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n")); +//KH Debug: Add the compile flag "RT2860 and condition +#ifdef RTMP_PCI_SUPPORT + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) + &&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); +#endif // RTMP_PCI_SUPPORT // return; } if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n")); +#ifdef RTMP_PCI_SUPPORT +if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) + &&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); +#endif // RTMP_PCI_SUPPORT // return; } +//KH Debug: need to check. I add the compile flag "CONFIG_STA_SUPPORT" to enclose the following codes. +#ifdef RTMP_PCI_SUPPORT +if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) + &&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) + { pAd->Mlme.bPsPollTimerRunning = FALSE; RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); + } +#endif // RTMP_PCI_SUPPORT // if (pAd->StaCfg.bRadio == TRUE) { pAd->bPCIclkOff = FALSE; @@ -1025,7 +1078,6 @@ VOID RadioOnExec( RTMPRingCleanUp(pAd, QID_AC_BE); RTMPRingCleanUp(pAd, QID_AC_VI); RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_HCCA); RTMPRingCleanUp(pAd, QID_MGMT); RTMPRingCleanUp(pAd, QID_RX); @@ -1058,9 +1110,23 @@ VOID RadioOnExec( AsicLockChannel(pAd, pAd->CommonCfg.Channel); } +//KH Debug:The following codes should be enclosed by RT3090 compile flag if (pChipOps->AsicReverseRfFromSleepMode) pChipOps->AsicReverseRfFromSleepMode(pAd); +#ifdef PCIE_PS_SUPPORT +// 3090 MCU Wakeup command needs more time to be stable. +// Before stable, don't issue other MCU command to prevent from firmware error. +if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) + { + RTMP_SEM_LOCK(&pAd->McuCmdLock); + pAd->brt30xxBanMcuCmd = FALSE; + RTMP_SEM_UNLOCK(&pAd->McuCmdLock); + } +#endif // PCIE_PS_SUPPORT // + // Clear Radio off flag RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); @@ -1077,8 +1143,6 @@ VOID RadioOnExec( RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0); } } -#endif // RTMP_PCI_SUPPORT // - /* ========================================================================== @@ -1102,12 +1166,24 @@ BOOLEAN RT28xxPciAsicRadioOn( if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE) return FALSE; -#ifdef RTMP_PCI_SUPPORT - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) + { + if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) { pAd->Mlme.bPsPollTimerRunning = FALSE; RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE)) + } + if ((pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)&& + ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE)) + ||(RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))) + { + // Some chips don't need to delay 6ms, so copy RTMPPCIePowerLinkCtrlRestore + // return condition here. + /* + if (((pAd->MACVersion&0xffff0000) != 0x28600000) + && ((pAd->DeviceID == NIC2860_PCIe_DEVICE_ID) + ||(pAd->DeviceID == NIC2790_PCIe_DEVICE_ID))) + */ { DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n")); // 1. Set PCI Link Control in Configuration Space. @@ -1115,9 +1191,17 @@ BOOLEAN RT28xxPciAsicRadioOn( RTMPusecDelay(6000); } } -#endif // RTMP_PCI_SUPPORT // + } +#ifdef PCIE_PS_SUPPORT +if (!(((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)))) +#endif // PCIE_PS_SUPPORT // + { pAd->bPCIclkOff = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("PSM :309xbPCIclkOff == %d\n", pAd->bPCIclkOff)); + } // 2. Send wake up command. AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02); pAd->bPCIclkOff = FALSE; @@ -1125,10 +1209,32 @@ BOOLEAN RT28xxPciAsicRadioOn( AsicCheckCommanOk(pAd, PowerWakeCID); RTMP_ASIC_INTERRUPT_ENABLE(pAd); - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); if (Level == GUI_IDLE_POWER_SAVE) { +#ifdef PCIE_PS_SUPPORT + + // add by johnli, RF power sequence setup, load RF normal operation-mode setup + if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) + { + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + + if (pChipOps->AsicReverseRfFromSleepMode) + pChipOps->AsicReverseRfFromSleepMode(pAd); + // 3090 MCU Wakeup command needs more time to be stable. + // Before stable, don't issue other MCU command to prevent from firmware error. + if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) + { + RTMP_SEM_LOCK(&pAd->McuCmdLock); + pAd->brt30xxBanMcuCmd = FALSE; + RTMP_SEM_UNLOCK(&pAd->McuCmdLock); + } + } + else + // end johnli +#endif // PCIE_PS_SUPPORT // { // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. { @@ -1198,11 +1304,13 @@ BOOLEAN RT28xxPciAsicRadioOff( } // Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops. - pAd->bPCIclkOffDisableTx = TRUE; - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE) && pAd->OpMode == OPMODE_STA) + //pAd->bPCIclkOffDisableTx = TRUE; + RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) + && pAd->OpMode == OPMODE_STA + &&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE + ) { - printk("==>fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE\n"); RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); @@ -1216,12 +1324,22 @@ BOOLEAN RT28xxPciAsicRadioOff( { DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime)); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - pAd->bPCIclkOffDisableTx = FALSE; + //pAd->bPCIclkOffDisableTx = FALSE; + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); return FALSE; } else { PsPollTime = (64*TbTTTime- LEAD_TIME*1024)/1000; +#ifdef PCIE_PS_SUPPORT + if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) + { + PsPollTime -= 5; + } + else +#endif // PCIE_PS_SUPPORT // PsPollTime -= 3; BeaconPeriodTime = pAd->CommonCfg.BeaconPeriod*102/100; @@ -1233,6 +1351,12 @@ BOOLEAN RT28xxPciAsicRadioOff( } } } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOff::Level!=DOT11POWERSAVE \n")); + } + + pAd->bPCIclkOffDisableTx = FALSE; RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); @@ -1315,6 +1439,23 @@ BOOLEAN RT28xxPciAsicRadioOff( pAd->CheckDmaBusyCount = 0; } */ +//KH Debug:My original codes have the follwoing codes, but currecnt codes do not have it. +// Disable for stability. If PCIE Link Control is modified for advance power save, re-covery this code segment. +RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x1280); +//OPSTATUS_SET_FLAG(pAd, fOP_STATUS_CLKSELECT_40MHZ); + +#ifdef PCIE_PS_SUPPORT +if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOff::3090 return to skip the following TbttNumToNextWakeUp setting for 279x\n")); + pAd->bPCIclkOff = TRUE; + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); + // For this case, doesn't need to below actions, so return here. + return brc; + } +#endif // PCIE_PS_SUPPORT // if (Level == DOT11POWERSAVE) { @@ -1335,7 +1476,6 @@ BOOLEAN RT28xxPciAsicRadioOff( RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); } -#ifdef RTMP_PCI_SUPPORT // 4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value. if (Level == RTMP_HALT && pAd->OpMode == OPMODE_STA) { @@ -1348,9 +1488,9 @@ BOOLEAN RT28xxPciAsicRadioOff( if ((brc == TRUE) && (i < 50)) RTMPPCIeLinkCtrlSetting(pAd, 3); } -#endif // RTMP_PCI_SUPPORT // - pAd->bPCIclkOffDisableTx = FALSE; + //pAd->bPCIclkOffDisableTx = FALSE; + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); return TRUE; } @@ -1365,41 +1505,37 @@ VOID RT28xxPciMlmeRadioOn( DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__)); - if ((pAd->OpMode == OPMODE_AP) || - ((pAd->OpMode == OPMODE_STA) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)))) + if ((pAd->OpMode == OPMODE_AP) || + ((pAd->OpMode == OPMODE_STA) + && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) + ||pAd->StaCfg.PSControl.field.EnableNewPS == FALSE + ))) { - if (pAd->OpMode == OPMODE_AP) RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); - //NICResetFromError(pAd); RTMPRingCleanUp(pAd, QID_AC_BK); RTMPRingCleanUp(pAd, QID_AC_BE); RTMPRingCleanUp(pAd, QID_AC_VI); RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_HCCA); RTMPRingCleanUp(pAd, QID_MGMT); RTMPRingCleanUp(pAd, QID_RX); - if (pAd->OpMode == OPMODE_STA) - { - AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); - RTMPusecDelay(10000); - } - // Enable Tx/Rx RTMPEnableRxTx(pAd); // Clear Radio off flag RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); + // Set LED RTMPSetLED(pAd, LED_RADIO_ON); } -#ifdef RTMP_PCI_SUPPORT if ((pAd->OpMode == OPMODE_STA) && - (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))) + (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) + &&(pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { BOOLEAN Cancelled; @@ -1408,9 +1544,8 @@ VOID RT28xxPciMlmeRadioOn( pAd->Mlme.bPsPollTimerRunning = FALSE; RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); - RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); + RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 40); } -#endif // RTMP_PCI_SUPPORT // } @@ -1455,19 +1590,33 @@ VOID RT28xxPciMlmeRadioOFF( { BOOLEAN Cancelled; + if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) + { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); } - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + // If during power safe mode. + if (pAd->StaCfg.bRadio == TRUE) + { + DBGPRINT(RT_DEBUG_TRACE,("-->MlmeRadioOff() return on bRadio == TRUE; \n")); + return; + } + // Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF). + if (IDLE_ON(pAd) && + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) + { + RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); + } + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { BOOLEAN Cancelled; pAd->Mlme.bPsPollTimerRunning = FALSE; RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); } + } // Link down first if any association exists if (INFRA_ON(pAd) || ADHOC_ON(pAd)) @@ -1477,28 +1626,38 @@ VOID RT28xxPciMlmeRadioOFF( // Clean up old bss table BssTableInit(&pAd->ScanTab); - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + /* + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); return; } + */ } - // Set LED + // Set LED.Move to here for fixing LED bug. This flag must be called after LinkDown RTMPSetLED(pAd, LED_RADIO_OFF); - if (pAd->OpMode == OPMODE_AP) +//KH Debug:All PCIe devices need to use timer to execute radio off function, or the PCIe&&EnableNewPS needs. +//KH Ans:It is right, because only when the PCIe and EnableNewPs is true, we need to delay the RadioOffTimer +//to avoid the deadlock with PCIe Power saving function. +if (pAd->OpMode == OPMODE_STA&& + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)&& + pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) + { + RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); + } +else +{ brc=RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0); if (brc==FALSE) { DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __func__)); } - - - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE) && - (pAd->OpMode == OPMODE_STA)) - AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); +} +/* +*/ } #endif // RTMP_MAC_PCI // Index: b/drivers/staging/rt2860/common/cmm_profile.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_profile.c +++ b/drivers/staging/rt2860/common/cmm_profile.c @@ -1266,6 +1266,49 @@ NDIS_STATUS RTMPSetProfileParameters( DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __func__, pAd->StaCfg.BssType)); } } +#ifdef RTMP_MAC_PCI + //NewPCIePS + if(RTMPGetKeyParameter("NewPCIePS", tmpbuf, 10, pBuffer, TRUE)) + { + UCHAR temp_buffer = (UCHAR) simple_strtol(tmpbuf, 0, 10); + if(temp_buffer>0) + pAd->StaCfg.PSControl.field.EnableNewPS=TRUE; + else + pAd->StaCfg.PSControl.field.EnableNewPS=FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("NewPCIePS=%d\n", pAd->StaCfg.PSControl.field.EnableNewPS)); + } +#endif // RTMP_MAC_PCI // +#ifdef RT3090 + //PCIePowerLevel + + if(RTMPGetKeyParameter("PCIePowerLevel", tmpbuf, 10, pBuffer, TRUE)) + { + pAd->StaCfg.PSControl.field.rt30xxPowerMode = (UCHAR) simple_strtol(tmpbuf, 0, 10); + DBGPRINT(RT_DEBUG_TRACE, ("PCIePowerLevel=%d\n", pAd->StaCfg.PSControl.field.rt30xxPowerMode)); + } + //FollowHostASPM + if(RTMPGetKeyParameter("FollowHostASPM", tmpbuf, 10, pBuffer, TRUE)) + { + UCHAR temp_buffer = (UCHAR) simple_strtol(tmpbuf, 0, 10); + + if(temp_buffer>0) + pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM=TRUE; + else + pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM=FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("rt30xxFollowHostASPM=%d\n", pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM)); + } + //ForceTestASPM + if(RTMPGetKeyParameter("ForceTestASPM", tmpbuf, 10, pBuffer, TRUE)) + { + UCHAR temp_buffer = (UCHAR) simple_strtol(tmpbuf, 0, 10); + + if(temp_buffer>0) + pAd->StaCfg.PSControl.field.rt30xxForceASPMTest=TRUE; + else + pAd->StaCfg.PSControl.field.rt30xxForceASPMTest=FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("rt30xxForceASPM=%d\n", pAd->StaCfg.PSControl.field.rt30xxForceASPMTest)); + } +#endif // RT3090 // //Channel if(RTMPGetKeyParameter("Channel", tmpbuf, 10, pBuffer, TRUE)) { Index: b/drivers/staging/rt2860/common/cmm_sync.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_sync.c +++ b/drivers/staging/rt2860/common/cmm_sync.c @@ -432,19 +432,6 @@ VOID ScanNextChannel( } { -#ifdef RT2860 - /* - If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp. - In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux. - To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here. - */ - if (ADHOC_ON(pAd)) - { - NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); - pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; - NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); - } -#endif // RT2860 // // // To prevent data lost. // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. Index: b/drivers/staging/rt2860/common/mlme.c =================================================================== --- a/drivers/staging/rt2860/common/mlme.c +++ b/drivers/staging/rt2860/common/mlme.c @@ -397,7 +397,7 @@ NDIS_STATUS MlmeInit( { #ifdef RTMP_PCI_SUPPORT - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { // only PCIe cards need these two timers RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE); @@ -569,7 +569,8 @@ VOID MlmeHalt( #ifdef RTMP_MAC_PCI - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) + &&(pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); @@ -678,6 +679,7 @@ VOID MlmePeriodicExec( { ULONG TxTotalCnt; PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext; + SHORT realavgrssi; #ifdef RTMP_MAC_PCI { @@ -691,7 +693,27 @@ VOID MlmePeriodicExec( UINT32 data = 0; // Read GPIO pin2 as Hardware controlled radio state +#ifndef RT3090 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data); +#endif // RT3090 // +//KH(PCIE PS):Added based on Jane<-- +#ifdef RT3090 +// Read GPIO pin2 as Hardware controlled radio state +// We need to Read GPIO if HW said so no mater what advance power saving +if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) + && (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + && (pAd->StaCfg.PSControl.field.EnablePSinIdle == TRUE)) + { + // Want to make sure device goes to L0 state before reading register. + RTMPPCIeLinkCtrlValueRestore(pAd, 0); + RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data); + RTMPPCIeLinkCtrlSetting(pAd, 3); + } +else + RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data); +#endif // RT3090 // +//KH(PCIE PS):Added based on Jane--> + if (data & 0x04) { pAd->StaCfg.bHwRadio = TRUE; @@ -1187,6 +1209,60 @@ VOID STAMlmePeriodicExec( } } #endif +#ifdef PCIE_PS_SUPPORT +// don't perform idle-power-save mechanism within 3 min after driver initialization. +// This can make rebooter test more robust +if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) + { + if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) + && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) + && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) + && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) + { + if (IS_RT3090(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd)) + { + if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__)); + + RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__)); + AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x2); + // Wait command success + AsicCheckCommanOk(pAd, PowerSafeCID); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); + DBGPRINT(RT_DEBUG_TRACE, ("PSM - rt30xx Issue Sleep command)\n")); + } + } + else if (pAd->Mlme.OneSecPeriodicRound > 180) + { + if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__)); + RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__)); + AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x02); + // Wait command success + AsicCheckCommanOk(pAd, PowerSafeCID); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); + DBGPRINT(RT_DEBUG_TRACE, ("PSM - rt28xx Issue Sleep command)\n")); + } + } + } + else + { + DBGPRINT(RT_DEBUG_TRACE,("STAMlmePeriodicExec MMCHK - CommonCfg.Ssid[%d]=%c%c%c%c... MlmeAux.Ssid[%d]=%c%c%c%c...\n", + pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid[0], pAd->CommonCfg.Ssid[1], pAd->CommonCfg.Ssid[2], pAd->CommonCfg.Ssid[3], + pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid[0], pAd->MlmeAux.Ssid[1], pAd->MlmeAux.Ssid[2], pAd->MlmeAux.Ssid[3])); + } + } +#endif // PCIE_PS_SUPPORT // if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) { @@ -1275,10 +1351,6 @@ VOID STAMlmePeriodicExec( { DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount)); - if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)) - pAd->StaCfg.bLostAp = TRUE; - // Lost AP, send disconnect & link down event LinkDown(pAd, FALSE); @@ -2240,10 +2312,6 @@ VOID MlmeDynamicTxRateSwitching( } pEntry->LastTxOkCount = TxSuccess; -#ifdef RT2860 - pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5]; -#endif // RT2860 // -#if defined(RT2870) || defined(RT3070) { UCHAR tmpTxRate; @@ -2261,7 +2329,6 @@ VOID MlmeDynamicTxRateSwitching( pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(tmpTxRate+1)*5]; } -#endif // RT2870 // if (bTxRateChanged && pNextTxRate) { MlmeSetTxRate(pAd, pEntry, pNextTxRate); @@ -3805,14 +3872,6 @@ VOID BssTableSsidSort( DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); continue; } -#ifdef RT2860 - if ((pAd->CommonCfg.PhyMode == PHY_11GN_MIXED) && - ((pInBss->SupRateLen + pInBss->ExtRateLen) < 12)) - { - DBGPRINT(RT_DEBUG_TRACE,("STA is in GN-only Mode, this AP is in B mode.\n")); - continue; - } -#endif // RT2860 // // New for WPA2 // Check the Authmode first if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) @@ -3921,14 +3980,7 @@ VOID BssTableSsidSort( DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); continue; } -#ifdef RT2860 - if ((pAd->CommonCfg.PhyMode == PHY_11GN_MIXED) && - ((pInBss->SupRateLen + pInBss->ExtRateLen) < 12)) - { - DBGPRINT(RT_DEBUG_TRACE,("STA is in GN-only Mode, this AP is in B mode.\n")); - continue; - } -#endif // RT2860 // + // New for WPA2 // Check the Authmode first if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) @@ -5495,6 +5547,9 @@ VOID AsicEvaluateRxAnt( #ifdef RT30xx || (pAd->EepromAccess) #endif // RT30xx // +#ifdef RT3090 + || (pAd->bPCIclkOff == TRUE) +#endif // RT3090 // ) return; @@ -5583,6 +5638,9 @@ VOID AsicRxAntEvalTimeout( #ifdef RT30xx || (pAd->EepromAccess) #endif // RT30xx // +#ifdef RT3090 + || (pAd->bPCIclkOff == TRUE) +#endif // RT3090 // ) return; Index: b/drivers/staging/rt2860/common/rt_rf.c =================================================================== --- a/drivers/staging/rt2860/common/rt_rf.c +++ b/drivers/staging/rt2860/common/rt_rf.c @@ -187,6 +187,14 @@ VOID RtmpChipOpsRFHook( } } #endif // RT3070 // +#ifdef RT3090 + if (IS_RT3090(pAd) && (pAd->infType == RTMP_DEV_INF_PCI)) + { + pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup; + pChipOps->AsicRfInit = NICInitRT3090RFRegisters; + pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup; + } +#endif // RT3090 // } #endif // RT30xx // } Index: b/drivers/staging/rt2860/common/rtmp_init.c =================================================================== --- a/drivers/staging/rt2860/common/rtmp_init.c +++ b/drivers/staging/rt2860/common/rtmp_init.c @@ -191,6 +191,9 @@ NDIS_STATUS RTMPAllocAdapterBlock( NdisAllocateSpinLock(&pAd->MgmtRingLock); #ifdef RTMP_MAC_PCI NdisAllocateSpinLock(&pAd->RxRingLock); +#ifdef RT3090 + NdisAllocateSpinLock(&pAd->McuCmdLock); +#endif // RT3090 // #endif // RTMP_MAC_PCI // for (index =0 ; index < NUM_OF_TX_RING; index++) @@ -1238,7 +1241,13 @@ VOID NICInitAsicFromEEPROM( { RTMPSetLED(pAd, LED_RADIO_ON); #ifdef RTMP_MAC_PCI +#ifdef RT3090 + AsicSendCommandToMcu(pAd, 0x30, PowerRadioOffCID, 0xff, 0x02); + AsicCheckCommanOk(pAd, PowerRadioOffCID); +#endif // RT3090 // +#ifndef RT3090 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); +#endif // RT3090 // AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00); // 2-1. wait command ok. AsicCheckCommanOk(pAd, PowerWakeCID); @@ -1246,6 +1255,29 @@ VOID NICInitAsicFromEEPROM( } } +#ifdef RTMP_MAC_PCI +#ifdef RT30xx + if (IS_RT3090(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd)) + { + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + if (pChipOps->AsicReverseRfFromSleepMode) + pChipOps->AsicReverseRfFromSleepMode(pAd); + } + // 3090 MCU Wakeup command needs more time to be stable. + // Before stable, don't issue other MCU command to prevent from firmware error. + + if ((IS_RT3090(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) + { + DBGPRINT(RT_DEBUG_TRACE,("%s::%d,release Mcu Lock\n",__FUNCTION__,__LINE__)); + RTMP_SEM_LOCK(&pAd->McuCmdLock); + pAd->brt30xxBanMcuCmd = FALSE; + RTMP_SEM_UNLOCK(&pAd->McuCmdLock); + } +#endif // RT30xx // +#endif // RTMP_MAC_PCI // + // Turn off patching for cardbus controller if (NicConfig2.field.CardbusAcceleration == 1) { @@ -1443,11 +1475,6 @@ retry: RTMP_IO_WRITE32(pAd, TX_BASE_PTR3, Value); DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR3 : 0x%x\n", Value)); - // Write HCCA base address register - Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_HCCA].Cell[0].AllocPa); - RTMP_IO_WRITE32(pAd, TX_BASE_PTR4, Value); - DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR4 : 0x%x\n", Value)); - // Write MGMT_BASE_CSR register Value = RTMP_GetPhysicalAddressLow(pAd->MgmtRing.Cell[0].AllocPa); RTMP_IO_WRITE32(pAd, TX_BASE_PTR5, Value); @@ -1641,7 +1668,7 @@ NDIS_STATUS NICInitializeAsic( for(Index=0; Index +#endif // RT3090 // RTMPusecDelay(1000); // Read BBP register, make sure BBP is up and running before write new data @@ -2588,6 +2620,8 @@ VOID UserCfgInit( pAd->LedIndicatorStrength = 0; pAd->RLnkCtrlOffset = 0; pAd->HostLnkCtrlOffset = 0; + pAd->StaCfg.PSControl.field.EnableNewPS=TRUE; + pAd->CheckDmaBusyCount = 0; #endif // RTMP_MAC_PCI // pAd->bAutoTxAgcA = FALSE; // Default is OFF @@ -2600,8 +2634,6 @@ VOID UserCfgInit( pAd->bForcePrintRX = FALSE; pAd->bStaFifoTest = FALSE; pAd->bProtectionTest = FALSE; - pAd->bHCCATest = FALSE; - pAd->bGenOneHCCA = FALSE; pAd->CommonCfg.Dsifs = 10; // in units of usec pAd->CommonCfg.TxPower = 100; //mW pAd->CommonCfg.TxPowerPercentage = 0xffffffff; // AUTO @@ -2720,6 +2752,15 @@ VOID UserCfgInit( pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; } +#ifdef PCIE_PS_SUPPORT +pAd->brt30xxBanMcuCmd = FALSE; +pAd->b3090ESpecialChip = FALSE; +//KH Debug:the following must be removed +pAd->StaCfg.PSControl.field.rt30xxPowerMode=3; +pAd->StaCfg.PSControl.field.rt30xxForceASPMTest=0; +pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM=1; +#endif // PCIE_PS_SUPPORT // + // global variables mXXXX used in MAC protocol state machines OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON); @@ -2757,6 +2798,9 @@ VOID UserCfgInit( pAd->StaCfg.LastScanTime -= (10 * OS_HZ); NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1); +#ifdef RTMP_MAC_PCI + sprintf((PSTRING) pAd->nickname, "RT2860STA"); +#endif // RTMP_MAC_PCI // #ifdef RTMP_MAC_USB sprintf((PSTRING) pAd->nickname, "RT2870STA"); #endif // RTMP_MAC_USB // @@ -2766,7 +2810,6 @@ VOID UserCfgInit( pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE; pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE; pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE; - pAd->StaCfg.bLostAp = FALSE; NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8); @@ -3272,7 +3315,7 @@ int rt28xx_init( // NICLoadFirmware will hang forever when interface is up again. // RT2860 PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) && - OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { AUTO_WAKEUP_STRUC AutoWakeupCfg; AsicForceWakeup(pAd, TRUE); @@ -3307,6 +3350,16 @@ int rt28xx_init( DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); #ifdef RTMP_MAC_PCI +#ifdef PCIE_PS_SUPPORT + /*Iverson patch PCIE L1 issue to make sure that driver can be read,write ,BBP and RF register at pcie L.1 level */ + if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))&&OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) + { + RTMP_IO_READ32(pAd, AUX_CTRL, &MacCsr0); + MacCsr0 |= 0x402; + RTMP_IO_WRITE32(pAd, AUX_CTRL, MacCsr0); + DBGPRINT(RT_DEBUG_TRACE, ("AUX_CTRL = 0x%x\n", MacCsr0)); + } +#endif // PCIE_PS_SUPPORT // // To fix driver disable/enable hang issue when radio off RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2); Index: b/drivers/staging/rt2860/common/rtmp_mcu.c =================================================================== --- a/drivers/staging/rt2860/common/rtmp_mcu.c +++ b/drivers/staging/rt2860/common/rtmp_mcu.c @@ -38,8 +38,9 @@ #include "../rt_config.h" -#ifdef RT2860 +#if defined(RT2860) || defined(RT3090) #include "firmware.h" +#include "../../rt3090/firmware.h" #endif #ifdef RT2870 #include "../../rt3070/firmware.h" @@ -115,20 +116,18 @@ NDIS_STATUS RtmpAsicLoadFirmware( { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PUCHAR pFirmwareImage; + PUCHAR pFirmwareImage = NULL; ULONG FileLength, Index; - //ULONG firm; UINT32 MacReg = 0; UINT32 Version = (pAd->MACVersion >> 16); -// pFirmwareImage = FirmwareImage; -// FileLength = sizeof(FirmwareImage); - // New 8k byte firmware size for RT3071/RT3072 { #ifdef RTMP_MAC_PCI - if ((Version == 0x2860) || (Version == 0x3572) || IS_RT3090(pAd)) - { + if (IS_RT3090(pAd) || IS_RT3390(pAd)) { + pFirmwareImage = FirmwareImage_3090; + FileLength = FIRMWAREIMAGE_MAX_LENGTH; + } else { pFirmwareImage = FirmwareImage_2860; FileLength = FIRMWAREIMAGE_MAX_LENGTH; } @@ -190,11 +189,74 @@ INT RtmpAsicSendCommandToMcu( HOST_CMD_CSR_STRUC H2MCmd; H2M_MAILBOX_STRUC H2MMailbox; ULONG i = 0; -#ifdef RTMP_MAC_PCI -#endif // RTMP_MAC_PCI // + +#ifdef PCIE_PS_SUPPORT + // 3090F power solution 3 has hw limitation that needs to ban all mcu command + // when firmware is in radio state. For other chip doesn't have this limitation. + if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) + { + RTMP_SEM_LOCK(&pAd->McuCmdLock); + if ((pAd->brt30xxBanMcuCmd == TRUE) + && (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD)) + { + RTMP_SEM_UNLOCK(&pAd->McuCmdLock); + DBGPRINT(RT_DEBUG_TRACE, (" Ban Mcu Cmd %x in sleep mode\n", Command)); + return FALSE; + } + else if ((Command == SLEEP_MCU_CMD) + ||(Command == RFOFF_MCU_CMD)) + { + pAd->brt30xxBanMcuCmd = TRUE; + } + else if (Command != WAKE_MCU_CMD) + { + pAd->brt30xxBanMcuCmd = FALSE; + } + + RTMP_SEM_UNLOCK(&pAd->McuCmdLock); + + } + if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) + && (Command == WAKE_MCU_CMD)) + { do { + RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word); + if (H2MMailbox.field.Owner == 0) + break; + + RTMPusecDelay(2); + DBGPRINT(RT_DEBUG_INFO, ("AsicSendCommanToMcu::Mail box is busy\n")); + } while(i++ < 100); + + if (i >= 100) + { + DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n")); + return FALSE; + } + + H2MMailbox.field.Owner = 1; // pass ownership to MCU + H2MMailbox.field.CmdToken = Token; + H2MMailbox.field.HighByte = Arg1; + H2MMailbox.field.LowByte = Arg0; + RTMP_IO_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word); + + H2MCmd.word = 0; + H2MCmd.field.HostCommand = Command; + RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word); + + + } + else +#endif // PCIE_PS_SUPPORT // + { + do + { RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word); if (H2MMailbox.field.Owner == 0) break; @@ -228,6 +290,22 @@ INT RtmpAsicSendCommandToMcu( if (Command != 0x80) { } +} +#ifdef PCIE_PS_SUPPORT + // 3090 MCU Wakeup command needs more time to be stable. + // Before stable, don't issue other MCU command to prevent from firmware error. + if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) + && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) + && (Command == WAKE_MCU_CMD)) + { + RTMPusecDelay(2000); + //Put this is after RF programming. + //NdisAcquireSpinLock(&pAd->McuCmdLock); + //pAd->brt30xxBanMcuCmd = FALSE; + //NdisReleaseSpinLock(&pAd->McuCmdLock); + } +#endif // PCIE_PS_SUPPORT // return TRUE; } Index: b/drivers/staging/rt2860/common/rtmp_timer.c =================================================================== --- a/drivers/staging/rt2860/common/rtmp_timer.c +++ b/drivers/staging/rt2860/common/rtmp_timer.c @@ -59,10 +59,10 @@ BUILD_TIMER_FUNCTION(DisassocTimeout); BUILD_TIMER_FUNCTION(LinkDownExec); BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec); BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); -#ifdef RTMP_PCI_SUPPORT +#ifdef RTMP_MAC_PCI BUILD_TIMER_FUNCTION(PsPollWakeExec); BUILD_TIMER_FUNCTION(RadioOnExec); -#endif // RTMP_PCI_SUPPORT // +#endif // RTMP_MAC_PCI // #ifdef RTMP_MAC_USB BUILD_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout); #endif // RTMP_MAC_USB // Index: b/drivers/staging/rt2860/iface/rtmp_pci.h =================================================================== --- a/drivers/staging/rt2860/iface/rtmp_pci.h +++ b/drivers/staging/rt2860/iface/rtmp_pci.h @@ -38,9 +38,7 @@ #define RT28XX_PUT_DEVICE(dev_p) -#ifndef SA_SHIRQ #define SA_SHIRQ IRQF_SHARED -#endif #ifdef PCI_MSI_SUPPORT #define RTMP_MSI_ENABLE(_pAd) \ Index: b/drivers/staging/rt2860/pci_main_dev.c =================================================================== --- a/drivers/staging/rt2860/pci_main_dev.c +++ b/drivers/staging/rt2860/pci_main_dev.c @@ -38,6 +38,13 @@ #include "rt_config.h" #include +// Following information will be show when you run 'modinfo' +// *** If you have a solution for the bug in current version of driver, please mail to me. +// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** +MODULE_AUTHOR("Jett Chen "); +MODULE_DESCRIPTION("RT2860/RT3090 Wireless Lan Linux Driver"); +MODULE_LICENSE("GPL"); + // // Function declarations // @@ -63,6 +70,7 @@ static int rt2860_resume(struct pci_dev // static struct pci_device_id rt2860_pci_tbl[] __devinitdata = { +#ifdef RT2860 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)}, //RT28602.4G {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)}, {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)}, @@ -75,11 +83,21 @@ static struct pci_device_id rt2860_pci_t {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7738)}, {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7748)}, {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7768)}, +#endif +#ifdef RT3090 + {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3090_PCIe_DEVICE_ID)}, + {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3091_PCIe_DEVICE_ID)}, + {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3092_PCIe_DEVICE_ID)}, +#endif // RT3090 // +#ifdef RT3390 + {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3390_PCIe_DEVICE_ID)}, + {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3391_PCIe_DEVICE_ID)}, + {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3392_PCIe_DEVICE_ID)}, +#endif // RT3390 // {0,} // terminate list }; MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl); -MODULE_LICENSE("GPL"); #ifdef MODULE_VERSION MODULE_VERSION(STA_DRIVER_VERSION); #endif @@ -363,9 +381,6 @@ static INT __devinit rt2860_probe( pAd->StaCfg.OriDevType = net_dev->type; RTMPInitPCIeDevice(pci_dev, pAd); -#ifdef KTHREAD_SUPPORT -#endif // KTHREAD_SUPPORT // - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n")); return 0; // probe ok @@ -478,11 +493,17 @@ BOOLEAN RT28XXChipsetCheck( pci_read_config_word(pci_dev, PCI_DEVICE_ID, &device_id); device_id = le2cpu16(device_id); pObj->DeviceID = device_id; - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE); if ( +#ifdef RT2860 (device_id == NIC2860_PCIe_DEVICE_ID) || (device_id == NIC2790_PCIe_DEVICE_ID) || (device_id == VEN_AWT_PCIe_DEVICE_ID) || +#endif +#ifdef RT3090 + (device_id == NIC3090_PCIe_DEVICE_ID) || + (device_id == NIC3091_PCIe_DEVICE_ID) || + (device_id == NIC3092_PCIe_DEVICE_ID) || +#endif // RT3090 // 0) { UINT32 MacCsr0 = 0, Index= 0; @@ -500,7 +521,7 @@ BOOLEAN RT28XXChipsetCheck( // MAC version at offset 0x1000 is 0x2872XXXX/0x2870XXXX(PCIe, USB, SDIO). if ((MacCsr0&0xffff0000) != 0x28600000) { - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE); + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PCIE_DEVICE); } } } @@ -511,24 +532,26 @@ VOID RTMPInitPCIeLinkCtrlValue( { INT pos; USHORT reg16, data2, PCIePowerSaveLevel, Configuration; + UINT32 MacValue; BOOLEAN bFindIntel = FALSE; POS_COOKIE pObj; pObj = (POS_COOKIE) pAd->OS_Cookie; - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) return; DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__)); // Init EEPROM, and save settings - if (!IS_RT3090(pAd)) + if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) { RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel); pAd->PCIePowerSaveLevel = PCIePowerSaveLevel & 0xff; + pAd->LnkCtrlBitMask = 0; if ((PCIePowerSaveLevel&0xff) == 0xff) { - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PCIE_DEVICE); DBGPRINT(RT_DEBUG_TRACE, ("====> PCIePowerSaveLevel = 0x%x.\n", PCIePowerSaveLevel)); return; } @@ -563,40 +586,108 @@ VOID RTMPInitPCIeLinkCtrlValue( pAd->LnkCtrlBitMask = 0x103; break; } + RT28xx_EEPROM_READ16(pAd, 0x24, data2); + if ((PCIePowerSaveLevel&0xff) != 0xff) + { + PCIePowerSaveLevel &= 0x3; + + if( !(((data2&0xff00) == 0x9200) && ((data2&0x80) !=0)) ) + { + if (PCIePowerSaveLevel > 1 ) + PCIePowerSaveLevel = 1; + } + + DBGPRINT(RT_DEBUG_TRACE, ("====> rt28xx Write 0x83 Command = 0x%x.\n", PCIePowerSaveLevel)); + printk("\n\n\n%s:%d\n",__FUNCTION__,__LINE__); + + AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, 0x00); + } DBGPRINT(RT_DEBUG_TRACE, ("====> LnkCtrlBitMask = 0x%x.\n", pAd->LnkCtrlBitMask)); } } - else if (IS_RT3090(pAd)) + else if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) { + UCHAR LinkCtrlSetting = 0; + + // Check 3090E special setting chip. + RT28xx_EEPROM_READ16(pAd, 0x24, data2); + if ((data2 == 0x9280) && ((pAd->MACVersion&0xffff) == 0x0211)) + { + pAd->b3090ESpecialChip = TRUE; + DBGPRINT_RAW(RT_DEBUG_ERROR,("Special 3090E chip \n")); + } + + RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue); + //enable WAKE_PCIE function, which forces to enable PCIE clock when mpu interrupt asserting. + //Force PCIE 125MHz CLK to toggle + MacValue |= 0x402; + RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue); + DBGPRINT_RAW(RT_DEBUG_ERROR,(" AUX_CTRL = 0x%32x\n", MacValue)); + + + + // for RT30xx F and after, PCIe infterface, and for power solution 3 + if ((IS_VERSION_AFTER_F(pAd)) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode >= 2) + && (pAd->StaCfg.PSControl.field.rt30xxPowerMode <= 3)) + { + RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue); + DBGPRINT_RAW(RT_DEBUG_ERROR,(" Read AUX_CTRL = 0x%x\n", MacValue)); + // turn on bit 12. + //enable 32KHz clock mode for power saving + MacValue |= 0x1000; + if (MacValue != 0xffffffff) + { + RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue); + DBGPRINT_RAW(RT_DEBUG_ERROR,(" Write AUX_CTRL = 0x%x\n", MacValue)); + // 1. if use PCIePowerSetting is 2 or 3, need to program OSC_CTRL to 0x3ff11. + MacValue = 0x3ff11; + RTMP_IO_WRITE32(pAd, OSC_CTRL, MacValue); + DBGPRINT_RAW(RT_DEBUG_ERROR,(" OSC_CTRL = 0x%x\n", MacValue)); + // 2. Write PCI register Clk ref bit + RTMPrt3xSetPCIePowerLinkCtrl(pAd); + } + else + { + // Error read Aux_Ctrl value. Force to use solution 1 + DBGPRINT(RT_DEBUG_ERROR,(" Error Value in AUX_CTRL = 0x%x\n", MacValue)); + pAd->StaCfg.PSControl.field.rt30xxPowerMode = 1; + DBGPRINT(RT_DEBUG_ERROR,(" Force to use power solution1 \n")); + } + } // 1. read setting from inf file. - // ..... - USHORT PCIePowerSetting = 0; - /* code from windows, default value of rt30xxPowerMode = 0 - PCIePowerSetting = pAd->StaCfg.PSControl.field.rt30xxPowerMode; - */ - DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx Read PowerLevelMode = 0x%x.\n", PCIePowerSetting)); - // 2. Check EnableNewPS - /* + + PCIePowerSaveLevel = (USHORT)pAd->StaCfg.PSControl.field.rt30xxPowerMode; + DBGPRINT(RT_DEBUG_ERROR, ("====> rt30xx Read PowerLevelMode = 0x%x.\n", PCIePowerSaveLevel)); + // 2. Check EnableNewPS. if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) - PCIePowerSetting = 1; - */ + PCIePowerSaveLevel = 1; - if ((pAd->MACVersion&0xffff) <= 0x0211) + if (IS_VERSION_BEFORE_F(pAd) && (pAd->b3090ESpecialChip == FALSE)) { - // Chip Version E only allow 1 - PCIePowerSetting = 1; - DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx Write 0x83 Command = 0x%x.\n", PCIePowerSetting)); - AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSetting, 0x00); + // Chip Version E only allow 1, So force set 1. + PCIePowerSaveLevel &= 0x1; + pAd->PCIePowerSaveLevel = (USHORT)PCIePowerSaveLevel; + DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx E Write 0x83 Command = 0x%x.\n", PCIePowerSaveLevel)); + + AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, 0x00); } else { - // Chip Version F only allow 1 or 2 - if ((PCIePowerSetting > 2) || (PCIePowerSetting == 0)) - PCIePowerSetting = 1; - DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx Write 0x83 Command = 0x%x.\n", PCIePowerSetting)); - AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSetting, 0x00); + // Chip Version F and after only allow 1 or 2 or 3. This might be modified after new chip version come out. + if (!((PCIePowerSaveLevel == 1) || (PCIePowerSaveLevel == 3))) + PCIePowerSaveLevel = 1; + DBGPRINT(RT_DEBUG_ERROR, ("====> rt30xx F Write 0x83 Command = 0x%x.\n", PCIePowerSaveLevel)); + pAd->PCIePowerSaveLevel = (USHORT)PCIePowerSaveLevel; + // for 3090F , we need to add high-byte arg for 0x83 command to indicate the link control setting in + // PCI Configuration Space. Because firmware can't read PCI Configuration Space + if ((pAd->Rt3xxRalinkLinkCtrl & 0x2) && (pAd->Rt3xxHostLinkCtrl & 0x2)) + { + LinkCtrlSetting = 1; + } + DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xxF LinkCtrlSetting = 0x%x.\n", LinkCtrlSetting)); + AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, LinkCtrlSetting); } - } // Find Ralink PCIe Device's Express Capability Offset @@ -613,6 +704,7 @@ VOID RTMPInitPCIeLinkCtrlValue( pAd->RLnkCtrlConfiguration = (Configuration & 0x103); Configuration &= 0xfefc; Configuration |= (0x0); +#ifdef RT2860 if ((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID) ||(pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)) { @@ -621,6 +713,7 @@ VOID RTMPInitPCIeLinkCtrlValue( DBGPRINT(RT_DEBUG_TRACE, ("Write (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n", pos + PCI_EXP_LNKCTL, Configuration)); } +#endif // RT2860 // RTMPFindHostPCIDev(pAd); if (pObj->parent_pci_dev) @@ -630,7 +723,10 @@ VOID RTMPInitPCIeLinkCtrlValue( pci_read_config_word(pObj->parent_pci_dev, PCI_VENDOR_ID, &vendor_id); vendor_id = le2cpu16(vendor_id); if (vendor_id == PCIBUS_INTEL_VENDOR) + { bFindIntel = TRUE; + RTMP_SET_PSFLAG(pAd, fRTMP_PS_TOGGLE_L1); + } // Find PCI-to-PCI Bridge Express Capability Offset pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP); @@ -650,10 +746,20 @@ VOID RTMPInitPCIeLinkCtrlValue( switch (pObj->DeviceID) { +#ifdef RT2860 case NIC2860_PCIe_DEVICE_ID: case NIC2790_PCIe_DEVICE_ID: bChange = TRUE; break; +#endif // RT2860 // +#ifdef RT3090 + case NIC3090_PCIe_DEVICE_ID: + case NIC3091_PCIe_DEVICE_ID: + case NIC3092_PCIe_DEVICE_ID: + if (bFindIntel == FALSE) + bChange = TRUE; + break; +#endif // RT3090 // default: break; } @@ -686,6 +792,11 @@ VOID RTMPInitPCIeLinkCtrlValue( // Doesn't switch L0, L1, So set PCIePowerSaveLevel to 0xff pAd->PCIePowerSaveLevel = 0xff; if ((pAd->RLnkCtrlOffset != 0) +#ifdef RT3090 + && ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID) + ||(pObj->DeviceID == NIC3091_PCIe_DEVICE_ID) + ||(pObj->DeviceID == NIC3092_PCIe_DEVICE_ID)) +#endif // RT3090 // ) { pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, ®16); @@ -714,7 +825,7 @@ VOID RTMPFindHostPCIDev( pObj = (POS_COOKIE) pAd->OS_Cookie; - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) return; DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__)); @@ -761,12 +872,27 @@ VOID RTMPPCIeLinkCtrlValueRestore( pObj = (POS_COOKIE) pAd->OS_Cookie; - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) return; +#ifdef RT2860 if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID) ||(pObj->DeviceID == NIC2790_PCIe_DEVICE_ID))) return; +#endif // RT2860 // + // Check PSControl Configuration + if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) + return TRUE; + + //3090 will not execute the following codes. + // Check interface : If not PCIe interface, return. + +#ifdef RT3090 + if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID) + ||(pObj->DeviceID == NIC3091_PCIe_DEVICE_ID) + ||(pObj->DeviceID == NIC3092_PCIe_DEVICE_ID)) + return; +#endif // RT3090 // DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__)); PCIePowerSaveLevel = pAd->PCIePowerSaveLevel; @@ -840,12 +966,32 @@ VOID RTMPPCIeLinkCtrlSetting( pObj = (POS_COOKIE) pAd->OS_Cookie; - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) return; +#ifdef RT2860 if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID) ||(pObj->DeviceID == NIC2790_PCIe_DEVICE_ID))) return; +#endif // RT2860 // + // Check PSControl Configuration + if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) + return TRUE; + + // Check interface : If not PCIe interface, return. + //Block 3090 to enter the following function + +#ifdef RT3090 + if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID) + ||(pObj->DeviceID == NIC3091_PCIe_DEVICE_ID) + ||(pObj->DeviceID == NIC3092_PCIe_DEVICE_ID)) + return; +#endif // RT3090 // + if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)) + { + DBGPRINT(RT_DEBUG_INFO, ("RTMPPCIePowerLinkCtrl return on fRTMP_PS_CAN_GO_SLEEP flag\n")); + return; + } DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__)); PCIePowerSaveLevel = pAd->PCIePowerSaveLevel; @@ -856,6 +1002,35 @@ VOID RTMPPCIeLinkCtrlSetting( } PCIePowerSaveLevel = PCIePowerSaveLevel>>6; + // Skip non-exist deice right away + if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0)) + { + PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration); + switch (PCIePowerSaveLevel) + { + case 0: + // Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 + Configuration &= 0xfefc; + break; + case 1: + // Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 + Configuration &= 0xfefc; + Configuration |= 0x1; + break; + case 2: + // Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 + Configuration &= 0xfefc; + Configuration |= 0x3; + break; + case 3: + // Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1 + Configuration &= 0xfefc; + Configuration |= 0x103; + break; + } + PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration); + DBGPRINT(RT_DEBUG_TRACE, ("Write PCI host offset 0x%x = 0x%x\n", pAd->HostLnkCtrlOffset, Configuration)); + } if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) { @@ -864,10 +1039,149 @@ VOID RTMPPCIeLinkCtrlSetting( PCIePowerSaveLevel = Max; PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration); - Configuration |= 0x100; + switch (PCIePowerSaveLevel) + { + case 0: + // No PCI power safe + // Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 . + Configuration &= 0xfefc; + break; + case 1: + // L0 + // Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 . + Configuration &= 0xfefc; + Configuration |= 0x1; + break; + case 2: + // L0 and L1 + // Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 + Configuration &= 0xfefc; + Configuration |= 0x3; + break; + case 3: + // L0 , L1 and clock management. + // Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1 + Configuration &= 0xfefc; + Configuration |= 0x103; + pAd->bPCIclkOff = TRUE; + break; + } PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration); DBGPRINT(RT_DEBUG_TRACE, ("Write Ralink device : offset 0x%x = 0x%x\n", pAd->RLnkCtrlOffset, Configuration)); } DBGPRINT(RT_DEBUG_TRACE,("RTMPPCIePowerLinkCtrl <==============\n")); } + +/* + ======================================================================== + + Routine Description: + 1. Write a PCI register for rt30xx power solution 3 + + ======================================================================== +*/ +VOID RTMPrt3xSetPCIePowerLinkCtrl( + IN PRTMP_ADAPTER pAd) +{ + + ULONG HostConfiguration; + ULONG Configuration; + ULONG Vendor; + ULONG offset; + POS_COOKIE pObj; + INT pos; + USHORT reg16; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + DBGPRINT(RT_DEBUG_INFO, ("RTMPrt3xSetPCIePowerLinkCtrl.===> %x\n", pAd->StaCfg.PSControl.word)); + + // Check PSControl Configuration + if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) + return; + RTMPFindHostPCIDev(pAd); + if (pObj->parent_pci_dev) + { + USHORT vendor_id; + // Find PCI-to-PCI Bridge Express Capability Offset + pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP); + + if (pos != 0) + { + pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL; + } + // If configurared to turn on L1. + HostConfiguration = 0; + if (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1) + { + DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM \n")); + + // Skip non-exist deice right away + if ((pAd->HostLnkCtrlOffset != 0)) + { + PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, HostConfiguration); + // Prepare Configuration to write to Host + HostConfiguration |= 0x3; + PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, HostConfiguration); + pAd->Rt3xxHostLinkCtrl = HostConfiguration; + // Because in rt30xxForceASPMTest Mode, Force turn on L0s, L1. + // Fix HostConfiguration bit0:1 = 0x3 for later use. + HostConfiguration = 0x3; + DBGPRINT(RT_DEBUG_TRACE, ("PSM : Force ASPM : Host device L1/L0s Value = 0x%x\n", HostConfiguration)); + } + } + else if (pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == 1) + { + + // Skip non-exist deice right away + if ((pAd->HostLnkCtrlOffset != 0)) + { + PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, HostConfiguration); + pAd->Rt3xxHostLinkCtrl = HostConfiguration; + HostConfiguration &= 0x3; + DBGPRINT(RT_DEBUG_TRACE, ("PSM : Follow Host ASPM : Host device L1/L0s Value = 0x%x\n", HostConfiguration)); + } + } + } + // Prepare to write Ralink setting. + // Find Ralink PCIe Device's Express Capability Offset + pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP); + + if (pos != 0) + { + // Ralink PCIe Device's Link Control Register Offset + pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL; + pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, ®16); + Configuration = le2cpu16(reg16); + DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n", + pAd->RLnkCtrlOffset, Configuration)); + Configuration |= 0x100; + if ((pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == 1) + || (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1)) + { + switch(HostConfiguration) + { + case 0: + Configuration &= 0xffffffc; + break; + case 1: + Configuration &= 0xffffffc; + Configuration |= 0x1; + break; + case 2: + Configuration &= 0xffffffc; + Configuration |= 0x2; + break; + case 3: + Configuration |= 0x3; + break; + } + } + reg16 = cpu2le16(Configuration); + pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, reg16); + pAd->Rt3xxRalinkLinkCtrl = Configuration; + DBGPRINT(RT_DEBUG_TRACE, ("PSM :Write Ralink device L1/L0s Value = 0x%x\n", Configuration)); + } + DBGPRINT(RT_DEBUG_INFO,("PSM :RTMPrt3xSetPCIePowerLinkCtrl <==============\n")); +} Index: b/drivers/staging/rt2860/rt_linux.c =================================================================== --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -283,6 +283,9 @@ VOID RTMPFreeAdapter( #ifdef RTMP_MAC_PCI NdisFreeSpinLock(&pAd->RxRingLock); +#ifdef RT3090 +NdisFreeSpinLock(&pAd->McuCmdLock); +#endif // RT3090 // #endif // RTMP_MAC_PCI // for (index =0 ; index < NUM_OF_TX_RING; index++) Index: b/drivers/staging/rt2860/rt_linux.h =================================================================== --- a/drivers/staging/rt2860/rt_linux.h +++ b/drivers/staging/rt2860/rt_linux.h @@ -590,6 +590,12 @@ void linux_pci_unmap_single(void *handle *_pV = 0; \ } +#define RTMP_IO_FORCE_READ32(_A, _R, _pV) \ +{ \ + (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \ + (*_pV = readl((void *)((_A)->CSRBaseAddress + (_R)))); \ +} + #define RTMP_IO_READ8(_A, _R, _pV) \ { \ (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \ @@ -605,7 +611,12 @@ void linux_pci_unmap_single(void *handle } \ } - +#define RTMP_IO_FORCE_WRITE32(_A, _R, _V) \ +{ \ + UINT Val; \ + Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \ + writel(_V, (void *)((_A)->CSRBaseAddress + (_R))); \ +} #if defined(RALINK_2880) || defined(RALINK_3052) #define RTMP_IO_WRITE8(_A, _R, _V) \ Index: b/drivers/staging/rt2860/rt_main_dev.c =================================================================== --- a/drivers/staging/rt2860/rt_main_dev.c +++ b/drivers/staging/rt2860/rt_main_dev.c @@ -226,9 +226,9 @@ int rt28xx_close(IN PNET_DEV dev) return 0; // close ok { -#ifdef RTMP_PCI_SUPPORT +#ifdef RTMP_MAC_PCI RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE); -#endif // RTMP_PCI_SUPPORT // +#endif // RTMP_MAC_PCI // // If dirver doesn't wake up firmware here, // NICLoadFirmware will hang forever when interface is up again. @@ -320,6 +320,10 @@ int rt28xx_close(IN PNET_DEV dev) brc=RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0); + +//In solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff + pAd->bPCIclkOff = FALSE; + if (brc==FALSE) { DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __func__)); @@ -400,11 +404,6 @@ int rt28xx_open(IN PNET_DEV dev) return -1; } -#ifdef RTMP_PCI_SUPPORT - RTMPInitPCIeLinkCtrlValue(pAd); -#endif // RTMP_PCI_SUPPORT // - - if (net_dev->priv_flags == INT_MAIN) { if (pAd->OpMode == OPMODE_STA) @@ -449,7 +448,9 @@ int rt28xx_open(IN PNET_DEV dev) // RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); } - +#ifdef RTMP_MAC_PCI + RTMPInitPCIeLinkCtrlValue(pAd); +#endif // RTMP_MAC_PCI // return (retval); Index: b/drivers/staging/rt2860/rt_pci_rbus.c =================================================================== --- a/drivers/staging/rt2860/rt_pci_rbus.c +++ b/drivers/staging/rt2860/rt_pci_rbus.c @@ -236,7 +236,6 @@ VOID Invalid_Remaining_Packet( PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE); } - NDIS_STATUS RtmpNetTaskInit(IN RTMP_ADAPTER *pAd) { POS_COOKIE pObj; @@ -871,7 +870,6 @@ void linux_pci_unmap_single(void *handle pAd=(PRTMP_ADAPTER)handle; pObj = (POS_COOKIE)pAd->OS_Cookie; - if (size > 0) - pci_unmap_single(pObj->pci_dev, dma_addr, size, direction); + pci_unmap_single(pObj->pci_dev, dma_addr, size, direction); } Index: b/drivers/staging/rt2860/rtmp.h =================================================================== --- a/drivers/staging/rt2860/rtmp.h +++ b/drivers/staging/rt2860/rtmp.h @@ -913,6 +913,20 @@ typedef enum _ABGBAND_STATE_ { A_BAND, } ABGBAND_STATE; +#ifdef RTMP_MAC_PCI +// Power save method control +typedef union _PS_CONTROL { + struct { + ULONG EnablePSinIdle:1; // Enable radio off when not connect to AP. radio on only when sitesurvey, + ULONG EnableNewPS:1; // Enable new Chip power save fucntion . New method can only be applied in chip version after 2872. and PCIe. + ULONG rt30xxPowerMode:2; // Power Level Mode for rt30xx chip + ULONG rt30xxFollowHostASPM:1; // Card Follows Host's setting for rt30xx chip. + ULONG rt30xxForceASPMTest:1; // Force enable L1 for rt30xx chip. This has higher priority than rt30xxFollowHostASPM Mode. + ULONG rsv:26; // Radio Measurement Enable + } field; + ULONG word; +} PS_CONTROL, *PPS_CONTROL; +#endif // RTMP_MAC_PCI // /*************************************************************************** * structure for MLME state machine @@ -1542,7 +1556,6 @@ typedef struct _STA_ADMIN_CONFIG { UCHAR WpaSupplicantUP; UCHAR WpaSupplicantScanCount; BOOLEAN bRSN_IE_FromWpaSupplicant; - BOOLEAN bLostAp; CHAR dev_name[16]; USHORT OriDevType; @@ -1557,6 +1570,10 @@ typedef struct _STA_ADMIN_CONFIG { #ifdef RTMP_MAC_PCI UCHAR BBPR3; + // PS Control has 2 meanings for advanced power save function. + // 1. EnablePSinIdle : When no connection, always radio off except need to do site survey. + // 2. EnableNewPS : will save more current in sleep or radio off mode. + PS_CONTROL PSControl; #endif // RTMP_MAC_PCI // @@ -1815,9 +1832,17 @@ struct _RTMP_ADAPTER USHORT HostLnkCtrlConfiguration; USHORT HostLnkCtrlOffset; USHORT PCIePowerSaveLevel; + ULONG Rt3xxHostLinkCtrl; // USed for 3090F chip + ULONG Rt3xxRalinkLinkCtrl; // USed for 3090F chip + USHORT DeviceID; // Read from PCI config + ULONG AccessBBPFailCount; BOOLEAN bPCIclkOff; // flag that indicate if the PICE power status in Configuration SPace.. BOOLEAN bPCIclkOffDisableTx; // + BOOLEAN brt30xxBanMcuCmd; //when = 0xff means all commands are ok to set . + BOOLEAN b3090ESpecialChip; //3090E special chip that write EEPROM 0x24=0x9280. + ULONG CheckDmaBusyCount; // Check Interrupt Status Register Count. + UINT int_enable_reg; UINT int_disable_mask; UINT int_pending; @@ -1923,6 +1948,9 @@ struct _RTMP_ADAPTER #ifdef RTMP_MAC_PCI RTMP_RX_RING RxRing; NDIS_SPIN_LOCK RxRingLock; // Rx Ring spinlock +#ifdef RT3090 + NDIS_SPIN_LOCK McuCmdLock; //MCU Command Queue spinlock +#endif // RT3090 // #endif // RTMP_MAC_PCI // #ifdef RTMP_MAC_USB RX_CONTEXT RxContext[RX_RING_SIZE]; // 1 for redundant multiple IRP bulk in. @@ -2179,8 +2207,6 @@ struct _RTMP_ADAPTER //BOOLEAN bDisablescanning; //defined in RT2870 USB BOOLEAN bStaFifoTest; BOOLEAN bProtectionTest; - BOOLEAN bHCCATest; - BOOLEAN bGenOneHCCA; BOOLEAN bBroadComHT; //+++Following add from RT2870 USB. ULONG BulkOutReq; @@ -2333,6 +2359,7 @@ typedef struct _TX_BLK_ UCHAR HeaderBuf[128]; // TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP //RT2870 2.1.0.0 uses only 80 bytes //RT3070 2.1.1.0 uses only 96 bytes + //RT3090 2.1.0.0 uses only 96 bytes UCHAR MpduHeaderLen; // 802.11 header length NOT including the padding UCHAR HdrPadLen; // recording Header Padding Length; UCHAR apidx; // The interface associated to this packet @@ -2875,10 +2902,6 @@ VOID WpaStaPairwiseKeySetting( VOID WpaStaGroupKeySetting( IN PRTMP_ADAPTER pAd); -VOID WpaSendEapolStart( - IN PRTMP_ADAPTER pAdapter, - IN PUCHAR pBssid); - NDIS_STATUS RTMPCloneNdisPacket( IN PRTMP_ADAPTER pAd, IN BOOLEAN pInsAMSDUHdr, @@ -3685,9 +3708,6 @@ VOID ScanNextChannel( ULONG MakeIbssBeacon( IN PRTMP_ADAPTER pAd); -VOID InitChannelRelatedValue( - IN PRTMP_ADAPTER pAd); - BOOLEAN MlmeScanReqSanity( IN PRTMP_ADAPTER pAd, IN VOID *Msg, @@ -4063,6 +4083,10 @@ VOID RT30xxReverseRFSleepModeSetup( VOID NICInitRT3070RFRegisters( IN RTMP_ADAPTER *pAd); #endif // RT3070 // +#ifdef RT3090 +VOID NICInitRT3090RFRegisters( + IN RTMP_ADAPTER *pAd); +#endif // RT3090 // VOID RT30xxHaltAction( IN PRTMP_ADAPTER pAd); @@ -5254,7 +5278,6 @@ BOOLEAN RT28xxPciAsicRadioOn( IN PRTMP_ADAPTER pAd, IN UCHAR Level); -#ifdef RTMP_PCI_SUPPORT VOID RTMPInitPCIeLinkCtrlValue( IN PRTMP_ADAPTER pAd); @@ -5269,6 +5292,9 @@ VOID RTMPPCIeLinkCtrlSetting( IN PRTMP_ADAPTER pAd, IN USHORT Max); +VOID RTMPrt3xSetPCIePowerLinkCtrl( + IN PRTMP_ADAPTER pAd); + VOID PsPollWakeExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, @@ -5280,7 +5306,6 @@ VOID RadioOnExec( IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3); -#endif // RTMP_PCI_SUPPORT // VOID RT28xxPciStaAsicForceWakeup( IN PRTMP_ADAPTER pAd, Index: b/drivers/staging/rt2860/rtmp_chip.h =================================================================== --- a/drivers/staging/rt2860/rtmp_chip.h +++ b/drivers/staging/rt2860/rtmp_chip.h @@ -49,6 +49,9 @@ #ifdef RT3070 #include "chip/rt3070.h" #endif // RT3070 // +#ifdef RT3090 +#include "chip/rt3090.h" +#endif // RT3090 // // We will have a cost down version which mac version is 0x3090xxxx // Index: b/drivers/staging/rt2860/rtmp_def.h =================================================================== --- a/drivers/staging/rt2860/rtmp_def.h +++ b/drivers/staging/rt2860/rtmp_def.h @@ -221,6 +221,11 @@ #define fRTMP_PS_GO_TO_SLEEP_NOW 0x00000008 #define fRTMP_PS_TOGGLE_L1 0x00000010 // Use Toggle L1 mechanism for rt28xx PCIe +#ifdef RT3090 +#define WAKE_MCU_CMD 0x31 +#define SLEEP_MCU_CMD 0x30 +#define RFOFF_MCU_CMD 0x35 +#endif // RT3090 // #define CCKSETPROTECT 0x1 #define OFDMSETPROTECT 0x2 Index: b/drivers/staging/rt2860/sta/assoc.c =================================================================== --- a/drivers/staging/rt2860/sta/assoc.c +++ b/drivers/staging/rt2860/sta/assoc.c @@ -464,18 +464,6 @@ VOID MlmeAssocReqAction( break; } } -#ifdef RT2860 - /* - When AuthMode is WPA2-Enterprise and AP reboot or STA lost AP, - AP would not do PMK cache with STA after STA re-connect to AP again. - In this case, driver doesn't need to send PMKID to AP and WpaSupplicant. - */ - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) && - (NdisEqualMemory(pAd->MlmeAux.Bssid, pAd->CommonCfg.LastBssid, MAC_ADDR_LEN))) - { - FoundPMK = FALSE; - } -#endif // RT2860 // if (FoundPMK) { // Set PMK number Index: b/drivers/staging/rt2860/sta/auth_rsp.c =================================================================== --- a/drivers/staging/rt2860/sta/auth_rsp.c +++ b/drivers/staging/rt2860/sta/auth_rsp.c @@ -137,10 +137,6 @@ VOID PeerDeauthAction( if (pAd->CommonCfg.bWirelessEvent) RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); - if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)) - pAd->StaCfg.bLostAp = TRUE; - LinkDown(pAd, TRUE); } } Index: b/drivers/staging/rt2860/sta/connect.c =================================================================== --- a/drivers/staging/rt2860/sta/connect.c +++ b/drivers/staging/rt2860/sta/connect.c @@ -1125,6 +1125,26 @@ VOID LinkUp( COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd); +#ifdef RTMP_MAC_PCI + // Before power save before link up function, We will force use 1R. + // So after link up, check Rx antenna # again. + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + if(pAd->Antenna.field.RxPath == 3) + { + Value |= (0x10); + } + else if(pAd->Antenna.field.RxPath == 2) + { + Value |= (0x8); + } + else if(pAd->Antenna.field.RxPath == 1) + { + Value |= (0x0); + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); + pAd->StaCfg.BBPR3 = Value; +#endif // RTMP_MAC_PCI // + if (BssType == BSS_ADHOC) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON); @@ -1134,8 +1154,6 @@ VOID LinkUp( if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) AdhocTurnOnQos(pAd); - InitChannelRelatedValue(pAd); - DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" )); } else @@ -1146,7 +1164,6 @@ VOID LinkUp( DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" )); } -#if defined(RT2870) || defined(RT3070) // 3*3 // reset Tx beamforming bit RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); @@ -1171,6 +1188,9 @@ VOID LinkUp( RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); Value &= (~0x20); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); +#ifdef RTMP_MAC_PCI + pAd->StaCfg.BBPR3 = Value; +#endif // RTMP_MAC_PCI // RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); Data &= 0xfffffffe; @@ -1205,6 +1225,9 @@ VOID LinkUp( RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); Value |= (0x20); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); +#ifdef RTMP_MAC_PCI + pAd->StaCfg.BBPR3 = Value; +#endif // RTMP_MAC_PCI // if (pAd->MACVersion == 0x28600100) { @@ -1234,6 +1257,9 @@ VOID LinkUp( RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); Value &= (~0x20); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); +#ifdef RTMP_MAC_PCI + pAd->StaCfg.BBPR3 = Value; +#endif // RTMP_MAC_PCI // if (pAd->MACVersion == 0x28600100) { @@ -1247,7 +1273,6 @@ VOID LinkUp( } RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); -#endif // RT2870 // // // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission @@ -1752,21 +1777,6 @@ VOID LinkUp( RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); - -#ifdef RT2860 - /* - When AuthMode is WPA2-Enterprise and AP reboot or STA lost AP, - WpaSupplicant would not send EapolStart to AP after STA re-connect to AP again. - In this case, driver would send EapolStart to AP. - */ - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) && - (NdisEqualMemory(pAd->CommonCfg.Bssid, pAd->CommonCfg.LastBssid, MAC_ADDR_LEN)) && - (pAd->StaCfg.bLostAp == TRUE)) - { - WpaSendEapolStart(pAd, pAd->CommonCfg.Bssid); - } -#endif // RT2860 // - pAd->StaCfg.bLostAp = FALSE; } /* @@ -1820,7 +1830,7 @@ VOID LinkDown( OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); #ifdef RTMP_MAC_PCI - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { BOOLEAN Cancelled; pAd->Mlme.bPsPollTimerRunning = FALSE; @@ -1841,6 +1851,10 @@ VOID LinkDown( OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); } +#ifdef RTMP_MAC_PCI + pAd->bPCIclkOff = FALSE; +#endif // RTMP_MAC_PCI // + if (ADHOC_ON(pAd)) // Adhoc mode link down { DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n")); @@ -2520,139 +2534,3 @@ ULONG MakeIbssBeacon( FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode)); return FrameLen; } - -VOID InitChannelRelatedValue( - IN PRTMP_ADAPTER pAd) -{ -#ifdef RT2860 - UCHAR Value = 0; - UINT32 Data = 0; - -#ifdef RTMP_MAC_PCI - // In power save , We will force use 1R. - // So after link up, check Rx antenna # again. - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - if(pAd->Antenna.field.RxPath == 3) - { - Value |= (0x10); - } - else if(pAd->Antenna.field.RxPath == 2) - { - Value |= (0x8); - } - else if(pAd->Antenna.field.RxPath == 1) - { - Value |= (0x0); - } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); - pAd->StaCfg.BBPR3 = Value; -#endif // RTMP_MAC_PCI // - - pAd->CommonCfg.CentralChannel = pAd->MlmeAux.CentralChannel; - pAd->CommonCfg.Channel = pAd->MlmeAux.Channel; - // Change to AP channel - if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) - { - // Must using 40MHz. - pAd->CommonCfg.BBPCurrentBW = BW_40; - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); - Value &= (~0x18); - Value |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); - - // RX : control channel at lower - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - Value &= (~0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); -#ifdef RTMP_MAC_PCI - pAd->StaCfg.BBPR3 = Value; -#endif // RTMP_MAC_PCI // - - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); - Data &= 0xfffffffe; - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); - - if (pAd->MACVersion == 0x28600100) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); - DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); - } - - DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel )); - } - else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) - { - // Must using 40MHz. - pAd->CommonCfg.BBPCurrentBW = BW_40; - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); - Value &= (~0x18); - Value |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); - - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); - Data |= 0x1; - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - Value |= (0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); -#ifdef RTMP_MAC_PCI - pAd->StaCfg.BBPR3 = Value; -#endif // RTMP_MAC_PCI // - - if (pAd->MACVersion == 0x28600100) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); - DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); - } - - DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel )); - } - else - { - pAd->CommonCfg.BBPCurrentBW = BW_20; - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); - Value &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); - - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); - Data &= 0xfffffffe; - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - Value &= (~0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); -#ifdef RTMP_MAC_PCI - pAd->StaCfg.BBPR3 = Value; -#endif // RTMP_MAC_PCI // - - if (pAd->MACVersion == 0x28600100) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); - DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); - } - - DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz !!! \n" )); - } - - RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); -#endif // RT2860 // -} - - Index: b/drivers/staging/rt2860/sta/rtmp_data.c =================================================================== --- a/drivers/staging/rt2860/sta/rtmp_data.c +++ b/drivers/staging/rt2860/sta/rtmp_data.c @@ -1208,7 +1208,6 @@ NDIS_STATUS RTMPFreeTXDRequest( case QID_AC_BE: case QID_AC_VI: case QID_AC_VO: - case QID_HCCA: if (pAd->TxRing[QueIdx].TxSwFreeIdx > pAd->TxRing[QueIdx].TxCpuIdx) FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx - pAd->TxRing[QueIdx].TxCpuIdx - 1; else Index: b/drivers/staging/rt2860/sta/sync.c =================================================================== --- a/drivers/staging/rt2860/sta/sync.c +++ b/drivers/staging/rt2860/sta/sync.c @@ -195,13 +195,23 @@ VOID MlmeScanReqAction( pAd->StaCfg.ScanCnt++; #ifdef RTMP_MAC_PCI - if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) && + if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) && (IDLE_ON(pAd)) && (pAd->StaCfg.bRadio == TRUE) && (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) { + if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) + { + AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02); + AsicCheckCommanOk(pAd, PowerWakeCID); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); + DBGPRINT(RT_DEBUG_TRACE, ("PSM - Issue Wake up command \n")); + } + else + { RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); } + } #endif // RTMP_MAC_PCI // // first check the parameter sanity @@ -303,7 +313,7 @@ VOID MlmeJoinReqAction( DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx)); #ifdef RTMP_MAC_PCI - if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) && + if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) && (IDLE_ON(pAd)) && (pAd->StaCfg.bRadio == TRUE) && (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) @@ -338,9 +348,7 @@ VOID MlmeJoinReqAction( RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); -#ifdef RT2860 - pAd->CommonCfg.BBPCurrentBW = BW_20; -#endif // RT2860 // + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n")); // switch channel and waiting for beacon timer @@ -898,8 +906,6 @@ VOID PeerBeaconAtJoinAction( else //Used the default TX Power Percentage. pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; - InitChannelRelatedValue(pAd); - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status); @@ -1317,7 +1323,7 @@ VOID PeerBeacon( if (MessageToMe) { #ifdef RTMP_MAC_PCI - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { // Restore to correct BBP R3 value if (pAd->Antenna.field.RxPath > 1) @@ -1336,7 +1342,7 @@ VOID PeerBeacon( else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM)) { #ifdef RTMP_MAC_PCI - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); @@ -1356,7 +1362,7 @@ VOID PeerBeacon( // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme // can we cheat here (i.e. just check MGMT & AC_BE) for better performance? #ifdef RTMP_MAC_PCI - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); Index: b/drivers/staging/rt2860/sta/wpa.c =================================================================== --- a/drivers/staging/rt2860/sta/wpa.c +++ b/drivers/staging/rt2860/sta/wpa.c @@ -389,51 +389,3 @@ VOID WpaStaGroupKeySetting( NULL); } - - -/* - ======================================================================== - - Routine Description: - Send EAPoL-Start packet to AP. - - Arguments: - pAd - NIC Adapter pointer - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - Actions after link up - 1. Change the correct parameters - 2. Send EAPOL - START - - ======================================================================== -*/ -VOID WpaSendEapolStart( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pBssid) -{ - IEEE8021X_FRAME Packet; - UCHAR Header802_3[14]; - - DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaSendEapolStart\n")); - - NdisZeroMemory(Header802_3,sizeof(UCHAR)*14); - - MAKE_802_3_HEADER(Header802_3, pBssid, &pAd->CurrentAddress[0], EAPOL); - - // Zero message 2 body - NdisZeroMemory(&Packet, sizeof(Packet)); - Packet.Version = EAPOL_VER; - Packet.Type = EAPOLStart; - Packet.Length = cpu2be16(0); - - // Copy frame to Tx ring - RTMPToWirelessSta((PRTMP_ADAPTER)pAd, &pAd->MacTab.Content[BSSID_WCID], - Header802_3, LENGTH_802_3, (PUCHAR)&Packet, 4, TRUE); - - DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaSendEapolStart\n")); -} Index: b/drivers/staging/rt2860/sta_ioctl.c =================================================================== --- a/drivers/staging/rt2860/sta_ioctl.c +++ b/drivers/staging/rt2860/sta_ioctl.c @@ -160,6 +160,12 @@ INT Set_PSMode_Proc( IN PRTMP_ADAPTER pAdapter, IN PSTRING arg); +#ifdef RT3090 +INT Set_PCIePSLevel_Proc( +IN PRTMP_ADAPTER pAdapter, +IN PUCHAR arg); +#endif // RT3090 // + INT Set_Wpa_Support( IN PRTMP_ADAPTER pAd, IN PSTRING arg); @@ -515,6 +521,7 @@ rt_ioctl_giwname(struct net_device *dev, { strncpy(name, "Ralink STA", IFNAMSIZ); // RT2870 2.1.0.0 uses "RT2870 Wireless" + // RT3090 2.1.0.0 uses "RT2860 Wireless" return 0; } Index: b/drivers/staging/rt2860/wpa.h =================================================================== --- a/drivers/staging/rt2860/wpa.h +++ b/drivers/staging/rt2860/wpa.h @@ -347,13 +347,6 @@ typedef enum _WpaMixPairCipher WPA_TKIPAES_WPA2_TKIPAES = 0x0F, } WPA_MIX_PAIR_CIPHER; -// 802.1x authentication format -typedef struct _IEEE8021X_FRAME { - UCHAR Version; // 1.0 - UCHAR Type; // 0 = EAP Packet - USHORT Length; -} IEEE8021X_FRAME, *PIEEE8021X_FRAME; - typedef struct PACKED _RSN_IE_HEADER_STRUCT { UCHAR Eid; UCHAR Length; Index: b/drivers/staging/rt3090/common/rtmp_mcu.c =================================================================== --- a/drivers/staging/rt3090/common/rtmp_mcu.c +++ b/drivers/staging/rt3090/common/rtmp_mcu.c @@ -43,7 +43,7 @@ // New 8k byte firmware size for RT3071/RT3072 #define FIRMWAREIMAGE_MAX_LENGTH 0x2000 -#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR)) +#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage_3090) / sizeof(UCHAR)) #define FIRMWARE_MAJOR_VERSION 0 #define FIRMWAREIMAGEV1_LENGTH 0x1000 @@ -335,8 +335,8 @@ NDIS_STATUS RtmpAsicLoadFirmware( UINT32 MacReg = 0; UINT32 Version = (pAd->MACVersion >> 16); - pFirmwareImage = FirmwareImage; - FileLength = sizeof(FirmwareImage); + pFirmwareImage = FirmwareImage_3090; + FileLength = sizeof(*pFirmwareImage); // New 8k byte firmware size for RT3071/RT3072 //DBGPRINT(RT_DEBUG_TRACE, ("Usb Chip\n")); @@ -347,7 +347,7 @@ NDIS_STATUS RtmpAsicLoadFirmware( #ifdef RTMP_MAC_PCI if ((Version == 0x2860) || IS_RT3090(pAd)||IS_RT3390(pAd)) { - pFirmwareImage = FirmwareImage; + pFirmwareImage = FirmwareImage_3090; FileLength = FIRMWAREIMAGE_LENGTH; } #endif // RTMP_MAC_PCI // Index: b/drivers/staging/rt3090/firmware.h =================================================================== --- a/drivers/staging/rt3090/firmware.h +++ b/drivers/staging/rt3090/firmware.h @@ -2,7 +2,7 @@ /* AUTO GEN PLEASE DO NOT MODIFY IT */ -UCHAR FirmwareImage [] = { +UCHAR FirmwareImage_3090 [] = { 0x02, 0x02, 0xf3, 0x02, 0x02, 0xa1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x27, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xd8, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,