diff options
author | marius <marius@FreeBSD.org> | 2008-08-29 20:31:41 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2008-08-29 20:31:41 +0000 |
commit | 05def23cd841458250224effc876a1566b5fbcd4 (patch) | |
tree | 55f0e91a915194eb313484e53b84b63450ae5bb7 /sys | |
parent | ff9581861d753816438c5400850ca305d42886cd (diff) | |
download | FreeBSD-src-05def23cd841458250224effc876a1566b5fbcd4.zip FreeBSD-src-05def23cd841458250224effc876a1566b5fbcd4.tar.gz |
For chips with a broken DC_ISR_RX_STATE which f.e. never signals
stopped nor the waiting state and also no other means to check
whether the receiver is idle (see also r163774), we have no choice
than to call mii_tick(9) unconditionally even in the case of the
DC_REDUCED_MII_POLL handling as far as the RX side is concerned.
This isn't necessarily worse than checking whether RX is idle
though because unlike as with TX we're racing with the hardware,
which might receive packets any time while we poll the MII, anyway.
Reported and tested by: Jacob Owens
Reviewed by: yongari
MFC after: 3 days
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/dc/if_dc.c | 12 | ||||
-rw-r--r-- | sys/dev/dc/if_dcreg.h | 4 |
2 files changed, 11 insertions, 5 deletions
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c index b7d5816..979748d 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 3ec7047..eb798dc 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 */ |