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