mirror of https://github.com/acidanthera/audk.git
Import SnpDxe, Tcp4Dxe, Udp4Dxe and MnpDxe.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3416 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
f9bef4b3ac
commit
8a67d61da4
|
@ -171,7 +171,7 @@ typedef struct _IP_IO_SEND_ENTRY {
|
|||
EFI_IP4_COMPLETION_TOKEN *SndToken;
|
||||
} IP_IO_SEND_ENTRY;
|
||||
|
||||
typedef struct _EFI_IP4_OVERRIDE_DATA IP_IO_OVERRIDE;
|
||||
typedef EFI_IP4_OVERRIDE_DATA IP_IO_OVERRIDE;
|
||||
|
||||
typedef struct _IP_IO_IP_INFO {
|
||||
IP4_ADDR Addr;
|
||||
|
|
|
@ -809,4 +809,79 @@ NetPseudoHeadChecksum (
|
|||
IN UINT8 Proto,
|
||||
IN UINT16 Len
|
||||
);
|
||||
|
||||
//
|
||||
// The debug level definition. This value is also used as the
|
||||
// syslog's servity level. Don't change it.
|
||||
//
|
||||
enum {
|
||||
NETDEBUG_LEVEL_TRACE = 5,
|
||||
NETDEBUG_LEVEL_WARNING = 4,
|
||||
NETDEBUG_LEVEL_ERROR = 3,
|
||||
};
|
||||
|
||||
#ifdef EFI_NETWORK_STACK_DEBUG
|
||||
|
||||
//
|
||||
// The debug output expects the ASCII format string, Use %a to print ASCII
|
||||
// string, and %s to print UNICODE string. PrintArg must be enclosed in ().
|
||||
// For example: NET_DEBUG_TRACE ("Tcp", ("State transit to %a\n", Name));
|
||||
//
|
||||
#define NET_DEBUG_TRACE(Module, PrintArg) \
|
||||
NetDebugOutput ( \
|
||||
NETDEBUG_LEVEL_TRACE, \
|
||||
Module, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
NetDebugASPrint PrintArg \
|
||||
)
|
||||
|
||||
#define NET_DEBUG_WARNING(Module, PrintArg) \
|
||||
NetDebugOutput ( \
|
||||
NETDEBUG_LEVEL_WARNING, \
|
||||
Module, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
NetDebugASPrint PrintArg \
|
||||
)
|
||||
|
||||
#define NET_DEBUG_ERROR(Module, PrintArg) \
|
||||
NetDebugOutput ( \
|
||||
NETDEBUG_LEVEL_ERROR, \
|
||||
Module, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
NetDebugASPrint PrintArg \
|
||||
)
|
||||
|
||||
#else
|
||||
#define NET_DEBUG_TRACE(Module, PrintString)
|
||||
#define NET_DEBUG_WARNING(Module, PrintString)
|
||||
#define NET_DEBUG_ERROR(Module, PrintString)
|
||||
#endif
|
||||
|
||||
UINT8 *
|
||||
NetDebugASPrint (
|
||||
UINT8 *Format,
|
||||
...
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
NetDebugOutput (
|
||||
UINT32 Level,
|
||||
UINT8 *Module,
|
||||
UINT8 *File,
|
||||
UINT32 Line,
|
||||
UINT8 *Message
|
||||
);
|
||||
|
||||
//
|
||||
// Network debug message is sent out as syslog.
|
||||
//
|
||||
enum {
|
||||
NET_SYSLOG_FACILITY = 16, // Syslog local facility local use
|
||||
NET_SYSLOG_PACKET_LEN = 512,
|
||||
NET_DEBUG_MSG_LEN = 470, // 512 - (ether+ip+udp head length)
|
||||
NET_SYSLOG_TX_TIMEOUT = 500 *1000 *10, // 500ms
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -41,25 +41,12 @@
|
|||
|
||||
|
||||
[LibraryClasses]
|
||||
MemoryAllocationLib
|
||||
UefiLib
|
||||
IpIoLib
|
||||
BaseLib
|
||||
UefiBootServicesTableLib
|
||||
UefiRuntimeServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
PrintLib
|
||||
|
||||
UefiBootServicesTableLib
|
||||
MemoryAllocationLib
|
||||
|
||||
[Protocols]
|
||||
gEfiIp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDriverDiagnosticsProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiUdp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiLoadedImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiIp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDriverConfigurationProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiSimpleNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDriverBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiComponentNameProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
[Sources.common]
|
||||
DxeNetLib.c
|
||||
NetBuffer.c
|
||||
NetDebug.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
@ -42,25 +43,15 @@
|
|||
|
||||
|
||||
[LibraryClasses]
|
||||
MemoryAllocationLib
|
||||
UefiLib
|
||||
BaseLib
|
||||
UefiBootServicesTableLib
|
||||
UefiRuntimeServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
PrintLib
|
||||
|
||||
NetLib
|
||||
BaseLib
|
||||
DebugLib
|
||||
BaseMemoryLib
|
||||
UefiBootServicesTableLib
|
||||
UefiRuntimeServicesTableLib
|
||||
UefiLib
|
||||
MemoryAllocationLib
|
||||
|
||||
[Protocols]
|
||||
gEfiIp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDriverDiagnosticsProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiUdp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiLoadedImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiIp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDriverConfigurationProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiSimpleNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDriverBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiComponentNameProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
||||
|
|
|
@ -0,0 +1,536 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
NetDebug.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Network debug facility. The debug information is wrapped in
|
||||
SYSLOG packets, then sent over SNP. This debug facility can't
|
||||
be used by SNP. Apply caution when used in MNP and non-network
|
||||
module because SNP is most likely not "thread safe". We assume
|
||||
that the SNP supports the EHTERNET.
|
||||
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/SimpleNetwork.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/NetLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
|
||||
|
||||
//
|
||||
// Any error level digitally larger than mNetDebugLevelMax
|
||||
// will be silently discarded.
|
||||
//
|
||||
UINTN mNetDebugLevelMax = NETDEBUG_LEVEL_ERROR;
|
||||
UINT32 mSyslogPacketSeq = 0xDEADBEEF;
|
||||
|
||||
//
|
||||
// You can change mSyslogDstMac mSyslogDstIp and mSyslogSrcIp
|
||||
// here to direct the syslog packets to the syslog deamon. The
|
||||
// default is broadcast to both the ethernet and IP.
|
||||
//
|
||||
UINT8 mSyslogDstMac [NET_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
UINT32 mSyslogDstIp = 0xffffffff;
|
||||
UINT32 mSyslogSrcIp = 0;
|
||||
|
||||
UINT8 *
|
||||
MonthName[] = {
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mar",
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec"
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Locate the handles that support SNP, then open one of them
|
||||
to send the syslog packets. The caller isn't required to close
|
||||
the SNP after use because the SNP is opened by HandleProtocol.
|
||||
|
||||
None
|
||||
|
||||
@return The point to SNP if one is properly openned. Otherwise NULL
|
||||
|
||||
**/
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *
|
||||
SyslogLocateSnp (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE *Handles;
|
||||
UINTN HandleCount;
|
||||
UINTN Index;
|
||||
|
||||
//
|
||||
// Locate the handles which has SNP installed.
|
||||
//
|
||||
Handles = NULL;
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&Handles
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status) || (HandleCount == 0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to open one of the ethernet SNP protocol to send packet
|
||||
//
|
||||
Snp = NULL;
|
||||
|
||||
for (Index = 0; Index < HandleCount; Index++) {
|
||||
Status = gBS->HandleProtocol (
|
||||
Handles[Index],
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
(VOID **) &Snp
|
||||
);
|
||||
|
||||
if ((Status == EFI_SUCCESS) && (Snp != NULL) &&
|
||||
(Snp->Mode->IfType == NET_IFTYPE_ETHERNET) &&
|
||||
(Snp->Mode->MaxPacketSize >= NET_SYSLOG_PACKET_LEN)) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
Snp = NULL;
|
||||
}
|
||||
|
||||
gBS->FreePool (Handles);
|
||||
return Snp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Transmit a syslog packet synchronously through SNP. The Packet
|
||||
already has the ethernet header prepended. This function should
|
||||
fill in the source MAC because it will try to locate a SNP each
|
||||
time it is called to avoid the problem if SNP is unloaded.
|
||||
This code snip is copied from MNP.
|
||||
|
||||
@param Packet The Syslog packet
|
||||
@param Length The length of the packet
|
||||
|
||||
@retval EFI_DEVICE_ERROR Failed to locate a usable SNP protocol
|
||||
@retval EFI_TIMEOUT Timeout happened to send the packet.
|
||||
@retval EFI_SUCCESS Packet is sent.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SyslogSendPacket (
|
||||
IN UINT8 *Packet,
|
||||
IN UINT32 Length
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||
ETHER_HEAD *Ether;
|
||||
EFI_STATUS Status;
|
||||
EFI_EVENT TimeoutEvent;
|
||||
UINT8 *TxBuf;
|
||||
|
||||
Snp = SyslogLocateSnp ();
|
||||
|
||||
if (Snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Ether = (ETHER_HEAD *) Packet;
|
||||
CopyMem (Ether->SrcMac, Snp->Mode->CurrentAddress.Addr, NET_ETHER_ADDR_LEN);
|
||||
|
||||
//
|
||||
// Start the timeout event.
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_TIMER,
|
||||
TPL_NOTIFY,
|
||||
NULL,
|
||||
NULL,
|
||||
&TimeoutEvent
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gBS->SetTimer (TimeoutEvent, TimerRelative, NET_SYSLOG_TX_TIMEOUT);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
//
|
||||
// Transmit the packet through SNP.
|
||||
//
|
||||
Status = Snp->Transmit (Snp, 0, Length, Packet, NULL, NULL, NULL);
|
||||
|
||||
if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_READY)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// If Status is EFI_SUCCESS, the packet is put in the transmit queue.
|
||||
// if Status is EFI_NOT_READY, the transmit engine of the network
|
||||
// interface is busy. Both need to sync SNP.
|
||||
//
|
||||
TxBuf = NULL;
|
||||
|
||||
do {
|
||||
//
|
||||
// Get the recycled transmit buffer status.
|
||||
//
|
||||
Snp->GetStatus (Snp, NULL, &TxBuf);
|
||||
|
||||
if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
|
||||
Status = EFI_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
} while (TxBuf == NULL);
|
||||
|
||||
if ((Status == EFI_SUCCESS) || (Status == EFI_TIMEOUT)) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Status is EFI_NOT_READY. Restart the timer event and
|
||||
// call Snp->Transmit again.
|
||||
//
|
||||
gBS->SetTimer (TimeoutEvent, TimerRelative, NET_SYSLOG_TX_TIMEOUT);
|
||||
}
|
||||
|
||||
gBS->SetTimer (TimeoutEvent, TimerCancel, 0);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->CloseEvent (TimeoutEvent);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Compute checksum for a bulk of data. This code is copied from the
|
||||
Netbuffer library.
|
||||
|
||||
@param Bulk Pointer to the data.
|
||||
@param Len Length of the data, in bytes.
|
||||
|
||||
@retval UINT16 The computed checksum.
|
||||
|
||||
**/
|
||||
UINT16
|
||||
SyslogChecksum (
|
||||
IN UINT8 *Bulk,
|
||||
IN UINT32 Len
|
||||
)
|
||||
{
|
||||
register UINT32 Sum;
|
||||
|
||||
Sum = 0;
|
||||
|
||||
while (Len > 1) {
|
||||
Sum += *(UINT16 *) Bulk;
|
||||
Bulk += 2;
|
||||
Len -= 2;
|
||||
}
|
||||
|
||||
//
|
||||
// Add left-over byte, if any
|
||||
//
|
||||
if (Len > 0) {
|
||||
Sum += *(UINT8 *) Bulk;
|
||||
}
|
||||
|
||||
//
|
||||
// Fold 32-bit sum to 16 bits
|
||||
//
|
||||
while (Sum >> 16) {
|
||||
Sum = (Sum & 0xffff) + (Sum >> 16);
|
||||
}
|
||||
|
||||
return (UINT16) ~Sum;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Build a syslog packet, including the Ethernet/Ip/Udp headers
|
||||
and user's message.
|
||||
|
||||
@param Buf The buffer to put the packet data
|
||||
@param BufLen The lenght of the Buf
|
||||
@param Level Syslog servity level
|
||||
@param Module The module that generates the log
|
||||
@param File The file that contains the current log
|
||||
@param Line The line of code in the File that contains the
|
||||
current log
|
||||
@param Message The log message
|
||||
|
||||
@return The length of the syslog packet built.
|
||||
|
||||
**/
|
||||
UINT32
|
||||
SyslogBuildPacket (
|
||||
UINT8 *Buf,
|
||||
UINT32 BufLen,
|
||||
UINT32 Level,
|
||||
UINT8 *Module,
|
||||
UINT8 *File,
|
||||
UINT32 Line,
|
||||
UINT8 *Message
|
||||
)
|
||||
{
|
||||
ETHER_HEAD *Ether;
|
||||
IP4_HEAD *Ip4;
|
||||
EFI_UDP4_HEADER *Udp4;
|
||||
EFI_TIME Time;
|
||||
UINT32 Pri;
|
||||
UINT32 Len;
|
||||
|
||||
//
|
||||
// Fill in the Ethernet header. Leave alone the source MAC.
|
||||
// SyslogSendPacket will fill in the address for us.
|
||||
//
|
||||
Ether = (ETHER_HEAD *) Buf;
|
||||
CopyMem (Ether->DstMac, mSyslogDstMac, NET_ETHER_ADDR_LEN);
|
||||
ZeroMem (Ether->SrcMac, NET_ETHER_ADDR_LEN);
|
||||
|
||||
Ether->EtherType = HTONS (0x0800); // IP protocol
|
||||
|
||||
Buf += sizeof (ETHER_HEAD);
|
||||
BufLen -= sizeof (ETHER_HEAD);
|
||||
|
||||
//
|
||||
// Fill in the IP header
|
||||
//
|
||||
Ip4 = (IP4_HEAD *) Buf;
|
||||
Ip4->HeadLen = 5;
|
||||
Ip4->Ver = 4;
|
||||
Ip4->Tos = 0;
|
||||
Ip4->TotalLen = 0;
|
||||
Ip4->Id = (UINT16) mSyslogPacketSeq;
|
||||
Ip4->Fragment = 0;
|
||||
Ip4->Ttl = 16;
|
||||
Ip4->Protocol = 0x11;
|
||||
Ip4->Checksum = 0;
|
||||
Ip4->Src = mSyslogSrcIp;
|
||||
Ip4->Dst = mSyslogDstIp;
|
||||
|
||||
Buf += sizeof (IP4_HEAD);
|
||||
BufLen -= sizeof (IP4_HEAD);
|
||||
|
||||
//
|
||||
// Fill in the UDP header, Udp checksum is optional. Leave it zero.
|
||||
//
|
||||
Udp4 = (EFI_UDP4_HEADER*) Buf;
|
||||
Udp4->SrcPort = HTONS (514);
|
||||
Udp4->DstPort = HTONS (514);
|
||||
Udp4->Length = 0;
|
||||
Udp4->Checksum = 0;
|
||||
|
||||
Buf += sizeof (EFI_UDP4_HEADER);
|
||||
BufLen -= sizeof (EFI_UDP4_HEADER);
|
||||
|
||||
//
|
||||
// Build the syslog message body with <PRI> Timestamp machine module Message
|
||||
//
|
||||
Pri = ((NET_SYSLOG_FACILITY & 31) << 3) | (Level & 7);
|
||||
gRT->GetTime (&Time, NULL);
|
||||
|
||||
//
|
||||
// Use %a to format the ASCII strings, %s to format UNICODE strings
|
||||
//
|
||||
Len = 0;
|
||||
Len += (UINT32) AsciiSPrint (
|
||||
Buf,
|
||||
BufLen,
|
||||
"<%d> %a %d %d:%d:%d ",
|
||||
Pri,
|
||||
MonthName [Time.Month-1],
|
||||
Time.Day,
|
||||
Time.Hour,
|
||||
Time.Minute,
|
||||
Time.Second
|
||||
);
|
||||
Len--;
|
||||
|
||||
Len += (UINT32) AsciiSPrint (
|
||||
Buf + Len,
|
||||
BufLen - Len,
|
||||
"Tiano %a: %a (Line: %d File: %a)",
|
||||
Module,
|
||||
Message,
|
||||
Line,
|
||||
File
|
||||
);
|
||||
Len--;
|
||||
|
||||
//
|
||||
// OK, patch the IP length/checksum and UDP length fields.
|
||||
//
|
||||
Len += sizeof (EFI_UDP4_HEADER);
|
||||
Udp4->Length = HTONS ((UINT16) Len);
|
||||
|
||||
Len += sizeof (IP4_HEAD);
|
||||
Ip4->TotalLen = HTONS ((UINT16) Len);
|
||||
Ip4->Checksum = SyslogChecksum ((UINT8 *) Ip4, sizeof (IP4_HEAD));
|
||||
|
||||
return Len + sizeof (ETHER_HEAD);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Allocate a buffer, then format the message to it. This is a
|
||||
help function for the NET_DEBUG_XXX macros. The PrintArg of
|
||||
these macros treats the variable length print parameters as a
|
||||
single parameter, and pass it to the NetDebugASPrint. For
|
||||
example, NET_DEBUG_TRACE ("Tcp", ("State transit to %a\n", Name))
|
||||
if extracted to:
|
||||
NetDebugOutput (
|
||||
NETDEBUG_LEVEL_TRACE,
|
||||
"Tcp",
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
NetDebugASPrint ("State transit to %a\n", Name)
|
||||
)
|
||||
This is exactly what we want.
|
||||
|
||||
@param Format The ASCII format string.
|
||||
@param ... The variable length parameter whose format is
|
||||
determined by the Format string.
|
||||
|
||||
@return The buffer containing the formatted message, or NULL if failed to
|
||||
@return allocate memory.
|
||||
|
||||
**/
|
||||
UINT8 *
|
||||
NetDebugASPrint (
|
||||
UINT8 *Format,
|
||||
...
|
||||
)
|
||||
{
|
||||
VA_LIST Marker;
|
||||
UINT8 *Buf;
|
||||
|
||||
Buf = AllocatePool (NET_DEBUG_MSG_LEN);
|
||||
|
||||
if (Buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VA_START (Marker, Format);
|
||||
AsciiVSPrint (Buf, NET_DEBUG_MSG_LEN, Format, Marker);
|
||||
VA_END (Marker);
|
||||
|
||||
return Buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Output a debug message to syslog. This function will locate a
|
||||
instance of SNP then send the message through it. Because it
|
||||
isn't open the SNP BY_DRIVER, apply caution when using it.
|
||||
|
||||
@param Level The servity level of the message.
|
||||
@param Module The Moudle that generates the log.
|
||||
@param File The file that contains the log.
|
||||
@param Line The exact line that contains the log.
|
||||
@param Message The user message to log.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the packet
|
||||
@retval EFI_SUCCESS The log is discard because that it is more verbose
|
||||
than the mNetDebugLevelMax. Or, it has been sent
|
||||
out.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
NetDebugOutput (
|
||||
UINT32 Level,
|
||||
UINT8 *Module,
|
||||
UINT8 *File,
|
||||
UINT32 Line,
|
||||
UINT8 *Message
|
||||
)
|
||||
{
|
||||
UINT8 *Packet;
|
||||
UINT32 Len;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Check whether the message should be sent out
|
||||
//
|
||||
if (Message == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
if (Level > mNetDebugLevelMax) {
|
||||
Status = EFI_SUCCESS;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate a maxium of 1024 bytes, the caller should ensure
|
||||
// that the message plus the ethernet/ip/udp header is shorter
|
||||
// than this
|
||||
//
|
||||
Packet = AllocatePool (NET_SYSLOG_PACKET_LEN);
|
||||
|
||||
if (Packet == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Build the message: Ethernet header + IP header + Udp Header + user data
|
||||
//
|
||||
Len = SyslogBuildPacket (
|
||||
Packet,
|
||||
NET_SYSLOG_PACKET_LEN,
|
||||
Level,
|
||||
Module,
|
||||
File,
|
||||
Line,
|
||||
Message
|
||||
);
|
||||
|
||||
mSyslogPacketSeq++;
|
||||
Status = SyslogSendPacket (Packet, Len);
|
||||
gBS->FreePool (Packet);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->FreePool (Message);
|
||||
return Status;
|
||||
}
|
|
@ -41,25 +41,12 @@
|
|||
|
||||
|
||||
[LibraryClasses]
|
||||
MemoryAllocationLib
|
||||
UefiLib
|
||||
UdpIoLib
|
||||
BaseLib
|
||||
UefiBootServicesTableLib
|
||||
UefiRuntimeServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
PrintLib
|
||||
|
||||
UefiBootServicesTableLib
|
||||
MemoryAllocationLib
|
||||
|
||||
[Protocols]
|
||||
gEfiIp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDriverDiagnosticsProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiUdp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiLoadedImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiIp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDriverConfigurationProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiSimpleNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDriverBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiComponentNameProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
||||
gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
|
@ -401,6 +401,10 @@
|
|||
$(WORKSPACE)/MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
|
||||
|
||||
$(WORKSPACE)/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
|
||||
$(WORKSPACE)/MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
|
||||
$(WORKSPACE)/MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
|
||||
$(WORKSPACE)/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
|
||||
$(WORKSPACE)/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
|
||||
|
||||
$(WORKSPACE)/MdeModulePkg/Application/HelloWorld/HelloWorld.inf
|
||||
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
ComponentName.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "MnpDriver.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
//
|
||||
// EFI Component Name Protocol
|
||||
//
|
||||
EFI_COMPONENT_NAME_PROTOCOL gMnpComponentName = {
|
||||
MnpComponentNameGetDriverName,
|
||||
MnpComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
STATIC EFI_UNICODE_STRING_TABLE mMnpDriverNameTable[] = {
|
||||
{
|
||||
"eng",
|
||||
L"MNP Network Service Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves a Unicode string that is the user readable name of the EFI Driver.
|
||||
|
||||
Arguments:
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
Language - A pointer to a three character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages specified
|
||||
in SupportedLanguages. The number of languages supported by a
|
||||
driver is up to the driver writer.
|
||||
DriverName - A pointer to the Unicode string to return. This Unicode string
|
||||
is the name of the driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCES - The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - DriverName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return LookupUnicodeString (
|
||||
Language,
|
||||
gMnpComponentName.SupportedLanguages,
|
||||
mMnpDriverNameTable,
|
||||
DriverName
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
Arguments:
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
ControllerHandle - The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
ChildHandle - The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL. It
|
||||
will be NULL for device drivers. It will also be NULL
|
||||
for a bus drivers that wish to retrieve the name of the
|
||||
bus controller. It will not be NULL for a bus driver
|
||||
that wishes to retrieve the name of a child controller.
|
||||
Language - A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller name
|
||||
that that the caller is requesting, and it must match one
|
||||
of the languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up to the
|
||||
driver writer.
|
||||
ControllerName - A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language specified
|
||||
by Language from the point of view of the driver specified
|
||||
by This.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The Unicode string for the user readable name in the
|
||||
language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - ControllerName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This is not currently managing
|
||||
the controller specified by ControllerHandle and
|
||||
ChildHandle.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,28 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
MnpDebug.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _MNP_DEBUG_H_
|
||||
#define _MNP_DEBUG_H_
|
||||
|
||||
#define MNP_DEBUG_TRACE(PrintArg) NET_DEBUG_TRACE ("Mnp", PrintArg)
|
||||
#define MNP_DEBUG_WARN(PrintArg) NET_DEBUG_WARNING ("Mnp", PrintArg)
|
||||
#define MNP_DEBUG_ERROR(PrintArg) NET_DEBUG_ERROR ("Mnp", PrintArg)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,560 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
MnpDriver.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "MnpDriver.h"
|
||||
#include "MnpDebug.h"
|
||||
#include "MnpImpl.h"
|
||||
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {
|
||||
MnpDriverBindingSupported,
|
||||
MnpDriverBindingStart,
|
||||
MnpDriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Test to see if this driver supports ControllerHandle.
|
||||
|
||||
@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_SUCCES This driver supports this device.
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on this device.
|
||||
@retval other This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Test to see if MNP is already installed.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Test to see if SNP is installed.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle.
|
||||
|
||||
@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_SUCCES This driver is added to ControllerHandle.
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on
|
||||
ControllerHandle.
|
||||
@retval other This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MNP_SERVICE_DATA *MnpServiceData;
|
||||
BOOLEAN MnpInitialized;
|
||||
|
||||
MnpInitialized = FALSE;
|
||||
|
||||
MnpServiceData = NetAllocateZeroPool (sizeof (MNP_SERVICE_DATA));
|
||||
if (MnpServiceData == NULL) {
|
||||
MNP_DEBUG_ERROR (("MnpDriverBindingStart(): Failed to allocate the "
|
||||
L"Mnp Service Data.\n"));
|
||||
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the Mnp Service Data.
|
||||
//
|
||||
Status = MnpInitializeServiceData (MnpServiceData, This->DriverBindingHandle, ControllerHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
MNP_DEBUG_ERROR (("MnpDriverBindingStart: MnpInitializeServiceData "
|
||||
L"failed, %r.\n",Status));
|
||||
goto ErrorExit;
|
||||
}
|
||||
|
||||
MnpInitialized = TRUE;
|
||||
|
||||
//
|
||||
// Install the MNP Service Binding Protocol.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ControllerHandle,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
&MnpServiceData->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
|
||||
ErrorExit:
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
if (MnpInitialized) {
|
||||
//
|
||||
// Flush the Mnp Service Data.
|
||||
//
|
||||
MnpFlushServiceData (MnpServiceData);
|
||||
}
|
||||
|
||||
//
|
||||
// Close the Simple Network Protocol.
|
||||
//
|
||||
gBS->CloseProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle
|
||||
);
|
||||
|
||||
NetFreePool (MnpServiceData);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle.
|
||||
|
||||
@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_SUCCES This driver is removed ControllerHandle.
|
||||
@retval other This driver was not removed from this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
MNP_SERVICE_DATA *MnpServiceData;
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
|
||||
//
|
||||
// Retrieve the MNP service binding protocol from the ControllerHandle.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
(VOID **) &ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
MNP_DEBUG_ERROR (
|
||||
("MnpDriverBindingStop: Locate MNP Service Binding Protocol failed, %r.\n",
|
||||
Status)
|
||||
);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);
|
||||
|
||||
while (!NetListIsEmpty (&MnpServiceData->ChildrenList)) {
|
||||
//
|
||||
// Don't use NetListRemoveHead here, the remove opreration will be done
|
||||
// in ServiceBindingDestroyChild.
|
||||
//
|
||||
Instance = NET_LIST_HEAD (
|
||||
&MnpServiceData->ChildrenList,
|
||||
MNP_INSTANCE_DATA,
|
||||
InstEntry
|
||||
);
|
||||
|
||||
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
|
||||
}
|
||||
|
||||
//
|
||||
// Uninstall the MNP Service Binding Protocol.
|
||||
//
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
ControllerHandle,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
MNP_DEBUG_ERROR (("MnpDriverBindingStop: Uninstall MNP Service Binding Protocol failed, %r.\n"));
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Close the openned Snp protocol.
|
||||
//
|
||||
Status = gBS->CloseProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
MNP_DEBUG_ERROR (("MnpDriverBindingStop: Close SNP Protocol failed, %r.\n", Status));
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Flush the Mnp service data.
|
||||
//
|
||||
MnpFlushServiceData (MnpServiceData);
|
||||
|
||||
NetFreePool (MnpServiceData);
|
||||
|
||||
EXIT:
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Creates a child handle with a set of I/O services.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If
|
||||
it is NULL, then a new handle is created. If it is
|
||||
not NULL, then the I/O services are added to the
|
||||
existing child handle.
|
||||
|
||||
@retval EFI_SUCCES The child handle was created with the I/O
|
||||
services.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
|
||||
the child.
|
||||
@retval other The child handle was not created.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MNP_SERVICE_DATA *MnpServiceData;
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
VOID *Snp;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Allocate buffer for the new instance.
|
||||
//
|
||||
Instance = NetAllocateZeroPool (sizeof (MNP_INSTANCE_DATA));
|
||||
if (Instance == NULL) {
|
||||
|
||||
MNP_DEBUG_ERROR (("MnpServiceBindingCreateChild: Faild to allocate memory for the new instance.\n"));
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Init the instance data.
|
||||
//
|
||||
MnpInitializeInstanceData (MnpServiceData, Instance);
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
&Instance->ManagedNetwork,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
MNP_DEBUG_ERROR (
|
||||
("MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",
|
||||
Status)
|
||||
);
|
||||
goto ErrorExit;
|
||||
}
|
||||
|
||||
//
|
||||
// Save the instance's childhandle.
|
||||
//
|
||||
Instance->Handle = *ChildHandle;
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
MnpServiceData->ControllerHandle,
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
(VOID **) &Snp,
|
||||
gMnpDriverBinding.DriverBindingHandle,
|
||||
Instance->Handle,
|
||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ErrorExit;
|
||||
}
|
||||
|
||||
//
|
||||
// Add the child instance into ChildrenList.
|
||||
//
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
NetListInsertTail (&MnpServiceData->ChildrenList, &Instance->InstEntry);
|
||||
MnpServiceData->ChildrenNumber++;
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
ErrorExit:
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
if (Instance->Handle != NULL) {
|
||||
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
&Instance->ManagedNetwork,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
NetFreePool (Instance);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destroys a child handle with a set of I/O services.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ChildHandle Handle of the child to destroy.
|
||||
|
||||
@retval EFI_SUCCES The I/O services were removed from the child
|
||||
handle.
|
||||
@retval EFI_UNSUPPORTED The child handle does not support the I/O services
|
||||
that are being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.
|
||||
@retval EFI_ACCESS_DENIED The child handle could not be destroyed because
|
||||
its I/O services are being used.
|
||||
@retval other The child handle was not destroyed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MNP_SERVICE_DATA *MnpServiceData;
|
||||
EFI_MANAGED_NETWORK_PROTOCOL *ManagedNetwork;
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Try to retrieve ManagedNetwork Protocol from ChildHandle.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
(VOID **) &ManagedNetwork,
|
||||
gMnpDriverBinding.DriverBindingHandle,
|
||||
ChildHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Instance = MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork);
|
||||
|
||||
//
|
||||
// MnpServiceBindingDestroyChild may be called twice: first called by
|
||||
// MnpServiceBindingStop, second called by uninstalling the MNP protocol
|
||||
// in this ChildHandle. Use destroyed to make sure the resource clean code
|
||||
// will only excecute once.
|
||||
//
|
||||
if (Instance->Destroyed) {
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Instance->Destroyed = TRUE;
|
||||
|
||||
//
|
||||
// Close the Simple Network protocol.
|
||||
//
|
||||
gBS->CloseProtocol (
|
||||
MnpServiceData->ControllerHandle,
|
||||
&gEfiSimpleNetworkProtocolGuid,
|
||||
gMnpDriverBinding.DriverBindingHandle,
|
||||
ChildHandle
|
||||
);
|
||||
|
||||
//
|
||||
// Uninstall the ManagedNetwork protocol.
|
||||
//
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
&Instance->ManagedNetwork,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
MNP_DEBUG_ERROR (
|
||||
("MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",
|
||||
Status)
|
||||
);
|
||||
|
||||
Instance->Destroyed = FALSE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
//
|
||||
// Reset the configuration.
|
||||
//
|
||||
ManagedNetwork->Configure (ManagedNetwork, NULL);
|
||||
|
||||
//
|
||||
// Try to flush the RcvdPacketQueue.
|
||||
//
|
||||
MnpFlushRcvdDataQueue (Instance);
|
||||
|
||||
//
|
||||
// Clean the RxTokenMap.
|
||||
//
|
||||
NetMapClean (&Instance->RxTokenMap);
|
||||
|
||||
//
|
||||
// Remove this instance from the ChildrenList.
|
||||
//
|
||||
NetListRemoveEntry (&Instance->InstEntry);
|
||||
MnpServiceData->ChildrenNumber--;
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
NetFreePool (Instance);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
//@MT: EFI_DRIVER_ENTRY_POINT (MnpDriverEntryPoint)
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpDriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The entry point for Mnp driver which installs the driver binding and component name
|
||||
protocol on its ImageHandle.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - The image handle of the driver.
|
||||
SystemTable - The system table.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - If the driver binding and component name protocols are successfully
|
||||
installed, otherwise if failed.
|
||||
|
||||
--*/
|
||||
{
|
||||
return NetLibInstallAllDriverProtocols (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gMnpDriverBinding,
|
||||
ImageHandle,
|
||||
&gMnpComponentName,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
MnpDriver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _MNP_DRIVER_H_
|
||||
#define _MNP_DRIVER_H_
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/ManagedNetwork.h>
|
||||
#include <Protocol/SimpleNetwork.h>
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/NetLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
|
||||
#include "MnpDebug.h"
|
||||
|
||||
//
|
||||
// Required Global Variables
|
||||
//
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding;
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gMnpComponentName;
|
||||
|
||||
#define MNP_SERVICE_DATA_SIGNATURE EFI_SIGNATURE_32 ('M', 'n', 'p', 'S')
|
||||
|
||||
typedef struct _MNP_SERVICE_DATA {
|
||||
UINT32 Signature;
|
||||
|
||||
EFI_HANDLE ControllerHandle;
|
||||
|
||||
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||
|
||||
UINT32 Mtu;
|
||||
|
||||
NET_LIST_ENTRY ChildrenList;
|
||||
UINTN ChildrenNumber;
|
||||
UINTN ConfiguredChildrenNumber;
|
||||
|
||||
NET_LIST_ENTRY GroupAddressList;
|
||||
UINT32 GroupAddressCount;
|
||||
|
||||
EFI_EVENT TxTimeoutEvent;
|
||||
|
||||
NET_BUF_QUEUE FreeNbufQue;
|
||||
INTN NbufCnt;
|
||||
|
||||
EFI_EVENT PollTimer;
|
||||
BOOLEAN EnableSystemPoll;
|
||||
|
||||
EFI_EVENT TimeoutCheckTimer;
|
||||
|
||||
UINT32 UnicastCount;
|
||||
UINT32 BroadcastCount;
|
||||
UINT32 MulticastCount;
|
||||
UINT32 PromiscuousCount;
|
||||
|
||||
//
|
||||
// The size of the data buffer in the MNP_PACKET_BUFFER used to
|
||||
// store a packet.
|
||||
//
|
||||
UINT32 BufferLength;
|
||||
NET_BUF *RxNbufCache;
|
||||
UINT8 *TxBuf;
|
||||
} MNP_SERVICE_DATA;
|
||||
|
||||
#define MNP_SERVICE_DATA_FROM_THIS(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
MNP_SERVICE_DATA, \
|
||||
ServiceBinding, \
|
||||
MNP_SERVICE_DATA_SIGNATURE \
|
||||
)
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL * This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL * This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
#/** @file
|
||||
# Component name for module Mnp
|
||||
#
|
||||
# FIX ME!
|
||||
# Copyright (c) 2006, Intel Corporation. All right reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = MnpDxe
|
||||
FILE_GUID = 025BBFC7-E6A9-4b8b-82AD-6815A1AEAF4A
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = MnpDriverEntryPoint
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources.common]
|
||||
MnpDebug.h
|
||||
MnpMain.c
|
||||
MnpIo.c
|
||||
MnpDriver.h
|
||||
ComponentName.c
|
||||
MnpDriver.c
|
||||
MnpConfig.c
|
||||
MnpImpl.h
|
||||
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
DebugLib
|
||||
NetLib
|
||||
|
||||
|
||||
[Protocols]
|
||||
gEfiManagedNetworkServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiSimpleNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiManagedNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<MsaHeader>
|
||||
<ModuleName>MnpDxe</ModuleName>
|
||||
<ModuleType>DXE_DRIVER</ModuleType>
|
||||
<GuidValue>025BBFC7-E6A9-4b8b-82AD-6815A1AEAF4A</GuidValue>
|
||||
<Version>1.0</Version>
|
||||
<Abstract>Component name for module Mnp</Abstract>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2006, Intel Corporation. All right reserved.</Copyright>
|
||||
<License>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.</License>
|
||||
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
|
||||
</MsaHeader>
|
||||
<ModuleDefinitions>
|
||||
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
|
||||
<BinaryModule>false</BinaryModule>
|
||||
<OutputFileBasename>MnpDxe</OutputFileBasename>
|
||||
</ModuleDefinitions>
|
||||
<LibraryClassDefinitions>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>DebugLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiDriverEntryPoint</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiBootServicesTableLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiLib</Keyword>
|
||||
</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>MnpImpl.h</Filename>
|
||||
<Filename>MnpConfig.c</Filename>
|
||||
<Filename>MnpDriver.c</Filename>
|
||||
<Filename>ComponentName.c</Filename>
|
||||
<Filename>MnpDriver.h</Filename>
|
||||
<Filename>MnpIo.c</Filename>
|
||||
<Filename>MnpMain.c</Filename>
|
||||
<Filename>MnpDebug.h</Filename>
|
||||
</SourceFiles>
|
||||
<PackageDependencies>
|
||||
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
|
||||
</PackageDependencies>
|
||||
<Protocols>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiManagedNetworkProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiSimpleNetworkProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiManagedNetworkServiceBindingProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
</Protocols>
|
||||
<Externs>
|
||||
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
|
||||
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
|
||||
<Extern>
|
||||
<ModuleEntryPoint>MnpDriverEntryPoint</ModuleEntryPoint>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
|
@ -0,0 +1,274 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
MnpImpl.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _MNP_IMPL_H_
|
||||
#define _MNP_IMPL_H_
|
||||
|
||||
#include "MnpDriver.h"
|
||||
#include "MnpDebug.h"
|
||||
|
||||
#define NET_ETHER_FCS_SIZE 4
|
||||
|
||||
#define MNP_SYS_POLL_INTERVAL (2 * TICKS_PER_MS) // 2 milliseconds
|
||||
#define MNP_TIMEOUT_CHECK_INTERVAL (50 * TICKS_PER_MS) // 50 milliseconds
|
||||
#define MNP_TX_TIMEOUT_TIME (500 * TICKS_PER_MS) // 500 milliseconds
|
||||
#define MNP_INIT_NET_BUFFER_NUM 512
|
||||
#define MNP_NET_BUFFER_INCREASEMENT 64
|
||||
#define MNP_MAX_NET_BUFFER_NUM 65536
|
||||
|
||||
#define MNP_MAX_RCVD_PACKET_QUE_SIZE 256
|
||||
|
||||
#define MNP_RECEIVE_UNICAST 0x01
|
||||
#define MNP_RECEIVE_BROADCAST 0x02
|
||||
|
||||
#define UNICAST_PACKET MNP_RECEIVE_UNICAST
|
||||
#define BROADCAST_PACKET MNP_RECEIVE_BROADCAST
|
||||
|
||||
#define MNP_INSTANCE_DATA_SIGNATURE EFI_SIGNATURE_32 ('M', 'n', 'p', 'I')
|
||||
|
||||
#define MNP_INSTANCE_DATA_FROM_THIS(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
MNP_INSTANCE_DATA, \
|
||||
ManagedNetwork, \
|
||||
MNP_INSTANCE_DATA_SIGNATURE \
|
||||
)
|
||||
|
||||
typedef struct _MNP_INSTANCE_DATA {
|
||||
UINT32 Signature;
|
||||
|
||||
MNP_SERVICE_DATA *MnpServiceData;
|
||||
|
||||
EFI_HANDLE Handle;
|
||||
|
||||
NET_LIST_ENTRY InstEntry;
|
||||
|
||||
EFI_MANAGED_NETWORK_PROTOCOL ManagedNetwork;
|
||||
|
||||
BOOLEAN Configured;
|
||||
BOOLEAN Destroyed;
|
||||
|
||||
NET_LIST_ENTRY GroupCtrlBlkList;
|
||||
|
||||
NET_MAP RxTokenMap;
|
||||
|
||||
NET_LIST_ENTRY RxDeliveredPacketQueue;
|
||||
NET_LIST_ENTRY RcvdPacketQueue;
|
||||
UINTN RcvdPacketQueueSize;
|
||||
|
||||
EFI_MANAGED_NETWORK_CONFIG_DATA ConfigData;
|
||||
|
||||
UINT8 ReceiveFilter;
|
||||
} MNP_INSTANCE_DATA;
|
||||
|
||||
typedef struct _MNP_GROUP_ADDRESS {
|
||||
NET_LIST_ENTRY AddrEntry;
|
||||
EFI_MAC_ADDRESS Address;
|
||||
INTN RefCnt;
|
||||
} MNP_GROUP_ADDRESS;
|
||||
|
||||
typedef struct _MNP_GROUP_CONTROL_BLOCK {
|
||||
NET_LIST_ENTRY CtrlBlkEntry;
|
||||
MNP_GROUP_ADDRESS *GroupAddress;
|
||||
} MNP_GROUP_CONTROL_BLOCK;
|
||||
|
||||
typedef struct _MNP_RXDATA_WRAP {
|
||||
NET_LIST_ENTRY WrapEntry;
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
EFI_MANAGED_NETWORK_RECEIVE_DATA RxData;
|
||||
NET_BUF *Nbuf;
|
||||
UINT64 TimeoutTick;
|
||||
} MNP_RXDATA_WRAP;
|
||||
|
||||
EFI_STATUS
|
||||
MnpInitializeServiceData (
|
||||
IN MNP_SERVICE_DATA *MnpServiceData,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_HANDLE ControllerHandle
|
||||
);
|
||||
|
||||
VOID
|
||||
MnpFlushServiceData (
|
||||
MNP_SERVICE_DATA *MnpServiceData
|
||||
);
|
||||
|
||||
VOID
|
||||
MnpInitializeInstanceData (
|
||||
IN MNP_SERVICE_DATA *MnpServiceData,
|
||||
IN MNP_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
MnpTokenExist (
|
||||
IN NET_MAP *Map,
|
||||
IN NET_MAP_ITEM *Item,
|
||||
IN VOID *Arg
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
MnpCancelTokens (
|
||||
IN NET_MAP *Map,
|
||||
IN NET_MAP_ITEM *Item,
|
||||
IN VOID *Arg
|
||||
);
|
||||
|
||||
VOID
|
||||
MnpFlushRcvdDataQueue (
|
||||
IN MNP_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
MnpConfigureInstance (
|
||||
IN MNP_INSTANCE_DATA *Instance,
|
||||
IN EFI_MANAGED_NETWORK_CONFIG_DATA *ConfigData OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
MnpGroupOp (
|
||||
IN MNP_INSTANCE_DATA *Instance,
|
||||
IN BOOLEAN JoinFlag,
|
||||
IN EFI_MAC_ADDRESS *MacAddr OPTIONAL,
|
||||
IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk OPTIONAL
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
MnpIsValidTxToken (
|
||||
IN MNP_INSTANCE_DATA *Instance,
|
||||
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
|
||||
);
|
||||
|
||||
VOID
|
||||
MnpBuildTxPacket (
|
||||
IN MNP_SERVICE_DATA *MnpServiceData,
|
||||
IN EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData,
|
||||
OUT UINT8 **PktBuf,
|
||||
OUT UINT32 *PktLen
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
MnpSyncSendPacket (
|
||||
IN MNP_SERVICE_DATA *MnpServiceData,
|
||||
IN UINT8 *Packet,
|
||||
IN UINT32 Length,
|
||||
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
MnpInstanceDeliverPacket (
|
||||
IN MNP_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
MnpRecycleRxData (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
MnpReceivePacket (
|
||||
IN MNP_SERVICE_DATA *MnpServiceData
|
||||
);
|
||||
|
||||
NET_BUF *
|
||||
MnpAllocNbuf (
|
||||
IN MNP_SERVICE_DATA *MnpServiceData
|
||||
);
|
||||
|
||||
VOID
|
||||
MnpFreeNbuf (
|
||||
IN MNP_SERVICE_DATA *MnpServiceData,
|
||||
IN NET_BUF *Nbuf
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
MnpCheckPacketTimeout (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
MnpSystemPoll (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpGetModeData (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
|
||||
OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpConfigure (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpMcastIpToMac (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN BOOLEAN Ipv6Flag,
|
||||
IN EFI_IP_ADDRESS *IpAddress,
|
||||
OUT EFI_MAC_ADDRESS *MacAddress
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpGroups (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN BOOLEAN JoinFlag,
|
||||
IN EFI_MAC_ADDRESS *MacAddress OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpTransmit (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpCancel (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpReceive (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpPoll (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This
|
||||
);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,655 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
MnpMain.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Implementation of Managed Network Protocol public services.
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
|
||||
#include "MnpImpl.h"
|
||||
|
||||
|
||||
/**
|
||||
Get configuration data of this instance.
|
||||
|
||||
@param This Pointer to the Managed Network Protocol.
|
||||
@param MnpConfigData Pointer to strorage for MNP operational
|
||||
parameters.
|
||||
@param SnpModeData Pointer to strorage for SNP operational
|
||||
parameters.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_STARTED This MNP child driver instance has not been
|
||||
configured The default values are returned in
|
||||
MnpConfigData if it is not NULL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpGetModeData (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
|
||||
OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
|
||||
)
|
||||
{
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (This == NULL) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if (MnpConfigData != NULL) {
|
||||
//
|
||||
// Copy the instance configuration data.
|
||||
//
|
||||
*MnpConfigData = Instance->ConfigData;
|
||||
}
|
||||
|
||||
if (SnpModeData != NULL) {
|
||||
//
|
||||
// Copy the underlayer Snp mode data.
|
||||
//
|
||||
Snp = Instance->MnpServiceData->Snp;
|
||||
*SnpModeData = *(Snp->Mode);
|
||||
}
|
||||
|
||||
if (!Instance->Configured) {
|
||||
Status = EFI_NOT_STARTED;
|
||||
} else {
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Set or clear the operational parameters for the MNP child driver.
|
||||
|
||||
@param This Pointer to the Managed Network Protocol.
|
||||
@param MnpConfigData Pointer to the configuration data that will be
|
||||
assigned to the MNP child driver instance. If
|
||||
NULL, the MNP child driver instance is reset to
|
||||
startup defaults and all pending transmit and
|
||||
receive requests are flushed.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameter is invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources (usually memory) could
|
||||
not be allocated.
|
||||
@retval EFI_UNSUPPORTED EnableReceiveTimestamps is TRUE, this
|
||||
implementation doesn't support it.
|
||||
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
|
||||
@retval Other The MNP child driver instance has been reset to
|
||||
startup defaults.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpConfigure (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL
|
||||
)
|
||||
{
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if ((This == NULL) ||
|
||||
((MnpConfigData != NULL) &&
|
||||
(MnpConfigData->ProtocolTypeFilter > 0) &&
|
||||
(MnpConfigData->ProtocolTypeFilter <= 1500))) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if ((MnpConfigData == NULL) && (!Instance->Configured)) {
|
||||
//
|
||||
// If the instance is not configured and a reset is requested, just return.
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Configure the instance.
|
||||
//
|
||||
Status = MnpConfigureInstance (Instance, MnpConfigData);
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Translate a multicast IP address to a multicast hardware (MAC) address.
|
||||
|
||||
@param This Pointer to the Managed Network Protocol.
|
||||
@param Ipv6Flag Set to TRUE if IpAddress is an IPv6 multicast
|
||||
address. Set to FALSE if IpAddress is an IPv4
|
||||
multicast address.
|
||||
@param IpAddress Pointer to the multicast IP address to convert.
|
||||
@param MacAddress Pointer to the resulting multicast MAC address.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameter is invalid.
|
||||
@retval EFI_NOT_STARTED This MNP child driver instance has not been
|
||||
configured.
|
||||
@retval EFI_UNSUPPORTED Ipv6Flag is TRUE, this implementation doesn't
|
||||
supported it.
|
||||
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
|
||||
@retval Other The address could not be converted.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpMcastIpToMac (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN BOOLEAN Ipv6Flag,
|
||||
IN EFI_IP_ADDRESS *IpAddress,
|
||||
OUT EFI_MAC_ADDRESS *MacAddress
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (IpAddress == NULL) || (MacAddress == NULL)) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Ipv6Flag) {
|
||||
//
|
||||
// Currently IPv6 isn't supported.
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (!IP4_IS_MULTICAST (EFI_NTOHL (*IpAddress))) {
|
||||
//
|
||||
// The IPv4 address passed in is not a multicast address.
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Snp = Instance->MnpServiceData->Snp;
|
||||
ASSERT (Snp != NULL);
|
||||
|
||||
if (Snp->Mode->IfType == NET_IFTYPE_ETHERNET) {
|
||||
//
|
||||
// Translate the IPv4 address into a multicast MAC address if the NIC is an
|
||||
// ethernet NIC.
|
||||
//
|
||||
MacAddress->Addr[0] = 0x01;
|
||||
MacAddress->Addr[1] = 0x00;
|
||||
MacAddress->Addr[2] = 0x5E;
|
||||
MacAddress->Addr[3] = IpAddress->v4.Addr[1] & 0x7F;
|
||||
MacAddress->Addr[4] = IpAddress->v4.Addr[2];
|
||||
MacAddress->Addr[5] = IpAddress->v4.Addr[3];
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
} else {
|
||||
//
|
||||
// Invoke Snp to translate the multicast IP address.
|
||||
//
|
||||
Status = Snp->MCastIpToMac (
|
||||
Snp,
|
||||
Ipv6Flag,
|
||||
IpAddress,
|
||||
MacAddress
|
||||
);
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Enable or disable receie filters for multicast address.
|
||||
|
||||
@param This Pointer to the Managed Network Protocol.
|
||||
@param JoinFlag Set to TRUE to join this multicast group. Set to
|
||||
FALSE to leave this multicast group.
|
||||
@param MacAddress Pointer to the multicast MAC group (address) to
|
||||
join or leave.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameter is invalid
|
||||
@retval EFI_NOT_STARTED This MNP child driver instance has not been
|
||||
configured.
|
||||
@retval EFI_ALREADY_STARTED The supplied multicast group is already joined.
|
||||
@retval EFI_NOT_FOUND The supplied multicast group is not joined.
|
||||
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
|
||||
@retval Other The requested operation could not be completed.
|
||||
The MNP multicast group settings are unchanged.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpGroups (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN BOOLEAN JoinFlag,
|
||||
IN EFI_MAC_ADDRESS *MacAddress OPTIONAL
|
||||
)
|
||||
{
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
EFI_SIMPLE_NETWORK_MODE *SnpMode;
|
||||
MNP_GROUP_CONTROL_BLOCK *GroupCtrlBlk;
|
||||
MNP_GROUP_ADDRESS *GroupAddress;
|
||||
NET_LIST_ENTRY *ListEntry;
|
||||
BOOLEAN AddressExist;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (This == NULL || (JoinFlag && (MacAddress == NULL))) {
|
||||
//
|
||||
// This is NULL, or it's a join operation but MacAddress is NULL.
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
|
||||
SnpMode = Instance->MnpServiceData->Snp->Mode;
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if ((!Instance->ConfigData.EnableMulticastReceive) ||
|
||||
((MacAddress != NULL) && !NET_MAC_IS_MULTICAST (MacAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize))) {
|
||||
//
|
||||
// The instance isn't configured to do mulitcast receive. OR
|
||||
// the passed in MacAddress is not a mutlticast mac address.
|
||||
//
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
AddressExist = FALSE;
|
||||
GroupCtrlBlk = NULL;
|
||||
|
||||
if (MacAddress != NULL) {
|
||||
//
|
||||
// Search the instance's GroupCtrlBlkList to find the specific address.
|
||||
//
|
||||
NET_LIST_FOR_EACH (ListEntry, &Instance->GroupCtrlBlkList) {
|
||||
|
||||
GroupCtrlBlk = NET_LIST_USER_STRUCT (
|
||||
ListEntry,
|
||||
MNP_GROUP_CONTROL_BLOCK,
|
||||
CtrlBlkEntry
|
||||
);
|
||||
GroupAddress = GroupCtrlBlk->GroupAddress;
|
||||
if (0 == NetCompareMem (
|
||||
MacAddress,
|
||||
&GroupAddress->Address,
|
||||
SnpMode->HwAddressSize
|
||||
)) {
|
||||
//
|
||||
// There is already the same multicast mac address configured.
|
||||
//
|
||||
AddressExist = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (JoinFlag && AddressExist) {
|
||||
//
|
||||
// The multicast mac address to join already exists.
|
||||
//
|
||||
Status = EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
if (!JoinFlag && !AddressExist) {
|
||||
//
|
||||
// The multicast mac address to leave doesn't exist in this instance.
|
||||
//
|
||||
Status = EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
} else if (NetListIsEmpty (&Instance->GroupCtrlBlkList)) {
|
||||
//
|
||||
// The MacAddress is NULL and there is no configured multicast mac address,
|
||||
// just return.
|
||||
//
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// OK, it is time to take action.
|
||||
//
|
||||
Status = MnpGroupOp (Instance, JoinFlag, MacAddress, GroupCtrlBlk);
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Place an outgoing packet into the transmit queue.
|
||||
|
||||
@param This Pointer to the Managed Network Protocol.
|
||||
@param Token Pointer to a token associated with the transmit
|
||||
data descriptor.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameter is invalid
|
||||
@retval EFI_NOT_STARTED This MNP child driver instance has not been
|
||||
configured.
|
||||
@retval EFI_ACCESS_DENIED The transmit completion token is already in the
|
||||
transmit queue.
|
||||
@retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a
|
||||
lack of system resources (usually memory).
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
The MNP child driver instance has been reset to
|
||||
startup defaults.
|
||||
@retval EFI_NOT_READY The transmit request could not be queued because
|
||||
the transmit queue is full.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpTransmit (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
MNP_SERVICE_DATA *MnpServiceData;
|
||||
UINT8 *PktBuf;
|
||||
UINT32 PktLen;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (Token == NULL)) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (!MnpIsValidTxToken (Instance, Token)) {
|
||||
//
|
||||
// The Token is invalid.
|
||||
//
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
MnpServiceData = Instance->MnpServiceData;
|
||||
NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
|
||||
|
||||
//
|
||||
// Build the tx packet
|
||||
//
|
||||
MnpBuildTxPacket (MnpServiceData, Token->Packet.TxData, &PktBuf, &PktLen);
|
||||
|
||||
//
|
||||
// OK, send the packet synchronously.
|
||||
//
|
||||
Status = MnpSyncSendPacket (MnpServiceData, PktBuf, PktLen, Token);
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Place an asynchronous receiving request into the receiving queue.
|
||||
|
||||
@param This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL
|
||||
instance.
|
||||
@param Token Pointer to a token associated with the receive
|
||||
data descriptor.
|
||||
|
||||
@retval EFI_SUCCESS The receive completion token was cached.
|
||||
@retval EFI_NOT_STARTED This MNP child driver instance has not been
|
||||
configured.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameter is invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a
|
||||
lack of system resources (usually memory).
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
The MNP child driver instance has been reset to
|
||||
startup defaults.
|
||||
@retval EFI_ACCESS_DENIED The receive completion token was already in the
|
||||
receive queue.
|
||||
@retval EFI_NOT_READY The receive request could not be queued because
|
||||
the receive queue is full.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpReceive (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (Token == NULL) || (Token->Event == NULL)) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether this token(event) is already in the rx token queue.
|
||||
//
|
||||
Status = NetMapIterate (&Instance->RxTokenMap, MnpTokenExist, (VOID *) Token);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Insert the Token into the RxTokenMap.
|
||||
//
|
||||
Status = NetMapInsertTail (&Instance->RxTokenMap, (VOID *) Token, NULL);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Try to deliver any buffered packets.
|
||||
//
|
||||
Status = MnpInstanceDeliverPacket (Instance);
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Abort a pending transmit or receive request.
|
||||
|
||||
@param This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL
|
||||
instance.
|
||||
@param Token Pointer to a token that has been issued by
|
||||
EFI_MANAGED_NETWORK_PROTOCOL.Transmit() or
|
||||
EFI_MANAGED_NETWORK_PROTOCOL.Receive(). If NULL,
|
||||
all pending tokens are aborted.
|
||||
|
||||
@retval EFI_SUCCESS The asynchronous I/O request was aborted and
|
||||
Token->Event was signaled.
|
||||
@retval EFI_NOT_STARTED This MNP child driver instance has not been
|
||||
configured.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_FOUND The asynchronous I/O request was not found in the
|
||||
transmit or receive queue. It has either completed
|
||||
or was not issued by Transmit() and Receive().
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpCancel (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This,
|
||||
IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Iterate the RxTokenMap to cancel the specified Token.
|
||||
//
|
||||
Status = NetMapIterate (&Instance->RxTokenMap, MnpCancelTokens, (VOID *) Token);
|
||||
|
||||
if (Token != NULL) {
|
||||
|
||||
Status = (Status == EFI_ABORTED) ? EFI_SUCCESS : EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Poll the network interface to do transmit/receive work.
|
||||
|
||||
@param This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL
|
||||
instance.
|
||||
|
||||
@retval EFI_SUCCESS Incoming or outgoing data was processed.
|
||||
@retval EFI_NOT_STARTED This MNP child driver instance has not been
|
||||
configured.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
The MNP child driver instance has been reset to
|
||||
startup defaults.
|
||||
@retval EFI_NOT_READY No incoming or outgoing data was processed.
|
||||
@retval EFI_TIMEOUT Data was dropped out of the transmit and/or
|
||||
receive queue.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MnpPoll (
|
||||
IN EFI_MANAGED_NETWORK_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
MNP_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to receive packets.
|
||||
//
|
||||
Status = MnpReceivePacket (Instance->MnpServiceData);
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
ComponentName.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SimpleNetworkComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SimpleNetworkComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
//
|
||||
// EFI Component Name Protocol
|
||||
//
|
||||
EFI_COMPONENT_NAME_PROTOCOL gSimpleNetworkComponentName = {
|
||||
SimpleNetworkComponentNameGetDriverName,
|
||||
SimpleNetworkComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
static EFI_UNICODE_STRING_TABLE mSimpleNetworkDriverNameTable[] = {
|
||||
{
|
||||
"eng",
|
||||
L"Simple Network Protocol Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SimpleNetworkComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves a Unicode string that is the user readable name of the EFI Driver.
|
||||
|
||||
Arguments:
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
Language - A pointer to a three character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages specified
|
||||
in SupportedLanguages. The number of languages supported by a
|
||||
driver is up to the driver writer.
|
||||
DriverName - A pointer to the Unicode string to return. This Unicode string
|
||||
is the name of the driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - DriverName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return LookupUnicodeString (
|
||||
Language,
|
||||
gSimpleNetworkComponentName.SupportedLanguages,
|
||||
mSimpleNetworkDriverNameTable,
|
||||
DriverName
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SimpleNetworkComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
Arguments:
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
ControllerHandle - The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
ChildHandle - The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL. It
|
||||
will be NULL for device drivers. It will also be NULL
|
||||
for a bus drivers that wish to retrieve the name of the
|
||||
bus controller. It will not be NULL for a bus driver
|
||||
that wishes to retrieve the name of a child controller.
|
||||
Language - A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller name
|
||||
that that the caller is requesting, and it must match one
|
||||
of the languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up to the
|
||||
driver writer.
|
||||
ControllerName - A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language specified
|
||||
by Language from the point of view of the driver specified
|
||||
by This.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The Unicode string for the user readable name in the
|
||||
language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - ControllerName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This is not currently managing
|
||||
the controller specified by ControllerHandle and
|
||||
ChildHandle.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
#/** @file
|
||||
# Component name for module SNP
|
||||
#
|
||||
# FIX ME!
|
||||
# Copyright (c) 2006, Intel Corporation. All right reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SnpDxe
|
||||
FILE_GUID = A2f436EA-A127-4EF8-957C-8048606FF670
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = InitializeSnpNiiDriver
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources.common]
|
||||
receive.c
|
||||
snp.h
|
||||
nvdata.c
|
||||
get_status.c
|
||||
start.c
|
||||
snp.c
|
||||
stop.c
|
||||
statistics.c
|
||||
reset.c
|
||||
shutdown.c
|
||||
mcast_ip_to_mac.c
|
||||
transmit.c
|
||||
WaitForPacket.c
|
||||
receive_filters.c
|
||||
initialize.c
|
||||
ComponentName.c
|
||||
callback.c
|
||||
station_address.c
|
||||
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
UefiLib
|
||||
BaseLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
|
||||
|
||||
[Protocols]
|
||||
gEfiPciIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiSimpleNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiNetworkInterfaceIdentifierProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiNetworkInterfaceIdentifierProtocolGuid_31 # PROTOCOL ALWAYS_CONSUMED
|
|
@ -0,0 +1,90 @@
|
|||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<MsaHeader>
|
||||
<ModuleName>SnpDxe</ModuleName>
|
||||
<ModuleType>DXE_DRIVER</ModuleType>
|
||||
<GuidValue>A2f436EA-A127-4EF8-957C-8048606FF670</GuidValue>
|
||||
<Version>1.0</Version>
|
||||
<Abstract>Component name for module SNP</Abstract>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2006, Intel Corporation. All right reserved.</Copyright>
|
||||
<License>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.</License>
|
||||
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
|
||||
</MsaHeader>
|
||||
<ModuleDefinitions>
|
||||
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
|
||||
<BinaryModule>false</BinaryModule>
|
||||
<OutputFileBasename>SnpDxe</OutputFileBasename>
|
||||
</ModuleDefinitions>
|
||||
<LibraryClassDefinitions>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>DebugLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>BaseMemoryLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiDriverEntryPoint</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiBootServicesTableLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>BaseLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiLib</Keyword>
|
||||
</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>station_address.c</Filename>
|
||||
<Filename>SNPEntry.c</Filename>
|
||||
<Filename>callback.c</Filename>
|
||||
<Filename>ComponentName.c</Filename>
|
||||
<Filename>initialize.c</Filename>
|
||||
<Filename>receive_filters.c</Filename>
|
||||
<Filename>WaitForPacket.c</Filename>
|
||||
<Filename>transmit.c</Filename>
|
||||
<Filename>mcast_ip_to_mac.c</Filename>
|
||||
<Filename>shutdown.c</Filename>
|
||||
<Filename>reset.c</Filename>
|
||||
<Filename>statistics.c</Filename>
|
||||
<Filename>stop.c</Filename>
|
||||
<Filename>snp.c</Filename>
|
||||
<Filename>start.c</Filename>
|
||||
<Filename>get_status.c</Filename>
|
||||
<Filename>nvdata.c</Filename>
|
||||
<Filename>snp.h</Filename>
|
||||
<Filename>receive.c</Filename>
|
||||
</SourceFiles>
|
||||
<PackageDependencies>
|
||||
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
|
||||
</PackageDependencies>
|
||||
<Protocols>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiNetworkInterfaceIdentifierProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiSimpleNetworkProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiPciIoProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
</Protocols>
|
||||
<Externs>
|
||||
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
|
||||
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
|
||||
<Extern>
|
||||
<ModuleEntryPoint>InitializeSnpNiiDriver</ModuleEntryPoint>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
|
@ -0,0 +1,97 @@
|
|||
/** @file
|
||||
Copyright (c) 2004, Intel Corporation
|
||||
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:
|
||||
WaitForPacket.c
|
||||
|
||||
Abstract:
|
||||
Event handler to check for available packet.
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
|
||||
/**
|
||||
|
||||
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpWaitForPacketNotify (
|
||||
EFI_EVENT Event,
|
||||
VOID *SnpPtr
|
||||
)
|
||||
{
|
||||
PXE_DB_GET_STATUS PxeDbGetStatus;
|
||||
|
||||
//
|
||||
// Do nothing if either parameter is a NULL pointer.
|
||||
//
|
||||
if (Event == NULL || SnpPtr == NULL) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// Do nothing if the SNP interface is not initialized.
|
||||
//
|
||||
switch (((SNP_DRIVER *) SnpPtr)->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
case EfiSimpleNetworkStarted:
|
||||
default:
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// Fill in CDB for UNDI GetStatus().
|
||||
//
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.OpCode = PXE_OPCODE_GET_STATUS;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.OpFlags = 0;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.DBsize = sizeof (UINT32) * 2;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.DBaddr = (UINT64)(UINTN) (((SNP_DRIVER *) SnpPtr)->db);
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.IFnum = ((SNP_DRIVER *) SnpPtr)->if_num;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Clear contents of DB buffer.
|
||||
//
|
||||
ZeroMem (((SNP_DRIVER *) SnpPtr)->db, sizeof (UINT32) * 2);
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
(*((SNP_DRIVER *) SnpPtr)->issue_undi32_command) ((UINT64)(UINTN) &((SNP_DRIVER *) SnpPtr)->cdb);
|
||||
|
||||
if (((SNP_DRIVER *) SnpPtr)->cdb.StatCode != EFI_SUCCESS) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// We might have a packet. Check the receive length and signal
|
||||
// the event if the length is not zero.
|
||||
//
|
||||
CopyMem (
|
||||
&PxeDbGetStatus,
|
||||
((SNP_DRIVER *) SnpPtr)->db,
|
||||
sizeof (UINT32) * 2
|
||||
);
|
||||
|
||||
if (PxeDbGetStatus.RxFrameLen != 0) {
|
||||
gBS->SignalEvent (Event);
|
||||
}
|
||||
}
|
||||
|
||||
/* eof - WaitForPacket.c */
|
|
@ -0,0 +1,611 @@
|
|||
/*++
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
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:
|
||||
callback.c
|
||||
|
||||
Abstract:
|
||||
This file contains two sets of callback routines for undi3.0 and undi3.1.
|
||||
the callback routines for Undi3.1 have an extra parameter UniqueId which
|
||||
stores the interface context for the NIC that snp is trying to talk..
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
//
|
||||
// Global variables
|
||||
// these 2 global variables are used only for 3.0 undi. we could not place
|
||||
// them in the snp structure because we will not know which snp structure
|
||||
// in the callback context!
|
||||
//
|
||||
STATIC BOOLEAN mInitializeLock = TRUE;
|
||||
STATIC EFI_LOCK mLock;
|
||||
|
||||
//
|
||||
// End Global variables
|
||||
//
|
||||
extern EFI_PCI_IO_PROTOCOL *mPciIoFncs;
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_v2p_30 (
|
||||
IN UINT64 CpuAddr,
|
||||
IN OUT UINT64 DeviceAddrPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine with a virtual or CPU address that SNP provided
|
||||
to convert it to a physical or device address. Since EFI uses the identical
|
||||
mapping, this routine returns the physical address same as the virtual address
|
||||
for most of the addresses. an address above 4GB cannot generally be used as a
|
||||
device address, it needs to be mapped to a lower physical address. This routine
|
||||
does not call the map routine itself, but it assumes that the mapping was done
|
||||
at the time of providing the address to UNDI. This routine just looks up the
|
||||
address in a map table (which is the v2p structure chain)
|
||||
|
||||
Arguments:
|
||||
CpuAddr - virtual address of a buffer
|
||||
DeviceAddrPtr - pointer to the physical address
|
||||
|
||||
Returns:
|
||||
void - The DeviceAddrPtr will contain 0 in case of any error
|
||||
|
||||
--*/
|
||||
{
|
||||
struct s_v2p *v2p;
|
||||
//
|
||||
// Do nothing if virtual address is zero or physical pointer is NULL.
|
||||
// No need to map if the virtual address is within 4GB limit since
|
||||
// EFI uses identical mapping
|
||||
//
|
||||
if ((CpuAddr == 0) || (DeviceAddrPtr == 0)) {
|
||||
DEBUG ((EFI_D_ERROR, "\nv2p: Null virtual address or physical pointer.\n"));
|
||||
return ;
|
||||
}
|
||||
|
||||
if (CpuAddr < FOUR_GIGABYTES) {
|
||||
*(UINT64 *) (UINTN) DeviceAddrPtr = CpuAddr;
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// SNP creates a vaddr tp paddr mapping at the time of calling undi with any
|
||||
// big address, this callback routine just looks up in the v2p list and
|
||||
// returns the physical address for any given virtual address.
|
||||
//
|
||||
if (find_v2p (&v2p, (VOID *) (UINTN) CpuAddr) != EFI_SUCCESS) {
|
||||
*(UINT64 *) (UINTN) DeviceAddrPtr = CpuAddr;
|
||||
} else {
|
||||
*(UINT64 *) (UINTN) DeviceAddrPtr = v2p->paddr;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_block_30 (
|
||||
IN UINT32 Enable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine when it wants to have exclusive access to a critical
|
||||
section of the code/data
|
||||
|
||||
Arguments:
|
||||
Enable - non-zero indicates acquire
|
||||
zero indicates release
|
||||
|
||||
Returns:
|
||||
void
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// tcpip was calling snp at tpl_notify and if we acquire a lock that was
|
||||
// created at a lower level (TPL_CALLBACK) it gives an assert!
|
||||
//
|
||||
if (mInitializeLock) {
|
||||
EfiInitializeLock (&mLock, TPL_NOTIFY);
|
||||
mInitializeLock = FALSE;
|
||||
}
|
||||
|
||||
if (Enable != 0) {
|
||||
EfiAcquireLock (&mLock);
|
||||
} else {
|
||||
EfiReleaseLock (&mLock);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_delay_30 (
|
||||
IN UINT64 MicroSeconds
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine with the number of micro seconds when it wants to
|
||||
pause.
|
||||
|
||||
Arguments:
|
||||
MicroSeconds - number of micro seconds to pause, ususlly multiple of 10
|
||||
|
||||
Returns:
|
||||
void
|
||||
--*/
|
||||
{
|
||||
if (MicroSeconds != 0) {
|
||||
gBS->Stall ((UINTN) MicroSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_memio_30 (
|
||||
IN UINT8 ReadOrWrite,
|
||||
IN UINT8 NumBytes,
|
||||
IN UINT64 Address,
|
||||
IN OUT UINT64 BufferAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
This is the IO routine for UNDI. This is not currently being used by UNDI3.0
|
||||
because Undi3.0 uses io/mem offsets relative to the beginning of the device
|
||||
io/mem address and so it needs to use the PCI_IO_FUNCTION that abstracts the
|
||||
start of the device's io/mem addresses. Since SNP cannot retrive the context
|
||||
of the undi3.0 interface it cannot use the PCI_IO_FUNCTION that specific for
|
||||
that NIC and uses one global IO functions structure, this does not work.
|
||||
This however works fine for EFI1.0 Undis because they use absolute addresses
|
||||
for io/mem access.
|
||||
|
||||
Arguments:
|
||||
ReadOrWrite - indicates read or write, IO or Memory
|
||||
NumBytes - number of bytes to read or write
|
||||
Address - IO or memory address to read from or write to
|
||||
BufferAddr - memory location to read into or that contains the bytes
|
||||
to write
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_PCI_IO_PROTOCOL_WIDTH Width;
|
||||
|
||||
switch (NumBytes) {
|
||||
case 2:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 2;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 0;
|
||||
}
|
||||
|
||||
switch (ReadOrWrite) {
|
||||
case PXE_IO_READ:
|
||||
mPciIoFncs->Io.Read (
|
||||
mPciIoFncs,
|
||||
Width,
|
||||
1, // BAR 1, IO base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_IO_WRITE:
|
||||
mPciIoFncs->Io.Write (
|
||||
mPciIoFncs,
|
||||
Width,
|
||||
1, // BAR 1, IO base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_MEM_READ:
|
||||
mPciIoFncs->Mem.Read (
|
||||
mPciIoFncs,
|
||||
Width,
|
||||
0, // BAR 0, Memory base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_MEM_WRITE:
|
||||
mPciIoFncs->Mem.Write (
|
||||
mPciIoFncs,
|
||||
Width,
|
||||
0, // BAR 0, Memory base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// New callbacks for 3.1:
|
||||
// there won't be a virtual2physical callback for UNDI 3.1 because undi3.1 uses
|
||||
// the MemMap call to map the required address by itself!
|
||||
//
|
||||
VOID
|
||||
snp_undi32_callback_block (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT32 Enable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI3.1 at undi_start time.
|
||||
UNDI call this routine when it wants to have exclusive access to a critical
|
||||
section of the code/data
|
||||
|
||||
Arguments:
|
||||
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
|
||||
Undi interface context (Undi does not read or write this variable)
|
||||
Enable - non-zero indicates acquire
|
||||
zero indicates release
|
||||
|
||||
Returns:
|
||||
void
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
|
||||
snp = (SNP_DRIVER *) (UINTN) UniqueId;
|
||||
//
|
||||
// tcpip was calling snp at tpl_notify and when we acquire a lock that was
|
||||
// created at a lower level (TPL_CALLBACK) it gives an assert!
|
||||
//
|
||||
if (Enable != 0) {
|
||||
EfiAcquireLock (&snp->lock);
|
||||
} else {
|
||||
EfiReleaseLock (&snp->lock);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_delay (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 MicroSeconds
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine with the number of micro seconds when it wants to
|
||||
pause.
|
||||
|
||||
Arguments:
|
||||
MicroSeconds - number of micro seconds to pause, ususlly multiple of 10
|
||||
|
||||
Returns:
|
||||
void
|
||||
--*/
|
||||
{
|
||||
if (MicroSeconds != 0) {
|
||||
gBS->Stall ((UINTN) MicroSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* IO routine for UNDI start CPB.
|
||||
*/
|
||||
VOID
|
||||
snp_undi32_callback_memio (
|
||||
UINT64 UniqueId,
|
||||
UINT8 ReadOrWrite,
|
||||
UINT8 NumBytes,
|
||||
UINT64 Address,
|
||||
UINT64 BufferAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
This is the IO routine for UNDI3.1.
|
||||
|
||||
Arguments:
|
||||
ReadOrWrite - indicates read or write, IO or Memory
|
||||
NumBytes - number of bytes to read or write
|
||||
Address - IO or memory address to read from or write to
|
||||
BufferAddr - memory location to read into or that contains the bytes
|
||||
to write
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_PCI_IO_PROTOCOL_WIDTH Width;
|
||||
|
||||
snp = (SNP_DRIVER *) (UINTN) UniqueId;
|
||||
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 0;
|
||||
switch (NumBytes) {
|
||||
case 2:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 2;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 3;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ReadOrWrite) {
|
||||
case PXE_IO_READ:
|
||||
snp->IoFncs->Io.Read (
|
||||
snp->IoFncs,
|
||||
Width,
|
||||
snp->IoBarIndex, // BAR 1 (for 32bit regs), IO base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_IO_WRITE:
|
||||
snp->IoFncs->Io.Write (
|
||||
snp->IoFncs,
|
||||
Width,
|
||||
snp->IoBarIndex, // BAR 1 (for 32bit regs), IO base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_MEM_READ:
|
||||
snp->IoFncs->Mem.Read (
|
||||
snp->IoFncs,
|
||||
Width,
|
||||
snp->MemoryBarIndex, // BAR 0, Memory base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_MEM_WRITE:
|
||||
snp->IoFncs->Mem.Write (
|
||||
snp->IoFncs,
|
||||
Width,
|
||||
snp->MemoryBarIndex, // BAR 0, Memory base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_map (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 CpuAddr,
|
||||
IN UINT32 NumBytes,
|
||||
IN UINT32 Direction,
|
||||
IN OUT UINT64 DeviceAddrPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine when it has to map a CPU address to a device
|
||||
address.
|
||||
|
||||
Arguments:
|
||||
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
|
||||
Undi interface context (Undi does not read or write this variable)
|
||||
CpuAddr - Virtual address to be mapped!
|
||||
NumBytes - size of memory to be mapped
|
||||
Direction - direction of data flow for this memory's usage:
|
||||
cpu->device, device->cpu or both ways
|
||||
DeviceAddrPtr - pointer to return the mapped device address
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS *DevAddrPtr;
|
||||
EFI_PCI_IO_PROTOCOL_OPERATION DirectionFlag;
|
||||
UINTN BuffSize;
|
||||
SNP_DRIVER *snp;
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
|
||||
BuffSize = (UINTN) NumBytes;
|
||||
snp = (SNP_DRIVER *) (UINTN) UniqueId;
|
||||
DevAddrPtr = (EFI_PHYSICAL_ADDRESS *) (UINTN) DeviceAddrPtr;
|
||||
|
||||
if (CpuAddr == 0) {
|
||||
*DevAddrPtr = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
switch (Direction) {
|
||||
case TO_AND_FROM_DEVICE:
|
||||
DirectionFlag = EfiPciIoOperationBusMasterCommonBuffer;
|
||||
break;
|
||||
|
||||
case FROM_DEVICE:
|
||||
DirectionFlag = EfiPciIoOperationBusMasterWrite;
|
||||
break;
|
||||
|
||||
case TO_DEVICE:
|
||||
DirectionFlag = EfiPciIoOperationBusMasterRead;
|
||||
break;
|
||||
|
||||
default:
|
||||
*DevAddrPtr = 0;
|
||||
//
|
||||
// any non zero indicates error!
|
||||
//
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// find an unused map_list entry
|
||||
//
|
||||
for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
|
||||
if (snp->map_list[Index].virt == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index >= MAX_MAP_LENGTH) {
|
||||
DEBUG ((EFI_D_INFO, "SNP maplist is FULL\n"));
|
||||
*DevAddrPtr = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
snp->map_list[Index].virt = (EFI_PHYSICAL_ADDRESS) CpuAddr;
|
||||
|
||||
Status = snp->IoFncs->Map (
|
||||
snp->IoFncs,
|
||||
DirectionFlag,
|
||||
(VOID *) (UINTN) CpuAddr,
|
||||
&BuffSize,
|
||||
DevAddrPtr,
|
||||
&(snp->map_list[Index].map_cookie)
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
*DevAddrPtr = 0;
|
||||
snp->map_list[Index].virt = 0;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_unmap (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 CpuAddr,
|
||||
IN UINT32 NumBytes,
|
||||
IN UINT32 Direction,
|
||||
IN UINT64 DeviceAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine when it wants to unmap an address that was previously
|
||||
mapped using map callback
|
||||
|
||||
Arguments:
|
||||
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
|
||||
Undi interface context (Undi does not read or write this variable)
|
||||
CpuAddr - Virtual address that was mapped!
|
||||
NumBytes - size of memory mapped
|
||||
Direction- direction of data flow for this memory's usage:
|
||||
cpu->device, device->cpu or both ways
|
||||
DeviceAddr - the mapped device address
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
UINT16 Index;
|
||||
|
||||
snp = (SNP_DRIVER *) (UINTN) UniqueId;
|
||||
|
||||
for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
|
||||
if (snp->map_list[Index].virt == CpuAddr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index >= MAX_MAP_LENGTH)
|
||||
{
|
||||
DEBUG ((EFI_D_ERROR, "SNP could not find a mapping, failed to unmap.\n"));
|
||||
return ;
|
||||
}
|
||||
|
||||
snp->IoFncs->Unmap (snp->IoFncs, snp->map_list[Index].map_cookie);
|
||||
snp->map_list[Index].virt = 0;
|
||||
snp->map_list[Index].map_cookie = NULL;
|
||||
return ;
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_sync (
|
||||
UINT64 UniqueId,
|
||||
UINT64 CpuAddr,
|
||||
UINT32 NumBytes,
|
||||
UINT32 Direction,
|
||||
UINT64 DeviceAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine when it wants synchronize the virtual buffer contents
|
||||
with the mapped buffer contents. The virtual and mapped buffers need not
|
||||
correspond to the same physical memory (especially if the virtual address is
|
||||
> 4GB). Depending on the direction for which the buffer is mapped, undi will
|
||||
need to synchronize their contents whenever it writes to/reads from the buffer
|
||||
using either the cpu address or the device address.
|
||||
|
||||
EFI does not provide a sync call, since virt=physical, we sould just do
|
||||
the synchronization ourself here!
|
||||
|
||||
Arguments:
|
||||
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
|
||||
Undi interface context (Undi does not read or write this variable)
|
||||
CpuAddr - Virtual address that was mapped!
|
||||
NumBytes - size of memory mapped
|
||||
Direction- direction of data flow for this memory's usage:
|
||||
cpu->device, device->cpu or both ways
|
||||
DeviceAddr - the mapped device address
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
if ((CpuAddr == 0) || (DeviceAddr == 0) || (NumBytes == 0)) {
|
||||
return ;
|
||||
|
||||
}
|
||||
|
||||
switch (Direction) {
|
||||
case FROM_DEVICE:
|
||||
CopyMem ((UINT8 *) (UINTN) CpuAddr, (UINT8 *) (UINTN) DeviceAddr, NumBytes);
|
||||
break;
|
||||
|
||||
case TO_DEVICE:
|
||||
CopyMem ((UINT8 *) (UINTN) DeviceAddr, (UINT8 *) (UINTN) CpuAddr, NumBytes);
|
||||
break;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
get_status.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-03 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
STATIC
|
||||
/**
|
||||
this routine calls undi to get the status of the interrupts, get the list of
|
||||
transmit buffers that completed transmitting!
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
@param InterruptStatusPtr a non null pointer gets the interrupt status
|
||||
@param TransmitBufferListPtrs a non null ointer gets the list of pointers of
|
||||
previously transmitted buffers whose
|
||||
transmission was completed asynchrnously.
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
pxe_getstatus (
|
||||
SNP_DRIVER *snp,
|
||||
UINT32 *InterruptStatusPtr,
|
||||
VOID **TransmitBufferListPtr
|
||||
)
|
||||
{
|
||||
PXE_DB_GET_STATUS *db;
|
||||
UINT16 InterruptFlags;
|
||||
UINT64 TempData;
|
||||
|
||||
db = snp->db;
|
||||
snp->cdb.OpCode = PXE_OPCODE_GET_STATUS;
|
||||
|
||||
snp->cdb.OpFlags = 0;
|
||||
|
||||
if (TransmitBufferListPtr != NULL) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS;
|
||||
}
|
||||
|
||||
if (InterruptStatusPtr != NULL) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_GET_INTERRUPT_STATUS;
|
||||
}
|
||||
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
|
||||
//
|
||||
// size DB for return of one buffer
|
||||
//
|
||||
snp->cdb.DBsize = (UINT16) (((UINT16) (sizeof (PXE_DB_GET_STATUS)) - (UINT16) (sizeof db->TxBuffer)) + (UINT16) (sizeof db->TxBuffer[0]));
|
||||
|
||||
snp->cdb.DBaddr = (UINT64)(UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.get_status() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != EFI_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nsnp->undi.get_status() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatFlags)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// report the values back..
|
||||
//
|
||||
if (InterruptStatusPtr != NULL) {
|
||||
InterruptFlags = (UINT16) (snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK);
|
||||
|
||||
*InterruptStatusPtr = 0;
|
||||
|
||||
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_RECEIVE) {
|
||||
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
|
||||
}
|
||||
|
||||
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_TRANSMIT) {
|
||||
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
|
||||
}
|
||||
|
||||
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_COMMAND) {
|
||||
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;
|
||||
}
|
||||
|
||||
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_SOFTWARE) {
|
||||
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (TransmitBufferListPtr != NULL) {
|
||||
*TransmitBufferListPtr =
|
||||
(
|
||||
(snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN) ||
|
||||
(snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY)
|
||||
) ? 0 : (VOID *) (UINTN) db->TxBuffer[0];
|
||||
|
||||
TempData = (UINT64) (UINTN) (*TransmitBufferListPtr);
|
||||
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
|
||||
del_v2p ((VOID *) (UINTN) (db->TxBuffer[0]));
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for getting the status
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_getstatus routine to actually get the undi status
|
||||
|
||||
@param this context pointer
|
||||
@param InterruptStatusPtr a non null pointer gets the interrupt status
|
||||
@param TransmitBufferListPtrs a non null ointer gets the list of pointers of
|
||||
previously transmitted buffers whose
|
||||
transmission was completed asynchrnously.
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_get_status (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
OUT UINT32 *InterruptStatusPtr OPTIONAL,
|
||||
OUT VOID **TransmitBufferListPtr OPTIONAL
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (InterruptStatusPtr == NULL && TransmitBufferListPtr == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = pxe_getstatus (snp, InterruptStatusPtr, TransmitBufferListPtr);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
initialize.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-09 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpWaitForPacketNotify (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *SnpPtr
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
this routine calls undi to initialize the interface.
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
@param CableDetectFlag Do/don't detect the cable (depending on what undi
|
||||
supports)
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
pxe_init (
|
||||
SNP_DRIVER *snp,
|
||||
UINT16 CableDetectFlag
|
||||
)
|
||||
{
|
||||
PXE_CPB_INITIALIZE *cpb;
|
||||
VOID *addr;
|
||||
EFI_STATUS Status;
|
||||
|
||||
cpb = snp->cpb;
|
||||
if (snp->tx_rx_bufsize != 0) {
|
||||
Status = snp->IoFncs->AllocateBuffer (
|
||||
snp->IoFncs,
|
||||
AllocateAnyPages,
|
||||
EfiBootServicesData,
|
||||
SNP_MEM_PAGES (snp->tx_rx_bufsize),
|
||||
&addr,
|
||||
0
|
||||
);
|
||||
|
||||
if (Status != EFI_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->pxe_init() AllocateBuffer %xh (%r)\n",
|
||||
Status,
|
||||
Status)
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
ASSERT (addr);
|
||||
|
||||
snp->tx_rx_buffer = addr;
|
||||
}
|
||||
|
||||
cpb->MemoryAddr = (UINT64)(UINTN) snp->tx_rx_buffer;
|
||||
|
||||
cpb->MemoryLength = snp->tx_rx_bufsize;
|
||||
|
||||
//
|
||||
// let UNDI decide/detect these values
|
||||
//
|
||||
cpb->LinkSpeed = 0;
|
||||
cpb->TxBufCnt = 0;
|
||||
cpb->TxBufSize = 0;
|
||||
cpb->RxBufCnt = 0;
|
||||
cpb->RxBufSize = 0;
|
||||
|
||||
cpb->DuplexMode = PXE_DUPLEX_DEFAULT;
|
||||
|
||||
cpb->LoopBackMode = LOOPBACK_NORMAL;
|
||||
|
||||
snp->cdb.OpCode = PXE_OPCODE_INITIALIZE;
|
||||
snp->cdb.OpFlags = CableDetectFlag;
|
||||
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_INITIALIZE);
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_INITIALIZE);
|
||||
|
||||
snp->cdb.CPBaddr = (UINT64)(UINTN) snp->cpb;
|
||||
snp->cdb.DBaddr = (UINT64)(UINTN) snp->db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.initialize() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode == PXE_STATCODE_SUCCESS) {
|
||||
snp->mode.State = EfiSimpleNetworkInitialized;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
} else {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nsnp->undi.initialize() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
if (snp->tx_rx_buffer != NULL) {
|
||||
snp->IoFncs->FreeBuffer (
|
||||
snp->IoFncs,
|
||||
SNP_MEM_PAGES (snp->tx_rx_bufsize),
|
||||
(VOID *) snp->tx_rx_buffer
|
||||
);
|
||||
}
|
||||
|
||||
snp->tx_rx_buffer = NULL;
|
||||
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for initializing the interface
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_initialize routine to actually do the undi initialization
|
||||
|
||||
@param this context pointer
|
||||
@param extra_rx_buffer_size optional parameter, indicates extra space for
|
||||
rx_buffers
|
||||
@param extra_tx_buffer_size optional parameter, indicates extra space for
|
||||
tx_buffers
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_initialize (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN UINTN extra_rx_buffer_size OPTIONAL,
|
||||
IN UINTN extra_tx_buffer_size OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS EfiStatus;
|
||||
SNP_DRIVER *snp;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
if (snp == NULL) {
|
||||
EfiStatus = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkStarted:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
EfiStatus = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
EfiStatus = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
EfiStatus = gBS->CreateEvent (
|
||||
EVT_NOTIFY_WAIT,
|
||||
TPL_NOTIFY,
|
||||
&SnpWaitForPacketNotify,
|
||||
snp,
|
||||
&snp->snp.WaitForPacket
|
||||
);
|
||||
|
||||
if (EFI_ERROR (EfiStatus)) {
|
||||
snp->snp.WaitForPacket = NULL;
|
||||
EfiStatus = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
snp->mode.MCastFilterCount = 0;
|
||||
snp->mode.ReceiveFilterSetting = 0;
|
||||
ZeroMem (snp->mode.MCastFilter, sizeof snp->mode.MCastFilter);
|
||||
CopyMem (
|
||||
&snp->mode.CurrentAddress,
|
||||
&snp->mode.PermanentAddress,
|
||||
sizeof (EFI_MAC_ADDRESS)
|
||||
);
|
||||
|
||||
//
|
||||
// Compute tx/rx buffer sizes based on UNDI init info and parameters.
|
||||
//
|
||||
snp->tx_rx_bufsize = (UINT32) (snp->init_info.MemoryRequired + extra_rx_buffer_size + extra_tx_buffer_size);
|
||||
|
||||
if (snp->mode.MediaPresentSupported) {
|
||||
if (pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {
|
||||
snp->mode.MediaPresent = TRUE;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
snp->mode.MediaPresent = FALSE;
|
||||
|
||||
EfiStatus = pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);
|
||||
|
||||
if (EFI_ERROR (EfiStatus)) {
|
||||
gBS->CloseEvent (snp->snp.WaitForPacket);
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return EfiStatus;
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
mcast_ip_to_mac.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-17 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
/**
|
||||
this routine calls undi to convert an multicast IP address to a MAC address
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
@param IPv6 flag to indicate if this is an ipv6 address
|
||||
@param IP multicast IP address
|
||||
@param MAC pointer to hold the return MAC address
|
||||
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
pxe_ip2mac (
|
||||
IN SNP_DRIVER *snp,
|
||||
IN BOOLEAN IPv6,
|
||||
IN EFI_IP_ADDRESS *IP,
|
||||
IN OUT EFI_MAC_ADDRESS *MAC
|
||||
)
|
||||
{
|
||||
PXE_CPB_MCAST_IP_TO_MAC *cpb;
|
||||
PXE_DB_MCAST_IP_TO_MAC *db;
|
||||
|
||||
cpb = snp->cpb;
|
||||
db = snp->db;
|
||||
snp->cdb.OpCode = PXE_OPCODE_MCAST_IP_TO_MAC;
|
||||
snp->cdb.OpFlags = (UINT16) (IPv6 ? PXE_OPFLAGS_MCAST_IPV6_TO_MAC : PXE_OPFLAGS_MCAST_IPV4_TO_MAC);
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_MCAST_IP_TO_MAC);
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_MCAST_IP_TO_MAC);
|
||||
|
||||
snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;
|
||||
snp->cdb.DBaddr = (UINT64)(UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
CopyMem (&cpb->IP, IP, sizeof (PXE_IP_ADDR));
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.mcast_ip_to_mac() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
break;
|
||||
|
||||
case PXE_STATCODE_INVALID_CPB:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
case PXE_STATCODE_UNSUPPORTED:
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nsnp->undi.mcast_ip_to_mac() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
default:
|
||||
//
|
||||
// UNDI command failed. Return EFI_DEVICE_ERROR
|
||||
// to caller.
|
||||
//
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nsnp->undi.mcast_ip_to_mac() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
CopyMem (MAC, &db->MAC, sizeof (PXE_MAC_ADDR));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for converting a multicast IP address to
|
||||
a MAC address.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_ip2mac routine to actually do the conversion
|
||||
|
||||
@param this context pointer
|
||||
@param IPv6 flag to indicate if this is an ipv6 address
|
||||
@param IP multicast IP address
|
||||
@param MAC pointer to hold the return MAC address
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_mcast_ip_to_mac (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN IPv6,
|
||||
IN EFI_IP_ADDRESS *IP,
|
||||
OUT EFI_MAC_ADDRESS *MAC
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Get pointer to SNP driver instance for *this.
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (IP == NULL || MAC == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = pxe_ip2mac (snp, IPv6, IP, MAC);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
nvdata.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-03 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
|
||||
/**
|
||||
This routine calls Undi to read the desired number of eeprom bytes.
|
||||
|
||||
@param snp pointer to the snp driver structure
|
||||
@param RegOffset eeprom register value relative to the base address
|
||||
@param NumBytes number of bytes to read
|
||||
@param BufferPtr pointer where to read into
|
||||
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
pxe_nvdata_read (
|
||||
IN SNP_DRIVER *snp,
|
||||
IN UINTN RegOffset,
|
||||
IN UINTN NumBytes,
|
||||
IN OUT VOID *BufferPtr
|
||||
)
|
||||
{
|
||||
PXE_DB_NVDATA *db;
|
||||
|
||||
db = snp->db;
|
||||
snp->cdb.OpCode = PXE_OPCODE_NVDATA;
|
||||
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NVDATA_READ;
|
||||
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_NVDATA);
|
||||
snp->cdb.DBaddr = (UINT64)(UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.nvdata () "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
break;
|
||||
|
||||
case PXE_STATCODE_UNSUPPORTED:
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nsnp->undi.nvdata() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
default:
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nsnp->undi.nvdata() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
CopyMem (BufferPtr, db->Data.Byte + RegOffset, NumBytes);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is an interface call provided by SNP.
|
||||
It does the basic checking on the input parameters and retrieves snp structure
|
||||
and then calls the read_nvdata() call which does the actual reading
|
||||
|
||||
@param this context pointer
|
||||
@param ReadOrWrite true for reading and false for writing
|
||||
@param RegOffset eeprom register relative to the base
|
||||
@param NumBytes how many bytes to read
|
||||
@param BufferPtr address of memory to read into
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_nvdata (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN ReadOrWrite,
|
||||
IN UINTN RegOffset,
|
||||
IN UINTN NumBytes,
|
||||
IN OUT VOID *BufferPtr
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Get pointer to SNP driver instance for *this.
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Return error if the SNP is not initialized.
|
||||
//
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// Return error if non-volatile memory variables are not valid.
|
||||
//
|
||||
if (snp->mode.NvRamSize == 0 || snp->mode.NvRamAccessSize == 0) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// Check for invalid parameter combinations.
|
||||
//
|
||||
if ((NumBytes == 0) ||
|
||||
(BufferPtr == NULL) ||
|
||||
(RegOffset >= snp->mode.NvRamSize) ||
|
||||
(RegOffset + NumBytes > snp->mode.NvRamSize) ||
|
||||
(NumBytes % snp->mode.NvRamAccessSize != 0) ||
|
||||
(RegOffset % snp->mode.NvRamAccessSize != 0)
|
||||
) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// check the implementation flags of undi if we can write the nvdata!
|
||||
//
|
||||
if (!ReadOrWrite) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
} else {
|
||||
Status = pxe_nvdata_read (snp, RegOffset, NumBytes, BufferPtr);
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
receive.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-03 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
/**
|
||||
this routine calls undi to receive a packet and fills in the data in the
|
||||
input pointers!
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
@param BufferPtr pointer to the memory for the received data
|
||||
@param BuffSizePtr is a pointer to the length of the buffer on entry and
|
||||
contains the length of the received data on return
|
||||
@param HeaderSizePtr pointer to the header portion of the data received.
|
||||
@param SourceAddrPtr optional parameter, is a pointer to contain the
|
||||
source ethernet address on return
|
||||
@param DestinationAddrPtr optional parameter, is a pointer to contain the
|
||||
destination ethernet address on return
|
||||
@param ProtocolPtr optional parameter, is a pointer to contain the
|
||||
protocol type from the ethernet header on return
|
||||
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
pxe_receive (
|
||||
SNP_DRIVER *snp,
|
||||
VOID *BufferPtr,
|
||||
UINTN *BuffSizePtr,
|
||||
UINTN *HeaderSizePtr,
|
||||
EFI_MAC_ADDRESS *SourceAddrPtr,
|
||||
EFI_MAC_ADDRESS *DestinationAddrPtr,
|
||||
UINT16 *ProtocolPtr
|
||||
)
|
||||
{
|
||||
PXE_CPB_RECEIVE *cpb;
|
||||
PXE_DB_RECEIVE *db;
|
||||
UINTN buf_size;
|
||||
UINT64 TempData;
|
||||
|
||||
cpb = snp->cpb;
|
||||
db = snp->db;
|
||||
buf_size = *BuffSizePtr;
|
||||
//
|
||||
// IMPORTANT NOTE:
|
||||
// In case of the older 3.0 UNDI, if the input buffer address is beyond 4GB,
|
||||
// DO NOT call the map function on the given buffer, instead use
|
||||
// a global buffer. The reason is that UNDI3.0 has some unnecessary check of
|
||||
// making sure that all the addresses (whether or not they will be given
|
||||
// to the NIC ) supplied to it are below 4GB. It may or may not use
|
||||
// the mapped address after all (like in case of CPB and DB)!
|
||||
// Instead of using the global buffer whose address is allocated within the
|
||||
// 2GB limit if I start mapping the given buffer we lose the data, here is
|
||||
// why!!!
|
||||
// if our address is > 4GB, the map call creates another buffer below 2GB and
|
||||
// copies data to/from the original buffer to the mapped buffer either at
|
||||
// map time or unmap time depending on the map direction.
|
||||
// UNDI will not complain since we already mapped the buffer to be
|
||||
// within the 2GB limit but will not use (I know undi) the mapped address
|
||||
// since it does not give the user buffers to the NIC's receive unit,
|
||||
// It just copies the received packet into the user buffer using the virtual
|
||||
// (CPU) address rather than the mapped (device or physical) address.
|
||||
// When the UNDI call returns, if we then unmap the buffer, we will lose
|
||||
// the contents because unmap copies the contents of the mapped buffer into
|
||||
// the original buffer (since the direction is FROM_DEVICE) !!!
|
||||
//
|
||||
// this is not a problem in Undi 3.1 because this undi uses it's map callback
|
||||
// routine to map a cpu address to device address and it does it only if
|
||||
// it is giving the address to the device and unmaps it before using the cpu
|
||||
// address!
|
||||
//
|
||||
TempData = (UINT64) (UINTN) BufferPtr;
|
||||
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
|
||||
cpb->BufferAddr = (UINT64)(UINTN) snp->receive_buf;
|
||||
cpb->BufferLen = (UINT32) (snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);
|
||||
} else {
|
||||
cpb->BufferAddr = (UINT64)(UINTN) BufferPtr;
|
||||
cpb->BufferLen = (UINT32) *BuffSizePtr;
|
||||
}
|
||||
|
||||
cpb->reserved = 0;
|
||||
|
||||
snp->cdb.OpCode = PXE_OPCODE_RECEIVE;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_RECEIVE);
|
||||
snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;
|
||||
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_RECEIVE);
|
||||
snp->cdb.DBaddr = (UINT64)(UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_INFO, "\nsnp->undi.receive () "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
break;
|
||||
|
||||
case PXE_STATCODE_NO_DATA:
|
||||
DEBUG (
|
||||
(EFI_D_INFO,
|
||||
"\nsnp->undi.receive () %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_NOT_READY;
|
||||
|
||||
default:
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.receive() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
*BuffSizePtr = db->FrameLen;
|
||||
|
||||
if (HeaderSizePtr != NULL) {
|
||||
*HeaderSizePtr = db->MediaHeaderLen;
|
||||
}
|
||||
|
||||
if (SourceAddrPtr != NULL) {
|
||||
CopyMem (SourceAddrPtr, &db->SrcAddr, snp->mode.HwAddressSize);
|
||||
}
|
||||
|
||||
if (DestinationAddrPtr != NULL) {
|
||||
CopyMem (DestinationAddrPtr, &db->DestAddr, snp->mode.HwAddressSize);
|
||||
}
|
||||
|
||||
if (ProtocolPtr != NULL) {
|
||||
*ProtocolPtr = (UINT16) PXE_SWAP_UINT16 (db->Protocol); /* we need to do the byte swapping */
|
||||
}
|
||||
|
||||
TempData = (UINT64) (UINTN) BufferPtr;
|
||||
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
|
||||
CopyMem (BufferPtr, snp->receive_buf, snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);
|
||||
}
|
||||
|
||||
return (*BuffSizePtr <= buf_size) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for receiving network data.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_receive routine to actually do the receive!
|
||||
|
||||
@param this context pointer
|
||||
@param HeaderSizePtr optional parameter and is a pointer to the header
|
||||
portion of the data received.
|
||||
@param BuffSizePtr is a pointer to the length of the buffer on entry and
|
||||
contains the length of the received data on return
|
||||
@param BufferPtr pointer to the memory for the received data
|
||||
@param SourceAddrPtr optional parameter, is a pointer to contain the
|
||||
source ethernet address on return
|
||||
@param DestinationAddrPtr optional parameter, is a pointer to contain the
|
||||
destination ethernet address on return
|
||||
@param ProtocolPtr optional parameter, is a pointer to contain the
|
||||
protocol type from the ethernet header on return
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_receive (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
OUT UINTN *HeaderSizePtr OPTIONAL,
|
||||
IN OUT UINTN *BuffSizePtr,
|
||||
OUT VOID *BufferPtr,
|
||||
OUT EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,
|
||||
OUT EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,
|
||||
OUT UINT16 *ProtocolPtr OPTIONAL
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if ((BuffSizePtr == NULL) || (BufferPtr == NULL)) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (!snp->mode.ReceiveFilterSetting) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = pxe_receive (
|
||||
snp,
|
||||
BufferPtr,
|
||||
BuffSizePtr,
|
||||
HeaderSizePtr,
|
||||
SourceAddrPtr,
|
||||
DestinationAddrPtr,
|
||||
ProtocolPtr
|
||||
);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,406 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
receive_filters.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-17 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
/**
|
||||
this routine calls undi to enable the receive filters.
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
@param EnableFlags bit mask for enabling the receive filters
|
||||
@param MCastAddressCount multicast address count for a new multicast address
|
||||
list
|
||||
@param MCastAddressList list of new multicast addresses
|
||||
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
pxe_rcvfilter_enable (
|
||||
SNP_DRIVER *snp,
|
||||
UINT32 EnableFlags,
|
||||
UINTN MCastAddressCount,
|
||||
EFI_MAC_ADDRESS *MCastAddressList
|
||||
)
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_RECEIVE_FILTER_ENABLE;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
|
||||
}
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
|
||||
}
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
|
||||
}
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
|
||||
}
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
|
||||
}
|
||||
|
||||
if (MCastAddressCount != 0) {
|
||||
snp->cdb.CPBsize = (UINT16) (MCastAddressCount * sizeof (EFI_MAC_ADDRESS));
|
||||
snp->cdb.CPBaddr = (UINT64)(UINTN) snp->cpb;
|
||||
CopyMem (snp->cpb, MCastAddressList, snp->cdb.CPBsize);
|
||||
}
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != EFI_SUCCESS) {
|
||||
//
|
||||
// UNDI command failed. Return UNDI status to caller.
|
||||
//
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.receive_filters() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_INVALID_CDB:
|
||||
case PXE_STATCODE_INVALID_CPB:
|
||||
case PXE_STATCODE_INVALID_PARAMETER:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
case PXE_STATCODE_UNSUPPORTED:
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
this routine calls undi to disable the receive filters.
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
@param DisableFlags bit mask for disabling the receive filters
|
||||
@param ResetMCastList boolean flag to reset/delete the multicast filter list
|
||||
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
pxe_rcvfilter_disable (
|
||||
SNP_DRIVER *snp,
|
||||
UINT32 DisableFlags,
|
||||
BOOLEAN ResetMCastList
|
||||
)
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
snp->cdb.OpFlags = (UINT16) (DisableFlags ? PXE_OPFLAGS_RECEIVE_FILTER_DISABLE : PXE_OPFLAGS_NOT_USED);
|
||||
|
||||
if (ResetMCastList) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST;
|
||||
}
|
||||
|
||||
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
|
||||
}
|
||||
|
||||
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
|
||||
}
|
||||
|
||||
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
|
||||
}
|
||||
|
||||
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
|
||||
}
|
||||
|
||||
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
|
||||
}
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != EFI_SUCCESS) {
|
||||
//
|
||||
// UNDI command failed. Return UNDI status to caller.
|
||||
//
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.receive_filters() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
this routine calls undi to read the receive filters.
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
pxe_rcvfilter_read (
|
||||
SNP_DRIVER *snp
|
||||
)
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_RECEIVE_FILTER_READ;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = (UINT16) (snp->mode.MaxMCastFilterCount * sizeof (EFI_MAC_ADDRESS));
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
if (snp->cdb.DBsize == 0) {
|
||||
snp->cdb.DBaddr = (UINT64)(UINTN) NULL;
|
||||
} else {
|
||||
snp->cdb.DBaddr = (UINT64)(UINTN) snp->db;
|
||||
ZeroMem (snp->db, snp->cdb.DBsize);
|
||||
}
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != EFI_SUCCESS) {
|
||||
//
|
||||
// UNDI command failed. Return UNDI status to caller.
|
||||
//
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.receive_filters() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Convert UNDI32 StatFlags to EFI SNP filter flags.
|
||||
//
|
||||
snp->mode.ReceiveFilterSetting = 0;
|
||||
|
||||
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_UNICAST) != 0) {
|
||||
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
|
||||
}
|
||||
|
||||
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST) != 0) {
|
||||
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
|
||||
}
|
||||
|
||||
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS) != 0) {
|
||||
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
|
||||
}
|
||||
|
||||
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) {
|
||||
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
|
||||
}
|
||||
|
||||
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
|
||||
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
|
||||
}
|
||||
|
||||
CopyMem (snp->mode.MCastFilter, snp->db, snp->cdb.DBsize);
|
||||
|
||||
//
|
||||
// Count number of active entries in multicast filter list.
|
||||
//
|
||||
{
|
||||
EFI_MAC_ADDRESS ZeroMacAddr;
|
||||
|
||||
SetMem (&ZeroMacAddr, sizeof ZeroMacAddr, 0);
|
||||
|
||||
for (snp->mode.MCastFilterCount = 0;
|
||||
snp->mode.MCastFilterCount < snp->mode.MaxMCastFilterCount;
|
||||
snp->mode.MCastFilterCount++
|
||||
) {
|
||||
if (CompareMem (
|
||||
&snp->mode.MCastFilter[snp->mode.MCastFilterCount],
|
||||
&ZeroMacAddr,
|
||||
sizeof ZeroMacAddr
|
||||
) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for reading/enabling/disabling the
|
||||
receive filters.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
checks the parameter validity, calls one of the above routines to actually
|
||||
do the work
|
||||
|
||||
@param this context pointer
|
||||
@param EnableFlags bit mask for enabling the receive filters
|
||||
@param DisableFlags bit mask for disabling the receive filters
|
||||
@param ResetMCastList boolean flag to reset/delete the multicast filter list
|
||||
@param MCastAddressCount multicast address count for a new multicast address
|
||||
list
|
||||
@param MCastAddressList list of new multicast addresses
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_receive_filters (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN UINT32 EnableFlags,
|
||||
IN UINT32 DisableFlags,
|
||||
IN BOOLEAN ResetMCastList,
|
||||
IN UINTN MCastAddressCount OPTIONAL,
|
||||
IN EFI_MAC_ADDRESS * MCastAddressList OPTIONAL
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// check if we are asked to enable or disable something that the UNDI
|
||||
// does not even support!
|
||||
//
|
||||
if (((EnableFlags &~snp->mode.ReceiveFilterMask) != 0) ||
|
||||
((DisableFlags &~snp->mode.ReceiveFilterMask) != 0)) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (ResetMCastList) {
|
||||
|
||||
DisableFlags |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & snp->mode.ReceiveFilterMask;
|
||||
MCastAddressCount = 0;
|
||||
MCastAddressList = NULL;
|
||||
} else {
|
||||
if (MCastAddressCount != 0) {
|
||||
if ((MCastAddressCount > snp->mode.MaxMCastFilterCount) ||
|
||||
(MCastAddressList == NULL)) {
|
||||
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EnableFlags == 0 && DisableFlags == 0 && !ResetMCastList && MCastAddressCount == 0) {
|
||||
Status = EFI_SUCCESS;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastAddressCount == 0) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if ((EnableFlags != 0) || (MCastAddressCount != 0)) {
|
||||
Status = pxe_rcvfilter_enable (
|
||||
snp,
|
||||
EnableFlags,
|
||||
MCastAddressCount,
|
||||
MCastAddressList
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((DisableFlags != 0) || ResetMCastList) {
|
||||
Status = pxe_rcvfilter_disable (snp, DisableFlags, ResetMCastList);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
Status = pxe_rcvfilter_read (snp);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
reset.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-09 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
|
||||
/**
|
||||
This routine calls undi to reset the nic.
|
||||
|
||||
@param snp pointer to the snp driver structure
|
||||
|
||||
@return EFI_SUCCESSFUL for a successful completion
|
||||
@return other for failed calls
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
pxe_reset (
|
||||
SNP_DRIVER *snp
|
||||
)
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_RESET;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.reset() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nsnp->undi32.reset() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
//
|
||||
// UNDI could not be reset. Return UNDI error.
|
||||
//
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for resetting the NIC
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_reset routine to actually do the reset!
|
||||
|
||||
@param this context pointer
|
||||
@param ExtendedVerification not implemented
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_reset (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN ExtendedVerification
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Resolve Warning 4 unreferenced parameter problem
|
||||
//
|
||||
ExtendedVerification = 0;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = pxe_reset (snp);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
shutdown.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-14 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
|
||||
/**
|
||||
this routine calls undi to shut down the interface.
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
pxe_shutdown (
|
||||
IN SNP_DRIVER *snp
|
||||
)
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_SHUTDOWN;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.shutdown() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
//
|
||||
// UNDI could not be shutdown. Return UNDI error.
|
||||
//
|
||||
DEBUG ((EFI_D_WARN, "\nsnp->undi.shutdown() %xh:%xh\n", snp->cdb.StatFlags, snp->cdb.StatCode));
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Free allocated memory.
|
||||
//
|
||||
if (snp->tx_rx_buffer != NULL) {
|
||||
snp->IoFncs->FreeBuffer (
|
||||
snp->IoFncs,
|
||||
SNP_MEM_PAGES (snp->tx_rx_bufsize),
|
||||
(VOID *) snp->tx_rx_buffer
|
||||
);
|
||||
}
|
||||
|
||||
snp->tx_rx_buffer = NULL;
|
||||
snp->tx_rx_bufsize = 0;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for shutting down the interface
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_shutdown routine to actually do the undi shutdown
|
||||
|
||||
@param this context pointer
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_shutdown (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
Status = pxe_shutdown (snp);
|
||||
|
||||
snp->mode.State = EfiSimpleNetworkStarted;
|
||||
snp->mode.ReceiveFilterSetting = 0;
|
||||
|
||||
snp->mode.MCastFilterCount = 0;
|
||||
snp->mode.ReceiveFilterSetting = 0;
|
||||
ZeroMem (snp->mode.MCastFilter, sizeof snp->mode.MCastFilter);
|
||||
CopyMem (
|
||||
&snp->mode.CurrentAddress,
|
||||
&snp->mode.PermanentAddress,
|
||||
sizeof (EFI_MAC_ADDRESS)
|
||||
);
|
||||
|
||||
gBS->CloseEvent (snp->snp.WaitForPacket);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,454 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
snp.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
|
||||
|
||||
**/
|
||||
#ifndef _SNP_H
|
||||
#define _SNP_H
|
||||
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/SimpleNetwork.h>
|
||||
#include <Protocol/PciIo.h>
|
||||
#include <Protocol/NetworkInterfaceIdentifier.h>
|
||||
#include <Protocol/DevicePath.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
|
||||
#include <IndustryStandard/Pci22.h>
|
||||
|
||||
#define FOUR_GIGABYTES (UINT64) 0x100000000ULL
|
||||
|
||||
//
|
||||
// Driver Consumed Protocol Prototypes
|
||||
//
|
||||
//@MT:#include EFI_PROTOCOL_DEFINITION (DevicePath)
|
||||
//@MT:#include EFI_PROTOCOL_DEFINITION (PciIo)
|
||||
//@MT:#include EFI_PROTOCOL_DEFINITION (EfiNetworkInterfaceIdentifier)
|
||||
|
||||
//
|
||||
// Driver Produced Protocol Prototypes
|
||||
//
|
||||
//@MT:#include EFI_PROTOCOL_DEFINITION (DriverBinding)
|
||||
//@MT:#include EFI_PROTOCOL_DEFINITION (ComponentName)
|
||||
//@MT:#include EFI_PROTOCOL_DEFINITION (ComponentName2)
|
||||
//@MT:#include EFI_PROTOCOL_DEFINITION (SimpleNetwork)
|
||||
|
||||
#define SNP_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('s', 'n', 'd', 's')
|
||||
#define MAX_MAP_LENGTH 100
|
||||
|
||||
#define PCI_BAR_IO_MASK 0x00000003
|
||||
#define PCI_BAR_IO_MODE 0x00000001
|
||||
|
||||
#define PCI_BAR_MEM_MASK 0x0000000F
|
||||
#define PCI_BAR_MEM_MODE 0x00000000
|
||||
#define PCI_BAR_MEM_64BIT 0x00000004
|
||||
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
EFI_LOCK lock;
|
||||
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL snp;
|
||||
EFI_SIMPLE_NETWORK_MODE mode;
|
||||
|
||||
EFI_HANDLE device_handle;
|
||||
EFI_DEVICE_PATH_PROTOCOL *device_path;
|
||||
|
||||
//
|
||||
// Local instance data needed by SNP driver
|
||||
//
|
||||
// Pointer to S/W UNDI API entry point
|
||||
// This will be NULL for H/W UNDI
|
||||
//
|
||||
EFI_STATUS (*issue_undi32_command) (UINT64 cdb);
|
||||
|
||||
BOOLEAN is_swundi;
|
||||
|
||||
//
|
||||
// undi interface number, if one undi manages more nics
|
||||
//
|
||||
PXE_IFNUM if_num;
|
||||
|
||||
//
|
||||
// Allocated tx/rx buffer that was passed to UNDI Initialize.
|
||||
//
|
||||
UINT32 tx_rx_bufsize;
|
||||
VOID *tx_rx_buffer;
|
||||
//
|
||||
// mappable buffers for receive and fill header for undi3.0
|
||||
// these will be used if the user buffers are above 4GB limit (instead of
|
||||
// mapping the user buffers)
|
||||
//
|
||||
UINT8 *receive_buf;
|
||||
VOID *ReceiveBufUnmap;
|
||||
UINT8 *fill_hdr_buf;
|
||||
VOID *FillHdrBufUnmap;
|
||||
|
||||
EFI_PCI_IO_PROTOCOL *IoFncs;
|
||||
UINT8 IoBarIndex;
|
||||
UINT8 MemoryBarIndex;
|
||||
BOOLEAN IsOldUndi; // true for EFI1.0 UNDI (3.0) drivers
|
||||
//
|
||||
// Buffers for command descriptor block, command parameter block
|
||||
// and data block.
|
||||
//
|
||||
PXE_CDB cdb;
|
||||
VOID *cpb;
|
||||
VOID *CpbUnmap;
|
||||
VOID *db;
|
||||
|
||||
//
|
||||
// UNDI structure, we need to remember the init info for a long time!
|
||||
//
|
||||
PXE_DB_GET_INIT_INFO init_info;
|
||||
|
||||
VOID *SnpDriverUnmap;
|
||||
//
|
||||
// when ever we map an address, we must remember it's address and the un-map
|
||||
// cookie so that we can unmap later
|
||||
//
|
||||
struct s_map_list {
|
||||
EFI_PHYSICAL_ADDRESS virt;
|
||||
VOID *map_cookie;
|
||||
} map_list[MAX_MAP_LENGTH];
|
||||
}
|
||||
SNP_DRIVER;
|
||||
|
||||
#define EFI_SIMPLE_NETWORK_DEV_FROM_THIS(a) CR (a, SNP_DRIVER, snp, SNP_DRIVER_SIGNATURE)
|
||||
|
||||
//
|
||||
// Global Variables
|
||||
//
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gSimpleNetworkComponentName;
|
||||
|
||||
//
|
||||
// Virtual to physical mapping for all UNDI 3.0s.
|
||||
//
|
||||
extern struct s_v2p {
|
||||
struct s_v2p *next;
|
||||
VOID *vaddr;
|
||||
UINTN bsize;
|
||||
EFI_PHYSICAL_ADDRESS paddr;
|
||||
VOID *unmap;
|
||||
}
|
||||
*_v2p;
|
||||
|
||||
EFI_STATUS
|
||||
add_v2p (
|
||||
struct s_v2p **v2p,
|
||||
EFI_PCI_IO_PROTOCOL_OPERATION type,
|
||||
VOID *vaddr,
|
||||
UINTN bsize
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
find_v2p (
|
||||
struct s_v2p **v2p,
|
||||
VOID *vaddr
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
del_v2p (
|
||||
VOID *vaddr
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_block_30 (
|
||||
IN UINT32 Enable
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_delay_30 (
|
||||
IN UINT64 MicroSeconds
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_memio_30 (
|
||||
IN UINT8 ReadOrWrite,
|
||||
IN UINT8 NumBytes,
|
||||
IN UINT64 MemOrPortAddress,
|
||||
IN OUT UINT64 BufferPtr
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_v2p_30 (
|
||||
IN UINT64 CpuAddr,
|
||||
IN OUT UINT64 DeviceAddrPtr
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_block (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT32 Enable
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_delay (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 MicroSeconds
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_memio (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT8 ReadOrWrite,
|
||||
IN UINT8 NumBytes,
|
||||
IN UINT64 MemOrPortAddr,
|
||||
IN OUT UINT64 BufferPtr
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_map (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 CpuAddr,
|
||||
IN UINT32 NumBytes,
|
||||
IN UINT32 Direction,
|
||||
IN OUT UINT64 DeviceAddrPtr
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_unmap (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 CpuAddr,
|
||||
IN UINT32 NumBytes,
|
||||
IN UINT32 Direction,
|
||||
IN UINT64 DeviceAddr // not a pointer to device address
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_sync (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 CpuAddr,
|
||||
IN UINT32 NumBytes,
|
||||
IN UINT32 Direction,
|
||||
IN UINT64 DeviceAddr // not a pointer to device address
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_start (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_stop (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_initialize (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN UINTN extra_rx_buffer_size OPTIONAL,
|
||||
IN UINTN extra_tx_buffer_size OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_reset (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN ExtendedVerification
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_shutdown (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_receive_filters (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN UINT32 enable,
|
||||
IN UINT32 disable,
|
||||
IN BOOLEAN reset_mcast_filter,
|
||||
IN UINTN mcast_filter_count OPTIONAL,
|
||||
IN EFI_MAC_ADDRESS * mcast_filter OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_station_address (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN BOOLEAN reset,
|
||||
IN EFI_MAC_ADDRESS *new OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_statistics (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN BOOLEAN reset,
|
||||
IN OUT UINTN *statistics_size OPTIONAL,
|
||||
IN OUT EFI_NETWORK_STATISTICS * statistics_table OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_mcast_ip_to_mac (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN IPv6,
|
||||
IN EFI_IP_ADDRESS *IP,
|
||||
OUT EFI_MAC_ADDRESS *MAC
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_nvdata (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN read_write,
|
||||
IN UINTN offset,
|
||||
IN UINTN buffer_size,
|
||||
IN OUT VOID *buffer
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_get_status (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
OUT UINT32 *interrupt_status OPTIONAL,
|
||||
OUT VOID **tx_buffer OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_transmit (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN UINTN header_size,
|
||||
IN UINTN buffer_size,
|
||||
IN VOID *buffer,
|
||||
IN EFI_MAC_ADDRESS * src_addr OPTIONAL,
|
||||
IN EFI_MAC_ADDRESS * dest_addr OPTIONAL,
|
||||
IN UINT16 *protocol OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_receive (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
OUT UINTN *header_size OPTIONAL,
|
||||
IN OUT UINTN *buffer_size,
|
||||
OUT VOID *buffer,
|
||||
OUT EFI_MAC_ADDRESS * src_addr OPTIONAL,
|
||||
OUT EFI_MAC_ADDRESS * dest_addr OPTIONAL,
|
||||
OUT UINT16 *protocol OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(*issue_undi32_command) (
|
||||
UINT64 cdb
|
||||
);
|
||||
typedef
|
||||
VOID
|
||||
(*ptr) (
|
||||
VOID
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Install all the driver protocol
|
||||
|
||||
@param ImageHandle Driver image handle
|
||||
@param SystemTable System services table
|
||||
|
||||
@retval EFI_SUCEESS Initialization routine has found UNDI hardware, loaded it's
|
||||
ROM, and installed a notify event for the Network
|
||||
Indentifier Interface Protocol successfully.
|
||||
@retval Other Return value from HandleProtocol for DeviceIoProtocol or
|
||||
LoadedImageProtocol
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeSnpNiiDriver (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
;
|
||||
|
||||
#ifdef EFI_SIZE_REDUCTION_APPLIED
|
||||
#define COMPONENT_NAME_CODE(code)
|
||||
#define COMPONENT_NAME NULL
|
||||
#else
|
||||
#define COMPONENT_NAME_CODE(code) code
|
||||
#define COMPONENT_NAME &gSimpleNetworkComponentName
|
||||
#endif
|
||||
|
||||
#define SNP_MEM_PAGES(x) (((x) - 1) / 4096 + 1)
|
||||
|
||||
|
||||
#endif /* _SNP_H */
|
|
@ -0,0 +1,191 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
start.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-07 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
|
||||
/**
|
||||
this routine calls undi to start the interface and changes the snp state!
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
pxe_start (
|
||||
SNP_DRIVER *snp
|
||||
)
|
||||
{
|
||||
PXE_CPB_START_30 *cpb;
|
||||
PXE_CPB_START_31 *cpb_31;
|
||||
|
||||
cpb = snp->cpb;
|
||||
cpb_31 = snp->cpb;
|
||||
//
|
||||
// Initialize UNDI Start CDB for H/W UNDI
|
||||
//
|
||||
snp->cdb.OpCode = PXE_OPCODE_START;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Make changes to H/W UNDI Start CDB if this is
|
||||
// a S/W UNDI.
|
||||
//
|
||||
if (snp->is_swundi) {
|
||||
if (snp->IsOldUndi) {
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_START_30);
|
||||
snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;
|
||||
|
||||
cpb->Delay = (UINT64)(UINTN) &snp_undi32_callback_delay_30;
|
||||
cpb->Block = (UINT64)(UINTN) &snp_undi32_callback_block_30;
|
||||
|
||||
//
|
||||
// Virtual == Physical. This can be set to zero.
|
||||
//
|
||||
cpb->Virt2Phys = (UINT64)(UINTN) &snp_undi32_callback_v2p_30;
|
||||
cpb->Mem_IO = (UINT64)(UINTN) &snp_undi32_callback_memio_30;
|
||||
} else {
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_START_31);
|
||||
snp->cdb.CPBaddr = (UINT64)(UINTN) cpb_31;
|
||||
|
||||
cpb_31->Delay = (UINT64)(UINTN) &snp_undi32_callback_delay;
|
||||
cpb_31->Block = (UINT64)(UINTN) &snp_undi32_callback_block;
|
||||
|
||||
//
|
||||
// Virtual == Physical. This can be set to zero.
|
||||
//
|
||||
cpb_31->Virt2Phys = (UINT64)(UINTN) 0;
|
||||
cpb_31->Mem_IO = (UINT64)(UINTN) &snp_undi32_callback_memio;
|
||||
|
||||
cpb_31->Map_Mem = (UINT64)(UINTN) &snp_undi32_callback_map;
|
||||
cpb_31->UnMap_Mem = (UINT64)(UINTN) &snp_undi32_callback_unmap;
|
||||
cpb_31->Sync_Mem = (UINT64)(UINTN) &snp_undi32_callback_sync;
|
||||
|
||||
cpb_31->Unique_ID = (UINT64)(UINTN) snp;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.start() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
//
|
||||
// UNDI could not be started. Return UNDI error.
|
||||
//
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.start() %xh:%xh\n",
|
||||
snp->cdb.StatCode,
|
||||
snp->cdb.StatFlags)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Set simple network state to Started and return success.
|
||||
//
|
||||
snp->mode.State = EfiSimpleNetworkStarted;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for starting the interface
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_start routine to actually do start undi interface
|
||||
|
||||
@param This context pointer
|
||||
|
||||
@retval EFI_INVALID_PARAMETER "This" is Null
|
||||
@retval No SNP driver can be extracted from "This"
|
||||
@retval EFI_ALREADY_STARTED The state of SNP is EfiSimpleNetworkStarted or
|
||||
EfiSimpleNetworkInitialized
|
||||
@retval EFI_DEVICE_ERROR The state of SNP is other than
|
||||
EfiSimpleNetworkStarted,
|
||||
EfiSimpleNetworkInitialized, and
|
||||
EfiSimpleNetworkStopped
|
||||
@retval EFI_SUCCESS UNDI interface is succesfully started
|
||||
@retval Other Error occurs while calling pxe_start function.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_start (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *Snp;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
switch (Snp->mode.State) {
|
||||
case EfiSimpleNetworkStopped:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
case EfiSimpleNetworkInitialized:
|
||||
Status = EFI_ALREADY_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = pxe_start (Snp);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// clear the map_list in SNP structure
|
||||
//
|
||||
for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
|
||||
Snp->map_list[Index].virt = 0;
|
||||
Snp->map_list[Index].map_cookie = 0;
|
||||
}
|
||||
|
||||
Snp->mode.MCastFilterCount = 0;
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
station_address.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-17 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
|
||||
/**
|
||||
this routine calls undi to read the MAC address of the NIC and updates the
|
||||
mode structure with the address.
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
pxe_get_stn_addr (
|
||||
SNP_DRIVER *snp
|
||||
)
|
||||
{
|
||||
PXE_DB_STATION_ADDRESS *db;
|
||||
|
||||
db = snp->db;
|
||||
snp->cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;
|
||||
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_STATION_ADDRESS);
|
||||
snp->cdb.DBaddr = (UINT64)(UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.station_addr() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Set new station address in SNP->Mode structure and return success.
|
||||
//
|
||||
CopyMem (
|
||||
&(snp->mode.CurrentAddress),
|
||||
&db->StationAddr,
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
|
||||
CopyMem (
|
||||
&snp->mode.BroadcastAddress,
|
||||
&db->BroadcastAddr,
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
|
||||
CopyMem (
|
||||
&snp->mode.PermanentAddress,
|
||||
&db->PermanentAddr,
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
this routine calls undi to set a new MAC address for the NIC,
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
@param NewMacAddr pointer to a mac address to be set for the nic, if this is
|
||||
NULL then this routine resets the mac address to the NIC's
|
||||
original address.
|
||||
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
pxe_set_stn_addr (
|
||||
SNP_DRIVER *snp,
|
||||
EFI_MAC_ADDRESS *NewMacAddr
|
||||
)
|
||||
{
|
||||
PXE_CPB_STATION_ADDRESS *cpb;
|
||||
PXE_DB_STATION_ADDRESS *db;
|
||||
|
||||
cpb = snp->cpb;
|
||||
db = snp->db;
|
||||
snp->cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;
|
||||
|
||||
if (NewMacAddr == NULL) {
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_RESET;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
} else {
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;
|
||||
//
|
||||
// even though the OPFLAGS are set to READ, supplying a new address
|
||||
// in the CPB will make undi change the mac address to the new one.
|
||||
//
|
||||
CopyMem (&cpb->StationAddr, NewMacAddr, snp->mode.HwAddressSize);
|
||||
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_STATION_ADDRESS);
|
||||
snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;
|
||||
}
|
||||
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_STATION_ADDRESS);
|
||||
snp->cdb.DBaddr = (UINT64)(UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.station_addr() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
//
|
||||
// UNDI command failed. Return UNDI status to caller.
|
||||
//
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// read the changed address and save it in SNP->Mode structure
|
||||
//
|
||||
pxe_get_stn_addr (snp);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for changing the NIC's mac address.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the above routines to actually do the work
|
||||
|
||||
@param this context pointer
|
||||
@param NewMacAddr pointer to a mac address to be set for the nic, if this is
|
||||
NULL then this routine resets the mac address to the NIC's
|
||||
original address.
|
||||
@param ResetFlag If true, the mac address will change to NIC's original
|
||||
address
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_station_address (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN BOOLEAN ResetFlag,
|
||||
IN EFI_MAC_ADDRESS * NewMacAddr OPTIONAL
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
//
|
||||
// Check for invalid parameter combinations.
|
||||
//
|
||||
if ((this == NULL) ||
|
||||
(!ResetFlag && (NewMacAddr == NULL))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Return error if the SNP is not initialized.
|
||||
//
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (ResetFlag) {
|
||||
Status = pxe_set_stn_addr (snp, NULL);
|
||||
} else {
|
||||
Status = pxe_set_stn_addr (snp, NewMacAddr);
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
statistics.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-17 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for getting the NIC's statistics.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_ routine to actually do the
|
||||
|
||||
@param this context pointer
|
||||
@param ResetFlag true to reset the NIC's statistics counters to zero.
|
||||
@param StatTableSizePtr pointer to the statistics table size
|
||||
@param StatTablePtr pointer to the statistics table
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_statistics (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN BOOLEAN ResetFlag,
|
||||
IN OUT UINTN *StatTableSizePtr OPTIONAL,
|
||||
IN OUT EFI_NETWORK_STATISTICS * StatTablePtr OPTIONAL
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
PXE_DB_STATISTICS *db;
|
||||
UINT64 *stp;
|
||||
UINT64 mask;
|
||||
UINTN size;
|
||||
UINTN n;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Get pointer to SNP driver instance for *this.
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Return error if the SNP is not initialized.
|
||||
//
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// if we are not resetting the counters, we have to have a valid stat table
|
||||
// with >0 size. if no reset, no table and no size, return success.
|
||||
//
|
||||
if (!ResetFlag && StatTableSizePtr == NULL) {
|
||||
Status = StatTablePtr ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// Initialize UNDI Statistics CDB
|
||||
//
|
||||
snp->cdb.OpCode = PXE_OPCODE_STATISTICS;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
if (ResetFlag) {
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_STATISTICS_RESET;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
db = snp->db;
|
||||
} else {
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_STATISTICS_READ;
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_STATISTICS);
|
||||
snp->cdb.DBaddr = (UINT64)(UINTN) (db = snp->db);
|
||||
}
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.statistics() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
break;
|
||||
|
||||
case PXE_STATCODE_UNSUPPORTED:
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.statistics() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.statistics() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (ResetFlag) {
|
||||
Status = EFI_SUCCESS;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (StatTablePtr == NULL) {
|
||||
*StatTableSizePtr = sizeof (EFI_NETWORK_STATISTICS);
|
||||
Status = EFI_BUFFER_TOO_SMALL;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
//
|
||||
// Convert the UNDI statistics information to SNP statistics
|
||||
// information.
|
||||
//
|
||||
ZeroMem (StatTablePtr, *StatTableSizePtr);
|
||||
stp = (UINT64 *) StatTablePtr;
|
||||
size = 0;
|
||||
|
||||
for (n = 0, mask = 1; n < 64; n++, mask = LShiftU64 (mask, 1), stp++) {
|
||||
//
|
||||
// There must be room for a full UINT64. Partial
|
||||
// numbers will not be stored.
|
||||
//
|
||||
if ((n + 1) * sizeof (UINT64) > *StatTableSizePtr) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (db->Supported & mask) {
|
||||
*stp = db->Data[n];
|
||||
size = n + 1;
|
||||
} else {
|
||||
SetMem (stp, sizeof (UINT64), 0xFF);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Compute size up to last supported statistic.
|
||||
//
|
||||
while (++n < 64) {
|
||||
if (db->Supported & (mask = LShiftU64 (mask, 1))) {
|
||||
size = n;
|
||||
}
|
||||
}
|
||||
|
||||
size *= sizeof (UINT64);
|
||||
|
||||
if (*StatTableSizePtr >= size) {
|
||||
*StatTableSizePtr = size;
|
||||
Status = EFI_SUCCESS;
|
||||
} else {
|
||||
*StatTableSizePtr = size;
|
||||
Status = EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
stop.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-09 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
|
||||
/**
|
||||
this routine calls undi to stop the interface and changes the snp state
|
||||
|
||||
@param snp pointer to snp driver structure
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
pxe_stop (
|
||||
SNP_DRIVER *snp
|
||||
)
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_STOP;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.stop() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nsnp->undi.stop() %xh:%xh\n",
|
||||
snp->cdb.StatCode,
|
||||
snp->cdb.StatFlags)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Set simple network state to Started and return success.
|
||||
//
|
||||
snp->mode.State = EfiSimpleNetworkStopped;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the SNP interface routine for stopping the interface.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_stop routine to actually stop the undi interface
|
||||
|
||||
@param this context pointer
|
||||
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_stop (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkStarted:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = pxe_stop (snp);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,399 @@
|
|||
/** @file
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
transmit.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-03 M(f)J Genesis.
|
||||
|
||||
**/
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
|
||||
/**
|
||||
This routine calls undi to create the meadia header for the given data buffer.
|
||||
|
||||
@param snp pointer to SNP driver structure
|
||||
@param MacHeaderPtr address where the media header will be filled in.
|
||||
@param MacHeaderSize size of the memory at MacHeaderPtr
|
||||
@param BufferPtr data buffer pointer
|
||||
@param BufferLength Size of data in the BufferPtr
|
||||
@param DestinationAddrPtr address of the destination mac address buffer
|
||||
@param SourceAddrPtr address of the source mac address buffer
|
||||
@param ProtocolPtr address of the protocol type
|
||||
|
||||
@retval EFI_SUCCESS if successfully completed the undi call
|
||||
@retval Other error return from undi call.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
pxe_fillheader (
|
||||
SNP_DRIVER *snp,
|
||||
VOID *MacHeaderPtr,
|
||||
UINTN MacHeaderSize,
|
||||
VOID *BufferPtr,
|
||||
UINTN BufferLength,
|
||||
EFI_MAC_ADDRESS *DestinationAddrPtr,
|
||||
EFI_MAC_ADDRESS *SourceAddrPtr,
|
||||
UINT16 *ProtocolPtr
|
||||
)
|
||||
{
|
||||
PXE_CPB_FILL_HEADER_FRAGMENTED *cpb;
|
||||
EFI_STATUS Status;
|
||||
struct s_v2p *pkt_v2p;
|
||||
UINT64 TempData;
|
||||
|
||||
cpb = snp->cpb;
|
||||
if (SourceAddrPtr) {
|
||||
CopyMem (
|
||||
(VOID *) cpb->SrcAddr,
|
||||
(VOID *) SourceAddrPtr,
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
} else {
|
||||
CopyMem (
|
||||
(VOID *) cpb->SrcAddr,
|
||||
(VOID *) &(snp->mode.CurrentAddress),
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
}
|
||||
|
||||
CopyMem (
|
||||
(VOID *) cpb->DestAddr,
|
||||
(VOID *) DestinationAddrPtr,
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
|
||||
//
|
||||
// we need to do the byte swapping
|
||||
//
|
||||
cpb->Protocol = (UINT16) PXE_SWAP_UINT16 (*ProtocolPtr);
|
||||
|
||||
cpb->PacketLen = (UINT32) (BufferLength);
|
||||
cpb->MediaHeaderLen = (UINT16) MacHeaderSize;
|
||||
|
||||
cpb->FragCnt = 2;
|
||||
cpb->reserved = 0;
|
||||
|
||||
cpb->FragDesc[0].FragAddr = (UINT64)(UINTN) MacHeaderPtr;
|
||||
cpb->FragDesc[0].FragLen = (UINT32) MacHeaderSize;
|
||||
cpb->FragDesc[1].FragAddr = (UINT64)(UINTN) BufferPtr;
|
||||
cpb->FragDesc[1].FragLen = (UINT32) BufferLength;
|
||||
|
||||
cpb->FragDesc[0].reserved = cpb->FragDesc[1].reserved = 0;
|
||||
|
||||
if (snp->IsOldUndi) {
|
||||
TempData = (UINT64) (UINTN) MacHeaderPtr;
|
||||
if (TempData >= FOUR_GIGABYTES) {
|
||||
cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) snp->fill_hdr_buf;
|
||||
cpb->FragDesc[0].FragLen = (UINT32) snp->init_info.MediaHeaderLen;
|
||||
}
|
||||
|
||||
TempData = (UINT64) (UINTN) (BufferPtr);
|
||||
if (TempData >= FOUR_GIGABYTES) {
|
||||
//
|
||||
// Let the device just read this buffer
|
||||
//
|
||||
Status = add_v2p (
|
||||
&pkt_v2p,
|
||||
EfiPciIoOperationBusMasterRead,
|
||||
BufferPtr,
|
||||
BufferLength
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// give the virtual address to UNDI and it will call back on Virt2Phys
|
||||
// to get the mapped address, if it needs it
|
||||
//
|
||||
cpb->FragDesc[1].FragLen = (UINT32) pkt_v2p->bsize;
|
||||
}
|
||||
}
|
||||
|
||||
snp->cdb.OpCode = PXE_OPCODE_FILL_HEADER;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_FILL_HEADER_FRAGMENTED;
|
||||
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED);
|
||||
snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.fill_header() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->IsOldUndi) {
|
||||
TempData = (UINT64) (UINTN) (BufferPtr);
|
||||
if (TempData >= FOUR_GIGABYTES) {
|
||||
del_v2p (BufferPtr);
|
||||
}
|
||||
//
|
||||
// if we used the global buffer for header, copy the contents
|
||||
//
|
||||
TempData = (UINT64) (UINTN) MacHeaderPtr;
|
||||
if (TempData >= FOUR_GIGABYTES) {
|
||||
CopyMem (
|
||||
MacHeaderPtr,
|
||||
snp->fill_hdr_buf,
|
||||
snp->init_info.MediaHeaderLen
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
return EFI_SUCCESS;
|
||||
|
||||
case PXE_STATCODE_INVALID_PARAMETER:
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.fill_header() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
default:
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.fill_header() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This routine calls undi to transmit the given data buffer
|
||||
|
||||
@param snp pointer to SNP driver structure
|
||||
@param BufferPtr data buffer pointer
|
||||
@param BufferLength Size of data in the BufferPtr
|
||||
|
||||
@retval EFI_SUCCESS if successfully completed the undi call
|
||||
@retval Other error return from undi call.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
pxe_transmit (
|
||||
SNP_DRIVER *snp,
|
||||
VOID *BufferPtr,
|
||||
UINTN BufferLength
|
||||
)
|
||||
{
|
||||
PXE_CPB_TRANSMIT *cpb;
|
||||
EFI_STATUS Status;
|
||||
struct s_v2p *v2p;
|
||||
UINT64 TempData;
|
||||
|
||||
cpb = snp->cpb;
|
||||
cpb->FrameAddr = (UINT64) (UINTN) BufferPtr;
|
||||
cpb->DataLen = (UINT32) BufferLength;
|
||||
|
||||
TempData = (UINT64) (UINTN) BufferPtr;
|
||||
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
|
||||
//
|
||||
// we need to create a mapping now and give it to the undi when it calls
|
||||
// the Virt2Phys on this address.
|
||||
// this is a transmit, just map it for the device to READ
|
||||
//
|
||||
Status = add_v2p (
|
||||
&v2p,
|
||||
EfiPciIoOperationBusMasterRead,
|
||||
BufferPtr,
|
||||
BufferLength
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
cpb->DataLen = (UINT32) v2p->bsize;
|
||||
}
|
||||
|
||||
cpb->MediaheaderLen = 0;
|
||||
cpb->reserved = 0;
|
||||
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_TRANSMIT_WHOLE;
|
||||
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_TRANSMIT);
|
||||
snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;
|
||||
|
||||
snp->cdb.OpCode = PXE_OPCODE_TRANSMIT;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.transmit() "));
|
||||
DEBUG ((EFI_D_NET, "\nsnp->cdb.OpCode == %x", snp->cdb.OpCode));
|
||||
DEBUG ((EFI_D_NET, "\nsnp->cdb.CPBaddr == %X", snp->cdb.CPBaddr));
|
||||
DEBUG ((EFI_D_NET, "\nsnp->cdb.DBaddr == %X", snp->cdb.DBaddr));
|
||||
DEBUG ((EFI_D_NET, "\ncpb->FrameAddr == %X\n", cpb->FrameAddr));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
DEBUG ((EFI_D_NET, "\nexit snp->undi.transmit() "));
|
||||
DEBUG ((EFI_D_NET, "\nsnp->cdb.StatCode == %r", snp->cdb.StatCode));
|
||||
|
||||
//
|
||||
// we will unmap the buffers in get_status call, not here
|
||||
//
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
return EFI_SUCCESS;
|
||||
|
||||
case PXE_STATCODE_QUEUE_FULL:
|
||||
case PXE_STATCODE_BUSY:
|
||||
Status = EFI_NOT_READY;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.transmit() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This is the snp interface routine for transmitting a packet. this routine
|
||||
basically retrieves the snp structure, checks the snp state and calls
|
||||
pxe_fill_header and pxe_transmit calls to complete the transmission.
|
||||
|
||||
@param this pointer to SNP driver context
|
||||
@param MacHeaderSize size of the memory at MacHeaderPtr
|
||||
@param BufferLength Size of data in the BufferPtr
|
||||
@param BufferPtr data buffer pointer
|
||||
@param SourceAddrPtr address of the source mac address buffer
|
||||
@param DestinationAddrPtr address of the destination mac address buffer
|
||||
@param ProtocolPtr address of the protocol type
|
||||
|
||||
@retval EFI_SUCCESS if successfully completed the undi call
|
||||
@retval Other error return from undi call.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_transmit (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN UINTN MacHeaderSize,
|
||||
IN UINTN BufferLength,
|
||||
IN VOID *BufferPtr,
|
||||
IN EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,
|
||||
IN EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,
|
||||
IN UINT16 *ProtocolPtr OPTIONAL
|
||||
)
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_EXIT;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (BufferPtr == NULL) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (BufferLength < snp->mode.MediaHeaderSize) {
|
||||
Status = EFI_BUFFER_TOO_SMALL;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// if the MacHeaderSize is non-zero, we need to fill up the header and for that
|
||||
// we need the destination address and the protocol
|
||||
//
|
||||
if (MacHeaderSize != 0) {
|
||||
if (MacHeaderSize != snp->mode.MediaHeaderSize || DestinationAddrPtr == 0 || ProtocolPtr == 0) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = pxe_fillheader (
|
||||
snp,
|
||||
BufferPtr,
|
||||
MacHeaderSize,
|
||||
(UINT8 *) BufferPtr + MacHeaderSize,
|
||||
BufferLength - MacHeaderSize,
|
||||
DestinationAddrPtr,
|
||||
SourceAddrPtr,
|
||||
ProtocolPtr
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
Status = pxe_transmit (snp, BufferPtr, BufferLength);
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
ComponentName.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "Tcp4Main.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TcpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TcpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
//
|
||||
// EFI Component Name Protocol
|
||||
//
|
||||
EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName = {
|
||||
TcpComponentNameGetDriverName,
|
||||
TcpComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
static EFI_UNICODE_STRING_TABLE mTcpDriverNameTable[] = {
|
||||
{
|
||||
"eng",
|
||||
L"Tcp Network Service Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TcpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Retrieves a Unicode string that is the user readable name of the EFI Driver.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
Language - A pointer to a three character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages
|
||||
specified in SupportedLanguages. The number of languages
|
||||
supported by a driver is up to the driver writer.
|
||||
DriverName - A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the driver specified by This in the
|
||||
language specified by Language.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCES - The Unicode string for the Driver specified by
|
||||
This and the language specified by Language was
|
||||
returned in DriverName.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - DriverName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return LookupUnicodeString (
|
||||
Language,
|
||||
gTcp4ComponentName.SupportedLanguages,
|
||||
mTcpDriverNameTable,
|
||||
DriverName
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TcpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
ControllerHandle - The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
ChildHandle - The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL.
|
||||
It will be NULL for device drivers. It will also be
|
||||
NULL for a bus drivers that wish to retrieve the name of
|
||||
the bus controller. It will not be NULL for a bus
|
||||
driver that wishes to retrieve the name of a child
|
||||
controller.
|
||||
Language - A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller
|
||||
name that that the caller is requesting, and it must
|
||||
match one of the languages specified in supported
|
||||
languages. The number of languages supported by a driver
|
||||
is up to the driver writer.
|
||||
ControllerName - A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language
|
||||
specified by Language from the point of view of the
|
||||
driver specified by This.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The Unicode string for the user readable name in
|
||||
the language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
|
||||
EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - ControllerName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,84 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
SockImpl.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _SOCK_IMPL_H_
|
||||
#define _SOCK_IMPL_H_
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
#define SOCK_DEBUG_ERROR(PrintArg) NET_DEBUG_ERROR("Sock", PrintArg)
|
||||
#define SOCK_DEBUG_WARN(PrintArg) NET_DEBUG_WARNING("Sock", PrintArg)
|
||||
#define SOCK_DEBUG_TRACE(PrintArg) NET_DEBUG_TRACE("Sock", PrintArg)
|
||||
|
||||
#define SOCK_TRIM_RCV_BUFF(Sock, Len) \
|
||||
(NetbufQueTrim ((Sock)->RcvBuffer.DataQueue, (Len)))
|
||||
|
||||
#define SIGNAL_TOKEN(Token, TokenStatus) \
|
||||
do { \
|
||||
(Token)->Status = (TokenStatus); \
|
||||
gBS->SignalEvent ((Token)->Event); \
|
||||
} while (0)
|
||||
|
||||
#define SOCK_HEADER_SPACE (60 + 60 + 72)
|
||||
|
||||
//
|
||||
// Supporting function for both SockImpl and SockInterface
|
||||
//
|
||||
VOID
|
||||
SockFreeFoo (
|
||||
IN EFI_EVENT Event
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
SockProcessTcpSndData (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *TcpTxData
|
||||
);
|
||||
|
||||
VOID
|
||||
SockSetTcpRxData (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *TcpRxData,
|
||||
IN UINT32 RcvdBytes,
|
||||
IN BOOLEAN IsOOB
|
||||
);
|
||||
|
||||
UINT32
|
||||
SockProcessRcvToken (
|
||||
IN SOCKET *Sock,
|
||||
IN SOCK_IO_TOKEN *RcvToken
|
||||
);
|
||||
|
||||
VOID
|
||||
SockConnFlush (
|
||||
IN SOCKET *Sock
|
||||
);
|
||||
|
||||
SOCKET *
|
||||
SockCreate (
|
||||
IN SOCK_INIT_DATA *SockInitData
|
||||
);
|
||||
|
||||
VOID
|
||||
SockDestroy (
|
||||
IN SOCKET *Sock
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,980 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
SockInterface.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "SockImpl.h"
|
||||
|
||||
|
||||
/**
|
||||
Check whether the Event is in the List.
|
||||
|
||||
@param List Pointer to the token list to be searched.
|
||||
@param Event The event to be checked.
|
||||
|
||||
@retval BOOLEAN If TRUE, the specific Event exists in the List. If
|
||||
FALSE, the specific Event is not in the List.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
SockTokenExistedInList (
|
||||
IN NET_LIST_ENTRY *List,
|
||||
IN EFI_EVENT Event
|
||||
)
|
||||
{
|
||||
NET_LIST_ENTRY *ListEntry;
|
||||
SOCK_TOKEN *SockToken;
|
||||
|
||||
NET_LIST_FOR_EACH (ListEntry, List) {
|
||||
SockToken = NET_LIST_USER_STRUCT (
|
||||
ListEntry,
|
||||
SOCK_TOKEN,
|
||||
TokenList
|
||||
);
|
||||
|
||||
if (Event == SockToken->Token->Event) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Call SockTokenExistedInList() to check whether the Event is
|
||||
in the related socket's lists.
|
||||
|
||||
@param Sock Pointer to the instance's socket.
|
||||
@param Event The event to be checked.
|
||||
|
||||
@return The specific Event exists in one of socket's lists or not.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
SockTokenExisted (
|
||||
IN SOCKET *Sock,
|
||||
IN EFI_EVENT Event
|
||||
)
|
||||
{
|
||||
|
||||
if (SockTokenExistedInList (&Sock->SndTokenList, Event) ||
|
||||
SockTokenExistedInList (&Sock->ProcessingSndTokenList, Event) ||
|
||||
SockTokenExistedInList (&Sock->RcvTokenList, Event) ||
|
||||
SockTokenExistedInList (&Sock->ListenTokenList, Event)
|
||||
) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((Sock->ConnectionToken != NULL) &&
|
||||
(Sock->ConnectionToken->Event == Event)) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((Sock->CloseToken != NULL) && (Sock->CloseToken->Event == Event)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Buffer a token into the specific list of socket Sock.
|
||||
|
||||
@param Sock Pointer to the instance's socket.
|
||||
@param List Pointer to the list to store the token.
|
||||
@param Token Pointer to the token to be buffered.
|
||||
@param DataLen The data length of the buffer contained in Token.
|
||||
|
||||
@return Pointer to the token that wraps Token. If NULL, error condition occurred.
|
||||
|
||||
**/
|
||||
SOCK_TOKEN *
|
||||
SockBufferToken (
|
||||
IN SOCKET *Sock,
|
||||
IN NET_LIST_ENTRY *List,
|
||||
IN VOID *Token,
|
||||
IN UINT32 DataLen
|
||||
)
|
||||
{
|
||||
SOCK_TOKEN *SockToken;
|
||||
|
||||
SockToken = NetAllocatePool (sizeof (SOCK_TOKEN));
|
||||
if (NULL == SockToken) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockBufferIOToken: No Memory "
|
||||
"to allocate SockToken\n"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SockToken->Sock = Sock;
|
||||
SockToken->Token = (SOCK_COMPLETION_TOKEN *) Token;
|
||||
SockToken->RemainDataLen = DataLen;
|
||||
NetListInsertTail (List, &SockToken->TokenList);
|
||||
|
||||
return SockToken;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destory the socket Sock and its associated protocol control block.
|
||||
|
||||
@param Sock The socket to be destroyed.
|
||||
|
||||
@retval EFI_SUCCESS The socket Sock is destroyed successfully.
|
||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockDestroyChild (
|
||||
IN SOCKET *Sock
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
ASSERT (Sock && Sock->ProtoHandler);
|
||||
|
||||
if (Sock->IsDestroyed) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Sock->IsDestroyed = TRUE;
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockDestroyChild: Get the lock to "
|
||||
"access socket failed with %r\n", Status));
|
||||
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
//
|
||||
// force protocol layer to detach the PCB
|
||||
//
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_DETACH, NULL);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockDestroyChild: Protocol detach socket"
|
||||
" failed with %r\n", Status));
|
||||
|
||||
Sock->IsDestroyed = FALSE;
|
||||
} else if (SOCK_IS_CONFIGURED (Sock)) {
|
||||
|
||||
SockConnFlush (Sock);
|
||||
SockSetState (Sock, SO_CLOSED);
|
||||
|
||||
Sock->ConfigureState = SO_UNCONFIGURED;
|
||||
}
|
||||
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
SockDestroy (Sock);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Create a socket and its associated protocol control block
|
||||
with the intial data SockInitData and protocol specific
|
||||
data ProtoData.
|
||||
|
||||
@param SockInitData Inital data to setting the socket.
|
||||
@param ProtoData Pointer to the protocol specific data.
|
||||
@param Len Length of the protocol specific data.
|
||||
|
||||
@return Pointer to the newly created socket. If NULL, error condition occured.
|
||||
|
||||
**/
|
||||
SOCKET *
|
||||
SockCreateChild (
|
||||
IN SOCK_INIT_DATA *SockInitData,
|
||||
IN VOID *ProtoData,
|
||||
IN UINT32 Len
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
EFI_STATUS Status;
|
||||
|
||||
ASSERT (ProtoData && (Len <= PROTO_RESERVED_LEN));
|
||||
|
||||
//
|
||||
// create a new socket
|
||||
//
|
||||
Sock = SockCreate (SockInitData);
|
||||
if (NULL == Sock) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockCreateChild: No resource to "
|
||||
"create a new socket\n"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Open the
|
||||
//
|
||||
|
||||
//
|
||||
// copy the protodata into socket
|
||||
//
|
||||
NetCopyMem (Sock->ProtoReserved, ProtoData, Len);
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockCreateChild: Get the lock to "
|
||||
"access socket failed with %r\n", Status));
|
||||
|
||||
SockDestroy (Sock);
|
||||
return NULL;
|
||||
}
|
||||
//
|
||||
// inform the protocol layer to attach the socket
|
||||
// with a new protocol control block
|
||||
//
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_ATTACH, NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockCreateChild: Protocol failed to"
|
||||
" attach a socket with %r\n", Status));
|
||||
|
||||
SockDestroy (Sock);
|
||||
Sock = NULL;
|
||||
}
|
||||
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
return Sock;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Configure the specific socket Sock using configuration data
|
||||
ConfigData.
|
||||
|
||||
@param Sock Pointer to the socket to be configured.
|
||||
@param ConfigData Pointer to the configuration data.
|
||||
|
||||
@retval EFI_SUCCESS The socket is configured successfully.
|
||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket or the
|
||||
socket is already configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockConfigure (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *ConfigData
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockConfigure: Get the access for "
|
||||
"socket failed with %r", Status));
|
||||
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (SOCK_IS_CONFIGURED (Sock)) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto OnExit;
|
||||
}
|
||||
|
||||
ASSERT (Sock->State == SO_CLOSED);
|
||||
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_CONFIGURE, ConfigData);
|
||||
|
||||
OnExit:
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initiate a connection establishment process.
|
||||
|
||||
@param Sock Pointer to the socket to initiate the initate the
|
||||
connection.
|
||||
@param Token Pointer to the token used for the connection
|
||||
operation.
|
||||
|
||||
@retval EFI_SUCCESS The connection is initialized successfully.
|
||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
||||
socket is closed, or the socket is not configured to
|
||||
be an active one, or the token is already in one of
|
||||
this socket's lists.
|
||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
||||
finished.
|
||||
@retval EFI_NOT_STARTED The socket is not configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockConnect (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Token
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_EVENT Event;
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockConnect: Get the access for "
|
||||
"socket failed with %r", Status));
|
||||
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
||||
Status = EFI_NO_MAPPING;
|
||||
goto OnExit;
|
||||
}
|
||||
|
||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
||||
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto OnExit;
|
||||
}
|
||||
|
||||
if (!SOCK_IS_CLOSED (Sock) || !SOCK_IS_CONFIGURED_ACTIVE (Sock)) {
|
||||
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto OnExit;
|
||||
}
|
||||
|
||||
Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;
|
||||
|
||||
if (SockTokenExisted (Sock, Event)) {
|
||||
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto OnExit;
|
||||
}
|
||||
|
||||
Sock->ConnectionToken = (SOCK_COMPLETION_TOKEN *) Token;
|
||||
SockSetState (Sock, SO_CONNECTING);
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_CONNECT, NULL);
|
||||
|
||||
OnExit:
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Issue a listen token to get an existed connected network instance
|
||||
or wait for a connection if there is none.
|
||||
|
||||
@param Sock Pointer to the socket to accept connections.
|
||||
@param Token The token to accept a connection.
|
||||
|
||||
@retval EFI_SUCCESS Either a connection is accpeted or the Token is
|
||||
buffered for further acception.
|
||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
||||
socket is closed, or the socket is not configured to
|
||||
be a passive one, or the token is already in one of
|
||||
this socket's lists.
|
||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
||||
finished.
|
||||
@retval EFI_NOT_STARTED The socket is not configured.
|
||||
@retval EFI_OUT_OF_RESOURCE Failed to buffer the Token due to memory limit.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockAccept (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Token
|
||||
)
|
||||
{
|
||||
EFI_TCP4_LISTEN_TOKEN *ListenToken;
|
||||
NET_LIST_ENTRY *ListEntry;
|
||||
EFI_STATUS Status;
|
||||
SOCKET *Socket;
|
||||
EFI_EVENT Event;
|
||||
|
||||
ASSERT (SOCK_STREAM == Sock->Type);
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockAccept: Get the access for socket"
|
||||
" failed with %r", Status));
|
||||
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
||||
Status = EFI_NO_MAPPING;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
||||
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (!SOCK_IS_LISTENING (Sock)) {
|
||||
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;
|
||||
|
||||
if (SockTokenExisted (Sock, Event)) {
|
||||
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
ListenToken = (EFI_TCP4_LISTEN_TOKEN *) Token;
|
||||
|
||||
//
|
||||
// Check if a connection has already in this Sock->ConnectionList
|
||||
//
|
||||
NET_LIST_FOR_EACH (ListEntry, &Sock->ConnectionList) {
|
||||
|
||||
Socket = NET_LIST_USER_STRUCT (ListEntry, SOCKET, ConnectionList);
|
||||
|
||||
if (SOCK_IS_CONNECTED (Socket)) {
|
||||
ListenToken->NewChildHandle = Socket->SockHandle;
|
||||
SIGNAL_TOKEN (&(ListenToken->CompletionToken), EFI_SUCCESS);
|
||||
|
||||
NetListRemoveEntry (ListEntry);
|
||||
|
||||
ASSERT (Socket->Parent);
|
||||
|
||||
Socket->Parent->ConnCnt--;
|
||||
|
||||
SOCK_DEBUG_WARN (("SockAccept: Accept a socket,"
|
||||
"now conncount is %d", Socket->Parent->ConnCnt)
|
||||
);
|
||||
Socket->Parent = NULL;
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Buffer this token for latter incoming connection request
|
||||
//
|
||||
if (NULL == SockBufferToken (Sock, &(Sock->ListenTokenList), Token, 0)) {
|
||||
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Exit:
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Issue a token with data to the socket to send out.
|
||||
|
||||
@param Sock Pointer to the socket to process the token with
|
||||
data.
|
||||
@param Token The token with data that needs to send out.
|
||||
|
||||
@retval EFI_SUCCESS The token is processed successfully.
|
||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
||||
socket is closed, or the socket is not in a
|
||||
synchronized state , or the token is already in one
|
||||
of this socket's lists.
|
||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
||||
finished.
|
||||
@retval EFI_NOT_STARTED The socket is not configured.
|
||||
@retval EFI_OUT_OF_RESOURCE Failed to buffer the token due to memory limit.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockSend (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Token
|
||||
)
|
||||
{
|
||||
SOCK_IO_TOKEN *SndToken;
|
||||
EFI_EVENT Event;
|
||||
UINT32 FreeSpace;
|
||||
EFI_TCP4_TRANSMIT_DATA *TxData;
|
||||
EFI_STATUS Status;
|
||||
SOCK_TOKEN *SockToken;
|
||||
UINT32 DataLen;
|
||||
|
||||
ASSERT (SOCK_STREAM == Sock->Type);
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockSend: Get the access for socket"
|
||||
" failed with %r", Status));
|
||||
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
||||
Status = EFI_NO_MAPPING;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
SndToken = (SOCK_IO_TOKEN *) Token;
|
||||
TxData = (EFI_TCP4_TRANSMIT_DATA *) SndToken->Packet.TxData;
|
||||
|
||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (!(SOCK_IS_CONNECTING (Sock) || SOCK_IS_CONNECTED (Sock))) {
|
||||
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// check if a token is already in the token buffer
|
||||
//
|
||||
Event = SndToken->Token.Event;
|
||||
|
||||
if (SockTokenExisted (Sock, Event)) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
DataLen = TxData->DataLength;
|
||||
|
||||
//
|
||||
// process this sending token now or buffer it only?
|
||||
//
|
||||
FreeSpace = SockGetFreeSpace (Sock, SOCK_SND_BUF);
|
||||
|
||||
if ((FreeSpace < Sock->SndBuffer.LowWater) || !SOCK_IS_CONNECTED (Sock)) {
|
||||
|
||||
SockToken = SockBufferToken (
|
||||
Sock,
|
||||
&Sock->SndTokenList,
|
||||
SndToken,
|
||||
DataLen
|
||||
);
|
||||
|
||||
if (NULL == SockToken) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
} else {
|
||||
|
||||
SockToken = SockBufferToken (
|
||||
Sock,
|
||||
&Sock->ProcessingSndTokenList,
|
||||
SndToken,
|
||||
DataLen
|
||||
);
|
||||
|
||||
if (NULL == SockToken) {
|
||||
SOCK_DEBUG_ERROR (("SockSend: Failed to buffer IO token into"
|
||||
" socket processing SndToken List\n", Status));
|
||||
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Status = SockProcessTcpSndData (Sock, TxData);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
SOCK_DEBUG_ERROR (("SockSend: Failed to process "
|
||||
"Snd Data\n", Status));
|
||||
|
||||
NetListRemoveEntry (&(SockToken->TokenList));
|
||||
NetFreePool (SockToken);
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Issue a token to get data from the socket.
|
||||
|
||||
@param Sock Pointer to the socket to get data from.
|
||||
@param Token The token to store the received data from the
|
||||
socket.
|
||||
|
||||
@retval EFI_SUCCESS The token is processed successfully.
|
||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
||||
socket is closed, or the socket is not in a
|
||||
synchronized state , or the token is already in one
|
||||
of this socket's lists.
|
||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
||||
finished.
|
||||
@retval EFI_NOT_STARTED The socket is not configured.
|
||||
@retval EFI_CONNECTION_FIN The connection is closed and there is no more data.
|
||||
@retval EFI_OUT_OF_RESOURCE Failed to buffer the token due to memory limit.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockRcv (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Token
|
||||
)
|
||||
{
|
||||
SOCK_IO_TOKEN *RcvToken;
|
||||
UINT32 RcvdBytes;
|
||||
EFI_STATUS Status;
|
||||
EFI_EVENT Event;
|
||||
|
||||
ASSERT (SOCK_STREAM == Sock->Type);
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockRcv: Get the access for socket"
|
||||
" failed with %r", Status));
|
||||
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
||||
|
||||
Status = EFI_NO_MAPPING;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
||||
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (!(SOCK_IS_CONNECTED (Sock) || SOCK_IS_CONNECTING (Sock))) {
|
||||
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
RcvToken = (SOCK_IO_TOKEN *) Token;
|
||||
|
||||
//
|
||||
// check if a token is already in the token buffer of this socket
|
||||
//
|
||||
Event = RcvToken->Token.Event;
|
||||
if (SockTokenExisted (Sock, Event)) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
RcvToken = (SOCK_IO_TOKEN *) Token;
|
||||
RcvdBytes = GET_RCV_DATASIZE (Sock);
|
||||
|
||||
//
|
||||
// check whether an error has happened before
|
||||
//
|
||||
if (EFI_ABORTED != Sock->SockError) {
|
||||
|
||||
SIGNAL_TOKEN (&(RcvToken->Token), Sock->SockError);
|
||||
Sock->SockError = EFI_ABORTED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// check whether can not receive and there is no any
|
||||
// data buffered in Sock->RcvBuffer
|
||||
//
|
||||
if (SOCK_IS_NO_MORE_DATA (Sock) && (0 == RcvdBytes)) {
|
||||
|
||||
Status = EFI_CONNECTION_FIN;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (RcvdBytes != 0) {
|
||||
Status = SockProcessRcvToken (Sock, RcvToken);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_CONSUMED, NULL);
|
||||
} else {
|
||||
|
||||
if (NULL == SockBufferToken (Sock, &Sock->RcvTokenList, RcvToken, 0)) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Reset the socket and its associated protocol control block.
|
||||
|
||||
@param Sock Pointer to the socket to be flushed.
|
||||
|
||||
@retval EFI_SUCCESS The socket is flushed successfully.
|
||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockFlush (
|
||||
IN SOCKET *Sock
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
ASSERT (SOCK_STREAM == Sock->Type);
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockFlush: Get the access for socket"
|
||||
" failed with %r", Status));
|
||||
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (!SOCK_IS_CONFIGURED (Sock)) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_FLUSH, NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockFlush: Protocol failed handling"
|
||||
" SOCK_FLUSH with %r", Status));
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
SOCK_ERROR (Sock, EFI_ABORTED);
|
||||
SockConnFlush (Sock);
|
||||
SockSetState (Sock, SO_CLOSED);
|
||||
|
||||
Sock->ConfigureState = SO_UNCONFIGURED;
|
||||
|
||||
Exit:
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Close or abort the socket associated connection.
|
||||
|
||||
@param Sock Pointer to the socket of the connection to close or
|
||||
abort.
|
||||
@param Token The token for close operation.
|
||||
@param OnAbort TRUE for aborting the connection, FALSE to close it.
|
||||
|
||||
@retval EFI_SUCCESS The close or abort operation is initialized
|
||||
successfully.
|
||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
|
||||
socket is closed, or the socket is not in a
|
||||
synchronized state , or the token is already in one
|
||||
of this socket's lists.
|
||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
||||
finished.
|
||||
@retval EFI_NOT_STARTED The socket is not configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockClose (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Token,
|
||||
IN BOOLEAN OnAbort
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_EVENT Event;
|
||||
|
||||
ASSERT (SOCK_STREAM == Sock->Type);
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
if (EFI_ERROR (Status)) {
|
||||
SOCK_DEBUG_ERROR (("SockClose: Get the access for socket"
|
||||
" failed with %r", Status));
|
||||
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
||||
Status = EFI_NO_MAPPING;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (SOCK_IS_DISCONNECTING (Sock)) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Event = ((SOCK_COMPLETION_TOKEN *) Token)->Event;
|
||||
|
||||
if (SockTokenExisted (Sock, Event)) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Sock->CloseToken = Token;
|
||||
SockSetState (Sock, SO_DISCONNECTING);
|
||||
|
||||
if (OnAbort) {
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_ABORT, NULL);
|
||||
} else {
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_CLOSE, NULL);
|
||||
}
|
||||
|
||||
Exit:
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Get the mode data of the low layer protocol.
|
||||
|
||||
@param Sock Pointer to the socket to get mode data from.
|
||||
@param Mode Pointer to the data to store the low layer mode
|
||||
information.
|
||||
|
||||
@retval EFI_SUCCESS The mode data is got successfully.
|
||||
@retval EFI_NOT_STARTED The socket is not configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockGetMode (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Mode
|
||||
)
|
||||
{
|
||||
return Sock->ProtoHandler (Sock, SOCK_MODE, Mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Configure the low level protocol to join a multicast group for
|
||||
this socket's connection.
|
||||
|
||||
@param Sock Pointer to the socket of the connection to join the
|
||||
specific multicast group.
|
||||
@param GroupInfo Pointer to the multicast group info.
|
||||
|
||||
@retval EFI_SUCCESS The configuration is done successfully.
|
||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
|
||||
@retval EFI_NOT_STARTED The socket is not configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockGroup (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *GroupInfo
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
SOCK_DEBUG_ERROR (("SockGroup: Get the access for socket"
|
||||
" failed with %r", Status));
|
||||
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_GROUP, GroupInfo);
|
||||
|
||||
Exit:
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Add or remove route information in IP route table associated
|
||||
with this socket.
|
||||
|
||||
@param Sock Pointer to the socket associated with the IP route
|
||||
table to operate on.
|
||||
@param RouteInfo Pointer to the route information to be processed.
|
||||
|
||||
@retval EFI_SUCCESS The route table is updated successfully.
|
||||
@retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
|
||||
@retval EFI_NO_MAPPING The IP address configuration operation is not
|
||||
finished.
|
||||
@retval EFI_NOT_STARTED The socket is not configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SockRoute (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *RouteInfo
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = NET_TRYLOCK (&(Sock->Lock));
|
||||
if (EFI_ERROR (Status)) {
|
||||
SOCK_DEBUG_ERROR (("SockRoute: Get the access for socket"
|
||||
" failed with %r", Status));
|
||||
|
||||
return EFI_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (SOCK_IS_NO_MAPPING (Sock)) {
|
||||
Status = EFI_NO_MAPPING;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (SOCK_IS_UNCONFIGURED (Sock)) {
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_ROUTE, RouteInfo);
|
||||
|
||||
Exit:
|
||||
NET_UNLOCK (&(Sock->Lock));
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,518 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Socket.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _SOCKET_H_
|
||||
#define _SOCKET_H_
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/IP4.h>
|
||||
#include <Protocol/Tcp4.h>
|
||||
#include <Protocol/Udp4.h>
|
||||
|
||||
#include <Library/NetLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
|
||||
#define SOCK_SND_BUF 0
|
||||
#define SOCK_RCV_BUF 1
|
||||
|
||||
#define SOCK_BUFF_LOW_WATER 2 * 1024
|
||||
#define SOCK_RCV_BUFF_SIZE 8 * 1024
|
||||
#define SOCK_SND_BUFF_SIZE 8 * 1024
|
||||
#define SOCK_BACKLOG 5
|
||||
|
||||
#define PROTO_RESERVED_LEN 20
|
||||
|
||||
#define SO_NO_MORE_DATA 0x0001
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
// When a socket is created it enters into SO_UNCONFIGURED,
|
||||
// no actions can be taken on this socket, only after calling
|
||||
// SockConfigure. The state transition diagram of socket is
|
||||
// as following:
|
||||
//
|
||||
// SO_UNCONFIGURED --- SO_CONFIGURED --- SO_CONNECTING
|
||||
// ^ | |
|
||||
// | ---> SO_LISTENING |
|
||||
// | |
|
||||
// |------------------SO_DISCONNECTING<-- SO_CONNECTED
|
||||
//
|
||||
// A passive socket can only go into SO_LISTENING and
|
||||
// SO_UNCONFIGURED state. SO_XXXING state is a middle state
|
||||
// when a socket is undergoing a protocol procedure such
|
||||
// as requesting a TCP connection.
|
||||
//
|
||||
//
|
||||
//
|
||||
typedef enum {
|
||||
SO_CLOSED = 0,
|
||||
SO_LISTENING,
|
||||
SO_CONNECTING,
|
||||
SO_CONNECTED,
|
||||
SO_DISCONNECTING
|
||||
} SOCK_STATE;
|
||||
|
||||
typedef enum {
|
||||
SO_UNCONFIGURED = 0,
|
||||
SO_CONFIGURED_ACTIVE,
|
||||
SO_CONFIGURED_PASSIVE,
|
||||
SO_NO_MAPPING
|
||||
} SOCK_CONFIGURE_STATE;
|
||||
|
||||
#define SOCK_NO_MORE_DATA(Sock) ((Sock)->Flag |= SO_NO_MORE_DATA)
|
||||
|
||||
#define SOCK_IS_UNCONFIGURED(Sock) ((Sock)->ConfigureState == SO_UNCONFIGURED)
|
||||
|
||||
#define SOCK_IS_CONFIGURED(Sock) \
|
||||
(((Sock)->ConfigureState == SO_CONFIGURED_ACTIVE) || \
|
||||
((Sock)->ConfigureState == SO_CONFIGURED_PASSIVE))
|
||||
|
||||
#define SOCK_IS_CONFIGURED_ACTIVE(Sock) \
|
||||
((Sock)->ConfigureState == SO_CONFIGURED_ACTIVE)
|
||||
|
||||
#define SOCK_IS_CONNECTED_PASSIVE(Sock) \
|
||||
((Sock)->ConfigureState == SO_CONFIGURED_PASSIVE)
|
||||
|
||||
#define SOCK_IS_NO_MAPPING(Sock) \
|
||||
((Sock)->ConfigureState == SO_NO_MAPPING)
|
||||
|
||||
#define SOCK_IS_CLOSED(Sock) ((Sock)->State == SO_CLOSED)
|
||||
|
||||
#define SOCK_IS_LISTENING(Sock) ((Sock)->State == SO_LISTENING)
|
||||
|
||||
#define SOCK_IS_CONNECTING(Sock) ((Sock)->State == SO_CONNECTING)
|
||||
|
||||
#define SOCK_IS_CONNECTED(Sock) ((Sock)->State == SO_CONNECTED)
|
||||
|
||||
#define SOCK_IS_DISCONNECTING(Sock) ((Sock)->State == SO_DISCONNECTING)
|
||||
|
||||
#define SOCK_IS_NO_MORE_DATA(Sock) (0 != ((Sock)->Flag & SO_NO_MORE_DATA))
|
||||
|
||||
#define SOCK_SIGNATURE EFI_SIGNATURE_32 ('S', 'O', 'C', 'K')
|
||||
|
||||
#define SOCK_FROM_THIS(a) CR ((a), SOCKET, NetProtocol, SOCK_SIGNATURE)
|
||||
|
||||
#define SET_RCV_BUFFSIZE(Sock, Size) ((Sock)->RcvBuffer.HighWater = (Size))
|
||||
|
||||
#define GET_RCV_BUFFSIZE(Sock) ((Sock)->RcvBuffer.HighWater)
|
||||
|
||||
#define GET_RCV_DATASIZE(Sock) (((Sock)->RcvBuffer.DataQueue)->BufSize)
|
||||
|
||||
#define SET_SND_BUFFSIZE(Sock, Size) ((Sock)->SndBuffer.HighWater = (Size))
|
||||
|
||||
#define GET_SND_BUFFSIZE(Sock) ((Sock)->SndBuffer.HighWater)
|
||||
|
||||
#define GET_SND_DATASIZE(Sock) (((Sock)->SndBuffer.DataQueue)->BufSize)
|
||||
|
||||
#define SET_BACKLOG(Sock, Value) ((Sock)->BackLog = (Value))
|
||||
|
||||
#define GET_BACKLOG(Sock) ((Sock)->BackLog)
|
||||
|
||||
#define SOCK_ERROR(Sock, Error) ((Sock)->SockError = (Error))
|
||||
|
||||
#define SND_BUF_HDR_LEN(Sock) \
|
||||
((SockBufFirst (&((Sock)->SndBuffer)))->TotalSize)
|
||||
|
||||
#define RCV_BUF_HDR_LEN(Sock) \
|
||||
((SockBufFirst (&((Sock)->RcvBuffer)))->TotalSize)
|
||||
|
||||
#define SOCK_FROM_TOKEN(Token) (((SOCK_TOKEN *) (Token))->Sock)
|
||||
|
||||
#define PROTO_TOKEN_FORM_SOCK(SockToken, Type) \
|
||||
((Type *) (((SOCK_TOKEN *) (SockToken))->Token))
|
||||
|
||||
typedef struct _SOCKET SOCKET;
|
||||
|
||||
typedef struct _SOCK_COMPLETION_TOKEN {
|
||||
EFI_EVENT Event;
|
||||
EFI_STATUS Status;
|
||||
} SOCK_COMPLETION_TOKEN;
|
||||
|
||||
typedef struct _SOCK_IO_TOKEN {
|
||||
SOCK_COMPLETION_TOKEN Token;
|
||||
union {
|
||||
VOID *RxData;
|
||||
VOID *TxData;
|
||||
} Packet;
|
||||
} SOCK_IO_TOKEN;
|
||||
|
||||
//
|
||||
// the request issued from socket layer to protocol layer
|
||||
//
|
||||
typedef enum {
|
||||
SOCK_ATTACH, // attach current socket to a new PCB
|
||||
SOCK_DETACH, // detach current socket from the PCB
|
||||
SOCK_CONFIGURE, // configure attached PCB
|
||||
SOCK_FLUSH, // flush attached PCB
|
||||
SOCK_SND, // need protocol to send something
|
||||
SOCK_SNDPUSH, // need protocol to send pushed data
|
||||
SOCK_SNDURG, // need protocol to send urgent data
|
||||
SOCK_CONSUMED, // application has retrieved data from socket
|
||||
SOCK_CONNECT, // need to connect to a peer
|
||||
SOCK_CLOSE, // need to close the protocol process
|
||||
SOCK_ABORT, // need to reset the protocol process
|
||||
SOCK_POLL, // need to poll to the protocol layer
|
||||
SOCK_ROUTE, // need to add a route information
|
||||
SOCK_MODE, // need to get the mode data of the protocol
|
||||
SOCK_GROUP // need to join a mcast group
|
||||
} SOCK_REQUEST;
|
||||
|
||||
//
|
||||
// the socket type
|
||||
//
|
||||
typedef enum {
|
||||
SOCK_DGRAM, // this socket providing datagram service
|
||||
SOCK_STREAM // this socket providing stream service
|
||||
} SOCK_TYPE;
|
||||
|
||||
//
|
||||
// the handler of protocol for request from socket
|
||||
//
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(*SOCK_PROTO_HANDLER) (
|
||||
IN SOCKET * Socket, // the socket issuing the request to protocol
|
||||
IN SOCK_REQUEST Request, // the request issued by socket
|
||||
IN VOID *RequestData // the request related data
|
||||
);
|
||||
|
||||
//
|
||||
// the buffer structure of rcvd data and send data used by socket
|
||||
//
|
||||
typedef struct _SOCK_BUFFER {
|
||||
UINT32 HighWater; // the buffersize upper limit of sock_buffer
|
||||
UINT32 LowWater; // the low warter mark of sock_buffer
|
||||
NET_BUF_QUEUE *DataQueue; // the queue to buffer data
|
||||
} SOCK_BUFFER;
|
||||
|
||||
//
|
||||
// the initialize data for create a new socket
|
||||
//
|
||||
typedef struct _SOCK_INIT_DATA {
|
||||
SOCK_TYPE Type;
|
||||
SOCK_STATE State;
|
||||
|
||||
SOCKET *Parent; // the parent of this socket
|
||||
UINT32 BackLog; // the connection limit for listening socket
|
||||
UINT32 SndBufferSize; // the high warter mark of send buffer
|
||||
UINT32 RcvBufferSize; // the high warter mark of receive buffer
|
||||
VOID *Protocol; // the pointer to protocol function template
|
||||
// wanted to install on socket
|
||||
|
||||
SOCK_PROTO_HANDLER ProtoHandler;
|
||||
|
||||
EFI_HANDLE DriverBinding; // the driver binding handle
|
||||
} SOCK_INIT_DATA;
|
||||
|
||||
//
|
||||
// socket provided oprerations for low layer protocol
|
||||
//
|
||||
|
||||
//
|
||||
// socket provided operations for user interface
|
||||
//
|
||||
VOID
|
||||
SockSetState (
|
||||
IN SOCKET *Sock,
|
||||
IN SOCK_STATE State
|
||||
);
|
||||
|
||||
//
|
||||
// when the connection establishment process for a Sock
|
||||
// is finished low layer protocol calling this function
|
||||
// to notify socket layer
|
||||
//
|
||||
VOID
|
||||
SockConnEstablished (
|
||||
IN SOCKET *Sock
|
||||
);
|
||||
|
||||
VOID
|
||||
SockConnClosed (
|
||||
IN SOCKET *Sock
|
||||
);
|
||||
|
||||
//
|
||||
// called by low layer protocol to trim send buffer of
|
||||
// Sock, when Count data is sent out completely
|
||||
//
|
||||
VOID
|
||||
SockDataSent (
|
||||
IN SOCKET *Sock,
|
||||
IN UINT32 Count
|
||||
);
|
||||
|
||||
//
|
||||
// called by low layer protocol to get Len of data from
|
||||
// socket to send and copy it in Dest
|
||||
//
|
||||
UINT32
|
||||
SockGetDataToSend (
|
||||
IN SOCKET *Sock,
|
||||
IN UINT32 Offset,
|
||||
IN UINT32 Len,
|
||||
IN UINT8 *Dest
|
||||
);
|
||||
|
||||
//
|
||||
// called by low layer protocol to notify socket no more data can be
|
||||
// received
|
||||
//
|
||||
VOID
|
||||
SockNoMoreData (
|
||||
IN SOCKET *Sock
|
||||
);
|
||||
|
||||
//
|
||||
// called by low layer protocol to append a NetBuffer
|
||||
// to rcv buffer of sock
|
||||
//
|
||||
VOID
|
||||
SockDataRcvd (
|
||||
IN SOCKET *Sock,
|
||||
IN NET_BUF *NetBuffer,
|
||||
IN UINT32 UrgLen
|
||||
);
|
||||
|
||||
UINT32
|
||||
SockGetFreeSpace (
|
||||
IN SOCKET *Sock,
|
||||
IN UINT32 Which
|
||||
);
|
||||
|
||||
SOCKET *
|
||||
SockClone (
|
||||
IN SOCKET *Sock
|
||||
);
|
||||
|
||||
VOID
|
||||
SockRcvdErr (
|
||||
IN SOCKET *Sock,
|
||||
IN EFI_STATUS Error
|
||||
);
|
||||
|
||||
//
|
||||
// the socket structure representing a network service access point
|
||||
//
|
||||
typedef struct _SOCKET {
|
||||
|
||||
//
|
||||
// socket description information
|
||||
//
|
||||
UINT32 Signature;
|
||||
EFI_HANDLE SockHandle; // the virtual handle of the socket
|
||||
EFI_HANDLE DriverBinding; // socket't driver binding protocol
|
||||
SOCK_CONFIGURE_STATE ConfigureState;
|
||||
SOCK_TYPE Type;
|
||||
SOCK_STATE State;
|
||||
UINT16 Flag;
|
||||
NET_LOCK Lock; // the lock of socket
|
||||
SOCK_BUFFER SndBuffer; // send buffer of application's data
|
||||
SOCK_BUFFER RcvBuffer; // receive buffer of received data
|
||||
EFI_STATUS SockError; // the error returned by low layer protocol
|
||||
BOOLEAN IsDestroyed;
|
||||
|
||||
//
|
||||
// fields used to manage the connection request
|
||||
//
|
||||
UINT32 BackLog; // the limit of connection to this socket
|
||||
UINT32 ConnCnt; // the current count of connections to it
|
||||
SOCKET *Parent; // listening parent that accept the connection
|
||||
NET_LIST_ENTRY ConnectionList; // the connections maintained by this socket
|
||||
//
|
||||
// the queue to buffer application's asynchronous token
|
||||
//
|
||||
NET_LIST_ENTRY ListenTokenList;
|
||||
NET_LIST_ENTRY RcvTokenList;
|
||||
NET_LIST_ENTRY SndTokenList;
|
||||
NET_LIST_ENTRY ProcessingSndTokenList;
|
||||
|
||||
SOCK_COMPLETION_TOKEN *ConnectionToken; // app's token to signal if connected
|
||||
SOCK_COMPLETION_TOKEN *CloseToken; // app's token to signal if closed
|
||||
|
||||
//
|
||||
// interface for low level protocol
|
||||
//
|
||||
SOCK_PROTO_HANDLER ProtoHandler; // the request handler of protocol
|
||||
UINT8 ProtoReserved[PROTO_RESERVED_LEN]; // Data fields reserved for protocol
|
||||
union {
|
||||
EFI_TCP4_PROTOCOL TcpProtocol;
|
||||
EFI_UDP4_PROTOCOL UdpProtocol;
|
||||
} NetProtocol;
|
||||
} SOCKET;
|
||||
|
||||
//
|
||||
// the token structure buffered in socket layer
|
||||
//
|
||||
typedef struct _SOCK_TOKEN {
|
||||
NET_LIST_ENTRY TokenList; // the entry to add in the token list
|
||||
SOCK_COMPLETION_TOKEN *Token; // The application's token
|
||||
UINT32 RemainDataLen; // unprocessed data length
|
||||
SOCKET *Sock; // the poninter to the socket this token
|
||||
// belongs to
|
||||
} SOCK_TOKEN;
|
||||
|
||||
//
|
||||
// reserved data to access the NET_BUF delivered by UDP driver
|
||||
//
|
||||
typedef struct _UDP_RSV_DATA {
|
||||
EFI_TIME TimeStamp;
|
||||
EFI_UDP4_SESSION_DATA Session;
|
||||
} UDP_RSV_DATA;
|
||||
|
||||
//
|
||||
// reserved data to access the NET_BUF delivered by TCP driver
|
||||
//
|
||||
typedef struct _TCP_RSV_DATA {
|
||||
UINT32 UrgLen;
|
||||
} TCP_RSV_DATA;
|
||||
|
||||
//
|
||||
// call it to creat a socket and attach it to a PCB
|
||||
//
|
||||
SOCKET *
|
||||
SockCreateChild (
|
||||
IN SOCK_INIT_DATA *SockInitData,
|
||||
IN VOID *ProtoData,
|
||||
IN UINT32 Len
|
||||
);
|
||||
|
||||
//
|
||||
// call it to destroy a socket and its related PCB
|
||||
//
|
||||
EFI_STATUS
|
||||
SockDestroyChild (
|
||||
IN SOCKET *Sock
|
||||
);
|
||||
|
||||
//
|
||||
// call it to configure a socket and its related PCB
|
||||
//
|
||||
EFI_STATUS
|
||||
SockConfigure (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *ConfigData
|
||||
);
|
||||
|
||||
//
|
||||
// call it to connect a socket to the peer
|
||||
//
|
||||
EFI_STATUS
|
||||
SockConnect (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Token
|
||||
);
|
||||
|
||||
//
|
||||
// call it to issue an asynchronous listen token to the socket
|
||||
//
|
||||
EFI_STATUS
|
||||
SockAccept (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Token
|
||||
);
|
||||
|
||||
//
|
||||
// Call it to send data using this socket
|
||||
//
|
||||
EFI_STATUS
|
||||
SockSend (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Token
|
||||
);
|
||||
|
||||
//
|
||||
// Call it to receive data from this socket
|
||||
//
|
||||
EFI_STATUS
|
||||
SockRcv (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Token
|
||||
);
|
||||
|
||||
//
|
||||
// Call it to flush a socket
|
||||
//
|
||||
EFI_STATUS
|
||||
SockFlush (
|
||||
IN SOCKET *Sock
|
||||
);
|
||||
|
||||
//
|
||||
// Call it to close a socket in the light of policy in Token
|
||||
//
|
||||
EFI_STATUS
|
||||
SockClose (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Token,
|
||||
IN BOOLEAN OnAbort
|
||||
);
|
||||
|
||||
//
|
||||
// Call it to get the mode data of low layer protocol
|
||||
//
|
||||
EFI_STATUS
|
||||
SockGetMode (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *Mode
|
||||
);
|
||||
|
||||
//
|
||||
// call it to add this socket instance into a group
|
||||
//
|
||||
EFI_STATUS
|
||||
SockGroup (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *GroupInfo
|
||||
);
|
||||
|
||||
//
|
||||
// call it to add a route entry for this socket instance
|
||||
//
|
||||
EFI_STATUS
|
||||
SockRoute (
|
||||
IN SOCKET *Sock,
|
||||
IN VOID *RouteInfo
|
||||
);
|
||||
|
||||
//
|
||||
// Supporting function to operate on socket buffer
|
||||
//
|
||||
NET_BUF *
|
||||
SockBufFirst (
|
||||
IN SOCK_BUFFER *Sockbuf
|
||||
);
|
||||
|
||||
NET_BUF *
|
||||
SockBufNext (
|
||||
IN SOCK_BUFFER *Sockbuf,
|
||||
IN NET_BUF *SockEntry
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,680 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Dispatcher.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "Tcp4Main.h"
|
||||
|
||||
#define TCP_COMP_VAL(Min, Max, Default, Val) \
|
||||
((((Val) <= (Max)) && ((Val) >= (Min))) ? (Val) : (Default))
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
Tcp4Route (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP4_ROUTE_INFO *RouteInfo
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Add or remove a route entry in the IP route table associated
|
||||
with this TCP instance.
|
||||
|
||||
Arguments:
|
||||
|
||||
Tcb - Pointer to the TCP_CB of this TCP instance.
|
||||
RouteInfo - Pointer to the route info to be processed.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The operation completed successfully.
|
||||
EFI_NOT_STARTED - The driver instance has not been started.
|
||||
EFI_NO_MAPPING - When using the default address, configuration(DHCP,
|
||||
BOOTP, RARP, etc.) is not finished yet.
|
||||
EFI_OUT_OF_RESOURCES - Could not add the entry to the routing table.
|
||||
EFI_NOT_FOUND - This route is not in the routing table
|
||||
(when RouteInfo->DeleteRoute is TRUE).
|
||||
EFI_ACCESS_DENIED - The route is already defined in the routing table
|
||||
(when RouteInfo->DeleteRoute is FALSE).
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_IP4_PROTOCOL *Ip;
|
||||
|
||||
Ip = Tcb->IpInfo->Ip;
|
||||
|
||||
ASSERT (Ip);
|
||||
|
||||
return Ip->Routes (
|
||||
Ip,
|
||||
RouteInfo->DeleteRoute,
|
||||
RouteInfo->SubnetAddress,
|
||||
RouteInfo->SubnetMask,
|
||||
RouteInfo->GatewayAddress
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Get the operational settings of this TCP instance.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
@param Mode Pointer to the buffer to store the operational
|
||||
settings.
|
||||
|
||||
@retval EFI_SUCCESS The mode data is read.
|
||||
@retval EFI_NOT_STARTED No configuration data is available because this
|
||||
instance hasn't been started.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
Tcp4GetMode (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP4_MODE_DATA *Mode
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
EFI_TCP4_CONFIG_DATA *ConfigData;
|
||||
EFI_TCP4_ACCESS_POINT *AccessPoint;
|
||||
EFI_TCP4_OPTION *Option;
|
||||
EFI_IP4_PROTOCOL *Ip;
|
||||
|
||||
Sock = Tcb->Sk;
|
||||
|
||||
if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp4ConfigData != NULL)) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
if (Mode->Tcp4State) {
|
||||
*(Mode->Tcp4State) = Tcb->State;
|
||||
}
|
||||
|
||||
if (Mode->Tcp4ConfigData) {
|
||||
|
||||
ConfigData = Mode->Tcp4ConfigData;
|
||||
AccessPoint = &(ConfigData->AccessPoint);
|
||||
Option = ConfigData->ControlOption;
|
||||
|
||||
ConfigData->TypeOfService = Tcb->TOS;
|
||||
ConfigData->TimeToLive = Tcb->TTL;
|
||||
|
||||
AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr;
|
||||
|
||||
EFI_IP4 (AccessPoint->StationAddress) = Tcb->LocalEnd.Ip;
|
||||
AccessPoint->SubnetMask = Tcb->SubnetMask;
|
||||
AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);
|
||||
|
||||
EFI_IP4 (AccessPoint->RemoteAddress) = Tcb->RemoteEnd.Ip;
|
||||
AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);
|
||||
AccessPoint->ActiveFlag = (BOOLEAN) (Tcb->State != TCP_LISTEN);
|
||||
|
||||
if (Option != NULL) {
|
||||
Option->ReceiveBufferSize = GET_RCV_BUFFSIZE (Tcb->Sk);
|
||||
Option->SendBufferSize = GET_SND_BUFFSIZE (Tcb->Sk);
|
||||
Option->MaxSynBackLog = GET_BACKLOG (Tcb->Sk);
|
||||
|
||||
Option->ConnectionTimeout = Tcb->ConnectTimeout / TCP_TICK_HZ;
|
||||
Option->DataRetries = Tcb->MaxRexmit;
|
||||
Option->FinTimeout = Tcb->FinWait2Timeout / TCP_TICK_HZ;
|
||||
Option->TimeWaitTimeout = Tcb->TimeWaitTimeout / TCP_TICK_HZ;
|
||||
Option->KeepAliveProbes = Tcb->MaxKeepAlive;
|
||||
Option->KeepAliveTime = Tcb->KeepAliveIdle / TCP_TICK_HZ;
|
||||
Option->KeepAliveInterval = Tcb->KeepAlivePeriod / TCP_TICK_HZ;
|
||||
|
||||
Option->EnableNagle = !TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);
|
||||
Option->EnableTimeStamp = !TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS);
|
||||
Option->EnableWindowScaling = !TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS);
|
||||
|
||||
Option->EnableSelectiveAck = FALSE;
|
||||
Option->EnablePathMtuDiscovery = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
Ip = Tcb->IpInfo->Ip;
|
||||
ASSERT (Ip);
|
||||
|
||||
return Ip->GetModeData (Ip, Mode->Ip4ModeData, Mode->MnpConfigData, Mode->SnpModeData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
If AP->StationPort isn't zero, check whether the access point
|
||||
is registered, else generate a random station port for this
|
||||
access point.
|
||||
|
||||
@param AP Pointer to the access point.
|
||||
|
||||
@retval EFI_SUCCESS The check is passed or the port is assigned.
|
||||
@retval EFI_INVALID_PARAMETER The non-zero station port is already used.
|
||||
@retval EFI_OUT_OF_RESOURCES No port can be allocated.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
Tcp4Bind (
|
||||
IN EFI_TCP4_ACCESS_POINT *AP
|
||||
)
|
||||
{
|
||||
BOOLEAN Cycle;
|
||||
|
||||
if (0 != AP->StationPort) {
|
||||
//
|
||||
// check if a same endpoint is bound
|
||||
//
|
||||
if (TcpFindTcbByPeer (&AP->StationAddress, AP->StationPort)) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// generate a random port
|
||||
//
|
||||
Cycle = FALSE;
|
||||
|
||||
if (TCP4_PORT_USER_RESERVED == mTcp4RandomPort) {
|
||||
mTcp4RandomPort = TCP4_PORT_KNOWN;
|
||||
}
|
||||
|
||||
mTcp4RandomPort++;
|
||||
|
||||
while (TcpFindTcbByPeer (&AP->StationAddress, mTcp4RandomPort)) {
|
||||
|
||||
mTcp4RandomPort++;
|
||||
|
||||
if (mTcp4RandomPort <= TCP4_PORT_KNOWN) {
|
||||
|
||||
if (Cycle) {
|
||||
TCP4_DEBUG_ERROR (("Tcp4Bind: no port can be allocated "
|
||||
"for this pcb\n"));
|
||||
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
mTcp4RandomPort = TCP4_PORT_KNOWN + 1;
|
||||
|
||||
Cycle = TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AP->StationPort = mTcp4RandomPort;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Flush the Tcb add its associated protocols..
|
||||
|
||||
@param Tcb Pointer to the TCP_CB to be flushed.
|
||||
|
||||
@retval EFI_SUCCESS The operation is completed successfully.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
Tcp4FlushPcb (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
TCP4_PROTO_DATA *TcpProto;
|
||||
|
||||
IpIoConfigIp (Tcb->IpInfo, NULL);
|
||||
|
||||
Sock = Tcb->Sk;
|
||||
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
||||
|
||||
if (SOCK_IS_CONFIGURED (Sock)) {
|
||||
NetListRemoveEntry (&Tcb->List);
|
||||
|
||||
TcpSetVariableData (TcpProto->TcpService);
|
||||
}
|
||||
|
||||
NetbufFreeList (&Tcb->SndQue);
|
||||
NetbufFreeList (&Tcb->RcvQue);
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
Tcp4AttachPcb (
|
||||
IN SOCKET *Sk
|
||||
)
|
||||
{
|
||||
TCP_CB *Tcb;
|
||||
TCP4_PROTO_DATA *ProtoData;
|
||||
IP_IO *IpIo;
|
||||
|
||||
Tcb = NetAllocateZeroPool (sizeof (TCP_CB));
|
||||
|
||||
if (Tcb == NULL) {
|
||||
|
||||
TCP4_DEBUG_ERROR (("Tcp4ConfigurePcb: failed to allocate a TCB\n"));
|
||||
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
|
||||
IpIo = ProtoData->TcpService->IpIo;
|
||||
|
||||
//
|
||||
// Create an IpInfo for this Tcb.
|
||||
//
|
||||
Tcb->IpInfo = IpIoAddIp (IpIo);
|
||||
if (Tcb->IpInfo == NULL) {
|
||||
|
||||
NetFreePool (Tcb);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
NetListInit (&Tcb->List);
|
||||
NetListInit (&Tcb->SndQue);
|
||||
NetListInit (&Tcb->RcvQue);
|
||||
|
||||
Tcb->State = TCP_CLOSED;
|
||||
Tcb->Sk = Sk;
|
||||
ProtoData->TcpPcb = Tcb;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
Tcp4DetachPcb (
|
||||
IN SOCKET *Sk
|
||||
)
|
||||
{
|
||||
TCP4_PROTO_DATA *ProtoData;
|
||||
TCP_CB *Tcb;
|
||||
|
||||
ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
|
||||
Tcb = ProtoData->TcpPcb;
|
||||
|
||||
ASSERT (Tcb != NULL);
|
||||
|
||||
Tcp4FlushPcb (Tcb);
|
||||
|
||||
IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);
|
||||
|
||||
NetFreePool (Tcb);
|
||||
|
||||
ProtoData->TcpPcb = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Configure the Tcb using CfgData.
|
||||
|
||||
@param Sk Pointer to the socket of this TCP instance.
|
||||
@param SkTcb Pointer to the TCP_CB of this TCP instance.
|
||||
@param CfgData Pointer to the TCP configuration data.
|
||||
|
||||
@retval EFI_SUCCESS The operation is completed successfully.
|
||||
@retval EFI_INVALID_PARAMETER A same access point has been configured in
|
||||
another TCP instance.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
Tcp4ConfigurePcb (
|
||||
IN SOCKET *Sk,
|
||||
IN EFI_TCP4_CONFIG_DATA *CfgData
|
||||
)
|
||||
{
|
||||
IP_IO *IpIo;
|
||||
EFI_IP4_CONFIG_DATA IpCfgData;
|
||||
EFI_STATUS Status;
|
||||
EFI_TCP4_OPTION *Option;
|
||||
TCP4_PROTO_DATA *TcpProto;
|
||||
TCP_CB *Tcb;
|
||||
|
||||
ASSERT (CfgData && Sk && Sk->SockHandle);
|
||||
|
||||
TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved;
|
||||
Tcb = TcpProto->TcpPcb;
|
||||
IpIo = TcpProto->TcpService->IpIo;
|
||||
|
||||
ASSERT (Tcb != NULL);
|
||||
|
||||
//
|
||||
// Add Ip for send pkt to the peer
|
||||
//
|
||||
IpCfgData = mIpIoDefaultIpConfigData;
|
||||
IpCfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
|
||||
IpCfgData.UseDefaultAddress = CfgData->AccessPoint.UseDefaultAddress;
|
||||
IpCfgData.StationAddress = CfgData->AccessPoint.StationAddress;
|
||||
IpCfgData.SubnetMask = CfgData->AccessPoint.SubnetMask;
|
||||
IpCfgData.ReceiveTimeout = (UINT32) (-1);
|
||||
|
||||
//
|
||||
// Configure the IP instance this Tcb consumes.
|
||||
//
|
||||
Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto OnExit;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the default address info if the instance is configured to use default address.
|
||||
//
|
||||
if (CfgData->AccessPoint.UseDefaultAddress) {
|
||||
CfgData->AccessPoint.StationAddress = IpCfgData.StationAddress;
|
||||
CfgData->AccessPoint.SubnetMask = IpCfgData.SubnetMask;
|
||||
}
|
||||
|
||||
//
|
||||
// check if we can bind this endpoint in CfgData
|
||||
//
|
||||
Status = Tcp4Bind (&(CfgData->AccessPoint));
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
TCP4_DEBUG_ERROR (("Tcp4ConfigurePcb: Bind endpoint failed "
|
||||
"with %r\n", Status));
|
||||
|
||||
goto OnExit;
|
||||
}
|
||||
|
||||
//
|
||||
// Initalize the operating information in this Tcb
|
||||
//
|
||||
ASSERT (Tcb->State == TCP_CLOSED &&
|
||||
NetListIsEmpty (&Tcb->SndQue) &&
|
||||
NetListIsEmpty (&Tcb->RcvQue));
|
||||
|
||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);
|
||||
Tcb->State = TCP_CLOSED;
|
||||
|
||||
Tcb->SndMss = 536;
|
||||
Tcb->RcvMss = TcpGetRcvMss (Sk);
|
||||
|
||||
Tcb->SRtt = 0;
|
||||
Tcb->Rto = 3 * TCP_TICK_HZ;
|
||||
|
||||
Tcb->CWnd = Tcb->SndMss;
|
||||
Tcb->Ssthresh = 0xffffffff;
|
||||
|
||||
Tcb->CongestState = TCP_CONGEST_OPEN;
|
||||
|
||||
Tcb->KeepAliveIdle = TCP_KEEPALIVE_IDLE_MIN;
|
||||
Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD;
|
||||
Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE;
|
||||
Tcb->MaxRexmit = TCP_MAX_LOSS;
|
||||
Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME;
|
||||
Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME;
|
||||
Tcb->ConnectTimeout = TCP_CONNECT_TIME;
|
||||
|
||||
//
|
||||
// initialize Tcb in the light of CfgData
|
||||
//
|
||||
Tcb->TTL = CfgData->TimeToLive;
|
||||
Tcb->TOS = CfgData->TypeOfService;
|
||||
|
||||
Tcb->LocalEnd.Ip = EFI_IP4 (CfgData->AccessPoint.StationAddress);
|
||||
Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort);
|
||||
Tcb->SubnetMask = CfgData->AccessPoint.SubnetMask;
|
||||
|
||||
Tcb->RemoteEnd.Ip = EFI_IP4 (CfgData->AccessPoint.RemoteAddress);
|
||||
Tcb->RemoteEnd.Port = HTONS (CfgData->AccessPoint.RemotePort);
|
||||
|
||||
Option = CfgData->ControlOption;
|
||||
|
||||
if (Option != NULL) {
|
||||
SET_RCV_BUFFSIZE (
|
||||
Sk,
|
||||
TCP_COMP_VAL (TCP_RCV_BUF_SIZE_MIN,
|
||||
TCP_RCV_BUF_SIZE,
|
||||
TCP_RCV_BUF_SIZE,
|
||||
Option->ReceiveBufferSize)
|
||||
);
|
||||
SET_SND_BUFFSIZE (
|
||||
Sk,
|
||||
TCP_COMP_VAL (TCP_SND_BUF_SIZE_MIN,
|
||||
TCP_SND_BUF_SIZE,
|
||||
TCP_SND_BUF_SIZE,
|
||||
Option->SendBufferSize)
|
||||
);
|
||||
|
||||
SET_BACKLOG (
|
||||
Sk,
|
||||
TCP_COMP_VAL (TCP_BACKLOG_MIN,
|
||||
TCP_BACKLOG,
|
||||
TCP_BACKLOG,
|
||||
Option->MaxSynBackLog)
|
||||
);
|
||||
|
||||
Tcb->MaxRexmit = (UINT16) TCP_COMP_VAL (
|
||||
TCP_MAX_LOSS_MIN,
|
||||
TCP_MAX_LOSS,
|
||||
TCP_MAX_LOSS,
|
||||
Option->DataRetries
|
||||
);
|
||||
Tcb->FinWait2Timeout = TCP_COMP_VAL (
|
||||
TCP_FIN_WAIT2_TIME,
|
||||
TCP_FIN_WAIT2_TIME_MAX,
|
||||
TCP_FIN_WAIT2_TIME,
|
||||
Option->FinTimeout * TCP_TICK_HZ
|
||||
);
|
||||
|
||||
if (Option->TimeWaitTimeout != 0) {
|
||||
Tcb->TimeWaitTimeout = TCP_COMP_VAL (
|
||||
TCP_TIME_WAIT_TIME,
|
||||
TCP_TIME_WAIT_TIME_MAX,
|
||||
TCP_TIME_WAIT_TIME,
|
||||
Option->TimeWaitTimeout * TCP_TICK_HZ
|
||||
);
|
||||
} else {
|
||||
Tcb->TimeWaitTimeout = 0;
|
||||
}
|
||||
|
||||
if (Option->KeepAliveProbes != 0) {
|
||||
TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);
|
||||
|
||||
Tcb->MaxKeepAlive = (UINT8) TCP_COMP_VAL (
|
||||
TCP_MAX_KEEPALIVE_MIN,
|
||||
TCP_MAX_KEEPALIVE,
|
||||
TCP_MAX_KEEPALIVE,
|
||||
Option->KeepAliveProbes
|
||||
);
|
||||
Tcb->KeepAliveIdle = TCP_COMP_VAL (
|
||||
TCP_KEEPALIVE_IDLE_MIN,
|
||||
TCP_KEEPALIVE_IDLE_MAX,
|
||||
TCP_KEEPALIVE_IDLE_MIN,
|
||||
Option->KeepAliveTime * TCP_TICK_HZ
|
||||
);
|
||||
Tcb->KeepAlivePeriod = TCP_COMP_VAL (
|
||||
TCP_KEEPALIVE_PERIOD_MIN,
|
||||
TCP_KEEPALIVE_PERIOD,
|
||||
TCP_KEEPALIVE_PERIOD,
|
||||
Option->KeepAliveInterval * TCP_TICK_HZ
|
||||
);
|
||||
}
|
||||
|
||||
Tcb->ConnectTimeout = TCP_COMP_VAL (
|
||||
TCP_CONNECT_TIME_MIN,
|
||||
TCP_CONNECT_TIME,
|
||||
TCP_CONNECT_TIME,
|
||||
Option->ConnectionTimeout * TCP_TICK_HZ
|
||||
);
|
||||
|
||||
if (Option->EnableNagle == FALSE) {
|
||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);
|
||||
}
|
||||
|
||||
if (Option->EnableTimeStamp == FALSE) {
|
||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);
|
||||
}
|
||||
|
||||
if (Option->EnableWindowScaling == FALSE) {
|
||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// update state of Tcb and socket
|
||||
//
|
||||
if (CfgData->AccessPoint.ActiveFlag == FALSE) {
|
||||
|
||||
TcpSetState (Tcb, TCP_LISTEN);
|
||||
SockSetState (Sk, SO_LISTENING);
|
||||
|
||||
Sk->ConfigureState = SO_CONFIGURED_PASSIVE;
|
||||
} else {
|
||||
|
||||
Sk->ConfigureState = SO_CONFIGURED_ACTIVE;
|
||||
}
|
||||
|
||||
TcpInsertTcb (Tcb);
|
||||
|
||||
OnExit:
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
The procotol handler provided to the socket layer, used to
|
||||
dispatch the socket level requests by calling the corresponding
|
||||
TCP layer functions.
|
||||
|
||||
@param Sock Pointer to the socket of this TCP instance.
|
||||
@param Request The code of this operation request.
|
||||
@param Data Pointer to the operation specific data passed in
|
||||
together with the operation request.
|
||||
|
||||
@retval EFI_SUCCESS The socket request is completed successfully.
|
||||
@retval other The error status returned by the corresponding TCP
|
||||
layer function.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Tcp4Dispatcher (
|
||||
IN SOCKET *Sock,
|
||||
IN SOCK_REQUEST Request,
|
||||
IN VOID *Data OPTIONAL
|
||||
)
|
||||
{
|
||||
TCP_CB *Tcb;
|
||||
TCP4_PROTO_DATA *ProtoData;
|
||||
EFI_IP4_PROTOCOL *Ip;
|
||||
|
||||
ProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
||||
Tcb = ProtoData->TcpPcb;
|
||||
|
||||
switch (Request) {
|
||||
case SOCK_POLL:
|
||||
Ip = ProtoData->TcpService->IpIo->Ip;
|
||||
Ip->Poll (Ip);
|
||||
break;
|
||||
|
||||
case SOCK_CONSUMED:
|
||||
//
|
||||
// After user received data from socket buffer, socket will
|
||||
// notify TCP using this message to give it a chance to send out
|
||||
// window update information
|
||||
//
|
||||
ASSERT (Tcb);
|
||||
TcpOnAppConsume (Tcb);
|
||||
break;
|
||||
|
||||
case SOCK_SND:
|
||||
|
||||
ASSERT (Tcb);
|
||||
TcpOnAppSend (Tcb);
|
||||
break;
|
||||
|
||||
case SOCK_CLOSE:
|
||||
|
||||
TcpOnAppClose (Tcb);
|
||||
|
||||
break;
|
||||
|
||||
case SOCK_ABORT:
|
||||
|
||||
TcpOnAppAbort (Tcb);
|
||||
|
||||
break;
|
||||
|
||||
case SOCK_SNDPUSH:
|
||||
Tcb->SndPsh = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk);
|
||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_PSH);
|
||||
|
||||
break;
|
||||
|
||||
case SOCK_SNDURG:
|
||||
Tcb->SndUp = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk) - 1;
|
||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);
|
||||
|
||||
break;
|
||||
|
||||
case SOCK_CONNECT:
|
||||
|
||||
TcpOnAppConnect (Tcb);
|
||||
|
||||
break;
|
||||
|
||||
case SOCK_ATTACH:
|
||||
|
||||
return Tcp4AttachPcb (Sock);
|
||||
|
||||
break;
|
||||
|
||||
case SOCK_FLUSH:
|
||||
|
||||
Tcp4FlushPcb (Tcb);
|
||||
|
||||
break;
|
||||
|
||||
case SOCK_DETACH:
|
||||
|
||||
Tcp4DetachPcb (Sock);
|
||||
|
||||
break;
|
||||
|
||||
case SOCK_CONFIGURE:
|
||||
|
||||
return Tcp4ConfigurePcb (
|
||||
Sock,
|
||||
(EFI_TCP4_CONFIG_DATA *) Data
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case SOCK_MODE:
|
||||
|
||||
ASSERT (Data && Tcb);
|
||||
|
||||
return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *) Data);
|
||||
|
||||
break;
|
||||
|
||||
case SOCK_ROUTE:
|
||||
|
||||
ASSERT (Data && Tcb);
|
||||
|
||||
return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *) Data);
|
||||
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
}
|
|
@ -0,0 +1,669 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Driver.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "Tcp4Main.h"
|
||||
|
||||
|
||||
UINT16 mTcp4RandomPort;
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName;
|
||||
|
||||
TCP4_HEARTBEAT_TIMER mTcp4Timer = {
|
||||
NULL,
|
||||
0
|
||||
};
|
||||
|
||||
EFI_TCP4_PROTOCOL mTcp4ProtocolTemplate = {
|
||||
Tcp4GetModeData,
|
||||
Tcp4Configure,
|
||||
Tcp4Routes,
|
||||
Tcp4Connect,
|
||||
Tcp4Accept,
|
||||
Tcp4Transmit,
|
||||
Tcp4Receive,
|
||||
Tcp4Close,
|
||||
Tcp4Cancel,
|
||||
Tcp4Poll
|
||||
};
|
||||
|
||||
SOCK_INIT_DATA mTcp4DefaultSockData = {
|
||||
SOCK_STREAM,
|
||||
0,
|
||||
NULL,
|
||||
TCP_BACKLOG,
|
||||
TCP_SND_BUF_SIZE,
|
||||
TCP_RCV_BUF_SIZE,
|
||||
&mTcp4ProtocolTemplate,
|
||||
Tcp4Dispatcher,
|
||||
NULL,
|
||||
};
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL mTcp4DriverBinding = {
|
||||
Tcp4DriverBindingSupported,
|
||||
Tcp4DriverBindingStart,
|
||||
Tcp4DriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
EFI_SERVICE_BINDING_PROTOCOL mTcp4ServiceBinding = {
|
||||
Tcp4ServiceBindingCreateChild,
|
||||
Tcp4ServiceBindingDestroyChild
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Create and start the heartbeat timer for TCP driver.
|
||||
|
||||
None.
|
||||
|
||||
@retval EFI_SUCCESS The timer is successfully created and started.
|
||||
@retval other The timer is not created.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
Tcp4CreateTimer (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
if (mTcp4Timer.RefCnt == 0) {
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_TIMER | EVT_NOTIFY_SIGNAL,
|
||||
NET_TPL_TIMER,
|
||||
TcpTicking,
|
||||
NULL,
|
||||
&mTcp4Timer.TimerEvent
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
|
||||
Status = gBS->SetTimer (
|
||||
mTcp4Timer.TimerEvent,
|
||||
TimerPeriodic,
|
||||
(UINT64) (TICKS_PER_SECOND / TCP_TICK_HZ)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
|
||||
mTcp4Timer.RefCnt++;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop and destroy the heartbeat timer for TCP driver.
|
||||
|
||||
None.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
Tcp4DestroyTimer (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ASSERT (mTcp4Timer.RefCnt > 0);
|
||||
|
||||
mTcp4Timer.RefCnt--;
|
||||
|
||||
if (mTcp4Timer.RefCnt > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
gBS->SetTimer (mTcp4Timer.TimerEvent, TimerCancel, 0);
|
||||
gBS->CloseEvent (mTcp4Timer.TimerEvent);
|
||||
mTcp4Timer.TimerEvent = NULL;
|
||||
}
|
||||
|
||||
//@MT: EFI_DRIVER_ENTRY_POINT (Tcp4DriverEntryPoint)
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4DriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The entry point for Tcp4 driver. used to install
|
||||
Tcp4 driver on the ImageHandle.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - The firmware allocated handle for this
|
||||
driver image.
|
||||
SystemTable - Pointer to the EFI system table.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Driver loaded.
|
||||
other - Driver not loaded.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 Seed;
|
||||
|
||||
//
|
||||
// Install the TCP4 Driver Binding Protocol
|
||||
//
|
||||
Status = NetLibInstallAllDriverProtocols (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&mTcp4DriverBinding,
|
||||
ImageHandle,
|
||||
&gTcp4ComponentName,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
//
|
||||
// Initialize ISS and random port.
|
||||
//
|
||||
Seed = NetRandomInitSeed ();
|
||||
mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;
|
||||
mTcp4RandomPort = TCP4_PORT_KNOWN +
|
||||
(UINT16) (NET_RANDOM(Seed) % TCP4_PORT_KNOWN);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test to see if this driver supports ControllerHandle.
|
||||
|
||||
@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_ALREADY_STARTED This driver is already running on this device.
|
||||
@retval other This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL * This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Test for the Tcp4ServiceBinding Protocol
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Test for the Ip4 Protocol
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiIp4ServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle.
|
||||
|
||||
@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 The driver is added to ControllerHandle.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
|
||||
driver.
|
||||
@retval other The driver cannot be added to ControllerHandle.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL * This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TCP4_SERVICE_DATA *TcpServiceData;
|
||||
IP_IO_OPEN_DATA OpenData;
|
||||
|
||||
TcpServiceData = NetAllocateZeroPool (sizeof (TCP4_SERVICE_DATA));
|
||||
|
||||
if (NULL == TcpServiceData) {
|
||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Have no enough"
|
||||
" resource to create a Tcp Servcie Data!\n"));
|
||||
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a new IP IO to Consume it
|
||||
//
|
||||
TcpServiceData->IpIo = IpIoCreate (This->DriverBindingHandle, ControllerHandle);
|
||||
if (NULL == TcpServiceData->IpIo) {
|
||||
|
||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Have no enough"
|
||||
" resource to create an Ip Io!\n"));
|
||||
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ReleaseServiceData;
|
||||
}
|
||||
|
||||
//
|
||||
// Configure and start IpIo.
|
||||
//
|
||||
NetZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));
|
||||
|
||||
OpenData.IpConfigData = mIpIoDefaultIpConfigData;
|
||||
OpenData.IpConfigData.DefaultProtocol = EFI_IP_PROTO_TCP;
|
||||
|
||||
OpenData.PktRcvdNotify = Tcp4RxCallback;
|
||||
Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ReleaseServiceData;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the timer event used by TCP driver
|
||||
//
|
||||
Status = Tcp4CreateTimer ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Create TcpTimer"
|
||||
" Event failed with %r\n", Status));
|
||||
|
||||
goto ReleaseIpIo;
|
||||
}
|
||||
|
||||
//
|
||||
// Install the Tcp4ServiceBinding Protocol on the
|
||||
// controller handle
|
||||
//
|
||||
TcpServiceData->Tcp4ServiceBinding = mTcp4ServiceBinding;
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ControllerHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
&TcpServiceData->Tcp4ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Install Tcp4 Service Binding"
|
||||
" Protocol failed for %r\n", Status));
|
||||
|
||||
goto ReleaseTimer;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize member in TcpServiceData
|
||||
//
|
||||
TcpServiceData->ControllerHandle = ControllerHandle;
|
||||
TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE;
|
||||
TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;
|
||||
|
||||
TcpSetVariableData (TcpServiceData);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ReleaseTimer:
|
||||
|
||||
Tcp4DestroyTimer ();
|
||||
|
||||
ReleaseIpIo:
|
||||
|
||||
IpIoDestroy (TcpServiceData->IpIo);
|
||||
|
||||
ReleaseServiceData:
|
||||
|
||||
NetFreePool (TcpServiceData);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle.
|
||||
|
||||
@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 This driver is removed from ControllerHandle.
|
||||
@retval other This driver is not removed from ControllerHandle.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE NicHandle;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *Tcp4ServiceBinding;
|
||||
TCP4_SERVICE_DATA *TcpServiceData;
|
||||
TCP_CB *TcpPcb;
|
||||
SOCKET *Sock;
|
||||
TCP4_PROTO_DATA *TcpProto;
|
||||
NET_LIST_ENTRY *Entry;
|
||||
NET_LIST_ENTRY *NextEntry;
|
||||
|
||||
// Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
|
||||
//
|
||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
|
||||
if (NicHandle == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve the TCP driver Data Structure
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
(VOID **) &Tcp4ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Locate Tcp4 Service "
|
||||
" Binding Protocol failed with %r\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
TcpServiceData = TCP4_FROM_THIS (Tcp4ServiceBinding);
|
||||
|
||||
//
|
||||
// Kill TCP driver
|
||||
//
|
||||
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpRunQue) {
|
||||
TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
||||
|
||||
//
|
||||
// Try to destroy this child
|
||||
//
|
||||
Sock = TcpPcb->Sk;
|
||||
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
||||
|
||||
if (TcpProto->TcpService == TcpServiceData) {
|
||||
Status = SockDestroyChild (Sock);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
|
||||
"instance failed with %r\n", Status));
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpListenQue) {
|
||||
TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
||||
|
||||
//
|
||||
// Try to destroy this child
|
||||
//
|
||||
Sock = TcpPcb->Sk;
|
||||
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
||||
|
||||
if (TcpProto->TcpService == TcpServiceData) {
|
||||
Status = SockDestroyChild (TcpPcb->Sk);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
|
||||
"instance failed with %r\n", Status));
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Uninstall TCP servicebinding protocol
|
||||
//
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
NicHandle,
|
||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||
Tcp4ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Uninstall TCP service "
|
||||
"binding protocol failed with %r\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Destroy the IpIO consumed by TCP driver
|
||||
//
|
||||
Status = IpIoDestroy (TcpServiceData->IpIo);
|
||||
|
||||
//
|
||||
// Destroy the heartbeat timer.
|
||||
//
|
||||
Tcp4DestroyTimer ();
|
||||
|
||||
//
|
||||
// Clear the variable.
|
||||
//
|
||||
TcpClearVariableData (TcpServiceData);
|
||||
|
||||
//
|
||||
// Release the TCP service data
|
||||
//
|
||||
NetFreePool (TcpServiceData);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Creates a child handle with a set of TCP4 services.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If
|
||||
it is NULL, then a new handle is created. If it is
|
||||
not NULL, then the I/O services are added to the
|
||||
existing child handle.
|
||||
|
||||
@retval EFI_SUCCESS The child handle is created.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources to create the
|
||||
child.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
TCP4_SERVICE_DATA *TcpServiceData;
|
||||
TCP4_PROTO_DATA TcpProto;
|
||||
EFI_STATUS Status;
|
||||
VOID *Ip4;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (NULL == This || NULL == ChildHandle) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
TcpServiceData = TCP4_FROM_THIS (This);
|
||||
TcpProto.TcpService = TcpServiceData;
|
||||
TcpProto.TcpPcb = NULL;
|
||||
|
||||
//
|
||||
// Create a tcp instance with defualt Tcp default
|
||||
// sock init data and TcpProto
|
||||
//
|
||||
mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;
|
||||
|
||||
Sock = SockCreateChild (&mTcp4DefaultSockData, &TcpProto, sizeof (TCP4_PROTO_DATA));
|
||||
if (NULL == Sock) {
|
||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingCreateChild: "
|
||||
"No resource to create a Tcp Child\n"));
|
||||
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
*ChildHandle = Sock->SockHandle;
|
||||
|
||||
//
|
||||
// Open the default Ip4 protocol of IP_IO BY_DRIVER.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
TcpServiceData->IpIo->ChildHandle,
|
||||
&gEfiIp4ProtocolGuid,
|
||||
(VOID **) &Ip4,
|
||||
TcpServiceData->DriverBindingHandle,
|
||||
Sock->SockHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
SockDestroyChild (Sock);
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destroys a child handle with a set of UDP4 services.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ChildHandle Handle of the child to be destroyed.
|
||||
|
||||
@retval EFI_SUCCESS The TCP4 services are removed from the child
|
||||
handle.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval other The child handle is not destroyed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_TCP4_PROTOCOL *Tcp4;
|
||||
SOCKET *Sock;
|
||||
TCP4_PROTO_DATA *TcpProtoData;
|
||||
TCP4_SERVICE_DATA *TcpServiceData;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (NULL == This || NULL == ChildHandle) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
//
|
||||
// retrieve the Tcp4 protocol from ChildHandle
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiTcp4ProtocolGuid,
|
||||
(VOID **) &Tcp4,
|
||||
mTcp4DriverBinding.DriverBindingHandle,
|
||||
ChildHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// destroy this sock and related Tcp protocol control
|
||||
// block
|
||||
//
|
||||
Sock = SOCK_FROM_THIS (Tcp4);
|
||||
TcpProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
||||
TcpServiceData = TcpProtoData->TcpService;
|
||||
|
||||
Status = SockDestroyChild (Sock);
|
||||
|
||||
//
|
||||
// Close the Ip4 protocol.
|
||||
//
|
||||
gBS->CloseProtocol (
|
||||
TcpServiceData->IpIo->ChildHandle,
|
||||
&gEfiIp4ProtocolGuid,
|
||||
TcpServiceData->DriverBindingHandle,
|
||||
ChildHandle
|
||||
);
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Driver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _TCP4_DRIVER_H_
|
||||
#define _TCP4_DRIVER_H_
|
||||
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
#include <Library/IpIoLib.h>
|
||||
|
||||
#define TCP4_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('T', 'C', 'P', '4')
|
||||
|
||||
#define TCP4_PORT_KNOWN 1024
|
||||
#define TCP4_PORT_USER_RESERVED 65535
|
||||
|
||||
typedef struct _TCP4_HEARTBEAT_TIMER {
|
||||
EFI_EVENT TimerEvent;
|
||||
INTN RefCnt;
|
||||
} TCP4_HEARTBEAT_TIMER;
|
||||
|
||||
typedef struct _TCP4_SERVICE_DATA {
|
||||
UINT32 Signature;
|
||||
EFI_HANDLE ControllerHandle;
|
||||
IP_IO *IpIo; // IP Io consumed by TCP4
|
||||
EFI_SERVICE_BINDING_PROTOCOL Tcp4ServiceBinding;
|
||||
EFI_HANDLE DriverBindingHandle;
|
||||
CHAR16 *MacString;
|
||||
} TCP4_SERVICE_DATA;
|
||||
|
||||
//
|
||||
// Prototype for TCP4 driver Rcv callback function registered to IP_IO
|
||||
//
|
||||
VOID
|
||||
Tcp4RxCallback (
|
||||
IN EFI_STATUS Status,
|
||||
IN ICMP_ERROR IcmpErr,
|
||||
IN EFI_NET_SESSION_DATA *NetSession,
|
||||
IN NET_BUF *Pkt,
|
||||
IN VOID *Context OPTIONAL
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpSendIpPacket (
|
||||
IN TCP_CB *Tcb,
|
||||
IN NET_BUF *Nbuf,
|
||||
IN UINT32 Src,
|
||||
IN UINT32 Dest
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
Tcp4Dispatcher (
|
||||
IN SOCKET *Sock,
|
||||
IN SOCK_REQUEST Request,
|
||||
IN VOID *Data OPTIONAL
|
||||
);
|
||||
|
||||
typedef struct _TCP4_PROTO_DATA {
|
||||
TCP4_SERVICE_DATA *TcpService;
|
||||
TCP_CB *TcpPcb;
|
||||
} TCP4_PROTO_DATA;
|
||||
|
||||
#define TCP4_FROM_THIS(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
TCP4_SERVICE_DATA, \
|
||||
Tcp4ServiceBinding, \
|
||||
TCP4_DRIVER_SIGNATURE \
|
||||
)
|
||||
|
||||
//
|
||||
// Function prototype for the driver's entry point
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4DriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
);
|
||||
|
||||
//
|
||||
// Function prototypes for the Drivr Binding Protocol
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL * This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL * This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
);
|
||||
|
||||
//
|
||||
// Function ptototypes for the ServiceBinding Prococol
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,77 @@
|
|||
#/** @file
|
||||
# Component name for module Tcp4
|
||||
#
|
||||
# FIX ME!
|
||||
# Copyright (c) 2006, Intel Corporation. All right reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = Tcp4Dxe
|
||||
FILE_GUID = 6d6963ab-906d-4a65-a7ca-bd40e5d6af4d
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = Tcp4DriverEntryPoint
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources.common]
|
||||
SockImpl.c
|
||||
SockInterface.c
|
||||
Tcp4Proto.h
|
||||
Tcp4Main.h
|
||||
SockImpl.h
|
||||
Tcp4Output.c
|
||||
Tcp4Timer.c
|
||||
Tcp4Option.h
|
||||
Tcp4Dispatcher.c
|
||||
Tcp4Input.c
|
||||
Tcp4Misc.c
|
||||
Tcp4Main.c
|
||||
Socket.h
|
||||
ComponentName.c
|
||||
Tcp4Driver.h
|
||||
Tcp4Io.c
|
||||
Tcp4Driver.c
|
||||
Tcp4Func.h
|
||||
Tcp4Option.c
|
||||
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
UefiLib
|
||||
BaseLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
UefiRuntimeServicesTableLib
|
||||
DebugLib
|
||||
NetLib
|
||||
IpIoLib
|
||||
|
||||
[Protocols]
|
||||
gEfiIp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiTcp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiIp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiTcp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<MsaHeader>
|
||||
<ModuleName>Tcp4Dxe</ModuleName>
|
||||
<ModuleType>DXE_DRIVER</ModuleType>
|
||||
<GuidValue>6d6963ab-906d-4a65-a7ca-bd40e5d6af4d</GuidValue>
|
||||
<Version>1.0</Version>
|
||||
<Abstract>Component name for module Tcp4</Abstract>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2006, Intel Corporation. All right reserved.</Copyright>
|
||||
<License>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.</License>
|
||||
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
|
||||
</MsaHeader>
|
||||
<ModuleDefinitions>
|
||||
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
|
||||
<BinaryModule>false</BinaryModule>
|
||||
<OutputFileBasename>Tcp4Dxe</OutputFileBasename>
|
||||
</ModuleDefinitions>
|
||||
<LibraryClassDefinitions>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>DebugLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiRuntimeServicesTableLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiDriverEntryPoint</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiBootServicesTableLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>BaseLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiLib</Keyword>
|
||||
</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>Tcp4Option.c</Filename>
|
||||
<Filename>Tcp4Func.h</Filename>
|
||||
<Filename>Tcp4Driver.c</Filename>
|
||||
<Filename>Tcp4Io.c</Filename>
|
||||
<Filename>Tcp4Driver.h</Filename>
|
||||
<Filename>ComponentName.c</Filename>
|
||||
<Filename>Socket.h</Filename>
|
||||
<Filename>Tcp4Main.c</Filename>
|
||||
<Filename>Tcp4Misc.c</Filename>
|
||||
<Filename>Tcp4Input.c</Filename>
|
||||
<Filename>Tcp4Dispatcher.c</Filename>
|
||||
<Filename>Tcp4Option.h</Filename>
|
||||
<Filename>Tcp4Timer.c</Filename>
|
||||
<Filename>Tcp4Output.c</Filename>
|
||||
<Filename>SockImpl.h</Filename>
|
||||
<Filename>Tcp4Main.h</Filename>
|
||||
<Filename>Tcp4Proto.h</Filename>
|
||||
<Filename>SockInterface.c</Filename>
|
||||
<Filename>SockImpl.c</Filename>
|
||||
</SourceFiles>
|
||||
<PackageDependencies>
|
||||
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
|
||||
</PackageDependencies>
|
||||
<Protocols>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiTcp4ProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiIp4ServiceBindingProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiTcp4ServiceBindingProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiIp4ProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
</Protocols>
|
||||
<Externs>
|
||||
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
|
||||
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
|
||||
<Extern>
|
||||
<ModuleEntryPoint>Tcp4DriverEntryPoint</ModuleEntryPoint>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
|
@ -0,0 +1,353 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Func.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _TCP4_FUNC_H_
|
||||
#define _TCP4_FUNC_H_
|
||||
|
||||
//
|
||||
// Declaration of all the functions in TCP
|
||||
// protocol. It is intended to keep tcp.h
|
||||
// clear.
|
||||
//
|
||||
|
||||
//
|
||||
// Functions in tcp.c
|
||||
//
|
||||
BOOLEAN
|
||||
TcpFindTcbByPeer (
|
||||
IN EFI_IPv4_ADDRESS *Addr,
|
||||
IN TCP_PORTNO Port
|
||||
);
|
||||
|
||||
TCP_CB *
|
||||
TcpLocateTcb (
|
||||
IN TCP_PORTNO LocalPort,
|
||||
IN UINT32 LocalIp,
|
||||
IN TCP_PORTNO RemotePort,
|
||||
IN UINT32 RemoteIp,
|
||||
IN BOOLEAN Syn
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpInsertTcb (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
TCP_CB *
|
||||
TcpCloneTcb (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
TCP_SEQNO
|
||||
TcpGetIss (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpInitTcbLocal (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpInitTcbPeer (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP_SEG *Seg,
|
||||
IN TCP_OPTION *Opt
|
||||
);
|
||||
|
||||
UINT16
|
||||
TcpGetRcvMss (
|
||||
IN SOCKET *Sock
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpSetState (
|
||||
IN TCP_CB *Tcb,
|
||||
IN UINT8 State
|
||||
);
|
||||
|
||||
//
|
||||
// Functions in Tcp4Output.c
|
||||
//
|
||||
INTN
|
||||
TcpSendIpPacket (
|
||||
IN TCP_CB *Tcb,
|
||||
IN NET_BUF *Nbuf,
|
||||
IN UINT32 Src,
|
||||
IN UINT32 Dst
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpToSendData (
|
||||
IN TCP_CB *Tcb,
|
||||
IN INTN Force
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpToSendAck (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpSendAck (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpSendZeroProbe (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpDeliverData (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpSendReset (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP_HEAD *Head,
|
||||
IN INT32 Len,
|
||||
IN UINT32 Local,
|
||||
IN UINT32 Remote
|
||||
);
|
||||
|
||||
UINT32
|
||||
TcpRcvWinOld (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
UINT32
|
||||
TcpRcvWinNow (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpRetransmit (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP_SEQNO Seq
|
||||
);
|
||||
|
||||
UINT32
|
||||
TcpDataToSend (
|
||||
IN TCP_CB *Tcb,
|
||||
IN INTN Force
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpVerifySegment (
|
||||
IN NET_BUF *Nbuf
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpCheckSndQue (
|
||||
IN NET_LIST_ENTRY *Head
|
||||
);
|
||||
|
||||
NET_BUF *
|
||||
TcpGetSegmentSndQue (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP_SEQNO Seq,
|
||||
IN UINT32 Len
|
||||
);
|
||||
|
||||
NET_BUF *
|
||||
TcpGetSegmentSock (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP_SEQNO Seq,
|
||||
IN UINT32 Len
|
||||
);
|
||||
|
||||
NET_BUF *
|
||||
TcpGetSegment (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP_SEQNO Seq,
|
||||
IN UINT32 Len
|
||||
);
|
||||
|
||||
TCP_SEQNO
|
||||
TcpGetMaxSndNxt (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
//
|
||||
// Functions from Tcp4Input.c
|
||||
//
|
||||
VOID
|
||||
TcpIcmpInput (
|
||||
IN NET_BUF *Nbuf,
|
||||
IN ICMP_ERROR IcmpErr,
|
||||
IN UINT32 Src,
|
||||
IN UINT32 Dst
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpInput (
|
||||
IN NET_BUF *Nbuf,
|
||||
IN UINT32 Src,
|
||||
IN UINT32 Dst
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpSeqAcceptable (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP_SEG *Seg
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpFastRecover (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP_SEG *Seg
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpFastLossRecover (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP_SEG *Seg
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpComputeRtt (
|
||||
IN TCP_CB *Tcb,
|
||||
IN UINT32 Measure
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpTrimInWnd (
|
||||
IN TCP_CB *Tcb,
|
||||
IN NET_BUF *Buf
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpQueueData (
|
||||
IN TCP_CB *Tcb,
|
||||
IN NET_BUF *Nbuf
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpAdjustSndQue (
|
||||
IN TCP_CB *Tcb,
|
||||
IN TCP_SEQNO Ack
|
||||
);
|
||||
|
||||
//
|
||||
// Functions from Tcp4Misc.c
|
||||
//
|
||||
UINT16
|
||||
TcpChecksum (
|
||||
IN NET_BUF *Buf,
|
||||
IN UINT16 HeadChecksum
|
||||
);
|
||||
|
||||
TCP_SEG *
|
||||
TcpFormatNetbuf (
|
||||
IN TCP_CB *Tcb,
|
||||
IN NET_BUF *Nbuf
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpOnAppConnect (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpOnAppConsume (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpOnAppClose (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpOnAppSend (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpOnAppAbort (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpResetConnection (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
//
|
||||
// Functions in Tcp4Timer.c
|
||||
//
|
||||
VOID
|
||||
TcpClose (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
TcpTicking (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpSetTimer (
|
||||
IN TCP_CB *Tcb,
|
||||
IN UINT16 Timer,
|
||||
IN UINT32 TimeOut
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpClearTimer (
|
||||
IN TCP_CB *Tcb,
|
||||
IN UINT16 Timer
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpClearAllTimer (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpSetProbeTimer (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpSetKeepaliveTimer (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpBackoffRto (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
TcpSetVariableData (
|
||||
IN TCP4_SERVICE_DATA *Tcp4Service
|
||||
);
|
||||
|
||||
VOID
|
||||
TcpClearVariableData (
|
||||
IN TCP4_SERVICE_DATA *Tcp4Service
|
||||
);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,117 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Io.c
|
||||
|
||||
Abstract:
|
||||
|
||||
I/O interfaces between TCP and IpIo.
|
||||
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "Tcp4Main.h"
|
||||
|
||||
|
||||
/**
|
||||
Packet receive callback function provided to IP_IO, used to call
|
||||
the proper function to handle the packet received by IP.
|
||||
|
||||
@param Status Status of the received packet.
|
||||
@param IcmpErr ICMP error number.
|
||||
@param NetSession Pointer to the net session of this packet.
|
||||
@param Pkt Pointer to the recieved packet.
|
||||
@param Context Pointer to the context configured in IpIoOpen(), not used
|
||||
now.
|
||||
|
||||
@return None
|
||||
|
||||
**/
|
||||
VOID
|
||||
Tcp4RxCallback (
|
||||
IN EFI_STATUS Status,
|
||||
IN ICMP_ERROR IcmpErr,
|
||||
IN EFI_NET_SESSION_DATA *NetSession,
|
||||
IN NET_BUF *Pkt,
|
||||
IN VOID *Context OPTIONAL
|
||||
)
|
||||
{
|
||||
if (EFI_SUCCESS == Status) {
|
||||
TcpInput (Pkt, NetSession->Source, NetSession->Dest);
|
||||
} else {
|
||||
TcpIcmpInput (Pkt, IcmpErr, NetSession->Source, NetSession->Dest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Send the segment to IP via IpIo function.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
@param Nbuf Pointer to the TCP segment to be sent.
|
||||
@param Src Source address of the TCP segment.
|
||||
@param Dest Destination address of the TCP segment.
|
||||
|
||||
@retval 0 The segment was sent out successfully.
|
||||
@retval -1 The segment was failed to send.
|
||||
|
||||
**/
|
||||
INTN
|
||||
TcpSendIpPacket (
|
||||
IN TCP_CB *Tcb,
|
||||
IN NET_BUF *Nbuf,
|
||||
IN UINT32 Src,
|
||||
IN UINT32 Dest
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
IP_IO *IpIo;
|
||||
IP_IO_OVERRIDE Override;
|
||||
SOCKET *Sock;
|
||||
VOID *IpSender;
|
||||
TCP4_PROTO_DATA *TcpProto;
|
||||
|
||||
if (NULL == Tcb) {
|
||||
|
||||
IpIo = NULL;
|
||||
IpSender = IpIoFindSender (&IpIo, Src);
|
||||
|
||||
if (IpSender == NULL) {
|
||||
TCP4_DEBUG_WARN (("TcpSendIpPacket: No appropriate IpSender.\n"));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
|
||||
Sock = Tcb->Sk;
|
||||
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
||||
IpIo = TcpProto->TcpService->IpIo;
|
||||
IpSender = Tcb->IpInfo;
|
||||
}
|
||||
|
||||
Override.TypeOfService = 0;
|
||||
Override.TimeToLive = 255;
|
||||
Override.DoNotFragment = FALSE;
|
||||
Override.Protocol = EFI_IP_PROTO_TCP;
|
||||
EFI_IP4 (Override.GatewayAddress) = 0;
|
||||
EFI_IP4 (Override.SourceAddress) = Src;
|
||||
|
||||
Status = IpIoSend (IpIo, Nbuf, IpSender, NULL, NULL, Dest, &Override);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
TCP4_DEBUG_ERROR (("TcpSendIpPacket: return %r error\n", Status));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,564 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Main.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Implementation of TCP4 protocol services.
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "Tcp4Main.h"
|
||||
|
||||
|
||||
/**
|
||||
Check the integrity of the data buffer.
|
||||
|
||||
@param DataLen The total length of the data buffer.
|
||||
@param FragmentCount The fragment count of the fragment table.
|
||||
@param FragmentTable Pointer to the fragment table of the data
|
||||
buffer.
|
||||
|
||||
@retval EFI_SUCCESS The integrity check is passed.
|
||||
@retval EFI_INVALID_PARAMETER The integrity check is failed.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
Tcp4ChkDataBuf (
|
||||
IN UINT32 DataLen,
|
||||
IN UINT32 FragmentCount,
|
||||
IN EFI_TCP4_FRAGMENT_DATA *FragmentTable
|
||||
)
|
||||
{
|
||||
UINT32 Index;
|
||||
|
||||
UINT32 Len;
|
||||
|
||||
for (Index = 0, Len = 0; Index < FragmentCount; Index++) {
|
||||
Len = Len + FragmentTable[Index].FragmentLength;
|
||||
}
|
||||
|
||||
if (DataLen != Len) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Get the current operational status.
|
||||
|
||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
||||
@param Tcp4State Pointer to the buffer to receive the current TCP
|
||||
state.
|
||||
@param Tcp4ConfigData Pointer to the buffer to receive the current TCP
|
||||
configuration.
|
||||
@param Ip4ModeData Pointer to the buffer to receive the current
|
||||
IPv4 configuration.
|
||||
@param MnpConfigData Pointer to the buffer to receive the current MNP
|
||||
configuration data indirectly used by the TCPv4
|
||||
Instance.
|
||||
@param SnpModeData Pointer to the buffer to receive the current SNP
|
||||
configuration data indirectly used by the TCPv4
|
||||
Instance.
|
||||
|
||||
@retval EFI_SUCCESS The mode data was read.
|
||||
@retval EFI_NOT_STARTED No configuration data is available because this
|
||||
instance hasn't been started.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4GetModeData (
|
||||
IN CONST EFI_TCP4_PROTOCOL * This,
|
||||
OUT EFI_TCP4_CONNECTION_STATE * Tcp4State OPTIONAL,
|
||||
OUT EFI_TCP4_CONFIG_DATA * Tcp4ConfigData OPTIONAL,
|
||||
OUT EFI_IP4_MODE_DATA * Ip4ModeData OPTIONAL,
|
||||
OUT EFI_MANAGED_NETWORK_CONFIG_DATA * MnpConfigData OPTIONAL,
|
||||
OUT EFI_SIMPLE_NETWORK_MODE * SnpModeData OPTIONAL
|
||||
)
|
||||
{
|
||||
TCP4_MODE_DATA TcpMode;
|
||||
SOCKET *Sock;
|
||||
|
||||
if (NULL == This) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Sock = SOCK_FROM_THIS (This);
|
||||
|
||||
TcpMode.Tcp4State = Tcp4State;
|
||||
TcpMode.Tcp4ConfigData = Tcp4ConfigData;
|
||||
TcpMode.Ip4ModeData = Ip4ModeData;
|
||||
TcpMode.MnpConfigData = MnpConfigData;
|
||||
TcpMode.SnpModeData = SnpModeData;
|
||||
|
||||
return SockGetMode (Sock, &TcpMode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialize or brutally reset the operational parameters for
|
||||
this EFI TCPv4 instance.
|
||||
|
||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
||||
@param TcpConfigData Pointer to the configure data to configure the
|
||||
instance.
|
||||
|
||||
@retval EFI_SUCCESS The operational settings are set, changed, or
|
||||
reset successfully.
|
||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
||||
(through DHCP, BOOTP, RARP, etc.) is not
|
||||
finished.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_ACCESS_DENIED Configuring TCP instance when it is already
|
||||
configured.
|
||||
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
|
||||
@retval EFI_UNSUPPORTED One or more of the control options are not
|
||||
supported in the implementation.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Configure (
|
||||
IN EFI_TCP4_PROTOCOL * This,
|
||||
IN EFI_TCP4_CONFIG_DATA * TcpConfigData OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_TCP4_OPTION *Option;
|
||||
SOCKET *Sock;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (NULL == This) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Tcp protocol related parameter check will be conducted here
|
||||
//
|
||||
if (NULL != TcpConfigData) {
|
||||
if ((EFI_IP4 (TcpConfigData->AccessPoint.RemoteAddress) != 0) &&
|
||||
!Ip4IsUnicast (EFI_NTOHL (TcpConfigData->AccessPoint.RemoteAddress), 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!TcpConfigData->AccessPoint.UseDefaultAddress) {
|
||||
if (!Ip4IsUnicast (EFI_NTOHL (TcpConfigData->AccessPoint.StationAddress), 0) ||
|
||||
!IP4_IS_VALID_NETMASK (EFI_NTOHL (TcpConfigData->AccessPoint.SubnetMask))
|
||||
) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
if (TcpConfigData->AccessPoint.ActiveFlag &&
|
||||
(0 == TcpConfigData->AccessPoint.RemotePort ||
|
||||
(EFI_IP4 (TcpConfigData->AccessPoint.RemoteAddress) == 0))
|
||||
) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Option = TcpConfigData->ControlOption;
|
||||
if ((NULL != Option) &&
|
||||
(Option->EnableSelectiveAck || Option->EnablePathMtuDiscovery)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
Sock = SOCK_FROM_THIS (This);
|
||||
|
||||
if (NULL == TcpConfigData) {
|
||||
return SockFlush (Sock);
|
||||
}
|
||||
|
||||
Status = SockConfigure (Sock, TcpConfigData);
|
||||
|
||||
if (EFI_NO_MAPPING == Status) {
|
||||
Sock->ConfigureState = SO_NO_MAPPING;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Add or delete routing entries.
|
||||
|
||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
||||
@param DeleteRoute If TRUE, delete the specified route from routing
|
||||
table; if FALSE, add the specified route to
|
||||
routing table.
|
||||
@param SubnetAddress The destination network.
|
||||
@param SubnetMask The subnet mask for the destination network.
|
||||
@param GatewayAddress The gateway address for this route.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance has not been
|
||||
configured.
|
||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
||||
(through DHCP, BOOTP, RARP, etc.) is not
|
||||
finished.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to add the
|
||||
entry to the routing table.
|
||||
@retval EFI_NOT_FOUND This route is not in the routing table.
|
||||
@retval EFI_ACCESS_DENIED This route is already in the routing table.
|
||||
@retval EFI_UNSUPPORTED The TCP driver does not support this operation.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Routes (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN BOOLEAN DeleteRoute,
|
||||
IN EFI_IPv4_ADDRESS *SubnetAddress,
|
||||
IN EFI_IPv4_ADDRESS *SubnetMask,
|
||||
IN EFI_IPv4_ADDRESS *GatewayAddress
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
TCP4_ROUTE_INFO RouteInfo;
|
||||
|
||||
if (NULL == This) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Sock = SOCK_FROM_THIS (This);
|
||||
|
||||
RouteInfo.DeleteRoute = DeleteRoute;
|
||||
RouteInfo.SubnetAddress = SubnetAddress;
|
||||
RouteInfo.SubnetMask = SubnetMask;
|
||||
RouteInfo.GatewayAddress = GatewayAddress;
|
||||
|
||||
return SockRoute (Sock, &RouteInfo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initiate a nonblocking TCP connection request for an active TCP instance.
|
||||
|
||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance
|
||||
@param ConnectionToken Pointer to the connection token to return when
|
||||
the TCP three way handshake finishes.
|
||||
|
||||
@retval EFI_SUCCESS The connection request is successfully
|
||||
initiated.
|
||||
@retval EFI_NOT_STARTED This EFI_TCP4_PROTOCOL instance hasn't been
|
||||
configured.
|
||||
@retval EFI_ACCESS_DENIED The instance is not configured as an active one
|
||||
or it is not in Tcp4StateClosed state.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The driver can't allocate enough resource to
|
||||
initiate the active open.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Connect (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN EFI_TCP4_CONNECTION_TOKEN *ConnectionToken
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
|
||||
if (NULL == This ||
|
||||
NULL == ConnectionToken ||
|
||||
NULL == ConnectionToken->CompletionToken.Event) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Sock = SOCK_FROM_THIS (This);
|
||||
|
||||
return SockConnect (Sock, ConnectionToken);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Listen on the passive instance to accept an incoming connection request.
|
||||
|
||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance
|
||||
@param ListenToken Pointer to the listen token to return when
|
||||
operation finishes.
|
||||
|
||||
@retval EFI_SUCCESS The listen token has been queued successfully.
|
||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
||||
configured.
|
||||
@retval EFI_ACCESS_DENIED The instatnce is not a passive one or it is not
|
||||
in Tcp4StateListen state or a same listen token
|
||||
has already existed in the listen token queue of
|
||||
this TCP instance.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to finish
|
||||
the operation.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Accept (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN EFI_TCP4_LISTEN_TOKEN *ListenToken
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
|
||||
if (NULL == This ||
|
||||
NULL == ListenToken ||
|
||||
NULL == ListenToken->CompletionToken.Event) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Sock = SOCK_FROM_THIS (This);
|
||||
|
||||
return SockAccept (Sock, ListenToken);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Queues outgoing data into the transmit queue
|
||||
|
||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance
|
||||
@param Token Pointer to the completion token to queue to the
|
||||
transmit queue
|
||||
|
||||
@retval EFI_SUCCESS The data has been queued for transmission
|
||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
||||
configured.
|
||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
||||
(DHCP, BOOTP, RARP, etc.) is not finished yet.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid
|
||||
@retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE:
|
||||
* A transmit completion token with the same
|
||||
Token-> CompletionToken.Event was already in the
|
||||
transmission queue. * The current instance is in
|
||||
Tcp4StateClosed state * The current instance is
|
||||
a passive one and it is in Tcp4StateListen
|
||||
state. * User has called Close() to disconnect
|
||||
this connection.
|
||||
@retval EFI_NOT_READY The completion token could not be queued because
|
||||
the transmit queue is full.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not queue the transmit data because of
|
||||
resource shortage.
|
||||
@retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or
|
||||
address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Transmit (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN EFI_TCP4_IO_TOKEN *Token
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (NULL == This ||
|
||||
NULL == Token ||
|
||||
NULL == Token->CompletionToken.Event ||
|
||||
NULL == Token->Packet.TxData ||
|
||||
0 == Token->Packet.TxData->FragmentCount ||
|
||||
0 == Token->Packet.TxData->DataLength
|
||||
) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = Tcp4ChkDataBuf (
|
||||
Token->Packet.TxData->DataLength,
|
||||
Token->Packet.TxData->FragmentCount,
|
||||
Token->Packet.TxData->FragmentTable
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Sock = SOCK_FROM_THIS (This);
|
||||
|
||||
return SockSend (Sock, Token);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Place an asynchronous receive request into the receiving queue.
|
||||
|
||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
||||
@param Token Pointer to a token that is associated with the
|
||||
receive data descriptor.
|
||||
|
||||
@retval EFI_SUCCESS The receive completion token was cached
|
||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
||||
configured.
|
||||
@retval EFI_NO_MAPPING When using a default address, configuration
|
||||
(DHCP, BOOTP, RARP, etc.) is not finished yet.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued
|
||||
due to a lack of system resources.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
@retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE:
|
||||
* A receive completion token with the same
|
||||
Token->CompletionToken.Event was already in the
|
||||
receive queue. * The current instance is in
|
||||
Tcp4StateClosed state. * The current instance is
|
||||
a passive one and it is in Tcp4StateListen
|
||||
state. * User has called Close() to disconnect
|
||||
this connection.
|
||||
@retval EFI_CONNECTION_FIN The communication peer has closed the connection
|
||||
and there is no any buffered data in the receive
|
||||
buffer of this instance.
|
||||
@retval EFI_NOT_READY The receive request could not be queued because
|
||||
the receive queue is full.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Receive (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN EFI_TCP4_IO_TOKEN *Token
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (NULL == This ||
|
||||
NULL == Token ||
|
||||
NULL == Token->CompletionToken.Event ||
|
||||
NULL == Token->Packet.RxData ||
|
||||
0 == Token->Packet.RxData->FragmentCount ||
|
||||
0 == Token->Packet.RxData->DataLength
|
||||
) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = Tcp4ChkDataBuf (
|
||||
Token->Packet.RxData->DataLength,
|
||||
Token->Packet.RxData->FragmentCount,
|
||||
Token->Packet.RxData->FragmentTable
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Sock = SOCK_FROM_THIS (This);
|
||||
|
||||
return SockRcv (Sock, Token);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Disconnecting a TCP connection gracefully or reset a TCP connection.
|
||||
|
||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance
|
||||
@param CloseToken Pointer to the close token to return when
|
||||
operation finishes.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully
|
||||
@retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
|
||||
configured.
|
||||
@retval EFI_ACCESS_DENIED One or more of the following are TRUE: *
|
||||
Configure() has been called with TcpConfigData
|
||||
set to NULL and this function has not returned.
|
||||
* Previous Close() call on this instance has not
|
||||
finished.
|
||||
@retval EFI_INVALID_PARAMETER One ore more parameters are invalid
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the
|
||||
operation
|
||||
@retval EFI_DEVICE_ERROR Any unexpected and not belonged to above
|
||||
category error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Close (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN EFI_TCP4_CLOSE_TOKEN *CloseToken
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
|
||||
if (NULL == This ||
|
||||
NULL == CloseToken ||
|
||||
NULL == CloseToken->CompletionToken.Event) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Sock = SOCK_FROM_THIS (This);
|
||||
|
||||
return SockClose (Sock, CloseToken, CloseToken->AbortOnClose);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Abort an asynchronous connection, listen, transmission or receive request.
|
||||
|
||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
||||
@param Token Pointer to a token that has been issued by
|
||||
Connect(), Accept(), Transmit() or Receive(). If
|
||||
NULL, all pending tokens issued by above four
|
||||
functions will be aborted.
|
||||
|
||||
@retval EFI_UNSUPPORTED The operation is not supported in current
|
||||
implementation.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Cancel (
|
||||
IN EFI_TCP4_PROTOCOL * This,
|
||||
IN EFI_TCP4_COMPLETION_TOKEN * Token OPTIONAL
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Poll to receive incoming data and transmit outgoing segments.
|
||||
|
||||
@param This Pointer to the EFI_TCP4_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS Incoming or outgoing data was processed.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
@retval EFI_NOT_READY No incoming or outgoing data was processed.
|
||||
@retval EFI_TIMEOUT Data was dropped out of the transmission or
|
||||
receive queue. Consider increasing the polling
|
||||
rate.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Poll (
|
||||
IN EFI_TCP4_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
SOCKET *Sock;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (NULL == This) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Sock = SOCK_FROM_THIS (This);
|
||||
|
||||
Status = Sock->ProtoHandler (Sock, SOCK_POLL, NULL);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Main.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _TCP4_MAIN_H_
|
||||
#define _TCP4_MAIN_H_
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
#include "Tcp4Proto.h"
|
||||
#include "Tcp4Driver.h"
|
||||
|
||||
|
||||
extern UINT16 mTcp4RandomPort;
|
||||
|
||||
//
|
||||
// Driver Produced Protocol Prototypes
|
||||
//
|
||||
//@MT:#include EFI_PROTOCOL_PRODUCER (Tcp4)
|
||||
|
||||
#define TCP4_DEBUG_ERROR(PrintArg) NET_DEBUG_ERROR ("Tcp", PrintArg)
|
||||
#define TCP4_DEBUG_WARN(PrintArg) NET_DEBUG_WARNING ("Tcp", PrintArg)
|
||||
#define TCP4_DEBUG_TRACE(PrintArg) NET_DEBUG_TRACE ("Tcp", PrintArg)
|
||||
|
||||
//
|
||||
// Function prototype for the Tcp4 socket request handler
|
||||
//
|
||||
EFI_STATUS
|
||||
Tcp4Dispatcher (
|
||||
IN SOCKET *Sock,
|
||||
IN SOCK_REQUEST Request,
|
||||
IN VOID *Data OPTIONAL
|
||||
);
|
||||
|
||||
typedef struct _TCP4_MODE_DATA {
|
||||
EFI_TCP4_CONNECTION_STATE *Tcp4State;
|
||||
EFI_TCP4_CONFIG_DATA *Tcp4ConfigData;
|
||||
EFI_IP4_MODE_DATA *Ip4ModeData;
|
||||
EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData;
|
||||
EFI_SIMPLE_NETWORK_MODE *SnpModeData;
|
||||
} TCP4_MODE_DATA;
|
||||
|
||||
typedef struct _TCP4_ROUTE_INFO {
|
||||
BOOLEAN DeleteRoute;
|
||||
EFI_IPv4_ADDRESS *SubnetAddress;
|
||||
EFI_IPv4_ADDRESS *SubnetMask;
|
||||
EFI_IPv4_ADDRESS *GatewayAddress;
|
||||
} TCP4_ROUTE_INFO;
|
||||
|
||||
//
|
||||
// Get the mode data of a TCP instance
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4GetModeData (
|
||||
IN CONST EFI_TCP4_PROTOCOL * This,
|
||||
OUT EFI_TCP4_CONNECTION_STATE * Tcp4State OPTIONAL,
|
||||
OUT EFI_TCP4_CONFIG_DATA * Tcp4ConfigData OPTIONAL,
|
||||
OUT EFI_IP4_MODE_DATA * Ip4ModeData OPTIONAL,
|
||||
OUT EFI_MANAGED_NETWORK_CONFIG_DATA * MnpConfigData OPTIONAL,
|
||||
OUT EFI_SIMPLE_NETWORK_MODE * SnpModeData OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// Initialize or reset a TCP instance
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Configure (
|
||||
IN EFI_TCP4_PROTOCOL * This,
|
||||
IN EFI_TCP4_CONFIG_DATA * TcpConfigData OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// Add a route entry to the route table
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Routes (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN BOOLEAN DeleteRoute,
|
||||
IN EFI_IPv4_ADDRESS *SubnetAddress,
|
||||
IN EFI_IPv4_ADDRESS *SubnetMask,
|
||||
IN EFI_IPv4_ADDRESS *GatewayAddress
|
||||
);
|
||||
|
||||
//
|
||||
// Issue an asynchronous connection establishment
|
||||
// request to the peer
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Connect (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN EFI_TCP4_CONNECTION_TOKEN *ConnectionToken
|
||||
);
|
||||
|
||||
//
|
||||
// Issue an asynchronous listent token to accept an
|
||||
// incoming connection reques
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Accept (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN EFI_TCP4_LISTEN_TOKEN *ListenToken
|
||||
);
|
||||
|
||||
//
|
||||
// Issue an asynchronous IO token to transmit some data
|
||||
// through this TCP instance
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Transmit (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN EFI_TCP4_IO_TOKEN *Token
|
||||
);
|
||||
|
||||
//
|
||||
// Issue an asynchronous IO token to receive some data
|
||||
// through this TCP instance
|
||||
//
|
||||
EFI_STATUS
|
||||
Tcp4Receive (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN EFI_TCP4_IO_TOKEN *Token
|
||||
);
|
||||
|
||||
//
|
||||
// Issue an asynchronous CloseToken to close a TCP
|
||||
// connection represented by instance
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Close (
|
||||
IN EFI_TCP4_PROTOCOL *This,
|
||||
IN EFI_TCP4_CLOSE_TOKEN *CloseToken
|
||||
);
|
||||
|
||||
//
|
||||
// cancle an connect, listent or IO token
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Cancel (
|
||||
IN EFI_TCP4_PROTOCOL * This,
|
||||
IN EFI_TCP4_COMPLETION_TOKEN * Token OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// poll data from NIC for receive
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Tcp4Poll (
|
||||
IN EFI_TCP4_PROTOCOL *This
|
||||
);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,380 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Option.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Routines to process TCP option.
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "Tcp4Main.h"
|
||||
|
||||
STATIC
|
||||
UINT16
|
||||
TcpGetUint16 (
|
||||
IN UINT8 *Buf
|
||||
)
|
||||
{
|
||||
UINT16 Value;
|
||||
NetCopyMem (&Value, Buf, sizeof (UINT16));
|
||||
return NTOHS (Value);
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
TcpPutUint16 (
|
||||
IN UINT8 *Buf,
|
||||
IN UINT16 Data
|
||||
)
|
||||
{
|
||||
Data = HTONS (Data);
|
||||
NetCopyMem (Buf, &Data, sizeof (UINT16));
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT32
|
||||
TcpGetUint32 (
|
||||
IN UINT8 *Buf
|
||||
)
|
||||
{
|
||||
UINT32 Value;
|
||||
NetCopyMem (&Value, Buf, sizeof (UINT32));
|
||||
return NTOHL (Value);
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
TcpPutUint32 (
|
||||
IN UINT8 *Buf,
|
||||
IN UINT32 Data
|
||||
)
|
||||
{
|
||||
Data = HTONL (Data);
|
||||
NetCopyMem (Buf, &Data, sizeof (UINT32));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Compute the window scale value according to the given
|
||||
buffer size.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@retval UINT8 The scale value.
|
||||
|
||||
**/
|
||||
UINT8
|
||||
TcpComputeScale (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
UINT8 Scale;
|
||||
UINT32 BufSize;
|
||||
|
||||
ASSERT (Tcb && Tcb->Sk);
|
||||
|
||||
BufSize = GET_RCV_BUFFSIZE (Tcb->Sk);
|
||||
|
||||
Scale = 0;
|
||||
while ((Scale < TCP_OPTION_MAX_WS) &&
|
||||
((UINT32) (TCP_OPTION_MAX_WIN << Scale) < BufSize)) {
|
||||
|
||||
Scale++;
|
||||
}
|
||||
|
||||
return Scale;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Build the TCP option in three-way handshake.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
@param Nbuf Pointer to the buffer to store the options.
|
||||
|
||||
@return The total length of the TCP option field.
|
||||
|
||||
**/
|
||||
UINT16
|
||||
TcpSynBuildOption (
|
||||
IN TCP_CB *Tcb,
|
||||
IN NET_BUF *Nbuf
|
||||
)
|
||||
{
|
||||
char *Data;
|
||||
UINT16 Len;
|
||||
|
||||
ASSERT (Tcb && Nbuf && !Nbuf->Tcp);
|
||||
|
||||
Len = 0;
|
||||
|
||||
//
|
||||
// Add timestamp option if not disabled by application
|
||||
// and it is the first SYN segment or the peer has sent
|
||||
// us its timestamp.
|
||||
//
|
||||
if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS) &&
|
||||
(!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_ACK) ||
|
||||
TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_TS))) {
|
||||
|
||||
Data = NetbufAllocSpace (
|
||||
Nbuf,
|
||||
TCP_OPTION_TS_ALIGNED_LEN,
|
||||
NET_BUF_HEAD
|
||||
);
|
||||
|
||||
ASSERT (Data);
|
||||
Len += TCP_OPTION_TS_ALIGNED_LEN;
|
||||
|
||||
TcpPutUint32 (Data, TCP_OPTION_TS_FAST);
|
||||
TcpPutUint32 (Data + 4, mTcpTick);
|
||||
TcpPutUint32 (Data + 8, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Build window scale option, only when are configured
|
||||
// to send WS option, and either we are doing active
|
||||
// open or we have received WS option from peer.
|
||||
//
|
||||
if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS) &&
|
||||
(!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_ACK) ||
|
||||
TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_WS))) {
|
||||
|
||||
Data = NetbufAllocSpace (
|
||||
Nbuf,
|
||||
TCP_OPTION_WS_ALIGNED_LEN,
|
||||
NET_BUF_HEAD
|
||||
);
|
||||
|
||||
ASSERT (Data);
|
||||
|
||||
Len += TCP_OPTION_WS_ALIGNED_LEN;
|
||||
TcpPutUint32 (Data, TCP_OPTION_WS_FAST | TcpComputeScale (Tcb));
|
||||
}
|
||||
|
||||
//
|
||||
// Build MSS option
|
||||
//
|
||||
Data = NetbufAllocSpace (Nbuf, TCP_OPTION_MSS_LEN, 1);
|
||||
ASSERT (Data);
|
||||
|
||||
Len += TCP_OPTION_MSS_LEN;
|
||||
TcpPutUint32 (Data, TCP_OPTION_MSS_FAST | Tcb->RcvMss);
|
||||
|
||||
return Len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Build the TCP option in synchronized states.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
@param Nbuf Pointer to the buffer to store the options.
|
||||
|
||||
@return The total length of the TCP option field.
|
||||
|
||||
**/
|
||||
UINT16
|
||||
TcpBuildOption (
|
||||
IN TCP_CB *Tcb,
|
||||
IN NET_BUF *Nbuf
|
||||
)
|
||||
{
|
||||
char *Data;
|
||||
UINT16 Len;
|
||||
|
||||
ASSERT (Tcb && Nbuf && !Nbuf->Tcp);
|
||||
Len = 0;
|
||||
|
||||
//
|
||||
// Build Timestamp option
|
||||
//
|
||||
if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_SND_TS) &&
|
||||
!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_RST)) {
|
||||
|
||||
Data = NetbufAllocSpace (
|
||||
Nbuf,
|
||||
TCP_OPTION_TS_ALIGNED_LEN,
|
||||
NET_BUF_HEAD
|
||||
);
|
||||
|
||||
ASSERT (Data);
|
||||
Len += TCP_OPTION_TS_ALIGNED_LEN;
|
||||
|
||||
TcpPutUint32 (Data, TCP_OPTION_TS_FAST);
|
||||
TcpPutUint32 (Data + 4, mTcpTick);
|
||||
TcpPutUint32 (Data + 8, Tcb->TsRecent);
|
||||
}
|
||||
|
||||
return Len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Parse the supported options.
|
||||
|
||||
@param Tcp Pointer to the TCP_CB of this TCP instance.
|
||||
@param Option Pointer to the TCP_OPTION used to store the successfully pasrsed
|
||||
options.
|
||||
|
||||
@retval 0 The options are successfully pasrsed.
|
||||
@retval -1 Ilegal option was found.
|
||||
|
||||
**/
|
||||
INTN
|
||||
TcpParseOption (
|
||||
IN TCP_HEAD *Tcp,
|
||||
IN TCP_OPTION *Option
|
||||
)
|
||||
{
|
||||
UINT8 *Head;
|
||||
UINT8 TotalLen;
|
||||
UINT8 Cur;
|
||||
UINT8 Type;
|
||||
UINT8 Len;
|
||||
|
||||
ASSERT (Tcp && Option);
|
||||
|
||||
Option->Flag = 0;
|
||||
|
||||
TotalLen = (Tcp->HeadLen << 2) - sizeof (TCP_HEAD);
|
||||
if (TotalLen <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Head = (UINT8 *) (Tcp + 1);
|
||||
|
||||
//
|
||||
// Fast process of timestamp option
|
||||
//
|
||||
if ((TotalLen == TCP_OPTION_TS_ALIGNED_LEN) &&
|
||||
(TcpGetUint32 (Head) == TCP_OPTION_TS_FAST)) {
|
||||
|
||||
Option->TSVal = TcpGetUint32 (Head + 4);
|
||||
Option->TSEcr = TcpGetUint32 (Head + 8);
|
||||
Option->Flag = TCP_OPTION_RCVD_TS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Slow path to process the options.
|
||||
//
|
||||
Cur = 0;
|
||||
|
||||
while (Cur < TotalLen) {
|
||||
Type = Head[Cur];
|
||||
|
||||
switch (Type) {
|
||||
case TCP_OPTION_MSS:
|
||||
Len = Head[Cur + 1];
|
||||
|
||||
if ((Len != TCP_OPTION_MSS_LEN) ||
|
||||
(TotalLen - Cur < TCP_OPTION_MSS_LEN)) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Option->Mss = TcpGetUint16 (&Head[Cur + 2]);
|
||||
TCP_SET_FLG (Option->Flag, TCP_OPTION_RCVD_MSS);
|
||||
|
||||
Cur += TCP_OPTION_MSS_LEN;
|
||||
break;
|
||||
|
||||
case TCP_OPTION_WS:
|
||||
Len = Head[Cur + 1];
|
||||
|
||||
if ((Len != TCP_OPTION_WS_LEN) ||
|
||||
(TotalLen - Cur < TCP_OPTION_WS_LEN)) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Option->WndScale = NET_MIN (14, Head[Cur + 2]);
|
||||
TCP_SET_FLG (Option->Flag, TCP_OPTION_RCVD_WS);
|
||||
|
||||
Cur += TCP_OPTION_WS_LEN;
|
||||
break;
|
||||
|
||||
case TCP_OPTION_TS:
|
||||
Len = Head[Cur + 1];
|
||||
|
||||
if ((Len != TCP_OPTION_TS_LEN) ||
|
||||
(TotalLen - Cur < TCP_OPTION_TS_LEN)) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Option->TSVal = TcpGetUint32 (&Head[Cur + 2]);
|
||||
Option->TSEcr = TcpGetUint32 (&Head[Cur + 6]);
|
||||
TCP_SET_FLG (Option->Flag, TCP_OPTION_RCVD_TS);
|
||||
|
||||
Cur += TCP_OPTION_TS_LEN;
|
||||
break;
|
||||
|
||||
case TCP_OPTION_NOP:
|
||||
Cur++;
|
||||
break;
|
||||
|
||||
case TCP_OPTION_EOP:
|
||||
Cur = TotalLen;
|
||||
break;
|
||||
|
||||
default:
|
||||
Len = Head[Cur + 1];
|
||||
|
||||
if (TotalLen - Cur < Len || Len < 2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Cur = Cur + Len;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Check the segment against PAWS.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
@param TSVal The timestamp value.
|
||||
|
||||
@retval 1 The segment passed the PAWS check.
|
||||
@retval 0 The segment failed to pass the PAWS check.
|
||||
|
||||
**/
|
||||
UINT32
|
||||
TcpPawsOK (
|
||||
IN TCP_CB *Tcb,
|
||||
IN UINT32 TSVal
|
||||
)
|
||||
{
|
||||
//
|
||||
// PAWS as defined in RFC1323, buggy...
|
||||
//
|
||||
if (TCP_TIME_LT (TSVal, Tcb->TsRecent) &&
|
||||
TCP_TIME_LT (Tcb->TsRecentAge + TCP_PAWS_24DAY, mTcpTick)) {
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Option.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _TCP4_OPTION_H_
|
||||
#define _TCP4_OPTION_H_
|
||||
|
||||
//
|
||||
// The structure to store the parse option value.
|
||||
// ParseOption only parse the options, don't process them.
|
||||
//
|
||||
typedef struct s_TCP_OPTION {
|
||||
UINT8 Flag; // flag such as TCP_OPTION_RCVD_MSS
|
||||
UINT8 WndScale; // the WndScale received
|
||||
UINT16 Mss; // the Mss received
|
||||
UINT32 TSVal; // the TSVal field in a timestamp option
|
||||
UINT32 TSEcr; // the TSEcr field in a timestamp option
|
||||
} TCP_OPTION;
|
||||
|
||||
enum {
|
||||
|
||||
//
|
||||
// supported TCP option type and their length
|
||||
//
|
||||
TCP_OPTION_EOP = 0, // End Of oPtion
|
||||
TCP_OPTION_NOP = 1, // No-Option.
|
||||
TCP_OPTION_MSS = 2, // Maximum Segment Size
|
||||
TCP_OPTION_WS = 3, // Window scale
|
||||
TCP_OPTION_TS = 8, // Timestamp
|
||||
TCP_OPTION_MSS_LEN = 4, // length of MSS option
|
||||
TCP_OPTION_WS_LEN = 3, // length of window scale option
|
||||
TCP_OPTION_TS_LEN = 10, // length of timestamp option
|
||||
TCP_OPTION_WS_ALIGNED_LEN = 4, // length of window scale option, aligned
|
||||
TCP_OPTION_TS_ALIGNED_LEN = 12, // length of timestamp option, aligned
|
||||
|
||||
//
|
||||
// recommend format of timestamp window scale
|
||||
// option for fast process.
|
||||
//
|
||||
TCP_OPTION_TS_FAST = ((TCP_OPTION_NOP << 24) |
|
||||
(TCP_OPTION_NOP << 16) |
|
||||
(TCP_OPTION_TS << 8) |
|
||||
TCP_OPTION_TS_LEN),
|
||||
|
||||
TCP_OPTION_WS_FAST = ((TCP_OPTION_NOP << 24) |
|
||||
(TCP_OPTION_WS << 16) |
|
||||
(TCP_OPTION_WS_LEN << 8)),
|
||||
|
||||
TCP_OPTION_MSS_FAST = ((TCP_OPTION_MSS << 24) |
|
||||
(TCP_OPTION_MSS_LEN << 16)),
|
||||
|
||||
//
|
||||
// Other misc definations
|
||||
//
|
||||
TCP_OPTION_MAX_WS = 14, // Maxium window scale value
|
||||
TCP_OPTION_MAX_WIN = 0xffff, // max window size in TCP header
|
||||
TCP_OPTION_RCVD_MSS = 0x01,
|
||||
TCP_OPTION_RCVD_WS = 0x02,
|
||||
TCP_OPTION_RCVD_TS = 0x04,
|
||||
};
|
||||
|
||||
UINT8
|
||||
TcpComputeScale (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
UINT16
|
||||
TcpSynBuildOption (
|
||||
IN TCP_CB *Tcb,
|
||||
IN NET_BUF *Buf
|
||||
);
|
||||
|
||||
UINT16
|
||||
TcpBuildOption (
|
||||
IN TCP_CB *Tcb,
|
||||
IN NET_BUF *Buf
|
||||
);
|
||||
|
||||
INTN
|
||||
TcpParseOption (
|
||||
IN TCP_HEAD *Tcp,
|
||||
IN TCP_OPTION *Option
|
||||
);
|
||||
|
||||
UINT32
|
||||
TcpPawsOK (
|
||||
IN TCP_CB *Tcb,
|
||||
IN UINT32 TSVal
|
||||
);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,355 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Proto.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _TCP4_PROTO_H_
|
||||
#define _TCP4_PROTO_H_
|
||||
|
||||
typedef struct _TCP_CB TCP_CB;
|
||||
|
||||
#include "Tcp4Driver.h"
|
||||
#include "Socket.h"
|
||||
#include "Tcp4Option.h"
|
||||
|
||||
//
|
||||
// tcp states, Don't change their order, it is used as
|
||||
// index to mTcpOutFlag and other macros
|
||||
//
|
||||
enum {
|
||||
TCP_CLOSED = 0,
|
||||
TCP_LISTEN,
|
||||
TCP_SYN_SENT,
|
||||
TCP_SYN_RCVD,
|
||||
TCP_ESTABLISHED,
|
||||
TCP_FIN_WAIT_1,
|
||||
TCP_FIN_WAIT_2,
|
||||
TCP_CLOSING,
|
||||
TCP_TIME_WAIT,
|
||||
TCP_CLOSE_WAIT,
|
||||
TCP_LAST_ACK,
|
||||
};
|
||||
|
||||
//
|
||||
// flags in the TCP header
|
||||
//
|
||||
enum {
|
||||
|
||||
TCP_FLG_FIN = 0x01,
|
||||
TCP_FLG_SYN = 0x02,
|
||||
TCP_FLG_RST = 0x04,
|
||||
TCP_FLG_PSH = 0x08,
|
||||
TCP_FLG_ACK = 0x10,
|
||||
TCP_FLG_URG = 0x20,
|
||||
TCP_FLG_FLAG = 0x3F, // mask for all the flags
|
||||
};
|
||||
|
||||
enum {
|
||||
|
||||
//
|
||||
// TCP error status
|
||||
//
|
||||
TCP_CONNECT_REFUSED = -1,
|
||||
TCP_CONNECT_RESET = -2,
|
||||
TCP_CONNECT_CLOSED = -3,
|
||||
|
||||
//
|
||||
// Current congestion status as suggested by RFC3782.
|
||||
//
|
||||
TCP_CONGEST_RECOVER = 1, // during the NewReno fast recovery
|
||||
TCP_CONGEST_LOSS = 2, // retxmit because of retxmit time out
|
||||
TCP_CONGEST_OPEN = 3, // TCP is opening its congestion window
|
||||
|
||||
//
|
||||
// TCP control flags
|
||||
//
|
||||
TCP_CTRL_NO_NAGLE = 0x0001, // disable Nagle algorithm
|
||||
TCP_CTRL_NO_KEEPALIVE = 0x0002, // disable keepalive timer
|
||||
TCP_CTRL_NO_WS = 0x0004, // disable window scale option
|
||||
TCP_CTRL_RCVD_WS = 0x0008, // rcvd a wnd scale option in syn
|
||||
TCP_CTRL_NO_TS = 0x0010, // disable Timestamp option
|
||||
TCP_CTRL_RCVD_TS = 0x0020, // rcvd a Timestamp option in syn
|
||||
TCP_CTRL_SND_TS = 0x0040, // Send Timestamp option to remote
|
||||
TCP_CTRL_SND_URG = 0x0080, // in urgent send mode
|
||||
TCP_CTRL_RCVD_URG = 0x0100, // in urgent receive mode
|
||||
TCP_CTRL_SND_PSH = 0x0200, // in PUSH send mode
|
||||
TCP_CTRL_FIN_SENT = 0x0400, // FIN is sent
|
||||
TCP_CTRL_FIN_ACKED = 0x0800, // FIN is ACKed.
|
||||
TCP_CTRL_TIMER_ON = 0x1000, // At least one of the timer is on
|
||||
TCP_CTRL_RTT_ON = 0x2000, // The RTT measurement is on
|
||||
TCP_CTRL_ACK_NOW = 0x4000, // Send the ACK now, don't delay
|
||||
|
||||
//
|
||||
// Timer related values
|
||||
//
|
||||
TCP_TIMER_CONNECT = 0, // Connection establishment timer
|
||||
TCP_TIMER_REXMIT = 1, // retransmit timer
|
||||
TCP_TIMER_PROBE = 2, // Window probe timer
|
||||
TCP_TIMER_KEEPALIVE = 3, // Keepalive timer
|
||||
TCP_TIMER_FINWAIT2 = 4, // FIN_WAIT_2 timer
|
||||
TCP_TIMER_2MSL = 5, // TIME_WAIT tiemr
|
||||
TCP_TIMER_NUMBER = 6, // the total number of TCP timer.
|
||||
TCP_TICK = 200, // every TCP tick is 200ms
|
||||
TCP_TICK_HZ = 5, // the frequence of TCP tick
|
||||
TCP_RTT_SHIFT = 3, // SRTT & RTTVAR scaled by 8
|
||||
TCP_RTO_MIN = TCP_TICK_HZ, // the minium value of RTO
|
||||
TCP_RTO_MAX = TCP_TICK_HZ *60, // the maxium value of RTO
|
||||
TCP_FOLD_RTT = 4, // timeout threshod to fold RTT
|
||||
|
||||
//
|
||||
// default values for some timers
|
||||
//
|
||||
TCP_MAX_LOSS = 12, // default max times to retxmit
|
||||
TCP_KEEPALIVE_IDLE_MIN = TCP_TICK_HZ *60 *60 *2, // First keep alive
|
||||
TCP_KEEPALIVE_PERIOD = TCP_TICK_HZ *60,
|
||||
TCP_MAX_KEEPALIVE = 8,
|
||||
TCP_FIN_WAIT2_TIME = 2 *TCP_TICK_HZ, // * 60,
|
||||
TCP_TIME_WAIT_TIME = 2 *TCP_TICK_HZ,
|
||||
TCP_PAWS_24DAY = 24 *24 *60 *60 *TCP_TICK_HZ,
|
||||
TCP_CONNECT_TIME = 75 *TCP_TICK_HZ,
|
||||
|
||||
//
|
||||
// The header space to be reserved before TCP data to accomodate :
|
||||
// 60byte IP head + 60byte TCP head + link layer head
|
||||
//
|
||||
TCP_MAX_HEAD = 192,
|
||||
|
||||
//
|
||||
// value ranges for some control option
|
||||
//
|
||||
TCP_RCV_BUF_SIZE = 2 *1024 *1024,
|
||||
TCP_RCV_BUF_SIZE_MIN = 8 *1024,
|
||||
TCP_SND_BUF_SIZE = 2 *1024 *1024,
|
||||
TCP_SND_BUF_SIZE_MIN = 8 *1024,
|
||||
TCP_BACKLOG = 10,
|
||||
TCP_BACKLOG_MIN = 5,
|
||||
TCP_MAX_LOSS_MIN = 6,
|
||||
TCP_CONNECT_TIME_MIN = 60 *TCP_TICK_HZ,
|
||||
TCP_MAX_KEEPALIVE_MIN = 4,
|
||||
TCP_KEEPALIVE_IDLE_MAX = TCP_TICK_HZ *60 *60 *4,
|
||||
TCP_KEEPALIVE_PERIOD_MIN= TCP_TICK_HZ *30,
|
||||
TCP_FIN_WAIT2_TIME_MAX = 4 *TCP_TICK_HZ,
|
||||
TCP_TIME_WAIT_TIME_MAX = 60 *TCP_TICK_HZ,
|
||||
};
|
||||
|
||||
typedef struct _TCP_SEG {
|
||||
TCP_SEQNO Seq; // Starting sequence number
|
||||
TCP_SEQNO End; // The sequence of the last byte + 1,
|
||||
// include SYN/FIN. End-Seq = SEG.LEN
|
||||
TCP_SEQNO Ack; // ACK fild in the segment
|
||||
UINT8 Flag; // TCP header flags
|
||||
UINT16 Urg; // Valid if URG flag is set.
|
||||
UINT32 Wnd; // TCP window size field
|
||||
} TCP_SEG;
|
||||
|
||||
typedef struct _TCP_PEER {
|
||||
UINT32 Ip; // Network byte order
|
||||
TCP_PORTNO Port; // Network byte order
|
||||
} TCP_PEER;
|
||||
|
||||
//
|
||||
// tcp control block, it includes various states
|
||||
//
|
||||
typedef struct _TCP_CB {
|
||||
NET_LIST_ENTRY List;
|
||||
TCP_CB *Parent;
|
||||
|
||||
SOCKET *Sk;
|
||||
TCP_PEER LocalEnd;
|
||||
TCP_PEER RemoteEnd;
|
||||
|
||||
NET_LIST_ENTRY SndQue; // retxmission queue
|
||||
NET_LIST_ENTRY RcvQue; // reassemble queue
|
||||
UINT32 CtrlFlag; // control flags, such as NO_NAGLE
|
||||
INT32 Error; // soft error status,TCP_CONNECT_RESET...
|
||||
|
||||
//
|
||||
// RFC793 and RFC1122 defined variables
|
||||
//
|
||||
UINT8 State; // TCP state, such as SYN_SENT, LISTEN
|
||||
UINT8 DelayedAck; // number of delayed ACKs
|
||||
UINT16 HeadSum; // checksum of the fixed parts of pesudo
|
||||
// header: Src IP, Dst IP, 0, Protocol,
|
||||
// not include the TCP length.
|
||||
|
||||
TCP_SEQNO Iss; // Initial Sending Sequence
|
||||
TCP_SEQNO SndUna; // first unacknowledged data
|
||||
TCP_SEQNO SndNxt; // next data sequence to send.
|
||||
TCP_SEQNO SndPsh; // Send PUSH point
|
||||
TCP_SEQNO SndUp; // Send urgent point
|
||||
UINT32 SndWnd; // Window advertised by the remote peer
|
||||
UINT32 SndWndMax; // max send window advertised by the peer
|
||||
TCP_SEQNO SndWl1; // Seq number used for last window update
|
||||
TCP_SEQNO SndWl2; // ack no of last window update
|
||||
UINT16 SndMss; // Max send segment size
|
||||
TCP_SEQNO RcvNxt; // Next sequence no to receive
|
||||
UINT32 RcvWnd; // Window advertised by the local peer
|
||||
TCP_SEQNO RcvWl2; // The RcvNxt (or ACK) of last window update.
|
||||
// It is necessary because of delayed ACK
|
||||
|
||||
TCP_SEQNO RcvUp; // urgent point;
|
||||
TCP_SEQNO Irs; // Initial Receiving Sequence
|
||||
UINT16 RcvMss; // Max receive segment size
|
||||
UINT16 EnabledTimer; // which timer is currently enabled
|
||||
UINT32 Timer[TCP_TIMER_NUMBER]; // when the timer will expire
|
||||
INT32 NextExpire; // count down offset for the nearest timer
|
||||
UINT32 Idle; // How long the connection is in idle
|
||||
UINT32 ProbeTime; // the time out value for current window prober
|
||||
|
||||
//
|
||||
// RFC1323 defined variables, about window scale,
|
||||
// timestamp and PAWS
|
||||
//
|
||||
UINT8 SndWndScale; // Wndscale received from the peer
|
||||
UINT8 RcvWndScale; // Wndscale used to scale local buffer
|
||||
UINT32 TsRecent; // TsRecent to echo to the remote peer
|
||||
UINT32 TsRecentAge; // When this TsRecent is updated
|
||||
|
||||
// TCP_SEQNO LastAckSent;
|
||||
// It isn't necessary to add LastAckSent here,
|
||||
// since it is the same as RcvWl2
|
||||
|
||||
//
|
||||
// RFC2988 defined variables. about RTT measurement
|
||||
//
|
||||
TCP_SEQNO RttSeq; // the seq of measured segment now
|
||||
UINT32 RttMeasure; // currently measured RTT in heart beats
|
||||
UINT32 SRtt; // Smoothed RTT, scaled by 8
|
||||
UINT32 RttVar; // RTT variance, scaled by 8
|
||||
UINT32 Rto; // Current RTO, not scaled
|
||||
|
||||
//
|
||||
// RFC2581, and 3782 variables.
|
||||
// Congestion control + NewReno fast recovery.
|
||||
//
|
||||
UINT32 CWnd; // Sender's congestion window
|
||||
UINT32 Ssthresh; // Slow start threshold.
|
||||
TCP_SEQNO Recover; // recover point for NewReno
|
||||
UINT16 DupAck; // number of duplicate ACKs
|
||||
UINT8 CongestState; // the current congestion state(RFC3782)
|
||||
UINT8 LossTimes; // number of retxmit timeouts in a row
|
||||
TCP_SEQNO LossRecover; // recover point for retxmit
|
||||
|
||||
//
|
||||
// configuration parameters, for EFI_TCP4_PROTOCOL specification
|
||||
//
|
||||
UINT32 KeepAliveIdle; // idle time before sending first probe
|
||||
UINT32 KeepAlivePeriod; // interval for subsequent keep alive probe
|
||||
UINT8 MaxKeepAlive; // Maxium keep alive probe times.
|
||||
UINT8 KeepAliveProbes; // the number of keep alive probe.
|
||||
UINT16 MaxRexmit; // The maxium number of retxmit before abort
|
||||
UINT32 FinWait2Timeout; // The FIN_WAIT_2 time out
|
||||
UINT32 TimeWaitTimeout; // The TIME_WAIT time out
|
||||
UINT32 ConnectTimeout;
|
||||
|
||||
//
|
||||
// configuration for tcp provided by user
|
||||
//
|
||||
BOOLEAN UseDefaultAddr;
|
||||
UINT8 TOS;
|
||||
UINT8 TTL;
|
||||
EFI_IPv4_ADDRESS SubnetMask;
|
||||
|
||||
//
|
||||
// pointer reference to Ip used to send pkt
|
||||
//
|
||||
IP_IO_IP_INFO *IpInfo;
|
||||
} TCP_CB;
|
||||
|
||||
extern NET_LIST_ENTRY mTcpRunQue;
|
||||
extern NET_LIST_ENTRY mTcpListenQue;
|
||||
extern TCP_SEQNO mTcpGlobalIss;
|
||||
extern UINT32 mTcpTick;
|
||||
|
||||
//
|
||||
// TCP_CONNECTED: both ends have synchronized their ISN.
|
||||
//
|
||||
#define TCP_CONNECTED(state) ((state) > TCP_SYN_RCVD)
|
||||
|
||||
#define TCP_FIN_RCVD(State) \
|
||||
(((State) == TCP_CLOSE_WAIT) || \
|
||||
((State) == TCP_LAST_ACK) || \
|
||||
((State) == TCP_CLOSING) || \
|
||||
((State) == TCP_TIME_WAIT))
|
||||
|
||||
#define TCP_LOCAL_CLOSED(State) \
|
||||
(((State) == TCP_FIN_WAIT_1) || \
|
||||
((State) == TCP_FIN_WAIT_2) || \
|
||||
((State) == TCP_CLOSING) || \
|
||||
((State) == TCP_TIME_WAIT) || \
|
||||
((State) == TCP_LAST_ACK))
|
||||
|
||||
//
|
||||
// Get the TCP_SEG point from a net buffer's ProtoData
|
||||
//
|
||||
#define TCPSEG_NETBUF(NBuf) ((TCP_SEG *) ((NBuf)->ProtoData))
|
||||
|
||||
//
|
||||
// macros to compare sequence no
|
||||
//
|
||||
#define TCP_SEQ_LT(SeqA, SeqB) ((INT32) ((SeqA) - (SeqB)) < 0)
|
||||
#define TCP_SEQ_LEQ(SeqA, SeqB) ((INT32) ((SeqA) - (SeqB)) <= 0)
|
||||
#define TCP_SEQ_GT(SeqA, SeqB) ((INT32) ((SeqB) - (SeqA)) < 0)
|
||||
#define TCP_SEQ_GEQ(SeqA, SeqB) ((INT32) ((SeqB) - (SeqA)) <= 0)
|
||||
|
||||
//
|
||||
// TCP_SEQ_BETWEEN return whether b <= m <= e
|
||||
//
|
||||
#define TCP_SEQ_BETWEEN(b, m, e) ((e) - (b) >= (m) - (b))
|
||||
|
||||
//
|
||||
// TCP_SUB_SEQ returns Seq1 - Seq2. Make sure Seq1 >= Seq2
|
||||
//
|
||||
#define TCP_SUB_SEQ(Seq1, Seq2) ((UINT32) ((Seq1) - (Seq2)))
|
||||
|
||||
#define TCP_FLG_ON(Value, Flag) ((BOOLEAN) (((Value) & (Flag)) != 0))
|
||||
#define TCP_SET_FLG(Value, Flag) ((Value) |= (Flag))
|
||||
#define TCP_CLEAR_FLG(Value, Flag) ((Value) &= ~(Flag))
|
||||
|
||||
//
|
||||
// test whether two peers are equal
|
||||
//
|
||||
#define TCP_PEER_EQUAL(Pa, Pb) \
|
||||
(((Pa)->Ip == (Pb)->Ip) && ((Pa)->Port == (Pb)->Port))
|
||||
|
||||
//
|
||||
// test whether Pa matches Pb, or Pa is more specific
|
||||
// than pb. Zero means wildcard.
|
||||
//
|
||||
#define TCP_PEER_MATCH(Pa, Pb) \
|
||||
((((Pb)->Ip == 0) || ((Pb)->Ip == (Pa)->Ip)) && \
|
||||
(((Pb)->Port == 0) || ((Pb)->Port == (Pa)->Port)))
|
||||
|
||||
#define TCP_TIMER_ON(Flag, Timer) ((Flag) & (1 << (Timer)))
|
||||
#define TCP_SET_TIMER(Flag, Timer) ((Flag) |= (1 << (Timer)))
|
||||
#define TCP_CLEAR_TIMER(Flag, Timer) ((Flag) &= ~(1 << (Timer)))
|
||||
|
||||
#define TCP_TIME_LT(Ta, Tb) ((INT32) ((Ta) - (Tb)) < 0)
|
||||
#define TCP_TIME_LEQ(Ta, Tb) ((INT32) ((Ta) - (Tb)) <= 0)
|
||||
#define TCP_SUB_TIME(Ta, Tb) ((UINT32) ((Ta) - (Tb)))
|
||||
|
||||
#define TCP_MAX_WIN 0xFFFFU
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(*TCP_TIMER_HANDLER) (
|
||||
IN TCP_CB * Tcb
|
||||
);
|
||||
|
||||
#include "Tcp4Func.h"
|
||||
#endif
|
|
@ -0,0 +1,582 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Tcp4Timer.c
|
||||
|
||||
Abstract:
|
||||
|
||||
TCP timer related functions.
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "Tcp4Main.h"
|
||||
|
||||
UINT32 mTcpTick = 1000;
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
TcpConnectTimeout (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
TcpRexmitTimeout (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
TcpProbeTimeout (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
TcpKeepaliveTimeout (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
TcpFinwait2Timeout (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
Tcp2MSLTimeout (
|
||||
IN TCP_CB *Tcb
|
||||
);
|
||||
|
||||
TCP_TIMER_HANDLER mTcpTimerHandler[TCP_TIMER_NUMBER] = {
|
||||
TcpConnectTimeout,
|
||||
TcpRexmitTimeout,
|
||||
TcpProbeTimeout,
|
||||
TcpKeepaliveTimeout,
|
||||
TcpFinwait2Timeout,
|
||||
Tcp2MSLTimeout,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Close the TCP connection.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
TcpClose (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
NetbufFreeList (&Tcb->SndQue);
|
||||
NetbufFreeList (&Tcb->RcvQue);
|
||||
|
||||
TcpSetState (Tcb, TCP_CLOSED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Connect timeout handler.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
TcpConnectTimeout (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
if (!TCP_CONNECTED (Tcb->State)) {
|
||||
TCP4_DEBUG_ERROR (("TcpConnectTimeout: connection closed "
|
||||
"because conenction timer timeout for TCB %x\n", Tcb));
|
||||
|
||||
if (EFI_ABORTED == Tcb->Sk->SockError) {
|
||||
SOCK_ERROR (Tcb->Sk, EFI_TIMEOUT);
|
||||
}
|
||||
|
||||
if (TCP_SYN_RCVD == Tcb->State) {
|
||||
TCP4_DEBUG_WARN (("TcpConnectTimeout: send reset because "
|
||||
"connection timer timeout for TCB %x\n", Tcb));
|
||||
|
||||
TcpResetConnection (Tcb);
|
||||
|
||||
}
|
||||
|
||||
TcpClose (Tcb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Timeout handler for TCP retransmission timer.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
TcpRexmitTimeout (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
UINT32 FlightSize;
|
||||
|
||||
TCP4_DEBUG_WARN (("TcpRexmitTimeout: transmission "
|
||||
"timeout for TCB %x\n", Tcb));
|
||||
|
||||
//
|
||||
// Set the congestion window. FlightSize is the
|
||||
// amount of data that has been sent but not
|
||||
// yet ACKed.
|
||||
//
|
||||
FlightSize = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna);
|
||||
Tcb->Ssthresh = NET_MAX ((UINT32) (2 * Tcb->SndMss), FlightSize / 2);
|
||||
|
||||
Tcb->CWnd = Tcb->SndMss;
|
||||
Tcb->LossRecover = Tcb->SndNxt;
|
||||
|
||||
Tcb->LossTimes++;
|
||||
if (Tcb->LossTimes > Tcb->MaxRexmit &&
|
||||
!TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_CONNECT)) {
|
||||
|
||||
TCP4_DEBUG_ERROR (("TcpRexmitTimeout: connection closed "
|
||||
"because too many timeouts for TCB %x\n", Tcb));
|
||||
|
||||
if (EFI_ABORTED == Tcb->Sk->SockError) {
|
||||
SOCK_ERROR (Tcb->Sk, EFI_TIMEOUT);
|
||||
}
|
||||
|
||||
TcpClose (Tcb);
|
||||
return ;
|
||||
}
|
||||
|
||||
TcpBackoffRto (Tcb);
|
||||
TcpRetransmit (Tcb, Tcb->SndUna);
|
||||
TcpSetTimer (Tcb, TCP_TIMER_REXMIT, Tcb->Rto);
|
||||
|
||||
Tcb->CongestState = TCP_CONGEST_LOSS;
|
||||
|
||||
TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_RTT_ON);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Timeout handler for window probe timer.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
TcpProbeTimeout (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
//
|
||||
// This is the timer for sender's SWSA. RFC1122 requires
|
||||
// a timer set for sender's SWSA, and suggest combine it
|
||||
// with window probe timer. If data is sent, don't set
|
||||
// the probe timer, since retransmit timer is on.
|
||||
//
|
||||
if ((TcpDataToSend (Tcb, 1) != 0) && (TcpToSendData (Tcb, 1) > 0)) {
|
||||
|
||||
ASSERT (TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_REXMIT));
|
||||
return ;
|
||||
}
|
||||
|
||||
TcpSendZeroProbe (Tcb);
|
||||
TcpSetProbeTimer (Tcb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Timeout handler for keepalive timer.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
TcpKeepaliveTimeout (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
Tcb->KeepAliveProbes++;
|
||||
|
||||
//
|
||||
// Too many Keep-alive probes, drop the connection
|
||||
//
|
||||
if (Tcb->KeepAliveProbes > Tcb->MaxKeepAlive) {
|
||||
|
||||
if (EFI_ABORTED == Tcb->Sk->SockError) {
|
||||
SOCK_ERROR (Tcb->Sk, EFI_TIMEOUT);
|
||||
}
|
||||
|
||||
TcpClose (Tcb);
|
||||
return ;
|
||||
}
|
||||
|
||||
TcpSendZeroProbe (Tcb);
|
||||
TcpSetKeepaliveTimer (Tcb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Timeout handler for FIN_WAIT_2 timer.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
TcpFinwait2Timeout (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
TCP4_DEBUG_WARN (("TcpFinwait2Timeout: connection closed "
|
||||
"because FIN_WAIT2 timer timeouts for TCB %x\n", Tcb));
|
||||
|
||||
TcpClose (Tcb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Timeout handler for 2MSL timer.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
Tcp2MSLTimeout (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
TCP4_DEBUG_WARN (("Tcp2MSLTimeout: connection closed "
|
||||
"because TIME_WAIT timer timeouts for TCB %x\n", Tcb));
|
||||
|
||||
TcpClose (Tcb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Update the timer status and the next expire time
|
||||
according to the timers to expire in a specific
|
||||
future time slot.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
TcpUpdateTimer (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
UINT16 Index;
|
||||
|
||||
//
|
||||
// Don't use a too large value to init NextExpire
|
||||
// since mTcpTick wraps around as sequence no does.
|
||||
//
|
||||
Tcb->NextExpire = 65535;
|
||||
TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_TIMER_ON);
|
||||
|
||||
for (Index = 0; Index < TCP_TIMER_NUMBER; Index++) {
|
||||
|
||||
if (TCP_TIMER_ON (Tcb->EnabledTimer, Index) &&
|
||||
TCP_TIME_LT (Tcb->Timer[Index], mTcpTick + Tcb->NextExpire)) {
|
||||
|
||||
Tcb->NextExpire = TCP_SUB_TIME (Tcb->Timer[Index], mTcpTick);
|
||||
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_TIMER_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Enable a TCP timer.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
@param Timer The index of the timer to be enabled.
|
||||
@param TimeOut The timeout value of this timer.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
TcpSetTimer (
|
||||
IN TCP_CB *Tcb,
|
||||
IN UINT16 Timer,
|
||||
IN UINT32 TimeOut
|
||||
)
|
||||
{
|
||||
TCP_SET_TIMER (Tcb->EnabledTimer, Timer);
|
||||
Tcb->Timer[Timer] = mTcpTick + TimeOut;
|
||||
|
||||
TcpUpdateTimer (Tcb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Clear one TCP timer.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
@param Timer The index of the timer to be cleared.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
TcpClearTimer (
|
||||
IN TCP_CB *Tcb,
|
||||
IN UINT16 Timer
|
||||
)
|
||||
{
|
||||
TCP_CLEAR_TIMER (Tcb->EnabledTimer, Timer);
|
||||
TcpUpdateTimer (Tcb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Clear all TCP timers.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
TcpClearAllTimer (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
Tcb->EnabledTimer = 0;
|
||||
TcpUpdateTimer (Tcb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Enable the window prober timer and set the timeout value.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
TcpSetProbeTimer (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
if (!TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_PROBE)) {
|
||||
Tcb->ProbeTime = Tcb->Rto;
|
||||
|
||||
} else {
|
||||
Tcb->ProbeTime <<= 1;
|
||||
}
|
||||
|
||||
if (Tcb->ProbeTime < TCP_RTO_MIN) {
|
||||
|
||||
Tcb->ProbeTime = TCP_RTO_MIN;
|
||||
} else if (Tcb->ProbeTime > TCP_RTO_MAX) {
|
||||
|
||||
Tcb->ProbeTime = TCP_RTO_MAX;
|
||||
}
|
||||
|
||||
TcpSetTimer (Tcb, TCP_TIMER_PROBE, Tcb->ProbeTime);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Enable the keepalive timer and set the timeout value.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
TcpSetKeepaliveTimer (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE)) {
|
||||
return ;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Set the timer to KeepAliveIdle if either
|
||||
// 1. the keepalive timer is off
|
||||
// 2. The keepalive timer is on, but the idle
|
||||
// is less than KeepAliveIdle, that means the
|
||||
// connection is alive since our last probe.
|
||||
//
|
||||
if (!TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_KEEPALIVE) ||
|
||||
(Tcb->Idle < Tcb->KeepAliveIdle)) {
|
||||
|
||||
TcpSetTimer (Tcb, TCP_TIMER_KEEPALIVE, Tcb->KeepAliveIdle);
|
||||
Tcb->KeepAliveProbes = 0;
|
||||
|
||||
} else {
|
||||
|
||||
TcpSetTimer (Tcb, TCP_TIMER_KEEPALIVE, Tcb->KeepAlivePeriod);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Backoff the RTO.
|
||||
|
||||
@param Tcb Pointer to the TCP_CB of this TCP instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
TcpBackoffRto (
|
||||
IN TCP_CB *Tcb
|
||||
)
|
||||
{
|
||||
//
|
||||
// Fold the RTT estimate if too many times, the estimate
|
||||
// may be wrong, fold it. So the next time a valid
|
||||
// measurement is sampled, we can start fresh.
|
||||
//
|
||||
if ((Tcb->LossTimes >= TCP_FOLD_RTT) && Tcb->SRtt) {
|
||||
Tcb->RttVar += Tcb->SRtt >> 2;
|
||||
Tcb->SRtt = 0;
|
||||
}
|
||||
|
||||
Tcb->Rto <<= 1;
|
||||
|
||||
if (Tcb->Rto < TCP_RTO_MIN) {
|
||||
|
||||
Tcb->Rto = TCP_RTO_MIN;
|
||||
} else if (Tcb->Rto > TCP_RTO_MAX) {
|
||||
|
||||
Tcb->Rto = TCP_RTO_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Heart beat timer handler.
|
||||
|
||||
@param Event Timer event signaled, ignored.
|
||||
@param Context Context of the timer event, ignored.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
TcpTicking (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
NET_LIST_ENTRY *Entry;
|
||||
NET_LIST_ENTRY *Next;
|
||||
TCP_CB *Tcb;
|
||||
INT16 Index;
|
||||
|
||||
mTcpTick++;
|
||||
mTcpGlobalIss += 100;
|
||||
|
||||
//
|
||||
// Don't use LIST_FOR_EACH, which isn't delete safe.
|
||||
//
|
||||
for (Entry = mTcpRunQue.ForwardLink; Entry != &mTcpRunQue; Entry = Next) {
|
||||
|
||||
Next = Entry->ForwardLink;
|
||||
|
||||
Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
||||
|
||||
if (Tcb->State == TCP_CLOSED) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// The connection is doing RTT measurement.
|
||||
//
|
||||
if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RTT_ON)) {
|
||||
Tcb->RttMeasure++;
|
||||
}
|
||||
|
||||
Tcb->Idle++;
|
||||
|
||||
if (Tcb->DelayedAck) {
|
||||
TcpSendAck (Tcb);
|
||||
}
|
||||
|
||||
//
|
||||
// No timer is active or no timer expired
|
||||
//
|
||||
if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_TIMER_ON) ||
|
||||
((--Tcb->NextExpire) > 0)) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Call the timeout handler for each expired timer.
|
||||
//
|
||||
for (Index = 0; Index < TCP_TIMER_NUMBER; Index++) {
|
||||
|
||||
if (TCP_TIMER_ON (Tcb->EnabledTimer, Index) &&
|
||||
TCP_TIME_LEQ (Tcb->Timer[Index], mTcpTick)) {
|
||||
//
|
||||
// disable the timer before calling the handler
|
||||
// in case the handler enables it again.
|
||||
//
|
||||
TCP_CLEAR_TIMER (Tcb->EnabledTimer, Index);
|
||||
mTcpTimerHandler[Index](Tcb);
|
||||
|
||||
//
|
||||
// The Tcb may have been deleted by the timer, or
|
||||
// no other timer is set.
|
||||
//
|
||||
if ((Next->BackLink != Entry) ||
|
||||
(Tcb->EnabledTimer == 0)) {
|
||||
|
||||
goto NextConnection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TcpUpdateTimer (Tcb);
|
||||
NextConnection:
|
||||
;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
ComponentName.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "Udp4Impl.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UdpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UdpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
//
|
||||
// EFI Component Name Protocol
|
||||
//
|
||||
EFI_COMPONENT_NAME_PROTOCOL gUdp4ComponentName = {
|
||||
UdpComponentNameGetDriverName,
|
||||
UdpComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
static EFI_UNICODE_STRING_TABLE mUdpDriverNameTable[] = {
|
||||
{
|
||||
"eng",
|
||||
L"UDP Network Service Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UdpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Retrieves a Unicode string that is the user readable name of the EFI Driver.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
Language - A pointer to a three character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages specified
|
||||
in SupportedLanguages. The number of languages supported by a
|
||||
driver is up to the driver writer.
|
||||
DriverName - A pointer to the Unicode string to return. This Unicode string
|
||||
is the name of the driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCES - The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - DriverName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return LookupUnicodeString (
|
||||
Language,
|
||||
gUdp4ComponentName.SupportedLanguages,
|
||||
mUdpDriverNameTable,
|
||||
DriverName
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UdpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
ControllerHandle - The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
ChildHandle - The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL. It
|
||||
will be NULL for device drivers. It will also be NULL
|
||||
for a bus drivers that wish to retrieve the name of the
|
||||
bus controller. It will not be NULL for a bus driver
|
||||
that wishes to retrieve the name of a child controller.
|
||||
Language - A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller name
|
||||
that that the caller is requesting, and it must match one
|
||||
of the languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up to the
|
||||
driver writer.
|
||||
ControllerName - A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language specified
|
||||
by Language from the point of view of the driver specified
|
||||
by This.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The Unicode string for the user readable name in the
|
||||
language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - ControllerName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This is not currently managing
|
||||
the controller specified by ControllerHandle and
|
||||
ChildHandle.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
|
@ -0,0 +1,526 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Udp4Driver.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "Udp4Impl.h"
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gUdp4DriverBinding = {
|
||||
Udp4DriverBindingSupported,
|
||||
Udp4DriverBindingStart,
|
||||
Udp4DriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding = {
|
||||
Udp4ServiceBindingCreateChild,
|
||||
Udp4ServiceBindingDestroyChild
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Test to see if this driver supports ControllerHandle.
|
||||
|
||||
@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_SUCCES This driver supports this device.
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Test for the Udp4ServiceBinding Protocol
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUdp4ServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Test for the Ip4 Protocol
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiIp4ServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle.
|
||||
|
||||
@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_SUCCES This driver is added to ControllerHandle
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
|
||||
@retval other This driver does not support this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UDP4_SERVICE_DATA *Udp4Service;
|
||||
|
||||
//
|
||||
// Allocate Private Context Data Structure.
|
||||
//
|
||||
Udp4Service = NetAllocatePool (sizeof (UDP4_SERVICE_DATA));
|
||||
if (Udp4Service == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = Udp4CreateService (Udp4Service, This->DriverBindingHandle, ControllerHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto FREE_SERVICE;
|
||||
}
|
||||
|
||||
//
|
||||
// Install the Udp4ServiceBindingProtocol on the ControllerHandle.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ControllerHandle,
|
||||
&gEfiUdp4ServiceBindingProtocolGuid,
|
||||
&Udp4Service->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto CLEAN_SERVICE;
|
||||
}
|
||||
|
||||
Udp4SetVariableData (Udp4Service);
|
||||
|
||||
return Status;
|
||||
|
||||
CLEAN_SERVICE:
|
||||
|
||||
Udp4CleanService (Udp4Service);
|
||||
|
||||
FREE_SERVICE:
|
||||
|
||||
NetFreePool (Udp4Service);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle.
|
||||
|
||||
@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_SUCCES This driver is removed ControllerHandle.
|
||||
@retval other This driver was not removed from this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE NicHandle;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
UDP4_SERVICE_DATA *Udp4Service;
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
|
||||
//
|
||||
// Find the NicHandle where UDP4 ServiceBinding Protocol is installed.
|
||||
//
|
||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
|
||||
if (NicHandle == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve the UDP4 ServiceBinding Protocol.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
&gEfiUdp4ServiceBindingProtocolGuid,
|
||||
(VOID **) &ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
NicHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding);
|
||||
|
||||
//
|
||||
// Uninstall the UDP4 ServiceBinding Protocol.
|
||||
//
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
NicHandle,
|
||||
&gEfiUdp4ServiceBindingProtocolGuid,
|
||||
&Udp4Service->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
while (!NetListIsEmpty (&Udp4Service->ChildrenList)) {
|
||||
//
|
||||
// Destroy all instances.
|
||||
//
|
||||
Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link);
|
||||
|
||||
ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
|
||||
}
|
||||
|
||||
Udp4ClearVariableData (Udp4Service);
|
||||
|
||||
Udp4CleanService (Udp4Service);
|
||||
|
||||
NetFreePool (Udp4Service);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Creates a child handle with a set of I/O services.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If
|
||||
it is NULL, then a new handle is created. If it
|
||||
is not NULL, then the I/O services are added to
|
||||
the existing child handle.
|
||||
|
||||
@retval EFI_SUCCES The child handle was created with the I/O services
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
|
||||
the child
|
||||
@retval other The child handle was not created
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UDP4_SERVICE_DATA *Udp4Service;
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
VOID *Ip4;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Allocate the instance private data structure.
|
||||
//
|
||||
Instance = NetAllocatePool (sizeof (UDP4_INSTANCE_DATA));
|
||||
if (Instance == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Udp4InitInstance (Udp4Service, Instance);
|
||||
|
||||
//
|
||||
// Add an IpInfo for this instance.
|
||||
//
|
||||
Instance->IpInfo = IpIoAddIp (Udp4Service->IpIo);
|
||||
if (Instance->IpInfo == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto FREE_INSTANCE;
|
||||
}
|
||||
|
||||
//
|
||||
// Install the Udp4Protocol for this instance.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiUdp4ProtocolGuid,
|
||||
&Instance->Udp4Proto,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto REMOVE_IPINFO;
|
||||
}
|
||||
|
||||
Instance->ChildHandle = *ChildHandle;
|
||||
|
||||
//
|
||||
// Open the default Ip4 protocol in the IP_IO BY_CHILD.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
Udp4Service->IpIo->ChildHandle,
|
||||
&gEfiIp4ProtocolGuid,
|
||||
(VOID **) &Ip4,
|
||||
gUdp4DriverBinding.DriverBindingHandle,
|
||||
Instance->ChildHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto UNINSTALL_PROTOCOL;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
//
|
||||
// Link this instance into the service context data and increase the ChildrenNumber.
|
||||
//
|
||||
NetListInsertTail (&Udp4Service->ChildrenList, &Instance->Link);
|
||||
Udp4Service->ChildrenNumber++;
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
|
||||
UNINSTALL_PROTOCOL:
|
||||
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
Instance->ChildHandle,
|
||||
&gEfiUdp4ProtocolGuid,
|
||||
&Instance->Udp4Proto,
|
||||
NULL
|
||||
);
|
||||
|
||||
REMOVE_IPINFO:
|
||||
|
||||
IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo);
|
||||
|
||||
FREE_INSTANCE:
|
||||
|
||||
Udp4CleanInstance (Instance);
|
||||
|
||||
NetFreePool (Instance);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destroys a child handle with a set of I/O services.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The I/O services were removed from the child
|
||||
handle
|
||||
@retval EFI_UNSUPPORTED The child handle does not support the I/O services
|
||||
that are being removed
|
||||
@retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.
|
||||
@retval EFI_ACCESS_DENIED The child handle could not be destroyed because
|
||||
its I/O services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UDP4_SERVICE_DATA *Udp4Service;
|
||||
EFI_UDP4_PROTOCOL *Udp4Proto;
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Try to get the Udp4 protocol from the ChildHandle.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiUdp4ProtocolGuid,
|
||||
(VOID **) &Udp4Proto,
|
||||
gUdp4DriverBinding.DriverBindingHandle,
|
||||
ChildHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Instance = UDP4_INSTANCE_DATA_FROM_THIS (Udp4Proto);
|
||||
|
||||
if (Instance->Destroyed) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Use the Destroyed flag to avoid the re-entering of the following code.
|
||||
//
|
||||
Instance->Destroyed = TRUE;
|
||||
|
||||
//
|
||||
// Close the Ip4 protocol.
|
||||
//
|
||||
gBS->CloseProtocol (
|
||||
Udp4Service->IpIo->ChildHandle,
|
||||
&gEfiIp4ProtocolGuid,
|
||||
gUdp4DriverBinding.DriverBindingHandle,
|
||||
Instance->ChildHandle
|
||||
);
|
||||
|
||||
//
|
||||
// Uninstall the Udp4Protocol previously installed on the ChildHandle.
|
||||
//
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiUdp4ProtocolGuid,
|
||||
(VOID *) &Instance->Udp4Proto,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Instance->Destroyed = FALSE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Reset the configuration in case the instance's consumer forgets to do this.
|
||||
//
|
||||
Udp4Proto->Configure (Udp4Proto, NULL);
|
||||
|
||||
//
|
||||
// Remove the IpInfo this instance consumes.
|
||||
//
|
||||
IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo);
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
//
|
||||
// Remove this instance from the service context data's ChildrenList.
|
||||
//
|
||||
NetListRemoveEntry (&Instance->Link);
|
||||
Udp4Service->ChildrenNumber--;
|
||||
|
||||
//
|
||||
// Clean the instance.
|
||||
//
|
||||
Udp4CleanInstance (Instance);
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
NetFreePool (Instance);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//@MT: EFI_DRIVER_ENTRY_POINT (Udp4DriverEntryPoint)
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4DriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The entry point for Udp4 driver which installs the driver binding
|
||||
and component name protocol on its ImageHandle.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - The image handle of the driver.
|
||||
SystemTable - The system table.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - if the driver binding and component name protocols are
|
||||
successfully installed, otherwise if failed.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Install the Udp4DriverBinding and Udp4ComponentName protocols.
|
||||
//
|
||||
Status = NetLibInstallAllDriverProtocols (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gUdp4DriverBinding,
|
||||
ImageHandle,
|
||||
&gUdp4ComponentName,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Initialize the UDP random port.
|
||||
//
|
||||
mUdp4RandomPort = ((UINT16) NetRandomInitSeed ()) % UDP4_PORT_KNOWN + UDP4_PORT_KNOWN;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
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:
|
||||
|
||||
Udp4Driver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _UDP4_DRIVER_H_
|
||||
#define _UDP4_DRIVER_H_
|
||||
|
||||
#include <PiDxe.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/NetLib.h>
|
||||
#include <Protocol/DriverBinding.h>
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#/** @file
|
||||
# Component name for module Udp4
|
||||
#
|
||||
# FIX ME!
|
||||
# Copyright (c) 2006, Intel Corporation. All right reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = Udp4
|
||||
FILE_GUID = 6d6963ab-906d-4a65-a7ca-bd40e5d6af2b
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = Udp4DriverEntryPoint
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources.common]
|
||||
Udp4Impl.h
|
||||
Udp4Main.c
|
||||
ComponentName.c
|
||||
Udp4Impl.c
|
||||
Udp4Driver.h
|
||||
Udp4Driver.c
|
||||
CommonHeader.h
|
||||
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
UefiLib
|
||||
BaseLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
UefiRuntimeServicesTableLib
|
||||
DebugLib
|
||||
IpIoLib
|
||||
NetLib
|
||||
|
||||
|
||||
[Protocols]
|
||||
gEfiIp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiUdp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiIp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<MsaHeader>
|
||||
<ModuleName>Udp4</ModuleName>
|
||||
<ModuleType>DXE_DRIVER</ModuleType>
|
||||
<GuidValue>6d6963ab-906d-4a65-a7ca-bd40e5d6af2b</GuidValue>
|
||||
<Version>1.0</Version>
|
||||
<Abstract>Component name for module Udp4</Abstract>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2006, Intel Corporation. All right reserved.</Copyright>
|
||||
<License>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.</License>
|
||||
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
|
||||
</MsaHeader>
|
||||
<ModuleDefinitions>
|
||||
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
|
||||
<BinaryModule>false</BinaryModule>
|
||||
<OutputFileBasename>Udp4</OutputFileBasename>
|
||||
</ModuleDefinitions>
|
||||
<LibraryClassDefinitions>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>DebugLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiRuntimeServicesTableLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiDriverEntryPoint</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiBootServicesTableLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>BaseLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiLib</Keyword>
|
||||
</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>Udp4Driver.c</Filename>
|
||||
<Filename>Udp4Driver.h</Filename>
|
||||
<Filename>Udp4Impl.c</Filename>
|
||||
<Filename>ComponentName.c</Filename>
|
||||
<Filename>Udp4Main.c</Filename>
|
||||
<Filename>Udp4Impl.h</Filename>
|
||||
</SourceFiles>
|
||||
<PackageDependencies>
|
||||
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
|
||||
</PackageDependencies>
|
||||
<Protocols>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiUdp4ProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiIp4ServiceBindingProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiUdp4ServiceBindingProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiIp4ProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
</Protocols>
|
||||
<Externs>
|
||||
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
|
||||
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
|
||||
<Extern>
|
||||
<ModuleEntryPoint>Udp4DriverEntryPoint</ModuleEntryPoint>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,299 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
Udp4Impl.h
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI UDPv4 protocol implementation
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _UDP4_IMPL_H_
|
||||
#define _UDP4_IMPL_H_
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/IP4.h>
|
||||
#include <Protocol/Udp4.h>
|
||||
|
||||
#include <Library/IpIoLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
|
||||
#include "Udp4Driver.h"
|
||||
|
||||
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gUdp4ComponentName;
|
||||
extern EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding;
|
||||
extern EFI_UDP4_PROTOCOL mUdp4Protocol;
|
||||
extern UINT16 mUdp4RandomPort;
|
||||
|
||||
#define ICMP_ERROR_PACKET_LENGTH 8
|
||||
|
||||
#define UDP4_TIMEOUT_INTERVAL (50 * TICKS_PER_MS) // 50 milliseconds
|
||||
|
||||
#define UDP4_HEADER_SIZE sizeof (EFI_UDP4_HEADER)
|
||||
#define UDP4_MAX_DATA_SIZE 65507
|
||||
|
||||
#define UDP4_PORT_KNOWN 1024
|
||||
|
||||
#define UDP4_SERVICE_DATA_SIGNATURE EFI_SIGNATURE_32('U', 'd', 'p', '4')
|
||||
|
||||
#define UDP4_SERVICE_DATA_FROM_THIS(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
UDP4_SERVICE_DATA, \
|
||||
ServiceBinding, \
|
||||
UDP4_SERVICE_DATA_SIGNATURE \
|
||||
)
|
||||
|
||||
typedef struct _UDP4_SERVICE_DATA_ {
|
||||
UINT32 Signature;
|
||||
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||
EFI_HANDLE ImageHandle;
|
||||
EFI_HANDLE ControllerHandle;
|
||||
NET_LIST_ENTRY ChildrenList;
|
||||
UINTN ChildrenNumber;
|
||||
IP_IO *IpIo;
|
||||
|
||||
EFI_EVENT TimeoutEvent;
|
||||
|
||||
CHAR16 *MacString;
|
||||
} UDP4_SERVICE_DATA;
|
||||
|
||||
#define UDP4_INSTANCE_DATA_SIGNATURE EFI_SIGNATURE_32('U', 'd', 'p', 'I')
|
||||
|
||||
#define UDP4_INSTANCE_DATA_FROM_THIS(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
UDP4_INSTANCE_DATA, \
|
||||
Udp4Proto, \
|
||||
UDP4_INSTANCE_DATA_SIGNATURE \
|
||||
)
|
||||
|
||||
typedef struct _UDP4_INSTANCE_DATA_ {
|
||||
UINT32 Signature;
|
||||
NET_LIST_ENTRY Link;
|
||||
|
||||
UDP4_SERVICE_DATA *Udp4Service;
|
||||
EFI_UDP4_PROTOCOL Udp4Proto;
|
||||
EFI_UDP4_CONFIG_DATA ConfigData;
|
||||
EFI_HANDLE ChildHandle;
|
||||
BOOLEAN Configured;
|
||||
BOOLEAN IsNoMapping;
|
||||
|
||||
NET_MAP TxTokens;
|
||||
NET_MAP RxTokens;
|
||||
|
||||
NET_MAP McastIps;
|
||||
|
||||
NET_LIST_ENTRY RcvdDgramQue;
|
||||
NET_LIST_ENTRY DeliveredDgramQue;
|
||||
|
||||
UINT16 HeadSum;
|
||||
|
||||
EFI_STATUS IcmpError;
|
||||
|
||||
IP_IO_IP_INFO *IpInfo;
|
||||
|
||||
BOOLEAN Destroyed;
|
||||
} UDP4_INSTANCE_DATA;
|
||||
|
||||
typedef struct _UDP4_RXDATA_WRAP_ {
|
||||
NET_LIST_ENTRY Link;
|
||||
NET_BUF *Packet;
|
||||
UINT32 TimeoutTick;
|
||||
EFI_UDP4_RECEIVE_DATA RxData;
|
||||
} UDP4_RXDATA_WRAP;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4GetModeData (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
OUT EFI_UDP4_CONFIG_DATA *Udp4ConfigData OPTIONAL,
|
||||
OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL,
|
||||
OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
|
||||
OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Configure (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN EFI_UDP4_CONFIG_DATA *UdpConfigData OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Groups (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN BOOLEAN JoinFlag,
|
||||
IN EFI_IPv4_ADDRESS *MulticastAddress OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Routes (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN BOOLEAN DeleteRoute,
|
||||
IN EFI_IPv4_ADDRESS *SubnetAddress,
|
||||
IN EFI_IPv4_ADDRESS *SubnetMask,
|
||||
IN EFI_IPv4_ADDRESS *GatewayAddress
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Transmit (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN EFI_UDP4_COMPLETION_TOKEN *Token
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Receive (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN EFI_UDP4_COMPLETION_TOKEN *Token
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Cancel (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN EFI_UDP4_COMPLETION_TOKEN *Token OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Poll (
|
||||
IN EFI_UDP4_PROTOCOL *This
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
Udp4CreateService (
|
||||
IN UDP4_SERVICE_DATA *Udp4Service,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_HANDLE ControllerHandle
|
||||
);
|
||||
|
||||
VOID
|
||||
Udp4CleanService (
|
||||
IN UDP4_SERVICE_DATA *Udp4Service
|
||||
);
|
||||
|
||||
VOID
|
||||
Udp4InitInstance (
|
||||
IN UDP4_SERVICE_DATA *Udp4Service,
|
||||
IN UDP4_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
VOID
|
||||
Udp4CleanInstance (
|
||||
IN UDP4_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
Udp4Bind (
|
||||
IN NET_LIST_ENTRY *InstanceList,
|
||||
IN EFI_UDP4_CONFIG_DATA *ConfigData
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
Udp4IsReconfigurable (
|
||||
IN EFI_UDP4_CONFIG_DATA *OldConfigData,
|
||||
IN EFI_UDP4_CONFIG_DATA *NewConfigData
|
||||
);
|
||||
|
||||
VOID
|
||||
Udp4BuildIp4ConfigData (
|
||||
IN EFI_UDP4_CONFIG_DATA *Udp4ConfigData,
|
||||
IN EFI_IP4_CONFIG_DATA *Ip4ConfigData
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
Udp4ValidateTxToken (
|
||||
IN UDP4_INSTANCE_DATA *Instance,
|
||||
IN EFI_UDP4_COMPLETION_TOKEN *TxToken
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
Udp4TokenExist (
|
||||
IN NET_MAP *Map,
|
||||
IN NET_MAP_ITEM *Item,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
UINT16
|
||||
Udp4Checksum (
|
||||
IN NET_BUF *Packet,
|
||||
IN UINT16 HeadSum
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
Udp4RemoveToken (
|
||||
IN NET_MAP *TokenMap,
|
||||
IN EFI_UDP4_COMPLETION_TOKEN *Token
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
Udp4LeaveGroup (
|
||||
IN NET_MAP *Map,
|
||||
IN NET_MAP_ITEM *Item,
|
||||
IN VOID *Arg OPTIONAL
|
||||
);
|
||||
|
||||
VOID
|
||||
Udp4FlushRxData (
|
||||
IN NET_LIST_ENTRY *RcvdDgramQue
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
Udp4InstanceCancelToken (
|
||||
IN UDP4_INSTANCE_DATA *Instance,
|
||||
IN EFI_UDP4_COMPLETION_TOKEN *Token OPTIONAL
|
||||
);
|
||||
|
||||
VOID
|
||||
Udp4InstanceDeliverDgram (
|
||||
IN UDP4_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
VOID
|
||||
Udp4ReportIcmpError (
|
||||
IN UDP4_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
VOID
|
||||
Udp4NetVectorExtFree (
|
||||
VOID *Context
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
Udp4SetVariableData (
|
||||
IN UDP4_SERVICE_DATA *Udp4Service
|
||||
);
|
||||
|
||||
VOID
|
||||
Udp4ClearVariableData (
|
||||
IN UDP4_SERVICE_DATA *Udp4Service
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,869 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
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:
|
||||
|
||||
Udp4Main.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "Udp4Impl.h"
|
||||
|
||||
#include <Protocol/Ip4.h>
|
||||
|
||||
EFI_UDP4_PROTOCOL mUdp4Protocol = {
|
||||
Udp4GetModeData,
|
||||
Udp4Configure,
|
||||
Udp4Groups,
|
||||
Udp4Routes,
|
||||
Udp4Transmit,
|
||||
Udp4Receive,
|
||||
Udp4Cancel,
|
||||
Udp4Poll
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This function copies the current operational settings of this EFI UDPv4 Protocol
|
||||
instance into user-supplied buffers. This function is used optionally to retrieve
|
||||
the operational mode data of underlying networks or drivers.
|
||||
|
||||
@param This Pointer to the EFI_UDP4_PROTOCOL instance.
|
||||
@param Udp4ConfigData Pointer to the buffer to receive the current
|
||||
configuration data.
|
||||
@param Ip4ModeData Pointer to the EFI IPv4 Protocol mode data
|
||||
structure.
|
||||
@param MnpConfigData Pointer to the managed network configuration data
|
||||
structure.
|
||||
@param SnpModeData Pointer to the simple network mode data structure.
|
||||
|
||||
@retval EFI_SUCCESS The mode data was read.
|
||||
@retval EFI_NOT_STARTED When Udp4ConfigData is queried, no configuration
|
||||
data is available because this instance has not
|
||||
been started.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4GetModeData (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
OUT EFI_UDP4_CONFIG_DATA *Udp4ConfigData OPTIONAL,
|
||||
OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL,
|
||||
OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
|
||||
OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
|
||||
)
|
||||
{
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
EFI_IP4_PROTOCOL *Ip;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = UDP4_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured && (Udp4ConfigData != NULL)) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if (Udp4ConfigData != NULL) {
|
||||
//
|
||||
// Set the Udp4ConfigData.
|
||||
//
|
||||
*Udp4ConfigData = Instance->ConfigData;
|
||||
}
|
||||
|
||||
Ip = Instance->IpInfo->Ip;
|
||||
|
||||
//
|
||||
// Get the underlying Ip4ModeData, MnpConfigData and SnpModeData.
|
||||
//
|
||||
Status = Ip->GetModeData (Ip, Ip4ModeData, MnpConfigData, SnpModeData);
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function is used to do the following:
|
||||
Initialize and start this instance of the EFI UDPv4 Protocol.
|
||||
Change the filtering rules and operational parameters.
|
||||
Reset this instance of the EFI UDPv4 Protocol.
|
||||
|
||||
@param This Pointer to the EFI_UDP4_PROTOCOL instance.
|
||||
@param UdpConfigData Pointer to the buffer to receive the current mode
|
||||
data.
|
||||
|
||||
@retval EFI_SUCCESS The configuration settings were set, changed, or
|
||||
reset successfully.
|
||||
@retval EFI_NO_MAPPING When using a default address, configuration (DHCP,
|
||||
BOOTP, RARP, etc.) is not finished yet.
|
||||
@retval EFI_INVALID_PARAMETER One or more following conditions are TRUE: This is
|
||||
NULL. UdpConfigData.StationAddress is not a valid
|
||||
unicast IPv4 address. UdpConfigData.SubnetMask is
|
||||
not a valid IPv4 address mask.
|
||||
UdpConfigData.RemoteAddress is not a valid unicast
|
||||
IPv4 address if it is not zero.
|
||||
@retval EFI_ALREADY_STARTED The EFI UDPv4 Protocol instance is already
|
||||
started/configured and must be stopped/reset
|
||||
before it can be reconfigured. Only TypeOfService,
|
||||
TimeToLive, DoNotFragment, ReceiveTimeout, and
|
||||
TransmitTimeout can be reconfigured without
|
||||
stopping the current instance of the EFI UDPv4
|
||||
Protocol.
|
||||
@retval EFI_ACCESS_DENIED UdpConfigData.AllowDuplicatePort is FALSE and
|
||||
UdpConfigData.StationPort is already used by other
|
||||
instance.
|
||||
@retval EFI_OUT_OF_RESOURCES The EFI UDPv4 Protocol driver cannot allocate
|
||||
memory for this EFI UDPv4 Protocol instance.
|
||||
@retval EFI_DEVICE_ERROR An unexpected network or system error occurred and
|
||||
this instance was not opened.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Configure (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN EFI_UDP4_CONFIG_DATA *UdpConfigData OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
UDP4_SERVICE_DATA *Udp4Service;
|
||||
EFI_TPL OldTpl;
|
||||
IP4_ADDR StationAddress;
|
||||
IP4_ADDR SubnetMask;
|
||||
IP4_ADDR RemoteAddress;
|
||||
EFI_IP4_CONFIG_DATA Ip4ConfigData;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = UDP4_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured && (UdpConfigData == NULL)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Udp4Service = Instance->Udp4Service;
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if (UdpConfigData != NULL) {
|
||||
|
||||
StationAddress = EFI_NTOHL (UdpConfigData->StationAddress);
|
||||
SubnetMask = EFI_NTOHL (UdpConfigData->SubnetMask);
|
||||
RemoteAddress = EFI_NTOHL (UdpConfigData->RemoteAddress);
|
||||
|
||||
if (!UdpConfigData->UseDefaultAddress &&
|
||||
(!IP4_IS_VALID_NETMASK (SubnetMask) ||
|
||||
!((StationAddress == 0) || Ip4IsUnicast (StationAddress, SubnetMask)) ||
|
||||
!((RemoteAddress == 0) || Ip4IsUnicast (RemoteAddress, 0)))) {
|
||||
//
|
||||
// Don't use default address, and subnet mask is invalid or StationAddress is not
|
||||
// a valid unicast IPv4 address or RemoteAddress is not a valid unicast IPv4 address
|
||||
// if it is not 0.
|
||||
//
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (Instance->Configured) {
|
||||
//
|
||||
// The instance is already configured, try to do the re-configuration.
|
||||
//
|
||||
if (!Udp4IsReconfigurable (&Instance->ConfigData, UdpConfigData)) {
|
||||
//
|
||||
// If the new configuration data wants to change some unreconfigurable
|
||||
// settings, return EFI_ALREADY_STARTED.
|
||||
//
|
||||
Status = EFI_ALREADY_STARTED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Save the reconfigurable parameters.
|
||||
//
|
||||
Instance->ConfigData.TypeOfService = UdpConfigData->TypeOfService;
|
||||
Instance->ConfigData.TimeToLive = UdpConfigData->TimeToLive;
|
||||
Instance->ConfigData.DoNotFragment = UdpConfigData->DoNotFragment;
|
||||
Instance->ConfigData.ReceiveTimeout = UdpConfigData->ReceiveTimeout;
|
||||
Instance->ConfigData.TransmitTimeout = UdpConfigData->TransmitTimeout;
|
||||
} else {
|
||||
//
|
||||
// Construct the Ip configuration data from the UdpConfigData.
|
||||
//
|
||||
Udp4BuildIp4ConfigData (UdpConfigData, &Ip4ConfigData);
|
||||
|
||||
//
|
||||
// Configure the Ip instance wrapped in the IpInfo.
|
||||
//
|
||||
Status = IpIoConfigIp (Instance->IpInfo, &Ip4ConfigData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status == EFI_NO_MAPPING) {
|
||||
Instance->IsNoMapping = TRUE;
|
||||
}
|
||||
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Instance->IsNoMapping = FALSE;
|
||||
|
||||
//
|
||||
// Save the configuration data.
|
||||
//
|
||||
Instance->ConfigData = *UdpConfigData;
|
||||
Instance->ConfigData.StationAddress = Ip4ConfigData.StationAddress;
|
||||
Instance->ConfigData.SubnetMask = Ip4ConfigData.SubnetMask;
|
||||
|
||||
//
|
||||
// Try to allocate the required port resource.
|
||||
//
|
||||
Status = Udp4Bind (&Udp4Service->ChildrenList, &Instance->ConfigData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Reset the ip instance if bind fails.
|
||||
//
|
||||
IpIoConfigIp (Instance->IpInfo, NULL);
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Pre calculate the checksum for the pseudo head, ignore the UDP length first.
|
||||
//
|
||||
Instance->HeadSum = NetPseudoHeadChecksum (
|
||||
EFI_IP4 (Instance->ConfigData.StationAddress),
|
||||
EFI_IP4 (Instance->ConfigData.RemoteAddress),
|
||||
EFI_IP_PROTO_UDP,
|
||||
0
|
||||
);
|
||||
|
||||
Instance->Configured = TRUE;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// UdpConfigData is NULL, reset the instance.
|
||||
//
|
||||
Instance->Configured = FALSE;
|
||||
Instance->IsNoMapping = FALSE;
|
||||
|
||||
//
|
||||
// Reset the Ip instance wrapped in the IpInfo.
|
||||
//
|
||||
IpIoConfigIp (Instance->IpInfo, NULL);
|
||||
|
||||
//
|
||||
// Cancel all the user tokens.
|
||||
//
|
||||
Udp4InstanceCancelToken (Instance, NULL);
|
||||
|
||||
//
|
||||
// Remove the buffered RxData for this instance.
|
||||
//
|
||||
Udp4FlushRxData (&Instance->RcvdDgramQue);
|
||||
}
|
||||
|
||||
Udp4SetVariableData (Instance->Udp4Service);
|
||||
|
||||
ON_EXIT:
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function is used to enable and disable the multicast group filtering.
|
||||
|
||||
@param This Pointer to the EFI_UDP4_PROTOCOL instance.
|
||||
@param JoinFlag Set to TRUE to join a multicast group. Set to
|
||||
FALSE to leave one or all multicast groups.
|
||||
@param MulticastAddress Pointer to multicast group address to join or
|
||||
leave.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_NOT_STARTED The EFI UDPv4 Protocol instance has not been
|
||||
started.
|
||||
@retval EFI_NO_MAPPING When using a default address, configuration (DHCP,
|
||||
BOOTP, RARP, etc.) is not finished yet.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate resources to join the group.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. JoinFlag is TRUE and
|
||||
MulticastAddress is NULL. JoinFlag is TRUE and
|
||||
*MulticastAddress is not a valid multicast
|
||||
address.
|
||||
@retval EFI_ALREADY_STARTED The group address is already in the group table
|
||||
(when JoinFlag is TRUE).
|
||||
@retval EFI_NOT_FOUND The group address is not in the group table (when
|
||||
JoinFlag is FALSE).
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Groups (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN BOOLEAN JoinFlag,
|
||||
IN EFI_IPv4_ADDRESS *MulticastAddress OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
EFI_IP4_PROTOCOL *Ip;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) ||
|
||||
(JoinFlag && (MulticastAddress == NULL)) ||
|
||||
(JoinFlag && !IP4_IS_MULTICAST (EFI_NTOHL (*MulticastAddress)))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = UDP4_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Instance->IsNoMapping) {
|
||||
return EFI_NO_MAPPING;
|
||||
}
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
Ip = Instance->IpInfo->Ip;
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
//
|
||||
// Invoke the Ip instance the Udp4 instance consumes to do the group operation.
|
||||
//
|
||||
Status = Ip->Groups (Ip, JoinFlag, MulticastAddress);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Keep a local copy of the configured multicast IPs because IpIo receives
|
||||
// datagrams from the 0 station address IP instance and then UDP delivers to
|
||||
// the matched instance. This copy of multicast IPs is used to avoid receive
|
||||
// the mutlicast datagrams destinated to multicast IPs the other instances configured.
|
||||
//
|
||||
if (JoinFlag) {
|
||||
|
||||
NetMapInsertTail (
|
||||
&Instance->McastIps,
|
||||
(VOID *) (UINTN) EFI_IP4 (*MulticastAddress),
|
||||
NULL
|
||||
);
|
||||
} else {
|
||||
|
||||
NetMapIterate (&Instance->McastIps, Udp4LeaveGroup, MulticastAddress);
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function adds a route to or deletes a route from the routing table.
|
||||
|
||||
@param This Pointer to the EFI_UDP4_PROTOCOL instance.
|
||||
@param DeleteRoute Set to TRUE to delete this route from the routing
|
||||
table. Set to FALSE to add this route to the
|
||||
routing table.
|
||||
@param SubnetAddress The destination network address that needs to be
|
||||
routed.
|
||||
@param SubnetMask The subnet mask of SubnetAddress.
|
||||
@param GatewayAddress The gateway IP address for this route.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_NOT_STARTED The EFI UDPv4 Protocol instance has not been
|
||||
started.
|
||||
@retval EFI_NO_MAPPING When using a default address, configuration (DHCP,
|
||||
BOOTP, RARP, etc.) is not finished yet.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. SubnetAddress is NULL. SubnetMask is
|
||||
NULL. GatewayAddress is NULL. SubnetAddress is not
|
||||
a valid subnet address. SubnetMask is not a valid
|
||||
subnet mask. GatewayAddress is not a valid unicast
|
||||
IP address.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table.
|
||||
@retval EFI_NOT_FOUND This route is not in the routing table.
|
||||
@retval EFI_ACCESS_DENIED The route is already defined in the routing table.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Routes (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN BOOLEAN DeleteRoute,
|
||||
IN EFI_IPv4_ADDRESS *SubnetAddress,
|
||||
IN EFI_IPv4_ADDRESS *SubnetMask,
|
||||
IN EFI_IPv4_ADDRESS *GatewayAddress
|
||||
)
|
||||
{
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
EFI_IP4_PROTOCOL *Ip;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = UDP4_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Instance->IsNoMapping) {
|
||||
return EFI_NO_MAPPING;
|
||||
}
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
Ip = Instance->IpInfo->Ip;
|
||||
|
||||
//
|
||||
// Invoke the Ip instance the Udp4 instance consumes to do the actual operation.
|
||||
//
|
||||
return Ip->Routes (Ip, DeleteRoute, SubnetAddress, SubnetMask, GatewayAddress);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function places a sending request to this instance of the EFI UDPv4 Protocol,
|
||||
alongside the transmit data that was filled by the user.
|
||||
|
||||
@param This Pointer to the EFI_UDP4_PROTOCOL instance.
|
||||
@param Token Pointer to the completion token that will be
|
||||
placed into the transmit queue.
|
||||
|
||||
@retval EFI_SUCCESS The data has been queued for transmission.
|
||||
@retval EFI_NOT_STARTED This EFI UDPv4 Protocol instance has not been
|
||||
started.
|
||||
@retval EFI_NO_MAPPING When using a default address, configuration (DHCP,
|
||||
BOOTP, RARP, etc.) is not finished yet.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following are TRUE: This is
|
||||
NULL. Token is NULL. Token.Event is NULL.
|
||||
Token.Packet.TxData is NULL.
|
||||
Token.Packet.TxData.FragmentCount is zero.
|
||||
Token.Packet.TxData.DataLength is not equal to the
|
||||
sum of fragment lengths. One or more of the
|
||||
Token.Packet.TxData.FragmentTable[].
|
||||
FragmentLength fields is zero. One or more of the
|
||||
Token.Packet.TxData.FragmentTable[].
|
||||
FragmentBuffer fields is NULL.
|
||||
Token.Packet.TxData. GatewayAddress is not a
|
||||
unicast IPv4 address if it is not NULL. One or
|
||||
more IPv4 addresses in Token.Packet.TxData.
|
||||
UdpSessionData are not valid unicast IPv4
|
||||
addresses if the UdpSessionData is not NULL.
|
||||
@retval EFI_ACCESS_DENIED The transmit completion token with the same
|
||||
Token.Event is already in the transmit queue.
|
||||
@retval EFI_NOT_READY The completion token could not be queued because
|
||||
the transmit queue is full.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not queue the transmit data.
|
||||
@retval EFI_NOT_FOUND There is no route to the destination network or
|
||||
address.
|
||||
@retval EFI_BAD_BUFFER_SIZE The data length is greater than the maximum UDP
|
||||
packet size. Or the length of the IP header + UDP
|
||||
header + data length is greater than MTU if
|
||||
DoNotFragment is TRUE.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Transmit (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN EFI_UDP4_COMPLETION_TOKEN *Token
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
NET_BUF *Packet;
|
||||
EFI_UDP4_HEADER *Udp4Header;
|
||||
EFI_UDP4_CONFIG_DATA *ConfigData;
|
||||
IP4_ADDR Destination;
|
||||
EFI_UDP4_TRANSMIT_DATA *TxData;
|
||||
EFI_UDP4_SESSION_DATA *UdpSessionData;
|
||||
UDP4_SERVICE_DATA *Udp4Service;
|
||||
IP_IO_OVERRIDE Override;
|
||||
UINT16 HeadSum;
|
||||
|
||||
if ((This == NULL) || (Token == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = UDP4_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Instance->IsNoMapping) {
|
||||
return EFI_NO_MAPPING;
|
||||
}
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
//
|
||||
// Validate the Token, if the token is invalid return the error code.
|
||||
//
|
||||
Status = Udp4ValidateTxToken (Instance, Token);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (EFI_ERROR (NetMapIterate (&Instance->TxTokens, Udp4TokenExist, Token)) ||
|
||||
EFI_ERROR (NetMapIterate (&Instance->RxTokens, Udp4TokenExist, Token))) {
|
||||
//
|
||||
// Try to find a duplicate token in the two token maps, if found, return
|
||||
// EFI_ACCESS_DENIED.
|
||||
//
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
TxData = Token->Packet.TxData;
|
||||
|
||||
//
|
||||
// Create a net buffer to hold the user buffer and the udp header.
|
||||
//
|
||||
Packet = NetbufFromExt (
|
||||
(NET_FRAGMENT *)TxData->FragmentTable,
|
||||
TxData->FragmentCount,
|
||||
UDP4_HEADER_SIZE,
|
||||
0,
|
||||
Udp4NetVectorExtFree,
|
||||
NULL
|
||||
);
|
||||
if (Packet == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Store the IpIo in ProtoData.
|
||||
//
|
||||
Udp4Service = Instance->Udp4Service;
|
||||
*((UINTN *) &Packet->ProtoData[0]) = (UINTN) (Udp4Service->IpIo);
|
||||
|
||||
Udp4Header = (EFI_UDP4_HEADER *) NetbufAllocSpace (Packet, UDP4_HEADER_SIZE, TRUE);
|
||||
ConfigData = &Instance->ConfigData;
|
||||
|
||||
//
|
||||
// Fill the udp header.
|
||||
//
|
||||
Udp4Header->SrcPort = HTONS (ConfigData->StationPort);
|
||||
Udp4Header->DstPort = HTONS (ConfigData->RemotePort);
|
||||
Udp4Header->Length = HTONS (Packet->TotalSize);
|
||||
Udp4Header->Checksum = 0;
|
||||
|
||||
UdpSessionData = TxData->UdpSessionData;
|
||||
Override.SourceAddress = ConfigData->StationAddress;
|
||||
|
||||
if (UdpSessionData != NULL) {
|
||||
//
|
||||
// Set the SourceAddress, SrcPort and Destination according to the specified
|
||||
// UdpSessionData.
|
||||
//
|
||||
if (EFI_IP4 (UdpSessionData->SourceAddress) != 0) {
|
||||
Override.SourceAddress = UdpSessionData->SourceAddress;
|
||||
}
|
||||
|
||||
if (UdpSessionData->SourcePort != 0) {
|
||||
Udp4Header->SrcPort = HTONS (UdpSessionData->SourcePort);
|
||||
}
|
||||
|
||||
Destination = EFI_IP4 (UdpSessionData->DestinationAddress);
|
||||
|
||||
if (UdpSessionData->DestinationPort != 0) {
|
||||
Udp4Header->DstPort = HTONS (UdpSessionData->DestinationPort);
|
||||
}
|
||||
|
||||
//
|
||||
// calculate the pseudo head checksum using the overridden parameters.
|
||||
//
|
||||
HeadSum = NetPseudoHeadChecksum (
|
||||
EFI_IP4 (Override.SourceAddress),
|
||||
Destination,
|
||||
EFI_IP_PROTO_UDP,
|
||||
0
|
||||
);
|
||||
} else {
|
||||
//
|
||||
// UdpSessionData is NULL, use the address and port information previously configured.
|
||||
//
|
||||
Destination = EFI_IP4 (ConfigData->RemoteAddress);
|
||||
HeadSum = Instance->HeadSum;
|
||||
}
|
||||
|
||||
//
|
||||
// calculate the checksum.
|
||||
//
|
||||
Udp4Header->Checksum = Udp4Checksum (Packet, HeadSum);
|
||||
if (Udp4Header->Checksum == 0) {
|
||||
//
|
||||
// If the calculated checksum is 0, fill the Checksum field with all ones.
|
||||
//
|
||||
Udp4Header->Checksum = 0xffff;
|
||||
}
|
||||
|
||||
//
|
||||
// Fill the IpIo Override data.
|
||||
//
|
||||
EFI_IP4 (Override.GatewayAddress) = (TxData->GatewayAddress != NULL) ?
|
||||
EFI_IP4 (*(TxData->GatewayAddress)) : 0;
|
||||
Override.Protocol = EFI_IP_PROTO_UDP;
|
||||
Override.TypeOfService = ConfigData->TypeOfService;
|
||||
Override.TimeToLive = ConfigData->TimeToLive;
|
||||
Override.DoNotFragment = ConfigData->DoNotFragment;
|
||||
|
||||
//
|
||||
// Save the token into the TxToken map.
|
||||
//
|
||||
Status = NetMapInsertTail (&Instance->TxTokens, Token, Packet);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto FREE_PACKET;
|
||||
}
|
||||
|
||||
//
|
||||
// Send out this datagram through IpIo.
|
||||
//
|
||||
Status = IpIoSend (
|
||||
Udp4Service->IpIo,
|
||||
Packet,
|
||||
Instance->IpInfo,
|
||||
Instance,
|
||||
Token,
|
||||
Destination,
|
||||
&Override
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Remove this token from the TxTokens.
|
||||
//
|
||||
Udp4RemoveToken (&Instance->TxTokens, Token);
|
||||
}
|
||||
|
||||
FREE_PACKET:
|
||||
|
||||
NetbufFree (Packet);
|
||||
|
||||
ON_EXIT:
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function places a completion token into the receive packet queue. This function
|
||||
is always asynchronous.
|
||||
|
||||
@param This Pointer to the EFI_UDP4_PROTOCOL instance.
|
||||
@param Token Pointer to a token that is associated with the
|
||||
receive data descriptor.
|
||||
|
||||
@retval EFI_SUCCESS The receive completion token is cached.
|
||||
@retval EFI_NOT_STARTED This EFI UDPv4 Protocol instance has not been
|
||||
started.
|
||||
@retval EFI_NO_MAPPING When using a default address, configuration (DHCP,
|
||||
BOOTP, RARP, etc.) is not finished yet.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. Token is NULL. Token.Event is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued
|
||||
due to a lack of system resources (usually
|
||||
memory).
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
The EFI UDPv4 Protocol instance has been reset to
|
||||
startup defaults.
|
||||
@retval EFI_ACCESS_DENIED A receive completion token with the same
|
||||
Token.Event is already in the receive queue.
|
||||
@retval EFI_NOT_READY The receive request could not be queued because
|
||||
the receive queue is full.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Receive (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN EFI_UDP4_COMPLETION_TOKEN *Token
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (Token == NULL) || (Token->Event == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = UDP4_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Instance->IsNoMapping) {
|
||||
return EFI_NO_MAPPING;
|
||||
}
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
if (EFI_ERROR (NetMapIterate (&Instance->RxTokens, Udp4TokenExist, Token))||
|
||||
EFI_ERROR (NetMapIterate (&Instance->TxTokens, Udp4TokenExist, Token))) {
|
||||
//
|
||||
// Return EFI_ACCESS_DENIED if the specified token is already in the TxTokens or
|
||||
// RxTokens map.
|
||||
//
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Token->Packet.RxData = NULL;
|
||||
|
||||
//
|
||||
// Save the token into the RxTokens map.
|
||||
//
|
||||
Status = NetMapInsertTail (&Instance->RxTokens, Token, NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
|
||||
//
|
||||
// If there is an icmp error, report it.
|
||||
//
|
||||
Udp4ReportIcmpError (Instance);
|
||||
|
||||
//
|
||||
// Try to delivered the received datagrams.
|
||||
//
|
||||
Udp4InstanceDeliverDgram (Instance);
|
||||
|
||||
ON_EXIT:
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function is used to abort a pending transmit or receive request.
|
||||
|
||||
@param This Pointer to the EFI_UDP4_PROTOCOL instance.
|
||||
@param Token Pointer to a token that has been issued by
|
||||
EFI_UDP4_PROTOCOL.Transmit() or
|
||||
EFI_UDP4_PROTOCOL.Receive().
|
||||
|
||||
@retval EFI_SUCCESS The asynchronous I/O request is aborted and
|
||||
Token.Event is signaled. When Token is NULL, all
|
||||
pending requests are aborted and their events are
|
||||
signaled.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_STARTED This instance has not been started.
|
||||
@retval EFI_NO_MAPPING When using the default address, configuration
|
||||
(DHCP, BOOTP, RARP, etc.) is not finished yet.
|
||||
@retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O
|
||||
request is not found in the transmit or receive
|
||||
queue. It is either completed or not issued by
|
||||
Transmit() or Receive().
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Cancel (
|
||||
IN EFI_UDP4_PROTOCOL *This,
|
||||
IN EFI_UDP4_COMPLETION_TOKEN *Token OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = UDP4_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Instance->IsNoMapping) {
|
||||
return EFI_NO_MAPPING;
|
||||
}
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
//
|
||||
// Cancle the tokens specified by Token for this instance.
|
||||
//
|
||||
Status = Udp4InstanceCancelToken (Instance, Token);
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function can be used by network drivers and applications to increase the rate that
|
||||
data packets are moved between the communications device and the transmit/receive queues.
|
||||
Argumens:
|
||||
This - Pointer to the EFI_UDP4_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS Incoming or outgoing data was processed.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
@retval EFI_TIMEOUT Data was dropped out of the transmit and/or
|
||||
receive queue.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Udp4Poll (
|
||||
IN EFI_UDP4_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
UDP4_INSTANCE_DATA *Instance;
|
||||
EFI_IP4_PROTOCOL *Ip;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = UDP4_INSTANCE_DATA_FROM_THIS (This);
|
||||
Ip = Instance->IpInfo->Ip;
|
||||
|
||||
//
|
||||
// Invode the Ip instance consumed by the udp instance to do the poll operation.
|
||||
//
|
||||
return Ip->Poll (Ip);
|
||||
}
|
Loading…
Reference in New Issue