aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-01-02 21:38:51 +0100
committerGitHub <[email protected]>2023-01-02 21:38:51 +0100
commit9900ac2c9a1e5c4ad2a30b2057f25cb19a27369b (patch)
treebb102787f330a0b327500ae5327d1447b3de2e42 /src
parent072b8ce0352f4a000db4d525683d170799b83b1a (diff)
parenta2bae33d8460eee6c3af6f20a790f725cf2c5602 (diff)
Merge pull request #29 from metlos/fix-pm
Be able to specify the power management mode at init time.
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs103
1 files changed, 96 insertions, 7 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 940322715..5733506ac 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -143,6 +143,90 @@ pub struct Control<'a> {
143 ioctl_state: &'a Cell<IoctlState>, 143 ioctl_state: &'a Cell<IoctlState>,
144} 144}
145 145
146#[derive(Debug, Clone, Copy, PartialEq, Eq)]
147pub enum PowerManagementMode {
148 /// Custom, officially unsupported mode. Use at your own risk.
149 /// All power-saving features set to their max at only a marginal decrease in power consumption
150 /// as oppposed to `Aggressive`.
151 SuperSave,
152
153 /// Aggressive power saving mode.
154 Aggressive,
155
156 /// The default mode.
157 PowerSave,
158
159 /// Performance is prefered over power consumption but still some power is conserved as opposed to
160 /// `None`.
161 Performance,
162
163 /// Unlike all the other PM modes, this lowers the power consumption at all times at the cost of
164 /// a much lower throughput.
165 ThroughputThrottling,
166
167 /// No power management is configured. This consumes the most power.
168 None,
169}
170
171impl Default for PowerManagementMode {
172 fn default() -> Self {
173 Self::PowerSave
174 }
175}
176
177impl PowerManagementMode {
178 fn sleep_ret_ms(&self) -> u16 {
179 match self {
180 PowerManagementMode::SuperSave => 2000,
181 PowerManagementMode::Aggressive => 2000,
182 PowerManagementMode::PowerSave => 200,
183 PowerManagementMode::Performance => 20,
184 PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
185 PowerManagementMode::None => 0, // value doesn't matter
186 }
187 }
188
189 fn beacon_period(&self) -> u8 {
190 match self {
191 PowerManagementMode::SuperSave => 255,
192 PowerManagementMode::Aggressive => 1,
193 PowerManagementMode::PowerSave => 1,
194 PowerManagementMode::Performance => 1,
195 PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
196 PowerManagementMode::None => 0, // value doesn't matter
197 }
198 }
199
200 fn dtim_period(&self) -> u8 {
201 match self {
202 PowerManagementMode::SuperSave => 255,
203 PowerManagementMode::Aggressive => 1,
204 PowerManagementMode::PowerSave => 1,
205 PowerManagementMode::Performance => 1,
206 PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
207 PowerManagementMode::None => 0, // value doesn't matter
208 }
209 }
210
211 fn assoc(&self) -> u8 {
212 match self {
213 PowerManagementMode::SuperSave => 255,
214 PowerManagementMode::Aggressive => 10,
215 PowerManagementMode::PowerSave => 10,
216 PowerManagementMode::Performance => 1,
217 PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
218 PowerManagementMode::None => 0, // value doesn't matter
219 }
220 }
221
222 fn mode(&self) -> u32 {
223 match self {
224 PowerManagementMode::ThroughputThrottling => 1,
225 _ => 2,
226 }
227 }
228}
229
146impl<'a> Control<'a> { 230impl<'a> Control<'a> {
147 pub async fn init(&mut self, clm: &[u8]) { 231 pub async fn init(&mut self, clm: &[u8]) {
148 const CHUNK_SIZE: usize = 1024; 232 const CHUNK_SIZE: usize = 1024;
@@ -239,13 +323,6 @@ impl<'a> Control<'a> {
239 323
240 Timer::after(Duration::from_millis(100)).await; 324 Timer::after(Duration::from_millis(100)).await;
241 325
242 // power save mode 2
243 self.set_iovar_u32("pm2_sleep_ret", 0xc8).await;
244 self.set_iovar_u32("bcn_li_bcn", 1).await;
245 self.set_iovar_u32("bcn_li_dtim", 1).await;
246 self.set_iovar_u32("assoc_listen", 10).await;
247 self.ioctl_set_u32(0x86, 0, 2).await;
248
249 self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto 326 self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto
250 self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any 327 self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any
251 328
@@ -257,6 +334,18 @@ impl<'a> Control<'a> {
257 info!("INIT DONE"); 334 info!("INIT DONE");
258 } 335 }
259 336
337 pub async fn set_power_management(&mut self, mode: PowerManagementMode) {
338 // power save mode
339 let mode_num = mode.mode();
340 if mode_num == 2 {
341 self.set_iovar_u32("pm2_sleep_ret", mode.sleep_ret_ms() as u32).await;
342 self.set_iovar_u32("bcn_li_bcn", mode.beacon_period() as u32).await;
343 self.set_iovar_u32("bcn_li_dtim", mode.dtim_period() as u32).await;
344 self.set_iovar_u32("assoc_listen", mode.assoc() as u32).await;
345 }
346 self.ioctl_set_u32(86, 0, mode_num).await;
347 }
348
260 pub async fn join_open(&mut self, ssid: &str) { 349 pub async fn join_open(&mut self, ssid: &str) {
261 self.set_iovar_u32("ampdu_ba_wsize", 8).await; 350 self.set_iovar_u32("ampdu_ba_wsize", 8).await;
262 351