Be able to specify the power management mode at init time.

This commit is contained in:
Lukas Krejci 2022-11-30 15:57:52 +01:00 committed by Dario Nieuwenhuis
parent 072b8ce035
commit 001610f0d0
2 changed files with 100 additions and 8 deletions

View File

@ -70,7 +70,7 @@ async fn main(spawner: Spawner) {
spawner.spawn(wifi_task(runner)).unwrap();
control.init(clm).await;
control.init(clm, cyw43::PowerManagementMode::PowerSave).await;
//control.join_open(env!("WIFI_NETWORK")).await;
control.join_wpa2(env!("WIFI_NETWORK"), env!("WIFI_PASSWORD")).await;

View File

@ -143,8 +143,92 @@ pub struct Control<'a> {
ioctl_state: &'a Cell<IoctlState>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PowerManagementMode {
/// Custom, officially unsupported mode. Use at your own risk.
/// All power-saving features set to their max at only a marginal decrease in power consumption
/// as oppposed to `Aggressive`.
SuperSave,
/// Aggressive power saving mode.
Aggressive,
/// The default mode.
PowerSave,
/// Performance is prefered over power consumption but still some power is conserved as opposed to
/// `None`.
Performance,
/// Unlike all the other PM modes, this lowers the power consumption at all times at the cost of
/// a much lower throughput.
ThroughputThrottling,
/// No power management is configured. This consumes the most power.
None,
}
impl Default for PowerManagementMode {
fn default() -> Self {
Self::PowerSave
}
}
impl PowerManagementMode {
fn sleep_ret_ms(&self) -> u16 {
match self {
PowerManagementMode::SuperSave => 2000,
PowerManagementMode::Aggressive => 2000,
PowerManagementMode::PowerSave => 200,
PowerManagementMode::Performance => 20,
PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
PowerManagementMode::None => 0, // value doesn't matter
}
}
fn beacon_period(&self) -> u8 {
match self {
PowerManagementMode::SuperSave => 255,
PowerManagementMode::Aggressive => 1,
PowerManagementMode::PowerSave => 1,
PowerManagementMode::Performance => 1,
PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
PowerManagementMode::None => 0, // value doesn't matter
}
}
fn dtim_period(&self) -> u8 {
match self {
PowerManagementMode::SuperSave => 255,
PowerManagementMode::Aggressive => 1,
PowerManagementMode::PowerSave => 1,
PowerManagementMode::Performance => 1,
PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
PowerManagementMode::None => 0, // value doesn't matter
}
}
fn assoc(&self) -> u8 {
match self {
PowerManagementMode::SuperSave => 255,
PowerManagementMode::Aggressive => 10,
PowerManagementMode::PowerSave => 10,
PowerManagementMode::Performance => 1,
PowerManagementMode::ThroughputThrottling => 0, // value doesn't matter
PowerManagementMode::None => 0, // value doesn't matter
}
}
fn mode(&self) -> u32 {
match self {
PowerManagementMode::ThroughputThrottling => 1,
_ => 2,
}
}
}
impl<'a> Control<'a> {
pub async fn init(&mut self, clm: &[u8]) {
pub async fn init(&mut self, clm: &[u8], power_save_mode: PowerManagementMode) {
const CHUNK_SIZE: usize = 1024;
info!("Downloading CLM...");
@ -239,12 +323,20 @@ impl<'a> Control<'a> {
Timer::after(Duration::from_millis(100)).await;
// power save mode 2
self.set_iovar_u32("pm2_sleep_ret", 0xc8).await;
self.set_iovar_u32("bcn_li_bcn", 1).await;
self.set_iovar_u32("bcn_li_dtim", 1).await;
self.set_iovar_u32("assoc_listen", 10).await;
self.ioctl_set_u32(0x86, 0, 2).await;
// power save mode
if power_save_mode != PowerManagementMode::None {
let mode = power_save_mode.mode();
if mode == 2 {
self.set_iovar_u32("pm2_sleep_ret", power_save_mode.sleep_ret_ms() as u32)
.await;
self.set_iovar_u32("bcn_li_bcn", power_save_mode.beacon_period() as u32)
.await;
self.set_iovar_u32("bcn_li_dtim", power_save_mode.dtim_period() as u32)
.await;
self.set_iovar_u32("assoc_listen", power_save_mode.assoc() as u32).await;
}
self.ioctl_set_u32(86, 0, mode).await;
}
self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto
self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any