blob: fc9a02d0a5d749dc1d30a204f43a4eb4572911e7 [file] [log] [blame]
developerd243af02023-12-21 14:49:33 +08001From d0f78e1b2efd0d0842c98a8733b06a7b59a9bd07 Mon Sep 17 00:00:00 2001
developere35b8e42023-10-16 11:04:00 +08002From: Howard Hsu <howard-yh.hsu@mediatek.com>
3Date: Thu, 21 Sep 2023 10:29:46 +0800
developerd243af02023-12-21 14:49:33 +08004Subject: [PATCH 50/54] mtk: hostapd: add support enable/disable preamble
5 puncture from mtk vendor command
developere35b8e42023-10-16 11:04:00 +08006
7This commit supports two ways to enable/disable preamble puncture
8feature.
9
101. Add new hostapd configuration "pp_mode". The possible value could be
111 to 3. When the value is 0, it means that the firmware will turn off
12the pp algorithm. When the value is 1, it means that the firmware will
13enable the pp algorithm, allowing the algorithm to determine whether pp
14could be applied on each txcmd. When the value is 2, it means that pp
15feature is manually configured by the user. Please noted that for
16current implementation, the default configuration is 0.
17
182. $ hostapd_cli -i <intf_name> raw set_pp mode val
19The argument "val" could be 0 for PP feature disabled or 1 to configure
20PP feature as auto mode.
21
22This commit also let user check whether pp feature is enabled by
23hostapd_cli command. The usage shows as below:
24$ hostapd_cli -i <intf_name> raw get_pp mode
25
26Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
27---
28 hostapd/config_file.c | 11 ++++++
29 hostapd/ctrl_iface.c | 59 +++++++++++++++++++++++++++++++
30 src/ap/ap_config.c | 1 +
31 src/ap/ap_config.h | 7 ++++
32 src/ap/ap_drv_ops.c | 9 +++++
33 src/ap/ap_drv_ops.h | 1 +
34 src/ap/hostapd.c | 2 ++
35 src/common/mtk_vendor.h | 12 +++++++
36 src/drivers/driver.h | 6 ++++
37 src/drivers/driver_nl80211.c | 49 +++++++++++++++++++++++++
38 src/drivers/driver_nl80211.h | 1 +
39 src/drivers/driver_nl80211_capa.c | 3 ++
40 12 files changed, 161 insertions(+)
41
42diff --git a/hostapd/config_file.c b/hostapd/config_file.c
developerd243af02023-12-21 14:49:33 +080043index a75199345..278f6b347 100644
developere35b8e42023-10-16 11:04:00 +080044--- a/hostapd/config_file.c
45+++ b/hostapd/config_file.c
46@@ -4801,6 +4801,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
47 conf->eht_phy_capab.mu_beamformer = atoi(pos);
48 } else if (os_strcmp(buf, "punct_bitmap") == 0) {
49 conf->punct_bitmap = atoi(pos);
50+ conf->pp_mode = PP_MANUAL_MODE;
51 } else if (os_strcmp(buf, "punct_acs_threshold") == 0) {
52 int val = atoi(pos);
53
54@@ -4876,6 +4877,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
55 return 1;
56 }
57 conf->amsdu = val;
58+ } else if (os_strcmp(buf, "pp_mode") == 0) {
59+ int val = atoi(pos);
60+
61+ if ((val != PP_MANUAL_MODE && conf->punct_bitmap) ||
62+ val < PP_DISABLE || val > PP_MANUAL_MODE) {
63+ wpa_printf(MSG_ERROR, "Line %d: invalid pp_mode value",
64+ line);
65+ return 1;
66+ }
67+ conf->pp_mode = (u8) val;
68 } else {
69 wpa_printf(MSG_ERROR,
70 "Line %d: unknown configuration item '%s'",
71diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
developerd243af02023-12-21 14:49:33 +080072index f7c7a09f3..64bab0228 100644
developere35b8e42023-10-16 11:04:00 +080073--- a/hostapd/ctrl_iface.c
74+++ b/hostapd/ctrl_iface.c
developerd243af02023-12-21 14:49:33 +080075@@ -4248,6 +4248,59 @@ hostapd_ctrl_iface_set_background_radar_mode(struct hostapd_data *hapd, char *cm
developere35b8e42023-10-16 11:04:00 +080076 return os_snprintf(buf, buflen, "OK\n");
77 }
78
79+static int
80+hostapd_ctrl_iface_set_pp(struct hostapd_data *hapd, char *cmd, char *buf,
81+ size_t buflen)
82+{
83+ char *pos, *config, *value;
84+
85+ config = cmd;
86+ pos = os_strchr(config, ' ');
87+ if (pos == NULL)
88+ return -1;
89+ *pos++ = '\0';
90+
91+ if (pos == NULL)
92+ return -1;
93+ value = pos;
94+
95+ if (os_strcmp(config, "mode") == 0) {
96+ int val = atoi(value);
97+
98+ if (val < PP_DISABLE || val > PP_AUTO_MODE) {
99+ wpa_printf(MSG_ERROR, "Invalid value for set_pp");
100+ return -1;
101+ }
102+ hapd->iconf->pp_mode = (u8) val;
103+ if (hostapd_drv_pp_mode_set(hapd) != 0)
104+ return -1;
105+ } else {
106+ wpa_printf(MSG_ERROR,
107+ "Unsupported parameter %s for set_pp", config);
108+ return -1;
109+ }
110+ return os_snprintf(buf, buflen, "OK\n");
111+}
112+
113+static int
114+hostapd_ctrl_iface_get_pp(struct hostapd_data *hapd, char *cmd, char *buf,
115+ size_t buflen)
116+{
117+ char *pos, *end;
118+
119+ pos = buf;
120+ end = buf + buflen;
121+
122+ if (os_strcmp(cmd, "mode") == 0) {
123+ return os_snprintf(pos, end - pos, "pp_mode: %d\n",
124+ hapd->iconf->pp_mode);
125+ } else {
126+ wpa_printf(MSG_ERROR,
127+ "Unsupported parameter %s for get_pp", cmd);
128+ return -1;
129+ }
130+}
131+
132 static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
133 char *buf, char *reply,
134 int reply_size,
developerd243af02023-12-21 14:49:33 +0800135@@ -4834,6 +4887,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
developere35b8e42023-10-16 11:04:00 +0800136 } else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
137 reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
138 reply, reply_size);
139+ } else if (os_strncmp(buf, "set_pp", 6) == 0) {
140+ reply_len = hostapd_ctrl_iface_set_pp(hapd, buf + 7, reply,
141+ reply_size);
142+ } else if (os_strncmp(buf, "get_pp", 6) == 0) {
143+ reply_len = hostapd_ctrl_iface_get_pp(hapd, buf + 7, reply,
144+ reply_size);
145 } else if (os_strncmp(buf, "set_muru_manual_config=", 23) == 0) {
146 // Replace first ':' with a single space ' '
147 char *pos = buf + 23;
148diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
developerd243af02023-12-21 14:49:33 +0800149index 223db56eb..d8dd5495a 100644
developere35b8e42023-10-16 11:04:00 +0800150--- a/src/ap/ap_config.c
151+++ b/src/ap/ap_config.c
152@@ -302,6 +302,7 @@ struct hostapd_config * hostapd_config_defaults(void)
153 conf->three_wire_enable = THREE_WIRE_MODE_DISABLE;
154 conf->ibf_enable = IBF_DEFAULT_ENABLE;
155 conf->amsdu = 1;
156+ conf->pp_mode = PP_DISABLE;
157
158 return conf;
159 }
160diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
developerd243af02023-12-21 14:49:33 +0800161index b6f05e7af..9e39e8285 100644
developere35b8e42023-10-16 11:04:00 +0800162--- a/src/ap/ap_config.h
163+++ b/src/ap/ap_config.h
164@@ -1205,6 +1205,7 @@ struct hostapd_config {
165 u8 dfs_detect_mode;
166 u8 amsdu;
167 void *muru_config;
168+ u8 pp_mode;
169 };
170
171 enum three_wire_mode {
172@@ -1257,6 +1258,12 @@ enum mtk_vendor_attr_edcca_ctrl_mode {
173 EDCCA_CTRL_NUM,
174 };
175
176+enum pp_mode {
177+ PP_DISABLE = 0,
178+ PP_AUTO_MODE,
179+ PP_MANUAL_MODE,
180+};
181+
182 #define EDCCA_DEFAULT_COMPENSATION -6
183 #define EDCCA_MIN_COMPENSATION -126
184 #define EDCCA_MAX_COMPENSATION 126
185diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
developerd243af02023-12-21 14:49:33 +0800186index 5b93ea647..d0d8279e2 100644
developere35b8e42023-10-16 11:04:00 +0800187--- a/src/ap/ap_drv_ops.c
188+++ b/src/ap/ap_drv_ops.c
189@@ -1271,3 +1271,12 @@ int hostapd_drv_background_radar_mode(struct hostapd_data *hapd)
190 return hapd->driver->background_radar_mode(hapd->drv_priv,
191 hapd->iconf->background_radar_mode);
192 }
193+
194+int hostapd_drv_pp_mode_set(struct hostapd_data *hapd)
195+{
196+ if (!hapd->driver || !hapd->driver->pp_mode_set ||
197+ hapd->iconf->pp_mode > PP_AUTO_MODE)
198+ return 0;
199+ return hapd->driver->pp_mode_set(hapd->drv_priv,
200+ hapd->iconf->pp_mode);
201+}
202diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
developerd243af02023-12-21 14:49:33 +0800203index 1e7ae7a8d..e4c2827bf 100644
developere35b8e42023-10-16 11:04:00 +0800204--- a/src/ap/ap_drv_ops.h
205+++ b/src/ap/ap_drv_ops.h
206@@ -163,6 +163,7 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
207
208 int hostapd_drv_amnt_set(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_sta_mac);
209 int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_buf);
210+int hostapd_drv_pp_mode_set(struct hostapd_data *hapd);
211
212 #include "drivers/driver.h"
213
214diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
developerd243af02023-12-21 14:49:33 +0800215index f01f607f3..2ffa3d4ea 100644
developere35b8e42023-10-16 11:04:00 +0800216--- a/src/ap/hostapd.c
217+++ b/src/ap/hostapd.c
218@@ -2526,6 +2526,8 @@ dfs_offload:
219 goto fail;
220 if (hostapd_drv_amsdu_ctrl(hapd) < 0)
221 goto fail;
222+ if (hostapd_drv_pp_mode_set(hapd) < 0)
223+ goto fail;
224
225 wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
226 iface->bss[0]->conf->iface);
227diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
developerd243af02023-12-21 14:49:33 +0800228index 5bc1e0444..6275c141d 100644
developere35b8e42023-10-16 11:04:00 +0800229--- a/src/common/mtk_vendor.h
230+++ b/src/common/mtk_vendor.h
231@@ -17,6 +17,7 @@ enum mtk_nl80211_vendor_subcmds {
232 MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
233 MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
234 MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL = 0xcb,
235+ MTK_NL80211_VENDOR_SUBCMD_PP_CTRL = 0xcc,
236 };
237
238 enum mtk_vendor_attr_edcca_ctrl {
239@@ -256,6 +257,17 @@ enum mtk_vendor_attr_background_radar_ctrl {
240 NUM_MTK_VENDOR_ATTRS_BACKGROUND_RADAR_CTRL - 1
241 };
242
243+enum mtk_vendor_attr_pp_ctrl {
244+ MTK_VENDOR_ATTR_PP_CTRL_UNSPEC,
245+
246+ MTK_VENDOR_ATTR_PP_MODE,
247+
248+ /* keep last */
249+ NUM_MTK_VENDOR_ATTRS_PP_CTRL,
250+ MTK_VENDOR_ATTR_PP_CTRL_MAX =
251+ NUM_MTK_VENDOR_ATTRS_PP_CTRL - 1
252+};
253+
254 #define CSI_MAX_COUNT 256
255 #define ETH_ALEN 6
256
257diff --git a/src/drivers/driver.h b/src/drivers/driver.h
developerd243af02023-12-21 14:49:33 +0800258index 0c1b2e452..fb463aaac 100644
developere35b8e42023-10-16 11:04:00 +0800259--- a/src/drivers/driver.h
260+++ b/src/drivers/driver.h
developerd243af02023-12-21 14:49:33 +0800261@@ -5211,6 +5211,12 @@ struct wpa_driver_ops {
developere35b8e42023-10-16 11:04:00 +0800262 * @background_radar_mode: background radar mode
263 */
264 int (*background_radar_mode)(void *priv, u8 background_radar_mode);
265+ /**
266+ * pp_mode_set - Set preamble puncture operation mode
267+ * @priv: Private driver interface data
268+ * @pp_mode: Value is defined in enum pp_mode
269+ */
270+ int (*pp_mode_set)(void *priv, const u8 pp_mode);
271 };
272
273 /**
274diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
developerd243af02023-12-21 14:49:33 +0800275index 3cbf8610a..cbe793cc6 100644
developere35b8e42023-10-16 11:04:00 +0800276--- a/src/drivers/driver_nl80211.c
277+++ b/src/drivers/driver_nl80211.c
developerd243af02023-12-21 14:49:33 +0800278@@ -151,6 +151,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
developere35b8e42023-10-16 11:04:00 +0800279 [MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
280 };
281
282+static struct nla_policy
283+pp_ctrl_policy[NUM_MTK_VENDOR_ATTRS_PP_CTRL] = {
284+ [MTK_VENDOR_ATTR_PP_MODE] = { .type = NLA_U8 },
285+};
286+
287 static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
288 {
289 struct nl_sock *handle;
developerd243af02023-12-21 14:49:33 +0800290@@ -14776,6 +14781,49 @@ static int nl80211_background_radar_mode(void *priv, const u8 background_radar_m
developere35b8e42023-10-16 11:04:00 +0800291 return ret;
292 }
293
294+static int nl80211_pp_mode_set(void *priv, const u8 pp_mode)
295+{
296+ struct i802_bss *bss = priv;
297+ struct wpa_driver_nl80211_data *drv = bss->drv;
298+ struct nl_msg *msg;
299+ struct nlattr *data;
300+ int ret;
301+
302+ if (!drv->mtk_pp_vendor_cmd_avail) {
303+ wpa_printf(MSG_DEBUG,
304+ "nl80211: Driver does not support setting preamble puncture");
305+ return 0;
306+ }
307+
308+ msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
309+ if (!msg)
310+ goto fail;
311+
312+ if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
313+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
314+ MTK_NL80211_VENDOR_SUBCMD_PP_CTRL))
315+ goto fail;
316+
317+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
318+ if (!data)
319+ goto fail;
320+
321+ nla_put_u8(msg, MTK_VENDOR_ATTR_PP_MODE, pp_mode);
322+
323+ nla_nest_end(msg, data);
324+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
325+
326+ if (ret)
327+ wpa_printf(MSG_ERROR, "Failed to set pp_enable. ret=%d (%s)",
328+ ret, strerror(-ret));
329+
330+ return ret;
331+
332+fail:
333+ nlmsg_free(msg);
334+ return -ENOBUFS;
335+}
336+
337 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
338 .name = "nl80211",
339 .desc = "Linux nl80211/cfg80211",
developerd243af02023-12-21 14:49:33 +0800340@@ -14949,4 +14997,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
developere35b8e42023-10-16 11:04:00 +0800341 .amnt_set = nl80211_amnt_set,
342 .amnt_dump = nl80211_amnt_dump,
343 .background_radar_mode = nl80211_background_radar_mode,
344+ .pp_mode_set = nl80211_pp_mode_set,
345 };
346diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
developerd243af02023-12-21 14:49:33 +0800347index 74ee9b191..1bba5b14e 100644
developere35b8e42023-10-16 11:04:00 +0800348--- a/src/drivers/driver_nl80211.h
349+++ b/src/drivers/driver_nl80211.h
350@@ -211,6 +211,7 @@ struct wpa_driver_nl80211_data {
351 unsigned int mtk_rfeatures_vendor_cmd_avail:1;
352 unsigned int mtk_amnt_vendor_cmd_avail:1;
353 unsigned int mtk_background_radar_vendor_cmd_avail:1;
354+ unsigned int mtk_pp_vendor_cmd_avail:1;
355
356 u64 vendor_scan_cookie;
357 u64 remain_on_chan_cookie;
358diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
developerd243af02023-12-21 14:49:33 +0800359index 74c3e0d86..0e044b03c 100644
developere35b8e42023-10-16 11:04:00 +0800360--- a/src/drivers/driver_nl80211_capa.c
361+++ b/src/drivers/driver_nl80211_capa.c
developerd243af02023-12-21 14:49:33 +0800362@@ -1140,6 +1140,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
developere35b8e42023-10-16 11:04:00 +0800363 case MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL:
364 drv->mtk_background_radar_vendor_cmd_avail = 1;
365 break;
366+ case MTK_NL80211_VENDOR_SUBCMD_PP_CTRL:
367+ drv->mtk_pp_vendor_cmd_avail = 1;
368+ break;
369 }
370 }
371
372--
3732.18.0
374