hostapd: automatically calculate channel center freq on chan_switch
authorFelix Fietkau <nbd@nbd.name>
Mon, 7 Feb 2022 12:11:01 +0000 (13:11 +0100)
committerFelix Fietkau <nbd@nbd.name>
Mon, 7 Feb 2022 16:01:18 +0000 (17:01 +0100)
Simplifies switching to different channels when on >= VHT80

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/network/services/hostapd/src/src/ap/ubus.c

index 3c016124f99ed89f8bfd99f6cae57b9aa4693e78..5855b257941455ee6361d9e2def5ac6c2b2af873 100644 (file)
@@ -11,6 +11,7 @@
 #include "utils/eloop.h"
 #include "utils/wpabuf.h"
 #include "common/ieee802_11_defs.h"
+#include "common/hw_features_common.h"
 #include "hostapd.h"
 #include "neighbor_db.h"
 #include "wps_hostapd.h"
@@ -22,6 +23,7 @@
 #include "wnm_ap.h"
 #include "taxonomy.h"
 #include "airtime_policy.h"
+#include "hw_features.h"
 
 static struct ubus_context *ctx;
 static struct blob_buf b;
@@ -801,6 +803,7 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj,
        struct hostapd_data *hapd = get_hapd_from_object(obj);
        struct hostapd_config *iconf = hapd->iface->conf;
        struct hostapd_freq_params *freq_params;
+       struct hostapd_hw_modes *mode = hapd->iface->current_mode;
        struct csa_settings css = {
                .freq_params = {
                        .ht_enabled = iconf->ieee80211n,
@@ -809,6 +812,8 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj,
                        .sec_channel_offset = iconf->secondary_channel,
                }
        };
+       u8 chwidth = hostapd_get_oper_chwidth(iconf);
+       u8 seg0 = 0, seg1 = 0;
        int ret = UBUS_STATUS_OK;
        int i;
 
@@ -850,6 +855,35 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj,
        SET_CSA_SETTING(CSA_HE, freq_params.he_enabled, bool);
        SET_CSA_SETTING(CSA_BLOCK_TX, block_tx, bool);
 
+       css.freq_params.channel = hostapd_hw_get_channel(hapd, css.freq_params.freq);
+       if (!css.freq_params.channel)
+               return UBUS_STATUS_NOT_SUPPORTED;
+
+       switch (css.freq_params.bandwidth) {
+       case 160:
+               chwidth = CHANWIDTH_160MHZ;
+               break;
+       case 80:
+               chwidth = css.freq_params.center_freq2 ? CHANWIDTH_80P80MHZ : CHANWIDTH_80MHZ;
+               break;
+       default:
+               chwidth = CHANWIDTH_USE_HT;
+               break;
+       }
+
+       hostapd_set_freq_params(&css.freq_params, iconf->hw_mode,
+                               css.freq_params.freq,
+                               css.freq_params.channel, iconf->enable_edmg,
+                               iconf->edmg_channel,
+                               css.freq_params.ht_enabled,
+                               css.freq_params.vht_enabled,
+                               css.freq_params.he_enabled,
+                               css.freq_params.sec_channel_offset,
+                               chwidth, seg0, seg1,
+                               iconf->vht_capab,
+                               mode ? &mode->he_capab[IEEE80211_MODE_AP] :
+                               NULL);
+
        for (i = 0; i < hapd->iface->num_bss; i++) {
                struct hostapd_data *bss = hapd->iface->bss[i];