From: Stefan Sperling Subject: Re: fix net80211 802.11g compatibility check To: tech@openbsd.org Date: Thu, 31 Jul 2025 16:16:49 +0200 On Thu, Jul 31, 2025 at 12:26:48PM +0100, Tom Smyth wrote: > so it would be better to check for at least one of the supported rates to > detect a particular standard of AP be it 802.11 b, or a or g or n or ac > etc... > If we make any of the extended rates count, then we could use a simpler heuristic: Check for the presence of the "extended rates" info element in beacons, probe responses, assoc requests etc. on 2GHz channels. M sys/dev/ic/qwx.c | 1+ 1- M sys/net80211/ieee80211_node.c | 7+ 29- 2 files changed, 8 insertions(+), 30 deletions(-) commit - 9af86e4b4d937c32c5d083ec0b7952c1b34fada6 commit + 1403242634014294ccb5ea5de1aabc3d401721b2 blob - f7921f80d7b005454efa677b714d90697dd06468 blob + 6d640b2d7627eb188213ca0960b21ac99914f4fa --- sys/dev/ic/qwx.c +++ sys/dev/ic/qwx.c @@ -23135,7 +23135,7 @@ qwx_mac_vdev_start_restart(struct qwx_softc *sc, struc /* Deduce a legacy mode based on the channel characteristics. */ if (IEEE80211_IS_CHAN_5GHZ(chan)) arg.channel.mode = MODE_11A; - else if (ieee80211_iserp_sta(ic->ic_bss)) + else if (ic->ic_bss->ni_flags & IEEE80211_NODE_ERP) arg.channel.mode = MODE_11G; else arg.channel.mode = MODE_11B; blob - c6ca10f5df7c13a01d8cddd8f552e3abf2b41184 blob + 3a5f05057cc85ece31e8cd14ea58fd79445a68e4 --- sys/net80211/ieee80211_node.c +++ sys/net80211/ieee80211_node.c @@ -2633,6 +2633,10 @@ ieee80211_setup_rates(struct ieee80211com *ic, struct } memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); rs->rs_nrates += nxrates; + + /* 11g support implies ERP support */ + if (nxrates > 0 && IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) + ni->ni_flags |= IEEE80211_NODE_ERP; } return ieee80211_fix_rate(ic, ni, flags); } @@ -2684,31 +2688,6 @@ ieee80211_node_addba_request_ac_vo_to(void *arg) ieee80211_node_addba_request(ni, EDCA_AC_VO); } -/* - * Check if the specified node supports ERP / 802.11g. - */ -int -ieee80211_iserp_sta(const struct ieee80211_node *ni) -{ - static const u_int8_t rates[] = { 2, 4, 11, 22, 12, 24, 48 }; - const struct ieee80211_rateset *rs = &ni->ni_rates; - int i, j; - - /* - * A STA supports ERP operation if it includes all the Clause 19 - * mandatory rates in its supported rate set. - */ - for (i = 0; i < nitems(rates); i++) { - for (j = 0; j < rs->rs_nrates; j++) { - if ((rs->rs_rates[j] & IEEE80211_RATE_VAL) == rates[i]) - break; - } - if (j == rs->rs_nrates) - return 0; - } - return 1; -} - #ifndef IEEE80211_STA_ONLY /* * This function is called to notify the 802.1X PACP machine that a new @@ -2804,7 +2783,7 @@ ieee80211_count_nonerpsta(void *arg, struct ieee80211_ if (ni->ni_associd == 0 || ni->ni_state == IEEE80211_STA_COLLECT) return; - if (!ieee80211_iserp_sta(ni)) + if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) (*nonerpsta)++; } @@ -2857,7 +2836,7 @@ ieee80211_node_join_11g(struct ieee80211com *ic, struc ether_sprintf(ni->ni_macaddr), longslotsta)); } - if (!ieee80211_iserp_sta(ni)) { + if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) { /* * Joining STA is non-ERP. */ @@ -2874,8 +2853,7 @@ ieee80211_node_join_11g(struct ieee80211com *ic, struc if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; - } else - ni->ni_flags |= IEEE80211_NODE_ERP; + } } void