2 * Copyright (c) 1992, 1993, University of Vermont and State
3 * Agricultural College.
4 * Copyright (c) 1992, 1993, Garrett A. Wollman.
7 * Copyright (c) 1990, 1991, William F. Jolitz
8 * Copyright (c) 1990, The Regents of the University of California
11 * Copyright (c) 1993, 1994, Charles M. Hannum
13 * EtherExpress 16 support:
14 * Copyright (c) 1993, 1994, 1995, Rodney W. Grimes
15 * Copyright (c) 1997, Aaron C. Smith
17 * All rights reserved.
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
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.
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
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.19 2005/06/14 15:30:58 joerg Exp $
55 * Intel 82586 Ethernet chip
56 * Register, bit, and structure definitions.
58 * Written by GAW with reference to the Clarkson Packet Driver code for this
59 * chip written by Russ Nelson and others.
61 * Intel EtherExpress 16 support from if_ix.c, written by Rodney W. Grimes.
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.
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.
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.
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
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.
111 #include "opt_inet.h"
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>
126 #include <net/ethernet.h>
128 #include <net/ifq_var.h>
129 #include <net/if_types.h>
130 #include <net/if_dl.h>
132 #include <netinet/in.h>
133 #include <netinet/if_ether.h>
135 #include <machine/clock.h>
136 #include <machine/md_var.h>
138 #include <bus/isa/i386/isa_device.h>
139 #include <i386/isa/ic/i82586.h>
140 #include <i386/isa/icu.h>
141 #include "if_iereg.h"
142 #include "if_ie507.h"
143 #include "if_iee16.h"
144 #include "../elink_layer/elink.h"
149 #define IED_RINT 0x01
150 #define IED_TINT 0x02
153 #define IED_READFRAME 0x10
154 static int ie_debug = IED_RNR;
158 DECLARE_DUMMY_MODULE(if_ie);
160 #define IE_BUF_LEN ETHER_MAX_LEN /* length of transmit buffer */
162 /* Forward declaration */
165 static int ieprobe(struct isa_device * dvp);
166 static int ieattach(struct isa_device * dvp);
167 static ointhand2_t ieintr;
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);
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,
178 static void iestart(struct ifnet * ifp);
180 static void el_reset_586(int unit);
181 static void el_chan_attn(int unit);
183 static void sl_reset_586(int unit);
184 static void sl_chan_attn(int unit);
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);
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 struct ether_header *);
209 static v_caddr_t setup_rfa(v_caddr_t ptr, struct ie_softc * ie);
210 static int mc_setup(int, v_caddr_t, volatile struct ie_sys_ctl_block *);
211 static void ie_mc_reset(int unit);
214 static void print_rbd(volatile struct ie_recv_buf_desc * rbd);
216 static int in_ierint = 0;
217 static int in_ietint = 0;
222 * This tells the autoconf code how to set us up.
224 struct isa_driver iedriver = {
225 ieprobe, ieattach, "ie",
238 static const char *ie_hardware_names[] = {
249 sizeof(iscp) == 1+1+2+4 == 8
250 sizeof(scb) == 2+2+2+2+2+2+2+2 == 16
251 NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384
252 sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18
253 sizeof(transmit buffer) == 1512
254 sizeof(transmit buffer desc) == 8
258 NRXBUFS * sizeof(rbd) == NRXBUFS*(2+2+4+2+2) == NRXBUFS*12
259 NRXBUFS * IE_RBUF_SIZE == NRXBUFS*256
261 NRXBUFS should be (16384 - 1946) / (256 + 12) == 14438 / 268 == 53
263 With NRXBUFS == 48, this leaves us 1574 bytes for another command or
264 more buffers. Another transmit command would be 18+8+1512 == 1538
267 Obviously all these would have to be reduced for smaller memory sizes.
268 With a larger memory, it would be possible to roughly double the number of
269 both transmit and receive buffers.
272 #define NFRAMES 8 /* number of receive frames */
273 #define NRXBUFS 48 /* number of buffers to allocate */
274 #define IE_RBUF_SIZE 256 /* size of each buffer, MUST BE POWER OF TWO */
275 #define NTXBUFS 2 /* number of transmit commands */
276 #define IE_TBUF_SIZE ETHER_MAX_LEN /* size of transmit buffer */
279 * Ethernet status, per interface.
281 static struct ie_softc {
282 struct arpcom arpcom;
283 void (*ie_reset_586) (int);
284 void (*ie_chan_attn) (int);
285 enum ie_hardware hard_type;
289 u_short port; /* i/o base address for this interface */
290 caddr_t iomem; /* memory size */
291 caddr_t iomembot; /* memory base address */
293 int bus_use; /* 0 means 16bit, 1 means 8 bit adapter */
300 volatile struct ie_int_sys_conf_ptr *iscp;
301 volatile struct ie_sys_ctl_block *scb;
302 volatile struct ie_recv_frame_desc **rframes; /* nframes worth */
303 volatile struct ie_recv_buf_desc **rbuffs; /* nrxbufs worth */
304 volatile u_char **cbuffs; /* nrxbufs worth */
305 int rfhead, rftail, rbhead, rbtail;
307 volatile struct ie_xmit_cmd **xmit_cmds; /* ntxbufs worth */
308 volatile struct ie_xmit_buf **xmit_buffs; /* ntxbufs worth */
309 volatile u_char **xmit_cbuffs; /* ntxbufs worth */
312 struct ie_en_addr mcast_addrs[MAXMCAST + 1];
315 u_short irq_encoded; /* encoded interrupt on IEE16 */
318 #define MK_24(base, ptr) ((caddr_t)((uintptr_t)ptr - (uintptr_t)base))
319 #define MK_16(base, ptr) ((u_short)(uintptr_t)MK_24(base, ptr))
321 #define PORT ie_softc[unit].port
322 #define MEM ie_softc[unit].iomem
325 ieprobe(struct isa_device *dvp)
335 ret = ee16_probe(dvp);
341 sl_probe(struct isa_device *dvp)
343 int unit = dvp->id_unit;
346 ie_softc[unit].port = dvp->id_iobase;
347 ie_softc[unit].iomembot = dvp->id_maddr;
348 ie_softc[unit].iomem = 0;
349 ie_softc[unit].bus_use = 0;
351 c = inb(PORT + IEATT_REVISION);
352 switch (SL_BOARD(c)) {
354 ie_softc[unit].hard_type = IE_STARLAN10;
355 ie_softc[unit].ie_reset_586 = sl_reset_586;
356 ie_softc[unit].ie_chan_attn = sl_chan_attn;
359 ie_softc[unit].hard_type = IE_EN100;
360 ie_softc[unit].ie_reset_586 = sl_reset_586;
361 ie_softc[unit].ie_chan_attn = sl_chan_attn;
364 ie_softc[unit].hard_type = IE_SLFIBER;
365 ie_softc[unit].ie_reset_586 = sl_reset_586;
366 ie_softc[unit].ie_chan_attn = sl_chan_attn;
370 * Anything else is not recognized or cannot be used.
376 ie_softc[unit].hard_vers = SL_REV(c);
379 * Divine memory size on-board the card. Ususally 16k.
381 find_ie_mem_size(unit);
383 if (!ie_softc[unit].iosize) {
386 dvp->id_msize = ie_softc[unit].iosize;
388 switch (ie_softc[unit].hard_type) {
392 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
397 printf("ie%d: unknown AT&T board type code %d\n", unit,
398 ie_softc[unit].hard_type);
407 el_probe(struct isa_device *dvp)
409 struct ie_softc *sc = &ie_softc[dvp->id_unit];
412 u_char signature[] = "*3COM*";
413 int unit = dvp->id_unit;
416 sc->port = dvp->id_iobase;
417 sc->iomembot = dvp->id_maddr;
420 /* Need this for part of the probe. */
421 sc->ie_reset_586 = el_reset_586;
422 sc->ie_chan_attn = el_chan_attn;
424 /* Reset and put card in CONFIG state without changing address. */
426 outb(ELINK_ID_PORT, 0x00);
427 elink_idseq(ELINK_507_POLY);
428 elink_idseq(ELINK_507_POLY);
429 outb(ELINK_ID_PORT, 0xff);
431 c = inb(PORT + IE507_MADDR);
434 printf("ie%d: can't map 3C507 RAM in high memory\n", unit);
438 /* go to RUN state */
439 outb(ELINK_ID_PORT, 0x00);
440 elink_idseq(ELINK_507_POLY);
441 outb(ELINK_ID_PORT, 0x00);
443 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
445 for (i = 0; i < 6; i++)
446 if (inb(PORT + i) != signature[i])
449 c = inb(PORT + IE507_IRQ) & 0x0f;
451 if (dvp->id_irq != (1 << c)) {
452 printf("ie%d: kernel configured irq %d "
453 "doesn't match board configured irq %d\n",
454 unit, ffs(dvp->id_irq) - 1, c);
457 c = (inb(PORT + IE507_MADDR) & 0x1c) + 0xc0;
459 if (kvtop(dvp->id_maddr) != ((int) c << 12)) {
460 printf("ie%d: kernel configured maddr %llx "
461 "doesn't match board configured maddr %x\n",
462 unit, kvtop(dvp->id_maddr), (int) c << 12);
465 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
467 sc->hard_type = IE_3C507;
468 sc->hard_vers = 0; /* 3C507 has no version number. */
471 * Divine memory size on-board the card.
473 find_ie_mem_size(unit);
476 printf("ie%d: can't find shared memory\n", unit);
477 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
481 dvp->id_msize = sc->iosize;
482 else if (dvp->id_msize != sc->iosize) {
483 printf("ie%d: kernel configured msize %d "
484 "doesn't match board configured msize %d\n",
485 unit, dvp->id_msize, sc->iosize);
486 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
489 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
491 /* Clear the interrupt latch just in case. */
492 outb(PORT + IE507_ICTRL, 1);
499 ni_probe(struct isa_device *dvp)
501 int unit = dvp->id_unit;
504 ie_softc[unit].port = dvp->id_iobase;
505 ie_softc[unit].iomembot = dvp->id_maddr;
506 ie_softc[unit].iomem = 0;
507 ie_softc[unit].bus_use = 1;
509 boardtype = inb(PORT + IEATT_REVISION);
510 c = inb(PORT + IEATT_REVISION + 1);
511 boardtype = boardtype + (c << 8);
513 case 0x5500: /* This is the magic cookie for the NI5210 */
514 ie_softc[unit].hard_type = IE_NI5210;
515 ie_softc[unit].ie_reset_586 = sl_reset_586;
516 ie_softc[unit].ie_chan_attn = sl_chan_attn;
520 * Anything else is not recognized or cannot be used.
526 ie_softc[unit].hard_vers = 0;
529 * Divine memory size on-board the card. Either 8 or 16k.
531 find_ie_mem_size(unit);
533 if (!ie_softc[unit].iosize) {
537 dvp->id_msize = ie_softc[unit].iosize;
538 else if (dvp->id_msize != ie_softc[unit].iosize) {
539 printf("ie%d: kernel configured msize %d "
540 "doesn't match board configured msize %d\n",
541 unit, dvp->id_msize, ie_softc[unit].iosize);
544 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
552 ee16_shutdown(void *sc, int howto)
554 struct ie_softc *ie = (struct ie_softc *)sc;
555 int unit = ie - &ie_softc[0];
557 ee16_reset_586(unit);
558 outb(PORT + IEE16_ECTRL, IEE16_RESET_ASIC);
559 outb(PORT + IEE16_ECTRL, 0);
563 /* Taken almost exactly from Rod's if_ix.c. */
566 ee16_probe(struct isa_device *dvp)
568 struct ie_softc *sc = &ie_softc[dvp->id_unit];
571 int unit = dvp->id_unit;
572 u_short board_id, id_var1, id_var2, checksum = 0;
573 u_short eaddrtemp, irq;
574 u_short pg, adjust, decode, edecode;
578 short irq_translate[] = {0, IRQ9, IRQ3, IRQ4, IRQ5, IRQ10, IRQ11, 0};
579 char irq_encode[] = {0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0};
581 /* Need this for part of the probe. */
582 sc->ie_reset_586 = ee16_reset_586;
583 sc->ie_chan_attn = ee16_chan_attn;
585 /* unsure if this is necessary */
588 /* reset any ee16 at the current iobase */
589 outb(dvp->id_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
590 outb(dvp->id_iobase + IEE16_ECTRL, 0);
593 /* now look for ee16. */
594 board_id = id_var1 = id_var2 = 0;
595 for (i = 0; i < 4; i++) {
596 id_var1 = inb(dvp->id_iobase + IEE16_ID_PORT);
597 id_var2 = ((id_var1 & 0x03) << 2);
598 board_id |= ((id_var1 >> 4) << id_var2);
601 if (board_id != IEE16_ID) {
603 printf("ie%d: unknown board_id: %x\n", unit, board_id);
606 /* need sc->port for ee16_read_eeprom */
607 sc->port = dvp->id_iobase;
608 sc->hard_type = IE_EE16;
611 * The shared RAM location on the EE16 is encoded into bits 3-7 of
612 * EEPROM location 6. We zero the upper byte, and shift the 5 bits
613 * right 3. The resulting number tells us the RAM location.
614 * Because the EE16 supports either 16k or 32k of shared RAM, we
615 * only worry about the 32k locations.
617 * NOTE: if a 64k EE16 exists, it should be added to this switch. then
618 * the ia->ia_msize would need to be set per case statement.
620 * value msize location ===== ===== ======== 0x03 0x8000
621 * 0xCC000 0x06 0x8000 0xD0000 0x0C 0x8000 0xD4000 0x18
627 i = (ee16_read_eeprom(sc, 6) & 0x00ff) >> 3;
645 dvp->id_msize = 0x8000;
646 if (kvtop(dvp->id_maddr) != bd_maddr) {
647 printf("ie%d: kernel configured maddr %llx "
648 "doesn't match board configured maddr %lx\n",
649 unit, kvtop(dvp->id_maddr), bd_maddr);
651 sc->iomembot = dvp->id_maddr;
652 sc->iomem = 0; /* XXX some probes set this and some don't */
653 sc->iosize = dvp->id_msize;
655 /* need to put the 586 in RESET while we access the eeprom. */
656 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
658 /* read the eeprom and checksum it, should == IEE16_ID */
659 for (i = 0; i < 0x40; i++)
660 checksum += ee16_read_eeprom(sc, i);
662 if (checksum != IEE16_ID) {
663 printf("ie%d: invalid eeprom checksum: %x\n", unit, checksum);
667 * Size and test the memory on the board. The size of the memory
668 * can be one of 16k, 32k, 48k or 64k. It can be located in the
669 * address range 0xC0000 to 0xEFFFF on 16k boundaries.
671 * If the size does not match the passed in memory allocation size
672 * issue a warning, but continue with the minimum of the two sizes.
675 switch (dvp->id_msize) {
677 case 32768: /* XXX Only support 32k and 64k right now */
682 printf("ie%d: mapped memory size %d not supported\n", unit,
685 break; /* NOTREACHED */
688 if ((kvtop(dvp->id_maddr) < 0xC0000) ||
689 (kvtop(dvp->id_maddr) + sc->iosize > 0xF0000)) {
690 printf("ie%d: mapped memory location %p out of range\n", unit,
691 (void *)dvp->id_maddr);
694 pg = (kvtop(dvp->id_maddr) & 0x3C000) >> 14;
695 adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
696 decode = ((1 << (sc->iosize / 16384)) - 1) << pg;
697 edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
699 /* ZZZ This should be checked against eeprom location 6, low byte */
700 outb(PORT + IEE16_MEMDEC, decode & 0xFF);
701 /* ZZZ This should be checked against eeprom location 1, low byte */
702 outb(PORT + IEE16_MCTRL, adjust);
703 /* ZZZ Now if I could find this one I would have it made */
704 outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
705 /* ZZZ I think this is location 6, high byte */
706 outb(PORT + IEE16_MECTRL, edecode); /* XXX disable Exxx */
708 (void) kvtop(dvp->id_maddr);
711 * first prime the stupid bart DRAM controller so that it works,
712 * then zero out all of memory.
714 bzero(sc->iomembot, 32);
715 bzero(sc->iomembot, sc->iosize);
718 * Get the encoded interrupt number from the EEPROM, check it
719 * against the passed in IRQ. Issue a warning if they do not match.
720 * Always use the passed in IRQ, not the one in the EEPROM.
722 irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
723 irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
724 irq = irq_translate[irq];
725 if (dvp->id_irq > 0) {
726 if (irq != dvp->id_irq) {
727 printf("ie%d: WARNING: board configured "
728 "at irq %u, using %u\n",
729 dvp->id_unit, dvp->id_irq, irq);
735 sc->irq_encoded = irq_encode[ffs(irq) - 1];
738 * Get the hardware ethernet address from the EEPROM and save it in
739 * the softc for use by the 586 setup code.
741 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
742 sc->arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
743 sc->arpcom.ac_enaddr[0] = eaddrtemp >> 8;
744 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
745 sc->arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
746 sc->arpcom.ac_enaddr[2] = eaddrtemp >> 8;
747 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
748 sc->arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
749 sc->arpcom.ac_enaddr[4] = eaddrtemp >> 8;
751 /* disable the board interrupts */
752 outb(PORT + IEE16_IRQ, sc->irq_encoded);
754 /* enable loopback to keep bad packets off the wire */
755 if (sc->hard_type == IE_EE16) {
756 bart_config = inb(PORT + IEE16_CONFIG);
757 bart_config |= IEE16_BART_LOOPBACK;
758 bart_config |= IEE16_BART_MCS16_TEST;/* inb doesn't get bit! */
759 outb(PORT + IEE16_CONFIG, bart_config);
760 bart_config = inb(PORT + IEE16_CONFIG);
762 /* take the board out of reset state */
763 outb(PORT + IEE16_ECTRL, 0);
766 if (!check_ie_present(unit, dvp->id_maddr, sc->iosize))
769 return (16); /* return the number of I/O ports */
773 * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
776 ieattach(struct isa_device *dvp)
779 int unit = dvp->id_unit;
780 struct ie_softc *ie = &ie_softc[unit];
781 struct ifnet *ifp = &ie->arpcom.ac_if;
784 dvp->id_ointr = ieintr;
787 * based on the amount of memory we have, allocate our tx and rx
790 factor = dvp->id_msize / 16384;
791 ie->nframes = factor * NFRAMES;
792 ie->nrxbufs = factor * NRXBUFS;
793 ie->ntxbufs = factor * NTXBUFS;
796 * Since all of these guys are arrays of pointers, allocate as one
797 * big chunk and dole out accordingly.
799 allocsize = sizeof(void *) * (ie->nframes
801 + (ie->ntxbufs * 3));
802 ie->rframes = malloc(allocsize, M_DEVBUF, M_WAITOK);
804 (volatile struct ie_recv_buf_desc **)&ie->rframes[ie->nframes];
805 ie->cbuffs = (volatile u_char **)&ie->rbuffs[ie->nrxbufs];
807 (volatile struct ie_xmit_cmd **)&ie->cbuffs[ie->nrxbufs];
809 (volatile struct ie_xmit_buf **)&ie->xmit_cmds[ie->ntxbufs];
810 ie->xmit_cbuffs = (volatile u_char **)&ie->xmit_buffs[ie->ntxbufs];
813 if_initname(ifp, iedriver.name, unit);
814 ifp->if_mtu = ETHERMTU;
815 if_printf(ifp, "<%s R%d>", ie_hardware_names[ie->hard_type],
818 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
819 ifp->if_start = iestart;
820 ifp->if_ioctl = ieioctl;
821 ifp->if_init = ieinit;
822 ifp->if_type = IFT_ETHER;
825 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
826 ifq_set_ready(&ifp->if_snd);
828 if (ie->hard_type == IE_EE16)
829 EVENTHANDLER_REGISTER(shutdown_post_sync, ee16_shutdown,
830 ie, SHUTDOWN_PRI_DEFAULT);
832 ether_ifattach(ifp, ie->arpcom.ac_enaddr);
837 * What to do upon receipt of an interrupt.
842 struct ie_softc *ie = &ie_softc[unit];
845 /* Clear the interrupt latch on the 3C507. */
846 if (ie->hard_type == IE_3C507
847 && (inb(PORT + IE507_CTRL) & EL_CTRL_INTL))
848 outb(PORT + IE507_ICTRL, 1);
850 /* disable interrupts on the EE16. */
851 if (ie->hard_type == IE_EE16)
852 outb(PORT + IEE16_IRQ, ie->irq_encoded);
854 status = ie->scb->ie_status;
858 /* Don't ack interrupts which we didn't receive */
859 ie_ack(ie->scb, IE_ST_WHENCE & status, unit, ie->ie_chan_attn);
861 if (status & (IE_ST_RECV | IE_ST_RNR)) {
864 if (ie_debug & IED_RINT)
865 printf("ie%d: rint\n", unit);
872 if (status & IE_ST_DONE) {
875 if (ie_debug & IED_TINT)
876 printf("ie%d: tint\n", unit);
883 if (status & IE_ST_RNR) {
885 if (ie_debug & IED_RNR)
886 printf("ie%d: rnr\n", unit);
891 if ((status & IE_ST_ALLDONE)
892 && (ie_debug & IED_CNA))
893 printf("ie%d: cna\n", unit);
896 if ((status = ie->scb->ie_status) & IE_ST_WHENCE)
899 /* Clear the interrupt latch on the 3C507. */
900 if (ie->hard_type == IE_3C507)
901 outb(PORT + IE507_ICTRL, 1);
903 /* enable interrupts on the EE16. */
904 if (ie->hard_type == IE_EE16)
905 outb(PORT + IEE16_IRQ, ie->irq_encoded | IEE16_IRQ_ENABLE);
910 * Process a received-frame interrupt.
913 ierint(int unit, struct ie_softc *ie)
916 static int timesthru = 1024;
920 status = ie->rframes[i]->ie_fd_status;
922 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
923 ie->arpcom.ac_if.if_ipackets++;
925 ie->arpcom.ac_if.if_ierrors +=
926 ie->scb->ie_err_crc +
927 ie->scb->ie_err_align +
928 ie->scb->ie_err_resource +
929 ie->scb->ie_err_overrun;
930 ie->scb->ie_err_crc = 0;
931 ie->scb->ie_err_align = 0;
932 ie->scb->ie_err_resource = 0;
933 ie->scb->ie_err_overrun = 0;
936 ie_readframe(unit, ie, i);
938 if (status & IE_FD_RNR) {
939 if (!(ie->scb->ie_status & IE_RU_READY)) {
940 ie->rframes[0]->ie_fd_next =
941 MK_16(MEM, ie->rbuffs[0]);
942 ie->scb->ie_recv_list =
943 MK_16(MEM, ie->rframes[0]);
944 command_and_wait(unit, IE_RU_START,
950 i = (i + 1) % ie->nframes;
956 * Process a command-complete interrupt. These are only generated by
957 * the transmission of frames. This routine is deceptively simple, since
958 * most of the real work is done by iestart().
961 ietint(int unit, struct ie_softc *ie)
966 ie->arpcom.ac_if.if_timer = 0;
967 ie->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
969 for (i = 0; i < ie->xmit_count; i++) {
970 status = ie->xmit_cmds[i]->ie_xmit_status;
972 if (status & IE_XS_LATECOLL) {
973 printf("ie%d: late collision\n", unit);
974 ie->arpcom.ac_if.if_collisions++;
975 ie->arpcom.ac_if.if_oerrors++;
976 } else if (status & IE_XS_NOCARRIER) {
977 printf("ie%d: no carrier\n", unit);
978 ie->arpcom.ac_if.if_oerrors++;
979 } else if (status & IE_XS_LOSTCTS) {
980 printf("ie%d: lost CTS\n", unit);
981 ie->arpcom.ac_if.if_oerrors++;
982 } else if (status & IE_XS_UNDERRUN) {
983 printf("ie%d: DMA underrun\n", unit);
984 ie->arpcom.ac_if.if_oerrors++;
985 } else if (status & IE_XS_EXCMAX) {
986 printf("ie%d: too many collisions\n", unit);
987 ie->arpcom.ac_if.if_collisions += 16;
988 ie->arpcom.ac_if.if_oerrors++;
990 ie->arpcom.ac_if.if_opackets++;
991 ie->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL;
997 * If multicast addresses were added or deleted while we were
998 * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
999 * that we should do it.
1001 if (ie->want_mcsetup) {
1002 mc_setup(unit, (v_caddr_t) ie->xmit_cbuffs[0], ie->scb);
1003 ie->want_mcsetup = 0;
1005 /* Wish I knew why this seems to be necessary... */
1006 ie->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
1008 iestart(&ie->arpcom.ac_if);
1009 return (0); /* shouldn't be necessary */
1013 * Process a receiver-not-ready interrupt. I believe that we get these
1014 * when there aren't enough buffers to go around. For now (FIXME), we
1015 * just restart the receiver, and hope everything's ok.
1018 iernr(int unit, struct ie_softc *ie)
1021 setup_rfa((v_caddr_t) ie->rframes[0], ie);
1023 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1024 command_and_wait(unit, IE_RU_START, 0, 0);
1026 /* This doesn't work either, but it doesn't hang either. */
1027 command_and_wait(unit, IE_RU_DISABLE, 0, 0); /* just in case */
1028 setup_rfa((v_caddr_t) ie->rframes[0], ie); /* ignore cast-qual */
1030 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1031 command_and_wait(unit, IE_RU_START, 0, 0); /* was ENABLE */
1034 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
1036 ie->arpcom.ac_if.if_ierrors++;
1041 * Compare two Ether/802 addresses for equality, inlined and
1042 * unrolled for speed. I'd love to have an inline assembler
1043 * version of this...
1046 ether_equal(u_char * one, u_char * two)
1048 if (one[0] != two[0])
1050 if (one[1] != two[1])
1052 if (one[2] != two[2])
1054 if (one[3] != two[3])
1056 if (one[4] != two[4])
1058 if (one[5] != two[5])
1064 * Determine quickly whether we should bother reading in this packet.
1065 * This depends on whether BPF and/or bridging is enabled, whether we
1066 * are receiving multicast address, and whether promiscuous mode is enabled.
1067 * We assume that if IFF_PROMISC is set, then *somebody* wants to see
1068 * all incoming packets.
1071 check_eh(struct ie_softc *ie, struct ether_header *eh)
1073 /* Optimize the common case: normal operation. We've received
1074 either a unicast with our dest or a multicast packet. */
1075 if (ie->promisc == 0) {
1078 /* If not multicast, it's definitely for us */
1079 if ((eh->ether_dhost[0] & 1) == 0)
1082 /* Accept broadcasts (loose but fast check) */
1083 if (eh->ether_dhost[0] == 0xff)
1086 /* Compare against our multicast addresses */
1087 for (i = 0; i < ie->mcast_count; i++) {
1088 if (ether_equal(eh->ether_dhost,
1089 (u_char *)&ie->mcast_addrs[i]))
1095 /* Always accept packets when in promiscuous mode */
1096 if ((ie->promisc & IFF_PROMISC) != 0)
1099 /* Always accept packets directed at us */
1100 if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1103 /* Must have IFF_ALLMULTI but not IFF_PROMISC set. The chip is
1104 actually in promiscuous mode, so discard unicast packets. */
1105 return((eh->ether_dhost[0] & 1) != 0);
1109 * We want to isolate the bits that have meaning... This assumes that
1110 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds
1111 * the size of the buffer, then we are screwed anyway.
1114 ie_buflen(struct ie_softc * ie, int head)
1116 return (ie->rbuffs[head]->ie_rbd_actual
1117 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
1121 ie_packet_len(int unit, struct ie_softc * ie)
1124 int head = ie->rbhead;
1128 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1130 print_rbd(ie->rbuffs[ie->rbhead]);
1133 "ie%d: receive descriptors out of sync at %d\n",
1138 i = ie->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
1140 acc += ie_buflen(ie, head);
1141 head = (head + 1) % ie->nrxbufs;
1148 * Read data off the interface, and turn it into an mbuf chain.
1150 * This code is DRAMATICALLY different from the previous version; this
1151 * version tries to allocate the entire mbuf chain up front, given the
1152 * length of the data available. This enables us to allocate mbuf
1153 * clusters in many situations where before we would have had a long
1154 * chain of partially-full mbufs. This should help to speed up the
1155 * operation considerably. (Provided that it works, of course.)
1158 ieget(int unit, struct ie_softc *ie, struct mbuf **mp, struct ether_header *ehp)
1160 struct mbuf *m, *top, **mymp;
1167 totlen = ie_packet_len(unit, ie);
1174 * Snarf the Ethernet header.
1176 bcopy((v_caddr_t) ie->cbuffs[i], (caddr_t) ehp, sizeof *ehp);
1177 /* ignore cast-qual warning here */
1180 * As quickly as possible, check if this packet is for us. If not,
1181 * don't waste a single cycle copying the rest of the packet in.
1182 * This is only a consideration when FILTER is defined; i.e., when
1183 * we are either running BPF or doing multicasting.
1185 if (!check_eh(ie, ehp)) {
1186 ie_drop_packet_buffer(unit, ie);
1187 ie->arpcom.ac_if.if_ierrors--; /* just this case, it's not an
1192 totlen -= (offset = sizeof *ehp);
1194 MGETHDR(*mp, MB_DONTWAIT, MT_DATA);
1196 ie_drop_packet_buffer(unit, ie);
1200 m->m_pkthdr.rcvif = &ie->arpcom.ac_if;
1202 resid = m->m_pkthdr.len = totlen;
1207 * This loop goes through and allocates mbufs for all the data we
1208 * will be copying in. It does not actually do the copying yet.
1210 do { /* while(resid > 0) */
1212 * Try to allocate an mbuf to hold the data that we have.
1213 * If we already allocated one, just get another one and
1214 * stick it on the end (eventually). If we don't already
1215 * have one, try to allocate an mbuf cluster big enough to
1216 * hold the whole packet, if we think it's reasonable, or a
1217 * single mbuf which may or may not be big enough. Got that?
1220 MGET(m, MB_DONTWAIT, MT_DATA);
1223 ie_drop_packet_buffer(unit, ie);
1228 if (resid >= MINCLSIZE) {
1229 MCLGET(m, MB_DONTWAIT);
1230 if (m->m_flags & M_EXT)
1231 m->m_len = min(resid, MCLBYTES);
1233 if (resid < m->m_len) {
1234 if (!top && resid + max_linkhdr <= m->m_len)
1235 m->m_data += max_linkhdr;
1242 } while (resid > 0);
1250 * Now we take the mbuf chain (hopefully only one mbuf most of the
1251 * time) and stuff the data into it. There are no possible failures
1252 * at or after this point.
1254 while (resid > 0) { /* while there's stuff left */
1255 int thislen = ie_buflen(ie, head) - offset;
1258 * If too much data for the current mbuf, then fill the
1259 * current one up, go to the next one, and try again.
1261 if (thislen > m->m_len - thismboff) {
1262 int newlen = m->m_len - thismboff;
1264 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1265 mtod(m, v_caddr_t) +thismboff, (unsigned) newlen);
1266 /* ignore cast-qual warning */
1268 thismboff = 0; /* new mbuf, so no offset */
1269 offset += newlen; /* we are now this far into
1271 resid -= newlen; /* so there is this much left
1276 * If there is more than enough space in the mbuf to hold
1277 * the contents of this buffer, copy everything in, advance
1278 * pointers, and so on.
1280 if (thislen < m->m_len - thismboff) {
1281 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1282 mtod(m, caddr_t) +thismboff, (unsigned) thislen);
1283 thismboff += thislen; /* we are this far into the
1285 resid -= thislen; /* and this much is left */
1289 * Otherwise, there is exactly enough space to put this
1290 * buffer's contents into the current mbuf. Do the
1291 * combination of the above actions.
1293 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1294 mtod(m, caddr_t) + thismboff, (unsigned) thislen);
1296 thismboff = 0; /* new mbuf, start at the beginning */
1297 resid -= thislen; /* and we are this far through */
1300 * Advance all the pointers. We can get here from either of
1301 * the last two cases, but never the first.
1305 ie->rbuffs[head]->ie_rbd_actual = 0;
1306 ie->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
1307 ie->rbhead = head = (head + 1) % ie->nrxbufs;
1308 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1309 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1313 * Unless something changed strangely while we were doing the copy,
1314 * we have now copied everything in from the shared memory. This
1315 * means that we are done.
1321 * Read frame NUM from unit UNIT (pre-cached as IE).
1323 * This routine reads the RFD at NUM, and copies in the buffers from
1324 * the list of RBD, then rotates the RBD and RFD lists so that the receiver
1325 * doesn't start complaining. Trailers are DROPPED---there's no point
1326 * in wasting time on confusing code to deal with them. Hopefully,
1327 * this machine will never ARP for trailers anyway.
1330 ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
1332 struct ie_recv_frame_desc rfd;
1334 struct ether_header eh;
1336 bcopy((v_caddr_t) (ie->rframes[num]), &rfd,
1337 sizeof(struct ie_recv_frame_desc));
1340 * Immediately advance the RFD list, since we we have copied ours
1343 ie->rframes[num]->ie_fd_status = 0;
1344 ie->rframes[num]->ie_fd_last |= IE_FD_LAST;
1345 ie->rframes[ie->rftail]->ie_fd_last &= ~IE_FD_LAST;
1346 ie->rftail = (ie->rftail + 1) % ie->nframes;
1347 ie->rfhead = (ie->rfhead + 1) % ie->nframes;
1349 if (rfd.ie_fd_status & IE_FD_OK) {
1350 if (ieget(unit, ie, &m, &eh)) {
1351 ie->arpcom.ac_if.if_ierrors++; /* this counts as an
1357 if (ie_debug & IED_READFRAME) {
1358 printf("ie%d: frame from ether %6D type %x\n", unit,
1359 eh.ether_shost, ":", (unsigned) eh.ether_type);
1361 if (ntohs(eh.ether_type) > ETHERTYPE_TRAIL
1362 && ntohs(eh.ether_type) < (ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER))
1363 printf("received trailer!\n");
1370 * Finally pass this packet up to higher layers.
1372 ether_input(&ie->arpcom.ac_if, &eh, m);
1376 ie_drop_packet_buffer(int unit, struct ie_softc * ie)
1382 * This means we are somehow out of sync. So, we reset the
1385 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1387 print_rbd(ie->rbuffs[ie->rbhead]);
1389 log(LOG_ERR, "ie%d: receive descriptors out of sync at %d\n",
1394 i = ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1396 ie->rbuffs[ie->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1397 ie->rbuffs[ie->rbhead]->ie_rbd_actual = 0;
1398 ie->rbhead = (ie->rbhead + 1) % ie->nrxbufs;
1399 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1400 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1406 * Start transmission on an interface.
1409 iestart(struct ifnet *ifp)
1411 struct ie_softc *ie = ifp->if_softc;
1412 struct mbuf *m0, *m;
1413 volatile unsigned char *buffer;
1417 * This is not really volatile, in this routine, but it makes gcc
1420 volatile u_short *bptr = &ie->scb->ie_command_list;
1422 if (!(ifp->if_flags & IFF_RUNNING))
1424 if (ifp->if_flags & IFF_OACTIVE)
1428 m = ifq_dequeue(&ie->arpcom.ac_if.if_snd);
1432 buffer = ie->xmit_cbuffs[ie->xmit_count];
1435 for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) {
1436 bcopy(mtod(m, caddr_t), buffer, m->m_len);
1442 len = max(len, ETHER_MIN_LEN);
1445 * See if bpf is listening on this interface, let it see the
1446 * packet before we commit it to the wire.
1448 BPF_TAP(&ie->arpcom.ac_if,
1449 __DEVOLATILE(u_char *, ie->xmit_cbuffs[ie->xmit_count]),
1452 ie->xmit_buffs[ie->xmit_count]->ie_xmit_flags =
1454 ie->xmit_buffs[ie->xmit_count]->ie_xmit_next = 0xffff;
1455 ie->xmit_buffs[ie->xmit_count]->ie_xmit_buf =
1456 MK_24(ie->iomem, ie->xmit_cbuffs[ie->xmit_count]);
1458 ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT;
1459 ie->xmit_cmds[ie->xmit_count]->ie_xmit_status = 0;
1460 ie->xmit_cmds[ie->xmit_count]->ie_xmit_desc =
1461 MK_16(ie->iomem, ie->xmit_buffs[ie->xmit_count]);
1463 *bptr = MK_16(ie->iomem, ie->xmit_cmds[ie->xmit_count]);
1464 bptr = &ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_link;
1466 } while (ie->xmit_count < ie->ntxbufs);
1469 * If we queued up anything for transmission, send it.
1471 if (ie->xmit_count) {
1472 ie->xmit_cmds[ie->xmit_count - 1]->com.ie_cmd_cmd |=
1473 IE_CMD_LAST | IE_CMD_INTR;
1476 * By passing the command pointer as a null, we tell
1477 * command_and_wait() to pretend that this isn't an action
1478 * command. I wish I understood what was happening here.
1480 command_and_wait(ifp->if_dunit, IE_CU_START, 0, 0);
1481 ifp->if_flags |= IFF_OACTIVE;
1487 * Check to see if there's an 82586 out there.
1490 check_ie_present(int unit, caddr_t where, unsigned size)
1492 volatile struct ie_sys_conf_ptr *scp;
1493 volatile struct ie_int_sys_conf_ptr *iscp;
1494 volatile struct ie_sys_ctl_block *scb;
1499 realbase = (uintptr_t) where + size - (1 << 24);
1501 scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t)
1502 (realbase + IE_SCP_ADDR);
1503 bzero((volatile char *) scp, sizeof *scp);
1506 * First we put the ISCP at the bottom of memory; this tests to make
1507 * sure that our idea of the size of memory is the same as the
1508 * controller's. This is NOT where the ISCP will be in normal
1511 iscp = (volatile struct ie_int_sys_conf_ptr *) where;
1512 bzero((volatile char *)iscp, sizeof *iscp);
1514 scb = (volatile struct ie_sys_ctl_block *) where;
1515 bzero((volatile char *)scb, sizeof *scb);
1517 scp->ie_bus_use = ie_softc[unit].bus_use; /* 8-bit or 16-bit */
1518 scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1519 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1522 iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1524 (*ie_softc[unit].ie_reset_586) (unit);
1525 (*ie_softc[unit].ie_chan_attn) (unit);
1527 DELAY(100); /* wait a while... */
1529 if (iscp->ie_busy) {
1534 * Now relocate the ISCP to its real home, and reset the controller
1537 iscp = (void *) Align((caddr_t) (uintptr_t)
1538 (realbase + IE_SCP_ADDR -
1539 sizeof(struct ie_int_sys_conf_ptr)));
1540 bzero((volatile char *) iscp, sizeof *iscp); /* ignore cast-qual */
1542 scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1543 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1546 iscp->ie_scb_offset = MK_16(realbase, scb);
1548 (*ie_softc[unit].ie_reset_586) (unit);
1549 (*ie_softc[unit].ie_chan_attn) (unit);
1553 if (iscp->ie_busy) {
1557 ie_softc[unit].iosize = size;
1558 ie_softc[unit].iomem = (caddr_t) (uintptr_t) realbase;
1560 ie_softc[unit].iscp = iscp;
1561 ie_softc[unit].scb = scb;
1564 * Acknowledge any interrupts we may have caused...
1566 ie_ack(scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1574 * Divine the memory size of ie board UNIT.
1575 * Better hope there's nothing important hiding just below the ie card...
1578 find_ie_mem_size(int unit)
1582 ie_softc[unit].iosize = 0;
1584 for (size = 65536; size >= 8192; size -= 8192) {
1585 if (check_ie_present(unit, ie_softc[unit].iomembot, size)) {
1594 el_reset_586(int unit)
1596 outb(PORT + IE507_CTRL, EL_CTRL_RESET);
1598 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
1603 sl_reset_586(int unit)
1605 outb(PORT + IEATT_RESET, 0);
1609 ee16_reset_586(int unit)
1611 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
1613 outb(PORT + IEE16_ECTRL, 0);
1618 el_chan_attn(int unit)
1620 outb(PORT + IE507_ATTN, 1);
1624 sl_chan_attn(int unit)
1626 outb(PORT + IEATT_ATTN, 0);
1630 ee16_chan_attn(int unit)
1632 outb(PORT + IEE16_ATTN, 0);
1636 ee16_read_eeprom(struct ie_softc *sc, int location)
1640 ectrl = inb(sc->port + IEE16_ECTRL);
1641 ectrl &= IEE16_ECTRL_MASK;
1642 ectrl |= IEE16_ECTRL_EECS;
1643 outb(sc->port + IEE16_ECTRL, ectrl);
1645 ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
1646 ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
1647 edata = ee16_eeprom_inbits(sc);
1648 ectrl = inb(sc->port + IEE16_ECTRL);
1649 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
1650 outb(sc->port + IEE16_ECTRL, ectrl);
1651 ee16_eeprom_clock(sc, 1);
1652 ee16_eeprom_clock(sc, 0);
1657 ee16_eeprom_outbits(struct ie_softc *sc, int edata, int count)
1661 ectrl = inb(sc->port + IEE16_ECTRL);
1662 ectrl &= ~IEE16_RESET_ASIC;
1663 for (i = count - 1; i >= 0; i--) {
1664 ectrl &= ~IEE16_ECTRL_EEDI;
1665 if (edata & (1 << i)) {
1666 ectrl |= IEE16_ECTRL_EEDI;
1668 outb(sc->port + IEE16_ECTRL, ectrl);
1669 DELAY(1); /* eeprom data must be setup for 0.4 uSec */
1670 ee16_eeprom_clock(sc, 1);
1671 ee16_eeprom_clock(sc, 0);
1673 ectrl &= ~IEE16_ECTRL_EEDI;
1674 outb(sc->port + IEE16_ECTRL, ectrl);
1675 DELAY(1); /* eeprom data must be held for 0.4 uSec */
1679 ee16_eeprom_inbits(struct ie_softc *sc)
1681 int ectrl, edata, i;
1683 ectrl = inb(sc->port + IEE16_ECTRL);
1684 ectrl &= ~IEE16_RESET_ASIC;
1685 for (edata = 0, i = 0; i < 16; i++) {
1687 ee16_eeprom_clock(sc, 1);
1688 ectrl = inb(sc->port + IEE16_ECTRL);
1689 if (ectrl & IEE16_ECTRL_EEDO) {
1692 ee16_eeprom_clock(sc, 0);
1698 ee16_eeprom_clock(struct ie_softc *sc, int state)
1702 ectrl = inb(sc->port + IEE16_ECTRL);
1703 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
1705 ectrl |= IEE16_ECTRL_EESK;
1707 outb(sc->port + IEE16_ECTRL, ectrl);
1708 DELAY(9); /* EESK must be stable for 8.38 uSec */
1711 static __inline void
1712 ee16_interrupt_enable(struct ie_softc *sc)
1715 outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1720 sl_read_ether(int unit, unsigned char addr[6])
1724 for (i = 0; i < 6; i++)
1725 addr[i] = inb(PORT + i);
1738 printf("ie%d: reset\n", unit);
1739 ie_softc[unit].arpcom.ac_if.if_flags &= ~IFF_UP;
1740 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, (struct ucred *)NULL);
1743 * Stop i82586 dead in its tracks.
1745 if (command_and_wait(unit, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1746 printf("ie%d: abort commands timed out\n", unit);
1748 if (command_and_wait(unit, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1749 printf("ie%d: disable commands timed out\n", unit);
1752 if (!check_ie_present(unit, ie_softc[unit].iomembot,
1753 e_softc[unit].iosize))
1754 panic("ie disappeared!");
1757 ie_softc[unit].arpcom.ac_if.if_flags |= IFF_UP;
1758 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, (struct ucred *)NULL);
1764 * Send a command to the controller and wait for it to either
1765 * complete or be accepted, depending on the command. If the
1766 * command pointer is null, then pretend that the command is
1767 * not an action command. If the command pointer is not null,
1768 * and the command is an action command, wait for
1769 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1773 command_and_wait(int unit, int cmd, volatile void *pcmd, int mask)
1775 volatile struct ie_cmd_common *cc = pcmd;
1777 ie_softc[unit].scb->ie_command = (u_short) cmd;
1779 if (IE_ACTION_COMMAND(cmd) && pcmd) {
1781 * According to the packet driver, the minimum timeout
1782 * should be .369 seconds.
1786 (*ie_softc[unit].ie_chan_attn) (unit);
1789 * Now spin-lock waiting for status. This is not a very
1790 * nice thing to do, but I haven't figured out how, or
1791 * indeed if, we can put the process waiting for action to
1792 * sleep. (We may be getting called through some other
1793 * timeout running in the kernel.)
1795 while (--timer > 0) {
1796 if (cc->ie_cmd_status & mask)
1807 * Otherwise, just wait for the command to be accepted.
1809 (*ie_softc[unit].ie_chan_attn) (unit);
1811 while (ie_softc[unit].scb->ie_command); /* spin lock */
1818 * Run the time-domain reflectometer...
1821 run_tdr(int unit, volatile struct ie_tdr_cmd *cmd)
1825 cmd->com.ie_cmd_status = 0;
1826 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1827 cmd->com.ie_cmd_link = 0xffff;
1828 cmd->ie_tdr_time = 0;
1830 ie_softc[unit].scb->ie_command_list = MK_16(MEM, cmd);
1831 cmd->ie_tdr_time = 0;
1833 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL))
1836 result = cmd->ie_tdr_time;
1838 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit,
1839 ie_softc[unit].ie_chan_attn);
1841 if (result & IE_TDR_SUCCESS)
1844 if (result & IE_TDR_XCVR) {
1845 printf("ie%d: transceiver problem\n", unit);
1846 } else if (result & IE_TDR_OPEN) {
1847 printf("ie%d: TDR detected an open %d clocks away\n", unit,
1848 result & IE_TDR_TIME);
1849 } else if (result & IE_TDR_SHORT) {
1850 printf("ie%d: TDR detected a short %d clocks away\n", unit,
1851 result & IE_TDR_TIME);
1853 printf("ie%d: TDR returned unknown status %x\n", unit, result);
1858 start_receiver(int unit)
1862 ie_softc[unit].scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1863 command_and_wait(unit, IE_RU_START, 0, 0);
1865 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1871 * Here is a helper routine for iernr() and ieinit(). This sets up
1875 setup_rfa(v_caddr_t ptr, struct ie_softc * ie)
1877 volatile struct ie_recv_frame_desc *rfd = (volatile void *)ptr;
1878 volatile struct ie_recv_buf_desc *rbd;
1880 int unit = ie - &ie_softc[0];
1882 /* First lay them out */
1883 for (i = 0; i < ie->nframes; i++) {
1884 ie->rframes[i] = rfd;
1885 bzero((volatile char *) rfd, sizeof *rfd); /* ignore cast-qual */
1889 ptr = Alignvol(rfd); /* ignore cast-qual */
1891 /* Now link them together */
1892 for (i = 0; i < ie->nframes; i++) {
1893 ie->rframes[i]->ie_fd_next =
1894 MK_16(MEM, ie->rframes[(i + 1) % ie->nframes]);
1897 /* Finally, set the EOL bit on the last one. */
1898 ie->rframes[ie->nframes - 1]->ie_fd_last |= IE_FD_LAST;
1901 * Now lay out some buffers for the incoming frames. Note that we
1902 * set aside a bit of slop in each buffer, to make sure that we have
1903 * enough space to hold a single frame in every buffer.
1905 rbd = (volatile void *) ptr;
1907 for (i = 0; i < ie->nrxbufs; i++) {
1908 ie->rbuffs[i] = rbd;
1909 bzero((volatile char *)rbd, sizeof *rbd);
1910 ptr = Alignvol(ptr + sizeof *rbd);
1911 rbd->ie_rbd_length = IE_RBUF_SIZE;
1912 rbd->ie_rbd_buffer = MK_24(MEM, ptr);
1913 ie->cbuffs[i] = (volatile void *) ptr;
1914 ptr += IE_RBUF_SIZE;
1915 rbd = (volatile void *) ptr;
1918 /* Now link them together */
1919 for (i = 0; i < ie->nrxbufs; i++) {
1920 ie->rbuffs[i]->ie_rbd_next =
1921 MK_16(MEM, ie->rbuffs[(i + 1) % ie->nrxbufs]);
1924 /* Tag EOF on the last one */
1925 ie->rbuffs[ie->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST;
1928 * We use the head and tail pointers on receive to keep track of the
1929 * order in which RFDs and RBDs are used.
1932 ie->rftail = ie->nframes - 1;
1934 ie->rbtail = ie->nrxbufs - 1;
1936 ie->scb->ie_recv_list = MK_16(MEM, ie->rframes[0]);
1937 ie->rframes[0]->ie_fd_buf_desc = MK_16(MEM, ie->rbuffs[0]);
1939 ptr = Alignvol(ptr);
1944 * Run the multicast setup command.
1947 mc_setup(int unit, v_caddr_t ptr,
1948 volatile struct ie_sys_ctl_block * scb)
1950 struct ie_softc *ie = &ie_softc[unit];
1951 volatile struct ie_mcast_cmd *cmd = (volatile void *) ptr;
1953 cmd->com.ie_cmd_status = 0;
1954 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1955 cmd->com.ie_cmd_link = 0xffff;
1957 /* ignore cast-qual */
1958 bcopy((v_caddr_t) ie->mcast_addrs, (v_caddr_t) cmd->ie_mcast_addrs,
1959 ie->mcast_count * sizeof *ie->mcast_addrs);
1961 cmd->ie_mcast_bytes = ie->mcast_count * 6; /* grrr... */
1963 scb->ie_command_list = MK_16(MEM, cmd);
1964 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
1965 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1966 printf("ie%d: multicast address setup command failed\n", unit);
1973 * This routine takes the environment generated by check_ie_present()
1974 * and adds to it all the other structures we need to operate the adapter.
1975 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1976 * starting the receiver unit, and clearing interrupts.
1982 struct ie_softc *ie = xsc;
1983 volatile struct ie_sys_ctl_block *scb = ie->scb;
1986 int unit = ie->unit;
1990 ptr = Alignvol((volatile char *) scb + sizeof *scb);
1993 * Send the configure command first.
1996 volatile struct ie_config_cmd *cmd = (volatile void *) ptr;
1998 ie_setup_config(cmd, ie->promisc,
1999 ie->hard_type == IE_STARLAN10);
2000 cmd->com.ie_cmd_status = 0;
2001 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
2002 cmd->com.ie_cmd_link = 0xffff;
2004 scb->ie_command_list = MK_16(MEM, cmd);
2006 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2007 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2009 printf("ie%d: configure command failed\n", unit);
2014 * Now send the Individual Address Setup command.
2017 volatile struct ie_iasetup_cmd *cmd = (volatile void *) ptr;
2019 cmd->com.ie_cmd_status = 0;
2020 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
2021 cmd->com.ie_cmd_link = 0xffff;
2023 bcopy((volatile char *)ie_softc[unit].arpcom.ac_enaddr,
2024 (volatile char *)&cmd->ie_address, sizeof cmd->ie_address);
2025 scb->ie_command_list = MK_16(MEM, cmd);
2026 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2027 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2029 printf("ie%d: individual address "
2030 "setup command failed\n", unit);
2036 * Now run the time-domain reflectometer.
2038 run_tdr(unit, (volatile void *) ptr);
2041 * Acknowledge any interrupts we have generated thus far.
2043 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
2048 ptr = setup_rfa(ptr, ie);
2051 * Finally, the transmit command and buffer are the last little bit
2055 /* transmit command buffers */
2056 for (i = 0; i < ie->ntxbufs; i++) {
2057 ie->xmit_cmds[i] = (volatile void *) ptr;
2058 ptr += sizeof *ie->xmit_cmds[i];
2059 ptr = Alignvol(ptr);
2060 ie->xmit_buffs[i] = (volatile void *)ptr;
2061 ptr += sizeof *ie->xmit_buffs[i];
2062 ptr = Alignvol(ptr);
2065 /* transmit buffers */
2066 for (i = 0; i < ie->ntxbufs - 1; i++) {
2067 ie->xmit_cbuffs[i] = (volatile void *)ptr;
2069 ptr = Alignvol(ptr);
2071 ie->xmit_cbuffs[ie->ntxbufs - 1] = (volatile void *) ptr;
2073 for (i = 1; i < ie->ntxbufs; i++) {
2074 bzero((v_caddr_t) ie->xmit_cmds[i], sizeof *ie->xmit_cmds[i]);
2075 bzero((v_caddr_t) ie->xmit_buffs[i], sizeof *ie->xmit_buffs[i]);
2079 * This must be coordinated with iestart() and ietint().
2081 ie->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
2083 /* take the ee16 out of loopback */
2084 if (ie->hard_type == IE_EE16) {
2085 u_int8_t bart_config;
2087 bart_config = inb(PORT + IEE16_CONFIG);
2088 bart_config &= ~IEE16_BART_LOOPBACK;
2089 /* inb doesn't get bit! */
2090 bart_config |= IEE16_BART_MCS16_TEST;
2091 outb(PORT + IEE16_CONFIG, bart_config);
2092 ee16_interrupt_enable(ie);
2093 ee16_chan_attn(unit);
2095 ie->arpcom.ac_if.if_flags |= IFF_RUNNING; /* tell higher levels
2097 start_receiver(unit);
2105 command_and_wait(unit, IE_RU_DISABLE, 0, 0);
2109 ieioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
2118 * Note that this device doesn't have an "all multicast"
2119 * mode, so we must turn on promiscuous mode and do the
2120 * filtering manually.
2122 if ((ifp->if_flags & IFF_UP) == 0 &&
2123 (ifp->if_flags & IFF_RUNNING)) {
2124 ifp->if_flags &= ~IFF_RUNNING;
2125 ie_stop(ifp->if_dunit);
2126 } else if ((ifp->if_flags & IFF_UP) &&
2127 (ifp->if_flags & IFF_RUNNING) == 0) {
2128 ie_softc[ifp->if_dunit].promisc =
2129 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2130 ieinit(ifp->if_softc);
2131 } else if (ie_softc[ifp->if_dunit].promisc ^
2132 (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) {
2133 ie_softc[ifp->if_dunit].promisc =
2134 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2135 ieinit(ifp->if_softc);
2142 * Update multicast listeners
2144 /* reset multicast filtering */
2145 ie_mc_reset(ifp->if_dunit);
2150 error = ether_ioctl(ifp, command, data);
2159 ie_mc_reset(int unit)
2161 struct ie_softc *ie = &ie_softc[unit];
2162 struct ifmultiaddr *ifma;
2165 * Step through the list of addresses.
2167 ie->mcast_count = 0;
2168 for (ifma = ie->arpcom.ac_if.if_multiaddrs.lh_first; ifma;
2169 ifma = ifma->ifma_link.le_next) {
2170 if (ifma->ifma_addr->sa_family != AF_LINK)
2173 /* XXX - this is broken... */
2174 if (ie->mcast_count >= MAXMCAST) {
2175 ie->arpcom.ac_if.if_flags |= IFF_ALLMULTI;
2176 ieioctl(&ie->arpcom.ac_if, SIOCSIFFLAGS, (void *) 0,
2177 (struct ucred *)NULL);
2180 bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
2181 &(ie->mcast_addrs[ie->mcast_count]), 6);
2186 ie->want_mcsetup = 1;
2192 print_rbd(volatile struct ie_recv_buf_desc * rbd)
2194 printf("RBD at %p:\n"
2195 "actual %04x, next %04x, buffer %p\n"
2196 "length %04x, mbz %04x\n",
2197 (volatile void *) rbd,
2198 rbd->ie_rbd_actual, rbd->ie_rbd_next,
2199 (void *) rbd->ie_rbd_buffer,
2200 rbd->ie_rbd_length, rbd->mbz);