1/*- 2 * Copyright (c) 2010-2015 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 are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * The views and conclusions contained in the software and documentation are 30 * those of the authors and should not be interpreted as representing official 31 * policies, either expressed or implied, of the FreeBSD Project. 32 */ 33 34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD: releng/10.3/sys/dev/sfxge/sfxge_port.c 292089 2015-12-11 06:41:01Z arybchik $"); 36 37#include <sys/types.h> 38#include <sys/limits.h> 39#include <net/ethernet.h> 40#include <net/if_dl.h> 41 42#include "common/efx.h" 43 44#include "sfxge.h" 45 46static int sfxge_phy_cap_mask(struct sfxge_softc *, int, uint32_t *); 47 48static int 49sfxge_mac_stat_update(struct sfxge_softc *sc) 50{ 51 struct sfxge_port *port = &sc->port; 52 efsys_mem_t *esmp = &(port->mac_stats.dma_buf); 53 clock_t now; 54 unsigned int count; 55 int rc; 56 57 SFXGE_PORT_LOCK_ASSERT_OWNED(port); 58 59 if (__predict_false(port->init_state != SFXGE_PORT_STARTED)) { 60 rc = 0; 61 goto out; 62 } 63 64 now = ticks; 65 if (now - port->mac_stats.update_time < hz) { 66 rc = 0; 67 goto out; 68 } 69 70 port->mac_stats.update_time = now; 71 72 /* If we're unlucky enough to read statistics wduring the DMA, wait 73 * up to 10ms for it to finish (typically takes <500us) */ 74 for (count = 0; count < 100; ++count) { 75 EFSYS_PROBE1(wait, unsigned int, count); 76 77 /* Try to update the cached counters */ 78 if ((rc = efx_mac_stats_update(sc->enp, esmp, 79 port->mac_stats.decode_buf, NULL)) != EAGAIN) 80 goto out; 81 82 DELAY(100); 83 } 84 85 rc = ETIMEDOUT; 86out: 87 return (rc); 88} 89 90void 91sfxge_port_update_stats(struct sfxge_softc *sc) 92{ 93 struct ifnet *ifp; 94 uint64_t *mac_stats; 95 96 SFXGE_PORT_LOCK(&sc->port); 97 98 /* Ignore error and use old values */ 99 (void)sfxge_mac_stat_update(sc); 100 101 ifp = sc->ifnet; 102 mac_stats = (uint64_t *)sc->port.mac_stats.decode_buf; 103 104 ifp->if_ipackets = mac_stats[EFX_MAC_RX_PKTS]; 105 ifp->if_ierrors = mac_stats[EFX_MAC_RX_ERRORS]; 106 ifp->if_opackets = mac_stats[EFX_MAC_TX_PKTS]; 107 ifp->if_oerrors = mac_stats[EFX_MAC_TX_ERRORS]; 108 ifp->if_collisions = 109 mac_stats[EFX_MAC_TX_SGL_COL_PKTS] + 110 mac_stats[EFX_MAC_TX_MULT_COL_PKTS] + 111 mac_stats[EFX_MAC_TX_EX_COL_PKTS] + 112 mac_stats[EFX_MAC_TX_LATE_COL_PKTS]; 113 ifp->if_ibytes = mac_stats[EFX_MAC_RX_OCTETS]; 114 ifp->if_obytes = mac_stats[EFX_MAC_TX_OCTETS]; 115 /* if_imcasts is maintained in net/if_ethersubr.c */ 116 ifp->if_omcasts = 117 mac_stats[EFX_MAC_TX_MULTICST_PKTS] + 118 mac_stats[EFX_MAC_TX_BRDCST_PKTS]; 119 /* if_iqdrops is maintained in net/if_ethersubr.c */ 120 /* if_noproto is maintained in net/if_ethersubr.c */ 121 122 SFXGE_PORT_UNLOCK(&sc->port); 123} 124 125static int 126sfxge_mac_stat_handler(SYSCTL_HANDLER_ARGS) 127{ 128 struct sfxge_softc *sc = arg1; 129 unsigned int id = arg2; 130 int rc; 131 uint64_t val; 132 133 SFXGE_PORT_LOCK(&sc->port); 134 if ((rc = sfxge_mac_stat_update(sc)) == 0) 135 val = ((uint64_t *)sc->port.mac_stats.decode_buf)[id]; 136 SFXGE_PORT_UNLOCK(&sc->port); 137 138 if (rc == 0) 139 rc = SYSCTL_OUT(req, &val, sizeof(val)); 140 return (rc); 141} 142 143static void 144sfxge_mac_stat_init(struct sfxge_softc *sc) 145{ 146 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); 147 struct sysctl_oid_list *stat_list; 148 unsigned int id; 149 const char *name; 150 151 stat_list = SYSCTL_CHILDREN(sc->stats_node); 152 153 /* Initialise the named stats */ 154 for (id = 0; id < EFX_MAC_NSTATS; id++) { 155 name = efx_mac_stat_name(sc->enp, id); 156 SYSCTL_ADD_PROC( 157 ctx, stat_list, 158 OID_AUTO, name, CTLTYPE_U64|CTLFLAG_RD, 159 sc, id, sfxge_mac_stat_handler, "Q", 160 ""); 161 } 162} 163 164#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS 165 166static unsigned int 167sfxge_port_wanted_fc(struct sfxge_softc *sc) 168{ 169 struct ifmedia_entry *ifm = sc->media.ifm_cur; 170 171 if (ifm->ifm_media == (IFM_ETHER | IFM_AUTO)) 172 return (EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE); 173 return (((ifm->ifm_media & IFM_ETH_RXPAUSE) ? EFX_FCNTL_RESPOND : 0) | 174 ((ifm->ifm_media & IFM_ETH_TXPAUSE) ? EFX_FCNTL_GENERATE : 0)); 175} 176 177static unsigned int 178sfxge_port_link_fc_ifm(struct sfxge_softc *sc) 179{ 180 unsigned int wanted_fc, link_fc; 181 182 efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc); 183 return ((link_fc & EFX_FCNTL_RESPOND) ? IFM_ETH_RXPAUSE : 0) | 184 ((link_fc & EFX_FCNTL_GENERATE) ? IFM_ETH_TXPAUSE : 0); 185} 186 187#else /* !SFXGE_HAVE_PAUSE_MEDIAOPTS */ 188 189static unsigned int 190sfxge_port_wanted_fc(struct sfxge_softc *sc) 191{ 192 return (sc->port.wanted_fc); 193} 194 195static unsigned int 196sfxge_port_link_fc_ifm(struct sfxge_softc *sc) 197{ 198 return (0); 199} 200 201static int 202sfxge_port_wanted_fc_handler(SYSCTL_HANDLER_ARGS) 203{ 204 struct sfxge_softc *sc; 205 struct sfxge_port *port; 206 unsigned int fcntl; 207 int error; 208 209 sc = arg1; 210 port = &sc->port; 211 212 if (req->newptr != NULL) { 213 if ((error = SYSCTL_IN(req, &fcntl, sizeof(fcntl))) != 0) 214 return (error); 215 216 SFXGE_PORT_LOCK(port); 217 218 if (port->wanted_fc != fcntl) { 219 if (port->init_state == SFXGE_PORT_STARTED) 220 error = efx_mac_fcntl_set(sc->enp, 221 port->wanted_fc, 222 B_TRUE); 223 if (error == 0) 224 port->wanted_fc = fcntl; 225 } 226 227 SFXGE_PORT_UNLOCK(port); 228 } else { 229 SFXGE_PORT_LOCK(port); 230 fcntl = port->wanted_fc; 231 SFXGE_PORT_UNLOCK(port); 232 233 error = SYSCTL_OUT(req, &fcntl, sizeof(fcntl)); 234 } 235 236 return (error); 237} 238 239static int 240sfxge_port_link_fc_handler(SYSCTL_HANDLER_ARGS) 241{ 242 struct sfxge_softc *sc; 243 struct sfxge_port *port; 244 unsigned int wanted_fc, link_fc; 245 246 sc = arg1; 247 port = &sc->port; 248 249 SFXGE_PORT_LOCK(port); 250 if (__predict_true(port->init_state == SFXGE_PORT_STARTED) && 251 SFXGE_LINK_UP(sc)) 252 efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc); 253 else 254 link_fc = 0; 255 SFXGE_PORT_UNLOCK(port); 256 257 return (SYSCTL_OUT(req, &link_fc, sizeof(link_fc))); 258} 259 260#endif /* SFXGE_HAVE_PAUSE_MEDIAOPTS */ 261 262static const uint64_t sfxge_link_baudrate[EFX_LINK_NMODES] = { 263 [EFX_LINK_10HDX] = IF_Mbps(10), 264 [EFX_LINK_10FDX] = IF_Mbps(10), 265 [EFX_LINK_100HDX] = IF_Mbps(100), 266 [EFX_LINK_100FDX] = IF_Mbps(100), 267 [EFX_LINK_1000HDX] = IF_Gbps(1), 268 [EFX_LINK_1000FDX] = IF_Gbps(1), 269 [EFX_LINK_10000FDX] = IF_Gbps(10), 270 [EFX_LINK_40000FDX] = IF_Gbps(40), 271}; 272 273void 274sfxge_mac_link_update(struct sfxge_softc *sc, efx_link_mode_t mode) 275{ 276 struct sfxge_port *port; 277 int link_state; 278 279 port = &sc->port; 280 281 if (port->link_mode == mode) 282 return; 283 284 port->link_mode = mode; 285 286 /* Push link state update to the OS */ 287 link_state = (port->link_mode != EFX_LINK_DOWN ? 288 LINK_STATE_UP : LINK_STATE_DOWN); 289 if_initbaudrate(sc->ifnet, sfxge_link_baudrate[port->link_mode]); 290 if_link_state_change(sc->ifnet, link_state); 291} 292 293static void 294sfxge_mac_poll_work(void *arg, int npending) 295{ 296 struct sfxge_softc *sc; 297 efx_nic_t *enp; 298 struct sfxge_port *port; 299 efx_link_mode_t mode; 300 301 sc = (struct sfxge_softc *)arg; 302 enp = sc->enp; 303 port = &sc->port; 304 305 SFXGE_PORT_LOCK(port); 306 307 if (__predict_false(port->init_state != SFXGE_PORT_STARTED)) 308 goto done; 309 310 /* This may sleep waiting for MCDI completion */ 311 (void)efx_port_poll(enp, &mode); 312 sfxge_mac_link_update(sc, mode); 313 314done: 315 SFXGE_PORT_UNLOCK(port); 316} 317 318static int 319sfxge_mac_multicast_list_set(struct sfxge_softc *sc) 320{ 321 struct ifnet *ifp = sc->ifnet; 322 struct sfxge_port *port = &sc->port; 323 uint8_t *mcast_addr = port->mcast_addrs; 324 struct ifmultiaddr *ifma; 325 struct sockaddr_dl *sa; 326 int rc = 0; 327 328 mtx_assert(&port->lock, MA_OWNED); 329 330 port->mcast_count = 0; 331 if_maddr_rlock(ifp); 332 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 333 if (ifma->ifma_addr->sa_family == AF_LINK) { 334 if (port->mcast_count == EFX_MAC_MULTICAST_LIST_MAX) { 335 device_printf(sc->dev, 336 "Too many multicast addresses\n"); 337 rc = EINVAL; 338 break; 339 } 340 341 sa = (struct sockaddr_dl *)ifma->ifma_addr; 342 memcpy(mcast_addr, LLADDR(sa), EFX_MAC_ADDR_LEN); 343 mcast_addr += EFX_MAC_ADDR_LEN; 344 ++port->mcast_count; 345 } 346 } 347 if_maddr_runlock(ifp); 348 349 if (rc == 0) { 350 rc = efx_mac_multicast_list_set(sc->enp, port->mcast_addrs, 351 port->mcast_count); 352 if (rc != 0) 353 device_printf(sc->dev, 354 "Cannot set multicast address list\n"); 355 } 356 357 return (rc); 358} 359 360static int 361sfxge_mac_filter_set_locked(struct sfxge_softc *sc) 362{ 363 struct ifnet *ifp = sc->ifnet; 364 struct sfxge_port *port = &sc->port; 365 boolean_t all_mulcst; 366 int rc; 367 368 mtx_assert(&port->lock, MA_OWNED); 369 370 all_mulcst = !!(ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)); 371 372 rc = sfxge_mac_multicast_list_set(sc); 373 /* Fallback to all multicast if cannot set multicast list */ 374 if (rc != 0) 375 all_mulcst = B_TRUE; 376 377 rc = efx_mac_filter_set(sc->enp, !!(ifp->if_flags & IFF_PROMISC), 378 (port->mcast_count > 0), all_mulcst, B_TRUE); 379 380 return (rc); 381} 382 383int 384sfxge_mac_filter_set(struct sfxge_softc *sc) 385{ 386 struct sfxge_port *port = &sc->port; 387 int rc; 388 389 SFXGE_PORT_LOCK(port); 390 /* 391 * The function may be called without softc_lock held in the 392 * case of SIOCADDMULTI and SIOCDELMULTI ioctls. ioctl handler 393 * checks IFF_DRV_RUNNING flag which implies port started, but 394 * it is not guaranteed to remain. softc_lock shared lock can't 395 * be held in the case of these ioctls processing, since it 396 * results in failure where kernel complains that non-sleepable 397 * lock is held in sleeping thread. Both problems are repeatable 398 * on LAG with LACP proto bring up. 399 */ 400 if (__predict_true(port->init_state == SFXGE_PORT_STARTED)) 401 rc = sfxge_mac_filter_set_locked(sc); 402 else 403 rc = 0; 404 SFXGE_PORT_UNLOCK(port); 405 return (rc); 406} 407 408void 409sfxge_port_stop(struct sfxge_softc *sc) 410{ 411 struct sfxge_port *port; 412 efx_nic_t *enp; 413 414 port = &sc->port; 415 enp = sc->enp; 416 417 SFXGE_PORT_LOCK(port); 418 419 KASSERT(port->init_state == SFXGE_PORT_STARTED, 420 ("port not started")); 421 422 port->init_state = SFXGE_PORT_INITIALIZED; 423 424 port->mac_stats.update_time = 0; 425 426 /* This may call MCDI */ 427 (void)efx_mac_drain(enp, B_TRUE); 428 429 (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE); 430 431 port->link_mode = EFX_LINK_UNKNOWN; 432 433 /* Destroy the common code port object. */ 434 efx_port_fini(enp); 435 436 efx_filter_fini(enp); 437 438 SFXGE_PORT_UNLOCK(port); 439} 440 441int 442sfxge_port_start(struct sfxge_softc *sc) 443{ 444 uint8_t mac_addr[ETHER_ADDR_LEN]; 445 struct ifnet *ifp = sc->ifnet; 446 struct sfxge_port *port; 447 efx_nic_t *enp; 448 size_t pdu; 449 int rc; 450 uint32_t phy_cap_mask; 451 452 port = &sc->port; 453 enp = sc->enp; 454 455 SFXGE_PORT_LOCK(port); 456 457 KASSERT(port->init_state == SFXGE_PORT_INITIALIZED, 458 ("port not initialized")); 459 460 /* Initialise the required filtering */ 461 if ((rc = efx_filter_init(enp)) != 0) 462 goto fail_filter_init; 463 464 /* Initialize the port object in the common code. */ 465 if ((rc = efx_port_init(sc->enp)) != 0) 466 goto fail; 467 468 /* Set the SDU */ 469 pdu = EFX_MAC_PDU(ifp->if_mtu); 470 if ((rc = efx_mac_pdu_set(enp, pdu)) != 0) 471 goto fail2; 472 473 if ((rc = efx_mac_fcntl_set(enp, sfxge_port_wanted_fc(sc), B_TRUE)) 474 != 0) 475 goto fail3; 476 477 /* Set the unicast address */ 478 if_addr_rlock(ifp); 479 bcopy(LLADDR((struct sockaddr_dl *)ifp->if_addr->ifa_addr), 480 mac_addr, sizeof(mac_addr)); 481 if_addr_runlock(ifp); 482 if ((rc = efx_mac_addr_set(enp, mac_addr)) != 0) 483 goto fail4; 484 485 sfxge_mac_filter_set_locked(sc); 486 487 /* Update MAC stats by DMA every second */ 488 if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 489 1000, B_FALSE)) != 0) 490 goto fail6; 491 492 if ((rc = efx_mac_drain(enp, B_FALSE)) != 0) 493 goto fail8; 494 495 if ((rc = sfxge_phy_cap_mask(sc, sc->media.ifm_cur->ifm_media, 496 &phy_cap_mask)) != 0) 497 goto fail9; 498 499 if ((rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask)) != 0) 500 goto fail10; 501 502 port->init_state = SFXGE_PORT_STARTED; 503 504 /* Single poll in case there were missing initial events */ 505 SFXGE_PORT_UNLOCK(port); 506 sfxge_mac_poll_work(sc, 0); 507 508 return (0); 509 510fail10: 511fail9: 512 (void)efx_mac_drain(enp, B_TRUE); 513fail8: 514 (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE); 515fail6: 516fail4: 517fail3: 518 519fail2: 520 efx_port_fini(enp); 521fail: 522 efx_filter_fini(enp); 523fail_filter_init: 524 SFXGE_PORT_UNLOCK(port); 525 526 return (rc); 527} 528 529static int 530sfxge_phy_stat_update(struct sfxge_softc *sc) 531{ 532 struct sfxge_port *port = &sc->port; 533 efsys_mem_t *esmp = &port->phy_stats.dma_buf; 534 clock_t now; 535 unsigned int count; 536 int rc; 537 538 SFXGE_PORT_LOCK_ASSERT_OWNED(port); 539 540 if (__predict_false(port->init_state != SFXGE_PORT_STARTED)) { 541 rc = 0; 542 goto out; 543 } 544 545 now = ticks; 546 if (now - port->phy_stats.update_time < hz) { 547 rc = 0; 548 goto out; 549 } 550 551 port->phy_stats.update_time = now; 552 553 /* If we're unlucky enough to read statistics wduring the DMA, wait 554 * up to 10ms for it to finish (typically takes <500us) */ 555 for (count = 0; count < 100; ++count) { 556 EFSYS_PROBE1(wait, unsigned int, count); 557 558 /* Synchronize the DMA memory for reading */ 559 bus_dmamap_sync(esmp->esm_tag, esmp->esm_map, 560 BUS_DMASYNC_POSTREAD); 561 562 /* Try to update the cached counters */ 563 if ((rc = efx_phy_stats_update(sc->enp, esmp, 564 port->phy_stats.decode_buf)) != EAGAIN) 565 goto out; 566 567 DELAY(100); 568 } 569 570 rc = ETIMEDOUT; 571out: 572 return (rc); 573} 574 575static int 576sfxge_phy_stat_handler(SYSCTL_HANDLER_ARGS) 577{ 578 struct sfxge_softc *sc = arg1; 579 unsigned int id = arg2; 580 int rc; 581 uint32_t val; 582 583 SFXGE_PORT_LOCK(&sc->port); 584 if ((rc = sfxge_phy_stat_update(sc)) == 0) 585 val = ((uint32_t *)sc->port.phy_stats.decode_buf)[id]; 586 SFXGE_PORT_UNLOCK(&sc->port); 587 588 if (rc == 0) 589 rc = SYSCTL_OUT(req, &val, sizeof(val)); 590 return (rc); 591} 592 593static void 594sfxge_phy_stat_init(struct sfxge_softc *sc) 595{ 596 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); 597 struct sysctl_oid_list *stat_list; 598 unsigned int id; 599 const char *name; 600 uint64_t stat_mask = efx_nic_cfg_get(sc->enp)->enc_phy_stat_mask; 601 602 stat_list = SYSCTL_CHILDREN(sc->stats_node); 603 604 /* Initialise the named stats */ 605 for (id = 0; id < EFX_PHY_NSTATS; id++) { 606 if (!(stat_mask & ((uint64_t)1 << id))) 607 continue; 608 name = efx_phy_stat_name(sc->enp, id); 609 SYSCTL_ADD_PROC( 610 ctx, stat_list, 611 OID_AUTO, name, CTLTYPE_UINT|CTLFLAG_RD, 612 sc, id, sfxge_phy_stat_handler, 613 id == EFX_PHY_STAT_OUI ? "IX" : "IU", 614 ""); 615 } 616} 617 618void 619sfxge_port_fini(struct sfxge_softc *sc) 620{ 621 struct sfxge_port *port; 622 efsys_mem_t *esmp; 623 624 port = &sc->port; 625 esmp = &port->mac_stats.dma_buf; 626 627 KASSERT(port->init_state == SFXGE_PORT_INITIALIZED, 628 ("Port not initialized")); 629 630 port->init_state = SFXGE_PORT_UNINITIALIZED; 631 632 port->link_mode = EFX_LINK_UNKNOWN; 633 634 /* Finish with PHY DMA memory */ 635 sfxge_dma_free(&port->phy_stats.dma_buf); 636 free(port->phy_stats.decode_buf, M_SFXGE); 637 638 sfxge_dma_free(esmp); 639 free(port->mac_stats.decode_buf, M_SFXGE); 640 641 SFXGE_PORT_LOCK_DESTROY(port); 642 643 port->sc = NULL; 644} 645 646int 647sfxge_port_init(struct sfxge_softc *sc) 648{ 649 struct sfxge_port *port; 650 struct sysctl_ctx_list *sysctl_ctx; 651 struct sysctl_oid *sysctl_tree; 652 efsys_mem_t *mac_stats_buf, *phy_stats_buf; 653 int rc; 654 655 port = &sc->port; 656 mac_stats_buf = &port->mac_stats.dma_buf; 657 phy_stats_buf = &port->phy_stats.dma_buf; 658 659 KASSERT(port->init_state == SFXGE_PORT_UNINITIALIZED, 660 ("Port already initialized")); 661 662 port->sc = sc; 663 664 SFXGE_PORT_LOCK_INIT(port, device_get_nameunit(sc->dev)); 665 666 DBGPRINT(sc->dev, "alloc PHY stats"); 667 port->phy_stats.decode_buf = malloc(EFX_PHY_NSTATS * sizeof(uint32_t), 668 M_SFXGE, M_WAITOK | M_ZERO); 669 if ((rc = sfxge_dma_alloc(sc, EFX_PHY_STATS_SIZE, phy_stats_buf)) != 0) 670 goto fail; 671 sfxge_phy_stat_init(sc); 672 673 DBGPRINT(sc->dev, "init sysctl"); 674 sysctl_ctx = device_get_sysctl_ctx(sc->dev); 675 sysctl_tree = device_get_sysctl_tree(sc->dev); 676 677#ifndef SFXGE_HAVE_PAUSE_MEDIAOPTS 678 /* If flow control cannot be configured or reported through 679 * ifmedia, provide sysctls for it. */ 680 port->wanted_fc = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE; 681 SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, 682 "wanted_fc", CTLTYPE_UINT|CTLFLAG_RW, sc, 0, 683 sfxge_port_wanted_fc_handler, "IU", "wanted flow control mode"); 684 SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, 685 "link_fc", CTLTYPE_UINT|CTLFLAG_RD, sc, 0, 686 sfxge_port_link_fc_handler, "IU", "link flow control mode"); 687#endif 688 689 DBGPRINT(sc->dev, "alloc MAC stats"); 690 port->mac_stats.decode_buf = malloc(EFX_MAC_NSTATS * sizeof(uint64_t), 691 M_SFXGE, M_WAITOK | M_ZERO); 692 if ((rc = sfxge_dma_alloc(sc, EFX_MAC_STATS_SIZE, mac_stats_buf)) != 0) 693 goto fail2; 694 sfxge_mac_stat_init(sc); 695 696 port->init_state = SFXGE_PORT_INITIALIZED; 697 698 DBGPRINT(sc->dev, "success"); 699 return (0); 700 701fail2: 702 free(port->mac_stats.decode_buf, M_SFXGE); 703 sfxge_dma_free(phy_stats_buf); 704fail: 705 free(port->phy_stats.decode_buf, M_SFXGE); 706 SFXGE_PORT_LOCK_DESTROY(port); 707 port->sc = NULL; 708 DBGPRINT(sc->dev, "failed %d", rc); 709 return (rc); 710} 711 712static const int sfxge_link_mode[EFX_PHY_MEDIA_NTYPES][EFX_LINK_NMODES] = { 713 [EFX_PHY_MEDIA_CX4] = { 714 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_CX4, 715 }, 716 [EFX_PHY_MEDIA_KX4] = { 717 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_KX4, 718 }, 719 [EFX_PHY_MEDIA_XFP] = { 720 /* Don't know the module type, but assume SR for now. */ 721 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR, 722 }, 723 [EFX_PHY_MEDIA_QSFP_PLUS] = { 724 /* Don't know the module type, but assume SR for now. */ 725 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR, 726 [EFX_LINK_40000FDX] = IFM_ETHER | IFM_FDX | IFM_40G_CR4, 727 }, 728 [EFX_PHY_MEDIA_SFP_PLUS] = { 729 /* Don't know the module type, but assume SX/SR for now. */ 730 [EFX_LINK_1000FDX] = IFM_ETHER | IFM_FDX | IFM_1000_SX, 731 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR, 732 }, 733 [EFX_PHY_MEDIA_BASE_T] = { 734 [EFX_LINK_10HDX] = IFM_ETHER | IFM_HDX | IFM_10_T, 735 [EFX_LINK_10FDX] = IFM_ETHER | IFM_FDX | IFM_10_T, 736 [EFX_LINK_100HDX] = IFM_ETHER | IFM_HDX | IFM_100_TX, 737 [EFX_LINK_100FDX] = IFM_ETHER | IFM_FDX | IFM_100_TX, 738 [EFX_LINK_1000HDX] = IFM_ETHER | IFM_HDX | IFM_1000_T, 739 [EFX_LINK_1000FDX] = IFM_ETHER | IFM_FDX | IFM_1000_T, 740 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_T, 741 }, 742}; 743 744static void 745sfxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) 746{ 747 struct sfxge_softc *sc; 748 efx_phy_media_type_t medium_type; 749 efx_link_mode_t mode; 750 751 sc = ifp->if_softc; 752 SFXGE_ADAPTER_LOCK(sc); 753 754 ifmr->ifm_status = IFM_AVALID; 755 ifmr->ifm_active = IFM_ETHER; 756 757 if (SFXGE_RUNNING(sc) && SFXGE_LINK_UP(sc)) { 758 ifmr->ifm_status |= IFM_ACTIVE; 759 760 efx_phy_media_type_get(sc->enp, &medium_type); 761 mode = sc->port.link_mode; 762 ifmr->ifm_active |= sfxge_link_mode[medium_type][mode]; 763 ifmr->ifm_active |= sfxge_port_link_fc_ifm(sc); 764 } 765 766 SFXGE_ADAPTER_UNLOCK(sc); 767} 768 769static efx_phy_cap_type_t 770sfxge_link_mode_to_phy_cap(efx_link_mode_t mode) 771{ 772 switch (mode) { 773 case EFX_LINK_10HDX: 774 return (EFX_PHY_CAP_10HDX); 775 case EFX_LINK_10FDX: 776 return (EFX_PHY_CAP_10FDX); 777 case EFX_LINK_100HDX: 778 return (EFX_PHY_CAP_100HDX); 779 case EFX_LINK_100FDX: 780 return (EFX_PHY_CAP_100FDX); 781 case EFX_LINK_1000HDX: 782 return (EFX_PHY_CAP_1000HDX); 783 case EFX_LINK_1000FDX: 784 return (EFX_PHY_CAP_1000FDX); 785 case EFX_LINK_10000FDX: 786 return (EFX_PHY_CAP_10000FDX); 787 case EFX_LINK_40000FDX: 788 return (EFX_PHY_CAP_40000FDX); 789 default: 790 EFSYS_ASSERT(B_FALSE); 791 return (EFX_PHY_CAP_INVALID); 792 } 793} 794 795static int 796sfxge_phy_cap_mask(struct sfxge_softc *sc, int ifmedia, uint32_t *phy_cap_mask) 797{ 798 /* Get global options (duplex), type and subtype bits */ 799 int ifmedia_masked = ifmedia & (IFM_GMASK | IFM_NMASK | IFM_TMASK); 800 efx_phy_media_type_t medium_type; 801 boolean_t mode_found = B_FALSE; 802 uint32_t cap_mask, mode_cap_mask; 803 efx_link_mode_t mode; 804 efx_phy_cap_type_t phy_cap; 805 806 efx_phy_media_type_get(sc->enp, &medium_type); 807 if (medium_type >= nitems(sfxge_link_mode)) { 808 if_printf(sc->ifnet, "unexpected media type %d\n", medium_type); 809 return (EINVAL); 810 } 811 812 efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask); 813 814 for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) { 815 if (ifmedia_masked == sfxge_link_mode[medium_type][mode]) { 816 mode_found = B_TRUE; 817 break; 818 } 819 } 820 821 if (!mode_found) { 822 /* 823 * If media is not in the table, it must be IFM_AUTO. 824 */ 825 KASSERT((cap_mask & (1 << EFX_PHY_CAP_AN)) && 826 ifmedia_masked == (IFM_ETHER | IFM_AUTO), 827 ("%s: no mode for media %#x", __func__, ifmedia)); 828 *phy_cap_mask = (cap_mask & ~(1 << EFX_PHY_CAP_ASYM)); 829 return (0); 830 } 831 832 phy_cap = sfxge_link_mode_to_phy_cap(mode); 833 if (phy_cap == EFX_PHY_CAP_INVALID) { 834 if_printf(sc->ifnet, 835 "cannot map link mode %d to phy capability\n", 836 mode); 837 return (EINVAL); 838 } 839 840 mode_cap_mask = (1 << phy_cap); 841 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_AN); 842#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS 843 if (ifmedia & IFM_ETH_RXPAUSE) 844 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE); 845 if (!(ifmedia & IFM_ETH_TXPAUSE)) 846 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_ASYM); 847#else 848 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE); 849#endif 850 851 *phy_cap_mask = mode_cap_mask; 852 return (0); 853} 854 855static int 856sfxge_media_change(struct ifnet *ifp) 857{ 858 struct sfxge_softc *sc; 859 struct ifmedia_entry *ifm; 860 int rc; 861 uint32_t phy_cap_mask; 862 863 sc = ifp->if_softc; 864 ifm = sc->media.ifm_cur; 865 866 SFXGE_ADAPTER_LOCK(sc); 867 868 if (!SFXGE_RUNNING(sc)) { 869 rc = 0; 870 goto out; 871 } 872 873 rc = efx_mac_fcntl_set(sc->enp, sfxge_port_wanted_fc(sc), B_TRUE); 874 if (rc != 0) 875 goto out; 876 877 if ((rc = sfxge_phy_cap_mask(sc, ifm->ifm_media, &phy_cap_mask)) != 0) 878 goto out; 879 880 rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask); 881out: 882 SFXGE_ADAPTER_UNLOCK(sc); 883 884 return (rc); 885} 886 887int sfxge_port_ifmedia_init(struct sfxge_softc *sc) 888{ 889 efx_phy_media_type_t medium_type; 890 uint32_t cap_mask, mode_cap_mask; 891 efx_link_mode_t mode; 892 efx_phy_cap_type_t phy_cap; 893 int mode_ifm, best_mode_ifm = 0; 894 int rc; 895 896 /* 897 * We need port state to initialise the ifmedia list. 898 * It requires initialized NIC what is already done in 899 * sfxge_create() when resources are estimated. 900 */ 901 if ((rc = efx_filter_init(sc->enp)) != 0) 902 goto out1; 903 if ((rc = efx_port_init(sc->enp)) != 0) 904 goto out2; 905 906 /* 907 * Register ifconfig callbacks for querying and setting the 908 * link mode and link status. 909 */ 910 ifmedia_init(&sc->media, IFM_IMASK, sfxge_media_change, 911 sfxge_media_status); 912 913 /* 914 * Map firmware medium type and capabilities to ifmedia types. 915 * ifmedia does not distinguish between forcing the link mode 916 * and disabling auto-negotiation. 1000BASE-T and 10GBASE-T 917 * require AN even if only one link mode is enabled, and for 918 * 100BASE-TX it is useful even if the link mode is forced. 919 * Therefore we never disable auto-negotiation. 920 * 921 * Also enable and advertise flow control by default. 922 */ 923 924 efx_phy_media_type_get(sc->enp, &medium_type); 925 efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask); 926 927 for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) { 928 phy_cap = sfxge_link_mode_to_phy_cap(mode); 929 if (phy_cap == EFX_PHY_CAP_INVALID) 930 continue; 931 932 mode_cap_mask = (1 << phy_cap); 933 mode_ifm = sfxge_link_mode[medium_type][mode]; 934 935 if ((cap_mask & mode_cap_mask) && mode_ifm) { 936 /* No flow-control */ 937 ifmedia_add(&sc->media, mode_ifm, 0, NULL); 938 939#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS 940 /* Respond-only. If using AN, we implicitly 941 * offer symmetric as well, but that doesn't 942 * mean we *have* to generate pause frames. 943 */ 944 mode_ifm |= IFM_ETH_RXPAUSE; 945 ifmedia_add(&sc->media, mode_ifm, 0, NULL); 946 947 /* Symmetric */ 948 mode_ifm |= IFM_ETH_TXPAUSE; 949 ifmedia_add(&sc->media, mode_ifm, 0, NULL); 950#endif 951 952 /* Link modes are numbered in order of speed, 953 * so assume the last one available is the best. 954 */ 955 best_mode_ifm = mode_ifm; 956 } 957 } 958 959 if (cap_mask & (1 << EFX_PHY_CAP_AN)) { 960 /* Add autoselect mode. */ 961 mode_ifm = IFM_ETHER | IFM_AUTO; 962 ifmedia_add(&sc->media, mode_ifm, 0, NULL); 963 best_mode_ifm = mode_ifm; 964 } 965 966 if (best_mode_ifm != 0) 967 ifmedia_set(&sc->media, best_mode_ifm); 968 969 /* Now discard port state until interface is started. */ 970 efx_port_fini(sc->enp); 971out2: 972 efx_filter_fini(sc->enp); 973out1: 974 return (rc); 975} 976