Restore the BSS channel only if iee80211_input() has not changed the BSS.
The same change was added to iwm a year ago, for a more detailed explanation
see https://marc.info/?l=openbsd-tech&m=153407168731621&w=2
ok?
Index: sys/dev/pci/if_iwn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
retrieving revision 1.217
diff -u -p -r1.217 if_iwn.c
--- sys/dev/pci/if_iwn.c 18 Sep 2019 23:52:32 -0000 1.217
+++ sys/dev/pci/if_iwn.c 8 Oct 2019 09:21:18 -0000
@@ -2017,6 +2017,7 @@ iwn_rx_done(struct iwn_softc *sc, struct
struct ieee80211_rxinfo rxi;
struct ieee80211_node *ni;
struct ieee80211_channel *bss_chan = NULL;
+ uint8_t saved_bssid[IEEE80211_ADDR_LEN] = { 0 };
struct mbuf *m, *m1;
struct iwn_rx_stat *stat;
caddr_t head;
@@ -2183,8 +2184,14 @@ iwn_rx_done(struct iwn_softc *sc, struct
chan = IEEE80211_CHAN_MAX;
/* Fix current channel. */
- if (ni == ic->ic_bss)
+ if (ni == ic->ic_bss) {
+ /*
+ * We may switch ic_bss's channel during scans.
+ * Record the current channel so we can restore it later.
+ */
bss_chan = ni->ni_chan;
+ IEEE80211_ADDR_COPY(&saved_bssid, ni->ni_macaddr);
+ }
ni->ni_chan = &ic->ic_channels[chan];
#if NBPFILTER > 0
@@ -2236,8 +2243,11 @@ iwn_rx_done(struct iwn_softc *sc, struct
rxi.rxi_tstamp = 0; /* unused */
ieee80211_inputm(ifp, m, ni, &rxi, ml);
- /* Restore BSS channel. */
- if (ni == ic->ic_bss)
+ /*
+ * ieee80211_input() might have changed our BSS.
+ * Restore ic_bss's channel if we are still in the same BSS.
+ */
+ if (ni == ic->ic_bss && IEEE80211_ADDR_EQ(saved_bssid, ni->ni_macaddr))
ni->ni_chan = bss_chan;
/* Node is no longer needed. */