public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [Patch v2] MdeModulePkg/NetLib: Add NetLibDetectMediaWaitTimeout() API to support EFI_NOT_READY media state detection
@ 2017-12-04  3:41 fanwang2
  2017-12-05  8:06 ` Fu, Siyuan
  0 siblings, 1 reply; 3+ messages in thread
From: fanwang2 @ 2017-12-04  3:41 UTC (permalink / raw)
  To: edk2-devel; +Cc: Fu Siyuan, Ye Ting, Jiaxin Wu, Wang Fan

V2:
  * Return error status code directly when Aip protocol falied to detect
    media rather than wait for another time's check.
  * Set media state default value to EFI_SUCCESS since some platforms may
    not support retrieving media state from Aip protocol.

Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wang Fan <fan.wang@intel.com>
---
 MdeModulePkg/Include/Library/NetLib.h        |  40 +++++++
 MdeModulePkg/Library/DxeNetLib/DxeNetLib.c   | 163 +++++++++++++++++++++++++++
 MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf |   2 +
 3 files changed, 205 insertions(+)

diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/Library/NetLib.h
index b9df46c..7862df9 100644
--- a/MdeModulePkg/Include/Library/NetLib.h
+++ b/MdeModulePkg/Include/Library/NetLib.h
@@ -93,10 +93,16 @@ typedef UINT16          TCP_PORTNO;
 #define  DNS_CLASS_INET        1
 #define  DNS_CLASS_CH          3
 #define  DNS_CLASS_HS          4
 #define  DNS_CLASS_ANY         255
 
+//
+// Number of 100ns units time Interval for network media state detect
+//
+#define MEDIA_STATE_DETECT_TIME_INTERVAL  1000000U
+
+
 #pragma pack(1)
 
 //
 // Ethernet head definition
 //
@@ -1246,10 +1252,44 @@ NetLibDetectMedia (
   IN  EFI_HANDLE            ServiceHandle,
   OUT BOOLEAN               *MediaPresent
   );
 
 /**
+
+  Detect media state for a network device. This routine will wait for a period of time at 
+  a specified checking interval when a certain network is under connecting until connection 
+  process finishes or timeout. If Aip protocol is supported by low layer drivers, three kinds
+  of media states can be detected: EFI_SUCCESS, EFI_NOT_READY and EFI_NO_MEDIA, represents
+  connected state, connecting state and no media state respectively. When function detects 
+  the current state is EFI_NOT_READY, it will loop to wait for next time's check until state 
+  turns to be EFI_SUCCESS or EFI_NO_MEDIA. If Aip protocol is not supported, function will 
+  call NetLibDetectMedia() and return state directly.
+
+  @param[in]   ServiceHandle    The handle where network service binding protocols are
+                                installed on.
+  @param[in]   Timeout          The maximum number of 100ns units to wait when network
+                                is connecting. Zero value means detect once and return
+                                immediately.
+  @param[out]  MediaState       The pointer to the detected media state.
+
+  @retval EFI_SUCCESS           Media detection success.
+  @retval EFI_INVALID_PARAMETER ServiceHandle is not a valid network device handle or 
+                                MediaState pointer is NULL.
+  @retval EFI_DEVICE_ERROR      A device error occurred.
+  @retval EFI_TIMEOUT           Network is connecting but timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+NetLibDetectMediaWaitTimeout (
+  IN  EFI_HANDLE            ServiceHandle,
+  IN  UINT64                Timeout,
+  OUT EFI_STATUS            *MediaState
+  );
+
+
+/**
   Create an IPv4 device path node.
 
   The header type of IPv4 device path node is MESSAGING_DEVICE_PATH.
   The header subtype of IPv4 device path node is MSG_IPv4_DP.
   The length of the IPv4 device path node in bytes is 19.
diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
index b8544b8..1bfa33d 100644
--- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
+++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
@@ -17,10 +17,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <IndustryStandard/SmBios.h>
 
 #include <Protocol/DriverBinding.h>
 #include <Protocol/ServiceBinding.h>
 #include <Protocol/SimpleNetwork.h>
+#include <Protocol/AdapterInformation.h>
 #include <Protocol/ManagedNetwork.h>
 #include <Protocol/Ip4Config2.h>
 #include <Protocol/ComponentName.h>
 #include <Protocol/ComponentName2.h>
 
@@ -2501,10 +2502,172 @@ Exit:
 
   return Status;
 }
 
 /**
+
+  Detect media state for a network device. This routine will wait for a period of time at 
+  a specified checking interval when a certain network is under connecting until connection 
+  process finishs or timeout. If Aip protocol is supported by low layer drivers, three kinds
+  of media states can be detected: EFI_SUCCESS, EFI_NOT_READY and EFI_NO_MEDIA, represents
+  connected state, connecting state and no media state respectively. When function detects 
+  the current state is EFI_NOT_READY, it will loop to wait for next time's check until state 
+  turns to be EFI_SUCCESS or EFI_NO_MEDIA. If Aip protocol is not supported, function will 
+  call NetLibDetectMedia() and return state directly.
+
+  @param[in]   ServiceHandle    The handle where network service binding protocols are
+                                installed on.
+  @param[in]   Timeout          The maximum number of 100ns units to wait when network
+                                is connecting. Zero value means detect once and return
+                                immediately.
+  @param[out]  MediaState       The pointer to the detected media state.
+
+  @retval EFI_SUCCESS           Media detection success.
+  @retval EFI_INVALID_PARAMETER ServiceHandle is not a valid network device handle or 
+                                MediaState pointer is NULL.
+  @retval EFI_DEVICE_ERROR      A device error occurred.
+  @retval EFI_TIMEOUT           Network is connecting but timeout.
+
+**/
+
+EFI_STATUS
+EFIAPI
+NetLibDetectMediaWaitTimeout (
+  IN  EFI_HANDLE            ServiceHandle,
+  IN  UINT64                Timeout,
+  OUT EFI_STATUS            *MediaState
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_HANDLE                        SnpHandle;
+  EFI_SIMPLE_NETWORK_PROTOCOL       *Snp;
+  EFI_ADAPTER_INFORMATION_PROTOCOL  *Aip;
+  EFI_ADAPTER_INFO_MEDIA_STATE      *MediaInfo;
+  BOOLEAN                           MediaPresent;
+  UINTN                             DataSize;
+  EFI_STATUS                        TimerStatus;
+  EFI_EVENT                         Timer;
+  UINT64                            TimeRemained;
+
+  if (MediaState == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *MediaState = EFI_SUCCESS;
+  MediaInfo   = NULL;
+
+  //
+  // Get SNP handle
+  //
+  Snp = NULL;
+  SnpHandle = NetLibGetSnpHandle (ServiceHandle, &Snp);
+  if (SnpHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = gBS->HandleProtocol (
+                  SnpHandle,
+                  &gEfiAdapterInformationProtocolGuid,
+                  (VOID *) &Aip
+                  );
+  if (EFI_ERROR (Status)) {
+
+    MediaPresent = TRUE;
+    Status = NetLibDetectMedia (ServiceHandle, &MediaPresent);
+    if (!EFI_ERROR (Status)) {
+      if (MediaPresent == TRUE) {
+        *MediaState = EFI_SUCCESS;
+      } else {
+        *MediaState = EFI_NO_MEDIA;
+      }
+    }
+
+    //
+    // NetLibDetectMedia doesn't support EFI_NOT_READY status, return now!
+    //
+    return Status;
+  }
+
+  Status = Aip->GetInformation (
+                  Aip,
+                  &gEfiAdapterInfoMediaStateGuid,
+                  (VOID **) &MediaInfo,
+                  &DataSize
+                  );
+  if (!EFI_ERROR (Status)) {
+
+    *MediaState = MediaInfo->MediaState;
+    FreePool (MediaInfo);
+    if (*MediaState != EFI_NOT_READY || Timeout < MEDIA_STATE_DETECT_TIME_INTERVAL) {
+
+      return EFI_SUCCESS;
+    }
+  } else {
+
+    if (MediaInfo != NULL) {
+      FreePool (MediaInfo);
+    }
+    return Status;
+  }
+
+  //
+  // Loop to check media state 
+  //
+
+  Timer        = NULL;
+  TimeRemained = Timeout;
+  Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  do {
+    Status = gBS->SetTimer (
+                    Timer,
+                    TimerRelative,
+                    MEDIA_STATE_DETECT_TIME_INTERVAL
+                    );
+    if (EFI_ERROR (Status)) {
+      gBS->CloseEvent(Timer);
+      return EFI_DEVICE_ERROR;
+    }
+
+    do {
+      TimerStatus = gBS->CheckEvent (Timer);
+      if (!EFI_ERROR (TimerStatus)) {
+
+        TimeRemained -= MEDIA_STATE_DETECT_TIME_INTERVAL;
+        Status = Aip->GetInformation (
+                        Aip,
+                        &gEfiAdapterInfoMediaStateGuid,
+                        (VOID **) &MediaInfo,
+                        &DataSize
+                        );
+        if (!EFI_ERROR (Status)) {
+
+          *MediaState = MediaInfo->MediaState;
+          FreePool (MediaInfo);
+        } else {
+
+          if (MediaInfo != NULL) {
+            FreePool (MediaInfo);
+          }
+          gBS->CloseEvent(Timer);
+          return Status;
+        }
+      }
+    } while (TimerStatus == EFI_NOT_READY);
+  } while (*MediaState == EFI_NOT_READY && TimeRemained >= MEDIA_STATE_DETECT_TIME_INTERVAL);
+
+  gBS->CloseEvent(Timer);
+  if (*MediaState == EFI_NOT_READY && TimeRemained < MEDIA_STATE_DETECT_TIME_INTERVAL) {
+    return EFI_TIMEOUT;
+  } else {
+    return EFI_SUCCESS;
+  }
+}
+
+/**
   Check the default address used by the IPv4 driver is static or dynamic (acquired
   from DHCP).
 
   If the controller handle does not have the EFI_IP4_CONFIG2_PROTOCOL installed, the
   default address is static. If failed to get the policy from Ip4 Config2 Protocol, 
diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
index 1ff3a4f..ad0727c 100644
--- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
@@ -52,14 +52,16 @@
 
 
 [Guids]
   gEfiSmbiosTableGuid                           ## SOMETIMES_CONSUMES  ## SystemTable
   gEfiSmbios3TableGuid                          ## SOMETIMES_CONSUMES  ## SystemTable
+  gEfiAdapterInfoMediaStateGuid                 ## SOMETIMES_CONSUMES
 
 
 [Protocols]
   gEfiSimpleNetworkProtocolGuid                 ## SOMETIMES_CONSUMES
   gEfiManagedNetworkProtocolGuid                ## SOMETIMES_CONSUMES
   gEfiManagedNetworkServiceBindingProtocolGuid  ## SOMETIMES_CONSUMES
   gEfiIp4Config2ProtocolGuid                    ## SOMETIMES_CONSUMES
   gEfiComponentNameProtocolGuid                 ## SOMETIMES_CONSUMES
   gEfiComponentName2ProtocolGuid                ## SOMETIMES_CONSUMES
+  gEfiAdapterInformationProtocolGuid            ## SOMETIMES_CONSUMES
\ No newline at end of file
-- 
1.9.5.msysgit.1



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-12-06  3:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-04  3:41 [Patch v2] MdeModulePkg/NetLib: Add NetLibDetectMediaWaitTimeout() API to support EFI_NOT_READY media state detection fanwang2
2017-12-05  8:06 ` Fu, Siyuan
2017-12-06  3:45   ` Wu, Jiaxin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox