netif_news.c revision 1.4 1 /* $NetBSD: netif_news.c,v 1.4 2003/03/13 14:49:12 drochner Exp $ */
2
3 /*
4 * Copyright (c) 1995 Gordon W. Ross
5 * 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 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 * 4. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Gordon W. Ross
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * The Sun PROM has a fairly general set of network drivers,
35 * so it is easiest to just replace the netif module with
36 * this adaptation to the PROM network interface.
37 */
38
39 #include <sys/param.h>
40 #include <sys/socket.h>
41
42 #include <net/if.h>
43 #include <net/if_ether.h>
44
45 #include <netinet/in.h>
46 #include <netinet/in_systm.h>
47
48 #include <lib/libsa/stand.h>
49 #include <lib/libsa/net.h>
50 #include <lib/libkern/libkern.h>
51
52 #include <machine/apcall.h>
53 #include <promdev.h>
54
55 #include "netif_news.h"
56
57 #ifdef NETIF_DEBUG
58 int netif_debug;
59 #endif
60
61 static struct iodesc sdesc;
62
63 struct iodesc *
64 socktodesc(sock)
65 int sock;
66 {
67 if (sock != 0) {
68 return(NULL);
69 }
70 return (&sdesc);
71 }
72
73 int
74 netif_news_open(pd)
75 struct romdev *pd;
76 {
77 struct iodesc *io;
78
79 /* find a free socket */
80 io = &sdesc;
81 if (io->io_netif) {
82 #ifdef DEBUG
83 printf("netif_open: device busy\n");
84 #endif
85 errno = ENFILE;
86 return (-1);
87 }
88 memset(io, 0, sizeof(*io));
89
90 io->io_netif = pd;
91
92 /* Put our ethernet address in io->myea */
93 prom_getether(pd, io->myea);
94
95 return(0);
96 }
97
98 void
99 netif_news_close(fd)
100 int fd;
101 {
102 struct iodesc *io;
103
104 io = &sdesc;
105 io->io_netif = NULL;
106 }
107
108 /*
109 * Send a packet. The ether header is already there.
110 * Return the length sent (or -1 on error).
111 */
112 ssize_t
113 netif_put(desc, pkt, len)
114 struct iodesc *desc;
115 void *pkt;
116 size_t len;
117 {
118 struct romdev *pd;
119 ssize_t rv;
120 size_t sendlen;
121
122 pd = (struct romdev *)desc->io_netif;
123
124 #ifdef NETIF_DEBUG
125 if (netif_debug) {
126 struct ether_header *eh;
127
128 printf("netif_put: desc=0x%x pkt=0x%x len=%d\n",
129 desc, pkt, len);
130 eh = pkt;
131 printf("dst: %s ", ether_sprintf(eh->ether_dhost));
132 printf("src: %s ", ether_sprintf(eh->ether_shost));
133 printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
134 }
135 #endif
136
137 sendlen = len;
138 if (sendlen < 60) {
139 sendlen = 60;
140 #ifdef NETIF_DEBUG
141 printf("netif_put: length padded to %d\n", sendlen);
142 #endif
143 }
144
145 rv = apcall_write(pd->fd, pkt, sendlen);
146
147 #ifdef NETIF_DEBUG
148 if (netif_debug)
149 printf("netif_put: xmit returned %d\n", rv);
150 #endif
151
152 return rv;
153 }
154
155 /*
156 * Receive a packet, including the ether header.
157 * Return the total length received (or -1 on error).
158 */
159 ssize_t
160 netif_get(desc, pkt, maxlen, timo)
161 struct iodesc *desc;
162 void *pkt;
163 size_t maxlen;
164 time_t timo;
165 {
166 struct romdev *pd;
167 int tick0;
168 ssize_t len;
169
170 pd = (struct romdev *)desc->io_netif;
171
172 #ifdef NETIF_DEBUG
173 if (netif_debug)
174 printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n",
175 pkt, maxlen, timo);
176 #endif
177
178 tick0 = getsecs();
179
180 do {
181 len = apcall_read(pd->fd, pkt, maxlen);
182 } while ((len == 0) && ((getsecs() - tick0) < timo));
183
184 #ifdef NETIF_DEBUG
185 if (netif_debug)
186 printf("netif_get: received len=%d\n", len);
187 #endif
188
189 if (len < 12)
190 return -1;
191
192 #ifdef NETIF_DEBUG
193 if (netif_debug) {
194 struct ether_header *eh = pkt;
195
196 printf("dst: %s ", ether_sprintf(eh->ether_dhost));
197 printf("src: %s ", ether_sprintf(eh->ether_shost));
198 printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
199 }
200 #endif
201
202 return len;
203 }
204
205 int
206 prom_getether(pd, ea)
207 struct romdev *pd;
208 u_char *ea;
209 {
210 if (apcall_ioctl(pd->fd, APIOCGIFHWADDR, ea));
211 return -1;
212
213 #ifdef BOOT_DEBUG
214 printf("hardware address %s\n", ether_sprintf(ea));
215 #endif
216
217 return 0;
218 }
219
220 time_t
221 getsecs()
222 {
223 u_int t[2];
224
225 apcall_gettimeofday(t); /* time = t[0](s) + t[1](ns) */
226 return t[0];
227 }
228