EmbeddedPkg/Lan9118Dxe: Ignore spurious RXE errors

Spurious error might appear during network transaction,
ignore them when there are not relevant.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ronald Cron <Ronald.Cron@arm.com>
Reviewed-by: Olivier Martin <Olivier.Martin@arm.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18028 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Ronald Cron 2015-07-16 11:24:42 +00:00 committed by oliviermartin
parent cf1e634b4b
commit 1130106eb2
1 changed files with 49 additions and 28 deletions

View File

@ -14,7 +14,6 @@
#include "Lan9118Dxe.h" #include "Lan9118Dxe.h"
typedef struct { typedef struct {
MAC_ADDR_DEVICE_PATH Lan9118; MAC_ADDR_DEVICE_PATH Lan9118;
EFI_DEVICE_PATH_PROTOCOL End; EFI_DEVICE_PATH_PROTOCOL End;
@ -1312,6 +1311,7 @@ SnpReceive (
) )
{ {
LAN9118_DRIVER *LanDriver; LAN9118_DRIVER *LanDriver;
UINT32 IntSts;
UINT32 RxFifoStatus; UINT32 RxFifoStatus;
UINT32 NumPackets; UINT32 NumPackets;
UINT32 RxCfgValue; UINT32 RxCfgValue;
@ -1346,6 +1346,27 @@ SnpReceive (
return EFI_NOT_STARTED; return EFI_NOT_STARTED;
} }
//
// If the receiver raised the RXE error bit, check if the receiver status
// FIFO is full and if not just acknowledge the error. The two other
// conditions to get a RXE error are :
// . the RX data FIFO is read whereas being empty.
// . the RX status FIFO is read whereas being empty.
// The RX data and status FIFO are read by this driver only in the following
// code of this function. After the readings, the RXE error bit is checked
// and if raised, the controller is reset. Thus, at this point, we consider
// that the only valid reason to get an RXE error is the receiver status
// FIFO being full. And if this is not the case, we consider that this is
// a spurious error and we just get rid of it. We experienced such 'spurious'
// errors when running the driver on an A57 on Juno. No valid reason to
// explain those errors has been found so far and everything seems to
// work perfectly when they are just ignored.
//
IntSts = MmioRead32 (LAN9118_INT_STS);
if ((IntSts & INSTS_RXE) && (!(IntSts & INSTS_RSFF))) {
MmioWrite32 (LAN9118_INT_STS, INSTS_RXE);
}
// Count dropped frames // Count dropped frames
DroppedFrames = MmioRead32 (LAN9118_RX_DROP); DroppedFrames = MmioRead32 (LAN9118_RX_DROP);
LanDriver->Stats.RxDroppedFrames += DroppedFrames; LanDriver->Stats.RxDroppedFrames += DroppedFrames;
@ -1453,6 +1474,33 @@ SnpReceive (
RawData[Count] = MmioRead32 (LAN9118_RX_DATA); RawData[Count] = MmioRead32 (LAN9118_RX_DATA);
} }
// Get the destination address
if (DstAddr != NULL) {
Dst.Addr[0] = (RawData[0] & 0xFF);
Dst.Addr[1] = (RawData[0] & 0xFF00) >> 8;
Dst.Addr[2] = (RawData[0] & 0xFF0000) >> 16;
Dst.Addr[3] = (RawData[0] & 0xFF000000) >> 24;
Dst.Addr[4] = (RawData[1] & 0xFF);
Dst.Addr[5] = (RawData[1] & 0xFF00) >> 8;
CopyMem (DstAddr, &Dst, NET_ETHER_ADDR_LEN);
}
// Get the source address
if (SrcAddr != NULL) {
Src.Addr[0] = (RawData[1] & 0xFF0000) >> 16;
Src.Addr[1] = (RawData[1] & 0xFF000000) >> 24;
Src.Addr[2] = (RawData[2] & 0xFF);
Src.Addr[3] = (RawData[2] & 0xFF00) >> 8;
Src.Addr[4] = (RawData[2] & 0xFF0000) >> 16;
Src.Addr[5] = (RawData[2] & 0xFF000000) >> 24;
CopyMem (SrcAddr, &Src, NET_ETHER_ADDR_LEN);
}
// Get the protocol
if (Protocol != NULL) {
*Protocol = NTOHS (RawData[3] & 0xFFFF);
}
// Check for Rx errors (worst possible error) // Check for Rx errors (worst possible error)
if (MmioRead32 (LAN9118_INT_STS) & INSTS_RXE) { if (MmioRead32 (LAN9118_INT_STS) & INSTS_RXE) {
DEBUG ((EFI_D_WARN, "Warning: Receiver Error. Restarting...\n")); DEBUG ((EFI_D_WARN, "Warning: Receiver Error. Restarting...\n"));
@ -1481,33 +1529,6 @@ SnpReceive (
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
// Get the destination address
if (DstAddr != NULL) {
Dst.Addr[0] = (RawData[0] & 0xFF);
Dst.Addr[1] = (RawData[0] & 0xFF00) >> 8;
Dst.Addr[2] = (RawData[0] & 0xFF0000) >> 16;
Dst.Addr[3] = (RawData[0] & 0xFF000000) >> 24;
Dst.Addr[4] = (RawData[1] & 0xFF);
Dst.Addr[5] = (RawData[1] & 0xFF00) >> 8;
CopyMem (DstAddr, &Dst, NET_ETHER_ADDR_LEN);
}
// Get the source address
if (SrcAddr != NULL) {
Src.Addr[0] = (RawData[1] & 0xFF0000) >> 16;
Src.Addr[1] = (RawData[1] & 0xFF000000) >> 24;
Src.Addr[2] = (RawData[2] & 0xFF);
Src.Addr[3] = (RawData[2] & 0xFF00) >> 8;
Src.Addr[4] = (RawData[2] & 0xFF0000) >> 16;
Src.Addr[5] = (RawData[2] & 0xFF000000) >> 24;
CopyMem (SrcAddr,&Src, NET_ETHER_ADDR_LEN);
}
// Get the protocol
if (Protocol != NULL) {
*Protocol = NTOHS (RawData[3] & 0xFFFF);
}
#if defined(EVAL_PERFORMANCE) #if defined(EVAL_PERFORMANCE)
UINT64 EndClock = GetPerformanceCounter (); UINT64 EndClock = GetPerformanceCounter ();
DEBUG ((EFI_D_ERROR, "Receive Time processing: %d counts @ %d Hz\n", StartClock - EndClock,Perf)); DEBUG ((EFI_D_ERROR, "Receive Time processing: %d counts @ %d Hz\n", StartClock - EndClock,Perf));