diff options
author | phk <phk@FreeBSD.org> | 2000-07-22 17:08:52 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2000-07-22 17:08:52 +0000 |
commit | bdf9ed1bd66431cd8bce8550a99e46a60c673e78 (patch) | |
tree | c7a4ad9bfc08102b78488802b1b414d64746ee71 /sys/dev/musycc | |
parent | 4001ccb3a66ef1548ebbe1039feb82794d697200 (diff) | |
download | FreeBSD-src-bdf9ed1bd66431cd8bce8550a99e46a60c673e78.zip FreeBSD-src-bdf9ed1bd66431cd8bce8550a99e46a60c673e78.tar.gz |
Add transmit buffer limitation depending on actual bandwidth.
Add unframed E1 mode.
Various cleanup.
Diffstat (limited to 'sys/dev/musycc')
-rw-r--r-- | sys/dev/musycc/musycc.c | 273 |
1 files changed, 160 insertions, 113 deletions
diff --git a/sys/dev/musycc/musycc.c b/sys/dev/musycc/musycc.c index 952763f..e28a1dc 100644 --- a/sys/dev/musycc/musycc.c +++ b/sys/dev/musycc/musycc.c @@ -14,6 +14,7 @@ #include <sys/systm.h> #include <sys/conf.h> #include <sys/kernel.h> +#include <sys/sysctl.h> #include <sys/malloc.h> #include <sys/bus.h> #include <sys/mbuf.h> @@ -35,7 +36,17 @@ static MALLOC_DEFINE(M_MUSYCC, "musycc", "MUSYCC related"); -static void init_8370(u_int32_t *p); +static int maxlatency = 250; +SYSCTL_INT(_debug, OID_AUTO, musycc_maxlatency, CTLFLAG_RW, &maxlatency, 0, + "The number of milliseconds a packet is allowed to spend in the output q +ueue. " + "If the output queue is longer than this number of milliseconds when the + packet " + "arrives for output, the packet will be dropped." +); + +struct softc; +static void init_8370(struct softc *sc); static u_int32_t parse_ts(const char *s, int *nbit); /* @@ -129,6 +140,7 @@ struct schan { u_long rx_drop; /* mbuf allocation failures */ u_long tx_limit; + u_long tx_pending; int tx_next_md; /* index to the next MD */ int tx_last_md; /* index to the last MD */ int rx_last_md; /* index to next MD */ @@ -151,13 +163,13 @@ struct schan { int last_error; int prev_error; - u_long tx_pending; #endif }; +enum framing {WHOKNOWS, E1, E1U, T1, T1U}; struct softc { - enum {WHOKNOWS, E1, T1} framing; + enum framing framing; u_int32_t last; struct csoftc *csc; u_int32_t *ds8370; @@ -232,24 +244,24 @@ parse_ts(const char *s, int *nbit) char *p; r = 0; - j = 0; + j = -1; *nbit = 0; while(*s) { i = strtol(s, &p, 0); - if (i < 1 || i > 31) + if (i < 0 || i > 31) return (0); - while (j && j < i) { + while (j != -1 && j < i) { r |= 1 << j++; (*nbit)++; } - j = 0; + j = -1; r |= 1 << i; (*nbit)++; if (*p == ',') { s = p + 1; continue; } else if (*p == '-') { - j = i; + j = i + 1; s = p + 1; continue; } else if (!*p) { @@ -289,60 +301,63 @@ poke_847x(void *dummy) } static void -init_847x(struct csoftc *sc) +init_847x(struct csoftc *csc) { - struct softc *sif; - - printf("init_847x(%p)\n", sc); - sif = &sc->serial[0]; - sif->reg->gbp = vtophys(sc->ram); - sc->ram->glcd = 0x3f30; /* XXX: designer magic */ - sc->ram->iqp = vtophys(sc->iqd); - sc->ram->iql = NIQD - 1; - sif->reg->srd = 0x400; - sif->last = 0x400; - sc->ram->dacbp = 0; /* 32bit only */ + struct softc *sc; + + printf("init_847x(%p)\n", csc); + sc = &csc->serial[0]; + sc->reg->gbp = vtophys(csc->ram); + csc->ram->glcd = 0x3f30; /* XXX: designer magic */ + csc->ram->iqp = vtophys(csc->iqd); + csc->ram->iql = NIQD - 1; + sc->reg->srd = 0x400; + sc->last = 0x400; + csc->ram->dacbp = 0; /* 32bit only */ timeout(poke_847x, NULL, 30*hz); } static void -init_ctrl(struct softc *sif) +init_ctrl(struct softc *sc) { int i; - printf("init_ctrl(%p) [%s] [%08x]\n", sif, sif->nodename, sif->csc->reg->glcd); - init_8370(sif->ds8370); - tsleep(sif, PZERO | PCATCH, "ds8370", hz); - sif->reg->gbp = vtophys(sif->ram); - sif->ram->grcd = 0x00000001; /* RXENBL */ - sif->ram->grcd |= 0x00000002; /* TXENBL */ - sif->ram->grcd |= 0x00000004; /* SUBDSBL */ - sif->ram->grcd |= 0x00000008; /* OOFABT */ + printf("init_ctrl(%p) [%s] [%08x]\n", sc, sc->nodename, sc->csc->reg->glcd); + init_8370(sc); + tsleep(sc, PZERO | PCATCH, "ds8370", hz); + sc->reg->gbp = vtophys(sc->ram); + sc->ram->grcd = 0x00000001; /* RXENBL */ + sc->ram->grcd |= 0x00000002; /* TXENBL */ + sc->ram->grcd |= 0x00000004; /* SUBDSBL */ + if (sc->framing == E1 || sc->framing == T1) + sc->ram->grcd |= 0x00000008; /* OOFABT */ + else + sc->ram->grcd |= 0x00000000; /* !OOFABT */ #if 0 - sif->ram->grcd |= 0x00000010; /* MSKOOF */ - sif->ram->grcd |= 0x00000020; /* MSKCOFA */ + sc->ram->grcd |= 0x00000010; /* MSKOOF */ + sc->ram->grcd |= 0x00000020; /* MSKCOFA */ #endif - sif->ram->grcd |= 0x00000c00; /* POLLTH=3 */ + sc->ram->grcd |= 0x00000400; /* POLLTH=1 */ #if 0 - sif->ram->grcd |= 0x00008000; /* SFALIGN */ + sc->ram->grcd |= 0x00008000; /* SFALIGN */ #endif - sif->ram->mpd = 0; /* Memory Protection NI [5-18] */ + sc->ram->mpd = 0; /* Memory Protection NI [5-18] */ - sif->ram->pcd = 0x0000001; /* PORTMD=1 (E1/32ts) */ - sif->ram->pcd |= 0x0000000; /* XXX */ + sc->ram->pcd = 0x0000001; /* PORTMD=1 (E1/32ts) */ + sc->ram->pcd |= 0x0000000; /* XXX */ /* Message length descriptor */ /* XXX: MTU */ - sif->ram->mld = 1600; - sif->ram->mld |= (1600 << 16); + sc->ram->mld = 1600; + sc->ram->mld |= (1600 << 16); for (i = 0; i < NHDLC; i++) { - sif->ram->ttsm[i] = 0; - sif->ram->rtsm[i] = 0; + sc->ram->ttsm[i] = 0; + sc->ram->rtsm[i] = 0; } - sif->reg->srd = sif->last = 0x500; + sc->reg->srd = sc->last = 0x500; } /* @@ -350,9 +365,10 @@ init_ctrl(struct softc *sif) */ static void -init_8370(u_int32_t *p) +init_8370(struct softc *sc) { int i; + u_int32_t *p = sc->ds8370; p[0x001] = 0x80; /* CR0 - Reset */ DELAY(20); @@ -375,23 +391,47 @@ init_8370(u_int32_t *p) p[0x028] = 0xda; /* EQ_OUT - */ p[0x02a] = 0xa6; /* PRE_EQ - */ - p[0x040] = 0x09; /* RCRO - XXX */ + if (sc->framing == E1U || sc->framing == T1U) + p[0x040] = 0x49; /* RCRO - XXX */ + else + p[0x040] = 0x09; /* RCRO - XXX */ + p[0x041] = 0x00; /* RPATT - XXX */ p[0x045] = 0x00; /* RALM - XXX */ p[0x046] = 0x05; /* LATCH - LATCH_CNT|LATCH_ALM */ p[0x068] = 0x4c; /* TLIU_CR - TERM|Pulse=6 */ p[0x070] = 0x04; /* TCR0 - TFRAME=4 */ - p[0x071] = 0x51; /* TCR1 - TZCS */ - p[0x072] = 0x1b; /* TCR1 - INS_YEL|INS_MF|INS_CRC|INS_FBIT */ + + if (sc->framing == E1U || sc->framing == T1U) + p[0x071] = 0x41; /* TCR1 - TZCS */ + else + p[0x071] = 0x51; /* TCR1 - TZCS */ + + if (sc->framing == E1U || sc->framing == T1U) + p[0x072] = 0x00; + else + p[0x072] = 0x1b; /* TCR1 - INS_YEL|INS_MF|INS_CRC|INS_FBIT */ + p[0x073] = 0x00; /* TERROR */ p[0x074] = 0x00; /* TMAN */ - p[0x075] = 0x10; /* TALM - AUTO_YEL */ + + if (sc->framing == E1U || sc->framing == T1U) + p[0x075] = 0x0; /* TALM */ + else + p[0x075] = 0x10; /* TALM - AUTO_YEL */ + p[0x076] = 0x00; /* TPATT */ p[0x077] = 0x00; /* TLP */ p[0x090] = 0x05; /* CLAD_CR - XXX */ p[0x091] = 0x01; /* CSEL - 2048kHz */ + + if (sc->framing == E1U || sc->framing == T1U) + p[0x0a0] = 0x00; + if (sc->framing == E1U || sc->framing == T1U) + p[0x0a6] = 0x00; + p[0x0d0] = 0x46; /* SBI_CR - SBI=6 */ p[0x0d1] = 0x70; /* RSB_CR - XXX */ p[0x0d2] = 0x00; /* RSYNC_BIT - 0 */ @@ -436,8 +476,10 @@ musycc_intr0_tx_eom(struct softc *sc, int ch) if (status & 0x80000000) break; /* Not our mdesc, done */ m = md->m; - if (m) + if (m) { + sch->tx_pending -= m->m_pkthdr.len; m_freem(m); + } md->m = NULL; md->data = 0; md->status = 0; @@ -477,6 +519,8 @@ musycc_intr0_rx_eom(struct softc *sc, int ch) m = md->m; m->m_len = m->m_pkthdr.len = status & 0x3fff; error = (status >> 16) & 0xf; + if (error == 8 && (sc->framing == E1U || sc->framing == T1U)) + error = 0; if (error == 0) { MGETHDR(m2, M_DONTWAIT, MT_DATA); if (m2 != NULL) { @@ -604,29 +648,6 @@ musycc_intr1(void *arg) } /* - * High-Level stuff - */ - -static void -set_chan_e1(struct softc *sif, char *ret) -{ - if (sif->framing == E1) - return; - init_ctrl(sif); - sif->framing = E1; - return; -} - -static void -set_chan_t1(struct softc *sif, char *ret) -{ - if (sif->framing == T1) - return; - strcpy(ret, "Error: T1 framing not implemented\n"); - return; -} - -/* * NetGraph Stuff */ @@ -647,24 +668,32 @@ ng_shutdown(node_p nodep) static void ng_config(node_p node, char *set, char *ret) { - struct softc *sif; - sif = node->private; + struct softc *sc; + sc = node->private; - printf("%s: CONFIG %p %p\n", sif->nodename, set, ret); + printf("%s: CONFIG %p %p\n", sc->nodename, set, ret); if (set != NULL) { - printf("%s CONFIG SET [%s]\n", sif->nodename, set); - if (!strcmp(set, "line e1")) - set_chan_e1(sif, ret); - else if (!strcmp(set, "line t1")) - set_chan_t1(sif, ret); - else + printf("%s CONFIG SET [%s]\n", sc->nodename, set); + if (!strcmp(set, "line e1")) { + if (sc->framing != E1) { + sc->framing = E1; + init_ctrl(sc); + } + } else if (!strcmp(set, "line e1u")) { + if (sc->framing != E1U) { + sc->framing = E1U; + init_ctrl(sc); + } + } else { goto barf; + } + return; } - if (sif->framing == E1) + if (sc->framing == E1) strcat(ret, "line e1\n"); - if (sif->framing == T1) - strcat(ret, "line t1\n"); + else if (sc->framing == E1U) + strcat(ret, "line e1u\n"); return; barf: strcpy(ret, "Syntax Error\n"); @@ -739,13 +768,22 @@ ng_newhook(node_p node, hook_p hook, const char *name) sc = node->private; csc = sc->csc; - printf("Newhook(\"%s\",\"%s\")\n", sc->nodename, name); if (name[0] != 't' || name[1] != 's') return (EINVAL); ts = parse_ts(name + 2, &nbit); if (ts == 0) return (EINVAL); chan = ffs(ts) - 1; + printf("Newhook(\"%s\",\"%s\" chan=%d ts=%08x nbit=%d)\n", sc->nodename, name, chan, ts, nbit); +#if 1 + if (sc->framing == E1U && nbit == 32) + ; + else if (sc->framing == T1U && nbit == 24) + ; + else if (ts & 1) + return (EINVAL); +#endif + if (sc->chan[chan] == NULL) { MALLOC(sch, struct schan *, sizeof(*sch), M_MUSYCC, M_WAITOK); bzero(sch, sizeof(*sch)); @@ -784,30 +822,39 @@ ng_rcvdata(hook_p hook, struct mbuf *m, meta_p meta, struct mbuf **ret_m, meta_p NG_FREE_META(meta); meta = NULL; - /* XXX: check channel state */ + if (sch->state != UP) { + NG_FREE_DATA(m, meta); + return (0); + } + if (sch->tx_pending + m->m_pkthdr.len > sch->tx_limit * maxlatency) { + NG_FREE_DATA(m, meta); + return (0); + } m2 = m; len = m->m_pkthdr.len; while (len) { - md = &sc->mdt[ch][sch->tx_next_md]; + if (m->m_len > 0) { /* XXX: needed ? */ + md = &sc->mdt[ch][sch->tx_next_md]; - if (++sch->tx_next_md >= sch->nmd) - sch->tx_next_md = 0; + if (++sch->tx_next_md >= sch->nmd) + sch->tx_next_md = 0; - md->data = vtophys(m->m_data); - len -= m->m_len; - u = 0x80000000; /* OWNER = MUSYCC */ - if (len > 0) { - md->m = 0; - } else { - u |= 1 << 29; /* EOM */ - md->m = m2; - } - - u |= m->m_len; - md->status = u; + md->data = vtophys(m->m_data); + len -= m->m_len; + u = 0x80000000; /* OWNER = MUSYCC */ + if (len > 0) { + md->m = 0; + } else { + u |= 1 << 29; /* EOM */ + md->m = m2; + } + u |= m->m_len; + md->status = u; + } m = m->m_next; } + sch->tx_pending += m2->m_pkthdr.len; return (0); } @@ -1035,7 +1082,7 @@ musycc_attach(device_t self) { struct csoftc *csc; struct resource *res; - struct softc *sif; + struct softc *sc; int rid, i, error; int f; u_int32_t *u32p; @@ -1116,31 +1163,31 @@ musycc_attach(device_t self) u32p[0x1000] = 0xfe; /* XXX: control-register */ for (i = 0; i < csc->nchan; i++) { - sif = &csc->serial[i]; - sif->csc = csc; - sif->last = 0xffffffff; - sif->ds8370 = (u_int32_t *) + sc = &csc->serial[i]; + sc->csc = csc; + sc->last = 0xffffffff; + sc->ds8370 = (u_int32_t *) (csc->virbase[1] + i * 0x800); - sif->ds847x = csc->virbase[0] + i * 0x800; - sif->reg = (struct globalr *) + sc->ds847x = csc->virbase[0] + i * 0x800; + sc->reg = (struct globalr *) (csc->virbase[0] + i * 0x800); - MALLOC(sif->mycg, struct mycg *, + MALLOC(sc->mycg, struct mycg *, sizeof(struct mycg), M_MUSYCC, M_WAITOK); - bzero(sif->mycg, sizeof(struct mycg)); - sif->ram = &sif->mycg->cg; + bzero(sc->mycg, sizeof(struct mycg)); + sc->ram = &sc->mycg->cg; - error = ng_make_node_common(&ngtypestruct, &sif->node); + error = ng_make_node_common(&ngtypestruct, &sc->node); if (error) { printf("ng_make_node_common() failed %d\n", error); continue; } - sif->node->private = sif; - sprintf(sif->nodename, "pci%d-%d-%d-%d", + sc->node->private = sc; + sprintf(sc->nodename, "pci%d-%d-%d-%d", device_get_unit(device_get_parent(self)), csc->bus, csc->slot, i); - error = ng_name_node(sif->node, sif->nodename); + error = ng_name_node(sc->node, sc->nodename); } csc->ram = (struct globalr *)&csc->serial[0].mycg->cg; init_847x(csc); |