Index: sys/dev/ath/if_ath.c =================================================================== --- sys/dev/ath/if_ath.c +++ sys/dev/ath/if_ath.c @@ -1675,6 +1675,16 @@ /* complete setup */ ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status, mac); + + /* Reflect promisc mode settings. */ + ATH_LOCK(sc); + if (sc->sc_nvaps > 1) { + ath_power_set_power_state(sc, HAL_PM_AWAKE); + ath_mode_init(sc); + ath_power_restore_power_state(sc); + } + ATH_UNLOCK(sc); + return vap; bad2: reclaim_address(sc, mac); @@ -6114,16 +6124,8 @@ ATH_LOCK(sc); if (ic->ic_nrunning > 0) { - /* - * To avoid rescanning another access point, - * do not call ath_init() here. Instead, - * only reflect promisc mode settings. - */ - if (sc->sc_running) { - ath_power_set_power_state(sc, HAL_PM_AWAKE); - ath_mode_init(sc); - ath_power_restore_power_state(sc); - } else if (!sc->sc_invalid) { + if (!sc->sc_running && !sc->sc_invalid) { + /* XXX is it still actual? */ /* * Beware of being called during attach/detach * to reset promiscuous mode. In that case we Index: sys/dev/bwn/if_bwn.c =================================================================== --- sys/dev/bwn/if_bwn.c +++ sys/dev/bwn/if_bwn.c @@ -1213,8 +1213,7 @@ if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) { bwn_init(sc); startall = 1; - } else - bwn_update_promisc(ic); + } } else if (sc->sc_flags & BWN_FLAG_RUNNING) bwn_stop(sc); BWN_UNLOCK(sc); @@ -2873,6 +2872,10 @@ { struct ieee80211vap *vap; struct bwn_vap *bvp; + int firstvap = 1; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) + firstvap = 0; switch (opmode) { case IEEE80211_M_HOSTAP: @@ -2902,6 +2905,11 @@ /* complete setup */ ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status, mac); + + /* Reflect promisc mode settings. */ + if (!firstvap) + bwn_update_promisc(ic); + return (vap); } Index: sys/dev/mwl/if_mwl.c =================================================================== --- sys/dev/mwl/if_mwl.c +++ sys/dev/mwl/if_mwl.c @@ -600,6 +600,10 @@ struct mwl_hal_vap *hvap; struct mwl_vap *mvp; uint8_t mac[IEEE80211_ADDR_LEN]; + int firstvap = 1; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) + firstvap = 0; IEEE80211_ADDR_COPY(mac, mac0); switch (opmode) { @@ -713,6 +717,13 @@ else ic->ic_opmode = opmode; + /* Reflect promisc mode settings. */ + if (!firstvap) { + MWL_LOCK(sc); + mwl_mode_init(sc); + MWL_UNLOCK(sc); + } + return vap; } @@ -4769,27 +4780,19 @@ MWL_LOCK(sc); if (ic->ic_nrunning > 0) { - if (sc->sc_running) { - /* - * To avoid rescanning another access point, - * do not call mwl_init() here. Instead, - * only reflect promisc mode settings. - */ - mwl_mode_init(sc); - } else { - /* - * Beware of being called during attach/detach - * to reset promiscuous mode. In that case we - * will still be marked UP but not RUNNING. - * However trying to re-init the interface - * is the wrong thing to do as we've already - * torn down much of our state. There's - * probably a better way to deal with this. - */ - if (!sc->sc_invalid) { - mwl_init(sc); /* XXX lose error */ - startall = 1; - } + /* XXX is it still actual? */ + /* + * Beware of being called during attach/detach + * to reset promiscuous mode. In that case we + * will still be marked UP but not RUNNING. + * However trying to re-init the interface + * is the wrong thing to do as we've already + * torn down much of our state. There's + * probably a better way to deal with this. + */ + if (!sc->sc_running && !sc->sc_invalid) { + mwl_init(sc); /* XXX lose error */ + startall = 1; } } else mwl_stop(sc); Index: sys/dev/otus/if_otus.c =================================================================== --- sys/dev/otus/if_otus.c +++ sys/dev/otus/if_otus.c @@ -420,20 +420,19 @@ otus_parent(struct ieee80211com *ic) { struct otus_softc *sc = ic->ic_softc; - int startall = 0; if (ic->ic_nrunning > 0) { if (!sc->sc_running) { - otus_init(sc); - startall = 1; - } else { - (void) otus_set_multi(sc); + if (otus_init(sc) != 0) { + struct ieee80211vap *vap = + TAILQ_FIRST(&ic->ic_vaps); + if (vap != NULL) + ieee80211_stop(vap); + } else + ieee80211_start_all(ic); } } else if (sc->sc_running) otus_stop(sc); - - if (startall) - ieee80211_start_all(ic); } static void Index: sys/dev/ral/rt2560.c =================================================================== --- sys/dev/ral/rt2560.c +++ sys/dev/ral/rt2560.c @@ -1954,8 +1954,7 @@ if ((sc->sc_flags & RT2560_F_RUNNING) == 0) { rt2560_init_locked(sc); startall = 1; - } else - rt2560_update_promisc(ic); + } } else if (sc->sc_flags & RT2560_F_RUNNING) rt2560_stop_locked(sc); RAL_UNLOCK(sc); Index: sys/dev/ral/rt2661.c =================================================================== --- sys/dev/ral/rt2661.c +++ sys/dev/ral/rt2661.c @@ -1694,8 +1694,7 @@ if ((sc->sc_flags & RAL_RUNNING) == 0) { rt2661_init_locked(sc); startall = 1; - } else - rt2661_update_promisc(ic); + } } else if (sc->sc_flags & RAL_RUNNING) rt2661_stop_locked(sc); RAL_UNLOCK(sc); Index: sys/dev/ral/rt2860.c =================================================================== --- sys/dev/ral/rt2860.c +++ sys/dev/ral/rt2860.c @@ -2008,12 +2008,11 @@ int startall = 0; RAL_LOCK(sc); - if (ic->ic_nrunning> 0) { + if (ic->ic_nrunning > 0) { if (!(sc->sc_flags & RT2860_RUNNING)) { rt2860_init_locked(sc); startall = 1; - } else - rt2860_update_promisc(ic); + } } else if (sc->sc_flags & RT2860_RUNNING) rt2860_stop_locked(sc); RAL_UNLOCK(sc); Index: sys/dev/usb/wlan/if_run.c =================================================================== --- sys/dev/usb/wlan/if_run.c +++ sys/dev/usb/wlan/if_run.c @@ -3736,8 +3736,7 @@ if (!(sc->sc_flags & RUN_RUNNING)) { startall = 1; run_init_locked(sc); - } else - run_update_promisc_locked(sc); + } } else if ((sc->sc_flags & RUN_RUNNING) && sc->rvp_cnt <= 1) run_stop(sc); RUN_UNLOCK(sc); Index: sys/dev/usb/wlan/if_upgt.c =================================================================== --- sys/dev/usb/wlan/if_upgt.c +++ sys/dev/usb/wlan/if_upgt.c @@ -440,10 +440,7 @@ return; } if (ic->ic_nrunning > 0) { - if (sc->sc_flags & UPGT_FLAG_INITDONE) { - if (ic->ic_allmulti > 0 || ic->ic_promisc > 0) - upgt_set_multi(sc); - } else { + if (!(sc->sc_flags & UPGT_FLAG_INITDONE)) { upgt_init(sc); startall = 1; } Index: sys/dev/usb/wlan/if_ural.c =================================================================== --- sys/dev/usb/wlan/if_ural.c +++ sys/dev/usb/wlan/if_ural.c @@ -1366,8 +1366,7 @@ if (sc->sc_running == 0) { ural_init(sc); startall = 1; - } else - ural_setpromisc(sc); + } } else if (sc->sc_running) ural_stop(sc); RAL_UNLOCK(sc); Index: sys/dev/usb/wlan/if_urtw.c =================================================================== --- sys/dev/usb/wlan/if_urtw.c +++ sys/dev/usb/wlan/if_urtw.c @@ -672,7 +672,9 @@ static void urtw_led_ch(void *); static void urtw_ledtask(void *, int); static void urtw_watchdog(void *); +#if 0 static void urtw_set_multi(void *); +#endif static int urtw_isbmode(uint16_t); static uint16_t urtw_rate2rtl(uint32_t); static uint16_t urtw_rtl2rate(uint32_t); @@ -1372,10 +1374,7 @@ } if (ic->ic_nrunning > 0) { - if (sc->sc_flags & URTW_RUNNING) { - if (ic->ic_promisc > 0 || ic->ic_allmulti > 0) - urtw_set_multi(sc); - } else { + if (!(sc->sc_flags & URTW_RUNNING)) { urtw_init(sc); startall = 1; } @@ -1875,11 +1874,13 @@ } } +#if 0 static void urtw_set_multi(void *arg) { /* XXX don't know how to set a device. Lack of docs. */ } +#endif static usb_error_t urtw_set_rate(struct urtw_softc *sc) Index: sys/dev/usb/wlan/if_zyd.c =================================================================== --- sys/dev/usb/wlan/if_zyd.c +++ sys/dev/usb/wlan/if_zyd.c @@ -2628,8 +2628,7 @@ if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) { zyd_init_locked(sc); startall = 1; - } else - zyd_set_multi(sc); + } } else if (sc->sc_flags & ZYD_FLAG_RUNNING) zyd_stop(sc); ZYD_UNLOCK(sc); Index: sys/dev/wi/if_wi.c =================================================================== --- sys/dev/wi/if_wi.c +++ sys/dev/wi/if_wi.c @@ -1143,27 +1143,8 @@ int startall = 0; WI_LOCK(sc); - /* - * Can't do promisc and hostap at the same time. If all that's - * changing is the promisc flag, try to short-circuit a call to - * wi_init() by just setting PROMISC in the hardware. - */ if (ic->ic_nrunning > 0) { - if (ic->ic_opmode != IEEE80211_M_HOSTAP && - sc->sc_flags & WI_FLAGS_RUNNING) { - if (ic->ic_promisc > 0 && - (sc->sc_flags & WI_FLAGS_PROMISC) == 0) { - wi_write_val(sc, WI_RID_PROMISC, 1); - sc->sc_flags |= WI_FLAGS_PROMISC; - } else if (ic->ic_promisc == 0 && - (sc->sc_flags & WI_FLAGS_PROMISC) != 0) { - wi_write_val(sc, WI_RID_PROMISC, 0); - sc->sc_flags &= ~WI_FLAGS_PROMISC; - } else { - wi_init(sc); - startall = 1; - } - } else { + if (!(sc->sc_flags & WI_FLAGS_RUNNING)) { wi_init(sc); startall = 1; } @@ -1547,9 +1528,11 @@ WI_LOCK(sc); /* XXX handle WEP special case handling? */ - wi_write_val(sc, WI_RID_PROMISC, + /* Can't do promisc and hostap at the same time. */ + wi_write_val(sc, WI_RID_PROMISC, + ic->ic_opmode != IEEE80211_M_HOSTAP && (ic->ic_opmode == IEEE80211_M_MONITOR || - (ic->ic_promisc > 0))); + ic->ic_promisc > 0)); WI_UNLOCK(sc); } Index: sys/dev/wi/if_wivar.h =================================================================== --- sys/dev/wi/if_wivar.h +++ sys/dev/wi/if_wivar.h @@ -152,7 +152,6 @@ #define WI_FLAGS_HAS_FRAGTHR 0x0200 #define WI_FLAGS_HAS_DBMADJUST 0x0400 #define WI_FLAGS_RUNNING 0x0800 -#define WI_FLAGS_PROMISC 0x1000 struct wi_card_ident { u_int16_t card_id;