blob: 591294ef529a27939cb271be6e9f219b83190b5b [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
Sundarajan Srinivasancd1631b2015-06-18 01:23:30 -070037extern int32_t nss_tx_rx_virt_if_copy_stats(int32_t if_num, int i, char *line);
38
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +053039uint64_t stats_shadow_pppoe_except[NSS_PPPOE_NUM_SESSION_PER_INTERFACE][NSS_PPPOE_EXCEPTION_EVENT_MAX];
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053040
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053041/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -070042 * Private data for every file descriptor
43 */
44struct nss_stats_data {
Sundarajan Srinivasan273d9002015-03-03 15:43:16 -080045 uint32_t if_num; /**< Interface number for stats */
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +053046 uint32_t index; /**< Index for GRE_REDIR stats */
Saurabh Misra09dddeb2014-09-30 16:38:07 -070047};
48
49/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053050 * Statistics structures
51 */
52
53/*
54 * nss_stats_str_ipv4
55 * IPv4 stats strings
56 */
57static int8_t *nss_stats_str_ipv4[NSS_STATS_IPV4_MAX] = {
58 "rx_pkts",
59 "rx_bytes",
60 "tx_pkts",
61 "tx_bytes",
62 "create_requests",
63 "create_collisions",
64 "create_invalid_interface",
65 "destroy_requests",
66 "destroy_misses",
67 "hash_hits",
68 "hash_reorders",
69 "flushes",
Selin Dag60ea2b22014-11-05 09:36:22 -080070 "evictions",
Kiran Kumar C. S. K12998002014-09-04 17:09:03 +053071 "fragmentations",
72 "mc_create_requests",
73 "mc_update_requests",
74 "mc_create_invalid_interface",
75 "mc_destroy_requests",
76 "mc_destroy_misses",
77 "mc_flushes",
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053078};
79
80/*
Selin Dag6d9b0c12014-11-04 18:27:21 -080081 * nss_stats_str_ipv4_reasm
82 * IPv4 reassembly stats strings
83 */
84static int8_t *nss_stats_str_ipv4_reasm[NSS_STATS_IPV4_REASM_MAX] = {
85 "evictions",
86 "alloc_fails",
87 "timeouts",
88};
89
90/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053091 * nss_stats_str_ipv6
92 * IPv6 stats strings
93 */
94static int8_t *nss_stats_str_ipv6[NSS_STATS_IPV6_MAX] = {
95 "rx_pkts",
96 "rx_bytes",
97 "tx_pkts",
98 "tx_bytes",
99 "create_requests",
100 "create_collisions",
101 "create_invalid_interface",
102 "destroy_requests",
103 "destroy_misses",
104 "hash_hits",
105 "hash_reorders",
106 "flushes",
107 "evictions",
Selin Dag5d68caa2015-05-12 13:23:33 -0700108 "fragmentations",
109 "frag_fails",
Kiran Kumar C. S. K12998002014-09-04 17:09:03 +0530110 "mc_create_requests",
111 "mc_update_requests",
112 "mc_create_invalid_interface",
113 "mc_destroy_requests",
114 "mc_destroy_misses",
115 "mc_flushes",
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530116};
117
118/*
Selin Dag60a2f5b2015-06-29 14:39:49 -0700119 * nss_stats_str_ipv6_reasm
120 * IPv6 reassembly stats strings
121 */
122static int8_t *nss_stats_str_ipv6_reasm[NSS_STATS_IPV6_REASM_MAX] = {
123 "alloc_fails",
124 "timeouts",
125 "discards",
126};
127
128/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530129 * nss_stats_str_n2h
130 * N2H stats strings
131 */
132static int8_t *nss_stats_str_n2h[NSS_STATS_N2H_MAX] = {
133 "queue_dropped",
134 "ticks",
135 "worst_ticks",
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700136 "iterations",
Thomas Wu3fd8dd72014-06-11 15:57:05 -0700137 "pbuf_ocm_alloc_fails",
138 "pbuf_ocm_free_count",
139 "pbuf_ocm_total_count",
140 "pbuf_default_alloc_fails",
141 "pbuf_default_free_count",
142 "pbuf_default_total_count",
Sakthi Vignesh Radhakrishnan2a8ee962014-11-22 13:35:38 -0800143 "payload_fails",
Thomas Wu53679842015-01-22 13:37:35 -0800144 "payload_free_count",
Sakthi Vignesh Radhakrishnan2a8ee962014-11-22 13:35:38 -0800145 "h2n_control_packets",
146 "h2n_control_bytes",
147 "n2h_control_packets",
148 "n2h_control_bytes",
149 "h2n_data_packets",
150 "h2n_data_bytes",
151 "n2h_data_packets",
152 "n2h_data_bytes",
Saurabh Misra71034db2015-06-04 16:18:38 -0700153 "n2h_tot_payloads",
Guojun Jin85dfa7b2015-09-02 15:13:56 -0700154 "n2h_data_interface_invalid",
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530155};
156
157/*
Thomas Wuc3e382c2014-10-29 15:35:13 -0700158 * nss_stats_str_lso_rx
159 * LSO_RX stats strings
160 */
161static int8_t *nss_stats_str_lso_rx[NSS_STATS_LSO_RX_MAX] = {
162 "tx_dropped",
163 "dropped",
164 "pbuf_alloc_fail",
165 "pbuf_reference_fail"
166};
167
168/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530169 * nss_stats_str_drv
170 * Host driver stats strings
171 */
172static int8_t *nss_stats_str_drv[NSS_STATS_DRV_MAX] = {
173 "nbuf_alloc_errors",
174 "tx_queue_full[0]",
175 "tx_queue_full[1]",
176 "tx_buffers_empty",
177 "tx_buffers_pkt",
178 "tx_buffers_cmd",
179 "tx_buffers_crypto",
180 "rx_buffers_empty",
181 "rx_buffers_pkt",
182 "rx_buffers_cmd_resp",
183 "rx_buffers_status_sync",
184 "rx_buffers_crypto",
Thomas Wu0acd8162014-12-07 15:43:39 -0800185 "rx_buffers_virtual",
186 "tx_skb_simple",
187 "tx_skb_nr_frags",
188 "tx_skb_fraglist",
189 "rx_skb_simple",
190 "rx_skb_nr_frags",
191 "rx_skb_fraglist",
Sundarajan Srinivasan6e0366b2015-01-20 12:10:42 -0800192 "rx_bad_desciptor",
Thomas Wu1fbf5212015-06-04 14:38:40 -0700193 "nss_skb_count",
194 "rx_chain_seg_processed",
195 "rx_frag_seg_processed"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530196};
197
198/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530199 * nss_stats_str_pppoe
200 * PPPoE stats strings
201 */
202static int8_t *nss_stats_str_pppoe[NSS_STATS_PPPOE_MAX] = {
203 "create_requests",
204 "create_failures",
205 "destroy_requests",
206 "destroy_misses"
207};
208
209/*
210 * nss_stats_str_gmac
211 * GMAC stats strings
212 */
213static int8_t *nss_stats_str_gmac[NSS_STATS_GMAC_MAX] = {
214 "ticks",
215 "worst_ticks",
216 "iterations"
217};
218
219/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530220 * nss_stats_str_node
221 * Interface stats strings per node
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530222 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530223static int8_t *nss_stats_str_node[NSS_STATS_NODE_MAX] = {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530224 "rx_packets",
225 "rx_bytes",
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530226 "rx_dropped",
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530227 "tx_packets",
228 "tx_bytes"
229};
230
231/*
Murat Sezgin99dab642014-08-28 14:40:34 -0700232 * nss_stats_str_eth_rx
233 * eth_rx stats strings
234 */
235static int8_t *nss_stats_str_eth_rx[NSS_STATS_ETH_RX_MAX] = {
236 "ticks",
237 "worst_ticks",
238 "iterations"
239};
240
241/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530242 * nss_stats_str_if_exception_unknown
243 * Interface stats strings for unknown exceptions
244 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530245static int8_t *nss_stats_str_if_exception_eth_rx[NSS_EXCEPTION_EVENT_ETH_RX_MAX] = {
Selin Dag2e8e48c2015-02-20 15:51:55 -0800246 "UNKNOWN_L3_PROTOCOL",
247 "ETH_HDR_MISSING",
248 "VLAN_MISSING"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530249};
250
251/*
252 * nss_stats_str_if_exception_ipv4
253 * Interface stats strings for ipv4 exceptions
254 */
255static int8_t *nss_stats_str_if_exception_ipv4[NSS_EXCEPTION_EVENT_IPV4_MAX] = {
256 "IPV4_ICMP_HEADER_INCOMPLETE",
257 "IPV4_ICMP_UNHANDLED_TYPE",
258 "IPV4_ICMP_IPV4_HEADER_INCOMPLETE",
259 "IPV4_ICMP_IPV4_UDP_HEADER_INCOMPLETE",
260 "IPV4_ICMP_IPV4_TCP_HEADER_INCOMPLETE",
261 "IPV4_ICMP_IPV4_UNKNOWN_PROTOCOL",
262 "IPV4_ICMP_NO_ICME",
263 "IPV4_ICMP_FLUSH_TO_HOST",
264 "IPV4_TCP_HEADER_INCOMPLETE",
265 "IPV4_TCP_NO_ICME",
266 "IPV4_TCP_IP_OPTION",
267 "IPV4_TCP_IP_FRAGMENT",
268 "IPV4_TCP_SMALL_TTL",
269 "IPV4_TCP_NEEDS_FRAGMENTATION",
270 "IPV4_TCP_FLAGS",
271 "IPV4_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
272 "IPV4_TCP_SMALL_DATA_OFFS",
273 "IPV4_TCP_BAD_SACK",
274 "IPV4_TCP_BIG_DATA_OFFS",
275 "IPV4_TCP_SEQ_BEFORE_LEFT_EDGE",
276 "IPV4_TCP_ACK_EXCEEDS_RIGHT_EDGE",
277 "IPV4_TCP_ACK_BEFORE_LEFT_EDGE",
278 "IPV4_UDP_HEADER_INCOMPLETE",
279 "IPV4_UDP_NO_ICME",
280 "IPV4_UDP_IP_OPTION",
281 "IPV4_UDP_IP_FRAGMENT",
282 "IPV4_UDP_SMALL_TTL",
283 "IPV4_UDP_NEEDS_FRAGMENTATION",
284 "IPV4_WRONG_TARGET_MAC",
285 "IPV4_HEADER_INCOMPLETE",
286 "IPV4_BAD_TOTAL_LENGTH",
287 "IPV4_BAD_CHECKSUM",
288 "IPV4_NON_INITIAL_FRAGMENT",
289 "IPV4_DATAGRAM_INCOMPLETE",
290 "IPV4_OPTIONS_INCOMPLETE",
Radha krishna Simha Jiguru59a1a1c2014-01-27 18:29:40 +0530291 "IPV4_UNKNOWN_PROTOCOL",
292 "IPV4_ESP_HEADER_INCOMPLETE",
293 "IPV4_ESP_NO_ICME",
294 "IPV4_ESP_IP_OPTION",
295 "IPV4_ESP_IP_FRAGMENT",
296 "IPV4_ESP_SMALL_TTL",
297 "IPV4_ESP_NEEDS_FRAGMENTATION",
298 "IPV4_INGRESS_VID_MISMATCH",
Thomas Wu8d6f4b22014-06-09 14:46:18 -0700299 "IPV4_INGRESS_VID_MISSING",
Radha krishna Simha Jiguru59a1a1c2014-01-27 18:29:40 +0530300 "IPV4_6RD_NO_ICME",
301 "IPV4_6RD_IP_OPTION",
302 "IPV4_6RD_IP_FRAGMENT",
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700303 "IPV4_6RD_NEEDS_FRAGMENTATION",
304 "IPV4_DSCP_MARKING_MISMATCH",
Murat Sezgin7c5956a2014-05-12 09:59:51 -0700305 "IPV4_VLAN_MARKING_MISMATCH",
Thomas Wu8d6f4b22014-06-09 14:46:18 -0700306 "IPV4_INTERFACE_MISMATCH",
Radha krishna Simha Jiguru00cfe562014-10-21 16:22:12 +0530307 "IPV4_GRE_HEADER_INCOMPLETE",
308 "IPV4_GRE_NO_ICME",
309 "IPV4_GRE_IP_OPTION",
310 "IPV4_GRE_IP_FRAGMENT",
311 "IPV4_GRE_SMALL_TTL",
312 "IPV4_GRE_NEEDS_FRAGMENTATION",
Selin Dag60ea2b22014-11-05 09:36:22 -0800313 "IPV4_FRAG_DF_SET",
314 "IPV4_FRAG_FAIL",
Saurabh Misra5b07cc02015-01-15 14:20:58 -0800315 "IPV4_DESTROY",
316 "IPV4_ICMP_IPV4_UDPLITE_HEADER_INCOMPLETE",
317 "IPV4_UDPLITE_HEADER_INCOMPLETE",
318 "IPV4_UDPLITE_NO_ICME",
319 "IPV4_UDPLITE_IP_OPTION",
320 "IPV4_UDPLITE_IP_FRAGMENT",
321 "IPV4_UDPLITE_SMALL_TTL",
Kiran Kumar C. S. K12998002014-09-04 17:09:03 +0530322 "IPV4_UDPLITE_NEEDS_FRAGMENTATION",
323 "IPV4_MC_UDP_NO_ICME",
324 "IPV4_MC_MEM_ALLOC_FAILURE",
325 "IPV4_MC_UPDATE_FAILURE",
326 "IPV4_MC_PBUF_ALLOC_FAILURE"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530327};
328
329/*
330 * nss_stats_str_if_exception_ipv6
331 * Interface stats strings for ipv6 exceptions
332 */
333static int8_t *nss_stats_str_if_exception_ipv6[NSS_EXCEPTION_EVENT_IPV6_MAX] = {
334 "IPV6_ICMP_HEADER_INCOMPLETE",
335 "IPV6_ICMP_UNHANDLED_TYPE",
336 "IPV6_ICMP_IPV6_HEADER_INCOMPLETE",
337 "IPV6_ICMP_IPV6_UDP_HEADER_INCOMPLETE",
338 "IPV6_ICMP_IPV6_TCP_HEADER_INCOMPLETE",
339 "IPV6_ICMP_IPV6_UNKNOWN_PROTOCOL",
340 "IPV6_ICMP_NO_ICME",
341 "IPV6_ICMP_FLUSH_TO_HOST",
342 "IPV6_TCP_HEADER_INCOMPLETE",
343 "IPV6_TCP_NO_ICME",
344 "IPV6_TCP_SMALL_HOP_LIMIT",
345 "IPV6_TCP_NEEDS_FRAGMENTATION",
346 "IPV6_TCP_FLAGS",
347 "IPV6_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
348 "IPV6_TCP_SMALL_DATA_OFFS",
349 "IPV6_TCP_BAD_SACK",
350 "IPV6_TCP_BIG_DATA_OFFS",
351 "IPV6_TCP_SEQ_BEFORE_LEFT_EDGE",
352 "IPV6_TCP_ACK_EXCEEDS_RIGHT_EDGE",
353 "IPV6_TCP_ACK_BEFORE_LEFT_EDGE",
354 "IPV6_UDP_HEADER_INCOMPLETE",
355 "IPV6_UDP_NO_ICME",
356 "IPV6_UDP_SMALL_HOP_LIMIT",
357 "IPV6_UDP_NEEDS_FRAGMENTATION",
358 "IPV6_WRONG_TARGET_MAC",
359 "IPV6_HEADER_INCOMPLETE",
Radha krishna Simha Jiguru59a1a1c2014-01-27 18:29:40 +0530360 "IPV6_UNKNOWN_PROTOCOL",
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700361 "IPV6_INGRESS_VID_MISMATCH",
Thomas Wu8d6f4b22014-06-09 14:46:18 -0700362 "IPV6_INGRESS_VID_MISSING",
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700363 "IPV6_DSCP_MARKING_MISMATCH",
364 "IPV6_VLAN_MARKING_MISMATCH",
Thomas Wu8d6f4b22014-06-09 14:46:18 -0700365 "IPV6_INTERFACE_MISMATCH",
Saurabh Misra5b07cc02015-01-15 14:20:58 -0800366 "IPV6_GRE_NO_ICME",
367 "IPV6_GRE_NEEDS_FRAGMENTATION",
368 "IPV6_GRE_SMALL_HOP_LIMIT",
369 "IPV6_DESTROY",
370 "IPV6_ICMP_IPV6_UDPLITE_HEADER_INCOMPLETE",
371 "IPV6_UDPLITE_HEADER_INCOMPLETE",
372 "IPV6_UDPLITE_NO_ICME",
373 "IPV6_UDPLITE_SMALL_HOP_LIMIT",
Kiran Kumar C. S. K12998002014-09-04 17:09:03 +0530374 "IPV6_UDPLITE_NEEDS_FRAGMENTATION",
375 "IPV6_MC_UDP_NO_ICME",
376 "IPV6_MC_MEM_ALLOC_FAILURE",
377 "IPV6_MC_UPDATE_FAILURE",
378 "IPV6_MC_PBUF_ALLOC_FAILURE"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530379};
380
381/*
382 * nss_stats_str_if_exception_pppoe
383 * Interface stats strings for PPPoE exceptions
384 */
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +0530385static int8_t *nss_stats_str_if_exception_pppoe[NSS_PPPOE_EXCEPTION_EVENT_MAX] = {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530386 "PPPOE_WRONG_VERSION_OR_TYPE",
387 "PPPOE_WRONG_CODE",
388 "PPPOE_HEADER_INCOMPLETE",
Murat Sezgin7c5956a2014-05-12 09:59:51 -0700389 "PPPOE_UNSUPPORTED_PPP_PROTOCOL",
390 "PPPOE_INTERFACE_MISMATCH"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530391};
392
393/*
Bharath M Kumarcc666e92014-12-24 19:17:28 +0530394 * nss_stats_str_wifi
395 * Wifi statistics strings
396 */
397static int8_t *nss_stats_str_wifi[NSS_STATS_WIFI_MAX] = {
398 "RX_PACKETS",
399 "RX_DROPPED",
400 "TX_PACKETS",
401 "TX_DROPPED",
402 "TX_TRANSMIT_COMPLETED",
403 "TX_MGMT_RECEIVED",
404 "TX_MGMT_TRANSMITTED",
405 "TX_MGMT_DROPPED",
406 "TX_MGMT_COMPLETED",
407 "TX_INV_PEER_ENQ_CNT",
408 "RX_INV_PEER_RCV_CNT",
409 "RX_PN_CHECK_FAILED",
410 "RX_PKTS_DELIVERD",
411};
412
413/*
ratheesh kannoth7af985d2015-06-24 15:08:40 +0530414 * nss_stats_str_l2tpv2_session_stats
415 * l2tpv2 statistics strings for nss session stats
416 */
417static int8_t *nss_stats_str_l2tpv2_session_debug_stats[NSS_STATS_L2TPV2_SESSION_MAX] = {
418 "RX_PPP_LCP_PKTS",
419 "RX_EXP_PKTS",
420 "ENCAP_PBUF_ALLOC_FAIL",
421 "DECAP_PBUF_ALLOC_FAIL"
422};
423
424/*
Shyam Sunder66e889d2015-11-02 15:31:20 +0530425 * nss_stats_str_ppt_session_stats
426 * PPTP statistics strings for nss session stats
427 */
428static int8_t *nss_stats_str_pptp_session_debug_stats[NSS_STATS_PPTP_SESSION_MAX] = {
429 "RX_DROPPED",
430 "TX_DROPPED",
431 "ENCAP_PBUF_ALLOC_FAIL",
432 "DECAP_PBUF_ALLOC_FAIL"
433};
434
435/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530436 * nss_stats_ipv4_read()
437 * Read IPV4 stats
438 */
439static ssize_t nss_stats_ipv4_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
440{
441 int32_t i;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530442 /*
443 * max output lines = #stats + start tag line + end tag line + three blank lines
444 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530445 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 +0530446 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
447 size_t size_wr = 0;
448 ssize_t bytes_read = 0;
449 uint64_t *stats_shadow;
450
451 char *lbuf = kzalloc(size_al, GFP_KERNEL);
452 if (unlikely(lbuf == NULL)) {
453 nss_warning("Could not allocate memory for local statistics buffer");
454 return 0;
455 }
456
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530457 /*
458 * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
459 */
460 stats_shadow = kzalloc(NSS_EXCEPTION_EVENT_IPV4_MAX * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530461 if (unlikely(stats_shadow == NULL)) {
462 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530463 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530464 return 0;
465 }
466
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530467 size_wr = scnprintf(lbuf, size_al, "ipv4 stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530468
469 /*
470 * Common node stats
471 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530472 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530473 spin_lock_bh(&nss_top_main.stats_lock);
474 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
475 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV4_RX_INTERFACE][i];
476 }
477
478 spin_unlock_bh(&nss_top_main.stats_lock);
479
480 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
481 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
482 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
483 }
484
485 /*
486 * IPv4 node stats
487 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530488 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530489
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530490 spin_lock_bh(&nss_top_main.stats_lock);
491 for (i = 0; (i < NSS_STATS_IPV4_MAX); i++) {
492 stats_shadow[i] = nss_top_main.stats_ipv4[i];
493 }
494
495 spin_unlock_bh(&nss_top_main.stats_lock);
496
497 for (i = 0; (i < NSS_STATS_IPV4_MAX); i++) {
498 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
499 "%s = %llu\n", nss_stats_str_ipv4[i], stats_shadow[i]);
500 }
501
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530502 /*
503 * Exception stats
504 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530505 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530506
507 spin_lock_bh(&nss_top_main.stats_lock);
508 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV4_MAX); i++) {
509 stats_shadow[i] = nss_top_main.stats_if_exception_ipv4[i];
510 }
511
512 spin_unlock_bh(&nss_top_main.stats_lock);
513
514 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV4_MAX); i++) {
515 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
516 "%s = %llu\n", nss_stats_str_if_exception_ipv4[i], stats_shadow[i]);
517 }
518
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530519 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530520 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
521 kfree(lbuf);
522 kfree(stats_shadow);
523
524 return bytes_read;
525}
526
527/*
Selin Dag6d9b0c12014-11-04 18:27:21 -0800528 * nss_stats_ipv4_reasm_read()
529 * Read IPV4 reassembly stats
530 */
531static ssize_t nss_stats_ipv4_reasm_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
532{
533 int32_t i;
534 /*
535 * max output lines = #stats + start tag line + end tag line + three blank lines
536 */
537 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV4_REASM_MAX + 3) + 5;
538 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
539 size_t size_wr = 0;
540 ssize_t bytes_read = 0;
541 uint64_t *stats_shadow;
542
543 char *lbuf = kzalloc(size_al, GFP_KERNEL);
544 if (unlikely(lbuf == NULL)) {
545 nss_warning("Could not allocate memory for local statistics buffer");
546 return 0;
547 }
548
549 stats_shadow = kzalloc(NSS_STATS_IPV4_REASM_MAX * 8, GFP_KERNEL);
550 if (unlikely(stats_shadow == NULL)) {
551 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530552 kfree(lbuf);
Selin Dag6d9b0c12014-11-04 18:27:21 -0800553 return 0;
554 }
555
556 size_wr = scnprintf(lbuf, size_al, "ipv4 reasm stats start:\n\n");
557
558 /*
559 * Common node stats
560 */
561 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
562 spin_lock_bh(&nss_top_main.stats_lock);
563 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
564 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV4_REASM_INTERFACE][i];
565 }
566
567 spin_unlock_bh(&nss_top_main.stats_lock);
568
569 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
570 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
571 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
572 }
573
574 /*
575 * IPv4 reasm node stats
576 */
577 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 reasm node stats:\n\n");
578
579 spin_lock_bh(&nss_top_main.stats_lock);
580 for (i = 0; (i < NSS_STATS_IPV4_REASM_MAX); i++) {
581 stats_shadow[i] = nss_top_main.stats_ipv4_reasm[i];
582 }
583
584 spin_unlock_bh(&nss_top_main.stats_lock);
585
586 for (i = 0; (i < NSS_STATS_IPV4_REASM_MAX); i++) {
587 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
588 "%s = %llu\n", nss_stats_str_ipv4_reasm[i], stats_shadow[i]);
589 }
590
591 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 reasm stats end\n\n");
592 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
593 kfree(lbuf);
594 kfree(stats_shadow);
595
596 return bytes_read;
597}
598
599/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530600 * nss_stats_ipv6_read()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530601 * Read IPV6 stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530602 */
603static ssize_t nss_stats_ipv6_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
604{
605 int32_t i;
606
607 /*
608 * max output lines = #stats + start tag line + end tag line + three blank lines
609 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530610 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 +0530611 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
612 size_t size_wr = 0;
613 ssize_t bytes_read = 0;
614 uint64_t *stats_shadow;
615
616 char *lbuf = kzalloc(size_al, GFP_KERNEL);
617 if (unlikely(lbuf == NULL)) {
618 nss_warning("Could not allocate memory for local statistics buffer");
619 return 0;
620 }
621
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530622 /*
623 * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
624 */
625 stats_shadow = kzalloc(NSS_EXCEPTION_EVENT_IPV6_MAX * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530626 if (unlikely(stats_shadow == NULL)) {
627 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530628 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530629 return 0;
630 }
631
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530632 size_wr = scnprintf(lbuf, size_al, "ipv6 stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530633
634 /*
635 * Common node stats
636 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530637 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530638 spin_lock_bh(&nss_top_main.stats_lock);
639 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
640 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV6_RX_INTERFACE][i];
641 }
642
643 spin_unlock_bh(&nss_top_main.stats_lock);
644
645 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
646 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
647 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
648 }
649
650 /*
651 * IPv6 node stats
652 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530653 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530654
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530655 spin_lock_bh(&nss_top_main.stats_lock);
656 for (i = 0; (i < NSS_STATS_IPV6_MAX); i++) {
657 stats_shadow[i] = nss_top_main.stats_ipv6[i];
658 }
659
660 spin_unlock_bh(&nss_top_main.stats_lock);
661
662 for (i = 0; (i < NSS_STATS_IPV6_MAX); i++) {
663 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
664 "%s = %llu\n", nss_stats_str_ipv6[i], stats_shadow[i]);
665 }
666
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530667 /*
668 * Exception stats
669 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530670 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530671
672 spin_lock_bh(&nss_top_main.stats_lock);
673 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV6_MAX); i++) {
674 stats_shadow[i] = nss_top_main.stats_if_exception_ipv6[i];
675 }
676
677 spin_unlock_bh(&nss_top_main.stats_lock);
678
679 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV6_MAX); i++) {
680 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
681 "%s = %llu\n", nss_stats_str_if_exception_ipv6[i], stats_shadow[i]);
682 }
683
684 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\nipv6 stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530685 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
686 kfree(lbuf);
687 kfree(stats_shadow);
688
689 return bytes_read;
690}
691
692/*
Selin Dag60a2f5b2015-06-29 14:39:49 -0700693 * nss_stats_ipv6_reasm_read()
694 * Read IPV6 reassembly stats
695 */
696static ssize_t nss_stats_ipv6_reasm_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
697{
698 int32_t i;
699 /*
700 * max output lines = #stats + start tag line + end tag line + three blank lines
701 */
702 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV6_REASM_MAX + 3) + 5;
703 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
704 size_t size_wr = 0;
705 ssize_t bytes_read = 0;
706 uint64_t *stats_shadow;
707
708 char *lbuf = kzalloc(size_al, GFP_KERNEL);
709 if (unlikely(lbuf == NULL)) {
710 nss_warning("Could not allocate memory for local statistics buffer");
711 return 0;
712 }
713
714 stats_shadow = kzalloc(NSS_STATS_IPV6_REASM_MAX * 8, GFP_KERNEL);
715 if (unlikely(stats_shadow == NULL)) {
716 nss_warning("Could not allocate memory for local shadow buffer");
717 kfree(lbuf);
718 return 0;
719 }
720
721 size_wr = scnprintf(lbuf, size_al, "ipv6 reasm stats start:\n\n");
722
723 /*
724 * Common node stats
725 */
726 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
727 spin_lock_bh(&nss_top_main.stats_lock);
728 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
729 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV6_REASM_INTERFACE][i];
730 }
731
732 spin_unlock_bh(&nss_top_main.stats_lock);
733
734 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
735 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
736 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
737 }
738
739 /*
740 * Ipv6 reasm node stats
741 */
742 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 reasm node stats:\n\n");
743
744 spin_lock_bh(&nss_top_main.stats_lock);
745 for (i = 0; (i < NSS_STATS_IPV6_REASM_MAX); i++) {
746 stats_shadow[i] = nss_top_main.stats_ipv6_reasm[i];
747 }
748
749 spin_unlock_bh(&nss_top_main.stats_lock);
750
751 for (i = 0; (i < NSS_STATS_IPV6_REASM_MAX); i++) {
752 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
753 "%s = %llu\n", nss_stats_str_ipv6_reasm[i], stats_shadow[i]);
754 }
755
756 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 reasm stats end\n\n");
757 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
758 kfree(lbuf);
759 kfree(stats_shadow);
760
761 return bytes_read;
762}
763
764/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530765 * nss_stats_eth_rx_read()
766 * Read ETH_RX stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530767 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530768static 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 +0530769{
770 int32_t i;
771
772 /*
773 * max output lines = #stats + start tag line + end tag line + three blank lines
774 */
Murat Sezgin99dab642014-08-28 14:40:34 -0700775 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 +0530776 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
777 size_t size_wr = 0;
778 ssize_t bytes_read = 0;
779 uint64_t *stats_shadow;
780
781 char *lbuf = kzalloc(size_al, GFP_KERNEL);
782 if (unlikely(lbuf == NULL)) {
783 nss_warning("Could not allocate memory for local statistics buffer");
784 return 0;
785 }
786
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530787 /*
788 * Note: The assumption here is that we do not have more than 64 stats
789 */
790 stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530791 if (unlikely(stats_shadow == NULL)) {
792 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530793 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530794 return 0;
795 }
796
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530797 size_wr = scnprintf(lbuf, size_al,"eth_rx stats start:\n\n");
798
799 /*
800 * Common node stats
801 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530802 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530803 spin_lock_bh(&nss_top_main.stats_lock);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530804 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
805 stats_shadow[i] = nss_top_main.stats_node[NSS_ETH_RX_INTERFACE][i];
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530806 }
807
808 spin_unlock_bh(&nss_top_main.stats_lock);
809
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530810 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530811 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530812 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530813 }
814
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530815 /*
Murat Sezgin99dab642014-08-28 14:40:34 -0700816 * eth_rx node stats
817 */
818 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx node stats:\n\n");
819 spin_lock_bh(&nss_top_main.stats_lock);
820 for (i = 0; (i < NSS_STATS_ETH_RX_MAX); i++) {
821 stats_shadow[i] = nss_top_main.stats_eth_rx[i];
822 }
823
824 spin_unlock_bh(&nss_top_main.stats_lock);
825
826 for (i = 0; (i < NSS_STATS_ETH_RX_MAX); i++) {
827 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
828 "%s = %llu\n", nss_stats_str_eth_rx[i], stats_shadow[i]);
829 }
830
831 /*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530832 * Exception stats
833 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530834 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530835
836 spin_lock_bh(&nss_top_main.stats_lock);
837 for (i = 0; (i < NSS_EXCEPTION_EVENT_ETH_RX_MAX); i++) {
838 stats_shadow[i] = nss_top_main.stats_if_exception_eth_rx[i];
839 }
840
841 spin_unlock_bh(&nss_top_main.stats_lock);
842
843 for (i = 0; (i < NSS_EXCEPTION_EVENT_ETH_RX_MAX); i++) {
844 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
845 "%s = %llu\n", nss_stats_str_if_exception_eth_rx[i], stats_shadow[i]);
846 }
847
848 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\neth_rx stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530849 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
850 kfree(lbuf);
851 kfree(stats_shadow);
852
853 return bytes_read;
854}
855
856/*
857 * nss_stats_n2h_read()
858 * Read N2H stats
859 */
860static ssize_t nss_stats_n2h_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
861{
862 int32_t i;
863
864 /*
865 * max output lines = #stats + start tag line + end tag line + three blank lines
866 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530867 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_N2H_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530868 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
869 size_t size_wr = 0;
870 ssize_t bytes_read = 0;
871 uint64_t *stats_shadow;
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700872 int max = NSS_STATS_N2H_MAX - NSS_STATS_NODE_MAX;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530873
874 char *lbuf = kzalloc(size_al, GFP_KERNEL);
875 if (unlikely(lbuf == NULL)) {
876 nss_warning("Could not allocate memory for local statistics buffer");
877 return 0;
878 }
879
880 stats_shadow = kzalloc(NSS_STATS_N2H_MAX * 8, GFP_KERNEL);
881 if (unlikely(stats_shadow == NULL)) {
882 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530883 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530884 return 0;
885 }
886
887 size_wr = scnprintf(lbuf, size_al, "n2h stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530888
889 /*
890 * Common node stats
891 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530892 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530893 spin_lock_bh(&nss_top_main.stats_lock);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530894 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
895 stats_shadow[i] = nss_top_main.nss[0].stats_n2h[i];
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530896 }
897
898 spin_unlock_bh(&nss_top_main.stats_lock);
899
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530900 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
901 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
902 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
903 }
904
905 /*
906 * N2H node stats
907 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530908 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530909 spin_lock_bh(&nss_top_main.stats_lock);
910 for (i = NSS_STATS_NODE_MAX; (i < NSS_STATS_N2H_MAX); i++) {
911 stats_shadow[i] = nss_top_main.nss[0].stats_n2h[i];
912 }
913
914 spin_unlock_bh(&nss_top_main.stats_lock);
915
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700916 for (i = 0; i < max; i++) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530917 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700918 "%s = %llu\n", nss_stats_str_n2h[i], stats_shadow[i + NSS_STATS_NODE_MAX]);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530919 }
920
921 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h stats end\n\n");
922 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
923 kfree(lbuf);
924 kfree(stats_shadow);
925
926 return bytes_read;
927}
928
929/*
Thomas Wuc3e382c2014-10-29 15:35:13 -0700930 * nss_stats_lso_rx_read()
931 * Read LSO_RX stats
932 */
933static ssize_t nss_stats_lso_rx_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
934{
935 int32_t i;
936
937 /*
938 * max output lines = #stats + start tag line + end tag line + three blank lines
939 */
940 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_LSO_RX_MAX + 3) + 5;
941 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
942 size_t size_wr = 0;
943 ssize_t bytes_read = 0;
944 uint64_t *stats_shadow;
945
946 char *lbuf = kzalloc(size_al, GFP_KERNEL);
947 if (unlikely(lbuf == NULL)) {
948 nss_warning("Could not allocate memory for local statistics buffer");
949 return 0;
950 }
951
952 stats_shadow = kzalloc(NSS_STATS_LSO_RX_MAX * 8, GFP_KERNEL);
953 if (unlikely(stats_shadow == NULL)) {
954 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +0530955 kfree(lbuf);
Thomas Wuc3e382c2014-10-29 15:35:13 -0700956 return 0;
957 }
958
959 size_wr = scnprintf(lbuf, size_al, "lso_rx stats start:\n\n");
960
961 /*
962 * Common node stats
963 */
964 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
965 spin_lock_bh(&nss_top_main.stats_lock);
966 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
967 stats_shadow[i] = nss_top_main.stats_node[NSS_LSO_RX_INTERFACE][i];
968 }
969
970 spin_unlock_bh(&nss_top_main.stats_lock);
971
972 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
973 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
974 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
975 }
976
977 /*
978 * lso_rx node stats
979 */
980 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nlso_rx node stats:\n\n");
981 spin_lock_bh(&nss_top_main.stats_lock);
982 for (i = 0; (i < NSS_STATS_LSO_RX_MAX); i++) {
983 stats_shadow[i] = nss_top_main.stats_lso_rx[i];
984 }
985
986 spin_unlock_bh(&nss_top_main.stats_lock);
987
988 for (i = 0; i < NSS_STATS_LSO_RX_MAX; i++) {
989 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
990 "%s = %llu\n", nss_stats_str_lso_rx[i], stats_shadow[i]);
991 }
992
993 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nlso_rx stats end\n\n");
994 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
995 kfree(lbuf);
996 kfree(stats_shadow);
997
998 return bytes_read;
999}
1000
1001/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301002 * nss_stats_drv_read()
1003 * Read HLOS driver stats
1004 */
1005static ssize_t nss_stats_drv_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1006{
1007 int32_t i;
1008
1009 /*
1010 * max output lines = #stats + start tag line + end tag line + three blank lines
1011 */
1012 uint32_t max_output_lines = NSS_STATS_DRV_MAX + 5;
1013 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
1014 size_t size_wr = 0;
1015 ssize_t bytes_read = 0;
1016 uint64_t *stats_shadow;
1017
1018 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1019 if (unlikely(lbuf == NULL)) {
1020 nss_warning("Could not allocate memory for local statistics buffer");
1021 return 0;
1022 }
1023
1024 stats_shadow = kzalloc(NSS_STATS_DRV_MAX * 8, GFP_KERNEL);
1025 if (unlikely(stats_shadow == NULL)) {
1026 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +05301027 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301028 return 0;
1029 }
1030
1031 size_wr = scnprintf(lbuf, size_al, "drv stats start:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301032 for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
Sundarajan Srinivasan62fee7e2015-01-22 11:13:10 -08001033 stats_shadow[i] = NSS_PKT_STATS_READ(&nss_top_main.stats_drv[i]);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301034 }
1035
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301036 for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
1037 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1038 "%s = %llu\n", nss_stats_str_drv[i], stats_shadow[i]);
1039 }
1040
1041 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ndrv stats end\n\n");
1042 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
1043 kfree(lbuf);
1044 kfree(stats_shadow);
1045
1046 return bytes_read;
1047}
1048
1049/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301050 * nss_stats_pppoe_read()
1051 * Read PPPoE stats
1052 */
1053static ssize_t nss_stats_pppoe_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1054{
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301055 int32_t i, j, k;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301056
1057 /*
1058 * max output lines = #stats + start tag line + end tag line + three blank lines
1059 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301060 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_PPPOE_MAX + 3) +
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +05301061 ((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 +05301062 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
1063 size_t size_wr = 0;
1064 ssize_t bytes_read = 0;
1065 uint64_t *stats_shadow;
1066
1067 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1068 if (unlikely(lbuf == NULL)) {
1069 nss_warning("Could not allocate memory for local statistics buffer");
1070 return 0;
1071 }
1072
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301073 stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301074 if (unlikely(stats_shadow == NULL)) {
1075 nss_warning("Could not allocate memory for local shadow buffer");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301076 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301077 return 0;
1078 }
1079
1080 size_wr = scnprintf(lbuf, size_al, "pppoe stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301081
1082 /*
1083 * Common node stats
1084 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +05301085 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301086 spin_lock_bh(&nss_top_main.stats_lock);
1087 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
1088 stats_shadow[i] = nss_top_main.stats_node[NSS_PPPOE_RX_INTERFACE][i];
1089 }
1090
1091 spin_unlock_bh(&nss_top_main.stats_lock);
1092
1093 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
1094 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1095 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
1096 }
1097
1098 /*
1099 * PPPoE node stats
1100 */
Murat Sezgin2f9241a2015-06-25 13:01:51 -07001101 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npppoe node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301102 spin_lock_bh(&nss_top_main.stats_lock);
1103 for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
1104 stats_shadow[i] = nss_top_main.stats_pppoe[i];
1105 }
1106
1107 spin_unlock_bh(&nss_top_main.stats_lock);
1108
1109 for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
1110 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1111 "%s = %llu\n", nss_stats_str_pppoe[i], stats_shadow[i]);
1112 }
1113
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301114 /*
1115 * Exception stats
1116 */
1117 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nException PPPoE:\n\n");
1118
Murat Sezgin2f9241a2015-06-25 13:01:51 -07001119 for (j = 1; j <= NSS_MAX_PHYSICAL_INTERFACES; j++) {
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301120 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nInterface %d:\n\n", j);
1121
1122 spin_lock_bh(&nss_top_main.stats_lock);
Murat Sezgin2f9241a2015-06-25 13:01:51 -07001123 for (k = 1; k <= NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +05301124 for (i = 0; (i < NSS_PPPOE_EXCEPTION_EVENT_MAX); i++) {
Murat Sezgin2f9241a2015-06-25 13:01:51 -07001125 stats_shadow_pppoe_except[k - 1][i] = nss_top_main.stats_if_exception_pppoe[j][k][i];
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301126 }
1127 }
1128
1129 spin_unlock_bh(&nss_top_main.stats_lock);
1130
Murat Sezgin2f9241a2015-06-25 13:01:51 -07001131 for (k = 1; k <= NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301132 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. Session\n", k);
Ankit Dhanukaa1569ce2014-05-13 19:58:06 +05301133 for (i = 0; (i < NSS_PPPOE_EXCEPTION_EVENT_MAX); i++) {
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301134 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1135 "%s = %llu\n",
1136 nss_stats_str_if_exception_pppoe[i],
Murat Sezgin2f9241a2015-06-25 13:01:51 -07001137 stats_shadow_pppoe_except[k - 1][i]);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301138 }
1139 }
1140
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301141 }
1142
Murat Sezgin2f9241a2015-06-25 13:01:51 -07001143 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npppoe stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301144 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
1145 kfree(lbuf);
1146 kfree(stats_shadow);
1147
1148 return bytes_read;
1149}
1150
1151/*
1152 * nss_stats_gmac_read()
1153 * Read GMAC stats
1154 */
1155static ssize_t nss_stats_gmac_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1156{
1157 uint32_t i, id;
1158
1159 /*
1160 * max output lines = ((#stats + start tag + one blank) * #GMACs) + start/end tag + 3 blank
1161 */
1162 uint32_t max_output_lines = ((NSS_STATS_GMAC_MAX + 2) * NSS_MAX_PHYSICAL_INTERFACES) + 5;
1163 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
1164 size_t size_wr = 0;
1165 ssize_t bytes_read = 0;
1166 uint64_t *stats_shadow;
1167
1168 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1169 if (unlikely(lbuf == NULL)) {
1170 nss_warning("Could not allocate memory for local statistics buffer");
1171 return 0;
1172 }
1173
1174 stats_shadow = kzalloc(NSS_STATS_GMAC_MAX * 8, GFP_KERNEL);
1175 if (unlikely(stats_shadow == NULL)) {
1176 nss_warning("Could not allocate memory for local shadow buffer");
Ankit Dhanuka14999992014-11-12 15:35:11 +05301177 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301178 return 0;
1179 }
1180
1181 size_wr = scnprintf(lbuf, size_al, "gmac stats start:\n\n");
1182
1183 for (id = 0; id < NSS_MAX_PHYSICAL_INTERFACES; id++) {
1184 spin_lock_bh(&nss_top_main.stats_lock);
1185 for (i = 0; (i < NSS_STATS_GMAC_MAX); i++) {
1186 stats_shadow[i] = nss_top_main.stats_gmac[id][i];
1187 }
1188
1189 spin_unlock_bh(&nss_top_main.stats_lock);
1190
1191 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "GMAC ID: %d\n", id);
1192 for (i = 0; (i < NSS_STATS_GMAC_MAX); i++) {
1193 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1194 "%s = %llu\n", nss_stats_str_gmac[i], stats_shadow[i]);
1195 }
1196 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\n");
1197 }
1198
1199 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngmac stats end\n\n");
1200 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
1201 kfree(lbuf);
1202 kfree(stats_shadow);
1203
1204 return bytes_read;
1205}
1206
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001207/*
Bharath M Kumarcc666e92014-12-24 19:17:28 +05301208 * nss_stats_wifi_read()
1209 * Read wifi statistics
1210 */
1211static ssize_t nss_stats_wifi_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1212{
1213 uint32_t i, id;
1214
1215 /*
1216 * max output lines = ((#stats + start tag + one blank) * #WIFI RADIOs) + start/end tag + 3 blank
1217 */
1218 uint32_t max_output_lines = ((NSS_STATS_WIFI_MAX + 2) * NSS_MAX_WIFI_RADIO_INTERFACES) + 5;
1219 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
1220 size_t size_wr = 0;
1221 ssize_t bytes_read = 0;
1222 uint64_t *stats_shadow;
1223
1224 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1225 if (unlikely(lbuf == NULL)) {
1226 nss_warning("Could not allocate memory for local statistics buffer");
1227 return 0;
1228 }
1229
1230 stats_shadow = kzalloc(NSS_STATS_WIFI_MAX * 8, GFP_KERNEL);
1231 if (unlikely(stats_shadow == NULL)) {
1232 nss_warning("Could not allocate memory for local shadow buffer");
1233 kfree(lbuf);
1234 return 0;
1235 }
1236
1237 size_wr = scnprintf(lbuf, size_al, "wifi stats start:\n\n");
1238
1239 for (id = 0; id < NSS_MAX_WIFI_RADIO_INTERFACES; id++) {
1240 spin_lock_bh(&nss_top_main.stats_lock);
1241 for (i = 0; (i < NSS_STATS_WIFI_MAX); i++) {
1242 stats_shadow[i] = nss_top_main.stats_wifi[id][i];
1243 }
1244
1245 spin_unlock_bh(&nss_top_main.stats_lock);
1246
1247 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "WIFI ID: %d\n", id);
1248 for (i = 0; (i < NSS_STATS_WIFI_MAX); i++) {
1249 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1250 "%s = %llu\n", nss_stats_str_wifi[i], stats_shadow[i]);
1251 }
1252 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\n");
1253 }
1254
1255 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nwifi stats end\n\n");
1256 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
1257 kfree(lbuf);
1258 kfree(stats_shadow);
1259
1260 return bytes_read;
1261}
1262
1263/*
ratheesh kannoth7af985d2015-06-24 15:08:40 +05301264 * nss_stats_l2tpv2_read()
1265 * Read l2tpv2 statistics
1266 */
1267static ssize_t nss_stats_l2tpv2_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1268{
1269
1270 uint32_t max_output_lines = 2 /* header & footer for session stats */
1271 + NSS_MAX_L2TPV2_DYNAMIC_INTERFACES * (NSS_STATS_L2TPV2_SESSION_MAX + 2) /*session stats */
1272 + 2;
1273 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines ;
1274 size_t size_wr = 0;
1275 ssize_t bytes_read = 0;
1276 struct net_device *dev;
1277 struct nss_stats_l2tpv2_session_debug l2tpv2_session_stats[NSS_MAX_L2TPV2_DYNAMIC_INTERFACES];
1278 int id, i;
1279
1280 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1281 if (unlikely(lbuf == NULL)) {
1282 nss_warning("Could not allocate memory for local statistics buffer");
1283 return 0;
1284 }
1285
1286 memset(&l2tpv2_session_stats, 0, sizeof(struct nss_stats_l2tpv2_session_debug) * NSS_MAX_L2TPV2_DYNAMIC_INTERFACES);
1287
1288 /*
1289 * Get all stats
1290 */
1291 nss_l2tpv2_session_debug_stats_get((void *)&l2tpv2_session_stats);
1292
1293 /*
1294 * Session stats
1295 */
1296 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nl2tp v2 session stats start:\n\n");
1297 for (id = 0; id < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; id++) {
1298
1299 if (!l2tpv2_session_stats[id].valid) {
1300 break;
1301 }
1302
1303 dev = dev_get_by_index(&init_net, l2tpv2_session_stats[id].if_index);
1304 if (likely(dev)) {
1305
1306 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id,
1307 l2tpv2_session_stats[id].if_num, dev->name);
1308 dev_put(dev);
1309 } else {
1310 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id,
1311 l2tpv2_session_stats[id].if_num);
1312 }
1313
1314 for (i = 0; i < NSS_STATS_L2TPV2_SESSION_MAX; i++) {
1315 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1316 "\t%s = %llu\n", nss_stats_str_l2tpv2_session_debug_stats[i],
1317 l2tpv2_session_stats[id].stats[i]);
1318 }
1319 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
1320 }
1321
1322 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nl2tp v2 session stats end\n");
1323 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
1324
1325 kfree(lbuf);
1326 return bytes_read;
1327}
1328
1329/*
Shyam Sunder66e889d2015-11-02 15:31:20 +05301330 * nss_stats_pptp_read()
1331 * Read pptp statistics
1332 */
1333static ssize_t nss_stats_pptp_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1334{
1335
1336 uint32_t max_output_lines = 2 /* header & footer for session stats */
1337 + NSS_MAX_PPTP_DYNAMIC_INTERFACES * (NSS_STATS_PPTP_SESSION_MAX + 2) /*session stats */
1338 + 2;
1339 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines ;
1340 size_t size_wr = 0;
1341 ssize_t bytes_read = 0;
1342 struct net_device *dev;
1343 struct nss_stats_pptp_session_debug pptp_session_stats[NSS_MAX_PPTP_DYNAMIC_INTERFACES];
1344 int id, i;
1345
1346 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1347 if (unlikely(lbuf == NULL)) {
1348 nss_warning("Could not allocate memory for local statistics buffer");
1349 return 0;
1350 }
1351
1352 memset(&pptp_session_stats, 0, sizeof(struct nss_stats_pptp_session_debug) * NSS_MAX_PPTP_DYNAMIC_INTERFACES);
1353
1354 /*
1355 * Get all stats
1356 */
1357 nss_pptp_session_debug_stats_get((void *)&pptp_session_stats);
1358
1359 /*
1360 * Session stats
1361 */
1362 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npptp session stats start:\n\n");
1363 for (id = 0; id < NSS_MAX_PPTP_DYNAMIC_INTERFACES; id++) {
1364
1365 if (!pptp_session_stats[id].valid) {
1366 break;
1367 }
1368
1369 dev = dev_get_by_index(&init_net, pptp_session_stats[id].if_index);
1370 if (likely(dev)) {
1371
1372 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id,
1373 pptp_session_stats[id].if_num, dev->name);
1374 dev_put(dev);
1375 } else {
1376 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id,
1377 pptp_session_stats[id].if_num);
1378 }
1379
1380 for (i = 0; i < NSS_STATS_PPTP_SESSION_MAX; i++) {
1381 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1382 "\t%s = %llu\n", nss_stats_str_pptp_session_debug_stats[i],
1383 pptp_session_stats[id].stats[i]);
1384 }
1385 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n");
1386 }
1387
1388 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npptp session stats end\n");
1389 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
1390
1391 kfree(lbuf);
1392 return bytes_read;
1393}
1394
1395/*
Ankit Dhanuka14999992014-11-12 15:35:11 +05301396 * nss_stats_sjack_read()
1397 * Read SJACK stats
1398 */
1399static ssize_t nss_stats_sjack_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1400{
1401 int32_t i;
1402 /*
1403 * max output lines = #stats + start tag line + end tag line + three blank lines
1404 */
1405 uint32_t max_output_lines = NSS_STATS_NODE_MAX + 5;
1406 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
1407 size_t size_wr = 0;
1408 ssize_t bytes_read = 0;
1409 uint64_t *stats_shadow;
1410
1411 char *lbuf = kzalloc(size_al, GFP_KERNEL);
1412 if (unlikely(lbuf == NULL)) {
1413 nss_warning("Could not allocate memory for local statistics buffer");
1414 return 0;
1415 }
1416
1417 stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL);
1418 if (unlikely(stats_shadow == NULL)) {
1419 nss_warning("Could not allocate memory for local shadow buffer");
1420 kfree(lbuf);
1421 return 0;
1422 }
1423
1424 size_wr = scnprintf(lbuf, size_al, "sjack stats start:\n\n");
1425
1426 /*
1427 * Common node stats
1428 */
1429 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
1430 spin_lock_bh(&nss_top_main.stats_lock);
1431 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
1432 stats_shadow[i] = nss_top_main.stats_node[NSS_SJACK_INTERFACE][i];
1433 }
1434
1435 spin_unlock_bh(&nss_top_main.stats_lock);
1436
1437 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
1438 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
1439 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
1440 }
1441
1442 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nsjack stats end\n\n");
1443
1444 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
1445 kfree(lbuf);
1446 kfree(stats_shadow);
1447
1448 return bytes_read;
1449}
1450
1451/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001452 * Make a row for CAPWAP encap stats.
1453 */
1454static ssize_t nss_stats_capwap_encap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s)
1455{
Saurabh Misra3f66e872015-04-03 11:30:42 -07001456 char *header[] = { "packets", "bytes", "fragments", "drop_ref", "drop_ver", "drop_unalign",
1457 "drop_hroom", "drop_dtls", "drop_nwireless", "drop_qfull", "drop_memfail", "unknown" };
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001458 uint64_t tcnt = 0;
1459
1460 switch (i) {
1461 case 0:
1462 tcnt = s->pnode_stats.tx_packets;
1463 break;
1464 case 1:
1465 tcnt = s->pnode_stats.tx_bytes;
1466 break;
1467 case 2:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001468 tcnt = s->tx_segments;
1469 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001470 case 3:
1471 tcnt = s->tx_dropped_sg_ref;
1472 break;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001473 case 4:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001474 tcnt = s->tx_dropped_ver_mis;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001475 break;
1476 case 5:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001477 tcnt = s->tx_dropped_unalign;
1478 break;
1479 case 6:
1480 tcnt = s->tx_dropped_hroom;
1481 break;
1482 case 7:
1483 tcnt = s->tx_dropped_dtls;
1484 break;
1485 case 8:
1486 tcnt = s->tx_dropped_nwireless;
1487 break;
1488 case 9:
1489 tcnt = s->tx_queue_full_drops;
1490 break;
1491 case 10:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001492 tcnt = s->tx_mem_failure_drops;
1493 break;
1494 default:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001495 return 0;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001496 }
1497
Saurabh Misra3f66e872015-04-03 11:30:42 -07001498 return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001499}
1500
1501/*
1502 * Make a row for CAPWAP decap stats.
1503 */
1504static ssize_t nss_stats_capwap_decap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s)
1505{
Saurabh Misra3f66e872015-04-03 11:30:42 -07001506 char *header[] = { "packets", "bytes", "DTLS_pkts", "fragments", "rx_dropped", "drop_oversize",
1507 "drop_frag_timeout", "drop_frag_dup", "drop_frag_gap", "drop_qfull", "drop_memfail",
1508 "drop_csum", "drop_malformed", "unknown" };
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001509 uint64_t tcnt = 0;
1510
1511 switch(i) {
1512 case 0:
1513 tcnt = s->pnode_stats.rx_packets;
1514 break;
1515 case 1:
1516 tcnt = s->pnode_stats.rx_bytes;
1517 break;
1518 case 2:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001519 tcnt = s->dtls_pkts;
1520 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001521 case 3:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001522 tcnt = s->rx_segments;
1523 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001524 case 4:
1525 tcnt = s->pnode_stats.rx_dropped;
1526 break;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001527 case 5:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001528 tcnt = s->rx_oversize_drops;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001529 break;
1530 case 6:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001531 tcnt = s->rx_frag_timeout_drops;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001532 break;
1533 case 7:
1534 tcnt = s->rx_dup_frag;
1535 break;
1536 case 8:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001537 tcnt = s->rx_frag_gap_drops;
1538 break;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001539 case 9:
Saurabh Misra3f66e872015-04-03 11:30:42 -07001540 tcnt = s->rx_queue_full_drops;
1541 return (snprintf(line, len, "%s = %llu (n2h = %llu)\n", header[i], tcnt, s->rx_n2h_queue_full_drops));
1542 case 10:
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001543 tcnt = s->rx_mem_failure_drops;
1544 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001545 case 11:
1546 tcnt = s->rx_csum_drops;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001547 break;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001548 case 12:
1549 tcnt = s->rx_malformed;
1550 break;
1551 default:
1552 return 0;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001553 }
1554
Saurabh Misra3f66e872015-04-03 11:30:42 -07001555 return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001556}
1557
1558/*
1559 * nss_stats_capwap_read()
1560 * Read CAPWAP stats
1561 */
1562static ssize_t nss_stats_capwap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos, uint16_t type)
1563{
1564 struct nss_stats_data *data = fp->private_data;
1565 ssize_t bytes_read = 0;
1566 struct nss_capwap_tunnel_stats stats;
1567 size_t bytes;
1568 char line[80];
Saurabh Misra3f66e872015-04-03 11:30:42 -07001569 int start;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001570 uint32_t if_num = NSS_DYNAMIC_IF_START;
1571 uint32_t max_if_num = NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES;
1572
1573 if (data) {
1574 if_num = data->if_num;
1575 }
1576
1577 /*
1578 * If we are done accomodating all the CAPWAP tunnels.
1579 */
1580 if (if_num > max_if_num) {
1581 return 0;
1582 }
1583
1584 for (; if_num <= max_if_num; if_num++) {
1585 bool isthere;
1586
1587 if (nss_is_dynamic_interface(if_num) == false) {
1588 continue;
1589 }
1590
1591 if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) {
1592 continue;
1593 }
1594
1595 /*
1596 * If CAPWAP tunnel does not exists, then isthere will be false.
1597 */
1598 isthere = nss_capwap_get_stats(if_num, &stats);
1599 if (!isthere) {
1600 continue;
1601 }
1602
Saurabh Misra3f66e872015-04-03 11:30:42 -07001603 bytes = snprintf(line, sizeof(line), "----if_num : %2d----\n", if_num);
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001604 if ((bytes_read + bytes) > sz) {
1605 break;
1606 }
1607
1608 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1609 bytes_read = -EFAULT;
1610 goto fail;
1611 }
1612 bytes_read += bytes;
1613 start = 0;
Saurabh Misra3f66e872015-04-03 11:30:42 -07001614 while (bytes_read < sz) {
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001615 if (type == 1) {
1616 bytes = nss_stats_capwap_encap(line, sizeof(line), start, &stats);
1617 } else {
1618 bytes = nss_stats_capwap_decap(line, sizeof(line), start, &stats);
1619 }
1620
Saurabh Misra3f66e872015-04-03 11:30:42 -07001621 /*
1622 * If we don't have any more lines in decap/encap.
1623 */
1624 if (bytes == 0) {
1625 break;
1626 }
1627
Saurabh Misra09dddeb2014-09-30 16:38:07 -07001628 if ((bytes_read + bytes) > sz)
1629 break;
1630
1631 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1632 bytes_read = -EFAULT;
1633 goto fail;
1634 }
1635
1636 bytes_read += bytes;
1637 start++;
1638 }
1639 }
1640
1641 if (bytes_read > 0) {
1642 *ppos = bytes_read;
1643 }
1644
1645 if (data) {
1646 data->if_num = if_num;
1647 }
1648fail:
1649 return bytes_read;
1650}
1651
1652/*
1653 * nss_stats_capwap_decap_read()
1654 * Read CAPWAP decap stats
1655 */
1656static ssize_t nss_stats_capwap_decap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1657{
1658 return (nss_stats_capwap_read(fp, ubuf, sz, ppos, 0));
1659}
1660
1661/*
1662 * nss_stats_capwap_encap_read()
1663 * Read CAPWAP encap stats
1664 */
1665static ssize_t nss_stats_capwap_encap_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1666{
1667 return (nss_stats_capwap_read(fp, ubuf, sz, ppos, 1));
1668}
1669
1670/*
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05301671 * nss_stats_gre_redir()
1672 * Make a row for GRE_REDIR stats.
1673 */
1674static ssize_t nss_stats_gre_redir(char *line, int len, int i, struct nss_gre_redir_tunnel_stats *s)
1675{
1676 char *header[] = { "TX Packets", "TX Bytes", "TX Drops", "RX Packets", "RX Bytes", "Rx Drops" };
1677 uint64_t tcnt = 0;
1678
1679 switch (i) {
1680 case 0:
1681 tcnt = s->node_stats.tx_packets;
1682 break;
1683 case 1:
1684 tcnt = s->node_stats.tx_bytes;
1685 break;
1686 case 2:
1687 tcnt = s->tx_dropped;
1688 break;
1689 case 3:
1690 tcnt = s->node_stats.rx_packets;
1691 break;
1692 case 4:
1693 tcnt = s->node_stats.rx_bytes;
1694 break;
1695 case 5:
1696 tcnt = s->node_stats.rx_dropped;
1697 break;
1698 default:
1699 i = 6;
1700 break;
1701 }
1702
1703 return (snprintf(line, len, "%s = %llu\n", header[i], tcnt));
1704}
1705
1706/*
1707 * nss_stats_gre_redir_read()
1708 * READ gre_redir tunnel stats.
1709 */
1710static ssize_t nss_stats_gre_redir_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1711{
1712 struct nss_stats_data *data = fp->private_data;
1713 ssize_t bytes_read = 0;
1714 struct nss_gre_redir_tunnel_stats stats;
1715 size_t bytes;
1716 char line[80];
1717 int start, end;
1718 int index = 0;
1719
1720 if (data) {
1721 index = data->index;
1722 }
1723
1724 /*
1725 * If we are done accomodating all the GRE_REDIR tunnels.
1726 */
1727 if (index >= NSS_GRE_REDIR_MAX_INTERFACES) {
1728 return 0;
1729 }
1730
1731 for (; index < NSS_GRE_REDIR_MAX_INTERFACES; index++) {
1732 bool isthere;
1733
1734 /*
1735 * If gre_redir tunnel does not exists, then isthere will be false.
1736 */
1737 isthere = nss_gre_redir_get_stats(index, &stats);
1738 if (!isthere) {
1739 continue;
1740 }
1741
1742 bytes = snprintf(line, sizeof(line), "\nTunnel if_num: %2d\n", stats.if_num);
1743 if ((bytes_read + bytes) > sz) {
1744 break;
1745 }
1746
1747 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1748 bytes_read = -EFAULT;
1749 goto fail;
1750 }
1751 bytes_read += bytes;
1752 start = 0;
1753 end = 6;
1754 while (bytes_read < sz && start < end) {
1755 bytes = nss_stats_gre_redir(line, sizeof(line), start, &stats);
1756
1757 if ((bytes_read + bytes) > sz)
1758 break;
1759
1760 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1761 bytes_read = -EFAULT;
1762 goto fail;
1763 }
1764
1765 bytes_read += bytes;
1766 start++;
1767 }
1768 }
1769
1770 if (bytes_read > 0) {
1771 *ppos = bytes_read;
1772 }
1773
1774 if (data) {
1775 data->index = index;
1776 }
1777
1778fail:
1779 return bytes_read;
1780}
1781
1782/*
Sundarajan Srinivasan273d9002015-03-03 15:43:16 -08001783 * nss_stats_wifi_if_read()
1784 * Read wifi_if statistics
1785 */
1786static ssize_t nss_stats_wifi_if_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
1787{
1788 struct nss_stats_data *data = fp->private_data;
1789 int32_t if_num = NSS_DYNAMIC_IF_START;
1790 int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
1791 size_t bytes = 0;
1792 ssize_t bytes_read = 0;
1793 char line[80];
1794 int start, end;
1795
1796 if (data) {
1797 if_num = data->if_num;
1798 }
1799
1800 if (if_num > max_if_num) {
1801 return 0;
1802 }
1803
1804 for (; if_num < max_if_num; if_num++) {
1805 if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
1806 continue;
1807
1808 bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
1809 if ((bytes_read + bytes) > sz)
1810 break;
1811
1812 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1813 bytes_read = -EFAULT;
1814 goto end;
1815 }
1816
1817 bytes_read += bytes;
1818
1819 start = 0;
1820 end = 7;
1821 while (bytes_read < sz && start < end) {
1822 bytes = nss_wifi_if_copy_stats(if_num, start, line);
1823 if (!bytes)
1824 break;
1825
1826 if ((bytes_read + bytes) > sz)
1827 break;
1828
1829 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1830 bytes_read = -EFAULT;
1831 goto end;
1832 }
1833
1834 bytes_read += bytes;
1835 start++;
1836 }
1837
1838 bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num);
1839 if (bytes_read > (sz - bytes))
1840 break;
1841
1842 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1843 bytes_read = -EFAULT;
1844 goto end;
1845 }
1846
1847 bytes_read += bytes;
1848 }
1849
1850 if (bytes_read > 0) {
1851 *ppos = bytes_read;
1852 }
1853
1854 if (data) {
1855 data->if_num = if_num;
1856 }
1857
1858end:
1859 return bytes_read;
1860}
1861
1862/*
Sundarajan Srinivasanab2c8562015-06-09 16:14:10 -07001863 * nss_stats_virt_if_read()
1864 * Read virt_if statistics
1865 */
1866static ssize_t nss_stats_virt_if_read(struct file *fp, char __user *ubuf,
1867 size_t sz, loff_t *ppos)
1868{
1869 struct nss_stats_data *data = fp->private_data;
1870 int32_t if_num = NSS_DYNAMIC_IF_START;
1871 int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
1872 size_t bytes = 0;
1873 ssize_t bytes_read = 0;
1874 char line[80];
1875 int start, end;
1876
1877 if (data) {
1878 if_num = data->if_num;
1879 }
1880
1881 if (if_num > max_if_num) {
1882 return 0;
1883 }
1884
1885 for (; if_num < max_if_num; if_num++) {
1886 if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
1887 continue;
1888
1889 bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
1890 if ((bytes_read + bytes) > sz)
1891 break;
1892
1893 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1894 bytes_read = -EFAULT;
1895 goto end;
1896 }
1897
1898 bytes_read += bytes;
1899
1900 start = 0;
1901 end = 7;
1902 while (bytes_read < sz && start < end) {
1903 bytes = nss_virt_if_copy_stats(if_num, start, line);
1904 if (!bytes)
1905 break;
1906
1907 if ((bytes_read + bytes) > sz)
1908 break;
1909
1910 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1911 bytes_read = -EFAULT;
1912 goto end;
1913 }
1914
1915 bytes_read += bytes;
1916 start++;
1917 }
1918
1919 bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num);
1920 if (bytes_read > (sz - bytes))
1921 break;
1922
1923 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1924 bytes_read = -EFAULT;
1925 goto end;
1926 }
1927
1928 bytes_read += bytes;
1929 }
1930
1931 if (bytes_read > 0) {
1932 *ppos = bytes_read;
1933 }
1934
1935 if (data) {
1936 data->if_num = if_num;
1937 }
1938
1939end:
1940 return bytes_read;
1941}
1942
1943/*
Sundarajan Srinivasancd1631b2015-06-18 01:23:30 -07001944 * nss_stats_tx_rx_virt_if_read()
1945 * Read tx_rx_virt_if statistics
1946 */
1947static ssize_t nss_stats_tx_rx_virt_if_read(struct file *fp, char __user *ubuf,
1948 size_t sz, loff_t *ppos)
1949{
1950 struct nss_stats_data *data = fp->private_data;
1951 int32_t if_num = NSS_DYNAMIC_IF_START;
1952 int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES;
1953 size_t bytes = 0;
1954 ssize_t bytes_read = 0;
1955 char line[80];
1956 int start, end;
1957
1958 if (data) {
1959 if_num = data->if_num;
1960 }
1961
1962 if (if_num > max_if_num) {
1963 return 0;
1964 }
1965
1966 for (; if_num < max_if_num; if_num++) {
1967 if (nss_dynamic_interface_get_type(if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED)
1968 continue;
1969
1970 bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num);
1971 if ((bytes_read + bytes) > sz)
1972 break;
1973
1974 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1975 bytes_read = -EFAULT;
1976 goto end;
1977 }
1978
1979 bytes_read += bytes;
1980
1981 start = 0;
1982 end = 7;
1983 while (bytes_read < sz && start < end) {
1984 bytes = nss_tx_rx_virt_if_copy_stats(if_num, start, line);
1985 if (!bytes)
1986 break;
1987
1988 if ((bytes_read + bytes) > sz)
1989 break;
1990
1991 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
1992 bytes_read = -EFAULT;
1993 goto end;
1994 }
1995
1996 bytes_read += bytes;
1997 start++;
1998 }
1999
2000 bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num);
2001 if (bytes_read > (sz - bytes))
2002 break;
2003
2004 if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) {
2005 bytes_read = -EFAULT;
2006 goto end;
2007 }
2008
2009 bytes_read += bytes;
2010 }
2011
2012 if (bytes_read > 0) {
2013 *ppos = bytes_read;
2014 }
2015
2016 if (data) {
2017 data->if_num = if_num;
2018 }
2019
2020end:
2021 return bytes_read;
2022}
2023
2024/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -07002025 * nss_stats_open()
2026 */
2027static int nss_stats_open(struct inode *inode, struct file *filp)
2028{
2029 struct nss_stats_data *data = NULL;
2030
2031 data = kzalloc(sizeof(struct nss_stats_data), GFP_KERNEL);
2032 if (!data) {
2033 return -ENOMEM;
2034 }
2035 memset(data, 0, sizeof (struct nss_stats_data));
2036 data->if_num = NSS_DYNAMIC_IF_START;
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05302037 data->index = 0;
Saurabh Misra09dddeb2014-09-30 16:38:07 -07002038 filp->private_data = data;
2039
2040 return 0;
2041}
2042
2043/*
2044 * nss_stats_release()
2045 */
2046static int nss_stats_release(struct inode *inode, struct file *filp)
2047{
2048 struct nss_stats_data *data = filp->private_data;
2049
2050 if (data) {
2051 kfree(data);
2052 }
2053
2054 return 0;
2055}
2056
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302057#define NSS_STATS_DECLARE_FILE_OPERATIONS(name) \
2058static const struct file_operations nss_stats_##name##_ops = { \
Saurabh Misra09dddeb2014-09-30 16:38:07 -07002059 .open = nss_stats_open, \
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302060 .read = nss_stats_##name##_read, \
2061 .llseek = generic_file_llseek, \
Saurabh Misra09dddeb2014-09-30 16:38:07 -07002062 .release = nss_stats_release, \
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302063};
2064
2065/*
2066 * nss_ipv4_stats_ops
2067 */
2068NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4)
2069
2070/*
Selin Dag6d9b0c12014-11-04 18:27:21 -08002071 * ipv4_reasm_stats_ops
2072 */
2073NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4_reasm)
2074
2075/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302076 * ipv6_stats_ops
2077 */
2078NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6)
2079
2080/*
Selin Dag60a2f5b2015-06-29 14:39:49 -07002081 * ipv6_reasm_stats_ops
2082 */
2083NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6_reasm)
2084
2085/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302086 * n2h_stats_ops
2087 */
2088NSS_STATS_DECLARE_FILE_OPERATIONS(n2h)
Thomas Wuc3e382c2014-10-29 15:35:13 -07002089
2090/*
2091 * lso_rx_stats_ops
2092 */
2093NSS_STATS_DECLARE_FILE_OPERATIONS(lso_rx)
2094
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302095/*
2096 * drv_stats_ops
2097 */
2098NSS_STATS_DECLARE_FILE_OPERATIONS(drv)
2099
2100/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302101 * pppoe_stats_ops
2102 */
2103NSS_STATS_DECLARE_FILE_OPERATIONS(pppoe)
2104
2105/*
ratheesh kannoth7af985d2015-06-24 15:08:40 +05302106 * l2tpv2_stats_ops
2107 */
2108NSS_STATS_DECLARE_FILE_OPERATIONS(l2tpv2)
2109
2110/*
Shyam Sunder66e889d2015-11-02 15:31:20 +05302111 * pptp_stats_ops
2112 */
2113NSS_STATS_DECLARE_FILE_OPERATIONS(pptp)
2114
2115/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302116 * gmac_stats_ops
2117 */
2118NSS_STATS_DECLARE_FILE_OPERATIONS(gmac)
2119
2120/*
Saurabh Misra09dddeb2014-09-30 16:38:07 -07002121 * capwap_stats_ops
2122 */
2123NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_encap)
2124NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_decap)
2125
2126/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05302127 * eth_rx_stats_ops
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302128 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05302129NSS_STATS_DECLARE_FILE_OPERATIONS(eth_rx)
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302130
2131/*
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05302132 * gre_redir_ops
2133 */
2134NSS_STATS_DECLARE_FILE_OPERATIONS(gre_redir)
2135
2136/*
Ankit Dhanuka14999992014-11-12 15:35:11 +05302137 * sjack_stats_ops
2138 */
2139NSS_STATS_DECLARE_FILE_OPERATIONS(sjack)
2140
Sundarajan Srinivasan273d9002015-03-03 15:43:16 -08002141NSS_STATS_DECLARE_FILE_OPERATIONS(wifi_if)
2142
Sundarajan Srinivasanab2c8562015-06-09 16:14:10 -07002143NSS_STATS_DECLARE_FILE_OPERATIONS(virt_if)
2144
Sundarajan Srinivasancd1631b2015-06-18 01:23:30 -07002145NSS_STATS_DECLARE_FILE_OPERATIONS(tx_rx_virt_if)
2146
Ankit Dhanuka14999992014-11-12 15:35:11 +05302147/*
Bharath M Kumarcc666e92014-12-24 19:17:28 +05302148 * wifi_stats_ops
2149 */
2150NSS_STATS_DECLARE_FILE_OPERATIONS(wifi)
2151
2152/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302153 * nss_stats_init()
2154 * Enable NSS statistics
2155 */
2156void nss_stats_init(void)
2157{
2158 /*
2159 * NSS driver entry
2160 */
2161 nss_top_main.top_dentry = debugfs_create_dir("qca-nss-drv", NULL);
2162 if (unlikely(nss_top_main.top_dentry == NULL)) {
2163 nss_warning("Failed to create qca-nss-drv directory in debugfs");
2164
2165 /*
2166 * Non availability of debugfs directory is not a catastrophy
2167 * We can still go ahead with other initialization
2168 */
2169 return;
2170 }
2171
2172 nss_top_main.stats_dentry = debugfs_create_dir("stats", nss_top_main.top_dentry);
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05302173 if (unlikely(nss_top_main.stats_dentry == NULL)) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302174 nss_warning("Failed to create qca-nss-drv directory in debugfs");
2175
2176 /*
2177 * Non availability of debugfs directory is not a catastrophy
2178 * We can still go ahead with rest of initialization
2179 */
2180 return;
2181 }
2182
2183 /*
2184 * Create files to obtain statistics
2185 */
2186
2187 /*
2188 * ipv4_stats
2189 */
2190 nss_top_main.ipv4_dentry = debugfs_create_file("ipv4", 0400,
2191 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv4_ops);
2192 if (unlikely(nss_top_main.ipv4_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05302193 nss_warning("Failed to create qca-nss-drv/stats/ipv4 file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302194 return;
2195 }
2196
2197 /*
Selin Dag6d9b0c12014-11-04 18:27:21 -08002198 * ipv4_reasm_stats
2199 */
2200 nss_top_main.ipv4_reasm_dentry = debugfs_create_file("ipv4_reasm", 0400,
2201 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv4_reasm_ops);
2202 if (unlikely(nss_top_main.ipv4_reasm_dentry == NULL)) {
2203 nss_warning("Failed to create qca-nss-drv/stats/ipv4_reasm file in debugfs");
2204 return;
2205 }
2206
2207 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302208 * ipv6_stats
2209 */
2210 nss_top_main.ipv6_dentry = debugfs_create_file("ipv6", 0400,
2211 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv6_ops);
2212 if (unlikely(nss_top_main.ipv6_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05302213 nss_warning("Failed to create qca-nss-drv/stats/ipv6 file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302214 return;
2215 }
2216
2217 /*
Selin Dag60a2f5b2015-06-29 14:39:49 -07002218 * ipv6_reasm_stats
2219 */
2220 nss_top_main.ipv6_reasm_dentry = debugfs_create_file("ipv6_reasm", 0400,
2221 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv6_reasm_ops);
2222 if (unlikely(nss_top_main.ipv6_reasm_dentry == NULL)) {
2223 nss_warning("Failed to create qca-nss-drv/stats/ipv6_reasm file in debugfs");
2224 return;
2225 }
2226
2227 /*
2228 * eth_rx__stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302229 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05302230 nss_top_main.eth_rx_dentry = debugfs_create_file("eth_rx", 0400,
2231 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_eth_rx_ops);
2232 if (unlikely(nss_top_main.eth_rx_dentry == NULL)) {
2233 nss_warning("Failed to create qca-nss-drv/stats/eth_rx file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302234 return;
2235 }
2236
2237 /*
2238 * n2h_stats
2239 */
2240 nss_top_main.n2h_dentry = debugfs_create_file("n2h", 0400,
2241 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_n2h_ops);
2242 if (unlikely(nss_top_main.n2h_dentry == NULL)) {
2243 nss_warning("Failed to create qca-nss-drv/stats/n2h directory in debugfs");
2244 return;
2245 }
2246
2247 /*
Thomas Wuc3e382c2014-10-29 15:35:13 -07002248 * lso_rx_stats
2249 */
2250 nss_top_main.lso_rx_dentry = debugfs_create_file("lso_rx", 0400,
2251 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_lso_rx_ops);
2252 if (unlikely(nss_top_main.lso_rx_dentry == NULL)) {
2253 nss_warning("Failed to create qca-nss-drv/stats/lso_rx file in debugfs");
2254 return;
2255 }
2256
2257 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302258 * drv_stats
2259 */
2260 nss_top_main.drv_dentry = debugfs_create_file("drv", 0400,
2261 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_drv_ops);
2262 if (unlikely(nss_top_main.drv_dentry == NULL)) {
2263 nss_warning("Failed to create qca-nss-drv/stats/drv directory in debugfs");
2264 return;
2265 }
2266
2267 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302268 * pppoe_stats
2269 */
2270 nss_top_main.pppoe_dentry = debugfs_create_file("pppoe", 0400,
2271 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_pppoe_ops);
2272 if (unlikely(nss_top_main.pppoe_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05302273 nss_warning("Failed to create qca-nss-drv/stats/pppoe file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302274 return;
2275 }
2276
2277 /*
2278 * gmac_stats
2279 */
2280 nss_top_main.gmac_dentry = debugfs_create_file("gmac", 0400,
2281 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gmac_ops);
2282 if (unlikely(nss_top_main.gmac_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +05302283 nss_warning("Failed to create qca-nss-drv/stats/gmac file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302284 return;
2285 }
Saurabh Misra09dddeb2014-09-30 16:38:07 -07002286
2287 /*
2288 * CAPWAP stats.
2289 */
2290 nss_top_main.capwap_encap_dentry = debugfs_create_file("capwap_encap", 0400,
2291 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_capwap_encap_ops);
2292 if (unlikely(nss_top_main.capwap_encap_dentry == NULL)) {
2293 nss_warning("Failed to create qca-nss-drv/stats/capwap_encap file in debugfs");
2294 return;
2295 }
2296
2297 nss_top_main.capwap_decap_dentry = debugfs_create_file("capwap_decap", 0400,
2298 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_capwap_decap_ops);
2299 if (unlikely(nss_top_main.capwap_decap_dentry == NULL)) {
2300 nss_warning("Failed to create qca-nss-drv/stats/capwap_decap file in debugfs");
2301 return;
2302 }
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05302303
2304 /*
2305 * GRE_REDIR stats
2306 */
2307 nss_top_main.gre_redir_dentry = debugfs_create_file("gre_redir", 0400,
Ankit Dhanuka14999992014-11-12 15:35:11 +05302308 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gre_redir_ops);
Ankit Dhanuka6228ebd2014-11-05 17:26:01 +05302309 if (unlikely(nss_top_main.gre_redir_dentry == NULL)) {
2310 nss_warning("Failed to create qca-nss-drv/stats/gre_redir file in debugfs");
2311 return;
2312 }
Ankit Dhanuka14999992014-11-12 15:35:11 +05302313
2314 /*
2315 * SJACK stats
2316 */
2317 nss_top_main.sjack_dentry = debugfs_create_file("sjack", 0400,
2318 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_sjack_ops);
2319 if (unlikely(nss_top_main.sjack_dentry == NULL)) {
2320 nss_warning("Failed to create qca-nss-drv/stats/sjack file in debugfs");
2321 return;
2322 }
Saurabh Misra96998db2014-07-10 12:15:48 -07002323
Bharath M Kumarcc666e92014-12-24 19:17:28 +05302324 /*
2325 * WIFI stats
2326 */
2327 nss_top_main.wifi_dentry = debugfs_create_file("wifi", 0400,
2328 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_wifi_ops);
2329 if (unlikely(nss_top_main.wifi_dentry == NULL)) {
2330 nss_warning("Failed to create qca-nss-drv/stats/wifi file in debugfs");
2331 return;
2332 }
2333
Sundarajan Srinivasan273d9002015-03-03 15:43:16 -08002334 /*
2335 * wifi_if stats
2336 */
2337 nss_top_main.wifi_if_dentry = debugfs_create_file("wifi_if", 0400,
2338 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_wifi_if_ops);
2339 if (unlikely(nss_top_main.wifi_if_dentry == NULL)) {
2340 nss_warning("Failed to create qca-nss-drv/stats/wifi_if file in debugfs");
2341 return;
2342 }
2343
Sundarajan Srinivasanab2c8562015-06-09 16:14:10 -07002344 nss_top_main.virt_if_dentry = debugfs_create_file("virt_if", 0400,
2345 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_virt_if_ops);
2346 if (unlikely(nss_top_main.virt_if_dentry == NULL)) {
2347 nss_warning("Failed to create qca-nss-drv/stats/virt_if file in debugfs");
2348 return;
2349 }
2350
Sundarajan Srinivasancd1631b2015-06-18 01:23:30 -07002351 nss_top_main.tx_rx_virt_if_dentry = debugfs_create_file("tx_rx_virt_if", 0400,
2352 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_tx_rx_virt_if_ops);
2353 if (unlikely(nss_top_main.virt_if_dentry == NULL)) {
2354 nss_warning("Failed to create qca-nss-drv/stats/tx_rx_virt_if file in debugfs");
2355 return;
2356 }
2357
ratheesh kannoth7af985d2015-06-24 15:08:40 +05302358 /*
2359 * L2TPV2 Stats
2360 */
2361 nss_top_main.l2tpv2_dentry = debugfs_create_file("l2tpv2", 0400,
2362 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_l2tpv2_ops);
2363 if (unlikely(nss_top_main.l2tpv2_dentry == NULL)) {
2364 nss_warning("Failed to create qca-nss-drv/stats/l2tpv2 file in debugfs");
2365 return;
2366 }
Shyam Sunder66e889d2015-11-02 15:31:20 +05302367
2368 /*
2369 * PPTP Stats
2370 */
2371 nss_top_main.pptp_dentry = debugfs_create_file("pptp", 0400,
2372 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_pptp_ops);
2373 if (unlikely(nss_top_main.pptp_dentry == NULL)) {
2374 nss_warning("Failed to create qca-nss-drv/stats/pptp file in debugfs");
2375 return;
2376 }
2377
Saurabh Misra96998db2014-07-10 12:15:48 -07002378 nss_log_init();
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302379}
2380
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302381/*
2382 * nss_stats_clean()
2383 * Cleanup NSS statistics files
2384 */
2385void nss_stats_clean(void)
2386{
2387 /*
2388 * Remove debugfs tree
2389 */
2390 if (likely(nss_top_main.top_dentry != NULL)) {
2391 debugfs_remove_recursive(nss_top_main.top_dentry);
Stephen Wangdc8b5322015-06-27 20:11:50 -07002392 nss_top_main.top_dentry = NULL;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05302393 }
2394}