]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / MnpDxe / MnpMain.c
index 02c0065c34c108b135d651103b2b2f43d02700b8..d96178a1d9943a3b835c030a38be35a6d4b21094 100644 (file)
@@ -1,82 +1,79 @@
 /** @file\r
-\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
-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
-  MnpMain.c\r
-\r
-Abstract:\r
-\r
   Implementation of Managed Network Protocol public services.\r
 \r
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/BaseLib.h>\r
-\r
 #include "MnpImpl.h"\r
 \r
-\r
 /**\r
-  Get configuration data of this instance.\r
-\r
-  @param  This                   Pointer to the Managed Network Protocol.\r
-  @param  MnpConfigData          Pointer to strorage for MNP operational\r
-                                 parameters.\r
-  @param  SnpModeData            Pointer to strorage for SNP operational\r
-                                 parameters.\r
-\r
-  @retval EFI_SUCCESS            The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  This is NULL.\r
-  @retval EFI_NOT_STARTED        This MNP child driver instance has not been\r
-                                 configured The default values are returned in\r
-                                 MnpConfigData if it is not NULL.\r
+  Returns the operational parameters for the current MNP child driver. May also\r
+  support returning the underlying SNP driver mode data.\r
+\r
+  The GetModeData() function is used to read the current mode data (operational\r
+  parameters) from the MNP or the underlying SNP.\r
+\r
+  @param[in]  This          Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.\r
+  @param[out] MnpConfigData Pointer to storage for MNP operational parameters. Type\r
+                            EFI_MANAGED_NETWORK_CONFIG_DATA is defined in "Related\r
+                            Definitions" below.\r
+  @param[out] SnpModeData   Pointer to storage for SNP operational parameters. This\r
+                            feature may be unsupported. Type EFI_SIMPLE_NETWORK_MODE\r
+                            is defined in the EFI_SIMPLE_NETWORK_PROTOCOL.\r
+\r
+  @retval EFI_SUCCESS           The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER This is NULL.\r
+  @retval EFI_UNSUPPORTED       The requested feature is unsupported in this\r
+                                MNP implementation.\r
+  @retval EFI_NOT_STARTED       This MNP child driver instance has not been\r
+                                configured. The default values are returned in\r
+                                MnpConfigData if it is not NULL.\r
+  @retval Others                The mode data could not be read.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpGetModeData (\r
-  IN  EFI_MANAGED_NETWORK_PROTOCOL     *This,\r
-  OUT EFI_MANAGED_NETWORK_CONFIG_DATA  *MnpConfigData OPTIONAL,\r
-  OUT EFI_SIMPLE_NETWORK_MODE          *SnpModeData OPTIONAL\r
+  IN     EFI_MANAGED_NETWORK_PROTOCOL      *This,\r
+     OUT EFI_MANAGED_NETWORK_CONFIG_DATA   *MnpConfigData OPTIONAL,\r
+     OUT EFI_SIMPLE_NETWORK_MODE           *SnpModeData OPTIONAL\r
   )\r
 {\r
   MNP_INSTANCE_DATA           *Instance;\r
   EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
   EFI_TPL                     OldTpl;\r
   EFI_STATUS                  Status;\r
+  UINT32                      InterruptStatus;\r
 \r
   if (This == NULL) {\r
-\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   Instance = MNP_INSTANCE_DATA_FROM_THIS (This);\r
 \r
-  OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if (MnpConfigData != NULL) {\r
     //\r
     // Copy the instance configuration data.\r
     //\r
-    *MnpConfigData = Instance->ConfigData;\r
+    CopyMem (MnpConfigData, &Instance->ConfigData, sizeof (*MnpConfigData));\r
   }\r
 \r
   if (SnpModeData != NULL) {\r
     //\r
     // Copy the underlayer Snp mode data.\r
     //\r
-    Snp           = Instance->MnpServiceData->Snp;\r
-    *SnpModeData  = *(Snp->Mode);\r
+    Snp = Instance->MnpServiceData->MnpDeviceData->Snp;\r
+\r
+    //\r
+    // Upon successful return of GetStatus(), the Snp->Mode->MediaPresent\r
+    // will be updated to reflect any change of media status\r
+    //\r
+    Snp->GetStatus (Snp, &InterruptStatus, NULL);\r
+    CopyMem (SnpModeData, Snp->Mode, sizeof (*SnpModeData));\r
   }\r
 \r
   if (!Instance->Configured) {\r
@@ -85,38 +82,69 @@ MnpGetModeData (
     Status = EFI_SUCCESS;\r
   }\r
 \r
-  NET_RESTORE_TPL (OldTpl);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r
 \r
 \r
 /**\r
-  Set or clear the operational parameters for the MNP child driver.\r
-\r
-  @param  This                   Pointer to the Managed Network Protocol.\r
-  @param  MnpConfigData          Pointer to the configuration data that will be\r
-                                 assigned to the MNP child driver instance. If\r
-                                 NULL, the MNP child driver instance is reset to\r
-                                 startup defaults and all pending transmit and\r
-                                 receive requests are flushed.\r
+  Sets or clears the operational parameters for the MNP child driver.\r
+\r
+  The Configure() function is used to set, change, or reset the operational\r
+  parameters for the MNP child driver instance. Until the operational parameters\r
+  have been set, no network traffic can be sent or received by this MNP child\r
+  driver instance. Once the operational parameters have been reset, no more\r
+  traffic can be sent or received until the operational parameters have been set\r
+  again.\r
+  Each MNP child driver instance can be started and stopped independently of\r
+  each other by setting or resetting their receive filter settings with the\r
+  Configure() function.\r
+  After any successful call to Configure(), the MNP child driver instance is\r
+  started. The internal periodic timer (if supported) is enabled. Data can be\r
+  transmitted and may be received if the receive filters have also been enabled.\r
+  Note: If multiple MNP child driver instances will receive the same packet\r
+  because of overlapping receive filter settings, then the first MNP child\r
+  driver instance will receive the original packet and additional instances will\r
+  receive copies of the original packet.\r
+  Note: Warning: Receive filter settings that overlap will consume extra\r
+  processor and/or DMA resources and degrade system and network performance.\r
+\r
+  @param[in]  This           Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.\r
+  @param[in]  MnpConfigData  Pointer to configuration data that will be assigned\r
+                             to the MNP child driver instance. If NULL, the MNP\r
+                             child driver instance is reset to startup defaults\r
+                             and all pending transmit and receive requests are\r
+                             flushed. Type EFI_MANAGED_NETWORK_CONFIG_DATA is\r
+                             defined in EFI_MANAGED_NETWORK_PROTOCOL.GetModeData().\r
 \r
   @retval EFI_SUCCESS            The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  One or more parameter is invalid.\r
-  @retval EFI_OUT_OF_RESOURCES   Required system resources (usually memory) could\r
-                                 not be allocated.\r
-  @retval EFI_UNSUPPORTED        EnableReceiveTimestamps is TRUE, this\r
-                                 implementation doesn't support it.\r
-  @retval EFI_DEVICE_ERROR       An unexpected network or system error occurred.\r
-  @retval Other                  The MNP child driver instance has been reset to\r
+  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is\r
+                                 TRUE:\r
+                                 * This is NULL.\r
+                                 * MnpConfigData.ProtocolTypeFilter is not\r
+                                   valid.\r
+                                 The operational data for the MNP child driver\r
+                                 instance is unchanged.\r
+  @retval EFI_OUT_OF_RESOURCES   Required system resources (usually memory)\r
+                                 could not be allocated.\r
+                                 The MNP child driver instance has been reset to\r
+                                 startup defaults.\r
+  @retval EFI_UNSUPPORTED        The requested feature is unsupported in\r
+                                 this [MNP] implementation. The operational data\r
+                                 for the MNP child driver instance is unchanged.\r
+  @retval EFI_DEVICE_ERROR       An unexpected network or system error\r
+                                 occurred. The MNP child driver instance has\r
+                                 been reset to startup defaults.\r
+  @retval Others                 The MNP child driver instance has been reset to\r
                                  startup defaults.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpConfigure (\r
-  IN EFI_MANAGED_NETWORK_PROTOCOL     *This,\r
-  IN EFI_MANAGED_NETWORK_CONFIG_DATA  *MnpConfigData OPTIONAL\r
+  IN EFI_MANAGED_NETWORK_PROTOCOL        *This,\r
+  IN EFI_MANAGED_NETWORK_CONFIG_DATA     *MnpConfigData OPTIONAL\r
   )\r
 {\r
   MNP_INSTANCE_DATA  *Instance;\r
@@ -124,16 +152,16 @@ MnpConfigure (
   EFI_STATUS         Status;\r
 \r
   if ((This == NULL) ||\r
-    ((MnpConfigData != NULL) &&\r
-    (MnpConfigData->ProtocolTypeFilter > 0) &&\r
-    (MnpConfigData->ProtocolTypeFilter <= 1500))) {\r
-\r
+      ((MnpConfigData != NULL) &&\r
+       (MnpConfigData->ProtocolTypeFilter > 0) &&\r
+       (MnpConfigData->ProtocolTypeFilter <= 1500))\r
+     ) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   Instance = MNP_INSTANCE_DATA_FROM_THIS (This);\r
 \r
-  OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if ((MnpConfigData == NULL) && (!Instance->Configured)) {\r
     //\r
@@ -149,68 +177,75 @@ MnpConfigure (
   Status = MnpConfigureInstance (Instance, MnpConfigData);\r
 \r
 ON_EXIT:\r
-  NET_RESTORE_TPL (OldTpl);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r
 \r
 \r
 /**\r
-  Translate a multicast IP address to a multicast hardware (MAC) address.\r
-\r
-  @param  This                   Pointer to the Managed Network Protocol.\r
-  @param  Ipv6Flag               Set to TRUE if IpAddress is an IPv6 multicast\r
-                                 address. Set to FALSE if IpAddress is an IPv4\r
-                                 multicast address.\r
-  @param  IpAddress              Pointer to the multicast IP address to convert.\r
-  @param  MacAddress             Pointer to the resulting multicast MAC address.\r
-\r
-  @retval EFI_SUCCESS            The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  One or more parameter is invalid.\r
-  @retval EFI_NOT_STARTED        This MNP child driver instance has not been\r
-                                 configured.\r
-  @retval EFI_UNSUPPORTED        Ipv6Flag is TRUE, this implementation doesn't\r
-                                 supported it.\r
-  @retval EFI_DEVICE_ERROR       An unexpected network or system error occurred.\r
-  @retval Other                  The address could not be converted.\r
-\r
+  Translates an IP multicast address to a hardware (MAC) multicast address. This\r
+  function may be unsupported in some MNP implementations.\r
+\r
+  The McastIpToMac() function translates an IP multicast address to a hardware\r
+  (MAC) multicast address. This function may be implemented by calling the\r
+  underlying EFI_SIMPLE_NETWORK. MCastIpToMac() function, which may also be\r
+  unsupported in some MNP implementations.\r
+\r
+  @param[in]  This        Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.\r
+  @param[in]  Ipv6Flag    Set to TRUE to if IpAddress is an IPv6 multicast address.\r
+                          Set to FALSE if IpAddress is an IPv4 multicast address.\r
+  @param[in]  IpAddress   Pointer to the multicast IP address (in network byte\r
+                          order) to convert.\r
+  @param[out] MacAddress  Pointer to the resulting multicast MAC address.\r
+\r
+  @retval EFI_SUCCESS           The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER One of the following conditions is TRUE:\r
+                                 * This is NULL.\r
+                                 * IpAddress is NULL.\r
+                                 * IpAddress is not a valid multicast IP\r
+                                   address.\r
+                                 * MacAddress is NULL.\r
+  @retval EFI_NOT_STARTED       This MNP child driver instance has not been\r
+                                configured.\r
+  @retval EFI_UNSUPPORTED       The requested feature is unsupported in this\r
+                                MNP implementation.\r
+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.\r
+  @retval Others                The address could not be converted.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpMcastIpToMac (\r
-  IN  EFI_MANAGED_NETWORK_PROTOCOL  *This,\r
-  IN  BOOLEAN                       Ipv6Flag,\r
-  IN  EFI_IP_ADDRESS                *IpAddress,\r
-  OUT EFI_MAC_ADDRESS               *MacAddress\r
+  IN     EFI_MANAGED_NETWORK_PROTOCOL    *This,\r
+  IN     BOOLEAN                         Ipv6Flag,\r
+  IN     EFI_IP_ADDRESS                  *IpAddress,\r
+     OUT EFI_MAC_ADDRESS                 *MacAddress\r
   )\r
 {\r
   EFI_STATUS                  Status;\r
   MNP_INSTANCE_DATA           *Instance;\r
   EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
   EFI_TPL                     OldTpl;\r
+  EFI_IPv6_ADDRESS            *Ip6Address;\r
 \r
   if ((This == NULL) || (IpAddress == NULL) || (MacAddress == NULL)) {\r
-\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (Ipv6Flag) {\r
-    //\r
-    // Currently IPv6 isn't supported.\r
-    //\r
-    return EFI_UNSUPPORTED;\r
-  }\r
+  Ip6Address = &IpAddress->v6;\r
 \r
-  if (!IP4_IS_MULTICAST (EFI_NTOHL (*IpAddress))) {\r
+  if ((Ipv6Flag && !IP6_IS_MULTICAST (Ip6Address)) ||\r
+      (!Ipv6Flag && !IP4_IS_MULTICAST (EFI_NTOHL (*IpAddress)))\r
+      ) {\r
     //\r
-    // The IPv4 address passed in is not a multicast address.\r
+    // The IP address passed in is not a multicast address.\r
     //\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   Instance = MNP_INSTANCE_DATA_FROM_THIS (This);\r
 \r
-  OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if (!Instance->Configured) {\r
 \r
@@ -218,20 +253,36 @@ MnpMcastIpToMac (
     goto ON_EXIT;\r
   }\r
 \r
-  Snp = Instance->MnpServiceData->Snp;\r
+  Snp = Instance->MnpServiceData->MnpDeviceData->Snp;\r
   ASSERT (Snp != NULL);\r
 \r
+  ZeroMem (MacAddress, sizeof (EFI_MAC_ADDRESS));\r
+\r
   if (Snp->Mode->IfType == NET_IFTYPE_ETHERNET) {\r
-    //\r
-    // Translate the IPv4 address into a multicast MAC address if the NIC is an\r
-    // ethernet NIC.\r
-    //\r
-    MacAddress->Addr[0] = 0x01;\r
-    MacAddress->Addr[1] = 0x00;\r
-    MacAddress->Addr[2] = 0x5E;\r
-    MacAddress->Addr[3] = IpAddress->v4.Addr[1] & 0x7F;\r
-    MacAddress->Addr[4] = IpAddress->v4.Addr[2];\r
-    MacAddress->Addr[5] = IpAddress->v4.Addr[3];\r
+    if (!Ipv6Flag) {\r
+      //\r
+      // Translate the IPv4 address into a multicast MAC address if the NIC is an\r
+      // ethernet NIC according to RFC1112..\r
+      //\r
+      MacAddress->Addr[0] = 0x01;\r
+      MacAddress->Addr[1] = 0x00;\r
+      MacAddress->Addr[2] = 0x5E;\r
+      MacAddress->Addr[3] = (UINT8) (IpAddress->v4.Addr[1] & 0x7F);\r
+      MacAddress->Addr[4] = IpAddress->v4.Addr[2];\r
+      MacAddress->Addr[5] = IpAddress->v4.Addr[3];\r
+    } else {\r
+      //\r
+      // Translate the IPv6 address into a multicast MAC address if the NIC is an\r
+      // ethernet NIC according to RFC2464.\r
+      //\r
+\r
+      MacAddress->Addr[0] = 0x33;\r
+      MacAddress->Addr[1] = 0x33;\r
+      MacAddress->Addr[2] = Ip6Address->Addr[12];\r
+      MacAddress->Addr[3] = Ip6Address->Addr[13];\r
+      MacAddress->Addr[4] = Ip6Address->Addr[14];\r
+      MacAddress->Addr[5] = Ip6Address->Addr[15];\r
+    }\r
 \r
     Status = EFI_SUCCESS;\r
   } else {\r
@@ -247,45 +298,60 @@ MnpMcastIpToMac (
   }\r
 \r
 ON_EXIT:\r
-  NET_RESTORE_TPL (OldTpl);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  Enable or disable receie filters for multicast address.\r
-\r
-  @param  This                   Pointer to the Managed Network Protocol.\r
-  @param  JoinFlag               Set to TRUE to join this multicast group. Set to\r
-                                 FALSE to leave this multicast group.\r
-  @param  MacAddress             Pointer to the multicast MAC group (address) to\r
-                                 join or leave.\r
-\r
-  @retval EFI_SUCCESS            The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  One or more parameter is invalid\r
-  @retval EFI_NOT_STARTED        This MNP child driver instance has not been\r
-                                 configured.\r
-  @retval EFI_ALREADY_STARTED    The supplied multicast group is already joined.\r
-  @retval EFI_NOT_FOUND          The supplied multicast group is not joined.\r
-  @retval EFI_DEVICE_ERROR       An unexpected network or system error occurred.\r
-  @retval Other                  The requested operation could not be completed.\r
-                                 The MNP multicast group settings are unchanged.\r
+  Enables and disables receive filters for multicast address. This function may\r
+  be unsupported in some MNP implementations.\r
+\r
+  The Groups() function only adds and removes multicast MAC addresses from the\r
+  filter list. The MNP driver does not transmit or process Internet Group\r
+  Management Protocol (IGMP) packets. If JoinFlag is FALSE and MacAddress is\r
+  NULL, then all joined groups are left.\r
+\r
+  @param[in]  This        Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.\r
+  @param[in]  JoinFlag    Set to TRUE to join this multicast group.\r
+                          Set to FALSE to leave this multicast group.\r
+  @param[in]  MacAddress  Pointer to the multicast MAC group (address) to join or\r
+                          leave.\r
+\r
+  @retval EFI_SUCCESS           The requested operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
+                                * This is NULL.\r
+                                * JoinFlag is TRUE and MacAddress is NULL.\r
+                                * MacAddress is not a valid multicast MAC\r
+                                  address.\r
+                                * The MNP multicast group settings are\r
+                                  unchanged.\r
+  @retval EFI_NOT_STARTED       This MNP child driver instance has not been\r
+                                configured.\r
+  @retval EFI_ALREADY_STARTED   The supplied multicast group is already joined.\r
+  @retval EFI_NOT_FOUND         The supplied multicast group is not joined.\r
+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.\r
+                                The MNP child driver instance has been reset to\r
+                                startup defaults.\r
+  @retval EFI_UNSUPPORTED       The requested feature is unsupported in this MNP\r
+                                implementation.\r
+  @retval Others                The requested operation could not be completed.\r
+                                The MNP multicast group settings are unchanged.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpGroups (\r
-  IN EFI_MANAGED_NETWORK_PROTOCOL  *This,\r
-  IN BOOLEAN                       JoinFlag,\r
-  IN EFI_MAC_ADDRESS               *MacAddress OPTIONAL\r
+  IN EFI_MANAGED_NETWORK_PROTOCOL    *This,\r
+  IN BOOLEAN                         JoinFlag,\r
+  IN EFI_MAC_ADDRESS                 *MacAddress OPTIONAL\r
   )\r
 {\r
   MNP_INSTANCE_DATA       *Instance;\r
   EFI_SIMPLE_NETWORK_MODE *SnpMode;\r
   MNP_GROUP_CONTROL_BLOCK *GroupCtrlBlk;\r
   MNP_GROUP_ADDRESS       *GroupAddress;\r
-  NET_LIST_ENTRY          *ListEntry;\r
+  LIST_ENTRY              *ListEntry;\r
   BOOLEAN                 AddressExist;\r
   EFI_TPL                 OldTpl;\r
   EFI_STATUS              Status;\r
@@ -298,12 +364,11 @@ MnpGroups (
   }\r
 \r
   Instance  = MNP_INSTANCE_DATA_FROM_THIS (This);\r
-  SnpMode   = Instance->MnpServiceData->Snp->Mode;\r
+  SnpMode   = Instance->MnpServiceData->MnpDeviceData->Snp->Mode;\r
 \r
-  OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if (!Instance->Configured) {\r
-\r
     Status = EFI_NOT_STARTED;\r
     goto ON_EXIT;\r
   }\r
@@ -334,7 +399,7 @@ MnpGroups (
                       CtrlBlkEntry\r
                       );\r
       GroupAddress = GroupCtrlBlk->GroupAddress;\r
-      if (0 == NetCompareMem (\r
+      if (0 == CompareMem (\r
                 MacAddress,\r
                 &GroupAddress->Address,\r
                 SnpMode->HwAddressSize\r
@@ -364,7 +429,7 @@ MnpGroups (
     if (EFI_ERROR (Status)) {\r
       goto ON_EXIT;\r
     }\r
-  } else if (NetListIsEmpty (&Instance->GroupCtrlBlkList)) {\r
+  } else if (IsListEmpty (&Instance->GroupCtrlBlkList)) {\r
     //\r
     // The MacAddress is NULL and there is no configured multicast mac address,\r
     // just return.\r
@@ -378,23 +443,55 @@ MnpGroups (
   Status = MnpGroupOp (Instance, JoinFlag, MacAddress, GroupCtrlBlk);\r
 \r
 ON_EXIT:\r
-  NET_RESTORE_TPL (OldTpl);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  Place an outgoing packet into the transmit queue.\r
-\r
-  @param  This                   Pointer to the Managed Network Protocol.\r
-  @param  Token                  Pointer to a token associated with the transmit\r
-                                 data descriptor.\r
-\r
-  @retval EFI_SUCCESS            The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  One or more parameter is invalid\r
+  Places asynchronous outgoing data packets into the transmit queue.\r
+\r
+  The Transmit() function places a completion token into the transmit packet\r
+  queue. This function is always asynchronous.\r
+  The caller must fill in the Token.Event and Token.TxData fields in the\r
+  completion token, and these fields cannot be NULL. When the transmit operation\r
+  completes, the MNP updates the Token.Status field and the Token.Event is\r
+  signaled.\r
+  Note: There may be a performance penalty if the packet needs to be\r
+  defragmented before it can be transmitted by the network device. Systems in\r
+  which performance is critical should review the requirements and features of\r
+  the underlying communications device and drivers.\r
+\r
+\r
+  @param[in]  This    Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.\r
+  @param[in]  Token   Pointer to a token associated with the transmit data\r
+                      descriptor. Type EFI_MANAGED_NETWORK_COMPLETION_TOKEN\r
+                      is defined in "Related Definitions" below.\r
+\r
+  @retval EFI_SUCCESS            The transmit completion token was cached.\r
   @retval EFI_NOT_STARTED        This MNP child driver instance has not been\r
                                  configured.\r
+  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is\r
+                                 TRUE:\r
+                                 * This is NULL.\r
+                                 * Token is NULL.\r
+                                 * Token.Event is NULL.\r
+                                 * Token.TxData is NULL.\r
+                                 * Token.TxData.DestinationAddress is not\r
+                                   NULL and Token.TxData.HeaderLength is zero.\r
+                                 * Token.TxData.FragmentCount is zero.\r
+                                 * (Token.TxData.HeaderLength +\r
+                                   Token.TxData.DataLength) is not equal to the\r
+                                   sum of the\r
+                                   Token.TxData.FragmentTable[].FragmentLength\r
+                                   fields.\r
+                                 * One or more of the\r
+                                   Token.TxData.FragmentTable[].FragmentLength\r
+                                   fields is zero.\r
+                                 * One or more of the\r
+                                   Token.TxData.FragmentTable[].FragmentBufferfields\r
+                                   is NULL.\r
+                                 * Token.TxData.DataLength is greater than MTU.\r
   @retval EFI_ACCESS_DENIED      The transmit completion token is already in the\r
                                  transmit queue.\r
   @retval EFI_OUT_OF_RESOURCES   The transmit data could not be queued due to a\r
@@ -409,8 +506,8 @@ ON_EXIT:
 EFI_STATUS\r
 EFIAPI\r
 MnpTransmit (\r
-  IN EFI_MANAGED_NETWORK_PROTOCOL          *This,\r
-  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *Token\r
+  IN EFI_MANAGED_NETWORK_PROTOCOL            *This,\r
+  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN    *Token\r
   )\r
 {\r
   EFI_STATUS        Status;\r
@@ -421,13 +518,12 @@ MnpTransmit (
   EFI_TPL           OldTpl;\r
 \r
   if ((This == NULL) || (Token == NULL)) {\r
-\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   Instance = MNP_INSTANCE_DATA_FROM_THIS (This);\r
 \r
-  OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if (!Instance->Configured) {\r
 \r
@@ -449,7 +545,10 @@ MnpTransmit (
   //\r
   // Build the tx packet\r
   //\r
-  MnpBuildTxPacket (MnpServiceData, Token->Packet.TxData, &PktBuf, &PktLen);\r
+  Status = MnpBuildTxPacket (MnpServiceData, Token->Packet.TxData, &PktBuf, &PktLen);\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_EXIT;\r
+  }\r
 \r
   //\r
   //  OK, send the packet synchronously.\r
@@ -457,24 +556,36 @@ MnpTransmit (
   Status = MnpSyncSendPacket (MnpServiceData, PktBuf, PktLen, Token);\r
 \r
 ON_EXIT:\r
-  NET_RESTORE_TPL (OldTpl);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r
 \r
 \r
 /**\r
-  Place an asynchronous receiving request into the receiving queue.\r
+  Places an asynchronous receiving request into the receiving queue.\r
+\r
+  The Receive() function places a completion token into the receive packet\r
+  queue. This function is always asynchronous.\r
+  The caller must fill in the Token.Event field in the completion token, and\r
+  this field cannot be NULL. When the receive operation completes, the MNP\r
+  updates the Token.Status and Token.RxData fields and the Token.Event is\r
+  signaled.\r
 \r
-  @param  This                   Pointer to the EFI_MANAGED_NETWORK_PROTOCOL\r
-                                 instance.\r
-  @param  Token                  Pointer to a token associated with the receive\r
-                                 data descriptor.\r
+  @param[in]  This      Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.\r
+  @param[in]  Token     Pointer to a token associated with the receive\r
+                        data descriptor. Type\r
+                        EFI_MANAGED_NETWORK_COMPLETION_TOKEN is defined in\r
+                        EFI_MANAGED_NETWORK_PROTOCOL.Transmit().\r
 \r
   @retval EFI_SUCCESS            The receive completion token was cached.\r
   @retval EFI_NOT_STARTED        This MNP child driver instance has not been\r
                                  configured.\r
-  @retval EFI_INVALID_PARAMETER  One or more parameter is invalid.\r
+  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is\r
+                                 TRUE:\r
+                                 * This is NULL.\r
+                                 * Token is NULL.\r
+                                 * Token.Event is NULL\r
   @retval EFI_OUT_OF_RESOURCES   The transmit data could not be queued due to a\r
                                  lack of system resources (usually memory).\r
   @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.\r
@@ -489,8 +600,8 @@ ON_EXIT:
 EFI_STATUS\r
 EFIAPI\r
 MnpReceive (\r
-  IN EFI_MANAGED_NETWORK_PROTOCOL          *This,\r
-  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *Token\r
+  IN EFI_MANAGED_NETWORK_PROTOCOL            *This,\r
+  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN    *Token\r
   )\r
 {\r
   EFI_STATUS         Status;\r
@@ -498,16 +609,14 @@ MnpReceive (
   EFI_TPL            OldTpl;\r
 \r
   if ((This == NULL) || (Token == NULL) || (Token->Event == NULL)) {\r
-\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   Instance = MNP_INSTANCE_DATA_FROM_THIS (This);\r
 \r
-  OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if (!Instance->Configured) {\r
-\r
     Status = EFI_NOT_STARTED;\r
     goto ON_EXIT;\r
   }\r
@@ -517,7 +626,6 @@ MnpReceive (
   //\r
   Status = NetMapIterate (&Instance->RxTokenMap, MnpTokenExist, (VOID *) Token);\r
   if (EFI_ERROR (Status)) {\r
-\r
     goto ON_EXIT;\r
   }\r
 \r
@@ -525,46 +633,58 @@ MnpReceive (
   // Insert the Token into the RxTokenMap.\r
   //\r
   Status = NetMapInsertTail (&Instance->RxTokenMap, (VOID *) Token, NULL);\r
-\r
   if (!EFI_ERROR (Status)) {\r
     //\r
     // 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
+    DispatchDpc ();\r
   }\r
 \r
 ON_EXIT:\r
-  NET_RESTORE_TPL (OldTpl);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  Abort a pending transmit or receive request.\r
+  Aborts an asynchronous transmit or receive request.\r
+\r
+  The Cancel() function is used to abort a pending transmit or receive request.\r
+  If the token is in the transmit or receive request queues, after calling this\r
+  function, Token.Status will be set to EFI_ABORTED and then Token.Event will be\r
+  signaled. If the token is not in one of the queues, which usually means that\r
+  the asynchronous operation has completed, this function will not signal the\r
+  token and EFI_NOT_FOUND is returned.\r
 \r
-  @param  This                   Pointer to the EFI_MANAGED_NETWORK_PROTOCOL\r
-                                 instance.\r
-  @param  Token                  Pointer to a token that has been issued by\r
-                                 EFI_MANAGED_NETWORK_PROTOCOL.Transmit() or\r
-                                 EFI_MANAGED_NETWORK_PROTOCOL.Receive(). If NULL,\r
-                                 all pending tokens are aborted.\r
+  @param[in]  This     Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.\r
+  @param[in]  Token    Pointer to a token that has been issued by\r
+                       EFI_MANAGED_NETWORK_PROTOCOL.Transmit() or\r
+                       EFI_MANAGED_NETWORK_PROTOCOL.Receive(). If NULL, all\r
+                       pending tokens are aborted.\r
 \r
   @retval EFI_SUCCESS            The asynchronous I/O request was aborted and\r
-                                 Token->Event was signaled.\r
+                                 Token.Event was signaled. When Token is NULL,\r
+                                 all pending requests were aborted and their\r
+                                 events were signaled.\r
   @retval EFI_NOT_STARTED        This MNP child driver instance has not been\r
                                  configured.\r
   @retval EFI_INVALID_PARAMETER  This is NULL.\r
-  @retval EFI_NOT_FOUND          The asynchronous I/O request was not found in the\r
-                                 transmit or receive queue. It has either completed\r
-                                 or was not issued by Transmit() and Receive().\r
+  @retval EFI_NOT_FOUND          When Token is not NULL, the asynchronous I/O\r
+                                 request was not found in the transmit or\r
+                                 receive queue. It has either completed or was\r
+                                 not issued by Transmit() and Receive().\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpCancel (\r
-  IN EFI_MANAGED_NETWORK_PROTOCOL          *This,\r
-  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *Token OPTIONAL\r
+  IN EFI_MANAGED_NETWORK_PROTOCOL            *This,\r
+  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN    *Token OPTIONAL\r
   )\r
 {\r
   EFI_STATUS         Status;\r
@@ -572,16 +692,14 @@ MnpCancel (
   EFI_TPL            OldTpl;\r
 \r
   if (This == NULL) {\r
-\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   Instance = MNP_INSTANCE_DATA_FROM_THIS (This);\r
 \r
-  OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if (!Instance->Configured) {\r
-\r
     Status = EFI_NOT_STARTED;\r
     goto ON_EXIT;\r
   }\r
@@ -590,40 +708,51 @@ MnpCancel (
   // Iterate the RxTokenMap to cancel the specified Token.\r
   //\r
   Status = NetMapIterate (&Instance->RxTokenMap, MnpCancelTokens, (VOID *) Token);\r
-\r
   if (Token != NULL) {\r
-\r
     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
+  DispatchDpc ();\r
+\r
 ON_EXIT:\r
-  NET_RESTORE_TPL (OldTpl);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  Poll the network interface to do transmit/receive work.\r
-\r
-  @param  This                   Pointer to the EFI_MANAGED_NETWORK_PROTOCOL\r
-                                 instance.\r
-\r
-  @retval EFI_SUCCESS            Incoming or outgoing data was processed.\r
-  @retval EFI_NOT_STARTED        This MNP child driver instance has not been\r
-                                 configured.\r
-  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.\r
-                                 The MNP child driver instance has been reset to\r
-                                 startup defaults.\r
-  @retval EFI_NOT_READY          No incoming or outgoing data was processed.\r
-  @retval EFI_TIMEOUT            Data was dropped out of the transmit and/or\r
-                                 receive queue.\r
+  Polls for incoming data packets and processes outgoing data packets.\r
+\r
+  The Poll() function can be used by network drivers and applications to\r
+  increase the rate that data packets are moved between the communications\r
+  device and the transmit and receive queues.\r
+  Normally, a periodic timer event internally calls the Poll() function. But, in\r
+  some systems, the periodic timer event may not call Poll() fast enough to\r
+  transmit and/or receive all data packets without missing packets. Drivers and\r
+  applications that are experiencing packet loss should try calling the Poll()\r
+  function more often.\r
+\r
+  @param[in]  This         Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.\r
+\r
+  @retval EFI_SUCCESS      Incoming or outgoing data was processed.\r
+  @retval EFI_NOT_STARTED  This MNP child driver instance has not been\r
+                           configured.\r
+  @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The\r
+                           MNP child driver instance has been reset to startup\r
+                           defaults.\r
+  @retval EFI_NOT_READY    No incoming or outgoing data was processed. Consider\r
+                           increasing the polling rate.\r
+  @retval EFI_TIMEOUT      Data was dropped out of the transmit and/or receive\r
+                           queue. Consider increasing the polling rate.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpPoll (\r
-  IN EFI_MANAGED_NETWORK_PROTOCOL  *This\r
+  IN EFI_MANAGED_NETWORK_PROTOCOL    *This\r
   )\r
 {\r
   EFI_STATUS         Status;\r
@@ -636,7 +765,7 @@ MnpPoll (
 \r
   Instance = MNP_INSTANCE_DATA_FROM_THIS (This);\r
 \r
-  OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if (!Instance->Configured) {\r
     Status = EFI_NOT_STARTED;\r
@@ -646,10 +775,15 @@ MnpPoll (
   //\r
   // Try to receive packets.\r
   //\r
-  Status = MnpReceivePacket (Instance->MnpServiceData);\r
+  Status = MnpReceivePacket (Instance->MnpServiceData->MnpDeviceData);\r
+\r
+  //\r
+  // Dispatch the DPC queued by the NotifyFunction of rx token's events.\r
+  //\r
+  DispatchDpc ();\r
 \r
 ON_EXIT:\r
-  NET_RESTORE_TPL (OldTpl);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r