]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Extend the setband support for 6 GHz and band combinations
authorVeerendranath Jakkam <vjakkam@codeaurora.org>
Thu, 6 Aug 2020 06:34:48 +0000 (12:04 +0530)
committerJouni Malinen <j@w1.fi>
Fri, 11 Dec 2020 17:56:14 +0000 (19:56 +0200)
Support possible band combinations of 2.4 GHz, 5 GHz, and 6 GHz with
QCA_WLAN_VENDOR_ATTR_SETBAND_MASK attribute. Ensure backwards
compatibility with old drivers that are using
QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE attribute and supporting only 2.4 GHz
and 5 GHz bands.

Signed-off-by: Veerendranath Jakkam <vjakkam@codeaurora.org>
hostapd/ctrl_iface.c
src/ap/ap_drv_ops.h
src/common/defs.h
src/drivers/driver.h
src/drivers/driver_nl80211.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/driver_i.h
wpa_supplicant/scan.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index e2ae0ad445dd641c0a002b1aad35932bae1de1de..7af4f095a368ecaec965603f988423e2ee7a876a 100644 (file)
@@ -1347,21 +1347,29 @@ static void hostapd_disassoc_deny_mac(struct hostapd_data *hapd)
 
 
 static int hostapd_ctrl_iface_set_band(struct hostapd_data *hapd,
-                                      const char *band)
+                                      const char *bands)
 {
        union wpa_event_data event;
-       enum set_band setband;
-
-       if (os_strcmp(band, "AUTO") == 0)
-               setband = WPA_SETBAND_AUTO;
-       else if (os_strcmp(band, "5G") == 0)
-               setband = WPA_SETBAND_5G;
-       else if (os_strcmp(band, "2G") == 0)
-               setband = WPA_SETBAND_2G;
-       else
-               return -1;
+       u32 setband_mask = WPA_SETBAND_AUTO;
+
+       /*
+        * For example:
+        *  SET setband 2G,6G
+        *  SET setband 5G
+        *  SET setband AUTO
+        */
+       if (!os_strstr(bands, "AUTO")) {
+               if (os_strstr(bands, "5G"))
+                       setband_mask |= WPA_SETBAND_5G;
+               if (os_strstr(bands, "6G"))
+                       setband_mask |= WPA_SETBAND_6G;
+               if (os_strstr(bands, "2G"))
+                       setband_mask |= WPA_SETBAND_2G;
+               if (setband_mask == WPA_SETBAND_AUTO)
+                       return -1;
+       }
 
-       if (hostapd_drv_set_band(hapd, setband) == 0) {
+       if (hostapd_drv_set_band(hapd, setband_mask) == 0) {
                os_memset(&event, 0, sizeof(event));
                event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
                event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
index cc7ea07a2f0b530b6b803b212da1d51b5a1a6d34..0257c3a65964b23a13a1ca98c3552767bcb879eb 100644 (file)
@@ -385,11 +385,11 @@ hostapd_drv_send_external_auth_status(struct hostapd_data *hapd,
 }
 
 static inline int
-hostapd_drv_set_band(struct hostapd_data *hapd, enum set_band band)
+hostapd_drv_set_band(struct hostapd_data *hapd, u32 band_mask)
 {
        if (!hapd->driver || !hapd->drv_priv || !hapd->driver->set_band)
                return -1;
-       return hapd->driver->set_band(hapd->drv_priv, band);
+       return hapd->driver->set_band(hapd->drv_priv, band_mask);
 }
 
 #endif /* AP_DRV_OPS */
index bbe3120de82ffd1f3c25515d46a0f076f5be08f6..b01ab03b650aaffe62e6aaa4c1aebc3d7cc38e2e 100644 (file)
@@ -388,9 +388,10 @@ enum mesh_plink_state {
 };
 
 enum set_band {
-       WPA_SETBAND_AUTO,
-       WPA_SETBAND_5G,
-       WPA_SETBAND_2G
+       WPA_SETBAND_AUTO = 0,
+       WPA_SETBAND_5G = BIT(0),
+       WPA_SETBAND_2G = BIT(1),
+       WPA_SETBAND_6G = BIT(2),
 };
 
 enum wpa_radio_work_band {
index 58a7bd776a5bcf974ac931f1831502dd15da5c14..b0543e7b42be4dba8d64f19cc1349256f44e4eae 100644 (file)
@@ -4277,12 +4277,12 @@ struct wpa_driver_ops {
        int (*do_acs)(void *priv, struct drv_acs_params *params);
 
        /**
-        * set_band - Notify driver of band selection
+        * set_band - Notify driver of band(s) selection
         * @priv: Private driver interface data
-        * @band: The selected band(s)
+        * @band_mask: The selected band(s) bit mask (from enum set_band)
         * Returns 0 on success, -1 on failure
         */
-       int (*set_band)(void *priv, enum set_band band);
+       int (*set_band)(void *priv, u32 band_mask);
 
        /**
         * get_pref_freq_list - Get preferred frequency list for an interface
index 8ba1bf72f8495323d9c0681f23ad53eea51aace1..448c404f303b7035f2f78b76db31da8093137b6e 100644 (file)
@@ -10795,38 +10795,49 @@ static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
 }
 
 
-static int nl80211_set_band(void *priv, enum set_band band)
+static int nl80211_set_band(void *priv, u32 band_mask)
 {
        struct i802_bss *bss = priv;
        struct wpa_driver_nl80211_data *drv = bss->drv;
        struct nl_msg *msg;
        struct nlattr *data;
        int ret;
-       enum qca_set_band qca_band;
+       enum qca_set_band qca_band_value;
+       u32 qca_band_mask = QCA_SETBAND_AUTO;
 
-       if (!drv->setband_vendor_cmd_avail)
+       if (!drv->setband_vendor_cmd_avail ||
+           (band_mask > (WPA_SETBAND_2G | WPA_SETBAND_5G | WPA_SETBAND_6G)))
                return -1;
 
-       switch (band) {
-       case WPA_SETBAND_AUTO:
-               qca_band = QCA_SETBAND_AUTO;
-               break;
-       case WPA_SETBAND_5G:
-               qca_band = QCA_SETBAND_5G;
-               break;
-       case WPA_SETBAND_2G:
-               qca_band = QCA_SETBAND_2G;
-               break;
-       default:
-               return -1;
-       }
+       if (band_mask & WPA_SETBAND_5G)
+               qca_band_mask |= QCA_SETBAND_5G;
+       if (band_mask & WPA_SETBAND_2G)
+               qca_band_mask |= QCA_SETBAND_2G;
+       if (band_mask & WPA_SETBAND_6G)
+               qca_band_mask |= QCA_SETBAND_6G;
+
+       /*
+        * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE is a legacy interface hence make
+        * it suite to its values (AUTO/5G/2G) for backwards compatibility.
+        */
+       qca_band_value = ((qca_band_mask & QCA_SETBAND_5G) &&
+                         (qca_band_mask & QCA_SETBAND_2G)) ?
+                               QCA_SETBAND_AUTO :
+                               qca_band_mask & ~QCA_SETBAND_6G;
+
+       wpa_printf(MSG_DEBUG,
+                  "nl80211: QCA_BAND_MASK = 0x%x, QCA_BAND_VALUE = %d",
+                  qca_band_mask, qca_band_value);
 
        if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
            nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
            nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
                        QCA_NL80211_VENDOR_SUBCMD_SETBAND) ||
            !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
-           nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE, qca_band)) {
+           nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE,
+                       qca_band_value) ||
+           nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SETBAND_MASK,
+                       qca_band_mask)) {
                nlmsg_free(msg);
                return -ENOBUFS;
        }
