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