use core::ffi;
use bitflags::bitflags;
use crate::{Boolean, Event, Guid, IpAddress, MacAddress, Status, guid, newtype_enum};
#[derive(Debug)]
#[repr(C)]
pub struct SimpleNetworkProtocol {
pub revision: u64,
pub start: unsafe extern "efiapi" fn(this: *const Self) -> Status,
pub stop: unsafe extern "efiapi" fn(this: *const Self) -> Status,
pub initialize: unsafe extern "efiapi" fn(
this: *const Self,
extra_receive_buffer_size: usize,
extra_transmit_buffer_size: usize,
) -> Status,
pub reset:
unsafe extern "efiapi" fn(this: *const Self, extended_verification: Boolean) -> Status,
pub shutdown: unsafe extern "efiapi" fn(this: *const Self) -> Status,
pub receive_filters: unsafe extern "efiapi" fn(
this: *const Self,
enable: ReceiveFlags,
disable: ReceiveFlags,
reset_multicast_filter: Boolean,
multicast_filter_count: usize,
multicast_filter: *const MacAddress,
) -> Status,
pub station_address: unsafe extern "efiapi" fn(
this: *const Self,
reset: Boolean,
new: *const MacAddress,
) -> Status,
pub statistics: unsafe extern "efiapi" fn(
this: *const Self,
reset: Boolean,
statistics_size: *mut usize,
statistics_table: *mut NetworkStatistics,
) -> Status,
pub multicast_ip_to_mac: unsafe extern "efiapi" fn(
this: *const Self,
ipv6: Boolean,
ip: *const IpAddress,
mac: *mut MacAddress,
) -> Status,
pub non_volatile_data: unsafe extern "efiapi" fn(
this: *const Self,
read: Boolean,
offset: usize,
buffer_size: usize,
buffer: *mut ffi::c_void,
) -> Status,
pub get_status: unsafe extern "efiapi" fn(
this: *const Self,
interrupt_status: *mut InterruptStatus,
transmit_buffer: *mut *mut ffi::c_void,
) -> Status,
pub transmit: unsafe extern "efiapi" fn(
this: *const Self,
header_size: usize,
buffer_size: usize,
buffer: *const ffi::c_void,
source_address: *const MacAddress,
dest_address: *const MacAddress,
protocol: *const u16,
) -> Status,
pub receive: unsafe extern "efiapi" fn(
this: *const Self,
header_size: *mut usize,
buffer_size: *mut usize,
buffer: *mut ffi::c_void,
source_address: *mut MacAddress,
dest_address: *mut MacAddress,
protocol: *mut u16,
) -> Status,
pub wait_for_packet: Event,
pub mode: *mut NetworkMode,
}
impl SimpleNetworkProtocol {
pub const GUID: Guid = guid!("a19832b9-ac25-11d3-9a2d-0090273fc14d");
}
bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct ReceiveFlags: u32 {
const UNICAST = 0x01;
const MULTICAST = 0x02;
const BROADCAST = 0x04;
const PROMISCUOUS = 0x08;
const PROMISCUOUS_MULTICAST = 0x10;
}
}
bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct InterruptStatus: u32 {
const RECEIVE = 0x01;
const TRANSMIT = 0x02;
const COMMAND = 0x04;
const SOFTWARE = 0x08;
}
}
#[repr(C)]
#[derive(Default, Debug)]
pub struct NetworkStatistics {
pub rx_total_frames: u64,
pub rx_good_frames: u64,
pub rx_undersize_frames: u64,
pub rx_oversize_frames: u64,
pub rx_dropped_frames: u64,
pub rx_unicast_frames: u64,
pub rx_broadcast_frames: u64,
pub rx_multicast_frames: u64,
pub rx_crc_error_frames: u64,
pub rx_total_bytes: u64,
pub tx_total_frames: u64,
pub tx_good_frames: u64,
pub tx_undersize_frames: u64,
pub tx_oversize_frames: u64,
pub tx_dropped_frames: u64,
pub tx_unicast_frames: u64,
pub tx_broadcast_frames: u64,
pub tx_multicast_frames: u64,
pub tx_crc_error_frames: u64,
pub tx_total_bytes: u64,
pub collisions: u64,
pub unsupported_protocol: u64,
pub rx_duplicated_frames: u64,
pub rx_decrypt_error_frames: u64,
pub tx_error_frames: u64,
pub tx_retry_frames: u64,
}
impl NetworkStatistics {
const fn available(&self, stat: u64) -> bool {
stat as i64 != -1
}
const fn to_option(&self, stat: u64) -> Option<u64> {
match self.available(stat) {
true => Some(stat),
false => None,
}
}
#[must_use]
pub const fn rx_total_frames(&self) -> Option<u64> {
self.to_option(self.rx_total_frames)
}
#[must_use]
pub const fn rx_good_frames(&self) -> Option<u64> {
self.to_option(self.rx_good_frames)
}
#[must_use]
pub const fn rx_undersize_frames(&self) -> Option<u64> {
self.to_option(self.rx_undersize_frames)
}
#[must_use]
pub const fn rx_oversize_frames(&self) -> Option<u64> {
self.to_option(self.rx_oversize_frames)
}
#[must_use]
pub const fn rx_dropped_frames(&self) -> Option<u64> {
self.to_option(self.rx_dropped_frames)
}
#[must_use]
pub const fn rx_unicast_frames(&self) -> Option<u64> {
self.to_option(self.rx_unicast_frames)
}
#[must_use]
pub const fn rx_broadcast_frames(&self) -> Option<u64> {
self.to_option(self.rx_broadcast_frames)
}
#[must_use]
pub const fn rx_multicast_frames(&self) -> Option<u64> {
self.to_option(self.rx_multicast_frames)
}
#[must_use]
pub const fn rx_crc_error_frames(&self) -> Option<u64> {
self.to_option(self.rx_crc_error_frames)
}
#[must_use]
pub const fn rx_total_bytes(&self) -> Option<u64> {
self.to_option(self.rx_total_bytes)
}
#[must_use]
pub const fn tx_total_frames(&self) -> Option<u64> {
self.to_option(self.tx_total_frames)
}
#[must_use]
pub const fn tx_good_frames(&self) -> Option<u64> {
self.to_option(self.tx_good_frames)
}
#[must_use]
pub const fn tx_undersize_frames(&self) -> Option<u64> {
self.to_option(self.tx_undersize_frames)
}
#[must_use]
pub const fn tx_oversize_frames(&self) -> Option<u64> {
self.to_option(self.tx_oversize_frames)
}
#[must_use]
pub const fn tx_dropped_frames(&self) -> Option<u64> {
self.to_option(self.tx_dropped_frames)
}
#[must_use]
pub const fn tx_unicast_frames(&self) -> Option<u64> {
self.to_option(self.tx_unicast_frames)
}
#[must_use]
pub const fn tx_broadcast_frames(&self) -> Option<u64> {
self.to_option(self.tx_broadcast_frames)
}
#[must_use]
pub const fn tx_multicast_frames(&self) -> Option<u64> {
self.to_option(self.tx_multicast_frames)
}
#[must_use]
pub const fn tx_crc_error_frames(&self) -> Option<u64> {
self.to_option(self.tx_crc_error_frames)
}
#[must_use]
pub const fn tx_total_bytes(&self) -> Option<u64> {
self.to_option(self.tx_total_bytes)
}
#[must_use]
pub const fn collisions(&self) -> Option<u64> {
self.to_option(self.collisions)
}
#[must_use]
pub const fn unsupported_protocol(&self) -> Option<u64> {
self.to_option(self.unsupported_protocol)
}
#[must_use]
pub const fn rx_duplicated_frames(&self) -> Option<u64> {
self.to_option(self.rx_duplicated_frames)
}
#[must_use]
pub const fn rx_decrypt_error_frames(&self) -> Option<u64> {
self.to_option(self.rx_decrypt_error_frames)
}
#[must_use]
pub const fn tx_error_frames(&self) -> Option<u64> {
self.to_option(self.tx_error_frames)
}
#[must_use]
pub const fn tx_retry_frames(&self) -> Option<u64> {
self.to_option(self.tx_retry_frames)
}
}
#[repr(C)]
#[derive(Debug)]
pub struct NetworkMode {
pub state: NetworkState,
pub hw_address_size: u32,
pub media_header_size: u32,
pub max_packet_size: u32,
pub nv_ram_size: u32,
pub nv_ram_access_size: u32,
pub receive_filter_mask: u32,
pub receive_filter_setting: u32,
pub max_mcast_filter_count: u32,
pub mcast_filter_count: u32,
pub mcast_filter: [MacAddress; 16],
pub current_address: MacAddress,
pub broadcast_address: MacAddress,
pub permanent_address: MacAddress,
pub if_type: u8,
pub mac_address_changeable: Boolean,
pub multiple_tx_supported: Boolean,
pub media_present_supported: Boolean,
pub media_present: Boolean,
}
newtype_enum! {
pub enum NetworkState: u32 => {
STOPPED = 0,
STARTED = 1,
INITIALIZED = 2,
MAX_STATE = 4,
}
}