if_ie.c revision 1.61 1 /* $NetBSD: if_ie.c,v 1.61 2016/12/15 09:28:04 ozaki-r Exp $ */
2
3 /*-
4 * Copyright (c) 1993, 1994, 1995 Charles M. Hannum.
5 * Copyright (c) 1992, 1993, University of Vermont and State
6 * Agricultural College.
7 * Copyright (c) 1992, 1993, Garrett A. Wollman.
8 *
9 * Portions:
10 * Copyright (c) 1994, 1995, Rafal K. Boni
11 * Copyright (c) 1990, 1991, William F. Jolitz
12 * Copyright (c) 1990, The Regents of the University of California
13 *
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. All advertising materials mentioning features or use of this software
25 * must display the following acknowledgement:
26 * This product includes software developed by Charles M. Hannum, by the
27 * University of Vermont and State Agricultural College and Garrett A.
28 * Wollman, by William F. Jolitz, and by the University of California,
29 * Berkeley, Lawrence Berkeley Laboratory, and its contributors.
30 * 4. Neither the names of the Universities nor the names of the authors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 */
46
47 /*
48 * Intel 82586 Ethernet chip
49 * Register, bit, and structure definitions.
50 *
51 * Original StarLAN driver written by Garrett Wollman with reference to the
52 * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
53 *
54 * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
55 *
56 * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
57 *
58 * Majorly cleaned up and 3C507 code merged by Charles Hannum.
59 *
60 * Converted to SUN ie driver by Charles D. Cranor,
61 * October 1994, January 1995.
62 * This sun version based on i386 version 1.30.
63 * [ see sys/dev/isa/if_ie.c ]
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
100 #include <sys/cdefs.h>
101 __KERNEL_RCSID(0, "$NetBSD: if_ie.c,v 1.61 2016/12/15 09:28:04 ozaki-r Exp $");
102
103 #include "opt_inet.h"
104 #include "opt_ns.h"
105
106 #include <sys/param.h>
107 #include <sys/systm.h>
108 #include <sys/mbuf.h>
109 #include <sys/buf.h>
110 #include <sys/protosw.h>
111 #include <sys/socket.h>
112 #include <sys/ioctl.h>
113 #include <sys/errno.h>
114 #include <sys/syslog.h>
115 #include <sys/device.h>
116
117 #include <net/if.h>
118 #include <net/if_types.h>
119 #include <net/if_dl.h>
120 #include <net/if_ether.h>
121
122 #include <net/bpf.h>
123 #include <net/bpfdesc.h>
124
125 #ifdef INET
126 #include <netinet/in.h>
127 #include <netinet/in_systm.h>
128 #include <netinet/in_var.h>
129 #include <netinet/ip.h>
130 #include <netinet/if_inarp.h>
131 #endif
132
133 #include <uvm/uvm_extern.h>
134
135 #include <machine/autoconf.h>
136 #include <machine/cpu.h>
137 #include <machine/pmap.h>
138
139 /*
140 * ugly byte-order hack for SUNs
141 */
142
143 #define XSWAP(y) ( (((y) & 0xff00) >> 8) | (((y) & 0xff) << 8) )
144 #define SWAP(x) ((u_short)(XSWAP((u_short)(x))))
145
146 #include "i82586.h"
147 #include "if_iereg.h"
148 #include "if_ievar.h"
149
150 /* #define IEDEBUG XXX */
151
152 /*
153 * IED: ie debug flags
154 */
155
156 #define IED_RINT 0x01
157 #define IED_TINT 0x02
158 #define IED_RNR 0x04
159 #define IED_CNA 0x08
160 #define IED_READFRAME 0x10
161 #define IED_ENQ 0x20
162 #define IED_XMIT 0x40
163 #define IED_ALL 0x7f
164
165 #ifdef IEDEBUG
166 #define inline /* not */
167 void print_rbd(volatile struct ie_recv_buf_desc *);
168 int in_ierint = 0;
169 int in_ietint = 0;
170 int ie_debug_flags = 0;
171 #endif
172
173 /* XXX - Skip TDR for now - it always complains... */
174 int ie_run_tdr = 0;
175
176 static void iewatchdog(struct ifnet *);
177 static int ieinit(struct ie_softc *);
178 static int ieioctl(struct ifnet *, u_long, void *);
179 static void iestart(struct ifnet *);
180 static void iereset(struct ie_softc *);
181 static int ie_setupram(struct ie_softc *);
182
183 static int cmd_and_wait(struct ie_softc *, int, void *, int);
184
185 static void ie_drop_packet_buffer(struct ie_softc *);
186 static void ie_readframe(struct ie_softc *, int);
187 static inline void ie_setup_config(struct ie_config_cmd *, int, int);
188
189 static void ierint(struct ie_softc *);
190 static void iestop(struct ie_softc *);
191 static void ietint(struct ie_softc *);
192 static void iexmit(struct ie_softc *);
193
194 static int mc_setup(struct ie_softc *, void *);
195 static void mc_reset(struct ie_softc *);
196 static void run_tdr(struct ie_softc *, struct ie_tdr_cmd *);
197 static void iememinit(struct ie_softc *);
198
199 static inline uint8_t *Align(char *);
200 static inline u_int Swap32(u_int);
201 static inline u_int vtop24(struct ie_softc *, void *);
202 static inline uint16_t vtop16sw(struct ie_softc *, void *);
203
204 static inline void ie_ack(struct ie_softc *, u_int);
205 static inline u_short ether_cmp(u_char *, uint8_t *);
206 static inline int ie_buflen(struct ie_softc *, int);
207 static inline int ie_packet_len(struct ie_softc *);
208 static inline struct mbuf * ieget(struct ie_softc *);
209
210
211 /*
212 * Here are a few useful functions. We could have done these as macros,
213 * but since we have the inline facility, it makes sense to use that
214 * instead.
215 */
216
217 /* KVA to 24 bit device address */
218 static inline u_int
219 vtop24(struct ie_softc *sc, void *ptr)
220 {
221 u_int pa;
222
223 pa = (vaddr_t)ptr - (vaddr_t)sc->sc_iobase;
224 #ifdef IEDEBUG
225 if (pa & ~0xffFFff)
226 panic("ie:vtop24");
227 #endif
228 return pa;
229 }
230
231 /* KVA to 16 bit offset, swapped */
232 static inline u_short
233 vtop16sw(struct ie_softc *sc, void *ptr)
234 {
235 u_int pa;
236
237 pa = (vaddr_t)ptr - (vaddr_t)sc->sc_maddr;
238 #ifdef IEDEBUG
239 if (pa & ~0xFFff)
240 panic("ie:vtop16");
241 #endif
242
243 return SWAP(pa);
244 }
245
246 static inline u_int
247 Swap32(u_int x)
248 {
249 u_int y;
250
251 y = x & 0xFF;
252 y <<= 8; x >>= 8;
253 y |= x & 0xFF;
254 y <<= 8; x >>= 8;
255 y |= x & 0xFF;
256 y <<= 8; x >>= 8;
257 y |= x & 0xFF;
258
259 return y;
260 }
261
262 static inline uint8_t *
263 Align(char *ptr)
264 {
265 u_long l = (u_long)ptr;
266
267 l = (l + 3) & ~3L;
268 return (uint8_t *)l;
269 }
270
271
272 static inline void
273 ie_ack(struct ie_softc *sc, u_int mask)
274 {
275 volatile struct ie_sys_ctl_block *scb = sc->scb;
276
277 cmd_and_wait(sc, scb->ie_status & mask, 0, 0);
278 }
279
280
281 /*
282 * Taken almost exactly from Bill's if_is.c,
283 * then modified beyond recognition...
284 */
285 void
286 ie_attach(struct ie_softc *sc)
287 {
288 struct ifnet *ifp = &sc->sc_if;
289
290 /* MD code has done its part before calling this. */
291 printf(": macaddr %s\n", ether_sprintf(sc->sc_addr));
292
293 /*
294 * Compute number of transmit and receive buffers.
295 * Tx buffers take 1536 bytes, and fixed in number.
296 * Rx buffers are 512 bytes each, variable number.
297 * Need at least 1 frame for each 3 rx buffers.
298 * The ratio 3bufs:2frames is a compromise.
299 */
300 sc->ntxbuf = NTXBUF; /* XXX - Fix me... */
301 switch (sc->sc_msize) {
302 case 16384:
303 sc->nframes = 8 * 4;
304 sc->nrxbuf = 8 * 6;
305 break;
306 case 32768:
307 sc->nframes = 16 * 4;
308 sc->nrxbuf = 16 * 6;
309 break;
310 case 65536:
311 sc->nframes = 32 * 4;
312 sc->nrxbuf = 32 * 6;
313 break;
314 default:
315 sc->nframes = 0;
316 }
317 if (sc->nframes > MXFRAMES)
318 sc->nframes = MXFRAMES;
319 if (sc->nrxbuf > MXRXBUF)
320 sc->nrxbuf = MXRXBUF;
321
322 #ifdef IEDEBUG
323 aprint_debug_dev(sc->sc_dev,
324 "%dK memory, %d tx frames, %d rx frames, %d rx bufs\n",
325 (sc->sc_msize >> 10), sc->ntxbuf, sc->nframes, sc->nrxbuf);
326 #endif
327
328 if ((sc->nframes <= 0) || (sc->nrxbuf <= 0))
329 panic("%s: weird memory size", __func__);
330
331 /*
332 * Setup RAM for transmit/receive
333 */
334 if (ie_setupram(sc) == 0) {
335 aprint_error(": RAM CONFIG FAILED!\n");
336 /* XXX should reclaim resources? */
337 return;
338 }
339
340 /*
341 * Initialize and attach S/W interface
342 */
343 strcpy(ifp->if_xname, device_xname(sc->sc_dev));
344 ifp->if_softc = sc;
345 ifp->if_start = iestart;
346 ifp->if_ioctl = ieioctl;
347 ifp->if_watchdog = iewatchdog;
348 ifp->if_flags =
349 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
350
351 /* Attach the interface. */
352 if_attach(ifp);
353 ether_ifattach(ifp, sc->sc_addr);
354 }
355
356 /*
357 * Setup IE's ram space.
358 */
359 static int
360 ie_setupram(struct ie_softc *sc)
361 {
362 volatile struct ie_sys_conf_ptr *scp;
363 volatile struct ie_int_sys_conf_ptr *iscp;
364 volatile struct ie_sys_ctl_block *scb;
365 int off;
366
367 /*
368 * Allocate from end of buffer space for
369 * ISCP, SCB, and other small stuff.
370 */
371 off = sc->buf_area_sz;
372 off &= ~3;
373
374 /* SCP (address already chosen). */
375 scp = sc->scp;
376 (sc->sc_memset)(__UNVOLATILE(scp), 0, sizeof(*scp));
377
378 /* ISCP */
379 off -= sizeof(*iscp);
380 iscp = (volatile void *)(sc->buf_area + off);
381 (sc->sc_memset)(__UNVOLATILE(iscp), 0, sizeof(*iscp));
382 sc->iscp = iscp;
383
384 /* SCB */
385 off -= sizeof(*scb);
386 scb = (volatile void *)(sc->buf_area + off);
387 (sc->sc_memset)(__UNVOLATILE(scb), 0, sizeof(*scb));
388 sc->scb = scb;
389
390 /* Remainder is for buffers, etc. */
391 sc->buf_area_sz = off;
392
393 /*
394 * Now fill in the structures we just allocated.
395 */
396
397 /* SCP: main thing is 24-bit ptr to ISCP */
398 scp->ie_bus_use = 0; /* 16-bit */
399 scp->ie_iscp_ptr = Swap32(vtop24(sc, __UNVOLATILE(iscp)));
400
401 /* ISCP */
402 iscp->ie_busy = 1; /* ie_busy == char */
403 iscp->ie_scb_offset = vtop16sw(sc, __UNVOLATILE(scb));
404 iscp->ie_base = Swap32(vtop24(sc, sc->sc_maddr));
405
406 /* SCB */
407 scb->ie_command_list = SWAP(0xffff);
408 scb->ie_recv_list = SWAP(0xffff);
409
410 /* Other stuff is done in ieinit() */
411 (sc->reset_586)(sc);
412 (sc->chan_attn)(sc);
413
414 delay(100); /* wait a while... */
415
416 if (iscp->ie_busy) {
417 return 0;
418 }
419 /*
420 * Acknowledge any interrupts we may have caused...
421 */
422 ie_ack(sc, IE_ST_WHENCE);
423
424 return 1;
425 }
426
427 /*
428 * Device timeout/watchdog routine. Entered if the device neglects to
429 * generate an interrupt after a transmit has been started on it.
430 */
431 static void
432 iewatchdog(struct ifnet *ifp)
433 {
434 struct ie_softc *sc = ifp->if_softc;
435
436 log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev));
437 ++ifp->if_oerrors;
438 iereset(sc);
439 }
440
441 /*
442 * What to do upon receipt of an interrupt.
443 */
444 int
445 ie_intr(void *arg)
446 {
447 struct ie_softc *sc = arg;
448 uint16_t status;
449 int loopcnt;
450
451 /*
452 * check for parity error
453 */
454 if (sc->hard_type == IE_VME) {
455 volatile struct ievme *iev =
456 (volatile struct ievme *)sc->sc_reg;
457
458 if (iev->status & IEVME_PERR) {
459 printf("%s: parity error (ctrl 0x%x @ 0x%02x%04x)\n",
460 device_xname(sc->sc_dev), iev->pectrl,
461 iev->pectrl & IEVME_HADDR, iev->peaddr);
462 iev->pectrl = iev->pectrl | IEVME_PARACK;
463 }
464 }
465
466 status = sc->scb->ie_status;
467 if ((status & IE_ST_WHENCE) == 0)
468 return 0;
469
470 loopcnt = sc->nframes;
471 loop:
472 /* Ack interrupts FIRST in case we receive more during the ISR. */
473 ie_ack(sc, IE_ST_WHENCE & status);
474
475 if (status & (IE_ST_RECV | IE_ST_RNR)) {
476 #ifdef IEDEBUG
477 in_ierint++;
478 if (sc->sc_debug & IED_RINT)
479 printf("%s: rint\n", device_xname(sc->sc_dev));
480 #endif
481 ierint(sc);
482 #ifdef IEDEBUG
483 in_ierint--;
484 #endif
485 }
486
487 if (status & IE_ST_DONE) {
488 #ifdef IEDEBUG
489 in_ietint++;
490 if (sc->sc_debug & IED_TINT)
491 printf("%s: tint\n", device_xname(sc->sc_dev));
492 #endif
493 ietint(sc);
494 #ifdef IEDEBUG
495 in_ietint--;
496 #endif
497 }
498
499 /*
500 * Receiver not ready (RNR) just means it has
501 * run out of resources (buffers or frames).
502 * One can easily cause this with (i.e.) spray.
503 * This is not a serious error, so be silent.
504 */
505 if (status & IE_ST_RNR) {
506 #ifdef IEDEBUG
507 printf("%s: receiver not ready\n", device_xname(sc->sc_dev));
508 #endif
509 sc->sc_if.if_ierrors++;
510 iereset(sc);
511 }
512
513 #ifdef IEDEBUG
514 if ((status & IE_ST_ALLDONE) && (sc->sc_debug & IED_CNA))
515 printf("%s: cna\n", device_xname(sc->sc_dev));
516 #endif
517
518 status = sc->scb->ie_status;
519 if (status & IE_ST_WHENCE) {
520 /* It still wants service... */
521 if (--loopcnt > 0)
522 goto loop;
523 /* ... but we've been here long enough. */
524 log(LOG_ERR, "%s: interrupt stuck?\n",
525 device_xname(sc->sc_dev));
526 iereset(sc);
527 }
528 return 1;
529 }
530
531 /*
532 * Process a received-frame interrupt.
533 */
534 void
535 ierint(struct ie_softc *sc)
536 {
537 volatile struct ie_sys_ctl_block *scb = sc->scb;
538 int i, status;
539 static int timesthru = 1024;
540
541 i = sc->rfhead;
542 for (;;) {
543 status = sc->rframes[i]->ie_fd_status;
544
545 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
546 if (!--timesthru) {
547 sc->sc_if.if_ierrors +=
548 SWAP(scb->ie_err_crc) +
549 SWAP(scb->ie_err_align) +
550 SWAP(scb->ie_err_resource) +
551 SWAP(scb->ie_err_overrun);
552 scb->ie_err_crc = 0;
553 scb->ie_err_align = 0;
554 scb->ie_err_resource = 0;
555 scb->ie_err_overrun = 0;
556 timesthru = 1024;
557 }
558 ie_readframe(sc, i);
559 } else {
560 if ((status & IE_FD_RNR) != 0 &&
561 (scb->ie_status & IE_RU_READY) == 0) {
562 sc->rframes[0]->ie_fd_buf_desc = vtop16sw(sc,
563 __UNVOLATILE(sc->rbuffs[0]));
564 scb->ie_recv_list = vtop16sw(sc,
565 __UNVOLATILE(sc->rframes[0]));
566 cmd_and_wait(sc, IE_RU_START, 0, 0);
567 }
568 break;
569 }
570 i = (i + 1) % sc->nframes;
571 }
572 }
573
574 /*
575 * Process a command-complete interrupt. These are only generated by the
576 * transmission of frames. This routine is deceptively simple, since most
577 * of the real work is done by iestart().
578 */
579 void
580 ietint(struct ie_softc *sc)
581 {
582 struct ifnet *ifp;
583 int status;
584
585 ifp = &sc->sc_if;
586
587 ifp->if_timer = 0;
588 ifp->if_flags &= ~IFF_OACTIVE;
589
590 status = sc->xmit_cmds[sc->xctail]->ie_xmit_status;
591
592 if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY))
593 printf("%s: command still busy!\n", __func__);
594
595 if (status & IE_STAT_OK) {
596 ifp->if_opackets++;
597 ifp->if_collisions +=
598 SWAP(status & IE_XS_MAXCOLL);
599 } else {
600 ifp->if_oerrors++;
601 /*
602 * XXX
603 * Check SQE and DEFERRED?
604 * What if more than one bit is set?
605 */
606 if (status & IE_STAT_ABORT)
607 printf("%s: send aborted\n", device_xname(sc->sc_dev));
608 if (status & IE_XS_LATECOLL)
609 printf("%s: late collision\n",
610 device_xname(sc->sc_dev));
611 if (status & IE_XS_NOCARRIER)
612 printf("%s: no carrier\n", device_xname(sc->sc_dev));
613 if (status & IE_XS_LOSTCTS)
614 printf("%s: lost CTS\n", device_xname(sc->sc_dev));
615 if (status & IE_XS_UNDERRUN)
616 printf("%s: DMA underrun\n", device_xname(sc->sc_dev));
617 if (status & IE_XS_EXCMAX) {
618 /* Do not print this one (too noisy). */
619 ifp->if_collisions += 16;
620 }
621 }
622
623 /*
624 * If multicast addresses were added or deleted while we
625 * were transmitting, mc_reset() set the want_mcsetup flag
626 * indicating that we should do it.
627 */
628 if (sc->want_mcsetup) {
629 mc_setup(sc, (void *)sc->xmit_cbuffs[sc->xctail]);
630 sc->want_mcsetup = 0;
631 }
632
633 /* Done with the buffer. */
634 sc->xmit_busy--;
635 sc->xctail = (sc->xctail + 1) % NTXBUF;
636
637 /* Start the next packet, if any, transmitting. */
638 if (sc->xmit_busy > 0)
639 iexmit(sc);
640
641 iestart(ifp);
642 }
643
644 /*
645 * Compare two Ether/802 addresses for equality, inlined and
646 * unrolled for speed. I'd love to have an inline assembler
647 * version of this... XXX: Who wanted that? mycroft?
648 * I wrote one, but the following is just as efficient.
649 * This expands to 10 short m68k instructions! -gwr
650 * Note: use this like memcmp()
651 */
652 static inline uint16_t
653 ether_cmp(uint8_t *one, uint8_t *two)
654 {
655 uint16_t *a = (uint16_t *)one;
656 uint16_t *b = (uint16_t *)two;
657 uint16_t diff;
658
659 diff = *a++ - *b++;
660 diff |= *a++ - *b++;
661 diff |= *a++ - *b++;
662
663 return diff;
664 }
665 #define ether_equal !ether_cmp
666
667 /*
668 * We want to isolate the bits that have meaning... This assumes that
669 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds
670 * the size of the buffer, then we are screwed anyway.
671 */
672 static inline int
673 ie_buflen(struct ie_softc *sc, int head)
674 {
675 int len;
676
677 len = SWAP(sc->rbuffs[head]->ie_rbd_actual);
678 len &= (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1));
679 return len;
680 }
681
682 static inline int
683 ie_packet_len(struct ie_softc *sc)
684 {
685 int i;
686 int head = sc->rbhead;
687 int acc = 0;
688
689 do {
690 if ((sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)
691 == 0) {
692 #ifdef IEDEBUG
693 print_rbd(sc->rbuffs[sc->rbhead]);
694 #endif
695 log(LOG_ERR,
696 "%s: receive descriptors out of sync at %d\n",
697 device_xname(sc->sc_dev), sc->rbhead);
698 iereset(sc);
699 return -1;
700 }
701
702 i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
703
704 acc += ie_buflen(sc, head);
705 head = (head + 1) % sc->nrxbuf;
706 } while (i == 0);
707
708 return acc;
709 }
710
711 /*
712 * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
713 * command to the chip to be executed. On the way, if we have a BPF listener
714 * also give him a copy.
715 */
716 static void
717 iexmit(struct ie_softc *sc)
718 {
719 struct ifnet *ifp;
720
721 ifp = &sc->sc_if;
722
723 #ifdef IEDEBUG
724 if (sc->sc_debug & IED_XMIT)
725 printf("%s: xmit buffer %d\n", device_xname(sc->sc_dev),
726 sc->xctail);
727 #endif
728
729 /*
730 * If BPF is listening on this interface, let it see the packet before
731 * we push it on the wire.
732 */
733 bpf_tap(ifp, sc->xmit_cbuffs[sc->xctail],
734 SWAP(sc->xmit_buffs[sc->xctail]->ie_xmit_flags));
735
736 sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST;
737 sc->xmit_buffs[sc->xctail]->ie_xmit_next = SWAP(0xffff);
738 sc->xmit_buffs[sc->xctail]->ie_xmit_buf =
739 Swap32(vtop24(sc, sc->xmit_cbuffs[sc->xctail]));
740
741 sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = SWAP(0xffff);
742 sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd =
743 IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST;
744
745 sc->xmit_cmds[sc->xctail]->ie_xmit_status = SWAP(0);
746 sc->xmit_cmds[sc->xctail]->ie_xmit_desc =
747 vtop16sw(sc, __UNVOLATILE(sc->xmit_buffs[sc->xctail]));
748
749 sc->scb->ie_command_list =
750 vtop16sw(sc, __UNVOLATILE(sc->xmit_cmds[sc->xctail]));
751 cmd_and_wait(sc, IE_CU_START, 0, 0);
752
753 ifp->if_timer = 5;
754 }
755
756 /*
757 * Read data off the interface, and turn it into an mbuf chain.
758 *
759 * This code is DRAMATICALLY different from the previous version; this
760 * version tries to allocate the entire mbuf chain up front, given the
761 * length of the data available. This enables us to allocate mbuf
762 * clusters in many situations where before we would have had a long
763 * chain of partially-full mbufs. This should help to speed up the
764 * operation considerably. (Provided that it works, of course.)
765 */
766 static inline struct mbuf *
767 ieget(struct ie_softc *sc)
768 {
769 struct mbuf *top, **mp, *m;
770 int len, totlen, resid;
771 int thisrboff, thismboff;
772 int head;
773 struct ether_header eh;
774
775 totlen = ie_packet_len(sc);
776 if (totlen <= 0)
777 return 0;
778
779 head = sc->rbhead;
780
781 /*
782 * Snarf the Ethernet header.
783 */
784 (sc->sc_memcpy)((void *)&eh, (void *)sc->cbuffs[head],
785 sizeof(struct ether_header));
786
787 resid = totlen;
788
789 MGETHDR(m, M_DONTWAIT, MT_DATA);
790 if (m == 0)
791 return 0;
792
793 m_set_rcvif(m, &sc->sc_if);
794 m->m_pkthdr.len = totlen;
795 len = MHLEN;
796 top = 0;
797 mp = ⊤
798
799 /*
800 * This loop goes through and allocates mbufs for all the data we will
801 * be copying in. It does not actually do the copying yet.
802 */
803 while (totlen > 0) {
804 if (top) {
805 MGET(m, M_DONTWAIT, MT_DATA);
806 if (m == 0) {
807 m_freem(top);
808 return 0;
809 }
810 len = MLEN;
811 }
812 if (totlen >= MINCLSIZE) {
813 MCLGET(m, M_DONTWAIT);
814 if (m->m_flags & M_EXT)
815 len = MCLBYTES;
816 }
817
818 if (mp == &top) {
819 char *newdata = (char *)
820 ALIGN(m->m_data + sizeof(struct ether_header)) -
821 sizeof(struct ether_header);
822 len -= newdata - m->m_data;
823 m->m_data = newdata;
824 }
825
826 m->m_len = len = min(totlen, len);
827
828 totlen -= len;
829 *mp = m;
830 mp = &m->m_next;
831 }
832
833 m = top;
834 thismboff = 0;
835
836 /*
837 * Copy the Ethernet header into the mbuf chain.
838 */
839 memcpy(mtod(m, void *), &eh, sizeof(struct ether_header));
840 thismboff = sizeof(struct ether_header);
841 thisrboff = sizeof(struct ether_header);
842 resid -= sizeof(struct ether_header);
843
844 /*
845 * Now we take the mbuf chain (hopefully only one mbuf most of the
846 * time) and stuff the data into it. There are no possible failures
847 * at or after this point.
848 */
849 while (resid > 0) {
850 int thisrblen = ie_buflen(sc, head) - thisrboff;
851 int thismblen = m->m_len - thismboff;
852
853 len = min(thisrblen, thismblen);
854 (sc->sc_memcpy)(mtod(m, char *) + thismboff,
855 (void *)(sc->cbuffs[head] + thisrboff),
856 (u_int)len);
857 resid -= len;
858
859 if (len == thismblen) {
860 m = m->m_next;
861 thismboff = 0;
862 } else
863 thismboff += len;
864
865 if (len == thisrblen) {
866 head = (head + 1) % sc->nrxbuf;
867 thisrboff = 0;
868 } else
869 thisrboff += len;
870 }
871
872 /*
873 * Unless something changed strangely while we were doing the copy,
874 * we have now copied everything in from the shared memory.
875 * This means that we are done.
876 */
877 return top;
878 }
879
880 /*
881 * Read frame NUM from unit UNIT (pre-cached as IE).
882 *
883 * This routine reads the RFD at NUM, and copies in the buffers from
884 * the list of RBD, then rotates the RBD and RFD lists so that the receiver
885 * doesn't start complaining. Trailers are DROPPED---there's no point
886 * in wasting time on confusing code to deal with them. Hopefully,
887 * this machine will never ARP for trailers anyway.
888 */
889 static void
890 ie_readframe(struct ie_softc *sc, int num)
891 {
892 int status;
893 struct mbuf *m = 0;
894
895 status = sc->rframes[num]->ie_fd_status;
896
897 /* Advance the RFD list, since we're done with this descriptor. */
898 sc->rframes[num]->ie_fd_status = SWAP(0);
899 sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
900 sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
901 sc->rftail = (sc->rftail + 1) % sc->nframes;
902 sc->rfhead = (sc->rfhead + 1) % sc->nframes;
903
904 if (status & IE_FD_OK) {
905 m = ieget(sc);
906 ie_drop_packet_buffer(sc);
907 }
908 if (m == 0) {
909 sc->sc_if.if_ierrors++;
910 return;
911 }
912
913 #ifdef IEDEBUG
914 if (sc->sc_debug & IED_READFRAME) {
915 struct ether_header *eh = mtod(m, struct ether_header *);
916
917 printf("%s: frame from ether %s type 0x%x\n",
918 device_xname(sc->sc_dev),
919 ether_sprintf(eh->ether_shost), (u_int)eh->ether_type);
920 }
921 #endif
922
923 /*
924 * Finally pass this packet up to higher layers.
925 */
926 if_percpuq_enqueue((&sc->sc_if)->if_percpuq, m);
927 }
928
929 static void
930 ie_drop_packet_buffer(struct ie_softc *sc)
931 {
932 int i;
933
934 do {
935 /*
936 * This means we are somehow out of sync. So, we reset the
937 * adapter.
938 */
939 if ((sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)
940 == 0) {
941 #ifdef IEDEBUG
942 print_rbd(sc->rbuffs[sc->rbhead]);
943 #endif
944 log(LOG_ERR,
945 "%s: receive descriptors out of sync at %d\n",
946 device_xname(sc->sc_dev), sc->rbhead);
947 iereset(sc);
948 return;
949 }
950
951 i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
952
953 sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
954 sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0);
955 sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf;
956 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
957 sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf;
958 } while (i == 0);
959 }
960
961 /*
962 * Start transmission on an interface.
963 */
964 static void
965 iestart(struct ifnet *ifp)
966 {
967 struct ie_softc *sc = ifp->if_softc;
968 struct mbuf *m0, *m;
969 uint8_t *buffer;
970 uint16_t len;
971
972 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
973 return;
974
975 for (;;) {
976 if (sc->xmit_busy == sc->ntxbuf) {
977 ifp->if_flags |= IFF_OACTIVE;
978 break;
979 }
980
981 IF_DEQUEUE(&ifp->if_snd, m0);
982 if (m0 == 0)
983 break;
984
985 /* We need to use m->m_pkthdr.len, so require the header */
986 if ((m0->m_flags & M_PKTHDR) == 0)
987 panic("%s: no header mbuf", __func__);
988
989 /* Tap off here if there is a BPF listener. */
990 bpf_mtap(ifp, m0);
991
992 #ifdef IEDEBUG
993 if (sc->sc_debug & IED_ENQ)
994 printf("%s: fill buffer %d\n", device_xname(sc->sc_dev),
995 sc->xchead);
996 #endif
997
998 buffer = sc->xmit_cbuffs[sc->xchead];
999 for (m = m0; m != 0; m = m->m_next) {
1000 (sc->sc_memcpy)(buffer, mtod(m, void *), m->m_len);
1001 buffer += m->m_len;
1002 }
1003 if (m0->m_pkthdr.len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
1004 sc->sc_memset(buffer, 0,
1005 ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len);
1006 len = ETHER_MIN_LEN - ETHER_CRC_LEN;
1007 } else
1008 len = m0->m_pkthdr.len;
1009
1010 m_freem(m0);
1011 sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len);
1012
1013 /* Start the first packet transmitting. */
1014 if (sc->xmit_busy == 0)
1015 iexmit(sc);
1016
1017 sc->xchead = (sc->xchead + 1) % sc->ntxbuf;
1018 sc->xmit_busy++;
1019 }
1020 }
1021
1022 static void
1023 iereset(struct ie_softc *sc)
1024 {
1025 int s;
1026
1027 s = splnet();
1028
1029 /* No message here. The caller does that. */
1030 iestop(sc);
1031
1032 /*
1033 * Stop i82586 dead in its tracks.
1034 */
1035 if (cmd_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1036 printf("%s: abort commands timed out\n",
1037 device_xname(sc->sc_dev));
1038
1039 if (cmd_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1040 printf("%s: disable commands timed out\n",
1041 device_xname(sc->sc_dev));
1042
1043 ieinit(sc);
1044
1045 splx(s);
1046 }
1047
1048 /*
1049 * Send a command to the controller and wait for it to either
1050 * complete or be accepted, depending on the command. If the
1051 * command pointer is null, then pretend that the command is
1052 * not an action command. If the command pointer is not null,
1053 * and the command is an action command, wait for
1054 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
1055 * to become true.
1056 */
1057 static int
1058 cmd_and_wait(struct ie_softc *sc, int cmd, void *pcmd, int mask)
1059 {
1060 volatile struct ie_cmd_common *cc = pcmd;
1061 volatile struct ie_sys_ctl_block *scb = sc->scb;
1062 int tmo;
1063
1064 scb->ie_command = (uint16_t)cmd;
1065 (sc->chan_attn)(sc);
1066
1067 /* Wait for the command to be accepted by the CU. */
1068 tmo = 10;
1069 while (scb->ie_command && --tmo)
1070 delay(10);
1071 if (scb->ie_command) {
1072 #ifdef IEDEBUG
1073 printf("%s: cmd_and_wait, CU stuck (1)\n",
1074 device_xname(sc->sc_dev));
1075 #endif
1076 return -1; /* timed out */
1077 }
1078
1079 /*
1080 * If asked, also wait for it to finish.
1081 */
1082 if (IE_ACTION_COMMAND(cmd) && pcmd) {
1083
1084 /*
1085 * According to the packet driver, the minimum timeout should
1086 * be .369 seconds, which we round up to .4.
1087 */
1088 tmo = 36900;
1089
1090 /*
1091 * Now spin-lock waiting for status. This is not a very nice
1092 * thing to do, but I haven't figured out how, or indeed if, we
1093 * can put the process waiting for action to sleep. (We may
1094 * be getting called through some other timeout running in the
1095 * kernel.)
1096 */
1097 while (((cc->ie_cmd_status & mask) == 0) && --tmo)
1098 delay(10);
1099
1100 if ((cc->ie_cmd_status & mask) == 0) {
1101 #ifdef IEDEBUG
1102 printf("%s: cmd_and_wait, CU stuck (2)\n",
1103 device_xname(sc->sc_dev));
1104 #endif
1105 return -1; /* timed out */
1106 }
1107 }
1108 return 0;
1109 }
1110
1111 /*
1112 * Run the time-domain reflectometer.
1113 */
1114 static void
1115 run_tdr(struct ie_softc *sc, struct ie_tdr_cmd *cmd)
1116 {
1117 int result;
1118
1119 cmd->com.ie_cmd_status = SWAP(0);
1120 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1121 cmd->com.ie_cmd_link = SWAP(0xffff);
1122
1123 sc->scb->ie_command_list = vtop16sw(sc, cmd);
1124 cmd->ie_tdr_time = SWAP(0);
1125
1126 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1127 (cmd->com.ie_cmd_status & IE_STAT_OK) == 0)
1128 result = 0x10000; /* impossible value */
1129 else
1130 result = cmd->ie_tdr_time;
1131
1132 ie_ack(sc, IE_ST_WHENCE);
1133
1134 if (result & IE_TDR_SUCCESS)
1135 return;
1136
1137 if (result & 0x10000) {
1138 printf("%s: TDR command failed\n", device_xname(sc->sc_dev));
1139 } else if (result & IE_TDR_XCVR) {
1140 printf("%s: transceiver problem\n", device_xname(sc->sc_dev));
1141 } else if (result & IE_TDR_OPEN) {
1142 printf("%s: TDR detected an open %d clocks away\n",
1143 device_xname(sc->sc_dev), SWAP(result & IE_TDR_TIME));
1144 } else if (result & IE_TDR_SHORT) {
1145 printf("%s: TDR detected a short %d clocks away\n",
1146 device_xname(sc->sc_dev), SWAP(result & IE_TDR_TIME));
1147 } else {
1148 printf("%s: TDR returned unknown status 0x%x\n",
1149 device_xname(sc->sc_dev), result);
1150 }
1151 }
1152
1153 /*
1154 * iememinit: set up the buffers
1155 *
1156 * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
1157 * this is to be used for the buffers. the chip indexs its control data
1158 * structures with 16 bit offsets, and it indexes actual buffers with
1159 * 24 bit addresses. so we should allocate control buffers first so that
1160 * we don't overflow the 16 bit offset field. The number of transmit
1161 * buffers is fixed at compile time.
1162 *
1163 * note: this function was written to be easy to understand, rather than
1164 * highly efficient (it isn't in the critical path).
1165 *
1166 * The memory layout is: tbufs, rbufs, (gap), control blocks
1167 * [tbuf0, tbuf1] [rbuf0,...rbufN] gap [rframes] [tframes]
1168 * XXX - This needs review...
1169 */
1170 static void
1171 iememinit(struct ie_softc *sc)
1172 {
1173 uint8_t *ptr;
1174 int i;
1175 uint16_t nxt;
1176
1177 /* First, zero all the memory. */
1178 ptr = sc->buf_area;
1179 (sc->sc_memset)(ptr, 0, sc->buf_area_sz);
1180
1181 /* Allocate tx/rx buffers. */
1182 for (i = 0; i < NTXBUF; i++) {
1183 sc->xmit_cbuffs[i] = ptr;
1184 ptr += IE_TBUF_SIZE;
1185 }
1186 for (i = 0; i < sc->nrxbuf; i++) {
1187 sc->cbuffs[i] = ptr;
1188 ptr += IE_RBUF_SIZE;
1189 }
1190
1191 /* Small pad (Don't trust the chip...) */
1192 ptr += 16;
1193
1194 /* Allocate and fill in xmit buffer descriptors. */
1195 for (i = 0; i < NTXBUF; i++) {
1196 sc->xmit_buffs[i] = (volatile void *)ptr;
1197 ptr = Align(ptr + sizeof(*sc->xmit_buffs[i]));
1198 sc->xmit_buffs[i]->ie_xmit_buf =
1199 Swap32(vtop24(sc, sc->xmit_cbuffs[i]));
1200 sc->xmit_buffs[i]->ie_xmit_next = SWAP(0xffff);
1201 }
1202
1203 /* Allocate and fill in recv buffer descriptors. */
1204 for (i = 0; i < sc->nrxbuf; i++) {
1205 sc->rbuffs[i] = (volatile void *)ptr;
1206 ptr = Align(ptr + sizeof(*sc->rbuffs[i]));
1207 sc->rbuffs[i]->ie_rbd_buffer =
1208 Swap32(vtop24(sc, sc->cbuffs[i]));
1209 sc->rbuffs[i]->ie_rbd_length = SWAP(IE_RBUF_SIZE);
1210 }
1211
1212 /* link together recv bufs and set EOL on last */
1213 i = sc->nrxbuf - 1;
1214 sc->rbuffs[i]->ie_rbd_length |= IE_RBD_LAST;
1215 nxt = vtop16sw(sc, __UNVOLATILE(sc->rbuffs[0]));
1216 do {
1217 sc->rbuffs[i]->ie_rbd_next = nxt;
1218 nxt = vtop16sw(sc, __UNVOLATILE(sc->rbuffs[i]));
1219 } while (--i >= 0);
1220
1221 /* Allocate transmit commands. */
1222 for (i = 0; i < NTXBUF; i++) {
1223 sc->xmit_cmds[i] = (volatile void *)ptr;
1224 ptr = Align(ptr + sizeof(*sc->xmit_cmds[i]));
1225 sc->xmit_cmds[i]->com.ie_cmd_link = SWAP(0xffff);
1226 }
1227
1228 /* Allocate receive frames. */
1229 for (i = 0; i < sc->nframes; i++) {
1230 sc->rframes[i] = (volatile void *)ptr;
1231 ptr = Align(ptr + sizeof(*sc->rframes[i]));
1232 }
1233
1234 /* Link together recv frames and set EOL on last */
1235 i = sc->nframes - 1;
1236 sc->rframes[i]->ie_fd_last |= IE_FD_LAST;
1237 nxt = vtop16sw(sc, __UNVOLATILE(sc->rframes[0]));
1238 do {
1239 sc->rframes[i]->ie_fd_next = nxt;
1240 nxt = vtop16sw(sc, __UNVOLATILE(sc->rframes[i]));
1241 } while (--i >= 0);
1242
1243
1244 /* Pointers to last packet sent and next available transmit buffer. */
1245 sc->xchead = sc->xctail = 0;
1246
1247 /* Clear transmit-busy flag. */
1248 sc->xmit_busy = 0;
1249
1250 /*
1251 * Set the head and tail pointers on receive to keep track of
1252 * the order in which RFDs and RBDs are used. link the
1253 * recv frames and buffer into the scb.
1254 */
1255 sc->rfhead = 0;
1256 sc->rftail = sc->nframes - 1;
1257 sc->rbhead = 0;
1258 sc->rbtail = sc->nrxbuf - 1;
1259
1260 sc->scb->ie_recv_list =
1261 vtop16sw(sc, __UNVOLATILE(sc->rframes[0]));
1262 sc->rframes[0]->ie_fd_buf_desc =
1263 vtop16sw(sc, __UNVOLATILE(sc->rbuffs[0]));
1264
1265 i = (ptr - sc->buf_area);
1266 #ifdef IEDEBUG
1267 printf("IE_DEBUG: used %d of %d bytes\n", i, sc->buf_area_sz);
1268 #endif
1269 if (i > sc->buf_area_sz)
1270 panic("ie: iememinit, out of space");
1271 }
1272
1273 /*
1274 * Run the multicast setup command.
1275 * Called at splnet().
1276 */
1277 static int
1278 mc_setup(struct ie_softc *sc, void *ptr)
1279 {
1280 struct ie_mcast_cmd *cmd = ptr; /* XXX - Was volatile */
1281
1282 cmd->com.ie_cmd_status = SWAP(0);
1283 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1284 cmd->com.ie_cmd_link = SWAP(0xffff);
1285
1286 (sc->sc_memcpy)((void *)cmd->ie_mcast_addrs,
1287 (void *)sc->mcast_addrs,
1288 sc->mcast_count * sizeof *sc->mcast_addrs);
1289
1290 cmd->ie_mcast_bytes =
1291 SWAP(sc->mcast_count * ETHER_ADDR_LEN); /* grrr... */
1292
1293 sc->scb->ie_command_list = vtop16sw(sc, cmd);
1294 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1295 (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) {
1296 printf("%s: multicast address setup command failed\n",
1297 device_xname(sc->sc_dev));
1298 return 0;
1299 }
1300 return 1;
1301 }
1302
1303 static inline void
1304 ie_setup_config(struct ie_config_cmd *cmd, int promiscuous, int manchester)
1305 {
1306
1307 /*
1308 * these are all char's so no need to byte-swap
1309 */
1310 cmd->ie_config_count = 0x0c;
1311 cmd->ie_fifo = 8;
1312 cmd->ie_save_bad = 0x40;
1313 cmd->ie_addr_len = 0x2e;
1314 cmd->ie_priority = 0;
1315 cmd->ie_ifs = 0x60;
1316 cmd->ie_slot_low = 0;
1317 cmd->ie_slot_high = 0xf2;
1318 cmd->ie_promisc = promiscuous | manchester << 2;
1319 cmd->ie_crs_cdt = 0;
1320 cmd->ie_min_len = 64;
1321 cmd->ie_junk = 0xff;
1322 }
1323
1324 /*
1325 * This routine inits the ie.
1326 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands,
1327 * starting the receiver unit, and clearing interrupts.
1328 *
1329 * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
1330 */
1331 static int
1332 ieinit(struct ie_softc *sc)
1333 {
1334 volatile struct ie_sys_ctl_block *scb = sc->scb;
1335 void *ptr;
1336 struct ifnet *ifp;
1337
1338 ifp = &sc->sc_if;
1339 ptr = sc->buf_area; /* XXX - Use scb instead? */
1340
1341 /*
1342 * Send the configure command first.
1343 */
1344 {
1345 struct ie_config_cmd *cmd = ptr; /* XXX - Was volatile */
1346
1347 scb->ie_command_list = vtop16sw(sc, cmd);
1348 cmd->com.ie_cmd_status = SWAP(0);
1349 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
1350 cmd->com.ie_cmd_link = SWAP(0xffff);
1351
1352 ie_setup_config(cmd, (sc->promisc != 0), 0);
1353
1354 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1355 (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) {
1356 printf("%s: configure command failed\n",
1357 device_xname(sc->sc_dev));
1358 return 0;
1359 }
1360 }
1361
1362 /*
1363 * Now send the Individual Address Setup command.
1364 */
1365 {
1366 struct ie_iasetup_cmd *cmd = ptr; /* XXX - Was volatile */
1367
1368 scb->ie_command_list = vtop16sw(sc, cmd);
1369 cmd->com.ie_cmd_status = SWAP(0);
1370 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
1371 cmd->com.ie_cmd_link = SWAP(0xffff);
1372
1373 (sc->sc_memcpy)((void *)&cmd->ie_address,
1374 CLLADDR(ifp->if_sadl), sizeof(cmd->ie_address));
1375
1376 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1377 (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) {
1378 printf("%s: individual address setup command failed\n",
1379 device_xname(sc->sc_dev));
1380 return 0;
1381 }
1382 }
1383
1384 /*
1385 * Now run the time-domain reflectometer.
1386 */
1387 if (ie_run_tdr)
1388 run_tdr(sc, ptr);
1389
1390 /*
1391 * Acknowledge any interrupts we have generated thus far.
1392 */
1393 ie_ack(sc, IE_ST_WHENCE);
1394
1395 /*
1396 * Set up the transmit and recv buffers.
1397 */
1398 iememinit(sc);
1399
1400 /* tell higher levels that we are here */
1401 ifp->if_flags |= IFF_RUNNING;
1402 ifp->if_flags &= ~IFF_OACTIVE;
1403
1404 sc->scb->ie_recv_list =
1405 vtop16sw(sc, __UNVOLATILE(sc->rframes[0]));
1406 cmd_and_wait(sc, IE_RU_START, 0, 0);
1407
1408 ie_ack(sc, IE_ST_WHENCE);
1409
1410 if (sc->run_586)
1411 (sc->run_586)(sc);
1412
1413 return 0;
1414 }
1415
1416 static void
1417 iestop(struct ie_softc *sc)
1418 {
1419
1420 cmd_and_wait(sc, IE_RU_DISABLE, 0, 0);
1421 }
1422
1423 static int
1424 ieioctl(struct ifnet *ifp, u_long cmd, void *data)
1425 {
1426 struct ie_softc *sc = ifp->if_softc;
1427 struct ifaddr *ifa = (struct ifaddr *)data;
1428 int s, error = 0;
1429
1430 s = splnet();
1431
1432 switch (cmd) {
1433
1434 case SIOCINITIFADDR:
1435 ifp->if_flags |= IFF_UP;
1436
1437 switch (ifa->ifa_addr->sa_family) {
1438 #ifdef INET
1439 case AF_INET:
1440 ieinit(sc);
1441 arp_ifinit(ifp, ifa);
1442 break;
1443 #endif
1444 default:
1445 ieinit(sc);
1446 break;
1447 }
1448 break;
1449
1450 case SIOCSIFFLAGS:
1451 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
1452 break;
1453 sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
1454
1455 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
1456 case IFF_RUNNING:
1457 /*
1458 * If interface is marked down and it is running, then
1459 * stop it.
1460 */
1461 iestop(sc);
1462 ifp->if_flags &= ~IFF_RUNNING;
1463 break;
1464 case IFF_UP:
1465 /*
1466 * If interface is marked up and it is stopped, then
1467 * start it.
1468 */
1469 ieinit(sc);
1470 break;
1471 default:
1472 /*
1473 * Reset the interface to pick up changes in any other
1474 * flags that affect hardware registers.
1475 */
1476 iestop(sc);
1477 ieinit(sc);
1478 break;
1479 }
1480 #ifdef IEDEBUG
1481 if (ifp->if_flags & IFF_DEBUG)
1482 sc->sc_debug = IED_ALL;
1483 else
1484 sc->sc_debug = ie_debug_flags;
1485 #endif
1486 break;
1487
1488 case SIOCADDMULTI:
1489 case SIOCDELMULTI:
1490 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
1491 /*
1492 * Multicast list has changed; set the hardware filter
1493 * accordingly.
1494 */
1495 if (ifp->if_flags & IFF_RUNNING)
1496 mc_reset(sc);
1497 error = 0;
1498 }
1499 break;
1500
1501 default:
1502 error = ether_ioctl(ifp, cmd, data);
1503 break;
1504 }
1505 splx(s);
1506 return error;
1507 }
1508
1509 static void
1510 mc_reset(struct ie_softc *sc)
1511 {
1512 struct ether_multi *enm;
1513 struct ether_multistep step;
1514 struct ifnet *ifp;
1515
1516 ifp = &sc->sc_if;
1517
1518 /*
1519 * Step through the list of addresses.
1520 */
1521 sc->mcast_count = 0;
1522 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1523 while (enm) {
1524 if (sc->mcast_count >= MAXMCAST ||
1525 ether_cmp(enm->enm_addrlo, enm->enm_addrhi) != 0) {
1526 ifp->if_flags |= IFF_ALLMULTI;
1527 ieioctl(ifp, SIOCSIFFLAGS, NULL);
1528 goto setflag;
1529 }
1530 memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo,
1531 ETHER_ADDR_LEN);
1532 sc->mcast_count++;
1533 ETHER_NEXT_MULTI(step, enm);
1534 }
1535 setflag:
1536 sc->want_mcsetup = 1;
1537 }
1538
1539 #ifdef IEDEBUG
1540 void
1541 print_rbd(volatile struct ie_recv_buf_desc *rbd)
1542 {
1543
1544 printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
1545 "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
1546 rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
1547 rbd->mbz);
1548 }
1549 #endif
1550