summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_iwn.c
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2018-02-01 11:21:35 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2018-02-01 11:21:35 +0000
commit8d2ff4a6e59d43d0c1adf093a491372c849d9bcb (patch)
treef42c3e0c5602de831c8f0f374131599155ea7466 /sys/dev/pci/if_iwn.c
parentfd571528bb540005997ba6154c3b7d69d9fe7974 (diff)
Make sure iwn(4) firmware and driver stay in sync when a scan is
requested by ifconfig while associated. For completeness, do the same for RUN->{ASSOC,AUTH} and AUTH->ASSOC transitions. i.e. always keep the firmware's association state in sync with the driver's state. The firmware should only be associated in RUN state. Fixes a problem where the driver remained in SCAN state forever after running 'ifconfig iwn0 scan' in associated (i.e. RUN) state, presumably because the firmware didn't like the driver's scan command and never signaled completion of the scan. ok kevlo@ phessler@
Diffstat (limited to 'sys/dev/pci/if_iwn.c')
-rw-r--r--sys/dev/pci/if_iwn.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c
index fdb270e8f1a..65969746188 100644
--- a/sys/dev/pci/if_iwn.c
+++ b/sys/dev/pci/if_iwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwn.c,v 1.199 2018/01/31 12:36:13 stsp Exp $ */
+/* $OpenBSD: if_iwn.c,v 1.200 2018/02/01 11:21:34 stsp Exp $ */
/*-
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -1772,6 +1772,25 @@ iwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
iwn_scan_abort(sc);
}
+ if (ic->ic_state == IEEE80211_S_SCAN) {
+ if (nstate == IEEE80211_S_SCAN)
+ return 0;
+ /* Turn LED off when leaving scan state. */
+ iwn_set_led(sc, IWN_LED_LINK, 1, 0);
+ }
+
+ if (ic->ic_state >= IEEE80211_S_ASSOC &&
+ nstate <= IEEE80211_S_ASSOC) {
+ /* Reset state to handle re- and disassociations. */
+ sc->rxon.associd = 0;
+ sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
+ sc->calib.state = IWN_CALIB_STATE_INIT;
+ error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
+ if (error != 0)
+ printf("%s: RXON command failed\n",
+ sc->sc_dev.dv_xname);
+ }
+
switch (nstate) {
case IEEE80211_S_SCAN:
/* Make the link LED blink while we're scanning. */
@@ -1794,11 +1813,6 @@ iwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
break;
/* FALLTHROUGH */
case IEEE80211_S_AUTH:
- /* Reset state to handle reassociations correctly. */
- sc->rxon.associd = 0;
- sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
- sc->calib.state = IWN_CALIB_STATE_INIT;
-
if ((error = iwn_auth(sc, arg)) != 0) {
printf("%s: could not move to auth state\n",
sc->sc_dev.dv_xname);