1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. |
4 | * |
5 | * Based on the r8180 driver, which is: |
6 | * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al. |
7 | * |
8 | * Contact Information: wlanfae <wlanfae@realtek.com> |
9 | */ |
10 | #include "rtl_ps.h" |
11 | #include "rtl_core.h" |
12 | #include "r8192E_phy.h" |
13 | #include "r8192E_phyreg.h" |
14 | #include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */ |
15 | #include "r8192E_cmdpkt.h" |
16 | #include <linux/jiffies.h> |
17 | |
18 | static void _rtl92e_hw_sleep(struct net_device *dev) |
19 | { |
20 | struct r8192_priv *priv = rtllib_priv(dev); |
21 | unsigned long flags = 0; |
22 | |
23 | spin_lock_irqsave(&priv->rf_ps_lock, flags); |
24 | if (priv->rf_change_in_progress) { |
25 | spin_unlock_irqrestore(lock: &priv->rf_ps_lock, flags); |
26 | return; |
27 | } |
28 | spin_unlock_irqrestore(lock: &priv->rf_ps_lock, flags); |
29 | rtl92e_set_rf_state(dev, state_to_set: rf_sleep, RF_CHANGE_BY_PS); |
30 | } |
31 | |
32 | void rtl92e_hw_sleep_wq(void *data) |
33 | { |
34 | struct rtllib_device *ieee = container_of_dwork_rsl(data, |
35 | struct rtllib_device, hw_sleep_wq); |
36 | struct net_device *dev = ieee->dev; |
37 | |
38 | _rtl92e_hw_sleep(dev); |
39 | } |
40 | |
41 | void rtl92e_hw_wakeup(struct net_device *dev) |
42 | { |
43 | struct r8192_priv *priv = rtllib_priv(dev); |
44 | unsigned long flags = 0; |
45 | |
46 | spin_lock_irqsave(&priv->rf_ps_lock, flags); |
47 | if (priv->rf_change_in_progress) { |
48 | spin_unlock_irqrestore(lock: &priv->rf_ps_lock, flags); |
49 | schedule_delayed_work(dwork: &priv->rtllib->hw_wakeup_wq, |
50 | delay: msecs_to_jiffies(m: 10)); |
51 | return; |
52 | } |
53 | spin_unlock_irqrestore(lock: &priv->rf_ps_lock, flags); |
54 | rtl92e_set_rf_state(dev, state_to_set: rf_on, RF_CHANGE_BY_PS); |
55 | } |
56 | |
57 | void rtl92e_hw_wakeup_wq(void *data) |
58 | { |
59 | struct rtllib_device *ieee = container_of_dwork_rsl(data, |
60 | struct rtllib_device, hw_wakeup_wq); |
61 | struct net_device *dev = ieee->dev; |
62 | |
63 | rtl92e_hw_wakeup(dev); |
64 | } |
65 | |
66 | #define MIN_SLEEP_TIME 50 |
67 | #define MAX_SLEEP_TIME 10000 |
68 | void rtl92e_enter_sleep(struct net_device *dev, u64 time) |
69 | { |
70 | struct r8192_priv *priv = rtllib_priv(dev); |
71 | |
72 | u32 tmp; |
73 | unsigned long flags; |
74 | unsigned long timeout; |
75 | |
76 | spin_lock_irqsave(&priv->ps_lock, flags); |
77 | |
78 | time -= msecs_to_jiffies(m: 8 + 16 + 7); |
79 | |
80 | timeout = jiffies + msecs_to_jiffies(MIN_SLEEP_TIME); |
81 | if (time_before((unsigned long)time, timeout)) { |
82 | spin_unlock_irqrestore(lock: &priv->ps_lock, flags); |
83 | netdev_info(dev, format: "too short to sleep::%lld < %ld\n" , |
84 | time - jiffies, msecs_to_jiffies(MIN_SLEEP_TIME)); |
85 | return; |
86 | } |
87 | timeout = jiffies + msecs_to_jiffies(MAX_SLEEP_TIME); |
88 | if (time_after((unsigned long)time, timeout)) { |
89 | netdev_info(dev, format: "========>too long to sleep:%lld > %ld\n" , |
90 | time - jiffies, msecs_to_jiffies(MAX_SLEEP_TIME)); |
91 | spin_unlock_irqrestore(lock: &priv->ps_lock, flags); |
92 | return; |
93 | } |
94 | tmp = time - jiffies; |
95 | schedule_delayed_work(dwork: &priv->rtllib->hw_wakeup_wq, delay: tmp); |
96 | schedule_delayed_work(dwork: &priv->rtllib->hw_sleep_wq, delay: 0); |
97 | spin_unlock_irqrestore(lock: &priv->ps_lock, flags); |
98 | } |
99 | |
100 | static void _rtl92e_ps_update_rf_state(struct net_device *dev) |
101 | { |
102 | struct r8192_priv *priv = rtllib_priv(dev); |
103 | struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) |
104 | &priv->rtllib->pwr_save_ctrl; |
105 | |
106 | psc->bSwRfProcessing = true; |
107 | rtl92e_set_rf_state(dev, state_to_set: psc->eInactivePowerState, RF_CHANGE_BY_IPS); |
108 | |
109 | psc->bSwRfProcessing = false; |
110 | } |
111 | |
112 | void rtl92e_ips_enter(struct net_device *dev) |
113 | { |
114 | struct r8192_priv *priv = rtllib_priv(dev); |
115 | struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) |
116 | &priv->rtllib->pwr_save_ctrl; |
117 | enum rt_rf_power_state rt_state; |
118 | |
119 | rt_state = priv->rtllib->rf_power_state; |
120 | if (rt_state == rf_on && !psc->bSwRfProcessing && |
121 | (priv->rtllib->link_state != MAC80211_LINKED)) { |
122 | psc->eInactivePowerState = rf_off; |
123 | _rtl92e_ps_update_rf_state(dev); |
124 | } |
125 | } |
126 | |
127 | void rtl92e_ips_leave(struct net_device *dev) |
128 | { |
129 | struct r8192_priv *priv = rtllib_priv(dev); |
130 | struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) |
131 | &priv->rtllib->pwr_save_ctrl; |
132 | enum rt_rf_power_state rt_state; |
133 | |
134 | rt_state = priv->rtllib->rf_power_state; |
135 | if (rt_state != rf_on && !psc->bSwRfProcessing && |
136 | priv->rtllib->rf_off_reason <= RF_CHANGE_BY_IPS) { |
137 | psc->eInactivePowerState = rf_on; |
138 | _rtl92e_ps_update_rf_state(dev); |
139 | } |
140 | } |
141 | |
142 | void rtl92e_ips_leave_wq(void *data) |
143 | { |
144 | struct rtllib_device *ieee = container_of(data, struct rtllib_device, ips_leave_wq); |
145 | struct net_device *dev = ieee->dev; |
146 | struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); |
147 | |
148 | mutex_lock(&priv->rtllib->ips_mutex); |
149 | rtl92e_ips_leave(dev); |
150 | mutex_unlock(lock: &priv->rtllib->ips_mutex); |
151 | } |
152 | |
153 | void rtl92e_rtllib_ips_leave_wq(struct net_device *dev) |
154 | { |
155 | struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); |
156 | enum rt_rf_power_state rt_state; |
157 | |
158 | rt_state = priv->rtllib->rf_power_state; |
159 | if (rt_state == rf_off) { |
160 | if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_IPS) { |
161 | netdev_warn(dev, format: "%s(): RF is OFF.\n" , |
162 | __func__); |
163 | return; |
164 | } |
165 | netdev_info(dev, format: "=========>%s(): rtl92e_ips_leave\n" , |
166 | __func__); |
167 | schedule_work(work: &priv->rtllib->ips_leave_wq); |
168 | } |
169 | } |
170 | |
171 | void rtl92e_rtllib_ips_leave(struct net_device *dev) |
172 | { |
173 | struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); |
174 | |
175 | mutex_lock(&priv->rtllib->ips_mutex); |
176 | rtl92e_ips_leave(dev); |
177 | mutex_unlock(lock: &priv->rtllib->ips_mutex); |
178 | } |
179 | |
180 | static bool _rtl92e_ps_set_mode(struct net_device *dev, u8 rtPsMode) |
181 | { |
182 | struct r8192_priv *priv = rtllib_priv(dev); |
183 | |
184 | priv->rtllib->ps = rtPsMode; |
185 | if (priv->rtllib->sta_sleep != LPS_IS_WAKE && |
186 | rtPsMode == RTLLIB_PS_DISABLED) { |
187 | unsigned long flags; |
188 | |
189 | rtl92e_hw_wakeup(dev); |
190 | priv->rtllib->sta_sleep = LPS_IS_WAKE; |
191 | |
192 | spin_lock_irqsave(&(priv->rtllib->mgmt_tx_lock), flags); |
193 | rtllib_sta_ps_send_null_frame(ieee: priv->rtllib, pwr: 0); |
194 | spin_unlock_irqrestore(lock: &(priv->rtllib->mgmt_tx_lock), flags); |
195 | } |
196 | |
197 | return true; |
198 | } |
199 | |
200 | void rtl92e_leisure_ps_enter(struct net_device *dev) |
201 | { |
202 | struct r8192_priv *priv = rtllib_priv(dev); |
203 | struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) |
204 | &priv->rtllib->pwr_save_ctrl; |
205 | |
206 | if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) && |
207 | (priv->rtllib->link_state == MAC80211_LINKED))) |
208 | return; |
209 | |
210 | if (psc->bLeisurePs) { |
211 | if (psc->lps_idle_count >= RT_CHECK_FOR_HANG_PERIOD) { |
212 | |
213 | if (priv->rtllib->ps == RTLLIB_PS_DISABLED) |
214 | _rtl92e_ps_set_mode(dev, RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST); |
215 | } else { |
216 | psc->lps_idle_count++; |
217 | } |
218 | } |
219 | } |
220 | |
221 | void rtl92e_leisure_ps_leave(struct net_device *dev) |
222 | { |
223 | struct r8192_priv *priv = rtllib_priv(dev); |
224 | struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) |
225 | &priv->rtllib->pwr_save_ctrl; |
226 | |
227 | if (psc->bLeisurePs) { |
228 | if (priv->rtllib->ps != RTLLIB_PS_DISABLED) |
229 | _rtl92e_ps_set_mode(dev, RTLLIB_PS_DISABLED); |
230 | } |
231 | } |
232 | |