diff options
| author | Lukas Krejci <[email protected]> | 2022-11-30 15:57:52 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-01-02 21:34:13 +0100 |
| commit | 001610f0d0b94859b8c8800dcdfa255343f2ea05 (patch) | |
| tree | 34ed7bfa5e96b6b6090f55c2b1eb3d4f4d117a96 /src/lib.rs | |
| parent | 072b8ce0352f4a000db4d525683d170799b83b1a (diff) | |
Be able to specify the power management mode at init time.
Diffstat (limited to 'src/lib.rs')
| -rw-r--r-- | src/lib.rs | 106 |
1 files changed, 99 insertions, 7 deletions
diff --git a/src/lib.rs b/src/lib.rs index 940322715..884cb082b 100644 --- a/src/lib.rs +++ b/src/lib.rs | |||
| @@ -143,8 +143,92 @@ 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)] | ||
| 147 | pub 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 | |||
| 171 | impl Default for PowerManagementMode { | ||
| 172 | fn default() -> Self { | ||
| 173 | Self::PowerSave | ||
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 177 | impl 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 | |||
| 146 | impl<'a> Control<'a> { | 230 | impl<'a> Control<'a> { |
| 147 | pub async fn init(&mut self, clm: &[u8]) { | 231 | pub async fn init(&mut self, clm: &[u8], power_save_mode: PowerManagementMode) { |
| 148 | const CHUNK_SIZE: usize = 1024; | 232 | const CHUNK_SIZE: usize = 1024; |
| 149 | 233 | ||
| 150 | info!("Downloading CLM..."); | 234 | info!("Downloading CLM..."); |
| @@ -239,12 +323,20 @@ 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 | 326 | // power save mode |
| 243 | self.set_iovar_u32("pm2_sleep_ret", 0xc8).await; | 327 | if power_save_mode != PowerManagementMode::None { |
| 244 | self.set_iovar_u32("bcn_li_bcn", 1).await; | 328 | let mode = power_save_mode.mode(); |
| 245 | self.set_iovar_u32("bcn_li_dtim", 1).await; | 329 | if mode == 2 { |
| 246 | self.set_iovar_u32("assoc_listen", 10).await; | 330 | self.set_iovar_u32("pm2_sleep_ret", power_save_mode.sleep_ret_ms() as u32) |
| 247 | self.ioctl_set_u32(0x86, 0, 2).await; | 331 | .await; |
| 332 | self.set_iovar_u32("bcn_li_bcn", power_save_mode.beacon_period() as u32) | ||
| 333 | .await; | ||
| 334 | self.set_iovar_u32("bcn_li_dtim", power_save_mode.dtim_period() as u32) | ||
| 335 | .await; | ||
| 336 | self.set_iovar_u32("assoc_listen", power_save_mode.assoc() as u32).await; | ||
| 337 | } | ||
| 338 | self.ioctl_set_u32(86, 0, mode).await; | ||
| 339 | } | ||
| 248 | 340 | ||
| 249 | self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto | 341 | self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto |
| 250 | self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any | 342 | self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any |
