From a80f65357463b353260d2d1f08da86dc6b85f181 Mon Sep 17 00:00:00 2001 From: Hartmut Brandt <harti@FreeBSD.org> Date: Thu, 7 Aug 2003 13:42:31 +0000 Subject: [PATCH] Make the driver preserve open connections accross ifconfig down and up commands. When configuring the interface down only the connections that are currently closing are deleted from the connection table. When the interface is configured up, all connections that are in the table are re-opened. --- sys/dev/hatm/if_hatm.c | 38 +++++++++++++++++++++++++----------- sys/dev/hatm/if_hatm_ioctl.c | 33 +++++++++++++++++++------------ sys/dev/hatm/if_hatm_tx.c | 11 ++++++++--- sys/dev/hatm/if_hatmvar.h | 1 + 4 files changed, 57 insertions(+), 26 deletions(-) diff --git a/sys/dev/hatm/if_hatm.c b/sys/dev/hatm/if_hatm.c index d423ec4a6c6c..51538ffcba53 100644 --- a/sys/dev/hatm/if_hatm.c +++ b/sys/dev/hatm/if_hatm.c @@ -438,14 +438,20 @@ hatm_stop_tpds(struct hatm_softc *sc) static void hatm_destroy(struct hatm_softc *sc) { + u_int cid; + bus_teardown_intr(sc->dev, sc->irqres, sc->ih); hatm_destroy_rmaps(sc); hatm_destroy_smbufs(sc); hatm_destroy_tpds(sc); - if (sc->vcc_zone != NULL) + if (sc->vcc_zone != NULL) { + for (cid = 0; cid < HE_MAX_VCCS; cid++) + if (sc->vccs[cid] != NULL) + uma_zfree(sc->vcc_zone, sc->vccs[cid]); uma_zdestroy(sc->vcc_zone); + } /* * Release all memory allocated to the various queues and @@ -1954,6 +1960,7 @@ void hatm_initialize(struct hatm_softc *sc) { uint32_t v; + u_int cid; static const u_int layout[2][7] = HE_CONFIG_MEM_LAYOUT; if (sc->ifatm.ifnet.if_flags & IFF_RUNNING) @@ -2231,6 +2238,11 @@ hatm_initialize(struct hatm_softc *sc) sc->utopia.flags &= ~UTP_FL_POLL_CARRIER; + /* reopen vccs */ + for (cid = 0; cid < HE_MAX_VCCS; cid++) + if (sc->vccs[cid] != NULL) + hatm_load_vc(sc, cid, 1); + ATMEV_SEND_IFSTATE_CHANGED(&sc->ifatm, sc->utopia.carrier == UTP_CARR_OK); } @@ -2343,19 +2355,23 @@ hatm_stop(struct hatm_softc *sc) */ for (cid = 0; cid < HE_MAX_VCCS; cid++) { if (sc->vccs[cid] != NULL) { - if (sc->vccs[cid]->chain != NULL) + if (sc->vccs[cid]->chain != NULL) { m_freem(sc->vccs[cid]->chain); - uma_zfree(sc->vcc_zone, sc->vccs[cid]); + sc->vccs[cid]->chain = NULL; + sc->vccs[cid]->last = NULL; + } + if (!(sc->vccs[cid]->vflags & (HE_VCC_RX_OPEN | + HE_VCC_TX_OPEN))) { + hatm_tx_vcc_closed(sc, cid); + uma_zfree(sc->vcc_zone, sc->vccs[cid]); + sc->vccs[cid] = NULL; + sc->open_vccs--; + } else { + sc->vccs[cid]->vflags = 0; + sc->vccs[cid]->ntpds = 0; + } } } - bzero(sc->vccs, sizeof(sc->vccs)); - sc->cbr_bw = 0; - sc->open_vccs = 0; - - /* - * Reset CBR rate groups - */ - bzero(sc->rate_ctrl, sizeof(sc->rate_ctrl)); if (sc->rbp_s0.size != 0) bzero(sc->rbp_s0.mem.base, sc->rbp_s0.mem.size); diff --git a/sys/dev/hatm/if_hatm_ioctl.c b/sys/dev/hatm/if_hatm_ioctl.c index c49e5ae7600f..f9098d83cc6a 100644 --- a/sys/dev/hatm/if_hatm_ioctl.c +++ b/sys/dev/hatm/if_hatm_ioctl.c @@ -159,21 +159,10 @@ hatm_open_vcc(struct hatm_softc *sc, struct atmio_openvcc *arg) /* ok - go ahead */ sc->vccs[cid] = vcc; - - if (!(vcc->param.flags & ATMIO_FLAG_NOTX)) - hatm_tx_vcc_open(sc, cid); - if (!(vcc->param.flags & ATMIO_FLAG_NORX)) - hatm_rx_vcc_open(sc, cid); - - /* inform management about non-NG and NG-PVCs */ - if (!(vcc->param.flags & ATMIO_FLAG_NG) || - (vcc->param.flags & ATMIO_FLAG_PVC)) - ATMEV_SEND_VCC_CHANGED(&sc->ifatm, arg->param.vpi, - arg->param.vci, 1); + hatm_load_vc(sc, cid, 0); /* don't free below */ vcc = NULL; - sc->open_vccs++; done: @@ -183,6 +172,26 @@ hatm_open_vcc(struct hatm_softc *sc, struct atmio_openvcc *arg) return (error); } +void +hatm_load_vc(struct hatm_softc *sc, u_int cid, int reopen) +{ + struct hevcc *vcc = sc->vccs[cid]; + + if (!(vcc->param.flags & ATMIO_FLAG_NOTX)) + hatm_tx_vcc_open(sc, cid); + if (!(vcc->param.flags & ATMIO_FLAG_NORX)) + hatm_rx_vcc_open(sc, cid); + + if (reopen) + return; + + /* inform management about non-NG and NG-PVCs */ + if (!(vcc->param.flags & ATMIO_FLAG_NG) || + (vcc->param.flags & ATMIO_FLAG_PVC)) + ATMEV_SEND_VCC_CHANGED(&sc->ifatm, vcc->param.vpi, + vcc->param.vci, 1); +} + /* * VCC has been finally closed. */ diff --git a/sys/dev/hatm/if_hatm_tx.c b/sys/dev/hatm/if_hatm_tx.c index 38903bd7ad72..5e915ee5fa87 100644 --- a/sys/dev/hatm/if_hatm_tx.c +++ b/sys/dev/hatm/if_hatm_tx.c @@ -577,9 +577,12 @@ hatm_tx_vcc_can_open(struct hatm_softc *sc, u_int cid, struct hevcc *vcc) if ((idx = free_idx) == HE_REGN_CS_STPER) return (EBUSY); sc->rate_ctrl[idx].rate = rc; - WRITE_MBOX4(sc, HE_REGO_CS_STPER(idx), rc); } vcc->rc = idx; + + /* commit */ + sc->rate_ctrl[idx].refcnt++; + sc->cbr_bw += t->pcr; break; case ATMIO_TRAFFIC_ABR: @@ -649,7 +652,10 @@ hatm_tx_vcc_open(struct hatm_softc *sc, u_int cid) case ATMIO_TRAFFIC_CBR: atmf = hatm_cps2atmf(t->pcr); - sc->rate_ctrl[vcc->rc].refcnt++; + + if (sc->rate_ctrl[vcc->rc].refcnt == 1) + WRITE_MBOX4(sc, HE_REGO_CS_STPER(vcc->rc), + sc->rate_ctrl[vcc->rc].rate); tsr0 |= HE_REGM_TSR0_TRAFFIC_CBR << HE_REGS_TSR0_TRAFFIC; tsr0 |= vcc->rc; @@ -670,7 +676,6 @@ hatm_tx_vcc_open(struct hatm_softc *sc, u_int cid) WRITE_TSR(sc, cid, 9, 0xf, HE_REGM_TSR9_INIT); WRITE_TSR(sc, cid, 0, 0xf, tsr0); - sc->cbr_bw += t->pcr; break; case ATMIO_TRAFFIC_ABR: diff --git a/sys/dev/hatm/if_hatmvar.h b/sys/dev/hatm/if_hatmvar.h index e5f4359dbf96..694dad145f02 100644 --- a/sys/dev/hatm/if_hatmvar.h +++ b/sys/dev/hatm/if_hatmvar.h @@ -618,3 +618,4 @@ void hatm_tx_vcc_close(struct hatm_softc *sc, u_int cid); void hatm_rx_vcc_close(struct hatm_softc *sc, u_int cid); void hatm_tx_vcc_closed(struct hatm_softc *sc, u_int cid); void hatm_vcc_closed(struct hatm_softc *sc, u_int cid); +void hatm_load_vc(struct hatm_softc *sc, u_int cid, int reopen);