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 <siyuan.fu@intel.com>
Reviewed-By: Ye Ting <ting.ye@intel.com>
Reviewed-By: Wu Jiaxin <jiaxin.wu@intel.com>
This commit is contained in:
Fu Siyuan 2016-05-03 17:11:22 +08:00
parent 89ecd4cf80
commit 128946c9c3
4 changed files with 64 additions and 16 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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 {

View File

@ -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