xref: /netbsd-src/sys/arch/cesfic/dev/if_le.c (revision d9941582bf2ed3c32007f8d190c32330e9a8eadc)
1*d9941582Stsutsui /*	$NetBSD: if_le.c,v 1.7 2008/04/04 12:25:06 tsutsui Exp $	*/
2e047259aSdrochner 
3e047259aSdrochner /*
4e047259aSdrochner  * Copyright (c) 1997, 1999
5e047259aSdrochner  *	Matthias Drochner.  All rights reserved.
6e047259aSdrochner  *
7e047259aSdrochner  * Redistribution and use in source and binary forms, with or without
8e047259aSdrochner  * modification, are permitted provided that the following conditions
9e047259aSdrochner  * are met:
10e047259aSdrochner  * 1. Redistributions of source code must retain the above copyright
11e047259aSdrochner  *    notice, this list of conditions and the following disclaimer.
12e047259aSdrochner  * 2. Redistributions in binary form must reproduce the above copyright
13e047259aSdrochner  *    notice, this list of conditions and the following disclaimer in the
14e047259aSdrochner  *    documentation and/or other materials provided with the distribution.
15e047259aSdrochner  *
16e047259aSdrochner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17e047259aSdrochner  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18e047259aSdrochner  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19e047259aSdrochner  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20e047259aSdrochner  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21e047259aSdrochner  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22e047259aSdrochner  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23e047259aSdrochner  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24e047259aSdrochner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25e047259aSdrochner  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26e047259aSdrochner  *
27e047259aSdrochner  */
28e047259aSdrochner 
29e803bea7Slukem #include <sys/cdefs.h>
30*d9941582Stsutsui __KERNEL_RCSID(0, "$NetBSD: if_le.c,v 1.7 2008/04/04 12:25:06 tsutsui Exp $");
31e803bea7Slukem 
32e047259aSdrochner #include "opt_inet.h"
33e047259aSdrochner 
34e047259aSdrochner #include <sys/param.h>
35e047259aSdrochner #include <sys/systm.h>
36e047259aSdrochner #include <sys/socket.h>
37e047259aSdrochner #include <sys/device.h>
38e047259aSdrochner 
39e047259aSdrochner #include <net/if.h>
40e047259aSdrochner #include <net/if_ether.h>
41e047259aSdrochner #include <net/if_media.h>
42e047259aSdrochner 
43e047259aSdrochner #ifdef INET
44e047259aSdrochner #include <netinet/in.h>
45e047259aSdrochner #include <netinet/if_inarp.h>
46e047259aSdrochner #endif
47e047259aSdrochner 
48e047259aSdrochner #include <machine/cpu.h>
49e047259aSdrochner #include <machine/pte.h>
50e047259aSdrochner 
51e047259aSdrochner #include <machine/autoconf.h>
52e047259aSdrochner 
53e047259aSdrochner #include <dev/ic/lancereg.h>
54e047259aSdrochner #include <dev/ic/lancevar.h>
55e047259aSdrochner #include <dev/ic/am79900reg.h>
56e047259aSdrochner #include <dev/ic/am79900var.h>
57e047259aSdrochner 
58e047259aSdrochner #include <cesfic/cesfic/isr.h>
59e047259aSdrochner 
60*d9941582Stsutsui int lematch(device_t, cfdata_t, void *);
61*d9941582Stsutsui void leattach(device_t, device_t, void *);
62e047259aSdrochner 
63*d9941582Stsutsui CFATTACH_DECL_NEW(le, sizeof(struct am79900_softc),
64c5e91d44Sthorpej     lematch, leattach, NULL, NULL);
65e047259aSdrochner 
66*d9941582Stsutsui int	leintr(void *);
67e047259aSdrochner 
68*d9941582Stsutsui void lewrcsr(struct lance_softc *, uint16_t, uint16_t);
69*d9941582Stsutsui uint16_t lerdcsr(struct lance_softc *, uint16_t);
70e047259aSdrochner 
71e047259aSdrochner static char *lebase, *lemembase;
72e047259aSdrochner 
73e047259aSdrochner void
lewrcsr(struct lance_softc * sc,uint16_t port,uint16_t val)74*d9941582Stsutsui lewrcsr(struct lance_softc *sc, uint16_t port, uint16_t val)
75e047259aSdrochner {
76*d9941582Stsutsui 
77e047259aSdrochner 	*(volatile int *)(lebase + 4) = port;
78e047259aSdrochner 	*(volatile int *)(lebase + 0) = val;
79e047259aSdrochner }
80e047259aSdrochner 
81*d9941582Stsutsui uint16_t
lerdcsr(struct lance_softc * sc,uint16_t port)82*d9941582Stsutsui lerdcsr(struct lance_softc *sc, uint16_t port)
83e047259aSdrochner {
84*d9941582Stsutsui 	uint16_t val;
85e047259aSdrochner 
86e047259aSdrochner 	*(volatile int *)(lebase + 4) = port;
87e047259aSdrochner 	val = *(volatile int *)(lebase + 0);
88e047259aSdrochner 	return (val);
89e047259aSdrochner }
90e047259aSdrochner 
91e047259aSdrochner int
lematch(device_t parent,cfdata_t cf,void * aux)92*d9941582Stsutsui lematch(device_t parent, cfdata_t cf, void *aux)
93e047259aSdrochner {
94*d9941582Stsutsui 
95e047259aSdrochner 	return (1);
96e047259aSdrochner }
97e047259aSdrochner 
98e047259aSdrochner /*
99e047259aSdrochner  * Interface exists: make available by filling in network interface
100e047259aSdrochner  * record.  System will initialize the interface when it is ready
101e047259aSdrochner  * to accept packets.
102e047259aSdrochner  */
103*d9941582Stsutsui extern void sic_enable_int(int, int, int, int, int);
104e047259aSdrochner static char hwa[6] = {0x00,0x80,0xa2,0x00,0x30,0x23};
105e047259aSdrochner void
leattach(device_t parent,device_t self,void * aux)106*d9941582Stsutsui leattach(device_t parent, device_t self, void *aux)
107e047259aSdrochner {
108*d9941582Stsutsui 	struct lance_softc *sc = device_private(self);
109e047259aSdrochner 	int i;
110e047259aSdrochner 
111212af23cScl 	mainbus_map(0x4c000000, 0x10000, 0, (void *)&lemembase);
112212af23cScl 	mainbus_map(0x48000000, 0x1000, 0, (void *)&lebase);
113e047259aSdrochner 
114*d9941582Stsutsui 	sc->sc_dev = self;
115e047259aSdrochner 	sc->sc_mem = lemembase;
116e047259aSdrochner 	sc->sc_conf3 = LE_C3_BSWP;
117e047259aSdrochner 	sc->sc_addr = 0x4c000000;
118e047259aSdrochner 	sc->sc_memsize = 64 * 1024;
119e047259aSdrochner 
120e047259aSdrochner 	if (cesfic_getetheraddr(sc->sc_enaddr)) {
121e047259aSdrochner 		/* fallback */
122e047259aSdrochner 		for (i = 0; i < sizeof(sc->sc_enaddr); i++) {
123e047259aSdrochner 			sc->sc_enaddr[i] = hwa[i];
124e047259aSdrochner 		}
125e047259aSdrochner 	}
126e047259aSdrochner 
127e047259aSdrochner 	sc->sc_copytodesc = lance_copytobuf_contig;
128e047259aSdrochner 	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
129e047259aSdrochner 	sc->sc_copytobuf = lance_copytobuf_contig;
130e047259aSdrochner 	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
131e047259aSdrochner 	sc->sc_zerobuf = lance_zerobuf_contig;
132e047259aSdrochner 
133e047259aSdrochner 	sc->sc_rdcsr = lerdcsr;
134e047259aSdrochner 	sc->sc_wrcsr = lewrcsr;
135e047259aSdrochner 	sc->sc_hwinit = NULL;
136e047259aSdrochner 
137e047259aSdrochner 	lewrcsr(sc, 4, 0x44);
138e047259aSdrochner 	am79900_config((struct am79900_softc *)sc);
139e047259aSdrochner 
140e047259aSdrochner 	/* Establish the interrupt handler. */
141e047259aSdrochner 	(void) isrlink(leintr, sc, 3, ISRPRI_NET);
142e047259aSdrochner 	sic_enable_int(17, 0, 1, 3, 0);
143e047259aSdrochner }
144e047259aSdrochner 
145e047259aSdrochner int
leintr(void * arg)146*d9941582Stsutsui leintr(void *arg)
147e047259aSdrochner {
148e047259aSdrochner 	struct lance_softc *sc = arg;
149*d9941582Stsutsui 	uint16_t isr4;
150e047259aSdrochner 
151e047259aSdrochner 	isr4 = lerdcsr(sc, 4);
152e047259aSdrochner 	if (isr4 & 0x08) {
153e047259aSdrochner 		lewrcsr(sc, 4, isr4);
154e047259aSdrochner 		return (1);
155e047259aSdrochner 	}
156e047259aSdrochner 
157e047259aSdrochner 	return (am79900_intr(sc));
158e047259aSdrochner }
159