index 8306950a57ae03ba5e33ce3fdddf40ebc96a8b67..7ce2a90e8a96bc64f544d4edf97cf971513cfbaf 100644 (file)
@@ -299,20 +299,30 @@ static int wpas_ctrl_pno(struct wpa_supplicant *wpa_s, char *cmd)
 }
 
 
-static int wpas_ctrl_set_band(struct wpa_supplicant *wpa_s, char *band)
+static int wpas_ctrl_set_band(struct wpa_supplicant *wpa_s, char *bands)
 {
        union wpa_event_data event;
+       u32 setband_mask = WPA_SETBAND_AUTO;
 
-       if (os_strcmp(band, "AUTO") == 0)
-               wpa_s->setband = WPA_SETBAND_AUTO;
-       else if (os_strcmp(band, "5G") == 0)
-               wpa_s->setband = WPA_SETBAND_5G;
-       else if (os_strcmp(band, "2G") == 0)
-               wpa_s->setband = WPA_SETBAND_2G;
-       else
-               return -1;
+       /*
+        * For example:
+        *  SET setband 2G,6G
+        *  SET setband 5G
+        *  SET setband AUTO
+        */
+       if (!os_strstr(bands, "AUTO")) {
+               if (os_strstr(bands, "5G"))
+                       setband_mask |= WPA_SETBAND_5G;
+               if (os_strstr(bands, "6G"))
+                       setband_mask |= WPA_SETBAND_6G;
+               if (os_strstr(bands, "2G"))
+                       setband_mask |= WPA_SETBAND_2G;
+               if (setband_mask == WPA_SETBAND_AUTO)
+                       return -1;
+       }
 
-       if (wpa_drv_setband(wpa_s, wpa_s->setband) == 0) {
+       wpa_s->setband_mask = setband_mask;
+       if (wpa_drv_setband(wpa_s, wpa_s->setband_mask) == 0) {
                os_memset(&event, 0, sizeof(event));
                event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
                event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
index 3a2828982a242d4cccca20faabcd039760e2ed23..237f4e08516fd237fdb7ebc18b3697e93ac55e6f 100644 (file)
@@ -954,11 +954,11 @@ static inline int wpa_drv_disable_transmit_sa(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_MACSEC */
 
 static inline int wpa_drv_setband(struct wpa_supplicant *wpa_s,
-                                 enum set_band band)
+                                 u32 band_mask)
 {
        if (!wpa_s->driver->set_band)
                return -1;
-       return wpa_s->driver->set_band(wpa_s->drv_priv, band);
+       return wpa_s->driver->set_band(wpa_s->drv_priv, band_mask);
 }
 
 static inline int wpa_drv_get_pref_freq_list(struct wpa_supplicant *wpa_s,
index edf3ca800e3efd7f54c0c417ffb04016c1e898b5..5339b796b52793d48fd7e332d475b775906a24cd 100644 (file)
@@ -713,12 +713,15 @@ static void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s,
        if (params->freqs)
                return; /* already using a limited channel set */
 
-       if (wpa_s->setband == WPA_SETBAND_5G)
+       if (wpa_s->setband_mask & WPA_SETBAND_5G)
                wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, params,
                                        0);
-       else if (wpa_s->setband == WPA_SETBAND_2G)
+       if (wpa_s->setband_mask & WPA_SETBAND_2G)
                wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, params,
                                        0);
+       if (wpa_s->setband_mask & WPA_SETBAND_6G)
+               wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, params,
+                                       1);
 }
 
 
index ddd43e5d2694f2647000d33ece7d06e552f7fe71..5560197bdfda8faf709ea85b1f55a547ba9968fa 100644 (file)
@@ -5111,6 +5111,7 @@ wpa_supplicant_alloc(struct wpa_supplicant *parent)
        wpa_s->parent = parent ? parent : wpa_s;
        wpa_s->p2pdev = wpa_s->parent;
        wpa_s->sched_scanning = 0;
+       wpa_s->setband_mask = WPA_SETBAND_AUTO;
 
        dl_list_init(&wpa_s->bss_tmp_disallowed);
        dl_list_init(&wpa_s->fils_hlp_req);
index ffaacf94804785a4bf357ebd143aca7c1d61c02d..212cc37b664097e28c67da0083ed304531c6bae5 100644 (file)
@@ -594,7 +594,7 @@ struct wpa_supplicant {
        struct wpa_ssid_value *disallow_aps_ssid;
        size_t disallow_aps_ssid_count;
 
-       enum set_band setband;
+       u32 setband_mask;
 
        /* Preferred network for the next connection attempt */
        struct wpa_ssid *next_ssid;