Deleted Added
full compact
midway.c (35210) midway.c (37939)
1/* $NetBSD: midway.c,v 1.25 1997/03/20 21:34:42 chuck Exp $ */
2/* (sync'd to midway.c 1.67) */
1/* $NetBSD: midway.c,v 1.30 1997/09/29 17:40:38 chuck Exp $ */
2/* (sync'd to midway.c 1.68) */
3
4/*
5 *
6 * Copyright (c) 1996 Charles D. Cranor and Washington University.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions

--- 30 unchanged lines hidden (view full) ---

41 * started: spring, 1996 (written from scratch).
42 *
43 * notes from the author:
44 * Extra special thanks go to Werner Almesberger, EPFL LRC. Werner's
45 * ENI driver was especially useful in figuring out how this card works.
46 * I would also like to thank Werner for promptly answering email and being
47 * generally helpful.
48 */
3
4/*
5 *
6 * Copyright (c) 1996 Charles D. Cranor and Washington University.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions

--- 30 unchanged lines hidden (view full) ---

41 * started: spring, 1996 (written from scratch).
42 *
43 * notes from the author:
44 * Extra special thanks go to Werner Almesberger, EPFL LRC. Werner's
45 * ENI driver was especially useful in figuring out how this card works.
46 * I would also like to thank Werner for promptly answering email and being
47 * generally helpful.
48 */
49/*
50 * 1997/12/02 kjc
51 * new features added:
52 * - support vc/vp shaping
53 * - integrate IPv6 support.
54 * - support pvc shadow interface
55 * (initial work on per-pvc-interface for ipv6 was done
56 * by Katsushi Kobayashi <ikob@cc.uec.ac.jp> of the WIDE Project,
57 * extensively modified by kjc.)
58 * code cleanup:
59 * - remove WMAYBE related code. ENI WMAYBE DMA doen't work.
60 * - drop support of FreeBSD-2.1.x and FreeBSD-3.0-SNAP-970124.
61 * - remove updating if_lastchange for every packet.
62 * - BPF related code is moved to midway.c as it should be.
63 * (bpfwrite should work if atm_pseudohdr and LLC/SNAP are
64 * prepended.)
65 * - BPF link type is changed to DLT_ATM_RFC1483.
66 * BPF now understands only LLC/SNAP!! (because bpf can't
67 * handle variable link header length.)
68 * It is recommended to use LLC/SNAP instead of NULL
69 * encapsulation for various reasons. (BPF, IPv6,
70 * interoperability, etc.)
71 * - altq queue implementation is moved from the driver internal
72 * queue to if_snd.
73 * - AFMAP related code cleanup.
74 */
49
75
50
51#undef EN_DEBUG
52#undef EN_DEBUG_RANGE /* check ranges on en_read/en_write's? */
53#define EN_MBUF_OPT /* try and put more stuff in mbuf? */
54#define EN_DIAG
55#define EN_STAT
56#ifndef EN_DMA
57#define EN_DMA 1 /* use dma? */
58#endif
59#define EN_NOTXDMA 0 /* hook to disable tx dma only */
60#define EN_NORXDMA 0 /* hook to disable rx dma only */
76#undef EN_DEBUG
77#undef EN_DEBUG_RANGE /* check ranges on en_read/en_write's? */
78#define EN_MBUF_OPT /* try and put more stuff in mbuf? */
79#define EN_DIAG
80#define EN_STAT
81#ifndef EN_DMA
82#define EN_DMA 1 /* use dma? */
83#endif
84#define EN_NOTXDMA 0 /* hook to disable tx dma only */
85#define EN_NORXDMA 0 /* hook to disable rx dma only */
61#define EN_NOWMAYBE 1 /* hook to disable word maybe DMA */
62 /* XXX: WMAYBE doesn't work, needs debugging */
63#define EN_DDBHOOK 1 /* compile in ddb functions */
86#define EN_DDBHOOK 1 /* compile in ddb functions */
64#ifdef __FreeBSD__
65/* somehow, misaligned DMA doesn't work on FreeBSD with ENI card.
66 * not sure if this is specific to FreeBSD.
67 * anyway, always fix unaligned or word fragmented mbufs. --kjc */
68#define EN_FIXMBUF
87#if defined(MIDWAY_ADPONLY)
88#define EN_ENIDMAFIX 0 /* no ENI cards to worry about */
89#else
90#define EN_ENIDMAFIX 1 /* avoid byte DMA on the ENI card (see below) */
69#endif
70
91#endif
92
93/*
94 * note on EN_ENIDMAFIX: the byte aligner on the ENI version of the card
95 * appears to be broken. it works just fine if there is no load... however
96 * when the card is loaded the data get corrupted. to see this, one only
97 * has to use "telnet" over ATM. do the following command in "telnet":
98 * cat /usr/share/misc/termcap
99 * "telnet" seems to generate lots of 1023 byte mbufs (which make great
100 * use of the byte aligner). watch "netstat -s" for checksum errors.
101 *
102 * I further tested this by adding a function that compared the transmit
103 * data on the card's SRAM with the data in the mbuf chain _after_ the
104 * "transmit DMA complete" interrupt. using the "telnet" test I got data
105 * mismatches where the byte-aligned data should have been. using ddb
106 * and en_dumpmem() I verified that the DTQs fed into the card were
107 * absolutely correct. thus, we are forced to concluded that the ENI
108 * hardware is buggy. note that the Adaptec version of the card works
109 * just fine with byte DMA.
110 *
111 * bottom line: we set EN_ENIDMAFIX to 1 to avoid byte DMAs on the ENI
112 * card.
113 */
114
71#if defined(DIAGNOSTIC) && !defined(EN_DIAG)
72#define EN_DIAG /* link in with master DIAG option */
73#endif
74#ifdef EN_STAT
75#define EN_COUNT(X) (X)++
76#else
77#define EN_COUNT(X) /* nothing */
78#endif

--- 13 unchanged lines hidden (view full) ---

92#include "opt_inet.h"
93#include "opt_natm.h"
94#endif
95
96#if NEN > 0 || !defined(__FreeBSD__)
97
98#include <sys/param.h>
99#include <sys/systm.h>
115#if defined(DIAGNOSTIC) && !defined(EN_DIAG)
116#define EN_DIAG /* link in with master DIAG option */
117#endif
118#ifdef EN_STAT
119#define EN_COUNT(X) (X)++
120#else
121#define EN_COUNT(X) /* nothing */
122#endif

--- 13 unchanged lines hidden (view full) ---

136#include "opt_inet.h"
137#include "opt_natm.h"
138#endif
139
140#if NEN > 0 || !defined(__FreeBSD__)
141
142#include <sys/param.h>
143#include <sys/systm.h>
144#include <sys/queue.h>
100#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
101#include <sys/device.h>
102#endif
103#include <sys/sockio.h>
104#include <sys/mbuf.h>
105#include <sys/socket.h>
145#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
146#include <sys/device.h>
147#endif
148#include <sys/sockio.h>
149#include <sys/mbuf.h>
150#include <sys/socket.h>
151#include <sys/proc.h>
106
107#include <net/if.h>
108#include <net/if_atm.h>
109
110#include <vm/vm.h>
111
152
153#include <net/if.h>
154#include <net/if_atm.h>
155
156#include <vm/vm.h>
157
112#ifdef INET
158#if defined(INET) || defined(INET6)
159#include <netinet/in.h>
113#include <netinet/if_atm.h>
114#endif
115
116#ifdef NATM
160#include <netinet/if_atm.h>
161#endif
162
163#ifdef NATM
117#include <netinet/in.h>
118#include <netnatm/natm.h>
119#endif
120
164#include <netnatm/natm.h>
165#endif
166
121
122#if !defined(sparc) && !defined(__FreeBSD__)
123#include <machine/bus.h>
124#endif
125
126#if defined(__NetBSD__) || defined(__OpenBSD__)
127#include <dev/ic/midwayreg.h>
128#include <dev/ic/midwayvar.h>
129#if defined(__alpha__)
130/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
131#undef vtophys
132#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
133#endif
134#elif defined(__FreeBSD__)
135#include <machine/clock.h> /* for DELAY */
136#include <dev/en/midwayreg.h>
137#include <dev/en/midwayvar.h>
138#include <vm/pmap.h> /* for vtophys proto */
139
167#if !defined(sparc) && !defined(__FreeBSD__)
168#include <machine/bus.h>
169#endif
170
171#if defined(__NetBSD__) || defined(__OpenBSD__)
172#include <dev/ic/midwayreg.h>
173#include <dev/ic/midwayvar.h>
174#if defined(__alpha__)
175/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
176#undef vtophys
177#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va))
178#endif
179#elif defined(__FreeBSD__)
180#include <machine/clock.h> /* for DELAY */
181#include <dev/en/midwayreg.h>
182#include <dev/en/midwayvar.h>
183#include <vm/pmap.h> /* for vtophys proto */
184
140/*
141 * 2.1.x does not have if_softc. detect this by seeing if IFF_NOTRAILERS
142 * is defined, as per kjc.
143 */
144#ifdef IFF_NOTRAILERS
145#define MISSING_IF_SOFTC
146#else
185#ifndef IFF_NOTRAILERS
147#define IFF_NOTRAILERS 0
148#endif
149
150#endif /* __FreeBSD__ */
151
186#define IFF_NOTRAILERS 0
187#endif
188
189#endif /* __FreeBSD__ */
190
191#include "bpfilter.h"
192#if NBPFILTER > 0
193#include <net/bpf.h>
194#ifdef __FreeBSD__
195#define BPFATTACH(ifp, dlt, hlen) bpfattach((ifp), (dlt), (hlen))
196#define BPF_MTAP(ifp, m) bpf_mtap((ifp), (m))
197#else
198#define BPFATTACH(ifp, dlt, hlen) bpfattach(&(ifp)->if_bpf, (ifp), (dlt), (hlen))
199#define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
200#endif
201#endif /* NBPFILTER > 0 */
202
152/*
153 * params
154 */
155
156#ifndef EN_TXHIWAT
157#define EN_TXHIWAT (64*1024) /* max 64 KB waiting to be DMAd out */
158#endif
159

--- 41 unchanged lines hidden (view full) ---

201 u_int32_t atm_vci; /* vci */
202 u_int8_t atm_flags; /* flags */
203};
204
205
206/*
207 * dma table (index by # of words)
208 *
203/*
204 * params
205 */
206
207#ifndef EN_TXHIWAT
208#define EN_TXHIWAT (64*1024) /* max 64 KB waiting to be DMAd out */
209#endif
210

--- 41 unchanged lines hidden (view full) ---

