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++) { if (sc->sc_vsd[i].vsd_buf) { pool_put(&sc->sc_pool, sc->sc_vsd[i].vsd_buf); sc->sc_vsd[i].vsd_buf = NULL; } sc->sc_vd->vd_desc[i].hdr.dstate = VIO_DESC_FREE; } }
void vnet_rx_vio_rdx(struct vnet_softc *sc, struct vio_msg_tag *tag) { struct ifnet *ifp = &sc->sc_ac.ac_if; switch(tag->stype) { case VIO_SUBTYPE_INFO: DPRINTF(("CTRL/INFO/RDX\n")); tag->stype = VIO_SUBTYPE_ACK; tag->sid = sc->sc_local_sid; vnet_sendmsg(sc, tag, sizeof(*tag)); sc->sc_vio_state |= VIO_RCV_RDX; break; case VIO_SUBTYPE_ACK: DPRINTF(("CTRL/ACK/RDX\n")); if (!ISSET(sc->sc_vio_state, VIO_SND_RDX)) { ldc_reset(&sc->sc_lc); break; } sc->sc_vio_state |= VIO_ACK_RDX; break; default: DPRINTF(("CTRL/0x%02x/RDX (VIO)\n", tag->stype)); break; } if (ISSET(sc->sc_vio_state, VIO_RCV_RDX) && ISSET(sc->sc_vio_state, VIO_ACK_RDX)) { /* Link is up! */ vnet_link_state(sc); /* Configure multicast now that we can. */ vnet_setmulti(sc, 1); KERNEL_LOCK(); ifp->if_flags &= ~IFF_OACTIVE; vnet_start(ifp); KERNEL_UNLOCK(); } }