From 128946c9c38977ac2047c86d4143db2a172fc2f6 Mon Sep 17 00:00:00 2001 From: Fu Siyuan Date: Tue, 3 May 2016 17:11:22 +0800 Subject: [PATCH] MdeModulePkg: Refine SNP driver's media status check logic. Some UNDI drivers may not support the cable detect in UNDI INITIALIZE command, but support the media present check in UNDI GET_STATUS command. Current SNP driver will set the MediaPresentSupported field to FALSE in EFI_SIMPLE_NETWORK_MODE for such case, which forbid the media detect from the callers. This patch updates the SNP driver to support such kind of UNDIs for media detect. MediaPresentSupported will be set to TRUE, and a GET_STATUS command will be issued immediately after INITIALIZE command in SNP->Initialize() function, to refresh the value of MediaPresent in SNP mode data. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Fu Siyuan Reviewed-By: Ye Ting Reviewed-By: Wu Jiaxin --- .../Universal/Network/SnpDxe/Get_status.c | 25 +++++++------- .../Universal/Network/SnpDxe/Initialize.c | 13 ++++++- MdeModulePkg/Universal/Network/SnpDxe/Snp.c | 8 +++-- MdeModulePkg/Universal/Network/SnpDxe/Snp.h | 34 ++++++++++++++++++- 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Get_status.c b/MdeModulePkg/Universal/Network/SnpDxe/Get_status.c index edbc0f2374..4c3bdae107 100644 --- a/MdeModulePkg/Universal/Network/SnpDxe/Get_status.c +++ b/MdeModulePkg/Universal/Network/SnpDxe/Get_status.c @@ -18,24 +18,25 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. /** Call undi to get the status of the interrupts, get the list of recycled transmit buffers that completed transmitting. The recycled transmit buffer address will - be saved into Snp->RecycledTxBuf. + be saved into Snp->RecycledTxBuf. This function will also update the MediaPresent + field of EFI_SIMPLE_NETWORK_MODE if UNDI support it. - @param Snp Pointer to snp driver structure. - @param InterruptStatusPtr A non null pointer to contain the interrupt - status. - @param GetTransmittedBuf Set to TRUE to retrieve the recycled transmit - buffer address. + @param[in] Snp Pointer to snp driver structure. + @param[out] InterruptStatusPtr A non null pointer to contain the interrupt + status. + @param[in] GetTransmittedBuf Set to TRUE to retrieve the recycled transmit + buffer address. - @retval EFI_SUCCESS The status of the network interface was retrieved. - @retval EFI_DEVICE_ERROR The command could not be sent to the network - interface. + @retval EFI_SUCCESS The status of the network interface was retrieved. + @retval EFI_DEVICE_ERROR The command could not be sent to the network + interface. **/ EFI_STATUS PxeGetStatus ( - SNP_DRIVER *Snp, - UINT32 *InterruptStatusPtr, - BOOLEAN GetTransmittedBuf + IN SNP_DRIVER *Snp, + OUT UINT32 *InterruptStatusPtr, + IN BOOLEAN GetTransmittedBuf ) { PXE_DB_GET_STATUS *Db; diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Initialize.c b/MdeModulePkg/Universal/Network/SnpDxe/Initialize.c index 3f40ef3ce7..21513752de 100644 --- a/MdeModulePkg/Universal/Network/SnpDxe/Initialize.c +++ b/MdeModulePkg/Universal/Network/SnpDxe/Initialize.c @@ -229,7 +229,10 @@ SnpUndi32Initialize ( // Snp->TxRxBufferSize = (UINT32) (Snp->InitInfo.MemoryRequired + ExtraRxBufferSize + ExtraTxBufferSize); - if (Snp->Mode.MediaPresentSupported) { + // + // If UNDI support cable detect for INITIALIZE command, try it first. + // + if (Snp->CableDetectSupported) { if (PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) { Snp->Mode.MediaPresent = TRUE; goto ON_EXIT; @@ -242,6 +245,14 @@ SnpUndi32Initialize ( if (EFI_ERROR (EfiStatus)) { gBS->CloseEvent (Snp->Snp.WaitForPacket); + goto ON_EXIT; + } + + // + // Try to update the MediaPresent field of EFI_SIMPLE_NETWORK_MODE if the UNDI support it. + // + if (Snp->MediaStatusSupported) { + PxeGetStatus (Snp, NULL, FALSE); } ON_EXIT: diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Snp.c b/MdeModulePkg/Universal/Network/SnpDxe/Snp.c index 5ff294f8b5..9f61aee057 100644 --- a/MdeModulePkg/Universal/Network/SnpDxe/Snp.c +++ b/MdeModulePkg/Universal/Network/SnpDxe/Snp.c @@ -554,12 +554,12 @@ SimpleNetworkDriverStart ( switch (InitStatFlags & PXE_STATFLAGS_CABLE_DETECT_MASK) { case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED: - Snp->Mode.MediaPresentSupported = TRUE; + Snp->CableDetectSupported = TRUE; break; case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED: default: - Snp->Mode.MediaPresentSupported = FALSE; + Snp->CableDetectSupported = FALSE; } switch (InitStatFlags & PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK) { @@ -572,6 +572,10 @@ SimpleNetworkDriverStart ( Snp->MediaStatusSupported = FALSE; } + if (Snp->CableDetectSupported || Snp->MediaStatusSupported) { + Snp->Mode.MediaPresentSupported = TRUE; + } + if ((Pxe->hw.Implementation & PXE_ROMID_IMP_STATION_ADDR_SETTABLE) != 0) { Snp->Mode.MacAddressChangeable = TRUE; } else { diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Snp.h b/MdeModulePkg/Universal/Network/SnpDxe/Snp.h index 67f65ffc42..9d5ae98e51 100644 --- a/MdeModulePkg/Universal/Network/SnpDxe/Snp.h +++ b/MdeModulePkg/Universal/Network/SnpDxe/Snp.h @@ -130,10 +130,18 @@ typedef struct { // // Whether UNDI support reporting media status from GET_STATUS command, - // i.e. PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED + // i.e. PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED or + // PXE_STATFLAGS_GET_STATUS_NO_MEDIA_NOT_SUPPORTED // BOOLEAN MediaStatusSupported; + // + // Whether UNDI support cable detect for INITIALIZE command, + // i.e. PXE_STATFLAGS_CABLE_DETECT_SUPPORTED or + // PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED + // + BOOLEAN CableDetectSupported; + // // Array of the recycled transmit buffer address from UNDI. // @@ -233,6 +241,30 @@ PxeGetStnAddr ( SNP_DRIVER *Snp ); +/** + Call undi to get the status of the interrupts, get the list of recycled transmit + buffers that completed transmitting. The recycled transmit buffer address will + be saved into Snp->RecycledTxBuf. This function will also update the MediaPresent + field of EFI_SIMPLE_NETWORK_MODE if UNDI support it. + + @param[in] Snp Pointer to snp driver structure. + @param[out] InterruptStatusPtr A non null pointer to contain the interrupt + status. + @param[in] GetTransmittedBuf Set to TRUE to retrieve the recycled transmit + buffer address. + + @retval EFI_SUCCESS The status of the network interface was retrieved. + @retval EFI_DEVICE_ERROR The command could not be sent to the network + interface. + +**/ +EFI_STATUS +PxeGetStatus ( + IN SNP_DRIVER *Snp, + OUT UINT32 *InterruptStatusPtr, + IN BOOLEAN GetTransmittedBuf + ); + /** This is a callback routine supplied to UNDI3.1 at undi_start time. UNDI call this routine when it wants to have exclusive access to a critical -- 2.39.2