blob: 952784dd23f8d7da03506a04fe6c45cf6462bdb8 [file] [log] [blame]
Amir Patel8f758182019-03-14 15:07:17 +05301/*
Debasis Dasfc04e122019-11-15 14:56:16 +05302 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
Amir Patel8f758182019-03-14 15:07:17 +05303 *
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/**
20 * file: peer rate statitistics application
21 * This file provides framework to display peer rate statistics
22 */
23#include <netinet/in.h>
24#include <arpa/inet.h>
25#include <qcatools_lib.h>
26#include <dp_rate_stats_pub.h>
27
28#ifndef min
29#define min(x, y) ((x) < (y) ? (x) : (y))
30#else
31#error confilicting defs of min
32#endif
33
Amir Patel42c63e42019-03-27 13:08:12 +053034#define PRINT(fmt, ...) \
Amir Patel8f758182019-03-14 15:07:17 +053035 do { \
36 printf(fmt, ##__VA_ARGS__); \
37 printf("\n"); \
38 } while (0)
39
40char interface[IFNAMSIZ];
41
42static void dp_peer_rx_rate_stats_print(uint8_t *peer_mac,
43 uint64_t peer_cookie,
44 void *buffer,
45 uint32_t buffer_len)
46{
47 int i = 0;
48 struct wlan_rx_rate_stats *rx_stats;
Amir Patel936900d2019-05-17 15:40:53 +053049 uint8_t is_lithium;
50 uint8_t chain, max_chain, bw, max_bw;
51 struct wlan_rx_rate_stats *tmp_rx_stats;;
Amir Patel8f758182019-03-14 15:07:17 +053052
Amir Patel936900d2019-05-17 15:40:53 +053053 rx_stats = tmp_rx_stats = (struct wlan_rx_rate_stats *)buffer;
Amir Patel42c63e42019-03-27 13:08:12 +053054 PRINT("\n......................................");
55 PRINT("......................................");
56 PRINT("PEER %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
57 peer_mac[0],
58 peer_mac[1],
59 peer_mac[2],
60 peer_mac[3],
61 peer_mac[4],
62 peer_mac[5]);
Debasis Dasfc04e122019-11-15 14:56:16 +053063 PRINT("\tpeer cookie: %016"PRIx64"\n",
64 (peer_cookie & 0xFFFFFFFF00000000) >>
65 WLANSTATS_PEER_COOKIE_LSB);
Amir Patel936900d2019-05-17 15:40:53 +053066 is_lithium = (peer_cookie & WLANSTATS_COOKIE_PLATFORM_OFFSET)
67 >> WLANSTATS_PEER_COOKIE_LSB;
68 if (is_lithium) {
69 max_chain = 8;
70 max_bw = 8;
71 } else {
72 max_chain = 4;
73 max_bw = 4;
74 }
Amir Patel42c63e42019-03-27 13:08:12 +053075 PRINT("\n..............................................");
76 PRINT("................................");
77 PRINT("................................................");
78 PRINT(".................................\n");
79 PRINT("\tRx statistics:");
Amir Patel936900d2019-05-17 15:40:53 +053080 PRINT(" %10s | %10s | %10s | %10s | %10s | %10s|",
Amir Patel42c63e42019-03-27 13:08:12 +053081 "rate",
82 "rix",
83 "bytes",
84 "msdus",
85 "mpdus",
86 "ppdus");
Amir Patel936900d2019-05-17 15:40:53 +053087 PRINT(" %10s | %10s | %10s |",
Amir Patel42c63e42019-03-27 13:08:12 +053088 "retries",
Amir Patel936900d2019-05-17 15:40:53 +053089 "sgi",
90 "rssi\n");
Amir Patel8f758182019-03-14 15:07:17 +053091
Pranita Solanke67a1dde2019-03-16 18:10:32 +053092 for (i = 0; i < WLANSTATS_CACHE_SIZE; i++) {
Amir Patel42c63e42019-03-27 13:08:12 +053093 if (rx_stats->rix != INVALID_CACHE_IDX) {
Amir Patel936900d2019-05-17 15:40:53 +053094 PRINT(" %10u | %10u | %10u | %10u | %10u | %10u |",
Amir Patel42c63e42019-03-27 13:08:12 +053095 rx_stats->rate,
Amir Patel737f4262019-08-14 09:54:38 +053096 GET_DP_PEER_STATS_RIX(rx_stats->rix),
Amir Patel42c63e42019-03-27 13:08:12 +053097 rx_stats->num_bytes,
98 rx_stats->num_msdus,
Amir Patel936900d2019-05-17 15:40:53 +053099 rx_stats->num_mpdus,
100 rx_stats->num_ppdus);
Aakanksha Dodadeba7142019-07-01 14:45:10 +0530101 PRINT(" %10u | %10u | %10lu |\n",
Amir Patel42c63e42019-03-27 13:08:12 +0530102 rx_stats->num_retries,
103 rx_stats->num_sgi,
Amir Patel936900d2019-05-17 15:40:53 +0530104 rx_stats->avg_rssi);
Amir Patel42c63e42019-03-27 13:08:12 +0530105 }
Amir Patel8f758182019-03-14 15:07:17 +0530106 rx_stats = rx_stats + 1;
107 }
Amir Patel936900d2019-05-17 15:40:53 +0530108 if (is_lithium) {
109 PRINT("\n %10s | %10s | %10s | %10s | %10s |",
110 "rate",
111 "rssi 1 p20",
112 "rssi 1 e20",
113 "rssi 1 e40 low20",
114 "rssi 1 e40 high20");
115 PRINT("\n | %10s | %10s | %10s | %10s |",
116 "rssi 1 ext80 low20",
117 "rssi 1 ext80 low_high20",
118 "rssi 1 ext80 high_low20",
119 "rssi 1 ext80 high20");
120 PRINT("\n | %10s | %10s | %10s | %10s |",
121 "rssi 2 p20",
122 "rssi 2 e20",
123 "rssi 2 e40 low20",
124 "rssi 2 e40 high20");
125 PRINT("\n | %10s | %10s | %10s | %10s |",
126 "rssi 2 ext80 low20",
127 "rssi 2 ext80 low_high20",
128 "rssi 2 ext80 high_low20",
129 "rssi 2 ext80 high20");
130 PRINT("\n | %10s | %10s | %10s | %10s |",
131 "rssi 3 p20",
132 "rssi 3 e20",
133 "rssi 3 e40 low20",
134 "rssi 3 e40 high20");
135 PRINT("\n | %10s | %10s | %10s | %10s |",
136 "rssi 3 ext80 low20",
137 "rssi 3 ext80 low_high20",
138 "rssi 3 ext80 high_low20",
139 "rssi 3 ext80 high20");
140 PRINT("\n | %10s | %10s | %10s | %10s |",
141 "rssi 4 p20",
142 "rssi 4 e20",
143 "rssi 4 e40 low20",
144 "rssi 4 e40 high20");
145 PRINT("\n | %10s | %10s | %10s | %10s |",
146 "rssi 4 ext80 low20",
147 "rssi 4 ext80 low_high20",
148 "rssi 4 ext80 high_low20",
149 "rssi 4 ext80 high20");
150 PRINT("\n | %10s | %10s | %10s | %10s |",
151 "rssi 5 p20",
152 "rssi 5 e20",
153 "rssi 5 e40 low20",
154 "rssi 5 e40 high20");
155 PRINT("\n | %10s | %10s | %10s | %10s |",
156 "rssi 5 ext80 low20",
157 "rssi 5 ext80 low_high20",
158 "rssi 5 ext80 high_low20",
159 "rssi 5 ext80 high20");
160 PRINT("\n | %10s | %10s | %10s | %10s |",
161 "rssi 6 p20",
162 "rssi 6 e20",
163 "rssi 6 e40 low20",
164 "rssi 6 e40 high20");
165 PRINT("\n | %10s | %10s | %10s | %10s |",
166 "rssi 6 ext80 low20",
167 "rssi 6 ext80 low_high20",
168 "rssi 6 ext80 high_low20",
169 "rssi 6 ext80 high20");
170 PRINT("\n | %10s | %10s | %10s | %10s |",
171 "rssi 7 p20",
172 "rssi 7 e20",
173 "rssi 7 e40 low20",
174 "rssi 7 e40 high20");
175 PRINT("\n | %10s | %10s | %10s | %10s |",
176 "rssi 7 ext80 low20",
177 "rssi 7 ext80 low_high20",
178 "rssi 7 ext80 high_low20",
179 "rssi 7 ext80 high20");
180 PRINT("\n | %10s | %10s | %10s | %10s |",
181 "rssi 8 p20",
182 "rssi 8 e20",
183 "rssi 8 e40 low20",
184 "rssi 8 e40 high20");
185 PRINT("\n | %10s | %10s | %10s | %10s |\n\n\n",
186 "rssi 8 ext80 low20",
187 "rssi 8 ext80 low_high20",
188 "rssi 8 ext80 high_low20",
189 "rssi 8 ext80 high20");
190 } else {
191 PRINT("\n %10s | %10s | %10s | %10s | %10s |",
192 "rate",
193 "rssi 1 p20",
194 "rssi 1 e20",
195 "rssi 1 e40",
196 "rssi 1 e80");
197 PRINT(" | %10s | %10s | %10s | %10s |",
198 "rssi 2 p20",
199 "rssi 2 e20",
200 "rssi 2 e40",
201 "rssi 2 e80");
202 PRINT(" | %10s | %10s | %10s | %10s |",
203 "rssi 3 p20",
204 "rssi 3 e20",
205 "rssi 3 e40",
206 "rssi 3 e80");
207 PRINT(" | %10s | %10s | %10s | %10s |\n\n\n",
208 "rssi 4 p20",
209 "rssi 4 e20",
210 "rssi 4 e40",
211 "rssi 4 e80");
212 }
213 for (i = 0; i < WLANSTATS_CACHE_SIZE; i++) {
214 if (tmp_rx_stats->rix != INVALID_CACHE_IDX) {
215 printf(" %10u |", tmp_rx_stats->rate);
216 for (chain = 0; chain < max_chain; chain++) {
217 for (bw = 0; bw < max_bw; bw++) {
velagapudi sureshead022e2019-07-08 14:46:38 +0530218 printf(" %10lu |",
Amir Patel936900d2019-05-17 15:40:53 +0530219 tmp_rx_stats->avg_rssi_ant[chain][bw]);
220 }
221 printf(" \n\t ");
222 }
Aakanksha Dodadeba7142019-07-01 14:45:10 +0530223 PRINT(" ");
Amir Patel936900d2019-05-17 15:40:53 +0530224 }
225 tmp_rx_stats = tmp_rx_stats + 1;
226 }
Amir Patel8f758182019-03-14 15:07:17 +0530227}
228
229static void
230dp_peer_tx_sojourn_stats_print(uint8_t *peer_mac,
231 uint64_t peer_cookie,
232 struct wlan_tx_sojourn_stats *sojourn_stats)
233{
234 uint8_t tid;
235
Amir Patel42c63e42019-03-27 13:08:12 +0530236 PRINT("\n..........................................");
237 PRINT("....................................");
238 PRINT("....................................");
239 PRINT(".........................................\n");
240 PRINT("PEER %02hhx:%02hhx:%02hhx:%02hhx%02hhx:%02hhx\n",
241 peer_mac[0],
242 peer_mac[1],
243 peer_mac[2],
244 peer_mac[3],
245 peer_mac[4],
246 peer_mac[5]);
Debasis Dasfc04e122019-11-15 14:56:16 +0530247 PRINT("\tPEER Cookie: %016"PRIx64"\n", peer_cookie);
Amir Patel42c63e42019-03-27 13:08:12 +0530248 PRINT("\n...........................................");
249 PRINT("...................................");
250 PRINT("..................................");
251 PRINT("............................................");
252 PRINT("\n\tSojourn statistics:\n");
253 PRINT("\t\t%10s %10s %20s %20s\n", "tid", "ave", "sum", "num");
Amir Patel8f758182019-03-14 15:07:17 +0530254
255 for (tid = 0; tid < WLAN_DATA_TID_MAX; tid++) {
256 /* change sum_sojourn_msdu data type to u64 */
Amir Patel42c63e42019-03-27 13:08:12 +0530257 PRINT("\t\t%10d %10lu %20u %20u\n",
258 tid,
259 sojourn_stats->avg_sojourn_msdu[tid],
260 sojourn_stats->sum_sojourn_msdu[tid],
261 sojourn_stats->num_msdus[tid]);
Amir Patel8f758182019-03-14 15:07:17 +0530262 }
Debasis Das107c3582020-03-08 21:11:39 +0530263#ifdef __LP64__
264 PRINT("sizeof(avg) : %"PRIu64,
265#else
266 PRINT("sizeof(avg) : %"PRIu32,
267#endif
Debasis Dasfc04e122019-11-15 14:56:16 +0530268 sizeof(sojourn_stats->avg_sojourn_msdu[tid]));
Amir Patel42c63e42019-03-27 13:08:12 +0530269 PRINT("\n...........................................");
270 PRINT("...................................");
271 PRINT("...................................");
272 PRINT("...........................................\n");
Amir Patel8f758182019-03-14 15:07:17 +0530273}
274
275static void dp_peer_tx_rate_stats_print(uint8_t *peer_mac,
276 uint64_t peer_cookie,
277 void *buffer,
278 uint32_t buffer_len)
279{
280 int i = 0;
281 struct wlan_tx_rate_stats *tx_stats;
282 struct wlan_tx_sojourn_stats *sojourn_stats;
283
Pranita Solanke67a1dde2019-03-16 18:10:32 +0530284 if (buffer_len < (WLANSTATS_CACHE_SIZE *
Amir Patel8f758182019-03-14 15:07:17 +0530285 sizeof(struct wlan_tx_rate_stats))
286 + sizeof(struct wlan_tx_sojourn_stats)) {
Amir Patel42c63e42019-03-27 13:08:12 +0530287 PRINT("invalid buffer len, return");
Amir Patel8f758182019-03-14 15:07:17 +0530288 return;
289 }
290 tx_stats = (struct wlan_tx_rate_stats *)buffer;
Amir Patel42c63e42019-03-27 13:08:12 +0530291 PRINT("\n...........................................");
292 PRINT("...................................");
293 PRINT("...................................");
294 PRINT("...........................................\n");
295 PRINT("PEER %02hhx:%02hhx:%02hhx:%02hhx%02hhx:%02hhx\n\n",
296 peer_mac[0],
297 peer_mac[1],
298 peer_mac[2],
299 peer_mac[3],
300 peer_mac[4],
301 peer_mac[5]);
Debasis Dasfc04e122019-11-15 14:56:16 +0530302 PRINT("\tPEER Cookie: %016"PRIx64, peer_cookie);
Amir Patel42c63e42019-03-27 13:08:12 +0530303 PRINT("\n...........................................");
304 PRINT("...................................");
305 PRINT("...................................");
306 PRINT("...........................................\n");
307 PRINT("\tTx statistics:\n");
308 PRINT("\t\t%10s | %10s | %10s | %10s | %10s",
309 "rate",
310 "rix",
311 "attempts",
312 "success",
313 "ppdus");
Amir Patela74d4df2019-08-14 14:45:35 +0530314 PRINT(" %10s | %10s | %10s |",
315 "msdus",
316 "bytes",
317 "retries\n");
Amir Patel42c63e42019-03-27 13:08:12 +0530318
Pranita Solanke67a1dde2019-03-16 18:10:32 +0530319 for (i = 0; i < WLANSTATS_CACHE_SIZE; i++) {
Amir Patel42c63e42019-03-27 13:08:12 +0530320 if (tx_stats->rix != INVALID_CACHE_IDX) {
321 PRINT("\t\t%10u | %10u | %10u | %10u | %10u\n",
322 tx_stats->rate,
Amir Patel737f4262019-08-14 09:54:38 +0530323 GET_DP_PEER_STATS_RIX(tx_stats->rix),
Amir Patel42c63e42019-03-27 13:08:12 +0530324 tx_stats->mpdu_attempts,
325 tx_stats->mpdu_success,
326 tx_stats->num_ppdus);
Debasis Dasfc04e122019-11-15 14:56:16 +0530327 PRINT(" %10u | %10u | %10u |\n",
Amir Patela74d4df2019-08-14 14:45:35 +0530328 tx_stats->num_msdus,
329 tx_stats->num_bytes,
330 tx_stats->num_retries);
Amir Patel42c63e42019-03-27 13:08:12 +0530331 }
Amir Patel8f758182019-03-14 15:07:17 +0530332 tx_stats = tx_stats + 1;
333 }
334
Amir Patel42c63e42019-03-27 13:08:12 +0530335 sojourn_stats = (struct wlan_tx_sojourn_stats *)((uint8_t *)buffer
336 + (WLANSTATS_CACHE_SIZE *
337 sizeof(struct wlan_tx_rate_stats)));
Amir Patel8f758182019-03-14 15:07:17 +0530338 dp_peer_tx_sojourn_stats_print(peer_mac, peer_cookie, sojourn_stats);
339
Viyom Mittal9184b992019-03-19 16:00:08 +0530340 return;
Amir Patel8f758182019-03-14 15:07:17 +0530341}
342
phadimane24d8322020-08-01 18:50:58 +0530343static void dp_peer_tx_link_stats_print(uint8_t *peer_mac,
344 uint64_t peer_cookie,
345 void *buffer,
346 uint32_t buffer_len)
347{
348 struct wlan_tx_link_stats *tx_stats;
349 uint8_t is_lithium;
350
351 is_lithium = (peer_cookie & WLANSTATS_COOKIE_PLATFORM_OFFSET)
352 >> WLANSTATS_PEER_COOKIE_LSB;
353
354 if (!is_lithium) {
355 PRINT("Not supported in non-lithium platforms\n");
356 return;
357 }
358
359 if (buffer_len < sizeof(struct wlan_tx_link_stats)) {
360 PRINT("invalid buffer len, return");
361 return;
362 }
363
364 tx_stats = (struct wlan_tx_link_stats *)buffer;
365
366 PRINT("\n\n");
367 PRINT("========= PEER TX LINK QUALITY METRICS =========\n");
368 PRINT("PEER %02hhx:%02hhx:%02hhx:%02hhx%02hhx:%02hhx",
369 peer_mac[0],
370 peer_mac[1],
371 peer_mac[2],
372 peer_mac[3],
373 peer_mac[4],
374 peer_mac[5]);
375 PRINT("num_ppdus: %u", tx_stats->num_ppdus);
376 PRINT("bytes: %"PRIu64, tx_stats->bytes);
377 PRINT("phy_rate_actual_su: %u kbps", tx_stats->phy_rate_actual_su);
378 PRINT("phy_rate_actual_mu: %u kbps", tx_stats->phy_rate_actual_mu);
379 PRINT("ofdma_usage: %u", tx_stats->ofdma_usage);
380 PRINT("mu_mimo_usage: %u", tx_stats->mu_mimo_usage);
381 PRINT("bw_usage_avg: %u MHz", tx_stats->bw.usage_avg);
382 PRINT("bw_usage_packets: 20MHz: %u 40MHz: %u 80MHz: %u 160MHz: %u",
383 tx_stats->bw.usage_counter[0], tx_stats->bw.usage_counter[1],
384 tx_stats->bw.usage_counter[2], tx_stats->bw.usage_counter[3]);
385 PRINT("bw_usage_max:: %u%%", tx_stats->bw.usage_max);
386 PRINT("ack_rssi: %lu", tx_stats->ack_rssi);
387 PRINT("pkt_error_rate: %u%%", tx_stats->pkt_error_rate);
388}
389
390static void dp_peer_rx_link_stats_print(uint8_t *peer_mac,
391 uint64_t peer_cookie,
392 void *buffer,
393 uint32_t buffer_len)
394{
395 struct wlan_rx_link_stats *rx_stats;
396 uint8_t is_lithium;
397
398 is_lithium = (peer_cookie & WLANSTATS_COOKIE_PLATFORM_OFFSET)
399 >> WLANSTATS_PEER_COOKIE_LSB;
400
401 if (!is_lithium) {
402 PRINT("Not supported in non-lithium platforms\n");
403 return;
404 }
405
406 if (buffer_len < sizeof(struct wlan_rx_link_stats)) {
407 PRINT("invalid buffer len, return");
408 return;
409 }
410
411 rx_stats = (struct wlan_rx_link_stats *)buffer;
412
413 PRINT("\n\n");
414 PRINT("========= PEER RX LINK QUALITY METRICS =========\n");
415 PRINT("PEER %02hhx:%02hhx:%02hhx:%02hhx%02hhx:%02hhx",
416 peer_mac[0],
417 peer_mac[1],
418 peer_mac[2],
419 peer_mac[3],
420 peer_mac[4],
421 peer_mac[5]);
422 PRINT("num_ppdus: %u", rx_stats->num_ppdus);
423 PRINT("bytes: %"PRIu64, rx_stats->bytes);
424 PRINT("phy_rate_actual_su: %u kbps", rx_stats->phy_rate_actual_su);
425 PRINT("phy_rate_actual_mu: %u kbps", rx_stats->phy_rate_actual_mu);
426 PRINT("ofdma_usage: %u", rx_stats->ofdma_usage);
427 PRINT("mu_mimo_usage: %u", rx_stats->mu_mimo_usage);
428 PRINT("bw_usage_avg: %u MHz", rx_stats->bw.usage_avg);
429 PRINT("bw_usage_packets: 20MHz: %u 40MHz: %u 80MHz: %u 160MHz: %u",
430 rx_stats->bw.usage_counter[0], rx_stats->bw.usage_counter[1],
431 rx_stats->bw.usage_counter[2], rx_stats->bw.usage_counter[3]);
432 PRINT("bw_usage_max: %u%%", rx_stats->bw.usage_max);
433 PRINT("su_rssi: %lu", rx_stats->su_rssi);
434 PRINT("pkt_error_rate: %u%%", rx_stats->pkt_error_rate);
435}
436
Viyom Mittal9184b992019-03-19 16:00:08 +0530437static void dp_peer_stats_handler(uint32_t cache_type,
Amir Patel8f758182019-03-14 15:07:17 +0530438 uint8_t *peer_mac,
439 uint64_t peer_cookie,
440 void *buffer,
441 uint32_t buffer_len)
442{
443 switch (cache_type) {
444 case DP_PEER_RX_RATE_STATS:
445 dp_peer_rx_rate_stats_print(peer_mac, peer_cookie,
446 buffer, buffer_len);
447 break;
448 case DP_PEER_TX_RATE_STATS:
449 dp_peer_tx_rate_stats_print(peer_mac, peer_cookie,
450 buffer, buffer_len);
451 break;
phadimane24d8322020-08-01 18:50:58 +0530452 case DP_PEER_TX_LINK_STATS:
453 dp_peer_tx_link_stats_print(peer_mac, peer_cookie,
454 buffer, buffer_len);
455 break;
456 case DP_PEER_RX_LINK_STATS:
457 dp_peer_rx_link_stats_print(peer_mac, peer_cookie,
458 buffer, buffer_len);
459 break;
Amir Patel8f758182019-03-14 15:07:17 +0530460 }
461}
462
463static void
464dp_peer_stats_event_callback(char *ifname,
465 uint32_t cmdid,
466 uint8_t *data,
467 size_t len)
468{
Amir Patel8f758182019-03-14 15:07:17 +0530469 struct nlattr *tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_MAX + 1];
470 struct nlattr *tb;
471 void *buffer = NULL;
472 uint32_t buffer_len = 0;
473 uint8_t *peer_mac;
474 uint32_t cache_type;
475 uint64_t peer_cookie;
476
477 if (cmdid != QCA_NL80211_VENDOR_SUBCMD_PEER_STATS_CACHE_FLUSH) {
478 /* ignore anyother events*/
479 return;
480 }
481
482 if (strncmp(interface, ifname, sizeof(interface)) != 0) {
483 /* ignore events for other interfaces*/
484 return;
485 }
486
487 if (nla_parse(tb_array, QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_MAX,
488 (struct nlattr *)data, len, NULL)) {
Amir Patel42c63e42019-03-27 13:08:12 +0530489 PRINT("Invalid event\n");
Amir Patel8f758182019-03-14 15:07:17 +0530490 return;
491 }
492
493 tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE];
494 if (!tb) {
Amir Patel42c63e42019-03-27 13:08:12 +0530495 PRINT("Cache type in NULL, return");
Amir Patel8f758182019-03-14 15:07:17 +0530496 return;
497 }
498 cache_type = nla_get_u32(tb);
499
500 tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_MAC];
501 if (!tb) {
Amir Patel42c63e42019-03-27 13:08:12 +0530502 PRINT("Peer mac addr is null, return");
Amir Patel8f758182019-03-14 15:07:17 +0530503 return;
504 }
505 peer_mac = (uint8_t *)nla_data(tb);
506
507 tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_DATA];
508 if (tb) {
509 buffer = (void *)nla_data(tb);
510 buffer_len = nla_len(tb);
511 }
512
513 tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_COOKIE];
514 if (!tb) {
Amir Patel42c63e42019-03-27 13:08:12 +0530515 PRINT("peer cookie attribute is null, return");
Amir Patel8f758182019-03-14 15:07:17 +0530516 return;
517 }
518 peer_cookie = nla_get_u64(tb);
519 if (!buffer) {
Amir Patel42c63e42019-03-27 13:08:12 +0530520 PRINT(" stats buffer is null, return");
Amir Patel8f758182019-03-14 15:07:17 +0530521 return;
522 }
523
524 dp_peer_stats_handler(cache_type, peer_mac, peer_cookie,
525 buffer, buffer_len);
526}
527
528int main(int argc, char *argv[])
529{
Amir Patel8f758182019-03-14 15:07:17 +0530530 int err = 0;
531 wifi_cfg80211_context cfg80211_ctxt;
532 char *ifname;
533 int num_msecs = 0;
Amir Patel8f758182019-03-14 15:07:17 +0530534 int status = 0;
535
536 if (argc < 2) {
537 fprintf(stderr, "Invalid commands args\n");
538 return -EIO;
539 }
540
541 /* Reset the cfg80211 context to 0 if the application does not pass
542 * custom private event and command sockets. In this case, the default
543 * port is used for netlink communication.
544 */
545 memset(&cfg80211_ctxt, 0, sizeof(wifi_cfg80211_context));
546
547 ifname = argv[1];
548 memcpy(interface, ifname, sizeof(interface));
549 cfg80211_ctxt.event_callback = dp_peer_stats_event_callback;
550
551 err = wifi_init_nl80211(&cfg80211_ctxt);
552 if (err) {
553 fprintf(stderr, "unable to create NL socket\n");
554 return -EIO;
555 }
556
557 /* Starting event thread to listen for responses*/
558 if (wifi_nl80211_start_event_thread(&cfg80211_ctxt)) {
559 fprintf(stderr, "Unable to setup nl80211 event thread\n");
560 status = -EIO;
561 goto cleanup;
562 }
563
564 while (true) {
565 /*sleep for 1 ms*/
566 usleep(1000);
567 num_msecs++;
568 }
569
570 wifi_destroy_nl80211(&cfg80211_ctxt);
571 return 0;
572
573cleanup:
574 wifi_destroy_nl80211(&cfg80211_ctxt);
575 return status;
576}