diff options
-rw-r--r-- | sys/dev/hatm/if_hatm.c | 38 | ||||
-rw-r--r-- | sys/dev/hatm/if_hatm_ioctl.c | 33 | ||||
-rw-r--r-- | sys/dev/hatm/if_hatm_tx.c | 11 | ||||
-rw-r--r-- | 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 d423ec4..51538ff 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 c49e5ae..f9098d8 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 38903bd..5e915ee 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 e5f4359..694dad1 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); |