summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64/dev
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2015-03-21 18:11:19 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2015-03-21 18:11:19 +0000
commita0cfbc7c809d309a59fee69668febb829332732e (patch)
treeb466220d4dd0627f34ad58e46df00716a33b6415 /sys/arch/sparc64/dev
parenta1256b58c51cc0c0da3b3a16de4666f0f78790e6 (diff)
Make sure we reset all relevant state when resetting or stopping an interface.
Our reset function did not reset the ring and LDC map and our stop function did not reset the LDC channel state and the some of the ring state. Also make sure we clear IFF_OACTIVE whenever we re-establish a connection on the LDC channel. Finally, initialize the link state to LINK_STATE_DOWN such that interfaces that have not been configured yet, don't show up as active. This should improve the reliability of re-establishing network connections between domains after some sort of hickup considerably.
Diffstat (limited to 'sys/arch/sparc64/dev')
-rw-r--r--sys/arch/sparc64/dev/vnet.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/sys/arch/sparc64/dev/vnet.c b/sys/arch/sparc64/dev/vnet.c
index ce2c78d89b4..e683cbace2c 100644
--- a/sys/arch/sparc64/dev/vnet.c
+++ b/sys/arch/sparc64/dev/vnet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnet.c,v 1.39 2015/03/10 09:26:24 mpi Exp $ */
+/* $OpenBSD: vnet.c,v 1.40 2015/03/21 18:11:18 kettenis Exp $ */
/*
* Copyright (c) 2009, 2015 Mark Kettenis
*
@@ -309,6 +309,7 @@ vnet_attach(struct device *parent, struct device *self, void *aux)
ifp = &sc->sc_ac.ac_if;
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_link_state = LINK_STATE_DOWN;
ifp->if_ioctl = vnet_ioctl;
ifp->if_start = vnet_start;
ifp->if_watchdog = vnet_watchdog;
@@ -390,6 +391,7 @@ vnet_rx_intr(void *arg)
lc->lc_tx_seqid = 0;
lc->lc_state = 0;
lc->lc_reset(lc);
+ timeout_add_msec(&sc->sc_handshake_to, 500);
break;
}
lc->lc_rx_state = rx_state;
@@ -656,6 +658,8 @@ vnet_rx_vio_rdx(struct vnet_softc *sc, struct vio_msg_tag *tag)
/* Configure multicast now that we can. */
vnet_setmulti(sc, 1);
+
+ ifp->if_flags &= ~IFF_OACTIVE;
vnet_start(ifp);
}
}
@@ -897,12 +901,21 @@ void
vnet_ldc_reset(struct ldc_conn *lc)
{
struct vnet_softc *sc = lc->lc_sc;
+ int i;
timeout_del(&sc->sc_handshake_to);
sc->sc_tx_prod = sc->sc_tx_cons = 0;
sc->sc_peer_state = VIO_DP_STOPPED;
sc->sc_vio_state = 0;
vnet_link_state(sc);
+
+ sc->sc_lm->lm_next = 1;
+ sc->sc_lm->lm_count = 1;
+ for (i = 1; i < sc->sc_lm->lm_nentries; i++)
+ sc->sc_lm->lm_slot[i].entry = 0;
+
+ for (i = 0; i < sc->sc_vd->vd_nentries; i++)
+ sc->sc_vd->vd_desc[i].hdr.dstate = VIO_DESC_FREE;
}
void
@@ -1391,7 +1404,6 @@ vnet_init(struct ifnet *ifp)
ldc_send_vers(lc);
ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
}
void
@@ -1408,7 +1420,10 @@ vnet_stop(struct ifnet *ifp)
hv_ldc_tx_qconf(lc->lc_id, 0, 0);
hv_ldc_rx_qconf(lc->lc_id, 0, 0);
+ lc->lc_tx_seqid = 0;
+ lc->lc_state = 0;
lc->lc_tx_state = lc->lc_rx_state = LDC_CHANNEL_DOWN;
+ vnet_ldc_reset(lc);
vnet_dring_free(sc->sc_dmatag, sc->sc_vd);