diff options
-rw-r--r-- | EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118Dxe.c | 77 |
1 files changed, 49 insertions, 28 deletions
diff --git a/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118Dxe.c b/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118Dxe.c index 5b7eda65c3..4de5204899 100644 --- a/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118Dxe.c +++ b/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118Dxe.c @@ -14,7 +14,6 @@ #include "Lan9118Dxe.h"
-
typedef struct {
MAC_ADDR_DEVICE_PATH Lan9118;
EFI_DEVICE_PATH_PROTOCOL End;
@@ -1312,6 +1311,7 @@ SnpReceive ( )
{
LAN9118_DRIVER *LanDriver;
+ UINT32 IntSts;
UINT32 RxFifoStatus;
UINT32 NumPackets;
UINT32 RxCfgValue;
@@ -1346,6 +1346,27 @@ SnpReceive ( 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
DroppedFrames = MmioRead32 (LAN9118_RX_DROP);
LanDriver->Stats.RxDroppedFrames += DroppedFrames;
@@ -1453,6 +1474,33 @@ SnpReceive ( 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)
if (MmioRead32 (LAN9118_INT_STS) & INSTS_RXE) {
DEBUG ((EFI_D_WARN, "Warning: Receiver Error. Restarting...\n"));
@@ -1481,33 +1529,6 @@ SnpReceive ( 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)
UINT64 EndClock = GetPerformanceCounter ();
DEBUG ((EFI_D_ERROR, "Receive Time processing: %d counts @ %d Hz\n", StartClock - EndClock,Perf));
|