#![no_std]
extern crate alloc;
use alloc::boxed::Box;
use core::ptr::NonNull;
pub use dma_api;
pub use rdif_base::{DriverGeneric, KError, io};
#[derive(thiserror::Error, Debug)]
pub enum NetError {
#[error("Operation not supported")]
NotSupported,
#[error("Operation should be retried")]
Retry,
#[error("Insufficient memory")]
NoMemory,
#[error("Link down")]
LinkDown,
#[error("Other error: {0}")]
Other(Box<dyn core::error::Error>),
}
impl From<NetError> for io::ErrorKind {
fn from(value: NetError) -> Self {
match value {
NetError::NotSupported => io::ErrorKind::Unsupported,
NetError::Retry => io::ErrorKind::Interrupted,
NetError::NoMemory => io::ErrorKind::OutOfMemory,
NetError::LinkDown => io::ErrorKind::NotAvailable,
NetError::Other(e) => io::ErrorKind::Other(e),
}
}
}
impl From<dma_api::DmaError> for NetError {
fn from(value: dma_api::DmaError) -> Self {
match value {
dma_api::DmaError::NoMemory => NetError::NoMemory,
e => NetError::Other(Box::new(e)),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct QueueConfig {
pub dma_mask: u64,
pub align: usize,
pub buf_size: usize,
pub ring_size: usize,
}
#[derive(Clone, Copy, Debug)]
pub struct DmaBuffer {
pub virt: NonNull<u8>,
pub bus_addr: u64,
pub len: usize,
}
#[repr(transparent)]
#[derive(Debug, Clone, Copy)]
pub struct IdList(u64);
impl IdList {
pub const fn none() -> Self {
Self(0)
}
pub fn contains(&self, id: usize) -> bool {
(self.0 & (1 << id)) != 0
}
pub fn insert(&mut self, id: usize) {
self.0 |= 1 << id;
}
pub fn remove(&mut self, id: usize) {
self.0 &= !(1 << id);
}
pub fn iter(&self) -> impl Iterator<Item = usize> {
let bits = self.0;
(0..64).filter(move |i| (bits & (1 << i)) != 0)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Event {
pub tx_queue: IdList,
pub rx_queue: IdList,
}
impl Event {
pub const fn none() -> Self {
Self {
tx_queue: IdList::none(),
rx_queue: IdList::none(),
}
}
}
pub trait Interface: DriverGeneric {
fn mac_address(&self) -> [u8; 6];
fn create_tx_queue(&mut self) -> Option<Box<dyn ITxQueue>>;
fn create_rx_queue(&mut self) -> Option<Box<dyn IRxQueue>>;
fn enable_irq(&mut self);
fn disable_irq(&mut self);
fn is_irq_enabled(&self) -> bool;
fn handle_irq(&mut self) -> Event;
}
pub trait ITxQueue: Send + 'static {
fn id(&self) -> usize;
fn config(&self) -> QueueConfig;
fn submit(&mut self, buffer: DmaBuffer) -> Result<(), NetError>;
fn reclaim(&mut self) -> Option<u64>;
}
pub trait IRxQueue: Send + 'static {
fn id(&self) -> usize;
fn config(&self) -> QueueConfig;
fn submit(&mut self, buffer: DmaBuffer) -> Result<(), NetError>;
fn reclaim(&mut self) -> Option<(u64, usize)>;
}