blob: 4959fb4b7493ae544446f9808003ec9aed013a8c [file] [log] [blame]
developer66e89bc2024-04-23 14:50:01 +08001From 51377e7c81b4164be42de4a5c4c48ba53a638afe Mon Sep 17 00:00:00 2001
2From: Howard Hsu <howard-yh.hsu@mediatek.com>
3Date: Thu, 21 Sep 2023 10:29:46 +0800
4Subject: [PATCH 072/104] mtk: hostapd: add support enable/disable preamble
5 puncture from mtk vendor command
6
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 | 12 +++++++
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, 162 insertions(+)
41
42diff --git a/hostapd/config_file.c b/hostapd/config_file.c
43index 9467a1128..050ef290e 100644
44--- a/hostapd/config_file.c
45+++ b/hostapd/config_file.c
46@@ -5333,6 +5333,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
47 } else if (os_strcmp(buf, "punct_bitmap") == 0) {
48 if (get_u16(pos, line, &conf->punct_bitmap))
49 return 1;
50+ conf->punct_bitmap = atoi(pos);
51+ conf->pp_mode = PP_MANUAL_MODE;
52 } else if (os_strcmp(buf, "punct_acs_threshold") == 0) {
53 int val = atoi(pos);
54
55@@ -5415,6 +5417,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
56 return 1;
57 }
58 conf->amsdu = val;
59+ } else if (os_strcmp(buf, "pp_mode") == 0) {
60+ int val = atoi(pos);
61+
62+ if ((val != PP_MANUAL_MODE && conf->punct_bitmap) ||
63+ val < PP_DISABLE || val > PP_MANUAL_MODE) {
64+ wpa_printf(MSG_ERROR, "Line %d: invalid pp_mode value",
65+ line);
66+ return 1;
67+ }
68+ conf->pp_mode = (u8) val;
69 } else {
70 wpa_printf(MSG_ERROR,
71 "Line %d: unknown configuration item '%s'",
72diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
73index 9b072d1b2..c9b53c64e 100644
74--- a/hostapd/ctrl_iface.c
75+++ b/hostapd/ctrl_iface.c
76@@ -4809,6 +4809,59 @@ hostapd_ctrl_iface_set_background_radar_mode(struct hostapd_data *hapd, char *cm
77 return os_snprintf(buf, buflen, "OK\n");
78 }
79
80+static int
81+hostapd_ctrl_iface_set_pp(struct hostapd_data *hapd, char *cmd, char *buf,
82+ size_t buflen)
83+{
84+ char *pos, *config, *value;
85+
86+ config = cmd;
87+ pos = os_strchr(config, ' ');
88+ if (pos == NULL)
89+ return -1;
90+ *pos++ = '\0';
91+
92+ if (pos == NULL)
93+ return -1;
94+ value = pos;
95+
96+ if (os_strcmp(config, "mode") == 0) {
97+ int val = atoi(value);
98+
99+ if (val < PP_DISABLE || val > PP_AUTO_MODE) {
100+ wpa_printf(MSG_ERROR, "Invalid value for set_pp");
101+ return -1;
102+ }
103+ hapd->iconf->pp_mode = (u8) val;
104+ if (hostapd_drv_pp_mode_set(hapd) != 0)
105+ return -1;
106+ } else {
107+ wpa_printf(MSG_ERROR,
108+ "Unsupported parameter %s for set_pp", config);
109+ return -1;
110+ }
111+ return os_snprintf(buf, buflen, "OK\n");
112+}
113+
114+static int
115+hostapd_ctrl_iface_get_pp(struct hostapd_data *hapd, char *cmd, char *buf,
116+ size_t buflen)
117+{
118+ char *pos, *end;
119+
120+ pos = buf;
121+ end = buf + buflen;
122+
123+ if (os_strcmp(cmd, "mode") == 0) {
124+ return os_snprintf(pos, end - pos, "pp_mode: %d\n",
125+ hapd->iconf->pp_mode);
126+ } else {
127+ wpa_printf(MSG_ERROR,
128+ "Unsupported parameter %s for get_pp", cmd);
129+ return -1;
130+ }
131+}
132+
133 static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
134 char *buf, char *reply,
135 int reply_size,
136@@ -5442,6 +5495,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
137 } else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
138 reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
139 reply, reply_size);
140+ } else if (os_strncmp(buf, "set_pp", 6) == 0) {
141+ reply_len = hostapd_ctrl_iface_set_pp(hapd, buf + 7, reply,
142+ reply_size);
143+ } else if (os_strncmp(buf, "get_pp", 6) == 0) {
144+ reply_len = hostapd_ctrl_iface_get_pp(hapd, buf + 7, reply,
145+ reply_size);
146 } else if (os_strncmp(buf, "set_muru_manual_config=", 23) == 0) {
147 // Replace first ':' with a single space ' '
148 char *pos = buf + 23;
149diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
150index ba1b2a7a3..056c38f73 100644
151--- a/src/ap/ap_config.c
152+++ b/src/ap/ap_config.c
153@@ -310,6 +310,7 @@ struct hostapd_config * hostapd_config_defaults(void)
154 conf->three_wire_enable = THREE_WIRE_MODE_DISABLE;
155 conf->ibf_enable = IBF_DEFAULT_ENABLE;
156 conf->amsdu = 1;
157+ conf->pp_mode = PP_DISABLE;
158
159 hostapd_set_and_check_bw320_offset(conf, 0);
160
161diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
162index 0b07be516..40edcdaa7 100644
163--- a/src/ap/ap_config.h
164+++ b/src/ap/ap_config.h
165@@ -1293,6 +1293,7 @@ struct hostapd_config {
166 u8 dfs_detect_mode;
167 u8 amsdu;
168 void *muru_config;
169+ u8 pp_mode;
170 };
171
172 enum three_wire_mode {
173@@ -1345,6 +1346,12 @@ enum mtk_vendor_attr_edcca_ctrl_mode {
174 EDCCA_CTRL_NUM,
175 };
176
177+enum pp_mode {
178+ PP_DISABLE = 0,
179+ PP_AUTO_MODE,
180+ PP_MANUAL_MODE,
181+};
182+
183 #define EDCCA_DEFAULT_COMPENSATION -6
184 #define EDCCA_MIN_COMPENSATION -126
185 #define EDCCA_MAX_COMPENSATION 126
186diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
187index 2028e70fb..c71cfe1bd 100644
188--- a/src/ap/ap_drv_ops.c
189+++ b/src/ap/ap_drv_ops.c
190@@ -1379,3 +1379,12 @@ int hostapd_drv_background_radar_mode(struct hostapd_data *hapd)
191 return hapd->driver->background_radar_mode(hapd->drv_priv,
192 hapd->iconf->background_radar_mode);
193 }
194+
195+int hostapd_drv_pp_mode_set(struct hostapd_data *hapd)
196+{
197+ if (!hapd->driver || !hapd->driver->pp_mode_set ||
198+ hapd->iconf->pp_mode > PP_AUTO_MODE)
199+ return 0;
200+ return hapd->driver->pp_mode_set(hapd->drv_priv,
201+ hapd->iconf->pp_mode);
202+}
203diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
204index f0e618bcc..ef61001e5 100644
205--- a/src/ap/ap_drv_ops.h
206+++ b/src/ap/ap_drv_ops.h
207@@ -169,6 +169,7 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
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_background_radar_mode(struct hostapd_data *hapd);
211+int hostapd_drv_pp_mode_set(struct hostapd_data *hapd);
212
213 #include "drivers/driver.h"
214
215diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
216index 0d4b79b48..cdbf81e38 100644
217--- a/src/ap/hostapd.c
218+++ b/src/ap/hostapd.c
219@@ -2708,6 +2708,8 @@ dfs_offload:
220 goto fail;
221 if (hostapd_drv_amsdu_ctrl(hapd) < 0)
222 goto fail;
223+ if (hostapd_drv_pp_mode_set(hapd) < 0)
224+ goto fail;
225
226 wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
227 iface->bss[0]->conf->iface);
228diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
229index 5bc1e0444..6275c141d 100644
230--- a/src/common/mtk_vendor.h
231+++ b/src/common/mtk_vendor.h
232@@ -17,6 +17,7 @@ enum mtk_nl80211_vendor_subcmds {
233 MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
234 MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
235 MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL = 0xcb,
236+ MTK_NL80211_VENDOR_SUBCMD_PP_CTRL = 0xcc,
237 };
238
239 enum mtk_vendor_attr_edcca_ctrl {
240@@ -256,6 +257,17 @@ enum mtk_vendor_attr_background_radar_ctrl {
241 NUM_MTK_VENDOR_ATTRS_BACKGROUND_RADAR_CTRL - 1
242 };
243
244+enum mtk_vendor_attr_pp_ctrl {
245+ MTK_VENDOR_ATTR_PP_CTRL_UNSPEC,
246+
247+ MTK_VENDOR_ATTR_PP_MODE,
248+
249+ /* keep last */
250+ NUM_MTK_VENDOR_ATTRS_PP_CTRL,
251+ MTK_VENDOR_ATTR_PP_CTRL_MAX =
252+ NUM_MTK_VENDOR_ATTRS_PP_CTRL - 1
253+};
254+
255 #define CSI_MAX_COUNT 256
256 #define ETH_ALEN 6
257
258diff --git a/src/drivers/driver.h b/src/drivers/driver.h
259index 863748d4f..be0e89ba3 100644
260--- a/src/drivers/driver.h
261+++ b/src/drivers/driver.h
262@@ -5326,6 +5326,12 @@ struct wpa_driver_ops {
263 * @background_radar_mode: background radar mode
264 */
265 int (*background_radar_mode)(void *priv, u8 background_radar_mode);
266+ /**
267+ * pp_mode_set - Set preamble puncture operation mode
268+ * @priv: Private driver interface data
269+ * @pp_mode: Value is defined in enum pp_mode
270+ */
271+ int (*pp_mode_set)(void *priv, const u8 pp_mode);
272 };
273
274 /**
275diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
276index e3f00b6d6..b47ab07ea 100644
277--- a/src/drivers/driver_nl80211.c
278+++ b/src/drivers/driver_nl80211.c
279@@ -156,6 +156,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
280 [MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
281 };
282
283+static struct nla_policy
284+pp_ctrl_policy[NUM_MTK_VENDOR_ATTRS_PP_CTRL] = {
285+ [MTK_VENDOR_ATTR_PP_MODE] = { .type = NLA_U8 },
286+};
287+
288 static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
289 {
290 struct nl_sock *handle;
291@@ -15085,6 +15090,49 @@ static int nl80211_background_radar_mode(void *priv, const u8 background_radar_m
292 return ret;
293 }
294
295+static int nl80211_pp_mode_set(void *priv, const u8 pp_mode)
296+{
297+ struct i802_bss *bss = priv;
298+ struct wpa_driver_nl80211_data *drv = bss->drv;
299+ struct nl_msg *msg;
300+ struct nlattr *data;
301+ int ret;
302+
303+ if (!drv->mtk_pp_vendor_cmd_avail) {
304+ wpa_printf(MSG_DEBUG,
305+ "nl80211: Driver does not support setting preamble puncture");
306+ return 0;
307+ }
308+
309+ msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
310+ if (!msg)
311+ goto fail;
312+
313+ if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
314+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
315+ MTK_NL80211_VENDOR_SUBCMD_PP_CTRL))
316+ goto fail;
317+
318+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
319+ if (!data)
320+ goto fail;
321+
322+ nla_put_u8(msg, MTK_VENDOR_ATTR_PP_MODE, pp_mode);
323+
324+ nla_nest_end(msg, data);
325+ ret = send_and_recv_cmd(drv, msg);
326+
327+ if (ret)
328+ wpa_printf(MSG_ERROR, "Failed to set pp_enable. ret=%d (%s)",
329+ ret, strerror(-ret));
330+
331+ return ret;
332+
333+fail:
334+ nlmsg_free(msg);
335+ return -ENOBUFS;
336+}
337+
338 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
339 .name = "nl80211",
340 .desc = "Linux nl80211/cfg80211",
341@@ -15263,4 +15311,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
342 .amnt_set = nl80211_amnt_set,
343 .amnt_dump = nl80211_amnt_dump,
344 .background_radar_mode = nl80211_background_radar_mode,
345+ .pp_mode_set = nl80211_pp_mode_set,
346 };
347diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
348index e9aae8d14..707bb7fe4 100644
349--- a/src/drivers/driver_nl80211.h
350+++ b/src/drivers/driver_nl80211.h
351@@ -209,6 +209,7 @@ struct wpa_driver_nl80211_data {
352 unsigned int mtk_rfeatures_vendor_cmd_avail:1;
353 unsigned int mtk_amnt_vendor_cmd_avail:1;
354 unsigned int mtk_background_radar_vendor_cmd_avail:1;
355+ unsigned int mtk_pp_vendor_cmd_avail:1;
356
357 u32 ignore_next_local_disconnect;
358 u32 ignore_next_local_deauth;
359diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
360index 9bc98aae7..ba3c0817b 100644
361--- a/src/drivers/driver_nl80211_capa.c
362+++ b/src/drivers/driver_nl80211_capa.c
363@@ -1167,6 +1167,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
364 case MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL:
365 drv->mtk_background_radar_vendor_cmd_avail = 1;
366 break;
367+ case MTK_NL80211_VENDOR_SUBCMD_PP_CTRL:
368+ drv->mtk_pp_vendor_cmd_avail = 1;
369+ break;
370 }
371 }
372
373--
3742.39.2
375