blob: ccc71db3890474853d367ca0a917c435911f6fd4 [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");
880 spin_lock_bh(&nss_top_main.stats_lock);
881 for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
882 stats_shadow[i] = nss_top_main.stats_drv[i];
883 }
884
885 spin_unlock_bh(&nss_top_main.stats_lock);
886
887 for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
888 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
889 "%s = %llu\n", nss_stats_str_drv[i], stats_shadow[i]);
890 }
891
892 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ndrv stats end\n\n");
893 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
894 kfree(lbuf);
895 kfree(stats_shadow);
896
897 return bytes_read;
898}
899
900/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530901 * nss_stats_pppoe_read()
902 * Read PPPoE stats
903 */
904static ssize_t nss_stats_pppoe_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
905{
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530906 int32_t i, j, k;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530907
908 /*
909 * max output lines = #stats + start tag line + end tag line + three blank lines
910 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530911 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_PPPOE_MAX + 3) +
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +0530912 ((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 +0530913 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
914 size_t size_wr = 0;
915 ssize_t bytes_read = 0;
916 uint64_t *stats_shadow;
917
918 char *lbuf = kzalloc(size_al, GFP_KERNEL);
919 if (unlikely(lbuf == NULL)) {
920 nss_warning("Could not allocate memory for local statistics buffer");
921 return 0;
922 }
923
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530924 stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530925 if (unlikely(stats_shadow == NULL)) {
926 nss_warning("Could not allocate memory for local shadow buffer");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530927 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530928 return 0;
929 }
930
931 size_wr = scnprintf(lbuf, size_al, "pppoe stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530932
933 /*
934 * Common node stats
935 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530936 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530937 spin_lock_bh(&nss_top_main.stats_lock);
938 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
939 stats_shadow[i] = nss_top_main.stats_node[NSS_PPPOE_RX_INTERFACE][i];
940 }
941
942 spin_unlock_bh(&nss_top_main.stats_lock);
943
944 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
945 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
946 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
947 }
948
949 /*
950 * PPPoE node stats
951 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530952 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "pppoe node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530953 spin_lock_bh(&nss_top_main.stats_lock);
954 for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
955 stats_shadow[i] = nss_top_main.stats_pppoe[i];
956 }
957
958 spin_unlock_bh(&nss_top_main.stats_lock);
959
960 for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
961 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
962 "%s = %llu\n", nss_stats_str_pppoe[i], stats_shadow[i]);
963 }
964
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530965 /*
966 * Exception stats
967 */
968 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nException PPPoE:\n\n");
969
970 for (j = 0; j < NSS_MAX_PHYSICAL_INTERFACES; j++) {
971 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nInterface %d:\n\n", j);
972
973 spin_lock_bh(&nss_top_main.stats_lock);
974 for (k = 0; k < NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +0530975 for (i = 0; (i < NSS_PPPOE_EXCEPTION_EVENT_MAX); i++) {
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530976 stats_shadow_pppoe_except[k][i] = nss_top_main.stats_if_exception_pppoe[j][k][i];
977 }
978 }
979
980 spin_unlock_bh(&nss_top_main.stats_lock);
981
982 for (k = 0; k < NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
983 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. Session\n", k);
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +0530984 for (i = 0; (i < NSS_PPPOE_EXCEPTION_EVENT_MAX); i++) {
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530985 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
986 "%s = %llu\n",
987 nss_stats_str_if_exception_pppoe[i],
988 stats_shadow_pppoe_except[k][i]);
989 }
990 }
991
992 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npppoe stats end\n\n");
993 }
994
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530995 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
996 kfree(lbuf);
997 kfree(stats_shadow);
998
999 return bytes_read;
1000}
1001
1002/*
1003 * nss_stats_gmac_read()
1004 * Read GMAC stats
1005 */
1006static ssize_t nss_stats_gmac_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1007{
1008 uint32_t i, id;
1009
1010 /*
1011 * max output lines = ((#stats + start tag + one blank) * #GMACs) + start/end tag + 3 blank
1012 */
1013 uint32_t max_output_lines = ((NSS_STATS_GMAC_MAX + 2) * NSS_MAX_PHYSICAL_INTERFACES) + 5;
1014 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
1015 size_t size_wr = 0;
1016 ssize_t bytes_read = 0;
1017 uint64_t *stats_shadow;
1018
1019 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1020 if (unlikely(lbuf == NULL)) {
1021 nss_warning("Could not allocate memory for local statistics buffer");
1022 return 0;
1023 }
1024
1025 stats_shadow = kzalloc(NSS_STATS_GMAC_MAX * 8, GFP_KERNEL);
1026 if (unlikely(stats_shadow == NULL)) {
1027 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +05301028 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301029 return 0;
1030 }
1031
1032 size_wr = scnprintf(lbuf, size_al, "gmac stats start:\n\n");
1033
1034 for (id = 0; id < NSS_MAX_PHYSICAL_INTERFACES; id++) {
1035 spin_lock_bh(&nss_top_main.stats_lock);
1036 for (i = 0; (i < NSS_STATS_GMAC_MAX); i++) {
1037 stats_shadow[i] = nss_top_main.stats_gmac[id][i];
1038 }
1039
1040 spin_unlock_bh(&nss_top_main.stats_lock);
1041
1042 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "GMAC ID: %d\n", id);
1043 for (i = 0; (i < NSS_STATS_GMAC_MAX); i++) {
1044 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1045 "%s = %llu\n", nss_stats_str_gmac[i], stats_shadow[i]);
1046 }
1047 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\n");
1048 }
1049
1050 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngmac stats end\n\n");
1051 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
1052 kfree(lbuf);
1053 kfree(stats_shadow);
1054
1055 return bytes_read;
1056}
1057
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001058/*
Ankit Dhanuka14999992014-11-12 15:35:11 +05301059 * nss_stats_sjack_read()
1060 * Read SJACK stats
1061 */
1062static ssize_t nss_stats_sjack_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1063{
1064 int32_t i;
1065 /*
1066 * max output lines = #stats + start tag line + end tag line + three blank lines
1067 */
1068 uint32_t max_output_lines = NSS_STATS_NODE_MAX + 5;
1069 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
1070 size_t size_wr = 0;
1071 ssize_t bytes_read = 0;
1072 uint64_t *stats_shadow;
1073
1074 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1075 if (unlikely(lbuf == NULL)) {
1076 nss_warning("Could not allocate memory for local statistics buffer");
1077 return 0;
1078 }
1079
1080 stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL);
1081 if (unlikely(stats_shadow == NULL)) {
1082 nss_warning("Could not allocate memory for local shadow buffer");
1083 kfree(lbuf);
1084 return 0;
1085 }
1086
1087 size_wr = scnprintf(lbuf, size_al, "sjack stats start:\n\n");
1088
1089 /*
1090 * Common node stats
1091 */
1092 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
1093 spin_lock_bh(&nss_top_main.stats_lock);
1094 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
1095 stats_shadow[i] = nss_top_main.stats_node[NSS_SJACK_INTERFACE][i];
1096 }
1097
1098 spin_unlock_bh(&nss_top_main.stats_lock);
1099
1100 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
1101 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1102 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
1103 }
1104
1105 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nsjack stats end\n\n");
1106
1107 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
1108 kfree(lbuf);
1109 kfree(stats_shadow);
1110
1111 return bytes_read;
1112}
1113
1114/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001115 * Make a row for CAPWAP encap stats.
1116 */
1117static ssize_t nss_stats_capwap_encap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s)
1118{
Saurabh Misra3f66e872015-04-03 11:30:42 -07001119 char *header[] = { "packets", "bytes", "fragments", "drop_ref", "drop_ver", "drop_unalign",
1120 "drop_hroom", "drop_dtls", "drop_nwireless", "drop_qfull", "drop_memfail", "unknown" };
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001121 uint64_t tcnt = 0;
1122
1123 switch (i) {
1124 case 0:
1125 tcnt = s->pnode_stats.tx_packets;
1126 break;
1127 case 1:
1128 tcnt = s->pnode_stats.tx_bytes;
1129 break;
1130 case 2:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001131 tcnt = s->tx_segments;
1132 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001133 case 3:
1134 tcnt = s->tx_dropped_sg_ref;
1135 break;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001136 case 4:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001137 tcnt = s->tx_dropped_ver_mis;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001138 break;
1139 case 5:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001140 tcnt = s->tx_dropped_unalign;
1141 break;
1142 case 6:
1143 tcnt = s->tx_dropped_hroom;
1144 break;
1145 case 7:
1146 tcnt = s->tx_dropped_dtls;
1147 break;
1148 case 8:
1149 tcnt = s->tx_dropped_nwireless;
1150 break;
1151 case 9:
1152 tcnt = s->tx_queue_full_drops;
1153 break;
1154 case 10:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001155 tcnt = s->tx_mem_failure_drops;
1156 break;
1157 default:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001158 return 0;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001159 }
1160
Saurabh Misra3f66e872015-04-03 11:30:42 -07001161 return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001162}
1163
1164/*
1165 * Make a row for CAPWAP decap stats.
1166 */
1167static ssize_t nss_stats_capwap_decap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s)
1168{
Saurabh Misra3f66e872015-04-03 11:30:42 -07001169 char *header[] = { "packets", "bytes", "DTLS_pkts", "fragments", "rx_dropped", "drop_oversize",
1170 "drop_frag_timeout", "drop_frag_dup", "drop_frag_gap", "drop_qfull", "drop_memfail",
1171 "drop_csum", "drop_malformed", "unknown" };
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001172 uint64_t tcnt = 0;
1173
1174 switch(i) {
1175 case 0:
1176 tcnt = s->pnode_stats.rx_packets;
1177 break;
1178 case 1:
1179 tcnt = s->pnode_stats.rx_bytes;
1180 break;
1181 case 2:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001182 tcnt = s->dtls_pkts;
1183 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001184 case 3:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001185 tcnt = s->rx_segments;
1186 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001187 case 4:
1188 tcnt = s->pnode_stats.rx_dropped;
1189 break;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001190 case 5:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001191 tcnt = s->rx_oversize_drops;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001192 break;
1193 case 6:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001194 tcnt = s->rx_frag_timeout_drops;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001195 break;
1196 case 7:
1197 tcnt = s->rx_dup_frag;
1198 break;
1199 case 8:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001200 tcnt = s->rx_frag_gap_drops;
1201 break;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001202 case 9:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001203 tcnt = s->rx_queue_full_drops;
1204 return (snprintf(line, len, "%s = %llu (n2h = %llu)\n", header[i], tcnt, s->rx_n2h_queue_full_drops));
1205 case 10:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001206 tcnt = s->rx_mem_failure_drops;
1207 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001208 case 11:
1209 tcnt = s->rx_csum_drops;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001210 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001211 case 12:
1212 tcnt = s->rx_malformed;
1213 break;
1214 default:
1215 return 0;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001216 }
1217
Saurabh Misra3f66e872015-04-03 11:30:42 -07001218 return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001219}
1220
1221/*
1222 * nss_stats_capwap_read()
1223 * Read CAPWAP stats
1224 */
1225static ssize_t nss_stats_capwap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos, uint16_t type)
1226{
1227 struct nss_stats_data *data = fp->private_data;
1228 ssize_t bytes_read = 0;
1229 struct nss_capwap_tunnel_stats stats;
1230 size_t bytes;
1231 char line[80];
Saurabh Misra3f66e872015-04-03 11:30:42 -07001232 int start;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001233 uint32_t if_num = NSS_DYNAMIC_IF_START;
1234 uint32_t max_if_num = NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES;
1235
1236 if (data) {
1237 if_num = data->if_num;
1238 }
1239
1240 /*
1241 * If we are done accomodating all the CAPWAP tunnels.
1242 */
1243 if (if_num > max_if_num) {
1244 return 0;
1245 }
1246
1247 for (; if_num <= max_if_num; if_num++) {
1248 bool isthere;
1249
1250 if (nss_is_dynamic_interface(if_num) == false) {
1251 continue;
1252 }
1253
1254 if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
1255 continue;
1256 }
1257
1258 /*
1259 * If CAPWAP tunnel does not exists, then isthere will be false.
1260 */
1261 isthere = nss_capwap_get_stats(if_num, &stats);
1262 if (!isthere) {
1263 continue;
1264 }
1265
Saurabh Misra3f66e872015-04-03 11:30:42 -07001266 bytes = snprintf(line, sizeof(line), "----if_num : %2d----\n", if_num);
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001267 if ((bytes_read + bytes) > sz) {
1268 break;
1269 }
1270
1271 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1272 bytes_read = -EFAULT;
1273 goto fail;
1274 }
1275 bytes_read += bytes;
1276 start = 0;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001277 while (bytes_read < sz) {
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001278 if (type == 1) {
1279 bytes = nss_stats_capwap_encap(line, sizeof(line), start, &stats);
1280 } else {
1281 bytes = nss_stats_capwap_decap(line, sizeof(line), start, &stats);
1282 }
1283
Saurabh Misra3f66e872015-04-03 11:30:42 -07001284 /*
1285 * If we don't have any more lines in decap/encap.
1286 */
1287 if (bytes == 0) {
1288 break;
1289 }
1290
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001291 if ((bytes_read + bytes) > sz)
1292 break;
1293
1294 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1295 bytes_read = -EFAULT;
1296 goto fail;
1297 }
1298
1299 bytes_read += bytes;
1300 start++;
1301 }
1302 }
1303
1304 if (bytes_read > 0) {
1305 *ppos = bytes_read;
1306 }
1307
1308 if (data) {
1309 data->if_num = if_num;
1310 }
1311fail:
1312 return bytes_read;
1313}
1314
1315/*
1316 * nss_stats_capwap_decap_read()
1317 * Read CAPWAP decap stats
1318 */
1319static ssize_t nss_stats_capwap_decap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1320{
1321 return (nss_stats_capwap_read(fp, ubuf, sz, ppos, 0));
1322}
1323
1324/*
1325 * nss_stats_capwap_encap_read()
1326 * Read CAPWAP encap stats
1327 */
1328static ssize_t nss_stats_capwap_encap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1329{
1330 return (nss_stats_capwap_read(fp, ubuf, sz, ppos, 1));
1331}
1332
1333/*
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301334 * nss_stats_gre_redir()
1335 * Make a row for GRE_REDIR stats.
1336 */
1337static ssize_t nss_stats_gre_redir(char *line, int len, int i, struct nss_gre_redir_tunnel_stats *s)
1338{
1339 char *header[] = { "TX Packets", "TX Bytes", "TX Drops", "RX Packets", "RX Bytes", "Rx Drops" };
1340 uint64_t tcnt = 0;
1341
1342 switch (i) {
1343 case 0:
1344 tcnt = s->node_stats.tx_packets;
1345 break;
1346 case 1:
1347 tcnt = s->node_stats.tx_bytes;
1348 break;
1349 case 2:
1350 tcnt = s->tx_dropped;
1351 break;
1352 case 3:
1353 tcnt = s->node_stats.rx_packets;
1354 break;
1355 case 4:
1356 tcnt = s->node_stats.rx_bytes;
1357 break;
1358 case 5:
1359 tcnt = s->node_stats.rx_dropped;
1360 break;
1361 default:
1362 i = 6;
1363 break;
1364 }
1365
1366 return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
1367}
1368
1369/*
1370 * nss_stats_gre_redir_read()
1371 * READ gre_redir tunnel stats.
1372 */
1373static ssize_t nss_stats_gre_redir_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1374{
1375 struct nss_stats_data *data = fp->private_data;
1376 ssize_t bytes_read = 0;
1377 struct nss_gre_redir_tunnel_stats stats;
1378 size_t bytes;
1379 char line[80];
1380 int start, end;
1381 int index = 0;
1382
1383 if (data) {
1384 index = data->index;
1385 }
1386
1387 /*
1388 * If we are done accomodating all the GRE_REDIR tunnels.
1389 */
1390 if (index >= NSS_GRE_REDIR_MAX_INTERFACES) {
1391 return 0;
1392 }
1393
1394 for (; index < NSS_GRE_REDIR_MAX_INTERFACES; index++) {
1395 bool isthere;
1396
1397 /*
1398 * If gre_redir tunnel does not exists, then isthere will be false.
1399 */
1400 isthere = nss_gre_redir_get_stats(index, &stats);
1401 if (!isthere) {
1402 continue;
1403 }
1404
1405 bytes = snprintf(line, sizeof(line), "\nTunnel if_num: %2d\n", stats.if_num);
1406 if ((bytes_read + bytes) > sz) {
1407 break;
1408 }
1409
1410 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1411 bytes_read = -EFAULT;
1412 goto fail;
1413 }
1414 bytes_read += bytes;
1415 start = 0;
1416 end = 6;
1417 while (bytes_read < sz && start < end) {
1418 bytes = nss_stats_gre_redir(line, sizeof(line), start, &stats);
1419
1420 if ((bytes_read + bytes) > sz)
1421 break;
1422
1423 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1424 bytes_read = -EFAULT;
1425 goto fail;
1426 }
1427
1428 bytes_read += bytes;
1429 start++;
1430 }
1431 }
1432
1433 if (bytes_read > 0) {
1434 *ppos = bytes_read;
1435 }
1436
1437 if (data) {
1438 data->index = index;
1439 }
1440
1441fail:
1442 return bytes_read;
1443}
1444
1445/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001446 * nss_stats_open()
1447 */
1448static int nss_stats_open(struct inode *inode, struct file *filp)
1449{
1450 struct nss_stats_data *data = NULL;
1451
1452 data = kzalloc(sizeof(struct nss_stats_data), GFP_KERNEL);
1453 if (!data) {
1454 return -ENOMEM;
1455 }
1456 memset(data, 0, sizeof (struct nss_stats_data));
1457 data->if_num = NSS_DYNAMIC_IF_START;
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301458 data->index = 0;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001459 filp->private_data = data;
1460
1461 return 0;
1462}
1463
1464/*
1465 * nss_stats_release()
1466 */
1467static int nss_stats_release(struct inode *inode, struct file *filp)
1468{
1469 struct nss_stats_data *data = filp->private_data;
1470
1471 if (data) {
1472 kfree(data);
1473 }
1474
1475 return 0;
1476}
1477
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301478#define NSS_STATS_DECLARE_FILE_OPERATIONS(name) \
1479static const struct file_operations nss_stats_##name##_ops = { \
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001480 .open = nss_stats_open, \
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301481 .read = nss_stats_##name##_read, \
1482 .llseek = generic_file_llseek, \
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001483 .release = nss_stats_release, \
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301484};
1485
1486/*
1487 * nss_ipv4_stats_ops
1488 */
1489NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4)
1490
1491/*
Selin Dag6d9b0c12014-11-04 18:27:21 -08001492 * ipv4_reasm_stats_ops
1493 */
1494NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4_reasm)
1495
1496/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301497 * ipv6_stats_ops
1498 */
1499NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6)
1500
1501/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301502 * n2h_stats_ops
1503 */
1504NSS_STATS_DECLARE_FILE_OPERATIONS(n2h)
Thomas Wuc3e382c2014-10-29 15:35:13 -07001505
1506/*
1507 * lso_rx_stats_ops
1508 */
1509NSS_STATS_DECLARE_FILE_OPERATIONS(lso_rx)
1510
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301511/*
1512 * drv_stats_ops
1513 */
1514NSS_STATS_DECLARE_FILE_OPERATIONS(drv)
1515
1516/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301517 * pppoe_stats_ops
1518 */
1519NSS_STATS_DECLARE_FILE_OPERATIONS(pppoe)
1520
1521/*
1522 * gmac_stats_ops
1523 */
1524NSS_STATS_DECLARE_FILE_OPERATIONS(gmac)
1525
1526/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001527 * capwap_stats_ops
1528 */
1529NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_encap)
1530NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_decap)
1531
1532/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301533 * eth_rx_stats_ops
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301534 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301535NSS_STATS_DECLARE_FILE_OPERATIONS(eth_rx)
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301536
1537/*
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301538 * gre_redir_ops
1539 */
1540NSS_STATS_DECLARE_FILE_OPERATIONS(gre_redir)
1541
1542/*
Ankit Dhanuka14999992014-11-12 15:35:11 +05301543 * sjack_stats_ops
1544 */
1545NSS_STATS_DECLARE_FILE_OPERATIONS(sjack)
1546
1547/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301548 * nss_stats_init()
1549 * Enable NSS statistics
1550 */
1551void nss_stats_init(void)
1552{
1553 /*
1554 * NSS driver entry
1555 */
1556 nss_top_main.top_dentry = debugfs_create_dir("qca-nss-drv", NULL);
1557 if (unlikely(nss_top_main.top_dentry == NULL)) {
1558 nss_warning("Failed to create qca-nss-drv directory in debugfs");
1559
1560 /*
1561 * Non availability of debugfs directory is not a catastrophy
1562 * We can still go ahead with other initialization
1563 */
1564 return;
1565 }
1566
1567 nss_top_main.stats_dentry = debugfs_create_dir("stats", nss_top_main.top_dentry);
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05301568 if (unlikely(nss_top_main.stats_dentry == NULL)) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301569 nss_warning("Failed to create qca-nss-drv directory in debugfs");
1570
1571 /*
1572 * Non availability of debugfs directory is not a catastrophy
1573 * We can still go ahead with rest of initialization
1574 */
1575 return;
1576 }
1577
1578 /*
1579 * Create files to obtain statistics
1580 */
1581
1582 /*
1583 * ipv4_stats
1584 */
1585 nss_top_main.ipv4_dentry = debugfs_create_file("ipv4", 0400,
1586 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv4_ops);
1587 if (unlikely(nss_top_main.ipv4_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05301588 nss_warning("Failed to create qca-nss-drv/stats/ipv4 file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301589 return;
1590 }
1591
1592 /*
Selin Dag6d9b0c12014-11-04 18:27:21 -08001593 * ipv4_reasm_stats
1594 */
1595 nss_top_main.ipv4_reasm_dentry = debugfs_create_file("ipv4_reasm", 0400,
1596 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv4_reasm_ops);
1597 if (unlikely(nss_top_main.ipv4_reasm_dentry == NULL)) {
1598 nss_warning("Failed to create qca-nss-drv/stats/ipv4_reasm file in debugfs");
1599 return;
1600 }
1601
1602 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301603 * ipv6_stats
1604 */
1605 nss_top_main.ipv6_dentry = debugfs_create_file("ipv6", 0400,
1606 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv6_ops);
1607 if (unlikely(nss_top_main.ipv6_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05301608 nss_warning("Failed to create qca-nss-drv/stats/ipv6 file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301609 return;
1610 }
1611
1612 /*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301613 * ipv6_stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301614 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301615 nss_top_main.eth_rx_dentry = debugfs_create_file("eth_rx", 0400,
1616 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_eth_rx_ops);
1617 if (unlikely(nss_top_main.eth_rx_dentry == NULL)) {
1618 nss_warning("Failed to create qca-nss-drv/stats/eth_rx file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301619 return;
1620 }
1621
1622 /*
1623 * n2h_stats
1624 */
1625 nss_top_main.n2h_dentry = debugfs_create_file("n2h", 0400,
1626 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_n2h_ops);
1627 if (unlikely(nss_top_main.n2h_dentry == NULL)) {
1628 nss_warning("Failed to create qca-nss-drv/stats/n2h directory in debugfs");
1629 return;
1630 }
1631
1632 /*
Thomas Wuc3e382c2014-10-29 15:35:13 -07001633 * lso_rx_stats
1634 */
1635 nss_top_main.lso_rx_dentry = debugfs_create_file("lso_rx", 0400,
1636 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_lso_rx_ops);
1637 if (unlikely(nss_top_main.lso_rx_dentry == NULL)) {
1638 nss_warning("Failed to create qca-nss-drv/stats/lso_rx file in debugfs");
1639 return;
1640 }
1641
1642 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301643 * drv_stats
1644 */
1645 nss_top_main.drv_dentry = debugfs_create_file("drv", 0400,
1646 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_drv_ops);
1647 if (unlikely(nss_top_main.drv_dentry == NULL)) {
1648 nss_warning("Failed to create qca-nss-drv/stats/drv directory in debugfs");
1649 return;
1650 }
1651
1652 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301653 * pppoe_stats
1654 */
1655 nss_top_main.pppoe_dentry = debugfs_create_file("pppoe", 0400,
1656 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_pppoe_ops);
1657 if (unlikely(nss_top_main.pppoe_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05301658 nss_warning("Failed to create qca-nss-drv/stats/pppoe file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301659 return;
1660 }
1661
1662 /*
1663 * gmac_stats
1664 */
1665 nss_top_main.gmac_dentry = debugfs_create_file("gmac", 0400,
1666 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gmac_ops);
1667 if (unlikely(nss_top_main.gmac_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05301668 nss_warning("Failed to create qca-nss-drv/stats/gmac file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301669 return;
1670 }
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001671
1672 /*
1673 * CAPWAP stats.
1674 */
1675 nss_top_main.capwap_encap_dentry = debugfs_create_file("capwap_encap", 0400,
1676 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_capwap_encap_ops);
1677 if (unlikely(nss_top_main.capwap_encap_dentry == NULL)) {
1678 nss_warning("Failed to create qca-nss-drv/stats/capwap_encap file in debugfs");
1679 return;
1680 }
1681
1682 nss_top_main.capwap_decap_dentry = debugfs_create_file("capwap_decap", 0400,
1683 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_capwap_decap_ops);
1684 if (unlikely(nss_top_main.capwap_decap_dentry == NULL)) {
1685 nss_warning("Failed to create qca-nss-drv/stats/capwap_decap file in debugfs");
1686 return;
1687 }
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301688
1689 /*
1690 * GRE_REDIR stats
1691 */
1692 nss_top_main.gre_redir_dentry = debugfs_create_file("gre_redir", 0400,
Ankit Dhanuka14999992014-11-12 15:35:11 +05301693 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gre_redir_ops);
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301694 if (unlikely(nss_top_main.gre_redir_dentry == NULL)) {
1695 nss_warning("Failed to create qca-nss-drv/stats/gre_redir file in debugfs");
1696 return;
1697 }
Ankit Dhanuka14999992014-11-12 15:35:11 +05301698
1699 /*
1700 * SJACK stats
1701 */
1702 nss_top_main.sjack_dentry = debugfs_create_file("sjack", 0400,
1703 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_sjack_ops);
1704 if (unlikely(nss_top_main.sjack_dentry == NULL)) {
1705 nss_warning("Failed to create qca-nss-drv/stats/sjack file in debugfs");
1706 return;
1707 }
Saurabh Misra96998db2014-07-10 12:15:48 -07001708
1709 nss_log_init();
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301710}
1711
1712
1713/*
1714 * nss_stats_clean()
1715 * Cleanup NSS statistics files
1716 */
1717void nss_stats_clean(void)
1718{
1719 /*
1720 * Remove debugfs tree
1721 */
1722 if (likely(nss_top_main.top_dentry != NULL)) {
1723 debugfs_remove_recursive(nss_top_main.top_dentry);
1724 }
1725}