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