252 u_int32_t atm_vci; /* vci */
253 u_int8_t atm_flags; /* flags */
254};
255
256
257/*
258 * dma table (index by # of words)
259 *
209 * plan A: use WMAYBE
260 * plan A: use WMAYBE (obsolete)
210 * plan B: avoid WMAYBE
211 */
212
213struct en_dmatab {
214 u_int8_t bcode; /* code */
215 u_int8_t divshift; /* byte divisor */
216};
217
261 * plan B: avoid WMAYBE
262 */
263
264struct en_dmatab {
265 u_int8_t bcode; /* code */
266 u_int8_t divshift; /* byte divisor */
267};
268
218static struct en_dmatab en_dma_planA[] = {
219 { 0, 0 }, /* 0 */ { MIDDMA_WORD, 2 }, /* 1 */
220 { MIDDMA_2WORD, 3}, /* 2 */ { MIDDMA_4WMAYBE, 2}, /* 3 */
221 { MIDDMA_4WORD, 4}, /* 4 */ { MIDDMA_8WMAYBE, 2}, /* 5 */
222 { MIDDMA_8WMAYBE, 2}, /* 6 */ { MIDDMA_8WMAYBE, 2}, /* 7 */
223 { MIDDMA_8WORD, 5}, /* 8 */ { MIDDMA_16WMAYBE, 2}, /* 9 */
224 { MIDDMA_16WMAYBE,2}, /* 10 */ { MIDDMA_16WMAYBE, 2}, /* 11 */
225 { MIDDMA_16WMAYBE,2}, /* 12 */ { MIDDMA_16WMAYBE, 2}, /* 13 */
226 { MIDDMA_16WMAYBE,2}, /* 14 */ { MIDDMA_16WMAYBE, 2}, /* 15 */
227 { MIDDMA_16WORD, 6}, /* 16 */
228};
229
230static struct en_dmatab en_dma_planB[] = {
231 { 0, 0 }, /* 0 */ { MIDDMA_WORD, 2}, /* 1 */
232 { MIDDMA_2WORD, 3}, /* 2 */ { MIDDMA_WORD, 2}, /* 3 */
233 { MIDDMA_4WORD, 4}, /* 4 */ { MIDDMA_WORD, 2}, /* 5 */
234 { MIDDMA_2WORD, 3}, /* 6 */ { MIDDMA_WORD, 2}, /* 7 */
235 { MIDDMA_8WORD, 5}, /* 8 */ { MIDDMA_WORD, 2}, /* 9 */
236 { MIDDMA_2WORD, 3}, /* 10 */ { MIDDMA_WORD, 2}, /* 11 */
237 { MIDDMA_4WORD, 4}, /* 12 */ { MIDDMA_WORD, 2}, /* 13 */
238 { MIDDMA_2WORD, 3}, /* 14 */ { MIDDMA_WORD, 2}, /* 15 */
239 { MIDDMA_16WORD, 6}, /* 16 */
240};
241
269static struct en_dmatab en_dma_planB[] = {
270 { 0, 0 }, /* 0 */ { MIDDMA_WORD, 2}, /* 1 */
271 { MIDDMA_2WORD, 3}, /* 2 */ { MIDDMA_WORD, 2}, /* 3 */
272 { MIDDMA_4WORD, 4}, /* 4 */ { MIDDMA_WORD, 2}, /* 5 */
273 { MIDDMA_2WORD, 3}, /* 6 */ { MIDDMA_WORD, 2}, /* 7 */
274 { MIDDMA_8WORD, 5}, /* 8 */ { MIDDMA_WORD, 2}, /* 9 */
275 { MIDDMA_2WORD, 3}, /* 10 */ { MIDDMA_WORD, 2}, /* 11 */
276 { MIDDMA_4WORD, 4}, /* 12 */ { MIDDMA_WORD, 2}, /* 13 */
277 { MIDDMA_2WORD, 3}, /* 14 */ { MIDDMA_WORD, 2}, /* 15 */
278 { MIDDMA_16WORD, 6}, /* 16 */
279};
280
242static struct en_dmatab *en_dmaplan = en_dma_planA;
243
281static struct en_dmatab *en_dmaplan = en_dma_planB;
282
244/*
245 * prototypes
246 */
247
283/*
284 * prototypes
285 */
286
248STATIC int en_b2sz __P((int));
287STATIC INLINE int en_b2sz __P((int)) __attribute__ ((unused));
249#ifdef EN_DDBHOOK
288#ifdef EN_DDBHOOK
250int en_dump __P((int,int));
251int en_dumpmem __P((int,int,int));
289 int en_dump __P((int,int));
290 int en_dumpmem __P((int,int,int));
252#endif
291#endif
253STATIC void en_dmaprobe __P((struct en_softc *));
254STATIC int en_dmaprobe_doit __P((struct en_softc *, u_int8_t *,
255 u_int8_t *, int));
256STATIC int en_dqneed __P((struct en_softc *, caddr_t, u_int, u_int));
257STATIC void en_init __P((struct en_softc *));
258STATIC int en_ioctl __P((struct ifnet *, EN_IOCTL_CMDT, caddr_t));
259STATIC int en_k2sz __P((int));
260STATIC void en_loadvc __P((struct en_softc *, int));
261STATIC int en_mfix __P((struct en_softc *, struct mbuf **, struct mbuf *));
262STATIC struct mbuf *en_mget __P((struct en_softc *, u_int, u_int *));
263STATIC u_int32_t en_read __P((struct en_softc *, u_int32_t));
264STATIC int en_rxctl __P((struct en_softc *, struct atm_pseudoioctl *, int));
265STATIC void en_txdma __P((struct en_softc *, int));
266STATIC void en_txlaunch __P((struct en_softc *, int, struct en_launch *));
267STATIC void en_service __P((struct en_softc *));
268STATIC void en_start __P((struct ifnet *));
269STATIC int en_sz2b __P((int));
270STATIC void en_write __P((struct en_softc *, u_int32_t, u_int32_t));
292STATIC void en_dmaprobe __P((struct en_softc *));
293STATIC int en_dmaprobe_doit __P((struct en_softc *, u_int8_t *,
294 u_int8_t *, int));
295STATIC INLINE int en_dqneed __P((struct en_softc *, caddr_t, u_int,
296 u_int)) __attribute__ ((unused));
297STATIC void en_init __P((struct en_softc *));
298STATIC int en_ioctl __P((struct ifnet *, EN_IOCTL_CMDT, caddr_t));
299STATIC INLINE int en_k2sz __P((int)) __attribute__ ((unused));
300STATIC void en_loadvc __P((struct en_softc *, int));
301STATIC int en_mfix __P((struct en_softc *, struct mbuf **,
302 struct mbuf *));
303STATIC INLINE struct mbuf *en_mget __P((struct en_softc *, u_int,
304 u_int *)) __attribute__ ((unused));
305STATIC INLINE u_int32_t en_read __P((struct en_softc *,
306 u_int32_t)) __attribute__ ((unused));
307STATIC int en_rxctl __P((struct en_softc *, struct atm_pseudoioctl *,
308 int));
309STATIC void en_txdma __P((struct en_softc *, int));
310STATIC void en_txlaunch __P((struct en_softc *, int,
311 struct en_launch *));
312STATIC void en_service __P((struct en_softc *));
313STATIC void en_start __P((struct ifnet *));
314STATIC INLINE int en_sz2b __P((int)) __attribute__ ((unused));
315STATIC INLINE void en_write __P((struct en_softc *, u_int32_t,
316 u_int32_t)) __attribute__ ((unused));
271
317
318#ifdef ATM_PVCEXT
319static int en_txctl __P((struct en_softc *, int, int, int));
320static int en_pvctx __P((struct en_softc *, struct pvctxreq *));
321static int en_pvctxget __P((struct en_softc *, struct pvctxreq *));
322static int en_pcr2txspeed __P((int));
323static int en_txspeed2pcr __P((int));
324#endif
325
272/*
273 * macros/inline
274 */
275
276/*
277 * raw read/write macros
278 */
279

--- 311 unchanged lines hidden (view full) ---

591 if (top) {
592 MGET(m, M_DONTWAIT, MT_DATA);
593 if (!m) {
594 m_freem(top);
595 return(NULL); /* out of mbufs */
596 }
597 m->m_len = MLEN;
598 }
326/*
327 * macros/inline
328 */
329
330/*
331 * raw read/write macros
332 */
333

--- 311 unchanged lines hidden (view full) ---

645 if (top) {
646 MGET(m, M_DONTWAIT, MT_DATA);
647 if (!m) {
648 m_freem(top);
649 return(NULL); /* out of mbufs */
650 }
651 m->m_len = MLEN;
652 }
599 if (top && totlen >= MINCLSIZE) {
653 if (totlen >= MINCLSIZE) {
600 MCLGET(m, M_DONTWAIT);
654 MCLGET(m, M_DONTWAIT);
601 if (m->m_flags & M_EXT)
602 m->m_len = MCLBYTES;
655 if ((m->m_flags & M_EXT) == 0) {
656 m_free(m);
657 m_freem(top);
658 return(NULL); /* out of mbuf clusters */
659 }
660 m->m_len = MCLBYTES;
603 }
604 m->m_len = min(totlen, m->m_len);
605 totlen -= m->m_len;
606 *mp = m;
607 mp = &m->m_next;
608
609 *drqneed += en_dqneed(sc, m->m_data, m->m_len, 0);
610

--- 71 unchanged lines hidden (view full) ---

682 else
683 printf("%s: FAILED DMA TEST: burst=%d, alburst=%d\n",
684 sc->sc_dev.dv_xname, sc->bestburstlen, sc->alburst);
685 } else {
686 printf("%s: maximum DMA burst length = %d bytes%s\n", sc->sc_dev.dv_xname,
687 sc->bestburstlen, (sc->alburst) ? " (must align)" : "");
688 }
689
661 }
662 m->m_len = min(totlen, m->m_len);
663 totlen -= m->m_len;
664 *mp = m;
665 mp = &m->m_next;
666
667 *drqneed += en_dqneed(sc, m->m_data, m->m_len, 0);
668

--- 71 unchanged lines hidden (view full) ---

740 else
741 printf("%s: FAILED DMA TEST: burst=%d, alburst=%d\n",
742 sc->sc_dev.dv_xname, sc->bestburstlen, sc->alburst);
743 } else {
744 printf("%s: maximum DMA burst length = %d bytes%s\n", sc->sc_dev.dv_xname,
745 sc->bestburstlen, (sc->alburst) ? " (must align)" : "");
746 }
747
690#if 0 /* WMAYBE doesn't work, don't complain about it */
691 /* check if en_dmaprobe disabled wmaybe */
692 if (en_dmaplan == en_dma_planB)
693 printf("%s: note: WMAYBE DMA has been disabled\n", sc->sc_dev.dv_xname);
694#endif
695
696 /*
697 * link into network subsystem and prepare card
698 */
699
700#if defined(__NetBSD__) || defined(__OpenBSD__)
701 bcopy(sc->sc_dev.dv_xname, sc->enif.if_xname, IFNAMSIZ);
702#endif
748 /*
749 * link into network subsystem and prepare card
750 */
751
752#if defined(__NetBSD__) || defined(__OpenBSD__)
753 bcopy(sc->sc_dev.dv_xname, sc->enif.if_xname, IFNAMSIZ);
754#endif
703#if !defined(MISSING_IF_SOFTC)
704 sc->enif.if_softc = sc;
755 sc->enif.if_softc = sc;
705#endif
706 ifp->if_flags = IFF_SIMPLEX|IFF_NOTRAILERS;
707 ifp->if_ioctl = en_ioctl;
708 ifp->if_output = atm_output;
709 ifp->if_start = en_start;
710
711 /*
712 * init softc
713 */

--- 30 unchanged lines hidden (view full) ---

