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