]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DFS: Introduce hostapd_dfs_request_channel_switch()
authorLorenzo Bianconi <lorenzo@kernel.org>
Sun, 6 Mar 2022 19:34:12 +0000 (20:34 +0100)
committerJouni Malinen <j@w1.fi>
Sun, 13 Mar 2022 19:12:43 +0000 (21:12 +0200)
This is a preliminary patch to add Channel Switch Announcement for
background radar detection.

Tested-by: Owen Peng <owen.peng@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
src/ap/dfs.c

index b221825a4416963b304d22142333c14b58a22a4a..a58ad2dab3617e26264092ceaa53b2479d71fb0e 100644 (file)
@@ -943,6 +943,90 @@ int hostapd_is_dfs_chan_available(struct hostapd_iface *iface)
 }
 
 
+static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,
+                                             int channel, int freq,
+                                             int secondary_channel,
+                                             u8 current_vht_oper_chwidth,
+                                             u8 oper_centr_freq_seg0_idx,
+                                             u8 oper_centr_freq_seg1_idx)
+{
+       struct hostapd_hw_modes *cmode = iface->current_mode;
+       int ieee80211_mode = IEEE80211_MODE_AP, err;
+       struct csa_settings csa_settings;
+       u8 new_vht_oper_chwidth;
+       unsigned int i;
+
+       wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", channel);
+       wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
+               "freq=%d chan=%d sec_chan=%d", freq, channel,
+               secondary_channel);
+
+       new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
+       hostapd_set_oper_chwidth(iface->conf, current_vht_oper_chwidth);
+
+       /* Setup CSA request */
+       os_memset(&csa_settings, 0, sizeof(csa_settings));
+       csa_settings.cs_count = 5;
+       csa_settings.block_tx = 1;
+#ifdef CONFIG_MESH
+       if (iface->mconf)
+               ieee80211_mode = IEEE80211_MODE_MESH;
+#endif /* CONFIG_MESH */
+       err = hostapd_set_freq_params(&csa_settings.freq_params,
+                                     iface->conf->hw_mode,
+                                     freq, channel,
+                                     iface->conf->enable_edmg,
+                                     iface->conf->edmg_channel,
+                                     iface->conf->ieee80211n,
+                                     iface->conf->ieee80211ac,
+                                     iface->conf->ieee80211ax,
+                                     secondary_channel,
+                                     new_vht_oper_chwidth,
+                                     oper_centr_freq_seg0_idx,
+                                     oper_centr_freq_seg1_idx,
+                                     cmode->vht_capab,
+                                     &cmode->he_capab[ieee80211_mode]);
+
+       if (err) {
+               wpa_printf(MSG_ERROR,
+                          "DFS failed to calculate CSA freq params");
+               hostapd_disable_iface(iface);
+               return err;
+       }
+
+       for (i = 0; i < iface->num_bss; i++) {
+               err = hostapd_switch_channel(iface->bss[i], &csa_settings);
+               if (err)
+                       break;
+       }
+
+       if (err) {
+               wpa_printf(MSG_WARNING,
+                          "DFS failed to schedule CSA (%d) - trying fallback",
+                          err);
+               iface->freq = freq;
+               iface->conf->channel = channel;
+               iface->conf->secondary_channel = secondary_channel;
+               hostapd_set_oper_chwidth(iface->conf, new_vht_oper_chwidth);
+               hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
+                                                    oper_centr_freq_seg0_idx);
+               hostapd_set_oper_centr_freq_seg1_idx(iface->conf,
+                                                    oper_centr_freq_seg1_idx);
+
+               hostapd_disable_iface(iface);
+               hostapd_enable_iface(iface);
+
+               return 0;
+       }
+
+       /* Channel configuration will be updated once CSA completes and
+        * ch_switch_notify event is received */
+       wpa_printf(MSG_DEBUG, "DFS waiting channel switch event");
+
+       return 0;
+}
+
+
 static void hostpad_dfs_update_background_chain(struct hostapd_iface *iface)
 {
        int sec = 0;
@@ -1195,14 +1279,8 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
        int secondary_channel;
        u8 oper_centr_freq_seg0_idx;
        u8 oper_centr_freq_seg1_idx;
-       u8 new_vht_oper_chwidth;
        enum dfs_channel_type channel_type = DFS_AVAILABLE;
-       struct csa_settings csa_settings;
-       unsigned int i;
-       int err = 1;
-       struct hostapd_hw_modes *cmode = iface->current_mode;
        u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
-       int ieee80211_mode = IEEE80211_MODE_AP;
 
        wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
                   __func__, iface->cac_started ? "yes" : "no",
@@ -1265,73 +1343,12 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
                }
        }
 
-       wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
-                  channel->chan);
-       wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
-               "freq=%d chan=%d sec_chan=%d", channel->freq,
-               channel->chan, secondary_channel);
-
-       new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
-       hostapd_set_oper_chwidth(iface->conf, current_vht_oper_chwidth);
-
-       /* Setup CSA request */
-       os_memset(&csa_settings, 0, sizeof(csa_settings));
-       csa_settings.cs_count = 5;
-       csa_settings.block_tx = 1;
-#ifdef CONFIG_MESH
-       if (iface->mconf)
-               ieee80211_mode = IEEE80211_MODE_MESH;
-#endif /* CONFIG_MESH */
-       err = hostapd_set_freq_params(&csa_settings.freq_params,
-                                     iface->conf->hw_mode,
-                                     channel->freq,
-                                     channel->chan,
-                                     iface->conf->enable_edmg,
-                                     iface->conf->edmg_channel,
-                                     iface->conf->ieee80211n,
-                                     iface->conf->ieee80211ac,
-                                     iface->conf->ieee80211ax,
-                                     secondary_channel,
-                                     new_vht_oper_chwidth,
-                                     oper_centr_freq_seg0_idx,
-                                     oper_centr_freq_seg1_idx,
-                                     cmode->vht_capab,
-                                     &cmode->he_capab[ieee80211_mode]);
-
-       if (err) {
-               wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
-               hostapd_disable_iface(iface);
-               return err;
-       }
-
-       for (i = 0; i < iface->num_bss; i++) {
-               err = hostapd_switch_channel(iface->bss[i], &csa_settings);
-               if (err)
-                       break;
-       }
-
-       if (err) {
-               wpa_printf(MSG_WARNING, "DFS failed to schedule CSA (%d) - trying fallback",
-                          err);
-               iface->freq = channel->freq;
-               iface->conf->channel = channel->chan;
-               iface->conf->secondary_channel = secondary_channel;
-               hostapd_set_oper_chwidth(iface->conf, new_vht_oper_chwidth);
-               hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
-                                                    oper_centr_freq_seg0_idx);
-               hostapd_set_oper_centr_freq_seg1_idx(iface->conf,
-                                                    oper_centr_freq_seg1_idx);
-
-               hostapd_disable_iface(iface);
-               hostapd_enable_iface(iface);
-               return 0;
-       }
-
-       /* Channel configuration will be updated once CSA completes and
-        * ch_switch_notify event is received */
-
-       wpa_printf(MSG_DEBUG, "DFS waiting channel switch event");
-       return 0;
+       return hostapd_dfs_request_channel_switch(iface, channel->chan,
+                                                 channel->freq,
+                                                 secondary_channel,
+                                                 current_vht_oper_chwidth,
+                                                 oper_centr_freq_seg0_idx,
+                                                 oper_centr_freq_seg1_idx);
 }