sel4_virtio_net/
lib.rs
1#![no_std]
9
10extern crate alloc;
11
12use alloc::rc::Rc;
13use core::cell::RefCell;
14use core::convert::Infallible;
15
16use log::trace;
17use sel4_driver_interfaces::net::{GetNetDeviceMeta, MacAddress};
18use sel4_driver_interfaces::HandleInterrupt;
19use smoltcp::phy::{Device, DeviceCapabilities, Medium, RxToken, TxToken};
20use smoltcp::time::Instant;
21use virtio_drivers::device::net::{RxBuffer, VirtIONet};
22use virtio_drivers::{transport::Transport, Error, Hal};
23
24pub const NET_QUEUE_SIZE: usize = 16;
25
26pub type DeviceImpl<H, T> = VirtIONet<H, T, NET_QUEUE_SIZE>;
27
28pub struct DeviceWrapper<H: Hal, T: Transport> {
29 inner: Rc<RefCell<DeviceImpl<H, T>>>,
30}
31
32impl<H: Hal, T: Transport> DeviceWrapper<H, T> {
33 pub fn new(dev: DeviceImpl<H, T>) -> Self {
34 DeviceWrapper {
35 inner: Rc::new(RefCell::new(dev)),
36 }
37 }
38}
39
40impl<H: Hal, T: Transport> HandleInterrupt for DeviceWrapper<H, T> {
41 fn handle_interrupt(&mut self) {
42 self.inner.borrow_mut().ack_interrupt();
43 }
44}
45
46impl<H: Hal, T: Transport> GetNetDeviceMeta for DeviceWrapper<H, T> {
47 type Error = Infallible;
48
49 fn get_mac_address(&mut self) -> Result<MacAddress, Self::Error> {
50 Ok(MacAddress(self.inner.borrow().mac_address()))
51 }
52}
53
54impl<H: Hal, T: Transport> Device for DeviceWrapper<H, T> {
55 type RxToken<'a>
56 = VirtioRxToken<H, T>
57 where
58 Self: 'a;
59 type TxToken<'a>
60 = VirtioTxToken<H, T>
61 where
62 Self: 'a;
63
64 fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
65 match self.inner.borrow_mut().receive() {
66 Ok(buf) => Some((
67 VirtioRxToken(self.inner.clone(), buf),
68 VirtioTxToken(self.inner.clone()),
69 )),
70 Err(Error::NotReady) => None,
71 Err(err) => panic!("receive failed: {}", err),
72 }
73 }
74
75 fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
76 Some(VirtioTxToken(self.inner.clone()))
77 }
78
79 fn capabilities(&self) -> DeviceCapabilities {
80 let mut caps = DeviceCapabilities::default();
81 caps.max_transmission_unit = 1536;
82 caps.max_burst_size = Some(1);
83 caps.medium = Medium::Ethernet;
84 caps
85 }
86}
87
88pub struct VirtioRxToken<H: Hal, T: Transport>(Rc<RefCell<DeviceImpl<H, T>>>, RxBuffer);
89
90impl<H: Hal, T: Transport> RxToken for VirtioRxToken<H, T> {
91 fn consume<R, F>(self, f: F) -> R
92 where
93 F: FnOnce(&mut [u8]) -> R,
94 {
95 let mut rx_buf = self.1;
96 trace!(
97 "RECV {} bytes: {:02X?}",
98 rx_buf.packet_len(),
99 rx_buf.packet()
100 );
101 let result = f(rx_buf.packet_mut());
102 self.0.borrow_mut().recycle_rx_buffer(rx_buf).unwrap();
103 result
104 }
105}
106
107pub struct VirtioTxToken<H: Hal, T: Transport>(Rc<RefCell<DeviceImpl<H, T>>>);
108
109impl<H: Hal, T: Transport> TxToken for VirtioTxToken<H, T> {
110 fn consume<R, F>(self, len: usize, f: F) -> R
111 where
112 F: FnOnce(&mut [u8]) -> R,
113 {
114 let mut dev = self.0.borrow_mut();
115 let mut tx_buf = dev.new_tx_buffer(len);
116 let result = f(tx_buf.packet_mut());
117 trace!("SEND {} bytes: {:02X?}", len, tx_buf.packet());
118 dev.send(tx_buf).unwrap();
119 result
120 }
121}