Author: avos
Date: Wed Jan 23 12:43:46 2019
New Revision: 343340
URL: https://svnweb.freebsd.org/changeset/base/343340

Log:
  net80211: fix channel list construction for non-auto operating mode.
  
  Change the way how channel list mode <-> desired mode match is done:
  - Match channel list mode for next non-auto desired modes:
   * 11b: 11g, 11ng, 11acg;
   * 11a: 11na, 11ac
  - Add pre-defined channels only when one of the next conditions met:
   * the desired channel mode is 'auto' or
   * the desired channel and selected channel list modes are exactly
  the same or
   * the previous rule (11g / 11n / 11ac promotion) applies.
  
  Before r275875 construction work properly for all except
  11ng / 11na / 11acg / 11ac modes - these were broken at all
  (i.e., the scan list was empty); after r275875 all checks were removed,
  so scan table was populated by all device-compatible channels
  (desired mode was ignored).
  
  For example, if I will set 'ifconfig wlan0 mode 11ng' for RTL8821AU:
  - pre-r275875: nothing, scan will not work;
  - after r275875: both 11ng and 11na bands were scanned; also, since 11b
  channel list was used, 14th channel was scanned too.
  - after this change: only 11ng - 1-13 channels - are used for scanning.
  
  Tested with:
   * RTL8188EE, STA mode.
   * RTL8821AU, STA mode.
  
  MFC after:    5 days

Modified:
  head/sys/net80211/ieee80211_scan_sta.c

Modified: head/sys/net80211/ieee80211_scan_sta.c
==============================================================================
--- head/sys/net80211/ieee80211_scan_sta.c      Wed Jan 23 10:05:27 2019        
(r343339)
+++ head/sys/net80211/ieee80211_scan_sta.c      Wed Jan 23 12:43:46 2019        
(r343340)
@@ -472,6 +472,8 @@ static const u_int chanflags[IEEE80211_MODE_MAX] = {
        /* check legacy */
        [IEEE80211_MODE_11NA]     = IEEE80211_CHAN_A,
        [IEEE80211_MODE_11NG]     = IEEE80211_CHAN_G,
+       [IEEE80211_MODE_VHT_5GHZ] = IEEE80211_CHAN_A,
+       [IEEE80211_MODE_VHT_2GHZ] = IEEE80211_CHAN_G,
 };
 
 static void
@@ -618,32 +620,48 @@ makescanlist(struct ieee80211_scan_state *ss, struct i
         */
        for (scan = table; scan->list != NULL; scan++) {
                mode = scan->mode;
-               if (vap->iv_des_mode != IEEE80211_MODE_AUTO) {
+
+               switch (mode) {
+               case IEEE80211_MODE_11B:
+                       if (vap->iv_des_mode == IEEE80211_MODE_11B)
+                               break;
+
                        /*
-                        * If a desired mode was specified, scan only 
-                        * channels that satisfy that constraint.
+                        * The scan table marks 2.4Ghz channels as b
+                        * so if the desired mode is 11g / 11ng / 11acg,
+                        * then use the 11b channel list but upgrade the mode.
+                        *
+                        * NB: 11b -> AUTO lets add_channels upgrade an
+                        * 11b channel to 11g if available.
                         */
-                       if (vap->iv_des_mode != mode) {
-                               /*
-                                * The scan table marks 2.4Ghz channels as b
-                                * so if the desired mode is 11g, then use
-                                * the 11b channel list but upgrade the mode.
-                                */
-                               if (vap->iv_des_mode == IEEE80211_MODE_11G) {
-                                       if (mode == IEEE80211_MODE_11G) /* Skip 
the G check */
-                                               continue;
-                                       else if (mode == IEEE80211_MODE_11B)
-                                               mode = IEEE80211_MODE_11G;      
/* upgrade */
-                               }
+                       if (vap->iv_des_mode == IEEE80211_MODE_AUTO ||
+                           vap->iv_des_mode == IEEE80211_MODE_11G ||
+                           vap->iv_des_mode == IEEE80211_MODE_11NG ||
+                           vap->iv_des_mode == IEEE80211_MODE_VHT_2GHZ) {
+                               mode = vap->iv_des_mode;
+                               break;
                        }
-               } else {
+
+                       continue;
+               case IEEE80211_MODE_11A:
+                       /* Use 11a channel list for 11na / 11ac modes */
+                       if (vap->iv_des_mode == IEEE80211_MODE_11NA ||
+                           vap->iv_des_mode == IEEE80211_MODE_VHT_5GHZ) {
+                               mode = vap->iv_des_mode;
+                               break;
+                       }
+
+                       /* FALLTHROUGH */
+               default:
                        /*
-                        * This lets add_channels upgrade an 11b channel
-                        * to 11g if available.
+                        * If a desired mode was specified, scan only
+                        * channels that satisfy that constraint.
                         */
-                       if (mode == IEEE80211_MODE_11B)
-                               mode = IEEE80211_MODE_AUTO;
+                       if (vap->iv_des_mode != IEEE80211_MODE_AUTO &&
+                           vap->iv_des_mode != mode)
+                               continue;
                }
+
 #ifdef IEEE80211_F_XR
                /* XR does not operate on turbo channels */
                if ((vap->iv_flags & IEEE80211_F_XR) &&
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to