summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2009-11-19 22:06:40 +0000
committerjhb <jhb@FreeBSD.org>2009-11-19 22:06:40 +0000
commitaffabaa85e18565f9c0a68b33c5b0f2e0587f05a (patch)
tree8407585eec2a1c0c6cadd011a7eb682949649bde
parentd49024b6f48c6368a3af0f695133bdc2a695e281 (diff)
downloadFreeBSD-src-affabaa85e18565f9c0a68b33c5b0f2e0587f05a.zip
FreeBSD-src-affabaa85e18565f9c0a68b33c5b0f2e0587f05a.tar.gz
- Add a private timer to drive the transmit watchdog instead of using
if_watchdog and if_timer. - Fix some issues in detach for sn(4), ste(4), and ti(4). Primarily this means calling ether_ifdetach() before anything else.
-rw-r--r--sys/dev/cm/smc90cx6.c28
-rw-r--r--sys/dev/cm/smc90cx6var.h2
-rw-r--r--sys/dev/ep/if_ep.c59
-rw-r--r--sys/dev/ep/if_epvar.h3
-rw-r--r--sys/dev/fatm/if_fatm.c21
-rw-r--r--sys/dev/fatm/if_fatmvar.h1
-rw-r--r--sys/dev/malo/if_malo.c24
-rw-r--r--sys/dev/malo/if_malo.h2
-rw-r--r--sys/dev/mwl/if_mwl.c26
-rw-r--r--sys/dev/mwl/if_mwlvar.h2
-rw-r--r--sys/dev/sn/if_sn.c57
-rw-r--r--sys/dev/sn/if_snvar.h2
-rw-r--r--sys/dev/ste/if_ste.c21
-rw-r--r--sys/dev/ste/if_stereg.h1
-rw-r--r--sys/dev/ti/if_ti.c43
-rw-r--r--sys/dev/ti/if_tireg.h2
-rw-r--r--sys/dev/vx/if_vx.c33
-rw-r--r--sys/dev/vx/if_vxvar.h2
18 files changed, 207 insertions, 122 deletions
diff --git a/sys/dev/cm/smc90cx6.c b/sys/dev/cm/smc90cx6.c
index 1dda17f..a0dedd9 100644
--- a/sys/dev/cm/smc90cx6.c
+++ b/sys/dev/cm/smc90cx6.c
@@ -124,7 +124,7 @@ static void cm_reset_locked(struct cm_softc *);
void cm_start(struct ifnet *);
void cm_start_locked(struct ifnet *);
int cm_ioctl(struct ifnet *, unsigned long, caddr_t);
-void cm_watchdog(struct ifnet *);
+void cm_watchdog(void *);
void cm_srint_locked(void *vsc);
static void cm_tint_locked(struct cm_softc *, int);
void cm_reconwatch_locked(void *);
@@ -194,11 +194,9 @@ cm_attach(dev)
ifp->if_output = arc_output;
ifp->if_start = cm_start;
ifp->if_ioctl = cm_ioctl;
- ifp->if_watchdog = cm_watchdog;
ifp->if_init = cm_init;
/* XXX IFQ_SET_READY(&ifp->if_snd); */
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
- ifp->if_timer = 0;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
arc_ifattach(ifp, linkaddress);
@@ -210,6 +208,7 @@ cm_attach(dev)
#endif
callout_init_mtx(&sc->sc_recon_ch, &sc->sc_mtx, 0);
+ callout_init_mtx(&sc->sc_watchdog_timer, &sc->sc_mtx, 0);
if_printf(ifp, "link addr 0x%02x (%d)\n", linkaddress, linkaddress);
return 0;
@@ -315,6 +314,7 @@ cm_reset_locked(sc)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ callout_reset(&sc->sc_watchdog_timer, hz, cm_watchdog, sc);
cm_start_locked(ifp);
}
@@ -332,7 +332,8 @@ cm_stop_locked(sc)
GETREG(CMRESET);
/* Stop watchdog timer */
- sc->sc_ifp->if_timer = 0;
+ callout_stop(&sc->sc_watchdog_timer);
+ sc->sc_timer = 0;
}
void
@@ -464,7 +465,7 @@ cm_start_locked(ifp)
PUTREG(CMCMD, CM_TX(buffer));
PUTREG(CMSTAT, sc->sc_intmask);
- ifp->if_timer = ARCTIMEOUT;
+ sc->sc_timer = ARCTIMEOUT;
}
m_freem(m);
@@ -627,7 +628,7 @@ cm_tint_locked(sc, isr)
if (isr & CM_TMA || sc->sc_broadcast[buffer])
ifp->if_opackets++;
#ifdef CMRETRANSMIT
- else if (ifp->if_flags & IFF_LINK2 && ifp->if_timer > 0
+ else if (ifp->if_flags & IFF_LINK2 && sc->sc_timer > 0
&& --sc->sc_retransmits[buffer] > 0) {
/* retransmit same buffer */
PUTREG(CMCMD, CM_TX(buffer));
@@ -657,7 +658,7 @@ cm_tint_locked(sc, isr)
*/
PUTREG(CMCMD, CM_TX(buffer));
/* init watchdog timer */
- ifp->if_timer = ARCTIMEOUT;
+ sc->sc_timer = ARCTIMEOUT;
#if defined(CM_DEBUG) && (CM_DEBUG > 1)
if_printf(ifp,
@@ -669,7 +670,7 @@ cm_tint_locked(sc, isr)
sc->sc_intmask &= ~CM_TA;
PUTREG(CMSTAT, sc->sc_intmask);
/* ... and watchdog timer */
- ifp->if_timer = 0;
+ sc->sc_timer = 0;
#ifdef CM_DEBUG
if_printf(ifp, "tint: no more buffers to send, status 0x%02x\n",
@@ -920,12 +921,13 @@ cm_ioctl(ifp, command, data)
* retransmission is implemented).
*/
void
-cm_watchdog(ifp)
- struct ifnet *ifp;
+cm_watchdog(void *arg)
{
- struct cm_softc *sc = ifp->if_softc;
+ struct cm_softc *sc;
- CM_LOCK(sc);
+ sc = arg;
+ callout_reset(&sc->sc_watchdog_timer, hz, cm_watchdog, sc);
+ if (sc->sc_timer == 0 || --sc->sc_timer > 0)
+ return;
PUTREG(CMCMD, CM_TXDIS);
- CM_UNLOCK(sc);
}
diff --git a/sys/dev/cm/smc90cx6var.h b/sys/dev/cm/smc90cx6var.h
index fe9cdbc..65b06a8 100644
--- a/sys/dev/cm/smc90cx6var.h
+++ b/sys/dev/cm/smc90cx6var.h
@@ -77,6 +77,8 @@ struct cm_softc {
u_long sc_reconcount_excessive; /* for the above */
#define ARC_EXCESSIVE_RECONS 20
#define ARC_EXCESSIVE_RECONS_REWARN 400
+ struct callout sc_watchdog_timer;
+ int sc_timer;
u_char sc_intmask;
u_char sc_rx_act; /* 2..3 */
u_char sc_tx_act; /* 0..1 */
diff --git a/sys/dev/ep/if_ep.c b/sys/dev/ep/if_ep.c
index c5b516c..a1bbb01 100644
--- a/sys/dev/ep/if_ep.c
+++ b/sys/dev/ep/if_ep.c
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
@@ -91,10 +92,12 @@ static int ep_media2if_media[] =
static void epinit(void *);
static int epioctl(struct ifnet *, u_long, caddr_t);
static void epstart(struct ifnet *);
-static void epwatchdog(struct ifnet *);
+static void ep_intr_locked(struct ep_softc *);
static void epstart_locked(struct ifnet *);
static void epinit_locked(struct ep_softc *);
+static void eptick(void *);
+static void epwatchdog(struct ep_softc *);
/* if_media functions */
static int ep_ifmedia_upd(struct ifnet *);
@@ -302,12 +305,12 @@ ep_attach(struct ep_softc *sc)
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_start = epstart;
ifp->if_ioctl = epioctl;
- ifp->if_watchdog = epwatchdog;
ifp->if_init = epinit;
IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
IFQ_SET_READY(&ifp->if_snd);
+ callout_init_mtx(&sc->watchdog_timer, &sc->sc_mtx, 0);
if (!sc->epb.mii_trans) {
ifmedia_init(&sc->ifmedia, 0, ep_ifmedia_upd, ep_ifmedia_sts);
@@ -361,6 +364,7 @@ ep_detach(device_t dev)
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
EP_UNLOCK(sc);
ether_ifdetach(ifp);
+ callout_drain(&sc->watchdog_timer);
ep_free(dev);
if_free(ifp);
@@ -457,6 +461,7 @@ epinit_locked(struct ep_softc *sc)
GO_WINDOW(sc, 1);
epstart_locked(ifp);
+ callout_reset(&sc->watchdog_timer, hz, eptick, sc);
}
static void
@@ -556,7 +561,7 @@ startagain:
BPF_MTAP(ifp, m0);
- ifp->if_timer = 2;
+ sc->tx_timer = 2;
ifp->if_opackets++;
m_freem(m0);
@@ -583,20 +588,26 @@ void
ep_intr(void *arg)
{
struct ep_softc *sc;
- int status;
- struct ifnet *ifp;
sc = (struct ep_softc *) arg;
EP_LOCK(sc);
+ ep_intr_locked(sc);
+ EP_UNLOCK(sc);
+}
+
+static void
+ep_intr_locked(struct ep_softc *sc)
+{
+ int status;
+ struct ifnet *ifp;
+
/* XXX 4.x splbio'd here to reduce interruptability */
/*
* quick fix: Try to detect an interrupt when the card goes away.
*/
- if (sc->gone || CSR_READ_2(sc, EP_STATUS) == 0xffff) {
- EP_UNLOCK(sc);
+ if (sc->gone || CSR_READ_2(sc, EP_STATUS) == 0xffff)
return;
- }
ifp = sc->ifp;
CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK); /* disable all Ints */
@@ -612,14 +623,14 @@ rescan:
epread(sc);
if (status & S_TX_AVAIL) {
/* we need ACK */
- ifp->if_timer = 0;
+ sc->tx_timer = 0;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
GO_WINDOW(sc, 1);
CSR_READ_2(sc, EP_W1_FREE_TX);
epstart_locked(ifp);
}
if (status & S_CARD_FAILURE) {
- ifp->if_timer = 0;
+ sc->tx_timer = 0;
#ifdef EP_LOCAL_STATS
device_printf(sc->dev, "\n\tStatus: %x\n", status);
GO_WINDOW(sc, 4);
@@ -642,11 +653,10 @@ rescan:
#endif
epinit_locked(sc);
- EP_UNLOCK(sc);
return;
}
if (status & S_TX_COMPLETE) {
- ifp->if_timer = 0;
+ sc->tx_timer = 0;
/*
* We need ACK. We do it at the end.
*
@@ -700,7 +710,6 @@ rescan:
/* re-enable Ints */
CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
- EP_UNLOCK(sc);
}
static void
@@ -933,7 +942,6 @@ epioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
EP_LOCK(sc);
if (((ifp->if_flags & IFF_UP) == 0) &&
(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
epstop(sc);
} else
/* reinitialize card on any parameter change */
@@ -966,15 +974,27 @@ epioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
static void
-epwatchdog(struct ifnet *ifp)
+eptick(void *arg)
{
- struct ep_softc *sc = ifp->if_softc;
+ struct ep_softc *sc;
+
+ sc = arg;
+ if (sc->tx_timer != 0 && --sc->tx_timer == 0)
+ epwatchdog(sc);
+ callout_reset(&sc->watchdog_timer, hz, eptick, sc);
+}
+
+static void
+epwatchdog(struct ep_softc *sc)
+{
+ struct ifnet *ifp;
+ ifp = sc->ifp;
if (sc->gone)
return;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- epstart(ifp);
- ep_intr(ifp->if_softc);
+ epstart_locked(ifp);
+ ep_intr_locked(sc);
}
static void
@@ -997,4 +1017,7 @@ epstop(struct ep_softc *sc)
CSR_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK);
CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK);
CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER);
+
+ sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ callout_stop(&sc->watchdog_timer);
}
diff --git a/sys/dev/ep/if_epvar.h b/sys/dev/ep/if_epvar.h
index 922a264..c7b9cb3 100644
--- a/sys/dev/ep/if_epvar.h
+++ b/sys/dev/ep/if_epvar.h
@@ -45,6 +45,9 @@ struct ep_softc {
bus_space_tag_t bst;
void *ep_intrhand;
+ struct callout watchdog_timer;
+ int tx_timer;
+
u_short ep_connectors; /* Connectors on this card. */
u_char ep_connector; /* Configured connector. */
diff --git a/sys/dev/fatm/if_fatm.c b/sys/dev/fatm/if_fatm.c
index 47a6443..18b619a 100644
--- a/sys/dev/fatm/if_fatm.c
+++ b/sys/dev/fatm/if_fatm.c
@@ -391,16 +391,14 @@ fatm_check_heartbeat(struct fatm_softc *sc)
* Ensure that the heart is still beating.
*/
static void
-fatm_watchdog(struct ifnet *ifp)
+fatm_watchdog(void *arg)
{
- struct fatm_softc *sc = ifp->if_softc;
+ struct fatm_softc *sc;
- FATM_LOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- fatm_check_heartbeat(sc);
- ifp->if_timer = 5;
- }
- FATM_UNLOCK(sc);
+ sc = arg;
+ FATM_CHECKLOCK(sc);
+ fatm_check_heartbeat(sc);
+ callout_reset(&sc->watchdog_timer, hz * 5, fatm_watchdog, sc);
}
/*
@@ -474,7 +472,7 @@ fatm_stop(struct fatm_softc *sc)
(void)fatm_reset(sc);
/* stop watchdog */
- sc->ifp->if_timer = 0;
+ callout_stop(&sc->watchdog_timer);
if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) {
sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
@@ -1341,7 +1339,7 @@ fatm_init_locked(struct fatm_softc *sc)
/*
* Start the watchdog timer
*/
- sc->ifp->if_timer = 5;
+ callout_reset(&sc->watchdog_timer, hz * 5, fatm_watchdog, sc);
/* start SUNI */
utopia_start(&sc->utopia);
@@ -2543,6 +2541,7 @@ fatm_detach(device_t dev)
FATM_UNLOCK(sc);
atm_ifdetach(sc->ifp); /* XXX race */
}
+ callout_drain(&sc->watchdog_timer);
if (sc->ih != NULL)
bus_teardown_intr(dev, sc->irqres, sc->ih);
@@ -2784,6 +2783,7 @@ fatm_attach(device_t dev)
cv_init(&sc->cv_regs, "fatm_regs");
sysctl_ctx_init(&sc->sysctl_ctx);
+ callout_init_mtx(&sc->watchdog_timer, &sc->mtx, 0);
/*
* Make the sysctl tree
@@ -2824,7 +2824,6 @@ fatm_attach(device_t dev)
ifp->if_flags = IFF_SIMPLEX;
ifp->if_ioctl = fatm_ioctl;
ifp->if_start = fatm_start;
- ifp->if_watchdog = fatm_watchdog;
ifp->if_init = fatm_init;
ifp->if_linkmib = &IFP2IFATM(sc->ifp)->mib;
ifp->if_linkmiblen = sizeof(IFP2IFATM(sc->ifp)->mib);
diff --git a/sys/dev/fatm/if_fatmvar.h b/sys/dev/fatm/if_fatmvar.h
index 697e915..bcd8759 100644
--- a/sys/dev/fatm/if_fatmvar.h
+++ b/sys/dev/fatm/if_fatmvar.h
@@ -188,6 +188,7 @@ struct fatm_softc {
struct ifnet *ifp; /* common part */
struct mtx mtx; /* lock this structure */
struct ifmedia media; /* media */
+ struct callout watchdog_timer;
int init_state; /* initialisation step */
int memid; /* resource id for card memory */
diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c
index d77718b..dd88aa6 100644
--- a/sys/dev/malo/if_malo.c
+++ b/sys/dev/malo/if_malo.c
@@ -135,7 +135,7 @@ static int malo_setup_hwdma(struct malo_softc *);
static void malo_txq_init(struct malo_softc *, struct malo_txq *, int);
static void malo_tx_cleanupq(struct malo_softc *, struct malo_txq *);
static void malo_start(struct ifnet *);
-static void malo_watchdog(struct ifnet *);
+static void malo_watchdog(void *);
static int malo_ioctl(struct ifnet *, u_long, caddr_t);
static void malo_updateslot(struct ifnet *);
static int malo_newstate(struct ieee80211vap *, enum ieee80211_state, int);
@@ -191,6 +191,7 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
ic = ifp->if_l2com;
MALO_LOCK_INIT(sc);
+ callout_init_mtx(&sc->malo_watchdog_timer, &sc->malo_mtx, 0);
/* set these up early for if_printf use */
if_initname(ifp, device_get_name(sc->malo_dev),
@@ -272,7 +273,6 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
ifp->if_softc = sc;
ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
ifp->if_start = malo_start;
- ifp->if_watchdog = malo_watchdog;
ifp->if_ioctl = malo_ioctl;
ifp->if_init = malo_init;
IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
@@ -1076,7 +1076,7 @@ malo_tx_proc(void *arg, int npending)
if (nreaped != 0) {
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_timer = 0;
+ sc->malo_timer = 0;
malo_start(ifp);
}
}
@@ -1260,7 +1260,7 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
MALO_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
ifp->if_opackets++;
- ifp->if_timer = 5;
+ sc->malo_timer = 5;
MALO_TXQ_UNLOCK(txq);
return 0;
#undef IEEE80211_DIR_DSTODS
@@ -1339,10 +1339,17 @@ malo_start(struct ifnet *ifp)
}
static void
-malo_watchdog(struct ifnet *ifp)
+malo_watchdog(void *arg)
{
- struct malo_softc *sc = ifp->if_softc;
+ struct malo_softc *sc;
+ struct ifnet *ifp;
+
+ sc = arg;
+ callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
+ if (sc->malo_timer == 0 || --sc->malo_timer > 0)
+ return;
+ ifp = sc->malo_ifp;
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->malo_invalid) {
if_printf(ifp, "watchdog timeout\n");
@@ -1536,6 +1543,7 @@ malo_init_locked(struct malo_softc *sc)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
malo_hal_intrset(mh, sc->malo_imask);
+ callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
}
static void
@@ -1699,7 +1707,8 @@ malo_stop_locked(struct ifnet *ifp, int disable)
* is gone (invalid).
*/
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- ifp->if_timer = 0;
+ callout_stop(&sc->malo_watchdog_timer);
+ sc->malo_timer = 0;
/* diable interrupt. */
malo_hal_intrset(mh, 0);
/* turn off the radio. */
@@ -2241,6 +2250,7 @@ malo_detach(struct malo_softc *sc)
* Other than that, it's straightforward...
*/
ieee80211_ifdetach(ic);
+ callout_drain(&sc->malo_watchdog_timer);
malo_dma_cleanup(sc);
malo_tx_cleanup(sc);
malo_hal_detach(sc->malo_mh);
diff --git a/sys/dev/malo/if_malo.h b/sys/dev/malo/if_malo.h
index 7e3a7e8..bac290c 100644
--- a/sys/dev/malo/if_malo.h
+++ b/sys/dev/malo/if_malo.h
@@ -550,6 +550,8 @@ struct malo_softc {
struct malo_txq malo_txq[MALO_NUM_TX_QUEUES];
struct task malo_txtask; /* tx int processing */
+ struct callout malo_watchdog_timer;
+ int malo_timer;
struct malo_tx_radiotap_header malo_tx_th;
struct malo_rx_radiotap_header malo_rx_th;
diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c
index 4a1dc8a..e4e469b 100644
--- a/sys/dev/mwl/if_mwl.c
+++ b/sys/dev/mwl/if_mwl.c
@@ -98,7 +98,7 @@ static void mwl_start(struct ifnet *);
static int mwl_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static int mwl_media_change(struct ifnet *);
-static void mwl_watchdog(struct ifnet *);
+static void mwl_watchdog(void *);
static int mwl_ioctl(struct ifnet *, u_long, caddr_t);
static void mwl_radar_proc(void *, int);
static void mwl_chanswitch_proc(void *, int);
@@ -360,6 +360,7 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
goto bad1;
callout_init(&sc->sc_timer, CALLOUT_MPSAFE);
+ callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
sc->sc_tq = taskqueue_create("mwl_taskq", M_NOWAIT,
taskqueue_thread_enqueue, &sc->sc_tq);
@@ -401,7 +402,6 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
ifp->if_softc = sc;
ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
ifp->if_start = mwl_start;
- ifp->if_watchdog = mwl_watchdog;
ifp->if_ioctl = mwl_ioctl;
ifp->if_init = mwl_init;
IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
@@ -558,6 +558,7 @@ mwl_detach(struct mwl_softc *sc)
* Other than that, it's straightforward...
*/
ieee80211_ifdetach(ic);
+ callout_drain(&sc->sc_watchdog);
mwl_dma_cleanup(sc);
mwl_tx_cleanup(sc);
mwl_hal_detach(sc->sc_mh);
@@ -1214,6 +1215,7 @@ mwl_init_locked(struct mwl_softc *sc)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
mwl_hal_intrset(mh, sc->sc_imask);
+ callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc);
return 0;
}
@@ -1251,7 +1253,8 @@ mwl_stop_locked(struct ifnet *ifp, int disable)
* Shutdown the hardware and driver.
*/
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- ifp->if_timer = 0;
+ callout_stop(&sc->sc_watchdog);
+ sc->sc_tx_timer = 0;
mwl_draintxq(sc);
}
}
@@ -3411,7 +3414,7 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf *
MWL_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
ifp->if_opackets++;
- ifp->if_timer = 5;
+ sc->sc_tx_timer = 5;
MWL_TXQ_UNLOCK(txq);
return 0;
@@ -3558,7 +3561,7 @@ mwl_tx_proc(void *arg, int npending)
if (nreaped != 0) {
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_timer = 0;
+ sc->sc_tx_timer = 0;
if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
/* NB: kick fw; the tx thread may have been preempted */
mwl_hal_txstart(sc->sc_mh, 0);
@@ -3624,7 +3627,7 @@ mwl_draintxq(struct mwl_softc *sc)
for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
mwl_tx_draintxq(sc, &sc->sc_txq[i]);
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_timer = 0;
+ sc->sc_tx_timer = 0;
}
#ifdef MWL_DIAGAPI
@@ -4770,10 +4773,17 @@ mwl_txq_dump(struct mwl_txq *txq)
#endif
static void
-mwl_watchdog(struct ifnet *ifp)
+mwl_watchdog(void *arg)
{
- struct mwl_softc *sc = ifp->if_softc;
+ struct mwl_softc *sc;
+ struct ifnet *ifp;
+
+ sc = arg;
+ callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc);
+ if (sc->sc_tx_timer == 0 || --sc->sc_tx_timer > 0)
+ return;
+ ifp = sc->sc_ifp;
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->sc_invalid) {
if (mwl_hal_setkeepalive(sc->sc_mh))
if_printf(ifp, "transmit timeout (firmware hung?)\n");
diff --git a/sys/dev/mwl/if_mwlvar.h b/sys/dev/mwl/if_mwlvar.h
index d69285d..a75ceda 100644
--- a/sys/dev/mwl/if_mwlvar.h
+++ b/sys/dev/mwl/if_mwlvar.h
@@ -255,6 +255,8 @@ struct mwl_softc {
bus_space_tag_t sc_io1t;
struct mtx sc_mtx; /* master lock (recursive) */
struct taskqueue *sc_tq; /* private task queue */
+ struct callout sc_watchdog;
+ int sc_tx_timer;
unsigned int sc_invalid : 1, /* disable hardware accesses */
sc_recvsetup:1, /* recv setup */
sc_csapending:1,/* 11h channel switch pending */
diff --git a/sys/dev/sn/if_sn.c b/sys/dev/sn/if_sn.c
index 751071a..217d811 100644
--- a/sys/dev/sn/if_sn.c
+++ b/sys/dev/sn/if_sn.c
@@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/errno.h>
+#include <sys/kernel.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@@ -121,6 +122,7 @@ static int snioctl(struct ifnet * ifp, u_long, caddr_t);
static void snresume(struct ifnet *);
+static void snintr_locked(struct sn_softc *);
static void sninit_locked(void *);
static void snstart_locked(struct ifnet *);
@@ -128,7 +130,7 @@ static void sninit(void *);
static void snread(struct ifnet *);
static void snstart(struct ifnet *);
static void snstop(struct sn_softc *);
-static void snwatchdog(struct ifnet *);
+static void snwatchdog(void *);
static void sn_setmcast(struct sn_softc *);
static int sn_getmcf(struct ifnet *ifp, u_char *mcf);
@@ -170,6 +172,7 @@ sn_attach(device_t dev)
}
SN_LOCK_INIT(sc);
+ callout_init_mtx(&sc->watchdog, &sc->sc_mtx, 0);
snstop(sc);
sc->pages_wanted = -1;
@@ -202,13 +205,11 @@ sn_attach(device_t dev)
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_start = snstart;
ifp->if_ioctl = snioctl;
- ifp->if_watchdog = snwatchdog;
ifp->if_init = sninit;
ifp->if_baudrate = 10000000;
IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
IFQ_SET_READY(&ifp->if_snd);
- ifp->if_timer = 0;
ether_ifattach(ifp, eaddr);
@@ -233,9 +234,11 @@ sn_detach(device_t dev)
struct sn_softc *sc = device_get_softc(dev);
struct ifnet *ifp = sc->ifp;
- snstop(sc);
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
ether_ifdetach(ifp);
+ SN_LOCK(sc);
+ snstop(sc);
+ SN_UNLOCK(sc);
+ callout_drain(&sc->watchdog);
sn_deactivate(dev);
if_free(ifp);
SN_LOCK_DESTROY(sc);
@@ -342,6 +345,7 @@ sninit_locked(void *xsc)
*/
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ callout_reset(&sc->watchdog, hz, snwatchdog, sc);
/*
* Attempt to push out any waiting packets.
@@ -463,7 +467,7 @@ startagain:
CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
sc->intr_mask = mask;
- ifp->if_timer = 1;
+ sc->timer = 1;
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
sc->pages_wanted = numPages;
return;
@@ -548,7 +552,7 @@ startagain:
CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_ENQUEUE);
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- ifp->if_timer = 1;
+ sc->timer = 1;
BPF_MTAP(ifp, top);
@@ -657,7 +661,7 @@ snresume(struct ifnet *ifp)
packet_no = CSR_READ_1(sc, ALLOC_RESULT_REG_B);
if (packet_no & ARR_FAILED) {
if_printf(ifp, "Memory allocation failed. Weird.\n");
- ifp->if_timer = 1;
+ sc->timer = 1;
goto try_start;
}
/*
@@ -755,24 +759,32 @@ try_start:
* Now pass control to snstart() to queue any additional packets
*/
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- snstart(ifp);
+ snstart_locked(ifp);
/*
* We've sent something, so we're active. Set a watchdog in case the
* TX_EMPTY interrupt is lost.
*/
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- ifp->if_timer = 1;
+ sc->timer = 1;
return;
}
-
void
sn_intr(void *arg)
{
- int status, interrupts;
struct sn_softc *sc = (struct sn_softc *) arg;
+
+ SN_LOCK(sc);
+ snintr_locked(sc);
+ SN_UNLOCK(sc);
+}
+
+static void
+snintr_locked(struct sn_softc *sc)
+{
+ int status, interrupts;
struct ifnet *ifp = sc->ifp;
/*
@@ -783,12 +795,10 @@ sn_intr(void *arg)
uint16_t tx_status;
uint16_t card_stats;
- SN_LOCK(sc);
-
/*
* Clear the watchdog.
*/
- ifp->if_timer = 0;
+ sc->timer = 0;
SMC_SELECT_BANK(sc, 2);
@@ -981,7 +991,6 @@ out:
mask |= CSR_READ_1(sc, INTR_MASK_REG_B);
CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
sc->intr_mask = mask;
- SN_UNLOCK(sc);
}
static void
@@ -1136,7 +1145,6 @@ snioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
SN_LOCK(sc);
if ((ifp->if_flags & IFF_UP) == 0 &&
ifp->if_drv_flags & IFF_DRV_RUNNING) {
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
snstop(sc);
} else {
/* reinitialize card on any parameter change */
@@ -1161,9 +1169,16 @@ snioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
static void
-snwatchdog(struct ifnet *ifp)
+snwatchdog(void *arg)
{
- sn_intr(ifp->if_softc);
+ struct sn_softc *sc;
+
+ sc = arg;
+ SN_ASSERT_LOCKED(sc);
+ callout_reset(&sc->watchdog, hz, snwatchdog, sc);
+ if (sc->timer == 0 || --sc->timer > 0)
+ return;
+ snintr_locked(sc);
}
@@ -1193,7 +1208,9 @@ snstop(struct sn_softc *sc)
/*
* Cancel watchdog.
*/
- ifp->if_timer = 0;
+ sc->timer = 0;
+ callout_stop(&sc->watchdog);
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
}
diff --git a/sys/dev/sn/if_snvar.h b/sys/dev/sn/if_snvar.h
index 79fc6e8..bd4f312 100644
--- a/sys/dev/sn/if_snvar.h
+++ b/sys/dev/sn/if_snvar.h
@@ -33,6 +33,8 @@
struct sn_softc {
struct ifnet *ifp;
struct mtx sc_mtx;
+ struct callout watchdog;
+ int timer;
int pages_wanted; /* Size of outstanding MMU ALLOC */
int intr_mask; /* Most recently set interrupt mask */
device_t dev;
diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c
index f68a97d..55b256f 100644
--- a/sys/dev/ste/if_ste.c
+++ b/sys/dev/ste/if_ste.c
@@ -108,7 +108,7 @@ static int ste_ioctl(struct ifnet *, u_long, caddr_t);
static int ste_encap(struct ste_softc *, struct ste_chain *, struct mbuf *);
static void ste_start(struct ifnet *);
static void ste_start_locked(struct ifnet *);
-static void ste_watchdog(struct ifnet *);
+static void ste_watchdog(struct ste_softc *);
static int ste_shutdown(device_t);
static int ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *,
struct mbuf *);
@@ -924,7 +924,7 @@ ste_txeof(sc)
sc->ste_cdata.ste_tx_cons = idx;
if (idx == sc->ste_cdata.ste_tx_prod)
- ifp->if_timer = 0;
+ sc->ste_timer = 0;
}
static void
@@ -960,6 +960,8 @@ ste_stats_update(xsc)
}
}
+ if (sc->ste_timer > 0 && --sc->ste_timer == 0)
+ ste_watchdog(sc);
callout_reset(&sc->ste_stat_callout, hz, ste_stats_update, sc);
return;
@@ -1094,7 +1096,6 @@ ste_attach(dev)
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = ste_ioctl;
ifp->if_start = ste_start;
- ifp->if_watchdog = ste_watchdog;
ifp->if_init = ste_init;
IFQ_SET_MAXLEN(&ifp->if_snd, STE_TX_LIST_CNT - 1);
ifp->if_snd.ifq_drv_maxlen = STE_TX_LIST_CNT - 1;
@@ -1159,11 +1160,11 @@ ste_detach(dev)
/* These should only be active if attach succeeded */
if (device_is_attached(dev)) {
+ ether_ifdetach(ifp);
STE_LOCK(sc);
ste_stop(sc);
STE_UNLOCK(sc);
callout_drain(&sc->ste_stat_callout);
- ether_ifdetach(ifp);
}
if (sc->ste_miibus)
device_delete_child(dev, sc->ste_miibus);
@@ -1708,7 +1709,7 @@ ste_start_locked(ifp)
BPF_MTAP(ifp, cur_tx->ste_mbuf);
STE_INC(idx, STE_TX_LIST_CNT);
- ifp->if_timer = 5;
+ sc->ste_timer = 5;
}
sc->ste_cdata.ste_tx_prod = idx;
@@ -1716,13 +1717,12 @@ ste_start_locked(ifp)
}
static void
-ste_watchdog(ifp)
- struct ifnet *ifp;
+ste_watchdog(struct ste_softc *sc)
{
- struct ste_softc *sc;
+ struct ifnet *ifp;
- sc = ifp->if_softc;
- STE_LOCK(sc);
+ ifp = sc->ste_ifp;
+ STE_LOCK_ASSERT(sc);
ifp->if_oerrors++;
if_printf(ifp, "watchdog timeout\n");
@@ -1736,7 +1736,6 @@ ste_watchdog(ifp)
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
ste_start_locked(ifp);
- STE_UNLOCK(sc);
return;
}
diff --git a/sys/dev/ste/if_stereg.h b/sys/dev/ste/if_stereg.h
index 0114ebe..68d9674 100644
--- a/sys/dev/ste/if_stereg.h
+++ b/sys/dev/ste/if_stereg.h
@@ -517,6 +517,7 @@ struct ste_softc {
int ste_tx_thresh;
u_int8_t ste_link;
int ste_if_flags;
+ int ste_timer;
struct ste_chain *ste_tx_prev;
struct ste_list_data *ste_ldata;
struct ste_chain_data ste_cdata;
diff --git a/sys/dev/ti/if_ti.c b/sys/dev/ti/if_ti.c
index 488d038..20130bc 100644
--- a/sys/dev/ti/if_ti.c
+++ b/sys/dev/ti/if_ti.c
@@ -194,7 +194,7 @@ static void ti_init(void *);
static void ti_init_locked(void *);
static void ti_init2(struct ti_softc *);
static void ti_stop(struct ti_softc *);
-static void ti_watchdog(struct ifnet *);
+static void ti_watchdog(void *);
static int ti_shutdown(device_t);
static int ti_ifmedia_upd(struct ifnet *);
static void ti_ifmedia_sts(struct ifnet *, struct ifmediareq *);
@@ -2285,6 +2285,7 @@ ti_attach(dev)
mtx_init(&sc->ti_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF);
+ callout_init_mtx(&sc->ti_watchdog, &sc->ti_mtx, 0);
ifmedia_init(&sc->ifmedia, IFM_IMASK, ti_ifmedia_upd, ti_ifmedia_sts);
ifp = sc->ti_ifp = if_alloc(IFT_ETHER);
if (ifp == NULL) {
@@ -2486,7 +2487,6 @@ ti_attach(dev)
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = ti_ioctl;
ifp->if_start = ti_start;
- ifp->if_watchdog = ti_watchdog;
ifp->if_init = ti_init;
ifp->if_baudrate = 1000000000;
ifp->if_mtu = ETHERMTU;
@@ -2565,24 +2565,22 @@ ti_detach(dev)
{
struct ti_softc *sc;
struct ifnet *ifp;
- int attached;
sc = device_get_softc(dev);
if (sc->dev)
destroy_dev(sc->dev);
KASSERT(mtx_initialized(&sc->ti_mtx), ("ti mutex not initialized"));
- attached = device_is_attached(dev);
- TI_LOCK(sc);
ifp = sc->ti_ifp;
- if (attached)
- ti_stop(sc);
- TI_UNLOCK(sc);
- if (attached)
+ if (device_is_attached(dev)) {
ether_ifdetach(ifp);
+ TI_LOCK(sc);
+ ti_stop(sc);
+ TI_UNLOCK(sc);
+ }
/* These should only be active if attach succeeded */
- if (attached)
- bus_generic_detach(dev);
+ callout_drain(&sc->ti_watchdog);
+ bus_generic_detach(dev);
ti_free_dmamaps(sc);
ifmedia_removeall(&sc->ifmedia);
@@ -2866,7 +2864,7 @@ ti_txeof(sc)
}
sc->ti_tx_saved_considx = idx;
- ifp->if_timer = sc->ti_txcnt > 0 ? 5 : 0;
+ sc->ti_timer = sc->ti_txcnt > 0 ? 5 : 0;
}
static void
@@ -3121,7 +3119,7 @@ ti_start_locked(ifp)
/*
* Set a timeout in case the chip goes out to lunch.
*/
- ifp->if_timer = 5;
+ sc->ti_timer = 5;
}
}
@@ -3225,6 +3223,7 @@ static void ti_init2(sc)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ callout_reset(&sc->ti_watchdog, hz, ti_watchdog, sc);
/*
* Make sure to set media properly. We have to do this
@@ -3786,30 +3785,31 @@ ti_ioctl2(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
}
static void
-ti_watchdog(ifp)
- struct ifnet *ifp;
+ti_watchdog(void *arg)
{
struct ti_softc *sc;
+ struct ifnet *ifp;
- sc = ifp->if_softc;
- TI_LOCK(sc);
+ sc = arg;
+ TI_LOCK_ASSERT(sc);
+ callout_reset(&sc->ti_watchdog, hz, ti_watchdog, sc);
+ if (sc->ti_timer == 0 || --sc->ti_timer > 0)
+ return;
/*
* When we're debugging, the chip is often stopped for long periods
* of time, and that would normally cause the watchdog timer to fire.
* Since that impedes debugging, we don't want to do that.
*/
- if (sc->ti_flags & TI_FLAG_DEBUGING) {
- TI_UNLOCK(sc);
+ if (sc->ti_flags & TI_FLAG_DEBUGING)
return;
- }
+ ifp = sc->ti_ifp;
if_printf(ifp, "watchdog timeout -- resetting\n");
ti_stop(sc);
ti_init_locked(sc);
ifp->if_oerrors++;
- TI_UNLOCK(sc);
}
/*
@@ -3859,6 +3859,7 @@ ti_stop(sc)
sc->ti_tx_saved_considx = TI_TXCONS_UNSET;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ callout_stop(&sc->ti_watchdog);
}
/*
diff --git a/sys/dev/ti/if_tireg.h b/sys/dev/ti/if_tireg.h
index 5f0bda9..070a70a 100644
--- a/sys/dev/ti/if_tireg.h
+++ b/sys/dev/ti/if_tireg.h
@@ -1038,6 +1038,8 @@ struct ti_softc {
int ti_if_flags;
int ti_txcnt;
struct mtx ti_mtx;
+ struct callout ti_watchdog;
+ int ti_timer;
ti_flag_vals ti_flags;
struct cdev *dev;
};
diff --git a/sys/dev/vx/if_vx.c b/sys/dev/vx/if_vx.c
index c810c71..0dea9bf 100644
--- a/sys/dev/vx/if_vx.c
+++ b/sys/dev/vx/if_vx.c
@@ -129,7 +129,7 @@ static void vx_init_locked(struct vx_softc *);
static int vx_ioctl(struct ifnet *, u_long, caddr_t);
static void vx_start(struct ifnet *);
static void vx_start_locked(struct ifnet *);
-static void vx_watchdog(struct ifnet *);
+static void vx_watchdog(void *);
static void vx_reset(struct vx_softc *);
static void vx_read(struct vx_softc *);
static struct mbuf *vx_get(struct vx_softc *, u_int);
@@ -157,6 +157,7 @@ vx_attach(device_t dev)
mtx_init(&sc->vx_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF);
callout_init_mtx(&sc->vx_callout, &sc->vx_mtx, 0);
+ callout_init_mtx(&sc->vx_watchdog, &sc->vx_mtx, 0);
GO_WINDOW(0);
CSR_WRITE_2(sc, VX_COMMAND, GLOBAL_RESET);
VX_BUSY_WAIT;
@@ -193,7 +194,6 @@ vx_attach(device_t dev)
ifp->if_start = vx_start;
ifp->if_ioctl = vx_ioctl;
ifp->if_init = vx_init;
- ifp->if_watchdog = vx_watchdog;
ifp->if_softc = sc;
ether_ifattach(ifp, eaddr);
@@ -269,6 +269,7 @@ vx_init_locked(struct vx_softc *sc)
/* Interface is now `running', with no output active. */
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc);
/* Attempt to start output, if any. */
vx_start_locked(ifp);
@@ -474,7 +475,7 @@ startagain:
/* not enough room in FIFO - make sure */
if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) {
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- ifp->if_timer = 1;
+ sc->vx_timer = 1;
return;
}
}
@@ -513,7 +514,7 @@ startagain:
CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0); /* Padding */
++ifp->if_opackets;
- ifp->if_timer = 1;
+ sc->vx_timer = 1;
readcheck:
if ((CSR_READ_2(sc, VX_W1_RX_STATUS) & ERR_INCOMPLETE) == 0) {
@@ -661,18 +662,18 @@ vx_intr(void *voidsc)
if (status & S_RX_COMPLETE)
vx_read(sc);
if (status & S_TX_AVAIL) {
- ifp->if_timer = 0;
+ sc->vx_timer = 0;
sc->vx_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
vx_start_locked(sc->vx_ifp);
}
if (status & S_CARD_FAILURE) {
if_printf(ifp, "adapter failure (%x)\n", status);
- ifp->if_timer = 0;
+ sc->vx_timer = 0;
vx_reset(sc);
break;
}
if (status & S_TX_COMPLETE) {
- ifp->if_timer = 0;
+ sc->vx_timer = 0;
vx_txstat(sc);
vx_start_locked(ifp);
}
@@ -970,26 +971,32 @@ vx_reset(struct vx_softc *sc)
}
static void
-vx_watchdog(struct ifnet *ifp)
+vx_watchdog(void *arg)
{
- struct vx_softc *sc = ifp->if_softc;
+ struct vx_softc *sc;
+ struct ifnet *ifp;
- VX_LOCK(sc);
+ sc = arg;
+ VX_LOCK_ASSERT(sc);
+ callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc);
+ if (sc->vx_timer == 0 || --sc->vx_timer > 0)
+ return;
+
+ ifp = sc->vx_ifp;
if (ifp->if_flags & IFF_DEBUG)
if_printf(ifp, "device timeout\n");
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
vx_start_locked(ifp);
vx_intr(sc);
- VX_UNLOCK(sc);
}
void
vx_stop(struct vx_softc *sc)
{
- struct ifnet *ifp = sc->vx_ifp;
VX_LOCK_ASSERT(sc);
- ifp->if_timer = 0;
+ sc->vx_timer = 0;
+ callout_stop(&sc->vx_watchdog);
CSR_WRITE_2(sc, VX_COMMAND, RX_DISABLE);
CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
diff --git a/sys/dev/vx/if_vxvar.h b/sys/dev/vx/if_vxvar.h
index ec20a3f..8c312e2 100644
--- a/sys/dev/vx/if_vxvar.h
+++ b/sys/dev/vx/if_vxvar.h
@@ -51,8 +51,10 @@ struct vx_softc {
int vx_tx_succ_ok; /* # packets sent in sequence */
/* w/o underrun */
struct callout vx_callout; /* Callout for timeouts */
+ struct callout vx_watchdog;
struct mtx vx_mtx;
int vx_buffill_pending;
+ int vx_timer;
};
#define CSR_WRITE_4(sc, reg, val) \
OpenPOWER on IntegriCloud