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 52311Sseb * Common Development and Distribution License (the "License"). 62311Sseb * 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*4089Sgd78059 * Copyright 2007 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 392311Sseb #define MAC_KSTAT_NAME "mac" 402311Sseb #define MAC_KSTAT_CLASS "net" 412311Sseb 422311Sseb static mac_stat_info_t i_mac_si[] = { 432311Sseb { MAC_STAT_IFSPEED, "ifspeed", KSTAT_DATA_UINT64, 0 }, 442311Sseb { MAC_STAT_MULTIRCV, "multircv", KSTAT_DATA_UINT32, 0 }, 452311Sseb { MAC_STAT_BRDCSTRCV, "brdcstrcv", KSTAT_DATA_UINT32, 0 }, 462311Sseb { MAC_STAT_MULTIXMT, "multixmt", KSTAT_DATA_UINT32, 0 }, 472311Sseb { MAC_STAT_BRDCSTXMT, "brdcstxmt", KSTAT_DATA_UINT32, 0 }, 482311Sseb { MAC_STAT_NORCVBUF, "norcvbuf", KSTAT_DATA_UINT32, 0 }, 492311Sseb { MAC_STAT_IERRORS, "ierrors", KSTAT_DATA_UINT32, 0 }, 502311Sseb { MAC_STAT_UNKNOWNS, "unknowns", KSTAT_DATA_UINT32, 0 }, 512311Sseb { MAC_STAT_NOXMTBUF, "noxmtbuf", KSTAT_DATA_UINT32, 0 }, 522311Sseb { MAC_STAT_OERRORS, "oerrors", KSTAT_DATA_UINT32, 0 }, 532311Sseb { MAC_STAT_COLLISIONS, "collisions", KSTAT_DATA_UINT32, 0 }, 54*4089Sgd78059 { MAC_STAT_UNDERFLOWS, "uflo", KSTAT_DATA_UINT32, 0 }, 55*4089Sgd78059 { MAC_STAT_OVERFLOWS, "oflo", KSTAT_DATA_UINT32, 0 }, 562311Sseb { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT32, 0 }, 572311Sseb { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT32, 0 }, 582311Sseb { MAC_STAT_OBYTES, "obytes", KSTAT_DATA_UINT32, 0 }, 592311Sseb { MAC_STAT_OPACKETS, "opackets", KSTAT_DATA_UINT32, 0 }, 602311Sseb { MAC_STAT_RBYTES, "rbytes64", KSTAT_DATA_UINT64, 0 }, 612311Sseb { MAC_STAT_IPACKETS, "ipackets64", KSTAT_DATA_UINT64, 0 }, 622311Sseb { MAC_STAT_OBYTES, "obytes64", KSTAT_DATA_UINT64, 0 }, 632311Sseb { MAC_STAT_OPACKETS, "opackets64", KSTAT_DATA_UINT64, 0 } 640Sstevel@tonic-gate }; 650Sstevel@tonic-gate 662311Sseb #define MAC_NKSTAT \ 672311Sseb (sizeof (i_mac_si) / sizeof (mac_stat_info_t)) 682311Sseb 692311Sseb static mac_stat_info_t i_mac_mod_si[] = { 702311Sseb { MAC_STAT_LINK_STATE, "link_state", KSTAT_DATA_UINT32, 712311Sseb (uint64_t)LINK_STATE_UNKNOWN }, 722311Sseb { MAC_STAT_LINK_UP, "link_up", KSTAT_DATA_UINT32, 0 }, 732311Sseb { MAC_STAT_PROMISC, "promisc", KSTAT_DATA_UINT32, 0 } 742311Sseb }; 752311Sseb 762311Sseb #define MAC_MOD_NKSTAT \ 772311Sseb (sizeof (i_mac_mod_si) / sizeof (mac_stat_info_t)) 782311Sseb 792311Sseb #define MAC_MOD_KSTAT_OFFSET 0 802311Sseb #define MAC_KSTAT_OFFSET MAC_MOD_KSTAT_OFFSET + MAC_MOD_NKSTAT 812311Sseb #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; 912311Sseb kstat_named_t *knp = ksp->ks_data; 920Sstevel@tonic-gate uint_t i; 930Sstevel@tonic-gate uint64_t val; 942311Sseb mac_stat_info_t *msi; 952311Sseb uint_t msi_index; 960Sstevel@tonic-gate 970Sstevel@tonic-gate if (rw != KSTAT_READ) 980Sstevel@tonic-gate return (EACCES); 990Sstevel@tonic-gate 1002311Sseb for (i = 0; i < mip->mi_kstat_count; i++, msi_index++) { 1012311Sseb if (i == MAC_MOD_KSTAT_OFFSET) { 1022311Sseb msi_index = 0; 1032311Sseb msi = i_mac_mod_si; 1042311Sseb } else if (i == MAC_KSTAT_OFFSET) { 1052311Sseb msi_index = 0; 1062311Sseb msi = i_mac_si; 1072311Sseb } else if (i == MAC_TYPE_KSTAT_OFFSET) { 1082311Sseb msi_index = 0; 1092311Sseb msi = mip->mi_type->mt_stats; 1102311Sseb } 1110Sstevel@tonic-gate 1122311Sseb val = mac_stat_get((mac_handle_t)mip, msi[msi_index].msi_stat); 1132311Sseb 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 1282311Sseb return (0); 1292311Sseb } 1300Sstevel@tonic-gate 1312311Sseb static void 1322311Sseb i_mac_kstat_init(kstat_named_t *knp, mac_stat_info_t *si, uint_t count) 1332311Sseb { 1342311Sseb int i; 1352311Sseb for (i = 0; i < count; i++) { 1362311Sseb kstat_named_init(knp, si[i].msi_name, si[i].msi_type); 1372311Sseb knp++; 1382311Sseb } 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate /* 1420Sstevel@tonic-gate * Exported functions. 1430Sstevel@tonic-gate */ 1440Sstevel@tonic-gate 1452311Sseb /* 1462311Sseb * Create the "mac" kstat. The "mac" kstat is comprised of three kinds of 1472311Sseb * statistics: statistics maintained by the mac module itself, generic mac 1482311Sseb * statistics maintained by the driver, and MAC-type specific statistics 1492311Sseb * also maintained by the driver. 1502311Sseb */ 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 1582311Sseb count = MAC_MOD_NKSTAT + MAC_NKSTAT + mip->mi_type->mt_statcount; 1592951Selowe ksp = kstat_create(mip->mi_drvname, mip->mi_instance, MAC_KSTAT_NAME, 1602951Selowe MAC_KSTAT_CLASS, KSTAT_TYPE_NAMED, count, 0); 1612311Sseb if (ksp == NULL) 1620Sstevel@tonic-gate return; 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate ksp->ks_update = i_mac_stat_update; 1652311Sseb ksp->ks_private = mip; 1660Sstevel@tonic-gate mip->mi_ksp = ksp; 1672311Sseb mip->mi_kstat_count = count; 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate knp = (kstat_named_t *)ksp->ks_data; 1702311Sseb i_mac_kstat_init(knp, i_mac_mod_si, MAC_MOD_NKSTAT); 1712311Sseb knp += MAC_MOD_NKSTAT; 1722311Sseb i_mac_kstat_init(knp, i_mac_si, MAC_NKSTAT); 1732311Sseb if (mip->mi_type->mt_statcount > 0) { 1742311Sseb knp += MAC_NKSTAT; 1752311Sseb i_mac_kstat_init(knp, mip->mi_type->mt_stats, 1762311Sseb 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 { 1862311Sseb if (mip->mi_ksp != NULL) { 1872311Sseb kstat_delete(mip->mi_ksp); 1882311Sseb mip->mi_ksp = NULL; 1892311Sseb mip->mi_kstat_count = 0; 1902311Sseb } 1910Sstevel@tonic-gate } 1922311Sseb 1932311Sseb uint64_t 1942311Sseb mac_stat_default(mac_impl_t *mip, uint_t stat) 1952311Sseb { 1962311Sseb uint_t stat_index; 1972311Sseb 1982311Sseb if (IS_MAC_STAT(stat)) { 1992311Sseb stat_index = stat - MAC_STAT_MIN; 2002311Sseb return (i_mac_si[stat_index].msi_default); 2012311Sseb } 2022311Sseb ASSERT(IS_MACTYPE_STAT(stat)); 2032311Sseb stat_index = stat - MACTYPE_STAT_MIN; 2042311Sseb return (mip->mi_type->mt_stats[stat_index].msi_default); 2052311Sseb } 206