]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.c
1. Add DPC protocol and DpcLib library in MdeModulePkg.
[mirror_edk2.git] / MdeModulePkg / Library / DxeUdpIoLib / DxeUdpIoLib.c
index 3a0075c4672f415b98a3dd832d8c90c452561996..b1329f860425bb26ef22922b0a9183d0b83964bb 100644 (file)
@@ -30,6 +30,14 @@ Abstract:
 #include <Library/DebugLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
+#include <library/BaseMemoryLib.h>\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+UdpIoOnDgramSentDpc (\r
+  IN VOID                   *Context\r
+  );\r
 \r
 STATIC\r
 VOID\r
@@ -77,6 +85,7 @@ UdpIoWrapTx (
   EFI_UDP4_TRANSMIT_DATA    *UdpTxData;\r
   EFI_STATUS                Status;\r
   UINT32                    Count;\r
+  IP4_ADDR                  Ip;\r
 \r
   Token = NetAllocatePool (sizeof (UDP_TX_TOKEN) +\r
                            sizeof (EFI_UDP4_FRAGMENT_DATA) * (Packet->BlockOpNum - 1));\r
@@ -98,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
@@ -116,15 +125,21 @@ UdpIoWrapTx (
   UdpTxData->GatewayAddress = NULL;\r
 \r
   if (EndPoint != NULL) {\r
-    EFI_IP4 (Token->UdpSession.SourceAddress)      = HTONL (EndPoint->LocalAddr);\r
-    EFI_IP4 (Token->UdpSession.DestinationAddress) = HTONL (EndPoint->RemoteAddr);\r
-    Token->UdpSession.SourcePort                   = EndPoint->LocalPort;\r
-    Token->UdpSession.DestinationPort              = EndPoint->RemotePort;\r
-    UdpTxData->UdpSessionData                      = &Token->UdpSession;\r
+    Ip = HTONL (EndPoint->LocalAddr);\r
+    NetCopyMem (&Token->UdpSession.SourceAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+\r
+    Ip = HTONL (EndPoint->RemoteAddr);\r
+    NetCopyMem (&Token->UdpSession.DestinationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+\r
+    Token->UdpSession.SourcePort      = EndPoint->LocalPort;\r
+    Token->UdpSession.DestinationPort = EndPoint->RemotePort;\r
+    UdpTxData->UdpSessionData         = &Token->UdpSession;\r
   }\r
 \r
   if (Gateway != 0) {\r
-    EFI_IP4 (Token->Gateway)  = HTONL (Gateway);\r
+    Ip = HTONL (Gateway);\r
+    NetCopyMem (&Token->Gateway, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+\r
     UdpTxData->GatewayAddress = &Token->Gateway;\r
   }\r
 \r
@@ -194,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
@@ -356,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
@@ -392,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
@@ -414,7 +424,10 @@ UdpIoFreePort (
     UdpIo->UdpHandle\r
     );\r
 \r
-  NetListRemoveEntry (&UdpIo->Link);\r
+  if (!IsListEmpty(&UdpIo->Link)) {\r
+    NetListRemoveEntry (&UdpIo->Link);\r
+  }\r
+\r
   NetFreePool (UdpIo);\r
   return EFI_SUCCESS;\r
 }\r
@@ -443,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
@@ -457,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
@@ -466,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
@@ -482,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
@@ -518,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
@@ -598,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
@@ -613,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
@@ -640,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
@@ -663,19 +701,58 @@ 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
-  Points.LocalAddr  = EFI_NTOHL (UdpSession->DestinationAddress);\r
   Points.LocalPort  = UdpSession->DestinationPort;\r
-  Points.RemoteAddr = EFI_NTOHL (UdpSession->SourceAddress);\r
   Points.RemotePort = UdpSession->SourcePort;\r
 \r
+  NetCopyMem (&Points.LocalAddr, &UdpSession->DestinationAddress, sizeof (IP4_ADDR));\r
+  NetCopyMem (&Points.RemoteAddr, &UdpSession->SourceAddress, sizeof (IP4_ADDR));\r
+  Points.LocalAddr  = NTOHL (Points.LocalAddr);\r
+  Points.RemoteAddr = NTOHL (Points.RemoteAddr);\r
+\r
   Token->CallBack (Netbuf, &Points, EFI_SUCCESS, Token->Context);\r
+}\r
 \r
-ON_EXIT:\r
-  return;\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
+  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
@@ -715,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