From 76db92af3f904b1c1d78b113510f2fb9f2eb6b29 Mon Sep 17 00:00:00 2001 From: Evan Lojewski Date: Sat, 11 Jul 2020 14:30:46 -0600 Subject: network: Fix a hang that can occur when the network drops during a transmission. (#86) --- libs/NCSI/ncsi.c | 10 ++++++++-- libs/Network/rx.c | 30 ++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) (limited to 'libs') diff --git a/libs/NCSI/ncsi.c b/libs/NCSI/ncsi.c index 91197a4..55b7dbc 100644 --- a/libs/NCSI/ncsi.c +++ b/libs/NCSI/ncsi.c @@ -69,7 +69,7 @@ uint8_t gPackageID = ((0 << PACKAGE_ID_SHIFT) | CHANNEL_ID_PACKAGE); // Response frame - global and usable by one thread at a time only. -NetworkFrame_t gResponseFrame = +NetworkFrame_t gResponseFrame = { .responsePacket = { .DestinationAddress = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, @@ -717,8 +717,14 @@ void NCSI_TxPacket(uint32_t *packet, uint32_t packet_len) txControl.bits.LastByteCount = packet_len; /* 2 bits - automatically rounded. */ // Wait for enough free space. - while (APE_PERI.BmcToNcTxStatus.bits.InFifo < packetWords) + int max_loops = 0x10000; + while (APE_PERI.BmcToNcTxStatus.bits.InFifo < packetWords && --max_loops) + ; + + if (!max_loops) { + printf("Error waiting for fifo space. Dropping NCSI packet."); + return; } // Transmit. diff --git a/libs/Network/rx.c b/libs/Network/rx.c index f1710d2..bb721d2 100644 --- a/libs/Network/rx.c +++ b/libs/Network/rx.c @@ -179,8 +179,34 @@ bool Network_PassthroughRxPatcket(NetworkPort_t *port) words--; } - while (APE_PERI.BmcToNcTxStatus.bits.InFifo < words) - ; + if (control.bits.first && APE_PERI.BmcToNcTxStatus.bits.InFifo < words) + { + // Not enough space in the fifo. + // Exit and check back next loop - after the network has been reset if needed. + return false; + } + else + { + // This can hang durning network reconfiguration events. + // Timeout if no packets are draining - recovery code outside of this block will handle it. + int max_loops = 0x10000; + while (APE_PERI.BmcToNcTxStatus.bits.InFifo < words && --max_loops) + { + // TODO: This should check for a network problem and exit if that is the case. + } + + if (!max_loops) + { + printf("Error waiting for fifo space. Network may be down."); + // Drop all packets that remain and exit. + retire.bits.Head = blockid; + retire.bits.Tail = rxbuf.bits.Tail; + *((RegAPERxPoolRetire_t *)port->rx_retire) = retire; + + // Tell the hardware that there are no more bytes to send. + APE_PERI.BmcToNcTxBufferLast.r32 = 0; + } + } if (control.bits.not_last) { -- cgit v1.2.1