diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2009-07-10 12:00:53 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2009-07-10 12:00:53 +0000 |
commit | 224ca3a3acc4d039366468f4646ad9e1221cbcf5 (patch) | |
tree | bc0939a70793059a55c2808ce59f26587044f717 /sys/dev/pci | |
parent | 880c67cf7703f937d2d7ead9cf1879051679a60d (diff) |
rework link state handling a bit. this reports missing link correctly. the
old code showed the nic as active all the time, which makes it suck as
part of a trunk.
testing and ok by reyk@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_ix.c | 105 |
1 files changed, 41 insertions, 64 deletions
diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index bce7a91158f..e4a03ef8e93 100644 --- a/sys/dev/pci/if_ix.c +++ b/sys/dev/pci/if_ix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.c,v 1.23 2009/06/29 16:40:46 jsg Exp $ */ +/* $OpenBSD: if_ix.c,v 1.24 2009/07/10 12:00:52 dlg Exp $ */ /****************************************************************************** @@ -755,26 +755,23 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) { struct ix_softc *sc = ifp->if_softc; - INIT_DEBUGOUT("ixgbe_media_status: begin"); - ixgbe_update_link_status(sc); - - ifmr->ifm_status = IFM_AVALID; ifmr->ifm_active = IFM_ETHER; + ifmr->ifm_status = IFM_AVALID; - if (!sc->link_active) { - ifmr->ifm_status |= IFM_NONE; - return; - } + INIT_DEBUGOUT("ixgbe_media_status: begin"); + ixgbe_update_link_status(sc); - ifmr->ifm_status |= IFM_ACTIVE; + if (LINK_STATE_IS_UP(ifp->if_link_state)) { + ifmr->ifm_status |= IFM_ACTIVE; - switch (sc->link_speed) { - case IXGBE_LINK_SPEED_1GB_FULL: - ifmr->ifm_active |= IFM_1000_T | IFM_FDX; - break; - case IXGBE_LINK_SPEED_10GB_FULL: - ifmr->ifm_active |= sc->optics | IFM_FDX; - break; + switch (sc->link_speed) { + case IXGBE_LINK_SPEED_1GB_FULL: + ifmr->ifm_active |= IFM_1000_T | IFM_FDX; + break; + case IXGBE_LINK_SPEED_10GB_FULL: + ifmr->ifm_active |= sc->optics | IFM_FDX; + break; + } } } @@ -789,25 +786,7 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) int ixgbe_media_change(struct ifnet * ifp) { - struct ix_softc *sc = ifp->if_softc; - struct ifmedia *ifm = &sc->media; - - INIT_DEBUGOUT("ixgbe_media_change: begin"); - - if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) - return (EINVAL); - - switch (IFM_SUBTYPE(ifm->ifm_media)) { - case IFM_AUTO: - sc->hw.mac.autoneg = TRUE; - sc->hw.phy.autoneg_advertised = - IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_10GB_FULL; - break; - default: - printf("%s: Only auto media type\n", ifp->if_xname); - return (EINVAL); - } - + /* ignore */ return (0); } @@ -1102,44 +1081,42 @@ ixgbe_update_link_status(struct ix_softc *sc) int link_up = FALSE; struct ifnet *ifp = &sc->arpcom.ac_if; struct tx_ring *txr = sc->tx_rings; + int link_state; int i; ixgbe_hw(&sc->hw, check_link, &sc->link_speed, &link_up, 0); - switch (sc->link_speed) { - case IXGBE_LINK_SPEED_UNKNOWN: - ifp->if_baudrate = 0; - break; - case IXGBE_LINK_SPEED_100_FULL: - ifp->if_baudrate = IF_Mbps(100); - break; - case IXGBE_LINK_SPEED_1GB_FULL: - ifp->if_baudrate = IF_Gbps(1); - break; - case IXGBE_LINK_SPEED_10GB_FULL: - ifp->if_baudrate = IF_Gbps(10); - break; + link_state = link_up ? LINK_STATE_FULL_DUPLEX : LINK_STATE_DOWN; + + if (ifp->if_link_state != link_state) { + sc->link_active = link_up; + ifp->if_link_state = link_state; + if_link_state_change(ifp); } - if (link_up){ - if (sc->link_active == FALSE) { - sc->link_active = TRUE; - ifp->if_link_state = LINK_STATE_FULL_DUPLEX; - if_link_state_change(ifp); - } - } else { /* Link down */ - if (sc->link_active == TRUE) { + if (LINK_STATE_IS_UP(ifp->if_link_state)) { + switch (sc->link_speed) { + case IXGBE_LINK_SPEED_UNKNOWN: ifp->if_baudrate = 0; - ifp->if_link_state = LINK_STATE_DOWN; - if_link_state_change(ifp); - sc->link_active = FALSE; - for (i = 0; i < sc->num_tx_queues; - i++, txr++) - txr->watchdog_timer = FALSE; - ifp->if_timer = 0; + break; + case IXGBE_LINK_SPEED_100_FULL: + ifp->if_baudrate = IF_Mbps(100); + break; + case IXGBE_LINK_SPEED_1GB_FULL: + ifp->if_baudrate = IF_Gbps(1); + break; + case IXGBE_LINK_SPEED_10GB_FULL: + ifp->if_baudrate = IF_Gbps(10); + break; } + } else { + ifp->if_baudrate = 0; + ifp->if_timer = 0; + for (i = 0; i < sc->num_tx_queues; i++) + txr[i].watchdog_timer = FALSE; } + return; } |