Browse Source

Silicon/SynQuacer/NetsecDxe: avoid media detection delay at boot

Instead of unconditionally delaying the boot up to 5 seconds, even
if no network cable is connected in the first place, provide an
implementation of the EFI adapter information protocol so that the
upper networking layers can wait gracefully for the link to come up,
but only when the network is actually used to boot from.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
Ard Biesheuvel 4 years ago
parent
commit
b29531f318

+ 0 - 1
Platform/Socionext/DeveloperBox/DeveloperBox.dsc

@@ -165,7 +165,6 @@
   gNetsecDxeTokenSpaceGuid.PcdFlowCtrl|0
   gNetsecDxeTokenSpaceGuid.PcdFlowCtrlStartThreshold|36
   gNetsecDxeTokenSpaceGuid.PcdFlowCtrlStopThreshold|48
-  gNetsecDxeTokenSpaceGuid.PcdMediaDetectTimeoutOnBoot|5
   gNetsecDxeTokenSpaceGuid.PcdPauseTime|256
 
   gSynQuacerTokenSpaceGuid.PcdNetsecEepromBase|0x08080000

+ 96 - 16
Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.c

@@ -279,8 +279,6 @@ SnpInitialize (
 
   ogma_err_t              ogma_err;
 
-  UINT32                  Index;
-
   // Check Snp Instance
   if (Snp == NULL) {
     return EFI_INVALID_PARAMETER;
@@ -363,20 +361,6 @@ SnpInitialize (
   ogma_disable_desc_ring_irq (LanDriver->Handle, OGMA_DESC_RING_ID_NRM_TX,
                               OGMA_CH_IRQ_REG_EMPTY);
 
-  // Wait for media linking up
-  for (Index = 0; Index < (UINT32)FixedPcdGet8 (PcdMediaDetectTimeoutOnBoot) * 10; Index++) {
-    Status = NetsecUpdateLink (Snp);
-    if (Status != EFI_SUCCESS) {
-      ReturnUnlock (EFI_DEVICE_ERROR);
-    }
-
-    if (Snp->Mode->MediaPresent) {
-      break;
-    }
-
-    MicroSecondDelay(100000);
-  }
-
   // Declare the driver as initialized
   Snp->Mode->State = EfiSimpleNetworkInitialized;
   Status = EFI_SUCCESS;
@@ -948,6 +932,96 @@ ExitUnlock:
   return Status;
 }
 
+STATIC
+EFI_STATUS
+EFIAPI
+NetsecAipGetInformation (
+  IN  EFI_ADAPTER_INFORMATION_PROTOCOL  *This,
+  IN  EFI_GUID                          *InformationType,
+  OUT VOID                              **InformationBlock,
+  OUT UINTN                             *InformationBlockSize
+  )
+{
+  EFI_ADAPTER_INFO_MEDIA_STATE  *AdapterInfo;
+  NETSEC_DRIVER                 *LanDriver;
+
+  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);
+
+  LanDriver = INSTANCE_FROM_AIP_THIS (This);
+  if (LanDriver->Snp.Mode->MediaPresent) {
+    AdapterInfo->MediaState = EFI_SUCCESS;
+  } else {
+    AdapterInfo->MediaState = EFI_NOT_READY;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+NetsecAipSetInformation (
+  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;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+NetsecAipGetSupportedTypes (
+  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;
+}
+
 EFI_STATUS
 NetsecInit (
   IN      EFI_HANDLE        DriverBindingHandle,
@@ -1046,6 +1120,10 @@ NetsecInit (
   SnpMode->MediaPresentSupported = TRUE;
   SnpMode->MediaPresent = FALSE;
 
+  LanDriver->Aip.GetInformation     = NetsecAipGetInformation;
+  LanDriver->Aip.SetInformation     = NetsecAipSetInformation;
+  LanDriver->Aip.GetSupportedTypes  = NetsecAipGetSupportedTypes;
+
   //  Set broadcast address
   SetMem (&SnpMode->BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);
 
@@ -1055,6 +1133,7 @@ NetsecInit (
   Status = gBS->InstallMultipleProtocolInterfaces (
                   &ControllerHandle,
                   &gEfiSimpleNetworkProtocolGuid, Snp,
+                  &gEfiAdapterInformationProtocolGuid, &LanDriver->Aip,
                   NULL);
 
   LanDriver->ControllerHandle = ControllerHandle;
@@ -1100,6 +1179,7 @@ NetsecRelease (
 
   Status = gBS->UninstallMultipleProtocolInterfaces (ControllerHandle,
                   &gEfiSimpleNetworkProtocolGuid, Snp,
+                  &gEfiAdapterInformationProtocolGuid, &LanDriver->Aip,
                   NULL);
   if (EFI_ERROR (Status)) {
     return Status;

+ 0 - 1
Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.dec

@@ -37,5 +37,4 @@
   gNetsecDxeTokenSpaceGuid.PcdFlowCtrl|0x0|UINT8|0x00000005
   gNetsecDxeTokenSpaceGuid.PcdFlowCtrlStartThreshold|0x0|UINT16|0x00000006
   gNetsecDxeTokenSpaceGuid.PcdFlowCtrlStopThreshold|0x0|UINT16|0x00000007
-  gNetsecDxeTokenSpaceGuid.PcdMediaDetectTimeoutOnBoot|0x0|UINT8|0x00000009
   gNetsecDxeTokenSpaceGuid.PcdPauseTime|0x0|UINT16|0x00000008

+ 5 - 0
Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.h

@@ -20,6 +20,7 @@
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiLib.h>
 
+#include <Protocol/AdapterInformation.h>
 #include <Protocol/NonDiscoverableDevice.h>
 
 #include "netsec_for_uefi/netsec_sdk/include/ogma_api.h"
@@ -50,6 +51,9 @@ typedef struct {
   // EFI Snp statistics instance
   EFI_NETWORK_STATISTICS            Stats;
 
+  // Adapter Information protocol
+  EFI_ADAPTER_INFORMATION_PROTOCOL  Aip;
+
   // ogma handle
   ogma_handle_t                     Handle;
 
@@ -65,6 +69,7 @@ typedef struct {
 
 #define NETSEC_SIGNATURE            SIGNATURE_32('n', 't', 's', 'c')
 #define INSTANCE_FROM_SNP_THIS(a)   CR((a), NETSEC_DRIVER, Snp, NETSEC_SIGNATURE)
+#define INSTANCE_FROM_AIP_THIS(a)   CR((a), NETSEC_DRIVER, Aip, NETSEC_SIGNATURE)
 
 /*------------------------------------------------------------------------------
 

+ 2 - 1
Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.inf

@@ -47,11 +47,13 @@
   UefiLib
 
 [Guids]
+  gEfiAdapterInfoMediaStateGuid
   gNetsecNonDiscoverableDeviceGuid
 
 [Protocols]
   gEfiCpuArchProtocolGuid                     ## CONSUMES
   gEdkiiNonDiscoverableDeviceProtocolGuid     ## TO_START
+  gEfiAdapterInformationProtocolGuid          ## BY_START
   gEfiSimpleNetworkProtocolGuid               ## BY_START
 
 [FixedPcd]
@@ -61,5 +63,4 @@
   gNetsecDxeTokenSpaceGuid.PcdFlowCtrlStartThreshold
   gNetsecDxeTokenSpaceGuid.PcdFlowCtrlStopThreshold
   gNetsecDxeTokenSpaceGuid.PcdJumboPacket
-  gNetsecDxeTokenSpaceGuid.PcdMediaDetectTimeoutOnBoot
   gNetsecDxeTokenSpaceGuid.PcdPauseTime