1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <sys/types.h>
28 #include <sys/errno.h>
29 #include <sys/param.h>
30 #include <sys/stream.h>
31 #include <sys/strsubr.h>
32 #include <sys/kmem.h>
33 #include <sys/ksynch.h>
34 #include <sys/stat.h>
35 #include <sys/vgen_stats.h>
36
37 /*
38 * A set of common kstat statistics related functions that are
39 * used by both vnet and vsw drivers to maintain the statistics specific
40 * LDCs.
41 */
42
43 /*
44 * Setup kstats for the LDC statistics.
45 * NOTE: the synchronization for the statistics is the
46 * responsibility of the caller.
47 */
48 kstat_t *
vgen_setup_kstats(char * ks_mod,int instance,char * ks_name,vgen_stats_t * statsp)49 vgen_setup_kstats(char *ks_mod, int instance,
50 char *ks_name, vgen_stats_t *statsp)
51 {
52 kstat_t *ksp;
53 vgen_kstats_t *ldckp;
54 size_t size;
55
56 size = sizeof (vgen_kstats_t) / sizeof (kstat_named_t);
57 ksp = kstat_create(ks_mod, instance, ks_name, "net", KSTAT_TYPE_NAMED,
58 size, 0);
59 if (ksp == NULL) {
60 return (NULL);
61 }
62
63 ldckp = (vgen_kstats_t *)ksp->ks_data;
64 kstat_named_init(&ldckp->ipackets, "ipackets",
65 KSTAT_DATA_ULONG);
66 kstat_named_init(&ldckp->ipackets64, "ipackets64",
67 KSTAT_DATA_ULONGLONG);
68 kstat_named_init(&ldckp->ierrors, "ierrors",
69 KSTAT_DATA_ULONG);
70 kstat_named_init(&ldckp->opackets, "opackets",
71 KSTAT_DATA_ULONG);
72 kstat_named_init(&ldckp->opackets64, "opackets64",
73 KSTAT_DATA_ULONGLONG);
74 kstat_named_init(&ldckp->oerrors, "oerrors",
75 KSTAT_DATA_ULONG);
76
77
78 /* MIB II kstat variables */
79 kstat_named_init(&ldckp->rbytes, "rbytes",
80 KSTAT_DATA_ULONG);
81 kstat_named_init(&ldckp->rbytes64, "rbytes64",
82 KSTAT_DATA_ULONGLONG);
83 kstat_named_init(&ldckp->obytes, "obytes",
84 KSTAT_DATA_ULONG);
85 kstat_named_init(&ldckp->obytes64, "obytes64",
86 KSTAT_DATA_ULONGLONG);
87 kstat_named_init(&ldckp->multircv, "multircv",
88 KSTAT_DATA_ULONG);
89 kstat_named_init(&ldckp->multixmt, "multixmt",
90 KSTAT_DATA_ULONG);
91 kstat_named_init(&ldckp->brdcstrcv, "brdcstrcv",
92 KSTAT_DATA_ULONG);
93 kstat_named_init(&ldckp->brdcstxmt, "brdcstxmt",
94 KSTAT_DATA_ULONG);
95 kstat_named_init(&ldckp->norcvbuf, "norcvbuf",
96 KSTAT_DATA_ULONG);
97 kstat_named_init(&ldckp->noxmtbuf, "noxmtbuf",
98 KSTAT_DATA_ULONG);
99
100 /* Tx stats */
101 kstat_named_init(&ldckp->tx_no_desc, "tx_no_desc",
102 KSTAT_DATA_ULONG);
103 kstat_named_init(&ldckp->tx_qfull, "tx_qfull",
104 KSTAT_DATA_ULONG);
105 kstat_named_init(&ldckp->tx_pri_fail, "tx_pri_fail",
106 KSTAT_DATA_ULONG);
107 kstat_named_init(&ldckp->tx_pri_packets, "tx_pri_packets",
108 KSTAT_DATA_ULONGLONG);
109 kstat_named_init(&ldckp->tx_pri_bytes, "tx_pri_bytes",
110 KSTAT_DATA_ULONGLONG);
111
112 /* Rx stats */
113 kstat_named_init(&ldckp->rx_allocb_fail, "rx_allocb_fail",
114 KSTAT_DATA_ULONG);
115 kstat_named_init(&ldckp->rx_vio_allocb_fail, "rx_vio_allocb_fail",
116 KSTAT_DATA_ULONG);
117 kstat_named_init(&ldckp->rx_lost_pkts, "rx_lost_pkts",
118 KSTAT_DATA_ULONG);
119 kstat_named_init(&ldckp->rx_pri_fail, "rx_pri_fail",
120 KSTAT_DATA_ULONG);
121 kstat_named_init(&ldckp->rx_pri_packets, "rx_pri_packets",
122 KSTAT_DATA_ULONGLONG);
123 kstat_named_init(&ldckp->rx_pri_bytes, "rx_pri_bytes",
124 KSTAT_DATA_ULONGLONG);
125
126 /* Interrupt stats */
127 kstat_named_init(&ldckp->callbacks, "callbacks",
128 KSTAT_DATA_ULONG);
129 kstat_named_init(&ldckp->dring_data_msgs_sent, "dring_data_msgs_sent",
130 KSTAT_DATA_ULONG);
131 kstat_named_init(&ldckp->dring_data_acks_rcvd, "dring_data_acks_rcvd",
132 KSTAT_DATA_ULONG);
133 kstat_named_init(&ldckp->dring_stopped_acks_rcvd,
134 "dring_stopped_acks_rcvd", KSTAT_DATA_ULONG);
135 kstat_named_init(&ldckp->dring_data_msgs_rcvd, "dring_data_msgs_rcvd",
136 KSTAT_DATA_ULONG);
137 kstat_named_init(&ldckp->dring_data_acks_sent, "dring_data_acks_sent",
138 KSTAT_DATA_ULONG);
139 kstat_named_init(&ldckp->dring_stopped_acks_sent,
140 "dring_stopped_acks_sent", KSTAT_DATA_ULONG);
141 kstat_named_init(&ldckp->dring_mode, "dring_mode", KSTAT_DATA_ULONG);
142
143 ksp->ks_update = vgen_kstat_update;
144 ksp->ks_private = (void *)statsp;
145 kstat_install(ksp);
146 return (ksp);
147 }
148
149 /*
150 * Destroy kstats.
151 */
152 void
vgen_destroy_kstats(kstat_t * ksp)153 vgen_destroy_kstats(kstat_t *ksp)
154 {
155 if (ksp != NULL)
156 kstat_delete(ksp);
157 }
158
159 /*
160 * Update the kstats.
161 */
162 int
vgen_kstat_update(kstat_t * ksp,int rw)163 vgen_kstat_update(kstat_t *ksp, int rw)
164 {
165 vgen_stats_t *statsp;
166 vgen_kstats_t *ldckp;
167
168 statsp = (vgen_stats_t *)ksp->ks_private;
169 ldckp = (vgen_kstats_t *)ksp->ks_data;
170
171 if (rw == KSTAT_READ) {
172 ldckp->ipackets.value.ul = (uint32_t)statsp->ipackets +
173 (uint32_t)statsp->rx_pri_packets;
174 ldckp->ipackets64.value.ull = statsp->ipackets +
175 statsp->rx_pri_packets;
176 ldckp->ierrors.value.ul = statsp->ierrors;
177 ldckp->opackets.value.ul = (uint32_t)statsp->opackets +
178 (uint32_t)statsp->tx_pri_packets;
179 ldckp->opackets64.value.ull = statsp->opackets +
180 statsp->tx_pri_packets;
181 ldckp->oerrors.value.ul = statsp->oerrors;
182
183 /*
184 * MIB II kstat variables
185 */
186 ldckp->rbytes.value.ul = (uint32_t)statsp->rbytes +
187 (uint32_t)statsp->rx_pri_bytes;
188 ldckp->rbytes64.value.ull = statsp->rbytes +
189 statsp->rx_pri_bytes;
190 ldckp->obytes.value.ul = (uint32_t)statsp->obytes +
191 (uint32_t)statsp->tx_pri_bytes;
192 ldckp->obytes64.value.ull = statsp->obytes +
193 statsp->tx_pri_bytes;
194 ldckp->multircv.value.ul = statsp->multircv;
195 ldckp->multixmt.value.ul = statsp->multixmt;
196 ldckp->brdcstrcv.value.ul = statsp->brdcstrcv;
197 ldckp->brdcstxmt.value.ul = statsp->brdcstxmt;
198 ldckp->norcvbuf.value.ul = statsp->norcvbuf;
199 ldckp->noxmtbuf.value.ul = statsp->noxmtbuf;
200
201 ldckp->tx_no_desc.value.ul = statsp->tx_no_desc;
202 ldckp->tx_qfull.value.ul = statsp->tx_qfull;
203 ldckp->tx_pri_fail.value.ul = statsp->tx_pri_fail;
204 ldckp->tx_pri_packets.value.ull = statsp->tx_pri_packets;
205 ldckp->tx_pri_bytes.value.ull = statsp->tx_pri_bytes;
206
207 ldckp->rx_allocb_fail.value.ul = statsp->rx_allocb_fail;
208 ldckp->rx_vio_allocb_fail.value.ul = statsp->rx_vio_allocb_fail;
209 ldckp->rx_lost_pkts.value.ul = statsp->rx_lost_pkts;
210 ldckp->rx_pri_fail.value.ul = statsp->rx_pri_fail;
211 ldckp->rx_pri_packets.value.ull = statsp->rx_pri_packets;
212 ldckp->rx_pri_bytes.value.ull = statsp->rx_pri_bytes;
213
214 ldckp->callbacks.value.ul = statsp->callbacks;
215
216 ldckp->dring_data_msgs_sent.value.ul =
217 statsp->dring_data_msgs_sent;
218 ldckp->dring_data_acks_rcvd.value.ul =
219 statsp->dring_data_acks_rcvd;
220 ldckp->dring_stopped_acks_rcvd.value.ul =
221 statsp->dring_stopped_acks_rcvd;
222 ldckp->dring_data_msgs_rcvd.value.ul =
223 statsp->dring_data_msgs_rcvd;
224 ldckp->dring_data_acks_sent.value.ul =
225 statsp->dring_data_acks_sent;
226 ldckp->dring_stopped_acks_sent.value.ul =
227 statsp->dring_stopped_acks_sent;
228 ldckp->dring_mode.value.ul = statsp->dring_mode;
229 } else {
230 statsp->ipackets = ldckp->ipackets64.value.ull;
231 statsp->ierrors = ldckp->ierrors.value.ul;
232 statsp->opackets = ldckp->opackets64.value.ull;
233 statsp->oerrors = ldckp->oerrors.value.ul;
234
235 /*
236 * MIB II kstat variables
237 */
238 statsp->rbytes = ldckp->rbytes64.value.ull;
239 statsp->obytes = ldckp->obytes64.value.ull;
240 statsp->multircv = ldckp->multircv.value.ul;
241 statsp->multixmt = ldckp->multixmt.value.ul;
242 statsp->brdcstrcv = ldckp->brdcstrcv.value.ul;
243 statsp->brdcstxmt = ldckp->brdcstxmt.value.ul;
244 statsp->norcvbuf = ldckp->norcvbuf.value.ul;
245 statsp->noxmtbuf = ldckp->noxmtbuf.value.ul;
246
247 statsp->tx_no_desc = ldckp->tx_no_desc.value.ul;
248 statsp->tx_qfull = ldckp->tx_qfull.value.ul;
249 statsp->tx_pri_fail = ldckp->tx_pri_fail.value.ul;
250 statsp->tx_pri_packets = ldckp->tx_pri_packets.value.ull;
251 statsp->tx_pri_bytes = ldckp->tx_pri_bytes.value.ull;
252
253 statsp->rx_allocb_fail = ldckp->rx_allocb_fail.value.ul;
254 statsp->rx_vio_allocb_fail = ldckp->rx_vio_allocb_fail.value.ul;
255 statsp->rx_lost_pkts = ldckp->rx_lost_pkts.value.ul;
256 statsp->rx_pri_fail = ldckp->rx_pri_fail.value.ul;
257 statsp->rx_pri_packets = ldckp->rx_pri_packets.value.ull;
258 statsp->rx_pri_bytes = ldckp->rx_pri_bytes.value.ull;
259
260 statsp->callbacks = ldckp->callbacks.value.ul;
261 statsp->dring_data_msgs_sent =
262 ldckp->dring_data_msgs_sent.value.ul;
263 statsp->dring_data_acks_rcvd =
264 ldckp->dring_data_acks_rcvd.value.ul;
265 statsp->dring_stopped_acks_rcvd =
266 ldckp->dring_stopped_acks_rcvd.value.ul;
267 statsp->dring_data_msgs_rcvd =
268 ldckp->dring_data_msgs_rcvd.value.ul;
269 statsp->dring_data_acks_sent =
270 ldckp->dring_data_acks_sent.value.ul;
271 statsp->dring_stopped_acks_sent =
272 ldckp->dring_stopped_acks_sent.value.ul;
273 statsp->dring_mode = ldckp->dring_mode.value.ul;
274 }
275
276 return (0);
277 }
278