diff options
| author | Ulf Lilleengen <[email protected]> | 2023-12-20 09:24:10 +0100 |
|---|---|---|
| committer | Ulf Lilleengen <[email protected]> | 2023-12-20 09:24:10 +0100 |
| commit | fc6e70caa5afb2e6b37e45516fad9a233e32d108 (patch) | |
| tree | 4b51c99c7955334fee3b7c60b07e7105b4b39632 /embassy-net-driver-channel/src/lib.rs | |
| parent | 97e919ea64402519153459fbd977d5b2630d4286 (diff) | |
docs: document public apis of embassy-net-driver-channel
Diffstat (limited to 'embassy-net-driver-channel/src/lib.rs')
| -rw-r--r-- | embassy-net-driver-channel/src/lib.rs | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/embassy-net-driver-channel/src/lib.rs b/embassy-net-driver-channel/src/lib.rs index bfb2c9c03..7ad4d449e 100644 --- a/embassy-net-driver-channel/src/lib.rs +++ b/embassy-net-driver-channel/src/lib.rs | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![doc = include_str!("../README.md")] | 2 | #![doc = include_str!("../README.md")] |
| 3 | #![warn(missing_docs)] | ||
| 3 | 4 | ||
| 4 | // must go first! | 5 | // must go first! |
| 5 | mod fmt; | 6 | mod fmt; |
| @@ -15,6 +16,9 @@ use embassy_sync::blocking_mutex::Mutex; | |||
| 15 | use embassy_sync::waitqueue::WakerRegistration; | 16 | use embassy_sync::waitqueue::WakerRegistration; |
| 16 | use embassy_sync::zerocopy_channel; | 17 | use embassy_sync::zerocopy_channel; |
| 17 | 18 | ||
| 19 | /// Channel state. | ||
| 20 | /// | ||
| 21 | /// Holds a buffer of packets with size MTU, for both TX and RX. | ||
| 18 | pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | 22 | pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { |
| 19 | rx: [PacketBuf<MTU>; N_RX], | 23 | rx: [PacketBuf<MTU>; N_RX], |
| 20 | tx: [PacketBuf<MTU>; N_TX], | 24 | tx: [PacketBuf<MTU>; N_TX], |
| @@ -24,6 +28,7 @@ pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | |||
| 24 | impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> { | 28 | impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> { |
| 25 | const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new(); | 29 | const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new(); |
| 26 | 30 | ||
| 31 | /// Create a new channel state. | ||
| 27 | pub const fn new() -> Self { | 32 | pub const fn new() -> Self { |
| 28 | Self { | 33 | Self { |
| 29 | rx: [Self::NEW_PACKET; N_RX], | 34 | rx: [Self::NEW_PACKET; N_RX], |
| @@ -39,33 +44,45 @@ struct StateInner<'d, const MTU: usize> { | |||
| 39 | shared: Mutex<NoopRawMutex, RefCell<Shared>>, | 44 | shared: Mutex<NoopRawMutex, RefCell<Shared>>, |
| 40 | } | 45 | } |
| 41 | 46 | ||
| 42 | /// State of the LinkState | ||
| 43 | struct Shared { | 47 | struct Shared { |
| 44 | link_state: LinkState, | 48 | link_state: LinkState, |
| 45 | waker: WakerRegistration, | 49 | waker: WakerRegistration, |
| 46 | hardware_address: driver::HardwareAddress, | 50 | hardware_address: driver::HardwareAddress, |
| 47 | } | 51 | } |
| 48 | 52 | ||
| 53 | /// Channel runner. | ||
| 54 | /// | ||
| 55 | /// Holds the shared state and the lower end of channels for inbound and outbound packets. | ||
| 49 | pub struct Runner<'d, const MTU: usize> { | 56 | pub struct Runner<'d, const MTU: usize> { |
| 50 | tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | 57 | tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |
| 51 | rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | 58 | rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |
| 52 | shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, | 59 | shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, |
| 53 | } | 60 | } |
| 54 | 61 | ||
| 62 | /// State runner. | ||
| 63 | /// | ||
| 64 | /// Holds the shared state of the channel such as link state. | ||
| 55 | #[derive(Clone, Copy)] | 65 | #[derive(Clone, Copy)] |
| 56 | pub struct StateRunner<'d> { | 66 | pub struct StateRunner<'d> { |
| 57 | shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, | 67 | shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, |
| 58 | } | 68 | } |
| 59 | 69 | ||
| 70 | /// RX runner. | ||
| 71 | /// | ||
| 72 | /// Holds the lower end of the channel for passing inbound packets up the stack. | ||
| 60 | pub struct RxRunner<'d, const MTU: usize> { | 73 | pub struct RxRunner<'d, const MTU: usize> { |
| 61 | rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | 74 | rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |
| 62 | } | 75 | } |
| 63 | 76 | ||
| 77 | /// TX runner. | ||
| 78 | /// | ||
| 79 | /// Holds the lower end of the channel for passing outbound packets down the stack. | ||
| 64 | pub struct TxRunner<'d, const MTU: usize> { | 80 | pub struct TxRunner<'d, const MTU: usize> { |
| 65 | tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | 81 | tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |
| 66 | } | 82 | } |
| 67 | 83 | ||
| 68 | impl<'d, const MTU: usize> Runner<'d, MTU> { | 84 | impl<'d, const MTU: usize> Runner<'d, MTU> { |
| 85 | /// Split the runner into separate runners for controlling state, rx and tx. | ||
| 69 | pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) { | 86 | pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) { |
| 70 | ( | 87 | ( |
| 71 | StateRunner { shared: self.shared }, | 88 | StateRunner { shared: self.shared }, |
| @@ -74,6 +91,7 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||
| 74 | ) | 91 | ) |
| 75 | } | 92 | } |
| 76 | 93 | ||
| 94 | /// Split the runner into separate runners for controlling state, rx and tx borrowing the underlying state. | ||
| 77 | pub fn borrow_split(&mut self) -> (StateRunner<'_>, RxRunner<'_, MTU>, TxRunner<'_, MTU>) { | 95 | pub fn borrow_split(&mut self) -> (StateRunner<'_>, RxRunner<'_, MTU>, TxRunner<'_, MTU>) { |
| 78 | ( | 96 | ( |
| 79 | StateRunner { shared: self.shared }, | 97 | StateRunner { shared: self.shared }, |
| @@ -86,10 +104,12 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||
| 86 | ) | 104 | ) |
| 87 | } | 105 | } |
| 88 | 106 | ||
| 107 | /// Create a state runner sharing the state channel. | ||
| 89 | pub fn state_runner(&self) -> StateRunner<'d> { | 108 | pub fn state_runner(&self) -> StateRunner<'d> { |
| 90 | StateRunner { shared: self.shared } | 109 | StateRunner { shared: self.shared } |
| 91 | } | 110 | } |
| 92 | 111 | ||
| 112 | /// Set the link state. | ||
| 93 | pub fn set_link_state(&mut self, state: LinkState) { | 113 | pub fn set_link_state(&mut self, state: LinkState) { |
| 94 | self.shared.lock(|s| { | 114 | self.shared.lock(|s| { |
| 95 | let s = &mut *s.borrow_mut(); | 115 | let s = &mut *s.borrow_mut(); |
| @@ -98,6 +118,7 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||
| 98 | }); | 118 | }); |
| 99 | } | 119 | } |
| 100 | 120 | ||
| 121 | /// Set the hardware address. | ||
| 101 | pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) { | 122 | pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) { |
| 102 | self.shared.lock(|s| { | 123 | self.shared.lock(|s| { |
| 103 | let s = &mut *s.borrow_mut(); | 124 | let s = &mut *s.borrow_mut(); |
| @@ -106,16 +127,19 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||
| 106 | }); | 127 | }); |
| 107 | } | 128 | } |
| 108 | 129 | ||
| 130 | /// Wait until there is space for more inbound packets and return a slice they can be copied into. | ||
| 109 | pub async fn rx_buf(&mut self) -> &mut [u8] { | 131 | pub async fn rx_buf(&mut self) -> &mut [u8] { |
| 110 | let p = self.rx_chan.send().await; | 132 | let p = self.rx_chan.send().await; |
| 111 | &mut p.buf | 133 | &mut p.buf |
| 112 | } | 134 | } |
| 113 | 135 | ||
| 136 | /// Check if there is space for more inbound packets right now. | ||
| 114 | pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { | 137 | pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { |
| 115 | let p = self.rx_chan.try_send()?; | 138 | let p = self.rx_chan.try_send()?; |
| 116 | Some(&mut p.buf) | 139 | Some(&mut p.buf) |
| 117 | } | 140 | } |
| 118 | 141 | ||
| 142 | /// Polling the inbound channel if there is space for packets. | ||
| 119 | pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | 143 | pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |
| 120 | match self.rx_chan.poll_send(cx) { | 144 | match self.rx_chan.poll_send(cx) { |
| 121 | Poll::Ready(p) => Poll::Ready(&mut p.buf), | 145 | Poll::Ready(p) => Poll::Ready(&mut p.buf), |
| @@ -123,22 +147,26 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||
| 123 | } | 147 | } |
| 124 | } | 148 | } |
| 125 | 149 | ||
| 150 | /// Mark packet of len bytes as pushed to the inbound channel. | ||
| 126 | pub fn rx_done(&mut self, len: usize) { | 151 | pub fn rx_done(&mut self, len: usize) { |
| 127 | let p = self.rx_chan.try_send().unwrap(); | 152 | let p = self.rx_chan.try_send().unwrap(); |
| 128 | p.len = len; | 153 | p.len = len; |
| 129 | self.rx_chan.send_done(); | 154 | self.rx_chan.send_done(); |
| 130 | } | 155 | } |
| 131 | 156 | ||
| 157 | /// Wait until there is space for more outbound packets and return a slice they can be copied into. | ||
| 132 | pub async fn tx_buf(&mut self) -> &mut [u8] { | 158 | pub async fn tx_buf(&mut self) -> &mut [u8] { |
| 133 | let p = self.tx_chan.receive().await; | 159 | let p = self.tx_chan.receive().await; |
| 134 | &mut p.buf[..p.len] | 160 | &mut p.buf[..p.len] |
| 135 | } | 161 | } |
| 136 | 162 | ||
| 163 | /// Check if there is space for more outbound packets right now. | ||
| 137 | pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { | 164 | pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { |
| 138 | let p = self.tx_chan.try_receive()?; | 165 | let p = self.tx_chan.try_receive()?; |
| 139 | Some(&mut p.buf[..p.len]) | 166 | Some(&mut p.buf[..p.len]) |
| 140 | } | 167 | } |
| 141 | 168 | ||
| 169 | /// Polling the outbound channel if there is space for packets. | ||
| 142 | pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | 170 | pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |
| 143 | match self.tx_chan.poll_receive(cx) { | 171 | match self.tx_chan.poll_receive(cx) { |
| 144 | Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), | 172 | Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), |
| @@ -146,12 +174,14 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||
| 146 | } | 174 | } |
| 147 | } | 175 | } |
| 148 | 176 | ||
| 177 | /// Mark outbound packet as copied. | ||
| 149 | pub fn tx_done(&mut self) { | 178 | pub fn tx_done(&mut self) { |
| 150 | self.tx_chan.receive_done(); | 179 | self.tx_chan.receive_done(); |
| 151 | } | 180 | } |
| 152 | } | 181 | } |
| 153 | 182 | ||
| 154 | impl<'d> StateRunner<'d> { | 183 | impl<'d> StateRunner<'d> { |
| 184 | /// Set link state. | ||
| 155 | pub fn set_link_state(&self, state: LinkState) { | 185 | pub fn set_link_state(&self, state: LinkState) { |
| 156 | self.shared.lock(|s| { | 186 | self.shared.lock(|s| { |
| 157 | let s = &mut *s.borrow_mut(); | 187 | let s = &mut *s.borrow_mut(); |
| @@ -160,6 +190,7 @@ impl<'d> StateRunner<'d> { | |||
| 160 | }); | 190 | }); |
| 161 | } | 191 | } |
| 162 | 192 | ||
| 193 | /// Set the hardware address. | ||
| 163 | pub fn set_hardware_address(&self, address: driver::HardwareAddress) { | 194 | pub fn set_hardware_address(&self, address: driver::HardwareAddress) { |
| 164 | self.shared.lock(|s| { | 195 | self.shared.lock(|s| { |
| 165 | let s = &mut *s.borrow_mut(); | 196 | let s = &mut *s.borrow_mut(); |
| @@ -170,16 +201,19 @@ impl<'d> StateRunner<'d> { | |||
| 170 | } | 201 | } |
| 171 | 202 | ||
| 172 | impl<'d, const MTU: usize> RxRunner<'d, MTU> { | 203 | impl<'d, const MTU: usize> RxRunner<'d, MTU> { |
| 204 | /// Wait until there is space for more inbound packets and return a slice they can be copied into. | ||
| 173 | pub async fn rx_buf(&mut self) -> &mut [u8] { | 205 | pub async fn rx_buf(&mut self) -> &mut [u8] { |
| 174 | let p = self.rx_chan.send().await; | 206 | let p = self.rx_chan.send().await; |
| 175 | &mut p.buf | 207 | &mut p.buf |
| 176 | } | 208 | } |
| 177 | 209 | ||
| 210 | /// Check if there is space for more inbound packets right now. | ||
| 178 | pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { | 211 | pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { |
| 179 | let p = self.rx_chan.try_send()?; | 212 | let p = self.rx_chan.try_send()?; |
| 180 | Some(&mut p.buf) | 213 | Some(&mut p.buf) |
| 181 | } | 214 | } |
| 182 | 215 | ||
| 216 | /// Polling the inbound channel if there is space for packets. | ||
| 183 | pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | 217 | pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |
| 184 | match self.rx_chan.poll_send(cx) { | 218 | match self.rx_chan.poll_send(cx) { |
| 185 | Poll::Ready(p) => Poll::Ready(&mut p.buf), | 219 | Poll::Ready(p) => Poll::Ready(&mut p.buf), |
| @@ -187,6 +221,7 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> { | |||
| 187 | } | 221 | } |
| 188 | } | 222 | } |
| 189 | 223 | ||
| 224 | /// Mark packet of len bytes as pushed to the inbound channel. | ||
| 190 | pub fn rx_done(&mut self, len: usize) { | 225 | pub fn rx_done(&mut self, len: usize) { |
| 191 | let p = self.rx_chan.try_send().unwrap(); | 226 | let p = self.rx_chan.try_send().unwrap(); |
| 192 | p.len = len; | 227 | p.len = len; |
| @@ -195,16 +230,19 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> { | |||
| 195 | } | 230 | } |
| 196 | 231 | ||
| 197 | impl<'d, const MTU: usize> TxRunner<'d, MTU> { | 232 | impl<'d, const MTU: usize> TxRunner<'d, MTU> { |
| 233 | /// Wait until there is space for more outbound packets and return a slice they can be copied into. | ||
| 198 | pub async fn tx_buf(&mut self) -> &mut [u8] { | 234 | pub async fn tx_buf(&mut self) -> &mut [u8] { |
| 199 | let p = self.tx_chan.receive().await; | 235 | let p = self.tx_chan.receive().await; |
| 200 | &mut p.buf[..p.len] | 236 | &mut p.buf[..p.len] |
| 201 | } | 237 | } |
| 202 | 238 | ||
| 239 | /// Check if there is space for more outbound packets right now. | ||
| 203 | pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { | 240 | pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { |
| 204 | let p = self.tx_chan.try_receive()?; | 241 | let p = self.tx_chan.try_receive()?; |
| 205 | Some(&mut p.buf[..p.len]) | 242 | Some(&mut p.buf[..p.len]) |
| 206 | } | 243 | } |
| 207 | 244 | ||
| 245 | /// Polling the outbound channel if there is space for packets. | ||
| 208 | pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | 246 | pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |
| 209 | match self.tx_chan.poll_receive(cx) { | 247 | match self.tx_chan.poll_receive(cx) { |
| 210 | Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), | 248 | Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), |
| @@ -212,11 +250,18 @@ impl<'d, const MTU: usize> TxRunner<'d, MTU> { | |||
| 212 | } | 250 | } |
| 213 | } | 251 | } |
| 214 | 252 | ||
| 253 | /// Mark outbound packet as copied. | ||
| 215 | pub fn tx_done(&mut self) { | 254 | pub fn tx_done(&mut self) { |
| 216 | self.tx_chan.receive_done(); | 255 | self.tx_chan.receive_done(); |
| 217 | } | 256 | } |
| 218 | } | 257 | } |
| 219 | 258 | ||
| 259 | /// Create a channel. | ||
| 260 | /// | ||
| 261 | /// Returns a pair of handles for interfacing with the peripheral and the networking stack. | ||
| 262 | /// | ||
| 263 | /// The runner is interfacing with the peripheral at the lower part of the stack. | ||
| 264 | /// The device is interfacing with the networking stack on the layer above. | ||
| 220 | pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( | 265 | pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( |
| 221 | state: &'d mut State<MTU, N_RX, N_TX>, | 266 | state: &'d mut State<MTU, N_RX, N_TX>, |
| 222 | hardware_address: driver::HardwareAddress, | 267 | hardware_address: driver::HardwareAddress, |
| @@ -257,17 +302,22 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( | |||
| 257 | ) | 302 | ) |
| 258 | } | 303 | } |
| 259 | 304 | ||
| 305 | /// Represents a packet of size MTU. | ||
| 260 | pub struct PacketBuf<const MTU: usize> { | 306 | pub struct PacketBuf<const MTU: usize> { |
| 261 | len: usize, | 307 | len: usize, |
| 262 | buf: [u8; MTU], | 308 | buf: [u8; MTU], |
| 263 | } | 309 | } |
| 264 | 310 | ||
| 265 | impl<const MTU: usize> PacketBuf<MTU> { | 311 | impl<const MTU: usize> PacketBuf<MTU> { |
| 312 | /// Create a new packet buffer. | ||
| 266 | pub const fn new() -> Self { | 313 | pub const fn new() -> Self { |
| 267 | Self { len: 0, buf: [0; MTU] } | 314 | Self { len: 0, buf: [0; MTU] } |
| 268 | } | 315 | } |
| 269 | } | 316 | } |
| 270 | 317 | ||
| 318 | /// Channel device. | ||
| 319 | /// | ||
| 320 | /// Holds the shared state and upper end of channels for inbound and outbound packets. | ||
| 271 | pub struct Device<'d, const MTU: usize> { | 321 | pub struct Device<'d, const MTU: usize> { |
| 272 | rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | 322 | rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |
| 273 | tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | 323 | tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |
| @@ -314,6 +364,9 @@ impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> { | |||
| 314 | } | 364 | } |
| 315 | } | 365 | } |
| 316 | 366 | ||
| 367 | /// A rx token. | ||
| 368 | /// | ||
| 369 | /// Holds inbound receive channel and interfaces with embassy-net-driver. | ||
| 317 | pub struct RxToken<'a, const MTU: usize> { | 370 | pub struct RxToken<'a, const MTU: usize> { |
| 318 | rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>, | 371 | rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>, |
| 319 | } | 372 | } |
| @@ -331,6 +384,9 @@ impl<'a, const MTU: usize> embassy_net_driver::RxToken for RxToken<'a, MTU> { | |||
| 331 | } | 384 | } |
| 332 | } | 385 | } |
| 333 | 386 | ||
| 387 | /// A tx token. | ||
| 388 | /// | ||
| 389 | /// Holds outbound transmit channel and interfaces with embassy-net-driver. | ||
| 334 | pub struct TxToken<'a, const MTU: usize> { | 390 | pub struct TxToken<'a, const MTU: usize> { |
| 335 | tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>, | 391 | tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>, |
| 336 | } | 392 | } |
