]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/SnpDxe/Snp.c
NetworkPkg: Move Network library and drivers from MdeModulePkg to NetworkPkg
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Snp.c
diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Snp.c b/MdeModulePkg/Universal/Network/SnpDxe/Snp.c
deleted file mode 100644 (file)
index a23af05..0000000
+++ /dev/null
@@ -1,862 +0,0 @@
-/** @file\r
-  Implementation of driver entry point and driver binding protocol.\r
-\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
-  One notified function to stop UNDI device when gBS->ExitBootServices() called.\r
-\r
-  @param  Event                   Pointer to this event\r
-  @param  Context                 Event handler private data\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-SnpNotifyExitBootServices (\r
-  EFI_EVENT Event,\r
-  VOID      *Context\r
-  )\r
-{\r
-  SNP_DRIVER             *Snp;\r
-\r
-  Snp  = (SNP_DRIVER *)Context;\r
-\r
-  //\r
-  // Shutdown and stop UNDI driver\r
-  //\r
-  PxeShutdown (Snp);\r
-  PxeStop (Snp);\r
-}\r
-\r
-/**\r
-  Send command to UNDI. It does nothing currently.\r
-\r
-  @param Cdb   command to be sent to UNDI.\r
-\r
-  @retval EFI_INVALID_PARAMETER  The command is 0.\r
-  @retval EFI_UNSUPPORTED        Default return status because it's not\r
-                                 supported currently.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IssueHwUndiCommand (\r
-  UINT64 Cdb\r
-  )\r
-{\r
-  DEBUG ((EFI_D_ERROR, "\nIssueHwUndiCommand() - This should not be called!"));\r
-\r
-  if (Cdb == 0) {\r
-    return EFI_INVALID_PARAMETER;\r
-\r
-  }\r
-  //\r
-  //  %%TBD - For now, nothing is done.\r
-  //\r
-  return EFI_UNSUPPORTED;\r
-}\r
-\r
-\r
-/**\r
-  Compute 8-bit checksum of a buffer.\r
-\r
-  @param  Buffer               Pointer to buffer.\r
-  @param  Length               Length of buffer in bytes.\r
-\r
-  @return 8-bit checksum of all bytes in buffer, or zero if ptr is NULL or len\r
-          is zero.\r
-\r
-**/\r
-UINT8\r
-Calc8BitCksum (\r
-  VOID  *Buffer,\r
-  UINTN Length\r
-  )\r
-{\r
-  UINT8 *Ptr;\r
-  UINT8 Cksum;\r
-\r
-  Ptr   = Buffer;\r
-  Cksum = 0;\r
-\r
-  if (Ptr == NULL || Length == 0) {\r
-    return 0;\r
-  }\r
-\r
-  while (Length-- != 0) {\r
-    Cksum = (UINT8) (Cksum + *Ptr++);\r
-  }\r
-\r
-  return Cksum;\r
-}\r
-\r
-/**\r
-  Test to see if this driver supports ControllerHandle. This service\r
-  is called by the EFI boot service ConnectController(). In\r
-  order to make drivers as small as possible, there are a few calling\r
-  restrictions for this service. ConnectController() must\r
-  follow these calling restrictions. If any other agent wishes to call\r
-  Supported() it must also follow these calling restrictions.\r
-\r
-  @param  This                Protocol instance pointer.\r
-  @param  ControllerHandle    Handle of device to test.\r
-  @param  RemainingDevicePath Optional parameter use to pick a specific child\r
-                              device to start.\r
-\r
-  @retval EFI_SUCCESS         This driver supports this device.\r
-  @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
-  @retval other               This driver does not support this device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SimpleNetworkDriverSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN EFI_HANDLE                     Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
-  )\r
-{\r
-  EFI_STATUS                                Status;\r
-  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *NiiProtocol;\r
-  PXE_UNDI                                  *Pxe;\r
-\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  NULL,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
-                  (VOID **) &NiiProtocol,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    if (Status == EFI_ALREADY_STARTED) {\r
-      DEBUG ((EFI_D_INFO, "Support(): Already Started. on handle %p\n", Controller));\r
-    }\r
-    return Status;\r
-  }\r
-\r
-  DEBUG ((EFI_D_INFO, "Support(): UNDI3.1 found on handle %p\n", Controller));\r
-\r
-  //\r
-  // check the version, we don't want to connect to the undi16\r
-  //\r
-  if (NiiProtocol->Type != EfiNetworkInterfaceUndi) {\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Done;\r
-  }\r
-  //\r
-  // Check to see if !PXE structure is valid. Paragraph alignment of !PXE structure is required.\r
-  //\r
-  if ((NiiProtocol->Id & 0x0F) != 0) {\r
-    DEBUG ((EFI_D_NET, "\n!PXE structure is not paragraph aligned.\n"));\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Done;\r
-  }\r
-\r
-  Pxe = (PXE_UNDI *) (UINTN) (NiiProtocol->Id);\r
-\r
-  //\r
-  //  Verify !PXE revisions.\r
-  //\r
-  if (Pxe->hw.Signature != PXE_ROMID_SIGNATURE) {\r
-    DEBUG ((EFI_D_NET, "\n!PXE signature is not valid.\n"));\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Done;\r
-  }\r
-\r
-  if (Pxe->hw.Rev < PXE_ROMID_REV) {\r
-    DEBUG ((EFI_D_NET, "\n!PXE.Rev is not supported.\n"));\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Done;\r
-  }\r
-\r
-  if (Pxe->hw.MajorVer < PXE_ROMID_MAJORVER) {\r
-\r
-    DEBUG ((EFI_D_NET, "\n!PXE.MajorVer is not supported.\n"));\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Done;\r
-\r
-  } else if (Pxe->hw.MajorVer == PXE_ROMID_MAJORVER && Pxe->hw.MinorVer < PXE_ROMID_MINORVER) {\r
-    DEBUG ((EFI_D_NET, "\n!PXE.MinorVer is not supported."));\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Done;\r
-  }\r
-  //\r
-  // Do S/W UNDI specific checks.\r
-  //\r
-  if ((Pxe->hw.Implementation & PXE_ROMID_IMP_HW_UNDI) == 0) {\r
-    if (Pxe->sw.EntryPoint < Pxe->sw.Len) {\r
-      DEBUG ((EFI_D_NET, "\n!PXE S/W entry point is not valid."));\r
-      Status = EFI_UNSUPPORTED;\r
-      goto Done;\r
-    }\r
-\r
-    if (Pxe->sw.BusCnt == 0) {\r
-      DEBUG ((EFI_D_NET, "\n!PXE.BusCnt is zero."));\r
-      Status = EFI_UNSUPPORTED;\r
-      goto Done;\r
-    }\r
-  }\r
-\r
-  Status = EFI_SUCCESS;\r
-  DEBUG ((EFI_D_INFO, "Support(): supported on %p\n", Controller));\r
-\r
-Done:\r
-  gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Start this driver on ControllerHandle. This service is called by the\r
-  EFI boot service ConnectController(). In order to make\r
-  drivers as small as possible, there are a few calling restrictions for\r
-  this service. ConnectController() must follow these\r
-  calling restrictions. If any other agent wishes to call Start() it\r
-  must also follow these calling restrictions.\r
-\r
-  @param  This                 Protocol instance pointer.\r
-  @param  ControllerHandle     Handle of device to bind driver to.\r
-  @param  RemainingDevicePath  Optional parameter use to pick a specific child\r
-                               device to start.\r
-\r
-  @retval EFI_SUCCESS          This driver is added to 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
-EFI_STATUS\r
-EFIAPI\r
-SimpleNetworkDriverStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN EFI_HANDLE                     Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
-  )\r
-{\r
-  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;\r
-  EFI_DEVICE_PATH_PROTOCOL                  *NiiDevicePath;\r
-  EFI_STATUS                                Status;\r
-  PXE_UNDI                                  *Pxe;\r
-  SNP_DRIVER                                *Snp;\r
-  VOID                                      *Address;\r
-  EFI_HANDLE                                Handle;\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
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &NiiDevicePath,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = gBS->LocateDevicePath (\r
-                  &gEfiPciIoProtocolGuid,\r
-                  &NiiDevicePath,\r
-                  &Handle\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = gBS->OpenProtocol (\r
-                  Handle,\r
-                  &gEfiPciIoProtocolGuid,\r
-                  (VOID **) &PciIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Get the NII interface.\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
-                  (VOID **) &Nii,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiDevicePathProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
-    return Status;\r
-  }\r
-\r
-  DEBUG ((EFI_D_INFO, "Start(): UNDI3.1 found\n"));\r
-\r
-  Pxe = (PXE_UNDI *) (UINTN) (Nii->Id);\r
-\r
-  if (Calc8BitCksum (Pxe, Pxe->hw.Len) != 0) {\r
-    DEBUG ((EFI_D_NET, "\n!PXE checksum is not correct.\n"));\r
-    goto NiiError;\r
-  }\r
-\r
-  if ((Pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED) != 0) {\r
-    //\r
-    //  We can get any packets.\r
-    //\r
-  } else if ((Pxe->hw.Implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED) != 0) {\r
-    //\r
-    //  We need to be able to get broadcast packets for DHCP.\r
-    //  If we do not have promiscuous support, we must at least have\r
-    //  broadcast support or we cannot do DHCP!\r
-    //\r
-  } else {\r
-    DEBUG ((EFI_D_NET, "\nUNDI does not have promiscuous or broadcast support."));\r
-    goto NiiError;\r
-  }\r
-  //\r
-  // 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 = 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
-    goto NiiError;\r
-  }\r
-\r
-  Snp = (SNP_DRIVER *) (UINTN) Address;\r
-\r
-  ZeroMem (Snp, sizeof (SNP_DRIVER));\r
-\r
-  Snp->PciIo      = PciIo;\r
-  Snp->Signature  = SNP_DRIVER_SIGNATURE;\r
-\r
-  EfiInitializeLock (&Snp->Lock, TPL_NOTIFY);\r
-\r
-  Snp->Snp.Revision       = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;\r
-  Snp->Snp.Start          = SnpUndi32Start;\r
-  Snp->Snp.Stop           = SnpUndi32Stop;\r
-  Snp->Snp.Initialize     = SnpUndi32Initialize;\r
-  Snp->Snp.Reset          = SnpUndi32Reset;\r
-  Snp->Snp.Shutdown       = SnpUndi32Shutdown;\r
-  Snp->Snp.ReceiveFilters = SnpUndi32ReceiveFilters;\r
-  Snp->Snp.StationAddress = SnpUndi32StationAddress;\r
-  Snp->Snp.Statistics     = SnpUndi32Statistics;\r
-  Snp->Snp.MCastIpToMac   = SnpUndi32McastIpToMac;\r
-  Snp->Snp.NvData         = SnpUndi32NvData;\r
-  Snp->Snp.GetStatus      = SnpUndi32GetStatus;\r
-  Snp->Snp.Transmit       = SnpUndi32Transmit;\r
-  Snp->Snp.Receive        = SnpUndi32Receive;\r
-  Snp->Snp.WaitForPacket  = NULL;\r
-\r
-  Snp->Snp.Mode           = &Snp->Mode;\r
-\r
-  Snp->TxRxBufferSize     = 0;\r
-  Snp->TxRxBuffer         = NULL;\r
-\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
-    Snp->IssueUndi32Command   = &IssueHwUndiCommand;\r
-  } else {\r
-    Snp->IsSwUndi = TRUE;\r
-\r
-    if ((Pxe->sw.Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR) != 0) {\r
-      Snp->IssueUndi32Command = (ISSUE_UNDI32_COMMAND) (UINTN) Pxe->sw.EntryPoint;\r
-    } else {\r
-      Snp->IssueUndi32Command = (ISSUE_UNDI32_COMMAND) (UINTN) ((UINT8) (UINTN) Pxe + Pxe->sw.EntryPoint);\r
-    }\r
-  }\r
-  //\r
-  // Allocate a global CPB and DB buffer for this UNDI interface.\r
-  // we do this because:\r
-  //\r
-  // -UNDI 3.0 wants all the addresses passed to it (even the cpb and db) to be\r
-  // within 2GB limit, create them here and map them so that when undi calls\r
-  // v2p callback to check if the physical address is < 2gb, we will pass.\r
-  //\r
-  // -This is not a requirement for 3.1 or later UNDIs but the code looks\r
-  // simpler if we use the same cpb, db variables for both old and new undi\r
-  // interfaces from all the SNP interface calls (we don't map the buffers\r
-  // for the newer undi interfaces though)\r
-  // .\r
-  // -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 = 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
-    goto Error_DeleteSNP;\r
-  }\r
-\r
-  Snp->Cpb  = (VOID *) (UINTN) Address;\r
-  Snp->Db   = (VOID *) ((UINTN) Address + 2048);\r
-\r
-  //\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
-  Status = PxeStart (Snp);\r
-\r
-  if (Status != EFI_SUCCESS) {\r
-    goto Error_DeleteSNP;\r
-  }\r
-\r
-  Snp->Cdb.OpCode     = PXE_OPCODE_GET_INIT_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 (Snp->InitInfo);\r
-  Snp->Cdb.DBaddr     = (UINT64)(UINTN) (&Snp->InitInfo);\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_init_info()  "));\r
-\r
-  (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
-\r
-  //\r
-  // Save the INIT Stat Code...\r
-  //\r
-  InitStatFlags = Snp->Cdb.StatFlags;\r
-\r
-  if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
-    DEBUG ((EFI_D_NET, "\nSnp->undi.init_info()  %xh:%xh\n", Snp->Cdb.StatFlags, Snp->Cdb.StatCode));\r
-    PxeStop (Snp);\r
-    goto Error_DeleteSNP;\r
-  }\r
-\r
-  //\r
-  //  Initialize simple network protocol mode structure\r
-  //\r
-  Snp->Mode.State               = EfiSimpleNetworkStopped;\r
-  Snp->Mode.HwAddressSize       = Snp->InitInfo.HWaddrLen;\r
-  Snp->Mode.MediaHeaderSize     = Snp->InitInfo.MediaHeaderLen;\r
-  Snp->Mode.MaxPacketSize       = Snp->InitInfo.FrameDataLen;\r
-  Snp->Mode.NvRamAccessSize     = Snp->InitInfo.NvWidth;\r
-  Snp->Mode.NvRamSize           = Snp->InitInfo.NvCount * Snp->Mode.NvRamAccessSize;\r
-  Snp->Mode.IfType              = Snp->InitInfo.IFtype;\r
-  Snp->Mode.MaxMCastFilterCount = Snp->InitInfo.MCastFilterCnt;\r
-  Snp->Mode.MCastFilterCount    = 0;\r
-\r
-  switch (InitStatFlags & PXE_STATFLAGS_CABLE_DETECT_MASK) {\r
-  case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED:\r
-    Snp->CableDetectSupported = TRUE;\r
-    break;\r
-\r
-  case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED:\r
-  default:\r
-    Snp->CableDetectSupported = FALSE;\r
-  }\r
-\r
-  switch (InitStatFlags & PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK) {\r
-  case PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED:\r
-    Snp->MediaStatusSupported = TRUE;\r
-    break;\r
-\r
-  case PXE_STATFLAGS_GET_STATUS_NO_MEDIA_NOT_SUPPORTED:\r
-  default:\r
-    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
-    Snp->Mode.MacAddressChangeable = FALSE;\r
-  }\r
-\r
-  if ((Pxe->hw.Implementation & PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED) != 0) {\r
-    Snp->Mode.MultipleTxSupported = TRUE;\r
-  } else {\r
-    Snp->Mode.MultipleTxSupported = FALSE;\r
-  }\r
-\r
-  Snp->Mode.ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;\r
-\r
-  if ((Pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) != 0) {\r
-    Snp->Mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
-\r
-  }\r
-\r
-  if ((Pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED) != 0) {\r
-    Snp->Mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;\r
-\r
-  }\r
-\r
-  if ((Pxe->hw.Implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED) != 0) {\r
-    Snp->Mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;\r
-\r
-  }\r
-\r
-  if ((Pxe->hw.Implementation & PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED) != 0) {\r
-    Snp->Mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;\r
-\r
-  }\r
-\r
-  if ((Pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) != 0) {\r
-    Snp->Mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
-\r
-  }\r
-\r
-  Snp->Mode.ReceiveFilterSetting = 0;\r
-\r
-  //\r
-  //  need to get the station address to save in the mode structure. we need to\r
-  // initialize the UNDI first for this.\r
-  //\r
-  Snp->TxRxBufferSize = Snp->InitInfo.MemoryRequired;\r
-  Status              = PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    PxeStop (Snp);\r
-    goto Error_DeleteSNP;\r
-  }\r
-\r
-  Status = PxeGetStnAddr (Snp);\r
-\r
-  if (Status != EFI_SUCCESS) {\r
-    DEBUG ((EFI_D_ERROR, "\nSnp->undi.get_station_addr() failed.\n"));\r
-    PxeShutdown (Snp);\r
-    PxeStop (Snp);\r
-    goto Error_DeleteSNP;\r
-  }\r
-\r
-  Snp->Mode.MediaPresent = FALSE;\r
-\r
-  //\r
-  // We should not leave UNDI started and initialized here. this DriverStart()\r
-  // routine must only find and attach the SNP interface to UNDI layer that it\r
-  // finds on the given handle!\r
-  // The UNDI layer will be started when upper layers call Snp->start.\r
-  // How ever, this DriverStart() must fill up the snp mode structure which\r
-  // contains the MAC address of the NIC. For this reason we started and\r
-  // initialized UNDI here, now we are done, do a shutdown and stop of the\r
-  // UNDI interface!\r
-  //\r
-  PxeShutdown (Snp);\r
-  PxeStop (Snp);\r
-\r
-  //\r
-  // Create EXIT_BOOT_SERIVES Event\r
-  //\r
-  Status = gBS->CreateEventEx (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  SnpNotifyExitBootServices,\r
-                  Snp,\r
-                  &gEfiEventExitBootServicesGuid,\r
-                  &Snp->ExitBootServicesEvent\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error_DeleteSNP;\r
-  }\r
-\r
-  //\r
-  //  add SNP to the undi handle\r
-  //\r
-  Status = gBS->InstallProtocolInterface (\r
-                  &Controller,\r
-                  &gEfiSimpleNetworkProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  &(Snp->Snp)\r
-                  );\r
-\r
-  if (!EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  PciIo->FreeBuffer (\r
-           PciIo,\r
-           SNP_MEM_PAGES (4096),\r
-           Snp->Cpb\r
-           );\r
-\r
-Error_DeleteSNP:\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
-        &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
-\r
-  gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiDevicePathProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        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
-/**\r
-  Stop this driver on ControllerHandle. This service is called by the\r
-  EFI boot service DisconnectController(). In order to\r
-  make drivers as small as possible, there are a few calling\r
-  restrictions for this service. DisconnectController()\r
-  must follow these calling restrictions. If any other agent wishes\r
-  to call Stop() it must also follow these calling restrictions.\r
-\r
-  @param  This              Protocol instance pointer.\r
-  @param  ControllerHandle  Handle of device to stop driver on\r
-  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
-                            children is zero stop the entire bus driver.\r
-  @param  ChildHandleBuffer List of Child Handles to Stop.\r
-\r
-  @retval EFI_SUCCESS       This driver is removed ControllerHandle\r
-  @retval other             This driver was not removed from this device\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SimpleNetworkDriverStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN  EFI_HANDLE                     Controller,\r
-  IN  UINTN                          NumberOfChildren,\r
-  IN  EFI_HANDLE                     *ChildHandleBuffer\r
-  )\r
-{\r
-  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
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiSimpleNetworkProtocolGuid,\r
-                  (VOID **) &SnpProtocol,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SnpProtocol);\r
-\r
-  Status = gBS->UninstallProtocolInterface (\r
-                  Controller,\r
-                  &gEfiSimpleNetworkProtocolGuid,\r
-                  &Snp->Snp\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Close EXIT_BOOT_SERIVES Event\r
-  //\r
-  gBS->CloseEvent (Snp->ExitBootServicesEvent);\r
-\r
-  Status = gBS->CloseProtocol (\r
-                  Controller,\r
-                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
-                  This->DriverBindingHandle,\r
-                  Controller\r
-                  );\r
-\r
-  Status = gBS->CloseProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  This->DriverBindingHandle,\r
-                  Controller\r
-                  );\r
-\r
-  PxeShutdown (Snp);\r
-  PxeStop (Snp);\r
-\r
-  FreePool (Snp->RecycledTxBuf);\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
-\r
-//\r
-// Simple Network Protocol Driver Global Variables\r
-//\r
-EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = {\r
-  SimpleNetworkDriverSupported,\r
-  SimpleNetworkDriverStart,\r
-  SimpleNetworkDriverStop,\r
-  0xa,\r
-  NULL,\r
-  NULL\r
-};\r
-\r
-/**\r
-  The SNP driver entry point.\r
-\r
-  @param ImageHandle       The driver image handle.\r
-  @param SystemTable       The system table.\r
-\r
-  @retval EFI_SUCEESS      Initialization routine has found UNDI hardware,\r
-                           loaded it's ROM, and installed a notify event for\r
-                           the Network Indentifier Interface Protocol\r
-                           successfully.\r
-  @retval Other            Return value from HandleProtocol for\r
-                           DeviceIoProtocol or LoadedImageProtocol\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeSnpNiiDriver (\r
-  IN EFI_HANDLE       ImageHandle,\r
-  IN EFI_SYSTEM_TABLE *SystemTable\r
-  )\r
-{\r
-  return EfiLibInstallDriverBindingComponentName2 (\r
-           ImageHandle,\r
-           SystemTable,\r
-           &gSimpleNetworkDriverBinding,\r
-           ImageHandle,\r
-           &gSimpleNetworkComponentName,\r
-           &gSimpleNetworkComponentName2\r
-           );\r
-}\r