744 sav = ptr;
745 ptr = roundup(ptr, EN_RXSZ * 1024); /* align */
746 sz = sz - (ptr - sav);
747 sc->en_nrx = sz / (EN_RXSZ * 1024);
748 if (sc->en_nrx <= 0) {
749 printf("%s: EN_NTX/EN_TXSZ/EN_RXSZ too big\n", sc->sc_dev.dv_xname);
750 return;
751 }
756 ifp->if_flags = IFF_SIMPLEX|IFF_NOTRAILERS;
757 ifp->if_ioctl = en_ioctl;
758 ifp->if_output = atm_output;
759 ifp->if_start = en_start;
760
761 /*
762 * init softc
763 */

--- 30 unchanged lines hidden (view full) ---

794 sav = ptr;
795 ptr = roundup(ptr, EN_RXSZ * 1024); /* align */
796 sz = sz - (ptr - sav);
797 sc->en_nrx = sz / (EN_RXSZ * 1024);
798 if (sc->en_nrx <= 0) {
799 printf("%s: EN_NTX/EN_TXSZ/EN_RXSZ too big\n", sc->sc_dev.dv_xname);
800 return;
801 }
752#if 1
753 /* leave one entry in the ringbuf unused to avoid wraparound */
802
803 /*
804 * ensure that there is always one VC slot on the service list free
805 * so that we can tell the difference between a full and empty list.
806 */
754 if (sc->en_nrx >= MID_N_VC)
807 if (sc->en_nrx >= MID_N_VC)
755 sc->en_nrx = MID_N_VC - 1;
756#endif
808 sc->en_nrx = MID_N_VC - 1;
809
757 for (lcv = 0 ; lcv < sc->en_nrx ; lcv++) {
758 sc->rxslot[lcv].rxhand = NULL;
759 sc->rxslot[lcv].oth_flags = ENOTHER_FREE;
760 bzero(&sc->rxslot[lcv].indma, sizeof(sc->rxslot[lcv].indma));
761 bzero(&sc->rxslot[lcv].q, sizeof(sc->rxslot[lcv].q));
762 midvloc = sc->rxslot[lcv].start = ptr;
763 ptr += (EN_RXSZ * 1024);
764 sz -= (EN_RXSZ * 1024);

--- 18 unchanged lines hidden (view full) ---

783 sc->rxdrqout = sc->ttrash = sc->rxmbufout = sc->mfixfail = 0;
784 sc->headbyte = sc->tailbyte = sc->tailflush = 0;
785#endif
786 sc->need_drqs = sc->need_dtqs = 0;
787
788 printf("%s: %d %dKB receive buffers, %d %dKB transmit buffers allocated\n",
789 sc->sc_dev.dv_xname, sc->en_nrx, EN_RXSZ, EN_NTX, EN_TXSZ);
790
810 for (lcv = 0 ; lcv < sc->en_nrx ; lcv++) {
811 sc->rxslot[lcv].rxhand = NULL;
812 sc->rxslot[lcv].oth_flags = ENOTHER_FREE;
813 bzero(&sc->rxslot[lcv].indma, sizeof(sc->rxslot[lcv].indma));
814 bzero(&sc->rxslot[lcv].q, sizeof(sc->rxslot[lcv].q));
815 midvloc = sc->rxslot[lcv].start = ptr;
816 ptr += (EN_RXSZ * 1024);
817 sz -= (EN_RXSZ * 1024);

--- 18 unchanged lines hidden (view full) ---

836 sc->rxdrqout = sc->ttrash = sc->rxmbufout = sc->mfixfail = 0;
837 sc->headbyte = sc->tailbyte = sc->tailflush = 0;
838#endif
839 sc->need_drqs = sc->need_dtqs = 0;
840
841 printf("%s: %d %dKB receive buffers, %d %dKB transmit buffers allocated\n",
842 sc->sc_dev.dv_xname, sc->en_nrx, EN_RXSZ, EN_NTX, EN_TXSZ);
843
844 printf("%s: End Station Identifier (mac address) %6D\n",
845 sc->sc_dev.dv_xname, sc->macaddr, ":");
846
791 /*
792 * final commit
793 */
794
795 if_attach(ifp);
796 atm_ifattach(ifp);
797
847 /*
848 * final commit
849 */
850
851 if_attach(ifp);
852 atm_ifattach(ifp);
853
854#if NBPFILTER > 0
855 BPFATTACH(ifp, DLT_ATM_RFC1483, sizeof(struct atmllc));
856#endif
798}
799
800
801/*
802 * en_dmaprobe: helper function for en_attach.
803 *
804 * see how the card handles DMA by running a few DMA tests. we need
805 * to figure out the largest number of bytes we can DMA in one burst
806 * ("bestburstlen"), and if the starting address for a burst needs to
807 * be aligned on any sort of boundary or not ("alburst").
808 *
809 * typical findings:
810 * sparc1: bestburstlen=4, alburst=0 (ick, broken DMA!)
811 * sparc2: bestburstlen=64, alburst=1
812 * p166: bestburstlen=64, alburst=0
813 */
814
857}
858
859
860/*
861 * en_dmaprobe: helper function for en_attach.
862 *
863 * see how the card handles DMA by running a few DMA tests. we need
864 * to figure out the largest number of bytes we can DMA in one burst
865 * ("bestburstlen"), and if the starting address for a burst needs to
866 * be aligned on any sort of boundary or not ("alburst").
867 *
868 * typical findings:
869 * sparc1: bestburstlen=4, alburst=0 (ick, broken DMA!)
870 * sparc2: bestburstlen=64, alburst=1
871 * p166: bestburstlen=64, alburst=0
872 */
873
874#if 1 /* __FreeBSD__ */
875#define NBURSTS 3 /* number of bursts to use for dmaprobe */
876#define BOUNDARY 1024 /* test misaligned dma crossing the bounday.
877 should be n * 64. at least 64*(NBURSTS+1).
878 dell P6 with EDO DRAM has 1K bounday problem */
879#endif
880
815STATIC void en_dmaprobe(sc)
816
817struct en_softc *sc;
818
819{
881STATIC void en_dmaprobe(sc)
882
883struct en_softc *sc;
884
885{
886#ifdef NBURSTS
887 /* be careful. kernel stack is only 8K */
888 u_int8_t buffer[BOUNDARY * 2 + 64 * (NBURSTS + 1)];
889#else
820 u_int32_t srcbuf[64], dstbuf[64];
890 u_int32_t srcbuf[64], dstbuf[64];
891#endif
821 u_int8_t *sp, *dp;
892 u_int8_t *sp, *dp;
822 int bestalgn, bestnotalgn, lcv, try, fail;
893 int bestalgn, bestnotalgn, lcv, try;
823
824 sc->alburst = 0;
825
894
895 sc->alburst = 0;
896
897#ifdef NBURSTS
898 /* setup src and dst buf at the end of the boundary */
899 sp = (u_int8_t *)roundup((unsigned long)buffer, 64);
900 while (((unsigned long)sp & (BOUNDARY - 1)) != (BOUNDARY - 64))
901 sp += 64;
902 dp = sp + BOUNDARY;
903
904 /*
905 * we can't dma across page boundary so that, if buf is at a page
906 * boundary, move it to the next page. but still either src or dst
907 * will be at the boundary, which should be ok.
908 */
909 if ((((unsigned long)sp + 64) & PAGE_MASK) == 0)
910 sp += 64;
911 if ((((unsigned long)dp + 64) & PAGE_MASK) == 0)
912 dp += 64;
913#else /* !NBURSTS */
826 sp = (u_int8_t *) srcbuf;
827 while ((((unsigned long) sp) % MIDDMA_MAXBURST) != 0)
828 sp += 4;
829 dp = (u_int8_t *) dstbuf;
830 while ((((unsigned long) dp) % MIDDMA_MAXBURST) != 0)
831 dp += 4;
914 sp = (u_int8_t *) srcbuf;
915 while ((((unsigned long) sp) % MIDDMA_MAXBURST) != 0)
916 sp += 4;
917 dp = (u_int8_t *) dstbuf;
918 while ((((unsigned long) dp) % MIDDMA_MAXBURST) != 0)
919 dp += 4;
920#endif /* !NBURSTS */
832
833 bestalgn = bestnotalgn = en_dmaprobe_doit(sc, sp, dp, 0);
834
835 for (lcv = 4 ; lcv < MIDDMA_MAXBURST ; lcv += 4) {
836 try = en_dmaprobe_doit(sc, sp+lcv, dp+lcv, 0);
921
922 bestalgn = bestnotalgn = en_dmaprobe_doit(sc, sp, dp, 0);
923
924 for (lcv = 4 ; lcv < MIDDMA_MAXBURST ; lcv += 4) {
925 try = en_dmaprobe_doit(sc, sp+lcv, dp+lcv, 0);
926#ifdef NBURSTS
927 if (try < bestnotalgn) {
928 bestnotalgn = try;
929 break;
930 }
931#else
837 if (try < bestnotalgn)
838 bestnotalgn = try;
932 if (try < bestnotalgn)
933 bestnotalgn = try;
934#endif
839 }
840
841 if (bestalgn != bestnotalgn) /* need bursts aligned */
842 sc->alburst = 1;
843
844 sc->bestburstlen = bestalgn;
845 sc->bestburstshift = en_log2(bestalgn);
846 sc->bestburstmask = sc->bestburstlen - 1; /* must be power of 2 */
847 sc->bestburstcode = en_sz2b(bestalgn);
848
935 }
936
937 if (bestalgn != bestnotalgn) /* need bursts aligned */
938 sc->alburst = 1;
939
940 sc->bestburstlen = bestalgn;
941 sc->bestburstshift = en_log2(bestalgn);
942 sc->bestburstmask = sc->bestburstlen - 1; /* must be power of 2 */
943 sc->bestburstcode = en_sz2b(bestalgn);
944
849 if (sc->bestburstlen <= 2*sizeof(u_int32_t))
850 return; /* won't be using WMAYBE */
851
945#if 1 /* __FreeBSD__ */
852 /*
946 /*
853 * adaptec does not have (or need) wmaybe. do not bother testing
854 * for it.
947 * correct pci chipsets should be able to handle misaligned-64-byte DMA.
948 * but there are too many broken chipsets around. we try to work around
949 * by finding the best workable dma size, but still some broken machines
950 * exhibit the problem later. so warn it here.
855 */
951 */
856 if (sc->is_adaptec) {
857 /* XXX, actually don't need a DMA plan: adaptec is smarter than that */
858 en_dmaplan = en_dma_planB;
859 return;
952 if (bestalgn != 64 || sc->alburst != 0) {
953 printf("%s: WARNING: DMA test detects a broken PCI chipset!\n",
954 sc->sc_dev.dv_xname);
955 printf(" trying to work around the problem... but if this doesn't\n");
956 printf(" work for you, you'd better switch to a newer motherboard.\n");
860 }
957 }
861
862 /*
863 * test that WMAYBE dma works like we think it should
864 * (i.e. no alignment restrictions on host address other than alburst)
865 */
866
867 try = sc->bestburstlen - 4;
868 fail = 0;
869 fail += en_dmaprobe_doit(sc, sp, dp, try);
870 for (lcv = 4 ; lcv < sc->bestburstlen ; lcv += 4) {
871 fail += en_dmaprobe_doit(sc, sp+lcv, dp+lcv, try);
872 if (sc->alburst)
873 try -= 4;
874 }
875 if (EN_NOWMAYBE || fail) {
876 if (fail)
877 printf("%s: WARNING: WMAYBE DMA test failed %d time(s)\n",
878 sc->sc_dev.dv_xname, fail);
879 en_dmaplan = en_dma_planB; /* fall back to plan B */
880 }
881
958#endif /* 1 */
959 return;
882}
883
884
885/*
886 * en_dmaprobe_doit: do actual testing
887 */
888
889int

--- 17 unchanged lines hidden (view full) ---

907
908 midvloc = ((MID_BUFOFF - MID_RAMOFF) / sizeof(u_int32_t)) >> MIDV_LOCTOPSHFT;
909 EN_WRITE(sc, MIDX_PLACE(0), MIDX_MKPLACE(en_k2sz(1), midvloc));
910 EN_WRITE(sc, MID_VC(0), (midvloc << MIDV_LOCSHIFT)
911 | (en_k2sz(1) << MIDV_SZSHIFT) | MIDV_TRASH);
912 EN_WRITE(sc, MID_DST_RP(0), 0);
913 EN_WRITE(sc, MID_WP_ST_CNT(0), 0);
914
960}
961
962
963/*
964 * en_dmaprobe_doit: do actual testing
965 */
966
967int

