virtio_drivers/device/net/
dev.rs1use alloc::vec;
2
3use super::net_buf::{RxBuffer, TxBuffer};
4use super::{EthernetAddress, VirtIONetRaw};
5use crate::transport::InterruptStatus;
6use crate::{hal::Hal, transport::Transport, Error, Result};
7
8pub struct VirtIONet<H: Hal, T: Transport, const QUEUE_SIZE: usize> {
22 inner: VirtIONetRaw<H, T, QUEUE_SIZE>,
23 rx_buffers: [Option<RxBuffer>; QUEUE_SIZE],
24}
25
26impl<H: Hal, T: Transport, const QUEUE_SIZE: usize> VirtIONet<H, T, QUEUE_SIZE> {
27 pub fn new(transport: T, buf_len: usize) -> Result<Self> {
29 let mut inner = VirtIONetRaw::new(transport)?;
30
31 const NONE_BUF: Option<RxBuffer> = None;
32 let mut rx_buffers = [NONE_BUF; QUEUE_SIZE];
33 for (i, rx_buf_place) in rx_buffers.iter_mut().enumerate() {
34 let mut rx_buf = RxBuffer::new(i, buf_len, inner.legacy_header);
35 let token = unsafe { inner.receive_begin(rx_buf.as_bytes_mut())? };
37 assert_eq!(token, i as u16);
38 *rx_buf_place = Some(rx_buf);
39 }
40
41 Ok(VirtIONet { inner, rx_buffers })
42 }
43
44 pub fn ack_interrupt(&mut self) -> InterruptStatus {
46 self.inner.ack_interrupt()
47 }
48
49 pub fn disable_interrupts(&mut self) {
51 self.inner.disable_interrupts()
52 }
53
54 pub fn enable_interrupts(&mut self) {
56 self.inner.enable_interrupts()
57 }
58
59 pub fn mac_address(&self) -> EthernetAddress {
61 self.inner.mac_address()
62 }
63
64 pub fn can_send(&self) -> bool {
66 self.inner.can_send()
67 }
68
69 pub fn can_recv(&self) -> bool {
71 self.inner.poll_receive().is_some()
72 }
73
74 pub fn receive(&mut self) -> Result<RxBuffer> {
80 if let Some(token) = self.inner.poll_receive() {
81 let mut rx_buf = self.rx_buffers[token as usize]
82 .take()
83 .ok_or(Error::WrongToken)?;
84 if token != rx_buf.idx {
85 return Err(Error::WrongToken);
86 }
87
88 let (_hdr_len, pkt_len) =
91 unsafe { self.inner.receive_complete(token, rx_buf.as_bytes_mut())? };
92 rx_buf.set_packet_len(pkt_len);
93 Ok(rx_buf)
94 } else {
95 Err(Error::NotReady)
96 }
97 }
98
99 pub fn recycle_rx_buffer(&mut self, mut rx_buf: RxBuffer) -> Result {
103 let new_token = unsafe { self.inner.receive_begin(rx_buf.as_bytes_mut()) }?;
106 if self.rx_buffers[new_token as usize].is_some() {
109 return Err(Error::WrongToken);
110 }
111 rx_buf.idx = new_token;
112 self.rx_buffers[new_token as usize] = Some(rx_buf);
113 Ok(())
114 }
115
116 pub fn new_tx_buffer(&self, buf_len: usize) -> TxBuffer {
118 TxBuffer(vec![0; buf_len])
119 }
120
121 pub fn send(&mut self, tx_buf: TxBuffer) -> Result {
124 self.inner.send(tx_buf.packet())
125 }
126}