if_bug.c revision 1.2.8.1 1 /* $NetBSD: if_bug.c,v 1.2.8.1 2009/01/19 13:16:32 skrll Exp $ */
2
3 /*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Steve C. Woodford.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
18 *
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.
30 */
31
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35
36 #include <netinet/in.h>
37 #include <netinet/in_systm.h>
38
39 #include <net/if.h>
40 #include <net/if_ether.h>
41
42 #include <lib/libkern/libkern.h>
43 #include <lib/libsa/stand.h>
44 #include <lib/libsa/net.h>
45 #include <lib/libsa/netif.h>
46
47 #include "libsa.h"
48 #include "bugsyscalls.h"
49
50 static int bug_match(struct netif *, void *);
51 static int bug_probe(struct netif *, void *);
52 static void bug_init(struct iodesc *, void *);
53 static int bug_get(struct iodesc *, void *, size_t, saseconds_t);
54 static int bug_put(struct iodesc *, void *, size_t);
55 static void bug_end(struct netif *);
56
57 static struct netif_stats bug_stats;
58
59 static struct netif_dif bug0_dif = {
60 0, 1, &bug_stats, 0, 0
61 };
62
63 struct netif_driver bug_driver = {
64 "net", /* netif_bname */
65 bug_match, /* match */
66 bug_probe, /* probe */
67 bug_init, /* init */
68 bug_get, /* get */
69 bug_put, /* put */
70 bug_end, /* end */
71 &bug0_dif, /* netif_ifs */
72 1, /* netif_nifs */
73 };
74
75 struct bug_softc {
76 u_int32_t sc_pad1;
77 u_int8_t sc_rxbuf[ETHER_MAX_LEN];
78 u_int32_t sc_pad2;
79 u_int8_t sc_txbuf[ETHER_MAX_LEN];
80 };
81
82 static struct bug_softc bug_softc;
83
84 int
85 bug_match(nif, machdep_hint)
86 struct netif *nif;
87 void *machdep_hint;
88 {
89
90 if (machdep_hint &&
91 memcmp(bug_driver.netif_bname, machdep_hint,
92 strlen(bug_driver.netif_bname)) == 0)
93 return (1);
94
95 return (0);
96 }
97
98 int
99 bug_probe(nif, machdep_hint)
100 struct netif *nif;
101 void *machdep_hint;
102 {
103
104 return (0);
105 }
106
107 void
108 bug_init(desc, machdep_hint)
109 struct iodesc *desc;
110 void *machdep_hint;
111 {
112 struct netif *nif = desc->io_netif;
113 struct bug_netio nio;
114
115 nio.nc_clun = 0;
116 nio.nc_dlun = 0;
117 nio.nc_status = 0;
118 nio.nc_command = BUG_NETIO_CMD_GET_MAC;
119 nio.nc_buffer = desc->myea;
120 nio.nc_length = 6;
121 nio.nc_csr = 0;
122
123 if (bugsys_netio(&nio) != 0 || nio.nc_status != 0)
124 panic("bug_init: Failed to get MAC address! (code 0x%x)",
125 nio.nc_status);
126
127 nio.nc_clun = 0;
128 nio.nc_dlun = 0;
129 nio.nc_status = 0;
130 nio.nc_command = BUG_NETIO_CMD_FLUSH;
131 nio.nc_buffer = NULL;
132 nio.nc_length = 0;
133 nio.nc_csr = 0;
134
135 if (bugsys_netio(&nio) != 0 || nio.nc_status != 0)
136 panic("bug_init: Failed to flush netio device (code 0x%x)",
137 nio.nc_status);
138
139 printf("network: %s%d attached to %s\n", nif->nif_driver->netif_bname,
140 nif->nif_unit, ether_sprintf(desc->myea));
141
142 nif->nif_devdata = &bug_softc;
143 }
144
145 int
146 bug_get(desc, pkt, len, timeout)
147 struct iodesc *desc;
148 void *pkt;
149 size_t len;
150 saseconds_t timeout;
151 {
152 struct netif *nif = desc->io_netif;
153 struct bug_softc *sc = nif->nif_devdata;
154 struct bug_netio nio;
155
156 nio.nc_clun = 0;
157 nio.nc_dlun = 0;
158 nio.nc_status = 0;
159 nio.nc_command = BUG_NETIO_CMD_RECEIVE;
160 nio.nc_buffer = sc->sc_rxbuf;
161 nio.nc_length = ETHER_MAX_LEN;
162 nio.nc_csr = 0;
163
164 if (bugsys_netio(&nio) != 0 || nio.nc_status != 0) {
165 printf("bug_get: Receive packet failed (code: 0x%x)\n",
166 nio.nc_status);
167 return (0);
168 }
169
170 if (nio.nc_length) {
171 memcpy(pkt, sc->sc_rxbuf, MIN(len, nio.nc_length));
172 return (MIN(len, nio.nc_length));
173 }
174
175 return (0);
176 }
177
178 int
179 bug_put(desc, pkt, len)
180 struct iodesc *desc;
181 void *pkt;
182 size_t len;
183 {
184 struct netif *nif = desc->io_netif;
185 struct bug_softc *sc = nif->nif_devdata;
186 struct bug_netio nio;
187
188 memcpy(&sc->sc_txbuf, pkt, len);
189
190 nio.nc_clun = 0;
191 nio.nc_dlun = 0;
192 nio.nc_status = 0;
193 nio.nc_command = BUG_NETIO_CMD_TRANSMIT;
194 nio.nc_buffer = sc->sc_txbuf;
195 nio.nc_length = MAX(len, ETHER_MIN_LEN);
196 nio.nc_csr = 0;
197
198 if (bugsys_netio(&nio) != 0 || nio.nc_status != 0) {
199 printf("bug_put: Send packet failed (code: 0x%x)\n",
200 nio.nc_status);
201 return (0);
202 }
203
204 return (len);
205 }
206
207 void
208 bug_end(nif)
209 struct netif *nif;
210 {
211 struct bug_netio nio;
212
213 nio.nc_clun = 0;
214 nio.nc_dlun = 0;
215 nio.nc_status = 0;
216 nio.nc_command = BUG_NETIO_CMD_FLUSH;
217 nio.nc_buffer = NULL;
218 nio.nc_length = 0;
219 nio.nc_csr = 0;
220
221 if (bugsys_netio(&nio) != 0 || nio.nc_status != 0)
222 printf("bug_end: netio failed (code: 0x%x)\n", nio.nc_status);
223 }
224