xref: /netbsd-src/sys/arch/luna68k/stand/boot/if_le.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* $NetBSD: if_le.c,v 1.6 2014/01/11 15:51:02 tsutsui Exp $ */
2 
3 /*
4  * Copyright (c) 2013 Izumi Tsutsui.  All rights reserved.
5  * Copyright (c) 2003 Tetsuya Isaki. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 /*
29  * Copyright (c) 1982, 1990, 1993
30  *      The Regents of the University of California.  All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  * 1. Redistributions of source code must retain the above copyright
36  *    notice, this list of conditions and the following disclaimer.
37  * 2. Redistributions in binary form must reproduce the above copyright
38  *    notice, this list of conditions and the following disclaimer in the
39  *    documentation and/or other materials provided with the distribution.
40  * 3. Neither the name of the University nor the names of its contributors
41  *    may be used to endorse or promote products derived from this software
42  *    without specific prior written permission.
43  *
44  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54  * SUCH DAMAGE.
55  *
56  * from: hp300/dev/if_le.c      7.16 (Berkeley) 3/11/93
57  *
58  *      @(#)if_le.c     8.1 (Berkeley) 6/10/93
59  */
60 
61 #include <sys/param.h>
62 
63 #include <machine/cpu.h>
64 
65 #include <net/if.h>
66 #include <net/if_ether.h>
67 #include <netinet/in.h>
68 #include <netinet/in_systm.h>
69 
70 #include <lib/libsa/stand.h>
71 #include <lib/libsa/net.h>
72 #include <lib/libsa/netif.h>
73 
74 #include <luna68k/stand/boot/samachdep.h>
75 
76 /* libsa netif_driver glue functions */
77 static int  le_match(struct netif *, void *);
78 static int  le_probe(struct netif *, void *);
79 static void le_init(struct iodesc *, void *);
80 static int  le_get(struct iodesc *, void *, size_t, saseconds_t);
81 static int  le_put(struct iodesc *, void *, size_t);
82 static void le_end(struct netif *);
83 
84 static void myetheraddr(uint8_t *);
85 
86 /* libsa netif glue stuff */
87 struct netif_stats le_stats;
88 struct netif_dif le_ifs[] = {
89 	{ 0, 1, &le_stats, 0, 0, },
90 };
91 
92 struct netif_driver le_netif_driver = {
93 	"le",
94 	le_match,
95 	le_probe,
96 	le_init,
97 	le_get,
98 	le_put,
99 	le_end,
100 	le_ifs,
101 	__arraycount(le_ifs),
102 };
103 
104 #ifdef DEBUG
105 int debug;
106 #endif
107 
108 int
109 leinit(int unit, void *addr)
110 {
111 	void *cookie;
112 	void *reg, *mem;
113 	uint8_t eaddr[6];
114 
115 	reg = addr;
116 	mem = (void *)0x71010000;	/* XXX */
117 
118 	myetheraddr(eaddr);
119 
120 	cookie = lance_attach(unit, reg, mem, eaddr);
121 	if (cookie == NULL)
122 		return 0;
123 
124 	printf("le%d: Am7990 LANCE Ethernet, mem at 0x%x\n",
125 	    unit, (uint32_t)mem);
126 	printf("le%d: Ethernet address = %s\n",
127 	    unit, ether_sprintf(eaddr));
128 
129 	return 1;
130 }
131 
132 static int
133 le_match(struct netif *nif, void *machdep_hint)
134 {
135 	void *cookie;
136 	uint8_t *eaddr;
137 
138 	/* XXX should check nif_unit and unit number in machdep_hint path */
139 
140 	cookie = lance_cookie(nif->nif_unit);
141 	if (cookie == NULL)
142 		return 0;
143 
144 	eaddr = lance_eaddr(cookie);
145 	if (eaddr == NULL)
146 		return 0;
147 
148 	return 1;
149 }
150 
151 static int
152 le_probe(struct netif *nif, void *machdep_hint)
153 {
154 
155 	/* XXX what should be checked? */
156 
157 	return 0;
158 }
159 
160 static void
161 le_init(struct iodesc *desc, void *machdep_hint)
162 {
163 	struct netif *nif = desc->io_netif;
164 	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
165 	void *cookie;
166 	uint8_t *eaddr;
167 
168 #ifdef DEBUG
169 	printf("%s\n", __func__);
170 #endif
171 
172 	cookie = lance_cookie(nif->nif_unit);
173 	eaddr = lance_eaddr(cookie);
174 
175 	lance_init(cookie);
176 
177 	/* fill glue stuff */
178 	dif->dif_private = cookie;
179 	memcpy(desc->myea, eaddr, 6);
180 }
181 
182 static int
183 le_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timeout)
184 {
185 	struct netif *nif = desc->io_netif;
186 	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
187 	void *cookie = dif->dif_private;
188 	int len = -1;
189 	saseconds_t t;
190 
191 	t = getsecs() + timeout;
192 	while (getsecs() < t) {
193 		len = lance_get(cookie, pkt, len);
194 		if (len > 0)
195 			break;
196 	}
197 
198 	return len;
199 }
200 
201 static int
202 le_put(struct iodesc *desc, void *pkt, size_t len)
203 {
204 	struct netif *nif = desc->io_netif;
205 	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
206 	void *cookie = dif->dif_private;
207 #ifdef DEBUG
208 	struct ether_header *eh;
209 
210 	eh = pkt;
211 	printf("dst:  %s\n", ether_sprintf(eh->ether_dhost));
212 	printf("src:  %s\n", ether_sprintf(eh->ether_shost));
213 	printf("type: 0x%x\n", eh->ether_type & 0xffff);
214 #endif
215 
216 	return lance_put(cookie, pkt, len) ? len : -1;
217 }
218 
219 static void
220 le_end(struct netif *nif)
221 {
222 	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
223 	void *cookie = dif->dif_private;
224 
225 #ifdef DEBUG
226 	printf("%s\n", __func__);
227 #endif
228 	lance_end(cookie);
229 }
230 
231 static void
232 myetheraddr(uint8_t *ether)
233 {
234 	unsigned int i, loc;
235 	uint8_t *ea;
236 	volatile struct { uint32_t ctl; } *ds1220;
237 
238 	switch (machtype) {
239 	case LUNA_I:
240 		ea = (uint8_t *)0x4101FFE0;
241 		for (i = 0; i < ETHER_ADDR_LEN; i++) {
242 			int u, l;
243 
244 			u = ea[0];
245 			u = (u < 'A') ? u & 0xf : u - 'A' + 10;
246 			l = ea[1];
247 			l = (l < 'A') ? l & 0xf : l - 'A' + 10;
248 
249 			ether[i] = l | (u << 4);
250 			ea += 2;
251 		}
252 		break;
253 	case LUNA_II:
254 		ds1220 = (void *)0xF1000004;
255 		loc = 12;
256 		for (i = 0; i < ETHER_ADDR_LEN; i++) {
257 			unsigned int u, l, hex;
258 
259 			ds1220->ctl = (loc) << 16;
260 			u = 0xf0 & (ds1220->ctl >> 12);
261 			ds1220->ctl = (loc + 1) << 16;
262 			l = 0x0f & (ds1220->ctl >> 16);
263 			hex = (u < '9') ? l : l + 9;
264 
265 			ds1220->ctl = (loc + 2) << 16;
266 			u = 0xf0 & (ds1220->ctl >> 12);
267 			ds1220->ctl = (loc + 3) << 16;
268 			l = 0x0f & (ds1220->ctl >> 16);
269 
270 			ether[i] = ((u < '9') ? l : l + 9) | (hex << 4);
271 			loc += 4;
272 		}
273 		break;
274 	default:
275 		ether[0] = 0x00; ether[1] = 0x00; ether[2] = 0x0a;
276 		ether[3] = 0xDE; ether[4] = 0xAD; ether[5] = 0x00;
277 		break;
278 	}
279 }
280