1/* 2 This is part of the rtl8192 driver 3 released under the GPL (See file COPYING for details). 4 5 This files contains programming code for the rtl8256 6 radio frontend. 7 8 *Many* thanks to Realtek Corp. for their great support! 9 10*/ 11 12#include "r8192U.h" 13#include "r8192U_hw.h" 14#include "r819xU_phyreg.h" 15#include "r819xU_phy.h" 16#include "r8190_rtl8256.h" 17 18/*-------------------------------------------------------------------------- 19 * Overview: set RF band width (20M or 40M) 20 * Input: struct net_device* dev 21 * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M 22 * Output: NONE 23 * Return: NONE 24 * Note: 8226 support both 20M and 40 MHz 25 *---------------------------------------------------------------------------*/ 26void PHY_SetRF8256Bandwidth(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth) 27{ 28 u8 eRFPath; 29 struct r8192_priv *priv = ieee80211_priv(dev); 30 31 /* for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; 32 * eRFPath++) 33 */ 34 for (eRFPath = 0; eRFPath < RF90_PATH_MAX; eRFPath++) { 35 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) 36 continue; 37 38 switch (Bandwidth) { 39 case HT_CHANNEL_WIDTH_20: 40 if (priv->card_8192_version == VERSION_819xU_A 41 || priv->card_8192_version 42 == VERSION_819xU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */ 43 rtl8192_phy_SetRFReg(dev, 44 (RF90_RADIO_PATH_E)eRFPath, 45 0x0b, bMask12Bits, 0x100); /* phy para:1ba */ 46 rtl8192_phy_SetRFReg(dev, 47 (RF90_RADIO_PATH_E)eRFPath, 48 0x2c, bMask12Bits, 0x3d7); 49 rtl8192_phy_SetRFReg(dev, 50 (RF90_RADIO_PATH_E)eRFPath, 51 0x0e, bMask12Bits, 0x021); 52 rtl8192_phy_SetRFReg(dev, 53 (RF90_RADIO_PATH_E)eRFPath, 54 0x14, bMask12Bits, 0x5ab); 55 } else { 56 RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); 57 } 58 break; 59 case HT_CHANNEL_WIDTH_20_40: 60 if (priv->card_8192_version == VERSION_819xU_A || priv->card_8192_version == VERSION_819xU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */ 61 rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); /* phy para:3ba */ 62 rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3df); 63 rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0a1); 64 65 if (priv->chan == 3 || priv->chan == 9) 66 /* I need to set priv->chan whenever current channel changes */ 67 rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x59b); 68 else 69 rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab); 70 } else { 71 RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); 72 } 73 break; 74 default: 75 RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n", Bandwidth); 76 break; 77 78 } 79 } 80} 81/*-------------------------------------------------------------------------- 82 * Overview: Interface to config 8256 83 * Input: struct net_device* dev 84 * Output: NONE 85 * Return: NONE 86 *---------------------------------------------------------------------------*/ 87void PHY_RF8256_Config(struct net_device *dev) 88{ 89 struct r8192_priv *priv = ieee80211_priv(dev); 90 /* Initialize general global value 91 * 92 * TODO: Extend RF_PATH_C and RF_PATH_D in the future 93 */ 94 priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH; 95 /* Config BB and RF */ 96 phy_RF8256_Config_ParaFile(dev); 97} 98/*-------------------------------------------------------------------------- 99 * Overview: Interface to config 8256 100 * Input: struct net_device* dev 101 * Output: NONE 102 * Return: NONE 103 *---------------------------------------------------------------------------*/ 104void phy_RF8256_Config_ParaFile(struct net_device *dev) 105{ 106 u32 u4RegValue = 0; 107 u8 eRFPath; 108 BB_REGISTER_DEFINITION_T *pPhyReg; 109 struct r8192_priv *priv = ieee80211_priv(dev); 110 u32 RegOffSetToBeCheck = 0x3; 111 u32 RegValueToBeCheck = 0x7f1; 112 u32 RF3_Final_Value = 0; 113 u8 ConstRetryTimes = 5, RetryTimes = 5; 114 u8 ret = 0; 115 /* Initialize RF */ 116 for (eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath < priv->NumTotalRFPath; eRFPath++) { 117 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) 118 continue; 119 120 pPhyReg = &priv->PHYRegDef[eRFPath]; 121 122 /* Joseph test for shorten RF config 123 * pHalData->RfReg0Value[eRFPath] = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord); 124 * ----Store original RFENV control type 125 */ 126 switch (eRFPath) { 127 case RF90_PATH_A: 128 case RF90_PATH_C: 129 u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV); 130 break; 131 case RF90_PATH_B: 132 case RF90_PATH_D: 133 u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16); 134 break; 135 } 136 137 /*----Set RF_ENV enable----*/ 138 rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); 139 140 /*----Set RF_ENV output high----*/ 141 rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); 142 143 /* Set bit number of Address and Data for RF register */ 144 rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258 */ 145 rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ??? */ 146 147 rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf); 148 149 /* Check RF block (for FPGA platform only)---- 150 * TODO: this function should be removed on ASIC , Emily 2007.2.2 151 */ 152 if (rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath)) { 153 RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath); 154 goto phy_RF8256_Config_ParaFile_Fail; 155 } 156 157 RetryTimes = ConstRetryTimes; 158 RF3_Final_Value = 0; 159 /*----Initialize RF fom connfiguration file----*/ 160 switch (eRFPath) { 161 case RF90_PATH_A: 162 while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { 163 ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath); 164 RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); 165 RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); 166 RetryTimes--; 167 } 168 break; 169 case RF90_PATH_B: 170 while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { 171 ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath); 172 RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); 173 RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); 174 RetryTimes--; 175 } 176 break; 177 case RF90_PATH_C: 178 while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { 179 ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath); 180 RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); 181 RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); 182 RetryTimes--; 183 } 184 break; 185 case RF90_PATH_D: 186 while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { 187 ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath); 188 RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); 189 RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); 190 RetryTimes--; 191 } 192 break; 193 } 194 195 /*----Restore RFENV control type----*/; 196 switch (eRFPath) { 197 case RF90_PATH_A: 198 case RF90_PATH_C: 199 rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); 200 break; 201 case RF90_PATH_B: 202 case RF90_PATH_D: 203 rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); 204 break; 205 } 206 207 if (ret) { 208 RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath); 209 goto phy_RF8256_Config_ParaFile_Fail; 210 } 211 212 } 213 214 RT_TRACE(COMP_PHY, "PHY Initialization Success\n"); 215 return; 216 217phy_RF8256_Config_ParaFile_Fail: 218 RT_TRACE(COMP_ERR, "PHY Initialization failed\n"); 219} 220 221 222void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel) 223{ 224 u32 TxAGC = 0; 225 struct r8192_priv *priv = ieee80211_priv(dev); 226 TxAGC = powerlevel; 227 228 if (priv->bDynamicTxLowPower) { 229 if (priv->CustomerID == RT_CID_819x_Netcore) 230 TxAGC = 0x22; 231 else 232 TxAGC += priv->CckPwEnl; 233 } 234 235 if (TxAGC > 0x24) 236 TxAGC = 0x24; 237 rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); 238} 239 240 241void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel) 242{ 243 struct r8192_priv *priv = ieee80211_priv(dev); 244 /* Joseph TxPower for 8192 testing */ 245 u32 writeVal, powerBase0, powerBase1, writeVal_tmp; 246 u8 index = 0; 247 u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; 248 u8 byte0, byte1, byte2, byte3; 249 250 powerBase0 = powerlevel + priv->TxPowerDiff; /* OFDM rates */ 251 powerBase0 = (powerBase0<<24) | (powerBase0<<16) | (powerBase0<<8) | powerBase0; 252 powerBase1 = powerlevel; /* MCS rates */ 253 powerBase1 = (powerBase1<<24) | (powerBase1<<16) | (powerBase1<<8) | powerBase1; 254 255 for (index = 0; index < 6; index++) { 256 writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index < 2)?powerBase0:powerBase1); 257 byte0 = (u8)(writeVal & 0x7f); 258 byte1 = (u8)((writeVal & 0x7f00)>>8); 259 byte2 = (u8)((writeVal & 0x7f0000)>>16); 260 byte3 = (u8)((writeVal & 0x7f000000)>>24); 261 262 if (byte0 > 0x24) 263 /* Max power index = 0x24 */ 264 byte0 = 0x24; 265 if (byte1 > 0x24) 266 byte1 = 0x24; 267 if (byte2 > 0x24) 268 byte2 = 0x24; 269 if (byte3 > 0x24) 270 byte3 = 0x24; 271 272 /* for tx power track */ 273 if (index == 3) { 274 writeVal_tmp = (byte3<<24) | (byte2<<16) | (byte1<<8) | byte0; 275 priv->Pwr_Track = writeVal_tmp; 276 } 277 278 if (priv->bDynamicTxHighPower) { 279 /*Add by Jacken 2008/03/06 280 *Emily, 20080613. Set low tx power for both MCS and legacy OFDM 281 */ 282 writeVal = 0x03030303; 283 } else { 284 writeVal = (byte3<<24) | (byte2<<16) | (byte1<<8) | byte0; 285 } 286 rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); 287 } 288 return; 289 290} 291