1use alloc::{boxed::Box, sync::Arc, vec::Vec};
8
9pub use rd_net::{DmaBuffer, RxCompletion, TxChecksumCapabilities, TxNotify, TxSubmitOptions};
10
11pub(crate) const ETH_ZLEN: usize = 60;
13pub(crate) const ETHERNET_FRAME_CAPACITY: usize = 2048;
15
16#[derive(Clone, Copy, Debug, Eq, PartialEq, thiserror::Error)]
17pub enum NetDeviceError {
18 #[error("network frame port should be retried")]
20 Again,
21 #[error("network frame port is stopped")]
23 Stopped,
24 #[error("invalid network frame size")]
26 InvalidParam,
27 #[error("network frame port I/O failed")]
29 Io,
30 #[error("network frame port memory allocation failed")]
32 NoMemory,
33}
34
35pub type NetDeviceResult<T = ()> = Result<T, NetDeviceError>;
36
37#[derive(Clone)]
44pub struct ProtocolEthernetFrame {
45 bytes: [u8; ETHERNET_FRAME_CAPACITY],
46 len: usize,
47}
48
49impl ProtocolEthernetFrame {
50 pub fn new(len: usize) -> NetDeviceResult<Self> {
51 if len > ETHERNET_FRAME_CAPACITY {
52 return Err(NetDeviceError::InvalidParam);
53 }
54 Ok(Self {
55 bytes: [0; ETHERNET_FRAME_CAPACITY],
56 len,
57 })
58 }
59
60 pub fn packet(&self) -> &[u8] {
61 &self.bytes[..self.len]
62 }
63
64 pub fn packet_mut(&mut self) -> &mut [u8] {
65 &mut self.bytes[..self.len]
66 }
67
68 pub fn packet_len(&self) -> usize {
69 self.len
70 }
71
72 pub(crate) fn copy_from_slice(packet: &[u8]) -> NetDeviceResult<Self> {
73 let mut frame = Self::new(packet.len())?;
74 frame.packet_mut().copy_from_slice(packet);
75 Ok(frame)
76 }
77}
78
79pub(crate) trait RxBufferRecycler: Send + Sync {
81 fn recycle(&self, buffer: DmaBuffer);
82}
83
84pub struct ProtocolRxFrame {
90 completion: Option<RxCompletion>,
91 recycler: Arc<dyn RxBufferRecycler>,
92}
93
94impl ProtocolRxFrame {
95 pub(crate) fn new(completion: RxCompletion, recycler: Arc<dyn RxBufferRecycler>) -> Self {
96 debug_assert!(completion.packet_len <= completion.buffer.capacity());
97 Self {
98 completion: Some(completion),
99 recycler,
100 }
101 }
102
103 pub fn packet_len(&self) -> usize {
105 self.completion
106 .as_ref()
107 .expect("owned RX frame lost its DMA token")
108 .packet_len
109 }
110
111 pub fn read_with<R>(&self, consume: impl FnOnce(&[u8]) -> R) -> R {
113 let completion = self
114 .completion
115 .as_ref()
116 .expect("owned RX frame lost its DMA token");
117 completion
118 .buffer
119 .read_with_cpu(completion.packet_len, consume)
120 }
121}
122
123impl Drop for ProtocolRxFrame {
124 fn drop(&mut self) {
125 if let Some(completion) = self.completion.take() {
126 self.recycler.recycle(completion.buffer);
127 }
128 }
129}
130
131pub trait EthernetFramePort: Send + 'static {
134 fn device_name(&self) -> &str;
136
137 fn mac_address(&self) -> [u8; 6];
139
140 fn checksum_capabilities(&self) -> TxChecksumCapabilities {
142 TxChecksumCapabilities::NONE
143 }
144
145 fn transmit(&mut self, frame: &ProtocolEthernetFrame) -> NetDeviceResult;
148
149 fn transmit_frame_with_options(
155 &mut self,
156 frame_len: usize,
157 options: TxSubmitOptions,
158 fill: &mut dyn FnMut(&mut [u8]),
159 ) -> NetDeviceResult {
160 if options.checksum.is_some() {
161 return Err(NetDeviceError::InvalidParam);
162 }
163 let mut frame = ProtocolEthernetFrame::new(frame_len)?;
164 fill(frame.packet_mut());
165 self.transmit(&frame)
166 }
167
168 fn receive(&mut self) -> NetDeviceResult<ProtocolEthernetFrame>;
170
171 fn drain_rx_drops(&mut self) -> u64 {
173 0
174 }
175
176 fn receive_owned(&mut self) -> NetDeviceResult<Option<ProtocolRxFrame>> {
181 Ok(None)
182 }
183
184 fn receive_with(&mut self, consume: &mut dyn FnMut(&[u8]) -> usize) -> NetDeviceResult<usize> {
189 let frame = self.receive()?;
190 Ok(consume(frame.packet()))
191 }
192}
193
194pub type EthernetFramePortList = Vec<Box<dyn EthernetFramePort>>;