blob: b219a1413746c3e9e07bd9953acfe34d266ca297 [file] [log] [blame]
Radhakrishna Jiguru1c9b2252013-08-27 23:57:48 +05301/*
2 **************************************************************************
Zac Livingston866b0e22013-10-23 18:14:17 -06003 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
Radhakrishna Jiguru1c9b2252013-08-27 23:57:48 +05304 * 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 copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 **************************************************************************
15 */
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053016
17/*
18 * nss_stats.c
19 * NSS stats APIs
20 *
21 */
22
23#include "nss_core.h"
24
25/*
26 * Maximum string length:
27 * This should be equal to maximum string size of any stats
28 * inclusive of stats value
29 */
30#define NSS_STATS_MAX_STR_LENGTH 96
31
32/*
33 * Global variables/extern declarations
34 */
35extern struct nss_top_instance nss_top_main;
36
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053037uint64_t stats_shadow_pppoe_except[NSS_PPPOE_NUM_SESSION_PER_INTERFACE][NSS_EXCEPTION_EVENT_PPPOE_MAX];
38
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053039/*
40 * Statistics structures
41 */
42
43/*
44 * nss_stats_str_ipv4
45 * IPv4 stats strings
46 */
47static int8_t *nss_stats_str_ipv4[NSS_STATS_IPV4_MAX] = {
48 "rx_pkts",
49 "rx_bytes",
50 "tx_pkts",
51 "tx_bytes",
52 "create_requests",
53 "create_collisions",
54 "create_invalid_interface",
55 "destroy_requests",
56 "destroy_misses",
57 "hash_hits",
58 "hash_reorders",
59 "flushes",
60 "evictions"
61};
62
63/*
64 * nss_stats_str_ipv6
65 * IPv6 stats strings
66 */
67static int8_t *nss_stats_str_ipv6[NSS_STATS_IPV6_MAX] = {
68 "rx_pkts",
69 "rx_bytes",
70 "tx_pkts",
71 "tx_bytes",
72 "create_requests",
73 "create_collisions",
74 "create_invalid_interface",
75 "destroy_requests",
76 "destroy_misses",
77 "hash_hits",
78 "hash_reorders",
79 "flushes",
80 "evictions",
81};
82
83/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053084 * nss_stats_str_n2h
85 * N2H stats strings
86 */
87static int8_t *nss_stats_str_n2h[NSS_STATS_N2H_MAX] = {
88 "queue_dropped",
89 "ticks",
90 "worst_ticks",
Murat Sezgin0c0561d2014-04-09 18:55:58 -070091 "iterations",
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053092 "pbuf_fails",
93 "payload_fails"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053094};
95
96/*
97 * nss_stats_str_drv
98 * Host driver stats strings
99 */
100static int8_t *nss_stats_str_drv[NSS_STATS_DRV_MAX] = {
101 "nbuf_alloc_errors",
102 "tx_queue_full[0]",
103 "tx_queue_full[1]",
104 "tx_buffers_empty",
105 "tx_buffers_pkt",
106 "tx_buffers_cmd",
107 "tx_buffers_crypto",
108 "rx_buffers_empty",
109 "rx_buffers_pkt",
110 "rx_buffers_cmd_resp",
111 "rx_buffers_status_sync",
112 "rx_buffers_crypto",
113 "rx_buffers_virtual"
114};
115
116/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530117 * nss_stats_str_pppoe
118 * PPPoE stats strings
119 */
120static int8_t *nss_stats_str_pppoe[NSS_STATS_PPPOE_MAX] = {
121 "create_requests",
122 "create_failures",
123 "destroy_requests",
124 "destroy_misses"
125};
126
127/*
128 * nss_stats_str_gmac
129 * GMAC stats strings
130 */
131static int8_t *nss_stats_str_gmac[NSS_STATS_GMAC_MAX] = {
132 "ticks",
133 "worst_ticks",
134 "iterations"
135};
136
137/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530138 * nss_stats_str_node
139 * Interface stats strings per node
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530140 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530141static int8_t *nss_stats_str_node[NSS_STATS_NODE_MAX] = {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530142 "rx_packets",
143 "rx_bytes",
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530144 "rx_dropped",
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530145 "tx_packets",
146 "tx_bytes"
147};
148
149/*
150 * nss_stats_str_if_exception_unknown
151 * Interface stats strings for unknown exceptions
152 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530153static int8_t *nss_stats_str_if_exception_eth_rx[NSS_EXCEPTION_EVENT_ETH_RX_MAX] = {
154 "UNKNOWN_L3_PROTOCOL"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530155};
156
157/*
158 * nss_stats_str_if_exception_ipv4
159 * Interface stats strings for ipv4 exceptions
160 */
161static int8_t *nss_stats_str_if_exception_ipv4[NSS_EXCEPTION_EVENT_IPV4_MAX] = {
162 "IPV4_ICMP_HEADER_INCOMPLETE",
163 "IPV4_ICMP_UNHANDLED_TYPE",
164 "IPV4_ICMP_IPV4_HEADER_INCOMPLETE",
165 "IPV4_ICMP_IPV4_UDP_HEADER_INCOMPLETE",
166 "IPV4_ICMP_IPV4_TCP_HEADER_INCOMPLETE",
167 "IPV4_ICMP_IPV4_UNKNOWN_PROTOCOL",
168 "IPV4_ICMP_NO_ICME",
169 "IPV4_ICMP_FLUSH_TO_HOST",
170 "IPV4_TCP_HEADER_INCOMPLETE",
171 "IPV4_TCP_NO_ICME",
172 "IPV4_TCP_IP_OPTION",
173 "IPV4_TCP_IP_FRAGMENT",
174 "IPV4_TCP_SMALL_TTL",
175 "IPV4_TCP_NEEDS_FRAGMENTATION",
176 "IPV4_TCP_FLAGS",
177 "IPV4_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
178 "IPV4_TCP_SMALL_DATA_OFFS",
179 "IPV4_TCP_BAD_SACK",
180 "IPV4_TCP_BIG_DATA_OFFS",
181 "IPV4_TCP_SEQ_BEFORE_LEFT_EDGE",
182 "IPV4_TCP_ACK_EXCEEDS_RIGHT_EDGE",
183 "IPV4_TCP_ACK_BEFORE_LEFT_EDGE",
184 "IPV4_UDP_HEADER_INCOMPLETE",
185 "IPV4_UDP_NO_ICME",
186 "IPV4_UDP_IP_OPTION",
187 "IPV4_UDP_IP_FRAGMENT",
188 "IPV4_UDP_SMALL_TTL",
189 "IPV4_UDP_NEEDS_FRAGMENTATION",
190 "IPV4_WRONG_TARGET_MAC",
191 "IPV4_HEADER_INCOMPLETE",
192 "IPV4_BAD_TOTAL_LENGTH",
193 "IPV4_BAD_CHECKSUM",
194 "IPV4_NON_INITIAL_FRAGMENT",
195 "IPV4_DATAGRAM_INCOMPLETE",
196 "IPV4_OPTIONS_INCOMPLETE",
Radha krishna Simha Jiguru59a1a1c2014-01-27 18:29:40 +0530197 "IPV4_UNKNOWN_PROTOCOL",
198 "IPV4_ESP_HEADER_INCOMPLETE",
199 "IPV4_ESP_NO_ICME",
200 "IPV4_ESP_IP_OPTION",
201 "IPV4_ESP_IP_FRAGMENT",
202 "IPV4_ESP_SMALL_TTL",
203 "IPV4_ESP_NEEDS_FRAGMENTATION",
204 "IPV4_INGRESS_VID_MISMATCH",
205 "IPV4_6RD_NO_ICME",
206 "IPV4_6RD_IP_OPTION",
207 "IPV4_6RD_IP_FRAGMENT",
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700208 "IPV4_6RD_NEEDS_FRAGMENTATION",
209 "IPV4_DSCP_MARKING_MISMATCH",
210 "IPV4_VLAN_MARKING_MISMATCH"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530211};
212
213/*
214 * nss_stats_str_if_exception_ipv6
215 * Interface stats strings for ipv6 exceptions
216 */
217static int8_t *nss_stats_str_if_exception_ipv6[NSS_EXCEPTION_EVENT_IPV6_MAX] = {
218 "IPV6_ICMP_HEADER_INCOMPLETE",
219 "IPV6_ICMP_UNHANDLED_TYPE",
220 "IPV6_ICMP_IPV6_HEADER_INCOMPLETE",
221 "IPV6_ICMP_IPV6_UDP_HEADER_INCOMPLETE",
222 "IPV6_ICMP_IPV6_TCP_HEADER_INCOMPLETE",
223 "IPV6_ICMP_IPV6_UNKNOWN_PROTOCOL",
224 "IPV6_ICMP_NO_ICME",
225 "IPV6_ICMP_FLUSH_TO_HOST",
226 "IPV6_TCP_HEADER_INCOMPLETE",
227 "IPV6_TCP_NO_ICME",
228 "IPV6_TCP_SMALL_HOP_LIMIT",
229 "IPV6_TCP_NEEDS_FRAGMENTATION",
230 "IPV6_TCP_FLAGS",
231 "IPV6_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
232 "IPV6_TCP_SMALL_DATA_OFFS",
233 "IPV6_TCP_BAD_SACK",
234 "IPV6_TCP_BIG_DATA_OFFS",
235 "IPV6_TCP_SEQ_BEFORE_LEFT_EDGE",
236 "IPV6_TCP_ACK_EXCEEDS_RIGHT_EDGE",
237 "IPV6_TCP_ACK_BEFORE_LEFT_EDGE",
238 "IPV6_UDP_HEADER_INCOMPLETE",
239 "IPV6_UDP_NO_ICME",
240 "IPV6_UDP_SMALL_HOP_LIMIT",
241 "IPV6_UDP_NEEDS_FRAGMENTATION",
242 "IPV6_WRONG_TARGET_MAC",
243 "IPV6_HEADER_INCOMPLETE",
Radha krishna Simha Jiguru59a1a1c2014-01-27 18:29:40 +0530244 "IPV6_UNKNOWN_PROTOCOL",
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700245 "IPV6_INGRESS_VID_MISMATCH",
246 "IPV6_DSCP_MARKING_MISMATCH",
247 "IPV6_VLAN_MARKING_MISMATCH",
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530248};
249
250/*
251 * nss_stats_str_if_exception_pppoe
252 * Interface stats strings for PPPoE exceptions
253 */
254static int8_t *nss_stats_str_if_exception_pppoe[NSS_EXCEPTION_EVENT_PPPOE_MAX] = {
255 "PPPOE_WRONG_VERSION_OR_TYPE",
256 "PPPOE_WRONG_CODE",
257 "PPPOE_HEADER_INCOMPLETE",
258 "PPPOE_UNSUPPORTED_PPP_PROTOCOL"
259};
260
261/*
262 * nss_stats_ipv4_read()
263 * Read IPV4 stats
264 */
265static ssize_t nss_stats_ipv4_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
266{
267 int32_t i;
268
269 /*
270 * max output lines = #stats + start tag line + end tag line + three blank lines
271 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530272 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV4_MAX + 3) + (NSS_EXCEPTION_EVENT_IPV4_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530273 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
274 size_t size_wr = 0;
275 ssize_t bytes_read = 0;
276 uint64_t *stats_shadow;
277
278 char *lbuf = kzalloc(size_al, GFP_KERNEL);
279 if (unlikely(lbuf == NULL)) {
280 nss_warning("Could not allocate memory for local statistics buffer");
281 return 0;
282 }
283
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530284 /*
285 * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
286 */
287 stats_shadow = kzalloc(NSS_EXCEPTION_EVENT_IPV4_MAX * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530288 if (unlikely(stats_shadow == NULL)) {
289 nss_warning("Could not allocate memory for local shadow buffer");
290 return 0;
291 }
292
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530293 size_wr = scnprintf(lbuf, size_al, "ipv4 stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530294
295 /*
296 * Common node stats
297 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530298 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530299 spin_lock_bh(&nss_top_main.stats_lock);
300 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
301 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV4_RX_INTERFACE][i];
302 }
303
304 spin_unlock_bh(&nss_top_main.stats_lock);
305
306 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
307 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
308 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
309 }
310
311 /*
312 * IPv4 node stats
313 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530314 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530315
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530316 spin_lock_bh(&nss_top_main.stats_lock);
317 for (i = 0; (i < NSS_STATS_IPV4_MAX); i++) {
318 stats_shadow[i] = nss_top_main.stats_ipv4[i];
319 }
320
321 spin_unlock_bh(&nss_top_main.stats_lock);
322
323 for (i = 0; (i < NSS_STATS_IPV4_MAX); i++) {
324 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
325 "%s = %llu\n", nss_stats_str_ipv4[i], stats_shadow[i]);
326 }
327
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530328 /*
329 * Exception stats
330 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530331 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530332
333 spin_lock_bh(&nss_top_main.stats_lock);
334 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV4_MAX); i++) {
335 stats_shadow[i] = nss_top_main.stats_if_exception_ipv4[i];
336 }
337
338 spin_unlock_bh(&nss_top_main.stats_lock);
339
340 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV4_MAX); i++) {
341 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
342 "%s = %llu\n", nss_stats_str_if_exception_ipv4[i], stats_shadow[i]);
343 }
344
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530345 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530346 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
347 kfree(lbuf);
348 kfree(stats_shadow);
349
350 return bytes_read;
351}
352
353/*
354 * nss_stats_ipv6_read()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530355 * Read IPV6 stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530356 */
357static ssize_t nss_stats_ipv6_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
358{
359 int32_t i;
360
361 /*
362 * max output lines = #stats + start tag line + end tag line + three blank lines
363 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530364 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV6_MAX + 3) + (NSS_EXCEPTION_EVENT_IPV6_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530365 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
366 size_t size_wr = 0;
367 ssize_t bytes_read = 0;
368 uint64_t *stats_shadow;
369
370 char *lbuf = kzalloc(size_al, GFP_KERNEL);
371 if (unlikely(lbuf == NULL)) {
372 nss_warning("Could not allocate memory for local statistics buffer");
373 return 0;
374 }
375
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530376 /*
377 * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
378 */
379 stats_shadow = kzalloc(NSS_EXCEPTION_EVENT_IPV6_MAX * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530380 if (unlikely(stats_shadow == NULL)) {
381 nss_warning("Could not allocate memory for local shadow buffer");
382 return 0;
383 }
384
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530385 size_wr = scnprintf(lbuf, size_al, "ipv6 stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530386
387 /*
388 * Common node stats
389 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530390 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530391 spin_lock_bh(&nss_top_main.stats_lock);
392 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
393 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV6_RX_INTERFACE][i];
394 }
395
396 spin_unlock_bh(&nss_top_main.stats_lock);
397
398 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
399 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
400 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
401 }
402
403 /*
404 * IPv6 node stats
405 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530406 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530407
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530408 spin_lock_bh(&nss_top_main.stats_lock);
409 for (i = 0; (i < NSS_STATS_IPV6_MAX); i++) {
410 stats_shadow[i] = nss_top_main.stats_ipv6[i];
411 }
412
413 spin_unlock_bh(&nss_top_main.stats_lock);
414
415 for (i = 0; (i < NSS_STATS_IPV6_MAX); i++) {
416 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
417 "%s = %llu\n", nss_stats_str_ipv6[i], stats_shadow[i]);
418 }
419
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530420 /*
421 * Exception stats
422 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530423 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530424
425 spin_lock_bh(&nss_top_main.stats_lock);
426 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV6_MAX); i++) {
427 stats_shadow[i] = nss_top_main.stats_if_exception_ipv6[i];
428 }
429
430 spin_unlock_bh(&nss_top_main.stats_lock);
431
432 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV6_MAX); i++) {
433 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
434 "%s = %llu\n", nss_stats_str_if_exception_ipv6[i], stats_shadow[i]);
435 }
436
437 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\nipv6 stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530438 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
439 kfree(lbuf);
440 kfree(stats_shadow);
441
442 return bytes_read;
443}
444
445/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530446 * nss_stats_eth_rx_read()
447 * Read ETH_RX stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530448 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530449static ssize_t nss_stats_eth_rx_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530450{
451 int32_t i;
452
453 /*
454 * max output lines = #stats + start tag line + end tag line + three blank lines
455 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530456 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_EXCEPTION_EVENT_ETH_RX_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530457 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
458 size_t size_wr = 0;
459 ssize_t bytes_read = 0;
460 uint64_t *stats_shadow;
461
462 char *lbuf = kzalloc(size_al, GFP_KERNEL);
463 if (unlikely(lbuf == NULL)) {
464 nss_warning("Could not allocate memory for local statistics buffer");
465 return 0;
466 }
467
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530468 /*
469 * Note: The assumption here is that we do not have more than 64 stats
470 */
471 stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530472 if (unlikely(stats_shadow == NULL)) {
473 nss_warning("Could not allocate memory for local shadow buffer");
474 return 0;
475 }
476
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530477 size_wr = scnprintf(lbuf, size_al,"eth_rx stats start:\n\n");
478
479 /*
480 * Common node stats
481 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530482 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530483 spin_lock_bh(&nss_top_main.stats_lock);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530484 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
485 stats_shadow[i] = nss_top_main.stats_node[NSS_ETH_RX_INTERFACE][i];
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530486 }
487
488 spin_unlock_bh(&nss_top_main.stats_lock);
489
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530490 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530491 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530492 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530493 }
494
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530495 /*
496 * Exception stats
497 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530498 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530499
500 spin_lock_bh(&nss_top_main.stats_lock);
501 for (i = 0; (i < NSS_EXCEPTION_EVENT_ETH_RX_MAX); i++) {
502 stats_shadow[i] = nss_top_main.stats_if_exception_eth_rx[i];
503 }
504
505 spin_unlock_bh(&nss_top_main.stats_lock);
506
507 for (i = 0; (i < NSS_EXCEPTION_EVENT_ETH_RX_MAX); i++) {
508 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
509 "%s = %llu\n", nss_stats_str_if_exception_eth_rx[i], stats_shadow[i]);
510 }
511
512 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\neth_rx stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530513 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
514 kfree(lbuf);
515 kfree(stats_shadow);
516
517 return bytes_read;
518}
519
520/*
521 * nss_stats_n2h_read()
522 * Read N2H stats
523 */
524static ssize_t nss_stats_n2h_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
525{
526 int32_t i;
527
528 /*
529 * max output lines = #stats + start tag line + end tag line + three blank lines
530 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530531 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_N2H_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530532 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
533 size_t size_wr = 0;
534 ssize_t bytes_read = 0;
535 uint64_t *stats_shadow;
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700536 int max = NSS_STATS_N2H_MAX - NSS_STATS_NODE_MAX;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530537
538 char *lbuf = kzalloc(size_al, GFP_KERNEL);
539 if (unlikely(lbuf == NULL)) {
540 nss_warning("Could not allocate memory for local statistics buffer");
541 return 0;
542 }
543
544 stats_shadow = kzalloc(NSS_STATS_N2H_MAX * 8, GFP_KERNEL);
545 if (unlikely(stats_shadow == NULL)) {
546 nss_warning("Could not allocate memory for local shadow buffer");
547 return 0;
548 }
549
550 size_wr = scnprintf(lbuf, size_al, "n2h stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530551
552 /*
553 * Common node stats
554 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530555 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530556 spin_lock_bh(&nss_top_main.stats_lock);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530557 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
558 stats_shadow[i] = nss_top_main.nss[0].stats_n2h[i];
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530559 }
560
561 spin_unlock_bh(&nss_top_main.stats_lock);
562
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530563 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
564 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
565 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
566 }
567
568 /*
569 * N2H node stats
570 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530571 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530572 spin_lock_bh(&nss_top_main.stats_lock);
573 for (i = NSS_STATS_NODE_MAX; (i < NSS_STATS_N2H_MAX); i++) {
574 stats_shadow[i] = nss_top_main.nss[0].stats_n2h[i];
575 }
576
577 spin_unlock_bh(&nss_top_main.stats_lock);
578
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700579 for (i = 0; i < max; i++) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530580 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700581 "%s = %llu\n", nss_stats_str_n2h[i], stats_shadow[i + NSS_STATS_NODE_MAX]);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530582 }
583
584 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h stats end\n\n");
585 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
586 kfree(lbuf);
587 kfree(stats_shadow);
588
589 return bytes_read;
590}
591
592/*
593 * nss_stats_drv_read()
594 * Read HLOS driver stats
595 */
596static ssize_t nss_stats_drv_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
597{
598 int32_t i;
599
600 /*
601 * max output lines = #stats + start tag line + end tag line + three blank lines
602 */
603 uint32_t max_output_lines = NSS_STATS_DRV_MAX + 5;
604 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
605 size_t size_wr = 0;
606 ssize_t bytes_read = 0;
607 uint64_t *stats_shadow;
608
609 char *lbuf = kzalloc(size_al, GFP_KERNEL);
610 if (unlikely(lbuf == NULL)) {
611 nss_warning("Could not allocate memory for local statistics buffer");
612 return 0;
613 }
614
615 stats_shadow = kzalloc(NSS_STATS_DRV_MAX * 8, GFP_KERNEL);
616 if (unlikely(stats_shadow == NULL)) {
617 nss_warning("Could not allocate memory for local shadow buffer");
618 return 0;
619 }
620
621 size_wr = scnprintf(lbuf, size_al, "drv stats start:\n\n");
622 spin_lock_bh(&nss_top_main.stats_lock);
623 for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
624 stats_shadow[i] = nss_top_main.stats_drv[i];
625 }
626
627 spin_unlock_bh(&nss_top_main.stats_lock);
628
629 for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
630 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
631 "%s = %llu\n", nss_stats_str_drv[i], stats_shadow[i]);
632 }
633
634 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ndrv stats end\n\n");
635 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
636 kfree(lbuf);
637 kfree(stats_shadow);
638
639 return bytes_read;
640}
641
642/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530643 * nss_stats_pppoe_read()
644 * Read PPPoE stats
645 */
646static ssize_t nss_stats_pppoe_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
647{
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530648 int32_t i, j, k;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530649
650 /*
651 * max output lines = #stats + start tag line + end tag line + three blank lines
652 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530653 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_PPPOE_MAX + 3) +
654 ((NSS_MAX_PHYSICAL_INTERFACES * NSS_PPPOE_NUM_SESSION_PER_INTERFACE * (NSS_EXCEPTION_EVENT_PPPOE_MAX + 5)) + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530655 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
656 size_t size_wr = 0;
657 ssize_t bytes_read = 0;
658 uint64_t *stats_shadow;
659
660 char *lbuf = kzalloc(size_al, GFP_KERNEL);
661 if (unlikely(lbuf == NULL)) {
662 nss_warning("Could not allocate memory for local statistics buffer");
663 return 0;
664 }
665
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530666 stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530667 if (unlikely(stats_shadow == NULL)) {
668 nss_warning("Could not allocate memory for local shadow buffer");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530669 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530670 return 0;
671 }
672
673 size_wr = scnprintf(lbuf, size_al, "pppoe stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530674
675 /*
676 * Common node stats
677 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530678 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530679 spin_lock_bh(&nss_top_main.stats_lock);
680 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
681 stats_shadow[i] = nss_top_main.stats_node[NSS_PPPOE_RX_INTERFACE][i];
682 }
683
684 spin_unlock_bh(&nss_top_main.stats_lock);
685
686 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
687 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
688 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
689 }
690
691 /*
692 * PPPoE node stats
693 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530694 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "pppoe node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530695 spin_lock_bh(&nss_top_main.stats_lock);
696 for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
697 stats_shadow[i] = nss_top_main.stats_pppoe[i];
698 }
699
700 spin_unlock_bh(&nss_top_main.stats_lock);
701
702 for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
703 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
704 "%s = %llu\n", nss_stats_str_pppoe[i], stats_shadow[i]);
705 }
706
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530707 /*
708 * Exception stats
709 */
710 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nException PPPoE:\n\n");
711
712 for (j = 0; j < NSS_MAX_PHYSICAL_INTERFACES; j++) {
713 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nInterface %d:\n\n", j);
714
715 spin_lock_bh(&nss_top_main.stats_lock);
716 for (k = 0; k < NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
717 for (i = 0; (i < NSS_EXCEPTION_EVENT_PPPOE_MAX); i++) {
718 stats_shadow_pppoe_except[k][i] = nss_top_main.stats_if_exception_pppoe[j][k][i];
719 }
720 }
721
722 spin_unlock_bh(&nss_top_main.stats_lock);
723
724 for (k = 0; k < NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
725 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. Session\n", k);
726 for (i = 0; (i < NSS_EXCEPTION_EVENT_PPPOE_MAX); i++) {
727 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
728 "%s = %llu\n",
729 nss_stats_str_if_exception_pppoe[i],
730 stats_shadow_pppoe_except[k][i]);
731 }
732 }
733
734 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npppoe stats end\n\n");
735 }
736
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530737 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
738 kfree(lbuf);
739 kfree(stats_shadow);
740
741 return bytes_read;
742}
743
744/*
745 * nss_stats_gmac_read()
746 * Read GMAC stats
747 */
748static ssize_t nss_stats_gmac_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
749{
750 uint32_t i, id;
751
752 /*
753 * max output lines = ((#stats + start tag + one blank) * #GMACs) + start/end tag + 3 blank
754 */
755 uint32_t max_output_lines = ((NSS_STATS_GMAC_MAX + 2) * NSS_MAX_PHYSICAL_INTERFACES) + 5;
756 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
757 size_t size_wr = 0;
758 ssize_t bytes_read = 0;
759 uint64_t *stats_shadow;
760
761 char *lbuf = kzalloc(size_al, GFP_KERNEL);
762 if (unlikely(lbuf == NULL)) {
763 nss_warning("Could not allocate memory for local statistics buffer");
764 return 0;
765 }
766
767 stats_shadow = kzalloc(NSS_STATS_GMAC_MAX * 8, GFP_KERNEL);
768 if (unlikely(stats_shadow == NULL)) {
769 nss_warning("Could not allocate memory for local shadow buffer");
770 return 0;
771 }
772
773 size_wr = scnprintf(lbuf, size_al, "gmac stats start:\n\n");
774
775 for (id = 0; id < NSS_MAX_PHYSICAL_INTERFACES; id++) {
776 spin_lock_bh(&nss_top_main.stats_lock);
777 for (i = 0; (i < NSS_STATS_GMAC_MAX); i++) {
778 stats_shadow[i] = nss_top_main.stats_gmac[id][i];
779 }
780
781 spin_unlock_bh(&nss_top_main.stats_lock);
782
783 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "GMAC ID: %d\n", id);
784 for (i = 0; (i < NSS_STATS_GMAC_MAX); i++) {
785 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
786 "%s = %llu\n", nss_stats_str_gmac[i], stats_shadow[i]);
787 }
788 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\n");
789 }
790
791 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngmac stats end\n\n");
792 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
793 kfree(lbuf);
794 kfree(stats_shadow);
795
796 return bytes_read;
797}
798
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530799#define NSS_STATS_DECLARE_FILE_OPERATIONS(name) \
800static const struct file_operations nss_stats_##name##_ops = { \
801 .open = simple_open, \
802 .read = nss_stats_##name##_read, \
803 .llseek = generic_file_llseek, \
804};
805
806/*
807 * nss_ipv4_stats_ops
808 */
809NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4)
810
811/*
812 * ipv6_stats_ops
813 */
814NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6)
815
816/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530817 * n2h_stats_ops
818 */
819NSS_STATS_DECLARE_FILE_OPERATIONS(n2h)
820/*
821 * drv_stats_ops
822 */
823NSS_STATS_DECLARE_FILE_OPERATIONS(drv)
824
825/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530826 * pppoe_stats_ops
827 */
828NSS_STATS_DECLARE_FILE_OPERATIONS(pppoe)
829
830/*
831 * gmac_stats_ops
832 */
833NSS_STATS_DECLARE_FILE_OPERATIONS(gmac)
834
835/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530836 * eth_rx_stats_ops
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530837 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530838NSS_STATS_DECLARE_FILE_OPERATIONS(eth_rx)
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530839
840/*
841 * nss_stats_init()
842 * Enable NSS statistics
843 */
844void nss_stats_init(void)
845{
846 /*
847 * NSS driver entry
848 */
849 nss_top_main.top_dentry = debugfs_create_dir("qca-nss-drv", NULL);
850 if (unlikely(nss_top_main.top_dentry == NULL)) {
851 nss_warning("Failed to create qca-nss-drv directory in debugfs");
852
853 /*
854 * Non availability of debugfs directory is not a catastrophy
855 * We can still go ahead with other initialization
856 */
857 return;
858 }
859
860 nss_top_main.stats_dentry = debugfs_create_dir("stats", nss_top_main.top_dentry);
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530861 if (unlikely(nss_top_main.stats_dentry == NULL)) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530862 nss_warning("Failed to create qca-nss-drv directory in debugfs");
863
864 /*
865 * Non availability of debugfs directory is not a catastrophy
866 * We can still go ahead with rest of initialization
867 */
868 return;
869 }
870
871 /*
872 * Create files to obtain statistics
873 */
874
875 /*
876 * ipv4_stats
877 */
878 nss_top_main.ipv4_dentry = debugfs_create_file("ipv4", 0400,
879 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv4_ops);
880 if (unlikely(nss_top_main.ipv4_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530881 nss_warning("Failed to create qca-nss-drv/stats/ipv4 file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530882 return;
883 }
884
885 /*
886 * ipv6_stats
887 */
888 nss_top_main.ipv6_dentry = debugfs_create_file("ipv6", 0400,
889 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv6_ops);
890 if (unlikely(nss_top_main.ipv6_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530891 nss_warning("Failed to create qca-nss-drv/stats/ipv6 file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530892 return;
893 }
894
895 /*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530896 * ipv6_stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530897 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530898 nss_top_main.eth_rx_dentry = debugfs_create_file("eth_rx", 0400,
899 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_eth_rx_ops);
900 if (unlikely(nss_top_main.eth_rx_dentry == NULL)) {
901 nss_warning("Failed to create qca-nss-drv/stats/eth_rx file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530902 return;
903 }
904
905 /*
906 * n2h_stats
907 */
908 nss_top_main.n2h_dentry = debugfs_create_file("n2h", 0400,
909 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_n2h_ops);
910 if (unlikely(nss_top_main.n2h_dentry == NULL)) {
911 nss_warning("Failed to create qca-nss-drv/stats/n2h directory in debugfs");
912 return;
913 }
914
915 /*
916 * drv_stats
917 */
918 nss_top_main.drv_dentry = debugfs_create_file("drv", 0400,
919 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_drv_ops);
920 if (unlikely(nss_top_main.drv_dentry == NULL)) {
921 nss_warning("Failed to create qca-nss-drv/stats/drv directory in debugfs");
922 return;
923 }
924
925 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530926 * pppoe_stats
927 */
928 nss_top_main.pppoe_dentry = debugfs_create_file("pppoe", 0400,
929 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_pppoe_ops);
930 if (unlikely(nss_top_main.pppoe_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530931 nss_warning("Failed to create qca-nss-drv/stats/pppoe file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530932 return;
933 }
934
935 /*
936 * gmac_stats
937 */
938 nss_top_main.gmac_dentry = debugfs_create_file("gmac", 0400,
939 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gmac_ops);
940 if (unlikely(nss_top_main.gmac_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530941 nss_warning("Failed to create qca-nss-drv/stats/gmac file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530942 return;
943 }
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530944}
945
946
947/*
948 * nss_stats_clean()
949 * Cleanup NSS statistics files
950 */
951void nss_stats_clean(void)
952{
953 /*
954 * Remove debugfs tree
955 */
956 if (likely(nss_top_main.top_dentry != NULL)) {
957 debugfs_remove_recursive(nss_top_main.top_dentry);
958 }
959}