Commit | Line | Data |
---|---|---|
8fc8598e JC |
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 | /*-------------------------------------------------------------------------- | |
35997ff0 | 19 | * Overview: set RF band width (20M or 40M) |
8fc8598e | 20 | * Input: struct net_device* dev |
35997ff0 | 21 | * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M |
8fc8598e JC |
22 | * Output: NONE |
23 | * Return: NONE | |
24 | * Note: 8226 support both 20M and 40 MHz | |
25 | *---------------------------------------------------------------------------*/ | |
683a6868 | 26 | void PHY_SetRF8256Bandwidth(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth) |
8fc8598e JC |
27 | { |
28 | u8 eRFPath; | |
29 | struct r8192_priv *priv = ieee80211_priv(dev); | |
30 | ||
104cb5c0 SS |
31 | /* for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; |
32 | * eRFPath++) | |
33 | */ | |
34 | for (eRFPath = 0; eRFPath < RF90_PATH_MAX; eRFPath++) { | |
8fc8598e | 35 | if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) |
a8d0df26 | 36 | continue; |
8fc8598e | 37 | |
104cb5c0 SS |
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); | |
104cb5c0 SS |
52 | rtl8192_phy_SetRFReg(dev, |
53 | (RF90_RADIO_PATH_E)eRFPath, | |
54 | 0x14, bMask12Bits, 0x5ab); | |
55 | } else { | |
8fc8598e | 56 | RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); |
104cb5c0 | 57 | } |
8fc8598e | 58 | break; |
104cb5c0 SS |
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! */ | |
93a9f05a | 61 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); /* phy para:3ba */ |
8fc8598e JC |
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 | ||
104cb5c0 | 65 | if (priv->chan == 3 || priv->chan == 9) |
93a9f05a | 66 | /* I need to set priv->chan whenever current channel changes */ |
8fc8598e JC |
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); | |
104cb5c0 | 70 | } else { |
8fc8598e | 71 | RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); |
104cb5c0 | 72 | } |
8fc8598e | 73 | break; |
104cb5c0 SS |
74 | default: |
75 | RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n", Bandwidth); | |
8fc8598e JC |
76 | break; |
77 | ||
78 | } | |
79 | } | |
8fc8598e JC |
80 | } |
81 | /*-------------------------------------------------------------------------- | |
82 | * Overview: Interface to config 8256 | |
83 | * Input: struct net_device* dev | |
84 | * Output: NONE | |
85 | * Return: NONE | |
86 | *---------------------------------------------------------------------------*/ | |
959674e3 | 87 | void PHY_RF8256_Config(struct net_device *dev) |
8fc8598e JC |
88 | { |
89 | struct r8192_priv *priv = ieee80211_priv(dev); | |
93a9f05a SS |
90 | /* Initialize general global value |
91 | * | |
92 | * TODO: Extend RF_PATH_C and RF_PATH_D in the future | |
93 | */ | |
8fc8598e | 94 | priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH; |
93a9f05a | 95 | /* Config BB and RF */ |
8fc8598e | 96 | phy_RF8256_Config_ParaFile(dev); |
8fc8598e JC |
97 | } |
98 | /*-------------------------------------------------------------------------- | |
99 | * Overview: Interface to config 8256 | |
100 | * Input: struct net_device* dev | |
101 | * Output: NONE | |
102 | * Return: NONE | |
103 | *---------------------------------------------------------------------------*/ | |
959674e3 | 104 | void phy_RF8256_Config_ParaFile(struct net_device *dev) |
8fc8598e | 105 | { |
35997ff0 | 106 | u32 u4RegValue = 0; |
35997ff0 | 107 | u8 eRFPath; |
8fc8598e JC |
108 | BB_REGISTER_DEFINITION_T *pPhyReg; |
109 | struct r8192_priv *priv = ieee80211_priv(dev); | |
110 | u32 RegOffSetToBeCheck = 0x3; | |
35997ff0 | 111 | u32 RegValueToBeCheck = 0x7f1; |
8fc8598e JC |
112 | u32 RF3_Final_Value = 0; |
113 | u8 ConstRetryTimes = 5, RetryTimes = 5; | |
114 | u8 ret = 0; | |
93a9f05a | 115 | /* Initialize RF */ |
104cb5c0 | 116 | for (eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath < priv->NumTotalRFPath; eRFPath++) { |
8fc8598e | 117 | if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) |
a8d0df26 | 118 | continue; |
8fc8598e JC |
119 | |
120 | pPhyReg = &priv->PHYRegDef[eRFPath]; | |
121 | ||
93a9f05a SS |
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 | */ | |
104cb5c0 | 126 | switch (eRFPath) { |
8fc8598e JC |
127 | case RF90_PATH_A: |
128 | case RF90_PATH_C: | |
129 | u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV); | |
130 | break; | |
104cb5c0 | 131 | case RF90_PATH_B: |
8fc8598e JC |
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 */ | |
93a9f05a SS |
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 ??? */ | |
8fc8598e JC |
146 | |
147 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf); | |
148 | ||
93a9f05a SS |
149 | /* Check RF block (for FPGA platform only)---- |
150 | * TODO: this function should be removed on ASIC , Emily 2007.2.2 | |
151 | */ | |
104cb5c0 | 152 | if (rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath)) { |
8fc8598e JC |
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----*/ | |
104cb5c0 | 160 | switch (eRFPath) { |
8fc8598e | 161 | case RF90_PATH_A: |
104cb5c0 SS |
162 | while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { |
163 | ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath); | |
8fc8598e JC |
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: | |
104cb5c0 SS |
170 | while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { |
171 | ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath); | |
8fc8598e JC |
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: | |
104cb5c0 SS |
178 | while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { |
179 | ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath); | |
8fc8598e JC |
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: | |
104cb5c0 SS |
186 | while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) { |
187 | ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath); | |
8fc8598e JC |
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----*/; | |
104cb5c0 | 196 | switch (eRFPath) { |
8fc8598e JC |
197 | case RF90_PATH_A: |
198 | case RF90_PATH_C: | |
199 | rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); | |
200 | break; | |
104cb5c0 | 201 | case RF90_PATH_B: |
8fc8598e JC |
202 | case RF90_PATH_D: |
203 | rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); | |
204 | break; | |
205 | } | |
206 | ||
104cb5c0 | 207 | if (ret) { |
8fc8598e JC |
208 | RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath); |
209 | goto phy_RF8256_Config_ParaFile_Fail; | |
210 | } | |
211 | ||
212 | } | |
213 | ||
104cb5c0 SS |
214 | RT_TRACE(COMP_PHY, "PHY Initialization Success\n"); |
215 | return; | |
8fc8598e JC |
216 | |
217 | phy_RF8256_Config_ParaFile_Fail: | |
104cb5c0 | 218 | RT_TRACE(COMP_ERR, "PHY Initialization failed\n"); |
8fc8598e JC |
219 | } |
220 | ||
221 | ||
959674e3 | 222 | void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel) |
8fc8598e | 223 | { |
104cb5c0 | 224 | u32 TxAGC = 0; |
8fc8598e | 225 | struct r8192_priv *priv = ieee80211_priv(dev); |
8fc8598e JC |
226 | TxAGC = powerlevel; |
227 | ||
72b16fe3 | 228 | if (priv->bDynamicTxLowPower) { |
104cb5c0 | 229 | if (priv->CustomerID == RT_CID_819x_Netcore) |
8fc8598e JC |
230 | TxAGC = 0x22; |
231 | else | |
a8d0df26 | 232 | TxAGC += priv->CckPwEnl; |
8fc8598e JC |
233 | } |
234 | ||
104cb5c0 | 235 | if (TxAGC > 0x24) |
8fc8598e JC |
236 | TxAGC = 0x24; |
237 | rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); | |
238 | } | |
239 | ||
240 | ||
959674e3 | 241 | void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel) |
8fc8598e JC |
242 | { |
243 | struct r8192_priv *priv = ieee80211_priv(dev); | |
93a9f05a | 244 | /* Joseph TxPower for 8192 testing */ |
8fc8598e JC |
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 | ||
93a9f05a | 250 | powerBase0 = powerlevel + priv->TxPowerDiff; /* OFDM rates */ |
104cb5c0 | 251 | powerBase0 = (powerBase0<<24) | (powerBase0<<16) | (powerBase0<<8) | powerBase0; |
93a9f05a | 252 | powerBase1 = powerlevel; /* MCS rates */ |
104cb5c0 | 253 | powerBase1 = (powerBase1<<24) | (powerBase1<<16) | (powerBase1<<8) | powerBase1; |
8fc8598e | 254 | |
104cb5c0 SS |
255 | for (index = 0; index < 6; index++) { |
256 | writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index < 2)?powerBase0:powerBase1); | |
8fc8598e JC |
257 | byte0 = (u8)(writeVal & 0x7f); |
258 | byte1 = (u8)((writeVal & 0x7f00)>>8); | |
259 | byte2 = (u8)((writeVal & 0x7f0000)>>16); | |
260 | byte3 = (u8)((writeVal & 0x7f000000)>>24); | |
104cb5c0 SS |
261 | |
262 | if (byte0 > 0x24) | |
263 | /* Max power index = 0x24 */ | |
8fc8598e | 264 | byte0 = 0x24; |
104cb5c0 | 265 | if (byte1 > 0x24) |
8fc8598e | 266 | byte1 = 0x24; |
104cb5c0 | 267 | if (byte2 > 0x24) |
8fc8598e | 268 | byte2 = 0x24; |
104cb5c0 | 269 | if (byte3 > 0x24) |
8fc8598e JC |
270 | byte3 = 0x24; |
271 | ||
93a9f05a | 272 | /* for tx power track */ |
104cb5c0 SS |
273 | if (index == 3) { |
274 | writeVal_tmp = (byte3<<24) | (byte2<<16) | (byte1<<8) | byte0; | |
8fc8598e JC |
275 | priv->Pwr_Track = writeVal_tmp; |
276 | } | |
277 | ||
72b16fe3 | 278 | if (priv->bDynamicTxHighPower) { |
104cb5c0 SS |
279 | /*Add by Jacken 2008/03/06 |
280 | *Emily, 20080613. Set low tx power for both MCS and legacy OFDM | |
281 | */ | |
8fc8598e | 282 | writeVal = 0x03030303; |
104cb5c0 SS |
283 | } else { |
284 | writeVal = (byte3<<24) | (byte2<<16) | (byte1<<8) | byte0; | |
285 | } | |
286 | rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); | |
8fc8598e JC |
287 | } |
288 | return; | |
289 | ||
290 | } |