Files
wlan-ap/feeds/wifi-ax/hostapd/patches/b00-013-hostap-add-signal-txrate-command.patch
John Crispin 04f6078da6 ipq807x: update AX support
Signed-off-by: John Crispin <john@phrozen.org>
2020-10-04 14:28:57 +02:00

263 lines
9.2 KiB
Diff

--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -3145,6 +3145,25 @@ static int hostapd_ctrl_iface_signal_mon
return -1;
}
+static int hostapd_ctrl_iface_signal_txrate(struct hostapd_data *hapd,
+ char *cmd)
+{
+ char *pos;
+ unsigned int low_thold = 0, high_thold = 0;
+
+ pos = os_strstr(cmd, "LOW=");
+ if (pos)
+ low_thold = atoi(pos + 4);
+
+ pos = os_strstr(cmd, "HIGH=");
+ if (pos)
+ high_thold = atoi(pos + 5);
+
+ if (hapd->driver->signal_txrate)
+ return hapd->driver->signal_txrate(hapd->drv_priv, low_thold,
+ high_thold);
+ return -1;
+}
static int hostapd_ctrl_driver_flags(struct hostapd_iface *iface, char *buf,
size_t buflen)
@@ -3791,6 +3810,9 @@ static int hostapd_ctrl_iface_receive_pr
} else if (os_strncmp(buf, "SIGNAL_MONITOR", 14) == 0) {
if (hostapd_ctrl_iface_signal_monitor(hapd, buf + 14))
reply_len = -1;
+ } else if (os_strncmp(buf, "SIGNAL_TXRATE", 13) == 0) {
+ if (hostapd_ctrl_iface_signal_txrate(hapd, buf + 13))
+ reply_len = -1;
} else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
reply_len = hostapd_ctrl_iface_get_capability(
hapd, buf + 15, reply, reply_size);
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -1505,6 +1505,12 @@ static int hostapd_cli_cmd_reload_wpa_ps
}
+static int hostapd_cli_cmd_signal_txrate(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return hostapd_cli_cmd(ctrl, "SIGNAL_TXRATE", 0, argc, argv);
+}
+
struct hostapd_cli_cmd {
const char *cmd;
int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
@@ -1680,6 +1686,9 @@ static const struct hostapd_cli_cmd host
"<addr> = poll a STA to check connectivity with a QoS null frame" },
{ "signal_monitor", hostapd_cli_cmd_signal_monitor, NULL,
"= set signal monitor parameters" },
+ { "signal_txrate", hostapd_cli_cmd_signal_txrate, NULL,
+ "= set signal tx rate parameters: signal_txrate "
+ "LOW=<> HIGH=<>" },
{ "req_beacon", hostapd_cli_cmd_req_beacon, NULL,
"<addr> [req_mode=] <measurement request hexdump> = send a Beacon report request to a station" },
{ "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL,
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -4412,6 +4412,20 @@ struct wpa_driver_ops {
*/
int (*get_peer_inactive_time)(void *priv, const u8 *addr);
+ /**
+ * signal_txrate - Set signal monitoring parameters
+ * @priv: Private driver interface data
+ * @low_thold: Low threshold value for signal txrate events; 0 = disabled
+ * @high_thold: High threshold value for signal txrate events; 0 = disabled
+ * Returns: 0 on success, -1 on failure (or if not supported)
+ *
+ * This function can be used to configure monitoring of signal tx rate
+ * with the current AP. Whenever txrate drops below the low_thold
+ * or increases above high_thold.
+ */
+ int (*signal_txrate)(void *priv, const u32 low_thold,
+ u32 high_thold);
+
/**
* update_connect_params - Update the connection parameters
* @priv: Private driver interface data
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -8268,6 +8268,29 @@ static int nl80211_signal_monitor(void *
return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
}
+static int nl80211_signal_txrate(void *priv, const u32 low_thold,
+ u32 high_thold)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+ struct nlattr *cqm;
+
+ if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_CQM)) ||
+ !(cqm = nla_nest_start(msg, NL80211_ATTR_CQM)) ||
+ nla_put_u32(msg, NL80211_ATTR_CQM_LOW_TX_RATE_THOLD,
+ low_thold) ||
+ nla_put_u32(msg, NL80211_ATTR_CQM_HIGH_TX_RATE_THOLD,
+ high_thold)) {
+ nlmsg_free(msg);
+ wpa_printf(MSG_WARNING, "nl80211: Signal txrate returning");
+ return -1;
+ }
+
+ nla_nest_end(msg, cqm);
+
+ return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
+}
static int get_channel_width(struct nl_msg *msg, void *arg)
{
@@ -11725,6 +11748,7 @@ const struct wpa_driver_ops wpa_driver_n
.deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,
.resume = wpa_driver_nl80211_resume,
.signal_monitor = nl80211_signal_monitor,
+ .signal_txrate = nl80211_signal_txrate,
.signal_poll = nl80211_signal_poll,
.channel_info = nl80211_channel_info,
.set_param = nl80211_set_param,
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -1274,12 +1274,15 @@ static void nl80211_cqm_event(struct wpa
[NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
[NL80211_ATTR_CQM_BEACON_LOSS_EVENT] = { .type = NLA_FLAG },
[NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_U32 },
+ [NL80211_ATTR_CQM_TX_RATE_THRESHOLD_EVENT] =
+ { .type = NLA_U32 },
};
struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
- enum nl80211_cqm_rssi_threshold_event event;
+ enum nl80211_cqm_rssi_threshold_event rssi_event;
+ enum nl80211_cqm_tx_rate_threshold_event txrate_event;
union wpa_event_data ed;
struct wpa_signal_info sig;
- int res, rssi_level;
+ int res, rssi_level, txrate_level;
u8 *addr = NULL;
if (tb[NL80211_ATTR_CQM] == NULL ||
@@ -1324,19 +1327,41 @@ static void nl80211_cqm_event(struct wpa
return;
}
+ if (tb[NL80211_ATTR_MAC])
+ addr = nla_data(tb[NL80211_ATTR_MAC]);
+
+ if (cqm[NL80211_ATTR_CQM_TX_RATE_THRESHOLD_EVENT]) {
+ txrate_event =
+ nla_get_u32(cqm[NL80211_ATTR_CQM_TX_RATE_THRESHOLD_EVENT]);
+ txrate_level =
+ nla_get_u32(cqm[NL80211_ATTR_CQM_TX_RATE_LEVEL]);
+
+ if (txrate_event == NL80211_CQM_TX_RATE_THRESHOLD_EVENT_HIGH) {
+ wpa_msg(drv->ctx, MSG_INFO, "nl80211: CQM TXRATE HIGH "
+ "event for "MACSTR " txrate :%d",
+ MAC2STR(addr), txrate_level);
+ } else if (txrate_event ==
+ NL80211_CQM_TX_RATE_THRESHOLD_EVENT_LOW) {
+ wpa_msg(drv->ctx, MSG_INFO, "nl80211: CQM TXRATE LOW "
+ "event for "MACSTR " txrate :%d",
+ MAC2STR(addr), txrate_level);
+ } else {
+ wpa_msg(drv->ctx, MSG_INFO, "Unknown CQM TXRATE "
+ " threshold event :%d", txrate_event);
+ return;
+ }
+ }
+
if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL) {
wpa_printf(MSG_DEBUG,
"nl80211: Not a CQM RSSI threshold event");
return;
}
- event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
-
- if (tb[NL80211_ATTR_MAC])
- addr = nla_data(tb[NL80211_ATTR_MAC]);
+ rssi_event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
rssi_level = (s32) nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_LEVEL]);
- if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
+ if (rssi_event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
if (addr) {
wpa_msg(drv->ctx, MSG_INFO, "nl80211: CQM RSSI HIGH "
"event for "MACSTR " RSSI :%d", MAC2STR(addr),
@@ -1346,7 +1371,7 @@ static void nl80211_cqm_event(struct wpa
wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
"event: RSSI high");
ed.signal_change.above_threshold = 1;
- } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
+ } else if (rssi_event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
if (addr) {
wpa_msg(drv->ctx, MSG_INFO, "nl80211: CQM RSSI LOW "
"event for "MACSTR " RSSI :%d", MAC2STR(addr),
@@ -1359,7 +1384,7 @@ static void nl80211_cqm_event(struct wpa
} else {
wpa_printf(MSG_DEBUG,
"nl80211: Unknown CQM RSSI threshold event: %d",
- event);
+ rssi_event);
return;
}
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -4792,6 +4792,17 @@ enum nl80211_ps_state {
* loss event
* @NL80211_ATTR_CQM_RSSI_LEVEL: the RSSI value in dBm that triggered the
* RSSI threshold event.
+ * @NL80211_ATTR_CQM_LOW_TX_RATE_THOLD: TX_RATE threshold in Kbps. This value
+ * specifies the low threshold for the TX_RATE level at which an event will be
+ * sent. Zero to disable. Events will be sent when the TX_RATE value goes
+ * lesser than this threshold.
+ * @NL80211_ATTR_CQM_HIGH_TX_RATE_THOLD: TX RATE in Kbps. This value
+ * specifies the high threshold for the TX_RATE level at which an event will
+ * be sent. Zero to diable. Event will be sent when the TX_RATE values goes
+ * greater than this threshold.
+ * @NL80211_ATTR_CQM_TX_RATE_THRESHOLD_EVENT: TX_RATE threshold event
+ * @NL80211_ATTR_CQM_TX_RATE_LEVEL: the tx rate value in Kbps that triggered the
+ * TX_RATE threshold event.
* @__NL80211_ATTR_CQM_AFTER_LAST: internal
* @NL80211_ATTR_CQM_MAX: highest key attribute
*/
@@ -4806,7 +4817,10 @@ enum nl80211_attr_cqm {
NL80211_ATTR_CQM_TXE_INTVL,
NL80211_ATTR_CQM_BEACON_LOSS_EVENT,
NL80211_ATTR_CQM_RSSI_LEVEL,
-
+ NL80211_ATTR_CQM_LOW_TX_RATE_THOLD,
+ NL80211_ATTR_CQM_HIGH_TX_RATE_THOLD,
+ NL80211_ATTR_CQM_TX_RATE_THRESHOLD_EVENT,
+ NL80211_ATTR_CQM_TX_RATE_LEVEL,
/* keep last */
__NL80211_ATTR_CQM_AFTER_LAST,
NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1
@@ -4820,13 +4834,17 @@ enum nl80211_attr_cqm {
* configured threshold
* @NL80211_CQM_RSSI_BEACON_LOSS_EVENT: (reserved, never sent)
*/
+
enum nl80211_cqm_rssi_threshold_event {
NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
};
-
+enum nl80211_cqm_tx_rate_threshold_event {
+ NL80211_CQM_TX_RATE_THRESHOLD_EVENT_LOW = 1,
+ NL80211_CQM_TX_RATE_THRESHOLD_EVENT_HIGH,
+};
/**
* enum nl80211_tx_power_setting - TX power adjustment
* @NL80211_TX_POWER_AUTOMATIC: automatically determine transmit power