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