1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * This file may contain confidential information of Nvidia 8 * and should not be distributed in source form without approval 9 * from Sun Legal. 10 */ 11 12 #pragma ident "%Z%%M% %I% %E% SMI" 13 14 #include "nge.h" 15 16 #undef NGE_DBG 17 #define NGE_DBG NGE_DBG_STATS /* debug flag for this code */ 18 19 /* 20 * Table of Hardware-defined Statistics Block Offsets and Names 21 */ 22 #define KS_NAME(s) { KS_ ## s, #s } 23 24 const nge_ksindex_t nge_statistics[] = { 25 26 KS_NAME(ifHOutOctets), 27 KS_NAME(ifHOutZeroRetranCount), 28 KS_NAME(ifHOutOneRetranCount), 29 KS_NAME(ifHOutMoreRetranCount), 30 KS_NAME(ifHOutColCount), 31 KS_NAME(ifHOutFifoovCount), 32 KS_NAME(ifHOutLOCCount), 33 KS_NAME(ifHOutExDecCount), 34 KS_NAME(ifHOutRetryCount), 35 KS_NAME(ifHInFrameErrCount), 36 KS_NAME(ifHInExtraOctErrCount), 37 KS_NAME(ifHInLColErrCount), 38 KS_NAME(ifHInOversizeErrCount), 39 KS_NAME(ifHInFovErrCount), 40 KS_NAME(ifHInFCSErrCount), 41 KS_NAME(ifHInAlignErrCount), 42 KS_NAME(ifHInLenErrCount), 43 KS_NAME(ifHInUniPktsCount), 44 KS_NAME(ifHInBroadPksCount), 45 KS_NAME(ifHInMulPksCount), 46 { KS_STATS_SIZE, NULL } 47 }; 48 49 /* 50 * Local datatype for defining tables of (Offset, Name) pairs 51 */ 52 static int 53 nge_statistics_update(kstat_t *ksp, int flag) 54 { 55 uint32_t regno; 56 nge_t *ngep; 57 nge_statistics_t *istp; 58 nge_hw_statistics_t *hw_stp; 59 kstat_named_t *knp; 60 const nge_ksindex_t *ksip; 61 62 if (flag != KSTAT_READ) 63 return (EACCES); 64 65 ngep = ksp->ks_private; 66 istp = &ngep->statistics; 67 hw_stp = &istp->hw_statistics; 68 knp = ksp->ks_data; 69 70 /* 71 * Transfer the statistics values from the hardware statistics regs 72 */ 73 for (ksip = nge_statistics; ksip->name != NULL; ++knp, ++ksip) { 74 regno = KS_BASE + ksip->index * sizeof (uint32_t); 75 hw_stp->a[ksip->index] = nge_reg_get32(ngep, regno); 76 knp->value.ui64 += hw_stp->a[ksip->index]; 77 } 78 79 return (0); 80 } 81 82 83 static const nge_ksindex_t nge_chipinfo[] = { 84 { 0, "businfo" }, 85 { 1, "command" }, 86 { 2, "vendor_id" }, 87 { 3, "device_id" }, 88 { 4, "subsystem_vendor_id" }, 89 { 5, "subsystem_device_id" }, 90 { 6, "revision_id" }, 91 { 7, "cache_line_size" }, 92 { 8, "latency_timer" }, 93 { 9, "phy_mode" }, 94 { 10, "phy_id" }, 95 { 11, "hw_mac_addr" }, 96 { 12, "&bus_type" }, 97 { 13, "&bus_speed" }, 98 { 14, "&bus_size" }, 99 { -1, NULL } 100 }; 101 102 static const nge_ksindex_t nge_debuginfo[] = { 103 { 0, "rx_realloc" }, 104 { 1, "rx_realloc_fails" }, 105 { 2, "rx_realloc_DMA_fails" }, 106 { 3, "rx_realloc_MP_fails" }, 107 { 4, "rx_rcfree" }, 108 { 5, "context_switch" }, 109 { 6, "ip_hsum_err" }, 110 { 7, "tcp_hsum_err" }, 111 { 8, "tc_next" }, 112 { 9, "tx_next" }, 113 { 10, "tx_free" }, 114 { 11, "tx_flow" }, 115 { 12, "rx_prod" }, 116 { 13, "rx_hold" }, 117 { 14, "rx_nobuf" }, 118 { 15, "rx_err" }, 119 {16, "tx_err" }, 120 {17, "tx_stall" }, 121 { -1, NULL } 122 }; 123 124 static int 125 nge_chipinfo_update(kstat_t *ksp, int flag) 126 { 127 nge_t *ngep; 128 kstat_named_t *knp; 129 chip_info_t *infop; 130 131 if (flag != KSTAT_READ) 132 return (EACCES); 133 134 ngep = ksp->ks_private; 135 infop = &ngep->chipinfo; 136 knp = ksp->ks_data; 137 138 (knp++)->value.ui64 = infop->businfo; 139 (knp++)->value.ui64 = infop->command; 140 (knp++)->value.ui64 = infop->vendor; 141 (knp++)->value.ui64 = infop->device; 142 (knp++)->value.ui64 = infop->subven; 143 (knp++)->value.ui64 = infop->subdev; 144 (knp++)->value.ui64 = infop->revision; 145 (knp++)->value.ui64 = infop->clsize; 146 (knp++)->value.ui64 = infop->latency; 147 (knp++)->value.ui64 = ngep->phy_mode; 148 (knp++)->value.ui64 = ngep->phy_id; 149 (knp++)->value.ui64 = infop->hw_mac_addr; 150 return (0); 151 } 152 153 static int 154 nge_debuginfo_update(kstat_t *ksp, int flag) 155 { 156 nge_t *ngep; 157 kstat_named_t *knp; 158 nge_sw_statistics_t *sw_stp; 159 160 if (flag != KSTAT_READ) 161 return (EACCES); 162 163 ngep = ksp->ks_private; 164 sw_stp = &ngep->statistics.sw_statistics; 165 knp = ksp->ks_data; 166 167 (knp++)->value.ui64 = sw_stp->recv_realloc; 168 (knp++)->value.ui64 = sw_stp->kmem_alloc_err; 169 (knp++)->value.ui64 = sw_stp->dma_alloc_err; 170 (knp++)->value.ui64 = sw_stp->mp_alloc_err; 171 (knp++)->value.ui64 = sw_stp->recy_free; 172 (knp++)->value.ui64 = sw_stp->load_context; 173 (knp++)->value.ui64 = sw_stp->ip_hwsum_err; 174 (knp++)->value.ui64 = sw_stp->tcp_hwsum_err; 175 (knp++)->value.ui64 = ngep->send->tc_next; 176 (knp++)->value.ui64 = ngep->send->tx_next; 177 (knp++)->value.ui64 = ngep->send->tx_free; 178 (knp++)->value.ui64 = ngep->send->tx_flow; 179 (knp++)->value.ui64 = ngep->recv->prod_index; 180 (knp++)->value.ui64 = ngep->buff->rx_hold; 181 (knp++)->value.ui64 = sw_stp->rx_nobuffer; 182 (knp++)->value.ui64 = sw_stp->rx_err; 183 (knp++)->value.ui64 = sw_stp->tx_stop_err; 184 (knp++)->value.ui64 = sw_stp->tx_stall; 185 return (0); 186 } 187 188 static kstat_t * 189 nge_setup_named_kstat(nge_t *ngep, int instance, char *name, 190 const nge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int)) 191 { 192 kstat_t *ksp; 193 kstat_named_t *knp; 194 char *np; 195 int type; 196 197 size /= sizeof (nge_ksindex_t); 198 ksp = kstat_create(NGE_DRIVER_NAME, instance, name, "net", 199 KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT); 200 if (ksp == NULL) 201 return (NULL); 202 203 ksp->ks_private = ngep; 204 ksp->ks_update = update; 205 for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) { 206 switch (*np) { 207 default: 208 type = KSTAT_DATA_UINT64; 209 break; 210 case '%': 211 np += 1; 212 type = KSTAT_DATA_UINT32; 213 break; 214 215 case '$': 216 np ++; 217 type = KSTAT_DATA_STRING; 218 break; 219 case '&': 220 np ++; 221 type = KSTAT_DATA_CHAR; 222 break; 223 } 224 kstat_named_init(knp, np, type); 225 } 226 kstat_install(ksp); 227 228 return (ksp); 229 } 230 231 /* 232 * Create kstats corresponding to NDD parameters 233 */ 234 static kstat_t * 235 nge_setup_params_kstat(nge_t *ngep, int instance, char *name, 236 int (*update)(kstat_t *, int)) 237 { 238 kstat_t *ksp; 239 kstat_named_t *knp; 240 int i; 241 242 ksp = kstat_create(NGE_DRIVER_NAME, instance, name, "net", 243 KSTAT_TYPE_NAMED, PARAM_COUNT, KSTAT_FLAG_PERSISTENT); 244 if (ksp != NULL) { 245 ksp->ks_private = ngep; 246 ksp->ks_update = update; 247 for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i) 248 kstat_named_init(knp, ngep->nd_params[i].ndp_name+1, 249 KSTAT_DATA_UINT64); 250 kstat_install(ksp); 251 } 252 253 return (ksp); 254 } 255 256 void 257 nge_init_kstats(nge_t *ngep, int instance) 258 { 259 const nge_ksindex_t *ksip; 260 261 NGE_TRACE(("nge_init_kstats($%p, %d)", (void *)ngep, instance)); 262 for (ksip = nge_statistics; ksip->name != NULL; ++ksip) { 263 (void) nge_reg_get32(ngep, 264 (nge_regno_t)(KS_BASE + sizeof (uint32_t)*ksip->index)); 265 } 266 267 ngep->nge_kstats[NGE_KSTAT_STATS] = nge_setup_named_kstat(ngep, 268 instance, "statistics", nge_statistics, 269 sizeof (nge_statistics), nge_statistics_update); 270 271 ngep->nge_kstats[NGE_KSTAT_CHIPID] = nge_setup_named_kstat(ngep, 272 instance, "chipinfo", nge_chipinfo, 273 sizeof (nge_chipinfo), nge_chipinfo_update); 274 275 ngep->nge_kstats[NGE_KSTAT_DEBUG] = nge_setup_named_kstat(ngep, 276 instance, "driver-debug", nge_debuginfo, 277 sizeof (nge_debuginfo), nge_debuginfo_update); 278 279 } 280 281 void 282 nge_fini_kstats(nge_t *ngep) 283 { 284 int i; 285 286 NGE_TRACE(("nge_fini_kstats($%p)", (void *)ngep)); 287 for (i = NGE_KSTAT_COUNT; --i >= 0; ) 288 if (ngep->nge_kstats[i] != NULL) 289 kstat_delete(ngep->nge_kstats[i]); 290 } 291 292 int 293 nge_m_stat(void *arg, uint_t stat, uint64_t *val) 294 { 295 nge_t *ngep = arg; 296 nge_statistics_t *nstp = &ngep->statistics; 297 nge_hw_statistics_t *hw_stp = &nstp->hw_statistics; 298 nge_sw_statistics_t *sw_stp = &nstp->sw_statistics; 299 300 switch (stat) { 301 case MAC_STAT_IFSPEED: 302 *val = ngep->param_link_speed * 1000000ull; 303 break; 304 305 case MAC_STAT_MULTIRCV: 306 *val = hw_stp->s.InMulPksCount; 307 break; 308 309 case MAC_STAT_BRDCSTRCV: 310 *val = hw_stp->s.InBroadPksCount; 311 break; 312 313 case MAC_STAT_NORCVBUF: 314 *val = sw_stp->rx_nobuffer; 315 break; 316 317 case MAC_STAT_IERRORS: 318 *val = hw_stp->s.InFrameErrCount + 319 hw_stp->s.InExtraOctErrCount + 320 hw_stp->s.InLColErrCount + 321 hw_stp->s.InOversizeErrCount + 322 hw_stp->s.InFovErrCount + 323 hw_stp->s.InFCSErrCount + 324 hw_stp->s.InAlignErrCount + 325 hw_stp->s.InLenErrCount; 326 break; 327 328 case MAC_STAT_OERRORS: 329 *val = hw_stp->s.OutFifoovCount + 330 hw_stp->s.OutLOCCount + 331 hw_stp->s.OutExDecCount + 332 hw_stp->s.OutRetryCount; 333 break; 334 335 case MAC_STAT_COLLISIONS: 336 *val = hw_stp->s.OutColCount; 337 break; 338 339 case MAC_STAT_RBYTES: 340 *val = sw_stp->rbytes; 341 break; 342 343 case MAC_STAT_IPACKETS: 344 *val = sw_stp->recv_count; 345 break; 346 347 case MAC_STAT_OBYTES: 348 *val = sw_stp->obytes; 349 break; 350 351 case MAC_STAT_OPACKETS: 352 *val = sw_stp->xmit_count; 353 break; 354 355 case ETHER_STAT_ALIGN_ERRORS: 356 *val = hw_stp->s.InAlignErrCount; 357 break; 358 359 case ETHER_STAT_FCS_ERRORS: 360 *val = hw_stp->s.InFCSErrCount; 361 break; 362 363 case ETHER_STAT_FIRST_COLLISIONS: 364 *val = hw_stp->s.OutZeroRetranCount; 365 break; 366 367 case ETHER_STAT_MULTI_COLLISIONS: 368 *val = hw_stp->s.OutOneRetranCount + 369 hw_stp->s.OutMoreRetranCount; 370 break; 371 372 case ETHER_STAT_DEFER_XMTS: 373 *val = hw_stp->s.OutExDecCount; 374 break; 375 376 case ETHER_STAT_TX_LATE_COLLISIONS: 377 *val = hw_stp->s.OutColCount; 378 break; 379 380 case ETHER_STAT_EX_COLLISIONS: 381 *val = hw_stp->s.OutRetryCount; 382 break; 383 384 case ETHER_STAT_CARRIER_ERRORS: 385 *val = hw_stp->s.OutLOCCount; 386 break; 387 388 case ETHER_STAT_TOOLONG_ERRORS: 389 *val = hw_stp->s.InOversizeErrCount; 390 break; 391 392 case ETHER_STAT_XCVR_ADDR: 393 *val = ngep->phy_xmii_addr; 394 break; 395 396 case ETHER_STAT_XCVR_ID: 397 *val = ngep->phy_id; 398 break; 399 400 case ETHER_STAT_XCVR_INUSE: 401 *val = XCVR_1000T; 402 break; 403 404 case ETHER_STAT_CAP_1000FDX: 405 *val = 1; 406 break; 407 408 case ETHER_STAT_CAP_1000HDX: 409 *val = 0; 410 break; 411 412 case ETHER_STAT_CAP_100FDX: 413 *val = 1; 414 break; 415 416 case ETHER_STAT_CAP_100HDX: 417 *val = 1; 418 break; 419 420 case ETHER_STAT_CAP_10FDX: 421 *val = 1; 422 break; 423 424 case ETHER_STAT_CAP_10HDX: 425 *val = 1; 426 break; 427 428 case ETHER_STAT_CAP_ASMPAUSE: 429 *val = 1; 430 break; 431 432 case ETHER_STAT_CAP_PAUSE: 433 *val = 1; 434 break; 435 436 case ETHER_STAT_CAP_AUTONEG: 437 *val = 1; 438 break; 439 440 case ETHER_STAT_ADV_CAP_1000FDX: 441 *val = ngep->param_adv_1000fdx; 442 break; 443 444 case ETHER_STAT_ADV_CAP_1000HDX: 445 *val = ngep->param_adv_1000hdx; 446 break; 447 448 case ETHER_STAT_ADV_CAP_100FDX: 449 *val = ngep->param_adv_100fdx; 450 break; 451 452 case ETHER_STAT_ADV_CAP_100HDX: 453 *val = ngep->param_adv_100hdx; 454 break; 455 456 case ETHER_STAT_ADV_CAP_10FDX: 457 *val = ngep->param_adv_10fdx; 458 break; 459 460 case ETHER_STAT_ADV_CAP_10HDX: 461 *val = ngep->param_adv_10hdx; 462 break; 463 464 case ETHER_STAT_ADV_CAP_ASMPAUSE: 465 *val = ngep->param_adv_asym_pause; 466 break; 467 468 case ETHER_STAT_ADV_CAP_PAUSE: 469 *val = ngep->param_adv_pause; 470 break; 471 472 case ETHER_STAT_ADV_CAP_AUTONEG: 473 *val = ngep->param_adv_autoneg; 474 break; 475 476 case ETHER_STAT_LP_CAP_1000FDX: 477 *val = ngep->param_lp_1000fdx; 478 break; 479 480 case ETHER_STAT_LP_CAP_1000HDX: 481 *val = ngep->param_lp_1000hdx; 482 break; 483 484 case ETHER_STAT_LP_CAP_100FDX: 485 *val = ngep->param_lp_100fdx; 486 break; 487 488 case ETHER_STAT_LP_CAP_100HDX: 489 *val = ngep->param_lp_100hdx; 490 break; 491 492 case ETHER_STAT_LP_CAP_10FDX: 493 *val = ngep->param_lp_10fdx; 494 break; 495 496 case ETHER_STAT_LP_CAP_10HDX: 497 *val = ngep->param_lp_10hdx; 498 break; 499 500 case ETHER_STAT_LP_CAP_ASMPAUSE: 501 *val = ngep->param_lp_asym_pause; 502 break; 503 504 case ETHER_STAT_LP_CAP_PAUSE: 505 *val = ngep->param_lp_pause; 506 break; 507 508 case ETHER_STAT_LP_CAP_AUTONEG: 509 *val = ngep->param_lp_autoneg; 510 break; 511 512 case ETHER_STAT_LINK_ASMPAUSE: 513 *val = ngep->param_adv_asym_pause && 514 ngep->param_lp_asym_pause && 515 ngep->param_adv_pause != ngep->param_lp_pause; 516 break; 517 518 case ETHER_STAT_LINK_PAUSE: 519 *val = ngep->param_link_rx_pause; 520 break; 521 522 case ETHER_STAT_LINK_AUTONEG: 523 *val = ngep->param_link_autoneg; 524 break; 525 526 case ETHER_STAT_LINK_DUPLEX: 527 *val = ngep->param_link_duplex; 528 break; 529 530 default: 531 return (ENOTSUP); 532 } 533 534 return (0); 535 } 536