This is a discussion on fix if_timer logic for sis(4) within the lucky.openbsd.tech forums, part of the OpenBSD category; --> Make sure that if_timer does not get reset if there are packets still queued for transmission. This should solve ...
| |||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| 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. From luigi FreeBSD Index: if_sis.c ================================================== ================= RCS file: /cvs/src/sys/dev/pci/if_sis.c,v retrieving revision 1.54 diff -u -p -r1.54 if_sis.c --- if_sis.c 14 Oct 2005 22:59:38 -0000 1.54 +++ if_sis.c 15 Oct 2005 04:52:00 -0000 @@ -1421,22 +1421,18 @@ void sis_rxeoc(sc) 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]; bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap, ((caddr_t)cur_tx - sc->sc_listkva), @@ -1446,11 +1442,8 @@ void sis_txeof(sc) 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++; @@ -1475,18 +1468,15 @@ void sis_txeof(sc) m_freem(cur_tx->sis_mbuf); cur_tx->sis_mbuf = NULL; } - - 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; + } - return; + ifp->if_timer = (sc->sis_cdata.sis_tx_cnt == 0) ? 0 : 5; } void sis_tick(xsc) Index: if_sisreg.h ================================================== ================= RCS file: /cvs/src/sys/dev/pci/if_sisreg.h,v retrieving revision 1.22 diff -u -p -r1.22 if_sisreg.h --- if_sisreg.h 14 Oct 2005 22:59:38 -0000 1.22 +++ if_sisreg.h 15 Oct 2005 04:52:00 -0000 @@ -330,7 +330,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 |