summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorEvan Lojewski <github@meklort.com>2020-07-11 14:30:46 -0600
committerGitHub <noreply@github.com>2020-07-11 14:30:46 -0600
commit76db92af3f904b1c1d78b113510f2fb9f2eb6b29 (patch)
tree65adf631f1e47121c7d80fdc4ce09a6113819879 /libs
parent2a370d432f5bb0580f9bfb5c24465f13c2726604 (diff)
downloadbcm5719-ortega-76db92af3f904b1c1d78b113510f2fb9f2eb6b29.tar.gz
bcm5719-ortega-76db92af3f904b1c1d78b113510f2fb9f2eb6b29.zip
network: Fix a hang that can occur when the network drops during a transmission. (#86)
Diffstat (limited to 'libs')
-rw-r--r--libs/NCSI/ncsi.c10
-rw-r--r--libs/Network/rx.c30
2 files changed, 36 insertions, 4 deletions
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)
{
OpenPOWER on IntegriCloud