]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/en/midway.c
This commit was generated by cvs2svn to compensate for changes in r131554,
[FreeBSD/FreeBSD.git] / sys / dev / en / midway.c
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
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by Charles D. Cranor and
20  *      Washington University.
21  * 4. The name of the author may not be used to endorse or promote products
22  *    derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 /*
39  *
40  * m i d w a y . c   e n i 1 5 5   d r i v e r 
41  *
42  * author: Chuck Cranor <chuck@ccrc.wustl.edu>
43  * started: spring, 1996 (written from scratch).
44  *
45  * notes from the author:
46  *   Extra special thanks go to Werner Almesberger, EPFL LRC.   Werner's
47  *   ENI driver was especially useful in figuring out how this card works.
48  *   I would also like to thank Werner for promptly answering email and being
49  *   generally helpful.
50  */
51
52 #define EN_DIAG
53 #define EN_DDBHOOK      1       /* compile in ddb functions */
54
55 /*
56  * Note on EN_ENIDMAFIX: the byte aligner on the ENI version of the card
57  * appears to be broken.   it works just fine if there is no load... however
58  * when the card is loaded the data get corrupted.   to see this, one only
59  * has to use "telnet" over ATM.   do the following command in "telnet":
60  *      cat /usr/share/misc/termcap
61  * "telnet" seems to generate lots of 1023 byte mbufs (which make great
62  * use of the byte aligner).   watch "netstat -s" for checksum errors.
63  * 
64  * I further tested this by adding a function that compared the transmit 
65  * data on the card's SRAM with the data in the mbuf chain _after_ the 
66  * "transmit DMA complete" interrupt.   using the "telnet" test I got data
67  * mismatches where the byte-aligned data should have been.   using ddb
68  * and en_dumpmem() I verified that the DTQs fed into the card were 
69  * absolutely correct.   thus, we are forced to concluded that the ENI
70  * hardware is buggy.   note that the Adaptec version of the card works
71  * just fine with byte DMA.
72  *
73  * bottom line: we set EN_ENIDMAFIX to 1 to avoid byte DMAs on the ENI
74  * card.
75  */
76
77 #if defined(DIAGNOSTIC) && !defined(EN_DIAG)
78 #define EN_DIAG                 /* link in with master DIAG option */
79 #endif
80
81 #define EN_COUNT(X) (X)++
82
83 #ifdef EN_DEBUG
84
85 #undef  EN_DDBHOOK
86 #define EN_DDBHOOK      1
87
88 /*
89  * This macro removes almost all the EN_DEBUG conditionals in the code that make
90  * to code a good deal less readable.
91  */
92 #define DBG(SC, FL, PRINT) do {                                         \
93         if ((SC)->debug & DBG_##FL) {                                   \
94                 if_printf(&(SC)->ifatm.ifnet, "%s: "#FL": ", __func__); \
95                 printf PRINT;                                           \
96                 printf("\n");                                           \
97         }                                                               \
98     } while (0)
99
100 enum {
101         DBG_INIT        = 0x0001,       /* debug attach/detach */
102         DBG_TX          = 0x0002,       /* debug transmitting */
103         DBG_SERV        = 0x0004,       /* debug service interrupts */
104         DBG_IOCTL       = 0x0008,       /* debug ioctls */
105         DBG_VC          = 0x0010,       /* debug VC handling */
106         DBG_INTR        = 0x0020,       /* debug interrupts */
107         DBG_DMA         = 0x0040,       /* debug DMA probing */
108         DBG_IPACKETS    = 0x0080,       /* print input packets */
109         DBG_REG         = 0x0100,       /* print all register access */
110         DBG_LOCK        = 0x0200,       /* debug locking */
111 };
112
113 #else /* EN_DEBUG */
114
115 #define DBG(SC, FL, PRINT) do { } while (0)
116
117 #endif /* EN_DEBUG */
118
119 #include "opt_inet.h"
120 #include "opt_natm.h"
121 #include "opt_ddb.h"
122
123 #ifdef DDB
124 #undef  EN_DDBHOOK
125 #define EN_DDBHOOK      1
126 #endif
127
128 #include <sys/param.h>
129 #include <sys/systm.h>
130 #include <sys/queue.h>
131 #include <sys/sockio.h>
132 #include <sys/socket.h>
133 #include <sys/mbuf.h>
134 #include <sys/endian.h>
135 #include <sys/stdint.h>
136 #include <sys/lock.h>
137 #include <sys/mutex.h>
138 #include <sys/condvar.h>
139 #include <vm/uma.h>
140
141 #include <net/if.h>
142 #include <net/if_media.h>
143 #include <net/if_atm.h>
144
145 #if defined(INET) || defined(INET6)
146 #include <netinet/in.h>
147 #include <netinet/if_atm.h>
148 #endif
149
150 #ifdef NATM
151 #include <netnatm/natm.h>
152 #endif
153
154 #include <sys/bus.h>
155 #include <machine/bus.h>
156 #include <sys/rman.h>
157 #include <sys/module.h>
158 #include <sys/sysctl.h>
159 #include <sys/malloc.h>
160 #include <machine/resource.h>
161 #include <dev/utopia/utopia.h>
162 #include <dev/en/midwayreg.h>
163 #include <dev/en/midwayvar.h>
164
165 #include <net/bpf.h>
166
167 /*
168  * params
169  */
170 #ifndef EN_TXHIWAT
171 #define EN_TXHIWAT      (64 * 1024)     /* max 64 KB waiting to be DMAd out */
172 #endif
173
174 SYSCTL_DECL(_hw_atm);
175
176 /*
177  * dma tables
178  *
179  * The plan is indexed by the number of words to transfer.
180  * The maximum index is 15 for 60 words.
181  */
182 struct en_dmatab {
183         uint8_t bcode;          /* code */
184         uint8_t divshift;       /* byte divisor */
185 };
186
187 static const struct en_dmatab en_dmaplan[] = {
188   { 0, 0 },             /* 0 */         { MIDDMA_WORD, 2},      /* 1 */
189   { MIDDMA_2WORD, 3},   /* 2 */         { MIDDMA_WORD, 2},      /* 3 */
190   { MIDDMA_4WORD, 4},   /* 4 */         { MIDDMA_WORD, 2},      /* 5 */
191   { MIDDMA_2WORD, 3},   /* 6 */         { MIDDMA_WORD, 2},      /* 7 */
192   { MIDDMA_8WORD, 5},   /* 8 */         { MIDDMA_WORD, 2},      /* 9 */
193   { MIDDMA_2WORD, 3},   /* 10 */        { MIDDMA_WORD, 2},      /* 11 */
194   { MIDDMA_4WORD, 4},   /* 12 */        { MIDDMA_WORD, 2},      /* 13 */
195   { MIDDMA_2WORD, 3},   /* 14 */        { MIDDMA_WORD, 2},      /* 15 */
196   { MIDDMA_16WORD,6},   /* 16 */
197 };
198
199 /*
200  * prototypes
201  */
202 #ifdef EN_DDBHOOK
203 int en_dump(int unit, int level);
204 int en_dumpmem(int,int,int);
205 #endif
206 static void en_close_finish(struct en_softc *sc, struct en_vcc *vc);
207
208 #define EN_LOCK(SC)     do {                            \
209         DBG(SC, LOCK, ("ENLOCK %d\n", __LINE__));       \
210         mtx_lock(&sc->en_mtx);                          \
211     } while (0)
212 #define EN_UNLOCK(SC)   do {                            \
213         DBG(SC, LOCK, ("ENUNLOCK %d\n", __LINE__));     \
214         mtx_unlock(&sc->en_mtx);                        \
215     } while (0)
216 #define EN_CHECKLOCK(sc)        mtx_assert(&sc->en_mtx, MA_OWNED)
217
218 /*
219  * While a transmit mbuf is waiting to get transmit DMA resources we
220  * need to keep some information with it. We don't want to allocate
221  * additional memory for this so we stuff it into free fields in the
222  * mbuf packet header. Neither the checksum fields nor the rcvif field are used
223  * so use these.
224  */
225 #define TX_AAL5         0x1     /* transmit AAL5 PDU */
226 #define TX_HAS_TBD      0x2     /* TBD did fit into mbuf */
227 #define TX_HAS_PAD      0x4     /* padding did fit into mbuf */
228 #define TX_HAS_PDU      0x8     /* PDU trailer did fit into mbuf */
229
230 #define MBUF_SET_TX(M, VCI, FLAGS, DATALEN, PAD, MAP) do {              \
231         (M)->m_pkthdr.csum_data = (VCI) | ((FLAGS) << MID_VCI_BITS);    \
232         (M)->m_pkthdr.csum_flags = ((DATALEN) & 0xffff) |               \
233             ((PAD & 0x3f) << 16);                                       \
234         (M)->m_pkthdr.rcvif = (void *)(MAP);                            \
235     } while (0)
236
237 #define MBUF_GET_TX(M, VCI, FLAGS, DATALEN, PAD, MAP) do {              \
238         (VCI) = (M)->m_pkthdr.csum_data & ((1 << MID_VCI_BITS) - 1);    \
239         (FLAGS) = ((M)->m_pkthdr.csum_data >> MID_VCI_BITS) & 0xf;      \
240         (DATALEN) = (M)->m_pkthdr.csum_flags & 0xffff;                  \
241         (PAD) = ((M)->m_pkthdr.csum_flags >> 16) & 0x3f;                \
242         (MAP) = (void *)((M)->m_pkthdr.rcvif);                          \
243     } while (0)
244
245
246 #define EN_WRAPADD(START, STOP, CUR, VAL) do {                  \
247         (CUR) = (CUR) + (VAL);                                  \
248         if ((CUR) >= (STOP))                                    \
249                 (CUR) = (START) + ((CUR) - (STOP));             \
250     } while (0)
251
252 #define WORD_IDX(START, X) (((X) - (START)) / sizeof(uint32_t))
253
254 #define SETQ_END(SC, VAL) ((SC)->is_adaptec ?                   \
255         ((VAL) | (MID_DMA_END >> 4)) :                          \
256         ((VAL) | (MID_DMA_END)))
257
258 /*
259  * The dtq and drq members are set for each END entry in the corresponding
260  * card queue entry. It is used to find out, when a buffer has been
261  * finished DMAing and can be freed.
262  *
263  * We store sc->dtq and sc->drq data in the following format...
264  * the 0x80000 ensures we != 0
265  */
266 #define EN_DQ_MK(SLOT, LEN)     (((SLOT) << 20) | (LEN) | (0x80000))
267 #define EN_DQ_SLOT(X)           ((X) >> 20)
268 #define EN_DQ_LEN(X)            ((X) & 0x3ffff)
269
270 /*
271  * Variables
272  */
273 static uma_zone_t en_vcc_zone;
274
275 /***********************************************************************/
276
277 /*
278  * en_read{x}: read a word from the card. These are the only functions
279  * that read from the card.
280  */
281 static __inline uint32_t
282 en_readx(struct en_softc *sc, uint32_t r)
283 {
284         uint32_t v;
285
286 #ifdef EN_DIAG
287         if (r > MID_MAXOFF || (r % 4))
288                 panic("en_read out of range, r=0x%x", r);
289 #endif
290         v = bus_space_read_4(sc->en_memt, sc->en_base, r);
291         return (v);
292 }
293
294 static __inline uint32_t
295 en_read(struct en_softc *sc, uint32_t r)
296 {
297         uint32_t v;
298
299 #ifdef EN_DIAG
300         if (r > MID_MAXOFF || (r % 4))
301                 panic("en_read out of range, r=0x%x", r);
302 #endif
303         v = bus_space_read_4(sc->en_memt, sc->en_base, r);
304         DBG(sc, REG, ("en_read(%#x) -> %08x", r, v));
305         return (v);
306 }
307
308 /*
309  * en_write: write a word to the card. This is the only function that
310  * writes to the card.
311  */
312 static __inline void
313 en_write(struct en_softc *sc, uint32_t r, uint32_t v)
314 {
315 #ifdef EN_DIAG
316         if (r > MID_MAXOFF || (r % 4))
317                 panic("en_write out of range, r=0x%x", r);
318 #endif
319         DBG(sc, REG, ("en_write(%#x) <- %08x", r, v));
320         bus_space_write_4(sc->en_memt, sc->en_base, r, v);
321 }
322
323 /*
324  * en_k2sz: convert KBytes to a size parameter (a log2)
325  */
326 static __inline int
327 en_k2sz(int k)
328 {
329         switch(k) {
330           case 1:   return (0);
331           case 2:   return (1);
332           case 4:   return (2);
333           case 8:   return (3);
334           case 16:  return (4);
335           case 32:  return (5);
336           case 64:  return (6);
337           case 128: return (7);
338           default:
339                 panic("en_k2sz");
340         }
341         return (0);
342 }
343 #define en_log2(X) en_k2sz(X)
344
345 /*
346  * en_b2sz: convert a DMA burst code to its byte size
347  */
348 static __inline int
349 en_b2sz(int b)
350 {
351         switch (b) {
352           case MIDDMA_WORD:   return (1*4);
353           case MIDDMA_2WMAYBE:
354           case MIDDMA_2WORD:  return (2*4);
355           case MIDDMA_4WMAYBE:
356           case MIDDMA_4WORD:  return (4*4);
357           case MIDDMA_8WMAYBE:
358           case MIDDMA_8WORD:  return (8*4);
359           case MIDDMA_16WMAYBE:
360           case MIDDMA_16WORD: return (16*4);
361           default:
362                 panic("en_b2sz");
363         }
364         return (0);
365 }
366
367 /*
368  * en_sz2b: convert a burst size (bytes) to DMA burst code
369  */
370 static __inline int
371 en_sz2b(int sz)
372 {
373         switch (sz) {
374           case 1*4:  return (MIDDMA_WORD);
375           case 2*4:  return (MIDDMA_2WORD);
376           case 4*4:  return (MIDDMA_4WORD);
377           case 8*4:  return (MIDDMA_8WORD);
378           case 16*4: return (MIDDMA_16WORD);
379           default:
380                 panic("en_sz2b");
381         }
382         return(0);
383 }
384
385 #ifdef EN_DEBUG
386 /*
387  * Dump a packet
388  */
389 static void
390 en_dump_packet(struct en_softc *sc, struct mbuf *m)
391 {
392         int plen = m->m_pkthdr.len;
393         u_int pos = 0;
394         u_int totlen = 0;
395         int len;
396         u_char *ptr;
397
398         if_printf(&sc->ifatm.ifnet, "packet len=%d", plen);
399         while (m != NULL) {
400                 totlen += m->m_len;
401                 ptr = mtod(m, u_char *);
402                 for (len = 0; len < m->m_len; len++, pos++, ptr++) {
403                         if (pos % 16 == 8)
404                                 printf(" ");
405                         if (pos % 16 == 0)
406                                 printf("\n");
407                         printf(" %02x", *ptr);
408                 }
409                 m = m->m_next;
410         }
411         printf("\n");
412         if (totlen != plen)
413                 printf("sum of m_len=%u\n", totlen);
414 }
415 #endif
416
417 /*********************************************************************/
418 /*
419  * DMA maps
420  */
421
422 /*
423  * Map constructor for a MAP.
424  *
425  * This is called each time when a map is allocated
426  * from the pool and about to be returned to the user. Here we actually
427  * allocate the map if there isn't one. The problem is that we may fail
428  * to allocate the DMA map yet have no means to signal this error. Therefor
429  * when allocating a map, the call must check that there is a map. An
430  * additional problem is, that i386 maps will be NULL, yet are ok and must
431  * be freed so let's use a flag to signal allocation.
432  *
433  * Caveat: we have no way to know that we are called from an interrupt context
434  * here. We rely on the fact, that bus_dmamap_create uses M_NOWAIT in all
435  * its allocations.
436  *
437  * LOCK: any, not needed
438  */
439 static void
440 en_map_ctor(void *mem, int size, void *arg)
441 {
442         struct en_softc *sc = arg;
443         struct en_map *map = mem;
444         int err;
445
446         if (map->sc == NULL)
447                 map->sc = sc;
448
449         if (!(map->flags & ENMAP_ALLOC)) {
450                 err = bus_dmamap_create(sc->txtag, 0, &map->map);
451                 if (err != 0)
452                         if_printf(&sc->ifatm.ifnet,
453                             "cannot create DMA map %d\n", err);
454                 else
455                         map->flags |= ENMAP_ALLOC;
456         }
457         map->flags &= ~ENMAP_LOADED;
458 }
459
460 /*
461  * Map destructor.
462  *
463  * Called when a map is disposed into the zone. If the map is loaded, unload
464  * it.
465  *
466  * LOCK: any, not needed
467  */
468 static void
469 en_map_dtor(void *mem, int size, void *arg)
470 {
471         struct en_map *map = mem;
472
473         if (map->flags & ENMAP_LOADED) {
474                 bus_dmamap_unload(map->sc->txtag, map->map);
475                 map->flags &= ~ENMAP_LOADED;
476         }
477 }
478
479 /*
480  * Map finializer.
481  *
482  * This is called each time a map is returned from the zone to the system.
483  * Get rid of the dmamap here.
484  *
485  * LOCK: any, not needed
486  */
487 static void
488 en_map_fini(void *mem, int size)
489 {
490         struct en_map *map = mem;
491
492         if (map->flags & ENMAP_ALLOC)
493                 bus_dmamap_destroy(map->sc->txtag, map->map);
494 }
495
496 /*********************************************************************/
497 /*
498  * Transmission
499  */
500
501 /*
502  * Argument structure to load a transmit DMA map
503  */
504 struct txarg {
505         struct en_softc *sc;
506         struct mbuf *m;
507         u_int vci;
508         u_int chan;             /* transmit channel */
509         u_int datalen;          /* length of user data */
510         u_int flags;
511         u_int wait;             /* return: out of resources */
512 };
513
514 /*
515  * TX DMA map loader helper. This function is the callback when the map
516  * is loaded. It should fill the DMA segment descriptors into the hardware.
517  *
518  * LOCK: locked, needed
519  */
520 static void
521 en_txdma_load(void *uarg, bus_dma_segment_t *segs, int nseg, bus_size_t mapsize,
522     int error)
523 {
524         struct txarg *tx = uarg;
525         struct en_softc *sc = tx->sc;
526         struct en_txslot *slot = &sc->txslot[tx->chan];
527         uint32_t cur;           /* on-card buffer position (bytes offset) */
528         uint32_t dtq;           /* on-card queue position (byte offset) */
529         uint32_t last_dtq;      /* last DTQ we have written */
530         uint32_t tmp;
531         u_int free;             /* free queue entries on card */
532         u_int needalign, cnt;
533         bus_size_t rest;        /* remaining bytes in current segment */
534         bus_addr_t addr;
535         bus_dma_segment_t *s;
536         uint32_t count, bcode;
537         int i;
538
539         if (error != 0)
540                 return;
541
542         cur = slot->cur;
543         dtq = sc->dtq_us;
544         free = sc->dtq_free;
545
546         last_dtq = 0;           /* make gcc happy */
547
548         /*
549          * Local macro to add an entry to the transmit DMA area. If there
550          * are no entries left, return. Save the byte offset of the entry
551          * in last_dtq for later use.
552          */
553 #define PUT_DTQ_ENTRY(ENI, BCODE, COUNT, ADDR)                          \
554         if (free == 0) {                                                \
555                 EN_COUNT(sc->stats.txdtqout);                           \
556                 tx->wait = 1;                                           \
557                 return;                                                 \
558         }                                                               \
559         last_dtq = dtq;                                                 \
560         en_write(sc, dtq + 0, (ENI || !sc->is_adaptec) ?                \
561             MID_MK_TXQ_ENI(COUNT, tx->chan, 0, BCODE) :                 \
562             MID_MK_TXQ_ADP(COUNT, tx->chan, 0, BCODE));                 \
563         en_write(sc, dtq + 4, ADDR);                                    \
564                                                                         \
565         EN_WRAPADD(MID_DTQOFF, MID_DTQEND, dtq, 8);                     \
566         free--;
567
568         /*
569          * Local macro to generate a DMA entry to DMA cnt bytes. Updates
570          * the current buffer byte offset accordingly.
571          */
572 #define DO_DTQ(TYPE) do {                                               \
573         rest -= cnt;                                                    \
574         EN_WRAPADD(slot->start, slot->stop, cur, cnt);                  \
575         DBG(sc, TX, ("tx%d: "TYPE" %u bytes, %ju left, cur %#x",        \
576             tx->chan, cnt, (uintmax_t)rest, cur));                      \
577                                                                         \
578         PUT_DTQ_ENTRY(1, bcode, count, addr);                           \
579                                                                         \
580         addr += cnt;                                                    \
581     } while (0)
582
583         if (!(tx->flags & TX_HAS_TBD)) {
584                 /*
585                  * Prepend the TBD - it did not fit into the first mbuf
586                  */
587                 tmp = MID_TBD_MK1((tx->flags & TX_AAL5) ?
588                     MID_TBD_AAL5 : MID_TBD_NOAAL5,
589                     sc->vccs[tx->vci]->txspeed,
590                     tx->m->m_pkthdr.len / MID_ATMDATASZ);
591                 en_write(sc, cur, tmp);
592                 EN_WRAPADD(slot->start, slot->stop, cur, 4);
593
594                 tmp = MID_TBD_MK2(tx->vci, 0, 0);
595                 en_write(sc, cur, tmp);
596                 EN_WRAPADD(slot->start, slot->stop, cur, 4);
597
598                 /* update DMA address */
599                 PUT_DTQ_ENTRY(0, MIDDMA_JK, WORD_IDX(slot->start, cur), 0);
600         }
601
602         for (i = 0, s = segs; i < nseg; i++, s++) {
603                 rest = s->ds_len;
604                 addr = s->ds_addr;
605
606                 if (sc->is_adaptec) {
607                         /* adaptec card - simple */
608
609                         /* advance the on-card buffer pointer */
610                         EN_WRAPADD(slot->start, slot->stop, cur, rest);
611                         DBG(sc, TX, ("tx%d: adp %ju bytes %#jx (cur now 0x%x)",
612                             tx->chan, (uintmax_t)rest, (uintmax_t)addr, cur));
613
614                         PUT_DTQ_ENTRY(0, 0, rest, addr);
615
616                         continue;
617                 }
618
619                 /*
620                  * do we need to do a DMA op to align to the maximum
621                  * burst? Note, that we are alway 32-bit aligned.
622                  */
623                 if (sc->alburst &&
624                     (needalign = (addr & sc->bestburstmask)) != 0) {
625                         /* compute number of bytes, words and code */
626                         cnt = sc->bestburstlen - needalign;
627                         if (cnt > rest)
628                                 cnt = rest;
629                         count = cnt / sizeof(uint32_t);
630                         if (sc->noalbursts) {
631                                 bcode = MIDDMA_WORD;
632                         } else {
633                                 bcode = en_dmaplan[count].bcode;
634                                 count = cnt >> en_dmaplan[count].divshift;
635                         }
636                         DO_DTQ("al_dma");
637                 }
638
639                 /* do we need to do a max-sized burst? */
640                 if (rest >= sc->bestburstlen) {
641                         count = rest >> sc->bestburstshift;
642                         cnt = count << sc->bestburstshift;
643                         bcode = sc->bestburstcode;
644                         DO_DTQ("best_dma");
645                 }
646
647                 /* do we need to do a cleanup burst? */
648                 if (rest != 0) {
649                         cnt = rest;
650                         count = rest / sizeof(uint32_t);
651                         if (sc->noalbursts) {
652                                 bcode = MIDDMA_WORD;
653                         } else {
654                                 bcode = en_dmaplan[count].bcode;
655                                 count = cnt >> en_dmaplan[count].divshift;
656                         }
657                         DO_DTQ("clean_dma");
658                 }
659         }
660
661         KASSERT (tx->flags & TX_HAS_PAD, ("PDU not padded"));
662
663         if ((tx->flags & TX_AAL5) && !(tx->flags & TX_HAS_PDU)) {
664                 /*
665                  * Append the AAL5 PDU trailer
666                  */
667                 tmp = MID_PDU_MK1(0, 0, tx->datalen);
668                 en_write(sc, cur, tmp);
669                 EN_WRAPADD(slot->start, slot->stop, cur, 4);
670
671                 en_write(sc, cur, 0);
672                 EN_WRAPADD(slot->start, slot->stop, cur, 4);
673
674                 /* update DMA address */
675                 PUT_DTQ_ENTRY(0, MIDDMA_JK, WORD_IDX(slot->start, cur), 0);
676         }
677
678         /* record the end for the interrupt routine */
679         sc->dtq[MID_DTQ_A2REG(last_dtq)] =
680             EN_DQ_MK(tx->chan, tx->m->m_pkthdr.len);
681
682         /* set the end flag in the last descriptor */
683         en_write(sc, last_dtq + 0, SETQ_END(sc, en_read(sc, last_dtq + 0)));
684
685 #undef PUT_DTQ_ENTRY
686 #undef DO_DTQ
687
688         /* commit */
689         slot->cur = cur;
690         sc->dtq_free = free;
691         sc->dtq_us = dtq;
692
693         /* tell card */
694         en_write(sc, MID_DMA_WRTX, MID_DTQ_A2REG(sc->dtq_us));
695 }
696
697 /*
698  * en_txdma: start transmit DMA on the given channel, if possible
699  *
700  * This is called from two places: when we got new packets from the upper
701  * layer or when we found that buffer space has freed up during interrupt
702  * processing.
703  *
704  * LOCK: locked, needed
705  */
706 static void
707 en_txdma(struct en_softc *sc, struct en_txslot *slot)
708 {
709         struct en_map *map;
710         struct mbuf *lastm;
711         struct txarg tx;
712         u_int pad;
713         int error;
714
715         DBG(sc, TX, ("tx%td: starting ...", slot - sc->txslot));
716   again:
717         bzero(&tx, sizeof(tx));
718         tx.chan = slot - sc->txslot;
719         tx.sc = sc;
720
721         /*
722          * get an mbuf waiting for DMA
723          */
724         _IF_DEQUEUE(&slot->q, tx.m);
725         if (tx.m == NULL) {
726                 DBG(sc, TX, ("tx%td: ...done!", slot - sc->txslot));
727                 return;
728         }
729         MBUF_GET_TX(tx.m, tx.vci, tx.flags, tx.datalen, pad, map);
730
731         /*
732          * note: don't use the entire buffer space.  if WRTX becomes equal
733          * to RDTX, the transmitter stops assuming the buffer is empty!  --kjc
734          */
735         if (tx.m->m_pkthdr.len >= slot->bfree) {
736                 EN_COUNT(sc->stats.txoutspace);
737                 DBG(sc, TX, ("tx%td: out of transmit space", slot - sc->txslot));
738                 goto waitres;
739         }
740   
741         lastm = NULL;
742         if (!(tx.flags & TX_HAS_PAD)) {
743                 if (pad != 0) {
744                         /* Append the padding buffer */
745                         (void)m_length(tx.m, &lastm);
746                         lastm->m_next = sc->padbuf;
747                         sc->padbuf->m_len = pad;
748                 }
749                 tx.flags |= TX_HAS_PAD;
750         }
751
752         /*
753          * Try to load that map
754          */
755         error = bus_dmamap_load_mbuf(sc->txtag, map->map, tx.m,
756             en_txdma_load, &tx, BUS_DMA_NOWAIT);
757
758         if (lastm != NULL)
759                 lastm->m_next = NULL;
760
761         if (error != 0) {
762                 if_printf(&sc->ifatm.ifnet, "loading TX map failed %d\n",
763                     error);
764                 goto dequeue_drop;
765         }
766         map->flags |= ENMAP_LOADED;
767         if (tx.wait) {
768                 /* probably not enough space */
769                 bus_dmamap_unload(map->sc->txtag, map->map);
770                 map->flags &= ~ENMAP_LOADED;
771
772                 sc->need_dtqs = 1;
773                 DBG(sc, TX, ("tx%td: out of transmit DTQs", slot - sc->txslot));
774                 goto waitres;
775         }
776
777         EN_COUNT(sc->stats.launch);
778         sc->ifatm.ifnet.if_opackets++;
779
780         sc->vccs[tx.vci]->opackets++;
781         sc->vccs[tx.vci]->obytes += tx.datalen;
782
783 #ifdef ENABLE_BPF
784         if (sc->ifatm.ifnet.if_bpf != NULL) {
785                 /*
786                  * adjust the top of the mbuf to skip the TBD if present
787                  * before passing the packet to bpf.
788                  * Also remove padding and the PDU trailer. Assume both of
789                  * them to be in the same mbuf. pktlen, m_len and m_data
790                  * are not needed anymore so we can change them.
791                  */
792                 if (tx.flags & TX_HAS_TBD) {
793                         tx.m->m_data += MID_TBD_SIZE;
794                         tx.m->m_len -= MID_TBD_SIZE;
795                 }
796                 tx.m->m_pkthdr.len = m_length(tx.m, &lastm);
797                 if (tx.m->m_pkthdr.len > tx.datalen) {
798                         lastm->m_len -= tx.m->m_pkthdr.len - tx.datalen;
799                         tx.m->m_pkthdr.len = tx.datalen;
800                 }
801
802                 BPF_MTAP(&sc->ifatm.ifnet, tx.m);
803         }
804 #endif
805
806         /*
807          * do some housekeeping and get the next packet
808          */
809         slot->bfree -= tx.m->m_pkthdr.len;
810         _IF_ENQUEUE(&slot->indma, tx.m);
811
812         goto again;
813
814         /*
815          * error handling. This is jumped to when we just want to drop
816          * the packet. Must be unlocked here.
817          */
818   dequeue_drop:
819         if (map != NULL)
820                 uma_zfree(sc->map_zone, map);
821
822         slot->mbsize -= tx.m->m_pkthdr.len;
823
824         m_freem(tx.m);
825
826         goto again;
827
828   waitres:
829         _IF_PREPEND(&slot->q, tx.m);
830 }
831
832 /*
833  * Create a copy of a single mbuf. It can have either internal or
834  * external data, it may have a packet header. External data is really
835  * copied, so the new buffer is writeable.
836  *
837  * LOCK: any, not needed
838  */
839 static struct mbuf *
840 copy_mbuf(struct mbuf *m)
841 {
842         struct mbuf *new;
843
844         MGET(new, M_TRYWAIT, MT_DATA);
845         if (new == NULL)
846                 return (NULL);
847
848         if (m->m_flags & M_PKTHDR) {
849                 M_MOVE_PKTHDR(new, m);
850                 if (m->m_len > MHLEN) {
851                         MCLGET(new, M_TRYWAIT);
852                         if ((m->m_flags & M_EXT) == 0) {
853                                 m_free(new);
854                                 return (NULL);
855                         }
856                 }
857         } else {
858                 if (m->m_len > MLEN) {
859                         MCLGET(new, M_TRYWAIT);
860                         if ((m->m_flags & M_EXT) == 0) {
861                                 m_free(new);
862                                 return (NULL);
863                         }
864                 }
865         }
866
867         bcopy(m->m_data, new->m_data, m->m_len);
868         new->m_len = m->m_len;
869         new->m_flags &= ~M_RDONLY;
870
871         return (new);
872 }
873
874 /*
875  * This function is called when we have an ENI adapter. It fixes the
876  * mbuf chain, so that all addresses and lengths are 4 byte aligned.
877  * The overall length is already padded to multiple of cells plus the
878  * TBD so this must always succeed. The routine can fail, when it
879  * needs to copy an mbuf (this may happen if an mbuf is readonly).
880  *
881  * We assume here, that aligning the virtual addresses to 4 bytes also
882  * aligns the physical addresses.
883  *
884  * LOCK: locked, needed
885  */
886 static struct mbuf *
887 en_fix_mchain(struct en_softc *sc, struct mbuf *m0, u_int *pad)
888 {
889         struct mbuf **prev = &m0;
890         struct mbuf *m = m0;
891         struct mbuf *new;
892         u_char *d;
893         int off;
894
895         while (m != NULL) {
896                 d = mtod(m, u_char *);
897                 if ((off = (uintptr_t)d % sizeof(uint32_t)) != 0) {
898                         EN_COUNT(sc->stats.mfixaddr);
899                         if (M_WRITABLE(m)) {
900                                 bcopy(d, d - off, m->m_len);
901                                 m->m_data -= off;
902                         } else {
903                                 if ((new = copy_mbuf(m)) == NULL) {
904                                         EN_COUNT(sc->stats.mfixfail);
905                                         m_freem(m0);
906                                         return (NULL);
907                                 }
908                                 new->m_next = m_free(m);
909                                 *prev = m = new;
910                         }
911                 }
912
913                 if ((off = m->m_len % sizeof(uint32_t)) != 0) {
914                         EN_COUNT(sc->stats.mfixlen);
915                         if (!M_WRITABLE(m)) {
916                                 if ((new = copy_mbuf(m)) == NULL) {
917                                         EN_COUNT(sc->stats.mfixfail);
918                                         m_freem(m0);
919                                         return (NULL);
920                                 }
921                                 new->m_next = m_free(m);
922                                 *prev = m = new;
923                         }
924                         d = mtod(m, u_char *) + m->m_len;
925                         off = 4 - off;
926                         while (off) {
927                                 while (m->m_next && m->m_next->m_len == 0)
928                                         m->m_next = m_free(m->m_next);
929
930                                 if (m->m_next == NULL) {
931                                         *d++ = 0;
932                                         KASSERT(*pad > 0, ("no padding space"));
933                                         (*pad)--;
934                                 } else {
935                                         *d++ = *mtod(m->m_next, u_char *);
936                                         m->m_next->m_len--;
937                                         m->m_next->m_data++;
938                                 }
939                                 m->m_len++;
940                                 off--;
941                         }
942                 }
943
944                 prev = &m->m_next;
945                 m = m->m_next;
946         }
947
948         return (m0);
949 }
950
951 /*
952  * en_start: start transmitting the next packet that needs to go out
953  * if there is one. We take off all packets from the interface's queue and
954  * put them into the channels queue.
955  *
956  * Here we also prepend the transmit packet descriptor and append the padding
957  * and (for aal5) the PDU trailer. This is different from the original driver:
958  * we assume, that allocating one or two additional mbufs is actually cheaper
959  * than all this algorithmic fiddling we would need otherwise.
960  *
961  * While the packet is on the channels wait queue we use the csum_* fields
962  * in the packet header to hold the original datalen, the AAL5 flag and the
963  * VCI. The packet length field in the header holds the needed buffer space.
964  * This may actually be more than the length of the current mbuf chain (when
965  * one or more of TBD, padding and PDU do not fit).
966  *
967  * LOCK: unlocked, needed
968  */
969 static void
970 en_start(struct ifnet *ifp)
971 {
972         struct en_softc *sc = (struct en_softc *)ifp->if_softc;
973         struct mbuf *m, *lastm;
974         struct atm_pseudohdr *ap;
975         u_int pad;              /* 0-bytes to pad at PDU end */
976         u_int datalen;          /* length of user data */
977         u_int vci;              /* the VCI we are transmitting on */
978         u_int flags;
979         uint32_t tbd[2];
980         uint32_t pdu[2];
981         struct en_vcc *vc;
982         struct en_map *map;
983         struct en_txslot *tx;
984
985         while (1) {
986                 IF_DEQUEUE(&ifp->if_snd, m);
987                 if (m == NULL)
988                         return;
989
990                 flags = 0;
991
992                 ap = mtod(m, struct atm_pseudohdr *);
993                 vci = ATM_PH_VCI(ap);
994
995                 if (ATM_PH_VPI(ap) != 0 || vci >= MID_N_VC ||
996                     (vc = sc->vccs[vci]) == NULL ||
997                     (vc->vflags & VCC_CLOSE_RX)) {
998                         DBG(sc, TX, ("output vpi=%u, vci=%u -- drop",
999                             ATM_PH_VPI(ap), vci));
1000                         m_freem(m);
1001                         continue;
1002                 }
1003                 if (vc->vcc.aal == ATMIO_AAL_5)
1004                         flags |= TX_AAL5;
1005                 m_adj(m, sizeof(struct atm_pseudohdr));
1006
1007                 /*
1008                  * (re-)calculate size of packet (in bytes)
1009                  */
1010                 m->m_pkthdr.len = datalen = m_length(m, &lastm);
1011
1012                 /*
1013                  * computing how much padding we need on the end of the mbuf,
1014                  * then see if we can put the TBD at the front of the mbuf
1015                  * where the link header goes (well behaved protocols will
1016                  * reserve room for us). Last, check if room for PDU tail.
1017                  */
1018                 if (flags & TX_AAL5)
1019                         m->m_pkthdr.len += MID_PDU_SIZE;
1020                 m->m_pkthdr.len = roundup(m->m_pkthdr.len, MID_ATMDATASZ);
1021                 pad = m->m_pkthdr.len - datalen;
1022                 if (flags & TX_AAL5)
1023                         pad -= MID_PDU_SIZE;
1024                 m->m_pkthdr.len += MID_TBD_SIZE;
1025
1026                 DBG(sc, TX, ("txvci%d: buflen=%u datalen=%u lead=%d trail=%d",
1027                     vci, m->m_pkthdr.len, datalen, (int)M_LEADINGSPACE(m),
1028                     (int)M_TRAILINGSPACE(lastm)));
1029
1030                 /*
1031                  * From here on we need access to sc
1032                  */
1033                 EN_LOCK(sc);
1034
1035                 /*
1036                  * Allocate a map. We do this here rather then in en_txdma,
1037                  * because en_txdma is also called from the interrupt handler
1038                  * and we are going to have a locking problem then. We must
1039                  * use NOWAIT here, because the ip_output path holds various
1040                  * locks.
1041                  */
1042                 map = uma_zalloc_arg(sc->map_zone, sc, M_NOWAIT);
1043                 if (map == NULL || !(map->flags & ENMAP_ALLOC)) {
1044                         /* drop that packet */
1045                         EN_COUNT(sc->stats.txnomap);
1046                         if (map != NULL)
1047                                 uma_zfree(sc->map_zone, map);
1048                         EN_UNLOCK(sc);
1049                         m_freem(m);
1050                         continue;
1051                 }
1052
1053                 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1054                         EN_UNLOCK(sc);
1055                         uma_zfree(sc->map_zone, map);
1056                         m_freem(m);
1057                         continue;
1058                 }
1059
1060                 /*
1061                  * Look, whether we can prepend the TBD (8 byte)
1062                  */
1063                 if (M_WRITABLE(m) && M_LEADINGSPACE(m) >= MID_TBD_SIZE) {
1064                         tbd[0] = htobe32(MID_TBD_MK1((flags & TX_AAL5) ?
1065                             MID_TBD_AAL5 : MID_TBD_NOAAL5,
1066                             vc->txspeed, m->m_pkthdr.len / MID_ATMDATASZ));
1067                         tbd[1] = htobe32(MID_TBD_MK2(vci, 0, 0));
1068
1069                         m->m_data -= MID_TBD_SIZE;
1070                         bcopy(tbd, m->m_data, MID_TBD_SIZE);
1071                         m->m_len += MID_TBD_SIZE;
1072                         flags |= TX_HAS_TBD;
1073                 }
1074
1075                 /*
1076                  * Check whether the padding fits (must be writeable -
1077                  * we pad with zero).
1078                  */
1079                 if (M_WRITABLE(lastm) && M_TRAILINGSPACE(lastm) >= pad) {
1080                         bzero(lastm->m_data + lastm->m_len, pad);
1081                         lastm->m_len += pad;
1082                         flags |= TX_HAS_PAD;
1083
1084                         if ((flags & TX_AAL5) &&
1085                             M_TRAILINGSPACE(lastm) > MID_PDU_SIZE) {
1086                                 pdu[0] = htobe32(MID_PDU_MK1(0, 0, datalen));
1087                                 pdu[1] = 0;
1088                                 bcopy(pdu, lastm->m_data + lastm->m_len,
1089                                     MID_PDU_SIZE);
1090                                 lastm->m_len += MID_PDU_SIZE;
1091                                 flags |= TX_HAS_PDU;
1092                         }
1093                 }
1094
1095                 if (!sc->is_adaptec &&
1096                     (m = en_fix_mchain(sc, m, &pad)) == NULL) {
1097                         EN_UNLOCK(sc);
1098                         uma_zfree(sc->map_zone, map);
1099                         continue;
1100                 }
1101
1102                 /*
1103                  * get assigned channel (will be zero unless txspeed is set)
1104                  */
1105                 tx = vc->txslot;
1106
1107                 if (m->m_pkthdr.len > EN_TXSZ * 1024) {
1108                         DBG(sc, TX, ("tx%zu: packet larger than xmit buffer "
1109                             "(%d > %d)\n", tx - sc->txslot, m->m_pkthdr.len,
1110                             EN_TXSZ * 1024));
1111                         EN_UNLOCK(sc);
1112                         m_freem(m);
1113                         uma_zfree(sc->map_zone, map);
1114                         continue;
1115                 }
1116
1117                 if (tx->mbsize > EN_TXHIWAT) {
1118                         EN_COUNT(sc->stats.txmbovr);
1119                         DBG(sc, TX, ("tx%d: buffer space shortage",
1120                             tx - sc->txslot));
1121                         EN_UNLOCK(sc);
1122                         m_freem(m);
1123                         uma_zfree(sc->map_zone, map);
1124                         continue;
1125                 }
1126
1127                 /* commit */
1128                 tx->mbsize += m->m_pkthdr.len;
1129
1130                 DBG(sc, TX, ("tx%zu: VCI=%d, speed=0x%x, buflen=%d, mbsize=%d",
1131                     tx - sc->txslot, vci, sc->vccs[vci]->txspeed,
1132                     m->m_pkthdr.len, tx->mbsize));
1133
1134                 MBUF_SET_TX(m, vci, flags, datalen, pad, map);
1135
1136                 _IF_ENQUEUE(&tx->q, m);
1137
1138                 en_txdma(sc, tx);
1139
1140                 EN_UNLOCK(sc);
1141         }
1142 }
1143
1144 /*********************************************************************/
1145 /*
1146  * VCs
1147  */
1148
1149 /*
1150  * en_loadvc: load a vc tab entry from a slot
1151  *
1152  * LOCK: locked, needed
1153  */
1154 static void
1155 en_loadvc(struct en_softc *sc, struct en_vcc *vc)
1156 {
1157         uint32_t reg = en_read(sc, MID_VC(vc->vcc.vci));
1158
1159         reg = MIDV_SETMODE(reg, MIDV_TRASH);
1160         en_write(sc, MID_VC(vc->vcc.vci), reg);
1161         DELAY(27);
1162
1163         /* no need to set CRC */
1164
1165         /* read pointer = 0, desc. start = 0 */
1166         en_write(sc, MID_DST_RP(vc->vcc.vci), 0);
1167         /* write pointer = 0 */
1168         en_write(sc, MID_WP_ST_CNT(vc->vcc.vci), 0);
1169         /* set mode, size, loc */
1170         en_write(sc, MID_VC(vc->vcc.vci), vc->rxslot->mode);
1171
1172         vc->rxslot->cur = vc->rxslot->start;
1173
1174         DBG(sc, VC, ("rx%d: assigned to VCI %d", vc->rxslot - sc->rxslot,
1175             vc->vcc.vci));
1176 }
1177
1178 /*
1179  * Open the given vcc.
1180  *
1181  * LOCK: unlocked, needed
1182  */
1183 static int
1184 en_open_vcc(struct en_softc *sc, struct atmio_openvcc *op)
1185 {
1186         uint32_t oldmode, newmode;
1187         struct en_rxslot *slot;
1188         struct en_vcc *vc;
1189         int error = 0;
1190
1191         DBG(sc, IOCTL, ("enable vpi=%d, vci=%d, flags=%#x",
1192             op->param.vpi, op->param.vci, op->param.flags));
1193
1194         if (op->param.vpi != 0 || op->param.vci >= MID_N_VC)
1195                 return (EINVAL);
1196
1197         vc = uma_zalloc(en_vcc_zone, M_NOWAIT | M_ZERO);
1198         if (vc == NULL)
1199                 return (ENOMEM);
1200
1201         EN_LOCK(sc);
1202
1203         if (sc->vccs[op->param.vci] != NULL) {
1204                 error = EBUSY;
1205                 goto done;
1206         }
1207
1208         /* find a free receive slot */
1209         for (slot = sc->rxslot; slot < &sc->rxslot[sc->en_nrx]; slot++)
1210                 if (slot->vcc == NULL)
1211                         break;
1212         if (slot == &sc->rxslot[sc->en_nrx]) {
1213                 error = ENOSPC;
1214                 goto done;
1215         }
1216
1217         vc->rxslot = slot;
1218         vc->rxhand = op->rxhand;
1219         vc->vcc = op->param;
1220
1221         oldmode = slot->mode;
1222         newmode = (op->param.aal == ATMIO_AAL_5) ? MIDV_AAL5 : MIDV_NOAAL;
1223         slot->mode = MIDV_SETMODE(oldmode, newmode);
1224         slot->vcc = vc;
1225
1226         KASSERT (_IF_QLEN(&slot->indma) == 0 && _IF_QLEN(&slot->q) == 0,
1227             ("en_rxctl: left over mbufs on enable slot=%tu",
1228             vc->rxslot - sc->rxslot));
1229
1230         vc->txspeed = 0;
1231         vc->txslot = sc->txslot;
1232         vc->txslot->nref++;     /* bump reference count */
1233
1234         en_loadvc(sc, vc);      /* does debug printf for us */
1235
1236         /* don't free below */
1237         sc->vccs[vc->vcc.vci] = vc;
1238         vc = NULL;
1239         sc->vccs_open++;
1240
1241   done:
1242         if (vc != NULL)
1243                 uma_zfree(en_vcc_zone, vc);
1244
1245         EN_UNLOCK(sc);
1246         return (error);
1247 }
1248
1249 /*
1250  * Close finished
1251  */
1252 static void
1253 en_close_finish(struct en_softc *sc, struct en_vcc *vc)
1254 {
1255
1256         if (vc->rxslot != NULL)
1257                 vc->rxslot->vcc = NULL;
1258
1259         DBG(sc, VC, ("vci: %u free (%p)", vc->vcc.vci, vc));
1260
1261         sc->vccs[vc->vcc.vci] = NULL;
1262         uma_zfree(en_vcc_zone, vc);
1263         sc->vccs_open--;
1264 }
1265
1266 /*
1267  * LOCK: unlocked, needed
1268  */
1269 static int
1270 en_close_vcc(struct en_softc *sc, struct atmio_closevcc *cl)
1271 {
1272         uint32_t oldmode, newmode;
1273         struct en_vcc *vc;
1274         int error = 0;
1275
1276         DBG(sc, IOCTL, ("disable vpi=%d, vci=%d", cl->vpi, cl->vci));
1277
1278         if (cl->vpi != 0 || cl->vci >= MID_N_VC)
1279                 return (EINVAL);
1280
1281         EN_LOCK(sc);
1282         if ((vc = sc->vccs[cl->vci]) == NULL) {
1283                 error = ENOTCONN;
1284                 goto done;
1285         }
1286
1287         /*
1288          * turn off VCI
1289          */
1290         if (vc->rxslot == NULL) {
1291                 error = ENOTCONN;
1292                 goto done;
1293         }
1294         if (vc->vflags & VCC_DRAIN) {
1295                 error = EINVAL;
1296                 goto done;
1297         }
1298
1299         oldmode = en_read(sc, MID_VC(cl->vci));
1300         newmode = MIDV_SETMODE(oldmode, MIDV_TRASH) & ~MIDV_INSERVICE;
1301         en_write(sc, MID_VC(cl->vci), (newmode | (oldmode & MIDV_INSERVICE)));
1302
1303         /* halt in tracks, be careful to preserve inservice bit */
1304         DELAY(27);
1305         vc->rxslot->mode = newmode;
1306
1307         vc->txslot->nref--;
1308
1309         /* if stuff is still going on we are going to have to drain it out */
1310         if (_IF_QLEN(&vc->rxslot->indma) == 0 &&
1311             _IF_QLEN(&vc->rxslot->q) == 0 &&
1312             (vc->vflags & VCC_SWSL) == 0) {
1313                 en_close_finish(sc, vc);
1314                 goto done;
1315         }
1316
1317         vc->vflags |= VCC_DRAIN;
1318         DBG(sc, IOCTL, ("VCI %u now draining", cl->vci));
1319
1320         if (vc->vcc.flags & ATMIO_FLAG_ASYNC)
1321                 goto done;
1322
1323         vc->vflags |= VCC_CLOSE_RX;
1324         while ((sc->ifatm.ifnet.if_flags & IFF_RUNNING) &&
1325             (vc->vflags & VCC_DRAIN))
1326                 cv_wait(&sc->cv_close, &sc->en_mtx);
1327
1328         en_close_finish(sc, vc);
1329         if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING)) {
1330                 error = EIO;
1331                 goto done;
1332         }
1333
1334
1335   done:
1336         EN_UNLOCK(sc);
1337         return (error);
1338 }
1339
1340 /*********************************************************************/
1341 /*
1342  * starting/stopping the card
1343  */
1344
1345 /*
1346  * en_reset_ul: reset the board, throw away work in progress.
1347  * must en_init to recover.
1348  *
1349  * LOCK: locked, needed
1350  */
1351 static void
1352 en_reset_ul(struct en_softc *sc)
1353 {
1354         struct en_map *map;
1355         struct mbuf *m;
1356         struct en_rxslot *rx;
1357         int lcv;
1358
1359         if_printf(&sc->ifatm.ifnet, "reset\n");
1360         sc->ifatm.ifnet.if_flags &= ~IFF_RUNNING;
1361
1362         if (sc->en_busreset)
1363                 sc->en_busreset(sc);
1364         en_write(sc, MID_RESID, 0x0);   /* reset hardware */
1365
1366         /*
1367          * recv: dump any mbufs we are dma'ing into, if DRAINing, then a reset
1368          * will free us! Don't release the rxslot from the channel.
1369          */
1370         for (lcv = 0 ; lcv < MID_N_VC ; lcv++) {
1371                 if (sc->vccs[lcv] == NULL)
1372                         continue;
1373                 rx = sc->vccs[lcv]->rxslot;
1374
1375                 for (;;) {
1376                         _IF_DEQUEUE(&rx->indma, m);
1377                         if (m == NULL)
1378                                 break;
1379                         map = (void *)m->m_pkthdr.rcvif;
1380                         uma_zfree(sc->map_zone, map);
1381                         m_freem(m);
1382                 }
1383                 for (;;) {
1384                         _IF_DEQUEUE(&rx->q, m);
1385                         if (m == NULL)
1386                                 break;
1387                         m_freem(m);
1388                 }
1389                 sc->vccs[lcv]->vflags = 0;
1390         }
1391
1392         /*
1393          * xmit: dump everything
1394          */
1395         for (lcv = 0 ; lcv < EN_NTX ; lcv++) {
1396                 for (;;) {
1397                         _IF_DEQUEUE(&sc->txslot[lcv].indma, m);
1398                         if (m == NULL)
1399                                 break;
1400                         map = (void *)m->m_pkthdr.rcvif;
1401                         uma_zfree(sc->map_zone, map);
1402                         m_freem(m);
1403                 }
1404                 for (;;) {
1405                         _IF_DEQUEUE(&sc->txslot[lcv].q, m);
1406                         if (m == NULL)
1407                                 break;
1408                         map = (void *)m->m_pkthdr.rcvif;
1409                         uma_zfree(sc->map_zone, map);
1410                         m_freem(m);
1411                 }
1412                 sc->txslot[lcv].mbsize = 0;
1413         }
1414
1415         /*
1416          * Unstop all waiters
1417          */
1418         cv_broadcast(&sc->cv_close);
1419 }
1420
1421 /*
1422  * en_reset: reset the board, throw away work in progress.
1423  * must en_init to recover.
1424  *
1425  * LOCK: unlocked, needed
1426  *
1427  * Use en_reset_ul if you alreay have the lock
1428  */
1429 void
1430 en_reset(struct en_softc *sc)
1431 {
1432         EN_LOCK(sc);
1433         en_reset_ul(sc);
1434         EN_UNLOCK(sc);
1435 }
1436
1437
1438 /*
1439  * en_init: init board and sync the card with the data in the softc.
1440  *
1441  * LOCK: locked, needed
1442  */
1443 static void
1444 en_init(struct en_softc *sc)
1445 {
1446         int vc, slot;
1447         uint32_t loc;
1448
1449         if ((sc->ifatm.ifnet.if_flags & IFF_UP) == 0) {
1450                 DBG(sc, INIT, ("going down"));
1451                 en_reset(sc);                           /* to be safe */
1452                 return;
1453         }
1454
1455         DBG(sc, INIT, ("going up"));
1456         sc->ifatm.ifnet.if_flags |= IFF_RUNNING;        /* enable */
1457
1458         if (sc->en_busreset)
1459                 sc->en_busreset(sc);
1460         en_write(sc, MID_RESID, 0x0);           /* reset */
1461
1462         /* zero memory */
1463         bus_space_set_region_4(sc->en_memt, sc->en_base,
1464             MID_RAMOFF, 0, sc->en_obmemsz / 4);
1465
1466         /*
1467          * init obmem data structures: vc tab, dma q's, slist.
1468          *
1469          * note that we set drq_free/dtq_free to one less than the total number
1470          * of DTQ/DRQs present.   we do this because the card uses the condition
1471          * (drq_chip == drq_us) to mean "list is empty"... but if you allow the
1472          * circular list to be completely full then (drq_chip == drq_us) [i.e.
1473          * the drq_us pointer will wrap all the way around].   by restricting
1474          * the number of active requests to (N - 1) we prevent the list from
1475          * becoming completely full.    note that the card will sometimes give
1476          * us an interrupt for a DTQ/DRQ we have already processes... this helps
1477          * keep that interrupt from messing us up.
1478          */
1479         bzero(&sc->drq, sizeof(sc->drq));
1480         sc->drq_free = MID_DRQ_N - 1;
1481         sc->drq_chip = MID_DRQ_REG2A(en_read(sc, MID_DMA_RDRX));
1482         en_write(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip)); 
1483         sc->drq_us = sc->drq_chip;
1484
1485         bzero(&sc->dtq, sizeof(sc->dtq));
1486         sc->dtq_free = MID_DTQ_N - 1;
1487         sc->dtq_chip = MID_DTQ_REG2A(en_read(sc, MID_DMA_RDTX));
1488         en_write(sc, MID_DMA_WRTX, MID_DRQ_A2REG(sc->dtq_chip)); 
1489         sc->dtq_us = sc->dtq_chip;
1490
1491         sc->hwslistp = MID_SL_REG2A(en_read(sc, MID_SERV_WRITE));
1492         sc->swsl_size = sc->swsl_head = sc->swsl_tail = 0;
1493
1494         DBG(sc, INIT, ("drq free/chip: %d/0x%x, dtq free/chip: %d/0x%x, "
1495             "hwslist: 0x%x", sc->drq_free, sc->drq_chip, sc->dtq_free,
1496             sc->dtq_chip, sc->hwslistp));
1497
1498         for (slot = 0 ; slot < EN_NTX ; slot++) {
1499                 sc->txslot[slot].bfree = EN_TXSZ * 1024;
1500                 en_write(sc, MIDX_READPTR(slot), 0);
1501                 en_write(sc, MIDX_DESCSTART(slot), 0);
1502                 loc = sc->txslot[slot].cur = sc->txslot[slot].start;
1503                 loc = loc - MID_RAMOFF;
1504                 /* mask, cvt to words */
1505                 loc = (loc & ~((EN_TXSZ * 1024) - 1)) >> 2;
1506                 /* top 11 bits */
1507                 loc = loc >> MIDV_LOCTOPSHFT;
1508                 en_write(sc, MIDX_PLACE(slot), MIDX_MKPLACE(en_k2sz(EN_TXSZ),
1509                     loc));
1510                 DBG(sc, INIT, ("tx%d: place 0x%x", slot,
1511                     (u_int)en_read(sc, MIDX_PLACE(slot))));
1512         }
1513
1514         for (vc = 0; vc < MID_N_VC; vc++) 
1515                 if (sc->vccs[vc] != NULL)
1516                         en_loadvc(sc, sc->vccs[vc]);
1517
1518         /*
1519          * enable!
1520          */
1521         en_write(sc, MID_INTENA, MID_INT_TX | MID_INT_DMA_OVR | MID_INT_IDENT |
1522             MID_INT_LERR | MID_INT_DMA_ERR | MID_INT_DMA_RX | MID_INT_DMA_TX |
1523             MID_INT_SERVICE | MID_INT_SUNI | MID_INT_STATS);
1524         en_write(sc, MID_MAST_CSR, MID_SETIPL(sc->ipl) | MID_MCSR_ENDMA |
1525             MID_MCSR_ENTX | MID_MCSR_ENRX);
1526 }
1527
1528 /*********************************************************************/
1529 /*
1530  * Ioctls
1531  */
1532 /*
1533  * en_ioctl: handle ioctl requests
1534  *
1535  * NOTE: if you add an ioctl to set txspeed, you should choose a new
1536  * TX channel/slot.   Choose the one with the lowest sc->txslot[slot].nref
1537  * value, subtract one from sc->txslot[0].nref, add one to the
1538  * sc->txslot[slot].nref, set sc->txvc2slot[vci] = slot, and then set
1539  * txspeed[vci].
1540  *
1541  * LOCK: unlocked, needed
1542  */
1543 static int
1544 en_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1545 {
1546         struct en_softc *sc = (struct en_softc *)ifp->if_softc;
1547         struct ifaddr *ifa = (struct ifaddr *)data;
1548         struct ifreq *ifr = (struct ifreq *)data;
1549         struct atmio_vcctable *vtab;
1550         int error = 0;
1551
1552         switch (cmd) {
1553
1554           case SIOCSIFADDR: 
1555                 EN_LOCK(sc);
1556                 ifp->if_flags |= IFF_UP;
1557 #if defined(INET) || defined(INET6)
1558                 if (ifa->ifa_addr->sa_family == AF_INET
1559                     || ifa->ifa_addr->sa_family == AF_INET6) {
1560                         if (!(ifp->if_flags & IFF_RUNNING)) {
1561                                 en_reset_ul(sc);
1562                                 en_init(sc);
1563                         }
1564                         ifa->ifa_rtrequest = atm_rtrequest; /* ??? */
1565                         EN_UNLOCK(sc);
1566                         break;
1567                 }
1568 #endif /* INET */
1569                 if (!(ifp->if_flags & IFF_RUNNING)) {
1570                         en_reset_ul(sc);
1571                         en_init(sc);
1572                 }
1573                 EN_UNLOCK(sc);
1574                 break;
1575
1576         case SIOCSIFFLAGS: 
1577                 EN_LOCK(sc);
1578                 if (ifp->if_flags & IFF_UP) {
1579                         if (!(ifp->if_flags & IFF_RUNNING))
1580                                 en_init(sc);
1581                 } else {
1582                         if (ifp->if_flags & IFF_RUNNING)
1583                                 en_reset_ul(sc);
1584                 }
1585                 EN_UNLOCK(sc);
1586                 break;
1587
1588           case SIOCSIFMTU:
1589                 /*
1590                  * Set the interface MTU.
1591                  */
1592                 if (ifr->ifr_mtu > ATMMTU) {
1593                         error = EINVAL;
1594                         break;
1595                 }
1596                 ifp->if_mtu = ifr->ifr_mtu;
1597                 break;
1598
1599           case SIOCSIFMEDIA:
1600           case SIOCGIFMEDIA:
1601                 error = ifmedia_ioctl(ifp, ifr, &sc->media, cmd);
1602                 break;
1603
1604           case SIOCATMOPENVCC:          /* kernel internal use */
1605                 error = en_open_vcc(sc, (struct atmio_openvcc *)data);
1606                 break;
1607
1608           case SIOCATMCLOSEVCC:         /* kernel internal use */
1609                 error = en_close_vcc(sc, (struct atmio_closevcc *)data);
1610                 break;
1611
1612           case SIOCATMGETVCCS:  /* internal netgraph use */
1613                 vtab = atm_getvccs((struct atmio_vcc **)sc->vccs,
1614                     MID_N_VC, sc->vccs_open, &sc->en_mtx, 0);
1615                 if (vtab == NULL) {
1616                         error = ENOMEM;
1617                         break;
1618                 }
1619                 *(void **)data = vtab;
1620                 break;
1621
1622           case SIOCATMGVCCS:    /* return vcc table */
1623                 vtab = atm_getvccs((struct atmio_vcc **)sc->vccs,
1624                     MID_N_VC, sc->vccs_open, &sc->en_mtx, 1);
1625                 error = copyout(vtab, ifr->ifr_data, sizeof(*vtab) +
1626                     vtab->count * sizeof(vtab->vccs[0]));
1627                 free(vtab, M_DEVBUF);
1628                 break;
1629
1630           default: 
1631                 error = EINVAL;
1632                 break;
1633         }
1634         return (error);
1635 }
1636
1637 /*********************************************************************/
1638 /*
1639  * Sysctl's
1640  */
1641
1642 /*
1643  * Sysctl handler for internal statistics
1644  *
1645  * LOCK: unlocked, needed
1646  */
1647 static int
1648 en_sysctl_istats(SYSCTL_HANDLER_ARGS)
1649 {
1650         struct en_softc *sc = arg1;
1651         uint32_t *ret;
1652         int error;
1653
1654         ret = malloc(sizeof(sc->stats), M_TEMP, M_WAITOK);
1655
1656         EN_LOCK(sc);
1657         bcopy(&sc->stats, ret, sizeof(sc->stats));
1658         EN_UNLOCK(sc);
1659
1660         error = SYSCTL_OUT(req, ret, sizeof(sc->stats));
1661         free(ret, M_TEMP);
1662
1663         return (error);
1664 }
1665
1666 /*********************************************************************/
1667 /*
1668  * Interrupts
1669  */
1670
1671 /*
1672  * Transmit interrupt handler
1673  *
1674  * check for tx complete, if detected then this means that some space
1675  * has come free on the card.   we must account for it and arrange to
1676  * kick the channel to life (in case it is stalled waiting on the card).
1677  *
1678  * LOCK: locked, needed
1679  */
1680 static uint32_t
1681 en_intr_tx(struct en_softc *sc, uint32_t reg)
1682 {
1683         uint32_t kick;
1684         uint32_t mask;
1685         uint32_t val;
1686         int chan;
1687
1688         kick = 0;               /* bitmask of channels to kick */
1689
1690         for (mask = 1, chan = 0; chan < EN_NTX; chan++, mask *= 2) {
1691                 if (!(reg & MID_TXCHAN(chan)))
1692                         continue;
1693
1694                 kick = kick | mask;
1695
1696                 /* current read pointer */
1697                 val = en_read(sc, MIDX_READPTR(chan));
1698                 /* as offset */
1699                 val = (val * sizeof(uint32_t)) + sc->txslot[chan].start;
1700                 if (val > sc->txslot[chan].cur)
1701                         sc->txslot[chan].bfree = val - sc->txslot[chan].cur;
1702                 else
1703                         sc->txslot[chan].bfree = (val + (EN_TXSZ * 1024)) -
1704                             sc->txslot[chan].cur;
1705                 DBG(sc, INTR, ("tx%d: transmit done. %d bytes now free in "
1706                     "buffer", chan, sc->txslot[chan].bfree));
1707         }
1708         return (kick);
1709 }
1710
1711 /*
1712  * TX DMA interrupt
1713  *
1714  * check for TX DMA complete, if detected then this means
1715  * that some DTQs are now free.   it also means some indma
1716  * mbufs can be freed. if we needed DTQs, kick all channels.
1717  *
1718  * LOCK: locked, needed
1719  */
1720 static uint32_t
1721 en_intr_tx_dma(struct en_softc *sc)
1722 {
1723         uint32_t kick = 0;
1724         uint32_t val;
1725         uint32_t idx;
1726         uint32_t slot;
1727         uint32_t dtq;
1728         struct en_map *map;
1729         struct mbuf *m;
1730
1731         val = en_read(sc, MID_DMA_RDTX);        /* chip's current location */
1732         idx = MID_DTQ_A2REG(sc->dtq_chip);      /* where we last saw chip */
1733
1734         if (sc->need_dtqs) {
1735                 kick = MID_NTX_CH - 1;  /* assume power of 2, kick all! */
1736                 sc->need_dtqs = 0;      /* recalculated in "kick" loop below */
1737                 DBG(sc, INTR, ("cleared need DTQ condition"));
1738         }
1739
1740         while (idx != val) {
1741                 sc->dtq_free++;
1742                 if ((dtq = sc->dtq[idx]) != 0) {
1743                         /* don't forget to zero it out when done */
1744                         sc->dtq[idx] = 0;
1745                         slot = EN_DQ_SLOT(dtq);
1746
1747                         _IF_DEQUEUE(&sc->txslot[slot].indma, m);
1748                         if (m == NULL)
1749                                 panic("enintr: dtqsync");
1750                         map = (void *)m->m_pkthdr.rcvif;
1751                         uma_zfree(sc->map_zone, map);
1752                         m_freem(m);
1753
1754                         sc->txslot[slot].mbsize -= EN_DQ_LEN(dtq);
1755                         DBG(sc, INTR, ("tx%d: free %d dma bytes, mbsize now "
1756                             "%d", slot, EN_DQ_LEN(dtq), 
1757                             sc->txslot[slot].mbsize));
1758                 }
1759                 EN_WRAPADD(0, MID_DTQ_N, idx, 1);
1760         }
1761         sc->dtq_chip = MID_DTQ_REG2A(val);      /* sync softc */
1762
1763         return (kick);
1764 }
1765
1766 /*
1767  * Service interrupt
1768  *
1769  * LOCK: locked, needed
1770  */
1771 static int
1772 en_intr_service(struct en_softc *sc)
1773 {
1774         uint32_t chip;
1775         uint32_t vci;
1776         int need_softserv = 0;
1777         struct en_vcc *vc;
1778
1779         chip = MID_SL_REG2A(en_read(sc, MID_SERV_WRITE));
1780
1781         while (sc->hwslistp != chip) {
1782                 /* fetch and remove it from hardware service list */
1783                 vci = en_read(sc, sc->hwslistp);
1784                 EN_WRAPADD(MID_SLOFF, MID_SLEND, sc->hwslistp, 4);
1785
1786                 if ((vc = sc->vccs[vci]) == NULL ||
1787                     (vc->vcc.flags & ATMIO_FLAG_NORX)) {
1788                         DBG(sc, INTR, ("unexpected rx interrupt VCI %d", vci));
1789                         en_write(sc, MID_VC(vci), MIDV_TRASH);  /* rx off */
1790                         continue;
1791                 }
1792
1793                 /* remove from hwsl */
1794                 en_write(sc, MID_VC(vci), vc->rxslot->mode);
1795                 EN_COUNT(sc->stats.hwpull);
1796
1797                 DBG(sc, INTR, ("pulled VCI %d off hwslist", vci));
1798
1799                 /* add it to the software service list (if needed) */
1800                 if ((vc->vflags & VCC_SWSL) == 0) {
1801                         EN_COUNT(sc->stats.swadd);
1802                         need_softserv = 1;
1803                         vc->vflags |= VCC_SWSL;
1804                         sc->swslist[sc->swsl_tail] = vci;
1805                         EN_WRAPADD(0, MID_SL_N, sc->swsl_tail, 1);
1806                         sc->swsl_size++;
1807                         DBG(sc, INTR, ("added VCI %d to swslist", vci));
1808                 }
1809         }
1810         return (need_softserv);
1811 }
1812
1813 /*
1814  * Handle a receive DMA completion
1815  */
1816 static void
1817 en_rx_drain(struct en_softc *sc, u_int drq)
1818 {
1819         struct en_rxslot *slot;
1820         struct en_vcc *vc;
1821         struct mbuf *m;
1822         struct atm_pseudohdr ah;
1823
1824         slot = &sc->rxslot[EN_DQ_SLOT(drq)];
1825
1826         m = NULL;       /* assume "JK" trash DMA */
1827         if (EN_DQ_LEN(drq) != 0) {
1828                 _IF_DEQUEUE(&slot->indma, m);
1829                 KASSERT(m != NULL, ("drqsync: %s: lost mbuf in slot %zu!",
1830                     sc->ifatm.ifnet.if_xname, slot - sc->rxslot));
1831                 uma_zfree(sc->map_zone, (struct en_map *)m->m_pkthdr.rcvif);
1832         }
1833         if ((vc = slot->vcc) == NULL) {
1834                 /* ups */
1835                 if (m != NULL)
1836                         m_freem(m);
1837                 return;
1838         }
1839
1840         /* do something with this mbuf */
1841         if (vc->vflags & VCC_DRAIN) {
1842                 /* drain? */
1843                 if (m != NULL)
1844                         m_freem(m);
1845                 if (_IF_QLEN(&slot->indma) == 0 && _IF_QLEN(&slot->q) == 0 &&
1846                     (en_read(sc, MID_VC(vc->vcc.vci)) & MIDV_INSERVICE) == 0 &&
1847                     (vc->vflags & VCC_SWSL) == 0) {
1848                         vc->vflags &= ~VCC_CLOSE_RX;
1849                         if (vc->vcc.flags & ATMIO_FLAG_ASYNC)
1850                                 en_close_finish(sc, vc);
1851                         else
1852                                 cv_signal(&sc->cv_close);
1853                 }
1854                 return;
1855         }
1856
1857         if (m != NULL) {
1858                 ATM_PH_FLAGS(&ah) = vc->vcc.flags;
1859                 ATM_PH_VPI(&ah) = 0;
1860                 ATM_PH_SETVCI(&ah, vc->vcc.vci);
1861
1862                 DBG(sc, INTR, ("rx%zu: rxvci%d: atm_input, mbuf %p, len %d, "
1863                     "hand %p", slot - sc->rxslot, vc->vcc.vci, m,
1864                     EN_DQ_LEN(drq), vc->rxhand));
1865
1866                 m->m_pkthdr.rcvif = &sc->ifatm.ifnet;
1867                 sc->ifatm.ifnet.if_ipackets++;
1868
1869                 vc->ipackets++;
1870                 vc->ibytes += m->m_pkthdr.len;
1871
1872 #ifdef EN_DEBUG
1873                 if (sc->debug & DBG_IPACKETS)
1874                         en_dump_packet(sc, m);
1875 #endif
1876 #ifdef ENABLE_BPF
1877                 BPF_MTAP(&sc->ifatm.ifnet, m);
1878 #endif
1879                 atm_input(&sc->ifatm.ifnet, &ah, m, vc->rxhand);
1880         }
1881 }
1882
1883 /*
1884  * check for RX DMA complete, and pass the data "upstairs"
1885  *
1886  * LOCK: locked, needed
1887  */
1888 static int
1889 en_intr_rx_dma(struct en_softc *sc)
1890 {
1891         uint32_t val;
1892         uint32_t idx;
1893         uint32_t drq;
1894
1895         val = en_read(sc, MID_DMA_RDRX);        /* chip's current location */
1896         idx = MID_DRQ_A2REG(sc->drq_chip);      /* where we last saw chip */
1897
1898         while (idx != val) {
1899                 sc->drq_free++;
1900                 if ((drq = sc->drq[idx]) != 0) {
1901                         /* don't forget to zero it out when done */
1902                         sc->drq[idx] = 0;
1903                         en_rx_drain(sc, drq);
1904                 }
1905                 EN_WRAPADD(0, MID_DRQ_N, idx, 1);
1906         }
1907         sc->drq_chip = MID_DRQ_REG2A(val);      /* sync softc */
1908
1909         if (sc->need_drqs) {
1910                 /* true if we had a DRQ shortage */
1911                 sc->need_drqs = 0;
1912                 DBG(sc, INTR, ("cleared need DRQ condition"));
1913                 return (1);
1914         } else
1915                 return (0);
1916 }
1917
1918 /*
1919  * en_mget: get an mbuf chain that can hold totlen bytes and return it
1920  * (for recv). For the actual allocation totlen is rounded up to a multiple
1921  * of 4. We also ensure, that each mbuf has a multiple of 4 bytes.
1922  *
1923  * After this call the sum of all the m_len's in the chain will be totlen.
1924  * This is called at interrupt time, so we can't wait here.
1925  *
1926  * LOCK: any, not needed
1927  */
1928 static struct mbuf *
1929 en_mget(struct en_softc *sc, u_int pktlen)
1930 {
1931         struct mbuf *m, *tmp;
1932         u_int totlen, pad;
1933
1934         totlen = roundup(pktlen, sizeof(uint32_t));
1935         pad = totlen - pktlen;
1936
1937         /*
1938          * First get an mbuf with header. Keep space for a couple of
1939          * words at the begin.
1940          */
1941         /* called from interrupt context */
1942         MGETHDR(m, M_DONTWAIT, MT_DATA);
1943         if (m == NULL)
1944                 return (NULL);
1945
1946         m->m_pkthdr.rcvif = NULL;
1947         m->m_pkthdr.len = pktlen;
1948         m->m_len = EN_RX1BUF;
1949         MH_ALIGN(m, EN_RX1BUF);
1950         if (m->m_len >= totlen) {
1951                 m->m_len = totlen;
1952
1953         } else {
1954                 totlen -= m->m_len;
1955
1956                 /* called from interrupt context */
1957                 tmp = m_getm(m, totlen, M_DONTWAIT, MT_DATA);
1958                 if (tmp == NULL) {
1959                         m_free(m);
1960                         return (NULL);
1961                 }
1962                 tmp = m->m_next;
1963                 /* m_getm could do this for us */
1964                 while (tmp != NULL) {
1965                         tmp->m_len = min(MCLBYTES, totlen);
1966                         totlen -= tmp->m_len;
1967                         tmp = tmp->m_next;
1968                 }
1969         }
1970
1971         return (m);
1972 }
1973
1974 /*
1975  * Argument for RX DMAMAP loader.
1976  */
1977 struct rxarg {
1978         struct en_softc *sc;
1979         struct mbuf *m;
1980         u_int pre_skip;         /* number of bytes to skip at begin */
1981         u_int post_skip;        /* number of bytes to skip at end */
1982         struct en_vcc *vc;      /* vc we are receiving on */
1983         int wait;               /* wait for DRQ entries */
1984 };
1985
1986 /*
1987  * Copy the segment table to the buffer for later use. And compute the
1988  * number of dma queue entries we need.
1989  *
1990  * LOCK: locked, needed
1991  */
1992 static void
1993 en_rxdma_load(void *uarg, bus_dma_segment_t *segs, int nseg,
1994     bus_size_t mapsize, int error)
1995 {
1996         struct rxarg *rx = uarg;
1997         struct en_softc *sc = rx->sc;
1998         struct en_rxslot *slot = rx->vc->rxslot;
1999         u_int           free;           /* number of free DRQ entries */
2000         uint32_t        cur;            /* current buffer offset */
2001         uint32_t        drq;            /* DRQ entry pointer */
2002         uint32_t        last_drq;       /* where we have written last */
2003         u_int           needalign, cnt, count, bcode;
2004         bus_addr_t      addr;
2005         bus_size_t      rest;
2006         int             i;
2007
2008         if (error != 0)
2009                 return;
2010         if (nseg > EN_MAX_DMASEG)
2011                 panic("too many DMA segments");
2012
2013         rx->wait = 0;
2014
2015         free = sc->drq_free;
2016         drq = sc->drq_us;
2017         cur = slot->cur;
2018
2019         last_drq = 0;
2020
2021         /*
2022          * Local macro to add an entry to the receive DMA area. If there
2023          * are no entries left, return. Save the byte offset of the entry
2024          * in last_drq for later use.
2025          */
2026 #define PUT_DRQ_ENTRY(ENI, BCODE, COUNT, ADDR)                          \
2027         if (free == 0) {                                                \
2028                 EN_COUNT(sc->stats.rxdrqout);                           \
2029                 rx->wait = 1;                                           \
2030                 return;                                                 \
2031         }                                                               \
2032         last_drq = drq;                                                 \
2033         en_write(sc, drq + 0, (ENI || !sc->is_adaptec) ?                \
2034             MID_MK_RXQ_ENI(COUNT, rx->vc->vcc.vci, 0, BCODE) :          \
2035             MID_MK_RXQ_ADP(COUNT, rx->vc->vcc.vci, 0, BCODE));          \
2036         en_write(sc, drq + 4, ADDR);                                    \
2037                                                                         \
2038         EN_WRAPADD(MID_DRQOFF, MID_DRQEND, drq, 8);                     \
2039         free--;
2040
2041         /*
2042          * Local macro to generate a DMA entry to DMA cnt bytes. Updates
2043          * the current buffer byte offset accordingly.
2044          */
2045 #define DO_DRQ(TYPE) do {                                               \
2046         rest -= cnt;                                                    \
2047         EN_WRAPADD(slot->start, slot->stop, cur, cnt);                  \
2048         DBG(sc, SERV, ("rx%td: "TYPE" %u bytes, %ju left, cur %#x",     \
2049             slot - sc->rxslot, cnt, (uintmax_t)rest, cur));             \
2050                                                                         \
2051         PUT_DRQ_ENTRY(1, bcode, count, addr);                           \
2052                                                                         \
2053         addr += cnt;                                                    \
2054     } while (0)
2055
2056         /*
2057          * Skip the RBD at the beginning
2058          */
2059         if (rx->pre_skip > 0) {
2060                 /* update DMA address */
2061                 EN_WRAPADD(slot->start, slot->stop, cur, rx->pre_skip);
2062
2063                 PUT_DRQ_ENTRY(0, MIDDMA_JK, WORD_IDX(slot->start, cur), 0);
2064         }
2065
2066         for (i = 0; i < nseg; i++, segs++) {
2067                 addr = segs->ds_addr;
2068                 rest = segs->ds_len;
2069
2070                 if (sc->is_adaptec) {
2071                         /* adaptec card - simple */
2072
2073                         /* advance the on-card buffer pointer */
2074                         EN_WRAPADD(slot->start, slot->stop, cur, rest);
2075                         DBG(sc, SERV, ("rx%td: adp %ju bytes %#jx "
2076                             "(cur now 0x%x)", slot - sc->rxslot,
2077                             (uintmax_t)rest, (uintmax_t)addr, cur));
2078
2079                         PUT_DRQ_ENTRY(0, 0, rest, addr);
2080
2081                         continue;
2082                 }
2083
2084                 /*
2085                  * do we need to do a DMA op to align to the maximum
2086                  * burst? Note, that we are alway 32-bit aligned.
2087                  */
2088                 if (sc->alburst &&
2089                     (needalign = (addr & sc->bestburstmask)) != 0) {
2090                         /* compute number of bytes, words and code */
2091                         cnt = sc->bestburstlen - needalign;
2092                         if (cnt > rest)
2093                                 cnt = rest;
2094                         count = cnt / sizeof(uint32_t);
2095                         if (sc->noalbursts) {
2096                                 bcode = MIDDMA_WORD;
2097                         } else {
2098                                 bcode = en_dmaplan[count].bcode;
2099                                 count = cnt >> en_dmaplan[count].divshift;
2100                         }
2101                         DO_DRQ("al_dma");
2102                 }
2103
2104                 /* do we need to do a max-sized burst? */
2105                 if (rest >= sc->bestburstlen) {
2106                         count = rest >> sc->bestburstshift;
2107                         cnt = count << sc->bestburstshift;
2108                         bcode = sc->bestburstcode;
2109                         DO_DRQ("best_dma");
2110                 }
2111
2112                 /* do we need to do a cleanup burst? */
2113                 if (rest != 0) {
2114                         cnt = rest;
2115                         count = rest / sizeof(uint32_t);
2116                         if (sc->noalbursts) {
2117                                 bcode = MIDDMA_WORD;
2118                         } else {
2119                                 bcode = en_dmaplan[count].bcode;
2120                                 count = cnt >> en_dmaplan[count].divshift;
2121                         }
2122                         DO_DRQ("clean_dma");
2123                 }
2124         }
2125
2126         /*
2127          * Skip stuff at the end
2128          */
2129         if (rx->post_skip > 0) {
2130                 /* update DMA address */
2131                 EN_WRAPADD(slot->start, slot->stop, cur, rx->post_skip);
2132
2133                 PUT_DRQ_ENTRY(0, MIDDMA_JK, WORD_IDX(slot->start, cur), 0);
2134         }
2135
2136         /* record the end for the interrupt routine */
2137         sc->drq[MID_DRQ_A2REG(last_drq)] =
2138             EN_DQ_MK(slot - sc->rxslot, rx->m->m_pkthdr.len);
2139
2140         /* set the end flag in the last descriptor */
2141         en_write(sc, last_drq + 0, SETQ_END(sc, en_read(sc, last_drq + 0)));
2142
2143 #undef PUT_DRQ_ENTRY
2144 #undef DO_DRQ
2145
2146         /* commit */
2147         slot->cur = cur;
2148         sc->drq_free = free;
2149         sc->drq_us = drq;
2150
2151         /* signal to card */
2152         en_write(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_us));
2153 }
2154
2155 /*
2156  * en_service: handle a service interrupt
2157  *
2158  * Q: why do we need a software service list?
2159  *
2160  * A: if we remove a VCI from the hardware list and we find that we are
2161  *    out of DRQs we must defer processing until some DRQs become free.
2162  *    so we must remember to look at this RX VCI/slot later, but we can't
2163  *    put it back on the hardware service list (since that isn't allowed).
2164  *    so we instead save it on the software service list.   it would be nice 
2165  *    if we could peek at the VCI on top of the hwservice list without removing
2166  *    it, however this leads to a race condition: if we peek at it and
2167  *    decide we are done with it new data could come in before we have a 
2168  *    chance to remove it from the hwslist.   by the time we get it out of
2169  *    the list the interrupt for the new data will be lost.   oops!
2170  *
2171  * LOCK: locked, needed
2172  */
2173 static void
2174 en_service(struct en_softc *sc)
2175 {
2176         struct mbuf     *m, *lastm;
2177         struct en_map   *map;
2178         struct rxarg    rx;
2179         uint32_t        cur;
2180         uint32_t        dstart;         /* data start (as reported by card) */
2181         uint32_t        rbd;            /* receive buffer descriptor */
2182         uint32_t        pdu;            /* AAL5 trailer */
2183         int             mlen;
2184         int             error;
2185         struct en_rxslot *slot;
2186         struct en_vcc *vc;
2187
2188         rx.sc = sc;
2189
2190   next_vci:
2191         if (sc->swsl_size == 0) {
2192                 DBG(sc, SERV, ("en_service done"));
2193                 return;
2194         }
2195
2196         /*
2197          * get vcc to service
2198          */
2199         rx.vc = vc = sc->vccs[sc->swslist[sc->swsl_head]];
2200         slot = vc->rxslot;
2201         KASSERT (slot->vcc->rxslot == slot, ("en_service: rx slot/vci sync"));
2202
2203         /*
2204          * determine our mode and if we've got any work to do
2205          */
2206         DBG(sc, SERV, ("rx%td: service vci=%d start/stop/cur=0x%x 0x%x "
2207             "0x%x", slot - sc->rxslot, vc->vcc.vci, slot->start,
2208             slot->stop, slot->cur));
2209
2210   same_vci:
2211         cur = slot->cur;
2212
2213         dstart = MIDV_DSTART(en_read(sc, MID_DST_RP(vc->vcc.vci)));
2214         dstart = (dstart * sizeof(uint32_t)) + slot->start;
2215
2216         /* check to see if there is any data at all */
2217         if (dstart == cur) {
2218                 EN_WRAPADD(0, MID_SL_N, sc->swsl_head, 1); 
2219                 /* remove from swslist */
2220                 vc->vflags &= ~VCC_SWSL;
2221                 sc->swsl_size--;
2222                 DBG(sc, SERV, ("rx%td: remove vci %d from swslist",
2223                     slot - sc->rxslot, vc->vcc.vci));
2224                 goto next_vci;
2225         }
2226
2227         /*
2228          * figure out how many bytes we need
2229          * [mlen = # bytes to go in mbufs]
2230          */
2231         rbd = en_read(sc, cur);
2232         if (MID_RBD_ID(rbd) != MID_RBD_STDID) 
2233                 panic("en_service: id mismatch");
2234
2235         if (rbd & MID_RBD_T) {
2236                 mlen = 0;               /* we've got trash */
2237                 rx.pre_skip = MID_RBD_SIZE;
2238                 rx.post_skip = 0;
2239                 EN_COUNT(sc->stats.ttrash);
2240                 DBG(sc, SERV, ("RX overflow lost %d cells!", MID_RBD_CNT(rbd)));
2241
2242         } else if (vc->vcc.aal != ATMIO_AAL_5) {
2243                 /* 1 cell (ick!) */
2244                 mlen = MID_CHDR_SIZE + MID_ATMDATASZ;
2245                 rx.pre_skip = MID_RBD_SIZE;
2246                 rx.post_skip = 0;
2247
2248         } else {
2249                 rx.pre_skip = MID_RBD_SIZE;
2250
2251                 /* get PDU trailer in correct byte order */
2252                 pdu = cur + MID_RBD_CNT(rbd) * MID_ATMDATASZ +
2253                     MID_RBD_SIZE - MID_PDU_SIZE;
2254                 if (pdu >= slot->stop)
2255                         pdu -= EN_RXSZ * 1024;
2256                 pdu = en_read(sc, pdu);
2257
2258                 if (MID_RBD_CNT(rbd) * MID_ATMDATASZ <
2259                     MID_PDU_LEN(pdu)) {
2260                         if_printf(&sc->ifatm.ifnet, "invalid AAL5 length\n");
2261                         rx.post_skip = MID_RBD_CNT(rbd) * MID_ATMDATASZ;
2262                         mlen = 0;
2263                         sc->ifatm.ifnet.if_ierrors++;
2264
2265                 } else if (rbd & MID_RBD_CRCERR) {
2266                         if_printf(&sc->ifatm.ifnet, "CRC error\n");
2267                         rx.post_skip = MID_RBD_CNT(rbd) * MID_ATMDATASZ;
2268                         mlen = 0;
2269                         sc->ifatm.ifnet.if_ierrors++;
2270
2271                 } else {
2272                         mlen = MID_PDU_LEN(pdu);
2273                         rx.post_skip = MID_RBD_CNT(rbd) * MID_ATMDATASZ - mlen;
2274                 }
2275         }
2276
2277         /*
2278          * now allocate mbufs for mlen bytes of data, if out of mbufs, trash all
2279          *
2280          * notes:
2281          *  1. it is possible that we've already allocated an mbuf for this pkt
2282          *     but ran out of DRQs, in which case we saved the allocated mbuf
2283          *     on "q".
2284          *  2. if we save an buf in "q" we store the "cur" (pointer) in the
2285          *     buf as an identity (that we can check later).
2286          *  3. after this block of code, if m is still NULL then we ran out of
2287          *     mbufs
2288          */
2289         _IF_DEQUEUE(&slot->q, m);
2290         if (m != NULL) {
2291                 if (m->m_pkthdr.csum_data != cur) {
2292                         /* wasn't ours */
2293                         DBG(sc, SERV, ("rx%td: q'ed buf %p not ours",
2294                             slot - sc->rxslot, m));
2295                         _IF_PREPEND(&slot->q, m);
2296                         m = NULL;
2297                         EN_COUNT(sc->stats.rxqnotus);
2298                 } else {
2299                         EN_COUNT(sc->stats.rxqus);
2300                         DBG(sc, SERV, ("rx%td: recovered q'ed buf %p",
2301                             slot - sc->rxslot, m));
2302                 }
2303         }
2304         if (mlen == 0 && m != NULL) {
2305                 /* should not happen */
2306                 m_freem(m);
2307                 m = NULL;
2308         }
2309
2310         if (mlen != 0 && m == NULL) {
2311                 m = en_mget(sc, mlen);
2312                 if (m == NULL) {
2313                         rx.post_skip += mlen;
2314                         mlen = 0;
2315                         EN_COUNT(sc->stats.rxmbufout);
2316                         DBG(sc, SERV, ("rx%td: out of mbufs",
2317                             slot - sc->rxslot));
2318                 } else
2319                         rx.post_skip -= roundup(mlen, sizeof(uint32_t)) - mlen;
2320
2321                 DBG(sc, SERV, ("rx%td: allocate buf %p, mlen=%d",
2322                     slot - sc->rxslot, m, mlen));
2323         }
2324
2325         DBG(sc, SERV, ("rx%td: VCI %d, rbuf %p, mlen %d, skip %u/%u",
2326             slot - sc->rxslot, vc->vcc.vci, m, mlen, rx.pre_skip,
2327             rx.post_skip));
2328
2329         if (m != NULL) {
2330                 /* M_NOWAIT - called from interrupt context */
2331                 map = uma_zalloc_arg(sc->map_zone, sc, M_NOWAIT);
2332                 if (map == NULL || !(map->flags & ENMAP_ALLOC)) {
2333                         rx.post_skip += mlen;
2334                         m_freem(m);
2335                         DBG(sc, SERV, ("rx%td: out of maps",
2336                             slot - sc->rxslot));
2337                         if (map->map != NULL)
2338                                 uma_zfree(sc->map_zone, map);
2339                         goto skip;
2340                 }
2341                 rx.m = m;
2342                 error = bus_dmamap_load_mbuf(sc->txtag, map->map, m,
2343                     en_rxdma_load, &rx, BUS_DMA_NOWAIT);
2344
2345                 if (error != 0) {
2346                         if_printf(&sc->ifatm.ifnet, "loading RX map failed "
2347                             "%d\n", error);
2348                         uma_zfree(sc->map_zone, map);
2349                         m_freem(m);
2350                         rx.post_skip += mlen;
2351                         goto skip;
2352
2353                 }
2354                 map->flags |= ENMAP_LOADED;
2355
2356                 if (rx.wait) {
2357                         /* out of DRQs - wait */
2358                         uma_zfree(sc->map_zone, map);
2359
2360                         m->m_pkthdr.csum_data = cur;
2361                         _IF_ENQUEUE(&slot->q, m);
2362                         EN_COUNT(sc->stats.rxdrqout);
2363
2364                         sc->need_drqs = 1;      /* flag condition */
2365                         return;
2366
2367                 }
2368                 (void)m_length(m, &lastm);
2369                 lastm->m_len -= roundup(mlen, sizeof(uint32_t)) - mlen;
2370
2371                 m->m_pkthdr.rcvif = (void *)map;
2372                 _IF_ENQUEUE(&slot->indma, m);
2373
2374                 /* get next packet in this slot */
2375                 goto same_vci;
2376         }
2377   skip:
2378         /*
2379          * Here we end if we should drop the packet from the receive buffer.
2380          * The number of bytes to drop is in fill. We can do this with on
2381          * JK entry. If we don't even have that one - wait.
2382          */
2383         if (sc->drq_free == 0) {
2384                 sc->need_drqs = 1;      /* flag condition */
2385                 return;
2386         }
2387         rx.post_skip += rx.pre_skip;
2388         DBG(sc, SERV, ("rx%td: skipping %u", slot - sc->rxslot, rx.post_skip));
2389
2390         /* advance buffer address */
2391         EN_WRAPADD(slot->start, slot->stop, cur, rx.post_skip);
2392
2393         /* write DRQ entry */
2394         if (sc->is_adaptec)
2395                 en_write(sc, sc->drq_us,
2396                     MID_MK_RXQ_ADP(WORD_IDX(slot->start, cur),
2397                     vc->vcc.vci, MID_DMA_END, MIDDMA_JK));
2398         else
2399                 en_write(sc, sc->drq_us,
2400                     MID_MK_RXQ_ENI(WORD_IDX(slot->start, cur),
2401                     vc->vcc.vci, MID_DMA_END, MIDDMA_JK));
2402         en_write(sc, sc->drq_us + 4, 0);
2403         EN_WRAPADD(MID_DRQOFF, MID_DRQEND, sc->drq_us, 8);
2404         sc->drq_free--;
2405
2406         /* signal to RX interrupt */
2407         sc->drq[MID_DRQ_A2REG(sc->drq_us)] = EN_DQ_MK(slot - sc->rxslot, 0);
2408         slot->cur = cur;
2409
2410         /* signal to card */
2411         en_write(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_us));
2412
2413         goto same_vci;
2414 }
2415
2416 /*
2417  * interrupt handler
2418  *
2419  * LOCK: unlocked, needed
2420  */
2421 void
2422 en_intr(void *arg)
2423 {
2424         struct en_softc *sc = arg;
2425         uint32_t reg, kick, mask;
2426         int lcv, need_softserv;
2427
2428         EN_LOCK(sc);
2429
2430         reg = en_read(sc, MID_INTACK);
2431         DBG(sc, INTR, ("interrupt=0x%b", reg, MID_INTBITS));
2432
2433         if ((reg & MID_INT_ANY) == 0) {
2434                 EN_UNLOCK(sc);
2435                 return;
2436         }
2437
2438         /*
2439          * unexpected errors that need a reset
2440          */
2441         if ((reg & (MID_INT_IDENT | MID_INT_LERR | MID_INT_DMA_ERR)) != 0) {
2442                 if_printf(&sc->ifatm.ifnet, "unexpected interrupt=0x%b, "
2443                     "resetting\n", reg, MID_INTBITS);
2444 #ifdef EN_DEBUG
2445 #ifdef DDB
2446                 Debugger("en: unexpected error");
2447 #endif  /* DDB */
2448                 sc->ifatm.ifnet.if_flags &= ~IFF_RUNNING; /* FREEZE! */
2449 #else
2450                 en_reset_ul(sc);
2451                 en_init(sc);
2452 #endif
2453                 EN_UNLOCK(sc);
2454                 return;
2455         }
2456
2457         if (reg & MID_INT_SUNI)
2458                 utopia_intr(&sc->utopia);
2459
2460         kick = 0;
2461         if (reg & MID_INT_TX)
2462                 kick |= en_intr_tx(sc, reg);
2463
2464         if (reg & MID_INT_DMA_TX)
2465                 kick |= en_intr_tx_dma(sc);
2466
2467         /*
2468          * kick xmit channels as needed.
2469          */
2470         if (kick) {
2471                 DBG(sc, INTR, ("tx kick mask = 0x%x", kick));
2472                 for (mask = 1, lcv = 0 ; lcv < EN_NTX ; lcv++, mask = mask * 2)
2473                         if ((kick & mask) && _IF_QLEN(&sc->txslot[lcv].q) != 0)
2474                                 en_txdma(sc, &sc->txslot[lcv]);
2475         }
2476
2477         need_softserv = 0;
2478         if (reg & MID_INT_DMA_RX)
2479                 need_softserv |= en_intr_rx_dma(sc);
2480
2481         if (reg & MID_INT_SERVICE)
2482                 need_softserv |= en_intr_service(sc);
2483
2484         if (need_softserv)
2485                 en_service(sc);
2486
2487         /*
2488          * keep our stats
2489          */
2490         if (reg & MID_INT_DMA_OVR) {
2491                 EN_COUNT(sc->stats.dmaovr);
2492                 DBG(sc, INTR, ("MID_INT_DMA_OVR"));
2493         }
2494         reg = en_read(sc, MID_STAT);
2495         sc->stats.otrash += MID_OTRASH(reg);
2496         sc->stats.vtrash += MID_VTRASH(reg);
2497
2498         EN_UNLOCK(sc);
2499 }
2500
2501 /*
2502  * Read at most n SUNI regs starting at reg into val
2503  */
2504 static int
2505 en_utopia_readregs(struct ifatm *ifatm, u_int reg, uint8_t *val, u_int *n)
2506 {
2507         struct en_softc *sc = ifatm->ifnet.if_softc;
2508         u_int i;
2509
2510         EN_CHECKLOCK(sc);
2511         if (reg >= MID_NSUNI)
2512                 return (EINVAL);
2513         if (reg + *n > MID_NSUNI)
2514                 *n = MID_NSUNI - reg;
2515
2516         for (i = 0; i < *n; i++)
2517                 val[i] = en_read(sc, MID_SUNIOFF + 4 * (reg + i));
2518
2519         return (0);
2520 }
2521
2522 /*
2523  * change the bits given by mask to them in val in register reg
2524  */
2525 static int
2526 en_utopia_writereg(struct ifatm *ifatm, u_int reg, u_int mask, u_int val)
2527 {
2528         struct en_softc *sc = ifatm->ifnet.if_softc;
2529         uint32_t regval;
2530
2531         EN_CHECKLOCK(sc);
2532         if (reg >= MID_NSUNI)
2533                 return (EINVAL);
2534         regval = en_read(sc, MID_SUNIOFF + 4 * reg);
2535         regval = (regval & ~mask) | (val & mask);
2536         en_write(sc, MID_SUNIOFF + 4 * reg, regval);
2537         return (0);
2538 }
2539
2540 static const struct utopia_methods en_utopia_methods = {
2541         en_utopia_readregs,
2542         en_utopia_writereg
2543 };
2544
2545 /*********************************************************************/
2546 /*
2547  * Probing the DMA brokeness of the card
2548  */
2549
2550 /*
2551  * Physical address load helper function for DMA probe
2552  *
2553  * LOCK: unlocked, not needed
2554  */
2555 static void
2556 en_dmaprobe_load(void *uarg, bus_dma_segment_t *segs, int nseg, int error)
2557 {
2558         if (error == 0)
2559                 *(bus_addr_t *)uarg = segs[0].ds_addr;
2560 }
2561
2562 /*
2563  * en_dmaprobe: helper function for en_attach.
2564  *
2565  * see how the card handles DMA by running a few DMA tests.   we need
2566  * to figure out the largest number of bytes we can DMA in one burst
2567  * ("bestburstlen"), and if the starting address for a burst needs to
2568  * be aligned on any sort of boundary or not ("alburst").
2569  *
2570  * Things turn out more complex than that, because on my (harti) brand
2571  * new motherboard (2.4GHz) we can do 64byte aligned DMAs, but everything
2572  * we more than 4 bytes fails (with an RX DMA timeout) for physical
2573  * addresses that end with 0xc. Therefor we search not only the largest
2574  * burst that is supported (hopefully 64) but also check what is the largerst
2575  * unaligned supported size. If that appears to be lesser than 4 words,
2576  * set the noalbursts flag. That will be set only if also alburst is set.
2577  */
2578
2579 /*
2580  * en_dmaprobe_doit: do actual testing for the DMA test.
2581  * Cycle through all bursts sizes from 8 up to 64 and try whether it works.
2582  * Return the largest one that works.
2583  *
2584  * LOCK: unlocked, not needed
2585  */
2586 static int
2587 en_dmaprobe_doit(struct en_softc *sc, uint8_t *sp, bus_addr_t psp)
2588 {
2589         uint8_t *dp = sp + MIDDMA_MAXBURST;
2590         bus_addr_t pdp = psp + MIDDMA_MAXBURST;
2591         int lcv, retval = 4, cnt;
2592         uint32_t reg, bcode, midvloc;
2593
2594         if (sc->en_busreset)
2595                 sc->en_busreset(sc);
2596         en_write(sc, MID_RESID, 0x0);   /* reset card before touching RAM */
2597
2598         /*
2599          * set up a 1k buffer at MID_BUFOFF
2600          */
2601         midvloc = ((MID_BUFOFF - MID_RAMOFF) / sizeof(uint32_t))
2602             >> MIDV_LOCTOPSHFT;
2603         en_write(sc, MIDX_PLACE(0), MIDX_MKPLACE(en_k2sz(1), midvloc));
2604         en_write(sc, MID_VC(0), (midvloc << MIDV_LOCSHIFT) 
2605             | (en_k2sz(1) << MIDV_SZSHIFT) | MIDV_TRASH);
2606         en_write(sc, MID_DST_RP(0), 0);
2607         en_write(sc, MID_WP_ST_CNT(0), 0);
2608
2609         /* set up sample data */
2610         for (lcv = 0 ; lcv < MIDDMA_MAXBURST; lcv++)
2611                 sp[lcv] = lcv + 1;
2612
2613         /* enable DMA (only) */
2614         en_write(sc, MID_MAST_CSR, MID_MCSR_ENDMA);
2615
2616         sc->drq_chip = MID_DRQ_REG2A(en_read(sc, MID_DMA_RDRX));
2617         sc->dtq_chip = MID_DTQ_REG2A(en_read(sc, MID_DMA_RDTX));
2618
2619         /*
2620          * try it now . . .  DMA it out, then DMA it back in and compare
2621          *
2622          * note: in order to get the dma stuff to reverse directions it wants
2623          * the "end" flag set!   since we are not dma'ing valid data we may
2624          * get an ident mismatch interrupt (which we will ignore).
2625          */
2626         DBG(sc, DMA, ("test sp=%p/%#lx, dp=%p/%#lx", 
2627             sp, (u_long)psp, dp, (u_long)pdp));
2628         for (lcv = 8 ; lcv <= MIDDMA_MAXBURST ; lcv = lcv * 2) {
2629                 DBG(sc, DMA, ("test lcv=%d", lcv));
2630
2631                 /* zero SRAM and dest buffer */
2632                 bus_space_set_region_4(sc->en_memt, sc->en_base,
2633                     MID_BUFOFF, 0, 1024 / 4);
2634                 bzero(dp, MIDDMA_MAXBURST);
2635
2636                 bcode = en_sz2b(lcv);
2637
2638                 /* build lcv-byte-DMA x NBURSTS */
2639                 if (sc->is_adaptec)
2640                         en_write(sc, sc->dtq_chip,
2641                             MID_MK_TXQ_ADP(lcv, 0, MID_DMA_END, 0));
2642                 else
2643                         en_write(sc, sc->dtq_chip,
2644                             MID_MK_TXQ_ENI(1, 0, MID_DMA_END, bcode));
2645                 en_write(sc, sc->dtq_chip + 4, psp);
2646                 EN_WRAPADD(MID_DTQOFF, MID_DTQEND, sc->dtq_chip, 8);
2647                 en_write(sc, MID_DMA_WRTX, MID_DTQ_A2REG(sc->dtq_chip));
2648
2649                 cnt = 1000;
2650                 while ((reg = en_readx(sc, MID_DMA_RDTX)) !=
2651                     MID_DTQ_A2REG(sc->dtq_chip)) {
2652                         DELAY(1);
2653                         if (--cnt == 0) {
2654                                 DBG(sc, DMA, ("unexpected timeout in tx "
2655                                     "DMA test\n  alignment=0x%lx, burst size=%d"
2656                                     ", dma addr reg=%#x, rdtx=%#x, stat=%#x\n",
2657                                     (u_long)sp & 63, lcv,
2658                                     en_read(sc, MID_DMA_ADDR), reg,
2659                                     en_read(sc, MID_INTSTAT)));
2660                                 return (retval);
2661                         }
2662                 }
2663
2664                 reg = en_read(sc, MID_INTACK); 
2665                 if ((reg & MID_INT_DMA_TX) != MID_INT_DMA_TX) {
2666                         DBG(sc, DMA, ("unexpected status in tx DMA test: %#x\n",
2667                             reg));
2668                         return (retval);
2669                 }
2670                 /* re-enable DMA (only) */
2671                 en_write(sc, MID_MAST_CSR, MID_MCSR_ENDMA);
2672
2673                 /* "return to sender..."  address is known ... */
2674
2675                 /* build lcv-byte-DMA x NBURSTS */
2676                 if (sc->is_adaptec)
2677                         en_write(sc, sc->drq_chip,
2678                             MID_MK_RXQ_ADP(lcv, 0, MID_DMA_END, 0));
2679                 else
2680                         en_write(sc, sc->drq_chip,
2681                             MID_MK_RXQ_ENI(1, 0, MID_DMA_END, bcode));
2682                 en_write(sc, sc->drq_chip + 4, pdp);
2683                 EN_WRAPADD(MID_DRQOFF, MID_DRQEND, sc->drq_chip, 8);
2684                 en_write(sc, MID_DMA_WRRX, MID_DRQ_A2REG(sc->drq_chip));
2685                 cnt = 1000;
2686                 while ((reg = en_readx(sc, MID_DMA_RDRX)) !=
2687                     MID_DRQ_A2REG(sc->drq_chip)) {
2688                         DELAY(1);
2689                         cnt--;
2690                         if (--cnt == 0) {
2691                                 DBG(sc, DMA, ("unexpected timeout in rx "
2692                                     "DMA test, rdrx=%#x\n", reg));
2693                                 return (retval);
2694                         }
2695                 }
2696                 reg = en_read(sc, MID_INTACK); 
2697                 if ((reg & MID_INT_DMA_RX) != MID_INT_DMA_RX) {
2698                         DBG(sc, DMA, ("unexpected status in rx DMA "
2699                             "test: 0x%x\n", reg));
2700                         return (retval);
2701                 }
2702                 if (bcmp(sp, dp, lcv)) {
2703                         DBG(sc, DMA, ("DMA test failed! lcv=%d, sp=%p, "
2704                             "dp=%p", lcv, sp, dp));
2705                         return (retval);
2706                 }
2707
2708                 retval = lcv;
2709         }
2710         return (retval);        /* studly 64 byte DMA present!  oh baby!! */
2711 }
2712
2713 /*
2714  * Find the best DMA parameters
2715  *
2716  * LOCK: unlocked, not needed
2717  */
2718 static void
2719 en_dmaprobe(struct en_softc *sc)
2720 {
2721         bus_dma_tag_t tag;
2722         bus_dmamap_t map;
2723         int err;
2724         void *buffer;
2725         int bestalgn, lcv, try, bestnoalgn;
2726         bus_addr_t phys;
2727         uint8_t *addr;
2728
2729         sc->alburst = 0;
2730         sc->noalbursts = 0;
2731
2732         /*
2733          * Allocate some DMA-able memory.
2734          * We need 3 times the max burst size aligned to the max burst size.
2735          */
2736         err = bus_dma_tag_create(NULL, MIDDMA_MAXBURST, 0,
2737             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
2738             3 * MIDDMA_MAXBURST, 1, 3 * MIDDMA_MAXBURST, 0,
2739             NULL, NULL, &tag);
2740         if (err)
2741                 panic("%s: cannot create test DMA tag %d", __func__, err);
2742
2743         err = bus_dmamem_alloc(tag, &buffer, 0, &map);
2744         if (err)
2745                 panic("%s: cannot allocate test DMA memory %d", __func__, err);
2746
2747         err = bus_dmamap_load(tag, map, buffer, 3 * MIDDMA_MAXBURST,
2748             en_dmaprobe_load, &phys, BUS_DMA_NOWAIT);
2749         if (err)
2750                 panic("%s: cannot load test DMA map %d", __func__, err);
2751         addr = buffer;
2752         DBG(sc, DMA, ("phys=%#lx addr=%p", (u_long)phys, addr));
2753
2754         /*
2755          * Now get the best burst size of the aligned case.
2756          */
2757         bestalgn = bestnoalgn = en_dmaprobe_doit(sc, addr, phys);
2758
2759         /*
2760          * Now try unaligned. 
2761          */
2762         for (lcv = 4; lcv < MIDDMA_MAXBURST; lcv += 4) {
2763                 try = en_dmaprobe_doit(sc, addr + lcv, phys + lcv);
2764
2765                 if (try < bestnoalgn)
2766                         bestnoalgn = try;
2767         }
2768
2769         if (bestnoalgn < bestalgn) {
2770                 sc->alburst = 1;
2771                 if (bestnoalgn < 32)
2772                         sc->noalbursts = 1;
2773         }
2774
2775         sc->bestburstlen = bestalgn;
2776         sc->bestburstshift = en_log2(bestalgn);
2777         sc->bestburstmask = sc->bestburstlen - 1; /* must be power of 2 */
2778         sc->bestburstcode = en_sz2b(bestalgn);
2779
2780         /*
2781          * Reset the chip before freeing the buffer. It may still be trying
2782          * to DMA.
2783          */
2784         if (sc->en_busreset)
2785                 sc->en_busreset(sc);
2786         en_write(sc, MID_RESID, 0x0);   /* reset card before touching RAM */
2787
2788         DELAY(10000);                   /* may still do DMA */
2789
2790         /*
2791          * Free the DMA stuff
2792          */
2793         bus_dmamap_unload(tag, map);
2794         bus_dmamem_free(tag, buffer, map);
2795         bus_dma_tag_destroy(tag);
2796 }
2797
2798 /*********************************************************************/
2799 /*
2800  * Attach/detach.
2801  */
2802
2803 /*
2804  * Attach to the card.
2805  *
2806  * LOCK: unlocked, not needed (but initialized)
2807  */
2808 int
2809 en_attach(struct en_softc *sc)
2810 {
2811         struct ifnet *ifp = &sc->ifatm.ifnet;
2812         int sz;
2813         uint32_t reg, lcv, check, ptr, sav, midvloc;
2814
2815 #ifdef EN_DEBUG
2816         sc->debug = EN_DEBUG;
2817 #endif
2818         /*
2819          * Probe card to determine memory size.
2820          *
2821          * The stupid ENI card always reports to PCI that it needs 4MB of
2822          * space (2MB regs and 2MB RAM). If it has less than 2MB RAM the
2823          * addresses wrap in the RAM address space (i.e. on a 512KB card
2824          * addresses 0x3ffffc, 0x37fffc, and 0x2ffffc are aliases for
2825          * 0x27fffc  [note that RAM starts at offset 0x200000]).
2826          */
2827
2828         /* reset card before touching RAM */
2829         if (sc->en_busreset)
2830                 sc->en_busreset(sc);
2831         en_write(sc, MID_RESID, 0x0);
2832
2833         for (lcv = MID_PROBEOFF; lcv <= MID_MAXOFF ; lcv += MID_PROBSIZE) {
2834                 en_write(sc, lcv, lcv); /* data[address] = address */
2835                 for (check = MID_PROBEOFF; check < lcv ;check += MID_PROBSIZE) {
2836                         reg = en_read(sc, check);
2837                         if (reg != check)
2838                                 /* found an alias! - quit */
2839                                 goto done_probe;
2840                 }
2841         }
2842   done_probe:
2843         lcv -= MID_PROBSIZE;                    /* take one step back */
2844         sc->en_obmemsz = (lcv + 4) - MID_RAMOFF;
2845
2846         /*
2847          * determine the largest DMA burst supported
2848          */
2849         en_dmaprobe(sc);
2850
2851         /*
2852          * "hello world"
2853          */
2854
2855         /* reset */
2856         if (sc->en_busreset)
2857                 sc->en_busreset(sc);
2858         en_write(sc, MID_RESID, 0x0);           /* reset */
2859
2860         /* zero memory */
2861         bus_space_set_region_4(sc->en_memt, sc->en_base,
2862             MID_RAMOFF, 0, sc->en_obmemsz / 4);
2863
2864         reg = en_read(sc, MID_RESID);
2865
2866         if_printf(&sc->ifatm.ifnet, "ATM midway v%d, board IDs %d.%d, %s%s%s, "
2867             "%ldKB on-board RAM\n", MID_VER(reg), MID_MID(reg), MID_DID(reg), 
2868             (MID_IS_SABRE(reg)) ? "sabre controller, " : "",
2869             (MID_IS_SUNI(reg)) ? "SUNI" : "Utopia",
2870             (!MID_IS_SUNI(reg) && MID_IS_UPIPE(reg)) ? " (pipelined)" : "",
2871             (long)sc->en_obmemsz / 1024);
2872
2873         /*
2874          * fill in common ATM interface stuff
2875          */
2876         sc->ifatm.mib.hw_version = (MID_VER(reg) << 16) |
2877             (MID_MID(reg) << 8) | MID_DID(reg);
2878         if (MID_DID(reg) & 0x4)
2879                 sc->ifatm.mib.media = IFM_ATM_UTP_155;
2880         else
2881                 sc->ifatm.mib.media = IFM_ATM_MM_155;
2882
2883         sc->ifatm.mib.pcr = ATM_RATE_155M;
2884         sc->ifatm.mib.vpi_bits = 0;
2885         sc->ifatm.mib.vci_bits = MID_VCI_BITS;
2886         sc->ifatm.mib.max_vccs = MID_N_VC;
2887         sc->ifatm.mib.max_vpcs = 0;
2888
2889         if (sc->is_adaptec) {
2890                 sc->ifatm.mib.device = ATM_DEVICE_ADP155P;
2891                 if (sc->bestburstlen == 64 && sc->alburst == 0)
2892                         if_printf(&sc->ifatm.ifnet,
2893                             "passed 64 byte DMA test\n");
2894                 else
2895                         if_printf(&sc->ifatm.ifnet, "FAILED DMA TEST: "
2896                             "burst=%d, alburst=%d\n", sc->bestburstlen,
2897                             sc->alburst);
2898         } else {
2899                 sc->ifatm.mib.device = ATM_DEVICE_ENI155P;
2900                 if_printf(&sc->ifatm.ifnet, "maximum DMA burst length = %d "
2901                     "bytes%s\n", sc->bestburstlen, sc->alburst ?
2902                     sc->noalbursts ?  " (no large bursts)" : " (must align)" :
2903                     "");
2904         }
2905
2906         /*
2907          * link into network subsystem and prepare card
2908          */
2909         sc->ifatm.ifnet.if_softc = sc;
2910         ifp->if_flags = IFF_SIMPLEX;
2911         ifp->if_ioctl = en_ioctl;
2912         ifp->if_start = en_start;
2913
2914         mtx_init(&sc->en_mtx, device_get_nameunit(sc->dev),
2915             MTX_NETWORK_LOCK, MTX_DEF);
2916         cv_init(&sc->cv_close, "VC close");
2917
2918         /*
2919          * Make the sysctl tree
2920          */
2921         sysctl_ctx_init(&sc->sysctl_ctx);
2922
2923         if ((sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
2924             SYSCTL_STATIC_CHILDREN(_hw_atm), OID_AUTO,
2925             device_get_nameunit(sc->dev), CTLFLAG_RD, 0, "")) == NULL)
2926                 goto fail;
2927
2928         if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
2929             OID_AUTO, "istats", CTLFLAG_RD, sc, 0, en_sysctl_istats,
2930             "S", "internal statistics") == NULL)
2931                 goto fail;
2932
2933 #ifdef EN_DEBUG
2934         if (SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
2935             OID_AUTO, "debug", CTLFLAG_RW , &sc->debug, 0, "") == NULL)
2936                 goto fail;
2937 #endif
2938
2939         sc->ifatm.phy = &sc->utopia;
2940         utopia_attach(&sc->utopia, &sc->ifatm, &sc->media, &sc->en_mtx,
2941             &sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
2942             &en_utopia_methods);
2943         utopia_init_media(&sc->utopia);
2944
2945         MGET(sc->padbuf, M_TRYWAIT, MT_DATA);
2946         if (sc->padbuf == NULL)
2947                 goto fail;
2948         bzero(sc->padbuf->m_data, MLEN);
2949
2950         if (bus_dma_tag_create(NULL, 1, 0,
2951             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
2952             EN_TXSZ * 1024, EN_MAX_DMASEG, EN_TXSZ * 1024, 0,
2953             NULL, NULL, &sc->txtag))
2954                 goto fail;
2955
2956         sc->map_zone = uma_zcreate("en dma maps", sizeof(struct en_map),
2957             en_map_ctor, en_map_dtor, NULL, en_map_fini, UMA_ALIGN_PTR,
2958             UMA_ZONE_ZINIT);
2959         if (sc->map_zone == NULL)
2960                 goto fail;
2961         uma_zone_set_max(sc->map_zone, EN_MAX_MAPS);
2962
2963         /*
2964          * init softc
2965          */
2966         sc->vccs = malloc(MID_N_VC * sizeof(sc->vccs[0]),
2967             M_DEVBUF, M_ZERO | M_WAITOK);
2968
2969         sz = sc->en_obmemsz - (MID_BUFOFF - MID_RAMOFF);
2970         ptr = sav = MID_BUFOFF;
2971         ptr = roundup(ptr, EN_TXSZ * 1024);     /* align */
2972         sz = sz - (ptr - sav);
2973         if (EN_TXSZ*1024 * EN_NTX > sz) {
2974                 if_printf(&sc->ifatm.ifnet, "EN_NTX/EN_TXSZ too big\n");
2975                 goto fail;
2976         }
2977         for (lcv = 0 ;lcv < EN_NTX ;lcv++) {
2978                 sc->txslot[lcv].mbsize = 0;
2979                 sc->txslot[lcv].start = ptr;
2980                 ptr += (EN_TXSZ * 1024);
2981                 sz -= (EN_TXSZ * 1024);
2982                 sc->txslot[lcv].stop = ptr;
2983                 sc->txslot[lcv].nref = 0;
2984                 DBG(sc, INIT, ("tx%d: start 0x%x, stop 0x%x", lcv,
2985                     sc->txslot[lcv].start, sc->txslot[lcv].stop));
2986         }
2987
2988         sav = ptr;
2989         ptr = roundup(ptr, EN_RXSZ * 1024);     /* align */
2990         sz = sz - (ptr - sav);
2991         sc->en_nrx = sz / (EN_RXSZ * 1024);
2992         if (sc->en_nrx <= 0) {
2993                 if_printf(&sc->ifatm.ifnet, "EN_NTX/EN_TXSZ/EN_RXSZ too big\n");
2994                 goto fail;
2995         }
2996
2997         /* 
2998          * ensure that there is always one VC slot on the service list free
2999          * so that we can tell the difference between a full and empty list.
3000          */
3001         if (sc->en_nrx >= MID_N_VC)
3002                 sc->en_nrx = MID_N_VC - 1;
3003
3004         for (lcv = 0 ; lcv < sc->en_nrx ; lcv++) {
3005                 sc->rxslot[lcv].vcc = NULL;
3006                 midvloc = sc->rxslot[lcv].start = ptr;
3007                 ptr += (EN_RXSZ * 1024);
3008                 sz -= (EN_RXSZ * 1024);
3009                 sc->rxslot[lcv].stop = ptr;
3010                 midvloc = midvloc - MID_RAMOFF;
3011                 /* mask, cvt to words */
3012                 midvloc = (midvloc & ~((EN_RXSZ*1024) - 1)) >> 2;
3013                 /* we only want the top 11 bits */
3014                 midvloc = midvloc >> MIDV_LOCTOPSHFT;
3015                 midvloc = (midvloc & MIDV_LOCMASK) << MIDV_LOCSHIFT;
3016                 sc->rxslot[lcv].mode = midvloc | 
3017                     (en_k2sz(EN_RXSZ) << MIDV_SZSHIFT) | MIDV_TRASH;
3018
3019                 DBG(sc, INIT, ("rx%d: start 0x%x, stop 0x%x, mode 0x%x", lcv,
3020                     sc->rxslot[lcv].start, sc->rxslot[lcv].stop,
3021                     sc->rxslot[lcv].mode));
3022         }
3023
3024         if_printf(&sc->ifatm.ifnet, "%d %dKB receive buffers, %d %dKB transmit "
3025             "buffers\n", sc->en_nrx, EN_RXSZ, EN_NTX, EN_TXSZ);
3026         if_printf(&sc->ifatm.ifnet, "end station identifier (mac address) "
3027             "%6D\n", sc->ifatm.mib.esi, ":");
3028
3029         /*
3030          * Start SUNI stuff. This will call our readregs/writeregs
3031          * functions and these assume the lock to be held so we must get it
3032          * here.
3033          */
3034         EN_LOCK(sc);
3035         utopia_start(&sc->utopia);
3036         utopia_reset(&sc->utopia);
3037         EN_UNLOCK(sc);
3038
3039         /*
3040          * final commit
3041          */
3042         atm_ifattach(ifp); 
3043
3044 #ifdef ENABLE_BPF
3045         bpfattach(ifp, DLT_ATM_RFC1483, sizeof(struct atmllc));
3046 #endif
3047
3048         return (0);
3049
3050  fail:
3051         en_destroy(sc);
3052         return (-1);
3053 }
3054
3055 /*
3056  * Free all internal resources. No access to bus resources here.
3057  * No locking required here (interrupt is already disabled).
3058  *
3059  * LOCK: unlocked, needed (but destroyed)
3060  */
3061 void
3062 en_destroy(struct en_softc *sc)
3063 {
3064         u_int i;
3065
3066         if (sc->utopia.state & UTP_ST_ATTACHED) {
3067                 /* these assume the lock to be held */
3068                 EN_LOCK(sc);
3069                 utopia_stop(&sc->utopia);
3070                 utopia_detach(&sc->utopia);
3071                 EN_UNLOCK(sc);
3072         }
3073
3074         if (sc->vccs != NULL) {
3075                 /* get rid of sticky VCCs */
3076                 for (i = 0; i < MID_N_VC; i++)
3077                         if (sc->vccs[i] != NULL)
3078                                 uma_zfree(en_vcc_zone, sc->vccs[i]);
3079                 free(sc->vccs, M_DEVBUF);
3080         }
3081
3082         if (sc->padbuf != NULL)
3083                 m_free(sc->padbuf);
3084
3085         /*
3086          * Destroy the map zone before the tag (the fini function will
3087          * destroy the DMA maps using the tag)
3088          */
3089         if (sc->map_zone != NULL)
3090                 uma_zdestroy(sc->map_zone);
3091
3092         if (sc->txtag != NULL)
3093                 bus_dma_tag_destroy(sc->txtag);
3094
3095         (void)sysctl_ctx_free(&sc->sysctl_ctx);
3096
3097         cv_destroy(&sc->cv_close);
3098         mtx_destroy(&sc->en_mtx);
3099 }
3100
3101 /*
3102  * Module loaded/unloaded
3103  */
3104 int
3105 en_modevent(module_t mod __unused, int event, void *arg __unused)
3106 {
3107
3108         switch (event) {
3109
3110           case MOD_LOAD:
3111                 en_vcc_zone = uma_zcreate("EN vccs", sizeof(struct en_vcc),
3112                     NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
3113                 if (en_vcc_zone == NULL)
3114                         return (ENOMEM);
3115                 break;
3116
3117           case MOD_UNLOAD:
3118                 uma_zdestroy(en_vcc_zone);
3119                 break;
3120         }
3121         return (0);
3122 }
3123
3124 /*********************************************************************/
3125 /*
3126  * Debugging support
3127  */
3128
3129 #ifdef EN_DDBHOOK
3130 /*
3131  * functions we can call from ddb
3132  */
3133
3134 /*
3135  * en_dump: dump the state
3136  */
3137 #define END_SWSL        0x00000040              /* swsl state */
3138 #define END_DRQ         0x00000020              /* drq state */
3139 #define END_DTQ         0x00000010              /* dtq state */
3140 #define END_RX          0x00000008              /* rx state */
3141 #define END_TX          0x00000004              /* tx state */
3142 #define END_MREGS       0x00000002              /* registers */
3143 #define END_STATS       0x00000001              /* dump stats */
3144
3145 #define END_BITS "\20\7SWSL\6DRQ\5DTQ\4RX\3TX\2MREGS\1STATS"
3146
3147 static void
3148 en_dump_stats(const struct en_stats *s)
3149 {
3150         printf("en_stats:\n");
3151         printf("\t%d/%d mfix (%d failed)\n", s->mfixaddr, s->mfixlen,
3152             s->mfixfail);
3153         printf("\t%d rx dma overflow interrupts\n", s->dmaovr);
3154         printf("\t%d times out of TX space and stalled\n", s->txoutspace);
3155         printf("\t%d times out of DTQs\n", s->txdtqout);
3156         printf("\t%d times launched a packet\n", s->launch);
3157         printf("\t%d times pulled the hw service list\n", s->hwpull);
3158         printf("\t%d times pushed a vci on the sw service list\n", s->swadd);
3159         printf("\t%d times RX pulled an mbuf from Q that wasn't ours\n",
3160             s->rxqnotus);
3161         printf("\t%d times RX pulled a good mbuf from Q\n", s->rxqus);
3162         printf("\t%d times ran out of DRQs\n", s->rxdrqout);
3163         printf("\t%d transmit packets dropped due to mbsize\n", s->txmbovr);
3164         printf("\t%d cells trashed due to turned off rxvc\n", s->vtrash);
3165         printf("\t%d cells trashed due to totally full buffer\n", s->otrash);
3166         printf("\t%d cells trashed due almost full buffer\n", s->ttrash);
3167         printf("\t%d rx mbuf allocation failures\n", s->rxmbufout);
3168         printf("\t%d times out of tx maps\n", s->txnomap);
3169 #ifdef NATM
3170 #ifdef NATM_STAT
3171         printf("\tnatmintr so_rcv: ok/drop cnt: %d/%d, ok/drop bytes: %d/%d\n",
3172             natm_sookcnt, natm_sodropcnt, natm_sookbytes, natm_sodropbytes);
3173 #endif
3174 #endif
3175 }
3176
3177 static void
3178 en_dump_mregs(struct en_softc *sc)
3179 {
3180         u_int cnt;
3181
3182         printf("mregs:\n");
3183         printf("resid = 0x%x\n", en_read(sc, MID_RESID));
3184         printf("interrupt status = 0x%b\n",
3185             (int)en_read(sc, MID_INTSTAT), MID_INTBITS);
3186         printf("interrupt enable = 0x%b\n", 
3187              (int)en_read(sc, MID_INTENA), MID_INTBITS);
3188         printf("mcsr = 0x%b\n", (int)en_read(sc, MID_MAST_CSR), MID_MCSRBITS);
3189         printf("serv_write = [chip=%u] [us=%u]\n", en_read(sc, MID_SERV_WRITE),
3190              MID_SL_A2REG(sc->hwslistp));
3191         printf("dma addr = 0x%x\n", en_read(sc, MID_DMA_ADDR));
3192         printf("DRQ: chip[rd=0x%x,wr=0x%x], sc[chip=0x%x,us=0x%x]\n",
3193             MID_DRQ_REG2A(en_read(sc, MID_DMA_RDRX)), 
3194             MID_DRQ_REG2A(en_read(sc, MID_DMA_WRRX)), sc->drq_chip, sc->drq_us);
3195         printf("DTQ: chip[rd=0x%x,wr=0x%x], sc[chip=0x%x,us=0x%x]\n",
3196             MID_DTQ_REG2A(en_read(sc, MID_DMA_RDTX)), 
3197             MID_DTQ_REG2A(en_read(sc, MID_DMA_WRTX)), sc->dtq_chip, sc->dtq_us);
3198
3199         printf("  unusal txspeeds:");
3200         for (cnt = 0 ; cnt < MID_N_VC ; cnt++)
3201                 if (sc->vccs[cnt]->txspeed)
3202                         printf(" vci%d=0x%x", cnt, sc->vccs[cnt]->txspeed);
3203         printf("\n");
3204
3205         printf("  rxvc slot mappings:");
3206         for (cnt = 0 ; cnt < MID_N_VC ; cnt++)
3207                 if (sc->vccs[cnt]->rxslot != NULL)
3208                         printf("  %d->%zu", cnt,
3209                             sc->vccs[cnt]->rxslot - sc->rxslot);
3210         printf("\n");
3211 }
3212
3213 static void
3214 en_dump_tx(struct en_softc *sc)
3215 {
3216         u_int slot;
3217
3218         printf("tx:\n");
3219         for (slot = 0 ; slot < EN_NTX; slot++) {
3220                 printf("tx%d: start/stop/cur=0x%x/0x%x/0x%x [%d]  ", slot,
3221                     sc->txslot[slot].start, sc->txslot[slot].stop,
3222                     sc->txslot[slot].cur,
3223                     (sc->txslot[slot].cur - sc->txslot[slot].start) / 4);
3224                 printf("mbsize=%d, bfree=%d\n", sc->txslot[slot].mbsize,
3225                     sc->txslot[slot].bfree);
3226                 printf("txhw: base_address=0x%x, size=%u, read=%u, "
3227                     "descstart=%u\n",
3228                     (u_int)MIDX_BASE(en_read(sc, MIDX_PLACE(slot))), 
3229                     MIDX_SZ(en_read(sc, MIDX_PLACE(slot))),
3230                     en_read(sc, MIDX_READPTR(slot)),
3231                     en_read(sc, MIDX_DESCSTART(slot)));
3232         }
3233 }
3234
3235 static void
3236 en_dump_rx(struct en_softc *sc)
3237 {
3238         struct en_rxslot *slot;
3239
3240         printf("  recv slots:\n");
3241         for (slot = sc->rxslot ; slot < &sc->rxslot[sc->en_nrx]; slot++) {
3242                 printf("rx%zu: start/stop/cur=0x%x/0x%x/0x%x mode=0x%x ",
3243                     slot - sc->rxslot, slot->start, slot->stop, slot->cur,
3244                     slot->mode);
3245                 if (slot->vcc != NULL) {
3246                         printf("vci=%u\n", slot->vcc->vcc.vci);
3247                         printf("RXHW: mode=0x%x, DST_RP=0x%x, WP_ST_CNT=0x%x\n",
3248                             en_read(sc, MID_VC(slot->vcc->vcc.vci)),
3249                             en_read(sc, MID_DST_RP(slot->vcc->vcc.vci)),
3250                             en_read(sc, MID_WP_ST_CNT(slot->vcc->vcc.vci)));
3251                 }
3252         }
3253 }
3254
3255 /*
3256  * This is only correct for non-adaptec adapters
3257  */
3258 static void
3259 en_dump_dtqs(struct en_softc *sc)
3260 {
3261         uint32_t ptr, reg;
3262
3263         printf("  dtq [need_dtqs=%d,dtq_free=%d]:\n", sc->need_dtqs,
3264             sc->dtq_free);
3265         ptr = sc->dtq_chip;
3266         while (ptr != sc->dtq_us) {
3267                 reg = en_read(sc, ptr);
3268                 printf("\t0x%x=[%#x cnt=%d, chan=%d, end=%d, type=%d @ 0x%x]\n", 
3269                     sc->dtq[MID_DTQ_A2REG(ptr)], reg, MID_DMA_CNT(reg),
3270                     MID_DMA_TXCHAN(reg), (reg & MID_DMA_END) != 0,
3271                     MID_DMA_TYPE(reg), en_read(sc, ptr + 4));
3272                 EN_WRAPADD(MID_DTQOFF, MID_DTQEND, ptr, 8);
3273         }
3274 }
3275
3276 static void
3277 en_dump_drqs(struct en_softc *sc)
3278 {
3279         uint32_t ptr, reg;
3280
3281         printf("  drq [need_drqs=%d,drq_free=%d]:\n", sc->need_drqs,
3282             sc->drq_free);
3283         ptr = sc->drq_chip;
3284         while (ptr != sc->drq_us) {
3285                 reg = en_read(sc, ptr);
3286                 printf("\t0x%x=[cnt=%d, chan=%d, end=%d, type=%d @ 0x%x]\n", 
3287                     sc->drq[MID_DRQ_A2REG(ptr)], MID_DMA_CNT(reg),
3288                     MID_DMA_RXVCI(reg), (reg & MID_DMA_END) != 0,
3289                     MID_DMA_TYPE(reg), en_read(sc, ptr + 4));
3290                 EN_WRAPADD(MID_DRQOFF, MID_DRQEND, ptr, 8);
3291         }
3292 }
3293
3294 /* Do not staticize - meant for calling from DDB! */
3295 int
3296 en_dump(int unit, int level)
3297 {
3298         struct en_softc *sc;
3299         int lcv, cnt;
3300         devclass_t dc;
3301         int maxunit;
3302
3303         dc = devclass_find("en");
3304         if (dc == NULL) {
3305                 printf("%s: can't find devclass!\n", __func__);
3306                 return (0);
3307         }
3308         maxunit = devclass_get_maxunit(dc);
3309         for (lcv = 0 ; lcv < maxunit ; lcv++) {
3310                 sc = devclass_get_softc(dc, lcv);
3311                 if (sc == NULL)
3312                         continue;
3313                 if (unit != -1 && unit != lcv)
3314                         continue;
3315
3316                 if_printf(&sc->ifatm.ifnet, "dumping device at level 0x%b\n",
3317                     level, END_BITS);
3318
3319                 if (sc->dtq_us == 0) {
3320                         printf("<hasn't been en_init'd yet>\n");
3321                         continue;
3322                 }
3323
3324                 if (level & END_STATS)
3325                         en_dump_stats(&sc->stats);
3326                 if (level & END_MREGS)
3327                         en_dump_mregs(sc);
3328                 if (level & END_TX)
3329                         en_dump_tx(sc);
3330                 if (level & END_RX)
3331                         en_dump_rx(sc);
3332                 if (level & END_DTQ)
3333                         en_dump_dtqs(sc);
3334                 if (level & END_DRQ)
3335                         en_dump_drqs(sc);
3336
3337                 if (level & END_SWSL) {
3338                         printf(" swslist [size=%d]: ", sc->swsl_size);
3339                         for (cnt = sc->swsl_head ; cnt != sc->swsl_tail ; 
3340                             cnt = (cnt + 1) % MID_SL_N)
3341                                 printf("0x%x ", sc->swslist[cnt]);
3342                         printf("\n");
3343                 }
3344         }
3345         return (0);
3346 }
3347
3348 /*
3349  * en_dumpmem: dump the memory
3350  *
3351  * Do not staticize - meant for calling from DDB!
3352  */
3353 int
3354 en_dumpmem(int unit, int addr, int len)
3355 {
3356         struct en_softc *sc;
3357         uint32_t reg;
3358         devclass_t dc;
3359
3360         dc = devclass_find("en");
3361         if (dc == NULL) {
3362                 printf("%s: can't find devclass\n", __func__);
3363                 return (0);
3364         }
3365         sc = devclass_get_softc(dc, unit);
3366         if (sc == NULL) {
3367                 printf("%s: invalid unit number: %d\n", __func__, unit);
3368                 return (0);
3369         }
3370
3371         addr = addr & ~3;
3372         if (addr < MID_RAMOFF || addr + len * 4 > MID_MAXOFF || len <= 0) {
3373                 printf("invalid addr/len number: %d, %d\n", addr, len);
3374                 return (0);
3375         }
3376         printf("dumping %d words starting at offset 0x%x\n", len, addr);
3377         while (len--) {
3378                 reg = en_read(sc, addr);
3379                 printf("mem[0x%x] = 0x%x\n", addr, reg);
3380                 addr += 4;
3381         }
3382         return (0);
3383 }
3384 #endif