| @@ -1,233 +1,233 @@ | | | @@ -1,233 +1,233 @@ |
1 | /* $NetBSD: netif_of.c,v 1.8 2011/05/21 15:50:42 tsutsui Exp $ */ | | 1 | /* $NetBSD: netif_of.c,v 1.9 2011/07/30 04:18:38 jakllsch Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (C) 1995 Wolfgang Solfrank. | | 4 | * Copyright (C) 1995 Wolfgang Solfrank. |
5 | * Copyright (C) 1995 TooLs GmbH. | | 5 | * Copyright (C) 1995 TooLs GmbH. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. | | 15 | * documentation and/or other materials provided with the distribution. |
16 | * 3. All advertising materials mentioning features or use of this software | | 16 | * 3. All advertising materials mentioning features or use of this software |
17 | * must display the following acknowledgement: | | 17 | * must display the following acknowledgement: |
18 | * This product includes software developed by TooLs GmbH. | | 18 | * This product includes software developed by TooLs GmbH. |
19 | * 4. The name of TooLs GmbH may not be used to endorse or promote products | | 19 | * 4. The name of TooLs GmbH may not be used to endorse or promote products |
20 | * derived from this software without specific prior written permission. | | 20 | * derived from this software without specific prior written permission. |
21 | * | | 21 | * |
22 | * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR | | 22 | * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR |
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
25 | * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | | 25 | * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | | 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | | 27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
28 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | | 28 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | | 29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
30 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | | 30 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
31 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 31 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | /* | | 34 | /* |
35 | * Open Firmware does most of the job for interfacing to the hardware, | | 35 | * Open Firmware does most of the job for interfacing to the hardware, |
36 | * so it is easiest to just replace the netif module with | | 36 | * so it is easiest to just replace the netif module with |
37 | * this adaptation to the PROM network interface. | | 37 | * this adaptation to the PROM network interface. |
38 | * | | 38 | * |
39 | * Note: this is based in part on sys/arch/sparc/stand/netif_sun.c | | 39 | * Note: this is based in part on sys/arch/sparc/stand/netif_sun.c |
40 | */ | | 40 | */ |
41 | | | 41 | |
42 | #include <sys/param.h> | | 42 | #include <sys/param.h> |
43 | #include <sys/socket.h> | | 43 | #include <sys/socket.h> |
44 | | | 44 | |
45 | #include <net/if.h> | | 45 | #include <net/if.h> |
46 | #include <net/if_ether.h> | | 46 | #include <net/if_ether.h> |
47 | | | 47 | |
48 | #include <netinet/in.h> | | 48 | #include <netinet/in.h> |
49 | #include <netinet/in_systm.h> | | 49 | #include <netinet/in_systm.h> |
50 | | | 50 | |
51 | #include <lib/libsa/stand.h> | | 51 | #include <lib/libsa/stand.h> |
52 | #include <lib/libsa/net.h> | | 52 | #include <lib/libsa/net.h> |
53 | #include <lib/libsa/netif.h> | | 53 | #include <lib/libsa/netif.h> |
54 | | | 54 | |
55 | #include <machine/promlib.h> | | 55 | #include <machine/promlib.h> |
56 | | | 56 | |
57 | #include "ofdev.h" | | 57 | #include "ofdev.h" |
58 | | | 58 | |
59 | static struct netif netif_of; | | 59 | static struct netif netif_of; |
60 | | | 60 | |
61 | struct iodesc sockets[SOPEN_MAX]; | | 61 | struct iodesc sockets[SOPEN_MAX]; |
62 | | | 62 | |
63 | struct iodesc * | | 63 | struct iodesc * |
64 | socktodesc(int sock) | | 64 | socktodesc(int sock) |
65 | { | | 65 | { |
66 | if (sock != 0) | | 66 | if (sock != 0) |
67 | return NULL; | | 67 | return NULL; |
68 | return sockets; | | 68 | return sockets; |
69 | } | | 69 | } |
70 | | | 70 | |
71 | int | | 71 | int |
72 | netif_open(void *machdep_hint) | | 72 | netif_open(void *machdep_hint) |
73 | { | | 73 | { |
74 | struct of_dev *op = machdep_hint; | | 74 | struct of_dev *op = machdep_hint; |
75 | struct iodesc *io; | | 75 | struct iodesc *io; |
76 | | | 76 | |
77 | #ifdef NETIF_DEBUG | | 77 | #ifdef NETIF_DEBUG |
78 | printf("netif_open..."); | | 78 | printf("netif_open..."); |
79 | #endif | | 79 | #endif |
80 | /* find a free socket */ | | 80 | /* find a free socket */ |
81 | io = sockets; | | 81 | io = sockets; |
82 | if (io->io_netif) { | | 82 | if (io->io_netif) { |
83 | #ifdef NETIF_DEBUG | | 83 | #ifdef NETIF_DEBUG |
84 | printf("device busy\n"); | | 84 | printf("device busy\n"); |
85 | #endif | | 85 | #endif |
86 | errno = ENFILE; | | 86 | errno = ENFILE; |
87 | return -1; | | 87 | return -1; |
88 | } | | 88 | } |
89 | memset(io, 0, sizeof *io); | | 89 | memset(io, 0, sizeof *io); |
90 | | | 90 | |
91 | netif_of.nif_devdata = op; | | 91 | netif_of.nif_devdata = op; |
92 | io->io_netif = &netif_of; | | 92 | io->io_netif = &netif_of; |
93 | | | 93 | |
94 | /* Put our ethernet address in io->myea */ | | 94 | /* Put our ethernet address in io->myea */ |
95 | _prom_getprop(prom_instance_to_package(op->handle), | | 95 | _prom_getprop(prom_instance_to_package(op->handle), |
96 | "mac-address", io->myea, sizeof io->myea); | | 96 | "mac-address", io->myea, sizeof io->myea); |
97 | | | 97 | |
98 | #ifdef NETIF_DEBUG | | 98 | #ifdef NETIF_DEBUG |
99 | printf("OK\n"); | | 99 | printf("OK\n"); |
100 | #endif | | 100 | #endif |
101 | return 0; | | 101 | return 0; |
102 | } | | 102 | } |
103 | | | 103 | |
104 | int | | 104 | int |
105 | netif_close(int fd) | | 105 | netif_close(int fd) |
106 | { | | 106 | { |
107 | struct iodesc *io; | | 107 | struct iodesc *io; |
108 | struct netif *ni; | | 108 | struct netif *ni; |
109 | | | 109 | |
110 | #ifdef NETIF_DEBUG | | 110 | #ifdef NETIF_DEBUG |
111 | printf("netif_close(%x)...", fd); | | 111 | printf("netif_close(%x)...", fd); |
112 | #endif | | 112 | #endif |
113 | if (fd != 0) { | | 113 | if (fd != 0) { |
114 | #ifdef NETIF_DEBUG | | 114 | #ifdef NETIF_DEBUG |
115 | printf("EBADF\n"); | | 115 | printf("EBADF\n"); |
116 | #endif | | 116 | #endif |
117 | errno = EBADF; | | 117 | errno = EBADF; |
118 | return -1; | | 118 | return -1; |
119 | } | | 119 | } |
120 | | | 120 | |
121 | io = &sockets[fd]; | | 121 | io = &sockets[fd]; |
122 | ni = io->io_netif; | | 122 | ni = io->io_netif; |
123 | if (ni != NULL) { | | 123 | if (ni != NULL) { |
124 | ni->nif_devdata = NULL; | | 124 | ni->nif_devdata = NULL; |
125 | io->io_netif = NULL; | | 125 | io->io_netif = NULL; |
126 | } | | 126 | } |
127 | #ifdef NETIF_DEBUG | | 127 | #ifdef NETIF_DEBUG |
128 | printf("OK\n"); | | 128 | printf("OK\n"); |
129 | #endif | | 129 | #endif |
130 | return 0; | | 130 | return 0; |
131 | } | | 131 | } |
132 | | | 132 | |
133 | /* | | 133 | /* |
134 | * Send a packet. The ether header is already there. | | 134 | * Send a packet. The ether header is already there. |
135 | * Return the length sent (or -1 on error). | | 135 | * Return the length sent (or -1 on error). |
136 | */ | | 136 | */ |
137 | ssize_t | | 137 | ssize_t |
138 | netif_put(struct iodesc *desc, void *pkt, size_t len) | | 138 | netif_put(struct iodesc *desc, void *pkt, size_t len) |
139 | { | | 139 | { |
140 | struct of_dev *op; | | 140 | struct of_dev *op; |
141 | ssize_t rv; | | 141 | ssize_t rv; |
142 | size_t sendlen; | | 142 | size_t sendlen; |
143 | | | 143 | |
144 | op = ((struct netif *)desc->io_netif)->nif_devdata; | | 144 | op = ((struct netif *)desc->io_netif)->nif_devdata; |
145 | | | 145 | |
146 | #ifdef NETIF_DEBUG | | 146 | #ifdef NETIF_DEBUG |
147 | { | | 147 | { |
148 | struct ether_header *eh; | | 148 | struct ether_header *eh; |
149 | | | 149 | |
150 | printf("netif_put: desc=0x%x pkt=0x%x len=%d\n", | | 150 | printf("netif_put: desc=%p pkt=%p len=%zu\n", |
151 | desc, pkt, len); | | 151 | desc, pkt, len); |
152 | eh = pkt; | | 152 | eh = pkt; |
153 | printf("dst: %s ", ether_sprintf(eh->ether_dhost)); | | 153 | printf("dst: %s ", ether_sprintf(eh->ether_dhost)); |
154 | printf("src: %s ", ether_sprintf(eh->ether_shost)); | | 154 | printf("src: %s ", ether_sprintf(eh->ether_shost)); |
155 | printf("type: 0x%x\n", eh->ether_type & 0xFFFF); | | 155 | printf("type: 0x%x\n", eh->ether_type & 0xFFFF); |
156 | } | | 156 | } |
157 | #endif | | 157 | #endif |
158 | | | 158 | |
159 | sendlen = len; | | 159 | sendlen = len; |
160 | if (sendlen < 60) { | | 160 | if (sendlen < 60) { |
161 | sendlen = 60; | | 161 | sendlen = 60; |
162 | #ifdef NETIF_DEBUG | | 162 | #ifdef NETIF_DEBUG |
163 | printf("netif_put: length padded to %d\n", sendlen); | | 163 | printf("netif_put: length padded to %zu\n", sendlen); |
164 | #endif | | 164 | #endif |
165 | } | | 165 | } |
166 | | | 166 | |
167 | rv = prom_write(op->handle, pkt, sendlen); | | 167 | rv = prom_write(op->handle, pkt, sendlen); |
168 | | | 168 | |
169 | #ifdef NETIF_DEBUG | | 169 | #ifdef NETIF_DEBUG |
170 | printf("netif_put: xmit returned %d\n", rv); | | 170 | printf("netif_put: xmit returned %zd\n", rv); |
171 | #endif | | 171 | #endif |
172 | | | 172 | |
173 | if (rv > len) | | 173 | if (rv > len) |
174 | rv = len; | | 174 | rv = len; |
175 | | | 175 | |
176 | return rv; | | 176 | return rv; |
177 | } | | 177 | } |
178 | | | 178 | |
179 | /* | | 179 | /* |
180 | * Receive a packet, including the ether header. | | 180 | * Receive a packet, including the ether header. |
181 | * Return the total length received (or -1 on error). | | 181 | * Return the total length received (or -1 on error). |
182 | */ | | 182 | */ |
183 | ssize_t | | 183 | ssize_t |
184 | netif_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timo) | | 184 | netif_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timo) |
185 | { | | 185 | { |
186 | struct of_dev *op; | | 186 | struct of_dev *op; |
187 | int tick0, tmo_ms; | | 187 | int tick0, tmo_ms; |
188 | int len; | | 188 | int len; |
189 | | | 189 | |
190 | op = ((struct netif *)desc->io_netif)->nif_devdata; | | 190 | op = ((struct netif *)desc->io_netif)->nif_devdata; |
191 | | | 191 | |
192 | #ifdef NETIF_DEBUG | | 192 | #ifdef NETIF_DEBUG |
193 | printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n", | | 193 | printf("netif_get: pkt=%p, maxlen=%zu, tmo=%d\n", |
194 | pkt, maxlen, timo); | | 194 | pkt, maxlen, timo); |
195 | #endif | | 195 | #endif |
196 | | | 196 | |
197 | tmo_ms = timo * 1000; | | 197 | tmo_ms = timo * 1000; |
198 | tick0 = prom_ticks(); | | 198 | tick0 = prom_ticks(); |
199 | | | 199 | |
200 | do { | | 200 | do { |
201 | len = prom_read(op->handle, pkt, maxlen); | | 201 | len = prom_read(op->handle, pkt, maxlen); |
202 | } while ((len == -2 || len == 0) && | | 202 | } while ((len == -2 || len == 0) && |
203 | (prom_ticks() - tick0 < tmo_ms)); | | 203 | (prom_ticks() - tick0 < tmo_ms)); |
204 | | | 204 | |
205 | #ifdef NETIF_DEBUG | | 205 | #ifdef NETIF_DEBUG |
206 | printf("netif_get: received len=%d\n", len); | | 206 | printf("netif_get: received len=%d\n", len); |
207 | #endif | | 207 | #endif |
208 | | | 208 | |
209 | if (len < 12) | | 209 | if (len < 12) |
210 | return -1; | | 210 | return -1; |
211 | | | 211 | |
212 | #ifdef NETIF_DEBUG | | 212 | #ifdef NETIF_DEBUG |
213 | { | | 213 | { |
214 | struct ether_header *eh = pkt; | | 214 | struct ether_header *eh = pkt; |
215 | | | 215 | |
216 | printf("dst: %s ", ether_sprintf(eh->ether_dhost)); | | 216 | printf("dst: %s ", ether_sprintf(eh->ether_dhost)); |
217 | printf("src: %s ", ether_sprintf(eh->ether_shost)); | | 217 | printf("src: %s ", ether_sprintf(eh->ether_shost)); |
218 | printf("type: 0x%x\n", eh->ether_type & 0xFFFF); | | 218 | printf("type: 0x%x\n", eh->ether_type & 0xFFFF); |
219 | } | | 219 | } |
220 | #endif | | 220 | #endif |
221 | | | 221 | |
222 | return len; | | 222 | return len; |
223 | } | | 223 | } |
224 | | | 224 | |
225 | /* | | 225 | /* |
226 | * Shouldn't really be here, but is used solely for networking, so... | | 226 | * Shouldn't really be here, but is used solely for networking, so... |
227 | */ | | 227 | */ |
228 | satime_t | | 228 | satime_t |
229 | getsecs(void) | | 229 | getsecs(void) |
230 | { | | 230 | { |
231 | | | 231 | |
232 | return prom_ticks() / 1000; | | 232 | return prom_ticks() / 1000; |
233 | } | | 233 | } |