On Thu, Dec 17, 2015 at 10:34 PM, Stefan Sperling <s...@stsp.name> wrote: > On Thu, Dec 17, 2015 at 08:13:03PM +0100, Stefan Sperling wrote: >> This should fix the infinite scanning loops people have been >> reporting with 11n-enabled iwn(4), as well as the issue where >> clients associating to 11g APs end up in 11b mode and can't >> use OFDM data rates. >> >> ok? > > Updated diff which allows scanning to work after somebody decided > to run 'ifconfig iwn0 media autoselect mode 11n' for some reason. > (Don't do that, it won't enforce 11n -- 11n cannot really be set > a priori because it's negotiated during association.) > > Also delete a bit of code from ieee80211_newstate() in ieee80211_proto.c > which is pointless now that ieee80211_chan2mode() won't return MODE_11N.
A minor problem I've noticed was dhclient being slower to get the link from my AP. The patch below fixed it. Thanks again David > Index: ieee80211.c > =================================================================== > RCS file: /cvs/src/sys/net80211/ieee80211.c,v > retrieving revision 1.52 > diff -u -p -r1.52 ieee80211.c > --- ieee80211.c 16 Dec 2015 12:52:03 -0000 1.52 > +++ ieee80211.c 17 Dec 2015 21:16:03 -0000 > @@ -856,10 +856,12 @@ ieee80211_next_mode(struct ifnet *ifp) > { > struct ieee80211com *ic = (void *)ifp; > > - if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO) { > + if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO && > + ic->ic_curmode != IEEE80211_MODE_11N) { > /* > * Reset the scan state and indicate a wrap around > * if we're running in a fixed, user-specified phy mode. > + * But 11n is not a valid phy mode for scanning (see below). > */ > ieee80211_reset_scan(ifp); > return (IEEE80211_MODE_AUTO); > @@ -874,6 +876,16 @@ ieee80211_next_mode(struct ifnet *ifp) > /* Wrap around and ignore turbo mode */ > if (ic->ic_curmode == IEEE80211_MODE_TURBO) > continue; > +#ifndef IEEE80211_NO_HT > + /* > + * Skip 11n mode while scanning. Its set of channels is > + * the superset of all channels supported by other modes > + * and 11n features cannot be negotiated without exchanging > + * frames in another mode first. > + */ > + if (ic->ic_curmode == IEEE80211_MODE_11N) > + continue; > +#endif > if (ic->ic_curmode >= IEEE80211_MODE_MAX) { > ic->ic_curmode = IEEE80211_MODE_AUTO; > break; > @@ -893,6 +905,11 @@ ieee80211_next_mode(struct ifnet *ifp) > * caller can select a rate set. This is problematic and the > * work here assumes how things work elsewhere in this code. > * > + * Because the result of this function is ultimately used to select > + * a rate from the rate set of the returned mode, it must not return > + * IEEE80211_MODE_11N. This function may be called in 11n mode to find > + * a non-MCS rate to use for sending frames to non-HT STAs. > + * > * XXX never returns turbo modes -dcy > */ > enum ieee80211_phymode > @@ -911,11 +928,6 @@ ieee80211_chan2mode(struct ieee80211com > * characteristics. We assume that turbo-only channels > * are not considered when the channel set is constructed. > */ > -#ifndef IEEE80211_NO_HT > - if (IEEE80211_IS_CHAN_N(chan)) > - return IEEE80211_MODE_11N; > - else > -#endif > if (IEEE80211_IS_CHAN_T(chan)) > return IEEE80211_MODE_TURBO; > else if (IEEE80211_IS_CHAN_5GHZ(chan)) > Index: ieee80211_input.c > =================================================================== > RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v > retrieving revision 1.145 > diff -u -p -r1.145 ieee80211_input.c > --- ieee80211_input.c 12 Dec 2015 13:56:10 -0000 1.145 > +++ ieee80211_input.c 17 Dec 2015 18:42:06 -0000 > @@ -2257,16 +2257,8 @@ ieee80211_recv_assoc_resp(struct ieee802 > > /* Hop out of 11n mode after associating to a non-HT AP. */ > if (ic->ic_curmode == IEEE80211_MODE_11N && > - (ni->ni_flags & IEEE80211_NODE_HT) == 0) { > - if (IEEE80211_IS_CHAN_T(ni->ni_chan)) > - ieee80211_setmode(ic, IEEE80211_MODE_TURBO); > - else if (IEEE80211_IS_CHAN_A(ni->ni_chan)) > - ieee80211_setmode(ic, IEEE80211_MODE_11A); > - else if (IEEE80211_IS_CHAN_G(ni->ni_chan)) > - ieee80211_setmode(ic, IEEE80211_MODE_11G); > - else > - ieee80211_setmode(ic, IEEE80211_MODE_11B); > - } > + (ni->ni_flags & IEEE80211_NODE_HT) == 0) > + ieee80211_setmode(ic, ieee80211_chan2mode(ic, ni->ni_chan)); > #endif > /* > * Configure state now that we are associated. > Index: ieee80211_proto.c > =================================================================== > RCS file: /cvs/src/sys/net80211/ieee80211_proto.c,v > retrieving revision 1.56 > diff -u -p -r1.56 ieee80211_proto.c > --- ieee80211_proto.c 24 Nov 2015 13:45:06 -0000 1.56 > +++ ieee80211_proto.c 17 Dec 2015 20:58:40 -0000 > @@ -894,15 +894,8 @@ justcleanup: > /* initialize bss for probe request */ > IEEE80211_ADDR_COPY(ni->ni_macaddr, etherbroadcastaddr); > IEEE80211_ADDR_COPY(ni->ni_bssid, etherbroadcastaddr); > -#ifndef IEEE80211_NO_HT > - if (ic->ic_curmode == IEEE80211_MODE_11N) > - ni->ni_rates = ic->ic_sup_rates[ > - IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ? > - IEEE80211_MODE_11G : IEEE80211_MODE_11A]; > - else > -#endif > - ni->ni_rates = ic->ic_sup_rates[ > - ieee80211_chan2mode(ic, ni->ni_chan)]; > + ni->ni_rates = ic->ic_sup_rates[ > + ieee80211_chan2mode(ic, ni->ni_chan)]; > ni->ni_associd = 0; > ni->ni_rstamp = 0; > switch (ostate) { > -- "If you try a few times and give up, you'll never get there. But if you keep at it... There's a lot of problems in the world which can really be solved by applying two or three times the persistence that other people will." -- Stewart Nelson