--- 17 unchanged lines hidden (view full) ---

985
986 midvloc = ((MID_BUFOFF - MID_RAMOFF) / sizeof(u_int32_t)) >> MIDV_LOCTOPSHFT;
987 EN_WRITE(sc, MIDX_PLACE(0), MIDX_MKPLACE(en_k2sz(1), midvloc));
988 EN_WRITE(sc, MID_VC(0), (midvloc << MIDV_LOCSHIFT)
989 | (en_k2sz(1) << MIDV_SZSHIFT) | MIDV_TRASH);
990 EN_WRITE(sc, MID_DST_RP(0), 0);
991 EN_WRITE(sc, MID_WP_ST_CNT(0), 0);
992
993#ifdef NBURSTS
994 for (lcv = 0 ; lcv < 64*NBURSTS; lcv++) /* set up sample data */
995#else
915 for (lcv = 0 ; lcv < 68 ; lcv++) /* set up sample data */
996 for (lcv = 0 ; lcv < 68 ; lcv++) /* set up sample data */
997#endif
916 sp[lcv] = lcv+1;
917 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* enable DMA (only) */
918
919 sc->drq_chip = MID_DRQ_REG2A(EN_READ(sc, MID_DMA_RDRX));
920 sc->dtq_chip = MID_DTQ_REG2A(EN_READ(sc, MID_DMA_RDTX));
921
922 /*
923 * try it now . . . DMA it out, then DMA it back in and compare

--- 5 unchanged lines hidden (view full) ---

929 * note: we've got two different tests rolled up in the same loop
930 * if (wmtry)
931 * then we are doing a wmaybe test and wmtry is a byte count
932 * else we are doing a burst test
933 */
934
935 for (lcv = 8 ; lcv <= MIDDMA_MAXBURST ; lcv = lcv * 2) {
936
998 sp[lcv] = lcv+1;
999 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* enable DMA (only) */
1000
1001 sc->drq_chip = MID_DRQ_REG2A(EN_READ(sc, MID_DMA_RDRX));
1002 sc->dtq_chip = MID_DTQ_REG2A(EN_READ(sc, MID_DMA_RDTX));
1003
1004 /*
1005 * try it now . . . DMA it out, then DMA it back in and compare

--- 5 unchanged lines hidden (view full) ---

1011 * note: we've got two different tests rolled up in the same loop
1012 * if (wmtry)
1013 * then we are doing a wmaybe test and wmtry is a byte count
1014 * else we are doing a burst test
1015 */
1016
1017 for (lcv = 8 ; lcv <= MIDDMA_MAXBURST ; lcv = lcv * 2) {
1018
1019#ifdef EN_DEBUG
1020 printf("DMA test lcv=%d, sp=0x%x, dp=0x%x, wmtry=%d\n",
1021 lcv, sp, dp, wmtry);
1022#endif
1023
937 /* zero SRAM and dest buffer */
938 for (cnt = 0 ; cnt < 1024; cnt += 4)
939 EN_WRITE(sc, MID_BUFOFF+cnt, 0); /* zero memory */
1024 /* zero SRAM and dest buffer */
1025 for (cnt = 0 ; cnt < 1024; cnt += 4)
1026 EN_WRITE(sc, MID_BUFOFF+cnt, 0); /* zero memory */
1027#ifdef NBURSTS
1028 for (cnt = 0 ; cnt < 64*NBURSTS; cnt++)
1029#else
940 for (cnt = 0 ; cnt < 68 ; cnt++)
1030 for (cnt = 0 ; cnt < 68 ; cnt++)
1031#endif
941 dp[cnt] = 0;
942
943 if (wmtry) {
944 count = (sc->bestburstlen - sizeof(u_int32_t)) / sizeof(u_int32_t);
945 bcode = en_dmaplan[count].bcode;
946 count = wmtry >> en_dmaplan[count].divshift;
947 } else {
948 bcode = en_sz2b(lcv);
949 count = 1;
950 }
1032 dp[cnt] = 0;
1033
1034 if (wmtry) {
1035 count = (sc->bestburstlen - sizeof(u_int32_t)) / sizeof(u_int32_t);
1036 bcode = en_dmaplan[count].bcode;
1037 count = wmtry >> en_dmaplan[count].divshift;
1038 } else {
1039 bcode = en_sz2b(lcv);
1040 count = 1;
1041 }
1042#ifdef NBURSTS
1043 /* build lcv-byte-DMA x NBURSTS */
951 if (sc->is_adaptec)
1044 if (sc->is_adaptec)
1045 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ADP(lcv*NBURSTS, 0, MID_DMA_END, 0));
1046 else
1047 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ENI(count*NBURSTS, 0, MID_DMA_END, bcode));
1048 EN_WRITE(sc, sc->dtq_chip+4, vtophys(sp));
1049 EN_WRAPADD(MID_DTQOFF, MID_DTQEND, sc->dtq_chip, 8);
1050 EN_WRITE(sc, MID_DMA_WRTX, MID_DTQ_A2REG(sc->dtq_chip));
1051 cnt = 1000;
1052 while (EN_READ(sc, MID_DMA_RDTX) != MID_DTQ_A2REG(sc->dtq_chip)) {
1053 DELAY(1);
1054 cnt--;
1055 if (cnt == 0) {
1056 printf("%s: unexpected timeout in tx DMA test\n", sc->sc_dev.dv_xname);
1057/*
1058 printf(" alignment=0x%x, burst size=%d, dma addr reg=0x%x\n",
1059 (u_long)sp & 63, lcv, EN_READ(sc, MID_DMA_ADDR));
1060*/
1061 return(retval); /* timeout, give up */
1062 }
1063 }
1064#else /* !NBURSTS */
1065 if (sc->is_adaptec)
952 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ADP(lcv, 0, MID_DMA_END, 0));
953 else
954 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ENI(count, 0, MID_DMA_END, bcode));
955 EN_WRITE(sc, sc->dtq_chip+4, vtophys(sp));
956 EN_WRITE(sc, MID_DMA_WRTX, MID_DTQ_A2REG(sc->dtq_chip+8));
957 cnt = 1000;
958 while (EN_READ(sc, MID_DMA_RDTX) == MID_DTQ_A2REG(sc->dtq_chip)) {
959 DELAY(1);
960 cnt--;
961 if (cnt == 0) {
962 printf("%s: unexpected timeout in tx DMA test\n", sc->sc_dev.dv_xname);
963 return(retval); /* timeout, give up */
964 }
965 }
966 EN_WRAPADD(MID_DTQOFF, MID_DTQEND, sc->dtq_chip, 8);
1066 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ADP(lcv, 0, MID_DMA_END, 0));
1067 else
1068 EN_WRITE(sc, sc->dtq_chip, MID_MK_TXQ_ENI(count, 0, MID_DMA_END, bcode));
1069 EN_WRITE(sc, sc->dtq_chip+4, vtophys(sp));
1070 EN_WRITE(sc, MID_DMA_WRTX, MID_DTQ_A2REG(sc->dtq_chip+8));
1071 cnt = 1000;
1072 while (EN_READ(sc, MID_DMA_RDTX) == MID_DTQ_A2REG(sc->dtq_chip)) {
1073 DELAY(1);
1074 cnt--;
1075 if (cnt == 0) {
1076 printf("%s: unexpected timeout in tx DMA test\n", sc->sc_dev.dv_xname);
1077 return(retval); /* timeout, give up */
1078 }
1079 }
1080 EN_WRAPADD(MID_DTQOFF, MID_DTQEND, sc->dtq_chip, 8);
1081#endif /* !NBURSTS */
967 reg = EN_READ(sc, MID_INTACK);
968 if ((reg & MID_INT_DMA_TX) != MID_INT_DMA_TX) {
969 printf("%s: unexpected status in tx DMA test: 0x%x\n",
970 sc->sc_dev.dv_xname, reg);
971 return(retval);
972 }
973 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* re-enable DMA (only) */
974
975 /* "return to sender..." address is known ... */
976
1082 reg = EN_READ(sc, MID_INTACK);
1083 if ((reg & MID_INT_DMA_TX) != MID_INT_DMA_TX) {
1084 printf("%s: unexpected status in tx DMA test: 0x%x\n",
1085 sc->sc_dev.dv_xname, reg);
1086 return(retval);
1087 }
1088 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* re-enable DMA (only) */
1089
1090 /* "return to sender..." address is known ... */
1091
1092#ifdef NBURSTS
1093 /* build lcv-byte-DMA x NBURSTS */
977 if (sc->is_adaptec)
1094 if (sc->is_adaptec)
1095 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ADP(lcv*NBURSTS, 0, MID_DMA_END, 0));
1096 else
1097 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ENI(count*NBURSTS, 0, MID_DMA_END, bcode));
1098 EN_WRITE(sc, sc->drq_chip+4, vtophys(dp));
1099 EN_WRAPADD(MID_DRQOFF, MID_DRQEND, sc->drq_chip, 8);
1100 EN_WRITE(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip));
1101 cnt = 1000;
1102 while (EN_READ(sc, MID_DMA_RDRX) != MID_DRQ_A2REG(sc->drq_chip)) {
1103 DELAY(1);
1104 cnt--;
1105 if (cnt == 0) {
1106 printf("%s: unexpected timeout in rx DMA test\n", sc->sc_dev.dv_xname);
1107 return(retval); /* timeout, give up */
1108 }
1109 }
1110#else /* !NBURSTS */
1111 if (sc->is_adaptec)
978 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ADP(lcv, 0, MID_DMA_END, 0));
979 else
980 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ENI(count, 0, MID_DMA_END, bcode));
981 EN_WRITE(sc, sc->drq_chip+4, vtophys(dp));
982 EN_WRITE(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip+8));
983 cnt = 1000;
984 while (EN_READ(sc, MID_DMA_RDRX) == MID_DRQ_A2REG(sc->drq_chip)) {
985 DELAY(1);
986 cnt--;
987 if (cnt == 0) {
988 printf("%s: unexpected timeout in rx DMA test\n", sc->sc_dev.dv_xname);
989 return(retval); /* timeout, give up */
990 }
991 }
992 EN_WRAPADD(MID_DRQOFF, MID_DRQEND, sc->drq_chip, 8);
1112 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ADP(lcv, 0, MID_DMA_END, 0));
1113 else
1114 EN_WRITE(sc, sc->drq_chip, MID_MK_RXQ_ENI(count, 0, MID_DMA_END, bcode));
1115 EN_WRITE(sc, sc->drq_chip+4, vtophys(dp));
1116 EN_WRITE(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip+8));
1117 cnt = 1000;
1118 while (EN_READ(sc, MID_DMA_RDRX) == MID_DRQ_A2REG(sc->drq_chip)) {
1119 DELAY(1);
1120 cnt--;
1121 if (cnt == 0) {
1122 printf("%s: unexpected timeout in rx DMA test\n", sc->sc_dev.dv_xname);
1123 return(retval); /* timeout, give up */
1124 }
1125 }
1126 EN_WRAPADD(MID_DRQOFF, MID_DRQEND, sc->drq_chip, 8);
1127#endif /* !NBURSTS */
993 reg = EN_READ(sc, MID_INTACK);
994 if ((reg & MID_INT_DMA_RX) != MID_INT_DMA_RX) {
995 printf("%s: unexpected status in rx DMA test: 0x%x\n",
996 sc->sc_dev.dv_xname, reg);
997 return(retval);
998 }
999 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* re-enable DMA (only) */
1000
1001 if (wmtry) {
1002 return(bcmp(sp, dp, wmtry)); /* wmtry always exits here, no looping */
1003 }
1004
1128 reg = EN_READ(sc, MID_INTACK);
1129 if ((reg & MID_INT_DMA_RX) != MID_INT_DMA_RX) {
1130 printf("%s: unexpected status in rx DMA test: 0x%x\n",
1131 sc->sc_dev.dv_xname, reg);
1132 return(retval);
1133 }
1134 EN_WRITE(sc, MID_MAST_CSR, MID_MCSR_ENDMA); /* re-enable DMA (only) */
1135
1136 if (wmtry) {
1137 return(bcmp(sp, dp, wmtry)); /* wmtry always exits here, no looping */
1138 }
1139
1140#ifdef NBURSTS
1141 if (bcmp(sp, dp, lcv * NBURSTS)) {
1142/* printf("DMA test failed! lcv=%d, sp=0x%x, dp=0x%x\n", lcv, sp, dp); */
1143 return(retval); /* failed, use last value */
1144 }
1145#else
1005 if (bcmp(sp, dp, lcv))
1006 return(retval); /* failed, use last value */
1146 if (bcmp(sp, dp, lcv))
1147 return(retval); /* failed, use last value */
1148#endif
1007
1008 retval = lcv;
1009
1010 }
1011 return(retval); /* studly 64 byte DMA present! oh baby!! */
1012}
1013
1014/***********************************************************************/

