1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
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.
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
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
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
26 * Larry Finger <Larry.Finger@lwfinger.net>
28 *****************************************************************************/
34 bool rtl_ps_enable_nic(struct ieee80211_hw
*hw
)
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
));
40 /*<1> reset trx ring */
41 if (rtlhal
->interface
== INTF_PCI
)
42 rtlpriv
->intf_ops
->reset_trx_ring(hw
);
44 if (is_hal_stop(rtlhal
))
45 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_WARNING
,
46 ("Driver is already down!\n"));
48 /*<2> Enable Adapter */
49 rtlpriv
->cfg
->ops
->hw_init(hw
);
50 RT_CLEAR_PS_LEVEL(ppsc
, RT_RF_OFF_LEVL_HALT_NIC
);
52 /*<3> Enable Interrupt */
53 rtlpriv
->cfg
->ops
->enable_interrupt(hw
);
56 rtl_watch_dog_timer_callback((unsigned long)hw
);
60 EXPORT_SYMBOL(rtl_ps_enable_nic
);
62 bool rtl_ps_disable_nic(struct ieee80211_hw
*hw
)
64 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
66 /*<1> Stop all timer */
67 rtl_deinit_deferred_work(hw
);
69 /*<2> Disable Interrupt */
70 rtlpriv
->cfg
->ops
->disable_interrupt(hw
);
72 /*<3> Disable Adapter */
73 rtlpriv
->cfg
->ops
->hw_disable(hw
);
77 EXPORT_SYMBOL(rtl_ps_disable_nic
);
79 bool rtl_ps_set_rf_state(struct ieee80211_hw
*hw
,
80 enum rf_pwrstate state_toset
,
81 u32 changesource
, bool protect_or_not
)
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;
90 /*protect_or_not = true; */
96 *Only one thread can change
97 *the RF state at one time, and others
98 *should wait to be executed.
101 spin_lock_irqsave(&rtlpriv
->locks
.rf_ps_lock
, flag
);
102 if (ppsc
->rfchange_inprogress
) {
103 spin_unlock_irqrestore(&rtlpriv
->locks
.rf_ps_lock
,
106 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_WARNING
,
107 ("RF Change in progress!"
108 "Wait to set..state_toset(%d).\n",
111 /* Set RF after the previous action is done. */
112 while (ppsc
->rfchange_inprogress
) {
117 *Wait too long, return false to avoid
120 if (rfwait_cnt
> 100)
124 ppsc
->rfchange_inprogress
= true;
125 spin_unlock_irqrestore(&rtlpriv
->locks
.rf_ps_lock
,
132 rtstate
= ppsc
->rfpwr_state
;
134 switch (state_toset
) {
136 ppsc
->rfoff_reason
&= (~changesource
);
138 if ((changesource
== RF_CHANGE_BY_HW
) &&
139 (ppsc
->hwradiooff
== true)) {
140 ppsc
->hwradiooff
= false;
143 if (!ppsc
->rfoff_reason
) {
144 ppsc
->rfoff_reason
= 0;
145 actionallowed
= true;
152 if ((changesource
== RF_CHANGE_BY_HW
)
153 && (ppsc
->hwradiooff
== false)) {
154 ppsc
->hwradiooff
= true;
157 ppsc
->rfoff_reason
|= changesource
;
158 actionallowed
= true;
162 ppsc
->rfoff_reason
|= changesource
;
163 actionallowed
= true;
167 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_EMERG
,
168 ("switch case not process\n"));
173 rtlpriv
->cfg
->ops
->set_rf_power_state(hw
, state_toset
);
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
);
181 return actionallowed
;
183 EXPORT_SYMBOL(rtl_ps_set_rf_state
);
185 static void _rtl_ps_inactive_ps(struct ieee80211_hw
*hw
)
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
));
191 ppsc
->swrf_processing
= true;
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
);
203 rtl_ps_set_rf_state(hw
, ppsc
->inactive_pwrstate
,
204 RF_CHANGE_BY_IPS
, false);
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
);
215 ppsc
->swrf_processing
= false;
218 void rtl_ips_nic_off_wq_callback(void *data
)
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
;
229 if (mac
->opmode
!= NL80211_IFTYPE_STATION
) {
230 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_WARNING
,
231 ("not station return\n"));
235 if (mac
->link_state
> MAC80211_NOLINK
)
238 if (is_hal_stop(rtlhal
))
241 if (rtlpriv
->sec
.being_setkey
)
244 if (ppsc
->inactiveps
) {
245 rtstate
= ppsc
->rfpwr_state
;
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)
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"));
264 ppsc
->inactive_pwrstate
= ERFOFF
;
265 ppsc
->in_powersavemode
= true;
267 /*rtl_pci_reset_trx_ring(hw); */
268 _rtl_ps_inactive_ps(hw
);
273 void rtl_ips_nic_off(struct ieee80211_hw
*hw
)
275 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
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
282 queue_delayed_work(rtlpriv
->works
.rtl_wq
,
283 &rtlpriv
->works
.ips_nic_off_wq
, MSECS(100));
286 void rtl_ips_nic_on(struct ieee80211_hw
*hw
)
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
;
294 if (mac
->opmode
!= NL80211_IFTYPE_STATION
)
297 spin_lock_irqsave(&rtlpriv
->locks
.ips_lock
, flags
);
299 if (ppsc
->inactiveps
) {
300 rtstate
= ppsc
->rfpwr_state
;
302 if (rtstate
!= ERFON
&&
303 !ppsc
->swrf_processing
&&
304 ppsc
->rfoff_reason
<= RF_CHANGE_BY_IPS
) {
306 ppsc
->inactive_pwrstate
= ERFON
;
307 ppsc
->in_powersavemode
= false;
309 _rtl_ps_inactive_ps(hw
);
313 spin_unlock_irqrestore(&rtlpriv
->locks
.ips_lock
, flags
);
319 *Determine if we can set Fw into PS mode
320 *in current condition.Return TRUE if it
323 static bool rtl_get_fwlps_doze(struct ieee80211_hw
*hw
)
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
));
330 ps_timediff
= jiffies_to_msecs(jiffies
-
331 ppsc
->last_delaylps_stamp_jiffies
);
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"));
340 if (mac
->link_state
!= MAC80211_LINKED
)
343 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
)
349 /* Change current and default preamble mode.*/
350 static void rtl_lps_set_psmode(struct ieee80211_hw
*hw
, u8 rt_psmode
)
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
;
357 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
)
360 if (mac
->link_state
!= MAC80211_LINKED
)
363 if (ppsc
->dot11_psmode
== rt_psmode
)
366 /* Update power save mode configured. */
367 ppsc
->dot11_psmode
= rt_psmode
;
372 * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode
373 * cmd to set Fw into PS mode.
375 * Send H2C fw_pwrmode cmd to Fw to set Fw into Active
376 * mode and set RPWM to turn RF on.
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",
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
,
390 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
391 HW_VAR_H2C_FW_PWRMODE
,
392 (u8
*) (&fw_pwrmode
));
393 fw_current_inps
= false;
395 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
396 HW_VAR_FW_PSMODE_STATUS
,
397 (u8
*) (&fw_current_inps
));
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
));
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
));
414 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
418 /* Reset the power save related parameters. */
419 ppsc
->dot11_psmode
= EACTIVE
;
425 /*Enter the leisure power save mode.*/
426 void rtl_lps_enter(struct ieee80211_hw
*hw
)
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
);
433 if (!ppsc
->fwctrl_lps
)
436 if (rtlpriv
->sec
.being_setkey
)
439 if (rtlpriv
->link_info
.busytraffic
)
442 /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
443 if (mac
->cnt_after_linked
< 5)
446 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
)
449 if (mac
->link_state
!= MAC80211_LINKED
)
452 spin_lock_irqsave(&rtlpriv
->locks
.lps_lock
, flag
);
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"));
460 rtl_lps_set_psmode(hw
, EAUTOPS
);
464 spin_unlock_irqrestore(&rtlpriv
->locks
.lps_lock
, flag
);
467 /*Leave the leisure power save mode.*/
468 void rtl_lps_leave(struct ieee80211_hw
*hw
)
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
));
475 spin_lock_irqsave(&rtlpriv
->locks
.lps_lock
, flag
);
477 if (ppsc
->fwctrl_lps
) {
478 if (ppsc
->dot11_psmode
!= EACTIVE
) {
481 rtlpriv
->cfg
->ops
->enable_interrupt(hw
);
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
);
490 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
491 ("Busy Traffic,Leave 802.11 power save..\n"));
493 rtl_lps_set_psmode(hw
, EACTIVE
);
496 spin_unlock_irqrestore(&rtlpriv
->locks
.lps_lock
, flag
);
500 void rtl_swlps_beacon(struct ieee80211_hw
*hw
, void *data
, unsigned int len
)
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
;
511 if (mac
->opmode
!= NL80211_IFTYPE_STATION
)
514 if (!rtlpriv
->psc
.swctrl_lps
)
517 if (rtlpriv
->mac80211
.link_state
!= MAC80211_LINKED
)
520 if (!rtlpriv
->psc
.sw_ps_enabled
)
523 if (rtlpriv
->psc
.fwctrl_lps
)
526 if (likely(!(hw
->conf
.flags
& IEEE80211_CONF_PS
)))
529 /* check if this really is a beacon */
530 if (!ieee80211_is_beacon(hdr
->frame_control
))
533 /* min. beacon length + FCS_LEN */
534 if (len
<= 40 + FCS_LEN
)
537 /* and only beacons from the associated BSSID, please */
538 if (compare_ether_addr(hdr
->addr3
, rtlpriv
->mac80211
.bssid
))
541 rtlpriv
->psc
.last_beacon
= jiffies
;
543 tim
= rtl_find_ie(data
, len
- FCS_LEN
, WLAN_EID_TIM
);
547 if (tim
[1] < sizeof(*tim_ie
))
551 tim_ie
= (struct ieee80211_tim_ie
*) &tim
[2];
553 if (!WARN_ON_ONCE(!hw
->conf
.ps_dtim_period
))
554 rtlpriv
->psc
.dtim_counter
= tim_ie
->dtim_count
;
556 /* Check whenever the PHY can be turned off again. */
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
);
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
;
566 /* unicast will process by mac80211 through
567 * set ~IEEE80211_CONF_PS, So we just check
568 * multicast frames here */
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));
575 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_DMESG
, ("u_bufferd: %x, "
576 "m_buffered: %x\n", u_buffed
, m_buffed
));
580 void rtl_swlps_rf_awake(struct ieee80211_hw
*hw
)
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
));
587 if (!rtlpriv
->psc
.swctrl_lps
)
589 if (mac
->link_state
!= MAC80211_LINKED
)
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
);
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
);
603 void rtl_swlps_rfon_wq_callback(void *data
)
605 struct rtl_works
*rtlworks
=
606 container_of_dwork_rtl(data
, struct rtl_works
, ps_rfon_wq
);
607 struct ieee80211_hw
*hw
= rtlworks
->hw
;
609 rtl_swlps_rf_awake(hw
);
612 void rtl_swlps_rf_sleep(struct ieee80211_hw
*hw
)
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
));
620 if (!rtlpriv
->psc
.sw_ps_enabled
)
623 if ((rtlpriv
->sec
.being_setkey
) ||
624 (mac
->opmode
== NL80211_IFTYPE_ADHOC
))
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))
631 if (rtlpriv
->link_info
.busytraffic
)
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
);
639 spin_unlock_irqrestore(&rtlpriv
->locks
.rf_ps_lock
, flag
);
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
);
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
);
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) */
657 if (rtlpriv
->psc
.dtim_counter
== 0) {
658 if (hw
->conf
.ps_dtim_period
== 1)
659 sleep_intv
= hw
->conf
.ps_dtim_period
* 2;
661 sleep_intv
= hw
->conf
.ps_dtim_period
;
663 sleep_intv
= rtlpriv
->psc
.dtim_counter
;
666 if (sleep_intv
> MAX_SW_LPS_SLEEP_INTV
)
667 sleep_intv
= MAX_SW_LPS_SLEEP_INTV
;
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
));
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));
682 void rtl_swlps_wq_callback(void *data
)
684 struct rtl_works
*rtlworks
= container_of_dwork_rtl(data
,
687 struct ieee80211_hw
*hw
= rtlworks
->hw
;
688 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
691 ps
= (hw
->conf
.flags
& IEEE80211_CONF_PS
);
693 /* we can sleep after ps null send ok */
694 if (rtlpriv
->psc
.state_inap
) {
695 rtl_swlps_rf_sleep(hw
);
697 if (rtlpriv
->psc
.state
&& !ps
) {
698 rtlpriv
->psc
.sleep_ms
= jiffies_to_msecs(jiffies
-
699 rtlpriv
->psc
.last_action
);
703 rtlpriv
->psc
.last_slept
= jiffies
;
705 rtlpriv
->psc
.last_action
= jiffies
;
706 rtlpriv
->psc
.state
= ps
;