]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/SnpDxe/Snp.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Snp.c
index f1fea0cff44f923fef3e3330bacbfd016198d7a2..a23af05078bc8939c7ea42dc83f2d26ad9489888 100644 (file)
@@ -1,32 +1,18 @@
 /** @file\r
   Implementation of driver entry point and driver binding protocol.\r
 \r
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed\r
-and made available under the terms and conditions of the BSD License which\r
-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
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "Snp.h"\r
 \r
-//\r
-//  Module global variables needed to support undi 3.0 interface\r
-//\r
-EFI_PCI_IO_PROTOCOL         *mPciIo;\r
-V2P                         *mV2p = NULL; // undi3.0 map_list head\r
-// End Global variables\r
-//\r
-\r
 /**\r
   One notified function to stop UNDI device when gBS->ExitBootServices() called.\r
 \r
   @param  Event                   Pointer to this event\r
-  @param  Context                 Event hanlder private data\r
+  @param  Context                 Event handler private data\r
 \r
 **/\r
 VOID\r
@@ -258,7 +244,7 @@ Done:
                                device to start.\r
 \r
   @retval EFI_SUCCESS          This driver is added to ControllerHandle\r
-  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle\r
+  @retval EFI_DEVICE_ERROR     This driver could not be started due to a device error\r
   @retval other                This driver does not support this device\r
 \r
 **/\r
