Sync the BSS channel restore parts around ieee80211_input() with iwm and iwn.
See: https://marc.info/?l=openbsd-tech&m=153407168731621&w=2 https://marc.info/?l=openbsd-tech&m=157052714901054&w=2 ok? Index: ic/bwfm.c =================================================================== RCS file: /cvs/src/sys/dev/ic/bwfm.c,v retrieving revision 1.64 diff -u -p -u -r1.64 bwfm.c --- ic/bwfm.c 27 Aug 2019 14:57:48 -0000 1.64 +++ ic/bwfm.c 8 Oct 2019 13:03:51 -0000 @@ -2369,6 +2369,7 @@ bwfm_scan_node(struct bwfm_softc *sc, st struct ieee80211_node *ni; struct ieee80211_rxinfo rxi; struct ieee80211_channel *bss_chan; + uint8_t saved_bssid[IEEE80211_ADDR_LEN] = { 0 }; struct mbuf *m; uint32_t pktlen, ieslen; uint16_t iesoff; @@ -2403,13 +2404,16 @@ bwfm_scan_node(struct bwfm_softc *sc, st /* Finalize mbuf. */ m->m_pkthdr.len = m->m_len = pktlen; ni = ieee80211_find_rxnode(ic, wh); - /* - * We may switch ic_bss's channel during scans. - * Record the current channel so we can restore it later. - */ - bss_chan = NULL; - if (ni == ic->ic_bss) + + /* Fix current channel. */ + 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); + } /* Channel mask equals IEEE80211_CHAN_MAX */ chanidx = bwfm_spec2chan(sc, letoh32(bss->chanspec)); ni->ni_chan = &ic->ic_channels[chanidx]; @@ -2418,9 +2422,14 @@ bwfm_scan_node(struct bwfm_softc *sc, st rxi.rxi_rssi = (int16_t)letoh16(bss->rssi); rxi.rxi_tstamp = 0; ieee80211_input(ifp, m, ni, &rxi); - /* Restore channel */ - if (bss_chan) + + /* + * 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. */ ieee80211_release_node(ic, ni); }
