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 #include "rge.h" 29 30 #define RGE_DBG RGE_DBG_STATS /* debug flag for this code */ 31 32 /* 33 * Local datatype for defining tables of (Offset, Name) pairs 34 */ 35 typedef struct { 36 offset_t index; 37 char *name; 38 } rge_ksindex_t; 39 40 static int 41 rge_params_update(kstat_t *ksp, int flag) 42 { 43 rge_t *rgep; 44 kstat_named_t *knp; 45 int i; 46 47 if (flag != KSTAT_READ) 48 return (EACCES); 49 50 rgep = ksp->ks_private; 51 for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i) 52 knp->value.ui64 = rgep->nd_params[i].ndp_val; 53 54 return (0); 55 } 56 57 58 static const rge_ksindex_t rge_driverinfo[] = { 59 { 0, "rx_ring_addr" }, 60 { 1, "rx_next" }, 61 { 2, "rx_free" }, 62 { 3, "rx_bcopy" }, 63 { 4, "tx_ring_addr" }, 64 { 5, "tx_next" }, 65 { 6, "tx_free" }, 66 { 7, "tx_flow" }, 67 { 8, "resched_needed" }, 68 { 9, "watchdog" }, 69 { 10, "rx_config" }, 70 { 11, "tx_config" }, 71 { 12, "mac_ver" }, 72 { 13, "phy_ver" }, 73 { 14, "chip_reset" }, 74 { 15, "phy_reset" }, 75 { -1, NULL } 76 }; 77 78 static int 79 rge_driverinfo_update(kstat_t *ksp, int flag) 80 { 81 rge_t *rgep; 82 kstat_named_t *knp; 83 84 if (flag != KSTAT_READ) 85 return (EACCES); 86 87 rgep = ksp->ks_private; 88 knp = ksp->ks_data; 89 90 (knp++)->value.ui64 = rgep->dma_area_rxdesc.cookie.dmac_laddress; 91 (knp++)->value.ui64 = rgep->rx_next; 92 (knp++)->value.ui64 = rgep->rx_free; 93 (knp++)->value.ui64 = rgep->rx_bcopy; 94 (knp++)->value.ui64 = rgep->dma_area_txdesc.cookie.dmac_laddress; 95 (knp++)->value.ui64 = rgep->tx_next; 96 (knp++)->value.ui64 = rgep->tx_free; 97 (knp++)->value.ui64 = rgep->tx_flow; 98 (knp++)->value.ui64 = rgep->resched_needed; 99 (knp++)->value.ui64 = rgep->watchdog; 100 (knp++)->value.ui64 = rgep->chipid.rxconfig; 101 (knp++)->value.ui64 = rgep->chipid.txconfig; 102 (knp++)->value.ui64 = rgep->chipid.mac_ver; 103 (knp++)->value.ui64 = rgep->chipid.phy_ver; 104 (knp++)->value.ui64 = rgep->stats.chip_reset; 105 (knp++)->value.ui64 = rgep->stats.phy_reset; 106 107 return (0); 108 } 109 110 static kstat_t * 111 rge_setup_named_kstat(rge_t *rgep, int instance, char *name, 112 const rge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int)) 113 { 114 kstat_t *ksp; 115 kstat_named_t *knp; 116 char *np; 117 int type; 118 119 size /= sizeof (rge_ksindex_t); 120 ksp = kstat_create(RGE_DRIVER_NAME, instance, name, "net", 121 KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT); 122 if (ksp == NULL) 123 return (NULL); 124 125 ksp->ks_private = rgep; 126 ksp->ks_update = update; 127 for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) { 128 switch (*np) { 129 default: 130 type = KSTAT_DATA_UINT64; 131 break; 132 case '%': 133 np += 1; 134 type = KSTAT_DATA_UINT32; 135 break; 136 case '$': 137 np += 1; 138 type = KSTAT_DATA_STRING; 139 break; 140 case '&': 141 np += 1; 142 type = KSTAT_DATA_CHAR; 143 break; 144 } 145 kstat_named_init(knp, np, type); 146 } 147 kstat_install(ksp); 148 149 return (ksp); 150 } 151 152 /* 153 * Create kstats corresponding to NDD parameters 154 */ 155 static kstat_t * 156 rge_setup_params_kstat(rge_t *rgep, int instance, char *name, 157 int (*update)(kstat_t *, int)) 158 { 159 kstat_t *ksp; 160 kstat_named_t *knp; 161 int i; 162 163 ksp = kstat_create(RGE_DRIVER_NAME, instance, name, "net", 164 KSTAT_TYPE_NAMED, PARAM_COUNT, KSTAT_FLAG_PERSISTENT); 165 if (ksp != NULL) { 166 ksp->ks_private = rgep; 167 ksp->ks_update = update; 168 for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i) 169 kstat_named_init(knp, rgep->nd_params[i].ndp_name+1, 170 KSTAT_DATA_UINT64); 171 kstat_install(ksp); 172 } 173 174 return (ksp); 175 } 176 177 void 178 rge_init_kstats(rge_t *rgep, int instance) 179 { 180 rgep->rge_kstats[RGE_KSTAT_PARAMS] = rge_setup_params_kstat(rgep, 181 instance, "parameters", rge_params_update); 182 183 rgep->rge_kstats[RGE_KSTAT_DRIVER] = rge_setup_named_kstat(rgep, 184 instance, "driverinfo", rge_driverinfo, 185 sizeof (rge_driverinfo), rge_driverinfo_update); 186 } 187 188 void 189 rge_fini_kstats(rge_t *rgep) 190 { 191 int i; 192 193 for (i = RGE_KSTAT_COUNT; --i >= 0; ) 194 if (rgep->rge_kstats[i] != NULL) { 195 kstat_delete(rgep->rge_kstats[i]); 196 } 197 } 198 199 int 200 rge_m_stat(void *arg, uint_t stat, uint64_t *val) 201 { 202 rge_t *rgep = arg; 203 rge_hw_stats_t *bstp; 204 205 mutex_enter(rgep->genlock); 206 rge_hw_stats_dump(rgep); 207 mutex_exit(rgep->genlock); 208 bstp = rgep->hw_stats; 209 210 switch (stat) { 211 case MAC_STAT_IFSPEED: 212 *val = rgep->param_link_speed * 1000000ull; 213 break; 214 215 case MAC_STAT_MULTIRCV: 216 *val = RGE_BSWAP_32(bstp->multi_rcv); 217 break; 218 219 case MAC_STAT_BRDCSTRCV: 220 *val = RGE_BSWAP_64(bstp->brdcst_rcv); 221 break; 222 223 case MAC_STAT_NORCVBUF: 224 *val = RGE_BSWAP_16(bstp->in_discards); 225 break; 226 227 case MAC_STAT_IERRORS: 228 *val = RGE_BSWAP_32(bstp->rcv_err); 229 break; 230 231 case MAC_STAT_OERRORS: 232 *val = RGE_BSWAP_64(bstp->xmt_err); 233 break; 234 235 case MAC_STAT_COLLISIONS: 236 *val = RGE_BSWAP_32(bstp->xmt_1col + bstp->xmt_mcol); 237 break; 238 239 case MAC_STAT_RBYTES: 240 *val = rgep->stats.rbytes; 241 break; 242 243 case MAC_STAT_IPACKETS: 244 *val = RGE_BSWAP_64(bstp->rcv_ok); 245 break; 246 247 case MAC_STAT_OBYTES: 248 *val = rgep->stats.obytes; 249 break; 250 251 case MAC_STAT_OPACKETS: 252 *val = RGE_BSWAP_64(bstp->xmt_ok); 253 break; 254 255 case ETHER_STAT_ALIGN_ERRORS: 256 *val = RGE_BSWAP_16(bstp->frame_err); 257 break; 258 259 case ETHER_STAT_FIRST_COLLISIONS: 260 *val = RGE_BSWAP_32(bstp->xmt_1col); 261 break; 262 263 case ETHER_STAT_MULTI_COLLISIONS: 264 *val = RGE_BSWAP_32(bstp->xmt_mcol); 265 break; 266 267 case ETHER_STAT_DEFER_XMTS: 268 *val = rgep->stats.defer; 269 break; 270 271 case ETHER_STAT_XCVR_ADDR: 272 *val = rgep->phy_mii_addr; 273 break; 274 275 case ETHER_STAT_XCVR_ID: 276 mutex_enter(rgep->genlock); 277 *val = rge_mii_get16(rgep, MII_PHYIDH); 278 *val <<= 16; 279 *val |= rge_mii_get16(rgep, MII_PHYIDL); 280 mutex_exit(rgep->genlock); 281 break; 282 283 case ETHER_STAT_XCVR_INUSE: 284 *val = XCVR_1000T; 285 break; 286 287 case ETHER_STAT_CAP_1000FDX: 288 *val = 1; 289 break; 290 291 case ETHER_STAT_CAP_1000HDX: 292 *val = 0; 293 break; 294 295 case ETHER_STAT_CAP_100FDX: 296 *val = 1; 297 break; 298 299 case ETHER_STAT_CAP_100HDX: 300 *val = 1; 301 break; 302 303 case ETHER_STAT_CAP_10FDX: 304 *val = 1; 305 break; 306 307 case ETHER_STAT_CAP_10HDX: 308 *val = 1; 309 break; 310 311 case ETHER_STAT_CAP_ASMPAUSE: 312 *val = 1; 313 break; 314 315 case ETHER_STAT_CAP_PAUSE: 316 *val = 1; 317 break; 318 319 case ETHER_STAT_CAP_AUTONEG: 320 *val = 1; 321 break; 322 323 case ETHER_STAT_ADV_CAP_1000FDX: 324 *val = rgep->param_adv_1000fdx; 325 break; 326 327 case ETHER_STAT_ADV_CAP_1000HDX: 328 *val = rgep->param_adv_1000hdx; 329 break; 330 331 case ETHER_STAT_ADV_CAP_100FDX: 332 *val = rgep->param_adv_100fdx; 333 break; 334 335 case ETHER_STAT_ADV_CAP_100HDX: 336 *val = rgep->param_adv_100hdx; 337 break; 338 339 case ETHER_STAT_ADV_CAP_10FDX: 340 *val = rgep->param_adv_10fdx; 341 break; 342 343 case ETHER_STAT_ADV_CAP_10HDX: 344 *val = rgep->param_adv_10hdx; 345 break; 346 347 case ETHER_STAT_ADV_CAP_ASMPAUSE: 348 *val = rgep->param_adv_asym_pause; 349 break; 350 351 case ETHER_STAT_ADV_CAP_PAUSE: 352 *val = rgep->param_adv_pause; 353 break; 354 355 case ETHER_STAT_ADV_CAP_AUTONEG: 356 *val = rgep->param_adv_autoneg; 357 break; 358 359 case ETHER_STAT_LINK_DUPLEX: 360 *val = rgep->param_link_duplex; 361 break; 362 363 default: 364 return (ENOTSUP); 365 } 366 367 return (0); 368 } 369