diff options
Diffstat (limited to 'drivers/staging/rt2870/common/rtmp_init.c')
-rw-r--r-- | drivers/staging/rt2870/common/rtmp_init.c | 432 |
1 files changed, 420 insertions, 12 deletions
diff --git a/drivers/staging/rt2870/common/rtmp_init.c b/drivers/staging/rt2870/common/rtmp_init.c index 69de5a34a11..92e25ff76cf 100644 --- a/drivers/staging/rt2870/common/rtmp_init.c +++ b/drivers/staging/rt2870/common/rtmp_init.c @@ -38,7 +38,12 @@ Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT. */ #include "../rt_config.h" +#ifndef RT30xx #include "firmware.h" +#endif +#ifdef RT30xx +#include "../../rt3070/firmware.h" +#endif UCHAR BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; ULONG BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008, @@ -134,7 +139,12 @@ REG_PAIR RT30xx_RFRegTable[] = { {RF_R06, 0x02}, {RF_R07, 0x70}, {RF_R09, 0x0F}, +#ifndef RT30xx {RF_R10, 0x71}, +#endif +#ifdef RT30xx + {RF_R10, 0x41}, +#endif {RF_R11, 0x21}, {RF_R12, 0x7B}, {RF_R14, 0x90}, @@ -147,7 +157,9 @@ REG_PAIR RT30xx_RFRegTable[] = { {RF_R21, 0xDB}, {RF_R24, 0x16}, {RF_R25, 0x01}, +#ifndef RT30xx {RF_R27, 0x03}, +#endif {RF_R29, 0x1F}, }; #define NUM_RF_REG_PARMS (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR)) @@ -184,6 +196,7 @@ RTMP_REG_PAIR MACRegTable[] = { {AUTO_RSP_CFG, 0x00000013}, // Initial Auto_Responder, because QA will turn off Auto-Responder {CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. {OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. +//PS packets use Tx1Q (for HCCA) when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) #ifdef RT2870 {PBF_CFG, 0xf40006}, // Only enable Queue 2 {MM40_PROT_CFG, 0x3F44084}, // Initial Auto_Responder, because QA will turn off Auto-Responder @@ -1070,6 +1083,7 @@ NDIS_STATUS NICReadRegParameters( ======================================================================== */ +#ifndef RT30xx VOID RTUSBFilterCalibration( IN PRTMP_ADAPTER pAd) { @@ -1206,13 +1220,168 @@ VOID RTUSBFilterCalibration( DBGPRINT(RT_DEBUG_TRACE, ("RTUSBFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24)); } +#endif /* RT30xx */ +#ifdef RT30xx +VOID RTMPFilterCalibration( + IN PRTMP_ADAPTER pAd) +{ + UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0; + UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0; + UCHAR RF_R24_Value = 0; + + // Give bbp filter initial value + pAd->Mlme.CaliBW20RfR24 = 0x1F; + pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40 + + do + { + if (loop == 1) //BandWidth = 40 MHz + { + // Write 0x27 to RF_R24 to program filter + RF_R24_Value = 0x27; + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + if (IS_RT3090(pAd)) + FilterTarget = 0x15; + else + FilterTarget = 0x19; + + // when calibrate BW40, BBP mask must set to BW40. + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue&= (~0x18); + BBPValue|= (0x10); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + + // set to BW40 + RT30xxReadRFRegister(pAd, RF_R31, &value); + value |= 0x20; + RT30xxWriteRFRegister(pAd, RF_R31, value); + } + else //BandWidth = 20 MHz + { + // Write 0x07 to RF_R24 to program filter + RF_R24_Value = 0x07; + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + if (IS_RT3090(pAd)) + FilterTarget = 0x13; + else + FilterTarget = 0x16; + + // set to BW20 + RT30xxReadRFRegister(pAd, RF_R31, &value); + value &= (~0x20); + RT30xxWriteRFRegister(pAd, RF_R31, value); + } + + // Write 0x01 to RF_R22 to enable baseband loopback mode + RT30xxReadRFRegister(pAd, RF_R22, &value); + value |= 0x01; + RT30xxWriteRFRegister(pAd, RF_R22, value); + + // Write 0x00 to BBP_R24 to set power & frequency of passband test tone + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); + + do + { + // Write 0x90 to BBP_R25 to transmit test tone + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); + + RTMPusecDelay(1000); + // Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0] + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); + R55x = value & 0xFF; + + } while ((ReTry++ < 100) && (R55x == 0)); + + // Write 0x06 to BBP_R24 to set power & frequency of stopband test tone + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06); + + while(TRUE) + { + // Write 0x90 to BBP_R25 to transmit test tone + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); + + //We need to wait for calibration + RTMPusecDelay(1000); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); + value &= 0xFF; + if ((R55x - value) < FilterTarget) + { + RF_R24_Value ++; + } + else if ((R55x - value) == FilterTarget) + { + RF_R24_Value ++; + count ++; + } + else + { + break; + } + + // prevent infinite loop cause driver hang. + if (loopcnt++ > 100) + { + DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt)); + break; + } + + // Write RF_R24 to program filter + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + } + + if (count > 0) + { + RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0)); + } + + // Store for future usage + if (loopcnt < 100) + { + if (loop++ == 0) + { + //BandWidth = 20 MHz + pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value; + } + else + { + //BandWidth = 40 MHz + pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value; + break; + } + } + else + break; + + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + + // reset count + count = 0; + } while(TRUE); + + // + // Set back to initial state + // + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); + + RT30xxReadRFRegister(pAd, RF_R22, &value); + value &= ~(0x01); + RT30xxWriteRFRegister(pAd, RF_R22, value); + + // set BBP back to BW20 + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue&= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24)); +} +#endif /* RT30xx */ VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd) { INT i; // Driver must read EEPROM to get RfIcType before initial RF registers // Initialize RF register to default value +#ifndef RT30xx if (IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) ||(pAd->RfIcType == RFIC_2020))) { // Init RF calibration @@ -1234,7 +1403,86 @@ VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd) //For RF filter Calibration RTUSBFilterCalibration(pAd); } +#endif +#ifdef RT30xx + if (IS_RT3070(pAd) || IS_RT3071(pAd)) + { + // Init RF calibration + // Driver should toggle RF R30 bit7 before init RF registers + UINT32 RfReg = 0; + UINT32 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); + + // 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); + } + + // add by johnli + if (IS_RT3070(pAd)) + { + // Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate + RTUSBReadMACRegister(pAd, LDO_CFG0, &data); + data = ((data & 0xF0FFFFFF) | 0x0D000000); + RTUSBWriteMACRegister(pAd, LDO_CFG0, data); + } + else if (IS_RT3071(pAd)) + { + // Driver should set RF R6 bit6 on before init RF registers + RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg); + RfReg |= 0x40; + RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg); + + // init R31 + RT30xxWriteRFRegister(pAd, RF_R31, 0x14); + + // RT3071 version E has fixed this issue + if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) + { + // patch tx EVM issue temporarily + RTUSBReadMACRegister(pAd, LDO_CFG0, &data); + data = ((data & 0xE0FFFFFF) | 0x0D000000); + RTUSBWriteMACRegister(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 + RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data); + data &= ~(0x20); + RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data); + } + + //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 + RTUSBReadMACRegister(pAd, OPT_14, &data); + data |= 0x01; + RTUSBWriteMACRegister(pAd, OPT_14, data); + + if (IS_RT3071(pAd)) + { + // add by johnli, RF power sequence setup, load RF normal operation-mode setup + RT30xxLoadRFNormalModeSetup(pAd); + } + } +#endif } #endif // RT2870 // @@ -1411,11 +1659,25 @@ VOID NICReadEEPROMParameters( Antenna.word = pAd->EEPROMDefaultValue[0]; if (Antenna.word == 0xFFFF) { - Antenna.word = 0; - Antenna.field.RfIcType = RFIC_2820; - Antenna.field.TxPath = 1; - Antenna.field.RxPath = 2; - DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word)); +#ifdef RT30xx + if(IS_RT3090(pAd)) + { + Antenna.word = 0; + Antenna.field.RfIcType = RFIC_3020; + Antenna.field.TxPath = 1; + Antenna.field.RxPath = 1; + } + else + { +#endif // RT30xx // + Antenna.word = 0; + Antenna.field.RfIcType = RFIC_2820; + Antenna.field.TxPath = 1; + Antenna.field.RxPath = 2; + DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word)); +#ifdef RT30xx + } +#endif // RT30xx // } // Choose the desired Tx&Rx stream. @@ -1444,7 +1706,9 @@ VOID NICReadEEPROMParameters( NicConfig2.word = pAd->EEPROMDefaultValue[1]; { +#ifndef RT30xx NicConfig2.word = 0; +#endif if ((NicConfig2.word & 0x00ff) == 0xff) { NicConfig2.word &= 0xff00; @@ -1637,6 +1901,14 @@ VOID NICReadEEPROMParameters( RTMPReadTxPwrPerRate(pAd); +#ifdef RT30xx + if (IS_RT30xx(pAd)) + { + eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value); + pAd->EFuseTag = (value & 0xff); + } +#endif // RT30xx // + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n")); } @@ -1681,16 +1953,49 @@ VOID NICInitAsicFromEEPROM( } } +#ifndef RT30xx Antenna.word = pAd->Antenna.word; +#endif +#ifdef RT30xx + Antenna.word = pAd->EEPROMDefaultValue[0]; + if (Antenna.word == 0xFFFF) + { + DBGPRINT(RT_DEBUG_ERROR, ("E2PROM error, hard code as 0x%04x\n", Antenna.word)); + BUG_ON(Antenna.word == 0xFFFF); + } +#endif pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath; pAd->RfIcType = (UCHAR) Antenna.field.RfIcType; +#ifdef RT30xx + DBGPRINT(RT_DEBUG_WARN, ("pAd->RfIcType = %d, RealRxPath=%d, TxPath = %d\n", pAd->RfIcType, pAd->Mlme.RealRxPath,Antenna.field.TxPath)); + + // Save the antenna for future use + pAd->Antenna.word = Antenna.word; +#endif NicConfig2.word = pAd->EEPROMDefaultValue[1]; +#ifdef RT30xx + { + if ((NicConfig2.word & 0x00ff) == 0xff) + { + NicConfig2.word &= 0xff00; + } + if ((NicConfig2.word >> 8) == 0xff) + { + NicConfig2.word &= 0x00ff; + } + } +#endif // Save the antenna for future use pAd->NicConfig2.word = NicConfig2.word; +#ifdef RT30xx + // set default antenna as main + if (pAd->RfIcType == RFIC_3020) + AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); +#endif // // Send LED Setting to MCU. // @@ -1919,6 +2224,9 @@ NDIS_STATUS NICInitializeAsic( NTSTATUS Status; UCHAR Value = 0xff; #endif // RT2870 // +#ifdef RT30xx + UINT32 eFuseCtrl; +#endif // RT30xx // USHORT KeyIdx; INT i,apidx; @@ -1959,9 +2267,16 @@ NDIS_STATUS NICInitializeAsic( // Initialize MAC register to default value for(Index=0; Index<NUM_MAC_REG_PARMS; Index++) { +#ifdef RT3070 + if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd))) + { + MACRegTable[Index].Value = 0x00000400; + } +#endif // RT3070 // RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value); } +#ifndef RT30xx if(IS_RT3070(pAd)) { // According to Frank Hsu (from Gary Tsao) @@ -1971,7 +2286,7 @@ NDIS_STATUS NICInitializeAsic( RTUSBWriteMACRegister(pAd, TX_SW_CFG1, 0); RTUSBWriteMACRegister(pAd, TX_SW_CFG2, 0); } - +#endif { for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) @@ -1981,6 +2296,36 @@ NDIS_STATUS NICInitializeAsic( } #endif // RT2870 // +#ifdef RT30xx + // Initialize RT3070 serial MAc registers which is different from RT2870 serial + if (IS_RT3090(pAd)) + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); + + // RT3071 version E has fixed this issue + if ((pAd->MACVersion & 0xffff) < 0x0211) + { + if (pAd->NicConfig2.field.DACTestBit == 1) + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically + } + else + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F); // To fix throughput drop drastically + } + } + else + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0); + } + } + else if (IS_RT3070(pAd)) + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically + } +#endif // RT30xx // + // // Before program BBP, we need to wait BBP/RF get wake up. // @@ -2020,6 +2365,7 @@ NDIS_STATUS NICInitializeAsic( RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value); } +#ifndef RT30xx // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. if ((pAd->MACVersion&0xffff) != 0x0101) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19); @@ -2033,7 +2379,55 @@ NDIS_STATUS NICInitializeAsic( RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, 0x05); } #endif // RT2870 // +#endif +#ifdef RT30xx + // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. + // RT3090 should not program BBP R84 to 0x19, otherwise TX will block. + if (((pAd->MACVersion&0xffff) != 0x0101) && (!IS_RT30xx(pAd))) + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19); + +// add by johnli, RF power sequence setup + if (IS_RT30xx(pAd)) + { //update for RT3070/71/72/90/91/92. + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33); + } + + if (IS_RT3090(pAd)) + { + UCHAR bbpreg=0; + // enable DC filter + if ((pAd->MACVersion & 0xffff) >= 0x0211) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0); + } + + // improve power consumption + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg); + if (pAd->Antenna.field.TxPath == 1) + { + // turn off tx DAC_1 + bbpreg = (bbpreg | 0x20); + } + + if (pAd->Antenna.field.RxPath == 1) + { + // turn off tx ADC_1 + bbpreg &= (~0x2); + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg); + + // improve power consumption in RT3071 Ver.E + if ((pAd->MACVersion & 0xffff) >= 0x0211) + { + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg); + bbpreg &= (~0x3); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg); + } + } +#endif if (pAd->MACVersion == 0x28600100) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); @@ -2123,6 +2517,20 @@ NDIS_STATUS NICInitializeAsic( Counter|=0x000001e; RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter); #endif // RT2870 // +#ifdef RT30xx + pAd->bUseEfuse=FALSE; + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl); + pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0; + if(pAd->bUseEfuse) + { + DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse\n")); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n")); + + } +#endif // RT30xx // { // for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT. @@ -2635,19 +3043,18 @@ NDIS_STATUS NICLoadFirmware( ULONG FileLength, Index; //ULONG firm; UINT32 MacReg = 0; -#ifdef RT2870 UINT32 Version = (pAd->MACVersion >> 16); -#endif // RT2870 // pFirmwareImage = FirmwareImage; FileLength = sizeof(FirmwareImage); -#ifdef RT2870 + // New 8k byte firmware size for RT3071/RT3072 //printk("Usb Chip\n"); if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH) //The firmware image consists of two parts. One is the origianl and the other is the new. //Use Second Part { +#ifdef RT2870 if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) { // Use Firmware V2. //printk("KH:Use New Version,part2\n"); @@ -2660,6 +3067,7 @@ NDIS_STATUS NICLoadFirmware( pFirmwareImage = FirmwareImage; FileLength = FIRMWAREIMAGEV1_LENGTH; } +#endif // RT2870 // } else { @@ -2667,8 +3075,6 @@ NDIS_STATUS NICLoadFirmware( Status = NDIS_STATUS_FAILURE; } -#endif // RT2870 // - RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength); /* check if MCU is ready */ @@ -2969,7 +3375,9 @@ VOID UserCfgInit( pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE; } } - +#ifdef RT30xx + pAd->EepromAccess = FALSE; +#endif pAd->Antenna.word = 0; pAd->CommonCfg.BBPCurrentBW = BW_20; |