diff mbox series

[3/4] hostapd_reload_config: allow update of mode and frequency

Message ID 20230329134455.4019868-4-raphael.melotte@mind.be
State Changes Requested
Headers show
Series hostapd: add support for AP+STA on the same radio | expand

Commit Message

Raphaël Mélotte March 29, 2023, 1:44 p.m. UTC
From: Felix Fietkau <nbd@nbd.name>

In commit 513dcec6562948e9f2dc3348923833c8d659eaf2,
hostapd_reload_config was changed to no longer reload the channel
information. However, we really do want to be able to switch channels,
change mode, etc. when changing the configuration. Therefore, revert
that commit. Instead, make sure that the changed mode and channel is
correctly taken into account.

Use hostapd_set_freq to update the internal data structures and the
driver. Use hostapd_hw_get_freq to get the frequency from the selected
mode and channel.

The new frequency may also be in another band. Update the current_mode
structure based on the configured hw_mode and prepare rates table after
frequency selection.

Signed-off-by: Felix Fietkau <nbd@nbd.name> [cleanup, patch refresh]
[Abhilash Tuse: add support for switching bands]
Signed-off-by: Abhilash Tuse <Abhilash.Tuse@imgtec.com>
[Arnout: add commit message, adapt to current mainline]
Signed-off-by: Arnout Vandecappelle <arnout@mind.be>
---
 src/ap/hostapd.c | 50 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 35 insertions(+), 15 deletions(-)
diff mbox series

Patch

diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 141c77f4b..cd9d1e6f0 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -142,6 +142,29 @@  static void hostapd_reload_bss(struct hostapd_data *hapd)
 #endif /* CONFIG_NO_RADIUS */
 
 	ssid = &hapd->conf->ssid;
+
+	hostapd_set_freq(hapd, hapd->iconf->hw_mode, hapd->iface->freq,
+			 hapd->iconf->channel,
+			 hapd->iconf->enable_edmg,
+			 hapd->iconf->edmg_channel,
+			 hapd->iconf->ieee80211n,
+			 hapd->iconf->ieee80211ac,
+			 hapd->iconf->ieee80211ax,
+			 hapd->iconf->ieee80211be,
+			 hapd->iconf->secondary_channel,
+			 hostapd_get_oper_chwidth(hapd->iconf),
+			 hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf),
+			 hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf));
+
+	if (hapd->iface->current_mode) {
+		if (hostapd_prepare_rates(hapd->iface, hapd->iface->current_mode)) {
+			wpa_printf(MSG_ERROR, "Failed to prepare rates table.");
+			hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
+				       HOSTAPD_LEVEL_WARNING,
+				       "Failed to prepare rates table.");
+		}
+	}
+
 	if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next &&
 	    ssid->wpa_passphrase_set && ssid->wpa_passphrase) {
 		/*
@@ -250,6 +273,7 @@  int hostapd_reload_config(struct hostapd_iface *iface)
 	struct hostapd_data *hapd = iface->bss[0];
 	struct hostapd_config *newconf, *oldconf;
 	size_t j;
+	int i;
 
 	if (iface->config_fname == NULL) {
 		/* Only in-memory config in use - assume it has been updated */
@@ -300,6 +324,17 @@  int hostapd_reload_config(struct hostapd_iface *iface)
 	}
 	iface->conf = newconf;
 
+	for (i = 0; i < iface->num_hw_features; i++) {
+		struct hostapd_hw_modes *mode = &iface->hw_features[i];
+		if (mode->mode == iface->conf->hw_mode) {
+			iface->current_mode = mode;
+			break;
+		}
+	}
+
+	if (iface->conf->channel)
+		iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel);
+
 	for (j = 0; j < iface->num_bss; j++) {
 		hapd = iface->bss[j];
 		if (!hapd->conf->config_id || !newconf->bss[j]->config_id ||
@@ -307,21 +342,6 @@  int hostapd_reload_config(struct hostapd_iface *iface)
 			      newconf->bss[j]->config_id) != 0)
 			hostapd_clear_old_bss(hapd);
 		hapd->iconf = newconf;
-		hapd->iconf->channel = oldconf->channel;
-		hapd->iconf->acs = oldconf->acs;
-		hapd->iconf->secondary_channel = oldconf->secondary_channel;
-		hapd->iconf->ieee80211n = oldconf->ieee80211n;
-		hapd->iconf->ieee80211ac = oldconf->ieee80211ac;
-		hapd->iconf->ht_capab = oldconf->ht_capab;
-		hapd->iconf->vht_capab = oldconf->vht_capab;
-		hostapd_set_oper_chwidth(hapd->iconf,
-					 hostapd_get_oper_chwidth(oldconf));
-		hostapd_set_oper_centr_freq_seg0_idx(
-			hapd->iconf,
-			hostapd_get_oper_centr_freq_seg0_idx(oldconf));
-		hostapd_set_oper_centr_freq_seg1_idx(
-			hapd->iconf,
-			hostapd_get_oper_centr_freq_seg1_idx(oldconf));
 		hapd->conf = newconf->bss[j];
 		hostapd_reload_bss(hapd);
 	}