--- 10 unchanged lines hidden (view full) ---

1025
1026STATIC int en_ioctl(ifp, cmd, data)
1027
1028struct ifnet *ifp;
1029EN_IOCTL_CMDT cmd;
1030caddr_t data;
1031
1032{
1149
1150 retval = lcv;
1151
1152 }
1153 return(retval); /* studly 64 byte DMA present! oh baby!! */
1154}
1155
1156/***********************************************************************/

--- 10 unchanged lines hidden (view full) ---

1167
1168STATIC int en_ioctl(ifp, cmd, data)
1169
1170struct ifnet *ifp;
1171EN_IOCTL_CMDT cmd;
1172caddr_t data;
1173
1174{
1033#ifdef MISSING_IF_SOFTC
1034 struct en_softc *sc = (struct en_softc *) en_cd.cd_devs[ifp->if_unit];
1035#else
1036 struct en_softc *sc = (struct en_softc *) ifp->if_softc;
1175 struct en_softc *sc = (struct en_softc *) ifp->if_softc;
1037#endif
1038 struct ifaddr *ifa = (struct ifaddr *) data;
1039 struct ifreq *ifr = (struct ifreq *) data;
1040 struct atm_pseudoioctl *api = (struct atm_pseudoioctl *)data;
1041#ifdef NATM
1042 struct atm_rawioctl *ario = (struct atm_rawioctl *)data;
1043 int slot;
1044#endif
1045 int s, error = 0;

--- 28 unchanged lines hidden (view full) ---

1074 printf("%s: rxvci%d: turn %s raw (boodi) mode\n",
1075 sc->sc_dev.dv_xname, ario->npcb->npcb_vci,
1076 (ario->rawvalue) ? "on" : "off");
1077#endif
1078 break;
1079#endif
1080 case SIOCSIFADDR:
1081 ifp->if_flags |= IFF_UP;
1176 struct ifaddr *ifa = (struct ifaddr *) data;
1177 struct ifreq *ifr = (struct ifreq *) data;
1178 struct atm_pseudoioctl *api = (struct atm_pseudoioctl *)data;
1179#ifdef NATM
1180 struct atm_rawioctl *ario = (struct atm_rawioctl *)data;
1181 int slot;
1182#endif
1183 int s, error = 0;

--- 28 unchanged lines hidden (view full) ---

1212 printf("%s: rxvci%d: turn %s raw (boodi) mode\n",
1213 sc->sc_dev.dv_xname, ario->npcb->npcb_vci,
1214 (ario->rawvalue) ? "on" : "off");
1215#endif
1216 break;
1217#endif
1218 case SIOCSIFADDR:
1219 ifp->if_flags |= IFF_UP;
1082#ifdef INET
1083 if (ifa->ifa_addr->sa_family == AF_INET) {
1220#if defined(INET) || defined(INET6)
1221 if (ifa->ifa_addr->sa_family == AF_INET
1222 || ifa->ifa_addr->sa_family == AF_INET6) {
1084 en_reset(sc);
1085 en_init(sc);
1086 ifa->ifa_rtrequest = atm_rtrequest; /* ??? */
1087 break;
1088 }
1089#endif /* INET */
1090 /* what to do if not INET? */
1091 en_reset(sc);

--- 24 unchanged lines hidden (view full) ---

1116#endif
1117 ifp->if_mtu = ifr->ifr_mtu;
1118 /* XXXCDC: do we really need to reset on MTU size change? */
1119 en_reset(sc);
1120 en_init(sc);
1121 break;
1122#endif /* SIOCSIFMTU */
1123
1223 en_reset(sc);
1224 en_init(sc);
1225 ifa->ifa_rtrequest = atm_rtrequest; /* ??? */
1226 break;
1227 }
1228#endif /* INET */
1229 /* what to do if not INET? */
1230 en_reset(sc);

--- 24 unchanged lines hidden (view full) ---

1255#endif
1256 ifp->if_mtu = ifr->ifr_mtu;
1257 /* XXXCDC: do we really need to reset on MTU size change? */
1258 en_reset(sc);
1259 en_init(sc);
1260 break;
1261#endif /* SIOCSIFMTU */
1262
1263#ifdef ATM_PVCEXT
1264 case SIOCSPVCTX:
1265 if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) == 0)
1266 error = en_pvctx(sc, (struct pvctxreq *)data);
1267 break;
1268
1269 case SIOCGPVCTX:
1270 error = en_pvctxget(sc, (struct pvctxreq *)data);
1271 break;
1272
1273 case SIOCSPVCSIF:
1274 do {
1275 struct ifnet *shadow;
1276
1277 if (error = suser(curproc->p_ucred, &curproc->p_acflag))
1278 break;
1279
1280 if ((shadow = pvc_attach(ifp)) != NULL) {
1281 sprintf(ifr->ifr_name, "%s%d",
1282 shadow->if_name, shadow->if_unit);
1283 }
1284 else
1285 error = ENOBUFS;
1286 } while (0);
1287 break;
1288
1289#endif /* ATM_PVCEXT */
1290
1124 default:
1125 error = EINVAL;
1126 break;
1127 }
1128 splx(s);
1129 return error;
1130}
1131

--- 159 unchanged lines hidden (view full) ---

1291 m_freem(m);
1292 }
1293 while (1) {
1294 IF_DEQUEUE(&sc->txslot[lcv].q, m);
1295 if (m == NULL)
1296 break; /* >>> exit 'while(1)' here <<< */
1297 m_freem(m);
1298 }
1291 default:
1292 error = EINVAL;
1293 break;
1294 }
1295 splx(s);
1296 return error;
1297}
1298

--- 159 unchanged lines hidden (view full) ---

1458 m_freem(m);
1459 }
1460 while (1) {
1461 IF_DEQUEUE(&sc->txslot[lcv].q, m);
1462 if (m == NULL)
1463 break; /* >>> exit 'while(1)' here <<< */
1464 m_freem(m);
1465 }
1466
1299 sc->txslot[lcv].mbsize = 0;
1300 }
1301
1302 return;
1303}
1304
1305
1306/*

--- 23 unchanged lines hidden (view full) ---

1330 sc->enif.if_flags |= IFF_RUNNING; /* enable */
1331
1332 if (sc->en_busreset)
1333 sc->en_busreset(sc);
1334 EN_WRITE(sc, MID_RESID, 0x0); /* reset */
1335
1336 /*
1337 * init obmem data structures: vc tab, dma q's, slist.
1467 sc->txslot[lcv].mbsize = 0;
1468 }
1469
1470 return;
1471}
1472
1473
1474/*

--- 23 unchanged lines hidden (view full) ---

1498 sc->enif.if_flags |= IFF_RUNNING; /* enable */
1499
1500 if (sc->en_busreset)
1501 sc->en_busreset(sc);
1502 EN_WRITE(sc, MID_RESID, 0x0); /* reset */
1503
1504 /*
1505 * init obmem data structures: vc tab, dma q's, slist.
1506 *
1507 * note that we set drq_free/dtq_free to one less than the total number
1508 * of DTQ/DRQs present. we do this because the card uses the condition
1509 * (drq_chip == drq_us) to mean "list is empty"... but if you allow the
1510 * circular list to be completely full then (drq_chip == drq_us) [i.e.
1511 * the drq_us pointer will wrap all the way around]. by restricting
1512 * the number of active requests to (N - 1) we prevent the list from
1513 * becoming completely full. note that the card will sometimes give
1514 * us an interrupt for a DTQ/DRQ we have already processes... this helps
1515 * keep that interrupt from messing us up.
1338 */
1339
1340 for (vc = 0 ; vc < MID_N_VC ; vc++)
1341 en_loadvc(sc, vc);
1342
1343 bzero(&sc->drq, sizeof(sc->drq));
1516 */
1517
1518 for (vc = 0 ; vc < MID_N_VC ; vc++)
1519 en_loadvc(sc, vc);
1520
1521 bzero(&sc->drq, sizeof(sc->drq));
1344#if 1
1345 /* leave one entry in the ringbuf unused to avoid wraparound */
1346 sc->drq_free = MID_DRQ_N - 1;
1347#else
1348 sc->drq_free = MID_DRQ_N;
1349#endif
1522 sc->drq_free = MID_DRQ_N - 1; /* N - 1 */
1350 sc->drq_chip = MID_DRQ_REG2A(EN_READ(sc, MID_DMA_RDRX));
1351 EN_WRITE(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip));
1352 /* ensure zero queue */
1353 sc->drq_us = sc->drq_chip;
1354
1355 bzero(&sc->dtq, sizeof(sc->dtq));
1523 sc->drq_chip = MID_DRQ_REG2A(EN_READ(sc, MID_DMA_RDRX));
1524 EN_WRITE(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip));
1525 /* ensure zero queue */
1526 sc->drq_us = sc->drq_chip;
1527
1528 bzero(&sc->dtq, sizeof(sc->dtq));
1356#if 1
1357 /* leave one entry in the ringbuf unused to avoid wraparound */
1358 sc->dtq_free = MID_DTQ_N - 1;
1359#else
1360 sc->dtq_free = MID_DTQ_N;
1361#endif
1529 sc->dtq_free = MID_DTQ_N - 1; /* N - 1 */
1362 sc->dtq_chip = MID_DTQ_REG2A(EN_READ(sc, MID_DMA_RDTX));
1363 EN_WRITE(sc, MID_DMA_WRTX, MID_DRQ_A2REG(sc->dtq_chip));
1364 /* ensure zero queue */
1365 sc->dtq_us = sc->dtq_chip;
1366
1367 sc->hwslistp = MID_SL_REG2A(EN_READ(sc, MID_SERV_WRITE));
1368 sc->swsl_size = sc->swsl_head = sc->swsl_tail = 0;
1369

