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