Skip to main content

os/drivers/net/
mod.rs

1use core::any::Any;
2
3use crate::drivers::virtio::VirtioHal;
4use crate::sync::UPIntrFreeCell;
5use alloc::sync::Arc;
6use lazy_static::*;
7use virtio_drivers::{VirtIOHeader, VirtIONet};
8
9const VIRTIO8: usize = 0x10004000;
10
11lazy_static! {
12    pub static ref NET_DEVICE: Arc<dyn NetDevice> = Arc::new(VirtIONetWrapper::new());
13}
14
15pub trait NetDevice: Send + Sync + Any {
16    fn transmit(&self, data: &[u8]);
17    fn receive(&self, data: &mut [u8]) -> usize;
18}
19
20pub struct VirtIONetWrapper(UPIntrFreeCell<VirtIONet<'static, VirtioHal>>);
21
22impl NetDevice for VirtIONetWrapper {
23    fn transmit(&self, data: &[u8]) {
24        self.0
25            .exclusive_access()
26            .send(data)
27            .expect("can't send data")
28    }
29
30    fn receive(&self, data: &mut [u8]) -> usize {
31        self.0
32            .exclusive_access()
33            .recv(data)
34            .expect("can't receive data")
35    }
36}
37
38impl VirtIONetWrapper {
39    pub fn new() -> Self {
40        unsafe {
41            let virtio = VirtIONet::<VirtioHal>::new(&mut *(VIRTIO8 as *mut VirtIOHeader))
42                .expect("can't create net device by virtio");
43            VirtIONetWrapper(UPIntrFreeCell::new(virtio))
44        }
45    }
46}