blob: a60c3c203655291c143e1194a57f8fd630d58765 [file] [log] [blame]
Wayne Tanb45933c2020-01-06 17:19:25 -08001/*
2 **************************************************************************
3 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all 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 */
16
17/*
18 * nss_strings.c
19 * NSS driver strings APIs.
20 */
21
22#include "nss_strings.h"
23#include "nss_core.h"
24
25/*
26 * common stats
27 */
28struct nss_stats_info nss_strings_stats_node[NSS_STATS_NODE_MAX] = {
29 {"rx_pkts" , NSS_STATS_TYPE_COMMON},
30 {"rx_byts" , NSS_STATS_TYPE_COMMON},
31 {"tx_pkts" , NSS_STATS_TYPE_COMMON},
32 {"tx_byts" , NSS_STATS_TYPE_COMMON},
33 {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP},
34 {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP},
35 {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP},
36 {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP}
37};
38
39/*
40 * nss_strings_print()
41 * Helper API to print stats names
42 */
43size_t nss_strings_print(char __user *ubuf, size_t sz, loff_t *ppos, struct nss_stats_info *stats_info, uint16_t max)
44{
45 int32_t i;
46 size_t size_al = (NSS_STATS_MAX_STR_LENGTH + 12) * max;
47 size_t size_wr = 0;
48 ssize_t bytes_read = 0;
49
50 char *lbuf = kzalloc(size_al, GFP_KERNEL);
51 if (!lbuf) {
52 nss_warning("Could not allocate memory for local statistics buffer");
53 return 0;
54 }
55
56 for (i = 0; i < max; i++) {
57 /*
58 * Print what we have but don't exceed the buffer.
59 */
60 if (size_wr >= size_al) {
61 nss_info_always("Buffer overflowed.\n");
62 break;
63 }
64 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
65 "\t%d , %s\n", stats_info[i].stats_type, stats_info[i].stats_name);
66 }
67
68 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
69 kfree(lbuf);
70
71 return bytes_read;
72}
73
74/*
75 * nss_strings_create_dentry()
76 * Create strings debug entry for subsystem.
77 */
78void nss_strings_create_dentry(char *name, const struct file_operations *ops)
79{
80 if (!nss_top_main.strings_dentry || !debugfs_create_file(name, 0400, nss_top_main.strings_dentry, &nss_top_main, ops)) {
81 nss_warning("Failed to create debug entry for subsystem %s\n", name);
82 }
83}
84
85/*
86 * nss_strings_open()
87 */
88int nss_strings_open(struct inode *inode, struct file *filp)
89{
90 struct nss_strings_data *data = NULL;
91
92 data = kzalloc(sizeof(struct nss_strings_data), GFP_KERNEL);
93 if (!data) {
94 return -ENOMEM;
95 }
96 data->if_num = NSS_DYNAMIC_IF_START;
97 data->nss_ctx = (struct nss_ctx_instance *)(inode->i_private);
98 filp->private_data = data;
99
100 return 0;
101}
102
103/*
104 * nss_strings_release()
105 */
106int nss_strings_release(struct inode *inode, struct file *filp)
107{
108 struct nss_strings_data *data = filp->private_data;
109
110 if (data) {
111 kfree(data);
112 }
113
114 return 0;
115}
116
117/*
118 * nss_common_node_stats_strings_read()
119 * Read common node statistics names.
120 */
121static ssize_t nss_common_node_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
122{
123 return nss_strings_print(ubuf, sz, ppos, nss_strings_stats_node, NSS_STATS_NODE_MAX);
124}
125
126/*
127 * nss_common_node_stats_strings_ops
128 */
129NSS_STRINGS_DECLARE_FILE_OPERATIONS(common_node_stats);
130
131/*
132 * nss_strings_init()
133 * Enable NSS statistics
134 */
135void nss_strings_init(void)
136{
137 nss_top_main.strings_dentry = debugfs_create_dir("strings", nss_top_main.top_dentry);
138 if (unlikely(nss_top_main.strings_dentry == NULL)) {
139 nss_warning("Failed to create strings directory in debugfs/qca-nss-drv");
140 return;
141 }
142
143 /*
144 * Common node statistics
145 */
146 nss_strings_create_dentry("common_node_stats", &nss_common_node_stats_strings_ops);
147}