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/types.h> 34 #include <sys/limits.h> 35 #include <net/ethernet.h> 36 #include <net/if_dl.h> 37 38 #include "common/efx.h" 39 40 #include "sfxge.h" 41 42 static int 43 sfxge_mac_stat_update(struct sfxge_softc *sc) 44 { 45 struct sfxge_port *port = &sc->port; 46 efsys_mem_t *esmp = &(port->mac_stats.dma_buf); 47 clock_t now; 48 unsigned int count; 49 int rc; 50 51 SFXGE_PORT_LOCK_ASSERT_OWNED(port); 52 53 if (port->init_state != SFXGE_PORT_STARTED) { 54 rc = 0; 55 goto out; 56 } 57 58 now = ticks; 59 if (now - port->mac_stats.update_time < hz) { 60 rc = 0; 61 goto out; 62 } 63 64 port->mac_stats.update_time = now; 65 66 /* If we're unlucky enough to read statistics wduring the DMA, wait 67 * up to 10ms for it to finish (typically takes <500us) */ 68 for (count = 0; count < 100; ++count) { 69 EFSYS_PROBE1(wait, unsigned int, count); 70 71 /* Synchronize the DMA memory for reading */ 72 bus_dmamap_sync(esmp->esm_tag, esmp->esm_map, 73 BUS_DMASYNC_POSTREAD); 74 75 /* Try to update the cached counters */ 76 if ((rc = efx_mac_stats_update(sc->enp, esmp, 77 port->mac_stats.decode_buf, NULL)) != EAGAIN) 78 goto out; 79 80 DELAY(100); 81 } 82 83 rc = ETIMEDOUT; 84 out: 85 return (rc); 86 } 87 88 uint64_t 89 sfxge_get_counter(struct ifnet *ifp, ift_counter c) 90 { 91 struct sfxge_softc *sc = ifp->if_softc; 92 uint64_t *mac_stats; 93 uint64_t val; 94 95 SFXGE_PORT_LOCK(&sc->port); 96 97 /* Ignore error and use old values */ 98 (void)sfxge_mac_stat_update(sc); 99 100 mac_stats = (uint64_t *)sc->port.mac_stats.decode_buf; 101 102 switch (c) { 103 case IFCOUNTER_IPACKETS: 104 val = mac_stats[EFX_MAC_RX_PKTS]; 105 break; 106 case IFCOUNTER_IERRORS: 107 val = mac_stats[EFX_MAC_RX_ERRORS]; 108 break; 109 case IFCOUNTER_OPACKETS: 110 val = mac_stats[EFX_MAC_TX_PKTS]; 111 break; 112 case IFCOUNTER_OERRORS: 113 val = mac_stats[EFX_MAC_TX_ERRORS]; 114 break; 115 case IFCOUNTER_COLLISIONS: 116 val = mac_stats[EFX_MAC_TX_SGL_COL_PKTS] + 117 mac_stats[EFX_MAC_TX_MULT_COL_PKTS] + 118 mac_stats[EFX_MAC_TX_EX_COL_PKTS] + 119 mac_stats[EFX_MAC_TX_LATE_COL_PKTS]; 120 break; 121 case IFCOUNTER_IBYTES: 122 val = mac_stats[EFX_MAC_RX_OCTETS]; 123 break; 124 case IFCOUNTER_OBYTES: 125 val = mac_stats[EFX_MAC_TX_OCTETS]; 126 break; 127 case IFCOUNTER_OMCASTS: 128 val = mac_stats[EFX_MAC_TX_MULTICST_PKTS] + 129 mac_stats[EFX_MAC_TX_BRDCST_PKTS]; 130 break; 131 case IFCOUNTER_OQDROPS: 132 SFXGE_PORT_UNLOCK(&sc->port); 133 return (sfxge_tx_get_drops(sc)); 134 case IFCOUNTER_IMCASTS: 135 /* if_imcasts is maintained in net/if_ethersubr.c */ 136 case IFCOUNTER_IQDROPS: 137 /* if_iqdrops is maintained in net/if_ethersubr.c */ 138 case IFCOUNTER_NOPROTO: 139 /* if_noproto is maintained in net/if_ethersubr.c */ 140 default: 141 SFXGE_PORT_UNLOCK(&sc->port); 142 return (if_get_counter_default(ifp, c)); 143 } 144 145 SFXGE_PORT_UNLOCK(&sc->port); 146 147 return (val); 148 } 149 150 static int 151 sfxge_mac_stat_handler(SYSCTL_HANDLER_ARGS) 152 { 153 struct sfxge_softc *sc = arg1; 154 unsigned int id = arg2; 155 int rc; 156 uint64_t val; 157 158 SFXGE_PORT_LOCK(&sc->port); 159 if ((rc = sfxge_mac_stat_update(sc)) == 0) 160 val = ((uint64_t *)sc->port.mac_stats.decode_buf)[id]; 161 SFXGE_PORT_UNLOCK(&sc->port); 162 163 if (rc == 0) 164 rc = SYSCTL_OUT(req, &val, sizeof(val)); 165 return (rc); 166 } 167 168 static void 169 sfxge_mac_stat_init(struct sfxge_softc *sc) 170 { 171 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); 172 struct sysctl_oid_list *stat_list; 173 unsigned int id; 174 const char *name; 175 176 stat_list = SYSCTL_CHILDREN(sc->stats_node); 177 178 /* Initialise the named stats */ 179 for (id = 0; id < EFX_MAC_NSTATS; id++) { 180 name = efx_mac_stat_name(sc->enp, id); 181 SYSCTL_ADD_PROC( 182 ctx, stat_list, 183 OID_AUTO, name, CTLTYPE_U64|CTLFLAG_RD, 184 sc, id, sfxge_mac_stat_handler, "Q", 185 ""); 186 } 187 } 188 189 #ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS 190 191 static unsigned int 192 sfxge_port_wanted_fc(struct sfxge_softc *sc) 193 { 194 struct ifmedia_entry *ifm = sc->media.ifm_cur; 195 196 if (ifm->ifm_media == (IFM_ETHER | IFM_AUTO)) 197 return (EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE); 198 return (((ifm->ifm_media & IFM_ETH_RXPAUSE) ? EFX_FCNTL_RESPOND : 0) | 199 ((ifm->ifm_media & IFM_ETH_TXPAUSE) ? EFX_FCNTL_GENERATE : 0)); 200 } 201 202 static unsigned int 203 sfxge_port_link_fc_ifm(struct sfxge_softc *sc) 204 { 205 unsigned int wanted_fc, link_fc; 206 207 efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc); 208 return ((link_fc & EFX_FCNTL_RESPOND) ? IFM_ETH_RXPAUSE : 0) | 209 ((link_fc & EFX_FCNTL_GENERATE) ? IFM_ETH_TXPAUSE : 0); 210 } 211 212 #else /* !SFXGE_HAVE_PAUSE_MEDIAOPTS */ 213 214 static unsigned int 215 sfxge_port_wanted_fc(struct sfxge_softc *sc) 216 { 217 return (sc->port.wanted_fc); 218 } 219 220 static unsigned int 221 sfxge_port_link_fc_ifm(struct sfxge_softc *sc) 222 { 223 return (0); 224 } 225 226 static int 227 sfxge_port_wanted_fc_handler(SYSCTL_HANDLER_ARGS) 228 { 229 struct sfxge_softc *sc; 230 struct sfxge_port *port; 231 unsigned int fcntl; 232 int error; 233 234 sc = arg1; 235 port = &sc->port; 236 237 if (req->newptr != NULL) { 238 if ((error = SYSCTL_IN(req, &fcntl, sizeof(fcntl))) != 0) 239 return (error); 240 241 SFXGE_PORT_LOCK(port); 242 243 if (port->wanted_fc != fcntl) { 244 if (port->init_state == SFXGE_PORT_STARTED) 245 error = efx_mac_fcntl_set(sc->enp, 246 port->wanted_fc, 247 B_TRUE); 248 if (error == 0) 249 port->wanted_fc = fcntl; 250 } 251 252 SFXGE_PORT_UNLOCK(port); 253 } else { 254 SFXGE_PORT_LOCK(port); 255 fcntl = port->wanted_fc; 256 SFXGE_PORT_UNLOCK(port); 257 258 error = SYSCTL_OUT(req, &fcntl, sizeof(fcntl)); 259 } 260 261 return (error); 262 } 263 264 static int 265 sfxge_port_link_fc_handler(SYSCTL_HANDLER_ARGS) 266 { 267 struct sfxge_softc *sc; 268 struct sfxge_port *port; 269 unsigned int wanted_fc, link_fc; 270 271 sc = arg1; 272 port = &sc->port; 273 274 SFXGE_PORT_LOCK(port); 275 if (port->init_state == SFXGE_PORT_STARTED && SFXGE_LINK_UP(sc)) 276 efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc); 277 else 278 link_fc = 0; 279 SFXGE_PORT_UNLOCK(port); 280 281 return (SYSCTL_OUT(req, &link_fc, sizeof(link_fc))); 282 } 283 284 #endif /* SFXGE_HAVE_PAUSE_MEDIAOPTS */ 285 286 static const uint64_t sfxge_link_baudrate[EFX_LINK_NMODES] = { 287 [EFX_LINK_10HDX] = IF_Mbps(10), 288 [EFX_LINK_10FDX] = IF_Mbps(10), 289 [EFX_LINK_100HDX] = IF_Mbps(100), 290 [EFX_LINK_100FDX] = IF_Mbps(100), 291 [EFX_LINK_1000HDX] = IF_Gbps(1), 292 [EFX_LINK_1000FDX] = IF_Gbps(1), 293 [EFX_LINK_10000FDX] = IF_Gbps(10), 294 }; 295 296 void 297 sfxge_mac_link_update(struct sfxge_softc *sc, efx_link_mode_t mode) 298 { 299 struct sfxge_port *port; 300 int link_state; 301 302 port = &sc->port; 303 304 if (port->link_mode == mode) 305 return; 306 307 port->link_mode = mode; 308 309 /* Push link state update to the OS */ 310 link_state = (port->link_mode != EFX_LINK_DOWN ? 311 LINK_STATE_UP : LINK_STATE_DOWN); 312 sc->ifnet->if_baudrate = sfxge_link_baudrate[port->link_mode]; 313 if_link_state_change(sc->ifnet, link_state); 314 } 315 316 static void 317 sfxge_mac_poll_work(void *arg, int npending) 318 { 319 struct sfxge_softc *sc; 320 efx_nic_t *enp; 321 struct sfxge_port *port; 322 efx_link_mode_t mode; 323 324 sc = (struct sfxge_softc *)arg; 325 enp = sc->enp; 326 port = &sc->port; 327 328 SFXGE_PORT_LOCK(port); 329 330 if (port->init_state != SFXGE_PORT_STARTED) 331 goto done; 332 333 /* This may sleep waiting for MCDI completion */ 334 (void)efx_port_poll(enp, &mode); 335 sfxge_mac_link_update(sc, mode); 336 337 done: 338 SFXGE_PORT_UNLOCK(port); 339 } 340 341 static int 342 sfxge_mac_filter_set_locked(struct sfxge_softc *sc) 343 { 344 unsigned int bucket[EFX_MAC_HASH_BITS]; 345 struct ifnet *ifp = sc->ifnet; 346 struct ifmultiaddr *ifma; 347 struct sockaddr_dl *sa; 348 efx_nic_t *enp = sc->enp; 349 unsigned int index; 350 int rc; 351 352 /* Set promisc-unicast and broadcast filter bits */ 353 if ((rc = efx_mac_filter_set(enp, !!(ifp->if_flags & IFF_PROMISC), 354 B_TRUE)) != 0) 355 return (rc); 356 357 /* Set multicast hash filter */ 358 if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) { 359 for (index = 0; index < EFX_MAC_HASH_BITS; index++) 360 bucket[index] = 1; 361 } else { 362 /* Broadcast frames also go through the multicast 363 * filter, and the broadcast address hashes to 364 * 0xff. */ 365 bucket[0xff] = 1; 366 367 if_maddr_rlock(ifp); 368 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 369 if (ifma->ifma_addr->sa_family == AF_LINK) { 370 sa = (struct sockaddr_dl *)ifma->ifma_addr; 371 index = ether_crc32_le(LLADDR(sa), 6) & 0xff; 372 bucket[index] = 1; 373 } 374 } 375 if_maddr_runlock(ifp); 376 } 377 return (efx_mac_hash_set(enp, bucket)); 378 } 379 380 int 381 sfxge_mac_filter_set(struct sfxge_softc *sc) 382 { 383 struct sfxge_port *port = &sc->port; 384 int rc; 385 386 SFXGE_PORT_LOCK(port); 387 /* 388 * The function may be called without softc_lock held in the 389 * case of SIOCADDMULTI and SIOCDELMULTI ioctls. ioctl handler 390 * checks IFF_DRV_RUNNING flag which implies port started, but 391 * it is not guaranteed to remain. softc_lock shared lock can't 392 * be held in the case of these ioctls processing, since it 393 * results in failure where kernel complains that non-sleepable 394 * lock is held in sleeping thread. Both problems are repeatable 395 * on LAG with LACP proto bring up. 396 */ 397 if (port->init_state == SFXGE_PORT_STARTED) 398 rc = sfxge_mac_filter_set_locked(sc); 399 else 400 rc = 0; 401 SFXGE_PORT_UNLOCK(port); 402 return (rc); 403 } 404 405 void 406 sfxge_port_stop(struct sfxge_softc *sc) 407 { 408 struct sfxge_port *port; 409 efx_nic_t *enp; 410 411 port = &sc->port; 412 enp = sc->enp; 413 414 SFXGE_PORT_LOCK(port); 415 416 KASSERT(port->init_state == SFXGE_PORT_STARTED, 417 ("port not started")); 418 419 port->init_state = SFXGE_PORT_INITIALIZED; 420 421 port->mac_stats.update_time = 0; 422 423 /* This may call MCDI */ 424 (void)efx_mac_drain(enp, B_TRUE); 425 426 (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE); 427 428 port->link_mode = EFX_LINK_UNKNOWN; 429 430 /* Destroy the common code port object. */ 431 efx_port_fini(sc->enp); 432 433 SFXGE_PORT_UNLOCK(port); 434 } 435 436 int 437 sfxge_port_start(struct sfxge_softc *sc) 438 { 439 uint8_t mac_addr[ETHER_ADDR_LEN]; 440 struct ifnet *ifp = sc->ifnet; 441 struct sfxge_port *port; 442 efx_nic_t *enp; 443 size_t pdu; 444 int rc; 445 446 port = &sc->port; 447 enp = sc->enp; 448 449 SFXGE_PORT_LOCK(port); 450 451 KASSERT(port->init_state == SFXGE_PORT_INITIALIZED, 452 ("port not initialized")); 453 454 /* Initialize the port object in the common code. */ 455 if ((rc = efx_port_init(sc->enp)) != 0) 456 goto fail; 457 458 /* Set the SDU */ 459 pdu = EFX_MAC_PDU(ifp->if_mtu); 460 if ((rc = efx_mac_pdu_set(enp, pdu)) != 0) 461 goto fail2; 462 463 if ((rc = efx_mac_fcntl_set(enp, sfxge_port_wanted_fc(sc), B_TRUE)) 464 != 0) 465 goto fail2; 466 467 /* Set the unicast address */ 468 if_addr_rlock(ifp); 469 bcopy(LLADDR((struct sockaddr_dl *)ifp->if_addr->ifa_addr), 470 mac_addr, sizeof(mac_addr)); 471 if_addr_runlock(ifp); 472 if ((rc = efx_mac_addr_set(enp, mac_addr)) != 0) 473 goto fail; 474 475 sfxge_mac_filter_set_locked(sc); 476 477 /* Update MAC stats by DMA every second */ 478 if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 479 1000, B_FALSE)) != 0) 480 goto fail2; 481 482 if ((rc = efx_mac_drain(enp, B_FALSE)) != 0) 483 goto fail3; 484 485 if ((rc = efx_phy_adv_cap_set(sc->enp, sc->media.ifm_cur->ifm_data)) 486 != 0) 487 goto fail4; 488 489 port->init_state = SFXGE_PORT_STARTED; 490 491 /* Single poll in case there were missing initial events */ 492 SFXGE_PORT_UNLOCK(port); 493 sfxge_mac_poll_work(sc, 0); 494 495 return (0); 496 497 fail4: 498 (void)efx_mac_drain(enp, B_TRUE); 499 fail3: 500 (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 501 0, B_FALSE); 502 fail2: 503 efx_port_fini(sc->enp); 504 fail: 505 SFXGE_PORT_UNLOCK(port); 506 507 return (rc); 508 } 509 510 static int 511 sfxge_phy_stat_update(struct sfxge_softc *sc) 512 { 513 struct sfxge_port *port = &sc->port; 514 efsys_mem_t *esmp = &port->phy_stats.dma_buf; 515 clock_t now; 516 unsigned int count; 517 int rc; 518 519 SFXGE_PORT_LOCK_ASSERT_OWNED(port); 520 521 if (port->init_state != SFXGE_PORT_STARTED) { 522 rc = 0; 523 goto out; 524 } 525 526 now = ticks; 527 if (now - port->phy_stats.update_time < hz) { 528 rc = 0; 529 goto out; 530 } 531 532 port->phy_stats.update_time = now; 533 534 /* If we're unlucky enough to read statistics wduring the DMA, wait 535 * up to 10ms for it to finish (typically takes <500us) */ 536 for (count = 0; count < 100; ++count) { 537 EFSYS_PROBE1(wait, unsigned int, count); 538 539 /* Synchronize the DMA memory for reading */ 540 bus_dmamap_sync(esmp->esm_tag, esmp->esm_map, 541 BUS_DMASYNC_POSTREAD); 542 543 /* Try to update the cached counters */ 544 if ((rc = efx_phy_stats_update(sc->enp, esmp, 545 port->phy_stats.decode_buf)) != EAGAIN) 546 goto out; 547 548 DELAY(100); 549 } 550 551 rc = ETIMEDOUT; 552 out: 553 return (rc); 554 } 555 556 static int 557 sfxge_phy_stat_handler(SYSCTL_HANDLER_ARGS) 558 { 559 struct sfxge_softc *sc = arg1; 560 unsigned int id = arg2; 561 int rc; 562 uint32_t val; 563 564 SFXGE_PORT_LOCK(&sc->port); 565 if ((rc = sfxge_phy_stat_update(sc)) == 0) 566 val = ((uint32_t *)sc->port.phy_stats.decode_buf)[id]; 567 SFXGE_PORT_UNLOCK(&sc->port); 568 569 if (rc == 0) 570 rc = SYSCTL_OUT(req, &val, sizeof(val)); 571 return (rc); 572 } 573 574 static void 575 sfxge_phy_stat_init(struct sfxge_softc *sc) 576 { 577 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); 578 struct sysctl_oid_list *stat_list; 579 unsigned int id; 580 const char *name; 581 uint64_t stat_mask = efx_nic_cfg_get(sc->enp)->enc_phy_stat_mask; 582 583 stat_list = SYSCTL_CHILDREN(sc->stats_node); 584 585 /* Initialise the named stats */ 586 for (id = 0; id < EFX_PHY_NSTATS; id++) { 587 if (!(stat_mask & ((uint64_t)1 << id))) 588 continue; 589 name = efx_phy_stat_name(sc->enp, id); 590 SYSCTL_ADD_PROC( 591 ctx, stat_list, 592 OID_AUTO, name, CTLTYPE_UINT|CTLFLAG_RD, 593 sc, id, sfxge_phy_stat_handler, 594 id == EFX_PHY_STAT_OUI ? "IX" : "IU", 595 ""); 596 } 597 } 598 599 void 600 sfxge_port_fini(struct sfxge_softc *sc) 601 { 602 struct sfxge_port *port; 603 efsys_mem_t *esmp; 604 605 port = &sc->port; 606 esmp = &port->mac_stats.dma_buf; 607 608 KASSERT(port->init_state == SFXGE_PORT_INITIALIZED, 609 ("Port not initialized")); 610 611 port->init_state = SFXGE_PORT_UNINITIALIZED; 612 613 port->link_mode = EFX_LINK_UNKNOWN; 614 615 /* Finish with PHY DMA memory */ 616 sfxge_dma_free(&port->phy_stats.dma_buf); 617 free(port->phy_stats.decode_buf, M_SFXGE); 618 619 sfxge_dma_free(esmp); 620 free(port->mac_stats.decode_buf, M_SFXGE); 621 622 SFXGE_PORT_LOCK_DESTROY(port); 623 624 port->sc = NULL; 625 } 626 627 int 628 sfxge_port_init(struct sfxge_softc *sc) 629 { 630 struct sfxge_port *port; 631 struct sysctl_ctx_list *sysctl_ctx; 632 struct sysctl_oid *sysctl_tree; 633 efsys_mem_t *mac_stats_buf, *phy_stats_buf; 634 int rc; 635 636 port = &sc->port; 637 mac_stats_buf = &port->mac_stats.dma_buf; 638 phy_stats_buf = &port->phy_stats.dma_buf; 639 640 KASSERT(port->init_state == SFXGE_PORT_UNINITIALIZED, 641 ("Port already initialized")); 642 643 port->sc = sc; 644 645 SFXGE_PORT_LOCK_INIT(port, device_get_nameunit(sc->dev)); 646 647 port->phy_stats.decode_buf = malloc(EFX_PHY_NSTATS * sizeof(uint32_t), 648 M_SFXGE, M_WAITOK | M_ZERO); 649 if ((rc = sfxge_dma_alloc(sc, EFX_PHY_STATS_SIZE, phy_stats_buf)) != 0) 650 goto fail; 651 sfxge_phy_stat_init(sc); 652 653 sysctl_ctx = device_get_sysctl_ctx(sc->dev); 654 sysctl_tree = device_get_sysctl_tree(sc->dev); 655 656 #ifndef SFXGE_HAVE_PAUSE_MEDIAOPTS 657 /* If flow control cannot be configured or reported through 658 * ifmedia, provide sysctls for it. */ 659 port->wanted_fc = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE; 660 SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, 661 "wanted_fc", CTLTYPE_UINT|CTLFLAG_RW, sc, 0, 662 sfxge_port_wanted_fc_handler, "IU", "wanted flow control mode"); 663 SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, 664 "link_fc", CTLTYPE_UINT|CTLFLAG_RD, sc, 0, 665 sfxge_port_link_fc_handler, "IU", "link flow control mode"); 666 #endif 667 668 port->mac_stats.decode_buf = malloc(EFX_MAC_NSTATS * sizeof(uint64_t), 669 M_SFXGE, M_WAITOK | M_ZERO); 670 if ((rc = sfxge_dma_alloc(sc, EFX_MAC_STATS_SIZE, mac_stats_buf)) != 0) 671 goto fail2; 672 sfxge_mac_stat_init(sc); 673 674 port->init_state = SFXGE_PORT_INITIALIZED; 675 676 return (0); 677 678 fail2: 679 free(port->mac_stats.decode_buf, M_SFXGE); 680 sfxge_dma_free(phy_stats_buf); 681 fail: 682 free(port->phy_stats.decode_buf, M_SFXGE); 683 SFXGE_PORT_LOCK_DESTROY(port); 684 port->sc = NULL; 685 return (rc); 686 } 687 688 static int sfxge_link_mode[EFX_PHY_MEDIA_NTYPES][EFX_LINK_NMODES] = { 689 [EFX_PHY_MEDIA_CX4] = { 690 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_CX4, 691 }, 692 [EFX_PHY_MEDIA_KX4] = { 693 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_KX4, 694 }, 695 [EFX_PHY_MEDIA_XFP] = { 696 /* Don't know the module type, but assume SR for now. */ 697 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR, 698 }, 699 [EFX_PHY_MEDIA_SFP_PLUS] = { 700 /* Don't know the module type, but assume SX/SR for now. */ 701 [EFX_LINK_1000FDX] = IFM_ETHER | IFM_FDX | IFM_1000_SX, 702 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR, 703 }, 704 [EFX_PHY_MEDIA_BASE_T] = { 705 [EFX_LINK_10HDX] = IFM_ETHER | IFM_HDX | IFM_10_T, 706 [EFX_LINK_10FDX] = IFM_ETHER | IFM_FDX | IFM_10_T, 707 [EFX_LINK_100HDX] = IFM_ETHER | IFM_HDX | IFM_100_TX, 708 [EFX_LINK_100FDX] = IFM_ETHER | IFM_FDX | IFM_100_TX, 709 [EFX_LINK_1000HDX] = IFM_ETHER | IFM_HDX | IFM_1000_T, 710 [EFX_LINK_1000FDX] = IFM_ETHER | IFM_FDX | IFM_1000_T, 711 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_T, 712 }, 713 }; 714 715 static void 716 sfxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) 717 { 718 struct sfxge_softc *sc; 719 efx_phy_media_type_t medium_type; 720 efx_link_mode_t mode; 721 722 sc = ifp->if_softc; 723 SFXGE_ADAPTER_LOCK(sc); 724 725 ifmr->ifm_status = IFM_AVALID; 726 ifmr->ifm_active = IFM_ETHER; 727 728 if (SFXGE_RUNNING(sc) && SFXGE_LINK_UP(sc)) { 729 ifmr->ifm_status |= IFM_ACTIVE; 730 731 efx_phy_media_type_get(sc->enp, &medium_type); 732 mode = sc->port.link_mode; 733 ifmr->ifm_active |= sfxge_link_mode[medium_type][mode]; 734 ifmr->ifm_active |= sfxge_port_link_fc_ifm(sc); 735 } 736 737 SFXGE_ADAPTER_UNLOCK(sc); 738 } 739 740 static int 741 sfxge_media_change(struct ifnet *ifp) 742 { 743 struct sfxge_softc *sc; 744 struct ifmedia_entry *ifm; 745 int rc; 746 747 sc = ifp->if_softc; 748 ifm = sc->media.ifm_cur; 749 750 SFXGE_ADAPTER_LOCK(sc); 751 752 if (!SFXGE_RUNNING(sc)) { 753 rc = 0; 754 goto out; 755 } 756 757 rc = efx_mac_fcntl_set(sc->enp, sfxge_port_wanted_fc(sc), B_TRUE); 758 if (rc != 0) 759 goto out; 760 761 rc = efx_phy_adv_cap_set(sc->enp, ifm->ifm_data); 762 out: 763 SFXGE_ADAPTER_UNLOCK(sc); 764 765 return (rc); 766 } 767 768 int sfxge_port_ifmedia_init(struct sfxge_softc *sc) 769 { 770 efx_phy_media_type_t medium_type; 771 uint32_t cap_mask, mode_cap_mask; 772 efx_link_mode_t mode; 773 int mode_ifm, best_mode_ifm = 0; 774 int rc; 775 776 /* We need port state to initialise the ifmedia list. */ 777 if ((rc = efx_nic_init(sc->enp)) != 0) 778 goto out; 779 if ((rc = efx_port_init(sc->enp)) != 0) 780 goto out2; 781 782 /* 783 * Register ifconfig callbacks for querying and setting the 784 * link mode and link status. 785 */ 786 ifmedia_init(&sc->media, IFM_IMASK, sfxge_media_change, 787 sfxge_media_status); 788 789 /* 790 * Map firmware medium type and capabilities to ifmedia types. 791 * ifmedia does not distinguish between forcing the link mode 792 * and disabling auto-negotiation. 1000BASE-T and 10GBASE-T 793 * require AN even if only one link mode is enabled, and for 794 * 100BASE-TX it is useful even if the link mode is forced. 795 * Therefore we never disable auto-negotiation. 796 * 797 * Also enable and advertise flow control by default. 798 */ 799 800 efx_phy_media_type_get(sc->enp, &medium_type); 801 efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask); 802 803 EFX_STATIC_ASSERT(EFX_LINK_10HDX == EFX_PHY_CAP_10HDX + 1); 804 EFX_STATIC_ASSERT(EFX_LINK_10FDX == EFX_PHY_CAP_10FDX + 1); 805 EFX_STATIC_ASSERT(EFX_LINK_100HDX == EFX_PHY_CAP_100HDX + 1); 806 EFX_STATIC_ASSERT(EFX_LINK_100FDX == EFX_PHY_CAP_100FDX + 1); 807 EFX_STATIC_ASSERT(EFX_LINK_1000HDX == EFX_PHY_CAP_1000HDX + 1); 808 EFX_STATIC_ASSERT(EFX_LINK_1000FDX == EFX_PHY_CAP_1000FDX + 1); 809 EFX_STATIC_ASSERT(EFX_LINK_10000FDX == EFX_PHY_CAP_10000FDX + 1); 810 811 for (mode = EFX_LINK_10HDX; mode <= EFX_LINK_10000FDX; mode++) { 812 mode_cap_mask = 1 << (mode - 1); 813 mode_ifm = sfxge_link_mode[medium_type][mode]; 814 815 if ((cap_mask & mode_cap_mask) && mode_ifm) { 816 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_AN); 817 818 #ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS 819 /* No flow-control */ 820 ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL); 821 822 /* Respond-only. If using AN, we implicitly 823 * offer symmetric as well, but that doesn't 824 * mean we *have* to generate pause frames. 825 */ 826 mode_cap_mask |= cap_mask & ((1 << EFX_PHY_CAP_PAUSE) | 827 (1 << EFX_PHY_CAP_ASYM)); 828 mode_ifm |= IFM_ETH_RXPAUSE; 829 ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL); 830 831 /* Symmetric */ 832 mode_cap_mask &= ~(1 << EFX_PHY_CAP_ASYM); 833 mode_ifm |= IFM_ETH_TXPAUSE; 834 #else /* !SFXGE_HAVE_PAUSE_MEDIAOPTS */ 835 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE); 836 #endif 837 ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL); 838 839 /* Link modes are numbered in order of speed, 840 * so assume the last one available is the best. 841 */ 842 best_mode_ifm = mode_ifm; 843 } 844 } 845 846 if (cap_mask & (1 << EFX_PHY_CAP_AN)) { 847 /* Add autoselect mode. */ 848 mode_ifm = IFM_ETHER | IFM_AUTO; 849 ifmedia_add(&sc->media, mode_ifm, 850 cap_mask & ~(1 << EFX_PHY_CAP_ASYM), NULL); 851 best_mode_ifm = mode_ifm; 852 } 853 854 if (best_mode_ifm != 0) 855 ifmedia_set(&sc->media, best_mode_ifm); 856 857 /* Now discard port state until interface is started. */ 858 efx_port_fini(sc->enp); 859 out2: 860 efx_nic_fini(sc->enp); 861 out: 862 return (rc); 863 } 864