blob: 5872b479bc6d1ef9125dbcf7c439d281f02bb58d [file] [log] [blame]
developer00c6c7a2023-04-29 06:26:42 +08001From 4c6d148fea7cd1ea380a792d83d2dabe61e9c869 Mon Sep 17 00:00:00 2001
developer1dcc2ea2023-03-17 16:22:27 +08002From: Evelyn Tsai <evelyn.tsai@mediatek.com>
3Date: Fri, 17 Mar 2023 16:17:14 +0800
developer00c6c7a2023-04-29 06:26:42 +08004Subject: [PATCH 26/29] hostapd: mtk: Add vendor for CAPI certification
developer1d9da7d2023-04-15 12:45:34 +08005 commands
developer1dcc2ea2023-03-17 16:22:27 +08006
7---
8 hostapd/ctrl_iface.c | 95 +++++++++++++++
9 src/ap/ap_drv_ops.c | 21 ++++
10 src/ap/ap_drv_ops.h | 3 +
11 src/common/mtk_vendor.h | 32 +-----
12 src/drivers/driver.h | 22 ++++
13 src/drivers/driver_nl80211.c | 185 ++++++++++++++++++++++++++++++
14 src/drivers/driver_nl80211.h | 1 +
15 src/drivers/driver_nl80211_capa.c | 3 +
16 8 files changed, 332 insertions(+), 30 deletions(-)
17
18diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
developer00c6c7a2023-04-29 06:26:42 +080019index 87448e7..b0323e7 100644
developer1dcc2ea2023-03-17 16:22:27 +080020--- a/hostapd/ctrl_iface.c
21+++ b/hostapd/ctrl_iface.c
22@@ -38,6 +38,7 @@
23 #endif /* CONFIG_DPP */
24 #include "common/wpa_ctrl.h"
25 #include "common/ptksa_cache.h"
26+#include "common/mtk_vendor.h"
27 #include "crypto/tls.h"
28 #include "drivers/driver.h"
29 #include "eapol_auth/eapol_auth_sm.h"
developer00c6c7a2023-04-29 06:26:42 +080030@@ -3727,6 +3728,96 @@ hostapd_ctrl_iface_get_aval_color_bmp(struct hostapd_data *hapd, char *buf,
developer1dcc2ea2023-03-17 16:22:27 +080031 return pos - buf;
32 }
33
34+static int
35+hostapd_ctrl_iface_ap_wireless(struct hostapd_data *hapd, char *cmd,
36+ char *buf, size_t buflen)
37+{
38+ char *pos, *value, *config = cmd;
39+ enum mtk_vendor_attr_wireless_ctrl sub_cmd;
40+
41+ pos = os_strchr(config, '=');
42+ if (pos == NULL)
43+ return -1;
44+ *pos++ = '\0';
45+
46+ if(pos == NULL)
47+ return -1;
48+ value = pos;
49+
50+ if (os_strncmp(config, "fixed_mcs", 9) == 0)
51+ sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS;
52+ else if (os_strncmp(config, "ofdma", 5) == 0)
53+ sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA;
54+ else if (os_strncmp(config, "ppdu_type", 9) == 0)
55+ sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE;
56+ else if (os_strncmp(config, "nusers_ofdma", 12) == 0)
57+ sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA;
58+ else if (os_strncmp(config, "add_ba_req_bufsize", 18) == 0)
59+ sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE;
60+ else if (os_strncmp(config, "mimo", 4) == 0)
61+ sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO;
62+ else if (os_strncmp(config, "cert", 4) == 0)
63+ sub_cmd = MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT ;
64+ else {
65+ wpa_printf(MSG_ERROR,
66+ "Unsupported parameter %s for ap_wireless", config);
67+ return -1;
68+ }
69+
70+ if (hostapd_drv_ap_wireless(hapd, (u8) sub_cmd, atoi(value)) != 0)
71+ return -1;
72+
73+ return os_snprintf(buf, buflen, "OK\n");
74+}
75+
76+static int
77+hostapd_ctrl_iface_ap_rfeatures(struct hostapd_data *hapd, char *cmd,
78+ char *buf, size_t buflen)
79+{
80+ char *pos, *value, *type, *config = cmd;
81+ enum mtk_vendor_attr_rfeature_ctrl sub_cmd;
82+
83+ pos = os_strchr(config, '=');
84+ if (pos == NULL)
85+ return -1;
86+ *pos++ = '\0';
87+
88+ if(pos == NULL)
89+ return -1;
90+ value = pos;
91+
92+ if (os_strncmp(config, "he_gi", 5) == 0)
93+ sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI;
94+ else if (os_strncmp(config, "he_ltf", 6) == 0)
95+ sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF;
96+ else if (os_strncmp(config, "trig_type", 9) == 0) {
97+ pos = os_strchr(value, ',');
98+ if (pos == NULL)
99+ return -1;
100+ *pos++ = '\0';
101+ if(pos == NULL)
102+ return -1;
103+ type = pos;
104+ goto trigtype;
105+ } else if (os_strcmp(config, "ack_policy") == 0)
106+ sub_cmd = MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY;
107+ else {
108+ wpa_printf(MSG_ERROR,
109+ "Unsupported parameter %s for ap_rfeatures", config);
110+ return -1;
111+ }
112+
113+ if (hostapd_drv_ap_rfeatures(hapd, (u8) sub_cmd, atoi(value)) != 0)
114+ return -1;
115+ goto exit;
116+
117+trigtype:
118+ if (hostapd_drv_ap_trig_type(hapd, atoi(value), atoi(type)) != 0)
119+ return -1;
120+
121+exit:
122+ return os_snprintf(buf, buflen, "OK\n");
123+}
124
125 static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
126 char *buf, char *reply,
developer00c6c7a2023-04-29 06:26:42 +0800127@@ -4298,6 +4389,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
developer1dcc2ea2023-03-17 16:22:27 +0800128 reply_len = hostapd_ctrl_iface_get_bss_color(hapd, reply, reply_size);
129 } else if (os_strncmp(buf, "AVAL_COLOR_BMP", 14) == 0) {
130 reply_len = hostapd_ctrl_iface_get_aval_color_bmp(hapd, reply, reply_size);
131+ } else if (os_strncmp(buf, "ap_wireless ", 12) == 0) {
132+ reply_len = hostapd_ctrl_iface_ap_wireless(hapd, buf + 12, reply, reply_size);
133+ } else if (os_strncmp(buf, "ap_rfeatures ", 13) == 0) {
134+ reply_len = hostapd_ctrl_iface_ap_rfeatures(hapd, buf + 13, reply, reply_size);
135 } else {
136 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
137 reply_len = 16;
138diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
139index 40b9a20..52d0fff 100644
140--- a/src/ap/ap_drv_ops.c
141+++ b/src/ap/ap_drv_ops.c
142@@ -1100,3 +1100,24 @@ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd, u64 *aval_colo
143 return 0;
144 return hapd->driver->get_aval_color_bmp(hapd->drv_priv, aval_color_bmp);
145 }
146+
147+int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
148+{
149+ if (!hapd->driver || !hapd->driver->ap_wireless)
150+ return 0;
151+ return hapd->driver->ap_wireless(hapd->drv_priv, sub_vendor_id, value);
152+}
153+
154+int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
155+{
156+ if (!hapd->driver || !hapd->driver->ap_rfeatures)
157+ return 0;
158+ return hapd->driver->ap_rfeatures(hapd->drv_priv, sub_vendor_id, value);
159+}
160+
161+int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type)
162+{
163+ if (!hapd->driver || !hapd->driver->ap_trigtype)
164+ return 0;
165+ return hapd->driver->ap_trigtype(hapd->drv_priv, enable, type);
166+}
167diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
168index 136a3ac..659c3f8 100644
169--- a/src/ap/ap_drv_ops.h
170+++ b/src/ap/ap_drv_ops.h
171@@ -151,6 +151,9 @@ int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd);
172 int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu);
173 int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd,
174 u64 *aval_color_bmp);
175+int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
176+int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
177+int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
178
179 #include "drivers/driver.h"
180
181diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
182index a99e6f2..32438af 100644
183--- a/src/common/mtk_vendor.h
184+++ b/src/common/mtk_vendor.h
185@@ -48,16 +48,6 @@ enum mtk_vendor_attr_edcca_dump {
186 NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP - 1
187 };
188
189-
190-static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
191- [MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
192- [MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
193- [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
194- [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
195- [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
196- [MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
197-};
198-
199 enum mtk_vendor_attr_3wire_ctrl {
200 MTK_VENDOR_ATTR_3WIRE_CTRL_UNSPEC,
201
202@@ -69,10 +59,6 @@ enum mtk_vendor_attr_3wire_ctrl {
203 NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL - 1
204 };
205
206-static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
207- [MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
208-};
209-
210 enum mtk_vendor_attr_csi_ctrl {
211 MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC,
212
213@@ -169,7 +155,7 @@ enum mtk_vendor_attr_wireless_ctrl {
214 MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
215 MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
216 MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU,
217- MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT,
218+ MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT = 9,
219 MTK_VENDOR_ATTR_WIRELESS_CTRL_RTS_SIGTA,
220
221 /* keep last */
222@@ -189,11 +175,6 @@ enum mtk_vendor_attr_wireless_dump {
223 NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP - 1
224 };
225
226-static const struct nla_policy
227-wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
228- [MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
229-};
230-
231 enum mtk_vendor_attr_rfeature_ctrl {
232 MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
233
234@@ -203,6 +184,7 @@ enum mtk_vendor_attr_rfeature_ctrl {
235 MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN,
236 MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE,
237 MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY,
238+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF,
239
240 /* keep last */
241 NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL,
242@@ -244,16 +226,6 @@ enum mtk_vendor_attr_ibf_dump {
243 NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1
244 };
245
246-static struct nla_policy
247-ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
248- [MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
249-};
250-
251-static struct nla_policy
252-ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
253- [MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
254-};
255-
256 enum mtk_vendor_attr_bss_color_ctrl {
257 MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
258
259diff --git a/src/drivers/driver.h b/src/drivers/driver.h
developer1d9da7d2023-04-15 12:45:34 +0800260index 1bf0cd6..6a46832 100644
developer1dcc2ea2023-03-17 16:22:27 +0800261--- a/src/drivers/driver.h
262+++ b/src/drivers/driver.h
developer1d9da7d2023-04-15 12:45:34 +0800263@@ -4787,6 +4787,28 @@ struct wpa_driver_ops {
developer1dcc2ea2023-03-17 16:22:27 +0800264 *
265 */
266 int (*get_aval_color_bmp)(void *priv, u64 *aval_color_bmp);
267+
268+ /**
269+ * ap_wireless - set wireless command
270+ * @priv: Private driver interface data
271+ * @value: value
272+ */
273+ int (*ap_wireless)(void *priv, u8 mode, int value);
274+
275+ /**
276+ * ap_rfeatures - set ap rf features command
277+ * @priv: Private driver interface data
278+ * @value: value
279+ */
280+ int (*ap_rfeatures)(void *priv, u8 mode, int value);
281+
282+ /**
283+ * ap_trigtype - set trigger type
284+ * @priv: Private driver interface data
285+ * @enable: enable or disable
286+ * @type: trigger type
287+ */
288+ int (*ap_trigtype)(void *priv, u8 enable, u8 type);
289 };
290
291 /**
292diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
developer1d9da7d2023-04-15 12:45:34 +0800293index 945ce3e..7fae013 100644
developer1dcc2ea2023-03-17 16:22:27 +0800294--- a/src/drivers/driver_nl80211.c
295+++ b/src/drivers/driver_nl80211.c
296@@ -74,6 +74,57 @@ enum nlmsgerr_attrs {
297 #endif /* ANDROID */
298
299
300+static struct nla_policy
301+ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
302+ [MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
303+};
304+
305+static struct nla_policy
306+ibf_dump_policy[NUM_MTK_VENDOR_ATTRS_IBF_DUMP] = {
307+ [MTK_VENDOR_ATTR_IBF_DUMP_ENABLE] = { .type = NLA_U8 },
308+};
309+
310+static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = {
311+ [MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 },
312+};
313+
314+static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
315+ [MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
316+ [MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
317+ [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
318+ [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
319+ [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
320+ [MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_U8 },
321+};
322+
323+static const struct nla_policy
324+wireless_dump_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_DUMP] = {
325+ [MTK_VENDOR_ATTR_WIRELESS_DUMP_AMSDU] = { .type = NLA_U8 },
326+};
327+
328+static const struct nla_policy
329+rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
330+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
331+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF] = { .type = NLA_U8 },
332+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG] = { .type = NLA_NESTED },
333+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN] = { .type = NLA_U8 },
334+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE] = { .type = NLA_U8 },
335+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY] = { .type = NLA_U8 },
336+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
337+};
338+
339+static const struct nla_policy
340+wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
341+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS] = {.type = NLA_U8 },
342+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA] = {.type = NLA_U8 },
343+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE] = {.type = NLA_U8 },
344+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 },
345+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 },
346+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 },
347+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU] = {.type = NLA_U8 },
348+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
349+};
350+
351 static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
352 {
353 struct nl_sock *handle;
developer1d9da7d2023-04-15 12:45:34 +0800354@@ -13014,6 +13065,137 @@ fail:
developer1dcc2ea2023-03-17 16:22:27 +0800355 return -ENOBUFS;
356 }
357
358+static int nl80211_ap_wireless(void *priv, u8 sub_vendor_id, int value)
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+ if (!drv->mtk_wireless_vendor_cmd_avail) {
367+ wpa_printf(MSG_INFO,
368+ "nl80211: Driver does not support setting ap wireless control");
369+ return 0;
370+ }
371+
372+ msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
373+ if (!msg)
374+ goto fail;
375+
376+ if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
377+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL))
378+ goto fail;
379+
380+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
381+ if (!data)
382+ goto fail;
383+
384+ if (sub_vendor_id == MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE)
385+ nla_put_u16(msg, sub_vendor_id, (u16) value);
386+ else
387+ nla_put_u8(msg, sub_vendor_id, (u8) value);
388+
389+ nla_nest_end(msg, data);
390+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
391+ if (ret)
392+ wpa_printf(MSG_ERROR, "Failed to set ap_wireless. ret=%d (%s)", ret, strerror(-ret));
393+
394+ return ret;
395+
396+fail:
397+ nlmsg_free(msg);
398+ return -ENOBUFS;
399+}
400+
401+static int nl80211_ap_rfeatures(void *priv, u8 sub_vendor_id, int value)
402+{
403+ struct i802_bss *bss = priv;
404+ struct wpa_driver_nl80211_data *drv = bss->drv;
405+ struct nl_msg *msg;
406+ struct nlattr *data;
407+ int ret;
408+
409+ if (!drv->mtk_rfeatures_vendor_cmd_avail) {
410+ wpa_printf(MSG_INFO,
411+ "nl80211: Driver does not support setting ap rfeatures control");
412+ return 0;
413+ }
414+
415+ msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
416+ if (!msg)
417+ goto fail;
418+
419+ if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
420+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
421+ goto fail;
422+
423+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
424+ if (!data)
425+ goto fail;
426+
427+ nla_put_u8(msg, sub_vendor_id, (u8) value);
428+
429+ nla_nest_end(msg, data);
430+
431+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
432+ if (ret)
433+ wpa_printf(MSG_ERROR, "Failed to set rf_features. ret=%d (%s)", ret, strerror(-ret));
434+
435+ return ret;
436+
437+fail:
438+ nlmsg_free(msg);
439+ return -ENOBUFS;
440+}
441+
442+static int nl80211_ap_trigtype(void *priv, u8 enable, u8 type)
443+{
444+ struct i802_bss *bss = priv;
445+ struct wpa_driver_nl80211_data *drv = bss->drv;
446+ struct nl_msg *msg;
447+ struct nlattr *data, *data2;
448+ int ret;
449+
450+ if (!drv->mtk_rfeatures_vendor_cmd_avail) {
451+ wpa_printf(MSG_INFO,
452+ "nl80211: Driver does not support setting ap rfeatures control");
453+ return 0;
454+ }
455+
456+ msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
457+ if (!msg)
458+ goto fail;
459+
460+ if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
461+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL))
462+ goto fail;
463+
464+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
465+ if (!data)
466+ goto fail;
467+
468+ data2 = nla_nest_start(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG);
469+ if (!data2)
470+ goto fail;
471+
472+ nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN, enable);
473+ nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE, type);
474+
475+ nla_nest_end(msg, data2);
476+ nla_nest_end(msg, data);
477+
478+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
479+ if (ret)
480+ wpa_printf(MSG_ERROR, "Failed to set trig_type. ret=%d (%s)", ret, strerror(-ret));
481+
482+ return ret;
483+
484+fail:
485+ nlmsg_free(msg);
486+ return -ENOBUFS;
487+}
488+
489 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
490 .name = "nl80211",
491 .desc = "Linux nl80211/cfg80211",
developer1d9da7d2023-04-15 12:45:34 +0800492@@ -13171,4 +13353,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
developer1dcc2ea2023-03-17 16:22:27 +0800493 .amsdu_ctrl = nl80211_enable_amsdu,
494 .amsdu_dump = nl80211_dump_amsdu,
495 .get_aval_color_bmp = nl80211_get_aval_color_bmp,
496+ .ap_wireless = nl80211_ap_wireless,
497+ .ap_rfeatures = nl80211_ap_rfeatures,
498+ .ap_trigtype = nl80211_ap_trigtype,
499 };
500diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
501index 72c7abd..7a03446 100644
502--- a/src/drivers/driver_nl80211.h
503+++ b/src/drivers/driver_nl80211.h
504@@ -187,6 +187,7 @@ struct wpa_driver_nl80211_data {
505 unsigned int mtk_ibf_vendor_cmd_avail:1;
506 unsigned int mtk_wireless_vendor_cmd_avail:1;
507 unsigned int mtk_bss_color_vendor_cmd_avail:1;
508+ unsigned int mtk_rfeatures_vendor_cmd_avail:1;
509
510 u64 vendor_scan_cookie;
511 u64 remain_on_chan_cookie;
512diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
513index e7c6f39..6f4d029 100644
514--- a/src/drivers/driver_nl80211_capa.c
515+++ b/src/drivers/driver_nl80211_capa.c
516@@ -1095,6 +1095,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
517 case MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL :
518 drv->mtk_bss_color_vendor_cmd_avail = 1;
519 break;
520+ case MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL:
521+ drv->mtk_rfeatures_vendor_cmd_avail = 1;
522+ break;
523 }
524 }
525
526--
5272.18.0
528