mirror of https://github.com/acidanthera/audk.git
MdeModulePkg: update SNP.GetStatus to handle multiple recycled TX buffer.
This patch fixes a bug in SNP.GetStatus() interface. The UNDI driver may return multiple transmitted buffers in a single GetStatus command, while SNP.GetStatus could only return one pointer each time, the rest of them are lost. This patch fixes this issue by store these recycled pointer in a temporary buffer in SNP driver. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19623 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
c2967d35d8
commit
7b4b93a247
|
@ -2,7 +2,7 @@
|
||||||
Implementation of reading the current interrupt status and recycled transmit
|
Implementation of reading the current interrupt status and recycled transmit
|
||||||
buffer status from a network interface.
|
buffer status from a network interface.
|
||||||
|
|
||||||
Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed
|
This program and the accompanying materials are licensed
|
||||||
and made available under the terms and conditions of the BSD License which
|
and made available under the terms and conditions of the BSD License which
|
||||||
accompanies this distribution. The full text of the license may be found at
|
accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -16,15 +16,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#include "Snp.h"
|
#include "Snp.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Call undi to get the status of the interrupts, get the list of transmit
|
Call undi to get the status of the interrupts, get the list of recycled transmit
|
||||||
buffers that completed transmitting.
|
buffers that completed transmitting. The recycled transmit buffer address will
|
||||||
|
be saved into Snp->RecycledTxBuf.
|
||||||
|
|
||||||
@param Snp Pointer to snp driver structure.
|
@param Snp Pointer to snp driver structure.
|
||||||
@param InterruptStatusPtr A non null pointer to contain the interrupt
|
@param InterruptStatusPtr A non null pointer to contain the interrupt
|
||||||
status.
|
status.
|
||||||
@param TransmitBufferListPtrs A non null pointer to contain the list of
|
@param GetTransmittedBuf Set to TRUE to retrieve the recycled transmit
|
||||||
pointers of previous transmitted buffers whose
|
buffer address.
|
||||||
transmission was completed asynchrnously.
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS The status of the network interface was retrieved.
|
@retval EFI_SUCCESS The status of the network interface was retrieved.
|
||||||
@retval EFI_DEVICE_ERROR The command could not be sent to the network
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network
|
||||||
|
@ -35,19 +35,23 @@ EFI_STATUS
|
||||||
PxeGetStatus (
|
PxeGetStatus (
|
||||||
SNP_DRIVER *Snp,
|
SNP_DRIVER *Snp,
|
||||||
UINT32 *InterruptStatusPtr,
|
UINT32 *InterruptStatusPtr,
|
||||||
VOID **TransmitBufferListPtr
|
BOOLEAN GetTransmittedBuf
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PXE_DB_GET_STATUS *Db;
|
PXE_DB_GET_STATUS *Db;
|
||||||
UINT16 InterruptFlags;
|
UINT16 InterruptFlags;
|
||||||
|
UINT32 Index;
|
||||||
|
UINT64 *Tmp;
|
||||||
|
|
||||||
|
Tmp = NULL;
|
||||||
Db = Snp->Db;
|
Db = Snp->Db;
|
||||||
Snp->Cdb.OpCode = PXE_OPCODE_GET_STATUS;
|
Snp->Cdb.OpCode = PXE_OPCODE_GET_STATUS;
|
||||||
|
|
||||||
Snp->Cdb.OpFlags = 0;
|
Snp->Cdb.OpFlags = 0;
|
||||||
|
|
||||||
if (TransmitBufferListPtr != NULL) {
|
if (GetTransmittedBuf) {
|
||||||
Snp->Cdb.OpFlags |= PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS;
|
Snp->Cdb.OpFlags |= PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS;
|
||||||
|
ZeroMem (Db->TxBuffer, sizeof (Db->TxBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InterruptStatusPtr != NULL) {
|
if (InterruptStatusPtr != NULL) {
|
||||||
|
@ -116,13 +120,34 @@ PxeGetStatus (
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TransmitBufferListPtr != NULL) {
|
if (GetTransmittedBuf) {
|
||||||
*TransmitBufferListPtr =
|
if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN) == 0) {
|
||||||
(
|
//
|
||||||
((Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN) != 0) ||
|
// UNDI has written some transmitted buffer addresses into the DB. Store them into Snp->RecycledTxBuf.
|
||||||
((Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY) != 0)
|
//
|
||||||
) ? 0 : (VOID *) (UINTN) Db->TxBuffer[0];
|
for (Index = 0; Index < MAX_XMIT_BUFFERS; Index++) {
|
||||||
|
if (Db->TxBuffer[Index] != 0) {
|
||||||
|
if (Snp->RecycledTxBufCount == Snp->MaxRecycledTxBuf) {
|
||||||
|
//
|
||||||
|
// Snp->RecycledTxBuf is full, reallocate a new one.
|
||||||
|
//
|
||||||
|
if ((Snp->MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT) >= SNP_MAX_TX_BUFFER_NUM) {
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
Tmp = AllocatePool (sizeof (UINT64) * (Snp->MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT));
|
||||||
|
if (Tmp == NULL) {
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
CopyMem (Tmp, Snp->RecycledTxBuf, sizeof (UINT64) * Snp->RecycledTxBufCount);
|
||||||
|
FreePool (Snp->RecycledTxBuf);
|
||||||
|
Snp->RecycledTxBuf = Tmp;
|
||||||
|
Snp->MaxRecycledTxBuf += SNP_TX_BUFFER_INCREASEMENT;
|
||||||
|
}
|
||||||
|
Snp->RecycledTxBuf[Snp->RecycledTxBufCount] = Db->TxBuffer[Index];
|
||||||
|
Snp->RecycledTxBufCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -216,7 +241,23 @@ SnpUndi32GetStatus (
|
||||||
goto ON_EXIT;
|
goto ON_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = PxeGetStatus (Snp, InterruptStatus, TxBuf);
|
if (Snp->RecycledTxBufCount == 0 && TxBuf != NULL) {
|
||||||
|
Status = PxeGetStatus (Snp, InterruptStatus, TRUE);
|
||||||
|
} else {
|
||||||
|
Status = PxeGetStatus (Snp, InterruptStatus, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TxBuf != NULL) {
|
||||||
|
//
|
||||||
|
// Get a recycled buf from Snp->RecycledTxBuf
|
||||||
|
//
|
||||||
|
if (Snp->RecycledTxBufCount == 0) {
|
||||||
|
*TxBuf = NULL;
|
||||||
|
} else {
|
||||||
|
Snp->RecycledTxBufCount--;
|
||||||
|
*TxBuf = (VOID *) (UINTN) Snp->RecycledTxBuf[Snp->RecycledTxBufCount];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ON_EXIT:
|
ON_EXIT:
|
||||||
gBS->RestoreTPL (OldTpl);
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Implementation of driver entry point and driver binding protocol.
|
Implementation of driver entry point and driver binding protocol.
|
||||||
|
|
||||||
Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed
|
This program and the accompanying materials are licensed
|
||||||
and made available under the terms and conditions of the BSD License which
|
and made available under the terms and conditions of the BSD License which
|
||||||
accompanies this distribution. The full text of the license may be found at
|
accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -403,6 +403,14 @@ SimpleNetworkDriverStart (
|
||||||
|
|
||||||
Snp->TxRxBufferSize = 0;
|
Snp->TxRxBufferSize = 0;
|
||||||
Snp->TxRxBuffer = NULL;
|
Snp->TxRxBuffer = NULL;
|
||||||
|
|
||||||
|
Snp->RecycledTxBuf = AllocatePool (sizeof (UINT64) * SNP_TX_BUFFER_INCREASEMENT);
|
||||||
|
if (Snp->RecycledTxBuf == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto Error_DeleteSNP;
|
||||||
|
}
|
||||||
|
Snp->MaxRecycledTxBuf = SNP_TX_BUFFER_INCREASEMENT;
|
||||||
|
Snp->RecycledTxBufCount = 0;
|
||||||
|
|
||||||
if (Nii->Revision >= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION) {
|
if (Nii->Revision >= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION) {
|
||||||
Snp->IfNum = Nii->IfNum;
|
Snp->IfNum = Nii->IfNum;
|
||||||
|
@ -678,6 +686,10 @@ SimpleNetworkDriverStart (
|
||||||
|
|
||||||
Error_DeleteSNP:
|
Error_DeleteSNP:
|
||||||
|
|
||||||
|
if (Snp->RecycledTxBuf != NULL) {
|
||||||
|
FreePool (Snp->RecycledTxBuf);
|
||||||
|
}
|
||||||
|
|
||||||
PciIo->FreeBuffer (
|
PciIo->FreeBuffer (
|
||||||
PciIo,
|
PciIo,
|
||||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||||
|
@ -790,6 +802,8 @@ SimpleNetworkDriverStop (
|
||||||
PxeShutdown (Snp);
|
PxeShutdown (Snp);
|
||||||
PxeStop (Snp);
|
PxeStop (Snp);
|
||||||
|
|
||||||
|
FreePool (Snp->RecycledTxBuf);
|
||||||
|
|
||||||
PciIo = Snp->PciIo;
|
PciIo = Snp->PciIo;
|
||||||
PciIo->FreeBuffer (
|
PciIo->FreeBuffer (
|
||||||
PciIo,
|
PciIo,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Declaration of strctures and functions for SnpDxe driver.
|
Declaration of strctures and functions for SnpDxe driver.
|
||||||
|
|
||||||
Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed
|
This program and the accompanying materials are licensed
|
||||||
and made available under the terms and conditions of the BSD License which
|
and made available under the terms and conditions of the BSD License which
|
||||||
accompanies this distribution. The full text of the license may be found at
|
accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -49,6 +49,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#define PCI_BAR_MEM_MODE 0x00000000
|
#define PCI_BAR_MEM_MODE 0x00000000
|
||||||
#define PCI_BAR_MEM_64BIT 0x00000004
|
#define PCI_BAR_MEM_64BIT 0x00000004
|
||||||
|
|
||||||
|
#define SNP_TX_BUFFER_INCREASEMENT MAX_XMIT_BUFFERS
|
||||||
|
#define SNP_MAX_TX_BUFFER_NUM 65536
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
(EFIAPI *ISSUE_UNDI32_COMMAND) (
|
(EFIAPI *ISSUE_UNDI32_COMMAND) (
|
||||||
|
@ -130,6 +133,19 @@ typedef struct {
|
||||||
// i.e. PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED
|
// i.e. PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED
|
||||||
//
|
//
|
||||||
BOOLEAN MediaStatusSupported;
|
BOOLEAN MediaStatusSupported;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Array of the recycled transmit buffer address from UNDI.
|
||||||
|
//
|
||||||
|
UINT64 *RecycledTxBuf;
|
||||||
|
//
|
||||||
|
// The maximum number of recycled buffer pointers in RecycledTxBuf.
|
||||||
|
//
|
||||||
|
UINT32 MaxRecycledTxBuf;
|
||||||
|
//
|
||||||
|
// Current number of recycled buffer pointers in RecycledTxBuf.
|
||||||
|
//
|
||||||
|
UINT32 RecycledTxBufCount;
|
||||||
} SNP_DRIVER;
|
} SNP_DRIVER;
|
||||||
|
|
||||||
#define EFI_SIMPLE_NETWORK_DEV_FROM_THIS(a) CR (a, SNP_DRIVER, Snp, SNP_DRIVER_SIGNATURE)
|
#define EFI_SIMPLE_NETWORK_DEV_FROM_THIS(a) CR (a, SNP_DRIVER, Snp, SNP_DRIVER_SIGNATURE)
|
||||||
|
|
Loading…
Reference in New Issue