rdif_eth/lib.rs
1#![no_std]
2
3extern crate alloc;
4
5use alloc::boxed::Box;
6
7pub use dma_api;
8pub use rdif_base::{DriverGeneric, KError, io};
9
10// ---------------------------------------------------------------------------
11// Error
12// ---------------------------------------------------------------------------
13
14/// Errors that can occur during network device operations.
15#[derive(thiserror::Error, Debug)]
16pub enum NetError {
17 /// The requested operation is not supported by the device.
18 #[error("Operation not supported")]
19 NotSupported,
20
21 /// The operation should be retried later (e.g. queue full).
22 #[error("Operation should be retried")]
23 Retry,
24
25 /// Insufficient memory to complete the operation.
26 #[error("Insufficient memory")]
27 NoMemory,
28
29 /// The network link is down.
30 #[error("Link down")]
31 LinkDown,
32
33 /// An unspecified error occurred.
34 #[error("Other error: {0}")]
35 Other(Box<dyn core::error::Error>),
36}
37
38impl From<NetError> for io::ErrorKind {
39 fn from(value: NetError) -> Self {
40 match value {
41 NetError::NotSupported => io::ErrorKind::Unsupported,
42 NetError::Retry => io::ErrorKind::Interrupted,
43 NetError::NoMemory => io::ErrorKind::OutOfMemory,
44 NetError::LinkDown => io::ErrorKind::NotAvailable,
45 NetError::Other(e) => io::ErrorKind::Other(e),
46 }
47 }
48}
49
50impl From<dma_api::DmaError> for NetError {
51 fn from(value: dma_api::DmaError) -> Self {
52 match value {
53 dma_api::DmaError::NoMemory => NetError::NoMemory,
54 e => NetError::Other(Box::new(e)),
55 }
56 }
57}
58
59// ---------------------------------------------------------------------------
60// DMA buffer helpers
61// ---------------------------------------------------------------------------
62
63/// Queue configuration needed by the upper layer DMA pool.
64#[derive(Debug, Clone, Copy)]
65pub struct QueueConfig {
66 /// DMA addressing mask for the device.
67 pub dma_mask: u64,
68
69 /// Required alignment for buffer addresses (in bytes).
70 pub align: usize,
71
72 /// DMA packet buffer size in bytes.
73 pub buf_size: usize,
74
75 /// Descriptor ring size.
76 pub ring_size: usize,
77}
78
79/// Bitmask tracking up to 64 queue identifiers.
80#[repr(transparent)]
81#[derive(Debug, Clone, Copy)]
82pub struct IdList(u64);
83
84impl IdList {
85 pub const fn none() -> Self {
86 Self(0)
87 }
88
89 pub fn contains(&self, id: usize) -> bool {
90 (self.0 & (1 << id)) != 0
91 }
92
93 pub fn insert(&mut self, id: usize) {
94 self.0 |= 1 << id;
95 }
96
97 pub fn remove(&mut self, id: usize) {
98 self.0 &= !(1 << id);
99 }
100
101 pub fn iter(&self) -> impl Iterator<Item = usize> {
102 let bits = self.0;
103 (0..64).filter(move |i| (bits & (1 << i)) != 0)
104 }
105}
106
107/// Event returned by [`Interface::handle_irq`] indicating which queues have
108/// completed operations.
109#[derive(Debug, Clone, Copy)]
110pub struct Event {
111 /// Bitmask of TX queue IDs that have completion events.
112 pub tx_queue: IdList,
113 /// Bitmask of RX queue IDs that have completion events.
114 pub rx_queue: IdList,
115}
116
117impl Event {
118 pub const fn none() -> Self {
119 Self {
120 tx_queue: IdList::none(),
121 rx_queue: IdList::none(),
122 }
123 }
124}
125
126/// Core interface that network device drivers must implement.
127///
128/// Provides device-level operations: queue creation, interrupt management,
129/// and MAC address retrieval. Individual packet I/O goes through the queue
130/// traits ([`ITxQueue`] / [`IRxQueue`]).
131pub trait Interface: DriverGeneric {
132 /// Returns the device's 6-byte MAC address.
133 fn mac_address(&self) -> [u8; 6];
134
135 /// Create a new transmit queue. Returns `None` if no more queues are
136 /// available.
137 fn create_tx_queue(&mut self) -> Option<Box<dyn ITxQueue>>;
138
139 /// Create a new receive queue. Returns `None` if no more queues are
140 /// available.
141 fn create_rx_queue(&mut self) -> Option<Box<dyn IRxQueue>>;
142
143 /// Enable device interrupts.
144 fn enable_irq(&mut self);
145
146 /// Disable device interrupts.
147 fn disable_irq(&mut self);
148
149 /// Check whether device interrupts are currently enabled.
150 fn is_irq_enabled(&self) -> bool;
151
152 /// Handle a device interrupt, returning which queues have events.
153 fn handle_irq(&mut self) -> Event;
154}
155
156// ---------------------------------------------------------------------------
157// Transmit queue
158// ---------------------------------------------------------------------------
159
160/// Transmit queue interface.
161///
162/// A driver creates one or more TX queues via [`Interface::create_tx_queue`]
163/// and exchanges DMA buffer bus addresses with the caller.
164pub trait ITxQueue: Send + 'static {
165 /// Queue identifier (unique within the device).
166 fn id(&self) -> usize;
167
168 /// DMA buffer configuration for this queue.
169 fn config(&self) -> QueueConfig;
170
171 /// Submit a DMA buffer for transmission.
172 ///
173 /// `bus_addr` must point to a DMA-capable buffer whose first `len` bytes
174 /// contain the packet to be transmitted.
175 fn submit(&mut self, bus_addr: u64, len: usize) -> Result<(), NetError>;
176
177 /// Reclaim the next completed transmit buffer.
178 ///
179 /// Returns the buffer bus address when the device has completed sending it.
180 fn reclaim(&mut self) -> Option<u64>;
181}
182
183// ---------------------------------------------------------------------------
184// Receive queue
185// ---------------------------------------------------------------------------
186
187/// Receive queue interface.
188///
189/// A driver creates one or more RX queues via [`Interface::create_rx_queue`]
190/// and exchanges DMA buffer bus addresses with the caller.
191pub trait IRxQueue: Send + 'static {
192 /// Queue identifier (unique within the device).
193 fn id(&self) -> usize;
194
195 /// DMA buffer configuration for this queue.
196 fn config(&self) -> QueueConfig;
197
198 /// Submit an empty DMA buffer to hardware.
199 ///
200 /// `bus_addr` must point to a DMA-capable buffer whose total size is `len`.
201 fn submit(&mut self, bus_addr: u64, len: usize) -> Result<(), NetError>;
202
203 /// Reclaim the next completed receive buffer.
204 ///
205 /// Returns the buffer bus address and the received byte count.
206 fn reclaim(&mut self) -> Option<(u64, usize)>;
207}