xref: /openbsd/sys/arch/luna88k/dev/if_le.c (revision 91f110e0)
1 /*	$OpenBSD: if_le.c,v 1.6 2013/09/24 20:10:45 miod 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/lancereg.h>
56 #include <dev/ic/lancevar.h>
57 #include <dev/ic/am7990reg.h>
58 #include <dev/ic/am7990var.h>
59 
60 #include <luna88k/luna88k/isr.h>
61 
62 /*
63  * LANCE registers.
64  * The real stuff is in dev/ic/am7990reg.h
65  */
66 struct lereg1 {
67 	volatile uint16_t	ler1_rdp;	/* data port */
68 	volatile unsigned	:16 ;		/* LUNA-88K2 has a 16 bit gap */
69 	volatile uint16_t	ler1_rap;	/* register select port */
70 };
71 
72 /*
73  * Ethernet software status per interface.
74  * The real stuff is in dev/ic/am7990var.h
75  */
76 struct	le_softc {
77 	struct	am7990_softc sc_am7990;	/* glue to MI code */
78 
79 	struct	lereg1 *sc_r1;		/* LANCE registers */
80 };
81 
82 int	le_match(struct device *, void *, void *);
83 void	le_attach(struct device *, struct device *, void *);
84 
85 const struct cfattach le_ca = {
86 	sizeof(struct le_softc), le_match, le_attach
87 };
88 
89 void lewrcsr(struct lance_softc *, uint16_t, uint16_t);
90 uint16_t lerdcsr(struct lance_softc *, uint16_t);
91 void myetheraddr(uint8_t *);
92 
93 void
94 lewrcsr(struct lance_softc *sc, uint16_t port, uint16_t 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 uint16_t
103 lerdcsr(struct lance_softc *sc, uint16_t port)
104 {
105 	register struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
106 	uint16_t val;
107 
108 	ler1->ler1_rap = port;
109 	val = ler1->ler1_rdp;
110 	return (val);
111 }
112 
113 int
114 le_match(struct device *parent, void *cf, void *aux)
115 {
116         struct mainbus_attach_args *ma = aux;
117 
118         if (strcmp(ma->ma_name, le_cd.cd_name))
119                 return (0);
120 
121         return (1);
122 }
123 
124 void
125 le_attach(struct device *parent, struct device *self, void *aux)
126 {
127 	struct le_softc *lesc = (struct le_softc *)self;
128 	struct lance_softc *sc = &lesc->sc_am7990.lsc;
129         struct mainbus_attach_args *ma = aux;
130 
131         lesc->sc_r1 = (struct lereg1 *)ma->ma_addr;     /* LANCE */
132 
133         sc->sc_mem = (void *)0x71000000;                /* SRAM */
134         sc->sc_conf3 = LE_C3_BSWP;
135         sc->sc_addr = (u_long)sc->sc_mem & 0xffffff;
136         sc->sc_memsize = 64 * 1024;                     /* 64KB */
137 
138         myetheraddr(sc->sc_arpcom.ac_enaddr);
139 
140 	sc->sc_copytodesc = lance_copytobuf_contig;
141 	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
142 	sc->sc_copytobuf = lance_copytobuf_contig;
143 	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
144 	sc->sc_zerobuf = lance_zerobuf_contig;
145 
146 	sc->sc_rdcsr = lerdcsr;
147 	sc->sc_wrcsr = lewrcsr;
148 	sc->sc_hwreset = NULL;
149 	sc->sc_hwinit = NULL;
150 
151 	am7990_config(&lesc->sc_am7990);
152 
153         isrlink_autovec(am7990_intr, (void *)sc, ma->ma_ilvl, ISRPRI_NET,
154 	    self->dv_xname);
155 }
156 
157 /*
158  * Partially taken from NetBSD/luna68k
159  *
160  * LUNA-88K has FUSE ROM, which contains MAC address.  The FUSE ROM
161  * contents are stored in fuse_rom_data[] during cpu_startup().
162  *
163  * LUNA-88K2 has 16Kbit NVSRAM on its ethercard, whose contents are
164  * accessible 4bit-wise by ctl register operation.  The register is
165  * mapped at 0xF1000008.
166  */
167 
168 extern int machtype;
169 extern char fuse_rom_data[];
170 
171 void
172 myetheraddr(uint8_t *ether)
173 {
174         unsigned i, loc;
175 	volatile struct { uint32_t ctl; } *ds1220;
176 
177 	switch (machtype) {
178 	case LUNA_88K:
179 		/*
180 		 * fuse_rom_data[] begins with "ENADDR=00000Axxxxxx"
181 		 */
182 		loc = 7;
183 		for (i = 0; i < 6; i++) {
184 			int u, l;
185 
186 			u = fuse_rom_data[loc];
187 			u = (u < 'A') ? u & 0xf : u - 'A' + 10;
188 			l = fuse_rom_data[loc + 1];
189 			l = (l < 'A') ? l & 0xf : l - 'A' + 10;
190 
191 			ether[i] = l | (u << 4);
192 			loc += 2;
193 		}
194 		break;
195 	case LUNA_88K2:
196 		ds1220 = (void *)0xF1000008;
197 		loc = 12;
198 		for (i = 0; i < 6; i++) {
199 			unsigned u, l, hex;
200 
201 			ds1220->ctl = (loc) << 16;
202 			u = 0xf0 & (ds1220->ctl >> 12);
203 			ds1220->ctl = (loc + 1) << 16;
204 			l = 0x0f & (ds1220->ctl >> 16);
205 			hex = (u < '9') ? l : l + 9;
206 
207 			ds1220->ctl = (loc + 2) << 16;
208 			u = 0xf0 & (ds1220->ctl >> 12);
209 			ds1220->ctl = (loc + 3) << 16;
210 			l = 0x0f & (ds1220->ctl >> 16);
211 
212 			ether[i] = ((u < '9') ? l : l + 9) | (hex << 4);
213 			loc += 4;
214 		}
215 		break;
216 	default:
217 		ether[0] = 0x00; ether[1] = 0x00; ether[2] = 0x0a;
218 		ether[3] = 0xDE; ether[4] = 0xAD; ether[5] = 0x00;
219 		break;
220 	}
221 }
222