xref: /onnv-gate/usr/src/uts/common/io/mac/mac_stat.c (revision 2311:2d86e52dcdf0)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*2311Sseb  * Common Development and Distribution License (the "License").
6*2311Sseb  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*2311Sseb  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * MAC Services Module
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate 
320Sstevel@tonic-gate #include <sys/types.h>
330Sstevel@tonic-gate #include <sys/sysmacros.h>
340Sstevel@tonic-gate #include <sys/stream.h>
350Sstevel@tonic-gate #include <sys/kstat.h>
360Sstevel@tonic-gate #include <sys/mac.h>
370Sstevel@tonic-gate #include <sys/mac_impl.h>
380Sstevel@tonic-gate 
39*2311Sseb #define	MAC_KSTAT_NAME	"mac"
40*2311Sseb #define	MAC_KSTAT_CLASS	"net"
41*2311Sseb 
42*2311Sseb typedef	int (*ks_update_fnp)(struct kstat *, int);
430Sstevel@tonic-gate 
44*2311Sseb static mac_stat_info_t	i_mac_si[] = {
45*2311Sseb 	{ MAC_STAT_IFSPEED,	"ifspeed",	KSTAT_DATA_UINT64,	0 },
46*2311Sseb 	{ MAC_STAT_MULTIRCV,	"multircv",	KSTAT_DATA_UINT32,	0 },
47*2311Sseb 	{ MAC_STAT_BRDCSTRCV,	"brdcstrcv",	KSTAT_DATA_UINT32,	0 },
48*2311Sseb 	{ MAC_STAT_MULTIXMT,	"multixmt",	KSTAT_DATA_UINT32,	0 },
49*2311Sseb 	{ MAC_STAT_BRDCSTXMT,	"brdcstxmt",	KSTAT_DATA_UINT32,	0 },
50*2311Sseb 	{ MAC_STAT_NORCVBUF,	"norcvbuf",	KSTAT_DATA_UINT32,	0 },
51*2311Sseb 	{ MAC_STAT_IERRORS,	"ierrors",	KSTAT_DATA_UINT32,	0 },
52*2311Sseb 	{ MAC_STAT_UNKNOWNS,	"unknowns",	KSTAT_DATA_UINT32,	0 },
53*2311Sseb 	{ MAC_STAT_NOXMTBUF,	"noxmtbuf",	KSTAT_DATA_UINT32,	0 },
54*2311Sseb 	{ MAC_STAT_OERRORS,	"oerrors",	KSTAT_DATA_UINT32,	0 },
55*2311Sseb 	{ MAC_STAT_COLLISIONS,	"collisions",	KSTAT_DATA_UINT32,	0 },
56*2311Sseb 	{ MAC_STAT_RBYTES,	"rbytes",	KSTAT_DATA_UINT32,	0 },
57*2311Sseb 	{ MAC_STAT_IPACKETS,	"ipackets",	KSTAT_DATA_UINT32,	0 },
58*2311Sseb 	{ MAC_STAT_OBYTES,	"obytes",	KSTAT_DATA_UINT32,	0 },
59*2311Sseb 	{ MAC_STAT_OPACKETS,	"opackets",	KSTAT_DATA_UINT32,	0 },
60*2311Sseb 	{ MAC_STAT_RBYTES,	"rbytes64",	KSTAT_DATA_UINT64,	0 },
61*2311Sseb 	{ MAC_STAT_IPACKETS,	"ipackets64",	KSTAT_DATA_UINT64,	0 },
62*2311Sseb 	{ MAC_STAT_OBYTES,	"obytes64",	KSTAT_DATA_UINT64,	0 },
63*2311Sseb 	{ MAC_STAT_OPACKETS,	"opackets64",	KSTAT_DATA_UINT64,	0 }
640Sstevel@tonic-gate };
650Sstevel@tonic-gate 
66*2311Sseb #define	MAC_NKSTAT \
67*2311Sseb 	(sizeof (i_mac_si) / sizeof (mac_stat_info_t))
68*2311Sseb 
69*2311Sseb static mac_stat_info_t	i_mac_mod_si[] = {
70*2311Sseb 	{ MAC_STAT_LINK_STATE,	"link_state",	KSTAT_DATA_UINT32,
71*2311Sseb 	    (uint64_t)LINK_STATE_UNKNOWN },
72*2311Sseb 	{ MAC_STAT_LINK_UP,	"link_up",	KSTAT_DATA_UINT32,	0 },
73*2311Sseb 	{ MAC_STAT_PROMISC,	"promisc",	KSTAT_DATA_UINT32,	0 }
74*2311Sseb };
75*2311Sseb 
76*2311Sseb #define	MAC_MOD_NKSTAT \
77*2311Sseb 	(sizeof (i_mac_mod_si) / sizeof (mac_stat_info_t))
78*2311Sseb 
79*2311Sseb #define	MAC_MOD_KSTAT_OFFSET	0
80*2311Sseb #define	MAC_KSTAT_OFFSET	MAC_MOD_KSTAT_OFFSET + MAC_MOD_NKSTAT
81*2311Sseb #define	MAC_TYPE_KSTAT_OFFSET	MAC_KSTAT_OFFSET + MAC_NKSTAT
820Sstevel@tonic-gate 
830Sstevel@tonic-gate /*
840Sstevel@tonic-gate  * Private functions.
850Sstevel@tonic-gate  */
860Sstevel@tonic-gate 
870Sstevel@tonic-gate static int
880Sstevel@tonic-gate i_mac_stat_update(kstat_t *ksp, int rw)
890Sstevel@tonic-gate {
900Sstevel@tonic-gate 	mac_impl_t	*mip = ksp->ks_private;
91*2311Sseb 	kstat_named_t	*knp = ksp->ks_data;
920Sstevel@tonic-gate 	uint_t		i;
930Sstevel@tonic-gate 	uint64_t	val;
94*2311Sseb 	mac_stat_info_t	*msi;
95*2311Sseb 	uint_t		msi_index;
960Sstevel@tonic-gate 
970Sstevel@tonic-gate 	if (rw != KSTAT_READ)
980Sstevel@tonic-gate 		return (EACCES);
990Sstevel@tonic-gate 
100*2311Sseb 	for (i = 0; i < mip->mi_kstat_count; i++, msi_index++) {
101*2311Sseb 		if (i == MAC_MOD_KSTAT_OFFSET) {
102*2311Sseb 			msi_index = 0;
103*2311Sseb 			msi = i_mac_mod_si;
104*2311Sseb 		} else if (i == MAC_KSTAT_OFFSET) {
105*2311Sseb 			msi_index = 0;
106*2311Sseb 			msi = i_mac_si;
107*2311Sseb 		} else if (i == MAC_TYPE_KSTAT_OFFSET) {
108*2311Sseb 			msi_index = 0;
109*2311Sseb 			msi = mip->mi_type->mt_stats;
110*2311Sseb 		}
1110Sstevel@tonic-gate 
112*2311Sseb 		val = mac_stat_get((mac_handle_t)mip, msi[msi_index].msi_stat);
113*2311Sseb 		switch (msi[msi_index].msi_type) {
1140Sstevel@tonic-gate 		case KSTAT_DATA_UINT64:
1150Sstevel@tonic-gate 			knp->value.ui64 = val;
1160Sstevel@tonic-gate 			break;
1170Sstevel@tonic-gate 		case KSTAT_DATA_UINT32:
1180Sstevel@tonic-gate 			knp->value.ui32 = (uint32_t)val;
1190Sstevel@tonic-gate 			break;
1200Sstevel@tonic-gate 		default:
1210Sstevel@tonic-gate 			ASSERT(B_FALSE);
1220Sstevel@tonic-gate 			break;
1230Sstevel@tonic-gate 		}
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 		knp++;
1260Sstevel@tonic-gate 	}
1270Sstevel@tonic-gate 
128*2311Sseb 	return (0);
129*2311Sseb }
1300Sstevel@tonic-gate 
131*2311Sseb static void
132*2311Sseb i_mac_kstat_init(kstat_named_t *knp, mac_stat_info_t *si, uint_t count)
133*2311Sseb {
134*2311Sseb 	int i;
135*2311Sseb 	for (i = 0; i < count; i++) {
136*2311Sseb 		kstat_named_init(knp, si[i].msi_name, si[i].msi_type);
137*2311Sseb 		knp++;
138*2311Sseb 	}
1390Sstevel@tonic-gate }
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate /*
1420Sstevel@tonic-gate  * Exported functions.
1430Sstevel@tonic-gate  */
1440Sstevel@tonic-gate 
145*2311Sseb /*
146*2311Sseb  * Create the "mac" kstat.  The "mac" kstat is comprised of three kinds of
147*2311Sseb  * statistics: statistics maintained by the mac module itself, generic mac
148*2311Sseb  * statistics maintained by the driver, and MAC-type specific statistics
149*2311Sseb  * also maintained by the driver.
150*2311Sseb  */
1510Sstevel@tonic-gate void
1520Sstevel@tonic-gate mac_stat_create(mac_impl_t *mip)
1530Sstevel@tonic-gate {
1540Sstevel@tonic-gate 	kstat_t		*ksp;
1550Sstevel@tonic-gate 	kstat_named_t	*knp;
1560Sstevel@tonic-gate 	uint_t		count;
1570Sstevel@tonic-gate 
158*2311Sseb 	count = MAC_MOD_NKSTAT + MAC_NKSTAT + mip->mi_type->mt_statcount;
159*2311Sseb 	ksp = kstat_create((char *)mip->mi_drvname, mip->mi_instance,
160*2311Sseb 	    MAC_KSTAT_NAME, MAC_KSTAT_CLASS, KSTAT_TYPE_NAMED, count, 0);
161*2311Sseb 	if (ksp == NULL)
1620Sstevel@tonic-gate 		return;
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 	ksp->ks_update = i_mac_stat_update;
165*2311Sseb 	ksp->ks_private = mip;
1660Sstevel@tonic-gate 	mip->mi_ksp = ksp;
167*2311Sseb 	mip->mi_kstat_count = count;
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	knp = (kstat_named_t *)ksp->ks_data;
170*2311Sseb 	i_mac_kstat_init(knp, i_mac_mod_si, MAC_MOD_NKSTAT);
171*2311Sseb 	knp += MAC_MOD_NKSTAT;
172*2311Sseb 	i_mac_kstat_init(knp, i_mac_si, MAC_NKSTAT);
173*2311Sseb 	if (mip->mi_type->mt_statcount > 0) {
174*2311Sseb 		knp += MAC_NKSTAT;
175*2311Sseb 		i_mac_kstat_init(knp, mip->mi_type->mt_stats,
176*2311Sseb 		    mip->mi_type->mt_statcount);
1770Sstevel@tonic-gate 	}
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 	kstat_install(ksp);
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate /*ARGSUSED*/
1830Sstevel@tonic-gate void
1840Sstevel@tonic-gate mac_stat_destroy(mac_impl_t *mip)
1850Sstevel@tonic-gate {
186*2311Sseb 	if (mip->mi_ksp != NULL) {
187*2311Sseb 		kstat_delete(mip->mi_ksp);
188*2311Sseb 		mip->mi_ksp = NULL;
189*2311Sseb 		mip->mi_kstat_count = 0;
190*2311Sseb 	}
1910Sstevel@tonic-gate }
192*2311Sseb 
193*2311Sseb uint64_t
194*2311Sseb mac_stat_default(mac_impl_t *mip, uint_t stat)
195*2311Sseb {
196*2311Sseb 	uint_t	stat_index;
197*2311Sseb 
198*2311Sseb 	if (IS_MAC_STAT(stat)) {
199*2311Sseb 		stat_index = stat - MAC_STAT_MIN;
200*2311Sseb 		return (i_mac_si[stat_index].msi_default);
201*2311Sseb 	}
202*2311Sseb 	ASSERT(IS_MACTYPE_STAT(stat));
203*2311Sseb 	stat_index = stat - MACTYPE_STAT_MIN;
204*2311Sseb 	return (mip->mi_type->mt_stats[stat_index].msi_default);
205*2311Sseb }
206