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