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