sfxge.c revision 283050
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: head/sys/dev/sfxge/sfxge.c 283050 2015-05-18 06:04:20Z arybchik $"); 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#include <sys/syslog.h> 46 47#include <dev/pci/pcireg.h> 48#include <dev/pci/pcivar.h> 49 50#include <net/ethernet.h> 51#include <net/if.h> 52#include <net/if_var.h> 53#include <net/if_media.h> 54#include <net/if_types.h> 55 56#include "common/efx.h" 57 58#include "sfxge.h" 59#include "sfxge_rx.h" 60#include "sfxge_version.h" 61 62#define SFXGE_CAP (IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM | \ 63 IFCAP_RXCSUM | IFCAP_TXCSUM | \ 64 IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6 | \ 65 IFCAP_TSO4 | IFCAP_TSO6 | \ 66 IFCAP_JUMBO_MTU | IFCAP_LRO | \ 67 IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE | IFCAP_HWSTATS) 68#define SFXGE_CAP_ENABLE SFXGE_CAP 69#define SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | \ 70 IFCAP_JUMBO_MTU | IFCAP_LINKSTATE | IFCAP_HWSTATS) 71 72MALLOC_DEFINE(M_SFXGE, "sfxge", "Solarflare 10GigE driver"); 73 74 75SYSCTL_NODE(_hw, OID_AUTO, sfxge, CTLFLAG_RD, 0, 76 "SFXGE driver parameters"); 77 78#define SFXGE_PARAM_RX_RING SFXGE_PARAM(rx_ring) 79static int sfxge_rx_ring_entries = SFXGE_NDESCS; 80TUNABLE_INT(SFXGE_PARAM_RX_RING, &sfxge_rx_ring_entries); 81SYSCTL_INT(_hw_sfxge, OID_AUTO, rx_ring, CTLFLAG_RDTUN, 82 &sfxge_rx_ring_entries, 0, 83 "Maximum number of descriptors in a receive ring"); 84 85#define SFXGE_PARAM_TX_RING SFXGE_PARAM(tx_ring) 86static int sfxge_tx_ring_entries = SFXGE_NDESCS; 87TUNABLE_INT(SFXGE_PARAM_TX_RING, &sfxge_tx_ring_entries); 88SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_ring, CTLFLAG_RDTUN, 89 &sfxge_tx_ring_entries, 0, 90 "Maximum number of descriptors in a transmit ring"); 91 92 93static void 94sfxge_reset(void *arg, int npending); 95 96static int 97sfxge_start(struct sfxge_softc *sc) 98{ 99 int rc; 100 101 SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc); 102 103 if (sc->init_state == SFXGE_STARTED) 104 return (0); 105 106 if (sc->init_state != SFXGE_REGISTERED) { 107 rc = EINVAL; 108 goto fail; 109 } 110 111 if ((rc = efx_nic_init(sc->enp)) != 0) 112 goto fail; 113 114 /* Start processing interrupts. */ 115 if ((rc = sfxge_intr_start(sc)) != 0) 116 goto fail2; 117 118 /* Start processing events. */ 119 if ((rc = sfxge_ev_start(sc)) != 0) 120 goto fail3; 121 122 /* Start the receiver side. */ 123 if ((rc = sfxge_rx_start(sc)) != 0) 124 goto fail4; 125 126 /* Start the transmitter side. */ 127 if ((rc = sfxge_tx_start(sc)) != 0) 128 goto fail5; 129 130 /* Fire up the port. */ 131 if ((rc = sfxge_port_start(sc)) != 0) 132 goto fail6; 133 134 sc->init_state = SFXGE_STARTED; 135 136 /* Tell the stack we're running. */ 137 sc->ifnet->if_drv_flags |= IFF_DRV_RUNNING; 138 sc->ifnet->if_drv_flags &= ~IFF_DRV_OACTIVE; 139 140 return (0); 141 142fail6: 143 sfxge_tx_stop(sc); 144 145fail5: 146 sfxge_rx_stop(sc); 147 148fail4: 149 sfxge_ev_stop(sc); 150 151fail3: 152 sfxge_intr_stop(sc); 153 154fail2: 155 efx_nic_fini(sc->enp); 156 157fail: 158 device_printf(sc->dev, "sfxge_start: %d\n", rc); 159 160 return (rc); 161} 162 163static void 164sfxge_if_init(void *arg) 165{ 166 struct sfxge_softc *sc; 167 168 sc = (struct sfxge_softc *)arg; 169 170 SFXGE_ADAPTER_LOCK(sc); 171 (void)sfxge_start(sc); 172 SFXGE_ADAPTER_UNLOCK(sc); 173} 174 175static void 176sfxge_stop(struct sfxge_softc *sc) 177{ 178 SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc); 179 180 if (sc->init_state != SFXGE_STARTED) 181 return; 182 183 sc->init_state = SFXGE_REGISTERED; 184 185 /* Stop the port. */ 186 sfxge_port_stop(sc); 187 188 /* Stop the transmitter. */ 189 sfxge_tx_stop(sc); 190 191 /* Stop the receiver. */ 192 sfxge_rx_stop(sc); 193 194 /* Stop processing events. */ 195 sfxge_ev_stop(sc); 196 197 /* Stop processing interrupts. */ 198 sfxge_intr_stop(sc); 199 200 efx_nic_fini(sc->enp); 201 202 sc->ifnet->if_drv_flags &= ~IFF_DRV_RUNNING; 203} 204 205static int 206sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) 207{ 208 struct sfxge_softc *sc; 209 struct ifreq *ifr; 210 int error; 211 212 ifr = (struct ifreq *)data; 213 sc = ifp->if_softc; 214 error = 0; 215 216 switch (command) { 217 case SIOCSIFFLAGS: 218 SFXGE_ADAPTER_LOCK(sc); 219 if (ifp->if_flags & IFF_UP) { 220 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 221 if ((ifp->if_flags ^ sc->if_flags) & 222 (IFF_PROMISC | IFF_ALLMULTI)) { 223 sfxge_mac_filter_set(sc); 224 } 225 } else 226 sfxge_start(sc); 227 } else 228 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 229 sfxge_stop(sc); 230 sc->if_flags = ifp->if_flags; 231 SFXGE_ADAPTER_UNLOCK(sc); 232 break; 233 case SIOCSIFMTU: 234 if (ifr->ifr_mtu == ifp->if_mtu) { 235 /* Nothing to do */ 236 error = 0; 237 } else if (ifr->ifr_mtu > SFXGE_MAX_MTU) { 238 error = EINVAL; 239 } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 240 ifp->if_mtu = ifr->ifr_mtu; 241 error = 0; 242 } else { 243 /* Restart required */ 244 SFXGE_ADAPTER_LOCK(sc); 245 sfxge_stop(sc); 246 ifp->if_mtu = ifr->ifr_mtu; 247 error = sfxge_start(sc); 248 SFXGE_ADAPTER_UNLOCK(sc); 249 if (error != 0) { 250 ifp->if_flags &= ~IFF_UP; 251 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 252 if_down(ifp); 253 } 254 } 255 break; 256 case SIOCADDMULTI: 257 case SIOCDELMULTI: 258 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 259 sfxge_mac_filter_set(sc); 260 break; 261 case SIOCSIFCAP: 262 { 263 int reqcap = ifr->ifr_reqcap; 264 int capchg_mask; 265 266 SFXGE_ADAPTER_LOCK(sc); 267 268 /* Capabilities to be changed in accordance with request */ 269 capchg_mask = ifp->if_capenable ^ reqcap; 270 271 /* 272 * The networking core already rejects attempts to 273 * enable capabilities we don't have. We still have 274 * to reject attempts to disable capabilities that we 275 * can't (yet) disable. 276 */ 277 KASSERT((reqcap & ~ifp->if_capabilities) == 0, 278 ("Unsupported capabilities %x requested %x vs %x", 279 reqcap & ~ifp->if_capabilities, 280 reqcap , ifp->if_capabilities)); 281 if (capchg_mask & SFXGE_CAP_FIXED) { 282 error = EINVAL; 283 SFXGE_ADAPTER_UNLOCK(sc); 284 break; 285 } 286 287 /* Check request before any changes */ 288 if ((capchg_mask & IFCAP_TSO4) && 289 (reqcap & (IFCAP_TSO4 | IFCAP_TXCSUM)) == IFCAP_TSO4) { 290 error = EAGAIN; 291 SFXGE_ADAPTER_UNLOCK(sc); 292 if_printf(ifp, "enable txcsum before tso4\n"); 293 break; 294 } 295 if ((capchg_mask & IFCAP_TSO6) && 296 (reqcap & (IFCAP_TSO6 | IFCAP_TXCSUM_IPV6)) == IFCAP_TSO6) { 297 error = EAGAIN; 298 SFXGE_ADAPTER_UNLOCK(sc); 299 if_printf(ifp, "enable txcsum6 before tso6\n"); 300 break; 301 } 302 303 if (reqcap & IFCAP_TXCSUM) { 304 ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP); 305 } else { 306 ifp->if_hwassist &= ~(CSUM_IP | CSUM_TCP | CSUM_UDP); 307 if (reqcap & IFCAP_TSO4) { 308 reqcap &= ~IFCAP_TSO4; 309 if_printf(ifp, 310 "tso4 disabled due to -txcsum\n"); 311 } 312 } 313 if (reqcap & IFCAP_TXCSUM_IPV6) { 314 ifp->if_hwassist |= (CSUM_TCP_IPV6 | CSUM_UDP_IPV6); 315 } else { 316 ifp->if_hwassist &= ~(CSUM_TCP_IPV6 | CSUM_UDP_IPV6); 317 if (reqcap & IFCAP_TSO6) { 318 reqcap &= ~IFCAP_TSO6; 319 if_printf(ifp, 320 "tso6 disabled due to -txcsum6\n"); 321 } 322 } 323 324 /* 325 * The kernel takes both IFCAP_TSOx and CSUM_TSO into 326 * account before using TSO. So, we do not touch 327 * checksum flags when IFCAP_TSOx is modified. 328 * Note that CSUM_TSO is (CSUM_IP_TSO|CSUM_IP6_TSO), 329 * but both bits are set in IPv4 and IPv6 mbufs. 330 */ 331 332 ifp->if_capenable = reqcap; 333 334 SFXGE_ADAPTER_UNLOCK(sc); 335 break; 336 } 337 case SIOCSIFMEDIA: 338 case SIOCGIFMEDIA: 339 error = ifmedia_ioctl(ifp, ifr, &sc->media, command); 340 break; 341 default: 342 error = ether_ioctl(ifp, command, data); 343 } 344 345 return (error); 346} 347 348static void 349sfxge_ifnet_fini(struct ifnet *ifp) 350{ 351 struct sfxge_softc *sc = ifp->if_softc; 352 353 SFXGE_ADAPTER_LOCK(sc); 354 sfxge_stop(sc); 355 SFXGE_ADAPTER_UNLOCK(sc); 356 357 ifmedia_removeall(&sc->media); 358 ether_ifdetach(ifp); 359 if_free(ifp); 360} 361 362static int 363sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc) 364{ 365 const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp); 366 device_t dev; 367 int rc; 368 369 dev = sc->dev; 370 sc->ifnet = ifp; 371 372 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 373 ifp->if_init = sfxge_if_init; 374 ifp->if_softc = sc; 375 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 376 ifp->if_ioctl = sfxge_if_ioctl; 377 378 ifp->if_capabilities = SFXGE_CAP; 379 ifp->if_capenable = SFXGE_CAP_ENABLE; 380 ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO | 381 CSUM_TCP_IPV6 | CSUM_UDP_IPV6; 382 383 ether_ifattach(ifp, encp->enc_mac_addr); 384 385 ifp->if_transmit = sfxge_if_transmit; 386 ifp->if_qflush = sfxge_if_qflush; 387 388 ifp->if_get_counter = sfxge_get_counter; 389 390 if ((rc = sfxge_port_ifmedia_init(sc)) != 0) 391 goto fail; 392 393 return (0); 394 395fail: 396 ether_ifdetach(sc->ifnet); 397 return (rc); 398} 399 400void 401sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n, uint32_t *idp) 402{ 403 KASSERT(sc->buffer_table_next + n <= 404 efx_nic_cfg_get(sc->enp)->enc_buftbl_limit, 405 ("buffer table full")); 406 407 *idp = sc->buffer_table_next; 408 sc->buffer_table_next += n; 409} 410 411static int 412sfxge_bar_init(struct sfxge_softc *sc) 413{ 414 efsys_bar_t *esbp = &sc->bar; 415 416 esbp->esb_rid = PCIR_BAR(EFX_MEM_BAR); 417 if ((esbp->esb_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, 418 &esbp->esb_rid, RF_ACTIVE)) == NULL) { 419 device_printf(sc->dev, "Cannot allocate BAR region %d\n", 420 EFX_MEM_BAR); 421 return (ENXIO); 422 } 423 esbp->esb_tag = rman_get_bustag(esbp->esb_res); 424 esbp->esb_handle = rman_get_bushandle(esbp->esb_res); 425 426 SFXGE_BAR_LOCK_INIT(esbp, device_get_nameunit(sc->dev)); 427 428 return (0); 429} 430 431static void 432sfxge_bar_fini(struct sfxge_softc *sc) 433{ 434 efsys_bar_t *esbp = &sc->bar; 435 436 bus_release_resource(sc->dev, SYS_RES_MEMORY, esbp->esb_rid, 437 esbp->esb_res); 438 SFXGE_BAR_LOCK_DESTROY(esbp); 439} 440 441static int 442sfxge_create(struct sfxge_softc *sc) 443{ 444 device_t dev; 445 efx_nic_t *enp; 446 int error; 447 char rss_param_name[sizeof(SFXGE_PARAM(%d.max_rss_channels))]; 448 449 dev = sc->dev; 450 451 SFXGE_ADAPTER_LOCK_INIT(sc, device_get_nameunit(sc->dev)); 452 453 sc->max_rss_channels = 0; 454 snprintf(rss_param_name, sizeof(rss_param_name), 455 SFXGE_PARAM(%d.max_rss_channels), 456 (int)device_get_unit(dev)); 457 TUNABLE_INT_FETCH(rss_param_name, &sc->max_rss_channels); 458 459 sc->stats_node = SYSCTL_ADD_NODE( 460 device_get_sysctl_ctx(dev), 461 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 462 OID_AUTO, "stats", CTLFLAG_RD, NULL, "Statistics"); 463 if (sc->stats_node == NULL) { 464 error = ENOMEM; 465 goto fail; 466 } 467 468 TASK_INIT(&sc->task_reset, 0, sfxge_reset, sc); 469 470 (void) pci_enable_busmaster(dev); 471 472 /* Initialize DMA mappings. */ 473 if ((error = sfxge_dma_init(sc)) != 0) 474 goto fail; 475 476 /* Map the device registers. */ 477 if ((error = sfxge_bar_init(sc)) != 0) 478 goto fail; 479 480 error = efx_family(pci_get_vendor(dev), pci_get_device(dev), 481 &sc->family); 482 KASSERT(error == 0, ("Family should be filtered by sfxge_probe()")); 483 484 /* Create the common code nic object. */ 485 SFXGE_EFSYS_LOCK_INIT(&sc->enp_lock, 486 device_get_nameunit(sc->dev), "nic"); 487 if ((error = efx_nic_create(sc->family, (efsys_identifier_t *)sc, 488 &sc->bar, &sc->enp_lock, &enp)) != 0) 489 goto fail3; 490 sc->enp = enp; 491 492 if (!ISP2(sfxge_rx_ring_entries) || 493 !(sfxge_rx_ring_entries & EFX_RXQ_NDESCS_MASK)) { 494 log(LOG_ERR, "%s=%d must be power of 2 from %u to %u", 495 SFXGE_PARAM_RX_RING, sfxge_rx_ring_entries, 496 EFX_RXQ_MINNDESCS, EFX_RXQ_MAXNDESCS); 497 error = EINVAL; 498 goto fail_rx_ring_entries; 499 } 500 sc->rxq_entries = sfxge_rx_ring_entries; 501 502 if (!ISP2(sfxge_tx_ring_entries) || 503 !(sfxge_tx_ring_entries & EFX_TXQ_NDESCS_MASK)) { 504 log(LOG_ERR, "%s=%d must be power of 2 from %u to %u", 505 SFXGE_PARAM_TX_RING, sfxge_tx_ring_entries, 506 EFX_TXQ_MINNDESCS, EFX_TXQ_MAXNDESCS); 507 error = EINVAL; 508 goto fail_tx_ring_entries; 509 } 510 sc->txq_entries = sfxge_tx_ring_entries; 511 512 /* Initialize MCDI to talk to the microcontroller. */ 513 if ((error = sfxge_mcdi_init(sc)) != 0) 514 goto fail4; 515 516 /* Probe the NIC and build the configuration data area. */ 517 if ((error = efx_nic_probe(enp)) != 0) 518 goto fail5; 519 520 SYSCTL_ADD_STRING(device_get_sysctl_ctx(dev), 521 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 522 OID_AUTO, "version", CTLFLAG_RD, 523 SFXGE_VERSION_STRING, 0, 524 "Driver version"); 525 526 /* Initialize the NVRAM. */ 527 if ((error = efx_nvram_init(enp)) != 0) 528 goto fail6; 529 530 /* Initialize the VPD. */ 531 if ((error = efx_vpd_init(enp)) != 0) 532 goto fail7; 533 534 /* Reset the NIC. */ 535 if ((error = efx_nic_reset(enp)) != 0) 536 goto fail8; 537 538 /* Initialize buffer table allocation. */ 539 sc->buffer_table_next = 0; 540 541 /* Set up interrupts. */ 542 if ((error = sfxge_intr_init(sc)) != 0) 543 goto fail8; 544 545 /* Initialize event processing state. */ 546 if ((error = sfxge_ev_init(sc)) != 0) 547 goto fail11; 548 549 /* Initialize receive state. */ 550 if ((error = sfxge_rx_init(sc)) != 0) 551 goto fail12; 552 553 /* Initialize transmit state. */ 554 if ((error = sfxge_tx_init(sc)) != 0) 555 goto fail13; 556 557 /* Initialize port state. */ 558 if ((error = sfxge_port_init(sc)) != 0) 559 goto fail14; 560 561 sc->init_state = SFXGE_INITIALIZED; 562 563 return (0); 564 565fail14: 566 sfxge_tx_fini(sc); 567 568fail13: 569 sfxge_rx_fini(sc); 570 571fail12: 572 sfxge_ev_fini(sc); 573 574fail11: 575 sfxge_intr_fini(sc); 576 577fail8: 578 efx_vpd_fini(enp); 579 580fail7: 581 efx_nvram_fini(enp); 582 583fail6: 584 efx_nic_unprobe(enp); 585 586fail5: 587 sfxge_mcdi_fini(sc); 588 589fail4: 590fail_tx_ring_entries: 591fail_rx_ring_entries: 592 sc->enp = NULL; 593 efx_nic_destroy(enp); 594 SFXGE_EFSYS_LOCK_DESTROY(&sc->enp_lock); 595 596fail3: 597 sfxge_bar_fini(sc); 598 (void) pci_disable_busmaster(sc->dev); 599 600fail: 601 sc->dev = NULL; 602 SFXGE_ADAPTER_LOCK_DESTROY(sc); 603 return (error); 604} 605 606static void 607sfxge_destroy(struct sfxge_softc *sc) 608{ 609 efx_nic_t *enp; 610 611 /* Clean up port state. */ 612 sfxge_port_fini(sc); 613 614 /* Clean up transmit state. */ 615 sfxge_tx_fini(sc); 616 617 /* Clean up receive state. */ 618 sfxge_rx_fini(sc); 619 620 /* Clean up event processing state. */ 621 sfxge_ev_fini(sc); 622 623 /* Clean up interrupts. */ 624 sfxge_intr_fini(sc); 625 626 /* Tear down common code subsystems. */ 627 efx_nic_reset(sc->enp); 628 efx_vpd_fini(sc->enp); 629 efx_nvram_fini(sc->enp); 630 efx_nic_unprobe(sc->enp); 631 632 /* Tear down MCDI. */ 633 sfxge_mcdi_fini(sc); 634 635 /* Destroy common code context. */ 636 enp = sc->enp; 637 sc->enp = NULL; 638 efx_nic_destroy(enp); 639 640 /* Free DMA memory. */ 641 sfxge_dma_fini(sc); 642 643 /* Free mapped BARs. */ 644 sfxge_bar_fini(sc); 645 646 (void) pci_disable_busmaster(sc->dev); 647 648 taskqueue_drain(taskqueue_thread, &sc->task_reset); 649 650 /* Destroy the softc lock. */ 651 SFXGE_ADAPTER_LOCK_DESTROY(sc); 652} 653 654static int 655sfxge_vpd_handler(SYSCTL_HANDLER_ARGS) 656{ 657 struct sfxge_softc *sc = arg1; 658 efx_vpd_value_t value; 659 int rc; 660 661 value.evv_tag = arg2 >> 16; 662 value.evv_keyword = arg2 & 0xffff; 663 if ((rc = efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value)) 664 != 0) 665 return (rc); 666 667 return (SYSCTL_OUT(req, value.evv_value, value.evv_length)); 668} 669 670static void 671sfxge_vpd_try_add(struct sfxge_softc *sc, struct sysctl_oid_list *list, 672 efx_vpd_tag_t tag, const char *keyword) 673{ 674 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); 675 efx_vpd_value_t value; 676 677 /* Check whether VPD tag/keyword is present */ 678 value.evv_tag = tag; 679 value.evv_keyword = EFX_VPD_KEYWORD(keyword[0], keyword[1]); 680 if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) != 0) 681 return; 682 683 SYSCTL_ADD_PROC( 684 ctx, list, OID_AUTO, keyword, CTLTYPE_STRING|CTLFLAG_RD, 685 sc, tag << 16 | EFX_VPD_KEYWORD(keyword[0], keyword[1]), 686 sfxge_vpd_handler, "A", ""); 687} 688 689static int 690sfxge_vpd_init(struct sfxge_softc *sc) 691{ 692 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); 693 struct sysctl_oid *vpd_node; 694 struct sysctl_oid_list *vpd_list; 695 char keyword[3]; 696 efx_vpd_value_t value; 697 int rc; 698 699 if ((rc = efx_vpd_size(sc->enp, &sc->vpd_size)) != 0) 700 goto fail; 701 sc->vpd_data = malloc(sc->vpd_size, M_SFXGE, M_WAITOK); 702 if ((rc = efx_vpd_read(sc->enp, sc->vpd_data, sc->vpd_size)) != 0) 703 goto fail2; 704 705 /* Copy ID (product name) into device description, and log it. */ 706 value.evv_tag = EFX_VPD_ID; 707 if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) == 0) { 708 value.evv_value[value.evv_length] = 0; 709 device_set_desc_copy(sc->dev, value.evv_value); 710 device_printf(sc->dev, "%s\n", value.evv_value); 711 } 712 713 vpd_node = SYSCTL_ADD_NODE( 714 ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), 715 OID_AUTO, "vpd", CTLFLAG_RD, NULL, "Vital Product Data"); 716 vpd_list = SYSCTL_CHILDREN(vpd_node); 717 718 /* Add sysctls for all expected and any vendor-defined keywords. */ 719 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "PN"); 720 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "EC"); 721 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "SN"); 722 keyword[0] = 'V'; 723 keyword[2] = 0; 724 for (keyword[1] = '0'; keyword[1] <= '9'; keyword[1]++) 725 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword); 726 for (keyword[1] = 'A'; keyword[1] <= 'Z'; keyword[1]++) 727 sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword); 728 729 return (0); 730 731fail2: 732 free(sc->vpd_data, M_SFXGE); 733fail: 734 return (rc); 735} 736 737static void 738sfxge_vpd_fini(struct sfxge_softc *sc) 739{ 740 free(sc->vpd_data, M_SFXGE); 741} 742 743static void 744sfxge_reset(void *arg, int npending) 745{ 746 struct sfxge_softc *sc; 747 int rc; 748 749 (void)npending; 750 751 sc = (struct sfxge_softc *)arg; 752 753 SFXGE_ADAPTER_LOCK(sc); 754 755 if (sc->init_state != SFXGE_STARTED) 756 goto done; 757 758 sfxge_stop(sc); 759 efx_nic_reset(sc->enp); 760 if ((rc = sfxge_start(sc)) != 0) 761 device_printf(sc->dev, 762 "reset failed (%d); interface is now stopped\n", 763 rc); 764 765done: 766 SFXGE_ADAPTER_UNLOCK(sc); 767} 768 769void 770sfxge_schedule_reset(struct sfxge_softc *sc) 771{ 772 taskqueue_enqueue(taskqueue_thread, &sc->task_reset); 773} 774 775static int 776sfxge_attach(device_t dev) 777{ 778 struct sfxge_softc *sc; 779 struct ifnet *ifp; 780 int error; 781 782 sc = device_get_softc(dev); 783 sc->dev = dev; 784 785 /* Allocate ifnet. */ 786 ifp = if_alloc(IFT_ETHER); 787 if (ifp == NULL) { 788 device_printf(dev, "Couldn't allocate ifnet\n"); 789 error = ENOMEM; 790 goto fail; 791 } 792 sc->ifnet = ifp; 793 794 /* Initialize hardware. */ 795 if ((error = sfxge_create(sc)) != 0) 796 goto fail2; 797 798 /* Create the ifnet for the port. */ 799 if ((error = sfxge_ifnet_init(ifp, sc)) != 0) 800 goto fail3; 801 802 if ((error = sfxge_vpd_init(sc)) != 0) 803 goto fail4; 804 805 sc->init_state = SFXGE_REGISTERED; 806 807 return (0); 808 809fail4: 810 sfxge_ifnet_fini(ifp); 811fail3: 812 sfxge_destroy(sc); 813 814fail2: 815 if_free(sc->ifnet); 816 817fail: 818 return (error); 819} 820 821static int 822sfxge_detach(device_t dev) 823{ 824 struct sfxge_softc *sc; 825 826 sc = device_get_softc(dev); 827 828 sfxge_vpd_fini(sc); 829 830 /* Destroy the ifnet. */ 831 sfxge_ifnet_fini(sc->ifnet); 832 833 /* Tear down hardware. */ 834 sfxge_destroy(sc); 835 836 return (0); 837} 838 839static int 840sfxge_probe(device_t dev) 841{ 842 uint16_t pci_vendor_id; 843 uint16_t pci_device_id; 844 efx_family_t family; 845 int rc; 846 847 pci_vendor_id = pci_get_vendor(dev); 848 pci_device_id = pci_get_device(dev); 849 850 rc = efx_family(pci_vendor_id, pci_device_id, &family); 851 if (rc != 0) 852 return (ENXIO); 853 854 KASSERT(family == EFX_FAMILY_SIENA, ("impossible controller family")); 855 device_set_desc(dev, "Solarflare SFC9000 family"); 856 return (0); 857} 858 859static device_method_t sfxge_methods[] = { 860 DEVMETHOD(device_probe, sfxge_probe), 861 DEVMETHOD(device_attach, sfxge_attach), 862 DEVMETHOD(device_detach, sfxge_detach), 863 864 DEVMETHOD_END 865}; 866 867static devclass_t sfxge_devclass; 868 869static driver_t sfxge_driver = { 870 "sfxge", 871 sfxge_methods, 872 sizeof(struct sfxge_softc) 873}; 874 875DRIVER_MODULE(sfxge, pci, sfxge_driver, sfxge_devclass, 0, 0); 876