1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2012 Realtek Corporation.*/
7 #include <linux/export.h>
8 #include "btcoexist/rtl_btc.h"
10 bool rtl_ps_enable_nic(struct ieee80211_hw
*hw
)
12 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
13 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
14 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
15 struct rtl_mac
*rtlmac
= rtl_mac(rtl_priv(hw
));
17 /*<1> reset trx ring */
18 if (rtlhal
->interface
== INTF_PCI
)
19 rtlpriv
->intf_ops
->reset_trx_ring(hw
);
21 if (is_hal_stop(rtlhal
))
22 rtl_dbg(rtlpriv
, COMP_ERR
, DBG_WARNING
,
23 "Driver is already down!\n");
25 /*<2> Enable Adapter */
26 if (rtlpriv
->cfg
->ops
->hw_init(hw
))
28 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_RETRY_LIMIT
,
30 RT_CLEAR_PS_LEVEL(ppsc
, RT_RF_OFF_LEVL_HALT_NIC
);
32 rtlpriv
->cfg
->ops
->switch_channel(hw
);
33 rtlpriv
->cfg
->ops
->set_channel_access(hw
);
34 rtlpriv
->cfg
->ops
->set_bw_mode(hw
,
35 cfg80211_get_chandef_type(&hw
->conf
.chandef
));
37 /*<3> Enable Interrupt */
38 rtlpriv
->cfg
->ops
->enable_interrupt(hw
);
41 rtl_watch_dog_timer_callback(&rtlpriv
->works
.watchdog_timer
);
45 EXPORT_SYMBOL(rtl_ps_enable_nic
);
47 bool rtl_ps_disable_nic(struct ieee80211_hw
*hw
)
49 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
51 /*<1> Stop all timer */
52 rtl_deinit_deferred_work(hw
, true);
54 /*<2> Disable Interrupt */
55 rtlpriv
->cfg
->ops
->disable_interrupt(hw
);
56 tasklet_kill(&rtlpriv
->works
.irq_tasklet
);
58 /*<3> Disable Adapter */
59 rtlpriv
->cfg
->ops
->hw_disable(hw
);
63 EXPORT_SYMBOL(rtl_ps_disable_nic
);
65 static bool rtl_ps_set_rf_state(struct ieee80211_hw
*hw
,
66 enum rf_pwrstate state_toset
,
69 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
70 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
71 bool actionallowed
= false;
74 /*Only one thread can change
75 *the RF state at one time, and others
76 *should wait to be executed.
79 spin_lock(&rtlpriv
->locks
.rf_ps_lock
);
80 if (ppsc
->rfchange_inprogress
) {
81 spin_unlock(&rtlpriv
->locks
.rf_ps_lock
);
83 rtl_dbg(rtlpriv
, COMP_ERR
, DBG_WARNING
,
84 "RF Change in progress! Wait to set..state_toset(%d).\n",
87 /* Set RF after the previous action is done. */
88 while (ppsc
->rfchange_inprogress
) {
91 /*Wait too long, return false to avoid
98 ppsc
->rfchange_inprogress
= true;
99 spin_unlock(&rtlpriv
->locks
.rf_ps_lock
);
104 switch (state_toset
) {
106 ppsc
->rfoff_reason
&= (~changesource
);
108 if ((changesource
== RF_CHANGE_BY_HW
) &&
109 (ppsc
->hwradiooff
)) {
110 ppsc
->hwradiooff
= false;
113 if (!ppsc
->rfoff_reason
) {
114 ppsc
->rfoff_reason
= 0;
115 actionallowed
= true;
122 if ((changesource
== RF_CHANGE_BY_HW
) && !ppsc
->hwradiooff
) {
123 ppsc
->hwradiooff
= true;
126 ppsc
->rfoff_reason
|= changesource
;
127 actionallowed
= true;
131 ppsc
->rfoff_reason
|= changesource
;
132 actionallowed
= true;
136 pr_err("switch case %#x not processed\n", state_toset
);
141 rtlpriv
->cfg
->ops
->set_rf_power_state(hw
, state_toset
);
143 spin_lock(&rtlpriv
->locks
.rf_ps_lock
);
144 ppsc
->rfchange_inprogress
= false;
145 spin_unlock(&rtlpriv
->locks
.rf_ps_lock
);
147 return actionallowed
;
150 static void _rtl_ps_inactive_ps(struct ieee80211_hw
*hw
)
152 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
153 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
154 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
156 ppsc
->swrf_processing
= true;
158 if (ppsc
->inactive_pwrstate
== ERFON
&&
159 rtlhal
->interface
== INTF_PCI
) {
160 if ((ppsc
->reg_rfps_level
& RT_RF_OFF_LEVL_ASPM
) &&
161 RT_IN_PS_LEVEL(ppsc
, RT_PS_LEVEL_ASPM
)) {
162 rtlpriv
->intf_ops
->disable_aspm(hw
);
163 RT_CLEAR_PS_LEVEL(ppsc
, RT_PS_LEVEL_ASPM
);
167 rtl_ps_set_rf_state(hw
, ppsc
->inactive_pwrstate
,
170 if (ppsc
->inactive_pwrstate
== ERFOFF
&&
171 rtlhal
->interface
== INTF_PCI
) {
172 if (ppsc
->reg_rfps_level
& RT_RF_OFF_LEVL_ASPM
&&
173 !RT_IN_PS_LEVEL(ppsc
, RT_PS_LEVEL_ASPM
)) {
174 rtlpriv
->intf_ops
->enable_aspm(hw
);
175 RT_SET_PS_LEVEL(ppsc
, RT_PS_LEVEL_ASPM
);
179 ppsc
->swrf_processing
= false;
182 void rtl_ips_nic_off_wq_callback(struct work_struct
*work
)
184 struct rtl_works
*rtlworks
= container_of(work
, struct rtl_works
,
185 ips_nic_off_wq
.work
);
186 struct ieee80211_hw
*hw
= rtlworks
->hw
;
187 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
188 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
189 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
190 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
191 enum rf_pwrstate rtstate
;
193 if (mac
->opmode
!= NL80211_IFTYPE_STATION
) {
194 rtl_dbg(rtlpriv
, COMP_ERR
, DBG_WARNING
,
195 "not station return\n");
202 if (mac
->link_state
> MAC80211_NOLINK
)
205 if (is_hal_stop(rtlhal
))
208 if (rtlpriv
->sec
.being_setkey
)
211 if (rtlpriv
->cfg
->ops
->bt_coex_off_before_lps
)
212 rtlpriv
->cfg
->ops
->bt_coex_off_before_lps(hw
);
214 if (ppsc
->inactiveps
) {
215 rtstate
= ppsc
->rfpwr_state
;
218 *Do not enter IPS in the following conditions:
219 *(1) RF is already OFF or Sleep
220 *(2) swrf_processing (indicates the IPS is still under going)
221 *(3) Connectted (only disconnected can trigger IPS)
222 *(4) IBSS (send Beacon)
223 *(5) AP mode (send Beacon)
224 *(6) monitor mode (rcv packet)
227 if (rtstate
== ERFON
&&
228 !ppsc
->swrf_processing
&&
229 (mac
->link_state
== MAC80211_NOLINK
) &&
230 !mac
->act_scanning
) {
231 rtl_dbg(rtlpriv
, COMP_RF
, DBG_TRACE
,
232 "IPSEnter(): Turn off RF\n");
234 ppsc
->inactive_pwrstate
= ERFOFF
;
235 ppsc
->in_powersavemode
= true;
237 /* call before RF off */
238 if (rtlpriv
->cfg
->ops
->get_btc_status())
239 rtlpriv
->btcoexist
.btc_ops
->btc_ips_notify(rtlpriv
,
240 ppsc
->inactive_pwrstate
);
242 /*rtl_pci_reset_trx_ring(hw); */
243 _rtl_ps_inactive_ps(hw
);
248 void rtl_ips_nic_off(struct ieee80211_hw
*hw
)
250 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
252 /* because when link with ap, mac80211 will ask us
253 * to disable nic quickly after scan before linking,
254 * this will cause link failed, so we delay 100ms here
256 queue_delayed_work(rtlpriv
->works
.rtl_wq
,
257 &rtlpriv
->works
.ips_nic_off_wq
, MSECS(100));
260 /* NOTICE: any opmode should exc nic_on, or disable without
261 * nic_on may something wrong, like adhoc TP
263 void rtl_ips_nic_on(struct ieee80211_hw
*hw
)
265 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
266 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
267 enum rf_pwrstate rtstate
;
269 cancel_delayed_work_sync(&rtlpriv
->works
.ips_nic_off_wq
);
271 mutex_lock(&rtlpriv
->locks
.ips_mutex
);
272 if (ppsc
->inactiveps
) {
273 rtstate
= ppsc
->rfpwr_state
;
275 if (rtstate
!= ERFON
&&
276 !ppsc
->swrf_processing
&&
277 ppsc
->rfoff_reason
<= RF_CHANGE_BY_IPS
) {
279 ppsc
->inactive_pwrstate
= ERFON
;
280 ppsc
->in_powersavemode
= false;
281 _rtl_ps_inactive_ps(hw
);
282 /* call after RF on */
283 if (rtlpriv
->cfg
->ops
->get_btc_status())
284 rtlpriv
->btcoexist
.btc_ops
->btc_ips_notify(rtlpriv
,
285 ppsc
->inactive_pwrstate
);
288 mutex_unlock(&rtlpriv
->locks
.ips_mutex
);
290 EXPORT_SYMBOL_GPL(rtl_ips_nic_on
);
295 *Determine if we can set Fw into PS mode
296 *in current condition.Return TRUE if it
299 static bool rtl_get_fwlps_doze(struct ieee80211_hw
*hw
)
301 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
302 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
303 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
306 ps_timediff
= jiffies_to_msecs(jiffies
-
307 ppsc
->last_delaylps_stamp_jiffies
);
309 if (ps_timediff
< 2000) {
310 rtl_dbg(rtlpriv
, COMP_POWER
, DBG_LOUD
,
311 "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n");
315 if (mac
->link_state
!= MAC80211_LINKED
)
318 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
)
324 /* Change current and default preamble mode.*/
325 void rtl_lps_set_psmode(struct ieee80211_hw
*hw
, u8 rt_psmode
)
327 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
328 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
329 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
332 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
)
335 if (mac
->link_state
!= MAC80211_LINKED
)
338 if (ppsc
->dot11_psmode
== rt_psmode
&& rt_psmode
== EACTIVE
)
341 /* Update power save mode configured. */
342 ppsc
->dot11_psmode
= rt_psmode
;
347 * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode
348 * cmd to set Fw into PS mode.
350 * Send H2C fw_pwrmode cmd to Fw to set Fw into Active
351 * mode and set RPWM to turn RF on.
354 if ((ppsc
->fwctrl_lps
) && ppsc
->report_linked
) {
355 if (ppsc
->dot11_psmode
== EACTIVE
) {
356 rtl_dbg(rtlpriv
, COMP_RF
, DBG_DMESG
,
357 "FW LPS leave ps_mode:%x\n",
360 ppsc
->pwr_mode
= FW_PS_ACTIVE_MODE
;
362 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_FW_LPS_ACTION
,
363 (u8
*)(&enter_fwlps
));
364 if (ppsc
->p2p_ps_info
.opp_ps
)
365 rtl_p2p_ps_cmd(hw
, P2P_PS_ENABLE
);
367 if (rtlpriv
->cfg
->ops
->get_btc_status())
368 rtlpriv
->btcoexist
.btc_ops
->btc_lps_notify(rtlpriv
, rt_psmode
);
370 if (rtl_get_fwlps_doze(hw
)) {
371 rtl_dbg(rtlpriv
, COMP_RF
, DBG_DMESG
,
372 "FW LPS enter ps_mode:%x\n",
373 ppsc
->fwctrl_psmode
);
374 if (rtlpriv
->cfg
->ops
->get_btc_status())
375 rtlpriv
->btcoexist
.btc_ops
->btc_lps_notify(rtlpriv
, rt_psmode
);
377 ppsc
->pwr_mode
= ppsc
->fwctrl_psmode
;
379 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
380 HW_VAR_FW_LPS_ACTION
,
381 (u8
*)(&enter_fwlps
));
384 /* Reset the power save related parameters. */
385 ppsc
->dot11_psmode
= EACTIVE
;
391 /* Interrupt safe routine to enter the leisure power save mode.*/
392 static void rtl_lps_enter_core(struct ieee80211_hw
*hw
)
394 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
395 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
396 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
398 if (!ppsc
->fwctrl_lps
)
401 if (rtlpriv
->sec
.being_setkey
)
404 if (rtlpriv
->link_info
.busytraffic
)
407 /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
408 if (mac
->cnt_after_linked
< 5)
411 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
)
414 if (mac
->link_state
!= MAC80211_LINKED
)
417 mutex_lock(&rtlpriv
->locks
.lps_mutex
);
419 /* Don't need to check (ppsc->dot11_psmode == EACTIVE), because
420 * bt_ccoexist may ask to enter lps.
421 * In normal case, this constraint move to rtl_lps_set_psmode().
423 rtl_dbg(rtlpriv
, COMP_POWER
, DBG_LOUD
,
424 "Enter 802.11 power save mode...\n");
425 rtl_lps_set_psmode(hw
, EAUTOPS
);
427 mutex_unlock(&rtlpriv
->locks
.lps_mutex
);
430 /* Interrupt safe routine to leave the leisure power save mode.*/
431 static void rtl_lps_leave_core(struct ieee80211_hw
*hw
)
433 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
434 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
435 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
437 mutex_lock(&rtlpriv
->locks
.lps_mutex
);
439 if (ppsc
->fwctrl_lps
) {
440 if (ppsc
->dot11_psmode
!= EACTIVE
) {
443 /*rtlpriv->cfg->ops->enable_interrupt(hw); */
445 if (ppsc
->reg_rfps_level
& RT_RF_LPS_LEVEL_ASPM
&&
446 RT_IN_PS_LEVEL(ppsc
, RT_PS_LEVEL_ASPM
) &&
447 rtlhal
->interface
== INTF_PCI
) {
448 rtlpriv
->intf_ops
->disable_aspm(hw
);
449 RT_CLEAR_PS_LEVEL(ppsc
, RT_PS_LEVEL_ASPM
);
452 rtl_dbg(rtlpriv
, COMP_POWER
, DBG_LOUD
,
453 "Busy Traffic,Leave 802.11 power save..\n");
455 rtl_lps_set_psmode(hw
, EACTIVE
);
458 mutex_unlock(&rtlpriv
->locks
.lps_mutex
);
462 void rtl_swlps_beacon(struct ieee80211_hw
*hw
, void *data
, unsigned int len
)
464 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
465 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
466 struct ieee80211_hdr
*hdr
= data
;
467 struct ieee80211_tim_ie
*tim_ie
;
473 if (mac
->opmode
!= NL80211_IFTYPE_STATION
)
476 if (!rtlpriv
->psc
.swctrl_lps
)
479 if (rtlpriv
->mac80211
.link_state
!= MAC80211_LINKED
)
482 if (!rtlpriv
->psc
.sw_ps_enabled
)
485 if (rtlpriv
->psc
.fwctrl_lps
)
488 if (likely(!(hw
->conf
.flags
& IEEE80211_CONF_PS
)))
491 /* check if this really is a beacon */
492 if (!ieee80211_is_beacon(hdr
->frame_control
))
495 /* min. beacon length + FCS_LEN */
496 if (len
<= 40 + FCS_LEN
)
499 /* and only beacons from the associated BSSID, please */
500 if (!ether_addr_equal_64bits(hdr
->addr3
, rtlpriv
->mac80211
.bssid
))
503 rtlpriv
->psc
.last_beacon
= jiffies
;
505 tim
= rtl_find_ie(data
, len
- FCS_LEN
, WLAN_EID_TIM
);
509 if (tim
[1] < sizeof(*tim_ie
))
513 tim_ie
= (struct ieee80211_tim_ie
*) &tim
[2];
515 if (!WARN_ON_ONCE(!hw
->conf
.ps_dtim_period
))
516 rtlpriv
->psc
.dtim_counter
= tim_ie
->dtim_count
;
518 /* Check whenever the PHY can be turned off again. */
520 /* 1. What about buffered unicast traffic for our AID? */
521 u_buffed
= ieee80211_check_tim(tim_ie
, tim_len
,
522 rtlpriv
->mac80211
.assoc_id
);
524 /* 2. Maybe the AP wants to send multicast/broadcast data? */
525 m_buffed
= tim_ie
->bitmap_ctrl
& 0x01;
526 rtlpriv
->psc
.multi_buffered
= m_buffed
;
528 /* unicast will process by mac80211 through
529 * set ~IEEE80211_CONF_PS, So we just check
530 * multicast frames here */
532 /* back to low-power land. and delay is
533 * prevent null power save frame tx fail */
534 queue_delayed_work(rtlpriv
->works
.rtl_wq
,
535 &rtlpriv
->works
.ps_work
, MSECS(5));
537 rtl_dbg(rtlpriv
, COMP_POWER
, DBG_DMESG
,
538 "u_bufferd: %x, m_buffered: %x\n", u_buffed
, m_buffed
);
541 EXPORT_SYMBOL_GPL(rtl_swlps_beacon
);
543 void rtl_swlps_rf_awake(struct ieee80211_hw
*hw
)
545 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
546 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
547 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
549 if (!rtlpriv
->psc
.swctrl_lps
)
551 if (mac
->link_state
!= MAC80211_LINKED
)
554 if (ppsc
->reg_rfps_level
& RT_RF_LPS_LEVEL_ASPM
&&
555 RT_IN_PS_LEVEL(ppsc
, RT_PS_LEVEL_ASPM
)) {
556 rtlpriv
->intf_ops
->disable_aspm(hw
);
557 RT_CLEAR_PS_LEVEL(ppsc
, RT_PS_LEVEL_ASPM
);
560 mutex_lock(&rtlpriv
->locks
.lps_mutex
);
561 rtl_ps_set_rf_state(hw
, ERFON
, RF_CHANGE_BY_PS
);
562 mutex_unlock(&rtlpriv
->locks
.lps_mutex
);
565 void rtl_swlps_rfon_wq_callback(struct work_struct
*work
)
567 struct rtl_works
*rtlworks
= container_of(work
, struct rtl_works
,
569 struct ieee80211_hw
*hw
= rtlworks
->hw
;
571 rtl_swlps_rf_awake(hw
);
574 void rtl_swlps_rf_sleep(struct ieee80211_hw
*hw
)
576 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
577 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
578 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
581 if (!rtlpriv
->psc
.sw_ps_enabled
)
584 if ((rtlpriv
->sec
.being_setkey
) ||
585 (mac
->opmode
== NL80211_IFTYPE_ADHOC
))
588 /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
589 if ((mac
->link_state
!= MAC80211_LINKED
) || (mac
->cnt_after_linked
< 5))
592 if (rtlpriv
->link_info
.busytraffic
)
595 spin_lock(&rtlpriv
->locks
.rf_ps_lock
);
596 if (rtlpriv
->psc
.rfchange_inprogress
) {
597 spin_unlock(&rtlpriv
->locks
.rf_ps_lock
);
600 spin_unlock(&rtlpriv
->locks
.rf_ps_lock
);
602 mutex_lock(&rtlpriv
->locks
.lps_mutex
);
603 rtl_ps_set_rf_state(hw
, ERFSLEEP
, RF_CHANGE_BY_PS
);
604 mutex_unlock(&rtlpriv
->locks
.lps_mutex
);
606 if (ppsc
->reg_rfps_level
& RT_RF_OFF_LEVL_ASPM
&&
607 !RT_IN_PS_LEVEL(ppsc
, RT_PS_LEVEL_ASPM
)) {
608 rtlpriv
->intf_ops
->enable_aspm(hw
);
609 RT_SET_PS_LEVEL(ppsc
, RT_PS_LEVEL_ASPM
);
612 /* here is power save alg, when this beacon is DTIM
613 * we will set sleep time to dtim_period * n;
614 * when this beacon is not DTIM, we will set sleep
615 * time to sleep_intv = rtlpriv->psc.dtim_counter or
616 * MAX_SW_LPS_SLEEP_INTV(default set to 5) */
618 if (rtlpriv
->psc
.dtim_counter
== 0) {
619 if (hw
->conf
.ps_dtim_period
== 1)
620 sleep_intv
= hw
->conf
.ps_dtim_period
* 2;
622 sleep_intv
= hw
->conf
.ps_dtim_period
;
624 sleep_intv
= rtlpriv
->psc
.dtim_counter
;
627 if (sleep_intv
> MAX_SW_LPS_SLEEP_INTV
)
628 sleep_intv
= MAX_SW_LPS_SLEEP_INTV
;
630 /* this print should always be dtim_conter = 0 &
631 * sleep = dtim_period, that meaons, we should
632 * awake before every dtim */
633 rtl_dbg(rtlpriv
, COMP_POWER
, DBG_DMESG
,
634 "dtim_counter:%x will sleep :%d beacon_intv\n",
635 rtlpriv
->psc
.dtim_counter
, sleep_intv
);
637 /* we tested that 40ms is enough for sw & hw sw delay */
638 queue_delayed_work(rtlpriv
->works
.rtl_wq
, &rtlpriv
->works
.ps_rfon_wq
,
639 MSECS(sleep_intv
* mac
->vif
->bss_conf
.beacon_int
- 40));
642 void rtl_lps_change_work_callback(struct work_struct
*work
)
644 struct rtl_works
*rtlworks
=
645 container_of(work
, struct rtl_works
, lps_change_work
);
646 struct ieee80211_hw
*hw
= rtlworks
->hw
;
647 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
649 if (rtlpriv
->enter_ps
)
650 rtl_lps_enter_core(hw
);
652 rtl_lps_leave_core(hw
);
654 EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback
);
656 void rtl_lps_enter(struct ieee80211_hw
*hw
, bool may_block
)
658 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
661 return rtl_lps_enter_core(hw
);
662 rtlpriv
->enter_ps
= true;
663 schedule_work(&rtlpriv
->works
.lps_change_work
);
665 EXPORT_SYMBOL_GPL(rtl_lps_enter
);
667 void rtl_lps_leave(struct ieee80211_hw
*hw
, bool may_block
)
669 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
672 return rtl_lps_leave_core(hw
);
673 rtlpriv
->enter_ps
= false;
674 schedule_work(&rtlpriv
->works
.lps_change_work
);
676 EXPORT_SYMBOL_GPL(rtl_lps_leave
);
678 void rtl_swlps_wq_callback(struct work_struct
*work
)
680 struct rtl_works
*rtlworks
= container_of(work
, struct rtl_works
,
682 struct ieee80211_hw
*hw
= rtlworks
->hw
;
683 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
686 ps
= (hw
->conf
.flags
& IEEE80211_CONF_PS
);
688 /* we can sleep after ps null send ok */
689 if (rtlpriv
->psc
.state_inap
) {
690 rtl_swlps_rf_sleep(hw
);
692 if (rtlpriv
->psc
.state
&& !ps
) {
693 rtlpriv
->psc
.sleep_ms
= jiffies_to_msecs(jiffies
-
694 rtlpriv
->psc
.last_action
);
698 rtlpriv
->psc
.last_slept
= jiffies
;
700 rtlpriv
->psc
.last_action
= jiffies
;
701 rtlpriv
->psc
.state
= ps
;
705 static void rtl_p2p_noa_ie(struct ieee80211_hw
*hw
, void *data
,
708 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
709 struct ieee80211_mgmt
*mgmt
= data
;
710 struct rtl_p2p_ps_info
*p2pinfo
= &(rtlpriv
->psc
.p2p_ps_info
);
713 static u8 p2p_oui_ie_type
[4] = {0x50, 0x6f, 0x9a, 0x09};
714 u8 noa_num
, index
, i
, noa_index
= 0;
715 bool find_p2p_ie
= false , find_p2p_ps_ie
= false;
717 pos
= (u8
*)mgmt
->u
.beacon
.variable
;
721 while (pos
+ 1 < end
) {
722 if (pos
+ 2 + pos
[1] > end
)
725 if (pos
[0] == 221 && pos
[1] > 4) {
726 if (memcmp(&pos
[2], p2p_oui_ie_type
, 4) == 0) {
738 while (ie
+ 1 < end
) {
739 noa_len
= le16_to_cpu(*((__le16
*)&ie
[1]));
740 if (ie
+ 3 + ie
[1] > end
)
744 find_p2p_ps_ie
= true;
745 if ((noa_len
- 2) % 13 != 0) {
746 rtl_dbg(rtlpriv
, COMP_INIT
, DBG_LOUD
,
747 "P2P notice of absence: invalid length.%d\n",
751 noa_num
= (noa_len
- 2) / 13;
752 if (noa_num
> P2P_MAX_NOA_NUM
)
753 noa_num
= P2P_MAX_NOA_NUM
;
757 if (rtlpriv
->psc
.p2p_ps_info
.p2p_ps_mode
==
758 P2P_PS_NONE
|| noa_index
!= p2pinfo
->noa_index
) {
759 rtl_dbg(rtlpriv
, COMP_FW
, DBG_LOUD
,
761 p2pinfo
->noa_index
= noa_index
;
762 p2pinfo
->opp_ps
= (ie
[4] >> 7);
763 p2pinfo
->ctwindow
= ie
[4] & 0x7F;
764 p2pinfo
->noa_num
= noa_num
;
766 for (i
= 0; i
< noa_num
; i
++) {
767 p2pinfo
->noa_count_type
[i
] =
770 p2pinfo
->noa_duration
[i
] =
771 le32_to_cpu(*(__le32
*)(ie
+ index
));
773 p2pinfo
->noa_interval
[i
] =
774 le32_to_cpu(*(__le32
*)(ie
+ index
));
776 p2pinfo
->noa_start_time
[i
] =
777 le32_to_cpu(*(__le32
*)(ie
+ index
));
781 if (p2pinfo
->opp_ps
== 1) {
782 p2pinfo
->p2p_ps_mode
= P2P_PS_CTWINDOW
;
783 /* Driver should wait LPS entering
786 if (rtlpriv
->psc
.fw_current_inpsmode
)
789 } else if (p2pinfo
->noa_num
> 0) {
790 p2pinfo
->p2p_ps_mode
= P2P_PS_NOA
;
791 rtl_p2p_ps_cmd(hw
, P2P_PS_ENABLE
);
792 } else if (p2pinfo
->p2p_ps_mode
> P2P_PS_NONE
) {
793 rtl_p2p_ps_cmd(hw
, P2P_PS_DISABLE
);
801 if (find_p2p_ie
== true) {
802 if ((p2pinfo
->p2p_ps_mode
> P2P_PS_NONE
) &&
803 (find_p2p_ps_ie
== false))
804 rtl_p2p_ps_cmd(hw
, P2P_PS_DISABLE
);
808 static void rtl_p2p_action_ie(struct ieee80211_hw
*hw
, void *data
,
811 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
812 struct ieee80211_mgmt
*mgmt
= data
;
813 struct rtl_p2p_ps_info
*p2pinfo
= &(rtlpriv
->psc
.p2p_ps_info
);
814 u8 noa_num
, index
, i
, noa_index
= 0;
817 static u8 p2p_oui_ie_type
[4] = {0x50, 0x6f, 0x9a, 0x09};
819 pos
= (u8
*)&mgmt
->u
.action
.category
;
823 if (pos
[0] == 0x7f) {
824 if (memcmp(&pos
[1], p2p_oui_ie_type
, 4) == 0)
831 rtl_dbg(rtlpriv
, COMP_FW
, DBG_LOUD
, "action frame find P2P IE.\n");
833 while (ie
+ 1 < end
) {
834 noa_len
= le16_to_cpu(*(__le16
*)&ie
[1]);
835 if (ie
+ 3 + ie
[1] > end
)
839 rtl_dbg(rtlpriv
, COMP_FW
, DBG_LOUD
, "find NOA IE.\n");
840 RT_PRINT_DATA(rtlpriv
, COMP_FW
, DBG_LOUD
, "noa ie ",
842 if ((noa_len
- 2) % 13 != 0) {
843 rtl_dbg(rtlpriv
, COMP_FW
, DBG_LOUD
,
844 "P2P notice of absence: invalid length.%d\n",
848 noa_num
= (noa_len
- 2) / 13;
849 if (noa_num
> P2P_MAX_NOA_NUM
)
850 noa_num
= P2P_MAX_NOA_NUM
;
854 if (rtlpriv
->psc
.p2p_ps_info
.p2p_ps_mode
==
855 P2P_PS_NONE
|| noa_index
!= p2pinfo
->noa_index
) {
856 p2pinfo
->noa_index
= noa_index
;
857 p2pinfo
->opp_ps
= (ie
[4] >> 7);
858 p2pinfo
->ctwindow
= ie
[4] & 0x7F;
859 p2pinfo
->noa_num
= noa_num
;
861 for (i
= 0; i
< noa_num
; i
++) {
862 p2pinfo
->noa_count_type
[i
] =
865 p2pinfo
->noa_duration
[i
] =
866 le32_to_cpu(*(__le32
*)(ie
+ index
));
868 p2pinfo
->noa_interval
[i
] =
869 le32_to_cpu(*(__le32
*)(ie
+ index
));
871 p2pinfo
->noa_start_time
[i
] =
872 le32_to_cpu(*(__le32
*)(ie
+ index
));
876 if (p2pinfo
->opp_ps
== 1) {
877 p2pinfo
->p2p_ps_mode
= P2P_PS_CTWINDOW
;
878 /* Driver should wait LPS entering
881 if (rtlpriv
->psc
.fw_current_inpsmode
)
884 } else if (p2pinfo
->noa_num
> 0) {
885 p2pinfo
->p2p_ps_mode
= P2P_PS_NOA
;
886 rtl_p2p_ps_cmd(hw
, P2P_PS_ENABLE
);
887 } else if (p2pinfo
->p2p_ps_mode
> P2P_PS_NONE
) {
888 rtl_p2p_ps_cmd(hw
, P2P_PS_DISABLE
);
897 void rtl_p2p_ps_cmd(struct ieee80211_hw
*hw
, u8 p2p_ps_state
)
899 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
900 struct rtl_ps_ctl
*rtlps
= rtl_psc(rtl_priv(hw
));
901 struct rtl_p2p_ps_info
*p2pinfo
= &(rtlpriv
->psc
.p2p_ps_info
);
903 rtl_dbg(rtlpriv
, COMP_FW
, DBG_LOUD
, " p2p state %x\n", p2p_ps_state
);
904 switch (p2p_ps_state
) {
906 p2pinfo
->p2p_ps_state
= p2p_ps_state
;
907 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_H2C_FW_P2P_PS_OFFLOAD
,
909 p2pinfo
->noa_index
= 0;
910 p2pinfo
->ctwindow
= 0;
912 p2pinfo
->noa_num
= 0;
913 p2pinfo
->p2p_ps_mode
= P2P_PS_NONE
;
914 if (rtlps
->fw_current_inpsmode
) {
915 if (rtlps
->smart_ps
== 0) {
917 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
918 HW_VAR_H2C_FW_PWRMODE
,
925 if (p2pinfo
->p2p_ps_mode
> P2P_PS_NONE
) {
926 p2pinfo
->p2p_ps_state
= p2p_ps_state
;
928 if (p2pinfo
->ctwindow
> 0) {
929 if (rtlps
->smart_ps
!= 0) {
931 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
932 HW_VAR_H2C_FW_PWRMODE
,
936 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
937 HW_VAR_H2C_FW_P2P_PS_OFFLOAD
,
943 case P2P_PS_SCAN_DONE
:
944 case P2P_PS_ALLSTASLEEP
:
945 if (p2pinfo
->p2p_ps_mode
> P2P_PS_NONE
) {
946 p2pinfo
->p2p_ps_state
= p2p_ps_state
;
947 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
948 HW_VAR_H2C_FW_P2P_PS_OFFLOAD
,
955 rtl_dbg(rtlpriv
, COMP_FW
, DBG_LOUD
,
956 "ctwindow %x oppps %x\n",
957 p2pinfo
->ctwindow
, p2pinfo
->opp_ps
);
958 rtl_dbg(rtlpriv
, COMP_FW
, DBG_LOUD
,
959 "count %x duration %x index %x interval %x start time %x noa num %x\n",
960 p2pinfo
->noa_count_type
[0],
961 p2pinfo
->noa_duration
[0],
963 p2pinfo
->noa_interval
[0],
964 p2pinfo
->noa_start_time
[0],
966 rtl_dbg(rtlpriv
, COMP_FW
, DBG_LOUD
, "end\n");
969 void rtl_p2p_info(struct ieee80211_hw
*hw
, void *data
, unsigned int len
)
971 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
972 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
973 struct ieee80211_hdr
*hdr
= data
;
977 if (mac
->link_state
!= MAC80211_LINKED
)
979 /* min. beacon length + FCS_LEN */
980 if (len
<= 40 + FCS_LEN
)
983 /* and only beacons from the associated BSSID, please */
984 if (!ether_addr_equal_64bits(hdr
->addr3
, rtlpriv
->mac80211
.bssid
))
987 /* check if this really is a beacon */
988 if (!(ieee80211_is_beacon(hdr
->frame_control
) ||
989 ieee80211_is_probe_resp(hdr
->frame_control
) ||
990 ieee80211_is_action(hdr
->frame_control
)))
993 if (ieee80211_is_action(hdr
->frame_control
))
994 rtl_p2p_action_ie(hw
, data
, len
- FCS_LEN
);
996 rtl_p2p_noa_ie(hw
, data
, len
- FCS_LEN
);
998 EXPORT_SYMBOL_GPL(rtl_p2p_info
);