]>
Commit | Line | Data |
---|---|---|
2ff79f2e | 1 | /** @file\r |
2 | \r | |
1b7edf0f | 3 | Copyright (c) 2010, Apple, Inc. All rights reserved.<BR>\r |
2ff79f2e | 4 | \r |
5 | This program and the accompanying materials\r | |
6 | are licensed and made available under the terms and conditions of the BSD License\r | |
7 | which accompanies this distribution. The full text of the license may be found at\r | |
8 | http://opensource.org/licenses/bsd-license.php\r | |
9 | \r | |
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
12 | \r | |
13 | Module Name:\r | |
14 | \r | |
15 | UnixSnp.c\r | |
16 | \r | |
17 | Abstract:\r | |
18 | \r | |
19 | -**/\r | |
20 | \r | |
21 | #include <Library/PrintLib.h>\r | |
22 | \r | |
23 | #include "UnixSnp.h"\r | |
24 | \r | |
25 | EFI_DRIVER_BINDING_PROTOCOL gUnixSnpDriverBinding =\r | |
26 | {\r | |
2ac288f9 | 27 | UnixSnpDriverBindingSupported,\r |
28 | UnixSnpDriverBindingStart,\r | |
29 | UnixSnpDriverBindingStop,\r | |
30 | 0xA,\r | |
31 | NULL,\r | |
32 | NULL\r | |
2ff79f2e | 33 | };\r |
34 | \r | |
35 | /**\r | |
36 | Changes the state of a network interface from "stopped" to "started".\r | |
37 | \r | |
38 | @param This Protocol instance pointer.\r | |
39 | \r | |
40 | @retval EFI_SUCCESS Always succeeds.\r | |
41 | \r | |
42 | **/\r | |
43 | EFI_STATUS\r | |
44 | EFIAPI\r | |
45 | UnixSnpStart(\r | |
2ac288f9 | 46 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r |
47 | );\r | |
2ff79f2e | 48 | \r |
49 | /**\r | |
50 | Changes the state of a network interface from "started" to "stopped".\r | |
51 | \r | |
52 | @param This Protocol instance pointer.\r | |
53 | \r | |
54 | @retval EFI_SUCCESS Always succeeds.\r | |
55 | \r | |
56 | **/\r | |
57 | EFI_STATUS\r | |
58 | EFIAPI\r | |
59 | UnixSnpStop(\r | |
2ac288f9 | 60 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r |
61 | );\r | |
2ff79f2e | 62 | \r |
63 | /**\r | |
64 | Resets a network adapter and allocates the transmit and receive buffers \r | |
65 | required by the network interface; optionally, also requests allocation \r | |
66 | of additional transmit and receive buffers.\r | |
67 | \r | |
68 | @param This Protocol instance pointer.\r | |
69 | @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space\r | |
70 | that the driver should allocate for the network interface.\r | |
71 | Some network interfaces will not be able to use the extra\r | |
72 | buffer, and the caller will not know if it is actually\r | |
73 | being used.\r | |
74 | @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space\r | |
75 | that the driver should allocate for the network interface.\r | |
76 | Some network interfaces will not be able to use the extra\r | |
77 | buffer, and the caller will not know if it is actually\r | |
78 | being used.\r | |
79 | \r | |
80 | @retval EFI_SUCCESS Always succeeds.\r | |
81 | \r | |
82 | **/\r | |
83 | EFI_STATUS\r | |
84 | EFIAPI\r | |
85 | UnixSnpInitialize(\r | |
2ac288f9 | 86 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
87 | IN UINTN ExtraRxBufferSize OPTIONAL,\r | |
88 | IN UINTN ExtraTxBufferSize OPTIONAL\r | |
89 | );\r | |
2ff79f2e | 90 | \r |
91 | /**\r | |
92 | Resets a network adapter and re-initializes it with the parameters that were \r | |
93 | provided in the previous call to Initialize(). \r | |
94 | \r | |
95 | @param This Protocol instance pointer.\r | |
96 | @param ExtendedVerification Indicates that the driver may perform a more\r | |
97 | exhaustive verification operation of the device\r | |
98 | during reset.\r | |
99 | \r | |
100 | @retval EFI_SUCCESS Always succeeds.\r | |
101 | \r | |
102 | **/\r | |
103 | EFI_STATUS\r | |
104 | EFIAPI\r | |
105 | UnixSnpReset(\r | |
2ac288f9 | 106 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
107 | IN BOOLEAN ExtendedVerification\r | |
108 | );\r | |
2ff79f2e | 109 | \r |
110 | /**\r | |
111 | Resets a network adapter and leaves it in a state that is safe for \r | |
112 | another driver to initialize.\r | |
113 | \r | |
114 | @param This Protocol instance pointer.\r | |
115 | \r | |
116 | @retval EFI_SUCCESS Always succeeds.\r | |
117 | \r | |
118 | **/\r | |
119 | EFI_STATUS\r | |
120 | EFIAPI\r | |
121 | UnixSnpShutdown(\r | |
2ac288f9 | 122 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r |
123 | );\r | |
2ff79f2e | 124 | \r |
125 | /**\r | |
126 | Manages the multicast receive filters of a network interface.\r | |
127 | \r | |
128 | @param This Protocol instance pointer.\r | |
129 | @param EnableBits A bit mask of receive filters to enable on the network interface.\r | |
130 | @param DisableBits A bit mask of receive filters to disable on the network interface.\r | |
131 | @param ResetMcastFilter Set to TRUE to reset the contents of the multicast receive\r | |
132 | filters on the network interface to their default values.\r | |
133 | @param McastFilterCount Number of multicast HW MAC addresses in the new\r | |
134 | MCastFilter list. This value must be less than or equal to\r | |
135 | the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This\r | |
136 | field is optional if ResetMCastFilter is TRUE.\r | |
137 | @param McastFilter A pointer to a list of new multicast receive filter HW MAC\r | |
138 | addresses. This list will replace any existing multicast\r | |
139 | HW MAC address list. This field is optional if\r | |
140 | ResetMCastFilter is TRUE.\r | |
141 | \r | |
142 | @retval EFI_SUCCESS The multicast receive filter list was updated.\r | |
143 | @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r | |
144 | \r | |
145 | **/\r | |
146 | EFI_STATUS\r | |
147 | EFIAPI\r | |
148 | UnixSnpReceiveFilters(\r | |
2ac288f9 | 149 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
150 | IN UINT32 EnableBits,\r | |
151 | IN UINT32 DisableBits,\r | |
152 | IN BOOLEAN ResetMcastFilter,\r | |
153 | IN UINTN McastFilterCount OPTIONAL,\r | |
154 | IN EFI_MAC_ADDRESS* McastFilter OPTIONAL\r | |
155 | );\r | |
2ff79f2e | 156 | \r |
157 | /**\r | |
158 | Modifies or resets the current station address, if supported.\r | |
159 | \r | |
160 | @param This Protocol instance pointer.\r | |
161 | @param Reset Flag used to reset the station address to the network interfaces\r | |
162 | permanent address.\r | |
163 | @param NewMacAddr New station address to be used for the network interface.\r | |
164 | \r | |
165 | @retval EFI_UNSUPPORTED Not supported yet.\r | |
166 | \r | |
167 | **/\r | |
168 | EFI_STATUS\r | |
169 | EFIAPI\r | |
170 | UnixSnpStationAddress(\r | |
2ac288f9 | 171 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
172 | IN BOOLEAN Reset,\r | |
173 | IN EFI_MAC_ADDRESS* NewMacAddr OPTIONAL\r | |
174 | );\r | |
2ff79f2e | 175 | \r |
176 | /**\r | |
177 | Resets or collects the statistics on a network interface.\r | |
178 | \r | |
179 | @param This Protocol instance pointer.\r | |
180 | @param Reset Set to TRUE to reset the statistics for the network interface.\r | |
181 | @param StatisticsSize On input the size, in bytes, of StatisticsTable. On\r | |
182 | output the size, in bytes, of the resulting table of\r | |
183 | statistics.\r | |
184 | @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that\r | |
185 | contains the statistics.\r | |
186 | \r | |
187 | @retval EFI_SUCCESS The statistics were collected from the network interface.\r | |
188 | @retval EFI_NOT_STARTED The network interface has not been started.\r | |
189 | @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r | |
190 | size needed to hold the statistics is returned in\r | |
191 | StatisticsSize.\r | |
192 | @retval EFI_UNSUPPORTED Not supported yet.\r | |
193 | \r | |
194 | **/\r | |
195 | EFI_STATUS\r | |
196 | EFIAPI\r | |
197 | UnixSnpStatistics(\r | |
2ac288f9 | 198 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
199 | IN BOOLEAN Reset,\r | |
200 | IN OUT UINTN* StatisticsSize OPTIONAL,\r | |
201 | OUT EFI_NETWORK_STATISTICS* StatisticsTable OPTIONAL\r | |
202 | );\r | |
2ff79f2e | 203 | \r |
204 | /**\r | |
205 | Converts a multicast IP address to a multicast HW MAC address.\r | |
206 | \r | |
207 | @param This Protocol instance pointer.\r | |
208 | @param Ipv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set\r | |
209 | to FALSE if the multicast IP address is IPv4 [RFC 791].\r | |
210 | @param Ip The multicast IP address that is to be converted to a multicast\r | |
211 | HW MAC address.\r | |
212 | @param Mac The multicast HW MAC address that is to be generated from IP.\r | |
213 | \r | |
214 | @retval EFI_SUCCESS The multicast IP address was mapped to the multicast\r | |
215 | HW MAC address.\r | |
216 | @retval EFI_NOT_STARTED The network interface has not been started.\r | |
217 | @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r | |
218 | size needed to hold the statistics is returned in\r | |
219 | StatisticsSize.\r | |
220 | @retval EFI_UNSUPPORTED Not supported yet.\r | |
221 | \r | |
222 | **/\r | |
223 | EFI_STATUS\r | |
224 | EFIAPI\r | |
225 | UnixSnpMcastIptoMac(\r | |
2ac288f9 | 226 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
227 | IN BOOLEAN Ipv6,\r | |
228 | IN EFI_IP_ADDRESS* Ip,\r | |
229 | OUT EFI_MAC_ADDRESS* Mac\r | |
230 | );\r | |
2ff79f2e | 231 | \r |
232 | /**\r | |
233 | Performs read and write operations on the NVRAM device attached to a \r | |
234 | network interface.\r | |
235 | \r | |
236 | @param This Protocol instance pointer.\r | |
237 | @param ReadOrWrite TRUE for read operations, FALSE for write operations.\r | |
238 | @param Offset Byte offset in the NVRAM device at which to start the read or\r | |
239 | write operation. This must be a multiple of NvRamAccessSize and\r | |
240 | less than NvRamSize.\r | |
241 | @param BufferSize The number of bytes to read or write from the NVRAM device.\r | |
242 | This must also be a multiple of NvramAccessSize.\r | |
243 | @param Buffer A pointer to the data buffer.\r | |
244 | \r | |
245 | @retval EFI_UNSUPPORTED Not supported yet.\r | |
246 | \r | |
247 | **/\r | |
248 | EFI_STATUS\r | |
249 | EFIAPI\r | |
250 | UnixSnpNvdata(\r | |
2ac288f9 | 251 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
252 | IN BOOLEAN ReadOrWrite,\r | |
253 | IN UINTN Offset,\r | |
254 | IN UINTN BufferSize,\r | |
255 | IN OUT VOID* Buffer\r | |
256 | );\r | |
2ff79f2e | 257 | \r |
258 | /**\r | |
259 | Reads the current interrupt status and recycled transmit buffer status from \r | |
260 | a network interface.\r | |
261 | \r | |
262 | @param This Protocol instance pointer.\r | |
263 | @param InterruptStatus A pointer to the bit mask of the currently active interrupts\r | |
264 | If this is NULL, the interrupt status will not be read from\r | |
265 | the device. If this is not NULL, the interrupt status will\r | |
266 | be read from the device. When the interrupt status is read,\r | |
267 | it will also be cleared. Clearing the transmit interrupt\r | |
268 | does not empty the recycled transmit buffer array.\r | |
269 | @param TxBuffer Recycled transmit buffer address. The network interface will\r | |
270 | not transmit if its internal recycled transmit buffer array\r | |
271 | is full. Reading the transmit buffer does not clear the\r | |
272 | transmit interrupt. If this is NULL, then the transmit buffer\r | |
273 | status will not be read. If there are no transmit buffers to\r | |
274 | recycle and TxBuf is not NULL, * TxBuf will be set to NULL.\r | |
275 | \r | |
276 | @retval EFI_SUCCESS Always succeeds.\r | |
277 | \r | |
278 | **/\r | |
279 | EFI_STATUS\r | |
280 | EFIAPI\r | |
281 | UnixSnpGetStatus(\r | |
2ac288f9 | 282 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
283 | OUT UINT32* InterruptStatus,\r | |
284 | OUT VOID** TxBuffer\r | |
285 | );\r | |
2ff79f2e | 286 | \r |
287 | /**\r | |
288 | Places a packet in the transmit queue of a network interface.\r | |
289 | \r | |
290 | @param This Protocol instance pointer.\r | |
291 | @param HeaderSize The size, in bytes, of the media header to be filled in by\r | |
292 | the Transmit() function. If HeaderSize is non-zero, then it\r | |
293 | must be equal to This->Mode->MediaHeaderSize and the DestAddr\r | |
294 | and Protocol parameters must not be NULL.\r | |
295 | @param BufferSize The size, in bytes, of the entire packet (media header and\r | |
296 | data) to be transmitted through the network interface.\r | |
297 | @param Buffer A pointer to the packet (media header followed by data) to be\r | |
298 | transmitted. This parameter cannot be NULL. If HeaderSize is zero,\r | |
299 | then the media header in Buffer must already be filled in by the\r | |
300 | caller. If HeaderSize is non-zero, then the media header will be\r | |
301 | filled in by the Transmit() function.\r | |
302 | @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter\r | |
303 | is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then\r | |
304 | This->Mode->CurrentAddress is used for the source HW MAC address.\r | |
305 | @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this\r | |
306 | parameter is ignored.\r | |
307 | @param Protocol The type of header to build. If HeaderSize is zero, then this\r | |
308 | parameter is ignored. See RFC 1700, section "Ether Types", for\r | |
309 | examples.\r | |
310 | \r | |
311 | @retval EFI_SUCCESS The packet was placed on the transmit queue.\r | |
312 | @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r | |
313 | @retval EFI_ACCESS_DENIED Error acquire global lock for operation.\r | |
314 | \r | |
315 | **/\r | |
316 | EFI_STATUS\r | |
317 | EFIAPI\r | |
318 | UnixSnpTransmit(\r | |
2ac288f9 | 319 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
320 | IN UINTN HeaderSize,\r | |
321 | IN UINTN BufferSize,\r | |
322 | IN VOID* Buffer,\r | |
323 | IN EFI_MAC_ADDRESS* SrcAddr OPTIONAL,\r | |
324 | IN EFI_MAC_ADDRESS* DestAddr OPTIONAL,\r | |
325 | IN UINT16* Protocol OPTIONAL\r | |
326 | );\r | |
2ff79f2e | 327 | \r |
328 | /**\r | |
329 | Receives a packet from a network interface.\r | |
330 | \r | |
331 | @param This Protocol instance pointer.\r | |
332 | @param HeaderSize The size, in bytes, of the media header received on the network\r | |
333 | interface. If this parameter is NULL, then the media header size\r | |
334 | will not be returned.\r | |
335 | @param BuffSize On entry, the size, in bytes, of Buffer. On exit, the size, in\r | |
336 | bytes, of the packet that was received on the network interface.\r | |
337 | @param Buffer A pointer to the data buffer to receive both the media header and\r | |
338 | the data.\r | |
339 | @param SourceAddr The source HW MAC address. If this parameter is NULL, the\r | |
340 | HW MAC source address will not be extracted from the media\r | |
341 | header.\r | |
342 | @param DestinationAddr The destination HW MAC address. If this parameter is NULL,\r | |
343 | the HW MAC destination address will not be extracted from the\r | |
344 | media header.\r | |
345 | @param Protocol The media header type. If this parameter is NULL, then the\r | |
346 | protocol will not be extracted from the media header. See\r | |
347 | RFC 1700 section "Ether Types" for examples.\r | |
348 | \r | |
349 | @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has\r | |
350 | been updated to the number of bytes received.\r | |
351 | @retval EFI_NOT_READY The network interface is too busy to accept this transmit\r | |
352 | request.\r | |
353 | @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r | |
354 | @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r | |
355 | @retval EFI_ACCESS_DENIED Error acquire global lock for operation.\r | |
356 | \r | |
357 | **/\r | |
358 | EFI_STATUS\r | |
359 | EFIAPI\r | |
360 | UnixSnpReceive(\r | |
2ac288f9 | 361 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
362 | OUT UINTN* HeaderSize OPTIONAL,\r | |
363 | IN OUT UINTN* BuffSize,\r | |
364 | OUT VOID* Buffer,\r | |
365 | OUT EFI_MAC_ADDRESS* SourceAddr OPTIONAL,\r | |
366 | OUT EFI_MAC_ADDRESS* DestinationAddr OPTIONAL,\r | |
367 | OUT UINT16* Protocol OPTIONAL\r | |
368 | );\r | |
2ff79f2e | 369 | \r |
370 | VOID\r | |
371 | EFIAPI\r | |
372 | UnixSnpWaitForPacketNotify(\r | |
2ac288f9 | 373 | IN EFI_EVENT Event,\r |
374 | IN VOID* Private\r | |
375 | );\r | |
2ff79f2e | 376 | \r |
377 | //\r | |
378 | // Strange, but there doesn't appear to be any structure for the Ethernet header in edk2...\r | |
379 | //\r | |
380 | \r | |
381 | typedef struct\r | |
382 | {\r | |
2ac288f9 | 383 | UINT8 DstAddr[ NET_ETHER_ADDR_LEN ];\r |
384 | UINT8 SrcAddr[ NET_ETHER_ADDR_LEN ];\r | |
385 | UINT16 Type;\r | |
2ff79f2e | 386 | } EthernetHeader;\r |
387 | \r | |
388 | UNIX_SNP_PRIVATE_DATA gUnixSnpPrivateTemplate =\r | |
389 | {\r | |
2ac288f9 | 390 | UNIX_SNP_PRIVATE_DATA_SIGNATURE, // Signature\r |
391 | NULL, // UnixThunk\r | |
392 | NULL, // DeviceHandle\r | |
393 | NULL, // DevicePath\r | |
394 | { 0 }, // MacAddress\r | |
395 | NULL, // InterfaceName\r | |
396 | 0, // ReadBufferSize\r | |
397 | NULL, // ReadBuffer\r | |
398 | NULL, // CurrentReadPointer\r | |
399 | NULL, // EndReadPointer\r | |
400 | 0, // BpfFd\r | |
401 | { // Snp\r | |
402 | EFI_SIMPLE_NETWORK_PROTOCOL_REVISION, // Revision\r | |
403 | UnixSnpStart, // Start\r | |
404 | UnixSnpStop, // Stop\r | |
405 | UnixSnpInitialize, // Initialize\r | |
406 | UnixSnpReset, // Reset\r | |
407 | UnixSnpShutdown, // Shutdown\r | |
408 | UnixSnpReceiveFilters, // ReceiveFilters\r | |
409 | UnixSnpStationAddress, // StationAddress\r | |
410 | UnixSnpStatistics, // Statistics\r | |
411 | UnixSnpMcastIptoMac, // MCastIpToMac\r | |
412 | UnixSnpNvdata, // NvData\r | |
413 | UnixSnpGetStatus, // GetStatus\r | |
414 | UnixSnpTransmit, // Transmit\r | |
415 | UnixSnpReceive, // Receive\r | |
416 | NULL, // WaitForPacket\r | |
417 | NULL // Mode\r | |
418 | },\r | |
419 | { // Mode\r | |
420 | EfiSimpleNetworkStopped, // State\r | |
421 | NET_ETHER_ADDR_LEN, // HwAddressSize\r | |
422 | NET_ETHER_HEADER_SIZE, // MediaHeaderSize\r | |
423 | 1500, // MaxPacketSize\r | |
424 | 0, // NvRamSize\r | |
425 | 0, // NvRamAccessSize\r | |
426 | 0, // ReceiveFilterMask\r | |
427 | 0, // ReceiveFilterSetting\r | |
428 | MAX_MCAST_FILTER_CNT, // MaxMCastFilterCount\r | |
429 | 0, // MCastFilterCount\r | |
430 | {\r | |
431 | 0\r | |
432 | }, // MCastFilter\r | |
433 | {\r | |
434 | 0\r | |
435 | }, // CurrentAddress\r | |
436 | {\r | |
437 | 0\r | |
438 | }, // BroadcastAddress\r | |
439 | {\r | |
440 | 0\r | |
441 | }, // PermanentAddress\r | |
442 | NET_IFTYPE_ETHERNET, // IfType\r | |
443 | FALSE, // MacAddressChangeable\r | |
444 | FALSE, // MultipleTxSupported\r | |
445 | FALSE, // MediaPresentSupported\r | |
446 | TRUE // MediaPresent\r | |
447 | }\r | |
2ff79f2e | 448 | };\r |
449 | \r | |
450 | STATIC EFI_STATUS\r | |
451 | GetInterfaceMacAddr(\r | |
2ac288f9 | 452 | IN UNIX_SNP_PRIVATE_DATA* Private,\r |
453 | IN EFI_UNIX_IO_PROTOCOL* UnixIo\r | |
454 | )\r | |
2ff79f2e | 455 | {\r |
2ac288f9 | 456 | struct ifaddrs* IfAddrs;\r |
457 | struct ifaddrs* If;\r | |
458 | struct sockaddr_dl* IfSdl;\r | |
459 | EFI_STATUS Status;\r | |
460 | INTN Result;\r | |
461 | \r | |
462 | Result = UnixIo->UnixThunk->GetIfAddrs( &IfAddrs );\r | |
463 | if ( Result != 0 )\r | |
464 | {\r | |
465 | return( EFI_UNSUPPORTED );\r | |
466 | }\r | |
467 | \r | |
468 | //\r | |
469 | // Convert the interface name to ASCII so we can find it.\r | |
470 | //\r | |
471 | Private->InterfaceName = AllocateZeroPool( StrLen( UnixIo->EnvString ) );\r | |
472 | \r | |
473 | if ( !Private->InterfaceName )\r | |
474 | {\r | |
475 | Status = EFI_OUT_OF_RESOURCES;\r | |
476 | goto Exit;\r | |
477 | }\r | |
478 | \r | |
479 | UnicodeStrToAsciiStr( UnixIo->EnvString, Private->InterfaceName );\r | |
480 | \r | |
481 | If = IfAddrs;\r | |
482 | \r | |
483 | while ( If != NULL )\r | |
484 | {\r | |
485 | IfSdl = ( struct sockaddr_dl * ) If->ifa_addr;\r | |
486 | \r | |
487 | if ( IfSdl->sdl_family == AF_LINK )\r | |
488 | {\r | |
489 | if ( !AsciiStrCmp( Private->InterfaceName, If->ifa_name ) )\r | |
490 | {\r | |
491 | CopyMem( &Private->MacAddress, LLADDR( IfSdl ), NET_ETHER_ADDR_LEN );\r | |
492 | \r | |
493 | Status = EFI_SUCCESS;\r | |
494 | break;\r | |
495 | }\r | |
496 | }\r | |
497 | \r | |
498 | If = If->ifa_next;\r | |
499 | }\r | |
2ff79f2e | 500 | \r |
501 | Exit:\r | |
2ac288f9 | 502 | ( VOID ) UnixIo->UnixThunk->FreeIfAddrs( IfAddrs );\r |
2ff79f2e | 503 | \r |
2ac288f9 | 504 | return( Status );\r |
2ff79f2e | 505 | }\r |
506 | \r | |
507 | \r | |
508 | STATIC EFI_STATUS\r | |
509 | OpenBpfFileDescriptor(\r | |
2ac288f9 | 510 | IN UNIX_SNP_PRIVATE_DATA* Private,\r |
511 | OUT INTN* Fd\r | |
512 | )\r | |
2ff79f2e | 513 | {\r |
2ac288f9 | 514 | CHAR8 BfpDeviceName[ 256 ];\r |
515 | INTN Index;\r | |
516 | EFI_STATUS Status = EFI_OUT_OF_RESOURCES;\r | |
517 | INTN Result;\r | |
518 | \r | |
519 | //\r | |
520 | // Open a Berkeley Packet Filter device. This must be done as root, so this is probably\r | |
521 | // the place which is most likely to fail...\r | |
522 | //\r | |
523 | for ( Index = 0; TRUE; Index++ )\r | |
524 | {\r | |
525 | AsciiSPrint( BfpDeviceName, sizeof( BfpDeviceName ), "/dev/bpf%d", Index );\r | |
526 | \r | |
527 | *Fd = Private->UnixThunk->Open( BfpDeviceName, O_RDWR, 0 );\r | |
528 | \r | |
529 | if ( *Fd >= 0 )\r | |
530 | {\r | |
531 | Status = EFI_SUCCESS;\r | |
532 | break;\r | |
533 | }\r | |
534 | \r | |
535 | Result = Private->UnixThunk->GetErrno();\r | |
2ff79f2e | 536 | if ( Result == EACCES )\r |
537 | {\r | |
538 | DEBUG( ( EFI_D_ERROR, "Permissions on '%a' are incorrect. Fix with 'sudo chmod 666 %a'.\n",\r | |
539 | BfpDeviceName, BfpDeviceName ) );\r | |
540 | }\r | |
2ac288f9 | 541 | if ( Result != EBUSY )\r |
542 | {\r | |
543 | break;\r | |
544 | }\r | |
545 | }\r | |
2ff79f2e | 546 | \r |
2ac288f9 | 547 | return( Status );\r |
2ff79f2e | 548 | }\r |
549 | \r | |
550 | \r | |
551 | /**\r | |
552 | Test to see if this driver supports ControllerHandle. This service\r | |
553 | is called by the EFI boot service ConnectController(). In\r | |
554 | order to make drivers as small as possible, there are a few calling\r | |
555 | restrictions for this service. ConnectController() must\r | |
556 | follow these calling restrictions. If any other agent wishes to call\r | |
557 | Supported() it must also follow these calling restrictions.\r | |
558 | \r | |
559 | @param This Protocol instance pointer.\r | |
560 | @param ControllerHandle Handle of device to test\r | |
561 | @param RemainingDevicePath Optional parameter use to pick a specific child\r | |
562 | device to start.\r | |
563 | \r | |
564 | @retval EFI_SUCCESS This driver supports this device\r | |
565 | @retval EFI_UNSUPPORTED This driver does not support this device\r | |
566 | \r | |
567 | **/\r | |
568 | EFI_STATUS\r | |
569 | EFIAPI\r | |
570 | UnixSnpDriverBindingSupported(\r | |
2ac288f9 | 571 | IN EFI_DRIVER_BINDING_PROTOCOL* This,\r |
572 | IN EFI_HANDLE ControllerHandle,\r | |
573 | IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath OPTIONAL\r | |
574 | )\r | |
2ff79f2e | 575 | {\r |
2ac288f9 | 576 | EFI_STATUS Status;\r |
577 | EFI_UNIX_IO_PROTOCOL* UnixIo;\r | |
578 | \r | |
579 | //\r | |
580 | // Open the I/O abstraction needed to perform the supported test.\r | |
581 | //\r | |
582 | Status = gBS->OpenProtocol(\r | |
583 | ControllerHandle,\r | |
584 | &gEfiUnixIoProtocolGuid,\r | |
585 | ( VOID ** ) &UnixIo,\r | |
586 | This->DriverBindingHandle,\r | |
587 | ControllerHandle,\r | |
588 | EFI_OPEN_PROTOCOL_BY_DRIVER\r | |
589 | );\r | |
590 | \r | |
591 | if ( EFI_ERROR( Status ) )\r | |
592 | {\r | |
593 | return( Status );\r | |
594 | }\r | |
595 | \r | |
596 | //\r | |
597 | // Validate GUID\r | |
598 | //\r | |
599 | Status = EFI_UNSUPPORTED;\r | |
600 | if ( CompareGuid( UnixIo->TypeGuid, &gEfiUnixNetworkGuid ) )\r | |
601 | {\r | |
602 | Status = EFI_SUCCESS;\r | |
603 | }\r | |
604 | \r | |
605 | //\r | |
606 | // Close the I/O abstraction used to perform the supported test.\r | |
607 | //\r | |
608 | gBS->CloseProtocol(\r | |
609 | ControllerHandle,\r | |
610 | &gEfiUnixIoProtocolGuid,\r | |
611 | This->DriverBindingHandle,\r | |
612 | ControllerHandle\r | |
613 | );\r | |
614 | \r | |
615 | return( Status );\r | |
2ff79f2e | 616 | }\r |
617 | \r | |
618 | \r | |
619 | /**\r | |
620 | Start this driver on ControllerHandle. This service is called by the\r | |
621 | EFI boot service ConnectController(). In order to make\r | |
622 | drivers as small as possible, there are a few calling restrictions for\r | |
623 | this service. ConnectController() must follow these\r | |
624 | calling restrictions. If any other agent wishes to call Start() it\r | |
625 | must also follow these calling restrictions.\r | |
626 | \r | |
627 | @param This Protocol instance pointer.\r | |
628 | @param ControllerHandle Handle of device to bind driver to\r | |
629 | @param RemainingDevicePath Optional parameter use to pick a specific child\r | |
630 | device to start.\r | |
631 | \r | |
632 | @retval EFI_SUCCESS Always succeeds.\r | |
633 | \r | |
634 | **/\r | |
635 | EFI_STATUS\r | |
636 | EFIAPI\r | |
637 | UnixSnpDriverBindingStart(\r | |
2ac288f9 | 638 | IN EFI_DRIVER_BINDING_PROTOCOL* This,\r |
639 | IN EFI_HANDLE ControllerHandle,\r | |
640 | IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath OPTIONAL\r | |
641 | )\r | |
2ff79f2e | 642 | {\r |
2ac288f9 | 643 | MAC_ADDR_DEVICE_PATH Node;\r |
644 | EFI_DEVICE_PATH_PROTOCOL* ParentDevicePath = NULL;\r | |
645 | EFI_UNIX_IO_PROTOCOL* UnixIo;\r | |
646 | UNIX_SNP_PRIVATE_DATA* Private = NULL;\r | |
647 | EFI_STATUS Status;\r | |
648 | BOOLEAN CreateDevice;\r | |
649 | \r | |
650 | //\r | |
651 | // Grab the protocols we need.\r | |
652 | //\r | |
653 | Status = gBS->OpenProtocol(\r | |
654 | ControllerHandle,\r | |
655 | &gEfiDevicePathProtocolGuid,\r | |
656 | ( VOID ** ) &ParentDevicePath,\r | |
657 | This->DriverBindingHandle,\r | |
658 | ControllerHandle,\r | |
659 | EFI_OPEN_PROTOCOL_BY_DRIVER\r | |
660 | );\r | |
661 | if ( EFI_ERROR( Status ) )\r | |
662 | {\r | |
663 | goto ErrorExit;\r | |
664 | }\r | |
665 | \r | |
666 | //\r | |
667 | // Open the I/O abstraction needed to perform the supported test.\r | |
668 | //\r | |
669 | Status = gBS->OpenProtocol(\r | |
670 | ControllerHandle,\r | |
671 | &gEfiUnixIoProtocolGuid,\r | |
672 | ( VOID ** ) &UnixIo,\r | |
673 | This->DriverBindingHandle,\r | |
674 | ControllerHandle,\r | |
675 | EFI_OPEN_PROTOCOL_BY_DRIVER\r | |
676 | );\r | |
677 | if ( EFI_ERROR( Status ) )\r | |
678 | {\r | |
679 | goto ErrorExit;\r | |
680 | }\r | |
681 | \r | |
682 | //\r | |
683 | // Validate GUID\r | |
684 | //\r | |
685 | if ( !CompareGuid( UnixIo->TypeGuid, &gEfiUnixNetworkGuid ) )\r | |
686 | {\r | |
687 | Status = EFI_UNSUPPORTED;\r | |
688 | goto ErrorExit;\r | |
689 | }\r | |
690 | \r | |
691 | CreateDevice = TRUE;\r | |
692 | if ( ( RemainingDevicePath != NULL ) && IsDevicePathEnd( RemainingDevicePath ) )\r | |
693 | {\r | |
694 | CreateDevice = FALSE;\r | |
695 | }\r | |
696 | \r | |
697 | if ( CreateDevice )\r | |
698 | {\r | |
699 | //\r | |
700 | // Allocate the private data.\r | |
701 | //\r | |
702 | Private = AllocateCopyPool( sizeof( UNIX_SNP_PRIVATE_DATA ), &gUnixSnpPrivateTemplate );\r | |
703 | if ( Private == NULL )\r | |
704 | {\r | |
705 | Status = EFI_OUT_OF_RESOURCES;\r | |
706 | goto ErrorExit;\r | |
707 | }\r | |
708 | \r | |
709 | Status = GetInterfaceMacAddr( Private, UnixIo );\r | |
710 | if ( EFI_ERROR( Status ) )\r | |
711 | {\r | |
712 | goto ErrorExit;\r | |
713 | }\r | |
714 | \r | |
715 | Private->UnixThunk = UnixIo->UnixThunk;\r | |
716 | \r | |
717 | Private->Snp.Mode = &Private->Mode;\r | |
718 | \r | |
719 | //\r | |
720 | // Set the broadcast address.\r | |
721 | //\r | |
722 | SetMem( &Private->Mode.BroadcastAddress, sizeof( EFI_MAC_ADDRESS ), 0xFF );\r | |
723 | \r | |
724 | CopyMem( &Private->Mode.CurrentAddress, &Private->MacAddress, sizeof( EFI_MAC_ADDRESS ) );\r | |
725 | CopyMem( &Private->Mode.PermanentAddress, &Private->MacAddress, sizeof( EFI_MAC_ADDRESS ) );\r | |
726 | \r | |
727 | //\r | |
728 | // Since the fake SNP is based on a real NIC, to avoid conflict with the host NIC\r | |
729 | // network stack, we use a different MAC address.\r | |
730 | // So just change the last byte of the MAC address for the real NIC.\r | |
731 | //\r | |
732 | Private->Mode.CurrentAddress.Addr[ NET_ETHER_ADDR_LEN - 1 ]++;\r | |
733 | \r | |
734 | //\r | |
735 | // Build the device path by appending the MAC node to the ParentDevicePath\r | |
736 | // from the UnixIo handle.\r | |
737 | //\r | |
738 | ZeroMem( &Node, sizeof( MAC_ADDR_DEVICE_PATH ) );\r | |
739 | \r | |
740 | Node.Header.Type = MESSAGING_DEVICE_PATH;\r | |
741 | Node.Header.SubType = MSG_MAC_ADDR_DP;\r | |
742 | Node.IfType = Private->Mode.IfType;\r | |
743 | \r | |
744 | SetDevicePathNodeLength( ( EFI_DEVICE_PATH_PROTOCOL * ) &Node, sizeof( MAC_ADDR_DEVICE_PATH ) );\r | |
745 | \r | |
746 | CopyMem( &Node.MacAddress, &Private->Mode.CurrentAddress, sizeof( EFI_MAC_ADDRESS ) );\r | |
747 | \r | |
748 | //\r | |
749 | // Build the device path by appending the MAC node to the ParentDevicePath from the UnixIo handle.\r | |
750 | //\r | |
751 | Private->DevicePath = AppendDevicePathNode( ParentDevicePath, ( EFI_DEVICE_PATH_PROTOCOL * ) &Node );\r | |
752 | if ( Private->DevicePath == NULL )\r | |
753 | {\r | |
754 | Status = EFI_OUT_OF_RESOURCES;\r | |
755 | goto ErrorExit;\r | |
756 | }\r | |
757 | \r | |
758 | Status = gBS->InstallMultipleProtocolInterfaces(\r | |
759 | &Private->DeviceHandle,\r | |
760 | &gEfiSimpleNetworkProtocolGuid,\r | |
761 | &Private->Snp,\r | |
762 | &gEfiDevicePathProtocolGuid,\r | |
763 | Private->DevicePath,\r | |
764 | NULL\r | |
765 | );\r | |
766 | if ( EFI_ERROR( Status ) )\r | |
767 | {\r | |
768 | goto ErrorExit;\r | |
769 | }\r | |
770 | \r | |
771 | Status = gBS->OpenProtocol(\r | |
772 | ControllerHandle,\r | |
773 | &gEfiUnixIoProtocolGuid,\r | |
774 | ( VOID ** ) &UnixIo,\r | |
775 | This->DriverBindingHandle,\r | |
776 | Private->DeviceHandle,\r | |
777 | EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r | |
778 | );\r | |
779 | if ( EFI_ERROR( Status ) )\r | |
780 | {\r | |
781 | goto ErrorExit;\r | |
782 | }\r | |
783 | }\r | |
784 | return( Status );\r | |
2ff79f2e | 785 | \r |
786 | ErrorExit:\r | |
2ac288f9 | 787 | if ( Private->InterfaceName != NULL )\r |
788 | {\r | |
789 | FreePool( Private->InterfaceName );\r | |
790 | Private->InterfaceName = NULL;\r | |
791 | }\r | |
792 | if ( Private != NULL )\r | |
793 | {\r | |
794 | FreePool( Private );\r | |
795 | }\r | |
796 | if ( ParentDevicePath != NULL )\r | |
797 | {\r | |
798 | gBS->CloseProtocol(\r | |
799 | ControllerHandle,\r | |
800 | &gEfiDevicePathProtocolGuid,\r | |
801 | This->DriverBindingHandle,\r | |
802 | ControllerHandle\r | |
803 | );\r | |
804 | }\r | |
805 | \r | |
806 | return( Status );\r | |
2ff79f2e | 807 | }\r |
808 | \r | |
809 | /**\r | |
810 | Stop this driver on ControllerHandle. This service is called by the\r | |
811 | EFI boot service DisconnectController(). In order to\r | |
812 | make drivers as small as possible, there are a few calling\r | |
813 | restrictions for this service. DisconnectController()\r | |
814 | must follow these calling restrictions. If any other agent wishes\r | |
815 | to call Stop() it must also follow these calling restrictions.\r | |
816 | \r | |
817 | @param This Protocol instance pointer.\r | |
818 | @param ControllerHandle Handle of device to stop driver on\r | |
819 | @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r | |
820 | children is zero stop the entire bus driver.\r | |
821 | @param ChildHandleBuffer List of Child Handles to Stop.\r | |
822 | \r | |
823 | @retval EFI_SUCCESS Always succeeds.\r | |
824 | \r | |
825 | **/\r | |
826 | EFI_STATUS\r | |
827 | EFIAPI\r | |
828 | UnixSnpDriverBindingStop(\r | |
2ac288f9 | 829 | IN EFI_DRIVER_BINDING_PROTOCOL* This,\r |
830 | IN EFI_HANDLE ControllerHandle,\r | |
831 | IN UINTN NumberOfChildren,\r | |
832 | IN EFI_HANDLE* ChildHandleBuffer\r | |
833 | )\r | |
2ff79f2e | 834 | {\r |
2ac288f9 | 835 | UNIX_SNP_PRIVATE_DATA* Private = NULL;\r |
836 | EFI_SIMPLE_NETWORK_PROTOCOL* Snp;\r | |
837 | EFI_STATUS Status;\r | |
838 | \r | |
839 | //\r | |
840 | // Get our context back.\r | |
841 | //\r | |
842 | Status = gBS->OpenProtocol(\r | |
843 | ControllerHandle,\r | |
844 | &gEfiSimpleNetworkProtocolGuid,\r | |
845 | ( VOID ** ) &Snp,\r | |
846 | This->DriverBindingHandle,\r | |
847 | ControllerHandle,\r | |
848 | EFI_OPEN_PROTOCOL_GET_PROTOCOL\r | |
849 | );\r | |
850 | if ( EFI_ERROR( Status ) )\r | |
851 | {\r | |
852 | return( EFI_UNSUPPORTED );\r | |
853 | }\r | |
854 | \r | |
855 | Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( Snp );\r | |
856 | \r | |
857 | Status = gBS->CloseProtocol(\r | |
858 | ControllerHandle,\r | |
859 | &gEfiUnixIoProtocolGuid,\r | |
860 | This->DriverBindingHandle,\r | |
861 | Private->DeviceHandle\r | |
862 | );\r | |
863 | \r | |
864 | Status = gBS->UninstallMultipleProtocolInterfaces(\r | |
865 | Private->DeviceHandle,\r | |
866 | &gEfiSimpleNetworkProtocolGuid,\r | |
867 | &Private->Snp,\r | |
868 | &gEfiDevicePathProtocolGuid,\r | |
869 | Private->DevicePath,\r | |
870 | NULL\r | |
871 | );\r | |
872 | \r | |
873 | FreePool( Private->InterfaceName );\r | |
874 | FreePool( Private->DevicePath );\r | |
875 | FreePool( Private );\r | |
876 | \r | |
877 | return( EFI_SUCCESS );\r | |
2ff79f2e | 878 | }\r |
879 | \r | |
880 | \r | |
881 | /**\r | |
882 | Changes the state of a network interface from "stopped" to "started".\r | |
883 | \r | |
884 | @param This Protocol instance pointer.\r | |
885 | \r | |
886 | @retval EFI_SUCCESS Always succeeds.\r | |
887 | \r | |
888 | **/\r | |
889 | EFI_STATUS\r | |
890 | EFIAPI\r | |
891 | UnixSnpStart(\r | |
2ac288f9 | 892 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r |
893 | )\r | |
2ff79f2e | 894 | {\r |
2ac288f9 | 895 | STATIC struct bpf_insn FilterInstructionTemplate[] =\r |
896 | {\r | |
897 | // Load 4 bytes from the destination MAC address.\r | |
898 | BPF_STMT( BPF_LD + BPF_W + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 0 ] ) ),\r | |
899 | \r | |
900 | // Compare to first 4 bytes of fake MAC address.\r | |
901 | BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0x12345678, 0, 3 ),\r | |
902 | \r | |
903 | // Load remaining 2 bytes from the destination MAC address.\r | |
904 | BPF_STMT( BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 4 ] ) ),\r | |
905 | \r | |
906 | // Compare to remaining 2 bytes of fake MAC address.\r | |
907 | BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0x9ABC, 5, 0 ),\r | |
908 | \r | |
909 | // Load 4 bytes from the destination MAC address.\r | |
910 | BPF_STMT( BPF_LD + BPF_W + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 0 ] ) ),\r | |
911 | \r | |
912 | // Compare to first 4 bytes of broadcast MAC address.\r | |
913 | BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0xFFFFFFFF, 0, 2 ),\r | |
914 | \r | |
915 | // Load remaining 2 bytes from the destination MAC address.\r | |
916 | BPF_STMT( BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 4 ] ) ),\r | |
917 | \r | |
918 | // Compare to remaining 2 bytes of broadcast MAC address.\r | |
919 | BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0xFFFF, 1, 0 ),\r | |
920 | \r | |
921 | // Reject packet.\r | |
922 | BPF_STMT( BPF_RET + BPF_K, 0 ),\r | |
923 | \r | |
924 | // Receive entire packet.\r | |
925 | BPF_STMT( BPF_RET + BPF_K, -1 )\r | |
926 | };\r | |
927 | struct ifreq BoundIf;\r | |
928 | struct bpf_program BpfProgram;\r | |
929 | struct bpf_insn* FilterProgram;\r | |
930 | UNIX_SNP_PRIVATE_DATA* Private;\r | |
931 | EFI_STATUS Status;\r | |
932 | UINT32 Temp32;\r | |
933 | INTN Fd;\r | |
934 | INTN Result;\r | |
935 | INTN Value;\r | |
936 | UINT16 Temp16;\r | |
937 | \r | |
938 | Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r | |
939 | \r | |
940 | switch ( Private->Snp.Mode->State )\r | |
941 | {\r | |
942 | case EfiSimpleNetworkStopped:\r | |
943 | break;\r | |
944 | \r | |
945 | case EfiSimpleNetworkStarted:\r | |
946 | case EfiSimpleNetworkInitialized:\r | |
947 | return( EFI_ALREADY_STARTED );\r | |
948 | break;\r | |
949 | \r | |
950 | default:\r | |
951 | return( EFI_DEVICE_ERROR );\r | |
952 | break;\r | |
953 | }\r | |
954 | \r | |
955 | if ( Private->BpfFd == 0 )\r | |
956 | {\r | |
957 | Status = OpenBpfFileDescriptor( Private, &Fd );\r | |
958 | \r | |
959 | if ( EFI_ERROR( Status ) )\r | |
960 | {\r | |
961 | goto ErrorExit;\r | |
962 | }\r | |
963 | \r | |
964 | Private->BpfFd = Fd;\r | |
965 | \r | |
966 | //\r | |
967 | // Associate our interface with this BPF file descriptor.\r | |
968 | //\r | |
969 | AsciiStrCpy( BoundIf.ifr_name, Private->InterfaceName );\r | |
970 | Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSETIF, &BoundIf );\r | |
971 | \r | |
972 | if ( Result < 0 )\r | |
973 | {\r | |
974 | goto DeviceErrorExit;\r | |
975 | }\r | |
976 | \r | |
977 | //\r | |
978 | // Enable immediate mode and find out the buffer size.\r | |
979 | //\r | |
980 | Value = 1;\r | |
981 | Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCIMMEDIATE, &Value );\r | |
982 | \r | |
983 | if ( Result < 0 )\r | |
984 | {\r | |
985 | goto DeviceErrorExit;\r | |
986 | }\r | |
987 | \r | |
988 | //\r | |
989 | // Enable non-blocking I/O.\r | |
990 | //\r | |
991 | \r | |
992 | Value = Private->UnixThunk->Fcntl( Private->BpfFd, F_GETFL, 0 );\r | |
993 | \r | |
994 | if ( Value == -1 )\r | |
995 | {\r | |
996 | goto DeviceErrorExit;\r | |
997 | }\r | |
998 | \r | |
999 | Value |= O_NONBLOCK;\r | |
1000 | \r | |
1001 | Result = Private->UnixThunk->Fcntl( Private->BpfFd, F_SETFL, (void *) Value );\r | |
1002 | \r | |
1003 | if ( Result == -1 )\r | |
1004 | {\r | |
1005 | goto DeviceErrorExit;\r | |
1006 | }\r | |
1007 | \r | |
1008 | //\r | |
1009 | // Disable "header complete" flag. This means the supplied source MAC address is\r | |
1010 | // what goes on the wire.\r | |
1011 | //\r | |
1012 | Value = 1;\r | |
1013 | Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSHDRCMPLT, &Value );\r | |
1014 | \r | |
1015 | if ( Result < 0 )\r | |
1016 | {\r | |
1017 | goto DeviceErrorExit;\r | |
1018 | }\r | |
1019 | \r | |
1020 | Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCGBLEN, &Value );\r | |
1021 | \r | |
1022 | if ( Result < 0 )\r | |
1023 | {\r | |
1024 | goto DeviceErrorExit;\r | |
1025 | }\r | |
1026 | \r | |
1027 | //\r | |
1028 | // Allocate read buffer.\r | |
1029 | //\r | |
1030 | Private->ReadBufferSize = Value;\r | |
1031 | Private->ReadBuffer = AllocateZeroPool( Private->ReadBufferSize );\r | |
1032 | if ( Private->ReadBuffer == NULL )\r | |
1033 | {\r | |
1034 | Status = EFI_OUT_OF_RESOURCES;\r | |
1035 | goto ErrorExit;\r | |
1036 | }\r | |
1037 | \r | |
1038 | Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer;\r | |
1039 | \r | |
1040 | //\r | |
1041 | // Install our packet filter: successful reads should only produce broadcast or unitcast\r | |
1042 | // packets directed to our fake MAC address.\r | |
1043 | //\r | |
1044 | FilterProgram = AllocateCopyPool( sizeof( FilterInstructionTemplate ), &FilterInstructionTemplate );\r | |
1045 | if ( FilterProgram == NULL )\r | |
1046 | {\r | |
1047 | goto ErrorExit;\r | |
1048 | }\r | |
1049 | \r | |
1050 | //\r | |
1051 | // Insert out fake MAC address into the filter. The data has to be host endian.\r | |
1052 | //\r | |
1053 | CopyMem( &Temp32, &Private->Mode.CurrentAddress.Addr[ 0 ], sizeof( UINT32 ) );\r | |
1054 | FilterProgram[ 1 ].k = NTOHL( Temp32 );\r | |
1055 | CopyMem( &Temp16, &Private->Mode.CurrentAddress.Addr[ 4 ], sizeof( UINT16 ) );\r | |
1056 | FilterProgram[ 3 ].k = NTOHS( Temp16 );\r | |
1057 | \r | |
1058 | BpfProgram.bf_len = sizeof( FilterInstructionTemplate ) / sizeof( struct bpf_insn );\r | |
1059 | BpfProgram.bf_insns = FilterProgram;\r | |
1060 | \r | |
1061 | Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSETF, &BpfProgram );\r | |
1062 | \r | |
1063 | if ( Result < 0 )\r | |
1064 | {\r | |
1065 | goto DeviceErrorExit;\r | |
1066 | }\r | |
1067 | \r | |
1068 | FreePool( FilterProgram );\r | |
1069 | \r | |
1070 | //\r | |
1071 | // Enable promiscuous mode.\r | |
1072 | //\r | |
1073 | \r | |
1074 | Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCPROMISC, 0 );\r | |
1075 | \r | |
1076 | if ( Result < 0 )\r | |
1077 | {\r | |
1078 | goto DeviceErrorExit;\r | |
1079 | }\r | |
2ff79f2e | 1080 | \r |
1081 | \r | |
2ac288f9 | 1082 | Private->Snp.Mode->State = EfiSimpleNetworkStarted; \r |
1083 | }\r | |
2ff79f2e | 1084 | \r |
2ac288f9 | 1085 | return( Status );\r |
2ff79f2e | 1086 | \r |
1087 | DeviceErrorExit:\r | |
2ac288f9 | 1088 | Status = EFI_DEVICE_ERROR;\r |
2ff79f2e | 1089 | ErrorExit:\r |
2ac288f9 | 1090 | if ( Private->ReadBuffer != NULL )\r |
1091 | {\r | |
1092 | FreePool( Private->ReadBuffer );\r | |
1093 | Private->ReadBuffer = NULL;\r | |
1094 | }\r | |
1095 | return( Status );\r | |
2ff79f2e | 1096 | }\r |
1097 | \r | |
1098 | \r | |
1099 | /**\r | |
1100 | Changes the state of a network interface from "started" to "stopped".\r | |
1101 | \r | |
1102 | @param This Protocol instance pointer.\r | |
1103 | \r | |
1104 | @retval EFI_SUCCESS Always succeeds.\r | |
1105 | \r | |
1106 | **/\r | |
1107 | EFI_STATUS\r | |
1108 | EFIAPI\r | |
1109 | UnixSnpStop(\r | |
2ac288f9 | 1110 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r |
1111 | )\r | |
2ff79f2e | 1112 | {\r |
2ac288f9 | 1113 | UNIX_SNP_PRIVATE_DATA* Private = EFI_SUCCESS;\r |
1114 | EFI_STATUS Status;\r | |
2ff79f2e | 1115 | \r |
2ac288f9 | 1116 | Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r |
2ff79f2e | 1117 | \r |
2ac288f9 | 1118 | switch ( Private->Snp.Mode->State )\r |
1119 | {\r | |
1120 | case EfiSimpleNetworkStarted:\r | |
1121 | break;\r | |
2ff79f2e | 1122 | \r |
2ac288f9 | 1123 | case EfiSimpleNetworkStopped:\r |
1124 | return( EFI_NOT_STARTED );\r | |
1125 | break;\r | |
2ff79f2e | 1126 | \r |
2ac288f9 | 1127 | default:\r |
1128 | return( EFI_DEVICE_ERROR );\r | |
1129 | break;\r | |
1130 | }\r | |
2ff79f2e | 1131 | \r |
2ac288f9 | 1132 | if ( Private->BpfFd != 0 )\r |
1133 | {\r | |
1134 | Private->UnixThunk->Close( Private->BpfFd );\r | |
1135 | Private->BpfFd = 0;\r | |
1136 | }\r | |
2ff79f2e | 1137 | \r |
2ac288f9 | 1138 | if ( Private->ReadBuffer != NULL )\r |
1139 | {\r | |
1140 | FreePool( Private->ReadBuffer );\r | |
1141 | Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer = NULL;\r | |
1142 | }\r | |
2ff79f2e | 1143 | \r |
2ac288f9 | 1144 | Private->Snp.Mode->State = EfiSimpleNetworkStopped;\r |
2ff79f2e | 1145 | \r |
2ac288f9 | 1146 | return( Status );\r |
2ff79f2e | 1147 | }\r |
1148 | \r | |
1149 | \r | |
1150 | /**\r | |
1151 | Resets a network adapter and allocates the transmit and receive buffers \r | |
1152 | required by the network interface; optionally, also requests allocation \r | |
1153 | of additional transmit and receive buffers.\r | |
1154 | \r | |
1155 | @param This Protocol instance pointer.\r | |
1156 | @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space\r | |
1157 | that the driver should allocate for the network interface.\r | |
1158 | Some network interfaces will not be able to use the extra\r | |
1159 | buffer, and the caller will not know if it is actually\r | |
1160 | being used.\r | |
1161 | @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space\r | |
1162 | that the driver should allocate for the network interface.\r | |
1163 | Some network interfaces will not be able to use the extra\r | |
1164 | buffer, and the caller will not know if it is actually\r | |
1165 | being used.\r | |
1166 | \r | |
1167 | @retval EFI_SUCCESS Always succeeds.\r | |
1168 | \r | |
1169 | **/\r | |
1170 | EFI_STATUS\r | |
1171 | EFIAPI\r | |
1172 | UnixSnpInitialize(\r | |
2ac288f9 | 1173 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
1174 | IN UINTN ExtraRxBufferSize OPTIONAL,\r | |
1175 | IN UINTN ExtraTxBufferSize OPTIONAL\r | |
1176 | )\r | |
2ff79f2e | 1177 | {\r |
2ac288f9 | 1178 | UNIX_SNP_PRIVATE_DATA* Private = EFI_SUCCESS;\r |
1179 | EFI_STATUS Status;\r | |
2ff79f2e | 1180 | \r |
2ac288f9 | 1181 | Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r |
2ff79f2e | 1182 | \r |
2ac288f9 | 1183 | switch ( Private->Snp.Mode->State )\r |
1184 | {\r | |
1185 | case EfiSimpleNetworkStarted:\r | |
1186 | break;\r | |
2ff79f2e | 1187 | \r |
2ac288f9 | 1188 | case EfiSimpleNetworkStopped:\r |
1189 | return( EFI_NOT_STARTED );\r | |
1190 | break;\r | |
2ff79f2e | 1191 | \r |
2ac288f9 | 1192 | default:\r |
1193 | return( EFI_DEVICE_ERROR );\r | |
1194 | break;\r | |
1195 | }\r | |
2ff79f2e | 1196 | \r |
1197 | #if 0\r | |
2ac288f9 | 1198 | Status = gBS->CreateEvent(\r |
1199 | EVT_NOTIFY_WAIT,\r | |
1200 | TPL_NOTIFY,\r | |
1201 | UnixSnpWaitForPacketNotify,\r | |
1202 | Private,\r | |
1203 | &Private->Snp.WaitForPacket\r | |
1204 | );\r | |
2ff79f2e | 1205 | #endif\r |
1206 | \r | |
2ac288f9 | 1207 | if ( !EFI_ERROR( Status ) )\r |
1208 | {\r | |
1209 | Private->Mode.MCastFilterCount = 0;\r | |
1210 | Private->Mode.ReceiveFilterSetting = 0;\r | |
1211 | ZeroMem( Private->Mode.MCastFilter, sizeof( Private->Mode.MCastFilter ) );\r | |
2ff79f2e | 1212 | \r |
2ac288f9 | 1213 | Private->Snp.Mode->State = EfiSimpleNetworkInitialized;\r |
1214 | }\r | |
2ff79f2e | 1215 | \r |
2ac288f9 | 1216 | return( Status );\r |
2ff79f2e | 1217 | }\r |
1218 | \r | |
1219 | /**\r | |
1220 | Resets a network adapter and re-initializes it with the parameters that were \r | |
1221 | provided in the previous call to Initialize(). \r | |
1222 | \r | |
1223 | @param This Protocol instance pointer.\r | |
1224 | @param ExtendedVerification Indicates that the driver may perform a more\r | |
1225 | exhaustive verification operation of the device\r | |
1226 | during reset.\r | |
1227 | \r | |
1228 | @retval EFI_SUCCESS Always succeeds.\r | |
1229 | \r | |
1230 | **/\r | |
1231 | EFI_STATUS\r | |
1232 | EFIAPI\r | |
1233 | UnixSnpReset(\r | |
2ac288f9 | 1234 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
1235 | IN BOOLEAN ExtendedVerification\r | |
1236 | )\r | |
2ff79f2e | 1237 | {\r |
2ac288f9 | 1238 | UNIX_SNP_PRIVATE_DATA* Private;\r |
1239 | EFI_STATUS Success = EFI_SUCCESS;\r | |
2ff79f2e | 1240 | \r |
2ac288f9 | 1241 | Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r |
2ff79f2e | 1242 | \r |
2ac288f9 | 1243 | switch ( Private->Snp.Mode->State )\r |
1244 | {\r | |
1245 | case EfiSimpleNetworkInitialized:\r | |
1246 | break;\r | |
2ff79f2e | 1247 | \r |
2ac288f9 | 1248 | case EfiSimpleNetworkStopped:\r |
1249 | return( EFI_NOT_STARTED );\r | |
1250 | break;\r | |
2ff79f2e | 1251 | \r |
2ac288f9 | 1252 | default:\r |
1253 | return( EFI_DEVICE_ERROR );\r | |
1254 | break;\r | |
1255 | }\r | |
2ff79f2e | 1256 | \r |
2ac288f9 | 1257 | return( Success );\r |
2ff79f2e | 1258 | }\r |
1259 | \r | |
1260 | /**\r | |
1261 | Resets a network adapter and leaves it in a state that is safe for \r | |
1262 | another driver to initialize.\r | |
1263 | \r | |
1264 | @param This Protocol instance pointer.\r | |
1265 | \r | |
1266 | @retval EFI_SUCCESS Always succeeds.\r | |
1267 | \r | |
1268 | **/\r | |
1269 | EFI_STATUS\r | |
1270 | EFIAPI\r | |
1271 | UnixSnpShutdown(\r | |
2ac288f9 | 1272 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r |
1273 | )\r | |
2ff79f2e | 1274 | {\r |
2ac288f9 | 1275 | UNIX_SNP_PRIVATE_DATA* Private;\r |
1276 | EFI_STATUS Success = EFI_SUCCESS;\r | |
1277 | \r | |
1278 | Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r | |
1279 | \r | |
1280 | switch ( Private->Snp.Mode->State )\r | |
1281 | {\r | |
1282 | case EfiSimpleNetworkInitialized:\r | |
1283 | break;\r | |
1284 | \r | |
1285 | case EfiSimpleNetworkStopped:\r | |
1286 | return( EFI_NOT_STARTED );\r | |
1287 | break;\r | |
1288 | \r | |
1289 | default:\r | |
1290 | return( EFI_DEVICE_ERROR );\r | |
1291 | break;\r | |
1292 | }\r | |
1293 | \r | |
1294 | Private->Snp.Mode->State = EfiSimpleNetworkStarted;\r | |
1295 | \r | |
1296 | Private->Mode.ReceiveFilterSetting = 0;\r | |
1297 | Private->Mode.MCastFilterCount = 0;\r | |
1298 | ZeroMem( Private->Mode.MCastFilter, sizeof( Private->Mode.MCastFilter ) );\r | |
1299 | \r | |
1300 | if ( Private->Snp.WaitForPacket != NULL )\r | |
1301 | {\r | |
1302 | gBS->CloseEvent( Private->Snp.WaitForPacket );\r | |
1303 | Private->Snp.WaitForPacket = NULL;\r | |
1304 | }\r | |
1305 | \r | |
1306 | if ( Private->BpfFd != 0 )\r | |
1307 | {\r | |
1308 | Private->UnixThunk->Close( Private->BpfFd );\r | |
1309 | Private->BpfFd = 0;\r | |
1310 | }\r | |
1311 | \r | |
1312 | if ( Private->ReadBuffer != NULL )\r | |
1313 | {\r | |
1314 | FreePool( Private->ReadBuffer );\r | |
1315 | Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer = NULL;\r | |
1316 | }\r | |
1317 | \r | |
1318 | return( Success );\r | |
2ff79f2e | 1319 | }\r |
1320 | \r | |
1321 | /**\r | |
1322 | Manages the multicast receive filters of a network interface.\r | |
1323 | \r | |
1324 | @param This Protocol instance pointer.\r | |
1325 | @param EnableBits A bit mask of receive filters to enable on the network interface.\r | |
1326 | @param DisableBits A bit mask of receive filters to disable on the network interface.\r | |
1327 | @param ResetMcastFilter Set to TRUE to reset the contents of the multicast receive\r | |
1328 | filters on the network interface to their default values.\r | |
1329 | @param McastFilterCount Number of multicast HW MAC addresses in the new\r | |
1330 | MCastFilter list. This value must be less than or equal to\r | |
1331 | the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This\r | |
1332 | field is optional if ResetMCastFilter is TRUE.\r | |
1333 | @param McastFilter A pointer to a list of new multicast receive filter HW MAC\r | |
1334 | addresses. This list will replace any existing multicast\r | |
1335 | HW MAC address list. This field is optional if\r | |
1336 | ResetMCastFilter is TRUE.\r | |
1337 | \r | |
1338 | @retval EFI_SUCCESS The multicast receive filter list was updated.\r | |
1339 | @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r | |
1340 | \r | |
1341 | **/\r | |
1342 | EFI_STATUS\r | |
1343 | EFIAPI\r | |
1344 | UnixSnpReceiveFilters(\r | |
2ac288f9 | 1345 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
1346 | IN UINT32 EnableBits,\r | |
1347 | IN UINT32 DisableBits,\r | |
1348 | IN BOOLEAN ResetMcastFilter,\r | |
1349 | IN UINTN McastFilterCount OPTIONAL,\r | |
1350 | IN EFI_MAC_ADDRESS* McastFilter OPTIONAL\r | |
1351 | )\r | |
2ff79f2e | 1352 | {\r |
2ac288f9 | 1353 | UNIX_SNP_PRIVATE_DATA* Private;\r |
2ff79f2e | 1354 | \r |
2ac288f9 | 1355 | Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r |
2ff79f2e | 1356 | \r |
1357 | // ReturnValue = GlobalData->NtNetUtilityTable.SetReceiveFilter (\r | |
1358 | // Instance->InterfaceInfo.InterfaceIndex,\r | |
1359 | // EnableBits,\r | |
1360 | // McastFilterCount,\r | |
1361 | // McastFilter\r | |
1362 | // );\r | |
1363 | \r | |
2ac288f9 | 1364 | // For now, just succeed...\r |
1365 | return( EFI_SUCCESS );\r | |
2ff79f2e | 1366 | }\r |
1367 | \r | |
1368 | /**\r | |
1369 | Modifies or resets the current station address, if supported.\r | |
1370 | \r | |
1371 | @param This Protocol instance pointer.\r | |
1372 | @param Reset Flag used to reset the station address to the network interfaces\r | |
1373 | permanent address.\r | |
1374 | @param NewMacAddr New station address to be used for the network interface.\r | |
1375 | \r | |
1376 | @retval EFI_UNSUPPORTED Not supported yet.\r | |
1377 | \r | |
1378 | **/\r | |
1379 | EFI_STATUS\r | |
1380 | EFIAPI\r | |
1381 | UnixSnpStationAddress(\r | |
2ac288f9 | 1382 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
1383 | IN BOOLEAN Reset,\r | |
1384 | IN EFI_MAC_ADDRESS* NewMacAddr OPTIONAL\r | |
1385 | )\r | |
2ff79f2e | 1386 | {\r |
2ac288f9 | 1387 | return( EFI_UNSUPPORTED );\r |
2ff79f2e | 1388 | }\r |
1389 | \r | |
1390 | /**\r | |
1391 | Resets or collects the statistics on a network interface.\r | |
1392 | \r | |
1393 | @param This Protocol instance pointer.\r | |
1394 | @param Reset Set to TRUE to reset the statistics for the network interface.\r | |
1395 | @param StatisticsSize On input the size, in bytes, of StatisticsTable. On\r | |
1396 | output the size, in bytes, of the resulting table of\r | |
1397 | statistics.\r | |
1398 | @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that\r | |
1399 | contains the statistics.\r | |
1400 | \r | |
1401 | @retval EFI_SUCCESS The statistics were collected from the network interface.\r | |
1402 | @retval EFI_NOT_STARTED The network interface has not been started.\r | |
1403 | @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r | |
1404 | size needed to hold the statistics is returned in\r | |
1405 | StatisticsSize.\r | |
1406 | @retval EFI_UNSUPPORTED Not supported yet.\r | |
1407 | \r | |
1408 | **/\r | |
1409 | EFI_STATUS\r | |
1410 | EFIAPI\r | |
1411 | UnixSnpStatistics(\r | |
2ac288f9 | 1412 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
1413 | IN BOOLEAN Reset,\r | |
1414 | IN OUT UINTN* StatisticsSize OPTIONAL,\r | |
1415 | OUT EFI_NETWORK_STATISTICS* StatisticsTable OPTIONAL\r | |
1416 | )\r | |
2ff79f2e | 1417 | {\r |
2ac288f9 | 1418 | return( EFI_UNSUPPORTED );\r |
2ff79f2e | 1419 | }\r |
1420 | \r | |
1421 | /**\r | |
1422 | Converts a multicast IP address to a multicast HW MAC address.\r | |
1423 | \r | |
1424 | @param This Protocol instance pointer.\r | |
1425 | @param Ipv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set\r | |
1426 | to FALSE if the multicast IP address is IPv4 [RFC 791].\r | |
1427 | @param Ip The multicast IP address that is to be converted to a multicast\r | |
1428 | HW MAC address.\r | |
1429 | @param Mac The multicast HW MAC address that is to be generated from IP.\r | |
1430 | \r | |
1431 | @retval EFI_SUCCESS The multicast IP address was mapped to the multicast\r | |
1432 | HW MAC address.\r | |
1433 | @retval EFI_NOT_STARTED The network interface has not been started.\r | |
1434 | @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r | |
1435 | size needed to hold the statistics is returned in\r | |
1436 | StatisticsSize.\r | |
1437 | @retval EFI_UNSUPPORTED Not supported yet.\r | |
1438 | \r | |
1439 | **/\r | |
1440 | EFI_STATUS\r | |
1441 | EFIAPI\r | |
1442 | UnixSnpMcastIptoMac(\r | |
2ac288f9 | 1443 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
1444 | IN BOOLEAN Ipv6,\r | |
1445 | IN EFI_IP_ADDRESS* Ip,\r | |
1446 | OUT EFI_MAC_ADDRESS* Mac\r | |
1447 | )\r | |
2ff79f2e | 1448 | {\r |
2ac288f9 | 1449 | return( EFI_UNSUPPORTED );\r |
2ff79f2e | 1450 | }\r |
1451 | \r | |
1452 | \r | |
1453 | /**\r | |
1454 | Performs read and write operations on the NVRAM device attached to a \r | |
1455 | network interface.\r | |
1456 | \r | |
1457 | @param This Protocol instance pointer.\r | |
1458 | @param ReadOrWrite TRUE for read operations, FALSE for write operations.\r | |
1459 | @param Offset Byte offset in the NVRAM device at which to start the read or\r | |
1460 | write operation. This must be a multiple of NvRamAccessSize and\r | |
1461 | less than NvRamSize.\r | |
1462 | @param BufferSize The number of bytes to read or write from the NVRAM device.\r | |
1463 | This must also be a multiple of NvramAccessSize.\r | |
1464 | @param Buffer A pointer to the data buffer.\r | |
1465 | \r | |
1466 | @retval EFI_UNSUPPORTED Not supported yet.\r | |
1467 | \r | |
1468 | **/\r | |
1469 | EFI_STATUS\r | |
1470 | EFIAPI\r | |
1471 | UnixSnpNvdata(\r | |
2ac288f9 | 1472 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
1473 | IN BOOLEAN ReadOrWrite,\r | |
1474 | IN UINTN Offset,\r | |
1475 | IN UINTN BufferSize,\r | |
1476 | IN OUT VOID* Buffer\r | |
1477 | )\r | |
2ff79f2e | 1478 | {\r |
2ac288f9 | 1479 | return( EFI_UNSUPPORTED );\r |
2ff79f2e | 1480 | }\r |
1481 | \r | |
1482 | \r | |
1483 | /**\r | |
1484 | Reads the current interrupt status and recycled transmit buffer status from \r | |
1485 | a network interface.\r | |
1486 | \r | |
1487 | @param This Protocol instance pointer.\r | |
1488 | @param InterruptStatus A pointer to the bit mask of the currently active interrupts\r | |
1489 | If this is NULL, the interrupt status will not be read from\r | |
1490 | the device. If this is not NULL, the interrupt status will\r | |
1491 | be read from the device. When the interrupt status is read,\r | |
1492 | it will also be cleared. Clearing the transmit interrupt\r | |
1493 | does not empty the recycled transmit buffer array.\r | |
1494 | @param TxBuffer Recycled transmit buffer address. The network interface will\r | |
1495 | not transmit if its internal recycled transmit buffer array\r | |
1496 | is full. Reading the transmit buffer does not clear the\r | |
1497 | transmit interrupt. If this is NULL, then the transmit buffer\r | |
1498 | status will not be read. If there are no transmit buffers to\r | |
1499 | recycle and TxBuf is not NULL, * TxBuf will be set to NULL.\r | |
1500 | \r | |
1501 | @retval EFI_SUCCESS Always succeeds.\r | |
1502 | \r | |
1503 | **/\r | |
1504 | EFI_STATUS\r | |
1505 | EFIAPI\r | |
1506 | UnixSnpGetStatus(\r | |
2ac288f9 | 1507 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
1508 | OUT UINT32* InterruptStatus,\r | |
1509 | OUT VOID** TxBuffer\r | |
1510 | )\r | |
2ff79f2e | 1511 | {\r |
2ac288f9 | 1512 | if ( TxBuffer != NULL )\r |
1513 | {\r | |
1514 | *( ( UINT8 ** ) TxBuffer ) = ( UINT8 * ) 1;\r | |
1515 | }\r | |
2ff79f2e | 1516 | \r |
2ac288f9 | 1517 | if ( InterruptStatus != NULL )\r |
1518 | {\r | |
1519 | *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;\r | |
1520 | }\r | |
2ff79f2e | 1521 | \r |
2ac288f9 | 1522 | return( EFI_SUCCESS );\r |
2ff79f2e | 1523 | }\r |
1524 | \r | |
1525 | \r | |
1526 | /**\r | |
1527 | Places a packet in the transmit queue of a network interface.\r | |
1528 | \r | |
1529 | @param This Protocol instance pointer.\r | |
1530 | @param HeaderSize The size, in bytes, of the media header to be filled in by\r | |
1531 | the Transmit() function. If HeaderSize is non-zero, then it\r | |
1532 | must be equal to This->Mode->MediaHeaderSize and the DestAddr\r | |
1533 | and Protocol parameters must not be NULL.\r | |
1534 | @param BufferSize The size, in bytes, of the entire packet (media header and\r | |
1535 | data) to be transmitted through the network interface.\r | |
1536 | @param Buffer A pointer to the packet (media header followed by data) to be\r | |
1537 | transmitted. This parameter cannot be NULL. If HeaderSize is zero,\r | |
1538 | then the media header in Buffer must already be filled in by the\r | |
1539 | caller. If HeaderSize is non-zero, then the media header will be\r | |
1540 | filled in by the Transmit() function.\r | |
1541 | @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter\r | |
1542 | is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then\r | |
1543 | This->Mode->CurrentAddress is used for the source HW MAC address.\r | |
1544 | @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this\r | |
1545 | parameter is ignored.\r | |
1546 | @param Protocol The type of header to build. If HeaderSize is zero, then this\r | |
1547 | parameter is ignored. See RFC 1700, section "Ether Types", for\r | |
1548 | examples.\r | |
1549 | \r | |
1550 | @retval EFI_SUCCESS The packet was placed on the transmit queue.\r | |
1551 | @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r | |
1552 | @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r | |
1553 | @retval EFI_NOT_STARTED The network interface has not been started.\r | |
1554 | \r | |
1555 | **/\r | |
1556 | EFI_STATUS\r | |
1557 | EFIAPI\r | |
1558 | UnixSnpTransmit(\r | |
2ac288f9 | 1559 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
1560 | IN UINTN HeaderSize,\r | |
1561 | IN UINTN BufferSize,\r | |
1562 | IN VOID* Buffer,\r | |
1563 | IN EFI_MAC_ADDRESS* SrcAddr OPTIONAL,\r | |
1564 | IN EFI_MAC_ADDRESS* DestAddr OPTIONAL,\r | |
1565 | IN UINT16* Protocol OPTIONAL\r | |
1566 | )\r | |
2ff79f2e | 1567 | {\r |
2ac288f9 | 1568 | UNIX_SNP_PRIVATE_DATA* Private;\r |
1569 | EthernetHeader* EnetHeader;\r | |
1570 | INTN Result;\r | |
1571 | \r | |
1572 | Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r | |
1573 | \r | |
1574 | if ( This->Mode->State < EfiSimpleNetworkStarted )\r | |
1575 | {\r | |
1576 | return( EFI_NOT_STARTED );\r | |
1577 | }\r | |
1578 | \r | |
1579 | if ( HeaderSize != 0 )\r | |
1580 | {\r | |
1581 | if ( ( DestAddr == NULL ) || ( Protocol == NULL ) || ( HeaderSize != This->Mode->MediaHeaderSize ) )\r | |
1582 | {\r | |
1583 | return( EFI_INVALID_PARAMETER );\r | |
1584 | }\r | |
1585 | \r | |
1586 | if ( SrcAddr == NULL )\r | |
1587 | {\r | |
1588 | SrcAddr = &This->Mode->CurrentAddress;\r | |
1589 | }\r | |
1590 | \r | |
1591 | EnetHeader = ( EthernetHeader * ) Buffer;\r | |
1592 | \r | |
1593 | CopyMem( EnetHeader->DstAddr, DestAddr, NET_ETHER_ADDR_LEN );\r | |
1594 | CopyMem( EnetHeader->SrcAddr, SrcAddr, NET_ETHER_ADDR_LEN );\r | |
1595 | \r | |
1596 | EnetHeader->Type = HTONS( *Protocol );\r | |
1597 | }\r | |
1598 | \r | |
1599 | Result = Private->UnixThunk->Write( Private->BpfFd, Buffer, BufferSize );\r | |
1600 | \r | |
1601 | if ( Result < 0 )\r | |
1602 | {\r | |
1603 | return( EFI_DEVICE_ERROR );\r | |
1604 | }\r | |
1605 | else\r | |
1606 | {\r | |
1607 | return( EFI_SUCCESS );\r | |
1608 | }\r | |
2ff79f2e | 1609 | }\r |
1610 | \r | |
1611 | /**\r | |
1612 | Receives a packet from a network interface.\r | |
1613 | \r | |
1614 | @param This Protocol instance pointer.\r | |
1615 | @param HeaderSize The size, in bytes, of the media header received on the network\r | |
1616 | interface. If this parameter is NULL, then the media header size\r | |
1617 | will not be returned.\r | |
1618 | @param BuffSize On entry, the size, in bytes, of Buffer. On exit, the size, in\r | |
1619 | bytes, of the packet that was received on the network interface.\r | |
1620 | @param Buffer A pointer to the data buffer to receive both the media header and\r | |
1621 | the data.\r | |
1622 | @param SourceAddr The source HW MAC address. If this parameter is NULL, the\r | |
1623 | HW MAC source address will not be extracted from the media\r | |
1624 | header.\r | |
1625 | @param DestinationAddr The destination HW MAC address. If this parameter is NULL,\r | |
1626 | the HW MAC destination address will not be extracted from the\r | |
1627 | media header.\r | |
1628 | @param Protocol The media header type. If this parameter is NULL, then the\r | |
1629 | protocol will not be extracted from the media header. See\r | |
1630 | RFC 1700 section "Ether Types" for examples.\r | |
1631 | \r | |
1632 | @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has\r | |
1633 | been updated to the number of bytes received.\r | |
1634 | @retval EFI_NOT_READY The network interface is too busy to accept this transmit\r | |
1635 | request.\r | |
1636 | @retval EFI_NOT_STARTED The network interface has not been started.\r | |
1637 | @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r | |
1638 | @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r | |
1639 | \r | |
1640 | **/\r | |
1641 | EFI_STATUS\r | |
1642 | EFIAPI\r | |
1643 | UnixSnpReceive(\r | |
2ac288f9 | 1644 | IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r |
1645 | OUT UINTN* HeaderSize OPTIONAL,\r | |
1646 | IN OUT UINTN* BuffSize,\r | |
1647 | OUT VOID* Buffer,\r | |
1648 | OUT EFI_MAC_ADDRESS* SourceAddr OPTIONAL,\r | |
1649 | OUT EFI_MAC_ADDRESS* DestinationAddr OPTIONAL,\r | |
1650 | OUT UINT16* Protocol OPTIONAL\r | |
1651 | )\r | |
2ff79f2e | 1652 | {\r |
2ac288f9 | 1653 | UNIX_SNP_PRIVATE_DATA* Private;\r |
1654 | struct bpf_hdr* BpfHeader;\r | |
1655 | EthernetHeader* EnetHeader;\r | |
1656 | EFI_STATUS Status = EFI_SUCCESS;\r | |
1657 | INTN Result;\r | |
1658 | \r | |
1659 | if ( This->Mode->State < EfiSimpleNetworkStarted )\r | |
1660 | {\r | |
1661 | return( EFI_NOT_STARTED );\r | |
1662 | }\r | |
1663 | \r | |
1664 | Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r | |
1665 | \r | |
1666 | //\r | |
1667 | // Do we have any remaining packets from the previous read?\r | |
1668 | //\r | |
1669 | if ( Private->CurrentReadPointer >= Private->EndReadPointer )\r | |
1670 | {\r | |
1671 | Result = Private->UnixThunk->Read( Private->BpfFd, Private->ReadBuffer, Private->ReadBufferSize );\r | |
1672 | \r | |
1673 | if ( Result < 0 )\r | |
1674 | {\r | |
1675 | Result = Private->UnixThunk->GetErrno();\r | |
1676 | \r | |
1677 | //\r | |
1678 | // EAGAIN means that there's no I/O outstanding against this file descriptor.\r | |
1679 | //\r | |
1680 | if ( Result == EAGAIN )\r | |
1681 | {\r | |
1682 | return( EFI_NOT_READY );\r | |
1683 | }\r | |
1684 | else\r | |
1685 | {\r | |
1686 | return( EFI_DEVICE_ERROR );\r | |
1687 | }\r | |
1688 | }\r | |
1689 | \r | |
1690 | if ( Result == 0 )\r | |
1691 | {\r | |
1692 | return( EFI_NOT_READY );\r | |
1693 | }\r | |
1694 | \r | |
1695 | Private->CurrentReadPointer = Private->ReadBuffer;\r | |
1696 | Private->EndReadPointer = Private->CurrentReadPointer + Result;\r | |
1697 | }\r | |
1698 | \r | |
1699 | BpfHeader = Private->CurrentReadPointer;\r | |
1700 | EnetHeader = Private->CurrentReadPointer + BpfHeader->bh_hdrlen;\r | |
1701 | \r | |
1702 | if ( BpfHeader->bh_caplen > *BuffSize )\r | |
1703 | {\r | |
1704 | *BuffSize = BpfHeader->bh_caplen;\r | |
1705 | return( EFI_BUFFER_TOO_SMALL );\r | |
1706 | }\r | |
1707 | \r | |
1708 | CopyMem( Buffer, EnetHeader, BpfHeader->bh_caplen );\r | |
1709 | *BuffSize = BpfHeader->bh_caplen;\r | |
1710 | \r | |
1711 | if ( HeaderSize != NULL )\r | |
1712 | {\r | |
1713 | *HeaderSize = sizeof( EthernetHeader );\r | |
1714 | }\r | |
1715 | \r | |
1716 | if ( DestinationAddr != NULL )\r | |
1717 | {\r | |
1718 | ZeroMem( DestinationAddr, sizeof( EFI_MAC_ADDRESS ) );\r | |
1719 | CopyMem( DestinationAddr, EnetHeader->DstAddr, NET_ETHER_ADDR_LEN );\r | |
1720 | }\r | |
1721 | \r | |
1722 | if ( SourceAddr != NULL )\r | |
1723 | {\r | |
1724 | ZeroMem( SourceAddr, sizeof( EFI_MAC_ADDRESS ) );\r | |
1725 | CopyMem( SourceAddr, EnetHeader->SrcAddr, NET_ETHER_ADDR_LEN );\r | |
1726 | }\r | |
1727 | \r | |
1728 | if ( Protocol != NULL )\r | |
1729 | {\r | |
1730 | *Protocol = NTOHS( EnetHeader->Type );\r | |
1731 | }\r | |
1732 | \r | |
1733 | Private->CurrentReadPointer += BPF_WORDALIGN( BpfHeader->bh_hdrlen + BpfHeader->bh_caplen );\r | |
1734 | \r | |
1735 | return( Status );\r | |
2ff79f2e | 1736 | }\r |
1737 | \r | |
1738 | \r | |
1739 | VOID\r | |
1740 | EFIAPI\r | |
1741 | UnixSnpWaitForPacketNotify(\r | |
2ac288f9 | 1742 | IN EFI_EVENT Event,\r |
1743 | IN VOID* Context\r | |
1744 | )\r | |
2ff79f2e | 1745 | {\r |
2ac288f9 | 1746 | UNIX_SNP_PRIVATE_DATA* Private;\r |
2ff79f2e | 1747 | \r |
2ac288f9 | 1748 | Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( Context );\r |
2ff79f2e | 1749 | \r |
2ac288f9 | 1750 | if ( Private->Snp.Mode->State < EfiSimpleNetworkStarted )\r |
1751 | {\r | |
1752 | return;\r | |
1753 | }\r | |
2ff79f2e | 1754 | }\r |
1755 | \r | |
1756 | \r | |
1757 | /**\r | |
1758 | This is the declaration of an EFI image entry point. This entry point is\r | |
1759 | the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r | |
1760 | both device drivers and bus drivers.\r | |
1761 | \r | |
1762 | @param ImageHandle The firmware allocated handle for the UEFI image.\r | |
1763 | @param SystemTable A pointer to the EFI System Table.\r | |
1764 | \r | |
1765 | @retval EFI_SUCCESS The operation completed successfully.\r | |
1766 | @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r | |
1767 | \r | |
1768 | **/\r | |
1769 | EFI_STATUS\r | |
1770 | InitializeUnixSnpDriver(\r | |
2ac288f9 | 1771 | IN EFI_HANDLE ImageHandle,\r |
1772 | IN EFI_SYSTEM_TABLE* SystemTable\r | |
1773 | )\r | |
2ff79f2e | 1774 | {\r |
2ac288f9 | 1775 | EFI_STATUS Status;\r |
1776 | \r | |
1777 | //\r | |
1778 | // Install the Driver Protocols\r | |
1779 | //\r | |
1780 | \r | |
1781 | Status = EfiLibInstallDriverBindingComponentName2(\r | |
1782 | ImageHandle,\r | |
1783 | SystemTable,\r | |
1784 | &gUnixSnpDriverBinding,\r | |
1785 | ImageHandle,\r | |
1786 | &gUnixSnpDriverComponentName,\r | |
1787 | &gUnixSnpDriverComponentName2\r | |
1788 | );\r | |
1789 | \r | |
1790 | return( Status );\r | |
2ff79f2e | 1791 | }\r |