summaryrefslogtreecommitdiffstats
path: root/sys/dev/en
diff options
context:
space:
mode:
authorkjc <kjc@FreeBSD.org>1999-05-08 14:23:40 +0000
committerkjc <kjc@FreeBSD.org>1999-05-08 14:23:40 +0000
commit2193f1d43473d72602aedf1ecdcb5552687edc6a (patch)
treee8d66bc24ca2964d1f748747343b92c17b401f26 /sys/dev/en
parentdda5cbbda41e442bf1eb739214a5c3ac36555d79 (diff)
downloadFreeBSD-src-2193f1d43473d72602aedf1ecdcb5552687edc6a.zip
FreeBSD-src-2193f1d43473d72602aedf1ecdcb5552687edc6a.tar.gz
clean up en atm driver
o fix DDB support - include "opt_ddb.h" - fix Debugger() arg pointed out by bde o back out pvc shadow interface support - it is currently not used - to make it easier to merge another implementation o misc minor cleanup
Diffstat (limited to 'sys/dev/en')
-rw-r--r--sys/dev/en/midway.c373
1 files changed, 54 insertions, 319 deletions
diff --git a/sys/dev/en/midway.c b/sys/dev/en/midway.c
index 9ce2401..a999ff5 100644
--- a/sys/dev/en/midway.c
+++ b/sys/dev/en/midway.c
@@ -46,32 +46,6 @@
* I would also like to thank Werner for promptly answering email and being
* generally helpful.
*/
-/*
- * 1997/12/02 kjc
- * new features added:
- * - support vc/vp shaping
- * - integrate IPv6 support.
- * - support pvc shadow interface
- * (initial work on per-pvc-interface for ipv6 was done
- * by Katsushi Kobayashi <ikob@cc.uec.ac.jp> of the WIDE Project,
- * extensively modified by kjc.)
- * code cleanup:
- * - remove WMAYBE related code. ENI WMAYBE DMA doen't work.
- * - drop support of FreeBSD-2.1.x and FreeBSD-3.0-SNAP-970124.
- * - remove updating if_lastchange for every packet.
- * - BPF related code is moved to midway.c as it should be.
- * (bpfwrite should work if atm_pseudohdr and LLC/SNAP are
- * prepended.)
- * - BPF link type is changed to DLT_ATM_RFC1483.
- * BPF now understands only LLC/SNAP!! (because bpf can't
- * handle variable link header length.)
- * It is recommended to use LLC/SNAP instead of NULL
- * encapsulation for various reasons. (BPF, IPv6,
- * interoperability, etc.)
- * - altq queue implementation is moved from the driver internal
- * queue to if_snd.
- * - AFMAP related code cleanup.
- */
#undef EN_DEBUG
#undef EN_DEBUG_RANGE /* check ranges on en_read/en_write's? */
@@ -135,6 +109,12 @@
#include "en.h"
#include "opt_inet.h"
#include "opt_natm.h"
+#include "opt_ddb.h"
+/* enable DDBHOOK when DDB is available */
+#undef EN_DDBHOOK
+#ifdef DDB
+#define EN_DDBHOOK 1
+#endif
#endif
#if NEN > 0 || !defined(__FreeBSD__)
@@ -146,6 +126,7 @@
#include <sys/device.h>
#endif
#include <sys/sockio.h>
+#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/proc.h>
@@ -315,14 +296,6 @@ STATIC INLINE int en_sz2b __P((int)) __attribute__ ((unused));
STATIC INLINE void en_write __P((struct en_softc *, u_int32_t,
u_int32_t)) __attribute__ ((unused));
-#ifdef ATM_PVCEXT
-static int en_txctl __P((struct en_softc *, int, int, int));
-static int en_pvctx __P((struct en_softc *, struct pvctxreq *));
-static int en_pvctxget __P((struct en_softc *, struct pvctxreq *));
-static int en_pcr2txspeed __P((int));
-static int en_txspeed2pcr __P((int));
-#endif
-
/*
* macros/inline
*/
@@ -450,10 +423,8 @@ u_int32_t r;
{
#ifdef EN_DEBUG_RANGE
- if (r > MID_MAXOFF || (r % 4)) {
- printf("en_read out of range, r=0x%x\n", r);
- panic("en_read");
- }
+ if (r > MID_MAXOFF || (r % 4))
+ panic("en_read out of range, r=0x%x", r);
#endif
return(bus_space_read_4(sc->en_memt, sc->en_base, r));
@@ -471,10 +442,8 @@ u_int32_t r, v;
{
#ifdef EN_DEBUG_RANGE
- if (r > MID_MAXOFF || (r % 4)) {
- printf("en_write out of range, r=0x%x\n", r);
- panic("en_write");
- }
+ if (r > MID_MAXOFF || (r % 4))
+ panic("en_write out of range, r=0x%x", r);
#endif
bus_space_write_4(sc->en_memt, sc->en_base, r, v);
@@ -1260,34 +1229,6 @@ caddr_t data;
break;
#endif /* SIOCSIFMTU */
-#ifdef ATM_PVCEXT
- case SIOCSPVCTX:
- if ((error = suser(curproc)) == 0)
- error = en_pvctx(sc, (struct pvctxreq *)data);
- break;
-
- case SIOCGPVCTX:
- error = en_pvctxget(sc, (struct pvctxreq *)data);
- break;
-
- case SIOCSPVCSIF:
- do {
- struct ifnet *shadow;
-
- if ((error = suser(curproc)) != 0)
- break;
-
- if ((shadow = pvc_attach(ifp)) != NULL) {
- snprintf(ifr->ifr_name, sizeof(ifr->ifr_name),
- "%s%d", shadow->if_name, shadow->if_unit);
- }
- else
- error = ENOBUFS;
- } while (0);
- break;
-
-#endif /* ATM_PVCEXT */
-
default:
error = EINVAL;
break;
@@ -2019,6 +1960,7 @@ int chan;
struct en_launch launch;
int datalen = 0, dtqneed, len, ncells;
u_int8_t *cp;
+ struct ifnet *ifp;
#ifdef EN_DEBUG
printf("%s: tx%d: starting...\n", sc->sc_dev.dv_xname, chan);
@@ -2162,7 +2104,9 @@ again:
*/
EN_COUNT(sc->launch);
- sc->enif.if_opackets++;
+ ifp = &sc->enif;
+ ifp->if_opackets++;
+
if ((launch.atm_flags & EN_OBHDR) == 0) {
EN_COUNT(sc->lheader);
/* store tbd1/tbd2 in host byte order */
@@ -2177,7 +2121,7 @@ again:
en_txlaunch(sc, chan, &launch);
#if NBPFILTER > 0
- if (sc->enif.if_bpf) {
+ if (ifp->if_bpf) {
/*
* adjust the top of the mbuf to skip the pseudo atm header
* (and TBD, if present) before passing the packet to bpf,
@@ -2190,7 +2134,7 @@ again:
launch.t->m_data += size;
launch.t->m_len -= size;
- BPF_MTAP(&sc->enif, launch.t);
+ BPF_MTAP(ifp, launch.t);
launch.t->m_data -= size;
launch.t->m_len += size;
@@ -2592,6 +2536,7 @@ void *arg;
struct en_softc *sc = (struct en_softc *) arg;
struct mbuf *m;
struct atm_pseudohdr ah;
+ struct ifnet *ifp;
u_int32_t reg, kick, val, mask, chip, vci, slot, dtq, drq;
int lcv, idx, need_softserv = 0;
@@ -2613,7 +2558,11 @@ void *arg;
sc->sc_dev.dv_xname, reg, MID_INTBITS);
#ifdef EN_DEBUG
#ifdef DDB
+#ifdef __FreeBSD__
+ Debugger("en: unexpected error");
+#else
Debugger();
+#endif
#endif /* DDB */
sc->enif.if_flags &= ~IFF_RUNNING; /* FREEZE! */
#else
@@ -2726,10 +2675,9 @@ void *arg;
m = NULL;
} else {
IF_DEQUEUE(&sc->rxslot[slot].indma, m);
- if (!m) {
- printf("%s: lost mbuf in slot %d!\n", sc->sc_dev.dv_xname, slot);
- panic("enintr: drqsync");
- }
+ if (!m)
+ panic("enintr: drqsync: %s: lost mbuf in slot %d!",
+ sc->sc_dev.dv_xname, slot);
}
/* do something with this mbuf */
if (sc->rxslot[slot].oth_flags & ENOTHER_DRAIN) { /* drain? */
@@ -2757,14 +2705,16 @@ void *arg;
sc->sc_dev.dv_xname, slot, sc->rxslot[slot].atm_vci, m,
EN_DQ_LEN(drq), sc->rxslot[slot].rxhand);
#endif
-#if NBPFILTER > 0
- if (sc->enif.if_bpf)
- BPF_MTAP(&sc->enif, m);
-#endif /* NBPFILTER > 0 */
- sc->enif.if_ipackets++;
+ ifp = &sc->enif;
+ ifp->if_ipackets++;
+
+#if NBPFILTER > 0
+ if (ifp->if_bpf)
+ BPF_MTAP(ifp, m);
+#endif
- atm_input(&sc->enif, &ah, m, sc->rxslot[slot].rxhand);
+ atm_input(ifp, &ah, m, sc->rxslot[slot].rxhand);
}
}
@@ -2954,7 +2904,7 @@ defer: /* defer processing */
llc = (aal5 && (sc->rxslot[slot].atm_flags & ATM_PH_LLCSNAP)) ? 1 : 0;
rbd = EN_READ(sc, cur);
if (MID_RBD_ID(rbd) != MID_RBD_STDID)
- panic("en_service: id mismatch\n");
+ panic("en_service: id mismatch");
if (rbd & MID_RBD_T) {
mlen = 0; /* we've got trash */
@@ -2967,6 +2917,8 @@ defer: /* defer processing */
mlen = MID_RBD_SIZE + MID_CHDR_SIZE + MID_ATMDATASZ; /* 1 cell (ick!) */
fill = 0;
} else {
+ struct ifnet *ifp;
+
tlen = (MID_RBD_CNT(rbd) * MID_ATMDATASZ) + MID_RBD_SIZE;
pdu = cur + tlen - MID_PDU_SIZE;
if (pdu >= stop)
@@ -2974,12 +2926,25 @@ defer: /* defer processing */
pdu = EN_READ(sc, pdu); /* get PDU in correct byte order */
fill = tlen - MID_RBD_SIZE - MID_PDU_LEN(pdu);
if (fill < 0 || (rbd & MID_RBD_CRCERR) != 0) {
- printf("%s: %s, dropping frame\n", sc->sc_dev.dv_xname,
- (rbd & MID_RBD_CRCERR) ? "CRC error" : "invalid AAL5 PDU length");
- printf("%s: got %d cells (%d bytes), AAL5 len is %d bytes (pdu=0x%x)\n",
- sc->sc_dev.dv_xname, MID_RBD_CNT(rbd), tlen - MID_RBD_SIZE,
- MID_PDU_LEN(pdu), pdu);
+ static int first = 1;
+
+ if (first) {
+ printf("%s: %s, dropping frame\n", sc->sc_dev.dv_xname,
+ (rbd & MID_RBD_CRCERR) ?
+ "CRC error" : "invalid AAL5 PDU length");
+ printf("%s: got %d cells (%d bytes), AAL5 len is %d bytes (pdu=0x%x)\n",
+ sc->sc_dev.dv_xname, MID_RBD_CNT(rbd),
+ tlen - MID_RBD_SIZE, MID_PDU_LEN(pdu), pdu);
+#ifndef EN_DEBUG
+ printf("CRC error report disabled from now on!\n");
+ first = 0;
+#endif
+ }
fill = tlen;
+
+ ifp = &sc->enif;
+ ifp->if_ierrors++;
+
}
mlen = tlen - fill;
}
@@ -3481,234 +3446,4 @@ int unit, addr, len;
}
#endif
-#ifdef ATM_PVCEXT
-/*
- * ATM PVC extention: shaper control and pvc shadow interfaces
- */
-
-/* txspeed conversion derived from linux drivers/atm/eni.c
- by Werner Almesberger, EPFL LRC */
-static const int pre_div[] = { 4,16,128,2048 };
-
-static int en_pcr2txspeed(pcr)
- int pcr;
-{
- int pre, res, div;
-
- if (pcr == 0 || pcr > 347222)
- pre = res = 0; /* max rate */
- else {
- for (pre = 0; pre < 3; pre++)
- if (25000000/pre_div[pre]/64 <= pcr)
- break;
- div = pre_div[pre]*(pcr);
-#if 1
- /*
- * the shaper value should be rounded down,
- * instead of rounded up.
- * (which means "res" should be rounded up.)
- */
- res = (25000000 + div -1)/div - 1;
-#else
- res = 25000000/div-1;
-#endif
- if (res < 0)
- res = 0;
- if (res > 63)
- res = 63;
- }
- return ((pre << 6) + res);
-}
-
-static int en_txspeed2pcr(txspeed)
- int txspeed;
-{
- int pre, res, pcr;
-
- pre = (txspeed >> 6) & 0x3;
- res = txspeed & 0x3f;
- pcr = 25000000 / pre_div[pre] / (res+1);
- return (pcr);
-}
-
-/*
- * en_txctl selects a hardware transmit channel and sets the shaper value.
- * en_txctl should be called after enabling the vc by en_rxctl
- * since it assumes a transmit channel is already assigned by en_rxctl
- * to the vc.
- */
-static int en_txctl(sc, vci, joint_vci, pcr)
- struct en_softc *sc;
- int vci;
- int joint_vci;
- int pcr;
-{
- int txspeed, txchan, c, s;
-
- if (pcr)
- txspeed = en_pcr2txspeed(pcr);
- else
- txspeed = 0;
-
- s = splimp();
- txchan = sc->txvc2slot[vci];
- sc->txslot[txchan].nref--;
-
- /* select a slot */
- if (joint_vci != 0)
- /* use the same channel */
- txchan = sc->txvc2slot[joint_vci];
- if (pcr == 0)
- txchan = 0;
- else {
- for (c = 1, txchan = 1; c < EN_NTX; c++) {
- if (sc->txslot[c].nref < sc->txslot[txchan].nref)
- txchan = c;
- if (sc->txslot[txchan].nref == 0)
- break;
- }
- }
- sc->txvc2slot[vci] = txchan;
- sc->txslot[txchan].nref++;
-
- /* set the shaper parameter */
- sc->txspeed[vci] = (u_int8_t)txspeed;
-
- splx(s);
-#ifdef EN_DEBUG
- printf("VCI:%d PCR set to %d, tx channel %d\n", vci, pcr, txchan);
- if (joint_vci != 0)
- printf(" slot shared with VCI:%d\n", joint_vci);
-#endif
- return (0);
-}
-
-static int en_pvctx(sc, pvcreq)
- struct en_softc *sc;
- struct pvctxreq *pvcreq;
-{
- struct ifnet *ifp;
- struct atm_pseudoioctl api;
- struct atm_pseudohdr *pvc_aph, *pvc_joint;
- int vci, joint_vci, pcr;
- int error = 0;
-
- /* check vpi:vci values */
- pvc_aph = &pvcreq->pvc_aph;
- pvc_joint = &pvcreq->pvc_joint;
-
- vci = ATM_PH_VCI(pvc_aph);
- joint_vci = ATM_PH_VCI(pvc_joint);
- pcr = pvcreq->pvc_pcr;
-
- if (ATM_PH_VPI(pvc_aph) != 0 || vci >= MID_N_VC ||
- ATM_PH_VPI(pvc_joint) != 0 || joint_vci >= MID_N_VC)
- return (EADDRNOTAVAIL);
-
- if ((ifp = ifunit(pvcreq->pvc_ifname)) == NULL)
- return (ENXIO);
-
- if (pcr < 0) {
- /* negative pcr means disable the vc. */
- if (sc->rxvc2slot[vci] == RX_NONE)
- /* already disabled */
- return 0;
-
- ATM_PH_FLAGS(&api.aph) = 0;
- ATM_PH_VPI(&api.aph) = 0;
- ATM_PH_SETVCI(&api.aph, vci);
- api.rxhand = NULL;
-
- error = en_rxctl(sc, &api, 0);
-
- if (error == 0 && &sc->enif != ifp) {
- /* clear vc info of shadow interface */
- ATM_PH_SETVCI(&api.aph, 0);
- pvc_setaph(ifp, &api.aph);
- }
- return (error);
- }
-
- if (&sc->enif == ifp) {
- /* called for an en interface */
- if (sc->rxvc2slot[vci] == RX_NONE) {
- /* vc is not active */
- printf("%s%d: en_pvctx: rx not active! vci=%d\n",
- ifp->if_name, ifp->if_unit, vci);
- return (EINVAL);
- }
- }
- else {
- /* called for a shadow interface */
- if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
- printf("en_pvctx: if %s is not point-to-point!\n",
- pvcreq->pvc_ifname);
- return (EINVAL);
- }
- snprintf(pvcreq->pvc_ifname, sizeof(pvcreq->pvc_ifname),
- "%s%d", sc->enif.if_name, sc->enif.if_unit);
-
- ATM_PH_FLAGS(&api.aph) = ATM_PH_PVCSIF |
- (ATM_PH_FLAGS(pvc_aph) & (ATM_PH_AAL5|ATM_PH_LLCSNAP));
- ATM_PH_VPI(&api.aph) = 0;
- ATM_PH_SETVCI(&api.aph, vci);
- api.rxhand = ifp;
- pvc_setaph(ifp, &api.aph);
-
- if (sc->rxvc2slot[vci] == RX_NONE) {
- /* vc is not active, enable rx */
- error = en_rxctl(sc, &api, 1);
- if (error)
- return error;
- }
- else {
- /* vc is already active, update aph in softc */
- sc->rxslot[sc->rxvc2slot[vci]].atm_flags =
- ATM_PH_FLAGS(&api.aph);
- }
-
- }
-
- error = en_txctl(sc, vci, joint_vci, pcr);
-
- if (error == 0) {
- if (sc->txspeed[vci] != 0)
- pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]);
- else
- pvcreq->pvc_pcr = 0;
- }
-
- return error;
-}
-
-static int en_pvctxget(sc, pvcreq)
- struct en_softc *sc;
- struct pvctxreq *pvcreq;
-{
- struct atm_pseudohdr *pvc_aph;
- int vci, slot;
-
- pvc_aph = &pvcreq->pvc_aph;
- vci = ATM_PH_VCI(pvc_aph);
-
- if ((slot = sc->rxvc2slot[vci]) == RX_NONE) {
- /* vc is not active */
- ATM_PH_FLAGS(pvc_aph) = 0;
- pvcreq->pvc_pcr = -1;
- }
- else {
- ATM_PH_FLAGS(pvc_aph) = sc->rxslot[slot].atm_flags;
- ATM_PH_VPI(pvc_aph) = 0;
- ATM_PH_SETVCI(pvc_aph, vci);
- if (sc->txspeed[vci])
- pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]);
- else
- pvcreq->pvc_pcr = 0;
- }
-
- return (0);
-}
-
-#endif /* ATM_PVCEXT */
-
#endif /* NEN > 0 || !defined(__FreeBSD__) */
OpenPOWER on IntegriCloud