1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * MAC Services Module 31 */ 32 33 #include <sys/types.h> 34 #include <sys/sysmacros.h> 35 #include <sys/stream.h> 36 #include <sys/kstat.h> 37 #include <sys/mac.h> 38 #include <sys/mac_impl.h> 39 40 typedef struct i_mac_stat_info_s { 41 enum mac_stat msi_stat; 42 char *msi_name; 43 uint_t msi_type; 44 } i_mac_stat_info_t; 45 46 static i_mac_stat_info_t i_mac_si[] = { 47 { MAC_STAT_IFSPEED, "ifspeed", KSTAT_DATA_UINT64 }, 48 { MAC_STAT_MULTIRCV, "multircv", KSTAT_DATA_UINT32 }, 49 { MAC_STAT_BRDCSTRCV, "brdcstrcv", KSTAT_DATA_UINT32 }, 50 { MAC_STAT_MULTIXMT, "multixmt", KSTAT_DATA_UINT32 }, 51 { MAC_STAT_BRDCSTXMT, "brdcstxmt", KSTAT_DATA_UINT32 }, 52 { MAC_STAT_NORCVBUF, "norcvbuf", KSTAT_DATA_UINT32 }, 53 { MAC_STAT_IERRORS, "ierrors", KSTAT_DATA_UINT32 }, 54 { MAC_STAT_UNKNOWNS, "unknowns", KSTAT_DATA_UINT32 }, 55 { MAC_STAT_NOXMTBUF, "noxmtbuf", KSTAT_DATA_UINT32 }, 56 { MAC_STAT_OERRORS, "oerrors", KSTAT_DATA_UINT32 }, 57 { MAC_STAT_COLLISIONS, "collisions", KSTAT_DATA_UINT32 }, 58 { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT32 }, 59 { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT32 }, 60 { MAC_STAT_OBYTES, "obytes", KSTAT_DATA_UINT32 }, 61 { MAC_STAT_OPACKETS, "opackets", KSTAT_DATA_UINT32 }, 62 { MAC_STAT_RBYTES, "rbytes64", KSTAT_DATA_UINT64 }, 63 { MAC_STAT_IPACKETS, "ipackets64", KSTAT_DATA_UINT64 }, 64 { MAC_STAT_OBYTES, "obytes64", KSTAT_DATA_UINT64 }, 65 { MAC_STAT_OPACKETS, "opackets64", KSTAT_DATA_UINT64 }, 66 { MAC_STAT_ALIGN_ERRORS, "align_errors", KSTAT_DATA_UINT32 }, 67 { MAC_STAT_FCS_ERRORS, "fcs_errors", KSTAT_DATA_UINT32 }, 68 { MAC_STAT_FIRST_COLLISIONS, "first_collsions", KSTAT_DATA_UINT32 }, 69 { MAC_STAT_MULTI_COLLISIONS, "multi_collsions", KSTAT_DATA_UINT32 }, 70 { MAC_STAT_SQE_ERRORS, "sqe_errors", KSTAT_DATA_UINT32 }, 71 { MAC_STAT_DEFER_XMTS, "defer_xmts", KSTAT_DATA_UINT32 }, 72 { MAC_STAT_TX_LATE_COLLISIONS, "tx_late_collsions", KSTAT_DATA_UINT32 }, 73 { MAC_STAT_EX_COLLISIONS, "ex_collsions", KSTAT_DATA_UINT32 }, 74 { MAC_STAT_MACXMT_ERRORS, "macxmt_errors", KSTAT_DATA_UINT32 }, 75 { MAC_STAT_CARRIER_ERRORS, "carrier_errors", KSTAT_DATA_UINT32 }, 76 { MAC_STAT_TOOLONG_ERRORS, "toolong_errors", KSTAT_DATA_UINT32 }, 77 { MAC_STAT_MACRCV_ERRORS, "macrcv_errors", KSTAT_DATA_UINT32 }, 78 { MAC_STAT_XCVR_ADDR, "xcvr_addr", KSTAT_DATA_UINT32 }, 79 { MAC_STAT_XCVR_ID, "xcvr_id", KSTAT_DATA_UINT32 }, 80 { MAC_STAT_XCVR_INUSE, "xcvr_inuse", KSTAT_DATA_UINT32 }, 81 { MAC_STAT_CAP_1000FDX, "cap_1000fdx", KSTAT_DATA_UINT32 }, 82 { MAC_STAT_CAP_1000HDX, "cap_1000hdx", KSTAT_DATA_UINT32 }, 83 { MAC_STAT_CAP_100FDX, "cap_100fdx", KSTAT_DATA_UINT32 }, 84 { MAC_STAT_CAP_100HDX, "cap_100hdx", KSTAT_DATA_UINT32 }, 85 { MAC_STAT_CAP_10FDX, "cap_10fdx", KSTAT_DATA_UINT32 }, 86 { MAC_STAT_CAP_10HDX, "cap_10hdx", KSTAT_DATA_UINT32 }, 87 { MAC_STAT_CAP_ASMPAUSE, "cap_asmpause", KSTAT_DATA_UINT32 }, 88 { MAC_STAT_CAP_PAUSE, "cap_pause", KSTAT_DATA_UINT32 }, 89 { MAC_STAT_CAP_AUTONEG, "cap_autoneg", KSTAT_DATA_UINT32 }, 90 { MAC_STAT_ADV_CAP_1000FDX, "adv_cap_1000fdx", KSTAT_DATA_UINT32 }, 91 { MAC_STAT_ADV_CAP_1000HDX, "adv_cap_1000hdx", KSTAT_DATA_UINT32 }, 92 { MAC_STAT_ADV_CAP_100FDX, "adv_cap_100fdx", KSTAT_DATA_UINT32 }, 93 { MAC_STAT_ADV_CAP_100HDX, "adv_cap_100hdx", KSTAT_DATA_UINT32 }, 94 { MAC_STAT_ADV_CAP_10FDX, "adv_cap_10fdx", KSTAT_DATA_UINT32 }, 95 { MAC_STAT_ADV_CAP_10HDX, "adv_cap_10hdx", KSTAT_DATA_UINT32 }, 96 { MAC_STAT_ADV_CAP_ASMPAUSE, "adv_cap_asmpause", KSTAT_DATA_UINT32 }, 97 { MAC_STAT_ADV_CAP_PAUSE, "adv_cap_pause", KSTAT_DATA_UINT32 }, 98 { MAC_STAT_ADV_CAP_AUTONEG, "adv_cap_autoneg", KSTAT_DATA_UINT32 }, 99 { MAC_STAT_LP_CAP_1000FDX, "lp_cap_1000fdx", KSTAT_DATA_UINT32 }, 100 { MAC_STAT_LP_CAP_1000HDX, "lp_cap_1000hdx", KSTAT_DATA_UINT32 }, 101 { MAC_STAT_LP_CAP_100FDX, "lp_cap_100fdx", KSTAT_DATA_UINT32 }, 102 { MAC_STAT_LP_CAP_100HDX, "lp_cap_100hdx", KSTAT_DATA_UINT32 }, 103 { MAC_STAT_LP_CAP_10FDX, "lp_cap_10fdx", KSTAT_DATA_UINT32 }, 104 { MAC_STAT_LP_CAP_10HDX, "lp_cap_10hdx", KSTAT_DATA_UINT32 }, 105 { MAC_STAT_LP_CAP_ASMPAUSE, "lp_cap_asmpause", KSTAT_DATA_UINT32 }, 106 { MAC_STAT_LP_CAP_PAUSE, "lp_cap_pause", KSTAT_DATA_UINT32 }, 107 { MAC_STAT_LP_CAP_AUTONEG, "lp_cap_autoneg", KSTAT_DATA_UINT32 }, 108 { MAC_STAT_LINK_ASMPAUSE, "link_asmpause", KSTAT_DATA_UINT32 }, 109 { MAC_STAT_LINK_PAUSE, "link_pause", KSTAT_DATA_UINT32 }, 110 { MAC_STAT_LINK_AUTONEG, "link_autoneg", KSTAT_DATA_UINT32 }, 111 { MAC_STAT_LINK_DUPLEX, "link_duplex", KSTAT_DATA_UINT32 } 112 }; 113 114 #define STAT_INFO_COUNT (sizeof (i_mac_si) / sizeof (i_mac_si[0])) 115 116 /* 117 * Private functions. 118 */ 119 120 static int 121 i_mac_stat_update(kstat_t *ksp, int rw) 122 { 123 mac_impl_t *mip = ksp->ks_private; 124 mac_t *mp = mip->mi_mp; 125 kstat_named_t *knp; 126 uint_t i; 127 uint64_t val; 128 129 if (rw != KSTAT_READ) 130 return (EACCES); 131 132 knp = ksp->ks_data; 133 for (i = 0; i < STAT_INFO_COUNT; i++) { 134 if (!(mp->m_info.mi_stat[i_mac_si[i].msi_stat])) 135 continue; 136 137 val = mac_stat_get((mac_handle_t)mip, i_mac_si[i].msi_stat); 138 139 switch (i_mac_si[i].msi_type) { 140 case KSTAT_DATA_UINT64: 141 knp->value.ui64 = val; 142 break; 143 case KSTAT_DATA_UINT32: 144 knp->value.ui32 = (uint32_t)val; 145 break; 146 default: 147 ASSERT(B_FALSE); 148 break; 149 } 150 151 knp++; 152 } 153 154 (knp++)->value.ui32 = mip->mi_link; 155 (knp++)->value.ui32 = (mip->mi_link == LINK_STATE_UP); 156 knp->value.ui32 = (mip->mi_devpromisc != 0); 157 158 return (0); 159 } 160 161 /* 162 * Exported functions. 163 */ 164 165 void 166 mac_stat_create(mac_impl_t *mip) 167 { 168 mac_t *mp = mip->mi_mp; 169 kstat_t *ksp; 170 kstat_named_t *knp; 171 uint_t i; 172 uint_t count; 173 174 count = 0; 175 for (i = 0; i < STAT_INFO_COUNT; i++) { 176 if (mp->m_info.mi_stat[i_mac_si[i].msi_stat]) 177 count++; 178 } 179 180 if ((ksp = kstat_create(mip->mi_dev, mip->mi_port, mip->mi_name, 181 "mac", KSTAT_TYPE_NAMED, count + 3, 0)) == NULL) 182 return; 183 184 ksp->ks_update = i_mac_stat_update; 185 ksp->ks_private = (void *)mip; 186 mip->mi_ksp = ksp; 187 188 knp = (kstat_named_t *)ksp->ks_data; 189 for (i = 0; i < STAT_INFO_COUNT; i++) { 190 if (!(mp->m_info.mi_stat[i_mac_si[i].msi_stat])) 191 continue; 192 193 kstat_named_init(knp, i_mac_si[i].msi_name, 194 i_mac_si[i].msi_type); 195 knp++; 196 --count; 197 } 198 ASSERT(count == 0); 199 200 kstat_named_init(knp++, "link_state", KSTAT_DATA_UINT32); 201 kstat_named_init(knp++, "link_up", KSTAT_DATA_UINT32); 202 kstat_named_init(knp, "promisc", KSTAT_DATA_UINT32); 203 204 kstat_install(ksp); 205 } 206 207 /*ARGSUSED*/ 208 void 209 mac_stat_destroy(mac_impl_t *mip) 210 { 211 kstat_delete(mip->mi_ksp); 212 mip->mi_ksp = NULL; 213 } 214