--- 68 unchanged lines hidden (view full) ---

1438 * if there is one. note that atm_output() has already splimp()'d us.
1439 */
1440
1441STATIC void en_start(ifp)
1442
1443struct ifnet *ifp;
1444
1445{
1530 sc->dtq_chip = MID_DTQ_REG2A(EN_READ(sc, MID_DMA_RDTX));
1531 EN_WRITE(sc, MID_DMA_WRTX, MID_DRQ_A2REG(sc->dtq_chip));
1532 /* ensure zero queue */
1533 sc->dtq_us = sc->dtq_chip;
1534
1535 sc->hwslistp = MID_SL_REG2A(EN_READ(sc, MID_SERV_WRITE));
1536 sc->swsl_size = sc->swsl_head = sc->swsl_tail = 0;
1537

--- 68 unchanged lines hidden (view full) ---

1606 * if there is one. note that atm_output() has already splimp()'d us.
1607 */
1608
1609STATIC void en_start(ifp)
1610
1611struct ifnet *ifp;
1612
1613{
1446#ifdef MISSING_IF_SOFTC
1447 struct en_softc *sc = (struct en_softc *) en_cd.cd_devs[ifp->if_unit];
1448#else
1449 struct en_softc *sc = (struct en_softc *) ifp->if_softc;
1614 struct en_softc *sc = (struct en_softc *) ifp->if_softc;
1450#endif
1451 struct ifqueue *ifq = &ifp->if_snd; /* if INPUT QUEUE */
1452 struct mbuf *m, *lastm, *prev;
1453 struct atm_pseudohdr *ap, *new_ap;
1454 int txchan, mlen, got, need, toadd, cellcnt, first;
1455 u_int32_t atm_vpi, atm_vci, atm_flags, *dat, aal;
1456 u_int8_t *cp;
1457
1458 if ((ifp->if_flags & IFF_RUNNING) == 0)

--- 19 unchanged lines hidden (view full) ---

1478 * after this loop mlen total length of mbuf chain (including atm_ph),
1479 * and lastm is a pointer to the last mbuf on the chain.
1480 */
1481
1482 lastm = m;
1483 mlen = 0;
1484 prev = NULL;
1485 while (1) {
1615 struct ifqueue *ifq = &ifp->if_snd; /* if INPUT QUEUE */
1616 struct mbuf *m, *lastm, *prev;
1617 struct atm_pseudohdr *ap, *new_ap;
1618 int txchan, mlen, got, need, toadd, cellcnt, first;
1619 u_int32_t atm_vpi, atm_vci, atm_flags, *dat, aal;
1620 u_int8_t *cp;
1621
1622 if ((ifp->if_flags & IFF_RUNNING) == 0)

--- 19 unchanged lines hidden (view full) ---

1642 * after this loop mlen total length of mbuf chain (including atm_ph),
1643 * and lastm is a pointer to the last mbuf on the chain.
1644 */
1645
1646 lastm = m;
1647 mlen = 0;
1648 prev = NULL;
1649 while (1) {
1486#ifdef EN_FIXMBUF
1487 /* if eni, always fix misaligned mbuf */
1488 if (!sc->is_adaptec || EN_NOTXDMA || !en_dma) {
1489#else
1490 if (EN_NOTXDMA || !en_dma) { /* no DMA? */
1491#endif
1650 /* no DMA? */
1651 if ((!sc->is_adaptec && EN_ENIDMAFIX) || EN_NOTXDMA || !en_dma) {
1492 if ( (mtod(lastm, unsigned long) % sizeof(u_int32_t)) != 0 ||
1493 ((lastm->m_len % sizeof(u_int32_t)) != 0 && lastm->m_next)) {
1494 first = (lastm == m);
1495 if (en_mfix(sc, &lastm, prev) == 0) { /* failed? */
1496 m_freem(m);
1497 m = NULL;
1498 break;
1499 }
1500 if (first)
1501 m = lastm; /* update */
1502 }
1503 prev = lastm;
1504 }
1652 if ( (mtod(lastm, unsigned long) % sizeof(u_int32_t)) != 0 ||
1653 ((lastm->m_len % sizeof(u_int32_t)) != 0 && lastm->m_next)) {
1654 first = (lastm == m);
1655 if (en_mfix(sc, &lastm, prev) == 0) { /* failed? */
1656 m_freem(m);
1657 m = NULL;
1658 break;
1659 }
1660 if (first)
1661 m = lastm; /* update */
1662 }
1663 prev = lastm;
1664 }
1665
1505 mlen += lastm->m_len;
1506 if (lastm->m_next == NULL)
1507 break;
1508 lastm = lastm->m_next;
1509 }
1510
1511 if (m == NULL) /* happens only if mfix fails */
1512 continue;

--- 106 unchanged lines hidden (view full) ---

1619 printf("%s: tx%d: VPI=%d, VCI=%d, FLAGS=0x%x, speed=0x%x\n",
1620 sc->sc_dev.dv_xname, txchan, atm_vpi, atm_vci, atm_flags,
1621 sc->txspeed[atm_vci]);
1622 printf(" adjusted mlen=%d, mbsize=%d\n", mlen,
1623 sc->txslot[txchan].mbsize);
1624#endif
1625
1626 IF_ENQUEUE(&sc->txslot[txchan].q, m);
1666 mlen += lastm->m_len;
1667 if (lastm->m_next == NULL)
1668 break;
1669 lastm = lastm->m_next;
1670 }
1671
1672 if (m == NULL) /* happens only if mfix fails */
1673 continue;

--- 106 unchanged lines hidden (view full) ---

1780 printf("%s: tx%d: VPI=%d, VCI=%d, FLAGS=0x%x, speed=0x%x\n",
1781 sc->sc_dev.dv_xname, txchan, atm_vpi, atm_vci, atm_flags,
1782 sc->txspeed[atm_vci]);
1783 printf(" adjusted mlen=%d, mbsize=%d\n", mlen,
1784 sc->txslot[txchan].mbsize);
1785#endif
1786
1787 IF_ENQUEUE(&sc->txslot[txchan].q, m);
1788
1627 en_txdma(sc, txchan);
1628
1629 }
1630 /*NOTREACHED*/
1631}
1632
1633
1634/*
1635 * en_mfix: fix a stupid mbuf
1636 */
1789 en_txdma(sc, txchan);
1790
1791 }
1792 /*NOTREACHED*/
1793}
1794
1795
1796/*
1797 * en_mfix: fix a stupid mbuf
1798 */
1799
1800#ifndef __FreeBSD__
1801
1802STATIC int en_mfix(sc, mm, prev)
1803
1804struct en_softc *sc;
1805struct mbuf **mm, *prev;
1806
1807{
1808 struct mbuf *m, *new;
1809 u_char *d, *cp;
1810 int off;
1811 struct mbuf *nxt;
1812
1813 m = *mm;
1814
1815 EN_COUNT(sc->mfix); /* count # of calls */
1816#ifdef EN_DEBUG
1817 printf("%s: mfix mbuf m_data=%p, m_len=%d\n", sc->sc_dev.dv_xname,
1818 m->m_data, m->m_len);
1819#endif
1820
1821 d = mtod(m, u_char *);
1822 off = ((unsigned long) d) % sizeof(u_int32_t);
1823
1824 if (off) {
1825 if ((m->m_flags & M_EXT) == 0) {
1826 bcopy(d, d - off, m->m_len); /* ALIGN! (with costly data copy...) */
1827 d -= off;
1828 m->m_data = (caddr_t)d;
1829 } else {
1830 /* can't write to an M_EXT mbuf since it may be shared */
1831 MGET(new, M_DONTWAIT, MT_DATA);
1832 if (!new) {
1833 EN_COUNT(sc->mfixfail);
1834 return(0);
1835 }
1836 MCLGET(new, M_DONTWAIT);
1837 if ((new->m_flags & M_EXT) == 0) {
1838 m_free(new);
1839 EN_COUNT(sc->mfixfail);
1840 return(0);
1841 }
1842 bcopy(d, new->m_data, m->m_len); /* ALIGN! (with costly data copy...) */
1843 new->m_len = m->m_len;
1844 new->m_next = m->m_next;
1845 if (prev)
1846 prev->m_next = new;
1847 m_free(m);
1848 *mm = m = new; /* note: 'd' now invalid */
1849 }
1850 }
1851
1852 off = m->m_len % sizeof(u_int32_t);
1853 if (off == 0)
1854 return(1);
1855
1856 d = mtod(m, u_char *) + m->m_len;
1857 off = sizeof(u_int32_t) - off;
1858
1859 nxt = m->m_next;
1860 while (off--) {
1861 for ( ; nxt != NULL && nxt->m_len == 0 ; nxt = nxt->m_next)
1862 /*null*/;
1863 if (nxt == NULL) { /* out of data, zero fill */
1864 *d++ = 0;
1865 continue; /* next "off" */
1866 }
1867 cp = mtod(nxt, u_char *);
1868 *d++ = *cp++;
1869 m->m_len++;
1870 nxt->m_len--;
1871 nxt->m_data = (caddr_t)cp;
1872 }
1873 return(1);
1874}
1875
1876#else /* __FreeBSD__ */
1877
1637STATIC int en_makeexclusive(struct en_softc *, struct mbuf **, struct mbuf *);
1638
1639STATIC int en_makeexclusive(sc, mm, prev)
1640 struct en_softc *sc;
1641 struct mbuf **mm, *prev;
1642{
1643 struct mbuf *m, *new;
1644

--- 111 unchanged lines hidden (view full) ---

1756 nxt->m_len--;
1757 nxt->m_data = (caddr_t)cp;
1758 }
1759 if (nxt != NULL && nxt->m_len == 0)
1760 m->m_next = m_free(nxt);
1761 return(1);
1762}
1763
1878STATIC int en_makeexclusive(struct en_softc *, struct mbuf **, struct mbuf *);
1879
1880STATIC int en_makeexclusive(sc, mm, prev)
1881 struct en_softc *sc;
1882 struct mbuf **mm, *prev;
1883{
1884 struct mbuf *m, *new;
1885

--- 111 unchanged lines hidden (view full) ---

1997 nxt->m_len--;
1998 nxt->m_data = (caddr_t)cp;
1999 }
2000 if (nxt != NULL && nxt->m_len == 0)
2001 m->m_next = m_free(nxt);
2002 return(1);
2003}
2004
2005#endif /* __FreeBSD__ */
1764
1765/*
1766 * en_txdma: start trasmit DMA, if possible
1767 */
1768
1769STATIC void en_txdma(sc, chan)
1770
1771struct en_softc *sc;

