1 /* $NetBSD: if_prom.c,v 1.6 2009/03/14 14:46:04 dsl Exp $ */
3 /* Copyright (c) 1999 The NetBSD Foundation, Inc.
6 * This code is derived from software contributed to The NetBSD Foundation
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/param.h>
32 #include <sys/types.h>
34 #include <net/if_ether.h>
35 #include <netinet/in.h>
36 #include <netinet/in_systm.h>
37 #include <netinet/ip.h>
39 #include <lib/libsa/stand.h>
40 #include <lib/libsa/net.h>
41 #include <lib/libsa/netif.h>
42 #include <lib/libsa/dev_net.h>
43 #include <lib/libkern/libkern.h>
45 #include <machine/dec_prom.h>
46 #include <stand/common/common.h>
49 void dump_packet_info(void *, int);
53 * For some reason the proms won't pass arp responses back to us. I
54 * have checked if the first parameter to bootread/bootwrite do anything
55 * but it doesn't appear so. Therefore, we stop the upper layers from
56 * sending arp requests in the first place, by monitoring packets which
57 * come in and filling the arp cache ourselves. - gmcgarry
64 extern struct arp_list arp_list
[8];
66 void fill_arpcache(void *, int);
69 /* forward declarations */
70 int prom_probe(struct netif
*, void *);
71 int prom_match(struct netif
*, void *);
72 void prom_init(struct iodesc
*, void *);
73 int prom_get(struct iodesc
*, void *, size_t, saseconds_t
);
74 int prom_put(struct iodesc
*, void *, size_t);
75 void prom_end(struct netif
*);
77 extern struct netif_stats prom_stats
[];
78 struct netif_dif prom_ifs
[] = {
79 /* dif_unit dif_nsel dif_stats dif_private */
80 { 0, 1, &prom_stats
[0], 0, },
82 #define NPROM_IFS (sizeof(prom_ifs) / sizeof(prom_ifs[0]))
83 struct netif_stats prom_stats
[NPROM_IFS
];
85 struct netif_driver prom_netif_driver
= {
86 "prom", /* netif_bname */
87 prom_match
, /* netif_match */
88 prom_probe
, /* netif_probe */
89 prom_init
, /* netif_init */
90 prom_get
, /* netif_get */
91 prom_put
, /* netif_put */
92 prom_end
, /* netif_end */
93 prom_ifs
, /* netif_ifs */
94 NPROM_IFS
/* netif_nifs */
97 static int sc_fd
; /* PROM file id */
100 prom_match(struct netif
*nif
, void *machdep_hint
)
104 printf("prom_match: called\n");
111 prom_probe(struct netif
*nif
, void *machdep_hint
)
115 printf("prom_probe: called\n");
122 prom_init(struct iodesc
*desc
, void *machdep_hint
)
125 ((struct netif
*)desc
->io_netif
)->nif_driver
->netif_bname
;
130 printf("prom_init: called\n");
136 * Get our hardware address (this prom call is one of the rare ones
137 * which is the same for new and old proms)
139 enet
= (*callv
->_getenv
)("enet");
143 printf("enet=%s\n", enet
);
148 for (i
=0; i
<6; i
++) {
154 num
+= (j
<10?j
:j
-39);
160 desc
->xid
= 0x66d30000;
162 if (callv
== &callvec
)
163 sc_fd
= prom_open(device
, 0);
165 sc_fd
= (*callv
->_bootinit
)(device
);
168 printf("problem initialising device\n");
173 prom_put(struct iodesc
*desc
, void *pkt
, size_t len
)
178 printf("prom_put: called\n");
183 dump_packet_info(pkt
,len
);
186 if (callv
== &callvec
)
187 s
= prom_write(sc_fd
, pkt
, len
);
189 s
= (*callv
->_bootwrite
)(0, pkt
, len
);
190 (*callv
->_wbflush
)(); /* didn't really make a difference */
199 prom_get(struct iodesc
*desc
, void *pkt
, size_t len
, saseconds_t timeout
)
205 printf("prom_get: called\n");
210 while (((getsecs() - t
) < timeout
) && !s
) {
211 if (callv
== &callvec
)
212 s
= prom_read(sc_fd
, pkt
, len
);
214 s
= (*callv
->_bootread
)(0, pkt
, len
);
219 fill_arpcache(pkt
,s
);
228 prom_end(struct netif
*nif
)
232 printf("prom_end: called\n");
235 if (callv
== &callvec
)
241 void fill_arpcache (pkt
, len
)
247 struct ether_header
*eh
= (struct ether_header
*)pkt
;
248 struct ip
*ih
= (struct ip
*)(eh
+ 1);
252 dump_packet_info(pkt
, len
);
255 if (ntohs(eh
->ether_type
) == 0x0800) {
257 /* check arp cache */
258 for (i
=0, al
=arp_list
; i
<arp_num
; ++i
, ++al
) {
259 if (al
->addr
.s_addr
== ih
->ip_src
.s_addr
) {
260 /* already in cache */
265 arp_num
= 1; /* recycle */
266 al
->addr
.s_addr
= ih
->ip_src
.s_addr
;
268 al
->ea
[i
] = eh
->ether_shost
[i
];
276 void dump_packet_info(pkt
, len
)
280 struct ether_header
*eh
= (struct ether_header
*)pkt
;
281 struct ip
*ih
= (struct ip
*)(eh
+ 1);
283 printf("ether_dhost = %s\n", ether_sprintf(eh
->ether_dhost
));
284 printf("ether_shost = %s\n", ether_sprintf(eh
->ether_shost
));
285 printf("ether_type = 0x%x\n", ntohs(eh
->ether_type
));
287 if (ntohs(eh
->ether_type
) == 0x0800) {
288 printf("ip packet version %d\n", ih
->ip_v
);
289 printf("source ip: 0x%x\n", ih
->ip_src
.s_addr
);
290 printf("dest ip: 0x%x\n", ih
->ip_dst
.s_addr
);