os/device/net/
net_device.rs1#[derive(Debug)]
3pub enum NetDeviceError {
4 IoError,
5 DeviceNotReady,
6 NotSupported,
7 QueueFull,
8 QueueEmpty,
9 AllocationFailed,
10}
11
12pub trait NetDevice: Send + Sync {
14 fn send(&self, packet: &[u8]) -> Result<(), NetDeviceError>;
16
17 fn receive(&self, buf: &mut [u8]) -> Result<usize, NetDeviceError>;
19
20 fn device_id(&self) -> usize;
22
23 fn mtu(&self) -> usize;
25
26 fn name(&self) -> &str;
28
29 fn mac_address(&self) -> [u8; 6];
31}
32
33use crate::device::virtio_hal::VirtIOHal;
34use crate::sync::SpinLock;
35use alloc::boxed::Box;
36use alloc::sync::Arc;
37use virtio_drivers::{
38 device::net::{TxBuffer, VirtIONet},
39 transport::Transport,
40};
41
42pub struct VirtioNetDevice<T: Transport + Send + Sync> {
44 virtio_net: SpinLock<Option<Box<VirtIONet<VirtIOHal, T, 256>>>>,
46 device_id: usize,
47 name: &'static str,
48 mac: [u8; 6],
49 mtu: usize,
50}
51
52impl<T: Transport + Send + Sync> VirtioNetDevice<T> {
53 pub fn new(transport: T, device_id: usize) -> Result<Arc<Self>, NetDeviceError> {
59 let virtio_net = VirtIONet::<VirtIOHal, T, 256>::new(transport, 0)
60 .map_err(|_| NetDeviceError::DeviceNotReady)?;
61
62 let mac = virtio_net.mac_address();
64 let mtu = 1500; Ok(Arc::new(Self {
67 virtio_net: SpinLock::new(Some(Box::new(virtio_net))),
68 device_id,
69 name: "virtio-net",
70 mac,
71 mtu,
72 }))
73 }
74}
75
76impl<T: Transport + Send + Sync> NetDevice for VirtioNetDevice<T> {
77 fn send(&self, packet: &[u8]) -> Result<(), NetDeviceError> {
79 if packet.len() > self.mtu {
80 return Err(NetDeviceError::QueueFull);
82 }
83
84 if let Some(ref mut virtio_net) = *self.virtio_net.lock() {
86 let tx_buffer = TxBuffer::from(packet);
87 match virtio_net.send(tx_buffer) {
88 Ok(_) => Ok(()),
89 Err(_) => Err(NetDeviceError::QueueFull),
90 }
91 } else {
92 Err(NetDeviceError::DeviceNotReady)
93 }
94 }
95
96 fn receive(&self, buf: &mut [u8]) -> Result<usize, NetDeviceError> {
98 if let Some(ref mut virtio_net) = *self.virtio_net.lock() {
100 match virtio_net.receive() {
101 Ok(rx_buffer) => {
102 let packet = rx_buffer.packet();
104 let actual_len = core::cmp::min(packet.len(), buf.len());
105 buf[..actual_len].copy_from_slice(&packet[..actual_len]);
106 Ok(actual_len)
107 }
108 Err(_) => Err(NetDeviceError::QueueEmpty),
109 }
110 } else {
111 Err(NetDeviceError::DeviceNotReady)
112 }
113 }
114
115 fn device_id(&self) -> usize {
117 self.device_id
118 }
119
120 fn mtu(&self) -> usize {
122 self.mtu
123 }
124
125 fn name(&self) -> &str {
127 self.name
128 }
129
130 fn mac_address(&self) -> [u8; 6] {
132 self.mac
133 }
134}