MdeModulePkg/NetLib: Add NetLibDetectMediaWaitTimeout() API to support EFI_NOT_READY media state detection

In wireless connection, connecting state needs to be cared more
about. ECR 1772 redefined the state EFI_NOT_READY to represent
connecting state and can be retrieved from Aip protocol. This
patch adds a new API to check media state at a specified time
interval when network is connecting until the connection process
finishes or timeout.

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>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
This commit is contained in:
fanwang2
2017-12-06 13:00:21 +08:00
committed by Jiaxin Wu
parent 1e6e6e188e
commit ca4e432392
3 changed files with 205 additions and 0 deletions

View File

@ -95,6 +95,12 @@ typedef UINT16 TCP_PORTNO;
#define DNS_CLASS_HS 4 #define DNS_CLASS_HS 4
#define DNS_CLASS_ANY 255 #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) #pragma pack(1)
// //
@ -1247,6 +1253,40 @@ NetLibDetectMedia (
OUT BOOLEAN *MediaPresent 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. Create an IPv4 device path node.

View File

@ -19,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/DriverBinding.h> #include <Protocol/DriverBinding.h>
#include <Protocol/ServiceBinding.h> #include <Protocol/ServiceBinding.h>
#include <Protocol/SimpleNetwork.h> #include <Protocol/SimpleNetwork.h>
#include <Protocol/AdapterInformation.h>
#include <Protocol/ManagedNetwork.h> #include <Protocol/ManagedNetwork.h>
#include <Protocol/Ip4Config2.h> #include <Protocol/Ip4Config2.h>
#include <Protocol/ComponentName.h> #include <Protocol/ComponentName.h>
@ -2502,6 +2503,168 @@ Exit:
return Status; 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 Check the default address used by the IPv4 driver is static or dynamic (acquired
from DHCP). from DHCP).

View File

@ -54,6 +54,7 @@
[Guids] [Guids]
gEfiSmbiosTableGuid ## SOMETIMES_CONSUMES ## SystemTable gEfiSmbiosTableGuid ## SOMETIMES_CONSUMES ## SystemTable
gEfiSmbios3TableGuid ## SOMETIMES_CONSUMES ## SystemTable gEfiSmbios3TableGuid ## SOMETIMES_CONSUMES ## SystemTable
gEfiAdapterInfoMediaStateGuid ## SOMETIMES_CONSUMES
[Protocols] [Protocols]
@ -63,3 +64,4 @@
gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMES gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMES
gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiAdapterInformationProtocolGuid ## SOMETIMES_CONSUMES