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