1 /*
2  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /**
18  * DOC: WLAN Host Device Driver periodic STA statistics related implementation
19  */
20 
21 #include "wlan_dp_periodic_sta_stats.h"
22 
dp_periodic_sta_stats_display(struct wlan_dp_psoc_context * dp_ctx)23 void dp_periodic_sta_stats_display(struct wlan_dp_psoc_context *dp_ctx)
24 {
25 	struct wlan_dp_intf *dp_intf, next_dp_intf = NULL;
26 	struct dp_stats sta_stats;
27 	struct wlan_dp_psoc_cfg *dp_cfg;
28 	char *dev_name;
29 	bool should_log;
30 
31 	if (!dp_ctx)
32 		return;
33 
34 	dp_for_each_intf_held_safe(dp_ctx, dp_intf, next_dp_intf) {
35 		should_log = false;
36 
37 		if (dp_intf->device_mode != QDF_STA_MODE)
38 			continue;
39 
40 		dp_cfg = dp_ctx->dp_cfg;
41 		qdf_mutex_acquire(&dp_intf->sta_periodic_stats_lock);
42 
43 		if (!dp_intf->is_sta_periodic_stats_enabled) {
44 			qdf_mutex_release(&dp_intf->sta_periodic_stats_lock);
45 			continue;
46 		}
47 
48 		dp_intf->periodic_stats_timer_counter++;
49 		if ((dp_intf->periodic_stats_timer_counter *
50 		    dp_cfg->bus_bw_compute_interval) >=
51 				dp_cfg->periodic_stats_timer_interval) {
52 			should_log = true;
53 
54 			dp_intf->periodic_stats_timer_count--;
55 			if (dp_intf->periodic_stats_timer_count == 0)
56 				dp_intf->is_sta_periodic_stats_enabled = false;
57 			dp_intf->periodic_stats_timer_counter = 0;
58 		}
59 		qdf_mutex_release(&dp_intf->sta_periodic_stats_lock);
60 
61 		if (should_log) {
62 			dev_name = qdf_netdev_get_devname(dp_intf->dev);
63 			sta_stats = dp_intf->dp_stats;
64 			dp_nofl_info("%s: Tx ARP requests: %d", dev_name,
65 				     sta_stats.dp_arp_stats.tx_arp_req_count);
66 			dp_nofl_info("%s: Rx ARP responses: %d", dev_name,
67 				     sta_stats.dp_arp_stats.rx_arp_rsp_count);
68 			dp_nofl_info("%s: Tx DNS requests: %d", dev_name,
69 				     sta_stats.dp_dns_stats.tx_dns_req_count);
70 			dp_nofl_info("%s: Rx DNS responses: %d", dev_name,
71 				     sta_stats.dp_dns_stats.rx_dns_rsp_count);
72 		}
73 	}
74 }
75 
dp_periodic_sta_stats_config(struct dp_config * config,struct wlan_objmgr_psoc * psoc)76 void dp_periodic_sta_stats_config(struct dp_config *config,
77 				  struct wlan_objmgr_psoc *psoc)
78 {
79 	config->periodic_stats_timer_interval =
80 		cfg_get(psoc, CFG_PERIODIC_STATS_TIMER_INTERVAL);
81 	config->periodic_stats_timer_duration =
82 		cfg_get(psoc, CFG_PERIODIC_STATS_TIMER_DURATION);
83 }
84 
dp_periodic_sta_stats_start(struct wlan_objmgr_vdev * vdev)85 void dp_periodic_sta_stats_start(struct wlan_objmgr_vdev *vdev)
86 {
87 	struct wlan_dp_link *dp_link = dp_get_vdev_priv_obj(vdev);
88 	struct wlan_dp_intf *dp_intf;
89 	struct dp_config *dp_cfg;
90 
91 	if (!dp_link) {
92 		dp_nofl_err("Unable to get DP link");
93 		return;
94 	}
95 
96 	dp_intf = dp_link->dp_intf;
97 	dp_cfg = dp_intf->dp_ctx->dp_cfg;
98 
99 	if ((dp_intf->device_mode == QDF_STA_MODE) &&
100 	    (dp_cfg->periodic_stats_timer_interval > 0)) {
101 		qdf_mutex_acquire(&dp_intf->sta_periodic_stats_lock);
102 
103 		/* Stop the periodic ARP and DNS stats timer */
104 		dp_intf->periodic_stats_timer_count = 0;
105 		dp_intf->is_sta_periodic_stats_enabled = false;
106 
107 		qdf_mutex_release(&dp_intf->sta_periodic_stats_lock);
108 	}
109 }
110 
dp_periodic_sta_stats_stop(struct wlan_objmgr_vdev * vdev)111 void dp_periodic_sta_stats_stop(struct wlan_objmgr_vdev *vdev)
112 {
113 	struct wlan_dp_link *dp_link = dp_get_vdev_priv_obj(vdev);
114 	struct wlan_dp_intf *dp_intf;
115 	struct dp_config *dp_cfg;
116 
117 	if (!dp_link) {
118 		dp_nofl_err("Unable to get DP link");
119 		return;
120 	}
121 
122 	dp_intf = dp_link->dp_intf;
123 	dp_cfg = dp_intf->dp_ctx->dp_cfg;
124 
125 	if ((dp_intf->device_mode == QDF_STA_MODE) &&
126 	    (dp_cfg->periodic_stats_timer_interval > 0)) {
127 		qdf_mutex_acquire(&dp_intf->sta_periodic_stats_lock);
128 
129 		dp_intf->periodic_stats_timer_count =
130 			dp_cfg->periodic_stats_timer_duration /
131 			dp_cfg->periodic_stats_timer_interval;
132 		dp_intf->periodic_stats_timer_counter = 0;
133 		if (dp_intf->periodic_stats_timer_count > 0)
134 			dp_intf->is_sta_periodic_stats_enabled = true;
135 
136 		qdf_mutex_release(&dp_intf->sta_periodic_stats_lock);
137 	}
138 }
139 
dp_periodic_sta_stats_init(struct wlan_dp_intf * dp_intf)140 void dp_periodic_sta_stats_init(struct wlan_dp_intf *dp_intf)
141 {
142 	dp_intf->is_sta_periodic_stats_enabled = false;
143 }
144 
dp_periodic_sta_stats_mutex_create(struct wlan_dp_intf * dp_intf)145 void dp_periodic_sta_stats_mutex_create(struct wlan_dp_intf *dp_intf)
146 {
147 	qdf_mutex_create(&dp_intf->sta_periodic_stats_lock);
148 }
149 
dp_periodic_sta_stats_mutex_destroy(struct wlan_dp_intf * dp_intf)150 void dp_periodic_sta_stats_mutex_destroy(struct wlan_dp_intf *dp_intf)
151 {
152 qdf_mutex_destroy(&dp_intf->sta_periodic_stats_lock);
153 }
154