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