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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Data-Link Services Module 30 */ 31 32 #include <sys/types.h> 33 #include <sys/sysmacros.h> 34 #include <sys/atomic.h> 35 #include <sys/kstat.h> 36 #include <sys/vlan.h> 37 #include <sys/mac.h> 38 #include <sys/ctype.h> 39 #include <sys/dls.h> 40 #include <sys/dls_impl.h> 41 42 static mac_stat_info_t i_dls_si[] = { 43 { MAC_STAT_IFSPEED, "ifspeed", KSTAT_DATA_UINT64, 0 }, 44 { MAC_STAT_MULTIRCV, "multircv", KSTAT_DATA_UINT32, 0 }, 45 { MAC_STAT_BRDCSTRCV, "brdcstrcv", KSTAT_DATA_UINT32, 0 }, 46 { MAC_STAT_MULTIXMT, "multixmt", KSTAT_DATA_UINT32, 0 }, 47 { MAC_STAT_BRDCSTXMT, "brdcstxmt", KSTAT_DATA_UINT32, 0 }, 48 { MAC_STAT_NORCVBUF, "norcvbuf", KSTAT_DATA_UINT32, 0 }, 49 { MAC_STAT_IERRORS, "ierrors", KSTAT_DATA_UINT32, 0 }, 50 { MAC_STAT_NOXMTBUF, "noxmtbuf", KSTAT_DATA_UINT32, 0 }, 51 { MAC_STAT_OERRORS, "oerrors", KSTAT_DATA_UINT32, 0 }, 52 { MAC_STAT_COLLISIONS, "collisions", KSTAT_DATA_UINT32, 0 }, 53 { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT32, 0 }, 54 { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT32, 0 }, 55 { MAC_STAT_OBYTES, "obytes", KSTAT_DATA_UINT32, 0 }, 56 { MAC_STAT_OPACKETS, "opackets", KSTAT_DATA_UINT32, 0 }, 57 { MAC_STAT_RBYTES, "rbytes64", KSTAT_DATA_UINT64, 0 }, 58 { MAC_STAT_IPACKETS, "ipackets64", KSTAT_DATA_UINT64, 0 }, 59 { MAC_STAT_OBYTES, "obytes64", KSTAT_DATA_UINT64, 0 }, 60 { MAC_STAT_OPACKETS, "opackets64", KSTAT_DATA_UINT64, 0 } 61 }; 62 63 #define STAT_INFO_COUNT (sizeof (i_dls_si) / sizeof (i_dls_si[0])) 64 65 /* 66 * Private functions. 67 */ 68 69 static int 70 i_dls_stat_update(kstat_t *ksp, int rw) 71 { 72 dls_vlan_t *dvp = ksp->ks_private; 73 dls_link_t *dlp = dvp->dv_dlp; 74 kstat_named_t *knp; 75 uint_t i; 76 uint64_t val; 77 int err; 78 79 if (rw != KSTAT_READ) 80 return (EACCES); 81 82 if ((err = dls_mac_hold(dlp)) != 0) 83 return (err); 84 85 knp = (kstat_named_t *)ksp->ks_data; 86 for (i = 0; i < STAT_INFO_COUNT; i++) { 87 val = mac_stat_get(dlp->dl_mh, i_dls_si[i].msi_stat); 88 89 switch (i_dls_si[i].msi_type) { 90 case KSTAT_DATA_UINT64: 91 knp->value.ui64 = val; 92 break; 93 case KSTAT_DATA_UINT32: 94 knp->value.ui32 = (uint32_t)val; 95 break; 96 default: 97 ASSERT(B_FALSE); 98 } 99 100 knp++; 101 } 102 103 knp->value.ui32 = dlp->dl_unknowns; 104 dls_mac_rele(dlp); 105 106 return (0); 107 } 108 109 /* 110 * Exported functions. 111 */ 112 113 void 114 dls_mac_stat_create(dls_vlan_t *dvp) 115 { 116 dls_link_t *dlp = dvp->dv_dlp; 117 char module[IFNAMSIZ]; 118 uint_t instance; 119 kstat_t *ksp; 120 kstat_named_t *knp; 121 uint_t i; 122 int err; 123 124 if (dls_mac_hold(dlp) != 0) 125 return; 126 127 err = ddi_parse(dvp->dv_name, module, &instance); 128 ASSERT(err == DDI_SUCCESS); 129 130 if ((ksp = kstat_create(module, instance, NULL, "net", 131 KSTAT_TYPE_NAMED, STAT_INFO_COUNT + 1, 0)) == NULL) 132 goto done; 133 134 ksp->ks_update = i_dls_stat_update; 135 ksp->ks_private = (void *)dvp; 136 dvp->dv_ksp = ksp; 137 138 knp = (kstat_named_t *)ksp->ks_data; 139 for (i = 0; i < STAT_INFO_COUNT; i++) { 140 kstat_named_init(knp, i_dls_si[i].msi_name, 141 i_dls_si[i].msi_type); 142 knp++; 143 } 144 145 kstat_named_init(knp, "unknowns", KSTAT_DATA_UINT32); 146 147 kstat_install(ksp); 148 done: 149 dls_mac_rele(dlp); 150 } 151 152 void 153 dls_mac_stat_destroy(dls_vlan_t *dvp) 154 { 155 kstat_delete(dvp->dv_ksp); 156 dvp->dv_ksp = NULL; 157 } 158