Kaynağa Gözat

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
Dustin Brown 8 yıl önce
ebeveyn
işleme
9d797d6b67
4 değiştirilmiş dosya ile 289 ekleme ve 251 silme
  1. 40 0
      core/mac/inc/sir_api.h
  2. 3 15
      core/wma/inc/wma.h
  3. 167 137
      core/wma/src/wma_features.c
  4. 79 99
      core/wma/src/wma_main.c

+ 40 - 0
core/mac/inc/sir_api.h

@@ -6172,6 +6172,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
@@ -6186,8 +6187,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;
@@ -6202,6 +6205,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;
 };
 
 /**

+ 3 - 15
core/wma/inc/wma.h

@@ -1006,6 +1006,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 {
@@ -1084,6 +1085,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)
@@ -1546,21 +1548,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;

+ 167 - 137
core/wma/src/wma_features.c

@@ -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: 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};
 
@@ -2414,16 +2413,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));
@@ -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: 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
@@ -3135,6 +3141,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
@@ -3150,14 +3178,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;
@@ -3167,13 +3194,16 @@ 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);
 	}
 
@@ -3249,11 +3279,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);
@@ -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_csa_offload_handler(handle, wmi_cmd_struct_ptr,
 					wow_buf_pkt_len);
-	break;
+		break;
 
 #ifdef FEATURE_WLAN_LPHB
 	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:
 #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:
@@ -3329,7 +3351,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 */
@@ -3364,7 +3385,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);
@@ -3373,8 +3393,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)
@@ -3398,8 +3416,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
@@ -3420,6 +3436,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,
@@ -8285,56 +8312,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;
 }

+ 79 - 99
core/wma/src/wma_main.c

@@ -1674,119 +1674,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);
 	}