Skip to content

Commit ac664be

Browse files
d-sonugaveluca93
authored andcommitted
wrapped SNP functions
1 parent 8b61a4c commit ac664be

File tree

1 file changed

+235
-9
lines changed

1 file changed

+235
-9
lines changed

uefi/src/proto/network/snp.rs

Lines changed: 235 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
//! Simple Network Protocol
2+
//!
3+
//! Provides a packet level interface to a network adapter.
4+
//! Once the adapter is initialized, the protocol provides services that allows
5+
//! packets to be transmitted and received.
6+
//!
7+
//! No interface function must be called until `SimpleNetwork.start` is successfully
8+
//! called first.
29
310
use core::ffi::c_void;
4-
use crate::Status;
11+
use core::ptr;
12+
use uefi_macros::{unsafe_guid, Protocol};
13+
use crate::{Status, Result};
514
use crate::data_types::Event;
615
use super::{IpAddress, MacAddress};
716

@@ -28,7 +37,7 @@ pub struct SimpleNetwork {
2837
mcast_filter_count: Option<usize>,
2938
mcast_filter: Option<*const [MacAddress]>
3039
) -> Status,
31-
station_address: extern "efiapi" fn(this: &Self, reset: bool, new: Option<MacAddress>) -> Status,
40+
station_address: extern "efiapi" fn(this: &Self, reset: bool, new: Option<&MacAddress>) -> Status,
3241
statistics: extern "efiapi" fn(
3342
this: &Self,
3443
reset: bool,
@@ -38,7 +47,7 @@ pub struct SimpleNetwork {
3847
mcast_ip_to_mac: extern "efiapi" fn(
3948
this: &Self,
4049
ipv6: bool,
41-
ip: &IpAdddress,
50+
ip: &IpAddress,
4251
mac: &mut MacAddress
4352
) -> Status,
4453
nv_data: extern "efiapi" fn(
@@ -50,17 +59,17 @@ pub struct SimpleNetwork {
5059
) -> Status,
5160
get_status: extern "efiapi" fn(
5261
this: &Self,
53-
interrupt_status: Option<&mut u32>,
62+
interrupt_status: Option<&mut InterruptStatus>,
5463
tx_buf: Option<&mut *mut c_void>
5564
) -> Status,
5665
transmit: extern "efiapi" fn(
5766
this: &Self,
5867
header_size: usize,
5968
buffer_size: usize,
6069
buffer: *mut c_void,
61-
src_addr: Option<&mut MacAddress>,
62-
dest_addr: Option<&mut MacAddress>,
63-
protocol: Option<&mut u16>
70+
src_addr: Option<&MacAddress>,
71+
dest_addr: Option<&MacAddress>,
72+
protocol: Option<&u16>
6473
) -> Status,
6574
receive: extern "efiapi" fn(
6675
this: &Self,
@@ -75,11 +84,219 @@ pub struct SimpleNetwork {
7584
mode: *const NetworkMode,
7685
}
7786

87+
impl SimpleNetwork {
88+
/// Changes the state of a network from "Stopped" to "Started"
89+
pub fn start(&self) -> Result {
90+
(self.start)(self).into()
91+
}
92+
93+
/// Changes the state of a network interface from "Started" to "Stopped"
94+
pub fn stop(&self) -> Result {
95+
(self.stop)(self).into()
96+
}
97+
98+
/// Resets a network adapter and allocates the transmit and receive buffers
99+
/// required by the network interface; optionally, also requests allocation of
100+
/// additional transmit and receive buffers
101+
pub fn initialize(
102+
&self,
103+
extra_rx_buffer_size: Option<usize>,
104+
extra_tx_buffer_size: Option<usize>
105+
) -> Result {
106+
(self.initialize)(self, extra_rx_buffer_size, extra_tx_buffer_size).into()
107+
}
108+
109+
/// Resets a network adapter and reinitializes it with the parameters that were
110+
/// provided in the previous call to `initialize`
111+
pub fn reset(&self, extended_verification: bool) -> Result {
112+
(self.reset)(self, extended_verification).into()
113+
}
114+
115+
/// Resets a network adapter and leaves it in a state that is safe
116+
/// for another driver to initialize
117+
pub fn shutdown(&self) -> Result {
118+
(self.shutdown)(self).into()
119+
}
120+
121+
/// Manages the multicast receive filters of a network
122+
pub fn receive_filters(
123+
&self,
124+
enable: u32,
125+
disable: u32,
126+
reset_mcast_filter: bool,
127+
mcast_filter_count: Option<usize>,
128+
mcast_filter: Option<*const [MacAddress]>
129+
) -> Result {
130+
(self.receive_filters)(
131+
self,
132+
enable,
133+
disable,
134+
reset_mcast_filter,
135+
mcast_filter_count,
136+
mcast_filter
137+
).into()
138+
}
139+
140+
/// Modifies or resets the current station address, if supported
141+
pub fn station_address(&self, reset: bool, new: Option<&MacAddress>) -> Result {
142+
(self.station_address)(
143+
self,
144+
reset,
145+
new
146+
).into()
147+
}
148+
149+
/// Resets statistics on a network interface
150+
pub fn reset_statistics(&self) -> Result {
151+
(self.statistics)(self, true, None, None).into()
152+
}
153+
154+
/// Collects statistics on a network interface
155+
pub fn collect_statistics(&self) -> Result<NetworkStats> {
156+
let mut stats_table: NetworkStats = Default::default();
157+
let mut stats_size = core::mem::size_of::<NetworkStats>();
158+
let status = (self.statistics)(self, false, Some(&mut stats_size), Some(&mut stats_table));
159+
Result::from(status)?;
160+
Ok(stats_table)
161+
}
162+
163+
/// Converts a multicast IP address to a multicast HW MAC Address
164+
pub fn mcast_ip_to_mac(&self, ipv6: bool, ip: IpAddress) -> Result<MacAddress> {
165+
let mut mac_address = MacAddress([0; 32]);
166+
let status = (self.mcast_ip_to_mac)(self, ipv6, &ip, &mut mac_address);
167+
Result::from(status)?;
168+
Ok(mac_address)
169+
}
170+
171+
/// Performs read operations on the NVRAM device attached to
172+
/// a network interface
173+
pub fn read_nv_data(&self, offset: usize, buffer_size: usize, buffer: *mut c_void) -> Result {
174+
(self.nv_data)(
175+
self,
176+
true,
177+
offset,
178+
buffer_size,
179+
buffer
180+
).into()
181+
}
182+
183+
/// Performs write operations on the NVRAM device attached to a network interface
184+
pub fn write_nv_data(&self, offset: usize, buffer_size: usize, buffer: *mut c_void) -> Result {
185+
(self.nv_data)(
186+
self,
187+
false,
188+
offset,
189+
buffer_size,
190+
buffer
191+
).into()
192+
}
193+
194+
/// Reads the current interrupt status and recycled transmit buffer
195+
/// status from a network interface
196+
pub fn get_interrupt_status(&self) -> Result<InterruptStatus> {
197+
let mut interrupt_status = InterruptStatus::new();
198+
let status = (self.get_status)(self, Some(&mut interrupt_status), None);
199+
Result::from(status)?;
200+
Ok(interrupt_status)
201+
}
202+
203+
/// Reads the current recycled transmit buffer status from a
204+
/// network interface
205+
pub fn get_recycled_transmit_buffer_status(&self) -> Result<Option<*mut u8>> {
206+
let mut tx_buf: *mut c_void = ptr::null_mut();
207+
let status = (self.get_status)(self, None, Some(&mut tx_buf));
208+
Result::from(status)?;
209+
if tx_buf == ptr::null_mut() {
210+
Ok(None)
211+
} else {
212+
Ok(Some(tx_buf.cast()))
213+
}
214+
}
215+
216+
/// Places a packet in the transmit queue of a network interface
217+
pub fn transmit(
218+
&self,
219+
header_size: usize,
220+
buffer: &mut [u8],
221+
src_addr: Option<&MacAddress>,
222+
dest_addr: Option<&MacAddress>,
223+
protocol: Option<&u16>
224+
) -> Result {
225+
(self.transmit)(
226+
self,
227+
header_size,
228+
buffer.len(),
229+
buffer.as_mut_ptr().cast(),
230+
src_addr,
231+
dest_addr,
232+
protocol
233+
).into()
234+
}
235+
236+
/// Receives a packet from a network interface
237+
///
238+
/// On success, returns the size of bytes of the received packet
239+
pub fn receive(
240+
&self,
241+
buffer: &mut [u8],
242+
header_size: Option<&mut usize>,
243+
src_addr: Option<&mut MacAddress>,
244+
dest_addr: Option<&mut MacAddress>,
245+
protocol: Option<&mut u16>
246+
) -> Result<usize> {
247+
let mut buffer_size = buffer.len();
248+
let status = (self.receive)(
249+
self,
250+
header_size,
251+
&mut buffer_size,
252+
buffer.as_mut_ptr().cast(),
253+
src_addr,
254+
dest_addr,
255+
protocol
256+
);
257+
Result::from(status)?;
258+
Ok(buffer_size)
259+
}
260+
261+
/// Returns a reference to the Simple Network mode
262+
pub fn mode(&self) -> &NetworkMode {
263+
unsafe { &*self.mode }
264+
}
265+
}
266+
267+
/// A bitmask of currently active interrupts
268+
#[repr(transparent)]
269+
pub struct InterruptStatus(u32);
270+
271+
impl InterruptStatus {
272+
/// Creates a new InterruptStatus instance with all bits unset
273+
pub fn new() -> Self {
274+
Self(0)
275+
}
276+
/// The receive interrupt bit
277+
pub fn receive_interrupt(&self) -> bool {
278+
self.0 & 0x01 == 1
279+
}
280+
/// The transmit interrupt bit
281+
pub fn transmit_interrupt(&self) -> bool {
282+
self.0 & 0x02 == 0x02
283+
}
284+
/// The command interrupt bit
285+
pub fn command_interrupt(&self) -> bool {
286+
self.0 & 0x04 == 0x04
287+
}
288+
/// The software interrupt bit
289+
pub fn software_interrupt(&self) -> bool {
290+
self.0 & 0x08 == 0x08
291+
}
292+
}
293+
78294
/// Network Statistics
79295
///
80296
/// The description of statistics on the network with the SNP's `statistics` function
81297
/// is returned in this structure
82298
#[repr(C)]
299+
#[derive(Default)]
83300
pub struct NetworkStats {
84301
total_frames_rx: u64,
85302
good_frames_rx: u64,
@@ -109,10 +326,10 @@ pub struct NetworkStats {
109326
retry_frames_tx: u64
110327
}
111328

329+
/// The Simple Network Mode
112330
#[repr(C)]
113-
#[derive(Debug)]
114331
pub struct NetworkMode {
115-
state: u32,
332+
state: NetworkState,
116333
hw_address_size: u32,
117334
media_header_size: u32,
118335
max_packet_size: u32,
@@ -131,4 +348,13 @@ pub struct NetworkMode {
131348
multiple_tx_supported: bool,
132349
media_present_supported: bool,
133350
media_present: bool
351+
}
352+
353+
newtype_enum! {
354+
pub enum NetworkState: u32 => {
355+
Stopped = 0,
356+
Started = 1,
357+
Initialized = 2,
358+
MaxState = 4
359+
}
134360
}

0 commit comments

Comments
 (0)