diff options
Diffstat (limited to 'drivers/staging/rt2870/common/mlme.c')
-rw-r--r-- | drivers/staging/rt2870/common/mlme.c | 810 |
1 files changed, 804 insertions, 6 deletions
diff --git a/drivers/staging/rt2870/common/mlme.c b/drivers/staging/rt2870/common/mlme.c index 399ced2..f1962e0 100644 --- a/drivers/staging/rt2870/common/mlme.c +++ b/drivers/staging/rt2870/common/mlme.c @@ -447,7 +447,13 @@ FREQUENCY_ITEM FreqItems3020[] = {13, 247, 2, 2}, {14, 248, 2, 4}, }; +#ifndef RT30xx #define NUM_OF_3020_CHNL (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM)) +#endif +#ifdef RT30xx +//2008/07/10:KH Modified to share this variable +UCHAR NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM)); +#endif /* ========================================================================== @@ -638,7 +644,10 @@ VOID MlmeHandler( VOID MlmeHalt( IN PRTMP_ADAPTER pAd) { - BOOLEAN Cancelled; + BOOLEAN Cancelled; +#ifdef RT3070 + UINT32 TxPinCfg = 0x00050F0F; +#endif // RT3070 // DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n")); @@ -679,6 +688,16 @@ VOID MlmeHalt( RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word); } #endif // RT2870 // +#ifdef RT3070 + // + // Turn off LNA_PE + // + if (IS_RT3070(pAd) || IS_RT3071(pAd)) + { + TxPinCfg &= 0xFFFFF0F0; + RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg); + } +#endif // RT3070 // } RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled @@ -789,6 +808,10 @@ VOID MlmePeriodicExec( // RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3); pAd->Mlme.PeriodicRound ++; +#ifdef RT3070 + // execute every 100ms, update the Tx FIFO Cnt for update Tx Rate. + NICUpdateFifoStaCounters(pAd); +#endif // RT3070 // // execute every 500ms if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/) { @@ -852,6 +875,7 @@ VOID MlmePeriodicExec( pAd->RalinkCounters.OneSecTxRetryOkCount + pAd->RalinkCounters.OneSecTxFailCount; + // dynamic adjust antenna evaluation period according to the traffic if (TxTotalCnt > 50) { if (pAd->Mlme.OneSecPeriodicRound % 10 == 0) @@ -1334,7 +1358,10 @@ VOID MlmeSelectTxRateTable( //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) if ((pEntry->RateLen == 4) +#ifndef RT30xx +//Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) +#endif ) {// B only AP *ppTable = RateSwitchTable11B; @@ -2501,6 +2528,7 @@ VOID MlmeCheckPsmChange( if (INFRA_ON(pAd) && (PowerMode != Ndis802_11PowerModeCAM) && (pAd->StaCfg.Psm == PWR_ACTIVE) && +#ifndef RT30xx (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)) { NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime); @@ -2515,6 +2543,42 @@ VOID MlmeCheckPsmChange( RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); } } +#endif +#ifdef RT30xx +// (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) /*&& + (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) && + (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/) + { + // add by johnli, use Rx OK data count per second to calculate throughput + // If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria + // Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps + if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) && +/* Iverson mark + (pAd->StaCfg.HTPhyMode.field.MODE <= MODE_OFDM) && +*/ + (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) || + ((pAd->StaCfg.HTPhyMode.field.MCS > 3) && +/* Iverson mark + (pAd->StaCfg.HTPhyMode.field.MODE > MODE_OFDM) && +*/ + (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400))) + { + // Get this time + NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime); + pAd->RalinkCounters.RxCountSinceLastNULL = 0; + MlmeSetPsmBit(pAd, PWR_SAVE); + if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) + { + RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE); + } + else + { + RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); + } + } + } +#endif } // IRQL = PASSIVE_LEVEL @@ -2529,7 +2593,9 @@ VOID MlmeSetPsmBit( RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word); csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0; RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word); +#ifndef RT30xx DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm)); +#endif } // IRQL = DISPATCH_LEVEL @@ -3560,9 +3626,21 @@ ULONG BssTableSetEntry( } else { +#ifndef RT30xx BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); +#endif +#ifdef RT30xx + /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */ + if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) || + (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen))) + { + BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin, + CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, + NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); + } +#endif } return Idx; @@ -3623,9 +3701,14 @@ VOID BssTableSsidSort( continue; // check group cipher +#ifndef RT30xx if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) && (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) && (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled)) +#endif +#ifdef RT30xx + if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) +#endif continue; // check pairwise cipher, skip if none matched @@ -3644,9 +3727,14 @@ VOID BssTableSsidSort( continue; // check group cipher +#ifndef RT30xx if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) && (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) && (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled)) +#endif +#ifdef RT30xx + if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher) +#endif continue; // check pairwise cipher, skip if none matched @@ -3924,10 +4012,16 @@ VOID BssCipherParse( switch (*pTmp) { case 1: +#ifndef RT30xx pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled; break; case 5: pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled; +#endif +#ifdef RT30xx + case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway + pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled; +#endif break; case 2: pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled; @@ -4014,7 +4108,6 @@ VOID BssCipherParse( pBss->AuthMode = Ndis802_11AuthModeWPANone; pBss->AuthModeAux = Ndis802_11AuthModeWPANone; pBss->WepStatus = pBss->WPA.GroupCipher; - // Patched bugs for old driver if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher; } @@ -4044,10 +4137,16 @@ VOID BssCipherParse( switch (pCipher->Type) { case 1: +#ifndef RT30xx pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled; break; case 5: pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled; +#endif +#ifdef RT30xx + case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway + pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled; +#endif break; case 2: pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled; @@ -4141,7 +4240,6 @@ VOID BssCipherParse( pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux; pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher; pBss->WepStatus = pBss->WPA.GroupCipher; - // Patched bugs for old driver if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher; } @@ -5249,6 +5347,277 @@ VOID AsicUpdateProtect( } } + +#ifdef RT30xx +/* + ======================================================================== + + Routine Description: Write RT30xx RF register through MAC + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RT30xxWriteRFRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR RegID, + IN UCHAR Value) +{ + RF_CSR_CFG_STRUC rfcsr; + UINT i = 0; + + do + { + RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); + + if (!rfcsr.field.RF_CSR_KICK) + break; + i++; + } + while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); + + if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); + return STATUS_UNSUCCESSFUL; + } + + rfcsr.field.RF_CSR_WR = 1; + rfcsr.field.RF_CSR_KICK = 1; + rfcsr.field.TESTCSR_RFACC_REGNUM = RegID; + rfcsr.field.RF_CSR_DATA = Value; + + RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); + + return STATUS_SUCCESS; +} + + +/* + ======================================================================== + + Routine Description: Read RT30xx RF register through MAC + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NTSTATUS RT30xxReadRFRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR RegID, + IN PUCHAR pValue) +{ + RF_CSR_CFG_STRUC rfcsr; + UINT i=0, k=0; + + for (i=0; i<MAX_BUSY_COUNT; i++) + { + RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); + + if (rfcsr.field.RF_CSR_KICK == BUSY) + { + continue; + } + rfcsr.word = 0; + rfcsr.field.RF_CSR_WR = 0; + rfcsr.field.RF_CSR_KICK = 1; + rfcsr.field.TESTCSR_RFACC_REGNUM = RegID; + RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); + for (k=0; k<MAX_BUSY_COUNT; k++) + { + RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); + + if (rfcsr.field.RF_CSR_KICK == IDLE) + break; + } + if ((rfcsr.field.RF_CSR_KICK == IDLE) && + (rfcsr.field.TESTCSR_RFACC_REGNUM == RegID)) + { + *pValue = (UCHAR)rfcsr.field.RF_CSR_DATA; + break; + } + } + if (rfcsr.field.RF_CSR_KICK == BUSY) + { + DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", RegID, rfcsr.word,i,k)); + return STATUS_UNSUCCESSFUL; + } + + return STATUS_SUCCESS; +} +#endif // RT30xx // + +#ifdef RT30xx +// add by johnli, RF power sequence setup +/* + ========================================================================== + Description: + + Load RF normal operation-mode setup + + ========================================================================== + */ +VOID RT30xxLoadRFNormalModeSetup( + IN PRTMP_ADAPTER pAd) +{ + UCHAR RFValue; + + // RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1 + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + RFValue = (RFValue & (~0x0C)) | 0x31; + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + // TX_LO2_en, RF R15 register Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R15, &RFValue); + RFValue &= (~0x08); + RT30xxWriteRFRegister(pAd, RF_R15, RFValue); + + // TX_LO1_en, RF R17 register Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R17, &RFValue); + RFValue &= (~0x08); + // to fix rx long range issue + if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0)) + { + RFValue |= 0x20; + } + RT30xxWriteRFRegister(pAd, RF_R17, RFValue); + + // RX_LO1_en, RF R20 register Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R20, &RFValue); + RFValue &= (~0x08); + RT30xxWriteRFRegister(pAd, RF_R20, RFValue); + + // RX_LO2_en, RF R21 register Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R21, &RFValue); + RFValue &= (~0x08); + RT30xxWriteRFRegister(pAd, RF_R21, RFValue); + + // LDORF_VC, RF R27 register Bit 2 to 0 + RT30xxReadRFRegister(pAd, RF_R27, &RFValue); + if ((pAd->MACVersion & 0xffff) < 0x0211) + RFValue = (RFValue & (~0x77)) | 0x3; + else + RFValue = (RFValue & (~0x77)); + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + /* end johnli */ +} + +/* + ========================================================================== + Description: + + Load RF sleep-mode setup + + ========================================================================== + */ +VOID RT30xxLoadRFSleepModeSetup( + IN PRTMP_ADAPTER pAd) +{ + UCHAR RFValue; + UINT32 MACValue; + + // RF_BLOCK_en. RF R1 register Bit 0 to 0 + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + RFValue &= (~0x01); + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + // VCO_IC, RF R7 register Bit 4 & Bit 5 to 0 + RT30xxReadRFRegister(pAd, RF_R07, &RFValue); + RFValue &= (~0x30); + RT30xxWriteRFRegister(pAd, RF_R07, RFValue); + + // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R09, &RFValue); + RFValue &= (~0x0E); + RT30xxWriteRFRegister(pAd, RF_R09, RFValue); + + // RX_CTB_en, RF R21 register Bit 7 to 0 + RT30xxReadRFRegister(pAd, RF_R21, &RFValue); + RFValue &= (~0x80); + RT30xxWriteRFRegister(pAd, RF_R21, RFValue); + + // LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1 + RT30xxReadRFRegister(pAd, RF_R27, &RFValue); + RFValue |= 0x77; + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + + RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); + MACValue |= 0x1D000000; + RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); +} + +/* + ========================================================================== + Description: + + Reverse RF sleep-mode setup + + ========================================================================== + */ +VOID RT30xxReverseRFSleepModeSetup( + IN PRTMP_ADAPTER pAd) +{ + UCHAR RFValue; + UINT32 MACValue; + + // RF_BLOCK_en, RF R1 register Bit 0 to 1 + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + RFValue |= 0x01; + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + // VCO_IC, RF R7 register Bit 4 & Bit 5 to 1 + RT30xxReadRFRegister(pAd, RF_R07, &RFValue); + RFValue |= 0x30; + RT30xxWriteRFRegister(pAd, RF_R07, RFValue); + + // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1 + RT30xxReadRFRegister(pAd, RF_R09, &RFValue); + RFValue |= 0x0E; + RT30xxWriteRFRegister(pAd, RF_R09, RFValue); + + // RX_CTB_en, RF R21 register Bit 7 to 1 + RT30xxReadRFRegister(pAd, RF_R21, &RFValue); + RFValue |= 0x80; + RT30xxWriteRFRegister(pAd, RF_R21, RFValue); + + // LDORF_VC, RF R27 register Bit 2 to 0 + RT30xxReadRFRegister(pAd, RF_R27, &RFValue); + if ((pAd->MACVersion & 0xffff) < 0x0211) + RFValue = (RFValue & (~0x77)) | 0x3; + else + RFValue = (RFValue & (~0x77)); + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + + // RT3071 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, &MACValue); + MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); + } + else + { + RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); + MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); + } +} +// end johnli +#endif // RT30xx // + /* ========================================================================== Description: @@ -5270,6 +5639,21 @@ VOID AsicSwitchChannel( RTMP_RF_REGS *RFRegTable; // Search Tx power value +#ifdef RT30xx + // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list + // in ChannelList, so use TxPower array instead. + // + for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) + { + if (Channel == pAd->TxPower[index].Channel) + { + TxPwer = pAd->TxPower[index].Power; + TxPwer2 = pAd->TxPower[index].Power2; + break; + } + } +#endif +#ifndef RT30xx for (index = 0; index < pAd->ChannelListNum; index++) { if (Channel == pAd->ChannelList[index].Channel) @@ -5279,15 +5663,27 @@ VOID AsicSwitchChannel( break; } } +#endif if (index == MAX_NUM_OF_CHANNELS) { +#ifndef RT30xx DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Cant find the Channel#%d \n", Channel)); +#endif +#ifdef RT30xx + DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel)); +#endif } #ifdef RT2870 // The RF programming sequence is difference between 3xxx and 2xxx +#ifdef RT30xx + if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) || + (pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022))) +#endif +#ifndef RT30xx if (IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020))) +#endif { /* modify by WY for Read RF Reg. error */ UCHAR RFValue; @@ -5300,6 +5696,7 @@ VOID AsicSwitchChannel( RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N); RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K); +#ifndef RT30xx RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RFValue); RFValue = (RFValue & 0xFC) | FreqItems3020[index].R; RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RFValue); @@ -5313,7 +5710,42 @@ VOID AsicSwitchChannel( RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue); RFValue = (RFValue & 0x80) | pAd->RfFreqOffset; RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue); +#endif +#ifdef RT30xx + RT30xxReadRFRegister(pAd, RF_R06, &RFValue); + RFValue = (RFValue & 0xFC) | FreqItems3020[index].R; + RT30xxWriteRFRegister(pAd, RF_R06, RFValue); + + // Set Tx0 Power + RT30xxReadRFRegister(pAd, RF_R12, &RFValue); + RFValue = (RFValue & 0xE0) | TxPwer; + RT30xxWriteRFRegister(pAd, RF_R12, RFValue); + + // Set Tx1 Power + RT30xxReadRFRegister(pAd, RF_R13, &RFValue); + RFValue = (RFValue & 0xE0) | TxPwer2; + RT30xxWriteRFRegister(pAd, RF_R13, RFValue); + + // Tx/Rx Stream setting + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + //if (IS_RT3090(pAd)) + // RFValue |= 0x01; // Enable RF block. + RFValue &= 0x03; //clear bit[7~2] + if (pAd->Antenna.field.TxPath == 1) + RFValue |= 0xA0; + else if (pAd->Antenna.field.TxPath == 2) + RFValue |= 0x80; + if (pAd->Antenna.field.RxPath == 1) + RFValue |= 0x50; + else if (pAd->Antenna.field.RxPath == 2) + RFValue |= 0x40; + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + // Set RF offset + RT30xxReadRFRegister(pAd, RF_R23, &RFValue); + RFValue = (RFValue & 0x80) | pAd->RfFreqOffset; + RT30xxWriteRFRegister(pAd, RF_R23, RFValue); +#endif // Set BW if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40)) { @@ -5324,6 +5756,7 @@ VOID AsicSwitchChannel( { RFValue = pAd->Mlme.CaliBW20RfR24; } +#ifndef RT30xx RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR)RFValue); // Enable RF tuning @@ -5333,11 +5766,34 @@ VOID AsicSwitchChannel( // latch channel for future usage. pAd->LatchRfRegs.Channel = Channel; +#endif +#ifdef RT30xx + RT30xxWriteRFRegister(pAd, RF_R24, RFValue); + RT30xxWriteRFRegister(pAd, RF_R31, RFValue); + // Enable RF tuning + RT30xxReadRFRegister(pAd, RF_R07, &RFValue); + RFValue = RFValue | 0x1; + RT30xxWriteRFRegister(pAd, RF_R07, RFValue); + + // latch channel for future usage. + pAd->LatchRfRegs.Channel = Channel; + + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", + Channel, + pAd->RfIcType, + TxPwer, + TxPwer2, + pAd->Antenna.field.TxPath, + FreqItems3020[index].N, + FreqItems3020[index].K, + FreqItems3020[index].R)); +#endif break; } } +#ifndef RT30xx DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", Channel, pAd->RfIcType, @@ -5347,6 +5803,7 @@ VOID AsicSwitchChannel( FreqItems3020[index].N, FreqItems3020[index].K, FreqItems3020[index].R)); +#endif } else #endif // RT2870 // @@ -5603,6 +6060,53 @@ VOID AsicAntennaSelect( IN PRTMP_ADAPTER pAd, IN UCHAR Channel) { +#ifdef RT30xx + if (pAd->Mlme.OneSecPeriodicRound % 2 == 1) + { + // patch for AsicSetRxAnt failed + pAd->RxAnt.EvaluatePeriod = 0; + + // check every 2 second. If rcv-beacon less than 5 in the past 2 second, then AvgRSSI is no longer a + // valid indication of the distance between this AP and its clients. + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + { + SHORT realavgrssi1; + + // if no traffic then reset average rssi to trigger evaluation + if (pAd->StaCfg.NumOfAvgRssiSample < 5) + { + pAd->RxAnt.Pair1LastAvgRssi = (-99); + pAd->RxAnt.Pair2LastAvgRssi = (-99); + DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no traffic/beacon, reset RSSI\n")); + } + + pAd->StaCfg.NumOfAvgRssiSample = 0; + realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3); + + DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi1, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt)); + + // if the difference between two rssi is larger or less than 5, then evaluate the other antenna + if ((pAd->RxAnt.EvaluateStableCnt < 2) || (realavgrssi1 > (pAd->RxAnt.Pair1LastAvgRssi + 5)) || (realavgrssi1 < (pAd->RxAnt.Pair1LastAvgRssi - 5))) + { + pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1; + AsicEvaluateRxAnt(pAd); + } + } + else + { + // if not connected, always switch antenna to try to connect + UCHAR temp; + + temp = pAd->RxAnt.Pair1PrimaryRxAnt; + pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt; + pAd->RxAnt.Pair1SecondaryRxAnt = temp; + + DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no connect, switch to another one to try connection\n")); + + AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); + } + } +#endif /* RT30xx */ } /* @@ -6320,6 +6824,14 @@ VOID AsicSetEdcaParm( Ac0Cfg.field.Aifsn = 3; Ac2Cfg.field.AcTxop = 5; } + +#ifdef RT30xx + if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020) + { + // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta. + Ac2Cfg.field.Aifsn = 5; + } +#endif // RT30xx // } Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO]; @@ -6386,7 +6898,7 @@ VOID AsicSetEdcaParm( AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4; // Tuning for TGn Wi-Fi 5.2.32 - // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta + // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta if (STA_TGN_WIFI_ON(pAd) && pEdcaParm->Aifsn[QID_AC_VI] == 10) { @@ -6399,6 +6911,10 @@ VOID AsicSetEdcaParm( } AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test +#ifdef RT30xx + if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020) + AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04. +#endif // RT30xx // RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word); @@ -6461,6 +6977,7 @@ VOID AsicSetSlotTime( SlotTime = (bUseShortSlotTime)? 9 : 20; { +#ifndef RT30xx // force using short SLOT time for FAE to demo performance when TxBurst is ON if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))) || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)) @@ -6470,6 +6987,10 @@ VOID AsicSetSlotTime( // And we will not set to short slot when bEnableTxBurst is TRUE. } else if (pAd->CommonCfg.bEnableTxBurst) +#endif +#ifdef RT30xx + if (pAd->CommonCfg.bEnableTxBurst) +#endif SlotTime = 9; } @@ -7302,6 +7823,58 @@ CHAR RTMPMaxRssi( return larger; } +#ifdef RT30xx +// Antenna divesity use GPIO3 and EESK pin for control +// Antenna and EEPROM access are both using EESK pin, +// Therefor we should avoid accessing EESK at the same time +// Then restore antenna after EEPROM access +VOID AsicSetRxAnt( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ant) +{ +#ifdef RT30xx + UINT32 Value; + UINT32 x; + + if ((pAd->EepromAccess) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + return; + } + + // the antenna selection is through firmware and MAC register(GPIO3) + if (Ant == 0) + { + // Main antenna + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x |= (EESK); + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); + Value &= ~(0x0808); + RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n")); + } + else + { + // Aux antenna + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EESK); + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); + Value &= ~(0x0808); + Value |= 0x08; + RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n")); + } +#endif // RT30xx // +} +#endif /* RT30xx */ + /* ======================================================================== Routine Description: @@ -7320,6 +7893,7 @@ VOID AsicEvaluateRxAnt( { UCHAR BBPR3 = 0; +#ifndef RT30xx { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | @@ -7366,6 +7940,89 @@ VOID AsicEvaluateRxAnt( pAd->Mlme.bLowThroughput = TRUE; } } +#endif /* RT30xx */ +#ifdef RT30xx + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_RADIO_OFF | + fRTMP_ADAPTER_NIC_NOT_EXIST | + fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) || + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) +#ifdef RT30xx + || (pAd->EepromAccess) +#endif // RT30xx // + ) + return; + + + { + //if (pAd->StaCfg.Psm == PWR_SAVE) + // return; + } + + // two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove + // one is antenna diversity:there is only one antenna can rx and tx + // the other is failed antenna remove:two physical antenna can rx and tx + if (pAd->NicConfig2.field.AntDiversity) + { + DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n", + pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt)); + + AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt); + + pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt + pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE; + pAd->RxAnt.RcvPktNumWhenEvaluate = 0; + + // a one-shot timer to end the evalution + // dynamic adjust antenna evaluation period according to the traffic + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100); + else + RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300); + } + else + { + if (pAd->StaCfg.Psm == PWR_SAVE) + return; + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3); + BBPR3 &= (~0x18); + if(pAd->Antenna.field.RxPath == 3) + { + BBPR3 |= (0x10); + } + else if(pAd->Antenna.field.RxPath == 2) + { + BBPR3 |= (0x8); + } + else if(pAd->Antenna.field.RxPath == 1) + { + BBPR3 |= (0x0); + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) + ) + { + ULONG TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + + pAd->RalinkCounters.OneSecTxRetryOkCount + + pAd->RalinkCounters.OneSecTxFailCount; + + // dynamic adjust antenna evaluation period according to the traffic + if (TxTotalCnt > 50) + { + RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20); + pAd->Mlme.bLowThroughput = FALSE; + } + else + { + RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300); + pAd->Mlme.bLowThroughput = TRUE; + } + } + } +#endif /* RT30xx */ } /* @@ -7391,6 +8048,7 @@ VOID AsicRxAntEvalTimeout( UCHAR BBPR3 = 0; CHAR larger = -127, rssi0, rssi1, rssi2; +#ifndef RT30xx { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) || @@ -7449,6 +8107,107 @@ VOID AsicRxAntEvalTimeout( } RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); } +#endif /* RT30xx */ +#ifdef RT30xx + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_RADIO_OFF | + fRTMP_ADAPTER_NIC_NOT_EXIST) || + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) +#ifdef RT30xx + || (pAd->EepromAccess) +#endif // RT30xx // + ) + return; + + { + //if (pAd->StaCfg.Psm == PWR_SAVE) + // return; + + if (pAd->NicConfig2.field.AntDiversity) + { + if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt])) + { + UCHAR temp; + + // + // select PrimaryRxAntPair + // Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair. + // Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt + // + temp = pAd->RxAnt.Pair1PrimaryRxAnt; + pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt; + pAd->RxAnt.Pair1SecondaryRxAnt = temp; + + pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3); + pAd->RxAnt.EvaluateStableCnt = 0; + } + else + { + // if the evaluated antenna is not better than original, switch back to original antenna + AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); + pAd->RxAnt.EvaluateStableCnt ++; + } + + pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt + + DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n", + pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate)); + } + else + { + if (pAd->StaCfg.Psm == PWR_SAVE) + return; + + // if the traffic is low, use average rssi as the criteria + if (pAd->Mlme.bLowThroughput == TRUE) + { + rssi0 = pAd->StaCfg.RssiSample.LastRssi0; + rssi1 = pAd->StaCfg.RssiSample.LastRssi1; + rssi2 = pAd->StaCfg.RssiSample.LastRssi2; + } + else + { + rssi0 = pAd->StaCfg.RssiSample.AvgRssi0; + rssi1 = pAd->StaCfg.RssiSample.AvgRssi1; + rssi2 = pAd->StaCfg.RssiSample.AvgRssi2; + } + + if(pAd->Antenna.field.RxPath == 3) + { + larger = max(rssi0, rssi1); + + if (larger > (rssi2 + 20)) + pAd->Mlme.RealRxPath = 2; + else + pAd->Mlme.RealRxPath = 3; + } + else if(pAd->Antenna.field.RxPath == 2) + { + if (rssi0 > (rssi1 + 20)) + pAd->Mlme.RealRxPath = 1; + else + pAd->Mlme.RealRxPath = 2; + } + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3); + BBPR3 &= (~0x18); + if(pAd->Mlme.RealRxPath == 3) + { + BBPR3 |= (0x10); + } + else if(pAd->Mlme.RealRxPath == 2) + { + BBPR3 |= (0x8); + } + else if(pAd->Mlme.RealRxPath == 1) + { + BBPR3 |= (0x0); + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); + } + } +#endif /* RT30xx */ } @@ -7664,14 +8423,24 @@ VOID AsicStaBbpTuning( #ifdef RT2870 // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control // Otherwise, it will have some throughput side effect when low RSSI +#ifndef RT30xx if (IS_RT3070(pAd)) +#endif +#ifdef RT30xx + if (IS_RT30xx(pAd)) +#endif { if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) { R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20; if (OrigR66Value != R66) { +#ifndef RT30xx RTUSBWriteBBPRegister(pAd, BBP_R66, R66); +#endif +#ifdef RT30xx + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); +#endif } } else @@ -7679,7 +8448,12 @@ VOID AsicStaBbpTuning( R66 = 0x1C + 2*GET_LNA_GAIN(pAd); if (OrigR66Value != R66) { +#ifndef RT30xx RTUSBWriteBBPRegister(pAd, BBP_R66, R66); +#endif +#ifdef RT30xx + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); +#endif } } } @@ -7781,12 +8555,20 @@ VOID AsicTurnOffRFClk( IN PRTMP_ADAPTER pAd, IN UCHAR Channel) { - // RF R2 bit 18 = 0 UINT32 R1 = 0, R2 = 0, R3 = 0; UCHAR index; RTMP_RF_REGS *RFRegTable; +#ifdef RT30xx + // The RF programming sequence is difference between 3xxx and 2xxx + if (IS_RT3090(pAd)) + { + RT30xxLoadRFSleepModeSetup(pAd); // add by johnli, RF power sequence setup, load RF sleep-mode setup + } + else + { +#endif // RT30xx // RFRegTable = RF2850RegTable; switch (pAd->RfIcType) @@ -7828,6 +8610,10 @@ VOID AsicTurnOffRFClk( default: break; } +#ifdef RT30xx + } +#endif // RT30xx // + } @@ -7835,12 +8621,19 @@ VOID AsicTurnOnRFClk( IN PRTMP_ADAPTER pAd, IN UCHAR Channel) { - // RF R2 bit 18 = 0 UINT32 R1 = 0, R2 = 0, R3 = 0; UCHAR index; RTMP_RF_REGS *RFRegTable; +#ifdef RT30xx + // The RF programming sequence is difference between 3xxx and 2xxx + if (IS_RT3090(pAd)) + { + } + else + { +#endif // RT30xx // RFRegTable = RF2850RegTable; switch (pAd->RfIcType) @@ -7887,9 +8680,14 @@ VOID AsicTurnOnRFClk( break; } +#ifndef RT30xx DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n", Channel, pAd->RfIcType, R2)); +#endif +#ifdef RT30xx + } +#endif // RT30xx // } |