X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/a5580466257337e74e48124c185e4db9d29325ec..1422e32db51ff2b1194fb24a6201c4310be5667d:/hw/stellaris_enet.c diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c index 36fabd3260..d7e1e21ff9 100644 --- a/hw/stellaris_enet.c +++ b/hw/stellaris_enet.c @@ -4,10 +4,10 @@ * Copyright (c) 2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" -#include "net.h" +#include "net/net.h" #include //#define DEBUG_STELLARIS_ENET 1 @@ -66,10 +66,10 @@ typedef struct { uint8_t *rx_fifo; int rx_fifo_len; int next_packet; - VLANClientState *vc; + NICState *nic; + NICConf conf; qemu_irq irq; - uint8_t macaddr[6]; - int mmio_index; + MemoryRegion mmio; } stellaris_enet_state; static void stellaris_enet_update(stellaris_enet_state *s) @@ -78,18 +78,18 @@ static void stellaris_enet_update(stellaris_enet_state *s) } /* TODO: Implement MAC address filtering. */ -static void stellaris_enet_receive(void *opaque, const uint8_t *buf, int size) +static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, size_t size) { - stellaris_enet_state *s = (stellaris_enet_state *)opaque; + stellaris_enet_state *s = DO_UPCAST(NICState, nc, nc)->opaque; int n; uint8_t *p; uint32_t crc; if ((s->rctl & SE_RCTL_RXEN) == 0) - return; + return -1; if (s->np >= 31) { DPRINTF("Packet dropped\n"); - return; + return -1; } DPRINTF("Received packet len=%d\n", size); @@ -116,11 +116,13 @@ static void stellaris_enet_receive(void *opaque, const uint8_t *buf, int size) s->ris |= SE_INT_RX; stellaris_enet_update(s); + + return size; } -static int stellaris_enet_can_receive(void *opaque) +static int stellaris_enet_can_receive(NetClientState *nc) { - stellaris_enet_state *s = (stellaris_enet_state *)opaque; + stellaris_enet_state *s = DO_UPCAST(NICState, nc, nc)->opaque; if ((s->rctl & SE_RCTL_RXEN) == 0) return 1; @@ -128,7 +130,8 @@ static int stellaris_enet_can_receive(void *opaque) return (s->np < 31); } -static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset) +static uint64_t stellaris_enet_read(void *opaque, hwaddr offset, + unsigned size) { stellaris_enet_state *s = (stellaris_enet_state *)opaque; uint32_t val; @@ -167,10 +170,10 @@ static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset) } return val; case 0x14: /* IA0 */ - return s->macaddr[0] | (s->macaddr[1] << 8) - | (s->macaddr[2] << 16) | (s->macaddr[3] << 24); + return s->conf.macaddr.a[0] | (s->conf.macaddr.a[1] << 8) + | (s->conf.macaddr.a[2] << 16) | (s->conf.macaddr.a[3] << 24); case 0x18: /* IA1 */ - return s->macaddr[4] | (s->macaddr[5] << 8); + return s->conf.macaddr.a[4] | (s->conf.macaddr.a[5] << 8); case 0x1c: /* THR */ return s->thr; case 0x20: /* MCTL */ @@ -195,8 +198,8 @@ static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset) } } -static void stellaris_enet_write(void *opaque, target_phys_addr_t offset, - uint32_t value) +static void stellaris_enet_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) { stellaris_enet_state *s = (stellaris_enet_state *)opaque; @@ -256,7 +259,7 @@ static void stellaris_enet_write(void *opaque, target_phys_addr_t offset, memset(&s->tx_fifo[s->tx_frame_len], 0, 60 - s->tx_frame_len); s->tx_fifo_len = 60; } - qemu_send_packet(s->vc, s->tx_fifo, s->tx_frame_len); + qemu_send_packet(&s->nic->nc, s->tx_fifo, s->tx_frame_len); s->tx_frame_len = -1; s->ris |= SE_INT_TXEMP; stellaris_enet_update(s); @@ -265,14 +268,14 @@ static void stellaris_enet_write(void *opaque, target_phys_addr_t offset, } break; case 0x14: /* IA0 */ - s->macaddr[0] = value; - s->macaddr[1] = value >> 8; - s->macaddr[2] = value >> 16; - s->macaddr[3] = value >> 24; + s->conf.macaddr.a[0] = value; + s->conf.macaddr.a[1] = value >> 8; + s->conf.macaddr.a[2] = value >> 16; + s->conf.macaddr.a[3] = value >> 24; break; case 0x18: /* IA1 */ - s->macaddr[4] = value; - s->macaddr[5] = value >> 8; + s->conf.macaddr.a[4] = value; + s->conf.macaddr.a[5] = value >> 8; break; case 0x1c: /* THR */ s->thr = value; @@ -301,17 +304,12 @@ static void stellaris_enet_write(void *opaque, target_phys_addr_t offset, } } -static CPUReadMemoryFunc *stellaris_enet_readfn[] = { - stellaris_enet_read, - stellaris_enet_read, - stellaris_enet_read +static const MemoryRegionOps stellaris_enet_ops = { + .read = stellaris_enet_read, + .write = stellaris_enet_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc *stellaris_enet_writefn[] = { - stellaris_enet_write, - stellaris_enet_write, - stellaris_enet_write -}; static void stellaris_enet_reset(stellaris_enet_state *s) { s->mdv = 0x80; @@ -383,42 +381,69 @@ static int stellaris_enet_load(QEMUFile *f, void *opaque, int version_id) return 0; } -static void stellaris_enet_cleanup(VLANClientState *vc) +static void stellaris_enet_cleanup(NetClientState *nc) { - stellaris_enet_state *s = vc->opaque; + stellaris_enet_state *s = DO_UPCAST(NICState, nc, nc)->opaque; - unregister_savevm("stellaris_enet", s); + unregister_savevm(&s->busdev.qdev, "stellaris_enet", s); - cpu_unregister_io_memory(s->mmio_index); + memory_region_destroy(&s->mmio); - qemu_free(s); + g_free(s); } -static void stellaris_enet_init(SysBusDevice *dev) +static NetClientInfo net_stellaris_enet_info = { + .type = NET_CLIENT_OPTIONS_KIND_NIC, + .size = sizeof(NICState), + .can_receive = stellaris_enet_can_receive, + .receive = stellaris_enet_receive, + .cleanup = stellaris_enet_cleanup, +}; + +static int stellaris_enet_init(SysBusDevice *dev) { stellaris_enet_state *s = FROM_SYSBUS(stellaris_enet_state, dev); - s->mmio_index = cpu_register_io_memory(0, stellaris_enet_readfn, - stellaris_enet_writefn, s); - sysbus_init_mmio(dev, 0x1000, s->mmio_index); + memory_region_init_io(&s->mmio, &stellaris_enet_ops, s, "stellaris_enet", + 0x1000); + sysbus_init_mmio(dev, &s->mmio); sysbus_init_irq(dev, &s->irq); - qdev_get_macaddr(&dev->qdev, s->macaddr); + qemu_macaddr_default_if_unset(&s->conf.macaddr); - s->vc = qdev_get_vlan_client(&dev->qdev, - stellaris_enet_receive, - stellaris_enet_can_receive, - stellaris_enet_cleanup, s); - qemu_format_nic_info_str(s->vc, s->macaddr); + s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf, + object_get_typename(OBJECT(dev)), dev->qdev.id, s); + qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); stellaris_enet_reset(s); - register_savevm("stellaris_enet", -1, 1, + register_savevm(&s->busdev.qdev, "stellaris_enet", -1, 1, stellaris_enet_save, stellaris_enet_load, s); + return 0; } -static void stellaris_enet_register_devices(void) +static Property stellaris_enet_properties[] = { + DEFINE_NIC_PROPERTIES(stellaris_enet_state, conf), + DEFINE_PROP_END_OF_LIST(), +}; + +static void stellaris_enet_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = stellaris_enet_init; + dc->props = stellaris_enet_properties; +} + +static TypeInfo stellaris_enet_info = { + .name = "stellaris_enet", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(stellaris_enet_state), + .class_init = stellaris_enet_class_init, +}; + +static void stellaris_enet_register_types(void) { - sysbus_register_dev("stellaris_enet", sizeof(stellaris_enet_state), - stellaris_enet_init); + type_register_static(&stellaris_enet_info); } -device_init(stellaris_enet_register_devices) +type_init(stellaris_enet_register_types)