diff --git a/drivers/bdring.c b/drivers/bdring.c index 5a5e5c8..eb95adf 100644 --- a/drivers/bdring.c +++ b/drivers/bdring.c @@ -107,7 +107,8 @@ int net_initRings(net_bufdesc_ring_t *rings, const size_t *sizes, size_t nrings, for (i = 0; i < nrings; ++i) { rings[i].ring = p; rings[i].bufp = bufp; - rings[i].head = rings[i].tail = 0; + atomic_init(&rings[i].head, 0); + atomic_init(&rings[i].tail, 0); rings[i].last = sizes[i] - 1; rings[i].phys = phys; rings[i].ops = ops; @@ -131,11 +132,11 @@ size_t net_receivePackets(net_bufdesc_ring_t *ring, struct netif *ni, unsigned e mutexLock(ring->lock); n = 0; - i = ring->head; + i = atomic_load(&ring->head); pkt = NULL; for (;;) { - if (i == ring->tail) { + if (i == atomic_load(&ring->tail)) { break; } @@ -172,7 +173,7 @@ size_t net_receivePackets(net_bufdesc_ring_t *ring, struct netif *ni, unsigned e ++n; } - ring->head = i; + atomic_store(&ring->head, i); mutexUnlock(ring->lock); return n; } @@ -190,7 +191,7 @@ size_t net_refillRx(net_bufdesc_ring_t *ring, size_t ethpad) nxt = (i + 1) & ring->last; // NOTE: 2^n ring size verified in net_initRings sz = ring->ops->pkt_buf_sz; - while (nxt != ring->head) { + while (nxt != atomic_load(&ring->head)) { p = net_allocDMAPbuf(&pa, sz); if (p == NULL) { break; @@ -206,7 +207,7 @@ size_t net_refillRx(net_bufdesc_ring_t *ring, size_t ethpad) ++n; } - ring->tail = i; + atomic_store(&ring->tail, i); mutexUnlock(ring->lock); return n; } @@ -218,7 +219,7 @@ size_t net_reapTxFinished(net_bufdesc_ring_t *ring) mutexLock(ring->lock); n = 0; - i = ring->tail; + i = atomic_load(&ring->tail); head = atomic_load(&ring->head); while (i != head) { if (ring->ops->nextTxDone(ring, i) == 0) { @@ -295,7 +296,7 @@ size_t net_transmitPacket(net_bufdesc_ring_t *ring, struct pbuf *p) mutexLock(ring->lock); // NOTE: 2^n ring size verified in net_initRings n = atomic_load(&ring->tail); // access tail once - it may be advanced by tx_done thread - i = ring->head; + i = atomic_load(&ring->head); n = (n - i - 1) & ring->last; if (n > MAX_TX_FRAGMENTS) { n = MAX_TX_FRAGMENTS; diff --git a/drivers/bdring.h b/drivers/bdring.h index a106059..15af422 100644 --- a/drivers/bdring.h +++ b/drivers/bdring.h @@ -46,7 +46,7 @@ struct net_bufdesc_ring_ { volatile void *ring; struct pbuf **bufp; - volatile unsigned head, tail; + _Atomic volatile unsigned head, tail; unsigned last; addr_t phys; const net_bufdesc_ops_t *ops; diff --git a/drivers/imx-enet-regs.h b/drivers/imx-enet-regs.h index 947c3ed..46f9277 100644 --- a/drivers/imx-enet-regs.h +++ b/drivers/imx-enet-regs.h @@ -308,7 +308,7 @@ struct enet_regs { typedef struct { uint16_t len; /* for last frag = whole frame size? (TBV) */ - uint16_t flags; + _Atomic volatile uint16_t flags; uint32_t addr; /* 64B-aligned buffer [size = TRUNC_FL ?] */ } enet_legacy_desc_t; @@ -317,7 +317,8 @@ typedef struct /* first 3 same as enet_short_desc_t */ union { struct { - uint16_t len, flags; + uint16_t len; + _Atomic volatile uint16_t flags; uint32_t addr; }; enet_legacy_desc_t legacy; diff --git a/drivers/imx-enet.c b/drivers/imx-enet.c index b52e116..1261eae 100644 --- a/drivers/imx-enet.c +++ b/drivers/imx-enet.c @@ -49,7 +49,7 @@ typedef struct volatile struct enet_regs *mmio; struct netif *netif; - unsigned drv_exit; + _Atomic volatile unsigned drv_exit; #define PRIV_RESOURCES(s) &(s)->irq_lock, 3, ~0x03 handle_t irq_lock, tx_lock; @@ -378,7 +378,7 @@ static size_t enet_nextRxBufferSize(const net_bufdesc_ring_t *ring, size_t i) } #endif - if ((desc->flags & ENET_DESC_RDY) != 0) { + if ((atomic_load(&desc->flags) & ENET_DESC_RDY) != 0) { return 0; } @@ -396,7 +396,7 @@ static int enet_pktRxFinished(const net_bufdesc_ring_t *ring, size_t i) { volatile enet_buf_desc_t *desc = (volatile enet_buf_desc_t *)ring->ring + i; - return desc->flags & ENET_DESC_LAST; + return atomic_load(&desc->flags) & ENET_DESC_LAST; } @@ -418,7 +418,7 @@ static int enet_nextTxDone(const net_bufdesc_ring_t *ring, size_t i) { volatile enet_buf_desc_t *desc = (volatile enet_buf_desc_t *)ring->ring + i; - return !(desc->flags & ENET_DESC_RDY); + return !(atomic_load(&desc->flags) & ENET_DESC_RDY); } @@ -1016,6 +1016,8 @@ static int enet_initDevice(enet_state_t *state, int irq, int mdio) return err; } + atomic_init(&state->drv_exit, 0x0); + err = enet_clockEnable(state); if (err < 0) { return err;