blob: 69615ec134ee1dc0a2e68c526be312904be665d5 [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From f7ffccc3487fbc51786d4063b03e0e4a090253b0 Mon Sep 17 00:00:00 2001
developer66e89bc2024-04-23 14:50:01 +08002From: Howard Hsu <howard-yh.hsu@mediatek.com>
3Date: Sat, 3 Jun 2023 17:12:15 +0800
developer05f3b2b2024-08-19 19:17:34 +08004Subject: [PATCH 034/126] mtk: hostapd: add connac3 PHY MURU manual mode config
developer66e89bc2024-04-23 14:50:01 +08005 support
6
7This commit supports read the following two formats to set MU/RU manual
8mode:
91. hostapd_cli -i <intf> raw set_muru_manual_config=<field>:<value>
102. hostapd_cli -i <intf> set_mu <field> <value>
11
12For the <field>, we support the following field:
131. ul_comm_user_cnt/dl_comm_user_cnt: set the number of user
142. ul_comm_bw/dl_comm_bw: set the bandwith
153. ul_user_ru_alloc/dl_user_ru_alloc: set the RU band idx and RU
16allocate idx
174. ul_user_mcs/dl_user_mcs: set the mcs for each user
185. ul_user_ssAlloc_raru: set the number of ss for each user
196. ul_comm_gi_ltf: set the combinations of gi and ltf for UL only.
207. dl_comm_toneplan: fix ru toneplan allocation
218. dl_comm_ack_policy: fix station ack policy
229. update : trigger driver to send mcu command to set muru manual mode.
23
24For the value of each field, please check wiki to learn the details:
25https://wiki.mediatek.inc/display/GWKB/muru_mancfg_user_guide
26
27For the fields that mt76 support to use, we will update in this wiki:
28https://wiki.mediatek.inc/pages/viewpage.action?pageId=1271741116
29
30Please noted that this commit is only for connac 3 gen chips. If this
31feature is to be used in other generations, the following actions must
32be taken:
331. Different data structue needs to be defined for different
34generations, e.g. connac4_muru_comm, connac4_muru_dl.
352. hostapd_ctrl_iface_set_mu() shall be modified.
363. A new code level configuration shall be defined to differentiate the
37code flow that different generations will go through.
developer05f3b2b2024-08-19 19:17:34 +080038
39Add support new argument global_comm_band for muru manual config
40command. This argument can be used to specify the band to apply manual
41config.
42
43Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
developer66e89bc2024-04-23 14:50:01 +080044---
developer05f3b2b2024-08-19 19:17:34 +080045 hostapd/ctrl_iface.c | 240 +++++++++++++++++++++++++++++++----
developer66e89bc2024-04-23 14:50:01 +080046 src/ap/ap_config.h | 1 +
47 src/ap/ap_drv_ops.c | 4 +-
48 src/ap/ap_drv_ops.h | 2 +-
49 src/ap/hostapd.c | 2 +-
50 src/common/mtk_vendor.h | 166 +++++++++++++++++++++++-
51 src/drivers/driver.h | 2 +-
developer05f3b2b2024-08-19 19:17:34 +080052 src/drivers/driver_nl80211.c | 21 ++-
53 8 files changed, 394 insertions(+), 44 deletions(-)
developer66e89bc2024-04-23 14:50:01 +080054
55diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
developer05f3b2b2024-08-19 19:17:34 +080056index b78ee24c0..68b83bf6e 100644
developer66e89bc2024-04-23 14:50:01 +080057--- a/hostapd/ctrl_iface.c
58+++ b/hostapd/ctrl_iface.c
developer05f3b2b2024-08-19 19:17:34 +080059@@ -3905,7 +3905,6 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
developer66e89bc2024-04-23 14:50:01 +080060 }
61 }
62
63-
64 #ifdef CONFIG_NAN_USD
65
66 static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd,
developer05f3b2b2024-08-19 19:17:34 +080067@@ -4192,21 +4191,61 @@ fail:
developer66e89bc2024-04-23 14:50:01 +080068 #endif /* CONFIG_NAN_USD */
69
70
71+static int
72+hostapd_parse_argument_helper(char *value, u16 **ptr_input)
73+{
74+#define MAX_MU_CTRL_NUM 17
75+ u16 *input;
76+ char *endptr;
77+ int cnt = 0;
78+
79+ input = os_zalloc(MAX_MU_CTRL_NUM * sizeof(u16));
80+ if (input == NULL) {
81+ wpa_printf(MSG_ERROR, "Failed to allocate memory.\n");
82+ return -1;
83+ }
84+ while (value) {
85+ u8 val = strtol(value, &endptr, 10);
86+
87+ if (value != endptr) {
88+ input[cnt++] = val;
89+ value = os_strchr(endptr, ':');
90+ if (value)
91+ value++;
92+ } else {
93+ break;
94+ }
95+ }
96+
97+ *ptr_input = input;
98+ return cnt;
99+}
100+
101+#define MURU_CFG_DEPENDENCE_CHECK(_val, _mask) do { \
102+ if ((le_to_host32(_val) & (_mask)) != _mask) { \
103+ wpa_printf(MSG_ERROR, "Set %s first\n", #_mask); \
104+ goto fail; \
105+ } \
106+ } while(0)
107+
108 static int
109 hostapd_ctrl_iface_set_mu(struct hostapd_data *hapd, char *cmd,
110- char *buf, size_t buflen)
111+ char *buf, size_t buflen)
112 {
113 char *pos, *config, *value;
114- u8 mode;
115+ u8 i;
116+ int cnt = 0, ret;
117+ u16 *val;
118+ struct connac3_muru *muru;
119+ struct connac3_muru_dl *dl;
120+ struct connac3_muru_ul *ul;
121+ struct connac3_muru_comm *comm;
122
123 config = cmd;
124 pos = os_strchr(config, ' ');
125- if (pos == NULL)
126- return -1;
127- *pos++ = '\0';
128+ if (pos != NULL)
129+ *pos++ = '\0';
130
131- if(pos == NULL)
132- return -1;
133 value = pos;
134
135 if (os_strcmp(config, "onoff") == 0) {
developer05f3b2b2024-08-19 19:17:34 +0800136@@ -4216,24 +4255,170 @@ hostapd_ctrl_iface_set_mu(struct hostapd_data *hapd, char *cmd,
developer66e89bc2024-04-23 14:50:01 +0800137 return -1;
138 }
139 hapd->iconf->mu_onoff = (u8) mu;
140- mode = MU_CTRL_ONOFF;
141- } else if (os_strcmp(config, "ul_user_cnt") == 0) {
142- mode = MU_CTRL_UL_USER_CNT;
143- wpa_printf(MSG_ERROR, "ul_user_cnt:%d\n", (u8)atoi(value));
144- } else if (os_strcmp(config, "dl_user_cnt") == 0) {
145- mode = MU_CTRL_DL_USER_CNT;
146- wpa_printf(MSG_ERROR, "dl_user_cnt:%d\n", (u8)atoi(value));
147- } else {
148- wpa_printf(MSG_ERROR,
149- "Unsupported parameter %s for SET_MU", config);
150- return -1;
151+
152+ if (hostapd_drv_mu_ctrl(hapd, MU_CTRL_ONOFF) == 0)
153+ return os_snprintf(buf, buflen, "OK\n");
154+ else
155+ goto fail;
156 }
157
158- if(hostapd_drv_mu_ctrl(hapd, mode, (u8)atoi(value)) == 0) {
159- return os_snprintf(buf, buflen, "OK\n");
160+ if (hapd->iconf->muru_config == NULL)
161+ hapd->iconf->muru_config = os_zalloc(sizeof(struct connac3_muru));
162+
163+ muru = hapd->iconf->muru_config;
164+ dl = &muru->dl;
165+ ul = &muru->ul;
166+ comm = &muru->comm;
167+
168+ if (os_strncmp(config, "update", 6) == 0) {
169+ ret = hostapd_drv_mu_ctrl(hapd, MU_CTRL_UPDATE);
170+
171+ os_free(hapd->iconf->muru_config);
172+ hapd->iconf->muru_config = NULL;
173+
174+ if (ret)
175+ goto fail;
176+ } else if (os_strcmp(config, "ul_comm_user_cnt") == 0) {
177+ ul->user_num = (u8)atoi(value);
178+ comm->ppdu_format |= MURU_PPDU_HE_TRIG;
179+ comm->sch_type |= MURU_OFDMA_SCH_TYPE_UL;
180+ muru->cfg_comm |= host_to_le32(MURU_COMM_SET);
181+ muru->cfg_ul |= host_to_le32(MURU_FIXED_UL_TOTAL_USER_CNT);
182+ } else if (os_strcmp(config, "dl_comm_user_cnt") == 0) {
183+ dl->user_num = (u8)atoi(value);
184+ comm->ppdu_format |= MURU_PPDU_HE_MU;
185+ comm->sch_type |= MURU_OFDMA_SCH_TYPE_DL;
186+ muru->cfg_comm |= host_to_le32(MURU_COMM_SET);
187+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_TOTAL_USER_CNT);
188+ } else if (os_strcmp(config, "dl_comm_bw") == 0) {
189+ dl->bw = (u8)atoi(value);
190+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_BW);
191+ } else if (os_strcmp(config, "ul_comm_bw") == 0) {
192+ ul->bw = (u8)atoi(value);
193+ muru->cfg_ul |= host_to_le32(MURU_FIXED_UL_BW);
194+ } else if (os_strcmp(config, "dl_user_ru_alloc") == 0) {
195+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_dl, MURU_FIXED_DL_TOTAL_USER_CNT);
196+ cnt = hostapd_parse_argument_helper(value, &val);
197+ if (cnt == -1)
198+ goto fail;
199+ if (cnt != (dl->user_num * 2))
200+ goto para_fail;
201+ for (i = 0; i < dl->user_num; i++) {
202+ dl->usr[i].ru_alloc_seg = (val[2 * i] & 0x1);
203+ dl->usr[i].ru_allo_ps160 = ((val[2 * i] & 0x2) >> 1);
204+ dl->usr[i].ru_idx = val[(2 * i) + 1];
205+ }
206+ os_free(val);
207+ muru->cfg_dl |= host_to_le32(MURU_FIXED_USER_DL_RU_ALLOC);
208+ } else if (os_strcmp(config, "ul_user_ru_alloc") == 0) {
209+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_ul, MURU_FIXED_UL_TOTAL_USER_CNT);
210+ cnt = hostapd_parse_argument_helper(value, &val);
211+ if (cnt == -1)
212+ goto fail;
213+ if (cnt != (ul->user_num * 2))
214+ goto para_fail;
215+ for (i = 0; i < ul->user_num; i++) {
216+ ul->usr[i].ru_alloc_seg = (val[2 * i] & 0x1);
217+ ul->usr[i].ru_allo_ps160 = ((val[2 * i] & 0x2) >> 1);
218+ ul->usr[i].ru_idx = val[(2 * i) + 1];
219+ }
220+ os_free(val);
221+ muru->cfg_ul |= host_to_le32(MURU_FIXED_USER_UL_RU_ALLOC);
222+ } else if (os_strcmp(config, "dl_user_mcs") == 0) {
223+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_dl, MURU_FIXED_DL_TOTAL_USER_CNT);
224+ cnt = hostapd_parse_argument_helper(value, &val);
225+ if (cnt == -1)
226+ goto fail;
227+ if (cnt != dl->user_num)
228+ goto para_fail;
229+ for (i = 0; i < cnt; i++)
230+ dl->usr[i].mcs = (u8) val[i];
231+ os_free(val);
232+ muru->cfg_dl |= host_to_le32(MURU_FIXED_USER_DL_MCS);
233+ } else if (os_strcmp(config, "ul_user_mcs") == 0) {
234+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_ul, MURU_FIXED_UL_TOTAL_USER_CNT);
235+ cnt = hostapd_parse_argument_helper(value, &val);
236+ if (cnt == -1)
237+ goto fail;
238+ if (cnt != ul->user_num)
239+ goto para_fail;
240+ for (i = 0; i < cnt; i++)
241+ ul->usr[i].mcs = (u8) val[i];
242+ os_free(val);
243+ muru->cfg_ul |= host_to_le32(MURU_FIXED_USER_UL_MCS);
244+ } else if (os_strcmp(config, "dl_user_cod") == 0) {
245+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_dl, MURU_FIXED_DL_TOTAL_USER_CNT);
246+ cnt = hostapd_parse_argument_helper(value, &val);
247+ if (cnt == -1)
248+ goto fail;
249+ if (cnt != dl->user_num)
250+ goto para_fail;
251+ for (i = 0; i < cnt; i++)
252+ dl->usr[i].ldpc = (u8) val[i];
253+ os_free(val);
254+ muru->cfg_dl |= host_to_le32(MURU_FIXED_USER_DL_COD);
255+ } else if (os_strcmp(config, "ul_user_cod") == 0) {
256+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_ul, MURU_FIXED_UL_TOTAL_USER_CNT);
257+ cnt = hostapd_parse_argument_helper(value, &val);
258+ if (cnt == -1)
259+ goto fail;
260+ if (cnt != ul->user_num)
261+ goto para_fail;
262+ for (i = 0; i < cnt; i++)
263+ ul->usr[i].ldpc = (u8) val[i];
264+ os_free(val);
265+ muru->cfg_ul |= host_to_le32(MURU_FIXED_USER_UL_COD);
266+ } else if (os_strcmp(config, "ul_user_ssAlloc_raru") == 0) {
267+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_ul, MURU_FIXED_UL_TOTAL_USER_CNT);
268+ cnt = hostapd_parse_argument_helper(value, &val);
269+ if (cnt == -1)
270+ goto fail;
271+ if (cnt != ul->user_num)
272+ goto para_fail;
273+ for (i = 0; i < cnt; i++)
274+ ul->usr[i].nss = (u8) val[i];
275+ os_free(val);
276+ muru->cfg_ul |= host_to_le32(MURU_FIXED_USER_UL_NSS);
277+ } else if (os_strcmp(config, "dl_comm_gi") == 0) {
278+ dl->gi = (u8)atoi(value);
279+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_GI);
280+ } else if (os_strcmp(config, "dl_comm_ltf") == 0) {
281+ dl->ltf = (u8)atoi(value);
282+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_LTF);
283+ } else if (os_strcmp(config, "ul_comm_gi_ltf") == 0) {
284+ ul->gi_ltf = (u8)atoi(value);
285+ muru->cfg_ul |= host_to_le32(MURU_FIXED_UL_GILTF);
286+ } else if (os_strcmp(config, "dl_comm_ack_policy") == 0) {
287+ dl->ack_policy = (u8)atoi(value);
288+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_ACK_PLY);
289+ } else if (os_strcmp(config, "dl_comm_toneplan") == 0) {
290+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_dl, MURU_FIXED_DL_BW);
291+ cnt = hostapd_parse_argument_helper(value, &val);
292+ if (cnt == -1)
293+ goto fail;
294+ i = pow(2, dl->bw);
295+ if (cnt != i)
296+ goto para_fail;
297+ for (i = 0; i < cnt; i++)
298+ dl->ru[i] = host_to_le16(val[i]);
299+ os_free(val);
300+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_TONE_PLAN);
developer05f3b2b2024-08-19 19:17:34 +0800301+ } else if (os_strcmp(config, "global_comm_band") == 0) {
302+ comm->band = (u8)atoi(value);
303+ muru->cfg_comm |= host_to_le32(MURU_COMM_BAND);
developer66e89bc2024-04-23 14:50:01 +0800304 } else {
305- return -1;
306+ wpa_printf(MSG_ERROR,
307+ "Unsupported parameter %s for SET_MU", config);
308+ goto fail;
309 }
310+
311+ return os_snprintf(buf, buflen, "OK\n");
312+
313+para_fail:
314+ os_free(val);
315+ wpa_printf(MSG_ERROR, "Incorrect input number\n");
316+fail:
317+ return os_snprintf(buf, buflen, "FAIL\n");
318 }
319
320
developer05f3b2b2024-08-19 19:17:34 +0800321@@ -5290,8 +5475,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
developer66e89bc2024-04-23 14:50:01 +0800322 reply_len = hostapd_ctrl_iface_get_edcca(hapd, buf+10, reply,
323 reply_size);
324 } else if (os_strncmp(buf, "SET_MU ", 7) == 0) {
325- reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 7, reply,
326- reply_size);
327+ reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 7, reply, reply_size);
328 } else if (os_strncmp(buf, "GET_MU", 6) == 0) {
329 reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
330 } else if (os_strncmp(buf, "GET_IBF", 7) == 0) {
developer05f3b2b2024-08-19 19:17:34 +0800331@@ -5317,6 +5501,14 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
developer66e89bc2024-04-23 14:50:01 +0800332 } else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
333 reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
334 reply, reply_size);
335+ } else if (os_strncmp(buf, "set_muru_manual_config=", 23) == 0) {
336+ // Replace first ':' with a single space ' '
337+ char *pos = buf + 23;
338+
339+ pos = os_strchr(pos, ':');
340+ if (pos)
341+ *pos = ' ';
342+ reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 23, reply, reply_size);
343 } else {
344 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
345 reply_len = 16;
346diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
developer05f3b2b2024-08-19 19:17:34 +0800347index f90f4d554..0c51d2ab9 100644
developer66e89bc2024-04-23 14:50:01 +0800348--- a/src/ap/ap_config.h
349+++ b/src/ap/ap_config.h
developer05f3b2b2024-08-19 19:17:34 +0800350@@ -1344,6 +1344,7 @@ struct hostapd_config {
developer66e89bc2024-04-23 14:50:01 +0800351 u8 ibf_enable;
352 u8 dfs_detect_mode;
353 u8 amsdu;
354+ void *muru_config;
355 };
356
357 enum three_wire_mode {
358diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
developer05f3b2b2024-08-19 19:17:34 +0800359index 496fd4263..ccd0cb939 100644
developer66e89bc2024-04-23 14:50:01 +0800360--- a/src/ap/ap_drv_ops.c
361+++ b/src/ap/ap_drv_ops.c
developer05f3b2b2024-08-19 19:17:34 +0800362@@ -1299,11 +1299,11 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value)
developer66e89bc2024-04-23 14:50:01 +0800363 return hapd->driver->get_edcca(hapd->drv_priv, mode, value);
364 }
365
366-int hostapd_drv_mu_ctrl(struct hostapd_data *hapd, u8 mode, u8 val)
367+int hostapd_drv_mu_ctrl(struct hostapd_data *hapd, u8 mode)
368 {
369 if (!hapd->driver || !hapd->driver->mu_ctrl)
370 return 0;
371- return hapd->driver->mu_ctrl(hapd->drv_priv, mode, val);
372+ return hapd->driver->mu_ctrl(hapd->drv_priv, mode, hapd->iconf);
373 }
374
375 int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff)
376diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
developer05f3b2b2024-08-19 19:17:34 +0800377index a949e168d..659154f56 100644
developer66e89bc2024-04-23 14:50:01 +0800378--- a/src/ap/ap_drv_ops.h
379+++ b/src/ap/ap_drv_ops.h
developer05f3b2b2024-08-19 19:17:34 +0800380@@ -156,7 +156,7 @@ int hostapd_drv_configure_edcca_enable(struct hostapd_data *hapd);
developer66e89bc2024-04-23 14:50:01 +0800381 int hostapd_drv_configure_edcca_threshold(struct hostapd_data *hapd,
382 const int *threshold);
383 int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value);
384-int hostapd_drv_mu_ctrl(struct hostapd_data *hapd, u8 mode, u8 val);
385+int hostapd_drv_mu_ctrl(struct hostapd_data *hapd, u8 mode);
386 int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff);
387 int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd);
388 int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
389diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
developer05f3b2b2024-08-19 19:17:34 +0800390index 9e1ba6a21..f06687064 100644
developer66e89bc2024-04-23 14:50:01 +0800391--- a/src/ap/hostapd.c
392+++ b/src/ap/hostapd.c
developer05f3b2b2024-08-19 19:17:34 +0800393@@ -2763,7 +2763,7 @@ dfs_offload:
developer66e89bc2024-04-23 14:50:01 +0800394 if (hostapd_drv_configure_edcca_threshold(hapd,
395 hapd->iconf->edcca_threshold) < 0)
396 goto fail;
397- if (hostapd_drv_mu_ctrl(hapd, MU_CTRL_ONOFF, hapd->iconf->mu_onoff) < 0)
398+ if (hostapd_drv_mu_ctrl(hapd, MU_CTRL_ONOFF) < 0)
399 goto fail;
400 if (hostapd_drv_three_wire_ctrl(hapd) < 0)
401 goto fail;
402diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
developer05f3b2b2024-08-19 19:17:34 +0800403index 34238f098..f0abcb6b1 100644
developer66e89bc2024-04-23 14:50:01 +0800404--- a/src/common/mtk_vendor.h
405+++ b/src/common/mtk_vendor.h
developer05f3b2b2024-08-19 19:17:34 +0800406@@ -202,8 +202,11 @@ enum mtk_vendor_attr_mu_ctrl {
developer66e89bc2024-04-23 14:50:01 +0800407
408 MTK_VENDOR_ATTR_MU_CTRL_ONOFF,
409 MTK_VENDOR_ATTR_MU_CTRL_DUMP,
410- MTK_VENDOR_ATTR_MU_CTRL_OFDMA_MODE,
411- MTK_VENDOR_ATTR_MU_CTRL_OFDMA_VAL,
412+ /**
413+ * The above attrs are also used by connac 2. It is best not to modify the
414+ * above data structure.
415+ */
416+ MTK_VENDOR_ATTR_MU_CTRL_STRUCT,
417
418 /* keep last */
419 NUM_MTK_VENDOR_ATTRS_MU_CTRL,
developer05f3b2b2024-08-19 19:17:34 +0800420@@ -278,8 +281,163 @@ struct amnt_resp_data {
developer66e89bc2024-04-23 14:50:01 +0800421 };
422
423 enum {
424+ MU_CTRL_UPDATE,
425 MU_CTRL_ONOFF,
426- MU_CTRL_DL_USER_CNT,
427- MU_CTRL_UL_USER_CNT,
428 };
429+
430+struct connac3_muru_comm {
431+ u8 pda_pol;
432+ u8 band;
433+ u8 spe_idx;
434+ u8 proc_type;
435+
436+ le16 mlo_ctrl;
437+ u8 sch_type;
438+ u8 ppdu_format;
439+ u8 ac;
440+ u8 _rsv[3];
441+};
442+
443+struct connac3_muru_dl {
444+ u8 user_num;
445+ u8 tx_mode;
446+ u8 bw;
447+ u8 gi;
448+
449+ u8 ltf;
450+ u8 mcs;
451+ u8 dcm;
452+ u8 cmprs;
453+
454+ le16 ru[16];
455+
456+ u8 c26[2];
457+ u8 ack_policy;
458+ u8 tx_power;
459+
460+ le16 mu_ppdu_duration;
461+ u8 agc_disp_order;
462+ u8 _rsv1;
463+
464+ u8 agc_disp_pol;
465+ u8 agc_disp_ratio;
466+ le16 agc_disp_linkMFG;
467+
468+ le16 prmbl_punc_bmp;
469+ u8 _rsv2[2];
470+
471+ struct {
472+ le16 wlan_idx;
473+ u8 ru_alloc_seg;
474+ u8 ru_idx;
475+ u8 ldpc;
476+ u8 nss;
477+ u8 mcs;
478+ u8 mu_group_idx;
479+ u8 vht_groud_id;
480+ u8 vht_up;
481+ u8 he_start_stream;
482+ u8 he_mu_spatial;
483+ le16 tx_power_alpha;
484+ u8 ack_policy;
485+ u8 ru_allo_ps160;
486+ } usr[16];
487+};
488+
489+struct connac3_muru_ul {
490+ u8 user_num;
491+ u8 tx_mode;
492+
493+ u8 ba_type;
494+ u8 _rsv;
495+
496+ u8 bw;
497+ u8 gi_ltf;
498+ le16 ul_len;
499+
500+ le16 trig_cnt;
501+ u8 pad;
502+ u8 trig_type;
503+
504+ le16 trig_intv;
505+ u8 trig_ta[ETH_ALEN];
506+ le16 ul_ru[16];
507+
508+ u8 c26[2];
509+ le16 agc_disp_linkMFG;
510+
511+ u8 agc_disp_mu_len;
512+ u8 agc_disp_pol;
513+ u8 agc_disp_ratio;
514+ u8 agc_disp_pu_idx;
515+
516+ struct {
517+ le16 wlan_idx;
518+ u8 ru_alloc_seg;
519+ u8 ru_idx;
520+ u8 ldpc;
521+ u8 nss;
522+ u8 mcs;
523+ u8 target_rssi;
524+ le32 trig_pkt_size;
525+ u8 ru_allo_ps160;
526+ u8 _rsv2[3];
527+ } usr[16];
528+};
529+
530+struct connac3_muru_dbg {
531+ /* HE TB RX Debug */
532+ le32 rx_hetb_nonsf_en_bitmap;
533+ le32 rx_hetb_cfg[2];
534+};
535+
536+struct connac3_muru {
537+ le32 cfg_comm;
538+ le32 cfg_dl;
539+ le32 cfg_ul;
540+ le32 cfg_dbg;
541+
542+ struct connac3_muru_comm comm;
543+ struct connac3_muru_dl dl;
544+ struct connac3_muru_ul ul;
545+ struct connac3_muru_dbg dbg;
546+};
547+
548+#define MURU_OFDMA_SCH_TYPE_DL BIT(0)
549+#define MURU_OFDMA_SCH_TYPE_UL BIT(1)
550+#define MURU_PPDU_HE_TRIG BIT(2)
551+#define MURU_PPDU_HE_MU BIT(3)
552+
553+/* Common Config */
554+#define MURU_COMM_PPDU_FMT BIT(0)
555+#define MURU_COMM_BAND BIT(2)
556+#define MURU_COMM_WMM BIT(3)
557+#define MURU_COMM_SPE_IDX BIT(4)
558+#define MURU_COMM_SET (MURU_COMM_PPDU_FMT | MURU_COMM_BAND | \
559+ MURU_COMM_WMM | MURU_COMM_SPE_IDX)
560+
561+/* DL Common config */
562+#define MURU_FIXED_DL_BW BIT(0)
563+#define MURU_FIXED_DL_GI BIT(1)
564+#define MURU_FIXED_DL_TONE_PLAN BIT(3)
565+#define MURU_FIXED_DL_TOTAL_USER_CNT BIT(4)
566+#define MURU_FIXED_DL_LTF BIT(5)
567+#define MURU_FIXED_DL_ACK_PLY BIT(9)
568+
569+/* DL Per User Config */
570+#define MURU_FIXED_USER_DL_COD BIT(17)
571+#define MURU_FIXED_USER_DL_MCS BIT(18)
572+#define MURU_FIXED_USER_DL_RU_ALLOC BIT(20)
573+
574+/* UL Common Config */
575+#define MURU_FIXED_UL_TOTAL_USER_CNT BIT(4)
576+#define MURU_FIXED_UL_BW BIT(5)
577+#define MURU_FIXED_UL_GILTF BIT(6)
578+
579+/* UL Per User Config */
580+#define MURU_FIXED_USER_UL_COD BIT(18)
581+#define MURU_FIXED_USER_UL_MCS BIT(19)
582+#define MURU_FIXED_USER_UL_NSS BIT(20)
583+#define MURU_FIXED_USER_UL_RU_ALLOC BIT(21)
584+
585 #endif /* MTK_VENDOR_H */
586diff --git a/src/drivers/driver.h b/src/drivers/driver.h
developer05f3b2b2024-08-19 19:17:34 +0800587index c8910739e..6fc79f659 100644
developer66e89bc2024-04-23 14:50:01 +0800588--- a/src/drivers/driver.h
589+++ b/src/drivers/driver.h
developer05f3b2b2024-08-19 19:17:34 +0800590@@ -5266,7 +5266,7 @@ struct wpa_driver_ops {
developer66e89bc2024-04-23 14:50:01 +0800591 * @priv: Private driver interface data
592 *
593 */
594- int (*mu_ctrl)(void *priv, u8 mode, u8 val);
595+ int (*mu_ctrl)(void *priv, u8 mode, void *config);
596 int (*mu_dump)(void *priv, u8 *mu_onoff);
597
598 /**
599diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
developer05f3b2b2024-08-19 19:17:34 +0800600index da1e6a8ed..8a8f8abe8 100644
developer66e89bc2024-04-23 14:50:01 +0800601--- a/src/drivers/driver_nl80211.c
602+++ b/src/drivers/driver_nl80211.c
developer05f3b2b2024-08-19 19:17:34 +0800603@@ -14007,12 +14007,13 @@ fail:
developer66e89bc2024-04-23 14:50:01 +0800604
605
606 #ifdef CONFIG_IEEE80211AX
607-static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
608+static int nl80211_mu_ctrl(void *priv, u8 mode, void *config)
609 {
610 struct i802_bss *bss = priv;
611 struct wpa_driver_nl80211_data *drv = bss->drv;
612 struct nl_msg *msg;
613 struct nlattr *data;
614+ struct hostapd_config *cfg = config;
615 int ret = -ENOBUFS;
616
617 if (!drv->mtk_mu_vendor_cmd_avail) {
developer05f3b2b2024-08-19 19:17:34 +0800618@@ -14029,17 +14030,16 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
developer66e89bc2024-04-23 14:50:01 +0800619
620 switch (mode) {
621 case MU_CTRL_ONOFF:
622- if (nla_put_u8(msg, MTK_VENDOR_ATTR_MU_CTRL_ONOFF, val))
623- goto fail;
624+ if (nla_put_u8(msg, MTK_VENDOR_ATTR_MU_CTRL_ONOFF, cfg->mu_onoff))
625+ goto fail;
626 break;
627- case MU_CTRL_UL_USER_CNT:
628- case MU_CTRL_DL_USER_CNT:
629- if (nla_put_u8(msg, MTK_VENDOR_ATTR_MU_CTRL_OFDMA_MODE, mode) ||
630- nla_put_u8(msg, MTK_VENDOR_ATTR_MU_CTRL_OFDMA_VAL, val))
631- goto fail;
632+ case MU_CTRL_UPDATE:
633+ if (nla_put(msg, MTK_VENDOR_ATTR_MU_CTRL_STRUCT,
634+ sizeof(struct connac3_muru), cfg->muru_config))
635+ goto fail;
636 break;
637 default:
638- wpa_printf(MSG_ERROR, "nl80211: Wrong mu mode !");
639+ wpa_printf(MSG_ERROR, "nl80211: Wrong mu mode %u!", mode);
640 ret = -EINVAL;
641 goto fail;
642 }
developer05f3b2b2024-08-19 19:17:34 +0800643@@ -14047,9 +14047,8 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
developer66e89bc2024-04-23 14:50:01 +0800644 nla_nest_end(msg, data);
645
646 ret = send_and_recv_cmd(drv, msg);
647- if(ret){
648+ if (ret)
649 wpa_printf(MSG_ERROR, "Failed to set mu_ctrl. ret=%d (%s)", ret, strerror(-ret));
650- }
651 return ret;
652
653 fail:
654--
developer05f3b2b2024-08-19 19:17:34 +08006552.18.0
developer66e89bc2024-04-23 14:50:01 +0800656