xref: /wlan-dirver/qca-wifi-host-cmn/dp/cmn_dp_api/dp_cal_client_api.c (revision 503663c6daafffe652fa360bde17243568cd6d2a)
1 /*
2  * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "dp_cal_client_api.h"
20 #include "qdf_module.h"
21 
22 /* dp_cal_client_attach - function to attach cal client timer
23  * @cal_client_ctx: cal client timer context
24  * @pdev: pdev handle
25  * @osdev: device pointer
26  * @dp_iterate_peer_list : function pointer to iterate and update peer stats
27  *
28  * return: void
29  */
30 void dp_cal_client_attach(struct cdp_cal_client **cal_client_ctx,
31 			  struct cdp_pdev *pdev,
32 			  qdf_device_t osdev,
33 			  void (*dp_iterate_peer_list)(struct cdp_pdev *))
34 {
35 	struct cal_client *cal_cl;
36 
37 	*cal_client_ctx = qdf_mem_malloc(sizeof(struct cal_client));
38 
39 	if (!(*cal_client_ctx))
40 		return;
41 
42 	cal_cl = (struct cal_client *)(*cal_client_ctx);
43 	cal_cl->iterate_update_peer_list = dp_iterate_peer_list;
44 	cal_cl->pdev_hdl = pdev;
45 
46 	qdf_timer_init(osdev, &cal_cl->cal_client_timer,
47 		       dp_cal_client_stats_timer_fn, *cal_client_ctx,
48 		       QDF_TIMER_TYPE_WAKE_APPS);
49 }
50 
51 qdf_export_symbol(dp_cal_client_attach);
52 
53 /* dp_cal_client_detach - detach cal client timer
54  * @cal_client_ctx: cal client timer context
55  *
56  * return: void
57  */
58 void dp_cal_client_detach(struct cdp_cal_client **cal_client_ctx)
59 {
60 	struct cal_client *cal_cl;
61 
62 	if (*cal_client_ctx) {
63 		cal_cl = (struct cal_client *)*cal_client_ctx;
64 
65 		qdf_timer_stop(&cal_cl->cal_client_timer);
66 		qdf_timer_free(&cal_cl->cal_client_timer);
67 		qdf_mem_free(cal_cl);
68 		*cal_client_ctx = NULL;
69 	}
70 }
71 
72 qdf_export_symbol(dp_cal_client_detach);
73 
74 /* dp_cal_client_timer_start- api to start cal client timer
75  * @ctx: cal client timer ctx
76  *
77  * return: void
78  */
79 void dp_cal_client_timer_start(void *ctx)
80 {
81 	struct cal_client *cal_cl;
82 
83 	if (ctx) {
84 		cal_cl  = (struct cal_client *)ctx;
85 		qdf_timer_start(&cal_cl->cal_client_timer, DP_CAL_CLIENT_TIME);
86 	}
87 }
88 
89 qdf_export_symbol(dp_cal_client_timer_start);
90 
91 /* dp_cal_client_timer_stop- api to stop cal client timer
92  * @ctx: cal client timer ctx
93  *
94  * return: void
95  */
96 void dp_cal_client_timer_stop(void *ctx)
97 {
98 	struct cal_client *cal_cl;
99 
100 	if (ctx) {
101 		cal_cl = (struct cal_client *)ctx;
102 		qdf_timer_sync_cancel(&cal_cl->cal_client_timer);
103 		qdf_timer_stop(&cal_cl->cal_client_timer);
104 	}
105 }
106 
107 qdf_export_symbol(dp_cal_client_timer_stop);
108 
109 /* dp_cal_client_stats_timer_fn- function called on timer interval
110  * @ctx: cal client timer ctx
111  *
112  * return: void
113  */
114 void dp_cal_client_stats_timer_fn(void *ctx)
115 {
116 	struct cal_client *cal_cl = (struct cal_client *)ctx;
117 
118 	if (!cal_cl)
119 		return;
120 
121 	cal_cl->iterate_update_peer_list(cal_cl->pdev_hdl);
122 	qdf_timer_mod(&cal_cl->cal_client_timer, DP_CAL_CLIENT_TIME);
123 }
124 
125 qdf_export_symbol(dp_cal_client_stats_timer_fn);
126 
127 /*dp_cal_client_update_peer_stats - update peer stats in peer
128  * @peer_stats: cdp peer stats pointer
129  *
130  * return: void
131  */
132 void dp_cal_client_update_peer_stats(struct cdp_peer_stats *peer_stats)
133 {
134 	uint32_t temp_rx_bytes = peer_stats->rx.to_stack.bytes;
135 	uint32_t temp_rx_data = peer_stats->rx.to_stack.num;
136 	uint32_t temp_tx_bytes = peer_stats->tx.tx_success.bytes;
137 	uint32_t temp_tx_data = peer_stats->tx.tx_success.num;
138 	uint32_t temp_tx_ucast_pkts = peer_stats->tx.ucast.num;
139 
140 	peer_stats->rx.rx_byte_rate = temp_rx_bytes -
141 					peer_stats->rx.rx_bytes_success_last;
142 	peer_stats->rx.rx_data_rate  = temp_rx_data -
143 					peer_stats->rx.rx_data_success_last;
144 	peer_stats->tx.tx_byte_rate = temp_tx_bytes -
145 					peer_stats->tx.tx_bytes_success_last;
146 	peer_stats->tx.tx_data_rate  = temp_tx_data -
147 					peer_stats->tx.tx_data_success_last;
148 	peer_stats->tx.tx_data_ucast_rate = temp_tx_ucast_pkts -
149 					peer_stats->tx.tx_data_ucast_last;
150 
151 	/* Check tx and rx packets in last one second, and increment
152 	 * inactive time for peer
153 	 */
154 	if (peer_stats->tx.tx_data_rate || peer_stats->rx.rx_data_rate)
155 		peer_stats->tx.inactive_time = 0;
156 	else
157 		peer_stats->tx.inactive_time++;
158 
159 	peer_stats->rx.rx_bytes_success_last = temp_rx_bytes;
160 	peer_stats->rx.rx_data_success_last = temp_rx_data;
161 	peer_stats->tx.tx_bytes_success_last = temp_tx_bytes;
162 	peer_stats->tx.tx_data_success_last = temp_tx_data;
163 	peer_stats->tx.tx_data_ucast_last = temp_tx_ucast_pkts;
164 
165 	if (peer_stats->tx.tx_data_ucast_rate) {
166 		if (peer_stats->tx.tx_data_ucast_rate >
167 				peer_stats->tx.tx_data_rate)
168 			peer_stats->tx.last_per =
169 				((peer_stats->tx.tx_data_ucast_rate -
170 					peer_stats->tx.tx_data_rate) * 100) /
171 				peer_stats->tx.tx_data_ucast_rate;
172 		else
173 			peer_stats->tx.last_per = 0;
174 	}
175 
176 }
177 
178 qdf_export_symbol(dp_cal_client_update_peer_stats);
179 
180