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