1 /* $NetBSD: if_el.c,v 1.83 2009/05/12 08:44:19 cegger Exp $ */
4 * Copyright (c) 1994, Matthew E. Kimmel. Permission is hereby granted
5 * to use, copy, modify and distribute this software provided that both
6 * the copyright notice and this permission notice appear in all copies
7 * of the software, derivative works or modified versions, and any
12 * 3COM Etherlink 3C501 device driver
16 * Bugs/possible improvements:
17 * - Does not currently support DMA
18 * - Does not currently support multicasts
21 #include <sys/cdefs.h>
22 __KERNEL_RCSID(0, "$NetBSD: if_el.c,v 1.83 2009/05/12 08:44:19 cegger Exp $");
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/errno.h>
31 #include <sys/ioctl.h>
33 #include <sys/socket.h>
34 #include <sys/syslog.h>
35 #include <sys/device.h>
41 #include <net/if_dl.h>
42 #include <net/if_types.h>
44 #include <net/if_ether.h>
47 #include <netinet/in.h>
48 #include <netinet/in_systm.h>
49 #include <netinet/in_var.h>
50 #include <netinet/ip.h>
51 #include <netinet/if_inarp.h>
57 #include <net/bpfdesc.h>
64 #include <dev/isa/isavar.h>
65 #include <dev/isa/if_elreg.h>
67 /* for debugging convenience */
69 #define DPRINTF(x) printf x
75 * per-line info and status
81 struct ethercom sc_ethercom
; /* ethernet common */
82 bus_space_tag_t sc_iot
; /* bus space identifier */
83 bus_space_handle_t sc_ioh
; /* i/o handle */
86 rndsource_element_t rnd_source
;
94 void elinit(struct el_softc
*);
95 int elioctl(struct ifnet
*, u_long
, void *);
96 void elstart(struct ifnet
*);
97 void elwatchdog(struct ifnet
*);
98 void elreset(struct el_softc
*);
99 void elstop(struct el_softc
*);
100 static int el_xmit(struct el_softc
*);
101 void elread(struct el_softc
*, int);
102 struct mbuf
*elget(struct el_softc
*sc
, int);
103 static inline void el_hardreset(struct el_softc
*);
105 int elprobe(device_t
, cfdata_t
, void *);
106 void elattach(device_t
, device_t
, void *);
108 CFATTACH_DECL(el
, sizeof(struct el_softc
),
109 elprobe
, elattach
, NULL
, NULL
);
114 * See if the card is there and at the right place.
115 * (XXX - cgd -- needs help)
118 elprobe(device_t parent
, cfdata_t match
, void *aux
)
120 struct isa_attach_args
*ia
= aux
;
121 bus_space_tag_t iot
= ia
->ia_iot
;
122 bus_space_handle_t ioh
;
124 u_int8_t station_addr
[ETHER_ADDR_LEN
];
135 if (ISA_DIRECT_CONFIG(ia
))
138 iobase
= ia
->ia_io
[0].ir_addr
;
140 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
)
142 if (ia
->ia_irq
[0].ir_irq
== ISA_UNKNOWN_IRQ
)
145 /* First check the base. */
146 if (iobase
< 0x200 || iobase
> 0x3f0)
150 if (bus_space_map(iot
, iobase
, 16, 0, &ioh
))
154 * Now attempt to grab the station address from the PROM and see if it
155 * contains the 3com vendor code.
157 DPRINTF(("Probing 3c501 at 0x%x...\n", iobase
));
159 /* Reset the board. */
160 DPRINTF(("Resetting board...\n"));
161 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_RESET
);
163 bus_space_write_1(iot
, ioh
, EL_AC
, 0);
165 /* Now read the address. */
166 DPRINTF(("Reading station address...\n"));
167 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++) {
168 bus_space_write_1(iot
, ioh
, EL_GPBL
, i
);
169 station_addr
[i
] = bus_space_read_1(iot
, ioh
, EL_EAW
);
171 DPRINTF(("Address is %s\n", ether_sprintf(station_addr
)));
174 * If the vendor code is ok, return a 1. We'll assume that whoever
175 * configured this system is right about the IRQ.
177 if (station_addr
[0] != 0x02 || station_addr
[1] != 0x60 ||
178 station_addr
[2] != 0x8c) {
179 DPRINTF(("Bad vendor code.\n"));
182 DPRINTF(("Vendor code ok.\n"));
185 ia
->ia_io
[0].ir_size
= 16;
195 bus_space_unmap(iot
, ioh
, 16);
200 * Attach the interface to the kernel data structures. By the time this is
201 * called, we know that the card exists at the given I/O address. We still
202 * assume that the IRQ given is correct.
205 elattach(device_t parent
, device_t self
, void *aux
)
207 struct el_softc
*sc
= (void *)self
;
208 struct isa_attach_args
*ia
= aux
;
209 bus_space_tag_t iot
= ia
->ia_iot
;
210 bus_space_handle_t ioh
;
211 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
212 u_int8_t myaddr
[ETHER_ADDR_LEN
];
217 DPRINTF(("Attaching %s...\n", device_xname(&sc
->sc_dev
)));
220 if (bus_space_map(iot
, ia
->ia_io
[0].ir_addr
, 16, 0, &ioh
)) {
221 aprint_error_dev(self
, "can't map i/o space\n");
228 /* Reset the board. */
229 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_RESET
);
231 bus_space_write_1(iot
, ioh
, EL_AC
, 0);
233 /* Now read the address. */
234 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++) {
235 bus_space_write_1(iot
, ioh
, EL_GPBL
, i
);
236 myaddr
[i
] = bus_space_read_1(iot
, ioh
, EL_EAW
);
239 /* Stop the board. */
242 /* Initialize ifnet structure. */
243 strlcpy(ifp
->if_xname
, device_xname(&sc
->sc_dev
), IFNAMSIZ
);
245 ifp
->if_start
= elstart
;
246 ifp
->if_ioctl
= elioctl
;
247 ifp
->if_watchdog
= elwatchdog
;
248 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_NOTRAILERS
;
249 IFQ_SET_READY(&ifp
->if_snd
);
251 /* Now we can attach the interface. */
252 DPRINTF(("Attaching interface...\n"));
254 ether_ifattach(ifp
, myaddr
);
256 /* Print out some information for the user. */
257 printf("%s: address %s\n", device_xname(self
), ether_sprintf(myaddr
));
259 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, ia
->ia_irq
[0].ir_irq
,
260 IST_EDGE
, IPL_NET
, elintr
, sc
);
263 DPRINTF(("Attaching to random...\n"));
264 rnd_attach_source(&sc
->rnd_source
, device_xname(&sc
->sc_dev
),
268 DPRINTF(("elattach() finished.\n"));
275 elreset(struct el_softc
*sc
)
279 DPRINTF(("elreset()\n"));
290 elstop(struct el_softc
*sc
)
293 bus_space_write_1(sc
->sc_iot
, sc
->sc_ioh
, EL_AC
, 0);
297 * Do a hardware reset of the board, and upload the ethernet address again in
298 * case the board forgets.
301 el_hardreset(struct el_softc
*sc
)
303 bus_space_tag_t iot
= sc
->sc_iot
;
304 bus_space_handle_t ioh
= sc
->sc_ioh
;
307 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_RESET
);
309 bus_space_write_1(iot
, ioh
, EL_AC
, 0);
311 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++)
312 bus_space_write_1(iot
, ioh
, i
,
313 CLLADDR(sc
->sc_ethercom
.ec_if
.if_sadl
)[i
]);
317 * Initialize interface.
320 elinit(struct el_softc
*sc
)
322 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
323 bus_space_tag_t iot
= sc
->sc_iot
;
324 bus_space_handle_t ioh
= sc
->sc_ioh
;
326 /* First, reset the board. */
330 DPRINTF(("Configuring rx...\n"));
331 if (ifp
->if_flags
& IFF_PROMISC
)
332 bus_space_write_1(iot
, ioh
, EL_RXC
,
333 EL_RXC_AGF
| EL_RXC_DSHORT
| EL_RXC_DDRIB
|
334 EL_RXC_DOFLOW
| EL_RXC_PROMISC
);
336 bus_space_write_1(iot
, ioh
, EL_RXC
,
337 EL_RXC_AGF
| EL_RXC_DSHORT
| EL_RXC_DDRIB
|
338 EL_RXC_DOFLOW
| EL_RXC_ABROAD
);
339 bus_space_write_1(iot
, ioh
, EL_RBC
, 0);
342 DPRINTF(("Configuring tx...\n"));
343 bus_space_write_1(iot
, ioh
, EL_TXC
, 0);
345 /* Start reception. */
346 DPRINTF(("Starting reception...\n"));
347 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_IRQE
| EL_AC_RX
);
349 /* Set flags appropriately. */
350 ifp
->if_flags
|= IFF_RUNNING
;
351 ifp
->if_flags
&= ~IFF_OACTIVE
;
353 /* And start output. */
358 * Start output on interface. Get datagrams from the queue and output them,
359 * giving the receiver a chance between datagrams. Call only from splnet or
363 elstart(struct ifnet
*ifp
)
365 struct el_softc
*sc
= ifp
->if_softc
;
366 bus_space_tag_t iot
= sc
->sc_iot
;
367 bus_space_handle_t ioh
= sc
->sc_ioh
;
369 int s
, i
, off
, retries
;
371 DPRINTF(("elstart()...\n"));
374 /* Don't do anything if output is active. */
375 if ((ifp
->if_flags
& IFF_OACTIVE
) != 0) {
380 ifp
->if_flags
|= IFF_OACTIVE
;
383 * The main loop. They warned me against endless loops, but would I
387 /* Dequeue the next datagram. */
388 IFQ_DEQUEUE(&ifp
->if_snd
, m0
);
390 /* If there's nothing to send, return. */
395 /* Give the packet to the bpf, if any. */
397 bpf_mtap(ifp
->if_bpf
, m0
);
400 /* Disable the receiver. */
401 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_HOST
);
402 bus_space_write_1(iot
, ioh
, EL_RBC
, 0);
404 /* Transfer datagram to board. */
405 DPRINTF(("el: xfr pkt length=%d...\n", m0
->m_pkthdr
.len
));
406 off
= EL_BUFSIZ
- max(m0
->m_pkthdr
.len
,
407 ETHER_MIN_LEN
- ETHER_CRC_LEN
);
409 if ((off
& 0xffff) != off
)
410 printf("%s: bogus off 0x%x\n",
411 device_xname(&sc
->sc_dev
), off
);
413 bus_space_write_1(iot
, ioh
, EL_GPBL
, off
& 0xff);
414 bus_space_write_1(iot
, ioh
, EL_GPBH
, (off
>> 8) & 0xff);
416 /* Copy the datagram to the buffer. */
417 for (m
= m0
; m
!= 0; m
= m
->m_next
)
418 bus_space_write_multi_1(iot
, ioh
, EL_BUF
,
419 mtod(m
, u_int8_t
*), m
->m_len
);
421 i
< ETHER_MIN_LEN
- ETHER_CRC_LEN
- m0
->m_pkthdr
.len
; i
++)
422 bus_space_write_1(iot
, ioh
, EL_BUF
, 0);
426 /* Now transmit the datagram. */
429 bus_space_write_1(iot
, ioh
, EL_GPBL
, off
& 0xff);
430 bus_space_write_1(iot
, ioh
, EL_GPBH
, (off
>> 8) & 0xff);
435 /* Check out status. */
436 i
= bus_space_read_1(iot
, ioh
, EL_TXS
);
437 DPRINTF(("tx status=0x%x\n", i
));
438 if ((i
& EL_TXS_READY
) == 0) {
439 DPRINTF(("el: err txs=%x\n", i
));
440 if (i
& (EL_TXS_COLL
| EL_TXS_COLL16
)) {
441 ifp
->if_collisions
++;
442 if ((i
& EL_TXC_DCOLL16
) == 0 &&
445 bus_space_write_1(iot
, ioh
,
459 * Now give the card a chance to receive.
460 * Gotta love 3c501s...
462 (void)bus_space_read_1(iot
, ioh
, EL_AS
);
463 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_IRQE
| EL_AC_RX
);
465 /* Interrupt here. */
469 (void)bus_space_read_1(iot
, ioh
, EL_AS
);
470 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_IRQE
| EL_AC_RX
);
471 ifp
->if_flags
&= ~IFF_OACTIVE
;
476 * This function actually attempts to transmit a datagram downloaded to the
477 * board. Call at splnet or interrupt, after downloading data! Returns 0 on
478 * success, non-0 on failure.
481 el_xmit(struct el_softc
*sc
)
483 bus_space_tag_t iot
= sc
->sc_iot
;
484 bus_space_handle_t ioh
= sc
->sc_ioh
;
489 * This busy-waits for the tx completion. Can we get an interrupt
493 DPRINTF(("el: xmit..."));
494 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_TXFRX
);
496 while ((bus_space_read_1(iot
, ioh
, EL_AS
) & EL_AS_TXBUSY
) && (i
> 0))
499 DPRINTF(("tx not ready\n"));
502 DPRINTF(("%d cycles.\n", 20000 - i
));
507 * Controller interrupt.
512 struct el_softc
*sc
= arg
;
513 bus_space_tag_t iot
= sc
->sc_iot
;
514 bus_space_handle_t ioh
= sc
->sc_ioh
;
518 DPRINTF(("elintr: "));
520 /* Check board status. */
521 if ((bus_space_read_1(iot
, ioh
, EL_AS
) & EL_AS_RXBUSY
) != 0) {
522 (void)bus_space_read_1(iot
, ioh
, EL_RXC
);
523 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_IRQE
| EL_AC_RX
);
528 rxstat
= bus_space_read_1(iot
, ioh
, EL_RXS
);
529 if (rxstat
& EL_RXS_STALE
)
532 /* If there's an overflow, reinit the board. */
533 if ((rxstat
& EL_RXS_NOFLOW
) == 0) {
534 DPRINTF(("overflow.\n"));
536 /* Put board back into receive mode. */
537 if (sc
->sc_ethercom
.ec_if
.if_flags
& IFF_PROMISC
)
538 bus_space_write_1(iot
, ioh
, EL_RXC
,
539 EL_RXC_AGF
| EL_RXC_DSHORT
| EL_RXC_DDRIB
|
540 EL_RXC_DOFLOW
| EL_RXC_PROMISC
);
542 bus_space_write_1(iot
, ioh
, EL_RXC
,
543 EL_RXC_AGF
| EL_RXC_DSHORT
| EL_RXC_DDRIB
|
544 EL_RXC_DOFLOW
| EL_RXC_ABROAD
);
545 (void)bus_space_read_1(iot
, ioh
, EL_AS
);
546 bus_space_write_1(iot
, ioh
, EL_RBC
, 0);
550 /* Incoming packet. */
551 len
= bus_space_read_1(iot
, ioh
, EL_RBL
);
552 len
|= bus_space_read_1(iot
, ioh
, EL_RBH
) << 8;
553 DPRINTF(("receive len=%d rxstat=%x ", len
, rxstat
));
554 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_HOST
);
556 /* Pass data up to upper levels. */
559 /* Is there another packet? */
560 if ((bus_space_read_1(iot
, ioh
, EL_AS
) & EL_AS_RXBUSY
) != 0)
564 rnd_add_uint32(&sc
->rnd_source
, rxstat
);
567 DPRINTF(("<rescan> "));
570 (void)bus_space_read_1(iot
, ioh
, EL_RXC
);
571 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_IRQE
| EL_AC_RX
);
576 * Pass a packet to the higher levels.
579 elread(struct el_softc
*sc
, int len
)
581 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
584 if (len
<= sizeof(struct ether_header
) ||
585 len
> ETHER_MAX_LEN
) {
586 printf("%s: invalid packet size %d; dropping\n",
587 device_xname(&sc
->sc_dev
), len
);
592 /* Pull packet off interface. */
603 * Check if there's a BPF listener on this interface.
604 * If so, hand off the raw packet to BPF.
607 bpf_mtap(ifp
->if_bpf
, m
);
610 (*ifp
->if_input
)(ifp
, m
);
614 * Pull read data off a interface. Len is length of data, with local net
615 * header stripped. We copy the data into mbufs. When full cluster sized
616 * units are present we copy into clusters.
619 elget(struct el_softc
*sc
, int totlen
)
621 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
622 bus_space_tag_t iot
= sc
->sc_iot
;
623 bus_space_handle_t ioh
= sc
->sc_ioh
;
624 struct mbuf
*m
, *m0
, *newm
;
627 MGETHDR(m0
, M_DONTWAIT
, MT_DATA
);
630 m0
->m_pkthdr
.rcvif
= ifp
;
631 m0
->m_pkthdr
.len
= totlen
;
635 bus_space_write_1(iot
, ioh
, EL_GPBL
, 0);
636 bus_space_write_1(iot
, ioh
, EL_GPBH
, 0);
639 if (totlen
>= MINCLSIZE
) {
640 MCLGET(m
, M_DONTWAIT
);
641 if ((m
->m_flags
& M_EXT
) == 0)
646 m
->m_len
= len
= min(totlen
, len
);
647 bus_space_read_multi_1(iot
, ioh
, EL_BUF
, mtod(m
, u_int8_t
*), len
);
651 MGET(newm
, M_DONTWAIT
, MT_DATA
);
655 m
= m
->m_next
= newm
;
659 bus_space_write_1(iot
, ioh
, EL_RBC
, 0);
660 bus_space_write_1(iot
, ioh
, EL_AC
, EL_AC_RX
);
670 * Process an ioctl request. This code needs some work - it looks pretty ugly.
673 elioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
675 struct el_softc
*sc
= ifp
->if_softc
;
676 struct ifaddr
*ifa
= (struct ifaddr
*)data
;
684 ifp
->if_flags
|= IFF_UP
;
687 switch (ifa
->ifa_addr
->sa_family
) {
690 arp_ifinit(ifp
, ifa
);
699 if ((error
= ifioctl_common(ifp
, cmd
, data
)) != 0)
701 /* XXX re-use ether_ioctl() */
702 switch (ifp
->if_flags
& (IFF_UP
|IFF_RUNNING
)) {
705 * If interface is marked down and it is running, then
709 ifp
->if_flags
&= ~IFF_RUNNING
;
713 * If interface is marked up and it is stopped, then
720 * Some other important flag might have changed, so
729 error
= ether_ioctl(ifp
, cmd
, data
);
738 * Device timeout routine.
741 elwatchdog(struct ifnet
*ifp
)
743 struct el_softc
*sc
= ifp
->if_softc
;
745 log(LOG_ERR
, "%s: device timeout\n", device_xname(&sc
->sc_dev
));
746 sc
->sc_ethercom
.ec_if
.if_oerrors
++;