diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index 4dd87760f30c..7a02eda6da40 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -289,9 +289,9 @@ ieee80211_ifdetach(struct ieee80211com *ic) struct ifnet *ifp = ic->ic_ifp; struct ieee80211vap *vap; - /* XXX ieee80211_stop_all? */ while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL) ieee80211_vap_destroy(vap); + ieee80211_waitfor_parent(ic); ieee80211_sysctl_detach(ic); ieee80211_regdomain_detach(ic); diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index db36adb6b51d..7f7417ece6cb 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -3265,7 +3265,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } IEEE80211_UNLOCK(ic); /* Wait for parent ioctl handler if it was queued */ - taskqueue_drain(taskqueue_thread, &ic->ic_parent_task); + ieee80211_waitfor_parent(ic); break; case SIOCADDMULTI: case SIOCDELMULTI: diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 31b68fdcdd7a..b31d3afe97bc 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -1071,6 +1071,17 @@ parent_updown(void *arg, int npending) parent->if_ioctl(parent, SIOCSIFFLAGS, NULL); } +/* + * Block until the parent is in a known state. This is + * used after any operations that dispatch a task (e.g. + * to auto-configure the parent device up/down). + */ +void +ieee80211_waitfor_parent(struct ieee80211com *ic) +{ + taskqueue_drain(taskqueue_thread, &ic->ic_parent_task); +} + /* * Start a vap running. If this is the first vap to be * set running on the underlying device then we @@ -1258,6 +1269,8 @@ ieee80211_stop_all(struct ieee80211com *ic) ieee80211_stop_locked(vap); } IEEE80211_UNLOCK(ic); + + ieee80211_waitfor_parent(ic); } /* @@ -1278,6 +1291,8 @@ ieee80211_suspend_all(struct ieee80211com *ic) } } IEEE80211_UNLOCK(ic); + + ieee80211_waitfor_parent(ic); } /* diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index f7395b63ad67..fa5075808368 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -260,6 +260,7 @@ ieee80211_gettid(const struct ieee80211_frame *wh) return tid; } +void ieee80211_waitfor_parent(struct ieee80211com *); void ieee80211_start_locked(struct ieee80211vap *); void ieee80211_init(void *); void ieee80211_start_all(struct ieee80211com *);