1 /* $NetBSD: if_de.c,v 1.26 2009/04/18 14:58:03 tsutsui Exp $ */
4 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * @(#)if_de.c 7.12 (Berkeley) 12/16/90
36 * Copyright (c) 2000 Ludd, University of Lule}, Sweden.
37 * All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by the University of
51 * California, Berkeley and its contributors.
52 * 4. Neither the name of the University nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * @(#)if_de.c 7.12 (Berkeley) 12/16/90
77 * Rewritten by Ragge 30 April 2000 to match new world.
80 * timeout routine (get statistics)
83 #include <sys/cdefs.h>
84 __KERNEL_RCSID(0, "$NetBSD: if_de.c,v 1.26 2009/04/18 14:58:03 tsutsui Exp $");
89 #include <sys/param.h>
90 #include <sys/systm.h>
93 #include <sys/protosw.h>
94 #include <sys/socket.h>
95 #include <sys/ioctl.h>
96 #include <sys/errno.h>
97 #include <sys/syslog.h>
98 #include <sys/device.h>
101 #include <net/if_ether.h>
102 #include <net/if_dl.h>
105 #include <netinet/in.h>
106 #include <netinet/if_inarp.h>
111 #include <net/bpfdesc.h>
116 #include <dev/qbus/ubavar.h>
117 #include <dev/qbus/if_dereg.h>
118 #include <dev/qbus/if_uba.h>
123 * Be careful with transmit/receive buffers, each entry steals 4 map
124 * registers, and there is only 496 on one unibus...
126 #define NRCV 7 /* number of receive buffers (must be > 1) */
127 #define NXMT 3 /* number of transmit buffers */
130 * Structure containing the elements that must be in DMA-safe memory.
133 /* the following structures are always mapped in */
134 struct de_pcbb dc_pcbb
; /* port control block */
135 struct de_ring dc_xrent
[NXMT
]; /* transmit ring entrys */
136 struct de_ring dc_rrent
[NRCV
]; /* receive ring entrys */
137 struct de_udbbuf dc_udbbuf
; /* UNIBUS data buffer */
138 /* end mapped area */
142 * Ethernet software status per interface.
144 * Each interface is referenced by a network interface structure,
145 * ds_if, which the routing code uses to locate the interface.
146 * This structure contains the output queue for the interface, its address, ...
147 * We also have, for each interface, a UBA interface structure, which
148 * contains information about the UNIBUS resources held by the interface:
149 * map registers, buffered data paths, etc. Information is cached in this
150 * structure for use by the if_uba.c routines in running the interface
154 device_t sc_dev
; /* Configuration common part */
155 struct uba_softc
*sc_uh
; /* our parent */
156 struct evcnt sc_intrcnt
; /* Interrupt counting */
157 struct ethercom sc_ec
; /* Ethernet common part */
158 #define sc_if sc_ec.ec_if /* network-visible interface */
159 bus_space_tag_t sc_iot
;
161 bus_dma_tag_t sc_dmat
;
165 struct de_cdata
*sc_dedata
; /* Control structure */
166 struct de_cdata
*sc_pdedata
; /* Bus-mapped control structure */
167 struct ifubinfo sc_ifuba
; /* UNIBUS resources */
168 struct ifrw sc_ifr
[NRCV
]; /* UNIBUS receive buffer maps */
169 struct ifxmt sc_ifw
[NXMT
]; /* UNIBUS receive buffer maps */
171 int sc_xindex
; /* UNA index into transmit chain */
172 int sc_rindex
; /* UNA index into receive chain */
173 int sc_xfree
; /* index for next transmit buffer */
174 int sc_nxmit
; /* # of transmits in progress */
175 void *sc_sh
; /* shutdownhook cookie */
178 static int dematch(device_t
, cfdata_t
, void *);
179 static void deattach(device_t
, device_t
, void *);
180 static void dewait(struct de_softc
*, const char *);
181 static int deinit(struct ifnet
*);
182 static int deioctl(struct ifnet
*, u_long
, void *);
183 static void dereset(device_t
);
184 static void destop(struct ifnet
*, int);
185 static void destart(struct ifnet
*);
186 static void derecv(struct de_softc
*);
187 static void deintr(void *);
188 static void deshutdown(void *);
190 CFATTACH_DECL_NEW(de
, sizeof(struct de_softc
),
191 dematch
, deattach
, NULL
, NULL
);
193 #define DE_WCSR(csr, val) \
194 bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val)
195 #define DE_WLOW(val) \
196 bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0, val)
197 #define DE_WHIGH(val) \
198 bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0 + 1, val)
199 #define DE_RCSR(csr) \
200 bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr)
202 #define LOWORD(x) ((int)(x) & 0xffff)
203 #define HIWORD(x) (((int)(x) >> 16) & 0x3)
205 * Interface exists: make available by filling in network interface
206 * record. System will initialize the interface when it is ready
207 * to accept packets. We get the ethernet address here.
210 deattach(device_t parent
, device_t self
, void *aux
)
212 struct uba_attach_args
*ua
= aux
;
213 struct de_softc
*sc
= device_private(self
);
214 struct ifnet
*ifp
= &sc
->sc_if
;
215 u_int8_t myaddr
[ETHER_ADDR_LEN
];
220 sc
->sc_uh
= device_private(parent
);
221 sc
->sc_iot
= ua
->ua_iot
;
222 sc
->sc_ioh
= ua
->ua_ioh
;
223 sc
->sc_dmat
= ua
->ua_dmat
;
226 * What kind of a board is this?
227 * The error bits 4-6 in pcsr1 are a device id as long as
228 * the high byte is zero.
230 csr1
= DE_RCSR(DE_PCSR1
);
233 else if (csr1
& 0x10)
239 * Reset the board and temporarily map
240 * the pcbb buffer onto the Unibus.
242 DE_WCSR(DE_PCSR0
, 0); /* reset INTE */
244 DE_WCSR(DE_PCSR0
, PCSR0_RSET
);
247 sc
->sc_ui
.ui_size
= sizeof(struct de_cdata
);
248 if ((error
= ubmemalloc(sc
->sc_uh
, &sc
->sc_ui
, 0)))
249 return printf(": failed ubmemalloc(), error = %d\n", error
);
250 sc
->sc_dedata
= (struct de_cdata
*)sc
->sc_ui
.ui_vaddr
;
253 * Tell the DEUNA about our PCB
255 DE_WCSR(DE_PCSR2
, LOWORD(sc
->sc_ui
.ui_baddr
));
256 DE_WCSR(DE_PCSR3
, HIWORD(sc
->sc_ui
.ui_baddr
));
257 DE_WLOW(CMD_GETPCBB
);
260 sc
->sc_dedata
->dc_pcbb
.pcbb0
= FC_RDPHYAD
;
262 dewait(sc
, "read addr ");
264 memcpy(myaddr
, (void *)&sc
->sc_dedata
->dc_pcbb
.pcbb2
, sizeof (myaddr
));
265 printf(": %s, hardware address %s\n", c
, ether_sprintf(myaddr
));
267 uba_intr_establish(ua
->ua_icookie
, ua
->ua_cvec
, deintr
, sc
,
269 uba_reset_establish(dereset
, sc
->sc_dev
);
270 evcnt_attach_dynamic(&sc
->sc_intrcnt
, EVCNT_TYPE_INTR
, ua
->ua_evcnt
,
271 device_xname(sc
->sc_dev
), "intr");
273 strcpy(ifp
->if_xname
, device_xname(sc
->sc_dev
));
275 ifp
->if_flags
= IFF_BROADCAST
|IFF_SIMPLEX
|IFF_MULTICAST
|IFF_ALLMULTI
;
276 ifp
->if_ioctl
= deioctl
;
277 ifp
->if_start
= destart
;
278 ifp
->if_init
= deinit
;
279 ifp
->if_stop
= destop
;
280 IFQ_SET_READY(&ifp
->if_snd
);
283 ether_ifattach(ifp
, myaddr
);
284 ubmemfree(sc
->sc_uh
, &sc
->sc_ui
);
286 sc
->sc_sh
= shutdownhook_establish(deshutdown
, sc
);
290 destop(struct ifnet
*ifp
, int a
)
292 struct de_softc
*sc
= ifp
->if_softc
;
301 * Reset of interface after UNIBUS reset.
304 dereset(device_t dev
)
306 struct de_softc
*sc
= (void *)dev
;
308 sc
->sc_if
.if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
309 sc
->sc_flags
&= ~DSF_MAPPED
;
310 sc
->sc_pdedata
= NULL
; /* All mappings lost */
311 DE_WCSR(DE_PCSR0
, PCSR0_RSET
);
317 * Initialization of interface; clear recorded pending
318 * operations, and reinitialize UNIBUS usage.
321 deinit(struct ifnet
*ifp
)
323 struct de_softc
*sc
= ifp
->if_softc
;
324 struct de_cdata
*dc
, *pdc
;
330 if (ifp
->if_flags
& IFF_RUNNING
)
332 if ((sc
->sc_flags
& DSF_MAPPED
) == 0) {
333 if (if_ubaminit(&sc
->sc_ifuba
, sc
->sc_uh
, MCLBYTES
,
334 sc
->sc_ifr
, NRCV
, sc
->sc_ifw
, NXMT
)) {
335 aprint_error_dev(sc
->sc_dev
, " can't initialize\n");
336 ifp
->if_flags
&= ~IFF_UP
;
339 sc
->sc_ui
.ui_size
= sizeof(struct de_cdata
);
340 if ((error
= ubmemalloc(sc
->sc_uh
, &sc
->sc_ui
, 0))) {
341 aprint_error(": unable to ubmemalloc(), error = %d\n",
345 sc
->sc_pdedata
= (struct de_cdata
*)sc
->sc_ui
.ui_baddr
;
346 sc
->sc_dedata
= (struct de_cdata
*)sc
->sc_ui
.ui_vaddr
;
347 sc
->sc_flags
|= DSF_MAPPED
;
351 * Tell the DEUNA about our PCB
353 DE_WCSR(DE_PCSR2
, LOWORD(sc
->sc_pdedata
));
354 DE_WCSR(DE_PCSR3
, HIWORD(sc
->sc_pdedata
));
355 DE_WLOW(0); /* reset INTE */
357 DE_WLOW(CMD_GETPCBB
);
361 pdc
= sc
->sc_pdedata
;
362 /* set the transmit and receive ring header addresses */
363 dc
->dc_pcbb
.pcbb0
= FC_WTRING
;
364 dc
->dc_pcbb
.pcbb2
= LOWORD(&pdc
->dc_udbbuf
);
365 dc
->dc_pcbb
.pcbb4
= HIWORD(&pdc
->dc_udbbuf
);
367 dc
->dc_udbbuf
.b_tdrbl
= LOWORD(&pdc
->dc_xrent
[0]);
368 dc
->dc_udbbuf
.b_tdrbh
= HIWORD(&pdc
->dc_xrent
[0]);
369 dc
->dc_udbbuf
.b_telen
= sizeof (struct de_ring
) / sizeof(u_int16_t
);
370 dc
->dc_udbbuf
.b_trlen
= NXMT
;
371 dc
->dc_udbbuf
.b_rdrbl
= LOWORD(&pdc
->dc_rrent
[0]);
372 dc
->dc_udbbuf
.b_rdrbh
= HIWORD(&pdc
->dc_rrent
[0]);
373 dc
->dc_udbbuf
.b_relen
= sizeof (struct de_ring
) / sizeof(u_int16_t
);
374 dc
->dc_udbbuf
.b_rrlen
= NRCV
;
377 dewait(sc
, "wtring");
379 sc
->sc_dedata
->dc_pcbb
.pcbb0
= FC_WTMODE
;
380 sc
->sc_dedata
->dc_pcbb
.pcbb2
= MOD_TPAD
|MOD_HDX
|MOD_DRDC
|MOD_ENAL
;
382 dewait(sc
, "wtmode");
384 /* set up the receive and transmit ring entries */
385 ifxp
= &sc
->sc_ifw
[0];
386 for (rp
= &dc
->dc_xrent
[0]; rp
< &dc
->dc_xrent
[NXMT
]; rp
++) {
387 rp
->r_segbl
= LOWORD(ifxp
->ifw_info
);
388 rp
->r_segbh
= HIWORD(ifxp
->ifw_info
);
392 ifrw
= &sc
->sc_ifr
[0];
393 for (rp
= &dc
->dc_rrent
[0]; rp
< &dc
->dc_rrent
[NRCV
]; rp
++) {
394 rp
->r_slen
= MCLBYTES
- 2;
395 rp
->r_segbl
= LOWORD(ifrw
->ifrw_info
);
396 rp
->r_segbh
= HIWORD(ifrw
->ifrw_info
);
397 rp
->r_flags
= RFLG_OWN
;
401 /* start up the board (rah rah) */
403 sc
->sc_rindex
= sc
->sc_xindex
= sc
->sc_xfree
= sc
->sc_nxmit
= 0;
404 sc
->sc_if
.if_flags
|= IFF_RUNNING
;
405 DE_WLOW(PCSR0_INTE
); /* avoid interlock */
406 destart(&sc
->sc_if
); /* queue output packets */
407 DE_WLOW(CMD_START
|PCSR0_INTE
);
413 * Setup output on interface.
414 * Get another datagram to send off of the interface queue,
415 * and map it to the interface before starting the output.
416 * Must be called from ipl >= our interrupt level.
419 destart(struct ifnet
*ifp
)
421 struct de_softc
*sc
= ifp
->if_softc
;
428 * the following test is necessary, since
429 * the code is not reentrant and we have
430 * multiple transmission buffers.
432 if (sc
->sc_if
.if_flags
& IFF_OACTIVE
)
435 for (nxmit
= sc
->sc_nxmit
; nxmit
< NXMT
; nxmit
++) {
436 IFQ_DEQUEUE(&ifp
->if_snd
, m
);
440 rp
= &dc
->dc_xrent
[sc
->sc_xfree
];
441 if (rp
->r_flags
& XFLG_OWN
)
442 panic("deuna xmit in progress");
445 bpf_mtap(ifp
->if_bpf
, m
);
448 len
= if_ubaput(&sc
->sc_ifuba
, &sc
->sc_ifw
[sc
->sc_xfree
], m
);
451 rp
->r_flags
= XFLG_STP
|XFLG_ENP
|XFLG_OWN
;
454 if (sc
->sc_xfree
== NXMT
)
457 if (sc
->sc_nxmit
!= nxmit
) {
458 sc
->sc_nxmit
= nxmit
;
459 if (ifp
->if_flags
& IFF_RUNNING
)
460 DE_WLOW(PCSR0_INTE
|CMD_PDMD
);
465 * Command done interrupt.
472 struct de_softc
*sc
= arg
;
476 /* save flags right away - clear out interrupt bits */
477 csr0
= DE_RCSR(DE_PCSR0
);
481 sc
->sc_if
.if_flags
|= IFF_OACTIVE
; /* prevent entering destart */
483 * if receive, put receive buffer on mbuf
484 * and hang the request again
489 * Poll transmit ring and check status.
490 * Be careful about loopback requests.
491 * Then free buffer space and check for
492 * more transmit requests.
495 for ( ; sc
->sc_nxmit
> 0; sc
->sc_nxmit
--) {
496 rp
= &dc
->dc_xrent
[sc
->sc_xindex
];
497 if (rp
->r_flags
& XFLG_OWN
)
500 sc
->sc_if
.if_opackets
++;
501 ifxp
= &sc
->sc_ifw
[sc
->sc_xindex
];
502 /* check for unusual conditions */
503 if (rp
->r_flags
& (XFLG_ERRS
|XFLG_MTCH
|XFLG_ONE
|XFLG_MORE
)) {
504 if (rp
->r_flags
& XFLG_ERRS
) {
506 sc
->sc_if
.if_oerrors
++;
507 } else if (rp
->r_flags
& XFLG_ONE
) {
509 sc
->sc_if
.if_collisions
++;
510 } else if (rp
->r_flags
& XFLG_MORE
) {
511 /* more than one collision */
512 sc
->sc_if
.if_collisions
+= 2; /* guess */
515 if_ubaend(&sc
->sc_ifuba
, ifxp
);
516 /* check if next transmit buffer also finished */
518 if (sc
->sc_xindex
== NXMT
)
521 sc
->sc_if
.if_flags
&= ~IFF_OACTIVE
;
524 if (csr0
& PCSR0_RCBI
) {
525 DE_WLOW(PCSR0_INTE
|CMD_PDMD
);
530 * Ethernet interface receiver interface.
531 * If input error just drop packet.
532 * Otherwise purge input buffered data path and examine
533 * packet to determine type. If can't determine length
534 * from type, then have to drop packet. Othewise decapsulate
535 * packet based on type and pass to type specific higher-level
539 derecv(struct de_softc
*sc
)
541 struct ifnet
*ifp
= &sc
->sc_if
;
548 rp
= &dc
->dc_rrent
[sc
->sc_rindex
];
549 while ((rp
->r_flags
& RFLG_OWN
) == 0) {
550 sc
->sc_if
.if_ipackets
++;
551 len
= (rp
->r_lenerr
&RERR_MLEN
) - ETHER_CRC_LEN
;
552 /* check for errors */
553 if ((rp
->r_flags
& (RFLG_ERRS
|RFLG_FRAM
|RFLG_OFLO
|RFLG_CRC
)) ||
554 (rp
->r_lenerr
& (RERR_BUFL
|RERR_UBTO
))) {
555 sc
->sc_if
.if_ierrors
++;
558 m
= if_ubaget(&sc
->sc_ifuba
, &sc
->sc_ifr
[sc
->sc_rindex
],
561 sc
->sc_if
.if_ierrors
++;
566 bpf_mtap(ifp
->if_bpf
, m
);
569 (*ifp
->if_input
)(ifp
, m
);
571 /* hang the receive buffer again */
572 next
: rp
->r_lenerr
= 0;
573 rp
->r_flags
= RFLG_OWN
;
575 /* check next receive buffer */
577 if (sc
->sc_rindex
== NRCV
)
579 rp
= &dc
->dc_rrent
[sc
->sc_rindex
];
584 * Process an ioctl request.
587 deioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
593 error
= ether_ioctl(ifp
, cmd
, data
);
594 if (error
== ENETRESET
)
602 * Await completion of the named function
603 * and check for errors.
606 dewait(struct de_softc
*sc
, const char *fn
)
610 while ((DE_RCSR(DE_PCSR0
) & PCSR0_INTR
) == 0)
612 csr0
= DE_RCSR(DE_PCSR0
);
614 if (csr0
& PCSR0_PCEI
) {
617 csr1
= DE_RCSR(DE_PCSR1
);
618 snprintb(bits0
, sizeof(bits0
), PCSR0_BITS
, csr0
);
619 snprintb(bits1
, sizeof(bits1
), PCSR1_BITS
, csr1
);
620 aprint_error_dev(sc
->sc_dev
, "%s failed, csr0=%s csr1=%s\n",
626 dematch(device_t parent
, cfdata_t cf
, void *aux
)
628 struct uba_attach_args
*ua
= aux
;
630 struct de_softc
*sc
= &ssc
;
633 sc
->sc_iot
= ua
->ua_iot
;
634 sc
->sc_ioh
= ua
->ua_ioh
;
636 * Make sure self-test is finished before we screw with the board.
637 * Self-test on a DELUA can take 15 seconds (argh).
641 (DE_RCSR(DE_PCSR0
) & PCSR0_FATI
) == 0 &&
642 (DE_RCSR(DE_PCSR1
) & PCSR1_STMASK
) == STAT_RESET
;
645 if (((DE_RCSR(DE_PCSR0
) & PCSR0_FATI
) != 0) ||
646 (((DE_RCSR(DE_PCSR1
) & PCSR1_STMASK
) != STAT_READY
) &&
647 ((DE_RCSR(DE_PCSR1
) & PCSR1_STMASK
) != STAT_RUN
)))
650 DE_WCSR(DE_PCSR0
, 0);
652 DE_WCSR(DE_PCSR0
, PCSR0_RSET
);
653 while ((DE_RCSR(DE_PCSR0
) & PCSR0_INTR
) == 0)
655 /* make board interrupt by executing a GETPCBB command */
656 DE_WCSR(DE_PCSR0
, PCSR0_INTE
);
657 DE_WCSR(DE_PCSR2
, 0);
658 DE_WCSR(DE_PCSR3
, 0);
659 DE_WCSR(DE_PCSR0
, PCSR0_INTE
|CMD_GETPCBB
);
666 deshutdown(void *arg
)
668 struct de_softc
*sc
= arg
;
670 DE_WCSR(DE_PCSR0
, 0);
672 DE_WCSR(DE_PCSR0
, PCSR0_RSET
);
673 dewait(sc
, "shutdown");