Merge branch 'batman-adv/next' of git://git.open-mesh.org/ecsv/linux-merge
[pandora-kernel.git] / drivers / net / wireless / rtlwifi / ps.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010  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
30 #include "wifi.h"
31 #include "base.h"
32 #include "ps.h"
33
34 bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
35 {
36         struct rtl_priv *rtlpriv = rtl_priv(hw);
37         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
38         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
39
40         /*<1> reset trx ring */
41         if (rtlhal->interface == INTF_PCI)
42                 rtlpriv->intf_ops->reset_trx_ring(hw);
43
44         if (is_hal_stop(rtlhal))
45                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
46                          ("Driver is already down!\n"));
47
48         /*<2> Enable Adapter */
49         rtlpriv->cfg->ops->hw_init(hw);
50         RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
51
52         /*<3> Enable Interrupt */
53         rtlpriv->cfg->ops->enable_interrupt(hw);
54
55         /*<enable timer> */
56         rtl_watch_dog_timer_callback((unsigned long)hw);
57
58         return true;
59 }
60 EXPORT_SYMBOL(rtl_ps_enable_nic);
61
62 bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
63 {
64         struct rtl_priv *rtlpriv = rtl_priv(hw);
65
66         /*<1> Stop all timer */
67         rtl_deinit_deferred_work(hw);
68
69         /*<2> Disable Interrupt */
70         rtlpriv->cfg->ops->disable_interrupt(hw);
71         tasklet_kill(&rtlpriv->works.irq_tasklet);
72
73         /*<3> Disable Adapter */
74         rtlpriv->cfg->ops->hw_disable(hw);
75
76         return true;
77 }
78 EXPORT_SYMBOL(rtl_ps_disable_nic);
79
80 bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
81                          enum rf_pwrstate state_toset,
82                          u32 changesource, bool protect_or_not)
83 {
84         struct rtl_priv *rtlpriv = rtl_priv(hw);
85         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
86         bool actionallowed = false;
87         u16 rfwait_cnt = 0;
88
89         /*protect_or_not = true; */
90
91         if (protect_or_not)
92                 goto no_protect;
93
94         /*
95          *Only one thread can change
96          *the RF state at one time, and others
97          *should wait to be executed.
98          */
99         while (true) {
100                 spin_lock(&rtlpriv->locks.rf_ps_lock);
101                 if (ppsc->rfchange_inprogress) {
102                         spin_unlock(&rtlpriv->locks.rf_ps_lock);
103
104                         RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
105                                  ("RF Change in progress!"
106                                   "Wait to set..state_toset(%d).\n",
107                                   state_toset));
108
109                         /* Set RF after the previous action is done.  */
110                         while (ppsc->rfchange_inprogress) {
111                                 rfwait_cnt++;
112                                 mdelay(1);
113
114                                 /*
115                                  *Wait too long, return false to avoid
116                                  *to be stuck here.
117                                  */
118                                 if (rfwait_cnt > 100)
119                                         return false;
120                         }
121                 } else {
122                         ppsc->rfchange_inprogress = true;
123                         spin_unlock(&rtlpriv->locks.rf_ps_lock);
124                         break;
125                 }
126         }
127
128 no_protect:
129         switch (state_toset) {
130         case ERFON:
131                 ppsc->rfoff_reason &= (~changesource);
132
133                 if ((changesource == RF_CHANGE_BY_HW) &&
134                     (ppsc->hwradiooff == true)) {
135                         ppsc->hwradiooff = false;
136                 }
137
138                 if (!ppsc->rfoff_reason) {
139                         ppsc->rfoff_reason = 0;
140                         actionallowed = true;
141                 }
142
143                 break;
144
145         case ERFOFF:
146
147                 if ((changesource == RF_CHANGE_BY_HW)
148                     && (ppsc->hwradiooff == false)) {
149                         ppsc->hwradiooff = true;
150                 }
151
152                 ppsc->rfoff_reason |= changesource;
153                 actionallowed = true;
154                 break;
155
156         case ERFSLEEP:
157                 ppsc->rfoff_reason |= changesource;
158                 actionallowed = true;
159                 break;
160
161         default:
162                 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
163                          ("switch case not process\n"));
164                 break;
165         }
166
167         if (actionallowed)
168                 rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
169
170         if (!protect_or_not) {
171                 spin_lock(&rtlpriv->locks.rf_ps_lock);
172                 ppsc->rfchange_inprogress = false;
173                 spin_unlock(&rtlpriv->locks.rf_ps_lock);
174         }
175
176         return actionallowed;
177 }
178 EXPORT_SYMBOL(rtl_ps_set_rf_state);
179
180 static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
181 {
182         struct rtl_priv *rtlpriv = rtl_priv(hw);
183         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
184         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
185
186         ppsc->swrf_processing = true;
187
188         if (ppsc->inactive_pwrstate == ERFON &&
189             rtlhal->interface == INTF_PCI) {
190                 if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
191                     RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
192                     rtlhal->interface == INTF_PCI) {
193                         rtlpriv->intf_ops->disable_aspm(hw);
194                         RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
195                 }
196         }
197
198         rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate,
199                             RF_CHANGE_BY_IPS, false);
200
201         if (ppsc->inactive_pwrstate == ERFOFF &&
202             rtlhal->interface == INTF_PCI) {
203                 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
204                         !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
205                         rtlpriv->intf_ops->enable_aspm(hw);
206                         RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
207                 }
208         }
209
210         ppsc->swrf_processing = false;
211 }
212
213 void rtl_ips_nic_off_wq_callback(void *data)
214 {
215         struct rtl_works *rtlworks =
216             container_of_dwork_rtl(data, struct rtl_works, ips_nic_off_wq);
217         struct ieee80211_hw *hw = rtlworks->hw;
218         struct rtl_priv *rtlpriv = rtl_priv(hw);
219         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
220         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
221         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
222         enum rf_pwrstate rtstate;
223
224         if (mac->opmode != NL80211_IFTYPE_STATION) {
225                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
226                          ("not station return\n"));
227                 return;
228         }
229
230         if (mac->link_state > MAC80211_NOLINK)
231                 return;
232
233         if (is_hal_stop(rtlhal))
234                 return;
235
236         if (rtlpriv->sec.being_setkey)
237                 return;
238
239         if (ppsc->inactiveps) {
240                 rtstate = ppsc->rfpwr_state;
241
242                 /*
243                  *Do not enter IPS in the following conditions:
244                  *(1) RF is already OFF or Sleep
245                  *(2) swrf_processing (indicates the IPS is still under going)
246                  *(3) Connectted (only disconnected can trigger IPS)
247                  *(4) IBSS (send Beacon)
248                  *(5) AP mode (send Beacon)
249                  *(6) monitor mode (rcv packet)
250                  */
251
252                 if (rtstate == ERFON &&
253                     !ppsc->swrf_processing &&
254                     (mac->link_state == MAC80211_NOLINK) &&
255                     !mac->act_scanning) {
256                         RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
257                                  ("IPSEnter(): Turn off RF.\n"));
258
259                         ppsc->inactive_pwrstate = ERFOFF;
260                         ppsc->in_powersavemode = true;
261
262                         /*rtl_pci_reset_trx_ring(hw); */
263                         _rtl_ps_inactive_ps(hw);
264                 }
265         }
266 }
267
268 void rtl_ips_nic_off(struct ieee80211_hw *hw)
269 {
270         struct rtl_priv *rtlpriv = rtl_priv(hw);
271
272         /*
273          *because when link with ap, mac80211 will ask us
274          *to disable nic quickly after scan before linking,
275          *this will cause link failed, so we delay 100ms here
276          */
277         queue_delayed_work(rtlpriv->works.rtl_wq,
278                            &rtlpriv->works.ips_nic_off_wq, MSECS(100));
279 }
280
281 void rtl_ips_nic_on(struct ieee80211_hw *hw)
282 {
283         struct rtl_priv *rtlpriv = rtl_priv(hw);
284         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
285         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
286         enum rf_pwrstate rtstate;
287
288         if (mac->opmode != NL80211_IFTYPE_STATION)
289                 return;
290
291         spin_lock(&rtlpriv->locks.ips_lock);
292
293         if (ppsc->inactiveps) {
294                 rtstate = ppsc->rfpwr_state;
295
296                 if (rtstate != ERFON &&
297                     !ppsc->swrf_processing &&
298                     ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) {
299
300                         ppsc->inactive_pwrstate = ERFON;
301                         ppsc->in_powersavemode = false;
302
303                         _rtl_ps_inactive_ps(hw);
304                 }
305         }
306
307         spin_unlock(&rtlpriv->locks.ips_lock);
308 }
309
310 /*for FW LPS*/
311
312 /*
313  *Determine if we can set Fw into PS mode
314  *in current condition.Return TRUE if it
315  *can enter PS mode.
316  */
317 static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw)
318 {
319         struct rtl_priv *rtlpriv = rtl_priv(hw);
320         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
321         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
322         u32 ps_timediff;
323
324         ps_timediff = jiffies_to_msecs(jiffies -
325                                        ppsc->last_delaylps_stamp_jiffies);
326
327         if (ps_timediff < 2000) {
328                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
329                          ("Delay enter Fw LPS for DHCP, ARP,"
330                           " or EAPOL exchanging state.\n"));
331                 return false;
332         }
333
334         if (mac->link_state != MAC80211_LINKED)
335                 return false;
336
337         if (mac->opmode == NL80211_IFTYPE_ADHOC)
338                 return false;
339
340         return true;
341 }
342
343 /* Change current and default preamble mode.*/
344 static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
345 {
346         struct rtl_priv *rtlpriv = rtl_priv(hw);
347         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
348         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
349         u8 rpwm_val, fw_pwrmode;
350
351         if (mac->opmode == NL80211_IFTYPE_ADHOC)
352                 return;
353
354         if (mac->link_state != MAC80211_LINKED)
355                 return;
356
357         if (ppsc->dot11_psmode == rt_psmode)
358                 return;
359
360         /* Update power save mode configured. */
361         ppsc->dot11_psmode = rt_psmode;
362
363         /*
364          *<FW control LPS>
365          *1. Enter PS mode
366          *   Set RPWM to Fw to turn RF off and send H2C fw_pwrmode
367          *   cmd to set Fw into PS mode.
368          *2. Leave PS mode
369          *   Send H2C fw_pwrmode cmd to Fw to set Fw into Active
370          *   mode and set RPWM to turn RF on.
371          */
372
373         if ((ppsc->fwctrl_lps) && ppsc->report_linked) {
374                 bool fw_current_inps;
375                 if (ppsc->dot11_psmode == EACTIVE) {
376                         RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
377                                  ("FW LPS leave ps_mode:%x\n",
378                                   FW_PS_ACTIVE_MODE));
379
380                         rpwm_val = 0x0C;        /* RF on */
381                         fw_pwrmode = FW_PS_ACTIVE_MODE;
382                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
383                                         (u8 *) (&rpwm_val));
384                         rtlpriv->cfg->ops->set_hw_reg(hw,
385                                         HW_VAR_H2C_FW_PWRMODE,
386                                         (u8 *) (&fw_pwrmode));
387                         fw_current_inps = false;
388
389                         rtlpriv->cfg->ops->set_hw_reg(hw,
390                                         HW_VAR_FW_PSMODE_STATUS,
391                                         (u8 *) (&fw_current_inps));
392
393                 } else {
394                         if (rtl_get_fwlps_doze(hw)) {
395                                 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
396                                                 ("FW LPS enter ps_mode:%x\n",
397                                                  ppsc->fwctrl_psmode));
398
399                                 rpwm_val = 0x02;        /* RF off */
400                                 fw_current_inps = true;
401                                 rtlpriv->cfg->ops->set_hw_reg(hw,
402                                                 HW_VAR_FW_PSMODE_STATUS,
403                                                 (u8 *) (&fw_current_inps));
404                                 rtlpriv->cfg->ops->set_hw_reg(hw,
405                                                 HW_VAR_H2C_FW_PWRMODE,
406                                                 (u8 *) (&ppsc->fwctrl_psmode));
407
408                                 rtlpriv->cfg->ops->set_hw_reg(hw,
409                                                 HW_VAR_SET_RPWM,
410                                                 (u8 *) (&rpwm_val));
411                         } else {
412                                 /* Reset the power save related parameters. */
413                                 ppsc->dot11_psmode = EACTIVE;
414                         }
415                 }
416         }
417 }
418
419 /*Enter the leisure power save mode.*/
420 void rtl_lps_enter(struct ieee80211_hw *hw)
421 {
422         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
423         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
424         struct rtl_priv *rtlpriv = rtl_priv(hw);
425
426         if (!ppsc->fwctrl_lps)
427                 return;
428
429         if (rtlpriv->sec.being_setkey)
430                 return;
431
432         if (rtlpriv->link_info.busytraffic)
433                 return;
434
435         /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
436         if (mac->cnt_after_linked < 5)
437                 return;
438
439         if (mac->opmode == NL80211_IFTYPE_ADHOC)
440                 return;
441
442         if (mac->link_state != MAC80211_LINKED)
443                 return;
444
445         spin_lock(&rtlpriv->locks.lps_lock);
446
447         /* Idle for a while if we connect to AP a while ago. */
448         if (mac->cnt_after_linked >= 2) {
449                 if (ppsc->dot11_psmode == EACTIVE) {
450                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
451                                         ("Enter 802.11 power save mode...\n"));
452
453                         rtl_lps_set_psmode(hw, EAUTOPS);
454                 }
455         }
456
457         spin_unlock(&rtlpriv->locks.lps_lock);
458 }
459
460 /*Leave the leisure power save mode.*/
461 void rtl_lps_leave(struct ieee80211_hw *hw)
462 {
463         struct rtl_priv *rtlpriv = rtl_priv(hw);
464         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
465         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
466
467         spin_lock(&rtlpriv->locks.lps_lock);
468
469         if (ppsc->fwctrl_lps) {
470                 if (ppsc->dot11_psmode != EACTIVE) {
471
472                         /*FIX ME */
473                         rtlpriv->cfg->ops->enable_interrupt(hw);
474
475                         if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
476                             RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
477                             rtlhal->interface == INTF_PCI) {
478                                 rtlpriv->intf_ops->disable_aspm(hw);
479                                 RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
480                         }
481
482                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
483                                  ("Busy Traffic,Leave 802.11 power save..\n"));
484
485                         rtl_lps_set_psmode(hw, EACTIVE);
486                 }
487         }
488         spin_unlock(&rtlpriv->locks.lps_lock);
489 }
490
491 /* For sw LPS*/
492 void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
493 {
494         struct rtl_priv *rtlpriv = rtl_priv(hw);
495         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
496         struct ieee80211_hdr *hdr = (void *) data;
497         struct ieee80211_tim_ie *tim_ie;
498         u8 *tim;
499         u8 tim_len;
500         bool u_buffed;
501         bool m_buffed;
502
503         if (mac->opmode != NL80211_IFTYPE_STATION)
504                 return;
505
506         if (!rtlpriv->psc.swctrl_lps)
507                 return;
508
509         if (rtlpriv->mac80211.link_state != MAC80211_LINKED)
510                 return;
511
512         if (!rtlpriv->psc.sw_ps_enabled)
513                 return;
514
515         if (rtlpriv->psc.fwctrl_lps)
516                 return;
517
518         if (likely(!(hw->conf.flags & IEEE80211_CONF_PS)))
519                 return;
520
521         /* check if this really is a beacon */
522         if (!ieee80211_is_beacon(hdr->frame_control))
523                 return;
524
525         /* min. beacon length + FCS_LEN */
526         if (len <= 40 + FCS_LEN)
527                 return;
528
529         /* and only beacons from the associated BSSID, please */
530         if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
531                 return;
532
533         rtlpriv->psc.last_beacon = jiffies;
534
535         tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
536         if (!tim)
537                 return;
538
539         if (tim[1] < sizeof(*tim_ie))
540                 return;
541
542         tim_len = tim[1];
543         tim_ie = (struct ieee80211_tim_ie *) &tim[2];
544
545         if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period))
546                 rtlpriv->psc.dtim_counter = tim_ie->dtim_count;
547
548         /* Check whenever the PHY can be turned off again. */
549
550         /* 1. What about buffered unicast traffic for our AID? */
551         u_buffed = ieee80211_check_tim(tim_ie, tim_len,
552                                        rtlpriv->mac80211.assoc_id);
553
554         /* 2. Maybe the AP wants to send multicast/broadcast data? */
555         m_buffed = tim_ie->bitmap_ctrl & 0x01;
556         rtlpriv->psc.multi_buffered = m_buffed;
557
558         /* unicast will process by mac80211 through
559          * set ~IEEE80211_CONF_PS, So we just check
560          * multicast frames here */
561         if (!m_buffed) {
562                 /* back to low-power land. and delay is
563                  * prevent null power save frame tx fail */
564                 queue_delayed_work(rtlpriv->works.rtl_wq,
565                                 &rtlpriv->works.ps_work, MSECS(5));
566         } else {
567                 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, "
568                                 "m_buffered: %x\n", u_buffed, m_buffed));
569         }
570 }
571
572 void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
573 {
574         struct rtl_priv *rtlpriv = rtl_priv(hw);
575         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
576         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
577
578         if (!rtlpriv->psc.swctrl_lps)
579                 return;
580         if (mac->link_state != MAC80211_LINKED)
581                 return;
582
583         if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
584                 RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
585                 rtlpriv->intf_ops->disable_aspm(hw);
586                 RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
587         }
588
589         spin_lock(&rtlpriv->locks.lps_lock);
590         rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false);
591         spin_unlock(&rtlpriv->locks.lps_lock);
592 }
593
594 void rtl_swlps_rfon_wq_callback(void *data)
595 {
596         struct rtl_works *rtlworks =
597             container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq);
598         struct ieee80211_hw *hw = rtlworks->hw;
599
600         rtl_swlps_rf_awake(hw);
601 }
602
603 void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
604 {
605         struct rtl_priv *rtlpriv = rtl_priv(hw);
606         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
607         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
608         u8 sleep_intv;
609
610         if (!rtlpriv->psc.sw_ps_enabled)
611                 return;
612
613         if ((rtlpriv->sec.being_setkey) ||
614             (mac->opmode == NL80211_IFTYPE_ADHOC))
615                 return;
616
617         /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
618         if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5))
619                 return;
620
621         if (rtlpriv->link_info.busytraffic)
622                 return;
623
624         spin_lock(&rtlpriv->locks.rf_ps_lock);
625         if (rtlpriv->psc.rfchange_inprogress) {
626                 spin_unlock(&rtlpriv->locks.rf_ps_lock);
627                 return;
628         }
629         spin_unlock(&rtlpriv->locks.rf_ps_lock);
630
631         spin_lock(&rtlpriv->locks.lps_lock);
632         rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false);
633         spin_unlock(&rtlpriv->locks.lps_lock);
634
635         if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
636                 !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
637                 rtlpriv->intf_ops->enable_aspm(hw);
638                 RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
639         }
640
641         /* here is power save alg, when this beacon is DTIM
642          * we will set sleep time to dtim_period * n;
643          * when this beacon is not DTIM, we will set sleep
644          * time to sleep_intv = rtlpriv->psc.dtim_counter or
645          * MAX_SW_LPS_SLEEP_INTV(default set to 5) */
646
647         if (rtlpriv->psc.dtim_counter == 0) {
648                 if (hw->conf.ps_dtim_period == 1)
649                         sleep_intv = hw->conf.ps_dtim_period * 2;
650                 else
651                         sleep_intv = hw->conf.ps_dtim_period;
652         } else {
653                 sleep_intv = rtlpriv->psc.dtim_counter;
654         }
655
656         if (sleep_intv > MAX_SW_LPS_SLEEP_INTV)
657                 sleep_intv = MAX_SW_LPS_SLEEP_INTV;
658
659         /* this print should always be dtim_conter = 0 &
660          * sleep  = dtim_period, that meaons, we should
661          * awake before every dtim */
662         RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
663                  ("dtim_counter:%x will sleep :%d"
664                  " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv));
665
666         /* we tested that 40ms is enough for sw & hw sw delay */
667         queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
668                         MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40));
669 }
670
671
672 void rtl_swlps_wq_callback(void *data)
673 {
674         struct rtl_works *rtlworks = container_of_dwork_rtl(data,
675                                      struct rtl_works,
676                                      ps_work);
677         struct ieee80211_hw *hw = rtlworks->hw;
678         struct rtl_priv *rtlpriv = rtl_priv(hw);
679         bool ps = false;
680
681         ps = (hw->conf.flags & IEEE80211_CONF_PS);
682
683         /* we can sleep after ps null send ok */
684         if (rtlpriv->psc.state_inap) {
685                 rtl_swlps_rf_sleep(hw);
686
687                 if (rtlpriv->psc.state && !ps) {
688                         rtlpriv->psc.sleep_ms = jiffies_to_msecs(jiffies -
689                                         rtlpriv->psc.last_action);
690                 }
691
692                 if (ps)
693                         rtlpriv->psc.last_slept = jiffies;
694
695                 rtlpriv->psc.last_action = jiffies;
696                 rtlpriv->psc.state = ps;
697         }
698 }