blob: afc66a5bb8c3d716cfb52e858ff82f592340964e [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From 288062b9de2d669b809ae7b0035ca4680c358192 Mon Sep 17 00:00:00 2001
2From: Shayne Chen <shayne.chen@mediatek.com>
3Date: Thu, 11 Apr 2024 18:16:38 +0800
4Subject: [PATCH 079/126] mtk: hostapd: make sure all links are set before
5 enabling beacon
6
7NL80211_CMD_NEW_BEACON will first be set, but we've modified mac80211 to
8disable this beacon. After that, hostapd will block
9NL80211_CMD_SET_BEACON until all links are setting up.
10(use NL80211_CMD_START_AP event to check if all expected links are enabled)
11
12Update: in wpa_driver_nl80211_set_ap(), send_and_recv() is used, implies
13that hostapd should already sync with driver, so don't need to use
14NL80211_CMD_START_AP event.
15
16This can make sure that the first beacon of each link includes the
17correct RNR and per-STA profile.
18
19Note that in NL80211_CMD_NEW_BEACON, we also set beacon interval to 0,
20which helps to bypass some mac80211 beacon active checks, e.g., during ACS.
21
22Add is_mld_finished check for ucode need.
23This function returns ture only if all links fromt all MLD APs are
24ready.
25
26Only after hostapd sets beacon for all links that hapd->mld->started is
27set to true. However, if the interface is about to do CAC,
28hapd->mld->started will be false until the CAC is done.
29
30For ucode, it only have to ckeck whether all link is added. Instead of
31checking hapd->mld->started, this commits check the link one by one, and
32return false if there are links unadded.
33
34Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
35Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
36---
37 hostapd/config_file.c | 2 ++
38 src/ap/ap_config.h | 2 ++
39 src/ap/beacon.c | 10 ++++++++++
40 src/ap/hostapd.c | 14 ++++++++++++++
41 src/ap/hostapd.h | 1 +
42 src/ap/ucode.c | 27 +++++++++++++++++++++++++++
43 6 files changed, 56 insertions(+)
44
45diff --git a/hostapd/config_file.c b/hostapd/config_file.c
46index 44615c564..206055b75 100644
47--- a/hostapd/config_file.c
48+++ b/hostapd/config_file.c
49@@ -5467,6 +5467,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
50 bss->mld_ap = !!atoi(pos);
51 } else if (os_strcmp(buf, "mld_primary") == 0) {
52 bss->mld_primary = !!atoi(pos);
53+ } else if (os_strcmp(buf, "mld_allowed_links") == 0) {
54+ bss->mld_allowed_links = atoi(pos);
55 } else if (os_strcmp(buf, "mld_addr") == 0) {
56 if (hwaddr_aton(pos, bss->mld_addr)) {
57 wpa_printf(MSG_ERROR, "Line %d: Invalid mld_addr",
58diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
59index 417b1d630..15b66ca30 100644
60--- a/src/ap/ap_config.h
61+++ b/src/ap/ap_config.h
62@@ -989,6 +989,8 @@ struct hostapd_bss_config {
63
64 /* The AP is the primary AP of an AP MLD */
65 u8 mld_primary;
66+ /* Allowed link bitmap of the AP MLD to which the AP is affiliated */
67+ u16 mld_allowed_links;
68
69 /* The MLD ID to which the AP MLD is affiliated with */
70 u8 mld_id;
71diff --git a/src/ap/beacon.c b/src/ap/beacon.c
72index 9bf73747f..88e35acc2 100644
73--- a/src/ap/beacon.c
74+++ b/src/ap/beacon.c
75@@ -2276,6 +2276,12 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
76 os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
77 head->u.beacon.beacon_int =
78 host_to_le16(hapd->iconf->beacon_int);
79+ /* if MLD AP hasn't finished setting up all links, also set beacon interval
80+ * to 0. This allows mac80211 to bypass some beacon active checks, for
81+ * example, when doing ACS
82+ */
83+ if (hapd->conf->mld_ap && !hapd->mld->started)
84+ head->u.beacon.beacon_int = host_to_le16(0);
85
86 /* hardware or low-level driver will setup seq_ctrl and timestamp */
87 capab_info = hostapd_own_capab_info(hapd);
88@@ -2677,6 +2683,10 @@ static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
89 int res, ret = -1, i;
90 struct hostapd_hw_modes *mode;
91
92+ /* skip setting beacon if other links are not started yet */
93+ if (hapd->conf->mld_ap && !hapd->mld->started && hapd->beacon_set_done)
94+ return 0;
95+
96 if (!hapd->drv_priv) {
97 wpa_printf(MSG_ERROR, "Interface is disabled");
98 return -1;
99diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
100index f5e11d43d..fe41f1821 100644
101--- a/src/ap/hostapd.c
102+++ b/src/ap/hostapd.c
103@@ -1315,6 +1315,20 @@ static int hostapd_start_beacon(struct hostapd_data *hapd,
104 if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0)
105 return -1;
106
107+ if (hapd->conf->mld_ap && !hapd->mld->started) {
108+ struct hostapd_data *p_hapd;
109+ u16 valid_links = 0;
110+
111+ for_each_mld_link(p_hapd, hapd)
112+ valid_links |= BIT(p_hapd->mld_link_id);
113+
114+ if (valid_links == hapd->conf->mld_allowed_links ||
115+ !hapd->conf->mld_allowed_links) {
116+ hapd->mld->started = 1;
117+ ieee802_11_set_beacon(hapd);
118+ }
119+ }
120+
121 if (flush_old_stations && !conf->start_disabled &&
122 conf->broadcast_deauth) {
123 u8 addr[ETH_ALEN];
124diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
125index 574a5ba1d..4db67096b 100644
126--- a/src/ap/hostapd.h
127+++ b/src/ap/hostapd.h
128@@ -544,6 +544,7 @@ struct hostapd_mld {
129 * freed when num_links is 0.
130 */
131 u8 refcount;
132+ bool started;
133
134 struct hostapd_data *fbss;
135 struct dl_list links; /* List head of all affiliated links */
136diff --git a/src/ap/ucode.c b/src/ap/ucode.c
137index 68f76dbe5..da1c4c1ac 100644
138--- a/src/ap/ucode.c
139+++ b/src/ap/ucode.c
140@@ -744,6 +744,32 @@ uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs)
141 return ucv_boolean_new(!ret);
142 }
143
144+static uc_value_t *
145+uc_hostapd_iface_is_mld_finished(uc_vm_t *vm, size_t nargs)
146+{
147+ struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
148+ bool finished = true;
149+ int i;
150+
151+ for (i = 0; i < iface->num_bss; i++) {
152+ if (iface->bss[i]->conf->mld_ap) {
153+ struct hostapd_data *p_hapd;
154+ u16 valid_links = 0;
155+
156+ for_each_mld_link(p_hapd, iface->bss[i])
157+ valid_links |= BIT(p_hapd->mld_link_id);
158+
159+ if (iface->bss[i]->conf->mld_allowed_links > 0 &&
160+ valid_links != iface->bss[i]->conf->mld_allowed_links) {
161+ finished = false;
162+ break;
163+ }
164+ }
165+ }
166+
167+ return ucv_boolean_new(finished);
168+}
169+
170 static uc_value_t *
171 uc_hostapd_bss_rename(uc_vm_t *vm, size_t nargs)
172 {
173@@ -816,6 +842,7 @@ int hostapd_ucode_init(struct hapd_interfaces *ifaces)
174 { "stop", uc_hostapd_iface_stop },
175 { "start", uc_hostapd_iface_start },
176 { "switch_channel", uc_hostapd_iface_switch_channel },
177+ { "is_mld_finished", uc_hostapd_iface_is_mld_finished },
178 };
179 uc_value_t *data, *proto;
180
181--
1822.18.0
183