/drivers/staging/rtl8192e/r8190_rtl8256.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2 · C · 677 lines · 463 code · 120 blank · 94 comment · 87 complexity · db4cdb97833e01758725545d82bc5c2d MD5 · raw file

  1. /*
  2. This is part of the rtl8192 driver
  3. released under the GPL (See file COPYING for details).
  4. This files contains programming code for the rtl8256
  5. radio frontend.
  6. *Many* thanks to Realtek Corp. for their great support!
  7. */
  8. #include "r8192E.h"
  9. #include "r8192E_hw.h"
  10. #include "r819xE_phyreg.h"
  11. #include "r819xE_phy.h"
  12. #include "r8190_rtl8256.h"
  13. /*--------------------------------------------------------------------------
  14. * Overview: set RF band width (20M or 40M)
  15. * Input: struct net_device* dev
  16. * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M
  17. * Output: NONE
  18. * Return: NONE
  19. * Note: 8226 support both 20M and 40 MHz
  20. *---------------------------------------------------------------------------*/
  21. void PHY_SetRF8256Bandwidth(struct r8192_priv *priv, HT_CHANNEL_WIDTH Bandwidth) //20M or 40M
  22. {
  23. u8 eRFPath;
  24. //for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
  25. for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
  26. {
  27. if (!rtl8192_phy_CheckIsLegalRFPath(priv, eRFPath))
  28. continue;
  29. switch(Bandwidth)
  30. {
  31. case HT_CHANNEL_WIDTH_20:
  32. if(priv->card_8192_version == VERSION_8190_BD || priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later!
  33. {
  34. rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba
  35. rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7);
  36. rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021);
  37. //cosa add for sd3's request 01/23/2008
  38. //rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
  39. }
  40. else
  41. {
  42. RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
  43. }
  44. break;
  45. case HT_CHANNEL_WIDTH_20_40:
  46. if(priv->card_8192_version == VERSION_8190_BD ||priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later!
  47. {
  48. rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba
  49. rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3ff);
  50. rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0e1);
  51. }
  52. else
  53. {
  54. RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
  55. }
  56. break;
  57. default:
  58. RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
  59. break;
  60. }
  61. }
  62. }
  63. /*--------------------------------------------------------------------------
  64. * Overview: Interface to config 8256
  65. * Input: struct net_device* dev
  66. * Output: NONE
  67. * Return: NONE
  68. *---------------------------------------------------------------------------*/
  69. RT_STATUS PHY_RF8256_Config(struct r8192_priv *priv)
  70. {
  71. // Initialize general global value
  72. //
  73. RT_STATUS rtStatus = RT_STATUS_SUCCESS;
  74. // TODO: Extend RF_PATH_C and RF_PATH_D in the future
  75. priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
  76. // Config BB and RF
  77. rtStatus = phy_RF8256_Config_ParaFile(priv);
  78. return rtStatus;
  79. }
  80. /*--------------------------------------------------------------------------
  81. * Overview: Interface to config 8256
  82. * Input: struct net_device* dev
  83. * Output: NONE
  84. * Return: NONE
  85. *---------------------------------------------------------------------------*/
  86. RT_STATUS phy_RF8256_Config_ParaFile(struct r8192_priv *priv)
  87. {
  88. u32 u4RegValue = 0;
  89. u8 eRFPath;
  90. RT_STATUS rtStatus = RT_STATUS_SUCCESS;
  91. BB_REGISTER_DEFINITION_T *pPhyReg;
  92. u32 RegOffSetToBeCheck = 0x3;
  93. u32 RegValueToBeCheck = 0x7f1;
  94. u32 RF3_Final_Value = 0;
  95. u8 ConstRetryTimes = 5, RetryTimes = 5;
  96. u8 ret = 0;
  97. //3//-----------------------------------------------------------------
  98. //3// <2> Initialize RF
  99. //3//-----------------------------------------------------------------
  100. for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++)
  101. {
  102. if (!rtl8192_phy_CheckIsLegalRFPath(priv, eRFPath))
  103. continue;
  104. pPhyReg = &priv->PHYRegDef[eRFPath];
  105. /*----Store original RFENV control type----*/
  106. switch(eRFPath)
  107. {
  108. case RF90_PATH_A:
  109. case RF90_PATH_C:
  110. u4RegValue = rtl8192_QueryBBReg(priv, pPhyReg->rfintfs, bRFSI_RFENV);
  111. break;
  112. case RF90_PATH_B :
  113. case RF90_PATH_D:
  114. u4RegValue = rtl8192_QueryBBReg(priv, pPhyReg->rfintfs, bRFSI_RFENV<<16);
  115. break;
  116. }
  117. /*----Set RF_ENV enable----*/
  118. rtl8192_setBBreg(priv, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
  119. /*----Set RF_ENV output high----*/
  120. rtl8192_setBBreg(priv, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
  121. /* Set bit number of Address and Data for RF register */
  122. rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258
  123. rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ???
  124. rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf);
  125. /*----Check RF block (for FPGA platform only)----*/
  126. // TODO: this function should be removed on ASIC , Emily 2007.2.2
  127. rtStatus = rtl8192_phy_checkBBAndRF(priv, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath);
  128. if(rtStatus!= RT_STATUS_SUCCESS)
  129. {
  130. RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath);
  131. goto phy_RF8256_Config_ParaFile_Fail;
  132. }
  133. RetryTimes = ConstRetryTimes;
  134. RF3_Final_Value = 0;
  135. /*----Initialize RF fom connfiguration file----*/
  136. switch(eRFPath)
  137. {
  138. case RF90_PATH_A:
  139. while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
  140. {
  141. ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath);
  142. RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
  143. RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
  144. RetryTimes--;
  145. }
  146. break;
  147. case RF90_PATH_B:
  148. while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
  149. {
  150. ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath);
  151. RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
  152. RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
  153. RetryTimes--;
  154. }
  155. break;
  156. case RF90_PATH_C:
  157. while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
  158. {
  159. ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath);
  160. RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
  161. RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
  162. RetryTimes--;
  163. }
  164. break;
  165. case RF90_PATH_D:
  166. while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
  167. {
  168. ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath);
  169. RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
  170. RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
  171. RetryTimes--;
  172. }
  173. break;
  174. }
  175. /*----Restore RFENV control type----*/;
  176. switch(eRFPath)
  177. {
  178. case RF90_PATH_A:
  179. case RF90_PATH_C:
  180. rtl8192_setBBreg(priv, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
  181. break;
  182. case RF90_PATH_B :
  183. case RF90_PATH_D:
  184. rtl8192_setBBreg(priv, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
  185. break;
  186. }
  187. if(ret){
  188. RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
  189. goto phy_RF8256_Config_ParaFile_Fail;
  190. }
  191. }
  192. RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ;
  193. return RT_STATUS_SUCCESS;
  194. phy_RF8256_Config_ParaFile_Fail:
  195. RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ;
  196. return RT_STATUS_FAILURE;
  197. }
  198. void PHY_SetRF8256CCKTxPower(struct r8192_priv *priv, u8 powerlevel)
  199. {
  200. u32 TxAGC=0;
  201. TxAGC = powerlevel;
  202. if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range
  203. {
  204. if(priv->CustomerID == RT_CID_819x_Netcore)
  205. TxAGC = 0x22;
  206. else
  207. TxAGC += priv->CckPwEnl;
  208. }
  209. if(TxAGC > 0x24)
  210. TxAGC = 0x24;
  211. rtl8192_setBBreg(priv, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
  212. }
  213. void PHY_SetRF8256OFDMTxPower(struct r8192_priv *priv, u8 powerlevel)
  214. {
  215. u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
  216. u8 index = 0;
  217. u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
  218. u8 byte0, byte1, byte2, byte3;
  219. powerBase0 = powerlevel + priv->LegacyHTTxPowerDiff; //OFDM rates
  220. powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
  221. powerBase1 = powerlevel; //MCS rates
  222. powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
  223. for(index=0; index<6; index++)
  224. {
  225. writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
  226. byte0 = (u8)(writeVal & 0x7f);
  227. byte1 = (u8)((writeVal & 0x7f00)>>8);
  228. byte2 = (u8)((writeVal & 0x7f0000)>>16);
  229. byte3 = (u8)((writeVal & 0x7f000000)>>24);
  230. if(byte0 > 0x24) // Max power index = 0x24
  231. byte0 = 0x24;
  232. if(byte1 > 0x24)
  233. byte1 = 0x24;
  234. if(byte2 > 0x24)
  235. byte2 = 0x24;
  236. if(byte3 > 0x24)
  237. byte3 = 0x24;
  238. if(index == 3)
  239. {
  240. writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
  241. priv->Pwr_Track = writeVal_tmp;
  242. }
  243. if(priv->bDynamicTxHighPower == true) //Add by Jacken 2008/03/06 //when DM implement, add this
  244. {
  245. writeVal = 0x03030303;
  246. }
  247. else
  248. {
  249. writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
  250. }
  251. rtl8192_setBBreg(priv, RegOffset[index], 0x7f7f7f7f, writeVal);
  252. }
  253. }
  254. #define MAX_DOZE_WAITING_TIMES_9x 64
  255. static void r8192e_drain_tx_queues(struct r8192_priv *priv)
  256. {
  257. u8 i, QueueID;
  258. for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
  259. {
  260. struct rtl8192_tx_ring *ring = &priv->tx_ring[QueueID];
  261. if(skb_queue_len(&ring->queue) == 0)
  262. {
  263. QueueID++;
  264. continue;
  265. }
  266. udelay(10);
  267. i++;
  268. if (i >= MAX_DOZE_WAITING_TIMES_9x)
  269. {
  270. RT_TRACE(COMP_POWER, "r8192e_drain_tx_queues() timeout queue %d\n", QueueID);
  271. break;
  272. }
  273. }
  274. }
  275. static bool SetRFPowerState8190(struct r8192_priv *priv,
  276. RT_RF_POWER_STATE eRFPowerState)
  277. {
  278. PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl;
  279. bool bResult = true;
  280. if (eRFPowerState == priv->eRFPowerState &&
  281. priv->bHwRfOffAction == 0) {
  282. bResult = false;
  283. goto out;
  284. }
  285. switch( eRFPowerState )
  286. {
  287. case eRfOn:
  288. // turn on RF
  289. if ((priv->eRFPowerState == eRfOff) &&
  290. RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
  291. {
  292. /*
  293. * The current RF state is OFF and the RF OFF level
  294. * is halting the NIC, re-initialize the NIC.
  295. */
  296. if (!NicIFEnableNIC(priv)) {
  297. RT_TRACE(COMP_ERR, "%s(): NicIFEnableNIC failed\n",__FUNCTION__);
  298. bResult = false;
  299. goto out;
  300. }
  301. RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
  302. } else {
  303. write_nic_byte(priv, ANAPAR, 0x37);//160MHz
  304. mdelay(1);
  305. //enable clock 80/88 MHz
  306. rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2]
  307. priv->bHwRfOffAction = 0;
  308. //RF-A, RF-B
  309. //enable RF-Chip A/B
  310. rtl8192_setBBreg(priv, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4]
  311. //analog to digital on
  312. rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
  313. //digital to analog on
  314. rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3]
  315. //rx antenna on
  316. rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
  317. //rx antenna on
  318. rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
  319. //analog to digital part2 on
  320. rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
  321. }
  322. break;
  323. //
  324. // In current solution, RFSleep=RFOff in order to save power under 802.11 power save.
  325. // By Bruce, 2008-01-16.
  326. //
  327. case eRfSleep:
  328. // HW setting had been configured with deeper mode.
  329. if(priv->eRFPowerState == eRfOff)
  330. break;
  331. r8192e_drain_tx_queues(priv);
  332. PHY_SetRtl8192eRfOff(priv);
  333. break;
  334. case eRfOff:
  335. //
  336. // Disconnect with Any AP or STA.
  337. //
  338. r8192e_drain_tx_queues(priv);
  339. if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
  340. {
  341. /* Disable all components. */
  342. NicIFDisableNIC(priv);
  343. RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
  344. }
  345. else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC))
  346. {
  347. /* Normal case - IPS should go to this. */
  348. PHY_SetRtl8192eRfOff(priv);
  349. }
  350. break;
  351. default:
  352. bResult = false;
  353. RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState);
  354. break;
  355. }
  356. if(bResult)
  357. {
  358. // Update current RF state variable.
  359. priv->eRFPowerState = eRFPowerState;
  360. }
  361. out:
  362. return bResult;
  363. }
  364. static void MgntDisconnectIBSS(struct r8192_priv *priv)
  365. {
  366. u8 i;
  367. bool bFilterOutNonAssociatedBSSID = false;
  368. priv->ieee80211->state = IEEE80211_NOLINK;
  369. for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i]= 0x55;
  370. priv->OpMode = RT_OP_MODE_NO_LINK;
  371. write_nic_word(priv, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]);
  372. write_nic_dword(priv, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]);
  373. {
  374. RT_OP_MODE OpMode = priv->OpMode;
  375. u8 btMsr = read_nic_byte(priv, MSR);
  376. btMsr &= 0xfc;
  377. switch(OpMode)
  378. {
  379. case RT_OP_MODE_INFRASTRUCTURE:
  380. btMsr |= MSR_LINK_MANAGED;
  381. break;
  382. case RT_OP_MODE_IBSS:
  383. btMsr |= MSR_LINK_ADHOC;
  384. // led link set separate
  385. break;
  386. case RT_OP_MODE_AP:
  387. btMsr |= MSR_LINK_MASTER;
  388. break;
  389. default:
  390. btMsr |= MSR_LINK_NONE;
  391. break;
  392. }
  393. write_nic_byte(priv, MSR, btMsr);
  394. }
  395. ieee80211_stop_send_beacons(priv->ieee80211);
  396. // If disconnect, clear RCR CBSSID bit
  397. bFilterOutNonAssociatedBSSID = false;
  398. {
  399. u32 RegRCR, Type;
  400. Type = bFilterOutNonAssociatedBSSID;
  401. RegRCR = read_nic_dword(priv, RCR);
  402. priv->ReceiveConfig = RegRCR;
  403. if (Type == true)
  404. RegRCR |= (RCR_CBSSID);
  405. else if (Type == false)
  406. RegRCR &= (~RCR_CBSSID);
  407. {
  408. write_nic_dword(priv, RCR, RegRCR);
  409. priv->ReceiveConfig = RegRCR;
  410. }
  411. }
  412. notify_wx_assoc_event(priv->ieee80211);
  413. }
  414. static void MlmeDisassociateRequest(struct r8192_priv *priv, u8 *asSta,
  415. u8 asRsn)
  416. {
  417. u8 i;
  418. RemovePeerTS(priv->ieee80211, asSta);
  419. SendDisassociation( priv->ieee80211, asSta, asRsn );
  420. if(memcpy(priv->ieee80211->current_network.bssid,asSta,6) == NULL)
  421. {
  422. //ShuChen TODO: change media status.
  423. //ShuChen TODO: What to do when disassociate.
  424. priv->ieee80211->state = IEEE80211_NOLINK;
  425. for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22;
  426. priv->OpMode = RT_OP_MODE_NO_LINK;
  427. {
  428. RT_OP_MODE OpMode = priv->OpMode;
  429. u8 btMsr = read_nic_byte(priv, MSR);
  430. btMsr &= 0xfc;
  431. switch(OpMode)
  432. {
  433. case RT_OP_MODE_INFRASTRUCTURE:
  434. btMsr |= MSR_LINK_MANAGED;
  435. break;
  436. case RT_OP_MODE_IBSS:
  437. btMsr |= MSR_LINK_ADHOC;
  438. // led link set separate
  439. break;
  440. case RT_OP_MODE_AP:
  441. btMsr |= MSR_LINK_MASTER;
  442. break;
  443. default:
  444. btMsr |= MSR_LINK_NONE;
  445. break;
  446. }
  447. write_nic_byte(priv, MSR, btMsr);
  448. }
  449. ieee80211_disassociate(priv->ieee80211);
  450. write_nic_word(priv, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]);
  451. write_nic_dword(priv, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]);
  452. }
  453. }
  454. static void MgntDisconnectAP(struct r8192_priv *priv, u8 asRsn)
  455. {
  456. bool bFilterOutNonAssociatedBSSID = false;
  457. u32 RegRCR, Type;
  458. /* If disconnect, clear RCR CBSSID bit */
  459. bFilterOutNonAssociatedBSSID = false;
  460. Type = bFilterOutNonAssociatedBSSID;
  461. RegRCR = read_nic_dword(priv, RCR);
  462. priv->ReceiveConfig = RegRCR;
  463. if (Type == true)
  464. RegRCR |= (RCR_CBSSID);
  465. else if (Type == false)
  466. RegRCR &= (~RCR_CBSSID);
  467. write_nic_dword(priv, RCR, RegRCR);
  468. priv->ReceiveConfig = RegRCR;
  469. MlmeDisassociateRequest(priv, priv->ieee80211->current_network.bssid, asRsn);
  470. priv->ieee80211->state = IEEE80211_NOLINK;
  471. }
  472. static bool MgntDisconnect(struct r8192_priv *priv, u8 asRsn)
  473. {
  474. // In adhoc mode, update beacon frame.
  475. if( priv->ieee80211->state == IEEE80211_LINKED )
  476. {
  477. if( priv->ieee80211->iw_mode == IW_MODE_ADHOC )
  478. {
  479. MgntDisconnectIBSS(priv);
  480. }
  481. if( priv->ieee80211->iw_mode == IW_MODE_INFRA )
  482. {
  483. // We clear key here instead of MgntDisconnectAP() because that
  484. // MgntActSet_802_11_DISASSOCIATE() is an interface called by OS,
  485. // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
  486. // used to handle disassociation related things to AP, e.g. send Disassoc
  487. // frame to AP. 2005.01.27, by rcnjko.
  488. MgntDisconnectAP(priv, asRsn);
  489. }
  490. }
  491. return true;
  492. }
  493. //
  494. // Description:
  495. // Chang RF Power State.
  496. // Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
  497. //
  498. // Assumption:
  499. // PASSIVE LEVEL.
  500. //
  501. bool MgntActSet_RF_State(struct r8192_priv *priv, RT_RF_POWER_STATE StateToSet,
  502. RT_RF_CHANGE_SOURCE ChangeSource)
  503. {
  504. bool bActionAllowed = false;
  505. bool bConnectBySSID = false;
  506. RT_RF_POWER_STATE rtState;
  507. RT_TRACE(COMP_POWER, "===>MgntActSet_RF_State(): StateToSet(%d)\n",StateToSet);
  508. spin_lock(&priv->rf_ps_lock);
  509. rtState = priv->eRFPowerState;
  510. switch(StateToSet)
  511. {
  512. case eRfOn:
  513. priv->RfOffReason &= (~ChangeSource);
  514. if (!priv->RfOffReason)
  515. {
  516. priv->RfOffReason = 0;
  517. bActionAllowed = true;
  518. if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW )
  519. {
  520. bConnectBySSID = true;
  521. }
  522. }
  523. else
  524. RT_TRACE(COMP_POWER, "MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource);
  525. break;
  526. case eRfOff:
  527. if (priv->RfOffReason > RF_CHANGE_BY_IPS)
  528. {
  529. // Disconnect to current BSS when radio off. Asked by QuanTa.
  530. MgntDisconnect(priv, disas_lv_ss);
  531. }
  532. priv->RfOffReason |= ChangeSource;
  533. bActionAllowed = true;
  534. break;
  535. case eRfSleep:
  536. priv->RfOffReason |= ChangeSource;
  537. bActionAllowed = true;
  538. break;
  539. }
  540. if (bActionAllowed)
  541. {
  542. RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason);
  543. // Config HW to the specified mode.
  544. SetRFPowerState8190(priv, StateToSet);
  545. }
  546. else
  547. {
  548. RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->RfOffReason);
  549. }
  550. // Release RF spinlock
  551. spin_unlock(&priv->rf_ps_lock);
  552. RT_TRACE(COMP_POWER, "<===MgntActSet_RF_State()\n");
  553. return bActionAllowed;
  554. }