From FreeBSD (appropriate pieces of revs 1.90 and 1.92):

Only clear the IFF_OACTIVE flag when we have a chance of being able
to queue a packet to the hardware, instead of when the hardware queue
is empty, and fix up handling and prodding of the tx.

These fixes clear up an occasional "sk0: watchdog timeout" from the
on-board ethernet on my Asus A8V motherboard.

OK christos@
This commit is contained in:
riz 2005-11-19 21:45:50 +00:00
parent 6e11a90e46
commit 8b1bf051e2

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_sk.c,v 1.16 2005/09/11 23:49:39 xtraeme Exp $ */
/* $NetBSD: if_sk.c,v 1.17 2005/11/19 21:45:50 riz Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@ -1759,11 +1759,13 @@ sk_start(struct ifnet *ifp)
return;
/* Transmit */
sc_if->sk_cdata.sk_tx_prod = idx;
CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
if (idx != sc_if->sk_cdata.sk_tx_prod) {
sc_if->sk_cdata.sk_tx_prod = idx;
CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
/* Set a timeout in case the chip goes out to lunch. */
ifp->if_timer = 5;
/* Set a timeout in case the chip goes out to lunch. */
ifp->if_timer = 5;
}
}
@ -1888,7 +1890,7 @@ void
sk_txeof(struct sk_if_softc *sc_if)
{
struct sk_softc *sc = sc_if->sk_softc;
struct sk_tx_desc *cur_tx = NULL;
struct sk_tx_desc *cur_tx;
struct ifnet *ifp = &sc_if->sk_ethercom.ec_if;
u_int32_t idx;
struct sk_txmap_entry *entry;
@ -1937,10 +1939,10 @@ sk_txeof(struct sk_if_softc *sc_if)
else /* nudge chip to keep tx ring moving */
CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
sc_if->sk_cdata.sk_tx_cons = idx;
if (cur_tx != NULL)
if (sc_if->sk_cdata.sk_tx_cnt < SK_TX_RING_CNT - 2)
ifp->if_flags &= ~IFF_OACTIVE;
sc_if->sk_cdata.sk_tx_cons = idx;
}
void