xref: /illumos-gate/usr/src/uts/common/io/mac/mac_stat.c (revision 10597944279b73141546abca67a8e947810e5bb2)
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  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  * Copyright 2018 Joyent, Inc.
25  * Copyright 2025 Oxide Computer Company
26  */
27 
28 /*
29  * MAC Services Module
30  */
31 
32 #include <sys/types.h>
33 #include <sys/sysmacros.h>
34 #include <sys/stream.h>
35 #include <sys/kstat.h>
36 #include <sys/mac.h>
37 #include <sys/mac_impl.h>
38 #include <sys/mac_client_impl.h>
39 #include <sys/mac_stat.h>
40 #include <sys/mac_soft_ring.h>
41 #include <sys/vlan.h>
42 
43 #define	MAC_KSTAT_NAME	"mac"
44 #define	MAC_KSTAT_CLASS	"net"
45 
46 enum mac_stat {
47 	MAC_STAT_LCL,
48 	MAC_STAT_LCLBYTES,
49 	MAC_STAT_INTRS,
50 	MAC_STAT_INTRBYTES,
51 	MAC_STAT_POLLS,
52 	MAC_STAT_POLLBYTES,
53 	MAC_STAT_RXSDROPS,
54 	MAC_STAT_CHU10,
55 	MAC_STAT_CH10T50,
56 	MAC_STAT_CHO50,
57 	MAC_STAT_BLOCK,
58 	MAC_STAT_UNBLOCK,
59 	MAC_STAT_TXSDROPS,
60 	MAC_STAT_TX_ERRORS,
61 	MAC_STAT_MACSPOOFED,
62 	MAC_STAT_IPSPOOFED,
63 	MAC_STAT_DHCPSPOOFED,
64 	MAC_STAT_RESTRICTED,
65 	MAC_STAT_DHCPDROPPED,
66 	MAC_STAT_MULTIRCVBYTES,
67 	MAC_STAT_BRDCSTRCVBYTES,
68 	MAC_STAT_MULTIXMTBYTES,
69 	MAC_STAT_BRDCSTXMTBYTES
70 };
71 
72 static mac_stat_info_t	i_mac_si[] = {
73 	{ MAC_STAT_IFSPEED,	"ifspeed",	KSTAT_DATA_UINT64,	0 },
74 	{ MAC_STAT_MULTIRCV,	"multircv",	KSTAT_DATA_UINT32,	0 },
75 	{ MAC_STAT_BRDCSTRCV,	"brdcstrcv",	KSTAT_DATA_UINT32,	0 },
76 	{ MAC_STAT_MULTIXMT,	"multixmt",	KSTAT_DATA_UINT32,	0 },
77 	{ MAC_STAT_BRDCSTXMT,	"brdcstxmt",	KSTAT_DATA_UINT32,	0 },
78 	{ MAC_STAT_NORCVBUF,	"norcvbuf",	KSTAT_DATA_UINT32,	0 },
79 	{ MAC_STAT_IERRORS,	"ierrors",	KSTAT_DATA_UINT32,	0 },
80 	{ MAC_STAT_UNKNOWNS,	"unknowns",	KSTAT_DATA_UINT32,	0 },
81 	{ MAC_STAT_NOXMTBUF,	"noxmtbuf",	KSTAT_DATA_UINT32,	0 },
82 	{ MAC_STAT_OERRORS,	"oerrors",	KSTAT_DATA_UINT32,	0 },
83 	{ MAC_STAT_COLLISIONS,	"collisions",	KSTAT_DATA_UINT32,	0 },
84 	{ MAC_STAT_UNDERFLOWS,	"uflo",		KSTAT_DATA_UINT32,	0 },
85 	{ MAC_STAT_OVERFLOWS,	"oflo",		KSTAT_DATA_UINT32,	0 },
86 	{ MAC_STAT_RBYTES,	"rbytes",	KSTAT_DATA_UINT32,	0 },
87 	{ MAC_STAT_IPACKETS,	"ipackets",	KSTAT_DATA_UINT32,	0 },
88 	{ MAC_STAT_OBYTES,	"obytes",	KSTAT_DATA_UINT32,	0 },
89 	{ MAC_STAT_OPACKETS,	"opackets",	KSTAT_DATA_UINT32,	0 },
90 	{ MAC_STAT_RBYTES,	"rbytes64",	KSTAT_DATA_UINT64,	0 },
91 	{ MAC_STAT_IPACKETS,	"ipackets64",	KSTAT_DATA_UINT64,	0 },
92 	{ MAC_STAT_OBYTES,	"obytes64",	KSTAT_DATA_UINT64,	0 },
93 	{ MAC_STAT_OPACKETS,	"opackets64",	KSTAT_DATA_UINT64,	0 }
94 };
95 #define	MAC_NKSTAT \
96 	(sizeof (i_mac_si) / sizeof (mac_stat_info_t))
97 
98 static mac_stat_info_t	i_mac_mod_si[] = {
99 	{ MAC_STAT_LINK_STATE,	"link_state",	KSTAT_DATA_UINT32,
100 	    (uint64_t)LINK_STATE_UNKNOWN },
101 	{ MAC_STAT_LINK_UP,	"link_up",	KSTAT_DATA_UINT32,	0 },
102 	{ MAC_STAT_PROMISC,	"promisc",	KSTAT_DATA_UINT32,	0 }
103 };
104 #define	MAC_MOD_NKSTAT \
105 	(sizeof (i_mac_mod_si) / sizeof (mac_stat_info_t))
106 
107 #define	MAC_MOD_KSTAT_OFFSET	0
108 #define	MAC_KSTAT_OFFSET	MAC_MOD_KSTAT_OFFSET + MAC_MOD_NKSTAT
109 #define	MAC_TYPE_KSTAT_OFFSET	MAC_KSTAT_OFFSET + MAC_NKSTAT
110 
111 /*
112  * Definitions for per rx ring statistics
113  */
114 static mac_stat_info_t  i_mac_rx_ring_si[] = {
115 	{ MAC_STAT_RBYTES,	"rbytes",	KSTAT_DATA_UINT64,	0},
116 	{ MAC_STAT_IPACKETS,	"ipackets",	KSTAT_DATA_UINT64,	0},
117 	{ MAC_STAT_HDROPS,	"hdrops",	KSTAT_DATA_UINT64,	0}
118 };
119 #define	MAC_RX_RING_NKSTAT \
120 	(sizeof (i_mac_rx_ring_si) / sizeof (mac_stat_info_t))
121 
122 /*
123  * Definitions for per tx ring statistics
124  */
125 static mac_stat_info_t  i_mac_tx_ring_si[] = {
126 	{ MAC_STAT_OBYTES,	"obytes",	KSTAT_DATA_UINT64,	0},
127 	{ MAC_STAT_OPACKETS,	"opackets",	KSTAT_DATA_UINT64,	0}
128 };
129 #define	MAC_TX_RING_NKSTAT \
130 	(sizeof (i_mac_tx_ring_si) / sizeof (mac_stat_info_t))
131 
132 
133 /*
134  * Definitions for per software lane tx statistics
135  */
136 static mac_stat_info_t  i_mac_tx_swlane_si[] = {
137 	{ MAC_STAT_OBYTES,	"obytes",	KSTAT_DATA_UINT64,	0},
138 	{ MAC_STAT_OPACKETS,	"opackets",	KSTAT_DATA_UINT64,	0},
139 	{ MAC_STAT_OERRORS,	"oerrors",	KSTAT_DATA_UINT64,	0},
140 	{ MAC_STAT_BLOCK,	"blockcnt",	KSTAT_DATA_UINT64,	0},
141 	{ MAC_STAT_UNBLOCK,	"unblockcnt",	KSTAT_DATA_UINT64,	0},
142 	{ MAC_STAT_TXSDROPS,	"txsdrops",	KSTAT_DATA_UINT64,	0}
143 };
144 #define	MAC_TX_SWLANE_NKSTAT \
145 	(sizeof (i_mac_tx_swlane_si) / sizeof (mac_stat_info_t))
146 
147 /*
148  * Definitions for per software lane rx statistics
149  */
150 static mac_stat_info_t  i_mac_rx_swlane_si[] = {
151 	{ MAC_STAT_IPACKETS,	"ipackets",	KSTAT_DATA_UINT64,	0},
152 	{ MAC_STAT_RBYTES,	"rbytes",	KSTAT_DATA_UINT64,	0},
153 	{ MAC_STAT_LCL,		"local",	KSTAT_DATA_UINT64,	0},
154 	{ MAC_STAT_LCLBYTES,	"localbytes",	KSTAT_DATA_UINT64,	0},
155 	{ MAC_STAT_INTRS,	"intrs",	KSTAT_DATA_UINT64,	0},
156 	{ MAC_STAT_INTRBYTES,	"intrbytes",	KSTAT_DATA_UINT64,	0},
157 	{ MAC_STAT_RXSDROPS,	"rxsdrops",	KSTAT_DATA_UINT64,	0}
158 };
159 #define	MAC_RX_SWLANE_NKSTAT \
160 	(sizeof (i_mac_rx_swlane_si) / sizeof (mac_stat_info_t))
161 
162 /*
163  * Definitions for per hardware lane rx statistics
164  */
165 static mac_stat_info_t  i_mac_rx_hwlane_si[] = {
166 	{ MAC_STAT_IPACKETS,	"ipackets",	KSTAT_DATA_UINT64,	0},
167 	{ MAC_STAT_RBYTES,	"rbytes",	KSTAT_DATA_UINT64,	0},
168 	{ MAC_STAT_INTRS,	"intrs",	KSTAT_DATA_UINT64,	0},
169 	{ MAC_STAT_INTRBYTES,	"intrbytes",	KSTAT_DATA_UINT64,	0},
170 	{ MAC_STAT_POLLS,	"polls",	KSTAT_DATA_UINT64,	0},
171 	{ MAC_STAT_POLLBYTES,	"pollbytes",	KSTAT_DATA_UINT64,	0},
172 	{ MAC_STAT_RXSDROPS,	"rxsdrops",	KSTAT_DATA_UINT64,	0},
173 	{ MAC_STAT_CHU10,	"chainunder10",	KSTAT_DATA_UINT64,	0},
174 	{ MAC_STAT_CH10T50,	"chain10to50",	KSTAT_DATA_UINT64,	0},
175 	{ MAC_STAT_CHO50,	"chainover50",	KSTAT_DATA_UINT64,	0}
176 };
177 #define	MAC_RX_HWLANE_NKSTAT \
178 	(sizeof (i_mac_rx_hwlane_si) / sizeof (mac_stat_info_t))
179 
180 /*
181  * Definitions for misc statistics
182  */
183 static mac_stat_info_t  i_mac_misc_si[] = {
184 	{ MAC_STAT_MULTIRCV,	"multircv",	KSTAT_DATA_UINT64,	0},
185 	{ MAC_STAT_BRDCSTRCV,	"brdcstrcv",	KSTAT_DATA_UINT64,	0},
186 	{ MAC_STAT_MULTIXMT,	"multixmt",	KSTAT_DATA_UINT64,	0},
187 	{ MAC_STAT_BRDCSTXMT,	"brdcstxmt",	KSTAT_DATA_UINT64,	0},
188 	{ MAC_STAT_MULTIRCVBYTES, "multircvbytes",   KSTAT_DATA_UINT64,	0},
189 	{ MAC_STAT_BRDCSTRCVBYTES, "brdcstrcvbytes", KSTAT_DATA_UINT64,	0},
190 	{ MAC_STAT_MULTIXMTBYTES,  "multixmtbytes",  KSTAT_DATA_UINT64,	0},
191 	{ MAC_STAT_BRDCSTXMTBYTES, "brdcstxmtbytes", KSTAT_DATA_UINT64,	0},
192 	{ MAC_STAT_TX_ERRORS,	"txerrors",	KSTAT_DATA_UINT64,	0},
193 	{ MAC_STAT_MACSPOOFED,	"macspoofed",	KSTAT_DATA_UINT64,	0},
194 	{ MAC_STAT_IPSPOOFED,	"ipspoofed",	KSTAT_DATA_UINT64,	0},
195 	{ MAC_STAT_DHCPSPOOFED,	"dhcpspoofed",	KSTAT_DATA_UINT64,	0},
196 	{ MAC_STAT_RESTRICTED,	"restricted",	KSTAT_DATA_UINT64,	0},
197 	{ MAC_STAT_DHCPDROPPED,	"dhcpdropped",	KSTAT_DATA_UINT64,	0},
198 	{ MAC_STAT_IPACKETS,	"ipackets",	KSTAT_DATA_UINT64,	0},
199 	{ MAC_STAT_RBYTES,	"rbytes",	KSTAT_DATA_UINT64,	0},
200 	{ MAC_STAT_LCL,		"local",	KSTAT_DATA_UINT64,	0},
201 	{ MAC_STAT_LCLBYTES,	"localbytes",	KSTAT_DATA_UINT64,	0},
202 	{ MAC_STAT_INTRS,	"intrs",	KSTAT_DATA_UINT64,	0},
203 	{ MAC_STAT_INTRBYTES,	"intrbytes",	KSTAT_DATA_UINT64,	0},
204 	{ MAC_STAT_POLLS,	"polls",	KSTAT_DATA_UINT64,	0},
205 	{ MAC_STAT_POLLBYTES,	"pollbytes",	KSTAT_DATA_UINT64,	0},
206 	{ MAC_STAT_RXSDROPS,	"rxsdrops",	KSTAT_DATA_UINT64,	0},
207 	{ MAC_STAT_CHU10,	"chainunder10",	KSTAT_DATA_UINT64,	0},
208 	{ MAC_STAT_CH10T50,	"chain10to50",	KSTAT_DATA_UINT64,	0},
209 	{ MAC_STAT_CHO50,	"chainover50",	KSTAT_DATA_UINT64,	0},
210 	{ MAC_STAT_OBYTES,	"obytes",	KSTAT_DATA_UINT64,	0},
211 	{ MAC_STAT_OPACKETS,	"opackets",	KSTAT_DATA_UINT64,	0},
212 	{ MAC_STAT_OERRORS,	"oerrors",	KSTAT_DATA_UINT64,	0},
213 	{ MAC_STAT_BLOCK,	"blockcnt",	KSTAT_DATA_UINT64,	0},
214 	{ MAC_STAT_UNBLOCK,	"unblockcnt",	KSTAT_DATA_UINT64,	0},
215 	{ MAC_STAT_TXSDROPS,	"txsdrops",	KSTAT_DATA_UINT64,	0}
216 };
217 #define	MAC_SUMMARY_NKSTAT \
218 	(sizeof (i_mac_misc_si) / sizeof (mac_stat_info_t))
219 
220 /*
221  * Definitions for per hardware lane tx statistics
222  */
223 static mac_stat_info_t  i_mac_tx_hwlane_si[] = {
224 	{ MAC_STAT_OBYTES,	"obytes",	KSTAT_DATA_UINT64,	0},
225 	{ MAC_STAT_OPACKETS,	"opackets",	KSTAT_DATA_UINT64,	0},
226 	{ MAC_STAT_OERRORS,	"oerrors",	KSTAT_DATA_UINT64,	0},
227 	{ MAC_STAT_BLOCK,	"blockcnt",	KSTAT_DATA_UINT64,	0},
228 	{ MAC_STAT_UNBLOCK,	"unblockcnt",	KSTAT_DATA_UINT64,	0},
229 	{ MAC_STAT_TXSDROPS,	"txsdrops",	KSTAT_DATA_UINT64,	0}
230 };
231 #define	MAC_TX_HWLANE_NKSTAT \
232 	(sizeof (i_mac_tx_hwlane_si) / sizeof (mac_stat_info_t))
233 
234 /*
235  * Definitions for per fanout rx statistics
236  */
237 static mac_stat_info_t  i_mac_rx_fanout_si[] = {
238 	{ MAC_STAT_RBYTES,	"rbytes",	KSTAT_DATA_UINT64,	0},
239 	{ MAC_STAT_IPACKETS,	"ipackets",	KSTAT_DATA_UINT64,	0},
240 };
241 #define	MAC_RX_FANOUT_NKSTAT \
242 	(sizeof (i_mac_rx_fanout_si) / sizeof (mac_stat_info_t))
243 
244 /*
245  * Private functions.
246  */
247 
248 typedef struct {
249 	uint_t	si_offset;
250 } stat_info_t;
251 
252 #define	RX_SRS_STAT_OFF(f)	(offsetof(mac_rx_stats_t, f))
253 static stat_info_t rx_srs_stats_list[] = {
254 	{RX_SRS_STAT_OFF(mrs_lclbytes)},
255 	{RX_SRS_STAT_OFF(mrs_lclcnt)},
256 	{RX_SRS_STAT_OFF(mrs_pollcnt)},
257 	{RX_SRS_STAT_OFF(mrs_pollbytes)},
258 	{RX_SRS_STAT_OFF(mrs_intrcnt)},
259 	{RX_SRS_STAT_OFF(mrs_intrbytes)},
260 	{RX_SRS_STAT_OFF(mrs_sdrops)},
261 	{RX_SRS_STAT_OFF(mrs_chaincntundr10)},
262 	{RX_SRS_STAT_OFF(mrs_chaincnt10to50)},
263 	{RX_SRS_STAT_OFF(mrs_chaincntover50)},
264 	{RX_SRS_STAT_OFF(mrs_ierrors)}
265 };
266 #define	RX_SRS_STAT_SIZE		\
267 	(sizeof (rx_srs_stats_list) / sizeof (stat_info_t))
268 
269 #define	TX_SOFTRING_STAT_OFF(f)	(offsetof(mac_tx_stats_t, f))
270 static stat_info_t tx_softring_stats_list[] = {
271 	{TX_SOFTRING_STAT_OFF(mts_obytes)},
272 	{TX_SOFTRING_STAT_OFF(mts_opackets)},
273 	{TX_SOFTRING_STAT_OFF(mts_oerrors)},
274 	{TX_SOFTRING_STAT_OFF(mts_blockcnt)},
275 	{TX_SOFTRING_STAT_OFF(mts_unblockcnt)},
276 	{TX_SOFTRING_STAT_OFF(mts_sdrops)},
277 };
278 #define	TX_SOFTRING_STAT_SIZE		\
279 	(sizeof (tx_softring_stats_list) / sizeof (stat_info_t))
280 
281 static void
i_mac_add_stats(void * sum,void * op1,void * op2,stat_info_t stats_list[],uint_t size)282 i_mac_add_stats(void *sum, void *op1, void *op2,
283     stat_info_t stats_list[], uint_t size)
284 {
285 	int	i;
286 
287 	for (i = 0; i < size; i++) {
288 		uint64_t *op1_val = (uint64_t *)
289 		    ((uchar_t *)op1 + stats_list[i].si_offset);
290 		uint64_t *op2_val = (uint64_t *)
291 		    ((uchar_t *)op2 + stats_list[i].si_offset);
292 		uint64_t *sum_val = (uint64_t *)
293 		    ((uchar_t *)sum + stats_list[i].si_offset);
294 
295 		*sum_val =  *op1_val + *op2_val;
296 	}
297 }
298 
299 static int
i_mac_driver_stat_update(kstat_t * ksp,int rw)300 i_mac_driver_stat_update(kstat_t *ksp, int rw)
301 {
302 	mac_impl_t	*mip = ksp->ks_private;
303 	kstat_named_t	*knp = ksp->ks_data;
304 	uint_t		i;
305 	uint64_t	val;
306 	mac_stat_info_t	*msi;
307 	uint_t		msi_index;
308 
309 	if (rw != KSTAT_READ)
310 		return (EACCES);
311 
312 	for (i = 0; i < mip->mi_kstat_count; i++, msi_index++) {
313 		if (i == MAC_MOD_KSTAT_OFFSET) {
314 			msi_index = 0;
315 			msi = i_mac_mod_si;
316 		} else if (i == MAC_KSTAT_OFFSET) {
317 			msi_index = 0;
318 			msi = i_mac_si;
319 		} else if (i == MAC_TYPE_KSTAT_OFFSET) {
320 			msi_index = 0;
321 			msi = mip->mi_type->mt_stats;
322 		}
323 
324 		val = mac_stat_get((mac_handle_t)mip, msi[msi_index].msi_stat);
325 		switch (msi[msi_index].msi_type) {
326 		case KSTAT_DATA_UINT64:
327 			knp->value.ui64 = val;
328 			break;
329 		case KSTAT_DATA_UINT32:
330 			knp->value.ui32 = (uint32_t)val;
331 			break;
332 		default:
333 			ASSERT(B_FALSE);
334 			break;
335 		}
336 
337 		knp++;
338 	}
339 
340 	return (0);
341 }
342 
343 static void
i_mac_kstat_init(kstat_named_t * knp,mac_stat_info_t * si,uint_t count)344 i_mac_kstat_init(kstat_named_t *knp, mac_stat_info_t *si, uint_t count)
345 {
346 	int i;
347 	for (i = 0; i < count; i++) {
348 		kstat_named_init(knp, si[i].msi_name, si[i].msi_type);
349 		knp++;
350 	}
351 }
352 
353 static int
i_mac_stat_update(kstat_t * ksp,int rw,uint64_t (* fn)(void *,uint_t),mac_stat_info_t * msi,uint_t count)354 i_mac_stat_update(kstat_t *ksp, int rw, uint64_t (*fn)(void *, uint_t),
355     mac_stat_info_t *msi, uint_t count)
356 {
357 	kstat_named_t	*knp = ksp->ks_data;
358 	uint_t		i;
359 	uint64_t	val;
360 
361 	if (rw != KSTAT_READ)
362 		return (EACCES);
363 
364 	for (i = 0; i < count; i++) {
365 		val = fn(ksp->ks_private, msi[i].msi_stat);
366 
367 		switch (msi[i].msi_type) {
368 		case KSTAT_DATA_UINT64:
369 			knp->value.ui64 = val;
370 			break;
371 		case KSTAT_DATA_UINT32:
372 			knp->value.ui32 = (uint32_t)val;
373 			break;
374 		default:
375 			ASSERT(B_FALSE);
376 			break;
377 		}
378 		knp++;
379 	}
380 	return (0);
381 }
382 
383 /*
384  * Create kstat with given name - statname, update function - fn
385  * and initialize it with given names - init_stat_info
386  */
387 static kstat_t *
i_mac_stat_create(void * handle,const char * modname,const char * statname,int (* fn)(kstat_t *,int),mac_stat_info_t * init_stat_info,uint_t count)388 i_mac_stat_create(void *handle, const char *modname, const char *statname,
389     int (*fn) (kstat_t *, int),
390     mac_stat_info_t *init_stat_info, uint_t count)
391 {
392 	kstat_t		*ksp;
393 	kstat_named_t	*knp;
394 
395 	ksp = kstat_create(modname, 0, statname, "net",
396 	    KSTAT_TYPE_NAMED, count, 0);
397 
398 	if (ksp == NULL)
399 		return (NULL);
400 
401 	ksp->ks_update = fn;
402 	ksp->ks_private = handle;
403 
404 	knp = (kstat_named_t *)ksp->ks_data;
405 	i_mac_kstat_init(knp, init_stat_info, count);
406 	kstat_install(ksp);
407 
408 	return (ksp);
409 }
410 
411 /*
412  * Per rx ring statistics
413  */
414 uint64_t
mac_rx_ring_stat_get(void * handle,uint_t stat)415 mac_rx_ring_stat_get(void *handle, uint_t stat)
416 {
417 	mac_ring_t		*ring = (mac_ring_t *)handle;
418 	uint64_t		val = 0;
419 
420 	/*
421 	 * XXX Every ring-capable driver must implement an entry point to
422 	 * query per ring statistics. CR 6893122 tracks this work item.
423 	 * Once this bug is fixed, the framework should fail registration
424 	 * for a driver that does not implement this entry point and
425 	 * assert ring->mr_stat != NULL here.
426 	 */
427 	if (ring->mr_stat != NULL)
428 		ring->mr_stat(ring->mr_driver, stat, &val);
429 
430 	return (val);
431 }
432 
433 static int
i_mac_rx_ring_stat_update(kstat_t * ksp,int rw)434 i_mac_rx_ring_stat_update(kstat_t *ksp, int rw)
435 {
436 	return (i_mac_stat_update(ksp, rw, mac_rx_ring_stat_get,
437 	    i_mac_rx_ring_si, MAC_RX_RING_NKSTAT));
438 }
439 
440 static void
i_mac_rx_ring_stat_create(mac_ring_t * ring,const char * modname,const char * statname)441 i_mac_rx_ring_stat_create(mac_ring_t *ring, const char *modname,
442     const char *statname)
443 {
444 	kstat_t		*ksp;
445 
446 	ksp = i_mac_stat_create(ring, modname, statname,
447 	    i_mac_rx_ring_stat_update, i_mac_rx_ring_si, MAC_RX_RING_NKSTAT);
448 
449 	ring->mr_ksp = ksp;
450 }
451 
452 /*
453  * Per tx ring statistics
454  */
455 uint64_t
mac_tx_ring_stat_get(void * handle,uint_t stat)456 mac_tx_ring_stat_get(void *handle, uint_t stat)
457 {
458 	mac_ring_t		*ring = (mac_ring_t *)handle;
459 	uint64_t		val = 0;
460 
461 	/*
462 	 * XXX Every ring-capable driver must implement an entry point to
463 	 * query per ring statistics. CR 6893122 tracks this work item.
464 	 * Once this bug is fixed, the framework should fail registration
465 	 * for a driver that does not implement this entry point and
466 	 * assert ring->mr_stat != NULL here.
467 	 */
468 	if (ring->mr_stat != NULL)
469 		ring->mr_stat(ring->mr_driver, stat, &val);
470 
471 	return (val);
472 }
473 
474 static int
i_mac_tx_ring_stat_update(kstat_t * ksp,int rw)475 i_mac_tx_ring_stat_update(kstat_t *ksp, int rw)
476 {
477 	return (i_mac_stat_update(ksp, rw, mac_tx_ring_stat_get,
478 	    i_mac_tx_ring_si, MAC_TX_RING_NKSTAT));
479 }
480 
481 static void
i_mac_tx_ring_stat_create(mac_ring_t * ring,const char * modname,const char * statname)482 i_mac_tx_ring_stat_create(mac_ring_t *ring, const char *modname,
483     const char *statname)
484 {
485 	kstat_t		*ksp;
486 
487 	ksp = i_mac_stat_create(ring, modname, statname,
488 	    i_mac_tx_ring_stat_update, i_mac_tx_ring_si, MAC_TX_RING_NKSTAT);
489 
490 	ring->mr_ksp = ksp;
491 }
492 
493 /*
494  * Per software lane tx statistics
495  */
496 static uint64_t
i_mac_tx_swlane_stat_get(void * handle,uint_t stat)497 i_mac_tx_swlane_stat_get(void *handle, uint_t stat)
498 {
499 	mac_soft_ring_set_t *mac_srs = (mac_soft_ring_set_t *)handle;
500 	mac_tx_stats_t *mac_tx_stat = &mac_srs->srs_tx.st_stat;
501 
502 	switch (stat) {
503 	case MAC_STAT_OBYTES:
504 		return (mac_tx_stat->mts_obytes);
505 
506 	case MAC_STAT_OPACKETS:
507 		return (mac_tx_stat->mts_opackets);
508 
509 	case MAC_STAT_OERRORS:
510 		return (mac_tx_stat->mts_oerrors);
511 
512 	case MAC_STAT_BLOCK:
513 		return (mac_tx_stat->mts_blockcnt);
514 
515 	case MAC_STAT_UNBLOCK:
516 		return (mac_tx_stat->mts_unblockcnt);
517 
518 	case MAC_STAT_TXSDROPS:
519 		return (mac_tx_stat->mts_sdrops);
520 
521 	default:
522 		return (0);
523 	}
524 }
525 
526 static int
i_mac_tx_swlane_stat_update(kstat_t * ksp,int rw)527 i_mac_tx_swlane_stat_update(kstat_t *ksp, int rw)
528 {
529 	return (i_mac_stat_update(ksp, rw, i_mac_tx_swlane_stat_get,
530 	    i_mac_tx_swlane_si, MAC_TX_SWLANE_NKSTAT));
531 }
532 
533 static void
i_mac_tx_swlane_stat_create(mac_soft_ring_set_t * mac_srs,const char * modname,const char * statname)534 i_mac_tx_swlane_stat_create(mac_soft_ring_set_t *mac_srs, const char *modname,
535     const char *statname)
536 {
537 	kstat_t		*ksp;
538 
539 	ksp = i_mac_stat_create(mac_srs, modname, statname,
540 	    i_mac_tx_swlane_stat_update, i_mac_tx_swlane_si,
541 	    MAC_TX_SWLANE_NKSTAT);
542 
543 	mac_srs->srs_ksp = ksp;
544 }
545 
546 /*
547  * Per software lane rx statistics
548  */
549 static uint64_t
i_mac_rx_swlane_stat_get(void * handle,uint_t stat)550 i_mac_rx_swlane_stat_get(void *handle, uint_t stat)
551 {
552 	mac_soft_ring_set_t	*mac_srs = (mac_soft_ring_set_t *)handle;
553 	mac_rx_stats_t		*mac_rx_stat = &mac_srs->srs_rx.sr_stat;
554 
555 	switch (stat) {
556 	case MAC_STAT_IPACKETS:
557 		return (mac_rx_stat->mrs_intrcnt +
558 		    mac_rx_stat->mrs_lclcnt);
559 
560 	case MAC_STAT_RBYTES:
561 		return (mac_rx_stat->mrs_intrbytes +
562 		    mac_rx_stat->mrs_lclbytes);
563 
564 	case MAC_STAT_LCL:
565 		return (mac_rx_stat->mrs_lclcnt);
566 
567 	case MAC_STAT_LCLBYTES:
568 		return (mac_rx_stat->mrs_lclbytes);
569 
570 	case MAC_STAT_INTRS:
571 		return (mac_rx_stat->mrs_intrcnt);
572 
573 	case MAC_STAT_INTRBYTES:
574 		return (mac_rx_stat->mrs_intrbytes);
575 
576 	case MAC_STAT_RXSDROPS:
577 		return (mac_rx_stat->mrs_sdrops);
578 
579 	default:
580 		return (0);
581 	}
582 }
583 
584 static int
i_mac_rx_swlane_stat_update(kstat_t * ksp,int rw)585 i_mac_rx_swlane_stat_update(kstat_t *ksp, int rw)
586 {
587 	return (i_mac_stat_update(ksp, rw, i_mac_rx_swlane_stat_get,
588 	    i_mac_rx_swlane_si, MAC_RX_SWLANE_NKSTAT));
589 }
590 
591 static void
i_mac_rx_swlane_stat_create(mac_soft_ring_set_t * mac_srs,const char * modname,const char * statname)592 i_mac_rx_swlane_stat_create(mac_soft_ring_set_t *mac_srs, const char *modname,
593     const char *statname)
594 {
595 	kstat_t		*ksp;
596 
597 	ksp = i_mac_stat_create(mac_srs, modname, statname,
598 	    i_mac_rx_swlane_stat_update, i_mac_rx_swlane_si,
599 	    MAC_RX_SWLANE_NKSTAT);
600 
601 	mac_srs->srs_ksp = ksp;
602 }
603 
604 
605 /*
606  * Per hardware lane rx statistics
607  */
608 static uint64_t
i_mac_rx_hwlane_stat_get(void * handle,uint_t stat)609 i_mac_rx_hwlane_stat_get(void *handle, uint_t stat)
610 {
611 	mac_soft_ring_set_t	*mac_srs = (mac_soft_ring_set_t *)handle;
612 	mac_rx_stats_t		*mac_rx_stat = &mac_srs->srs_rx.sr_stat;
613 
614 	switch (stat) {
615 	case MAC_STAT_IPACKETS:
616 		return (mac_rx_stat->mrs_intrcnt +
617 		    mac_rx_stat->mrs_pollcnt);
618 
619 	case MAC_STAT_RBYTES:
620 		return (mac_rx_stat->mrs_intrbytes +
621 		    mac_rx_stat->mrs_pollbytes);
622 
623 	case MAC_STAT_INTRS:
624 		return (mac_rx_stat->mrs_intrcnt);
625 
626 	case MAC_STAT_INTRBYTES:
627 		return (mac_rx_stat->mrs_intrbytes);
628 
629 	case MAC_STAT_POLLS:
630 		return (mac_rx_stat->mrs_pollcnt);
631 
632 	case MAC_STAT_POLLBYTES:
633 		return (mac_rx_stat->mrs_pollbytes);
634 
635 	case MAC_STAT_RXSDROPS:
636 		return (mac_rx_stat->mrs_sdrops);
637 
638 	case MAC_STAT_CHU10:
639 		return (mac_rx_stat->mrs_chaincntundr10);
640 
641 	case MAC_STAT_CH10T50:
642 		return (mac_rx_stat->mrs_chaincnt10to50);
643 
644 	case MAC_STAT_CHO50:
645 		return (mac_rx_stat->mrs_chaincntover50);
646 
647 	default:
648 		return (0);
649 	}
650 }
651 
652 static int
i_mac_rx_hwlane_stat_update(kstat_t * ksp,int rw)653 i_mac_rx_hwlane_stat_update(kstat_t *ksp, int rw)
654 {
655 	return (i_mac_stat_update(ksp, rw, i_mac_rx_hwlane_stat_get,
656 	    i_mac_rx_hwlane_si, MAC_RX_HWLANE_NKSTAT));
657 }
658 
659 static void
i_mac_rx_hwlane_stat_create(mac_soft_ring_set_t * mac_srs,const char * modname,const char * statname)660 i_mac_rx_hwlane_stat_create(mac_soft_ring_set_t *mac_srs, const char *modname,
661     const char *statname)
662 {
663 	kstat_t		*ksp;
664 
665 	ksp = i_mac_stat_create(mac_srs, modname, statname,
666 	    i_mac_rx_hwlane_stat_update, i_mac_rx_hwlane_si,
667 	    MAC_RX_HWLANE_NKSTAT);
668 
669 	mac_srs->srs_ksp = ksp;
670 }
671 
672 
673 /*
674  * Misc statistics
675  *
676  * Counts for
677  *	- Multicast/broadcast Rx/Tx counts
678  *	- Tx errors
679  */
680 static uint64_t
i_mac_misc_stat_get(void * handle,uint_t stat)681 i_mac_misc_stat_get(void *handle, uint_t stat)
682 {
683 	flow_entry_t		*flent = handle;
684 	mac_client_impl_t	*mcip = flent->fe_mcip;
685 	mac_misc_stats_t	*mac_misc_stat = &mcip->mci_misc_stat;
686 	mac_rx_stats_t		*mac_rx_stat;
687 	mac_tx_stats_t		*mac_tx_stat;
688 
689 	mac_rx_stat = &mac_misc_stat->mms_defunctrxlanestats;
690 	mac_tx_stat = &mac_misc_stat->mms_defuncttxlanestats;
691 
692 	switch (stat) {
693 	case MAC_STAT_MULTIRCV:
694 		return (mac_misc_stat->mms_multircv);
695 
696 	case MAC_STAT_BRDCSTRCV:
697 		return (mac_misc_stat->mms_brdcstrcv);
698 
699 	case MAC_STAT_MULTIXMT:
700 		return (mac_misc_stat->mms_multixmt);
701 
702 	case MAC_STAT_BRDCSTXMT:
703 		return (mac_misc_stat->mms_brdcstxmt);
704 
705 	case MAC_STAT_MULTIRCVBYTES:
706 		return (mac_misc_stat->mms_multircvbytes);
707 
708 	case MAC_STAT_BRDCSTRCVBYTES:
709 		return (mac_misc_stat->mms_brdcstrcvbytes);
710 
711 	case MAC_STAT_MULTIXMTBYTES:
712 		return (mac_misc_stat->mms_multixmtbytes);
713 
714 	case MAC_STAT_BRDCSTXMTBYTES:
715 		return (mac_misc_stat->mms_brdcstxmtbytes);
716 
717 	case MAC_STAT_TX_ERRORS:
718 		return (mac_misc_stat->mms_txerrors);
719 
720 	case MAC_STAT_MACSPOOFED:
721 		return (mac_misc_stat->mms_macspoofed);
722 
723 	case MAC_STAT_IPSPOOFED:
724 		return (mac_misc_stat->mms_ipspoofed);
725 
726 	case MAC_STAT_DHCPSPOOFED:
727 		return (mac_misc_stat->mms_dhcpspoofed);
728 
729 	case MAC_STAT_RESTRICTED:
730 		return (mac_misc_stat->mms_restricted);
731 
732 	case MAC_STAT_DHCPDROPPED:
733 		return (mac_misc_stat->mms_dhcpdropped);
734 
735 	case MAC_STAT_IPACKETS:
736 		return (mac_rx_stat->mrs_intrcnt +
737 		    mac_rx_stat->mrs_pollcnt);
738 
739 	case MAC_STAT_RBYTES:
740 		return (mac_rx_stat->mrs_intrbytes +
741 		    mac_rx_stat->mrs_pollbytes);
742 
743 	case MAC_STAT_LCL:
744 		return (mac_rx_stat->mrs_lclcnt);
745 
746 	case MAC_STAT_LCLBYTES:
747 		return (mac_rx_stat->mrs_lclbytes);
748 
749 	case MAC_STAT_INTRS:
750 		return (mac_rx_stat->mrs_intrcnt);
751 
752 	case MAC_STAT_INTRBYTES:
753 		return (mac_rx_stat->mrs_intrbytes);
754 
755 	case MAC_STAT_POLLS:
756 		return (mac_rx_stat->mrs_pollcnt);
757 
758 	case MAC_STAT_POLLBYTES:
759 		return (mac_rx_stat->mrs_pollbytes);
760 
761 	case MAC_STAT_RXSDROPS:
762 		return (mac_rx_stat->mrs_sdrops);
763 
764 	case MAC_STAT_CHU10:
765 		return (mac_rx_stat->mrs_chaincntundr10);
766 
767 	case MAC_STAT_CH10T50:
768 		return (mac_rx_stat->mrs_chaincnt10to50);
769 
770 	case MAC_STAT_CHO50:
771 		return (mac_rx_stat->mrs_chaincntover50);
772 
773 	case MAC_STAT_OBYTES:
774 		return (mac_tx_stat->mts_obytes);
775 
776 	case MAC_STAT_OPACKETS:
777 		return (mac_tx_stat->mts_opackets);
778 
779 	case MAC_STAT_OERRORS:
780 		return (mac_tx_stat->mts_oerrors);
781 
782 	case MAC_STAT_BLOCK:
783 		return (mac_tx_stat->mts_blockcnt);
784 
785 	case MAC_STAT_UNBLOCK:
786 		return (mac_tx_stat->mts_unblockcnt);
787 
788 	case MAC_STAT_TXSDROPS:
789 		return (mac_tx_stat->mts_sdrops);
790 
791 	default:
792 		return (0);
793 	}
794 }
795 
796 static int
i_mac_misc_stat_update(kstat_t * ksp,int rw)797 i_mac_misc_stat_update(kstat_t *ksp, int rw)
798 {
799 	return (i_mac_stat_update(ksp, rw, i_mac_misc_stat_get,
800 	    i_mac_misc_si, MAC_SUMMARY_NKSTAT));
801 }
802 
803 static void
i_mac_misc_stat_create(flow_entry_t * flent,const char * modname,const char * statname)804 i_mac_misc_stat_create(flow_entry_t *flent, const char *modname,
805     const char *statname)
806 {
807 	kstat_t		*ksp;
808 
809 	ksp = i_mac_stat_create(flent, modname, statname,
810 	    i_mac_misc_stat_update, i_mac_misc_si,
811 	    MAC_SUMMARY_NKSTAT);
812 
813 	flent->fe_misc_stat_ksp = ksp;
814 }
815 
816 /*
817  * Per hardware lane tx statistics
818  */
819 static uint64_t
i_mac_tx_hwlane_stat_get(void * handle,uint_t stat)820 i_mac_tx_hwlane_stat_get(void *handle, uint_t stat)
821 {
822 	mac_soft_ring_t	*ringp = (mac_soft_ring_t *)handle;
823 	mac_tx_stats_t	*mac_tx_stat = &ringp->s_st_stat;
824 
825 	switch (stat) {
826 	case MAC_STAT_OBYTES:
827 		return (mac_tx_stat->mts_obytes);
828 
829 	case MAC_STAT_OPACKETS:
830 		return (mac_tx_stat->mts_opackets);
831 
832 	case MAC_STAT_OERRORS:
833 		return (mac_tx_stat->mts_oerrors);
834 
835 	case MAC_STAT_BLOCK:
836 		return (mac_tx_stat->mts_blockcnt);
837 
838 	case MAC_STAT_UNBLOCK:
839 		return (mac_tx_stat->mts_unblockcnt);
840 
841 	case MAC_STAT_TXSDROPS:
842 		return (mac_tx_stat->mts_sdrops);
843 
844 	default:
845 		return (0);
846 	}
847 }
848 
849 static int
i_mac_tx_hwlane_stat_update(kstat_t * ksp,int rw)850 i_mac_tx_hwlane_stat_update(kstat_t *ksp, int rw)
851 {
852 	return (i_mac_stat_update(ksp, rw, i_mac_tx_hwlane_stat_get,
853 	    i_mac_tx_hwlane_si, MAC_TX_HWLANE_NKSTAT));
854 }
855 
856 static void
i_mac_tx_hwlane_stat_create(mac_soft_ring_t * ringp,const char * modname,const char * statname)857 i_mac_tx_hwlane_stat_create(mac_soft_ring_t *ringp, const char *modname,
858     const char *statname)
859 {
860 	kstat_t		*ksp;
861 
862 	ksp = i_mac_stat_create(ringp, modname, statname,
863 	    i_mac_tx_hwlane_stat_update, i_mac_tx_hwlane_si,
864 	    MAC_TX_HWLANE_NKSTAT);
865 
866 	ringp->s_ring_ksp = ksp;
867 }
868 
869 /*
870  * Per fanout rx statistics
871  */
872 static uint64_t
i_mac_rx_fanout_stat_get(void * handle,uint_t stat)873 i_mac_rx_fanout_stat_get(void *handle, uint_t stat)
874 {
875 	mac_soft_ring_t		*tcp_ringp = (mac_soft_ring_t *)handle;
876 	mac_soft_ring_t		*tcp6_ringp = NULL, *udp_ringp = NULL;
877 	mac_soft_ring_t		*udp6_ringp = NULL, *oth_ringp = NULL;
878 	mac_soft_ring_set_t	*mac_srs = tcp_ringp->s_ring_set;
879 	int			index;
880 	uint64_t		val;
881 
882 	mutex_enter(&mac_srs->srs_lock);
883 	/* Extract corresponding udp and oth ring pointers */
884 	for (index = 0; mac_srs->srs_tcp_soft_rings[index] != NULL; index++) {
885 		if (mac_srs->srs_tcp_soft_rings[index] == tcp_ringp) {
886 			tcp6_ringp = mac_srs->srs_tcp6_soft_rings[index];
887 			udp_ringp = mac_srs->srs_udp_soft_rings[index];
888 			udp6_ringp = mac_srs->srs_udp6_soft_rings[index];
889 			oth_ringp = mac_srs->srs_oth_soft_rings[index];
890 			break;
891 		}
892 	}
893 
894 	ASSERT((tcp6_ringp != NULL) && (udp_ringp != NULL) &&
895 	    (udp6_ringp != NULL) && (oth_ringp != NULL));
896 
897 	switch (stat) {
898 	case MAC_STAT_RBYTES:
899 		val = (tcp_ringp->s_ring_total_rbytes) +
900 		    (tcp6_ringp->s_ring_total_rbytes) +
901 		    (udp_ringp->s_ring_total_rbytes) +
902 		    (udp6_ringp->s_ring_total_rbytes) +
903 		    (oth_ringp->s_ring_total_rbytes);
904 		break;
905 
906 	case MAC_STAT_IPACKETS:
907 		val = (tcp_ringp->s_ring_total_inpkt) +
908 		    (tcp6_ringp->s_ring_total_inpkt) +
909 		    (udp_ringp->s_ring_total_inpkt) +
910 		    (udp6_ringp->s_ring_total_inpkt) +
911 		    (oth_ringp->s_ring_total_inpkt);
912 		break;
913 
914 	default:
915 		val = 0;
916 		break;
917 	}
918 	mutex_exit(&mac_srs->srs_lock);
919 	return (val);
920 }
921 
922 static int
i_mac_rx_fanout_stat_update(kstat_t * ksp,int rw)923 i_mac_rx_fanout_stat_update(kstat_t *ksp, int rw)
924 {
925 	return (i_mac_stat_update(ksp, rw, i_mac_rx_fanout_stat_get,
926 	    i_mac_rx_fanout_si, MAC_RX_FANOUT_NKSTAT));
927 }
928 
929 static void
i_mac_rx_fanout_stat_create(mac_soft_ring_t * ringp,const char * modname,const char * statname)930 i_mac_rx_fanout_stat_create(mac_soft_ring_t *ringp, const char *modname,
931     const char *statname)
932 {
933 	kstat_t		*ksp;
934 
935 	ksp = i_mac_stat_create(ringp, modname, statname,
936 	    i_mac_rx_fanout_stat_update, i_mac_rx_fanout_si,
937 	    MAC_RX_FANOUT_NKSTAT);
938 
939 	ringp->s_ring_ksp = ksp;
940 }
941 
942 /*
943  * Exported functions.
944  */
945 
946 /*
947  * Create the "mac" kstat.  The "mac" kstat is comprised of three kinds of
948  * statistics: statistics maintained by the mac module itself, generic mac
949  * statistics maintained by the driver, and MAC-type specific statistics
950  * also maintained by the driver.
951  */
952 void
mac_driver_stat_create(mac_impl_t * mip)953 mac_driver_stat_create(mac_impl_t *mip)
954 {
955 	kstat_t		*ksp;
956 	kstat_named_t	*knp;
957 	uint_t		count;
958 	major_t		major = getmajor(mip->mi_phy_dev);
959 
960 	count = MAC_MOD_NKSTAT + MAC_NKSTAT + mip->mi_type->mt_statcount;
961 	ksp = kstat_create((const char *)ddi_major_to_name(major),
962 	    getminor(mip->mi_phy_dev) - 1, MAC_KSTAT_NAME,
963 	    MAC_KSTAT_CLASS, KSTAT_TYPE_NAMED, count, 0);
964 	if (ksp == NULL)
965 		return;
966 
967 	ksp->ks_update = i_mac_driver_stat_update;
968 	ksp->ks_private = mip;
969 	mip->mi_ksp = ksp;
970 	mip->mi_kstat_count = count;
971 
972 	knp = (kstat_named_t *)ksp->ks_data;
973 	i_mac_kstat_init(knp, i_mac_mod_si, MAC_MOD_NKSTAT);
974 	knp += MAC_MOD_NKSTAT;
975 	i_mac_kstat_init(knp, i_mac_si, MAC_NKSTAT);
976 	if (mip->mi_type->mt_statcount > 0) {
977 		knp += MAC_NKSTAT;
978 		i_mac_kstat_init(knp, mip->mi_type->mt_stats,
979 		    mip->mi_type->mt_statcount);
980 	}
981 
982 	kstat_install(ksp);
983 }
984 
985 /*ARGSUSED*/
986 void
mac_driver_stat_delete(mac_impl_t * mip)987 mac_driver_stat_delete(mac_impl_t *mip)
988 {
989 	if (mip->mi_ksp != NULL) {
990 		kstat_delete(mip->mi_ksp);
991 		mip->mi_ksp = NULL;
992 		mip->mi_kstat_count = 0;
993 	}
994 }
995 
996 uint64_t
mac_driver_stat_default(mac_impl_t * mip,uint_t stat)997 mac_driver_stat_default(mac_impl_t *mip, uint_t stat)
998 {
999 	uint_t	stat_index;
1000 
1001 	if (IS_MAC_STAT(stat)) {
1002 		stat_index = stat - MAC_STAT_MIN;
1003 		ASSERT(stat_index < MAC_NKSTAT);
1004 		return (i_mac_si[stat_index].msi_default);
1005 	}
1006 	ASSERT(IS_MACTYPE_STAT(stat));
1007 	stat_index = stat - MACTYPE_STAT_MIN;
1008 	ASSERT(stat_index < mip->mi_type->mt_statcount);
1009 	return (mip->mi_type->mt_stats[stat_index].msi_default);
1010 }
1011 
1012 void
mac_ring_stat_create(mac_ring_t * ring)1013 mac_ring_stat_create(mac_ring_t *ring)
1014 {
1015 	mac_impl_t	*mip = ring->mr_mip;
1016 	mac_group_t	*grp = (mac_group_t *)ring->mr_gh;
1017 	char		statname[MAXNAMELEN];
1018 	char		modname[MAXNAMELEN];
1019 
1020 	if (mip->mi_state_flags & MIS_IS_AGGR) {
1021 		(void) strlcpy(modname, mip->mi_clients_list->mci_name,
1022 		    MAXNAMELEN);
1023 	} else
1024 		(void) strlcpy(modname, mip->mi_name, MAXNAMELEN);
1025 
1026 	switch (ring->mr_type) {
1027 	case MAC_RING_TYPE_RX:
1028 		(void) snprintf(statname, sizeof (statname),
1029 		    "mac_rx_ring_%d_%d", grp->mrg_index, ring->mr_index);
1030 		i_mac_rx_ring_stat_create(ring, modname, statname);
1031 		break;
1032 
1033 	case MAC_RING_TYPE_TX:
1034 		(void) snprintf(statname, sizeof (statname), "mac_tx_ring%d",
1035 		    ring->mr_index);
1036 		i_mac_tx_ring_stat_create(ring, modname, statname);
1037 		break;
1038 
1039 	default:
1040 		ASSERT(B_FALSE);
1041 		break;
1042 	}
1043 }
1044 
1045 void
mac_srs_stat_create(mac_soft_ring_set_t * mac_srs)1046 mac_srs_stat_create(mac_soft_ring_set_t *mac_srs)
1047 {
1048 	flow_entry_t	*flent = mac_srs->srs_flent;
1049 	char		statname[MAXNAMELEN];
1050 	boolean_t	is_tx_srs;
1051 
1052 	/* No hardware/software lanes for user defined flows */
1053 	if ((flent->fe_type & FLOW_USER) != 0)
1054 		return;
1055 
1056 	is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1057 
1058 	if (is_tx_srs) {
1059 		mac_srs_tx_t	*srs_tx = &mac_srs->srs_tx;
1060 		mac_ring_t	*ring = srs_tx->st_arg2;
1061 
1062 		if (ring != NULL) {
1063 			(void) snprintf(statname, sizeof (statname),
1064 			    "mac_tx_hwlane%d", ring->mr_index);
1065 		} else {
1066 			(void) snprintf(statname, sizeof (statname),
1067 			    "mac_tx_swlane0");
1068 		}
1069 		i_mac_tx_swlane_stat_create(mac_srs, flent->fe_flow_name,
1070 		    statname);
1071 	} else {
1072 		mac_ring_t	*ring = mac_srs->srs_ring;
1073 
1074 		if (ring == NULL) {
1075 			(void) snprintf(statname, sizeof (statname),
1076 			    "mac_rx_swlane0");
1077 			i_mac_rx_swlane_stat_create(mac_srs,
1078 			    flent->fe_flow_name, statname);
1079 		} else {
1080 			(void) snprintf(statname, sizeof (statname),
1081 			    "mac_rx_hwlane%d", ring->mr_index);
1082 			i_mac_rx_hwlane_stat_create(mac_srs,
1083 			    flent->fe_flow_name, statname);
1084 		}
1085 	}
1086 }
1087 
1088 void
mac_misc_stat_create(flow_entry_t * flent)1089 mac_misc_stat_create(flow_entry_t *flent)
1090 {
1091 	char	statname[MAXNAMELEN];
1092 
1093 	/* No misc stats for user defined or mcast/bcast flows */
1094 	if (((flent->fe_type & FLOW_USER) != 0) ||
1095 	    ((flent->fe_type & FLOW_MCAST) != 0))
1096 		return;
1097 
1098 	(void) snprintf(statname, sizeof (statname), "mac_misc_stat");
1099 	i_mac_misc_stat_create(flent, flent->fe_flow_name, statname);
1100 }
1101 
1102 void
mac_soft_ring_stat_create(mac_soft_ring_t * ringp)1103 mac_soft_ring_stat_create(mac_soft_ring_t *ringp)
1104 {
1105 	mac_soft_ring_set_t	*mac_srs = ringp->s_ring_set;
1106 	flow_entry_t		*flent = ringp->s_ring_mcip->mci_flent;
1107 	mac_ring_t		*ring = (mac_ring_t *)ringp->s_ring_tx_arg2;
1108 	boolean_t		is_tx_srs;
1109 	char			statname[MAXNAMELEN];
1110 
1111 	/* No hardware/software lanes for user defined flows */
1112 	if ((flent->fe_type & FLOW_USER) != 0)
1113 		return;
1114 
1115 	is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1116 	if (is_tx_srs) {	/* tx side hardware lane */
1117 		ASSERT(ring != NULL);
1118 		(void) snprintf(statname, sizeof (statname), "mac_tx_hwlane%d",
1119 		    ring->mr_index);
1120 		i_mac_tx_hwlane_stat_create(ringp, flent->fe_flow_name,
1121 		    statname);
1122 	} else {		/* rx side fanout */
1123 				/* Maintain single stat for (tcp, udp, oth) */
1124 		if (ringp->s_ring_type & ST_RING_TCP) {
1125 			int			index;
1126 			mac_soft_ring_t		*softring;
1127 
1128 			for (index = 0, softring = mac_srs->srs_soft_ring_head;
1129 			    softring != NULL;
1130 			    index++, softring = softring->s_ring_next) {
1131 				if (softring == ringp)
1132 					break;
1133 			}
1134 
1135 			if (mac_srs->srs_ring == NULL) {
1136 				(void) snprintf(statname, sizeof (statname),
1137 				    "mac_rx_swlane0_fanout%d", index/3);
1138 			} else {
1139 				(void) snprintf(statname, sizeof (statname),
1140 				    "mac_rx_hwlane%d_fanout%d",
1141 				    mac_srs->srs_ring->mr_index, index/3);
1142 			}
1143 			i_mac_rx_fanout_stat_create(ringp, flent->fe_flow_name,
1144 			    statname);
1145 		}
1146 	}
1147 }
1148 
1149 void
mac_ring_stat_delete(mac_ring_t * ring)1150 mac_ring_stat_delete(mac_ring_t *ring)
1151 {
1152 	if (ring->mr_ksp != NULL) {
1153 		kstat_delete(ring->mr_ksp);
1154 		ring->mr_ksp = NULL;
1155 	}
1156 }
1157 
1158 void
mac_srs_stat_delete(mac_soft_ring_set_t * mac_srs)1159 mac_srs_stat_delete(mac_soft_ring_set_t *mac_srs)
1160 {
1161 	boolean_t	is_tx_srs;
1162 
1163 	is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1164 	if (!is_tx_srs) {
1165 		/*
1166 		 * Rx ring has been taken away. Before destroying corresponding
1167 		 * SRS, save the stats recorded by that SRS.
1168 		 */
1169 		mac_client_impl_t	*mcip = mac_srs->srs_mcip;
1170 		mac_misc_stats_t	*mac_misc_stat = &mcip->mci_misc_stat;
1171 		mac_rx_stats_t		*mac_rx_stat = &mac_srs->srs_rx.sr_stat;
1172 
1173 		i_mac_add_stats(&mac_misc_stat->mms_defunctrxlanestats,
1174 		    mac_rx_stat, &mac_misc_stat->mms_defunctrxlanestats,
1175 		    rx_srs_stats_list, RX_SRS_STAT_SIZE);
1176 	}
1177 
1178 	if (mac_srs->srs_ksp != NULL) {
1179 		kstat_delete(mac_srs->srs_ksp);
1180 		mac_srs->srs_ksp = NULL;
1181 	}
1182 }
1183 
1184 void
mac_misc_stat_delete(flow_entry_t * flent)1185 mac_misc_stat_delete(flow_entry_t *flent)
1186 {
1187 	if (flent->fe_misc_stat_ksp != NULL) {
1188 		kstat_delete(flent->fe_misc_stat_ksp);
1189 		flent->fe_misc_stat_ksp = NULL;
1190 	}
1191 }
1192 
1193 void
mac_soft_ring_stat_delete(mac_soft_ring_t * ringp)1194 mac_soft_ring_stat_delete(mac_soft_ring_t *ringp)
1195 {
1196 	mac_soft_ring_set_t	*mac_srs = ringp->s_ring_set;
1197 	boolean_t		is_tx_srs;
1198 
1199 	is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1200 	if (is_tx_srs) {
1201 		/*
1202 		 * Tx ring has been taken away. Before destroying corresponding
1203 		 * soft ring, save the stats recorded by that soft ring.
1204 		 */
1205 		mac_client_impl_t	*mcip = mac_srs->srs_mcip;
1206 		mac_misc_stats_t	*mac_misc_stat = &mcip->mci_misc_stat;
1207 		mac_tx_stats_t		*mac_tx_stat = &ringp->s_st_stat;
1208 
1209 		i_mac_add_stats(&mac_misc_stat->mms_defuncttxlanestats,
1210 		    mac_tx_stat, &mac_misc_stat->mms_defuncttxlanestats,
1211 		    tx_softring_stats_list, TX_SOFTRING_STAT_SIZE);
1212 	}
1213 
1214 	if (ringp->s_ring_ksp) {
1215 		kstat_delete(ringp->s_ring_ksp);
1216 		ringp->s_ring_ksp = NULL;
1217 	}
1218 }
1219 
1220 void
mac_pseudo_ring_stat_rename(mac_impl_t * mip)1221 mac_pseudo_ring_stat_rename(mac_impl_t *mip)
1222 {
1223 	mac_group_t	*group;
1224 	mac_ring_t	*ring;
1225 
1226 	/* Recreate pseudo rx ring kstats */
1227 	for (group = mip->mi_rx_groups; group != NULL;
1228 	    group = group->mrg_next) {
1229 		for (ring = group->mrg_rings; ring != NULL;
1230 		    ring = ring->mr_next) {
1231 			mac_ring_stat_delete(ring);
1232 			mac_ring_stat_create(ring);
1233 		}
1234 	}
1235 
1236 	/* Recreate pseudo tx ring kstats */
1237 	for (group = mip->mi_tx_groups; group != NULL;
1238 	    group = group->mrg_next) {
1239 		for (ring = group->mrg_rings; ring != NULL;
1240 		    ring = ring->mr_next) {
1241 			mac_ring_stat_delete(ring);
1242 			mac_ring_stat_create(ring);
1243 		}
1244 	}
1245 }
1246 
1247 void
mac_stat_rename(mac_client_impl_t * mcip)1248 mac_stat_rename(mac_client_impl_t *mcip)
1249 {
1250 	flow_entry_t		*flent = mcip->mci_flent;
1251 	mac_soft_ring_set_t	*mac_srs;
1252 	mac_soft_ring_t		*ringp;
1253 	int			i, j;
1254 
1255 	ASSERT(flent != NULL);
1256 
1257 	/* Recreate rx SRSes kstats */
1258 	for (i = 0; i < flent->fe_rx_srs_cnt; i++) {
1259 		mac_srs = (mac_soft_ring_set_t *)flent->fe_rx_srs[i];
1260 		mac_srs_stat_delete(mac_srs);
1261 		mac_srs_stat_create(mac_srs);
1262 
1263 		/* Recreate rx fanout kstats */
1264 		for (j = 0; j < mac_srs->srs_tcp_ring_count; j++) {
1265 			ringp = mac_srs->srs_tcp_soft_rings[j];
1266 			mac_soft_ring_stat_delete(ringp);
1267 			mac_soft_ring_stat_create(ringp);
1268 		}
1269 	}
1270 
1271 	/* Recreate tx SRS kstats */
1272 	mac_srs = (mac_soft_ring_set_t *)flent->fe_tx_srs;
1273 	mac_srs_stat_delete(mac_srs);
1274 	mac_srs_stat_create(mac_srs);
1275 
1276 	/* Recreate tx sofring kstats */
1277 	for (ringp = mac_srs->srs_soft_ring_head; ringp;
1278 	    ringp = ringp->s_ring_next) {
1279 		mac_soft_ring_stat_delete(ringp);
1280 		mac_soft_ring_stat_create(ringp);
1281 	}
1282 
1283 	/* Recreate misc kstats */
1284 	mac_misc_stat_delete(flent);
1285 	mac_misc_stat_create(flent);
1286 }
1287 
1288 void
mac_tx_srs_stat_recreate(mac_soft_ring_set_t * tx_srs,boolean_t add_stats)1289 mac_tx_srs_stat_recreate(mac_soft_ring_set_t *tx_srs, boolean_t add_stats)
1290 {
1291 	mac_client_impl_t	*mcip = tx_srs->srs_mcip;
1292 	mac_misc_stats_t	*mac_misc_stat = &mcip->mci_misc_stat;
1293 	mac_tx_stats_t		*mac_tx_stat = &tx_srs->srs_tx.st_stat;
1294 
1295 	if (add_stats) {
1296 		/* Add the stats to cumulative stats */
1297 		i_mac_add_stats(&mac_misc_stat->mms_defuncttxlanestats,
1298 		    mac_tx_stat, &mac_misc_stat->mms_defuncttxlanestats,
1299 		    tx_softring_stats_list, TX_SOFTRING_STAT_SIZE);
1300 	}
1301 
1302 	bzero(mac_tx_stat, sizeof (mac_tx_stats_t));
1303 	mac_srs_stat_delete(tx_srs);
1304 	mac_srs_stat_create(tx_srs);
1305 }
1306