On Sun, Aug 25, 2019 at 03:42:53PM +0200, Stefan Sperling wrote:
> On Sun, Aug 25, 2019 at 02:53:58PM +0200, Stefan Sperling wrote:
> > I've seen iwm(4) get stuck trying to associate to 2 GHz APs only and
> > never trying available 5 GHz ones. This happens because net80211 sets
> > a fixed mode during association attempts (11g in my case). If roaming
> > fails, the interface remains stuck in that mode (and the mode is never
> > upgraded to 11n if association fails, so we're now stuck on 2 GHz).
> >
> > This patch fixes the problem for me. Below are logs which show the
> > problematic case: all 5 Ghz APs keep getting rejected because their
> > channel is not considered part of the active channel set.
> >
> > With the fix the interface will roam between both bands as expected.
> >
> > OK?
> >
>
> The previous patch broke operation in a fixed user-specified phy mode.
> E.g. iwm(4) would associate to a 5 GHz AP after 'ifconfig iwm0 mode 11g'.
>
> Updated diff with that problem fixed:
I have got one positive test report from fkr.
Anyone else looking at this?
> diff refs/heads/keepnodes refs/heads/roaming
> blob - 83b42976022d4ed42a9165720139abe5c1508324
> blob + 6bca50ffd8bc6cbeba4db35a222e02f35e6b8143
> --- sys/dev/pci/if_iwm.c
> +++ sys/dev/pci/if_iwm.c
> @@ -5694,6 +5694,13 @@ iwm_scan(struct iwm_softc *sc)
> return err;
> }
>
> + /*
> + * The current mode might have been fixed during association.
> + * Ensure all channels get scanned.
> + */
> + if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
> + ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
> +
> sc->sc_flags |= IWM_FLAG_SCANNING;
> if (ifp->if_flags & IFF_DEBUG)
> printf("%s: %s -> %s\n", ifp->if_xname,
> blob - ef5f81699e90f2d4c4202b25880c9120907e5ec3
> blob + f2f51baa751bc57c3c5fe43eebb55dd68b5283ef
> --- sys/dev/pci/if_iwn.c
> +++ sys/dev/pci/if_iwn.c
> @@ -5199,6 +5199,13 @@ iwn_scan(struct iwn_softc *sc, uint16_t flags, int bgs
> DPRINTF(("sending scan command nchan=%d\n", hdr->nchan));
> error = iwn_cmd(sc, IWN_CMD_SCAN, buf, buflen, 1);
> if (error == 0) {
> + /*
> + * The current mode might have been fixed during association.
> + * Ensure all channels get scanned.
> + */
> + if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
> + ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
> +
> sc->sc_flags |= IWN_FLAG_SCANNING;
> if (bgscan)
> sc->sc_flags |= IWN_FLAG_BGSCAN;
> blob - 9424dd2a492f1fb2398b9208d36906d2d2ab71ea
> blob + f4b8e9f8c0b4072a33514f7abc2ebcb1e0947fe0
> --- sys/net80211/ieee80211.c
> +++ sys/net80211/ieee80211.c
> @@ -1035,11 +1035,20 @@ ieee80211_next_mode(struct ifnet *ifp)
>
> /*
> * Indicate a wrap-around if we're running in a fixed, user-specified
> - * phy mode or if the driver scans all bands in one scan iteration.
> + * phy mode.
> */
> - if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO ||
> - (ic->ic_caps & IEEE80211_C_SCANALLBAND))
> + if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO)
> return (IEEE80211_MODE_AUTO);
> +
> + /*
> + * Always scan in AUTO mode if the driver scans all bands.
> + * The current mode might have changed during association
> + * so we must reset it here.
> + */
> + if (ic->ic_caps & IEEE80211_C_SCANALLBAND) {
> + ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
> + return (ic->ic_curmode);
> + }
>
> /*
> * Get the next supported mode; effectively, this alternates between
>