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