diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-09-22 18:44:24 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 20:21:45 (GMT) |
commit | e44fd1cfded0e42c681ad5419b1ceea600ead29d (patch) | |
tree | 4f6811b11a8cb4c79e40b887e083005336281186 /drivers/staging/rt2860/common | |
parent | c3126b93b512c046340dfc4ab38beabd8084169f (diff) | |
download | linux-fsl-qoriq-e44fd1cfded0e42c681ad5419b1ceea600ead29d.tar.xz |
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 <bzolnier@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/rt2860/common')
-rw-r--r-- | drivers/staging/rt2860/common/cmm_asic.c | 29 | ||||
-rw-r--r-- | drivers/staging/rt2860/common/cmm_data_pci.c | 6 | ||||
-rw-r--r-- | drivers/staging/rt2860/common/cmm_mac_pci.c | 255 | ||||
-rw-r--r-- | drivers/staging/rt2860/common/cmm_profile.c | 43 | ||||
-rw-r--r-- | drivers/staging/rt2860/common/cmm_sync.c | 13 | ||||
-rw-r--r-- | drivers/staging/rt2860/common/mlme.c | 112 | ||||
-rw-r--r-- | drivers/staging/rt2860/common/rt_rf.c | 8 | ||||
-rw-r--r-- | drivers/staging/rt2860/common/rtmp_init.c | 73 | ||||
-rw-r--r-- | drivers/staging/rt2860/common/rtmp_mcu.c | 98 | ||||
-rw-r--r-- | drivers/staging/rt2860/common/rtmp_timer.c | 4 |
10 files changed, 525 insertions, 116 deletions
diff --git a/drivers/staging/rt2860/common/cmm_asic.c b/drivers/staging/rt2860/common/cmm_asic.c index 83ed07b..5d3a387 100644 --- 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; diff --git a/drivers/staging/rt2860/common/cmm_data_pci.c b/drivers/staging/rt2860/common/cmm_data_pci.c index d808e7d..e9739b4 100644 --- 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; } diff --git a/drivers/staging/rt2860/common/cmm_mac_pci.c b/drivers/staging/rt2860/common/cmm_mac_pci.c index 5aa6944..73992cb 100644 --- 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 // diff --git a/drivers/staging/rt2860/common/cmm_profile.c b/drivers/staging/rt2860/common/cmm_profile.c index 2d28524..056cffd 100644 --- 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)) { diff --git a/drivers/staging/rt2860/common/cmm_sync.c b/drivers/staging/rt2860/common/cmm_sync.c index 4cb507d..9be4d50 100644 --- 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. diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c index 02627c7..7647c09 100644 --- 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; diff --git a/drivers/staging/rt2860/common/rt_rf.c b/drivers/staging/rt2860/common/rt_rf.c index 34a6fca..e9f9384 100644 --- 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 // } diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c index 1dd4c82..3b43101 100644 --- 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<NUM_MAC_REG_PARMS; Index++) { #ifdef RT30xx - if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd))) + if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))) { MACRegTable[Index].Value = 0x00000400; } @@ -1713,6 +1740,11 @@ NDIS_STATUS NICInitializeAsic( // PCI and USB are not the same because PCI driver needs to wait for PCI bus ready RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0); // initialize BBP R/W access agent RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0); +#ifdef RT3090 + //2008/11/28:KH add to fix the dead rf frequency offset bug<-- + AsicSendCommandToMcu(pAd, 0x72, 0, 0, 0); + //2008/11/28:KH add to fix the dead rf frequency offset bug--> +#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); diff --git a/drivers/staging/rt2860/common/rtmp_mcu.c b/drivers/staging/rt2860/common/rtmp_mcu.c index 24531c5..229ea05 100644 --- 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,9 +189,72 @@ 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); @@ -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; } diff --git a/drivers/staging/rt2860/common/rtmp_timer.c b/drivers/staging/rt2860/common/rtmp_timer.c index 258ab1b..fa77f5d 100644 --- 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 // |