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.2 2003/06/17 04:28:27 dillon 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>
125 #include <net/ethernet.h>
127 #include <net/if_types.h>
128 #include <net/if_dl.h>
130 #include <netinet/in.h>
131 #include <netinet/if_ether.h>
133 #include <machine/clock.h>
134 #include <machine/md_var.h>
136 #include <i386/isa/isa_device.h>
137 #include <i386/isa/ic/i82586.h>
138 #include <i386/isa/icu.h>
139 #include <dev/ie/if_iereg.h>
140 #include <dev/ie/if_ie507.h>
141 #include <dev/ie/if_iee16.h>
142 #include <i386/isa/elink.h>
147 #define IED_RINT 0x01
148 #define IED_TINT 0x02
151 #define IED_READFRAME 0x10
152 static int ie_debug = IED_RNR;
156 #define IE_BUF_LEN ETHER_MAX_LEN /* length of transmit buffer */
158 /* Forward declaration */
161 static int ieprobe(struct isa_device * dvp);
162 static int ieattach(struct isa_device * dvp);
163 static ointhand2_t ieintr;
164 static int sl_probe(struct isa_device * dvp);
165 static int el_probe(struct isa_device * dvp);
166 static int ni_probe(struct isa_device * dvp);
167 static int ee16_probe(struct isa_device * dvp);
169 static int check_ie_present(int unit, caddr_t where, unsigned size);
170 static void ieinit(void *);
171 static void ie_stop(int unit);
172 static int ieioctl(struct ifnet * ifp, u_long command, caddr_t data);
173 static void iestart(struct ifnet * ifp);
175 static void el_reset_586(int unit);
176 static void el_chan_attn(int unit);
178 static void sl_reset_586(int unit);
179 static void sl_chan_attn(int unit);
181 static void ee16_reset_586(int unit);
182 static void ee16_chan_attn(int unit);
183 static __inline void ee16_interrupt_enable(struct ie_softc * ie);
184 static void ee16_eeprom_outbits(struct ie_softc * ie, int edata, int cnt);
185 static void ee16_eeprom_clock(struct ie_softc * ie, int state);
186 static u_short ee16_read_eeprom(struct ie_softc * ie, int location);
187 static int ee16_eeprom_inbits(struct ie_softc * ie);
188 static void ee16_shutdown(void *sc, int howto);
190 static void iereset(int unit);
191 static void ie_readframe(int unit, struct ie_softc * ie, int bufno);
192 static void ie_drop_packet_buffer(int unit, struct ie_softc * ie);
193 static void sl_read_ether(int unit, unsigned char addr[6]);
194 static void find_ie_mem_size(int unit);
195 static void chan_attn_timeout(void *rock);
196 static int command_and_wait(int unit, int command,
197 void volatile * pcmd, int);
198 static void run_tdr(int unit, volatile struct ie_tdr_cmd * cmd);
199 static int ierint(int unit, struct ie_softc * ie);
200 static int ietint(int unit, struct ie_softc * ie);
201 static int iernr(int unit, struct ie_softc * ie);
202 static void start_receiver(int unit);
203 static __inline int ieget(int, struct ie_softc *, struct mbuf **,
204 struct ether_header *);
205 static v_caddr_t setup_rfa(v_caddr_t ptr, struct ie_softc * ie);
206 static int mc_setup(int, v_caddr_t, volatile struct ie_sys_ctl_block *);
207 static void ie_mc_reset(int unit);
210 static void print_rbd(volatile struct ie_recv_buf_desc * rbd);
212 static int in_ierint = 0;
213 static int in_ietint = 0;
218 * This tells the autoconf code how to set us up.
220 struct isa_driver iedriver = {
221 ieprobe, ieattach, "ie",
234 static const char *ie_hardware_names[] = {
245 sizeof(iscp) == 1+1+2+4 == 8
246 sizeof(scb) == 2+2+2+2+2+2+2+2 == 16
247 NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384
248 sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18
249 sizeof(transmit buffer) == 1512
250 sizeof(transmit buffer desc) == 8
254 NRXBUFS * sizeof(rbd) == NRXBUFS*(2+2+4+2+2) == NRXBUFS*12
255 NRXBUFS * IE_RBUF_SIZE == NRXBUFS*256
257 NRXBUFS should be (16384 - 1946) / (256 + 12) == 14438 / 268 == 53
259 With NRXBUFS == 48, this leaves us 1574 bytes for another command or
260 more buffers. Another transmit command would be 18+8+1512 == 1538
263 Obviously all these would have to be reduced for smaller memory sizes.
264 With a larger memory, it would be possible to roughly double the number of
265 both transmit and receive buffers.
268 #define NFRAMES 8 /* number of receive frames */
269 #define NRXBUFS 48 /* number of buffers to allocate */
270 #define IE_RBUF_SIZE 256 /* size of each buffer, MUST BE POWER OF TWO */
271 #define NTXBUFS 2 /* number of transmit commands */
272 #define IE_TBUF_SIZE ETHER_MAX_LEN /* size of transmit buffer */
275 * Ethernet status, per interface.
277 static struct ie_softc {
278 struct arpcom arpcom;
279 void (*ie_reset_586) (int);
280 void (*ie_chan_attn) (int);
281 enum ie_hardware hard_type;
285 u_short port; /* i/o base address for this interface */
286 caddr_t iomem; /* memory size */
287 caddr_t iomembot; /* memory base address */
289 int bus_use; /* 0 means 16bit, 1 means 8 bit adapter */
296 volatile struct ie_int_sys_conf_ptr *iscp;
297 volatile struct ie_sys_ctl_block *scb;
298 volatile struct ie_recv_frame_desc **rframes; /* nframes worth */
299 volatile struct ie_recv_buf_desc **rbuffs; /* nrxbufs worth */
300 volatile u_char **cbuffs; /* nrxbufs worth */
301 int rfhead, rftail, rbhead, rbtail;
303 volatile struct ie_xmit_cmd **xmit_cmds; /* ntxbufs worth */
304 volatile struct ie_xmit_buf **xmit_buffs; /* ntxbufs worth */
305 volatile u_char **xmit_cbuffs; /* ntxbufs worth */
308 struct ie_en_addr mcast_addrs[MAXMCAST + 1];
311 u_short irq_encoded; /* encoded interrupt on IEE16 */
314 #define MK_24(base, ptr) ((caddr_t)((uintptr_t)ptr - (uintptr_t)base))
315 #define MK_16(base, ptr) ((u_short)(uintptr_t)MK_24(base, ptr))
317 #define PORT ie_softc[unit].port
318 #define MEM ie_softc[unit].iomem
321 ieprobe(struct isa_device *dvp)
331 ret = ee16_probe(dvp);
337 sl_probe(struct isa_device *dvp)
339 int unit = dvp->id_unit;
342 ie_softc[unit].port = dvp->id_iobase;
343 ie_softc[unit].iomembot = dvp->id_maddr;
344 ie_softc[unit].iomem = 0;
345 ie_softc[unit].bus_use = 0;
347 c = inb(PORT + IEATT_REVISION);
348 switch (SL_BOARD(c)) {
350 ie_softc[unit].hard_type = IE_STARLAN10;
351 ie_softc[unit].ie_reset_586 = sl_reset_586;
352 ie_softc[unit].ie_chan_attn = sl_chan_attn;
355 ie_softc[unit].hard_type = IE_EN100;
356 ie_softc[unit].ie_reset_586 = sl_reset_586;
357 ie_softc[unit].ie_chan_attn = sl_chan_attn;
360 ie_softc[unit].hard_type = IE_SLFIBER;
361 ie_softc[unit].ie_reset_586 = sl_reset_586;
362 ie_softc[unit].ie_chan_attn = sl_chan_attn;
366 * Anything else is not recognized or cannot be used.
372 ie_softc[unit].hard_vers = SL_REV(c);
375 * Divine memory size on-board the card. Ususally 16k.
377 find_ie_mem_size(unit);
379 if (!ie_softc[unit].iosize) {
382 dvp->id_msize = ie_softc[unit].iosize;
384 switch (ie_softc[unit].hard_type) {
388 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
393 printf("ie%d: unknown AT&T board type code %d\n", unit,
394 ie_softc[unit].hard_type);
403 el_probe(struct isa_device *dvp)
405 struct ie_softc *sc = &ie_softc[dvp->id_unit];
408 u_char signature[] = "*3COM*";
409 int unit = dvp->id_unit;
412 sc->port = dvp->id_iobase;
413 sc->iomembot = dvp->id_maddr;
416 /* Need this for part of the probe. */
417 sc->ie_reset_586 = el_reset_586;
418 sc->ie_chan_attn = el_chan_attn;
420 /* Reset and put card in CONFIG state without changing address. */
422 outb(ELINK_ID_PORT, 0x00);
423 elink_idseq(ELINK_507_POLY);
424 elink_idseq(ELINK_507_POLY);
425 outb(ELINK_ID_PORT, 0xff);
427 c = inb(PORT + IE507_MADDR);
430 printf("ie%d: can't map 3C507 RAM in high memory\n", unit);
434 /* go to RUN state */
435 outb(ELINK_ID_PORT, 0x00);
436 elink_idseq(ELINK_507_POLY);
437 outb(ELINK_ID_PORT, 0x00);
439 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
441 for (i = 0; i < 6; i++)
442 if (inb(PORT + i) != signature[i])
445 c = inb(PORT + IE507_IRQ) & 0x0f;
447 if (dvp->id_irq != (1 << c)) {
448 printf("ie%d: kernel configured irq %d "
449 "doesn't match board configured irq %d\n",
450 unit, ffs(dvp->id_irq) - 1, c);
453 c = (inb(PORT + IE507_MADDR) & 0x1c) + 0xc0;
455 if (kvtop(dvp->id_maddr) != ((int) c << 12)) {
456 printf("ie%d: kernel configured maddr %lx "
457 "doesn't match board configured maddr %x\n",
458 unit, kvtop(dvp->id_maddr), (int) c << 12);
461 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
463 sc->hard_type = IE_3C507;
464 sc->hard_vers = 0; /* 3C507 has no version number. */
467 * Divine memory size on-board the card.
469 find_ie_mem_size(unit);
472 printf("ie%d: can't find shared memory\n", unit);
473 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
477 dvp->id_msize = sc->iosize;
478 else if (dvp->id_msize != sc->iosize) {
479 printf("ie%d: kernel configured msize %d "
480 "doesn't match board configured msize %d\n",
481 unit, dvp->id_msize, sc->iosize);
482 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
485 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
487 /* Clear the interrupt latch just in case. */
488 outb(PORT + IE507_ICTRL, 1);
495 ni_probe(struct isa_device *dvp)
497 int unit = dvp->id_unit;
500 ie_softc[unit].port = dvp->id_iobase;
501 ie_softc[unit].iomembot = dvp->id_maddr;
502 ie_softc[unit].iomem = 0;
503 ie_softc[unit].bus_use = 1;
505 boardtype = inb(PORT + IEATT_REVISION);
506 c = inb(PORT + IEATT_REVISION + 1);
507 boardtype = boardtype + (c << 8);
509 case 0x5500: /* This is the magic cookie for the NI5210 */
510 ie_softc[unit].hard_type = IE_NI5210;
511 ie_softc[unit].ie_reset_586 = sl_reset_586;
512 ie_softc[unit].ie_chan_attn = sl_chan_attn;
516 * Anything else is not recognized or cannot be used.
522 ie_softc[unit].hard_vers = 0;
525 * Divine memory size on-board the card. Either 8 or 16k.
527 find_ie_mem_size(unit);
529 if (!ie_softc[unit].iosize) {
533 dvp->id_msize = ie_softc[unit].iosize;
534 else if (dvp->id_msize != ie_softc[unit].iosize) {
535 printf("ie%d: kernel configured msize %d "
536 "doesn't match board configured msize %d\n",
537 unit, dvp->id_msize, ie_softc[unit].iosize);
540 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
548 ee16_shutdown(void *sc, int howto)
550 struct ie_softc *ie = (struct ie_softc *)sc;
551 int unit = ie - &ie_softc[0];
553 ee16_reset_586(unit);
554 outb(PORT + IEE16_ECTRL, IEE16_RESET_ASIC);
555 outb(PORT + IEE16_ECTRL, 0);
559 /* Taken almost exactly from Rod's if_ix.c. */
562 ee16_probe(struct isa_device *dvp)
564 struct ie_softc *sc = &ie_softc[dvp->id_unit];
567 int unit = dvp->id_unit;
568 u_short board_id, id_var1, id_var2, checksum = 0;
569 u_short eaddrtemp, irq;
570 u_short pg, adjust, decode, edecode;
574 short irq_translate[] = {0, IRQ9, IRQ3, IRQ4, IRQ5, IRQ10, IRQ11, 0};
575 char irq_encode[] = {0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0};
577 /* Need this for part of the probe. */
578 sc->ie_reset_586 = ee16_reset_586;
579 sc->ie_chan_attn = ee16_chan_attn;
581 /* unsure if this is necessary */
584 /* reset any ee16 at the current iobase */
585 outb(dvp->id_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
586 outb(dvp->id_iobase + IEE16_ECTRL, 0);
589 /* now look for ee16. */
590 board_id = id_var1 = id_var2 = 0;
591 for (i = 0; i < 4; i++) {
592 id_var1 = inb(dvp->id_iobase + IEE16_ID_PORT);
593 id_var2 = ((id_var1 & 0x03) << 2);
594 board_id |= ((id_var1 >> 4) << id_var2);
597 if (board_id != IEE16_ID) {
599 printf("ie%d: unknown board_id: %x\n", unit, board_id);
602 /* need sc->port for ee16_read_eeprom */
603 sc->port = dvp->id_iobase;
604 sc->hard_type = IE_EE16;
607 * The shared RAM location on the EE16 is encoded into bits 3-7 of
608 * EEPROM location 6. We zero the upper byte, and shift the 5 bits
609 * right 3. The resulting number tells us the RAM location.
610 * Because the EE16 supports either 16k or 32k of shared RAM, we
611 * only worry about the 32k locations.
613 * NOTE: if a 64k EE16 exists, it should be added to this switch. then
614 * the ia->ia_msize would need to be set per case statement.
616 * value msize location ===== ===== ======== 0x03 0x8000
617 * 0xCC000 0x06 0x8000 0xD0000 0x0C 0x8000 0xD4000 0x18
623 i = (ee16_read_eeprom(sc, 6) & 0x00ff) >> 3;
641 dvp->id_msize = 0x8000;
642 if (kvtop(dvp->id_maddr) != bd_maddr) {
643 printf("ie%d: kernel configured maddr %lx "
644 "doesn't match board configured maddr %lx\n",
645 unit, kvtop(dvp->id_maddr), bd_maddr);
647 sc->iomembot = dvp->id_maddr;
648 sc->iomem = 0; /* XXX some probes set this and some don't */
649 sc->iosize = dvp->id_msize;
651 /* need to put the 586 in RESET while we access the eeprom. */
652 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
654 /* read the eeprom and checksum it, should == IEE16_ID */
655 for (i = 0; i < 0x40; i++)
656 checksum += ee16_read_eeprom(sc, i);
658 if (checksum != IEE16_ID) {
659 printf("ie%d: invalid eeprom checksum: %x\n", unit, checksum);
663 * Size and test the memory on the board. The size of the memory
664 * can be one of 16k, 32k, 48k or 64k. It can be located in the
665 * address range 0xC0000 to 0xEFFFF on 16k boundaries.
667 * If the size does not match the passed in memory allocation size
668 * issue a warning, but continue with the minimum of the two sizes.
671 switch (dvp->id_msize) {
673 case 32768: /* XXX Only support 32k and 64k right now */
678 printf("ie%d: mapped memory size %d not supported\n", unit,
681 break; /* NOTREACHED */
684 if ((kvtop(dvp->id_maddr) < 0xC0000) ||
685 (kvtop(dvp->id_maddr) + sc->iosize > 0xF0000)) {
686 printf("ie%d: mapped memory location %p out of range\n", unit,
687 (void *)dvp->id_maddr);
690 pg = (kvtop(dvp->id_maddr) & 0x3C000) >> 14;
691 adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
692 decode = ((1 << (sc->iosize / 16384)) - 1) << pg;
693 edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
695 /* ZZZ This should be checked against eeprom location 6, low byte */
696 outb(PORT + IEE16_MEMDEC, decode & 0xFF);
697 /* ZZZ This should be checked against eeprom location 1, low byte */
698 outb(PORT + IEE16_MCTRL, adjust);
699 /* ZZZ Now if I could find this one I would have it made */
700 outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
701 /* ZZZ I think this is location 6, high byte */
702 outb(PORT + IEE16_MECTRL, edecode); /* XXX disable Exxx */
704 (void) kvtop(dvp->id_maddr);
707 * first prime the stupid bart DRAM controller so that it works,
708 * then zero out all of memory.
710 bzero(sc->iomembot, 32);
711 bzero(sc->iomembot, sc->iosize);
714 * Get the encoded interrupt number from the EEPROM, check it
715 * against the passed in IRQ. Issue a warning if they do not match.
716 * Always use the passed in IRQ, not the one in the EEPROM.
718 irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
719 irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
720 irq = irq_translate[irq];
721 if (dvp->id_irq > 0) {
722 if (irq != dvp->id_irq) {
723 printf("ie%d: WARNING: board configured "
724 "at irq %u, using %u\n",
725 dvp->id_unit, dvp->id_irq, irq);
731 sc->irq_encoded = irq_encode[ffs(irq) - 1];
734 * Get the hardware ethernet address from the EEPROM and save it in
735 * the softc for use by the 586 setup code.
737 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
738 sc->arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
739 sc->arpcom.ac_enaddr[0] = eaddrtemp >> 8;
740 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
741 sc->arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
742 sc->arpcom.ac_enaddr[2] = eaddrtemp >> 8;
743 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
744 sc->arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
745 sc->arpcom.ac_enaddr[4] = eaddrtemp >> 8;
747 /* disable the board interrupts */
748 outb(PORT + IEE16_IRQ, sc->irq_encoded);
750 /* enable loopback to keep bad packets off the wire */
751 if (sc->hard_type == IE_EE16) {
752 bart_config = inb(PORT + IEE16_CONFIG);
753 bart_config |= IEE16_BART_LOOPBACK;
754 bart_config |= IEE16_BART_MCS16_TEST;/* inb doesn't get bit! */
755 outb(PORT + IEE16_CONFIG, bart_config);
756 bart_config = inb(PORT + IEE16_CONFIG);
758 /* take the board out of reset state */
759 outb(PORT + IEE16_ECTRL, 0);
762 if (!check_ie_present(unit, dvp->id_maddr, sc->iosize))
765 return (16); /* return the number of I/O ports */
769 * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
772 ieattach(struct isa_device *dvp)
775 int unit = dvp->id_unit;
776 struct ie_softc *ie = &ie_softc[unit];
777 struct ifnet *ifp = &ie->arpcom.ac_if;
780 dvp->id_ointr = ieintr;
783 * based on the amount of memory we have, allocate our tx and rx
786 factor = dvp->id_msize / 16384;
787 ie->nframes = factor * NFRAMES;
788 ie->nrxbufs = factor * NRXBUFS;
789 ie->ntxbufs = factor * NTXBUFS;
792 * Since all of these guys are arrays of pointers, allocate as one
793 * big chunk and dole out accordingly.
795 allocsize = sizeof(void *) * (ie->nframes
797 + (ie->ntxbufs * 3));
798 ie->rframes = (volatile struct ie_recv_frame_desc **) malloc(allocsize,
801 if (ie->rframes == NULL)
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];
814 ifp->if_name = iedriver.name;
815 ifp->if_mtu = ETHERMTU;
816 printf("ie%d: <%s R%d> address %6D\n", unit,
817 ie_hardware_names[ie->hard_type],
819 ie->arpcom.ac_enaddr, ":");
821 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
822 ifp->if_output = ether_output;
823 ifp->if_start = iestart;
824 ifp->if_ioctl = ieioctl;
825 ifp->if_init = ieinit;
826 ifp->if_type = IFT_ETHER;
829 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
831 if (ie->hard_type == IE_EE16)
832 EVENTHANDLER_REGISTER(shutdown_post_sync, ee16_shutdown,
833 ie, SHUTDOWN_PRI_DEFAULT);
835 ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
840 * What to do upon receipt of an interrupt.
845 register struct ie_softc *ie = &ie_softc[unit];
846 register u_short status;
848 /* Clear the interrupt latch on the 3C507. */
849 if (ie->hard_type == IE_3C507
850 && (inb(PORT + IE507_CTRL) & EL_CTRL_INTL))
851 outb(PORT + IE507_ICTRL, 1);
853 /* disable interrupts on the EE16. */
854 if (ie->hard_type == IE_EE16)
855 outb(PORT + IEE16_IRQ, ie->irq_encoded);
857 status = ie->scb->ie_status;
861 /* Don't ack interrupts which we didn't receive */
862 ie_ack(ie->scb, IE_ST_WHENCE & status, unit, ie->ie_chan_attn);
864 if (status & (IE_ST_RECV | IE_ST_RNR)) {
867 if (ie_debug & IED_RINT)
868 printf("ie%d: rint\n", unit);
875 if (status & IE_ST_DONE) {
878 if (ie_debug & IED_TINT)
879 printf("ie%d: tint\n", unit);
886 if (status & IE_ST_RNR) {
888 if (ie_debug & IED_RNR)
889 printf("ie%d: rnr\n", unit);
894 if ((status & IE_ST_ALLDONE)
895 && (ie_debug & IED_CNA))
896 printf("ie%d: cna\n", unit);
899 if ((status = ie->scb->ie_status) & IE_ST_WHENCE)
902 /* Clear the interrupt latch on the 3C507. */
903 if (ie->hard_type == IE_3C507)
904 outb(PORT + IE507_ICTRL, 1);
906 /* enable interrupts on the EE16. */
907 if (ie->hard_type == IE_EE16)
908 outb(PORT + IEE16_IRQ, ie->irq_encoded | IEE16_IRQ_ENABLE);
913 * Process a received-frame interrupt.
916 ierint(int unit, struct ie_softc *ie)
919 static int timesthru = 1024;
923 status = ie->rframes[i]->ie_fd_status;
925 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
926 ie->arpcom.ac_if.if_ipackets++;
928 ie->arpcom.ac_if.if_ierrors +=
929 ie->scb->ie_err_crc +
930 ie->scb->ie_err_align +
931 ie->scb->ie_err_resource +
932 ie->scb->ie_err_overrun;
933 ie->scb->ie_err_crc = 0;
934 ie->scb->ie_err_align = 0;
935 ie->scb->ie_err_resource = 0;
936 ie->scb->ie_err_overrun = 0;
939 ie_readframe(unit, ie, i);
941 if (status & IE_FD_RNR) {
942 if (!(ie->scb->ie_status & IE_RU_READY)) {
943 ie->rframes[0]->ie_fd_next =
944 MK_16(MEM, ie->rbuffs[0]);
945 ie->scb->ie_recv_list =
946 MK_16(MEM, ie->rframes[0]);
947 command_and_wait(unit, IE_RU_START,
953 i = (i + 1) % ie->nframes;
959 * Process a command-complete interrupt. These are only generated by
960 * the transmission of frames. This routine is deceptively simple, since
961 * most of the real work is done by iestart().
964 ietint(int unit, struct ie_softc *ie)
969 ie->arpcom.ac_if.if_timer = 0;
970 ie->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
972 for (i = 0; i < ie->xmit_count; i++) {
973 status = ie->xmit_cmds[i]->ie_xmit_status;
975 if (status & IE_XS_LATECOLL) {
976 printf("ie%d: late collision\n", unit);
977 ie->arpcom.ac_if.if_collisions++;
978 ie->arpcom.ac_if.if_oerrors++;
979 } else if (status & IE_XS_NOCARRIER) {
980 printf("ie%d: no carrier\n", unit);
981 ie->arpcom.ac_if.if_oerrors++;
982 } else if (status & IE_XS_LOSTCTS) {
983 printf("ie%d: lost CTS\n", unit);
984 ie->arpcom.ac_if.if_oerrors++;
985 } else if (status & IE_XS_UNDERRUN) {
986 printf("ie%d: DMA underrun\n", unit);
987 ie->arpcom.ac_if.if_oerrors++;
988 } else if (status & IE_XS_EXCMAX) {
989 printf("ie%d: too many collisions\n", unit);
990 ie->arpcom.ac_if.if_collisions += 16;
991 ie->arpcom.ac_if.if_oerrors++;
993 ie->arpcom.ac_if.if_opackets++;
994 ie->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL;
1000 * If multicast addresses were added or deleted while we were
1001 * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
1002 * that we should do it.
1004 if (ie->want_mcsetup) {
1005 mc_setup(unit, (v_caddr_t) ie->xmit_cbuffs[0], ie->scb);
1006 ie->want_mcsetup = 0;
1008 /* Wish I knew why this seems to be necessary... */
1009 ie->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
1011 iestart(&ie->arpcom.ac_if);
1012 return (0); /* shouldn't be necessary */
1016 * Process a receiver-not-ready interrupt. I believe that we get these
1017 * when there aren't enough buffers to go around. For now (FIXME), we
1018 * just restart the receiver, and hope everything's ok.
1021 iernr(int unit, struct ie_softc *ie)
1024 setup_rfa((v_caddr_t) ie->rframes[0], ie);
1026 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1027 command_and_wait(unit, IE_RU_START, 0, 0);
1029 /* This doesn't work either, but it doesn't hang either. */
1030 command_and_wait(unit, IE_RU_DISABLE, 0, 0); /* just in case */
1031 setup_rfa((v_caddr_t) ie->rframes[0], ie); /* ignore cast-qual */
1033 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1034 command_and_wait(unit, IE_RU_START, 0, 0); /* was ENABLE */
1037 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
1039 ie->arpcom.ac_if.if_ierrors++;
1044 * Compare two Ether/802 addresses for equality, inlined and
1045 * unrolled for speed. I'd love to have an inline assembler
1046 * version of this...
1049 ether_equal(u_char * one, u_char * two)
1051 if (one[0] != two[0])
1053 if (one[1] != two[1])
1055 if (one[2] != two[2])
1057 if (one[3] != two[3])
1059 if (one[4] != two[4])
1061 if (one[5] != two[5])
1067 * Determine quickly whether we should bother reading in this packet.
1068 * This depends on whether BPF and/or bridging is enabled, whether we
1069 * are receiving multicast address, and whether promiscuous mode is enabled.
1070 * We assume that if IFF_PROMISC is set, then *somebody* wants to see
1071 * all incoming packets.
1074 check_eh(struct ie_softc *ie, struct ether_header *eh)
1076 /* Optimize the common case: normal operation. We've received
1077 either a unicast with our dest or a multicast packet. */
1078 if (ie->promisc == 0) {
1081 /* If not multicast, it's definitely for us */
1082 if ((eh->ether_dhost[0] & 1) == 0)
1085 /* Accept broadcasts (loose but fast check) */
1086 if (eh->ether_dhost[0] == 0xff)
1089 /* Compare against our multicast addresses */
1090 for (i = 0; i < ie->mcast_count; i++) {
1091 if (ether_equal(eh->ether_dhost,
1092 (u_char *)&ie->mcast_addrs[i]))
1098 /* Always accept packets when in promiscuous mode */
1099 if ((ie->promisc & IFF_PROMISC) != 0)
1102 /* Always accept packets directed at us */
1103 if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1106 /* Must have IFF_ALLMULTI but not IFF_PROMISC set. The chip is
1107 actually in promiscuous mode, so discard unicast packets. */
1108 return((eh->ether_dhost[0] & 1) != 0);
1112 * We want to isolate the bits that have meaning... This assumes that
1113 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds
1114 * the size of the buffer, then we are screwed anyway.
1117 ie_buflen(struct ie_softc * ie, int head)
1119 return (ie->rbuffs[head]->ie_rbd_actual
1120 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
1124 ie_packet_len(int unit, struct ie_softc * ie)
1127 int head = ie->rbhead;
1131 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1133 print_rbd(ie->rbuffs[ie->rbhead]);
1136 "ie%d: receive descriptors out of sync at %d\n",
1141 i = ie->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
1143 acc += ie_buflen(ie, head);
1144 head = (head + 1) % ie->nrxbufs;
1151 * Read data off the interface, and turn it into an mbuf chain.
1153 * This code is DRAMATICALLY different from the previous version; this
1154 * version tries to allocate the entire mbuf chain up front, given the
1155 * length of the data available. This enables us to allocate mbuf
1156 * clusters in many situations where before we would have had a long
1157 * chain of partially-full mbufs. This should help to speed up the
1158 * operation considerably. (Provided that it works, of course.)
1161 ieget(int unit, struct ie_softc *ie, struct mbuf **mp, struct ether_header *ehp)
1163 struct mbuf *m, *top, **mymp;
1170 totlen = ie_packet_len(unit, ie);
1177 * Snarf the Ethernet header.
1179 bcopy((v_caddr_t) ie->cbuffs[i], (caddr_t) ehp, sizeof *ehp);
1180 /* ignore cast-qual warning here */
1183 * As quickly as possible, check if this packet is for us. If not,
1184 * don't waste a single cycle copying the rest of the packet in.
1185 * This is only a consideration when FILTER is defined; i.e., when
1186 * we are either running BPF or doing multicasting.
1188 if (!check_eh(ie, ehp)) {
1189 ie_drop_packet_buffer(unit, ie);
1190 ie->arpcom.ac_if.if_ierrors--; /* just this case, it's not an
1195 totlen -= (offset = sizeof *ehp);
1197 MGETHDR(*mp, M_DONTWAIT, MT_DATA);
1199 ie_drop_packet_buffer(unit, ie);
1203 m->m_pkthdr.rcvif = &ie->arpcom.ac_if;
1205 resid = m->m_pkthdr.len = totlen;
1210 * This loop goes through and allocates mbufs for all the data we
1211 * will be copying in. It does not actually do the copying yet.
1213 do { /* while(resid > 0) */
1215 * Try to allocate an mbuf to hold the data that we have.
1216 * If we already allocated one, just get another one and
1217 * stick it on the end (eventually). If we don't already
1218 * have one, try to allocate an mbuf cluster big enough to
1219 * hold the whole packet, if we think it's reasonable, or a
1220 * single mbuf which may or may not be big enough. Got that?
1223 MGET(m, M_DONTWAIT, MT_DATA);
1226 ie_drop_packet_buffer(unit, ie);
1231 if (resid >= MINCLSIZE) {
1232 MCLGET(m, M_DONTWAIT);
1233 if (m->m_flags & M_EXT)
1234 m->m_len = min(resid, MCLBYTES);
1236 if (resid < m->m_len) {
1237 if (!top && resid + max_linkhdr <= m->m_len)
1238 m->m_data += max_linkhdr;
1245 } while (resid > 0);
1253 * Now we take the mbuf chain (hopefully only one mbuf most of the
1254 * time) and stuff the data into it. There are no possible failures
1255 * at or after this point.
1257 while (resid > 0) { /* while there's stuff left */
1258 int thislen = ie_buflen(ie, head) - offset;
1261 * If too much data for the current mbuf, then fill the
1262 * current one up, go to the next one, and try again.
1264 if (thislen > m->m_len - thismboff) {
1265 int newlen = m->m_len - thismboff;
1267 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1268 mtod(m, v_caddr_t) +thismboff, (unsigned) newlen);
1269 /* ignore cast-qual warning */
1271 thismboff = 0; /* new mbuf, so no offset */
1272 offset += newlen; /* we are now this far into
1274 resid -= newlen; /* so there is this much left
1279 * If there is more than enough space in the mbuf to hold
1280 * the contents of this buffer, copy everything in, advance
1281 * pointers, and so on.
1283 if (thislen < m->m_len - thismboff) {
1284 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1285 mtod(m, caddr_t) +thismboff, (unsigned) thislen);
1286 thismboff += thislen; /* we are this far into the
1288 resid -= thislen; /* and this much is left */
1292 * Otherwise, there is exactly enough space to put this
1293 * buffer's contents into the current mbuf. Do the
1294 * combination of the above actions.
1296 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1297 mtod(m, caddr_t) + thismboff, (unsigned) thislen);
1299 thismboff = 0; /* new mbuf, start at the beginning */
1300 resid -= thislen; /* and we are this far through */
1303 * Advance all the pointers. We can get here from either of
1304 * the last two cases, but never the first.
1308 ie->rbuffs[head]->ie_rbd_actual = 0;
1309 ie->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
1310 ie->rbhead = head = (head + 1) % ie->nrxbufs;
1311 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1312 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1316 * Unless something changed strangely while we were doing the copy,
1317 * we have now copied everything in from the shared memory. This
1318 * means that we are done.
1324 * Read frame NUM from unit UNIT (pre-cached as IE).
1326 * This routine reads the RFD at NUM, and copies in the buffers from
1327 * the list of RBD, then rotates the RBD and RFD lists so that the receiver
1328 * doesn't start complaining. Trailers are DROPPED---there's no point
1329 * in wasting time on confusing code to deal with them. Hopefully,
1330 * this machine will never ARP for trailers anyway.
1333 ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
1335 struct ie_recv_frame_desc rfd;
1337 struct ether_header eh;
1339 bcopy((v_caddr_t) (ie->rframes[num]), &rfd,
1340 sizeof(struct ie_recv_frame_desc));
1343 * Immediately advance the RFD list, since we we have copied ours
1346 ie->rframes[num]->ie_fd_status = 0;
1347 ie->rframes[num]->ie_fd_last |= IE_FD_LAST;
1348 ie->rframes[ie->rftail]->ie_fd_last &= ~IE_FD_LAST;
1349 ie->rftail = (ie->rftail + 1) % ie->nframes;
1350 ie->rfhead = (ie->rfhead + 1) % ie->nframes;
1352 if (rfd.ie_fd_status & IE_FD_OK) {
1353 if (ieget(unit, ie, &m, &eh)) {
1354 ie->arpcom.ac_if.if_ierrors++; /* this counts as an
1360 if (ie_debug & IED_READFRAME) {
1361 printf("ie%d: frame from ether %6D type %x\n", unit,
1362 eh.ether_shost, ":", (unsigned) eh.ether_type);
1364 if (ntohs(eh.ether_type) > ETHERTYPE_TRAIL
1365 && ntohs(eh.ether_type) < (ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER))
1366 printf("received trailer!\n");
1373 * Finally pass this packet up to higher layers.
1375 ether_input(&ie->arpcom.ac_if, &eh, m);
1379 ie_drop_packet_buffer(int unit, struct ie_softc * ie)
1385 * This means we are somehow out of sync. So, we reset the
1388 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1390 print_rbd(ie->rbuffs[ie->rbhead]);
1392 log(LOG_ERR, "ie%d: receive descriptors out of sync at %d\n",
1397 i = ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1399 ie->rbuffs[ie->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1400 ie->rbuffs[ie->rbhead]->ie_rbd_actual = 0;
1401 ie->rbhead = (ie->rbhead + 1) % ie->nrxbufs;
1402 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1403 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1409 * Start transmission on an interface.
1412 iestart(struct ifnet *ifp)
1414 struct ie_softc *ie = ifp->if_softc;
1415 struct mbuf *m0, *m;
1416 volatile unsigned char *buffer;
1420 * This is not really volatile, in this routine, but it makes gcc
1423 volatile u_short *bptr = &ie->scb->ie_command_list;
1425 if (!(ifp->if_flags & IFF_RUNNING))
1427 if (ifp->if_flags & IFF_OACTIVE)
1431 IF_DEQUEUE(&ie->arpcom.ac_if.if_snd, m);
1435 buffer = ie->xmit_cbuffs[ie->xmit_count];
1438 for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) {
1439 bcopy(mtod(m, caddr_t), buffer, m->m_len);
1445 len = max(len, ETHER_MIN_LEN);
1448 * See if bpf is listening on this interface, let it see the
1449 * packet before we commit it to the wire.
1451 if (ie->arpcom.ac_if.if_bpf)
1452 bpf_tap(&ie->arpcom.ac_if,
1453 (void *)ie->xmit_cbuffs[ie->xmit_count], len);
1455 ie->xmit_buffs[ie->xmit_count]->ie_xmit_flags =
1457 ie->xmit_buffs[ie->xmit_count]->ie_xmit_next = 0xffff;
1458 ie->xmit_buffs[ie->xmit_count]->ie_xmit_buf =
1459 MK_24(ie->iomem, ie->xmit_cbuffs[ie->xmit_count]);
1461 ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT;
1462 ie->xmit_cmds[ie->xmit_count]->ie_xmit_status = 0;
1463 ie->xmit_cmds[ie->xmit_count]->ie_xmit_desc =
1464 MK_16(ie->iomem, ie->xmit_buffs[ie->xmit_count]);
1466 *bptr = MK_16(ie->iomem, ie->xmit_cmds[ie->xmit_count]);
1467 bptr = &ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_link;
1469 } while (ie->xmit_count < ie->ntxbufs);
1472 * If we queued up anything for transmission, send it.
1474 if (ie->xmit_count) {
1475 ie->xmit_cmds[ie->xmit_count - 1]->com.ie_cmd_cmd |=
1476 IE_CMD_LAST | IE_CMD_INTR;
1479 * By passing the command pointer as a null, we tell
1480 * command_and_wait() to pretend that this isn't an action
1481 * command. I wish I understood what was happening here.
1483 command_and_wait(ifp->if_unit, IE_CU_START, 0, 0);
1484 ifp->if_flags |= IFF_OACTIVE;
1490 * Check to see if there's an 82586 out there.
1493 check_ie_present(int unit, caddr_t where, unsigned size)
1495 volatile struct ie_sys_conf_ptr *scp;
1496 volatile struct ie_int_sys_conf_ptr *iscp;
1497 volatile struct ie_sys_ctl_block *scb;
1503 realbase = (uintptr_t) where + size - (1 << 24);
1505 scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t)
1506 (realbase + IE_SCP_ADDR);
1507 bzero((volatile char *) scp, sizeof *scp);
1510 * First we put the ISCP at the bottom of memory; this tests to make
1511 * sure that our idea of the size of memory is the same as the
1512 * controller's. This is NOT where the ISCP will be in normal
1515 iscp = (volatile struct ie_int_sys_conf_ptr *) where;
1516 bzero((volatile char *)iscp, sizeof *iscp);
1518 scb = (volatile struct ie_sys_ctl_block *) where;
1519 bzero((volatile char *)scb, sizeof *scb);
1521 scp->ie_bus_use = ie_softc[unit].bus_use; /* 8-bit or 16-bit */
1522 scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1523 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1526 iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1528 (*ie_softc[unit].ie_reset_586) (unit);
1529 (*ie_softc[unit].ie_chan_attn) (unit);
1531 DELAY(100); /* wait a while... */
1533 if (iscp->ie_busy) {
1538 * Now relocate the ISCP to its real home, and reset the controller
1541 iscp = (void *) Align((caddr_t) (uintptr_t)
1542 (realbase + IE_SCP_ADDR -
1543 sizeof(struct ie_int_sys_conf_ptr)));
1544 bzero((volatile char *) iscp, sizeof *iscp); /* ignore cast-qual */
1546 scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1547 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1550 iscp->ie_scb_offset = MK_16(realbase, scb);
1552 (*ie_softc[unit].ie_reset_586) (unit);
1553 (*ie_softc[unit].ie_chan_attn) (unit);
1557 if (iscp->ie_busy) {
1561 ie_softc[unit].iosize = size;
1562 ie_softc[unit].iomem = (caddr_t) (uintptr_t) realbase;
1564 ie_softc[unit].iscp = iscp;
1565 ie_softc[unit].scb = scb;
1568 * Acknowledge any interrupts we may have caused...
1570 ie_ack(scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1577 * Divine the memory size of ie board UNIT.
1578 * Better hope there's nothing important hiding just below the ie card...
1581 find_ie_mem_size(int unit)
1585 ie_softc[unit].iosize = 0;
1587 for (size = 65536; size >= 8192; size -= 8192) {
1588 if (check_ie_present(unit, ie_softc[unit].iomembot, size)) {
1597 el_reset_586(int unit)
1599 outb(PORT + IE507_CTRL, EL_CTRL_RESET);
1601 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
1606 sl_reset_586(int unit)
1608 outb(PORT + IEATT_RESET, 0);
1612 ee16_reset_586(int unit)
1614 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
1616 outb(PORT + IEE16_ECTRL, 0);
1621 el_chan_attn(int unit)
1623 outb(PORT + IE507_ATTN, 1);
1627 sl_chan_attn(int unit)
1629 outb(PORT + IEATT_ATTN, 0);
1633 ee16_chan_attn(int unit)
1635 outb(PORT + IEE16_ATTN, 0);
1639 ee16_read_eeprom(struct ie_softc *sc, int location)
1643 ectrl = inb(sc->port + IEE16_ECTRL);
1644 ectrl &= IEE16_ECTRL_MASK;
1645 ectrl |= IEE16_ECTRL_EECS;
1646 outb(sc->port + IEE16_ECTRL, ectrl);
1648 ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
1649 ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
1650 edata = ee16_eeprom_inbits(sc);
1651 ectrl = inb(sc->port + IEE16_ECTRL);
1652 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
1653 outb(sc->port + IEE16_ECTRL, ectrl);
1654 ee16_eeprom_clock(sc, 1);
1655 ee16_eeprom_clock(sc, 0);
1660 ee16_eeprom_outbits(struct ie_softc *sc, int edata, int count)
1664 ectrl = inb(sc->port + IEE16_ECTRL);
1665 ectrl &= ~IEE16_RESET_ASIC;
1666 for (i = count - 1; i >= 0; i--) {
1667 ectrl &= ~IEE16_ECTRL_EEDI;
1668 if (edata & (1 << i)) {
1669 ectrl |= IEE16_ECTRL_EEDI;
1671 outb(sc->port + IEE16_ECTRL, ectrl);
1672 DELAY(1); /* eeprom data must be setup for 0.4 uSec */
1673 ee16_eeprom_clock(sc, 1);
1674 ee16_eeprom_clock(sc, 0);
1676 ectrl &= ~IEE16_ECTRL_EEDI;
1677 outb(sc->port + IEE16_ECTRL, ectrl);
1678 DELAY(1); /* eeprom data must be held for 0.4 uSec */
1682 ee16_eeprom_inbits(struct ie_softc *sc)
1684 int ectrl, edata, i;
1686 ectrl = inb(sc->port + IEE16_ECTRL);
1687 ectrl &= ~IEE16_RESET_ASIC;
1688 for (edata = 0, i = 0; i < 16; i++) {
1690 ee16_eeprom_clock(sc, 1);
1691 ectrl = inb(sc->port + IEE16_ECTRL);
1692 if (ectrl & IEE16_ECTRL_EEDO) {
1695 ee16_eeprom_clock(sc, 0);
1701 ee16_eeprom_clock(struct ie_softc *sc, int state)
1705 ectrl = inb(sc->port + IEE16_ECTRL);
1706 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
1708 ectrl |= IEE16_ECTRL_EESK;
1710 outb(sc->port + IEE16_ECTRL, ectrl);
1711 DELAY(9); /* EESK must be stable for 8.38 uSec */
1714 static __inline void
1715 ee16_interrupt_enable(struct ie_softc *sc)
1718 outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1723 sl_read_ether(int unit, unsigned char addr[6])
1727 for (i = 0; i < 6; i++)
1728 addr[i] = inb(PORT + i);
1741 printf("ie%d: reset\n", unit);
1742 ie_softc[unit].arpcom.ac_if.if_flags &= ~IFF_UP;
1743 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0);
1746 * Stop i82586 dead in its tracks.
1748 if (command_and_wait(unit, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1749 printf("ie%d: abort commands timed out\n", unit);
1751 if (command_and_wait(unit, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1752 printf("ie%d: disable commands timed out\n", unit);
1755 if (!check_ie_present(unit, ie_softc[unit].iomembot,
1756 e_softc[unit].iosize))
1757 panic("ie disappeared!");
1760 ie_softc[unit].arpcom.ac_if.if_flags |= IFF_UP;
1761 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0);
1768 * This is called if we time out.
1771 chan_attn_timeout(void *rock)
1777 * Send a command to the controller and wait for it to either
1778 * complete or be accepted, depending on the command. If the
1779 * command pointer is null, then pretend that the command is
1780 * not an action command. If the command pointer is not null,
1781 * and the command is an action command, wait for
1782 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1786 command_and_wait(int unit, int cmd, volatile void *pcmd, int mask)
1788 volatile struct ie_cmd_common *cc = pcmd;
1789 volatile int timedout = 0;
1790 struct callout_handle ch;
1792 ie_softc[unit].scb->ie_command = (u_short) cmd;
1794 if (IE_ACTION_COMMAND(cmd) && pcmd) {
1795 (*ie_softc[unit].ie_chan_attn) (unit);
1798 * According to the packet driver, the minimum timeout
1799 * should be .369 seconds, which we round up to .37.
1801 ch = timeout(chan_attn_timeout, (caddr_t)&timedout,
1803 /* ignore cast-qual */
1806 * Now spin-lock waiting for status. This is not a very
1807 * nice thing to do, but I haven't figured out how, or
1808 * indeed if, we can put the process waiting for action to
1809 * sleep. (We may be getting called through some other
1810 * timeout running in the kernel.)
1813 if ((cc->ie_cmd_status & mask) || timedout)
1817 untimeout(chan_attn_timeout, (caddr_t)&timedout, ch);
1818 /* ignore cast-qual */
1824 * Otherwise, just wait for the command to be accepted.
1826 (*ie_softc[unit].ie_chan_attn) (unit);
1828 while (ie_softc[unit].scb->ie_command); /* spin lock */
1835 * Run the time-domain reflectometer...
1838 run_tdr(int unit, volatile struct ie_tdr_cmd *cmd)
1842 cmd->com.ie_cmd_status = 0;
1843 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1844 cmd->com.ie_cmd_link = 0xffff;
1845 cmd->ie_tdr_time = 0;
1847 ie_softc[unit].scb->ie_command_list = MK_16(MEM, cmd);
1848 cmd->ie_tdr_time = 0;
1850 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL))
1853 result = cmd->ie_tdr_time;
1855 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit,
1856 ie_softc[unit].ie_chan_attn);
1858 if (result & IE_TDR_SUCCESS)
1861 if (result & IE_TDR_XCVR) {
1862 printf("ie%d: transceiver problem\n", unit);
1863 } else if (result & IE_TDR_OPEN) {
1864 printf("ie%d: TDR detected an open %d clocks away\n", unit,
1865 result & IE_TDR_TIME);
1866 } else if (result & IE_TDR_SHORT) {
1867 printf("ie%d: TDR detected a short %d clocks away\n", unit,
1868 result & IE_TDR_TIME);
1870 printf("ie%d: TDR returned unknown status %x\n", unit, result);
1875 start_receiver(int unit)
1879 ie_softc[unit].scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1880 command_and_wait(unit, IE_RU_START, 0, 0);
1882 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1888 * Here is a helper routine for iernr() and ieinit(). This sets up
1892 setup_rfa(v_caddr_t ptr, struct ie_softc * ie)
1894 volatile struct ie_recv_frame_desc *rfd = (volatile void *)ptr;
1895 volatile struct ie_recv_buf_desc *rbd;
1897 int unit = ie - &ie_softc[0];
1899 /* First lay them out */
1900 for (i = 0; i < ie->nframes; i++) {
1901 ie->rframes[i] = rfd;
1902 bzero((volatile char *) rfd, sizeof *rfd); /* ignore cast-qual */
1906 ptr = Alignvol(rfd); /* ignore cast-qual */
1908 /* Now link them together */
1909 for (i = 0; i < ie->nframes; i++) {
1910 ie->rframes[i]->ie_fd_next =
1911 MK_16(MEM, ie->rframes[(i + 1) % ie->nframes]);
1914 /* Finally, set the EOL bit on the last one. */
1915 ie->rframes[ie->nframes - 1]->ie_fd_last |= IE_FD_LAST;
1918 * Now lay out some buffers for the incoming frames. Note that we
1919 * set aside a bit of slop in each buffer, to make sure that we have
1920 * enough space to hold a single frame in every buffer.
1922 rbd = (volatile void *) ptr;
1924 for (i = 0; i < ie->nrxbufs; i++) {
1925 ie->rbuffs[i] = rbd;
1926 bzero((volatile char *)rbd, sizeof *rbd);
1927 ptr = Alignvol(ptr + sizeof *rbd);
1928 rbd->ie_rbd_length = IE_RBUF_SIZE;
1929 rbd->ie_rbd_buffer = MK_24(MEM, ptr);
1930 ie->cbuffs[i] = (volatile void *) ptr;
1931 ptr += IE_RBUF_SIZE;
1932 rbd = (volatile void *) ptr;
1935 /* Now link them together */
1936 for (i = 0; i < ie->nrxbufs; i++) {
1937 ie->rbuffs[i]->ie_rbd_next =
1938 MK_16(MEM, ie->rbuffs[(i + 1) % ie->nrxbufs]);
1941 /* Tag EOF on the last one */
1942 ie->rbuffs[ie->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST;
1945 * We use the head and tail pointers on receive to keep track of the
1946 * order in which RFDs and RBDs are used.
1949 ie->rftail = ie->nframes - 1;
1951 ie->rbtail = ie->nrxbufs - 1;
1953 ie->scb->ie_recv_list = MK_16(MEM, ie->rframes[0]);
1954 ie->rframes[0]->ie_fd_buf_desc = MK_16(MEM, ie->rbuffs[0]);
1956 ptr = Alignvol(ptr);
1961 * Run the multicast setup command.
1965 mc_setup(int unit, v_caddr_t ptr,
1966 volatile struct ie_sys_ctl_block * scb)
1968 struct ie_softc *ie = &ie_softc[unit];
1969 volatile struct ie_mcast_cmd *cmd = (volatile void *) ptr;
1971 cmd->com.ie_cmd_status = 0;
1972 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1973 cmd->com.ie_cmd_link = 0xffff;
1975 /* ignore cast-qual */
1976 bcopy((v_caddr_t) ie->mcast_addrs, (v_caddr_t) cmd->ie_mcast_addrs,
1977 ie->mcast_count * sizeof *ie->mcast_addrs);
1979 cmd->ie_mcast_bytes = ie->mcast_count * 6; /* grrr... */
1981 scb->ie_command_list = MK_16(MEM, cmd);
1982 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
1983 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1984 printf("ie%d: multicast address setup command failed\n", unit);
1991 * This routine takes the environment generated by check_ie_present()
1992 * and adds to it all the other structures we need to operate the adapter.
1993 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1994 * starting the receiver unit, and clearing interrupts.
1996 * THIS ROUTINE MUST BE CALLED AT splimp() OR HIGHER.
2002 struct ie_softc *ie = xsc;
2003 volatile struct ie_sys_ctl_block *scb = ie->scb;
2006 int unit = ie->unit;
2008 ptr = Alignvol((volatile char *) scb + sizeof *scb);
2011 * Send the configure command first.
2014 volatile struct ie_config_cmd *cmd = (volatile void *) ptr;
2016 ie_setup_config(cmd, ie->promisc,
2017 ie->hard_type == IE_STARLAN10);
2018 cmd->com.ie_cmd_status = 0;
2019 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
2020 cmd->com.ie_cmd_link = 0xffff;
2022 scb->ie_command_list = MK_16(MEM, cmd);
2024 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2025 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2026 printf("ie%d: configure command failed\n", unit);
2031 * Now send the Individual Address Setup command.
2034 volatile struct ie_iasetup_cmd *cmd = (volatile void *) ptr;
2036 cmd->com.ie_cmd_status = 0;
2037 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
2038 cmd->com.ie_cmd_link = 0xffff;
2040 bcopy((volatile char *)ie_softc[unit].arpcom.ac_enaddr,
2041 (volatile char *)&cmd->ie_address, sizeof cmd->ie_address);
2042 scb->ie_command_list = MK_16(MEM, cmd);
2043 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2044 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2045 printf("ie%d: individual address "
2046 "setup command failed\n", unit);
2052 * Now run the time-domain reflectometer.
2054 run_tdr(unit, (volatile void *) ptr);
2057 * Acknowledge any interrupts we have generated thus far.
2059 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
2064 ptr = setup_rfa(ptr, ie);
2067 * Finally, the transmit command and buffer are the last little bit
2071 /* transmit command buffers */
2072 for (i = 0; i < ie->ntxbufs; i++) {
2073 ie->xmit_cmds[i] = (volatile void *) ptr;
2074 ptr += sizeof *ie->xmit_cmds[i];
2075 ptr = Alignvol(ptr);
2076 ie->xmit_buffs[i] = (volatile void *)ptr;
2077 ptr += sizeof *ie->xmit_buffs[i];
2078 ptr = Alignvol(ptr);
2081 /* transmit buffers */
2082 for (i = 0; i < ie->ntxbufs - 1; i++) {
2083 ie->xmit_cbuffs[i] = (volatile void *)ptr;
2085 ptr = Alignvol(ptr);
2087 ie->xmit_cbuffs[ie->ntxbufs - 1] = (volatile void *) ptr;
2089 for (i = 1; i < ie->ntxbufs; i++) {
2090 bzero((v_caddr_t) ie->xmit_cmds[i], sizeof *ie->xmit_cmds[i]);
2091 bzero((v_caddr_t) ie->xmit_buffs[i], sizeof *ie->xmit_buffs[i]);
2095 * This must be coordinated with iestart() and ietint().
2097 ie->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
2099 /* take the ee16 out of loopback */
2100 if (ie->hard_type == IE_EE16) {
2101 u_int8_t bart_config;
2103 bart_config = inb(PORT + IEE16_CONFIG);
2104 bart_config &= ~IEE16_BART_LOOPBACK;
2105 /* inb doesn't get bit! */
2106 bart_config |= IEE16_BART_MCS16_TEST;
2107 outb(PORT + IEE16_CONFIG, bart_config);
2108 ee16_interrupt_enable(ie);
2109 ee16_chan_attn(unit);
2111 ie->arpcom.ac_if.if_flags |= IFF_RUNNING; /* tell higher levels
2113 start_receiver(unit);
2121 command_and_wait(unit, IE_RU_DISABLE, 0, 0);
2125 ieioctl(struct ifnet *ifp, u_long command, caddr_t data)
2135 error = ether_ioctl(ifp, command, data);
2140 * Note that this device doesn't have an "all multicast"
2141 * mode, so we must turn on promiscuous mode and do the
2142 * filtering manually.
2144 if ((ifp->if_flags & IFF_UP) == 0 &&
2145 (ifp->if_flags & IFF_RUNNING)) {
2146 ifp->if_flags &= ~IFF_RUNNING;
2147 ie_stop(ifp->if_unit);
2148 } else if ((ifp->if_flags & IFF_UP) &&
2149 (ifp->if_flags & IFF_RUNNING) == 0) {
2150 ie_softc[ifp->if_unit].promisc =
2151 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2152 ieinit(ifp->if_softc);
2153 } else if (ie_softc[ifp->if_unit].promisc ^
2154 (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) {
2155 ie_softc[ifp->if_unit].promisc =
2156 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2157 ieinit(ifp->if_softc);
2164 * Update multicast listeners
2166 /* reset multicast filtering */
2167 ie_mc_reset(ifp->if_unit);
2180 ie_mc_reset(int unit)
2182 struct ie_softc *ie = &ie_softc[unit];
2183 struct ifmultiaddr *ifma;
2186 * Step through the list of addresses.
2188 ie->mcast_count = 0;
2189 for (ifma = ie->arpcom.ac_if.if_multiaddrs.lh_first; ifma;
2190 ifma = ifma->ifma_link.le_next) {
2191 if (ifma->ifma_addr->sa_family != AF_LINK)
2194 /* XXX - this is broken... */
2195 if (ie->mcast_count >= MAXMCAST) {
2196 ie->arpcom.ac_if.if_flags |= IFF_ALLMULTI;
2197 ieioctl(&ie->arpcom.ac_if, SIOCSIFFLAGS, (void *) 0);
2200 bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
2201 &(ie->mcast_addrs[ie->mcast_count]), 6);
2206 ie->want_mcsetup = 1;
2212 print_rbd(volatile struct ie_recv_buf_desc * rbd)
2214 printf("RBD at %p:\n"
2215 "actual %04x, next %04x, buffer %p\n"
2216 "length %04x, mbz %04x\n",
2217 (volatile void *) rbd,
2218 rbd->ie_rbd_actual, rbd->ie_rbd_next,
2219 (void *) rbd->ie_rbd_buffer,
2220 rbd->ie_rbd_length, rbd->mbz);