Fix atomicity of Sonata ethernet driver. The network stack expects to be able to receive frames in one thread and send them from another. The Sonata Ethernet has some MMIO state that is shared between the two. This is not a complete fix because other SPI devices can also be interleaved. We see this sometimes when packets end up written into the LCD display.
diff --git a/sdk/include/platform/sunburst/platform-ethernet.hh b/sdk/include/platform/sunburst/platform-ethernet.hh index 418b1ef..0e9b3a7 100644 --- a/sdk/include/platform/sunburst/platform-ethernet.hh +++ b/sdk/include/platform/sunburst/platform-ethernet.hh
@@ -435,6 +435,12 @@ RecursiveMutex receiveBufferMutex; /** + * Reads and writes of the GPIO space use the same bits of the MMIO region + * and so need to be protected. + */ + FlagLockPriorityInherited gpioLock; + + /** * Buffer used by receive_frame. */ std::unique_ptr<uint8_t[]> receiveBuffer; @@ -620,6 +626,7 @@ std::optional<Frame> receive_frame() { + LockGuard g{gpioLock}; if (framesToProcess == 0) { uint16_t isr = register_read(RegisterOffset::InterruptStatus); @@ -759,6 +766,8 @@ return false; } + LockGuard g{gpioLock}; + // Wait for the transmit buffer to be available on the device side. // This needs to include the header. while ((register_read(RegisterOffset::TransmitQueueMemoryInfo) &