summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPadma, Santhosh Kumar <skpadma@codeaurora.org>2016-08-08 19:07:06 +0530
committerqcabuildsw <qcabuildsw@localhost>2016-08-19 16:58:18 -0700
commit5e33bebbc2d4f0cb41cf47119a7306dc35108a95 (patch)
tree8f272a7a4f7ecc753d56d54139ace870eda28c81
parent068c4b0fc35d8939d76ecbbf3c34f25290ad9235 (diff)
qcacld-3.0: Get wakelock stats
qcacld-2.0 to qcacld-3.0 propagation Send wakelock stats to HAL layer when it requests through vendor command QCA_NL80211_VENDOR_SUBCMD_WAKELOCK_STATS. This is a blocking request in HDD. Change-Id: Ie043323d90f63c19de2da9d1b8b54bc28d2c8f3d CRs-Fixed: 958964
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c230
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.h63
-rw-r--r--core/mac/inc/sir_api.h20
-rw-r--r--core/wma/inc/wma_api.h1
-rw-r--r--core/wma/src/wma_features.c42
5 files changed, 356 insertions, 0 deletions
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 5bcf100a23c2..b6ec705992ef 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -6819,6 +6819,228 @@ static int wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy,
#undef BPF_CURRENT_OFFSET
#undef BPF_PROGRAM
#undef BPF_MAX
+
+/**
+ * define short names for the global vendor params
+ * used by wlan_hdd_cfg80211_wakelock_stats_rsp_callback()
+ */
+#define PARAM_TOTAL_CMD_EVENT_WAKE \
+ QCA_WLAN_VENDOR_ATTR_TOTAL_CMD_EVENT_WAKE
+#define PARAM_CMD_EVENT_WAKE_CNT_PTR \
+ QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_PTR
+#define PARAM_CMD_EVENT_WAKE_CNT_SZ \
+ QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_SZ
+#define PARAM_TOTAL_DRIVER_FW_LOCAL_WAKE \
+ QCA_WLAN_VENDOR_ATTR_TOTAL_DRIVER_FW_LOCAL_WAKE
+#define PARAM_DRIVER_FW_LOCAL_WAKE_CNT_PTR \
+ QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_PTR
+#define PARAM_DRIVER_FW_LOCAL_WAKE_CNT_SZ \
+ QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_SZ
+#define PARAM_TOTAL_RX_DATA_WAKE \
+ QCA_WLAN_VENDOR_ATTR_TOTAL_RX_DATA_WAKE
+#define PARAM_RX_UNICAST_CNT \
+ QCA_WLAN_VENDOR_ATTR_RX_UNICAST_CNT
+#define PARAM_RX_MULTICAST_CNT \
+ QCA_WLAN_VENDOR_ATTR_RX_MULTICAST_CNT
+#define PARAM_RX_BROADCAST_CNT \
+ QCA_WLAN_VENDOR_ATTR_RX_BROADCAST_CNT
+#define PARAM_ICMP_PKT \
+ QCA_WLAN_VENDOR_ATTR_ICMP_PKT
+#define PARAM_ICMP6_PKT \
+ QCA_WLAN_VENDOR_ATTR_ICMP6_PKT
+#define PARAM_ICMP6_RA \
+ QCA_WLAN_VENDOR_ATTR_ICMP6_RA
+#define PARAM_ICMP6_NA \
+ QCA_WLAN_VENDOR_ATTR_ICMP6_NA
+#define PARAM_ICMP6_NS \
+ QCA_WLAN_VENDOR_ATTR_ICMP6_NS
+#define PARAM_ICMP4_RX_MULTICAST_CNT \
+ QCA_WLAN_VENDOR_ATTR_ICMP4_RX_MULTICAST_CNT
+#define PARAM_ICMP6_RX_MULTICAST_CNT \
+ QCA_WLAN_VENDOR_ATTR_ICMP6_RX_MULTICAST_CNT
+#define PARAM_OTHER_RX_MULTICAST_CNT \
+ QCA_WLAN_VENDOR_ATTR_OTHER_RX_MULTICAST_CNT
+
+
+/**
+ * hdd_send_wakelock_stats() - API to send wakelock stats
+ * @ctx: context to be passed to callback
+ * @data: data passed to callback
+ *
+ * This function is used to send wake lock stats to HAL layer
+ *
+ * Return: 0 on success, error number otherwise.
+ */
+static uint32_t hdd_send_wakelock_stats(hdd_context_t *hdd_ctx,
+ const struct sir_wake_lock_stats *data)
+{
+ struct sk_buff *skb;
+ uint32_t nl_buf_len;
+ uint32_t total_rx_data_wake, rx_multicast_cnt;
+ uint32_t ipv6_rx_multicast_addr_cnt;
+
+ ENTER();
+
+ nl_buf_len = NLMSG_HDRLEN;
+ nl_buf_len +=
+ QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX *
+ (NLMSG_HDRLEN + sizeof(uint32_t));
+
+ skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+
+ if (!skb) {
+ hdd_log(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
+ return -ENOMEM;
+ }
+
+ hdd_log(LOG1, "wow_ucast_wake_up_count %d",
+ data->wow_ucast_wake_up_count);
+ hdd_log(LOG1, "wow_bcast_wake_up_count %d",
+ data->wow_bcast_wake_up_count);
+ hdd_log(LOG1, "wow_ipv4_mcast_wake_up_count %d",
+ data->wow_ipv4_mcast_wake_up_count);
+ hdd_log(LOG1, "wow_ipv6_mcast_wake_up_count %d",
+ data->wow_ipv6_mcast_wake_up_count);
+ hdd_log(LOG1, "wow_ipv6_mcast_ra_stats %d",
+ data->wow_ipv6_mcast_ra_stats);
+ hdd_log(LOG1, "wow_ipv6_mcast_ns_stats %d",
+ data->wow_ipv6_mcast_ns_stats);
+ hdd_log(LOG1, "wow_ipv6_mcast_na_stats %d",
+ data->wow_ipv6_mcast_na_stats);
+
+ ipv6_rx_multicast_addr_cnt =
+ data->wow_ipv6_mcast_wake_up_count +
+ data->wow_ipv6_mcast_ra_stats +
+ data->wow_ipv6_mcast_ns_stats +
+ data->wow_ipv6_mcast_na_stats;
+
+ rx_multicast_cnt =
+ data->wow_ipv4_mcast_wake_up_count +
+ ipv6_rx_multicast_addr_cnt;
+
+ total_rx_data_wake =
+ data->wow_ucast_wake_up_count +
+ data->wow_bcast_wake_up_count +
+ rx_multicast_cnt;
+
+ if (nla_put_u32(skb, PARAM_TOTAL_CMD_EVENT_WAKE, 0) ||
+ nla_put_u32(skb, PARAM_CMD_EVENT_WAKE_CNT_PTR, 0) ||
+ nla_put_u32(skb, PARAM_CMD_EVENT_WAKE_CNT_SZ, 0) ||
+ nla_put_u32(skb, PARAM_TOTAL_DRIVER_FW_LOCAL_WAKE, 0) ||
+ nla_put_u32(skb, PARAM_DRIVER_FW_LOCAL_WAKE_CNT_PTR, 0) ||
+ nla_put_u32(skb, PARAM_DRIVER_FW_LOCAL_WAKE_CNT_SZ, 0) ||
+ nla_put_u32(skb, PARAM_TOTAL_RX_DATA_WAKE,
+ total_rx_data_wake) ||
+ nla_put_u32(skb, PARAM_RX_UNICAST_CNT,
+ data->wow_ucast_wake_up_count) ||
+ nla_put_u32(skb, PARAM_RX_MULTICAST_CNT,
+ rx_multicast_cnt) ||
+ nla_put_u32(skb, PARAM_RX_BROADCAST_CNT,
+ data->wow_bcast_wake_up_count) ||
+ nla_put_u32(skb, PARAM_ICMP6_RA,
+ data->wow_ipv6_mcast_ra_stats) ||
+ nla_put_u32(skb, PARAM_ICMP6_NA,
+ data->wow_ipv6_mcast_na_stats) ||
+ nla_put_u32(skb, PARAM_ICMP6_NS,
+ data->wow_ipv6_mcast_ns_stats) ||
+ nla_put_u32(skb, PARAM_ICMP4_RX_MULTICAST_CNT,
+ data->wow_ipv4_mcast_wake_up_count) ||
+ nla_put_u32(skb, PARAM_ICMP6_RX_MULTICAST_CNT,
+ ipv6_rx_multicast_addr_cnt) ||
+ nla_put_u32(skb, PARAM_OTHER_RX_MULTICAST_CNT, 0)) {
+ hdd_log(LOGE, FL("nla put fail"));
+ goto nla_put_failure;
+ }
+
+ cfg80211_vendor_cmd_reply(skb);
+
+ EXIT();
+ return 0;
+
+nla_put_failure:
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
+/**
+ * __wlan_hdd_cfg80211_get_wakelock_stats() - gets wake lock stats
+ * @wiphy: wiphy pointer
+ * @wdev: pointer to struct wireless_dev
+ * @data: pointer to incoming NL vendor data
+ * @data_len: length of @data
+ *
+ * This function parses the incoming NL vendor command data attributes and
+ * invokes the SME Api and blocks on a completion variable.
+ * WMA copies required data and invokes callback
+ * wlan_hdd_cfg80211_wakelock_stats_rsp_callback to send wake lock stats.
+ *
+ * Return: 0 on success; error number otherwise.
+ */
+static int __wlan_hdd_cfg80211_get_wakelock_stats(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ int status, ret;
+ struct sir_wake_lock_stats wake_lock_stats;
+ QDF_STATUS qdf_status;
+
+ ENTER();
+
+ if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+ hdd_log(LOGE, FL("Command not allowed in FTM mode"));
+ return -EINVAL;
+ }
+
+ status = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != status)
+ return -EINVAL;
+
+ qdf_status = wma_get_wakelock_stats(&wake_lock_stats);
+ if (qdf_status != QDF_STATUS_SUCCESS) {
+ hdd_log(LOGE,
+ FL("failed to get wakelock stats(err=%d)"), qdf_status);
+ return -EINVAL;
+ }
+
+ ret = hdd_send_wakelock_stats(hdd_ctx,
+ &wake_lock_stats);
+ if (ret)
+ hdd_log(LOGE, FL("Failed to post wake lock stats"));
+
+ EXIT();
+ return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_get_wakelock_stats() - gets wake lock stats
+ * @wiphy: wiphy pointer
+ * @wdev: pointer to struct wireless_dev
+ * @data: pointer to incoming NL vendor data
+ * @data_len: length of @data
+ *
+ * This function parses the incoming NL vendor command data attributes and
+ * invokes the SME Api and blocks on a completion variable.
+ * WMA copies required data and invokes callback
+ * wlan_hdd_cfg80211_wakelock_stats_rsp_callback to send wake lock stats.
+ *
+ * Return: 0 on success; error number otherwise.
+ */
+static int wlan_hdd_cfg80211_get_wakelock_stats(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ int ret;
+
+ cds_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_get_wakelock_stats(wiphy, wdev, data,
+ data_len);
+ cds_ssr_protect(__func__);
+
+ return ret;
+}
+
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
{
.info.vendor_id = QCA_NL80211_VENDOR_ID,
@@ -7352,6 +7574,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
.doit = wlan_hdd_cfg80211_process_ndp_cmd
},
#endif
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlan_hdd_cfg80211_get_wakelock_stats
+ },
};
/**
diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h
index 1bd642d9d583..3edf6cbceda9 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.h
+++ b/core/hdd/src/wlan_hdd_cfg80211.h
@@ -374,6 +374,9 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_NDP = 81,
QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER = 83,
+
+ QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS = 85,
+
/* OCB commands */
QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG = 92,
QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME = 93,
@@ -2421,6 +2424,66 @@ enum qca_wlan_vendor_attr_packet_filter {
};
/**
+ * enum qca_wlan_vendor_attr_wake_stats - wake lock stats
+ * @QCA_WLAN_VENDOR_ATTR_GET_WAKE_STATS_INVALID: invalid
+ * @QCA_WLAN_VENDOR_ATTR_TOTAL_CMD_EVENT_WAKE:
+ * @QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_PTR:
+ * @QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_SZ:
+ * @QCA_WLAN_VENDOR_ATTR_TOTAL_DRIVER_FW_LOCAL_WAKE:
+ * @QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_PTR:
+ * @QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_SZ:
+ * @QCA_WLAN_VENDOR_ATTR_TOTAL_RX_DATA_WAKE:
+ * total rx wakeup count
+ * @QCA_WLAN_VENDOR_ATTR_RX_UNICAST_CNT:
+ * Total rx unicast packet which woke up host
+ * @QCA_WLAN_VENDOR_ATTR_RX_MULTICAST_CNT:
+ * Total rx multicast packet which woke up host
+ * @QCA_WLAN_VENDOR_ATTR_RX_BROADCAST_CNT:
+ * Total rx broadcast packet which woke up host
+ * @QCA_WLAN_VENDOR_ATTR_ICMP_PKT:
+ * wake icmp packet count
+ * @QCA_WLAN_VENDOR_ATTR_ICMP6_PKT:
+ * wake icmp6 packet count
+ * @QCA_WLAN_VENDOR_ATTR_ICMP6_RA:
+ * wake icmp6 RA packet count
+ * @QCA_WLAN_VENDOR_ATTR_ICMP6_NA:
+ * wake icmp6 NA packet count
+ * @QCA_WLAN_VENDOR_ATTR_ICMP6_NS:
+ * wake icmp6 NS packet count
+ * @QCA_WLAN_VENDOR_ATTR_ICMP4_RX_MULTICAST_CNT:
+ * Rx wake packet count due to ipv4 multicast
+ * @QCA_WLAN_VENDOR_ATTR_ICMP6_RX_MULTICAST_CNT:
+ * Rx wake packet count due to ipv6 multicast
+ * @QCA_WLAN_VENDOR_ATTR_OTHER_RX_MULTICAST_CNT:
+ * Rx wake packet count due to non-ipv4 and non-ipv6 packets
+ */
+enum qca_wlan_vendor_attr_wake_stats {
+ QCA_WLAN_VENDOR_ATTR_GET_WAKE_STATS_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_TOTAL_CMD_EVENT_WAKE,
+ QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_PTR,
+ QCA_WLAN_VENDOR_ATTR_CMD_EVENT_WAKE_CNT_SZ,
+ QCA_WLAN_VENDOR_ATTR_TOTAL_DRIVER_FW_LOCAL_WAKE,
+ QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_PTR,
+ QCA_WLAN_VENDOR_ATTR_DRIVER_FW_LOCAL_WAKE_CNT_SZ,
+ QCA_WLAN_VENDOR_ATTR_TOTAL_RX_DATA_WAKE,
+ QCA_WLAN_VENDOR_ATTR_RX_UNICAST_CNT,
+ QCA_WLAN_VENDOR_ATTR_RX_MULTICAST_CNT,
+ QCA_WLAN_VENDOR_ATTR_RX_BROADCAST_CNT,
+ QCA_WLAN_VENDOR_ATTR_ICMP_PKT,
+ QCA_WLAN_VENDOR_ATTR_ICMP6_PKT,
+ QCA_WLAN_VENDOR_ATTR_ICMP6_RA,
+ QCA_WLAN_VENDOR_ATTR_ICMP6_NA,
+ QCA_WLAN_VENDOR_ATTR_ICMP6_NS,
+ QCA_WLAN_VENDOR_ATTR_ICMP4_RX_MULTICAST_CNT,
+ QCA_WLAN_VENDOR_ATTR_ICMP6_RX_MULTICAST_CNT,
+ QCA_WLAN_VENDOR_ATTR_OTHER_RX_MULTICAST_CNT,
+ /* keep last */
+ QCA_WLAN_VENDOR_GET_WAKE_STATS_AFTER_LAST,
+ QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX =
+ QCA_WLAN_VENDOR_GET_WAKE_STATS_AFTER_LAST - 1,
+};
+
+/**
* enum qca_vendor_attr_get_tsf: Vendor attributes for TSF capture
* @QCA_WLAN_VENDOR_ATTR_TSF_INVALID: Invalid attribute value
* @QCA_WLAN_VENDOR_ATTR_TSF_CMD: enum qca_tsf_operation (u32)
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index c4b7daf8a2cd..0a03be79b056 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -5936,6 +5936,26 @@ struct sir_bpf_get_offload {
};
/**
+ * struct sir_wake_lock_stats - wake lock stats structure
+ * @wow_ucast_wake_up_count: Unicast wakeup count
+ * @wow_bcast_wake_up_count: Broadcast wakeup count
+ * @wow_ipv4_mcast_wake_up_count: ipv4 multicast wakeup count
+ * @wow_ipv6_mcast_wake_up_count: ipv6 multicast wakeup count
+ * @wow_ipv6_mcast_ra_stats: ipv6 multicast ra stats
+ * @wow_ipv6_mcast_ns_stats: ipv6 multicast ns stats
+ * @wow_ipv6_mcast_na_stats: ipv6 multicast na stats
+ */
+struct sir_wake_lock_stats {
+ uint32_t wow_ucast_wake_up_count;
+ uint32_t wow_bcast_wake_up_count;
+ uint32_t wow_ipv4_mcast_wake_up_count;
+ uint32_t wow_ipv6_mcast_wake_up_count;
+ uint32_t wow_ipv6_mcast_ra_stats;
+ uint32_t wow_ipv6_mcast_ns_stats;
+ uint32_t wow_ipv6_mcast_na_stats;
+};
+
+/**
* enum ht_capability_fields - HT Capabilities bit fields
* @HT_CAPS_LDPC: ldpc coding capability bit field
* @HT_CAPS_SUPPORTED_CHANNEL_SET: channel width set bit field
diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h
index 00b64767a203..a80887894351 100644
--- a/core/wma/inc/wma_api.h
+++ b/core/wma/inc/wma_api.h
@@ -268,4 +268,5 @@ static inline QDF_STATUS wma_register_ndp_cb(QDF_STATUS (*pe_ndp_event_handler)
bool wma_is_p2p_lo_capable(void);
QDF_STATUS wma_p2p_lo_start(struct sir_p2p_lo_start *params);
QDF_STATUS wma_p2p_lo_stop(u_int32_t vdev_id);
+QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *wake_lock_stats);
#endif
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 316fae5b809e..d34050c967f9 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -7905,3 +7905,45 @@ int wma_p2p_lo_event_handler(void *handle, uint8_t *event_buf,
return 0;
}
+
+/**
+ * wma_get_wakelock_stats() - Collects wake lock stats
+ * @wake_lock_stats: wakelock structure to be filled
+ *
+ * This function collects wake lock stats
+ *
+ * Return: VOS_STATUS_SUCCESS on success, error number otherwise
+ */
+QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *wake_lock_stats)
+{
+ tp_wma_handle wma_handle;
+
+ wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+ if (!wake_lock_stats) {
+ WMA_LOGE("%s: invalid pointer", __func__);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!wma_handle) {
+ WMA_LOGE("%s: WMA context is invalid!", __func__);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ wake_lock_stats->wow_ucast_wake_up_count =
+ wma_handle->wow_ucast_wake_up_count;
+ wake_lock_stats->wow_bcast_wake_up_count =
+ wma_handle->wow_bcast_wake_up_count;
+ wake_lock_stats->wow_ipv4_mcast_wake_up_count =
+ wma_handle->wow_ipv4_mcast_wake_up_count;
+ wake_lock_stats->wow_ipv6_mcast_wake_up_count =
+ wma_handle->wow_ipv6_mcast_wake_up_count;
+ wake_lock_stats->wow_ipv6_mcast_ra_stats =
+ wma_handle->wow_ipv6_mcast_ra_stats;
+ wake_lock_stats->wow_ipv6_mcast_ns_stats =
+ wma_handle->wow_ipv6_mcast_ns_stats;
+ wake_lock_stats->wow_ipv6_mcast_na_stats =
+ wma_handle->wow_ipv6_mcast_na_stats;
+
+ return QDF_STATUS_SUCCESS;
+}