summaryrefslogtreecommitdiffstats
path: root/sys/dev/hatm
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2003-08-07 13:42:31 +0000
committerharti <harti@FreeBSD.org>2003-08-07 13:42:31 +0000
commitc47985e350989a08effa9ee72e9aa7c100d8d407 (patch)
treea8d419fc85f7eea9fda691f985b5aa94c0b39423 /sys/dev/hatm
parent136c4125667d7ca587662848cea09e5a072b12e5 (diff)
downloadFreeBSD-src-c47985e350989a08effa9ee72e9aa7c100d8d407.zip
FreeBSD-src-c47985e350989a08effa9ee72e9aa7c100d8d407.tar.gz
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.
Diffstat (limited to 'sys/dev/hatm')
-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