summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDustin Brown <dustinb@codeaurora.org>2017-01-11 16:39:12 -0800
committerqcabuildsw <qcabuildsw@localhost>2017-01-13 00:34:27 -0800
commitc81c91db91290aa865ff2c8bb2e0c268809477e0 (patch)
tree31476b5f8fae1bf9b500a3d4cb26785c5ee51944
parent529f71ca231829011379b8263fc6cf44acbafee6 (diff)
qcacld-3.0: Track WoW stats per vdev
Currently wake-on-wireless wake-up stats are tracked globaly. Split WoW stats tracking per virtual device instead. Change-Id: If913081cf726d20b9cda2dde58a9b9f4f7cbcf19 CRs-Fixed: 1110403
-rw-r--r--core/mac/inc/sir_api.h40
-rw-r--r--core/wma/inc/wma.h20
-rw-r--r--core/wma/src/wma_features.c359
-rw-r--r--core/wma/src/wma_main.c178
4 files changed, 325 insertions, 272 deletions
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 5afff55896ae..dd8f57a2f3e2 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -6178,6 +6178,7 @@ struct sir_bpf_get_offload {
/**
* struct sir_wake_lock_stats - wake lock stats structure
+ * @wow_unspecified_wake_up_count: number of non-wow related wake ups
* @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
@@ -6192,8 +6193,10 @@ struct sir_bpf_get_offload {
* @wow_gscan_wake_up_count: gscan wakeup count
* @wow_pno_complete_wake_up_count: pno complete wakeup count
* @wow_pno_match_wake_up_count: pno match wakeup count
+ * @wow_oem_response_wake_up_count: oem response wakeup count
*/
struct sir_wake_lock_stats {
+ uint32_t wow_unspecified_wake_up_count;
uint32_t wow_ucast_wake_up_count;
uint32_t wow_bcast_wake_up_count;
uint32_t wow_ipv4_mcast_wake_up_count;
@@ -6208,6 +6211,43 @@ struct sir_wake_lock_stats {
uint32_t wow_gscan_wake_up_count;
uint32_t wow_pno_complete_wake_up_count;
uint32_t wow_pno_match_wake_up_count;
+ uint32_t wow_oem_response_wake_up_count;
+};
+
+/**
+ * struct sir_vdev_wow_stats - container for per vdev wow related stat counters
+ * @ucast: Unicast wakeup count
+ * @bcast: Broadcast wakeup count
+ * @ipv4_mcast: ipv4 multicast wakeup count
+ * @ipv6_mcast: ipv6 multicast wakeup count
+ * @ipv6_mcast_ra: ipv6 multicast ra stats
+ * @ipv6_mcast_ns: ipv6 multicast ns stats
+ * @ipv6_mcast_na: ipv6 multicast na stats
+ * @icmpv4: ipv4 icmp packet count
+ * @icmpv6: ipv6 icmp packet count
+ * @rssi_breach: rssi breach wakeup count
+ * @low_rssi: low rssi wakeup count
+ * @gscan: gscan wakeup count
+ * @pno_complete: pno complete wakeup count
+ * @pno_match: pno match wakeup count
+ * @oem_response: oem response wakeup count
+ */
+struct sir_vdev_wow_stats {
+ uint32_t ucast;
+ uint32_t bcast;
+ uint32_t ipv4_mcast;
+ uint32_t ipv6_mcast;
+ uint32_t ipv6_mcast_ra;
+ uint32_t ipv6_mcast_ns;
+ uint32_t ipv6_mcast_na;
+ uint32_t icmpv4;
+ uint32_t icmpv6;
+ uint32_t rssi_breach;
+ uint32_t low_rssi;
+ uint32_t gscan;
+ uint32_t pno_complete;
+ uint32_t pno_match;
+ uint32_t oem_response;
};
/**
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index 6d700edfb7a2..3e8f9aaf2c4e 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1013,6 +1013,7 @@ typedef struct {
* @wep_default_key_idx: wep default index for group key
* @arp_offload_req: cached arp offload request
* @ns_offload_req: cached ns offload request
+ * @wow_stats: stat counters for WoW related events
* It stores parameters per vdev in wma.
*/
struct wma_txrx_node {
@@ -1091,6 +1092,7 @@ struct wma_txrx_node {
tSirHostOffloadReq arp_offload_req;
tSirHostOffloadReq ns_offload_req;
bool is_vdev_valid;
+ struct sir_vdev_wow_stats wow_stats;
};
#if defined(QCA_WIFI_FTM)
@@ -1554,21 +1556,7 @@ typedef struct {
qdf_atomic_t scan_id_counter;
qdf_atomic_t num_pending_scans;
wma_peer_authorized_fp peer_authorized_cb;
- uint32_t wow_pno_match_wake_up_count;
- uint32_t wow_pno_complete_wake_up_count;
- uint32_t wow_gscan_wake_up_count;
- uint32_t wow_low_rssi_wake_up_count;
- uint32_t wow_rssi_breach_wake_up_count;
- 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;
- uint32_t wow_icmpv4_count;
- uint32_t wow_icmpv6_count;
- uint32_t wow_oem_response_wake_up_count;
+ uint32_t wow_unspecified_wake_count;
/* OCB request contexts */
struct sir_ocb_config *ocb_config_req;
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index aea1db58a7de..ba5481b3e753 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -117,41 +117,56 @@ static const uint8_t discvr_mask[] = {0xf0, 0x00, 0x00, 0xf8};
#ifdef FEATURE_WLAN_DIAG_SUPPORT
/**
* qdf_wma_wow_wakeup_stats_event()- send wow wakeup stats
- * @tp_wma_handle wma: WOW wakeup packet counter
*
* This function sends wow wakeup stats diag event
*
* Return: void.
*/
-static void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)
+static void qdf_wma_wow_wakeup_stats_event(void)
{
+ QDF_STATUS status;
+ struct sir_wake_lock_stats stats;
WLAN_HOST_DIAG_EVENT_DEF(WowStats,
- struct host_event_wlan_powersave_wow_stats);
- qdf_mem_zero(&WowStats, sizeof(WowStats));
+ struct host_event_wlan_powersave_wow_stats);
+
+ status = wma_get_wakelock_stats(&stats);
+ if (QDF_IS_STATUS_ERROR(status))
+ return;
- WowStats.wow_bcast_wake_up_count = wma->wow_bcast_wake_up_count;
+ qdf_mem_zero(&WowStats, sizeof(WowStats));
+ WowStats.wow_bcast_wake_up_count =
+ stats.wow_bcast_wake_up_count;
WowStats.wow_ipv4_mcast_wake_up_count =
- wma->wow_ipv4_mcast_wake_up_count;
+ stats.wow_ipv4_mcast_wake_up_count;
WowStats.wow_ipv6_mcast_wake_up_count =
- wma->wow_ipv6_mcast_wake_up_count;
- WowStats.wow_ipv6_mcast_ra_stats = wma->wow_ipv6_mcast_ra_stats;
- WowStats.wow_ipv6_mcast_ns_stats = wma->wow_ipv6_mcast_ns_stats;
- WowStats.wow_ipv6_mcast_na_stats = wma->wow_ipv6_mcast_na_stats;
- WowStats.wow_pno_match_wake_up_count = wma->wow_pno_match_wake_up_count;
+ stats.wow_ipv6_mcast_wake_up_count;
+ WowStats.wow_ipv6_mcast_ra_stats =
+ stats.wow_ipv6_mcast_ra_stats;
+ WowStats.wow_ipv6_mcast_ns_stats =
+ stats.wow_ipv6_mcast_ns_stats;
+ WowStats.wow_ipv6_mcast_na_stats =
+ stats.wow_ipv6_mcast_na_stats;
+ WowStats.wow_pno_match_wake_up_count =
+ stats.wow_pno_match_wake_up_count;
WowStats.wow_pno_complete_wake_up_count =
- wma->wow_pno_complete_wake_up_count;
- WowStats.wow_gscan_wake_up_count = wma->wow_gscan_wake_up_count;
- WowStats.wow_low_rssi_wake_up_count = wma->wow_low_rssi_wake_up_count;
+ stats.wow_pno_complete_wake_up_count;
+ WowStats.wow_gscan_wake_up_count =
+ stats.wow_gscan_wake_up_count;
+ WowStats.wow_low_rssi_wake_up_count =
+ stats.wow_low_rssi_wake_up_count;
WowStats.wow_rssi_breach_wake_up_count =
- wma->wow_rssi_breach_wake_up_count;
- WowStats.wow_icmpv4_count = wma->wow_icmpv4_count;
- WowStats.wow_icmpv6_count = wma->wow_icmpv6_count;
+ stats.wow_rssi_breach_wake_up_count;
+ WowStats.wow_icmpv4_count =
+ stats.wow_icmpv4_count;
+ WowStats.wow_icmpv6_count =
+ stats.wow_icmpv6_count;
WowStats.wow_oem_response_wake_up_count =
- wma->wow_oem_response_wake_up_count;
+ stats.wow_oem_response_wake_up_count;
+
WLAN_HOST_DIAG_EVENT_REPORT(&WowStats, EVENT_WLAN_POWERSAVE_WOW_STATS);
}
#else
-static void qdf_wma_wow_wakeup_stats_event(tp_wma_handle wma)
+static void qdf_wma_wow_wakeup_stats_event(void)
{
return;
}
@@ -2426,41 +2441,40 @@ static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason)
}
/**
- * wma_wow_wake_up_stats_display() - display wow wake up stats
- * @wma: Pointer to wma handle
+ * wma_wow_stats_display() - display wow wake up stats
+ * @stats: per vdev stats counters
*
* Return: none
*/
-static void wma_wow_wake_up_stats_display(tp_wma_handle wma)
+static void wma_wow_stats_display(struct sir_vdev_wow_stats *stats)
{
WMA_LOGA("uc %d bc %d v4_mc %d v6_mc %d ra %d ns %d na %d pno_match %d pno_complete %d gscan %d low_rssi %d rssi_breach %d icmp %d icmpv6 %d oem %d",
- wma->wow_ucast_wake_up_count,
- wma->wow_bcast_wake_up_count,
- wma->wow_ipv4_mcast_wake_up_count,
- wma->wow_ipv6_mcast_wake_up_count,
- wma->wow_ipv6_mcast_ra_stats,
- wma->wow_ipv6_mcast_ns_stats,
- wma->wow_ipv6_mcast_na_stats,
- wma->wow_pno_match_wake_up_count,
- wma->wow_pno_complete_wake_up_count,
- wma->wow_gscan_wake_up_count,
- wma->wow_low_rssi_wake_up_count,
- wma->wow_rssi_breach_wake_up_count,
- wma->wow_icmpv4_count,
- wma->wow_icmpv6_count,
- wma->wow_oem_response_wake_up_count);
-
- return;
+ stats->ucast,
+ stats->bcast,
+ stats->ipv4_mcast,
+ stats->ipv6_mcast,
+ stats->ipv6_mcast_ra,
+ stats->ipv6_mcast_ns,
+ stats->ipv6_mcast_na,
+ stats->pno_match,
+ stats->pno_complete,
+ stats->gscan,
+ stats->low_rssi,
+ stats->rssi_breach,
+ stats->icmpv4,
+ stats->icmpv6,
+ stats->oem_response);
}
/**
* wma_wow_ipv6_mcast_stats() - ipv6 mcast wake up stats
- * @wma: Pointer to wma handle
+ * @stats: per vdev stats counters
* @data: Pointer to pattern match data
*
* Return: none
*/
-static void wma_wow_ipv6_mcast_stats(tp_wma_handle wma, uint8_t *data)
+static void wma_wow_ipv6_mcast_stats(struct sir_vdev_wow_stats *stats,
+ uint8_t *data)
{
static const uint8_t ipv6_ether_type[] = {0x86, 0xDD};
@@ -2468,16 +2482,16 @@ static void wma_wow_ipv6_mcast_stats(tp_wma_handle wma, uint8_t *data)
sizeof(ipv6_ether_type))) {
if (WMA_ICMP_V6_HEADER_TYPE ==
*(data + WMA_ICMP_V6_HEADER_OFFSET)) {
- wma->wow_icmpv6_count++;
+ stats->icmpv6++;
if (WMA_ICMP_V6_RA_TYPE ==
*(data + WMA_ICMP_V6_TYPE_OFFSET))
- wma->wow_ipv6_mcast_ra_stats++;
+ stats->ipv6_mcast_ra++;
else if (WMA_ICMP_V6_NS_TYPE ==
*(data + WMA_ICMP_V6_TYPE_OFFSET))
- wma->wow_ipv6_mcast_ns_stats++;
+ stats->ipv6_mcast_ns++;
else if (WMA_ICMP_V6_NA_TYPE ==
*(data + WMA_ICMP_V6_TYPE_OFFSET))
- wma->wow_ipv6_mcast_na_stats++;
+ stats->ipv6_mcast_na++;
else
WMA_LOGA("ICMP V6 type : 0x%x",
*(data + WMA_ICMP_V6_TYPE_OFFSET));
@@ -2495,92 +2509,99 @@ static void wma_wow_ipv6_mcast_stats(tp_wma_handle wma, uint8_t *data)
}
/**
- * wma_wow_wake_up_stats() - maintain wow pattern match wake up stats
- * @wma: Pointer to wma handle
+ * wma_inc_wow_stats() - maintain wow pattern match wake up stats
+ * @stats: per vdev stats counters
* @data: Pointer to pattern match data
* @len: Pattern match data length
- * @event: Wake up event
+ * @reason: Wake up reason
*
* Return: none
*/
-static void wma_wow_wake_up_stats(tp_wma_handle wma, uint8_t *data,
- int32_t len, WOW_WAKE_REASON_TYPE event)
+static void wma_inc_wow_stats(struct sir_vdev_wow_stats *stats, uint8_t *data,
+ int32_t len, WOW_WAKE_REASON_TYPE reason)
{
- switch (event) {
-
+ switch (reason) {
case WOW_REASON_BPF_ALLOW:
case WOW_REASON_PATTERN_MATCH_FOUND:
+ if (!data || len == 0) {
+ WMA_LOGE("Null data packet for wow reason %s",
+ wma_wow_wake_reason_str(reason));
+ break;
+ }
+
if (WMA_BCAST_MAC_ADDR == *data) {
- wma->wow_bcast_wake_up_count++;
+ stats->bcast++;
if (len >= WMA_IPV4_PROTO_GET_MIN_LEN &&
qdf_nbuf_data_is_icmp_pkt(data))
- wma->wow_icmpv4_count++;
+ stats->icmpv4++;
else if ((len > WMA_ICMP_V6_TYPE_OFFSET) &&
qdf_nbuf_data_is_icmpv6_pkt(data))
- wma->wow_icmpv6_count++;
+ stats->icmpv6++;
} else if (WMA_MCAST_IPV4_MAC_ADDR == *data) {
- wma->wow_ipv4_mcast_wake_up_count++;
+ stats->ipv4_mcast++;
if (len >= WMA_IPV4_PROTO_GET_MIN_LEN &&
WMA_ICMP_PROTOCOL == *(data + WMA_IPV4_PROTOCOL))
- wma->wow_icmpv4_count++;
+ stats->icmpv4++;
} else if (WMA_MCAST_IPV6_MAC_ADDR == *data) {
- wma->wow_ipv6_mcast_wake_up_count++;
+ stats->ipv6_mcast++;
if (len > WMA_ICMP_V6_TYPE_OFFSET)
- wma_wow_ipv6_mcast_stats(wma, data);
+ wma_wow_ipv6_mcast_stats(stats, data);
else
WMA_LOGA("ICMP_V6 data len %d", len);
} else {
- wma->wow_ucast_wake_up_count++;
+ stats->ucast++;
if (qdf_nbuf_data_is_ipv4_mcast_pkt(data))
- wma->wow_ipv4_mcast_wake_up_count++;
+ stats->ipv4_mcast++;
else if (qdf_nbuf_data_is_ipv6_mcast_pkt(data))
- wma->wow_ipv6_mcast_wake_up_count++;
+ stats->ipv6_mcast++;
if (len >= WMA_IPV4_PROTO_GET_MIN_LEN &&
qdf_nbuf_data_is_icmp_pkt(data))
- wma->wow_icmpv4_count++;
+ stats->icmpv4++;
else if (len > WMA_ICMP_V6_TYPE_OFFSET &&
qdf_nbuf_data_is_icmpv6_pkt(data))
- wma->wow_icmpv6_count++;
+ stats->icmpv6++;
}
break;
case WOW_REASON_RA_MATCH:
- wma->wow_icmpv6_count++;
- wma->wow_ipv6_mcast_ra_stats++;
- wma->wow_ipv6_mcast_wake_up_count++;
+ stats->ipv6_mcast++;
+ stats->ipv6_mcast_ra++;
+ stats->icmpv6++;
break;
case WOW_REASON_NLOD:
- wma->wow_pno_match_wake_up_count++;
+ stats->pno_match++;
break;
case WOW_REASON_NLO_SCAN_COMPLETE:
- wma->wow_pno_complete_wake_up_count++;
+ stats->pno_complete++;
break;
case WOW_REASON_LOW_RSSI:
- wma->wow_low_rssi_wake_up_count++;
+ stats->low_rssi++;
break;
case WOW_REASON_EXTSCAN:
- wma->wow_gscan_wake_up_count++;
+ stats->gscan++;
break;
case WOW_REASON_RSSI_BREACH_EVENT:
- wma->wow_rssi_breach_wake_up_count++;
+ stats->rssi_breach++;
break;
case WOW_REASON_OEM_RESPONSE_EVENT:
- wma->wow_oem_response_wake_up_count++;
+ stats->oem_response++;
break;
default:
- WMA_LOGE("Unknown wake up reason");
- break;
+ WMA_LOGI("Stats for WoW reason %s are not tracked",
+ wma_wow_wake_reason_str(reason));
+
+ /* don't bother displaying stats that haven't changed */
+ return;
}
- wma_wow_wake_up_stats_display(wma);
- return;
+ wma_wow_stats_display(stats);
}
#ifdef FEATURE_WLAN_EXTSCAN
@@ -3189,6 +3210,28 @@ exit_handler:
wma_beacon_miss_handler(wma, wake_info->vdev_id, 0);
}
+static const char *wma_vdev_type_str(uint32_t vdev_type)
+{
+ switch (vdev_type) {
+ case WMI_VDEV_TYPE_AP:
+ return "AP";
+ case WMI_VDEV_TYPE_STA:
+ return "STA";
+ case WMI_VDEV_TYPE_IBSS:
+ return "IBSS";
+ case WMI_VDEV_TYPE_MONITOR:
+ return "MONITOR";
+ case WMI_VDEV_TYPE_NAN:
+ return "NAN";
+ case WMI_VDEV_TYPE_OCB:
+ return "OCB";
+ case WMI_VDEV_TYPE_NDI:
+ return "NDI";
+ default:
+ return "unknown";
+ }
+}
+
/**
* wma_wow_wakeup_host_event() - wakeup host event handler
* @handle: wma handle
@@ -3204,14 +3247,13 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
uint32_t len)
{
tp_wma_handle wma = (tp_wma_handle) handle;
+ struct wma_txrx_node *wma_vdev;
WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *param_buf;
WOW_EVENT_INFO_fixed_param *wake_info;
-#ifdef FEATURE_WLAN_SCAN_PNO
- struct wma_txrx_node *node;
-#endif /* FEATURE_WLAN_SCAN_PNO */
uint32_t wake_lock_duration = 0;
void *wmi_cmd_struct_ptr = NULL;
uint32_t tlv_hdr, tag, wow_buf_pkt_len = 0, event_id = 0;
+ uint8_t *wow_buf_data = NULL;
int tlv_ok_status;
param_buf = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *) event;
@@ -3221,15 +3263,18 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
}
wake_info = param_buf->fixed_param;
+ wma_vdev = &wma->interfaces[wake_info->vdev_id];
if ((wake_info->wake_reason != WOW_REASON_UNSPECIFIED) ||
(wake_info->wake_reason == WOW_REASON_UNSPECIFIED &&
!wmi_get_runtime_pm_inprogress(wma->wmi_handle))) {
- WMA_LOGA("WOW wakeup host event received (reason: %s(%d)) for vdev %d",
+ WMA_LOGA("WOW wakeup host event received; reason: %s(%d), vdev_id: %d, vdev_type: %s",
wma_wow_wake_reason_str(wake_info->wake_reason),
- wake_info->wake_reason, wake_info->vdev_id);
+ wake_info->wake_reason,
+ wake_info->vdev_id,
+ wma_vdev ? wma_vdev_type_str(wma_vdev->type) : "null");
qdf_wow_wakeup_host_event(wake_info->wake_reason);
- qdf_wma_wow_wakeup_stats_event(wma);
+ qdf_wma_wow_wakeup_stats_event();
}
qdf_event_set(&wma->wma_resume_event);
@@ -3304,11 +3349,9 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
#ifdef FEATURE_WLAN_SCAN_PNO
case WOW_REASON_NLOD:
- wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_NLOD);
- node = &wma->interfaces[wake_info->vdev_id];
- if (node) {
+ if (wma_vdev) {
WMA_LOGD("NLO match happened");
- node->nlo_match_evt_received = true;
+ wma_vdev->nlo_match_evt_received = true;
cds_host_diag_log_work(&wma->pno_wake_lock,
WMA_PNO_MATCH_WAKE_LOCK_TIMEOUT,
WIFI_POWER_EVENT_WAKELOCK_PNO);
@@ -3331,7 +3374,7 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
WMA_LOGD("Host woken up because of CSA IE");
wma_csa_offload_handler(handle, wmi_cmd_struct_ptr,
wow_buf_pkt_len);
- break;
+ break;
#ifdef FEATURE_WLAN_LPHB
case WOW_REASON_WLAN_HB:
@@ -3348,34 +3391,28 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
case WOW_REASON_RA_MATCH:
#endif /* FEATURE_WLAN_RA_FILTERING */
case WOW_REASON_RECV_MAGIC_PATTERN:
- wma_wow_wake_up_stats_display(wma);
- WMA_LOGD("Wake up for Rx packet, dump starting from ethernet hdr");
- if (param_buf->wow_packet_buffer) {
- /* First 4-bytes of wow_packet_buffer is the length */
- qdf_mem_copy((uint8_t *) &wow_buf_pkt_len,
- param_buf->wow_packet_buffer, 4);
- if (wow_buf_pkt_len) {
- uint8_t *data;
-
- wma_wow_wake_up_stats(wma,
- param_buf->wow_packet_buffer + 4,
- wow_buf_pkt_len,
- wake_info->wake_reason);
- qdf_trace_hex_dump(QDF_MODULE_ID_WMA,
- QDF_TRACE_LEVEL_DEBUG,
- param_buf->wow_packet_buffer + 4,
- wow_buf_pkt_len);
+ if (wma_vdev)
+ wma_wow_stats_display(&wma_vdev->wow_stats);
- data = (uint8_t *)
- (param_buf->wow_packet_buffer + 4);
- wma_wow_parse_data_pkt_buffer(data,
- wow_buf_pkt_len);
- } else {
- WMA_LOGE("wow packet buffer is empty");
- }
- } else {
+ WMA_LOGD("Wake up for Rx packet, dump starting from ethernet hdr");
+ if (!param_buf->wow_packet_buffer) {
WMA_LOGE("No wow packet buffer present");
+ break;
+ }
+
+ /* First 4-bytes of wow_packet_buffer is the length */
+ qdf_mem_copy((uint8_t *)&wow_buf_pkt_len,
+ param_buf->wow_packet_buffer, 4);
+ if (wow_buf_pkt_len == 0) {
+ WMA_LOGE("wow packet buffer is empty");
+ break;
}
+
+ wow_buf_data = (uint8_t *)(param_buf->wow_packet_buffer + 4);
+ qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
+ wow_buf_data, wow_buf_pkt_len);
+ wma_wow_parse_data_pkt_buffer(wow_buf_data, wow_buf_pkt_len);
+
break;
case WOW_REASON_LOW_RSSI:
@@ -3384,7 +3421,6 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
* WMI_ROAM_REASON_SUITABLE_AP will be handled by
* wma_roam_event_callback().
*/
- wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_LOW_RSSI);
WMA_LOGD("Host woken up because of roam event");
if (param_buf->wow_packet_buffer) {
/* Roam event is embedded in wow_packet_buffer */
@@ -3419,7 +3455,6 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
#ifdef FEATURE_WLAN_EXTSCAN
case WOW_REASON_EXTSCAN:
WMA_LOGD("Host woken up because of extscan reason");
- wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_EXTSCAN);
if (param_buf->wow_packet_buffer)
wma_extscan_wow_event_callback(handle,
wmi_cmd_struct_ptr, wow_buf_pkt_len);
@@ -3428,8 +3463,6 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
break;
#endif
case WOW_REASON_RSSI_BREACH_EVENT:
- wma_wow_wake_up_stats(wma, NULL, 0,
- WOW_REASON_RSSI_BREACH_EVENT);
WMA_LOGD("Host woken up because of rssi breach reason");
/* rssi breach event is embedded in wow_packet_buffer */
if (param_buf->wow_packet_buffer)
@@ -3453,8 +3486,6 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
}
break;
case WOW_REASON_OEM_RESPONSE_EVENT:
- wma_wow_wake_up_stats(wma, NULL, 0,
- WOW_REASON_OEM_RESPONSE_EVENT);
/*
* Actual OEM Response event will follow after this
* WOW Wakeup event
@@ -3475,6 +3506,17 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
break;
}
+ /* Log wake reason at appropriate (global/vdev) level */
+ if (wake_info->wake_reason == WOW_REASON_UNSPECIFIED)
+ wma->wow_unspecified_wake_count++;
+ else if (wma_vdev)
+ wma_inc_wow_stats(&wma_vdev->wow_stats,
+ wow_buf_data,
+ wow_buf_data ? wow_buf_pkt_len : 0,
+ wake_info->wake_reason);
+ else
+ WMA_LOGE("Vdev is NULL, but wake reason is vdev related");
+
if (wake_lock_duration) {
cds_host_diag_log_work(&wma->wow_wake_lock,
wake_lock_duration,
@@ -8324,56 +8366,59 @@ int wma_p2p_lo_event_handler(void *handle, uint8_t *event_buf,
}
/**
- * wma_get_wakelock_stats() - Collects wake lock stats
- * @wake_lock_stats: wakelock structure to be filled
+ * wma_get_wakelock_stats() - Populates wake lock stats
+ * @stats: non-null wakelock structure to populate
*
* This function collects wake lock stats
*
- * Return: VOS_STATUS_SUCCESS on success, error number otherwise
+ * Return: QDF_STATUS_SUCCESS on success, error value otherwise
*/
-QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *wake_lock_stats)
+QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *stats)
{
- tp_wma_handle wma_handle;
-
- wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+ t_wma_handle *wma;
+ struct sir_vdev_wow_stats *vstats;
+ int i;
- if (!wake_lock_stats) {
- WMA_LOGE("%s: invalid pointer", __func__);
+ if (!stats) {
+ WMA_LOGE("%s: invalid stats pointer", __func__);
return QDF_STATUS_E_INVAL;
}
- if (!wma_handle) {
- WMA_LOGE("%s: WMA context is invalid!", __func__);
+ wma = cds_get_context(QDF_MODULE_ID_WMA);
+ if (!wma) {
+ WMA_LOGE("%s: invalid WMA context", __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;
- wake_lock_stats->wow_icmpv4_count = wma_handle->wow_icmpv4_count;
- wake_lock_stats->wow_icmpv6_count =
- wma_handle->wow_icmpv6_count;
- wake_lock_stats->wow_rssi_breach_wake_up_count =
- wma_handle->wow_rssi_breach_wake_up_count;
- wake_lock_stats->wow_low_rssi_wake_up_count =
- wma_handle->wow_low_rssi_wake_up_count;
- wake_lock_stats->wow_gscan_wake_up_count =
- wma_handle->wow_gscan_wake_up_count;
- wake_lock_stats->wow_pno_complete_wake_up_count =
- wma_handle->wow_pno_complete_wake_up_count;
- wake_lock_stats->wow_pno_match_wake_up_count =
- wma_handle->wow_pno_match_wake_up_count;
+ /* ensure counters are zeroed */
+ qdf_mem_zero(stats, sizeof(*stats));
+
+ /* populate global level stats */
+ stats->wow_unspecified_wake_up_count = wma->wow_unspecified_wake_count;
+
+ /* populate vdev level stats */
+ for (i = 0; i < wma->max_bssid; ++i) {
+ if (!wma->interfaces[i].handle)
+ continue;
+
+ vstats = &wma->interfaces[i].wow_stats;
+
+ stats->wow_ucast_wake_up_count += vstats->ucast;
+ stats->wow_bcast_wake_up_count += vstats->bcast;
+ stats->wow_ipv4_mcast_wake_up_count += vstats->ipv4_mcast;
+ stats->wow_ipv6_mcast_wake_up_count += vstats->ipv6_mcast;
+ stats->wow_ipv6_mcast_ra_stats += vstats->ipv6_mcast_ra;
+ stats->wow_ipv6_mcast_ns_stats += vstats->ipv6_mcast_ns;
+ stats->wow_ipv6_mcast_na_stats += vstats->ipv6_mcast_na;
+ stats->wow_icmpv4_count += vstats->icmpv4;
+ stats->wow_icmpv6_count += vstats->icmpv6;
+ stats->wow_rssi_breach_wake_up_count += vstats->rssi_breach;
+ stats->wow_low_rssi_wake_up_count += vstats->low_rssi;
+ stats->wow_gscan_wake_up_count += vstats->gscan;
+ stats->wow_pno_complete_wake_up_count += vstats->pno_complete;
+ stats->wow_pno_match_wake_up_count += vstats->pno_match;
+ stats->wow_oem_response_wake_up_count += vstats->oem_response;
+ }
return QDF_STATUS_SUCCESS;
}
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 9180e1595377..004982bc0486 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -1750,119 +1750,99 @@ struct wma_version_info g_wmi_version_info;
*/
static void wma_state_info_dump(char **buf_ptr, uint16_t *size)
{
- tp_wma_handle wma_handle;
+ t_wma_handle *wma;
+ struct sir_vdev_wow_stats *stats;
uint16_t len = 0;
char *buf = *buf_ptr;
struct wma_txrx_node *iface;
uint8_t vdev_id;
- wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
- if (!wma_handle) {
+ wma = cds_get_context(QDF_MODULE_ID_WMA);
+ if (!wma) {
WMA_LOGE("%s: WMA context is invald!", __func__);
return;
}
WMA_LOGI("%s: size of buffer: %d", __func__, *size);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_pno_match_wake_up_count %d",
- wma_handle->wow_pno_match_wake_up_count);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_pno_complete_wake_up_count %d",
- wma_handle->wow_pno_complete_wake_up_count);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_gscan_wake_up_count %d",
- wma_handle->wow_gscan_wake_up_count);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_low_rssi_wake_up_count %d",
- wma_handle->wow_low_rssi_wake_up_count);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_rssi_breach_wake_up_count %d",
- wma_handle->wow_rssi_breach_wake_up_count);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_ucast_wake_up_count %d",
- wma_handle->wow_ucast_wake_up_count);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_bcast_wake_up_count %d",
- wma_handle->wow_bcast_wake_up_count);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_ipv4_mcast_wake_up_count %d",
- wma_handle->wow_ipv4_mcast_wake_up_count);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_ipv6_mcast_ra_stats %d",
- wma_handle->wow_ipv6_mcast_ra_stats);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_ipv6_mcast_ns_stats %d",
- wma_handle->wow_ipv6_mcast_ns_stats);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n wow_ipv6_mcast_na_stats %d",
- wma_handle->wow_ipv6_mcast_na_stats);
-
- for (vdev_id = 0; vdev_id < wma_handle->max_bssid; vdev_id++) {
- if (!wma_handle->interfaces[vdev_id].handle)
+ for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
+ iface = &wma->interfaces[vdev_id];
+ if (!iface->handle)
continue;
- iface = &wma_handle->interfaces[vdev_id];
-
- len += qdf_scnprintf(buf + len, *size - len,
- "\n vdev_id %d",
- vdev_id);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n conn_state %d",
- iface->conn_state);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n dtimPeriod %d",
- iface->dtimPeriod);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n chanmode %d",
- iface->chanmode);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n vht_capable %d",
- iface->vht_capable);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n ht_capable %d",
- iface->ht_capable);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n chan_width %d",
- iface->chan_width);
+ stats = &iface->wow_stats;
len += qdf_scnprintf(buf + len, *size - len,
- "\n vdev_active %d",
- iface->vdev_active);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n vdev_up %d",
- iface->vdev_up);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n aid %d",
- iface->aid);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n rate_flags %d",
- iface->rate_flags);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n nss %d",
- iface->nss);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n tx_power %d",
- iface->tx_power);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n max_tx_power %d",
- iface->max_tx_power);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n nwType %d",
- iface->nwType);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n tx_streams %d",
- iface->tx_streams);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n rx_streams %d",
- iface->rx_streams);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n chain_mask %d",
- iface->chain_mask);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n nss_2g %d",
- iface->nss_2g);
- len += qdf_scnprintf(buf + len, *size - len,
- "\n nss_5g %d",
+ "\n"
+ "vdev_id %d\n"
+ "WoW Stats\n"
+ "\tpno_match %u\n"
+ "\tpno_complete %u\n"
+ "\tgscan %u\n"
+ "\tlow_rssi %u\n"
+ "\trssi_breach %u\n"
+ "\tucast %u\n"
+ "\tbcast %u\n"
+ "\ticmpv4 %u\n"
+ "\ticmpv6 %u\n"
+ "\tipv4_mcast %u\n"
+ "\tipv6_mcast %u\n"
+ "\tipv6_mcast_ra %u\n"
+ "\tipv6_mcast_ns %u\n"
+ "\tipv6_mcast_na %u\n"
+ "\toem_response %u\n"
+ "conn_state %d\n"
+ "dtimPeriod %d\n"
+ "chanmode %d\n"
+ "vht_capable %d\n"
+ "ht_capable %d\n"
+ "chan_width %d\n"
+ "vdev_active %d\n"
+ "vdev_up %d\n"
+ "aid %d\n"
+ "rate_flags %d\n"
+ "nss %d\n"
+ "tx_power %d\n"
+ "max_tx_power %d\n"
+ "nwType %d\n"
+ "tx_streams %d\n"
+ "rx_streams %d\n"
+ "chain_mask %d\n"
+ "nss_2g %d\n"
+ "nss_5g %d",
+ vdev_id,
+ stats->pno_match,
+ stats->pno_complete,
+ stats->gscan,
+ stats->low_rssi,
+ stats->rssi_breach,
+ stats->ucast,
+ stats->bcast,
+ stats->icmpv4,
+ stats->icmpv6,
+ stats->ipv4_mcast,
+ stats->ipv6_mcast,
+ stats->ipv6_mcast_ra,
+ stats->ipv6_mcast_ns,
+ stats->ipv6_mcast_na,
+ stats->oem_response,
+ iface->conn_state,
+ iface->dtimPeriod,
+ iface->chanmode,
+ iface->vht_capable,
+ iface->ht_capable,
+ iface->chan_width,
+ iface->vdev_active,
+ iface->vdev_up,
+ iface->aid,
+ iface->rate_flags,
+ iface->nss,
+ iface->tx_power,
+ iface->max_tx_power,
+ iface->nwType,
+ iface->tx_streams,
+ iface->rx_streams,
+ iface->chain_mask,
+ iface->nss_2g,
iface->nss_5g);
}