FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/if_ie.c
1 /*-
2 * Copyright (c) 1992, 1993, University of Vermont and State
3 * Agricultural College.
4 * Copyright (c) 1992, 1993, Garrett A. Wollman.
5 *
6 * Portions:
7 * Copyright (c) 1990, 1991, William F. Jolitz
8 * Copyright (c) 1990, The Regents of the University of California
9 *
10 * 3Com 3C507 support:
11 * Copyright (c) 1993, 1994, Charles M. Hannum
12 *
13 * EtherExpress 16 support:
14 * Copyright (c) 1993, 1994, 1995, Rodney W. Grimes
15 * Copyright (c) 1997, Aaron C. Smith
16 *
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * 3. All advertising materials mentioning features or use of this software
28 * must display the following acknowledgement:
29 * This product includes software developed by the University of
30 * Vermont and State Agricultural College and Garrett A. Wollman, by
31 * William F. Jolitz, by the University of California, Berkeley,
32 * Lawrence Berkeley Laboratory, and their contributors, by
33 * Charles M. Hannum, by Rodney W. Grimes, and by Aaron C. Smith.
34 * 4. Neither the names of the Universities nor the names of the authors
35 * may be used to endorse or promote products derived from this software
36 * without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 *
50 * $FreeBSD$
51 */
52
53 /*
54 * Intel 82586 Ethernet chip
55 * Register, bit, and structure definitions.
56 *
57 * Written by GAW with reference to the Clarkson Packet Driver code for this
58 * chip written by Russ Nelson and others.
59 *
60 * Intel EtherExpress 16 support from if_ix.c, written by Rodney W. Grimes.
61 */
62
63 /*
64 * The i82586 is a very versatile chip, found in many implementations.
65 * Programming this chip is mostly the same, but certain details differ
66 * from card to card. This driver is written so that different cards
67 * can be automatically detected at run-time.
68 */
69
70 /*
71 Mode of operation:
72
73 We run the 82586 in a standard Ethernet mode. We keep NFRAMES received
74 frame descriptors around for the receiver to use, and NRXBUFS associated
75 receive buffer descriptors, both in a circular list. Whenever a frame is
76 received, we rotate both lists as necessary. (The 586 treats both lists
77 as a simple queue.) We also keep a transmit command around so that packets
78 can be sent off quickly.
79
80 We configure the adapter in AL-LOC = 1 mode, which means that the
81 Ethernet/802.3 MAC header is placed at the beginning of the receive buffer
82 rather than being split off into various fields in the RFD. This also
83 means that we must include this header in the transmit buffer as well.
84
85 By convention, all transmit commands, and only transmit commands, shall
86 have the I (IE_CMD_INTR) bit set in the command. This way, when an
87 interrupt arrives at ieintr(), it is immediately possible to tell
88 what precisely caused it. ANY OTHER command-sending routines should
89 run at splimp(), and should post an acknowledgement to every interrupt
90 they generate.
91
92 The 82586 has a 24-bit address space internally, and the adaptor's memory
93 is located at the top of this region. However, the value we are given in
94 configuration is normally the *bottom* of the adaptor RAM. So, we must go
95 through a few gyrations to come up with a kernel virtual address which
96 represents the actual beginning of the 586 address space. First, we
97 autosize the RAM by running through several possible sizes and trying to
98 initialize the adapter under the assumption that the selected size is
99 correct. Then, knowing the correct RAM size, we set up our pointers in
100 ie_softc[unit]. `iomem' represents the computed base of the 586 address
101 space. `iomembot' represents the actual configured base of adapter RAM.
102 Finally, `iosize' represents the calculated size of 586 RAM. Then, when
103 laying out commands, we use the interval [iomembot, iomembot + iosize); to
104 make 24-pointers, we subtract iomem, and to make 16-pointers, we subtract
105 iomem and and with 0xffff.
106
107 */
108
109 #include "ie.h"
110 #if NIE > 0
111 #include "opt_inet.h"
112 #include "opt_ipx.h"
113
114 #include <sys/param.h>
115 #include <sys/systm.h>
116 #include <sys/kernel.h>
117 #include <sys/malloc.h>
118 #include <sys/conf.h>
119 #include <sys/mbuf.h>
120 #include <sys/socket.h>
121 #include <sys/sockio.h>
122 #include <sys/syslog.h>
123
124 #include <net/if.h>
125 #include <net/if_types.h>
126 #include <net/if_dl.h>
127
128 #include "bpfilter.h"
129
130 #ifdef INET
131 #include <netinet/in.h>
132 #include <netinet/if_ether.h>
133 #endif
134
135 #ifdef IPX
136 #include <netipx/ipx.h>
137 #include <netipx/ipx_if.h>
138 #endif
139
140 #ifdef NS
141 #include <netns/ns.h>
142 #include <netns/ns_if.h>
143 #endif
144
145 #include <machine/clock.h>
146 #include <machine/md_var.h>
147
148 #include <i386/isa/isa_device.h>
149 #include <i386/isa/ic/i82586.h>
150 #include <i386/isa/icu.h>
151 #include <i386/isa/if_iereg.h>
152 #include <i386/isa/if_ie507.h>
153 #include <i386/isa/if_iee16.h>
154 #include <i386/isa/elink.h>
155
156 #if NBPFILTER > 0
157 #include <net/bpf.h>
158 #endif
159
160 #ifdef DEBUG
161 #define IED_RINT 0x01
162 #define IED_TINT 0x02
163 #define IED_RNR 0x04
164 #define IED_CNA 0x08
165 #define IED_READFRAME 0x10
166 static int ie_debug = IED_RNR;
167
168 #endif
169
170 #define IE_BUF_LEN ETHER_MAX_LEN /* length of transmit buffer */
171
172 /* Forward declaration */
173 struct ie_softc;
174
175 static struct mbuf *last_not_for_us;
176
177 static int ieprobe(struct isa_device * dvp);
178 static int ieattach(struct isa_device * dvp);
179 static ointhand2_t ieintr;
180 static int sl_probe(struct isa_device * dvp);
181 static int el_probe(struct isa_device * dvp);
182 static int ni_probe(struct isa_device * dvp);
183 static int ee16_probe(struct isa_device * dvp);
184
185 static int check_ie_present(int unit, caddr_t where, unsigned size);
186 static void ieinit(int unit);
187 static void ie_stop(int unit);
188 static int ieioctl(struct ifnet * ifp, u_long command, caddr_t data);
189 static void iestart(struct ifnet * ifp);
190
191 static void el_reset_586(int unit);
192 static void el_chan_attn(int unit);
193
194 static void sl_reset_586(int unit);
195 static void sl_chan_attn(int unit);
196
197 static void ee16_reset_586(int unit);
198 static void ee16_chan_attn(int unit);
199 static __inline void ee16_interrupt_enable(struct ie_softc * ie);
200 static void ee16_eeprom_outbits(struct ie_softc * ie, int edata, int cnt);
201 static void ee16_eeprom_clock(struct ie_softc * ie, int state);
202 static u_short ee16_read_eeprom(struct ie_softc * ie, int location);
203 static int ee16_eeprom_inbits(struct ie_softc * ie);
204 static void ee16_shutdown(int howto, void *sc);
205
206 static void iereset(int unit);
207 static void ie_readframe(int unit, struct ie_softc * ie, int bufno);
208 static void ie_drop_packet_buffer(int unit, struct ie_softc * ie);
209 static void sl_read_ether(int unit, unsigned char addr[6]);
210 static void find_ie_mem_size(int unit);
211 static void chan_attn_timeout(void *rock);
212 static int command_and_wait(int unit, int command,
213 void volatile * pcmd, int);
214 static void run_tdr(int unit, struct ie_tdr_cmd * cmd);
215 static int ierint(int unit, struct ie_softc * ie);
216 static int ietint(int unit, struct ie_softc * ie);
217 static int iernr(int unit, struct ie_softc * ie);
218 static void start_receiver(int unit);
219 static __inline int ieget(int, struct ie_softc *, struct mbuf **,
220 struct ether_header *, int *);
221 static caddr_t setup_rfa(caddr_t ptr, struct ie_softc * ie);
222 static int mc_setup(int, caddr_t, volatile struct ie_sys_ctl_block *);
223 static void ie_mc_reset(int unit);
224
225 #ifdef DEBUG
226 static void print_rbd(volatile struct ie_recv_buf_desc * rbd);
227
228 static int in_ierint = 0;
229 static int in_ietint = 0;
230
231 #endif
232
233 /*
234 * This tells the autoconf code how to set us up.
235 */
236 struct isa_driver iedriver = {
237 ieprobe, ieattach, "ie",
238 };
239
240 enum ie_hardware {
241 IE_STARLAN10,
242 IE_EN100,
243 IE_SLFIBER,
244 IE_3C507,
245 IE_NI5210,
246 IE_EE16,
247 IE_UNKNOWN
248 };
249
250 static const char *ie_hardware_names[] = {
251 "StarLAN 10",
252 "EN100",
253 "StarLAN Fiber",
254 "3C507",
255 "NI5210",
256 "EtherExpress 16",
257 "Unknown"
258 };
259
260 /*
261 sizeof(iscp) == 1+1+2+4 == 8
262 sizeof(scb) == 2+2+2+2+2+2+2+2 == 16
263 NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384
264 sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18
265 sizeof(transmit buffer) == 1512
266 sizeof(transmit buffer desc) == 8
267 -----
268 1946
269
270 NRXBUFS * sizeof(rbd) == NRXBUFS*(2+2+4+2+2) == NRXBUFS*12
271 NRXBUFS * IE_RBUF_SIZE == NRXBUFS*256
272
273 NRXBUFS should be (16384 - 1946) / (256 + 12) == 14438 / 268 == 53
274
275 With NRXBUFS == 48, this leaves us 1574 bytes for another command or
276 more buffers. Another transmit command would be 18+8+1512 == 1538
277 ---just barely fits!
278
279 Obviously all these would have to be reduced for smaller memory sizes.
280 With a larger memory, it would be possible to roughly double the number of
281 both transmit and receive buffers.
282 */
283
284 #define NFRAMES 8 /* number of receive frames */
285 #define NRXBUFS 48 /* number of buffers to allocate */
286 #define IE_RBUF_SIZE 256 /* size of each buffer, MUST BE POWER OF TWO */
287 #define NTXBUFS 2 /* number of transmit commands */
288 #define IE_TBUF_SIZE ETHER_MAX_LEN /* size of transmit buffer */
289
290 /*
291 * Ethernet status, per interface.
292 */
293 static struct ie_softc {
294 struct arpcom arpcom;
295 void (*ie_reset_586) (int);
296 void (*ie_chan_attn) (int);
297 enum ie_hardware hard_type;
298 int hard_vers;
299
300 u_short port; /* i/o base address for this interface */
301 caddr_t iomem; /* memory size */
302 caddr_t iomembot; /* memory base address */
303 unsigned iosize;
304 int bus_use; /* 0 means 16bit, 1 means 8 bit adapter */
305
306 int want_mcsetup;
307 int promisc;
308 int nframes;
309 int nrxbufs;
310 int ntxbufs;
311 volatile struct ie_int_sys_conf_ptr *iscp;
312 volatile struct ie_sys_ctl_block *scb;
313 volatile struct ie_recv_frame_desc **rframes; /* nframes worth */
314 volatile struct ie_recv_buf_desc **rbuffs; /* nrxbufs worth */
315 volatile u_char **cbuffs; /* nrxbufs worth */
316 int rfhead, rftail, rbhead, rbtail;
317
318 volatile struct ie_xmit_cmd **xmit_cmds; /* ntxbufs worth */
319 volatile struct ie_xmit_buf **xmit_buffs; /* ntxbufs worth */
320 u_char **xmit_cbuffs; /* ntxbufs worth */
321 int xmit_count;
322
323 struct ie_en_addr mcast_addrs[MAXMCAST + 1];
324 int mcast_count;
325
326 u_short irq_encoded; /* encoded interrupt on IEE16 */
327 } ie_softc[NIE];
328
329 #define MK_24(base, ptr) ((caddr_t)((uintptr_t)ptr - (uintptr_t)base))
330 #define MK_16(base, ptr) ((u_short)(uintptr_t)MK_24(base, ptr))
331
332 #define PORT ie_softc[unit].port
333 #define MEM ie_softc[unit].iomem
334
335 int
336 ieprobe(struct isa_device *dvp)
337 {
338 int ret;
339
340 ret = sl_probe(dvp);
341 if (!ret)
342 ret = el_probe(dvp);
343 if (!ret)
344 ret = ni_probe(dvp);
345 if (!ret)
346 ret = ee16_probe(dvp);
347
348 return (ret);
349 }
350
351 static int
352 sl_probe(struct isa_device *dvp)
353 {
354 int unit = dvp->id_unit;
355 u_char c;
356
357 ie_softc[unit].port = dvp->id_iobase;
358 ie_softc[unit].iomembot = dvp->id_maddr;
359 ie_softc[unit].iomem = 0;
360 ie_softc[unit].bus_use = 0;
361
362 c = inb(PORT + IEATT_REVISION);
363 switch (SL_BOARD(c)) {
364 case SL10_BOARD:
365 ie_softc[unit].hard_type = IE_STARLAN10;
366 ie_softc[unit].ie_reset_586 = sl_reset_586;
367 ie_softc[unit].ie_chan_attn = sl_chan_attn;
368 break;
369 case EN100_BOARD:
370 ie_softc[unit].hard_type = IE_EN100;
371 ie_softc[unit].ie_reset_586 = sl_reset_586;
372 ie_softc[unit].ie_chan_attn = sl_chan_attn;
373 break;
374 case SLFIBER_BOARD:
375 ie_softc[unit].hard_type = IE_SLFIBER;
376 ie_softc[unit].ie_reset_586 = sl_reset_586;
377 ie_softc[unit].ie_chan_attn = sl_chan_attn;
378 break;
379
380 /*
381 * Anything else is not recognized or cannot be used.
382 */
383 default:
384 return (0);
385 }
386
387 ie_softc[unit].hard_vers = SL_REV(c);
388
389 /*
390 * Divine memory size on-board the card. Ususally 16k.
391 */
392 find_ie_mem_size(unit);
393
394 if (!ie_softc[unit].iosize) {
395 return (0);
396 }
397 dvp->id_msize = ie_softc[unit].iosize;
398
399 switch (ie_softc[unit].hard_type) {
400 case IE_EN100:
401 case IE_STARLAN10:
402 case IE_SLFIBER:
403 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
404 break;
405
406 default:
407 if (bootverbose)
408 printf("ie%d: unknown AT&T board type code %d\n", unit,
409 ie_softc[unit].hard_type);
410 return (0);
411 }
412
413 return (1);
414 }
415
416
417 static int
418 el_probe(struct isa_device *dvp)
419 {
420 struct ie_softc *sc = &ie_softc[dvp->id_unit];
421 u_char c;
422 int i;
423 u_char signature[] = "*3COM*";
424 int unit = dvp->id_unit;
425
426 sc->port = dvp->id_iobase;
427 sc->iomembot = dvp->id_maddr;
428 sc->bus_use = 0;
429
430 /* Need this for part of the probe. */
431 sc->ie_reset_586 = el_reset_586;
432 sc->ie_chan_attn = el_chan_attn;
433
434 /* Reset and put card in CONFIG state without changing address. */
435 elink_reset();
436 outb(ELINK_ID_PORT, 0x00);
437 elink_idseq(ELINK_507_POLY);
438 elink_idseq(ELINK_507_POLY);
439 outb(ELINK_ID_PORT, 0xff);
440
441 c = inb(PORT + IE507_MADDR);
442 if (c & 0x20) {
443 #ifdef DEBUG
444 printf("ie%d: can't map 3C507 RAM in high memory\n", unit);
445 #endif
446 return (0);
447 }
448 /* go to RUN state */
449 outb(ELINK_ID_PORT, 0x00);
450 elink_idseq(ELINK_507_POLY);
451 outb(ELINK_ID_PORT, 0x00);
452
453 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
454
455 for (i = 0; i < 6; i++)
456 if (inb(PORT + i) != signature[i])
457 return (0);
458
459 c = inb(PORT + IE507_IRQ) & 0x0f;
460
461 if (dvp->id_irq != (1 << c)) {
462 printf("ie%d: kernel configured irq %d "
463 "doesn't match board configured irq %d\n",
464 unit, ffs(dvp->id_irq) - 1, c);
465 return (0);
466 }
467 c = (inb(PORT + IE507_MADDR) & 0x1c) + 0xc0;
468
469 if (kvtop(dvp->id_maddr) != ((int) c << 12)) {
470 printf("ie%d: kernel configured maddr %lx "
471 "doesn't match board configured maddr %x\n",
472 unit, kvtop(dvp->id_maddr), (int) c << 12);
473 return (0);
474 }
475 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
476
477 sc->hard_type = IE_3C507;
478 sc->hard_vers = 0; /* 3C507 has no version number. */
479
480 /*
481 * Divine memory size on-board the card.
482 */
483 find_ie_mem_size(unit);
484
485 if (!sc->iosize) {
486 printf("ie%d: can't find shared memory\n", unit);
487 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
488 return (0);
489 }
490 if (!dvp->id_msize)
491 dvp->id_msize = sc->iosize;
492 else if (dvp->id_msize != sc->iosize) {
493 printf("ie%d: kernel configured msize %d "
494 "doesn't match board configured msize %d\n",
495 unit, dvp->id_msize, sc->iosize);
496 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
497 return (0);
498 }
499 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
500
501 /* Clear the interrupt latch just in case. */
502 outb(PORT + IE507_ICTRL, 1);
503
504 return (16);
505 }
506
507
508 static int
509 ni_probe(struct isa_device *dvp)
510 {
511 int unit = dvp->id_unit;
512 int boardtype, c;
513
514 ie_softc[unit].port = dvp->id_iobase;
515 ie_softc[unit].iomembot = dvp->id_maddr;
516 ie_softc[unit].iomem = 0;
517 ie_softc[unit].bus_use = 1;
518
519 boardtype = inb(PORT + IEATT_REVISION);
520 c = inb(PORT + IEATT_REVISION + 1);
521 boardtype = boardtype + (c << 8);
522 switch (boardtype) {
523 case 0x5500: /* This is the magic cookie for the NI5210 */
524 ie_softc[unit].hard_type = IE_NI5210;
525 ie_softc[unit].ie_reset_586 = sl_reset_586;
526 ie_softc[unit].ie_chan_attn = sl_chan_attn;
527 break;
528
529 /*
530 * Anything else is not recognized or cannot be used.
531 */
532 default:
533 return (0);
534 }
535
536 ie_softc[unit].hard_vers = 0;
537
538 /*
539 * Divine memory size on-board the card. Either 8 or 16k.
540 */
541 find_ie_mem_size(unit);
542
543 if (!ie_softc[unit].iosize) {
544 return (0);
545 }
546 if (!dvp->id_msize)
547 dvp->id_msize = ie_softc[unit].iosize;
548 else if (dvp->id_msize != ie_softc[unit].iosize) {
549 printf("ie%d: kernel configured msize %d "
550 "doesn't match board configured msize %d\n",
551 unit, dvp->id_msize, ie_softc[unit].iosize);
552 return (0);
553 }
554 sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr);
555
556 return (8);
557
558 }
559
560
561 static void
562 ee16_shutdown(int howto, void *sc)
563 {
564 struct ie_softc *ie = (struct ie_softc *)sc;
565 int unit = ie - &ie_softc[0];
566
567 ee16_reset_586(unit);
568 outb(PORT + IEE16_ECTRL, IEE16_RESET_ASIC);
569 outb(PORT + IEE16_ECTRL, 0);
570 }
571
572
573 /* Taken almost exactly from Rod's if_ix.c. */
574
575 int
576 ee16_probe(struct isa_device *dvp)
577 {
578 struct ie_softc *sc = &ie_softc[dvp->id_unit];
579
580 int i;
581 int unit = dvp->id_unit;
582 u_short board_id, id_var1, id_var2, checksum = 0;
583 u_short eaddrtemp, irq;
584 u_short pg, adjust, decode, edecode;
585 u_char bart_config;
586 u_long bd_maddr;
587
588 short irq_translate[] = {0, IRQ9, IRQ3, IRQ4, IRQ5, IRQ10, IRQ11, 0};
589 char irq_encode[] = {0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0};
590
591 /* Need this for part of the probe. */
592 sc->ie_reset_586 = ee16_reset_586;
593 sc->ie_chan_attn = ee16_chan_attn;
594
595 /* unsure if this is necessary */
596 sc->bus_use = 0;
597
598 /* reset any ee16 at the current iobase */
599 outb(dvp->id_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
600 outb(dvp->id_iobase + IEE16_ECTRL, 0);
601 DELAY(240);
602
603 /* now look for ee16. */
604 board_id = id_var1 = id_var2 = 0;
605 for (i = 0; i < 4; i++) {
606 id_var1 = inb(dvp->id_iobase + IEE16_ID_PORT);
607 id_var2 = ((id_var1 & 0x03) << 2);
608 board_id |= ((id_var1 >> 4) << id_var2);
609 }
610
611 if (board_id != IEE16_ID) {
612 printf("ie%d: unknown board_id: %x\n", unit, board_id);
613 return (0);
614 }
615 /* need sc->port for ee16_read_eeprom */
616 sc->port = dvp->id_iobase;
617 sc->hard_type = IE_EE16;
618
619 /*
620 * The shared RAM location on the EE16 is encoded into bits 3-7 of
621 * EEPROM location 6. We zero the upper byte, and shift the 5 bits
622 * right 3. The resulting number tells us the RAM location.
623 * Because the EE16 supports either 16k or 32k of shared RAM, we
624 * only worry about the 32k locations.
625 *
626 * NOTE: if a 64k EE16 exists, it should be added to this switch. then
627 * the ia->ia_msize would need to be set per case statement.
628 *
629 * value msize location ===== ===== ======== 0x03 0x8000
630 * 0xCC000 0x06 0x8000 0xD0000 0x0C 0x8000 0xD4000 0x18
631 * 0x8000 0xD8000
632 *
633 */
634
635 bd_maddr = 0;
636 i = (ee16_read_eeprom(sc, 6) & 0x00ff) >> 3;
637 switch (i) {
638 case 0x03:
639 bd_maddr = 0xCC000;
640 break;
641 case 0x06:
642 bd_maddr = 0xD0000;
643 break;
644 case 0x0c:
645 bd_maddr = 0xD4000;
646 break;
647 case 0x18:
648 bd_maddr = 0xD8000;
649 break;
650 default:
651 bd_maddr = 0;
652 break;
653 }
654 dvp->id_msize = 0x8000;
655 if (kvtop(dvp->id_maddr) != bd_maddr) {
656 printf("ie%d: kernel configured maddr %lx "
657 "doesn't match board configured maddr %lx\n",
658 unit, kvtop(dvp->id_maddr), bd_maddr);
659 }
660 sc->iomembot = dvp->id_maddr;
661 sc->iomem = 0; /* XXX some probes set this and some don't */
662 sc->iosize = dvp->id_msize;
663
664 /* need to put the 586 in RESET while we access the eeprom. */
665 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
666
667 /* read the eeprom and checksum it, should == IEE16_ID */
668 for (i = 0; i < 0x40; i++)
669 checksum += ee16_read_eeprom(sc, i);
670
671 if (checksum != IEE16_ID) {
672 printf("ie%d: invalid eeprom checksum: %x\n", unit, checksum);
673 return (0);
674 }
675 /*
676 * Size and test the memory on the board. The size of the memory
677 * can be one of 16k, 32k, 48k or 64k. It can be located in the
678 * address range 0xC0000 to 0xEFFFF on 16k boundaries.
679 *
680 * If the size does not match the passed in memory allocation size
681 * issue a warning, but continue with the minimum of the two sizes.
682 */
683
684 switch (dvp->id_msize) {
685 case 65536:
686 case 32768: /* XXX Only support 32k and 64k right now */
687 break;
688 case 16384:
689 case 49512:
690 default:
691 printf("ie%d: mapped memory size %d not supported\n", unit,
692 dvp->id_msize);
693 return (0);
694 break; /* NOTREACHED */
695 }
696
697 if ((kvtop(dvp->id_maddr) < 0xC0000) ||
698 (kvtop(dvp->id_maddr) + sc->iosize > 0xF0000)) {
699 printf("ie%d: mapped memory location %p out of range\n", unit,
700 (void *)dvp->id_maddr);
701 return (0);
702 }
703 pg = (kvtop(dvp->id_maddr) & 0x3C000) >> 14;
704 adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
705 decode = ((1 << (sc->iosize / 16384)) - 1) << pg;
706 edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
707
708 /* ZZZ This should be checked against eeprom location 6, low byte */
709 outb(PORT + IEE16_MEMDEC, decode & 0xFF);
710 /* ZZZ This should be checked against eeprom location 1, low byte */
711 outb(PORT + IEE16_MCTRL, adjust);
712 /* ZZZ Now if I could find this one I would have it made */
713 outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
714 /* ZZZ I think this is location 6, high byte */
715 outb(PORT + IEE16_MECTRL, edecode); /* XXX disable Exxx */
716
717 (void) kvtop(dvp->id_maddr);
718
719 /*
720 * first prime the stupid bart DRAM controller so that it works,
721 * then zero out all of memory.
722 */
723 bzero(sc->iomembot, 32);
724 bzero(sc->iomembot, sc->iosize);
725
726 /*
727 * Get the encoded interrupt number from the EEPROM, check it
728 * against the passed in IRQ. Issue a warning if they do not match.
729 * Always use the passed in IRQ, not the one in the EEPROM.
730 */
731 irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
732 irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
733 irq = irq_translate[irq];
734 if (dvp->id_irq > 0) {
735 if (irq != dvp->id_irq) {
736 printf("ie%d: WARNING: board configured "
737 "at irq %u, using %u\n",
738 dvp->id_unit, dvp->id_irq, irq);
739 irq = dvp->id_unit;
740 }
741 } else {
742 dvp->id_irq = irq;
743 }
744 sc->irq_encoded = irq_encode[ffs(irq) - 1];
745
746 /*
747 * Get the hardware ethernet address from the EEPROM and save it in
748 * the softc for use by the 586 setup code.
749 */
750 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
751 sc->arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
752 sc->arpcom.ac_enaddr[0] = eaddrtemp >> 8;
753 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
754 sc->arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
755 sc->arpcom.ac_enaddr[2] = eaddrtemp >> 8;
756 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
757 sc->arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
758 sc->arpcom.ac_enaddr[4] = eaddrtemp >> 8;
759
760 /* disable the board interrupts */
761 outb(PORT + IEE16_IRQ, sc->irq_encoded);
762
763 /* enable loopback to keep bad packets off the wire */
764 if (sc->hard_type == IE_EE16) {
765 bart_config = inb(PORT + IEE16_CONFIG);
766 bart_config |= IEE16_BART_LOOPBACK;
767 bart_config |= IEE16_BART_MCS16_TEST;/* inb doesn't get bit! */
768 outb(PORT + IEE16_CONFIG, bart_config);
769 bart_config = inb(PORT + IEE16_CONFIG);
770 }
771 /* take the board out of reset state */
772 outb(PORT + IEE16_ECTRL, 0);
773 DELAY(100);
774
775 if (!check_ie_present(unit, dvp->id_maddr, sc->iosize))
776 return (0);
777
778 return (16); /* return the number of I/O ports */
779 }
780
781 /*
782 * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
783 */
784 int
785 ieattach(struct isa_device *dvp)
786 {
787 int factor;
788 int unit = dvp->id_unit;
789 struct ie_softc *ie = &ie_softc[unit];
790 struct ifnet *ifp = &ie->arpcom.ac_if;
791 size_t allocsize;
792
793 dvp->id_ointr = ieintr;
794
795 /*
796 * based on the amount of memory we have, allocate our tx and rx
797 * resources.
798 */
799 factor = dvp->id_msize / 16384;
800 ie->nframes = factor * NFRAMES;
801 ie->nrxbufs = factor * NRXBUFS;
802 ie->ntxbufs = factor * NTXBUFS;
803
804 /*
805 * Since all of these guys are arrays of pointers, allocate as one
806 * big chunk and dole out accordingly.
807 */
808 allocsize = sizeof(void *) * (ie->nframes
809 + (ie->nrxbufs * 2)
810 + (ie->ntxbufs * 3));
811 ie->rframes = (volatile struct ie_recv_frame_desc **) malloc(allocsize,
812 M_DEVBUF,
813 M_NOWAIT);
814 if (ie->rframes == NULL)
815 return (0);
816 ie->rbuffs =
817 (volatile struct ie_recv_buf_desc **)&ie->rframes[ie->nframes];
818 ie->cbuffs = (volatile u_char **)&ie->rbuffs[ie->nrxbufs];
819 ie->xmit_cmds =
820 (volatile struct ie_xmit_cmd **)&ie->cbuffs[ie->nrxbufs];
821 ie->xmit_buffs =
822 (volatile struct ie_xmit_buf **)&ie->xmit_cmds[ie->ntxbufs];
823 ie->xmit_cbuffs = (u_char **)&ie->xmit_buffs[ie->ntxbufs];
824
825 ifp->if_softc = ie;
826 ifp->if_unit = unit;
827 ifp->if_name = iedriver.name;
828 ifp->if_mtu = ETHERMTU;
829 printf("ie%d: <%s R%d> address %6D\n", unit,
830 ie_hardware_names[ie->hard_type],
831 ie->hard_vers + 1,
832 ie->arpcom.ac_enaddr, ":");
833
834 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
835 ifp->if_output = ether_output;
836 ifp->if_start = iestart;
837 ifp->if_ioctl = ieioctl;
838 ifp->if_type = IFT_ETHER;
839 ifp->if_addrlen = 6;
840 ifp->if_hdrlen = 14;
841
842 if (ie->hard_type == IE_EE16)
843 at_shutdown(ee16_shutdown, ie, SHUTDOWN_POST_SYNC);
844
845 #if NBPFILTER > 0
846 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
847 #endif
848
849 if_attach(ifp);
850 ether_ifattach(ifp);
851 return (1);
852 }
853
854 /*
855 * What to do upon receipt of an interrupt.
856 */
857 static void
858 ieintr(int unit)
859 {
860 register struct ie_softc *ie = &ie_softc[unit];
861 register u_short status;
862
863 /* Clear the interrupt latch on the 3C507. */
864 if (ie->hard_type == IE_3C507
865 && (inb(PORT + IE507_CTRL) & EL_CTRL_INTL))
866 outb(PORT + IE507_ICTRL, 1);
867
868 /* disable interrupts on the EE16. */
869 if (ie->hard_type == IE_EE16)
870 outb(PORT + IEE16_IRQ, ie->irq_encoded);
871
872 status = ie->scb->ie_status;
873
874 loop:
875
876 /* Don't ack interrupts which we didn't receive */
877 ie_ack(ie->scb, IE_ST_WHENCE & status, unit, ie->ie_chan_attn);
878
879 if (status & (IE_ST_RECV | IE_ST_RNR)) {
880 #ifdef DEBUG
881 in_ierint++;
882 if (ie_debug & IED_RINT)
883 printf("ie%d: rint\n", unit);
884 #endif
885 ierint(unit, ie);
886 #ifdef DEBUG
887 in_ierint--;
888 #endif
889 }
890 if (status & IE_ST_DONE) {
891 #ifdef DEBUG
892 in_ietint++;
893 if (ie_debug & IED_TINT)
894 printf("ie%d: tint\n", unit);
895 #endif
896 ietint(unit, ie);
897 #ifdef DEBUG
898 in_ietint--;
899 #endif
900 }
901 if (status & IE_ST_RNR) {
902 #ifdef DEBUG
903 if (ie_debug & IED_RNR)
904 printf("ie%d: rnr\n", unit);
905 #endif
906 iernr(unit, ie);
907 }
908 #ifdef DEBUG
909 if ((status & IE_ST_ALLDONE)
910 && (ie_debug & IED_CNA))
911 printf("ie%d: cna\n", unit);
912 #endif
913
914 if ((status = ie->scb->ie_status) & IE_ST_WHENCE)
915 goto loop;
916
917 /* Clear the interrupt latch on the 3C507. */
918 if (ie->hard_type == IE_3C507)
919 outb(PORT + IE507_ICTRL, 1);
920
921 /* enable interrupts on the EE16. */
922 if (ie->hard_type == IE_EE16)
923 outb(PORT + IEE16_IRQ, ie->irq_encoded | IEE16_IRQ_ENABLE);
924
925 }
926
927 /*
928 * Process a received-frame interrupt.
929 */
930 static int
931 ierint(int unit, struct ie_softc *ie)
932 {
933 int i, status;
934 static int timesthru = 1024;
935
936 i = ie->rfhead;
937 while (1) {
938 status = ie->rframes[i]->ie_fd_status;
939
940 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
941 ie->arpcom.ac_if.if_ipackets++;
942 if (!--timesthru) {
943 ie->arpcom.ac_if.if_ierrors +=
944 ie->scb->ie_err_crc +
945 ie->scb->ie_err_align +
946 ie->scb->ie_err_resource +
947 ie->scb->ie_err_overrun;
948 ie->scb->ie_err_crc = 0;
949 ie->scb->ie_err_align = 0;
950 ie->scb->ie_err_resource = 0;
951 ie->scb->ie_err_overrun = 0;
952 timesthru = 1024;
953 }
954 ie_readframe(unit, ie, i);
955 } else {
956 if (status & IE_FD_RNR) {
957 if (!(ie->scb->ie_status & IE_RU_READY)) {
958 ie->rframes[0]->ie_fd_next =
959 MK_16(MEM, ie->rbuffs[0]);
960 ie->scb->ie_recv_list =
961 MK_16(MEM, ie->rframes[0]);
962 command_and_wait(unit, IE_RU_START,
963 0, 0);
964 }
965 }
966 break;
967 }
968 i = (i + 1) % ie->nframes;
969 }
970 return (0);
971 }
972
973 /*
974 * Process a command-complete interrupt. These are only generated by
975 * the transmission of frames. This routine is deceptively simple, since
976 * most of the real work is done by iestart().
977 */
978 static int
979 ietint(int unit, struct ie_softc *ie)
980 {
981 int status;
982 int i;
983
984 ie->arpcom.ac_if.if_timer = 0;
985 ie->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
986
987 for (i = 0; i < ie->xmit_count; i++) {
988 status = ie->xmit_cmds[i]->ie_xmit_status;
989
990 if (status & IE_XS_LATECOLL) {
991 printf("ie%d: late collision\n", unit);
992 ie->arpcom.ac_if.if_collisions++;
993 ie->arpcom.ac_if.if_oerrors++;
994 } else if (status & IE_XS_NOCARRIER) {
995 printf("ie%d: no carrier\n", unit);
996 ie->arpcom.ac_if.if_oerrors++;
997 } else if (status & IE_XS_LOSTCTS) {
998 printf("ie%d: lost CTS\n", unit);
999 ie->arpcom.ac_if.if_oerrors++;
1000 } else if (status & IE_XS_UNDERRUN) {
1001 printf("ie%d: DMA underrun\n", unit);
1002 ie->arpcom.ac_if.if_oerrors++;
1003 } else if (status & IE_XS_EXCMAX) {
1004 printf("ie%d: too many collisions\n", unit);
1005 ie->arpcom.ac_if.if_collisions += 16;
1006 ie->arpcom.ac_if.if_oerrors++;
1007 } else {
1008 ie->arpcom.ac_if.if_opackets++;
1009 ie->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL;
1010 }
1011 }
1012 ie->xmit_count = 0;
1013
1014 /*
1015 * If multicast addresses were added or deleted while we were
1016 * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
1017 * that we should do it.
1018 */
1019 if (ie->want_mcsetup) {
1020 mc_setup(unit, (caddr_t) ie->xmit_cbuffs[0], ie->scb);
1021 ie->want_mcsetup = 0;
1022 }
1023 /* Wish I knew why this seems to be necessary... */
1024 ie->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;
1025
1026 iestart(&ie->arpcom.ac_if);
1027 return (0); /* shouldn't be necessary */
1028 }
1029
1030 /*
1031 * Process a receiver-not-ready interrupt. I believe that we get these
1032 * when there aren't enough buffers to go around. For now (FIXME), we
1033 * just restart the receiver, and hope everything's ok.
1034 */
1035 static int
1036 iernr(int unit, struct ie_softc *ie)
1037 {
1038 #ifdef doesnt_work
1039 setup_rfa((caddr_t) ie->rframes[0], ie);
1040
1041 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1042 command_and_wait(unit, IE_RU_START, 0, 0);
1043 #else
1044 /* This doesn't work either, but it doesn't hang either. */
1045 command_and_wait(unit, IE_RU_DISABLE, 0, 0); /* just in case */
1046 setup_rfa((caddr_t) ie->rframes[0], ie); /* ignore cast-qual */
1047
1048 ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
1049 command_and_wait(unit, IE_RU_START, 0, 0); /* was ENABLE */
1050
1051 #endif
1052 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
1053
1054 ie->arpcom.ac_if.if_ierrors++;
1055 return (0);
1056 }
1057
1058 /*
1059 * Compare two Ether/802 addresses for equality, inlined and
1060 * unrolled for speed. I'd love to have an inline assembler
1061 * version of this...
1062 */
1063 static __inline int
1064 ether_equal(u_char * one, u_char * two)
1065 {
1066 if (one[0] != two[0])
1067 return (0);
1068 if (one[1] != two[1])
1069 return (0);
1070 if (one[2] != two[2])
1071 return (0);
1072 if (one[3] != two[3])
1073 return (0);
1074 if (one[4] != two[4])
1075 return (0);
1076 if (one[5] != two[5])
1077 return (0);
1078 return 1;
1079 }
1080
1081 /*
1082 * Check for a valid address. to_bpf is filled in with one of the following:
1083 * 0 -> BPF doesn't get this packet
1084 * 1 -> BPF does get this packet
1085 * 2 -> BPF does get this packet, but we don't
1086 * Return value is true if the packet is for us, and false otherwise.
1087 *
1088 * This routine is a mess, but it's also critical that it be as fast
1089 * as possible. It could be made cleaner if we can assume that the
1090 * only client which will fiddle with IFF_PROMISC is BPF. This is
1091 * probably a good assumption, but we do not make it here. (Yet.)
1092 */
1093 static __inline int
1094 check_eh(struct ie_softc * ie, struct ether_header * eh, int *to_bpf)
1095 {
1096 int i;
1097
1098 switch (ie->promisc) {
1099 case IFF_ALLMULTI:
1100 /*
1101 * Receiving all multicasts, but no unicasts except those
1102 * destined for us.
1103 */
1104 #if NBPFILTER > 0
1105 /* BPF gets this packet if anybody cares */
1106 *to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
1107 #endif
1108 if (eh->ether_dhost[0] & 1) {
1109 return (1);
1110 }
1111 if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1112 return (1);
1113 return (0);
1114
1115 case IFF_PROMISC:
1116 /*
1117 * Receiving all packets. These need to be passed on to
1118 * BPF.
1119 */
1120 #if NBPFILTER > 0
1121 *to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
1122 #endif
1123 /* If for us, accept and hand up to BPF */
1124 if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1125 return (1);
1126
1127 #if NBPFILTER > 0
1128 if (*to_bpf)
1129 *to_bpf = 2; /* we don't need to see it */
1130 #endif
1131
1132 /*
1133 * Not a multicast, so BPF wants to see it but we don't.
1134 */
1135 if (!(eh->ether_dhost[0] & 1))
1136 return (1);
1137
1138 /*
1139 * If it's one of our multicast groups, accept it and pass
1140 * it up.
1141 */
1142 for (i = 0; i < ie->mcast_count; i++) {
1143 if (ether_equal(eh->ether_dhost,
1144 (u_char *)&ie->mcast_addrs[i])) {
1145 #if NBPFILTER > 0
1146 if (*to_bpf)
1147 *to_bpf = 1;
1148 #endif
1149 return (1);
1150 }
1151 }
1152 return (1);
1153
1154 case IFF_ALLMULTI | IFF_PROMISC:
1155 /*
1156 * Acting as a multicast router, and BPF running at the same
1157 * time. Whew! (Hope this is a fast machine...)
1158 */
1159 #if NBPFILTER > 0
1160 *to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
1161 #endif
1162 /* We want to see multicasts. */
1163 if (eh->ether_dhost[0] & 1)
1164 return (1);
1165
1166 /* We want to see our own packets */
1167 if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr))
1168 return (1);
1169
1170 /* Anything else goes to BPF but nothing else. */
1171 #if NBPFILTER > 0
1172 if (*to_bpf)
1173 *to_bpf = 2;
1174 #endif
1175 return (1);
1176
1177 default:
1178 /*
1179 * Only accept unicast packets destined for us, or
1180 * multicasts for groups that we belong to. For now, we
1181 * assume that the '586 will only return packets that we
1182 * asked it for. This isn't strictly true (it uses hashing
1183 * for the multicast filter), but it will do in this case,
1184 * and we want to get out of here as quickly as possible.
1185 */
1186 #if NBPFILTER > 0
1187 *to_bpf = (ie->arpcom.ac_if.if_bpf != 0);
1188 #endif
1189 return (1);
1190 }
1191 return (0);
1192 }
1193
1194 /*
1195 * We want to isolate the bits that have meaning... This assumes that
1196 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds
1197 * the size of the buffer, then we are screwed anyway.
1198 */
1199 static __inline int
1200 ie_buflen(struct ie_softc * ie, int head)
1201 {
1202 return (ie->rbuffs[head]->ie_rbd_actual
1203 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
1204 }
1205
1206 static __inline int
1207 ie_packet_len(int unit, struct ie_softc * ie)
1208 {
1209 int i;
1210 int head = ie->rbhead;
1211 int acc = 0;
1212
1213 do {
1214 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1215 #ifdef DEBUG
1216 print_rbd(ie->rbuffs[ie->rbhead]);
1217 #endif
1218 log(LOG_ERR,
1219 "ie%d: receive descriptors out of sync at %d\n",
1220 unit, ie->rbhead);
1221 iereset(unit);
1222 return (-1);
1223 }
1224 i = ie->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
1225
1226 acc += ie_buflen(ie, head);
1227 head = (head + 1) % ie->nrxbufs;
1228 } while (!i);
1229
1230 return (acc);
1231 }
1232
1233 /*
1234 * Read data off the interface, and turn it into an mbuf chain.
1235 *
1236 * This code is DRAMATICALLY different from the previous version; this
1237 * version tries to allocate the entire mbuf chain up front, given the
1238 * length of the data available. This enables us to allocate mbuf
1239 * clusters in many situations where before we would have had a long
1240 * chain of partially-full mbufs. This should help to speed up the
1241 * operation considerably. (Provided that it works, of course.)
1242 */
1243 static __inline int
1244 ieget(int unit, struct ie_softc *ie, struct mbuf **mp,
1245 struct ether_header *ehp, int *to_bpf)
1246 {
1247 struct mbuf *m, *top, **mymp;
1248 int i;
1249 int offset;
1250 int totlen, resid;
1251 int thismboff;
1252 int head;
1253
1254 totlen = ie_packet_len(unit, ie);
1255 if (totlen <= 0)
1256 return (-1);
1257
1258 i = ie->rbhead;
1259
1260 /*
1261 * Snarf the Ethernet header.
1262 */
1263 bcopy((caddr_t) ie->cbuffs[i], (caddr_t) ehp, sizeof *ehp);
1264 /* ignore cast-qual warning here */
1265
1266 /*
1267 * As quickly as possible, check if this packet is for us. If not,
1268 * don't waste a single cycle copying the rest of the packet in.
1269 * This is only a consideration when FILTER is defined; i.e., when
1270 * we are either running BPF or doing multicasting.
1271 */
1272 if (!check_eh(ie, ehp, to_bpf)) {
1273 ie_drop_packet_buffer(unit, ie);
1274 ie->arpcom.ac_if.if_ierrors--; /* just this case, it's not an
1275 * error
1276 */
1277 return (-1);
1278 }
1279 totlen -= (offset = sizeof *ehp);
1280
1281 MGETHDR(*mp, M_DONTWAIT, MT_DATA);
1282 if (!*mp) {
1283 ie_drop_packet_buffer(unit, ie);
1284 return (-1);
1285 }
1286 m = *mp;
1287 m->m_pkthdr.rcvif = &ie->arpcom.ac_if;
1288 m->m_len = MHLEN;
1289 resid = m->m_pkthdr.len = totlen;
1290 top = 0;
1291 mymp = ⊤
1292
1293 /*
1294 * This loop goes through and allocates mbufs for all the data we
1295 * will be copying in. It does not actually do the copying yet.
1296 */
1297 do { /* while(resid > 0) */
1298 /*
1299 * Try to allocate an mbuf to hold the data that we have.
1300 * If we already allocated one, just get another one and
1301 * stick it on the end (eventually). If we don't already
1302 * have one, try to allocate an mbuf cluster big enough to
1303 * hold the whole packet, if we think it's reasonable, or a
1304 * single mbuf which may or may not be big enough. Got that?
1305 */
1306 if (top) {
1307 MGET(m, M_DONTWAIT, MT_DATA);
1308 if (!m) {
1309 m_freem(top);
1310 ie_drop_packet_buffer(unit, ie);
1311 return (-1);
1312 }
1313 m->m_len = MLEN;
1314 }
1315 if (resid >= MINCLSIZE) {
1316 MCLGET(m, M_DONTWAIT);
1317 if (m->m_flags & M_EXT)
1318 m->m_len = min(resid, MCLBYTES);
1319 } else {
1320 if (resid < m->m_len) {
1321 if (!top && resid + max_linkhdr <= m->m_len)
1322 m->m_data += max_linkhdr;
1323 m->m_len = resid;
1324 }
1325 }
1326 resid -= m->m_len;
1327 *mymp = m;
1328 mymp = &m->m_next;
1329 } while (resid > 0);
1330
1331 resid = totlen;
1332 m = top;
1333 thismboff = 0;
1334 head = ie->rbhead;
1335
1336 /*
1337 * Now we take the mbuf chain (hopefully only one mbuf most of the
1338 * time) and stuff the data into it. There are no possible failures
1339 * at or after this point.
1340 */
1341 while (resid > 0) { /* while there's stuff left */
1342 int thislen = ie_buflen(ie, head) - offset;
1343
1344 /*
1345 * If too much data for the current mbuf, then fill the
1346 * current one up, go to the next one, and try again.
1347 */
1348 if (thislen > m->m_len - thismboff) {
1349 int newlen = m->m_len - thismboff;
1350
1351 bcopy((caddr_t) (ie->cbuffs[head] + offset),
1352 mtod(m, caddr_t) +thismboff, (unsigned) newlen);
1353 /* ignore cast-qual warning */
1354 m = m->m_next;
1355 thismboff = 0; /* new mbuf, so no offset */
1356 offset += newlen; /* we are now this far into
1357 * the packet */
1358 resid -= newlen; /* so there is this much left
1359 * to get */
1360 continue;
1361 }
1362 /*
1363 * If there is more than enough space in the mbuf to hold
1364 * the contents of this buffer, copy everything in, advance
1365 * pointers, and so on.
1366 */
1367 if (thislen < m->m_len - thismboff) {
1368 bcopy((caddr_t) (ie->cbuffs[head] + offset),
1369 mtod(m, caddr_t) +thismboff, (unsigned) thislen);
1370 thismboff += thislen; /* we are this far into the
1371 * mbuf */
1372 resid -= thislen; /* and this much is left */
1373 goto nextbuf;
1374 }
1375 /*
1376 * Otherwise, there is exactly enough space to put this
1377 * buffer's contents into the current mbuf. Do the
1378 * combination of the above actions.
1379 */
1380 bcopy((caddr_t) (ie->cbuffs[head] + offset),
1381 mtod(m, caddr_t) + thismboff, (unsigned) thislen);
1382 m = m->m_next;
1383 thismboff = 0; /* new mbuf, start at the beginning */
1384 resid -= thislen; /* and we are this far through */
1385
1386 /*
1387 * Advance all the pointers. We can get here from either of
1388 * the last two cases, but never the first.
1389 */
1390 nextbuf:
1391 offset = 0;
1392 ie->rbuffs[head]->ie_rbd_actual = 0;
1393 ie->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST;
1394 ie->rbhead = head = (head + 1) % ie->nrxbufs;
1395 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1396 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1397 }
1398
1399 /*
1400 * Unless something changed strangely while we were doing the copy,
1401 * we have now copied everything in from the shared memory. This
1402 * means that we are done.
1403 */
1404 return (0);
1405 }
1406
1407 /*
1408 * Read frame NUM from unit UNIT (pre-cached as IE).
1409 *
1410 * This routine reads the RFD at NUM, and copies in the buffers from
1411 * the list of RBD, then rotates the RBD and RFD lists so that the receiver
1412 * doesn't start complaining. Trailers are DROPPED---there's no point
1413 * in wasting time on confusing code to deal with them. Hopefully,
1414 * this machine will never ARP for trailers anyway.
1415 */
1416 static void
1417 ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */)
1418 {
1419 struct ie_recv_frame_desc rfd;
1420 struct mbuf *m = 0;
1421 struct ether_header eh;
1422
1423 #if NBPFILTER > 0
1424 int bpf_gets_it = 0;
1425
1426 #endif
1427
1428 bcopy((caddr_t) (ie->rframes[num]), &rfd,
1429 sizeof(struct ie_recv_frame_desc));
1430
1431 /*
1432 * Immediately advance the RFD list, since we we have copied ours
1433 * now.
1434 */
1435 ie->rframes[num]->ie_fd_status = 0;
1436 ie->rframes[num]->ie_fd_last |= IE_FD_LAST;
1437 ie->rframes[ie->rftail]->ie_fd_last &= ~IE_FD_LAST;
1438 ie->rftail = (ie->rftail + 1) % ie->nframes;
1439 ie->rfhead = (ie->rfhead + 1) % ie->nframes;
1440
1441 if (rfd.ie_fd_status & IE_FD_OK) {
1442 #if NBPFILTER > 0
1443 if (ieget(unit, ie, &m, &eh, &bpf_gets_it)) {
1444 #else
1445 if (ieget(unit, ie, &m, &eh, (int *)0)) {
1446 #endif
1447 ie->arpcom.ac_if.if_ierrors++; /* this counts as an
1448 * error */
1449 return;
1450 }
1451 }
1452 #ifdef DEBUG
1453 if (ie_debug & IED_READFRAME) {
1454 printf("ie%d: frame from ether %6D type %x\n", unit,
1455 eh.ether_shost, ":", (unsigned) eh.ether_type);
1456 }
1457 if (ntohs(eh.ether_type) > ETHERTYPE_TRAIL
1458 && ntohs(eh.ether_type) < (ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER))
1459 printf("received trailer!\n");
1460 #endif
1461
1462 if (!m)
1463 return;
1464
1465 if (last_not_for_us) {
1466 m_freem(last_not_for_us);
1467 last_not_for_us = 0;
1468 }
1469 #if NBPFILTER > 0
1470 /*
1471 * Check for a BPF filter; if so, hand it up. Note that we have to
1472 * stick an extra mbuf up front, because bpf_mtap expects to have
1473 * the ether header at the front. It doesn't matter that this
1474 * results in an ill-formatted mbuf chain, since BPF just looks at
1475 * the data. (It doesn't try to free the mbuf, tho' it will make a
1476 * copy for tcpdump.)
1477 */
1478 if (bpf_gets_it) {
1479 struct mbuf m0;
1480
1481 m0.m_len = sizeof eh;
1482 m0.m_data = (caddr_t)&eh;
1483 m0.m_next = m;
1484
1485 /* Pass it up */
1486 bpf_mtap(&ie->arpcom.ac_if, &m0);
1487 }
1488 /*
1489 * A signal passed up from the filtering code indicating that the
1490 * packet is intended for BPF but not for the protocol machinery. We
1491 * can save a few cycles by not handing it off to them.
1492 */
1493 if (bpf_gets_it == 2) {
1494 last_not_for_us = m;
1495 return;
1496 }
1497 #endif /* NBPFILTER > 0 */
1498 /*
1499 * In here there used to be code to check destination addresses upon
1500 * receipt of a packet. We have deleted that code, and replaced it
1501 * with code to check the address much earlier in the cycle, before
1502 * copying the data in; this saves us valuable cycles when operating
1503 * as a multicast router or when using BPF.
1504 */
1505
1506 /*
1507 * Finally pass this packet up to higher layers.
1508 */
1509 ether_input(&ie->arpcom.ac_if, &eh, m);
1510 }
1511
1512 static void
1513 ie_drop_packet_buffer(int unit, struct ie_softc * ie)
1514 {
1515 int i;
1516
1517 do {
1518 /*
1519 * This means we are somehow out of sync. So, we reset the
1520 * adapter.
1521 */
1522 if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1523 #ifdef DEBUG
1524 print_rbd(ie->rbuffs[ie->rbhead]);
1525 #endif
1526 log(LOG_ERR, "ie%d: receive descriptors out of sync at %d\n",
1527 unit, ie->rbhead);
1528 iereset(unit);
1529 return;
1530 }
1531 i = ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1532
1533 ie->rbuffs[ie->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1534 ie->rbuffs[ie->rbhead]->ie_rbd_actual = 0;
1535 ie->rbhead = (ie->rbhead + 1) % ie->nrxbufs;
1536 ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1537 ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs;
1538 } while (!i);
1539 }
1540
1541
1542 /*
1543 * Start transmission on an interface.
1544 */
1545 static void
1546 iestart(struct ifnet *ifp)
1547 {
1548 struct ie_softc *ie = ifp->if_softc;
1549 struct mbuf *m0, *m;
1550 unsigned char *buffer;
1551 u_short len;
1552
1553 /*
1554 * This is not really volatile, in this routine, but it makes gcc
1555 * happy.
1556 */
1557 volatile u_short *bptr = &ie->scb->ie_command_list;
1558
1559 if (!(ifp->if_flags & IFF_RUNNING))
1560 return;
1561 if (ifp->if_flags & IFF_OACTIVE)
1562 return;
1563
1564 do {
1565 IF_DEQUEUE(&ie->arpcom.ac_if.if_snd, m);
1566 if (!m)
1567 break;
1568
1569 buffer = ie->xmit_cbuffs[ie->xmit_count];
1570 len = 0;
1571
1572 for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) {
1573 bcopy(mtod(m, caddr_t), buffer, m->m_len);
1574 buffer += m->m_len;
1575 len += m->m_len;
1576 }
1577
1578 m_freem(m0);
1579 len = max(len, ETHER_MIN_LEN);
1580
1581 #if NBPFILTER > 0
1582 /*
1583 * See if bpf is listening on this interface, let it see the
1584 * packet before we commit it to the wire.
1585 */
1586 if (ie->arpcom.ac_if.if_bpf)
1587 bpf_tap(&ie->arpcom.ac_if,
1588 ie->xmit_cbuffs[ie->xmit_count], len);
1589 #endif
1590
1591 ie->xmit_buffs[ie->xmit_count]->ie_xmit_flags =
1592 IE_XMIT_LAST|len;
1593 ie->xmit_buffs[ie->xmit_count]->ie_xmit_next = 0xffff;
1594 ie->xmit_buffs[ie->xmit_count]->ie_xmit_buf =
1595 MK_24(ie->iomem, ie->xmit_cbuffs[ie->xmit_count]);
1596
1597 ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT;
1598 ie->xmit_cmds[ie->xmit_count]->ie_xmit_status = 0;
1599 ie->xmit_cmds[ie->xmit_count]->ie_xmit_desc =
1600 MK_16(ie->iomem, ie->xmit_buffs[ie->xmit_count]);
1601
1602 *bptr = MK_16(ie->iomem, ie->xmit_cmds[ie->xmit_count]);
1603 bptr = &ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_link;
1604 ie->xmit_count++;
1605 } while (ie->xmit_count < ie->ntxbufs);
1606
1607 /*
1608 * If we queued up anything for transmission, send it.
1609 */
1610 if (ie->xmit_count) {
1611 ie->xmit_cmds[ie->xmit_count - 1]->com.ie_cmd_cmd |=
1612 IE_CMD_LAST | IE_CMD_INTR;
1613
1614 /*
1615 * By passing the command pointer as a null, we tell
1616 * command_and_wait() to pretend that this isn't an action
1617 * command. I wish I understood what was happening here.
1618 */
1619 command_and_wait(ifp->if_unit, IE_CU_START, 0, 0);
1620 ifp->if_flags |= IFF_OACTIVE;
1621 }
1622 return;
1623 }
1624
1625 /*
1626 * Check to see if there's an 82586 out there.
1627 */
1628 static int
1629 check_ie_present(int unit, caddr_t where, unsigned size)
1630 {
1631 volatile struct ie_sys_conf_ptr *scp;
1632 volatile struct ie_int_sys_conf_ptr *iscp;
1633 volatile struct ie_sys_ctl_block *scb;
1634 u_long realbase;
1635 int s;
1636
1637 s = splimp();
1638
1639 realbase = (uintptr_t) where + size - (1 << 24);
1640
1641 scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t)
1642 (realbase + IE_SCP_ADDR);
1643 bzero((char *) scp, sizeof *scp);
1644
1645 /*
1646 * First we put the ISCP at the bottom of memory; this tests to make
1647 * sure that our idea of the size of memory is the same as the
1648 * controller's. This is NOT where the ISCP will be in normal
1649 * operation.
1650 */
1651 iscp = (volatile struct ie_int_sys_conf_ptr *) where;
1652 bzero((char *)iscp, sizeof *iscp);
1653
1654 scb = (volatile struct ie_sys_ctl_block *) where;
1655 bzero((char *)scb, sizeof *scb);
1656
1657 scp->ie_bus_use = ie_softc[unit].bus_use; /* 8-bit or 16-bit */
1658 scp->ie_iscp_ptr = (caddr_t) ((volatile caddr_t) iscp -
1659 (volatile caddr_t) (volatile uintptr_t)
1660 realbase);
1661
1662 iscp->ie_busy = 1;
1663 iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1664
1665 (*ie_softc[unit].ie_reset_586) (unit);
1666 (*ie_softc[unit].ie_chan_attn) (unit);
1667
1668 DELAY(100); /* wait a while... */
1669
1670 if (iscp->ie_busy) {
1671 splx(s);
1672 return (0);
1673 }
1674 /*
1675 * Now relocate the ISCP to its real home, and reset the controller
1676 * again.
1677 */
1678 iscp = (void *) Align((caddr_t) (uintptr_t)
1679 (realbase + IE_SCP_ADDR -
1680 sizeof(struct ie_int_sys_conf_ptr)));
1681 bzero((char *) iscp, sizeof *iscp); /* ignore cast-qual */
1682
1683 scp->ie_iscp_ptr = (caddr_t) ((caddr_t) iscp -
1684 (caddr_t) (uintptr_t) realbase);
1685 /* ignore cast-qual */
1686
1687 iscp->ie_busy = 1;
1688 iscp->ie_scb_offset = MK_16(realbase, scb);
1689
1690 (*ie_softc[unit].ie_reset_586) (unit);
1691 (*ie_softc[unit].ie_chan_attn) (unit);
1692
1693 DELAY(100);
1694
1695 if (iscp->ie_busy) {
1696 splx(s);
1697 return (0);
1698 }
1699 ie_softc[unit].iosize = size;
1700 ie_softc[unit].iomem = (caddr_t) (uintptr_t) realbase;
1701
1702 ie_softc[unit].iscp = iscp;
1703 ie_softc[unit].scb = scb;
1704
1705 /*
1706 * Acknowledge any interrupts we may have caused...
1707 */
1708 ie_ack(scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
1709 splx(s);
1710
1711 return (1);
1712 }
1713
1714 /*
1715 * Divine the memory size of ie board UNIT.
1716 * Better hope there's nothing important hiding just below the ie card...
1717 */
1718 static void
1719 find_ie_mem_size(int unit)
1720 {
1721 unsigned size;
1722
1723 ie_softc[unit].iosize = 0;
1724
1725 for (size = 65536; size >= 8192; size -= 8192) {
1726 if (check_ie_present(unit, ie_softc[unit].iomembot, size)) {
1727 return;
1728 }
1729 }
1730
1731 return;
1732 }
1733
1734 void
1735 el_reset_586(int unit)
1736 {
1737 outb(PORT + IE507_CTRL, EL_CTRL_RESET);
1738 DELAY(100);
1739 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
1740 DELAY(100);
1741 }
1742
1743 void
1744 sl_reset_586(int unit)
1745 {
1746 outb(PORT + IEATT_RESET, 0);
1747 }
1748
1749 void
1750 ee16_reset_586(int unit)
1751 {
1752 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
1753 DELAY(100);
1754 outb(PORT + IEE16_ECTRL, 0);
1755 DELAY(100);
1756 }
1757
1758 void
1759 el_chan_attn(int unit)
1760 {
1761 outb(PORT + IE507_ATTN, 1);
1762 }
1763
1764 void
1765 sl_chan_attn(int unit)
1766 {
1767 outb(PORT + IEATT_ATTN, 0);
1768 }
1769
1770 void
1771 ee16_chan_attn(int unit)
1772 {
1773 outb(PORT + IEE16_ATTN, 0);
1774 }
1775
1776 u_short
1777 ee16_read_eeprom(struct ie_softc *sc, int location)
1778 {
1779 int ectrl, edata;
1780
1781 ectrl = inb(sc->port + IEE16_ECTRL);
1782 ectrl &= IEE16_ECTRL_MASK;
1783 ectrl |= IEE16_ECTRL_EECS;
1784 outb(sc->port + IEE16_ECTRL, ectrl);
1785
1786 ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
1787 ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
1788 edata = ee16_eeprom_inbits(sc);
1789 ectrl = inb(sc->port + IEE16_ECTRL);
1790 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
1791 outb(sc->port + IEE16_ECTRL, ectrl);
1792 ee16_eeprom_clock(sc, 1);
1793 ee16_eeprom_clock(sc, 0);
1794 return edata;
1795 }
1796
1797 void
1798 ee16_eeprom_outbits(struct ie_softc *sc, int edata, int count)
1799 {
1800 int ectrl, i;
1801
1802 ectrl = inb(sc->port + IEE16_ECTRL);
1803 ectrl &= ~IEE16_RESET_ASIC;
1804 for (i = count - 1; i >= 0; i--) {
1805 ectrl &= ~IEE16_ECTRL_EEDI;
1806 if (edata & (1 << i)) {
1807 ectrl |= IEE16_ECTRL_EEDI;
1808 }
1809 outb(sc->port + IEE16_ECTRL, ectrl);
1810 DELAY(1); /* eeprom data must be setup for 0.4 uSec */
1811 ee16_eeprom_clock(sc, 1);
1812 ee16_eeprom_clock(sc, 0);
1813 }
1814 ectrl &= ~IEE16_ECTRL_EEDI;
1815 outb(sc->port + IEE16_ECTRL, ectrl);
1816 DELAY(1); /* eeprom data must be held for 0.4 uSec */
1817 }
1818
1819 int
1820 ee16_eeprom_inbits(struct ie_softc *sc)
1821 {
1822 int ectrl, edata, i;
1823
1824 ectrl = inb(sc->port + IEE16_ECTRL);
1825 ectrl &= ~IEE16_RESET_ASIC;
1826 for (edata = 0, i = 0; i < 16; i++) {
1827 edata = edata << 1;
1828 ee16_eeprom_clock(sc, 1);
1829 ectrl = inb(sc->port + IEE16_ECTRL);
1830 if (ectrl & IEE16_ECTRL_EEDO) {
1831 edata |= 1;
1832 }
1833 ee16_eeprom_clock(sc, 0);
1834 }
1835 return (edata);
1836 }
1837
1838 void
1839 ee16_eeprom_clock(struct ie_softc *sc, int state)
1840 {
1841 int ectrl;
1842
1843 ectrl = inb(sc->port + IEE16_ECTRL);
1844 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
1845 if (state) {
1846 ectrl |= IEE16_ECTRL_EESK;
1847 }
1848 outb(sc->port + IEE16_ECTRL, ectrl);
1849 DELAY(9); /* EESK must be stable for 8.38 uSec */
1850 }
1851
1852 static __inline void
1853 ee16_interrupt_enable(struct ie_softc *sc)
1854 {
1855 DELAY(100);
1856 outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1857 DELAY(100);
1858 }
1859
1860 void
1861 sl_read_ether(int unit, unsigned char addr[6])
1862 {
1863 int i;
1864
1865 for (i = 0; i < 6; i++)
1866 addr[i] = inb(PORT + i);
1867 }
1868
1869
1870 static void
1871 iereset(int unit)
1872 {
1873 int s = splimp();
1874
1875 if (unit >= NIE) {
1876 splx(s);
1877 return;
1878 }
1879 printf("ie%d: reset\n", unit);
1880 ie_softc[unit].arpcom.ac_if.if_flags &= ~IFF_UP;
1881 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0);
1882
1883 /*
1884 * Stop i82586 dead in its tracks.
1885 */
1886 if (command_and_wait(unit, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1887 printf("ie%d: abort commands timed out\n", unit);
1888
1889 if (command_and_wait(unit, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1890 printf("ie%d: disable commands timed out\n", unit);
1891
1892 #ifdef notdef
1893 if (!check_ie_present(unit, ie_softc[unit].iomembot,
1894 e_softc[unit].iosize))
1895 panic("ie disappeared!");
1896 #endif
1897
1898 ie_softc[unit].arpcom.ac_if.if_flags |= IFF_UP;
1899 ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0);
1900
1901 splx(s);
1902 return;
1903 }
1904
1905 /*
1906 * This is called if we time out.
1907 */
1908 static void
1909 chan_attn_timeout(void *rock)
1910 {
1911 *(int *) rock = 1;
1912 }
1913
1914 /*
1915 * Send a command to the controller and wait for it to either
1916 * complete or be accepted, depending on the command. If the
1917 * command pointer is null, then pretend that the command is
1918 * not an action command. If the command pointer is not null,
1919 * and the command is an action command, wait for
1920 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1921 * to become true.
1922 */
1923 static int
1924 command_and_wait(int unit, int cmd, volatile void *pcmd, int mask)
1925 {
1926 volatile struct ie_cmd_common *cc = pcmd;
1927 volatile int timedout = 0;
1928 struct callout_handle ch;
1929
1930 ie_softc[unit].scb->ie_command = (u_short) cmd;
1931
1932 if (IE_ACTION_COMMAND(cmd) && pcmd) {
1933 (*ie_softc[unit].ie_chan_attn) (unit);
1934
1935 /*
1936 * According to the packet driver, the minimum timeout
1937 * should be .369 seconds, which we round up to .37.
1938 */
1939 ch = timeout(chan_attn_timeout, (caddr_t)&timedout,
1940 37 * hz / 100);
1941 /* ignore cast-qual */
1942
1943 /*
1944 * Now spin-lock waiting for status. This is not a very
1945 * nice thing to do, but I haven't figured out how, or
1946 * indeed if, we can put the process waiting for action to
1947 * sleep. (We may be getting called through some other
1948 * timeout running in the kernel.)
1949 */
1950 while (1) {
1951 if ((cc->ie_cmd_status & mask) || timedout)
1952 break;
1953 }
1954
1955 untimeout(chan_attn_timeout, (caddr_t)&timedout, ch);
1956 /* ignore cast-qual */
1957
1958 return (timedout);
1959 } else {
1960
1961 /*
1962 * Otherwise, just wait for the command to be accepted.
1963 */
1964 (*ie_softc[unit].ie_chan_attn) (unit);
1965
1966 while (ie_softc[unit].scb->ie_command); /* spin lock */
1967
1968 return (0);
1969 }
1970 }
1971
1972 /*
1973 * Run the time-domain reflectometer...
1974 */
1975 static void
1976 run_tdr(int unit, struct ie_tdr_cmd *cmd)
1977 {
1978 int result;
1979
1980 cmd->com.ie_cmd_status = 0;
1981 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1982 cmd->com.ie_cmd_link = 0xffff;
1983 cmd->ie_tdr_time = 0;
1984
1985 ie_softc[unit].scb->ie_command_list = MK_16(MEM, cmd);
1986 cmd->ie_tdr_time = 0;
1987
1988 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL))
1989 result = 0x2000;
1990 else
1991 result = cmd->ie_tdr_time;
1992
1993 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit,
1994 ie_softc[unit].ie_chan_attn);
1995
1996 if (result & IE_TDR_SUCCESS)
1997 return;
1998
1999 if (result & IE_TDR_XCVR) {
2000 printf("ie%d: transceiver problem\n", unit);
2001 } else if (result & IE_TDR_OPEN) {
2002 printf("ie%d: TDR detected an open %d clocks away\n", unit,
2003 result & IE_TDR_TIME);
2004 } else if (result & IE_TDR_SHORT) {
2005 printf("ie%d: TDR detected a short %d clocks away\n", unit,
2006 result & IE_TDR_TIME);
2007 } else {
2008 printf("ie%d: TDR returned unknown status %x\n", unit, result);
2009 }
2010 }
2011
2012 static void
2013 start_receiver(int unit)
2014 {
2015 int s = splimp();
2016
2017 ie_softc[unit].scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]);
2018 command_and_wait(unit, IE_RU_START, 0, 0);
2019
2020 ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn);
2021
2022 splx(s);
2023 }
2024
2025 /*
2026 * Here is a helper routine for iernr() and ieinit(). This sets up
2027 * the RFA.
2028 */
2029 static caddr_t
2030 setup_rfa(caddr_t ptr, struct ie_softc * ie)
2031 {
2032 volatile struct ie_recv_frame_desc *rfd = (void *) ptr;
2033 volatile struct ie_recv_buf_desc *rbd;
2034 int i;
2035 int unit = ie - &ie_softc[0];
2036
2037 /* First lay them out */
2038 for (i = 0; i < ie->nframes; i++) {
2039 ie->rframes[i] = rfd;
2040 bzero((char *) rfd, sizeof *rfd); /* ignore cast-qual */
2041 rfd++;
2042 }
2043
2044 ptr = (caddr_t) Align((caddr_t) rfd); /* ignore cast-qual */
2045
2046 /* Now link them together */
2047 for (i = 0; i < ie->nframes; i++) {
2048 ie->rframes[i]->ie_fd_next =
2049 MK_16(MEM, ie->rframes[(i + 1) % ie->nframes]);
2050 }
2051
2052 /* Finally, set the EOL bit on the last one. */
2053 ie->rframes[ie->nframes - 1]->ie_fd_last |= IE_FD_LAST;
2054
2055 /*
2056 * Now lay out some buffers for the incoming frames. Note that we
2057 * set aside a bit of slop in each buffer, to make sure that we have
2058 * enough space to hold a single frame in every buffer.
2059 */
2060 rbd = (void *) ptr;
2061
2062 for (i = 0; i < ie->nrxbufs; i++) {
2063 ie->rbuffs[i] = rbd;
2064 bzero((char *)rbd, sizeof *rbd);
2065 ptr = (caddr_t) Align(ptr + sizeof *rbd);
2066 rbd->ie_rbd_length = IE_RBUF_SIZE;
2067 rbd->ie_rbd_buffer = MK_24(MEM, ptr);
2068 ie->cbuffs[i] = (void *) ptr;
2069 ptr += IE_RBUF_SIZE;
2070 rbd = (void *) ptr;
2071 }
2072
2073 /* Now link them together */
2074 for (i = 0; i < ie->nrxbufs; i++) {
2075 ie->rbuffs[i]->ie_rbd_next =
2076 MK_16(MEM, ie->rbuffs[(i + 1) % ie->nrxbufs]);
2077 }
2078
2079 /* Tag EOF on the last one */
2080 ie->rbuffs[ie->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST;
2081
2082 /*
2083 * We use the head and tail pointers on receive to keep track of the
2084 * order in which RFDs and RBDs are used.
2085 */
2086 ie->rfhead = 0;
2087 ie->rftail = ie->nframes - 1;
2088 ie->rbhead = 0;
2089 ie->rbtail = ie->nrxbufs - 1;
2090
2091 ie->scb->ie_recv_list = MK_16(MEM, ie->rframes[0]);
2092 ie->rframes[0]->ie_fd_buf_desc = MK_16(MEM, ie->rbuffs[0]);
2093
2094 ptr = Align(ptr);
2095 return (ptr);
2096 }
2097
2098 /*
2099 * Run the multicast setup command.
2100 * Call at splimp().
2101 */
2102 static int
2103 mc_setup(int unit, caddr_t ptr,
2104 volatile struct ie_sys_ctl_block * scb)
2105 {
2106 struct ie_softc *ie = &ie_softc[unit];
2107 volatile struct ie_mcast_cmd *cmd = (void *) ptr;
2108
2109 cmd->com.ie_cmd_status = 0;
2110 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
2111 cmd->com.ie_cmd_link = 0xffff;
2112
2113 /* ignore cast-qual */
2114 bcopy((caddr_t) ie->mcast_addrs, (caddr_t) cmd->ie_mcast_addrs,
2115 ie->mcast_count * sizeof *ie->mcast_addrs);
2116
2117 cmd->ie_mcast_bytes = ie->mcast_count * 6; /* grrr... */
2118
2119 scb->ie_command_list = MK_16(MEM, cmd);
2120 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2121 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2122 printf("ie%d: multicast address setup command failed\n", unit);
2123 return (0);
2124 }
2125 return (1);
2126 }
2127
2128 /*
2129 * This routine takes the environment generated by check_ie_present()
2130 * and adds to it all the other structures we need to operate the adapter.
2131 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
2132 * starting the receiver unit, and clearing interrupts.
2133 *
2134 * THIS ROUTINE MUST BE CALLED AT splimp() OR HIGHER.
2135 */
2136 static void
2137 ieinit(int unit)
2138 {
2139 struct ie_softc *ie = &ie_softc[unit];
2140 volatile struct ie_sys_ctl_block *scb = ie->scb;
2141 caddr_t ptr;
2142 int i;
2143
2144 ptr = (caddr_t) Align((caddr_t) scb + sizeof *scb);
2145
2146 /*
2147 * Send the configure command first.
2148 */
2149 {
2150 volatile struct ie_config_cmd *cmd = (void *) ptr;
2151
2152 ie_setup_config(cmd, ie->promisc,
2153 ie->hard_type == IE_STARLAN10);
2154 cmd->com.ie_cmd_status = 0;
2155 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
2156 cmd->com.ie_cmd_link = 0xffff;
2157
2158 scb->ie_command_list = MK_16(MEM, cmd);
2159
2160 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2161 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2162 printf("ie%d: configure command failed\n", unit);
2163 return;
2164 }
2165 }
2166 /*
2167 * Now send the Individual Address Setup command.
2168 */
2169 {
2170 volatile struct ie_iasetup_cmd *cmd = (void *) ptr;
2171
2172 cmd->com.ie_cmd_status = 0;
2173 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
2174 cmd->com.ie_cmd_link = 0xffff;
2175
2176 bcopy((char *)ie_softc[unit].arpcom.ac_enaddr,
2177 (char *)&cmd->ie_address, sizeof cmd->ie_address);
2178 scb->ie_command_list = MK_16(MEM, cmd);
2179 if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)
2180 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2181 printf("ie%d: individual address "
2182 "setup command failed\n", unit);
2183 return;
2184 }
2185 }
2186
2187 /*
2188 * Now run the time-domain reflectometer.
2189 */
2190 run_tdr(unit, (void *) ptr);
2191
2192 /*
2193 * Acknowledge any interrupts we have generated thus far.
2194 */
2195 ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn);
2196
2197 /*
2198 * Set up the RFA.
2199 */
2200 ptr = setup_rfa(ptr, ie);
2201
2202 /*
2203 * Finally, the transmit command and buffer are the last little bit
2204 * of work.
2205 */
2206
2207 /* transmit command buffers */
2208 for (i = 0; i < ie->ntxbufs; i++) {
2209 ie->xmit_cmds[i] = (void *) ptr;
2210 ptr += sizeof *ie->xmit_cmds[i];
2211 ptr = Align(ptr);
2212 ie->xmit_buffs[i] = (void *)ptr;
2213 ptr += sizeof *ie->xmit_buffs[i];
2214 ptr = Align(ptr);
2215 }
2216
2217 /* transmit buffers */
2218 for (i = 0; i < ie->ntxbufs - 1; i++) {
2219 ie->xmit_cbuffs[i] = (void *)ptr;
2220 ptr += IE_BUF_LEN;
2221 ptr = Align(ptr);
2222 }
2223 ie->xmit_cbuffs[ie->ntxbufs - 1] = (void *) ptr;
2224
2225 for (i = 1; i < ie->ntxbufs; i++) {
2226 bzero((caddr_t) ie->xmit_cmds[i], sizeof *ie->xmit_cmds[i]);
2227 bzero((caddr_t) ie->xmit_buffs[i], sizeof *ie->xmit_buffs[i]);
2228 }
2229
2230 /*
2231 * This must be coordinated with iestart() and ietint().
2232 */
2233 ie->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL;
2234
2235 /* take the ee16 out of loopback */
2236 if (ie->hard_type == IE_EE16) {
2237 u_int8_t bart_config;
2238
2239 bart_config = inb(PORT + IEE16_CONFIG);
2240 bart_config &= ~IEE16_BART_LOOPBACK;
2241 /* inb doesn't get bit! */
2242 bart_config |= IEE16_BART_MCS16_TEST;
2243 outb(PORT + IEE16_CONFIG, bart_config);
2244 ee16_interrupt_enable(ie);
2245 ee16_chan_attn(unit);
2246 }
2247 ie->arpcom.ac_if.if_flags |= IFF_RUNNING; /* tell higher levels
2248 * we're here */
2249 start_receiver(unit);
2250
2251 return;
2252 }
2253
2254 static void
2255 ie_stop(int unit)
2256 {
2257 command_and_wait(unit, IE_RU_DISABLE, 0, 0);
2258 }
2259
2260 static int
2261 ieioctl(struct ifnet *ifp, u_long command, caddr_t data)
2262 {
2263 struct ifaddr *ifa = (struct ifaddr *) data;
2264 #if defined(IPX) || defined(NS)
2265 struct ie_softc *ie = ifp->if_softc;
2266 #endif
2267 struct ifreq *ifr = (struct ifreq *) data;
2268 int s, error = 0;
2269
2270 s = splimp();
2271
2272 switch (command) {
2273 case SIOCSIFADDR:
2274 ifp->if_flags |= IFF_UP;
2275
2276 switch (ifa->ifa_addr->sa_family) {
2277 #ifdef INET
2278 case AF_INET:
2279 ieinit(ifp->if_unit);
2280 arp_ifinit((struct arpcom *) ifp, ifa);
2281 break;
2282 #endif /* INET */
2283
2284 #ifdef IPX
2285 /*
2286 * This magic copied from if_is.c; I don't use XNS,
2287 * so I have no way of telling if this actually
2288 * works or not.
2289 */
2290 case AF_IPX:
2291 {
2292 struct ipx_addr *ina =
2293 &(IA_SIPX(ifa)->sipx_addr);
2294
2295 if (ipx_nullhost(*ina)) {
2296 ina->x_host = *(union ipx_host *) (ie->arpcom.ac_enaddr);
2297 } else {
2298 ifp->if_flags &= ~IFF_RUNNING;
2299 bcopy((caddr_t) ina->x_host.c_host,
2300 (caddr_t) ie->arpcom.ac_enaddr,
2301 sizeof ie->arpcom.ac_enaddr);
2302 }
2303
2304 ieinit(ifp->if_unit);
2305 }
2306 break;
2307 #endif /* IPX */
2308
2309 #ifdef NS
2310 /*
2311 * This magic copied from if_is.c; I don't use XNS,
2312 * so I have no way of telling if this actually
2313 * works or not.
2314 */
2315 case AF_NS:
2316 {
2317 struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
2318
2319 if (ns_nullhost(*ina)) {
2320 ina->x_host = *(union ns_host *)(ie->arpcom.ac_enaddr);
2321 } else {
2322 ifp->if_flags &= ~IFF_RUNNING;
2323 bcopy((caddr_t) ina->x_host.c_host,
2324 (caddr_t) ie->arpcom.ac_enaddr,
2325 sizeof ie->arpcom.ac_enaddr);
2326 }
2327
2328 ieinit(ifp->if_unit);
2329 }
2330 break;
2331 #endif /* NS */
2332
2333 default:
2334 ieinit(ifp->if_unit);
2335 break;
2336 }
2337 break;
2338
2339 case SIOCSIFFLAGS:
2340 /*
2341 * Note that this device doesn't have an "all multicast"
2342 * mode, so we must turn on promiscuous mode and do the
2343 * filtering manually.
2344 */
2345 if ((ifp->if_flags & IFF_UP) == 0 &&
2346 (ifp->if_flags & IFF_RUNNING)) {
2347 ifp->if_flags &= ~IFF_RUNNING;
2348 ie_stop(ifp->if_unit);
2349 } else if ((ifp->if_flags & IFF_UP) &&
2350 (ifp->if_flags & IFF_RUNNING) == 0) {
2351 ie_softc[ifp->if_unit].promisc =
2352 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2353 ieinit(ifp->if_unit);
2354 } else if (ie_softc[ifp->if_unit].promisc ^
2355 (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) {
2356 ie_softc[ifp->if_unit].promisc =
2357 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2358 ieinit(ifp->if_unit);
2359 }
2360 break;
2361
2362 case SIOCADDMULTI:
2363 case SIOCDELMULTI:
2364 /*
2365 * Update multicast listeners
2366 */
2367 /* reset multicast filtering */
2368 ie_mc_reset(ifp->if_unit);
2369 error = 0;
2370 break;
2371
2372 case SIOCSIFMTU:
2373 /*
2374 * Set the interface MTU.
2375 */
2376 if (ifr->ifr_mtu > ETHERMTU) {
2377 error = EINVAL;
2378 } else {
2379 ifp->if_mtu = ifr->ifr_mtu;
2380 }
2381 break;
2382
2383 default:
2384 error = EINVAL;
2385 }
2386
2387 splx(s);
2388 return (error);
2389 }
2390
2391 static void
2392 ie_mc_reset(int unit)
2393 {
2394 struct ie_softc *ie = &ie_softc[unit];
2395 struct ifmultiaddr *ifma;
2396
2397 /*
2398 * Step through the list of addresses.
2399 */
2400 ie->mcast_count = 0;
2401 for (ifma = ie->arpcom.ac_if.if_multiaddrs.lh_first; ifma;
2402 ifma = ifma->ifma_link.le_next) {
2403 if (ifma->ifma_addr->sa_family != AF_LINK)
2404 continue;
2405
2406 /* XXX - this is broken... */
2407 if (ie->mcast_count >= MAXMCAST) {
2408 ie->arpcom.ac_if.if_flags |= IFF_ALLMULTI;
2409 ieioctl(&ie->arpcom.ac_if, SIOCSIFFLAGS, (void *) 0);
2410 goto setflag;
2411 }
2412 bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
2413 &(ie->mcast_addrs[ie->mcast_count]), 6);
2414 ie->mcast_count++;
2415 }
2416
2417 setflag:
2418 ie->want_mcsetup = 1;
2419 }
2420
2421
2422 #ifdef DEBUG
2423 static void
2424 print_rbd(volatile struct ie_recv_buf_desc * rbd)
2425 {
2426 printf("RBD at %p:\n"
2427 "actual %04x, next %04x, buffer %p\n"
2428 "length %04x, mbz %04x\n",
2429 (void *) rbd,
2430 rbd->ie_rbd_actual, rbd->ie_rbd_next,
2431 (void *) rbd->ie_rbd_buffer,
2432 rbd->ie_rbd_length, rbd->mbz);
2433 }
2434
2435 #endif /* DEBUG */
2436 #endif /* NIE > 0 */
Cache object: aa7101418026ab086880a8cde2582664
|