|
|
1.1 root 1: #include "ds_oskit.h"
2:
3: #include <device/net_io.h>
4: #include <device/if_ether.h>
5:
6: #include <stddef.h>
7: #include <string.h>
8: #include <oskit/dev/net.h>
9: #include <oskit/dev/ethernet.h>
10:
11:
12: io_return_t
13: ds_net_get_status (device_t dev, dev_flavor_t flavor, dev_status_t status,
14: mach_msg_type_number_t *status_count)
15: {
16: oskit_error_t rc;
17: oskit_etherdev_t *eth;
18:
19: rc = oskit_device_query (dev->com_device, &oskit_etherdev_iid,
20: (void **) ð);
21: if (OSKIT_FAILED (rc))
22: return D_INVALID_OPERATION; /* XXX we only support ethernet devices */
23:
24: switch (flavor)
25: {
26: case NET_ADDRESS:
27: {
28: #define WORDS ((OSKIT_ETHERDEV_ADDR_SIZE + sizeof (int) - 1) / sizeof (int))
29:
30: if (*status_count < WORDS)
31: {
32: oskit_etherdev_release (eth);
33: return D_INVALID_OPERATION;
34: }
35: *status_count = WORDS;
36:
37: bzero (status, OSKIT_ETHERDEV_ADDR_SIZE);
38: oskit_etherdev_getaddr (eth, (void *) status);
39: oskit_etherdev_release (eth);
40:
41: status[0] = ntohl (status[0]);
42: status[1] = ntohl (status[1]);
43:
44: return D_SUCCESS;
45: }
46:
47: case NET_STATUS:
48: {
49: struct net_status *ns = (void *) status;
50:
51: oskit_etherdev_release (eth);
52:
53: if (*status_count < NET_STATUS_COUNT)
54: return D_INVALID_OPERATION;
55: *status_count = NET_STATUS_COUNT;
56:
57: ns->header_format = HDR_ETHERNET;
58: ns->min_packet_size = ns->header_size = sizeof (struct ether_header);
59: ns->max_packet_size = sizeof (struct ether_header) + ETHERMTU;
60: ns->address_size = OSKIT_ETHERDEV_ADDR_SIZE;
61: ns->flags = IFF_UP|IFF_RUNNING|IFF_BROADCAST;
62: ns->mapped_size = 0;
63:
64: return D_SUCCESS;
65: }
66: }
67:
68: oskit_etherdev_release (eth);
69: return D_INVALID_OPERATION;
70: }
71:
72: io_return_t
73: ds_net_set_filter (device_t dev, ipc_port_t port, int priority,
74: filter_t *filter, unsigned filter_count)
75: {
76: return net_set_filter (&dev->com.net.ifnet,
77: port, priority, filter, filter_count);
78: }
79:
80:
81: #if 0
82: io_return_t
83: ds_net_write (device_t dev, ipc_port_t reply_port,
84: mach_msg_type_name_t reply_port_type, dev_mode_t mode,
85: recnum_t recnum, io_buf_ptr_t data, unsigned int count,
86: int *bytes_written)
87: {
88: oskit_error_t rc;
89: io_return_t err;
90: oskit_u32_t wrote;
91: vm_offset_t addr;
92: oskit_bufio_t *bio;
93:
94: if (count < sizeof (struct ether_header) ||
95: count > sizeof (struct ether_header) + ETHERMTU)
96: return D_INVALID_SIZE;
97:
98: err = vm_map_copyout (device_io_map, &addr, (vm_map_copy_t) data);
99: if (err != KERN_SUCCESS)
100: return err;
101:
102:
103: }
104: #endif
105:
106: /* XXX
107: The oskit network drivers want to call our bufio object from interrupt
108: handlers. This makes it impractical for us to do anything fancy in
109: there, like map the VM on demand--we can't do that from interrupt level!
110: So we rely on the outbound netio_push to see bufio_map fail and copy out
111: the data without attempting to save a reference to the bufio COM object. */
112:
113: struct bufio_impl
114: {
115: oskit_bufio_t ioi;
116: char *buf;
117: oskit_size_t size;
118: };
119:
120: static OSKIT_COMDECL
121: bufio_query(oskit_bufio_t *io, const oskit_iid_t *iid, void **out_ihandle)
122: { panic(__FUNCTION__); }
123:
124: static OSKIT_COMDECL_U
125: bufio_addref(oskit_bufio_t *io)
126: { panic(__FUNCTION__); }
127:
128: static OSKIT_COMDECL_U
129: bufio_release(oskit_bufio_t *io)
130: { panic(__FUNCTION__); }
131:
132: static OSKIT_COMDECL_U
133: bufio_getblocksize(oskit_bufio_t *io)
134: {
135: return 1;
136: }
137:
138: static OSKIT_COMDECL
139: bufio_read(oskit_bufio_t *io, void *dest, oskit_off_t offset,
140: oskit_size_t count, oskit_size_t *out_actual)
141: {
142: struct bufio_impl *b = (struct bufio_impl *) io;
143:
144: if (offset >= b->size)
145: return OSKIT_EINVAL;
146: if (offset + count > b->size)
147: count = b->size - offset;
148:
149: memcpy (dest, b->buf + offset, count);
150: *out_actual = count;
151: return 0;
152: }
153:
154: static OSKIT_COMDECL
155: bufio_write(oskit_bufio_t *io, const void *src, oskit_off_t offset,
156: oskit_size_t count, oskit_size_t *out_actual)
157: { panic(__FUNCTION__); }
158:
159: static OSKIT_COMDECL
160: bufio_getsize(oskit_bufio_t *io, oskit_off_t *out_size)
161: {
162: struct bufio_impl *b = (struct bufio_impl *) io;
163:
164: *out_size = b->size;
165: return 0;
166: }
167:
168: static OSKIT_COMDECL
169: bufio_setsize(oskit_bufio_t *io, oskit_off_t size)
170: { return OSKIT_E_NOTIMPL; }
171:
172:
173: static OSKIT_COMDECL
174: bufio_map(oskit_bufio_t *io, void **out_addr,
175: oskit_off_t offset, oskit_size_t count)
176: { return OSKIT_E_NOTIMPL; }
177:
178: static OSKIT_COMDECL
179: bufio_unmap(oskit_bufio_t *io, void *addr, oskit_off_t offset, oskit_size_t count)
180: { return OSKIT_E_NOTIMPL; }
181:
182: static OSKIT_COMDECL
183: bufio_wire(oskit_bufio_t *io, oskit_addr_t *out_physaddr,
184: oskit_off_t offset, oskit_size_t count)
185: {
186: return OSKIT_E_NOTIMPL;
187: }
188:
189: static OSKIT_COMDECL
190: bufio_unwire(oskit_bufio_t *io, oskit_addr_t phys_addr,
191: oskit_off_t offset, oskit_size_t count)
192: {
193: return OSKIT_E_NOTIMPL;
194: }
195:
196: static OSKIT_COMDECL
197: bufio_copy(oskit_bufio_t *io, oskit_off_t offset, oskit_size_t count,
198: oskit_bufio_t **out_io)
199: {
200: return OSKIT_E_NOTIMPL;
201: }
202:
203:
204: static struct oskit_bufio_ops bio_ops = {
205: bufio_query, bufio_addref, bufio_release,
206: bufio_getblocksize,
207: bufio_read, bufio_write,
208: bufio_getsize, bufio_setsize,
209: bufio_map, bufio_unmap,
210: bufio_wire, bufio_unwire,
211: bufio_copy
212: };
213:
214:
215: io_return_t
216: ds_net_write_inband (device_t dev, ipc_port_t reply_port,
217: mach_msg_type_name_t reply_port_type, dev_mode_t mode,
218: recnum_t recnum, io_buf_ptr_t data, unsigned int count,
219: int *bytes_written)
220: {
221: oskit_error_t rc;
222: struct bufio_impl bio = { { &bio_ops }, data, count };
223:
224: if (count < sizeof (struct ether_header) ||
225: count > sizeof (struct ether_header) + ETHERMTU)
226: return D_INVALID_SIZE;
227:
228: rc = oskit_netio_push (dev->com.net.sendi, &bio.ioi, count);
229: *bytes_written = count;
230:
231: return oskit_to_mach_error (rc);
232: }
233:
234:
235: const struct device_ops net_device_ops =
236: {
237: write_inband: ds_net_write_inband,
238: set_filter: ds_net_set_filter,
239: get_status: ds_net_get_status,
240: };
241:
242:
243: static device_t
244: recv_netio_device (oskit_netio_t *recvi)
245: {
246: return (device_t) ((char *) recvi - offsetof (struct device, com.net.recvi));
247: }
248:
249: static OSKIT_COMDECL
250: net_query(oskit_netio_t *io, const oskit_iid_t *iid, void **out_ihandle)
251: {
252: device_t dev = recv_netio_device (io);
253:
254: if (memcmp(iid, &oskit_iunknown_iid, sizeof(*iid)) == 0 ||
255: memcmp(iid, &oskit_netio_iid, sizeof(*iid)) == 0) {
256: *out_ihandle = &dev->com.net.recvi;
257: device_reference (dev);
258: return 0;
259: }
260:
261: *out_ihandle = 0;
262: return OSKIT_E_NOINTERFACE;
263: }
264:
265: static OSKIT_COMDECL_U
266: net_addref(oskit_netio_t *io)
267: {
268: device_t dev = recv_netio_device (io);
269: device_reference (dev);
270: return dev->ref_count;
271: }
272:
273: static OSKIT_COMDECL_U
274: net_release(oskit_netio_t *io)
275: {
276: device_t dev = recv_netio_device (io);
277: oskit_u32_t n = dev->ref_count - 1;
278: device_deallocate (dev);
279: return n;
280: }
281:
282: static OSKIT_COMDECL
283: net_push(oskit_netio_t *ioi, oskit_bufio_t *b, oskit_size_t pkt_size)
284: {
285: device_t dev = recv_netio_device (ioi);
286: ipc_kmsg_t kmsg;
287: struct ether_header *eh;
288: struct packet_header *ph;
289: oskit_error_t rc;
290: oskit_size_t n;
291:
292: /* Allocate a kernel message buffer. */
293: kmsg = net_kmsg_get ();
294: if (!kmsg)
295: /* No buffer, drop packet. */
296: return 0;
297:
298: /* Copy packet into message buffer. */
299: eh = (struct ether_header *) (net_kmsg (kmsg)->header);
300: ph = (struct packet_header *) (net_kmsg (kmsg)->packet);
301:
302: rc = oskit_bufio_read (b, eh, 0, sizeof (struct ether_header), &n);
303: if (rc || n != sizeof (struct ether_header))
304: panic("oskit_bufio_read: %x\n", rc);
305: rc = oskit_bufio_read (b, ph + 1, sizeof (struct ether_header),
306: pkt_size - sizeof (struct ether_header), &n);
307: if (rc || n != pkt_size - sizeof (struct ether_header))
308: panic("oskit_bufio_read: %x\n", rc);
309:
310: ph->type = eh->ether_type;
311: ph->length = (sizeof (struct packet_header)
312: + pkt_size - sizeof (struct ether_header));
313:
314: /* Pass packet up to the microkernel. */
315: net_packet (&dev->com.net.ifnet, kmsg, ph->length, ethernet_priority (kmsg));
316:
317: return 0;
318: }
319:
320: static struct oskit_netio_ops recv_netio_ops =
321: { net_query, net_addref, net_release, net_push };
322:
323:
324: oskit_error_t
325: ds_netdev_open (device_t dev, oskit_netdev_t *netdev)
326: {
327: oskit_error_t rc;
328: struct ifnet *const ifp = &dev->com.net.ifnet;
329:
330: if_init_queues (ifp);
331:
332: dev->com.net.recvi.ops = &recv_netio_ops;
333:
334: rc = oskit_netdev_open (netdev, 0, &dev->com.net.recvi, &dev->com.net.sendi);
335:
336: return rc;
337: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.