--- 152 unchanged lines hidden (view full) ---

1924 launch.tbd2 = MID_TBD_MK2(launch.atm_vci, 0, 0);
1925 }
1926 if ((launch.atm_flags & EN_OBTRL) == 0 && launch.aal == MID_TBD_AAL5) {
1927 EN_COUNT(sc->ltail);
1928 launch.pdu1 = MID_PDU_MK1(0, 0, datalen); /* host byte order */
1929 }
1930
1931 en_txlaunch(sc, chan, &launch);
2006
2007/*
2008 * en_txdma: start trasmit DMA, if possible
2009 */
2010
2011STATIC void en_txdma(sc, chan)
2012
2013struct en_softc *sc;

--- 152 unchanged lines hidden (view full) ---

2166 launch.tbd2 = MID_TBD_MK2(launch.atm_vci, 0, 0);
2167 }
2168 if ((launch.atm_flags & EN_OBTRL) == 0 && launch.aal == MID_TBD_AAL5) {
2169 EN_COUNT(sc->ltail);
2170 launch.pdu1 = MID_PDU_MK1(0, 0, datalen); /* host byte order */
2171 }
2172
2173 en_txlaunch(sc, chan, &launch);
1932
2174
2175#if NBPFILTER > 0
2176 if (sc->enif.if_bpf) {
2177 /*
2178 * adjust the top of the mbuf to skip the pseudo atm header
2179 * (and TBD, if present) before passing the packet to bpf,
2180 * restore it afterwards.
2181 */
2182 int size = sizeof(struct atm_pseudohdr);
2183 if (launch.atm_flags & EN_OBHDR)
2184 size += MID_TBD_SIZE;
2185
2186 launch.t->m_data += size;
2187 launch.t->m_len -= size;
2188
2189 BPF_MTAP(&sc->enif, launch.t);
2190
2191 launch.t->m_data -= size;
2192 launch.t->m_len += size;
2193 }
2194#endif /* NBPFILTER > 0 */
1933 /*
1934 * do some housekeeping and get the next packet
1935 */
1936
1937 sc->txslot[chan].bfree -= launch.need;
1938 IF_ENQUEUE(&sc->txslot[chan].indma, launch.t);
1939 goto again;
1940

--- 472 unchanged lines hidden (view full) ---

2413#ifdef EN_DEBUG
2414 printf("%s: tx%d: free %d dma bytes, mbsize now %d\n",
2415 sc->sc_dev.dv_xname, slot, EN_DQ_LEN(dtq),
2416 sc->txslot[slot].mbsize);
2417#endif
2418 m_freem(m);
2419 }
2420 EN_WRAPADD(0, MID_DTQ_N, idx, 1);
2195 /*
2196 * do some housekeeping and get the next packet
2197 */
2198
2199 sc->txslot[chan].bfree -= launch.need;
2200 IF_ENQUEUE(&sc->txslot[chan].indma, launch.t);
2201 goto again;
2202

--- 472 unchanged lines hidden (view full) ---

2675#ifdef EN_DEBUG
2676 printf("%s: tx%d: free %d dma bytes, mbsize now %d\n",
2677 sc->sc_dev.dv_xname, slot, EN_DQ_LEN(dtq),
2678 sc->txslot[slot].mbsize);
2679#endif
2680 m_freem(m);
2681 }
2682 EN_WRAPADD(0, MID_DTQ_N, idx, 1);
2421 }
2683 };
2422 sc->dtq_chip = MID_DTQ_REG2A(val); /* sync softc */
2423 }
2424
2425
2426 /*
2427 * kick xmit channels as needed
2428 */
2429

--- 55 unchanged lines hidden (view full) ---

2485 ATM_PH_FLAGS(&ah) = sc->rxslot[slot].atm_flags;
2486 ATM_PH_VPI(&ah) = 0;
2487 ATM_PH_SETVCI(&ah, sc->rxslot[slot].atm_vci);
2488#ifdef EN_DEBUG
2489 printf("%s: rx%d: rxvci%d: atm_input, mbuf %p, len %d, hand %p\n",
2490 sc->sc_dev.dv_xname, slot, sc->rxslot[slot].atm_vci, m,
2491 EN_DQ_LEN(drq), sc->rxslot[slot].rxhand);
2492#endif
2684 sc->dtq_chip = MID_DTQ_REG2A(val); /* sync softc */
2685 }
2686
2687
2688 /*
2689 * kick xmit channels as needed
2690 */
2691

--- 55 unchanged lines hidden (view full) ---

2747 ATM_PH_FLAGS(&ah) = sc->rxslot[slot].atm_flags;
2748 ATM_PH_VPI(&ah) = 0;
2749 ATM_PH_SETVCI(&ah, sc->rxslot[slot].atm_vci);
2750#ifdef EN_DEBUG
2751 printf("%s: rx%d: rxvci%d: atm_input, mbuf %p, len %d, hand %p\n",
2752 sc->sc_dev.dv_xname, slot, sc->rxslot[slot].atm_vci, m,
2753 EN_DQ_LEN(drq), sc->rxslot[slot].rxhand);
2754#endif
2755#if NBPFILTER > 0
2756 if (sc->enif.if_bpf)
2757 BPF_MTAP(&sc->enif, m);
2758#endif /* NBPFILTER > 0 */
2759
2493 sc->enif.if_ipackets++;
2494
2495 atm_input(&sc->enif, &ah, m, sc->rxslot[slot].rxhand);
2496 }
2497
2498 }
2499 EN_WRAPADD(0, MID_DRQ_N, idx, 1);
2760 sc->enif.if_ipackets++;
2761
2762 atm_input(&sc->enif, &ah, m, sc->rxslot[slot].rxhand);
2763 }
2764
2765 }
2766 EN_WRAPADD(0, MID_DRQ_N, idx, 1);
2500 }
2767 };
2501 sc->drq_chip = MID_DRQ_REG2A(val); /* sync softc */
2502
2503 if (sc->need_drqs) { /* true if we had a DRQ shortage */
2504 need_softserv = 1;
2505 sc->need_drqs = 0;
2506#ifdef EN_DEBUG
2507 printf("%s: cleared need DRQ condition\n", sc->sc_dev.dv_xname);
2508#endif

--- 35 unchanged lines hidden (view full) ---

2544 sc->rxslot[slot].oth_flags |= ENOTHER_SWSL;
2545 sc->swslist[sc->swsl_tail] = slot;
2546 EN_WRAPADD(0, MID_SL_N, sc->swsl_tail, 1);
2547 sc->swsl_size++;
2548#ifdef EN_DEBUG
2549 printf("%s: added VCI %d to swslist\n", sc->sc_dev.dv_xname, vci);
2550#endif
2551 }
2768 sc->drq_chip = MID_DRQ_REG2A(val); /* sync softc */
2769
2770 if (sc->need_drqs) { /* true if we had a DRQ shortage */
2771 need_softserv = 1;
2772 sc->need_drqs = 0;
2773#ifdef EN_DEBUG
2774 printf("%s: cleared need DRQ condition\n", sc->sc_dev.dv_xname);
2775#endif

--- 35 unchanged lines hidden (view full) ---

2811 sc->rxslot[slot].oth_flags |= ENOTHER_SWSL;
2812 sc->swslist[sc->swsl_tail] = slot;
2813 EN_WRAPADD(0, MID_SL_N, sc->swsl_tail, 1);
2814 sc->swsl_size++;
2815#ifdef EN_DEBUG
2816 printf("%s: added VCI %d to swslist\n", sc->sc_dev.dv_xname, vci);
2817#endif
2818 }
2552 }
2819 };
2553 }
2554
2555 /*
2556 * now service (function too big to include here)
2557 */
2558
2559 if (need_softserv)
2560 en_service(sc);

--- 122 unchanged lines hidden (view full) ---

2683 rbd = EN_READ(sc, cur);
2684 if (MID_RBD_ID(rbd) != MID_RBD_STDID)
2685 panic("en_service: id mismatch\n");
2686
2687 if (rbd & MID_RBD_T) {
2688 mlen = 0; /* we've got trash */
2689 fill = MID_RBD_SIZE;
2690 EN_COUNT(sc->ttrash);
2820 }
2821
2822 /*
2823 * now service (function too big to include here)
2824 */
2825
2826 if (need_softserv)
2827 en_service(sc);

--- 122 unchanged lines hidden (view full) ---

