Merge from vendor branch GCC:
[dragonfly.git] / sys / dev / netif / ie / if_ie.c
1 /*-
2  * Copyright (c) 1992, 1993, University of Vermont and State
3  *  Agricultural College.
4  * Copyright (c) 1992, 1993, Garrett A. Wollman.
5  *
6  * Portions:
7  * Copyright (c) 1990, 1991, William F. Jolitz
8  * Copyright (c) 1990, The Regents of the University of California
9  *
10  * 3Com 3C507 support:
11  * Copyright (c) 1993, 1994, Charles M. Hannum
12  *
13  * EtherExpress 16 support:
14  * Copyright (c) 1993, 1994, 1995, Rodney W. Grimes
15  * Copyright (c) 1997, Aaron C. Smith
16  *
17  * All rights reserved.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions
21  * are met:
22  * 1. Redistributions of source code must retain the above copyright
23  *    notice, this list of conditions and the following disclaimer.
24  * 2. Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in the
26  *    documentation and/or other materials provided with the distribution.
27  * 3. All advertising materials mentioning features or use of this software
28  *    must display the following acknowledgement:
29  *      This product includes software developed by the University of
30  *      Vermont and State Agricultural College and Garrett A. Wollman, by
31  *      William F. Jolitz, by the University of California, Berkeley,
32  *      Lawrence Berkeley Laboratory, and their contributors, by
33  *      Charles M. Hannum, by Rodney W. Grimes, and by Aaron C. Smith.
34  * 4. Neither the names of the Universities nor the names of the authors
35  *    may be used to endorse or promote products derived from this software
36  *    without specific prior written permission.
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
42  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  *
50  * $FreeBSD: src/sys/dev/ie/if_ie.c,v 1.72.2.4 2003/03/27 21:01:49 mdodd Exp $
51  * $DragonFly: src/sys/dev/netif/ie/if_ie.c,v 1.12 2004/06/02 14:42:52 eirikn Exp $
52  */
53
54 /*
55  * Intel 82586 Ethernet chip
56  * Register, bit, and structure definitions.
57  *
58  * Written by GAW with reference to the Clarkson Packet Driver code for this
59  * chip written by Russ Nelson and others.
60  *
61  * Intel EtherExpress 16 support from if_ix.c, written by Rodney W. Grimes.
62  */
63
64 /*
65  * The i82586 is a very versatile chip, found in many implementations.
66  * Programming this chip is mostly the same, but certain details differ
67  * from card to card.  This driver is written so that different cards
68  * can be automatically detected at run-time.
69  */
70
71 /*
72 Mode of operation:
73
74 We run the 82586 in a standard Ethernet mode.  We keep NFRAMES received
75 frame descriptors around for the receiver to use, and NRXBUFS associated
76 receive buffer descriptors, both in a circular list.  Whenever a frame is
77 received, we rotate both lists as necessary.  (The 586 treats both lists
78 as a simple queue.)  We also keep a transmit command around so that packets
79 can be sent off quickly.
80
81 We configure the adapter in AL-LOC = 1 mode, which means that the
82 Ethernet/802.3 MAC header is placed at the beginning of the receive buffer
83 rather than being split off into various fields in the RFD.  This also
84 means that we must include this header in the transmit buffer as well.
85
86 By convention, all transmit commands, and only transmit commands, shall
87 have the I (IE_CMD_INTR) bit set in the command.  This way, when an
88 interrupt arrives at ieintr(), it is immediately possible to tell
89 what precisely caused it.  ANY OTHER command-sending routines should
90 run at splimp(), and should post an acknowledgement to every interrupt
91 they generate.
92
93 The 82586 has a 24-bit address space internally, and the adaptor's memory
94 is located at the top of this region.  However, the value we are given in
95 configuration is normally the *bottom* of the adaptor RAM.  So, we must go
96 through a few gyrations to come up with a kernel virtual address which
97 represents the actual beginning of the 586 address space.  First, we
98 autosize the RAM by running through several possible sizes and trying to
99 initialize the adapter under the assumption that the selected size is
100 correct.  Then, knowing the correct RAM size, we set up our pointers in
101 ie_softc[unit].  `iomem' represents the computed base of the 586 address
102 space.  `iomembot' represents the actual configured base of adapter RAM.
103 Finally, `iosize' represents the calculated size of 586 RAM.  Then, when
104 laying out commands, we use the interval [iomembot, iomembot + iosize); to
105 make 24-pointers, we subtract iomem, and to make 16-pointers, we subtract
106 iomem and and with 0xffff.
107
108 */
109
110 #include "use_ie.h"
111 #include "opt_inet.h"
112 #include "opt_ipx.h"
113
114 #include <sys/param.h>
115 #include <sys/systm.h>
116 #include <sys/eventhandler.h>
117 #include <sys/kernel.h>
118 #include <sys/malloc.h>
119 #include <sys/conf.h>
120 #include <sys/mbuf.h>
121 #include <sys/socket.h>
122 #include <sys/sockio.h>
123 #include <sys/syslog.h>
124
125 #include <net/ethernet.h>
126 #include <net/if.h>
127 #include <net/if_types.h>
128 #include <net/if_dl.h>
129
130 #include <netinet/in.h>
131 #include <netinet/if_ether.h>
132
133 #include <machine/clock.h>
134 #include <machine/md_var.h>
135
136 #include <bus/isa/i386/isa_device.h>
137 #include <i386/isa/ic/i82586.h>
138 #include <i386/isa/icu.h>
139 #include "if_iereg.h"
140 #include "if_ie507.h"
141 #include "if_iee16.h"
142 #include "../elink_layer/elink.h"
143
144 #include <net/bpf.h>
145
146 #ifdef DEBUG
147 #define IED_RINT        0x01
148 #define IED_TINT        0x02
149 #define IED_RNR         0x04
150 #define IED_CNA         0x08
151 #define IED_READFRAME   0x10
152 static int      ie_debug = IED_RNR;
153
154 #endif
155
156 DECLARE_DUMMY_MODULE(if_ie);
157
158 #define IE_BUF_LEN      ETHER_MAX_LEN   /* length of transmit buffer */
159
160 /* Forward declaration */
161 struct ie_softc;
162
163 static int      ieprobe(struct isa_device * dvp);
164 static int      ieattach(struct isa_device * dvp);
165 static ointhand2_t      ieintr;
166 static int      sl_probe(struct isa_device * dvp);
167 static int      el_probe(struct isa_device * dvp);
168 static int      ni_probe(struct isa_device * dvp);
169 static int      ee16_probe(struct isa_device * dvp);
170
171 static int      check_ie_present(int unit, caddr_t where, unsigned size);
172 static void     ieinit(void *);
173 static void     ie_stop(int unit);
174 static int      ieioctl(struct ifnet * ifp, u_long command, caddr_t data,
175                         struct ucred *);
176 static void     iestart(struct ifnet * ifp);
177
178 static void     el_reset_586(int unit);
179 static void     el_chan_attn(int unit);
180
181 static void     sl_reset_586(int unit);
182 static void     sl_chan_attn(int unit);
183
184 static void     ee16_reset_586(int unit);
185 static void     ee16_chan_attn(int unit);
186 static __inline void ee16_interrupt_enable(struct ie_softc * ie);
187 static void     ee16_eeprom_outbits(struct ie_softc * ie, int edata, int cnt);
188 static void     ee16_eeprom_clock(struct ie_softc * ie, int state);
189 static u_short  ee16_read_eeprom(struct ie_softc * ie, int location);
190 static int      ee16_eeprom_inbits(struct ie_softc * ie);
191 static void     ee16_shutdown(void *sc, int howto);
192
193 static void     iereset(int unit);
194 static void     ie_readframe(int unit, struct ie_softc * ie, int bufno);
195 static void     ie_drop_packet_buffer(int unit, struct ie_softc * ie);
196 static void     sl_read_ether(int unit, unsigned char addr[6]);
197 static void     find_ie_mem_size(int unit);
198 static void     chan_attn_timeout(void *rock);
199 static int      command_and_wait(int unit, int command,
200                                  void volatile * pcmd, int);
201 static void     run_tdr(int unit, volatile struct ie_tdr_cmd * cmd);
202 static int      ierint(int unit, struct ie_softc * ie);
203 static int      ietint(int unit, struct ie_softc * ie);
204 static int      iernr(int unit, struct ie_softc * ie);
205 static void     start_receiver(int unit);
206 static __inline int ieget(int, struct ie_softc *, struct mbuf **,
207                           struct ether_header *);
208 static v_caddr_t setup_rfa(v_caddr_t ptr, struct ie_softc * ie);
209 static int      mc_setup(int, v_caddr_t, volatile struct ie_sys_ctl_block *);
210 static void     ie_mc_reset(int unit);
211
212 #ifdef DEBUG
213 static void     print_rbd(volatile struct ie_recv_buf_desc * rbd);
214
215 static int      in_ierint = 0;
216 static int      in_ietint = 0;
217
218 #endif
219
220 /*
221  * This tells the autoconf code how to set us up.
222  */
223 struct isa_driver iedriver = {
224         ieprobe, ieattach, "ie",
225 };
226
227 enum ie_hardware {
228         IE_STARLAN10,
229         IE_EN100,
230         IE_SLFIBER,
231         IE_3C507,
232         IE_NI5210,
233         IE_EE16,
234         IE_UNKNOWN
235 };
236
237 static const char *ie_hardware_names[] = {
238         "StarLAN 10",
239         "EN100",
240         "StarLAN Fiber",
241         "3C507",
242         "NI5210",
243         "EtherExpress 16",
244         "Unknown"
245 };
246
247 /*
248 sizeof(iscp) == 1+1+2+4 == 8
249 sizeof(scb) == 2+2+2+2+2+2+2+2 == 16
250 NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384
251 sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18
252 sizeof(transmit buffer) == 1512
253 sizeof(transmit buffer desc) == 8
254 -----
255 1946
256
257 NRXBUFS * sizeof(rbd) == NRXBUFS*(2+2+4+2+2) == NRXBUFS*12
258 NRXBUFS * IE_RBUF_SIZE == NRXBUFS*256
259
260 NRXBUFS should be (16384 - 1946) / (256 + 12) == 14438 / 268 == 53
261
262 With NRXBUFS == 48, this leaves us 1574 bytes for another command or
263 more buffers.  Another transmit command would be 18+8+1512 == 1538
264 ---just barely fits!
265
266 Obviously all these would have to be reduced for smaller memory sizes.
267 With a larger memory, it would be possible to roughly double the number of
268 both transmit and receive buffers.
269 */
270
271 #define NFRAMES         8       /* number of receive frames */
272 #define NRXBUFS         48      /* number of buffers to allocate */
273 #define IE_RBUF_SIZE    256     /* size of each buffer, MUST BE POWER OF TWO */
274 #define NTXBUFS         2       /* number of transmit commands */
275 #define IE_TBUF_SIZE    ETHER_MAX_LEN   /* size of transmit buffer */
276
277 /*
278  * Ethernet status, per interface.
279  */
280 static struct ie_softc {
281         struct   arpcom arpcom;
282         void     (*ie_reset_586) (int);
283         void     (*ie_chan_attn) (int);
284         enum     ie_hardware hard_type;
285         int      hard_vers;
286         int      unit;
287
288         u_short  port;          /* i/o base address for this interface */
289         caddr_t  iomem;         /* memory size */
290         caddr_t  iomembot;      /* memory base address */
291         unsigned iosize;
292         int      bus_use;       /* 0 means 16bit, 1 means 8 bit adapter */
293
294         int      want_mcsetup;
295         int      promisc;
296         int      nframes;
297         int      nrxbufs;
298         int      ntxbufs;
299         volatile struct ie_int_sys_conf_ptr *iscp;
300         volatile struct ie_sys_ctl_block *scb;
301         volatile struct ie_recv_frame_desc **rframes;   /* nframes worth */
302         volatile struct ie_recv_buf_desc **rbuffs;      /* nrxbufs worth */
303         volatile u_char **cbuffs;                       /* nrxbufs worth */
304         int      rfhead, rftail, rbhead, rbtail;
305
306         volatile struct ie_xmit_cmd **xmit_cmds;        /* ntxbufs worth */
307         volatile struct ie_xmit_buf **xmit_buffs;       /* ntxbufs worth */
308         volatile u_char  **xmit_cbuffs;                 /* ntxbufs worth */
309         int      xmit_count;
310
311         struct   ie_en_addr mcast_addrs[MAXMCAST + 1];
312         int      mcast_count;
313
314         u_short  irq_encoded;   /* encoded interrupt on IEE16 */
315 }       ie_softc[NIE];
316
317 #define MK_24(base, ptr) ((caddr_t)((uintptr_t)ptr - (uintptr_t)base))
318 #define MK_16(base, ptr) ((u_short)(uintptr_t)MK_24(base, ptr))
319
320 #define PORT ie_softc[unit].port
321 #define MEM  ie_softc[unit].iomem
322
323 int
324 ieprobe(struct isa_device *dvp)
325 {
326         int     ret;
327
328         ret = sl_probe(dvp);
329         if (!ret)
330                 ret = el_probe(dvp);
331         if (!ret)
332                 ret = ni_probe(dvp);
333         if (!ret)
334                 ret = ee16_probe(dvp);
335
336         return (ret);
337 }
338
339 static int
340 sl_probe(struct isa_device *dvp)
341 {
342         int     unit = dvp->id_unit;
343         u_char  c;
344
345         ie_softc[unit].port = dvp->id_iobase;
346         ie_softc[unit].iomembot = dvp->id_maddr;
347         ie_softc[unit].iomem = 0;
348         ie_softc[unit].bus_use = 0;
349
350         c = inb(PORT + IEATT_REVISION);
351         switch (SL_BOARD(c)) {
352         case SL10_BOARD:
353                 ie_softc[unit].hard_type = IE_STARLAN10;
354                 ie_softc[unit].ie_reset_586 = sl_reset_586;
355                 ie_softc[unit].ie_chan_attn = sl_chan_attn;
356                 break;
357         case EN100_BOARD:
358                 ie_softc[unit].hard_type = IE_EN100;
359                 ie_softc[unit].ie_reset_586 = sl_reset_586;
360                 ie_softc[unit].ie_chan_attn = sl_chan_attn;
361                 break;
362         case SLFIBER_BOARD:
363                 ie_softc[unit].hard_type = IE_SLFIBER;
364                 ie_softc[unit].ie_reset_586 = sl_reset_586;
365                 ie_softc[unit].ie_chan_attn = sl_chan_attn;
366                 break;
367
368                 /*
369                  * Anything else is not recognized or cannot be used.
370                  */
371         default:
372                 return (0);
373         }
374
375         ie_softc[unit].hard_vers = SL_REV(c);
376
377         /*
378          * Divine memory size on-board the card.  Ususally 16k.
379          */
380         find_ie_mem_size(unit);
381
382         if (!ie_softc[unit].iosize) {
383                 return (0);
384         }
385         dvp->id_msize = ie_softc[unit].iosize;
386
387         switch (ie_softc[unit].hard_type) {
388         case IE_EN100:
389         case IE_STARLAN10:
390         case IE_SLFIBER:
391                 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
392                 break;
393
394         default:
395                 if (bootverbose)
396                         printf("ie%d: unknown AT&T board type code %d\n", unit,
397                         ie_softc[unit].hard_type);
398                 return (0);
399         }
400
401         return (1);
402 }
403
404
405 static int
406 el_probe(struct isa_device *dvp)
407 {
408         struct ie_softc *sc = &ie_softc[dvp->id_unit];
409         u_char  c;
410         int     i;
411         u_char  signature[] = "*3COM*";
412         int     unit = dvp->id_unit;
413
414         sc->unit = unit;
415         sc->port = dvp->id_iobase;
416         sc->iomembot = dvp->id_maddr;
417         sc->bus_use = 0;
418
419         /* Need this for part of the probe. */
420         sc->ie_reset_586 = el_reset_586;
421         sc->ie_chan_attn = el_chan_attn;
422
423         /* Reset and put card in CONFIG state without changing address. */
424         elink_reset();
425         outb(ELINK_ID_PORT, 0x00);
426         elink_idseq(ELINK_507_POLY);
427         elink_idseq(ELINK_507_POLY);
428         outb(ELINK_ID_PORT, 0xff);
429
430         c = inb(PORT + IE507_MADDR);
431         if (c & 0x20) {
432 #ifdef DEBUG
433                 printf("ie%d: can't map 3C507 RAM in high memory\n", unit);
434 #endif
435                 return (0);
436         }
437         /* go to RUN state */
438         outb(ELINK_ID_PORT, 0x00);
439         elink_idseq(ELINK_507_POLY);
440         outb(ELINK_ID_PORT, 0x00);
441
442         outb(PORT + IE507_CTRL, EL_CTRL_NRST);
443
444         for (i = 0; i < 6; i++)
445                 if (inb(PORT + i) != signature[i])
446                         return (0);
447
448         c = inb(PORT + IE507_IRQ) & 0x0f;
449
450         if (dvp->id_irq != (1 << c)) {
451                 printf("ie%d: kernel configured irq %d "
452                        "doesn't match board configured irq %d\n",
453                        unit, ffs(dvp->id_irq) - 1, c);
454                 return (0);
455         }
456         c = (inb(PORT + IE507_MADDR) & 0x1c) + 0xc0;
457
458         if (kvtop(dvp->id_maddr) != ((int) c << 12)) {
459                 printf("ie%d: kernel configured maddr %llx "
460                        "doesn't match board configured maddr %x\n",
461                        unit, kvtop(dvp->id_maddr), (int) c << 12);
462                 return (0);
463         }
464         outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
465
466         sc->hard_type = IE_3C507;
467         sc->hard_vers = 0;      /* 3C507 has no version number. */
468
469         /*
470          * Divine memory size on-board the card.
471          */
472         find_ie_mem_size(unit);
473
474         if (!sc->iosize) {
475                 printf("ie%d: can't find shared memory\n", unit);
476                 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
477                 return (0);
478         }
479         if (!dvp->id_msize)
480                 dvp->id_msize = sc->iosize;
481         else if (dvp->id_msize != sc->iosize) {
482                 printf("ie%d: kernel configured msize %d "
483                        "doesn't match board configured msize %d\n",
484                        unit, dvp->id_msize, sc->iosize);
485                 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
486                 return (0);
487         }
488         sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
489
490         /* Clear the interrupt latch just in case. */
491         outb(PORT + IE507_ICTRL, 1);
492
493         return (16);
494 }
495
496
497 static int
498 ni_probe(struct isa_device *dvp)
499 {
500         int     unit = dvp->id_unit;
501         int     boardtype, c;
502
503         ie_softc[unit].port = dvp->id_iobase;
504         ie_softc[unit].iomembot = dvp->id_maddr;
505         ie_softc[unit].iomem = 0;
506         ie_softc[unit].bus_use = 1;
507
508         boardtype = inb(PORT + IEATT_REVISION);
509         c = inb(PORT + IEATT_REVISION + 1);
510         boardtype = boardtype + (c << 8);
511         switch (boardtype) {
512         case 0x5500:            /* This is the magic cookie for the NI5210 */
513                 ie_softc[unit].hard_type = IE_NI5210;
514                 ie_softc[unit].ie_reset_586 = sl_reset_586;
515                 ie_softc[unit].ie_chan_attn = sl_chan_attn;
516                 break;
517
518                 /*
519                  * Anything else is not recognized or cannot be used.
520                  */
521         default:
522                 return (0);
523         }
524
525         ie_softc[unit].hard_vers = 0;
526
527         /*
528          * Divine memory size on-board the card.  Either 8 or 16k.
529          */
530         find_ie_mem_size(unit);
531
532         if (!ie_softc[unit].iosize) {
533                 return (0);
534         }
535         if (!dvp->id_msize)
536                 dvp->id_msize = ie_softc[unit].iosize;
537         else if (dvp->id_msize != ie_softc[unit].iosize) {
538                 printf("ie%d: kernel configured msize %d "
539                        "doesn't match board configured msize %d\n",
540                        unit, dvp->id_msize, ie_softc[unit].iosize);
541                 return (0);
542         }
543         sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
544
545         return (8);
546
547 }
548
549
550 static void
551 ee16_shutdown(void *sc, int howto)
552 {
553         struct  ie_softc *ie = (struct ie_softc *)sc;
554         int     unit = ie - &ie_softc[0];
555
556         ee16_reset_586(unit);
557         outb(PORT + IEE16_ECTRL, IEE16_RESET_ASIC);
558         outb(PORT + IEE16_ECTRL, 0);
559 }
560
561
562 /* Taken almost exactly from Rod's if_ix.c. */
563
564 int
565 ee16_probe(struct isa_device *dvp)
566 {
567         struct ie_softc *sc = &ie_softc[dvp->id_unit];
568
569         int     i;
570         int     unit = dvp->id_unit;
571         u_short board_id, id_var1, id_var2, checksum = 0;
572         u_short eaddrtemp, irq;
573         u_short pg, adjust, decode, edecode;
574         u_char  bart_config;
575         u_long  bd_maddr;
576
577         short   irq_translate[] = {0, IRQ9, IRQ3, IRQ4, IRQ5, IRQ10, IRQ11, 0};
578         char    irq_encode[] = {0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0};
579
580         /* Need this for part of the probe. */
581         sc->ie_reset_586 = ee16_reset_586;
582         sc->ie_chan_attn = ee16_chan_attn;
583
584         /* unsure if this is necessary */
585         sc->bus_use = 0;
586
587         /* reset any ee16 at the current iobase */
588         outb(dvp->id_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
589         outb(dvp->id_iobase + IEE16_ECTRL, 0);
590         DELAY(240);
591
592         /* now look for ee16. */
593         board_id = id_var1 = id_var2 = 0;
594         for (i = 0; i < 4; i++) {
595                 id_var1 = inb(dvp->id_iobase + IEE16_ID_PORT);
596                 id_var2 = ((id_var1 & 0x03) << 2);
597                 board_id |= ((id_var1 >> 4) << id_var2);
598         }
599
600         if (board_id != IEE16_ID) {
601                 if (bootverbose)
602                         printf("ie%d: unknown board_id: %x\n", unit, board_id);
603                 return (0);
604         }
605         /* need sc->port for ee16_read_eeprom */
606         sc->port = dvp->id_iobase;
607         sc->hard_type = IE_EE16;
608
609         /*
610          * The shared RAM location on the EE16 is encoded into bits 3-7 of
611          * EEPROM location 6.  We zero the upper byte, and shift the 5 bits
612          * right 3.  The resulting number tells us the RAM location.
613          * Because the EE16 supports either 16k or 32k of shared RAM, we
614          * only worry about the 32k locations.
615          *
616          * NOTE: if a 64k EE16 exists, it should be added to this switch. then
617          * the ia->ia_msize would need to be set per case statement.
618          *
619          * value        msize   location =====  =====   ======== 0x03   0x8000
620          * 0xCC000 0x06 0x8000  0xD0000 0x0C    0x8000  0xD4000 0x18
621          * 0x8000       0xD8000
622          *
623          */
624
625         bd_maddr = 0;
626         i = (ee16_read_eeprom(sc, 6) & 0x00ff) >> 3;
627         switch (i) {
628         case 0x03:
629                 bd_maddr = 0xCC000;
630                 break;
631         case 0x06:
632                 bd_maddr = 0xD0000;
633                 break;
634         case 0x0c:
635                 bd_maddr = 0xD4000;
636                 break;
637         case 0x18:
638                 bd_maddr = 0xD8000;
639                 break;
640         default:
641                 bd_maddr = 0;
642                 break;
643         }
644         dvp->id_msize = 0x8000;
645         if (kvtop(dvp->id_maddr) != bd_maddr) {
646                 printf("ie%d: kernel configured maddr %llx "
647                        "doesn't match board configured maddr %lx\n",
648                        unit, kvtop(dvp->id_maddr), bd_maddr);
649         }
650         sc->iomembot = dvp->id_maddr;
651         sc->iomem = 0;          /* XXX some probes set this and some don't */
652         sc->iosize = dvp->id_msize;
653
654         /* need to put the 586 in RESET while we access the eeprom. */
655         outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
656
657         /* read the eeprom and checksum it, should == IEE16_ID */
658         for (i = 0; i < 0x40; i++)
659                 checksum += ee16_read_eeprom(sc, i);
660
661         if (checksum != IEE16_ID) {
662                 printf("ie%d: invalid eeprom checksum: %x\n", unit, checksum);
663                 return (0);
664         }
665         /*
666          * Size and test the memory on the board.  The size of the memory
667          * can be one of 16k, 32k, 48k or 64k.  It can be located in the
668          * address range 0xC0000 to 0xEFFFF on 16k boundaries.
669          *
670          * If the size does not match the passed in memory allocation size
671          * issue a warning, but continue with the minimum of the two sizes.
672          */
673
674         switch (dvp->id_msize) {
675         case 65536:
676         case 32768:             /* XXX Only support 32k and 64k right now */
677                 break;
678         case 16384:
679         case 49512:
680         default:
681                 printf("ie%d: mapped memory size %d not supported\n", unit,
682                        dvp->id_msize);
683                 return (0);
684                 break;          /* NOTREACHED */
685         }
686
687         if ((kvtop(dvp->id_maddr) < 0xC0000) ||
688             (kvtop(dvp->id_maddr) + sc->iosize > 0xF0000)) {
689                 printf("ie%d: mapped memory location %p out of range\n", unit,
690                        (void *)dvp->id_maddr);
691                 return (0);
692         }
693         pg = (kvtop(dvp->id_maddr) & 0x3C000) >> 14;
694         adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
695         decode = ((1 << (sc->iosize / 16384)) - 1) << pg;
696         edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
697
698         /* ZZZ This should be checked against eeprom location 6, low byte */
699         outb(PORT + IEE16_MEMDEC, decode & 0xFF);
700         /* ZZZ This should be checked against eeprom location 1, low byte */
701         outb(PORT + IEE16_MCTRL, adjust);
702         /* ZZZ Now if I could find this one I would have it made */
703         outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
704         /* ZZZ I think this is location 6, high byte */
705         outb(PORT + IEE16_MECTRL, edecode);     /* XXX disable Exxx */
706
707         (void) kvtop(dvp->id_maddr);
708
709         /*
710          * first prime the stupid bart DRAM controller so that it works,
711          * then zero out all of memory.
712          */
713         bzero(sc->iomembot, 32);
714         bzero(sc->iomembot, sc->iosize);
715
716         /*
717          * Get the encoded interrupt number from the EEPROM, check it
718          * against the passed in IRQ.  Issue a warning if they do not match.
719          * Always use the passed in IRQ, not the one in the EEPROM.
720          */
721         irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
722         irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
723         irq = irq_translate[irq];
724         if (dvp->id_irq > 0) {
725                 if (irq != dvp->id_irq) {
726                         printf("ie%d: WARNING: board configured "
727                                "at irq %u, using %u\n",
728                                dvp->id_unit, dvp->id_irq, irq);
729                         irq = dvp->id_unit;
730                 }
731         } else {
732                 dvp->id_irq = irq;
733         }
734         sc->irq_encoded = irq_encode[ffs(irq) - 1];
735
736         /*
737          * Get the hardware ethernet address from the EEPROM and save it in
738          * the softc for use by the 586 setup code.
739          */
740         eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
741         sc->arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
742         sc->arpcom.ac_enaddr[0] = eaddrtemp >> 8;
743         eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
744         sc->arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
745         sc->arpcom.ac_enaddr[2] = eaddrtemp >> 8;
746         eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
747         sc->arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
748         sc->arpcom.ac_enaddr[4] = eaddrtemp >> 8;
749
750         /* disable the board interrupts */
751         outb(PORT + IEE16_IRQ, sc->irq_encoded);
752
753         /* enable loopback to keep bad packets off the wire */
754         if (sc->hard_type == IE_EE16) {
755                 bart_config = inb(PORT + IEE16_CONFIG);
756                 bart_config |= IEE16_BART_LOOPBACK;
757                 bart_config |= IEE16_BART_MCS16_TEST;/* inb doesn't get bit! */
758                 outb(PORT + IEE16_CONFIG, bart_config);
759                 bart_config = inb(PORT + IEE16_CONFIG);
760         }
761         /* take the board out of reset state */
762         outb(PORT + IEE16_ECTRL, 0);
763         DELAY(100);
764
765         if (!check_ie_present(unit, dvp->id_maddr, sc->iosize))
766                 return (0);
767
768         return (16);            /* return the number of I/O ports */
769 }
770
771 /*
772  * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
773  */
774 int
775 ieattach(struct isa_device *dvp)
776 {
777         int     factor;
778         int     unit = dvp->id_unit;
779         struct ie_softc *ie = &ie_softc[unit];
780         struct ifnet *ifp = &ie->arpcom.ac_if;
781         size_t  allocsize;
782
783         dvp->id_ointr = ieintr;
784
785         /*
786          * based on the amount of memory we have, allocate our tx and rx
787          * resources.
788          */
789         factor = dvp->id_msize / 16384;
790         ie->nframes = factor * NFRAMES;
791         ie->nrxbufs = factor * NRXBUFS;
792         ie->ntxbufs = factor * NTXBUFS;
793
794         /*
795          * Since all of these guys are arrays of pointers, allocate as one
796          * big chunk and dole out accordingly.
797          */
798         allocsize = sizeof(void *) * (ie->nframes
799                                       + (ie->nrxbufs * 2)
800                                       + (ie->ntxbufs * 3));
801         ie->rframes = malloc(allocsize, M_DEVBUF, M_WAITOK);
802         ie->rbuffs =
803             (volatile struct ie_recv_buf_desc **)&ie->rframes[ie->nframes];
804         ie->cbuffs = (volatile u_char **)&ie->rbuffs[ie->nrxbufs];
805         ie->xmit_cmds =
806             (volatile struct ie_xmit_cmd **)&ie->cbuffs[ie->nrxbufs];
807         ie->xmit_buffs =
808             (volatile struct ie_xmit_buf **)&ie->xmit_cmds[ie->ntxbufs];
809         ie->xmit_cbuffs = (volatile u_char **)&ie->xmit_buffs[ie->ntxbufs];
810
811         ifp->if_softc = ie;
812         if_initname(ifp, iedriver.name, unit);
813         ifp->if_mtu = ETHERMTU;
814         printf("ie%d: <%s R%d> address %6D\n", unit,
815                ie_hardware_names[ie->hard_type],
816                ie->hard_vers + 1,
817                ie->arpcom.ac_enaddr, ":");
818
819         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
820         ifp->if_output = ether_output;
821         ifp->if_start = iestart;
822         ifp->if_ioctl = ieioctl;
823         ifp->if_init = ieinit;
824         ifp->if_type = IFT_ETHER;
825         ifp->if_addrlen = 6;
826         ifp->if_hdrlen = 14;
827         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
828
829         if (ie->hard_type == IE_EE16)
830                 EVENTHANDLER_REGISTER(shutdown_post_sync, ee16_shutdown,
831                                       ie, SHUTDOWN_PRI_DEFAULT);
832
833         ether_ifattach(ifp, ie->arpcom.ac_enaddr);
834         return (1);
835 }
836
837 /*
838  * What to do upon receipt of an interrupt.
839  */
840 static void
841 ieintr(int unit)
842 {
843         struct ie_softc *ie = &ie_softc[unit];
844         u_short status;
845
846         /* Clear the interrupt latch on the 3C507. */
847         if (ie->hard_type == IE_3C507
848          && (inb(PORT + IE507_CTRL) & EL_CTRL_INTL))
849                 outb(PORT + IE507_ICTRL, 1);
850
851         /* disable interrupts on the EE16. */
852         if (ie->hard_type == IE_EE16)
853                 outb(PORT + IEE16_IRQ, ie->irq_encoded);
854
855         status = ie->scb->ie_status;
856
857 loop:
858
859         /* Don't ack interrupts which we didn't receive */
860         ie_ack(ie->scb, IE_ST_WHENCE & status, unit, ie->ie_chan_attn);
861
862         if (status & (IE_ST_RECV | IE_ST_RNR)) {
863 #ifdef DEBUG
864                 in_ierint++;
865                 if (ie_debug & IED_RINT)
866                         printf("ie%d: rint\n", unit);
867 #endif
868                 ierint(unit, ie);
869 #ifdef DEBUG
870                 in_ierint--;
871 #endif
872         }
873         if (status & IE_ST_DONE) {
874 #ifdef DEBUG
875                 in_ietint++;
876                 if (ie_debug & IED_TINT)
877                         printf("ie%d: tint\n", unit);
878 #endif
879                 ietint(unit, ie);
880 #ifdef DEBUG
881                 in_ietint--;
882 #endif
883         }
884         if (status & IE_ST_RNR) {
885 #ifdef DEBUG
886                 if (ie_debug & IED_RNR)
887                         printf("ie%d: rnr\n", unit);
888 #endif
889                 iernr(unit, ie);
890         }
891 #ifdef DEBUG
892         if ((status & IE_ST_ALLDONE)
893             && (ie_debug & IED_CNA))
894                 printf("ie%d: cna\n", unit);
895 #endif
896
897         if ((status = ie->scb->ie_status) & IE_ST_WHENCE)
898                 goto loop;
899
900         /* Clear the interrupt latch on the 3C507. */
901         if (ie->hard_type == IE_3C507)
902                 outb(PORT + IE507_ICTRL, 1);
903
904         /* enable interrupts on the EE16. */
905         if (ie->hard_type == IE_EE16)
906                 outb(PORT + IEE16_IRQ, ie->irq_encoded | IEE16_IRQ_ENABLE);
907
908 }
909
910 /*
911  * Process a received-frame interrupt.
912  */
913 static int
914 ierint(int unit, struct ie_softc *ie)
915 {
916         int     i, status;
917         static int timesthru = 1024;
918
919         i = ie->rfhead;
920         while (1) {
921                 status = ie->rframes[i]->ie_fd_status;
922
923                 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
924                         ie->arpcom.ac_if.if_ipackets++;
925                         if (!--timesthru) {
926                                 ie->arpcom.ac_if.if_ierrors +=
927                                     ie->scb->ie_err_crc +
928                                     ie->scb->ie_err_align +
929                                     ie->scb->ie_err_resource +
930                                     ie->scb->ie_err_overrun;
931                                 ie->scb->ie_err_crc = 0;
932                                 ie->scb->ie_err_align = 0;
933                                 ie->scb->ie_err_resource = 0;
934                                 ie->scb->ie_err_overrun = 0;
935                                 timesthru = 1024;
936                         }
937                         ie_readframe(unit, ie, i);
938                 } else {
939                         if (status & IE_FD_RNR) {
940                                 if (!(ie->scb->ie_status & IE_RU_READY)) {
941                                         ie->rframes[0]->ie_fd_next =
942                                             MK_16(MEM, ie->rbuffs[0]);
943                                         ie->scb->ie_recv_list =
944                                             MK_16(MEM, ie->rframes[0]);
945                                         command_and_wait(unit, IE_RU_START,
946                                                          0, 0);
947                                 }
948                         }
949                         break;
950                 }
951                 i = (i + 1) % ie->nframes;
952         }
953         return (0);
954 }
955
956 /*
957  * Process a command-complete interrupt.  These are only generated by
958  * the transmission of frames.  This routine is deceptively simple, since
959  * most of the real work is done by iestart().
960  */
961 static int
962 ietint(int unit, struct ie_softc *ie)
963 {
964         int     status;
965         int     i;
966
967         ie->arpcom.ac_if.if_timer = 0;
968         ie->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
969
970         for (i = 0; i < ie->xmit_count; i++) {
971                 status = ie->xmit_cmds[i]->ie_xmit_status;
972
973                 if (status & IE_XS_LATECOLL) {
974                         printf("ie%d: late collision\n", unit);
975                         ie->arpcom.ac_if.if_collisions++;
976                         ie->arpcom.ac_if.if_oerrors++;
977                 } else if (status & IE_XS_NOCARRIER) {
978                         printf("ie%d: no carrier\n", unit);
979                         ie->arpcom.ac_if.if_oerrors++;
980                 } else if (status & IE_XS_LOSTCTS) {
981                         printf("ie%d: lost CTS\n", unit);
982                         ie->arpcom.ac_if.if_oerrors++;
983                 } else if (status & IE_XS_UNDERRUN) {
984                         printf("ie%d: DMA underrun\n", unit);
985                         ie->arpcom.ac_if.if_oerrors++;
986                 } else if (status & IE_XS_EXCMAX) {
987                         printf("ie%d: too many collisions\n", unit);
988                         ie->arpcom.ac_if.if_collisions += 16;
989                         ie->arpcom.ac_if.if_oerrors++;
990                 } else {
991                         ie->arpcom.ac_if.if_opackets++;
992                         ie->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL;
993                 }
994         }
995         ie->xmit_count = 0;
996
997         /*
998          * If multicast addresses were added or deleted while we were
999          * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
1000          * that we should do it.
1001          */
1002         if (ie->want_mcsetup) {
1003                 mc_setup(unit, (v_caddr_t) ie->xmit_cbuffs[0], ie->scb);
1004                 ie->want_mcsetup = 0;
1005         }
1006         /* Wish I knew why this seems to be necessary... */
1007         ie->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
1008
1009         iestart(&ie->arpcom.ac_if);
1010         return (0);             /* shouldn't be necessary */
1011 }
1012
1013 /*
1014  * Process a receiver-not-ready interrupt.  I believe that we get these
1015  * when there aren't enough buffers to go around.  For now (FIXME), we
1016  * just restart the receiver, and hope everything's ok.
1017  */
1018 static int
1019 iernr(int unit, struct ie_softc *ie)
1020 {
1021 #ifdef doesnt_work
1022         setup_rfa((v_caddr_t) ie->rframes[0], ie);
1023
1024         ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1025         command_and_wait(unit, IE_RU_START, 0, 0);
1026 #else
1027         /* This doesn't work either, but it doesn't hang either. */
1028         command_and_wait(unit, IE_RU_DISABLE, 0, 0);    /* just in case */
1029         setup_rfa((v_caddr_t) ie->rframes[0], ie);      /* ignore cast-qual */
1030
1031         ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1032         command_and_wait(unit, IE_RU_START, 0, 0);      /* was ENABLE */
1033
1034 #endif
1035         ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
1036
1037         ie->arpcom.ac_if.if_ierrors++;
1038         return (0);
1039 }
1040
1041 /*
1042  * Compare two Ether/802 addresses for equality, inlined and
1043  * unrolled for speed.  I'd love to have an inline assembler
1044  * version of this...
1045  */
1046 static __inline int
1047 ether_equal(u_char * one, u_char * two)
1048 {
1049         if (one[0] != two[0])
1050                 return (0);
1051         if (one[1] != two[1])
1052                 return (0);
1053         if (one[2] != two[2])
1054                 return (0);
1055         if (one[3] != two[3])
1056                 return (0);
1057         if (one[4] != two[4])
1058                 return (0);
1059         if (one[5] != two[5])
1060                 return (0);
1061         return 1;
1062 }
1063
1064 /*
1065  * Determine quickly whether we should bother reading in this packet.
1066  * This depends on whether BPF and/or bridging is enabled, whether we
1067  * are receiving multicast address, and whether promiscuous mode is enabled.
1068  * We assume that if IFF_PROMISC is set, then *somebody* wants to see
1069  * all incoming packets.
1070  */
1071 static __inline int
1072 check_eh(struct ie_softc *ie, struct ether_header *eh)
1073 {
1074         /* Optimize the common case: normal operation. We've received
1075            either a unicast with our dest or a multicast packet. */
1076         if (ie->promisc == 0) {
1077                 int i;
1078
1079                 /* If not multicast, it's definitely for us */
1080                 if ((eh->ether_dhost[0] & 1) == 0)
1081                         return (1);
1082
1083                 /* Accept broadcasts (loose but fast check) */
1084                 if (eh->ether_dhost[0] == 0xff)
1085                         return (1);
1086
1087                 /* Compare against our multicast addresses */
1088                 for (i = 0; i < ie->mcast_count; i++) {
1089                         if (ether_equal(eh->ether_dhost,
1090                             (u_char *)&ie->mcast_addrs[i]))
1091                                 return (1);
1092                 }
1093                 return (0);
1094         }
1095
1096         /* Always accept packets when in promiscuous mode */
1097         if ((ie->promisc & IFF_PROMISC) != 0)
1098                 return (1);
1099
1100         /* Always accept packets directed at us */
1101         if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1102                 return (1);
1103
1104         /* Must have IFF_ALLMULTI but not IFF_PROMISC set. The chip is
1105            actually in promiscuous mode, so discard unicast packets. */
1106         return((eh->ether_dhost[0] & 1) != 0);
1107 }
1108
1109 /*
1110  * We want to isolate the bits that have meaning...  This assumes that
1111  * IE_RBUF_SIZE is an even power of two.  If somehow the act_len exceeds
1112  * the size of the buffer, then we are screwed anyway.
1113  */
1114 static __inline int
1115 ie_buflen(struct ie_softc * ie, int head)
1116 {
1117         return (ie->rbuffs[head]->ie_rbd_actual
1118                 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
1119 }
1120
1121 static __inline int
1122 ie_packet_len(int unit, struct ie_softc * ie)
1123 {
1124         int     i;
1125         int     head = ie->rbhead;
1126         int     acc = 0;
1127
1128         do {
1129                 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1130 #ifdef DEBUG
1131                         print_rbd(ie->rbuffs[ie->rbhead]);
1132 #endif
1133                         log(LOG_ERR,
1134                             "ie%d: receive descriptors out of sync at %d\n",
1135                             unit, ie->rbhead);
1136                         iereset(unit);
1137                         return (-1);
1138                 }
1139                 i = ie->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
1140
1141                 acc += ie_buflen(ie, head);
1142                 head = (head + 1) % ie->nrxbufs;
1143         } while (!i);
1144
1145         return (acc);
1146 }
1147
1148 /*
1149  * Read data off the interface, and turn it into an mbuf chain.
1150  *
1151  * This code is DRAMATICALLY different from the previous version; this
1152  * version tries to allocate the entire mbuf chain up front, given the
1153  * length of the data available.  This enables us to allocate mbuf
1154  * clusters in many situations where before we would have had a long
1155  * chain of partially-full mbufs.  This should help to speed up the
1156  * operation considerably.  (Provided that it works, of course.)
1157  */
1158 static __inline int
1159 ieget(int unit, struct ie_softc *ie, struct mbuf **mp, struct ether_header *ehp)
1160 {
1161         struct  mbuf *m, *top, **mymp;
1162         int     i;
1163         int     offset;
1164         int     totlen, resid;
1165         int     thismboff;
1166         int     head;
1167
1168         totlen = ie_packet_len(unit, ie);
1169         if (totlen <= 0)
1170                 return (-1);
1171
1172         i = ie->rbhead;
1173
1174         /*
1175          * Snarf the Ethernet header.
1176          */
1177         bcopy((v_caddr_t) ie->cbuffs[i], (caddr_t) ehp, sizeof *ehp);
1178         /* ignore cast-qual warning here */
1179
1180         /*
1181          * As quickly as possible, check if this packet is for us. If not,
1182          * don't waste a single cycle copying the rest of the packet in.
1183          * This is only a consideration when FILTER is defined; i.e., when
1184          * we are either running BPF or doing multicasting.
1185          */
1186         if (!check_eh(ie, ehp)) {
1187                 ie_drop_packet_buffer(unit, ie);
1188                 ie->arpcom.ac_if.if_ierrors--;  /* just this case, it's not an
1189                                                  * error
1190                                                  */
1191                 return (-1);
1192         }
1193         totlen -= (offset = sizeof *ehp);
1194
1195         MGETHDR(*mp, MB_DONTWAIT, MT_DATA);
1196         if (!*mp) {
1197                 ie_drop_packet_buffer(unit, ie);
1198                 return (-1);
1199         }
1200         m = *mp;
1201         m->m_pkthdr.rcvif = &ie->arpcom.ac_if;
1202         m->m_len = MHLEN;
1203         resid = m->m_pkthdr.len = totlen;
1204         top = 0;
1205         mymp = &top;
1206
1207         /*
1208          * This loop goes through and allocates mbufs for all the data we
1209          * will be copying in.  It does not actually do the copying yet.
1210          */
1211         do {                    /* while(resid > 0) */
1212                 /*
1213                  * Try to allocate an mbuf to hold the data that we have.
1214                  * If we already allocated one, just get another one and
1215                  * stick it on the end (eventually).  If we don't already
1216                  * have one, try to allocate an mbuf cluster big enough to
1217                  * hold the whole packet, if we think it's reasonable, or a
1218                  * single mbuf which may or may not be big enough. Got that?
1219                  */
1220                 if (top) {
1221                         MGET(m, MB_DONTWAIT, MT_DATA);
1222                         if (!m) {
1223                                 m_freem(top);
1224                                 ie_drop_packet_buffer(unit, ie);
1225                                 return (-1);
1226                         }
1227                         m->m_len = MLEN;
1228                 }
1229                 if (resid >= MINCLSIZE) {
1230                         MCLGET(m, MB_DONTWAIT);
1231                         if (m->m_flags & M_EXT)
1232                                 m->m_len = min(resid, MCLBYTES);
1233                 } else {
1234                         if (resid < m->m_len) {
1235                                 if (!top && resid + max_linkhdr <= m->m_len)
1236                                         m->m_data += max_linkhdr;
1237                                 m->m_len = resid;
1238                         }
1239                 }
1240                 resid -= m->m_len;
1241                 *mymp = m;
1242                 mymp = &m->m_next;
1243         } while (resid > 0);
1244
1245         resid = totlen;
1246         m = top;
1247         thismboff = 0;
1248         head = ie->rbhead;
1249
1250         /*
1251          * Now we take the mbuf chain (hopefully only one mbuf most of the
1252          * time) and stuff the data into it.  There are no possible failures
1253          * at or after this point.
1254          */
1255         while (resid > 0) {     /* while there's stuff left */
1256                 int     thislen = ie_buflen(ie, head) - offset;
1257
1258                 /*
1259                  * If too much data for the current mbuf, then fill the
1260                  * current one up, go to the next one, and try again.
1261                  */
1262                 if (thislen > m->m_len - thismboff) {
1263                         int     newlen = m->m_len - thismboff;
1264
1265                         bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1266                               mtod(m, v_caddr_t) +thismboff, (unsigned) newlen);
1267                         /* ignore cast-qual warning */
1268                         m = m->m_next;
1269                         thismboff = 0;  /* new mbuf, so no offset */
1270                         offset += newlen;       /* we are now this far into
1271                                                  * the packet */
1272                         resid -= newlen;        /* so there is this much left
1273                                                  * to get */
1274                         continue;
1275                 }
1276                 /*
1277                  * If there is more than enough space in the mbuf to hold
1278                  * the contents of this buffer, copy everything in, advance
1279                  * pointers, and so on.
1280                  */
1281                 if (thislen < m->m_len - thismboff) {
1282                         bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1283                             mtod(m, caddr_t) +thismboff, (unsigned) thislen);
1284                         thismboff += thislen;   /* we are this far into the
1285                                                  * mbuf */
1286                         resid -= thislen;       /* and this much is left */
1287                         goto nextbuf;
1288                 }
1289                 /*
1290                  * Otherwise, there is exactly enough space to put this
1291                  * buffer's contents into the current mbuf.  Do the
1292                  * combination of the above actions.
1293                  */
1294                 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1295                       mtod(m, caddr_t) + thismboff, (unsigned) thislen);
1296                 m = m->m_next;
1297                 thismboff = 0;          /* new mbuf, start at the beginning */
1298                 resid -= thislen;       /* and we are this far through */
1299
1300                 /*
1301                  * Advance all the pointers.  We can get here from either of
1302                  * the last two cases, but never the first.
1303                  */
1304 nextbuf:
1305                 offset = 0;
1306                 ie->rbuffs[head]->ie_rbd_actual = 0;
1307                 ie->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
1308                 ie->rbhead = head = (head + 1) % ie->nrxbufs;
1309                 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1310                 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1311         }
1312
1313         /*
1314          * Unless something changed strangely while we were doing the copy,
1315          * we have now copied everything in from the shared memory. This
1316          * means that we are done.
1317          */
1318         return (0);
1319 }
1320
1321 /*
1322  * Read frame NUM from unit UNIT (pre-cached as IE).
1323  *
1324  * This routine reads the RFD at NUM, and copies in the buffers from
1325  * the list of RBD, then rotates the RBD and RFD lists so that the receiver
1326  * doesn't start complaining.  Trailers are DROPPED---there's no point
1327  * in wasting time on confusing code to deal with them.  Hopefully,
1328  * this machine will never ARP for trailers anyway.
1329  */
1330 static void
1331 ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
1332 {
1333         struct ie_recv_frame_desc rfd;
1334         struct mbuf *m = 0;
1335         struct ether_header eh;
1336
1337         bcopy((v_caddr_t) (ie->rframes[num]), &rfd,
1338               sizeof(struct ie_recv_frame_desc));
1339
1340         /*
1341          * Immediately advance the RFD list, since we we have copied ours
1342          * now.
1343          */
1344         ie->rframes[num]->ie_fd_status = 0;
1345         ie->rframes[num]->ie_fd_last |= IE_FD_LAST;
1346         ie->rframes[ie->rftail]->ie_fd_last &= ~IE_FD_LAST;
1347         ie->rftail = (ie->rftail + 1) % ie->nframes;
1348         ie->rfhead = (ie->rfhead + 1) % ie->nframes;
1349
1350         if (rfd.ie_fd_status & IE_FD_OK) {
1351                 if (ieget(unit, ie, &m, &eh)) {
1352                         ie->arpcom.ac_if.if_ierrors++;  /* this counts as an
1353                                                          * error */
1354                         return;
1355                 }
1356         }
1357 #ifdef DEBUG
1358         if (ie_debug & IED_READFRAME) {
1359                 printf("ie%d: frame from ether %6D type %x\n", unit,
1360                        eh.ether_shost, ":", (unsigned) eh.ether_type);
1361         }
1362         if (ntohs(eh.ether_type) > ETHERTYPE_TRAIL
1363             && ntohs(eh.ether_type) < (ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER))
1364                 printf("received trailer!\n");
1365 #endif
1366
1367         if (!m)
1368                 return;
1369
1370         /*
1371          * Finally pass this packet up to higher layers.
1372          */
1373         ether_input(&ie->arpcom.ac_if, &eh, m);
1374 }
1375
1376 static void
1377 ie_drop_packet_buffer(int unit, struct ie_softc * ie)
1378 {
1379         int     i;
1380
1381         do {
1382                 /*
1383                  * This means we are somehow out of sync.  So, we reset the
1384                  * adapter.
1385                  */
1386                 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1387 #ifdef DEBUG
1388                         print_rbd(ie->rbuffs[ie->rbhead]);
1389 #endif
1390                         log(LOG_ERR, "ie%d: receive descriptors out of sync at %d\n",
1391                             unit, ie->rbhead);
1392                         iereset(unit);
1393                         return;
1394                 }
1395                 i = ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1396
1397                 ie->rbuffs[ie->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1398                 ie->rbuffs[ie->rbhead]->ie_rbd_actual = 0;
1399                 ie->rbhead = (ie->rbhead + 1) % ie->nrxbufs;
1400                 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1401                 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1402         } while (!i);
1403 }
1404
1405
1406 /*
1407  * Start transmission on an interface.
1408  */
1409 static void
1410 iestart(struct ifnet *ifp)
1411 {
1412         struct   ie_softc *ie = ifp->if_softc;
1413         struct   mbuf *m0, *m;
1414         volatile unsigned char *buffer;
1415         u_short  len;
1416
1417         /*
1418          * This is not really volatile, in this routine, but it makes gcc
1419          * happy.
1420          */
1421         volatile u_short *bptr = &ie->scb->ie_command_list;
1422
1423         if (!(ifp->if_flags & IFF_RUNNING))
1424                 return;
1425         if (ifp->if_flags & IFF_OACTIVE)
1426                 return;
1427
1428         do {
1429                 IF_DEQUEUE(&ie->arpcom.ac_if.if_snd, m);
1430                 if (!m)
1431                         break;
1432
1433                 buffer = ie->xmit_cbuffs[ie->xmit_count];
1434                 len = 0;
1435
1436                 for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) {
1437                         bcopy(mtod(m, caddr_t), buffer, m->m_len);
1438                         buffer += m->m_len;
1439                         len += m->m_len;
1440                 }
1441
1442                 m_freem(m0);
1443                 len = max(len, ETHER_MIN_LEN);
1444
1445                 /*
1446                  * See if bpf is listening on this interface, let it see the
1447                  * packet before we commit it to the wire.
1448                  */
1449                 BPF_TAP(&ie->arpcom.ac_if,
1450                     __DEVOLATILE(u_char *, ie->xmit_cbuffs[ie->xmit_count]),
1451                     len);
1452
1453                 ie->xmit_buffs[ie->xmit_count]->ie_xmit_flags =
1454                     IE_XMIT_LAST|len;
1455                 ie->xmit_buffs[ie->xmit_count]->ie_xmit_next = 0xffff;
1456                 ie->xmit_buffs[ie->xmit_count]->ie_xmit_buf =
1457                     MK_24(ie->iomem, ie->xmit_cbuffs[ie->xmit_count]);
1458
1459                 ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT;
1460                 ie->xmit_cmds[ie->xmit_count]->ie_xmit_status = 0;
1461                 ie->xmit_cmds[ie->xmit_count]->ie_xmit_desc =
1462                     MK_16(ie->iomem, ie->xmit_buffs[ie->xmit_count]);
1463
1464                 *bptr = MK_16(ie->iomem, ie->xmit_cmds[ie->xmit_count]);
1465                 bptr = &ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_link;
1466                 ie->xmit_count++;
1467         } while (ie->xmit_count < ie->ntxbufs);
1468
1469         /*
1470          * If we queued up anything for transmission, send it.
1471          */
1472         if (ie->xmit_count) {
1473                 ie->xmit_cmds[ie->xmit_count - 1]->com.ie_cmd_cmd |=
1474                     IE_CMD_LAST | IE_CMD_INTR;
1475
1476                 /*
1477                  * By passing the command pointer as a null, we tell
1478                  * command_and_wait() to pretend that this isn't an action
1479                  * command.  I wish I understood what was happening here.
1480                  */
1481                 command_and_wait(ifp->if_dunit, IE_CU_START, 0, 0);
1482                 ifp->if_flags |= IFF_OACTIVE;
1483         }
1484         return;
1485 }
1486
1487 /*
1488  * Check to see if there's an 82586 out there.
1489  */
1490 static int
1491 check_ie_present(int unit, caddr_t where, unsigned size)
1492 {
1493         volatile struct ie_sys_conf_ptr *scp;
1494         volatile struct ie_int_sys_conf_ptr *iscp;
1495         volatile struct ie_sys_ctl_block *scb;
1496         u_long  realbase;
1497         int     s;
1498
1499         s = splimp();
1500
1501         realbase = (uintptr_t) where + size - (1 << 24);
1502
1503         scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t)
1504               (realbase + IE_SCP_ADDR);
1505         bzero((volatile char *) scp, sizeof *scp);
1506
1507         /*
1508          * First we put the ISCP at the bottom of memory; this tests to make
1509          * sure that our idea of the size of memory is the same as the
1510          * controller's. This is NOT where the ISCP will be in normal
1511          * operation.
1512          */
1513         iscp = (volatile struct ie_int_sys_conf_ptr *) where;
1514         bzero((volatile char *)iscp, sizeof *iscp);
1515
1516         scb = (volatile struct ie_sys_ctl_block *) where;
1517         bzero((volatile char *)scb, sizeof *scb);
1518
1519         scp->ie_bus_use = ie_softc[unit].bus_use;       /* 8-bit or 16-bit */
1520         scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1521             ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1522
1523         iscp->ie_busy = 1;
1524         iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1525
1526         (*ie_softc[unit].ie_reset_586) (unit);
1527         (*ie_softc[unit].ie_chan_attn) (unit);
1528
1529         DELAY(100);             /* wait a while... */
1530
1531         if (iscp->ie_busy) {
1532                 splx(s);
1533                 return (0);
1534         }
1535         /*
1536          * Now relocate the ISCP to its real home, and reset the controller
1537          * again.
1538          */
1539         iscp = (void *) Align((caddr_t) (uintptr_t)
1540                               (realbase + IE_SCP_ADDR -
1541                                sizeof(struct ie_int_sys_conf_ptr)));
1542         bzero((volatile char *) iscp, sizeof *iscp);    /* ignore cast-qual */
1543
1544         scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1545             ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1546
1547         iscp->ie_busy = 1;
1548         iscp->ie_scb_offset = MK_16(realbase, scb);
1549
1550         (*ie_softc[unit].ie_reset_586) (unit);
1551         (*ie_softc[unit].ie_chan_attn) (unit);
1552
1553         DELAY(100);
1554
1555         if (iscp->ie_busy) {
1556                 splx(s);
1557                 return (0);
1558         }
1559         ie_softc[unit].iosize = size;
1560         ie_softc[unit].iomem = (caddr_t) (uintptr_t) realbase;
1561
1562         ie_softc[unit].iscp = iscp;
1563         ie_softc[unit].scb = scb;
1564
1565         /*
1566          * Acknowledge any interrupts we may have caused...
1567          */
1568         ie_ack(scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1569         splx(s);
1570
1571         return (1);
1572 }
1573
1574 /*
1575  * Divine the memory size of ie board UNIT.
1576  * Better hope there's nothing important hiding just below the ie card...
1577  */
1578 static void
1579 find_ie_mem_size(int unit)
1580 {
1581         unsigned size;
1582
1583         ie_softc[unit].iosize = 0;
1584
1585         for (size = 65536; size >= 8192; size -= 8192) {
1586                 if (check_ie_present(unit, ie_softc[unit].iomembot, size)) {
1587                         return;
1588                 }
1589         }
1590
1591         return;
1592 }
1593
1594 void
1595 el_reset_586(int unit)
1596 {
1597         outb(PORT + IE507_CTRL, EL_CTRL_RESET);
1598         DELAY(100);
1599         outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
1600         DELAY(100);
1601 }
1602
1603 void
1604 sl_reset_586(int unit)
1605 {
1606         outb(PORT + IEATT_RESET, 0);
1607 }
1608
1609 void
1610 ee16_reset_586(int unit)
1611 {
1612         outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
1613         DELAY(100);
1614         outb(PORT + IEE16_ECTRL, 0);
1615         DELAY(100);
1616 }
1617
1618 void
1619 el_chan_attn(int unit)
1620 {
1621         outb(PORT + IE507_ATTN, 1);
1622 }
1623
1624 void
1625 sl_chan_attn(int unit)
1626 {
1627         outb(PORT + IEATT_ATTN, 0);
1628 }
1629
1630 void
1631 ee16_chan_attn(int unit)
1632 {
1633         outb(PORT + IEE16_ATTN, 0);
1634 }
1635
1636 u_short
1637 ee16_read_eeprom(struct ie_softc *sc, int location)
1638 {
1639         int     ectrl, edata;
1640
1641         ectrl = inb(sc->port + IEE16_ECTRL);
1642         ectrl &= IEE16_ECTRL_MASK;
1643         ectrl |= IEE16_ECTRL_EECS;
1644         outb(sc->port + IEE16_ECTRL, ectrl);
1645
1646         ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
1647         ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
1648         edata = ee16_eeprom_inbits(sc);
1649         ectrl = inb(sc->port + IEE16_ECTRL);
1650         ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
1651         outb(sc->port + IEE16_ECTRL, ectrl);
1652         ee16_eeprom_clock(sc, 1);
1653         ee16_eeprom_clock(sc, 0);
1654         return edata;
1655 }
1656
1657 void
1658 ee16_eeprom_outbits(struct ie_softc *sc, int edata, int count)
1659 {
1660         int     ectrl, i;
1661
1662         ectrl = inb(sc->port + IEE16_ECTRL);
1663         ectrl &= ~IEE16_RESET_ASIC;
1664         for (i = count - 1; i >= 0; i--) {
1665                 ectrl &= ~IEE16_ECTRL_EEDI;
1666                 if (edata & (1 << i)) {
1667                         ectrl |= IEE16_ECTRL_EEDI;
1668                 }
1669                 outb(sc->port + IEE16_ECTRL, ectrl);
1670                 DELAY(1);       /* eeprom data must be setup for 0.4 uSec */
1671                 ee16_eeprom_clock(sc, 1);
1672                 ee16_eeprom_clock(sc, 0);
1673         }
1674         ectrl &= ~IEE16_ECTRL_EEDI;
1675         outb(sc->port + IEE16_ECTRL, ectrl);
1676         DELAY(1);               /* eeprom data must be held for 0.4 uSec */
1677 }
1678
1679 int
1680 ee16_eeprom_inbits(struct ie_softc *sc)
1681 {
1682         int     ectrl, edata, i;
1683
1684         ectrl = inb(sc->port + IEE16_ECTRL);
1685         ectrl &= ~IEE16_RESET_ASIC;
1686         for (edata = 0, i = 0; i < 16; i++) {
1687                 edata = edata << 1;
1688                 ee16_eeprom_clock(sc, 1);
1689                 ectrl = inb(sc->port + IEE16_ECTRL);
1690                 if (ectrl & IEE16_ECTRL_EEDO) {
1691                         edata |= 1;
1692                 }
1693                 ee16_eeprom_clock(sc, 0);
1694         }
1695         return (edata);
1696 }
1697
1698 void
1699 ee16_eeprom_clock(struct ie_softc *sc, int state)
1700 {
1701         int     ectrl;
1702
1703         ectrl = inb(sc->port + IEE16_ECTRL);
1704         ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
1705         if (state) {
1706                 ectrl |= IEE16_ECTRL_EESK;
1707         }
1708         outb(sc->port + IEE16_ECTRL, ectrl);
1709         DELAY(9);               /* EESK must be stable for 8.38 uSec */
1710 }
1711
1712 static __inline void
1713 ee16_interrupt_enable(struct ie_softc *sc)
1714 {
1715         DELAY(100);
1716         outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1717         DELAY(100);
1718 }
1719
1720 void
1721 sl_read_ether(int unit, unsigned char addr[6])
1722 {
1723         int     i;
1724
1725         for (i = 0; i < 6; i++)
1726                 addr[i] = inb(PORT + i);
1727 }
1728
1729
1730 static void
1731 iereset(int unit)
1732 {
1733         int     s = splimp();
1734
1735         if (unit >= NIE) {
1736                 splx(s);
1737                 return;
1738         }
1739         printf("ie%d: reset\n", unit);
1740         ie_softc[unit].arpcom.ac_if.if_flags &= ~IFF_UP;
1741         ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, (struct ucred *)NULL);
1742
1743         /*
1744          * Stop i82586 dead in its tracks.
1745          */
1746         if (command_and_wait(unit, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1747                 printf("ie%d: abort commands timed out\n", unit);
1748
1749         if (command_and_wait(unit, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1750                 printf("ie%d: disable commands timed out\n", unit);
1751
1752 #ifdef notdef
1753         if (!check_ie_present(unit, ie_softc[unit].iomembot,
1754                               e_softc[unit].iosize))
1755                 panic("ie disappeared!");
1756 #endif
1757
1758         ie_softc[unit].arpcom.ac_if.if_flags |= IFF_UP;
1759         ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, (struct ucred *)NULL);
1760
1761         splx(s);
1762         return;
1763 }
1764
1765 /*
1766  * This is called if we time out.
1767  */
1768 static void
1769 chan_attn_timeout(void *rock)
1770 {
1771         *(int *) rock = 1;
1772 }
1773
1774 /*
1775  * Send a command to the controller and wait for it to either
1776  * complete or be accepted, depending on the command.  If the
1777  * command pointer is null, then pretend that the command is
1778  * not an action command.  If the command pointer is not null,
1779  * and the command is an action command, wait for
1780  * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1781  * to become true.
1782  */
1783 static int
1784 command_and_wait(int unit, int cmd, volatile void *pcmd, int mask)
1785 {
1786         volatile struct ie_cmd_common *cc = pcmd;
1787         volatile int timedout = 0;
1788         struct   callout_handle ch;
1789
1790         ie_softc[unit].scb->ie_command = (u_short) cmd;
1791
1792         if (IE_ACTION_COMMAND(cmd) && pcmd) {
1793                 (*ie_softc[unit].ie_chan_attn) (unit);
1794
1795                 /*
1796                  * According to the packet driver, the minimum timeout
1797                  * should be .369 seconds, which we round up to .37.
1798                  */
1799                 ch = timeout(chan_attn_timeout, __DEVOLATILE(int *, &timedout),
1800                              37 * hz / 100);
1801                 /* ignore cast-qual */
1802
1803                 /*
1804                  * Now spin-lock waiting for status.  This is not a very
1805                  * nice thing to do, but I haven't figured out how, or
1806                  * indeed if, we can put the process waiting for action to
1807                  * sleep.  (We may be getting called through some other
1808                  * timeout running in the kernel.)
1809                  */
1810                 while (1) {
1811                         if ((cc->ie_cmd_status & mask) || timedout)
1812                                 break;
1813                 }
1814
1815                 untimeout(chan_attn_timeout, __DEVOLATILE(int *, &timedout), ch);
1816                 /* ignore cast-qual */
1817
1818                 return (timedout);
1819         } else {
1820
1821                 /*
1822                  * Otherwise, just wait for the command to be accepted.
1823                  */
1824                 (*ie_softc[unit].ie_chan_attn) (unit);
1825
1826                 while (ie_softc[unit].scb->ie_command); /* spin lock */
1827
1828                 return (0);
1829         }
1830 }
1831
1832 /*
1833  * Run the time-domain reflectometer...
1834  */
1835 static void
1836 run_tdr(int unit, volatile struct ie_tdr_cmd *cmd)
1837 {
1838         int     result;
1839
1840         cmd->com.ie_cmd_status = 0;
1841         cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1842         cmd->com.ie_cmd_link = 0xffff;
1843         cmd->ie_tdr_time = 0;
1844
1845         ie_softc[unit].scb->ie_command_list = MK_16(MEM, cmd);
1846         cmd->ie_tdr_time = 0;
1847
1848         if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL))
1849                 result = 0x2000;
1850         else
1851                 result = cmd->ie_tdr_time;
1852
1853         ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit,
1854                ie_softc[unit].ie_chan_attn);
1855
1856         if (result & IE_TDR_SUCCESS)
1857                 return;
1858
1859         if (result & IE_TDR_XCVR) {
1860                 printf("ie%d: transceiver problem\n", unit);
1861         } else if (result & IE_TDR_OPEN) {
1862                 printf("ie%d: TDR detected an open %d clocks away\n", unit,
1863                        result & IE_TDR_TIME);
1864         } else if (result & IE_TDR_SHORT) {
1865                 printf("ie%d: TDR detected a short %d clocks away\n", unit,
1866                        result & IE_TDR_TIME);
1867         } else {
1868                 printf("ie%d: TDR returned unknown status %x\n", unit, result);
1869         }
1870 }
1871
1872 static void
1873 start_receiver(int unit)
1874 {
1875         int     s = splimp();
1876
1877         ie_softc[unit].scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1878         command_and_wait(unit, IE_RU_START, 0, 0);
1879
1880         ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1881
1882         splx(s);
1883 }
1884
1885 /*
1886  * Here is a helper routine for iernr() and ieinit().  This sets up
1887  * the RFA.
1888  */
1889 static v_caddr_t
1890 setup_rfa(v_caddr_t ptr, struct ie_softc * ie)
1891 {
1892         volatile struct ie_recv_frame_desc *rfd = (volatile void *)ptr;
1893         volatile struct ie_recv_buf_desc *rbd;
1894         int     i;
1895         int     unit = ie - &ie_softc[0];
1896
1897         /* First lay them out */
1898         for (i = 0; i < ie->nframes; i++) {
1899                 ie->rframes[i] = rfd;
1900                 bzero((volatile char *) rfd, sizeof *rfd);      /* ignore cast-qual */
1901                 rfd++;
1902         }
1903
1904         ptr = Alignvol(rfd);            /* ignore cast-qual */
1905
1906         /* Now link them together */
1907         for (i = 0; i < ie->nframes; i++) {
1908                 ie->rframes[i]->ie_fd_next =
1909                     MK_16(MEM, ie->rframes[(i + 1) % ie->nframes]);
1910         }
1911
1912         /* Finally, set the EOL bit on the last one. */
1913         ie->rframes[ie->nframes - 1]->ie_fd_last |= IE_FD_LAST;
1914
1915         /*
1916          * Now lay out some buffers for the incoming frames.  Note that we
1917          * set aside a bit of slop in each buffer, to make sure that we have
1918          * enough space to hold a single frame in every buffer.
1919          */
1920         rbd = (volatile void *) ptr;
1921
1922         for (i = 0; i < ie->nrxbufs; i++) {
1923                 ie->rbuffs[i] = rbd;
1924                 bzero((volatile char *)rbd, sizeof *rbd);
1925                 ptr = Alignvol(ptr + sizeof *rbd);
1926                 rbd->ie_rbd_length = IE_RBUF_SIZE;
1927                 rbd->ie_rbd_buffer = MK_24(MEM, ptr);
1928                 ie->cbuffs[i] = (volatile void *) ptr;
1929                 ptr += IE_RBUF_SIZE;
1930                 rbd = (volatile void *) ptr;
1931         }
1932
1933         /* Now link them together */
1934         for (i = 0; i < ie->nrxbufs; i++) {
1935                 ie->rbuffs[i]->ie_rbd_next =
1936                     MK_16(MEM, ie->rbuffs[(i + 1) % ie->nrxbufs]);
1937         }
1938
1939         /* Tag EOF on the last one */
1940         ie->rbuffs[ie->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST;
1941
1942         /*
1943          * We use the head and tail pointers on receive to keep track of the
1944          * order in which RFDs and RBDs are used.
1945          */
1946         ie->rfhead = 0;
1947         ie->rftail = ie->nframes - 1;
1948         ie->rbhead = 0;
1949         ie->rbtail = ie->nrxbufs - 1;
1950
1951         ie->scb->ie_recv_list = MK_16(MEM, ie->rframes[0]);
1952         ie->rframes[0]->ie_fd_buf_desc = MK_16(MEM, ie->rbuffs[0]);
1953
1954         ptr = Alignvol(ptr);
1955         return (ptr);
1956 }
1957
1958 /*
1959  * Run the multicast setup command.
1960  * Call at splimp().
1961  */
1962 static int
1963 mc_setup(int unit, v_caddr_t ptr,
1964          volatile struct ie_sys_ctl_block * scb)
1965 {
1966         struct ie_softc *ie = &ie_softc[unit];
1967         volatile struct ie_mcast_cmd *cmd = (volatile void *) ptr;
1968
1969         cmd->com.ie_cmd_status = 0;
1970         cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1971         cmd->com.ie_cmd_link = 0xffff;
1972
1973         /* ignore cast-qual */
1974         bcopy((v_caddr_t) ie->mcast_addrs, (v_caddr_t) cmd->ie_mcast_addrs,
1975               ie->mcast_count * sizeof *ie->mcast_addrs);
1976
1977         cmd->ie_mcast_bytes = ie->mcast_count * 6;      /* grrr... */
1978
1979         scb->ie_command_list = MK_16(MEM, cmd);
1980         if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
1981             || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1982                 printf("ie%d: multicast address setup command failed\n", unit);
1983                 return (0);
1984         }
1985         return (1);
1986 }
1987
1988 /*
1989  * This routine takes the environment generated by check_ie_present()
1990  * and adds to it all the other structures we need to operate the adapter.
1991  * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1992  * starting the receiver unit, and clearing interrupts.
1993  *
1994  * THIS ROUTINE MUST BE CALLED AT splimp() OR HIGHER.
1995  */
1996 static void
1997 ieinit(xsc)
1998         void *xsc;
1999 {
2000         struct ie_softc *ie = xsc;
2001         volatile struct ie_sys_ctl_block *scb = ie->scb;
2002         v_caddr_t ptr;
2003         int     i;
2004         int     unit = ie->unit;
2005
2006         ptr = Alignvol((volatile char *) scb + sizeof *scb);
2007
2008         /*
2009          * Send the configure command first.
2010          */
2011         {
2012                 volatile struct ie_config_cmd *cmd = (volatile void *) ptr;
2013
2014                 ie_setup_config(cmd, ie->promisc,
2015                                 ie->hard_type == IE_STARLAN10);
2016                 cmd->com.ie_cmd_status = 0;
2017                 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
2018                 cmd->com.ie_cmd_link = 0xffff;
2019
2020                 scb->ie_command_list = MK_16(MEM, cmd);
2021
2022                 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2023                  || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2024                         printf("ie%d: configure command failed\n", unit);
2025                         return;
2026                 }
2027         }
2028         /*
2029          * Now send the Individual Address Setup command.
2030          */
2031         {
2032                 volatile struct ie_iasetup_cmd *cmd = (volatile void *) ptr;
2033
2034                 cmd->com.ie_cmd_status = 0;
2035                 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
2036                 cmd->com.ie_cmd_link = 0xffff;
2037
2038                 bcopy((volatile char *)ie_softc[unit].arpcom.ac_enaddr,
2039                       (volatile char *)&cmd->ie_address, sizeof cmd->ie_address);
2040                 scb->ie_command_list = MK_16(MEM, cmd);
2041                 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2042                     || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2043                         printf("ie%d: individual address "
2044                                "setup command failed\n", unit);
2045                         return;
2046                 }
2047         }
2048
2049         /*
2050          * Now run the time-domain reflectometer.
2051          */
2052         run_tdr(unit, (volatile void *) ptr);
2053
2054         /*
2055          * Acknowledge any interrupts we have generated thus far.
2056          */
2057         ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
2058
2059         /*
2060          * Set up the RFA.
2061          */
2062         ptr = setup_rfa(ptr, ie);
2063
2064         /*
2065          * Finally, the transmit command and buffer are the last little bit
2066          * of work.
2067          */
2068
2069         /* transmit command buffers */
2070         for (i = 0; i < ie->ntxbufs; i++) {
2071                 ie->xmit_cmds[i] = (volatile void *) ptr;
2072                 ptr += sizeof *ie->xmit_cmds[i];
2073                 ptr = Alignvol(ptr);
2074                 ie->xmit_buffs[i] = (volatile void *)ptr;
2075                 ptr += sizeof *ie->xmit_buffs[i];
2076                 ptr = Alignvol(ptr);
2077         }
2078
2079         /* transmit buffers */
2080         for (i = 0; i < ie->ntxbufs - 1; i++) {
2081                 ie->xmit_cbuffs[i] = (volatile void *)ptr;
2082                 ptr += IE_BUF_LEN;
2083                 ptr = Alignvol(ptr);
2084         }
2085         ie->xmit_cbuffs[ie->ntxbufs - 1] = (volatile void *) ptr;
2086
2087         for (i = 1; i < ie->ntxbufs; i++) {
2088                 bzero((v_caddr_t) ie->xmit_cmds[i], sizeof *ie->xmit_cmds[i]);
2089                 bzero((v_caddr_t) ie->xmit_buffs[i], sizeof *ie->xmit_buffs[i]);
2090         }
2091
2092         /*
2093          * This must be coordinated with iestart() and ietint().
2094          */
2095         ie->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
2096
2097         /* take the ee16 out of loopback */
2098         if (ie->hard_type == IE_EE16) {
2099                 u_int8_t bart_config;
2100
2101                 bart_config = inb(PORT + IEE16_CONFIG);
2102                 bart_config &= ~IEE16_BART_LOOPBACK;
2103                 /* inb doesn't get bit! */
2104                 bart_config |= IEE16_BART_MCS16_TEST;
2105                 outb(PORT + IEE16_CONFIG, bart_config);
2106                 ee16_interrupt_enable(ie);
2107                 ee16_chan_attn(unit);
2108         }
2109         ie->arpcom.ac_if.if_flags |= IFF_RUNNING;       /* tell higher levels
2110                                                          * we're here */
2111         start_receiver(unit);
2112
2113         return;
2114 }
2115
2116 static void
2117 ie_stop(int unit)
2118 {
2119         command_and_wait(unit, IE_RU_DISABLE, 0, 0);
2120 }
2121
2122 static int
2123 ieioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
2124 {
2125         int     s, error = 0;
2126
2127         s = splimp();
2128
2129         switch (command) {
2130         case SIOCSIFADDR:
2131         case SIOCGIFADDR:
2132         case SIOCSIFMTU:
2133                 error = ether_ioctl(ifp, command, data);
2134                 break;
2135
2136         case SIOCSIFFLAGS:
2137                 /*
2138                  * Note that this device doesn't have an "all multicast"
2139                  * mode, so we must turn on promiscuous mode and do the
2140                  * filtering manually.
2141                  */
2142                 if ((ifp->if_flags & IFF_UP) == 0 &&
2143                     (ifp->if_flags & IFF_RUNNING)) {
2144                         ifp->if_flags &= ~IFF_RUNNING;
2145                         ie_stop(ifp->if_dunit);
2146                 } else if ((ifp->if_flags & IFF_UP) &&
2147                            (ifp->if_flags & IFF_RUNNING) == 0) {
2148                         ie_softc[ifp->if_dunit].promisc =
2149                             ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2150                         ieinit(ifp->if_softc);
2151                 } else if (ie_softc[ifp->if_dunit].promisc ^
2152                            (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) {
2153                         ie_softc[ifp->if_dunit].promisc =
2154                             ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2155                         ieinit(ifp->if_softc);
2156                 }
2157                 break;
2158
2159         case SIOCADDMULTI:
2160         case SIOCDELMULTI:
2161                 /*
2162                  * Update multicast listeners
2163                  */
2164                 /* reset multicast filtering */
2165                 ie_mc_reset(ifp->if_dunit);
2166                 error = 0;
2167                 break;
2168
2169         default:
2170                 error = EINVAL;
2171         }
2172
2173         splx(s);
2174         return (error);
2175 }
2176
2177 static void
2178 ie_mc_reset(int unit)
2179 {
2180         struct ie_softc *ie = &ie_softc[unit];
2181         struct ifmultiaddr *ifma;
2182
2183         /*
2184          * Step through the list of addresses.
2185          */
2186         ie->mcast_count = 0;
2187         for (ifma = ie->arpcom.ac_if.if_multiaddrs.lh_first; ifma;
2188              ifma = ifma->ifma_link.le_next) {
2189                 if (ifma->ifma_addr->sa_family != AF_LINK)
2190                         continue;
2191
2192                 /* XXX - this is broken... */
2193                 if (ie->mcast_count >= MAXMCAST) {
2194                         ie->arpcom.ac_if.if_flags |= IFF_ALLMULTI;
2195                         ieioctl(&ie->arpcom.ac_if, SIOCSIFFLAGS, (void *) 0,
2196                                 (struct ucred *)NULL);
2197                         goto setflag;
2198                 }
2199                 bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
2200                       &(ie->mcast_addrs[ie->mcast_count]), 6);
2201                 ie->mcast_count++;
2202         }
2203
2204 setflag:
2205         ie->want_mcsetup = 1;
2206 }
2207
2208
2209 #ifdef DEBUG
2210 static void
2211 print_rbd(volatile struct ie_recv_buf_desc * rbd)
2212 {
2213         printf("RBD at %p:\n"
2214                "actual %04x, next %04x, buffer %p\n"
2215                "length %04x, mbz %04x\n",
2216                (volatile void *) rbd,
2217                rbd->ie_rbd_actual, rbd->ie_rbd_next,
2218                (void *) rbd->ie_rbd_buffer,
2219                rbd->ie_rbd_length, rbd->mbz);
2220 }
2221
2222 #endif                          /* DEBUG */