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:

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

Reply via email to