i82586.c revision 1.6 1 /* $NetBSD: i82586.c,v 1.6 1997/08/01 20:04:40 pk Exp $ */
2
3 /*-
4 * Copyright (c) 1997 Paul Kranenburg.
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) 1994, 1995, Rafal K. Boni
12 * Copyright (c) 1990, 1991, William F. Jolitz
13 * Copyright (c) 1990, The Regents of the University of California
14 *
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. All advertising materials mentioning features or use of this software
26 * must display the following acknowledgement:
27 * This product includes software developed by Charles Hannum, by the
28 * University of Vermont and State Agricultural College and Garrett A.
29 * Wollman, by William F. Jolitz, and by the University of California,
30 * Berkeley, Lawrence Berkeley Laboratory, and its contributors.
31 * 4. Neither the names of the Universities nor the names of the authors
32 * may be used to endorse or promote products derived from this software
33 * without specific prior written permission.
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * SUCH DAMAGE.
46 */
47
48 /*
49 * Intel 82586 Ethernet chip
50 * Register, bit, and structure definitions.
51 *
52 * Original StarLAN driver written by Garrett Wollman with reference to the
53 * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
54 *
55 * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
56 *
57 * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
58 *
59 * Majorly cleaned up and 3C507 code merged by Charles Hannum.
60 *
61 * Converted to SUN ie driver by Charles D. Cranor,
62 * October 1994, January 1995.
63 * This sun version based on i386 version 1.30.
64 */
65
66 /*
67 * The i82586 is a very painful chip, found in sun3's, sun-4/100's
68 * sun-4/200's, and VME based suns. The byte order is all wrong for a
69 * SUN, making life difficult. Programming this chip is mostly the same,
70 * but certain details differ from system to system. This driver is
71 * written so that different "ie" interfaces can be controled by the same
72 * driver.
73 */
74
75 /*
76 Mode of operation:
77
78 We run the 82586 in a standard Ethernet mode. We keep NFRAMES
79 received frame descriptors around for the receiver to use, and
80 NRXBUF associated receive buffer descriptors, both in a circular
81 list. Whenever a frame is received, we rotate both lists as
82 necessary. (The 586 treats both lists as a simple queue.) We also
83 keep a transmit command around so that packets can be sent off
84 quickly.
85
86 We configure the adapter in AL-LOC = 1 mode, which means that the
87 Ethernet/802.3 MAC header is placed at the beginning of the receive
88 buffer rather than being split off into various fields in the RFD.
89 This also means that we must include this header in the transmit
90 buffer as well.
91
92 By convention, all transmit commands, and only transmit commands,
93 shall have the I (IE_CMD_INTR) bit set in the command. This way,
94 when an interrupt arrives at ieintr(), it is immediately possible
95 to tell what precisely caused it. ANY OTHER command-sending
96 routines should run at splnet(), and should post an acknowledgement
97 to every interrupt they generate.
98
99 To save the expense of shipping a command to 82586 every time we
100 want to send a frame, we use a linked list of commands consisting
101 of alternate XMIT and NOP commands. The links of these elements
102 are manipulated (in iexmit()) such that the NOP command loops back
103 to itself whenever the following XMIT command is not yet ready to
104 go. Whenever an XMIT is ready, the preceding NOP link is pointed
105 at it, while its own link field points to the following NOP command.
106 Thus, a single transmit command sets off an interlocked traversal
107 of the xmit command chain, with the host processor in control of
108 the synchronization.
109 */
110
111 #include "bpfilter.h"
112
113 #include <sys/param.h>
114 #include <sys/systm.h>
115 #include <sys/mbuf.h>
116 #include <sys/buf.h>
117 #include <sys/protosw.h>
118 #include <sys/socket.h>
119 #include <sys/ioctl.h>
120 #include <sys/errno.h>
121 #include <sys/syslog.h>
122 #include <sys/device.h>
123
124 #include <net/if.h>
125 #include <net/if_types.h>
126 #include <net/if_dl.h>
127 #include <net/if_ether.h>
128
129 #if NBPFILTER > 0
130 #include <net/bpf.h>
131 #include <net/bpfdesc.h>
132 #endif
133
134 #ifdef INET
135 #include <netinet/in.h>
136 #include <netinet/in_systm.h>
137 #include <netinet/in_var.h>
138 #include <netinet/ip.h>
139 #include <netinet/if_inarp.h>
140 #endif
141
142 #ifdef NS
143 #include <netns/ns.h>
144 #include <netns/ns_if.h>
145 #endif
146
147 #include <machine/bus.h>
148
149 #include <dev/ic/i82586reg.h>
150 #include <dev/ic/i82586var.h>
151
152 void iewatchdog __P((struct ifnet *));
153 int ieinit __P((struct ie_softc *));
154 int ieioctl __P((struct ifnet *, u_long, caddr_t));
155 void iestart __P((struct ifnet *));
156 void iereset __P((struct ie_softc *));
157 static void ie_readframe __P((struct ie_softc *, int));
158 static void ie_drop_packet_buffer __P((struct ie_softc *));
159 int ie_setupram __P((struct ie_softc *));
160 static int command_and_wait __P((struct ie_softc *, int,
161 void volatile *, int));
162 /*static*/ void ierint __P((struct ie_softc *));
163 /*static*/ void ietint __P((struct ie_softc *));
164 static struct mbuf *ieget __P((struct ie_softc *,
165 struct ether_header *, int *));
166 static void setup_bufs __P((struct ie_softc *));
167 static int mc_setup __P((struct ie_softc *, void *));
168 static void mc_reset __P((struct ie_softc *));
169 static __inline int ether_equal __P((u_char *, u_char *));
170 static __inline void ie_ack __P((struct ie_softc *, u_int));
171 static __inline void ie_setup_config __P((volatile struct ie_config_cmd *,
172 int, int));
173 static __inline int check_eh __P((struct ie_softc *, struct ether_header *,
174 int *));
175 static __inline int ie_buflen __P((struct ie_softc *, int));
176 static __inline int ie_packet_len __P((struct ie_softc *));
177 static __inline void iexmit __P((struct ie_softc *));
178 static void i82586_start_transceiver __P((struct ie_softc *));
179
180 static void run_tdr __P((struct ie_softc *, struct ie_tdr_cmd *));
181 static void iestop __P((struct ie_softc *));
182
183 #ifdef IEDEBUG
184 void print_rbd __P((volatile struct ie_recv_buf_desc *));
185
186 int in_ierint = 0;
187 int in_ietint = 0;
188 #endif
189
190 int i82586_xmitnopchain = 1; /* Controls use of xmit NOP chains */
191
192 struct cfdriver ie_cd = {
193 NULL, "ie", DV_IFNET
194 };
195
196 /*
197 * Address generation macros:
198 * MK_24 = KVA -> 24 bit address in native byte order
199 * MK_16 = KVA -> 16 bit address in INTEL byte order
200 * ST_24 = store a 24 bit address in native byte order to INTEL byte order
201 */
202 #define MK_24(base, ptr) ((caddr_t)((u_long)ptr - (u_long)base))
203
204 #if BYTE_ORDER == BIG_ENDIAN
205 #define XSWAP(y) ( ((y) >> 8) | ((y) << 8) )
206 #define SWAP(x) ({u_short _z=(x); (u_short)XSWAP(_z);})
207
208 #define MK_16(base, ptr) SWAP((u_short)( ((u_long)(ptr)) - ((u_long)(base)) ))
209 #define ST_24(to, from) { \
210 u_long fval = (u_long)(from); \
211 u_char *t = (u_char *)&(to), *f = (u_char *)&fval; \
212 t[0] = f[3]; t[1] = f[2]; t[2] = f[1]; /*t[3] = f[0] ;*/ \
213 }
214 #else
215 #define SWAP(x) x
216 #define MK_16(base, ptr) ((u_short)(u_long)MK_24(base, ptr))
217 #define ST_24(to, from) {to = (from);}
218 #endif
219
220 /*
221 * Here are a few useful functions. We could have done these as macros, but
222 * since we have the inline facility, it makes sense to use that instead.
223 */
224 static __inline void
225 ie_setup_config(cmd, promiscuous, manchester)
226 volatile struct ie_config_cmd *cmd;
227 int promiscuous, manchester;
228 {
229
230 cmd->ie_config_count = 0x0c;
231 cmd->ie_fifo = 8;
232 cmd->ie_save_bad = 0x40;
233 cmd->ie_addr_len = 0x2e;
234 cmd->ie_priority = 0;
235 cmd->ie_ifs = 0x60;
236 cmd->ie_slot_low = 0;
237 cmd->ie_slot_high = 0xf2;
238 cmd->ie_promisc = !!promiscuous | manchester << 2;
239 cmd->ie_crs_cdt = 0;
240 cmd->ie_min_len = 64;
241 cmd->ie_junk = 0xff;
242 }
243
244 static __inline void
245 ie_ack(sc, mask)
246 struct ie_softc *sc;
247 u_int mask; /* in native byte-order */
248 {
249 volatile struct ie_sys_ctl_block *scb = sc->scb;
250
251 bus_space_barrier(sc->bt, sc->bh, 0, 0, BUS_SPACE_BARRIER_READ);
252 command_and_wait(sc, SWAP(scb->ie_status) & mask, 0, 0);
253 }
254
255
256 /*
257 * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
258 */
259 void
260 ie_attach(sc, name, etheraddr)
261 struct ie_softc *sc;
262 char *name;
263 u_int8_t *etheraddr;
264 {
265 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
266
267 if (ie_setupram(sc) == 0) { /* XXX - ISA version? */
268 printf(": RAM CONFIG FAILED!\n");
269 /* XXX should reclaim resources? */
270 return;
271 }
272
273 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
274 ifp->if_softc = sc;
275 ifp->if_start = iestart;
276 ifp->if_ioctl = ieioctl;
277 ifp->if_watchdog = iewatchdog;
278 ifp->if_flags =
279 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
280
281 /* Attach the interface. */
282 if_attach(ifp);
283 ether_ifattach(ifp, etheraddr);
284
285 printf(" address %s, type %s\n", ether_sprintf(etheraddr), name);
286
287 #if NBPFILTER > 0
288 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
289 #endif
290 }
291
292
293 /*
294 * Device timeout/watchdog routine. Entered if the device neglects to generate
295 * an interrupt after a transmit has been started on it.
296 */
297 void
298 iewatchdog(ifp)
299 struct ifnet *ifp;
300 {
301 struct ie_softc *sc = ifp->if_softc;
302
303 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
304 ++ifp->if_oerrors;
305
306 iereset(sc);
307 }
308
309 /*
310 * What to do upon receipt of an interrupt.
311 */
312 int
313 ieintr(v)
314 void *v;
315 {
316 struct ie_softc *sc = v;
317 u_int status;
318
319 /*
320 * Implementation dependent interrupt handling.
321 */
322 if (sc->intrhook)
323 (*sc->intrhook)(sc);
324
325 bus_space_barrier(sc->bt, sc->bh, 0, 0, BUS_SPACE_BARRIER_READ);
326 status = SWAP(sc->scb->ie_status) & IE_ST_WHENCE;
327
328 if (status == 0) {
329 printf("%s: spurious interrupt; status=0x%x\n",
330 sc->sc_dev.dv_xname, status);
331 return (0);
332 }
333 loop:
334 /* Ack interrupts FIRST in case we receive more during the ISR. */
335 ie_ack(sc, status);
336
337 if (status & (IE_ST_FR | IE_ST_RNR)) {
338 #ifdef IEDEBUG
339 in_ierint++;
340 if (sc->sc_debug & IED_RINT)
341 printf("%s: rint\n", sc->sc_dev.dv_xname);
342 #endif
343 ierint(sc);
344 #ifdef IEDEBUG
345 in_ierint--;
346 #endif
347 }
348
349 if (status & IE_ST_CX) {
350 #ifdef IEDEBUG
351 in_ietint++;
352 if (sc->sc_debug & IED_TINT)
353 printf("%s: tint\n", sc->sc_dev.dv_xname);
354 #endif
355 ietint(sc);
356 #ifdef IEDEBUG
357 in_ietint--;
358 #endif
359 }
360
361 if (status & IE_ST_RNR) {
362 printf("%s: receiver not ready; status=0x%x\n",
363 sc->sc_dev.dv_xname, status);
364 sc->sc_ethercom.ec_if.if_ierrors++;
365 iereset(sc);
366 return (1);
367 }
368
369 #ifdef IEDEBUG
370 if ((status & IE_ST_CNA) && (sc->sc_debug & IED_CNA))
371 printf("%s: cna; status=0x%x\n", sc->sc_dev.dv_xname, status);
372 #endif
373
374 bus_space_barrier(sc->bt, sc->bh, 0, 0, BUS_SPACE_BARRIER_READ);
375 status = SWAP(sc->scb->ie_status) & IE_ST_WHENCE;
376 if (status != 0)
377 goto loop;
378
379 return (1);
380 }
381
382 /*
383 * Process a received-frame interrupt.
384 */
385 void
386 ierint(sc)
387 struct ie_softc *sc;
388 {
389 volatile struct ie_sys_ctl_block *scb = sc->scb;
390 int i, status;
391 static int timesthru = 1024;
392
393 i = sc->rfhead;
394 for (;;) {
395 bus_space_barrier(sc->bt, sc->bh, 0, 0, BUS_SPACE_BARRIER_READ);
396 status = SWAP(sc->rframes[i]->ie_fd_status);
397
398 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
399 if (--timesthru == 0) {
400 sc->sc_ethercom.ec_if.if_ierrors +=
401 SWAP(scb->ie_err_crc) +
402 SWAP(scb->ie_err_align) +
403 SWAP(scb->ie_err_resource) +
404 SWAP(scb->ie_err_overrun);
405 scb->ie_err_crc = scb->ie_err_align =
406 scb->ie_err_resource = scb->ie_err_overrun =
407 SWAP(0);
408 timesthru = 1024;
409 }
410 ie_readframe(sc, i);
411 } else {
412 if ((status & IE_FD_RNR) != 0 &&
413 (SWAP(scb->ie_status) & IE_RU_READY) == 0) {
414 i82586_start_transceiver(sc);
415 }
416 break;
417 }
418 i = (i + 1) % sc->nframes;
419 }
420 }
421
422 /*
423 * Process a command-complete interrupt. These are only generated by the
424 * transmission of frames. This routine is deceptively simple, since most of
425 * the real work is done by iestart().
426 */
427 void
428 ietint(sc)
429 struct ie_softc *sc;
430 {
431 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
432 int status;
433
434 ifp->if_timer = 0;
435 ifp->if_flags &= ~IFF_OACTIVE;
436
437 #ifdef IEDEBUG
438 if (sc->xmit_busy <= 0) {
439 printf("ietint: WEIRD: xmit_busy = %d, xctail = %d, xchead=%d\n",
440 sc->xmit_busy, sc->xctail, sc->xchead);
441 return;
442 }
443 #endif
444
445 status = SWAP(sc->xmit_cmds[sc->xctail]->ie_xmit_status);
446
447 if ((status & IE_STAT_COMPL) == 0 || (status & IE_STAT_BUSY)) {
448 printf("ietint: command still busy; status=0x%x; tail=%d\n",
449 status, sc->xctail);
450 printf("iestatus = 0x%x\n", SWAP(sc->scb->ie_status));
451 }
452
453 if (status & IE_STAT_OK) {
454 ifp->if_opackets++;
455 ifp->if_collisions += (status & IE_XS_MAXCOLL);
456 } else {
457 ifp->if_oerrors++;
458 /*
459 * Check SQE and DEFERRED?
460 * What if more than one bit is set?
461 */
462 if (status & IE_STAT_ABORT)
463 printf("%s: send aborted\n", sc->sc_dev.dv_xname);
464 else if (status & IE_XS_NOCARRIER)
465 printf("%s: no carrier\n", sc->sc_dev.dv_xname);
466 else if (status & IE_XS_LOSTCTS)
467 printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
468 else if (status & IE_XS_UNDERRUN)
469 printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
470 else if (status & IE_XS_EXCMAX) {
471 printf("%s: too many collisions\n",
472 sc->sc_dev.dv_xname);
473 sc->sc_ethercom.ec_if.if_collisions += 16;
474 }
475 }
476
477 /*
478 * If multicast addresses were added or deleted while transmitting,
479 * mc_reset() set the want_mcsetup flag indicating that we should do
480 * it.
481 */
482 if (sc->want_mcsetup) {
483 mc_setup(sc, (caddr_t)sc->xmit_cbuffs[sc->xctail]);
484 sc->want_mcsetup = 0;
485 }
486
487 /* Done with the buffer. */
488 sc->xmit_busy--;
489 sc->xctail = (sc->xctail + 1) % NTXBUF;
490
491 /* Start the next packet, if any, transmitting. */
492 if (sc->xmit_busy > 0)
493 iexmit(sc);
494
495 iestart(ifp);
496 }
497
498 /*
499 * Compare two Ether/802 addresses for equality, inlined and unrolled for
500 * speed.
501 */
502 static __inline int
503 ether_equal(one, two)
504 u_char *one, *two;
505 {
506
507 if (one[5] != two[5] || one[4] != two[4] || one[3] != two[3] ||
508 one[2] != two[2] || one[1] != two[1] || one[0] != two[0])
509 return 0;
510 return 1;
511 }
512
513 /*
514 * Check for a valid address. to_bpf is filled in with one of the following:
515 * 0 -> BPF doesn't get this packet
516 * 1 -> BPF does get this packet
517 * 2 -> BPF does get this packet, but we don't
518 * Return value is true if the packet is for us, and false otherwise.
519 *
520 * This routine is a mess, but it's also critical that it be as fast
521 * as possible. It could be made cleaner if we can assume that the
522 * only client which will fiddle with IFF_PROMISC is BPF. This is
523 * probably a good assumption, but we do not make it here. (Yet.)
524 */
525 static __inline int
526 check_eh(sc, eh, to_bpf)
527 struct ie_softc *sc;
528 struct ether_header *eh;
529 int *to_bpf;
530 {
531 struct ifnet *ifp;
532 int i;
533
534 ifp = &sc->sc_ethercom.ec_if;
535
536 switch(sc->promisc) {
537 case IFF_ALLMULTI:
538 /*
539 * Receiving all multicasts, but no unicasts except those
540 * destined for us.
541 */
542 #if NBPFILTER > 0
543 /* BPF gets this packet if anybody cares */
544 *to_bpf = (ifp->if_bpf != 0);
545 #endif
546 if (eh->ether_dhost[0] & 1)
547 return 1;
548 if (ether_equal(eh->ether_dhost, LLADDR(ifp->if_sadl)))
549 return 1;
550 return 0;
551
552 case IFF_PROMISC:
553 /*
554 * Receiving all packets. These need to be passed on to BPF.
555 */
556 #if NBPFILTER > 0
557 *to_bpf = (ifp->if_bpf != 0);
558 #endif
559 /* If for us, accept and hand up to BPF */
560 if (ether_equal(eh->ether_dhost, LLADDR(ifp->if_sadl)))
561 return 1;
562
563 #if NBPFILTER > 0
564 if (*to_bpf)
565 *to_bpf = 2; /* we don't need to see it */
566 #endif
567
568 /*
569 * Not a multicast, so BPF wants to see it but we don't.
570 */
571 if ((eh->ether_dhost[0] & 1) == 0)
572 return 1;
573
574 /*
575 * If it's one of our multicast groups, accept it and pass it
576 * up.
577 */
578 for (i = 0; i < sc->mcast_count; i++) {
579 if (ether_equal(eh->ether_dhost,
580 (u_char *)&sc->mcast_addrs[i])) {
581 #if NBPFILTER > 0
582 if (*to_bpf)
583 *to_bpf = 1;
584 #endif
585 return 1;
586 }
587 }
588 return 1;
589
590 case IFF_ALLMULTI | IFF_PROMISC:
591 /*
592 * Acting as a multicast router, and BPF running at the same
593 * time. Whew! (Hope this is a fast machine...)
594 */
595 #if NBPFILTER > 0
596 *to_bpf = (ifp->if_bpf != 0);
597 #endif
598 /* We want to see multicasts. */
599 if (eh->ether_dhost[0] & 1)
600 return 1;
601
602 /* We want to see our own packets */
603 if (ether_equal(eh->ether_dhost, LLADDR(ifp->if_sadl)))
604 return 1;
605
606 /* Anything else goes to BPF but nothing else. */
607 #if NBPFILTER > 0
608 if (*to_bpf)
609 *to_bpf = 2;
610 #endif
611 return 1;
612
613 default:
614 /*
615 * Only accept unicast packets destined for us, or multicasts
616 * for groups that we belong to. For now, we assume that the
617 * '586 will only return packets that we asked it for. This
618 * isn't strictly true (it uses hashing for the multicast
619 * filter), but it will do in this case, and we want to get
620 * out of here as quickly as possible.
621 */
622 #if NBPFILTER > 0
623 *to_bpf = (ifp->if_bpf != 0);
624 #endif
625 return 1;
626 }
627 return 0;
628 }
629
630 /*
631 * We want to isolate the bits that have meaning... This assumes that
632 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds
633 * the size of the buffer, then we are screwed anyway.
634 */
635 static __inline int
636 ie_buflen(sc, head)
637 struct ie_softc *sc;
638 int head;
639 {
640
641 return (SWAP(sc->rbuffs[head]->ie_rbd_actual)
642 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
643 }
644
645
646 static __inline int
647 ie_packet_len(sc)
648 struct ie_softc *sc;
649 {
650 int i;
651 int head = sc->rbhead;
652 int acc = 0;
653 int oldhead = head;
654
655 do {
656 bus_space_barrier(sc->bt, sc->bh, 0, 0, BUS_SPACE_BARRIER_READ);
657 i = SWAP(sc->rbuffs[head]->ie_rbd_actual);
658 if ((i & IE_RBD_USED) == 0) {
659 #ifdef IEDEBUG
660 print_rbd(sc->rbuffs[head]);
661 #endif
662 log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
663 sc->sc_dev.dv_xname, sc->rbhead);
664 iereset(sc);
665 return -1;
666 }
667
668 i = (i & IE_RBD_LAST) != 0;
669
670 acc += ie_buflen(sc, head);
671 head = (head + 1) % sc->nrxbuf;
672 if (oldhead == head) {
673 printf("ie: packet len: looping: acc = %d (head=%d)\n",
674 acc, head);
675 iereset(sc);
676 return -1;
677 }
678 } while (!i);
679
680 return acc;
681 }
682
683 /*
684 * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
685 * command to the chip to be executed.
686 */
687 static __inline void
688 iexmit(sc)
689 struct ie_softc *sc;
690 {
691 int cur, prev;
692
693 cur = sc->xctail;
694
695 #ifdef IEDEBUG
696 if (sc->sc_debug & IED_XMIT)
697 printf("%s: xmit buffer %d\n", sc->sc_dev.dv_xname, cur);
698 #endif
699
700 sc->xmit_buffs[cur]->ie_xmit_flags |= SWAP(IE_XMIT_LAST);
701 sc->xmit_buffs[cur]->ie_xmit_next = SWAP(0xffff);
702 ST_24(sc->xmit_buffs[cur]->ie_xmit_buf,
703 MK_24(sc->sc_iobase, sc->xmit_cbuffs[cur]));
704
705 sc->xmit_cmds[cur]->ie_xmit_desc =
706 MK_16(sc->sc_maddr, sc->xmit_buffs[cur]);
707
708 sc->xmit_cmds[cur]->ie_xmit_status = SWAP(0);
709
710 if (i82586_xmitnopchain) {
711 /* Gate this XMIT to following NOP */
712 sc->xmit_cmds[cur]->com.ie_cmd_link =
713 MK_16(sc->sc_maddr, sc->nop_cmds[cur]);
714 sc->xmit_cmds[cur]->com.ie_cmd_cmd =
715 SWAP(IE_CMD_XMIT | IE_CMD_INTR);
716
717 /* Loopback at following NOP */
718 sc->nop_cmds[cur]->ie_cmd_status = SWAP(0);
719 sc->nop_cmds[cur]->ie_cmd_link =
720 MK_16(sc->sc_maddr, sc->nop_cmds[cur]);
721
722 /* Gate preceding NOP to this XMIT command */
723 prev = (cur + NTXBUF - 1) % NTXBUF;
724 sc->nop_cmds[prev]->ie_cmd_status = SWAP(0);
725 sc->nop_cmds[prev]->ie_cmd_link =
726 MK_16(sc->sc_maddr, sc->xmit_cmds[cur]);
727 bus_space_barrier(sc->bt, sc->bh, 0, 0, BUS_SPACE_BARRIER_WRITE);
728 if ((SWAP(sc->scb->ie_status) & IE_CU_ACTIVE) == 0) {
729 printf("iexmit: CU not active\n");
730 i82586_start_transceiver(sc);
731 }
732 } else {
733 sc->xmit_cmds[cur]->com.ie_cmd_link = SWAP(0xffff);
734 sc->xmit_cmds[cur]->com.ie_cmd_cmd =
735 SWAP(IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST);
736
737 sc->scb->ie_command_list =
738 MK_16(sc->sc_maddr, sc->xmit_cmds[cur]);
739
740 bus_space_barrier(sc->bt, sc->bh, 0, 0, BUS_SPACE_BARRIER_WRITE);
741 if (command_and_wait(sc, IE_CU_START, 0, 0))
742 printf("%s: iexmit: start xmit command timed out\n",
743 sc->sc_dev.dv_xname);
744 }
745
746 sc->sc_ethercom.ec_if.if_timer = 5;
747 }
748
749 /*
750 * Read data off the interface, and turn it into an mbuf chain.
751 *
752 * This code is DRAMATICALLY different from the previous version; this
753 * version tries to allocate the entire mbuf chain up front, given the
754 * length of the data available. This enables us to allocate mbuf
755 * clusters in many situations where before we would have had a long
756 * chain of partially-full mbufs. This should help to speed up the
757 * operation considerably. (Provided that it works, of course.)
758 */
759 struct mbuf *
760 ieget(sc, ehp, to_bpf)
761 struct ie_softc *sc;
762 struct ether_header *ehp;
763 int *to_bpf;
764 {
765 struct mbuf *top, **mp, *m;
766 int len, totlen, resid;
767 int thisrboff, thismboff;
768 int head;
769
770 totlen = ie_packet_len(sc);
771 if (totlen <= 0)
772 return 0;
773
774 head = sc->rbhead;
775
776 /*
777 * Snarf the Ethernet header.
778 */
779 (sc->memcopy)((caddr_t)sc->cbuffs[head], (caddr_t)ehp, sizeof *ehp);
780
781 /*
782 * As quickly as possible, check if this packet is for us.
783 * If not, don't waste a single cycle copying the rest of the
784 * packet in.
785 * This is only a consideration when FILTER is defined; i.e., when
786 * we are either running BPF or doing multicasting.
787 */
788 if (!check_eh(sc, ehp, to_bpf)) {
789 /* just this case, it's not an error */
790 sc->sc_ethercom.ec_if.if_ierrors--;
791 return 0;
792 }
793
794 resid = totlen -= (thisrboff = sizeof *ehp);
795
796 MGETHDR(m, M_DONTWAIT, MT_DATA);
797 if (m == 0)
798 return 0;
799 m->m_pkthdr.rcvif = &sc->sc_ethercom.ec_if;
800 m->m_pkthdr.len = totlen;
801 len = MHLEN;
802 top = 0;
803 mp = ⊤
804
805 /*
806 * This loop goes through and allocates mbufs for all the data we will
807 * be copying in. It does not actually do the copying yet.
808 */
809 while (totlen > 0) {
810 if (top) {
811 MGET(m, M_DONTWAIT, MT_DATA);
812 if (m == 0) {
813 m_freem(top);
814 return 0;
815 }
816 len = MLEN;
817 }
818 if (totlen >= MINCLSIZE) {
819 MCLGET(m, M_DONTWAIT);
820 if ((m->m_flags & M_EXT) == 0) {
821 m_freem(top);
822 return 0;
823 }
824 len = MCLBYTES;
825 }
826 m->m_len = len = min(totlen, len);
827 totlen -= len;
828 *mp = m;
829 mp = &m->m_next;
830 }
831
832 m = top;
833 thismboff = 0;
834
835 /*
836 * Now we take the mbuf chain (hopefully only one mbuf most of the
837 * time) and stuff the data into it. There are no possible failures at
838 * or after this point.
839 */
840 while (resid > 0) {
841 int thisrblen = ie_buflen(sc, head) - thisrboff,
842 thismblen = m->m_len - thismboff;
843 len = min(thisrblen, thismblen);
844
845 (sc->memcopy)((caddr_t)(sc->cbuffs[head] + thisrboff),
846 mtod(m, caddr_t) + thismboff, (u_int)len);
847 resid -= len;
848
849 if (len == thismblen) {
850 m = m->m_next;
851 thismboff = 0;
852 } else
853 thismboff += len;
854
855 if (len == thisrblen) {
856 head = (head + 1) % sc->nrxbuf;
857 thisrboff = 0;
858 } else
859 thisrboff += len;
860 }
861
862 /*
863 * Unless something changed strangely while we were doing the copy, we
864 * have now copied everything in from the shared memory.
865 * This means that we are done.
866 */
867 return top;
868 }
869
870 /*
871 * Read frame NUM from unit UNIT (pre-cached as IE).
872 *
873 * This routine reads the RFD at NUM, and copies in the buffers from the list
874 * of RBD, then rotates the RBD and RFD lists so that the receiver doesn't
875 * start complaining. Trailers are DROPPED---there's no point in wasting time
876 * on confusing code to deal with them. Hopefully, this machine will never ARP
877 * for trailers anyway.
878 */
879 static void
880 ie_readframe(sc, num)
881 struct ie_softc *sc;
882 int num; /* frame number to read */
883 {
884 int status;
885 struct mbuf *m = 0;
886 struct ether_header eh;
887 #if NBPFILTER > 0
888 int bpf_gets_it = 0;
889 #endif
890
891 status = SWAP(sc->rframes[num]->ie_fd_status);
892
893 /* Immediately advance the RFD list, since we have copied ours now. */
894 sc->rframes[num]->ie_fd_status = SWAP(0);
895 sc->rframes[num]->ie_fd_last |= SWAP(IE_FD_LAST);
896 sc->rframes[sc->rftail]->ie_fd_last &= ~SWAP(IE_FD_LAST);
897 sc->rftail = (sc->rftail + 1) % sc->nframes;
898 sc->rfhead = (sc->rfhead + 1) % sc->nframes;
899
900 if (status & IE_FD_OK) {
901 #if NBPFILTER > 0
902 m = ieget(sc, &eh, &bpf_gets_it);
903 #else
904 m = ieget(sc, &eh, 0);
905 #endif
906 ie_drop_packet_buffer(sc);
907 }
908 if (m == 0) {
909 sc->sc_ethercom.ec_if.if_ierrors++;
910 return;
911 }
912
913 #ifdef IEDEBUG
914 if (sc->sc_debug & IED_READFRAME)
915 printf("%s: frame from ether %s type 0x%x\n",
916 sc->sc_dev.dv_xname,
917 ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
918 #endif
919
920 #if NBPFILTER > 0
921 /*
922 * Check for a BPF filter; if so, hand it up.
923 * Note that we have to stick an extra mbuf up front, because bpf_mtap
924 * expects to have the ether header at the front.
925 * It doesn't matter that this results in an ill-formatted mbuf chain,
926 * since BPF just looks at the data. (It doesn't try to free the mbuf,
927 * tho' it will make a copy for tcpdump.)
928 */
929 if (bpf_gets_it) {
930 struct mbuf m0;
931 m0.m_len = sizeof eh;
932 m0.m_data = (caddr_t)&eh;
933 m0.m_next = m;
934
935 /* Pass it up. */
936 bpf_mtap(sc->sc_ethercom.ec_if.if_bpf, &m0);
937
938 /*
939 * A signal passed up from the filtering code indicating that
940 * the packet is intended for BPF but not for the protocol
941 * machinery. We can save a few cycles by not handing it off
942 * to them.
943 */
944 if (bpf_gets_it == 2) {
945 m_freem(m);
946 return;
947 }
948 }
949 #endif /* NBPFILTER > 0 */
950
951 /*
952 * In here there used to be code to check destination addresses upon
953 * receipt of a packet. We have deleted that code, and replaced it
954 * with code to check the address much earlier in the cycle, before
955 * copying the data in; this saves us valuable cycles when operating
956 * as a multicast router or when using BPF.
957 */
958
959 /*
960 * Finally pass this packet up to higher layers.
961 */
962 ether_input(&sc->sc_ethercom.ec_if, &eh, m);
963 sc->sc_ethercom.ec_if.if_ipackets++;
964 }
965
966 static void
967 ie_drop_packet_buffer(sc)
968 struct ie_softc *sc;
969 {
970 int i;
971
972 do {
973 bus_space_barrier(sc->bt, sc->bh, 0, 0, BUS_SPACE_BARRIER_READ);
974 i = SWAP(sc->rbuffs[sc->rbhead]->ie_rbd_actual);
975 if ((i & IE_RBD_USED) == 0) {
976 /*
977 * This means we are somehow out of sync. So, we
978 * reset the adapter.
979 */
980 #ifdef IEDEBUG
981 print_rbd(sc->rbuffs[sc->rbhead]);
982 #endif
983 log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
984 sc->sc_dev.dv_xname, sc->rbhead);
985 iereset(sc);
986 return;
987 }
988
989 i = (i & IE_RBD_LAST) != 0;
990
991 sc->rbuffs[sc->rbhead]->ie_rbd_length |= SWAP(IE_RBD_LAST);
992 sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0);
993 sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf;
994 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~SWAP(IE_RBD_LAST);
995 sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
996 } while (!i);
997 }
998
999
1000 /*
1001 * Start transmission on an interface.
1002 */
1003 void
1004 iestart(ifp)
1005 struct ifnet *ifp;
1006 {
1007 struct ie_softc *sc = ifp->if_softc;
1008 struct mbuf *m0, *m;
1009 u_char *buffer;
1010 u_short len;
1011 int s;
1012
1013 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1014 return;
1015
1016 for (;;) {
1017 if (sc->xmit_busy == NTXBUF) {
1018 ifp->if_flags |= IFF_OACTIVE;
1019 break;
1020 }
1021
1022 IF_DEQUEUE(&ifp->if_snd, m0);
1023 if (m0 == 0)
1024 break;
1025
1026 /* We need to use m->m_pkthdr.len, so require the header */
1027 if ((m0->m_flags & M_PKTHDR) == 0)
1028 panic("iestart: no header mbuf");
1029
1030 #if NBPFILTER > 0
1031 /* Tap off here if there is a BPF listener. */
1032 if (ifp->if_bpf)
1033 bpf_mtap(ifp->if_bpf, m0);
1034 #endif
1035
1036 #ifdef IEDEBUG
1037 if (sc->sc_debug & IED_ENQ)
1038 printf("%s: fill buffer %d\n", sc->sc_dev.dv_xname,
1039 sc->xchead);
1040 #endif
1041
1042 if (m0->m_pkthdr.len > IE_TBUF_SIZE)
1043 printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname);
1044
1045 buffer = sc->xmit_cbuffs[sc->xchead];
1046 for (m = m0; m != 0; m = m->m_next) {
1047 (sc->memcopy)(mtod(m, caddr_t), buffer, m->m_len);
1048 buffer += m->m_len;
1049 }
1050
1051 len = max(m0->m_pkthdr.len, ETHER_MIN_LEN);
1052 m_freem(m0);
1053
1054 sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len);
1055
1056 sc->xchead = (sc->xchead + 1) % NTXBUF;
1057
1058 s = splnet();
1059 /* Start the first packet transmitting. */
1060 if (sc->xmit_busy == 0)
1061 iexmit(sc);
1062
1063 sc->xmit_busy++;
1064 splx(s);
1065 }
1066 }
1067
1068 /*
1069 * set up IE's ram space
1070 */
1071 int
1072 ie_setupram(sc)
1073 struct ie_softc *sc;
1074 {
1075 volatile struct ie_sys_conf_ptr *scp;
1076 volatile struct ie_int_sys_conf_ptr *iscp;
1077 volatile struct ie_sys_ctl_block *scb;
1078 int s;
1079
1080 s = splnet();
1081
1082 scp = sc->scp;
1083 (sc->memzero)((char *) scp, sizeof *scp);
1084
1085 iscp = sc->iscp;
1086 (sc->memzero)((char *) iscp, sizeof *iscp);
1087
1088 scb = sc->scb;
1089 (sc->memzero)((char *) scb, sizeof *scb);
1090
1091 scp->ie_bus_use = 0; /* 16-bit */
1092 ST_24(scp->ie_iscp_ptr, MK_24(sc->sc_iobase, iscp));
1093
1094 iscp->ie_busy = 1; /* ie_busy == char */
1095 iscp->ie_scb_offset = MK_16(sc->sc_maddr, scb);
1096 ST_24(iscp->ie_base, MK_24(sc->sc_iobase, sc->sc_maddr));
1097
1098 if (sc->hwreset)
1099 (sc->hwreset)(sc);
1100
1101 (sc->chan_attn) (sc);
1102
1103 delay(100); /* wait a while... */
1104
1105 if (iscp->ie_busy) {
1106 splx(s);
1107 return 0;
1108 }
1109 /*
1110 * Acknowledge any interrupts we may have caused...
1111 */
1112 ie_ack(sc, IE_ST_WHENCE);
1113 splx(s);
1114
1115 return 1;
1116 }
1117
1118 void
1119 iereset(sc)
1120 struct ie_softc *sc;
1121 {
1122 int s = splnet();
1123
1124 printf("%s: reset\n", sc->sc_dev.dv_xname);
1125
1126 /* Clear OACTIVE in case we're called from watchdog (frozen xmit). */
1127 sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
1128
1129 /*
1130 * Stop i82586 dead in its tracks.
1131 */
1132 if (command_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1133 printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
1134
1135 if (command_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1136 printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname);
1137
1138 if (sc->hwreset)
1139 (sc->hwreset)(sc);
1140
1141 ie_ack(sc, IE_ST_WHENCE);
1142
1143 #ifdef notdef
1144 if (!check_ie_present(sc, sc->sc_maddr, sc->sc_msize))
1145 panic("ie disappeared!\n");
1146 #endif
1147
1148 if ((sc->sc_ethercom.ec_if.if_flags & IFF_UP) != 0)
1149 ieinit(sc);
1150
1151 splx(s);
1152 }
1153
1154 /*
1155 * Send a command to the controller and wait for it to either complete
1156 * or be accepted, depending on the command. If the command pointer
1157 * is null, then pretend that the command is not an action command.
1158 * If the command pointer is not null, and the command is an action
1159 * command, wait for
1160 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1161 * to become true.
1162 */
1163 static int
1164 command_and_wait(sc, cmd, pcmd, mask)
1165 struct ie_softc *sc;
1166 int cmd; /* native byte-order */
1167 volatile void *pcmd;
1168 int mask; /* native byte-order */
1169 {
1170 volatile struct ie_cmd_common *cc = pcmd;
1171 volatile struct ie_sys_ctl_block *scb = sc->scb;
1172 int i;
1173
1174 scb->ie_command = (u_short)SWAP(cmd);
1175 bus_space_barrier(sc->bt, sc->bh, 0, 0, BUS_SPACE_BARRIER_WRITE);
1176 (sc->chan_attn)(sc);
1177
1178 if (IE_ACTION_COMMAND(cmd) && pcmd) {
1179 /*
1180 * According to the packet driver, the minimum timeout should
1181 * be .369 seconds, which we round up to .4.
1182 */
1183
1184 /*
1185 * Now spin-lock waiting for status. This is not a very nice
1186 * thing to do, but I haven't figured out how, or indeed if, we
1187 * can put the process waiting for action to sleep. (We may
1188 * be getting called through some other timeout running in the
1189 * kernel.)
1190 */
1191 for (i = 0; i < 369000; i++) {
1192 bus_space_barrier(sc->bt, sc->bh, 0, 0,
1193 BUS_SPACE_BARRIER_READ);
1194 if ((SWAP(cc->ie_cmd_status) & mask))
1195 return (0);
1196 delay(1);
1197 }
1198
1199 } else {
1200 /*
1201 * Otherwise, just wait for the command to be accepted.
1202 */
1203
1204 /* XXX spin lock; wait at most 0.9 seconds */
1205 for (i = 0; i < 900000; i++) {
1206 bus_space_barrier(sc->bt, sc->bh, 0, 0,
1207 BUS_SPACE_BARRIER_READ);
1208 if (scb->ie_command == 0)
1209 return (0);
1210 delay(1);
1211 }
1212 }
1213
1214 /* Timeout */
1215 return (1);
1216 }
1217
1218 /*
1219 * Run the time-domain reflectometer.
1220 */
1221 static void
1222 run_tdr(sc, cmd)
1223 struct ie_softc *sc;
1224 struct ie_tdr_cmd *cmd;
1225 {
1226 int result;
1227
1228 cmd->com.ie_cmd_status = SWAP(0);
1229 cmd->com.ie_cmd_cmd = SWAP(IE_CMD_TDR | IE_CMD_LAST);
1230 cmd->com.ie_cmd_link = SWAP(0xffff);
1231
1232 sc->scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
1233 cmd->ie_tdr_time = SWAP(0);
1234
1235 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1236 (SWAP(cmd->com.ie_cmd_status) & IE_STAT_OK) == 0)
1237 result = 0x10000; /* XXX */
1238 else
1239 result = SWAP(cmd->ie_tdr_time);
1240
1241 ie_ack(sc, IE_ST_WHENCE);
1242
1243 if (result & IE_TDR_SUCCESS)
1244 return;
1245
1246 if (result & 0x10000)
1247 printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
1248 else if (result & IE_TDR_XCVR)
1249 printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
1250 else if (result & IE_TDR_OPEN)
1251 printf("%s: TDR detected an open %d clocks away\n",
1252 sc->sc_dev.dv_xname, result & IE_TDR_TIME);
1253 else if (result & IE_TDR_SHORT)
1254 printf("%s: TDR detected a short %d clocks away\n",
1255 sc->sc_dev.dv_xname, result & IE_TDR_TIME);
1256 else
1257 printf("%s: TDR returned unknown status 0x%x\n",
1258 sc->sc_dev.dv_xname, result);
1259 }
1260
1261 #ifdef notdef
1262 /* ALIGN works on 8 byte boundaries.... but 4 byte boundaries are ok for sun */
1263 #define _ALLOC(p, n) (bzero(p, n), p += n, p - n)
1264 #define ALLOC(p, n) _ALLOC(p, ALIGN(n)) /* XXX convert to this? */
1265 #endif
1266
1267 /*
1268 * setup_bufs: set up the buffers
1269 *
1270 * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
1271 * this is to be used for the buffers. the chip indexs its control data
1272 * structures with 16 bit offsets, and it indexes actual buffers with
1273 * 24 bit addresses. so we should allocate control buffers first so that
1274 * we don't overflow the 16 bit offset field. The number of transmit
1275 * buffers is fixed at compile time.
1276 *
1277 * note: this function was written to be easy to understand, rather than
1278 * highly efficient (it isn't in the critical path).
1279 */
1280 static void
1281 setup_bufs(sc)
1282 struct ie_softc *sc;
1283 {
1284 caddr_t ptr = sc->buf_area; /* memory pool */
1285 int n, r;
1286
1287 /*
1288 * step 0: zero memory and figure out how many recv buffers and
1289 * frames we can have.
1290 */
1291 (sc->memzero)(ptr, sc->buf_area_sz);
1292 ptr = (sc->align)(ptr); /* set alignment and stick with it */
1293
1294 n = (int)(sc->align)((caddr_t) sizeof(struct ie_cmd_common)) +
1295 (int)(sc->align)((caddr_t) sizeof(struct ie_xmit_cmd)) +
1296 (int)(sc->align)((caddr_t) sizeof(struct ie_xmit_buf)) + IE_TBUF_SIZE;
1297 n *= NTXBUF; /* n = total size of xmit area */
1298
1299 n = sc->buf_area_sz - n;/* n = free space for recv stuff */
1300
1301 r = (int)(sc->align)((caddr_t) sizeof(struct ie_recv_frame_desc)) +
1302 (((int)(sc->align)((caddr_t) sizeof(struct ie_recv_buf_desc)) +
1303 IE_RBUF_SIZE) * B_PER_F);
1304
1305 /* r = size of one R frame */
1306
1307 sc->nframes = n / r;
1308 if (sc->nframes <= 0)
1309 panic("ie: bogus buffer calc\n");
1310 if (sc->nframes > MAXFRAMES)
1311 sc->nframes = MAXFRAMES;
1312
1313 sc->nrxbuf = sc->nframes * B_PER_F;
1314
1315 #ifdef IEDEBUG
1316 printf("IEDEBUG: %d frames %d bufs\n", sc->nframes, sc->nrxbuf);
1317 #endif
1318
1319 /*
1320 * step 1a: lay out and zero frame data structures for transmit and recv
1321 */
1322 for (n = 0; n < NTXBUF; n++) {
1323 sc->nop_cmds[n] = (volatile struct ie_cmd_common *) ptr;
1324 ptr = (sc->align)(ptr + sizeof(struct ie_cmd_common));
1325 }
1326 for (n = 0; n < NTXBUF; n++) {
1327 sc->xmit_cmds[n] = (volatile struct ie_xmit_cmd *) ptr;
1328 ptr = (sc->align)(ptr + sizeof(struct ie_xmit_cmd));
1329 }
1330
1331 for (n = 0; n < sc->nframes; n++) {
1332 sc->rframes[n] = (volatile struct ie_recv_frame_desc *) ptr;
1333 ptr = (sc->align)(ptr + sizeof(struct ie_recv_frame_desc));
1334 }
1335
1336 /*
1337 * step 1b: link together the recv frames and set EOL on last one
1338 */
1339 for (n = 0; n < sc->nframes; n++) {
1340 sc->rframes[n]->ie_fd_next =
1341 MK_16(sc->sc_maddr, sc->rframes[(n + 1) % sc->nframes]);
1342 }
1343 sc->rframes[sc->nframes - 1]->ie_fd_last |= SWAP(IE_FD_LAST);
1344
1345 /*
1346 * step 1c: link the xmit no-op frames to themselves
1347 */
1348 for (n = 0; n < NTXBUF; n++) {
1349 sc->nop_cmds[n]->ie_cmd_status = SWAP(0);
1350 sc->nop_cmds[n]->ie_cmd_cmd = SWAP(IE_CMD_NOP);
1351 sc->nop_cmds[n]->ie_cmd_link =
1352 MK_16(sc->sc_maddr, sc->nop_cmds[n]);
1353 }
1354
1355 /*
1356 * step 2a: lay out and zero frame buffer structures for xmit and recv
1357 */
1358 for (n = 0; n < NTXBUF; n++) {
1359 sc->xmit_buffs[n] = (volatile struct ie_xmit_buf *) ptr;
1360 ptr = (sc->align)(ptr + sizeof(struct ie_xmit_buf));
1361 }
1362
1363 for (n = 0; n < sc->nrxbuf; n++) {
1364 sc->rbuffs[n] = (volatile struct ie_recv_buf_desc *) ptr;
1365 ptr = (sc->align)(ptr + sizeof(struct ie_recv_buf_desc));
1366 }
1367
1368 /*
1369 * step 2b: link together recv bufs and set EOL on last one
1370 */
1371 for (n = 0; n < sc->nrxbuf; n++) {
1372 sc->rbuffs[n]->ie_rbd_next =
1373 MK_16(sc->sc_maddr, sc->rbuffs[(n + 1) % sc->nrxbuf]);
1374 }
1375 sc->rbuffs[sc->nrxbuf - 1]->ie_rbd_length |= SWAP(IE_RBD_LAST);
1376
1377 /*
1378 * step 3: allocate the actual data buffers for xmit and recv
1379 * recv buffer gets linked into recv_buf_desc list here
1380 */
1381 for (n = 0; n < NTXBUF; n++) {
1382 sc->xmit_cbuffs[n] = (u_char *) ptr;
1383 ptr = (sc->align)(ptr + IE_TBUF_SIZE);
1384 }
1385
1386 /* Pointers to last packet sent and next available transmit buffer. */
1387 sc->xchead = sc->xctail = 0;
1388
1389 /* Clear transmit-busy flag and set number of free transmit buffers. */
1390 sc->xmit_busy = 0;
1391
1392 for (n = 0; n < sc->nrxbuf; n++) {
1393 sc->cbuffs[n] = (char *) ptr; /* XXX why char vs uchar? */
1394 sc->rbuffs[n]->ie_rbd_length = SWAP(IE_RBUF_SIZE);
1395 ST_24(sc->rbuffs[n]->ie_rbd_buffer, MK_24(sc->sc_iobase, ptr));
1396 ptr = (sc->align)(ptr + IE_RBUF_SIZE);
1397 }
1398
1399 /*
1400 * step 4: set the head and tail pointers on receive to keep track of
1401 * the order in which RFDs and RBDs are used. link in recv frames
1402 * and buffer into the scb.
1403 */
1404
1405 sc->rfhead = 0;
1406 sc->rftail = sc->nframes - 1;
1407 sc->rbhead = 0;
1408 sc->rbtail = sc->nrxbuf - 1;
1409
1410 #ifdef IEDEBUG
1411 printf("IE_DEBUG: reserved %d bytes\n", ptr - sc->buf_area);
1412 #endif
1413 }
1414
1415 /*
1416 * Run the multicast setup command.
1417 * Called at splnet().
1418 */
1419 static int
1420 mc_setup(sc, ptr)
1421 struct ie_softc *sc;
1422 void *ptr;
1423 {
1424 volatile struct ie_mcast_cmd *cmd = ptr;
1425
1426 cmd->com.ie_cmd_status = SWAP(0);
1427 cmd->com.ie_cmd_cmd = SWAP(IE_CMD_MCAST | IE_CMD_LAST);
1428 cmd->com.ie_cmd_link = SWAP(0xffff);
1429
1430 (sc->memcopy)((caddr_t)sc->mcast_addrs, (caddr_t)cmd->ie_mcast_addrs,
1431 sc->mcast_count * sizeof *sc->mcast_addrs);
1432
1433 cmd->ie_mcast_bytes =
1434 SWAP(sc->mcast_count * ETHER_ADDR_LEN); /* grrr... */
1435
1436 sc->scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
1437 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1438 (SWAP(cmd->com.ie_cmd_status) & IE_STAT_OK) == 0) {
1439 printf("%s: multicast address setup command failed\n",
1440 sc->sc_dev.dv_xname);
1441 return 0;
1442 }
1443
1444 i82586_start_transceiver(sc);
1445 return 1;
1446 }
1447
1448 /*
1449 * This routine takes the environment generated by check_ie_present() and adds
1450 * to it all the other structures we need to operate the adapter. This
1451 * includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, starting
1452 * the receiver unit, and clearing interrupts.
1453 *
1454 * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
1455 */
1456 int
1457 ieinit(sc)
1458 struct ie_softc *sc;
1459 {
1460 volatile struct ie_sys_ctl_block *scb = sc->scb;
1461 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1462 void *ptr;
1463
1464 ptr = sc->buf_area;
1465
1466 /*
1467 * Send the configure command first.
1468 */
1469 {
1470 volatile struct ie_config_cmd *cmd = ptr;
1471
1472 scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
1473 cmd->com.ie_cmd_status = SWAP(0);
1474 cmd->com.ie_cmd_cmd = SWAP(IE_CMD_CONFIG | IE_CMD_LAST);
1475 cmd->com.ie_cmd_link = SWAP(0xffff);
1476
1477 ie_setup_config(cmd, sc->promisc, 0);
1478
1479 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1480 (SWAP(cmd->com.ie_cmd_status) & IE_STAT_OK) == 0) {
1481 printf("%s: configure command failed\n",
1482 sc->sc_dev.dv_xname);
1483 return 0;
1484 }
1485 }
1486
1487 /*
1488 * Now send the Individual Address Setup command.
1489 */
1490 {
1491 volatile struct ie_iasetup_cmd *cmd = ptr;
1492
1493 scb->ie_command_list = MK_16(sc->sc_maddr, cmd);
1494 cmd->com.ie_cmd_status = SWAP(0);
1495 cmd->com.ie_cmd_cmd = SWAP(IE_CMD_IASETUP | IE_CMD_LAST);
1496 cmd->com.ie_cmd_link = SWAP(0xffff);
1497
1498 (sc->memcopy)(LLADDR(ifp->if_sadl),
1499 (caddr_t)&cmd->ie_address, sizeof cmd->ie_address);
1500
1501 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1502 (SWAP(cmd->com.ie_cmd_status) & IE_STAT_OK) == 0) {
1503 printf("%s: individual address setup command failed\n",
1504 sc->sc_dev.dv_xname);
1505 return 0;
1506 }
1507 }
1508
1509 /*
1510 * Now run the time-domain reflectometer.
1511 */
1512 run_tdr(sc, ptr);
1513
1514 /*
1515 * Acknowledge any interrupts we have generated thus far.
1516 */
1517 ie_ack(sc, IE_ST_WHENCE);
1518
1519 /*
1520 * Set up the transmit and recv buffers.
1521 */
1522 setup_bufs(sc);
1523
1524 ie_ack(sc, IE_ST_WHENCE);
1525
1526 if (sc->hwinit)
1527 (sc->hwinit)(sc);
1528
1529 ifp->if_flags |= IFF_RUNNING;
1530 ifp->if_flags &= ~IFF_OACTIVE;
1531
1532 if (NTXBUF < 2)
1533 i82586_xmitnopchain = 0;
1534
1535 i82586_start_transceiver(sc);
1536
1537 return 0;
1538 }
1539
1540 static void
1541 i82586_start_transceiver(sc)
1542 struct ie_softc *sc;
1543 {
1544 sc->rframes[0]->ie_fd_buf_desc = MK_16(sc->sc_maddr, sc->rbuffs[0]);
1545 sc->scb->ie_recv_list = MK_16(sc->sc_maddr, sc->rframes[0]);
1546
1547 if (i82586_xmitnopchain) {
1548 /* Stop transmit command chain */
1549 if (command_and_wait(sc, IE_CU_STOP|IE_RU_DISABLE, 0, 0))
1550 printf("%s: CU/RU stop command timed out\n",
1551 sc->sc_dev.dv_xname);
1552
1553 /* Start the receiver & transmitter chain */
1554 sc->scb->ie_command_list =
1555 MK_16(sc->sc_maddr,
1556 sc->nop_cmds[(sc->xctail + NTXBUF - 1) % NTXBUF]);
1557 if (command_and_wait(sc, IE_CU_START|IE_RU_START, 0, 0))
1558 printf("%s: CU/RU command timed out\n",
1559 sc->sc_dev.dv_xname);
1560 } else {
1561 if (command_and_wait(sc, IE_RU_START, 0, 0))
1562 printf("%s: RU command timed out\n",
1563 sc->sc_dev.dv_xname);
1564 }
1565 }
1566
1567 static void
1568 iestop(sc)
1569 struct ie_softc *sc;
1570 {
1571
1572 if (command_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1573 printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname);
1574 }
1575
1576 int
1577 ieioctl(ifp, cmd, data)
1578 register struct ifnet *ifp;
1579 u_long cmd;
1580 caddr_t data;
1581 {
1582 struct ie_softc *sc = ifp->if_softc;
1583 struct ifaddr *ifa = (struct ifaddr *)data;
1584 struct ifreq *ifr = (struct ifreq *)data;
1585 int s, error = 0;
1586
1587 s = splnet();
1588
1589 switch(cmd) {
1590
1591 case SIOCSIFADDR:
1592 ifp->if_flags |= IFF_UP;
1593
1594 switch(ifa->ifa_addr->sa_family) {
1595 #ifdef INET
1596 case AF_INET:
1597 ieinit(sc);
1598 arp_ifinit(ifp, ifa);
1599 break;
1600 #endif
1601 #ifdef NS
1602 /* XXX - This code is probably wrong. */
1603 case AF_NS:
1604 {
1605 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1606
1607 if (ns_nullhost(*ina))
1608 ina->x_host =
1609 *(union ns_host *)LLADDR(ifp->if_sadl);
1610 else
1611 bcopy(ina->x_host.c_host,
1612 LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
1613 /* Set new address. */
1614 ieinit(sc);
1615 break;
1616 }
1617 #endif /* NS */
1618 default:
1619 ieinit(sc);
1620 break;
1621 }
1622 break;
1623
1624 case SIOCSIFFLAGS:
1625 sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
1626 if ((ifp->if_flags & IFF_UP) == 0 &&
1627 (ifp->if_flags & IFF_RUNNING) != 0) {
1628 /*
1629 * If interface is marked down and it is running, then
1630 * stop it.
1631 */
1632 iestop(sc);
1633 ifp->if_flags &= ~IFF_RUNNING;
1634 } else if ((ifp->if_flags & IFF_UP) != 0 &&
1635 (ifp->if_flags & IFF_RUNNING) == 0) {
1636 /*
1637 * If interface is marked up and it is stopped, then
1638 * start it.
1639 */
1640 ieinit(sc);
1641 } else {
1642 /*
1643 * Reset the interface to pick up changes in any other
1644 * flags that affect hardware registers.
1645 */
1646 iestop(sc);
1647 ieinit(sc);
1648 }
1649 #ifdef IEDEBUG
1650 if (ifp->if_flags & IFF_DEBUG)
1651 sc->sc_debug = IED_ALL;
1652 else
1653 sc->sc_debug = 0;
1654 #endif
1655 break;
1656
1657 case SIOCADDMULTI:
1658 case SIOCDELMULTI:
1659 error = (cmd == SIOCADDMULTI) ?
1660 ether_addmulti(ifr, &sc->sc_ethercom):
1661 ether_delmulti(ifr, &sc->sc_ethercom);
1662
1663 if (error == ENETRESET) {
1664 /*
1665 * Multicast list has changed; set the hardware filter
1666 * accordingly.
1667 */
1668 mc_reset(sc);
1669 error = 0;
1670 }
1671 break;
1672
1673 default:
1674 error = EINVAL;
1675 }
1676 splx(s);
1677 return error;
1678 }
1679
1680 static void
1681 mc_reset(sc)
1682 struct ie_softc *sc;
1683 {
1684 struct ether_multi *enm;
1685 struct ether_multistep step;
1686
1687 /*
1688 * Step through the list of addresses.
1689 */
1690 sc->mcast_count = 0;
1691 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1692 while (enm) {
1693 if (sc->mcast_count >= MAXMCAST ||
1694 bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
1695 sc->sc_ethercom.ec_if.if_flags |= IFF_ALLMULTI;
1696 ieioctl(&sc->sc_ethercom.ec_if, SIOCSIFFLAGS, (void *)0);
1697 goto setflag;
1698 }
1699
1700 bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
1701 sc->mcast_count++;
1702 ETHER_NEXT_MULTI(step, enm);
1703 }
1704 setflag:
1705 sc->want_mcsetup = 1;
1706 }
1707
1708 #ifdef IEDEBUG
1709 void
1710 print_rbd(rbd)
1711 volatile struct ie_recv_buf_desc *rbd;
1712 {
1713 u_long bufval;
1714
1715 bcopy((char *)&rbd->ie_rbd_buffer, &bufval, 4); /*XXX*/
1716
1717 printf("RBD at %08lx:\nactual %04x, next %04x, buffer %lx\n"
1718 "length %04x, mbz %04x\n", (u_long)rbd,
1719 SWAP(rbd->ie_rbd_actual),
1720 SWAP(rbd->ie_rbd_next),
1721 bufval,
1722 SWAP(rbd->ie_rbd_length),
1723 rbd->mbz);
1724 }
1725 #endif
1726