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