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
This commit is contained in:
Marius Strobl 2008-08-29 20:31:41 +00:00
parent a0f01ecb62
commit d0d67284f8
2 changed files with 11 additions and 5 deletions

View File

@ -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))

View File

@ -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 */