ps.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2009-2012 Realtek Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. * The full GNU General Public License is included in this distribution in the
  19. * file called LICENSE.
  20. *
  21. * Contact Information:
  22. * wlanfae <wlanfae@realtek.com>
  23. * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  24. * Hsinchu 300, Taiwan.
  25. *
  26. * Larry Finger <Larry.Finger@lwfinger.net>
  27. *
  28. *****************************************************************************/
  29. #include <linux/export.h>
  30. #include "wifi.h"
  31. #include "base.h"
  32. #include "ps.h"
  33. /* Description:
  34. * This routine deals with the Power Configuration CMD
  35. * parsing for RTL8723/RTL8188E Series IC.
  36. * Assumption:
  37. * We should follow specific format that was released from HW SD.
  38. */
  39. bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
  40. u8 faversion, u8 interface_type,
  41. struct wlan_pwr_cfg pwrcfgcmd[])
  42. {
  43. struct wlan_pwr_cfg cfg_cmd = {0};
  44. bool polling_bit = false;
  45. u32 ary_idx = 0;
  46. u8 value = 0;
  47. u32 offset = 0;
  48. u32 polling_count = 0;
  49. u32 max_polling_cnt = 5000;
  50. do {
  51. cfg_cmd = pwrcfgcmd[ary_idx];
  52. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  53. "rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x),"
  54. "interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n",
  55. GET_PWR_CFG_OFFSET(cfg_cmd),
  56. GET_PWR_CFG_CUT_MASK(cfg_cmd),
  57. GET_PWR_CFG_FAB_MASK(cfg_cmd),
  58. GET_PWR_CFG_INTF_MASK(cfg_cmd),
  59. GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd),
  60. GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd));
  61. if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) &&
  62. (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) &&
  63. (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) {
  64. switch (GET_PWR_CFG_CMD(cfg_cmd)) {
  65. case PWR_CMD_READ:
  66. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  67. "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n");
  68. break;
  69. case PWR_CMD_WRITE:
  70. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  71. "rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n");
  72. offset = GET_PWR_CFG_OFFSET(cfg_cmd);
  73. /*Read the value from system register*/
  74. value = rtl_read_byte(rtlpriv, offset);
  75. value &= (~(GET_PWR_CFG_MASK(cfg_cmd)));
  76. value |= (GET_PWR_CFG_VALUE(cfg_cmd) &
  77. GET_PWR_CFG_MASK(cfg_cmd));
  78. /*Write the value back to sytem register*/
  79. rtl_write_byte(rtlpriv, offset, value);
  80. break;
  81. case PWR_CMD_POLLING:
  82. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  83. "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n");
  84. polling_bit = false;
  85. offset = GET_PWR_CFG_OFFSET(cfg_cmd);
  86. do {
  87. value = rtl_read_byte(rtlpriv, offset);
  88. value &= GET_PWR_CFG_MASK(cfg_cmd);
  89. if (value ==
  90. (GET_PWR_CFG_VALUE(cfg_cmd)
  91. & GET_PWR_CFG_MASK(cfg_cmd)))
  92. polling_bit = true;
  93. else
  94. udelay(10);
  95. if (polling_count++ > max_polling_cnt)
  96. return false;
  97. } while (!polling_bit);
  98. break;
  99. case PWR_CMD_DELAY:
  100. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  101. "rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n");
  102. if (GET_PWR_CFG_VALUE(cfg_cmd) ==
  103. PWRSEQ_DELAY_US)
  104. udelay(GET_PWR_CFG_OFFSET(cfg_cmd));
  105. else
  106. mdelay(GET_PWR_CFG_OFFSET(cfg_cmd));
  107. break;
  108. case PWR_CMD_END:
  109. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  110. "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n");
  111. return true;
  112. default:
  113. RT_ASSERT(false,
  114. "rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n");
  115. break;
  116. }
  117. }
  118. ary_idx++;
  119. } while (1);
  120. return true;
  121. }
  122. EXPORT_SYMBOL(rtl_hal_pwrseqcmdparsing);
  123. bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
  124. {
  125. struct rtl_priv *rtlpriv = rtl_priv(hw);
  126. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  127. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  128. /*<1> reset trx ring */
  129. if (rtlhal->interface == INTF_PCI)
  130. rtlpriv->intf_ops->reset_trx_ring(hw);
  131. if (is_hal_stop(rtlhal))
  132. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  133. "Driver is already down!\n");
  134. /*<2> Enable Adapter */
  135. if (rtlpriv->cfg->ops->hw_init(hw))
  136. return false;
  137. RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
  138. /*<3> Enable Interrupt */
  139. rtlpriv->cfg->ops->enable_interrupt(hw);
  140. /*<enable timer> */
  141. rtl_watch_dog_timer_callback((unsigned long)hw);
  142. return true;
  143. }
  144. EXPORT_SYMBOL(rtl_ps_enable_nic);
  145. bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
  146. {
  147. struct rtl_priv *rtlpriv = rtl_priv(hw);
  148. /*<1> Stop all timer */
  149. rtl_deinit_deferred_work(hw);
  150. /*<2> Disable Interrupt */
  151. rtlpriv->cfg->ops->disable_interrupt(hw);
  152. tasklet_kill(&rtlpriv->works.irq_tasklet);
  153. /*<3> Disable Adapter */
  154. rtlpriv->cfg->ops->hw_disable(hw);
  155. return true;
  156. }
  157. EXPORT_SYMBOL(rtl_ps_disable_nic);
  158. bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
  159. enum rf_pwrstate state_toset,
  160. u32 changesource)
  161. {
  162. struct rtl_priv *rtlpriv = rtl_priv(hw);
  163. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  164. bool actionallowed = false;
  165. switch (state_toset) {
  166. case ERFON:
  167. ppsc->rfoff_reason &= (~changesource);
  168. if ((changesource == RF_CHANGE_BY_HW) &&
  169. (ppsc->hwradiooff)) {
  170. ppsc->hwradiooff = false;
  171. }
  172. if (!ppsc->rfoff_reason) {
  173. ppsc->rfoff_reason = 0;
  174. actionallowed = true;
  175. }
  176. break;
  177. case ERFOFF:
  178. if ((changesource == RF_CHANGE_BY_HW) && !ppsc->hwradiooff) {
  179. ppsc->hwradiooff = true;
  180. }
  181. ppsc->rfoff_reason |= changesource;
  182. actionallowed = true;
  183. break;
  184. case ERFSLEEP:
  185. ppsc->rfoff_reason |= changesource;
  186. actionallowed = true;
  187. break;
  188. default:
  189. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  190. "switch case not processed\n");
  191. break;
  192. }
  193. if (actionallowed)
  194. rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
  195. return actionallowed;
  196. }
  197. EXPORT_SYMBOL(rtl_ps_set_rf_state);
  198. static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
  199. {
  200. struct rtl_priv *rtlpriv = rtl_priv(hw);
  201. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  202. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  203. ppsc->swrf_processing = true;
  204. if (ppsc->inactive_pwrstate == ERFON &&
  205. rtlhal->interface == INTF_PCI) {
  206. if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
  207. RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
  208. rtlhal->interface == INTF_PCI) {
  209. rtlpriv->intf_ops->disable_aspm(hw);
  210. RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
  211. }
  212. }
  213. rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, RF_CHANGE_BY_IPS);
  214. if (ppsc->inactive_pwrstate == ERFOFF &&
  215. rtlhal->interface == INTF_PCI) {
  216. if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
  217. !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
  218. rtlpriv->intf_ops->enable_aspm(hw);
  219. RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
  220. }
  221. }
  222. ppsc->swrf_processing = false;
  223. }
  224. void rtl_ips_nic_off_wq_callback(void *data)
  225. {
  226. struct rtl_works *rtlworks =
  227. container_of_dwork_rtl(data, struct rtl_works, ips_nic_off_wq);
  228. struct ieee80211_hw *hw = rtlworks->hw;
  229. struct rtl_priv *rtlpriv = rtl_priv(hw);
  230. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  231. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  232. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  233. enum rf_pwrstate rtstate;
  234. if (mac->opmode != NL80211_IFTYPE_STATION) {
  235. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  236. "not station return\n");
  237. return;
  238. }
  239. if (mac->p2p_in_use)
  240. return;
  241. if (mac->link_state > MAC80211_NOLINK)
  242. return;
  243. if (is_hal_stop(rtlhal))
  244. return;
  245. if (rtlpriv->sec.being_setkey)
  246. return;
  247. if (rtlpriv->cfg->ops->bt_coex_off_before_lps)
  248. rtlpriv->cfg->ops->bt_coex_off_before_lps(hw);
  249. if (ppsc->inactiveps) {
  250. rtstate = ppsc->rfpwr_state;
  251. /*
  252. *Do not enter IPS in the following conditions:
  253. *(1) RF is already OFF or Sleep
  254. *(2) swrf_processing (indicates the IPS is still under going)
  255. *(3) Connectted (only disconnected can trigger IPS)
  256. *(4) IBSS (send Beacon)
  257. *(5) AP mode (send Beacon)
  258. *(6) monitor mode (rcv packet)
  259. */
  260. if (rtstate == ERFON &&
  261. !ppsc->swrf_processing &&
  262. (mac->link_state == MAC80211_NOLINK) &&
  263. !mac->act_scanning) {
  264. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  265. "IPSEnter(): Turn off RF\n");
  266. ppsc->inactive_pwrstate = ERFOFF;
  267. ppsc->in_powersavemode = true;
  268. /*rtl_pci_reset_trx_ring(hw); */
  269. _rtl_ps_inactive_ps(hw);
  270. }
  271. }
  272. }
  273. void rtl_ips_nic_off(struct ieee80211_hw *hw)
  274. {
  275. struct rtl_priv *rtlpriv = rtl_priv(hw);
  276. /*
  277. *because when link with ap, mac80211 will ask us
  278. *to disable nic quickly after scan before linking,
  279. *this will cause link failed, so we delay 100ms here
  280. */
  281. queue_delayed_work(rtlpriv->works.rtl_wq,
  282. &rtlpriv->works.ips_nic_off_wq, MSECS(100));
  283. }
  284. /* NOTICE: any opmode should exc nic_on, or disable without
  285. * nic_on may something wrong, like adhoc TP
  286. */
  287. void rtl_ips_nic_on(struct ieee80211_hw *hw)
  288. {
  289. struct rtl_priv *rtlpriv = rtl_priv(hw);
  290. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  291. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  292. enum rf_pwrstate rtstate;
  293. unsigned long flags;
  294. if (mac->opmode != NL80211_IFTYPE_STATION)
  295. return;
  296. spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags);
  297. if (ppsc->inactiveps) {
  298. rtstate = ppsc->rfpwr_state;
  299. if (rtstate != ERFON &&
  300. !ppsc->swrf_processing &&
  301. ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) {
  302. ppsc->inactive_pwrstate = ERFON;
  303. ppsc->in_powersavemode = false;
  304. _rtl_ps_inactive_ps(hw);
  305. }
  306. }
  307. spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags);
  308. }
  309. EXPORT_SYMBOL_GPL(rtl_ips_nic_on);
  310. /*for FW LPS*/
  311. /*
  312. *Determine if we can set Fw into PS mode
  313. *in current condition.Return TRUE if it
  314. *can enter PS mode.
  315. */
  316. static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw)
  317. {
  318. struct rtl_priv *rtlpriv = rtl_priv(hw);
  319. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  320. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  321. u32 ps_timediff;
  322. ps_timediff = jiffies_to_msecs(jiffies -
  323. ppsc->last_delaylps_stamp_jiffies);
  324. if (ps_timediff < 2000) {
  325. RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
  326. "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n");
  327. return false;
  328. }
  329. if (mac->link_state != MAC80211_LINKED)
  330. return false;
  331. if (mac->opmode == NL80211_IFTYPE_ADHOC)
  332. return false;
  333. return true;
  334. }
  335. /* Change current and default preamble mode.*/
  336. static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
  337. {
  338. struct rtl_priv *rtlpriv = rtl_priv(hw);
  339. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  340. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  341. bool enter_fwlps;
  342. if (mac->opmode == NL80211_IFTYPE_ADHOC)
  343. return;
  344. if (mac->link_state != MAC80211_LINKED)
  345. return;
  346. if (ppsc->dot11_psmode == rt_psmode)
  347. return;
  348. /* Update power save mode configured. */
  349. ppsc->dot11_psmode = rt_psmode;
  350. /*
  351. *<FW control LPS>
  352. *1. Enter PS mode
  353. * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode
  354. * cmd to set Fw into PS mode.
  355. *2. Leave PS mode
  356. * Send H2C fw_pwrmode cmd to Fw to set Fw into Active
  357. * mode and set RPWM to turn RF on.
  358. */
  359. if ((ppsc->fwctrl_lps) && ppsc->report_linked) {
  360. if (ppsc->dot11_psmode == EACTIVE) {
  361. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  362. "FW LPS leave ps_mode:%x\n",
  363. FW_PS_ACTIVE_MODE);
  364. enter_fwlps = false;
  365. ppsc->pwr_mode = FW_PS_ACTIVE_MODE;
  366. ppsc->smart_ps = 0;
  367. rtlpriv->cfg->ops->set_hw_reg(hw,
  368. HW_VAR_FW_LPS_ACTION,
  369. (u8 *)(&enter_fwlps));
  370. if (ppsc->p2p_ps_info.opp_ps)
  371. rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
  372. } else {
  373. if (rtl_get_fwlps_doze(hw)) {
  374. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  375. "FW LPS enter ps_mode:%x\n",
  376. ppsc->fwctrl_psmode);
  377. enter_fwlps = true;
  378. ppsc->pwr_mode = ppsc->fwctrl_psmode;
  379. ppsc->smart_ps = 2;
  380. rtlpriv->cfg->ops->set_hw_reg(hw,
  381. HW_VAR_FW_LPS_ACTION,
  382. (u8 *)(&enter_fwlps));
  383. } else {
  384. /* Reset the power save related parameters. */
  385. ppsc->dot11_psmode = EACTIVE;
  386. }
  387. }
  388. }
  389. }
  390. /*Enter the leisure power save mode.*/
  391. void rtl_lps_enter(struct ieee80211_hw *hw)
  392. {
  393. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  394. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  395. struct rtl_priv *rtlpriv = rtl_priv(hw);
  396. if (!ppsc->fwctrl_lps)
  397. return;
  398. if (rtlpriv->sec.being_setkey)
  399. return;
  400. if (rtlpriv->link_info.busytraffic)
  401. return;
  402. /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
  403. if (mac->cnt_after_linked < 5)
  404. return;
  405. if (mac->opmode == NL80211_IFTYPE_ADHOC)
  406. return;
  407. if (mac->link_state != MAC80211_LINKED)
  408. return;
  409. mutex_lock(&rtlpriv->locks.ps_mutex);
  410. /* Idle for a while if we connect to AP a while ago. */
  411. if (mac->cnt_after_linked >= 2) {
  412. if (ppsc->dot11_psmode == EACTIVE) {
  413. RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
  414. "Enter 802.11 power save mode...\n");
  415. rtl_lps_set_psmode(hw, EAUTOPS);
  416. }
  417. }
  418. mutex_unlock(&rtlpriv->locks.ps_mutex);
  419. }
  420. /*Leave the leisure power save mode.*/
  421. void rtl_lps_leave(struct ieee80211_hw *hw)
  422. {
  423. struct rtl_priv *rtlpriv = rtl_priv(hw);
  424. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  425. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  426. mutex_lock(&rtlpriv->locks.ps_mutex);
  427. if (ppsc->fwctrl_lps) {
  428. if (ppsc->dot11_psmode != EACTIVE) {
  429. /*FIX ME */
  430. rtlpriv->cfg->ops->enable_interrupt(hw);
  431. if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
  432. RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
  433. rtlhal->interface == INTF_PCI) {
  434. rtlpriv->intf_ops->disable_aspm(hw);
  435. RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
  436. }
  437. RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
  438. "Busy Traffic,Leave 802.11 power save..\n");
  439. rtl_lps_set_psmode(hw, EACTIVE);
  440. }
  441. }
  442. mutex_unlock(&rtlpriv->locks.ps_mutex);
  443. }
  444. /* For sw LPS*/
  445. void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
  446. {
  447. struct rtl_priv *rtlpriv = rtl_priv(hw);
  448. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  449. struct ieee80211_hdr *hdr = data;
  450. struct ieee80211_tim_ie *tim_ie;
  451. u8 *tim;
  452. u8 tim_len;
  453. bool u_buffed;
  454. bool m_buffed;
  455. if (mac->opmode != NL80211_IFTYPE_STATION)
  456. return;
  457. if (!rtlpriv->psc.swctrl_lps)
  458. return;
  459. if (rtlpriv->mac80211.link_state != MAC80211_LINKED)
  460. return;
  461. if (!rtlpriv->psc.sw_ps_enabled)
  462. return;
  463. if (rtlpriv->psc.fwctrl_lps)
  464. return;
  465. if (likely(!(hw->conf.flags & IEEE80211_CONF_PS)))
  466. return;
  467. /* check if this really is a beacon */
  468. if (!ieee80211_is_beacon(hdr->frame_control))
  469. return;
  470. /* min. beacon length + FCS_LEN */
  471. if (len <= 40 + FCS_LEN)
  472. return;
  473. /* and only beacons from the associated BSSID, please */
  474. if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))
  475. return;
  476. rtlpriv->psc.last_beacon = jiffies;
  477. tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
  478. if (!tim)
  479. return;
  480. if (tim[1] < sizeof(*tim_ie))
  481. return;
  482. tim_len = tim[1];
  483. tim_ie = (struct ieee80211_tim_ie *) &tim[2];
  484. if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period))
  485. rtlpriv->psc.dtim_counter = tim_ie->dtim_count;
  486. /* Check whenever the PHY can be turned off again. */
  487. /* 1. What about buffered unicast traffic for our AID? */
  488. u_buffed = ieee80211_check_tim(tim_ie, tim_len,
  489. rtlpriv->mac80211.assoc_id);
  490. /* 2. Maybe the AP wants to send multicast/broadcast data? */
  491. m_buffed = tim_ie->bitmap_ctrl & 0x01;
  492. rtlpriv->psc.multi_buffered = m_buffed;
  493. /* unicast will process by mac80211 through
  494. * set ~IEEE80211_CONF_PS, So we just check
  495. * multicast frames here */
  496. if (!m_buffed) {
  497. /* back to low-power land. and delay is
  498. * prevent null power save frame tx fail */
  499. queue_delayed_work(rtlpriv->works.rtl_wq,
  500. &rtlpriv->works.ps_work, MSECS(5));
  501. } else {
  502. RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
  503. "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed);
  504. }
  505. }
  506. EXPORT_SYMBOL_GPL(rtl_swlps_beacon);
  507. void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
  508. {
  509. struct rtl_priv *rtlpriv = rtl_priv(hw);
  510. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  511. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  512. if (!rtlpriv->psc.swctrl_lps)
  513. return;
  514. if (mac->link_state != MAC80211_LINKED)
  515. return;
  516. if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
  517. RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
  518. rtlpriv->intf_ops->disable_aspm(hw);
  519. RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
  520. }
  521. mutex_lock(&rtlpriv->locks.ps_mutex);
  522. rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS);
  523. mutex_unlock(&rtlpriv->locks.ps_mutex);
  524. }
  525. void rtl_swlps_rfon_wq_callback(void *data)
  526. {
  527. struct rtl_works *rtlworks =
  528. container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq);
  529. struct ieee80211_hw *hw = rtlworks->hw;
  530. rtl_swlps_rf_awake(hw);
  531. }
  532. void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
  533. {
  534. struct rtl_priv *rtlpriv = rtl_priv(hw);
  535. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  536. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  537. u8 sleep_intv;
  538. if (!rtlpriv->psc.sw_ps_enabled)
  539. return;
  540. if ((rtlpriv->sec.being_setkey) ||
  541. (mac->opmode == NL80211_IFTYPE_ADHOC))
  542. return;
  543. /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
  544. if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5))
  545. return;
  546. if (rtlpriv->link_info.busytraffic)
  547. return;
  548. mutex_lock(&rtlpriv->locks.ps_mutex);
  549. rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS);
  550. mutex_unlock(&rtlpriv->locks.ps_mutex);
  551. if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
  552. !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
  553. rtlpriv->intf_ops->enable_aspm(hw);
  554. RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
  555. }
  556. /* here is power save alg, when this beacon is DTIM
  557. * we will set sleep time to dtim_period * n;
  558. * when this beacon is not DTIM, we will set sleep
  559. * time to sleep_intv = rtlpriv->psc.dtim_counter or
  560. * MAX_SW_LPS_SLEEP_INTV(default set to 5) */
  561. if (rtlpriv->psc.dtim_counter == 0) {
  562. if (hw->conf.ps_dtim_period == 1)
  563. sleep_intv = hw->conf.ps_dtim_period * 2;
  564. else
  565. sleep_intv = hw->conf.ps_dtim_period;
  566. } else {
  567. sleep_intv = rtlpriv->psc.dtim_counter;
  568. }
  569. if (sleep_intv > MAX_SW_LPS_SLEEP_INTV)
  570. sleep_intv = MAX_SW_LPS_SLEEP_INTV;
  571. /* this print should always be dtim_conter = 0 &
  572. * sleep = dtim_period, that meaons, we should
  573. * awake before every dtim */
  574. RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
  575. "dtim_counter:%x will sleep :%d beacon_intv\n",
  576. rtlpriv->psc.dtim_counter, sleep_intv);
  577. /* we tested that 40ms is enough for sw & hw sw delay */
  578. queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
  579. MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40));
  580. }
  581. void rtl_lps_change_work_callback(struct work_struct *work)
  582. {
  583. struct rtl_works *rtlworks =
  584. container_of(work, struct rtl_works, lps_change_work);
  585. struct ieee80211_hw *hw = rtlworks->hw;
  586. struct rtl_priv *rtlpriv = rtl_priv(hw);
  587. if (rtlpriv->enter_ps)
  588. rtl_lps_enter(hw);
  589. else
  590. rtl_lps_leave(hw);
  591. }
  592. EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback);
  593. void rtl_swlps_wq_callback(void *data)
  594. {
  595. struct rtl_works *rtlworks = container_of_dwork_rtl(data,
  596. struct rtl_works,
  597. ps_work);
  598. struct ieee80211_hw *hw = rtlworks->hw;
  599. struct rtl_priv *rtlpriv = rtl_priv(hw);
  600. bool ps = false;
  601. ps = (hw->conf.flags & IEEE80211_CONF_PS);
  602. /* we can sleep after ps null send ok */
  603. if (rtlpriv->psc.state_inap) {
  604. rtl_swlps_rf_sleep(hw);
  605. if (rtlpriv->psc.state && !ps) {
  606. rtlpriv->psc.sleep_ms = jiffies_to_msecs(jiffies -
  607. rtlpriv->psc.last_action);
  608. }
  609. if (ps)
  610. rtlpriv->psc.last_slept = jiffies;
  611. rtlpriv->psc.last_action = jiffies;
  612. rtlpriv->psc.state = ps;
  613. }
  614. }
  615. static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data,
  616. unsigned int len)
  617. {
  618. struct rtl_priv *rtlpriv = rtl_priv(hw);
  619. struct ieee80211_mgmt *mgmt = data;
  620. struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
  621. u8 *pos, *end, *ie;
  622. u16 noa_len;
  623. static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09};
  624. u8 noa_num, index, i, noa_index = 0;
  625. bool find_p2p_ie = false , find_p2p_ps_ie = false;
  626. pos = (u8 *)mgmt->u.beacon.variable;
  627. end = data + len;
  628. ie = NULL;
  629. while (pos + 1 < end) {
  630. if (pos + 2 + pos[1] > end)
  631. return;
  632. if (pos[0] == 221 && pos[1] > 4) {
  633. if (memcmp(&pos[2], p2p_oui_ie_type, 4) == 0) {
  634. ie = pos + 2+4;
  635. break;
  636. }
  637. }
  638. pos += 2 + pos[1];
  639. }
  640. if (ie == NULL)
  641. return;
  642. find_p2p_ie = true;
  643. /*to find noa ie*/
  644. while (ie + 1 < end) {
  645. noa_len = READEF2BYTE((__le16 *)&ie[1]);
  646. if (ie + 3 + ie[1] > end)
  647. return;
  648. if (ie[0] == 12) {
  649. find_p2p_ps_ie = true;
  650. if ((noa_len - 2) % 13 != 0) {
  651. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  652. "P2P notice of absence: invalid length.%d\n",
  653. noa_len);
  654. return;
  655. } else {
  656. noa_num = (noa_len - 2) / 13;
  657. }
  658. noa_index = ie[3];
  659. if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode ==
  660. P2P_PS_NONE || noa_index != p2pinfo->noa_index) {
  661. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
  662. "update NOA ie.\n");
  663. p2pinfo->noa_index = noa_index;
  664. p2pinfo->opp_ps = (ie[4] >> 7);
  665. p2pinfo->ctwindow = ie[4] & 0x7F;
  666. p2pinfo->noa_num = noa_num;
  667. index = 5;
  668. for (i = 0; i < noa_num; i++) {
  669. p2pinfo->noa_count_type[i] =
  670. READEF1BYTE(ie+index);
  671. index += 1;
  672. p2pinfo->noa_duration[i] =
  673. READEF4BYTE((__le32 *)ie+index);
  674. index += 4;
  675. p2pinfo->noa_interval[i] =
  676. READEF4BYTE((__le32 *)ie+index);
  677. index += 4;
  678. p2pinfo->noa_start_time[i] =
  679. READEF4BYTE((__le32 *)ie+index);
  680. index += 4;
  681. }
  682. if (p2pinfo->opp_ps == 1) {
  683. p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
  684. /* Driver should wait LPS entering
  685. * CTWindow
  686. */
  687. if (rtlpriv->psc.fw_current_inpsmode)
  688. rtl_p2p_ps_cmd(hw,
  689. P2P_PS_ENABLE);
  690. } else if (p2pinfo->noa_num > 0) {
  691. p2pinfo->p2p_ps_mode = P2P_PS_NOA;
  692. rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
  693. } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
  694. rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
  695. }
  696. }
  697. break;
  698. }
  699. ie += 3 + noa_len;
  700. }
  701. if (find_p2p_ie == true) {
  702. if ((p2pinfo->p2p_ps_mode > P2P_PS_NONE) &&
  703. (find_p2p_ps_ie == false))
  704. rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
  705. }
  706. }
  707. static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data,
  708. unsigned int len)
  709. {
  710. struct rtl_priv *rtlpriv = rtl_priv(hw);
  711. struct ieee80211_mgmt *mgmt = data;
  712. struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
  713. u8 noa_num, index, i, noa_index = 0;
  714. u8 *pos, *end, *ie;
  715. u16 noa_len;
  716. static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09};
  717. pos = (u8 *)&mgmt->u.action.category;
  718. end = data + len;
  719. ie = NULL;
  720. if (pos[0] == 0x7f) {
  721. if (memcmp(&pos[1], p2p_oui_ie_type, 4) == 0)
  722. ie = pos + 3+4;
  723. }
  724. if (ie == NULL)
  725. return;
  726. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n");
  727. /*to find noa ie*/
  728. while (ie + 1 < end) {
  729. noa_len = READEF2BYTE((__le16 *)&ie[1]);
  730. if (ie + 3 + ie[1] > end)
  731. return;
  732. if (ie[0] == 12) {
  733. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n");
  734. RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, "noa ie ",
  735. ie, noa_len);
  736. if ((noa_len - 2) % 13 != 0) {
  737. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
  738. "P2P notice of absence: invalid length.%d\n",
  739. noa_len);
  740. return;
  741. } else {
  742. noa_num = (noa_len - 2) / 13;
  743. }
  744. noa_index = ie[3];
  745. if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode ==
  746. P2P_PS_NONE || noa_index != p2pinfo->noa_index) {
  747. p2pinfo->noa_index = noa_index;
  748. p2pinfo->opp_ps = (ie[4] >> 7);
  749. p2pinfo->ctwindow = ie[4] & 0x7F;
  750. p2pinfo->noa_num = noa_num;
  751. index = 5;
  752. for (i = 0; i < noa_num; i++) {
  753. p2pinfo->noa_count_type[i] =
  754. READEF1BYTE(ie+index);
  755. index += 1;
  756. p2pinfo->noa_duration[i] =
  757. READEF4BYTE((__le32 *)ie+index);
  758. index += 4;
  759. p2pinfo->noa_interval[i] =
  760. READEF4BYTE((__le32 *)ie+index);
  761. index += 4;
  762. p2pinfo->noa_start_time[i] =
  763. READEF4BYTE((__le32 *)ie+index);
  764. index += 4;
  765. }
  766. if (p2pinfo->opp_ps == 1) {
  767. p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
  768. /* Driver should wait LPS entering
  769. * CTWindow
  770. */
  771. if (rtlpriv->psc.fw_current_inpsmode)
  772. rtl_p2p_ps_cmd(hw,
  773. P2P_PS_ENABLE);
  774. } else if (p2pinfo->noa_num > 0) {
  775. p2pinfo->p2p_ps_mode = P2P_PS_NOA;
  776. rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE);
  777. } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
  778. rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
  779. }
  780. }
  781. break;
  782. }
  783. ie += 3 + noa_len;
  784. }
  785. }
  786. void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
  787. {
  788. struct rtl_priv *rtlpriv = rtl_priv(hw);
  789. struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
  790. struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);
  791. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, " p2p state %x\n", p2p_ps_state);
  792. switch (p2p_ps_state) {
  793. case P2P_PS_DISABLE:
  794. p2pinfo->p2p_ps_state = p2p_ps_state;
  795. rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
  796. &p2p_ps_state);
  797. p2pinfo->noa_index = 0;
  798. p2pinfo->ctwindow = 0;
  799. p2pinfo->opp_ps = 0;
  800. p2pinfo->noa_num = 0;
  801. p2pinfo->p2p_ps_mode = P2P_PS_NONE;
  802. if (rtlps->fw_current_inpsmode == true) {
  803. if (rtlps->smart_ps == 0) {
  804. rtlps->smart_ps = 2;
  805. rtlpriv->cfg->ops->set_hw_reg(hw,
  806. HW_VAR_H2C_FW_PWRMODE,
  807. &rtlps->pwr_mode);
  808. }
  809. }
  810. break;
  811. case P2P_PS_ENABLE:
  812. if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
  813. p2pinfo->p2p_ps_state = p2p_ps_state;
  814. if (p2pinfo->ctwindow > 0) {
  815. if (rtlps->smart_ps != 0) {
  816. rtlps->smart_ps = 0;
  817. rtlpriv->cfg->ops->set_hw_reg(hw,
  818. HW_VAR_H2C_FW_PWRMODE,
  819. &rtlps->pwr_mode);
  820. }
  821. }
  822. rtlpriv->cfg->ops->set_hw_reg(hw,
  823. HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
  824. &p2p_ps_state);
  825. }
  826. break;
  827. case P2P_PS_SCAN:
  828. case P2P_PS_SCAN_DONE:
  829. case P2P_PS_ALLSTASLEEP:
  830. if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) {
  831. p2pinfo->p2p_ps_state = p2p_ps_state;
  832. rtlpriv->cfg->ops->set_hw_reg(hw,
  833. HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
  834. &p2p_ps_state);
  835. }
  836. break;
  837. default:
  838. break;
  839. }
  840. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
  841. "ctwindow %x oppps %x\n", p2pinfo->ctwindow, p2pinfo->opp_ps);
  842. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
  843. "count %x duration %x index %x interval %x start time %x noa num %x\n",
  844. p2pinfo->noa_count_type[0], p2pinfo->noa_duration[0],
  845. p2pinfo->noa_index, p2pinfo->noa_interval[0],
  846. p2pinfo->noa_start_time[0], p2pinfo->noa_num);
  847. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "end\n");
  848. }
  849. void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)
  850. {
  851. struct rtl_priv *rtlpriv = rtl_priv(hw);
  852. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  853. struct ieee80211_hdr *hdr = data;
  854. if (!mac->p2p)
  855. return;
  856. if (mac->link_state != MAC80211_LINKED)
  857. return;
  858. /* min. beacon length + FCS_LEN */
  859. if (len <= 40 + FCS_LEN)
  860. return;
  861. /* and only beacons from the associated BSSID, please */
  862. if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))
  863. return;
  864. /* check if this really is a beacon */
  865. if (!(ieee80211_is_beacon(hdr->frame_control) ||
  866. ieee80211_is_probe_resp(hdr->frame_control) ||
  867. ieee80211_is_action(hdr->frame_control)))
  868. return;
  869. if (ieee80211_is_action(hdr->frame_control))
  870. rtl_p2p_action_ie(hw, data, len - FCS_LEN);
  871. else
  872. rtl_p2p_noa_ie(hw, data, len - FCS_LEN);
  873. }
  874. EXPORT_SYMBOL_GPL(rtl_p2p_info);