summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorchuck <chuck@cvs.openbsd.org>1996-06-27 04:27:50 +0000
committerchuck <chuck@cvs.openbsd.org>1996-06-27 04:27:50 +0000
commite9ed80a08bbb6cd8a13097c9e3478134b83910a4 (patch)
treebee01f5bb2c31058fec1a63102f2c06b7742b580 /sys/dev/ic
parentf5ae657df2ce0ee025ca9ec9c7cefad3c438273b (diff)
fixes/improvements:
- more stat counters (rxmbufout -- mbufs, ttrash -- trashed RBD) - add swsl_size to keep track of size of software slist - revise when we call en_service - fix handling of circular lists (was getting full vs empty confused in extreem cases...) - native mode atm: remove sbappend code: can't do it here since socket buffer is protected only by splsoftnet and that doesn't mask enintr off. forces us to switch to a two level interrupt scheme. revise call to atm_input to reflect that.
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/midway.c157
-rw-r--r--sys/dev/ic/midwayvar.h7
2 files changed, 85 insertions, 79 deletions
diff --git a/sys/dev/ic/midway.c b/sys/dev/ic/midway.c
index 519ba17057c..09548b10549 100644
--- a/sys/dev/ic/midway.c
+++ b/sys/dev/ic/midway.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: midway.c,v 1.3 1996/06/26 04:06:59 chuck Exp $ */
-/* (sync'd to midway.c 1.52) */
+/* $OpenBSD: midway.c,v 1.4 1996/06/27 04:27:49 chuck Exp $ */
+/* (sync'd to midway.c 1.53) */
/*
*
@@ -640,10 +640,10 @@ done_probe:
}
#ifdef EN_STAT
- sc->vtrash = sc->otrash = sc->mfix = sc->txmbovr = sc->dmaovr = sc->ddrop = 0;
+ sc->vtrash = sc->otrash = sc->mfix = sc->txmbovr = sc->dmaovr = 0;
sc->txoutspace = sc->txdtqout = sc->launch = sc->lheader = sc->ltail = 0;
sc->hwpull = sc->swadd = sc->rxqnotus = sc->rxqus = sc->rxoutboth = 0;
- sc->rxdrqout = 0;
+ sc->rxdrqout = sc->ttrash = sc->rxmbufout = 0;
#endif
sc->need_drqs = sc->need_dtqs = 0;
@@ -1148,7 +1148,7 @@ struct en_softc *sc;
sc->dtq_us = sc->dtq_chip;
sc->hwslistp = MID_SL_REG2A(EN_READ(sc, MID_SERV_WRITE));
- sc->swsl_head = sc->swsl_tail = 0;
+ sc->swsl_size = sc->swsl_head = sc->swsl_tail = 0;
#ifdef EN_DEBUG
printf("%s: drq free/chip: %d/0x%x, dtq free/chip: %d/0x%x, hwslist: 0x%x\n",
@@ -1870,7 +1870,7 @@ void *arg;
struct mbuf *m;
struct atm_pseudohdr ah;
u_int32_t reg, kick, val, mask, chip, vci, slot, dtq, drq;
- int lcv, idx, something_added;
+ int lcv, idx, need_softserv = 0;
reg = EN_READ(sc, MID_INTACK);
@@ -1946,7 +1946,7 @@ void *arg;
printf("%s: cleared need DTQ condition\n", sc->sc_dev.dv_xname);
#endif
}
- while (idx != val) {
+ do { /* while idx != val */
sc->dtq_free++;
if ((dtq = sc->dtq[idx]) != 0) {
sc->dtq[idx] = 0; /* don't forget to zero it out when done */
@@ -1962,7 +1962,7 @@ void *arg;
m_freem(m);
}
EN_WRAPADD(0, MID_DTQ_N, idx, 1);
- }
+ } while (idx != val);
sc->dtq_chip = MID_DTQ_REG2A(val); /* sync softc */
}
@@ -1994,7 +1994,7 @@ void *arg;
if (reg & MID_INT_DMA_RX) {
val = EN_READ(sc, MID_DMA_RDRX); /* chip's current location */
idx = MID_DRQ_A2REG(sc->drq_chip);/* where we last saw chip */
- while (idx != val) {
+ do { /* while (idx != val) */
sc->drq_free++;
if ((drq = sc->drq[idx]) != 0) {
sc->drq[idx] = 0; /* don't forget to zero it out when done */
@@ -2006,59 +2006,39 @@ void *arg;
}
/* do something with this mbuf */
- if (sc->rxslot[slot].rxso) {
- if (sbspace(&sc->rxslot[slot].rxso->so_rcv) >
- EN_DQ_LEN(drq)) {
- sbappend(&sc->rxslot[slot].rxso->so_rcv, m);
- sorwakeup(sc->rxslot[slot].rxso);
-#ifdef EN_DEBUG
- printf("%s: tx%d: sbappend 0x%x, vci=%d\n", sc->sc_dev.dv_xname,
- slot, sc->rxslot[slot].rxso, sc->rxslot[slot].atm_vci);
-#endif
- } else {
- m_freem(m);
- EN_COUNT(sc->ddrop); /* count it */
-#ifdef EN_DEBUG
- printf("%s: tx%d: sbappend DROP 0x%x, vci=%d\n",
- sc->sc_dev.dv_xname, slot,
- sc->rxslot[slot].rxso, sc->rxslot[slot].atm_vci);
-#endif
- }
- } else {
- if (sc->rxslot[slot].oth_flags & ENOTHER_DRAIN) { /* drain? */
- m_freem(m);
- if (sc->rxslot[slot].indma.ifq_head == NULL &&
+ if (sc->rxslot[slot].oth_flags & ENOTHER_DRAIN) { /* drain? */
+ m_freem(m);
+ if (sc->rxslot[slot].indma.ifq_head == NULL &&
sc->rxslot[slot].q.ifq_head == NULL &&
(EN_READ(sc, MID_VC(vci)) & MIDV_INSERVICE) == 0 &&
(sc->rxslot[slot].oth_flags & ENOTHER_SWSL) == 0) {
- sc->rxslot[slot].oth_flags = ENOTHER_FREE; /* done drain */
- sc->rxslot[slot].atm_vci = RX_NONE;
- sc->rxvc2slot[vci] = RX_NONE;
+ sc->rxslot[slot].oth_flags = ENOTHER_FREE; /* done drain */
+ sc->rxslot[slot].atm_vci = RX_NONE;
+ sc->rxvc2slot[vci] = RX_NONE;
#ifdef EN_DEBUG
- printf("%s: rx%d: VCI %d now free\n", sc->sc_dev.dv_xname,
+ printf("%s: rx%d: VCI %d now free\n", sc->sc_dev.dv_xname,
slot, vci);
#endif
- }
- } else {
- ATM_PH_FLAGS(&ah) = sc->rxslot[slot].atm_flags;
- ATM_PH_VPI(&ah) = 0;
- ATM_PH_SETVCI(&ah, sc->rxslot[slot].atm_vci);
+ }
+ } else {
+ ATM_PH_FLAGS(&ah) = sc->rxslot[slot].atm_flags;
+ ATM_PH_VPI(&ah) = 0;
+ ATM_PH_SETVCI(&ah, sc->rxslot[slot].atm_vci);
#ifdef EN_DEBUG
- printf("%s: rx%d: rxvci%d: atm_input, mbuf 0x%x, len %d\n",
+ printf("%s: rx%d: rxvci%d: atm_input, mbuf 0x%x, len %d, sok 0x%x\n",
sc->sc_dev.dv_xname, slot, sc->rxslot[slot].atm_vci, m,
- EN_DQ_LEN(drq));
+ EN_DQ_LEN(drq), sc->rxslot[slot].rxso);
#endif
- atm_input(&sc->enif, &ah, m);
- }
+ atm_input(&sc->enif, &ah, m, sc->rxslot[slot].rxso);
}
}
EN_WRAPADD(0, MID_DRQ_N, idx, 1);
- }
+ } while (idx != val);
sc->drq_chip = MID_DRQ_REG2A(val); /* sync softc */
if (sc->need_drqs) { /* true if we had a DRQ shortage */
- reg |= MID_INT_SERVICE;
+ need_softserv = 1;
sc->need_drqs = 0;
#ifdef EN_DEBUG
printf("%s: cleared need DRQ condition\n", sc->sc_dev.dv_xname);
@@ -2072,9 +2052,8 @@ void *arg;
if (reg & MID_INT_SERVICE) {
chip = MID_SL_REG2A(EN_READ(sc, MID_SERV_WRITE));
- something_added = 0;
- while (sc->hwslistp != chip) {
+ do { /* while sc->hwslistp != chip */
/* fetch and remove it from hardware service list */
vci = EN_READ(sc, sc->hwslistp);
@@ -2095,23 +2074,24 @@ void *arg;
/* add it to the software service list (if needed) */
if ((sc->rxslot[slot].oth_flags & ENOTHER_SWSL) == 0) {
EN_COUNT(sc->swadd);
- something_added = 1;
+ need_softserv = 1;
sc->rxslot[slot].oth_flags |= ENOTHER_SWSL;
sc->swslist[sc->swsl_tail] = slot;
EN_WRAPADD(0, MID_SL_N, sc->swsl_tail, 1);
+ sc->swsl_size++;
#ifdef EN_DEBUG
printf("%s: added VCI %d to swslist\n", sc->sc_dev.dv_xname, vci);
#endif
}
- }
+ } while (sc->hwslistp != chip);
+ }
- /*
- * now service (function too big to include here)
- */
+ /*
+ * now service (function too big to include here)
+ */
- if (something_added || (reg & MID_INT_DMA_RX) != 0)
- en_service(sc);
- }
+ if (need_softserv)
+ en_service(sc);
/*
* keep our stats
@@ -2162,7 +2142,7 @@ struct en_softc *sc;
int slot, raw, aal5, llc, vci, fill, mlen, tlen, drqneed, need, needfill;
next_vci:
- if (sc->swsl_head == sc->swsl_tail) {
+ if (sc->swsl_size == 0) {
#ifdef EN_DEBUG
printf("%s: en_service done\n", sc->sc_dev.dv_xname);
#endif
@@ -2201,6 +2181,7 @@ same_vci:
if (dstart == cur) {
EN_WRAPADD(0, MID_SL_N, sc->swsl_head, 1);
sc->rxslot[slot].oth_flags &= ~ENOTHER_SWSL;
+ sc->swsl_size--;
/* >>> remove from swslist <<< */
#ifdef EN_DEBUG
printf("%s: rx%d: remove vci %d from swslist\n",
@@ -2235,6 +2216,7 @@ same_vci:
if (rbd & MID_RBD_T) {
mlen = 0; /* we've got trash */
fill = MID_RBD_SIZE;
+ EN_COUNT(sc->ttrash);
} else if (!aal5) {
mlen = MID_RBD_SIZE + MID_CHDR_SIZE + MID_ATMDATASZ; /* 1 cell (ick!) */
fill = 0;
@@ -2289,6 +2271,7 @@ same_vci:
if (m == NULL) {
fill += mlen;
mlen = 0;
+ EN_COUNT(sc->rxmbufout);
#ifdef EN_DEBUG
printf("%s: rx%d: out of mbufs\n", sc->sc_dev.dv_xname, slot);
#endif
@@ -2471,14 +2454,16 @@ same_vci:
*/
done:
- if (!raw && m) {
- cnt = MID_RBD_SIZE;
- if (!aal5) cnt += MID_CHDR_SIZE;
- m->m_len -= cnt; /* chop! */
- m->m_pkthdr.len -= cnt;
- m->m_data += cnt;
+ if (m) {
+ if (!raw) {
+ cnt = MID_RBD_SIZE;
+ if (!aal5) cnt += MID_CHDR_SIZE;
+ m->m_len -= cnt; /* chop! */
+ m->m_pkthdr.len -= cnt;
+ m->m_data += cnt;
+ }
+ IF_ENQUEUE(&sc->rxslot[slot].indma, m);
}
- IF_ENQUEUE(&sc->rxslot[slot].indma, m);
sc->rxslot[slot].cur = cur; /* update master copy of 'cur' */
#ifdef EN_DEBUG
@@ -2495,10 +2480,16 @@ done:
* functions we can call from ddb
*/
+#ifdef NATM
+#include <netinet/in.h>
+#include <netnatm/natm.h>
+#endif
+
/*
* en_dump: dump the state
*/
+#define END_SWSL 0x00000040 /* swsl state */
#define END_DRQ 0x00000020 /* drq state */
#define END_DTQ 0x00000010 /* dtq state */
#define END_RX 0x00000008 /* rx state */
@@ -2506,7 +2497,7 @@ done:
#define END_MREGS 0x00000002 /* registers */
#define END_STATS 0x00000001 /* dump stats */
-#define END_BITS "\20\6DRQ\5DTQ\4RX\3TX\2MREGS\1STATS"
+#define END_BITS "\20\7SWSL\6DRQ\5DTQ\4RX\3TX\2MREGS\1STATS"
int en_dump(unit, level)
@@ -2533,12 +2524,8 @@ int unit, level;
if (level & END_STATS) {
printf(" en_stats:\n");
- printf(" %d cells trashed due to turned off rxvc\n", sc->vtrash);
- printf(" %d cells trashed due to totally full buffer\n", sc->otrash);
printf(" %d mbufs fixed by mfix (should be zero)\n", sc->mfix);
- printf(" %d trasmit packets dropped due mbsize\n", sc->txmbovr);
printf(" %d rx dma overflow interrupts\n", sc->dmaovr);
- printf(" %d packets droped due to sbsize being full\n", sc->ddrop);
printf(" %d times we ran out of TX space and stalled\n",
sc->txoutspace);
printf(" %d times we ran out of DTQs\n", sc->txdtqout);
@@ -2553,6 +2540,19 @@ int unit, level;
printf(" %d times RX pulled a good mbuf from Q\n", sc->rxqus);
printf(" %d times we ran out of mbufs *and* DRQs\n", sc->rxoutboth);
printf(" %d times we ran out of DRQs\n", sc->rxdrqout);
+
+ printf(" %d trasmit packets dropped due to mbsize\n", sc->txmbovr);
+ printf(" %d cells trashed due to turned off rxvc\n", sc->vtrash);
+ printf(" %d cells trashed due to totally full buffer\n", sc->otrash);
+ printf(" %d cells trashed due almost full buffer\n", sc->ttrash);
+ printf(" %d rx mbuf allocation failures\n", sc->rxmbufout);
+#ifdef NATM
+ printf(" %d drops at natmintrq\n", natmintrq.ifq_drops);
+#ifdef NATM_STAT
+ printf(" natmintr so_rcv: ok/drop cnt: %d/%d, ok/drop bytes: %d/%d\n",
+ natm_sookcnt, natm_sodropcnt, natm_sookbytes, natm_sodropbytes);
+#endif
+#endif
}
if (level & END_MREGS) {
@@ -2585,11 +2585,6 @@ int unit, level;
printf(" %d->%d", cnt, sc->rxvc2slot[cnt]);
printf("\n");
- printf(" swslist: ");
- for (cnt = sc->swsl_tail ; cnt != sc->swsl_head ;
- cnt = (cnt + 1) % MID_SL_N)
- printf("0x%x ", sc->swslist[cnt]);
- printf("\n");
}
if (level & END_TX) {
@@ -2624,7 +2619,8 @@ int unit, level;
}
if (level & END_DTQ) {
- printf(" dtq:\n");
+ printf(" dtq [need_dtqs=%d,dtq_free=%d]:\n",
+ sc->need_dtqs, sc->dtq_free);
ptr = sc->dtq_chip;
while (ptr != sc->dtq_us) {
reg = EN_READ(sc, ptr);
@@ -2636,7 +2632,8 @@ int unit, level;
}
if (level & END_DRQ) {
- printf(" drq:\n");
+ printf(" drq [need_drqs=%d,drq_free=%d]:\n",
+ sc->need_drqs, sc->drq_free);
ptr = sc->drq_chip;
while (ptr != sc->drq_us) {
reg = EN_READ(sc, ptr);
@@ -2647,6 +2644,14 @@ int unit, level;
}
}
+ if (level & END_SWSL) {
+ printf(" swslist [size=%d]: ", sc->swsl_size);
+ for (cnt = sc->swsl_head ; cnt != sc->swsl_tail ;
+ cnt = (cnt + 1) % MID_SL_N)
+ printf("0x%x ", sc->swslist[cnt]);
+ printf("\n");
+ }
+
}
return(0);
}
diff --git a/sys/dev/ic/midwayvar.h b/sys/dev/ic/midwayvar.h
index 5cd5bead839..f1dc6569b77 100644
--- a/sys/dev/ic/midwayvar.h
+++ b/sys/dev/ic/midwayvar.h
@@ -1,5 +1,4 @@
-/* $OpenBSD: midwayvar.h,v 1.2 1996/06/21 21:36:33 chuck Exp $ */
-/* (sync'd to midwayvar.h 1.4) */
+/* $OpenBSD: midwayvar.h,v 1.3 1996/06/27 04:27:48 chuck Exp $ */
/*
*
@@ -78,6 +77,7 @@ struct en_softc {
u_int16_t swslist[MID_SL_N]; /* software service list (see en_service()) */
u_int16_t swsl_head, /* ends of swslist (index into swslist) */
swsl_tail;
+ u_int32_t swsl_size; /* # of items in swsl */
/* xmit dma */
@@ -127,10 +127,10 @@ struct en_softc {
/* stats */
u_int32_t vtrash; /* sw copy of counter */
u_int32_t otrash; /* sw copy of counter */
+ u_int32_t ttrash; /* # of RBD's with T bit set */
u_int32_t mfix; /* # of times we had to call mfix */
u_int32_t txmbovr; /* # of times we dropped due to mbsize */
u_int32_t dmaovr; /* tx dma overflow count */
- u_int32_t ddrop; /* # of direct deposit drops due to sbsize */
u_int32_t txoutspace; /* out of space in xmit buffer */
u_int32_t txdtqout; /* out of DTQs */
u_int32_t launch; /* total # of launches */
@@ -142,6 +142,7 @@ struct en_softc {
u_int32_t rxqus; /* # of good pulls from rx q */
u_int32_t rxoutboth; /* # of times out of mbufs and DRQs */
u_int32_t rxdrqout; /* # of times out of DRQs */
+ u_int32_t rxmbufout; /* # of time out of mbufs */
/* random stuff */
u_int32_t ipl; /* sbus interrupt lvl (1 on pci?) */