]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Fix CHAN_SWITCH command for VHT20 and VHT40
authorSathishkumar Muruganandam <murugana@codeaurora.org>
Mon, 7 May 2018 10:27:18 +0000 (15:57 +0530)
committerJouni Malinen <j@w1.fi>
Tue, 15 May 2018 22:16:54 +0000 (01:16 +0300)
Previously, hostapd CHAN_SWITCH command did not effect VHT configuration
for the following:

When VHT is currently disabled (ieee80211ac=0),

1. hostapd_cli -p /var/run/hostapd chan_switch 10 5180 \
                sec_channel_offset=1 center_freq1=5190 bandwidth=40 ht

====> Comes up in HT40

2. hostapd_cli -p /var/run/hostapd chan_switch 10 5765 \
                sec_channel_offset=-1 center_freq1=5775 bandwidth=40 vht

====> Comes up in HT40

3. hostapd_cli -p /var/run/hostapd chan_switch 10 5200 center_freq1=5200 \
                                                  bandwidth=20 vht

====> Comes up in HT20

When VHT is currently enabled (ieee80211ac=1),

1. hostapd_cli -p /var/run/hostapd chan_switch 10 5180 \
                sec_channel_offset=1 center_freq1=5190 bandwidth=40 ht

====> Comes up in VHT40

2. hostapd_cli -p /var/run/hostapd chan_switch 10 5200 center_freq1=5200 \
                                                  bandwidth=20 ht

====> Comes up in VHT20

This is since VHT config from chan_switch is processed only for
bandwidths 80 and above (80P80, 160) and for VHT20, VHT40 cases, only
NLA chan type and chan width are updated.

There is no NL attribute for determining if it is HT or VHT for
bandwidths 20 & 40 and currently they are updated as HT20, HT40 (+ or -
depending on offset). Same is notified back via
NL80211_CMD_CH_SWITCH_NOTIFY.

Instead of adding new NL attribute for tracking HT/VHT enabled config,
we are adding new hostapd VHT config parameter to save the chan_switch
config and use only for chan_switch case of VHT20 and VHT40.

Tested with all combinations of chan_switch (noHT->20->40->80->) HT/VHT
and confirmed to be working.

Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
hostapd/ctrl_iface.c
src/ap/ap_config.h
src/ap/drv_callbacks.c
src/ap/hostapd.c
src/ap/hostapd.h

index e8b1810e17a7fbdf0842bb2708a93fb8d296df39..cef2976bd5345b18bcfe34f187399101ad0fad5f 100644 (file)
@@ -2222,6 +2222,11 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
                return ret;
 
        for (i = 0; i < iface->num_bss; i++) {
+
+               /* Save CHAN_SWITCH VHT config */
+               hostapd_chan_switch_vht_config(
+                       iface->bss[i], settings.freq_params.vht_enabled);
+
                ret = hostapd_switch_channel(iface->bss[i], &settings);
                if (ret) {
                        /* FIX: What do we do if CSA fails in the middle of
index 35ccd21e60690b51443a861d0a8ed82396ed6ded..bc6489a84497374b90e10c138cf242e21c955f36 100644 (file)
@@ -818,6 +818,11 @@ struct hostapd_config {
        struct he_phy_capabilities_info he_phy_capab;
        struct he_operation he_op;
 #endif /* CONFIG_IEEE80211AX */
+
+       /* VHT enable/disable config from CHAN_SWITCH */
+#define CH_SWITCH_VHT_ENABLED BIT(0)
+#define CH_SWITCH_VHT_DISABLED BIT(1)
+       unsigned int ch_switch_vht_config;
 };
 
 
index c5fd15e0620ecf9ba5d678b7cb080edeb7fcd21f..79fcd9ca1c9ffdb4c9075c05255f394f068f2b13 100644 (file)
@@ -737,9 +737,9 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
 
        hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
                       HOSTAPD_LEVEL_INFO,
-                      "driver had channel switch: freq=%d, ht=%d, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
-                      freq, ht, offset, width, channel_width_to_string(width),
-                      cf1, cf2);
+                      "driver had channel switch: freq=%d, ht=%d, vht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
+                      freq, ht, hapd->iconf->ch_switch_vht_config, offset,
+                      width, channel_width_to_string(width), cf1, cf2);
 
        hapd->iface->freq = freq;
 
@@ -784,8 +784,19 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
 
        hapd->iconf->channel = channel;
        hapd->iconf->ieee80211n = ht;
-       if (!ht)
+       if (!ht) {
                hapd->iconf->ieee80211ac = 0;
+       } else if (hapd->iconf->ch_switch_vht_config) {
+               /* CHAN_SWITCH VHT config */
+               if (hapd->iconf->ch_switch_vht_config &
+                   CH_SWITCH_VHT_ENABLED)
+                       hapd->iconf->ieee80211ac = 1;
+               else if (hapd->iconf->ch_switch_vht_config &
+                        CH_SWITCH_VHT_DISABLED)
+                       hapd->iconf->ieee80211ac = 0;
+       }
+       hapd->iconf->ch_switch_vht_config = 0;
+
        hapd->iconf->secondary_channel = offset;
        hapd->iconf->vht_oper_chwidth = chwidth;
        hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx;
index 49cceb88b6ba9dd40b5b695216af058f230f48cc..42e82cdec5327ec518031fdb14c386a8c2dc30b6 100644 (file)
@@ -3370,6 +3370,19 @@ void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
 }
 
 
+void hostapd_chan_switch_vht_config(struct hostapd_data *hapd, int vht_enabled)
+{
+       if (vht_enabled)
+               hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_ENABLED;
+       else
+               hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_DISABLED;
+
+       hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
+                      HOSTAPD_LEVEL_INFO, "CHAN_SWITCH VHT CONFIG 0x%x",
+                      hapd->iconf->ch_switch_vht_config);
+}
+
+
 int hostapd_switch_channel(struct hostapd_data *hapd,
                           struct csa_settings *settings)
 {
index 7743acf257fd4c1b3fce30ee36f0c5c5dbb8b223..4129120f3e783fd57130bd7829ed48142bcefc09 100644 (file)
@@ -564,6 +564,7 @@ void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator);
 void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s);
 const char * hostapd_state_text(enum hostapd_iface_state s);
 int hostapd_csa_in_progress(struct hostapd_iface *iface);
+void hostapd_chan_switch_vht_config(struct hostapd_data *hapd, int vht_enabled);
 int hostapd_switch_channel(struct hostapd_data *hapd,
                           struct csa_settings *settings);
 void