wlan: Add Vendor command to set/get NUD debug stats
Add vendor commands to set/reset and get NUD debug stats
from firmware.
Change-Id: Ib016a4580a97d7048c6c1c06ae51264ce0342f27
CRs-Fixed: 1115214
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index b89fa7d..604b327 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -199,6 +199,10 @@
QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES = 101,
QCA_NL80211_VENDOR_SUBCMD_SETBAND = 105,
+ /* Start / Stop the NUD stats collections */
+ QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET = 149,
+ /* Get the NUD stats, represented by the enum qca_attr_nud_stats_get */
+ QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET = 150,
};
enum qca_nl80211_vendor_subcmds_index {
@@ -234,8 +238,65 @@
QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX,
+ QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX,
};
+/**
+ * qca_wlan_vendor_attr_nud_stats_set: attribute to vendor subcmd
+ * QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET. This carry the requisite
+ * information to start / stop the NUD stats collection.
+ */
+enum qca_attr_nud_stats_set {
+ QCA_ATTR_NUD_STATS_SET_INVALID = 0,
+
+ /* Flag to Start / Stop the NUD stats collection
+ * Start - If included , Stop - If not included
+ */
+ QCA_ATTR_NUD_STATS_SET_START = 1,
+ /* IPv4 address of Default Gateway (in network byte order) */
+ QCA_ATTR_NUD_STATS_GW_IPV4 = 2,
+
+ /* keep last */
+ QCA_ATTR_NUD_STATS_SET_LAST,
+ QCA_ATTR_NUD_STATS_SET_MAX =
+ QCA_ATTR_NUD_STATS_SET_LAST - 1,
+};
+
+/**
+ * qca_attr_nud_stats_get: attribute to vendor subcmd
+ * QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET. This carry the requisite
+ * NUD stats collected when queried.
+ */
+enum qca_attr_nud_stats_get {
+ QCA_ATTR_NUD_STATS_GET_INVALID = 0,
+ /* ARP Request Count from net dev */
+ QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV = 1,
+ /* ARP Request Count sent to lower MAC from upper MAC */
+ QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC = 2,
+ /* ARP Request Count received by lower MAC from upper MAC */
+ QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC = 3,
+ /* ARP Request Count successfully transmitted by the device */
+ QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS = 4,
+ /* ARP Response Count received by lower MAC */
+ QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC = 5,
+ /* ARP Response Count received by upper MAC */
+ QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC = 6,
+ /* ARP Response Count delivered to netdev */
+ QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV = 7,
+ /* ARP Response Count delivered to netdev */
+ QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP = 8,
+ /*
+ * Flag indicating if the Stations Link to AP is active.
+ * Active Link - If exists, Inactive link - If not included
+ */
+ QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE= 9,
+ QCA_ATTR_NUD_STATS_AP_LINK_DAD= 10,
+ /* keep last */
+ QCA_ATTR_NUD_STATS_GET_LAST,
+ QCA_ATTR_NUD_STATS_GET_MAX =
+ QCA_ATTR_NUD_STATS_GET_LAST - 1,
+ };
+
enum qca_wlan_vendor_attr
{
QCA_WLAN_VENDOR_ATTR_INVALID = 0,
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 4d9faa1..d5cfd29 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -395,6 +395,35 @@
} hdd_pmf_stats_t;
#endif
+typedef enum
+{
+ HDD_TX_FRAME_IN_NOT_ASSOCIATED_STATE = 0,
+ HDD_VOS_PACKET_RETURNED_BY_VOSS_IS_NULL,
+ HDD_WLANTL_STAPKTPENDING_RETURNED_ERROR_CODE,
+ HDD_INSERT_TX_QUEUE_FAILED,
+ HDD_FAILED_TO_SIGNAL_TL,
+ HDD_ERROR_ATTACHING_SKB,
+ HDD_FAILURE_EXTRACTING_SKB_FROM_VOS_PKT,
+ HDD_FAILURE_WALKING_PACKET_CHAIN,
+ HDD_STA_RX_ARP_PACKET_REFUSED_IN_NET_STACK
+} HDD_PACKET_DROP_CAUSE;
+
+typedef struct hdd_arp_stats_s
+{
+ uint16 txCount;
+ uint16 rxCount;
+ uint16 txDropped;
+ uint16 rxDropped;
+ uint16 rxDelivered;
+ uint16 rxRefused;
+ uint16 tx_host_fw_sent;
+ uint16 rx_host_drop_reorder;
+ uint16_t tx_fw_cnt;
+ uint16_t rx_fw_cnt;
+ uint16_t tx_ack_cnt;
+ HDD_PACKET_DROP_CAUSE reason;
+} hdd_arp_stats_t;
+
typedef struct hdd_stats_s
{
tCsrSummaryStatsInfo summary_stat;
@@ -405,6 +434,7 @@
tCsrPerStaStatsInfo perStaStats;
hdd_tx_rx_stats_t hddTxRxStats;
hdd_chip_reset_stats_t hddChipResetStats;
+ hdd_arp_stats_t hddArpStats;
#ifdef WLAN_FEATURE_11W
hdd_pmf_stats_t hddPmfStats;
#endif
@@ -1323,6 +1353,8 @@
#ifdef WLAN_FEATURE_TSF
struct hdd_tsf_ctx_s tsf_cap_ctx;
#endif
+ bool con_status;
+ bool dad;
};
#define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station)
@@ -1380,6 +1412,10 @@
#define WLAN_WAIT_TIME_LL_STATS 800
+#define WLAN_WAIT_TIME_NUD_STATS 800
+#define WLAN_NUD_STATS_LEN 800
+#define WLAN_NUD_STATS_ARP_PKT_TYPE 1
+
/* FW memory dump feature
@TODO : Move this code to a separate file later */
#define PROCFS_MEMDUMP_DIR "debug"
@@ -1427,6 +1463,16 @@
struct completion response_event;
};
#endif /* End of WLAN_FEATURE_LINK_LAYER_STATS */
+
+/**
+ * struct hdd_nud_stats_context - hdd NUD stats context
+ *
+ * @response_event: NUD stats request wait event
+ */
+struct hdd_nud_stats_context {
+ struct completion response_event;
+};
+
#ifdef WLAN_FEATURE_EXTSCAN
/**
* struct hdd_ext_scan_context - hdd ext scan context
@@ -1714,6 +1760,7 @@
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
struct hdd_ll_stats_context ll_stats_context;
#endif /* End of WLAN_FEATURE_LINK_LAYER_STATS */
+ struct hdd_nud_stats_context nud_stats_context;
#ifdef WLAN_FEATURE_EXTSCAN
struct hdd_ext_scan_context ext_scan_context;
@@ -2079,6 +2126,19 @@
return;
}
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+/**
+ * hdd_init_nud_stats_ctx() - initialize NUD stats context
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Return: none
+ */
+static inline void hdd_init_nud_stats_ctx(hdd_context_t *hdd_ctx)
+{
+ init_completion(&hdd_ctx->nud_stats_context.response_event);
+ return;
+}
+
void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter);
void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy);
void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx);
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index b2e69e6..214d9aa 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -7504,6 +7504,355 @@
return ret;
}
+
+/*
+ * define short names for the global vendor params
+ * used by wlan_hdd_cfg80211_setarp_stats_cmd()
+ */
+#define STATS_SET_INVALID \
+ QCA_ATTR_NUD_STATS_SET_INVALID
+#define STATS_SET_START \
+ QCA_ATTR_NUD_STATS_SET_START
+#define STATS_GW_IPV4 \
+ QCA_ATTR_NUD_STATS_GW_IPV4
+#define STATS_SET_MAX \
+ QCA_ATTR_NUD_STATS_SET_MAX
+
+const struct nla_policy
+qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
+{
+ [STATS_SET_START] = {.type = NLA_FLAG },
+ [STATS_GW_IPV4] = {.type = NLA_U32 },
+};
+
+/**
+ * hdd_set_nud_stats_cb() - hdd callback api to get status
+ * @data: pointer to adapter
+ * @rsp: status
+ *
+ * Return: None
+ */
+static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
+{
+
+ hdd_adapter_t *adapter = (hdd_adapter_t *)data;
+
+ if (NULL == adapter)
+ return;
+
+ if (VOS_STATUS_SUCCESS == rsp) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s success received STATS_SET_START", __func__);
+ } else {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s STATS_SET_START Failed!!", __func__);
+ }
+ return;
+}
+
+/**
+ * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to apfind configuration data.
+ * @data_len: the length in byte of apfind data.
+ *
+ * This is called when wlan driver needs to send arp stats to
+ * firmware.
+ *
+ * Return: An error code or 0 on success.
+ */
+static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ struct nlattr *tb[STATS_SET_MAX + 1];
+ struct net_device *dev = wdev->netdev;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ setArpStatsParams arp_stats_params;
+ int err = 0;
+
+ ENTER();
+
+ err = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != err)
+ return err;
+
+ if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s NUD_DEBUG feature not supported by firmware!!", __func__);
+ return -EINVAL;
+ }
+
+ err = nla_parse(tb, STATS_SET_MAX, data, data_len,
+ qca_wlan_vendor_set_nud_stats);
+ if (err)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s STATS_SET_START ATTR", __func__);
+ return err;
+ }
+
+ if (tb[STATS_SET_START])
+ {
+ if (!tb[STATS_GW_IPV4]) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s STATS_SET_START CMD", __func__);
+ return -EINVAL;
+ }
+ arp_stats_params.flag = true;
+ arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
+ } else {
+ arp_stats_params.flag = false;
+ }
+ if (arp_stats_params.flag) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s STATS_SET_START Cleared!!", __func__);
+ vos_mem_zero(&adapter->hdd_stats.hddArpStats, sizeof(adapter->hdd_stats.hddArpStats));
+ }
+
+ arp_stats_params.pkt_type = 1; // ARP packet type
+
+ arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
+ arp_stats_params.data_ctx = adapter;
+
+ if (eHAL_STATUS_SUCCESS !=
+ sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s STATS_SET_START CMD Failed!!", __func__);
+ return -EINVAL;
+ }
+
+ EXIT();
+
+ return err;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to apfind configuration data.
+ * @data_len: the length in byte of apfind data.
+ *
+ * This is called when wlan driver needs to send arp stats to
+ * firmware.
+ *
+ * Return: An error code or 0 on success.
+ */
+static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
+#undef STATS_SET_INVALID
+#undef STATS_SET_START
+#undef STATS_GW_IPV4
+#undef STATS_SET_MAX
+
+/*
+ * define short names for the global vendor params
+ * used by wlan_hdd_cfg80211_setarp_stats_cmd()
+ */
+#define STATS_GET_INVALID \
+ QCA_ATTR_NUD_STATS_SET_INVALID
+#define COUNT_FROM_NETDEV \
+ QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
+#define COUNT_TO_LOWER_MAC \
+ QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
+#define RX_COUNT_BY_LOWER_MAC \
+ QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
+#define COUNT_TX_SUCCESS \
+ QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
+#define RSP_RX_COUNT_BY_LOWER_MAC \
+ QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
+#define RSP_RX_COUNT_BY_UPPER_MAC \
+ QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
+#define RSP_COUNT_TO_NETDEV \
+ QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
+#define RSP_COUNT_OUT_OF_ORDER_DROP \
+ QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
+#define AP_LINK_ACTIVE \
+ QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
+#define AP_LINK_DAD \
+ QCA_ATTR_NUD_STATS_AP_LINK_DAD
+#define STATS_GET_MAX \
+ QCA_ATTR_NUD_STATS_GET_MAX
+
+const struct nla_policy
+qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
+{
+ [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
+ [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
+ [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
+ [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
+ [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
+ [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
+ [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
+ [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
+ [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
+ [AP_LINK_DAD] = {.type = NLA_FLAG },
+};
+
+static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
+{
+
+ hdd_adapter_t *adapter = (hdd_adapter_t *)data;
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ struct hdd_nud_stats_context *context;
+ int status;
+
+ ENTER();
+
+ if (NULL == adapter)
+ return;
+
+ status = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != status) {
+ return;
+ }
+
+ if (!rsp) {
+ hddLog(LOGE, FL("data is null"));
+ return;
+ }
+
+ adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
+ adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
+ adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
+ adapter->dad |= rsp->dad;
+
+ spin_lock(&hdd_context_lock);
+ context = &hdd_ctx->nud_stats_context;
+ complete(&context->response_event);
+ spin_unlock(&hdd_context_lock);
+
+ return;
+}
+static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ int err = 0;
+ unsigned long rc;
+ struct hdd_nud_stats_context *context;
+ struct net_device *dev = wdev->netdev;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ getArpStatsParams arp_stats_params;
+ struct sk_buff *skb;
+
+ ENTER();
+
+ err = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != err)
+ return err;
+
+ arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
+ arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
+ arp_stats_params.data_ctx = adapter;
+
+ spin_lock(&hdd_context_lock);
+ context = &hdd_ctx->nud_stats_context;
+ INIT_COMPLETION(context->response_event);
+ spin_unlock(&hdd_context_lock);
+
+ if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s NUD_DEBUG feature not supported by firmware!!", __func__);
+ return -EINVAL;
+ }
+
+ if (eHAL_STATUS_SUCCESS !=
+ sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s STATS_SET_START CMD Failed!!", __func__);
+ return -EINVAL;
+ }
+
+ rc = wait_for_completion_timeout(&context->response_event,
+ msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
+ if (!rc)
+ {
+ hddLog(LOGE,
+ FL("Target response timed out request "));
+ return -ETIMEDOUT;
+ }
+
+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
+ WLAN_NUD_STATS_LEN);
+ if (!skb)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
+ __func__);
+ return -ENOMEM;
+ }
+
+ if (nla_put_u16(skb, COUNT_FROM_NETDEV,
+ adapter->hdd_stats.hddArpStats.txCount) ||
+ nla_put_u16(skb, COUNT_TO_LOWER_MAC,
+ adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
+ nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
+ adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
+ nla_put_u16(skb, COUNT_TX_SUCCESS,
+ adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
+ nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
+ adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
+ nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
+ adapter->hdd_stats.hddArpStats.rxCount) ||
+ nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
+ adapter->hdd_stats.hddArpStats.rxDelivered) ||
+ nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
+ adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
+ hddLog(LOGE, FL("nla put fail"));
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+ if (adapter->con_status)
+ nla_put_flag(skb, AP_LINK_ACTIVE);
+ if (adapter->dad)
+ nla_put_flag(skb, AP_LINK_DAD);
+
+ cfg80211_vendor_cmd_reply(skb);
+ return err;
+}
+
+static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
+
+#undef QCA_ATTR_NUD_STATS_SET_INVALID
+#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
+#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
+#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
+#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
+#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
+#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
+#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
+#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
+#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
+#undef QCA_ATTR_NUD_STATS_GET_MAX
+
+
+
#ifdef WLAN_FEATURE_APFIND
/**
* __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
@@ -7827,6 +8176,22 @@
.doit = wlan_hdd_cfg80211_apfind_cmd
},
#endif /* WLAN_FEATURE_APFIND */
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlan_hdd_cfg80211_set_nud_stats
+ },
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlan_hdd_cfg80211_get_nud_stats
+ },
};
/* vendor specific events */
@@ -7957,7 +8322,10 @@
.vendor_id = QCA_NL80211_VENDOR_ID,
.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
},
-
+ [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
+ .vendor_id = QCA_NL80211_VENDOR_ID,
+ .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
+ },
};
/*
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 8ffb9fb..7b51c26 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -11821,6 +11821,7 @@
hdd_init_ll_stats_ctx(pHddCtx);
+ hdd_init_nud_stats_ctx(pHddCtx);
#ifdef CONFIG_ENABLE_LINUX_REG
init_completion(&pHddCtx->linux_reg_req);