staging: rtl8192e: Remove rf_chip variable, hardcode to RF_8256
[deliverable/linux.git] / drivers / staging / rtl8192e / r8190_rtl8256.c
CommitLineData
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 *---------------------------------------------------------------------------*/
26void 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
ecdfa446
GKH
62 }
63 else
64 {
65 RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
66 }
67
68
69 break;
70 default:
71 RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
72 break;
73
74 }
75 }
ecdfa446
GKH
76}
77/*--------------------------------------------------------------------------
78 * Overview: Interface to config 8256
79 * Input: struct net_device* dev
80 * Output: NONE
81 * Return: NONE
82 *---------------------------------------------------------------------------*/
83RT_STATUS PHY_RF8256_Config(struct net_device* dev)
84{
85 struct r8192_priv *priv = ieee80211_priv(dev);
86 // Initialize general global value
87 //
88 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
89 // TODO: Extend RF_PATH_C and RF_PATH_D in the future
90 priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
91 // Config BB and RF
92 rtStatus = phy_RF8256_Config_ParaFile(dev);
93
94 return rtStatus;
95}
96/*--------------------------------------------------------------------------
97 * Overview: Interface to config 8256
98 * Input: struct net_device* dev
99 * Output: NONE
100 * Return: NONE
101 *---------------------------------------------------------------------------*/
102RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev)
103{
104 u32 u4RegValue = 0;
105 u8 eRFPath;
106 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
107 BB_REGISTER_DEFINITION_T *pPhyReg;
108 struct r8192_priv *priv = ieee80211_priv(dev);
109 u32 RegOffSetToBeCheck = 0x3;
110 u32 RegValueToBeCheck = 0x7f1;
111 u32 RF3_Final_Value = 0;
112 u8 ConstRetryTimes = 5, RetryTimes = 5;
113 u8 ret = 0;
114 //3//-----------------------------------------------------------------
115 //3// <2> Initialize RF
116 //3//-----------------------------------------------------------------
117 for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++)
118 {
119 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
120 continue;
121
122 pPhyReg = &priv->PHYRegDef[eRFPath];
123
124 // Joseph test for shorten RF config
125 // pHalData->RfReg0Value[eRFPath] = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord);
126
127 /*----Store original RFENV control type----*/
128 switch(eRFPath)
129 {
130 case RF90_PATH_A:
131 case RF90_PATH_C:
132 u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
133 break;
134 case RF90_PATH_B :
135 case RF90_PATH_D:
136 u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16);
137 break;
138 }
139
140 /*----Set RF_ENV enable----*/
141 rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
142
143 /*----Set RF_ENV output high----*/
144 rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
145
146 /* Set bit number of Address and Data for RF register */
147 rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258
148 rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ???
149
150 rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf);
151
152 /*----Check RF block (for FPGA platform only)----*/
153 // TODO: this function should be removed on ASIC , Emily 2007.2.2
154 rtStatus = rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath);
155 if(rtStatus!= RT_STATUS_SUCCESS)
156 {
157 RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath);
158 goto phy_RF8256_Config_ParaFile_Fail;
159 }
160
161 RetryTimes = ConstRetryTimes;
162 RF3_Final_Value = 0;
163 /*----Initialize RF fom connfiguration file----*/
164 switch(eRFPath)
165 {
166 case RF90_PATH_A:
167 while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
168 {
169 ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
170 RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
171 RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
172 RetryTimes--;
173 }
174 break;
175 case RF90_PATH_B:
176 while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
177 {
178 ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
179 RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
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:
185 while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
186 {
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 case RF90_PATH_D:
194 while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
195 {
196 ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
197 RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
198 RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
199 RetryTimes--;
200 }
201 break;
202 }
203
204 /*----Restore RFENV control type----*/;
205 switch(eRFPath)
206 {
207 case RF90_PATH_A:
208 case RF90_PATH_C:
209 rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
210 break;
211 case RF90_PATH_B :
212 case RF90_PATH_D:
213 rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
214 break;
215 }
216
217 if(ret){
218 RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
219 goto phy_RF8256_Config_ParaFile_Fail;
220 }
221
222 }
223
224 RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ;
225 return RT_STATUS_SUCCESS;
226
227phy_RF8256_Config_ParaFile_Fail:
228 RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ;
229 return RT_STATUS_FAILURE;
230}
231
232
233void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel)
234{
235 u32 TxAGC=0;
236 struct r8192_priv *priv = ieee80211_priv(dev);
ecdfa446
GKH
237
238 TxAGC = powerlevel;
239 if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range
240 {
241 if(priv->CustomerID == RT_CID_819x_Netcore)
242 TxAGC = 0x22;
243 else
244 TxAGC += priv->CckPwEnl;
245 }
246 if(TxAGC > 0x24)
247 TxAGC = 0x24;
248 rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
ecdfa446
GKH
249}
250
251
252void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel)
253{
254 struct r8192_priv *priv = ieee80211_priv(dev);
ecdfa446 255
ecdfa446
GKH
256 u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
257 u8 index = 0;
258 u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
259 u8 byte0, byte1, byte2, byte3;
260
261 powerBase0 = powerlevel + priv->LegacyHTTxPowerDiff; //OFDM rates
262 powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
263 powerBase1 = powerlevel; //MCS rates
264 powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
265
266 for(index=0; index<6; index++)
267 {
268 writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
269 byte0 = (u8)(writeVal & 0x7f);
270 byte1 = (u8)((writeVal & 0x7f00)>>8);
271 byte2 = (u8)((writeVal & 0x7f0000)>>16);
272 byte3 = (u8)((writeVal & 0x7f000000)>>24);
273 if(byte0 > 0x24) // Max power index = 0x24
274 byte0 = 0x24;
275 if(byte1 > 0x24)
276 byte1 = 0x24;
277 if(byte2 > 0x24)
278 byte2 = 0x24;
279 if(byte3 > 0x24)
280 byte3 = 0x24;
281
282 if(index == 3)
283 {
284 writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
285 priv->Pwr_Track = writeVal_tmp;
286 }
287
288 if(priv->bDynamicTxHighPower == true) //Add by Jacken 2008/03/06 //when DM implement, add this
289 {
290 writeVal = 0x03030303;
291 }
292 else
293 {
294 writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
295 }
296 rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
297 }
ecdfa446
GKH
298}
299
300#define MAX_DOZE_WAITING_TIMES_9x 64
5e1ad18a 301static bool
6f304eb2 302SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState)
ecdfa446
GKH
303{
304 struct r8192_priv *priv = ieee80211_priv(dev);
305 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
306 bool bResult = true;
ecdfa446 307 u8 i = 0, QueueID = 0;
65a43784 308 struct rtl8192_tx_ring *ring = NULL;
ecdfa446
GKH
309
310 if(priv->SetRFPowerStateInProgress == true)
311 return false;
ecdfa446
GKH
312 priv->SetRFPowerStateInProgress = true;
313
6f304eb2 314 switch( eRFPowerState )
ecdfa446 315 {
6f304eb2
MM
316 case eRfOn:
317
318 // turn on RF
319 if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
320 { // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC.
321 bool rtstatus = true;
322 u32 InitializeCount = 3;
323 do
324 {
325 InitializeCount--;
326 rtstatus = NicIFEnableNIC(dev);
327 }while( (rtstatus != true) &&(InitializeCount >0) );
328
329 if(rtstatus != true)
330 {
331 RT_TRACE(COMP_ERR,"%s():Initialize Adapter fail,return\n",__FUNCTION__);
332 priv->SetRFPowerStateInProgress = false;
333 return false;
334 }
335
336 RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
337 } else {
338 write_nic_byte(priv, ANAPAR, 0x37);//160MHz
339 mdelay(1);
340 //enable clock 80/88 MHz
341 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2]
342 priv->bHwRfOffAction = 0;
343
344 //RF-A, RF-B
345 //enable RF-Chip A/B
346 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4]
347 //analog to digital on
348 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
349 //digital to analog on
350 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3]
351 //rx antenna on
352 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
353 //rx antenna on
354 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
355 //analog to digital part2 on
356 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
357
358 }
359
360 break;
361
362 //
363 // In current solution, RFSleep=RFOff in order to save power under 802.11 power save.
364 // By Bruce, 2008-01-16.
365 //
366 case eRfSleep:
367
368 // HW setting had been configured with deeper mode.
369 if(priv->ieee80211->eRFPowerState == eRfOff)
370 break;
371
372 for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
ecdfa446 373 {
6f304eb2 374 ring = &priv->tx_ring[QueueID];
65a43784 375
6f304eb2
MM
376 if(skb_queue_len(&ring->queue) == 0)
377 {
378 QueueID++;
379 continue;
380 }
381 else
382 {
383 RT_TRACE((COMP_POWER|COMP_RF), "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
384 udelay(10);
385 i++;
386 }
65a43784 387
6f304eb2
MM
388 if(i >= MAX_DOZE_WAITING_TIMES_9x)
389 {
390 RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
d2bddcf8 391 break;
6f304eb2
MM
392 }
393 }
ecdfa446 394
6f304eb2 395 PHY_SetRtl8192eRfOff(dev);
ecdfa446 396
6f304eb2 397 break;
ecdfa446 398
6f304eb2 399 case eRfOff:
ecdfa446 400
6f304eb2
MM
401 //
402 // Disconnect with Any AP or STA.
403 //
404 for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
405 {
406 ring = &priv->tx_ring[QueueID];
d2bddcf8 407
6f304eb2
MM
408 if(skb_queue_len(&ring->queue) == 0)
409 {
410 QueueID++;
411 continue;
412 }
413 else
414 {
415 RT_TRACE(COMP_POWER,
416 "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
417 udelay(10);
418 i++;
419 }
65a43784 420
6f304eb2
MM
421 if(i >= MAX_DOZE_WAITING_TIMES_9x)
422 {
423 RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
4803ef77 424 break;
6f304eb2 425 }
ecdfa446
GKH
426 }
427
6f304eb2
MM
428
429 if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
430 {
431 /* Disable all components. */
432 NicIFDisableNIC(dev);
433 RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
434 }
435 else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC))
436 {
437 /* Normal case - IPS should go to this. */
438 PHY_SetRtl8192eRfOff(dev);
439 }
ecdfa446
GKH
440 break;
441
6f304eb2
MM
442 default:
443 bResult = false;
444 RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState);
445 break;
ecdfa446
GKH
446 }
447
448 if(bResult)
449 {
450 // Update current RF state variable.
451 priv->ieee80211->eRFPowerState = eRFPowerState;
ecdfa446
GKH
452 }
453
454 priv->SetRFPowerStateInProgress = false;
ecdfa446
GKH
455 return bResult;
456}
457
458
459
460//
461// Description:
462// Change RF power state.
463//
464// Assumption:
465// This function must be executed in re-schdulable context,
466// ie. PASSIVE_LEVEL.
467//
468// 050823, by rcnjko.
469//
5e1ad18a 470static bool
ecdfa446
GKH
471SetRFPowerState(
472 struct net_device* dev,
473 RT_RF_POWER_STATE eRFPowerState
474 )
475{
476 struct r8192_priv *priv = ieee80211_priv(dev);
477
478 bool bResult = false;
479
480 RT_TRACE(COMP_RF,"---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
ecdfa446 481 if(eRFPowerState == priv->ieee80211->eRFPowerState && priv->bHwRfOffAction == 0)
ecdfa446
GKH
482 {
483 RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
484 return bResult;
485 }
486
487 bResult = SetRFPowerState8190(dev, eRFPowerState);
488
489 RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): bResult(%d)\n", bResult);
490
491 return bResult;
492}
493
5e1ad18a 494static void
ecdfa446
GKH
495MgntDisconnectIBSS(
496 struct net_device* dev
497)
498{
499 struct r8192_priv *priv = ieee80211_priv(dev);
500 //RT_OP_MODE OpMode;
501 u8 i;
502 bool bFilterOutNonAssociatedBSSID = false;
503
ecdfa446
GKH
504 priv->ieee80211->state = IEEE80211_NOLINK;
505
506// PlatformZeroMemory( pMgntInfo->Bssid, 6 );
507 for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i]= 0x55;
508 priv->OpMode = RT_OP_MODE_NO_LINK;
3f9ab1ee
MM
509 write_nic_word(priv, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]);
510 write_nic_dword(priv, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]);
ecdfa446
GKH
511 {
512 RT_OP_MODE OpMode = priv->OpMode;
513 //LED_CTL_MODE LedAction = LED_CTL_NO_LINK;
3f9ab1ee 514 u8 btMsr = read_nic_byte(priv, MSR);
ecdfa446
GKH
515
516 btMsr &= 0xfc;
517
518 switch(OpMode)
519 {
520 case RT_OP_MODE_INFRASTRUCTURE:
521 btMsr |= MSR_LINK_MANAGED;
522 //LedAction = LED_CTL_LINK;
523 break;
524
525 case RT_OP_MODE_IBSS:
526 btMsr |= MSR_LINK_ADHOC;
935e99fb 527 // led link set separate
ecdfa446
GKH
528 break;
529
530 case RT_OP_MODE_AP:
531 btMsr |= MSR_LINK_MASTER;
532 //LedAction = LED_CTL_LINK;
533 break;
534
535 default:
536 btMsr |= MSR_LINK_NONE;
537 break;
538 }
539
3f9ab1ee 540 write_nic_byte(priv, MSR, btMsr);
ecdfa446
GKH
541
542 // LED control
543 //Adapter->HalFunc.LedControlHandler(Adapter, LedAction);
544 }
545 ieee80211_stop_send_beacons(priv->ieee80211);
546
547 // If disconnect, clear RCR CBSSID bit
548 bFilterOutNonAssociatedBSSID = false;
549 {
550 u32 RegRCR, Type;
551 Type = bFilterOutNonAssociatedBSSID;
3f9ab1ee 552 RegRCR = read_nic_dword(priv, RCR);
ecdfa446
GKH
553 priv->ReceiveConfig = RegRCR;
554 if (Type == true)
555 RegRCR |= (RCR_CBSSID);
556 else if (Type == false)
557 RegRCR &= (~RCR_CBSSID);
558
559 {
3f9ab1ee 560 write_nic_dword(priv, RCR, RegRCR);
ecdfa446
GKH
561 priv->ReceiveConfig = RegRCR;
562 }
563
564 }
565 //MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE );
566 notify_wx_assoc_event(priv->ieee80211);
567
568}
569
5e1ad18a 570static void
ecdfa446
GKH
571MlmeDisassociateRequest(
572 struct net_device* dev,
573 u8* asSta,
574 u8 asRsn
575 )
576{
577 struct r8192_priv *priv = ieee80211_priv(dev);
578 u8 i;
579
580 RemovePeerTS(priv->ieee80211, asSta);
581
582 SendDisassociation( priv->ieee80211, asSta, asRsn );
583
5e1ad18a 584 if(memcpy(priv->ieee80211->current_network.bssid,asSta,6) == NULL)
ecdfa446
GKH
585 {
586 //ShuChen TODO: change media status.
587 //ShuChen TODO: What to do when disassociate.
588 priv->ieee80211->state = IEEE80211_NOLINK;
589 //pMgntInfo->AsocTimestamp = 0;
590 for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22;
591// pMgntInfo->mBrates.Length = 0;
592// Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) );
593 priv->OpMode = RT_OP_MODE_NO_LINK;
594 {
595 RT_OP_MODE OpMode = priv->OpMode;
596 //LED_CTL_MODE LedAction = LED_CTL_NO_LINK;
3f9ab1ee 597 u8 btMsr = read_nic_byte(priv, MSR);
ecdfa446
GKH
598
599 btMsr &= 0xfc;
600
601 switch(OpMode)
602 {
603 case RT_OP_MODE_INFRASTRUCTURE:
604 btMsr |= MSR_LINK_MANAGED;
605 //LedAction = LED_CTL_LINK;
606 break;
607
608 case RT_OP_MODE_IBSS:
609 btMsr |= MSR_LINK_ADHOC;
935e99fb 610 // led link set separate
ecdfa446
GKH
611 break;
612
613 case RT_OP_MODE_AP:
614 btMsr |= MSR_LINK_MASTER;
615 //LedAction = LED_CTL_LINK;
616 break;
617
618 default:
619 btMsr |= MSR_LINK_NONE;
620 break;
621 }
622
3f9ab1ee 623 write_nic_byte(priv, MSR, btMsr);
ecdfa446
GKH
624
625 // LED control
626 //Adapter->HalFunc.LedControlHandler(Adapter, LedAction);
627 }
628 ieee80211_disassociate(priv->ieee80211);
629
3f9ab1ee
MM
630 write_nic_word(priv, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]);
631 write_nic_dword(priv, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]);
ecdfa446
GKH
632
633 }
634
635}
636
637
5e1ad18a 638static void
ecdfa446
GKH
639MgntDisconnectAP(
640 struct net_device* dev,
641 u8 asRsn
642)
643{
644 struct r8192_priv *priv = ieee80211_priv(dev);
645 bool bFilterOutNonAssociatedBSSID = false;
646
647//
648// Commented out by rcnjko, 2005.01.27:
649// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
650//
651// //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
652// SecClearAllKeys(Adapter);
653
654 // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
655#ifdef TO_DO
656 if( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch ||
657 (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) ) // In CCKM mode will Clear key
658 {
659 SecClearAllKeys(Adapter);
660 RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key..."))
661 }
662#endif
663 // If disconnect, clear RCR CBSSID bit
664 bFilterOutNonAssociatedBSSID = false;
665 {
666 u32 RegRCR, Type;
667
668 Type = bFilterOutNonAssociatedBSSID;
669 //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RCR, (pu1Byte)(&RegRCR));
3f9ab1ee 670 RegRCR = read_nic_dword(priv, RCR);
ecdfa446
GKH
671 priv->ReceiveConfig = RegRCR;
672
673 if (Type == true)
674 RegRCR |= (RCR_CBSSID);
675 else if (Type == false)
676 RegRCR &= (~RCR_CBSSID);
677
3f9ab1ee 678 write_nic_dword(priv, RCR, RegRCR);
ecdfa446
GKH
679 priv->ReceiveConfig = RegRCR;
680
681
682 }
683 // 2004.10.11, by rcnjko.
684 //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss );
685 MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn );
686
687 priv->ieee80211->state = IEEE80211_NOLINK;
688 //pMgntInfo->AsocTimestamp = 0;
689}
690
691
5e1ad18a 692static bool
ecdfa446
GKH
693MgntDisconnect(
694 struct net_device* dev,
695 u8 asRsn
696)
697{
698 struct r8192_priv *priv = ieee80211_priv(dev);
699
700 //
701 // Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
702 //
703#ifdef TO_DO
704 if(pMgntInfo->mPss != eAwake)
705 {
706 //
707 // Using AwkaeTimer to prevent mismatch ps state.
708 // In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31.
709 //
710 // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) );
711 PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 );
712 }
713#endif
714 // Follow 8180 AP mode, 2005.05.30, by rcnjko.
715#ifdef TO_DO
716 if(pMgntInfo->mActingAsAp)
717 {
718 RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> AP_DisassociateAllStation\n"));
719 AP_DisassociateAllStation(Adapter, unspec_reason);
720 return TRUE;
721 }
722#endif
723 // Indication of disassociation event.
724 //DrvIFIndicateDisassociation(Adapter, asRsn);
725
726 // In adhoc mode, update beacon frame.
727 if( priv->ieee80211->state == IEEE80211_LINKED )
728 {
729 if( priv->ieee80211->iw_mode == IW_MODE_ADHOC )
730 {
ecdfa446
GKH
731 MgntDisconnectIBSS(dev);
732 }
733 if( priv->ieee80211->iw_mode == IW_MODE_INFRA )
734 {
735 // We clear key here instead of MgntDisconnectAP() because that
736 // MgntActSet_802_11_DISASSOCIATE() is an interface called by OS,
737 // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
738 // used to handle disassociation related things to AP, e.g. send Disassoc
739 // frame to AP. 2005.01.27, by rcnjko.
ecdfa446
GKH
740 MgntDisconnectAP(dev, asRsn);
741 }
742
743 // Inidicate Disconnect, 2005.02.23, by rcnjko.
744 //MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE);
745 }
746
747 return true;
748}
749
750//
751// Description:
752// Chang RF Power State.
753// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
754//
755// Assumption:
756// PASSIVE LEVEL.
757//
758bool
759MgntActSet_RF_State(
760 struct net_device* dev,
761 RT_RF_POWER_STATE StateToSet,
762 RT_RF_CHANGE_SOURCE ChangeSource
763 )
764{
765 struct r8192_priv *priv = ieee80211_priv(dev);
766 bool bActionAllowed = false;
767 bool bConnectBySSID = false;
768 RT_RF_POWER_STATE rtState;
769 u16 RFWaitCounter = 0;
770 unsigned long flag;
771 RT_TRACE(COMP_POWER, "===>MgntActSet_RF_State(): StateToSet(%d)\n",StateToSet);
772
773 //1//
774 //1//<1>Prevent the race condition of RF state change.
775 //1//
776 // Only one thread can change the RF state at one time, and others should wait to be executed. By Bruce, 2007-11-28.
777
778 while(true)
779 {
780 spin_lock_irqsave(&priv->rf_ps_lock,flag);
781 if(priv->RFChangeInProgress)
782 {
783 spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
784 RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet);
785
786 // Set RF after the previous action is done.
787 while(priv->RFChangeInProgress)
788 {
789 RFWaitCounter ++;
790 RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter);
791 udelay(1000); // 1 ms
792
793 // Wait too long, return FALSE to avoid to be stuck here.
794 if(RFWaitCounter > 100)
795 {
796 RT_TRACE(COMP_ERR, "MgntActSet_RF_State(): Wait too logn to set RF\n");
797 // TODO: Reset RF state?
798 return false;
799 }
800 }
801 }
802 else
803 {
804 priv->RFChangeInProgress = true;
805 spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
806 break;
807 }
808 }
809
810 rtState = priv->ieee80211->eRFPowerState;
811
812 switch(StateToSet)
813 {
814 case eRfOn:
815 //
816 // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
817 // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
818 //
819
820 priv->ieee80211->RfOffReason &= (~ChangeSource);
821
822 if(! priv->ieee80211->RfOffReason)
823 {
824 priv->ieee80211->RfOffReason = 0;
825 bActionAllowed = true;
826
827
828 if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW )
829 {
830 bConnectBySSID = true;
831 }
832 }
833 else
834 RT_TRACE(COMP_POWER, "MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->ieee80211->RfOffReason, ChangeSource);
835
836 break;
837
838 case eRfOff:
839
840 if (priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
841 {
842 //
843 // 060808, Annie:
844 // Disconnect to current BSS when radio off. Asked by QuanTa.
845 //
846 // Set all link status falg, by Bruce, 2007-06-26.
847 //MgntActSet_802_11_DISASSOCIATE( Adapter, disas_lv_ss );
848 MgntDisconnect(dev, disas_lv_ss);
849
850 // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
851 // 2007.05.28, by shien chang.
852
853 }
854
855
856 priv->ieee80211->RfOffReason |= ChangeSource;
857 bActionAllowed = true;
858 break;
859
860 case eRfSleep:
861 priv->ieee80211->RfOffReason |= ChangeSource;
862 bActionAllowed = true;
863 break;
864
865 default:
866 break;
867 }
868
869 if(bActionAllowed)
870 {
871 RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->ieee80211->RfOffReason);
872 // Config HW to the specified mode.
873 SetRFPowerState(dev, StateToSet);
874 // Turn on RF.
875 if(StateToSet == eRfOn)
876 {
877 //Adapter->HalFunc.HalEnableRxHandler(Adapter);
878 if(bConnectBySSID)
879 {
880 //MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
881 }
882 }
883 // Turn off RF.
884 else if(StateToSet == eRfOff)
885 {
886 //Adapter->HalFunc.HalDisableRxHandler(Adapter);
887 }
888 }
889 else
890 {
891 RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->ieee80211->RfOffReason);
892 }
893
894 // Release RF spinlock
895 spin_lock_irqsave(&priv->rf_ps_lock,flag);
896 priv->RFChangeInProgress = false;
897 spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
898
899 RT_TRACE(COMP_POWER, "<===MgntActSet_RF_State()\n");
900 return bActionAllowed;
901}
902
903
This page took 0.20324 seconds and 5 git commands to generate.