Annotation of OSKit-Mach/oskit/ds_net.c, revision 1.1.1.1

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 **) &eth);
                     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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.