@@ -277,11 +263,12 @@ SimpleNetworkDriverStart (
   SNP_DRIVER                                *Snp;\r
   VOID                                      *Address;\r
   EFI_HANDLE                                Handle;\r
-  PXE_PCI_CONFIG_INFO                       ConfigInfo;\r
-  PCI_TYPE00                                *ConfigHeader;\r
-  UINT32                                    *TempBar;\r
   UINT8                                     BarIndex;\r
   PXE_STATFLAGS                             InitStatFlags;\r
+  EFI_PCI_IO_PROTOCOL                       *PciIo;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR         *BarDesc;\r
+  BOOLEAN                                   FoundIoBar;\r
+  BOOLEAN                                   FoundMemoryBar;\r
 \r
   DEBUG ((EFI_D_NET, "\nSnpNotifyNetworkInterfaceIdentifier()  "));\r
 \r
@@ -311,7 +298,7 @@ SimpleNetworkDriverStart (
   Status = gBS->OpenProtocol (\r
                   Handle,\r
                   &gEfiPciIoProtocolGuid,\r
-                  (VOID **) &mPciIo,\r
+                  (VOID **) &PciIo,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -367,14 +354,14 @@ SimpleNetworkDriverStart (
   // OK, we like this UNDI, and we know snp is not already there on this handle\r
   // Allocate and initialize a new simple network protocol structure.\r
   //\r
-  Status = mPciIo->AllocateBuffer (\r
-                        mPciIo,\r
-                        AllocateAnyPages,\r
-                        EfiBootServicesData,\r
-                        SNP_MEM_PAGES (sizeof (SNP_DRIVER)),\r
-                        &Address,\r
-                        0\r
-                        );\r
+  Status = PciIo->AllocateBuffer (\r
+                    PciIo,\r
+                    AllocateAnyPages,\r
+                    EfiBootServicesData,\r
+                    SNP_MEM_PAGES (sizeof (SNP_DRIVER)),\r
+                    &Address,\r
+                    0\r
+                    );\r
 \r
   if (Status != EFI_SUCCESS) {\r
     DEBUG ((EFI_D_NET, "\nCould not allocate SNP_DRIVER structure.\n"));\r
@@ -385,7 +372,7 @@ SimpleNetworkDriverStart (
 \r
   ZeroMem (Snp, sizeof (SNP_DRIVER));\r
 \r
-  Snp->PciIo      = mPciIo;\r
+  Snp->PciIo      = PciIo;\r
   Snp->Signature  = SNP_DRIVER_SIGNATURE;\r
 \r
   EfiInitializeLock (&Snp->Lock, TPL_NOTIFY);\r
@@ -411,7 +398,20 @@ SimpleNetworkDriverStart (
   Snp->TxRxBufferSize     = 0;\r
   Snp->TxRxBuffer         = NULL;\r
 \r
-  Snp->IfNum              = Nii->IfNum;\r
+  Snp->RecycledTxBuf = AllocatePool (sizeof (UINT64) * SNP_TX_BUFFER_INCREASEMENT);\r
+  if (Snp->RecycledTxBuf == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Error_DeleteSNP;\r
+  }\r
+  Snp->MaxRecycledTxBuf    = SNP_TX_BUFFER_INCREASEMENT;\r
+  Snp->RecycledTxBufCount  = 0;\r
+\r
+  if (Nii->Revision >= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION) {\r
+    Snp->IfNum = Nii->IfNum;\r
+\r
+  } else {\r
+    Snp->IfNum = (UINT8) (Nii->IfNum & 0xFF);\r
+  }\r
 \r
   if ((Pxe->hw.Implementation & PXE_ROMID_IMP_HW_UNDI) != 0) {\r
     Snp->IsSwUndi             = FALSE;\r
@@ -441,14 +441,14 @@ SimpleNetworkDriverStart (
   // -it is OK to allocate one global set of CPB, DB pair for each UNDI\r
   // interface as EFI does not multi-task and so SNP will not be re-entered!\r
   //\r
-  Status = mPciIo->AllocateBuffer (\r
-                        mPciIo,\r
-                        AllocateAnyPages,\r
-                        EfiBootServicesData,\r
-                        SNP_MEM_PAGES (4096),\r
-                        &Address,\r
-                        0\r
-                        );\r
+  Status = PciIo->AllocateBuffer (\r
+                    PciIo,\r
+                    AllocateAnyPages,\r
+                    EfiBootServicesData,\r
+                    SNP_MEM_PAGES (4096),\r
+                    &Address,\r
+                    0\r
+                    );\r
 \r
   if (Status != EFI_SUCCESS) {\r
     DEBUG ((EFI_D_NET, "\nCould not allocate CPB and DB structures.\n"));\r
@@ -459,19 +459,44 @@ SimpleNetworkDriverStart (
   Snp->Db   = (VOID *) ((UINTN) Address + 2048);\r
 \r
   //\r
-  // PxeStart call is going to give the callback functions to UNDI, these callback\r
-  // functions use the BarIndex values from the snp structure, so these must be initialized\r
-  // with default values before doing a PxeStart. The correct values can be obtained after\r
-  // getting the config information from UNDI\r
+  // Find the correct BAR to do IO.\r
+  //\r
+  // Enumerate through the PCI BARs for the device to determine which one is\r
+  // the IO BAR.  Save the index of the BAR into the adapter info structure.\r
+  // for regular 32bit BARs, 0 is memory mapped, 1 is io mapped\r
   //\r
   Snp->MemoryBarIndex = 0;\r
   Snp->IoBarIndex     = 1;\r
+  FoundMemoryBar      = FALSE;\r
+  FoundIoBar          = FALSE;\r
+  for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {\r
+    Status = PciIo->GetBarAttributes (\r
+                      PciIo,\r
+                      BarIndex,\r
+                      NULL,\r
+                      (VOID**) &BarDesc\r
+                      );\r
+    if (Status == EFI_UNSUPPORTED) {\r
+      continue;\r
+    } else if (EFI_ERROR (Status)) {\r
+      goto Error_DeleteSNP;\r
+    }\r
+\r
+    if ((!FoundMemoryBar) && (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM)) {\r
+      Snp->MemoryBarIndex = BarIndex;\r
+      FoundMemoryBar      = TRUE;\r
+    } else if ((!FoundIoBar) && (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_IO)) {\r
+      Snp->IoBarIndex = BarIndex;\r
+      FoundIoBar      = TRUE;\r
+    }\r
+\r
+    FreePool (BarDesc);\r
+\r
+    if (FoundMemoryBar && FoundIoBar) {\r
+      break;\r
+    }\r
+  }\r
 \r
-  //\r
-  // we need the undi init information many times in this snp code, just get it\r
-  // once here and store it in the snp driver structure. to get Init Info\r
-  // from UNDI we have to start undi first.\r
-  //\r
   Status = PxeStart (Snp);\r
 \r
   if (Status != EFI_SUCCESS) {\r
@@ -508,57 +533,6 @@ SimpleNetworkDriverStart (
     goto Error_DeleteSNP;\r
   }\r
 \r
-  Snp->Cdb.OpCode     = PXE_OPCODE_GET_CONFIG_INFO;\r
-  Snp->Cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;\r
-\r
-  Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;\r
-  Snp->Cdb.CPBaddr    = PXE_DBADDR_NOT_USED;\r
-\r
-  Snp->Cdb.DBsize     = (UINT16) sizeof (ConfigInfo);\r
-  Snp->Cdb.DBaddr     = (UINT64)(UINTN) &ConfigInfo;\r
-\r
-  Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;\r
-  Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;\r
-\r
-  Snp->Cdb.IFnum      = Snp->IfNum;\r
-  Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;\r
-\r
-  DEBUG ((EFI_D_NET, "\nSnp->undi.get_config_info()  "));\r
-\r
-  (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
-\r
-  if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
-    DEBUG ((EFI_D_NET, "\nSnp->undi.config_info()  %xh:%xh\n", Snp->Cdb.StatFlags, Snp->Cdb.StatCode));\r
-    PxeStop (Snp);\r
-    goto Error_DeleteSNP;\r
-  }\r
-  //\r
-  // Find the correct BAR to do IO.\r
-  //\r
-  //\r
-  // Enumerate through the PCI BARs for the device to determine which one is\r
-  // the IO BAR.  Save the index of the BAR into the adapter info structure.\r
-  // for  regular 32bit BARs, 0 is memory mapped, 1 is io mapped\r
-  //\r
-  ConfigHeader  = (PCI_TYPE00 *) &ConfigInfo.Config.Byte[0];\r
-  TempBar       = (UINT32 *) &ConfigHeader->Device.Bar[0];\r
-  for (BarIndex = 0; BarIndex <= 5; BarIndex++) {\r
-    if ((*TempBar & PCI_BAR_MEM_MASK) == PCI_BAR_MEM_64BIT) {\r
-      //\r
-      // This is a 64-bit memory bar, skip this and the\r
-      // next bar as well.\r
-      //\r
-      TempBar++;\r
-    }\r
-\r
-    if ((*TempBar & PCI_BAR_IO_MASK) == PCI_BAR_IO_MODE) {\r
-      Snp->IoBarIndex = BarIndex;\r
-      break;\r
-    }\r
-\r
-    TempBar++;\r
-  }\r
-\r
   //\r
   //  Initialize simple network protocol mode structure\r
   //\r
@@ -574,12 +548,12 @@ SimpleNetworkDriverStart (
 \r
   switch (InitStatFlags & PXE_STATFLAGS_CABLE_DETECT_MASK) {\r
   case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED:\r
-    Snp->Mode.MediaPresentSupported = TRUE;\r
+    Snp->CableDetectSupported = TRUE;\r
     break;\r
 \r
   case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED:\r
   default:\r
-    Snp->Mode.MediaPresentSupported = FALSE;\r
+    Snp->CableDetectSupported = FALSE;\r
   }\r
 \r
   switch (InitStatFlags & PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK) {\r
@@ -592,6 +566,10 @@ SimpleNetworkDriverStart (
     Snp->MediaStatusSupported = FALSE;\r
   }\r
 \r
+  if (Snp->CableDetectSupported || Snp->MediaStatusSupported) {\r
+    Snp->Mode.MediaPresentSupported = TRUE;\r
+  }\r
+\r
   if ((Pxe->hw.Implementation & PXE_ROMID_IMP_STATION_ADDR_SETTABLE) != 0) {\r
     Snp->Mode.MacAddressChangeable = TRUE;\r
   } else {\r
@@ -698,19 +676,23 @@ SimpleNetworkDriverStart (
     return Status;\r
   }\r
 \r
-  Status = mPciIo->FreeBuffer (\r
-                        mPciIo,\r
-                        SNP_MEM_PAGES (4096),\r
-                        Snp->Cpb\r
-                        );\r
+  PciIo->FreeBuffer (\r
+           PciIo,\r
+           SNP_MEM_PAGES (4096),\r
+           Snp->Cpb\r
+           );\r
 \r
 Error_DeleteSNP:\r
 \r
-  mPciIo->FreeBuffer (\r
-                mPciIo,\r
-                SNP_MEM_PAGES (sizeof (SNP_DRIVER)),\r
-                Snp\r
-                );\r
+  if (Snp->RecycledTxBuf != NULL) {\r
+    FreePool (Snp->RecycledTxBuf);\r
+  }\r
+\r
+  PciIo->FreeBuffer (\r
+           PciIo,\r
+           SNP_MEM_PAGES (sizeof (SNP_DRIVER)),\r
+           Snp\r
+           );\r
 NiiError:\r
   gBS->CloseProtocol (\r
         Controller,\r
@@ -726,6 +708,13 @@ NiiError:
         Controller\r
         );\r
 \r
+  //\r
+  // If we got here that means we are in error state.\r
+  //\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -759,6 +748,7 @@ SimpleNetworkDriverStop (
   EFI_STATUS                  Status;\r
   EFI_SIMPLE_NETWORK_PROTOCOL *SnpProtocol;\r
   SNP_DRIVER                  *Snp;\r
+  EFI_PCI_IO_PROTOCOL         *PciIo;\r
 \r
   //\r
   // Get our context back.\r
@@ -810,17 +800,20 @@ SimpleNetworkDriverStop (
   PxeShutdown (Snp);\r
   PxeStop (Snp);\r
 \r
-  mPciIo->FreeBuffer (\r
-                mPciIo,\r
-                SNP_MEM_PAGES (4096),\r
-                Snp->Cpb\r
-                );\r
+  FreePool (Snp->RecycledTxBuf);\r
 \r
-  mPciIo->FreeBuffer (\r
-                mPciIo,\r
-                SNP_MEM_PAGES (sizeof (SNP_DRIVER)),\r
-                Snp\r
-                );\r
+  PciIo = Snp->PciIo;\r
+  PciIo->FreeBuffer (\r
+           PciIo,\r
+           SNP_MEM_PAGES (4096),\r
+           Snp->Cpb\r
+           );\r
+\r
+  PciIo->FreeBuffer (\r
+           PciIo,\r
+           SNP_MEM_PAGES (sizeof (SNP_DRIVER)),\r
+           Snp\r
+           );\r
 \r
   return Status;\r
 }\r
@@ -837,159 +830,6 @@ EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = {
   NULL\r
 };\r
 \r
-\r
-/**\r
-  This routine maps the given CPU address to a Device address. It creates a\r
-  an entry in the map list with the virtual and physical addresses and the\r
-  un map cookie.\r
-\r
-  @param  V2p                  pointer to return a map list node pointer.\r
-  @param  Type                 the direction in which the data flows from the given\r
-                               virtual address device->cpu or cpu->device or both\r
-                               ways.\r
-  @param  VirtualAddress       virtual address (or CPU address) to be mapped.\r
-  @param  BufferSize           size of the buffer to be mapped.\r
-\r
-  @retval EFI_SUCEESS           routine has completed the mapping.\r
-  @retval EFI_INVALID_PARAMETER invalid parameter.\r
-  @retval EFI_OUT_OF_RESOURCES  out of resource.\r
-  @retval other                 error as indicated.\r
-\r
-**/\r
-EFI_STATUS\r
-AddV2P (\r
-  IN OUT V2P                    **V2p,\r
-  EFI_PCI_IO_PROTOCOL_OPERATION Type,\r
-  VOID                          *VirtualAddress,\r
-  UINTN                         BufferSize\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  if ((V2p == NULL) || (VirtualAddress == NULL) || (BufferSize == 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  *V2p = AllocatePool (sizeof (V2P));\r
-  if (*V2p == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Status = mPciIo->Map (\r
-                     mPciIo,\r
-                     Type,\r
-                     VirtualAddress,\r
-                     &BufferSize,\r
-                     &(*V2p)->PhysicalAddress,\r
-                     &(*V2p)->Unmap\r
-                     );\r
-  if (Status != EFI_SUCCESS) {\r
-    FreePool (*V2p);\r
-    return Status;\r
-  }\r
-  (*V2p)->VirtualAddress = VirtualAddress;\r
-  (*V2p)->BufferSize     = BufferSize;\r
-  (*V2p)->Next           = mV2p;\r
-  mV2p                   = *V2p;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  This routine searches the linked list of mapped address nodes (for undi3.0\r
-  interface) to find the node that corresponds to the given virtual address and\r
-  returns a pointer to that node.\r
-\r
-  @param  V2p                  pointer to return a map list node pointer.\r
-  @param  VirtualAddr          virtual address (or CPU address) to be searched in\r
-                               the map list\r
-\r
-  @retval EFI_SUCEESS          A match was found.\r
-  @retval Other                A match cannot be found.\r
-\r
-**/\r
-EFI_STATUS\r
-FindV2p (\r
-  V2P          **V2p,\r
-  VOID         *VirtualAddr\r
-  )\r
-{\r
-  V2P    *Ptr;\r
-\r
-  if (V2p == NULL || VirtualAddr == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  for (Ptr = mV2p; Ptr != NULL; Ptr = Ptr->Next) {\r
-    if (Ptr->VirtualAddress == VirtualAddr) {\r
-      *V2p = Ptr;\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
-  Unmap the given virtual address and free the memory allocated for the map list\r
-  node corresponding to that address.\r
-\r
-  @param  VirtualAddress       virtual address (or CPU address) to be unmapped.\r
-\r
-  @retval EFI_SUCEESS          Successfully unmapped.\r
-  @retval Other                Other errors as indicated.\r
-\r
-**/\r
-EFI_STATUS\r
-DelV2p (\r
-  VOID *VirtualAddress\r
-  )\r
-{\r
-  V2P           *Current;\r
-  V2P           *Next;\r
-  EFI_STATUS    Status;\r
-\r
-  if (VirtualAddress == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (mV2p == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-  //\r
-  // Is our node at the head of the list??\r
-  //\r
-  if ((Current = mV2p)->VirtualAddress == VirtualAddress) {\r
-    mV2p    = mV2p->Next;\r
-\r
-    Status  = mPciIo->Unmap (mPciIo, Current->Unmap);\r
-\r
-    FreePool (Current);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "Unmap failed with status = %r\n", Status));\r
-    }\r
-    return Status;\r
-  }\r
-\r
-  for (; Current->Next != NULL; Current = Next) {\r
-    if ((Next = Current->Next)->VirtualAddress == VirtualAddress) {\r
-      Current->Next = Next->Next;\r
-      Status  = mPciIo->Unmap (mPciIo, Next->Unmap);\r
-      FreePool (Next);\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_ERROR, "Unmap failed with status = %r\n", Status));\r
-      }\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
 /**\r
   The SNP driver entry point.\r
 \r