asterinas/kernel/comps/network/src/lib.rs

124 lines
3.5 KiB
Rust
Raw Normal View History

2024-01-03 03:22:36 +00:00
// SPDX-License-Identifier: MPL-2.0
2023-05-30 08:34:28 +00:00
#![no_std]
#![forbid(unsafe_code)]
#![feature(trait_alias)]
2023-08-28 07:03:28 +00:00
#![feature(fn_traits)]
pub mod buffer;
pub mod driver;
2023-05-30 08:34:28 +00:00
extern crate alloc;
use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec};
use core::{any::Any, fmt::Debug};
2023-12-25 03:12:25 +00:00
use aster_frame::sync::SpinLock;
use aster_util::safe_ptr::Pod;
use buffer::{RxBuffer, TxBuffer};
use component::{init_component, ComponentInitError};
2023-08-28 07:03:28 +00:00
use smoltcp::phy;
2023-05-30 08:34:28 +00:00
use spin::Once;
2023-08-28 07:03:28 +00:00
#[derive(Debug, Clone, Copy, Pod)]
#[repr(C)]
pub struct EthernetAddr(pub [u8; 6]);
#[derive(Debug, Clone, Copy)]
pub enum VirtioNetError {
NotReady,
WrongToken,
Unknown,
}
2023-05-30 08:34:28 +00:00
2023-11-20 12:37:51 +00:00
pub trait AnyNetworkDevice: Send + Sync + Any + Debug {
2023-08-28 07:03:28 +00:00
// ================Device Information=================
2023-05-30 08:34:28 +00:00
fn mac_addr(&self) -> EthernetAddr;
2023-08-28 07:03:28 +00:00
fn capabilities(&self) -> phy::DeviceCapabilities;
// ================Device Operation===================
fn can_receive(&self) -> bool;
fn can_send(&self) -> bool;
/// Receive a packet from network. If packet is ready, returns a RxBuffer containing the packet.
/// Otherwise, return NotReady error.
fn receive(&mut self) -> Result<RxBuffer, VirtioNetError>;
/// Send a packet to network. Return until the request completes.
fn send(&mut self, tx_buffer: TxBuffer) -> Result<(), VirtioNetError>;
}
pub trait NetDeviceIrqHandler = Fn() + Send + Sync + 'static;
pub fn register_device(name: String, device: Arc<SpinLock<dyn AnyNetworkDevice>>) {
2023-08-28 07:03:28 +00:00
COMPONENT
.get()
.unwrap()
2023-11-20 12:37:51 +00:00
.network_device_table
2023-08-28 07:03:28 +00:00
.lock()
.insert(name, (Arc::new(SpinLock::new(Vec::new())), device));
}
pub fn get_device(str: &str) -> Option<Arc<SpinLock<dyn AnyNetworkDevice>>> {
2023-11-20 12:37:51 +00:00
let lock = COMPONENT.get().unwrap().network_device_table.lock();
let (_, device) = lock.get(str)?;
2023-08-28 07:03:28 +00:00
Some(device.clone())
}
2023-11-20 12:37:51 +00:00
pub fn register_recv_callback(name: &str, callback: impl NetDeviceIrqHandler) {
let lock = COMPONENT.get().unwrap().network_device_table.lock();
2023-08-28 07:03:28 +00:00
let Some((callbacks, _)) = lock.get(name) else {
return;
};
callbacks.lock().push(Arc::new(callback));
}
2023-11-20 12:37:51 +00:00
pub fn handle_recv_irq(name: &str) {
let lock = COMPONENT.get().unwrap().network_device_table.lock();
2023-08-28 07:03:28 +00:00
let Some((callbacks, _)) = lock.get(name) else {
return;
};
let callbacks = callbacks.clone();
let lock = callbacks.lock();
for callback in lock.iter() {
callback.call(())
}
}
2023-09-04 03:04:42 +00:00
pub fn all_devices() -> Vec<(String, NetworkDeviceRef)> {
2023-11-20 12:37:51 +00:00
let network_devs = COMPONENT.get().unwrap().network_device_table.lock();
network_devs
.iter()
.map(|(name, (_, device))| (name.clone(), device.clone()))
.collect()
2023-05-30 08:34:28 +00:00
}
2023-08-28 07:03:28 +00:00
static COMPONENT: Once<Component> = Once::new();
2023-05-30 08:34:28 +00:00
pub(crate) static NETWORK_IRQ_HANDLERS: Once<SpinLock<Vec<Arc<dyn NetDeviceIrqHandler>>>> =
Once::new();
#[init_component]
fn init() -> Result<(), ComponentInitError> {
2023-08-28 07:03:28 +00:00
let a = Component::init()?;
COMPONENT.call_once(|| a);
2023-05-30 08:34:28 +00:00
NETWORK_IRQ_HANDLERS.call_once(|| SpinLock::new(Vec::new()));
Ok(())
}
2023-09-04 03:04:42 +00:00
type NetDeviceIrqHandlerListRef = Arc<SpinLock<Vec<Arc<dyn NetDeviceIrqHandler>>>>;
type NetworkDeviceRef = Arc<SpinLock<dyn AnyNetworkDevice>>;
2023-09-04 03:04:42 +00:00
2023-08-28 07:03:28 +00:00
struct Component {
/// Device list, the key is device name, value is (callbacks, device);
2023-11-20 12:37:51 +00:00
network_device_table:
SpinLock<BTreeMap<String, (NetDeviceIrqHandlerListRef, NetworkDeviceRef)>>,
2023-05-30 08:34:28 +00:00
}
2023-08-28 07:03:28 +00:00
impl Component {
pub fn init() -> Result<Self, ComponentInitError> {
Ok(Self {
2023-11-20 12:37:51 +00:00
network_device_table: SpinLock::new(BTreeMap::new()),
2023-08-28 07:03:28 +00:00
})
}
2023-05-30 08:34:28 +00:00
}