#![no_std]
extern crate alloc;
use core::ops::{Deref, DerefMut};
use alloc::boxed::Box;
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)),
}
}
}
pub struct BuffConfig {
pub dma_mask: u64,
pub align: usize,
pub size: usize,
}
#[derive(Clone, Copy)]
pub struct Buffer {
pub virt: *mut u8,
pub bus: u64,
pub size: usize,
}
impl Deref for Buffer {
type Target = [u8];
fn deref(&self) -> &Self::Target {
unsafe { core::slice::from_raw_parts(self.virt, self.size) }
}
}
impl DerefMut for Buffer {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { core::slice::from_raw_parts_mut(self.virt, self.size) }
}
}
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RequestId(usize);
impl RequestId {
pub fn new(id: usize) -> Self {
Self(id)
}
}
impl From<RequestId> for usize {
fn from(value: RequestId) -> Self {
value.0
}
}
#[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 struct TxRequest<'a> {
pub data: &'a [u8],
}
pub struct RxRequest {
pub buffer: Buffer,
}
pub struct RxResponse {
pub len: usize,
}
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 mtu(&self) -> usize;
fn buff_config(&self) -> BuffConfig;
fn submit_request(&mut self, request: TxRequest<'_>) -> Result<RequestId, NetError>;
fn poll_request(&mut self, request: RequestId) -> Result<(), NetError>;
}
pub trait IRxQueue: Send + 'static {
fn id(&self) -> usize;
fn mtu(&self) -> usize;
fn buff_config(&self) -> BuffConfig;
fn submit_request(&mut self, request: RxRequest) -> Result<RequestId, NetError>;
fn poll_request(&mut self, request: RequestId) -> Result<RxResponse, NetError>;
}