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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Data-Link Services Module 28 */ 29 30 #include <sys/dld_impl.h> 31 #include <sys/mac_ether.h> 32 33 static mac_stat_info_t i_dls_si[] = { 34 { MAC_STAT_IFSPEED, "ifspeed", KSTAT_DATA_UINT64, 0 }, 35 { MAC_STAT_MULTIRCV, "multircv", KSTAT_DATA_UINT32, 0 }, 36 { MAC_STAT_BRDCSTRCV, "brdcstrcv", KSTAT_DATA_UINT32, 0 }, 37 { MAC_STAT_MULTIXMT, "multixmt", KSTAT_DATA_UINT32, 0 }, 38 { MAC_STAT_BRDCSTXMT, "brdcstxmt", KSTAT_DATA_UINT32, 0 }, 39 { MAC_STAT_NORCVBUF, "norcvbuf", KSTAT_DATA_UINT32, 0 }, 40 { MAC_STAT_IERRORS, "ierrors", KSTAT_DATA_UINT32, 0 }, 41 { MAC_STAT_NOXMTBUF, "noxmtbuf", KSTAT_DATA_UINT32, 0 }, 42 { MAC_STAT_OERRORS, "oerrors", KSTAT_DATA_UINT32, 0 }, 43 { MAC_STAT_COLLISIONS, "collisions", KSTAT_DATA_UINT32, 0 }, 44 { MAC_STAT_RBYTES, "rbytes", KSTAT_DATA_UINT32, 0 }, 45 { MAC_STAT_IPACKETS, "ipackets", KSTAT_DATA_UINT32, 0 }, 46 { MAC_STAT_OBYTES, "obytes", KSTAT_DATA_UINT32, 0 }, 47 { MAC_STAT_OPACKETS, "opackets", KSTAT_DATA_UINT32, 0 }, 48 { MAC_STAT_RBYTES, "rbytes64", KSTAT_DATA_UINT64, 0 }, 49 { MAC_STAT_IPACKETS, "ipackets64", KSTAT_DATA_UINT64, 0 }, 50 { MAC_STAT_OBYTES, "obytes64", KSTAT_DATA_UINT64, 0 }, 51 { MAC_STAT_OPACKETS, "opackets64", KSTAT_DATA_UINT64, 0 }, 52 { MAC_STAT_LINK_STATE, "link_state", KSTAT_DATA_UINT32, 53 (uint64_t)LINK_STATE_UNKNOWN} 54 }; 55 56 #define STAT_INFO_COUNT (sizeof (i_dls_si) / sizeof (i_dls_si[0])) 57 58 /* 59 * Exported functions. 60 */ 61 int 62 dls_stat_update(kstat_t *ksp, dls_link_t *dlp, int rw) 63 { 64 kstat_named_t *knp; 65 uint_t i; 66 uint64_t val; 67 68 if (rw != KSTAT_READ) 69 return (EACCES); 70 71 knp = (kstat_named_t *)ksp->ks_data; 72 for (i = 0; i < STAT_INFO_COUNT; i++) { 73 val = mac_stat_get(dlp->dl_mh, i_dls_si[i].msi_stat); 74 75 switch (i_dls_si[i].msi_type) { 76 case KSTAT_DATA_UINT64: 77 knp->value.ui64 = val; 78 break; 79 case KSTAT_DATA_UINT32: 80 knp->value.ui32 = (uint32_t)val; 81 break; 82 default: 83 ASSERT(B_FALSE); 84 } 85 86 knp++; 87 } 88 89 /* 90 * Ethernet specific kstat "link_duplex" 91 */ 92 if (dlp->dl_mip->mi_nativemedia != DL_ETHER) { 93 knp->value.ui32 = LINK_DUPLEX_UNKNOWN; 94 } else { 95 val = mac_stat_get(dlp->dl_mh, ETHER_STAT_LINK_DUPLEX); 96 knp->value.ui32 = (uint32_t)val; 97 } 98 knp++; 99 knp->value.ui32 = dlp->dl_unknowns; 100 101 return (0); 102 } 103 104 int 105 dls_stat_create(const char *module, int instance, const char *name, 106 int (*update)(struct kstat *, int), void *private, kstat_t **kspp) 107 { 108 kstat_t *ksp; 109 kstat_named_t *knp; 110 uint_t i; 111 112 if ((ksp = kstat_create(module, instance, name, "net", 113 KSTAT_TYPE_NAMED, STAT_INFO_COUNT + 2, 0)) == NULL) { 114 return (EINVAL); 115 } 116 117 ksp->ks_update = update; 118 ksp->ks_private = private; 119 120 knp = (kstat_named_t *)ksp->ks_data; 121 for (i = 0; i < STAT_INFO_COUNT; i++) { 122 kstat_named_init(knp, i_dls_si[i].msi_name, 123 i_dls_si[i].msi_type); 124 knp++; 125 } 126 127 kstat_named_init(knp++, "link_duplex", KSTAT_DATA_UINT32); 128 kstat_named_init(knp, "unknowns", KSTAT_DATA_UINT32); 129 kstat_install(ksp); 130 *kspp = ksp; 131 return (0); 132 } 133