/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * Taiwan, R.O.C. * * (c) Copyright 2002-2010, Ralink Technology, Inc. * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * *************************************************************************/ #include "rt_config.h" #ifndef RTMP_RF_RW_SUPPORT #error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip" #endif /* RTMP_RF_RW_SUPPORT */ #ifdef RTMP_FLASH_SUPPORT UCHAR RT5390_EeBuffer[EEPROM_SIZE] = { 0x90, 0x53, 0x02, 0x01, 0x00, 0x0c, 0x43, 0x30, 0x92, 0x00, 0x92, 0x30, 0x14, 0x18, 0x01, 0x80, 0x00, 0x00, 0x92, 0x30, 0x14, 0x18, 0x00, 0x00, 0x01, 0x00, 0x6a, 0xff, 0x13, 0x02, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8e, 0x75, 0x01, 0x43, 0x22, 0x08, 0x27, 0x00, 0xff, 0xff, 0x16, 0x01, 0xff, 0xff, 0xd9, 0xfa, 0xcc, 0x88, 0xff, 0xff, 0x0a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1d, 0x1a, 0x15, 0x11, 0x0f, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x88, 0x88, 0xcc, 0xcc, 0xaa, 0x88, 0xcc, 0xcc, 0xaa, 0x88, 0xcc, 0xcc, 0xaa, 0x88, 0xcc, 0xcc, 0xaa, 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; #endif /* RTMP_FLASH_SUPPORT */ REG_PAIR RF5390RegTable[] = { /* {RF_R00, 0x20}, //Read only */ {RF_R01, 0x0F}, {RF_R02, 0x80}, {RF_R03, 0x88}, /* vcocal_double_step */ /* {RF_R04, 0x51}, // Read only */ {RF_R05, 0x10}, {RF_R06, 0xA0}, {RF_R07, 0x00}, /* {RF_R08, 0xF1}, // By channel plan */ /* {RF_R09, 0x02}, // By channel plan */ {RF_R10, 0x53}, {RF_R11, 0x4A}, {RF_R12, 0x46}, {RF_R13, 0x9F}, {RF_R14, 0x00}, {RF_R15, 0x00}, {RF_R16, 0x00}, /* {RF_R17, 0x00}, // Bit 7=0, and based on the frequency offset in the EEPROM */ {RF_R18, 0x03}, {RF_R19, 0x00}, /* Spare */ {RF_R20, 0x00}, {RF_R21, 0x00}, /* Spare */ {RF_R22, 0x20}, {RF_R23, 0x00}, /* Spare */ {RF_R24, 0x00}, /* Spare */ {RF_R25, 0xC0}, {RF_R26, 0x00}, /* Spare */ {RF_R27, 0x09}, {RF_R28, 0x00}, {RF_R29, 0x10}, {RF_R30, 0x10}, {RF_R31, 0x80}, {RF_R32, 0x80}, {RF_R33, 0x00}, /* Spare */ {RF_R34, 0x07}, {RF_R35, 0x12}, {RF_R36, 0x00}, {RF_R37, 0x08}, {RF_R38, 0x85}, {RF_R39, 0x1B}, {RF_R40, 0x0B}, {RF_R41, 0xBB}, {RF_R42, 0xD2}, {RF_R43, 0x9A}, {RF_R44, 0x0E}, {RF_R45, 0xA2}, {RF_R46, 0x7B}, {RF_R47, 0x00}, {RF_R48, 0x10}, {RF_R49, 0x94}, /* {RF_R50, 0x00}, // NC */ /* {RF_R51, 0x00}, // NC */ {RF_R52, 0x38}, {RF_R53, 0x84}, /* RT5370 only. RT5390, RT5370F and RT5390F will re-write to 0x00 */ {RF_R54, 0x78}, {RF_R55, 0x44}, /* Changed by channel */ {RF_R56, 0x22}, {RF_R57, 0x80}, {RF_R58, 0x7F}, {RF_R59, 0x8F}, /* Changed by channel */ {RF_R60, 0x45}, {RF_R61, 0xDD}, {RF_R62, 0x00}, /* Spare */ {RF_R63, 0x00}, /* Spare */ }; /* 5390U (5370 using PCIe interface) */ REG_PAIR RF5390URegTable[] = { /* {RF_R00, 0x20}, // Read only */ {RF_R01, 0x0F}, {RF_R02, 0x80}, {RF_R03, 0x88}, /* vcocal_double_step */ /* {RF_R04, 0x51}, // Read only */ {RF_R05, 0x10}, {RF_R06, 0xE0}, {RF_R07, 0x00}, /* {RF_R08, 0xF1}, // By channel plan */ /* {RF_R09, 0x02}, // By channel plan */ {RF_R10, 0x53}, {RF_R11, 0x4A}, {RF_R12, 0x46}, {RF_R13, 0x9F}, {RF_R14, 0x00}, {RF_R15, 0x00}, {RF_R16, 0x00}, /* {RF_R17, 0x00}, // Based on the frequency offset in the EEPROM */ {RF_R18, 0x03}, {RF_R19, 0x00}, /* Spare */ {RF_R20, 0x00}, {RF_R21, 0x00}, /* Spare */ {RF_R22, 0x20}, {RF_R23, 0x00}, /* Spare */ {RF_R24, 0x00}, /* Spare */ {RF_R25, 0x80}, {RF_R26, 0x00}, /* Spare */ {RF_R27, 0x09}, {RF_R28, 0x00}, {RF_R29, 0x10}, {RF_R30, 0x10}, {RF_R31, 0x80}, {RF_R32, 0x80}, {RF_R33, 0x00}, /* Spare */ {RF_R34, 0x07}, {RF_R35, 0x12}, {RF_R36, 0x00}, {RF_R37, 0x08}, {RF_R38, 0x85}, {RF_R39, 0x1B}, {RF_R40, 0x0B}, {RF_R41, 0xBB}, {RF_R42, 0xD2}, {RF_R43, 0x9A}, {RF_R44, 0x0E}, {RF_R45, 0xA2}, {RF_R46, 0x73}, {RF_R47, 0x00}, {RF_R48, 0x10}, {RF_R49, 0x94}, /* {RF_R50, 0x00}, // NC */ /* {RF_R51, 0x00}, // NC */ {RF_R52, 0x38}, {RF_R53, 0x00}, {RF_R54, 0x78}, {RF_R55, 0x23}, {RF_R56, 0x22}, {RF_R57, 0x80}, {RF_R58, 0x7F}, {RF_R59, 0x07}, {RF_R60, 0x45}, {RF_R61, 0xD1}, {RF_R62, 0x00}, /* Spare */ {RF_R63, 0x00}, /* Spare */ }; REG_PAIR RF5392RegTable[] = { /* {RF_R00, 0x20}, // Read only */ {RF_R01, 0x17}, /* {RF_R02, 0x80}, // Removed since 20111229 update */ {RF_R03, 0x88}, /* vcocal_double_step */ /* {RF_R04, 0x51}, // Read only */ {RF_R05, 0x10}, {RF_R06, 0xE0}, /* 20101018 update */ {RF_R07, 0x00}, /* {RF_R08, 0xF1}, // By channel plan */ /* {RF_R09, 0x02}, // By channel plan */ {RF_R10, 0x53}, {RF_R11, 0x4A}, {RF_R12, 0x46}, {RF_R13, 0x9F}, {RF_R14, 0x00}, {RF_R15, 0x00}, {RF_R16, 0x00}, /* {RF_R17, 0x00}, // Based on the frequency offset in the EEPROM */ {RF_R18, 0x03}, {RF_R19, 0x4D}, /* Spare */ {RF_R20, 0x00}, {RF_R21, 0x8D}, /* Spare 20101018 update. */ {RF_R22, 0x20}, {RF_R23, 0x0B}, /* Spare 20101018 update. */ {RF_R24, 0x44}, /* Spare */ {RF_R25, 0x80}, /* 20101018 update. */ {RF_R26, 0x82}, /* Spare */ {RF_R27, 0x09}, {RF_R28, 0x00}, {RF_R29, 0x10}, {RF_R30, 0x10}, {RF_R31, 0x80}, {RF_R32, 0x20}, {RF_R33, 0xC0}, /* Spare */ {RF_R34, 0x07}, {RF_R35, 0x12}, {RF_R36, 0x00}, {RF_R37, 0x08}, {RF_R38, 0x89}, /* 20101118 update. */ {RF_R39, 0x1B}, {RF_R40, 0x0F}, /* 20101118 update. */ {RF_R41, 0xBB}, {RF_R42, 0xD5}, /* 20101018 update. */ {RF_R43, 0x9B}, /* 20101018 update. */ {RF_R44, 0x0E}, {RF_R45, 0xA2}, {RF_R46, 0x73}, {RF_R47, 0x0C}, {RF_R48, 0x10}, {RF_R49, 0x94}, {RF_R50, 0x94}, /* 5392_todo */ {RF_R51, 0x3A}, /* 20101018 update */ {RF_R52, 0x48}, /* 20101018 update. */ {RF_R53, 0x44}, /* 20101018 update. */ {RF_R54, 0x38}, {RF_R55, 0x43}, {RF_R56, 0xA1}, /* 20101018 update. */ {RF_R57, 0x00}, /* 20101018 update.*/ {RF_R58, 0x39}, {RF_R59, 0x07}, /* 20101018 update. */ {RF_R60, 0x45}, /* 20101018 update.*/ {RF_R61, 0x91}, /* 20101018 update. */ {RF_R62, 0x39}, /* Spare */ {RF_R63, 0x07}, /* Spare */ }; RTMP_REG_PAIR RT5390_MACRegTable[] = { {TX_SW_CFG0, 0x0404}, }; RTMP_REG_PAIR RT5392_MACRegTable[] = { {TX_SW_CFG0, 0x0404}, {MAX_LEN_CFG, 0x2FFF}, {HT_FBK_CFG1, 0xEDCB4980}, {LG_FBK_CFG0, 0xEDCBA322}, }; /* RT5390 RF for OFDM */ const REG_PAIR RF5390Reg_OFDM[] = { {RF_R32, 0x80}, }; /* RT5390 RF for CCK */ const REG_PAIR RF5390Reg_CCK[] = { {RF_R32, 0xC0}, }; /* RT5390/92 RF for BW */ const REG_PAIR_BW RF539xReg_BW[] = { {RF_R30, BW_20, 0x10}, {RF_R30, BW_40, 0x16}, }; /* RT5392 BBP for BW */ const REG_PAIR_BW BBP5392Reg_BW[] = { {BBP_R105, BW_20, 0x3C}, {BBP_R105, BW_40, 0x1C}, }; /* RT5392 RF for OFDM */ const REG_PAIR RF5392Reg_OFDM[] = { {RF_R31, 0x80}, {RF_R32, 0x20}, {RF_R55, 0x43}, }; /* RT5392 RF for CCK */ const REG_PAIR RF5392Reg_CCK[] = { {RF_R31, 0xF8}, {RF_R32, 0xC0}, {RF_R55, 0x47}, }; #define NUM_RF_5390_REG_PARMS (sizeof(RF5390RegTable) / sizeof(REG_PAIR)) #define NUM_RF_5390U_REG_PARMS (sizeof(RF5390URegTable) / sizeof(REG_PAIR)) #define NUM_RF_5392_REG_PARMS (sizeof(RF5392RegTable) / sizeof(REG_PAIR)) UCHAR RT5390_NUM_MAC_REG_PARMS = (sizeof(RT5390_MACRegTable) / sizeof(RTMP_REG_PAIR)); UCHAR RT5392_NUM_MAC_REG_PARMS = (sizeof(RT5392_MACRegTable) / sizeof(RTMP_REG_PAIR)); UCHAR NUM_RF5390Reg_OFDM = (sizeof(RF5390Reg_OFDM) / sizeof(REG_PAIR)); UCHAR NUM_RF5390Reg_CCK = (sizeof(RF5390Reg_CCK) / sizeof(REG_PAIR)); UCHAR NUM_RF539xReg_BW = (sizeof(RF539xReg_BW) / sizeof(REG_PAIR_BW)); UCHAR NUM_RF5392Reg_OFDM = (sizeof(RF5392Reg_OFDM) / sizeof(REG_PAIR)); UCHAR NUM_RF5392Reg_CCK = (sizeof(RF5392Reg_CCK) / sizeof(REG_PAIR)); UCHAR NUM_BBP5392Reg_BW = (sizeof(BBP5392Reg_BW) / sizeof(REG_PAIR_BW)); #if defined(RTMP_INTERNAL_TX_ALC) || defined(RTMP_TEMPERATURE_COMPENSATION) /* The Tx power tuning entry */ TX_POWER_TUNING_ENTRY_STRUCT RT5390_TxPowerTuningTable[] = { /* idxTxPowerTable Tx power control over RF Tx power control over MAC */ /* (zero-based array) { RF R49[5:0]: Tx0 ALC}, {MAC 0x1314~0x1324} */ /* 0 */ {0x00, -15}, /* 1 */ {0x01, -15}, /* 2 */ {0x00, -14}, /* 3 */ {0x01, -14}, /* 4 */ {0x00, -13}, /* 5 */ {0x01, -13}, /* 6 */ {0x00, -12}, /* 7 */ {0x01, -12}, /* 8 */ {0x00, -11}, /* 9 */ {0x01, -11}, /* 10 */ {0x00, -10}, /* 11 */ {0x01, -10}, /* 12 */ {0x00, -9}, /* 13 */ {0x01, -9}, /* 14 */ {0x00, -8}, /* 15 */ {0x01, -8}, /* 16 */ {0x00, -7}, /* 17 */ {0x01, -7}, /* 18 */ {0x00, -6}, /* 19 */ {0x01, -6}, /* 20 */ {0x00, -5}, /* 21 */ {0x01, -5}, /* 22 */ {0x00, -4}, /* 23 */ {0x01, -4}, /* 24 */ {0x00, -3}, /* 25 */ {0x01, -3}, /* 26 */ {0x00, -2}, /* 27 */ {0x01, -2}, /* 28 */ {0x00, -1}, /* 29 */ {0x01, -1}, /* 30 */ {0x00, 0}, /* 31 */ {0x01, 0}, /* 32 */ {0x02, 0}, /* 33 */ {0x03, 0}, /* 34 */ {0x04, 0}, /* 35 */ {0x05, 0}, /* 36 */ {0x06, 0}, /* 37 */ {0x07, 0}, /* 38 */ {0x08, 0}, /* 39 */ {0x09, 0}, /* 40 */ {0x0A, 0}, /* 41 */ {0x0B, 0}, /* 42 */ {0x0C, 0}, /* 43 */ {0x0D, 0}, /* 44 */ {0x0E, 0}, /* 45 */ {0x0F, 0}, /* 46 */ {0x10, 0}, /* 47 */ {0x11, 0}, /* 48 */ {0x12, 0}, /* 49 */ {0x13, 0}, /* 50 */ {0x14, 0}, /* 51 */ {0x15, 0}, /* 52 */ {0x16, 0}, /* 53 */ {0x17, 0}, /* 54 */ {0x18, 0}, /* 55 */ {0x19, 0}, /* 56 */ {0x1A, 0}, /* 57 */ {0x1B, 0}, /* 58 */ {0x1C, 0}, /* 59 */ {0x1D, 0}, /* 60 */ {0x1E, 0}, /* 61 */ {0x1F, 0}, /* 62 */ {0x20, 0}, /* 63 */ {0x21, 0}, /* 64 */ {0x22, 0}, /* 65 */ {0x23, 0}, /* 66 */ {0x24, 0}, /* 67 */ {0x25, 0}, /* 68 */ {0x26, 0}, /* 69 */ {0x27, 0}, /* 70 */ {0x27-1, 1}, /* 71 */ {0x27, 1}, /* 72 */ {0x27-1, 2}, /* 73 */ {0x27, 2}, /* 74 */ {0x27-1, 3}, /* 75 */ {0x27, 3}, /* 76 */ {0x27-1, 4}, /* 77 */ {0x27, 4}, /* 78 */ {0x27-1, 5}, /* 79 */ {0x27, 5}, /* 80 */ {0x27-1, 6}, /* 81 */ {0x27, 6}, /* 82 */ {0x27-1, 7}, /* 83 */ {0x27, 7}, /* 84 */ {0x27-1, 8}, /* 85 */ {0x27, 8}, /* 86 */ {0x27-1, 9}, /* 87 */ {0x27, 9}, /* 88 */ {0x27-1, 10}, /* 89 */ {0x27, 10}, /* 90 */ {0x27-1, 11}, /* 91 */ {0x27, 11}, /* 92 */ {0x27-1, 12}, /* 93 */ {0x27, 12}, /* 94 */ {0x27-1, 13}, /* 95 */ {0x27, 13}, /* 96 */ {0x27-1, 14}, /* 97 */ {0x27, 14}, /* 98 */ {0x27-1, 15}, /* 99 */ {0x27, 15}, }; #ifdef RTMP_INTERNAL_TX_ALC ULONG TssiRatioTable[][2] = { /* {numerator, denominator} Power delta (dBm) Ratio Index */ {955, 10000}, /* -12 0.0955 0 */ {1161, 10000}, /* -11 0.1161 1 */ {1413, 10000}, /* -10 0.1413 2 */ {1718, 10000}, /* -9 0.1718 3 */ {2089, 10000}, /* -8 0.2089 4 */ {2541, 10000}, /* -7 0.2541 5 */ {3090, 10000}, /* -6 0.3090 6 */ {3758, 10000}, /* -5 0.3758 7 */ {4571, 10000}, /* -4 0.4571 8 */ {5559, 10000}, /* -3 0.5559 9 */ {6761, 10000}, /* -2 0.6761 10 */ {8222, 10000}, /* -1 0.8222 11 */ {1, 1}, /* 0 1 12 */ {12162, 10000}, /* 1 1.2162 13 */ {14791, 10000}, /* 2 1.4791 14 */ {17989, 10000}, /* 3 1.7989 15 */ {21878, 10000}, /* 4 2.1878 16 */ {26607, 10000}, /* 5 2.6607 17 */ {32359, 10000}, /* 6 3.2359 18 */ {39355, 10000}, /* 7 3.9355 19 */ {47863, 10000}, /* 8 4.7863 20 */ {58210, 10000}, /* 9 5.8210 21 */ {70795, 10000}, /* 10 7.0795 22 */ {86099, 10000}, /* 11 8.6099 23 */ {104713, 10000}, /* 12 10.4713 24 */ }; /* The desired TSSI over CCK (with extended TSSI information) */ CHAR RT5390_desiredTSSIOverCCKExt[NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET + 1][4]; /* The desired TSSI over OFDM (with extended TSSI information) */ CHAR RT5390_desiredTSSIOverOFDMExt[NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET + 1][8]; /* The desired TSSI over HT (with extended TSSI information) */ CHAR RT5390_desiredTSSIOverHTExt[NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET + 1][8]; /* The desired TSSI over HT40 (with extended TSSI information) */ CHAR RT5390_desiredTSSIOverHT40Ext[NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET + 1][8]; /* The desired TSSI over HT using STBC (with extended TSSI information) */ CHAR RT5390_desiredTSSIOverHTUsingSTBCExt[NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET + 1][8]; #endif /* RTMP_INTERNAL_TX_ALC */ #endif /* RTMP_INTERNAL_TX_ALC || RTMP_TEMPERATURE_COMPENSATION */ /* ======================================================================== Routine Description: Initialize RT5390. Arguments: pAd - WLAN control block pointer Return Value: None Note: ======================================================================== */ VOID RT5390_Init( IN PRTMP_ADAPTER pAd) { RTMP_CHIP_OP *pChipOps = &pAd->chipOps; RTMP_CHIP_CAP *pChipCap = &pAd->chipCap; /* pAd->RfIcType = RFIC_3320; */ /* Init capability */ if (IS_RT5390(pAd)) pChipCap->pRFRegTable = RF5390RegTable; else if (IS_RT5392(pAd)) pChipCap->pRFRegTable = RF5392RegTable; pChipCap->MaxNumOfRfId = 63; pChipCap->MaxNumOfBbpId = 255; pChipCap->pBBPRegTable = NULL; /* The same with BBPRegTable */ pChipCap->bbpRegTbSize = 0; pChipCap->SnrFormula = SNR_FORMULA3; pChipCap->TXWISize = 16; pChipCap->RXWISize = 16; pChipCap->FlgIsHwWapiSup = TRUE; pChipCap->FlgIsVcoReCalMode = VCO_CAL_MODE_2; pChipCap->RfReg17WtMethod = RF_REG_WT_METHOD_STEP_ON; #ifdef RTMP_FLASH_SUPPORT pChipCap->eebuf = RT5390_EeBuffer; #endif /* RTMP_FLASH_SUPPORT */ #ifdef RTMP_EFUSE_SUPPORT pChipCap->EFUSE_USAGE_MAP_START = 0x2d0; pChipCap->EFUSE_USAGE_MAP_END = 0x2fc; if (IS_RT5390R(pAd)) pChipCap->EFUSE_USAGE_MAP_SIZE = 29; else pChipCap->EFUSE_USAGE_MAP_SIZE = 45; DBGPRINT(RT_DEBUG_OFF, ("Efuse Size=0x%x [%x-%x] \n", pAd->chipCap.EFUSE_USAGE_MAP_SIZE, pAd->chipCap.EFUSE_USAGE_MAP_START, pAd->chipCap.EFUSE_USAGE_MAP_END)); #endif /* RTMP_EFUSE_SUPPORT */ #ifdef NEW_MBSSID_MODE pChipCap->MBSSIDMode = MBSSID_MODE1; #else pChipCap->MBSSIDMode = MBSSID_MODE0; #endif /* NEW_MBSSID_MODE */ if (IS_RT5370G(pAd) || IS_RT5390R(pAd)) { DBGPRINT(RT_DEBUG_OFF, ("\x1b[31m%s: FlgIsHwAntennaDiversitySup --> True\x1b[m\n", __FUNCTION__)); pChipCap->FlgIsHwAntennaDiversitySup = TRUE; } else pChipCap->FlgIsHwAntennaDiversitySup = FALSE; /* Init operator */ pChipOps->AsicRfInit = NICInitRT5390RFRegisters; pChipOps->AsicBbpInit = NICInitRT5390BbpRegisters; if (IS_RT5390(pAd)) pChipOps->AsicMacInit = NICInitRT5390MacRegisters; else if (IS_RT5392(pAd)) pChipOps->AsicMacInit = NICInitRT5392MacRegisters; pChipOps->RxSensitivityTuning = RT5390_RxSensitivityTuning; pChipOps->AsicAdjustTxPower = AsicAdjustTxPower; #ifdef CONFIG_STA_SUPPORT pChipOps->ChipAGCAdjust = RT5390_ChipAGCAdjust; #endif /* CONFIG_STA_SUPPORT */ pChipOps->ChipBBPAdjust = RT5390_ChipBBPAdjust; pChipOps->ChipSwitchChannel = RT5390_ChipSwitchChannel; pChipOps->ChipAGCInit = RT5390_ChipAGCInit; pChipOps->AsicGetTxPowerOffset = AsicGetTxPowerOffset; /* 5390/92 have other MAC registers to extra compensate Tx power for OFDM 54, HT MCS 7 and STBC MCS 7 */ pChipOps->AsicExtraPowerOverMAC = RT539x_AsicExtraPowerOverMAC; pChipOps->AsicHaltAction = RT5390HaltAction; pChipOps->AsicRfTurnOff = RT5390LoadRFSleepModeSetup; pChipOps->AsicReverseRfFromSleepMode = RT5390ReverseRFSleepModeSetup; if (IS_RT5392(pAd)) pChipOps->AsicResetBbpAgent = RT5392_AsicResetBBPAgent; else pChipOps->AsicResetBbpAgent = NULL; #ifdef RTMP_INTERNAL_TX_ALC if (IS_RT5390(pAd)) { pChipCap->TxAlcTxPowerUpperBound_2G = 69; pChipCap->TxPowerTuningTable_2G = RT5390_TxPowerTuningTable; pChipOps->InitDesiredTSSITable = RT5390_InitDesiredTSSITable; pChipOps->AsicTxAlcGetAutoAgcOffset = RT5390_AsicTxAlcGetAutoAgcOffset; } #ifdef TSSI_ANTENNA_VARIATION pChipCap->bLimitPowerRange = TRUE; #else pChipCap->bLimitPowerRange = FALSE; #endif /* TSSI_ANTENNA_VARIATION */ #endif /* RTMP_INTERNAL_TX_ALC */ #ifdef RTMP_TEMPERATURE_COMPENSATION if (IS_RT5392(pAd)) { pChipCap->bTempCompTxALC = TRUE; pChipCap->TxAlcTxPowerUpperBound_2G = 69; pChipCap->TxPowerTuningTable_2G = RT5390_TxPowerTuningTable; pChipOps->AsicTxAlcGetAutoAgcOffset = AsicGetAutoAgcOffsetForTemperatureSensor; } #endif /* RTMP_TEMPERATURE_COMPENSATION */ #ifdef IQ_CAL_SUPPORT if (IS_RT5390(pAd)) pChipOps->ChipIQCalibration = IQCalibrationViaBBPAccessSpace; else if (IS_RT5392(pAd)) pChipOps->ChipIQCalibration = IQCalibration; #endif /* IQ_CAL_SUPPORT */ #ifdef RTMP_FREQ_CALIBRATION_SUPPORT #ifdef CONFIG_STA_SUPPORT pChipCap->FreqCalibrationSupport = TRUE, pChipCap->FreqCalInitMode = FREQ_CAL_INIT_MODE2; pChipCap->FreqCalMode = FREQ_CAL_MODE1; pChipCap->RxWIFrqOffset = RXWI_FRQ_OFFSET_FIELD1; #endif /* CONFIG_STA_SUPPORT */ #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ if (IS_RT5390(pAd)) { pChipOps->SetRxAnt = RT5390SetRxAnt; #ifdef TXRX_SW_ANTDIV_SUPPORT pChipCap->bTxRxSwAntDiv = FALSE; #endif /* TXRX_SW_ANTDIV_SUPPORT */ pAd->Mlme.bEnableAutoAntennaCheck = FALSE; } #ifdef CARRIER_DETECTION_SUPPORT pChipCap->carrier_func = TONE_RADAR_V2; pChipOps->ToneRadarProgram = ToneRadarProgram_v2; #endif /* CARRIER_DETECTION_SUPPORT */ RtmpChipBcnSpecInit(pAd); } VOID NICInitRT5390RFRegisters( IN PRTMP_ADAPTER pAd) { INT i; ULONG data; UCHAR RfReg = 0; UINT16 ChipId = 0; UCHAR RFValue = 0; /* The purpose is to identify RT5390H */ RT28xx_EEPROM_READ16(pAd, 0x00, ChipId); pAd->ChipId = ChipId; if (IS_RT5390H(pAd)) DBGPRINT(RT_DEBUG_ERROR, ("The chip belongs to 0x%04x\n", pAd->ChipId)); /* Init RF calibration */ /* Driver should toggle RF R30 bit7 before init RF registers */ if (IS_RT5392(pAd)) { /* RF_R02 toggle mechanism for RT5362/72/92 is to initiate calibration only once */ RT30xxWriteRFRegister(pAd, RF_R02, 0x80); } else { RT30xxReadRFRegister(pAd, RF_R02, (PUCHAR)&RfReg); RfReg = ((RfReg & ~0x80) | 0x80); /* rescal_en (initiate calbration) */ RT30xxWriteRFRegister(pAd, RF_R02, (UCHAR)RfReg); RTMPusecDelay(1000); RfReg = ((RfReg & ~0x80) | 0x00); /* rescal_en (initiate calbration) */ RT30xxWriteRFRegister(pAd, RF_R02, (UCHAR)RfReg); } /* Step 1: Read RF_R17 firstly */ RT30xxReadRFRegister(pAd, RF_R17, (PUCHAR)&RFValue); DBGPRINT(RT_DEBUG_ERROR, ("%s: Initialize frequency - EEPROM = %d, RF_R17 = %d\n", __FUNCTION__, (UCHAR)(pAd->RfFreqOffset & 0x7F), (UCHAR)(RFValue & 0x7F))); /* Step 2: Compare EEPROM FreqOffset and RF_R17 to deside whether to set frequency */ if ((UCHAR)(pAd->RfFreqOffset & 0x7F) != (UCHAR)(RFValue & 0x7F)) { #ifdef RT_SOC_SUPPORT /* Step 2-1: Set high-current if it's a share-Xtal case in APSoC platform */ { /* Disable step-by-step method for RF_R17 */ pAd->chipCap.RfReg17WtMethod = RF_REG_WT_METHOD_NONE; RT30xxWriteRFRegister(pAd, RF_R17, 0x80); RtmpOsMsDelay(1); /* Re-enable step-by-step method for RF_R17 */ pAd->chipCap.RfReg17WtMethod = RF_REG_WT_METHOD_STEP_ON; } #endif /* RT_SOC_SUPPORT */ /* Step 3: Set frequency offset */ RTMPAdjustFrequencyOffset(pAd, (PUCHAR)&pAd->RfFreqOffset); RtmpOsMsDelay(1); } DBGPRINT(RT_DEBUG_TRACE, ("%s: Initialize the RF registers to the default values", __FUNCTION__)); /* Initialize RF register to default value */ if (IS_RT5392(pAd)) { /* Initialize RF register to default value */ for (i = 0; i < NUM_RF_5392_REG_PARMS; i++) { if (IS_RT5392C(pAd)) { #ifdef RTMP_MAC_USB /* For >= RT5372C */ if (RF5392RegTable[i].Register == RF_R23) { RF5392RegTable[i].Value = 0x0F; } else if (RF5392RegTable[i].Register == RF_R24) { RF5392RegTable[i].Value = 0x3E; } else if (RF5392RegTable[i].Register == RF_R51) { RF5392RegTable[i].Value = 0x32; } else if (RF5392RegTable[i].Register == RF_R53) { RF5392RegTable[i].Value = 0x22; } else if (RF5392RegTable[i].Register == RF_R56) { RF5392RegTable[i].Value = 0xC1; } else if (RF5392RegTable[i].Register == RF_R59) { RF5392RegTable[i].Value = 0x0F; } #endif /* RTMP_MAC_USB */ } RT30xxWriteRFRegister(pAd, RF5392RegTable[i].Register, RF5392RegTable[i].Value); } } else if (IS_RT5390U(pAd)) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Initialize the RF registers to the default values (5390U)", __FUNCTION__)); /* Initialize RF register to default value */ for (i = 0; i < NUM_RF_5390U_REG_PARMS; i++) { RT30xxWriteRFRegister(pAd, RF5390URegTable[i].Register, RF5390URegTable[i].Value); } } else if (IS_RT5390(pAd) && !IS_MINI_CARD(pAd)) { /* Initialize RF register to default value */ for (i = 0; i < NUM_RF_5390_REG_PARMS; i++) { #ifdef RTMP_MAC_USB /* For >= RT5370F */ if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R06)) { RF5390RegTable[i].Value = 0xE0; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R25)) { RF5390RegTable[i].Value = 0x80; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R46)) { RF5390RegTable[i].Value = 0x73; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R53)) { RF5390RegTable[i].Value = 0x00; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R56)) { RF5390RegTable[i].Value = 0x42; } else if (IS_RT5390F(pAd) && (RF5390RegTable[i].Register == RF_R61)) { RF5390RegTable[i].Value = 0xD1; } #endif /* RTMP_MAC_USB */ RT30xxWriteRFRegister(pAd, RF5390RegTable[i].Register, RF5390RegTable[i].Value); } } /* Where to add the following codes? RT5390BC8, Disable RF_R40 bit[6] to save power consumption */ if (pAd->NicConfig2.field.CoexBit == TRUE) { RT30xxReadRFRegister(pAd, RF_R40, (PUCHAR)&RfReg); RfReg &= (~0x40); RT30xxWriteRFRegister(pAd, RF_R40, (UCHAR)RfReg); } /* Give bbp filter initial value. Moved here from RTMPFilterCalibration( ) */ pAd->Mlme.CaliBW20RfR24 = 0x1F; pAd->Mlme.CaliBW40RfR24 = 0x2F; /* Bit[5] must be 1 for BW 40 */ /* 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); RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0); /* Set main antenna as the default Rx */ if (IS_RT5390(pAd)) { AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); } /* Patch RSSI inaccurate issue, due to design change */ 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); /* Enable DC filter */ if ((pAd->MACVersion & 0xffff) >= 0x0211) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0); } /* 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 */ RT5390LoadRFNormalModeSetup(pAd); } /* 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 The original name of this function is AsicSetRxAnt(), now changes to this. */ VOID RT5390SetRxAnt( IN PRTMP_ADAPTER pAd, IN UCHAR Ant) { if ((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; } if (IS_RT5390(pAd) ) { UCHAR BbpValue = 0; #ifdef TXRX_SW_ANTDIV_SUPPORT /* EEPROM 34h bit 13 = 1, support SW antenna diverity TX/RX boundle switch */ if (pAd->chipCap.bTxRxSwAntDiv) /* Mini card with TX/RX Diversity (RT5390U) & USB with TX/RX Diversity (RT5370) */ { UINT32 Value; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BbpValue); BbpValue = (BbpValue | 0x80); /* MSB =1 , TX/RX is the same path */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BbpValue); if (Ant == 0) /* 0: Main antenna */ { RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); DBGPRINT(RT_DEBUG_ERROR, ("AsicSetRxTxAnt, before switch to main antenna(%X)\n", Value)); Value &= ~(0x04000808); /* GPIO3 = 0, GIPO10 = 1 */ Value |= (0x00040000); RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); DBGPRINT(RT_DEBUG_ERROR, ("AsicSetRxTxAnt, after switch to main antenna(%X)\n", Value)); } else if (Ant == 1) /* 1: Aux. antenna */ { RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); DBGPRINT(RT_DEBUG_ERROR, ("AsicSetRxTxAnt, before switch to aux antenna(%X)\n", Value)); Value &= ~(0x04040800); /* GPIO3 = 1, GIPO10 = 0 */ Value |= (0x8); RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); DBGPRINT(RT_DEBUG_ERROR, ("AsicSetRxTxAnt, after switch to aux antenna(%X)\n", Value)); } } else #endif /* TXRX_SW_ANTDIV_SUPPORT */ if (pAd->chipCap.FlgIsHwAntennaDiversitySup) /* PPAD support */ { /* For PPAD Debug, BBP R153[7] = 1 --> Main Ant, R153[7] = 0 --> Aux Ant */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R150, 0x00); /* Disable ANTSW_OFDM */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R151, 0x00); /* Disable ANTSW_CCK */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, 0x00); /* Clear R154[4], Rx Ant is not bound to the previous rx packet selected Ant */ if (Ant == 0) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, 0x80); /* Main Ant */ DBGPRINT(RT_DEBUG_OFF, ("\x1b[31m%s: rt5370G/rt5390R --> switch to main\x1b[m\n", __FUNCTION__)); } else { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, 0x00); /* Aux Ant */ DBGPRINT(RT_DEBUG_OFF, ("\x1b[31m%s: rt5370G/rt5390R --> switch to aux\x1b[m\n", __FUNCTION__)); } } else { if (Ant == 0) /* 0: Main antenna */ { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BbpValue); BbpValue = ((BbpValue & ~0x80) | (0x80)); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BbpValue); DBGPRINT(RT_DEBUG_OFF, ("AsicSetRxAnt, switch to main antenna\n")); } else /* 1: Aux. antenna */ { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BbpValue); BbpValue = ((BbpValue & ~0x80) | (0x00)); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BbpValue); DBGPRINT(RT_DEBUG_OFF, ("AsicSetRxAnt, switch to aux. antenna\n")); } } } } /* RF power sequence setup ========================================================================== Description: Load RF normal operation-mode setup ========================================================================== */ VOID RT5390LoadRFNormalModeSetup( IN PRTMP_ADAPTER pAd) { UCHAR RFValue, bbpreg = 0; /* 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); RT30xxReadRFRegister(pAd, RF_R38, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x20) | 0x00); /* rx_lo1_en (enable RX LO1, 0: LO1 follows TR switch) */ RT30xxWriteRFRegister(pAd, RF_R38, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R39, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x80) | 0x00); /* rx_lo2_en (enable RX LO2, 0: LO2 follows TR switch) */ RT30xxWriteRFRegister(pAd, RF_R39, (UCHAR)RFValue); /* Avoid data lost and CRC error */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &bbpreg); bbpreg = ((bbpreg & ~0x40) | 0x40); /* MAC interface control (MAC_IF_80M, 1: 80 MHz) */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, bbpreg); RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x18) | 0x10); /* rxvcm (Rx BB filter VCM) */ RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RFValue); } /* ========================================================================== Description: Load RF sleep-mode setup ========================================================================== */ VOID RT5390LoadRFSleepModeSetup( IN PRTMP_ADAPTER pAd) { UCHAR rfreg; RT30xxReadRFRegister(pAd, RF_R01, &rfreg); rfreg = ((rfreg & ~0x01) | 0x00); /* vco_en */ RT30xxWriteRFRegister(pAd, RF_R01, rfreg); RT30xxReadRFRegister(pAd, RF_R06, &rfreg); rfreg = ((rfreg & ~0xC0) | 0x00); /* vco_ic (VCO bias current control, 00: off) */ RT30xxWriteRFRegister(pAd, RF_R06, rfreg); RT30xxReadRFRegister(pAd, RF_R22, &rfreg); rfreg = ((rfreg & ~0xE0) | 0x00); /* cp_ic (reference current control, 000: 0.25 mA) */ RT30xxWriteRFRegister(pAd, RF_R22, rfreg); RT30xxReadRFRegister(pAd, RF_R42, &rfreg); rfreg = ((rfreg & ~0x40) | 0x00); /* rx_ctb_en */ RT30xxWriteRFRegister(pAd, RF_R42, rfreg); RT30xxReadRFRegister(pAd, RF_R20, &rfreg); rfreg = ((rfreg & ~0x77) | 0x77); /* ldo_pll_vc and ldo_rf_vc (111: -0.15) */ RT30xxWriteRFRegister(pAd, RF_R20, rfreg); /* Don't touch LDO_CFG0 for 3090F & 3593, possibly the board is single power scheme */ } VOID RT5390HaltAction( IN PRTMP_ADAPTER pAd) { UINT32 TxPinCfg = 0x00050F0F; /* Turn off LNA_PE or TRSW_POL */ if ((IS_RT5390(pAd) || IS_RT5392(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); } /* ========================================================================== Description: Reverse RF sleep-mode setup ========================================================================== */ VOID RT5390ReverseRFSleepModeSetup( IN PRTMP_ADAPTER pAd, IN BOOLEAN FlgIsInitState) { UCHAR rfreg; RT30xxReadRFRegister(pAd, RF_R01, &rfreg); if (IS_RT5392(pAd)) { rfreg = ((rfreg & ~0x3F) | 0x3F); } else { rfreg = ((rfreg & ~0x0F) | 0x0F); /* Enable rf_block_en, pll_en, rx0_en and tx0_en */ } RT30xxWriteRFRegister(pAd, RF_R01, rfreg); RT30xxReadRFRegister(pAd, RF_R06, &rfreg); if (IS_RT5390F(pAd) || IS_RT5392C(pAd)) { rfreg = ((rfreg & ~0xC0) | 0xC0); /* vco_ic (VCO bias current control, 11: high) */ } else { rfreg = ((rfreg & ~0xC0) | 0x80); /* vco_ic (VCO bias current control, 10: mid.) */ } RT30xxWriteRFRegister(pAd, RF_R06, rfreg); if (!IS_RT5392(pAd)) { RT30xxReadRFRegister(pAd, RF_R02, &rfreg); rfreg = ((rfreg & ~0x80) | 0x80); /* rescal_en (initiate calibration) */ RT30xxWriteRFRegister(pAd, RF_R02, rfreg); } RT30xxReadRFRegister(pAd, RF_R22, &rfreg); rfreg = ((rfreg & ~0xE0) | 0x20); /* cp_ic (reference current control, 001: 0.33 mA) */ RT30xxWriteRFRegister(pAd, RF_R22, rfreg); RT30xxReadRFRegister(pAd, RF_R42, &rfreg); rfreg = ((rfreg & ~0x40) | 0x40); /* rx_ctb_en */ RT30xxWriteRFRegister(pAd, RF_R42, rfreg); RT30xxReadRFRegister(pAd, RF_R20, &rfreg); rfreg = ((rfreg & ~0x77) | 0x00); /* ldo_rf_vc and ldo_pll_vc ( 111: +0.15) */ RT30xxWriteRFRegister(pAd, RF_R20, rfreg); RT30xxReadRFRegister(pAd, RF_R03, &rfreg); rfreg = ((rfreg & ~0x80) | 0x80); /* vcocal_en (initiate VCO calibration (reset after completion)) */ RT30xxWriteRFRegister(pAd, RF_R03, rfreg); } VOID RT5390_RxSensitivityTuning( IN PRTMP_ADAPTER pAd) { } /* ======================================================================== Routine Description: Initialize specific MAC registers. Arguments: pAd - WLAN control block pointer Return Value: None Note: ======================================================================== */ VOID NICInitRT5390MacRegisters( IN PRTMP_ADAPTER pAd) { UINT32 IdReg; for (IdReg=0; IdReg %s\n", __FUNCTION__)); /* The channel estimation updates based on remodulation of L-SIG and HT-SIG symbols. */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &BBPR105.byte); /* Apply Maximum Likelihood Detection (MLD) for 2 stream case (reserved field if single RX) */ if (pAd->Antenna.field.RxPath == 1) /* Single RX */ BBPR105.field.MLDFor2Stream = 0; else BBPR105.field.MLDFor2Stream = 1; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, BBPR105.byte); DBGPRINT(RT_DEBUG_TRACE, ("%s: BBP_R105: BBPR105.field.EnableSIGRemodulation = %d, BBPR105.field.MLDFor2Stream = %d\n", __FUNCTION__, BBPR105.field.EnableSIGRemodulation, BBPR105.field.MLDFor2Stream)); /* Avoid data lost and CRC error */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpReg); BbpReg = ((BbpReg & ~0x40) | 0x40); /* MAC interface control (MAC_IF_80M, 1: 80 MHz) */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpReg); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, 0x08); /* ADC/DAC contro */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, 0x0B); /* Rx AGC energy lower bound in log2 */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x0D); /* Request by Gary 2012/9/14 */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x06); /* Rx AGC SQ CCK Xcorr threshold */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x13); /* Rx AGC SQ ACorr threshold */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); /* Rx high power VGA offset for LNA offset */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R76, 0x28); /* Rx medium power VGA offset for LNA offset */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R77, 0x59); /* Rx high/medium power threshold in log2 */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); /* Rx AGC LNA select threshold in log2 */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R83, 0x7A); /* Rx AGC LNA MM select threshold in log2 */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x9A); /* Rx AGC VGA/LNA delay */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x38); /* Rx AGC high gain threshold in dB */ if (IS_RT5392(pAd)) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R88, 0x90); /* Request by Gary 2011/11/23 */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R91, 0x04); /* Guard interval delay counter for 20M band */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R92, 0x02); /* Guard interval delay counter for 40M band */ if (IS_RT5392(pAd)) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R95, 0x9A); /* CCK MRC decode */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R98, 0x12); /* TX CCK higher gain */ } RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xC0); /* Rx - 11b adaptive equalizer gear down control and signal energy average period */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R104, 0x92); /* SIGN detection threshold/GF CDD control */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, 0x3C); /* FEQ control */ if (IS_RT5392(pAd)) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R106, 0x12); /* GI remover. For RX peak throughput enhancement. 2011/11/23 */ else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R106, 0x03); /* GI remover */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R128, 0x12); /* R/W remodulation control */ if (IS_RT5392(pAd)) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R134, 0xD0); /* TX CCK higher gain */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R135, 0xF6); /* TX CCK higher gain */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R148, 0x84); /* To enhance RX angle sensitivity */ } { if (pAd->NicConfig2.field.AntOpt == 1) { if (pAd->NicConfig2.field.AntDiversity == 0) /* 0: Main antenna */ { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BbpReg); BbpReg = ((BbpReg & ~0x80) | (0x80)); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BbpReg); DBGPRINT(RT_DEBUG_TRACE, ("%s, switch to main antenna\n", __FUNCTION__)); } else /* 1: Aux. antenna */ { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BbpReg); BbpReg = ((BbpReg & ~0x80) | (0x00)); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BbpReg); DBGPRINT(RT_DEBUG_TRACE, ("%s, switch to aux. antenna\n", __FUNCTION__)); } } else if (pAd->NicConfig2.field.AntDiversity == 0) /* Diversity is Off, set to Main Antenna as default */ { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R152, &BbpReg); BbpReg = ((BbpReg & ~0x80) | (0x80)); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R152, BbpReg); DBGPRINT(RT_DEBUG_TRACE, ("%s, switch to main antenna as default ...... 3\n", __FUNCTION__)); } } if (IS_RT5390(pAd)) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R154, 0x0); /* Disable HW Antenna Diversity (5390/5370 only) */ DBGPRINT(RT_DEBUG_TRACE, ("<-- %s\n", __FUNCTION__)); } #ifdef CONFIG_STA_SUPPORT /* ========================================================================== Description: dynamic tune BBP R66 to find a balance between sensibility and noise isolation IRQL = DISPATCH_LEVEL ========================================================================== */ UCHAR RT5390_ChipAGCAdjust( IN PRTMP_ADAPTER pAd, IN CHAR Rssi, IN UCHAR OrigR66Value) { UCHAR R66 = OrigR66Value; /* R66UpperBound = 0x30, R66LowerBound = 0x30; */ if (pAd->LatchRfRegs.Channel <= 14) /* BG band */ { R66 = 0x1C + 2*GET_LNA_GAIN(pAd); if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) R66 += 0x20; if (OrigR66Value != R66) { AsicBBPWriteWithRxChain(pAd, BBP_R66, R66, RX_CHAIN_ALL); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R83, 0x4A); } } return R66; } #endif /* CONFIG_STA_SUPPORT */ VOID RT5390_ChipBBPAdjust( IN RTMP_ADAPTER *pAd) { UINT32 Value; UCHAR byteValue = 0; #ifdef DOT11_N_SUPPORT if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)) { pAd->CommonCfg.BBPCurrentBW = BW_40; pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; /* TX : control channel at lower */ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); Value &= (~0x1); RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); /* RX : control channel at lower */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &byteValue); byteValue &= (~0x20); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, byteValue); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); byteValue &= (~0x18); byteValue |= 0x10; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); /* Requested by Gary 20070208 for middle and long range A/G Band */ if (pAd->CommonCfg.Channel > 14) AsicBBPWriteWithRxChain(pAd, BBP_R66, 0x48, RX_CHAIN_ALL); else AsicBBPWriteWithRxChain(pAd, BBP_R66, 0x38, RX_CHAIN_ALL); DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : ExtAbove, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d)\n", pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, pAd->CommonCfg.Channel, pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); } else if ((pAd->CommonCfg.Channel > 2) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)) { pAd->CommonCfg.BBPCurrentBW = BW_40; if (pAd->CommonCfg.Channel == 14) pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1; else pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; /* TX : control channel at upper */ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); Value |= (0x1); RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); /* RX : control channel at upper */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &byteValue); byteValue |= (0x20); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, byteValue); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); byteValue &= (~0x18); byteValue |= 0x10; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); /* Requested by Gary 20070208 for middle and long range A/G Band */ if (pAd->CommonCfg.Channel > 14) AsicBBPWriteWithRxChain(pAd, BBP_R66, 0x48, RX_CHAIN_ALL); else AsicBBPWriteWithRxChain(pAd, BBP_R66, 0x38, RX_CHAIN_ALL); DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : ExtBlow, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, pAd->CommonCfg.Channel, pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); } else #endif /* DOT11_N_SUPPORT */ { pAd->CommonCfg.BBPCurrentBW = BW_20; pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; /* TX : control channel at lower */ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); Value &= (~0x1); RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &byteValue); byteValue &= (~0x18); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, byteValue); /* 20 MHz bandwidth */ if (pAd->CommonCfg.Channel > 14) { /* request by Gary 20070208 */ AsicBBPWriteWithRxChain(pAd, BBP_R66, 0x40, RX_CHAIN_ALL); } else { /* Requested by Gary 20070208 */ /* AsicBBPWriteWithRxChain(pAd, BBP_R66, 0x30, RX_CHAIN_ALL); */ /* request by Brian 20070306 */ AsicBBPWriteWithRxChain(pAd, BBP_R66, 0x38, RX_CHAIN_ALL); } #ifdef DOT11_N_SUPPORT DBGPRINT(RT_DEBUG_TRACE, ("ApStartUp : 20MHz, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, pAd->CommonCfg.Channel, pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); #endif /* DOT11_N_SUPPORT */ } /* RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); */ if (pAd->CommonCfg.Channel > 14) { /* Requested by Gary 20070208 for middle and long range A Band */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, 0x1D); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, 0x1D); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, 0x1D); /* RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x1D); */ } else { /* Requested by Gary 20070208 for middle and long range G band */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, 0x2D); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, 0x2D); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, 0x2D); /* RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x2D); */ } } VOID RT5390_ChipSwitchChannel( IN PRTMP_ADAPTER pAd, IN UCHAR Channel, IN BOOLEAN bScan) { UINT i = 0; CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; UCHAR Tx0FinePowerCtrl = 0, Tx1FinePowerCtrl = 0; UCHAR index, RFValue = 0, TxRxh20M = 0; UINT32 Value = 0; /* Search Tx power value. 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; Tx0FinePowerCtrl = pAd->TxPower[index].Tx0FinePowerCtrl; Tx1FinePowerCtrl = pAd->TxPower[index].Tx1FinePowerCtrl; break; } } if (index == MAX_NUM_OF_CHANNELS) { DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel)); } for (index = 0; index < NUM_OF_3020_CHNL; index++) { if (Channel == FreqItems3020[index].Channel) { /* Programming channel parameters */ RT30xxWriteRFRegister(pAd, RF_R08, FreqItems3020[index].N); /* N */ RT30xxWriteRFRegister(pAd, RF_R09, (FreqItems3020[index].K & 0x0F)); /* K, N<11:8> is set to zero */ RT30xxReadRFRegister(pAd, RF_R11, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x03) | (FreqItems3020[index].R & 0x03)); /* R */ RT30xxWriteRFRegister(pAd, RF_R11, (UCHAR)RFValue); RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)&RFValue); RFValue = ((RFValue & ~0x3F) | (TxPwer & 0x3F)); /* tx0_alc */ if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x27 */ { RFValue = ((RFValue & ~0x3F) | 0x27); } RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)RFValue); if (IS_RT5392(pAd)) { RT30xxReadRFRegister(pAd, RF_R50, &RFValue); RFValue = ((RFValue & ~0x3F) | (TxPwer2 & 0x3F)); /* tx0_alc */ if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x27 */ { RFValue = ((RFValue & ~0x3F) | 0x27); } RT30xxWriteRFRegister(pAd, RF_R50, RFValue); } RT30xxReadRFRegister(pAd, RF_R01, (PUCHAR)&RFValue); if (IS_RT5392(pAd)) { RFValue = ((RFValue & ~0x3F) | 0x3F); } else { RFValue = ((RFValue & ~0x0F) | 0x0F); /* Enable rf_block_en, pll_en, rx0_en and tx0_en */ } RT30xxWriteRFRegister(pAd, RF_R01, (UCHAR)RFValue); if (!IS_RT5392(pAd)) { RT30xxReadRFRegister(pAd, RF_R02, (PUCHAR)&RFValue); RFValue |= 0x80; RT30xxWriteRFRegister(pAd, RF_R02, (UCHAR)RFValue); RTMPusecDelay(1000); RFValue &= 0x7F; RT30xxWriteRFRegister(pAd, RF_R02, (UCHAR)RFValue); } #ifdef CONFIG_STA_SUPPORT #ifdef RTMP_FREQ_CALIBRATION_SUPPORT if( (pAd->FreqCalibrationCtrl.bEnableFrequencyCalibration == TRUE) && INFRA_ON(pAd)) { UCHAR RefFreqOffset; RefFreqOffset = pAd->FreqCalibrationCtrl.AdaptiveFreqOffset; RTMPAdjustFrequencyOffset(pAd, &RefFreqOffset); } #endif /* RTMP_FREQ_CALIBRATION_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ if ((!bScan) && (pAd->CommonCfg.BBPCurrentBW == BW_40)) /* BW 40 */ { TxRxh20M = ((pAd->Mlme.CaliBW40RfR24 & 0x20) >> 5); /* Tx/Rx h20M */ } else /* BW 20 */ { TxRxh20M = ((pAd->Mlme.CaliBW20RfR24 & 0x20) >> 5); /* Tx/Rx h20M */ } #ifdef RTMP_MAC_USB if (IS_RT5392(pAd)) /* For RT5372 */ { if (IS_RT5392C(pAd)) /* For >= RT5372C */ { if ((Channel >= 1) && (Channel <= 4)) { RT30xxWriteRFRegister(pAd, RF_R23, 0x0F); } else if ((Channel >= 5) && (Channel <= 7)) { RT30xxWriteRFRegister(pAd, RF_R23, 0x0E); } else if ((Channel >= 8) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R23, 0x0D); } if ((Channel >= 1) && (Channel <= 4)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0C); } else if (Channel == 5) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0B); } else if ((Channel >= 6) && (Channel <= 7)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0A); } else if ((Channel >= 8) && (Channel <= 10)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x09); } else if ((Channel >= 11) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x08); } } else { if ((Channel >= 1) && (Channel <= 11)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0F); } else if ((Channel >= 12) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0B); } } } else if (IS_RT5390U(pAd)) /* For RT5390U */ { if ((Channel >= 1) && (Channel <= 4)) { RT30xxWriteRFRegister(pAd, RF_R55, 0x23); } else if ((Channel >= 5) && (Channel <= 6)) { RT30xxWriteRFRegister(pAd, RF_R55, 0x13); } else if ((Channel >= 7) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R55, 0x03); } if ((Channel >= 1) && (Channel <= 10)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x07); } else if (Channel == 11) { RT30xxWriteRFRegister(pAd, RF_R59, 0x06); } else if (Channel == 12) { RT30xxWriteRFRegister(pAd, RF_R59, 0x05); } else if ((Channel >= 13) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x04); } } else if (IS_RT5390F(pAd) && !IS_MINI_CARD(pAd)) /* For >= RT5370F */ { if ((Channel >= 1) && (Channel <= 11)) { RT30xxWriteRFRegister(pAd, RF_R55, 0x43); } else if ((Channel >= 12) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R55, 0x23); } if ((Channel >= 1) && (Channel <= 11)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0F); } else if (Channel == 12) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0D); } else if ((Channel >= 13) && (Channel <= 14)) { RT30xxWriteRFRegister(pAd, RF_R59, 0x0B); } } else if (IS_RT5390(pAd)) /* For RT5370 */ { RT30xxWriteRFRegister(pAd, RF_R55, 0x44); RT30xxWriteRFRegister(pAd, RF_R59, 0x8F); } else #endif /* RTMP_MAC_USB */ #ifdef RTMP_TEMPERATURE_COMPENSATION if (pAd->chipCap.bTempCompTxALC) { /* Set RF_R27 */ RT30xxReadRFRegister(pAd, RF_R27, &RFValue); /* Set [3:0] to TssiGain */ RFValue = (RFValue & 0xf0); RFValue = (RFValue | pAd->TxPowerCtrl.TssiGain[IEEE80211_BAND_2G]); RT30xxWriteRFRegister(pAd, RF_R27, RFValue); } #endif /* RTMP_TEMPERATURE_COMPENSATION */ RT30xxReadRFRegister(pAd, RF_R03, (PUCHAR)&RFValue); /* vcocal_en (initiate VCO calibration (reset after completion)) - It should be at the end of RF configuration. */ RFValue = ((RFValue & ~0x80) | 0x80); RT30xxWriteRFRegister(pAd, RF_R03, (UCHAR)RFValue); pAd->LatchRfRegs.Channel = Channel; /* Channel latch */ DBGPRINT(RT_DEBUG_TRACE, ("%s: 5390: SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", __FUNCTION__, Channel, pAd->RfIcType, TxPwer, TxPwer2, pAd->Antenna.field.TxPath, FreqItems3020[index].N, FreqItems3020[index].K, FreqItems3020[index].R)); break; } } /* Change BBP setting during siwtch from a->g, g->a */ if (Channel <= 14) { ULONG TxPinCfg = 0x00050F0A; /* Gary 2007/08/09 0x050A0A */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); /* Rx High power VGA offset for LNA select */ if (pAd->NicConfig2.field.ExternalLNAForG) { #ifdef RTMP_MAC_USB RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x52); #else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); #endif /* RTMP_MAC_USB */ } else { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); } /* 5G band selection PIN, bit1 and bit2 are complement */ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); Value &= (~0x6); Value |= (0x04); RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); /* Turn off unused PA or LNA when only 1T or 1R */ if (pAd->Antenna.field.TxPath == 1) { TxPinCfg &= 0xFFFFFFF3; } if (pAd->Antenna.field.RxPath == 1) { TxPinCfg &= 0xFFFFF3FF; } RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); /* PCIe PHY Transmit attenuation adjustment */ if (IS_PCIE_INF(pAd)) { INTERNAL_1_STRUCT Internal_1 = { { 0 } }; RTMP_IO_READ32(pAd, INTERNAL_1, &Internal_1.word); if (Channel == 14) /* Channel #14 */ { Internal_1.field.PCIE_PHY_TX_ATTEN_EN = 1; /* Enable PCIe PHY Tx attenuation */ Internal_1.field.PCIE_PHY_TX_ATTEN_VALUE = 4; /* 9/16 full drive level */ } else /* Channel #1~#13 */ { Internal_1.field.PCIE_PHY_TX_ATTEN_EN = 0; /* Disable PCIe PHY Tx attenuation */ Internal_1.field.PCIE_PHY_TX_ATTEN_VALUE = 0; /* n/a */ } RTMP_IO_WRITE32(pAd, INTERNAL_1, Internal_1.word); } RtmpUpdateFilterCoefficientControl(pAd, Channel); } else { ULONG TxPinCfg = 0x00050F05; /* Gary 2007/8/9 0x050505 */ UINT8 bbpValue; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); /* Set the BBP_R82 value here */ bbpValue = 0xF2; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, bbpValue); /* Rx High power VGA offset for LNA select */ if (pAd->NicConfig2.field.ExternalLNAForA) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); } else { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); } /* 5G band selection PIN, bit1 and bit2 are complement */ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); Value &= (~0x6); Value |= (0x02); RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); /* Turn off unused PA or LNA when only 1T or 1R */ if (pAd->Antenna.field.TxPath == 1) { TxPinCfg &= 0xFFFFFFF3; } if (pAd->Antenna.field.RxPath == 1) { TxPinCfg &= 0xFFFFF3FF; } RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); } if (IS_RT5390(pAd)) { if (pAd->CommonCfg.PhyMode == PHY_11B) { /* RF for CCK */ for (i = 0; i < NUM_RF5390Reg_CCK; i++) RT30xxWriteRFRegister(pAd, RF5390Reg_CCK[i].Register, RF5390Reg_CCK[i].Value); } else { /* RF for OFDM */ for (i = 0; i < NUM_RF5390Reg_OFDM; i++) RT30xxWriteRFRegister(pAd, RF5390Reg_OFDM[i].Register, RF5390Reg_OFDM[i].Value); } } else if (IS_RT5392(pAd)) { if (pAd->CommonCfg.PhyMode == PHY_11B) { /* RF for CCK */ for (i = 0; i < NUM_RF5392Reg_CCK; i++) RT30xxWriteRFRegister(pAd, RF5392Reg_CCK[i].Register, RF5392Reg_CCK[i].Value); } else { /* RF for OFDM */ for (i = 0; i < NUM_RF5392Reg_OFDM; i++) RT30xxWriteRFRegister(pAd, RF5392Reg_OFDM[i].Register, RF5392Reg_OFDM[i].Value); } /* BBP for BW */ for (i = 0; i < NUM_BBP5392Reg_BW; i++) { if (pAd->CommonCfg.BBPCurrentBW == BBP5392Reg_BW[i].BW) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP5392Reg_BW[i].Register, BBP5392Reg_BW[i].Value); } } /* RT5390/92 RF for BW */ for (i = 0; i < NUM_RF539xReg_BW; i++) { if (pAd->CommonCfg.BBPCurrentBW == RF539xReg_BW[i].BW) RT30xxWriteRFRegister(pAd, RF539xReg_BW[i].Register, RF539xReg_BW[i].Value); } if (bScan) { RTMPSetAGCInitValue(pAd, BW_20); } else { RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); } #ifdef IQ_CAL_SUPPORT /* IQ Calibration */ RTMP_CHIP_IQ_CAL(pAd, Channel); #endif /* IQ_CAL_SUPPORT */ /* On 11A, We should delay and wait RF/BBP to be stable and the appropriate time should be 1000 micro seconds 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. */ RTMPusecDelay(1000); } VOID RT539x_AsicExtraPowerOverMAC( IN PRTMP_ADAPTER pAd) { ULONG ExtraPwrOverMAC = 0; ULONG ExtraPwrOverTxPwrCfg7 = 0, ExtraPwrOverTxPwrCfg8 = 0, ExtraPwrOverTxPwrCfg9 = 0; /* For OFDM_54 and HT_MCS_7, extra fill the corresponding register value into MAC 0x13D4 */ RTMP_IO_READ32(pAd, 0x1318, &ExtraPwrOverMAC); ExtraPwrOverTxPwrCfg7 |= (ExtraPwrOverMAC & 0x0000FF00) >> 8; /* Get Tx power for OFDM 54 */ RTMP_IO_READ32(pAd, 0x131C, &ExtraPwrOverMAC); ExtraPwrOverTxPwrCfg7 |= (ExtraPwrOverMAC & 0x0000FF00) << 8; /* Get Tx power for HT MCS 7 */ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_7, ExtraPwrOverTxPwrCfg7); /* For STBC_MCS_7, extra fill the corresponding register value into MAC 0x13DC */ RTMP_IO_READ32(pAd, 0x1324, &ExtraPwrOverMAC); ExtraPwrOverTxPwrCfg9 |= (ExtraPwrOverMAC & 0x0000FF00) >> 8; /* Get Tx power for STBC MCS 7 */ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_9, ExtraPwrOverTxPwrCfg9); if (IS_RT5392(pAd)) { /* For HT_MCS_15, extra fill the corresponding register value into MAC 0x13DC */ RTMP_IO_READ32(pAd, 0x1320, &ExtraPwrOverMAC); ExtraPwrOverTxPwrCfg8 |= (ExtraPwrOverMAC & 0x0000FF00) >> 8; /* Get Tx power for HT MCS 15 */ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_8, ExtraPwrOverTxPwrCfg8); DBGPRINT(RT_DEBUG_TRACE, ("Offset =0x13D8, TxPwr = 0x%08X, ", (UINT)ExtraPwrOverTxPwrCfg8)); } DBGPRINT(RT_DEBUG_TRACE, ("Offset = 0x13D4, TxPwr = 0x%08X, Offset = 0x13DC, TxPwr = 0x%08X\n", (UINT)ExtraPwrOverTxPwrCfg7, (UINT)ExtraPwrOverTxPwrCfg9)); } #ifdef RTMP_INTERNAL_TX_ALC VOID RT5390_InitDesiredTSSITable( IN PRTMP_ADAPTER pAd) { INT i = 0; CHAR DesiredTssi = 0; CHAR BWPowerDelta = 0; UCHAR ch = 0; UCHAR index = 0; UCHAR BbpR47 = 0; UCHAR RFValue = 0; UCHAR TSSIBase = 0; /* The TSSI over OFDM 54Mbps */ USHORT Value = 0; USHORT TxPower = 0, TxPowerOFDM54 = 0; BOOLEAN bExtendedTssiMode = FALSE; EEPROM_TX_PWR_OFFSET_STRUC TxPwrOffset = {{0}}; if (pAd->TxPowerCtrl.bInternalTxALC == FALSE) { return; } DBGPRINT(RT_DEBUG_TRACE, ("---> %s\n", __FUNCTION__)); if (IS_RT5390(pAd)) { RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, Value); if ((Value & 0xFF) == 0xFF) /* 20M/40M BW Power Delta for 2.4GHz band */ { DBGPRINT(RT_DEBUG_TRACE, ("%s: Don't considerate 20M/40M BW Delta Power since EEPROM is not calibrated.\n", __FUNCTION__)); } else { if ((Value & 0xC0) == 0xC0) { BWPowerDelta += (Value & 0x3F); /* Increase 40M BW Tx power with the delta value */ } else if ((Value & 0xC0) == 0x80) { BWPowerDelta -= (Value & 0x3F); /* Decrease 40M BW Tx power with the delta value */ } else DBGPRINT(RT_DEBUG_TRACE, ("%s: 20/40M BW Delta Power is not enabled, Value = 0x%X\n", __FUNCTION__, Value)); } RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_OVER_OFDM_54, Value); TSSIBase = (Value & 0x007F); /* Range: bit6~bit0 */ RT28xx_EEPROM_READ16(pAd, (EEPROM_TSSI_STEP_OVER_2DOT4G - 1), Value); if (((Value >> 8) & 0x80) == 0x80) /* Enable the extended TSSI mode */ { bExtendedTssiMode = TRUE; } else { bExtendedTssiMode = FALSE; } if (bExtendedTssiMode == TRUE) /* Tx power offset for the extended TSSI mode */ { pAd->TxPowerCtrl.bExtendedTssiMode = TRUE; /* Get the per-channel Tx power offset */ RT28xx_EEPROM_READ16(pAd, (EEPROM_TX_POWER_OFFSET_OVER_CH_1 - 1), TxPwrOffset.word); pAd->TxPowerCtrl.PerChTxPwrOffset[1] = (TxPwrOffset.field.Byte1 & 0x0F); /* Tx power offset over channel 1 */ pAd->TxPowerCtrl.PerChTxPwrOffset[2] = (((TxPwrOffset.field.Byte1 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 2 */ RT28xx_EEPROM_READ16(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_3, TxPwrOffset.word); pAd->TxPowerCtrl.PerChTxPwrOffset[3] = (TxPwrOffset.field.Byte0 & 0x0F); /* Tx power offset over channel 3 */ pAd->TxPowerCtrl.PerChTxPwrOffset[4] = (((TxPwrOffset.field.Byte0 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 4 */ pAd->TxPowerCtrl.PerChTxPwrOffset[5] = (TxPwrOffset.field.Byte1 & 0x0F); /* Tx power offset over channel 5 */ pAd->TxPowerCtrl.PerChTxPwrOffset[6] = (((TxPwrOffset.field.Byte1 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 6 */ RT28xx_EEPROM_READ16(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_7, TxPwrOffset.word); pAd->TxPowerCtrl.PerChTxPwrOffset[7] = (TxPwrOffset.field.Byte0 & 0x0F); /* Tx power offset over channel 7 */ pAd->TxPowerCtrl.PerChTxPwrOffset[8] = (((TxPwrOffset.field.Byte0 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 8 */ pAd->TxPowerCtrl.PerChTxPwrOffset[9] = (TxPwrOffset.field.Byte1 & 0x0F); /* Tx power offset over channel 9 */ pAd->TxPowerCtrl.PerChTxPwrOffset[10] = (((TxPwrOffset.field.Byte1 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 10 */ RT28xx_EEPROM_READ16(pAd, EEPROM_TX_POWER_OFFSET_OVER_CH_11, TxPwrOffset.word); pAd->TxPowerCtrl.PerChTxPwrOffset[11] = (TxPwrOffset.field.Byte0 & 0x0F); /* Tx power offset over channel 11 */ pAd->TxPowerCtrl.PerChTxPwrOffset[12] = (((TxPwrOffset.field.Byte0 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 12 */ pAd->TxPowerCtrl.PerChTxPwrOffset[13] = (TxPwrOffset.field.Byte1 & 0x0F); /* Tx power offset over channel 13 */ pAd->TxPowerCtrl.PerChTxPwrOffset[14] = (((TxPwrOffset.field.Byte1 & 0xF0) >> 4) & 0x0F); /* Tx power offset over channel 14 */ /* 4-bit representation ==> 8-bit representation (2's complement) */ for (i = 1; i <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; i++) { if ((pAd->TxPowerCtrl.PerChTxPwrOffset[i] & 0x08) == 0x00) /* Positive number */ { pAd->TxPowerCtrl.PerChTxPwrOffset[i] = (pAd->TxPowerCtrl.PerChTxPwrOffset[i] & ~0xF8); } else /* 0x08: Negative number */ { pAd->TxPowerCtrl.PerChTxPwrOffset[i] = (pAd->TxPowerCtrl.PerChTxPwrOffset[i] | 0xF0); } } DBGPRINT(RT_DEBUG_TRACE, ("%s: TxPwrOffset[1] = %d, TxPwrOffset[2] = %d, TxPwrOffset[3] = %d, TxPwrOffset[4] = %d\n", __FUNCTION__, pAd->TxPowerCtrl.PerChTxPwrOffset[1], pAd->TxPowerCtrl.PerChTxPwrOffset[2], pAd->TxPowerCtrl.PerChTxPwrOffset[3], pAd->TxPowerCtrl.PerChTxPwrOffset[4])); DBGPRINT(RT_DEBUG_TRACE, ("%s: TxPwrOffset[5] = %d, TxPwrOffset[6] = %d, TxPwrOffset[7] = %d, TxPwrOffset[8] = %d\n", __FUNCTION__, pAd->TxPowerCtrl.PerChTxPwrOffset[5], pAd->TxPowerCtrl.PerChTxPwrOffset[6], pAd->TxPowerCtrl.PerChTxPwrOffset[7], pAd->TxPowerCtrl.PerChTxPwrOffset[8])); DBGPRINT(RT_DEBUG_TRACE, ("%s: TxPwrOffset[9] = %d, TxPwrOffset[10] = %d, TxPwrOffset[11] = %d, TxPwrOffset[12] = %d\n", __FUNCTION__, pAd->TxPowerCtrl.PerChTxPwrOffset[9], pAd->TxPowerCtrl.PerChTxPwrOffset[10], pAd->TxPowerCtrl.PerChTxPwrOffset[11], pAd->TxPowerCtrl.PerChTxPwrOffset[12])); DBGPRINT(RT_DEBUG_TRACE, ("%s: TxPwrOffset[13] = %d, TxPwrOffset[14] = %d\n", __FUNCTION__, pAd->TxPowerCtrl.PerChTxPwrOffset[13], pAd->TxPowerCtrl.PerChTxPwrOffset[14])); } else { pAd->TxPowerCtrl.bExtendedTssiMode = FALSE; RTMPZeroMemory(pAd->TxPowerCtrl.PerChTxPwrOffset, sizeof (pAd->TxPowerCtrl.PerChTxPwrOffset)); } RT28xx_EEPROM_READ16(pAd, (EEPROM_OFDM_MCS6_MCS7 - 1), Value); TxPowerOFDM54 = (0x000F & (Value >> 8)); DBGPRINT(RT_DEBUG_TRACE, ("%s: TSSIBase = 0x%X, TxPowerOFDM54 = 0x%X, , bExtendedTssiMode = %d\n", __FUNCTION__, TSSIBase, TxPowerOFDM54, pAd->TxPowerCtrl.bExtendedTssiMode)); /* The desired TSSI over CCK */ DBGPRINT(RT_DEBUG_TRACE, ("%s: ------------------------------------------------------\n", __FUNCTION__)); DBGPRINT(RT_DEBUG_TRACE, ("%s: The desired TSSI over CCK\n", __FUNCTION__)); RT28xx_EEPROM_READ16(pAd, EEPROM_CCK_MCS0_MCS1, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xDE = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + 3 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverCCKExt[ch][MCS_0] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverCCKExt[ch][MCS_1] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_CCK_MCS2_MCS3 - 1), Value); TxPower = ((Value >> 8) & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xDF = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + 3 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverCCKExt[ch][MCS_2] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverCCKExt[ch][MCS_3] = (CHAR)DesiredTssi; } for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, RT5390_desiredTSSIOverCCK[%d][0] = %d, RT5390_desiredTSSIOverCCK[%d][1] = %d, RT5390_desiredTSSIOverCCK[%d][2] = %d, RT5390_desiredTSSIOverCCK[%d][3] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverCCKExt[ch][0], ch, RT5390_desiredTSSIOverCCKExt[ch][1], ch, RT5390_desiredTSSIOverCCKExt[ch][2], ch, RT5390_desiredTSSIOverCCKExt[ch][3])); } /* The desired TSSI over OFDM */ DBGPRINT(RT_DEBUG_TRACE, ("%s: ------------------------------------------------------\n", __FUNCTION__)); DBGPRINT(RT_DEBUG_TRACE, ("%s: The desired TSSI over OFDM\n", __FUNCTION__)); RT28xx_EEPROM_READ16(pAd, EEPROM_OFDM_MCS0_MCS1, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE0 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverOFDMExt[ch][MCS_0] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverOFDMExt[ch][MCS_1] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_OFDM_MCS2_MCS3 - 1), Value); TxPower = ((Value >> 8) & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE1 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverOFDMExt[ch][MCS_2] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverOFDMExt[ch][MCS_3] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, EEPROM_OFDM_MCS4_MCS5, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE2 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverOFDMExt[ch][MCS_4] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverOFDMExt[ch][MCS_5] = (CHAR)DesiredTssi; index = GET_TSSI_RATE_TABLE_INDEX(pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverOFDMExt[ch][MCS_6] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverOFDMExt[ch][MCS_7] =(CHAR) DesiredTssi; } for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverOFDM[%d][0] = %d, desiredTSSIOverOFDM[%d][1] = %d, desiredTSSIOverOFDM[%d][2] = %d, desiredTSSIOverOFDM[%d][3] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverOFDMExt[ch][0], ch, RT5390_desiredTSSIOverOFDMExt[ch][1], ch, RT5390_desiredTSSIOverOFDMExt[ch][2], ch, RT5390_desiredTSSIOverOFDMExt[ch][3])); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverOFDM[%d][4] = %d, desiredTSSIOverOFDM[%d][5] = %d, desiredTSSIOverOFDM[[%d]6] = %d, desiredTSSIOverOFDM[%d][7] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverOFDMExt[ch][4], ch, RT5390_desiredTSSIOverOFDMExt[ch][5], ch, RT5390_desiredTSSIOverOFDMExt[ch][6], ch, RT5390_desiredTSSIOverOFDMExt[ch][7])); } /* The desired TSSI over HT */ DBGPRINT(RT_DEBUG_TRACE, ("%s: ------------------------------------------------------\n", __FUNCTION__)); DBGPRINT(RT_DEBUG_TRACE, ("%s: The desired TSSI over HT\n", __FUNCTION__)); RT28xx_EEPROM_READ16(pAd, EEPROM_HT_MCS0_MCS1, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE4 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET + BWPowerDelta); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverHTExt[ch][MCS_0] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTExt[ch][MCS_1] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_MCS2_MCS3 - 1), Value); TxPower = ((Value >> 8) & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE5 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET + BWPowerDelta); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverHTExt[ch][MCS_2] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTExt[ch][MCS_3] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, EEPROM_HT_MCS4_MCS5, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE6 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET + BWPowerDelta); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverHTExt[ch][MCS_4] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTExt[ch][MCS_5] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_MCS6_MCS7 - 1), Value); TxPower = ((Value >> 8) & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE7 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET + BWPowerDelta); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverHTExt[ch][MCS_6] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTExt[ch][MCS_7] = (CHAR)DesiredTssi; } for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverHT[%d][0] = %d, desiredTSSIOverHT[%d][1] = %d, desiredTSSIOverHT[%d][2] = %d, desiredTSSIOverHT[%d][3] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverHTExt[ch][0], ch, RT5390_desiredTSSIOverHTExt[ch][1], ch, RT5390_desiredTSSIOverHTExt[ch][2], ch, RT5390_desiredTSSIOverHTExt[ch][3])); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverHT[%d][4] = %d, desiredTSSIOverHT[%d][5] = %d, desiredTSSIOverHT[%d][6] = %d, desiredTSSIOverHT[%d][7] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverHTExt[ch][4], ch, RT5390_desiredTSSIOverHTExt[ch][5], ch, RT5390_desiredTSSIOverHTExt[ch][6], ch, RT5390_desiredTSSIOverHTExt[ch][7])); } /* Calcuate the desired TSSI over HT for MCS 5, 6 and 7 in BW40 */ DBGPRINT(RT_DEBUG_TRACE, ("%s: Calculate the desired TSSI over HT for MCS 5, 6 and 7 in BW40\n", __FUNCTION__)); RT28xx_EEPROM_READ16(pAd, EEPROM_HT_MCS4_MCS5, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE6 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] - 1 + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverHT40Ext[ch][MCS_5] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_MCS6_MCS7 - 1), Value); TxPower = ((Value >> 8) & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xE7 = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] - 1 + TSSI_RATIO_TABLE_OFFSET + BWPowerDelta); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverHT40Ext[ch][MCS_6] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHT40Ext[ch][MCS_7] = (CHAR)DesiredTssi; } for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverHT40[%d][0] = %d, desiredTSSIOverHT40[%d][1] = %d, desiredTSSIOverHT40[%d][2] = %d, desiredTSSIOverHT40[%d][3] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverHT40Ext[ch][0], ch, RT5390_desiredTSSIOverHT40Ext[ch][1], ch, RT5390_desiredTSSIOverHT40Ext[ch][2], ch, RT5390_desiredTSSIOverHT40Ext[ch][3])); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverHT40[%d][4] = %d, desiredTSSIOverHT40[%d][5] = %d, desiredTSSIOverHT40[%d][6] = %d, desiredTSSIOverHT40[%d][7] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverHT40Ext[ch][4], ch, RT5390_desiredTSSIOverHT40Ext[ch][5], ch, RT5390_desiredTSSIOverHT40Ext[ch][6], ch, RT5390_desiredTSSIOverHT40Ext[ch][7])); } /* The desired TSSI over HT using STBC */ DBGPRINT(RT_DEBUG_TRACE, ("%s: ------------------------------------------------------\n", __FUNCTION__)); DBGPRINT(RT_DEBUG_TRACE, ("%s: The desired TSSI over HT using STBC\n", __FUNCTION__)); RT28xx_EEPROM_READ16(pAd, EEPROM_HT_USING_STBC_MCS0_MCS1, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xEC = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_0] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_1] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_USING_STBC_MCS2_MCS3 - 1), Value); TxPower = ((Value >> 8) & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xED = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s:ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_2] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_3] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, EEPROM_HT_USING_STBC_MCS4_MCS5, Value); TxPower = (Value & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xEE = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_4] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_5] = (CHAR)DesiredTssi; } RT28xx_EEPROM_READ16(pAd, (EEPROM_HT_USING_STBC_MCS6_MCS7 - 1), Value); TxPower = ((Value >> 8) & 0x000F); DBGPRINT(RT_DEBUG_TRACE, ("%s: eFuse 0xEF = 0x%X\n", __FUNCTION__, TxPower)); for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { index = GET_TSSI_RATE_TABLE_INDEX(TxPower - TxPowerOFDM54 + pAd->TxPowerCtrl.PerChTxPwrOffset[ch] + TSSI_RATIO_TABLE_OFFSET); DesiredTssi = (SHORT)Rounding(pAd, (TSSIBase * TssiRatioTable[index][0] / TssiRatioTable[index][1]), (TSSIBase * TssiRatioTable[index][0] % TssiRatioTable[index][1]), TssiRatioTable[index][1]); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, index = %d, DesiredTssi = 0x%02X\n", __FUNCTION__, ch, index, DesiredTssi)); /* Boundary verification: the desired TSSI value */ if (DesiredTssi < 0x00) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x00; } else if (DesiredTssi > 0x7C) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Out of range, DesiredTssi = 0x%02X\n", __FUNCTION__, DesiredTssi)); DesiredTssi = 0x7C; } RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_6] = (CHAR)DesiredTssi; RT5390_desiredTSSIOverHTUsingSTBCExt[ch][MCS_7] = (CHAR)DesiredTssi; } for (ch = 1; ch <= NUM_OF_CH_FOR_PER_CH_TX_PWR_OFFSET; ch++) { DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverHTUsingSTBC[%d][0] = %d, desiredTSSIOverHTUsingSTBC[%d][1] = %d, desiredTSSIOverHTUsingSTBC[%d][2] = %d, desiredTSSIOverHTUsingSTBC[%d][3] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][0], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][1], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][2], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][3])); DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, desiredTSSIOverHTUsingSTBC[%d][4] = %d, desiredTSSIOverHTUsingSTBC[%d][5] = %d, desiredTSSIOverHTUsingSTBC[%d][6] = %d, desiredTSSIOverHTUsingSTBC[%d][7] = %d\n", __FUNCTION__, ch, ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][4], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][5], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][6], ch, RT5390_desiredTSSIOverHTUsingSTBCExt[ch][7])); } /* 5390 RF TSSI configuraiton */ RT30xxReadRFRegister(pAd, RF_R28, (PUCHAR)(&RFValue)); RFValue = 0; RT30xxWriteRFRegister(pAd, RF_R28, RFValue); RT30xxReadRFRegister(pAd, RF_R29, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x03) | 0x00); RT30xxWriteRFRegister(pAd, RF_R29, RFValue); RT30xxReadRFRegister(pAd, RF_R27, (PUCHAR)(&RFValue)); RFValue = (RFValue & ~0xFC); /* [7:4] = 0, [3:2] = 0 */ RFValue = (RFValue | 0x03); /* [1:0] = 0x03 (tssi_gain = 12dB) */ RT30xxWriteRFRegister(pAd, RF_R27, RFValue); RT28xx_EEPROM_READ16(pAd, EEPROM_TSSI_GAIN_AND_ATTENUATION,Value); Value = (Value & 0x00FF); DBGPRINT(RT_DEBUG_TRACE, ("%s: EEPROM_TSSI_GAIN_AND_ATTENUATION = 0x%X\n", __FUNCTION__, Value)); if ((Value != 0x00) && (Value != 0xFF)) { RT30xxReadRFRegister(pAd, RF_R27, (PUCHAR)(&RFValue)); Value = (Value & 0x000F); RFValue = ((RFValue & 0xF0) | Value); /* [3:0] = (tssi_gain and tssi_atten) */ RT30xxWriteRFRegister(pAd, RF_R27, RFValue); } /* 5390 BBP TSSI configuration */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x80) | 0x80); /* ADC6 on */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x18) | 0x10); /* TSSI_MODE (new averaged TSSI mode for 3290/5390) */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x07) | 0x04); /* TSSI_REPORT_SEL (TSSI INFO 0 - TSSI) and enable TSSI INFO udpate */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); } DBGPRINT(RT_DEBUG_TRACE, ("<--- %s\n", __FUNCTION__)); } VOID RT5390_AsicTxAlcGetAutoAgcOffset( IN PRTMP_ADAPTER pAd, IN PCHAR pDeltaPwr, IN PCHAR pTotalDeltaPwr, IN PCHAR pAgcCompensate, IN PCHAR pDeltaPowerByBbpR1) { const TX_POWER_TUNING_ENTRY_STRUCT *TxPowerTuningTable = pAd->chipCap.TxPowerTuningTable_2G; PTX_POWER_TUNING_ENTRY_STRUCT pTxPowerTuningEntry = NULL; UCHAR RFValue = 0; CHAR desiredTssi = 0; CHAR currentTssi = 0; CHAR TotalDeltaPower = 0; CHAR TuningTableIndex = 0; CHAR TX0_DAC = 0; RTMP_CHIP_CAP *pChipCap = &pAd->chipCap; /* Locate the Internal Tx ALC tuning entry */ if ((pAd->TxPowerCtrl.bInternalTxALC == TRUE) && (IS_RT5390(pAd))) { if ((pAd->Mlme.OneSecPeriodicRound % 4 == 0) && (*pDeltaPowerByBbpR1 == 0)) { if (GetDesiredTssiAndCurrentTssi(pAd, &desiredTssi, ¤tTssi) == FALSE) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect desired TSSI or current TSSI\n", __FUNCTION__)); /* Tx power adjustment over RF */ RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x3F) | pAd->TxPowerCtrl.RF_TX_ALC); if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x27 */ { RFValue = ((RFValue & ~0x3F) | 0x27); } RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)(RFValue)); /* Tx power adjustment over MAC */ TotalDeltaPower += pAd->TxPowerCtrl.MAC_PowerDelta; } else { #ifdef DOT11_N_SUPPORT TX0_DAC = pAd->TxPower[pAd->CommonCfg.CentralChannel-1].Power; #else TX0_DAC = pAd->TxPower[pAd->CommonCfg.Channel-1].Power; #endif /* DOT11_N_SUPPORT */ if (pChipCap->bLimitPowerRange == FALSE) { if (desiredTssi > currentTssi) { pAd->TxPowerCtrl.idxTxPowerTable++; } if (desiredTssi < currentTssi) { pAd->TxPowerCtrl.idxTxPowerTable--; } } else /* Enable the limit power compensation range */ { if ((desiredTssi > currentTssi) && (pAd->TxPowerCtrl.idxTxPowerTable < 4)) { pAd->TxPowerCtrl.idxTxPowerTable++; } if (desiredTssi < currentTssi) /* No compensation limitation on negative side */ { pAd->TxPowerCtrl.idxTxPowerTable--; } DBGPRINT(RT_DEBUG_TRACE, ("Tssi antenna variation: idxTxPowerTable=%d\n", pAd->TxPowerCtrl.idxTxPowerTable)); } TuningTableIndex = pAd->TxPowerCtrl.idxTxPowerTable + TX0_DAC; TuningTableIndex = (TuningTableIndex < LOWERBOUND_TX_POWER_TUNING_ENTRY) ? LOWERBOUND_TX_POWER_TUNING_ENTRY : TuningTableIndex; TuningTableIndex = (TuningTableIndex > UPPERBOUND_TX_POWER_TUNING_ENTRY(pAd)) ? UPPERBOUND_TX_POWER_TUNING_ENTRY(pAd) : TuningTableIndex; /* Valide pAd->TxPowerCtrl.idxTxPowerTable: -30 ~ 69 */ pTxPowerTuningEntry = &TxPowerTuningTable[TuningTableIndex + TX_POWER_TUNING_ENTRY_OFFSET ]; pAd->TxPowerCtrl.RF_TX_ALC = pTxPowerTuningEntry->RF_TX_ALC; pAd->TxPowerCtrl.MAC_PowerDelta = pTxPowerTuningEntry->MAC_PowerDelta; /* Tx power adjustment over RF */ RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x3F) | pAd->TxPowerCtrl.RF_TX_ALC); if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x1F */ { RFValue = ((RFValue & ~0x3F) | 0x27); } RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)(RFValue)); /* Tx power adjustment over MAC */ TotalDeltaPower += pAd->TxPowerCtrl.MAC_PowerDelta; DBGPRINT(RT_DEBUG_TRACE, ("%s: desiredTSSI = %d, currentTSSI = %d, idxTxPowerTable = %d, TuningTableIndex = %d, {RF_TX_ALC = 0x%X, MAC_PowerDelta = %d}\n", __FUNCTION__, desiredTssi, currentTssi, pAd->TxPowerCtrl.idxTxPowerTable, TuningTableIndex, pTxPowerTuningEntry->RF_TX_ALC, pTxPowerTuningEntry->MAC_PowerDelta)); } } else { /* Tx power adjustment over RF */ RT30xxReadRFRegister(pAd, RF_R49, (PUCHAR)(&RFValue)); RFValue = ((RFValue & ~0x3F) | pAd->TxPowerCtrl.RF_TX_ALC); if ((RFValue & 0x3F) > 0x27) /* The valid range of the RF R49 (<5:0>tx0_alc<5:0>) is 0x00~0x1F */ { RFValue = ((RFValue & ~0x3F) | 0x27); } RT30xxWriteRFRegister(pAd, RF_R49, (UCHAR)(RFValue)); /* Tx power adjustment over MAC */ TotalDeltaPower += pAd->TxPowerCtrl.MAC_PowerDelta; } } *pTotalDeltaPwr = TotalDeltaPower; } /* Rounding to integer e.g., +16.9 ~= 17 and -16.9 ~= -17 Parameters pAd: The adapter data structure Integer: Integer part Fraction: Fraction part DenominatorOfTssiRatio: The denominator of the TSSI ratio Return Value: Rounding result */ LONG Rounding( IN PRTMP_ADAPTER pAd, IN LONG Integer, IN LONG Fraction, IN LONG DenominatorOfTssiRatio) { LONG temp = 0; DBGPRINT(RT_DEBUG_INFO, ("%s: Integer = %d, Fraction = %d, DenominatorOfTssiRatio = %d\n", __FUNCTION__, (INT)Integer, (INT)Fraction, (INT)DenominatorOfTssiRatio)); if (Fraction >= 0) { if (Fraction < (DenominatorOfTssiRatio / 10)) { return Integer; /* e.g., 32.08059 ~= 32 */ } } else { if (-Fraction < (DenominatorOfTssiRatio / 10)) { return Integer; /* e.g., -32.08059 ~= -32 */ } } if (Integer >= 0) { if (Fraction == 0) { return Integer; } else { do { /* Coverity found the condition (Fration ==0) will not be executed, after line 3378. */ { temp = Fraction / 10; if (temp == 0) { break; } else { Fraction = temp; } } } while (1); DBGPRINT(RT_DEBUG_INFO, ("%s: [+] temp = %d, Fraction = %d\n", __FUNCTION__, (INT)temp, (INT)Fraction)); if (Fraction >= 5) { return (Integer + 1); } else { return Integer; } } } else { if (Fraction == 0) { return Integer; } else { do { if (Fraction == 0) { break; } else { temp = Fraction / 10; if (temp == 0) { break; } else { Fraction = temp; } } } while (1); DBGPRINT(RT_DEBUG_INFO, ("%s: [-] temp = %d, Fraction = %d\n", __FUNCTION__, (INT)temp, (INT)Fraction)); if (Fraction <= -5) { return (Integer - 1); } else { return Integer; } } } } /* Get the desired TSSI based on the latest packet Parameters pAd: The adapter data structure pDesiredTssi: The desired TSSI pCurrentTssi: The current TSSI/ Return Value: Success or failure */ BOOLEAN GetDesiredTssiAndCurrentTssi( IN PRTMP_ADAPTER pAd, INOUT PCHAR pDesiredTssi, INOUT PCHAR pCurrentTssi) { UCHAR BbpR47 = 0; UCHAR RateInfo = 0; CCK_TSSI_INFO cckTssiInfo = {{0}}; OFDM_TSSI_INFO ofdmTssiInfo = {{0}}; HT_TSSI_INFO htTssiInfo = { .PartA.value= 0, .PartB.value = 0, }; UCHAR ch=0; DBGPRINT(RT_DEBUG_INFO, ("---> %s\n", __FUNCTION__)); if (IS_RT5390(pAd)) { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); if ((BbpR47 & 0x04) == 0x04) /* The TSSI INFO is not ready. */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: BBP TSSI INFO is not ready. (BbpR47 = 0x%X)\n", __FUNCTION__, BbpR47)); return FALSE; } /* Get TSSI */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, (PUCHAR)(pCurrentTssi)); if ((*pCurrentTssi < 0) || (*pCurrentTssi > 0x7C)) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Out of range, *pCurrentTssi = %d\n", __FUNCTION__, *pCurrentTssi)); *pCurrentTssi = 0; } DBGPRINT(RT_DEBUG_TRACE, ("%s: *pCurrentTssi = %d\n", __FUNCTION__, *pCurrentTssi)); /* Get packet information */ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x03) | 0x01); /* TSSI_REPORT_SEL (TSSI INFO 1 - Packet infomation) */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, (PUCHAR)(&RateInfo)); if ((RateInfo & 0x03) == MODE_CCK) /* CCK */ { cckTssiInfo.value = RateInfo; DBGPRINT(RT_DEBUG_TRACE, ("%s: CCK, cckTssiInfo.field.Rate = %d\n", __FUNCTION__, cckTssiInfo.field.Rate)); DBGPRINT(RT_DEBUG_INFO, ("%s: RateInfo = 0x%X\n", __FUNCTION__, RateInfo)); if (cckTssiInfo.field.Rate >= 4) /* boundary verification */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: cckTssiInfo.field.Rate = %d\n", __FUNCTION__, cckTssiInfo.field.Rate)); return FALSE; } if ((pAd->CommonCfg.CentralChannel >= 1) && (pAd->CommonCfg.CentralChannel <= 14)) { ch = pAd->CommonCfg.CentralChannel; } else { ch = 1; DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect channel #%d\n", __FUNCTION__, pAd->CommonCfg.CentralChannel)); } *pDesiredTssi = RT5390_desiredTSSIOverCCKExt[ch][cckTssiInfo.field.Rate]; DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, *pDesiredTssi = %d\n", __FUNCTION__, ch, *pDesiredTssi)); } else if ((RateInfo & 0x03) == MODE_OFDM) /* OFDM */ { ofdmTssiInfo.value = RateInfo; /* BBP OFDM rate format ==> MAC OFDM rate format */ switch (ofdmTssiInfo.field.Rate) { case 0x0B: /* 6 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_0; } break; case 0x0F: /* 9 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_1; } break; case 0x0A: /* 12 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_2; } break; case 0x0E: /* 18 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_3; } break; case 0x09: /* 24 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_4; } break; case 0x0D: /* 36 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_5; } break; case 0x08: /* 48 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_6; } break; case 0x0C: /* 54 Mbits/s */ { ofdmTssiInfo.field.Rate = MCS_7; } break; default: { DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect OFDM rate = 0x%X\n", __FUNCTION__, ofdmTssiInfo.field.Rate)); return FALSE; } break; } DBGPRINT(RT_DEBUG_TRACE, ("%s: OFDM, ofdmTssiInfo.field.Rate = %d\n", __FUNCTION__, ofdmTssiInfo.field.Rate)); if (ofdmTssiInfo.field.Rate > 7) /* boundary verification */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: ofdmTssiInfo.field.Rate = %d\n", __FUNCTION__, ofdmTssiInfo.field.Rate)); return FALSE; } if ((pAd->CommonCfg.CentralChannel >= 1) && (pAd->CommonCfg.CentralChannel <= 14)) { ch = pAd->CommonCfg.CentralChannel; } else { ch = 1; DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect channel #%d\n", __FUNCTION__, pAd->CommonCfg.CentralChannel)); } *pDesiredTssi = RT5390_desiredTSSIOverOFDMExt[ch][ofdmTssiInfo.field.Rate]; DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, *pDesiredTssi = %d\n", __FUNCTION__, ch, *pDesiredTssi)); DBGPRINT(RT_DEBUG_INFO, ("%s: RateInfo = 0x%X\n", __FUNCTION__, RateInfo)); } else /* Mixed mode or green-field mode */ { htTssiInfo.PartA.value = RateInfo; DBGPRINT(RT_DEBUG_INFO, ("%s: RateInfo = 0x%X\n", __FUNCTION__, RateInfo)); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x03) | 0x02); /* TSSI_REPORT_SEL (TSSI INFO 2 - Packet infomation) */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, 0x92); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, (PUCHAR)(&RateInfo)); htTssiInfo.PartB.value = RateInfo; DBGPRINT(RT_DEBUG_INFO, ("%s: RateInfo = 0x%X\n", __FUNCTION__, RateInfo)); DBGPRINT(RT_DEBUG_TRACE, ("%s: HT, htTssiInfo.PartA.field.STBC = %d, htTssiInfo.PartB.field.MCS = %d\n", __FUNCTION__, htTssiInfo.PartA.field.STBC, htTssiInfo.PartB.field.MCS)); if ((htTssiInfo.PartB.field.MCS < 0) || (htTssiInfo.PartB.field.MCS > 7)) /* boundary verification */ { DBGPRINT(RT_DEBUG_ERROR, ("%s: incorrect MCS: htTssiInfo.PartB.field.MCS = %d\n", __FUNCTION__, htTssiInfo.PartB.field.MCS)); return FALSE; } if ((pAd->CommonCfg.CentralChannel >= 1) && (pAd->CommonCfg.CentralChannel <= 14)) { ch = pAd->CommonCfg.CentralChannel; } else { ch = 1; DBGPRINT(RT_DEBUG_ERROR, ("%s: Incorrect channel #%d\n", __FUNCTION__, pAd->CommonCfg.CentralChannel)); } if (htTssiInfo.PartA.field.STBC == 0) { if ((htTssiInfo.PartB.field.BW == BW_40) && ((htTssiInfo.PartB.field.MCS == MCS_5) || (htTssiInfo.PartB.field.MCS == MCS_6) || (htTssiInfo.PartB.field.MCS == MCS_7))) { *pDesiredTssi = RT5390_desiredTSSIOverHT40Ext[ch][htTssiInfo.PartB.field.MCS]; } else { *pDesiredTssi = RT5390_desiredTSSIOverHTExt[ch][htTssiInfo.PartB.field.MCS]; } } else { *pDesiredTssi = RT5390_desiredTSSIOverHTUsingSTBCExt[ch][htTssiInfo.PartB.field.MCS]; } DBGPRINT(RT_DEBUG_TRACE, ("%s: ch = %d, *pDesiredTssi = %d\n", __FUNCTION__, ch, *pDesiredTssi)); } if (*pDesiredTssi < 0x00) { *pDesiredTssi = 0x00; } else if (*pDesiredTssi > 0x7C) { *pDesiredTssi = 0x7C; } RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R47, &BbpR47); BbpR47 = ((BbpR47 & ~0x07) | 0x04); /* TSSI_REPORT_SEL (TSSI INFO 0 - TSSI) and enable TSSI INFO udpate */ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R47, BbpR47); } DBGPRINT(RT_DEBUG_INFO, ("<--- %s\n", __FUNCTION__)); return TRUE; } #endif /* RTMP_INTERNAL_TX_ALC */ VOID RT5390_ChipAGCInit( IN PRTMP_ADAPTER pAd, IN UCHAR BandWidth) { UCHAR R66 = 0x30; if (pAd->LatchRfRegs.Channel <= 14) /* BG band */ { /* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */ R66 = 0x1C + 2*GET_LNA_GAIN(pAd); AsicBBPWriteWithRxChain(pAd, BBP_R66, R66, RX_CHAIN_ALL); /* 20100902 update for Rx Sensitive */ if (IS_RT5392(pAd)) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R135 ,0xF6); } else /* A band */ { if (BandWidth == BW_20) R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3); #ifdef DOT11_N_SUPPORT else R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3); #endif /* DOT11_N_SUPPORT */ AsicBBPWriteWithRxChain(pAd, BBP_R66, R66, RX_CHAIN_ALL); } } VOID NICStoreBBPValue( IN PRTMP_ADAPTER pAd, IN REG_PAIR *RegPair) { UCHAR BBPIndex = 0, BBPValue = 0; INT32 i = 0; /* BBP R1 ~ R4 */ for (BBPIndex = BBP_R1; BBPIndex <= BBP_R4; BBPIndex++) { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; } /* BBP R31 */ BBPIndex = BBP_R31; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; /* BBP R47 */ BBPIndex = BBP_R47; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; /* BBP R53 */ BBPIndex = BBP_R53; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; /* BBP R62~R92 */ for (BBPIndex = BBP_R62; BBPIndex <= BBP_R92; BBPIndex++) { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; } /* BBP R98 */ BBPIndex = BBP_R98; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; /* BBP R103~R106 */ for (BBPIndex = BBP_R103; BBPIndex <= BBP_R106; BBPIndex++) { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; } /* BBP R128 */ BBPIndex = BBP_R128; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; /* BBP R134 */ BBPIndex = BBP_R134; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; /* BBP R135 */ BBPIndex = BBP_R135; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; /* BBP R148 */ BBPIndex = BBP_R148; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; i++; /* BBP R152 */ BBPIndex = BBP_R152; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBPIndex, &BBPValue); RegPair[i].Register = BBPIndex; RegPair[i].Value = BBPValue; } VOID NICRestoreBBPValue( IN PRTMP_ADAPTER pAd, IN REG_PAIR *RegPair) { INT32 i = 0; for (i = 0; i < BBP_RECORD_NUM; i++) { if (RegPair[i].Register) { DBGPRINT(RT_DEBUG_TRACE, ("BBPRecordIndex = %d, BBPIndex = %d, BBPValue = 0x%x\n", i, RegPair[i].Register, RegPair[i].Value)); if (i == 10) AsicBBPWriteWithRxChain(pAd, BBP_R66, RegPair[i].Value, RX_CHAIN_ALL); else RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, RegPair[i].Register, RegPair[i].Value); } } } VOID RT5392_AsicResetBBPAgent( IN PRTMP_ADAPTER pAd) { DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit!!\n")); NICStoreBBPValue(pAd, pAd->BBPResetCtl.BBPRegDB); RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xe); RTMPusecDelay(50); RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc); RTMPusecDelay(50); NICRestoreBBPValue(pAd, pAd->BBPResetCtl.BBPRegDB); }