diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-01-02 21:38:51 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-01-02 21:38:51 +0100 |
| commit | 9900ac2c9a1e5c4ad2a30b2057f25cb19a27369b (patch) | |
| tree | bb102787f330a0b327500ae5327d1447b3de2e42 /src | |
| parent | 072b8ce0352f4a000db4d525683d170799b83b1a (diff) | |
| parent | a2bae33d8460eee6c3af6f20a790f725cf2c5602 (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.rs | 103 |
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)] | ||
| 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]) { |
| 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 | ||
