blob: be54e066154d11718f291fa43aac5ac8560eb85c [file] [log] [blame]
developerc41fcd32022-09-20 22:09:06 +08001From 166ba374624b2aed360427f087c20b8f511fb2e0 Mon Sep 17 00:00:00 2001
developer91fc9452022-06-28 11:24:56 +08002From: Howard Hsu <howard-yh.hsu@mediatek.com>
3Date: Mon, 30 May 2022 16:31:34 +0800
developerc41fcd32022-09-20 22:09:06 +08004Subject: [PATCH 99912/99916] Support new hostapd configuration, edcca_enable
5 and edcca_compensation
developer91fc9452022-06-28 11:24:56 +08006
7---
8 hostapd/config_file.c | 20 +++++++++++++++
9 src/ap/ap_config.c | 3 +++
10 src/ap/ap_config.h | 10 ++++++++
11 src/ap/ap_drv_ops.c | 9 +++++++
12 src/ap/ap_drv_ops.h | 2 +-
13 src/ap/hostapd.c | 3 +++
14 src/drivers/driver.h | 2 ++
15 src/drivers/driver_nl80211.c | 42 +++++++++++++++++++++++++++++++
16 src/drivers/driver_nl80211.h | 1 +
17 src/drivers/driver_nl80211_capa.c | 7 ++++++
18 10 files changed, 98 insertions(+), 1 deletion(-)
19
20diff --git a/hostapd/config_file.c b/hostapd/config_file.c
developerc41fcd32022-09-20 22:09:06 +080021index eda9db021..8a21c9698 100644
developer91fc9452022-06-28 11:24:56 +080022--- a/hostapd/config_file.c
23+++ b/hostapd/config_file.c
developerc41fcd32022-09-20 22:09:06 +080024@@ -4753,6 +4753,26 @@ static int hostapd_config_fill(struct hostapd_config *conf,
developer91fc9452022-06-28 11:24:56 +080025 } else if (os_strcmp(buf, "eht_mu_beamformer") == 0) {
26 conf->eht_phy_capab.mu_beamformer = atoi(pos);
27 #endif /* CONFIG_IEEE80211BE */
28+ } else if (os_strcmp(buf, "edcca_enable") == 0) {
29+ int mode = atoi(pos);
30+ if (mode < EDCCA_MODE_FORCE_DISABLE || mode > EDCCA_MODE_AUTO) {
31+ wpa_printf(MSG_ERROR, "Line %d: Invalid edcca_enable %d;"
32+ " allowed value 0 (Force Disable) or 1(Auto) ",
33+ line, mode);
34+ return 1;
35+ }
36+ conf->edcca_enable = (u8) mode;
37+ } else if (os_strcmp(buf, "edcca_compensation") == 0) {
38+ int val = atoi(pos);
39+ if (val < EDCCA_MIN_COMPENSATION ||
40+ val > EDCCA_MAX_COMPENSATION) {
41+ wpa_printf(MSG_ERROR, "Line %d: Invalid compensation"
42+ " value %d; allowed value %d ~ %d.",
43+ line, val, EDCCA_MIN_COMPENSATION,
44+ EDCCA_MAX_COMPENSATION);
45+ return 1;
46+ }
47+ conf->edcca_compensation = (s8) val;
48 } else {
49 wpa_printf(MSG_ERROR,
50 "Line %d: unknown configuration item '%s'",
51diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
developerc41fcd32022-09-20 22:09:06 +080052index 4a20eb4e1..373879f79 100644
developer91fc9452022-06-28 11:24:56 +080053--- a/src/ap/ap_config.c
54+++ b/src/ap/ap_config.c
55@@ -294,6 +294,9 @@ struct hostapd_config * hostapd_config_defaults(void)
56 conf->airtime_update_interval = AIRTIME_DEFAULT_UPDATE_INTERVAL;
57 #endif /* CONFIG_AIRTIME_POLICY */
58
59+ conf->edcca_enable = EDCCA_MODE_AUTO;
60+ conf->edcca_compensation = EDCCA_DEFAULT_COMPENSATION;
61+
62 return conf;
63 }
64
65diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
developerc41fcd32022-09-20 22:09:06 +080066index 3f68e76d5..3ac2ae070 100644
developer91fc9452022-06-28 11:24:56 +080067--- a/src/ap/ap_config.h
68+++ b/src/ap/ap_config.h
developerc41fcd32022-09-20 22:09:06 +080069@@ -1153,8 +1153,18 @@ struct hostapd_config {
developer91fc9452022-06-28 11:24:56 +080070 #define CH_SWITCH_EHT_ENABLED BIT(0)
71 #define CH_SWITCH_EHT_DISABLED BIT(1)
72 unsigned int ch_switch_eht_config;
73+ u8 edcca_enable;
74+ s8 edcca_compensation;
75 };
76
77+enum edcca_mode {
78+ EDCCA_MODE_FORCE_DISABLE = 0,
79+ EDCCA_MODE_AUTO = 1,
80+};
81+
82+#define EDCCA_DEFAULT_COMPENSATION -6
83+#define EDCCA_MIN_COMPENSATION -126
84+#define EDCCA_MAX_COMPENSATION 126
85
developerc41fcd32022-09-20 22:09:06 +080086 static inline enum oper_chan_width
87 hostapd_get_oper_chwidth(struct hostapd_config *conf)
developer91fc9452022-06-28 11:24:56 +080088diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
developerc41fcd32022-09-20 22:09:06 +080089index 0c7aee276..5d2d79c38 100644
developer91fc9452022-06-28 11:24:56 +080090--- a/src/ap/ap_drv_ops.c
91+++ b/src/ap/ap_drv_ops.c
developerc41fcd32022-09-20 22:09:06 +080092@@ -1015,3 +1015,12 @@ int hostapd_drv_dpp_listen(struct hostapd_data *hapd, bool enable)
developer91fc9452022-06-28 11:24:56 +080093 return 0;
94 return hapd->driver->dpp_listen(hapd->drv_priv, enable);
95 }
96+
97+int hostapd_drv_configure_edcca_threshold(struct hostapd_data *hapd)
98+{
99+ if (!hapd->driver || !hapd->driver->configure_edcca_threshold)
100+ return 0;
101+ return hapd->driver->configure_edcca_threshold(hapd->drv_priv,
102+ hapd->iconf->edcca_enable,
103+ hapd->iconf->edcca_compensation);
104+}
105diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
developerc41fcd32022-09-20 22:09:06 +0800106index b4fb766ee..f8fef1929 100644
developer91fc9452022-06-28 11:24:56 +0800107--- a/src/ap/ap_drv_ops.h
108+++ b/src/ap/ap_drv_ops.h
109@@ -138,7 +138,7 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd);
110 int hostapd_drv_update_dh_ie(struct hostapd_data *hapd, const u8 *peer,
111 u16 reason_code, const u8 *ie, size_t ielen);
112 int hostapd_drv_dpp_listen(struct hostapd_data *hapd, bool enable);
113-
114+int hostapd_drv_configure_edcca_threshold(struct hostapd_data *hapd);
115
116 #include "drivers/driver.h"
117
118diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
developerc41fcd32022-09-20 22:09:06 +0800119index 0dd8c13b7..6babb036a 100644
developer91fc9452022-06-28 11:24:56 +0800120--- a/src/ap/hostapd.c
121+++ b/src/ap/hostapd.c
122@@ -2295,6 +2295,9 @@ dfs_offload:
123 }
124 #endif /* CONFIG_MESH */
125
126+ if (hostapd_drv_configure_edcca_threshold(hapd) < 0)
127+ goto fail;
128+
129 wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
130 iface->bss[0]->conf->iface);
131 if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
132diff --git a/src/drivers/driver.h b/src/drivers/driver.h
developerc41fcd32022-09-20 22:09:06 +0800133index 1d2b1b265..575448a93 100644
developer91fc9452022-06-28 11:24:56 +0800134--- a/src/drivers/driver.h
135+++ b/src/drivers/driver.h
developerc41fcd32022-09-20 22:09:06 +0800136@@ -4676,6 +4676,8 @@ struct wpa_driver_ops {
developer91fc9452022-06-28 11:24:56 +0800137 const u8 *match, size_t match_len,
138 bool multicast);
139 #endif /* CONFIG_TESTING_OPTIONS */
140+ int (*configure_edcca_threshold)(void *priv, const u8 edcca_enable,
141+ const s8 edcca_compensation);
142 };
143
144 /**
145diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
developerc41fcd32022-09-20 22:09:06 +0800146index 5eba0ea1b..76680dfd3 100644
developer91fc9452022-06-28 11:24:56 +0800147--- a/src/drivers/driver_nl80211.c
148+++ b/src/drivers/driver_nl80211.c
149@@ -35,6 +35,7 @@
150 #include "radiotap_iter.h"
151 #include "rfkill.h"
152 #include "driver_nl80211.h"
153+#include "common/mtk_vendor.h"
154
155
156 #ifndef NETLINK_CAP_ACK
developerc41fcd32022-09-20 22:09:06 +0800157@@ -12368,6 +12369,45 @@ static int testing_nl80211_radio_disable(void *priv, int disabled)
developer91fc9452022-06-28 11:24:56 +0800158
159 #endif /* CONFIG_TESTING_OPTIONS */
160
161+static int nl80211_configure_edcca_threshold(void *priv,
162+ const u8 edcca_enable,
163+ const s8 edcca_compensation)
164+{
165+ struct i802_bss *bss = priv;
166+ struct wpa_driver_nl80211_data *drv = bss->drv;
167+ /* Prepare nl80211 cmd */
168+ struct nl_msg *msg;
169+ struct nlattr *data;
170+ int ret;
171+
172+ if (!drv->mtk_edcca_vendor_cmd_avail) {
developera12553c2022-07-13 17:30:23 +0800173+ wpa_printf(MSG_INFO,
developer91fc9452022-06-28 11:24:56 +0800174+ "nl80211: Driver does not support setting EDCCA threshold");
developera12553c2022-07-13 17:30:23 +0800175+ return 0;
developer91fc9452022-06-28 11:24:56 +0800176+ }
177+
178+ if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
179+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
180+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
181+ MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL) ||
182+ !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
183+ nla_put_u8(msg, MTK_VENDOR_ATTR_EDCCA_CTRL_MODE, EDCCA_CTRL_SET_EN) ||
184+ nla_put_u8(msg, MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL, edcca_enable) ||
185+ nla_put_u8(msg, MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE,
186+ edcca_compensation)) {
187+ wpa_printf (MSG_ERROR, "Prepare nl80211 msg fail");
188+ nlmsg_free(msg);
189+ return -ENOBUFS;
190+ }
191+ nla_nest_end(msg, data);
192+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
193+ if (ret) {
194+ wpa_printf(MSG_ERROR, "Failed to configure EDCCA. ret=%d (%s) ",
195+ ret, strerror(-ret));
196+ }
197+ return ret;
198+}
199+
200
201 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
202 .name = "nl80211",
developerc41fcd32022-09-20 22:09:06 +0800203@@ -12514,4 +12554,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
developer91fc9452022-06-28 11:24:56 +0800204 .register_frame = testing_nl80211_register_frame,
205 .radio_disable = testing_nl80211_radio_disable,
206 #endif /* CONFIG_TESTING_OPTIONS */
207+/* Need ifdef CONFIG_DRIVER_NL80211_MTK */
208+ .configure_edcca_threshold = nl80211_configure_edcca_threshold,
209 };
210diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
developerc41fcd32022-09-20 22:09:06 +0800211index 6e40d5556..13e5d248c 100644
developer91fc9452022-06-28 11:24:56 +0800212--- a/src/drivers/driver_nl80211.h
213+++ b/src/drivers/driver_nl80211.h
developerc41fcd32022-09-20 22:09:06 +0800214@@ -181,6 +181,7 @@ struct wpa_driver_nl80211_data {
developer91fc9452022-06-28 11:24:56 +0800215 unsigned int qca_do_acs:1;
216 unsigned int brcm_do_acs:1;
developerc41fcd32022-09-20 22:09:06 +0800217 unsigned int uses_6ghz:1;
developer91fc9452022-06-28 11:24:56 +0800218+ unsigned int mtk_edcca_vendor_cmd_avail:1;
219
220 u64 vendor_scan_cookie;
221 u64 remain_on_chan_cookie;
222diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
developerc41fcd32022-09-20 22:09:06 +0800223index 7ede0d030..732ae292d 100644
developer91fc9452022-06-28 11:24:56 +0800224--- a/src/drivers/driver_nl80211_capa.c
225+++ b/src/drivers/driver_nl80211_capa.c
226@@ -18,6 +18,7 @@
227 #include "common/qca-vendor-attr.h"
228 #include "common/brcm_vendor.h"
229 #include "driver_nl80211.h"
230+#include "common/mtk_vendor.h"
231
232
233 static int protocol_feature_handler(struct nl_msg *msg, void *arg)
developerc41fcd32022-09-20 22:09:06 +0800234@@ -1050,6 +1051,12 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
developer91fc9452022-06-28 11:24:56 +0800235 break;
236 }
237 #endif /* CONFIG_DRIVER_NL80211_BRCM */
238+ } else if (vinfo->vendor_id == OUI_MTK) {
239+ switch (vinfo->subcmd) {
240+ case MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL :
241+ drv->mtk_edcca_vendor_cmd_avail = 1;
242+ break;
243+ }
244 }
245
246 wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
247--
developerc41fcd32022-09-20 22:09:06 +08002482.25.1
developer91fc9452022-06-28 11:24:56 +0800249