From 3656bc213a7a22de472a4650382a460a15265659 Mon Sep 17 00:00:00 2001 From: Parker Newman Date: Fri, 8 Sep 2023 12:50:18 -0400 Subject: [PATCH] feat: Add UEFI Adapter Information Protocol Support This adds support for the UEFI Adapter Information Protocol (AIP) for Nvidia Ethernet controllers. This fixes an issue where PXE does not load if the network interface is not ready (MediaPresent) when the PXE driver starts. Without AIP support NetLibDetectMediaWaitTimeout() will check if the network interface is ready only once. If it is not then it cancels PXE boot. This means if the network interface is slow to link the system will not attempt to PXE boot. When AIP support is availible NetLibDetectMediaWaitTimeout() will poll for "MediaPresent" to be "TRUE" or until it times out. Based on: edk2-platforms/Silicon/Broadcom/Drivers/Net/BcmGenetDxe/ Found at: https://github.com/tianocore/edk2-platforms/ Signed-off-by: Parker Newman --- .../Drivers/EqosDeviceDxe/DwEqosSnpDxe.h | 31 +++++ .../Drivers/EqosDeviceDxe/EqosAdapterInfo.c | 106 ++++++++++++++++++ .../Drivers/EqosDeviceDxe/EqosDeviceDxe.c | 9 ++ .../Drivers/EqosDeviceDxe/EqosDeviceDxe.inf | 3 + 4 files changed, 149 insertions(+) create mode 100644 Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosAdapterInfo.c diff --git a/Silicon/NVIDIA/Drivers/EqosDeviceDxe/DwEqosSnpDxe.h b/Silicon/NVIDIA/Drivers/EqosDeviceDxe/DwEqosSnpDxe.h index 52c8d43315..26f1c92f3d 100644 --- a/Silicon/NVIDIA/Drivers/EqosDeviceDxe/DwEqosSnpDxe.h +++ b/Silicon/NVIDIA/Drivers/EqosDeviceDxe/DwEqosSnpDxe.h @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -39,6 +40,7 @@ typedef struct { // EFI SNP protocol instances EFI_SIMPLE_NETWORK_PROTOCOL Snp; EFI_SIMPLE_NETWORK_MODE SnpMode; + EFI_ADAPTER_INFORMATION_PROTOCOL Aip; EMAC_DRIVER MacDriver; PHY_DRIVER PhyDriver; @@ -67,6 +69,7 @@ extern EFI_COMPONENT_NAME2_PROTOCOL gSnpComponentName2; #define SNP_DRIVER_SIGNATURE SIGNATURE_32('A', 'S', 'N', 'P') #define INSTANCE_FROM_SNP_THIS(a) CR(a, SIMPLE_NETWORK_DRIVER, Snp, SNP_DRIVER_SIGNATURE) +#define INSTANCE_FROM_AIP_THIS(a) CR(a, SIMPLE_NETWORK_DRIVER, Aip, SNP_DRIVER_SIGNATURE) #define ETHERNET_MAC_ADDRESS_INDEX 0 #define ETHERNET_MAC_BROADCAST_INDEX 1 @@ -192,6 +195,34 @@ SnpReceive ( OUT UINT16 *Protocol OPTIONAL ); +// Adapter Information Protocol Functions +EFI_STATUS +EFIAPI +EqosAipGetInformation ( + IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, + IN EFI_GUID *InformationType, + OUT VOID **InformationBlock, + OUT UINTN *InformationBlockSize + ); + +EFI_STATUS +EFIAPI +EqosAipSetInformation ( + IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN VOID *InformationBlock, + IN UINTN InformationBlockSize + ); + +EFI_STATUS +EFIAPI +EqosAipGetSupportedTypes ( + IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, + OUT EFI_GUID **InfoTypesBuffer, + OUT UINTN *InfoTypesBufferCount + ); + + // Internal helper functions /** diff --git a/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosAdapterInfo.c b/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosAdapterInfo.c new file mode 100644 index 0000000000..0edeebeba2 --- /dev/null +++ b/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosAdapterInfo.c @@ -0,0 +1,106 @@ +/* @file + + Copyright (c) 2020 Arm, Limited. All rights reserved. + Copyright (c) 2023 Connect Tech Inc. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +#include "DwEqosSnpDxe.h" + + +EFI_STATUS +EFIAPI +EqosAipGetInformation ( + IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, + IN EFI_GUID *InformationType, + OUT VOID **InformationBlock, + OUT UINTN *InformationBlockSize + ) +{ + EFI_ADAPTER_INFO_MEDIA_STATE *AdapterInfo; + SIMPLE_NETWORK_DRIVER *Snp; + + if (This == NULL || InformationBlock == NULL || + InformationBlockSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (!CompareGuid (InformationType, &gEfiAdapterInfoMediaStateGuid)) { + return EFI_UNSUPPORTED; + } + + AdapterInfo = AllocateZeroPool (sizeof (EFI_ADAPTER_INFO_MEDIA_STATE)); + if (AdapterInfo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *InformationBlock = AdapterInfo; + *InformationBlockSize = sizeof (EFI_ADAPTER_INFO_MEDIA_STATE); + + Snp = INSTANCE_FROM_AIP_THIS (This); + + if (Snp->SnpMode.MediaPresent) { + AdapterInfo->MediaState = EFI_SUCCESS; + } else { + AdapterInfo->MediaState = EFI_NOT_READY; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EqosAipSetInformation ( + IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN VOID *InformationBlock, + IN UINTN InformationBlockSize + ) +{ + if (This == NULL || InformationBlock == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (CompareGuid (InformationType, &gEfiAdapterInfoMediaStateGuid)) { + return EFI_WRITE_PROTECTED; + } + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +EqosAipGetSupportedTypes ( + IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, + OUT EFI_GUID **InfoTypesBuffer, + OUT UINTN *InfoTypesBufferCount + ) +{ + EFI_GUID *Guid; + + if (This == NULL || InfoTypesBuffer == NULL || + InfoTypesBufferCount == NULL) { + return EFI_INVALID_PARAMETER; + } + + Guid = AllocatePool (sizeof *Guid); + if (Guid == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + CopyGuid (Guid, &gEfiAdapterInfoMediaStateGuid); + + *InfoTypesBuffer = Guid; + *InfoTypesBufferCount = 1; + + return EFI_SUCCESS; +} + + diff --git a/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosDeviceDxe.c b/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosDeviceDxe.c index 1d3f6628ee..c6b59f263d 100644 --- a/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosDeviceDxe.c +++ b/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosDeviceDxe.c @@ -268,6 +268,11 @@ DeviceDiscoveryNotify ( return EFI_UNSUPPORTED; } + // Assign Adapter Information Protocol Pointers + Snp->Aip.GetInformation = EqosAipGetInformation; + Snp->Aip.SetInformation = EqosAipSetInformation; + Snp->Aip.GetSupportedTypes = EqosAipGetSupportedTypes; + // Assign fields and func pointers Snp->Snp.Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION; Snp->Snp.WaitForPacket = NULL; @@ -594,6 +599,8 @@ DeviceDiscoveryNotify ( &ControllerHandle, &gEfiSimpleNetworkProtocolGuid, &(Snp->Snp), + &gEfiAdapterInformationProtocolGuid, + &(Snp->Aip), NULL ); @@ -629,6 +636,8 @@ DeviceDiscoveryNotify ( ControllerHandle, &gEfiSimpleNetworkProtocolGuid, &Snp->Snp, + &gEfiAdapterInformationProtocolGuid, + &(Snp->Aip), NULL ); if (EFI_ERROR (Status)) { diff --git a/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosDeviceDxe.inf b/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosDeviceDxe.inf index 364652d63f..20be68617d 100644 --- a/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosDeviceDxe.inf +++ b/Silicon/NVIDIA/Drivers/EqosDeviceDxe/EqosDeviceDxe.inf @@ -37,6 +37,7 @@ PhyMicrel.c PhyMgbe.c DtAcpiMacUpdate.c + EqosAdapterInfo.c nvethernetrm/osd.c nvethernetrm/osi/core/debug.c @@ -94,6 +95,7 @@ gNVIDIACvmEepromProtocolGuid gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiAcpiSdtProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiAdapterInformationProtocolGuid [Guids] gDwEqosNetNonDiscoverableDeviceGuid @@ -103,6 +105,7 @@ gFdtTableGuid gEfiAcpiTableGuid gEfiEventExitBootServicesGuid + gEfiAdapterInfoMediaStateGuid [Depex] gEmbeddedGpioProtocolGuid