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
This commit is contained in:
Dustin Brown
2017-01-11 16:39:12 -08:00
committed by qcabuildsw
parent 4ead0fe522
commit 9d797d6b67
4 changed files with 289 additions and 251 deletions

View File

@@ -6172,6 +6172,7 @@ struct sir_bpf_get_offload {
/** /**
* struct sir_wake_lock_stats - wake lock stats structure * 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_ucast_wake_up_count: Unicast wakeup count
* @wow_bcast_wake_up_count: Broadcast wakeup count * @wow_bcast_wake_up_count: Broadcast wakeup count
* @wow_ipv4_mcast_wake_up_count: ipv4 multicast wakeup count * @wow_ipv4_mcast_wake_up_count: ipv4 multicast wakeup count
@@ -6186,8 +6187,10 @@ struct sir_bpf_get_offload {
* @wow_gscan_wake_up_count: gscan wakeup count * @wow_gscan_wake_up_count: gscan wakeup count
* @wow_pno_complete_wake_up_count: pno complete wakeup count * @wow_pno_complete_wake_up_count: pno complete wakeup count
* @wow_pno_match_wake_up_count: pno match 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 { struct sir_wake_lock_stats {
uint32_t wow_unspecified_wake_up_count;
uint32_t wow_ucast_wake_up_count; uint32_t wow_ucast_wake_up_count;
uint32_t wow_bcast_wake_up_count; uint32_t wow_bcast_wake_up_count;
uint32_t wow_ipv4_mcast_wake_up_count; uint32_t wow_ipv4_mcast_wake_up_count;
@@ -6202,6 +6205,43 @@ struct sir_wake_lock_stats {
uint32_t wow_gscan_wake_up_count; uint32_t wow_gscan_wake_up_count;
uint32_t wow_pno_complete_wake_up_count; uint32_t wow_pno_complete_wake_up_count;
uint32_t wow_pno_match_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;
}; };
/** /**

View File

@@ -1006,6 +1006,7 @@ typedef struct {
* @wep_default_key_idx: wep default index for group key * @wep_default_key_idx: wep default index for group key
* @arp_offload_req: cached arp offload request * @arp_offload_req: cached arp offload request
* @ns_offload_req: cached ns offload request * @ns_offload_req: cached ns offload request
* @wow_stats: stat counters for WoW related events
* It stores parameters per vdev in wma. * It stores parameters per vdev in wma.
*/ */
struct wma_txrx_node { struct wma_txrx_node {
@@ -1084,6 +1085,7 @@ struct wma_txrx_node {
tSirHostOffloadReq arp_offload_req; tSirHostOffloadReq arp_offload_req;
tSirHostOffloadReq ns_offload_req; tSirHostOffloadReq ns_offload_req;
bool is_vdev_valid; bool is_vdev_valid;
struct sir_vdev_wow_stats wow_stats;
}; };
#if defined(QCA_WIFI_FTM) #if defined(QCA_WIFI_FTM)
@@ -1546,21 +1548,7 @@ typedef struct {
qdf_atomic_t scan_id_counter; qdf_atomic_t scan_id_counter;
qdf_atomic_t num_pending_scans; qdf_atomic_t num_pending_scans;
wma_peer_authorized_fp peer_authorized_cb; wma_peer_authorized_fp peer_authorized_cb;
uint32_t wow_pno_match_wake_up_count; uint32_t wow_unspecified_wake_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;
/* OCB request contexts */ /* OCB request contexts */
struct sir_ocb_config *ocb_config_req; struct sir_ocb_config *ocb_config_req;

View File

@@ -2372,41 +2372,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_wow_stats_display() - display wow wake up stats
* @wma: Pointer to wma handle * @stats: per vdev stats counters
* *
* Return: none * 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_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, stats->ucast,
wma->wow_bcast_wake_up_count, stats->bcast,
wma->wow_ipv4_mcast_wake_up_count, stats->ipv4_mcast,
wma->wow_ipv6_mcast_wake_up_count, stats->ipv6_mcast,
wma->wow_ipv6_mcast_ra_stats, stats->ipv6_mcast_ra,
wma->wow_ipv6_mcast_ns_stats, stats->ipv6_mcast_ns,
wma->wow_ipv6_mcast_na_stats, stats->ipv6_mcast_na,
wma->wow_pno_match_wake_up_count, stats->pno_match,
wma->wow_pno_complete_wake_up_count, stats->pno_complete,
wma->wow_gscan_wake_up_count, stats->gscan,
wma->wow_low_rssi_wake_up_count, stats->low_rssi,
wma->wow_rssi_breach_wake_up_count, stats->rssi_breach,
wma->wow_icmpv4_count, stats->icmpv4,
wma->wow_icmpv6_count, stats->icmpv6,
wma->wow_oem_response_wake_up_count); stats->oem_response);
return;
} }
/** /**
* wma_wow_ipv6_mcast_stats() - ipv6 mcast wake up stats * 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 * @data: Pointer to pattern match data
* *
* Return: none * 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}; static const uint8_t ipv6_ether_type[] = {0x86, 0xDD};
@@ -2414,16 +2413,16 @@ static void wma_wow_ipv6_mcast_stats(tp_wma_handle wma, uint8_t *data)
sizeof(ipv6_ether_type))) { sizeof(ipv6_ether_type))) {
if (WMA_ICMP_V6_HEADER_TYPE == if (WMA_ICMP_V6_HEADER_TYPE ==
*(data + WMA_ICMP_V6_HEADER_OFFSET)) { *(data + WMA_ICMP_V6_HEADER_OFFSET)) {
wma->wow_icmpv6_count++; stats->icmpv6++;
if (WMA_ICMP_V6_RA_TYPE == if (WMA_ICMP_V6_RA_TYPE ==
*(data + WMA_ICMP_V6_TYPE_OFFSET)) *(data + WMA_ICMP_V6_TYPE_OFFSET))
wma->wow_ipv6_mcast_ra_stats++; stats->ipv6_mcast_ra++;
else if (WMA_ICMP_V6_NS_TYPE == else if (WMA_ICMP_V6_NS_TYPE ==
*(data + WMA_ICMP_V6_TYPE_OFFSET)) *(data + WMA_ICMP_V6_TYPE_OFFSET))
wma->wow_ipv6_mcast_ns_stats++; stats->ipv6_mcast_ns++;
else if (WMA_ICMP_V6_NA_TYPE == else if (WMA_ICMP_V6_NA_TYPE ==
*(data + WMA_ICMP_V6_TYPE_OFFSET)) *(data + WMA_ICMP_V6_TYPE_OFFSET))
wma->wow_ipv6_mcast_na_stats++; stats->ipv6_mcast_na++;
else else
WMA_LOGA("ICMP V6 type : 0x%x", WMA_LOGA("ICMP V6 type : 0x%x",
*(data + WMA_ICMP_V6_TYPE_OFFSET)); *(data + WMA_ICMP_V6_TYPE_OFFSET));
@@ -2441,92 +2440,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_inc_wow_stats() - maintain wow pattern match wake up stats
* @wma: Pointer to wma handle * @stats: per vdev stats counters
* @data: Pointer to pattern match data * @data: Pointer to pattern match data
* @len: Pattern match data length * @len: Pattern match data length
* @event: Wake up event * @reason: Wake up reason
* *
* Return: none * Return: none
*/ */
static void wma_wow_wake_up_stats(tp_wma_handle wma, uint8_t *data, static void wma_inc_wow_stats(struct sir_vdev_wow_stats *stats, uint8_t *data,
int32_t len, WOW_WAKE_REASON_TYPE event) int32_t len, WOW_WAKE_REASON_TYPE reason)
{ {
switch (event) { switch (reason) {
case WOW_REASON_BPF_ALLOW: case WOW_REASON_BPF_ALLOW:
case WOW_REASON_PATTERN_MATCH_FOUND: 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) { if (WMA_BCAST_MAC_ADDR == *data) {
wma->wow_bcast_wake_up_count++; stats->bcast++;
if (len >= WMA_IPV4_PROTO_GET_MIN_LEN && if (len >= WMA_IPV4_PROTO_GET_MIN_LEN &&
qdf_nbuf_data_is_icmp_pkt(data)) qdf_nbuf_data_is_icmp_pkt(data))
wma->wow_icmpv4_count++; stats->icmpv4++;
else if ((len > WMA_ICMP_V6_TYPE_OFFSET) && else if ((len > WMA_ICMP_V6_TYPE_OFFSET) &&
qdf_nbuf_data_is_icmpv6_pkt(data)) qdf_nbuf_data_is_icmpv6_pkt(data))
wma->wow_icmpv6_count++; stats->icmpv6++;
} else if (WMA_MCAST_IPV4_MAC_ADDR == *data) { } 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 && if (len >= WMA_IPV4_PROTO_GET_MIN_LEN &&
WMA_ICMP_PROTOCOL == *(data + WMA_IPV4_PROTOCOL)) WMA_ICMP_PROTOCOL == *(data + WMA_IPV4_PROTOCOL))
wma->wow_icmpv4_count++; stats->icmpv4++;
} else if (WMA_MCAST_IPV6_MAC_ADDR == *data) { } 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) if (len > WMA_ICMP_V6_TYPE_OFFSET)
wma_wow_ipv6_mcast_stats(wma, data); wma_wow_ipv6_mcast_stats(stats, data);
else else
WMA_LOGA("ICMP_V6 data len %d", len); WMA_LOGA("ICMP_V6 data len %d", len);
} else { } else {
wma->wow_ucast_wake_up_count++; stats->ucast++;
if (qdf_nbuf_data_is_ipv4_mcast_pkt(data)) 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)) 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 && if (len >= WMA_IPV4_PROTO_GET_MIN_LEN &&
qdf_nbuf_data_is_icmp_pkt(data)) qdf_nbuf_data_is_icmp_pkt(data))
wma->wow_icmpv4_count++; stats->icmpv4++;
else if (len > WMA_ICMP_V6_TYPE_OFFSET && else if (len > WMA_ICMP_V6_TYPE_OFFSET &&
qdf_nbuf_data_is_icmpv6_pkt(data)) qdf_nbuf_data_is_icmpv6_pkt(data))
wma->wow_icmpv6_count++; stats->icmpv6++;
} }
break; break;
case WOW_REASON_RA_MATCH: case WOW_REASON_RA_MATCH:
wma->wow_icmpv6_count++; stats->ipv6_mcast++;
wma->wow_ipv6_mcast_ra_stats++; stats->ipv6_mcast_ra++;
wma->wow_ipv6_mcast_wake_up_count++; stats->icmpv6++;
break; break;
case WOW_REASON_NLOD: case WOW_REASON_NLOD:
wma->wow_pno_match_wake_up_count++; stats->pno_match++;
break; break;
case WOW_REASON_NLO_SCAN_COMPLETE: case WOW_REASON_NLO_SCAN_COMPLETE:
wma->wow_pno_complete_wake_up_count++; stats->pno_complete++;
break; break;
case WOW_REASON_LOW_RSSI: case WOW_REASON_LOW_RSSI:
wma->wow_low_rssi_wake_up_count++; stats->low_rssi++;
break; break;
case WOW_REASON_EXTSCAN: case WOW_REASON_EXTSCAN:
wma->wow_gscan_wake_up_count++; stats->gscan++;
break; break;
case WOW_REASON_RSSI_BREACH_EVENT: case WOW_REASON_RSSI_BREACH_EVENT:
wma->wow_rssi_breach_wake_up_count++; stats->rssi_breach++;
break; break;
case WOW_REASON_OEM_RESPONSE_EVENT: case WOW_REASON_OEM_RESPONSE_EVENT:
wma->wow_oem_response_wake_up_count++; stats->oem_response++;
break; break;
default: default:
WMA_LOGE("Unknown wake up reason"); WMA_LOGI("Stats for WoW reason %s are not tracked",
break; wma_wow_wake_reason_str(reason));
/* don't bother displaying stats that haven't changed */
return;
} }
wma_wow_wake_up_stats_display(wma); wma_wow_stats_display(stats);
return;
} }
#ifdef FEATURE_WLAN_EXTSCAN #ifdef FEATURE_WLAN_EXTSCAN
@@ -3135,6 +3141,28 @@ exit_handler:
wma_beacon_miss_handler(wma, wake_info->vdev_id, 0); 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 * wma_wow_wakeup_host_event() - wakeup host event handler
* @handle: wma handle * @handle: wma handle
@@ -3150,14 +3178,13 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
uint32_t len) uint32_t len)
{ {
tp_wma_handle wma = (tp_wma_handle) handle; tp_wma_handle wma = (tp_wma_handle) handle;
struct wma_txrx_node *wma_vdev;
WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *param_buf; WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *param_buf;
WOW_EVENT_INFO_fixed_param *wake_info; 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; uint32_t wake_lock_duration = 0;
void *wmi_cmd_struct_ptr = NULL; void *wmi_cmd_struct_ptr = NULL;
uint32_t tlv_hdr, tag, wow_buf_pkt_len = 0, event_id = 0; uint32_t tlv_hdr, tag, wow_buf_pkt_len = 0, event_id = 0;
uint8_t *wow_buf_data = NULL;
int tlv_ok_status; int tlv_ok_status;
param_buf = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *) event; param_buf = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *) event;
@@ -3167,13 +3194,16 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
} }
wake_info = param_buf->fixed_param; wake_info = param_buf->fixed_param;
wma_vdev = &wma->interfaces[wake_info->vdev_id];
if ((wake_info->wake_reason != WOW_REASON_UNSPECIFIED) || if ((wake_info->wake_reason != WOW_REASON_UNSPECIFIED) ||
(wake_info->wake_reason == WOW_REASON_UNSPECIFIED && (wake_info->wake_reason == WOW_REASON_UNSPECIFIED &&
!wmi_get_runtime_pm_inprogress(wma->wmi_handle))) { !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), 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_wow_wakeup_host_event(wake_info->wake_reason);
} }
@@ -3249,11 +3279,9 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */ #endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
#ifdef FEATURE_WLAN_SCAN_PNO #ifdef FEATURE_WLAN_SCAN_PNO
case WOW_REASON_NLOD: case WOW_REASON_NLOD:
wma_wow_wake_up_stats(wma, NULL, 0, WOW_REASON_NLOD); if (wma_vdev) {
node = &wma->interfaces[wake_info->vdev_id];
if (node) {
WMA_LOGD("NLO match happened"); 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, cds_host_diag_log_work(&wma->pno_wake_lock,
WMA_PNO_MATCH_WAKE_LOCK_TIMEOUT, WMA_PNO_MATCH_WAKE_LOCK_TIMEOUT,
WIFI_POWER_EVENT_WAKELOCK_PNO); WIFI_POWER_EVENT_WAKELOCK_PNO);
@@ -3276,7 +3304,7 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
WMA_LOGD("Host woken up because of CSA IE"); WMA_LOGD("Host woken up because of CSA IE");
wma_csa_offload_handler(handle, wmi_cmd_struct_ptr, wma_csa_offload_handler(handle, wmi_cmd_struct_ptr,
wow_buf_pkt_len); wow_buf_pkt_len);
break; break;
#ifdef FEATURE_WLAN_LPHB #ifdef FEATURE_WLAN_LPHB
case WOW_REASON_WLAN_HB: case WOW_REASON_WLAN_HB:
@@ -3293,34 +3321,28 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
case WOW_REASON_RA_MATCH: case WOW_REASON_RA_MATCH:
#endif /* FEATURE_WLAN_RA_FILTERING */ #endif /* FEATURE_WLAN_RA_FILTERING */
case WOW_REASON_RECV_MAGIC_PATTERN: case WOW_REASON_RECV_MAGIC_PATTERN:
wma_wow_wake_up_stats_display(wma); if (wma_vdev)
wma_wow_stats_display(&wma_vdev->wow_stats);
WMA_LOGD("Wake up for Rx packet, dump starting from ethernet hdr"); WMA_LOGD("Wake up for Rx packet, dump starting from ethernet hdr");
if (param_buf->wow_packet_buffer) { 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);
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_LOGE("No wow packet buffer present"); 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; break;
case WOW_REASON_LOW_RSSI: case WOW_REASON_LOW_RSSI:
@@ -3329,7 +3351,6 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
* WMI_ROAM_REASON_SUITABLE_AP will be handled by * WMI_ROAM_REASON_SUITABLE_AP will be handled by
* wma_roam_event_callback(). * 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"); WMA_LOGD("Host woken up because of roam event");
if (param_buf->wow_packet_buffer) { if (param_buf->wow_packet_buffer) {
/* Roam event is embedded in wow_packet_buffer */ /* Roam event is embedded in wow_packet_buffer */
@@ -3364,7 +3385,6 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
#ifdef FEATURE_WLAN_EXTSCAN #ifdef FEATURE_WLAN_EXTSCAN
case WOW_REASON_EXTSCAN: case WOW_REASON_EXTSCAN:
WMA_LOGD("Host woken up because of extscan reason"); 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) if (param_buf->wow_packet_buffer)
wma_extscan_wow_event_callback(handle, wma_extscan_wow_event_callback(handle,
wmi_cmd_struct_ptr, wow_buf_pkt_len); wmi_cmd_struct_ptr, wow_buf_pkt_len);
@@ -3373,8 +3393,6 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
break; break;
#endif #endif
case WOW_REASON_RSSI_BREACH_EVENT: 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"); WMA_LOGD("Host woken up because of rssi breach reason");
/* rssi breach event is embedded in wow_packet_buffer */ /* rssi breach event is embedded in wow_packet_buffer */
if (param_buf->wow_packet_buffer) if (param_buf->wow_packet_buffer)
@@ -3398,8 +3416,6 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
} }
break; break;
case WOW_REASON_OEM_RESPONSE_EVENT: 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 * Actual OEM Response event will follow after this
* WOW Wakeup event * WOW Wakeup event
@@ -3420,6 +3436,17 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
break; 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) { if (wake_lock_duration) {
cds_host_diag_log_work(&wma->wow_wake_lock, cds_host_diag_log_work(&wma->wow_wake_lock,
wake_lock_duration, wake_lock_duration,
@@ -8285,56 +8312,59 @@ int wma_p2p_lo_event_handler(void *handle, uint8_t *event_buf,
} }
/** /**
* wma_get_wakelock_stats() - Collects wake lock stats * wma_get_wakelock_stats() - Populates wake lock stats
* @wake_lock_stats: wakelock structure to be filled * @stats: non-null wakelock structure to populate
* *
* This function collects wake lock stats * 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; t_wma_handle *wma;
struct sir_vdev_wow_stats *vstats;
int i;
wma_handle = cds_get_context(QDF_MODULE_ID_WMA); if (!stats) {
WMA_LOGE("%s: invalid stats pointer", __func__);
if (!wake_lock_stats) {
WMA_LOGE("%s: invalid pointer", __func__);
return QDF_STATUS_E_INVAL; return QDF_STATUS_E_INVAL;
} }
if (!wma_handle) { wma = cds_get_context(QDF_MODULE_ID_WMA);
WMA_LOGE("%s: WMA context is invalid!", __func__); if (!wma) {
WMA_LOGE("%s: invalid WMA context", __func__);
return QDF_STATUS_E_INVAL; return QDF_STATUS_E_INVAL;
} }
wake_lock_stats->wow_ucast_wake_up_count = /* ensure counters are zeroed */
wma_handle->wow_ucast_wake_up_count; qdf_mem_zero(stats, sizeof(*stats));
wake_lock_stats->wow_bcast_wake_up_count =
wma_handle->wow_bcast_wake_up_count; /* populate global level stats */
wake_lock_stats->wow_ipv4_mcast_wake_up_count = stats->wow_unspecified_wake_up_count = wma->wow_unspecified_wake_count;
wma_handle->wow_ipv4_mcast_wake_up_count;
wake_lock_stats->wow_ipv6_mcast_wake_up_count = /* populate vdev level stats */
wma_handle->wow_ipv6_mcast_wake_up_count; for (i = 0; i < wma->max_bssid; ++i) {
wake_lock_stats->wow_ipv6_mcast_ra_stats = if (!wma->interfaces[i].handle)
wma_handle->wow_ipv6_mcast_ra_stats; continue;
wake_lock_stats->wow_ipv6_mcast_ns_stats =
wma_handle->wow_ipv6_mcast_ns_stats; vstats = &wma->interfaces[i].wow_stats;
wake_lock_stats->wow_ipv6_mcast_na_stats =
wma_handle->wow_ipv6_mcast_na_stats; stats->wow_ucast_wake_up_count += vstats->ucast;
wake_lock_stats->wow_icmpv4_count = wma_handle->wow_icmpv4_count; stats->wow_bcast_wake_up_count += vstats->bcast;
wake_lock_stats->wow_icmpv6_count = stats->wow_ipv4_mcast_wake_up_count += vstats->ipv4_mcast;
wma_handle->wow_icmpv6_count; stats->wow_ipv6_mcast_wake_up_count += vstats->ipv6_mcast;
wake_lock_stats->wow_rssi_breach_wake_up_count = stats->wow_ipv6_mcast_ra_stats += vstats->ipv6_mcast_ra;
wma_handle->wow_rssi_breach_wake_up_count; stats->wow_ipv6_mcast_ns_stats += vstats->ipv6_mcast_ns;
wake_lock_stats->wow_low_rssi_wake_up_count = stats->wow_ipv6_mcast_na_stats += vstats->ipv6_mcast_na;
wma_handle->wow_low_rssi_wake_up_count; stats->wow_icmpv4_count += vstats->icmpv4;
wake_lock_stats->wow_gscan_wake_up_count = stats->wow_icmpv6_count += vstats->icmpv6;
wma_handle->wow_gscan_wake_up_count; stats->wow_rssi_breach_wake_up_count += vstats->rssi_breach;
wake_lock_stats->wow_pno_complete_wake_up_count = stats->wow_low_rssi_wake_up_count += vstats->low_rssi;
wma_handle->wow_pno_complete_wake_up_count; stats->wow_gscan_wake_up_count += vstats->gscan;
wake_lock_stats->wow_pno_match_wake_up_count = stats->wow_pno_complete_wake_up_count += vstats->pno_complete;
wma_handle->wow_pno_match_wake_up_count; stats->wow_pno_match_wake_up_count += vstats->pno_match;
stats->wow_oem_response_wake_up_count += vstats->oem_response;
}
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }

View File

@@ -1674,119 +1674,99 @@ struct wma_version_info g_wmi_version_info;
*/ */
static void wma_state_info_dump(char **buf_ptr, uint16_t *size) 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; uint16_t len = 0;
char *buf = *buf_ptr; char *buf = *buf_ptr;
struct wma_txrx_node *iface; struct wma_txrx_node *iface;
uint8_t vdev_id; uint8_t vdev_id;
wma_handle = cds_get_context(QDF_MODULE_ID_WMA); wma = cds_get_context(QDF_MODULE_ID_WMA);
if (!wma_handle) { if (!wma) {
WMA_LOGE("%s: WMA context is invald!", __func__); WMA_LOGE("%s: WMA context is invald!", __func__);
return; return;
} }
WMA_LOGI("%s: size of buffer: %d", __func__, *size); WMA_LOGI("%s: size of buffer: %d", __func__, *size);
len += qdf_scnprintf(buf + len, *size - len, for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
"\n wow_pno_match_wake_up_count %d", iface = &wma->interfaces[vdev_id];
wma_handle->wow_pno_match_wake_up_count); if (!iface->handle)
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)
continue; continue;
iface = &wma_handle->interfaces[vdev_id]; stats = &iface->wow_stats;
len += qdf_scnprintf(buf + len, *size - len, len += qdf_scnprintf(buf + len, *size - len,
"\n vdev_id %d", "\n"
vdev_id); "vdev_id %d\n"
len += qdf_scnprintf(buf + len, *size - len, "WoW Stats\n"
"\n conn_state %d", "\tpno_match %u\n"
iface->conn_state); "\tpno_complete %u\n"
len += qdf_scnprintf(buf + len, *size - len, "\tgscan %u\n"
"\n dtimPeriod %d", "\tlow_rssi %u\n"
iface->dtimPeriod); "\trssi_breach %u\n"
len += qdf_scnprintf(buf + len, *size - len, "\tucast %u\n"
"\n chanmode %d", "\tbcast %u\n"
iface->chanmode); "\ticmpv4 %u\n"
len += qdf_scnprintf(buf + len, *size - len, "\ticmpv6 %u\n"
"\n vht_capable %d", "\tipv4_mcast %u\n"
iface->vht_capable); "\tipv6_mcast %u\n"
len += qdf_scnprintf(buf + len, *size - len, "\tipv6_mcast_ra %u\n"
"\n ht_capable %d", "\tipv6_mcast_ns %u\n"
iface->ht_capable); "\tipv6_mcast_na %u\n"
len += qdf_scnprintf(buf + len, *size - len, "\toem_response %u\n"
"\n chan_width %d", "conn_state %d\n"
iface->chan_width); "dtimPeriod %d\n"
len += qdf_scnprintf(buf + len, *size - len, "chanmode %d\n"
"\n vdev_active %d", "vht_capable %d\n"
iface->vdev_active); "ht_capable %d\n"
len += qdf_scnprintf(buf + len, *size - len, "chan_width %d\n"
"\n vdev_up %d", "vdev_active %d\n"
iface->vdev_up); "vdev_up %d\n"
len += qdf_scnprintf(buf + len, *size - len, "aid %d\n"
"\n aid %d", "rate_flags %d\n"
iface->aid); "nss %d\n"
len += qdf_scnprintf(buf + len, *size - len, "tx_power %d\n"
"\n rate_flags %d", "max_tx_power %d\n"
iface->rate_flags); "nwType %d\n"
len += qdf_scnprintf(buf + len, *size - len, "tx_streams %d\n"
"\n nss %d", "rx_streams %d\n"
iface->nss); "chain_mask %d\n"
len += qdf_scnprintf(buf + len, *size - len, "nss_2g %d\n"
"\n tx_power %d", "nss_5g %d",
iface->tx_power); vdev_id,
len += qdf_scnprintf(buf + len, *size - len, stats->pno_match,
"\n max_tx_power %d", stats->pno_complete,
iface->max_tx_power); stats->gscan,
len += qdf_scnprintf(buf + len, *size - len, stats->low_rssi,
"\n nwType %d", stats->rssi_breach,
iface->nwType); stats->ucast,
len += qdf_scnprintf(buf + len, *size - len, stats->bcast,
"\n tx_streams %d", stats->icmpv4,
iface->tx_streams); stats->icmpv6,
len += qdf_scnprintf(buf + len, *size - len, stats->ipv4_mcast,
"\n rx_streams %d", stats->ipv6_mcast,
iface->rx_streams); stats->ipv6_mcast_ra,
len += qdf_scnprintf(buf + len, *size - len, stats->ipv6_mcast_ns,
"\n chain_mask %d", stats->ipv6_mcast_na,
iface->chain_mask); stats->oem_response,
len += qdf_scnprintf(buf + len, *size - len, iface->conn_state,
"\n nss_2g %d", iface->dtimPeriod,
iface->nss_2g); iface->chanmode,
len += qdf_scnprintf(buf + len, *size - len, iface->vht_capable,
"\n nss_5g %d", 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); iface->nss_5g);
} }