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 }