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.9 2004/03/23 22:19:01 hsu 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 <bus/isa/i386/isa_device.h>
137 #include <i386/isa/ic/i82586.h>
138 #include <i386/isa/icu.h>
139 #include "if_iereg.h"
140 #include "if_ie507.h"
141 #include "if_iee16.h"
142 #include "../elink_layer/elink.h"
147 #define IED_RINT 0x01
148 #define IED_TINT 0x02
151 #define IED_READFRAME 0x10
152 static int ie_debug = IED_RNR;
156 DECLARE_DUMMY_MODULE(if_ie);
158 #define IE_BUF_LEN ETHER_MAX_LEN /* length of transmit buffer */
160 /* Forward declaration */
163 static int ieprobe(struct isa_device * dvp);
164 static int ieattach(struct isa_device * dvp);
165 static ointhand2_t ieintr;
166 static int sl_probe(struct isa_device * dvp);
167 static int el_probe(struct isa_device * dvp);
168 static int ni_probe(struct isa_device * dvp);
169 static int ee16_probe(struct isa_device * dvp);
171 static int check_ie_present(int unit, caddr_t where, unsigned size);
172 static void ieinit(void *);
173 static void ie_stop(int unit);
174 static int ieioctl(struct ifnet * ifp, u_long command, caddr_t data,
176 static void iestart(struct ifnet * ifp);
178 static void el_reset_586(int unit);
179 static void el_chan_attn(int unit);
181 static void sl_reset_586(int unit);
182 static void sl_chan_attn(int unit);
184 static void ee16_reset_586(int unit);
185 static void ee16_chan_attn(int unit);
186 static __inline void ee16_interrupt_enable(struct ie_softc * ie);
187 static void ee16_eeprom_outbits(struct ie_softc * ie, int edata, int cnt);
188 static void ee16_eeprom_clock(struct ie_softc * ie, int state);
189 static u_short ee16_read_eeprom(struct ie_softc * ie, int location);
190 static int ee16_eeprom_inbits(struct ie_softc * ie);
191 static void ee16_shutdown(void *sc, int howto);
193 static void iereset(int unit);
194 static void ie_readframe(int unit, struct ie_softc * ie, int bufno);
195 static void ie_drop_packet_buffer(int unit, struct ie_softc * ie);
196 static void sl_read_ether(int unit, unsigned char addr[6]);
197 static void find_ie_mem_size(int unit);
198 static void chan_attn_timeout(void *rock);
199 static int command_and_wait(int unit, int command,
200 void volatile * pcmd, int);
201 static void run_tdr(int unit, volatile struct ie_tdr_cmd * cmd);
202 static int ierint(int unit, struct ie_softc * ie);
203 static int ietint(int unit, struct ie_softc * ie);
204 static int iernr(int unit, struct ie_softc * ie);
205 static void start_receiver(int unit);
206 static __inline int ieget(int, struct ie_softc *, struct mbuf **,
207 struct ether_header *);
208 static v_caddr_t setup_rfa(v_caddr_t ptr, struct ie_softc * ie);
209 static int mc_setup(int, v_caddr_t, volatile struct ie_sys_ctl_block *);
210 static void ie_mc_reset(int unit);
213 static void print_rbd(volatile struct ie_recv_buf_desc * rbd);
215 static int in_ierint = 0;
216 static int in_ietint = 0;
221 * This tells the autoconf code how to set us up.
223 struct isa_driver iedriver = {
224 ieprobe, ieattach, "ie",
237 static const char *ie_hardware_names[] = {
248 sizeof(iscp) == 1+1+2+4 == 8
249 sizeof(scb) == 2+2+2+2+2+2+2+2 == 16
250 NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384
251 sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18
252 sizeof(transmit buffer) == 1512
253 sizeof(transmit buffer desc) == 8
257 NRXBUFS * sizeof(rbd) == NRXBUFS*(2+2+4+2+2) == NRXBUFS*12
258 NRXBUFS * IE_RBUF_SIZE == NRXBUFS*256
260 NRXBUFS should be (16384 - 1946) / (256 + 12) == 14438 / 268 == 53
262 With NRXBUFS == 48, this leaves us 1574 bytes for another command or
263 more buffers. Another transmit command would be 18+8+1512 == 1538
266 Obviously all these would have to be reduced for smaller memory sizes.
267 With a larger memory, it would be possible to roughly double the number of
268 both transmit and receive buffers.
271 #define NFRAMES 8 /* number of receive frames */
272 #define NRXBUFS 48 /* number of buffers to allocate */
273 #define IE_RBUF_SIZE 256 /* size of each buffer, MUST BE POWER OF TWO */
274 #define NTXBUFS 2 /* number of transmit commands */
275 #define IE_TBUF_SIZE ETHER_MAX_LEN /* size of transmit buffer */
278 * Ethernet status, per interface.
280 static struct ie_softc {
281 struct arpcom arpcom;
282 void (*ie_reset_586) (int);
283 void (*ie_chan_attn) (int);
284 enum ie_hardware hard_type;
288 u_short port; /* i/o base address for this interface */
289 caddr_t iomem; /* memory size */
290 caddr_t iomembot; /* memory base address */
292 int bus_use; /* 0 means 16bit, 1 means 8 bit adapter */
299 volatile struct ie_int_sys_conf_ptr *iscp;
300 volatile struct ie_sys_ctl_block *scb;
301 volatile struct ie_recv_frame_desc **rframes; /* nframes worth */
302 volatile struct ie_recv_buf_desc **rbuffs; /* nrxbufs worth */
303 volatile u_char **cbuffs; /* nrxbufs worth */
304 int rfhead, rftail, rbhead, rbtail;
306 volatile struct ie_xmit_cmd **xmit_cmds; /* ntxbufs worth */
307 volatile struct ie_xmit_buf **xmit_buffs; /* ntxbufs worth */
308 volatile u_char **xmit_cbuffs; /* ntxbufs worth */
311 struct ie_en_addr mcast_addrs[MAXMCAST + 1];
314 u_short irq_encoded; /* encoded interrupt on IEE16 */
317 #define MK_24(base, ptr) ((caddr_t)((uintptr_t)ptr - (uintptr_t)base))
318 #define MK_16(base, ptr) ((u_short)(uintptr_t)MK_24(base, ptr))
320 #define PORT ie_softc[unit].port
321 #define MEM ie_softc[unit].iomem
324 ieprobe(struct isa_device *dvp)
334 ret = ee16_probe(dvp);
340 sl_probe(struct isa_device *dvp)
342 int unit = dvp->id_unit;
345 ie_softc[unit].port = dvp->id_iobase;
346 ie_softc[unit].iomembot = dvp->id_maddr;
347 ie_softc[unit].iomem = 0;
348 ie_softc[unit].bus_use = 0;
350 c = inb(PORT + IEATT_REVISION);
351 switch (SL_BOARD(c)) {
353 ie_softc[unit].hard_type = IE_STARLAN10;
354 ie_softc[unit].ie_reset_586 = sl_reset_586;
355 ie_softc[unit].ie_chan_attn = sl_chan_attn;
358 ie_softc[unit].hard_type = IE_EN100;
359 ie_softc[unit].ie_reset_586 = sl_reset_586;
360 ie_softc[unit].ie_chan_attn = sl_chan_attn;
363 ie_softc[unit].hard_type = IE_SLFIBER;
364 ie_softc[unit].ie_reset_586 = sl_reset_586;
365 ie_softc[unit].ie_chan_attn = sl_chan_attn;
369 * Anything else is not recognized or cannot be used.
375 ie_softc[unit].hard_vers = SL_REV(c);
378 * Divine memory size on-board the card. Ususally 16k.
380 find_ie_mem_size(unit);
382 if (!ie_softc[unit].iosize) {
385 dvp->id_msize = ie_softc[unit].iosize;
387 switch (ie_softc[unit].hard_type) {
391 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
396 printf("ie%d: unknown AT&T board type code %d\n", unit,
397 ie_softc[unit].hard_type);
406 el_probe(struct isa_device *dvp)
408 struct ie_softc *sc = &ie_softc[dvp->id_unit];
411 u_char signature[] = "*3COM*";
412 int unit = dvp->id_unit;
415 sc->port = dvp->id_iobase;
416 sc->iomembot = dvp->id_maddr;
419 /* Need this for part of the probe. */
420 sc->ie_reset_586 = el_reset_586;
421 sc->ie_chan_attn = el_chan_attn;
423 /* Reset and put card in CONFIG state without changing address. */
425 outb(ELINK_ID_PORT, 0x00);
426 elink_idseq(ELINK_507_POLY);
427 elink_idseq(ELINK_507_POLY);
428 outb(ELINK_ID_PORT, 0xff);
430 c = inb(PORT + IE507_MADDR);
433 printf("ie%d: can't map 3C507 RAM in high memory\n", unit);
437 /* go to RUN state */
438 outb(ELINK_ID_PORT, 0x00);
439 elink_idseq(ELINK_507_POLY);
440 outb(ELINK_ID_PORT, 0x00);
442 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
444 for (i = 0; i < 6; i++)
445 if (inb(PORT + i) != signature[i])
448 c = inb(PORT + IE507_IRQ) & 0x0f;
450 if (dvp->id_irq != (1 << c)) {
451 printf("ie%d: kernel configured irq %d "
452 "doesn't match board configured irq %d\n",
453 unit, ffs(dvp->id_irq) - 1, c);
456 c = (inb(PORT + IE507_MADDR) & 0x1c) + 0xc0;
458 if (kvtop(dvp->id_maddr) != ((int) c << 12)) {
459 printf("ie%d: kernel configured maddr %llx "
460 "doesn't match board configured maddr %x\n",
461 unit, kvtop(dvp->id_maddr), (int) c << 12);
464 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
466 sc->hard_type = IE_3C507;
467 sc->hard_vers = 0; /* 3C507 has no version number. */
470 * Divine memory size on-board the card.
472 find_ie_mem_size(unit);
475 printf("ie%d: can't find shared memory\n", unit);
476 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
480 dvp->id_msize = sc->iosize;
481 else if (dvp->id_msize != sc->iosize) {
482 printf("ie%d: kernel configured msize %d "
483 "doesn't match board configured msize %d\n",
484 unit, dvp->id_msize, sc->iosize);
485 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
488 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
490 /* Clear the interrupt latch just in case. */
491 outb(PORT + IE507_ICTRL, 1);
498 ni_probe(struct isa_device *dvp)
500 int unit = dvp->id_unit;
503 ie_softc[unit].port = dvp->id_iobase;
504 ie_softc[unit].iomembot = dvp->id_maddr;
505 ie_softc[unit].iomem = 0;
506 ie_softc[unit].bus_use = 1;
508 boardtype = inb(PORT + IEATT_REVISION);
509 c = inb(PORT + IEATT_REVISION + 1);
510 boardtype = boardtype + (c << 8);
512 case 0x5500: /* This is the magic cookie for the NI5210 */
513 ie_softc[unit].hard_type = IE_NI5210;
514 ie_softc[unit].ie_reset_586 = sl_reset_586;
515 ie_softc[unit].ie_chan_attn = sl_chan_attn;
519 * Anything else is not recognized or cannot be used.
525 ie_softc[unit].hard_vers = 0;
528 * Divine memory size on-board the card. Either 8 or 16k.
530 find_ie_mem_size(unit);
532 if (!ie_softc[unit].iosize) {
536 dvp->id_msize = ie_softc[unit].iosize;
537 else if (dvp->id_msize != ie_softc[unit].iosize) {
538 printf("ie%d: kernel configured msize %d "
539 "doesn't match board configured msize %d\n",
540 unit, dvp->id_msize, ie_softc[unit].iosize);
543 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
551 ee16_shutdown(void *sc, int howto)
553 struct ie_softc *ie = (struct ie_softc *)sc;
554 int unit = ie - &ie_softc[0];
556 ee16_reset_586(unit);
557 outb(PORT + IEE16_ECTRL, IEE16_RESET_ASIC);
558 outb(PORT + IEE16_ECTRL, 0);
562 /* Taken almost exactly from Rod's if_ix.c. */
565 ee16_probe(struct isa_device *dvp)
567 struct ie_softc *sc = &ie_softc[dvp->id_unit];
570 int unit = dvp->id_unit;
571 u_short board_id, id_var1, id_var2, checksum = 0;
572 u_short eaddrtemp, irq;
573 u_short pg, adjust, decode, edecode;
577 short irq_translate[] = {0, IRQ9, IRQ3, IRQ4, IRQ5, IRQ10, IRQ11, 0};
578 char irq_encode[] = {0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0};
580 /* Need this for part of the probe. */
581 sc->ie_reset_586 = ee16_reset_586;
582 sc->ie_chan_attn = ee16_chan_attn;
584 /* unsure if this is necessary */
587 /* reset any ee16 at the current iobase */
588 outb(dvp->id_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
589 outb(dvp->id_iobase + IEE16_ECTRL, 0);
592 /* now look for ee16. */
593 board_id = id_var1 = id_var2 = 0;
594 for (i = 0; i < 4; i++) {
595 id_var1 = inb(dvp->id_iobase + IEE16_ID_PORT);
596 id_var2 = ((id_var1 & 0x03) << 2);
597 board_id |= ((id_var1 >> 4) << id_var2);
600 if (board_id != IEE16_ID) {
602 printf("ie%d: unknown board_id: %x\n", unit, board_id);
605 /* need sc->port for ee16_read_eeprom */
606 sc->port = dvp->id_iobase;
607 sc->hard_type = IE_EE16;
610 * The shared RAM location on the EE16 is encoded into bits 3-7 of
611 * EEPROM location 6. We zero the upper byte, and shift the 5 bits
612 * right 3. The resulting number tells us the RAM location.
613 * Because the EE16 supports either 16k or 32k of shared RAM, we
614 * only worry about the 32k locations.
616 * NOTE: if a 64k EE16 exists, it should be added to this switch. then
617 * the ia->ia_msize would need to be set per case statement.
619 * value msize location ===== ===== ======== 0x03 0x8000
620 * 0xCC000 0x06 0x8000 0xD0000 0x0C 0x8000 0xD4000 0x18
626 i = (ee16_read_eeprom(sc, 6) & 0x00ff) >> 3;
644 dvp->id_msize = 0x8000;
645 if (kvtop(dvp->id_maddr) != bd_maddr) {
646 printf("ie%d: kernel configured maddr %llx "
647 "doesn't match board configured maddr %lx\n",
648 unit, kvtop(dvp->id_maddr), bd_maddr);
650 sc->iomembot = dvp->id_maddr;
651 sc->iomem = 0; /* XXX some probes set this and some don't */
652 sc->iosize = dvp->id_msize;
654 /* need to put the 586 in RESET while we access the eeprom. */
655 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
657 /* read the eeprom and checksum it, should == IEE16_ID */
658 for (i = 0; i < 0x40; i++)
659 checksum += ee16_read_eeprom(sc, i);
661 if (checksum != IEE16_ID) {
662 printf("ie%d: invalid eeprom checksum: %x\n", unit, checksum);
666 * Size and test the memory on the board. The size of the memory
667 * can be one of 16k, 32k, 48k or 64k. It can be located in the
668 * address range 0xC0000 to 0xEFFFF on 16k boundaries.
670 * If the size does not match the passed in memory allocation size
671 * issue a warning, but continue with the minimum of the two sizes.
674 switch (dvp->id_msize) {
676 case 32768: /* XXX Only support 32k and 64k right now */
681 printf("ie%d: mapped memory size %d not supported\n", unit,
684 break; /* NOTREACHED */
687 if ((kvtop(dvp->id_maddr) < 0xC0000) ||
688 (kvtop(dvp->id_maddr) + sc->iosize > 0xF0000)) {
689 printf("ie%d: mapped memory location %p out of range\n", unit,
690 (void *)dvp->id_maddr);
693 pg = (kvtop(dvp->id_maddr) & 0x3C000) >> 14;
694 adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
695 decode = ((1 << (sc->iosize / 16384)) - 1) << pg;
696 edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
698 /* ZZZ This should be checked against eeprom location 6, low byte */
699 outb(PORT + IEE16_MEMDEC, decode & 0xFF);
700 /* ZZZ This should be checked against eeprom location 1, low byte */
701 outb(PORT + IEE16_MCTRL, adjust);
702 /* ZZZ Now if I could find this one I would have it made */
703 outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
704 /* ZZZ I think this is location 6, high byte */
705 outb(PORT + IEE16_MECTRL, edecode); /* XXX disable Exxx */
707 (void) kvtop(dvp->id_maddr);
710 * first prime the stupid bart DRAM controller so that it works,
711 * then zero out all of memory.
713 bzero(sc->iomembot, 32);
714 bzero(sc->iomembot, sc->iosize);
717 * Get the encoded interrupt number from the EEPROM, check it
718 * against the passed in IRQ. Issue a warning if they do not match.
719 * Always use the passed in IRQ, not the one in the EEPROM.
721 irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
722 irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
723 irq = irq_translate[irq];
724 if (dvp->id_irq > 0) {
725 if (irq != dvp->id_irq) {
726 printf("ie%d: WARNING: board configured "
727 "at irq %u, using %u\n",
728 dvp->id_unit, dvp->id_irq, irq);
734 sc->irq_encoded = irq_encode[ffs(irq) - 1];
737 * Get the hardware ethernet address from the EEPROM and save it in
738 * the softc for use by the 586 setup code.
740 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
741 sc->arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
742 sc->arpcom.ac_enaddr[0] = eaddrtemp >> 8;
743 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
744 sc->arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
745 sc->arpcom.ac_enaddr[2] = eaddrtemp >> 8;
746 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
747 sc->arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
748 sc->arpcom.ac_enaddr[4] = eaddrtemp >> 8;
750 /* disable the board interrupts */
751 outb(PORT + IEE16_IRQ, sc->irq_encoded);
753 /* enable loopback to keep bad packets off the wire */
754 if (sc->hard_type == IE_EE16) {
755 bart_config = inb(PORT + IEE16_CONFIG);
756 bart_config |= IEE16_BART_LOOPBACK;
757 bart_config |= IEE16_BART_MCS16_TEST;/* inb doesn't get bit! */
758 outb(PORT + IEE16_CONFIG, bart_config);
759 bart_config = inb(PORT + IEE16_CONFIG);
761 /* take the board out of reset state */
762 outb(PORT + IEE16_ECTRL, 0);
765 if (!check_ie_present(unit, dvp->id_maddr, sc->iosize))
768 return (16); /* return the number of I/O ports */
772 * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
775 ieattach(struct isa_device *dvp)
778 int unit = dvp->id_unit;
779 struct ie_softc *ie = &ie_softc[unit];
780 struct ifnet *ifp = &ie->arpcom.ac_if;
783 dvp->id_ointr = ieintr;
786 * based on the amount of memory we have, allocate our tx and rx
789 factor = dvp->id_msize / 16384;
790 ie->nframes = factor * NFRAMES;
791 ie->nrxbufs = factor * NRXBUFS;
792 ie->ntxbufs = factor * NTXBUFS;
795 * Since all of these guys are arrays of pointers, allocate as one
796 * big chunk and dole out accordingly.
798 allocsize = sizeof(void *) * (ie->nframes
800 + (ie->ntxbufs * 3));
801 ie->rframes = (volatile struct ie_recv_frame_desc **) malloc(allocsize,
804 if (ie->rframes == NULL)
807 (volatile struct ie_recv_buf_desc **)&ie->rframes[ie->nframes];
808 ie->cbuffs = (volatile u_char **)&ie->rbuffs[ie->nrxbufs];
810 (volatile struct ie_xmit_cmd **)&ie->cbuffs[ie->nrxbufs];
812 (volatile struct ie_xmit_buf **)&ie->xmit_cmds[ie->ntxbufs];
813 ie->xmit_cbuffs = (volatile u_char **)&ie->xmit_buffs[ie->ntxbufs];
816 if_initname(ifp, iedriver.name, unit);
817 ifp->if_mtu = ETHERMTU;
818 printf("ie%d: <%s R%d> address %6D\n", unit,
819 ie_hardware_names[ie->hard_type],
821 ie->arpcom.ac_enaddr, ":");
823 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
824 ifp->if_output = ether_output;
825 ifp->if_start = iestart;
826 ifp->if_ioctl = ieioctl;
827 ifp->if_init = ieinit;
828 ifp->if_type = IFT_ETHER;
831 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
833 if (ie->hard_type == IE_EE16)
834 EVENTHANDLER_REGISTER(shutdown_post_sync, ee16_shutdown,
835 ie, SHUTDOWN_PRI_DEFAULT);
837 ether_ifattach(ifp, ie->arpcom.ac_enaddr);
842 * What to do upon receipt of an interrupt.
847 struct ie_softc *ie = &ie_softc[unit];
850 /* Clear the interrupt latch on the 3C507. */
851 if (ie->hard_type == IE_3C507
852 && (inb(PORT + IE507_CTRL) & EL_CTRL_INTL))
853 outb(PORT + IE507_ICTRL, 1);
855 /* disable interrupts on the EE16. */
856 if (ie->hard_type == IE_EE16)
857 outb(PORT + IEE16_IRQ, ie->irq_encoded);
859 status = ie->scb->ie_status;
863 /* Don't ack interrupts which we didn't receive */
864 ie_ack(ie->scb, IE_ST_WHENCE & status, unit, ie->ie_chan_attn);
866 if (status & (IE_ST_RECV | IE_ST_RNR)) {
869 if (ie_debug & IED_RINT)
870 printf("ie%d: rint\n", unit);
877 if (status & IE_ST_DONE) {
880 if (ie_debug & IED_TINT)
881 printf("ie%d: tint\n", unit);
888 if (status & IE_ST_RNR) {
890 if (ie_debug & IED_RNR)
891 printf("ie%d: rnr\n", unit);
896 if ((status & IE_ST_ALLDONE)
897 && (ie_debug & IED_CNA))
898 printf("ie%d: cna\n", unit);
901 if ((status = ie->scb->ie_status) & IE_ST_WHENCE)
904 /* Clear the interrupt latch on the 3C507. */
905 if (ie->hard_type == IE_3C507)
906 outb(PORT + IE507_ICTRL, 1);
908 /* enable interrupts on the EE16. */
909 if (ie->hard_type == IE_EE16)
910 outb(PORT + IEE16_IRQ, ie->irq_encoded | IEE16_IRQ_ENABLE);
915 * Process a received-frame interrupt.
918 ierint(int unit, struct ie_softc *ie)
921 static int timesthru = 1024;
925 status = ie->rframes[i]->ie_fd_status;
927 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
928 ie->arpcom.ac_if.if_ipackets++;
930 ie->arpcom.ac_if.if_ierrors +=
931 ie->scb->ie_err_crc +
932 ie->scb->ie_err_align +
933 ie->scb->ie_err_resource +
934 ie->scb->ie_err_overrun;
935 ie->scb->ie_err_crc = 0;
936 ie->scb->ie_err_align = 0;
937 ie->scb->ie_err_resource = 0;
938 ie->scb->ie_err_overrun = 0;
941 ie_readframe(unit, ie, i);
943 if (status & IE_FD_RNR) {
944 if (!(ie->scb->ie_status & IE_RU_READY)) {
945 ie->rframes[0]->ie_fd_next =
946 MK_16(MEM, ie->rbuffs[0]);
947 ie->scb->ie_recv_list =
948 MK_16(MEM, ie->rframes[0]);
949 command_and_wait(unit, IE_RU_START,
955 i = (i + 1) % ie->nframes;
961 * Process a command-complete interrupt. These are only generated by
962 * the transmission of frames. This routine is deceptively simple, since
963 * most of the real work is done by iestart().
966 ietint(int unit, struct ie_softc *ie)
971 ie->arpcom.ac_if.if_timer = 0;
972 ie->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
974 for (i = 0; i < ie->xmit_count; i++) {
975 status = ie->xmit_cmds[i]->ie_xmit_status;
977 if (status & IE_XS_LATECOLL) {
978 printf("ie%d: late collision\n", unit);
979 ie->arpcom.ac_if.if_collisions++;
980 ie->arpcom.ac_if.if_oerrors++;
981 } else if (status & IE_XS_NOCARRIER) {
982 printf("ie%d: no carrier\n", unit);
983 ie->arpcom.ac_if.if_oerrors++;
984 } else if (status & IE_XS_LOSTCTS) {
985 printf("ie%d: lost CTS\n", unit);
986 ie->arpcom.ac_if.if_oerrors++;
987 } else if (status & IE_XS_UNDERRUN) {
988 printf("ie%d: DMA underrun\n", unit);
989 ie->arpcom.ac_if.if_oerrors++;
990 } else if (status & IE_XS_EXCMAX) {
991 printf("ie%d: too many collisions\n", unit);
992 ie->arpcom.ac_if.if_collisions += 16;
993 ie->arpcom.ac_if.if_oerrors++;
995 ie->arpcom.ac_if.if_opackets++;
996 ie->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL;
1002 * If multicast addresses were added or deleted while we were
1003 * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
1004 * that we should do it.
1006 if (ie->want_mcsetup) {
1007 mc_setup(unit, (v_caddr_t) ie->xmit_cbuffs[0], ie->scb);
1008 ie->want_mcsetup = 0;
1010 /* Wish I knew why this seems to be necessary... */
1011 ie->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
1013 iestart(&ie->arpcom.ac_if);
1014 return (0); /* shouldn't be necessary */
1018 * Process a receiver-not-ready interrupt. I believe that we get these
1019 * when there aren't enough buffers to go around. For now (FIXME), we
1020 * just restart the receiver, and hope everything's ok.
1023 iernr(int unit, struct ie_softc *ie)
1026 setup_rfa((v_caddr_t) ie->rframes[0], ie);
1028 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1029 command_and_wait(unit, IE_RU_START, 0, 0);
1031 /* This doesn't work either, but it doesn't hang either. */
1032 command_and_wait(unit, IE_RU_DISABLE, 0, 0); /* just in case */
1033 setup_rfa((v_caddr_t) ie->rframes[0], ie); /* ignore cast-qual */
1035 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1036 command_and_wait(unit, IE_RU_START, 0, 0); /* was ENABLE */
1039 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
1041 ie->arpcom.ac_if.if_ierrors++;
1046 * Compare two Ether/802 addresses for equality, inlined and
1047 * unrolled for speed. I'd love to have an inline assembler
1048 * version of this...
1051 ether_equal(u_char * one, u_char * two)
1053 if (one[0] != two[0])
1055 if (one[1] != two[1])
1057 if (one[2] != two[2])
1059 if (one[3] != two[3])
1061 if (one[4] != two[4])
1063 if (one[5] != two[5])
1069 * Determine quickly whether we should bother reading in this packet.
1070 * This depends on whether BPF and/or bridging is enabled, whether we
1071 * are receiving multicast address, and whether promiscuous mode is enabled.
1072 * We assume that if IFF_PROMISC is set, then *somebody* wants to see
1073 * all incoming packets.
1076 check_eh(struct ie_softc *ie, struct ether_header *eh)
1078 /* Optimize the common case: normal operation. We've received
1079 either a unicast with our dest or a multicast packet. */
1080 if (ie->promisc == 0) {
1083 /* If not multicast, it's definitely for us */
1084 if ((eh->ether_dhost[0] & 1) == 0)
1087 /* Accept broadcasts (loose but fast check) */
1088 if (eh->ether_dhost[0] == 0xff)
1091 /* Compare against our multicast addresses */
1092 for (i = 0; i < ie->mcast_count; i++) {
1093 if (ether_equal(eh->ether_dhost,
1094 (u_char *)&ie->mcast_addrs[i]))
1100 /* Always accept packets when in promiscuous mode */
1101 if ((ie->promisc & IFF_PROMISC) != 0)
1104 /* Always accept packets directed at us */
1105 if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1108 /* Must have IFF_ALLMULTI but not IFF_PROMISC set. The chip is
1109 actually in promiscuous mode, so discard unicast packets. */
1110 return((eh->ether_dhost[0] & 1) != 0);
1114 * We want to isolate the bits that have meaning... This assumes that
1115 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds
1116 * the size of the buffer, then we are screwed anyway.
1119 ie_buflen(struct ie_softc * ie, int head)
1121 return (ie->rbuffs[head]->ie_rbd_actual
1122 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
1126 ie_packet_len(int unit, struct ie_softc * ie)
1129 int head = ie->rbhead;
1133 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1135 print_rbd(ie->rbuffs[ie->rbhead]);
1138 "ie%d: receive descriptors out of sync at %d\n",
1143 i = ie->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
1145 acc += ie_buflen(ie, head);
1146 head = (head + 1) % ie->nrxbufs;
1153 * Read data off the interface, and turn it into an mbuf chain.
1155 * This code is DRAMATICALLY different from the previous version; this
1156 * version tries to allocate the entire mbuf chain up front, given the
1157 * length of the data available. This enables us to allocate mbuf
1158 * clusters in many situations where before we would have had a long
1159 * chain of partially-full mbufs. This should help to speed up the
1160 * operation considerably. (Provided that it works, of course.)
1163 ieget(int unit, struct ie_softc *ie, struct mbuf **mp, struct ether_header *ehp)
1165 struct mbuf *m, *top, **mymp;
1172 totlen = ie_packet_len(unit, ie);
1179 * Snarf the Ethernet header.
1181 bcopy((v_caddr_t) ie->cbuffs[i], (caddr_t) ehp, sizeof *ehp);
1182 /* ignore cast-qual warning here */
1185 * As quickly as possible, check if this packet is for us. If not,
1186 * don't waste a single cycle copying the rest of the packet in.
1187 * This is only a consideration when FILTER is defined; i.e., when
1188 * we are either running BPF or doing multicasting.
1190 if (!check_eh(ie, ehp)) {
1191 ie_drop_packet_buffer(unit, ie);
1192 ie->arpcom.ac_if.if_ierrors--; /* just this case, it's not an
1197 totlen -= (offset = sizeof *ehp);
1199 MGETHDR(*mp, M_DONTWAIT, MT_DATA);
1201 ie_drop_packet_buffer(unit, ie);
1205 m->m_pkthdr.rcvif = &ie->arpcom.ac_if;
1207 resid = m->m_pkthdr.len = totlen;
1212 * This loop goes through and allocates mbufs for all the data we
1213 * will be copying in. It does not actually do the copying yet.
1215 do { /* while(resid > 0) */
1217 * Try to allocate an mbuf to hold the data that we have.
1218 * If we already allocated one, just get another one and
1219 * stick it on the end (eventually). If we don't already
1220 * have one, try to allocate an mbuf cluster big enough to
1221 * hold the whole packet, if we think it's reasonable, or a
1222 * single mbuf which may or may not be big enough. Got that?
1225 MGET(m, M_DONTWAIT, MT_DATA);
1228 ie_drop_packet_buffer(unit, ie);
1233 if (resid >= MINCLSIZE) {
1234 MCLGET(m, M_DONTWAIT);
1235 if (m->m_flags & M_EXT)
1236 m->m_len = min(resid, MCLBYTES);
1238 if (resid < m->m_len) {
1239 if (!top && resid + max_linkhdr <= m->m_len)
1240 m->m_data += max_linkhdr;
1247 } while (resid > 0);
1255 * Now we take the mbuf chain (hopefully only one mbuf most of the
1256 * time) and stuff the data into it. There are no possible failures
1257 * at or after this point.
1259 while (resid > 0) { /* while there's stuff left */
1260 int thislen = ie_buflen(ie, head) - offset;
1263 * If too much data for the current mbuf, then fill the
1264 * current one up, go to the next one, and try again.
1266 if (thislen > m->m_len - thismboff) {
1267 int newlen = m->m_len - thismboff;
1269 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1270 mtod(m, v_caddr_t) +thismboff, (unsigned) newlen);
1271 /* ignore cast-qual warning */
1273 thismboff = 0; /* new mbuf, so no offset */
1274 offset += newlen; /* we are now this far into
1276 resid -= newlen; /* so there is this much left
1281 * If there is more than enough space in the mbuf to hold
1282 * the contents of this buffer, copy everything in, advance
1283 * pointers, and so on.
1285 if (thislen < m->m_len - thismboff) {
1286 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1287 mtod(m, caddr_t) +thismboff, (unsigned) thislen);
1288 thismboff += thislen; /* we are this far into the
1290 resid -= thislen; /* and this much is left */
1294 * Otherwise, there is exactly enough space to put this
1295 * buffer's contents into the current mbuf. Do the
1296 * combination of the above actions.
1298 bcopy((v_caddr_t) (ie->cbuffs[head] + offset),
1299 mtod(m, caddr_t) + thismboff, (unsigned) thislen);
1301 thismboff = 0; /* new mbuf, start at the beginning */
1302 resid -= thislen; /* and we are this far through */
1305 * Advance all the pointers. We can get here from either of
1306 * the last two cases, but never the first.
1310 ie->rbuffs[head]->ie_rbd_actual = 0;
1311 ie->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
1312 ie->rbhead = head = (head + 1) % ie->nrxbufs;
1313 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1314 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1318 * Unless something changed strangely while we were doing the copy,
1319 * we have now copied everything in from the shared memory. This
1320 * means that we are done.
1326 * Read frame NUM from unit UNIT (pre-cached as IE).
1328 * This routine reads the RFD at NUM, and copies in the buffers from
1329 * the list of RBD, then rotates the RBD and RFD lists so that the receiver
1330 * doesn't start complaining. Trailers are DROPPED---there's no point
1331 * in wasting time on confusing code to deal with them. Hopefully,
1332 * this machine will never ARP for trailers anyway.
1335 ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
1337 struct ie_recv_frame_desc rfd;
1339 struct ether_header eh;
1341 bcopy((v_caddr_t) (ie->rframes[num]), &rfd,
1342 sizeof(struct ie_recv_frame_desc));
1345 * Immediately advance the RFD list, since we we have copied ours
1348 ie->rframes[num]->ie_fd_status = 0;
1349 ie->rframes[num]->ie_fd_last |= IE_FD_LAST;
1350 ie->rframes[ie->rftail]->ie_fd_last &= ~IE_FD_LAST;
1351 ie->rftail = (ie->rftail + 1) % ie->nframes;
1352 ie->rfhead = (ie->rfhead + 1) % ie->nframes;
1354 if (rfd.ie_fd_status & IE_FD_OK) {
1355 if (ieget(unit, ie, &m, &eh)) {
1356 ie->arpcom.ac_if.if_ierrors++; /* this counts as an
1362 if (ie_debug & IED_READFRAME) {
1363 printf("ie%d: frame from ether %6D type %x\n", unit,
1364 eh.ether_shost, ":", (unsigned) eh.ether_type);
1366 if (ntohs(eh.ether_type) > ETHERTYPE_TRAIL
1367 && ntohs(eh.ether_type) < (ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER))
1368 printf("received trailer!\n");
1375 * Finally pass this packet up to higher layers.
1377 ether_input(&ie->arpcom.ac_if, &eh, m);
1381 ie_drop_packet_buffer(int unit, struct ie_softc * ie)
1387 * This means we are somehow out of sync. So, we reset the
1390 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1392 print_rbd(ie->rbuffs[ie->rbhead]);
1394 log(LOG_ERR, "ie%d: receive descriptors out of sync at %d\n",
1399 i = ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1401 ie->rbuffs[ie->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1402 ie->rbuffs[ie->rbhead]->ie_rbd_actual = 0;
1403 ie->rbhead = (ie->rbhead + 1) % ie->nrxbufs;
1404 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1405 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1411 * Start transmission on an interface.
1414 iestart(struct ifnet *ifp)
1416 struct ie_softc *ie = ifp->if_softc;
1417 struct mbuf *m0, *m;
1418 volatile unsigned char *buffer;
1422 * This is not really volatile, in this routine, but it makes gcc
1425 volatile u_short *bptr = &ie->scb->ie_command_list;
1427 if (!(ifp->if_flags & IFF_RUNNING))
1429 if (ifp->if_flags & IFF_OACTIVE)
1433 IF_DEQUEUE(&ie->arpcom.ac_if.if_snd, m);
1437 buffer = ie->xmit_cbuffs[ie->xmit_count];
1440 for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) {
1441 bcopy(mtod(m, caddr_t), buffer, m->m_len);
1447 len = max(len, ETHER_MIN_LEN);
1450 * See if bpf is listening on this interface, let it see the
1451 * packet before we commit it to the wire.
1453 if (ie->arpcom.ac_if.if_bpf)
1454 bpf_tap(&ie->arpcom.ac_if,
1455 (void *)ie->xmit_cbuffs[ie->xmit_count], len);
1457 ie->xmit_buffs[ie->xmit_count]->ie_xmit_flags =
1459 ie->xmit_buffs[ie->xmit_count]->ie_xmit_next = 0xffff;
1460 ie->xmit_buffs[ie->xmit_count]->ie_xmit_buf =
1461 MK_24(ie->iomem, ie->xmit_cbuffs[ie->xmit_count]);
1463 ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT;
1464 ie->xmit_cmds[ie->xmit_count]->ie_xmit_status = 0;
1465 ie->xmit_cmds[ie->xmit_count]->ie_xmit_desc =
1466 MK_16(ie->iomem, ie->xmit_buffs[ie->xmit_count]);
1468 *bptr = MK_16(ie->iomem, ie->xmit_cmds[ie->xmit_count]);
1469 bptr = &ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_link;
1471 } while (ie->xmit_count < ie->ntxbufs);
1474 * If we queued up anything for transmission, send it.
1476 if (ie->xmit_count) {
1477 ie->xmit_cmds[ie->xmit_count - 1]->com.ie_cmd_cmd |=
1478 IE_CMD_LAST | IE_CMD_INTR;
1481 * By passing the command pointer as a null, we tell
1482 * command_and_wait() to pretend that this isn't an action
1483 * command. I wish I understood what was happening here.
1485 command_and_wait(ifp->if_dunit, IE_CU_START, 0, 0);
1486 ifp->if_flags |= IFF_OACTIVE;
1492 * Check to see if there's an 82586 out there.
1495 check_ie_present(int unit, caddr_t where, unsigned size)
1497 volatile struct ie_sys_conf_ptr *scp;
1498 volatile struct ie_int_sys_conf_ptr *iscp;
1499 volatile struct ie_sys_ctl_block *scb;
1505 realbase = (uintptr_t) where + size - (1 << 24);
1507 scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t)
1508 (realbase + IE_SCP_ADDR);
1509 bzero((volatile char *) scp, sizeof *scp);
1512 * First we put the ISCP at the bottom of memory; this tests to make
1513 * sure that our idea of the size of memory is the same as the
1514 * controller's. This is NOT where the ISCP will be in normal
1517 iscp = (volatile struct ie_int_sys_conf_ptr *) where;
1518 bzero((volatile char *)iscp, sizeof *iscp);
1520 scb = (volatile struct ie_sys_ctl_block *) where;
1521 bzero((volatile char *)scb, sizeof *scb);
1523 scp->ie_bus_use = ie_softc[unit].bus_use; /* 8-bit or 16-bit */
1524 scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1525 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1528 iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1530 (*ie_softc[unit].ie_reset_586) (unit);
1531 (*ie_softc[unit].ie_chan_attn) (unit);
1533 DELAY(100); /* wait a while... */
1535 if (iscp->ie_busy) {
1540 * Now relocate the ISCP to its real home, and reset the controller
1543 iscp = (void *) Align((caddr_t) (uintptr_t)
1544 (realbase + IE_SCP_ADDR -
1545 sizeof(struct ie_int_sys_conf_ptr)));
1546 bzero((volatile char *) iscp, sizeof *iscp); /* ignore cast-qual */
1548 scp->ie_iscp_ptr = (caddr_t) (uintptr_t)
1549 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase);
1552 iscp->ie_scb_offset = MK_16(realbase, scb);
1554 (*ie_softc[unit].ie_reset_586) (unit);
1555 (*ie_softc[unit].ie_chan_attn) (unit);
1559 if (iscp->ie_busy) {
1563 ie_softc[unit].iosize = size;
1564 ie_softc[unit].iomem = (caddr_t) (uintptr_t) realbase;
1566 ie_softc[unit].iscp = iscp;
1567 ie_softc[unit].scb = scb;
1570 * Acknowledge any interrupts we may have caused...
1572 ie_ack(scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1579 * Divine the memory size of ie board UNIT.
1580 * Better hope there's nothing important hiding just below the ie card...
1583 find_ie_mem_size(int unit)
1587 ie_softc[unit].iosize = 0;
1589 for (size = 65536; size >= 8192; size -= 8192) {
1590 if (check_ie_present(unit, ie_softc[unit].iomembot, size)) {
1599 el_reset_586(int unit)
1601 outb(PORT + IE507_CTRL, EL_CTRL_RESET);
1603 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
1608 sl_reset_586(int unit)
1610 outb(PORT + IEATT_RESET, 0);
1614 ee16_reset_586(int unit)
1616 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
1618 outb(PORT + IEE16_ECTRL, 0);
1623 el_chan_attn(int unit)
1625 outb(PORT + IE507_ATTN, 1);
1629 sl_chan_attn(int unit)
1631 outb(PORT + IEATT_ATTN, 0);
1635 ee16_chan_attn(int unit)
1637 outb(PORT + IEE16_ATTN, 0);
1641 ee16_read_eeprom(struct ie_softc *sc, int location)
1645 ectrl = inb(sc->port + IEE16_ECTRL);
1646 ectrl &= IEE16_ECTRL_MASK;
1647 ectrl |= IEE16_ECTRL_EECS;
1648 outb(sc->port + IEE16_ECTRL, ectrl);
1650 ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
1651 ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
1652 edata = ee16_eeprom_inbits(sc);
1653 ectrl = inb(sc->port + IEE16_ECTRL);
1654 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
1655 outb(sc->port + IEE16_ECTRL, ectrl);
1656 ee16_eeprom_clock(sc, 1);
1657 ee16_eeprom_clock(sc, 0);
1662 ee16_eeprom_outbits(struct ie_softc *sc, int edata, int count)
1666 ectrl = inb(sc->port + IEE16_ECTRL);
1667 ectrl &= ~IEE16_RESET_ASIC;
1668 for (i = count - 1; i >= 0; i--) {
1669 ectrl &= ~IEE16_ECTRL_EEDI;
1670 if (edata & (1 << i)) {
1671 ectrl |= IEE16_ECTRL_EEDI;
1673 outb(sc->port + IEE16_ECTRL, ectrl);
1674 DELAY(1); /* eeprom data must be setup for 0.4 uSec */
1675 ee16_eeprom_clock(sc, 1);
1676 ee16_eeprom_clock(sc, 0);
1678 ectrl &= ~IEE16_ECTRL_EEDI;
1679 outb(sc->port + IEE16_ECTRL, ectrl);
1680 DELAY(1); /* eeprom data must be held for 0.4 uSec */
1684 ee16_eeprom_inbits(struct ie_softc *sc)
1686 int ectrl, edata, i;
1688 ectrl = inb(sc->port + IEE16_ECTRL);
1689 ectrl &= ~IEE16_RESET_ASIC;
1690 for (edata = 0, i = 0; i < 16; i++) {
1692 ee16_eeprom_clock(sc, 1);
1693 ectrl = inb(sc->port + IEE16_ECTRL);
1694 if (ectrl & IEE16_ECTRL_EEDO) {
1697 ee16_eeprom_clock(sc, 0);
1703 ee16_eeprom_clock(struct ie_softc *sc, int state)
1707 ectrl = inb(sc->port + IEE16_ECTRL);
1708 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
1710 ectrl |= IEE16_ECTRL_EESK;
1712 outb(sc->port + IEE16_ECTRL, ectrl);
1713 DELAY(9); /* EESK must be stable for 8.38 uSec */
1716 static __inline void
1717 ee16_interrupt_enable(struct ie_softc *sc)
1720 outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1725 sl_read_ether(int unit, unsigned char addr[6])
1729 for (i = 0; i < 6; i++)
1730 addr[i] = inb(PORT + i);
1743 printf("ie%d: reset\n", unit);
1744 ie_softc[unit].arpcom.ac_if.if_flags &= ~IFF_UP;
1745 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, (struct ucred *)NULL);
1748 * Stop i82586 dead in its tracks.
1750 if (command_and_wait(unit, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1751 printf("ie%d: abort commands timed out\n", unit);
1753 if (command_and_wait(unit, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1754 printf("ie%d: disable commands timed out\n", unit);
1757 if (!check_ie_present(unit, ie_softc[unit].iomembot,
1758 e_softc[unit].iosize))
1759 panic("ie disappeared!");
1762 ie_softc[unit].arpcom.ac_if.if_flags |= IFF_UP;
1763 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0, (struct ucred *)NULL);
1770 * This is called if we time out.
1773 chan_attn_timeout(void *rock)
1779 * Send a command to the controller and wait for it to either
1780 * complete or be accepted, depending on the command. If the
1781 * command pointer is null, then pretend that the command is
1782 * not an action command. If the command pointer is not null,
1783 * and the command is an action command, wait for
1784 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1788 command_and_wait(int unit, int cmd, volatile void *pcmd, int mask)
1790 volatile struct ie_cmd_common *cc = pcmd;
1791 volatile int timedout = 0;
1792 struct callout_handle ch;
1794 ie_softc[unit].scb->ie_command = (u_short) cmd;
1796 if (IE_ACTION_COMMAND(cmd) && pcmd) {
1797 (*ie_softc[unit].ie_chan_attn) (unit);
1800 * According to the packet driver, the minimum timeout
1801 * should be .369 seconds, which we round up to .37.
1803 ch = timeout(chan_attn_timeout, &timedout,
1805 /* ignore cast-qual */
1808 * Now spin-lock waiting for status. This is not a very
1809 * nice thing to do, but I haven't figured out how, or
1810 * indeed if, we can put the process waiting for action to
1811 * sleep. (We may be getting called through some other
1812 * timeout running in the kernel.)
1815 if ((cc->ie_cmd_status & mask) || timedout)
1819 untimeout(chan_attn_timeout, (caddr_t)&timedout, ch);
1820 /* ignore cast-qual */
1826 * Otherwise, just wait for the command to be accepted.
1828 (*ie_softc[unit].ie_chan_attn) (unit);
1830 while (ie_softc[unit].scb->ie_command); /* spin lock */
1837 * Run the time-domain reflectometer...
1840 run_tdr(int unit, volatile struct ie_tdr_cmd *cmd)
1844 cmd->com.ie_cmd_status = 0;
1845 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1846 cmd->com.ie_cmd_link = 0xffff;
1847 cmd->ie_tdr_time = 0;
1849 ie_softc[unit].scb->ie_command_list = MK_16(MEM, cmd);
1850 cmd->ie_tdr_time = 0;
1852 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL))
1855 result = cmd->ie_tdr_time;
1857 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit,
1858 ie_softc[unit].ie_chan_attn);
1860 if (result & IE_TDR_SUCCESS)
1863 if (result & IE_TDR_XCVR) {
1864 printf("ie%d: transceiver problem\n", unit);
1865 } else if (result & IE_TDR_OPEN) {
1866 printf("ie%d: TDR detected an open %d clocks away\n", unit,
1867 result & IE_TDR_TIME);
1868 } else if (result & IE_TDR_SHORT) {
1869 printf("ie%d: TDR detected a short %d clocks away\n", unit,
1870 result & IE_TDR_TIME);
1872 printf("ie%d: TDR returned unknown status %x\n", unit, result);
1877 start_receiver(int unit)
1881 ie_softc[unit].scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1882 command_and_wait(unit, IE_RU_START, 0, 0);
1884 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1890 * Here is a helper routine for iernr() and ieinit(). This sets up
1894 setup_rfa(v_caddr_t ptr, struct ie_softc * ie)
1896 volatile struct ie_recv_frame_desc *rfd = (volatile void *)ptr;
1897 volatile struct ie_recv_buf_desc *rbd;
1899 int unit = ie - &ie_softc[0];
1901 /* First lay them out */
1902 for (i = 0; i < ie->nframes; i++) {
1903 ie->rframes[i] = rfd;
1904 bzero((volatile char *) rfd, sizeof *rfd); /* ignore cast-qual */
1908 ptr = Alignvol(rfd); /* ignore cast-qual */
1910 /* Now link them together */
1911 for (i = 0; i < ie->nframes; i++) {
1912 ie->rframes[i]->ie_fd_next =
1913 MK_16(MEM, ie->rframes[(i + 1) % ie->nframes]);
1916 /* Finally, set the EOL bit on the last one. */
1917 ie->rframes[ie->nframes - 1]->ie_fd_last |= IE_FD_LAST;
1920 * Now lay out some buffers for the incoming frames. Note that we
1921 * set aside a bit of slop in each buffer, to make sure that we have
1922 * enough space to hold a single frame in every buffer.
1924 rbd = (volatile void *) ptr;
1926 for (i = 0; i < ie->nrxbufs; i++) {
1927 ie->rbuffs[i] = rbd;
1928 bzero((volatile char *)rbd, sizeof *rbd);
1929 ptr = Alignvol(ptr + sizeof *rbd);
1930 rbd->ie_rbd_length = IE_RBUF_SIZE;
1931 rbd->ie_rbd_buffer = MK_24(MEM, ptr);
1932 ie->cbuffs[i] = (volatile void *) ptr;
1933 ptr += IE_RBUF_SIZE;
1934 rbd = (volatile void *) ptr;
1937 /* Now link them together */
1938 for (i = 0; i < ie->nrxbufs; i++) {
1939 ie->rbuffs[i]->ie_rbd_next =
1940 MK_16(MEM, ie->rbuffs[(i + 1) % ie->nrxbufs]);
1943 /* Tag EOF on the last one */
1944 ie->rbuffs[ie->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST;
1947 * We use the head and tail pointers on receive to keep track of the
1948 * order in which RFDs and RBDs are used.
1951 ie->rftail = ie->nframes - 1;
1953 ie->rbtail = ie->nrxbufs - 1;
1955 ie->scb->ie_recv_list = MK_16(MEM, ie->rframes[0]);
1956 ie->rframes[0]->ie_fd_buf_desc = MK_16(MEM, ie->rbuffs[0]);
1958 ptr = Alignvol(ptr);
1963 * Run the multicast setup command.
1967 mc_setup(int unit, v_caddr_t ptr,
1968 volatile struct ie_sys_ctl_block * scb)
1970 struct ie_softc *ie = &ie_softc[unit];
1971 volatile struct ie_mcast_cmd *cmd = (volatile void *) ptr;
1973 cmd->com.ie_cmd_status = 0;
1974 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1975 cmd->com.ie_cmd_link = 0xffff;
1977 /* ignore cast-qual */
1978 bcopy((v_caddr_t) ie->mcast_addrs, (v_caddr_t) cmd->ie_mcast_addrs,
1979 ie->mcast_count * sizeof *ie->mcast_addrs);
1981 cmd->ie_mcast_bytes = ie->mcast_count * 6; /* grrr... */
1983 scb->ie_command_list = MK_16(MEM, cmd);
1984 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
1985 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
1986 printf("ie%d: multicast address setup command failed\n", unit);
1993 * This routine takes the environment generated by check_ie_present()
1994 * and adds to it all the other structures we need to operate the adapter.
1995 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1996 * starting the receiver unit, and clearing interrupts.
1998 * THIS ROUTINE MUST BE CALLED AT splimp() OR HIGHER.
2004 struct ie_softc *ie = xsc;
2005 volatile struct ie_sys_ctl_block *scb = ie->scb;
2008 int unit = ie->unit;
2010 ptr = Alignvol((volatile char *) scb + sizeof *scb);
2013 * Send the configure command first.
2016 volatile struct ie_config_cmd *cmd = (volatile void *) ptr;
2018 ie_setup_config(cmd, ie->promisc,
2019 ie->hard_type == IE_STARLAN10);
2020 cmd->com.ie_cmd_status = 0;
2021 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
2022 cmd->com.ie_cmd_link = 0xffff;
2024 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)) {
2028 printf("ie%d: configure command failed\n", unit);
2033 * Now send the Individual Address Setup command.
2036 volatile struct ie_iasetup_cmd *cmd = (volatile void *) ptr;
2038 cmd->com.ie_cmd_status = 0;
2039 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
2040 cmd->com.ie_cmd_link = 0xffff;
2042 bcopy((volatile char *)ie_softc[unit].arpcom.ac_enaddr,
2043 (volatile char *)&cmd->ie_address, sizeof cmd->ie_address);
2044 scb->ie_command_list = MK_16(MEM, cmd);
2045 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2046 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2047 printf("ie%d: individual address "
2048 "setup command failed\n", unit);
2054 * Now run the time-domain reflectometer.
2056 run_tdr(unit, (volatile void *) ptr);
2059 * Acknowledge any interrupts we have generated thus far.
2061 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
2066 ptr = setup_rfa(ptr, ie);
2069 * Finally, the transmit command and buffer are the last little bit
2073 /* transmit command buffers */
2074 for (i = 0; i < ie->ntxbufs; i++) {
2075 ie->xmit_cmds[i] = (volatile void *) ptr;
2076 ptr += sizeof *ie->xmit_cmds[i];
2077 ptr = Alignvol(ptr);
2078 ie->xmit_buffs[i] = (volatile void *)ptr;
2079 ptr += sizeof *ie->xmit_buffs[i];
2080 ptr = Alignvol(ptr);
2083 /* transmit buffers */
2084 for (i = 0; i < ie->ntxbufs - 1; i++) {
2085 ie->xmit_cbuffs[i] = (volatile void *)ptr;
2087 ptr = Alignvol(ptr);
2089 ie->xmit_cbuffs[ie->ntxbufs - 1] = (volatile void *) ptr;
2091 for (i = 1; i < ie->ntxbufs; i++) {
2092 bzero((v_caddr_t) ie->xmit_cmds[i], sizeof *ie->xmit_cmds[i]);
2093 bzero((v_caddr_t) ie->xmit_buffs[i], sizeof *ie->xmit_buffs[i]);
2097 * This must be coordinated with iestart() and ietint().
2099 ie->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
2101 /* take the ee16 out of loopback */
2102 if (ie->hard_type == IE_EE16) {
2103 u_int8_t bart_config;
2105 bart_config = inb(PORT + IEE16_CONFIG);
2106 bart_config &= ~IEE16_BART_LOOPBACK;
2107 /* inb doesn't get bit! */
2108 bart_config |= IEE16_BART_MCS16_TEST;
2109 outb(PORT + IEE16_CONFIG, bart_config);
2110 ee16_interrupt_enable(ie);
2111 ee16_chan_attn(unit);
2113 ie->arpcom.ac_if.if_flags |= IFF_RUNNING; /* tell higher levels
2115 start_receiver(unit);
2123 command_and_wait(unit, IE_RU_DISABLE, 0, 0);
2127 ieioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
2137 error = ether_ioctl(ifp, command, data);
2142 * Note that this device doesn't have an "all multicast"
2143 * mode, so we must turn on promiscuous mode and do the
2144 * filtering manually.
2146 if ((ifp->if_flags & IFF_UP) == 0 &&
2147 (ifp->if_flags & IFF_RUNNING)) {
2148 ifp->if_flags &= ~IFF_RUNNING;
2149 ie_stop(ifp->if_dunit);
2150 } else if ((ifp->if_flags & IFF_UP) &&
2151 (ifp->if_flags & IFF_RUNNING) == 0) {
2152 ie_softc[ifp->if_dunit].promisc =
2153 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2154 ieinit(ifp->if_softc);
2155 } else if (ie_softc[ifp->if_dunit].promisc ^
2156 (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) {
2157 ie_softc[ifp->if_dunit].promisc =
2158 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2159 ieinit(ifp->if_softc);
2166 * Update multicast listeners
2168 /* reset multicast filtering */
2169 ie_mc_reset(ifp->if_dunit);
2182 ie_mc_reset(int unit)
2184 struct ie_softc *ie = &ie_softc[unit];
2185 struct ifmultiaddr *ifma;
2188 * Step through the list of addresses.
2190 ie->mcast_count = 0;
2191 for (ifma = ie->arpcom.ac_if.if_multiaddrs.lh_first; ifma;
2192 ifma = ifma->ifma_link.le_next) {
2193 if (ifma->ifma_addr->sa_family != AF_LINK)
2196 /* XXX - this is broken... */
2197 if (ie->mcast_count >= MAXMCAST) {
2198 ie->arpcom.ac_if.if_flags |= IFF_ALLMULTI;
2199 ieioctl(&ie->arpcom.ac_if, SIOCSIFFLAGS, (void *) 0,
2200 (struct ucred *)NULL);
2203 bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
2204 &(ie->mcast_addrs[ie->mcast_count]), 6);
2209 ie->want_mcsetup = 1;
2215 print_rbd(volatile struct ie_recv_buf_desc * rbd)
2217 printf("RBD at %p:\n"
2218 "actual %04x, next %04x, buffer %p\n"
2219 "length %04x, mbz %04x\n",
2220 (volatile void *) rbd,
2221 rbd->ie_rbd_actual, rbd->ie_rbd_next,
2222 (void *) rbd->ie_rbd_buffer,
2223 rbd->ie_rbd_length, rbd->mbz);