xref: /netbsd-src/sys/arch/vax/if/if_le.c (revision 76dfffe33547c37f8bdd446e3e4ab0f3c16cea4b)
1 /*	$NetBSD: if_le.c,v 1.3 1996/10/13 03:34:53 christos Exp $	*/
2 
3 #define LEDEBUG	 1		/* debug-level: 0 or 1 */
4 /* #define LE_CHIP_IS_POKEY	/* does VS2000 need this ??? */
5 
6 /*-
7  * Copyright (c) 1995 Charles M. Hannum.  All rights reserved.
8  * Copyright (c) 1992, 1993
9  *	The Regents of the University of California.  All rights reserved.
10  *
11  * This code is derived from software contributed to Berkeley by
12  * Ralph Campbell and Rick Macklem.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. All advertising materials mentioning features or use of this software
23  *    must display the following acknowledgement:
24  *	This product includes software developed by the University of
25  *	California, Berkeley and its contributors.
26  * 4. Neither the name of the University nor the names of its contributors
27  *    may be used to endorse or promote products derived from this software
28  *    without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40  * SUCH DAMAGE.
41  *
42  *	@(#)if_le.c	8.2 (Berkeley) 11/16/93
43  */
44 
45 #include "bpfilter.h"
46 
47 #include <sys/param.h>
48 #include <sys/syslog.h>
49 #include <sys/socket.h>
50 #include <sys/device.h>
51 
52 #include <net/if.h>
53 
54 #if INET
55 #include <netinet/in.h>
56 #include <netinet/if_ether.h>
57 #endif
58 
59 /*
60  * This would be nice, but it's not yet there...
61  *
62  * #include <machine/autoconf.h>
63  */
64 
65 #include <machine/pte.h>
66 #include <machine/cpu.h>
67 #include <machine/mtpr.h>
68 #include <machine/uvax.h>
69 #include <machine/ka410.h>
70 #include <machine/vsbus.h>
71 
72 #include <dev/ic/am7990reg.h>
73 #define LE_NEED_BUF_CONTIG
74 #include <dev/ic/am7990var.h>
75 
76 #include <dev/tc/if_levar.h>
77 
78 #define xdebug(x)
79 
80 #ifdef LE_CHIP_IS_POKEY
81 /*
82  * access LANCE registers and double-check their contents
83  */
84 #define wbflush()	/* do nothing */
85 void lewritereg();
86 #define LERDWR(cntl, src, dst)	{ (dst) = (src); wbflush(); }
87 #define LEWREG(src, dst)	lewritereg(&(dst), (src))
88 #endif
89 
90 #define LE_IOSIZE 64*1024	/* 64K of real-mem are reserved and already */
91 extern void *le_iomem;		/* mapped into virt-mem by cpu_steal_pages */
92 extern u_long le_ioaddr;	/* le_iomem is virt, le_ioaddr is phys */
93 
94 #define LE_SOFTC(unit)	le_cd.cd_devs[unit]
95 #define LE_DELAY(x)	DELAY(x)
96 
97 int lematch __P((struct device *, void *, void *));
98 void leattach __P((struct device *, struct device *, void *));
99 
100 int leintr __P((void *sc));
101 
102 struct cfattach le_ca = {
103 	sizeof(struct le_softc), lematch, leattach
104 };
105 
106 integrate void
107 lewrcsr(sc, port, val)
108 	struct le_softc *sc;
109 	u_int16_t port, val;
110 {
111 	struct lereg1 *ler1 = sc->sc_r1;
112 
113 #ifdef LE_CHIP_IS_POKEY
114 	LEWREG(port, ler1->ler1_rap);
115 	LERDWR(port, val, ler1->ler1_rdp);
116 #else
117 	ler1->ler1_rap = port;
118 	ler1->ler1_rdp = val;
119 #endif
120 }
121 
122 integrate u_int16_t
123 lerdcsr(sc, port)
124 	struct le_softc *sc;
125 	u_int16_t port;
126 {
127 	struct lereg1 *ler1 = sc->sc_r1;
128 	u_int16_t val;
129 
130 #ifdef LE_CHIP_IS_POKEY
131 	LEWREG(port, ler1->ler1_rap);
132 	LERDWR(0, ler1->ler1_rdp, val);
133 #else
134 	ler1->ler1_rap = port;
135 	val = ler1->ler1_rdp;
136 #endif
137 	return (val);
138 }
139 
140 int
141 lematch(parent, match, aux)
142 	struct device *parent;
143 	void *match, *aux;
144 {
145 	struct cfdata *cf = match;
146 	struct confargs *ca = aux;
147 
148 	/*
149 	 * There could/should be more checks, but for now...
150 	 */
151 	if (strcmp(ca->ca_name, "le") &&
152 	    strcmp(ca->ca_name, "am7990") &&
153 	    strcmp(ca->ca_name, "AM7990"))
154 		return (0);
155 
156 	return (1);
157 }
158 
159 /*
160  *
161  */
162 void
163 leattach(parent, self, aux)
164 	struct device *parent, *self;
165 	void *aux;
166 {
167 	register struct le_softc *sc = (void *)self;
168 	struct confargs *ca = aux;
169 	u_char *cp;	/* pointer to MAC address */
170 	int i;
171 
172 	sc->sc_r1  = (void*)uvax_phys2virt(ca->ca_ioaddr);
173 
174 	sc->sc_am7990.sc_conf3 = 0;
175 	sc->sc_am7990.sc_mem = le_iomem;
176 	sc->sc_am7990.sc_addr = le_ioaddr;
177 	sc->sc_am7990.sc_memsize = LE_IOSIZE;
178 
179 	xdebug(("leattach: mem=%x, addr=%x, size=%x (%d)\n",
180 	    sc->sc_am7990.sc_mem, sc->sc_am7990.sc_addr,
181 	    sc->sc_am7990.sc_memsize, sc->sc_am7990.sc_memsize));
182 
183 	sc->sc_am7990.sc_copytodesc = am7990_copytobuf_contig;
184 	sc->sc_am7990.sc_copyfromdesc = am7990_copyfrombuf_contig;
185 	sc->sc_am7990.sc_copytobuf = am7990_copytobuf_contig;
186 	sc->sc_am7990.sc_copyfrombuf = am7990_copyfrombuf_contig;
187 	sc->sc_am7990.sc_zerobuf = am7990_zerobuf_contig;
188 
189 	/*
190 	 * Get the ethernet address out of rom
191 	 */
192 	for (i = 0; i < sizeof(sc->sc_am7990.sc_arpcom.ac_enaddr); i++) {
193 		int *eaddr = (void*)uvax_phys2virt(ca->ca_enaddr);
194 		sc->sc_am7990.sc_arpcom.ac_enaddr[i] = (u_char)eaddr[i];
195 	}
196 
197 	bcopy(self->dv_xname, sc->sc_am7990.sc_arpcom.ac_if.if_xname, IFNAMSIZ);
198 	am7990_config(&sc->sc_am7990);
199 
200 #ifdef LEDEBUG
201 	sc->sc_am7990.sc_debug = LEDEBUG;
202 #endif
203 
204 	vsbus_intr_register(ca, am7990_intr, &sc->sc_am7990);
205 	vsbus_intr_enable(ca);
206 }
207 
208 integrate void
209 lehwinit(sc)
210 	struct le_softc *sc;
211 {
212 }
213 
214 #ifdef LE_CHIP_IS_POKEY
215 /*
216  * Write a lance register port, reading it back to ensure success. This seems
217  * to be necessary during initialization, since the chip appears to be a bit
218  * pokey sometimes.
219  */
220 void
221 lewritereg(regptr, val)
222 	register volatile u_short *regptr;
223 	register u_short val;
224 {
225 	register int i = 0;
226 
227 	while (*regptr != val) {
228 		*regptr = val;
229 		wbflush();
230 		if (++i > 10000) {
231 			printf("le: Reg did not settle (to x%x): x%x\n", val,
232 			    *regptr);
233 			return;
234 		}
235 		DELAY(100);
236 	}
237 }
238 #endif
239