diff --git a/embassy-net-driver-channel/src/lib.rs b/embassy-net-driver-channel/src/lib.rs index 369dc5a9d..0c8dcc22b 100644 --- a/embassy-net-driver-channel/src/lib.rs +++ b/embassy-net-driver-channel/src/lib.rs @@ -34,24 +34,29 @@ impl State { rx: zerocopy_channel::Channel<'d, NoopRawMutex, PacketBuf>, tx: zerocopy_channel::Channel<'d, NoopRawMutex, PacketBuf>, - link_state: Mutex>, + shared: Mutex>, } /// State of the LinkState -struct LinkStateState { - state: LinkState, +struct Shared { + link_state: LinkState, waker: WakerRegistration, + ethernet_address: [u8; 6], } pub struct Runner<'d, const MTU: usize> { tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf>, rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf>, - link_state: &'d Mutex>, + shared: &'d Mutex>, +} + +#[derive(Clone, Copy)] +pub struct StateRunner<'d> { + shared: &'d Mutex>, } pub struct RxRunner<'d, const MTU: usize> { rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf>, - link_state: &'d Mutex>, } pub struct TxRunner<'d, const MTU: usize> { @@ -59,20 +64,30 @@ pub struct TxRunner<'d, const MTU: usize> { } impl<'d, const MTU: usize> Runner<'d, MTU> { - pub fn split(self) -> (RxRunner<'d, MTU>, TxRunner<'d, MTU>) { + pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) { ( - RxRunner { - link_state: self.link_state, - rx_chan: self.rx_chan, - }, + StateRunner { shared: self.shared }, + RxRunner { rx_chan: self.rx_chan }, TxRunner { tx_chan: self.tx_chan }, ) } + pub fn state_runner(&self) -> StateRunner<'d> { + StateRunner { shared: self.shared } + } + pub fn set_link_state(&mut self, state: LinkState) { - self.link_state.lock(|s| { + self.shared.lock(|s| { let s = &mut *s.borrow_mut(); - s.state = state; + s.link_state = state; + s.waker.wake(); + }); + } + + pub fn set_ethernet_address(&mut self, address: [u8; 6]) { + self.shared.lock(|s| { + let s = &mut *s.borrow_mut(); + s.ethernet_address = address; s.waker.wake(); }); } @@ -122,15 +137,25 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { } } -impl<'d, const MTU: usize> RxRunner<'d, MTU> { - pub fn set_link_state(&mut self, state: LinkState) { - self.link_state.lock(|s| { +impl<'d> StateRunner<'d> { + pub fn set_link_state(&self, state: LinkState) { + self.shared.lock(|s| { let s = &mut *s.borrow_mut(); - s.state = state; + s.link_state = state; s.waker.wake(); }); } + pub fn set_ethernet_address(&self, address: [u8; 6]) { + self.shared.lock(|s| { + let s = &mut *s.borrow_mut(); + s.ethernet_address = address; + s.waker.wake(); + }); + } +} + +impl<'d, const MTU: usize> RxRunner<'d, MTU> { pub async fn rx_buf(&mut self) -> &mut [u8] { let p = self.rx_chan.send().await; &mut p.buf @@ -194,8 +219,9 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( let state = unsafe { &mut *state_uninit }.write(StateInner { rx: zerocopy_channel::Channel::new(&mut state.rx[..]), tx: zerocopy_channel::Channel::new(&mut state.tx[..]), - link_state: Mutex::new(RefCell::new(LinkStateState { - state: LinkState::Down, + shared: Mutex::new(RefCell::new(Shared { + link_state: LinkState::Down, + ethernet_address, waker: WakerRegistration::new(), })), }); @@ -207,12 +233,11 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( Runner { tx_chan: tx_receiver, rx_chan: rx_sender, - link_state: &state.link_state, + shared: &state.shared, }, Device { caps, - ethernet_address, - link_state: &state.link_state, + shared: &state.shared, rx: rx_receiver, tx: tx_sender, }, @@ -233,9 +258,8 @@ impl PacketBuf { pub struct Device<'d, const MTU: usize> { rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf>, tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf>, - link_state: &'d Mutex>, + shared: &'d Mutex>, caps: Capabilities, - ethernet_address: [u8; 6], } impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> { @@ -265,14 +289,14 @@ impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> { } fn ethernet_address(&self) -> [u8; 6] { - self.ethernet_address + self.shared.lock(|s| s.borrow().ethernet_address) } fn link_state(&mut self, cx: &mut Context) -> LinkState { - self.link_state.lock(|s| { + self.shared.lock(|s| { let s = &mut *s.borrow_mut(); s.waker.register(cx.waker()); - s.state + s.link_state }) } } diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index b58c9cf36..e4a4218e3 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -111,20 +111,13 @@ impl Stack { #[cfg(feature = "medium-ethernet")] let medium = device.capabilities().medium; - #[cfg(feature = "medium-ethernet")] - let ethernet_addr = if medium == Medium::Ethernet { - device.ethernet_address() - } else { - [0, 0, 0, 0, 0, 0] - }; - let mut b = InterfaceBuilder::new(); b = b.ip_addrs(&mut resources.addresses[..]); b = b.random_seed(random_seed); #[cfg(feature = "medium-ethernet")] if medium == Medium::Ethernet { - b = b.hardware_addr(HardwareAddress::Ethernet(EthernetAddress(ethernet_addr))); + b = b.hardware_addr(HardwareAddress::Ethernet(EthernetAddress(device.ethernet_address()))); b = b.neighbor_cache(NeighborCache::new(&mut resources.neighbor_cache[..])); b = b.routes(Routes::new(&mut resources.routes[..])); } @@ -261,6 +254,13 @@ impl Inner { fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { s.waker.register(cx.waker()); + #[cfg(feature = "medium-ethernet")] + if self.device.capabilities().medium == Medium::Ethernet { + s.iface.set_hardware_addr(HardwareAddress::Ethernet(EthernetAddress( + self.device.ethernet_address(), + ))); + } + let timestamp = instant_to_smoltcp(Instant::now()); let mut smoldev = DriverAdapter { cx: Some(cx), diff --git a/embassy-usb/src/class/cdc_ncm/embassy_net.rs b/embassy-usb/src/class/cdc_ncm/embassy_net.rs index 7ecf693d2..501df2d8c 100644 --- a/embassy-usb/src/class/cdc_ncm/embassy_net.rs +++ b/embassy-usb/src/class/cdc_ncm/embassy_net.rs @@ -25,16 +25,16 @@ pub struct Runner<'d, D: Driver<'d>, const MTU: usize> { impl<'d, D: Driver<'d>, const MTU: usize> Runner<'d, D, MTU> { pub async fn run(mut self) -> ! { - let (mut rx_chan, mut tx_chan) = self.ch.split(); + let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); let rx_fut = async move { loop { trace!("WAITING for connection"); - rx_chan.set_link_state(LinkState::Down); + state_chan.set_link_state(LinkState::Down); self.rx_usb.wait_connection().await.unwrap(); trace!("Connected"); - rx_chan.set_link_state(LinkState::Up); + state_chan.set_link_state(LinkState::Up); loop { let p = rx_chan.rx_buf().await;