diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c index b7d5816b28c3..979748dd135a 100644 --- a/sys/dev/dc/if_dc.c +++ b/sys/dev/dc/if_dc.c @@ -1393,9 +1393,7 @@ dc_setcfg(struct dc_softc *sc, int media) __func__); if (!((isr & DC_ISR_RX_STATE) == DC_RXSTATE_STOPPED || (isr & DC_ISR_RX_STATE) == DC_RXSTATE_WAIT) && - !(DC_IS_CENTAUR(sc) || DC_IS_CONEXANT(sc) || - (DC_IS_DAVICOM(sc) && pci_get_revid(sc->dc_dev) >= - DC_REVISION_DM9102A))) + !DC_HAS_BROKEN_RXSTATE(sc)) device_printf(sc->dc_dev, "%s: failed to force rx to idle state\n", __func__); @@ -2884,8 +2882,12 @@ dc_tick(void *xsc) if (sc->dc_link == 0) mii_tick(mii); } else { - r = CSR_READ_4(sc, DC_ISR); - if ((r & DC_ISR_RX_STATE) == DC_RXSTATE_WAIT && + /* + * For NICs which never report DC_RXSTATE_WAIT, we + * have to bite the bullet... + */ + if ((DC_HAS_BROKEN_RXSTATE(sc) || (CSR_READ_4(sc, + DC_ISR) & DC_ISR_RX_STATE) == DC_RXSTATE_WAIT) && sc->dc_cdata.dc_tx_cnt == 0) { mii_tick(mii); if (!(mii->mii_media_status & IFM_ACTIVE)) diff --git a/sys/dev/dc/if_dcreg.h b/sys/dev/dc/if_dcreg.h index 3ec704780bc0..eb798dcb19bb 100644 --- a/sys/dev/dc/if_dcreg.h +++ b/sys/dev/dc/if_dcreg.h @@ -182,6 +182,10 @@ #define DC_RXSTATE_FLUSH 0x000C0000 /* 110 - flush from FIFO */ #define DC_RXSTATE_DEQUEUE 0x000E0000 /* 111 - dequeue from FIFO */ +#define DC_HAS_BROKEN_RXSTATE(x) \ + (DC_IS_CENTAUR(x) || DC_IS_CONEXANT(x) || (DC_IS_DAVICOM(x) && \ + pci_get_revid((x)->dc_dev) >= DC_REVISION_DM9102A)) + #define DC_TXSTATE_RESET 0x00000000 /* 000 - reset */ #define DC_TXSTATE_FETCH 0x00100000 /* 001 - fetching descriptor */ #define DC_TXSTATE_WAITEND 0x00200000 /* 010 - wait for tx end */