2 * Copyright (c) 2010-2011 Solarflare Communications, Inc.
5 * This software was developed in part by Philip Paeps under contract for
6 * Solarflare Communications, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/types.h>
34 #include <sys/limits.h>
35 #include <net/ethernet.h>
36 #include <net/if_dl.h>
38 #include "common/efx.h"
42 static int sfxge_phy_cap_mask(struct sfxge_softc *, int, uint32_t *);
45 sfxge_mac_stat_update(struct sfxge_softc *sc)
47 struct sfxge_port *port = &sc->port;
48 efsys_mem_t *esmp = &(port->mac_stats.dma_buf);
53 SFXGE_PORT_LOCK_ASSERT_OWNED(port);
55 if (__predict_false(port->init_state != SFXGE_PORT_STARTED)) {
61 if (now - port->mac_stats.update_time < hz) {
66 port->mac_stats.update_time = now;
68 /* If we're unlucky enough to read statistics wduring the DMA, wait
69 * up to 10ms for it to finish (typically takes <500us) */
70 for (count = 0; count < 100; ++count) {
71 EFSYS_PROBE1(wait, unsigned int, count);
73 /* Synchronize the DMA memory for reading */
74 bus_dmamap_sync(esmp->esm_tag, esmp->esm_map,
75 BUS_DMASYNC_POSTREAD);
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)
91 sfxge_get_counter(struct ifnet *ifp, ift_counter c)
93 struct sfxge_softc *sc = ifp->if_softc;
97 SFXGE_PORT_LOCK(&sc->port);
99 /* Ignore error and use old values */
100 (void)sfxge_mac_stat_update(sc);
102 mac_stats = (uint64_t *)sc->port.mac_stats.decode_buf;
105 case IFCOUNTER_IPACKETS:
106 val = mac_stats[EFX_MAC_RX_PKTS];
108 case IFCOUNTER_IERRORS:
109 val = mac_stats[EFX_MAC_RX_ERRORS];
111 case IFCOUNTER_OPACKETS:
112 val = mac_stats[EFX_MAC_TX_PKTS];
114 case IFCOUNTER_OERRORS:
115 val = mac_stats[EFX_MAC_TX_ERRORS];
117 case IFCOUNTER_COLLISIONS:
118 val = mac_stats[EFX_MAC_TX_SGL_COL_PKTS] +
119 mac_stats[EFX_MAC_TX_MULT_COL_PKTS] +
120 mac_stats[EFX_MAC_TX_EX_COL_PKTS] +
121 mac_stats[EFX_MAC_TX_LATE_COL_PKTS];
123 case IFCOUNTER_IBYTES:
124 val = mac_stats[EFX_MAC_RX_OCTETS];
126 case IFCOUNTER_OBYTES:
127 val = mac_stats[EFX_MAC_TX_OCTETS];
129 case IFCOUNTER_OMCASTS:
130 val = mac_stats[EFX_MAC_TX_MULTICST_PKTS] +
131 mac_stats[EFX_MAC_TX_BRDCST_PKTS];
133 case IFCOUNTER_OQDROPS:
134 SFXGE_PORT_UNLOCK(&sc->port);
135 return (sfxge_tx_get_drops(sc));
136 case IFCOUNTER_IMCASTS:
137 /* if_imcasts is maintained in net/if_ethersubr.c */
138 case IFCOUNTER_IQDROPS:
139 /* if_iqdrops is maintained in net/if_ethersubr.c */
140 case IFCOUNTER_NOPROTO:
141 /* if_noproto is maintained in net/if_ethersubr.c */
143 SFXGE_PORT_UNLOCK(&sc->port);
144 return (if_get_counter_default(ifp, c));
147 SFXGE_PORT_UNLOCK(&sc->port);
153 sfxge_mac_stat_handler(SYSCTL_HANDLER_ARGS)
155 struct sfxge_softc *sc = arg1;
156 unsigned int id = arg2;
160 SFXGE_PORT_LOCK(&sc->port);
161 if ((rc = sfxge_mac_stat_update(sc)) == 0)
162 val = ((uint64_t *)sc->port.mac_stats.decode_buf)[id];
163 SFXGE_PORT_UNLOCK(&sc->port);
166 rc = SYSCTL_OUT(req, &val, sizeof(val));
171 sfxge_mac_stat_init(struct sfxge_softc *sc)
173 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
174 struct sysctl_oid_list *stat_list;
178 stat_list = SYSCTL_CHILDREN(sc->stats_node);
180 /* Initialise the named stats */
181 for (id = 0; id < EFX_MAC_NSTATS; id++) {
182 name = efx_mac_stat_name(sc->enp, id);
185 OID_AUTO, name, CTLTYPE_U64|CTLFLAG_RD,
186 sc, id, sfxge_mac_stat_handler, "Q",
191 #ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
194 sfxge_port_wanted_fc(struct sfxge_softc *sc)
196 struct ifmedia_entry *ifm = sc->media.ifm_cur;
198 if (ifm->ifm_media == (IFM_ETHER | IFM_AUTO))
199 return (EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE);
200 return (((ifm->ifm_media & IFM_ETH_RXPAUSE) ? EFX_FCNTL_RESPOND : 0) |
201 ((ifm->ifm_media & IFM_ETH_TXPAUSE) ? EFX_FCNTL_GENERATE : 0));
205 sfxge_port_link_fc_ifm(struct sfxge_softc *sc)
207 unsigned int wanted_fc, link_fc;
209 efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc);
210 return ((link_fc & EFX_FCNTL_RESPOND) ? IFM_ETH_RXPAUSE : 0) |
211 ((link_fc & EFX_FCNTL_GENERATE) ? IFM_ETH_TXPAUSE : 0);
214 #else /* !SFXGE_HAVE_PAUSE_MEDIAOPTS */
217 sfxge_port_wanted_fc(struct sfxge_softc *sc)
219 return (sc->port.wanted_fc);
223 sfxge_port_link_fc_ifm(struct sfxge_softc *sc)
229 sfxge_port_wanted_fc_handler(SYSCTL_HANDLER_ARGS)
231 struct sfxge_softc *sc;
232 struct sfxge_port *port;
239 if (req->newptr != NULL) {
240 if ((error = SYSCTL_IN(req, &fcntl, sizeof(fcntl))) != 0)
243 SFXGE_PORT_LOCK(port);
245 if (port->wanted_fc != fcntl) {
246 if (port->init_state == SFXGE_PORT_STARTED)
247 error = efx_mac_fcntl_set(sc->enp,
251 port->wanted_fc = fcntl;
254 SFXGE_PORT_UNLOCK(port);
256 SFXGE_PORT_LOCK(port);
257 fcntl = port->wanted_fc;
258 SFXGE_PORT_UNLOCK(port);
260 error = SYSCTL_OUT(req, &fcntl, sizeof(fcntl));
267 sfxge_port_link_fc_handler(SYSCTL_HANDLER_ARGS)
269 struct sfxge_softc *sc;
270 struct sfxge_port *port;
271 unsigned int wanted_fc, link_fc;
276 SFXGE_PORT_LOCK(port);
277 if (__predict_true(port->init_state == SFXGE_PORT_STARTED) &&
279 efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc);
282 SFXGE_PORT_UNLOCK(port);
284 return (SYSCTL_OUT(req, &link_fc, sizeof(link_fc)));
287 #endif /* SFXGE_HAVE_PAUSE_MEDIAOPTS */
289 static const uint64_t sfxge_link_baudrate[EFX_LINK_NMODES] = {
290 [EFX_LINK_10HDX] = IF_Mbps(10),
291 [EFX_LINK_10FDX] = IF_Mbps(10),
292 [EFX_LINK_100HDX] = IF_Mbps(100),
293 [EFX_LINK_100FDX] = IF_Mbps(100),
294 [EFX_LINK_1000HDX] = IF_Gbps(1),
295 [EFX_LINK_1000FDX] = IF_Gbps(1),
296 [EFX_LINK_10000FDX] = IF_Gbps(10),
300 sfxge_mac_link_update(struct sfxge_softc *sc, efx_link_mode_t mode)
302 struct sfxge_port *port;
307 if (port->link_mode == mode)
310 port->link_mode = mode;
312 /* Push link state update to the OS */
313 link_state = (port->link_mode != EFX_LINK_DOWN ?
314 LINK_STATE_UP : LINK_STATE_DOWN);
315 sc->ifnet->if_baudrate = sfxge_link_baudrate[port->link_mode];
316 if_link_state_change(sc->ifnet, link_state);
320 sfxge_mac_poll_work(void *arg, int npending)
322 struct sfxge_softc *sc;
324 struct sfxge_port *port;
325 efx_link_mode_t mode;
327 sc = (struct sfxge_softc *)arg;
331 SFXGE_PORT_LOCK(port);
333 if (__predict_false(port->init_state != SFXGE_PORT_STARTED))
336 /* This may sleep waiting for MCDI completion */
337 (void)efx_port_poll(enp, &mode);
338 sfxge_mac_link_update(sc, mode);
341 SFXGE_PORT_UNLOCK(port);
345 sfxge_mac_filter_set_locked(struct sfxge_softc *sc)
347 unsigned int bucket[EFX_MAC_HASH_BITS];
348 struct ifnet *ifp = sc->ifnet;
349 struct ifmultiaddr *ifma;
350 struct sockaddr_dl *sa;
351 efx_nic_t *enp = sc->enp;
355 /* Set promisc-unicast and broadcast filter bits */
356 if ((rc = efx_mac_filter_set(enp, !!(ifp->if_flags & IFF_PROMISC),
360 /* Set multicast hash filter */
361 if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) {
362 for (index = 0; index < EFX_MAC_HASH_BITS; index++)
365 /* Broadcast frames also go through the multicast
366 * filter, and the broadcast address hashes to
371 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
372 if (ifma->ifma_addr->sa_family == AF_LINK) {
373 sa = (struct sockaddr_dl *)ifma->ifma_addr;
374 index = ether_crc32_le(LLADDR(sa), 6) & 0xff;
378 if_maddr_runlock(ifp);
380 return (efx_mac_hash_set(enp, bucket));
384 sfxge_mac_filter_set(struct sfxge_softc *sc)
386 struct sfxge_port *port = &sc->port;
389 SFXGE_PORT_LOCK(port);
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.
400 if (__predict_true(port->init_state == SFXGE_PORT_STARTED))
401 rc = sfxge_mac_filter_set_locked(sc);
404 SFXGE_PORT_UNLOCK(port);
409 sfxge_port_stop(struct sfxge_softc *sc)
411 struct sfxge_port *port;
417 SFXGE_PORT_LOCK(port);
419 KASSERT(port->init_state == SFXGE_PORT_STARTED,
420 ("port not started"));
422 port->init_state = SFXGE_PORT_INITIALIZED;
424 port->mac_stats.update_time = 0;
426 /* This may call MCDI */
427 (void)efx_mac_drain(enp, B_TRUE);
429 (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE);
431 port->link_mode = EFX_LINK_UNKNOWN;
433 /* Destroy the common code port object. */
434 efx_port_fini(sc->enp);
436 SFXGE_PORT_UNLOCK(port);
440 sfxge_port_start(struct sfxge_softc *sc)
442 uint8_t mac_addr[ETHER_ADDR_LEN];
443 struct ifnet *ifp = sc->ifnet;
444 struct sfxge_port *port;
448 uint32_t phy_cap_mask;
453 SFXGE_PORT_LOCK(port);
455 KASSERT(port->init_state == SFXGE_PORT_INITIALIZED,
456 ("port not initialized"));
458 /* Initialize the port object in the common code. */
459 if ((rc = efx_port_init(sc->enp)) != 0)
463 pdu = EFX_MAC_PDU(ifp->if_mtu);
464 if ((rc = efx_mac_pdu_set(enp, pdu)) != 0)
467 if ((rc = efx_mac_fcntl_set(enp, sfxge_port_wanted_fc(sc), B_TRUE))
471 /* Set the unicast address */
473 bcopy(LLADDR((struct sockaddr_dl *)ifp->if_addr->ifa_addr),
474 mac_addr, sizeof(mac_addr));
475 if_addr_runlock(ifp);
476 if ((rc = efx_mac_addr_set(enp, mac_addr)) != 0)
479 sfxge_mac_filter_set_locked(sc);
481 /* Update MAC stats by DMA every second */
482 if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
483 1000, B_FALSE)) != 0)
486 if ((rc = efx_mac_drain(enp, B_FALSE)) != 0)
489 if ((rc = sfxge_phy_cap_mask(sc, sc->media.ifm_cur->ifm_media,
490 &phy_cap_mask)) != 0)
493 if ((rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask)) != 0)
496 port->init_state = SFXGE_PORT_STARTED;
498 /* Single poll in case there were missing initial events */
499 SFXGE_PORT_UNLOCK(port);
500 sfxge_mac_poll_work(sc, 0);
506 (void)efx_mac_drain(enp, B_TRUE);
508 (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
511 efx_port_fini(sc->enp);
513 SFXGE_PORT_UNLOCK(port);
519 sfxge_phy_stat_update(struct sfxge_softc *sc)
521 struct sfxge_port *port = &sc->port;
522 efsys_mem_t *esmp = &port->phy_stats.dma_buf;
527 SFXGE_PORT_LOCK_ASSERT_OWNED(port);
529 if (__predict_false(port->init_state != SFXGE_PORT_STARTED)) {
535 if (now - port->phy_stats.update_time < hz) {
540 port->phy_stats.update_time = now;
542 /* If we're unlucky enough to read statistics wduring the DMA, wait
543 * up to 10ms for it to finish (typically takes <500us) */
544 for (count = 0; count < 100; ++count) {
545 EFSYS_PROBE1(wait, unsigned int, count);
547 /* Synchronize the DMA memory for reading */
548 bus_dmamap_sync(esmp->esm_tag, esmp->esm_map,
549 BUS_DMASYNC_POSTREAD);
551 /* Try to update the cached counters */
552 if ((rc = efx_phy_stats_update(sc->enp, esmp,
553 port->phy_stats.decode_buf)) != EAGAIN)
565 sfxge_phy_stat_handler(SYSCTL_HANDLER_ARGS)
567 struct sfxge_softc *sc = arg1;
568 unsigned int id = arg2;
572 SFXGE_PORT_LOCK(&sc->port);
573 if ((rc = sfxge_phy_stat_update(sc)) == 0)
574 val = ((uint32_t *)sc->port.phy_stats.decode_buf)[id];
575 SFXGE_PORT_UNLOCK(&sc->port);
578 rc = SYSCTL_OUT(req, &val, sizeof(val));
583 sfxge_phy_stat_init(struct sfxge_softc *sc)
585 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
586 struct sysctl_oid_list *stat_list;
589 uint64_t stat_mask = efx_nic_cfg_get(sc->enp)->enc_phy_stat_mask;
591 stat_list = SYSCTL_CHILDREN(sc->stats_node);
593 /* Initialise the named stats */
594 for (id = 0; id < EFX_PHY_NSTATS; id++) {
595 if (!(stat_mask & ((uint64_t)1 << id)))
597 name = efx_phy_stat_name(sc->enp, id);
600 OID_AUTO, name, CTLTYPE_UINT|CTLFLAG_RD,
601 sc, id, sfxge_phy_stat_handler,
602 id == EFX_PHY_STAT_OUI ? "IX" : "IU",
608 sfxge_port_fini(struct sfxge_softc *sc)
610 struct sfxge_port *port;
614 esmp = &port->mac_stats.dma_buf;
616 KASSERT(port->init_state == SFXGE_PORT_INITIALIZED,
617 ("Port not initialized"));
619 port->init_state = SFXGE_PORT_UNINITIALIZED;
621 port->link_mode = EFX_LINK_UNKNOWN;
623 /* Finish with PHY DMA memory */
624 sfxge_dma_free(&port->phy_stats.dma_buf);
625 free(port->phy_stats.decode_buf, M_SFXGE);
627 sfxge_dma_free(esmp);
628 free(port->mac_stats.decode_buf, M_SFXGE);
630 SFXGE_PORT_LOCK_DESTROY(port);
636 sfxge_port_init(struct sfxge_softc *sc)
638 struct sfxge_port *port;
639 struct sysctl_ctx_list *sysctl_ctx;
640 struct sysctl_oid *sysctl_tree;
641 efsys_mem_t *mac_stats_buf, *phy_stats_buf;
645 mac_stats_buf = &port->mac_stats.dma_buf;
646 phy_stats_buf = &port->phy_stats.dma_buf;
648 KASSERT(port->init_state == SFXGE_PORT_UNINITIALIZED,
649 ("Port already initialized"));
653 SFXGE_PORT_LOCK_INIT(port, device_get_nameunit(sc->dev));
655 port->phy_stats.decode_buf = malloc(EFX_PHY_NSTATS * sizeof(uint32_t),
656 M_SFXGE, M_WAITOK | M_ZERO);
657 if ((rc = sfxge_dma_alloc(sc, EFX_PHY_STATS_SIZE, phy_stats_buf)) != 0)
659 sfxge_phy_stat_init(sc);
661 sysctl_ctx = device_get_sysctl_ctx(sc->dev);
662 sysctl_tree = device_get_sysctl_tree(sc->dev);
664 #ifndef SFXGE_HAVE_PAUSE_MEDIAOPTS
665 /* If flow control cannot be configured or reported through
666 * ifmedia, provide sysctls for it. */
667 port->wanted_fc = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
668 SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
669 "wanted_fc", CTLTYPE_UINT|CTLFLAG_RW, sc, 0,
670 sfxge_port_wanted_fc_handler, "IU", "wanted flow control mode");
671 SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
672 "link_fc", CTLTYPE_UINT|CTLFLAG_RD, sc, 0,
673 sfxge_port_link_fc_handler, "IU", "link flow control mode");
676 port->mac_stats.decode_buf = malloc(EFX_MAC_NSTATS * sizeof(uint64_t),
677 M_SFXGE, M_WAITOK | M_ZERO);
678 if ((rc = sfxge_dma_alloc(sc, EFX_MAC_STATS_SIZE, mac_stats_buf)) != 0)
680 sfxge_mac_stat_init(sc);
682 port->init_state = SFXGE_PORT_INITIALIZED;
687 free(port->mac_stats.decode_buf, M_SFXGE);
688 sfxge_dma_free(phy_stats_buf);
690 free(port->phy_stats.decode_buf, M_SFXGE);
691 SFXGE_PORT_LOCK_DESTROY(port);
696 static const int sfxge_link_mode[EFX_PHY_MEDIA_NTYPES][EFX_LINK_NMODES] = {
697 [EFX_PHY_MEDIA_CX4] = {
698 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_CX4,
700 [EFX_PHY_MEDIA_KX4] = {
701 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_KX4,
703 [EFX_PHY_MEDIA_XFP] = {
704 /* Don't know the module type, but assume SR for now. */
705 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR,
707 [EFX_PHY_MEDIA_SFP_PLUS] = {
708 /* Don't know the module type, but assume SX/SR for now. */
709 [EFX_LINK_1000FDX] = IFM_ETHER | IFM_FDX | IFM_1000_SX,
710 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR,
712 [EFX_PHY_MEDIA_BASE_T] = {
713 [EFX_LINK_10HDX] = IFM_ETHER | IFM_HDX | IFM_10_T,
714 [EFX_LINK_10FDX] = IFM_ETHER | IFM_FDX | IFM_10_T,
715 [EFX_LINK_100HDX] = IFM_ETHER | IFM_HDX | IFM_100_TX,
716 [EFX_LINK_100FDX] = IFM_ETHER | IFM_FDX | IFM_100_TX,
717 [EFX_LINK_1000HDX] = IFM_ETHER | IFM_HDX | IFM_1000_T,
718 [EFX_LINK_1000FDX] = IFM_ETHER | IFM_FDX | IFM_1000_T,
719 [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_T,
724 sfxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
726 struct sfxge_softc *sc;
727 efx_phy_media_type_t medium_type;
728 efx_link_mode_t mode;
731 SFXGE_ADAPTER_LOCK(sc);
733 ifmr->ifm_status = IFM_AVALID;
734 ifmr->ifm_active = IFM_ETHER;
736 if (SFXGE_RUNNING(sc) && SFXGE_LINK_UP(sc)) {
737 ifmr->ifm_status |= IFM_ACTIVE;
739 efx_phy_media_type_get(sc->enp, &medium_type);
740 mode = sc->port.link_mode;
741 ifmr->ifm_active |= sfxge_link_mode[medium_type][mode];
742 ifmr->ifm_active |= sfxge_port_link_fc_ifm(sc);
745 SFXGE_ADAPTER_UNLOCK(sc);
748 static efx_phy_cap_type_t
749 sfxge_link_mode_to_phy_cap(efx_link_mode_t mode)
753 return (EFX_PHY_CAP_10HDX);
755 return (EFX_PHY_CAP_10FDX);
756 case EFX_LINK_100HDX:
757 return (EFX_PHY_CAP_100HDX);
758 case EFX_LINK_100FDX:
759 return (EFX_PHY_CAP_100FDX);
760 case EFX_LINK_1000HDX:
761 return (EFX_PHY_CAP_1000HDX);
762 case EFX_LINK_1000FDX:
763 return (EFX_PHY_CAP_1000FDX);
764 case EFX_LINK_10000FDX:
765 return (EFX_PHY_CAP_10000FDX);
767 EFSYS_ASSERT(B_FALSE);
768 return (EFX_PHY_CAP_INVALID);
773 sfxge_phy_cap_mask(struct sfxge_softc *sc, int ifmedia, uint32_t *phy_cap_mask)
775 efx_phy_media_type_t medium_type;
776 boolean_t mode_found = B_FALSE;
777 uint32_t cap_mask, mode_cap_mask;
778 efx_link_mode_t mode;
779 efx_phy_cap_type_t phy_cap;
781 efx_phy_media_type_get(sc->enp, &medium_type);
782 if (medium_type >= nitems(sfxge_link_mode)) {
783 if_printf(sc->ifnet, "unexpected media type %d\n", medium_type);
787 efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
789 for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
790 if (ifmedia == sfxge_link_mode[medium_type][mode]) {
798 * If media is not in the table, it must be IFM_AUTO.
800 KASSERT((cap_mask & (1 << EFX_PHY_CAP_AN)) &&
801 ifmedia == (IFM_ETHER | IFM_AUTO),
802 ("%s: no mode for media %d", __func__, ifmedia));
803 *phy_cap_mask = (cap_mask & ~(1 << EFX_PHY_CAP_ASYM));
807 phy_cap = sfxge_link_mode_to_phy_cap(mode);
808 if (phy_cap == EFX_PHY_CAP_INVALID) {
810 "cannot map link mode %d to phy capability\n",
815 mode_cap_mask = (1 << phy_cap);
816 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_AN);
817 #ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
818 if (ifmedia & IFM_ETH_RXPAUSE)
819 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
820 if (!(ifmedia & IFM_ETH_TXPAUSE))
821 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_ASYM);
823 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
826 *phy_cap_mask = mode_cap_mask;
831 sfxge_media_change(struct ifnet *ifp)
833 struct sfxge_softc *sc;
834 struct ifmedia_entry *ifm;
836 uint32_t phy_cap_mask;
839 ifm = sc->media.ifm_cur;
841 SFXGE_ADAPTER_LOCK(sc);
843 if (!SFXGE_RUNNING(sc)) {
848 rc = efx_mac_fcntl_set(sc->enp, sfxge_port_wanted_fc(sc), B_TRUE);
852 if ((rc = sfxge_phy_cap_mask(sc, ifm->ifm_media, &phy_cap_mask)) != 0)
855 rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask);
857 SFXGE_ADAPTER_UNLOCK(sc);
862 int sfxge_port_ifmedia_init(struct sfxge_softc *sc)
864 efx_phy_media_type_t medium_type;
865 uint32_t cap_mask, mode_cap_mask;
866 efx_link_mode_t mode;
867 efx_phy_cap_type_t phy_cap;
868 int mode_ifm, best_mode_ifm = 0;
871 /* We need port state to initialise the ifmedia list. */
872 if ((rc = efx_nic_init(sc->enp)) != 0)
874 if ((rc = efx_port_init(sc->enp)) != 0)
878 * Register ifconfig callbacks for querying and setting the
879 * link mode and link status.
881 ifmedia_init(&sc->media, IFM_IMASK, sfxge_media_change,
885 * Map firmware medium type and capabilities to ifmedia types.
886 * ifmedia does not distinguish between forcing the link mode
887 * and disabling auto-negotiation. 1000BASE-T and 10GBASE-T
888 * require AN even if only one link mode is enabled, and for
889 * 100BASE-TX it is useful even if the link mode is forced.
890 * Therefore we never disable auto-negotiation.
892 * Also enable and advertise flow control by default.
895 efx_phy_media_type_get(sc->enp, &medium_type);
896 efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
898 for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
899 phy_cap = sfxge_link_mode_to_phy_cap(mode);
900 if (phy_cap == EFX_PHY_CAP_INVALID)
903 mode_cap_mask = (1 << phy_cap);
904 mode_ifm = sfxge_link_mode[medium_type][mode];
906 if ((cap_mask & mode_cap_mask) && mode_ifm) {
907 /* No flow-control */
908 ifmedia_add(&sc->media, mode_ifm, 0, NULL);
910 #ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
911 /* Respond-only. If using AN, we implicitly
912 * offer symmetric as well, but that doesn't
913 * mean we *have* to generate pause frames.
915 mode_ifm |= IFM_ETH_RXPAUSE;
916 ifmedia_add(&sc->media, mode_ifm, 0, NULL);
919 mode_ifm |= IFM_ETH_TXPAUSE;
920 ifmedia_add(&sc->media, mode_ifm, 0, NULL);
923 /* Link modes are numbered in order of speed,
924 * so assume the last one available is the best.
926 best_mode_ifm = mode_ifm;
930 if (cap_mask & (1 << EFX_PHY_CAP_AN)) {
931 /* Add autoselect mode. */
932 mode_ifm = IFM_ETHER | IFM_AUTO;
933 ifmedia_add(&sc->media, mode_ifm, 0, NULL);
934 best_mode_ifm = mode_ifm;
937 if (best_mode_ifm != 0)
938 ifmedia_set(&sc->media, best_mode_ifm);
940 /* Now discard port state until interface is started. */
941 efx_port_fini(sc->enp);
943 efx_nic_fini(sc->enp);