VOID RT30xxHaltAction( IN PRTMP_ADAPTER pAd) { UINT32 TxPinCfg = 0x00050F0F; // // Turn off LNA_PE or TRSW_POL // if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd) || IS_RT5390(pAd)) { if ((IS_RT3071(pAd) || IS_RT3572(pAd) || IS_RT5390(pAd)) #ifdef RTMP_EFUSE_SUPPORT && (pAd->bUseEfuse) #endif // RTMP_EFUSE_SUPPORT // ) { TxPinCfg &= 0xFFFBF0F0; // bit18 off } else { TxPinCfg &= 0xFFFFF0F0; } RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); } }
/* ======================================================================== Routine Description: Initialize RT35xx. Arguments: pAd - WLAN control block pointer Return Value: None Note: ======================================================================== */ VOID RT30xx_Init( IN PRTMP_ADAPTER pAd) { RTMP_CHIP_OP *pChipOps = &pAd->chipOps; RTMP_CHIP_CAP *pChipCap = &pAd->chipCap; /* init capability */ /* WARNING: Currently following table are shared by all RT30xx based IC, change it carefully when you add a new IC here. */ pChipCap->pRFRegTable = RT3020_RFRegTable; pChipCap->MaxNumOfBbpId = 185; /* init operator */ if((IS_RT3070(pAd) || IS_RT3071(pAd)) || IS_RT3090(pAd)) { #ifdef RT3070 if (pAd->infType == RTMP_DEV_INF_USB) { pChipOps->AsicRfInit = NICInitRT3070RFRegisters; } #endif /* RT3070 */ pChipOps->AsicHaltAction = RT30xxHaltAction; pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup; pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup; pChipOps->ChipSwitchChannel = RT30xx_ChipSwitchChannel; pChipOps->ChipBBPAdjust = RT30xx_ChipBBPAdjust; pChipOps->RTMPSetAGCInitValue = RT30xx_RTMPSetAGCInitValue; /* 1T1R only */ if (!IS_RT3071(pAd)) { pChipOps->SetRxAnt = RT30xxSetRxAnt; pAd->Mlme.bEnableAutoAntennaCheck = FALSE; } pChipOps->ChipResumeMsduTransmission = NULL; pChipOps->VdrTuning1 = NULL; pChipOps->RxSensitivityTuning = NULL; #ifdef RTMP_FREQ_CALIBRATION_SUPPORT pChipOps->AsicFreqCalInit = NULL; pChipOps->AsicFreqCalStop = NULL; pChipOps->AsicFreqCal = NULL; pChipOps->AsicFreqOffsetGet = NULL; #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ } }
VOID RT28xxUsbMlmeRadioOn( IN PRTMP_ADAPTER pAd) { DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n")); if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) return; AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); RTMPusecDelay(10000); NICResetFromError(pAd); RTMPEnableRxTx(pAd); #ifdef RT3070 if (IS_RT3071(pAd)) { RT30xxReverseRFSleepModeSetup(pAd); } #endif RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); RTUSBBulkReceive(pAd); RTMPSetLED(pAd, LED_RADIO_ON); }
VOID RT30xxHaltAction( IN PRTMP_ADAPTER pAd) { UINT32 TxPinCfg = 0x00050F0F; /* Turn off LNA_PE or TRSW_POL*/ if ((IS_RT3071(pAd) || IS_RT3572(pAd)) #ifdef RTMP_EFUSE_SUPPORT && (pAd->bUseEfuse) #endif /* RTMP_EFUSE_SUPPORT */ ) { TxPinCfg &= 0xFFFBF0F0; /* bit18 off */ } else { TxPinCfg &= 0xFFFFF0F0; } #ifdef RT35xx if (IS_RT3572(pAd)) RT30xxWriteRFRegister(pAd, RF_R08, (UCHAR)0x00); #endif /* RT35xx */ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); }
VOID RtmpChipOpsRFHook( IN RTMP_ADAPTER *pAd) { RTMP_CHIP_OP *pChipOps = &pAd->chipOps; pChipOps->pRFRegTable = NULL; pChipOps->pBBPRegTable = NULL; pChipOps->AsicRfInit = NULL; pChipOps->AsicRfTurnOn = NULL; pChipOps->AsicRfTurnOff = NULL; pChipOps->AsicReverseRfFromSleepMode = NULL; pChipOps->AsicHaltAction = NULL; /* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */ #ifdef RT30xx #ifdef RT3593 if (IS_RT3593(pAd)) { pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup; pChipOps->pRFRegTable = RF3053RegTable; pChipOps->AsicRfInit = NICInitRT3593RFRegisters; pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup; pChipOps->AsicHaltAction = RT30xxHaltAction; } #endif // RT3593 // if (IS_RT30xx(pAd)) { /* WARNING: Currently following table are shared by all RT30xx based IC, change it carefully when you add a new IC here. */ pChipOps->pRFRegTable = RT3020_RFRegTable; pChipOps->AsicHaltAction = RT30xxHaltAction; pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup; pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup; #ifdef RT3070 if((IS_RT3070(pAd) || IS_RT3071(pAd)) && (pAd->infType == RTMP_DEV_INF_USB)) { pChipOps->AsicRfInit = NICInitRT3070RFRegisters; } #endif // RT3070 // } #endif // RT30xx // if (pChipOps->pBBPRegTable != NULL) pChipOps->bbpRegTbSize = (sizeof(*(pChipOps->pBBPRegTable)) / sizeof(REG_PAIR)); DBGPRINT(RT_DEBUG_TRACE, ("Chip specific bbpRegTbSize=%d!\n", pChipOps->bbpRegTbSize)); }
void RT30xxHaltAction(struct rt_rtmp_adapter *pAd) { u32 TxPinCfg = 0x00050F0F; /* */ /* Turn off LNA_PE or TRSW_POL */ /* */ if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)) { if ((IS_RT3071(pAd) || IS_RT3572(pAd)) #ifdef RTMP_EFUSE_SUPPORT && (pAd->bUseEfuse) #endif /* RTMP_EFUSE_SUPPORT // */ ) { TxPinCfg &= 0xFFFBF0F0; /* bit18 off */ } else { TxPinCfg &= 0xFFFFF0F0; } RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); } }
void RtmpChipOpsRFHook(struct rt_rtmp_adapter *pAd) { struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; pChipOps->pRFRegTable = NULL; pChipOps->AsicRfInit = NULL; pChipOps->AsicRfTurnOn = NULL; pChipOps->AsicRfTurnOff = NULL; pChipOps->AsicReverseRfFromSleepMode = NULL; pChipOps->AsicHaltAction = NULL; /* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */ #ifdef RT30xx if (IS_RT30xx(pAd)) { pChipOps->pRFRegTable = RT30xx_RFRegTable; pChipOps->AsicHaltAction = RT30xxHaltAction; #ifdef RT3070 if ((IS_RT3070(pAd) || IS_RT3071(pAd)) && (pAd->infType == RTMP_DEV_INF_USB)) { pChipOps->AsicRfInit = NICInitRT3070RFRegisters; if (IS_RT3071(pAd)) { pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup; pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup; } } #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 // */ }
/* ======================================================================== Routine Description: For RF filter calibration purpose Arguments: pAd Pointer to our adapter Return Value: None IRQL = PASSIVE_LEVEL ======================================================================== */ 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 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) return; if (loop == 1) //BandWidth = 40 MHz { // Write 0x27 to RF_R24 to program filter RT30xxReadRFRegister(pAd, RF_R24, (PUCHAR)(&RF_R24_Value)); RF_R24_Value = (RF_R24_Value & 0xC0) | 0x27; // <bit 5>:tx_h20M<bit 5> and <bit 4:0>:tx_agc_fc<bit 4:0> RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); if (IS_RT3071(pAd) || IS_RT3572(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 RT30xxReadRFRegister(pAd, RF_R24, (PUCHAR)(&RF_R24_Value)); RF_R24_Value = (RF_R24_Value & 0xC0) | 0x07; // <bit 5>:tx_h20M<bit 5> and <bit 4:0>:tx_agc_fc<bit 4:0> RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); if (IS_RT3071(pAd) || IS_RT3572(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 { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) return; // 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) { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) return; // 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); // // Check BBP R25 RF Calibration at bit 4. Patch from windows driver // RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R25, &BBPValue); if (BBPValue & 0x10) { // // Clear RF calibration // BBPValue &= (~0x10); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, BBPValue); DBGPRINT(RT_DEBUG_WARN, ("RTMPFilterCalibration, RF calibration should be done\n")); } // 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)); }
VOID NICInitRT3070RFRegisters(IN PRTMP_ADAPTER pAd) { INT i; UCHAR RFValue; /* Driver must read EEPROM to get RfIcType before initial RF registers Initialize RF register to default value */ if (IS_RT3070(pAd) || IS_RT3071(pAd)) { /* Init RF calibration Driver should toggle RF R30 bit7 before init RF registers */ UINT8 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); /* set default antenna as main */ if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020) AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); /* Initialize RF register to default value */ for (i = 0; i < NUM_RF_3020_REG_PARMS; i++) { RT30xxWriteRFRegister(pAd, RT3020_RFRegTable[i].Register, RT3020_RFRegTable[i].Value); } RT30xxWriteRFRegister(pAd, RF_R31, 0x14); /* add by johnli */ if (IS_RT3070(pAd)) { /* The DAC issue(LDO_CFG0) has been fixed in RT3070(F). The voltage raising patch is no longer needed for RT3070(F) */ if ((pAd->MACVersion & 0xffff) < 0x0201) { /* 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); /* 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() TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). Raising RF voltage is no longer needed for RT3070(F) */ if ((IS_RT3070(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0201)) { RT30xxWriteRFRegister(pAd, RF_R27, 0x3); } else if ((IS_RT3071(pAd)) && ((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)) { /* RF power sequence setup, load RF normal operation-mode setup */ RT30xxLoadRFNormalModeSetup(pAd); } else if (IS_RT3070(pAd)) { /* 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->NicConfig2.field.ExternalLNAForG == 0) { if ((IS_RT3071(pAd) && ((pAd->MACVersion & 0xffff) >= 0x0211)) || IS_RT3070(pAd)) { RFValue |= 0x20; } } /* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */ if (pAd->TxMixerGain24G >= 1) { RFValue &= (~0x7); /* clean bit [2:0] */ RFValue |= pAd->TxMixerGain24G; } RT30xxWriteRFRegister(pAd, RF_R17, RFValue); /* add by johnli, reset RF_R27 when interface down & up to fix throughput problem */ /* LDORF_VC, RF R27 register Bit 2 to 0 */ RT30xxReadRFRegister(pAd, RF_R27, &RFValue); /* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). Raising RF voltage is no longer needed for RT3070(F) */ if ((pAd->MACVersion & 0xffff) < 0x0201) RFValue = (RFValue & (~0x77)) | 0x3; else RFValue = (RFValue & (~0x77)); RT30xxWriteRFRegister(pAd, RF_R27, RFValue); /* end johnli */ } } }
VOID AsicGetAutoAgcOffsetForExternalTxAlc( IN PRTMP_ADAPTER pAd, IN PCHAR pDeltaPwr, IN PCHAR pTotalDeltaPwr, IN PCHAR pAgcCompensate, IN PCHAR pDeltaPowerByBbpR1) { BBP_R49_STRUC BbpR49; BOOLEAN bAutoTxAgc = FALSE; UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep, idx; PCHAR pTxAgcCompensate = NULL; CHAR DeltaPwr = 0; DBGPRINT(RT_DEBUG_INFO, ("-->%s\n", __FUNCTION__)); BbpR49.byte = 0; /* TX power compensation for temperature variation based on TSSI. Try every 4 second */ if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) { if (pAd->CommonCfg.Channel <= 14) { /* bg channel */ bAutoTxAgc = pAd->bAutoTxAgcG; TssiRef = pAd->TssiRefG; pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0]; pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0]; TxAgcStep = pAd->TxAgcStepG; pTxAgcCompensate = &pAd->TxAgcCompensateG; } else { /* a channel */ bAutoTxAgc = pAd->bAutoTxAgcA; TssiRef = pAd->TssiRefA; pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0]; pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0]; TxAgcStep = pAd->TxAgcStepA; pTxAgcCompensate = &pAd->TxAgcCompensateA; } if (bAutoTxAgc) { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49.byte); /* TSSI representation */ if (IS_RT3071(pAd) || IS_RT3390(pAd) || IS_RT3090A(pAd) || IS_RT3572(pAd)) /* 5-bits */ { BbpR49.byte = (BbpR49.byte & 0x1F); } /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */ /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */ /* step value is defined in pAd->TxAgcStepG for tx power value */ /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */ /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0 above value are examined in mass factory production */ /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */ /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */ /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */ /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */ if (BbpR49.byte > pTssiMinusBoundary[1]) { /* Reading is larger than the reference value */ /* Check for how large we need to decrease the Tx power */ for (idx = 1; idx < 5; idx++) { if (BbpR49.byte <= pTssiMinusBoundary[idx]) /* Found the range */ break; } /* The index is the step we should decrease, idx = 0 means there is nothing to compensate */ *pTxAgcCompensate = -(TxAgcStep * (idx-1)); DeltaPwr += (*pTxAgcCompensate); DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n", BbpR49.byte, TssiRef, TxAgcStep, idx-1)); } else if (BbpR49.byte < pTssiPlusBoundary[1]) { /* Reading is smaller than the reference value */ /* Check for how large we need to increase the Tx power */ for (idx = 1; idx < 5; idx++) { if (BbpR49.byte >= pTssiPlusBoundary[idx]) /* Found the range*/ break; } /* The index is the step we should increase, idx = 0 means there is nothing to compensate */ *pTxAgcCompensate = TxAgcStep * (idx-1); DeltaPwr += (*pTxAgcCompensate); DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", BbpR49.byte, TssiRef, TxAgcStep, idx-1)); } else { *pTxAgcCompensate = 0; DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", BbpR49.byte, TssiRef, TxAgcStep, 0)); } } } else { if (pAd->CommonCfg.Channel <= 14) { bAutoTxAgc = pAd->bAutoTxAgcG; pTxAgcCompensate = &pAd->TxAgcCompensateG; } else { bAutoTxAgc = pAd->bAutoTxAgcA; pTxAgcCompensate = &pAd->TxAgcCompensateA; } if (bAutoTxAgc) DeltaPwr += (*pTxAgcCompensate); } *pDeltaPwr = DeltaPwr; *pAgcCompensate = *pTxAgcCompensate; DBGPRINT(RT_DEBUG_INFO, ("<--%s\n", __FUNCTION__)); }
VOID NICInitRT3390RFRegisters(IN PRTMP_ADAPTER pAd) { INT i; UINT8 RfReg = 0; UINT32 data; /*CHAR bbpreg;*/ // Driver must read EEPROM to get RfIcType before initial RF registers // Initialize RF register to default value // Init RF calibration // Driver should toggle RF R30 bit7 before init RF registers 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); if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) { 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) | 0x0D000000); RTMP_IO_WRITE32(pAd, LDO_CFG0, data); RTMPusecDelay(1000); data = ((data & 0xE0FFFFFF) | 0x01000000); RTMP_IO_WRITE32(pAd, LDO_CFG0, data); } if (IS_RT3071(pAd) || IS_RT3390(pAd)) { RTMP_IO_READ32(pAd, GPIO_SWITCH, &data); data &= ~(0x20); RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data); // RF registers initialization for (i = 0; i < NUM_RF_3320_REG_PARMS; i++) { RT30xxWriteRFRegister(pAd, RF3320_RFRegTable[i].Register, RF3320_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); if (IS_RT3390(pAd)) // Disable RF filter calibration { // Disable RF filter calibration pAd->Mlme.CaliBW20RfR24 = BW20RFR24; pAd->Mlme.CaliBW40RfR24 = BW40RFR24; pAd->Mlme.CaliBW20RfR31 = BW20RFR31; pAd->Mlme.CaliBW40RfR31 = BW40RFR31; } else { //For RF filter Calibration //RT33xxFilterCalibration(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); // Initialize RT3090 serial MAc registers which is different from RT2860 serial 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); } // set default antenna as main if (pAd->RfIcType == RFIC_3320) AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); /* From RT3071 Power Sequence v1.1 document, the Normal Operation Setting Registers as follow : BBP_R138 / RF_R1 / RF_R15 / RF_R17 / RF_R20 / RF_R21. */ // RF power sequence setup, load RF normal operation-mode setup RT33xxLoadRFNormalModeSetup(pAd); } }
/* ======================================================================== Routine Description: For RF filter calibration purpose Arguments: pAd Pointer to our adapter Return Value: None IRQL = PASSIVE_LEVEL ======================================================================== */ 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->CaliBW20RfR24 = 0x1F; pAd->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*/ RT30xxReadRFRegister(pAd, RF_R24, (PUCHAR)(&RF_R24_Value)); RF_R24_Value = (RF_R24_Value & 0xC0) | 0x27; /* <bit 5>:tx_h20M<bit 5> and <bit 4:0>:tx_agc_fc<bit 4:0>*/ RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); if (IS_RT3071(pAd) || IS_RT3572(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*/ RT30xxReadRFRegister(pAd, RF_R24, (PUCHAR)(&RF_R24_Value)); RF_R24_Value = (RF_R24_Value & 0xC0) | 0x07; /* <bit 5>:tx_h20M<bit 5> and <bit 4:0>:tx_agc_fc<bit 4:0>*/ RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); if (IS_RT3071(pAd) || IS_RT3572(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->CaliBW20RfR24 = (UCHAR)RF_R24_Value; } else { /*BandWidth = 40 MHz*/ pAd->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->CaliBW20RfR24, pAd->CaliBW40RfR24); }
static const struct firmware *rtmp_get_firmware(struct rt_rtmp_adapter *adapter) { const char *name; const struct firmware *fw = NULL; u8 min_version; struct device *dev; int err; if (adapter->firmware) return adapter->firmware; #ifdef RTMP_MAC_USB if (IS_RT3071(adapter)) { name = FIRMWARE_3071_FILENAME; min_version = FIRMWARE_3071_MIN_VERSION; } else if (IS_RT3070(adapter)) { name = FIRMWARE_3070_FILENAME; min_version = FIRMWARE_3070_MIN_VERSION; } else { name = FIRMWARE_2870_FILENAME; min_version = FIRMWARE_2870_MIN_VERSION; } dev = &((struct os_cookie *)adapter->OS_Cookie)->pUsb_Dev->dev; #else /* RTMP_MAC_PCI */ if (IS_RT3090(adapter) || IS_RT3390(adapter)) { name = FIRMWARE_3090_FILENAME; min_version = FIRMWARE_3090_MIN_VERSION; } else { name = FIRMWARE_2860_FILENAME; min_version = FIRMWARE_2860_MIN_VERSION; } dev = &((struct os_cookie *)adapter->OS_Cookie)->pci_dev->dev; #endif err = request_firmware(&fw, name, dev); if (err) { dev_err(dev, "firmware file %s request failed (%d)\n", name, err); return NULL; } if (fw->size < FIRMWAREIMAGE_LENGTH) { dev_err(dev, "firmware file %s size is invalid\n", name); goto invalid; } /* is it new enough? */ adapter->FirmwareVersion = fw->data[FIRMWAREIMAGE_LENGTH - 3]; if (adapter->FirmwareVersion < min_version) { dev_err(dev, "firmware file %s is too old;" " driver requires v%d or later\n", name, min_version); goto invalid; } /* is the internal CRC correct? */ if (crc_ccitt(0xffff, fw->data, FIRMWAREIMAGE_LENGTH - 2) != (fw->data[FIRMWAREIMAGE_LENGTH - 2] | (fw->data[FIRMWAREIMAGE_LENGTH - 1] << 8))) { dev_err(dev, "firmware file %s failed internal CRC\n", name); goto invalid; } adapter->firmware = fw; return fw; invalid: release_firmware(fw); return NULL; }