diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2022-03-20 12:01:59 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2022-03-20 12:01:59 +0000 |
commit | 424bafeee6cdf0c7b8cad002411e5d9efad0ac85 (patch) | |
tree | 8fa476396947559a660fb1e68f28c792043fc6b2 /sys/dev/ic | |
parent | 8b7cfdd9f0073651f6759f7a077c8c9593cf76f8 (diff) |
Introduce an alternative mechanism for wifi drivers to communicate
the channel on which a frame was received.
ieee80211_inputm() was expecting that ic->ic_bss->ni_chan would correspond
to the channel which is currently being scanned. This dates back to older
devices which are manually tuned to the next channel by the driver during
SCAN->SCAN state transitions.
However, this approach is very awkward for drivers which scan across a
whole range of channels in firmware. Such drivers had an ugly workaround
in place which tweaked ni_chan for each received frame.
Introduce a channel number field in the Rx info struct which drivers
can use to indicate the channel on which a frame was received.
If this field is set, net80211 will use it instead of using the current
channel of ic_bss. Use this new mechanism in all affected drivers.
Tested by jmc@, sthen@, and myself on iwm(4) and iwx(4).
Changes to iwn(4) and bwfm(4) are the same mechanical changes to get rid
of the ni_chan tweak, and are therefore expected to work.
ok sthen@ dlg@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/bwfm.c | 20 |
1 files changed, 2 insertions, 18 deletions
diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c index 15e712c92ee..c245bcdac69 100644 --- a/sys/dev/ic/bwfm.c +++ b/sys/dev/ic/bwfm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfm.c,v 1.101 2022/03/06 18:52:47 kettenis Exp $ */ +/* $OpenBSD: bwfm.c,v 1.102 2022/03/20 12:01:58 stsp Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -2703,8 +2703,6 @@ bwfm_scan_node(struct bwfm_softc *sc, struct bwfm_bss_info *bss, size_t len) struct ieee80211_frame *wh; 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; @@ -2739,28 +2737,14 @@ bwfm_scan_node(struct bwfm_softc *sc, struct bwfm_bss_info *bss, size_t len) /* Finalize mbuf. */ m->m_pkthdr.len = m->m_len = pktlen; ni = ieee80211_find_rxnode(ic, wh); - 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]; /* Supply RSSI */ rxi.rxi_flags = 0; rxi.rxi_rssi = (int16_t)letoh16(bss->rssi); rxi.rxi_tstamp = 0; + rxi.rxi_chan = chanidx; ieee80211_input(ifp, m, ni, &rxi); - /* - * 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); } |