+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2010, Apple, Inc. All rights reserved.<BR>\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- UnixSnp.c\r
-\r
-Abstract:\r
-\r
--**/\r
-\r
-#include <Library/PrintLib.h>\r
-\r
-#include "UnixSnp.h"\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gUnixSnpDriverBinding =\r
-{\r
- UnixSnpDriverBindingSupported,\r
- UnixSnpDriverBindingStart,\r
- UnixSnpDriverBindingStop,\r
- 0xA,\r
- NULL,\r
- NULL\r
-};\r
-\r
-/**\r
- Changes the state of a network interface from "stopped" to "started".\r
-\r
- @param This Protocol instance pointer.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpStart(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r
- );\r
- \r
-/**\r
- Changes the state of a network interface from "started" to "stopped".\r
-\r
- @param This Protocol instance pointer.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpStop(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r
- );\r
- \r
-/**\r
- Resets a network adapter and allocates the transmit and receive buffers \r
- required by the network interface; optionally, also requests allocation \r
- of additional transmit and receive buffers.\r
-\r
- @param This Protocol instance pointer.\r
- @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space\r
- that the driver should allocate for the network interface.\r
- Some network interfaces will not be able to use the extra\r
- buffer, and the caller will not know if it is actually\r
- being used.\r
- @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space\r
- that the driver should allocate for the network interface.\r
- Some network interfaces will not be able to use the extra\r
- buffer, and the caller will not know if it is actually\r
- being used.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpInitialize(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN UINTN ExtraRxBufferSize OPTIONAL,\r
- IN UINTN ExtraTxBufferSize OPTIONAL\r
- );\r
- \r
-/**\r
- Resets a network adapter and re-initializes it with the parameters that were \r
- provided in the previous call to Initialize(). \r
-\r
- @param This Protocol instance pointer.\r
- @param ExtendedVerification Indicates that the driver may perform a more\r
- exhaustive verification operation of the device\r
- during reset.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpReset(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN BOOLEAN ExtendedVerification\r
- );\r
-\r
-/**\r
- Resets a network adapter and leaves it in a state that is safe for \r
- another driver to initialize.\r
-\r
- @param This Protocol instance pointer.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpShutdown(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r
- );\r
-\r
-/**\r
- Manages the multicast receive filters of a network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param EnableBits A bit mask of receive filters to enable on the network interface.\r
- @param DisableBits A bit mask of receive filters to disable on the network interface.\r
- @param ResetMcastFilter Set to TRUE to reset the contents of the multicast receive\r
- filters on the network interface to their default values.\r
- @param McastFilterCount Number of multicast HW MAC addresses in the new\r
- MCastFilter list. This value must be less than or equal to\r
- the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This\r
- field is optional if ResetMCastFilter is TRUE.\r
- @param McastFilter A pointer to a list of new multicast receive filter HW MAC\r
- addresses. This list will replace any existing multicast\r
- HW MAC address list. This field is optional if\r
- ResetMCastFilter is TRUE.\r
-\r
- @retval EFI_SUCCESS The multicast receive filter list was updated.\r
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpReceiveFilters(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN UINT32 EnableBits,\r
- IN UINT32 DisableBits,\r
- IN BOOLEAN ResetMcastFilter,\r
- IN UINTN McastFilterCount OPTIONAL,\r
- IN EFI_MAC_ADDRESS* McastFilter OPTIONAL\r
- );\r
-\r
-/**\r
- Modifies or resets the current station address, if supported.\r
-\r
- @param This Protocol instance pointer.\r
- @param Reset Flag used to reset the station address to the network interfaces\r
- permanent address.\r
- @param NewMacAddr New station address to be used for the network interface.\r
-\r
- @retval EFI_UNSUPPORTED Not supported yet.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpStationAddress(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN BOOLEAN Reset,\r
- IN EFI_MAC_ADDRESS* NewMacAddr OPTIONAL\r
- );\r
-\r
-/**\r
- Resets or collects the statistics on a network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param Reset Set to TRUE to reset the statistics for the network interface.\r
- @param StatisticsSize On input the size, in bytes, of StatisticsTable. On\r
- output the size, in bytes, of the resulting table of\r
- statistics.\r
- @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that\r
- contains the statistics.\r
-\r
- @retval EFI_SUCCESS The statistics were collected from the network interface.\r
- @retval EFI_NOT_STARTED The network interface has not been started.\r
- @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r
- size needed to hold the statistics is returned in\r
- StatisticsSize.\r
- @retval EFI_UNSUPPORTED Not supported yet.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpStatistics(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN BOOLEAN Reset,\r
- IN OUT UINTN* StatisticsSize OPTIONAL,\r
- OUT EFI_NETWORK_STATISTICS* StatisticsTable OPTIONAL\r
- );\r
- \r
-/**\r
- Converts a multicast IP address to a multicast HW MAC address.\r
- \r
- @param This Protocol instance pointer.\r
- @param Ipv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set\r
- to FALSE if the multicast IP address is IPv4 [RFC 791].\r
- @param Ip The multicast IP address that is to be converted to a multicast\r
- HW MAC address.\r
- @param Mac The multicast HW MAC address that is to be generated from IP.\r
-\r
- @retval EFI_SUCCESS The multicast IP address was mapped to the multicast\r
- HW MAC address.\r
- @retval EFI_NOT_STARTED The network interface has not been started.\r
- @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r
- size needed to hold the statistics is returned in\r
- StatisticsSize.\r
- @retval EFI_UNSUPPORTED Not supported yet.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpMcastIptoMac(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN BOOLEAN Ipv6,\r
- IN EFI_IP_ADDRESS* Ip,\r
- OUT EFI_MAC_ADDRESS* Mac\r
- );\r
-\r
-/**\r
- Performs read and write operations on the NVRAM device attached to a \r
- network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param ReadOrWrite TRUE for read operations, FALSE for write operations.\r
- @param Offset Byte offset in the NVRAM device at which to start the read or\r
- write operation. This must be a multiple of NvRamAccessSize and\r
- less than NvRamSize.\r
- @param BufferSize The number of bytes to read or write from the NVRAM device.\r
- This must also be a multiple of NvramAccessSize.\r
- @param Buffer A pointer to the data buffer.\r
-\r
- @retval EFI_UNSUPPORTED Not supported yet.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpNvdata(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN BOOLEAN ReadOrWrite,\r
- IN UINTN Offset,\r
- IN UINTN BufferSize,\r
- IN OUT VOID* Buffer\r
- );\r
-\r
-/**\r
- Reads the current interrupt status and recycled transmit buffer status from \r
- a network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param InterruptStatus A pointer to the bit mask of the currently active interrupts\r
- If this is NULL, the interrupt status will not be read from\r
- the device. If this is not NULL, the interrupt status will\r
- be read from the device. When the interrupt status is read,\r
- it will also be cleared. Clearing the transmit interrupt\r
- does not empty the recycled transmit buffer array.\r
- @param TxBuffer Recycled transmit buffer address. The network interface will\r
- not transmit if its internal recycled transmit buffer array\r
- is full. Reading the transmit buffer does not clear the\r
- transmit interrupt. If this is NULL, then the transmit buffer\r
- status will not be read. If there are no transmit buffers to\r
- recycle and TxBuf is not NULL, * TxBuf will be set to NULL.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpGetStatus(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- OUT UINT32* InterruptStatus,\r
- OUT VOID** TxBuffer\r
- );\r
-\r
-/**\r
- Places a packet in the transmit queue of a network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param HeaderSize The size, in bytes, of the media header to be filled in by\r
- the Transmit() function. If HeaderSize is non-zero, then it\r
- must be equal to This->Mode->MediaHeaderSize and the DestAddr\r
- and Protocol parameters must not be NULL.\r
- @param BufferSize The size, in bytes, of the entire packet (media header and\r
- data) to be transmitted through the network interface.\r
- @param Buffer A pointer to the packet (media header followed by data) to be\r
- transmitted. This parameter cannot be NULL. If HeaderSize is zero,\r
- then the media header in Buffer must already be filled in by the\r
- caller. If HeaderSize is non-zero, then the media header will be\r
- filled in by the Transmit() function.\r
- @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter\r
- is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then\r
- This->Mode->CurrentAddress is used for the source HW MAC address.\r
- @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this\r
- parameter is ignored.\r
- @param Protocol The type of header to build. If HeaderSize is zero, then this\r
- parameter is ignored. See RFC 1700, section "Ether Types", for\r
- examples.\r
-\r
- @retval EFI_SUCCESS The packet was placed on the transmit queue.\r
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
- @retval EFI_ACCESS_DENIED Error acquire global lock for operation.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpTransmit(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN UINTN HeaderSize,\r
- IN UINTN BufferSize,\r
- IN VOID* Buffer,\r
- IN EFI_MAC_ADDRESS* SrcAddr OPTIONAL,\r
- IN EFI_MAC_ADDRESS* DestAddr OPTIONAL,\r
- IN UINT16* Protocol OPTIONAL\r
- );\r
-\r
-/**\r
- Receives a packet from a network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param HeaderSize The size, in bytes, of the media header received on the network\r
- interface. If this parameter is NULL, then the media header size\r
- will not be returned.\r
- @param BuffSize On entry, the size, in bytes, of Buffer. On exit, the size, in\r
- bytes, of the packet that was received on the network interface.\r
- @param Buffer A pointer to the data buffer to receive both the media header and\r
- the data.\r
- @param SourceAddr The source HW MAC address. If this parameter is NULL, the\r
- HW MAC source address will not be extracted from the media\r
- header.\r
- @param DestinationAddr The destination HW MAC address. If this parameter is NULL,\r
- the HW MAC destination address will not be extracted from the\r
- media header.\r
- @param Protocol The media header type. If this parameter is NULL, then the\r
- protocol will not be extracted from the media header. See\r
- RFC 1700 section "Ether Types" for examples.\r
-\r
- @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has\r
- been updated to the number of bytes received.\r
- @retval EFI_NOT_READY The network interface is too busy to accept this transmit\r
- request.\r
- @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
- @retval EFI_ACCESS_DENIED Error acquire global lock for operation.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpReceive(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- OUT UINTN* HeaderSize OPTIONAL,\r
- IN OUT UINTN* BuffSize,\r
- OUT VOID* Buffer,\r
- OUT EFI_MAC_ADDRESS* SourceAddr OPTIONAL,\r
- OUT EFI_MAC_ADDRESS* DestinationAddr OPTIONAL,\r
- OUT UINT16* Protocol OPTIONAL\r
- );\r
-\r
-VOID\r
-EFIAPI\r
-UnixSnpWaitForPacketNotify(\r
- IN EFI_EVENT Event,\r
- IN VOID* Private\r
- );\r
-\r
-//\r
-// Strange, but there doesn't appear to be any structure for the Ethernet header in edk2...\r
-//\r
-\r
-typedef struct\r
-{\r
- UINT8 DstAddr[ NET_ETHER_ADDR_LEN ];\r
- UINT8 SrcAddr[ NET_ETHER_ADDR_LEN ];\r
- UINT16 Type;\r
-} EthernetHeader;\r
-\r
-UNIX_SNP_PRIVATE_DATA gUnixSnpPrivateTemplate =\r
-{\r
- UNIX_SNP_PRIVATE_DATA_SIGNATURE, // Signature\r
- NULL, // UnixThunk\r
- NULL, // DeviceHandle\r
- NULL, // DevicePath\r
- { 0 }, // MacAddress\r
- NULL, // InterfaceName\r
- 0, // ReadBufferSize\r
- NULL, // ReadBuffer\r
- NULL, // CurrentReadPointer\r
- NULL, // EndReadPointer\r
- 0, // BpfFd\r
- { // Snp\r
- EFI_SIMPLE_NETWORK_PROTOCOL_REVISION, // Revision\r
- UnixSnpStart, // Start\r
- UnixSnpStop, // Stop\r
- UnixSnpInitialize, // Initialize\r
- UnixSnpReset, // Reset\r
- UnixSnpShutdown, // Shutdown\r
- UnixSnpReceiveFilters, // ReceiveFilters\r
- UnixSnpStationAddress, // StationAddress\r
- UnixSnpStatistics, // Statistics\r
- UnixSnpMcastIptoMac, // MCastIpToMac\r
- UnixSnpNvdata, // NvData\r
- UnixSnpGetStatus, // GetStatus\r
- UnixSnpTransmit, // Transmit\r
- UnixSnpReceive, // Receive\r
- NULL, // WaitForPacket\r
- NULL // Mode\r
- },\r
- { // Mode\r
- EfiSimpleNetworkStopped, // State\r
- NET_ETHER_ADDR_LEN, // HwAddressSize\r
- NET_ETHER_HEADER_SIZE, // MediaHeaderSize\r
- 1500, // MaxPacketSize\r
- 0, // NvRamSize\r
- 0, // NvRamAccessSize\r
- 0, // ReceiveFilterMask\r
- 0, // ReceiveFilterSetting\r
- MAX_MCAST_FILTER_CNT, // MaxMCastFilterCount\r
- 0, // MCastFilterCount\r
- {\r
- 0\r
- }, // MCastFilter\r
- {\r
- 0\r
- }, // CurrentAddress\r
- {\r
- 0\r
- }, // BroadcastAddress\r
- {\r
- 0\r
- }, // PermanentAddress\r
- NET_IFTYPE_ETHERNET, // IfType\r
- FALSE, // MacAddressChangeable\r
- FALSE, // MultipleTxSupported\r
- FALSE, // MediaPresentSupported\r
- TRUE // MediaPresent\r
- }\r
-};\r
-\r
-STATIC EFI_STATUS\r
-GetInterfaceMacAddr(\r
- IN UNIX_SNP_PRIVATE_DATA* Private,\r
- IN EFI_UNIX_IO_PROTOCOL* UnixIo\r
- )\r
-{\r
- struct ifaddrs* IfAddrs;\r
- struct ifaddrs* If;\r
- struct sockaddr_dl* IfSdl;\r
- EFI_STATUS Status;\r
- INTN Result;\r
-\r
- Result = UnixIo->UnixThunk->GetIfAddrs( &IfAddrs );\r
- if ( Result != 0 )\r
- {\r
- return( EFI_UNSUPPORTED );\r
- }\r
-\r
- //\r
- // Convert the interface name to ASCII so we can find it.\r
- //\r
- Private->InterfaceName = AllocateZeroPool( StrLen( UnixIo->EnvString ) );\r
-\r
- if ( !Private->InterfaceName )\r
- {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Exit;\r
- }\r
-\r
- UnicodeStrToAsciiStr( UnixIo->EnvString, Private->InterfaceName );\r
-\r
- If = IfAddrs;\r
-\r
- while ( If != NULL )\r
- {\r
- IfSdl = ( struct sockaddr_dl * ) If->ifa_addr;\r
-\r
- if ( IfSdl->sdl_family == AF_LINK )\r
- {\r
- if ( !AsciiStrCmp( Private->InterfaceName, If->ifa_name ) )\r
- {\r
- CopyMem( &Private->MacAddress, LLADDR( IfSdl ), NET_ETHER_ADDR_LEN );\r
-\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
- }\r
-\r
- If = If->ifa_next;\r
- }\r
-\r
-Exit:\r
- ( VOID ) UnixIo->UnixThunk->FreeIfAddrs( IfAddrs );\r
-\r
- return( Status );\r
-}\r
-\r
-\r
-STATIC EFI_STATUS\r
-OpenBpfFileDescriptor(\r
- IN UNIX_SNP_PRIVATE_DATA* Private,\r
- OUT INTN* Fd\r
- )\r
-{\r
- CHAR8 BfpDeviceName[ 256 ];\r
- INTN Index;\r
- EFI_STATUS Status = EFI_OUT_OF_RESOURCES;\r
- INTN Result;\r
-\r
- //\r
- // Open a Berkeley Packet Filter device. This must be done as root, so this is probably\r
- // the place which is most likely to fail...\r
- //\r
- for ( Index = 0; TRUE; Index++ )\r
- {\r
- AsciiSPrint( BfpDeviceName, sizeof( BfpDeviceName ), "/dev/bpf%d", Index );\r
-\r
- *Fd = Private->UnixThunk->Open( BfpDeviceName, O_RDWR, 0 );\r
-\r
- if ( *Fd >= 0 )\r
- {\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
-\r
- Result = Private->UnixThunk->GetErrno();\r
- if ( Result == EACCES )\r
- {\r
- DEBUG( ( EFI_D_ERROR, "Permissions on '%a' are incorrect. Fix with 'sudo chmod 666 %a'.\n",\r
- BfpDeviceName, BfpDeviceName ) );\r
- }\r
- if ( Result != EBUSY )\r
- {\r
- break;\r
- }\r
- }\r
-\r
- return( Status );\r
-}\r
-\r
-\r
-/**\r
- Test to see if this driver supports ControllerHandle. This service\r
- is called by the EFI boot service ConnectController(). In\r
- order to make drivers as small as possible, there are a few calling\r
- restrictions for this service. ConnectController() must\r
- follow these calling restrictions. If any other agent wishes to call\r
- Supported() it must also follow these calling restrictions.\r
-\r
- @param This Protocol instance pointer.\r
- @param ControllerHandle Handle of device to test\r
- @param RemainingDevicePath Optional parameter use to pick a specific child\r
- device to start.\r
-\r
- @retval EFI_SUCCESS This driver supports this device\r
- @retval EFI_UNSUPPORTED This driver does not support this device\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpDriverBindingSupported(\r
- IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_UNIX_IO_PROTOCOL* UnixIo;\r
-\r
- //\r
- // Open the I/O abstraction needed to perform the supported test.\r
- //\r
- Status = gBS->OpenProtocol(\r
- ControllerHandle,\r
- &gEfiUnixIoProtocolGuid,\r
- ( VOID ** ) &UnixIo,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
-\r
- if ( EFI_ERROR( Status ) )\r
- {\r
- return( Status );\r
- }\r
-\r
- //\r
- // Validate GUID\r
- //\r
- Status = EFI_UNSUPPORTED;\r
- if ( CompareGuid( UnixIo->TypeGuid, &gEfiUnixNetworkGuid ) )\r
- {\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Close the I/O abstraction used to perform the supported test.\r
- //\r
- gBS->CloseProtocol(\r
- ControllerHandle,\r
- &gEfiUnixIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
-\r
- return( Status );\r
-}\r
-\r
-\r
-/**\r
- Start this driver on ControllerHandle. This service is called by the\r
- EFI boot service ConnectController(). In order to make\r
- drivers as small as possible, there are a few calling restrictions for\r
- this service. ConnectController() must follow these\r
- calling restrictions. If any other agent wishes to call Start() it\r
- must also follow these calling restrictions.\r
-\r
- @param This Protocol instance pointer.\r
- @param ControllerHandle Handle of device to bind driver to\r
- @param RemainingDevicePath Optional parameter use to pick a specific child\r
- device to start.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpDriverBindingStart(\r
- IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath OPTIONAL\r
- )\r
-{\r
- MAC_ADDR_DEVICE_PATH Node;\r
- EFI_DEVICE_PATH_PROTOCOL* ParentDevicePath = NULL;\r
- EFI_UNIX_IO_PROTOCOL* UnixIo;\r
- UNIX_SNP_PRIVATE_DATA* Private = NULL;\r
- EFI_STATUS Status;\r
- BOOLEAN CreateDevice;\r
-\r
- //\r
- // Grab the protocols we need.\r
- //\r
- Status = gBS->OpenProtocol(\r
- ControllerHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- ( VOID ** ) &ParentDevicePath,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if ( EFI_ERROR( Status ) )\r
- {\r
- goto ErrorExit;\r
- }\r
-\r
- //\r
- // Open the I/O abstraction needed to perform the supported test.\r
- //\r
- Status = gBS->OpenProtocol(\r
- ControllerHandle,\r
- &gEfiUnixIoProtocolGuid,\r
- ( VOID ** ) &UnixIo,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if ( EFI_ERROR( Status ) )\r
- {\r
- goto ErrorExit;\r
- }\r
-\r
- //\r
- // Validate GUID\r
- //\r
- if ( !CompareGuid( UnixIo->TypeGuid, &gEfiUnixNetworkGuid ) )\r
- {\r
- Status = EFI_UNSUPPORTED;\r
- goto ErrorExit;\r
- }\r
-\r
- CreateDevice = TRUE;\r
- if ( ( RemainingDevicePath != NULL ) && IsDevicePathEnd( RemainingDevicePath ) )\r
- {\r
- CreateDevice = FALSE;\r
- }\r
-\r
- if ( CreateDevice )\r
- {\r
- //\r
- // Allocate the private data.\r
- //\r
- Private = AllocateCopyPool( sizeof( UNIX_SNP_PRIVATE_DATA ), &gUnixSnpPrivateTemplate );\r
- if ( Private == NULL )\r
- {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ErrorExit;\r
- }\r
-\r
- Status = GetInterfaceMacAddr( Private, UnixIo );\r
- if ( EFI_ERROR( Status ) )\r
- {\r
- goto ErrorExit;\r
- }\r
-\r
- Private->UnixThunk = UnixIo->UnixThunk;\r
-\r
- Private->Snp.Mode = &Private->Mode;\r
-\r
- //\r
- // Set the broadcast address.\r
- //\r
- SetMem( &Private->Mode.BroadcastAddress, sizeof( EFI_MAC_ADDRESS ), 0xFF );\r
-\r
- CopyMem( &Private->Mode.CurrentAddress, &Private->MacAddress, sizeof( EFI_MAC_ADDRESS ) );\r
- CopyMem( &Private->Mode.PermanentAddress, &Private->MacAddress, sizeof( EFI_MAC_ADDRESS ) );\r
-\r
- //\r
- // Since the fake SNP is based on a real NIC, to avoid conflict with the host NIC\r
- // network stack, we use a different MAC address.\r
- // So just change the last byte of the MAC address for the real NIC.\r
- //\r
- Private->Mode.CurrentAddress.Addr[ NET_ETHER_ADDR_LEN - 1 ]++;\r
-\r
- //\r
- // Build the device path by appending the MAC node to the ParentDevicePath\r
- // from the UnixIo handle.\r
- //\r
- ZeroMem( &Node, sizeof( MAC_ADDR_DEVICE_PATH ) );\r
-\r
- Node.Header.Type = MESSAGING_DEVICE_PATH;\r
- Node.Header.SubType = MSG_MAC_ADDR_DP;\r
- Node.IfType = Private->Mode.IfType;\r
-\r
- SetDevicePathNodeLength( ( EFI_DEVICE_PATH_PROTOCOL * ) &Node, sizeof( MAC_ADDR_DEVICE_PATH ) );\r
-\r
- CopyMem( &Node.MacAddress, &Private->Mode.CurrentAddress, sizeof( EFI_MAC_ADDRESS ) );\r
-\r
- //\r
- // Build the device path by appending the MAC node to the ParentDevicePath from the UnixIo handle.\r
- //\r
- Private->DevicePath = AppendDevicePathNode( ParentDevicePath, ( EFI_DEVICE_PATH_PROTOCOL * ) &Node );\r
- if ( Private->DevicePath == NULL )\r
- {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ErrorExit;\r
- }\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces(\r
- &Private->DeviceHandle,\r
- &gEfiSimpleNetworkProtocolGuid,\r
- &Private->Snp,\r
- &gEfiDevicePathProtocolGuid,\r
- Private->DevicePath,\r
- NULL\r
- );\r
- if ( EFI_ERROR( Status ) )\r
- {\r
- goto ErrorExit;\r
- }\r
-\r
- Status = gBS->OpenProtocol(\r
- ControllerHandle,\r
- &gEfiUnixIoProtocolGuid,\r
- ( VOID ** ) &UnixIo,\r
- This->DriverBindingHandle,\r
- Private->DeviceHandle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- if ( EFI_ERROR( Status ) )\r
- {\r
- goto ErrorExit;\r
- }\r
- }\r
- return( Status );\r
-\r
-ErrorExit:\r
- if ( Private->InterfaceName != NULL )\r
- {\r
- FreePool( Private->InterfaceName );\r
- Private->InterfaceName = NULL;\r
- }\r
- if ( Private != NULL )\r
- {\r
- FreePool( Private );\r
- }\r
- if ( ParentDevicePath != NULL )\r
- {\r
- gBS->CloseProtocol(\r
- ControllerHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
- }\r
-\r
- return( Status );\r
-}\r
-\r
-/**\r
- Stop this driver on ControllerHandle. This service is called by the\r
- EFI boot service DisconnectController(). In order to\r
- make drivers as small as possible, there are a few calling\r
- restrictions for this service. DisconnectController()\r
- must follow these calling restrictions. If any other agent wishes\r
- to call Stop() it must also follow these calling restrictions.\r
- \r
- @param This Protocol instance pointer.\r
- @param ControllerHandle Handle of device to stop driver on\r
- @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
- children is zero stop the entire bus driver.\r
- @param ChildHandleBuffer List of Child Handles to Stop.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpDriverBindingStop(\r
- IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE* ChildHandleBuffer\r
- )\r
-{\r
- UNIX_SNP_PRIVATE_DATA* Private = NULL;\r
- EFI_SIMPLE_NETWORK_PROTOCOL* Snp;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Get our context back.\r
- //\r
- Status = gBS->OpenProtocol(\r
- ControllerHandle,\r
- &gEfiSimpleNetworkProtocolGuid,\r
- ( VOID ** ) &Snp,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if ( EFI_ERROR( Status ) )\r
- {\r
- return( EFI_UNSUPPORTED );\r
- }\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( Snp );\r
-\r
- Status = gBS->CloseProtocol(\r
- ControllerHandle,\r
- &gEfiUnixIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Private->DeviceHandle\r
- );\r
-\r
- Status = gBS->UninstallMultipleProtocolInterfaces(\r
- Private->DeviceHandle,\r
- &gEfiSimpleNetworkProtocolGuid,\r
- &Private->Snp,\r
- &gEfiDevicePathProtocolGuid,\r
- Private->DevicePath,\r
- NULL\r
- );\r
-\r
- FreePool( Private->InterfaceName );\r
- FreePool( Private->DevicePath );\r
- FreePool( Private );\r
-\r
- return( EFI_SUCCESS );\r
-}\r
-\r
-\r
-/**\r
- Changes the state of a network interface from "stopped" to "started".\r
-\r
- @param This Protocol instance pointer.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpStart(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r
- )\r
-{\r
- STATIC struct bpf_insn FilterInstructionTemplate[] =\r
- {\r
- // Load 4 bytes from the destination MAC address.\r
- BPF_STMT( BPF_LD + BPF_W + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 0 ] ) ),\r
-\r
- // Compare to first 4 bytes of fake MAC address.\r
- BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0x12345678, 0, 3 ),\r
-\r
- // Load remaining 2 bytes from the destination MAC address.\r
- BPF_STMT( BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 4 ] ) ),\r
-\r
- // Compare to remaining 2 bytes of fake MAC address.\r
- BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0x9ABC, 5, 0 ),\r
-\r
- // Load 4 bytes from the destination MAC address.\r
- BPF_STMT( BPF_LD + BPF_W + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 0 ] ) ),\r
-\r
- // Compare to first 4 bytes of broadcast MAC address.\r
- BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0xFFFFFFFF, 0, 2 ),\r
-\r
- // Load remaining 2 bytes from the destination MAC address.\r
- BPF_STMT( BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 4 ] ) ),\r
-\r
- // Compare to remaining 2 bytes of broadcast MAC address.\r
- BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0xFFFF, 1, 0 ),\r
-\r
- // Reject packet.\r
- BPF_STMT( BPF_RET + BPF_K, 0 ),\r
-\r
- // Receive entire packet.\r
- BPF_STMT( BPF_RET + BPF_K, -1 )\r
- };\r
- struct ifreq BoundIf;\r
- struct bpf_program BpfProgram;\r
- struct bpf_insn* FilterProgram;\r
- UNIX_SNP_PRIVATE_DATA* Private;\r
- EFI_STATUS Status;\r
- UINT32 Temp32;\r
- INTN Fd;\r
- INTN Result;\r
- INTN Value;\r
- UINT16 Temp16;\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r
-\r
- switch ( Private->Snp.Mode->State )\r
- {\r
- case EfiSimpleNetworkStopped:\r
- break;\r
-\r
- case EfiSimpleNetworkStarted:\r
- case EfiSimpleNetworkInitialized:\r
- return( EFI_ALREADY_STARTED );\r
- break;\r
-\r
- default:\r
- return( EFI_DEVICE_ERROR );\r
- break;\r
- }\r
-\r
- if ( Private->BpfFd == 0 )\r
- {\r
- Status = OpenBpfFileDescriptor( Private, &Fd );\r
-\r
- if ( EFI_ERROR( Status ) )\r
- {\r
- goto ErrorExit;\r
- }\r
-\r
- Private->BpfFd = Fd;\r
-\r
- //\r
- // Associate our interface with this BPF file descriptor.\r
- //\r
- AsciiStrCpy( BoundIf.ifr_name, Private->InterfaceName );\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSETIF, &BoundIf );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- //\r
- // Enable immediate mode and find out the buffer size.\r
- //\r
- Value = 1;\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCIMMEDIATE, &Value );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- //\r
- // Enable non-blocking I/O.\r
- //\r
-\r
- Value = Private->UnixThunk->Fcntl( Private->BpfFd, F_GETFL, 0 );\r
-\r
- if ( Value == -1 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- Value |= O_NONBLOCK;\r
-\r
- Result = Private->UnixThunk->Fcntl( Private->BpfFd, F_SETFL, (void *) Value );\r
-\r
- if ( Result == -1 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- //\r
- // Disable "header complete" flag. This means the supplied source MAC address is\r
- // what goes on the wire.\r
- //\r
- Value = 1;\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSHDRCMPLT, &Value );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCGBLEN, &Value );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- //\r
- // Allocate read buffer.\r
- //\r
- Private->ReadBufferSize = Value;\r
- Private->ReadBuffer = AllocateZeroPool( Private->ReadBufferSize );\r
- if ( Private->ReadBuffer == NULL )\r
- {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ErrorExit;\r
- }\r
-\r
- Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer;\r
-\r
- //\r
- // Install our packet filter: successful reads should only produce broadcast or unitcast\r
- // packets directed to our fake MAC address.\r
- //\r
- FilterProgram = AllocateCopyPool( sizeof( FilterInstructionTemplate ), &FilterInstructionTemplate );\r
- if ( FilterProgram == NULL )\r
- {\r
- goto ErrorExit;\r
- }\r
-\r
- //\r
- // Insert out fake MAC address into the filter. The data has to be host endian.\r
- //\r
- CopyMem( &Temp32, &Private->Mode.CurrentAddress.Addr[ 0 ], sizeof( UINT32 ) );\r
- FilterProgram[ 1 ].k = NTOHL( Temp32 );\r
- CopyMem( &Temp16, &Private->Mode.CurrentAddress.Addr[ 4 ], sizeof( UINT16 ) );\r
- FilterProgram[ 3 ].k = NTOHS( Temp16 );\r
-\r
- BpfProgram.bf_len = sizeof( FilterInstructionTemplate ) / sizeof( struct bpf_insn );\r
- BpfProgram.bf_insns = FilterProgram;\r
-\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSETF, &BpfProgram );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- FreePool( FilterProgram );\r
-\r
- //\r
- // Enable promiscuous mode.\r
- //\r
-\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCPROMISC, 0 );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
-\r
- Private->Snp.Mode->State = EfiSimpleNetworkStarted; \r
- }\r
-\r
- return( Status );\r
-\r
-DeviceErrorExit:\r
- Status = EFI_DEVICE_ERROR;\r
-ErrorExit:\r
- if ( Private->ReadBuffer != NULL )\r
- {\r
- FreePool( Private->ReadBuffer );\r
- Private->ReadBuffer = NULL;\r
- }\r
- return( Status );\r
-}\r
-\r
-\r
-/**\r
- Changes the state of a network interface from "started" to "stopped".\r
-\r
- @param This Protocol instance pointer.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpStop(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r
- )\r
-{\r
- UNIX_SNP_PRIVATE_DATA* Private = EFI_SUCCESS;\r
- EFI_STATUS Status;\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r
-\r
- switch ( Private->Snp.Mode->State )\r
- {\r
- case EfiSimpleNetworkStarted:\r
- break;\r
-\r
- case EfiSimpleNetworkStopped:\r
- return( EFI_NOT_STARTED );\r
- break;\r
-\r
- default:\r
- return( EFI_DEVICE_ERROR );\r
- break;\r
- }\r
-\r
- if ( Private->BpfFd != 0 )\r
- {\r
- Private->UnixThunk->Close( Private->BpfFd );\r
- Private->BpfFd = 0;\r
- }\r
-\r
- if ( Private->ReadBuffer != NULL )\r
- {\r
- FreePool( Private->ReadBuffer );\r
- Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer = NULL;\r
- }\r
-\r
- Private->Snp.Mode->State = EfiSimpleNetworkStopped;\r
-\r
- return( Status );\r
-}\r
-\r
-\r
-/**\r
- Resets a network adapter and allocates the transmit and receive buffers \r
- required by the network interface; optionally, also requests allocation \r
- of additional transmit and receive buffers.\r
-\r
- @param This Protocol instance pointer.\r
- @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space\r
- that the driver should allocate for the network interface.\r
- Some network interfaces will not be able to use the extra\r
- buffer, and the caller will not know if it is actually\r
- being used.\r
- @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space\r
- that the driver should allocate for the network interface.\r
- Some network interfaces will not be able to use the extra\r
- buffer, and the caller will not know if it is actually\r
- being used.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpInitialize(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN UINTN ExtraRxBufferSize OPTIONAL,\r
- IN UINTN ExtraTxBufferSize OPTIONAL\r
- )\r
-{\r
- UNIX_SNP_PRIVATE_DATA* Private = EFI_SUCCESS;\r
- EFI_STATUS Status;\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r
-\r
- switch ( Private->Snp.Mode->State )\r
- {\r
- case EfiSimpleNetworkStarted:\r
- break;\r
-\r
- case EfiSimpleNetworkStopped:\r
- return( EFI_NOT_STARTED );\r
- break;\r
-\r
- default:\r
- return( EFI_DEVICE_ERROR );\r
- break;\r
- }\r
-\r
-#if 0\r
- Status = gBS->CreateEvent(\r
- EVT_NOTIFY_WAIT,\r
- TPL_NOTIFY,\r
- UnixSnpWaitForPacketNotify,\r
- Private,\r
- &Private->Snp.WaitForPacket\r
- );\r
-#endif\r
-\r
- if ( !EFI_ERROR( Status ) )\r
- {\r
- Private->Mode.MCastFilterCount = 0;\r
- Private->Mode.ReceiveFilterSetting = 0;\r
- ZeroMem( Private->Mode.MCastFilter, sizeof( Private->Mode.MCastFilter ) );\r
-\r
- Private->Snp.Mode->State = EfiSimpleNetworkInitialized;\r
- }\r
-\r
- return( Status );\r
-}\r
-\r
-/**\r
- Resets a network adapter and re-initializes it with the parameters that were \r
- provided in the previous call to Initialize(). \r
-\r
- @param This Protocol instance pointer.\r
- @param ExtendedVerification Indicates that the driver may perform a more\r
- exhaustive verification operation of the device\r
- during reset.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpReset(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN BOOLEAN ExtendedVerification\r
- )\r
-{\r
- UNIX_SNP_PRIVATE_DATA* Private;\r
- EFI_STATUS Success = EFI_SUCCESS;\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r
-\r
- switch ( Private->Snp.Mode->State )\r
- {\r
- case EfiSimpleNetworkInitialized:\r
- break;\r
-\r
- case EfiSimpleNetworkStopped:\r
- return( EFI_NOT_STARTED );\r
- break;\r
-\r
- default:\r
- return( EFI_DEVICE_ERROR );\r
- break;\r
- }\r
-\r
- return( Success );\r
-}\r
-\r
-/**\r
- Resets a network adapter and leaves it in a state that is safe for \r
- another driver to initialize.\r
-\r
- @param This Protocol instance pointer.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpShutdown(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This\r
- )\r
-{\r
- UNIX_SNP_PRIVATE_DATA* Private;\r
- EFI_STATUS Success = EFI_SUCCESS;\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r
-\r
- switch ( Private->Snp.Mode->State )\r
- {\r
- case EfiSimpleNetworkInitialized:\r
- break;\r
-\r
- case EfiSimpleNetworkStopped:\r
- return( EFI_NOT_STARTED );\r
- break;\r
-\r
- default:\r
- return( EFI_DEVICE_ERROR );\r
- break;\r
- }\r
-\r
- Private->Snp.Mode->State = EfiSimpleNetworkStarted;\r
-\r
- Private->Mode.ReceiveFilterSetting = 0;\r
- Private->Mode.MCastFilterCount = 0;\r
- ZeroMem( Private->Mode.MCastFilter, sizeof( Private->Mode.MCastFilter ) );\r
-\r
- if ( Private->Snp.WaitForPacket != NULL )\r
- {\r
- gBS->CloseEvent( Private->Snp.WaitForPacket );\r
- Private->Snp.WaitForPacket = NULL;\r
- }\r
-\r
- if ( Private->BpfFd != 0 )\r
- {\r
- Private->UnixThunk->Close( Private->BpfFd );\r
- Private->BpfFd = 0;\r
- }\r
-\r
- if ( Private->ReadBuffer != NULL )\r
- {\r
- FreePool( Private->ReadBuffer );\r
- Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer = NULL;\r
- }\r
-\r
- return( Success );\r
-}\r
-\r
-/**\r
- Manages the multicast receive filters of a network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param EnableBits A bit mask of receive filters to enable on the network interface.\r
- @param DisableBits A bit mask of receive filters to disable on the network interface.\r
- @param ResetMcastFilter Set to TRUE to reset the contents of the multicast receive\r
- filters on the network interface to their default values.\r
- @param McastFilterCount Number of multicast HW MAC addresses in the new\r
- MCastFilter list. This value must be less than or equal to\r
- the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This\r
- field is optional if ResetMCastFilter is TRUE.\r
- @param McastFilter A pointer to a list of new multicast receive filter HW MAC\r
- addresses. This list will replace any existing multicast\r
- HW MAC address list. This field is optional if\r
- ResetMCastFilter is TRUE.\r
-\r
- @retval EFI_SUCCESS The multicast receive filter list was updated.\r
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpReceiveFilters(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN UINT32 EnableBits,\r
- IN UINT32 DisableBits,\r
- IN BOOLEAN ResetMcastFilter,\r
- IN UINTN McastFilterCount OPTIONAL,\r
- IN EFI_MAC_ADDRESS* McastFilter OPTIONAL\r
- )\r
-{\r
- UNIX_SNP_PRIVATE_DATA* Private;\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r
-\r
-// ReturnValue = GlobalData->NtNetUtilityTable.SetReceiveFilter (\r
-// Instance->InterfaceInfo.InterfaceIndex,\r
-// EnableBits,\r
-// McastFilterCount,\r
-// McastFilter\r
-// );\r
-\r
- // For now, just succeed...\r
- return( EFI_SUCCESS );\r
-}\r
-\r
-/**\r
- Modifies or resets the current station address, if supported.\r
-\r
- @param This Protocol instance pointer.\r
- @param Reset Flag used to reset the station address to the network interfaces\r
- permanent address.\r
- @param NewMacAddr New station address to be used for the network interface.\r
-\r
- @retval EFI_UNSUPPORTED Not supported yet.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpStationAddress(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN BOOLEAN Reset,\r
- IN EFI_MAC_ADDRESS* NewMacAddr OPTIONAL\r
- )\r
-{\r
- return( EFI_UNSUPPORTED );\r
-}\r
-\r
-/**\r
- Resets or collects the statistics on a network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param Reset Set to TRUE to reset the statistics for the network interface.\r
- @param StatisticsSize On input the size, in bytes, of StatisticsTable. On\r
- output the size, in bytes, of the resulting table of\r
- statistics.\r
- @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that\r
- contains the statistics.\r
-\r
- @retval EFI_SUCCESS The statistics were collected from the network interface.\r
- @retval EFI_NOT_STARTED The network interface has not been started.\r
- @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r
- size needed to hold the statistics is returned in\r
- StatisticsSize.\r
- @retval EFI_UNSUPPORTED Not supported yet.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpStatistics(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN BOOLEAN Reset,\r
- IN OUT UINTN* StatisticsSize OPTIONAL,\r
- OUT EFI_NETWORK_STATISTICS* StatisticsTable OPTIONAL\r
- )\r
-{\r
- return( EFI_UNSUPPORTED );\r
-}\r
-\r
-/**\r
- Converts a multicast IP address to a multicast HW MAC address.\r
-\r
- @param This Protocol instance pointer.\r
- @param Ipv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set\r
- to FALSE if the multicast IP address is IPv4 [RFC 791].\r
- @param Ip The multicast IP address that is to be converted to a multicast\r
- HW MAC address.\r
- @param Mac The multicast HW MAC address that is to be generated from IP.\r
-\r
- @retval EFI_SUCCESS The multicast IP address was mapped to the multicast\r
- HW MAC address.\r
- @retval EFI_NOT_STARTED The network interface has not been started.\r
- @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r
- size needed to hold the statistics is returned in\r
- StatisticsSize.\r
- @retval EFI_UNSUPPORTED Not supported yet.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpMcastIptoMac(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN BOOLEAN Ipv6,\r
- IN EFI_IP_ADDRESS* Ip,\r
- OUT EFI_MAC_ADDRESS* Mac\r
- )\r
-{\r
- return( EFI_UNSUPPORTED );\r
-}\r
-\r
-\r
-/**\r
- Performs read and write operations on the NVRAM device attached to a \r
- network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param ReadOrWrite TRUE for read operations, FALSE for write operations.\r
- @param Offset Byte offset in the NVRAM device at which to start the read or\r
- write operation. This must be a multiple of NvRamAccessSize and\r
- less than NvRamSize.\r
- @param BufferSize The number of bytes to read or write from the NVRAM device.\r
- This must also be a multiple of NvramAccessSize.\r
- @param Buffer A pointer to the data buffer.\r
-\r
- @retval EFI_UNSUPPORTED Not supported yet.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpNvdata(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN BOOLEAN ReadOrWrite,\r
- IN UINTN Offset,\r
- IN UINTN BufferSize,\r
- IN OUT VOID* Buffer\r
- )\r
-{\r
- return( EFI_UNSUPPORTED );\r
-}\r
-\r
-\r
-/**\r
- Reads the current interrupt status and recycled transmit buffer status from \r
- a network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param InterruptStatus A pointer to the bit mask of the currently active interrupts\r
- If this is NULL, the interrupt status will not be read from\r
- the device. If this is not NULL, the interrupt status will\r
- be read from the device. When the interrupt status is read,\r
- it will also be cleared. Clearing the transmit interrupt\r
- does not empty the recycled transmit buffer array.\r
- @param TxBuffer Recycled transmit buffer address. The network interface will\r
- not transmit if its internal recycled transmit buffer array\r
- is full. Reading the transmit buffer does not clear the\r
- transmit interrupt. If this is NULL, then the transmit buffer\r
- status will not be read. If there are no transmit buffers to\r
- recycle and TxBuf is not NULL, * TxBuf will be set to NULL.\r
-\r
- @retval EFI_SUCCESS Always succeeds.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpGetStatus(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- OUT UINT32* InterruptStatus,\r
- OUT VOID** TxBuffer\r
- )\r
-{\r
- if ( TxBuffer != NULL )\r
- {\r
- *( ( UINT8 ** ) TxBuffer ) = ( UINT8 * ) 1;\r
- }\r
-\r
- if ( InterruptStatus != NULL )\r
- {\r
- *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;\r
- }\r
-\r
- return( EFI_SUCCESS );\r
-}\r
-\r
-\r
-/**\r
- Places a packet in the transmit queue of a network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param HeaderSize The size, in bytes, of the media header to be filled in by\r
- the Transmit() function. If HeaderSize is non-zero, then it\r
- must be equal to This->Mode->MediaHeaderSize and the DestAddr\r
- and Protocol parameters must not be NULL.\r
- @param BufferSize The size, in bytes, of the entire packet (media header and\r
- data) to be transmitted through the network interface.\r
- @param Buffer A pointer to the packet (media header followed by data) to be\r
- transmitted. This parameter cannot be NULL. If HeaderSize is zero,\r
- then the media header in Buffer must already be filled in by the\r
- caller. If HeaderSize is non-zero, then the media header will be\r
- filled in by the Transmit() function.\r
- @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter\r
- is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then\r
- This->Mode->CurrentAddress is used for the source HW MAC address.\r
- @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this\r
- parameter is ignored.\r
- @param Protocol The type of header to build. If HeaderSize is zero, then this\r
- parameter is ignored. See RFC 1700, section "Ether Types", for\r
- examples.\r
-\r
- @retval EFI_SUCCESS The packet was placed on the transmit queue.\r
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
- @retval EFI_NOT_STARTED The network interface has not been started.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpTransmit(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- IN UINTN HeaderSize,\r
- IN UINTN BufferSize,\r
- IN VOID* Buffer,\r
- IN EFI_MAC_ADDRESS* SrcAddr OPTIONAL,\r
- IN EFI_MAC_ADDRESS* DestAddr OPTIONAL,\r
- IN UINT16* Protocol OPTIONAL\r
- )\r
-{\r
- UNIX_SNP_PRIVATE_DATA* Private;\r
- EthernetHeader* EnetHeader;\r
- INTN Result;\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r
-\r
- if ( This->Mode->State < EfiSimpleNetworkStarted )\r
- {\r
- return( EFI_NOT_STARTED );\r
- }\r
-\r
- if ( HeaderSize != 0 )\r
- {\r
- if ( ( DestAddr == NULL ) || ( Protocol == NULL ) || ( HeaderSize != This->Mode->MediaHeaderSize ) )\r
- {\r
- return( EFI_INVALID_PARAMETER );\r
- }\r
-\r
- if ( SrcAddr == NULL )\r
- {\r
- SrcAddr = &This->Mode->CurrentAddress;\r
- }\r
-\r
- EnetHeader = ( EthernetHeader * ) Buffer;\r
-\r
- CopyMem( EnetHeader->DstAddr, DestAddr, NET_ETHER_ADDR_LEN );\r
- CopyMem( EnetHeader->SrcAddr, SrcAddr, NET_ETHER_ADDR_LEN );\r
-\r
- EnetHeader->Type = HTONS( *Protocol );\r
- }\r
-\r
- Result = Private->UnixThunk->Write( Private->BpfFd, Buffer, BufferSize );\r
-\r
- if ( Result < 0 )\r
- {\r
- return( EFI_DEVICE_ERROR );\r
- }\r
- else\r
- {\r
- return( EFI_SUCCESS );\r
- }\r
-}\r
-\r
-/**\r
- Receives a packet from a network interface.\r
-\r
- @param This Protocol instance pointer.\r
- @param HeaderSize The size, in bytes, of the media header received on the network\r
- interface. If this parameter is NULL, then the media header size\r
- will not be returned.\r
- @param BuffSize On entry, the size, in bytes, of Buffer. On exit, the size, in\r
- bytes, of the packet that was received on the network interface.\r
- @param Buffer A pointer to the data buffer to receive both the media header and\r
- the data.\r
- @param SourceAddr The source HW MAC address. If this parameter is NULL, the\r
- HW MAC source address will not be extracted from the media\r
- header.\r
- @param DestinationAddr The destination HW MAC address. If this parameter is NULL,\r
- the HW MAC destination address will not be extracted from the\r
- media header.\r
- @param Protocol The media header type. If this parameter is NULL, then the\r
- protocol will not be extracted from the media header. See\r
- RFC 1700 section "Ether Types" for examples.\r
-\r
- @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has\r
- been updated to the number of bytes received.\r
- @retval EFI_NOT_READY The network interface is too busy to accept this transmit\r
- request.\r
- @retval EFI_NOT_STARTED The network interface has not been started.\r
- @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnixSnpReceive(\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL* This,\r
- OUT UINTN* HeaderSize OPTIONAL,\r
- IN OUT UINTN* BuffSize,\r
- OUT VOID* Buffer,\r
- OUT EFI_MAC_ADDRESS* SourceAddr OPTIONAL,\r
- OUT EFI_MAC_ADDRESS* DestinationAddr OPTIONAL,\r
- OUT UINT16* Protocol OPTIONAL\r
- )\r
-{\r
- UNIX_SNP_PRIVATE_DATA* Private;\r
- struct bpf_hdr* BpfHeader;\r
- EthernetHeader* EnetHeader;\r
- EFI_STATUS Status = EFI_SUCCESS;\r
- INTN Result;\r
-\r
- if ( This->Mode->State < EfiSimpleNetworkStarted )\r
- {\r
- return( EFI_NOT_STARTED );\r
- }\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r
-\r
- //\r
- // Do we have any remaining packets from the previous read?\r
- //\r
- if ( Private->CurrentReadPointer >= Private->EndReadPointer )\r
- {\r
- Result = Private->UnixThunk->Read( Private->BpfFd, Private->ReadBuffer, Private->ReadBufferSize );\r
-\r
- if ( Result < 0 )\r
- {\r
- Result = Private->UnixThunk->GetErrno();\r
-\r
- //\r
- // EAGAIN means that there's no I/O outstanding against this file descriptor.\r
- //\r
- if ( Result == EAGAIN )\r
- {\r
- return( EFI_NOT_READY );\r
- }\r
- else\r
- {\r
- return( EFI_DEVICE_ERROR );\r
- }\r
- }\r
-\r
- if ( Result == 0 )\r
- {\r
- return( EFI_NOT_READY );\r
- }\r
-\r
- Private->CurrentReadPointer = Private->ReadBuffer;\r
- Private->EndReadPointer = Private->CurrentReadPointer + Result;\r
- }\r
-\r
- BpfHeader = Private->CurrentReadPointer;\r
- EnetHeader = Private->CurrentReadPointer + BpfHeader->bh_hdrlen;\r
-\r
- if ( BpfHeader->bh_caplen > *BuffSize )\r
- {\r
- *BuffSize = BpfHeader->bh_caplen;\r
- return( EFI_BUFFER_TOO_SMALL );\r
- }\r
-\r
- CopyMem( Buffer, EnetHeader, BpfHeader->bh_caplen );\r
- *BuffSize = BpfHeader->bh_caplen;\r
-\r
- if ( HeaderSize != NULL )\r
- {\r
- *HeaderSize = sizeof( EthernetHeader );\r
- }\r
-\r
- if ( DestinationAddr != NULL )\r
- {\r
- ZeroMem( DestinationAddr, sizeof( EFI_MAC_ADDRESS ) );\r
- CopyMem( DestinationAddr, EnetHeader->DstAddr, NET_ETHER_ADDR_LEN );\r
- }\r
-\r
- if ( SourceAddr != NULL )\r
- {\r
- ZeroMem( SourceAddr, sizeof( EFI_MAC_ADDRESS ) );\r
- CopyMem( SourceAddr, EnetHeader->SrcAddr, NET_ETHER_ADDR_LEN );\r
- }\r
-\r
- if ( Protocol != NULL )\r
- {\r
- *Protocol = NTOHS( EnetHeader->Type );\r
- }\r
-\r
- Private->CurrentReadPointer += BPF_WORDALIGN( BpfHeader->bh_hdrlen + BpfHeader->bh_caplen );\r
-\r
- return( Status );\r
-}\r
-\r
-\r
-VOID\r
-EFIAPI\r
-UnixSnpWaitForPacketNotify(\r
- IN EFI_EVENT Event,\r
- IN VOID* Context\r
- )\r
-{\r
- UNIX_SNP_PRIVATE_DATA* Private;\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( Context );\r
-\r
- if ( Private->Snp.Mode->State < EfiSimpleNetworkStarted )\r
- {\r
- return;\r
- }\r
-}\r
-\r
-\r
-/**\r
- This is the declaration of an EFI image entry point. This entry point is\r
- the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
- both device drivers and bus drivers.\r
-\r
- @param ImageHandle The firmware allocated handle for the UEFI image.\r
- @param SystemTable A pointer to the EFI System Table.\r
-\r
- @retval EFI_SUCCESS The operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-InitializeUnixSnpDriver(\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE* SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Install the Driver Protocols\r
- //\r
-\r
- Status = EfiLibInstallDriverBindingComponentName2(\r
- ImageHandle,\r
- SystemTable,\r
- &gUnixSnpDriverBinding,\r
- ImageHandle,\r
- &gUnixSnpDriverComponentName,\r
- &gUnixSnpDriverComponentName2\r
- );\r
-\r
- return( Status );\r
-}\r