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