67e013e43e9b790310505fee12adf4ddb0a1f389
[games.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.34 2008/08/02 01:14:42 dillon 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 #include <sys/thread2.h>
125
126 #include <net/ethernet.h>
127 #include <net/if.h>
128 #include <net/ifq_var.h>
129 #include <net/if_types.h>
130 #include <net/if_dl.h>
131
132 #include <netinet/in.h>
133 #include <netinet/if_ether.h>
134
135 #include <machine/clock.h>
136 #include <machine/md_var.h>
137
138 #include <bus/isa/isa_device.h>
139 #include <machine_base/isa/ic/i82586.h>
140 #include <machine_base/icu/icu.h>
141 #include "if_iereg.h"
142 #include "if_ie507.h"
143 #include "if_iee16.h"
144 #include "../elink_layer/elink.h"
145
146 #include <net/bpf.h>
147
148 #ifdef DEBUG
149 #define IED_RINT        0x01
150 #define IED_TINT        0x02
151 #define IED_RNR         0x04
152 #define IED_CNA         0x08
153 #define IED_READFRAME   0x10
154 static int      ie_debug = IED_RNR;
155
156 #endif
157
158 DECLARE_DUMMY_MODULE(if_ie);
159
160 #define IE_BUF_LEN      ETHER_MAX_LEN   /* length of transmit buffer */
161
162 /* Forward declaration */
163 struct ie_softc;
164
165 static int      ieprobe(struct isa_device * dvp);
166 static int      ieattach(struct isa_device * dvp);
167 static void     ieintr(void *);
168 static int      sl_probe(struct isa_device * dvp);
169 static int      el_probe(struct isa_device * dvp);
170 static int      ni_probe(struct isa_device * dvp);
171 static int      ee16_probe(struct isa_device * dvp);
172
173 static int      check_ie_present(int unit, caddr_t where, unsigned size);
174 static void     ieinit(void *);
175 static void     ie_stop(int unit);
176 static int      ieioctl(struct ifnet * ifp, u_long command, caddr_t data,
177                         struct ucred *);
178 static void     iestart(struct ifnet * ifp);
179
180 static void     el_reset_586(int unit);
181 static void     el_chan_attn(int unit);
182
183 static void     sl_reset_586(int unit);
184 static void     sl_chan_attn(int unit);
185
186 static void     ee16_reset_586(int unit);
187 static void     ee16_chan_attn(int unit);
188 static __inline void ee16_interrupt_enable(struct ie_softc * ie);
189 static void     ee16_eeprom_outbits(struct ie_softc * ie, int edata, int cnt);
190 static void     ee16_eeprom_clock(struct ie_softc * ie, int state);
191 static u_short  ee16_read_eeprom(struct ie_softc * ie, int location);
192 static int      ee16_eeprom_inbits(struct ie_softc * ie);
193 static void     ee16_shutdown(void *sc, int howto);
194
195 static void     iereset(int unit);
196 static void     ie_readframe(int unit, struct ie_softc * ie, int bufno);
197 static void     ie_drop_packet_buffer(int unit, struct ie_softc * ie);
198 static void     sl_read_ether(int unit, unsigned char addr[6]);
199 static void     find_ie_mem_size(int unit);
200 static int      command_and_wait(int unit, int command,
201                                  void volatile * pcmd, int);
202 static void     run_tdr(int unit, volatile struct ie_tdr_cmd * cmd);
203 static int      ierint(int unit, struct ie_softc * ie);
204 static int      ietint(int unit, struct ie_softc * ie);
205 static int      iernr(int unit, struct ie_softc * ie);
206 static void     start_receiver(int unit);
207 static __inline int ieget(int, struct ie_softc *, struct mbuf **);
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                         kprintf("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                 kprintf("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                 kprintf("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                 kprintf("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                 kprintf("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                 kprintf("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                 kprintf("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, 1 << ICU_IRQ9, 1 << ICU_IRQ3, 
578                                    1 << ICU_IRQ4, 1 << ICU_IRQ5, 
579                                    1 << ICU_IRQ10, 1 << ICU_IRQ11, 0};
580         char    irq_encode[] = {0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0};
581
582         /* Need this for part of the probe. */
583         sc->ie_reset_586 = ee16_reset_586;
584         sc->ie_chan_attn = ee16_chan_attn;
585
586         /* unsure if this is necessary */
587         sc->bus_use = 0;
588
589         /* reset any ee16 at the current iobase */
590         outb(dvp->id_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
591         outb(dvp->id_iobase + IEE16_ECTRL, 0);
592         DELAY(240);
593
594         /* now look for ee16. */
595         board_id = id_var1 = id_var2 = 0;
596         for (i = 0; i < 4; i++) {
597                 id_var1 = inb(dvp->id_iobase + IEE16_ID_PORT);
598                 id_var2 = ((id_var1 & 0x03) << 2);
599                 board_id |= ((id_var1 >> 4) << id_var2);
600         }
601
602         if (board_id != IEE16_ID) {
603                 if (bootverbose)
604                         kprintf("ie%d: unknown board_id: %x\n", unit, board_id);
605                 return (0);
606         }
607         /* need sc->port for ee16_read_eeprom */
608         sc->port = dvp->id_iobase;
609         sc->hard_type = IE_EE16;
610
611         /*
612          * The shared RAM location on the EE16 is encoded into bits 3-7 of
613          * EEPROM location 6.  We zero the upper byte, and shift the 5 bits
614          * right 3.  The resulting number tells us the RAM location.
615          * Because the EE16 supports either 16k or 32k of shared RAM, we
616          * only worry about the 32k locations.
617          *
618          * NOTE: if a 64k EE16 exists, it should be added to this switch. then
619          * the ia->ia_msize would need to be set per case statement.
620          *
621          * value        msize   location =====  =====   ======== 0x03   0x8000
622          * 0xCC000 0x06 0x8000  0xD0000 0x0C    0x8000  0xD4000 0x18
623          * 0x8000       0xD8000
624          *
625          */
626
627         bd_maddr = 0;
628         i = (ee16_read_eeprom(sc, 6) & 0x00ff) >> 3;
629         switch (i) {
630         case 0x03:
631                 bd_maddr = 0xCC000;
632                 break;
633         case 0x06:
634                 bd_maddr = 0xD0000;
635                 break;
636         case 0x0c:
637                 bd_maddr = 0xD4000;
638                 break;
639         case 0x18:
640                 bd_maddr = 0xD8000;
641                 break;
642         default:
643                 bd_maddr = 0;
644                 break;
645         }
646         dvp->id_msize = 0x8000;
647         if (kvtop(dvp->id_maddr) != bd_maddr) {
648                 kprintf("ie%d: kernel configured maddr %llx "
649                        "doesn't match board configured maddr %lx\n",
650                        unit, kvtop(dvp->id_maddr), bd_maddr);
651         }
652         sc->iomembot = dvp->id_maddr;
653         sc->iomem = 0;          /* XXX some probes set this and some don't */
654         sc->iosize = dvp->id_msize;
655
656         /* need to put the 586 in RESET while we access the eeprom. */
657         outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
658
659         /* read the eeprom and checksum it, should == IEE16_ID */
660         for (i = 0; i < 0x40; i++)
661                 checksum += ee16_read_eeprom(sc, i);
662
663         if (checksum != IEE16_ID) {
664                 kprintf("ie%d: invalid eeprom checksum: %x\n", unit, checksum);
665                 return (0);
666         }
667         /*
668          * Size and test the memory on the board.  The size of the memory
669          * can be one of 16k, 32k, 48k or 64k.  It can be located in the
670          * address range 0xC0000 to 0xEFFFF on 16k boundaries.
671          *
672          * If the size does not match the passed in memory allocation size
673          * issue a warning, but continue with the minimum of the two sizes.
674          */
675
676         switch (dvp->id_msize) {
677         case 65536:
678         case 32768:             /* XXX Only support 32k and 64k right now */
679                 break;
680         case 16384:
681         case 49512:
682         default:
683                 kprintf("ie%d: mapped memory size %d not supported\n", unit,
684                        dvp->id_msize);
685                 return (0);
686                 break;          /* NOTREACHED */
687         }
688
689         if ((kvtop(dvp->id_maddr) < 0xC0000) ||
690             (kvtop(dvp->id_maddr) + sc->iosize > 0xF0000)) {
691                 kprintf("ie%d: mapped memory location %p out of range\n", unit,
692                        (void *)dvp->id_maddr);
693                 return (0);
694         }
695         pg = (kvtop(dvp->id_maddr) & 0x3C000) >> 14;
696         adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
697         decode = ((1 << (sc->iosize / 16384)) - 1) << pg;
698         edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
699
700         /* ZZZ This should be checked against eeprom location 6, low byte */
701         outb(PORT + IEE16_MEMDEC, decode & 0xFF);
702         /* ZZZ This should be checked against eeprom location 1, low byte */
703         outb(PORT + IEE16_MCTRL, adjust);
704         /* ZZZ Now if I could find this one I would have it made */
705         outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
706         /* ZZZ I think this is location 6, high byte */
707         outb(PORT + IEE16_MECTRL, edecode);     /* XXX disable Exxx */
708
709         kvtop(dvp->id_maddr);
710
711         /*
712          * first prime the stupid bart DRAM controller so that it works,
713          * then zero out all of memory.
714          */
715         bzero(sc->iomembot, 32);
716         bzero(sc->iomembot, sc->iosize);
717
718         /*
719          * Get the encoded interrupt number from the EEPROM, check it
720          * against the passed in IRQ.  Issue a warning if they do not match.
721          * Always use the passed in IRQ, not the one in the EEPROM.
722          */
723         irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
724         irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
725         irq = irq_translate[irq];
726         if (dvp->id_irq > 0) {
727                 if (irq != dvp->id_irq) {
728                         kprintf("ie%d: WARNING: board configured "
729                                "at irq %u, using %u\n",
730                                dvp->id_unit, dvp->id_irq, irq);
731                         irq = dvp->id_unit;
732                 }
733         } else {
734                 dvp->id_irq = irq;
735         }
736         sc->irq_encoded = irq_encode[ffs(irq) - 1];
737
738         /*
739          * Get the hardware ethernet address from the EEPROM and save it in
740          * the softc for use by the 586 setup code.
741          */
742         eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
743         sc->arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
744         sc->arpcom.ac_enaddr[0] = eaddrtemp >> 8;
745         eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
746         sc->arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
747         sc->arpcom.ac_enaddr[2] = eaddrtemp >> 8;
748         eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
749         sc->arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
750         sc->arpcom.ac_enaddr[4] = eaddrtemp >> 8;
751
752         /* disable the board interrupts */
753         outb(PORT + IEE16_IRQ, sc->irq_encoded);
754
755         /* enable loopback to keep bad packets off the wire */
756         if (sc->hard_type == IE_EE16) {
757                 bart_config = inb(PORT + IEE16_CONFIG);
758                 bart_config |= IEE16_BART_LOOPBACK;
759                 bart_config |= IEE16_BART_MCS16_TEST;/* inb doesn't get bit! */
760                 outb(PORT + IEE16_CONFIG, bart_config);
761                 bart_config = inb(PORT + IEE16_CONFIG);
762         }
763         /* take the board out of reset state */
764         outb(PORT + IEE16_ECTRL, 0);
765         DELAY(100);
766
767         if (!check_ie_present(unit, dvp->id_maddr, sc->iosize))
768                 return (0);
769
770         return (16);            /* return the number of I/O ports */
771 }
772
773 /*
774  * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
775  */
776 int
777 ieattach(struct isa_device *dvp)
778 {
779         int     factor;
780         int     unit = dvp->id_unit;
781         struct ie_softc *ie = &ie_softc[unit];
782         struct ifnet *ifp = &ie->arpcom.ac_if;
783         size_t  allocsize;
784
785         dvp->id_intr = (inthand2_t *)ieintr;
786
787         /*
788          * based on the amount of memory we have, allocate our tx and rx
789          * resources.
790          */
791         factor = dvp->id_msize / 16384;
792         ie->nframes = factor * NFRAMES;
793         ie->nrxbufs = factor * NRXBUFS;
794         ie->ntxbufs = factor * NTXBUFS;
795
796         /*
797          * Since all of these guys are arrays of pointers, allocate as one
798          * big chunk and dole out accordingly.
799          */
800         allocsize = sizeof(void *) * (ie->nframes
801                                       + (ie->nrxbufs * 2)
802                                       + (ie->ntxbufs * 3));
803         ie->rframes = kmalloc(allocsize, M_DEVBUF, M_WAITOK);
804         ie->rbuffs =
805             (volatile struct ie_recv_buf_desc **)&ie->rframes[ie->nframes];
806         ie->cbuffs = (volatile u_char **)&ie->rbuffs[ie->nrxbufs];
807         ie->xmit_cmds =
808             (volatile struct ie_xmit_cmd **)&ie->cbuffs[ie->nrxbufs];
809         ie->xmit_buffs =
810             (volatile struct ie_xmit_buf **)&ie->xmit_cmds[ie->ntxbufs];
811         ie->xmit_cbuffs = (volatile u_char **)&ie->xmit_buffs[ie->ntxbufs];
812
813         ifp->if_softc = ie;
814         if_initname(ifp, iedriver.name, unit);
815         ifp->if_mtu = ETHERMTU;
816         if_printf(ifp, "<%s R%d>", ie_hardware_names[ie->hard_type],
817                   ie->hard_vers + 1);
818
819         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
820         ifp->if_start = iestart;
821         ifp->if_ioctl = ieioctl;
822         ifp->if_init = ieinit;
823         ifp->if_type = IFT_ETHER;
824         ifp->if_addrlen = 6;
825         ifp->if_hdrlen = 14;
826         ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
827         ifq_set_ready(&ifp->if_snd);
828
829         if (ie->hard_type == IE_EE16)
830                 EVENTHANDLER_REGISTER(shutdown_post_sync, ee16_shutdown,
831                                       ie, SHUTDOWN_PRI_DRIVER);
832
833         ether_ifattach(ifp, ie->arpcom.ac_enaddr, NULL);
834         return (1);
835 }
836
837 /*
838  * What to do upon receipt of an interrupt.
839  */
840 static void
841 ieintr(void *arg)
842 {
843         int unit = (int)arg;
844         struct ie_softc *ie = &ie_softc[unit];
845         u_short status;
846
847         lwkt_serialize_enter(ie->arpcom.ac_if.if_serializer);
848
849         /* Clear the interrupt latch on the 3C507. */
850         if (ie->hard_type == IE_3C507
851          && (inb(PORT + IE507_CTRL) & EL_CTRL_INTL))
852                 outb(PORT + IE507_ICTRL, 1);
853
854         /* disable interrupts on the EE16. */
855         if (ie->hard_type == IE_EE16)
856                 outb(PORT + IEE16_IRQ, ie->irq_encoded);
857
858         status = ie->scb->ie_status;
859
860 loop:
861
862         /* Don't ack interrupts which we didn't receive */
863         ie_ack(ie->scb, IE_ST_WHENCE & status, unit, ie->ie_chan_attn);
864
865         if (status & (IE_ST_RECV | IE_ST_RNR)) {
866 #ifdef DEBUG
867                 in_ierint++;
868                 if (ie_debug & IED_RINT)
869                         kprintf("ie%d: rint\n", unit);
870 #endif
871                 ierint(unit, ie);
872 #ifdef DEBUG
873                 in_ierint--;
874 #endif
875         }
876         if (status & IE_ST_DONE) {
877 #ifdef DEBUG
878                 in_ietint++;
879                 if (ie_debug & IED_TINT)
880                         kprintf("ie%d: tint\n", unit);
881 #endif
882                 ietint(unit, ie);
883 #ifdef DEBUG
884                 in_ietint--;
885 #endif
886         }
887         if (status & IE_ST_RNR) {
888 #ifdef DEBUG
889                 if (ie_debug & IED_RNR)
890                         kprintf("ie%d: rnr\n", unit);
891 #endif
892                 iernr(unit, ie);
893         }
894 #ifdef DEBUG
895         if ((status & IE_ST_ALLDONE)
896             && (ie_debug & IED_CNA))
897                 kprintf("ie%d: cna\n", unit);
898 #endif
899
900         if ((status = ie->scb->ie_status) & IE_ST_WHENCE)
901                 goto loop;
902
903         /* Clear the interrupt latch on the 3C507. */
904         if (ie->hard_type == IE_3C507)
905                 outb(PORT + IE507_ICTRL, 1);
906
907         /* enable interrupts on the EE16. */
908         if (ie->hard_type == IE_EE16)
909                 outb(PORT + IEE16_IRQ, ie->irq_encoded | IEE16_IRQ_ENABLE);
910
911         lwkt_serialize_exit(ie->arpcom.ac_if.if_serializer);
912 }
913
914 /*
915  * Process a received-frame interrupt.
916  */
917 static int
918 ierint(int unit, struct ie_softc *ie)
919 {
920         int     i, status;
921         static int timesthru = 1024;
922
923         i = ie->rfhead;
924         while (1) {
925                 status = ie->rframes[i]->ie_fd_status;
926
927                 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
928                         ie->arpcom.ac_if.if_ipackets++;
929                         if (!--timesthru) {
930                                 ie->arpcom.ac_if.if_ierrors +=
931                                     ie->scb->ie_err_crc +
932                                     ie->scb->ie_err_align +
933                                     ie->scb->ie_err_resource +
934                                     ie->scb->ie_err_overrun;
935                                 ie->scb->ie_err_crc = 0;
936                                 ie->scb->ie_err_align = 0;
937                                 ie->scb->ie_err_resource = 0;
938                                 ie->scb->ie_err_overrun = 0;
939                                 timesthru = 1024;
940                         }
941                         ie_readframe(unit, ie, i);
942                 } else {
943                         if (status & IE_FD_RNR) {
944                                 if (!(ie->scb->ie_status & IE_RU_READY)) {
945                                         ie->rframes[0]->ie_fd_next =
946                                             MK_16(MEM, ie->rbuffs[0]);
947                                         ie->scb->ie_recv_list =
948                                             MK_16(MEM, ie->rframes[0]);
949                                         command_and_wait(unit, IE_RU_START,
950                                                          0, 0);
951                                 }
952                         }
953                         break;
954                 }
955                 i = (i + 1) % ie->nframes;
956         }
957         return (0);
958 }
959
960 /*
961  * Process a command-complete interrupt.  These are only generated by
962  * the transmission of frames.  This routine is deceptively simple, since
963  * most of the real work is done by iestart().
964  */
965 static int
966 ietint(int unit, struct ie_softc *ie)
967 {
968         int     status;
969         int     i;
970
971         ie->arpcom.ac_if.if_timer = 0;
972         ie->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
973
974         for (i = 0; i < ie->xmit_count; i++) {
975                 status = ie->xmit_cmds[i]->ie_xmit_status;
976
977                 if (status & IE_XS_LATECOLL) {
978                         kprintf("ie%d: late collision\n", unit);
979                         ie->arpcom.ac_if.if_collisions++;
980                         ie->arpcom.ac_if.if_oerrors++;
981                 } else if (status & IE_XS_NOCARRIER) {
982                         kprintf("ie%d: no carrier\n", unit);
983                         ie->arpcom.ac_if.if_oerrors++;
984                 } else if (status & IE_XS_LOSTCTS) {
985                         kprintf("ie%d: lost CTS\n", unit);
986                         ie->arpcom.ac_if.if_oerrors++;
987                 } else if (status & IE_XS_UNDERRUN) {
988                         kprintf("ie%d: DMA underrun\n", unit);
989                         ie->arpcom.ac_if.if_oerrors++;
990                 } else if (status & IE_XS_EXCMAX) {
991                         kprintf("ie%d: too many collisions\n", unit);
992                         ie->arpcom.ac_if.if_collisions += 16;
993                         ie->arpcom.ac_if.if_oerrors++;
994                 } else {
995                         ie->arpcom.ac_if.if_opackets++;
996                         ie->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL;
997                 }
998         }
999         ie->xmit_count = 0;
1000
1001         /*
1002          * If multicast addresses were added or deleted while we were
1003          * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
1004          * that we should do it.
1005          */
1006         if (ie->want_mcsetup) {
1007                 mc_setup(unit, (v_caddr_t) ie->xmit_cbuffs[0], ie->scb);
1008                 ie->want_mcsetup = 0;
1009         }
1010         /* Wish I knew why this seems to be necessary... */
1011         ie->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
1012
1013         if_devstart(&ie->arpcom.ac_if);
1014         return (0);             /* shouldn't be necessary */
1015 }
1016
1017 /*
1018  * Process a receiver-not-ready interrupt.  I believe that we get these
1019  * when there aren't enough buffers to go around.  For now (FIXME), we
1020  * just restart the receiver, and hope everything's ok.
1021  */
1022 static int
1023 iernr(int unit, struct ie_softc *ie)
1024 {
1025 #ifdef doesnt_work
1026         setup_rfa((v_caddr_t) ie->rframes[0], ie);
1027
1028         ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1029         command_and_wait(unit, IE_RU_START, 0, 0);
1030 #else
1031         /* This doesn't work either, but it doesn't hang either. */
1032         command_and_wait(unit, IE_RU_DISABLE, 0, 0);    /* just in case */
1033         setup_rfa((v_caddr_t) ie->rframes[0], ie);      /* ignore cast-qual */
1034
1035         ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1036         command_and_wait(unit, IE_RU_START, 0, 0);      /* was ENABLE */
1037
1038 #endif
1039         ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
1040
1041         ie->arpcom.ac_if.if_ierrors++;
1042         return (0);
1043 }
1044
1045 /*
1046  * Compare two Ether/802 addresses for equality, inlined and
1047  * unrolled for speed.  I'd love to have an inline assembler
1048  * version of this...
1049  */
1050 static __inline int
1051 ether_equal(u_char * one, u_char * two)
1052 {
1053         if (one[0] != two[0])
1054                 return (0);
1055         if (one[1] != two[1])
1056                 return (0);
1057         if (one[2] != two[2])
1058                 return (0);
1059         if (one[3] != two[3])
1060                 return (0);
1061         if (one[4] != two[4])
1062                 return (0);
1063         if (one[5] != two[5])
1064                 return (0);
1065         return 1;
1066 }
1067
1068 /*
1069  * Determine quickly whether we should bother reading in this packet.
1070  * This depends on whether BPF and/or bridging is enabled, whether we
1071  * are receiving multicast address, and whether promiscuous mode is enabled.
1072  * We assume that if IFF_PROMISC is set, then *somebody* wants to see
1073  * all incoming packets.
1074  */
1075 static __inline int
1076 check_eh(struct ie_softc *ie, struct ether_header *eh)
1077 {
1078         /* Optimize the common case: normal operation. We've received
1079            either a unicast with our dest or a multicast packet. */
1080         if (ie->promisc == 0) {
1081                 int i;
1082
1083                 /* If not multicast, it's definitely for us */
1084                 if ((eh->ether_dhost[0] & 1) == 0)
1085                         return (1);
1086
1087                 /* Accept broadcasts (loose but fast check) */
1088                 if (eh->ether_dhost[0] == 0xff)
1089                         return (1);
1090
1091                 /* Compare against our multicast addresses */
1092                 for (i = 0; i < ie->mcast_count; i++) {
1093                         if (ether_equal(eh->ether_dhost,
1094                             (u_char *)&ie->mcast_addrs[i]))
1095                                 return (1);
1096                 }
1097                 return (0);
1098         }
1099
1100         /* Always accept packets when in promiscuous mode */
1101         if ((ie->promisc & IFF_PROMISC) != 0)
1102                 return (1);
1103
1104         /* Always accept packets directed at us */
1105         if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1106                 return (1);
1107
1108         /* Must have IFF_ALLMULTI but not IFF_PROMISC set. The chip is
1109            actually in promiscuous mode, so discard unicast packets. */
1110         return((eh->ether_dhost[0] & 1) != 0);
1111 }
1112
1113 /*
1114  * We want to isolate the bits that have meaning...  This assumes that
1115  * IE_RBUF_SIZE is an even power of two.  If somehow the act_len exceeds
1116  * the size of the buffer, then we are screwed anyway.
1117  */
1118 static __inline int
1119 ie_buflen(struct ie_softc * ie, int head)
1120 {
1121         return (ie->rbuffs[head]->ie_rbd_actual
1122                 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
1123 }
1124
1125 static __inline int
1126 ie_packet_len(int unit, struct ie_softc * ie)
1127 {
1128         int     i;
1129         int     head = ie->rbhead;
1130         int     acc = 0;
1131
1132         do {
1133                 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1134 #ifdef DEBUG
1135                         print_rbd(ie->rbuffs[ie->rbhead]);
1136 #endif
1137                         log(LOG_ERR,
1138                             "ie%d: receive descriptors out of sync at %d\n",
1139                             unit, ie->rbhead);
1140                         iereset(unit);
1141                         return (-1);
1142                 }
1143                 i = ie->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
1144
1145                 acc += ie_buflen(ie, head);
1146                 head = (head + 1) % ie->nrxbufs;
1147         } while (!i);
1148
1149         return (acc);
1150 }
1151
1152 /*
1153  * Read data off the interface, and turn it into an mbuf chain.
1154  *
1155  * This code is DRAMATICALLY different from the previous version; this
1156  * version tries to allocate the entire mbuf chain up front, given the
1157  * length of the data available.  This enables us to allocate mbuf
1158  * clusters in many situations where before we would have had a long
1159  * chain of partially-full mbufs.  This should help to speed up the
1160  * operation considerably.  (Provided that it works, of course.)
1161  */
1162 static __inline int
1163 ieget(int unit, struct ie_softc *ie, struct mbuf **mp)
1164 {
1165         struct  mbuf *m, *top, **mymp;
1166         struct  ether_header eh;
1167         int     i;
1168         int     offset;
1169         int     totlen, resid;
1170         int     thismboff;
1171         int     head;
1172
1173         totlen = ie_packet_len(unit, ie);
1174         if (totlen <= 0)
1175                 return (-1);
1176
1177         i = ie->rbhead;
1178
1179         /*
1180          * Snarf the Ethernet header.
1181          */
1182         bcopy((v_caddr_t) ie->cbuffs[i], (caddr_t) &eh, sizeof eh);
1183         /* ignore cast-qual warning here */
1184
1185         /*
1186          * As quickly as possible, check if this packet is for us. If not,
1187          * don't waste a single cycle copying the rest of the packet in.
1188          * This is only a consideration when FILTER is defined; i.e., when
1189          * we are either running BPF or doing multicasting.
1190          */
1191         if (!check_eh(ie, &eh)) {
1192                 ie_drop_packet_buffer(unit, ie);
1193                 ie->arpcom.ac_if.if_ierrors--;  /* just this case, it's not an
1194                                                  * error
1195                                                  */
1196                 return (-1);
1197         }
1198         offset = 0;
1199
1200         MGETHDR(*mp, MB_DONTWAIT, MT_DATA);
1201         if (!*mp) {
1202                 ie_drop_packet_buffer(unit, ie);
1203                 return (-1);
1204         }
1205         m = *mp;
1206         m->m_len = MHLEN;
1207         resid = m->m_pkthdr.len = totlen;
1208         top = 0;
1209         mymp = &top;
1210
1211         /*
1212          * This loop goes through and allocates mbufs for all the data we
1213          * will be copying in.  It does not actually do the copying yet.
1214          */
1215         do {                    /* while(resid > 0) */
1216                 /*
1217                  * Try to allocate an mbuf to hold the data that we have.
1218                  * If we already allocated one, just get another one and
1219                  * stick it on the end (eventually).  If we don't already
1220                  * have one, try to allocate an mbuf cluster big enough to
1221                  * hold the whole packet, if we think it's reasonable, or a
1222                  * single mbuf which may or may not be big enough. Got that?
1223                  */
1224                 if (top) {
1225                         MGET(m, MB_DONTWAIT, MT_DATA);
1226                         if (!m) {
1227                                 m_freem(top);
1228                                 ie_drop_packet_buffer(unit, ie);
1229                                 return (-1);
1230                         }
1231                         m->m_len = MLEN;
1232                 }
1233                 if (resid >= MINCLSIZE) {
1234                         MCLGET(m, MB_DONTWAIT);
1235                         if (m->m_flags & M_EXT)
1236                                 m->m_len = min(resid, MCLBYTES);
1237                 } else {
1238                         if (resid < m->m_len) {
1239                                 if (!top && resid + max_linkhdr <= m->m_len)
1240                                         m->m_data += max_linkhdr;
1241                                 m->m_len = resid;
1242                         }
1243                 }
1244                 resid -= m->m_len;
1245                 *mymp = m;
1246                 mymp = &m->m_next;
1247         } while (resid > 0);
1248
1249         resid = totlen;
1250         m = top;
1251         thismboff = 0;
1252         head = ie->rbhead;
1253
1254         /*
1255          * Now we take the mbuf chain (hopefully only one mbuf most of the
1256          * time) and stuff the data into it.  There are no possible failures
1257          * at or after this point.
1258          */
1259         while (resid > 0) {     /* while there's stuff left */
1260                 int     thislen = ie_buflen(ie, head) - offset;
1261
1262                 /*
1263                  * If too much data for the current mbuf, then fill the
1264                  * current one up, go to the next one, and try again.
1265                  */
1266                 if (thislen > m->m_len - thismboff) {
1267                         int     newlen = m->m_len - thismboff;
1268
1269                         bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1270                               mtod(m, v_caddr_t) +thismboff, (unsigned) newlen);
1271                         /* ignore cast-qual warning */
1272                         m = m->m_next;
1273                         thismboff = 0;  /* new mbuf, so no offset */
1274                         offset += newlen;       /* we are now this far into
1275                                                  * the packet */
1276                         resid -= newlen;        /* so there is this much left
1277                                                  * to get */
1278                         continue;
1279                 }
1280                 /*
1281                  * If there is more than enough space in the mbuf to hold
1282                  * the contents of this buffer, copy everything in, advance
1283                  * pointers, and so on.
1284                  */
1285                 if (thislen < m->m_len - thismboff) {
1286                         bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1287                             mtod(m, caddr_t) +thismboff, (unsigned) thislen);
1288                         thismboff += thislen;   /* we are this far into the
1289                                                  * mbuf */
1290                         resid -= thislen;       /* and this much is left */
1291                         goto nextbuf;
1292                 }
1293                 /*
1294                  * Otherwise, there is exactly enough space to put this
1295                  * buffer's contents into the current mbuf.  Do the
1296                  * combination of the above actions.
1297                  */
1298                 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1299                       mtod(m, caddr_t) + thismboff, (unsigned) thislen);
1300                 m = m->m_next;
1301                 thismboff = 0;          /* new mbuf, start at the beginning */
1302                 resid -= thislen;       /* and we are this far through */
1303
1304                 /*
1305                  * Advance all the pointers.  We can get here from either of
1306                  * the last two cases, but never the first.
1307                  */
1308 nextbuf:
1309                 offset = 0;
1310                 ie->rbuffs[head]->ie_rbd_actual = 0;
1311                 ie->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
1312                 ie->rbhead = head = (head + 1) % ie->nrxbufs;
1313                 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1314                 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1315         }
1316
1317         /*
1318          * Unless something changed strangely while we were doing the copy,
1319          * we have now copied everything in from the shared memory. This
1320          * means that we are done.
1321          */
1322         return (0);
1323 }
1324
1325 /*
1326  * Read frame NUM from unit UNIT (pre-cached as IE).
1327  *
1328  * This routine reads the RFD at NUM, and copies in the buffers from
1329  * the list of RBD, then rotates the RBD and RFD lists so that the receiver
1330  * doesn't start complaining.  Trailers are DROPPED---there's no point
1331  * in wasting time on confusing code to deal with them.  Hopefully,
1332  * this machine will never ARP for trailers anyway.
1333  */
1334 static void
1335 ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
1336 {
1337         struct ie_recv_frame_desc rfd;
1338         struct mbuf *m = NULL;
1339
1340         bcopy((v_caddr_t) (ie->rframes[num]), &rfd,
1341               sizeof(struct ie_recv_frame_desc));
1342
1343         /*
1344          * Immediately advance the RFD list, since we we have copied ours
1345          * now.
1346          */
1347         ie->rframes[num]->ie_fd_status = 0;
1348         ie->rframes[num]->ie_fd_last |= IE_FD_LAST;
1349         ie->rframes[ie->rftail]->ie_fd_last &= ~IE_FD_LAST;
1350         ie->rftail = (ie->rftail + 1) % ie->nframes;
1351         ie->rfhead = (ie->rfhead + 1) % ie->nframes;
1352
1353         if (rfd.ie_fd_status & IE_FD_OK) {
1354                 if (ieget(unit, ie, &m)) {
1355                         ie->arpcom.ac_if.if_ierrors++;  /* this counts as an
1356                                                          * error */
1357                         return;
1358                 }
1359         }
1360
1361         if (!m)
1362                 return;
1363
1364         /*
1365          * Finally pass this packet up to higher layers.
1366          */
1367         ie->arpcom.ac_if.if_input(&ie->arpcom.ac_if, m);
1368 }
1369
1370 static void
1371 ie_drop_packet_buffer(int unit, struct ie_softc * ie)
1372 {
1373         int     i;
1374
1375         do {
1376                 /*
1377                  * This means we are somehow out of sync.  So, we reset the
1378                  * adapter.
1379                  */
1380                 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1381 #ifdef DEBUG
1382                         print_rbd(ie->rbuffs[ie->rbhead]);
1383 #endif
1384                         log(LOG_ERR, "ie%d: receive descriptors out of sync at %d\n",
1385                             unit, ie->rbhead);
1386                         iereset(unit);
1387                         return;
1388                 }
1389                 i = ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1390
1391                 ie->rbuffs[ie->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1392                 ie->rbuffs[ie->rbhead]->ie_rbd_actual = 0;
1393                 ie->rbhead = (ie->rbhead + 1) % ie->nrxbufs;
1394                 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1395                 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1396         } while (!i);
1397 }
1398
1399
1400 /*
1401  * Start transmission on an interface.
1402  */
1403 static void
1404 iestart(struct ifnet *ifp)
1405 {
1406         struct   ie_softc *ie = ifp->if_softc;
1407         struct   mbuf *m0, *m;
1408         volatile unsigned char *buffer;
1409         u_short  len;
1410
1411         /*
1412          * This is not really volatile, in this routine, but it makes gcc
1413          * happy.
1414          */
1415         volatile u_short *bptr = &ie->scb->ie_command_list;
1416
1417         if (!(ifp->if_flags & IFF_RUNNING))
1418                 return;
1419         if (ifp->if_flags & IFF_OACTIVE)
1420                 return;
1421
1422         do {
1423                 m = ifq_dequeue(&ie->arpcom.ac_if.if_snd, NULL);
1424                 if (m == NULL)
1425                         break;
1426
1427                 buffer = ie->xmit_cbuffs[ie->xmit_count];
1428                 len = 0;
1429
1430                 for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) {
1431                         bcopy(mtod(m, caddr_t), buffer, m->m_len);
1432                         buffer += m->m_len;
1433                         len += m->m_len;
1434                 }
1435
1436                 m_freem(m0);
1437                 len = max(len, ETHER_MIN_LEN);
1438
1439                 /*
1440                  * See if bpf is listening on this interface, let it see the
1441                  * packet before we commit it to the wire.
1442                  */
1443                 BPF_TAP(&ie->arpcom.ac_if,
1444                     __DEVOLATILE(u_char *, ie->xmit_cbuffs[ie->xmit_count]),
1445                     len);
1446
1447                 ie->xmit_buffs[ie->xmit_count]->ie_xmit_flags =
1448                     IE_XMIT_LAST|len;
1449                 ie->xmit_buffs[ie->xmit_count]->ie_xmit_next = 0xffff;
1450                 ie->xmit_buffs[ie->xmit_count]->ie_xmit_buf =
1451                     MK_24(ie->iomem, ie->xmit_cbuffs[ie->xmit_count]);
1452
1453                 ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT;
1454                 ie->xmit_cmds[ie->xmit_count]->ie_xmit_status = 0;
1455                 ie->xmit_cmds[ie->xmit_count]->ie_xmit_desc =
1456                     MK_16(ie->iomem, ie->xmit_buffs[ie->xmit_count]);
1457
1458                 *bptr = MK_16(ie->iomem, ie->xmit_cmds[ie->xmit_count]);
1459                 bptr = &ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_link;
1460                 ie->xmit_count++;
1461         } while (ie->xmit_count < ie->ntxbufs);
1462
1463         /*
1464          * If we queued up anything for transmission, send it.
1465          */
1466         if (ie->xmit_count) {
1467                 ie->xmit_cmds[ie->xmit_count - 1]->com.ie_cmd_cmd |=
1468                     IE_CMD_LAST | IE_CMD_INTR;
1469
1470                 /*
1471                  * By passing the command pointer as a null, we tell
1472                  * command_and_wait() to pretend that this isn't an action
1473                  * command.  I wish I understood what was happening here.
1474                  */
1475                 command_and_wait(ifp->if_dunit, IE_CU_START, 0, 0);
1476                 ifp->if_flags |= IFF_OACTIVE;
1477         }
1478         return;
1479 }
1480
1481 /*
1482  * Check to see if there's an 82586 out there.
1483  */
1484 static int
1485 check_ie_present(int unit, caddr_t where, unsigned size)
1486 {
1487         volatile struct ie_sys_conf_ptr *scp;
1488         volatile struct ie_int_sys_conf_ptr *iscp;
1489         volatile struct ie_sys_ctl_block *scb;
1490         u_long  realbase;
1491
1492         realbase = (uintptr_t) where + size - (1 << 24);
1493
1494         scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t)
1495               (realbase + IE_SCP_ADDR);
1496         bzero((volatile char *) scp, sizeof *scp);
1497
1498         /*
1499          * First we put the ISCP at the bottom of memory; this tests to make
1500          * sure that our idea of the size of memory is the same as the
1501          * controller's. This is NOT where the ISCP will be in normal
1502          * operation.
1503          */
1504         iscp = (volatile struct ie_int_sys_conf_ptr *) where;
1505         bzero((volatile char *)iscp, sizeof *iscp);
1506
1507         scb = (volatile struct ie_sys_ctl_block *) where;
1508         bzero((volatile char *)scb, sizeof *scb);
1509
1510         scp->ie_bus_use = ie_softc[unit].bus_use;       /* 8-bit or 16-bit */
1511         scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1512             ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1513
1514         iscp->ie_busy = 1;
1515         iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1516
1517         (*ie_softc[unit].ie_reset_586) (unit);
1518         (*ie_softc[unit].ie_chan_attn) (unit);
1519
1520         DELAY(100);             /* wait a while... */
1521
1522         if (iscp->ie_busy) {
1523                 return (0);
1524         }
1525         /*
1526          * Now relocate the ISCP to its real home, and reset the controller
1527          * again.
1528          */
1529         iscp = (void *) Align((caddr_t) (uintptr_t)
1530                               (realbase + IE_SCP_ADDR -
1531                                sizeof(struct ie_int_sys_conf_ptr)));
1532         bzero((volatile char *) iscp, sizeof *iscp);    /* ignore cast-qual */
1533
1534         scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1535             ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1536
1537         iscp->ie_busy = 1;
1538         iscp->ie_scb_offset = MK_16(realbase, scb);
1539
1540         (*ie_softc[unit].ie_reset_586) (unit);
1541         (*ie_softc[unit].ie_chan_attn) (unit);
1542
1543         DELAY(100);
1544
1545         if (iscp->ie_busy) {
1546                 return (0);
1547         }
1548         ie_softc[unit].iosize = size;
1549         ie_softc[unit].iomem = (caddr_t) (uintptr_t) realbase;
1550
1551         ie_softc[unit].iscp = iscp;
1552         ie_softc[unit].scb = scb;
1553
1554         /*
1555          * Acknowledge any interrupts we may have caused...
1556          */
1557         ie_ack(scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1558
1559         return (1);
1560 }
1561
1562 /*
1563  * Divine the memory size of ie board UNIT.
1564  * Better hope there's nothing important hiding just below the ie card...
1565  */
1566 static void
1567 find_ie_mem_size(int unit)
1568 {
1569         unsigned size;
1570
1571         ie_softc[unit].iosize = 0;
1572
1573         for (size = 65536; size >= 8192; size -= 8192) {
1574                 if (check_ie_present(unit, ie_softc[unit].iomembot, size)) {
1575                         return;
1576                 }
1577         }
1578
1579         return;
1580 }
1581
1582 void
1583 el_reset_586(int unit)
1584 {
1585         outb(PORT + IE507_CTRL, EL_CTRL_RESET);
1586         DELAY(100);
1587         outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
1588         DELAY(100);
1589 }
1590
1591 void
1592 sl_reset_586(int unit)
1593 {
1594         outb(PORT + IEATT_RESET, 0);
1595 }
1596
1597 void
1598 ee16_reset_586(int unit)
1599 {
1600         outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
1601         DELAY(100);
1602         outb(PORT + IEE16_ECTRL, 0);
1603         DELAY(100);
1604 }
1605
1606 void
1607 el_chan_attn(int unit)
1608 {
1609         outb(PORT + IE507_ATTN, 1);
1610 }
1611
1612 void
1613 sl_chan_attn(int unit)
1614 {
1615         outb(PORT + IEATT_ATTN, 0);
1616 }
1617
1618 void
1619 ee16_chan_attn(int unit)
1620 {
1621         outb(PORT + IEE16_ATTN, 0);
1622 }
1623
1624 u_short
1625 ee16_read_eeprom(struct ie_softc *sc, int location)
1626 {
1627         int     ectrl, edata;
1628
1629         ectrl = inb(sc->port + IEE16_ECTRL);
1630         ectrl &= IEE16_ECTRL_MASK;
1631         ectrl |= IEE16_ECTRL_EECS;
1632         outb(sc->port + IEE16_ECTRL, ectrl);
1633
1634         ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
1635         ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
1636         edata = ee16_eeprom_inbits(sc);
1637         ectrl = inb(sc->port + IEE16_ECTRL);
1638         ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
1639         outb(sc->port + IEE16_ECTRL, ectrl);
1640         ee16_eeprom_clock(sc, 1);
1641         ee16_eeprom_clock(sc, 0);
1642         return edata;
1643 }
1644
1645 void
1646 ee16_eeprom_outbits(struct ie_softc *sc, int edata, int count)
1647 {
1648         int     ectrl, i;
1649
1650         ectrl = inb(sc->port + IEE16_ECTRL);
1651         ectrl &= ~IEE16_RESET_ASIC;
1652         for (i = count - 1; i >= 0; i--) {
1653                 ectrl &= ~IEE16_ECTRL_EEDI;
1654                 if (edata & (1 << i)) {
1655                         ectrl |= IEE16_ECTRL_EEDI;
1656                 }
1657                 outb(sc->port + IEE16_ECTRL, ectrl);
1658                 DELAY(1);       /* eeprom data must be setup for 0.4 uSec */
1659                 ee16_eeprom_clock(sc, 1);
1660                 ee16_eeprom_clock(sc, 0);
1661         }
1662         ectrl &= ~IEE16_ECTRL_EEDI;
1663         outb(sc->port + IEE16_ECTRL, ectrl);
1664         DELAY(1);               /* eeprom data must be held for 0.4 uSec */
1665 }
1666
1667 int
1668 ee16_eeprom_inbits(struct ie_softc *sc)
1669 {
1670         int     ectrl, edata, i;
1671
1672         ectrl = inb(sc->port + IEE16_ECTRL);
1673         ectrl &= ~IEE16_RESET_ASIC;
1674         for (edata = 0, i = 0; i < 16; i++) {
1675                 edata = edata << 1;
1676                 ee16_eeprom_clock(sc, 1);
1677                 ectrl = inb(sc->port + IEE16_ECTRL);
1678                 if (ectrl & IEE16_ECTRL_EEDO) {
1679                         edata |= 1;
1680                 }
1681                 ee16_eeprom_clock(sc, 0);
1682         }
1683         return (edata);
1684 }
1685
1686 void
1687 ee16_eeprom_clock(struct ie_softc *sc, int state)
1688 {
1689         int     ectrl;
1690
1691         ectrl = inb(sc->port + IEE16_ECTRL);
1692         ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
1693         if (state) {
1694                 ectrl |= IEE16_ECTRL_EESK;
1695         }
1696         outb(sc->port + IEE16_ECTRL, ectrl);
1697         DELAY(9);               /* EESK must be stable for 8.38 uSec */
1698 }
1699
1700 static __inline void
1701 ee16_interrupt_enable(struct ie_softc *sc)
1702 {
1703         DELAY(100);
1704         outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1705         DELAY(100);
1706 }
1707
1708 void
1709 sl_read_ether(int unit, unsigned char addr[6])
1710 {
1711         int     i;
1712
1713         for (i = 0; i < 6; i++)
1714                 addr[i] = inb(PORT + i);
1715 }
1716
1717
1718 static void
1719 iereset(int unit)
1720 {
1721         if (unit >= NIE) {
1722                 return;
1723         }
1724         kprintf("ie%d: reset\n", unit);
1725         ie_softc[unit].arpcom.ac_if.if_flags &= ~IFF_UP;
1726         ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, (struct ucred *)NULL);
1727
1728         /*
1729          * Stop i82586 dead in its tracks.
1730          */
1731         if (command_and_wait(unit, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1732                 kprintf("ie%d: abort commands timed out\n", unit);
1733
1734         if (command_and_wait(unit, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1735                 kprintf("ie%d: disable commands timed out\n", unit);
1736
1737 #ifdef notdef
1738         if (!check_ie_present(unit, ie_softc[unit].iomembot,
1739                               e_softc[unit].iosize))
1740                 panic("ie disappeared!");
1741 #endif
1742
1743         ie_softc[unit].arpcom.ac_if.if_flags |= IFF_UP;
1744         ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, (struct ucred *)NULL);
1745 }
1746
1747 /*
1748  * Send a command to the controller and wait for it to either
1749  * complete or be accepted, depending on the command.  If the
1750  * command pointer is null, then pretend that the command is
1751  * not an action command.  If the command pointer is not null,
1752  * and the command is an action command, wait for
1753  * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1754  * to become true.
1755  */
1756 static int
1757 command_and_wait(int unit, int cmd, volatile void *pcmd, int mask)
1758 {
1759         volatile struct ie_cmd_common *cc = pcmd;
1760
1761         ie_softc[unit].scb->ie_command = (u_short) cmd;
1762
1763         if (IE_ACTION_COMMAND(cmd) && pcmd) {
1764                 /*
1765                  * According to the packet driver, the minimum timeout
1766                  * should be .369 seconds.
1767                  */
1768                 int timer = 370;
1769
1770                 (*ie_softc[unit].ie_chan_attn) (unit);
1771
1772                 /*
1773                  * Now spin-lock waiting for status.  This is not a very
1774                  * nice thing to do, but I haven't figured out how, or
1775                  * indeed if, we can put the process waiting for action to
1776                  * sleep.  (We may be getting called through some other
1777                  * timeout running in the kernel.)
1778                  */
1779                 while (--timer > 0) {
1780                         if (cc->ie_cmd_status & mask)
1781                                 break;
1782                         DELAY(1000);
1783                 }
1784                 if (timer == 0)
1785                         return(1);
1786                 else
1787                         return(0);
1788         } else {
1789
1790                 /*
1791                  * Otherwise, just wait for the command to be accepted.
1792                  */
1793                 (*ie_softc[unit].ie_chan_attn) (unit);
1794
1795                 while (ie_softc[unit].scb->ie_command); /* spin lock */
1796
1797                 return (0);
1798         }
1799 }
1800
1801 /*
1802  * Run the time-domain reflectometer...
1803  */
1804 static void
1805 run_tdr(int unit, volatile struct ie_tdr_cmd *cmd)
1806 {
1807         int     result;
1808
1809         cmd->com.ie_cmd_status = 0;
1810         cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1811         cmd->com.ie_cmd_link = 0xffff;
1812         cmd->ie_tdr_time = 0;
1813
1814         ie_softc[unit].scb->ie_command_list = MK_16(MEM, cmd);
1815         cmd->ie_tdr_time = 0;
1816
1817         if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL))
1818                 result = 0x2000;
1819         else
1820                 result = cmd->ie_tdr_time;
1821
1822         ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit,
1823                ie_softc[unit].ie_chan_attn);
1824
1825         if (result & IE_TDR_SUCCESS)
1826                 return;
1827
1828         if (result & IE_TDR_XCVR) {
1829                 kprintf("ie%d: transceiver problem\n", unit);
1830         } else if (result & IE_TDR_OPEN) {
1831                 kprintf("ie%d: TDR detected an open %d clocks away\n", unit,
1832                        result & IE_TDR_TIME);
1833         } else if (result & IE_TDR_SHORT) {
1834                 kprintf("ie%d: TDR detected a short %d clocks away\n", unit,
1835                        result & IE_TDR_TIME);
1836         } else {
1837                 kprintf("ie%d: TDR returned unknown status %x\n", unit, result);
1838         }
1839 }
1840
1841 static void
1842 start_receiver(int unit)
1843 {
1844         ie_softc[unit].scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1845         command_and_wait(unit, IE_RU_START, 0, 0);
1846
1847         ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1848 }
1849
1850 /*
1851  * Here is a helper routine for iernr() and ieinit().  This sets up
1852  * the RFA.
1853  */
1854 static v_caddr_t
1855 setup_rfa(v_caddr_t ptr, struct ie_softc * ie)
1856 {
1857         volatile struct ie_recv_frame_desc *rfd = (volatile void *)ptr;
1858         volatile struct ie_recv_buf_desc *rbd;
1859         int     i;
1860         int     unit = ie - &ie_softc[0];
1861
1862         /* First lay them out */
1863         for (i = 0; i < ie->nframes; i++) {
1864                 ie->rframes[i] = rfd;
1865                 bzero((volatile char *) rfd, sizeof *rfd);      /* ignore cast-qual */
1866                 rfd++;
1867         }
1868
1869         ptr = Alignvol(rfd);            /* ignore cast-qual */
1870
1871         /* Now link them together */
1872         for (i = 0; i < ie->nframes; i++) {
1873                 ie->rframes[i]->ie_fd_next =
1874                     MK_16(MEM, ie->rframes[(i + 1) % ie->nframes]);
1875         }
1876
1877         /* Finally, set the EOL bit on the last one. */
1878         ie->rframes[ie->nframes - 1]->ie_fd_last |= IE_FD_LAST;
1879
1880         /*
1881          * Now lay out some buffers for the incoming frames.  Note that we
1882          * set aside a bit of slop in each buffer, to make sure that we have
1883          * enough space to hold a single frame in every buffer.
1884          */
1885         rbd = (volatile void *) ptr;
1886
1887         for (i = 0; i < ie->nrxbufs; i++) {
1888                 ie->rbuffs[i] = rbd;
1889                 bzero((volatile char *)rbd, sizeof *rbd);
1890                 ptr = Alignvol(ptr + sizeof *rbd);
1891                 rbd->ie_rbd_length = IE_RBUF_SIZE;
1892                 rbd->ie_rbd_buffer = MK_24(MEM, ptr);
1893                 ie->cbuffs[i] = (volatile void *) ptr;
1894                 ptr += IE_RBUF_SIZE;
1895                 rbd = (volatile void *) ptr;
1896         }
1897
1898         /* Now link them together */
1899         for (i = 0; i < ie->nrxbufs; i++) {
1900                 ie->rbuffs[i]->ie_rbd_next =
1901                     MK_16(MEM, ie->rbuffs[(i + 1) % ie->nrxbufs]);
1902         }
1903
1904         /* Tag EOF on the last one */
1905         ie->rbuffs[ie->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST;
1906
1907         /*
1908          * We use the head and tail pointers on receive to keep track of the
1909          * order in which RFDs and RBDs are used.
1910          */
1911         ie->rfhead = 0;
1912         ie->rftail = ie->nframes - 1;
1913         ie->rbhead = 0;
1914         ie->rbtail = ie->nrxbufs - 1;
1915
1916         ie->scb->ie_recv_list = MK_16(MEM, ie->rframes[0]);
1917         ie->rframes[0]->ie_fd_buf_desc = MK_16(MEM, ie->rbuffs[0]);
1918
1919         ptr = Alignvol(ptr);
1920         return (ptr);
1921 }
1922
1923 /*
1924  * Run the multicast setup command.
1925  */
1926 static int
1927 mc_setup(int unit, v_caddr_t ptr,
1928          volatile struct ie_sys_ctl_block * scb)
1929 {
1930         struct ie_softc *ie = &ie_softc[unit];
1931         volatile struct ie_mcast_cmd *cmd = (volatile void *) ptr;
1932
1933         cmd->com.ie_cmd_status = 0;
1934         cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1935         cmd->com.ie_cmd_link = 0xffff;
1936
1937         /* ignore cast-qual */
1938         bcopy((v_caddr_t) ie->mcast_addrs, (v_caddr_t) cmd->ie_mcast_addrs,
1939               ie->mcast_count * sizeof *ie->mcast_addrs);
1940
1941         cmd->ie_mcast_bytes = ie->mcast_count * 6;      /* grrr... */
1942
1943         scb->ie_command_list = MK_16(MEM, cmd);
1944         if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
1945             || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1946                 kprintf("ie%d: multicast address setup command failed\n", unit);
1947                 return (0);
1948         }
1949         return (1);
1950 }
1951
1952 /*
1953  * This routine takes the environment generated by check_ie_present()
1954  * and adds to it all the other structures we need to operate the adapter.
1955  * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1956  * starting the receiver unit, and clearing interrupts.
1957  */
1958 static void
1959 ieinit(void *xsc)
1960 {
1961         struct ie_softc *ie = xsc;
1962         volatile struct ie_sys_ctl_block *scb = ie->scb;
1963         v_caddr_t ptr;
1964         int     i;
1965         int     unit = ie->unit;
1966
1967         ptr = Alignvol((volatile char *) scb + sizeof *scb);
1968
1969         /*
1970          * Send the configure command first.
1971          */
1972         {
1973                 volatile struct ie_config_cmd *cmd = (volatile void *) ptr;
1974
1975                 ie_setup_config(cmd, ie->promisc,
1976                                 ie->hard_type == IE_STARLAN10);
1977                 cmd->com.ie_cmd_status = 0;
1978                 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
1979                 cmd->com.ie_cmd_link = 0xffff;
1980
1981                 scb->ie_command_list = MK_16(MEM, cmd);
1982
1983                 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
1984                  || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1985                         kprintf("ie%d: configure command failed\n", unit);
1986                         return;
1987                 }
1988         }
1989         /*
1990          * Now send the Individual Address Setup command.
1991          */
1992         {
1993                 volatile struct ie_iasetup_cmd *cmd = (volatile void *) ptr;
1994
1995                 cmd->com.ie_cmd_status = 0;
1996                 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
1997                 cmd->com.ie_cmd_link = 0xffff;
1998
1999                 bcopy((volatile char *)ie_softc[unit].arpcom.ac_enaddr,
2000                       (volatile char *)&cmd->ie_address, sizeof cmd->ie_address);
2001                 scb->ie_command_list = MK_16(MEM, cmd);
2002                 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2003                     || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2004                         kprintf("ie%d: individual address "
2005                                "setup command failed\n", unit);
2006                         return;
2007                 }
2008         }
2009
2010         /*
2011          * Now run the time-domain reflectometer.
2012          */
2013         run_tdr(unit, (volatile void *) ptr);
2014
2015         /*
2016          * Acknowledge any interrupts we have generated thus far.
2017          */
2018         ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
2019
2020         /*
2021          * Set up the RFA.
2022          */
2023         ptr = setup_rfa(ptr, ie);
2024
2025         /*
2026          * Finally, the transmit command and buffer are the last little bit
2027          * of work.
2028          */
2029
2030         /* transmit command buffers */
2031         for (i = 0; i < ie->ntxbufs; i++) {
2032                 ie->xmit_cmds[i] = (volatile void *) ptr;
2033                 ptr += sizeof *ie->xmit_cmds[i];
2034                 ptr = Alignvol(ptr);
2035                 ie->xmit_buffs[i] = (volatile void *)ptr;
2036                 ptr += sizeof *ie->xmit_buffs[i];
2037                 ptr = Alignvol(ptr);
2038         }
2039
2040         /* transmit buffers */
2041         for (i = 0; i < ie->ntxbufs - 1; i++) {
2042                 ie->xmit_cbuffs[i] = (volatile void *)ptr;
2043                 ptr += IE_BUF_LEN;
2044                 ptr = Alignvol(ptr);
2045         }
2046         ie->xmit_cbuffs[ie->ntxbufs - 1] = (volatile void *) ptr;
2047
2048         for (i = 1; i < ie->ntxbufs; i++) {
2049                 bzero((v_caddr_t) ie->xmit_cmds[i], sizeof *ie->xmit_cmds[i]);
2050                 bzero((v_caddr_t) ie->xmit_buffs[i], sizeof *ie->xmit_buffs[i]);
2051         }
2052
2053         /*
2054          * This must be coordinated with iestart() and ietint().
2055          */
2056         ie->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
2057
2058         /* take the ee16 out of loopback */
2059         if (ie->hard_type == IE_EE16) {
2060                 u_int8_t bart_config;
2061
2062                 bart_config = inb(PORT + IEE16_CONFIG);
2063                 bart_config &= ~IEE16_BART_LOOPBACK;
2064                 /* inb doesn't get bit! */
2065                 bart_config |= IEE16_BART_MCS16_TEST;
2066                 outb(PORT + IEE16_CONFIG, bart_config);
2067                 ee16_interrupt_enable(ie);
2068                 ee16_chan_attn(unit);
2069         }
2070         ie->arpcom.ac_if.if_flags |= IFF_RUNNING;       /* tell higher levels
2071                                                          * we're here */
2072         start_receiver(unit);
2073 }
2074
2075 static void
2076 ie_stop(int unit)
2077 {
2078         command_and_wait(unit, IE_RU_DISABLE, 0, 0);
2079 }
2080
2081 static int
2082 ieioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
2083 {
2084         int error = 0;
2085
2086         switch (command) {
2087         case SIOCSIFFLAGS:
2088                 /*
2089                  * Note that this device doesn't have an "all multicast"
2090                  * mode, so we must turn on promiscuous mode and do the
2091                  * filtering manually.
2092                  */
2093                 if ((ifp->if_flags & IFF_UP) == 0 &&
2094                     (ifp->if_flags & IFF_RUNNING)) {
2095                         ifp->if_flags &= ~IFF_RUNNING;
2096                         ie_stop(ifp->if_dunit);
2097                 } else if ((ifp->if_flags & IFF_UP) &&
2098                            (ifp->if_flags & IFF_RUNNING) == 0) {
2099                         ie_softc[ifp->if_dunit].promisc =
2100                             ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2101                         ieinit(ifp->if_softc);
2102                 } else if (ie_softc[ifp->if_dunit].promisc ^
2103                            (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) {
2104                         ie_softc[ifp->if_dunit].promisc =
2105                             ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2106                         ieinit(ifp->if_softc);
2107                 }
2108                 break;
2109
2110         case SIOCADDMULTI:
2111         case SIOCDELMULTI:
2112                 /*
2113                  * Update multicast listeners
2114                  */
2115                 /* reset multicast filtering */
2116                 ie_mc_reset(ifp->if_dunit);
2117                 error = 0;
2118                 break;
2119
2120         default:
2121                 error = ether_ioctl(ifp, command, data);
2122                 break;
2123         }
2124         return (error);
2125 }
2126
2127 static void
2128 ie_mc_reset(int unit)
2129 {
2130         struct ie_softc *ie = &ie_softc[unit];
2131         struct ifmultiaddr *ifma;
2132
2133         /*
2134          * Step through the list of addresses.
2135          */
2136         ie->mcast_count = 0;
2137         LIST_FOREACH(ifma, &ie->arpcom.ac_if.if_multiaddrs, ifma_link) {
2138                 if (ifma->ifma_addr->sa_family != AF_LINK)
2139                         continue;
2140
2141                 /* XXX - this is broken... */
2142                 if (ie->mcast_count >= MAXMCAST) {
2143                         ie->arpcom.ac_if.if_flags |= IFF_ALLMULTI;
2144                         ieioctl(&ie->arpcom.ac_if, SIOCSIFFLAGS, NULL,
2145                                 (struct ucred *)NULL);
2146                         goto setflag;
2147                 }
2148                 bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
2149                       &(ie->mcast_addrs[ie->mcast_count]), 6);
2150                 ie->mcast_count++;
2151         }
2152
2153 setflag:
2154         ie->want_mcsetup = 1;
2155 }
2156
2157
2158 #ifdef DEBUG
2159 static void
2160 print_rbd(volatile struct ie_recv_buf_desc * rbd)
2161 {
2162         kprintf("RBD at %p:\n"
2163                "actual %04x, next %04x, buffer %p\n"
2164                "length %04x, mbz %04x\n",
2165                (volatile void *) rbd,
2166                rbd->ie_rbd_actual, rbd->ie_rbd_next,
2167                (void *) rbd->ie_rbd_buffer,
2168                rbd->ie_rbd_length, rbd->mbz);
2169 }
2170
2171 #endif                          /* DEBUG */