1 /* $NetBSD: netif_sun.c,v 1.8 2009/01/12 11:32:45 tsutsui Exp $ */
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * The Sun PROM has a fairly general set of network drivers,
34 * so it is easiest to just replace the netif module with
35 * this adaptation to the PROM network interface.
38 #include <sys/param.h>
39 #include <sys/socket.h>
42 #include <net/if_ether.h>
44 #include <netinet/in.h>
45 #include <netinet/in_systm.h>
47 #include <machine/idprom.h>
48 #include <machine/mon.h>
53 #include <lib/libkern/libkern.h>
60 #define PKT_BUF_SIZE 2048
64 struct iodesc sockets
[SOPEN_MAX
];
66 struct netif prom_netif
;
77 struct devdata
* netif_init(void *);
78 void netif_fini(struct devdata
*);
79 int netif_attach(struct netif
*, struct iodesc
*, void *);
80 void netif_detach(struct netif
*);
82 void netif_getether(struct saif
*, u_char
*);
86 * Open the PROM device.
87 * Return netif ptr on success.
92 struct devdata
*dd
= &netif_devdata
;
98 * Setup our part of the saioreq.
99 * (determines what gets opened)
102 memset(si
, 0, sizeof(*si
));
103 bp
= *romVectorPtr
->bootParam
;
104 si
->si_boottab
= bp
->bootDevice
;
105 si
->si_ctlr
= bp
->ctlrNum
;
106 si
->si_unit
= bp
->unitNum
;
107 si
->si_boff
= bp
->partNum
;
111 printf("netif_init: calling prom_iopen\n");
115 * Note: Sun PROMs will do RARP on open, but does not tell
116 * you the IP address it gets, so it is just noise to us...
118 if ((error
= prom_iopen(si
)) != 0) {
119 printf("netif_init: prom_iopen, error=%d\n", error
);
123 if (si
->si_sif
== NULL
) {
124 printf("netif_init: not a network device\n");
129 /* Allocate the transmit/receive buffers. */
130 if (dd
->rbuf
== NULL
) {
131 dd
->rbuf_len
= PKT_BUF_SIZE
;
132 dd
->rbuf
= dvma_alloc(dd
->rbuf_len
);
134 if (dd
->tbuf
== NULL
) {
135 dd
->tbuf_len
= PKT_BUF_SIZE
;
136 dd
->tbuf
= dvma_alloc(dd
->tbuf_len
);
138 if ((dd
->rbuf
== NULL
) ||
140 panic("netif_init: malloc failed");
144 printf("netif_init: rbuf=0x%x, tbuf=0x%x\n",
148 /* Record our ethernet address. */
149 netif_getether(si
->si_sif
, dd
->dd_myea
);
157 netif_fini(struct devdata
*dd
)
165 printf("netif_fini: calling prom_iclose\n");
169 /* Dellocate the transmit/receive buffers. */
171 dvma_free(dd
->rbuf
, dd
->rbuf_len
);
175 dvma_free(dd
->tbuf
, dd
->tbuf_len
);
181 netif_attach(struct netif
*nif
, struct iodesc
*s
, void *aux
)
185 dd
= nif
->nif_devdata
;
187 dd
= netif_init(aux
);
190 nif
->nif_devdata
= dd
;
193 MACPY(dd
->dd_myea
, s
->myea
);
199 netif_detach(struct netif
*nif
)
203 dd
= nif
->nif_devdata
;
207 if (dd
->dd_opens
> 0)
210 nif
->nif_devdata
= NULL
;
214 netif_open(void *aux
)
220 /* find a free socket */
221 for (fd
= 0, s
= sockets
; fd
< SOPEN_MAX
; fd
++, s
++)
222 if (s
->io_netif
== NULL
)
228 memset(s
, 0, sizeof(*s
));
230 error
= netif_attach(nif
, s
, aux
);
244 if (fd
< 0 || fd
>= SOPEN_MAX
) {
250 /* Already closed? */
262 if (fd
< 0 || fd
>= SOPEN_MAX
) {
266 return (&sockets
[fd
]);
271 * Send a packet. The ether header is already there.
272 * Return the length sent (or -1 on error).
275 netif_put(struct iodesc
*desc
, void *pkt
, size_t len
)
285 struct ether_header
*eh
;
287 printf("netif_put: desc=0x%x pkt=0x%x len=%d\n",
290 printf("dst: %s ", ether_sprintf(eh
->ether_dhost
));
291 printf("src: %s ", ether_sprintf(eh
->ether_shost
));
292 printf("type: 0x%x\n", eh
->ether_type
& 0xFFFF);
296 nif
= desc
->io_netif
;
297 dd
= nif
->nif_devdata
;
304 panic("netif_put: no saif ptr");
308 * Copy into our transmit buffer because the PROM
309 * network driver might continue using the packet
310 * after the sif_xmit call returns. We never send
311 * very much data anyway, so the copy is fine.
313 if (slen
> dd
->tbuf_len
)
314 panic("netif_put: slen=%d", slen
);
315 memcpy(dd
->tbuf
, pkt
, slen
);
321 rv
= (*sif
->sif_xmit
)(si
->si_devdata
, dd
->tbuf
, slen
);
325 printf("netif_put: xmit returned %d\n", rv
);
328 * Just ignore the return value. If the PROM transmit
329 * function fails, it will make some noise, such as:
337 * Receive a packet, including the ether header.
338 * Return the total length received (or -1 on error).
341 netif_get(struct iodesc
*desc
, void *pkt
, size_t maxlen
, saseconds_t timo
)
347 int tick0
, tmo_ticks
;
352 printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n",
356 nif
= desc
->io_netif
;
357 dd
= nif
->nif_devdata
;
361 tmo_ticks
= timo
* hz
;
363 /* Have to receive into our own buffer and copy. */
367 rlen
= (*sif
->sif_poll
)(si
->si_devdata
, dd
->rbuf
);
370 } while (getticks() == tick0
);
371 } while (--tmo_ticks
> 0);
374 /* No packet arrived. Better reset the interface. */
375 printf("netif_get: timeout; resetting\n");
376 (*sif
->sif_reset
)(si
->si_devdata
, si
);
383 printf("netif_get: received rlen=%d\n", rlen
);
386 /* Need at least a valid Ethernet header. */
390 /* If we went beyond our buffer, were dead! */
391 if (rlen
> dd
->rbuf_len
)
392 panic("netif_get: rlen=%d", rlen
);
394 /* The caller's buffer may be smaller... */
398 memcpy(pkt
, dd
->rbuf
, rlen
);
402 struct ether_header
*eh
= pkt
;
404 printf("dst: %s ", ether_sprintf(eh
->ether_dhost
));
405 printf("src: %s ", ether_sprintf(eh
->ether_shost
));
406 printf("type: 0x%x\n", eh
->ether_type
& 0xFFFF);
414 * Copy our Ethernet address into the passed array.
417 netif_getether(struct saif
*sif
, u_char
*ea
)
423 * Sun3: These usually have old PROMs
424 * without the sif_macaddr function, but
425 * reading the IDPROM on these machines is
426 * very easy, so just always do that.
428 idprom_etheraddr(ea
);
433 * Sun3X: Want to use sif->sif_macaddr(), but
434 * it's only in PROM revisions 3.0 and later,
435 * so we have to check the PROM rev first.
436 * Note that old PROMs prefix the rev string
437 * with "Rev " (i.e. "Rev 2.6").
439 rev
= romVectorPtr
->monId
;
440 if (!strncmp(rev
, "Rev ", 4))
442 if (!strncmp(rev
, "3.", 2)) {
443 /* Great! We can call the PROM. */
444 (*sif
->sif_macaddr
)(ea
);
449 * Sun3X with PROM rev < 3.0.
450 * Finding the IDPROM is a pain, but
451 * we have no choice. Warn the user.
453 printf("netboot: Old PROM Rev (%s)\n", rev
);
454 idprom_etheraddr(ea
);