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
|
||||
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
|
||||
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
|
||||
|
@ -16,15 +16,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
#include "Snp.h"
|
||||
|
||||
/**
|
||||
Call undi to get the status of the interrupts, get the list of transmit
|
||||
buffers that completed transmitting.
|
||||
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.
|
||||
|
||||
@param Snp Pointer to snp driver structure.
|
||||
@param InterruptStatusPtr A non null pointer to contain the interrupt
|
||||
status.
|
||||
@param TransmitBufferListPtrs A non null pointer to contain the list of
|
||||
pointers of previous transmitted buffers whose
|
||||
transmission was completed asynchrnously.
|
||||
@param 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
|
||||
|
@ -35,19 +35,23 @@ EFI_STATUS
|
|||
PxeGetStatus (
|
||||
SNP_DRIVER *Snp,
|
||||
UINT32 *InterruptStatusPtr,
|
||||
VOID **TransmitBufferListPtr
|
||||
BOOLEAN GetTransmittedBuf
|
||||
)
|
||||
{
|
||||
PXE_DB_GET_STATUS *Db;
|
||||
UINT16 InterruptFlags;
|
||||
UINT32 Index;
|
||||
UINT64 *Tmp;
|
||||
|
||||
Tmp = NULL;
|
||||
Db = Snp->Db;
|
||||
Snp->Cdb.OpCode = PXE_OPCODE_GET_STATUS;
|
||||
|
||||
Snp->Cdb.OpFlags = 0;
|
||||
|
||||
if (TransmitBufferListPtr != NULL) {
|
||||
if (GetTransmittedBuf) {
|
||||
Snp->Cdb.OpFlags |= PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS;
|
||||
ZeroMem (Db->TxBuffer, sizeof (Db->TxBuffer));
|
||||
}
|
||||
|
||||
if (InterruptStatusPtr != NULL) {
|
||||
|
@ -116,13 +120,34 @@ PxeGetStatus (
|
|||
|
||||
}
|
||||
|
||||
if (TransmitBufferListPtr != NULL) {
|
||||
*TransmitBufferListPtr =
|
||||
(
|
||||
((Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN) != 0) ||
|
||||
((Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY) != 0)
|
||||
) ? 0 : (VOID *) (UINTN) Db->TxBuffer[0];
|
||||
|
||||
if (GetTransmittedBuf) {
|
||||
if ((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.
|
||||
//
|
||||
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;
|
||||
}
|
||||
|
||||
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:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
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
|
||||
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
|
||||
|
@ -404,6 +404,14 @@ SimpleNetworkDriverStart (
|
|||
Snp->TxRxBufferSize = 0;
|
||||
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) {
|
||||
Snp->IfNum = Nii->IfNum;
|
||||
|
||||
|
@ -678,6 +686,10 @@ SimpleNetworkDriverStart (
|
|||
|
||||
Error_DeleteSNP:
|
||||
|
||||
if (Snp->RecycledTxBuf != NULL) {
|
||||
FreePool (Snp->RecycledTxBuf);
|
||||
}
|
||||
|
||||
PciIo->FreeBuffer (
|
||||
PciIo,
|
||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||
|
@ -790,6 +802,8 @@ SimpleNetworkDriverStop (
|
|||
PxeShutdown (Snp);
|
||||
PxeStop (Snp);
|
||||
|
||||
FreePool (Snp->RecycledTxBuf);
|
||||
|
||||
PciIo = Snp->PciIo;
|
||||
PciIo->FreeBuffer (
|
||||
PciIo,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
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
|
||||
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
|
||||
|
@ -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_64BIT 0x00000004
|
||||
|
||||
#define SNP_TX_BUFFER_INCREASEMENT MAX_XMIT_BUFFERS
|
||||
#define SNP_MAX_TX_BUFFER_NUM 65536
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *ISSUE_UNDI32_COMMAND) (
|
||||
|
@ -130,6 +133,19 @@ typedef struct {
|
|||
// i.e. PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED
|
||||
//
|
||||
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;
|
||||
|
||||
#define EFI_SIMPLE_NETWORK_DEV_FROM_THIS(a) CR (a, SNP_DRIVER, Snp, SNP_DRIVER_SIGNATURE)
|
||||
|
|
Loading…
Reference in New Issue