| From ec7d47b2566da59c52d995f5e404a1c00e746fe5 Mon Sep 17 00:00:00 2001 |
| From: Shayne Chen <shayne.chen@mediatek.com> |
| Date: Thu, 11 Apr 2024 18:16:38 +0800 |
| Subject: [PATCH 103/104] mtk: hostapd: make sure all links are set before |
| enabling beacon |
| |
| NL80211_CMD_NEW_BEACON will first be set, but we've modified mac80211 to |
| disable this beacon. After that, hostapd will block |
| NL80211_CMD_SET_BEACON until all links are setting up. |
| (use NL80211_CMD_START_AP event to check if all expected links are enabled) |
| |
| Update: in wpa_driver_nl80211_set_ap(), send_and_recv() is used, implies |
| that hostapd should already sync with driver, so don't need to use |
| NL80211_CMD_START_AP event. |
| |
| This can make sure that the first beacon of each link includes the |
| correct RNR and per-STA profile. |
| |
| Note that in NL80211_CMD_NEW_BEACON, we also set beacon interval to 0, |
| which helps to bypass some mac80211 beacon active checks, e.g., during ACS. |
| |
| CR-Id: WCNCR00238098 |
| Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> |
| Change-Id: I99320f7802041dc7d8e780041bb686ce3700c0b6 |
| --- |
| hostapd/config_file.c | 2 ++ |
| src/ap/ap_config.h | 2 ++ |
| src/ap/beacon.c | 10 ++++++++++ |
| src/ap/hostapd.c | 14 ++++++++++++++ |
| src/ap/hostapd.h | 1 + |
| 5 files changed, 29 insertions(+) |
| |
| diff --git a/hostapd/config_file.c b/hostapd/config_file.c |
| index 2add62ca9..8abe1bc46 100644 |
| --- a/hostapd/config_file.c |
| +++ b/hostapd/config_file.c |
| @@ -5354,6 +5354,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| bss->mld_ap = !!atoi(pos); |
| } else if (os_strcmp(buf, "mld_primary") == 0) { |
| bss->mld_primary = !!atoi(pos); |
| + } else if (os_strcmp(buf, "mld_allowed_links") == 0) { |
| + bss->mld_allowed_links = atoi(pos); |
| } else if (os_strcmp(buf, "mld_addr") == 0) { |
| if (hwaddr_aton(pos, bss->mld_addr)) { |
| wpa_printf(MSG_ERROR, "Line %d: Invalid mld_addr", |
| diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h |
| index 5192c1f07..0ea5a04e2 100644 |
| --- a/src/ap/ap_config.h |
| +++ b/src/ap/ap_config.h |
| @@ -968,6 +968,8 @@ struct hostapd_bss_config { |
| |
| /* The AP is the primary AP of an AP MLD */ |
| u8 mld_primary; |
| + /* Allowed link bitmap of the AP MLD to which the AP is affiliated */ |
| + u16 mld_allowed_links; |
| |
| /* The MLD ID to which the AP MLD is affiliated with */ |
| u8 mld_id; |
| diff --git a/src/ap/beacon.c b/src/ap/beacon.c |
| index a5c46b067..a5c9dd87e 100644 |
| --- a/src/ap/beacon.c |
| +++ b/src/ap/beacon.c |
| @@ -2164,6 +2164,12 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, |
| os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN); |
| head->u.beacon.beacon_int = |
| host_to_le16(hapd->iconf->beacon_int); |
| + /* if MLD AP hasn't finished setting up all links, also set beacon interval |
| + * to 0. This allows mac80211 to bypass some beacon active checks, for |
| + * example, when doing ACS |
| + */ |
| + if (hapd->conf->mld_ap && !hapd->mld->started) |
| + head->u.beacon.beacon_int = host_to_le16(0); |
| |
| /* hardware or low-level driver will setup seq_ctrl and timestamp */ |
| capab_info = hostapd_own_capab_info(hapd); |
| @@ -2553,6 +2559,10 @@ static int __ieee802_11_set_beacon(struct hostapd_data *hapd) |
| int res, ret = -1, i; |
| struct hostapd_hw_modes *mode; |
| |
| + /* skip setting beacon if other links are not started yet */ |
| + if (hapd->conf->mld_ap && !hapd->mld->started && hapd->beacon_set_done) |
| + return 0; |
| + |
| if (!hapd->drv_priv) { |
| wpa_printf(MSG_ERROR, "Interface is disabled"); |
| return -1; |
| diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c |
| index 3d3359291..c31e0badd 100644 |
| --- a/src/ap/hostapd.c |
| +++ b/src/ap/hostapd.c |
| @@ -1314,6 +1314,20 @@ static int hostapd_start_beacon(struct hostapd_data *hapd, |
| if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0) |
| return -1; |
| |
| + if (hapd->conf->mld_ap && !hapd->mld->started) { |
| + struct hostapd_data *p_hapd; |
| + u16 valid_links = 0; |
| + |
| + for_each_mld_link(p_hapd, hapd) |
| + valid_links |= BIT(p_hapd->mld_link_id); |
| + |
| + if (valid_links == hapd->conf->mld_allowed_links || |
| + !hapd->conf->mld_allowed_links) { |
| + hapd->mld->started = 1; |
| + ieee802_11_set_beacon(hapd); |
| + } |
| + } |
| + |
| if (flush_old_stations && !conf->start_disabled && |
| conf->broadcast_deauth) { |
| u8 addr[ETH_ALEN]; |
| diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h |
| index 5b37be87b..83636649f 100644 |
| --- a/src/ap/hostapd.h |
| +++ b/src/ap/hostapd.h |
| @@ -537,6 +537,7 @@ struct hostapd_mld { |
| * freed when num_links is 0. |
| */ |
| u8 refcount; |
| + bool started; |
| |
| struct hostapd_data *fbss; |
| struct dl_list links; /* List head of all affiliated links */ |
| -- |
| 2.39.2 |
| |