wlan-ap-Telecominfraproject/feeds/ipq95xx/iw/patches/614-iw-add-support-to-configure-telemetry.patch
John Crispin 460050a114 ipq50xx: add CIF WF-198 support
Signed-off-by: John Crispin <john@phrozen.org>
2024-02-28 18:56:21 +01:00

429 lines
16 KiB
Diff

From 6dd3cb94e051d1ebe923ff854aa666dea719a30f Mon Sep 17 00:00:00 2001
From: Mahendran P <quic_mahep@quicinc.com>
Date: Mon, 29 May 2023 10:34:24 +0530
Subject: [PATCH] iw: add support to configure telemetry
Add sla samples configuration, sla thershold configuration and sla detection configuration
Below is the command to configure sla samples configuration
- iw phy <phyname> telemetry sla_samples_cfg <moving_avg_pkt> <moving_avg_window> <sla_num_pkt> <sla_time_sec>
Below is the command to configure sla thershold
- iw phy <phyname> telemetry sla_thershold <service_id> <min_throughput_rate> <max_throughput_rate> <burst_size> <service_interval> <delay_bound> <msdu_ttl> <msdu_rate_loss>
Below is the command to configure sla detection
- iw phy <phyname> telemetry sla_detection_cfg <detection_option> <min_throughput_rate> <max_throughput_rate> <burst_size> <service_interval> <delay_bound> <msdu_ttl> <msdu_rate_loss>
Signed-off-by: Mahendran P <quic_mahep@quicinc.com>
---
iw.h | 52 +++++++++-
telemetry.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 323 insertions(+), 1 deletion(-)
create mode 100644 telemetry.c
--- a/iw.h
+++ b/iw.h
@@ -76,7 +76,11 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_SVC_VIEW = 206,
QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP = 207,
QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_UNMAP = 208,
- QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP_REP = 209
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP_REP = 209,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_THERSHOLD_CFG = 210,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_SAMPLES_COLLECTION_CFG = 211,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_BREACH_DETECTION_CFG = 212
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_SLA_BREACH = 214,
};
/* Attributes for data used by
* QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION and
@@ -127,6 +131,82 @@ enum qca_wlan_vendor_sawf_attr_config {
QCA_WLAN_VENDOR_SAWF_ATTR_CONFIG_AFTER_LAST - 1,
};
+enum qca_wlan_vendor_attr_telemetry_sawf_sla_samples_config {
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_MOVING_AVG_PKT = 1,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_MOVING_AVG_WIN,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_NUM_PKT,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_TIME_SEC,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_SAMPLES_CFG_ATTR_AFTER_LAST,
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_SAMPLES_CFG_ATTR_CONFIG_MAX =
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_SAMPLES_CFG_ATTR_AFTER_LAST - 1,
+};
+
+enum qca_wlan_vendor_attr_telemetry_sawf_sla_detect_config {
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECTION_PARAM = 1,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MIN_TP,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MAX_TP,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_BURST_SIZE,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_INTERVAL,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_DELAY_BOUND,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MSDU_TTL,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MSDU_RATE_LOSS,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_DETECT_AFTER_LAST,
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_DETECT_ATTR_CONFIG_MAX =
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_DETECT_AFTER_LAST - 1,
+
+};
+
+enum qca_wlan_vendor_attr_telemetry_sawf_sla_thershold_config {
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_SVC_ID = 1,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MIN_TP,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MAX_TP,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_BURST_SIZE,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_INTERVAL,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_DELAY_BOUND,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MSDU_TTL,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MSDU_RATE_LOSS,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_THERSHOLD_CFG_AFTER_LAST,
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_THERSHOLD_CFG_ATTR_CONFIG_MAX =
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_THERSHOLD_CFG_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_sawf_sla_params - This enum defines
+ * attributes required for QCA_NL80211_VENDOR_SUBCMD_SAWF_SLA_BREACH
+ * Used to send sla clear event to driver.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SLA_PEER_MAC: Unsigned 8-bit array
+ * of size 6, representing peer mac address.
+ * @QCA_WLAN_VENDOR_ATTR_SLA_SVC_ID: Unsigned 8-bit representing service ID
+ * @QCA_WLAN_VENDOR_ATTR_SLA_PARAM: Unsigned 8-bit indicaing service class
+ * from qca_vendor_attr_sla_param_type
+ * @QCA_WLAN_VENDOR_ATTR_SLA_PEER_MLD_MAC: Unsigned 8-bit array
+ * of size 6, representing peer mld mac address. Filled only for ML capable
+ * peers
+ * @QCA_WLAN_VENDOR_ATTR_SLA_AC: Unsigned 8-bit representing AC for breach
+ *
+ */
+enum qca_wlan_vendor_attr_sawf_sla_params {
+ QCA_WLAN_VENDOR_ATTR_SLA_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_SLA_PEER_MAC = 1,
+ QCA_WLAN_VENDOR_ATTR_SLA_SVC_ID = 2,
+ QCA_WLAN_VENDOR_ATTR_SLA_PARAM = 3,
+ QCA_WLAN_VENDOR_ATTR_SLA_SET_CLEAR = 4,
+ QCA_WLAN_VENDOR_ATTR_SLA_PEER_MLD_MAC = 5,
+ QCA_WLAN_VENDOR_ATTR_SLA_AC = 6,
+
+ /* Keep last */
+ QCA_WLAN_VENDOR_ATTR_SLA_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_SLA_MAX =
+ QCA_WLAN_VENDOR_ATTR_SLA_AFTER_LAST - 1
+};
+
#define HANDLER_RET_USAGE 1
#define HANDLER_RET_DONE 3
--- /dev/null
+++ b/telemetry.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include <arpa/inet.h>
+
+#include "nl80211.h"
+#include "iw.h"
+
+#define OUI_QCA 0x001374
+#define MAX_OPTIONAL_STRINGS 15
+#define MAX_STRING_SIZE 60
+#define MAX_RANGE(type) pow(2, 8 * sizeof(type)) - 1
+#define SVC_CREATE_MIN_ARGUMENTS 2
+#define SVC_CREATE_MAX_ARGUMENTS 32
+#define SVC_DISABLE_MAX_ARGUMENTS 1
+#define SVC_VIEW_MAX_ARGUMENTS 1
+#define APP_NAME_MAX_BYTES 64
+#define streq(a, b) (strcmp((a), (b)) == 0)
+
+#define TELEMETRY_SLA_SAMPLES_CONFIG_NUM_OF_PARAMS 4
+#define TELEMETRY_SLA_THERSHOLD_CONFIG_NUM_OF_PARAMS 8
+#define TELEMETRY_SLA_DETECTION_CONFIG_NUM_OF_PARAMS 8
+
+struct telemetry_sawf_generic_param {
+ uint32_t moving_avg_pkt;
+ uint32_t moving_avg_win;
+ uint32_t sla_num_pkt;
+ uint32_t sla_time_sec;
+};
+
+struct telemetry_sawf_sla_thershold {
+ uint8_t svc_id;
+ uint32_t min_throughput_rate;
+ uint32_t max_throughput_rate;
+ uint32_t burst_size;
+ uint32_t service_interval;
+ uint32_t delay_bound;
+ uint32_t msdu_ttl;
+ uint32_t msdu_rate_loss;
+};
+
+enum telemetry_sawf_sla_detect {
+ SLA_DETECT_NUM_PACKET,
+ SLA_DETECT_PER_SECOND,
+ SLA_DETECT_MOV_AVG,
+ SLA_DETECT_NUM_SECOND,
+ SLA_DETECT_MAX,
+};
+
+struct telemetry_sawf_sla_detect_param {
+ enum telemetry_sawf_sla_detect sla_detect;
+ uint32_t min_throughput_rate;
+ uint32_t max_throughput_rate;
+ uint32_t burst_size;
+ uint32_t service_interval;
+ uint32_t delay_bound;
+ uint32_t msdu_ttl;
+ uint32_t msdu_rate_loss;
+};
+
+
+SECTION(telemetry);
+
+static int handle_telemetry_sawf_sla_samples_colletion_cfg
+ (struct nl80211_state *state, struct nl_msg *msg,
+ int argc, char **argv, enum id_input id)
+{
+ struct nlattr *telemetry_cfg;
+ char *end;
+ struct telemetry_sawf_generic_param telemetry_param;
+
+ if (argc != TELEMETRY_SLA_SAMPLES_CONFIG_NUM_OF_PARAMS)
+ goto err;
+
+ telemetry_param.moving_avg_pkt = strtoul(argv[0], &end, 10);
+ telemetry_param.moving_avg_win = strtoul(argv[1], &end, 10);
+ telemetry_param.sla_num_pkt = strtoul(argv[2], &end, 10);
+ telemetry_param.sla_time_sec = strtoul(argv[3], &end, 10);
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_SAMPLES_COLLECTION_CFG);
+
+ telemetry_cfg = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!telemetry_cfg)
+ return -ENOBUFS;
+
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_MOVING_AVG_PKT,
+ telemetry_param.moving_avg_pkt);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_MOVING_AVG_WIN,
+ telemetry_param.moving_avg_win);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_NUM_PKT,
+ telemetry_param.sla_num_pkt);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_TIME_SEC,
+ telemetry_param.sla_time_sec);
+
+ nla_nest_end(msg, telemetry_cfg);
+
+ return 0;
+
+err:
+ printf("invalid telemetry sla samples configuration command format: Usage\n");
+ printf("\t iw phy <phyname> telemetry sla_samples_cfg <moving_avg_pkt> <moving_avg_window> <sla_num_pkt> <sla_time_sec>\n");
+ return -EINVAL;
+}
+
+COMMAND(telemetry, sla_samples_cfg, "<moving_avg_pkt> <moving_avg_window>"
+"<sla_num_pkt> <sla_time_sec>", NL80211_CMD_VENDOR, 0, CIB_PHY,
+handle_telemetry_sawf_sla_samples_colletion_cfg, ".");
+
+static int handle_telemetry_sawf_sla_thershold_cfg(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *telemetry_cfg;
+ char *end;
+ struct telemetry_sawf_sla_thershold sla_thershold_cfg;
+
+ if (argc != TELEMETRY_SLA_THERSHOLD_CONFIG_NUM_OF_PARAMS)
+ goto err;
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_THERSHOLD_CFG);
+
+ telemetry_cfg = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!telemetry_cfg)
+ return -ENOBUFS;
+
+ sla_thershold_cfg.svc_id = strtoul(argv[0], &end, 10);
+ sla_thershold_cfg.min_throughput_rate = strtoul(argv[1], &end, 10);
+ sla_thershold_cfg.max_throughput_rate = strtoul(argv[2], &end, 10);
+ sla_thershold_cfg.burst_size = strtoul(argv[3], &end, 10);
+ sla_thershold_cfg.service_interval = strtoul(argv[4], &end, 10);
+ sla_thershold_cfg.delay_bound = strtoul(argv[5], &end, 10);
+ sla_thershold_cfg.msdu_ttl = strtoul(argv[6], &end, 10);
+ sla_thershold_cfg.msdu_rate_loss = strtoul(argv[7], &end, 10);
+
+
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_SVC_ID,
+ sla_thershold_cfg.svc_id);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MIN_TP,
+ sla_thershold_cfg.min_throughput_rate);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MAX_TP,
+ sla_thershold_cfg.max_throughput_rate);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_BURST_SIZE,
+ sla_thershold_cfg.burst_size);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_INTERVAL,
+ sla_thershold_cfg.service_interval);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_DELAY_BOUND,
+ sla_thershold_cfg.delay_bound);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MSDU_TTL,
+ sla_thershold_cfg.msdu_ttl);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MSDU_RATE_LOSS,
+ sla_thershold_cfg.msdu_rate_loss);
+ nla_nest_end(msg, telemetry_cfg);
+ return 0;
+
+err:
+ printf("invalid telemetry sla thershold configuration command format: Usage\n");
+ printf("\t iw phy <phyname> telemetry sla_thershold <service_id> ");
+ printf(" <min_throughput_rate> <max_throughput_rate> <burst_size> <service_interval> ");
+ printf(" <delay_bound> <msdu_ttl> <msdu_rate_loss> \n");
+ return -EINVAL;
+}
+
+COMMAND(telemetry, sla_thershold, "<service_id> <min_throughput_rate> <max_throughput_rate>"
+"<burst_size> <service_interval> <delay_bound> <msdu_ttl> <msdu_rate_loss>", NL80211_CMD_VENDOR, 0,
+CIB_PHY, handle_telemetry_sawf_sla_thershold_cfg, ".");
+
+
+static int handle_telemetry_sawf_sla_detection_cfg(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *telemetry_cfg;
+ char *end;
+ struct telemetry_sawf_sla_detect_param telemetry_param;
+
+ if (argc != TELEMETRY_SLA_DETECTION_CONFIG_NUM_OF_PARAMS)
+ goto err;
+
+ if (streq(argv[0], "num_packet"))
+ telemetry_param.sla_detect = SLA_DETECT_NUM_PACKET;
+
+ if (streq(argv[0], "per_second"))
+ telemetry_param.sla_detect = SLA_DETECT_PER_SECOND;
+
+ if (streq(argv[0], "moving_avg"))
+ telemetry_param.sla_detect = SLA_DETECT_MOV_AVG;
+
+ if (streq(argv[0], "num_second"))
+ telemetry_param.sla_detect = SLA_DETECT_NUM_SECOND;
+
+ telemetry_param.min_throughput_rate = strtoul(argv[1], &end, 10);
+ telemetry_param.max_throughput_rate = strtoul(argv[2], &end, 10);
+ telemetry_param.burst_size = strtoul(argv[3], &end, 10);
+ telemetry_param.service_interval = strtoul(argv[4], &end, 10);
+ telemetry_param.delay_bound = strtoul(argv[5], &end, 10);
+ telemetry_param.msdu_ttl = strtoul(argv[6], &end, 10);
+ telemetry_param.msdu_rate_loss = strtoul(argv[7], &end, 10);
+
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_BREACH_DETECTION_CFG);
+
+ telemetry_cfg = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!telemetry_cfg)
+ return -ENOBUFS;
+
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECTION_PARAM,
+ telemetry_param.sla_detect);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MIN_TP,
+ telemetry_param.min_throughput_rate);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MAX_TP,
+ telemetry_param.max_throughput_rate);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_BURST_SIZE,
+ telemetry_param.burst_size);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_INTERVAL,
+ telemetry_param.service_interval);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_DELAY_BOUND,
+ telemetry_param.delay_bound);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MSDU_TTL,
+ telemetry_param.msdu_ttl);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MSDU_RATE_LOSS,
+ telemetry_param.msdu_rate_loss);
+ nla_nest_end(msg, telemetry_cfg);
+
+ return 0;
+
+err:
+ printf("invalid telemetry sla breach detection configuration command format: Usage\n");
+ printf("\t iw phy <phyname> telemetry sla_detection_cfg <detection_option> <min_throughput_rate> <max_throughput_rate> <burst_size> <service_interval> <delay_bound> <msdu_ttl> <msdu_rate_loss>\n");
+ return -EINVAL;
+}
+
+COMMAND(telemetry, sla_detection_cfg, "<detection_option> <min_throughput_rate>"
+"<max_throughput_rate> <burst_size> <service_interval> <delay_bound> <msdu_ttl>"
+"<msdu_rate_loss>", NL80211_CMD_VENDOR, 0, CIB_PHY,
+handle_telemetry_sawf_sla_detection_cfg, ".");
+
+#define TELEMETRY_SLA_CLEAR_STATS_MAX_ARG 1
+#define MAC_ADDR_LEN 18
+
+static int handle_telemetry_sla_clear_stats(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *sla_clear;
+ unsigned char mac_addr[MAC_ADDR_LEN];
+
+ if (argc != TELEMETRY_SLA_CLEAR_STATS_MAX_ARG)
+ goto err;
+
+ if (mac_addr_a2n(mac_addr, argv[0])) {
+ printf("Invalid MAC address\n");
+ return -EINVAL;
+ }
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_SLA_BREACH);
+
+ sla_clear = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!sla_clear)
+ return -ENOBUFS;
+
+ if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_SLA_PEER_MAC,
+ ETH_ALEN, mac_addr))
+ return -ENOBUFS;
+
+ nla_nest_end(msg, sla_clear);
+ return NL_OK;
+err:
+ printf("Invalid telemetry sla clear stats, command format: Usage\n");
+ printf("\t iw dev <devname> telemetry sla_clear_stats <peer_mac>\n");
+ return NL_STOP;
+}
+COMMAND(telemetry, sla_clear_stats, "<peer_mac>", NL80211_CMD_VENDOR, 0, CIB_NETDEV,
+ handle_telemetry_sla_clear_stats, ".");