1. Add DPC protocol and DpcLib library in MdeModulePkg.
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 20 Nov 2007 05:42:23 +0000 (05:42 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 20 Nov 2007 05:42:23 +0000 (05:42 +0000)
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

48 files changed:
MdeModulePkg/Include/Library/DpcLib.h [new file with mode: 0644]
MdeModulePkg/Include/Library/NetLib.h
MdeModulePkg/Include/Protocol/Dpc.h [new file with mode: 0644]
MdeModulePkg/Library/DxeDpcLib/DpcLib.c [new file with mode: 0644]
MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf [new file with mode: 0644]
MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c
MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.c
MdeModulePkg/MdeModulePkg.dec
MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c
MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c
MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h
MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.c
MdeModulePkg/Universal/Network/DpcDxe/Dpc.c [new file with mode: 0644]
MdeModulePkg/Universal/Network/DpcDxe/Dpc.h [new file with mode: 0644]
MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf [new file with mode: 0644]
MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c
MdeModulePkg/Universal/Network/Ip4ConfigDxe/NicIp4Variable.h
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Igmp.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c
MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h
MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c
MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h
MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Input.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Option.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Output.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Timer.c
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c
Nt32Pkg/Nt32Pkg.dsc

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