1 /*        $NetBSD: i82586.c,v 1.91 2024/02/09 22:08:34 andvar Exp $   */
2 
3 /*-
4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Paul Kranenburg and Charles M. Hannum.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*-
33  * Copyright (c) 1997 Paul Kranenburg.
34  * Copyright (c) 1992, 1993, University of Vermont and State
35  *  Agricultural College.
36  * Copyright (c) 1992, 1993, Garrett A. Wollman.
37  *
38  * Portions:
39  * Copyright (c) 1994, 1995, Rafal K. Boni
40  * Copyright (c) 1990, 1991, William F. Jolitz
41  * Copyright (c) 1990, The Regents of the University of California
42  *
43  * All rights reserved.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions
47  * are met:
48  * 1. Redistributions of source code must retain the above copyright
49  *    notice, this list of conditions and the following disclaimer.
50  * 2. Redistributions in binary form must reproduce the above copyright
51  *    notice, this list of conditions and the following disclaimer in the
52  *    documentation and/or other materials provided with the distribution.
53  * 3. All advertising materials mentioning features or use of this software
54  *    must display the following acknowledgement:
55  *        This product includes software developed by the University of Vermont
56  *        and State Agricultural College and Garrett A. Wollman, by William F.
57  *        Jolitz, and by the University of California, Berkeley, Lawrence
58  *        Berkeley Laboratory, and its contributors.
59  * 4. Neither the names of the Universities nor the names of the authors
60  *    may be used to endorse or promote products derived from this software
61  *    without specific prior written permission.
62  *
63  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
67  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73  * SUCH DAMAGE.
74  */
75 
76 /*
77  * Intel 82586 Ethernet chip
78  * Register, bit, and structure definitions.
79  *
80  * Original StarLAN driver written by Garrett Wollman with reference to the
81  * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
82  *
83  * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
84  *
85  * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
86  *
87  * Majorly cleaned up and 3C507 code merged by Charles Hannum.
88  *
89  * Converted to SUN ie driver by Charles D. Cranor,
90  *                  October 1994, January 1995.
91  * This sun version based on i386 version 1.30.
92  */
93 
94 /*
95  * The i82586 is a very painful chip, found in sun3's, sun-4/100's
96  * sun-4/200's, and VME based suns.  The byte order is all wrong for a
97  * SUN, making life difficult.  Programming this chip is mostly the same,
98  * but certain details differ from system to system.  This driver is
99  * written so that different "ie" interfaces can be controlled by the same
100  * driver.
101  */
102 
103 /*
104 Mode of operation:
105 
106    We run the 82586 in a standard Ethernet mode.  We keep NFRAMES
107    received frame descriptors around for the receiver to use, and
108    NRXBUF associated receive buffer descriptors, both in a circular
109    list.  Whenever a frame is received, we rotate both lists as
110    necessary.  (The 586 treats both lists as a simple queue.)  We also
111    keep a transmit command around so that packets can be sent off
112    quickly.
113 
114    We configure the adapter in AL-LOC = 1 mode, which means that the
115    Ethernet/802.3 MAC header is placed at the beginning of the receive
116    buffer rather than being split off into various fields in the RFD.
117    This also means that we must include this header in the transmit
118    buffer as well.
119 
120    By convention, all transmit commands, and only transmit commands,
121    shall have the I (IE_CMD_INTR) bit set in the command.  This way,
122    when an interrupt arrives at i82586_intr(), it is immediately possible
123    to tell what precisely caused it.  ANY OTHER command-sending
124    routines should run at splnet(), and should post an acknowledgement
125    to every interrupt they generate.
126 
127    To save the expense of shipping a command to 82586 every time we
128    want to send a frame, we use a linked list of commands consisting
129    of alternate XMIT and NOP commands. The links of these elements
130    are manipulated (in iexmit()) such that the NOP command loops back
131    to itself whenever the following XMIT command is not yet ready to
132    go. Whenever an XMIT is ready, the preceding NOP link is pointed
133    at it, while its own link field points to the following NOP command.
134    Thus, a single transmit command sets off an interlocked traversal
135    of the xmit command chain, with the host processor in control of
136    the synchronization.
137 */
138 
139 #include <sys/cdefs.h>
140 __KERNEL_RCSID(0, "$NetBSD: i82586.c,v 1.91 2024/02/09 22:08:34 andvar Exp $");
141 
142 
143 #include <sys/param.h>
144 #include <sys/systm.h>
145 #include <sys/mbuf.h>
146 #include <sys/socket.h>
147 #include <sys/ioctl.h>
148 #include <sys/errno.h>
149 #include <sys/syslog.h>
150 #include <sys/device.h>
151 #include <sys/bus.h>
152 
153 #include <net/if.h>
154 #include <net/if_dl.h>
155 #include <net/if_types.h>
156 #include <net/if_media.h>
157 #include <net/if_ether.h>
158 #include <net/bpf.h>
159 
160 #include <dev/ic/i82586reg.h>
161 #include <dev/ic/i82586var.h>
162 
163 void                i82586_reset(struct ie_softc *, int);
164 void                i82586_watchdog(struct ifnet *);
165 int                 i82586_init(struct ifnet *);
166 int                 i82586_ioctl(struct ifnet *, u_long, void *);
167 void                i82586_start(struct ifnet *);
168 void                i82586_stop(struct ifnet *, int);
169 
170 
171 int                 i82586_rint(struct ie_softc *, int);
172 int                 i82586_tint(struct ie_softc *, int);
173 
174 int                 i82586_mediachange(struct ifnet *);
175 void                i82586_mediastatus(struct ifnet *, struct ifmediareq *);
176 
177 static int          ie_readframe(struct ie_softc *, int);
178 static struct mbuf *ieget(struct ie_softc *, int, int);
179 static int          i82586_get_rbd_list(struct ie_softc *,
180                                                        uint16_t *, uint16_t *, int *);
181 static void         i82586_release_rbd_list(struct ie_softc *,
182                                                        uint16_t, uint16_t);
183 static int          i82586_drop_frames(struct ie_softc *);
184 static int          i82586_chk_rx_ring(struct ie_softc *);
185 
186 static inline void ie_ack(struct ie_softc *, u_int);
187 static inline void iexmit(struct ie_softc *);
188 static void         i82586_start_transceiver(struct ie_softc *);
189 
190 static void         i82586_count_errors(struct ie_softc *);
191 static void         i82586_rx_errors(struct ie_softc *, int, int);
192 static void         i82586_setup_bufs(struct ie_softc *);
193 static void         setup_simple_command(struct ie_softc *, int, int);
194 static int          ie_cfg_setup(struct ie_softc *, int, int, int);
195 static int          ie_ia_setup(struct ie_softc *, int);
196 static void         ie_run_tdr(struct ie_softc *, int);
197 static int          ie_mc_setup(struct ie_softc *, int);
198 static void         ie_mc_reset(struct ie_softc *);
199 static int          i82586_start_cmd(struct ie_softc *, int, int, int, int);
200 static int          i82586_cmd_wait(struct ie_softc *);
201 
202 #if I82586_DEBUG
203 void                print_rbd(struct ie_softc *, int);
204 #endif
205 
206 static char* padbuf = NULL;
207 
208 /*
209  * Front-ends call this function to attach to the MI driver.
210  *
211  * The front-end has responsibility for managing the ICP and ISCP
212  * structures. Both of these are opaque to us.  Also, the front-end
213  * chooses a location for the SCB which is expected to be addressable
214  * (through `sc->scb') as an offset against the shared-memory bus handle.
215  *
216  * The following MD interface function must be setup by the front-end
217  * before calling here:
218  *
219  *        hwreset                       - board dependent reset
220  *        hwinit                        - board dependent initialization
221  *        chan_attn           - channel attention
222  *        intrhook            - board dependent interrupt processing
223  *        memcopyin           - shared memory copy: board to KVA
224  *        memcopyout                    - shared memory copy: KVA to board
225  *        ie_bus_read16                 - read a sixteen-bit i82586 pointer
226  *        ie_bus_write16                - write a sixteen-bit i82586 pointer
227  *        ie_bus_write24                - write a twenty-four-bit i82586 pointer
228  *
229  */
230 void
i82586_attach(struct ie_softc * sc,const char * name,uint8_t * etheraddr,int * media,int nmedia,int defmedia)231 i82586_attach(struct ie_softc *sc, const char *name, uint8_t *etheraddr,
232     int *media, int nmedia, int defmedia)
233 {
234           int i;
235           struct ifnet *ifp = &sc->sc_ethercom.ec_if;
236 
237           strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
238           ifp->if_softc = sc;
239           ifp->if_start = i82586_start;
240           ifp->if_ioctl = i82586_ioctl;
241           ifp->if_init = i82586_init;
242           ifp->if_stop = i82586_stop;
243           ifp->if_watchdog = i82586_watchdog;
244           ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
245           IFQ_SET_READY(&ifp->if_snd);
246 
247           /* Initialize media goo. */
248           sc->sc_ethercom.ec_ifmedia = &sc->sc_media;
249           ifmedia_init(&sc->sc_media, 0, i82586_mediachange, i82586_mediastatus);
250           if (media != NULL) {
251                     for (i = 0; i < nmedia; i++)
252                               ifmedia_add(&sc->sc_media, media[i], 0, NULL);
253                     ifmedia_set(&sc->sc_media, defmedia);
254           } else {
255                     ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL);
256                     ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL);
257           }
258 
259           if (padbuf == NULL) {
260                     padbuf = malloc(ETHER_MIN_LEN - ETHER_CRC_LEN, M_DEVBUF,
261                         M_ZERO | M_WAITOK);
262           }
263 
264           /* Attach the interface. */
265           if_attach(ifp);
266           if_deferred_start_init(ifp, NULL);
267           ether_ifattach(ifp, etheraddr);
268 
269           aprint_normal(" address %s, type %s\n", ether_sprintf(etheraddr),name);
270 }
271 
272 
273 /*
274  * Device timeout/watchdog routine.
275  * Entered if the device neglects to generate an interrupt after a
276  * transmit has been started on it.
277  */
278 void
i82586_watchdog(struct ifnet * ifp)279 i82586_watchdog(struct ifnet *ifp)
280 {
281           struct ie_softc *sc = ifp->if_softc;
282 
283           log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev));
284           if_statinc(ifp, if_oerrors);
285 
286           i82586_reset(sc, 1);
287 }
288 
289 static int
i82586_cmd_wait(struct ie_softc * sc)290 i82586_cmd_wait(struct ie_softc *sc)
291 {
292           /* spin on i82586 command acknowledge; wait at most 0.9 (!) seconds */
293           int i, off;
294           uint16_t cmd;
295 
296           for (i = 0; i < 900000; i++) {
297                     /* Read the command word */
298                     off = IE_SCB_CMD(sc->scb);
299 
300                     IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
301                     if ((cmd = sc->ie_bus_read16(sc, off)) == 0)
302                               return (0);
303                     delay(1);
304           }
305 
306           off = IE_SCB_STATUS(sc->scb);
307           printf("i82586_cmd_wait: timo(%ssync): scb status: 0x%x, cmd: 0x%x\n",
308                     sc->async_cmd_inprogress?"a":"",
309                     sc->ie_bus_read16(sc, off), cmd);
310 
311           return (1);         /* Timeout */
312 }
313 
314 /*
315  * Send a command to the controller and wait for it to either complete
316  * or be accepted, depending on the command.  If the command pointer
317  * is null, then pretend that the command is not an action command.
318  * If the command pointer is not null, and the command is an action
319  * command, wait for one of the MASK bits to turn on in the command's
320  * status field.
321  * If ASYNC is set, we just call the chip's attention and return.
322  * We may have to wait for the command's acceptance later though.
323  */
324 static int
i82586_start_cmd(struct ie_softc * sc,int cmd,int iecmdbuf,int mask,int async)325 i82586_start_cmd(struct ie_softc *sc, int cmd, int iecmdbuf, int mask,
326     int async)
327 {
328           int i;
329           int off;
330 
331           if (sc->async_cmd_inprogress != 0) {
332                     /*
333                      * If previous command was issued asynchronously, wait
334                      * for it now.
335                      */
336                     if (i82586_cmd_wait(sc) != 0)
337                               return (1);
338                     sc->async_cmd_inprogress = 0;
339           }
340 
341           off = IE_SCB_CMD(sc->scb);
342           sc->ie_bus_write16(sc, off, cmd);
343           IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
344           (sc->chan_attn)(sc, CARD_RESET);
345 
346           if (async != 0) {
347                     sc->async_cmd_inprogress = 1;
348                     return (0);
349           }
350 
351           if (IE_ACTION_COMMAND(cmd) && iecmdbuf) {
352                     int status;
353                     /*
354                      * Now spin-lock waiting for status.  This is not a very nice
355                      * thing to do, and can kill performance pretty well...
356                      * According to the packet driver, the minimum timeout
357                      * should be .369 seconds.
358                      */
359                     for (i = 0; i < 369000; i++) {
360                               /* Read the command status */
361                               off = IE_CMD_COMMON_STATUS(iecmdbuf);
362                               IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
363                               status = sc->ie_bus_read16(sc, off);
364                               if (status & mask)
365                                         return (0);
366                               delay(1);
367                     }
368 
369           } else {
370                     /*
371                      * Otherwise, just wait for the command to be accepted.
372                      */
373                     return (i82586_cmd_wait(sc));
374           }
375 
376           /* Timeout */
377           return (1);
378 }
379 
380 /*
381  * Interrupt Acknowledge.
382  */
383 static inline void
ie_ack(struct ie_softc * sc,u_int mask)384 ie_ack(struct ie_softc *sc, u_int mask)
385           /* mask:   in native byte-order */
386 {
387           u_int status;
388 
389           IE_BUS_BARRIER(sc, 0, 0, BUS_SPACE_BARRIER_READ);
390           status = sc->ie_bus_read16(sc, IE_SCB_STATUS(sc->scb));
391           i82586_start_cmd(sc, status & mask, 0, 0, 0);
392           if (sc->intrhook)
393                     sc->intrhook(sc, INTR_ACK);
394 }
395 
396 /*
397  * Transfer accumulated chip error counters to IF.
398  */
399 static inline void
i82586_count_errors(struct ie_softc * sc)400 i82586_count_errors(struct ie_softc *sc)
401 {
402           int scb = sc->scb;
403 
404           if_statadd(&sc->sc_ethercom.ec_if, if_ierrors,
405               sc->ie_bus_read16(sc, IE_SCB_ERRCRC(scb)) +
406               sc->ie_bus_read16(sc, IE_SCB_ERRALN(scb)) +
407               sc->ie_bus_read16(sc, IE_SCB_ERRRES(scb)) +
408               sc->ie_bus_read16(sc, IE_SCB_ERROVR(scb)));
409 
410           /* Clear error counters */
411           sc->ie_bus_write16(sc, IE_SCB_ERRCRC(scb), 0);
412           sc->ie_bus_write16(sc, IE_SCB_ERRALN(scb), 0);
413           sc->ie_bus_write16(sc, IE_SCB_ERRRES(scb), 0);
414           sc->ie_bus_write16(sc, IE_SCB_ERROVR(scb), 0);
415 }
416 
417 static void
i82586_rx_errors(struct ie_softc * sc,int fn,int status)418 i82586_rx_errors(struct ie_softc *sc, int fn, int status)
419 {
420           char bits[128];
421           snprintb(bits, sizeof(bits), IE_FD_STATUSBITS, status);
422           log(LOG_ERR, "%s: rx error (frame# %d): %s\n",
423               device_xname(sc->sc_dev), fn, bits);
424 }
425 
426 /*
427  * i82586 interrupt entry point.
428  */
429 int
i82586_intr(void * v)430 i82586_intr(void *v)
431 {
432           struct ie_softc *sc = v;
433           u_int status;
434           int off;
435 
436           /*
437            * Implementation dependent interrupt handling.
438            */
439           if (sc->intrhook)
440                     (sc->intrhook)(sc, INTR_ENTER);
441 
442           off = IE_SCB_STATUS(sc->scb);
443           IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
444           status = sc->ie_bus_read16(sc, off) & IE_ST_WHENCE;
445 
446           if ((status & IE_ST_WHENCE) == 0) {
447                     if (sc->intrhook)
448                               (sc->intrhook)(sc, INTR_EXIT);
449 
450                     return (0);
451           }
452 
453 loop:
454           /* Ack interrupts FIRST in case we receive more during the ISR. */
455 #if 0
456           ie_ack(sc, status & IE_ST_WHENCE);
457 #endif
458           i82586_start_cmd(sc, status & IE_ST_WHENCE, 0, 0, 1);
459 
460           if (status & (IE_ST_FR | IE_ST_RNR))
461                     if (i82586_rint(sc, status) != 0)
462                               goto reset;
463 
464           if (status & IE_ST_CX)
465                     if (i82586_tint(sc, status) != 0)
466                               goto reset;
467 
468 #if I82586_DEBUG
469           if ((status & IE_ST_CNA) && (sc->sc_debug & IED_CNA))
470                     printf("%s: cna; status=0x%x\n", device_xname(sc->sc_dev),
471                         status);
472 #endif
473           if (sc->intrhook)
474                     (sc->intrhook)(sc, INTR_LOOP);
475 
476           /*
477            * Interrupt ACK was posted asynchronously; wait for
478            * completion here before reading SCB status again.
479            *
480            * If ACK fails, try to reset the chip, in hopes that
481            * it helps.
482            */
483           if (i82586_cmd_wait(sc) != 0)
484                     goto reset;
485 
486           IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
487           status = sc->ie_bus_read16(sc, off);
488           if ((status & IE_ST_WHENCE) != 0)
489                     goto loop;
490 
491 out:
492           if (sc->intrhook)
493                     (sc->intrhook)(sc, INTR_EXIT);
494           return (1);
495 
496 reset:
497           i82586_cmd_wait(sc);
498           i82586_reset(sc, 1);
499           goto out;
500 
501 }
502 
503 /*
504  * Process a received-frame interrupt.
505  */
506 int
i82586_rint(struct ie_softc * sc,int scbstatus)507 i82586_rint(struct ie_softc *sc, int scbstatus)
508 {
509 static    int timesthru = 1024;
510           int i, status, off;
511 
512 #if I82586_DEBUG
513           if (sc->sc_debug & IED_RINT)
514                     printf("%s: rint: status 0x%x\n",
515                               device_xname(sc->sc_dev), scbstatus);
516 #endif
517 
518           for (;;) {
519                     int drop = 0;
520 
521                     i = sc->rfhead;
522                     off = IE_RFRAME_STATUS(sc->rframes, i);
523                     IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
524                     status = sc->ie_bus_read16(sc, off);
525 
526 #if I82586_DEBUG
527                     if (sc->sc_debug & IED_RINT)
528                               printf("%s: rint: frame(%d) status 0x%x\n",
529                                         device_xname(sc->sc_dev), i, status);
530 #endif
531                     if ((status & IE_FD_COMPLETE) == 0) {
532                               if ((status & IE_FD_OK) != 0) {
533                                         printf("%s: rint: weird: ",
534                                                   device_xname(sc->sc_dev));
535                                         i82586_rx_errors(sc, i, status);
536                                         break;
537                               }
538                               if (--timesthru == 0) {
539                                         /* Account the accumulated errors */
540                                         i82586_count_errors(sc);
541                                         timesthru = 1024;
542                               }
543                               break;
544                     } else if ((status & IE_FD_OK) == 0) {
545                               /*
546                                * If the chip is configured to automatically
547                                * discard bad frames, the only reason we can
548                                * get here is an "out-of-resource" condition.
549                                */
550                               i82586_rx_errors(sc, i, status);
551                               drop = 1;
552                     }
553 
554 #if I82586_DEBUG
555                     if ((status & IE_FD_BUSY) != 0)
556                               printf("%s: rint: frame(%d) busy; status=0x%x\n",
557                                         device_xname(sc->sc_dev), i, status);
558 #endif
559 
560 
561                     /*
562                      * Advance the RFD list, since we're done with
563                      * this descriptor.
564                      */
565 
566                     /* Clear frame status */
567                     sc->ie_bus_write16(sc, off, 0);
568 
569                     /* Put fence at this frame (the head) */
570                     off = IE_RFRAME_LAST(sc->rframes, i);
571                     sc->ie_bus_write16(sc, off, IE_FD_EOL | IE_FD_SUSP);
572 
573                     /* and clear RBD field */
574                     off = IE_RFRAME_BUFDESC(sc->rframes, i);
575                     sc->ie_bus_write16(sc, off, 0xffff);
576 
577                     /* Remove fence from current tail */
578                     off = IE_RFRAME_LAST(sc->rframes, sc->rftail);
579                     sc->ie_bus_write16(sc, off, 0);
580 
581                     if (++sc->rftail == sc->nframes)
582                               sc->rftail = 0;
583                     if (++sc->rfhead == sc->nframes)
584                               sc->rfhead = 0;
585 
586                     /* Pull the frame off the board */
587                     if (drop) {
588                               i82586_drop_frames(sc);
589                               if ((status & IE_FD_RNR) != 0)
590                                         sc->rnr_expect = 1;
591                               if_statinc(&sc->sc_ethercom.ec_if, if_ierrors);
592                     } else if (ie_readframe(sc, i) != 0)
593                               return (1);
594           }
595 
596           if ((scbstatus & IE_ST_RNR) != 0) {
597 
598                     /*
599                      * Receiver went "Not Ready". We try to figure out
600                      * whether this was an expected event based on past
601                      * frame status values.
602                      */
603 
604                     if ((scbstatus & IE_RUS_SUSPEND) != 0) {
605                               /*
606                                * We use the "suspend on last frame" flag.
607                                * Send a RU RESUME command in response, since
608                                * we should have dealt with all completed frames
609                                * by now.
610                                */
611                               printf("RINT: SUSPENDED; scbstatus=0x%x\n",
612                                         scbstatus);
613                               if (i82586_start_cmd(sc, IE_RUC_RESUME, 0, 0, 0) == 0)
614                                         return (0);
615                               aprint_error_dev(sc->sc_dev,
616                                   "RU RESUME command timed out\n");
617                               return (1);         /* Ask for a reset */
618                     }
619 
620                     if (sc->rnr_expect != 0) {
621                               /*
622                                * The RNR condition was announced in the previously
623                                * completed frame.  Assume the receive ring is Ok,
624                                * so restart the receiver without further delay.
625                                */
626                               i82586_start_transceiver(sc);
627                               sc->rnr_expect = 0;
628                               return (0);
629 
630                     } else if ((scbstatus & IE_RUS_NOSPACE) != 0) {
631                               /*
632                                * We saw no previous IF_FD_RNR flag.
633                                * We check our ring invariants and, if ok,
634                                * just restart the receiver at the current
635                                * point in the ring.
636                                */
637                               if (i82586_chk_rx_ring(sc) != 0)
638                                         return (1);
639 
640                               i82586_start_transceiver(sc);
641                               if_statinc(&sc->sc_ethercom.ec_if, if_ierrors);
642                               return (0);
643                     } else
644                               printf("%s: receiver not ready; scbstatus=0x%x\n",
645                                         device_xname(sc->sc_dev), scbstatus);
646 
647                     if_statinc(&sc->sc_ethercom.ec_if, if_ierrors);
648                     return (1);         /* Ask for a reset */
649           }
650 
651           return (0);
652 }
653 
654 /*
655  * Process a command-complete interrupt.  These are only generated by the
656  * transmission of frames.  This routine is deceptively simple, since most
657  * of the real work is done by i82586_start().
658  */
659 int
i82586_tint(struct ie_softc * sc,int scbstatus)660 i82586_tint(struct ie_softc *sc, int scbstatus)
661 {
662           struct ifnet *ifp = &sc->sc_ethercom.ec_if;
663           int status;
664 
665           ifp->if_timer = 0;
666 
667 #if I82586_DEBUG
668           if (sc->xmit_busy <= 0) {
669               printf("i82586_tint: WEIRD: xmit_busy=%d, xctail=%d, xchead=%d\n",
670                        sc->xmit_busy, sc->xctail, sc->xchead);
671                     return (0);
672           }
673 #endif
674 
675           status = sc->ie_bus_read16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds,
676                                                                         sc->xctail));
677 
678 #if I82586_DEBUG
679           if (sc->sc_debug & IED_TINT)
680                     printf("%s: tint: SCB status 0x%x; xmit status 0x%x\n",
681                               device_xname(sc->sc_dev), scbstatus, status);
682 #endif
683 
684           if ((status & IE_STAT_COMPL) == 0 || (status & IE_STAT_BUSY)) {
685               printf("i82586_tint: command still busy; status=0x%x; tail=%d\n",
686                        status, sc->xctail);
687               printf("iestatus = 0x%x\n", scbstatus);
688           }
689 
690           if (status & IE_STAT_OK) {
691                     if_statadd2(ifp, if_opackets, 1,
692                         if_collisions, status & IE_XS_MAXCOLL);
693           } else {
694                     if_statinc(ifp, if_oerrors);
695                     /*
696                      * Check SQE and DEFERRED?
697                      * What if more than one bit is set?
698                      */
699                     if (status & IE_STAT_ABORT)
700                               aprint_error_dev(sc->sc_dev, "send aborted\n");
701                     else if (status & IE_XS_NOCARRIER)
702                               aprint_error_dev(sc->sc_dev, "no carrier\n");
703                     else if (status & IE_XS_LOSTCTS)
704                               aprint_error_dev(sc->sc_dev, "lost CTS\n");
705                     else if (status & IE_XS_UNDERRUN)
706                               aprint_error_dev(sc->sc_dev, "DMA underrun\n");
707                     else if (status & IE_XS_EXCMAX) {
708                               aprint_error_dev(sc->sc_dev, "too many collisions\n");
709                               if_statadd(&sc->sc_ethercom.ec_if, if_collisions, 16);
710                     }
711           }
712 
713           /*
714            * If multicast addresses were added or deleted while transmitting,
715            * ie_mc_reset() set the want_mcsetup flag indicating that we
716            * should do it.
717            */
718           if (sc->want_mcsetup) {
719                     ie_mc_setup(sc, IE_XBUF_ADDR(sc, sc->xctail));
720                     sc->want_mcsetup = 0;
721           }
722 
723           /* Done with the buffer. */
724           sc->xmit_busy--;
725           sc->xctail = (sc->xctail + 1) % NTXBUF;
726 
727           /* Start the next packet, if any, transmitting. */
728           if (sc->xmit_busy > 0)
729                     iexmit(sc);
730 
731           if_schedule_deferred_start(ifp);
732           return (0);
733 }
734 
735 /*
736  * Get a range of receive buffer descriptors that represent one packet.
737  */
738 static int
i82586_get_rbd_list(struct ie_softc * sc,uint16_t * start,uint16_t * end,int * pktlen)739 i82586_get_rbd_list(struct ie_softc *sc, uint16_t *start, uint16_t *end,
740     int *pktlen)
741 {
742           int       off, rbbase = sc->rbds;
743           int       rbindex, count = 0;
744           int       plen = 0;
745           int       rbdstatus;
746 
747           *start = rbindex = sc->rbhead;
748 
749           do {
750                     off = IE_RBD_STATUS(rbbase, rbindex);
751                     IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
752                     rbdstatus = sc->ie_bus_read16(sc, off);
753                     if ((rbdstatus & IE_RBD_USED) == 0) {
754                               /*
755                                * This means we are somehow out of sync.  So, we
756                                * reset the adapter.
757                                */
758 #if I82586_DEBUG
759                               print_rbd(sc, rbindex);
760 #endif
761                               log(LOG_ERR,
762                                   "%s: receive descriptors out of sync at %d\n",
763                                   device_xname(sc->sc_dev), rbindex);
764                               return (0);
765                     }
766                     plen += (rbdstatus & IE_RBD_CNTMASK);
767 
768                     if (++rbindex == sc->nrxbuf)
769                               rbindex = 0;
770 
771                     ++count;
772           } while ((rbdstatus & IE_RBD_LAST) == 0);
773           *end = rbindex;
774           *pktlen = plen;
775           return (count);
776 }
777 
778 
779 /*
780  * Release a range of receive buffer descriptors after we've copied the packet.
781  */
782 static void
i82586_release_rbd_list(struct ie_softc * sc,uint16_t start,uint16_t end)783 i82586_release_rbd_list(struct ie_softc *sc, uint16_t start, uint16_t end)
784 {
785           int       off, rbbase = sc->rbds;
786           int       rbindex = start;
787 
788           do {
789                     /* Clear buffer status */
790                     off = IE_RBD_STATUS(rbbase, rbindex);
791                     sc->ie_bus_write16(sc, off, 0);
792                     if (++rbindex == sc->nrxbuf)
793                               rbindex = 0;
794           } while (rbindex != end);
795 
796           /* Mark EOL at new tail */
797           rbindex = ((rbindex == 0) ? sc->nrxbuf : rbindex) - 1;
798           off = IE_RBD_BUFLEN(rbbase, rbindex);
799           sc->ie_bus_write16(sc, off, IE_RBUF_SIZE | IE_RBD_EOL);
800 
801           /* Remove EOL from current tail */
802           off = IE_RBD_BUFLEN(rbbase, sc->rbtail);
803           sc->ie_bus_write16(sc, off, IE_RBUF_SIZE);
804 
805           /* New head & tail pointer */
806 /* hmm, why have both? head is always (tail + 1) % NRXBUF */
807           sc->rbhead = end;
808           sc->rbtail = rbindex;
809 }
810 
811 /*
812  * Drop the packet at the head of the RX buffer ring.
813  * Called if the frame descriptor reports an error on this packet.
814  * Returns 1 if the buffer descriptor ring appears to be corrupt;
815  * and 0 otherwise.
816  */
817 static int
i82586_drop_frames(struct ie_softc * sc)818 i82586_drop_frames(struct ie_softc *sc)
819 {
820           uint16_t bstart, bend;
821           int pktlen;
822 
823           if (i82586_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0)
824                     return (1);
825           i82586_release_rbd_list(sc, bstart, bend);
826           return (0);
827 }
828 
829 /*
830  * Check the RX frame & buffer descriptor lists for our invariants,
831  * i.e.: EOL bit set iff. it is pointed at by the r*tail pointer.
832  *
833  * Called when the receive unit has stopped unexpectedly.
834  * Returns 1 if an inconsistency is detected; 0 otherwise.
835  *
836  * The Receive Unit is expected to be NOT RUNNING.
837  */
838 static int
i82586_chk_rx_ring(struct ie_softc * sc)839 i82586_chk_rx_ring(struct ie_softc *sc)
840 {
841           int n, off, val;
842 
843           for (n = 0; n < sc->nrxbuf; n++) {
844                     off = IE_RBD_BUFLEN(sc->rbds, n);
845                     val = sc->ie_bus_read16(sc, off);
846                     if ((n == sc->rbtail) ^ ((val & IE_RBD_EOL) != 0)) {
847                               /* `rbtail' and EOL flag out of sync */
848                               log(LOG_ERR,
849                                   "%s: rx buffer descriptors out of sync at %d\n",
850                                   device_xname(sc->sc_dev), n);
851                               return (1);
852                     }
853 
854                     /* Take the opportunity to clear the status fields here ? */
855           }
856 
857           for (n = 0; n < sc->nframes; n++) {
858                     off = IE_RFRAME_LAST(sc->rframes, n);
859                     val = sc->ie_bus_read16(sc, off);
860                     if ((n == sc->rftail) ^ ((val & (IE_FD_EOL | IE_FD_SUSP))
861                         != 0)) {
862                               /* `rftail' and EOL flag out of sync */
863                               log(LOG_ERR,
864                                   "%s: rx frame list out of sync at %d\n",
865                                   device_xname(sc->sc_dev), n);
866                               return (1);
867                     }
868           }
869 
870           return (0);
871 }
872 
873 /*
874  * Read data off the interface, and turn it into an mbuf chain.
875  *
876  * This code is DRAMATICALLY different from the previous version; this
877  * version tries to allocate the entire mbuf chain up front, given the
878  * length of the data available.  This enables us to allocate mbuf
879  * clusters in many situations where before we would have had a long
880  * chain of partially-full mbufs.  This should help to speed up the
881  * operation considerably.  (Provided that it works, of course.)
882  */
883 static inline struct mbuf *
ieget(struct ie_softc * sc,int head,int totlen)884 ieget(struct ie_softc *sc, int head, int totlen)
885 {
886           struct mbuf *m, *m0, *newm;
887           int len, resid;
888           int thisrboff, thismboff;
889           struct ether_header eh;
890 
891           /*
892            * Snarf the Ethernet header.
893            */
894           (sc->memcopyin)(sc, &eh, IE_RBUF_ADDR(sc, head),
895               sizeof(struct ether_header));
896 
897           resid = totlen;
898 
899           MGETHDR(m0, M_DONTWAIT, MT_DATA);
900           if (m0 == 0)
901                     return (0);
902           m_set_rcvif(m0, &sc->sc_ethercom.ec_if);
903           m0->m_pkthdr.len = totlen;
904           len = MHLEN;
905           m = m0;
906 
907           /*
908            * This loop goes through and allocates mbufs for all the data we will
909            * be copying in.  It does not actually do the copying yet.
910            */
911           while (totlen > 0) {
912                     if (totlen >= MINCLSIZE) {
913                               MCLGET(m, M_DONTWAIT);
914                               if ((m->m_flags & M_EXT) == 0)
915                                         goto bad;
916                               len = MCLBYTES;
917                     }
918 
919                     if (m == m0) {
920                               char *newdata = (char *)
921                                   ALIGN(m->m_data + sizeof(struct ether_header)) -
922                                   sizeof(struct ether_header);
923                               len -= newdata - m->m_data;
924                               m->m_data = newdata;
925                     }
926 
927                     m->m_len = len = uimin(totlen, len);
928 
929                     totlen -= len;
930                     if (totlen > 0) {
931                               MGET(newm, M_DONTWAIT, MT_DATA);
932                               if (newm == 0)
933                                         goto bad;
934                               len = MLEN;
935                               m = m->m_next = newm;
936                     }
937           }
938 
939           m = m0;
940           thismboff = 0;
941 
942           /*
943            * Copy the Ethernet header into the mbuf chain.
944            */
945           memcpy(mtod(m, void *), &eh, sizeof(struct ether_header));
946           thismboff = sizeof(struct ether_header);
947           thisrboff = sizeof(struct ether_header);
948           resid -= sizeof(struct ether_header);
949 
950           /*
951            * Now we take the mbuf chain (hopefully only one mbuf most of the
952            * time) and stuff the data into it.  There are no possible failures
953            * at or after this point.
954            */
955           while (resid > 0) {
956                     int thisrblen = IE_RBUF_SIZE - thisrboff,
957                         thismblen = m->m_len - thismboff;
958                     len = uimin(thisrblen, thismblen);
959 
960                     (sc->memcopyin)(sc, mtod(m, char *) + thismboff,
961                                         IE_RBUF_ADDR(sc, head) + thisrboff,
962                                         (u_int)len);
963                     resid -= len;
964 
965                     if (len == thismblen) {
966                               m = m->m_next;
967                               thismboff = 0;
968                     } else
969                               thismboff += len;
970 
971                     if (len == thisrblen) {
972                               if (++head == sc->nrxbuf)
973                                         head = 0;
974                               thisrboff = 0;
975                     } else
976                               thisrboff += len;
977           }
978 
979           /*
980            * Unless something changed strangely while we were doing the copy,
981            * we have now copied everything in from the shared memory.
982            * This means that we are done.
983            */
984           return (m0);
985 
986 bad:
987           m_freem(m0);
988           return (0);
989 }
990 
991 /*
992  * Read frame NUM from unit UNIT (pre-cached as IE).
993  *
994  * This routine reads the RFD at NUM, and copies in the buffers from the list
995  * of RBD, then rotates the RBD list so that the receiver doesn't start
996  * complaining.  Trailers are DROPPED---there's no point in wasting time
997  * on confusing code to deal with them.  Hopefully, this machine will
998  * never ARP for trailers anyway.
999  */
1000 static int
ie_readframe(struct ie_softc * sc,int num)1001 ie_readframe(
1002     struct ie_softc *sc,
1003     int num)                  /* frame number to read */
1004 {
1005           struct mbuf *m;
1006           uint16_t bstart, bend;
1007           int pktlen;
1008 
1009           if (i82586_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0) {
1010                     if_statinc(&sc->sc_ethercom.ec_if, if_ierrors);
1011                     return (1);
1012           }
1013 
1014           m = ieget(sc, bstart, pktlen);
1015           i82586_release_rbd_list(sc, bstart, bend);
1016 
1017           if (m == 0) {
1018                     if_statinc(&sc->sc_ethercom.ec_if, if_ierrors);
1019                     return (0);
1020           }
1021 
1022 #if I82586_DEBUG
1023           if (sc->sc_debug & IED_READFRAME) {
1024                     struct ether_header *eh = mtod(m, struct ether_header *);
1025 
1026                     printf("%s: frame from ether %s type 0x%x len %d\n",
1027                               device_xname(sc->sc_dev),
1028                               ether_sprintf(eh->ether_shost),
1029                               (u_int)ntohs(eh->ether_type),
1030                               pktlen);
1031           }
1032 #endif
1033 
1034           /*
1035            * Finally pass this packet up to higher layers.
1036            */
1037           if_percpuq_enqueue((&sc->sc_ethercom.ec_if)->if_percpuq, m);
1038           return (0);
1039 }
1040 
1041 
1042 /*
1043  * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
1044  * command to the chip to be executed.
1045  */
1046 static inline void
iexmit(struct ie_softc * sc)1047 iexmit(struct ie_softc *sc)
1048 {
1049           int off;
1050           int cur, prev;
1051 
1052           cur = sc->xctail;
1053 
1054 #if I82586_DEBUG
1055           if (sc->sc_debug & IED_XMIT)
1056                     printf("%s: xmit buffer %d\n", device_xname(sc->sc_dev), cur);
1057 #endif
1058 
1059           /*
1060            * Setup the transmit command.
1061            */
1062           sc->ie_bus_write16(sc, IE_CMD_XMIT_DESC(sc->xmit_cmds, cur),
1063                                      IE_XBD_ADDR(sc->xbds, cur));
1064 
1065           sc->ie_bus_write16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds, cur), 0);
1066 
1067           if (sc->do_xmitnopchain) {
1068                     /*
1069                      * Gate this XMIT command to the following NOP
1070                      */
1071                     sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds, cur),
1072                                                IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
1073                     sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
1074                                                IE_CMD_XMIT | IE_CMD_INTR);
1075 
1076                     /*
1077                      * Loopback at following NOP
1078                      */
1079                     sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, cur), 0);
1080                     sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, cur),
1081                                                IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
1082 
1083                     /*
1084                      * Gate preceding NOP to this XMIT command
1085                      */
1086                     prev = (cur + NTXBUF - 1) % NTXBUF;
1087                     sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, prev),
1088                         0);
1089                     sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, prev),
1090                                                IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
1091 
1092                     off = IE_SCB_STATUS(sc->scb);
1093                     IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
1094                     if ((sc->ie_bus_read16(sc, off) & IE_CUS_ACTIVE) == 0) {
1095                               printf("iexmit: CU not active\n");
1096                               i82586_start_transceiver(sc);
1097                     }
1098           } else {
1099                     sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds, cur),
1100                                                0xffff);
1101 
1102                     sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
1103                         IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST);
1104 
1105                     off = IE_SCB_CMDLST(sc->scb);
1106                     sc->ie_bus_write16(sc, off, IE_CMD_XMIT_ADDR(sc->xmit_cmds,
1107                               cur));
1108                     IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
1109 
1110                     if (i82586_start_cmd(sc, IE_CUC_START, 0, 0, 1))
1111                               aprint_error_dev(sc->sc_dev,
1112                                   "iexmit: start xmit command timed out\n");
1113           }
1114 
1115           sc->sc_ethercom.ec_if.if_timer = 5;
1116 }
1117 
1118 
1119 /*
1120  * Start transmission on an interface.
1121  */
1122 void
i82586_start(struct ifnet * ifp)1123 i82586_start(struct ifnet *ifp)
1124 {
1125           struct ie_softc *sc = ifp->if_softc;
1126           struct mbuf *m0, *m;
1127           int       buffer, head, xbase;
1128           u_short   len;
1129           int       s;
1130 
1131           if ((ifp->if_flags & IFF_RUNNING) != IFF_RUNNING)
1132                     return;
1133 
1134           while (sc->xmit_busy < NTXBUF) {
1135                     head = sc->xchead;
1136                     xbase = sc->xbds;
1137 
1138                     IFQ_DEQUEUE(&ifp->if_snd, m0);
1139                     if (m0 == 0)
1140                               break;
1141 
1142                     /* We need to use m->m_pkthdr.len, so require the header */
1143                     if ((m0->m_flags & M_PKTHDR) == 0)
1144                               panic("i82586_start: no header mbuf");
1145 
1146                     /* Tap off here if there is a BPF listener. */
1147                     bpf_mtap(ifp, m0, BPF_D_OUT);
1148 
1149 #if I82586_DEBUG
1150                     if (sc->sc_debug & IED_ENQ)
1151                               printf("%s: fill buffer %d\n", device_xname(sc->sc_dev),
1152                                         sc->xchead);
1153 #endif
1154 
1155                     if (m0->m_pkthdr.len > IE_TBUF_SIZE)
1156                               printf("%s: tbuf overflow\n", device_xname(sc->sc_dev));
1157 
1158                     buffer = IE_XBUF_ADDR(sc, head);
1159                     for (m = m0; m != 0; m = m->m_next) {
1160                               (sc->memcopyout)(sc, mtod(m,void *), buffer, m->m_len);
1161                               buffer += m->m_len;
1162                     }
1163                     len = m0->m_pkthdr.len;
1164                     if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
1165                               (sc->memcopyout)(sc, padbuf, buffer,
1166                                   ETHER_MIN_LEN - ETHER_CRC_LEN - len);
1167                               buffer += ETHER_MIN_LEN -ETHER_CRC_LEN - len;
1168                               len = ETHER_MIN_LEN - ETHER_CRC_LEN;
1169                     }
1170                     m_freem(m0);
1171 
1172                     /*
1173                      * Setup the transmit buffer descriptor here, while we
1174                      * know the packet's length.
1175                      */
1176                     sc->ie_bus_write16(sc, IE_XBD_FLAGS(xbase, head),
1177                                                len | IE_TBD_EOL);
1178                     sc->ie_bus_write16(sc, IE_XBD_NEXT(xbase, head), 0xffff);
1179                     sc->ie_bus_write24(sc, IE_XBD_BUF(xbase, head),
1180                                                IE_XBUF_ADDR(sc, head));
1181 
1182                     if (++head == NTXBUF)
1183                               head = 0;
1184                     sc->xchead = head;
1185 
1186                     s = splnet();
1187                     /* Start the first packet transmitting. */
1188                     if (sc->xmit_busy == 0)
1189                               iexmit(sc);
1190 
1191                     sc->xmit_busy++;
1192                     splx(s);
1193           }
1194 }
1195 
1196 /*
1197  * Probe IE's ram setup   [ Move all this into MD front-end!? ]
1198  * Use only if SCP and ISCP represent offsets into shared ram space.
1199  */
1200 int
i82586_proberam(struct ie_softc * sc)1201 i82586_proberam(struct ie_softc *sc)
1202 {
1203           int result, off;
1204 
1205           /* Put in 16-bit mode */
1206           off = IE_SCP_BUS_USE(sc->scp);
1207           sc->ie_bus_write16(sc, off, IE_SYSBUS_16BIT);
1208           IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
1209 
1210           /* Set the ISCP `busy' bit */
1211           off = IE_ISCP_BUSY(sc->iscp);
1212           sc->ie_bus_write16(sc, off, 1);
1213           IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
1214 
1215           if (sc->hwreset)
1216                     (sc->hwreset)(sc, CHIP_PROBE);
1217 
1218           (sc->chan_attn) (sc, CHIP_PROBE);
1219 
1220           delay(100);                   /* wait a while... */
1221 
1222           /* Read back the ISCP `busy' bit; it should be clear by now */
1223           off = IE_ISCP_BUSY(sc->iscp);
1224           IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
1225           result = sc->ie_bus_read16(sc, off) == 0;
1226 
1227           /* Acknowledge any interrupts we may have caused. */
1228           ie_ack(sc, IE_ST_WHENCE);
1229 
1230           return (result);
1231 }
1232 
1233 void
i82586_reset(struct ie_softc * sc,int hard)1234 i82586_reset(struct ie_softc *sc, int hard)
1235 {
1236           int s = splnet();
1237 
1238           if (hard)
1239                     printf("%s: reset\n", device_xname(sc->sc_dev));
1240 
1241           sc->sc_ethercom.ec_if.if_timer = 0;
1242 
1243           /*
1244            * Stop i82586 dead in its tracks.
1245            */
1246           if (i82586_start_cmd(sc, IE_RUC_ABORT | IE_CUC_ABORT, 0, 0, 0))
1247                     aprint_error_dev(sc->sc_dev, "abort commands timed out\n");
1248 
1249           /*
1250            * This can really slow down the i82586_reset() on some cards, but it's
1251            * necessary to unwedge other ones (eg, the Sun VME ones) from certain
1252            * lockups.
1253            */
1254           if (hard && sc->hwreset)
1255                     (sc->hwreset)(sc, CARD_RESET);
1256 
1257           delay(100);
1258           ie_ack(sc, IE_ST_WHENCE);
1259 
1260           if ((sc->sc_ethercom.ec_if.if_flags & IFF_UP) != 0) {
1261                     int retries=0;      /* XXX - find out why init sometimes fails */
1262                     while (retries++ < 2)
1263                               if (i82586_init(&sc->sc_ethercom.ec_if) == 0)
1264                                         break;
1265           }
1266 
1267           splx(s);
1268 }
1269 
1270 
1271 static void
setup_simple_command(struct ie_softc * sc,int cmd,int cmdbuf)1272 setup_simple_command(struct ie_softc *sc, int cmd, int cmdbuf)
1273 {
1274           /* Setup a simple command */
1275           sc->ie_bus_write16(sc, IE_CMD_COMMON_STATUS(cmdbuf), 0);
1276           sc->ie_bus_write16(sc, IE_CMD_COMMON_CMD(cmdbuf), cmd | IE_CMD_LAST);
1277           sc->ie_bus_write16(sc, IE_CMD_COMMON_LINK(cmdbuf), 0xffff);
1278 
1279           /* Assign the command buffer to the SCB command list */
1280           sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb), cmdbuf);
1281 }
1282 
1283 /*
1284  * Run the time-domain reflectometer.
1285  */
1286 static void
ie_run_tdr(struct ie_softc * sc,int cmd)1287 ie_run_tdr(struct ie_softc *sc, int cmd)
1288 {
1289           int result;
1290 
1291           setup_simple_command(sc, IE_CMD_TDR, cmd);
1292           sc->ie_bus_write16(sc, IE_CMD_TDR_TIME(cmd), 0);
1293 
1294           if (i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0) ||
1295               (sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd)) & IE_STAT_OK) == 0)
1296                     result = 0x10000; /* XXX */
1297           else
1298                     result = sc->ie_bus_read16(sc, IE_CMD_TDR_TIME(cmd));
1299 
1300           /* Squash any pending interrupts */
1301           ie_ack(sc, IE_ST_WHENCE);
1302 
1303           if (result & IE_TDR_SUCCESS)
1304                     return;
1305 
1306           if (result & 0x10000)
1307                     aprint_error_dev(sc->sc_dev, "TDR command failed\n");
1308           else if (result & IE_TDR_XCVR)
1309                     aprint_error_dev(sc->sc_dev, "transceiver problem\n");
1310           else if (result & IE_TDR_OPEN)
1311                     aprint_error_dev(sc->sc_dev, "TDR detected incorrect "
1312                         "termination %d clocks away\n", result & IE_TDR_TIME);
1313           else if (result & IE_TDR_SHORT)
1314                     aprint_error_dev(sc->sc_dev, "TDR detected a short circuit "
1315                         "%d clocks away\n", result & IE_TDR_TIME);
1316           else
1317                     aprint_error_dev(sc->sc_dev,
1318                         "TDR returned unknown status 0x%x\n", result);
1319 }
1320 
1321 
1322 /*
1323  * i82586_setup_bufs: set up the buffers
1324  *
1325  * We have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
1326  * this is to be used for the buffers.  The chip indexes its control data
1327  * structures with 16 bit offsets, and it indexes actual buffers with
1328  * 24 bit addresses.   So we should allocate control buffers first so that
1329  * we don't overflow the 16 bit offset field.   The number of transmit
1330  * buffers is fixed at compile time.
1331  *
1332  */
1333 static void
i82586_setup_bufs(struct ie_softc * sc)1334 i82586_setup_bufs(struct ie_softc *sc)
1335 {
1336           int       ptr = sc->buf_area; /* memory pool */
1337           int       n, r;
1338 
1339           /*
1340            * step 0: zero memory and figure out how many recv buffers and
1341            * frames we can have.
1342            */
1343           ptr = (ptr + 3) & ~3;         /* set alignment and stick with it */
1344 
1345 
1346           /*
1347            *  step 1: lay out data structures in the shared-memory area
1348            */
1349 
1350           /* The no-op commands; used if "nop-chaining" is in effect */
1351           sc->nop_cmds = ptr;
1352           ptr += NTXBUF * IE_CMD_NOP_SZ;
1353 
1354           /* The transmit commands */
1355           sc->xmit_cmds = ptr;
1356           ptr += NTXBUF * IE_CMD_XMIT_SZ;
1357 
1358           /* The transmit buffers descriptors */
1359           sc->xbds = ptr;
1360           ptr += NTXBUF * IE_XBD_SZ;
1361 
1362           /* The transmit buffers */
1363           sc->xbufs = ptr;
1364           ptr += NTXBUF * IE_TBUF_SIZE;
1365 
1366           ptr = (ptr + 3) & ~3;                   /* re-align.. just in case */
1367 
1368           /* Compute free space for RECV stuff */
1369           n = sc->buf_area_sz - (ptr - sc->buf_area);
1370 
1371           /* Compute size of one RECV frame */
1372           r = IE_RFRAME_SZ + ((IE_RBD_SZ + IE_RBUF_SIZE) * B_PER_F);
1373 
1374           sc->nframes = n / r;
1375 
1376           if (sc->nframes <= 0)
1377                     panic("ie: bogus buffer calc");
1378 
1379           sc->nrxbuf = sc->nframes * B_PER_F;
1380 
1381           /* The receive frame descriptors */
1382           sc->rframes = ptr;
1383           ptr += sc->nframes * IE_RFRAME_SZ;
1384 
1385           /* The receive buffer descriptors */
1386           sc->rbds = ptr;
1387           ptr += sc->nrxbuf * IE_RBD_SZ;
1388 
1389           /* The receive buffers */
1390           sc->rbufs = ptr;
1391           ptr += sc->nrxbuf * IE_RBUF_SIZE;
1392 
1393 #if I82586_DEBUG
1394           printf("%s: %d frames %d bufs\n", device_xname(sc->sc_dev),
1395               sc->nframes, sc->nrxbuf);
1396 #endif
1397 
1398           /*
1399            * step 2: link together the recv frames and set EOL on last one
1400            */
1401           for (n = 0; n < sc->nframes; n++) {
1402                     int m = (n == sc->nframes - 1) ? 0 : n + 1;
1403 
1404                     /* Clear status */
1405                     sc->ie_bus_write16(sc, IE_RFRAME_STATUS(sc->rframes, n), 0);
1406 
1407                     /* RBD link = NULL */
1408                     sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes, n),
1409                                                0xffff);
1410 
1411                     /* Make a circular list */
1412                     sc->ie_bus_write16(sc, IE_RFRAME_NEXT(sc->rframes, n),
1413                                                IE_RFRAME_ADDR(sc->rframes, m));
1414 
1415                     /* Mark last as EOL */
1416                     sc->ie_bus_write16(sc, IE_RFRAME_LAST(sc->rframes, n),
1417                                                ((m==0)? (IE_FD_EOL | IE_FD_SUSP) : 0));
1418           }
1419 
1420           /*
1421            * step 3: link the RBDs and set EOL on last one
1422            */
1423           for (n = 0; n < sc->nrxbuf; n++) {
1424                     int m = (n == sc->nrxbuf - 1) ? 0 : n + 1;
1425 
1426                     /* Clear status */
1427                     sc->ie_bus_write16(sc, IE_RBD_STATUS(sc->rbds, n), 0);
1428 
1429                     /* Make a circular list */
1430                     sc->ie_bus_write16(sc, IE_RBD_NEXT(sc->rbds, n),
1431                                                IE_RBD_ADDR(sc->rbds, m));
1432 
1433                     /* Link to data buffers */
1434                     sc->ie_bus_write24(sc, IE_RBD_BUFADDR(sc->rbds, n),
1435                                                IE_RBUF_ADDR(sc, n));
1436                     sc->ie_bus_write16(sc, IE_RBD_BUFLEN(sc->rbds, n),
1437                                                IE_RBUF_SIZE | ((m==0)?IE_RBD_EOL:0));
1438           }
1439 
1440           /*
1441            * step 4: all xmit no-op commands loopback onto themselves
1442            */
1443           for (n = 0; n < NTXBUF; n++) {
1444                     sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, n), 0);
1445 
1446                     sc->ie_bus_write16(sc, IE_CMD_NOP_CMD(sc->nop_cmds, n),
1447                                                    IE_CMD_NOP);
1448 
1449                     sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, n),
1450                                                    IE_CMD_NOP_ADDR(sc->nop_cmds, n));
1451           }
1452 
1453 
1454           /*
1455            * step 6: set the head and tail pointers on receive to keep track of
1456            * the order in which RFDs and RBDs are used.
1457            */
1458 
1459           /* Pointers to last packet sent and next available transmit buffer. */
1460           sc->xchead = sc->xctail = 0;
1461 
1462           /* Clear transmit-busy flag and set number of free transmit buffers. */
1463           sc->xmit_busy = 0;
1464 
1465           /*
1466            * Pointers to first and last receive frame.
1467            * The RFD pointed to by rftail is the only one that has EOL set.
1468            */
1469           sc->rfhead = 0;
1470           sc->rftail = sc->nframes - 1;
1471 
1472           /*
1473            * Pointers to first and last receive descriptor buffer.
1474            * The RBD pointed to by rbtail is the only one that has EOL set.
1475            */
1476           sc->rbhead = 0;
1477           sc->rbtail = sc->nrxbuf - 1;
1478 
1479 /* link in recv frames * and buffer into the scb. */
1480 #if I82586_DEBUG
1481           printf("%s: reserved %d bytes\n",
1482                     device_xname(sc->sc_dev), ptr - sc->buf_area);
1483 #endif
1484 }
1485 
1486 static int
ie_cfg_setup(struct ie_softc * sc,int cmd,int promiscuous,int manchester)1487 ie_cfg_setup(struct ie_softc *sc, int cmd, int promiscuous, int manchester)
1488 {
1489           int cmdresult, status;
1490           uint8_t buf[IE_CMD_CFG_SZ]; /* XXX malloc? */
1491 
1492           *IE_CMD_CFG_CNT(buf)             = 0x0c;
1493           *IE_CMD_CFG_FIFO(buf)            = 8;
1494           *IE_CMD_CFG_SAVEBAD(buf)   = 0x40;
1495           *IE_CMD_CFG_ADDRLEN(buf)   = 0x2e;
1496           *IE_CMD_CFG_PRIORITY(buf)  = 0;
1497           *IE_CMD_CFG_IFS(buf)             = 0x60;
1498           *IE_CMD_CFG_SLOT_LOW(buf)  = 0;
1499           *IE_CMD_CFG_SLOT_HIGH(buf) = 0xf2;
1500           *IE_CMD_CFG_PROMISC(buf)   = (!!promiscuous) | manchester << 2;
1501           *IE_CMD_CFG_CRSCDT(buf)          = 0;
1502           *IE_CMD_CFG_MINLEN(buf)          = 64;
1503           *IE_CMD_CFG_JUNK(buf)            = 0xff;
1504           sc->memcopyout(sc, buf, cmd, IE_CMD_CFG_SZ);
1505           setup_simple_command(sc, IE_CMD_CONFIG, cmd);
1506           IE_BUS_BARRIER(sc, cmd, IE_CMD_CFG_SZ, BUS_SPACE_BARRIER_WRITE);
1507 
1508           cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0);
1509           status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd));
1510           if (cmdresult != 0) {
1511                     aprint_error_dev(sc->sc_dev,
1512                         "configure command timed out; status %x\n", status);
1513                     return (0);
1514           }
1515           if ((status & IE_STAT_OK) == 0) {
1516                     aprint_error_dev(sc->sc_dev,
1517                         "configure command failed; status %x\n", status);
1518                     return (0);
1519           }
1520 
1521           /* Squash any pending interrupts */
1522           ie_ack(sc, IE_ST_WHENCE);
1523           return (1);
1524 }
1525 
1526 static int
ie_ia_setup(struct ie_softc * sc,int cmdbuf)1527 ie_ia_setup(struct ie_softc *sc, int cmdbuf)
1528 {
1529           int cmdresult, status;
1530           struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1531 
1532           setup_simple_command(sc, IE_CMD_IASETUP, cmdbuf);
1533 
1534           (sc->memcopyout)(sc, CLLADDR(ifp->if_sadl),
1535                                IE_CMD_IAS_EADDR(cmdbuf), ETHER_ADDR_LEN);
1536 
1537           cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
1538           status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
1539           if (cmdresult != 0) {
1540                     aprint_error_dev(sc->sc_dev,
1541                         "individual address command timed out; status %x\n",
1542                         status);
1543                     return (0);
1544           }
1545           if ((status & IE_STAT_OK) == 0) {
1546                     aprint_error_dev(sc->sc_dev,
1547                         "individual address command failed; status %x\n", status);
1548                     return (0);
1549           }
1550 
1551           /* Squash any pending interrupts */
1552           ie_ack(sc, IE_ST_WHENCE);
1553           return (1);
1554 }
1555 
1556 /*
1557  * Run the multicast setup command.
1558  * Called at splnet().
1559  */
1560 static int
ie_mc_setup(struct ie_softc * sc,int cmdbuf)1561 ie_mc_setup(struct ie_softc *sc, int cmdbuf)
1562 {
1563           int cmdresult, status;
1564 
1565           if (sc->mcast_count == 0)
1566                     return (1);
1567 
1568           setup_simple_command(sc, IE_CMD_MCAST, cmdbuf);
1569 
1570           (sc->memcopyout)(sc, (void *)sc->mcast_addrs,
1571                                IE_CMD_MCAST_MADDR(cmdbuf),
1572                                sc->mcast_count * ETHER_ADDR_LEN);
1573 
1574           sc->ie_bus_write16(sc, IE_CMD_MCAST_BYTES(cmdbuf),
1575                                      sc->mcast_count * ETHER_ADDR_LEN);
1576 
1577           /* Start the command */
1578           cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL,
1579               0);
1580           status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
1581           if (cmdresult != 0) {
1582                     aprint_error_dev(sc->sc_dev,
1583                         "multicast setup command timed out; status %x\n", status);
1584                     return (0);
1585           }
1586           if ((status & IE_STAT_OK) == 0) {
1587                     aprint_error_dev(sc->sc_dev,
1588                         "multicast setup command failed; status %x\n", status);
1589                     return (0);
1590           }
1591 
1592           /* Squash any pending interrupts */
1593           ie_ack(sc, IE_ST_WHENCE);
1594           return (1);
1595 }
1596 
1597 /*
1598  * This routine takes the environment generated by check_ie_present() and adds
1599  * to it all the other structures we need to operate the adapter.  This
1600  * includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, starting
1601  * the receiver unit, and clearing interrupts.
1602  *
1603  * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
1604  */
1605 int
i82586_init(struct ifnet * ifp)1606 i82586_init(struct ifnet *ifp)
1607 {
1608           struct ie_softc *sc = ifp->if_softc;
1609           int cmd;
1610 
1611           sc->async_cmd_inprogress = 0;
1612 
1613           cmd = sc->buf_area;
1614 
1615           /*
1616            * Send the configure command first.
1617            */
1618           if (ie_cfg_setup(sc, cmd, sc->promisc, 0) == 0)
1619                     return EIO;
1620 
1621           /*
1622            * Send the Individual Address Setup command.
1623            */
1624           if (ie_ia_setup(sc, cmd) == 0)
1625                     return EIO;
1626 
1627           /*
1628            * Run the time-domain reflectometer.
1629            */
1630           ie_run_tdr(sc, cmd);
1631 
1632           /*
1633            * Set the multi-cast filter, if any
1634            */
1635           if (ie_mc_setup(sc, cmd) == 0)
1636                     return EIO;
1637 
1638           /*
1639            * Acknowledge any interrupts we have generated thus far.
1640            */
1641           ie_ack(sc, IE_ST_WHENCE);
1642 
1643           /*
1644            * Set up the transmit and recv buffers.
1645            */
1646           i82586_setup_bufs(sc);
1647 
1648           if (sc->hwinit)
1649                     (sc->hwinit)(sc);
1650 
1651           ifp->if_flags |= IFF_RUNNING;
1652 
1653           if (NTXBUF < 2)
1654                     sc->do_xmitnopchain = 0;
1655 
1656           i82586_start_transceiver(sc);
1657           return (0);
1658 }
1659 
1660 /*
1661  * Start the RU and possibly the CU unit
1662  */
1663 static void
i82586_start_transceiver(struct ie_softc * sc)1664 i82586_start_transceiver(struct ie_softc *sc)
1665 {
1666 
1667           /*
1668            * Start RU at current position in frame & RBD lists.
1669            */
1670           sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes, sc->rfhead),
1671                                      IE_RBD_ADDR(sc->rbds, sc->rbhead));
1672 
1673           sc->ie_bus_write16(sc, IE_SCB_RCVLST(sc->scb),
1674                                      IE_RFRAME_ADDR(sc->rframes, sc->rfhead));
1675 
1676           if (sc->do_xmitnopchain) {
1677                     /* Stop transmit command chain */
1678                     if (i82586_start_cmd(sc, IE_CUC_SUSPEND | IE_RUC_SUSPEND,
1679                         0, 0, 0))
1680                               aprint_error_dev(sc->sc_dev,
1681                                   "CU/RU stop command timed out\n");
1682 
1683                     /* Start the receiver & transmitter chain */
1684                     /* sc->scb->ie_command_list =
1685                               IEADDR(sc->nop_cmds[(sc->xctail+NTXBUF-1) % NTXBUF]);*/
1686                     sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb),
1687                                            IE_CMD_NOP_ADDR(
1688                                                   sc->nop_cmds,
1689                                                   (sc->xctail + NTXBUF - 1) % NTXBUF));
1690 
1691                     if (i82586_start_cmd(sc, IE_CUC_START | IE_RUC_START, 0, 0, 0))
1692                               aprint_error_dev(sc->sc_dev,
1693                                   "CU/RU command timed out\n");
1694           } else {
1695                     if (i82586_start_cmd(sc, IE_RUC_START, 0, 0, 0))
1696                               aprint_error_dev(sc->sc_dev, "RU command timed out\n");
1697           }
1698 }
1699 
1700 void
i82586_stop(struct ifnet * ifp,int disable)1701 i82586_stop(struct ifnet *ifp, int disable)
1702 {
1703           struct ie_softc *sc = ifp->if_softc;
1704 
1705           if (i82586_start_cmd(sc, IE_RUC_SUSPEND | IE_CUC_SUSPEND, 0, 0, 0))
1706                     aprint_error_dev(sc->sc_dev,
1707                         "iestop: disable commands timed out\n");
1708 }
1709 
1710 int
i82586_ioctl(struct ifnet * ifp,unsigned long cmd,void * data)1711 i82586_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
1712 {
1713           struct ie_softc *sc = ifp->if_softc;
1714           int s, error = 0;
1715 
1716           s = splnet();
1717           switch (cmd) {
1718           default:
1719                     error = ether_ioctl(ifp, cmd, data);
1720                     if (error == ENETRESET) {
1721                               /*
1722                                * Multicast list has changed; set the hardware filter
1723                                * accordingly.
1724                                */
1725                               if (ifp->if_flags & IFF_RUNNING)
1726                                         ie_mc_reset(sc);
1727                               error = 0;
1728                     }
1729                     break;
1730           }
1731 #if I82586_DEBUG
1732           if (cmd == SIOCSIFFLAGS)
1733                     sc->sc_debug = (ifp->if_flags & IFF_DEBUG) ? IED_ALL : 0;
1734 #endif
1735           splx(s);
1736           return (error);
1737 }
1738 
1739 static void
ie_mc_reset(struct ie_softc * sc)1740 ie_mc_reset(struct ie_softc *sc)
1741 {
1742           struct ethercom *ec = &sc->sc_ethercom;
1743           struct ether_multi *enm;
1744           struct ether_multistep step;
1745           int size;
1746 
1747           /*
1748            * Step through the list of addresses.
1749            */
1750 again:
1751           size = 0;
1752           sc->mcast_count = 0;
1753           ETHER_LOCK(ec);
1754           ETHER_FIRST_MULTI(step, ec, enm);
1755           while (enm) {
1756                     size += 6;
1757                     if (sc->mcast_count >= IE_MAXMCAST ||
1758                         memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
1759                               ec->ec_if.if_flags |= IFF_ALLMULTI;
1760                               i82586_ioctl(&ec->ec_if, SIOCSIFFLAGS, NULL);
1761                               ETHER_UNLOCK(ec);
1762                               return;
1763                     }
1764                     ETHER_NEXT_MULTI(step, enm);
1765           }
1766           ETHER_UNLOCK(ec);
1767 
1768           if (size > sc->mcast_addrs_size) {
1769                     /* Need to allocate more space */
1770                     if (sc->mcast_addrs_size)
1771                               free(sc->mcast_addrs, M_IFMADDR);
1772                     sc->mcast_addrs = (char *)
1773                               malloc(size, M_IFMADDR, M_WAITOK);
1774                     sc->mcast_addrs_size = size;
1775           }
1776 
1777           /*
1778            * We've got the space; now copy the addresses
1779            */
1780           ETHER_LOCK(ec);
1781           ETHER_FIRST_MULTI(step, ec, enm);
1782           while (enm) {
1783                     if (sc->mcast_count >= IE_MAXMCAST) {
1784                               ETHER_UNLOCK(ec);
1785                               goto again; /* Just in case */
1786                     }
1787 
1788                     memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo, 6);
1789                     sc->mcast_count++;
1790                     ETHER_NEXT_MULTI(step, enm);
1791           }
1792           ETHER_UNLOCK(ec);
1793           sc->want_mcsetup = 1;
1794 }
1795 
1796 /*
1797  * Media change callback.
1798  */
1799 int
i82586_mediachange(struct ifnet * ifp)1800 i82586_mediachange(struct ifnet *ifp)
1801 {
1802           struct ie_softc *sc = ifp->if_softc;
1803 
1804           if (sc->sc_mediachange)
1805                     return ((*sc->sc_mediachange)(sc));
1806           return (0);
1807 }
1808 
1809 /*
1810  * Media status callback.
1811  */
1812 void
i82586_mediastatus(struct ifnet * ifp,struct ifmediareq * ifmr)1813 i82586_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1814 {
1815           struct ie_softc *sc = ifp->if_softc;
1816 
1817           if (sc->sc_mediastatus)
1818                     (*sc->sc_mediastatus)(sc, ifmr);
1819 }
1820 
1821 #if I82586_DEBUG
1822 void
print_rbd(struct ie_softc * sc,int n)1823 print_rbd(struct ie_softc *sc, int n)
1824 {
1825 
1826           printf("RBD at %08x:\n        status %04x, next %04x, buffer %lx\n"
1827                     "length/EOL %04x\n", IE_RBD_ADDR(sc->rbds, n),
1828                     sc->ie_bus_read16(sc, IE_RBD_STATUS(sc->rbds, n)),
1829                     sc->ie_bus_read16(sc, IE_RBD_NEXT(sc->rbds, n)),
1830                     (u_long)0,/*bus_space_read_4(sc->bt, sc->bh, IE_RBD_BUFADDR(sc->rbds,n)),-* XXX */
1831                     sc->ie_bus_read16(sc, IE_RBD_BUFLEN(sc->rbds, n)));
1832 }
1833 #endif
1834