aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/malo
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2009-11-19 22:06:40 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2009-11-19 22:06:40 +0000
commit7cf545d0a16bce3e3ecda172a69504aee58f3e14 (patch)
tree8407585eec2a1c0c6cadd011a7eb682949649bde /sys/dev/malo
parentd95121b427cb7f0cc2c2f253e8dc37e8850b4198 (diff)
downloadsrc-7cf545d0a16bce3e3ecda172a69504aee58f3e14.tar.gz
src-7cf545d0a16bce3e3ecda172a69504aee58f3e14.zip
- 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.
Notes
Notes: svn path=/head/; revision=199559
Diffstat (limited to 'sys/dev/malo')
-rw-r--r--sys/dev/malo/if_malo.c24
-rw-r--r--sys/dev/malo/if_malo.h2
2 files changed, 19 insertions, 7 deletions
diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c
index d77718b0d1e3..dd88aa657e6e 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 7e3a7e89e486..bac290c6330b 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;