Changeset 29f9822 in rtems-libbsd


Ignore:
Timestamp:
06/01/22 07:45:13 (19 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
5-freebsd-12
Children:
484186e
Parents:
62d320d
git-author:
Sebastian Huber <sebastian.huber@…> (06/01/22 07:45:13)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/01/22 07:55:25)
Message:

if_atsam: Recover from receive freezes

Under unknown conditions the receive path ended up in a frozen state.
In this state, the DMA and driver descriptor head were equal and all
receive descriptors had the used bit set. So, the DMA was unable to
store received frames. However, the receive daemon was never woken up
to refill the receive buffers. It seems that the RXUBR interrupt can be
used to recover from this state.

Update #4651.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • rtemsbsd/sys/dev/atsam/if_atsam.c

    r62d320d r29f9822  
    109109#define IGNORE_RX_ERR false
    110110
     111#define RX_INTERRUPTS (GMAC_ISR_RCOMP | GMAC_ISR_RXUBR | GMAC_ISR_ROVR)
     112
    111113#define RX_DESC_LOG2 3
    112114#define RX_DESC_COUNT (1U << RX_DESC_LOG2)
     
    188190                /* Software */
    189191                uint32_t rx_overrun_errors;
     192                uint32_t rx_used_bit_reads;
    190193                uint32_t rx_interrupts;
    191194                uint32_t tx_tur_errors;
     
    401404
    402405        /* Check receive interrupts */
    403         if (__predict_true((is & (GMAC_IER_ROVR | GMAC_IER_RCOMP)) != 0)) {
    404                 if (__predict_false((is & GMAC_IER_ROVR) != 0)) {
     406        if (__predict_true((is & RX_INTERRUPTS) != 0)) {
     407                if (__predict_false((is & GMAC_ISR_RXUBR) != 0)) {
     408                        ++sc->stats.rx_used_bit_reads;
     409                }
     410
     411                if (__predict_false((is & GMAC_ISR_ROVR) != 0)) {
    405412                        ++sc->stats.rx_overrun_errors;
    406413                }
     
    408415                ++sc->stats.rx_interrupts;
    409416
    410                 /* Erase the interrupts for RX completion and errors */
    411                 pHw->GMAC_IDR = GMAC_IER_RCOMP | GMAC_IER_ROVR;
     417                /* Disable RX interrupts */
     418                pHw->GMAC_IDR = RX_INTERRUPTS;
    412419
    413420                (void)rtems_event_send(sc->rx_daemon_tid,
     
    512519
    513520                /* Enable RX interrupts */
    514                 pHw->GMAC_IER = GMAC_IER_RCOMP | GMAC_IER_ROVR;
     521                pHw->GMAC_IER = RX_INTERRUPTS;
    515522
    516523                (void) rtems_event_receive(ATSAMV7_ETH_RX_EVENT_INTERRUPT,
     
    12931300            CTLFLAG_RD, &sc->stats.rx_overrun_errors, 0,
    12941301            "RX overrun errors");
     1302        SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "rx_used_bit_reads",
     1303            CTLFLAG_RD, &sc->stats.rx_used_bit_reads, 0,
     1304            "RX used bit reads");
    12951305        SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "rx_interrupts",
    12961306            CTLFLAG_RD, &sc->stats.rx_interrupts, 0,
Note: See TracChangeset for help on using the changeset viewer.