From: Stefan Sperling Subject: Re: fix 802.11 mode selection in ieee80211_node_join_bss() To: tech@openbsd.org Date: Fri, 25 Jul 2025 11:34:42 +0200 On Fri, Jul 25, 2025 at 11:19:16AM +0200, Stefan Sperling wrote: > When we are joining a new BSS (i.e. a new access point) while roaming, > we might have to switch bands from 2 GHz to 5 GHz or vice-versa. > @@ -1303,7 +1303,13 @@ ieee80211_node_join_bss(struct ieee80211com *ic, struc > uint32_t assoc_fail = 0; > > /* Reinitialize media mode and channels if needed. */ > - mode = ieee80211_chan2mode(ic, selbs->ni_chan); > + if (IEEE80211_IS_CHAN_5GHZ(selbs->ni_chan)) > + mode = IEEE80211_MODE_11A; > + else if (ieee80211_iserp_sta(selbs)) > + mode = IEEE80211_MODE_11G; > + else > + mode = IEEE80211_MODE_11B; > + Ooops, this layer needs to take into account whether the driver supports 11g. Drivers announce what they support by setting appropriate channel flags. Check those as well to avoid breaking 11b-only devices such as atw(4). M sys/net80211/ieee80211_node.c | 9+ 3- 1 file changed, 9 insertions(+), 3 deletions(-) commit - d64e5fcced832f2a47ed1896e35987cba9887e42 commit + bccdbcb2d328be6d1547cc7b82972e40e32611a7 blob - c6ca10f5df7c13a01d8cddd8f552e3abf2b41184 blob + 491e5ef044a00ce6912c53914f5f114e1473e2c6 --- sys/net80211/ieee80211_node.c +++ sys/net80211/ieee80211_node.c @@ -1303,7 +1303,15 @@ ieee80211_node_join_bss(struct ieee80211com *ic, struc uint32_t assoc_fail = 0; /* Reinitialize media mode and channels if needed. */ - mode = ieee80211_chan2mode(ic, selbs->ni_chan); + if (IEEE80211_IS_CHAN_5GHZ(selbs->ni_chan)) + mode = IEEE80211_MODE_11A; + else if (ieee80211_iserp_sta(selbs) && + ((selbs->ni_chan->ic_flags & + (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN)) != 0)) + mode = IEEE80211_MODE_11G; + else + mode = IEEE80211_MODE_11B; + if (mode != ic->ic_curmode) ieee80211_setmode(ic, mode); @@ -1317,8 +1325,6 @@ ieee80211_node_join_bss(struct ieee80211com *ic, struc ni = ic->ic_bss; ni->ni_assoc_fail |= assoc_fail; - ic->ic_curmode = ieee80211_chan2mode(ic, ni->ni_chan); - /* Make sure we send valid rates in an association request. */ if (ic->ic_opmode == IEEE80211_M_STA) ieee80211_fix_rate(ic, ni,