From 8f094175c45cca70ff7d7c09e2e3ce649157d71a Mon Sep 17 00:00:00 2001 From: stsp Date: Wed, 9 Mar 2022 11:38:51 +0000 Subject: [PATCH] Improve stability of roaming on iwn(4), in particular with wpa_supplicant. Clear HT-related rxon flags in firmware when switching away from RUN or ASSOC state. This avoids fatal firmware errors. When starting a scan, set link state down and clear ic_bss before sending the scan command to the device, not after. tested by mbuhl@ on eduroam ok mbuhl@ --- sys/dev/pci/if_iwn.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c index 39723423208..2c06d010424 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.254 2022/01/09 05:42:52 jsg Exp $ */ +/* $OpenBSD: if_iwn.c,v 1.255 2022/03/09 11:38:51 stsp Exp $ */ /*- * Copyright (c) 2007-2010 Damien Bergamini @@ -1821,6 +1821,8 @@ iwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) /* Reset state to handle re- and disassociations. */ sc->rxon.associd = 0; sc->rxon.filter &= ~htole32(IWN_FILTER_BSS); + sc->rxon.flags &= ~htole32(IWN_RXON_HT_CHANMODE_MIXED2040 | + IWN_RXON_HT_CHANMODE_PURE40 | IWN_RXON_HT_HT40MINUS); sc->calib.state = IWN_CALIB_STATE_INIT; error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1); if (error != 0) @@ -1833,21 +1835,20 @@ iwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) /* Make the link LED blink while we're scanning. */ iwn_set_led(sc, IWN_LED_LINK, 10, 10); - if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ, 0)) != 0) { - printf("%s: could not initiate scan\n", - sc->sc_dev.dv_xname); - return error; + if ((sc->sc_flags & IWN_FLAG_BGSCAN) == 0) { + ieee80211_set_link_state(ic, LINK_STATE_DOWN); + ieee80211_node_cleanup(ic, ic->ic_bss); } if (ifp->if_flags & IFF_DEBUG) printf("%s: %s -> %s\n", ifp->if_xname, ieee80211_state_name[ic->ic_state], ieee80211_state_name[nstate]); - if ((sc->sc_flags & IWN_FLAG_BGSCAN) == 0) { - ieee80211_set_link_state(ic, LINK_STATE_DOWN); - ieee80211_node_cleanup(ic, ic->ic_bss); - } ic->ic_state = nstate; - return 0; + if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ, 0)) != 0) { + printf("%s: could not initiate scan\n", + sc->sc_dev.dv_xname); + } + return error; case IEEE80211_S_ASSOC: if (ic->ic_state != IEEE80211_S_RUN) -- 2.20.1