#include <Protocol/DriverBinding.h>\r
#include <Protocol/ServiceBinding.h>\r
#include <Protocol/SimpleNetwork.h>\r
+#include <Protocol/AdapterInformation.h>\r
#include <Protocol/ManagedNetwork.h>\r
#include <Protocol/Ip4Config2.h>\r
#include <Protocol/ComponentName.h>\r
return Status;\r
}\r
\r
+/**\r
+\r
+ Detect media state for a network device. This routine will wait for a period of time at \r
+ a specified checking interval when a certain network is under connecting until connection \r
+ process finishs or timeout. If Aip protocol is supported by low layer drivers, three kinds\r
+ of media states can be detected: EFI_SUCCESS, EFI_NOT_READY and EFI_NO_MEDIA, represents\r
+ connected state, connecting state and no media state respectively. When function detects \r
+ the current state is EFI_NOT_READY, it will loop to wait for next time's check until state \r
+ turns to be EFI_SUCCESS or EFI_NO_MEDIA. If Aip protocol is not supported, function will \r
+ call NetLibDetectMedia() and return state directly.\r
+\r
+ @param[in] ServiceHandle The handle where network service binding protocols are\r
+ installed on.\r
+ @param[in] Timeout The maximum number of 100ns units to wait when network\r
+ is connecting. Zero value means detect once and return\r
+ immediately.\r
+ @param[out] MediaState The pointer to the detected media state.\r
+\r
+ @retval EFI_SUCCESS Media detection success.\r
+ @retval EFI_INVALID_PARAMETER ServiceHandle is not a valid network device handle or \r
+ MediaState pointer is NULL.\r
+ @retval EFI_DEVICE_ERROR A device error occurred.\r
+ @retval EFI_TIMEOUT Network is connecting but timeout.\r
+\r
+**/\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+NetLibDetectMediaWaitTimeout (\r
+ IN EFI_HANDLE ServiceHandle,\r
+ IN UINT64 Timeout,\r
+ OUT EFI_STATUS *MediaState\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE SnpHandle;\r
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
+ EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r
+ EFI_ADAPTER_INFO_MEDIA_STATE *MediaInfo;\r
+ BOOLEAN MediaPresent;\r
+ UINTN DataSize;\r
+ EFI_STATUS TimerStatus;\r
+ EFI_EVENT Timer;\r
+ UINT64 TimeRemained;\r
+\r
+ if (MediaState == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ *MediaState = EFI_SUCCESS;\r
+ MediaInfo = NULL;\r
+\r
+ //\r
+ // Get SNP handle\r
+ //\r
+ Snp = NULL;\r
+ SnpHandle = NetLibGetSnpHandle (ServiceHandle, &Snp);\r
+ if (SnpHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = gBS->HandleProtocol (\r
+ SnpHandle,\r
+ &gEfiAdapterInformationProtocolGuid,\r
+ (VOID *) &Aip\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+\r
+ MediaPresent = TRUE;\r
+ Status = NetLibDetectMedia (ServiceHandle, &MediaPresent);\r
+ if (!EFI_ERROR (Status)) {\r
+ if (MediaPresent == TRUE) {\r
+ *MediaState = EFI_SUCCESS;\r
+ } else {\r
+ *MediaState = EFI_NO_MEDIA;\r
+ }\r
+ }\r
+\r
+ //\r
+ // NetLibDetectMedia doesn't support EFI_NOT_READY status, return now!\r
+ //\r
+ return Status;\r
+ }\r
+\r
+ Status = Aip->GetInformation (\r
+ Aip,\r
+ &gEfiAdapterInfoMediaStateGuid,\r
+ (VOID **) &MediaInfo,\r
+ &DataSize\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ *MediaState = MediaInfo->MediaState;\r
+ FreePool (MediaInfo);\r
+ if (*MediaState != EFI_NOT_READY || Timeout < MEDIA_STATE_DETECT_TIME_INTERVAL) {\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+ } else {\r
+\r
+ if (MediaInfo != NULL) {\r
+ FreePool (MediaInfo);\r
+ }\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Loop to check media state \r
+ //\r
+\r
+ Timer = NULL;\r
+ TimeRemained = Timeout;\r
+ Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ do {\r
+ Status = gBS->SetTimer (\r
+ Timer,\r
+ TimerRelative,\r
+ MEDIA_STATE_DETECT_TIME_INTERVAL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->CloseEvent(Timer);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ do {\r
+ TimerStatus = gBS->CheckEvent (Timer);\r
+ if (!EFI_ERROR (TimerStatus)) {\r
+\r
+ TimeRemained -= MEDIA_STATE_DETECT_TIME_INTERVAL;\r
+ Status = Aip->GetInformation (\r
+ Aip,\r
+ &gEfiAdapterInfoMediaStateGuid,\r
+ (VOID **) &MediaInfo,\r
+ &DataSize\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+\r
+ *MediaState = MediaInfo->MediaState;\r
+ FreePool (MediaInfo);\r
+ } else {\r
+\r
+ if (MediaInfo != NULL) {\r
+ FreePool (MediaInfo);\r
+ }\r
+ gBS->CloseEvent(Timer);\r
+ return Status;\r
+ }\r
+ }\r
+ } while (TimerStatus == EFI_NOT_READY);\r
+ } while (*MediaState == EFI_NOT_READY && TimeRemained >= MEDIA_STATE_DETECT_TIME_INTERVAL);\r
+\r
+ gBS->CloseEvent(Timer);\r
+ if (*MediaState == EFI_NOT_READY && TimeRemained < MEDIA_STATE_DETECT_TIME_INTERVAL) {\r
+ return EFI_TIMEOUT;\r
+ } else {\r
+ return EFI_SUCCESS;\r
+ }\r
+}\r
+\r
/**\r
Check the default address used by the IPv4 driver is static or dynamic (acquired\r
from DHCP).\r