summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2002-06-30 21:59:08 +0000
committerluigi <luigi@FreeBSD.org>2002-06-30 21:59:08 +0000
commite34ef2877bee4cc1dd4c0c6702add67b8c81c6a0 (patch)
treec49e01c1e0017c8dc98db742120350df62e00c37 /sys/pci
parenta8195db27e3129f3da53acacef257e34d842be6a (diff)
downloadFreeBSD-src-e34ef2877bee4cc1dd4c0c6702add67b8c81c6a0.zip
FreeBSD-src-e34ef2877bee4cc1dd4c0c6702add67b8c81c6a0.tar.gz
Make sure that if_timer does not get reset if there are packets
still queued for transmission. This should solve the problem of the device stalling on transmissions if some link event prevents transmission. There are other drivers which have the same problem and need to be fixed in the same way. MFC after: 3 days
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/if_sis.c28
-rw-r--r--sys/pci/if_sisreg.h2
2 files changed, 11 insertions, 19 deletions
diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c
index 22a2163..3801957 100644
--- a/sys/pci/if_sis.c
+++ b/sys/pci/if_sis.c
@@ -1393,31 +1393,24 @@ void sis_rxeoc(sc)
static void sis_txeof(sc)
struct sis_softc *sc;
{
- struct sis_desc *cur_tx = NULL;
struct ifnet *ifp;
u_int32_t idx;
ifp = &sc->arpcom.ac_if;
- /* Clear the timeout timer. */
- ifp->if_timer = 0;
-
/*
* Go through our tx list and free mbufs for those
* frames that have been transmitted.
*/
- idx = sc->sis_cdata.sis_tx_cons;
- while (idx != sc->sis_cdata.sis_tx_prod) {
- cur_tx = &sc->sis_ldata.sis_tx_list[idx];
+ for (idx = sc->sis_cdata.sis_tx_cons; sc->sis_cdata.sis_tx_cnt > 0;
+ sc->sis_cdata.sis_tx_cnt--, SIS_INC(idx, SIS_TX_LIST_CNT) ) {
+ struct sis_desc *cur_tx = &sc->sis_ldata.sis_tx_list[idx];
if (SIS_OWNDESC(cur_tx))
break;
- if (cur_tx->sis_ctl & SIS_CMDSTS_MORE) {
- sc->sis_cdata.sis_tx_cnt--;
- SIS_INC(idx, SIS_TX_LIST_CNT);
+ if (cur_tx->sis_ctl & SIS_CMDSTS_MORE)
continue;
- }
if (!(cur_tx->sis_ctl & SIS_CMDSTS_PKT_OK)) {
ifp->if_oerrors++;
@@ -1437,16 +1430,15 @@ static void sis_txeof(sc)
bus_dmamap_unload(sc->sis_tag, cur_tx->sis_map);
bus_dmamap_destroy(sc->sis_tag, cur_tx->sis_map);
}
-
- sc->sis_cdata.sis_tx_cnt--;
- SIS_INC(idx, SIS_TX_LIST_CNT);
- ifp->if_timer = 0;
}
- sc->sis_cdata.sis_tx_cons = idx;
-
- if (cur_tx != NULL)
+ if (idx != sc->sis_cdata.sis_tx_cons) {
+ /* we freed up some buffers */
+ sc->sis_cdata.sis_tx_cons = idx;
ifp->if_flags &= ~IFF_OACTIVE;
+ }
+
+ ifp->if_timer = (sc->sis_cdata.sis_tx_cnt == 0) ? 0 : 5;
return;
}
diff --git a/sys/pci/if_sisreg.h b/sys/pci/if_sisreg.h
index 8244f2a..2e2ee19 100644
--- a/sys/pci/if_sisreg.h
+++ b/sys/pci/if_sisreg.h
@@ -309,7 +309,7 @@ struct sis_desc {
#define SIS_LASTDESC(x) (!((x)->sis_ctl & SIS_CMDSTS_MORE)))
#define SIS_OWNDESC(x) ((x)->sis_ctl & SIS_CMDSTS_OWN)
-#define SIS_INC(x, y) { if (++(x) == y) x = 0; }
+#define SIS_INC(x, y) (x) = ((x) == ((y)-1)) ? 0 : (x)+1
#define SIS_RXBYTES(x) (((x)->sis_ctl & SIS_CMDSTS_BUFLEN) - ETHER_CRC_LEN)
#define SIS_RXSTAT_COLL 0x00010000
OpenPOWER on IntegriCloud