xref: /openbsd/sys/arch/luna88k/dev/if_le.c (revision 898184e3)
1 /*	$OpenBSD: if_le.c,v 1.5 2008/06/26 05:42:11 ray Exp $	*/
2 /*	$NetBSD: if_le.c,v 1.33 1996/11/20 18:56:52 gwr Exp $	*/
3 
4 /*-
5  * Copyright (c) 1996 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Adam Glass and Gordon W. Ross.
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 REGENTS OR CONTRIBUTORS BE
24  * 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 /* based on OpenBSD: sys/arch/sun3/dev/if_le.c */
34 
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/mbuf.h>
38 #include <sys/syslog.h>
39 #include <sys/socket.h>
40 #include <sys/device.h>
41 
42 #include <net/if.h>
43 
44 #ifdef INET
45 #include <netinet/in.h>
46 #include <netinet/if_ether.h>
47 #endif
48 
49 #include <net/if_media.h>
50 
51 #include <machine/autoconf.h>
52 #include <machine/board.h>
53 #include <machine/cpu.h>
54 
55 #include <dev/ic/am7990reg.h>
56 #include <dev/ic/am7990var.h>
57 
58 #include <luna88k/luna88k/isr.h>
59 
60 /*
61  * LANCE registers.
62  * The real stuff is in dev/ic/am7990reg.h
63  */
64 struct lereg1 {
65 	volatile u_int16_t	ler1_rdp;	/* data port */
66 	volatile unsigned	: 16 ;		/* LUNA-88K2 has a 16 bit gap */
67 	volatile u_int16_t	ler1_rap;	/* register select port */
68 };
69 
70 /*
71  * Ethernet software status per interface.
72  * The real stuff is in dev/ic/am7990var.h
73  */
74 struct	le_softc {
75 	struct	am7990_softc sc_am7990;	/* glue to MI code */
76 
77 	struct	lereg1 *sc_r1;		/* LANCE registers */
78 };
79 
80 static int	le_match(struct device *, void *, void *);
81 static void	le_attach(struct device *, struct device *, void *);
82 
83 struct cfattach le_ca = {
84 	sizeof(struct le_softc), le_match, le_attach
85 };
86 
87 hide void lewrcsr(struct am7990_softc *, u_int16_t, u_int16_t);
88 hide u_int16_t lerdcsr(struct am7990_softc *, u_int16_t);
89 hide void myetheraddr(u_int8_t *);
90 
91 hide void
92 lewrcsr(sc, port, val)
93 	struct am7990_softc *sc;
94 	u_int16_t port, val;
95 {
96 	register struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
97 
98 	ler1->ler1_rap = port;
99 	ler1->ler1_rdp = val;
100 }
101 
102 hide u_int16_t
103 lerdcsr(sc, port)
104 	struct am7990_softc *sc;
105 	u_int16_t port;
106 {
107 	register struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
108 	u_int16_t val;
109 
110 	ler1->ler1_rap = port;
111 	val = ler1->ler1_rdp;
112 	return (val);
113 }
114 
115 static int
116 le_match(parent, cf, aux)
117         struct device *parent;
118         void *cf, *aux;
119 {
120         struct mainbus_attach_args *ma = aux;
121 
122         if (strcmp(ma->ma_name, le_cd.cd_name))
123                 return (0);
124 
125         return (1);
126 }
127 
128 void
129 le_attach(parent, self, aux)
130         struct device *parent, *self;
131         void *aux;
132 {
133 	struct le_softc *lesc = (struct le_softc *)self;
134 	struct am7990_softc *sc = &lesc->sc_am7990;
135         struct mainbus_attach_args *ma = aux;
136 
137         lesc->sc_r1 = (struct lereg1 *)ma->ma_addr;     /* LANCE */
138 
139         sc->sc_mem = (void *)0x71000000;                /* SRAM */
140         sc->sc_conf3 = LE_C3_BSWP;
141         sc->sc_addr = (u_long)sc->sc_mem & 0xffffff;
142         sc->sc_memsize = 64 * 1024;                     /* 64KB */
143 
144         myetheraddr(sc->sc_arpcom.ac_enaddr);
145 
146 	sc->sc_copytodesc = am7990_copytobuf_contig;
147 	sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
148 	sc->sc_copytobuf = am7990_copytobuf_contig;
149 	sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
150 	sc->sc_zerobuf = am7990_zerobuf_contig;
151 
152 	sc->sc_rdcsr = lerdcsr;
153 	sc->sc_wrcsr = lewrcsr;
154 	sc->sc_hwreset = NULL;
155 	sc->sc_hwinit = NULL;
156 
157 	am7990_config(sc);
158 
159         isrlink_autovec(am7990_intr, (void *)sc, ma->ma_ilvl, ISRPRI_NET,
160 	    self->dv_xname);
161 }
162 
163 /*
164  * Partially taken from NetBSD/luna68k
165  *
166  * LUNA-88K has FUSE ROM, which contains MAC address.  The FUSE ROM
167  * contents are stored in fuse_rom_data[] during cpu_startup().
168  *
169  * LUNA-88K2 has 16Kbit NVSRAM on its ethercard, whose contents are
170  * accessible 4bit-wise by ctl register operation.  The register is
171  * mapped at 0xF1000008.
172  */
173 
174 extern int machtype;
175 extern char fuse_rom_data[];
176 
177 hide void
178 myetheraddr(ether)
179         u_int8_t *ether;
180 {
181         unsigned i, loc;
182 	volatile struct { u_int32_t ctl; } *ds1220;
183 
184 	switch (machtype) {
185 	case LUNA_88K:
186 		/*
187 		 * fuse_rom_data[] begins with "ENADDR=00000Axxxxxx"
188 		 */
189 		loc = 7;
190 		for (i = 0; i < 6; i++) {
191 			int u, l;
192 
193 			u = fuse_rom_data[loc];
194 			u = (u < 'A') ? u & 0xf : u - 'A' + 10;
195 			l = fuse_rom_data[loc + 1];
196 			l = (l < 'A') ? l & 0xf : l - 'A' + 10;
197 
198 			ether[i] = l | (u << 4);
199 			loc += 2;
200 		}
201 		break;
202 	case LUNA_88K2:
203 		ds1220 = (void *)0xF1000008;
204 		loc = 12;
205 		for (i = 0; i < 6; i++) {
206 			unsigned u, l, hex;
207 
208 			ds1220->ctl = (loc) << 16;
209 			u = 0xf0 & (ds1220->ctl >> 12);
210 			ds1220->ctl = (loc + 1) << 16;
211 			l = 0x0f & (ds1220->ctl >> 16);
212 			hex = (u < '9') ? l : l + 9;
213 
214 			ds1220->ctl = (loc + 2) << 16;
215 			u = 0xf0 & (ds1220->ctl >> 12);
216 			ds1220->ctl = (loc + 3) << 16;
217 			l = 0x0f & (ds1220->ctl >> 16);
218 
219 			ether[i] = ((u < '9') ? l : l + 9) | (hex << 4);
220 			loc += 4;
221 		}
222 		break;
223 	default:
224 		ether[0] = 0x00; ether[1] = 0x00; ether[2] = 0x0a;
225 		ether[3] = 0xDE; ether[4] = 0xAD; ether[5] = 0x00;
226 		break;
227 	}
228 }
229