blob: 56149a418053c18d4702f3bd53d7292f91912c5d [file] [log] [blame]
developer66e89bc2024-04-23 14:50:01 +08001From 235a6041bde6ce30da6e631b901260dec5fadcda Mon Sep 17 00:00:00 2001
2From: mtk27835 <shurong.wen@mediatek.com>
3Date: Wed, 7 Sep 2022 14:41:51 -0700
4Subject: [PATCH 036/104] mtk: hostapd: Add hostapd iBF control
5
6Signed-off-by: mtk27835 <shurong.wen@mediatek.com>
7---
8 hostapd/config_file.c | 3 +
9 hostapd/ctrl_iface.c | 26 +++++++
10 hostapd/hostapd_cli.c | 9 +++
11 src/ap/ap_config.c | 1 +
12 src/ap/ap_config.h | 2 +
13 src/ap/ap_drv_ops.c | 14 ++++
14 src/ap/ap_drv_ops.h | 2 +
15 src/ap/hostapd.c | 2 +
16 src/common/mtk_vendor.h | 35 +++++++++-
17 src/drivers/driver.h | 19 ++++++
18 src/drivers/driver_nl80211.c | 108 ++++++++++++++++++++++++++++++
19 src/drivers/driver_nl80211.h | 1 +
20 src/drivers/driver_nl80211_capa.c | 3 +
21 13 files changed, 224 insertions(+), 1 deletion(-)
22
23diff --git a/hostapd/config_file.c b/hostapd/config_file.c
24index 3d9923692..247d68811 100644
25--- a/hostapd/config_file.c
26+++ b/hostapd/config_file.c
27@@ -5395,6 +5395,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
28 u8 en = atoi(pos);
29
30 conf->three_wire_enable = en;
31+ } else if (os_strcmp(buf, "ibf_enable") == 0) { /*ibf setting is per device*/
32+ int val = atoi(pos);
33+ conf->ibf_enable = !!val;
34 } else {
35 wpa_printf(MSG_ERROR,
36 "Line %d: unknown configuration item '%s'",
37diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
38index 3a79a1284..10bbce341 100644
39--- a/hostapd/ctrl_iface.c
40+++ b/hostapd/ctrl_iface.c
41@@ -4110,6 +4110,30 @@ hostapd_ctrl_iface_get_mu(struct hostapd_data *hapd, char *buf,
42 }
43
44
45+static int
46+hostapd_ctrl_iface_get_ibf(struct hostapd_data *hapd, char *buf,
47+ size_t buflen)
48+{
49+ u8 ibf_enable;
50+ int ret;
51+ char *pos, *end;
52+
53+ pos = buf;
54+ end = buf + buflen;
55+
56+ if (hostapd_drv_ibf_dump(hapd, &ibf_enable) == 0) {
57+ hapd->iconf->ibf_enable = ibf_enable;
58+ ret = os_snprintf(pos, end - pos, "ibf_enable: %u\n",
59+ ibf_enable);
60+ }
61+
62+ if (os_snprintf_error(end - pos, ret))
63+ return 0;
64+
65+ return ret;
66+}
67+
68+
69 static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
70 char *buf, char *reply,
71 int reply_size,
72@@ -4721,6 +4745,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
73 reply_size);
74 } else if (os_strncmp(buf, "GET_MU", 6) == 0) {
75 reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
76+ } else if (os_strncmp(buf, "GET_IBF", 7) == 0) {
77+ reply_len = hostapd_ctrl_iface_get_ibf(hapd, reply, reply_size);
78 } else {
79 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
80 reply_len = 16;
81diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
82index da9dabd6f..276ca578c 100644
83--- a/hostapd/hostapd_cli.c
84+++ b/hostapd/hostapd_cli.c
85@@ -1666,6 +1666,13 @@ static int hostapd_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
86 #endif /* ANDROID */
87
88
89+static int hostapd_cli_cmd_get_ibf(struct wpa_ctrl *ctrl, int argc,
90+ char *argv[])
91+{
92+ return hostapd_cli_cmd(ctrl, "GET_IBF", 0, NULL, NULL);
93+}
94+
95+
96 struct hostapd_cli_cmd {
97 const char *cmd;
98 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
99@@ -1889,6 +1896,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
100 #endif /* ANDROID */
101 { "inband_discovery", hostapd_cli_cmd_inband_discovery, NULL,
102 "<tx type(0/1/2)> <interval> = runtime set inband discovery" },
103+ { "get_ibf", hostapd_cli_cmd_get_ibf, NULL,
104+ " = show iBF state (enabled/disabled)"},
105 { NULL, NULL, NULL, NULL }
106 };
107
108diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
109index 79fd3a24b..04e263167 100644
110--- a/src/ap/ap_config.c
111+++ b/src/ap/ap_config.c
112@@ -307,6 +307,7 @@ struct hostapd_config * hostapd_config_defaults(void)
113 conf->edcca_enable = EDCCA_MODE_AUTO;
114 conf->edcca_compensation = EDCCA_DEFAULT_COMPENSATION;
115 conf->three_wire_enable = THREE_WIRE_MODE_DISABLE;
116+ conf->ibf_enable = IBF_DEFAULT_ENABLE;
117
118 hostapd_set_and_check_bw320_offset(conf, 0);
119
120diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
121index d1bbd238c..5f084796d 100644
122--- a/src/ap/ap_config.h
123+++ b/src/ap/ap_config.h
124@@ -1287,6 +1287,7 @@ struct hostapd_config {
125 s8 edcca_compensation;
126 int *edcca_threshold;
127 u8 three_wire_enable;
128+ u8 ibf_enable;
129 };
130
131 enum three_wire_mode {
132@@ -1450,6 +1451,7 @@ hostapd_set_and_check_bw320_offset(struct hostapd_config *conf,
133 #endif /* CONFIG_IEEE80211BE */
134 }
135
136+#define IBF_DEFAULT_ENABLE 0
137
138 int hostapd_mac_comp(const void *a, const void *b);
139 struct hostapd_config * hostapd_config_defaults(void);
140diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
141index 587b8f37f..3cace58e5 100644
142--- a/src/ap/ap_drv_ops.c
143+++ b/src/ap/ap_drv_ops.c
144@@ -1294,3 +1294,17 @@ int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd)
145 }
146 return hapd->driver->three_wire_ctrl(hapd->drv_priv, hapd->iconf->three_wire_enable);
147 }
148+
149+int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd)
150+{
151+ if (!hapd->driver || !hapd->driver->ibf_ctrl)
152+ return 0;
153+ return hapd->driver->ibf_ctrl(hapd->drv_priv, hapd->iconf->ibf_enable);
154+}
155+
156+int hostapd_drv_ibf_dump(struct hostapd_data *hapd, u8 *ibf_enable)
157+{
158+ if (!hapd->driver || !hapd->driver->ibf_dump)
159+ return 0;
160+ return hapd->driver->ibf_dump(hapd->drv_priv, ibf_enable);
161+}
162\ No newline at end of file
163diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
164index 7448e7954..0886acb2d 100644
165--- a/src/ap/ap_drv_ops.h
166+++ b/src/ap/ap_drv_ops.h
167@@ -156,6 +156,8 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value);
168 int hostapd_drv_mu_ctrl(struct hostapd_data *hapd);
169 int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff);
170 int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd);
171+int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
172+int hostapd_drv_ibf_dump(struct hostapd_data *hapd, u8 *ibf_enable);
173
174 #include "drivers/driver.h"
175
176diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
177index 5ceb49962..1d941683f 100644
178--- a/src/ap/hostapd.c
179+++ b/src/ap/hostapd.c
180@@ -2703,6 +2703,8 @@ dfs_offload:
181 goto fail;
182 if (hostapd_drv_three_wire_ctrl(hapd) < 0)
183 goto fail;
184+ if (hostapd_drv_ibf_ctrl(hapd) < 0)
185+ goto fail;
186
187 wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
188 iface->bss[0]->conf->iface);
189diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
190index 99ecbaf71..9811f266e 100644
191--- a/src/common/mtk_vendor.h
192+++ b/src/common/mtk_vendor.h
193@@ -13,7 +13,8 @@ enum mtk_nl80211_vendor_subcmds {
194 MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
195 MTK_NL80211_VENDOR_SUBCMD_PHY_CAPA_CTRL= 0xc6,
196 MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL = 0xc7,
197- MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8
198+ MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8,
199+ MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
200 };
201
202 enum mtk_vendor_attr_edcca_ctrl {
203@@ -207,6 +208,38 @@ enum mtk_vendor_attr_mu_ctrl {
204 NUM_MTK_VENDOR_ATTRS_MU_CTRL - 1
205 };
206
207+enum mtk_vendor_attr_ibf_ctrl {
208+ MTK_VENDOR_ATTR_IBF_CTRL_UNSPEC,
209+
210+ MTK_VENDOR_ATTR_IBF_CTRL_ENABLE,
211+
212+ /* keep last */
213+ NUM_MTK_VENDOR_ATTRS_IBF_CTRL,
214+ MTK_VENDOR_ATTR_IBF_CTRL_MAX =
215+ NUM_MTK_VENDOR_ATTRS_IBF_CTRL - 1
216+};
217+
218+enum mtk_vendor_attr_ibf_dump {
219+ MTK_VENDOR_ATTR_IBF_DUMP_UNSPEC,
220+
221+ MTK_VENDOR_ATTR_IBF_DUMP_ENABLE,
222+
223+ /* keep last */
224+ NUM_MTK_VENDOR_ATTRS_IBF_DUMP,
225+ MTK_VENDOR_ATTR_IBF_DUMP_MAX =
226+ NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1
227+};
228+
229+static struct nla_policy
230+ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
231+ [MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
232+};
233+
234+static struct nla_policy
235+ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
236+ [MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
237+};
238+
239
240 #define CSI_MAX_COUNT 256
241 #define ETH_ALEN 6
242diff --git a/src/drivers/driver.h b/src/drivers/driver.h
243index dec4336a4..f5cff646e 100644
244--- a/src/drivers/driver.h
245+++ b/src/drivers/driver.h
246@@ -181,6 +181,11 @@ struct hostapd_channel_data {
247 * mu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
248 */
249 u8 mu_onoff;
250+
251+ /**
252+ * ibf_enable=<val>
253+ */
254+ u8 ibf_enable;
255 };
256
257 #define HE_MAC_CAPAB_0 0
258@@ -5245,6 +5250,20 @@ struct wpa_driver_ops {
259 *
260 */
261 int (*three_wire_ctrl)(void *priv, u8 three_wire_enable);
262+
263+ /**
264+ * ibf_ctrl - ctrl disable/enable for ibf
265+ * @priv: Private driver interface data
266+ *
267+ */
268+ int (*ibf_ctrl)(void *priv, u8 ibf_enable);
269+
270+ /**
271+ * ibf_dump - dump ibf
272+ * @priv: Private driver interface data
273+ *
274+ */
275+ int (*ibf_dump)(void *priv, u8 *ibf_enable);
276 };
277
278 /**
279diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
280index c9899e492..c17052f22 100644
281--- a/src/drivers/driver_nl80211.c
282+++ b/src/drivers/driver_nl80211.c
283@@ -14390,6 +14390,112 @@ static int nl80211_enable_three_wire(void *priv, const u8 three_wire_enable)
284 return ret;
285 }
286
287+static int nl80211_ibf_enable(void *priv, u8 ibf_enable)
288+{
289+ struct i802_bss *bss = priv;
290+ struct wpa_driver_nl80211_data *drv = bss->drv;
291+ struct nl_msg *msg;
292+ struct nlattr *data;
293+ int ret;
294+
295+ if (!drv->mtk_ibf_vendor_cmd_avail) {
296+ wpa_printf(MSG_INFO,
297+ "nl80211: Driver does not support setting ibf control");
298+ return 0;
299+ }
300+
301+ msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
302+ if (!msg)
303+ goto fail;
304+
305+ if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
306+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL))
307+ goto fail;
308+
309+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
310+ if (!data)
311+ goto fail;
312+
313+ nla_put_u8(msg, MTK_VENDOR_ATTR_IBF_CTRL_ENABLE, ibf_enable);
314+
315+ nla_nest_end(msg, data);
316+ ret = send_and_recv_cmd(drv, msg);
317+ if (ret) {
318+ wpa_printf(MSG_ERROR, "Failed to set ibf_enable. ret=%d (%s)", ret, strerror(-ret));
319+ }
320+
321+ return ret;
322+
323+fail:
324+ nlmsg_free(msg);
325+ return -ENOBUFS;
326+}
327+
328+static int ibf_dump_handler(struct nl_msg *msg, void *arg)
329+{
330+ u8 *ibf_enable = (u8 *) arg;
331+ struct nlattr *tb[NL80211_ATTR_MAX + 1];
332+ struct nlattr *tb_vendor[MTK_VENDOR_ATTR_IBF_DUMP_MAX + 1];
333+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
334+ struct nlattr *nl_vend, *attr;
335+
336+ nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
337+ genlmsg_attrlen(gnlh, 0), NULL);
338+
339+ nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
340+ if (!nl_vend)
341+ return NL_SKIP;
342+
343+ nla_parse(tb_vendor, MTK_VENDOR_ATTR_IBF_DUMP_MAX,
344+ nla_data(nl_vend), nla_len(nl_vend), NULL);
345+
346+ attr = tb_vendor[MTK_VENDOR_ATTR_IBF_DUMP_ENABLE];
347+ if (!attr) {
348+ wpa_printf(MSG_ERROR, "nl80211: cannot find MTK_VENDOR_ATTR_IBF_DUMP_ENABLE");
349+ return NL_SKIP;
350+ }
351+
352+ *ibf_enable = nla_get_u8(attr);
353+
354+ return NL_SKIP;
355+}
356+
357+static int
358+nl80211_ibf_dump(void *priv, u8 *ibf_enable)
359+{
360+ struct i802_bss *bss = priv;
361+ struct wpa_driver_nl80211_data *drv = bss->drv;
362+ struct nl_msg *msg;
363+ struct nlattr *data;
364+ int ret;
365+
366+ msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_VENDOR);
367+ if (!msg)
368+ goto fail;
369+
370+ if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
371+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL))
372+ goto fail;
373+
374+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
375+ if (!data)
376+ goto fail;
377+
378+ nla_nest_end(msg, data);
379+
380+ ret = send_and_recv_resp(drv, msg, ibf_dump_handler, ibf_enable);
381+
382+ if (ret) {
383+ wpa_printf(MSG_ERROR, "Failed to dump ibf_enable. ret=%d (%s)", ret, strerror(-ret));
384+ }
385+
386+ return ret;
387+
388+fail:
389+ nlmsg_free(msg);
390+ return -ENOBUFS;
391+}
392+
393 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
394 .name = "nl80211",
395 .desc = "Linux nl80211/cfg80211",
396@@ -14557,4 +14663,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
397 .configure_edcca_threshold = nl80211_configure_edcca_threshold,
398 .get_edcca = nl80211_get_edcca,
399 .three_wire_ctrl = nl80211_enable_three_wire,
400+ .ibf_ctrl = nl80211_ibf_enable,
401+ .ibf_dump = nl80211_ibf_dump,
402 };
403diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
404index 5de6ca6f0..1432eeda8 100644
405--- a/src/drivers/driver_nl80211.h
406+++ b/src/drivers/driver_nl80211.h
407@@ -203,6 +203,7 @@ struct wpa_driver_nl80211_data {
408 unsigned int mtk_edcca_vendor_cmd_avail:1;
409 unsigned int mtk_mu_vendor_cmd_avail:1;
410 unsigned int mtk_3wire_vendor_cmd_avail:1;
411+ unsigned int mtk_ibf_vendor_cmd_avail:1;
412
413 u32 ignore_next_local_disconnect;
414 u32 ignore_next_local_deauth;
415diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
416index fddcf8349..615af2eb2 100644
417--- a/src/drivers/driver_nl80211_capa.c
418+++ b/src/drivers/driver_nl80211_capa.c
419@@ -1150,6 +1150,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
420 case MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL :
421 drv->mtk_3wire_vendor_cmd_avail = 1;
422 break;
423+ case MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL:
424+ drv->mtk_ibf_vendor_cmd_avail = 1;
425+ break;
426 }
427 }
428
429--
4302.39.2
431