123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134 |
- /**@file
- Windows Packet Filter implementation of the EMU_SNP_PROTOCOL that allows the
- emulator to get on real networks.
- Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>
- Portions copyright (c) 2011, Apple Inc. All rights reserved.
- (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "WinHost.h"
- #define NETWORK_LIBRARY_NAME_U L"SnpNt32Io.dll"
- #define NETWORK_LIBRARY_INITIALIZE "SnpInitialize"
- #define NETWORK_LIBRARY_FINALIZE "SnpFinalize"
- #define NETWORK_LIBRARY_SET_RCV_FILTER "SnpSetReceiveFilter"
- #define NETWORK_LIBRARY_RECEIVE "SnpReceive"
- #define NETWORK_LIBRARY_TRANSMIT "SnpTransmit"
- #pragma pack(1)
- typedef struct _NT_NET_INTERFACE_INFO {
- UINT32 InterfaceIndex;
- EFI_MAC_ADDRESS MacAddr;
- } NT_NET_INTERFACE_INFO;
- #pragma pack()
- #define NET_ETHER_HEADER_SIZE 14
- #define MAX_INTERFACE_INFO_NUMBER 16
- #define SNP_MAX_TX_BUFFER_NUM 65536
- #define SNP_TX_BUFFER_INCREASEMENT 32
- #define DEFAULT_SELECTED_NIC_INDEX 0
- //
- // Functions in Net Library
- //
- typedef
- INT32
- (*NT_NET_INITIALIZE) (
- IN OUT UINT32 *InterfaceCount,
- IN OUT NT_NET_INTERFACE_INFO *InterfaceInfoBuffer
- );
- typedef
- INT32
- (*NT_NET_FINALIZE) (
- VOID
- );
- typedef
- INT32
- (*NT_NET_SET_RECEIVE_FILTER) (
- IN UINT32 Index,
- IN UINT32 EnableFilter,
- IN UINT32 MCastFilterCnt,
- IN EFI_MAC_ADDRESS *MCastFilter
- );
- typedef
- INT32
- (*NT_NET_RECEIVE) (
- IN UINT32 Index,
- IN OUT UINT32 *BufferSize,
- OUT VOID *Buffer
- );
- typedef
- INT32
- (*NT_NET_TRANSMIT) (
- IN UINT32 Index,
- IN UINT32 HeaderSize,
- IN UINT32 BufferSize,
- IN VOID *Buffer,
- IN EFI_MAC_ADDRESS *SrcAddr,
- IN EFI_MAC_ADDRESS *DestAddr,
- IN UINT16 *Protocol
- );
- typedef struct _NT_NET_UTILITY_TABLE {
- NT_NET_INITIALIZE Initialize;
- NT_NET_FINALIZE Finalize;
- NT_NET_SET_RECEIVE_FILTER SetReceiveFilter;
- NT_NET_RECEIVE Receive;
- NT_NET_TRANSMIT Transmit;
- } NT_NET_UTILITY_TABLE;
- //
- // Instance data for each fake SNP instance
- //
- #define WIN_NT_INSTANCE_SIGNATURE SIGNATURE_32 ('N', 'T', 'I', 'S')
- typedef struct {
- UINT32 Signature;
- //
- // Array of the recycled transmit buffer address.
- //
- UINT64 *RecycledTxBuf;
- //
- // Current number of recycled buffer pointers in RecycledTxBuf.
- //
- UINT32 RecycledTxBufCount;
- //
- // The maximum number of recycled buffer pointers in RecycledTxBuf.
- //
- UINT32 MaxRecycledTxBuf;
- EFI_SIMPLE_NETWORK_MODE Mode;
- NT_NET_INTERFACE_INFO InterfaceInfo;
- } WIN_NT_INSTANCE_DATA;
- //
- // Instance data for each SNP private instance
- //
- #define WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE SIGNATURE_32 ('N', 'T', 's', 'n')
- typedef struct {
- UINTN Signature;
- EMU_IO_THUNK_PROTOCOL *Thunk;
- EMU_SNP_PROTOCOL EmuSnp;
- EFI_SIMPLE_NETWORK_MODE *Mode;
- HMODULE NetworkLibraryHandle;
- NT_NET_UTILITY_TABLE NtNetUtilityTable;
- WIN_NT_INSTANCE_DATA Instance;
- } WIN_NT_SNP_PRIVATE;
- #define WIN_NT_SNP_PRIVATE_DATA_FROM_THIS(a) \
- CR(a, WIN_NT_SNP_PRIVATE, EmuSnp, WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE)
- /**
- Register storage for SNP Mode.
- @param This Protocol instance pointer.
- @param Mode SimpleNetworkProtocol Mode structure passed into driver.
- @retval EFI_SUCCESS The network interface was started.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- **/
- EFI_STATUS
- WinNtSnpCreateMapping (
- IN EMU_SNP_PROTOCOL *This,
- IN EFI_SIMPLE_NETWORK_MODE *Mode
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- Private->Mode = Mode;
- //
- // Set the broadcast address.
- //
- CopyMem (&Mode->BroadcastAddress, &Private->Instance.Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS));
- //
- // Set the MAC address.
- //
- CopyMem (&Mode->CurrentAddress, &Private->Instance.Mode.CurrentAddress, sizeof (EFI_MAC_ADDRESS));
- CopyMem (&Mode->PermanentAddress, &Private->Instance.Mode.PermanentAddress, sizeof (EFI_MAC_ADDRESS));
- return EFI_SUCCESS;
- }
- /**
- Changes the state of a network interface from "stopped" to "started".
- @param This Protocol instance pointer.
- @retval EFI_SUCCESS The network interface was started.
- @retval EFI_ALREADY_STARTED The network interface is already in the started state.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpStart (
- IN EMU_SNP_PROTOCOL *This
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- switch (Private->Mode->State) {
- case EfiSimpleNetworkStopped:
- break;
- case EfiSimpleNetworkStarted:
- case EfiSimpleNetworkInitialized:
- return EFI_ALREADY_STARTED;
- break;
- default:
- return EFI_DEVICE_ERROR;
- break;
- }
- Private->Mode->State = EfiSimpleNetworkStarted;
- return EFI_SUCCESS;
- }
- /**
- Changes the state of a network interface from "started" to "stopped".
- @param This Protocol instance pointer.
- @retval EFI_SUCCESS The network interface was stopped.
- @retval EFI_ALREADY_STARTED The network interface is already in the stopped state.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpStop (
- IN EMU_SNP_PROTOCOL *This
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- switch ( Private->Mode->State ) {
- case EfiSimpleNetworkStarted:
- break;
- case EfiSimpleNetworkStopped:
- return EFI_NOT_STARTED;
- break;
- default:
- return EFI_DEVICE_ERROR;
- break;
- }
- Private->Mode->State = EfiSimpleNetworkStopped;
- return EFI_SUCCESS;
- }
- /**
- 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 The 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 The network interface was initialized.
- @retval EFI_NOT_STARTED The network interface has not been started.
- @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and
- receive buffers.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpInitialize (
- IN EMU_SNP_PROTOCOL *This,
- IN UINTN ExtraRxBufferSize OPTIONAL,
- IN UINTN ExtraTxBufferSize OPTIONAL
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- switch ( Private->Mode->State ) {
- case EfiSimpleNetworkStarted:
- break;
- case EfiSimpleNetworkStopped:
- return EFI_NOT_STARTED;
- break;
- default:
- return EFI_DEVICE_ERROR;
- break;
- }
- Private->Mode->MCastFilterCount = 0;
- Private->Mode->ReceiveFilterSetting = 0;
- ZeroMem (Private->Mode->MCastFilter, sizeof (Private->Mode->MCastFilter));
- Private->Mode->State = EfiSimpleNetworkInitialized;
- return EFI_SUCCESS;
- }
- /**
- Resets a network adapter and re-initializes it with the parameters that were
- provided in the previous call to Initialize().
- @param This The protocol instance pointer.
- @param ExtendedVerification Indicates that the driver may perform a more
- exhaustive verification operation of the device
- during reset.
- @retval EFI_SUCCESS The network interface was reset.
- @retval EFI_NOT_STARTED The network interface has not been started.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpReset (
- IN EMU_SNP_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- switch ( Private->Mode->State ) {
- case EfiSimpleNetworkInitialized:
- break;
- case EfiSimpleNetworkStopped:
- return EFI_NOT_STARTED;
- break;
- default:
- return EFI_DEVICE_ERROR;
- break;
- }
- return EFI_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 The network interface was shutdown.
- @retval EFI_NOT_STARTED The network interface has not been started.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpShutdown (
- IN EMU_SNP_PROTOCOL *This
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- switch ( Private->Mode->State ) {
- case EfiSimpleNetworkInitialized:
- break;
- case EfiSimpleNetworkStopped:
- return EFI_NOT_STARTED;
- break;
- default:
- return EFI_DEVICE_ERROR;
- break;
- }
- Private->Mode->State = EfiSimpleNetworkStarted;
- Private->Mode->ReceiveFilterSetting = 0;
- Private->Mode->MCastFilterCount = 0;
- ZeroMem (Private->Mode->MCastFilter, sizeof (Private->Mode->MCastFilter));
- return EFI_SUCCESS;
- }
- /**
- Manages the multicast receive filters of a network interface.
- @param This The protocol instance pointer.
- @param Enable A bit mask of receive filters to enable on the network interface.
- @param Disable 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 McastFilterCnt Number of multicast HW MAC addresses in the new
- MCastFilter list. This value must be less than or equal to
- the MCastFilterCnt field of EMU_SNP_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_NOT_STARTED The network interface has not been started.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpReceiveFilters (
- IN EMU_SNP_PROTOCOL *This,
- IN UINT32 Enable,
- IN UINT32 Disable,
- IN BOOLEAN ResetMCastFilter,
- IN UINTN MCastFilterCnt OPTIONAL,
- IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- INT32 ReturnValue;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- ReturnValue = Private->NtNetUtilityTable.SetReceiveFilter (
- Private->Instance.InterfaceInfo.InterfaceIndex,
- Enable,
- (UINT32)MCastFilterCnt,
- MCastFilter
- );
- if (ReturnValue <= 0) {
- return EFI_DEVICE_ERROR;
- }
- return EFI_SUCCESS;
- }
- /**
- Modifies or resets the current station address, if supported.
- @param This The protocol instance pointer.
- @param Reset Flag used to reset the station address to the network interfaces
- permanent address.
- @param New The new station address to be used for the network interface.
- @retval EFI_SUCCESS The network interfaces station address was updated.
- @retval EFI_NOT_STARTED The network interface has not been started.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpStationAddress (
- IN EMU_SNP_PROTOCOL *This,
- IN BOOLEAN Reset,
- IN EFI_MAC_ADDRESS *New OPTIONAL
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- 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_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpStatistics (
- IN EMU_SNP_PROTOCOL *This,
- IN BOOLEAN Reset,
- IN OUT UINTN *StatisticsSize OPTIONAL,
- OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- return EFI_UNSUPPORTED;
- }
- /**
- Converts a multicast IP address to a multicast HW MAC address.
- @param This The 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_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpMCastIpToMac (
- IN EMU_SNP_PROTOCOL *This,
- IN BOOLEAN IPv6,
- IN EFI_IP_ADDRESS *IP,
- OUT EFI_MAC_ADDRESS *MAC
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- return EFI_UNSUPPORTED;
- }
- /**
- Performs read and write operations on the NVRAM device attached to a
- network interface.
- @param This The protocol instance pointer.
- @param ReadWrite 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_SUCCESS The NVRAM access was performed.
- @retval EFI_NOT_STARTED The network interface has not been started.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpNvData (
- IN EMU_SNP_PROTOCOL *This,
- IN BOOLEAN ReadWrite,
- IN UINTN Offset,
- IN UINTN BufferSize,
- IN OUT VOID *Buffer
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- return EFI_UNSUPPORTED;
- }
- /**
- Reads the current interrupt status and recycled transmit buffer status from
- a network interface.
- @param This The 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 TxBuf 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 The status of the network interface was retrieved.
- @retval EFI_NOT_STARTED The network interface has not been started.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpGetStatus (
- IN EMU_SNP_PROTOCOL *This,
- OUT UINT32 *InterruptStatus OPTIONAL,
- OUT VOID **TxBuf OPTIONAL
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- if (TxBuf != NULL) {
- if (Private->Instance.RecycledTxBufCount != 0) {
- Private->Instance.RecycledTxBufCount--;
- *((UINT8 **)TxBuf) = (UINT8 *)(UINTN)Private->Instance.RecycledTxBuf[Private->Instance.RecycledTxBufCount];
- } else {
- *((UINT8 **)TxBuf) = NULL;
- }
- }
- 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 The 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_NOT_STARTED The network interface has not been started.
- @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_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpTransmit (
- IN EMU_SNP_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
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- INT32 ReturnValue;
- UINT64 *Tmp;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- if ((HeaderSize != 0) && (SrcAddr == NULL)) {
- SrcAddr = &Private->Instance.Mode.CurrentAddress;
- }
- ReturnValue = Private->NtNetUtilityTable.Transmit (
- Private->Instance.InterfaceInfo.InterfaceIndex,
- (UINT32)HeaderSize,
- (UINT32)BufferSize,
- Buffer,
- SrcAddr,
- DestAddr,
- Protocol
- );
- if (ReturnValue < 0) {
- return EFI_DEVICE_ERROR;
- } else {
- if ((Private->Instance.MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT) >= SNP_MAX_TX_BUFFER_NUM) {
- return EFI_NOT_READY;
- }
- if (Private->Instance.RecycledTxBufCount < Private->Instance.MaxRecycledTxBuf) {
- Private->Instance.RecycledTxBuf[Private->Instance.RecycledTxBufCount] = (UINT64)Buffer;
- Private->Instance.RecycledTxBufCount++;
- } else {
- Tmp = malloc (sizeof (UINT64) * (Private->Instance.MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT));
- if (Tmp == NULL) {
- return EFI_DEVICE_ERROR;
- }
- CopyMem (Tmp, Private->Instance.RecycledTxBuf, sizeof (UINT64) * Private->Instance.RecycledTxBufCount);
- free (Private->Instance.RecycledTxBuf);
- Private->Instance.RecycledTxBuf = Tmp;
- Private->Instance.MaxRecycledTxBuf += SNP_TX_BUFFER_INCREASEMENT;
- }
- }
- return EFI_SUCCESS;
- }
- /**
- Receives a packet from a network interface.
- @param This The 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 BufferSize 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 SrcAddr The source HW MAC address. If this parameter is NULL, the
- HW MAC source address will not be extracted from the media
- header.
- @param DestAddr 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_STARTED The network interface has not been started.
- @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_INVALID_PARAMETER One or more of the parameters has an unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network interface.
- **/
- EFI_STATUS
- WinNtSnpReceive (
- IN EMU_SNP_PROTOCOL *This,
- OUT UINTN *HeaderSize OPTIONAL,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer,
- OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
- OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,
- OUT UINT16 *Protocol OPTIONAL
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- INT32 ReturnValue;
- UINTN BufSize;
- Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);
- BufSize = *BufferSize;
- ASSERT (Private->NtNetUtilityTable.Receive != NULL);
- ReturnValue = Private->NtNetUtilityTable.Receive (
- Private->Instance.InterfaceInfo.InterfaceIndex,
- BufferSize,
- Buffer
- );
- if (ReturnValue < 0) {
- if (ReturnValue == -100) {
- return EFI_BUFFER_TOO_SMALL;
- }
- return EFI_DEVICE_ERROR;
- } else if (ReturnValue == 0) {
- return EFI_NOT_READY;
- }
- if (HeaderSize != NULL) {
- *HeaderSize = 14;
- }
- if (SrcAddr != NULL) {
- ZeroMem (SrcAddr, sizeof (EFI_MAC_ADDRESS));
- CopyMem (SrcAddr, ((UINT8 *)Buffer) + 6, 6);
- }
- if (DestAddr != NULL) {
- ZeroMem (DestAddr, sizeof (EFI_MAC_ADDRESS));
- CopyMem (DestAddr, ((UINT8 *)Buffer), 6);
- }
- if (Protocol != NULL) {
- *Protocol = NTOHS (*((UINT16 *)(((UINT8 *)Buffer) + 12)));
- }
- return (*BufferSize <= BufSize) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
- }
- /**
- Initialize the snpnt32 driver instance.
- @param Instance Pointer to the instance context data.
- @param NetInfo Pointer to the interface info.
- @retval EFI_SUCCESS The driver instance is initialized.
- @retval other Initialization errors.
- **/
- EFI_STATUS
- WinNtInitializeInstanceData (
- IN OUT WIN_NT_INSTANCE_DATA *Instance,
- IN NT_NET_INTERFACE_INFO *NetInfo
- )
- {
- if ((Instance == NULL) || (NetInfo == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- ZeroMem (Instance, sizeof (WIN_NT_INSTANCE_DATA));
- Instance->Signature = WIN_NT_INSTANCE_SIGNATURE;
- Instance->RecycledTxBufCount = 0;
- Instance->MaxRecycledTxBuf = 32;
- Instance->Mode.State = EfiSimpleNetworkInitialized;
- Instance->Mode.HwAddressSize = NET_ETHER_ADDR_LEN;
- Instance->Mode.MediaHeaderSize = NET_ETHER_HEADER_SIZE;
- Instance->Mode.MaxPacketSize = 1500;
- Instance->Mode.MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
- Instance->Mode.IfType = NET_IFTYPE_ETHERNET;
- Instance->Mode.MediaPresentSupported = TRUE;
- Instance->Mode.MediaPresent = TRUE;
- //
- // Allocate the RecycledTxBuf.
- //
- Instance->RecycledTxBuf = malloc (sizeof (UINT64) * Instance->MaxRecycledTxBuf);
- if (Instance->RecycledTxBuf == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Set the interface information.
- //
- CopyMem (&Instance->InterfaceInfo, NetInfo, sizeof (Instance->InterfaceInfo));
- //
- // Set broadcast address
- //
- SetMem (&Instance->Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);
- //
- // Copy Current/PermanentAddress MAC address
- //
- CopyMem (&Instance->Mode.CurrentAddress, &Instance->InterfaceInfo.MacAddr, sizeof (Instance->Mode.CurrentAddress));
- CopyMem (&Instance->Mode.PermanentAddress, &Instance->InterfaceInfo.MacAddr, sizeof (Instance->Mode.PermanentAddress));
- //
- // 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.
- //
- Instance->Mode.CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++;
- return EFI_SUCCESS;
- }
- /**
- Initialize the net utility data.
- @param This Pointer to the private data.
- @param ActiveInstance The active network interface.
- @retval EFI_SUCCESS The global data is initialized.
- @retval EFI_NOT_FOUND The required DLL is not found.
- @retval EFI_DEVICE_ERROR Error initialize network utility library.
- @retval other Other errors.
- **/
- EFI_STATUS
- WintNtInitializeNetUtilityData (
- IN OUT WIN_NT_SNP_PRIVATE *Private,
- IN UINT8 ActiveInstance
- )
- {
- EFI_STATUS Status;
- CHAR16 *DllFileNameU;
- INT32 ReturnValue;
- BOOLEAN NetUtilityLibInitDone;
- NT_NET_INTERFACE_INFO NetInterfaceInfoBuffer[MAX_INTERFACE_INFO_NUMBER];
- UINT32 InterfaceCount;
- UINT8 ActiveInterfaceIndex;
- if (Private == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- NetUtilityLibInitDone = FALSE;
- InterfaceCount = MAX_INTERFACE_INFO_NUMBER;
- DllFileNameU = NETWORK_LIBRARY_NAME_U;
- //
- // Load network utility library
- //
- Private->NetworkLibraryHandle = LoadLibraryEx (DllFileNameU, NULL, 0);
- if (NULL == Private->NetworkLibraryHandle) {
- return EFI_NOT_FOUND;
- }
- Private->NtNetUtilityTable.Initialize = (NT_NET_INITIALIZE)GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_INITIALIZE);
- if (NULL == Private->NtNetUtilityTable.Initialize) {
- Status = EFI_NOT_FOUND;
- goto ErrorReturn;
- }
- Private->NtNetUtilityTable.Finalize = (NT_NET_FINALIZE)GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_FINALIZE);
- if (NULL == Private->NtNetUtilityTable.Finalize) {
- Status = EFI_NOT_FOUND;
- goto ErrorReturn;
- }
- Private->NtNetUtilityTable.SetReceiveFilter = (NT_NET_SET_RECEIVE_FILTER)GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_SET_RCV_FILTER);
- if (NULL == Private->NtNetUtilityTable.SetReceiveFilter) {
- Status = EFI_NOT_FOUND;
- goto ErrorReturn;
- }
- Private->NtNetUtilityTable.Receive = (NT_NET_RECEIVE)GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_RECEIVE);
- if (NULL == Private->NtNetUtilityTable.Receive) {
- Status = EFI_NOT_FOUND;
- goto ErrorReturn;
- }
- Private->NtNetUtilityTable.Transmit = (NT_NET_TRANSMIT)GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_TRANSMIT);
- if (NULL == Private->NtNetUtilityTable.Transmit) {
- Status = EFI_NOT_FOUND;
- goto ErrorReturn;
- }
- //
- // Initialize the network utility library
- // And enumerate the interfaces in emulator host
- //
- ReturnValue = Private->NtNetUtilityTable.Initialize (&InterfaceCount, &NetInterfaceInfoBuffer[0]);
- if (ReturnValue <= 0) {
- Status = EFI_DEVICE_ERROR;
- goto ErrorReturn;
- }
- NetUtilityLibInitDone = TRUE;
- if (InterfaceCount == 0) {
- Status = EFI_NOT_FOUND;
- goto ErrorReturn;
- }
- DEBUG ((DEBUG_INFO, "%a, total %d interface(s) found\n", __FUNCTION__, InterfaceCount));
- //
- // Active interface index is set to first interface if given instance does
- // not exist.
- //
- ActiveInterfaceIndex = (ActiveInstance >= InterfaceCount ? DEFAULT_SELECTED_NIC_INDEX : ActiveInstance);
- //
- // Initialize instance
- //
- Status = WinNtInitializeInstanceData (&Private->Instance, &NetInterfaceInfoBuffer[ActiveInterfaceIndex]);
- if (EFI_ERROR (Status)) {
- goto ErrorReturn;
- }
- return EFI_SUCCESS;
- ErrorReturn:
- if (Private->Instance.RecycledTxBuf != NULL) {
- free (Private->Instance.RecycledTxBuf);
- }
- if (NetUtilityLibInitDone) {
- if (Private->NtNetUtilityTable.Finalize != NULL) {
- Private->NtNetUtilityTable.Finalize ();
- Private->NtNetUtilityTable.Finalize = NULL;
- }
- }
- return Status;
- }
- /**
- Release the net utility data.
- @param This Pointer to the private data.
- @retval EFI_SUCCESS The global data is released.
- @retval other Other errors.
- **/
- EFI_STATUS
- WintNtReleaseNetUtilityData (
- IN OUT WIN_NT_SNP_PRIVATE *Private
- )
- {
- if (Private == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- if (Private->Instance.RecycledTxBuf != NULL) {
- free (Private->Instance.RecycledTxBuf);
- }
- if (Private->NtNetUtilityTable.Finalize != NULL) {
- Private->NtNetUtilityTable.Finalize ();
- }
- FreeLibrary (Private->NetworkLibraryHandle);
- return EFI_SUCCESS;
- }
- EMU_SNP_PROTOCOL mWinNtSnpProtocol = {
- WinNtSnpCreateMapping,
- WinNtSnpStart,
- WinNtSnpStop,
- WinNtSnpInitialize,
- WinNtSnpReset,
- WinNtSnpShutdown,
- WinNtSnpReceiveFilters,
- WinNtSnpStationAddress,
- WinNtSnpStatistics,
- WinNtSnpMCastIpToMac,
- WinNtSnpNvData,
- WinNtSnpGetStatus,
- WinNtSnpTransmit,
- WinNtSnpReceive
- };
- /**
- Open SNP thunk protocol.
- @param This Pointer to the thunk protocol instance.
- @retval EFI_SUCCESS SNP thunk protocol is opened successfully.
- @retval EFI_UNSUPPORTED This is not SNP thunk protocol.
- @retval EFI_OUT_OF_RESOURCES Not enough memory.
- @retval other Other errors.
- **/
- EFI_STATUS
- WinNtSnpThunkOpen (
- IN EMU_IO_THUNK_PROTOCOL *This
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- UINT8 HostInterfaceIndex;
- HostInterfaceIndex = 0;
- if (This->Private != NULL) {
- return EFI_ALREADY_STARTED;
- }
- if (!CompareGuid (This->Protocol, &gEmuSnpProtocolGuid)) {
- return EFI_UNSUPPORTED;
- }
- Private = malloc (sizeof (WIN_NT_SNP_PRIVATE));
- if (Private == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- Private->Signature = WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE;
- Private->Thunk = This;
- CopyMem (&Private->EmuSnp, &mWinNtSnpProtocol, sizeof (mWinNtSnpProtocol));
- This->Interface = &Private->EmuSnp;
- This->Private = Private;
- if ((This->ConfigString != NULL) && (This->ConfigString[0] != '\0')) {
- HostInterfaceIndex = (UINT8)StrDecimalToUintn (This->ConfigString);
- }
- return WintNtInitializeNetUtilityData (Private, HostInterfaceIndex);
- }
- /**
- Close SNP thunk protocol.
- @param This Pointer to the thunk protocol instance.
- @retval EFI_SUCCESS SNP thunk protocol is closed successfully.
- @retval EFI_UNSUPPORTED This is not SNP thunk protocol.
- @retval other Other errors.
- **/
- EFI_STATUS
- WinNtSnpThunkClose (
- IN EMU_IO_THUNK_PROTOCOL *This
- )
- {
- WIN_NT_SNP_PRIVATE *Private;
- if (!CompareGuid (This->Protocol, &gEmuSnpProtocolGuid)) {
- return EFI_UNSUPPORTED;
- }
- Private = This->Private;
- WintNtReleaseNetUtilityData (Private);
- free (Private);
- return EFI_SUCCESS;
- }
- EMU_IO_THUNK_PROTOCOL mWinNtSnpThunkIo = {
- &gEmuSnpProtocolGuid,
- NULL,
- NULL,
- 0,
- WinNtSnpThunkOpen,
- WinNtSnpThunkClose,
- NULL
- };
|