summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_iwm.c
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2021-09-30 09:27:48 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2021-09-30 09:27:48 +0000
commitb3cecd2a97a59f9c398eaa56988cf7a7d5216677 (patch)
treefb2f74bd49dfba771bbfe70d87488336cfccb58b /sys/dev/pci/if_iwm.c
parentd913ef2cd7383900278eb942777962af62bd0a0a (diff)
In iwm(4) and iwx(4), prevent attemps to transition towards the same state
in cases where this would result in a redundant or illegal state transition. jmc@ observed ASSOC -> ASSOC transitions which would result in a hang. Such transitions are invalid and never intentionally triggered by net80211. They imply a race between the Rx interrupt handler and the newstate task. Tested by jmc@ on AX200 for a week and several known issues seem to be fixed.
Diffstat (limited to 'sys/dev/pci/if_iwm.c')
-rw-r--r--sys/dev/pci/if_iwm.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
index cb75fbf0f19..c8229ae3802 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.368 2021/09/24 19:02:16 stsp Exp $ */
+/* $OpenBSD: if_iwm.c,v 1.369 2021/09/30 09:27:47 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -9004,6 +9004,14 @@ iwm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
struct iwm_softc *sc = ifp->if_softc;
int i;
+ /*
+ * Prevent attemps to transition towards the same state, unless
+ * we are scanning in which case a SCAN -> SCAN transition
+ * triggers another scan iteration.
+ */
+ if (sc->ns_nstate == nstate && nstate != IEEE80211_S_SCAN)
+ return 0;
+
if (ic->ic_state == IEEE80211_S_RUN) {
timeout_del(&sc->sc_calib_to);
iwm_del_task(sc, systq, &sc->ba_task);