#[cfg(feature = "alloc")]
mod dev;
mod dev_raw;
#[cfg(feature = "alloc")]
mod net_buf;
pub use self::dev_raw::VirtIONetRaw;
#[cfg(feature = "alloc")]
pub use self::{dev::VirtIONet, net_buf::RxBuffer, net_buf::TxBuffer};
use crate::config::ReadOnly;
use bitflags::bitflags;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
const MAX_BUFFER_LEN: usize = 65535;
const MIN_BUFFER_LEN: usize = 1526;
bitflags! {
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
struct Features: u64 {
const CSUM = 1 << 0;
const GUEST_CSUM = 1 << 1;
const CTRL_GUEST_OFFLOADS = 1 << 2;
const MTU = 1 << 3;
const MAC = 1 << 5;
const GSO = 1 << 6;
const GUEST_TSO4 = 1 << 7;
const GUEST_TSO6 = 1 << 8;
const GUEST_ECN = 1 << 9;
const GUEST_UFO = 1 << 10;
const HOST_TSO4 = 1 << 11;
const HOST_TSO6 = 1 << 12;
const HOST_ECN = 1 << 13;
const HOST_UFO = 1 << 14;
const MRG_RXBUF = 1 << 15;
const STATUS = 1 << 16;
const CTRL_VQ = 1 << 17;
const CTRL_RX = 1 << 18;
const CTRL_VLAN = 1 << 19;
const CTRL_RX_EXTRA = 1 << 20;
const GUEST_ANNOUNCE = 1 << 21;
const MQ = 1 << 22;
const CTL_MAC_ADDR = 1 << 23;
const RING_INDIRECT_DESC = 1 << 28;
const RING_EVENT_IDX = 1 << 29;
const VERSION_1 = 1 << 32; }
}
#[derive(
Copy, Clone, Debug, Default, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq,
)]
#[repr(transparent)]
struct Status(u16);
bitflags! {
impl Status: u16 {
const LINK_UP = 1;
const ANNOUNCE = 2;
}
}
bitflags! {
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
struct InterruptStatus : u32 {
const USED_RING_UPDATE = 1 << 0;
const CONFIGURATION_CHANGE = 1 << 1;
}
}
#[repr(C)]
struct Config {
mac: ReadOnly<EthernetAddress>,
status: ReadOnly<Status>,
max_virtqueue_pairs: ReadOnly<u16>,
mtu: ReadOnly<u16>,
}
type EthernetAddress = [u8; 6];
#[repr(C)]
#[derive(Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
pub(crate) struct VirtioNetHdrLegacy {
flags: Flags,
gso_type: GsoType,
hdr_len: u16, gso_size: u16,
csum_start: u16,
csum_offset: u16,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
pub struct VirtioNetHdr {
flags: Flags,
gso_type: GsoType,
hdr_len: u16, gso_size: u16,
csum_start: u16,
csum_offset: u16,
num_buffers: u16,
}
impl From<&VirtioNetHdrLegacy> for VirtioNetHdr {
fn from(legacy: &VirtioNetHdrLegacy) -> Self {
let VirtioNetHdrLegacy {
flags,
gso_type,
hdr_len,
gso_size,
csum_start,
csum_offset,
} = *legacy;
Self {
flags,
gso_type,
hdr_len,
gso_size,
csum_start,
csum_offset,
num_buffers: 0,
}
}
}
#[derive(
IntoBytes, Copy, Clone, Debug, Default, Eq, FromBytes, Immutable, KnownLayout, PartialEq,
)]
#[repr(transparent)]
struct Flags(u8);
bitflags! {
impl Flags: u8 {
const NEEDS_CSUM = 1;
const DATA_VALID = 2;
const RSC_INFO = 4;
}
}
#[repr(transparent)]
#[derive(
IntoBytes, Debug, Copy, Clone, Default, Eq, FromBytes, Immutable, KnownLayout, PartialEq,
)]
struct GsoType(u8);
impl GsoType {
const NONE: GsoType = GsoType(0);
const TCPV4: GsoType = GsoType(1);
const UDP: GsoType = GsoType(3);
const TCPV6: GsoType = GsoType(4);
const ECN: GsoType = GsoType(0x80);
}
const QUEUE_RECEIVE: u16 = 0;
const QUEUE_TRANSMIT: u16 = 1;
const SUPPORTED_FEATURES: Features = Features::MAC
.union(Features::STATUS)
.union(Features::RING_EVENT_IDX)
.union(Features::RING_INDIRECT_DESC)
.union(Features::VERSION_1);