Download raw body.
fix 802.11 mode selection in ieee80211_node_join_bss()
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.
This works, but there is a cosmetic wrinkle where the wrong mode will be
displayed in ifconfig.
For example, starting out on a 2 GHz AP in 11g mode:
media: IEEE802.11 autoselect (DS1 mode 11g)
status: active
ieee80211: join ... chan 13
Then roaming to a 5 GHz AP, we switch to the 5GHz channel but the mode
displayed is still "11g":
media: IEEE802.11 autoselect (OFDM48 mode 11g)
status: active
ieee80211: join ... chan 64
The bug is in ieee80211_node_join_bss(), where ieee80211_chan2mode() is used
to select the new mode. This function does not actually change the mode if
ic_curmode is currently set to anything other than AUTO (which is bad and
should probably be fixed in a similar way as below, but I do not want to
change chan2mode's parameters and audit and adjust all its callers right now).
The patch below fixes this by selecting the new mode correctly based on
the new AP's channel, and the AP's support of 11g vs. 11b on 2 GHz.
Now we switch into the correct mode when roaming with qwx:
media: IEEE802.11 autoselect (OFDM48 mode 11a)
status: active
ieee80211: join ... chan 64
This issue didn't stand out on intel drivers because if the AP uses 11n or 11ac
then this bug is masked by switching mode again to 11n or 11ac after association.
ok?
M sys/net80211/ieee80211_node.c | 7+ 3-
1 file changed, 7 insertions(+), 3 deletions(-)
commit - d64e5fcced832f2a47ed1896e35987cba9887e42
commit + 72dcd758474af3c9b355067a177acaf1811ad6c7
blob - c6ca10f5df7c13a01d8cddd8f552e3abf2b41184
blob + 41dfa6f1dc184b2959babd49eface11c548e38b0
--- sys/net80211/ieee80211_node.c
+++ sys/net80211/ieee80211_node.c
@@ -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;
+
if (mode != ic->ic_curmode)
ieee80211_setmode(ic, mode);
@@ -1317,8 +1323,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,
fix 802.11 mode selection in ieee80211_node_join_bss()