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