1/*- 2 * Copyright (c) 2010-2011 Solarflare Communications, Inc. 3 * All rights reserved. 4 * 5 * This software was developed in part by Philip Paeps under contract for 6 * Solarflare Communications, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD$"); 32 33#include <sys/param.h> 34#include <sys/kernel.h> 35#include <sys/bus.h> 36#include <sys/rman.h> 37#include <sys/lock.h> 38#include <sys/module.h> 39#include <sys/mutex.h> 40#include <sys/smp.h> 41#include <sys/socket.h> 42#include <sys/taskqueue.h> 43#include <sys/sockio.h> 44#include <sys/sysctl.h> 45 46#include <dev/pci/pcireg.h> 47#include <dev/pci/pcivar.h> 48 49#include <net/ethernet.h> 50#include <net/if.h> 51#include <net/if_media.h> 52#include <net/if_types.h> 53 54#include "common/efx.h" 55 56#include "sfxge.h" 57#include "sfxge_rx.h" 58 59#define SFXGE_CAP (IFCAP_VLAN_MTU | \ 60 IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | \ 61 IFCAP_JUMBO_MTU | IFCAP_LRO | \ 62 IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE) 63#define SFXGE_CAP_ENABLE SFXGE_CAP 64#define SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \ 65 IFCAP_JUMBO_MTU | IFCAP_LINKSTATE) 66 67MALLOC_DEFINE(M_SFXGE, "sfxge", "Solarflare 10GigE driver"); 68 69static void 70sfxge_reset(void *arg, int npending); 71 72static int 73sfxge_start(struct sfxge_softc *sc) 74{ 75 int rc; 76 77 sx_assert(&sc->softc_lock, LA_XLOCKED); 78 79 if (sc->init_state == SFXGE_STARTED) 80 return 0; 81 82 if (sc->init_state != SFXGE_REGISTERED) { 83 rc = EINVAL; 84 goto fail; 85 } 86 87 if ((rc = efx_nic_init(sc->enp)) != 0) 88 goto fail; 89 90 /* Start processing interrupts. */ 91 if ((rc = sfxge_intr_start(sc)) != 0) 92 goto fail2; 93 94 /* Start processing events. */ 95 if ((rc = sfxge_ev_start(sc)) != 0) 96 goto fail3; 97 98 /* Start the receiver side. */ 99 if ((rc = sfxge_rx_start(sc)) != 0) 100 goto fail4; 101 102 /* Start the transmitter side. */ 103 if ((rc = sfxge_tx_start(sc)) != 0) 104 goto fail5; 105 106 /* Fire up the port. */ 107 if ((rc = sfxge_port_start(sc)) != 0) 108 goto fail6; 109 110 sc->init_state = SFXGE_STARTED; 111 112 /* Tell the stack we're running. */ 113 sc->ifnet->if_drv_flags |= IFF_DRV_RUNNING; 114 sc->ifnet->if_drv_flags &= ~IFF_DRV_OACTIVE; 115 116 return (0); 117 118fail6: 119 sfxge_tx_stop(sc); 120 121fail5: 122 sfxge_rx_stop(sc); 123 124fail4: 125 sfxge_ev_stop(sc); 126 127fail3: 128 sfxge_intr_stop(sc); 129 130fail2: 131 efx_nic_fini(sc->enp); 132 133fail: 134 device_printf(sc->dev, "sfxge_start: %d\n", rc); 135 136 return (rc); 137} 138 139static void 140sfxge_if_init(void *arg) 141{ 142 struct sfxge_softc *sc; 143 144 sc = (struct sfxge_softc *)arg; 145 146 sx_xlock(&sc->softc_lock); 147 (void)sfxge_start(sc); 148 sx_xunlock(&sc->softc_lock); 149} 150 151static void 152sfxge_stop(struct sfxge_softc *sc) 153{ 154 sx_assert(&sc->softc_lock, LA_XLOCKED); 155 156 if (sc->init_state != SFXGE_STARTED) 157 return; 158 159 sc->init_state = SFXGE_REGISTERED; 160 161 /* Stop the port. */ 162 sfxge_port_stop(sc); 163 164 /* Stop the transmitter. */ 165 sfxge_tx_stop(sc); 166 167 /* Stop the receiver. */ 168 sfxge_rx_stop(sc); 169 170 /* Stop processing events. */ 171 sfxge_ev_stop(sc); 172 173 /* Stop processing interrupts. */ 174 sfxge_intr_stop(sc); 175 176 efx_nic_fini(sc->enp); 177 178 sc->ifnet->if_drv_flags &= ~IFF_DRV_RUNNING; 179} 180 181static int 182sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) 183{ 184 struct sfxge_softc *sc; 185 struct ifreq *ifr; 186 int error; 187 188 ifr = (struct ifreq *)data; 189 sc = ifp->if_softc; 190 error = 0; 191 192 switch (command) { 193 case SIOCSIFFLAGS: 194 sx_xlock(&sc->softc_lock); 195 if (ifp->if_flags & IFF_UP) { 196 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 197 if ((ifp->if_flags ^ sc->if_flags) & 198 (IFF_PROMISC | IFF_ALLMULTI)) { 199 sfxge_mac_filter_set(sc); 200 } 201 } else 202 sfxge_start(sc); 203 } else 204 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 205 sfxge_stop(sc); 206 sc->if_flags = ifp->if_flags; 207 sx_xunlock(&sc->softc_lock); 208 break; 209 case SIOCSIFMTU: 210 if (ifr->ifr_mtu == ifp->if_mtu) { 211 /* Nothing to do */ 212 error = 0; 213 } else if (ifr->ifr_mtu > SFXGE_MAX_MTU) { 214 error = EINVAL; 215 } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 216 ifp->if_mtu = ifr->ifr_mtu; 217 error = 0; 218 } else { 219 /* Restart required */ 220 sx_xlock(&sc->softc_lock); 221 sfxge_stop(sc); 222 ifp->if_mtu = ifr->ifr_mtu; 223 error = sfxge_start(sc); 224 sx_xunlock(&sc->softc_lock); 225 if (error) { 226 ifp->if_flags &= ~IFF_UP; 227 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 228 if_down(ifp); 229 } 230 } 231 break; 232 case SIOCADDMULTI: 233 case SIOCDELMULTI: 234 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 235 sfxge_mac_filter_set(sc); 236 break; 237 case SIOCSIFCAP: 238 sx_xlock(&sc->softc_lock); 239 240 /* 241 * The networking core already rejects attempts to 242 * enable capabilities we don't have. We still have 243 * to reject attempts to disable capabilities that we 244 * can't (yet) disable. 245 */ 246 if (~ifr->ifr_reqcap & SFXGE_CAP_FIXED) { 247 error = EINVAL; 248 sx_xunlock(&sc->softc_lock); 249 break; 250 } 251 252 ifp->if_capenable = ifr->ifr_reqcap; 253 if (ifp->if_capenable & IFCAP_TXCSUM) 254 ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP); 255 else 256 ifp->if_hwassist &= ~(CSUM_IP | CSUM_TCP | CSUM_UDP); 257 if (ifp->if_capenable & IFCAP_TSO) 258 ifp->if_hwassist |= CSUM_TSO; 259 else 260 ifp->if_hwassist &= ~CSUM_TSO; 261 262 sx_xunlock(&sc->softc_lock); 263 break; 264 case SIOCSIFMEDIA: 265 case SIOCGIFMEDIA: 266 error = ifmedia_ioctl(ifp, ifr, &sc->media, command); 267 break; 268 default: 269 error = ether_ioctl(ifp, command, data); 270 } 271 272 return (error); 273} 274 275static void 276sfxge_ifnet_fini(struct ifnet *ifp) 277{ 278 struct sfxge_softc *sc = ifp->if_softc; 279 280 sx_xlock(&sc->softc_lock); 281 sfxge_stop(sc); 282 sx_xunlock(&sc->softc_lock); 283 284 ifmedia_removeall(&sc->media); 285 ether_ifdetach(ifp); 286 if_free(ifp); 287} 288 289static int 290sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc) 291{ 292 const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp); 293 device_t dev; 294 int rc; 295 296 dev = sc->dev; 297 sc->ifnet = ifp; 298 299 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 300 ifp->if_init = sfxge_if_init; 301 ifp->if_softc = sc; 302 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 303 ifp->if_ioctl = sfxge_if_ioctl; 304 305 ifp->if_capabilities = SFXGE_CAP; 306 ifp->if_capenable = SFXGE_CAP_ENABLE; 307 ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO; 308 309 ether_ifattach(ifp, encp->enc_mac_addr); 310 311#ifdef SFXGE_HAVE_MQ 312 ifp->if_transmit = sfxge_if_transmit; 313 ifp->if_qflush = sfxge_if_qflush; 314#else 315 ifp->if_start = sfxge_if_start; 316 IFQ_SET_MAXLEN(&ifp->if_snd, SFXGE_NDESCS - 1); 317 ifp->if_snd.ifq_drv_maxlen = SFXGE_NDESCS - 1; 318 IFQ_SET_READY(&ifp->if_snd); 319 320 mtx_init(&sc->tx_lock, "txq", NULL, MTX_DEF); 321#endif 322 323 if ((rc = sfxge_port_ifmedia_init(sc)) != 0) 324 goto fail; 325 326 return 0; 327 328fail: 329 ether_ifdetach(sc->ifnet); 330 return rc; 331} 332 333void 334sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n, uint32_t *idp) 335{ 336 KASSERT(sc->buffer_table_next + n <= 337 efx_nic_cfg_get(sc->enp)->enc_buftbl_limit, 338 ("buffer table full")); 339 340 *idp = sc->buffer_table_next; 341 sc->buffer_table_next += n; 342} 343 344static int 345sfxge_bar_init(struct sfxge_softc *sc) 346{ 347 efsys_bar_t *esbp = &sc->bar; 348 349 esbp->esb_rid = PCIR_BAR(EFX_MEM_BAR); 350 if ((esbp->esb_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, 351 &esbp->esb_rid, RF_ACTIVE)) == NULL) { 352 device_printf(sc->dev, "Cannot allocate BAR region %d\n", 353 EFX_MEM_BAR); 354 return (ENXIO); 355 } 356 esbp->esb_tag = rman_get_bustag(esbp->esb_res); 357 esbp->esb_handle = rman_get_bushandle(esbp->esb_res); 358 mtx_init(&esbp->esb_lock, "sfxge_efsys_bar", NULL, MTX_DEF); 359 360 return (0); 361} 362 363static void 364sfxge_bar_fini(struct sfxge_softc *sc) 365{ 366 efsys_bar_t *esbp = &sc->bar; 367 368 bus_release_resource(sc->dev, SYS_RES_MEMORY, esbp->esb_rid, 369 esbp->esb_res); 370 mtx_destroy(&esbp->esb_lock); 371} 372 373static int 374sfxge_create(struct sfxge_softc *sc) 375{ 376 device_t dev; 377 efx_nic_t *enp; 378 int error; 379 380 dev = sc->dev; 381 382 sx_init(&sc->softc_lock, "sfxge_softc"); 383 384 sc->stats_node = SYSCTL_ADD_NODE( 385 device_get_sysctl_ctx(dev), 386 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 387 OID_AUTO, "stats", CTLFLAG_RD, NULL, "Statistics"); 388 if (!sc->stats_node) { 389 error = ENOMEM; 390 goto fail; 391 } 392 393 TASK_INIT(&sc->task_reset, 0, sfxge_reset, sc); 394 395 (void) pci_enable_busmaster(dev); 396 397 /* Initialize DMA mappings. */ 398 if ((error = sfxge_dma_init(sc)) != 0) 399 goto fail; 400 401 /* Map the device registers. */ 402 if ((error = sfxge_bar_init(sc)) != 0) 403 goto fail; 404 405 error = efx_family(pci_get_vendor(dev), pci_get_device(dev), 406 &sc->family); 407 KASSERT(error == 0, ("Family should be filtered by sfxge_probe()")); 408 409 /* Create the common code nic object. */ 410 mtx_init(&sc->enp_lock, "sfxge_nic", NULL, MTX_DEF); 411 if ((error = efx_nic_create(sc->family, (efsys_identifier_t *)sc, 412 &sc->bar, &sc->enp_lock, &enp)) != 0) 413 goto fail3; 414 sc->enp = enp; 415 416 /* Initialize MCDI to talk to the microcontroller. */ 417 if ((error = sfxge_mcdi_init(sc)) != 0) 418 goto fail4; 419 420 /* Probe the NIC and build the configuration data area. */ 421 if ((error = efx_nic_probe(enp)) != 0) 422 goto fail5; 423 424 /* Initialize the NVRAM. */ 425 if ((error = efx_nvram_init(enp)) != 0) 426 goto fail6; 427 428 /* Initialize the VPD. */ 429 if ((error = efx_vpd_init(enp)) != 0) 430 goto fail7; 431 432 /* Reset the NIC. */ 433 if ((error = efx_nic_reset(enp)) != 0) 434 goto fail8; 435 436 /* Initialize buffer table allocation. */ 437 sc->buffer_table_next = 0; 438 439 /* Set up interrupts. */ 440 if ((error = sfxge_intr_init(sc)) != 0) 441 goto fail8; 442 443 /* Initialize event processing state. */ 444 if ((error = sfxge_ev_init(sc)) != 0) 445 goto fail11; 446 447 /* Initialize receive state. */ 448 if ((error = sfxge_rx_init(sc)) != 0) 449 goto fail12; 450 451 /* Initialize transmit state. */ 452 if ((error = sfxge_tx_init(sc)) != 0) 453 goto fail13; 454 455 /* Initialize port state. */ 456 if ((error = sfxge_port_init(sc)) != 0) 457 goto fail14; 458 459 sc->init_state = SFXGE_INITIALIZED; 460 461 return (0); 462 463fail14: 464 sfxge_tx_fini(sc); 465 466fail13: 467 sfxge_rx_fini(sc); 468 469fail12: 470 sfxge_ev_fini(sc); 471 472fail11: 473 sfxge_intr_fini(sc); 474 475fail8: 476 efx_vpd_fini(enp); 477 478fail7: 479 efx_nvram_fini(enp); 480 481fail6: 482 efx_nic_unprobe(enp); 483 484fail5: 485 sfxge_mcdi_fini(sc); 486 487fail4: 488 sc->enp = NULL; 489 efx_nic_destroy(enp); 490 mtx_destroy(&sc->enp_lock); 491 492fail3: 493 sfxge_bar_fini(sc); 494 (void) pci_disable_busmaster(sc->dev); 495 496fail: 497 sc->dev = NULL; 498 sx_destroy(&sc->softc_lock); 499 return (error); 500} 501 502static void 503sfxge_destroy(struct sfxge_softc *sc) 504{ 505 efx_nic_t *enp; 506 507 /* Clean up port state. */ 508 sfxge_port_fini(sc); 509 510 /* Clean up transmit state. */ 511 sfxge_tx_fini(sc); 512 513 /* Clean up receive state. */ 514 sfxge_rx_fini(sc); 515 516 /* Clean up event processing state. */ 517 sfxge_ev_fini(sc); 518 519 /* Clean up interrupts. */ 520 sfxge_intr_fini(sc); 521 522 /* Tear down common code subsystems. */ 523 efx_nic_reset(sc->enp); 524 efx_vpd_fini(sc->enp); 525 efx_nvram_fini(sc->enp); 526 efx_nic_unprobe(sc->enp); 527 528 /* Tear down MCDI. */ 529 sfxge_mcdi_fini(sc); 530 531 /* Destroy common code context. */ 532 enp = sc->enp; 533 sc->enp = NULL; 534 efx_nic_destroy(enp); 535 536 /* Free DMA memory. */ 537 sfxge_dma_fini(sc); 538 539 /* Free mapped BARs. */ 540 sfxge_bar_fini(sc); 541 542 (void) pci_disable_busmaster(sc->dev); 543 544 taskqueue_drain(taskqueue_thread, &sc->task_reset); 545 546 /* Destroy the softc lock. */ 547 sx_destroy(&sc->softc_lock); 548} 549 550static int 551sfxge_vpd_handler(SYSCTL_HANDLER_ARGS) 552{ 553 struct sfxge_softc *sc = arg1; 554 efx_vpd_value_t value; 555 int rc; 556 557 value.evv_tag = arg2 >> 16; 558 value.evv_keyword = arg2 & 0xffff; 559 if ((rc = efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value)) 560 != 0) 561 return rc; 562 563 return SYSCTL_OUT(req, value.evv_value, value.evv_length); 564} 565 566static void 567sfxge_vpd_try_add(struct sfxge_softc *sc, struct sysctl_oid_list *list, 568 efx_vpd_tag_t tag, const char *keyword) 569{ 570 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); 571 efx_vpd_value_t value; 572 573 /* Check whether VPD tag/keyword is present */ 574 value.evv_tag = tag; 575 value.evv_keyword = EFX_VPD_KEYWORD(keyword[0], keyword[1]); 576 if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) != 0) 577 return; 578 579 SYSCTL_ADD_PROC( 580 ctx, list, OID_AUTO, keyword, CTLTYPE_STRING|CTLFLAG_RD, 581 sc, tag << 16 | EFX_VPD_KEYWORD(keyword[0], keyword[1]), 582 sfxge_vpd_handler, "A", ""); 583} 584 585static int 586sfxge_vpd_init(struct sfxge_softc *sc) 587{ 588 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); 589 struct sysctl_oid *vpd_node; 590 struct sysctl_oid_list *vpd_list; 591 char keyword[3]; 592 efx_vpd_value_t value; 593 int rc; 594 595 if ((rc = efx_vpd_size(sc->enp, &sc->vpd_size)) != 0) 596 goto fail; 597 sc->vpd_data = malloc(sc->vpd_size, M_SFXGE, M_WAITOK); 598 if ((rc = efx_vpd_read(sc->enp, sc->vpd_data, sc->vpd_size)) != 0) 599 goto fail2; 600 601 /* Copy ID (product name) into device description, and log it. */ 602 value.evv_tag = EFX_VPD_ID; 603 if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) == 0) { 604 value.evv_value[value.evv_length] = 0; 605 device_set_desc_copy(sc->dev, value.evv_value); 606 device_printf(sc->dev, "%s\n", value.evv_value); 607 } 608 609 vpd_node = SYSCTL_ADD_NODE( 610 ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), 611 OID_AUTO, "vpd", CTLFLAG_RD, NULL, "Vital Product Data"); 612 vpd_list = SYSCTL_CHILDREN(vpd_node); 613 614 /* Add sysctls for all expected and any vendor-defined keywords. */ 615 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "PN"); 616 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "EC"); 617 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "SN"); 618 keyword[0] = 'V'; 619 keyword[2] = 0; 620 for (keyword[1] = '0'; keyword[1] <= '9'; keyword[1]++) 621 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword); 622 for (keyword[1] = 'A'; keyword[1] <= 'Z'; keyword[1]++) 623 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword); 624 625 return 0; 626 627fail2: 628 free(sc->vpd_data, M_SFXGE); 629fail: 630 return rc; 631} 632 633static void 634sfxge_vpd_fini(struct sfxge_softc *sc) 635{ 636 free(sc->vpd_data, M_SFXGE); 637} 638 639static void 640sfxge_reset(void *arg, int npending) 641{ 642 struct sfxge_softc *sc; 643 int rc; 644 645 (void)npending; 646 647 sc = (struct sfxge_softc *)arg; 648 649 sx_xlock(&sc->softc_lock); 650 651 if (sc->init_state != SFXGE_STARTED) 652 goto done; 653 654 sfxge_stop(sc); 655 efx_nic_reset(sc->enp); 656 if ((rc = sfxge_start(sc)) != 0) 657 device_printf(sc->dev, 658 "reset failed (%d); interface is now stopped\n", 659 rc); 660 661done: 662 sx_xunlock(&sc->softc_lock); 663} 664 665void 666sfxge_schedule_reset(struct sfxge_softc *sc) 667{ 668 taskqueue_enqueue(taskqueue_thread, &sc->task_reset); 669} 670 671static int 672sfxge_attach(device_t dev) 673{ 674 struct sfxge_softc *sc; 675 struct ifnet *ifp; 676 int error; 677 678 sc = device_get_softc(dev); 679 sc->dev = dev; 680 681 /* Allocate ifnet. */ 682 ifp = if_alloc(IFT_ETHER); 683 if (ifp == NULL) { 684 device_printf(dev, "Couldn't allocate ifnet\n"); 685 error = ENOMEM; 686 goto fail; 687 } 688 sc->ifnet = ifp; 689 690 /* Initialize hardware. */ 691 if ((error = sfxge_create(sc)) != 0) 692 goto fail2; 693 694 /* Create the ifnet for the port. */ 695 if ((error = sfxge_ifnet_init(ifp, sc)) != 0) 696 goto fail3; 697 698 if ((error = sfxge_vpd_init(sc)) != 0) 699 goto fail4; 700 701 sc->init_state = SFXGE_REGISTERED; 702 703 return (0); 704 705fail4: 706 sfxge_ifnet_fini(ifp); 707fail3: 708 sfxge_destroy(sc); 709 710fail2: 711 if_free(sc->ifnet); 712 713fail: 714 return (error); 715} 716 717static int 718sfxge_detach(device_t dev) 719{ 720 struct sfxge_softc *sc; 721 722 sc = device_get_softc(dev); 723 724 sfxge_vpd_fini(sc); 725 726 /* Destroy the ifnet. */ 727 sfxge_ifnet_fini(sc->ifnet); 728 729 /* Tear down hardware. */ 730 sfxge_destroy(sc); 731 732 return (0); 733} 734 735static int 736sfxge_probe(device_t dev) 737{ 738 uint16_t pci_vendor_id; 739 uint16_t pci_device_id; 740 efx_family_t family; 741 int rc; 742 743 pci_vendor_id = pci_get_vendor(dev); 744 pci_device_id = pci_get_device(dev); 745 746 rc = efx_family(pci_vendor_id, pci_device_id, &family); 747 if (rc) 748 return ENXIO; 749 750 KASSERT(family == EFX_FAMILY_SIENA, ("impossible controller family")); 751 device_set_desc(dev, "Solarflare SFC9000 family"); 752 return 0; 753} 754 755static device_method_t sfxge_methods[] = { 756 DEVMETHOD(device_probe, sfxge_probe), 757 DEVMETHOD(device_attach, sfxge_attach), 758 DEVMETHOD(device_detach, sfxge_detach), 759 760 DEVMETHOD_END 761}; 762 763static devclass_t sfxge_devclass; 764 765static driver_t sfxge_driver = { 766 "sfxge", 767 sfxge_methods, 768 sizeof(struct sfxge_softc) 769}; 770 771DRIVER_MODULE(sfxge, pci, sfxge_driver, sfxge_devclass, 0, 0); 772