summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2008-08-29 20:31:41 +0000
committermarius <marius@FreeBSD.org>2008-08-29 20:31:41 +0000
commit05def23cd841458250224effc876a1566b5fbcd4 (patch)
tree55f0e91a915194eb313484e53b84b63450ae5bb7 /sys
parentff9581861d753816438c5400850ca305d42886cd (diff)
downloadFreeBSD-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.c12
-rw-r--r--sys/dev/dc/if_dcreg.h4
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 */
OpenPOWER on IntegriCloud