xref: /openbsd/sys/arch/luna88k/stand/boot/if_le.c (revision 09467b48)
1 /*	$OpenBSD: if_le.c,v 1.4 2014/08/21 14:24:08 mpi 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 
66 #include <luna88k/stand/boot/samachdep.h>
67 #include <machine/board.h>
68 #include <lib/libsa/net.h>
69 #include <lib/libsa/netif.h>
70 
71 /* libsa netif_driver glue functions */
72 static int  le_match(struct netif *, void *);
73 static int  le_probe(struct netif *, void *);
74 static void le_init(struct iodesc *, void *);
75 static int  le_get(struct iodesc *, void *, size_t, time_t);
76 static int  le_put(struct iodesc *, void *, size_t);
77 static void le_end(struct netif *);
78 
79 static void myetheraddr(uint8_t *);
80 
81 /* libsa netif glue stuff */
82 struct netif_stats le_stats;
83 struct netif_dif le_ifs[] = {
84 	{ 0, 1, &le_stats, 0, 0, },
85 };
86 
87 struct netif_driver le_netif_driver = {
88 	"le",
89 	le_match,
90 	le_probe,
91 	le_init,
92 	le_get,
93 	le_put,
94 	le_end,
95 	le_ifs,
96 	sizeof(le_ifs) / sizeof(le_ifs[0]),
97 };
98 
99 int
100 leinit(void)
101 {
102 	void *cookie;
103 	void *reg, *mem;
104 	uint8_t eaddr[6];
105 
106 	reg = (void *)LANCE_ADDR;
107 	mem = (void *)(TRI_PORT_RAM + 0x010000);	/* XXX */
108 
109 	if (badaddr(reg, 4) != 0)
110 		return 0;
111 
112 	myetheraddr(eaddr);
113 
114 	cookie = lance_attach(0, reg, mem, eaddr);
115 	if (cookie == NULL)
116 		return 0;
117 
118 	printf("le0: Ethernet address %s\n", ether_sprintf(eaddr));
119 
120 	return 1;
121 }
122 
123 static int
124 le_match(struct netif *nif, void *machdep_hint)
125 {
126 	void *cookie;
127 	uint8_t *eaddr;
128 
129 	/* XXX should check nif_unit and unit number in machdep_hint path */
130 
131 	cookie = lance_cookie(nif->nif_unit);
132 	if (cookie == NULL && nif->nif_unit == 0 && leinit() != 0)
133 		cookie = lance_cookie(nif->nif_unit);
134 	if (cookie == NULL)
135 		return 0;
136 
137 	eaddr = lance_eaddr(cookie);
138 	if (eaddr == NULL)
139 		return 0;
140 
141 	return 1;
142 }
143 
144 static int
145 le_probe(struct netif *nif, void *machdep_hint)
146 {
147 
148 	/* XXX what should be checked? */
149 
150 	return 0;
151 }
152 
153 static void
154 le_init(struct iodesc *desc, void *machdep_hint)
155 {
156 	struct netif *nif = desc->io_netif;
157 	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
158 	void *cookie;
159 	uint8_t *eaddr;
160 
161 #ifdef DEBUG
162 	printf("%s\n", __func__);
163 #endif
164 
165 	cookie = lance_cookie(nif->nif_unit);
166 	eaddr = lance_eaddr(cookie);
167 
168 	lance_init(cookie);
169 
170 	/* fill glue stuff */
171 	dif->dif_private = cookie;
172 	memcpy(desc->myea, eaddr, 6);
173 }
174 
175 static int
176 le_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout)
177 {
178 	struct netif *nif = desc->io_netif;
179 	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
180 	void *cookie = dif->dif_private;
181 	int len = -1;
182 	time_t t;
183 
184 	t = getsecs() + timeout;
185 	while (getsecs() < t) {
186 		len = lance_get(cookie, pkt, len);
187 		if (len > 0)
188 			break;
189 	}
190 
191 	return len;
192 }
193 
194 static int
195 le_put(struct iodesc *desc, void *pkt, size_t len)
196 {
197 	struct netif *nif = desc->io_netif;
198 	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
199 	void *cookie = dif->dif_private;
200 #ifdef DEBUG
201  	struct ether_header *eh;
202 
203  	eh = pkt;
204  	printf("dst:  %s\n", ether_sprintf(eh->ether_dhost));
205  	printf("src:  %s\n", ether_sprintf(eh->ether_shost));
206  	printf("type: 0x%x\n", eh->ether_type & 0xffff);
207 #endif
208 
209 	return lance_put(cookie, pkt, len) ? len : -1;
210 }
211 
212 static void
213 le_end(struct netif *nif)
214 {
215 	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
216 	void *cookie = dif->dif_private;
217 
218 #ifdef DEBUG
219 	printf("%s\n", __func__);
220 #endif
221 	lance_end(cookie);
222 }
223 
224 static void
225 myetheraddr(uint8_t *ether)
226 {
227 	unsigned int i, loc;
228 	volatile struct { uint32_t ctl; } *ds1220;
229 
230 	switch (machtype) {
231 	case LUNA_88K:
232 		/*
233 		 * fuse_rom_data[] begins with "ENADDR=00000Axxxxxx"
234 		 */
235 		loc = 7;
236 		for (i = 0; i < 6; i++) {
237 			int u, l;
238 
239 			u = fuse_rom_data[loc];
240 			u = (u < 'A') ? u & 0xf : u - 'A' + 10;
241 			l = fuse_rom_data[loc + 1];
242 			l = (l < 'A') ? l & 0xf : l - 'A' + 10;
243 
244 			ether[i] = l | (u << 4);
245 			loc += 2;
246 		}
247 		break;
248 	case LUNA_88K2:
249 		ds1220 = (void *)(LANCE_ADDR + 8);
250 		loc = 12;
251 		for (i = 0; i < 6; i++) {
252 			unsigned int u, l, hex;
253 
254 			ds1220->ctl = (loc) << 16;
255 			u = 0xf0 & (ds1220->ctl >> 12);
256 			ds1220->ctl = (loc + 1) << 16;
257 			l = 0x0f & (ds1220->ctl >> 16);
258 			hex = (u < '9') ? l : l + 9;
259 
260 			ds1220->ctl = (loc + 2) << 16;
261 			u = 0xf0 & (ds1220->ctl >> 12);
262 			ds1220->ctl = (loc + 3) << 16;
263 			l = 0x0f & (ds1220->ctl >> 16);
264 
265 			ether[i] = ((u < '9') ? l : l + 9) | (hex << 4);
266 			loc += 4;
267 		}
268 		break;
269 	default:
270 		ether[0] = 0x00; ether[1] = 0x00; ether[2] = 0x0a;
271 		ether[3] = 0xDE; ether[4] = 0xAD; ether[5] = 0x00;
272 		break;
273 	}
274 }
275