From 36ee91ca3661d3d020a7841aacbf858d885c4728 Mon Sep 17 00:00:00 2001 From: vanjeff Date: Tue, 20 Nov 2007 05:42:23 +0000 Subject: [PATCH] 1. Add DPC protocol and DpcLib library in MdeModulePkg. 2. Add DpcDxe module and DxeDpcLib module in MdeModulePkg 3. Port network stack module to use DPC. 4. Use MIN, and MAX defined in MdePkg to replace NET_MIN and NET_MAX. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4307 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Include/Library/DpcLib.h | 65 +++ MdeModulePkg/Include/Library/NetLib.h | 526 +++++++++--------- MdeModulePkg/Include/Protocol/Dpc.h | 111 ++++ MdeModulePkg/Library/DxeDpcLib/DpcLib.c | 104 ++++ MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf | 46 ++ MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c | 109 +++- MdeModulePkg/Library/DxeNetLib/DxeNetLib.c | 72 ++- MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf | 3 +- .../Library/DxeUdpIoLib/DxeUdpIoLib.c | 117 +++- MdeModulePkg/MdeModulePkg.dec | 12 +- MdeModulePkg/MdeModulePkg.dsc | 5 +- .../Universal/Network/ArpDxe/ArpDriver.c | 24 +- .../Universal/Network/ArpDxe/ArpImpl.c | 83 ++- .../Universal/Network/ArpDxe/ArpImpl.h | 14 +- .../Universal/Network/ArpDxe/ArpMain.c | 71 ++- .../Universal/Network/Dhcp4Dxe/Dhcp4Impl.c | 8 +- .../Universal/Network/Dhcp4Dxe/Dhcp4Io.c | 2 +- .../Universal/Network/Dhcp4Dxe/Dhcp4Option.c | 2 +- MdeModulePkg/Universal/Network/DpcDxe/Dpc.c | 352 ++++++++++++ MdeModulePkg/Universal/Network/DpcDxe/Dpc.h | 86 +++ .../Universal/Network/DpcDxe/DpcDxe.inf | 52 ++ .../Network/Ip4ConfigDxe/Ip4Config.c | 2 +- .../Network/Ip4ConfigDxe/NicIp4Variable.h | 4 +- .../Universal/Network/Ip4Dxe/Ip4Driver.c | 4 +- MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c | 165 +++++- .../Universal/Network/Ip4Dxe/Ip4Igmp.c | 2 +- .../Universal/Network/Ip4Dxe/Ip4Impl.c | 75 ++- .../Universal/Network/Ip4Dxe/Ip4Impl.h | 1 + .../Universal/Network/Ip4Dxe/Ip4Input.c | 6 + .../Universal/Network/MnpDxe/MnpConfig.c | 16 +- .../Universal/Network/MnpDxe/MnpImpl.h | 2 +- MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c | 25 +- .../Universal/Network/MnpDxe/MnpMain.c | 13 + .../Network/Mtftp4Dxe/Mtftp4Driver.c | 4 +- .../Universal/Network/Mtftp4Dxe/Mtftp4Impl.c | 18 +- .../Universal/Network/Mtftp4Dxe/Mtftp4Impl.h | 14 +- .../Universal/Network/Tcp4Dxe/SockImpl.c | 8 +- .../Universal/Network/Tcp4Dxe/Tcp4Driver.c | 2 +- .../Universal/Network/Tcp4Dxe/Tcp4Input.c | 14 +- .../Universal/Network/Tcp4Dxe/Tcp4Main.c | 1 + .../Universal/Network/Tcp4Dxe/Tcp4Misc.c | 2 +- .../Universal/Network/Tcp4Dxe/Tcp4Option.c | 3 +- .../Universal/Network/Tcp4Dxe/Tcp4Output.c | 8 +- .../Universal/Network/Tcp4Dxe/Tcp4Timer.c | 28 +- .../Universal/Network/Udp4Dxe/Udp4Impl.c | 38 +- .../Universal/Network/Udp4Dxe/Udp4Impl.h | 4 +- .../Universal/Network/Udp4Dxe/Udp4Main.c | 21 +- Nt32Pkg/Nt32Pkg.dsc | 2 + 48 files changed, 1819 insertions(+), 527 deletions(-) create mode 100644 MdeModulePkg/Include/Library/DpcLib.h create mode 100644 MdeModulePkg/Include/Protocol/Dpc.h create mode 100644 MdeModulePkg/Library/DxeDpcLib/DpcLib.c create mode 100644 MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf create mode 100644 MdeModulePkg/Universal/Network/DpcDxe/Dpc.c create mode 100644 MdeModulePkg/Universal/Network/DpcDxe/Dpc.h create mode 100644 MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf diff --git a/MdeModulePkg/Include/Library/DpcLib.h b/MdeModulePkg/Include/Library/DpcLib.h new file mode 100644 index 0000000000..7771afb680 --- /dev/null +++ b/MdeModulePkg/Include/Library/DpcLib.h @@ -0,0 +1,65 @@ +/** @file + +Copyright (c) 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: + + DpcLib.h + +Abstract: + + Library for Deferred Procedure Calls. + +**/ + +#ifndef _DPC_LIB_H_ +#define _DPC_LIB_H_ + +#include +#include + +/** + Add a Deferred Procedure Call to the end of the DPC queue. + + @param DpcTpl The EFI_TPL that the DPC should be invoked. + @param DpcProcedure Pointer to the DPC's function. + @param DpcContext Pointer to the DPC's context. Passed to DpcProcedure + when DpcProcedure is invoked. + + @retval EFI_SUCCESS The DPC was queued. + @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL. + @retval EFI_INVALID_PARAMETER DpcProcedure is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + add the DPC to the queue. + +**/ +EFI_STATUS +QueueDpc ( + IN EFI_TPL DpcTpl, + IN EFI_DPC_PROCEDURE DpcProcedure, + IN VOID *DpcContext OPTIONAL + ); + +/** + Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl + value greater than or equal to the current TPL are invoked in the order that + they were queued. DPCs with higher DpcTpl values are invoked before DPCs with + lower DpcTpl values. + + @retval EFI_SUCCESS One or more DPCs were invoked. + @retval EFI_NOT_FOUND No DPCs were invoked. + +**/ +EFI_STATUS +DispatchDpc ( + VOID + ); + +#endif diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/Library/NetLib.h index 3a8274198d..c843b6ce79 100644 --- a/MdeModulePkg/Include/Library/NetLib.h +++ b/MdeModulePkg/Include/Library/NetLib.h @@ -28,184 +28,185 @@ Abstract: #include #include #include +#include + +#define EFI_NET_LITTLE_ENDIAN + +typedef UINT32 IP4_ADDR; +typedef UINT32 TCP_SEQNO; +typedef UINT16 TCP_PORTNO; + +enum { + NET_ETHER_ADDR_LEN = 6, + NET_IFTYPE_ETHERNET = 0x01, + + EFI_IP_PROTO_UDP = 0x11, + EFI_IP_PROTO_TCP = 0x06, + EFI_IP_PROTO_ICMP = 0x01, + + // + // The address classfication + // + IP4_ADDR_CLASSA = 1, + IP4_ADDR_CLASSB, + IP4_ADDR_CLASSC, + IP4_ADDR_CLASSD, + IP4_ADDR_CLASSE, + + IP4_MASK_NUM = 33, +}; + +#pragma pack(1) + +// +// Ethernet head definition +// +typedef struct { + UINT8 DstMac [NET_ETHER_ADDR_LEN]; + UINT8 SrcMac [NET_ETHER_ADDR_LEN]; + UINT16 EtherType; +} ETHER_HEAD; + + +// +// The EFI_IP4_HEADER is hard to use because the source and +// destination address are defined as EFI_IPv4_ADDRESS, which +// is a structure. Two structures can't be compared or masked +// directly. This is why there is an internal representation. +// +typedef struct { +#ifdef EFI_NET_LITTLE_ENDIAN + UINT8 HeadLen : 4; + UINT8 Ver : 4; +#else + UINT8 Ver : 4; + UINT8 HeadLen : 4; +#endif + UINT8 Tos; + UINT16 TotalLen; + UINT16 Id; + UINT16 Fragment; + UINT8 Ttl; + UINT8 Protocol; + UINT16 Checksum; + IP4_ADDR Src; + IP4_ADDR Dst; +} IP4_HEAD; + + +// +// ICMP head definition. ICMP message is categoried as either an error +// message or query message. Two message types have their own head format. +// +typedef struct { + UINT8 Type; + UINT8 Code; + UINT16 Checksum; +} IP4_ICMP_HEAD; + +typedef struct { + IP4_ICMP_HEAD Head; + UINT32 Fourth; // 4th filed of the head, it depends on Type. + IP4_HEAD IpHead; +} IP4_ICMP_ERROR_HEAD; + +typedef struct { + IP4_ICMP_HEAD Head; + UINT16 Id; + UINT16 Seq; +} IP4_ICMP_QUERY_HEAD; + + +// +// UDP header definition +// +typedef struct { + UINT16 SrcPort; + UINT16 DstPort; + UINT16 Length; + UINT16 Checksum; +} EFI_UDP4_HEADER; + + +// +// TCP header definition +// +typedef struct { + TCP_PORTNO SrcPort; + TCP_PORTNO DstPort; + TCP_SEQNO Seq; + TCP_SEQNO Ack; +#ifdef EFI_NET_LITTLE_ENDIAN + UINT8 Res : 4; + UINT8 HeadLen : 4; +#else + UINT8 HeadLen : 4; + UINT8 Res : 4; +#endif + UINT8 Flag; + UINT16 Wnd; + UINT16 Checksum; + UINT16 Urg; +} TCP_HEAD; + +#pragma pack() + +#define NET_MAC_EQUAL(pMac1, pMac2, Len) \ + (NetCompareMem ((pMac1), (pMac2), Len) == 0) + +#define NET_MAC_IS_MULTICAST(Mac, BMac, Len) \ + (((*((UINT8 *) Mac) & 0x01) == 0x01) && (!NET_MAC_EQUAL (Mac, BMac, Len))) + +#ifdef EFI_NET_LITTLE_ENDIAN +#define NTOHL(x) (UINT32)((((UINT32) (x) & 0xff) << 24) | \ + (((UINT32) (x) & 0xff00) << 8) | \ + (((UINT32) (x) & 0xff0000) >> 8) | \ + (((UINT32) (x) & 0xff000000) >> 24)) + +#define HTONL(x) NTOHL(x) + +#define NTOHS(x) (UINT16)((((UINT16) (x) & 0xff) << 8) | \ + (((UINT16) (x) & 0xff00) >> 8)) + +#define HTONS(x) NTOHS(x) +#else +#define NTOHL(x) (UINT32)(x) +#define HTONL(x) (UINT32)(x) +#define NTOHS(x) (UINT16)(x) +#define HTONS(x) (UINT16)(x) +#endif + +// +// Test the IP's attribute, All the IPs are in host byte order. +// +#define IP4_IS_MULTICAST(Ip) (((Ip) & 0xF0000000) == 0xE0000000) +#define IP4_IS_LOCAL_BROADCAST(Ip) ((Ip) == 0xFFFFFFFF) +#define IP4_NET_EQUAL(Ip1, Ip2, NetMask) (((Ip1) & (NetMask)) == ((Ip2) & (NetMask))) +#define IP4_IS_VALID_NETMASK(Ip) (NetGetMaskLength (Ip) != IP4_MASK_NUM) + +// +// Convert the EFI_IP4_ADDRESS to plain UINT32 IP4 address. +// +#define EFI_IP4(EfiIpAddr) (*(IP4_ADDR *) ((EfiIpAddr).Addr)) +#define EFI_NTOHL(EfiIp) (NTOHL (EFI_IP4 ((EfiIp)))) +#define EFI_IP4_EQUAL(Ip1, Ip2) (NetCompareMem ((Ip1), (Ip2), sizeof (EFI_IPv4_ADDRESS)) == 0) + +INTN +NetGetMaskLength ( + IN IP4_ADDR Mask + ); + +INTN +NetGetIpClass ( + IN IP4_ADDR Addr + ); + +BOOLEAN +Ip4IsUnicast ( + IN IP4_ADDR Ip, + IN IP4_ADDR NetMask + ); -#define EFI_NET_LITTLE_ENDIAN - -typedef UINT32 IP4_ADDR; -typedef UINT32 TCP_SEQNO; -typedef UINT16 TCP_PORTNO; - -enum { - NET_ETHER_ADDR_LEN = 6, - NET_IFTYPE_ETHERNET = 0x01, - - EFI_IP_PROTO_UDP = 0x11, - EFI_IP_PROTO_TCP = 0x06, - EFI_IP_PROTO_ICMP = 0x01, - - // - // The address classfication - // - IP4_ADDR_CLASSA = 1, - IP4_ADDR_CLASSB, - IP4_ADDR_CLASSC, - IP4_ADDR_CLASSD, - IP4_ADDR_CLASSE, - - IP4_MASK_NUM = 33, -}; - -#pragma pack(1) - -// -// Ethernet head definition -// -typedef struct { - UINT8 DstMac [NET_ETHER_ADDR_LEN]; - UINT8 SrcMac [NET_ETHER_ADDR_LEN]; - UINT16 EtherType; -} ETHER_HEAD; - - -// -// The EFI_IP4_HEADER is hard to use because the source and -// destination address are defined as EFI_IPv4_ADDRESS, which -// is a structure. Two structures can't be compared or masked -// directly. This is why there is an internal representation. -// -typedef struct { -#ifdef EFI_NET_LITTLE_ENDIAN - UINT8 HeadLen : 4; - UINT8 Ver : 4; -#else - UINT8 Ver : 4; - UINT8 HeadLen : 4; -#endif - UINT8 Tos; - UINT16 TotalLen; - UINT16 Id; - UINT16 Fragment; - UINT8 Ttl; - UINT8 Protocol; - UINT16 Checksum; - IP4_ADDR Src; - IP4_ADDR Dst; -} IP4_HEAD; - - -// -// ICMP head definition. ICMP message is categoried as either an error -// message or query message. Two message types have their own head format. -// -typedef struct { - UINT8 Type; - UINT8 Code; - UINT16 Checksum; -} IP4_ICMP_HEAD; - -typedef struct { - IP4_ICMP_HEAD Head; - UINT32 Fourth; // 4th filed of the head, it depends on Type. - IP4_HEAD IpHead; -} IP4_ICMP_ERROR_HEAD; - -typedef struct { - IP4_ICMP_HEAD Head; - UINT16 Id; - UINT16 Seq; -} IP4_ICMP_QUERY_HEAD; - - -// -// UDP header definition -// -typedef struct { - UINT16 SrcPort; - UINT16 DstPort; - UINT16 Length; - UINT16 Checksum; -} EFI_UDP4_HEADER; - - -// -// TCP header definition -// -typedef struct { - TCP_PORTNO SrcPort; - TCP_PORTNO DstPort; - TCP_SEQNO Seq; - TCP_SEQNO Ack; -#ifdef EFI_NET_LITTLE_ENDIAN - UINT8 Res : 4; - UINT8 HeadLen : 4; -#else - UINT8 HeadLen : 4; - UINT8 Res : 4; -#endif - UINT8 Flag; - UINT16 Wnd; - UINT16 Checksum; - UINT16 Urg; -} TCP_HEAD; - -#pragma pack() - -#define NET_MAC_EQUAL(pMac1, pMac2, Len) \ - (NetCompareMem ((pMac1), (pMac2), Len) == 0) - -#define NET_MAC_IS_MULTICAST(Mac, BMac, Len) \ - (((*((UINT8 *) Mac) & 0x01) == 0x01) && (!NET_MAC_EQUAL (Mac, BMac, Len))) - -#ifdef EFI_NET_LITTLE_ENDIAN -#define NTOHL(x) (UINT32)((((UINT32) (x) & 0xff) << 24) | \ - (((UINT32) (x) & 0xff00) << 8) | \ - (((UINT32) (x) & 0xff0000) >> 8) | \ - (((UINT32) (x) & 0xff000000) >> 24)) - -#define HTONL(x) NTOHL(x) - -#define NTOHS(x) (UINT16)((((UINT16) (x) & 0xff) << 8) | \ - (((UINT16) (x) & 0xff00) >> 8)) - -#define HTONS(x) NTOHS(x) -#else -#define NTOHL(x) (UINT32)(x) -#define HTONL(x) (UINT32)(x) -#define NTOHS(x) (UINT16)(x) -#define HTONS(x) (UINT16)(x) -#endif - -// -// Test the IP's attribute, All the IPs are in host byte order. -// -#define IP4_IS_MULTICAST(Ip) (((Ip) & 0xF0000000) == 0xE0000000) -#define IP4_IS_LOCAL_BROADCAST(Ip) ((Ip) == 0xFFFFFFFF) -#define IP4_NET_EQUAL(Ip1, Ip2, NetMask) (((Ip1) & (NetMask)) == ((Ip2) & (NetMask))) -#define IP4_IS_VALID_NETMASK(Ip) (NetGetMaskLength (Ip) != IP4_MASK_NUM) - -// -// Convert the EFI_IP4_ADDRESS to plain UINT32 IP4 address. -// -#define EFI_IP4(EfiIpAddr) (*(IP4_ADDR *) ((EfiIpAddr).Addr)) -#define EFI_NTOHL(EfiIp) (NTOHL (EFI_IP4 ((EfiIp)))) -#define EFI_IP4_EQUAL(Ip1, Ip2) (NetCompareMem ((Ip1), (Ip2), sizeof (EFI_IPv4_ADDRESS)) == 0) - -INTN -NetGetMaskLength ( - IN IP4_ADDR Mask - ); - -INTN -NetGetIpClass ( - IN IP4_ADDR Addr - ); - -BOOLEAN -Ip4IsUnicast ( - IN IP4_ADDR Ip, - IN IP4_ADDR NetMask - ); - extern IP4_ADDR mIp4AllMasks [IP4_MASK_NUM]; @@ -228,16 +229,13 @@ extern EFI_IPv4_ADDRESS mZeroIp4Addr; // to the standard EFI enviornment. It will NOT consider multiprocessor. // #define NET_TPL_LOCK TPL_CALLBACK -#define NET_TPL_RECYCLE_LOCK (NET_TPL_LOCK + 1) -#define NET_TPL_EVENT TPL_CALLBACK -#define NET_TPL_RECYCLE (NET_TPL_LOCK + 1) -#define NET_TPL_SLOW_TIMER (TPL_CALLBACK - 1) -#define NET_TPL_FAST_TIMER NET_TPL_RECYCLE -#define NET_TPL_TIMER TPL_CALLBACK +#define NET_TPL_EVENT TPL_NOTIFY +#define NET_TPL_RECYCLE TPL_NOTIFY +#define NET_TPL_TIMER NET_TPL_LOCK #define NET_LOCK EFI_LOCK #define NET_LOCK_INIT(x) EfiInitializeLock (x, NET_TPL_LOCK) -#define NET_RECYCLE_LOCK_INIT(x) EfiInitializeLock (x, NET_TPL_RECYCLE_LOCK) +#define NET_RECYCLE_LOCK_INIT(x) EfiInitializeLock (x, NET_TPL_RECYCLE) #define NET_TRYLOCK(x) EfiAcquireLockOrFail (x) #define NET_UNLOCK(x) EfiReleaseLock (x) @@ -247,8 +245,6 @@ extern EFI_IPv4_ADDRESS mZeroIp4Addr; #define TICKS_PER_MS 10000U #define TICKS_PER_SECOND 10000000U -#define NET_MIN(a, b) ((a) < (b) ? (a) : (b)) -#define NET_MAX(a, b) ((a) > (b) ? (a) : (b)) #define NET_RANDOM(Seed) ((UINT32) ((UINT32) (Seed) * 1103515245UL + 12345) % 4294967295UL) @@ -475,6 +471,18 @@ NetLibGetNicHandle ( IN EFI_GUID *ProtocolGuid ); +EFI_STATUS +NetLibQueueDpc ( + IN EFI_TPL DpcTpl, + IN EFI_DPC_PROCEDURE DpcProcedure, + IN VOID *DpcContext OPTIONAL + ); + +EFI_STATUS +NetLibDispatchDpc ( + VOID + ); + EFI_STATUS EFIAPI NetLibDefaultUnload ( @@ -793,78 +801,78 @@ NetPseudoHeadChecksum ( 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 +// +// 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 diff --git a/MdeModulePkg/Include/Protocol/Dpc.h b/MdeModulePkg/Include/Protocol/Dpc.h new file mode 100644 index 0000000000..d20c16a629 --- /dev/null +++ b/MdeModulePkg/Include/Protocol/Dpc.h @@ -0,0 +1,111 @@ +/*++ + +Copyright (c) 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: + + Dpc.h + +Abstract: + + EFI Deferred Procedure Call Protocol + +Revision History + +--*/ + + +#ifndef __DPC_H__ +#define __DPC_H__ + +// +// DPC Protocol GUID value +// +#define EFI_DPC_PROTOCOL_GUID \ + { \ + 0x480f8ae9, 0xc46, 0x4aa9, { 0xbc, 0x89, 0xdb, 0x9f, 0xba, 0x61, 0x98, 0x6 } \ + } + +// +// Forward reference for pure ANSI compatability +// +typedef struct _EFI_DPC_PROTOCOL EFI_DPC_PROTOCOL; + + +/** + Invoke a Deferred Procedure Call. + + @param DpcContext Pointer to the Deferred Procedure Call's context, + which is implementation dependent. + +**/ +typedef +VOID +(EFIAPI *EFI_DPC_PROCEDURE) ( + IN VOID *DpcContext + ); + +/** + Add a Deferred Procedure Call to the end of the DPC queue. + + @param This Protocol instance pointer. + @param DpcTpl The EFI_TPL that the DPC should be invoked. + @param DpcProcedure Pointer to the DPC's function. + @param DpcContext Pointer to the DPC's context. Passed to DpcProcedure + when DpcProcedure is invoked. + + @retval EFI_SUCCESS The DPC was queued. + @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL. + @retval EFI_INVALID_PARAMETER DpcProcedure is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + add the DPC to the queue. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DPC_QUEUE_DPC) ( + IN EFI_DPC_PROTOCOL *This, + IN EFI_TPL DpcTpl, + IN EFI_DPC_PROCEDURE DpcProcedure, + IN VOID *DpcContext OPTIONAL + ); + +/** + Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl + value greater than or equal to the current TPL are invoked in the order that + they were queued. DPCs with higher DpcTpl values are invoked before DPCs with + lower DpcTpl values. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS One or more DPCs were invoked. + @retval EFI_NOT_FOUND No DPCs were invoked. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_DPC_DISPATCH_DPC) ( + IN EFI_DPC_PROTOCOL *This + ); + +// +// DPC Protocol structure +// +typedef struct _EFI_DPC_PROTOCOL { + EFI_DPC_QUEUE_DPC QueueDpc; + EFI_DPC_DISPATCH_DPC DispatchDpc; +}; + +// +// DPC Protocol GUID variable +// +extern EFI_GUID gEfiDpcProtocolGuid; + +#endif diff --git a/MdeModulePkg/Library/DxeDpcLib/DpcLib.c b/MdeModulePkg/Library/DxeDpcLib/DpcLib.c new file mode 100644 index 0000000000..bc834f7a3e --- /dev/null +++ b/MdeModulePkg/Library/DxeDpcLib/DpcLib.c @@ -0,0 +1,104 @@ +/** @file + +Copyright (c) 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: + + DpcLib.c + +Abstract: + +**/ + +#include +#include +#include +#include + +// +// Pointer to the DPC Protocol +// +EFI_DPC_PROTOCOL *mDpc; + +/** + This constructor function caches the EFI_DPC_PROTOCOL pointer. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always return EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +DpcLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Locate the EFI_DPC_PROTOCOL in the handle database + // + Status = gBS->LocateProtocol (&gEfiDpcProtocolGuid, NULL, (VOID **)&mDpc); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +/** + Add a Deferred Procedure Call to the end of the DPC queue. + + @param DpcTpl The EFI_TPL that the DPC should be invoked. + @param DpcProcedure Pointer to the DPC's function. + @param DpcContext Pointer to the DPC's context. Passed to DpcProcedure + when DpcProcedure is invoked. + + @retval EFI_SUCCESS The DPC was queued. + @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL. + @retval EFI_INVALID_PARAMETER DpcProcedure is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + add the DPC to the queue. + +**/ +EFI_STATUS +QueueDpc ( + IN EFI_TPL DpcTpl, + IN EFI_DPC_PROCEDURE DpcProcedure, + IN VOID *DpcContext + ) +{ + // + // Call the EFI_DPC_PROTOCOL to queue the DPC + // + return mDpc->QueueDpc (mDpc, DpcTpl, DpcProcedure, DpcContext); +} + +/** + Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl + value greater than or equal to the current TPL are invoked in the order that + they were queued. DPCs with higher DpcTpl values are invoked before DPCs with + lower DpcTpl values. + + @retval EFI_SUCCESS One or more DPCs were invoked. + @retval EFI_NOT_FOUND No DPCs were invoked. + +**/ +EFI_STATUS +DispatchDpc ( + VOID + ) +{ + // + // Call the EFI_DPC_PROTOCOL to dispatch previously queued DPCs + // + return mDpc->DispatchDpc (mDpc); +} diff --git a/MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf b/MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf new file mode 100644 index 0000000000..9268837ffe --- /dev/null +++ b/MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf @@ -0,0 +1,46 @@ +#/** @file +# Component name for module DxeDpcLib +# +# Copyright (c) 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. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeDpcLib + FILE_GUID = 38897D86-FF36-4472-AE64-1DB9AE715C81 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = DpcLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + CONSTRUCTOR = DpcLibConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + DpcLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + DebugLib + UefiBootServicesTableLib + +[Protocols] + gEfiDpcProtocolGuid # PROTOCOL ALWAYS_CONSUMED diff --git a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c index 608bdd297e..279ada7b11 100644 --- a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c +++ b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c @@ -71,6 +71,13 @@ STATIC ICMP_ERROR_INFO mIcmpErrMap[10] = { {FALSE, TRUE} }; +STATIC +VOID +EFIAPI +IpIoTransmitHandlerDpc ( + IN VOID *Context + ); + STATIC VOID EFIAPI @@ -430,7 +437,7 @@ IpIoCreateSndEntry ( // // Set the fields of OverrideData // - NetCopyMem (OverrideData, Override, sizeof (*OverrideData)); + CopyMem (OverrideData, Override, sizeof (*OverrideData)); } // @@ -523,7 +530,6 @@ IpIoDestroySndEntry ( /** Notify function for IP transmit token. - @param Event The event signaled. @param Context The context passed in by the event notifier. @return None. @@ -532,8 +538,7 @@ IpIoDestroySndEntry ( STATIC VOID EFIAPI -IpIoTransmitHandler ( - IN EFI_EVENT Event, +IpIoTransmitHandlerDpc ( IN VOID *Context ) { @@ -556,11 +561,34 @@ IpIoTransmitHandler ( IpIoDestroySndEntry (SndEntry); } +/** + Notify function for IP transmit token. + + @param Event The event signaled. + @param Context The context passed in by the event notifier. + + @return None. + +**/ + +STATIC +VOID +EFIAPI +IpIoTransmitHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Request IpIoTransmitHandlerDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, IpIoTransmitHandlerDpc, Context); +} + /** The dummy handler for the dummy IP receive token. - @param Evt The event signaled. @param Context The context passed in by the event notifier. @return None. @@ -569,20 +597,22 @@ IpIoTransmitHandler ( STATIC VOID EFIAPI -IpIoDummyHandler ( - IN EFI_EVENT Event, +IpIoDummyHandlerDpc ( IN VOID *Context ) { IP_IO_IP_INFO *IpInfo; EFI_IP4_COMPLETION_TOKEN *DummyToken; - ASSERT (Event && Context); - IpInfo = (IP_IO_IP_INFO *) Context; DummyToken = &(IpInfo->DummyRcvToken); - if (EFI_SUCCESS == DummyToken->Status) { + if (EFI_ABORTED == DummyToken->Status) { + // + // The reception is actively aborted by the consumer, directly return. + // + return; + } else if (EFI_SUCCESS == DummyToken->Status) { ASSERT (DummyToken->Packet.RxData); gBS->SignalEvent (DummyToken->Packet.RxData->RecycleSignal); @@ -593,8 +623,7 @@ IpIoDummyHandler ( /** - Notify function for the IP receive token, used to process - the received IP packets. + Request IpIoDummyHandlerDpc as a DPC at TPL_CALLBACK. @param Event The event signaled. @param Context The context passed in by the event notifier. @@ -605,10 +634,33 @@ IpIoDummyHandler ( STATIC VOID EFIAPI -IpIoListenHandler ( +IpIoDummyHandler ( IN EFI_EVENT Event, IN VOID *Context ) +{ + // + // Request IpIoDummyHandlerDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, IpIoDummyHandlerDpc, Context); +} + + +/** + Notify function for the IP receive token, used to process + the received IP packets. + + @param Context The context passed in by the event notifier. + + @return None. + +**/ +STATIC +VOID +EFIAPI +IpIoListenHandlerDpc ( + IN VOID *Context + ) { IP_IO *IpIo; EFI_STATUS Status; @@ -623,6 +675,13 @@ IpIoListenHandler ( Status = IpIo->RcvToken.Status; RxData = IpIo->RcvToken.Packet.RxData; + if (EFI_ABORTED == Status) { + // + // The reception is actively aborted by the consumer, directly return. + // + return; + } + if (((EFI_SUCCESS != Status) && (EFI_ICMP_ERROR != Status)) || (NULL == RxData)) { // // Only process the normal packets and the icmp error packets, if RxData is NULL @@ -689,6 +748,30 @@ Resume: } +/** + Request IpIoListenHandlerDpc as a DPC at TPL_CALLBACK + + @param Event The event signaled. + @param Context The context passed in by the event notifier. + + @return None. + +**/ +STATIC +VOID +EFIAPI +IpIoListenHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Request IpIoListenHandlerDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, IpIoListenHandlerDpc, Context); +} + + /** Create a new IP_IO instance. diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c index 0eee6076f7..f65489e7ed 100644 --- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c +++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c @@ -36,6 +36,8 @@ Abstract: #include +EFI_DPC_PROTOCOL *mDpc = NULL; + // // All the supported IP4 maskes in host byte order. // @@ -227,7 +229,7 @@ NetRandomInitSeed ( UINT32 Seed; gRT->GetTime (&Time, NULL); - Seed = (~Time.Hour << 24 | Time.Second << 16 | Time.Minute << 8 | Time.Day); + Seed = (~Time.Hour << 24 | Time.Day << 16 | Time.Minute << 8 | Time.Second); Seed ^= Time.Nanosecond; Seed ^= Time.Year << 7; @@ -1276,3 +1278,71 @@ NetLibGetNicHandle ( return Handle; } +/** + Add a Deferred Procedure Call to the end of the DPC queue. + + @DpcTpl The EFI_TPL that the DPC should be invoked. + @DpcProcedure Pointer to the DPC's function. + @DpcContext Pointer to the DPC's context. Passed to DpcProcedure + when DpcProcedure is invoked. + + @retval EFI_SUCCESS The DPC was queued. + @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL. + DpcProcedure is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + add the DPC to the queue. + +**/ +EFI_STATUS +NetLibQueueDpc ( + IN EFI_TPL DpcTpl, + IN EFI_DPC_PROCEDURE DpcProcedure, + IN VOID *DpcContext OPTIONAL + ) +{ + return mDpc->QueueDpc (mDpc, DpcTpl, DpcProcedure, DpcContext); +} + +/** + Add a Deferred Procedure Call to the end of the DPC queue. + + @retval EFI_SUCCESS One or more DPCs were invoked. + @retval EFI_NOT_FOUND No DPCs were invoked. + +**/ +EFI_STATUS +NetLibDispatchDpc ( + VOID + ) +{ + return mDpc->DispatchDpc(mDpc); +} + + +/** + The constructor function caches the pointer to DPC protocol. + + The constructor function locates DPC protocol from protocol database. + It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +NetLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = gBS->LocateProtocol (&gEfiDpcProtocolGuid, NULL, (VOID**) &mDpc); + ASSERT_EFI_ERROR (Status); + ASSERT (mDpc != NULL); + + return Status; +} diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf index 2bd876e9a0..deb8949924 100644 --- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf +++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf @@ -25,6 +25,7 @@ EDK_RELEASE_VERSION = 0x00020000 EFI_SPECIFICATION_VERSION = 0x00020000 + CONSTRUCTOR = NetLibConstructor # # The following information is for reference only and not required by the build tools. @@ -43,7 +44,6 @@ [LibraryClasses] - NetLib BaseLib DebugLib BaseMemoryLib @@ -55,3 +55,4 @@ [Protocols] gEfiSimpleNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiNicIp4ConfigProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiDpcProtocolGuid # PROTOCOL ALWAYS_CONSUMED diff --git a/MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.c b/MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.c index d56456afb2..b1329f8604 100644 --- a/MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.c +++ b/MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.c @@ -32,6 +32,13 @@ Abstract: #include #include +STATIC +VOID +EFIAPI +UdpIoOnDgramSentDpc ( + IN VOID *Context + ); + STATIC VOID EFIAPI @@ -100,7 +107,7 @@ UdpIoWrapTx ( Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, + NET_TPL_EVENT, UdpIoOnDgramSent, Token, &UdpToken->Event @@ -202,7 +209,7 @@ UdpIoCreateRxToken ( Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, + NET_TPL_EVENT, UdpIoOnDgramRcvd, Token, &Token->UdpToken.Event @@ -364,10 +371,7 @@ UdpIoCancelDgrams ( Token = NET_LIST_USER_STRUCT (Entry, UDP_TX_TOKEN, Link); if ((ToCancel == NULL) || (ToCancel (Token, Context))) { - NetListRemoveEntry (Entry); UdpIo->Udp->Cancel (UdpIo->Udp, &Token->UdpToken); - Token->CallBack (Token->Packet, NULL, IoStatus, Token->Context); - UdpIoFreeTxToken (Token); } } } @@ -400,9 +404,7 @@ UdpIoFreePort ( UdpIoCancelDgrams (UdpIo, EFI_ABORTED, NULL, NULL); if ((RxToken = UdpIo->RecvRequest) != NULL) { - UdpIo->RecvRequest = NULL; UdpIo->Udp->Cancel (UdpIo->Udp, &RxToken->UdpToken); - UdpIoFreeRxToken (RxToken); } // @@ -454,9 +456,7 @@ UdpIoCleanPort ( UdpIoCancelDgrams (UdpIo, EFI_ABORTED, NULL, NULL); if ((RxToken = UdpIo->RecvRequest) != NULL) { - UdpIo->RecvRequest = NULL; UdpIo->Udp->Cancel (UdpIo->Udp, &RxToken->UdpToken); - UdpIoFreeRxToken (RxToken); } UdpIo->Udp->Configure (UdpIo->Udp, NULL); @@ -468,7 +468,6 @@ UdpIoCleanPort ( It will remove the packet from the local list then call the packet owner's callback function. - @param Event The event signalled. @param Context The UDP TX Token. @return None @@ -477,8 +476,7 @@ UdpIoCleanPort ( STATIC VOID EFIAPI -UdpIoOnDgramSent ( - IN EFI_EVENT Event, +UdpIoOnDgramSentDpc ( IN VOID *Context ) { @@ -493,6 +491,29 @@ UdpIoOnDgramSent ( UdpIoFreeTxToken (Token); } +/** + Request UdpIoOnDgramSentDpc as a DPC at TPL_CALLBACK. + + @param Event The event signalled. + @param Context The UDP TX Token. + + @return None + +**/ +STATIC +VOID +EFIAPI +UdpIoOnDgramSent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Request UdpIoOnDgramSentDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, UdpIoOnDgramSentDpc, Context); +} + /** Send a packet through the UDP IO port. @@ -529,14 +550,18 @@ UdpIoSendDatagram ( return EFI_OUT_OF_RESOURCES; } + // + // Insert the tx token into SendDatagram list before transmitting it. Remove + // it from the list if the returned status is not EFI_SUCCESS. + // + NetListInsertHead (&UdpIo->SentDatagram, &Token->Link); Status = UdpIo->Udp->Transmit (UdpIo->Udp, &Token->UdpToken); - if (EFI_ERROR (Status)) { + NetListRemoveEntry (&Token->Link); UdpIoFreeTxToken (Token); return Status; } - NetListInsertHead (&UdpIo->SentDatagram, &Token->Link); return EFI_SUCCESS; } @@ -609,13 +634,11 @@ UdpIoRecycleDgram ( UdpIoFreeRxToken (Token); } - /** The event handle for UDP receive request. It will build a NET_BUF from the recieved UDP data, then deliver it to the receiver. - @param Event The UDP receive request event @param Context The UDP RX token. @return None @@ -624,8 +647,7 @@ UdpIoRecycleDgram ( STATIC VOID EFIAPI -UdpIoOnDgramRcvd ( - IN EFI_EVENT Event, +UdpIoOnDgramRcvdDpc ( IN VOID *Context ) { @@ -651,10 +673,15 @@ UdpIoOnDgramRcvd ( UdpRxData = UdpToken->Packet.RxData; if (EFI_ERROR (UdpToken->Status) || (UdpRxData == NULL)) { - Token->CallBack (NULL, NULL, UdpToken->Status, Token->Context); - UdpIoFreeRxToken (Token); + if (UdpToken->Status != EFI_ABORTED) { + // + // Invoke the CallBack only if the reception is not actively aborted. + // + Token->CallBack (NULL, NULL, UdpToken->Status, Token->Context); + } - goto ON_EXIT; + UdpIoFreeRxToken (Token); + return; } // @@ -674,7 +701,7 @@ UdpIoOnDgramRcvd ( Token->CallBack (NULL, NULL, EFI_OUT_OF_RESOURCES, Token->Context); UdpIoFreeRxToken (Token); - goto ON_EXIT; + return; } UdpSession = &UdpRxData->UdpSession; @@ -687,9 +714,45 @@ UdpIoOnDgramRcvd ( Points.RemoteAddr = NTOHL (Points.RemoteAddr); Token->CallBack (Netbuf, &Points, EFI_SUCCESS, Token->Context); +} + +/** + Request UdpIoOnDgramRcvdDpc as a DPC at TPL_CALLBACK. + + @param Event The UDP receive request event. + @param Context The UDP RX token. + + @return None + +**/ +STATIC +VOID +EFIAPI +UdpIoOnDgramRcvd ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + + Request UdpIoOnDgramRcvdDpc as a DPC at TPL_CALLBACK + +Arguments: + + Event - The UDP receive request event + Context - The UDP RX token. + +Returns: -ON_EXIT: - return; + None + +--*/ +{ + // + // Request UdpIoOnDgramRcvdDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, UdpIoOnDgramRcvdDpc, Context); } @@ -729,13 +792,13 @@ UdpIoRecvDatagram ( return EFI_OUT_OF_RESOURCES; } + UdpIo->RecvRequest = Token; Status = UdpIo->Udp->Receive (UdpIo->Udp, &Token->UdpToken); if (EFI_ERROR (Status)) { + UdpIo->RecvRequest = NULL; UdpIoFreeRxToken (Token); - return Status; } - UdpIo->RecvRequest = Token; - return EFI_SUCCESS; + return Status; } diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index a3b8ae6a46..888ac8c3db 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -85,12 +85,12 @@ gEfiTianoDecompressProtocolGuid = { 0xE84CF29C, 0x191F, 0x4EAE, { 0x96, 0xE1, 0xF4, 0x6A, 0xEC, 0xEA, 0xEA, 0x0B }} gEfiCustomizedDecompressProtocolGuid = { 0x9A44198E, 0xA4A2, 0x44E6, { 0x8A, 0x1F, 0x39, 0xBE, 0xFD, 0xAC, 0x89, 0x6F }} - gEfiNicIp4ConfigProtocolGuid = {0xdca3d4d, 0x12da, 0x4728, { 0xbf, 0x7e, 0x86, 0xce, 0xb9, 0x28, 0xd0, 0x67 }} - gEfiNicIp4ConfigVariableGuid = {0xd8944553, 0xc4dd, 0x41f4, { 0x9b, 0x30, 0xe1, 0x39, 0x7c, 0xfb, 0x26, 0x7b }} - - gEfiTcpProtocolGuid = { 0x02b3d5f2, 0xac28, 0x11d3, { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d }} - gEfiPxeDhcp4CallbackProtocolGuid = { 0xc1544c01, 0x92a4, 0x4198, {0x8a, 0x84, 0x77, 0x85, 0x83, 0xc2, 0x36, 0x21 } } - gEfiPxeDhcp4ProtocolGuid = { 0x03c4e624, 0xac28, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x29, 0x3f, 0xc1, 0x4d } } + gEfiNicIp4ConfigProtocolGuid = {0xdca3d4d, 0x12da, 0x4728, { 0xbf, 0x7e, 0x86, 0xce, 0xb9, 0x28, 0xd0, 0x67 }} + gEfiNicIp4ConfigVariableGuid = {0xd8944553, 0xc4dd, 0x41f4, { 0x9b, 0x30, 0xe1, 0x39, 0x7c, 0xfb, 0x26, 0x7b }} + gEfiTcpProtocolGuid = {0x02b3d5f2, 0xac28, 0x11d3, { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d }} + gEfiPxeDhcp4CallbackProtocolGuid = {0xc1544c01, 0x92a4, 0x4198, {0x8a, 0x84, 0x77, 0x85, 0x83, 0xc2, 0x36, 0x21 }} + gEfiPxeDhcp4ProtocolGuid = {0x03c4e624, 0xac28, 0x11d3, { 0x9a, 0x2d, 0x00, 0x90, 0x29, 0x3f, 0xc1, 0x4d }} + gEfiDpcProtocolGuid = {0x480f8ae9, 0xc46, 0x4aa9, { 0xbc, 0x89, 0xdb, 0x9f, 0xba, 0x61, 0x98, 0x6 }} [Ppis.common] gPeiBaseMemoryTestPpiGuid = { 0xB6EC423C, 0x21D2, 0x490D, { 0x85, 0xC6, 0xDD, 0x58, 0x64, 0xEA, 0xA6, 0x74 }} diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 4b8d282a6e..2a8598e517 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -68,6 +68,7 @@ NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf + DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf [LibraryClasses.IA32] @@ -241,12 +242,13 @@ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf } - + MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf MdeModulePkg/Library/EdkDxePrintLib/EdkDxePrintLib.inf + MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf @@ -265,6 +267,7 @@ MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf + MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf MdeModulePkg/Application/HelloWorld/HelloWorld.inf diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c b/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c index 58bc72219c..af2e082576 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c +++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2006, Intel Corporation +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 @@ -177,11 +177,6 @@ ArpCreateService ( goto ERROR_EXIT; } - // - // Init the lock. - // - NET_LOCK_INIT (&ArpService->Lock); - // // Init the lists. // @@ -506,6 +501,7 @@ ArpServiceBindingCreateChild ( ARP_SERVICE_DATA *ArpService; ARP_INSTANCE_DATA *Instance; VOID *Mnp; + EFI_TPL OldTpl; if ((This == NULL) || (ChildHandle == NULL)) { return EFI_INVALID_PARAMETER; @@ -564,11 +560,7 @@ ArpServiceBindingCreateChild ( goto ERROR; } - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - - Status = EFI_ACCESS_DENIED; - goto ERROR; - } + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); // // Insert the instance into children list managed by the arp service context data. @@ -576,7 +568,7 @@ ArpServiceBindingCreateChild ( NetListInsertTail (&ArpService->ChildrenList, &Instance->List); ArpService->ChildrenNumber++; - NET_UNLOCK (&ArpService->Lock); + NET_RESTORE_TPL (OldTpl); ERROR: @@ -633,6 +625,7 @@ ArpServiceBindingDestroyChild ( ARP_SERVICE_DATA *ArpService; ARP_INSTANCE_DATA *Instance; EFI_ARP_PROTOCOL *Arp; + EFI_TPL OldTpl; if ((This == NULL) || (ChildHandle == NULL)) { return EFI_INVALID_PARAMETER; @@ -693,10 +686,7 @@ ArpServiceBindingDestroyChild ( return Status; } - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - Instance->Destroyed = FALSE; - return EFI_ACCESS_DENIED; - } + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); if (Instance->Configured) { // @@ -716,7 +706,7 @@ ArpServiceBindingDestroyChild ( NetListRemoveEntry (&Instance->List); ArpService->ChildrenNumber--; - NET_UNLOCK (&ArpService->Lock); + NET_RESTORE_TPL (OldTpl); NetFreePool (Instance); diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c index 52b6e21652..404e6cc9d6 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c +++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c @@ -66,7 +66,6 @@ ArpInitInstance ( /** Process the Arp packets received from Mnp, the procedure conforms to RFC826. - @param Event The Event this notify function registered to. @param Context Pointer to the context data registerd to the Event. @@ -75,8 +74,7 @@ ArpInitInstance ( **/ VOID EFIAPI -ArpOnFrameRcvd ( - IN EFI_EVENT Event, +ArpOnFrameRcvdDpc ( IN VOID *Context ) { @@ -146,11 +144,6 @@ ArpOnFrameRcvd ( ArpAddress.TargetHwAddr = ArpAddress.SenderProtoAddr + Head->ProtoAddrLen; ArpAddress.TargetProtoAddr = ArpAddress.TargetHwAddr + Head->HwAddrLen; - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - ARP_DEBUG_ERROR (("ArpOnFrameRcvd: Faild to acquire the CacheTableLock.\n")); - goto RECYCLE_RXDATA; - } - SenderAddress[Hardware].Type = Head->HwType; SenderAddress[Hardware].Length = Head->HwAddrLen; SenderAddress[Hardware].AddressPtr = ArpAddress.SenderHwAddr; @@ -172,7 +165,7 @@ ArpOnFrameRcvd ( // This address (either hardware or protocol address, or both) is configured to // be a deny entry, silently skip the normal process. // - goto UNLOCK_EXIT; + goto RECYCLE_RXDATA; } ProtoMatched = FALSE; @@ -211,7 +204,7 @@ ArpOnFrameRcvd ( // // Protocol type unmatchable, skip. // - goto UNLOCK_EXIT; + goto RECYCLE_RXDATA; } // @@ -238,7 +231,7 @@ ArpOnFrameRcvd ( // // This arp packet isn't targeted to us, skip now. // - goto UNLOCK_EXIT; + goto RECYCLE_RXDATA; } if (!MergeFlag) { @@ -259,7 +252,7 @@ ArpOnFrameRcvd ( // CacheEntry = ArpAllocCacheEntry (NULL); if (CacheEntry == NULL) { - goto UNLOCK_EXIT; + goto RECYCLE_RXDATA; } } @@ -295,10 +288,6 @@ ArpOnFrameRcvd ( ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REPLY); } -UNLOCK_EXIT: - - NET_UNLOCK (&ArpService->Lock); - RECYCLE_RXDATA: // @@ -321,9 +310,8 @@ RESTART_RECEIVE: ); } - /** - Process the already sent arp packets. + Queue ArpOnFrameRcvdDpc as a DPC at TPL_CALLBACK. @param Event The Event this notify function registered to. @param Context Pointer to the context data registerd to the @@ -334,10 +322,31 @@ RESTART_RECEIVE: **/ VOID EFIAPI -ArpOnFrameSent ( +ArpOnFrameRcvd ( IN EFI_EVENT Event, IN VOID *Context ) +{ + // + // Request ArpOnFrameRcvdDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, ArpOnFrameRcvdDpc, Context); +} + +/** + Process the already sent arp packets. + + @param Context Pointer to the context data registerd to the + Event. + + @return None. + +**/ +VOID +EFIAPI +ArpOnFrameSentDpc ( + IN VOID *Context + ) { EFI_MANAGED_NETWORK_COMPLETION_TOKEN *TxToken; EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData; @@ -362,6 +371,29 @@ ArpOnFrameSent ( NetFreePool (TxToken); } +/** + Request ArpOnFrameSentDpc as a DPC at TPL_CALLBACK. + + @param Event The Event this notify function registered to. + @param Context Pointer to the context data registerd to the + Event. + + @return None. + +**/ +VOID +EFIAPI +ArpOnFrameSent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Request ArpOnFrameSentDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, ArpOnFrameSentDpc, Context); +} + /** Process the arp cache olding and drive the retrying arp requests. @@ -390,10 +422,6 @@ ArpTimerHandler ( ASSERT (Context != NULL); ArpService = (ARP_SERVICE_DATA *)Context; - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return; - } - // // Iterate all the pending requests to see whether a retry is needed to send out // or the request finally fails because the retry time reaches the limitation. @@ -492,8 +520,6 @@ ArpTimerHandler ( CacheEntry->DecayTime -= ARP_PERIODIC_TIMER_INTERVAL; } } - - NET_UNLOCK (&ArpService->Lock); } @@ -789,6 +815,11 @@ ArpAddressResolved ( } } + // + // Dispatch the DPCs queued by the NotifyFunction of the Context->UserRequestEvent. + // + NetLibDispatchDpc (); + return Count; } @@ -958,7 +989,7 @@ ArpConfigureInstance ( // // Cancel the arp requests issued by this instance. // - ArpCancelRequest (Instance, NULL, NULL); + Instance->ArpProto.Cancel (&Instance->ArpProto, NULL, NULL); // // Free the buffer previously allocated to hold the station address. diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h index 729cb5d68e..1c5e421a04 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h +++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h @@ -125,8 +125,6 @@ struct _ARP_SERVICE_DATA { EFI_SIMPLE_NETWORK_MODE SnpMode; - NET_LOCK Lock; - UINTN ChildrenNumber; NET_LIST_ENTRY ChildrenList; @@ -298,6 +296,12 @@ ArpInitInstance ( IN ARP_INSTANCE_DATA *Instance ); +VOID +EFIAPI +ArpOnFrameRcvdDpc ( + IN VOID *Context + ); + VOID EFIAPI ArpOnFrameRcvd ( @@ -305,6 +309,12 @@ ArpOnFrameRcvd ( IN VOID *Context ); +VOID +EFIAPI +ArpOnFrameSentDpc ( + IN VOID *Context + ); + VOID EFIAPI ArpOnFrameSent ( diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c b/MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c index eb1b082a21..d760f7c018 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c +++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c @@ -51,6 +51,7 @@ ArpConfigure ( { EFI_STATUS Status; ARP_INSTANCE_DATA *Instance; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -65,16 +66,14 @@ ArpConfigure ( Instance = ARP_INSTANCE_DATA_FROM_THIS (This); - if (EFI_ERROR (NET_TRYLOCK (&Instance->ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); // // Configure this instance, the ConfigData has already passed the basic checks. // Status = ArpConfigureInstance (Instance, ConfigData); - NET_UNLOCK (&Instance->ArpService->Lock); + NET_RESTORE_TPL (OldTpl); return Status; } @@ -131,6 +130,7 @@ ArpAdd ( ARP_CACHE_ENTRY *CacheEntry; EFI_SIMPLE_NETWORK_MODE *SnpMode; NET_ARP_ADDRESS MatchAddress[2]; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -166,9 +166,7 @@ ArpAdd ( MatchAddress[Protocol].Length = Instance->ConfigData.SwAddressLength; MatchAddress[Protocol].AddressPtr = TargetSwAddress; - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); // // See whether the entry to add exists. Check the DeinedCacheTable first. @@ -262,7 +260,7 @@ ArpAdd ( UNLOCK_EXIT: - NET_UNLOCK (&ArpService->Lock); + NET_RESTORE_TPL (OldTpl); return Status; } @@ -309,7 +307,7 @@ ArpFind ( { EFI_STATUS Status; ARP_INSTANCE_DATA *Instance; - ARP_SERVICE_DATA *ArpService; + EFI_TPL OldTpl; if ((This == NULL) || (!Refresh && (EntryCount == NULL) && (EntryLength == NULL)) || @@ -318,15 +316,12 @@ ArpFind ( } Instance = ARP_INSTANCE_DATA_FROM_THIS (This); - ArpService = Instance->ArpService; if (!Instance->Configured) { return EFI_NOT_STARTED; } - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); // // All the check passed, find the cache entries now. @@ -341,7 +336,7 @@ ArpFind ( Refresh ); - NET_UNLOCK (&ArpService->Lock); + NET_RESTORE_TPL (OldTpl); return Status; } @@ -373,8 +368,8 @@ ArpDelete ( ) { ARP_INSTANCE_DATA *Instance; - ARP_SERVICE_DATA *ArpService; UINTN Count; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -386,18 +381,14 @@ ArpDelete ( return EFI_NOT_STARTED; } - ArpService = Instance->ArpService; - - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); // // Delete the specified cache entries. // Count = ArpDeleteCacheEntry (Instance, BySwAddress, AddressBuffer, TRUE); - NET_UNLOCK (&ArpService->Lock); + NET_RESTORE_TPL (OldTpl); return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS; } @@ -422,8 +413,8 @@ ArpFlush ( ) { ARP_INSTANCE_DATA *Instance; - ARP_SERVICE_DATA *ArpService; UINTN Count; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -435,18 +426,14 @@ ArpFlush ( return EFI_NOT_STARTED; } - ArpService = Instance->ArpService; - - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); // // Delete the dynamic entries from the cache table. // Count = ArpDeleteCacheEntry (Instance, FALSE, NULL, FALSE); - NET_UNLOCK (&ArpService->Lock); + NET_RESTORE_TPL (OldTpl); return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS; } @@ -491,6 +478,7 @@ ArpRequest ( NET_ARP_ADDRESS HardwareAddress; NET_ARP_ADDRESS ProtocolAddress; USER_REQUEST_CONTEXT *RequestContext; + EFI_TPL OldTpl; if ((This == NULL) || (TargetHwAddress == NULL)) { return EFI_INVALID_PARAMETER; @@ -545,9 +533,7 @@ ArpRequest ( // NetZeroMem (TargetHwAddress, SnpMode->HwAddressSize); - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); // // Check whether the software address is in the denied table. @@ -653,12 +639,17 @@ ArpRequest ( UNLOCK_EXIT: - NET_UNLOCK (&ArpService->Lock); + NET_RESTORE_TPL (OldTpl); SIGNAL_USER: if ((ResolvedEvent != NULL) && (Status == EFI_SUCCESS)) { gBS->SignalEvent (ResolvedEvent); + + // + // Dispatch the DPC queued by the NotifyFunction of ResolvedEvent. + // + NetLibDispatchDpc (); } return Status; @@ -695,8 +686,8 @@ ArpCancel ( ) { ARP_INSTANCE_DATA *Instance; - ARP_SERVICE_DATA *ArpService; UINTN Count; + EFI_TPL OldTpl; if ((This == NULL) || ((TargetSwAddress != NULL) && (ResolvedEvent == NULL)) || @@ -710,18 +701,20 @@ ArpCancel ( return EFI_NOT_STARTED; } - ArpService = Instance->ArpService; - - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); // // Cancel the specified request. // Count = ArpCancelRequest (Instance, TargetSwAddress, ResolvedEvent); - NET_UNLOCK (&ArpService->Lock); + // + // Dispatch the DPCs queued by the NotifyFunction of the events signaled + // by ArpCancleRequest. + // + NetLibDispatchDpc (); + + NET_RESTORE_TPL (OldTpl); return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS; } diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c index 69598f15c3..e8e9b383f8 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c @@ -178,7 +178,7 @@ DhcpCopyConfigure ( } for (Index = 0; Index < Src->DiscoverTryCount; Index++) { - Dst->DiscoverTimeout[Index] = NET_MAX (Src->DiscoverTimeout[Index], 1); + Dst->DiscoverTimeout[Index] = MAX (Src->DiscoverTimeout[Index], 1); } } @@ -194,7 +194,7 @@ DhcpCopyConfigure ( } for (Index = 0; Index < Src->RequestTryCount; Index++) { - Dst->RequestTimeout[Index] = NET_MAX (Src->RequestTimeout[Index], 1); + Dst->RequestTimeout[Index] = MAX (Src->RequestTimeout[Index], 1); } } @@ -214,7 +214,7 @@ DhcpCopyConfigure ( SrcOptions = Src->OptionList; for (Index = 0; Index < Src->OptionCount; Index++) { - Len = sizeof (EFI_DHCP4_PACKET_OPTION) + NET_MAX (SrcOptions[Index]->Length - 1, 0); + Len = sizeof (EFI_DHCP4_PACKET_OPTION) + MAX (SrcOptions[Index]->Length - 1, 0); DstOptions[Index] = NetAllocatePool (Len); @@ -819,7 +819,7 @@ Dhcp4ParseCheckOption ( Parse = (DHCP_PARSE_CONTEXT *) Context; Parse->Index++; - if (Parse->Index < Parse->OptionCount) { + if (Parse->Index <= Parse->OptionCount) { // // Use _CR to get the memory position of EFI_DHCP4_PACKET_OPTION for // the EFI_DHCP4_PACKET_OPTION->Data because DhcpIterateOptions only diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c index 17c61007f1..8adf40ff43 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c @@ -1310,7 +1310,7 @@ DhcpSendMessage ( // Append the user's message if it isn't NULL // if (Msg != NULL) { - Len = NET_MIN ((UINT32) AsciiStrLen ((CHAR8 *) Msg), 255); + Len = MIN ((UINT32) AsciiStrLen ((CHAR8 *) Msg), 255); Buf = DhcpAppendOption (Buf, DHCP_TAG_MESSAGE, (UINT16) Len, Msg); } diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.c index cf43dfa206..cf81199839 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.c @@ -763,7 +763,7 @@ DhcpAppendOption ( ASSERT (DataLen != 0); for (Index = 0; Index < (DataLen + 254) / 255; Index++) { - Len = NET_MIN (255, DataLen - Index * 255); + Len = MIN (255, DataLen - Index * 255); *(Buf++) = Tag; *(Buf++) = (UINT8) Len; diff --git a/MdeModulePkg/Universal/Network/DpcDxe/Dpc.c b/MdeModulePkg/Universal/Network/DpcDxe/Dpc.c new file mode 100644 index 0000000000..cccedf5e46 --- /dev/null +++ b/MdeModulePkg/Universal/Network/DpcDxe/Dpc.c @@ -0,0 +1,352 @@ +/** @file + +Copyright (c) 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: + + Dpc.c + +Abstract: + + +**/ + +#include "Dpc.h" + +// +// Handle for the EFI_DPC_PROTOCOL instance +// +EFI_HANDLE mDpcHandle = NULL; + +// +// The EFI_DPC_PROTOCOL instances that is installed onto mDpcHandle +// +EFI_DPC_PROTOCOL mDpc = { + DpcQueueDpc, + DpcDispatchDpc +}; + +// +// Global variables used to meaasure the DPC Queue Depths +// +UINTN mDpcQueueDepth = 0; +UINTN mMaxDpcQueueDepth = 0; + +// +// Free list of DPC entries. As DPCs are queued, entries are removed from this +// free list. As DPC entries are dispatched, DPC entries are added to the free list. +// If the free list is empty and a DPC is queued, the free list is grown by allocating +// an additional set of DPC entries. +// +LIST_ENTRY mDpcEntryFreeList = INITIALIZE_LIST_HEAD_VARIABLE(mDpcEntryFreeList); + +// +// An array of DPC queues. A DPC queue is allocated for every leval EFI_TPL value. +// As DPCs are queued, they are added to the end of the linked list. +// As DPCs are dispatched, they are removed from the beginning of the linked list. +// +LIST_ENTRY mDpcQueue[TPL_HIGH_LEVEL + 1]; + +/** + Add a Deferred Procedure Call to the end of the DPC queue. + + @param This Protocol instance pointer. + @param DpcTpl The EFI_TPL that the DPC should be invoked. + @param DpcProcedure Pointer to the DPC's function. + @param DpcContext Pointer to the DPC's context. Passed to DpcProcedure + when DpcProcedure is invoked. + + @retval EFI_SUCCESS The DPC was queued. + @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL. + @retval EFI_INVALID_PARAMETER DpcProcedure is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + add the DPC to the queue. + +**/ +EFI_STATUS +EFIAPI +DpcQueueDpc ( + IN EFI_DPC_PROTOCOL *This, + IN EFI_TPL DpcTpl, + IN EFI_DPC_PROCEDURE DpcProcedure, + IN VOID *DpcContext OPTIONAL + ) +{ + EFI_STATUS ReturnStatus; + EFI_TPL OriginalTpl; + DPC_ENTRY *DpcEntry; + UINTN Index; + + // + // Make sure DpcTpl is valid + // + if (DpcTpl < TPL_APPLICATION || DpcTpl > TPL_HIGH_LEVEL) { + return EFI_INVALID_PARAMETER; + } + + // + // Make sure DpcProcedure is valid + // + if (DpcProcedure == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Assume this function will succeed + // + ReturnStatus = EFI_SUCCESS; + + // + // Raise the TPL level to TPL_HIGH_LEVEL for DPC list operation and save the + // current TPL value so it can be restored when this function returns. + // + OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); + + // + // Check to see if there are any entries in the DPC free list + // + if (IsListEmpty (&mDpcEntryFreeList)) { + // + // If the current TPL is greater than TPL_NOTIFY, then memory allocations + // can not be performed, so the free list can not be expanded. In this case + // return EFI_OUT_OF_RESOURCES. + // + if (OriginalTpl > TPL_NOTIFY) { + ReturnStatus = EFI_OUT_OF_RESOURCES; + goto Done; + } + + // + // Add 64 DPC entries to the free list + // + for (Index = 0; Index < 64; Index++) { + // + // Lower the TPL level to perform a memory allocation + // + gBS->RestoreTPL (OriginalTpl); + + // + // Allocate a new DPC entry + // + DpcEntry = AllocatePool (sizeof (DPC_ENTRY)); + + // + // Raise the TPL level back to TPL_HIGH_LEVEL for DPC list operations + // + gBS->RaiseTPL (TPL_HIGH_LEVEL); + + // + // If the allocation of a DPC entry fails, and the free list is empty, + // then return EFI_OUT_OF_RESOURCES. + // + if (DpcEntry == NULL) { + if (IsListEmpty (&mDpcEntryFreeList)) { + ReturnStatus = EFI_OUT_OF_RESOURCES; + goto Done; + } + } + + // + // Add the newly allocated DPC entry to the DPC free list + // + InsertTailList (&mDpcEntryFreeList, &DpcEntry->ListEntry); + } + } + + // + // Retrieve the first node from the free list of DPCs + // + DpcEntry = (DPC_ENTRY *)(GetFirstNode (&mDpcEntryFreeList)); + + // + // Remove the first node from the free list of DPCs + // + RemoveEntryList (&DpcEntry->ListEntry); + + // + // Fill in the DPC entry with the DpcProcedure and DpcContext + // + DpcEntry->DpcProcedure = DpcProcedure; + DpcEntry->DpcContext = DpcContext; + + // + // Add the DPC entry to the end of the list for the specified DplTpl. + // + InsertTailList (&mDpcQueue[DpcTpl], &DpcEntry->ListEntry); + + // + // Increment the measured DPC queue depth across all TPLs + // + mDpcQueueDepth++; + + // + // Measure the maximum DPC queue depth across all TPLs + // + if (mDpcQueueDepth > mMaxDpcQueueDepth) { + mMaxDpcQueueDepth = mDpcQueueDepth; + } + +Done: + // + // Restore the original TPL level when this function was called + // + gBS->RestoreTPL (OriginalTpl); + + return ReturnStatus; +} + +/** + Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl + value greater than or equal to the current TPL are invoked in the order that + they were queued. DPCs with higher DpcTpl values are invoked before DPCs with + lower DpcTpl values. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS One or more DPCs were invoked. + @retval EFI_NOT_FOUND No DPCs were invoked. + +**/ +EFI_STATUS +EFIAPI +DpcDispatchDpc ( + IN EFI_DPC_PROTOCOL *This + ) +{ + EFI_STATUS ReturnStatus; + EFI_TPL OriginalTpl; + EFI_TPL Tpl; + DPC_ENTRY *DpcEntry; + + // + // Assume that no DPCs will be invoked + // + ReturnStatus = EFI_NOT_FOUND; + + // + // Raise the TPL level to TPL_HIGH_LEVEL for DPC list operation and save the + // current TPL value so it can be restored when this function returns. + // + OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); + + // + // Check to see if there are 1 or more DPCs currently queued + // + if (mDpcQueueDepth > 0) { + // + // Loop from TPL_HIGH_LEVEL down to the current TPL value + // + for (Tpl = TPL_HIGH_LEVEL; Tpl >= OriginalTpl; Tpl--) { + // + // Check to see if the DPC queue is empty + // + while (!IsListEmpty (&mDpcQueue[Tpl])) { + // + // Retrieve the first DPC entry from the DPC queue specified by Tpl + // + DpcEntry = (DPC_ENTRY *)(GetFirstNode (&mDpcQueue[Tpl])); + + // + // Remove the first DPC entry from the DPC queue specified by Tpl + // + RemoveEntryList (&DpcEntry->ListEntry); + + // + // Decrement the measured DPC Queue Depth across all TPLs + // + mDpcQueueDepth--; + + // + // Lower the TPL to TPL value of the current DPC queue + // + gBS->RestoreTPL (Tpl); + + // + // Invoke the DPC passing in its context + // + (DpcEntry->DpcProcedure) (DpcEntry->DpcContext); + + // + // At least one DPC has been invoked, so set the return status to EFI_SUCCESS + // + ReturnStatus = EFI_SUCCESS; + + // + // Raise the TPL level back to TPL_HIGH_LEVEL for DPC list operations + // + gBS->RaiseTPL (TPL_HIGH_LEVEL); + + // + // Add the invoked DPC entry to the DPC free list + // + InsertTailList (&mDpcEntryFreeList, &DpcEntry->ListEntry); + } + } + } + + // + // Restore the original TPL level when this function was called + // + gBS->RestoreTPL (OriginalTpl); + + return ReturnStatus; +} + +EFI_STATUS +EFIAPI +DpcDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + The entry point for DPC driver which installs the EFI_DPC_PROTOCOL onto a new handle. + +Arguments: + + ImageHandle - The image handle of the driver. + SystemTable - The system table. + +Returns: + + EFI_SUCCESS - The DPC queues were initialized and the EFI_DPC_PROTOCOL was + installed onto a new handle. + +--*/ +{ + EFI_STATUS Status; + UINTN Index; + + // + // ASSERT() if the EFI_DPC_PROTOCOL is already present in the handle database + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiDpcProtocolGuid); + + // + // Initialize the DPC queue for all possible TPL values + // + for (Index = 0; Index <= TPL_HIGH_LEVEL; Index++) { + InitializeListHead (&mDpcQueue[Index]); + } + + // + // Install the EFI_DPC_PROTOCOL instance onto a new handle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &mDpcHandle, + &gEfiDpcProtocolGuid, &mDpc, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/MdeModulePkg/Universal/Network/DpcDxe/Dpc.h b/MdeModulePkg/Universal/Network/DpcDxe/Dpc.h new file mode 100644 index 0000000000..d113947272 --- /dev/null +++ b/MdeModulePkg/Universal/Network/DpcDxe/Dpc.h @@ -0,0 +1,86 @@ +/** @file + +Copyright (c) 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: + + Dpc.h + +Abstract: + + +**/ + +#ifndef _DPC_H_ +#define _DPC_H_ + +#include +#include +#include +#include +#include +#include +#include + +// +// Internal data struture for managing DPCs. A DPC entry is either on the free +// list or on a DPC queue at a specific EFI_TPL. +// +typedef struct { + LIST_ENTRY ListEntry; + EFI_DPC_PROCEDURE DpcProcedure; + VOID *DpcContext; +} DPC_ENTRY; + +/** + Add a Deferred Procedure Call to the end of the DPC queue. + + @param This Protocol instance pointer. + @param DpcTpl The EFI_TPL that the DPC should be invoked. + @param DpcProcedure Pointer to the DPC's function. + @param DpcContext Pointer to the DPC's context. Passed to DpcProcedure + when DpcProcedure is invoked. + + @retval EFI_SUCCESS The DPC was queued. + @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL. + @retval EFI_INVALID_PARAMETER DpcProcedure is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + add the DPC to the queue. + +**/ +EFI_STATUS +EFIAPI +DpcQueueDpc ( + IN EFI_DPC_PROTOCOL *This, + IN EFI_TPL DpcTpl, + IN EFI_DPC_PROCEDURE DpcProcedure, + IN VOID *DpcContext OPTIONAL + ); + +/** + Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl + value greater than or equal to the current TPL are invoked in the order that + they were queued. DPCs with higher DpcTpl values are invoked before DPCs with + lower DpcTpl values. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS One or more DPCs were invoked. + @retval EFI_NOT_FOUND No DPCs were invoked. + +**/ +EFI_STATUS +EFIAPI +DpcDispatchDpc ( + IN EFI_DPC_PROTOCOL *This + ); + +#endif + diff --git a/MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf b/MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf new file mode 100644 index 0000000000..5159c2bcae --- /dev/null +++ b/MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf @@ -0,0 +1,52 @@ +#/** @file +# Component description file for DPC module +# +# Copyright (c) 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. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DpcDxe + FILE_GUID = A210F973-229D-4f4d-AA37-9895E6C9EABA + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + ENTRY_POINT = DpcDriverEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + Dpc.c + Dpc.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + DebugLib + UefiBootServicesTableLib + MemoryAllocationLib + +[Protocols] + gEfiDpcProtocolGuid # PROTOCOL ALWAYS_PRODUCED + +[Depex] + TRUE \ No newline at end of file diff --git a/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c b/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c index bec1a4f0b0..13ed771282 100644 --- a/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c +++ b/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c @@ -415,7 +415,7 @@ EfiIp4ConfigStart ( // Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, - NET_TPL_EVENT, + NET_TPL_LOCK, Ip4ConfigOnDhcp4Complete, Instance, &Instance->Dhcp4Event diff --git a/MdeModulePkg/Universal/Network/Ip4ConfigDxe/NicIp4Variable.h b/MdeModulePkg/Universal/Network/Ip4ConfigDxe/NicIp4Variable.h index be8ccd7b5f..103072c61a 100644 --- a/MdeModulePkg/Universal/Network/Ip4ConfigDxe/NicIp4Variable.h +++ b/MdeModulePkg/Universal/Network/Ip4ConfigDxe/NicIp4Variable.h @@ -32,11 +32,11 @@ Abstract: // #define SIZEOF_IP4_CONFIG_INFO(Ip4Config) \ (sizeof (EFI_IP4_IPCONFIG_DATA) + \ - sizeof (EFI_IP4_ROUTE_TABLE) * (NET_MAX (1, (Ip4Config)->RouteTableSize) - 1)) + sizeof (EFI_IP4_ROUTE_TABLE) * (MAX (1, (Ip4Config)->RouteTableSize) - 1)) #define SIZEOF_NIC_IP4_CONFIG_INFO(NicConfig) \ (sizeof (NIC_IP4_CONFIG_INFO) + \ - sizeof (EFI_IP4_ROUTE_TABLE) * (NET_MAX (1, (NicConfig)->Ip4Info.RouteTableSize) - 1)) + sizeof (EFI_IP4_ROUTE_TABLE) * (MAX (1, (NicConfig)->Ip4Info.RouteTableSize) - 1)) // // Compare whether two NIC address are equal includes their type and length. diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c index 0d308c0521..bf43677e8a 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c @@ -208,6 +208,7 @@ Ip4CreateService ( IpSb->Ip4Config = NULL; IpSb->DoneEvent = NULL; IpSb->ReconfigEvent = NULL; + IpSb->ActiveEvent = NULL; // // Create various resources. First create the route table, timer @@ -223,7 +224,7 @@ Ip4CreateService ( Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL | EVT_TIMER, - TPL_CALLBACK, + NET_TPL_TIMER, Ip4TimerTicking, IpSb, &IpSb->Timer @@ -375,6 +376,7 @@ Ip4CleanService ( gBS->CloseEvent (IpSb->DoneEvent); gBS->CloseEvent (IpSb->ReconfigEvent); + IpSb->ActiveEvent = NULL; IpSb->Ip4Config = NULL; } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c index bfb9616c2d..eaed123b84 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c @@ -29,6 +29,13 @@ Abstract: // STATIC EFI_MAC_ADDRESS mZeroMacAddress; +STATIC +VOID +EFIAPI +Ip4OnFrameSentDpc ( + IN VOID *Context + ); + STATIC VOID EFIAPI @@ -37,6 +44,13 @@ Ip4OnFrameSent ( IN VOID *Context ); +STATIC +VOID +EFIAPI +Ip4OnArpResolvedDpc ( + IN VOID *Context + ); + STATIC VOID EFIAPI @@ -45,6 +59,13 @@ Ip4OnArpResolved ( IN VOID *Context ); +STATIC +VOID +EFIAPI +Ip4OnFrameReceivedDpc ( + IN VOID *Context + ); + STATIC VOID EFIAPI @@ -116,7 +137,7 @@ Ip4WrapLinkTxToken ( Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, + NET_TPL_EVENT, Ip4OnFrameSent, Token, &MnpToken->Event @@ -201,7 +222,7 @@ Ip4CreateArpQue ( Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, + NET_TPL_EVENT, Ip4OnArpResolved, ArpQue, &ArpQue->OnResolved @@ -289,7 +310,7 @@ Ip4CreateLinkRxToken ( Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, + NET_TPL_EVENT, Ip4OnFrameReceived, Token, &MnpToken->Event @@ -404,10 +425,7 @@ Ip4CancelFrames ( Ip4CancelFrameArp (ArpQue, IoStatus, FrameToCancel, Context); if (NetListIsEmpty (&ArpQue->Frames)) { - NetListRemoveEntry (Entry); - Interface->Arp->Cancel (Interface->Arp, &ArpQue->Ip, ArpQue->OnResolved); - Ip4FreeArpQue (ArpQue, EFI_ABORTED); } } @@ -419,11 +437,7 @@ Ip4CancelFrames ( Token = NET_LIST_USER_STRUCT (Entry, IP4_LINK_TX_TOKEN, Link); if ((FrameToCancel == NULL) || FrameToCancel (Token, Context)) { - NetListRemoveEntry (Entry); - Interface->Mnp->Cancel (Interface->Mnp, &Token->MnpToken); - Token->CallBack (Token->IpInstance, Token->Packet, IoStatus, 0, Token->Context); - Ip4FreeLinkTxToken (Token); } } } @@ -540,7 +554,7 @@ Ip4SetAddress ( Type = NetGetIpClass (IpAddr); Len = NetGetMaskLength (SubnetMask); - Netmask = mIp4AllMasks[NET_MIN (Len, Type << 3)]; + Netmask = mIp4AllMasks[MIN (Len, Type << 3)]; Interface->NetBrdcast = (IpAddr | ~Netmask); // @@ -747,7 +761,6 @@ Ip4FreeInterface ( all the queued frame if the ARP requests failed. Or transmit them if the request succeed. - @param Event The Arp request event @param Context The context of the callback, a point to the ARP queue @@ -757,8 +770,7 @@ Ip4FreeInterface ( STATIC VOID EFIAPI -Ip4OnArpResolved ( - IN EFI_EVENT Event, +Ip4OnArpResolvedDpc ( IN VOID *Context ) { @@ -798,27 +810,64 @@ Ip4OnArpResolved ( Token = NET_LIST_USER_STRUCT (Entry, IP4_LINK_TX_TOKEN, Link); CopyMem (&Token->DstMac, &ArpQue->Mac, sizeof (Token->DstMac)); - Status = Interface->Mnp->Transmit (Interface->Mnp, &Token->MnpToken); + // + // Insert the tx token before transmitting it via MNP as the FrameSentDpc + // may be called before Mnp->Transmit returns which will remove this tx + // token from the SentFrames list. Remove it from the list if the returned + // Status of Mnp->Transmit is not EFI_SUCCESS as in this case the + // FrameSentDpc won't be queued. + // + NetListInsertTail (&Interface->SentFrames, &Token->Link); + Status = Interface->Mnp->Transmit (Interface->Mnp, &Token->MnpToken); if (EFI_ERROR (Status)) { + NetListRemoveEntry (Entry); Token->CallBack (Token->IpInstance, Token->Packet, Status, 0, Token->Context); Ip4FreeLinkTxToken (Token); continue; } - - NetListInsertTail (&Interface->SentFrames, &Token->Link); } Ip4FreeArpQue (ArpQue, EFI_SUCCESS); } +STATIC +VOID +EFIAPI +Ip4OnArpResolved ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + + Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK + +Arguments: + + Event - The Arp request event + Context - The context of the callback, a point to the ARP queue + +Returns: + + None + +--*/ +{ + // + // Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, Ip4OnArpResolvedDpc, Context); +} + + /** Callback funtion when frame transmission is finished. It will call the frame owner's callback function to tell it the result. - @param Event The transmit token's event @param Context Context which is point to the token. @return None. @@ -827,8 +876,7 @@ Ip4OnArpResolved ( STATIC VOID EFIAPI -Ip4OnFrameSent ( - IN EFI_EVENT Event, +Ip4OnFrameSentDpc ( IN VOID *Context ) { @@ -850,6 +898,36 @@ Ip4OnFrameSent ( Ip4FreeLinkTxToken (Token); } +STATIC +VOID +EFIAPI +Ip4OnFrameSent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + + Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK + +Arguments: + + Event - The transmit token's event + Context - Context which is point to the token. + +Returns: + + None. + +--*/ +{ + // + // Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, Ip4OnFrameSentDpc, Context); +} + /** @@ -983,13 +1061,17 @@ Ip4SendFrame ( return EFI_SUCCESS; SEND_NOW: + // + // Insert the tx token into the SentFrames list before calling Mnp->Transmit. + // Remove it if the returned status is not EFI_SUCCESS. + // + NetListInsertTail (&Interface->SentFrames, &Token->Link); Status = Interface->Mnp->Transmit (Interface->Mnp, &Token->MnpToken); - if (EFI_ERROR (Status)) { + NetListRemoveEntry (&Interface->SentFrames); goto ON_ERROR; } - NetListInsertTail (&Interface->SentFrames, &Token->Link); return EFI_SUCCESS; ON_ERROR: @@ -1031,7 +1113,6 @@ Ip4RecycleFrame ( again call the Ip4RecycleFrame to signal MNP's event and free the token used. - @param Event The receive event delivered to MNP for receive. @param Context Context for the callback. @return None. @@ -1040,8 +1121,7 @@ Ip4RecycleFrame ( STATIC VOID EFIAPI -Ip4OnFrameReceived ( - IN EFI_EVENT Event, +Ip4OnFrameReceivedDpc ( IN VOID *Context ) { @@ -1096,6 +1176,36 @@ Ip4OnFrameReceived ( Token->CallBack (Token->IpInstance, Packet, EFI_SUCCESS, Flag, Token->Context); } +STATIC +VOID +EFIAPI +Ip4OnFrameReceived ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + + Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK + +Arguments: + + Event - The receive event delivered to MNP for receive. + Context - Context for the callback. + +Returns: + + None. + +--*/ +{ + // + // Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, Ip4OnFrameReceivedDpc, Context); +} + /** Request to receive the packet from the interface. @@ -1134,13 +1244,12 @@ Ip4ReceiveFrame ( return EFI_OUT_OF_RESOURCES; } + Interface->RecvRequest = Token; Status = Interface->Mnp->Receive (Interface->Mnp, &Token->MnpToken); - if (EFI_ERROR (Status)) { + Interface->RecvRequest = NULL; Ip4FreeFrameRxToken (Token); return Status; } - - Interface->RecvRequest = Token; return EFI_SUCCESS; } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Igmp.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Igmp.c index 6609b1334d..70fbebdc44 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Igmp.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Igmp.c @@ -482,7 +482,7 @@ Ip4IgmpHandle ( // is longer than the MaxRespTime. TODO: randomize the DelayTime. // if ((Group->DelayTime == 0) || (Group->DelayTime > Igmp.MaxRespTime)) { - Group->DelayTime = NET_MAX (1, Igmp.MaxRespTime); + Group->DelayTime = MAX (1, Igmp.MaxRespTime); } } } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c index 40c5daacd8..04ca79578f 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c @@ -214,7 +214,6 @@ Ip4ServiceConfigMnp ( it will configure the default interface and default route table with the configuration information retrieved by IP4_CONFIGURE. - @param Event The event that is signalled. @param Context The IP4 service binding instance. @return None @@ -222,8 +221,7 @@ Ip4ServiceConfigMnp ( **/ VOID EFIAPI -Ip4AutoConfigCallBack ( - IN EFI_EVENT Event, +Ip4AutoConfigCallBackDpc ( IN VOID *Context ) { @@ -252,7 +250,7 @@ Ip4AutoConfigCallBack ( // frames on the default address, and when the default interface is // freed, Ip4AcceptFrame won't be informed. // - if (Event == IpSb->ReconfigEvent) { + if (IpSb->ActiveEvent == IpSb->ReconfigEvent) { if (IpSb->DefaultInterface->Configured) { IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image); @@ -360,6 +358,40 @@ ON_EXIT: NetFreePool (Data); } +VOID +EFIAPI +Ip4AutoConfigCallBack ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + + Request Ip4AutoConfigCallBackDpc as a DPC at TPL_CALLBACK + +Arguments: + + Event - The event that is signalled. + Context - The IP4 service binding instance. + +Returns: + + None + +--*/ +{ + IP4_SERVICE *IpSb; + + IpSb = (IP4_SERVICE *) Context; + IpSb->ActiveEvent = Event; + + // + // Request Ip4AutoConfigCallBackDpc as a DPC at TPL_CALLBACK + // + NetLibQueueDpc (TPL_CALLBACK, Ip4AutoConfigCallBackDpc, Context); +} + /** Start the auto configuration for this IP service instance. @@ -401,7 +433,7 @@ Ip4StartAutoConfig ( Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, + NET_TPL_EVENT, Ip4AutoConfigCallBack, IpSb, &IpSb->ReconfigEvent @@ -764,7 +796,7 @@ Ip4StationAddressValid ( return FALSE; } - NetBrdcastMask = mIp4AllMasks[NET_MIN (Len, Type << 3)]; + NetBrdcastMask = mIp4AllMasks[MIN (Len, Type << 3)]; if (Ip == (Ip | ~NetBrdcastMask)) { return FALSE; @@ -1356,6 +1388,11 @@ Ip4FreeTxToken ( if (Wrap->Sent) { gBS->SignalEvent (Wrap->Token->Event); + + // + // Dispatch the DPC queued by the NotifyFunction of Token->Event. + // + NetLibDispatchDpc (); } NetFreePool (Wrap); @@ -1562,6 +1599,12 @@ EfiIp4Transmit ( goto ON_EXIT; } + // + // Mark the packet sent before output it. Mark it not sent again if the + // returned status is not EFI_SUCCESS; + // + Wrap->Sent = TRUE; + Status = Ip4Output ( IpSb, IpInstance, @@ -1575,16 +1618,10 @@ EfiIp4Transmit ( ); if (EFI_ERROR (Status)) { + Wrap->Sent = FALSE; NetbufFree (Wrap->Packet); - goto ON_EXIT; } - // - // Mark the packet sent, so when Ip4FreeTxToken is called, it - // will signal the upper layer. - // - Wrap->Sent = TRUE; - ON_EXIT: NET_RESTORE_TPL (OldTpl); return Status; @@ -1668,6 +1705,12 @@ EfiIp4Receive ( Status = Ip4InstanceDeliverPacket (IpInstance); + // + // Dispatch the DPC queued by the NotifyFunction of this instane's receive + // event. + // + NetLibDispatchDpc (); + ON_EXIT: NET_RESTORE_TPL (OldTpl); return Status; @@ -1820,7 +1863,11 @@ Ip4Cancel ( // for Token!=NULL and it is cancelled. // Status = NetMapIterate (&IpInstance->RxTokens, Ip4CancelRxTokens, Token); - + // + // Dispatch the DPCs queued by the NotifyFunction of the canceled rx token's + // events. + // + NetLibDispatchDpc (); if (EFI_ERROR (Status)) { if ((Token != NULL) && (Status == EFI_ABORTED)) { return EFI_SUCCESS; diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h index 35ada7feff..aba5055ccb 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h @@ -194,6 +194,7 @@ struct _IP4_SERVICE { EFI_IP4_CONFIG_PROTOCOL *Ip4Config; EFI_EVENT DoneEvent; EFI_EVENT ReconfigEvent; + EFI_EVENT ActiveEvent; // // The string representation of the current mac address of the diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c index 5ed1ec79f0..b2308c6935 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c @@ -607,6 +607,12 @@ Ip4AccpetFrame ( Packet = NULL; + // + // Dispatch the DPCs queued by the NotifyFunction of the rx token's events + // which are signaled with received data. + // + NetLibDispatchDpc (); + RESTART: Ip4ReceiveFrame (IpSb->DefaultInterface, NULL, Ip4AccpetFrame, IpSb); diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c index 88158ea50b..c2bb839e6b 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c @@ -395,7 +395,7 @@ MnpInitializeServiceData ( // Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL | EVT_TIMER, - NET_TPL_EVENT, + NET_TPL_TIMER, MnpCheckPacketTimeout, MnpServiceData, &MnpServiceData->TimeoutCheckTimer @@ -411,7 +411,7 @@ MnpInitializeServiceData ( // Status = gBS->CreateEvent ( EVT_TIMER, - NET_TPL_SLOW_TIMER, + NET_TPL_TIMER, NULL, NULL, &MnpServiceData->TxTimeoutEvent @@ -636,15 +636,15 @@ MnpCancelTokens ( TokenToCancel = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *) Item->Key; // - // Cancel this token with status set to EFI_ABORTED. + // Remove the item from the map. // - TokenToCancel->Status = EFI_ABORTED; - gBS->SignalEvent (TokenToCancel->Event); + NetMapRemoveItem (Map, Item, NULL); // - // Remove the item from the map. + // Cancel this token with status set to EFI_ABORTED. // - NetMapRemoveItem (Map, Item, NULL); + TokenToCancel->Status = EFI_ABORTED; + gBS->SignalEvent (TokenToCancel->Event); if (Arg != NULL) { // @@ -1027,7 +1027,7 @@ MnpConfigureInstance ( if (ConfigData == NULL) { - NetMapIterate (&Instance->RxTokenMap, MnpCancelTokens, NULL); + Instance->ManagedNetwork.Cancel (&Instance->ManagedNetwork, NULL); } if (!NewConfigData->EnableMulticastReceive) { diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h b/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h index 7f6669fba3..880414231c 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h @@ -26,7 +26,7 @@ Abstract: #define NET_ETHER_FCS_SIZE 4 -#define MNP_SYS_POLL_INTERVAL (2 * TICKS_PER_MS) // 2 milliseconds +#define MNP_SYS_POLL_INTERVAL (50 * TICKS_PER_MS) // 50 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 diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c index 3d26ec2a4c..ed8bf78282 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c @@ -294,6 +294,11 @@ SIGNAL_TOKEN: Token->Status = Status; gBS->SignalEvent (Token->Event); + // + // Dispatch the DPC queued by the NotifyFunction of Token->Event. + // + NetLibDispatchDpc (); + return EFI_SUCCESS; } @@ -562,12 +567,6 @@ MnpMatchPacket ( ConfigData = &Instance->ConfigData; - if (ConfigData->EnablePromiscuousReceive) { - // - // Always match if this instance is configured to be promiscuous. - // - return TRUE; - } // // Check the protocol type. // @@ -575,6 +574,13 @@ MnpMatchPacket ( return FALSE; } + if (ConfigData->EnablePromiscuousReceive) { + // + // Always match if this instance is configured to be promiscuous. + // + return TRUE; + } + // // The protocol type is matched, check receive filter, include unicast and broadcast. // @@ -987,6 +993,11 @@ MnpReceivePacket ( // MnpDeliverPacket (MnpServiceData); + // + // Dispatch the DPC queued by the NotifyFunction of rx token's events. + // + NetLibDispatchDpc (); + EXIT: ASSERT (Nbuf->TotalSize == MnpServiceData->BufferLength); @@ -1087,4 +1098,6 @@ MnpSystemPoll ( // Try to receive packets from Snp. // MnpReceivePacket (MnpServiceData); + + NetLibDispatchDpc (); } diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c index 04e437e939..b6d93921b2 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c @@ -531,6 +531,11 @@ MnpReceive ( // Try to deliver any buffered packets. // Status = MnpInstanceDeliverPacket (Instance); + + // + // Dispatch the DPC queued by the NotifyFunction of Token->Event. + // + NetLibDispatchDpc (); } ON_EXIT: @@ -596,6 +601,11 @@ MnpCancel ( Status = (Status == EFI_ABORTED) ? EFI_SUCCESS : EFI_NOT_FOUND; } + // + // Dispatch the DPC queued by the NotifyFunction of the cancled token's events. + // + NetLibDispatchDpc (); + ON_EXIT: NET_RESTORE_TPL (OldTpl); @@ -648,8 +658,11 @@ MnpPoll ( // Status = MnpReceivePacket (Instance->MnpServiceData); + NetLibDispatchDpc (); + ON_EXIT: NET_RESTORE_TPL (OldTpl); return Status; } + diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c index ceabbfe41f..1186249513 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c @@ -174,7 +174,7 @@ Mtftp4CreateService ( // Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL | EVT_TIMER, - TPL_CALLBACK, + NET_TPL_TIMER, Mtftp4OnTimerTick, MtftpSb, &MtftpSb->Timer @@ -191,7 +191,7 @@ Mtftp4CreateService ( // Status = gBS->CreateEvent ( EVT_TIMER, - TPL_CALLBACK, + NET_TPL_TIMER, NULL, NULL, &MtftpSb->TimerToGetMap diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c index 3ce8792537..214ac44745 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c @@ -260,13 +260,11 @@ Mtftp4GetInfoCheckPacket ( IN EFI_MTFTP4_PACKET *Packet ) { - MTFTP4_PROTOCOL *Instance; MTFTP4_GETINFO_STATE *State; EFI_STATUS Status; UINT16 OpCode; - Instance = MTFTP4_PROTOCOL_FROM_THIS (This); - State = &Instance->GetInfoState; + State = (MTFTP4_GETINFO_STATE *) Token->Context; OpCode = NTOHS (Packet->OpCode); // @@ -337,8 +335,7 @@ EfiMtftp4GetInfo ( ) { EFI_MTFTP4_TOKEN Token; - MTFTP4_PROTOCOL *Instance; - MTFTP4_GETINFO_STATE *State; + MTFTP4_GETINFO_STATE State; EFI_STATUS Status; if ((This == NULL) || (Filename == NULL) || (PacketLength == NULL) || @@ -351,11 +348,9 @@ EfiMtftp4GetInfo ( } *PacketLength = 0; - Instance = MTFTP4_PROTOCOL_FROM_THIS (This); - State = &Instance->GetInfoState; - State->Packet = Packet; - State->PacketLen = PacketLength; - State->Status = EFI_SUCCESS; + State.Packet = Packet; + State.PacketLen = PacketLength; + State.Status = EFI_SUCCESS; // // Fill in the Token to issue an synchronous ReadFile operation @@ -369,6 +364,7 @@ EfiMtftp4GetInfo ( Token.OptionList = OptionList; Token.BufferSize = 0; Token.Buffer = NULL; + Token.Context = &State; Token.CheckPacket = Mtftp4GetInfoCheckPacket; Token.TimeoutCallback = NULL; Token.PacketNeeded = NULL; @@ -376,7 +372,7 @@ EfiMtftp4GetInfo ( Status = EfiMtftp4ReadFile (This, &Token); if (EFI_ABORTED == Status) { - return State->Status; + return State.Status; } return Status; diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h index c12b1dd007..9491506601 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h @@ -86,12 +86,6 @@ struct _MTFTP4_SERVICE { UDP_IO_PORT *ConnectUdp; }; -typedef struct { - EFI_MTFTP4_PACKET **Packet; - UINT32 *PacketLen; - EFI_STATUS Status; -} MTFTP4_GETINFO_STATE; - struct _MTFTP4_PROTOCOL { UINT32 Signature; NET_LIST_ENTRY Link; @@ -146,10 +140,14 @@ struct _MTFTP4_PROTOCOL { UINT16 McastPort; BOOLEAN Master; UDP_IO_PORT *McastUdpPort; - - MTFTP4_GETINFO_STATE GetInfoState; }; +typedef struct { + EFI_MTFTP4_PACKET **Packet; + UINT32 *PacketLen; + EFI_STATUS Status; +} MTFTP4_GETINFO_STATE; + VOID Mtftp4CleanOperation ( IN MTFTP4_PROTOCOL *Instance, diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c index bc70403698..585d91bfa5 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c @@ -80,7 +80,7 @@ SockTcpDataToRcv ( if (*IsUrg && TcpRsvData->UrgLen < RcvBufEntry->TotalSize) { - DataLen = NET_MIN (TcpRsvData->UrgLen, BufLen); + DataLen = MIN (TcpRsvData->UrgLen, BufLen); if (DataLen < TcpRsvData->UrgLen) { TcpRsvData->UrgLen = TcpRsvData->UrgLen - DataLen; @@ -114,7 +114,7 @@ SockTcpDataToRcv ( TcpRsvData->UrgLen = TcpRsvData->UrgLen - (BufLen - DataLen); } - return NET_MIN (TcpRsvData->UrgLen + DataLen, BufLen); + return MIN (TcpRsvData->UrgLen + DataLen, BufLen); } @@ -123,7 +123,7 @@ SockTcpDataToRcv ( RcvBufEntry = SockBufNext (SockBuffer, RcvBufEntry); } - DataLen = NET_MIN (BufLen, DataLen); + DataLen = MIN (BufLen, DataLen); return DataLen; } @@ -165,7 +165,7 @@ SockSetTcpRxData ( for (Index = 0; (Index < RxData->FragmentCount) && (RcvdBytes > 0); Index++) { Fragment = &RxData->FragmentTable[Index]; - CopyBytes = NET_MIN ((UINT32) (Fragment->FragmentLength), RcvdBytes); + CopyBytes = MIN ((UINT32) (Fragment->FragmentLength), RcvdBytes); NetbufQueCopy ( Sock->RcvBuffer.DataQueue, diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c index a8185b0b92..1d9138b39b 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c @@ -93,7 +93,7 @@ Tcp4CreateTimer ( Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, - NET_TPL_TIMER, + NET_TPL_EVENT, TcpTicking, NULL, &mTcp4Timer.TimerEvent diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Input.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Input.c index b636016207..3a3e904c7c 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Input.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Input.c @@ -72,7 +72,7 @@ TcpFastRecover ( // FlightSize = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna); - Tcb->Ssthresh = NET_MAX (FlightSize >> 1, (UINT32) (2 * Tcb->SndMss)); + Tcb->Ssthresh = MAX (FlightSize >> 1, (UINT32) (2 * Tcb->SndMss)); Tcb->Recover = Tcb->SndNxt; Tcb->CongestState = TCP_CONGEST_RECOVER; @@ -120,7 +120,7 @@ TcpFastRecover ( // FlightSize = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna); - Tcb->CWnd = NET_MIN (Tcb->Ssthresh, FlightSize + Tcb->SndMss); + Tcb->CWnd = MIN (Tcb->Ssthresh, FlightSize + Tcb->SndMss); Tcb->CongestState = TCP_CONGEST_OPEN; TCP4_DEBUG_TRACE (("TcpFastRecover: received a full ACK(%d)" @@ -241,7 +241,7 @@ TcpComputeRtt ( Tcb->RttVar = Measure << (TCP_RTT_SHIFT - 1); } - Tcb->Rto = (Tcb->SRtt + NET_MAX (8, 4 * Tcb->RttVar)) >> TCP_RTT_SHIFT; + Tcb->Rto = (Tcb->SRtt + MAX (8, 4 * Tcb->RttVar)) >> TCP_RTT_SHIFT; // // Step 2.4: Limit the RTO to at least 1 second @@ -1044,7 +1044,7 @@ TcpInput ( TCP_SEQ_LEQ (Seg->Ack, Tcb->SndNxt)) { Tcb->SndWnd = Seg->Wnd; - Tcb->SndWndMax = NET_MAX (Tcb->SndWnd, Tcb->SndWndMax); + Tcb->SndWndMax = MAX (Tcb->SndWnd, Tcb->SndWndMax); Tcb->SndWl1 = Seg->Seq; Tcb->SndWl2 = Seg->Ack; TcpSetState (Tcb, TCP_ESTABLISHED); @@ -1143,10 +1143,10 @@ TcpInput ( Tcb->CWnd += Tcb->SndMss; } else { - Tcb->CWnd += NET_MAX (Tcb->SndMss * Tcb->SndMss / Tcb->CWnd, 1); + Tcb->CWnd += MAX (Tcb->SndMss * Tcb->SndMss / Tcb->CWnd, 1); } - Tcb->CWnd = NET_MIN (Tcb->CWnd, TCP_MAX_WIN << Tcb->SndWndScale); + Tcb->CWnd = MIN (Tcb->CWnd, TCP_MAX_WIN << Tcb->SndWndScale); } if (Tcb->CongestState == TCP_CONGEST_LOSS) { @@ -1214,7 +1214,7 @@ TcpInput ( } Tcb->SndWnd = Seg->Wnd; - Tcb->SndWndMax = NET_MAX (Tcb->SndWnd, Tcb->SndWndMax); + Tcb->SndWndMax = MAX (Tcb->SndWnd, Tcb->SndWndMax); Tcb->SndWl1 = Seg->Seq; Tcb->SndWl2 = Seg->Ack; } diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.c index 24f97eb93b..cbf9c0aa2f 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.c @@ -147,6 +147,7 @@ Tcp4Configure ( IP4_ADDR Ip; IP4_ADDR SubnetMask; +// CpuBreakpoint (); if (NULL == This) { return EFI_INVALID_PARAMETER; } diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c index 2eaf0ccec5..41516a9ad8 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c @@ -125,7 +125,7 @@ TcpInitTcbPeer ( } if (TCP_FLG_ON (Opt->Flag, TCP_OPTION_RCVD_MSS)) { - Tcb->SndMss = (UINT16) NET_MAX (64, Opt->Mss); + Tcb->SndMss = (UINT16) MAX (64, Opt->Mss); RcvMss = TcpGetRcvMss (Tcb->Sk); if (Tcb->SndMss > RcvMss) { diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Option.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Option.c index 4c11806f22..af1de48b97 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Option.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Option.c @@ -33,6 +33,7 @@ TcpGetUint16 ( return NTOHS (Value); } +STATIC VOID TcpPutUint16 ( IN UINT8 *Buf, @@ -302,7 +303,7 @@ TcpParseOption ( return -1; } - Option->WndScale = (UINT8) NET_MIN (14, Head[Cur + 2]); + Option->WndScale = (UINT8) MIN (14, Head[Cur + 2]); TCP_SET_FLG (Option->Flag, TCP_OPTION_RCVD_WS); Cur += TCP_OPTION_WS_LEN; diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Output.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Output.c index 870403fa2e..707bc3ada3 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Output.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Output.c @@ -144,7 +144,7 @@ TcpComputeWnd ( Tcb->RcvWnd = Wnd; } - Wnd = NET_MIN (Wnd >> Tcb->RcvWndScale, 0xffff); + Wnd = MIN (Wnd >> Tcb->RcvWndScale, 0xffff); return NTOHS ((UINT16) Wnd); } @@ -230,7 +230,7 @@ TcpDataToSend ( Left = GET_SND_DATASIZE (Sk) + TCP_SUB_SEQ (TcpGetMaxSndNxt (Tcb), Tcb->SndNxt); - Len = NET_MIN (Win, Left); + Len = MIN (Win, Left); if (Len > Tcb->SndMss) { Len = Tcb->SndMss; @@ -379,7 +379,7 @@ TcpTransmitSegment ( Seg->Urg = (UINT16) TCP_SUB_SEQ (Tcb->SndUp, Seg->Seq); } else { - Seg->Urg = (UINT16) NET_MIN ( + Seg->Urg = (UINT16) MIN ( TCP_SUB_SEQ (Tcb->SndUp, Seg->Seq), 0xffff @@ -686,7 +686,7 @@ TcpRetransmit ( } Len = TCP_SUB_SEQ (Tcb->SndWl2 + Tcb->SndWnd, Seq); - Len = NET_MIN (Len, Tcb->SndMss); + Len = MIN (Len, Tcb->SndMss); Nbuf = TcpGetSegmentSndQue (Tcb, Seq, Len); if (Nbuf == NULL) { diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Timer.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Timer.c index 20679b4f95..7802ba0119 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Timer.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Timer.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2005 - 2006, Intel Corporation +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 @@ -150,7 +150,7 @@ TcpRexmitTimeout ( // yet ACKed. // FlightSize = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna); - Tcb->Ssthresh = NET_MAX ((UINT32) (2 * Tcb->SndMss), FlightSize / 2); + Tcb->Ssthresh = MAX ((UINT32) (2 * Tcb->SndMss), FlightSize / 2); Tcb->CWnd = Tcb->SndMss; Tcb->LossRecover = Tcb->SndNxt; @@ -494,7 +494,6 @@ TcpBackoffRto ( /** Heart beat timer handler. - @param Event Timer event signaled, ignored. @param Context Context of the timer event, ignored. @return None. @@ -502,8 +501,7 @@ TcpBackoffRto ( **/ VOID EFIAPI -TcpTicking ( - IN EFI_EVENT Event, +TcpTickingDpc ( IN VOID *Context ) { @@ -580,3 +578,23 @@ NextConnection: ; } } + +/** + Heart beat timer handler, queues the DPC at TPL_CALLBACK. + + @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 + ) +{ + NetLibQueueDpc (TPL_CALLBACK, TcpTickingDpc, Context); +} + diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c index dd4ed1bf32..9cbd29511f 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c @@ -192,7 +192,7 @@ Udp4CreateService ( // Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, - NET_TPL_FAST_TIMER, + NET_TPL_TIMER, Udp4CheckTimeout, Udp4Service, &Udp4Service->TimeoutEvent @@ -618,8 +618,8 @@ Udp4BuildIp4ConfigData ( Ip4ConfigData->AcceptBroadcast = Udp4ConfigData->AcceptBroadcast; Ip4ConfigData->AcceptPromiscuous = Udp4ConfigData->AcceptPromiscuous; Ip4ConfigData->UseDefaultAddress = Udp4ConfigData->UseDefaultAddress; - Ip4ConfigData->StationAddress = Udp4ConfigData->StationAddress; - Ip4ConfigData->SubnetMask = Udp4ConfigData->SubnetMask; + CopyMem (&Ip4ConfigData->StationAddress, &Udp4ConfigData->StationAddress, sizeof (EFI_IPv4_ADDRESS)); + CopyMem (&Ip4ConfigData->SubnetMask, &Udp4ConfigData->SubnetMask, sizeof (EFI_IPv4_ADDRESS)); // // use the -1 magic number to disable the receiving process of the ip instance. @@ -891,6 +891,7 @@ Udp4DgramSent ( // Token->Status = Status; gBS->SignalEvent (Token->Event); + NetLibDispatchDpc (); } } @@ -935,6 +936,12 @@ Udp4DgramRcvd ( // Udp4IcmpHandler ((UDP4_SERVICE_DATA *) Context, IcmpError, NetSession, Packet); } + + // + // Dispatch the DPC queued by the NotifyFunction of the rx token's events + // which are signaled with received data. + // + NetLibDispatchDpc (); } @@ -1033,11 +1040,10 @@ Udp4CancelTokens ( // The token is a receive token. Abort it and remove it from the Map. // TokenToCancel = (EFI_UDP4_COMPLETION_TOKEN *) Item->Key; + NetMapRemoveItem (Map, Item, NULL); TokenToCancel->Status = EFI_ABORTED; gBS->SignalEvent (TokenToCancel->Event); - - NetMapRemoveItem (Map, Item, NULL); } if (Arg != NULL) { @@ -1057,28 +1063,23 @@ Udp4CancelTokens ( **/ VOID -Udp4FlushRxData ( - IN NET_LIST_ENTRY *RcvdDgramQue +Udp4FlushRcvdDgram ( + IN UDP4_INSTANCE_DATA *Instance ) { UDP4_RXDATA_WRAP *Wrap; - EFI_TPL OldTpl; - - OldTpl = NET_RAISE_TPL (NET_TPL_RECYCLE); - while (!NetListIsEmpty (RcvdDgramQue)) { + while (!NetListIsEmpty (&Instance->RcvdDgramQue)) { // // Iterate all the Wraps in the RcvdDgramQue. // - Wrap = NET_LIST_HEAD (RcvdDgramQue, UDP4_RXDATA_WRAP, Link); + Wrap = NET_LIST_HEAD (&Instance->RcvdDgramQue, UDP4_RXDATA_WRAP, Link); // // The Wrap will be removed from the RcvdDgramQue by this function call. // Udp4RecycleRxDataWrap (NULL, (VOID *) Wrap); } - - NET_RESTORE_TPL (OldTpl); } @@ -1383,6 +1384,7 @@ Udp4InstanceDeliverDgram ( EFI_UDP4_COMPLETION_TOKEN *Token; NET_BUF *Dup; EFI_UDP4_RECEIVE_DATA *RxData; + EFI_TPL OldTpl; if (!NetListIsEmpty (&Instance->RcvdDgramQue) && !NetMapIsEmpty (&Instance->RxTokens)) { @@ -1401,7 +1403,7 @@ Udp4InstanceDeliverDgram ( NetbufFree (Wrap->Packet); Wrap->Packet = Dup; - } + } NetListRemoveHead (&Instance->RcvdDgramQue); @@ -1422,9 +1424,11 @@ Udp4InstanceDeliverDgram ( Token->Status = EFI_SUCCESS; Token->Packet.RxData = &Wrap->RxData; - gBS->SignalEvent (Token->Event); - + OldTpl = NET_RAISE_TPL (NET_TPL_RECYCLE); NetListInsertTail (&Instance->DeliveredDgramQue, &Wrap->Link); + NET_RESTORE_TPL (OldTpl); + + gBS->SignalEvent (Token->Event); } } diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h index bdc855b52c..2cf4a541b4 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h @@ -261,8 +261,8 @@ Udp4LeaveGroup ( ); VOID -Udp4FlushRxData ( - IN NET_LIST_ENTRY *RcvdDgramQue +Udp4FlushRcvdDgram ( + IN UDP4_INSTANCE_DATA *Instance ); EFI_STATUS diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c index abb2e6fcef..93a5cee35b 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c @@ -180,7 +180,7 @@ Udp4Configure ( StationAddress = NTOHL (StationAddress); SubnetMask = NTOHL (SubnetMask); RemoteAddress = NTOHL (RemoteAddress); - + if (!UdpConfigData->UseDefaultAddress && (!IP4_IS_VALID_NETMASK (SubnetMask) || @@ -284,12 +284,14 @@ Udp4Configure ( // // Cancel all the user tokens. // - Udp4InstanceCancelToken (Instance, NULL); + Instance->Udp4Proto.Cancel (&Instance->Udp4Proto, NULL); // // Remove the buffered RxData for this instance. // - Udp4FlushRxData (&Instance->RcvdDgramQue); + Udp4FlushRcvdDgram (Instance); + +////bugbug ASSERT (NetListIsEmpty (&Instance->DeliveredDgramQue)); } Udp4SetVariableData (Instance->Udp4Service); @@ -772,7 +774,8 @@ Udp4Receive ( // Status = NetMapInsertTail (&Instance->RxTokens, Token, NULL); if (EFI_ERROR (Status)) { - return EFI_NOT_READY; + Status = EFI_NOT_READY; + goto ON_EXIT; } // @@ -785,6 +788,11 @@ Udp4Receive ( // Udp4InstanceDeliverDgram (Instance); + // + // Dispatch the DPC queued by the NotifyFunction of Token->Event. + // + NetLibDispatchDpc (); + ON_EXIT: NET_RESTORE_TPL (OldTpl); @@ -847,6 +855,11 @@ Udp4Cancel ( // Status = Udp4InstanceCancelToken (Instance, Token); + // + // Dispatch the DPC queued by the NotifyFunction of the canceled token's events. + // + NetLibDispatchDpc (); + NET_RESTORE_TPL (OldTpl); return Status; diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc index 940e6f24a1..0e589ad8db 100644 --- a/Nt32Pkg/Nt32Pkg.dsc +++ b/Nt32Pkg/Nt32Pkg.dsc @@ -199,6 +199,7 @@ NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf + DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf [LibraryClasses.common.UEFI_APPLICATION] DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf @@ -451,6 +452,7 @@ # Network stack drivers # To test network drivers, need network Io driver(SnpNt32Io.dll), please refer to NETWORK-IO Subproject. # + MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf -- 2.39.2