1
1
//! 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.
2
9
3
10
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 } ;
5
14
use crate :: data_types:: Event ;
6
15
use super :: { IpAddress , MacAddress } ;
7
16
@@ -28,7 +37,7 @@ pub struct SimpleNetwork {
28
37
mcast_filter_count : Option < usize > ,
29
38
mcast_filter : Option < * const [ MacAddress ] >
30
39
) -> 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 ,
32
41
statistics : extern "efiapi" fn (
33
42
this : & Self ,
34
43
reset : bool ,
@@ -38,7 +47,7 @@ pub struct SimpleNetwork {
38
47
mcast_ip_to_mac : extern "efiapi" fn (
39
48
this : & Self ,
40
49
ipv6 : bool ,
41
- ip : & IpAdddress ,
50
+ ip : & IpAddress ,
42
51
mac : & mut MacAddress
43
52
) -> Status ,
44
53
nv_data : extern "efiapi" fn (
@@ -50,17 +59,17 @@ pub struct SimpleNetwork {
50
59
) -> Status ,
51
60
get_status : extern "efiapi" fn (
52
61
this : & Self ,
53
- interrupt_status : Option < & mut u32 > ,
62
+ interrupt_status : Option < & mut InterruptStatus > ,
54
63
tx_buf : Option < & mut * mut c_void >
55
64
) -> Status ,
56
65
transmit : extern "efiapi" fn (
57
66
this : & Self ,
58
67
header_size : usize ,
59
68
buffer_size : usize ,
60
69
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 >
64
73
) -> Status ,
65
74
receive : extern "efiapi" fn (
66
75
this : & Self ,
@@ -75,11 +84,219 @@ pub struct SimpleNetwork {
75
84
mode : * const NetworkMode ,
76
85
}
77
86
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
+
78
294
/// Network Statistics
79
295
///
80
296
/// The description of statistics on the network with the SNP's `statistics` function
81
297
/// is returned in this structure
82
298
#[ repr( C ) ]
299
+ #[ derive( Default ) ]
83
300
pub struct NetworkStats {
84
301
total_frames_rx : u64 ,
85
302
good_frames_rx : u64 ,
@@ -109,10 +326,10 @@ pub struct NetworkStats {
109
326
retry_frames_tx : u64
110
327
}
111
328
329
+ /// The Simple Network Mode
112
330
#[ repr( C ) ]
113
- #[ derive( Debug ) ]
114
331
pub struct NetworkMode {
115
- state : u32 ,
332
+ state : NetworkState ,
116
333
hw_address_size : u32 ,
117
334
media_header_size : u32 ,
118
335
max_packet_size : u32 ,
@@ -131,4 +348,13 @@ pub struct NetworkMode {
131
348
multiple_tx_supported : bool ,
132
349
media_present_supported : bool ,
133
350
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
+ }
134
360
}
0 commit comments