summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2009-07-10 12:00:53 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2009-07-10 12:00:53 +0000
commit224ca3a3acc4d039366468f4646ad9e1221cbcf5 (patch)
treebc0939a70793059a55c2808ce59f26587044f717 /sys/dev/pci
parent880c67cf7703f937d2d7ead9cf1879051679a60d (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.c105
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;
}