2950 rbd = EN_READ(sc, cur);
2951 if (MID_RBD_ID(rbd) != MID_RBD_STDID)
2952 panic("en_service: id mismatch\n");
2953
2954 if (rbd & MID_RBD_T) {
2955 mlen = 0; /* we've got trash */
2956 fill = MID_RBD_SIZE;
2957 EN_COUNT(sc->ttrash);
2958#ifdef EN_DEBUG
2959 printf("RX overflow lost %d cells!\n", MID_RBD_CNT(rbd));
2960#endif
2691 } else if (!aal5) {
2692 mlen = MID_RBD_SIZE + MID_CHDR_SIZE + MID_ATMDATASZ; /* 1 cell (ick!) */
2693 fill = 0;
2694 } else {
2695 tlen = (MID_RBD_CNT(rbd) * MID_ATMDATASZ) + MID_RBD_SIZE;
2696 pdu = cur + tlen - MID_PDU_SIZE;
2697 if (pdu >= stop)
2698 pdu -= (EN_RXSZ*1024);
2699 pdu = EN_READ(sc, pdu); /* get PDU in correct byte order */
2700 fill = tlen - MID_RBD_SIZE - MID_PDU_LEN(pdu);
2701 if (fill < 0 || (rbd & MID_RBD_CRCERR) != 0) {
2961 } else if (!aal5) {
2962 mlen = MID_RBD_SIZE + MID_CHDR_SIZE + MID_ATMDATASZ; /* 1 cell (ick!) */
2963 fill = 0;
2964 } else {
2965 tlen = (MID_RBD_CNT(rbd) * MID_ATMDATASZ) + MID_RBD_SIZE;
2966 pdu = cur + tlen - MID_PDU_SIZE;
2967 if (pdu >= stop)
2968 pdu -= (EN_RXSZ*1024);
2969 pdu = EN_READ(sc, pdu); /* get PDU in correct byte order */
2970 fill = tlen - MID_RBD_SIZE - MID_PDU_LEN(pdu);
2971 if (fill < 0 || (rbd & MID_RBD_CRCERR) != 0) {
2702 printf("%s: invalid AAL5 PDU length or CRC detected, dropping frame\n",
2703 sc->sc_dev.dv_xname);
2704 printf("%s: got %d cells (%d bytes), AAL5 len is %d bytes (pdu=0x%x) CRCERR=%d\n",
2705 sc->sc_dev.dv_xname, MID_RBD_CNT(rbd), tlen - MID_RBD_SIZE,
2706 MID_PDU_LEN(pdu), pdu, (rbd & MID_RBD_CRCERR)?1:0);
2972 printf("%s: %s, dropping frame\n", sc->sc_dev.dv_xname,
2973 (rbd & MID_RBD_CRCERR) ? "CRC error" : "invalid AAL5 PDU length");
2974 printf("%s: got %d cells (%d bytes), AAL5 len is %d bytes (pdu=0x%x)\n",
2975 sc->sc_dev.dv_xname, MID_RBD_CNT(rbd), tlen - MID_RBD_SIZE,
2976 MID_PDU_LEN(pdu), pdu);
2707 fill = tlen;
2708 }
2709 mlen = tlen - fill;
2710 }
2711
2712 }
2713
2714 /*

--- 442 unchanged lines hidden (view full) ---

3157
3158 if (level & END_SWSL) {
3159 printf(" swslist [size=%d]: ", sc->swsl_size);
3160 for (cnt = sc->swsl_head ; cnt != sc->swsl_tail ;
3161 cnt = (cnt + 1) % MID_SL_N)
3162 printf("0x%x ", sc->swslist[cnt]);
3163 printf("\n");
3164 }
2977 fill = tlen;
2978 }
2979 mlen = tlen - fill;
2980 }
2981
2982 }
2983
2984 /*

--- 442 unchanged lines hidden (view full) ---

3427
3428 if (level & END_SWSL) {
3429 printf(" swslist [size=%d]: ", sc->swsl_size);
3430 for (cnt = sc->swsl_head ; cnt != sc->swsl_tail ;
3431 cnt = (cnt + 1) % MID_SL_N)
3432 printf("0x%x ", sc->swslist[cnt]);
3433 printf("\n");
3434 }
3165
3166 }
3167 return(0);
3168}
3169
3170/*
3171 * en_dumpmem: dump the memory
3172 */
3173

--- 20 unchanged lines hidden (view full) ---

3194 reg = EN_READ(sc, addr);
3195 printf("mem[0x%x] = 0x%x\n", addr, reg);
3196 addr += 4;
3197 }
3198 return(0);
3199}
3200#endif
3201
3435 }
3436 return(0);
3437}
3438
3439/*
3440 * en_dumpmem: dump the memory
3441 */
3442

--- 20 unchanged lines hidden (view full) ---

3463 reg = EN_READ(sc, addr);
3464 printf("mem[0x%x] = 0x%x\n", addr, reg);
3465 addr += 4;
3466 }
3467 return(0);
3468}
3469#endif
3470
3471#ifdef ATM_PVCEXT
3472/*
3473 * ATM PVC extention: shaper control and pvc shadow interfaces
3474 */
3202
3475
3476/* txspeed conversion derived from linux drivers/atm/eni.c
3477 by Werner Almesberger, EPFL LRC */
3478static const int pre_div[] = { 4,16,128,2048 };
3479
3480static int en_pcr2txspeed(pcr)
3481 int pcr;
3482{
3483 int pre, res, div;
3484
3485 if (pcr == 0 || pcr > 347222)
3486 pre = res = 0; /* max rate */
3487 else {
3488 for (pre = 0; pre < 3; pre++)
3489 if (25000000/pre_div[pre]/64 <= pcr)
3490 break;
3491 div = pre_div[pre]*(pcr);
3492#if 1
3493 /*
3494 * the shaper value should be rounded down,
3495 * instead of rounded up.
3496 * (which means "res" should be rounded up.)
3497 */
3498 res = (25000000 + div -1)/div - 1;
3499#else
3500 res = 25000000/div-1;
3501#endif
3502 if (res < 0)
3503 res = 0;
3504 if (res > 63)
3505 res = 63;
3506 }
3507 return ((pre << 6) + res);
3508}
3509
3510static int en_txspeed2pcr(txspeed)
3511 int txspeed;
3512{
3513 int pre, res, pcr;
3514
3515 pre = (txspeed >> 6) & 0x3;
3516 res = txspeed & 0x3f;
3517 pcr = 25000000 / pre_div[pre] / (res+1);
3518 return (pcr);
3519}
3520
3521/*
3522 * en_txctl selects a hardware transmit channel and sets the shaper value.
3523 * en_txctl should be called after enabling the vc by en_rxctl
3524 * since it assumes a transmit channel is already assigned by en_rxctl
3525 * to the vc.
3526 */
3527static int en_txctl(sc, vci, joint_vci, pcr)
3528 struct en_softc *sc;
3529 int vci;
3530 int joint_vci;
3531 int pcr;
3532{
3533 int txspeed, txchan, c, s;
3534
3535 if (pcr)
3536 txspeed = en_pcr2txspeed(pcr);
3537 else
3538 txspeed = 0;
3539
3540 s = splimp();
3541 txchan = sc->txvc2slot[vci];
3542 sc->txslot[txchan].nref--;
3543
3544 /* select a slot */
3545 if (joint_vci != 0)
3546 /* use the same channel */
3547 txchan = sc->txvc2slot[joint_vci];
3548 if (pcr == 0)
3549 txchan = 0;
3550 else {
3551 for (c = 1, txchan = 1; c < EN_NTX; c++) {
3552 if (sc->txslot[c].nref < sc->txslot[txchan].nref)
3553 txchan = c;
3554 if (sc->txslot[txchan].nref == 0)
3555 break;
3556 }
3557 }
3558 sc->txvc2slot[vci] = txchan;
3559 sc->txslot[txchan].nref++;
3560
3561 /* set the shaper parameter */
3562 sc->txspeed[vci] = (u_int8_t)txspeed;
3563
3564 splx(s);
3565#ifdef EN_DEBUG
3566 printf("VCI:%d PCR set to %d, tx channel %d\n", vci, pcr, txchan);
3567 if (joint_vci != 0)
3568 printf(" slot shared with VCI:%d\n", joint_vci);
3569#endif
3570 return (0);
3571}
3572
3573static int en_pvctx(sc, pvcreq)
3574 struct en_softc *sc;
3575 struct pvctxreq *pvcreq;
3576{
3577 struct ifnet *ifp;
3578 struct atm_pseudoioctl api;
3579 struct atm_pseudohdr *pvc_aph, *pvc_joint;
3580 int vci, joint_vci, pcr;
3581 int error = 0;
3582
3583 /* check vpi:vci values */
3584 pvc_aph = &pvcreq->pvc_aph;
3585 pvc_joint = &pvcreq->pvc_joint;
3586
3587 vci = ATM_PH_VCI(pvc_aph);
3588 joint_vci = ATM_PH_VCI(pvc_joint);
3589 pcr = pvcreq->pvc_pcr;
3590
3591 if (ATM_PH_VPI(pvc_aph) != 0 || vci >= MID_N_VC ||
3592 ATM_PH_VPI(pvc_joint) != 0 || joint_vci >= MID_N_VC)
3593 return (EADDRNOTAVAIL);
3594
3595 if ((ifp = ifunit(pvcreq->pvc_ifname)) == NULL)
3596 return (ENXIO);
3597
3598 if (pcr < 0) {
3599 /* negative pcr means disable the vc. */
3600 if (sc->rxvc2slot[vci] == RX_NONE)
3601 /* already disabled */
3602 return 0;
3603
3604 ATM_PH_FLAGS(&api.aph) = 0;
3605 ATM_PH_VPI(&api.aph) = 0;
3606 ATM_PH_SETVCI(&api.aph, vci);
3607 api.rxhand = NULL;
3608
3609 error = en_rxctl(sc, &api, 0);
3610
3611 if (error == 0 && &sc->enif != ifp) {
3612 /* clear vc info of shadow interface */
3613 ATM_PH_SETVCI(&api.aph, 0);
3614 pvc_setaph(ifp, &api.aph);
3615 }
3616 return (error);
3617 }
3618
3619 if (&sc->enif == ifp) {
3620 /* called for an en interface */
3621 if (sc->rxvc2slot[vci] == RX_NONE) {
3622 /* vc is not active */
3623 printf("%s%d: en_pvctx: rx not active! vci=%d\n",
3624 ifp->if_name, ifp->if_unit, vci);
3625 return (EINVAL);
3626 }
3627 }
3628 else {
3629 /* called for a shadow interface */
3630 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
3631 printf("en_pvctx: if %s is not point-to-point!\n",
3632 pvcreq->pvc_ifname);
3633 return (EINVAL);
3634 }
3635 sprintf(pvcreq->pvc_ifname, "%s%d",
3636 sc->enif.if_name, sc->enif.if_unit);
3637
3638 ATM_PH_FLAGS(&api.aph) = ATM_PH_PVCSIF |
3639 (ATM_PH_FLAGS(pvc_aph) & (ATM_PH_AAL5|ATM_PH_LLCSNAP));
3640 ATM_PH_VPI(&api.aph) = 0;
3641 ATM_PH_SETVCI(&api.aph, vci);
3642 api.rxhand = ifp;
3643 pvc_setaph(ifp, &api.aph);
3644
3645 if (sc->rxvc2slot[vci] == RX_NONE) {
3646 /* vc is not active, enable rx */
3647 error = en_rxctl(sc, &api, 1);
3648 if (error)
3649 return error;
3650 }
3651 else {
3652 /* vc is already active, update aph in softc */
3653 sc->rxslot[sc->rxvc2slot[vci]].atm_flags =
3654 ATM_PH_FLAGS(&api.aph);
3655 }
3656
3657 }
3658
3659 error = en_txctl(sc, vci, joint_vci, pcr);
3660
3661 if (error == 0) {
3662 if (sc->txspeed[vci] != 0)
3663 pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]);
3664 else
3665 pvcreq->pvc_pcr = 0;
3666 }
3667
3668 return error;
3669}
3670
3671static int en_pvctxget(sc, pvcreq)
3672 struct en_softc *sc;
3673 struct pvctxreq *pvcreq;
3674{
3675 struct atm_pseudohdr *pvc_aph;
3676 int vci, slot;
3677
3678 pvc_aph = &pvcreq->pvc_aph;
3679 vci = ATM_PH_VCI(pvc_aph);
3680
3681 if ((slot = sc->rxvc2slot[vci]) == RX_NONE) {
3682 /* vc is not active */
3683 ATM_PH_FLAGS(pvc_aph) = 0;
3684 pvcreq->pvc_pcr = -1;
3685 }
3686 else {
3687 ATM_PH_FLAGS(pvc_aph) = sc->rxslot[slot].atm_flags;
3688 ATM_PH_VPI(pvc_aph) = 0;
3689 ATM_PH_SETVCI(pvc_aph, vci);
3690 if (sc->txspeed[vci])
3691 pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]);
3692 else
3693 pvcreq->pvc_pcr = 0;
3694 }
3695
3696 return (0);
3697}
3698
3699#endif /* ATM_PVCEXT */
3700
3203#endif /* NEN > 0 || !defined(__FreeBSD__) */
3701#endif /* NEN > 0 || !defined(__FreeBSD__) */