+++ /dev/null
-/** @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