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 /* 23 * Copyright 2008-2013 Solarflare Communications Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/ddi.h> 29 #include <sys/sunddi.h> 30 #include <sys/modctl.h> 31 #include <sys/conf.h> 32 #include <sys/ethernet.h> 33 #include <sys/pci.h> 34 #include <sys/stream.h> 35 #include <sys/strsun.h> 36 #include <sys/processor.h> 37 #include <sys/cpuvar.h> 38 #include <sys/pghw.h> 39 40 #include "version.h" 41 42 #include "sfxge.h" 43 #include "efsys.h" 44 #include "efx.h" 45 46 #ifdef DEBUG 47 boolean_t sfxge_aask = B_FALSE; 48 #endif 49 50 /* Receive queue TRIM default polling interval (in microseconds) */ 51 #define SFXGE_RX_QPOLL_USEC (5000000) 52 53 /* Broadcast address */ 54 uint8_t sfxge_brdcst[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 55 56 /* Soft state head */ 57 static void *sfxge_ss; 58 59 /* 60 * By default modinfo will display lines truncated to 80 characters and so just 61 * show 32 characters of our sfxge_ident string. At the moment CI_VERSION_STRING 62 * is 12 characters. To show the whole string use modinfo -w 63 */ 64 #if defined(_USE_GLD_V3_SOL10) && !defined(_USE_GLD_V3_SOL11) 65 #ifdef DEBUG 66 /* 67 * The (DEBUG) part of this string will not be displayed in modinfo by 68 * default. See previous comment. 69 */ 70 const char sfxge_ident[] = 71 CI_VERSION_STRING" for Sol10u8,u9,u10 (DEBUG)"; 72 #else 73 const char sfxge_ident[] = 74 CI_VERSION_STRING" for Sol10u8,u9,u10"; 75 #endif 76 #elif defined(_USE_GLD_V3_SOL11) 77 #ifdef DEBUG 78 const char sfxge_ident[] = CI_VERSION_STRING" for Sol11 (DEBUG)"; 79 #else 80 const char sfxge_ident[] = CI_VERSION_STRING" for Sol11"; 81 #endif 82 #elif defined(_USE_GLD_V3) 83 #ifdef DEBUG 84 const char sfxge_ident[] = CI_VERSION_STRING" GLDv3 (DEBUG)"; 85 #else 86 const char sfxge_ident[] = CI_VERSION_STRING" GLDv3"; 87 #endif 88 #elif defined(_USE_GLD_V2) 89 #ifdef DEBUG 90 const char sfxge_ident[] = CI_VERSION_STRING" GLDv2 (DEBUG)"; 91 #else 92 const char sfxge_ident[] = CI_VERSION_STRING" GLDv2"; 93 #endif 94 #else 95 #error "sfxge_ident undefined" 96 #endif 97 const char sfxge_version[] = CI_VERSION_STRING; 98 99 static void 100 sfxge_cfg_build(sfxge_t *sp) 101 { 102 const efx_nic_cfg_t *encp = efx_nic_cfg_get(sp->s_enp); 103 (void) snprintf(sp->s_cfg_kstat.buf.sck_mac, 64, 104 "%02X:%02X:%02X:%02X:%02X:%02X", 105 encp->enc_mac_addr[0], encp->enc_mac_addr[1], 106 encp->enc_mac_addr[2], encp->enc_mac_addr[3], 107 encp->enc_mac_addr[4], encp->enc_mac_addr[5]); 108 } 109 110 static int 111 sfxge_create(dev_info_t *dip, sfxge_t **spp) 112 { 113 int instance = ddi_get_instance(dip); 114 sfxge_t *sp; 115 efx_nic_t *enp; 116 char name[MAXNAMELEN]; 117 unsigned int rxq_size; 118 int rxq_poll_usec; 119 int rc; 120 121 /* Allocate the soft state object */ 122 if (ddi_soft_state_zalloc(sfxge_ss, instance) != DDI_SUCCESS) { 123 rc = ENOMEM; 124 goto fail1; 125 } 126 127 sp = ddi_get_soft_state(sfxge_ss, instance); 128 ASSERT(sp != NULL); 129 130 SFXGE_OBJ_CHECK(sp, sfxge_t); 131 132 sp->s_dip = dip; 133 134 mutex_init(&(sp->s_state_lock), "", MUTEX_DRIVER, NULL); 135 sp->s_state = SFXGE_UNINITIALIZED; 136 137 /* Get property values */ 138 sp->s_mtu = ddi_prop_get_int(DDI_DEV_T_ANY, sp->s_dip, 139 DDI_PROP_DONTPASS, "mtu", ETHERMTU); 140 141 sp->s_action_on_hw_err = ddi_prop_get_int(DDI_DEV_T_ANY, sp->s_dip, 142 DDI_PROP_DONTPASS, "action_on_hw_err", SFXGE_RECOVER); 143 144 rxq_size = ddi_prop_get_int(DDI_DEV_T_ANY, sp->s_dip, 145 DDI_PROP_DONTPASS, "rxq_size", SFXGE_DEFAULT_RXQ_SIZE); 146 if (!(IS_POW2(rxq_size))) 147 rxq_size = SFXGE_DEFAULT_RXQ_SIZE; 148 rxq_size = min(rxq_size, EFX_RXQ_MAXNDESCS); 149 sp->s_rxq_size = max(rxq_size, EFX_RXQ_MINNDESCS); 150 151 /* Configure polling interval for queue refill/trim */ 152 rxq_poll_usec = ddi_prop_get_int(DDI_DEV_T_ANY, sp->s_dip, 153 DDI_PROP_DONTPASS, "rxq_poll_usec", SFXGE_RX_QPOLL_USEC); 154 if (rxq_poll_usec <= 0) 155 rxq_poll_usec = SFXGE_RX_QPOLL_USEC; 156 sp->s_rxq_poll_usec = rxq_poll_usec; 157 158 /* Create a taskq */ 159 (void) snprintf(name, MAXNAMELEN - 1, "%s_tq", ddi_driver_name(dip)); 160 sp->s_tqp = ddi_taskq_create(dip, name, 1, TASKQ_DEFAULTPRI, DDI_SLEEP); 161 if (sp->s_tqp == NULL) { 162 rc = ENOMEM; 163 goto fail2; 164 } 165 166 /* Check and initialize PCI configuration space */ 167 if ((rc = sfxge_pci_init(sp)) != 0) 168 goto fail3; 169 170 /* Map the device registers */ 171 if ((rc = sfxge_bar_init(sp)) != 0) 172 goto fail4; 173 174 /* Create the NIC object */ 175 mutex_init(&(sp->s_nic_lock), NULL, MUTEX_DRIVER, NULL); 176 177 if ((rc = efx_nic_create(sp->s_family, (efsys_identifier_t *)sp, 178 &(sp->s_bar), &(sp->s_nic_lock), &enp)) != 0) 179 goto fail5; 180 181 sp->s_enp = enp; 182 183 /* Initialize MCDI to talk to the Microcontroller */ 184 if ((rc = sfxge_mcdi_init(sp)) != 0) 185 goto fail6; 186 187 /* Probe the NIC and build the configuration data area */ 188 if ((rc = efx_nic_probe(enp)) != 0) 189 goto fail7; 190 191 if (sp->s_family == EFX_FAMILY_SIENA) { 192 sfxge_pcie_check_link(sp, 8, 2); /* PCI 8x Gen2 */ 193 194 } else if (sp->s_family == EFX_FAMILY_FALCON) { 195 sfxge_pcie_check_link(sp, 8, 1); /* PCI 8x Gen1 */ 196 197 rc = efx_nic_pcie_tune(enp, sp->s_pcie_nlanes); 198 ASSERT(rc == 0); 199 } 200 201 if ((rc = efx_nvram_init(enp)) != 0) 202 goto fail8; 203 204 if ((rc = efx_vpd_init(enp)) != 0) 205 goto fail9; 206 207 if ((rc = efx_nic_reset(enp)) != 0) 208 goto fail10; 209 210 sfxge_sram_init(sp); 211 212 if ((rc = sfxge_intr_init(sp)) != 0) 213 goto fail11; 214 215 if ((rc = sfxge_ev_init(sp)) != 0) 216 goto fail12; 217 218 if ((rc = sfxge_rx_init(sp)) != 0) 219 goto fail13; 220 221 if ((rc = sfxge_tx_init(sp)) != 0) 222 goto fail14; 223 224 if ((rc = sfxge_mon_init(sp)) != 0) 225 goto fail15; 226 227 if ((rc = sfxge_mac_init(sp)) != 0) 228 goto fail16; 229 230 mutex_init(&(sp->s_tx_flush_lock), "", MUTEX_DRIVER, 231 DDI_INTR_PRI(sp->s_intr.si_intr_pri)); 232 cv_init(&(sp->s_tx_flush_kv), "", CV_DRIVER, NULL); 233 234 sp->s_state = SFXGE_INITIALIZED; 235 236 *spp = sp; 237 return (0); 238 239 fail16: 240 DTRACE_PROBE(fail16); 241 sfxge_mon_fini(sp); 242 243 fail15: 244 DTRACE_PROBE(fail15); 245 sfxge_tx_fini(sp); 246 247 fail14: 248 DTRACE_PROBE(fail14); 249 sfxge_rx_fini(sp); 250 251 fail13: 252 DTRACE_PROBE(fail13); 253 sfxge_ev_fini(sp); 254 255 fail12: 256 DTRACE_PROBE(fail12); 257 sfxge_intr_fini(sp); 258 259 fail11: 260 DTRACE_PROBE(fail11); 261 sfxge_sram_fini(sp); 262 (void) efx_nic_reset(sp->s_enp); 263 264 fail10: 265 DTRACE_PROBE(fail10); 266 efx_vpd_fini(enp); 267 268 fail9: 269 DTRACE_PROBE(fail9); 270 efx_nvram_fini(enp); 271 272 fail8: 273 DTRACE_PROBE(fail8); 274 efx_nic_unprobe(enp); 275 276 fail7: 277 DTRACE_PROBE(fail7); 278 sfxge_mcdi_fini(sp); 279 280 fail6: 281 DTRACE_PROBE(fail6); 282 sp->s_enp = NULL; 283 efx_nic_destroy(enp); 284 285 fail5: 286 DTRACE_PROBE(fail5); 287 mutex_destroy(&(sp->s_nic_lock)); 288 sfxge_bar_fini(sp); 289 290 fail4: 291 DTRACE_PROBE(fail4); 292 sfxge_pci_fini(sp); 293 294 fail3: 295 DTRACE_PROBE(fail3); 296 ddi_taskq_destroy(sp->s_tqp); 297 sp->s_tqp = NULL; 298 299 fail2: 300 DTRACE_PROBE(fail2); 301 302 /* Clear property values */ 303 sp->s_mtu = 0; 304 305 mutex_destroy(&(sp->s_state_lock)); 306 307 /* Free the soft state */ 308 sp->s_dip = NULL; 309 310 SFXGE_OBJ_CHECK(sp, sfxge_t); 311 ddi_soft_state_free(sfxge_ss, instance); 312 313 fail1: 314 DTRACE_PROBE1(fail1, int, rc); 315 316 return (rc); 317 } 318 319 320 static int 321 sfxge_start_locked(sfxge_t *sp, boolean_t restart) 322 { 323 int rc; 324 325 ASSERT(mutex_owned(&(sp->s_state_lock))); 326 327 if (sp->s_state == SFXGE_STARTED) 328 goto done; 329 330 if (sp->s_state != SFXGE_REGISTERED) { 331 rc = EINVAL; 332 goto fail1; 333 } 334 sp->s_state = SFXGE_STARTING; 335 336 if ((rc = efx_nic_reset(sp->s_enp)) != 0) 337 goto fail2; 338 339 if ((rc = efx_nic_init(sp->s_enp)) != 0) 340 goto fail3; 341 342 if ((rc = sfxge_sram_start(sp)) != 0) 343 goto fail4; 344 345 if ((rc = sfxge_intr_start(sp)) != 0) 346 goto fail5; 347 348 if ((rc = sfxge_ev_start(sp)) != 0) 349 goto fail6; 350 351 if ((rc = sfxge_rx_start(sp)) != 0) 352 goto fail7; 353 354 if ((rc = sfxge_tx_start(sp)) != 0) 355 goto fail8; 356 357 if ((rc = sfxge_mon_start(sp)) != 0) 358 goto fail9; 359 360 if ((rc = sfxge_mac_start(sp, restart)) != 0) 361 goto fail10; 362 363 ASSERT3U(sp->s_state, ==, SFXGE_STARTING); 364 sp->s_state = SFXGE_STARTED; 365 366 /* Notify any change of MTU */ 367 sfxge_gld_mtu_update(sp); 368 369 done: 370 return (0); 371 372 fail10: 373 DTRACE_PROBE(fail10); 374 sfxge_mon_stop(sp); 375 376 fail9: 377 DTRACE_PROBE(fail9); 378 sfxge_tx_stop(sp); 379 380 fail8: 381 DTRACE_PROBE(fail8); 382 sfxge_rx_stop(sp); 383 384 fail7: 385 DTRACE_PROBE(fail7); 386 sfxge_ev_stop(sp); 387 388 fail6: 389 DTRACE_PROBE(fail6); 390 sfxge_intr_stop(sp); 391 392 fail5: 393 DTRACE_PROBE(fail5); 394 sfxge_sram_stop(sp); 395 396 fail4: 397 DTRACE_PROBE(fail4); 398 efx_nic_fini(sp->s_enp); 399 400 fail3: 401 DTRACE_PROBE(fail3); 402 (void) efx_nic_reset(sp->s_enp); 403 404 fail2: 405 DTRACE_PROBE(fail2); 406 407 ASSERT3U(sp->s_state, ==, SFXGE_STARTING); 408 sp->s_state = SFXGE_REGISTERED; 409 410 fail1: 411 DTRACE_PROBE1(fail1, int, rc); 412 413 return (rc); 414 } 415 416 417 int 418 sfxge_start(sfxge_t *sp, boolean_t restart) 419 { 420 int rc; 421 422 mutex_enter(&(sp->s_state_lock)); 423 rc = sfxge_start_locked(sp, restart); 424 mutex_exit(&(sp->s_state_lock)); 425 return (rc); 426 } 427 428 429 static void 430 sfxge_stop_locked(sfxge_t *sp) 431 { 432 ASSERT(mutex_owned(&(sp->s_state_lock))); 433 434 if (sp->s_state != SFXGE_STARTED) { 435 return; 436 } 437 sp->s_state = SFXGE_STOPPING; 438 439 sfxge_mac_stop(sp); 440 sfxge_mon_stop(sp); 441 sfxge_tx_stop(sp); 442 sfxge_rx_stop(sp); 443 444 /* Stop event processing - must be after rx_stop see sfxge_rx_qpoll() */ 445 sfxge_ev_stop(sp); 446 sfxge_intr_stop(sp); /* cope with late flush/soft events until here */ 447 sfxge_sram_stop(sp); 448 449 efx_nic_fini(sp->s_enp); 450 efx_nic_reset(sp->s_enp); 451 452 ASSERT3U(sp->s_state, ==, SFXGE_STOPPING); 453 sp->s_state = SFXGE_REGISTERED; 454 } 455 456 void 457 sfxge_stop(sfxge_t *sp) 458 { 459 mutex_enter(&(sp->s_state_lock)); 460 sfxge_stop_locked(sp); 461 mutex_exit(&(sp->s_state_lock)); 462 } 463 464 static void 465 _sfxge_restart(void *arg) 466 { 467 sfxge_t *sp = arg; 468 int rc; 469 470 /* logging on entry is in sfxge_restart_dispatch */ 471 mutex_enter(&(sp->s_state_lock)); 472 473 DTRACE_PROBE(_sfxge_restart); 474 if (sp->s_state != SFXGE_STARTED) 475 goto done; 476 477 /* inform the OS that the link is down - may trigger IPMP failover */ 478 if (sp->s_hw_err && sp->s_action_on_hw_err != SFXGE_INVISIBLE) { 479 sp->s_mac.sm_link_mode = EFX_LINK_DOWN; 480 sfxge_gld_link_update(sp); 481 } 482 483 /* Stop processing */ 484 sfxge_stop_locked(sp); 485 486 if (sp->s_hw_err && sp->s_action_on_hw_err == SFXGE_LEAVE_DEAD) { 487 cmn_err(CE_WARN, SFXGE_CMN_ERR "[%s%d] NIC error - interface is" 488 " being left permanently DOWN per driver config", 489 ddi_driver_name(sp->s_dip), ddi_get_instance(sp->s_dip)); 490 mutex_exit(&(sp->s_state_lock)); 491 return; 492 } else 493 sp->s_hw_err = SFXGE_HW_OK; 494 495 /* Start processing */ 496 if ((rc = sfxge_start_locked(sp, B_TRUE)) != 0) 497 goto fail1; 498 499 done: 500 mutex_exit(&(sp->s_state_lock)); 501 cmn_err(CE_WARN, SFXGE_CMN_ERR "[%s%d] NIC restart complete", 502 ddi_driver_name(sp->s_dip), ddi_get_instance(sp->s_dip)); 503 return; 504 505 fail1: 506 DTRACE_PROBE1(fail1, int, rc); 507 cmn_err(CE_WARN, 508 SFXGE_CMN_ERR "[%s%d] FATAL ERROR: NIC restart failed rc=%d", 509 ddi_driver_name(sp->s_dip), ddi_get_instance(sp->s_dip), rc); 510 511 mutex_exit(&(sp->s_state_lock)); 512 } 513 514 int 515 sfxge_restart_dispatch(sfxge_t *sp, uint_t cflags, sfxge_hw_err_t hw_err, 516 const char *reason, uint32_t errval) 517 { 518 if (hw_err == SFXGE_HW_OK) 519 sp->s_num_restarts++; 520 else { 521 sp->s_hw_err = hw_err; 522 sp->s_num_restarts_hw_err++; 523 } 524 525 DTRACE_PROBE2(sfxge_restart_dispatch, sfxge_hw_err_t, hw_err, char *, 526 reason); 527 528 cmn_err(CE_WARN, SFXGE_CMN_ERR "[%s%d] NIC restart due to %s:%d", 529 ddi_driver_name(sp->s_dip), ddi_get_instance(sp->s_dip), reason, 530 errval); 531 532 /* If cflags == DDI_SLEEP then guaranteed to succeed */ 533 return (ddi_taskq_dispatch(sp->s_tqp, _sfxge_restart, sp, cflags)); 534 } 535 536 537 static int 538 sfxge_can_destroy(sfxge_t *sp) 539 { 540 sfxge_intr_t *sip = &(sp->s_intr); 541 int index; 542 543 /* 544 * In SFC bug 19834 it was noted that a mblk passed up to STREAMS 545 * could be reused for transmit and sit in the sfxge_tx_packet_cache. 546 * This call to empty the TX deferred packet list may result in 547 * rx_loaned reducing. 548 */ 549 index = sip->si_nalloc; 550 while (--index >= 0) { 551 sfxge_txq_t *stp = sp->s_stp[index]; 552 sfxge_tx_qdpl_flush(stp); 553 } 554 555 /* Need to wait for desballoc free_func callback */ 556 return (sfxge_rx_loaned(sp)); 557 } 558 559 560 static int 561 sfxge_destroy(sfxge_t *sp) 562 { 563 dev_info_t *dip = sp->s_dip; 564 int instance = ddi_get_instance(dip); 565 ddi_taskq_t *tqp; 566 efx_nic_t *enp; 567 int rc; 568 569 ASSERT3U(sp->s_state, ==, SFXGE_INITIALIZED); 570 enp = sp->s_enp; 571 572 if (sfxge_can_destroy(sp) != 0) { 573 rc = EBUSY; 574 goto fail1; 575 } 576 577 sp->s_state = SFXGE_UNINITIALIZED; 578 579 cv_destroy(&(sp->s_tx_flush_kv)); 580 mutex_destroy(&(sp->s_tx_flush_lock)); 581 582 sfxge_mac_fini(sp); 583 sfxge_mon_fini(sp); 584 sfxge_tx_fini(sp); 585 sfxge_rx_fini(sp); 586 sfxge_ev_fini(sp); 587 sfxge_intr_fini(sp); 588 sfxge_sram_fini(sp); 589 (void) efx_nic_reset(enp); 590 591 efx_vpd_fini(enp); 592 efx_nvram_fini(enp); 593 efx_nic_unprobe(enp); 594 sfxge_mcdi_fini(sp); 595 596 /* Destroy the NIC object */ 597 sp->s_enp = NULL; 598 efx_nic_destroy(enp); 599 600 mutex_destroy(&(sp->s_nic_lock)); 601 602 /* Unmap the device registers */ 603 sfxge_bar_fini(sp); 604 605 /* Tear down PCI configuration space */ 606 sfxge_pci_fini(sp); 607 608 /* Destroy the taskq */ 609 tqp = sp->s_tqp; 610 sp->s_tqp = NULL; 611 ddi_taskq_destroy(tqp); 612 613 mutex_destroy(&(sp->s_state_lock)); 614 615 /* Clear property values */ 616 sp->s_mtu = 0; 617 618 /* Free the soft state */ 619 sp->s_dip = NULL; 620 621 SFXGE_OBJ_CHECK(sp, sfxge_t); 622 ddi_soft_state_free(sfxge_ss, instance); 623 624 return (0); 625 626 fail1: 627 DTRACE_PROBE1(fail1, int, rc); 628 629 return (rc); 630 } 631 632 void 633 sfxge_ioctl(sfxge_t *sp, queue_t *wq, mblk_t *mp) 634 { 635 struct iocblk *iocp; 636 int rc, taskq_wait = 0; 637 size_t ioclen = 0; 638 639 /* 640 * single concurrent IOCTL 641 * serialized from sfxge_create, _destroy, _(re)start, _stop 642 */ 643 mutex_enter(&(sp->s_state_lock)); 644 645 /*LINTED*/ 646 iocp = (struct iocblk *)mp->b_rptr; 647 648 switch (iocp->ioc_cmd) { 649 case SFXGE_TX_IOC: 650 ioclen = sizeof (sfxge_tx_ioc_t); 651 break; 652 case SFXGE_RX_IOC: 653 ioclen = sizeof (sfxge_rx_ioc_t); 654 break; 655 case SFXGE_BAR_IOC: 656 ioclen = sizeof (sfxge_bar_ioc_t); 657 break; 658 case SFXGE_PCI_IOC: 659 ioclen = sizeof (sfxge_pci_ioc_t); 660 break; 661 case SFXGE_MAC_IOC: 662 ioclen = sizeof (sfxge_mac_ioc_t); 663 break; 664 case SFXGE_PHY_IOC: 665 ioclen = sizeof (sfxge_phy_ioc_t); 666 break; 667 case SFXGE_PHY_BIST_IOC: 668 ioclen = sizeof (sfxge_phy_bist_ioc_t); 669 break; 670 case SFXGE_SRAM_IOC: 671 ioclen = sizeof (sfxge_sram_ioc_t); 672 break; 673 case SFXGE_NVRAM_IOC: 674 ioclen = sizeof (sfxge_nvram_ioc_t); 675 break; 676 case SFXGE_MCDI_IOC: 677 ioclen = sizeof (sfxge_mcdi_ioc_t); 678 break; 679 case SFXGE_VPD_IOC: 680 ioclen = sizeof (sfxge_vpd_ioc_t); 681 break; 682 case SFXGE_START_IOC: 683 case SFXGE_STOP_IOC: 684 case SFXGE_NIC_RESET_IOC: 685 break; 686 default: 687 rc = ENOTSUP; 688 goto fail1; 689 } 690 691 if (iocp->ioc_count != ioclen) { 692 rc = EINVAL; 693 goto fail2; 694 } 695 696 /* if in multiple fragments pull it up to one linear buffer */ 697 if ((rc = miocpullup(mp, ioclen)) != 0) { 698 goto fail3; 699 } 700 701 switch (iocp->ioc_cmd) { 702 case SFXGE_START_IOC: 703 if ((rc = sfxge_start_locked(sp, B_TRUE)) != 0) 704 goto fail4; 705 706 break; 707 708 case SFXGE_STOP_IOC: 709 sfxge_stop_locked(sp); 710 break; 711 712 case SFXGE_TX_IOC: { 713 sfxge_tx_ioc_t *stip = (sfxge_tx_ioc_t *)mp->b_cont->b_rptr; 714 715 if ((rc = sfxge_tx_ioctl(sp, stip)) != 0) 716 goto fail4; 717 718 break; 719 } 720 case SFXGE_RX_IOC: { 721 sfxge_rx_ioc_t *srip = (sfxge_rx_ioc_t *)mp->b_cont->b_rptr; 722 723 if ((rc = sfxge_rx_ioctl(sp, srip)) != 0) 724 goto fail4; 725 726 break; 727 } 728 case SFXGE_BAR_IOC: { 729 sfxge_bar_ioc_t *sbip = (sfxge_bar_ioc_t *)mp->b_cont->b_rptr; 730 731 if ((rc = sfxge_bar_ioctl(sp, sbip)) != 0) 732 goto fail4; 733 734 break; 735 } 736 case SFXGE_PCI_IOC: { 737 sfxge_pci_ioc_t *spip = (sfxge_pci_ioc_t *)mp->b_cont->b_rptr; 738 739 if ((rc = sfxge_pci_ioctl(sp, spip)) != 0) 740 goto fail4; 741 742 break; 743 } 744 case SFXGE_MAC_IOC: { 745 sfxge_mac_ioc_t *smip = (sfxge_mac_ioc_t *)mp->b_cont->b_rptr; 746 747 if ((rc = sfxge_mac_ioctl(sp, smip)) != 0) 748 goto fail4; 749 750 break; 751 } 752 case SFXGE_PHY_IOC: { 753 sfxge_phy_ioc_t *spip = (sfxge_phy_ioc_t *)mp->b_cont->b_rptr; 754 755 if ((rc = sfxge_phy_ioctl(sp, spip)) != 0) 756 goto fail4; 757 758 break; 759 } 760 case SFXGE_PHY_BIST_IOC: { 761 sfxge_phy_bist_ioc_t *spbip; 762 763 spbip = (sfxge_phy_bist_ioc_t *)mp->b_cont->b_rptr; 764 765 if ((rc = sfxge_phy_bist_ioctl(sp, spbip)) != 0) 766 goto fail4; 767 768 break; 769 } 770 case SFXGE_SRAM_IOC: { 771 sfxge_sram_ioc_t *ssip = (sfxge_sram_ioc_t *)mp->b_cont->b_rptr; 772 773 if ((rc = sfxge_sram_ioctl(sp, ssip)) != 0) 774 goto fail4; 775 776 break; 777 } 778 case SFXGE_NVRAM_IOC: { 779 sfxge_nvram_ioc_t *snip = 780 (sfxge_nvram_ioc_t *)mp->b_cont->b_rptr; 781 782 if ((rc = sfxge_nvram_ioctl(sp, snip)) != 0) 783 goto fail4; 784 785 break; 786 } 787 case SFXGE_MCDI_IOC: { 788 sfxge_mcdi_ioc_t *smip = (sfxge_mcdi_ioc_t *)mp->b_cont->b_rptr; 789 790 if ((rc = sfxge_mcdi_ioctl(sp, smip)) != 0) 791 goto fail4; 792 taskq_wait = 1; 793 794 break; 795 } 796 case SFXGE_NIC_RESET_IOC: { 797 DTRACE_PROBE(nic_reset_ioc); 798 799 /* sp->s_state_lock held */ 800 (void) sfxge_restart_dispatch(sp, DDI_SLEEP, SFXGE_HW_OK, 801 "NIC_RESET_IOC", 0); 802 taskq_wait = 1; 803 804 break; 805 } 806 case SFXGE_VPD_IOC: { 807 sfxge_vpd_ioc_t *svip = (sfxge_vpd_ioc_t *)mp->b_cont->b_rptr; 808 809 if ((rc = sfxge_vpd_ioctl(sp, svip)) != 0) 810 goto fail4; 811 812 break; 813 } 814 default: 815 ASSERT(0); 816 } 817 818 mutex_exit(&(sp->s_state_lock)); 819 820 if (taskq_wait) { 821 /* 822 * Wait for any tasks that may be accessing GLD functions 823 * This may end up waiting for multiple nic_resets 824 * as it needs to be outside of s_state_lock for sfxge_restart() 825 */ 826 ddi_taskq_wait(sp->s_tqp); 827 } 828 829 /* The entire structure is the acknowledgement */ 830 miocack(wq, mp, iocp->ioc_count, 0); 831 832 return; 833 834 fail4: 835 DTRACE_PROBE(fail4); 836 fail3: 837 DTRACE_PROBE(fail3); 838 fail2: 839 DTRACE_PROBE(fail2); 840 fail1: 841 DTRACE_PROBE1(fail1, int, rc); 842 843 mutex_exit(&(sp->s_state_lock)); 844 845 /* no data returned */ 846 miocnak(wq, mp, 0, rc); 847 } 848 849 static int 850 sfxge_register(sfxge_t *sp) 851 { 852 int rc; 853 854 ASSERT3U(sp->s_state, ==, SFXGE_INITIALIZED); 855 856 if ((rc = sfxge_gld_register(sp)) != 0) 857 goto fail1; 858 859 sp->s_state = SFXGE_REGISTERED; 860 861 return (0); 862 863 fail1: 864 DTRACE_PROBE1(fail1, int, rc); 865 866 return (rc); 867 } 868 869 static int 870 sfxge_unregister(sfxge_t *sp) 871 { 872 int rc; 873 874 ASSERT3U(sp->s_state, ==, SFXGE_REGISTERED); 875 876 /* Wait for any tasks that may be accessing GLD functions */ 877 ddi_taskq_wait(sp->s_tqp); 878 879 if ((rc = sfxge_gld_unregister(sp)) != 0) 880 goto fail1; 881 882 sp->s_state = SFXGE_INITIALIZED; 883 884 return (0); 885 886 fail1: 887 DTRACE_PROBE1(fail1, int, rc); 888 889 return (rc); 890 } 891 892 static void 893 _sfxge_vpd_kstat_init(sfxge_t *sp, caddr_t vpd, size_t size, efx_vpd_tag_t tag, 894 const char *keyword, sfxge_vpd_type_t type) 895 { 896 static const char unknown[] = "?"; 897 efx_nic_t *enp = sp->s_enp; 898 sfxge_vpd_kstat_t *svkp = &(sp->s_vpd_kstat); 899 kstat_named_t *knp; 900 efx_vpd_value_t *evvp; 901 902 evvp = svkp->svk_vv + type; 903 evvp->evv_tag = tag; 904 evvp->evv_keyword = EFX_VPD_KEYWORD(keyword[0], keyword[1]); 905 906 if (efx_vpd_get(enp, vpd, size, evvp) != 0) { 907 evvp->evv_length = strlen(unknown) + 1; 908 memcpy(evvp->evv_value, unknown, evvp->evv_length); 909 } 910 911 knp = &(svkp->svk_stat[type]); 912 913 kstat_named_init(knp, (char *)keyword, KSTAT_DATA_STRING); 914 kstat_named_setstr(knp, (char *)evvp->evv_value); 915 svkp->svk_ksp->ks_data_size += sizeof (*evvp); 916 } 917 918 static int 919 sfxge_vpd_kstat_init(sfxge_t *sp) 920 { 921 efx_nic_t *enp = sp->s_enp; 922 sfxge_vpd_kstat_t *svkp = &(sp->s_vpd_kstat); 923 dev_info_t *dip = sp->s_dip; 924 char name[MAXNAMELEN]; 925 kstat_t *ksp; 926 caddr_t vpd; 927 size_t size; 928 int rc; 929 930 SFXGE_OBJ_CHECK(svkp, sfxge_vpd_kstat_t); 931 (void) snprintf(name, MAXNAMELEN - 1, "%s_vpd", ddi_driver_name(dip)); 932 933 /* Get a copy of the VPD space */ 934 if ((rc = efx_vpd_size(enp, &size)) != 0) 935 goto fail1; 936 937 if ((vpd = kmem_zalloc(size, KM_NOSLEEP)) == NULL) { 938 rc = ENOMEM; 939 goto fail2; 940 } 941 942 if ((svkp->svk_vv = kmem_zalloc(sizeof (efx_vpd_value_t) * 943 SFXGE_VPD_MAX, KM_NOSLEEP)) == NULL) { 944 rc = ENOMEM; 945 goto fail3; 946 } 947 948 if ((rc = efx_vpd_read(enp, vpd, size)) != 0) 949 goto fail4; 950 951 if ((ksp = kstat_create((char *)ddi_driver_name(dip), 952 ddi_get_instance(dip), name, "vpd", KSTAT_TYPE_NAMED, SFXGE_VPD_MAX, 953 KSTAT_FLAG_VIRTUAL)) == NULL) { 954 rc = ENOMEM; 955 goto fail5; 956 } 957 svkp->svk_ksp = ksp; 958 ksp->ks_data = &(svkp->svk_stat); 959 960 _sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_ID, "ID", SFXGE_VPD_ID); 961 _sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_RO, "PN", SFXGE_VPD_PN); 962 _sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_RO, "SN", SFXGE_VPD_SN); 963 _sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_RO, "EC", SFXGE_VPD_EC); 964 _sfxge_vpd_kstat_init(sp, vpd, size, EFX_VPD_RO, "VD", SFXGE_VPD_VD); 965 966 kstat_install(ksp); 967 kmem_free(vpd, size); 968 969 return (0); 970 971 fail5: 972 DTRACE_PROBE(fail5); 973 fail4: 974 DTRACE_PROBE(fail4); 975 kmem_free(svkp->svk_vv, sizeof (efx_vpd_value_t) * SFXGE_VPD_MAX); 976 fail3: 977 DTRACE_PROBE(fail3); 978 kmem_free(vpd, size); 979 fail2: 980 DTRACE_PROBE(fail2); 981 fail1: 982 DTRACE_PROBE1(fail1, int, rc); 983 SFXGE_OBJ_CHECK(svkp, sfxge_vpd_kstat_t); 984 985 return (rc); 986 } 987 988 static void 989 sfxge_vpd_kstat_fini(sfxge_t *sp) 990 { 991 sfxge_vpd_kstat_t *svkp = &(sp->s_vpd_kstat); 992 993 /* NOTE: VPD support is optional, so kstats might not be registered */ 994 if (svkp->svk_ksp != NULL) { 995 996 kstat_delete(svkp->svk_ksp); 997 998 kmem_free(svkp->svk_vv, 999 sizeof (efx_vpd_value_t) * SFXGE_VPD_MAX); 1000 1001 bzero(svkp->svk_stat, 1002 sizeof (kstat_named_t) * SFXGE_VPD_MAX); 1003 1004 svkp->svk_ksp = NULL; 1005 } 1006 1007 SFXGE_OBJ_CHECK(svkp, sfxge_vpd_kstat_t); 1008 } 1009 1010 static int 1011 sfxge_cfg_kstat_init(sfxge_t *sp) 1012 { 1013 dev_info_t *dip = sp->s_dip; 1014 char name[MAXNAMELEN]; 1015 kstat_t *ksp; 1016 sfxge_cfg_kstat_t *sckp; 1017 int rc; 1018 1019 sfxge_cfg_build(sp); 1020 1021 /* Create the set */ 1022 (void) snprintf(name, MAXNAMELEN - 1, "%s_cfg", ddi_driver_name(dip)); 1023 1024 if ((ksp = kstat_create((char *)ddi_driver_name(dip), 1025 ddi_get_instance(dip), name, "cfg", KSTAT_TYPE_NAMED, 1026 sizeof (sckp->kstat) / sizeof (kstat_named_t), 1027 KSTAT_FLAG_VIRTUAL)) == NULL) { 1028 rc = ENOMEM; 1029 goto fail1; 1030 } 1031 1032 sp->s_cfg_ksp = ksp; 1033 1034 ksp->ks_data = sckp = &(sp->s_cfg_kstat); 1035 1036 kstat_named_init(&(sckp->kstat.sck_mac), "mac", KSTAT_DATA_STRING); 1037 kstat_named_setstr(&(sckp->kstat.sck_mac), sckp->buf.sck_mac); 1038 ksp->ks_data_size += sizeof (sckp->buf.sck_mac); 1039 1040 kstat_named_init(&(sckp->kstat.sck_version), "version", 1041 KSTAT_DATA_STRING); 1042 kstat_named_setstr(&(sckp->kstat.sck_version), sfxge_version); 1043 ksp->ks_data_size += sizeof (sfxge_version); 1044 1045 kstat_install(ksp); 1046 return (0); 1047 1048 fail1: 1049 DTRACE_PROBE1(fail1, int, rc); 1050 1051 return (rc); 1052 } 1053 1054 static void 1055 sfxge_cfg_kstat_fini(sfxge_t *sp) 1056 { 1057 if (sp->s_cfg_ksp == NULL) 1058 return; 1059 1060 kstat_delete(sp->s_cfg_ksp); 1061 sp->s_cfg_ksp = NULL; 1062 1063 bzero(&(sp->s_cfg_kstat), sizeof (sfxge_cfg_kstat_t)); 1064 } 1065 1066 static int 1067 sfxge_resume(dev_info_t *dip) 1068 { 1069 sfxge_t *sp = ddi_get_soft_state(sfxge_ss, ddi_get_instance(dip)); 1070 int rc; 1071 1072 /* Start processing */ 1073 if ((rc = sfxge_start(sp, B_FALSE)) != 0) 1074 goto fail1; 1075 1076 return (DDI_SUCCESS); 1077 1078 fail1: 1079 DTRACE_PROBE1(fail1, int, rc); 1080 1081 return (DDI_FAILURE); 1082 } 1083 1084 static int 1085 sfxge_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1086 { 1087 sfxge_t *sp = ddi_get_soft_state(sfxge_ss, ddi_get_instance(dip)); 1088 int rc; 1089 1090 switch (cmd) { 1091 case DDI_ATTACH: 1092 if (sp != NULL) { 1093 cmn_err(CE_WARN, SFXGE_CMN_ERR 1094 "[%s%d] ATTACH for attached instance\n", 1095 ddi_driver_name(sp->s_dip), 1096 ddi_get_instance(sp->s_dip)); 1097 return (DDI_FAILURE); 1098 } 1099 break; 1100 1101 case DDI_RESUME: 1102 if (sp == NULL) { 1103 cmn_err(CE_WARN, SFXGE_CMN_ERR 1104 "[%s%d] RESUME for missing instance\n", 1105 ddi_driver_name(sp->s_dip), 1106 ddi_get_instance(sp->s_dip)); 1107 return (DDI_FAILURE); 1108 } 1109 return (sfxge_resume(dip)); 1110 1111 default: 1112 return (DDI_FAILURE); 1113 } 1114 1115 /* Create the soft state */ 1116 if ((rc = sfxge_create(dip, &sp)) != 0) 1117 goto fail1; 1118 1119 /* Create the configuration kstats */ 1120 if ((rc = sfxge_cfg_kstat_init(sp)) != 0) 1121 goto fail2; 1122 1123 /* Create the VPD kstats */ 1124 if ((rc = sfxge_vpd_kstat_init(sp)) != 0) { 1125 if (rc != ENOTSUP) 1126 goto fail3; 1127 } 1128 1129 /* Register the interface */ 1130 if ((rc = sfxge_register(sp)) != 0) 1131 goto fail4; 1132 1133 /* Announce ourselves in the system log */ 1134 ddi_report_dev(dip); 1135 1136 return (DDI_SUCCESS); 1137 1138 fail4: 1139 DTRACE_PROBE(fail4); 1140 1141 /* Destroy the VPD kstats */ 1142 sfxge_vpd_kstat_fini(sp); 1143 1144 fail3: 1145 DTRACE_PROBE(fail3); 1146 1147 /* Destroy the configuration kstats */ 1148 sfxge_cfg_kstat_fini(sp); 1149 1150 fail2: 1151 DTRACE_PROBE(fail2); 1152 1153 /* Destroy the soft state */ 1154 (void) sfxge_destroy(sp); 1155 1156 fail1: 1157 DTRACE_PROBE1(fail1, int, rc); 1158 1159 return (DDI_FAILURE); 1160 } 1161 1162 static int 1163 sfxge_suspend(dev_info_t *dip) 1164 { 1165 sfxge_t *sp = ddi_get_soft_state(sfxge_ss, ddi_get_instance(dip)); 1166 1167 /* Stop processing */ 1168 sfxge_stop(sp); 1169 1170 return (DDI_SUCCESS); 1171 } 1172 1173 static int 1174 sfxge_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1175 { 1176 sfxge_t *sp = ddi_get_soft_state(sfxge_ss, ddi_get_instance(dip)); 1177 int rc; 1178 1179 switch (cmd) { 1180 case DDI_DETACH: 1181 if (sp == NULL) { 1182 cmn_err(CE_WARN, SFXGE_CMN_ERR 1183 "[%s%d] DETACH for missing instance\n", 1184 ddi_driver_name(sp->s_dip), 1185 ddi_get_instance(sp->s_dip)); 1186 return (DDI_FAILURE); 1187 } 1188 break; 1189 1190 case DDI_SUSPEND: 1191 if (sp == NULL) { 1192 cmn_err(CE_WARN, SFXGE_CMN_ERR 1193 "[%s%d] SUSPEND for missing instance\n", 1194 ddi_driver_name(sp->s_dip), 1195 ddi_get_instance(sp->s_dip)); 1196 return (DDI_FAILURE); 1197 } 1198 return (sfxge_suspend(dip)); 1199 1200 default: 1201 return (DDI_FAILURE); 1202 } 1203 1204 ASSERT(sp != NULL); 1205 1206 /* Wait for any pending restarts to complete */ 1207 ddi_taskq_wait(sp->s_tqp); 1208 1209 /* 1210 * IOCTLs from utilites can cause GLD mc_start() (SFXGE_STARTED state) 1211 * And mc_stop() may not occur until detach time and race. SFC bug 19855 1212 * Holding the lock seems to be enough - the log message is not seen 1213 */ 1214 mutex_enter(&(sp->s_state_lock)); 1215 if (sp->s_state == SFXGE_STARTED) { 1216 cmn_err(CE_WARN, SFXGE_CMN_ERR 1217 "[%s%d] STREAMS detach when STARTED\n", 1218 ddi_driver_name(sp->s_dip), 1219 ddi_get_instance(sp->s_dip)); 1220 sfxge_stop_locked(sp); 1221 ASSERT3U(sp->s_state, ==, SFXGE_REGISTERED); 1222 } 1223 mutex_exit(&(sp->s_state_lock)); 1224 1225 ASSERT(sp->s_state == SFXGE_REGISTERED || 1226 sp->s_state == SFXGE_INITIALIZED); 1227 1228 if (sp->s_state != SFXGE_REGISTERED) 1229 goto destroy; 1230 1231 /* Unregister the interface */ 1232 if ((rc = sfxge_unregister(sp)) != 0) 1233 goto fail1; 1234 1235 destroy: 1236 /* Destroy the VPD kstats */ 1237 sfxge_vpd_kstat_fini(sp); 1238 1239 /* Destroy the configuration kstats */ 1240 sfxge_cfg_kstat_fini(sp); 1241 1242 /* 1243 * Destroy the soft state - this might fail until rx_loaned packets that 1244 * have been passed up the STREAMS stack are returned 1245 */ 1246 if ((rc = sfxge_destroy(sp)) != 0) 1247 goto fail2; 1248 1249 return (DDI_SUCCESS); 1250 1251 fail2: 1252 DTRACE_PROBE(fail2); 1253 fail1: 1254 DTRACE_PROBE1(fail1, int, rc); 1255 1256 return (DDI_FAILURE); 1257 } 1258 1259 #ifdef _USE_GLD_V3 1260 #ifndef _USE_GLD_V3_SOL10 1261 static int 1262 sfxge_quiesce(dev_info_t *dip) 1263 { 1264 sfxge_t *sp = ddi_get_soft_state(sfxge_ss, ddi_get_instance(dip)); 1265 int rc; 1266 1267 /* Reset the hardware */ 1268 if ((rc = sfxge_reset(sp, B_FALSE)) != 0) 1269 goto fail1; 1270 1271 return (DDI_SUCCESS); 1272 1273 fail1: 1274 DTRACE_PROBE1(fail1, int, rc); 1275 1276 return (DDI_FAILURE); 1277 } 1278 #endif 1279 #endif 1280 1281 /* 1282 * modlinkage 1283 */ 1284 DDI_DEFINE_STREAM_OPS(sfxge_dev_ops, nulldev, nulldev, sfxge_attach, 1285 sfxge_detach, nulldev, NULL, D_MP, NULL, NULL); 1286 1287 #ifdef _USE_GLD_V2 1288 1289 static struct module_info sfxge_module_info = { 1290 0, 1291 SFXGE_DRIVER_NAME, 1292 0, 1293 INFPSZ, 1294 1, 1295 0 1296 }; 1297 1298 static struct qinit sfxge_rqinit = { 1299 NULL, 1300 gld_rsrv, 1301 gld_open, 1302 gld_close, 1303 NULL, 1304 &sfxge_module_info, 1305 NULL 1306 }; 1307 1308 static struct qinit sfxge_wqinit = { 1309 gld_wput, 1310 gld_wsrv, 1311 NULL, 1312 NULL, 1313 NULL, 1314 &sfxge_module_info, 1315 NULL 1316 }; 1317 1318 static struct streamtab sfxge_streamtab = { 1319 &sfxge_rqinit, 1320 &sfxge_wqinit, 1321 NULL, 1322 NULL 1323 }; 1324 1325 static struct cb_ops sfxge_cb_ops = { 1326 nulldev, /* cb_open */ 1327 nulldev, /* cb_close */ 1328 nodev, /* cb_strategy */ 1329 nodev, /* cb_print */ 1330 nodev, /* cb_dump */ 1331 nodev, /* cb_read */ 1332 nodev, /* cb_write */ 1333 nodev, /* cb_ioctl */ 1334 nodev, /* cb_devmap */ 1335 nodev, /* cb_mmap */ 1336 nodev, /* cb_segmap */ 1337 nochpoll, /* cb_chpoll */ 1338 ddi_prop_op, /* cb_prop_op */ 1339 &sfxge_streamtab, /* cb_stream */ 1340 D_MP, /* cb_flag */ 1341 CB_REV, /* cb_rev */ 1342 nodev, /* cb_aread */ 1343 nodev, /* cb_awrite */ 1344 }; 1345 1346 static struct dev_ops sfxge_dev_ops = { 1347 DEVO_REV, /* devo_rev */ 1348 0, /* devo_refcnt */ 1349 NULL, /* devo_getinfo */ 1350 nulldev, /* devo_identify */ 1351 nulldev, /* devo_probe */ 1352 sfxge_attach, /* devo_attach */ 1353 sfxge_detach, /* devo_detach */ 1354 nulldev, /* devo_reset */ 1355 &sfxge_cb_ops, /* devo_cb_ops */ 1356 (struct bus_ops *)NULL, /* devo_bus_ops */ 1357 NULL /* devo_power */ 1358 }; 1359 1360 #endif 1361 1362 static struct modldrv sfxge_modldrv = { 1363 &mod_driverops, 1364 (char *)sfxge_ident, 1365 &sfxge_dev_ops, 1366 }; 1367 1368 static struct modlinkage sfxge_modlinkage = { 1369 MODREV_1, 1370 { &sfxge_modldrv, NULL } 1371 }; 1372 1373 kmutex_t sfxge_global_lock; 1374 unsigned int *sfxge_cpu; 1375 #ifdef _USE_CPU_PHYSID 1376 unsigned int *sfxge_core; 1377 unsigned int *sfxge_cache; 1378 unsigned int *sfxge_chip; 1379 #endif 1380 1381 int 1382 _init(void) 1383 { 1384 int rc; 1385 1386 mutex_init(&sfxge_global_lock, NULL, MUTEX_DRIVER, NULL); 1387 1388 /* Create tables for CPU, core, cache and chip counts */ 1389 sfxge_cpu = kmem_zalloc(sizeof (unsigned int) * NCPU, KM_SLEEP); 1390 #ifdef _USE_CPU_PHYSID 1391 sfxge_core = kmem_zalloc(sizeof (unsigned int) * NCPU, KM_SLEEP); 1392 sfxge_cache = kmem_zalloc(sizeof (unsigned int) * NCPU, KM_SLEEP); 1393 sfxge_chip = kmem_zalloc(sizeof (unsigned int) * NCPU, KM_SLEEP); 1394 #endif 1395 1396 if ((rc = ddi_soft_state_init(&sfxge_ss, sizeof (sfxge_t), 0)) != 0) 1397 goto fail1; 1398 1399 #ifdef _USE_GLD_V3 1400 mac_init_ops(&sfxge_dev_ops, SFXGE_DRIVER_NAME); 1401 #endif 1402 1403 if ((rc = mod_install(&sfxge_modlinkage)) != 0) 1404 goto fail2; 1405 1406 cmn_err(CE_NOTE, SFXGE_CMN_ERR 1407 "LOAD: Solarflare Ethernet Driver (%s) %s", 1408 SFXGE_DRIVER_NAME, sfxge_ident); 1409 1410 return (0); 1411 1412 fail2: 1413 DTRACE_PROBE(fail2); 1414 1415 #ifdef _USE_GLD_V3 1416 // mac_fini_ops(&sfxge_dev_ops); 1417 #endif 1418 1419 ddi_soft_state_fini(&sfxge_ss); 1420 1421 fail1: 1422 DTRACE_PROBE1(fail1, int, rc); 1423 1424 return (rc); 1425 } 1426 1427 int 1428 _fini(void) 1429 { 1430 int rc; 1431 1432 if ((rc = mod_remove(&sfxge_modlinkage)) != 0) 1433 return (rc); 1434 1435 cmn_err(CE_NOTE, SFXGE_CMN_ERR 1436 "UNLOAD: Solarflare Ethernet Driver (%s) %s", 1437 SFXGE_DRIVER_NAME, sfxge_ident); 1438 1439 #ifdef _USE_GLD_V3 1440 mac_fini_ops(&sfxge_dev_ops); 1441 #endif 1442 1443 ddi_soft_state_fini(&sfxge_ss); 1444 1445 /* Destroy tables */ 1446 #ifdef _USE_CPU_PHYSID 1447 kmem_free(sfxge_chip, sizeof (unsigned int) * NCPU); 1448 kmem_free(sfxge_cache, sizeof (unsigned int) * NCPU); 1449 kmem_free(sfxge_core, sizeof (unsigned int) * NCPU); 1450 #endif 1451 kmem_free(sfxge_cpu, sizeof (unsigned int) * NCPU); 1452 1453 mutex_destroy(&sfxge_global_lock); 1454 1455 return (0); 1456 } 1457 1458 int 1459 _info(struct modinfo *mip) 1460 { 1461 return (mod_info(&sfxge_modlinkage, mip)); 1462 }