]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - src/ap/ap_drv_ops.c
Add ACS support for 60 GHz channel bonding
[thirdparty/hostap.git] / src / ap / ap_drv_ops.c
index dcc4fdc459fa229ffe8abc2dc838cfa195c185b4..1aa2ab038476c6a50b205f133dd912c28ba48b5a 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "utils/common.h"
 #include "common/ieee802_11_defs.h"
+#include "common/ieee802_11_common.h"
 #include "common/hw_features_common.h"
 #include "wps/wps.h"
 #include "p2p/p2p.h"
@@ -679,36 +680,41 @@ int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
 
 int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
                        enum wpa_alg alg, const u8 *addr,
-                       int key_idx, int set_tx,
+                       int key_idx, int vlan_id, int set_tx,
                        const u8 *seq, size_t seq_len,
-                       const u8 *key, size_t key_len)
+                       const u8 *key, size_t key_len, enum key_flag key_flag)
 {
+       struct wpa_driver_set_key_params params;
+
        if (hapd->driver == NULL || hapd->driver->set_key == NULL)
                return 0;
-       return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
-                                    key_idx, set_tx, seq, seq_len, key,
-                                    key_len);
-}
 
+       os_memset(&params, 0, sizeof(params));
+       params.ifname = ifname;
+       params.alg = alg;
+       params.addr = addr;
+       params.key_idx = key_idx;
+       params.set_tx = set_tx;
+       params.seq = seq;
+       params.seq_len = seq_len;
+       params.key = key;
+       params.key_len = key_len;
+       params.vlan_id = vlan_id;
+       params.key_flag = key_flag;
 
-int hostapd_drv_send_mlme(struct hostapd_data *hapd,
-                         const void *msg, size_t len, int noack)
-{
-       if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
-               return 0;
-       return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
-                                      NULL, 0);
+       return hapd->driver->set_key(hapd->drv_priv, &params);
 }
 
 
-int hostapd_drv_send_mlme_csa(struct hostapd_data *hapd,
-                             const void *msg, size_t len, int noack,
-                             const u16 *csa_offs, size_t csa_offs_len)
+int hostapd_drv_send_mlme(struct hostapd_data *hapd,
+                         const void *msg, size_t len, int noack,
+                         const u16 *csa_offs, size_t csa_offs_len,
+                         int no_encrypt)
 {
-       if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
+       if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
                return 0;
        return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
-                                      csa_offs, csa_offs_len);
+                                      csa_offs, csa_offs_len, no_encrypt, 0);
 }
 
 
@@ -855,10 +861,24 @@ static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
        for (i = 0; i < mode->num_channels; i++) {
                struct hostapd_channel_data *chan = &mode->channels[i];
 
-               if ((acs_ch_list_all ||
-                    freq_range_list_includes(&hapd->iface->conf->acs_ch_list,
-                                             chan->chan)) &&
-                   !(chan->flag & HOSTAPD_CHAN_DISABLED) &&
+               if (!acs_ch_list_all &&
+                   (hapd->iface->conf->acs_freq_list.num &&
+                    !freq_range_list_includes(
+                            &hapd->iface->conf->acs_freq_list,
+                            chan->freq)))
+                       continue;
+               if (!acs_ch_list_all &&
+                   (!hapd->iface->conf->acs_freq_list_present &&
+                    hapd->iface->conf->acs_ch_list.num &&
+                    !freq_range_list_includes(
+                            &hapd->iface->conf->acs_ch_list,
+                            chan->chan)))
+                       continue;
+               if (is_6ghz_freq(chan->freq) &&
+                   hapd->iface->conf->acs_exclude_6ghz_non_psc &&
+                   !is_6ghz_psc_frequency(chan->freq))
+                       continue;
+               if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
                    !(hapd->iface->conf->acs_exclude_dfs &&
                      (chan->flag & HOSTAPD_CHAN_RADAR)))
                        int_array_add_unique(freq_list, chan->freq);
@@ -886,6 +906,7 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd)
        int ret, i, acs_ch_list_all = 0;
        struct hostapd_hw_modes *mode;
        int *freq_list = NULL;
+       enum hostapd_hw_mode selected_mode;
 
        if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
                return 0;
@@ -897,35 +918,27 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd)
         * If no chanlist config parameter is provided, include all enabled
         * channels of the selected hw_mode.
         */
-       if (!hapd->iface->conf->acs_ch_list.num)
-               acs_ch_list_all = 1;
-
-       mode = hapd->iface->current_mode;
-       if (mode) {
-               for (i = 0; i < mode->num_channels; i++) {
-                       struct hostapd_channel_data *chan = &mode->channels[i];
-                       if (!acs_ch_list_all &&
-                           !freq_range_list_includes(
-                                   &hapd->iface->conf->acs_ch_list,
-                                   chan->chan))
-                               continue;
-                       if (hapd->iface->conf->acs_exclude_dfs &&
-                           (chan->flag & HOSTAPD_CHAN_RADAR))
-                               continue;
-                       if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) {
-                               int_array_add_unique(&freq_list, chan->freq);
-                       }
-               }
-       } else {
-               for (i = 0; i < hapd->iface->num_hw_features; i++) {
-                       mode = &hapd->iface->hw_features[i];
-                       hostapd_get_hw_mode_any_channels(hapd, mode,
-                                                        acs_ch_list_all,
-                                                        &freq_list);
-               }
+       if (hapd->iface->conf->acs_freq_list_present)
+               acs_ch_list_all = !hapd->iface->conf->acs_freq_list.num;
+       else
+               acs_ch_list_all = !hapd->iface->conf->acs_ch_list.num;
+
+       if (hapd->iface->current_mode)
+               selected_mode = hapd->iface->current_mode->mode;
+       else
+               selected_mode = HOSTAPD_MODE_IEEE80211ANY;
+
+       for (i = 0; i < hapd->iface->num_hw_features; i++) {
+               mode = &hapd->iface->hw_features[i];
+               if (selected_mode != HOSTAPD_MODE_IEEE80211ANY &&
+                   selected_mode != mode->mode)
+                       continue;
+               hostapd_get_hw_mode_any_channels(hapd, mode, acs_ch_list_all,
+                                                &freq_list);
        }
 
        params.freq_list = freq_list;
+       params.edmg_enabled = hapd->iface->conf->enable_edmg;
 
        params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
        params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
@@ -949,7 +962,11 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd)
                        params.ch_width = 160;
        }
 
+       if (hapd->iface->conf->op_class)
+               params.ch_width = op_class_to_bandwidth(
+                       hapd->iface->conf->op_class);
        ret = hapd->driver->do_acs(hapd->drv_priv, &params);
+       os_free(freq_list);
 
        return ret;
 }