blob: 420137907b9ec705a53fa9f36cd86806072e8cb0 [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From 4c0dd29eb15b2cef5cf5256459a19d59e5c98adc Mon Sep 17 00:00:00 2001
2From: Allen Ye <allen.ye@mediatek.com>
3Date: Fri, 22 Dec 2023 18:09:20 +0800
4Subject: [PATCH 120/126] mtk: hostapd: Add txpower vendor command
5
6Porting and refactor from wifi6 power vendor cmd. Add lpi psd control,
7sku index and duplicate mode enhancement.
8
9Signed-off-by: Allen Ye <allen.ye@mediatek.com>
10---
11 hostapd/config_file.c | 8 +++++
12 src/ap/ap_config.c | 4 +++
13 src/ap/ap_config.h | 3 ++
14 src/ap/ap_drv_ops.c | 16 +++++++++
15 src/ap/ap_drv_ops.h | 1 +
16 src/ap/hostapd.c | 2 ++
17 src/ap/ieee802_11_he.c | 3 ++
18 src/common/mtk_vendor.h | 15 +++++++++
19 src/drivers/driver.h | 10 ++++++
20 src/drivers/driver_nl80211.c | 55 +++++++++++++++++++++++++++++++
21 src/drivers/driver_nl80211.h | 1 +
22 src/drivers/driver_nl80211_capa.c | 3 ++
23 12 files changed, 121 insertions(+)
24
25diff --git a/hostapd/config_file.c b/hostapd/config_file.c
26index f7bfc357a..944669270 100644
27--- a/hostapd/config_file.c
28+++ b/hostapd/config_file.c
29@@ -5570,6 +5570,14 @@ static int hostapd_config_fill(struct hostapd_config *conf,
30 return 1;
31 }
32 conf->band_idx = (u8) val;
33+ } else if (os_strcmp(buf, "lpi_psd") == 0) {
34+ u8 en = strtol(pos, NULL, 10);
35+ conf->lpi_psd = !!en;
36+ } else if (os_strcmp(buf, "sku_idx") == 0) {
37+ conf->sku_idx = strtol(pos, NULL, 10);
38+ } else if (os_strcmp(buf, "lpi_bcn_enhance") == 0) {
39+ u8 en = strtol(pos, NULL, 10);
40+ conf->lpi_bcn_enhance = !!en;
41 } else {
42 wpa_printf(MSG_ERROR,
43 "Line %d: unknown configuration item '%s'",
44diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
45index 4528df823..bb5ec78a1 100644
46--- a/src/ap/ap_config.c
47+++ b/src/ap/ap_config.c
48@@ -315,6 +315,10 @@ struct hostapd_config * hostapd_config_defaults(void)
49 conf->pp_mode = PP_FW_MODE;
50 conf->band_idx = 255;
51
52+ conf->lpi_psd = 0;
53+ conf->sku_idx = 0;
54+ conf->lpi_bcn_enhance = 0;
55+
56 hostapd_set_and_check_bw320_offset(conf, 0);
57
58 return conf;
59diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
60index 9c3a28cf4..ea8507cea 100644
61--- a/src/ap/ap_config.h
62+++ b/src/ap/ap_config.h
63@@ -1356,6 +1356,9 @@ struct hostapd_config {
64 void *muru_config;
65 u8 pp_mode;
66 u8 band_idx;
67+ u8 lpi_psd;
68+ u8 sku_idx;
69+ u8 lpi_bcn_enhance;
70 };
71
72 enum three_wire_mode {
73diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
74index a25a67cdd..2f53c518f 100644
75--- a/src/ap/ap_drv_ops.c
76+++ b/src/ap/ap_drv_ops.c
77@@ -1391,6 +1391,22 @@ int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd, u64 *aval_colo
78 return hapd->driver->get_aval_color_bmp(hapd->drv_priv, aval_color_bmp);
79 }
80
81+int hostapd_drv_txpower_ctrl(struct hostapd_data *hapd)
82+{
83+ s8 link_id = -1;
84+
85+ if (!hapd->driver || !hapd->driver->txpower_ctrl)
86+ return 0;
87+
88+ if (hapd->conf->mld_ap)
89+ link_id = hapd->mld_link_id;
90+
91+ return hapd->driver->txpower_ctrl(hapd->drv_priv, hapd->iconf->lpi_psd,
92+ hapd->iconf->sku_idx,
93+ hapd->iconf->lpi_bcn_enhance,
94+ link_id);
95+}
96+
97 int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value)
98 {
99 s8 link_id = -1;
100diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
101index 7f108bc1d..a8c60b6f6 100644
102--- a/src/ap/ap_drv_ops.h
103+++ b/src/ap/ap_drv_ops.h
104@@ -167,6 +167,7 @@ int hostapd_drv_amsdu_ctrl(struct hostapd_data *hapd);
105 int hostapd_drv_amsdu_dump(struct hostapd_data *hapd, u8 *amsdu);
106 int hostapd_drv_get_aval_bss_color_bmp(struct hostapd_data *hapd,
107 u64 *aval_color_bmp);
108+int hostapd_drv_txpower_ctrl(struct hostapd_data *hapd);
109 int hostapd_drv_ap_wireless(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
110 int hostapd_drv_ap_rfeatures(struct hostapd_data *hapd, u8 sub_vendor_id, int value);
111 int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
112diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
113index 9388f6070..6f7f13f9f 100644
114--- a/src/ap/hostapd.c
115+++ b/src/ap/hostapd.c
116@@ -2879,6 +2879,8 @@ dfs_offload:
117 goto fail;
118 if (hostapd_drv_amsdu_ctrl(hapd) < 0)
119 goto fail;
120+ if (hostapd_drv_txpower_ctrl(hapd) < 0)
121+ goto fail;
122
123 wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
124 iface->bss[0]->conf->iface);
125diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
126index 3b6b2041c..f3a5679a0 100644
127--- a/src/ap/ieee802_11_he.c
128+++ b/src/ap/ieee802_11_he.c
129@@ -264,6 +264,9 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid)
130 else
131 control = center_idx_to_bw_6ghz(seg0);
132
133+ if (hapd->iconf->lpi_bcn_enhance)
134+ control |= HE_6GHZ_OPER_INFO_CTRL_DUP_BEACON;
135+
136 control |= hapd->iconf->he_6ghz_reg_pwr_type <<
137 HE_6GHZ_OPER_INFO_CTRL_REG_INFO_SHIFT;
138
139diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
140index 933f0099d..6d75d39c2 100644
141--- a/src/common/mtk_vendor.h
142+++ b/src/common/mtk_vendor.h
143@@ -19,6 +19,7 @@ enum mtk_nl80211_vendor_subcmds {
144 MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL = 0xcb,
145 MTK_NL80211_VENDOR_SUBCMD_PP_CTRL = 0xcc,
146 MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL = 0xcd,
147+ MTK_NL80211_VENDOR_SUBCMD_TXPOWER_CTRL = 0xce,
148 MTK_NL80211_VENDOR_SUBCMD_EML_CTRL = 0xd3,
149 };
150
151@@ -310,6 +311,20 @@ enum mtk_vendor_attr_eml_ctrl {
152 NUM_MTK_VENDOR_ATTRS_EML_CTRL -1
153 };
154
155+enum mtk_vendor_attr_txpower_ctrl {
156+ MTK_VENDOR_ATTR_TXPOWER_CTRL_UNSPEC,
157+
158+ MTK_VENDOR_ATTR_TXPOWER_CTRL_LPI_PSD,
159+ MTK_VENDOR_ATTR_TXPOWER_CTRL_SKU_IDX,
160+ MTK_VENDOR_ATTR_TXPOWER_CTRL_LPI_BCN_ENHANCE,
161+ MTK_VENDOR_ATTR_TXPOWER_CTRL_LINK_ID,
162+
163+ /* keep last */
164+ NUM_MTK_VENDOR_ATTRS_TXPOWER_CTRL,
165+ MTK_VENDOR_ATTR_TXPOWER_CTRL_MAX =
166+ NUM_MTK_VENDOR_ATTRS_TXPOWER_CTRL - 1
167+};
168+
169 #define CSI_BW20_DATA_COUNT 64
170 #define CSI_BW40_DATA_COUNT 128
171 #define CSI_BW80_DATA_COUNT 256
172diff --git a/src/drivers/driver.h b/src/drivers/driver.h
173index fe327e560..55f62f537 100644
174--- a/src/drivers/driver.h
175+++ b/src/drivers/driver.h
176@@ -5443,6 +5443,16 @@ struct wpa_driver_ops {
177 * @dump_buf: Dump_struct that store csi data and related info
178 */
179 int (*csi_dump)(void *priv, u8 band_idx, void *dump_buf);
180+ /**
181+ * txpower_ctrl - ctrl txpower operation
182+ * @priv: Private driver interface data
183+ * @lpi_psd: 1 to enable lpi psd compensate, 0 to disable
184+ * @lpi_bcn_enhance: 1 to enable beacon duplicate enhancement in 6G lpi mode, 0 to disable enhancement
185+ * @sku_idx: index used to indicate which sku table should be used
186+ * @link_id: MLD link id. -1 if this is an non-MLD AP
187+ */
188+ int (*txpower_ctrl)(void *priv, u8 lpi_psd, u8 sku_idx, u8 lpi_bcn_enhance,
189+ u8 link_id);
190 };
191
192 /**
193diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
194index 05b231c52..395bb5926 100644
195--- a/src/drivers/driver_nl80211.c
196+++ b/src/drivers/driver_nl80211.c
197@@ -195,6 +195,14 @@ static struct nla_policy csi_data_policy[NUM_MTK_VENDOR_ATTRS_CSI_DATA] = {
198 [MTK_VENDOR_ATTR_CSI_DATA_CHAIN_INFO] = { .type = NLA_U32 },
199 };
200
201+static struct nla_policy
202+txpower_ctrl_policy[NUM_MTK_VENDOR_ATTRS_TXPOWER_CTRL] = {
203+ [MTK_VENDOR_ATTR_TXPOWER_CTRL_LPI_PSD] = { .type = NLA_U8 },
204+ [MTK_VENDOR_ATTR_TXPOWER_CTRL_SKU_IDX] = { .type = NLA_U8 },
205+ [MTK_VENDOR_ATTR_TXPOWER_CTRL_LPI_BCN_ENHANCE] = { .type = NLA_U8 },
206+ [MTK_VENDOR_ATTR_TXPOWER_CTRL_LINK_ID] = { .type = NLA_U8 },
207+};
208+
209 static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
210 {
211 struct nl_sock *handle;
212@@ -15592,6 +15600,52 @@ fail:
213 return -ENOBUFS;
214 }
215
216+static int nl80211_txpower_ctrl(void *priv, u8 lpi_psd, u8 sku_idx, u8 lpi_bcn_enhance,
217+ u8 link_id)
218+{
219+ struct i802_bss *bss = priv;
220+ struct wpa_driver_nl80211_data *drv = bss->drv;
221+ struct nl_msg *msg;
222+ struct nlattr *data;
223+ int ret;
224+
225+ if (!drv->mtk_txpower_vendor_cmd_avail) {
226+ wpa_printf(MSG_INFO,
227+ "nl80211: Driver does not support setting txpower control");
228+ return 0;
229+ }
230+
231+ msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
232+ if (!msg)
233+ goto fail;
234+
235+ if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
236+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
237+ MTK_NL80211_VENDOR_SUBCMD_TXPOWER_CTRL))
238+ goto fail;
239+
240+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
241+ if (!data)
242+ goto fail;
243+
244+ nla_put_u8(msg, MTK_VENDOR_ATTR_TXPOWER_CTRL_LPI_PSD, lpi_psd);
245+ nla_put_u8(msg, MTK_VENDOR_ATTR_TXPOWER_CTRL_SKU_IDX, sku_idx);
246+ nla_put_u8(msg, MTK_VENDOR_ATTR_TXPOWER_CTRL_LPI_BCN_ENHANCE, lpi_bcn_enhance);
247+ nla_put_u8(msg, MTK_VENDOR_ATTR_TXPOWER_CTRL_LINK_ID, link_id);
248+
249+ nla_nest_end(msg, data);
250+ ret = send_and_recv_cmd(drv, msg);
251+ if (ret)
252+ wpa_printf(MSG_ERROR, "Failed to set power. ret=%d (%s)",
253+ ret, strerror(-ret));
254+
255+ return ret;
256+
257+fail:
258+ nlmsg_free(msg);
259+ return -ENOBUFS;
260+}
261+
262 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
263 .name = "nl80211",
264 .desc = "Linux nl80211/cfg80211",
265@@ -15779,4 +15833,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
266 #endif
267 .csi_set = nl80211_csi_set,
268 .csi_dump = nl80211_csi_dump,
269+ .txpower_ctrl = nl80211_txpower_ctrl,
270 };
271diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
272index 2cc40e0dc..d32c0ff4d 100644
273--- a/src/drivers/driver_nl80211.h
274+++ b/src/drivers/driver_nl80211.h
275@@ -214,6 +214,7 @@ struct wpa_driver_nl80211_data {
276 unsigned int mtk_beacon_ctrl_vendor_cmd_avail:1;
277 unsigned int mtk_csi_vendor_cmd_avail:1;
278 unsigned int mtk_eml_vendor_cmd_avail:1;
279+ unsigned int mtk_txpower_vendor_cmd_avail:1;
280
281 u32 ignore_next_local_disconnect;
282 u32 ignore_next_local_deauth;
283diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
284index c1327a679..fc7f9062f 100644
285--- a/src/drivers/driver_nl80211_capa.c
286+++ b/src/drivers/driver_nl80211_capa.c
287@@ -1179,6 +1179,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
288 case MTK_NL80211_VENDOR_SUBCMD_EML_CTRL:
289 drv->mtk_eml_vendor_cmd_avail = 1;
290 break;
291+ case MTK_NL80211_VENDOR_SUBCMD_TXPOWER_CTRL:
292+ drv->mtk_txpower_vendor_cmd_avail = 1;
293+ break;
294 }
295 }
296
297--
2982.18.0
299