Commit | Line | Data |
---|---|---|
ecdfa446 GKH |
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 "r8192E.h" | |
13 | #include "r8192E_hw.h" | |
14 | #include "r819xE_phyreg.h" | |
15 | #include "r819xE_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 | *---------------------------------------------------------------------------*/ | |
26 | void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth) //20M or 40M | |
27 | { | |
28 | u8 eRFPath; | |
29 | struct r8192_priv *priv = ieee80211_priv(dev); | |
30 | ||
31 | //for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++) | |
32 | for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++) | |
33 | { | |
34 | if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) | |
35 | continue; | |
36 | ||
37 | switch(Bandwidth) | |
38 | { | |
39 | case HT_CHANNEL_WIDTH_20: | |
40 | if(priv->card_8192_version == VERSION_8190_BD || priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later! | |
41 | { | |
42 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba | |
43 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7); | |
44 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021); | |
45 | ||
46 | //cosa add for sd3's request 01/23/2008 | |
47 | //rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab); | |
48 | } | |
49 | else | |
50 | { | |
51 | RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); | |
52 | } | |
53 | ||
54 | break; | |
55 | case HT_CHANNEL_WIDTH_20_40: | |
56 | if(priv->card_8192_version == VERSION_8190_BD ||priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later! | |
57 | { | |
58 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba | |
59 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3ff); | |
60 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0e1); | |
61 | ||
62 | //cosa add for sd3's request 01/23/2008 | |
63 | #if 0 | |
64 | if(priv->chan == 3 || priv->chan == 9) //I need to set priv->chan whenever current channel changes | |
65 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x59b); | |
66 | else | |
67 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab); | |
68 | #endif | |
69 | } | |
70 | else | |
71 | { | |
72 | RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); | |
73 | } | |
74 | ||
75 | ||
76 | break; | |
77 | default: | |
78 | RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth ); | |
79 | break; | |
80 | ||
81 | } | |
82 | } | |
ecdfa446 GKH |
83 | } |
84 | /*-------------------------------------------------------------------------- | |
85 | * Overview: Interface to config 8256 | |
86 | * Input: struct net_device* dev | |
87 | * Output: NONE | |
88 | * Return: NONE | |
89 | *---------------------------------------------------------------------------*/ | |
90 | RT_STATUS PHY_RF8256_Config(struct net_device* dev) | |
91 | { | |
92 | struct r8192_priv *priv = ieee80211_priv(dev); | |
93 | // Initialize general global value | |
94 | // | |
95 | RT_STATUS rtStatus = RT_STATUS_SUCCESS; | |
96 | // TODO: Extend RF_PATH_C and RF_PATH_D in the future | |
97 | priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH; | |
98 | // Config BB and RF | |
99 | rtStatus = phy_RF8256_Config_ParaFile(dev); | |
100 | ||
101 | return rtStatus; | |
102 | } | |
103 | /*-------------------------------------------------------------------------- | |
104 | * Overview: Interface to config 8256 | |
105 | * Input: struct net_device* dev | |
106 | * Output: NONE | |
107 | * Return: NONE | |
108 | *---------------------------------------------------------------------------*/ | |
109 | RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev) | |
110 | { | |
111 | u32 u4RegValue = 0; | |
112 | u8 eRFPath; | |
113 | RT_STATUS rtStatus = RT_STATUS_SUCCESS; | |
114 | BB_REGISTER_DEFINITION_T *pPhyReg; | |
115 | struct r8192_priv *priv = ieee80211_priv(dev); | |
116 | u32 RegOffSetToBeCheck = 0x3; | |
117 | u32 RegValueToBeCheck = 0x7f1; | |
118 | u32 RF3_Final_Value = 0; | |
119 | u8 ConstRetryTimes = 5, RetryTimes = 5; | |
120 | u8 ret = 0; | |
121 | //3//----------------------------------------------------------------- | |
122 | //3// <2> Initialize RF | |
123 | //3//----------------------------------------------------------------- | |
124 | for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++) | |
125 | { | |
126 | if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) | |
127 | continue; | |
128 | ||
129 | pPhyReg = &priv->PHYRegDef[eRFPath]; | |
130 | ||
131 | // Joseph test for shorten RF config | |
132 | // pHalData->RfReg0Value[eRFPath] = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord); | |
133 | ||
134 | /*----Store original RFENV control type----*/ | |
135 | switch(eRFPath) | |
136 | { | |
137 | case RF90_PATH_A: | |
138 | case RF90_PATH_C: | |
139 | u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV); | |
140 | break; | |
141 | case RF90_PATH_B : | |
142 | case RF90_PATH_D: | |
143 | u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16); | |
144 | break; | |
145 | } | |
146 | ||
147 | /*----Set RF_ENV enable----*/ | |
148 | rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); | |
149 | ||
150 | /*----Set RF_ENV output high----*/ | |
151 | rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); | |
152 | ||
153 | /* Set bit number of Address and Data for RF register */ | |
154 | rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258 | |
155 | rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ??? | |
156 | ||
157 | rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf); | |
158 | ||
159 | /*----Check RF block (for FPGA platform only)----*/ | |
160 | // TODO: this function should be removed on ASIC , Emily 2007.2.2 | |
161 | rtStatus = rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath); | |
162 | if(rtStatus!= RT_STATUS_SUCCESS) | |
163 | { | |
164 | RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath); | |
165 | goto phy_RF8256_Config_ParaFile_Fail; | |
166 | } | |
167 | ||
168 | RetryTimes = ConstRetryTimes; | |
169 | RF3_Final_Value = 0; | |
170 | /*----Initialize RF fom connfiguration file----*/ | |
171 | switch(eRFPath) | |
172 | { | |
173 | case RF90_PATH_A: | |
174 | while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) | |
175 | { | |
176 | ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); | |
177 | RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); | |
178 | RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); | |
179 | RetryTimes--; | |
180 | } | |
181 | break; | |
182 | case RF90_PATH_B: | |
183 | while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) | |
184 | { | |
185 | ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); | |
186 | RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); | |
187 | RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); | |
188 | RetryTimes--; | |
189 | } | |
190 | break; | |
191 | case RF90_PATH_C: | |
192 | while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) | |
193 | { | |
194 | ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); | |
195 | RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); | |
196 | RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); | |
197 | RetryTimes--; | |
198 | } | |
199 | break; | |
200 | case RF90_PATH_D: | |
201 | while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) | |
202 | { | |
203 | ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); | |
204 | RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); | |
205 | RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); | |
206 | RetryTimes--; | |
207 | } | |
208 | break; | |
209 | } | |
210 | ||
211 | /*----Restore RFENV control type----*/; | |
212 | switch(eRFPath) | |
213 | { | |
214 | case RF90_PATH_A: | |
215 | case RF90_PATH_C: | |
216 | rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); | |
217 | break; | |
218 | case RF90_PATH_B : | |
219 | case RF90_PATH_D: | |
220 | rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); | |
221 | break; | |
222 | } | |
223 | ||
224 | if(ret){ | |
225 | RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath); | |
226 | goto phy_RF8256_Config_ParaFile_Fail; | |
227 | } | |
228 | ||
229 | } | |
230 | ||
231 | RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ; | |
232 | return RT_STATUS_SUCCESS; | |
233 | ||
234 | phy_RF8256_Config_ParaFile_Fail: | |
235 | RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ; | |
236 | return RT_STATUS_FAILURE; | |
237 | } | |
238 | ||
239 | ||
240 | void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel) | |
241 | { | |
242 | u32 TxAGC=0; | |
243 | struct r8192_priv *priv = ieee80211_priv(dev); | |
244 | #ifdef RTL8190P | |
245 | u8 byte0, byte1; | |
246 | ||
247 | TxAGC |= ((powerlevel<<8)|powerlevel); | |
248 | TxAGC += priv->CCKTxPowerLevelOriginalOffset; | |
249 | ||
250 | if(priv->bDynamicTxLowPower == true //cosa 04282008 for cck long range | |
251 | /*pMgntInfo->bScanInProgress == TRUE*/ ) //cosa 05/22/2008 for scan | |
252 | { | |
253 | if(priv->CustomerID == RT_CID_819x_Netcore) | |
254 | TxAGC = 0x2222; | |
255 | else | |
256 | TxAGC += ((priv->CckPwEnl<<8)|priv->CckPwEnl); | |
257 | } | |
258 | ||
259 | byte0 = (u8)(TxAGC & 0xff); | |
260 | byte1 = (u8)((TxAGC & 0xff00)>>8); | |
261 | if(byte0 > 0x24) | |
262 | byte0 = 0x24; | |
263 | if(byte1 > 0x24) | |
264 | byte1 = 0x24; | |
265 | if(priv->rf_type == RF_2T4R) //Only 2T4R you have to care the Antenna Tx Power offset | |
266 | { // check antenna C over the max index 0x24 | |
267 | if(priv->RF_C_TxPwDiff > 0) | |
268 | { | |
269 | if( (byte0 + (u8)priv->RF_C_TxPwDiff) > 0x24) | |
270 | byte0 = 0x24 - priv->RF_C_TxPwDiff; | |
271 | if( (byte1 + (u8)priv->RF_C_TxPwDiff) > 0x24) | |
272 | byte1 = 0x24 - priv->RF_C_TxPwDiff; | |
273 | } | |
274 | } | |
275 | TxAGC = (byte1<<8) |byte0; | |
276 | write_nic_dword(dev, CCK_TXAGC, TxAGC); | |
277 | #else | |
278 | #ifdef RTL8192E | |
279 | ||
280 | TxAGC = powerlevel; | |
281 | if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range | |
282 | { | |
283 | if(priv->CustomerID == RT_CID_819x_Netcore) | |
284 | TxAGC = 0x22; | |
285 | else | |
286 | TxAGC += priv->CckPwEnl; | |
287 | } | |
288 | if(TxAGC > 0x24) | |
289 | TxAGC = 0x24; | |
290 | rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); | |
291 | #endif | |
292 | #endif | |
293 | } | |
294 | ||
295 | ||
296 | void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel) | |
297 | { | |
298 | struct r8192_priv *priv = ieee80211_priv(dev); | |
299 | //Joseph TxPower for 8192 testing | |
300 | #ifdef RTL8190P | |
301 | u32 TxAGC1=0, TxAGC2=0, TxAGC2_tmp = 0; | |
302 | u8 i, byteVal1[4], byteVal2[4], byteVal3[4]; | |
303 | ||
304 | if(priv->bDynamicTxHighPower == true) //Add by Jacken 2008/03/06 | |
305 | { | |
306 | TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel); | |
307 | //for tx power track | |
308 | TxAGC2_tmp = TxAGC1; | |
309 | ||
310 | TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0]; | |
311 | TxAGC2 =0x03030303; | |
312 | ||
313 | //for tx power track | |
314 | TxAGC2_tmp += priv->MCSTxPowerLevelOriginalOffset[1]; | |
315 | } | |
316 | else | |
317 | { | |
318 | TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel); | |
319 | TxAGC2 = TxAGC1; | |
320 | ||
321 | TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0]; | |
322 | TxAGC2 += priv->MCSTxPowerLevelOriginalOffset[1]; | |
323 | ||
324 | TxAGC2_tmp = TxAGC2; | |
325 | ||
326 | } | |
327 | for(i=0; i<4; i++) | |
328 | { | |
329 | byteVal1[i] = (u8)( (TxAGC1 & (0xff<<(i*8))) >>(i*8) ); | |
330 | if(byteVal1[i] > 0x24) | |
331 | byteVal1[i] = 0x24; | |
332 | byteVal2[i] = (u8)( (TxAGC2 & (0xff<<(i*8))) >>(i*8) ); | |
333 | if(byteVal2[i] > 0x24) | |
334 | byteVal2[i] = 0x24; | |
335 | ||
336 | //for tx power track | |
337 | byteVal3[i] = (u8)( (TxAGC2_tmp & (0xff<<(i*8))) >>(i*8) ); | |
338 | if(byteVal3[i] > 0x24) | |
339 | byteVal3[i] = 0x24; | |
340 | } | |
341 | ||
342 | if(priv->rf_type == RF_2T4R) //Only 2T4R you have to care the Antenna Tx Power offset | |
343 | { // check antenna C over the max index 0x24 | |
344 | if(priv->RF_C_TxPwDiff > 0) | |
345 | { | |
346 | for(i=0; i<4; i++) | |
347 | { | |
348 | if( (byteVal1[i] + (u8)priv->RF_C_TxPwDiff) > 0x24) | |
349 | byteVal1[i] = 0x24 - priv->RF_C_TxPwDiff; | |
350 | if( (byteVal2[i] + (u8)priv->RF_C_TxPwDiff) > 0x24) | |
351 | byteVal2[i] = 0x24 - priv->RF_C_TxPwDiff; | |
352 | if( (byteVal3[i] + (u8)priv->RF_C_TxPwDiff) > 0x24) | |
353 | byteVal3[i] = 0x24 - priv->RF_C_TxPwDiff; | |
354 | } | |
355 | } | |
356 | } | |
357 | ||
358 | TxAGC1 = (byteVal1[3]<<24) | (byteVal1[2]<<16) |(byteVal1[1]<<8) |byteVal1[0]; | |
359 | TxAGC2 = (byteVal2[3]<<24) | (byteVal2[2]<<16) |(byteVal2[1]<<8) |byteVal2[0]; | |
360 | ||
361 | //for tx power track | |
362 | TxAGC2_tmp = (byteVal3[3]<<24) | (byteVal3[2]<<16) |(byteVal3[1]<<8) |byteVal3[0]; | |
363 | priv->Pwr_Track = TxAGC2_tmp; | |
364 | //DbgPrint("TxAGC2_tmp = 0x%x\n", TxAGC2_tmp); | |
365 | ||
366 | //DbgPrint("TxAGC1/TxAGC2 = 0x%x/0x%x\n", TxAGC1, TxAGC2); | |
367 | write_nic_dword(dev, MCS_TXAGC, TxAGC1); | |
368 | write_nic_dword(dev, MCS_TXAGC+4, TxAGC2); | |
369 | #else | |
370 | #ifdef RTL8192E | |
371 | u32 writeVal, powerBase0, powerBase1, writeVal_tmp; | |
372 | u8 index = 0; | |
373 | u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; | |
374 | u8 byte0, byte1, byte2, byte3; | |
375 | ||
376 | powerBase0 = powerlevel + priv->LegacyHTTxPowerDiff; //OFDM rates | |
377 | powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0; | |
378 | powerBase1 = powerlevel; //MCS rates | |
379 | powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1; | |
380 | ||
381 | for(index=0; index<6; index++) | |
382 | { | |
383 | writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1); | |
384 | byte0 = (u8)(writeVal & 0x7f); | |
385 | byte1 = (u8)((writeVal & 0x7f00)>>8); | |
386 | byte2 = (u8)((writeVal & 0x7f0000)>>16); | |
387 | byte3 = (u8)((writeVal & 0x7f000000)>>24); | |
388 | if(byte0 > 0x24) // Max power index = 0x24 | |
389 | byte0 = 0x24; | |
390 | if(byte1 > 0x24) | |
391 | byte1 = 0x24; | |
392 | if(byte2 > 0x24) | |
393 | byte2 = 0x24; | |
394 | if(byte3 > 0x24) | |
395 | byte3 = 0x24; | |
396 | ||
397 | if(index == 3) | |
398 | { | |
399 | writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0; | |
400 | priv->Pwr_Track = writeVal_tmp; | |
401 | } | |
402 | ||
403 | if(priv->bDynamicTxHighPower == true) //Add by Jacken 2008/03/06 //when DM implement, add this | |
404 | { | |
405 | writeVal = 0x03030303; | |
406 | } | |
407 | else | |
408 | { | |
409 | writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0; | |
410 | } | |
411 | rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); | |
412 | } | |
413 | ||
414 | #endif | |
415 | #endif | |
ecdfa446 GKH |
416 | } |
417 | ||
418 | #define MAX_DOZE_WAITING_TIMES_9x 64 | |
5e1ad18a | 419 | static bool |
ecdfa446 GKH |
420 | SetRFPowerState8190( |
421 | struct net_device* dev, | |
422 | RT_RF_POWER_STATE eRFPowerState | |
423 | ) | |
424 | { | |
425 | struct r8192_priv *priv = ieee80211_priv(dev); | |
426 | PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); | |
427 | bool bResult = true; | |
428 | //u8 eRFPath; | |
429 | u8 i = 0, QueueID = 0; | |
65a43784 | 430 | //ptx_ring head=NULL,tail=NULL; |
431 | struct rtl8192_tx_ring *ring = NULL; | |
ecdfa446 GKH |
432 | |
433 | if(priv->SetRFPowerStateInProgress == true) | |
434 | return false; | |
65a43784 | 435 | //RT_TRACE(COMP_PS, "===========> SetRFPowerState8190()!\n"); |
ecdfa446 GKH |
436 | priv->SetRFPowerStateInProgress = true; |
437 | ||
438 | switch(priv->rf_chip) | |
439 | { | |
440 | case RF_8256: | |
441 | switch( eRFPowerState ) | |
442 | { | |
443 | case eRfOn: | |
65a43784 | 444 | //RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOn !\n"); |
ecdfa446 GKH |
445 | //RXTX enable control: On |
446 | //for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++) | |
65a43784 | 447 | // PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2); |
448 | #ifdef RTL8190P | |
ecdfa446 GKH |
449 | if(priv->rf_type == RF_2T4R) |
450 | { | |
451 | //enable RF-Chip A/B | |
452 | rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] | |
453 | //enable RF-Chip C/D | |
454 | rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4] | |
455 | //analog to digital on | |
456 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8] | |
457 | //digital to analog on | |
458 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0xf); // 0x880[8:5] | |
459 | //rx antenna on | |
460 | rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0xf);// 0xc04[3:0] | |
461 | //rx antenna on | |
462 | rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0xf);// 0xd04[3:0] | |
463 | //analog to digital part2 on | |
464 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0xf); // 0x880[12:9] | |
465 | } | |
466 | else if(priv->rf_type == RF_1T2R) //RF-C, RF-D | |
467 | { | |
468 | //enable RF-Chip C/D | |
469 | rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4] | |
470 | //analog to digital on | |
471 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10] | |
472 | //digital to analog on | |
473 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x180, 0x3); // 0x880[8:7] | |
474 | //rx antenna on | |
475 | rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xc, 0x3);// 0xc04[3:2] | |
476 | //rx antenna on | |
477 | rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xc, 0x3);// 0xd04[3:2] | |
478 | //analog to digital part2 on | |
479 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1800, 0x3); // 0x880[12:11] | |
480 | } | |
65a43784 | 481 | else if(priv->rf_type == RF_1T1R) //RF-C |
482 | { | |
483 | //enable RF-Chip C/D | |
484 | rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4] | |
485 | //analog to digital on | |
486 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x400, 0x1);// 0x88c[10] | |
487 | //digital to analog on | |
488 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x80, 0x1); // 0x880[7] | |
489 | //rx antenna on | |
490 | rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x4, 0x1);// 0xc04[2] | |
491 | //rx antenna on | |
492 | rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x4, 0x1);// 0xd04[2] | |
493 | //analog to digital part2 on | |
494 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x800, 0x1); // 0x880[11] | |
495 | } | |
496 | ||
497 | #elif defined RTL8192E | |
498 | // turn on RF | |
499 | if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) | |
500 | { // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC. | |
501 | bool rtstatus = true; | |
37523e84 | 502 | u32 InitializeCount = 3; |
65a43784 | 503 | do |
504 | { | |
37523e84 | 505 | InitializeCount--; |
65a43784 | 506 | priv->RegRfOff = false; |
507 | rtstatus = NicIFEnableNIC(dev); | |
37523e84 | 508 | }while( (rtstatus != true) &&(InitializeCount >0) ); |
65a43784 | 509 | |
510 | if(rtstatus != true) | |
511 | { | |
512 | RT_TRACE(COMP_ERR,"%s():Initialize Adapter fail,return\n",__FUNCTION__); | |
513 | priv->SetRFPowerStateInProgress = false; | |
514 | return false; | |
515 | } | |
516 | ||
517 | RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); | |
518 | } else { | |
519 | write_nic_byte(dev, ANAPAR, 0x37);//160MHz | |
520 | //write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403 | |
521 | mdelay(1); | |
522 | //enable clock 80/88 MHz | |
523 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2] | |
524 | priv->bHwRfOffAction = 0; | |
525 | //} | |
526 | ||
527 | //RF-A, RF-B | |
528 | //enable RF-Chip A/B | |
ecdfa446 | 529 | rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] |
65a43784 | 530 | //analog to digital on |
531 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] | |
532 | //digital to analog on | |
533 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3] | |
534 | //rx antenna on | |
535 | rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] | |
536 | //rx antenna on | |
537 | rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] | |
538 | //analog to digital part2 on | |
539 | rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] | |
540 | ||
541 | // Baseband reset 2008.09.30 add | |
542 | //write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); | |
543 | ||
544 | //2 AFE | |
545 | // 2008.09.30 add | |
546 | //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884 | |
547 | //analog to digital part2 on | |
548 | //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] | |
549 | ||
550 | ||
551 | //digital to analog on | |
552 | //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3] | |
553 | //analog to digital on | |
554 | //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8] | |
555 | //rx antenna on | |
556 | //PHY_SetBBReg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] | |
557 | //rx antenna on 2008.09.30 mark | |
558 | //PHY_SetBBReg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] | |
559 | ||
560 | //2 RF | |
561 | //enable RF-Chip A/B | |
562 | //rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] | |
563 | //rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1); // 0x864[4] | |
564 | ||
565 | } | |
566 | ||
ecdfa446 GKH |
567 | #endif |
568 | break; | |
569 | ||
570 | // | |
571 | // In current solution, RFSleep=RFOff in order to save power under 802.11 power save. | |
572 | // By Bruce, 2008-01-16. | |
573 | // | |
574 | case eRfSleep: | |
65a43784 | 575 | { |
576 | // HW setting had been configured with deeper mode. | |
577 | if(priv->ieee80211->eRFPowerState == eRfOff) | |
578 | break; | |
579 | ||
580 | // Update current RF state variable. | |
581 | //priv->ieee80211->eRFPowerState = eRFPowerState; | |
582 | ||
583 | //if (pPSC->bLeisurePs) | |
ecdfa446 GKH |
584 | { |
585 | for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) | |
586 | { | |
65a43784 | 587 | ring = &priv->tx_ring[QueueID]; |
588 | ||
589 | if(skb_queue_len(&ring->queue) == 0) | |
590 | { | |
591 | QueueID++; | |
592 | continue; | |
593 | } | |
594 | else | |
595 | { | |
596 | RT_TRACE((COMP_POWER|COMP_RF), "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); | |
597 | udelay(10); | |
598 | i++; | |
599 | } | |
600 | ||
601 | if(i >= MAX_DOZE_WAITING_TIMES_9x) | |
602 | { | |
603 | RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); | |
ecdfa446 | 604 | break; |
65a43784 | 605 | } |
606 | } | |
607 | } | |
ecdfa446 | 608 | |
65a43784 | 609 | //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P) |
610 | #ifdef RTL8190P | |
611 | { | |
612 | PHY_SetRtl8190pRfOff(dev); | |
613 | } | |
614 | //else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E) | |
615 | #elif defined RTL8192E | |
616 | { | |
617 | PHY_SetRtl8192eRfOff(dev); | |
618 | } | |
619 | #endif | |
620 | } | |
ecdfa446 GKH |
621 | break; |
622 | ||
65a43784 | 623 | case eRfOff: |
624 | //RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOff/Sleep !\n"); | |
ecdfa446 | 625 | |
65a43784 | 626 | // Update current RF state variable. |
627 | //priv->ieee80211->eRFPowerState = eRFPowerState; | |
ecdfa446 | 628 | |
65a43784 | 629 | // |
630 | // Disconnect with Any AP or STA. | |
631 | // | |
632 | for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) | |
633 | { | |
634 | ring = &priv->tx_ring[QueueID]; | |
ecdfa446 | 635 | |
65a43784 | 636 | if(skb_queue_len(&ring->queue) == 0) |
ecdfa446 | 637 | { |
ecdfa446 GKH |
638 | QueueID++; |
639 | continue; | |
640 | } | |
641 | else | |
642 | { | |
65a43784 | 643 | RT_TRACE(COMP_POWER, |
644 | "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); | |
ecdfa446 GKH |
645 | udelay(10); |
646 | i++; | |
647 | } | |
648 | ||
649 | if(i >= MAX_DOZE_WAITING_TIMES_9x) | |
650 | { | |
65a43784 | 651 | RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); |
ecdfa446 GKH |
652 | break; |
653 | } | |
654 | } | |
65a43784 | 655 | |
656 | //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P) | |
657 | #if defined RTL8190P | |
658 | { | |
659 | PHY_SetRtl8190pRfOff(dev); | |
ecdfa446 | 660 | } |
65a43784 | 661 | //else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E) |
662 | #elif defined RTL8192E | |
ecdfa446 | 663 | { |
65a43784 | 664 | //if(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC) && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) |
665 | if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) | |
666 | { // Disable all components. | |
667 | // | |
668 | // Note: | |
669 | // NicIFSetLinkStatus is a big problem when we indicate the status to OS, | |
670 | // the OS(XP) will reset. But now, we cnnot find why the NIC is hard to receive | |
671 | // packets after RF ON. Just keep this function here and still work to find out the root couse. | |
672 | // By Bruce, 2009-05-01. | |
673 | // | |
674 | //NicIFSetLinkStatus( Adapter, RT_MEDIA_DISCONNECT ); | |
675 | //if HW radio of , need to indicate scan complete first for not be reset. | |
676 | //if(MgntScanInProgress(pMgntInfo)) | |
677 | // MgntResetScanProcess( Adapter ); | |
678 | ||
679 | // <1> Disable Interrupt | |
680 | //rtl8192_irq_disable(dev); | |
681 | // <2> Stop all timer | |
682 | //MgntCancelAllTimer(Adapter); | |
683 | // <3> Disable Adapter | |
684 | //NicIFHaltAdapter(Adapter, false); | |
685 | NicIFDisableNIC(dev); | |
686 | RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); | |
687 | } | |
688 | else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC)) | |
689 | { // Normal case. | |
690 | // IPS should go to this. | |
691 | PHY_SetRtl8192eRfOff(dev); | |
692 | } | |
693 | } | |
694 | #else | |
695 | else | |
696 | { | |
697 | RT_TRACE(COMP_DBG,DBG_TRACE,("It is not 8190Pci and 8192PciE \n")); | |
ecdfa446 | 698 | } |
ecdfa446 | 699 | #endif |
65a43784 | 700 | |
ecdfa446 GKH |
701 | break; |
702 | ||
703 | default: | |
704 | bResult = false; | |
65a43784 | 705 | RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState); |
ecdfa446 GKH |
706 | break; |
707 | } | |
708 | ||
709 | break; | |
710 | ||
711 | default: | |
712 | RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n"); | |
713 | break; | |
714 | } | |
715 | ||
716 | if(bResult) | |
717 | { | |
718 | // Update current RF state variable. | |
719 | priv->ieee80211->eRFPowerState = eRFPowerState; | |
ecdfa446 GKH |
720 | } |
721 | ||
65a43784 | 722 | //printk("%s()priv->ieee80211->eRFPowerState:%s\n" ,__func__,priv->ieee80211->eRFPowerState == eRfOn ? "On" : "Off"); |
ecdfa446 | 723 | priv->SetRFPowerStateInProgress = false; |
65a43784 | 724 | //RT_TRACE(COMP_PS, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult); |
ecdfa446 GKH |
725 | return bResult; |
726 | } | |
727 | ||
728 | ||
729 | ||
730 | // | |
731 | // Description: | |
732 | // Change RF power state. | |
733 | // | |
734 | // Assumption: | |
735 | // This function must be executed in re-schdulable context, | |
736 | // ie. PASSIVE_LEVEL. | |
737 | // | |
738 | // 050823, by rcnjko. | |
739 | // | |
5e1ad18a | 740 | static bool |
ecdfa446 GKH |
741 | SetRFPowerState( |
742 | struct net_device* dev, | |
743 | RT_RF_POWER_STATE eRFPowerState | |
744 | ) | |
745 | { | |
746 | struct r8192_priv *priv = ieee80211_priv(dev); | |
747 | ||
748 | bool bResult = false; | |
749 | ||
750 | RT_TRACE(COMP_RF,"---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState); | |
751 | #ifdef RTL8192E | |
752 | if(eRFPowerState == priv->ieee80211->eRFPowerState && priv->bHwRfOffAction == 0) | |
753 | #else | |
754 | if(eRFPowerState == priv->ieee80211->eRFPowerState) | |
755 | #endif | |
756 | { | |
757 | RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState); | |
758 | return bResult; | |
759 | } | |
760 | ||
761 | bResult = SetRFPowerState8190(dev, eRFPowerState); | |
762 | ||
763 | RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): bResult(%d)\n", bResult); | |
764 | ||
765 | return bResult; | |
766 | } | |
767 | ||
5e1ad18a | 768 | static void |
ecdfa446 GKH |
769 | MgntDisconnectIBSS( |
770 | struct net_device* dev | |
771 | ) | |
772 | { | |
773 | struct r8192_priv *priv = ieee80211_priv(dev); | |
774 | //RT_OP_MODE OpMode; | |
775 | u8 i; | |
776 | bool bFilterOutNonAssociatedBSSID = false; | |
777 | ||
778 | //IEEE80211_DEBUG(IEEE80211_DL_TRACE, "XXXXXXXXXX MgntDisconnect IBSS\n"); | |
779 | ||
780 | priv->ieee80211->state = IEEE80211_NOLINK; | |
781 | ||
782 | // PlatformZeroMemory( pMgntInfo->Bssid, 6 ); | |
783 | for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i]= 0x55; | |
784 | priv->OpMode = RT_OP_MODE_NO_LINK; | |
785 | write_nic_word(dev, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); | |
786 | write_nic_dword(dev, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); | |
787 | { | |
788 | RT_OP_MODE OpMode = priv->OpMode; | |
789 | //LED_CTL_MODE LedAction = LED_CTL_NO_LINK; | |
790 | u8 btMsr = read_nic_byte(dev, MSR); | |
791 | ||
792 | btMsr &= 0xfc; | |
793 | ||
794 | switch(OpMode) | |
795 | { | |
796 | case RT_OP_MODE_INFRASTRUCTURE: | |
797 | btMsr |= MSR_LINK_MANAGED; | |
798 | //LedAction = LED_CTL_LINK; | |
799 | break; | |
800 | ||
801 | case RT_OP_MODE_IBSS: | |
802 | btMsr |= MSR_LINK_ADHOC; | |
935e99fb | 803 | // led link set separate |
ecdfa446 GKH |
804 | break; |
805 | ||
806 | case RT_OP_MODE_AP: | |
807 | btMsr |= MSR_LINK_MASTER; | |
808 | //LedAction = LED_CTL_LINK; | |
809 | break; | |
810 | ||
811 | default: | |
812 | btMsr |= MSR_LINK_NONE; | |
813 | break; | |
814 | } | |
815 | ||
816 | write_nic_byte(dev, MSR, btMsr); | |
817 | ||
818 | // LED control | |
819 | //Adapter->HalFunc.LedControlHandler(Adapter, LedAction); | |
820 | } | |
821 | ieee80211_stop_send_beacons(priv->ieee80211); | |
822 | ||
823 | // If disconnect, clear RCR CBSSID bit | |
824 | bFilterOutNonAssociatedBSSID = false; | |
825 | { | |
826 | u32 RegRCR, Type; | |
827 | Type = bFilterOutNonAssociatedBSSID; | |
828 | RegRCR = read_nic_dword(dev,RCR); | |
829 | priv->ReceiveConfig = RegRCR; | |
830 | if (Type == true) | |
831 | RegRCR |= (RCR_CBSSID); | |
832 | else if (Type == false) | |
833 | RegRCR &= (~RCR_CBSSID); | |
834 | ||
835 | { | |
836 | write_nic_dword(dev, RCR,RegRCR); | |
837 | priv->ReceiveConfig = RegRCR; | |
838 | } | |
839 | ||
840 | } | |
841 | //MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE ); | |
842 | notify_wx_assoc_event(priv->ieee80211); | |
843 | ||
844 | } | |
845 | ||
5e1ad18a | 846 | static void |
ecdfa446 GKH |
847 | MlmeDisassociateRequest( |
848 | struct net_device* dev, | |
849 | u8* asSta, | |
850 | u8 asRsn | |
851 | ) | |
852 | { | |
853 | struct r8192_priv *priv = ieee80211_priv(dev); | |
854 | u8 i; | |
855 | ||
856 | RemovePeerTS(priv->ieee80211, asSta); | |
857 | ||
858 | SendDisassociation( priv->ieee80211, asSta, asRsn ); | |
859 | ||
5e1ad18a | 860 | if(memcpy(priv->ieee80211->current_network.bssid,asSta,6) == NULL) |
ecdfa446 GKH |
861 | { |
862 | //ShuChen TODO: change media status. | |
863 | //ShuChen TODO: What to do when disassociate. | |
864 | priv->ieee80211->state = IEEE80211_NOLINK; | |
865 | //pMgntInfo->AsocTimestamp = 0; | |
866 | for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22; | |
867 | // pMgntInfo->mBrates.Length = 0; | |
868 | // Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) ); | |
869 | priv->OpMode = RT_OP_MODE_NO_LINK; | |
870 | { | |
871 | RT_OP_MODE OpMode = priv->OpMode; | |
872 | //LED_CTL_MODE LedAction = LED_CTL_NO_LINK; | |
873 | u8 btMsr = read_nic_byte(dev, MSR); | |
874 | ||
875 | btMsr &= 0xfc; | |
876 | ||
877 | switch(OpMode) | |
878 | { | |
879 | case RT_OP_MODE_INFRASTRUCTURE: | |
880 | btMsr |= MSR_LINK_MANAGED; | |
881 | //LedAction = LED_CTL_LINK; | |
882 | break; | |
883 | ||
884 | case RT_OP_MODE_IBSS: | |
885 | btMsr |= MSR_LINK_ADHOC; | |
935e99fb | 886 | // led link set separate |
ecdfa446 GKH |
887 | break; |
888 | ||
889 | case RT_OP_MODE_AP: | |
890 | btMsr |= MSR_LINK_MASTER; | |
891 | //LedAction = LED_CTL_LINK; | |
892 | break; | |
893 | ||
894 | default: | |
895 | btMsr |= MSR_LINK_NONE; | |
896 | break; | |
897 | } | |
898 | ||
899 | write_nic_byte(dev, MSR, btMsr); | |
900 | ||
901 | // LED control | |
902 | //Adapter->HalFunc.LedControlHandler(Adapter, LedAction); | |
903 | } | |
904 | ieee80211_disassociate(priv->ieee80211); | |
905 | ||
906 | write_nic_word(dev, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); | |
907 | write_nic_dword(dev, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); | |
908 | ||
909 | } | |
910 | ||
911 | } | |
912 | ||
913 | ||
5e1ad18a | 914 | static void |
ecdfa446 GKH |
915 | MgntDisconnectAP( |
916 | struct net_device* dev, | |
917 | u8 asRsn | |
918 | ) | |
919 | { | |
920 | struct r8192_priv *priv = ieee80211_priv(dev); | |
921 | bool bFilterOutNonAssociatedBSSID = false; | |
922 | ||
923 | // | |
924 | // Commented out by rcnjko, 2005.01.27: | |
925 | // I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE(). | |
926 | // | |
927 | // //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success | |
928 | // SecClearAllKeys(Adapter); | |
929 | ||
930 | // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking. | |
931 | #ifdef TO_DO | |
932 | if( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch || | |
933 | (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) ) // In CCKM mode will Clear key | |
934 | { | |
935 | SecClearAllKeys(Adapter); | |
936 | RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key...")) | |
937 | } | |
938 | #endif | |
939 | // If disconnect, clear RCR CBSSID bit | |
940 | bFilterOutNonAssociatedBSSID = false; | |
941 | { | |
942 | u32 RegRCR, Type; | |
943 | ||
944 | Type = bFilterOutNonAssociatedBSSID; | |
945 | //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RCR, (pu1Byte)(&RegRCR)); | |
946 | RegRCR = read_nic_dword(dev,RCR); | |
947 | priv->ReceiveConfig = RegRCR; | |
948 | ||
949 | if (Type == true) | |
950 | RegRCR |= (RCR_CBSSID); | |
951 | else if (Type == false) | |
952 | RegRCR &= (~RCR_CBSSID); | |
953 | ||
954 | write_nic_dword(dev, RCR,RegRCR); | |
955 | priv->ReceiveConfig = RegRCR; | |
956 | ||
957 | ||
958 | } | |
959 | // 2004.10.11, by rcnjko. | |
960 | //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss ); | |
961 | MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn ); | |
962 | ||
963 | priv->ieee80211->state = IEEE80211_NOLINK; | |
964 | //pMgntInfo->AsocTimestamp = 0; | |
965 | } | |
966 | ||
967 | ||
5e1ad18a | 968 | static bool |
ecdfa446 GKH |
969 | MgntDisconnect( |
970 | struct net_device* dev, | |
971 | u8 asRsn | |
972 | ) | |
973 | { | |
974 | struct r8192_priv *priv = ieee80211_priv(dev); | |
975 | ||
976 | // | |
977 | // Schedule an workitem to wake up for ps mode, 070109, by rcnjko. | |
978 | // | |
979 | #ifdef TO_DO | |
980 | if(pMgntInfo->mPss != eAwake) | |
981 | { | |
982 | // | |
983 | // Using AwkaeTimer to prevent mismatch ps state. | |
984 | // In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31. | |
985 | // | |
986 | // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) ); | |
987 | PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 ); | |
988 | } | |
989 | #endif | |
990 | // Follow 8180 AP mode, 2005.05.30, by rcnjko. | |
991 | #ifdef TO_DO | |
992 | if(pMgntInfo->mActingAsAp) | |
993 | { | |
994 | RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> AP_DisassociateAllStation\n")); | |
995 | AP_DisassociateAllStation(Adapter, unspec_reason); | |
996 | return TRUE; | |
997 | } | |
998 | #endif | |
999 | // Indication of disassociation event. | |
1000 | //DrvIFIndicateDisassociation(Adapter, asRsn); | |
1001 | ||
1002 | // In adhoc mode, update beacon frame. | |
1003 | if( priv->ieee80211->state == IEEE80211_LINKED ) | |
1004 | { | |
1005 | if( priv->ieee80211->iw_mode == IW_MODE_ADHOC ) | |
1006 | { | |
1007 | //RT_TRACE(COMP_MLME, "MgntDisconnect() ===> MgntDisconnectIBSS\n"); | |
1008 | MgntDisconnectIBSS(dev); | |
1009 | } | |
1010 | if( priv->ieee80211->iw_mode == IW_MODE_INFRA ) | |
1011 | { | |
1012 | // We clear key here instead of MgntDisconnectAP() because that | |
1013 | // MgntActSet_802_11_DISASSOCIATE() is an interface called by OS, | |
1014 | // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is | |
1015 | // used to handle disassociation related things to AP, e.g. send Disassoc | |
1016 | // frame to AP. 2005.01.27, by rcnjko. | |
1017 | //IEEE80211_DEBUG(IEEE80211_DL_TRACE,"MgntDisconnect() ===> MgntDisconnectAP\n"); | |
1018 | MgntDisconnectAP(dev, asRsn); | |
1019 | } | |
1020 | ||
1021 | // Inidicate Disconnect, 2005.02.23, by rcnjko. | |
1022 | //MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE); | |
1023 | } | |
1024 | ||
1025 | return true; | |
1026 | } | |
1027 | ||
1028 | // | |
1029 | // Description: | |
1030 | // Chang RF Power State. | |
1031 | // Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE. | |
1032 | // | |
1033 | // Assumption: | |
1034 | // PASSIVE LEVEL. | |
1035 | // | |
1036 | bool | |
1037 | MgntActSet_RF_State( | |
1038 | struct net_device* dev, | |
1039 | RT_RF_POWER_STATE StateToSet, | |
1040 | RT_RF_CHANGE_SOURCE ChangeSource | |
1041 | ) | |
1042 | { | |
1043 | struct r8192_priv *priv = ieee80211_priv(dev); | |
1044 | bool bActionAllowed = false; | |
1045 | bool bConnectBySSID = false; | |
1046 | RT_RF_POWER_STATE rtState; | |
1047 | u16 RFWaitCounter = 0; | |
1048 | unsigned long flag; | |
1049 | RT_TRACE(COMP_POWER, "===>MgntActSet_RF_State(): StateToSet(%d)\n",StateToSet); | |
1050 | ||
1051 | //1// | |
1052 | //1//<1>Prevent the race condition of RF state change. | |
1053 | //1// | |
1054 | // Only one thread can change the RF state at one time, and others should wait to be executed. By Bruce, 2007-11-28. | |
1055 | ||
1056 | while(true) | |
1057 | { | |
1058 | spin_lock_irqsave(&priv->rf_ps_lock,flag); | |
1059 | if(priv->RFChangeInProgress) | |
1060 | { | |
1061 | spin_unlock_irqrestore(&priv->rf_ps_lock,flag); | |
1062 | RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet); | |
1063 | ||
1064 | // Set RF after the previous action is done. | |
1065 | while(priv->RFChangeInProgress) | |
1066 | { | |
1067 | RFWaitCounter ++; | |
1068 | RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter); | |
1069 | udelay(1000); // 1 ms | |
1070 | ||
1071 | // Wait too long, return FALSE to avoid to be stuck here. | |
1072 | if(RFWaitCounter > 100) | |
1073 | { | |
1074 | RT_TRACE(COMP_ERR, "MgntActSet_RF_State(): Wait too logn to set RF\n"); | |
1075 | // TODO: Reset RF state? | |
1076 | return false; | |
1077 | } | |
1078 | } | |
1079 | } | |
1080 | else | |
1081 | { | |
1082 | priv->RFChangeInProgress = true; | |
1083 | spin_unlock_irqrestore(&priv->rf_ps_lock,flag); | |
1084 | break; | |
1085 | } | |
1086 | } | |
1087 | ||
1088 | rtState = priv->ieee80211->eRFPowerState; | |
1089 | ||
1090 | switch(StateToSet) | |
1091 | { | |
1092 | case eRfOn: | |
1093 | // | |
1094 | // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or | |
1095 | // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02. | |
1096 | // | |
1097 | ||
1098 | priv->ieee80211->RfOffReason &= (~ChangeSource); | |
1099 | ||
1100 | if(! priv->ieee80211->RfOffReason) | |
1101 | { | |
1102 | priv->ieee80211->RfOffReason = 0; | |
1103 | bActionAllowed = true; | |
1104 | ||
1105 | ||
1106 | if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW ) | |
1107 | { | |
1108 | bConnectBySSID = true; | |
1109 | } | |
1110 | } | |
1111 | else | |
1112 | RT_TRACE(COMP_POWER, "MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->ieee80211->RfOffReason, ChangeSource); | |
1113 | ||
1114 | break; | |
1115 | ||
1116 | case eRfOff: | |
1117 | ||
1118 | if (priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) | |
1119 | { | |
1120 | // | |
1121 | // 060808, Annie: | |
1122 | // Disconnect to current BSS when radio off. Asked by QuanTa. | |
1123 | // | |
1124 | // Set all link status falg, by Bruce, 2007-06-26. | |
1125 | //MgntActSet_802_11_DISASSOCIATE( Adapter, disas_lv_ss ); | |
1126 | MgntDisconnect(dev, disas_lv_ss); | |
1127 | ||
1128 | // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. | |
1129 | // 2007.05.28, by shien chang. | |
1130 | ||
1131 | } | |
1132 | ||
1133 | ||
1134 | priv->ieee80211->RfOffReason |= ChangeSource; | |
1135 | bActionAllowed = true; | |
1136 | break; | |
1137 | ||
1138 | case eRfSleep: | |
1139 | priv->ieee80211->RfOffReason |= ChangeSource; | |
1140 | bActionAllowed = true; | |
1141 | break; | |
1142 | ||
1143 | default: | |
1144 | break; | |
1145 | } | |
1146 | ||
1147 | if(bActionAllowed) | |
1148 | { | |
1149 | RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->ieee80211->RfOffReason); | |
1150 | // Config HW to the specified mode. | |
1151 | SetRFPowerState(dev, StateToSet); | |
1152 | // Turn on RF. | |
1153 | if(StateToSet == eRfOn) | |
1154 | { | |
1155 | //Adapter->HalFunc.HalEnableRxHandler(Adapter); | |
1156 | if(bConnectBySSID) | |
1157 | { | |
1158 | //MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE ); | |
1159 | } | |
1160 | } | |
1161 | // Turn off RF. | |
1162 | else if(StateToSet == eRfOff) | |
1163 | { | |
1164 | //Adapter->HalFunc.HalDisableRxHandler(Adapter); | |
1165 | } | |
1166 | } | |
1167 | else | |
1168 | { | |
1169 | RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->ieee80211->RfOffReason); | |
1170 | } | |
1171 | ||
1172 | // Release RF spinlock | |
1173 | spin_lock_irqsave(&priv->rf_ps_lock,flag); | |
1174 | priv->RFChangeInProgress = false; | |
1175 | spin_unlock_irqrestore(&priv->rf_ps_lock,flag); | |
1176 | ||
1177 | RT_TRACE(COMP_POWER, "<===MgntActSet_RF_State()\n"); | |
1178 | return bActionAllowed; | |
1179 | } | |
1180 | ||
1181 |