xref: /illumos-gate/usr/src/uts/common/io/mac/mac_stat.c (revision ba2e4443)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*ba2e4443Sseb  * Common Development and Distribution License (the "License").
6*ba2e4443Sseb  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*ba2e4443Sseb  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * MAC Services Module
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
347c478bd9Sstevel@tonic-gate #include <sys/stream.h>
357c478bd9Sstevel@tonic-gate #include <sys/kstat.h>
367c478bd9Sstevel@tonic-gate #include <sys/mac.h>
377c478bd9Sstevel@tonic-gate #include <sys/mac_impl.h>
387c478bd9Sstevel@tonic-gate 
39*ba2e4443Sseb #define	MAC_KSTAT_NAME	"mac"
40*ba2e4443Sseb #define	MAC_KSTAT_CLASS	"net"
41*ba2e4443Sseb 
42*ba2e4443Sseb typedef	int (*ks_update_fnp)(struct kstat *, int);
43*ba2e4443Sseb 
44*ba2e4443Sseb static mac_stat_info_t	i_mac_si[] = {
45*ba2e4443Sseb 	{ MAC_STAT_IFSPEED,	"ifspeed",	KSTAT_DATA_UINT64,	0 },
46*ba2e4443Sseb 	{ MAC_STAT_MULTIRCV,	"multircv",	KSTAT_DATA_UINT32,	0 },
47*ba2e4443Sseb 	{ MAC_STAT_BRDCSTRCV,	"brdcstrcv",	KSTAT_DATA_UINT32,	0 },
48*ba2e4443Sseb 	{ MAC_STAT_MULTIXMT,	"multixmt",	KSTAT_DATA_UINT32,	0 },
49*ba2e4443Sseb 	{ MAC_STAT_BRDCSTXMT,	"brdcstxmt",	KSTAT_DATA_UINT32,	0 },
50*ba2e4443Sseb 	{ MAC_STAT_NORCVBUF,	"norcvbuf",	KSTAT_DATA_UINT32,	0 },
51*ba2e4443Sseb 	{ MAC_STAT_IERRORS,	"ierrors",	KSTAT_DATA_UINT32,	0 },
52*ba2e4443Sseb 	{ MAC_STAT_UNKNOWNS,	"unknowns",	KSTAT_DATA_UINT32,	0 },
53*ba2e4443Sseb 	{ MAC_STAT_NOXMTBUF,	"noxmtbuf",	KSTAT_DATA_UINT32,	0 },
54*ba2e4443Sseb 	{ MAC_STAT_OERRORS,	"oerrors",	KSTAT_DATA_UINT32,	0 },
55*ba2e4443Sseb 	{ MAC_STAT_COLLISIONS,	"collisions",	KSTAT_DATA_UINT32,	0 },
56*ba2e4443Sseb 	{ MAC_STAT_RBYTES,	"rbytes",	KSTAT_DATA_UINT32,	0 },
57*ba2e4443Sseb 	{ MAC_STAT_IPACKETS,	"ipackets",	KSTAT_DATA_UINT32,	0 },
58*ba2e4443Sseb 	{ MAC_STAT_OBYTES,	"obytes",	KSTAT_DATA_UINT32,	0 },
59*ba2e4443Sseb 	{ MAC_STAT_OPACKETS,	"opackets",	KSTAT_DATA_UINT32,	0 },
60*ba2e4443Sseb 	{ MAC_STAT_RBYTES,	"rbytes64",	KSTAT_DATA_UINT64,	0 },
61*ba2e4443Sseb 	{ MAC_STAT_IPACKETS,	"ipackets64",	KSTAT_DATA_UINT64,	0 },
62*ba2e4443Sseb 	{ MAC_STAT_OBYTES,	"obytes64",	KSTAT_DATA_UINT64,	0 },
63*ba2e4443Sseb 	{ MAC_STAT_OPACKETS,	"opackets64",	KSTAT_DATA_UINT64,	0 }
647c478bd9Sstevel@tonic-gate };
657c478bd9Sstevel@tonic-gate 
66*ba2e4443Sseb #define	MAC_NKSTAT \
67*ba2e4443Sseb 	(sizeof (i_mac_si) / sizeof (mac_stat_info_t))
68*ba2e4443Sseb 
69*ba2e4443Sseb static mac_stat_info_t	i_mac_mod_si[] = {
70*ba2e4443Sseb 	{ MAC_STAT_LINK_STATE,	"link_state",	KSTAT_DATA_UINT32,
71*ba2e4443Sseb 	    (uint64_t)LINK_STATE_UNKNOWN },
72*ba2e4443Sseb 	{ MAC_STAT_LINK_UP,	"link_up",	KSTAT_DATA_UINT32,	0 },
73*ba2e4443Sseb 	{ MAC_STAT_PROMISC,	"promisc",	KSTAT_DATA_UINT32,	0 }
74*ba2e4443Sseb };
75*ba2e4443Sseb 
76*ba2e4443Sseb #define	MAC_MOD_NKSTAT \
77*ba2e4443Sseb 	(sizeof (i_mac_mod_si) / sizeof (mac_stat_info_t))
78*ba2e4443Sseb 
79*ba2e4443Sseb #define	MAC_MOD_KSTAT_OFFSET	0
80*ba2e4443Sseb #define	MAC_KSTAT_OFFSET	MAC_MOD_KSTAT_OFFSET + MAC_MOD_NKSTAT
81*ba2e4443Sseb #define	MAC_TYPE_KSTAT_OFFSET	MAC_KSTAT_OFFSET + MAC_NKSTAT
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate /*
847c478bd9Sstevel@tonic-gate  * Private functions.
857c478bd9Sstevel@tonic-gate  */
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate static int
887c478bd9Sstevel@tonic-gate i_mac_stat_update(kstat_t *ksp, int rw)
897c478bd9Sstevel@tonic-gate {
907c478bd9Sstevel@tonic-gate 	mac_impl_t	*mip = ksp->ks_private;
91*ba2e4443Sseb 	kstat_named_t	*knp = ksp->ks_data;
927c478bd9Sstevel@tonic-gate 	uint_t		i;
937c478bd9Sstevel@tonic-gate 	uint64_t	val;
94*ba2e4443Sseb 	mac_stat_info_t	*msi;
95*ba2e4443Sseb 	uint_t		msi_index;
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	if (rw != KSTAT_READ)
987c478bd9Sstevel@tonic-gate 		return (EACCES);
997c478bd9Sstevel@tonic-gate 
100*ba2e4443Sseb 	for (i = 0; i < mip->mi_kstat_count; i++, msi_index++) {
101*ba2e4443Sseb 		if (i == MAC_MOD_KSTAT_OFFSET) {
102*ba2e4443Sseb 			msi_index = 0;
103*ba2e4443Sseb 			msi = i_mac_mod_si;
104*ba2e4443Sseb 		} else if (i == MAC_KSTAT_OFFSET) {
105*ba2e4443Sseb 			msi_index = 0;
106*ba2e4443Sseb 			msi = i_mac_si;
107*ba2e4443Sseb 		} else if (i == MAC_TYPE_KSTAT_OFFSET) {
108*ba2e4443Sseb 			msi_index = 0;
109*ba2e4443Sseb 			msi = mip->mi_type->mt_stats;
110*ba2e4443Sseb 		}
1117c478bd9Sstevel@tonic-gate 
112*ba2e4443Sseb 		val = mac_stat_get((mac_handle_t)mip, msi[msi_index].msi_stat);
113*ba2e4443Sseb 		switch (msi[msi_index].msi_type) {
1147c478bd9Sstevel@tonic-gate 		case KSTAT_DATA_UINT64:
1157c478bd9Sstevel@tonic-gate 			knp->value.ui64 = val;
1167c478bd9Sstevel@tonic-gate 			break;
1177c478bd9Sstevel@tonic-gate 		case KSTAT_DATA_UINT32:
1187c478bd9Sstevel@tonic-gate 			knp->value.ui32 = (uint32_t)val;
1197c478bd9Sstevel@tonic-gate 			break;
1207c478bd9Sstevel@tonic-gate 		default:
1217c478bd9Sstevel@tonic-gate 			ASSERT(B_FALSE);
1227c478bd9Sstevel@tonic-gate 			break;
1237c478bd9Sstevel@tonic-gate 		}
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 		knp++;
1267c478bd9Sstevel@tonic-gate 	}
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	return (0);
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate 
131*ba2e4443Sseb static void
132*ba2e4443Sseb i_mac_kstat_init(kstat_named_t *knp, mac_stat_info_t *si, uint_t count)
133*ba2e4443Sseb {
134*ba2e4443Sseb 	int i;
135*ba2e4443Sseb 	for (i = 0; i < count; i++) {
136*ba2e4443Sseb 		kstat_named_init(knp, si[i].msi_name, si[i].msi_type);
137*ba2e4443Sseb 		knp++;
138*ba2e4443Sseb 	}
139*ba2e4443Sseb }
140*ba2e4443Sseb 
1417c478bd9Sstevel@tonic-gate /*
1427c478bd9Sstevel@tonic-gate  * Exported functions.
1437c478bd9Sstevel@tonic-gate  */
1447c478bd9Sstevel@tonic-gate 
145*ba2e4443Sseb /*
146*ba2e4443Sseb  * Create the "mac" kstat.  The "mac" kstat is comprised of three kinds of
147*ba2e4443Sseb  * statistics: statistics maintained by the mac module itself, generic mac
148*ba2e4443Sseb  * statistics maintained by the driver, and MAC-type specific statistics
149*ba2e4443Sseb  * also maintained by the driver.
150*ba2e4443Sseb  */
1517c478bd9Sstevel@tonic-gate void
1527c478bd9Sstevel@tonic-gate mac_stat_create(mac_impl_t *mip)
1537c478bd9Sstevel@tonic-gate {
1547c478bd9Sstevel@tonic-gate 	kstat_t		*ksp;
1557c478bd9Sstevel@tonic-gate 	kstat_named_t	*knp;
1567c478bd9Sstevel@tonic-gate 	uint_t		count;
1577c478bd9Sstevel@tonic-gate 
158*ba2e4443Sseb 	count = MAC_MOD_NKSTAT + MAC_NKSTAT + mip->mi_type->mt_statcount;
159*ba2e4443Sseb 	ksp = kstat_create((char *)mip->mi_drvname, mip->mi_instance,
160*ba2e4443Sseb 	    MAC_KSTAT_NAME, MAC_KSTAT_CLASS, KSTAT_TYPE_NAMED, count, 0);
161*ba2e4443Sseb 	if (ksp == NULL)
1627c478bd9Sstevel@tonic-gate 		return;
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	ksp->ks_update = i_mac_stat_update;
165*ba2e4443Sseb 	ksp->ks_private = mip;
1667c478bd9Sstevel@tonic-gate 	mip->mi_ksp = ksp;
167*ba2e4443Sseb 	mip->mi_kstat_count = count;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	knp = (kstat_named_t *)ksp->ks_data;
170*ba2e4443Sseb 	i_mac_kstat_init(knp, i_mac_mod_si, MAC_MOD_NKSTAT);
171*ba2e4443Sseb 	knp += MAC_MOD_NKSTAT;
172*ba2e4443Sseb 	i_mac_kstat_init(knp, i_mac_si, MAC_NKSTAT);
173*ba2e4443Sseb 	if (mip->mi_type->mt_statcount > 0) {
174*ba2e4443Sseb 		knp += MAC_NKSTAT;
175*ba2e4443Sseb 		i_mac_kstat_init(knp, mip->mi_type->mt_stats,
176*ba2e4443Sseb 		    mip->mi_type->mt_statcount);
1777c478bd9Sstevel@tonic-gate 	}
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	kstat_install(ksp);
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1837c478bd9Sstevel@tonic-gate void
1847c478bd9Sstevel@tonic-gate mac_stat_destroy(mac_impl_t *mip)
1857c478bd9Sstevel@tonic-gate {
186*ba2e4443Sseb 	if (mip->mi_ksp != NULL) {
187*ba2e4443Sseb 		kstat_delete(mip->mi_ksp);
188*ba2e4443Sseb 		mip->mi_ksp = NULL;
189*ba2e4443Sseb 		mip->mi_kstat_count = 0;
190*ba2e4443Sseb 	}
191*ba2e4443Sseb }
192*ba2e4443Sseb 
193*ba2e4443Sseb uint64_t
194*ba2e4443Sseb mac_stat_default(mac_impl_t *mip, uint_t stat)
195*ba2e4443Sseb {
196*ba2e4443Sseb 	uint_t	stat_index;
197*ba2e4443Sseb 
198*ba2e4443Sseb 	if (IS_MAC_STAT(stat)) {
199*ba2e4443Sseb 		stat_index = stat - MAC_STAT_MIN;
200*ba2e4443Sseb 		return (i_mac_si[stat_index].msi_default);
201*ba2e4443Sseb 	}
202*ba2e4443Sseb 	ASSERT(IS_MACTYPE_STAT(stat));
203*ba2e4443Sseb 	stat_index = stat - MACTYPE_STAT_MIN;
204*ba2e4443Sseb 	return (mip->mi_type->mt_stats[stat_index].msi_default);
2057c478bd9Sstevel@tonic-gate }
206