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