| 
						
						
						
						 |  | @@ -1,6 +1,5 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | #![no_std] |  |  |  | #![no_std] | 
			
		
	
		
		
			
				
					
					|  |  |  | #![doc = include_str!("../README.md")] |  |  |  | #![doc = include_str!("../README.md")] | 
			
		
	
		
		
			
				
					
					|  |  |  | #![warn(missing_docs)] |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | // must go first! |  |  |  | // must go first! | 
			
		
	
		
		
			
				
					
					|  |  |  | mod fmt; |  |  |  | mod fmt; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -16,9 +15,6 @@ use embassy_sync::blocking_mutex::Mutex; | 
			
		
	
		
		
			
				
					
					|  |  |  | use embassy_sync::waitqueue::WakerRegistration; |  |  |  | use embassy_sync::waitqueue::WakerRegistration; | 
			
		
	
		
		
			
				
					
					|  |  |  | use embassy_sync::zerocopy_channel; |  |  |  | use embassy_sync::zerocopy_channel; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Channel state. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Holds a buffer of packets with size MTU, for both TX and RX. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { |  |  |  | pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     rx: [PacketBuf<MTU>; N_RX], |  |  |  |     rx: [PacketBuf<MTU>; N_RX], | 
			
		
	
		
		
			
				
					
					|  |  |  |     tx: [PacketBuf<MTU>; N_TX], |  |  |  |     tx: [PacketBuf<MTU>; N_TX], | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -28,7 +24,6 @@ pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | 
			
		
	
		
		
			
				
					
					|  |  |  | impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> { |  |  |  | impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new(); |  |  |  |     const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Create a new channel state. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub const fn new() -> Self { |  |  |  |     pub const fn new() -> Self { | 
			
		
	
		
		
			
				
					
					|  |  |  |         Self { |  |  |  |         Self { | 
			
		
	
		
		
			
				
					
					|  |  |  |             rx: [Self::NEW_PACKET; N_RX], |  |  |  |             rx: [Self::NEW_PACKET; N_RX], | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -44,45 +39,33 @@ struct StateInner<'d, const MTU: usize> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     shared: Mutex<NoopRawMutex, RefCell<Shared>>, |  |  |  |     shared: Mutex<NoopRawMutex, RefCell<Shared>>, | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /// State of the LinkState | 
			
		
	
		
		
			
				
					
					|  |  |  | struct Shared { |  |  |  | struct Shared { | 
			
		
	
		
		
			
				
					
					|  |  |  |     link_state: LinkState, |  |  |  |     link_state: LinkState, | 
			
		
	
		
		
			
				
					
					|  |  |  |     waker: WakerRegistration, |  |  |  |     waker: WakerRegistration, | 
			
		
	
		
		
			
				
					
					|  |  |  |     hardware_address: driver::HardwareAddress, |  |  |  |     hardware_address: driver::HardwareAddress, | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Channel runner. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Holds the shared state and the lower end of channels for inbound and outbound packets. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | pub struct Runner<'d, const MTU: usize> { |  |  |  | pub struct Runner<'d, const MTU: usize> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |  |  |  |     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | 
			
		
	
		
		
			
				
					
					|  |  |  |     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |  |  |  |     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | 
			
		
	
		
		
			
				
					
					|  |  |  |     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, |  |  |  |     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// State runner. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Holds the shared state of the channel such as link state. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #[derive(Clone, Copy)] |  |  |  | #[derive(Clone, Copy)] | 
			
		
	
		
		
			
				
					
					|  |  |  | pub struct StateRunner<'d> { |  |  |  | pub struct StateRunner<'d> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, |  |  |  |     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// RX runner. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Holds the lower end of the channel for passing inbound packets up the stack. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | pub struct RxRunner<'d, const MTU: usize> { |  |  |  | pub struct RxRunner<'d, const MTU: usize> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |  |  |  |     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// TX runner. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Holds the lower end of the channel for passing outbound packets down the stack. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | pub struct TxRunner<'d, const MTU: usize> { |  |  |  | pub struct TxRunner<'d, const MTU: usize> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |  |  |  |     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | impl<'d, const MTU: usize> Runner<'d, MTU> { |  |  |  | impl<'d, const MTU: usize> Runner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Split the runner into separate runners for controlling state, rx and tx. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) { |  |  |  |     pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         ( |  |  |  |         ( | 
			
		
	
		
		
			
				
					
					|  |  |  |             StateRunner { shared: self.shared }, |  |  |  |             StateRunner { shared: self.shared }, | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -91,7 +74,6 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         ) |  |  |  |         ) | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Split the runner into separate runners for controlling state, rx and tx borrowing the underlying state. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn borrow_split(&mut self) -> (StateRunner<'_>, RxRunner<'_, MTU>, TxRunner<'_, MTU>) { |  |  |  |     pub fn borrow_split(&mut self) -> (StateRunner<'_>, RxRunner<'_, MTU>, TxRunner<'_, MTU>) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         ( |  |  |  |         ( | 
			
		
	
		
		
			
				
					
					|  |  |  |             StateRunner { shared: self.shared }, |  |  |  |             StateRunner { shared: self.shared }, | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -104,12 +86,10 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         ) |  |  |  |         ) | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Create a state runner sharing the state channel. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn state_runner(&self) -> StateRunner<'d> { |  |  |  |     pub fn state_runner(&self) -> StateRunner<'d> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         StateRunner { shared: self.shared } |  |  |  |         StateRunner { shared: self.shared } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Set the link state. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn set_link_state(&mut self, state: LinkState) { |  |  |  |     pub fn set_link_state(&mut self, state: LinkState) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.shared.lock(|s| { |  |  |  |         self.shared.lock(|s| { | 
			
		
	
		
		
			
				
					
					|  |  |  |             let s = &mut *s.borrow_mut(); |  |  |  |             let s = &mut *s.borrow_mut(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -118,7 +98,6 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         }); |  |  |  |         }); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Set the hardware address. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) { |  |  |  |     pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.shared.lock(|s| { |  |  |  |         self.shared.lock(|s| { | 
			
		
	
		
		
			
				
					
					|  |  |  |             let s = &mut *s.borrow_mut(); |  |  |  |             let s = &mut *s.borrow_mut(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -127,19 +106,16 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         }); |  |  |  |         }); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Wait until there is space for more inbound packets and return a slice they can be copied into. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub async fn rx_buf(&mut self) -> &mut [u8] { |  |  |  |     pub async fn rx_buf(&mut self) -> &mut [u8] { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let p = self.rx_chan.send().await; |  |  |  |         let p = self.rx_chan.send().await; | 
			
		
	
		
		
			
				
					
					|  |  |  |         &mut p.buf |  |  |  |         &mut p.buf | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Check if there is space for more inbound packets right now. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { |  |  |  |     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let p = self.rx_chan.try_send()?; |  |  |  |         let p = self.rx_chan.try_send()?; | 
			
		
	
		
		
			
				
					
					|  |  |  |         Some(&mut p.buf) |  |  |  |         Some(&mut p.buf) | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Polling the inbound channel if there is space for packets. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |  |  |  |     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         match self.rx_chan.poll_send(cx) { |  |  |  |         match self.rx_chan.poll_send(cx) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             Poll::Ready(p) => Poll::Ready(&mut p.buf), |  |  |  |             Poll::Ready(p) => Poll::Ready(&mut p.buf), | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -147,26 +123,22 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Mark packet of len bytes as pushed to the inbound channel. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn rx_done(&mut self, len: usize) { |  |  |  |     pub fn rx_done(&mut self, len: usize) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let p = self.rx_chan.try_send().unwrap(); |  |  |  |         let p = self.rx_chan.try_send().unwrap(); | 
			
		
	
		
		
			
				
					
					|  |  |  |         p.len = len; |  |  |  |         p.len = len; | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.rx_chan.send_done(); |  |  |  |         self.rx_chan.send_done(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Wait until there is space for more outbound packets and return a slice they can be copied into. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub async fn tx_buf(&mut self) -> &mut [u8] { |  |  |  |     pub async fn tx_buf(&mut self) -> &mut [u8] { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let p = self.tx_chan.receive().await; |  |  |  |         let p = self.tx_chan.receive().await; | 
			
		
	
		
		
			
				
					
					|  |  |  |         &mut p.buf[..p.len] |  |  |  |         &mut p.buf[..p.len] | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Check if there is space for more outbound packets right now. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { |  |  |  |     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let p = self.tx_chan.try_receive()?; |  |  |  |         let p = self.tx_chan.try_receive()?; | 
			
		
	
		
		
			
				
					
					|  |  |  |         Some(&mut p.buf[..p.len]) |  |  |  |         Some(&mut p.buf[..p.len]) | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Polling the outbound channel if there is space for packets. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |  |  |  |     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         match self.tx_chan.poll_receive(cx) { |  |  |  |         match self.tx_chan.poll_receive(cx) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), |  |  |  |             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -174,14 +146,12 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Mark outbound packet as copied. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn tx_done(&mut self) { |  |  |  |     pub fn tx_done(&mut self) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.tx_chan.receive_done(); |  |  |  |         self.tx_chan.receive_done(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | impl<'d> StateRunner<'d> { |  |  |  | impl<'d> StateRunner<'d> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Set link state. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn set_link_state(&self, state: LinkState) { |  |  |  |     pub fn set_link_state(&self, state: LinkState) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.shared.lock(|s| { |  |  |  |         self.shared.lock(|s| { | 
			
		
	
		
		
			
				
					
					|  |  |  |             let s = &mut *s.borrow_mut(); |  |  |  |             let s = &mut *s.borrow_mut(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -190,7 +160,6 @@ impl<'d> StateRunner<'d> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         }); |  |  |  |         }); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Set the hardware address. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn set_hardware_address(&self, address: driver::HardwareAddress) { |  |  |  |     pub fn set_hardware_address(&self, address: driver::HardwareAddress) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.shared.lock(|s| { |  |  |  |         self.shared.lock(|s| { | 
			
		
	
		
		
			
				
					
					|  |  |  |             let s = &mut *s.borrow_mut(); |  |  |  |             let s = &mut *s.borrow_mut(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -201,19 +170,16 @@ impl<'d> StateRunner<'d> { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | impl<'d, const MTU: usize> RxRunner<'d, MTU> { |  |  |  | impl<'d, const MTU: usize> RxRunner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Wait until there is space for more inbound packets and return a slice they can be copied into. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub async fn rx_buf(&mut self) -> &mut [u8] { |  |  |  |     pub async fn rx_buf(&mut self) -> &mut [u8] { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let p = self.rx_chan.send().await; |  |  |  |         let p = self.rx_chan.send().await; | 
			
		
	
		
		
			
				
					
					|  |  |  |         &mut p.buf |  |  |  |         &mut p.buf | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Check if there is space for more inbound packets right now. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { |  |  |  |     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let p = self.rx_chan.try_send()?; |  |  |  |         let p = self.rx_chan.try_send()?; | 
			
		
	
		
		
			
				
					
					|  |  |  |         Some(&mut p.buf) |  |  |  |         Some(&mut p.buf) | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Polling the inbound channel if there is space for packets. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |  |  |  |     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         match self.rx_chan.poll_send(cx) { |  |  |  |         match self.rx_chan.poll_send(cx) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             Poll::Ready(p) => Poll::Ready(&mut p.buf), |  |  |  |             Poll::Ready(p) => Poll::Ready(&mut p.buf), | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -221,7 +187,6 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Mark packet of len bytes as pushed to the inbound channel. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn rx_done(&mut self, len: usize) { |  |  |  |     pub fn rx_done(&mut self, len: usize) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let p = self.rx_chan.try_send().unwrap(); |  |  |  |         let p = self.rx_chan.try_send().unwrap(); | 
			
		
	
		
		
			
				
					
					|  |  |  |         p.len = len; |  |  |  |         p.len = len; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -230,19 +195,16 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | impl<'d, const MTU: usize> TxRunner<'d, MTU> { |  |  |  | impl<'d, const MTU: usize> TxRunner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Wait until there is space for more outbound packets and return a slice they can be copied into. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub async fn tx_buf(&mut self) -> &mut [u8] { |  |  |  |     pub async fn tx_buf(&mut self) -> &mut [u8] { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let p = self.tx_chan.receive().await; |  |  |  |         let p = self.tx_chan.receive().await; | 
			
		
	
		
		
			
				
					
					|  |  |  |         &mut p.buf[..p.len] |  |  |  |         &mut p.buf[..p.len] | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Check if there is space for more outbound packets right now. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { |  |  |  |     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         let p = self.tx_chan.try_receive()?; |  |  |  |         let p = self.tx_chan.try_receive()?; | 
			
		
	
		
		
			
				
					
					|  |  |  |         Some(&mut p.buf[..p.len]) |  |  |  |         Some(&mut p.buf[..p.len]) | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Polling the outbound channel if there is space for packets. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |  |  |  |     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         match self.tx_chan.poll_receive(cx) { |  |  |  |         match self.tx_chan.poll_receive(cx) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), |  |  |  |             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -250,18 +212,11 @@ impl<'d, const MTU: usize> TxRunner<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Mark outbound packet as copied. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub fn tx_done(&mut self) { |  |  |  |     pub fn tx_done(&mut self) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         self.tx_chan.receive_done(); |  |  |  |         self.tx_chan.receive_done(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Create a channel. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Returns a pair of handles for interfacing with the peripheral and the networking stack. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// The runner is interfacing with the peripheral at the lower part of the stack. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// The device is interfacing with the networking stack on the layer above. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( |  |  |  | pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( | 
			
		
	
		
		
			
				
					
					|  |  |  |     state: &'d mut State<MTU, N_RX, N_TX>, |  |  |  |     state: &'d mut State<MTU, N_RX, N_TX>, | 
			
		
	
		
		
			
				
					
					|  |  |  |     hardware_address: driver::HardwareAddress, |  |  |  |     hardware_address: driver::HardwareAddress, | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -302,22 +257,17 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( | 
			
		
	
		
		
			
				
					
					|  |  |  |     ) |  |  |  |     ) | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Represents a packet of size MTU. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | pub struct PacketBuf<const MTU: usize> { |  |  |  | pub struct PacketBuf<const MTU: usize> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     len: usize, |  |  |  |     len: usize, | 
			
		
	
		
		
			
				
					
					|  |  |  |     buf: [u8; MTU], |  |  |  |     buf: [u8; MTU], | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | impl<const MTU: usize> PacketBuf<MTU> { |  |  |  | impl<const MTU: usize> PacketBuf<MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     /// Create a new packet buffer. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     pub const fn new() -> Self { |  |  |  |     pub const fn new() -> Self { | 
			
		
	
		
		
			
				
					
					|  |  |  |         Self { len: 0, buf: [0; MTU] } |  |  |  |         Self { len: 0, buf: [0; MTU] } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Channel device. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Holds the shared state and upper end of channels for inbound and outbound packets. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | pub struct Device<'d, const MTU: usize> { |  |  |  | pub struct Device<'d, const MTU: usize> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |  |  |  |     rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | 
			
		
	
		
		
			
				
					
					|  |  |  |     tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |  |  |  |     tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -364,9 +314,6 @@ impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// A rx token. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Holds inbound receive channel and interfaces with embassy-net-driver. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | pub struct RxToken<'a, const MTU: usize> { |  |  |  | pub struct RxToken<'a, const MTU: usize> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>, |  |  |  |     rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>, | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -384,9 +331,6 @@ impl<'a, const MTU: usize> embassy_net_driver::RxToken for RxToken<'a, MTU> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// A tx token. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /// Holds outbound transmit channel and interfaces with embassy-net-driver. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | pub struct TxToken<'a, const MTU: usize> { |  |  |  | pub struct TxToken<'a, const MTU: usize> { | 
			
		
	
		
		
			
				
					
					|  |  |  |     tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>, |  |  |  |     tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>, | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					
					|  |  |   |