summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/hatm/if_hatm.c38
-rw-r--r--sys/dev/hatm/if_hatm_ioctl.c33
-rw-r--r--sys/dev/hatm/if_hatm_tx.c11
-rw-r--r--sys/dev/hatm/if_hatmvar.h1
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);
OpenPOWER on IntegriCloud