]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c
1. Add DPC protocol and DpcLib library in MdeModulePkg.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4Dxe / Ip4If.c
index bfb9616c2d830b55988823873bdf5cc1b35c5ed6..eaed123b84cf54c7d0b5193832373eccdce5e4e8 100644 (file)
@@ -29,6 +29,13 @@ Abstract:
 //\r
 STATIC EFI_MAC_ADDRESS  mZeroMacAddress;\r
 \r
+STATIC\r
+VOID\r
+EFIAPI\r
+Ip4OnFrameSentDpc (\r
+  IN VOID                   *Context\r
+  );\r
+\r
 STATIC\r
 VOID\r
 EFIAPI\r
@@ -37,6 +44,13 @@ Ip4OnFrameSent (
   IN VOID                   *Context\r
   );\r
 \r
+STATIC\r
+VOID\r
+EFIAPI\r
+Ip4OnArpResolvedDpc (\r
+  IN VOID                   *Context\r
+  );\r
+\r
 STATIC\r
 VOID\r
 EFIAPI\r
@@ -45,6 +59,13 @@ Ip4OnArpResolved (
   IN VOID                   *Context\r
   );\r
 \r
+STATIC\r
+VOID\r
+EFIAPI\r
+Ip4OnFrameReceivedDpc (\r
+  IN VOID                   *Context\r
+  );\r
+\r
 STATIC\r
 VOID\r
 EFIAPI\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