Skip to content

drivers: ethernet: nxp_enet_qos: reclaim TX resources on link drop - #117399

Open
bperseghetti wants to merge 2 commits into
zephyrproject-rtos:mainfrom
CogniPilot:pr-deps-enet-qos-rx-reliability
Open

drivers: ethernet: nxp_enet_qos: reclaim TX resources on link drop#117399
bperseghetti wants to merge 2 commits into
zephyrproject-rtos:mainfrom
CogniPilot:pr-deps-enet-qos-rx-reliability

Conversation

@bperseghetti

@bperseghetti bperseghetti commented Aug 26, 2026

Copy link
Copy Markdown
Member

Two RX/TX reliability fixes for the enet_qos driver.

Restore the RX buffer address on every drop path. The DMA writeback clobbers RDES0, which in read format is the buffer address, so any dropped frame handed the descriptor back to the DMA with a corrupt address and permanently poisoned that ring slot.

Reclaim TX resources when the link drops. A frame handed to the transmit DMA when carrier is lost is never written back, so the completion interrupt that returns the packet and the single transmit slot never arrives, and every later send fails with -EBUSY until reset. A bounded TX watchdog abandons the transmission, the abort and completion paths are serialized under irq_lock so exactly one of them releases the packet, and speed and duplex are programmed only with the transmitter and receiver disabled before carrier is announced.

Validated on NXP MCXN947 hardware across repeated physical link flaps. RX and TX both recover on every cycle and the TX buffer pool returns to its baseline with no leaked buffers.

Every RX descriptor writeback clobbers RDES0, which in read format is
the buffer address: the writeback formats alias it with the VLAN tag or
the timestamp low word. The success path restores it before handing the
descriptor back to the DMA, but the four drop paths (errored frame,
packet alloc failure, bad length, fragment alloc failure) re-arm the
descriptor with whatever the writeback left there, so the next use of
that slot makes the DMA write into flash or reserved address space and
receive stops permanently. Restore the reserved buffer's address on
every drop path, as the success path does.

Signed-off-by: Benjamin Perseghetti <bperseghetti@rudislabs.com>
A frame handed to the ENET QoS transmit DMA when the link goes down is
never written back, so the completion interrupt that returns the packet
and frees the single transmit slot never arrives. The slot stays taken
across the link coming back, every later send on the interface fails
with -EBUSY, and the packet and its fragments are gone from their pools
for good, so a handful of link transitions exhaust the buffer pool and
the interface stops transmitting.

Give the driver a claim and release pair so that completion and
abandonment race for the packet and exactly one of them returns it, and
arm a transmit watchdog, CONFIG_ETH_NXP_ENET_QOS_TX_TIMEOUT_MS, that
takes the descriptors back, flushes the transmit queue and reinitializes
the ring when the DMA does not finish. Abandon an outstanding frame from
the PHY callback on carrier loss, and program speed and duplex with the
transmitter and receiver disabled before the carrier is announced, so
the MAC configuration write cannot land on a frame the stack has already
handed to the DMA.

Publish the packet, arm the watchdog and start the DMA as one step under
irq_lock so an abort can never observe a half-built submission, and flush
the transmit queue with a bounded wait.

Signed-off-by: Benjamin Perseghetti <bperseghetti@rudislabs.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants