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