diff options
author | 2017-06-14 16:56:50 +0000 | |
---|---|---|
committer | 2017-06-14 16:56:50 +0000 | |
commit | 90e46a7be75b277c317f80ee4ebed30b937dd0eb (patch) | |
tree | 7f3715f8004888e01e09b5db7243c58712961b9c | |
parent | Make iwm(4) wait for the PHY calibration result notification during HW init. (diff) | |
download | wireguard-openbsd-90e46a7be75b277c317f80ee4ebed30b937dd0eb.tar.xz wireguard-openbsd-90e46a7be75b277c317f80ee4ebed30b937dd0eb.zip |
Make the iwm(4) ioctl handler wait until the transition to SCAN has completed
when bringing the interface up. Otherwise we get racy behaviour when running
ifconfig commands which issue several ioctls in quick succession.
Should fix the occasional "could not initiate scan" errors.
ok deraadt@
-rw-r--r-- | sys/dev/pci/if_iwm.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index 9478ce76dec..1edfdd72179 100644 --- a/sys/dev/pci/if_iwm.c +++ b/sys/dev/pci/if_iwm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwm.c,v 1.193 2017/06/14 16:56:04 stsp Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.194 2017/06/14 16:56:50 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh <info@genua.de> @@ -5623,6 +5623,7 @@ iwm_newstate_task(void *psc) sc->sc_flags |= IWM_FLAG_SCANNING; ic->ic_state = nstate; iwm_led_blink_start(sc); + wakeup(&ic->ic_state); /* wake iwm_init() */ return; case IEEE80211_S_AUTH: @@ -6102,7 +6103,8 @@ int iwm_init(struct ifnet *ifp) { struct iwm_softc *sc = ifp->if_softc; - int err; + struct ieee80211com *ic = &sc->sc_ic; + int err, generation; if (sc->sc_flags & IWM_FLAG_HW_INITED) { return 0; @@ -6119,6 +6121,20 @@ iwm_init(struct ifnet *ifp) ifp->if_flags |= IFF_RUNNING; ieee80211_begin_scan(ifp); + + /* + * ieee80211_begin_scan() ends up scheduling iwm_newstate_task(). + * Wait until the transition to SCAN state has completed. + */ + do { + generation = sc->sc_generation; + err = tsleep(&ic->ic_state, PCATCH, "iwminit", hz); + if (generation != sc->sc_generation) + return ENXIO; + if (err) + return err; + } while (ic->ic_state != IEEE80211_S_SCAN); + sc->sc_flags |= IWM_FLAG_HW_INITED; return 0; |