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 /* 222311Sseb * 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 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 }, 542311Sseb { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT32, 0 }, 552311Sseb { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT32, 0 }, 562311Sseb { MAC_STAT_OBYTES, "obytes", KSTAT_DATA_UINT32, 0 }, 572311Sseb { MAC_STAT_OPACKETS, "opackets", KSTAT_DATA_UINT32, 0 }, 582311Sseb { MAC_STAT_RBYTES, "rbytes64", KSTAT_DATA_UINT64, 0 }, 592311Sseb { MAC_STAT_IPACKETS, "ipackets64", KSTAT_DATA_UINT64, 0 }, 602311Sseb { MAC_STAT_OBYTES, "obytes64", KSTAT_DATA_UINT64, 0 }, 612311Sseb { MAC_STAT_OPACKETS, "opackets64", KSTAT_DATA_UINT64, 0 } 620Sstevel@tonic-gate }; 630Sstevel@tonic-gate 642311Sseb #define MAC_NKSTAT \ 652311Sseb (sizeof (i_mac_si) / sizeof (mac_stat_info_t)) 662311Sseb 672311Sseb static mac_stat_info_t i_mac_mod_si[] = { 682311Sseb { MAC_STAT_LINK_STATE, "link_state", KSTAT_DATA_UINT32, 692311Sseb (uint64_t)LINK_STATE_UNKNOWN }, 702311Sseb { MAC_STAT_LINK_UP, "link_up", KSTAT_DATA_UINT32, 0 }, 712311Sseb { MAC_STAT_PROMISC, "promisc", KSTAT_DATA_UINT32, 0 } 722311Sseb }; 732311Sseb 742311Sseb #define MAC_MOD_NKSTAT \ 752311Sseb (sizeof (i_mac_mod_si) / sizeof (mac_stat_info_t)) 762311Sseb 772311Sseb #define MAC_MOD_KSTAT_OFFSET 0 782311Sseb #define MAC_KSTAT_OFFSET MAC_MOD_KSTAT_OFFSET + MAC_MOD_NKSTAT 792311Sseb #define MAC_TYPE_KSTAT_OFFSET MAC_KSTAT_OFFSET + MAC_NKSTAT 800Sstevel@tonic-gate 810Sstevel@tonic-gate /* 820Sstevel@tonic-gate * Private functions. 830Sstevel@tonic-gate */ 840Sstevel@tonic-gate 850Sstevel@tonic-gate static int 860Sstevel@tonic-gate i_mac_stat_update(kstat_t *ksp, int rw) 870Sstevel@tonic-gate { 880Sstevel@tonic-gate mac_impl_t *mip = ksp->ks_private; 892311Sseb kstat_named_t *knp = ksp->ks_data; 900Sstevel@tonic-gate uint_t i; 910Sstevel@tonic-gate uint64_t val; 922311Sseb mac_stat_info_t *msi; 932311Sseb uint_t msi_index; 940Sstevel@tonic-gate 950Sstevel@tonic-gate if (rw != KSTAT_READ) 960Sstevel@tonic-gate return (EACCES); 970Sstevel@tonic-gate 982311Sseb for (i = 0; i < mip->mi_kstat_count; i++, msi_index++) { 992311Sseb if (i == MAC_MOD_KSTAT_OFFSET) { 1002311Sseb msi_index = 0; 1012311Sseb msi = i_mac_mod_si; 1022311Sseb } else if (i == MAC_KSTAT_OFFSET) { 1032311Sseb msi_index = 0; 1042311Sseb msi = i_mac_si; 1052311Sseb } else if (i == MAC_TYPE_KSTAT_OFFSET) { 1062311Sseb msi_index = 0; 1072311Sseb msi = mip->mi_type->mt_stats; 1082311Sseb } 1090Sstevel@tonic-gate 1102311Sseb val = mac_stat_get((mac_handle_t)mip, msi[msi_index].msi_stat); 1112311Sseb switch (msi[msi_index].msi_type) { 1120Sstevel@tonic-gate case KSTAT_DATA_UINT64: 1130Sstevel@tonic-gate knp->value.ui64 = val; 1140Sstevel@tonic-gate break; 1150Sstevel@tonic-gate case KSTAT_DATA_UINT32: 1160Sstevel@tonic-gate knp->value.ui32 = (uint32_t)val; 1170Sstevel@tonic-gate break; 1180Sstevel@tonic-gate default: 1190Sstevel@tonic-gate ASSERT(B_FALSE); 1200Sstevel@tonic-gate break; 1210Sstevel@tonic-gate } 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate knp++; 1240Sstevel@tonic-gate } 1250Sstevel@tonic-gate 1262311Sseb return (0); 1272311Sseb } 1280Sstevel@tonic-gate 1292311Sseb static void 1302311Sseb i_mac_kstat_init(kstat_named_t *knp, mac_stat_info_t *si, uint_t count) 1312311Sseb { 1322311Sseb int i; 1332311Sseb for (i = 0; i < count; i++) { 1342311Sseb kstat_named_init(knp, si[i].msi_name, si[i].msi_type); 1352311Sseb knp++; 1362311Sseb } 1370Sstevel@tonic-gate } 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate /* 1400Sstevel@tonic-gate * Exported functions. 1410Sstevel@tonic-gate */ 1420Sstevel@tonic-gate 1432311Sseb /* 1442311Sseb * Create the "mac" kstat. The "mac" kstat is comprised of three kinds of 1452311Sseb * statistics: statistics maintained by the mac module itself, generic mac 1462311Sseb * statistics maintained by the driver, and MAC-type specific statistics 1472311Sseb * also maintained by the driver. 1482311Sseb */ 1490Sstevel@tonic-gate void 1500Sstevel@tonic-gate mac_stat_create(mac_impl_t *mip) 1510Sstevel@tonic-gate { 1520Sstevel@tonic-gate kstat_t *ksp; 1530Sstevel@tonic-gate kstat_named_t *knp; 1540Sstevel@tonic-gate uint_t count; 1550Sstevel@tonic-gate 1562311Sseb count = MAC_MOD_NKSTAT + MAC_NKSTAT + mip->mi_type->mt_statcount; 157*2951Selowe ksp = kstat_create(mip->mi_drvname, mip->mi_instance, MAC_KSTAT_NAME, 158*2951Selowe MAC_KSTAT_CLASS, KSTAT_TYPE_NAMED, count, 0); 1592311Sseb if (ksp == NULL) 1600Sstevel@tonic-gate return; 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate ksp->ks_update = i_mac_stat_update; 1632311Sseb ksp->ks_private = mip; 1640Sstevel@tonic-gate mip->mi_ksp = ksp; 1652311Sseb mip->mi_kstat_count = count; 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate knp = (kstat_named_t *)ksp->ks_data; 1682311Sseb i_mac_kstat_init(knp, i_mac_mod_si, MAC_MOD_NKSTAT); 1692311Sseb knp += MAC_MOD_NKSTAT; 1702311Sseb i_mac_kstat_init(knp, i_mac_si, MAC_NKSTAT); 1712311Sseb if (mip->mi_type->mt_statcount > 0) { 1722311Sseb knp += MAC_NKSTAT; 1732311Sseb i_mac_kstat_init(knp, mip->mi_type->mt_stats, 1742311Sseb mip->mi_type->mt_statcount); 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate kstat_install(ksp); 1780Sstevel@tonic-gate } 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate /*ARGSUSED*/ 1810Sstevel@tonic-gate void 1820Sstevel@tonic-gate mac_stat_destroy(mac_impl_t *mip) 1830Sstevel@tonic-gate { 1842311Sseb if (mip->mi_ksp != NULL) { 1852311Sseb kstat_delete(mip->mi_ksp); 1862311Sseb mip->mi_ksp = NULL; 1872311Sseb mip->mi_kstat_count = 0; 1882311Sseb } 1890Sstevel@tonic-gate } 1902311Sseb 1912311Sseb uint64_t 1922311Sseb mac_stat_default(mac_impl_t *mip, uint_t stat) 1932311Sseb { 1942311Sseb uint_t stat_index; 1952311Sseb 1962311Sseb if (IS_MAC_STAT(stat)) { 1972311Sseb stat_index = stat - MAC_STAT_MIN; 1982311Sseb return (i_mac_si[stat_index].msi_default); 1992311Sseb } 2002311Sseb ASSERT(IS_MACTYPE_STAT(stat)); 2012311Sseb stat_index = stat - MACTYPE_STAT_MIN; 2022311Sseb return (mip->mi_type->mt_stats[stat_index].msi_default); 2032311Sseb } 204