blob: 19a3c79c0052632c2d5d18e3f153d7d007103370 [file] [log] [blame]
developerbddc9db2023-09-11 13:34:36 +08001From 7f1a652729514a0f9a885be30185810c18110c4d Mon Sep 17 00:00:00 2001
developer327aa322023-07-10 13:49:56 +08002From: Howard Hsu <howard-yh.hsu@mediatek.com>
3Date: Sat, 3 Jun 2023 17:12:15 +0800
developerbddc9db2023-09-11 13:34:36 +08004Subject: [PATCH 25/40] hostapd: mtk: add connac3 PHY MURU manual mode config
5 support
developer327aa322023-07-10 13:49:56 +08006
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.
38---
39 hostapd/ctrl_iface.c | 235 +++++++++++++++++++++++++++++++----
40 src/ap/ap_config.h | 1 +
41 src/ap/ap_drv_ops.c | 4 +-
42 src/ap/ap_drv_ops.h | 2 +-
43 src/ap/hostapd.c | 2 +-
44 src/common/mtk_vendor.h | 166 ++++++++++++++++++++++++-
45 src/drivers/driver.h | 2 +-
46 src/drivers/driver_nl80211.c | 21 ++--
47 8 files changed, 390 insertions(+), 43 deletions(-)
48
49diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
developerbddc9db2023-09-11 13:34:36 +080050index f36c138..c288352 100644
developer327aa322023-07-10 13:49:56 +080051--- a/hostapd/ctrl_iface.c
52+++ b/hostapd/ctrl_iface.c
developerbddc9db2023-09-11 13:34:36 +080053@@ -3500,22 +3500,61 @@ hostapd_ctrl_iface_get_edcca(struct hostapd_data *hapd, char *cmd, char *buf,
developer327aa322023-07-10 13:49:56 +080054 }
55 }
56
57+static int
58+hostapd_parse_argument_helper(char *value, u16 **ptr_input)
59+{
60+#define MAX_MU_CTRL_NUM 17
61+
62+ u16 *input;
63+ char *endptr;
64+ int cnt = 0;
65+
66+ input = os_zalloc(MAX_MU_CTRL_NUM * sizeof(u16));
67+ if (input == NULL) {
68+ wpa_printf(MSG_ERROR, "Failed to allocate memory.\n");
69+ return -1;
70+ }
71+ while (value) {
72+ u8 val = strtol(value, &endptr, 10);
73+
74+ if (value != endptr) {
75+ input[cnt++] = val;
76+ value = os_strchr(endptr, ':');
77+ if (value)
78+ value++;
79+ } else {
80+ break;
81+ }
82+ }
83
84+ *ptr_input = input;
85+ return cnt;
86+}
87+
88+#define MURU_CFG_DEPENDENCE_CHECK(_val, _mask) do { \
89+ if ((le_to_host32(_val) & (_mask)) != _mask) { \
90+ wpa_printf(MSG_ERROR, "Set %s first\n", #_mask); \
91+ goto fail; \
92+ } \
93+ } while(0)
94 static int
95 hostapd_ctrl_iface_set_mu(struct hostapd_data *hapd, char *cmd,
96- char *buf, size_t buflen)
97+ char *buf, size_t buflen)
98 {
99 char *pos, *config, *value;
100- u8 mode;
101+ u8 i;
102+ int cnt = 0, ret;
103+ u16 *val;
104+ struct connac3_muru *muru;
105+ struct connac3_muru_dl *dl;
106+ struct connac3_muru_ul *ul;
107+ struct connac3_muru_comm *comm;
108
109 config = cmd;
110 pos = os_strchr(config, ' ');
111- if (pos == NULL)
112- return -1;
113- *pos++ = '\0';
114+ if (pos != NULL)
115+ *pos++ = '\0';
116
117- if(pos == NULL)
118- return -1;
119 value = pos;
120
121 if (os_strcmp(config, "onoff") == 0) {
developerbddc9db2023-09-11 13:34:36 +0800122@@ -3525,24 +3564,167 @@ hostapd_ctrl_iface_set_mu(struct hostapd_data *hapd, char *cmd,
developer327aa322023-07-10 13:49:56 +0800123 return -1;
124 }
125 hapd->iconf->mu_onoff = (u8) mu;
126- mode = MU_CTRL_ONOFF;
127- } else if (os_strcmp(config, "ul_user_cnt") == 0) {
128- mode = MU_CTRL_UL_USER_CNT;
129- wpa_printf(MSG_ERROR, "ul_user_cnt:%d\n", (u8)atoi(value));
130- } else if (os_strcmp(config, "dl_user_cnt") == 0) {
131- mode = MU_CTRL_DL_USER_CNT;
132- wpa_printf(MSG_ERROR, "dl_user_cnt:%d\n", (u8)atoi(value));
133- } else {
134- wpa_printf(MSG_ERROR,
135- "Unsupported parameter %s for SET_MU", config);
136- return -1;
137+
138+ if (hostapd_drv_mu_ctrl(hapd, MU_CTRL_ONOFF) == 0)
139+ return os_snprintf(buf, buflen, "OK\n");
140+ else
141+ goto fail;
142 }
143
144- if(hostapd_drv_mu_ctrl(hapd, mode, (u8)atoi(value)) == 0) {
145- return os_snprintf(buf, buflen, "OK\n");
146+ if (hapd->iconf->muru_config == NULL)
147+ hapd->iconf->muru_config = os_zalloc(sizeof(struct connac3_muru));
148+
149+ muru = hapd->iconf->muru_config;
150+ dl = &muru->dl;
151+ ul = &muru->ul;
152+ comm = &muru->comm;
153+
154+ if (os_strncmp(config, "update", 6) == 0) {
155+ ret = hostapd_drv_mu_ctrl(hapd, MU_CTRL_UPDATE);
156+
157+ os_free(hapd->iconf->muru_config);
158+ hapd->iconf->muru_config = NULL;
159+
160+ if (ret)
161+ goto fail;
162+ } else if (os_strcmp(config, "ul_comm_user_cnt") == 0) {
163+ ul->user_num = (u8)atoi(value);
164+ comm->ppdu_format |= MURU_PPDU_HE_TRIG;
165+ comm->sch_type |= MURU_OFDMA_SCH_TYPE_UL;
166+ muru->cfg_comm |= host_to_le32(MURU_COMM_SET);
167+ muru->cfg_ul |= host_to_le32(MURU_FIXED_UL_TOTAL_USER_CNT);
168+ } else if (os_strcmp(config, "dl_comm_user_cnt") == 0) {
169+ dl->user_num = (u8)atoi(value);
170+ comm->ppdu_format |= MURU_PPDU_HE_MU;
171+ comm->sch_type |= MURU_OFDMA_SCH_TYPE_DL;
172+ muru->cfg_comm |= host_to_le32(MURU_COMM_SET);
173+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_TOTAL_USER_CNT);
174+ } else if (os_strcmp(config, "dl_comm_bw") == 0) {
175+ dl->bw = (u8)atoi(value);
176+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_BW);
177+ } else if (os_strcmp(config, "ul_comm_bw") == 0) {
178+ ul->bw = (u8)atoi(value);
179+ muru->cfg_ul |= host_to_le32(MURU_FIXED_UL_BW);
180+ } else if (os_strcmp(config, "dl_user_ru_alloc") == 0) {
181+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_dl, MURU_FIXED_DL_TOTAL_USER_CNT);
182+ cnt = hostapd_parse_argument_helper(value, &val);
183+ if (cnt == -1)
184+ goto fail;
185+ if (cnt != (dl->user_num * 2))
186+ goto para_fail;
187+ for (i = 0; i < dl->user_num; i++) {
188+ dl->usr[i].ru_alloc_seg = (val[2 * i] & 0x1);
189+ dl->usr[i].ru_allo_ps160 = ((val[2 * i] & 0x2) >> 1);
developer9a587882023-07-17 11:11:44 +0800190+ dl->usr[i].ru_idx = val[(2 * i) + 1];
developer327aa322023-07-10 13:49:56 +0800191+ }
192+ os_free(val);
193+ muru->cfg_dl |= host_to_le32(MURU_FIXED_USER_DL_RU_ALLOC);
194+ } else if (os_strcmp(config, "ul_user_ru_alloc") == 0) {
195+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_ul, MURU_FIXED_UL_TOTAL_USER_CNT);
196+ cnt = hostapd_parse_argument_helper(value, &val);
197+ if (cnt == -1)
198+ goto fail;
199+ if (cnt != (ul->user_num * 2))
200+ goto para_fail;
201+ for (i = 0; i < ul->user_num; i++) {
202+ ul->usr[i].ru_alloc_seg = (val[2 * i] & 0x1);
203+ ul->usr[i].ru_allo_ps160 = ((val[2 * i] & 0x2) >> 1);
developer9a587882023-07-17 11:11:44 +0800204+ ul->usr[i].ru_idx = val[(2 * i) + 1];
developer327aa322023-07-10 13:49:56 +0800205+ }
206+ os_free(val);
207+ muru->cfg_ul |= host_to_le32(MURU_FIXED_USER_UL_RU_ALLOC);
208+ } else if (os_strcmp(config, "dl_user_mcs") == 0) {
209+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_dl, MURU_FIXED_DL_TOTAL_USER_CNT);
210+ cnt = hostapd_parse_argument_helper(value, &val);
211+ if (cnt == -1)
212+ goto fail;
213+ if (cnt != dl->user_num)
214+ goto para_fail;
215+ for (i = 0; i < cnt; i++)
216+ dl->usr[i].mcs = (u8) val[i];
217+ os_free(val);
218+ muru->cfg_dl |= host_to_le32(MURU_FIXED_USER_DL_MCS);
219+ } else if (os_strcmp(config, "ul_user_mcs") == 0) {
220+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_ul, MURU_FIXED_UL_TOTAL_USER_CNT);
221+ cnt = hostapd_parse_argument_helper(value, &val);
222+ if (cnt == -1)
223+ goto fail;
224+ if (cnt != ul->user_num)
225+ goto para_fail;
226+ for (i = 0; i < cnt; i++)
227+ ul->usr[i].mcs = (u8) val[i];
228+ os_free(val);
229+ muru->cfg_ul |= host_to_le32(MURU_FIXED_USER_UL_MCS);
230+ } else if (os_strcmp(config, "dl_user_cod") == 0) {
231+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_dl, MURU_FIXED_DL_TOTAL_USER_CNT);
232+ cnt = hostapd_parse_argument_helper(value, &val);
233+ if (cnt == -1)
234+ goto fail;
235+ if (cnt != dl->user_num)
236+ goto para_fail;
237+ for (i = 0; i < cnt; i++)
238+ dl->usr[i].ldpc = (u8) val[i];
239+ os_free(val);
240+ muru->cfg_dl |= host_to_le32(MURU_FIXED_USER_DL_COD);
241+ } else if (os_strcmp(config, "ul_user_cod") == 0) {
242+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_ul, MURU_FIXED_UL_TOTAL_USER_CNT);
243+ cnt = hostapd_parse_argument_helper(value, &val);
244+ if (cnt == -1)
245+ goto fail;
246+ if (cnt != ul->user_num)
247+ goto para_fail;
248+ for (i = 0; i < cnt; i++)
249+ ul->usr[i].ldpc = (u8) val[i];
250+ os_free(val);
251+ muru->cfg_ul |= host_to_le32(MURU_FIXED_USER_UL_COD);
252+ } else if (os_strcmp(config, "ul_user_ssAlloc_raru") == 0) {
253+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_ul, MURU_FIXED_UL_TOTAL_USER_CNT);
254+ cnt = hostapd_parse_argument_helper(value, &val);
255+ if (cnt == -1)
256+ goto fail;
257+ if (cnt != ul->user_num)
258+ goto para_fail;
259+ for (i = 0; i < cnt; i++)
260+ ul->usr[i].nss = (u8) val[i];
261+ os_free(val);
262+ muru->cfg_ul |= host_to_le32(MURU_FIXED_USER_UL_NSS);
263+ } else if (os_strcmp(config, "dl_comm_gi") == 0) {
264+ dl->gi = (u8)atoi(value);
265+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_GI);
266+ } else if (os_strcmp(config, "dl_comm_ltf") == 0) {
267+ dl->ltf = (u8)atoi(value);
268+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_LTF);
269+ } else if (os_strcmp(config, "ul_comm_gi_ltf") == 0) {
270+ ul->gi_ltf = (u8)atoi(value);
271+ muru->cfg_ul |= host_to_le32(MURU_FIXED_UL_GILTF);
272+ } else if (os_strcmp(config, "dl_comm_ack_policy") == 0) {
273+ dl->ack_policy = (u8)atoi(value);
274+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_ACK_PLY);
275+ } else if (os_strcmp(config, "dl_comm_toneplan") == 0) {
276+ MURU_CFG_DEPENDENCE_CHECK(muru->cfg_dl, MURU_FIXED_DL_BW);
277+ cnt = hostapd_parse_argument_helper(value, &val);
278+ if (cnt == -1)
279+ goto fail;
280+ i = pow(2, dl->bw);
281+ if (cnt != i)
282+ goto para_fail;
283+ for (i = 0; i < cnt; i++)
284+ dl->ru[i] = host_to_le16(val[i]);
285+ os_free(val);
286+ muru->cfg_dl |= host_to_le32(MURU_FIXED_DL_TONE_PLAN);
287 } else {
288- return -1;
289+ wpa_printf(MSG_ERROR,
290+ "Unsupported parameter %s for SET_MU", config);
291+ goto fail;
292 }
293+
294+ return os_snprintf(buf, buflen, "OK\n");
295+
296+para_fail:
297+ os_free(val);
298+ wpa_printf(MSG_ERROR, "Incorrect input number\n");
299+fail:
300+ return os_snprintf(buf, buflen, "FAIL\n");
301 }
302
303
developerbddc9db2023-09-11 13:34:36 +0800304@@ -4534,8 +4716,7 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
developer327aa322023-07-10 13:49:56 +0800305 reply_len = hostapd_ctrl_iface_get_edcca(hapd, buf+10, reply,
306 reply_size);
307 } else if (os_strncmp(buf, "SET_MU ", 7) == 0) {
308- reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 7, reply,
309- reply_size);
310+ reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 7, reply, reply_size);
311 } else if (os_strncmp(buf, "GET_MU", 6) == 0) {
312 reply_len = hostapd_ctrl_iface_get_mu(hapd, reply, reply_size);
313 } else if (os_strncmp(buf, "GET_IBF", 7) == 0) {
developerbddc9db2023-09-11 13:34:36 +0800314@@ -4561,6 +4742,14 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
developer327aa322023-07-10 13:49:56 +0800315 } else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
316 reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
317 reply, reply_size);
318+ } else if (os_strncmp(buf, "set_muru_manual_config=", 23) == 0) {
319+ // Replace first ':' with a single space ' '
320+ char *pos = buf + 23;
321+
322+ pos = os_strchr(pos, ':');
323+ if (pos)
324+ *pos = ' ';
325+ reply_len = hostapd_ctrl_iface_set_mu(hapd, buf + 23, reply, reply_size);
326 } else {
327 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
328 reply_len = 16;
329diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
developerbddc9db2023-09-11 13:34:36 +0800330index b329e81..d43f1a6 100644
developer327aa322023-07-10 13:49:56 +0800331--- a/src/ap/ap_config.h
332+++ b/src/ap/ap_config.h
developerbddc9db2023-09-11 13:34:36 +0800333@@ -1200,6 +1200,7 @@ struct hostapd_config {
developer327aa322023-07-10 13:49:56 +0800334 u8 ibf_enable;
335 u8 dfs_detect_mode;
336 u8 amsdu;
337+ void *muru_config;
338 };
339
340 enum three_wire_mode {
341diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
developer9a587882023-07-17 11:11:44 +0800342index 0aec9e9..721bfa0 100644
developer327aa322023-07-10 13:49:56 +0800343--- a/src/ap/ap_drv_ops.c
344+++ b/src/ap/ap_drv_ops.c
developer9a587882023-07-17 11:11:44 +0800345@@ -1162,11 +1162,11 @@ int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value)
developer327aa322023-07-10 13:49:56 +0800346 return hapd->driver->get_edcca(hapd->drv_priv, mode, value);
347 }
348
349-int hostapd_drv_mu_ctrl(struct hostapd_data *hapd, u8 mode, u8 val)
350+int hostapd_drv_mu_ctrl(struct hostapd_data *hapd, u8 mode)
351 {
352 if (!hapd->driver || !hapd->driver->mu_ctrl)
353 return 0;
354- return hapd->driver->mu_ctrl(hapd->drv_priv, mode, val);
355+ return hapd->driver->mu_ctrl(hapd->drv_priv, mode, hapd->iconf);
356 }
357
358 int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff)
359diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
developer9a587882023-07-17 11:11:44 +0800360index 5dd701e..741fdab 100644
developer327aa322023-07-10 13:49:56 +0800361--- a/src/ap/ap_drv_ops.h
362+++ b/src/ap/ap_drv_ops.h
363@@ -148,7 +148,7 @@ int hostapd_drv_configure_edcca_enable(struct hostapd_data *hapd);
364 int hostapd_drv_configure_edcca_threshold(struct hostapd_data *hapd,
365 const int *threshold);
366 int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value);
367-int hostapd_drv_mu_ctrl(struct hostapd_data *hapd, u8 mode, u8 val);
368+int hostapd_drv_mu_ctrl(struct hostapd_data *hapd, u8 mode);
369 int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff);
370 int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd);
371 int hostapd_drv_ibf_ctrl(struct hostapd_data *hapd);
372diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
developerbddc9db2023-09-11 13:34:36 +0800373index 25ae08f..0dc86bf 100644
developer327aa322023-07-10 13:49:56 +0800374--- a/src/ap/hostapd.c
375+++ b/src/ap/hostapd.c
developerbddc9db2023-09-11 13:34:36 +0800376@@ -2518,7 +2518,7 @@ dfs_offload:
developer327aa322023-07-10 13:49:56 +0800377 if (hostapd_drv_configure_edcca_threshold(hapd,
378 hapd->iconf->edcca_threshold) < 0)
379 goto fail;
380- if (hostapd_drv_mu_ctrl(hapd, MU_CTRL_ONOFF, hapd->iconf->mu_onoff) < 0)
381+ if (hostapd_drv_mu_ctrl(hapd, MU_CTRL_ONOFF) < 0)
382 goto fail;
383 if (hostapd_drv_three_wire_ctrl(hapd) < 0)
384 goto fail;
385diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
developer9a587882023-07-17 11:11:44 +0800386index 99371bf..e140de6 100644
developer327aa322023-07-10 13:49:56 +0800387--- a/src/common/mtk_vendor.h
388+++ b/src/common/mtk_vendor.h
developer9a587882023-07-17 11:11:44 +0800389@@ -199,8 +199,11 @@ enum mtk_vendor_attr_mu_ctrl {
developer327aa322023-07-10 13:49:56 +0800390
391 MTK_VENDOR_ATTR_MU_CTRL_ONOFF,
392 MTK_VENDOR_ATTR_MU_CTRL_DUMP,
393- MTK_VENDOR_ATTR_MU_CTRL_OFDMA_MODE,
394- MTK_VENDOR_ATTR_MU_CTRL_OFDMA_VAL,
395+ /**
396+ * The above attrs are also used by connac 2. It is best not to modify the
397+ * above data structure.
398+ */
399+ MTK_VENDOR_ATTR_MU_CTRL_STRUCT,
400
401 /* keep last */
402 NUM_MTK_VENDOR_ATTRS_MU_CTRL,
developer9a587882023-07-17 11:11:44 +0800403@@ -275,8 +278,163 @@ struct amnt_resp_data {
developer327aa322023-07-10 13:49:56 +0800404 };
405
406 enum {
407+ MU_CTRL_UPDATE,
408 MU_CTRL_ONOFF,
409- MU_CTRL_DL_USER_CNT,
410- MU_CTRL_UL_USER_CNT,
411 };
412+
413+struct connac3_muru_comm {
414+ u8 pda_pol;
415+ u8 band;
416+ u8 spe_idx;
417+ u8 proc_type;
418+
419+ le16 mlo_ctrl;
420+ u8 sch_type;
421+ u8 ppdu_format;
422+ u8 ac;
423+ u8 _rsv[3];
424+};
425+
426+struct connac3_muru_dl {
427+ u8 user_num;
428+ u8 tx_mode;
429+ u8 bw;
430+ u8 gi;
431+
432+ u8 ltf;
433+ u8 mcs;
434+ u8 dcm;
435+ u8 cmprs;
436+
437+ le16 ru[16];
438+
439+ u8 c26[2];
440+ u8 ack_policy;
441+ u8 tx_power;
442+
443+ le16 mu_ppdu_duration;
444+ u8 agc_disp_order;
445+ u8 _rsv1;
446+
447+ u8 agc_disp_pol;
448+ u8 agc_disp_ratio;
449+ le16 agc_disp_linkMFG;
450+
451+ le16 prmbl_punc_bmp;
452+ u8 _rsv2[2];
453+
454+ struct {
455+ le16 wlan_idx;
456+ u8 ru_alloc_seg;
457+ u8 ru_idx;
458+ u8 ldpc;
459+ u8 nss;
460+ u8 mcs;
461+ u8 mu_group_idx;
462+ u8 vht_groud_id;
463+ u8 vht_up;
464+ u8 he_start_stream;
465+ u8 he_mu_spatial;
466+ le16 tx_power_alpha;
467+ u8 ack_policy;
468+ u8 ru_allo_ps160;
469+ } usr[16];
470+};
471+
472+struct connac3_muru_ul {
473+ u8 user_num;
474+ u8 tx_mode;
475+
476+ u8 ba_type;
477+ u8 _rsv;
478+
479+ u8 bw;
480+ u8 gi_ltf;
481+ le16 ul_len;
482+
483+ le16 trig_cnt;
484+ u8 pad;
485+ u8 trig_type;
486+
487+ le16 trig_intv;
488+ u8 trig_ta[ETH_ALEN];
489+ le16 ul_ru[16];
490+
491+ u8 c26[2];
492+ le16 agc_disp_linkMFG;
493+
494+ u8 agc_disp_mu_len;
495+ u8 agc_disp_pol;
496+ u8 agc_disp_ratio;
497+ u8 agc_disp_pu_idx;
498+
499+ struct {
500+ le16 wlan_idx;
501+ u8 ru_alloc_seg;
502+ u8 ru_idx;
503+ u8 ldpc;
504+ u8 nss;
505+ u8 mcs;
506+ u8 target_rssi;
507+ le32 trig_pkt_size;
508+ u8 ru_allo_ps160;
509+ u8 _rsv2[3];
510+ } usr[16];
511+};
512+
513+struct connac3_muru_dbg {
514+ /* HE TB RX Debug */
515+ le32 rx_hetb_nonsf_en_bitmap;
516+ le32 rx_hetb_cfg[2];
517+};
518+
519+struct connac3_muru {
520+ le32 cfg_comm;
521+ le32 cfg_dl;
522+ le32 cfg_ul;
523+ le32 cfg_dbg;
524+
525+ struct connac3_muru_comm comm;
526+ struct connac3_muru_dl dl;
527+ struct connac3_muru_ul ul;
528+ struct connac3_muru_dbg dbg;
529+};
530+
531+#define MURU_OFDMA_SCH_TYPE_DL BIT(0)
532+#define MURU_OFDMA_SCH_TYPE_UL BIT(1)
533+#define MURU_PPDU_HE_TRIG BIT(2)
534+#define MURU_PPDU_HE_MU BIT(3)
535+
536+/* Common Config */
537+#define MURU_COMM_PPDU_FMT BIT(0)
538+#define MURU_COMM_BAND BIT(2)
539+#define MURU_COMM_WMM BIT(3)
540+#define MURU_COMM_SPE_IDX BIT(4)
541+#define MURU_COMM_SET (MURU_COMM_PPDU_FMT | MURU_COMM_BAND | \
542+ MURU_COMM_WMM | MURU_COMM_SPE_IDX)
543+
544+/* DL Common config */
545+#define MURU_FIXED_DL_BW BIT(0)
546+#define MURU_FIXED_DL_GI BIT(1)
547+#define MURU_FIXED_DL_TONE_PLAN BIT(3)
548+#define MURU_FIXED_DL_TOTAL_USER_CNT BIT(4)
549+#define MURU_FIXED_DL_LTF BIT(5)
550+#define MURU_FIXED_DL_ACK_PLY BIT(9)
551+
552+/* DL Per User Config */
553+#define MURU_FIXED_USER_DL_COD BIT(17)
554+#define MURU_FIXED_USER_DL_MCS BIT(18)
555+#define MURU_FIXED_USER_DL_RU_ALLOC BIT(20)
556+
557+/* UL Common Config */
558+#define MURU_FIXED_UL_TOTAL_USER_CNT BIT(4)
559+#define MURU_FIXED_UL_BW BIT(5)
560+#define MURU_FIXED_UL_GILTF BIT(6)
561+
562+/* UL Per User Config */
563+#define MURU_FIXED_USER_UL_COD BIT(18)
564+#define MURU_FIXED_USER_UL_MCS BIT(19)
565+#define MURU_FIXED_USER_UL_NSS BIT(20)
566+#define MURU_FIXED_USER_UL_RU_ALLOC BIT(21)
567+
568 #endif /* MTK_VENDOR_H */
569diff --git a/src/drivers/driver.h b/src/drivers/driver.h
developer9a587882023-07-17 11:11:44 +0800570index 84387a6..9ec0e96 100644
developer327aa322023-07-10 13:49:56 +0800571--- a/src/drivers/driver.h
572+++ b/src/drivers/driver.h
developer9a587882023-07-17 11:11:44 +0800573@@ -5100,7 +5100,7 @@ struct wpa_driver_ops {
developer327aa322023-07-10 13:49:56 +0800574 * @priv: Private driver interface data
575 *
576 */
577- int (*mu_ctrl)(void *priv, u8 mode, u8 val);
578+ int (*mu_ctrl)(void *priv, u8 mode, void *config);
579 int (*mu_dump)(void *priv, u8 *mu_onoff);
580
581 /**
582diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
developerbddc9db2023-09-11 13:34:36 +0800583index b682620..22c56f9 100644
developer327aa322023-07-10 13:49:56 +0800584--- a/src/drivers/driver_nl80211.c
585+++ b/src/drivers/driver_nl80211.c
developerbddc9db2023-09-11 13:34:36 +0800586@@ -13562,12 +13562,13 @@ fail:
developer327aa322023-07-10 13:49:56 +0800587
588
589 #ifdef CONFIG_IEEE80211AX
590-static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
591+static int nl80211_mu_ctrl(void *priv, u8 mode, void *config)
592 {
593 struct i802_bss *bss = priv;
594 struct wpa_driver_nl80211_data *drv = bss->drv;
595 struct nl_msg *msg;
596 struct nlattr *data;
597+ struct hostapd_config *cfg = config;
598 int ret = -ENOBUFS;
599
600 if (!drv->mtk_mu_vendor_cmd_avail) {
developerbddc9db2023-09-11 13:34:36 +0800601@@ -13584,17 +13585,16 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
developer327aa322023-07-10 13:49:56 +0800602
603 switch (mode) {
604 case MU_CTRL_ONOFF:
605- if (nla_put_u8(msg, MTK_VENDOR_ATTR_MU_CTRL_ONOFF, val))
606- goto fail;
607+ if (nla_put_u8(msg, MTK_VENDOR_ATTR_MU_CTRL_ONOFF, cfg->mu_onoff))
608+ goto fail;
609 break;
610- case MU_CTRL_UL_USER_CNT:
611- case MU_CTRL_DL_USER_CNT:
612- if (nla_put_u8(msg, MTK_VENDOR_ATTR_MU_CTRL_OFDMA_MODE, mode) ||
613- nla_put_u8(msg, MTK_VENDOR_ATTR_MU_CTRL_OFDMA_VAL, val))
614- goto fail;
615+ case MU_CTRL_UPDATE:
616+ if (nla_put(msg, MTK_VENDOR_ATTR_MU_CTRL_STRUCT,
617+ sizeof(struct connac3_muru), cfg->muru_config))
618+ goto fail;
619 break;
620 default:
621- wpa_printf(MSG_ERROR, "nl80211: Wrong mu mode !");
622+ wpa_printf(MSG_ERROR, "nl80211: Wrong mu mode %u!", mode);
623 ret = -EINVAL;
624 goto fail;
625 }
developerbddc9db2023-09-11 13:34:36 +0800626@@ -13602,9 +13602,8 @@ static int nl80211_mu_ctrl(void *priv, u8 mode, u8 val)
developer327aa322023-07-10 13:49:56 +0800627 nla_nest_end(msg, data);
628
629 ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
630- if(ret){
631+ if (ret)
632 wpa_printf(MSG_ERROR, "Failed to set mu_ctrl. ret=%d (%s)", ret, strerror(-ret));
633- }
634 return ret;
635
636 fail:
637--
6382.18.0
639