The wireless stack usually runs its scanning loop once per frequency band.
It begins with 5GHz so that APs on this band are preferred. Within a band,
an AP with the best RSSI (receive signal strength indicator) is chosen,
after matching all other desired parameters such as the ESSID etc.

I am not sure what the rationale was at the time this code was written
but today there is a good reason to prefer 5GHz. This band is usually
much less crowded and gives a much better experience as a result.
Because 5GHz is scanned first we'll usually prefer this band.

However, iwm(4) runs a scan across all bands at once so we pick an AP based
on RSSI alone. In practice, we often end up choosing 2GHz APs instead of
5GHz APs, even in cases where 5GHz would work fine, just with a slightly
lower RSSI.

With this diff we prefer 5GHz APs with "good enough" RSSI over 2GHz APs.

Index: ieee80211_node.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.103
diff -u -p -r1.103 ieee80211_node.c
--- ieee80211_node.c    21 May 2016 09:07:11 -0000      1.103
+++ ieee80211_node.c    15 Aug 2016 12:14:21 -0000
@@ -622,12 +622,23 @@ ieee80211_end_scan(struct ifnet *ifp)
                                ieee80211_free_node(ic, ni);
                        continue;
                }
-               if (ieee80211_match_bss(ic, ni) == 0) {
-                       if (selbs == NULL)
-                               selbs = ni;
-                       else if (ni->ni_rssi > selbs->ni_rssi)
-                               selbs = ni;
-               }
+               if (ieee80211_match_bss(ic, ni) != 0)
+                       continue;
+
+               /* Pick the AP/IBSS match with the best RSSI. */
+               if (selbs == NULL)
+                       selbs = ni;
+               else if ((ic->ic_caps & IEEE80211_C_SCANALLBAND) &&
+                   IEEE80211_IS_CHAN_5GHZ(selbs->ni_chan) &&
+                   IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) &&
+                   selbs->ni_rssi >= (ic->ic_max_rssi - (ic->ic_max_rssi / 4)))
+                       /* 
+                        * Prefer 5GHz (with reasonable RSSI) over 2GHz since
+                        * the 5GHz band is usually less saturated.
+                        */
+                       continue;
+               else if (ni->ni_rssi > selbs->ni_rssi)
+                       selbs = ni;
        }
        if (selbs == NULL)
                goto notfound;

Reply via email to