aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/hatm
diff options
context:
space:
mode:
authorHartmut Brandt <harti@FreeBSD.org>2003-08-07 13:42:31 +0000
committerHartmut Brandt <harti@FreeBSD.org>2003-08-07 13:42:31 +0000
commita80f65357463b353260d2d1f08da86dc6b85f181 (patch)
treea8d419fc85f7eea9fda691f985b5aa94c0b39423 /sys/dev/hatm
parent3593b9247891e48ec434b0410e5b25cbc4cd755f (diff)
downloadsrc-a80f65357463b353260d2d1f08da86dc6b85f181.tar.gz
src-a80f65357463b353260d2d1f08da86dc6b85f181.zip
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.
Notes
Notes: svn path=/head/; revision=118598
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 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);