blob: e99e2a351913eded98ec3b6ecc3c04d0f7f64294 [file] [log] [blame]
From e621aacd1eb69668a8e9176b4cd09125394d2fb8 Mon Sep 17 00:00:00 2001
From: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
Date: Wed, 24 Jan 2024 15:15:26 +0800
Subject: [PATCH] hostapd: mtk: add no_beacon vendor command for cert
Add the vendor command to disable/enable beacon
[Usage]
hostapd_cli -i <interface> no_beacon <value>
<value>
0: enable beacon
1: disable beacon
---
hostapd/ctrl_iface.c | 18 +++++++++++++++++
hostapd/hostapd_cli.c | 7 +++++++
src/ap/ap_drv_ops.c | 7 +++++++
src/ap/ap_drv_ops.h | 1 +
src/common/mtk_vendor.h | 12 +++++++++++
src/drivers/driver.h | 7 +++++++
src/drivers/driver_nl80211.c | 33 +++++++++++++++++++++++++++++++
src/drivers/driver_nl80211.h | 1 +
src/drivers/driver_nl80211_capa.c | 3 +++
9 files changed, 89 insertions(+)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index bacf14c..c662417 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -4034,6 +4034,22 @@ hostapd_ctrl_iface_set_offchan_ctrl(struct hostapd_data *hapd, char *cmd,
return os_snprintf(buf, buflen, "OK\n");
}
+static int
+hostapd_ctrl_iface_disable_beacon(struct hostapd_data *hapd, char *value,
+ char *buf, size_t buflen)
+{
+ int disable_beacon = atoi(value);
+
+ if (disable_beacon < 0) {
+ wpa_printf(MSG_ERROR, "Invalid value for beacon ctrl");
+ return -1;
+ }
+
+ if (hostapd_drv_beacon_ctrl(hapd, !disable_beacon) == 0)
+ return os_snprintf(buf, buflen, "OK\n");
+ else
+ return -1;
+}
static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
char *buf, char *reply,
@@ -4615,6 +4631,8 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
reply, reply_size);
} else if (os_strncmp(buf, "SET_OFFCHAN_CTRL", 16) == 0) {
reply_len = hostapd_ctrl_iface_set_offchan_ctrl(hapd, buf + 16, reply, reply_size);
+ } else if (os_strncmp(buf, "NO_BEACON ", 10) == 0) {
+ reply_len = hostapd_ctrl_iface_disable_beacon(hapd, buf + 10, reply, reply_size);
} else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
reply_len = 16;
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index 0c4a176..60e963a 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -1393,6 +1393,11 @@ static int hostapd_cli_cmd_get_mu(struct wpa_ctrl *ctrl, int argc,
return hostapd_cli_cmd(ctrl, "GET_MU", 0, NULL, NULL);
}
+static int hostapd_cli_cmd_disable_beacon(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return hostapd_cli_cmd(ctrl, "NO_BEACON", 1, argc, argv);
+}
#ifdef CONFIG_DPP
@@ -1762,6 +1767,8 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
"<value> [0-15] bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0)"},
{ "get_mu", hostapd_cli_cmd_get_mu, NULL,
" = show mu onoff value in 0-15 bitmap"},
+ { "no_beacon", hostapd_cli_cmd_disable_beacon, NULL,
+ "<value> 0: Enable beacon, 1: Disable beacon"},
#ifdef CONFIG_DPP
{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
"report a scanned DPP URI from a QR Code" },
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index a060f5c..b1f7c92 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -1143,3 +1143,10 @@ int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_
return 0;
return hapd->driver->amnt_dump(hapd->drv_priv, amnt_idx, amnt_dump_buf);
}
+
+int hostapd_drv_beacon_ctrl(struct hostapd_data *hapd, u8 beacon_mode)
+{
+ if (!hapd->driver || !hapd->driver->beacon_ctrl)
+ return 0;
+ return hapd->driver->beacon_ctrl(hapd->drv_priv, beacon_mode);
+}
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 5f11a57..c5fdb00 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -158,6 +158,7 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
int hostapd_drv_amnt_set(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_sta_mac);
int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_buf);
+int hostapd_drv_beacon_ctrl(struct hostapd_data *hapd, u8 beacon_mode);
#include "drivers/driver.h"
diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
index 21e735f..c7ed8e8 100644
--- a/src/common/mtk_vendor.h
+++ b/src/common/mtk_vendor.h
@@ -16,6 +16,7 @@ enum mtk_nl80211_vendor_subcmds {
MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8,
MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
+ MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL = 0xcd,
MTK_NL80211_VENDOR_SUBCMD_TXPOWER_CTRL = 0xce,
};
@@ -253,6 +254,17 @@ enum mtk_vendor_attr_txpower_ctrl {
NUM_MTK_VENDOR_ATTRS_TXPOWER_CTRL - 1
};
+enum mtk_vendor_attr_beacon_ctrl {
+ MTK_VENDOR_ATTR_BEACON_CTRL_UNSPEC,
+
+ MTK_VENDOR_ATTR_BEACON_CTRL_MODE,
+
+ /* keep last */
+ NUM_MTK_VENDOR_ATTRS_BEACON_CTRL,
+ MTK_VENDOR_ATTR_BEACON_CTRL_MAX =
+ NUM_MTK_VENDOR_ATTRS_BEACON_CTRL - 1
+};
+
#define CSI_MAX_COUNT 256
#define ETH_ALEN 6
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 0e3934e..f420464 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -4749,6 +4749,13 @@ struct wpa_driver_ops {
int (*mu_ctrl)(void *priv, u8 mode, u8 val);
int (*mu_dump)(void *priv, u8 *mu_onoff);
+ /**
+ * beacon_ctrl - ctrl on off for beacon
+ * @priv: Private driver interface data
+ *
+ */
+ int (*beacon_ctrl)(void *priv, u8 beacon_mode);
+
/**
* three_wire_ctrl - set three_wire_ctrl mode
* @priv: Private driver interface data
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index c8720bb..a1ce671 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -12565,6 +12565,38 @@ static int nl80211_mu_dump(void *priv, u8 *mu_onoff)
}
#endif /* CONFIG_IEEE80211AX */
+static int nl80211_beacon_ctrl(void *priv, u8 beacon_mode)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+ struct nlattr *data;
+ int ret;
+
+ if (!drv->mtk_beacon_ctrl_vendor_cmd_avail) {
+ wpa_printf(MSG_ERROR,
+ "nl80211: Driver does not support setting beacon control");
+ return 0;
+ }
+
+ if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL) ||
+ !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
+ nla_put_u8(msg, MTK_VENDOR_ATTR_BEACON_CTRL_MODE, beacon_mode)) {
+ nlmsg_free(msg);
+ return -ENOBUFS;
+ }
+
+ nla_nest_end(msg, data);
+
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
+
+ if (ret)
+ wpa_printf(MSG_ERROR, "Failed to set beacon_ctrl. ret=%d (%s)", ret, strerror(-ret));
+
+ return ret;
+}
#ifdef CONFIG_DPP
static int nl80211_dpp_listen(void *priv, bool enable)
@@ -13586,6 +13618,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.set_4addr_mode = nl80211_set_4addr_mode,
.mu_ctrl = nl80211_mu_ctrl,
.mu_dump = nl80211_mu_dump,
+ .beacon_ctrl = nl80211_beacon_ctrl,
#ifdef CONFIG_DPP
.dpp_listen = nl80211_dpp_listen,
#endif /* CONFIG_DPP */
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index 640fdc5..53cf2be 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -190,6 +190,7 @@ struct wpa_driver_nl80211_data {
unsigned int mtk_rfeatures_vendor_cmd_avail:1;
unsigned int mtk_amnt_vendor_cmd_avail:1;
unsigned int mtk_txpower_vendor_cmd_avail:1;
+ unsigned int mtk_beacon_ctrl_vendor_cmd_avail:1;
u64 vendor_scan_cookie;
u64 remain_on_chan_cookie;
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index 004c452..d13a64c 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -1103,6 +1103,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
case MTK_NL80211_VENDOR_SUBCMD_TXPOWER_CTRL:
drv->mtk_txpower_vendor_cmd_avail = 1;
break;
+ case MTK_NL80211_VENDOR_SUBCMD_BEACON_CTRL :
+ drv->mtk_beacon_ctrl_vendor_cmd_avail = 1;
+ break;
}
}
--
2.18.0