diff --git a/Cargo.lock b/Cargo.lock
index cd656d7fc81ca1c86298bdedbb1efbbbd52f8328..45617451fbad6bbff3e3103772596eae85fa185e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -337,7 +337,7 @@ checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
 [[package]]
 name = "caprand"
 version = "0.1.0"
-source = "git+https://github.com/mkj/caprand#1204da26c3d60f75ae8f522494415cc18c736888"
+source = "git+https://github.com/mkj/caprand#a292401a503b422993ee6052a0f6fd316d6bff5c"
 dependencies = [
  "cortex-m",
  "critical-section 1.1.1",
@@ -346,6 +346,7 @@ dependencies = [
  "log",
  "rand 0.8.5",
  "rand_chacha 0.3.1",
+ "rp-pac",
  "sha2 0.10.7",
 ]
 
@@ -1071,6 +1072,8 @@ dependencies = [
  "critical-section 1.1.1",
  "defmt",
  "embedded-hal 0.2.7",
+ "embedded-hal 1.0.0-alpha.11",
+ "embedded-hal-async",
  "futures-util",
  "heapless",
  "log",
diff --git a/embassy/demos/common/src/menu.rs b/embassy/demos/common/src/menu.rs
index 5c4dd5c74794853da117dc0e904bfc9d9119b0d5..f2ac1ae29bd639f98c88e5798b8ec53005ae66e4 100644
--- a/embassy/demos/common/src/menu.rs
+++ b/embassy/demos/common/src/menu.rs
@@ -317,6 +317,7 @@ where
             Outcome::CommandProcessed
         } else if input == 0x03 {
             // Handling ctrl-c, clear current command
+            let _ = write!(self.context, "\r");
             Outcome::CommandProcessed
         } else if (input == 0x08) || (input == 0x7F) {
             // Handling backspace or delete
@@ -364,8 +365,8 @@ where
         };
         match outcome {
             Outcome::CommandProcessed => {
+                self.prompt(self.used > 0);
                 self.used = 0;
-                self.prompt(true);
             }
             Outcome::NeedMore => {}
         }
diff --git a/embassy/demos/picow/Cargo.toml b/embassy/demos/picow/Cargo.toml
index fce77bd8b058a5820e8bf2588a4f5ee9e86c22ab..e14efbe6b0aad8e5e49134eee7b19b4a8f91e4f3 100644
--- a/embassy/demos/picow/Cargo.toml
+++ b/embassy/demos/picow/Cargo.toml
@@ -17,8 +17,8 @@ cyw43-pio = { version = "0.1.0", optional = true }
 embassy-net-w5500 = { version = "0.1.0", optional = true }
 
 embassy-executor = { version = "0.2",  features = ["defmt", "integrated-timers", "executor-thread", "arch-cortex-m", "nightly"] }
-embassy-time = { version = "0.1",  features = ["defmt", "defmt-timestamp-uptime"] }
-embassy-rp = { version = "0.1.0",  features = ["defmt", "unstable-traits", "nightly", "unstable-pac"] }
+embassy-time = { version = "0.1",  features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "nightly"] }
+embassy-rp = { version = "0.1.0",  features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver"] }
 # embassy-net/nightly is required for asynch::Read/Write on TcpReader/TcpWriter
 embassy-net = { version = "0.1.0", features = ["tcp", "dhcpv4", "medium-ethernet", "nightly"] }
 embassy-net-driver = { version = "0.1.0" }
diff --git a/embassy/demos/picow/build.rs b/embassy/demos/picow/build.rs
index 7b19e112bcf15b4da9d3c3fe5ebc98363b5473a6..b51424e2d5855c1a5d8ce5efb8ab405a59d88d57 100644
--- a/embassy/demos/picow/build.rs
+++ b/embassy/demos/picow/build.rs
@@ -43,9 +43,9 @@ fn link() {
 
 fn git() {
     let git_rev = Command::new("git")
-        .args(&["describe", "--always", "--tags", "--dirty=+"])
+        .args(["describe", "--always", "--tags", "--dirty=+"])
         .output()
-        .map(|o| String::from_utf8(o.stdout).unwrap().to_string())
+        .map(|o| String::from_utf8(o.stdout).unwrap())
         .unwrap_or("(unknown)".to_string());
 
     println!("cargo:rustc-env=GIT_REV={git_rev}");
diff --git a/embassy/demos/picow/firmware/43439A0.bin b/embassy/demos/picow/firmware/43439A0.bin
index b46b3beff05de7dfcbf41d53a12bf3a74381881b..017375277d77d10e198deb1c668e2e6bb074d869 100755
Binary files a/embassy/demos/picow/firmware/43439A0.bin and b/embassy/demos/picow/firmware/43439A0.bin differ
diff --git a/embassy/demos/picow/firmware/43439A0_clm.bin b/embassy/demos/picow/firmware/43439A0_clm.bin
index 6e3ba786b2b496ef3d347d8f8150cb433f684692..1fedd753ac255eb8feb4b81a8214d4070a8e414c 100755
Binary files a/embassy/demos/picow/firmware/43439A0_clm.bin and b/embassy/demos/picow/firmware/43439A0_clm.bin differ
diff --git a/embassy/demos/picow/firmware/README.md b/embassy/demos/picow/firmware/README.md
index 7381fdc56bb2f2f8827f2664f0d3e3018fcbdc5d..db3d9c9cf79eabb68b7f0b4eb1700e88cf494257 100644
--- a/embassy/demos/picow/firmware/README.md
+++ b/embassy/demos/picow/firmware/README.md
@@ -2,4 +2,8 @@
 
 Firmware obtained from https://github.com/Infineon/wifi-host-driver/tree/master/WiFi_Host_Driver/resources/firmware/COMPONENT_43439
 
-Licensed under the [Infineon Permissive Binary License](./LICENSE-permissive-binary-license-1.0.txt)
\ No newline at end of file
+Licensed under the [Infineon Permissive Binary License](./LICENSE-permissive-binary-license-1.0.txt)
+
+## Changelog
+
+* 2023-07-28: synced with `ad3bad0` - Update 43439 fw from 7.95.55 ot 7.95.62
diff --git a/embassy/demos/picow/src/flashconfig.rs b/embassy/demos/picow/src/flashconfig.rs
index 792142b5ad6aaf8cbfe6c127a23b6535b55fc9a8..2b6e04d46c00689ff14c9ddd2c3d636d8a9da30d 100644
--- a/embassy/demos/picow/src/flashconfig.rs
+++ b/embassy/demos/picow/src/flashconfig.rs
@@ -12,7 +12,7 @@ pub use {
 #[cfg(feature = "defmt")]
 pub use defmt::{debug, info, warn, panic, error, trace};
 
-use embassy_rp::flash::{Flash, ERASE_SIZE};
+use embassy_rp::flash::{Flash, Async, ERASE_SIZE};
 use embassy_rp::peripherals::FLASH;
 
 use sha2::Digest;
@@ -30,6 +30,8 @@ use demo_common::SSHConfig;
 const CONFIG_OFFSET: u32 = 0x150000;
 pub const FLASH_SIZE: usize = 2*1024*1024;
 
+pub(crate) type Fl<'a> = Flash<'a, FLASH, Async, FLASH_SIZE>;
+
 // SSHConfig::CURRENT_VERSION must be bumped if any of this struct changes
 #[derive(SSHEncode, SSHDecode)]
 struct FlashConfig<'a> {
@@ -50,7 +52,7 @@ fn config_hash(config: &SSHConfig) -> Result<[u8; 32]> {
 }
 
 /// Loads a SSHConfig at startup. Good for persisting hostkeys.
-pub fn load_or_create(flash: &mut Flash<'_, FLASH, FLASH_SIZE>) -> Result<SSHConfig> {
+pub fn load_or_create(flash: &mut Fl<'_>) -> Result<SSHConfig> {
     use snafu::Error;
     match load(flash) {
         Ok(c) => {
@@ -64,7 +66,7 @@ pub fn load_or_create(flash: &mut Flash<'_, FLASH, FLASH_SIZE>) -> Result<SSHCon
     create(flash)
 }
 
-pub fn create(flash: &mut Flash<'_, FLASH, FLASH_SIZE>) -> Result<SSHConfig> {
+pub fn create(flash: &mut Fl<'_>) -> Result<SSHConfig> {
     let c = SSHConfig::new()?;
     if let Err(_) = save(flash, &c) {
         warn!("Error writing config");
@@ -72,7 +74,7 @@ pub fn create(flash: &mut Flash<'_, FLASH, FLASH_SIZE>) -> Result<SSHConfig> {
     Ok(c)
 }
 
-pub fn load(flash: &mut Flash<'_, FLASH, FLASH_SIZE>) -> Result<SSHConfig> {
+pub fn load(flash: &mut Fl<'_>) -> Result<SSHConfig> {
     // let mut buf = [0u8; ERASE_SIZE];
     let mut buf = [0u8; FlashConfig::BUF_SIZE];
     flash.read(CONFIG_OFFSET, &mut buf).map_err(|_| Error::msg("flash error"))?;
@@ -102,7 +104,7 @@ pub fn load(flash: &mut Flash<'_, FLASH, FLASH_SIZE>) -> Result<SSHConfig> {
     }
 }
 
-pub fn save(flash: &mut Flash<'_, FLASH, FLASH_SIZE>, config: &SSHConfig) -> Result<()> {
+pub fn save(flash: &mut Fl<'_>, config: &SSHConfig) -> Result<()> {
     let mut buf = [0u8; ERASE_SIZE];
     let sc = FlashConfig {
         version: SSHConfig::CURRENT_VERSION,
diff --git a/embassy/demos/picow/src/main.rs b/embassy/demos/picow/src/main.rs
index cb4089ac80fa79c88eba2fa29a2381bc8d894fde..b32fad1cce0ff86c7bf64faa09fc855c4060dc1f 100644
--- a/embassy/demos/picow/src/main.rs
+++ b/embassy/demos/picow/src/main.rs
@@ -16,8 +16,7 @@ use {defmt_rtt as _, panic_probe as _};
 
 use embassy_executor::Spawner;
 use embassy_futures::select::select;
-use embassy_net::Stack;
-use embassy_rp::peripherals::FLASH;
+use embassy_net::{Stack, HardwareAddress, EthernetAddress};
 use embedded_io::asynch::Write as _;
 use embedded_io::{asynch, Io};
 
@@ -71,7 +70,7 @@ async fn main(spawner: Spawner) {
     getrandom::register_custom_getrandom!(caprand::getrandom);
 
     // Configuration loaded from flash
-    let mut flash = embassy_rp::flash::Flash::new(p.FLASH);
+    let mut flash = flashconfig::Fl::new(p.FLASH, p.DMA_CH2);
 
     let config = if option_env!("RESET_CONFIG").is_some() {
         flashconfig::create(&mut flash).unwrap()
@@ -120,7 +119,9 @@ async fn main(spawner: Spawner) {
         )
         .await;
 
-        let net_mac = stack.ethernet_address();
+        let net_mac = match stack.hardware_address() {
+            HardwareAddress::Ethernet(EthernetAddress(eth)) => eth,
+        };
         let g = GlobalState { usb_pipe, serial1_pipe, config, flash, watchdog, net_mac };
         state = singleton!(g);
         for _ in 0..NUM_LISTENERS {
@@ -137,7 +138,9 @@ async fn main(spawner: Spawner) {
         )
         .await;
 
-        let net_mac = stack.ethernet_address();
+        let net_mac = match stack.hardware_address() {
+            HardwareAddress::Ethernet(EthernetAddress(eth)) => eth,
+        };
         let g = GlobalState { usb_pipe, serial1_pipe, config, flash, watchdog, net_mac };
         state = singleton!(g);
         for _ in 0..NUM_LISTENERS {
@@ -176,9 +179,7 @@ pub(crate) struct GlobalState {
     pub serial1_pipe: &'static TakePipe<'static>,
 
     pub config: &'static SunsetMutex<SSHConfig>,
-    pub flash: &'static SunsetMutex<
-        embassy_rp::flash::Flash<'static, FLASH, { flashconfig::FLASH_SIZE }>,
-    >,
+    pub flash: &'static SunsetMutex<flashconfig::Fl<'static>>,
     pub watchdog: &'static SunsetMutex<embassy_rp::watchdog::Watchdog>,
 
     pub net_mac: [u8; 6],
diff --git a/embassy/demos/picow/src/w5500.rs b/embassy/demos/picow/src/w5500.rs
index 324ebec8ef3c474d7ae9691210d643ef8e68ca50..b1676ed794c5d93d59c44f2796cf2bef01e6eec0 100644
--- a/embassy/demos/picow/src/w5500.rs
+++ b/embassy/demos/picow/src/w5500.rs
@@ -1,4 +1,4 @@
-// Modified from https://github.com/embassy-rs/cyw43/
+// Modified from https://github.com/embassy-rs/embassy/
 // Copyright (c) 2019-2022 Embassy project contributors
 // MIT or Apache-2.0 license
 
@@ -15,6 +15,7 @@ use embassy_net::{Stack, StackResources};
 use embassy_rp::gpio::{Input, Level, Output, Pull};
 use embassy_rp::peripherals::*;
 use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
+use embassy_time::Delay;
 use embedded_hal_async::spi::ExclusiveDevice;
 
 use embassy_net_w5500::*;
@@ -30,7 +31,7 @@ use crate::{SSHConfig, SunsetMutex};
 async fn ethernet_task(
     runner: Runner<
         'static,
-        ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>>,
+        ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>,
         Input<'static, PIN_21>,
         Output<'static, PIN_20>,
     >,
@@ -65,7 +66,7 @@ pub(crate) async fn w5500_stack(
     let (device, runner) = embassy_net_w5500::new(
         mac_addr,
         state,
-        ExclusiveDevice::new(spi, cs),
+        ExclusiveDevice::new(spi, cs, Delay),
         w5500_int,
         w5500_reset,
     )
diff --git a/embassy/demos/picow/src/wifi.rs b/embassy/demos/picow/src/wifi.rs
index a455ffd3134906b37199bda2e87384f1c5277ded..f0492c03f80b25ef5226c526cf3e1ad822c7e505 100644
--- a/embassy/demos/picow/src/wifi.rs
+++ b/embassy/demos/picow/src/wifi.rs
@@ -16,6 +16,7 @@ pub use defmt::{debug, info, warn, panic, error, trace};
 use embassy_rp::gpio::{Level, Output};
 use embassy_rp::pio::Pio;
 use embassy_rp::peripherals::*;
+use embassy_rp::bind_interrupts;
 use embassy_executor::Spawner;
 use embassy_net::{Stack, StackResources};
 
@@ -28,6 +29,10 @@ use rand::RngCore;
 use crate::demo_common::singleton;
 use crate::{SunsetMutex, SSHConfig};
 
+bind_interrupts!(struct Irqs {
+    PIO0_IRQ_0 => embassy_rp::pio::InterruptHandler<PIO0>;
+});
+
 #[embassy_executor::task]
 async fn wifi_task(
     runner: cyw43::Runner<
@@ -52,7 +57,7 @@ pub(crate) async fn wifi_stack(spawner: &Spawner,
 
     let pwr = Output::new(p23, Level::Low);
     let cs = Output::new(p25, Level::High);
-    let mut pio = Pio::new(pio0);
+    let mut pio = Pio::new(pio0, Irqs);
     let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p24, p29, dma);
 
     let state = singleton!(cyw43::State::new());
@@ -115,7 +120,6 @@ async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! {
 
 // Get the WiFi firmware and Country Locale Matrix (CLM) blobs.
 fn get_fw() -> (&'static [u8], &'static [u8]) {
-    #[cfg(not(feature = "romfw"))]
     let (fw, clm) = (
         include_bytes!("../firmware/43439A0.bin"),
         include_bytes!("../firmware/43439A0_clm.bin"),
@@ -127,8 +131,8 @@ fn get_fw() -> (&'static [u8], &'static [u8]) {
     //     probe-rs-cli download 43439A0_clm.bin --format bin --chip RP2040 --base-address 0x10140000
     #[cfg(feature = "romfw")]
     let (fw, clm) = (
-        unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 224190) },
-        unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) },
+        unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, fw.len()) },
+        unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, clm.len()) },
         );
 
     (fw, clm)
diff --git a/embassy/src/embassy_sunset.rs b/embassy/src/embassy_sunset.rs
index 0dc7a715b19574d255b909f9f402b12d05cb0546..1ee2e34cf57857419117074109ed6d87d0753951 100644
--- a/embassy/src/embassy_sunset.rs
+++ b/embassy/src/embassy_sunset.rs
@@ -67,7 +67,7 @@ impl<'a, C: CliBehaviour, S: ServBehaviour> Inner<'a, C, S> {
         self.chan_handles[num.0 as usize].as_ref().map(|ch| {
             (&mut self.runner, ch, &mut self.wakers)
         })
-        .ok_or_else(|| Error::bug())
+        .ok_or_else(Error::bug)
     }
 }
 
@@ -166,8 +166,8 @@ impl<'a, C: CliBehaviour, S: ServBehaviour> EmbassySunset<'a, C, S> {
                     break
                 }
                 let mut buf = &buf[..l];
-                while buf.len() > 0 {
-                    let n = self.input(&buf).await?;
+                while !buf.is_empty() {
+                    let n = self.input(buf).await?;
                     buf = &buf[n..];
                 }
             }
@@ -352,7 +352,7 @@ impl<'a, C: CliBehaviour, S: ServBehaviour> EmbassySunset<'a, C, S> {
             // Attempt to lock .inner
             let i = self.inner.lock();
             pin_mut!(i);
-            let r = match i.poll(cx) {
+            match i.poll(cx) {
                 Poll::Ready(mut inner) => {
                     f(&mut inner, cx)
                 }
@@ -360,8 +360,7 @@ impl<'a, C: CliBehaviour, S: ServBehaviour> EmbassySunset<'a, C, S> {
                     // .inner lock is busy
                     Poll::Pending
                 }
-            };
-            r
+            }
         })
         .await
     }
@@ -559,7 +558,7 @@ pub async fn io_buf_copy<R, W>(r: &mut R, w: &mut W) -> Result<()>
 {
     loop {
         let b = r.fill_buf().await?;
-        if b.len() == 0 {
+        if b.is_empty() {
             return sunset::error::ChannelEOF.fail();
         }
         let n = b.len();
@@ -583,7 +582,7 @@ pub async fn io_buf_copy_noreaderror<R, W>(r: &mut R, w: &mut W) -> Result<()>
                 continue;
             }
         };
-        if b.len() == 0 {
+        if b.is_empty() {
             return sunset::error::ChannelEOF.fail();
         }
         let n = b.len();
diff --git a/src/channel.rs b/src/channel.rs
index 885677c3292f9f03dcecac2275e98189c3894a11..fd6e5f38f90f6157be09a593d62ef992b80b1e42 100644
--- a/src/channel.rs
+++ b/src/channel.rs
@@ -163,7 +163,7 @@ impl<C: CliBehaviour, S: ServBehaviour> Channels<C, S> {
         dt: ChanData,
         data: &'b [u8],
     ) -> Result<Packet<'b>> {
-        debug_assert!(data.len() > 0);
+        debug_assert!(!data.is_empty());
 
         let ch = self.get_mut(num)?;
         let send = ch.send.as_mut().trap()?;
@@ -330,9 +330,9 @@ impl<C: CliBehaviour, S: ServBehaviour> Channels<C, S> {
 
                         if matches!(ch.ty, ChanType::Session) {
                             // let the CliBehaviour open a shell etc
-                            let mut opener = SessionOpener::new(&ch, s);
+                            let mut opener = SessionOpener::new(ch, s);
                             let r = b.client()?.session_opened(ch.num(), &mut opener).await;
-                            if let Err(_) = r {
+                            if r.is_err() {
                                 trace!("Error from session_opened");
                             }
                         }
@@ -793,10 +793,7 @@ impl Channel {
     }
 
     fn have_recv_eof(&self) -> bool {
-        match self.state {
-            ChanState::RecvEof | ChanState::RecvClose => true,
-            _ => false,
-        }
+        matches!(self.state, ChanState::RecvEof | ChanState::RecvClose)
     }
 
     fn is_closed(&self) -> bool {
diff --git a/src/cliauth.rs b/src/cliauth.rs
index a4c9abbbdca031f5dfc236434cc53014bbe37032..9b279895e55f8839a81a89402f0871dd8382c7f0 100644
--- a/src/cliauth.rs
+++ b/src/cliauth.rs
@@ -143,6 +143,7 @@ impl CliAuth {
         &mut self,
         b: &mut impl CliBehaviour,
     ) -> Option<Req> {
+        #[allow(clippy::never_loop)]
         loop {
             let k = b.next_authkey().unwrap_or_else(|_| {
                 warn!("Error getting pubkey for auth");
@@ -241,7 +242,7 @@ impl CliAuth {
 
                     // Sign the packet without the signature
                     let p = last_req.req_packet(&self.username, parse_ctx, None)?;
-                    let new_sig = Self::auth_sig_msg(&key, sess_id, &p, b).await?;
+                    let new_sig = Self::auth_sig_msg(key, sess_id, &p, b).await?;
                     let p = last_req.req_packet(&self.username, parse_ctx, Some(&new_sig))?;
 
                     s.send(p)?;
@@ -306,7 +307,7 @@ impl CliAuth {
     pub fn success(&mut self, b: &mut impl CliBehaviour) -> Result<()> {
         // TODO: check current state? Probably just informational
         self.state = AuthState::Idle;
-        let _ = b.authenticated();
+        b.authenticated();
         // TODO errors
         Ok(())
     }
diff --git a/src/conn.rs b/src/conn.rs
index 1df974325f6389798f0e4ea8801c4891132d2608..ab2c401c39d2e24949478ce5d8c7075070b12e4c 100644
--- a/src/conn.rs
+++ b/src/conn.rs
@@ -161,10 +161,7 @@ impl<C: CliBehaviour, S: ServBehaviour> Conn<C, S> {
     }
 
     pub(crate) fn initial_sent(&self) -> bool {
-        match self.state {
-            ConnState::SendIdent => false,
-            _ => true,
-        }
+        !matches!(self.state, ConnState::SendIdent)
     }
 
     /// Consumes an input payload which is a view into [`traffic::Traffic::rxbuf`].
@@ -188,7 +185,7 @@ impl<C: CliBehaviour, S: ServBehaviour> Conn<C, S> {
             }
             Err(e) => {
                 error!("Error decoding packet: {e}");
-                return Err(e)
+                Err(e)
             }
         }
     }
diff --git a/src/encrypt.rs b/src/encrypt.rs
index 4ddadef659b2085003909fa08ae75e4ebe24e1bd..8d9c0949c00fbe23cf5cdeac2b28e9646277945c 100644
--- a/src/encrypt.rs
+++ b/src/encrypt.rs
@@ -6,21 +6,24 @@ use {
     log::{debug, error, info, log, trace, warn},
 };
 
-use core::num::Wrapping;
 use core::fmt;
 use core::fmt::Debug;
+use core::num::Wrapping;
 
-use aes::{cipher::{BlockSizeUser, KeyIvInit, KeySizeUser, StreamCipher}, Aes256};
-use pretty_hex::PrettyHex;
-use zeroize::ZeroizeOnDrop;
+use aes::{
+    cipher::{BlockSizeUser, KeyIvInit, KeySizeUser, StreamCipher},
+    Aes256,
+};
 use hmac::{Hmac, Mac};
+use pretty_hex::PrettyHex;
 use sha2::Digest as Sha2DigestForTrait;
+use zeroize::ZeroizeOnDrop;
 
 use crate::*;
 use kex::{self, SessId};
+use ssh_chapoly::SSHChaPoly;
 use sshnames::*;
 use sshwire::hash_mpint;
-use ssh_chapoly::SSHChaPoly;
 
 // TODO: check that Ctr32 is sufficient. Should be OK with SSH rekeying.
 type Aes256Ctr32BE = ctr::Ctr32BE<aes::Aes256>;
@@ -79,7 +82,7 @@ impl KeyState {
 
     /// Decrypt bytes 4 onwards of the buffer and validate AEAD Tag or MAC.
     /// Ensures that the packet meets minimum length.
-    pub fn decrypt<'b>(&mut self, buf: &'b mut [u8]) -> Result<usize, Error> {
+    pub fn decrypt(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
         let e = self.keys.decrypt(buf, self.seq_decrypt.0);
         self.seq_decrypt += 1;
         e
@@ -88,8 +91,10 @@ impl KeyState {
     /// [`buf`] is the entire output buffer to encrypt in place.
     /// payload_len is the length of the payload portion
     /// This is stateful, updating the sequence number.
-    pub fn encrypt<'b>(
-        &mut self, payload_len: usize, buf: &'b mut [u8],
+    pub fn encrypt(
+        &mut self,
+        payload_len: usize,
+        buf: &mut [u8],
     ) -> Result<usize, Error> {
         let e = self.keys.encrypt(payload_len, buf, self.seq_encrypt.0);
         self.seq_encrypt += 1;
@@ -149,8 +154,10 @@ impl Keys {
         }
     }
 
-    pub fn derive(kex_out: kex::KexOutput,
-        sess_id: &SessId, algos: &kex::Algos,
+    pub fn derive(
+        kex_out: kex::KexOutput,
+        sess_id: &SessId,
+        algos: &kex::Algos,
     ) -> Result<Self, Error> {
         let mut key = [0u8; MAX_KEY_LEN];
         let mut iv = [0u8; MAX_IV_LEN];
@@ -222,7 +229,9 @@ impl Keys {
     /// Whether bytes `buf[4..block_size]` are decrypted depends on the cipher, they may be
     /// handled later by [`decrypt`]. Bytes `buf[0..4]` may be left unmodified.
     fn decrypt_first_block(
-        &mut self, buf: &mut [u8], seq: u32,
+        &mut self,
+        buf: &mut [u8],
+        seq: u32,
     ) -> Result<usize, Error> {
         if buf.len() < self.dec.size_block() {
             return Err(Error::bug());
@@ -279,9 +288,7 @@ impl Keys {
 
         match &mut self.dec {
             DecKey::ChaPoly(k) => {
-                k.decrypt(seq, data, mac).map_err(|_| {
-                    Error::BadDecrypt
-                })?;
+                k.decrypt(seq, data, mac).map_err(|_| Error::BadDecrypt)?;
             }
             DecKey::Aes256Ctr(a) => {
                 // safe index, checked data.len()
@@ -297,9 +304,7 @@ impl Keys {
                 let mut h = HmacSha256::new_from_slice(&k).trap()?;
                 h.update(&seq.to_be_bytes());
                 h.update(data);
-                h.verify_slice(mac).map_err(|_| {
-                    Error::BadDecrypt
-                })?;
+                h.verify_slice(mac).map_err(|_| Error::BadDecrypt)?;
             }
         }
 
@@ -345,7 +350,10 @@ impl Keys {
     /// Returns the total length.
     /// Ensures that the packet meets minimum and other length requirements.
     fn encrypt(
-        &mut self, payload_len: usize, buf: &mut [u8], seq: u32,
+        &mut self,
+        payload_len: usize,
+        buf: &mut [u8],
+        seq: u32,
     ) -> Result<usize, Error> {
         let size_block = self.enc.size_block();
         let size_integ = self.integ_enc.size_out();
@@ -389,9 +397,7 @@ impl Keys {
         }
 
         match &mut self.enc {
-            EncKey::ChaPoly(k) => {
-                k.encrypt(seq, enc, mac).trap()?
-            }
+            EncKey::ChaPoly(k) => k.encrypt(seq, enc, mac).trap()?,
             EncKey::Aes256Ctr(a) => {
                 a.apply_keystream(enc);
             }
@@ -484,7 +490,9 @@ impl Debug for EncKey {
 impl EncKey {
     /// Construct a key
     pub fn from_cipher<'a>(
-        cipher: &Cipher, key: &'a [u8], iv: &'a [u8],
+        cipher: &Cipher,
+        key: &'a [u8],
+        iv: &'a [u8],
     ) -> Result<Self, Error> {
         match cipher {
             Cipher::ChaPoly => {
@@ -534,7 +542,9 @@ impl Debug for DecKey {
 impl DecKey {
     /// Construct a key
     pub fn from_cipher<'a>(
-        cipher: &Cipher, key: &'a [u8], iv: &'a [u8],
+        cipher: &Cipher,
+        key: &'a [u8],
+        iv: &'a [u8],
     ) -> Result<Self, Error> {
         match cipher {
             Cipher::ChaPoly => {
@@ -616,12 +626,10 @@ impl Debug for IntegKey {
 }
 
 impl IntegKey {
-    pub fn from_integ<'a>(integ: &Integ, key: &'a [u8]) -> Result<Self, Error> {
+    pub fn from_integ(integ: &Integ, key: &[u8]) -> Result<Self, Error> {
         match integ {
             Integ::ChaPoly => Ok(IntegKey::ChaPoly),
-            Integ::HmacSha256 => {
-                Ok(IntegKey::HmacSha256(key.try_into().trap()?))
-            }
+            Integ::HmacSha256 => Ok(IntegKey::HmacSha256(key.try_into().trap()?)),
         }
     }
     pub fn size_out(&self) -> usize {
@@ -635,17 +643,21 @@ impl IntegKey {
 
 #[cfg(test)]
 mod tests {
-    use crate::sunsetlog::*;
     use crate::encrypt::*;
-    use crate::kex::KexOutput;
     use crate::error::Error;
+    use crate::kex::KexOutput;
     use crate::sshnames::SSH_NAME_CURVE25519;
+    use crate::sunsetlog::*;
     #[allow(unused_imports)]
     use pretty_hex::PrettyHex;
     use sha2::Sha256;
 
     // setting `corrupt` tests that incorrect mac is detected
-    fn do_roundtrips(keys_enc: &mut KeyState, keys_dec: &mut KeyState, corrupt: bool) {
+    fn do_roundtrips(
+        keys_enc: &mut KeyState,
+        keys_dec: &mut KeyState,
+        corrupt: bool,
+    ) {
         for i in 0usize..80 {
             let mut v: std::vec::Vec<u8> = (0u8..i as u8 + 60).collect();
             let orig_payload = v[SSH_PAYLOAD_START..SSH_PAYLOAD_START + i].to_vec();
@@ -698,33 +710,33 @@ mod tests {
         // TODO make this combinatorial
         // order is enc, dec
         const COMBOS: [(Cipher, Integ, Cipher, Integ); 4] = [
-            (Cipher::Aes256Ctr, Integ::HmacSha256,
-                Cipher::Aes256Ctr, Integ::HmacSha256),
-
-            (Cipher::ChaPoly, Integ::ChaPoly,
-                Cipher::ChaPoly, Integ::ChaPoly),
-
-            (Cipher::Aes256Ctr, Integ::HmacSha256,
-                Cipher::ChaPoly, Integ::ChaPoly),
-
-            (Cipher::ChaPoly, Integ::ChaPoly,
-                Cipher::Aes256Ctr, Integ::HmacSha256),
+            (
+                Cipher::Aes256Ctr,
+                Integ::HmacSha256,
+                Cipher::Aes256Ctr,
+                Integ::HmacSha256,
+            ),
+            (Cipher::ChaPoly, Integ::ChaPoly, Cipher::ChaPoly, Integ::ChaPoly),
+            (Cipher::Aes256Ctr, Integ::HmacSha256, Cipher::ChaPoly, Integ::ChaPoly),
+            (Cipher::ChaPoly, Integ::ChaPoly, Cipher::Aes256Ctr, Integ::HmacSha256),
         ];
-        COMBOS.iter().map(|(ce, ie, cd, id)| {
-            Some(kex::Algos {
-                kex: kex::SharedSecret::from_name(SSH_NAME_CURVE25519).unwrap(),
-                hostsig: sign::SigType::Ed25519,
-                cipher_enc: ce.clone(),
-                cipher_dec: cd.clone(),
-                integ_enc: ie.clone(),
-                integ_dec: id.clone(),
-                discard_next: false,
-                is_client: false,
-                send_ext_info: true,
+        COMBOS
+            .iter()
+            .map(|(ce, ie, cd, id)| {
+                Some(kex::Algos {
+                    kex: kex::SharedSecret::from_name(SSH_NAME_CURVE25519).unwrap(),
+                    hostsig: sign::SigType::Ed25519,
+                    cipher_enc: ce.clone(),
+                    cipher_dec: cd.clone(),
+                    integ_enc: ie.clone(),
+                    integ_dec: id.clone(),
+                    discard_next: false,
+                    is_client: false,
+                    send_ext_info: true,
+                })
             })
-        })
-        // and plaintext
-        .chain(core::iter::once(None))
+            // and plaintext
+            .chain(core::iter::once(None))
     }
 
     #[test]
@@ -732,13 +744,17 @@ mod tests {
         init_test_log();
 
         for mut algos in algo_combos() {
-
             let mut keys_enc = KeyState::new_cleartext();
             let mut keys_dec = KeyState::new_cleartext();
             if let Some(ref mut algos) = algos {
                 // arbitrary keys
-                let h = SessId::from_slice(&Sha256::digest("some exchange hash".as_bytes())).unwrap();
-                let sess_id = SessId::from_slice(&Sha256::digest("some sessid".as_bytes())).unwrap();
+                let h = SessId::from_slice(&Sha256::digest(
+                    "some exchange hash".as_bytes(),
+                ))
+                .unwrap();
+                let sess_id =
+                    SessId::from_slice(&Sha256::digest("some sessid".as_bytes()))
+                        .unwrap();
                 let sharedkey = b"hello";
                 let ko = KexOutput::new_test(sharedkey, &algos, &h);
                 let ko_b = KexOutput::new_test(sharedkey, &algos, &h);
@@ -755,7 +771,6 @@ mod tests {
                 trace!("algos dec {algos:?}");
                 let newkeys_b = Keys::derive(ko_b, &sess_id, &algos).unwrap();
                 keys_dec.rekey(newkeys_b);
-
             } else {
                 trace!("Trying cleartext");
             }
@@ -772,12 +787,13 @@ mod tests {
     fn max_enc_payload() {
         init_test_log();
         for algos in algo_combos() {
-
             let mut keys = KeyState::new_cleartext();
             if let Some(algos) = algos {
                 // arbitrary keys
-                let h = SessId::from_slice(&Sha256::digest(b"some exchange hash")).unwrap();
-                let sess_id = SessId::from_slice(&Sha256::digest(b"some sessid")).unwrap();
+                let h = SessId::from_slice(&Sha256::digest(b"some exchange hash"))
+                    .unwrap();
+                let sess_id =
+                    SessId::from_slice(&Sha256::digest(b"some sessid")).unwrap();
                 let sharedkey = b"hello";
                 let ko = KexOutput::new_test(sharedkey, &algos, &h);
                 let newkeys = Keys::derive(ko, &sess_id, &algos).unwrap();
@@ -801,7 +817,7 @@ mod tests {
                     assert!(l >= i.saturating_sub(keys.keys.enc.size_block()));
 
                     // check a larger payload would bump the packet size
-                    let l = keys.encrypt(p+1, &mut buf).unwrap();
+                    let l = keys.encrypt(p + 1, &mut buf).unwrap();
                     assert!(l > i);
                 }
             }
diff --git a/src/ident.rs b/src/ident.rs
index 256904143250068b2a6b904343512822211eb9ff..49f28d3cbd35c9a1de5bb6096d09c59ce994eb51 100644
--- a/src/ident.rs
+++ b/src/ident.rs
@@ -24,7 +24,7 @@ pub(crate) fn write_version(buf: &mut [u8]) -> Result<usize> {
     b[0] = CR;
     b[1] = LF;
 
-    return Ok(total_len)
+    Ok(total_len)
 }
 
 /// Parses and stores the remove SSH version string
diff --git a/src/kex.rs b/src/kex.rs
index f0ed5f0cb8ad9f8f4c5fb93b16d9a5212c9d0b6c..9ae87e4f3113f9ab85fda0989bb39e2a84cc800a 100644
--- a/src/kex.rs
+++ b/src/kex.rs
@@ -32,23 +32,23 @@ pub type SessId = heapless::Vec<u8, MAX_SESSID>;
 use pretty_hex::PrettyHex;
 
 // TODO this will be configurable.
-const fixed_options_kex: &[&'static str] =
+const fixed_options_kex: &[&str] =
     &[SSH_NAME_CURVE25519, SSH_NAME_CURVE25519_LIBSSH];
 
 /// Options that can't be negotiated
-const marker_only_kexs: &[&'static str] =
+const marker_only_kexs: &[&str] =
     &[SSH_NAME_EXT_INFO_C, SSH_NAME_EXT_INFO_S, SSH_NAME_KEXGUESS2];
 
-const fixed_options_hostsig: &[&'static str] = &[
+const fixed_options_hostsig: &[&str] = &[
     SSH_NAME_ED25519,
     #[cfg(feature = "rsa")]
     SSH_NAME_RSA_SHA256,
 ];
 
-const fixed_options_cipher: &[&'static str] =
+const fixed_options_cipher: &[&str] =
     &[SSH_NAME_CHAPOLY, SSH_NAME_AES256_CTR];
-const fixed_options_mac: &[&'static str] = &[SSH_NAME_HMAC_SHA256];
-const fixed_options_comp: &[&'static str] = &[SSH_NAME_NONE];
+const fixed_options_mac: &[&str] = &[SSH_NAME_HMAC_SHA256];
+const fixed_options_comp: &[&str] = &[SSH_NAME_NONE];
 
 pub(crate) struct AlgoConfig {
     kexs: LocalNames,
@@ -193,7 +193,7 @@ impl KexHash {
 
     // Hashes a slice, with added u32 length prefix.
     fn hash_slice(&mut self, v: &[u8]) {
-        self.hash_ctx.update(&(v.len() as u32).to_be_bytes());
+        self.hash_ctx.update((v.len() as u32).to_be_bytes());
         self.hash_ctx.update(v);
     }
 }
@@ -292,7 +292,7 @@ impl Kex {
 
     fn make_kexinit<'a>(cookie: &'a KexCookie, conf: &'a AlgoConfig) -> Packet<'a> {
         packets::KexInit {
-            cookie: cookie,
+            cookie,
             kex: (&conf.kexs).into(),
             hostsig: (&conf.hostsig).into(),
             cipher_c2s: (&conf.ciphers).into(),
@@ -568,7 +568,7 @@ impl SharedSecret {
     }
 
     // server only. consumes algos and kex_hash
-    fn handle_kexdhinit<'a>(
+    fn handle_kexdhinit(
         algos: &mut Algos, mut kex_hash: KexHash,
         p: &packets::KexDHInit,
         s: &mut TrafSend, b: &mut impl ServBehaviour,
@@ -666,18 +666,18 @@ impl KexOutput {
         let (k1, rest) = out.split_at_mut(l);
         let (k2, _) = rest.split_at_mut(len - l);
 
-        let sess_id: &[u8] = &sess_id;
+        let sess_id: &[u8] = sess_id;
 
         let mut hash_ctx = self.partial_hash.clone();
         // K || H is already included
-        hash_ctx.update(&[letter as u8]);
+        hash_ctx.update([letter as u8]);
         hash_ctx.update(sess_id);
         hash_ctx.finalize_into(w.into());
 
         // fill first part
         k1.copy_from_slice(&w[..k1.len()]);
 
-        if k2.len() > 0 {
+        if !k2.is_empty() {
             // generate next block K2 = HASH(K || H || K1)
             let mut hash_ctx = self.partial_hash.clone();
             // K || H is already included
diff --git a/src/namelist.rs b/src/namelist.rs
index f871fac8053eec7e86149965ca30fd9e8a48b9bc..9babd64fb966c90d838732fa7c58f34f8403f8e6 100644
--- a/src/namelist.rs
+++ b/src/namelist.rs
@@ -190,7 +190,7 @@ impl LocalNames {
     }
 
     pub fn first(&self) -> &str {
-        if self.0.len() == 0 {
+        if self.0.is_empty() {
             ""
         } else {
             self.0[0]
diff --git a/src/runner.rs b/src/runner.rs
index 2df15bf169e0114fd0778bae5f33c554d5e727f2..5f5750177faa7a955119a810cf4ed50a02d2b498 100644
--- a/src/runner.rs
+++ b/src/runner.rs
@@ -186,8 +186,9 @@ impl<'a, C: CliBehaviour, S: ServBehaviour> Runner<'a, C, S> {
                 return
             }
         }
-        self.input_waker.replace(waker.clone())
-        .map(|w| w.wake());
+        if let Some(w) = self.input_waker.replace(waker.clone()) {
+            w.wake()
+        }
     }
 
     /// Set a waker to be notified when SSH socket output is ready
@@ -197,8 +198,9 @@ impl<'a, C: CliBehaviour, S: ServBehaviour> Runner<'a, C, S> {
                 return
             }
         }
-        self.output_waker.replace(waker.clone())
-        .map(|w| w.wake());
+        if let Some(w) = self.input_waker.replace(waker.clone()) {
+            w.wake()
+        }
     }
 
     pub fn close(&mut self) {
@@ -232,7 +234,7 @@ impl<'a, C: CliBehaviour, S: ServBehaviour> Runner<'a, C, S> {
             return error::ChannelEOF.fail()
         }
 
-        if buf.len() == 0 {
+        if buf.is_empty() {
             return Ok(0)
         }
 
diff --git a/src/servauth.rs b/src/servauth.rs
index 838d3c96e9d2e52d07c090327513868a4da772b9..d72186fb0c87591e48723daae7bbe61189e2b162 100644
--- a/src/servauth.rs
+++ b/src/servauth.rs
@@ -39,7 +39,7 @@ impl ServAuth {
         // TODO: what to do they've already authed? we have to be careful in case
         // behaviours don't handle it well.
 
-        let username = p.username.clone();
+        let username = p.username;
 
         let inner = async {
             // even allows "none" auth
@@ -142,14 +142,14 @@ impl ServAuth {
             Err(_) => return false,
         };
 
-        let msg = auth::AuthSigMsg::new(&p, sess_id);
+        let msg = auth::AuthSigMsg::new(p, sess_id);
         match sig_type.verify(&m.pubkey.0, &&msg, sig) {
             Ok(()) => true,
             Err(e) => { trace!("sig failed  {e}"); false},
         }
     }
 
-    fn avail_methods<'f>(
+    fn avail_methods(
         &self,
         user: TextString,
         b: &mut impl ServBehaviour,
diff --git a/src/ssh_chapoly.rs b/src/ssh_chapoly.rs
index af70c90486ba4dcd10a235175906b4e4fa7d7cc2..0c333fa99d6f30c7ab85cb72fd4f263d8f004dcb 100644
--- a/src/ssh_chapoly.rs
+++ b/src/ssh_chapoly.rs
@@ -64,7 +64,7 @@ impl SSHChaPoly {
         let mut c = Self::cha20(&self.k1, seq);
         c.apply_keystream(&mut b);
         trace!("packet_length {:?}", b.hex_dump());
-        Ok(u32::from_be_bytes(b.try_into().unwrap()))
+        Ok(u32::from_be_bytes(b))
     }
 
     /// Decrypts in-place and validates the MAC.
@@ -87,7 +87,7 @@ impl SSHChaPoly {
         let poly = Poly1305::new((&poly_key).into());
         // compute_unpadded() adds the necessary trailing 1 byte when padding output
         let tag = poly.compute_unpadded(msg);
-        let good: bool = tag.ct_eq(&msg_tag).into();
+        let good: bool = tag.ct_eq(msg_tag).into();
         if !good {
             return Err(Error::BadDecrypt);
         }
diff --git a/src/sshwire.rs b/src/sshwire.rs
index 1f5498ad690800ea3566e3b6214c377307b43e74..882f1c19e8eee8c15df750c4ed0debba90e006b3 100644
--- a/src/sshwire.rs
+++ b/src/sshwire.rs
@@ -246,7 +246,7 @@ impl<'de> SSHSource<'de> for DecodeBytes<'de> {
 // Hashes a slice to be treated as a mpint. Has u32 length prefix
 // and an extra 0x00 byte if the MSB is set.
 pub fn hash_mpint(hash_ctx: &mut dyn SSHWireDigestUpdate, m: &[u8]) {
-    let pad = m.len() > 0 && (m[0] & 0x80) != 0;
+    let pad = !m.is_empty() && (m[0] & 0x80) != 0;
     let l = m.len() as u32 + pad as u32;
     hash_ctx.digest_update(&l.to_be_bytes());
     if pad {
@@ -657,7 +657,7 @@ impl<'de, T: SSHDecode<'de>> SSHDecode<'de> for OwnOrBorrow<'_, T> {
 impl<'a, T> core::borrow::Borrow<T> for OwnOrBorrow<'a, T> {
     fn borrow(&self) -> &T {
         match self {
-            Self::Own(t) => &t,
+            Self::Own(t) => t,
             Self::Borrow(t) => t,
         }
     }
diff --git a/src/traffic.rs b/src/traffic.rs
index 8162cd9fe54ea05ca6f60cc2c3776bdb510bc253..5261d41e82c821d20424772a3fbe062d2ad6e016 100644
--- a/src/traffic.rs
+++ b/src/traffic.rs
@@ -164,7 +164,7 @@ impl<'a> TrafIn<'a> {
         // Fill the initial block from either Idle with input,
         // partial initial block
         if let Some(idx) = match self.state {
-            RxState::Idle if r.len() > 0 => Some(0),
+            RxState::Idle if !r.is_empty() => Some(0),
             RxState::ReadInitial { idx } => Some(idx),
             _ => None,
         } {
@@ -346,7 +346,7 @@ impl<'a> TrafOut<'a> {
         }
         let plen = sshwire::write_ssh(&mut wbuf[SSH_PAYLOAD_START..], &p)?;
         trace!("Sending {p:?}");
-        trace!("new {plen} {:?}", (&wbuf[SSH_PAYLOAD_START..SSH_PAYLOAD_START+plen]).hex_dump());
+        trace!("new {plen} {:?}", (wbuf[SSH_PAYLOAD_START..SSH_PAYLOAD_START+plen]).hex_dump());
 
         // Encrypt in place
         let elen = keys.encrypt(plen, wbuf)?;
@@ -356,10 +356,7 @@ impl<'a> TrafOut<'a> {
     }
 
     pub fn is_output_pending(&self) -> bool {
-        match self.state {
-            TxState::Write { .. } => true,
-            _ => false
-        }
+        matches!(self.state, TxState::Write { .. })
     }
 
     /// A simple test if a packet can be sent. `send_allowed` should be used
@@ -389,7 +386,7 @@ impl<'a> TrafOut<'a> {
             return Err(Error::bug());
         }
 
-        let len = ident::write_version(&mut self.buf)?;
+        let len = ident::write_version(self.buf)?;
         self.state = TxState::Write { idx: 0, len };
         Ok(())
     }
@@ -429,7 +426,7 @@ pub(crate) struct TrafSend<'s, 'a> {
 }
 
 impl<'s, 'a> TrafSend<'s, 'a> {
-    fn new<'f>(out: &'s mut TrafOut<'a>, keys: &'s mut KeyState) -> Self {
+    fn new(out: &'s mut TrafOut<'a>, keys: &'s mut KeyState) -> Self {
         Self {
             out,
             keys,
diff --git a/sshwire-derive/src/lib.rs b/sshwire-derive/src/lib.rs
index e509c8e43caca4d38a6b71d9376a68b6b2898c55..88bd0f3f542307f9eda24af00f850dd29720f9aa 100644
--- a/sshwire-derive/src/lib.rs
+++ b/sshwire-derive/src/lib.rs
@@ -12,12 +12,11 @@ use virtue::parse::{Attribute, AttributeLocation, EnumBody, StructBody};
 use virtue::utils::{parse_tagged_attribute, ParsedAttribute};
 use virtue::prelude::*;
 
-const ENV_SSHWIRE_DEBUG: &'static str = &"SSHWIRE_DEBUG";
+const ENV_SSHWIRE_DEBUG: &str = "SSHWIRE_DEBUG";
 
 #[proc_macro_derive(SSHEncode, attributes(sshwire))]
 pub fn derive_encode(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-    let r = encode_inner(input).unwrap_or_else(|e| e.into_token_stream());
-    r
+    encode_inner(input).unwrap_or_else(|e| e.into_token_stream())
 }
 
 #[proc_macro_derive(SSHDecode, attributes(sshwire))]
@@ -187,7 +186,7 @@ fn take_field_atts(atts: &[Attribute]) -> Result<Vec<FieldAtt>> {
                             }),
                         };
 
-                        if let Some(_) = g.next() {
+                        if g.next().is_some() {
                             Err(Error::Custom {
                                 error: "Extra unhandled parts".into(),
                                 span: Some(a.tokens.span()),
diff --git a/testing/ci.sh b/testing/ci.sh
index 160580d279555048cf71580e029e3fcbefaa4314..409e1552fdac15669636717ead2a28bb3672396b 100755
--- a/testing/ci.sh
+++ b/testing/ci.sh
@@ -62,6 +62,7 @@ cd embassy/demos/picow
 cargo build --release
 cargo bloat --release -n 100 | tee "$OUT/picow-bloat.txt"
 cargo bloat --release --crates | tee "$OUT/picow-bloat-crates.txt"
+cargo build --release --no-default-features --features w5500,romfw
 )
 size target/thumbv6m-none-eabi/release/sunset-demo-embassy-picow | tee "$OUT/picow-size.txt"