blob: 90bc0e86bc26e5c43c085359a87cbddb1b412679 [file] [log] [blame]
Radhakrishna Jiguru1c9b2252013-08-27 23:57:48 +05301/*
2 **************************************************************************
Sundarajan Srinivasan6e0366b2015-01-20 12:10:42 -08003 * Copyright (c) 2013-2015, 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
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +053037uint64_t stats_shadow_pppoe_except[NSS_PPPOE_NUM_SESSION_PER_INTERFACE][NSS_PPPOE_EXCEPTION_EVENT_MAX];
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053038
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053039/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -070040 * Private data for every file descriptor
41 */
42struct nss_stats_data {
43 uint32_t if_num; /**< Interface number for CAPWAP stats */
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +053044 uint32_t index; /**< Index for GRE_REDIR stats */
Saurabh Misra09dddeb2014-09-30 16:38:07 -070045};
46
47/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053048 * Statistics structures
49 */
50
51/*
52 * nss_stats_str_ipv4
53 * IPv4 stats strings
54 */
55static int8_t *nss_stats_str_ipv4[NSS_STATS_IPV4_MAX] = {
56 "rx_pkts",
57 "rx_bytes",
58 "tx_pkts",
59 "tx_bytes",
60 "create_requests",
61 "create_collisions",
62 "create_invalid_interface",
63 "destroy_requests",
64 "destroy_misses",
65 "hash_hits",
66 "hash_reorders",
67 "flushes",
Selin Dag60ea2b22014-11-05 09:36:22 -080068 "evictions",
69 "fragmentations"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053070};
71
72/*
Selin Dag6d9b0c12014-11-04 18:27:21 -080073 * nss_stats_str_ipv4_reasm
74 * IPv4 reassembly stats strings
75 */
76static int8_t *nss_stats_str_ipv4_reasm[NSS_STATS_IPV4_REASM_MAX] = {
77 "evictions",
78 "alloc_fails",
79 "timeouts",
80};
81
82/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053083 * nss_stats_str_ipv6
84 * IPv6 stats strings
85 */
86static int8_t *nss_stats_str_ipv6[NSS_STATS_IPV6_MAX] = {
87 "rx_pkts",
88 "rx_bytes",
89 "tx_pkts",
90 "tx_bytes",
91 "create_requests",
92 "create_collisions",
93 "create_invalid_interface",
94 "destroy_requests",
95 "destroy_misses",
96 "hash_hits",
97 "hash_reorders",
98 "flushes",
99 "evictions",
100};
101
102/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530103 * nss_stats_str_n2h
104 * N2H stats strings
105 */
106static int8_t *nss_stats_str_n2h[NSS_STATS_N2H_MAX] = {
107 "queue_dropped",
108 "ticks",
109 "worst_ticks",
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700110 "iterations",
Thomas Wu3fd8dd72014-06-11 15:57:05 -0700111 "pbuf_ocm_alloc_fails",
112 "pbuf_ocm_free_count",
113 "pbuf_ocm_total_count",
114 "pbuf_default_alloc_fails",
115 "pbuf_default_free_count",
116 "pbuf_default_total_count",
Sakthi Vignesh Radhakrishnan2a8ee962014-11-22 13:35:38 -0800117 "payload_fails",
Thomas Wu53679842015-01-22 13:37:35 -0800118 "payload_free_count",
Sakthi Vignesh Radhakrishnan2a8ee962014-11-22 13:35:38 -0800119 "h2n_control_packets",
120 "h2n_control_bytes",
121 "n2h_control_packets",
122 "n2h_control_bytes",
123 "h2n_data_packets",
124 "h2n_data_bytes",
125 "n2h_data_packets",
126 "n2h_data_bytes",
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530127};
128
129/*
Thomas Wuc3e382c2014-10-29 15:35:13 -0700130 * nss_stats_str_lso_rx
131 * LSO_RX stats strings
132 */
133static int8_t *nss_stats_str_lso_rx[NSS_STATS_LSO_RX_MAX] = {
134 "tx_dropped",
135 "dropped",
136 "pbuf_alloc_fail",
137 "pbuf_reference_fail"
138};
139
140/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530141 * nss_stats_str_drv
142 * Host driver stats strings
143 */
144static int8_t *nss_stats_str_drv[NSS_STATS_DRV_MAX] = {
145 "nbuf_alloc_errors",
146 "tx_queue_full[0]",
147 "tx_queue_full[1]",
148 "tx_buffers_empty",
149 "tx_buffers_pkt",
150 "tx_buffers_cmd",
151 "tx_buffers_crypto",
152 "rx_buffers_empty",
153 "rx_buffers_pkt",
154 "rx_buffers_cmd_resp",
155 "rx_buffers_status_sync",
156 "rx_buffers_crypto",
Thomas Wu0acd8162014-12-07 15:43:39 -0800157 "rx_buffers_virtual",
158 "tx_skb_simple",
159 "tx_skb_nr_frags",
160 "tx_skb_fraglist",
161 "rx_skb_simple",
162 "rx_skb_nr_frags",
163 "rx_skb_fraglist",
Sundarajan Srinivasan6e0366b2015-01-20 12:10:42 -0800164 "rx_bad_desciptor",
165 "nss_skb_count"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530166};
167
168/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530169 * nss_stats_str_pppoe
170 * PPPoE stats strings
171 */
172static int8_t *nss_stats_str_pppoe[NSS_STATS_PPPOE_MAX] = {
173 "create_requests",
174 "create_failures",
175 "destroy_requests",
176 "destroy_misses"
177};
178
179/*
180 * nss_stats_str_gmac
181 * GMAC stats strings
182 */
183static int8_t *nss_stats_str_gmac[NSS_STATS_GMAC_MAX] = {
184 "ticks",
185 "worst_ticks",
186 "iterations"
187};
188
189/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530190 * nss_stats_str_node
191 * Interface stats strings per node
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530192 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530193static int8_t *nss_stats_str_node[NSS_STATS_NODE_MAX] = {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530194 "rx_packets",
195 "rx_bytes",
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530196 "rx_dropped",
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530197 "tx_packets",
198 "tx_bytes"
199};
200
201/*
Murat Sezgin99dab642014-08-28 14:40:34 -0700202 * nss_stats_str_eth_rx
203 * eth_rx stats strings
204 */
205static int8_t *nss_stats_str_eth_rx[NSS_STATS_ETH_RX_MAX] = {
206 "ticks",
207 "worst_ticks",
208 "iterations"
209};
210
211/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530212 * nss_stats_str_if_exception_unknown
213 * Interface stats strings for unknown exceptions
214 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530215static int8_t *nss_stats_str_if_exception_eth_rx[NSS_EXCEPTION_EVENT_ETH_RX_MAX] = {
Selin Dag2e8e48c2015-02-20 15:51:55 -0800216 "UNKNOWN_L3_PROTOCOL",
217 "ETH_HDR_MISSING",
218 "VLAN_MISSING"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530219};
220
221/*
222 * nss_stats_str_if_exception_ipv4
223 * Interface stats strings for ipv4 exceptions
224 */
225static int8_t *nss_stats_str_if_exception_ipv4[NSS_EXCEPTION_EVENT_IPV4_MAX] = {
226 "IPV4_ICMP_HEADER_INCOMPLETE",
227 "IPV4_ICMP_UNHANDLED_TYPE",
228 "IPV4_ICMP_IPV4_HEADER_INCOMPLETE",
229 "IPV4_ICMP_IPV4_UDP_HEADER_INCOMPLETE",
230 "IPV4_ICMP_IPV4_TCP_HEADER_INCOMPLETE",
231 "IPV4_ICMP_IPV4_UNKNOWN_PROTOCOL",
232 "IPV4_ICMP_NO_ICME",
233 "IPV4_ICMP_FLUSH_TO_HOST",
234 "IPV4_TCP_HEADER_INCOMPLETE",
235 "IPV4_TCP_NO_ICME",
236 "IPV4_TCP_IP_OPTION",
237 "IPV4_TCP_IP_FRAGMENT",
238 "IPV4_TCP_SMALL_TTL",
239 "IPV4_TCP_NEEDS_FRAGMENTATION",
240 "IPV4_TCP_FLAGS",
241 "IPV4_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
242 "IPV4_TCP_SMALL_DATA_OFFS",
243 "IPV4_TCP_BAD_SACK",
244 "IPV4_TCP_BIG_DATA_OFFS",
245 "IPV4_TCP_SEQ_BEFORE_LEFT_EDGE",
246 "IPV4_TCP_ACK_EXCEEDS_RIGHT_EDGE",
247 "IPV4_TCP_ACK_BEFORE_LEFT_EDGE",
248 "IPV4_UDP_HEADER_INCOMPLETE",
249 "IPV4_UDP_NO_ICME",
250 "IPV4_UDP_IP_OPTION",
251 "IPV4_UDP_IP_FRAGMENT",
252 "IPV4_UDP_SMALL_TTL",
253 "IPV4_UDP_NEEDS_FRAGMENTATION",
254 "IPV4_WRONG_TARGET_MAC",
255 "IPV4_HEADER_INCOMPLETE",
256 "IPV4_BAD_TOTAL_LENGTH",
257 "IPV4_BAD_CHECKSUM",
258 "IPV4_NON_INITIAL_FRAGMENT",
259 "IPV4_DATAGRAM_INCOMPLETE",
260 "IPV4_OPTIONS_INCOMPLETE",
Radha krishna Simha Jiguru59a1a1c2014-01-27 18:29:40 +0530261 "IPV4_UNKNOWN_PROTOCOL",
262 "IPV4_ESP_HEADER_INCOMPLETE",
263 "IPV4_ESP_NO_ICME",
264 "IPV4_ESP_IP_OPTION",
265 "IPV4_ESP_IP_FRAGMENT",
266 "IPV4_ESP_SMALL_TTL",
267 "IPV4_ESP_NEEDS_FRAGMENTATION",
268 "IPV4_INGRESS_VID_MISMATCH",
Thomas Wu8d6f4b22014-06-09 14:46:18 -0700269 "IPV4_INGRESS_VID_MISSING",
Radha krishna Simha Jiguru59a1a1c2014-01-27 18:29:40 +0530270 "IPV4_6RD_NO_ICME",
271 "IPV4_6RD_IP_OPTION",
272 "IPV4_6RD_IP_FRAGMENT",
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700273 "IPV4_6RD_NEEDS_FRAGMENTATION",
274 "IPV4_DSCP_MARKING_MISMATCH",
Murat Sezgin7c5956a2014-05-12 09:59:51 -0700275 "IPV4_VLAN_MARKING_MISMATCH",
Thomas Wu8d6f4b22014-06-09 14:46:18 -0700276 "IPV4_INTERFACE_MISMATCH",
Radha krishna Simha Jiguru00cfe562014-10-21 16:22:12 +0530277 "IPV4_GRE_HEADER_INCOMPLETE",
278 "IPV4_GRE_NO_ICME",
279 "IPV4_GRE_IP_OPTION",
280 "IPV4_GRE_IP_FRAGMENT",
281 "IPV4_GRE_SMALL_TTL",
282 "IPV4_GRE_NEEDS_FRAGMENTATION",
Selin Dag60ea2b22014-11-05 09:36:22 -0800283 "IPV4_FRAG_DF_SET",
284 "IPV4_FRAG_FAIL",
Saurabh Misra5b07cc02015-01-15 14:20:58 -0800285 "IPV4_DESTROY",
286 "IPV4_ICMP_IPV4_UDPLITE_HEADER_INCOMPLETE",
287 "IPV4_UDPLITE_HEADER_INCOMPLETE",
288 "IPV4_UDPLITE_NO_ICME",
289 "IPV4_UDPLITE_IP_OPTION",
290 "IPV4_UDPLITE_IP_FRAGMENT",
291 "IPV4_UDPLITE_SMALL_TTL",
292 "IPV4_UDPLITE_NEEDS_FRAGMENTATION"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530293};
294
295/*
296 * nss_stats_str_if_exception_ipv6
297 * Interface stats strings for ipv6 exceptions
298 */
299static int8_t *nss_stats_str_if_exception_ipv6[NSS_EXCEPTION_EVENT_IPV6_MAX] = {
300 "IPV6_ICMP_HEADER_INCOMPLETE",
301 "IPV6_ICMP_UNHANDLED_TYPE",
302 "IPV6_ICMP_IPV6_HEADER_INCOMPLETE",
303 "IPV6_ICMP_IPV6_UDP_HEADER_INCOMPLETE",
304 "IPV6_ICMP_IPV6_TCP_HEADER_INCOMPLETE",
305 "IPV6_ICMP_IPV6_UNKNOWN_PROTOCOL",
306 "IPV6_ICMP_NO_ICME",
307 "IPV6_ICMP_FLUSH_TO_HOST",
308 "IPV6_TCP_HEADER_INCOMPLETE",
309 "IPV6_TCP_NO_ICME",
310 "IPV6_TCP_SMALL_HOP_LIMIT",
311 "IPV6_TCP_NEEDS_FRAGMENTATION",
312 "IPV6_TCP_FLAGS",
313 "IPV6_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
314 "IPV6_TCP_SMALL_DATA_OFFS",
315 "IPV6_TCP_BAD_SACK",
316 "IPV6_TCP_BIG_DATA_OFFS",
317 "IPV6_TCP_SEQ_BEFORE_LEFT_EDGE",
318 "IPV6_TCP_ACK_EXCEEDS_RIGHT_EDGE",
319 "IPV6_TCP_ACK_BEFORE_LEFT_EDGE",
320 "IPV6_UDP_HEADER_INCOMPLETE",
321 "IPV6_UDP_NO_ICME",
322 "IPV6_UDP_SMALL_HOP_LIMIT",
323 "IPV6_UDP_NEEDS_FRAGMENTATION",
324 "IPV6_WRONG_TARGET_MAC",
325 "IPV6_HEADER_INCOMPLETE",
Radha krishna Simha Jiguru59a1a1c2014-01-27 18:29:40 +0530326 "IPV6_UNKNOWN_PROTOCOL",
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700327 "IPV6_INGRESS_VID_MISMATCH",
Thomas Wu8d6f4b22014-06-09 14:46:18 -0700328 "IPV6_INGRESS_VID_MISSING",
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700329 "IPV6_DSCP_MARKING_MISMATCH",
330 "IPV6_VLAN_MARKING_MISMATCH",
Thomas Wu8d6f4b22014-06-09 14:46:18 -0700331 "IPV6_INTERFACE_MISMATCH",
Saurabh Misra5b07cc02015-01-15 14:20:58 -0800332 "IPV6_GRE_NO_ICME",
333 "IPV6_GRE_NEEDS_FRAGMENTATION",
334 "IPV6_GRE_SMALL_HOP_LIMIT",
335 "IPV6_DESTROY",
336 "IPV6_ICMP_IPV6_UDPLITE_HEADER_INCOMPLETE",
337 "IPV6_UDPLITE_HEADER_INCOMPLETE",
338 "IPV6_UDPLITE_NO_ICME",
339 "IPV6_UDPLITE_SMALL_HOP_LIMIT",
340 "IPV6_UDPLITE_NEEDS_FRAGMENTATION"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530341};
342
343/*
344 * nss_stats_str_if_exception_pppoe
345 * Interface stats strings for PPPoE exceptions
346 */
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +0530347static int8_t *nss_stats_str_if_exception_pppoe[NSS_PPPOE_EXCEPTION_EVENT_MAX] = {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530348 "PPPOE_WRONG_VERSION_OR_TYPE",
349 "PPPOE_WRONG_CODE",
350 "PPPOE_HEADER_INCOMPLETE",
Murat Sezgin7c5956a2014-05-12 09:59:51 -0700351 "PPPOE_UNSUPPORTED_PPP_PROTOCOL",
352 "PPPOE_INTERFACE_MISMATCH"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530353};
354
355/*
356 * nss_stats_ipv4_read()
357 * Read IPV4 stats
358 */
359static ssize_t nss_stats_ipv4_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
360{
361 int32_t i;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530362 /*
363 * max output lines = #stats + start tag line + end tag line + three blank lines
364 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530365 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 +0530366 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
367 size_t size_wr = 0;
368 ssize_t bytes_read = 0;
369 uint64_t *stats_shadow;
370
371 char *lbuf = kzalloc(size_al, GFP_KERNEL);
372 if (unlikely(lbuf == NULL)) {
373 nss_warning("Could not allocate memory for local statistics buffer");
374 return 0;
375 }
376
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530377 /*
378 * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
379 */
380 stats_shadow = kzalloc(NSS_EXCEPTION_EVENT_IPV4_MAX * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530381 if (unlikely(stats_shadow == NULL)) {
382 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530383 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530384 return 0;
385 }
386
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530387 size_wr = scnprintf(lbuf, size_al, "ipv4 stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530388
389 /*
390 * Common node stats
391 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530392 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530393 spin_lock_bh(&nss_top_main.stats_lock);
394 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
395 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV4_RX_INTERFACE][i];
396 }
397
398 spin_unlock_bh(&nss_top_main.stats_lock);
399
400 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
401 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
402 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
403 }
404
405 /*
406 * IPv4 node stats
407 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530408 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530409
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530410 spin_lock_bh(&nss_top_main.stats_lock);
411 for (i = 0; (i < NSS_STATS_IPV4_MAX); i++) {
412 stats_shadow[i] = nss_top_main.stats_ipv4[i];
413 }
414
415 spin_unlock_bh(&nss_top_main.stats_lock);
416
417 for (i = 0; (i < NSS_STATS_IPV4_MAX); i++) {
418 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
419 "%s = %llu\n", nss_stats_str_ipv4[i], stats_shadow[i]);
420 }
421
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530422 /*
423 * Exception stats
424 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530425 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530426
427 spin_lock_bh(&nss_top_main.stats_lock);
428 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV4_MAX); i++) {
429 stats_shadow[i] = nss_top_main.stats_if_exception_ipv4[i];
430 }
431
432 spin_unlock_bh(&nss_top_main.stats_lock);
433
434 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV4_MAX); i++) {
435 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
436 "%s = %llu\n", nss_stats_str_if_exception_ipv4[i], stats_shadow[i]);
437 }
438
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530439 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530440 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
441 kfree(lbuf);
442 kfree(stats_shadow);
443
444 return bytes_read;
445}
446
447/*
Selin Dag6d9b0c12014-11-04 18:27:21 -0800448 * nss_stats_ipv4_reasm_read()
449 * Read IPV4 reassembly stats
450 */
451static ssize_t nss_stats_ipv4_reasm_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
452{
453 int32_t i;
454 /*
455 * max output lines = #stats + start tag line + end tag line + three blank lines
456 */
457 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV4_REASM_MAX + 3) + 5;
458 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
459 size_t size_wr = 0;
460 ssize_t bytes_read = 0;
461 uint64_t *stats_shadow;
462
463 char *lbuf = kzalloc(size_al, GFP_KERNEL);
464 if (unlikely(lbuf == NULL)) {
465 nss_warning("Could not allocate memory for local statistics buffer");
466 return 0;
467 }
468
469 stats_shadow = kzalloc(NSS_STATS_IPV4_REASM_MAX * 8, GFP_KERNEL);
470 if (unlikely(stats_shadow == NULL)) {
471 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530472 kfree(lbuf);
Selin Dag6d9b0c12014-11-04 18:27:21 -0800473 return 0;
474 }
475
476 size_wr = scnprintf(lbuf, size_al, "ipv4 reasm stats start:\n\n");
477
478 /*
479 * Common node stats
480 */
481 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
482 spin_lock_bh(&nss_top_main.stats_lock);
483 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
484 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV4_REASM_INTERFACE][i];
485 }
486
487 spin_unlock_bh(&nss_top_main.stats_lock);
488
489 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
490 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
491 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
492 }
493
494 /*
495 * IPv4 reasm node stats
496 */
497 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 reasm node stats:\n\n");
498
499 spin_lock_bh(&nss_top_main.stats_lock);
500 for (i = 0; (i < NSS_STATS_IPV4_REASM_MAX); i++) {
501 stats_shadow[i] = nss_top_main.stats_ipv4_reasm[i];
502 }
503
504 spin_unlock_bh(&nss_top_main.stats_lock);
505
506 for (i = 0; (i < NSS_STATS_IPV4_REASM_MAX); i++) {
507 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
508 "%s = %llu\n", nss_stats_str_ipv4_reasm[i], stats_shadow[i]);
509 }
510
511 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 reasm stats end\n\n");
512 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
513 kfree(lbuf);
514 kfree(stats_shadow);
515
516 return bytes_read;
517}
518
519/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530520 * nss_stats_ipv6_read()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530521 * Read IPV6 stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530522 */
523static ssize_t nss_stats_ipv6_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
524{
525 int32_t i;
526
527 /*
528 * max output lines = #stats + start tag line + end tag line + three blank lines
529 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530530 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 +0530531 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
532 size_t size_wr = 0;
533 ssize_t bytes_read = 0;
534 uint64_t *stats_shadow;
535
536 char *lbuf = kzalloc(size_al, GFP_KERNEL);
537 if (unlikely(lbuf == NULL)) {
538 nss_warning("Could not allocate memory for local statistics buffer");
539 return 0;
540 }
541
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530542 /*
543 * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
544 */
545 stats_shadow = kzalloc(NSS_EXCEPTION_EVENT_IPV6_MAX * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530546 if (unlikely(stats_shadow == NULL)) {
547 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530548 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530549 return 0;
550 }
551
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530552 size_wr = scnprintf(lbuf, size_al, "ipv6 stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530553
554 /*
555 * Common node stats
556 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530557 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530558 spin_lock_bh(&nss_top_main.stats_lock);
559 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
560 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV6_RX_INTERFACE][i];
561 }
562
563 spin_unlock_bh(&nss_top_main.stats_lock);
564
565 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
566 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
567 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
568 }
569
570 /*
571 * IPv6 node stats
572 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530573 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530574
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530575 spin_lock_bh(&nss_top_main.stats_lock);
576 for (i = 0; (i < NSS_STATS_IPV6_MAX); i++) {
577 stats_shadow[i] = nss_top_main.stats_ipv6[i];
578 }
579
580 spin_unlock_bh(&nss_top_main.stats_lock);
581
582 for (i = 0; (i < NSS_STATS_IPV6_MAX); i++) {
583 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
584 "%s = %llu\n", nss_stats_str_ipv6[i], stats_shadow[i]);
585 }
586
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530587 /*
588 * Exception stats
589 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530590 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530591
592 spin_lock_bh(&nss_top_main.stats_lock);
593 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV6_MAX); i++) {
594 stats_shadow[i] = nss_top_main.stats_if_exception_ipv6[i];
595 }
596
597 spin_unlock_bh(&nss_top_main.stats_lock);
598
599 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV6_MAX); i++) {
600 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
601 "%s = %llu\n", nss_stats_str_if_exception_ipv6[i], stats_shadow[i]);
602 }
603
604 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\nipv6 stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530605 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
606 kfree(lbuf);
607 kfree(stats_shadow);
608
609 return bytes_read;
610}
611
612/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530613 * nss_stats_eth_rx_read()
614 * Read ETH_RX stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530615 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530616static 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 +0530617{
618 int32_t i;
619
620 /*
621 * max output lines = #stats + start tag line + end tag line + three blank lines
622 */
Murat Sezgin99dab642014-08-28 14:40:34 -0700623 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_ETH_RX_MAX + 3) + (NSS_EXCEPTION_EVENT_ETH_RX_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530624 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
625 size_t size_wr = 0;
626 ssize_t bytes_read = 0;
627 uint64_t *stats_shadow;
628
629 char *lbuf = kzalloc(size_al, GFP_KERNEL);
630 if (unlikely(lbuf == NULL)) {
631 nss_warning("Could not allocate memory for local statistics buffer");
632 return 0;
633 }
634
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530635 /*
636 * Note: The assumption here is that we do not have more than 64 stats
637 */
638 stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530639 if (unlikely(stats_shadow == NULL)) {
640 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530641 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530642 return 0;
643 }
644
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530645 size_wr = scnprintf(lbuf, size_al,"eth_rx stats start:\n\n");
646
647 /*
648 * Common node stats
649 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530650 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530651 spin_lock_bh(&nss_top_main.stats_lock);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530652 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
653 stats_shadow[i] = nss_top_main.stats_node[NSS_ETH_RX_INTERFACE][i];
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530654 }
655
656 spin_unlock_bh(&nss_top_main.stats_lock);
657
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530658 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530659 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530660 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530661 }
662
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530663 /*
Murat Sezgin99dab642014-08-28 14:40:34 -0700664 * eth_rx node stats
665 */
666 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx node stats:\n\n");
667 spin_lock_bh(&nss_top_main.stats_lock);
668 for (i = 0; (i < NSS_STATS_ETH_RX_MAX); i++) {
669 stats_shadow[i] = nss_top_main.stats_eth_rx[i];
670 }
671
672 spin_unlock_bh(&nss_top_main.stats_lock);
673
674 for (i = 0; (i < NSS_STATS_ETH_RX_MAX); i++) {
675 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
676 "%s = %llu\n", nss_stats_str_eth_rx[i], stats_shadow[i]);
677 }
678
679 /*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530680 * Exception stats
681 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530682 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530683
684 spin_lock_bh(&nss_top_main.stats_lock);
685 for (i = 0; (i < NSS_EXCEPTION_EVENT_ETH_RX_MAX); i++) {
686 stats_shadow[i] = nss_top_main.stats_if_exception_eth_rx[i];
687 }
688
689 spin_unlock_bh(&nss_top_main.stats_lock);
690
691 for (i = 0; (i < NSS_EXCEPTION_EVENT_ETH_RX_MAX); i++) {
692 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
693 "%s = %llu\n", nss_stats_str_if_exception_eth_rx[i], stats_shadow[i]);
694 }
695
696 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\neth_rx stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530697 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
698 kfree(lbuf);
699 kfree(stats_shadow);
700
701 return bytes_read;
702}
703
704/*
705 * nss_stats_n2h_read()
706 * Read N2H stats
707 */
708static ssize_t nss_stats_n2h_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
709{
710 int32_t i;
711
712 /*
713 * max output lines = #stats + start tag line + end tag line + three blank lines
714 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530715 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_N2H_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530716 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
717 size_t size_wr = 0;
718 ssize_t bytes_read = 0;
719 uint64_t *stats_shadow;
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700720 int max = NSS_STATS_N2H_MAX - NSS_STATS_NODE_MAX;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530721
722 char *lbuf = kzalloc(size_al, GFP_KERNEL);
723 if (unlikely(lbuf == NULL)) {
724 nss_warning("Could not allocate memory for local statistics buffer");
725 return 0;
726 }
727
728 stats_shadow = kzalloc(NSS_STATS_N2H_MAX * 8, GFP_KERNEL);
729 if (unlikely(stats_shadow == NULL)) {
730 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530731 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530732 return 0;
733 }
734
735 size_wr = scnprintf(lbuf, size_al, "n2h stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530736
737 /*
738 * Common node stats
739 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530740 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530741 spin_lock_bh(&nss_top_main.stats_lock);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530742 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
743 stats_shadow[i] = nss_top_main.nss[0].stats_n2h[i];
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530744 }
745
746 spin_unlock_bh(&nss_top_main.stats_lock);
747
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530748 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
749 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
750 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
751 }
752
753 /*
754 * N2H node stats
755 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530756 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530757 spin_lock_bh(&nss_top_main.stats_lock);
758 for (i = NSS_STATS_NODE_MAX; (i < NSS_STATS_N2H_MAX); i++) {
759 stats_shadow[i] = nss_top_main.nss[0].stats_n2h[i];
760 }
761
762 spin_unlock_bh(&nss_top_main.stats_lock);
763
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700764 for (i = 0; i < max; i++) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530765 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700766 "%s = %llu\n", nss_stats_str_n2h[i], stats_shadow[i + NSS_STATS_NODE_MAX]);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530767 }
768
769 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h stats end\n\n");
770 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
771 kfree(lbuf);
772 kfree(stats_shadow);
773
774 return bytes_read;
775}
776
777/*
Thomas Wuc3e382c2014-10-29 15:35:13 -0700778 * nss_stats_lso_rx_read()
779 * Read LSO_RX stats
780 */
781static ssize_t nss_stats_lso_rx_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
782{
783 int32_t i;
784
785 /*
786 * max output lines = #stats + start tag line + end tag line + three blank lines
787 */
788 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_LSO_RX_MAX + 3) + 5;
789 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
790 size_t size_wr = 0;
791 ssize_t bytes_read = 0;
792 uint64_t *stats_shadow;
793
794 char *lbuf = kzalloc(size_al, GFP_KERNEL);
795 if (unlikely(lbuf == NULL)) {
796 nss_warning("Could not allocate memory for local statistics buffer");
797 return 0;
798 }
799
800 stats_shadow = kzalloc(NSS_STATS_LSO_RX_MAX * 8, GFP_KERNEL);
801 if (unlikely(stats_shadow == NULL)) {
802 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530803 kfree(lbuf);
Thomas Wuc3e382c2014-10-29 15:35:13 -0700804 return 0;
805 }
806
807 size_wr = scnprintf(lbuf, size_al, "lso_rx stats start:\n\n");
808
809 /*
810 * Common node stats
811 */
812 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
813 spin_lock_bh(&nss_top_main.stats_lock);
814 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
815 stats_shadow[i] = nss_top_main.stats_node[NSS_LSO_RX_INTERFACE][i];
816 }
817
818 spin_unlock_bh(&nss_top_main.stats_lock);
819
820 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
821 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
822 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
823 }
824
825 /*
826 * lso_rx node stats
827 */
828 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nlso_rx node stats:\n\n");
829 spin_lock_bh(&nss_top_main.stats_lock);
830 for (i = 0; (i < NSS_STATS_LSO_RX_MAX); i++) {
831 stats_shadow[i] = nss_top_main.stats_lso_rx[i];
832 }
833
834 spin_unlock_bh(&nss_top_main.stats_lock);
835
836 for (i = 0; i < NSS_STATS_LSO_RX_MAX; i++) {
837 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
838 "%s = %llu\n", nss_stats_str_lso_rx[i], stats_shadow[i]);
839 }
840
841 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nlso_rx stats end\n\n");
842 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
843 kfree(lbuf);
844 kfree(stats_shadow);
845
846 return bytes_read;
847}
848
849/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530850 * nss_stats_drv_read()
851 * Read HLOS driver stats
852 */
853static ssize_t nss_stats_drv_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
854{
855 int32_t i;
856
857 /*
858 * max output lines = #stats + start tag line + end tag line + three blank lines
859 */
860 uint32_t max_output_lines = NSS_STATS_DRV_MAX + 5;
861 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
862 size_t size_wr = 0;
863 ssize_t bytes_read = 0;
864 uint64_t *stats_shadow;
865
866 char *lbuf = kzalloc(size_al, GFP_KERNEL);
867 if (unlikely(lbuf == NULL)) {
868 nss_warning("Could not allocate memory for local statistics buffer");
869 return 0;
870 }
871
872 stats_shadow = kzalloc(NSS_STATS_DRV_MAX * 8, GFP_KERNEL);
873 if (unlikely(stats_shadow == NULL)) {
874 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530875 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530876 return 0;
877 }
878
879 size_wr = scnprintf(lbuf, size_al, "drv stats start:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530880 for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
Sundarajan Srinivasan62fee7e2015-01-22 11:13:10 -0800881 stats_shadow[i] = NSS_PKT_STATS_READ(&nss_top_main.stats_drv[i]);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530882 }
883
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530884 for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
885 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
886 "%s = %llu\n", nss_stats_str_drv[i], stats_shadow[i]);
887 }
888
889 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ndrv stats end\n\n");
890 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
891 kfree(lbuf);
892 kfree(stats_shadow);
893
894 return bytes_read;
895}
896
897/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530898 * nss_stats_pppoe_read()
899 * Read PPPoE stats
900 */
901static ssize_t nss_stats_pppoe_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
902{
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530903 int32_t i, j, k;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530904
905 /*
906 * max output lines = #stats + start tag line + end tag line + three blank lines
907 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530908 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_PPPOE_MAX + 3) +
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +0530909 ((NSS_MAX_PHYSICAL_INTERFACES * NSS_PPPOE_NUM_SESSION_PER_INTERFACE * (NSS_PPPOE_EXCEPTION_EVENT_MAX + 5)) + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530910 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
911 size_t size_wr = 0;
912 ssize_t bytes_read = 0;
913 uint64_t *stats_shadow;
914
915 char *lbuf = kzalloc(size_al, GFP_KERNEL);
916 if (unlikely(lbuf == NULL)) {
917 nss_warning("Could not allocate memory for local statistics buffer");
918 return 0;
919 }
920
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530921 stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530922 if (unlikely(stats_shadow == NULL)) {
923 nss_warning("Could not allocate memory for local shadow buffer");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530924 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530925 return 0;
926 }
927
928 size_wr = scnprintf(lbuf, size_al, "pppoe stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530929
930 /*
931 * Common node stats
932 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530933 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530934 spin_lock_bh(&nss_top_main.stats_lock);
935 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
936 stats_shadow[i] = nss_top_main.stats_node[NSS_PPPOE_RX_INTERFACE][i];
937 }
938
939 spin_unlock_bh(&nss_top_main.stats_lock);
940
941 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
942 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
943 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
944 }
945
946 /*
947 * PPPoE node stats
948 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530949 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "pppoe node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530950 spin_lock_bh(&nss_top_main.stats_lock);
951 for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
952 stats_shadow[i] = nss_top_main.stats_pppoe[i];
953 }
954
955 spin_unlock_bh(&nss_top_main.stats_lock);
956
957 for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
958 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
959 "%s = %llu\n", nss_stats_str_pppoe[i], stats_shadow[i]);
960 }
961
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530962 /*
963 * Exception stats
964 */
965 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nException PPPoE:\n\n");
966
967 for (j = 0; j < NSS_MAX_PHYSICAL_INTERFACES; j++) {
968 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nInterface %d:\n\n", j);
969
970 spin_lock_bh(&nss_top_main.stats_lock);
971 for (k = 0; k < NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +0530972 for (i = 0; (i < NSS_PPPOE_EXCEPTION_EVENT_MAX); i++) {
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530973 stats_shadow_pppoe_except[k][i] = nss_top_main.stats_if_exception_pppoe[j][k][i];
974 }
975 }
976
977 spin_unlock_bh(&nss_top_main.stats_lock);
978
979 for (k = 0; k < NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
980 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. Session\n", k);
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +0530981 for (i = 0; (i < NSS_PPPOE_EXCEPTION_EVENT_MAX); i++) {
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530982 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
983 "%s = %llu\n",
984 nss_stats_str_if_exception_pppoe[i],
985 stats_shadow_pppoe_except[k][i]);
986 }
987 }
988
989 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npppoe stats end\n\n");
990 }
991
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530992 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
993 kfree(lbuf);
994 kfree(stats_shadow);
995
996 return bytes_read;
997}
998
999/*
1000 * nss_stats_gmac_read()
1001 * Read GMAC stats
1002 */
1003static ssize_t nss_stats_gmac_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1004{
1005 uint32_t i, id;
1006
1007 /*
1008 * max output lines = ((#stats + start tag + one blank) * #GMACs) + start/end tag + 3 blank
1009 */
1010 uint32_t max_output_lines = ((NSS_STATS_GMAC_MAX + 2) * NSS_MAX_PHYSICAL_INTERFACES) + 5;
1011 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
1012 size_t size_wr = 0;
1013 ssize_t bytes_read = 0;
1014 uint64_t *stats_shadow;
1015
1016 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1017 if (unlikely(lbuf == NULL)) {
1018 nss_warning("Could not allocate memory for local statistics buffer");
1019 return 0;
1020 }
1021
1022 stats_shadow = kzalloc(NSS_STATS_GMAC_MAX * 8, GFP_KERNEL);
1023 if (unlikely(stats_shadow == NULL)) {
1024 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +05301025 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301026 return 0;
1027 }
1028
1029 size_wr = scnprintf(lbuf, size_al, "gmac stats start:\n\n");
1030
1031 for (id = 0; id < NSS_MAX_PHYSICAL_INTERFACES; id++) {
1032 spin_lock_bh(&nss_top_main.stats_lock);
1033 for (i = 0; (i < NSS_STATS_GMAC_MAX); i++) {
1034 stats_shadow[i] = nss_top_main.stats_gmac[id][i];
1035 }
1036
1037 spin_unlock_bh(&nss_top_main.stats_lock);
1038
1039 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "GMAC ID: %d\n", id);
1040 for (i = 0; (i < NSS_STATS_GMAC_MAX); i++) {
1041 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1042 "%s = %llu\n", nss_stats_str_gmac[i], stats_shadow[i]);
1043 }
1044 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\n");
1045 }
1046
1047 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngmac stats end\n\n");
1048 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
1049 kfree(lbuf);
1050 kfree(stats_shadow);
1051
1052 return bytes_read;
1053}
1054
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001055/*
Ankit Dhanuka14999992014-11-12 15:35:11 +05301056 * nss_stats_sjack_read()
1057 * Read SJACK stats
1058 */
1059static ssize_t nss_stats_sjack_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1060{
1061 int32_t i;
1062 /*
1063 * max output lines = #stats + start tag line + end tag line + three blank lines
1064 */
1065 uint32_t max_output_lines = NSS_STATS_NODE_MAX + 5;
1066 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
1067 size_t size_wr = 0;
1068 ssize_t bytes_read = 0;
1069 uint64_t *stats_shadow;
1070
1071 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1072 if (unlikely(lbuf == NULL)) {
1073 nss_warning("Could not allocate memory for local statistics buffer");
1074 return 0;
1075 }
1076
1077 stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL);
1078 if (unlikely(stats_shadow == NULL)) {
1079 nss_warning("Could not allocate memory for local shadow buffer");
1080 kfree(lbuf);
1081 return 0;
1082 }
1083
1084 size_wr = scnprintf(lbuf, size_al, "sjack stats start:\n\n");
1085
1086 /*
1087 * Common node stats
1088 */
1089 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
1090 spin_lock_bh(&nss_top_main.stats_lock);
1091 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
1092 stats_shadow[i] = nss_top_main.stats_node[NSS_SJACK_INTERFACE][i];
1093 }
1094
1095 spin_unlock_bh(&nss_top_main.stats_lock);
1096
1097 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
1098 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1099 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
1100 }
1101
1102 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nsjack stats end\n\n");
1103
1104 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
1105 kfree(lbuf);
1106 kfree(stats_shadow);
1107
1108 return bytes_read;
1109}
1110
1111/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001112 * Make a row for CAPWAP encap stats.
1113 */
1114static ssize_t nss_stats_capwap_encap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s)
1115{
Saurabh Misra3f66e872015-04-03 11:30:42 -07001116 char *header[] = { "packets", "bytes", "fragments", "drop_ref", "drop_ver", "drop_unalign",
1117 "drop_hroom", "drop_dtls", "drop_nwireless", "drop_qfull", "drop_memfail", "unknown" };
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001118 uint64_t tcnt = 0;
1119
1120 switch (i) {
1121 case 0:
1122 tcnt = s->pnode_stats.tx_packets;
1123 break;
1124 case 1:
1125 tcnt = s->pnode_stats.tx_bytes;
1126 break;
1127 case 2:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001128 tcnt = s->tx_segments;
1129 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001130 case 3:
1131 tcnt = s->tx_dropped_sg_ref;
1132 break;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001133 case 4:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001134 tcnt = s->tx_dropped_ver_mis;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001135 break;
1136 case 5:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001137 tcnt = s->tx_dropped_unalign;
1138 break;
1139 case 6:
1140 tcnt = s->tx_dropped_hroom;
1141 break;
1142 case 7:
1143 tcnt = s->tx_dropped_dtls;
1144 break;
1145 case 8:
1146 tcnt = s->tx_dropped_nwireless;
1147 break;
1148 case 9:
1149 tcnt = s->tx_queue_full_drops;
1150 break;
1151 case 10:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001152 tcnt = s->tx_mem_failure_drops;
1153 break;
1154 default:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001155 return 0;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001156 }
1157
Saurabh Misra3f66e872015-04-03 11:30:42 -07001158 return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001159}
1160
1161/*
1162 * Make a row for CAPWAP decap stats.
1163 */
1164static ssize_t nss_stats_capwap_decap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s)
1165{
Saurabh Misra3f66e872015-04-03 11:30:42 -07001166 char *header[] = { "packets", "bytes", "DTLS_pkts", "fragments", "rx_dropped", "drop_oversize",
1167 "drop_frag_timeout", "drop_frag_dup", "drop_frag_gap", "drop_qfull", "drop_memfail",
1168 "drop_csum", "drop_malformed", "unknown" };
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001169 uint64_t tcnt = 0;
1170
1171 switch(i) {
1172 case 0:
1173 tcnt = s->pnode_stats.rx_packets;
1174 break;
1175 case 1:
1176 tcnt = s->pnode_stats.rx_bytes;
1177 break;
1178 case 2:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001179 tcnt = s->dtls_pkts;
1180 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001181 case 3:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001182 tcnt = s->rx_segments;
1183 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001184 case 4:
1185 tcnt = s->pnode_stats.rx_dropped;
1186 break;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001187 case 5:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001188 tcnt = s->rx_oversize_drops;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001189 break;
1190 case 6:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001191 tcnt = s->rx_frag_timeout_drops;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001192 break;
1193 case 7:
1194 tcnt = s->rx_dup_frag;
1195 break;
1196 case 8:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001197 tcnt = s->rx_frag_gap_drops;
1198 break;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001199 case 9:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001200 tcnt = s->rx_queue_full_drops;
1201 return (snprintf(line, len, "%s = %llu (n2h = %llu)\n", header[i], tcnt, s->rx_n2h_queue_full_drops));
1202 case 10:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001203 tcnt = s->rx_mem_failure_drops;
1204 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001205 case 11:
1206 tcnt = s->rx_csum_drops;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001207 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001208 case 12:
1209 tcnt = s->rx_malformed;
1210 break;
1211 default:
1212 return 0;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001213 }
1214
Saurabh Misra3f66e872015-04-03 11:30:42 -07001215 return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001216}
1217
1218/*
1219 * nss_stats_capwap_read()
1220 * Read CAPWAP stats
1221 */
1222static ssize_t nss_stats_capwap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos, uint16_t type)
1223{
1224 struct nss_stats_data *data = fp->private_data;
1225 ssize_t bytes_read = 0;
1226 struct nss_capwap_tunnel_stats stats;
1227 size_t bytes;
1228 char line[80];
Saurabh Misra3f66e872015-04-03 11:30:42 -07001229 int start;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001230 uint32_t if_num = NSS_DYNAMIC_IF_START;
1231 uint32_t max_if_num = NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES;
1232
1233 if (data) {
1234 if_num = data->if_num;
1235 }
1236
1237 /*
1238 * If we are done accomodating all the CAPWAP tunnels.
1239 */
1240 if (if_num > max_if_num) {
1241 return 0;
1242 }
1243
1244 for (; if_num <= max_if_num; if_num++) {
1245 bool isthere;
1246
1247 if (nss_is_dynamic_interface(if_num) == false) {
1248 continue;
1249 }
1250
1251 if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
1252 continue;
1253 }
1254
1255 /*
1256 * If CAPWAP tunnel does not exists, then isthere will be false.
1257 */
1258 isthere = nss_capwap_get_stats(if_num, &stats);
1259 if (!isthere) {
1260 continue;
1261 }
1262
Saurabh Misra3f66e872015-04-03 11:30:42 -07001263 bytes = snprintf(line, sizeof(line), "----if_num : %2d----\n", if_num);
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001264 if ((bytes_read + bytes) > sz) {
1265 break;
1266 }
1267
1268 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1269 bytes_read = -EFAULT;
1270 goto fail;
1271 }
1272 bytes_read += bytes;
1273 start = 0;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001274 while (bytes_read < sz) {
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001275 if (type == 1) {
1276 bytes = nss_stats_capwap_encap(line, sizeof(line), start, &stats);
1277 } else {
1278 bytes = nss_stats_capwap_decap(line, sizeof(line), start, &stats);
1279 }
1280
Saurabh Misra3f66e872015-04-03 11:30:42 -07001281 /*
1282 * If we don't have any more lines in decap/encap.
1283 */
1284 if (bytes == 0) {
1285 break;
1286 }
1287
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001288 if ((bytes_read + bytes) > sz)
1289 break;
1290
1291 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1292 bytes_read = -EFAULT;
1293 goto fail;
1294 }
1295
1296 bytes_read += bytes;
1297 start++;
1298 }
1299 }
1300
1301 if (bytes_read > 0) {
1302 *ppos = bytes_read;
1303 }
1304
1305 if (data) {
1306 data->if_num = if_num;
1307 }
1308fail:
1309 return bytes_read;
1310}
1311
1312/*
1313 * nss_stats_capwap_decap_read()
1314 * Read CAPWAP decap stats
1315 */
1316static ssize_t nss_stats_capwap_decap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1317{
1318 return (nss_stats_capwap_read(fp, ubuf, sz, ppos, 0));
1319}
1320
1321/*
1322 * nss_stats_capwap_encap_read()
1323 * Read CAPWAP encap stats
1324 */
1325static ssize_t nss_stats_capwap_encap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1326{
1327 return (nss_stats_capwap_read(fp, ubuf, sz, ppos, 1));
1328}
1329
1330/*
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301331 * nss_stats_gre_redir()
1332 * Make a row for GRE_REDIR stats.
1333 */
1334static ssize_t nss_stats_gre_redir(char *line, int len, int i, struct nss_gre_redir_tunnel_stats *s)
1335{
1336 char *header[] = { "TX Packets", "TX Bytes", "TX Drops", "RX Packets", "RX Bytes", "Rx Drops" };
1337 uint64_t tcnt = 0;
1338
1339 switch (i) {
1340 case 0:
1341 tcnt = s->node_stats.tx_packets;
1342 break;
1343 case 1:
1344 tcnt = s->node_stats.tx_bytes;
1345 break;
1346 case 2:
1347 tcnt = s->tx_dropped;
1348 break;
1349 case 3:
1350 tcnt = s->node_stats.rx_packets;
1351 break;
1352 case 4:
1353 tcnt = s->node_stats.rx_bytes;
1354 break;
1355 case 5:
1356 tcnt = s->node_stats.rx_dropped;
1357 break;
1358 default:
1359 i = 6;
1360 break;
1361 }
1362
1363 return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
1364}
1365
1366/*
1367 * nss_stats_gre_redir_read()
1368 * READ gre_redir tunnel stats.
1369 */
1370static ssize_t nss_stats_gre_redir_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1371{
1372 struct nss_stats_data *data = fp->private_data;
1373 ssize_t bytes_read = 0;
1374 struct nss_gre_redir_tunnel_stats stats;
1375 size_t bytes;
1376 char line[80];
1377 int start, end;
1378 int index = 0;
1379
1380 if (data) {
1381 index = data->index;
1382 }
1383
1384 /*
1385 * If we are done accomodating all the GRE_REDIR tunnels.
1386 */
1387 if (index >= NSS_GRE_REDIR_MAX_INTERFACES) {
1388 return 0;
1389 }
1390
1391 for (; index < NSS_GRE_REDIR_MAX_INTERFACES; index++) {
1392 bool isthere;
1393
1394 /*
1395 * If gre_redir tunnel does not exists, then isthere will be false.
1396 */
1397 isthere = nss_gre_redir_get_stats(index, &stats);
1398 if (!isthere) {
1399 continue;
1400 }
1401
1402 bytes = snprintf(line, sizeof(line), "\nTunnel if_num: %2d\n", stats.if_num);
1403 if ((bytes_read + bytes) > sz) {
1404 break;
1405 }
1406
1407 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1408 bytes_read = -EFAULT;
1409 goto fail;
1410 }
1411 bytes_read += bytes;
1412 start = 0;
1413 end = 6;
1414 while (bytes_read < sz && start < end) {
1415 bytes = nss_stats_gre_redir(line, sizeof(line), start, &stats);
1416
1417 if ((bytes_read + bytes) > sz)
1418 break;
1419
1420 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1421 bytes_read = -EFAULT;
1422 goto fail;
1423 }
1424
1425 bytes_read += bytes;
1426 start++;
1427 }
1428 }
1429
1430 if (bytes_read > 0) {
1431 *ppos = bytes_read;
1432 }
1433
1434 if (data) {
1435 data->index = index;
1436 }
1437
1438fail:
1439 return bytes_read;
1440}
1441
1442/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001443 * nss_stats_open()
1444 */
1445static int nss_stats_open(struct inode *inode, struct file *filp)
1446{
1447 struct nss_stats_data *data = NULL;
1448
1449 data = kzalloc(sizeof(struct nss_stats_data), GFP_KERNEL);
1450 if (!data) {
1451 return -ENOMEM;
1452 }
1453 memset(data, 0, sizeof (struct nss_stats_data));
1454 data->if_num = NSS_DYNAMIC_IF_START;
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301455 data->index = 0;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001456 filp->private_data = data;
1457
1458 return 0;
1459}
1460
1461/*
1462 * nss_stats_release()
1463 */
1464static int nss_stats_release(struct inode *inode, struct file *filp)
1465{
1466 struct nss_stats_data *data = filp->private_data;
1467
1468 if (data) {
1469 kfree(data);
1470 }
1471
1472 return 0;
1473}
1474
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301475#define NSS_STATS_DECLARE_FILE_OPERATIONS(name) \
1476static const struct file_operations nss_stats_##name##_ops = { \
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001477 .open = nss_stats_open, \
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301478 .read = nss_stats_##name##_read, \
1479 .llseek = generic_file_llseek, \
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001480 .release = nss_stats_release, \
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301481};
1482
1483/*
1484 * nss_ipv4_stats_ops
1485 */
1486NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4)
1487
1488/*
Selin Dag6d9b0c12014-11-04 18:27:21 -08001489 * ipv4_reasm_stats_ops
1490 */
1491NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4_reasm)
1492
1493/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301494 * ipv6_stats_ops
1495 */
1496NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6)
1497
1498/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301499 * n2h_stats_ops
1500 */
1501NSS_STATS_DECLARE_FILE_OPERATIONS(n2h)
Thomas Wuc3e382c2014-10-29 15:35:13 -07001502
1503/*
1504 * lso_rx_stats_ops
1505 */
1506NSS_STATS_DECLARE_FILE_OPERATIONS(lso_rx)
1507
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301508/*
1509 * drv_stats_ops
1510 */
1511NSS_STATS_DECLARE_FILE_OPERATIONS(drv)
1512
1513/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301514 * pppoe_stats_ops
1515 */
1516NSS_STATS_DECLARE_FILE_OPERATIONS(pppoe)
1517
1518/*
1519 * gmac_stats_ops
1520 */
1521NSS_STATS_DECLARE_FILE_OPERATIONS(gmac)
1522
1523/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001524 * capwap_stats_ops
1525 */
1526NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_encap)
1527NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_decap)
1528
1529/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301530 * eth_rx_stats_ops
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301531 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301532NSS_STATS_DECLARE_FILE_OPERATIONS(eth_rx)
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301533
1534/*
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301535 * gre_redir_ops
1536 */
1537NSS_STATS_DECLARE_FILE_OPERATIONS(gre_redir)
1538
1539/*
Ankit Dhanuka14999992014-11-12 15:35:11 +05301540 * sjack_stats_ops
1541 */
1542NSS_STATS_DECLARE_FILE_OPERATIONS(sjack)
1543
1544/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301545 * nss_stats_init()
1546 * Enable NSS statistics
1547 */
1548void nss_stats_init(void)
1549{
1550 /*
1551 * NSS driver entry
1552 */
1553 nss_top_main.top_dentry = debugfs_create_dir("qca-nss-drv", NULL);
1554 if (unlikely(nss_top_main.top_dentry == NULL)) {
1555 nss_warning("Failed to create qca-nss-drv directory in debugfs");
1556
1557 /*
1558 * Non availability of debugfs directory is not a catastrophy
1559 * We can still go ahead with other initialization
1560 */
1561 return;
1562 }
1563
1564 nss_top_main.stats_dentry = debugfs_create_dir("stats", nss_top_main.top_dentry);
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05301565 if (unlikely(nss_top_main.stats_dentry == NULL)) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301566 nss_warning("Failed to create qca-nss-drv directory in debugfs");
1567
1568 /*
1569 * Non availability of debugfs directory is not a catastrophy
1570 * We can still go ahead with rest of initialization
1571 */
1572 return;
1573 }
1574
1575 /*
1576 * Create files to obtain statistics
1577 */
1578
1579 /*
1580 * ipv4_stats
1581 */
1582 nss_top_main.ipv4_dentry = debugfs_create_file("ipv4", 0400,
1583 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv4_ops);
1584 if (unlikely(nss_top_main.ipv4_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05301585 nss_warning("Failed to create qca-nss-drv/stats/ipv4 file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301586 return;
1587 }
1588
1589 /*
Selin Dag6d9b0c12014-11-04 18:27:21 -08001590 * ipv4_reasm_stats
1591 */
1592 nss_top_main.ipv4_reasm_dentry = debugfs_create_file("ipv4_reasm", 0400,
1593 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv4_reasm_ops);
1594 if (unlikely(nss_top_main.ipv4_reasm_dentry == NULL)) {
1595 nss_warning("Failed to create qca-nss-drv/stats/ipv4_reasm file in debugfs");
1596 return;
1597 }
1598
1599 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301600 * ipv6_stats
1601 */
1602 nss_top_main.ipv6_dentry = debugfs_create_file("ipv6", 0400,
1603 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv6_ops);
1604 if (unlikely(nss_top_main.ipv6_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05301605 nss_warning("Failed to create qca-nss-drv/stats/ipv6 file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301606 return;
1607 }
1608
1609 /*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301610 * ipv6_stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301611 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301612 nss_top_main.eth_rx_dentry = debugfs_create_file("eth_rx", 0400,
1613 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_eth_rx_ops);
1614 if (unlikely(nss_top_main.eth_rx_dentry == NULL)) {
1615 nss_warning("Failed to create qca-nss-drv/stats/eth_rx file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301616 return;
1617 }
1618
1619 /*
1620 * n2h_stats
1621 */
1622 nss_top_main.n2h_dentry = debugfs_create_file("n2h", 0400,
1623 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_n2h_ops);
1624 if (unlikely(nss_top_main.n2h_dentry == NULL)) {
1625 nss_warning("Failed to create qca-nss-drv/stats/n2h directory in debugfs");
1626 return;
1627 }
1628
1629 /*
Thomas Wuc3e382c2014-10-29 15:35:13 -07001630 * lso_rx_stats
1631 */
1632 nss_top_main.lso_rx_dentry = debugfs_create_file("lso_rx", 0400,
1633 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_lso_rx_ops);
1634 if (unlikely(nss_top_main.lso_rx_dentry == NULL)) {
1635 nss_warning("Failed to create qca-nss-drv/stats/lso_rx file in debugfs");
1636 return;
1637 }
1638
1639 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301640 * drv_stats
1641 */
1642 nss_top_main.drv_dentry = debugfs_create_file("drv", 0400,
1643 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_drv_ops);
1644 if (unlikely(nss_top_main.drv_dentry == NULL)) {
1645 nss_warning("Failed to create qca-nss-drv/stats/drv directory in debugfs");
1646 return;
1647 }
1648
1649 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301650 * pppoe_stats
1651 */
1652 nss_top_main.pppoe_dentry = debugfs_create_file("pppoe", 0400,
1653 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_pppoe_ops);
1654 if (unlikely(nss_top_main.pppoe_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05301655 nss_warning("Failed to create qca-nss-drv/stats/pppoe file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301656 return;
1657 }
1658
1659 /*
1660 * gmac_stats
1661 */
1662 nss_top_main.gmac_dentry = debugfs_create_file("gmac", 0400,
1663 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gmac_ops);
1664 if (unlikely(nss_top_main.gmac_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05301665 nss_warning("Failed to create qca-nss-drv/stats/gmac file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301666 return;
1667 }
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001668
1669 /*
1670 * CAPWAP stats.
1671 */
1672 nss_top_main.capwap_encap_dentry = debugfs_create_file("capwap_encap", 0400,
1673 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_capwap_encap_ops);
1674 if (unlikely(nss_top_main.capwap_encap_dentry == NULL)) {
1675 nss_warning("Failed to create qca-nss-drv/stats/capwap_encap file in debugfs");
1676 return;
1677 }
1678
1679 nss_top_main.capwap_decap_dentry = debugfs_create_file("capwap_decap", 0400,
1680 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_capwap_decap_ops);
1681 if (unlikely(nss_top_main.capwap_decap_dentry == NULL)) {
1682 nss_warning("Failed to create qca-nss-drv/stats/capwap_decap file in debugfs");
1683 return;
1684 }
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301685
1686 /*
1687 * GRE_REDIR stats
1688 */
1689 nss_top_main.gre_redir_dentry = debugfs_create_file("gre_redir", 0400,
Ankit Dhanuka14999992014-11-12 15:35:11 +05301690 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gre_redir_ops);
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301691 if (unlikely(nss_top_main.gre_redir_dentry == NULL)) {
1692 nss_warning("Failed to create qca-nss-drv/stats/gre_redir file in debugfs");
1693 return;
1694 }
Ankit Dhanuka14999992014-11-12 15:35:11 +05301695
1696 /*
1697 * SJACK stats
1698 */
1699 nss_top_main.sjack_dentry = debugfs_create_file("sjack", 0400,
1700 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_sjack_ops);
1701 if (unlikely(nss_top_main.sjack_dentry == NULL)) {
1702 nss_warning("Failed to create qca-nss-drv/stats/sjack file in debugfs");
1703 return;
1704 }
Saurabh Misra96998db2014-07-10 12:15:48 -07001705
1706 nss_log_init();
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301707}
1708
1709
1710/*
1711 * nss_stats_clean()
1712 * Cleanup NSS statistics files
1713 */
1714void nss_stats_clean(void)
1715{
1716 /*
1717 * Remove debugfs tree
1718 */
1719 if (likely(nss_top_main.top_dentry != NULL)) {
1720 debugfs_remove_recursive(nss_top_main.top_dentry);
1721 }
1722}