diff options
Diffstat (limited to 'hw/net')
-rw-r--r-- | hw/net/cadence_gem.c | 29 | ||||
-rw-r--r-- | hw/net/dp8393x.c | 2 | ||||
-rw-r--r-- | hw/net/e1000.c | 78 | ||||
-rw-r--r-- | hw/net/eepro100.c | 15 | ||||
-rw-r--r-- | hw/net/etraxfs_eth.c | 55 | ||||
-rw-r--r-- | hw/net/lan9118.c | 29 | ||||
-rw-r--r-- | hw/net/lance.c | 28 | ||||
-rw-r--r-- | hw/net/mcf_fec.c | 2 | ||||
-rw-r--r-- | hw/net/milkymist-minimac2.c | 33 | ||||
-rw-r--r-- | hw/net/mipsnet.c | 24 | ||||
-rw-r--r-- | hw/net/ne2000-isa.c | 18 | ||||
-rw-r--r-- | hw/net/ne2000.c | 7 | ||||
-rw-r--r-- | hw/net/ne2000.h | 2 | ||||
-rw-r--r-- | hw/net/opencores_eth.c | 29 | ||||
-rw-r--r-- | hw/net/pcnet-pci.c | 28 | ||||
-rw-r--r-- | hw/net/pcnet.c | 4 | ||||
-rw-r--r-- | hw/net/rtl8139.c | 121 | ||||
-rw-r--r-- | hw/net/smc91c111.c | 32 | ||||
-rw-r--r-- | hw/net/spapr_llan.c | 50 | ||||
-rw-r--r-- | hw/net/stellaris_enet.c | 42 | ||||
-rw-r--r-- | hw/net/virtio-net.c | 233 | ||||
-rw-r--r-- | hw/net/vmxnet3.c | 23 | ||||
-rw-r--r-- | hw/net/vmxnet_tx_pkt.c | 2 | ||||
-rw-r--r-- | hw/net/xgmac.c | 49 | ||||
-rw-r--r-- | hw/net/xilinx_axienet.c | 4 | ||||
-rw-r--r-- | hw/net/xilinx_ethlite.c | 24 |
26 files changed, 654 insertions, 309 deletions
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index e177057e49..4a355bbbef 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -315,8 +315,12 @@ static inline void rx_desc_set_length(unsigned *desc, unsigned len) desc[1] |= len; } -typedef struct { - SysBusDevice busdev; +#define TYPE_CADENCE_GEM "cadence_gem" +#define GEM(obj) OBJECT_CHECK(GemState, (obj), TYPE_CADENCE_GEM) + +typedef struct GemState { + SysBusDevice parent_obj; + MemoryRegion iomem; NICState *nic; NICConf conf; @@ -945,7 +949,7 @@ static void gem_phy_reset(GemState *s) static void gem_reset(DeviceState *d) { - GemState *s = FROM_SYSBUS(GemState, SYS_BUS_DEVICE(d)); + GemState *s = GEM(d); DB_PRINT("\n"); @@ -1155,21 +1159,22 @@ static NetClientInfo net_gem_info = { .link_status_changed = gem_set_link, }; -static int gem_init(SysBusDevice *dev) +static int gem_init(SysBusDevice *sbd) { - GemState *s; + DeviceState *dev = DEVICE(sbd); + GemState *s = GEM(dev); DB_PRINT("\n"); - s = FROM_SYSBUS(GemState, dev); gem_init_register_masks(s); - memory_region_init_io(&s->iomem, &gem_ops, s, "enet", sizeof(s->regs)); - sysbus_init_mmio(dev, &s->iomem); - sysbus_init_irq(dev, &s->irq); + memory_region_init_io(&s->iomem, OBJECT(s), &gem_ops, s, + "enet", sizeof(s->regs)); + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->irq); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_gem_info, &s->conf, - object_get_typename(OBJECT(dev)), dev->qdev.id, s); + object_get_typename(OBJECT(dev)), dev->id, s); return 0; } @@ -1205,10 +1210,10 @@ static void gem_class_init(ObjectClass *klass, void *data) } static const TypeInfo gem_info = { - .class_init = gem_class_init, - .name = "cadence_gem", + .name = TYPE_CADENCE_GEM, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(GemState), + .class_init = gem_class_init, }; static void gem_register_types(void) diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index 2289f089ad..049aa704c1 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -908,7 +908,7 @@ void dp83932_init(NICInfo *nd, hwaddr base, int it_shift, qemu_register_reset(nic_reset, s); nic_reset(s); - memory_region_init_io(&s->mmio, &dp8393x_ops, s, + memory_region_init_io(&s->mmio, NULL, &dp8393x_ops, s, "dp8393x", 0x40 << it_shift); memory_region_add_subregion(address_space, base, &s->mmio); } diff --git a/hw/net/e1000.c b/hw/net/e1000.c index e6f46f0c51..fdb1f890b4 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -85,7 +85,10 @@ enum { }; typedef struct E1000State_st { - PCIDevice dev; + /*< private >*/ + PCIDevice parent_obj; + /*< public >*/ + NICState *nic; NICConf conf; MemoryRegion mmio; @@ -138,6 +141,11 @@ typedef struct E1000State_st { uint32_t compat_flags; } E1000State; +#define TYPE_E1000 "e1000" + +#define E1000(obj) \ + OBJECT_CHECK(E1000State, (obj), TYPE_E1000) + #define defreg(x) x = (E1000_##x>>2) enum { defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC), @@ -240,6 +248,8 @@ static const uint32_t mac_reg_init[] = { static void set_interrupt_cause(E1000State *s, int index, uint32_t val) { + PCIDevice *d = PCI_DEVICE(s); + if (val && (E1000_DEVID >= E1000_DEV_ID_82547EI_MOBILE)) { /* Only for 8257x */ val |= E1000_ICR_INT_ASSERTED; @@ -256,7 +266,7 @@ set_interrupt_cause(E1000State *s, int index, uint32_t val) */ s->mac_reg[ICS] = val; - qemu_set_irq(s->dev.irq[0], (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0); + qemu_set_irq(d->irq[0], (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0); } static void @@ -553,10 +563,11 @@ xmit_seg(E1000State *s) static void process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) { + PCIDevice *d = PCI_DEVICE(s); uint32_t txd_lower = le32_to_cpu(dp->lower.data); uint32_t dtype = txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D); unsigned int split_size = txd_lower & 0xffff, bytes, sz, op; - unsigned int msh = 0xfffff, hdr = 0; + unsigned int msh = 0xfffff; uint64_t addr; struct e1000_context_desc *xp = (struct e1000_context_desc *)dp; struct e1000_tx *tp = &s->tx; @@ -603,23 +614,24 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) addr = le64_to_cpu(dp->buffer_addr); if (tp->tse && tp->cptse) { - hdr = tp->hdr_len; - msh = hdr + tp->mss; + msh = tp->hdr_len + tp->mss; do { bytes = split_size; if (tp->size + bytes > msh) bytes = msh - tp->size; bytes = MIN(sizeof(tp->data) - tp->size, bytes); - pci_dma_read(&s->dev, addr, tp->data + tp->size, bytes); - if ((sz = tp->size + bytes) >= hdr && tp->size < hdr) - memmove(tp->header, tp->data, hdr); + pci_dma_read(d, addr, tp->data + tp->size, bytes); + sz = tp->size + bytes; + if (sz >= tp->hdr_len && tp->size < tp->hdr_len) { + memmove(tp->header, tp->data, tp->hdr_len); + } tp->size = sz; addr += bytes; if (sz == msh) { xmit_seg(s); - memmove(tp->data, tp->header, hdr); - tp->size = hdr; + memmove(tp->data, tp->header, tp->hdr_len); + tp->size = tp->hdr_len; } } while (split_size -= bytes); } else if (!tp->tse && tp->cptse) { @@ -627,14 +639,15 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) DBGOUT(TXERR, "TCP segmentation error\n"); } else { split_size = MIN(sizeof(tp->data) - tp->size, split_size); - pci_dma_read(&s->dev, addr, tp->data + tp->size, split_size); + pci_dma_read(d, addr, tp->data + tp->size, split_size); tp->size += split_size; } if (!(txd_lower & E1000_TXD_CMD_EOP)) return; - if (!(tp->tse && tp->cptse && tp->size < hdr)) + if (!(tp->tse && tp->cptse && tp->size < tp->hdr_len)) { xmit_seg(s); + } tp->tso_frames = 0; tp->sum_needed = 0; tp->vlan_needed = 0; @@ -645,6 +658,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) static uint32_t txdesc_writeback(E1000State *s, dma_addr_t base, struct e1000_tx_desc *dp) { + PCIDevice *d = PCI_DEVICE(s); uint32_t txd_upper, txd_lower = le32_to_cpu(dp->lower.data); if (!(txd_lower & (E1000_TXD_CMD_RS|E1000_TXD_CMD_RPS))) @@ -652,7 +666,7 @@ txdesc_writeback(E1000State *s, dma_addr_t base, struct e1000_tx_desc *dp) txd_upper = (le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD) & ~(E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | E1000_TXD_STAT_TU); dp->upper.data = cpu_to_le32(txd_upper); - pci_dma_write(&s->dev, base + ((char *)&dp->upper - (char *)dp), + pci_dma_write(d, base + ((char *)&dp->upper - (char *)dp), &dp->upper, sizeof(dp->upper)); return E1000_ICR_TXDW; } @@ -668,6 +682,7 @@ static uint64_t tx_desc_base(E1000State *s) static void start_xmit(E1000State *s) { + PCIDevice *d = PCI_DEVICE(s); dma_addr_t base; struct e1000_tx_desc desc; uint32_t tdh_start = s->mac_reg[TDH], cause = E1000_ICS_TXQE; @@ -680,7 +695,7 @@ start_xmit(E1000State *s) while (s->mac_reg[TDH] != s->mac_reg[TDT]) { base = tx_desc_base(s) + sizeof(struct e1000_tx_desc) * s->mac_reg[TDH]; - pci_dma_read(&s->dev, base, &desc, sizeof(desc)); + pci_dma_read(d, base, &desc, sizeof(desc)); DBGOUT(TX, "index %d: %p : %x %x\n", s->mac_reg[TDH], (void *)(intptr_t)desc.buffer_addr, desc.lower.data, @@ -813,6 +828,7 @@ static ssize_t e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size) { E1000State *s = qemu_get_nic_opaque(nc); + PCIDevice *d = PCI_DEVICE(s); struct e1000_rx_desc desc; dma_addr_t base; unsigned int n, rdt; @@ -872,7 +888,7 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size) desc_size = s->rxbuf_size; } base = rx_desc_base(s) + sizeof(desc) * s->mac_reg[RDH]; - pci_dma_read(&s->dev, base, &desc, sizeof(desc)); + pci_dma_read(d, base, &desc, sizeof(desc)); desc.special = vlan_special; desc.status |= (vlan_status | E1000_RXD_STAT_DD); if (desc.buffer_addr) { @@ -881,7 +897,7 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size) if (copy_size > s->rxbuf_size) { copy_size = s->rxbuf_size; } - pci_dma_write(&s->dev, le64_to_cpu(desc.buffer_addr), + pci_dma_write(d, le64_to_cpu(desc.buffer_addr), buf + desc_offset + vlan_offset, copy_size); } desc_offset += desc_size; @@ -896,7 +912,7 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size) } else { // as per intel docs; skip descriptors with null buf addr DBGOUT(RX, "Null RX descriptor!!\n"); } - pci_dma_write(&s->dev, base, &desc, sizeof(desc)); + pci_dma_write(d, base, &desc, sizeof(desc)); if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN]) s->mac_reg[RDH] = 0; @@ -1182,7 +1198,7 @@ static const VMStateDescription vmstate_e1000 = { .pre_save = e1000_pre_save, .post_load = e1000_post_load, .fields = (VMStateField []) { - VMSTATE_PCI_DEVICE(dev, E1000State), + VMSTATE_PCI_DEVICE(parent_obj, E1000State), VMSTATE_UNUSED_TEST(is_version_1, 4), /* was instance id */ VMSTATE_UNUSED(4), /* Was mmio_base. */ VMSTATE_UINT32(rxbuf_size, E1000State), @@ -1276,13 +1292,13 @@ e1000_mmio_setup(E1000State *d) E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE }; - memory_region_init_io(&d->mmio, &e1000_mmio_ops, d, "e1000-mmio", - PNPMMIO_SIZE); + memory_region_init_io(&d->mmio, OBJECT(d), &e1000_mmio_ops, d, + "e1000-mmio", PNPMMIO_SIZE); memory_region_add_coalescing(&d->mmio, 0, excluded_regs[0]); for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++) memory_region_add_coalescing(&d->mmio, excluded_regs[i] + 4, excluded_regs[i+1] - excluded_regs[i] - 4); - memory_region_init_io(&d->io, &e1000_io_ops, d, "e1000-io", IOPORT_SIZE); + memory_region_init_io(&d->io, OBJECT(d), &e1000_io_ops, d, "e1000-io", IOPORT_SIZE); } static void @@ -1296,7 +1312,7 @@ e1000_cleanup(NetClientState *nc) static void pci_e1000_uninit(PCIDevice *dev) { - E1000State *d = DO_UPCAST(E1000State, dev, dev); + E1000State *d = E1000(dev); qemu_del_timer(d->autoneg_timer); qemu_free_timer(d->autoneg_timer); @@ -1316,13 +1332,14 @@ static NetClientInfo net_e1000_info = { static int pci_e1000_init(PCIDevice *pci_dev) { - E1000State *d = DO_UPCAST(E1000State, dev, pci_dev); + DeviceState *dev = DEVICE(pci_dev); + E1000State *d = E1000(pci_dev); uint8_t *pci_conf; uint16_t checksum = 0; int i; uint8_t *macaddr; - pci_conf = d->dev.config; + pci_conf = pci_dev->config; /* TODO: RST# value should be 0, PCI spec 6.2.4 */ pci_conf[PCI_CACHE_LINE_SIZE] = 0x10; @@ -1331,9 +1348,9 @@ static int pci_e1000_init(PCIDevice *pci_dev) e1000_mmio_setup(d); - pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); + pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); - pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io); + pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io); memmove(d->eeprom_data, e1000_eeprom_template, sizeof e1000_eeprom_template); @@ -1347,11 +1364,11 @@ static int pci_e1000_init(PCIDevice *pci_dev) d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum; d->nic = qemu_new_nic(&net_e1000_info, &d->conf, - object_get_typename(OBJECT(d)), d->dev.qdev.id, d); + object_get_typename(OBJECT(d)), dev->id, d); qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr); - add_boot_device_path(d->conf.bootindex, &pci_dev->qdev, "/ethernet-phy@0"); + add_boot_device_path(d->conf.bootindex, dev, "/ethernet-phy@0"); d->autoneg_timer = qemu_new_timer_ms(vm_clock, e1000_autoneg_timer, d); @@ -1360,7 +1377,7 @@ static int pci_e1000_init(PCIDevice *pci_dev) static void qdev_e1000_reset(DeviceState *dev) { - E1000State *d = DO_UPCAST(E1000State, dev.qdev, dev); + E1000State *d = E1000(dev); e1000_reset(d); } @@ -1383,6 +1400,7 @@ static void e1000_class_init(ObjectClass *klass, void *data) k->device_id = E1000_DEVID; k->revision = 0x03; k->class_id = PCI_CLASS_NETWORK_ETHERNET; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); dc->desc = "Intel Gigabit Ethernet"; dc->reset = qdev_e1000_reset; dc->vmsd = &vmstate_e1000; @@ -1390,7 +1408,7 @@ static void e1000_class_init(ObjectClass *klass, void *data) } static const TypeInfo e1000_info = { - .name = "e1000", + .name = TYPE_E1000, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(E1000State), .class_init = e1000_class_init, diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c index dc99ea6ea0..ffa60d5c96 100644 --- a/hw/net/eepro100.c +++ b/hw/net/eepro100.c @@ -47,6 +47,7 @@ #include "hw/nvram/eeprom93xx.h" #include "sysemu/sysemu.h" #include "sysemu/dma.h" +#include "qemu/bitops.h" /* QEMU sends frames smaller than 60 bytes to ethernet nics. * Such frames are rejected by real nics and their emulations. @@ -105,7 +106,6 @@ #define PCI_IO_SIZE 64 #define PCI_FLASH_SIZE (128 * KiB) -#define BIT(n) (1 << (n)) #define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m) /* The SCB accepts the following controls for the Tx and Rx units: */ @@ -1876,15 +1876,15 @@ static int e100_nic_init(PCIDevice *pci_dev) s->eeprom = eeprom93xx_new(&pci_dev->qdev, EEPROM_SIZE); /* Handler for memory-mapped I/O */ - memory_region_init_io(&s->mmio_bar, &eepro100_ops, s, "eepro100-mmio", - PCI_MEM_SIZE); + memory_region_init_io(&s->mmio_bar, OBJECT(s), &eepro100_ops, s, + "eepro100-mmio", PCI_MEM_SIZE); pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->mmio_bar); - memory_region_init_io(&s->io_bar, &eepro100_ops, s, "eepro100-io", - PCI_IO_SIZE); + memory_region_init_io(&s->io_bar, OBJECT(s), &eepro100_ops, s, + "eepro100-io", PCI_IO_SIZE); pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); /* FIXME: flash aliases to mmio?! */ - memory_region_init_io(&s->flash_bar, &eepro100_ops, s, "eepro100-flash", - PCI_FLASH_SIZE); + memory_region_init_io(&s->flash_bar, OBJECT(s), &eepro100_ops, s, + "eepro100-flash", PCI_FLASH_SIZE); pci_register_bar(&s->dev, 2, 0, &s->flash_bar); qemu_macaddr_default_if_unset(&s->conf.macaddr); @@ -2083,6 +2083,7 @@ static void eepro100_class_init(ObjectClass *klass, void *data) info = eepro100_get_class_by_name(object_class_get_name(klass)); + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); dc->props = e100_properties; dc->desc = info->desc; k->vendor_id = PCI_VENDOR_ID_INTEL; diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c index 1039913e0f..78ebbbca72 100644 --- a/hw/net/etraxfs_eth.c +++ b/hw/net/etraxfs_eth.c @@ -322,9 +322,14 @@ static void mdio_cycle(struct qemu_mdio *bus) #define R_STAT 0x0b #define FS_ETH_MAX_REGS 0x17 -struct fs_eth +#define TYPE_ETRAX_FS_ETH "etraxfs-eth" +#define ETRAX_FS_ETH(obj) \ + OBJECT_CHECK(ETRAXFSEthState, (obj), TYPE_ETRAX_FS_ETH) + +typedef struct ETRAXFSEthState { - SysBusDevice busdev; + SysBusDevice parent_obj; + MemoryRegion mmio; NICState *nic; NICConf conf; @@ -349,9 +354,9 @@ struct fs_eth /* PHY. */ struct qemu_phy phy; -}; +} ETRAXFSEthState; -static void eth_validate_duplex(struct fs_eth *eth) +static void eth_validate_duplex(ETRAXFSEthState *eth) { struct qemu_phy *phy; unsigned int phy_duplex; @@ -382,7 +387,7 @@ static void eth_validate_duplex(struct fs_eth *eth) static uint64_t eth_read(void *opaque, hwaddr addr, unsigned int size) { - struct fs_eth *eth = opaque; + ETRAXFSEthState *eth = opaque; uint32_t r = 0; addr >>= 2; @@ -399,7 +404,7 @@ eth_read(void *opaque, hwaddr addr, unsigned int size) return r; } -static void eth_update_ma(struct fs_eth *eth, int ma) +static void eth_update_ma(ETRAXFSEthState *eth, int ma) { int reg; int i = 0; @@ -428,7 +433,7 @@ static void eth_write(void *opaque, hwaddr addr, uint64_t val64, unsigned int size) { - struct fs_eth *eth = opaque; + ETRAXFSEthState *eth = opaque; uint32_t value = val64; addr >>= 2; @@ -472,7 +477,7 @@ eth_write(void *opaque, hwaddr addr, /* The ETRAX FS has a groupt address table (GAT) which works like a k=1 bloom filter dropping group addresses we have not joined. The filter has 64 bits (m). The has function is a simple nible xor of the group addr. */ -static int eth_match_groupaddr(struct fs_eth *eth, const unsigned char *sa) +static int eth_match_groupaddr(ETRAXFSEthState *eth, const unsigned char *sa) { unsigned int hsh; int m_individual = eth->regs[RW_REC_CTRL] & 4; @@ -523,7 +528,7 @@ static int eth_can_receive(NetClientState *nc) static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size) { unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - struct fs_eth *eth = qemu_get_nic_opaque(nc); + ETRAXFSEthState *eth = qemu_get_nic_opaque(nc); int use_ma0 = eth->regs[RW_REC_CTRL] & 1; int use_ma1 = eth->regs[RW_REC_CTRL] & 2; int r_bcast = eth->regs[RW_REC_CTRL] & 8; @@ -547,12 +552,12 @@ static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size) /* FIXME: Find another way to pass on the fake csum. */ etraxfs_dmac_input(eth->dma_in, (void *)buf, size + 4, 1); - return size; + return size; } static int eth_tx_push(void *opaque, unsigned char *buf, int len, bool eop) { - struct fs_eth *eth = opaque; + ETRAXFSEthState *eth = opaque; D(printf("%s buf=%p len=%d\n", __func__, buf, len)); qemu_send_packet(qemu_get_queue(eth->nic), buf, len); @@ -561,7 +566,7 @@ static int eth_tx_push(void *opaque, unsigned char *buf, int len, bool eop) static void eth_set_link(NetClientState *nc) { - struct fs_eth *eth = qemu_get_nic_opaque(nc); + ETRAXFSEthState *eth = qemu_get_nic_opaque(nc); D(printf("%s %d\n", __func__, nc->link_down)); eth->phy.link = !nc->link_down; } @@ -578,7 +583,7 @@ static const MemoryRegionOps eth_ops = { static void eth_cleanup(NetClientState *nc) { - struct fs_eth *eth = qemu_get_nic_opaque(nc); + ETRAXFSEthState *eth = qemu_get_nic_opaque(nc); /* Disconnect the client. */ eth->dma_out->client.push = NULL; @@ -597,9 +602,10 @@ static NetClientInfo net_etraxfs_info = { .link_status_changed = eth_set_link, }; -static int fs_eth_init(SysBusDevice *dev) +static int fs_eth_init(SysBusDevice *sbd) { - struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev); + DeviceState *dev = DEVICE(sbd); + ETRAXFSEthState *s = ETRAX_FS_ETH(dev); if (!s->dma_out || !s->dma_in) { hw_error("Unconnected ETRAX-FS Ethernet MAC.\n"); @@ -610,12 +616,13 @@ static int fs_eth_init(SysBusDevice *dev) s->dma_in->client.opaque = s; s->dma_in->client.pull = NULL; - memory_region_init_io(&s->mmio, ð_ops, s, "etraxfs-eth", 0x5c); - sysbus_init_mmio(dev, &s->mmio); + memory_region_init_io(&s->mmio, OBJECT(dev), ð_ops, s, + "etraxfs-eth", 0x5c); + sysbus_init_mmio(sbd, &s->mmio); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf, - object_get_typename(OBJECT(s)), dev->qdev.id, s); + object_get_typename(OBJECT(s)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); @@ -625,10 +632,10 @@ static int fs_eth_init(SysBusDevice *dev) } static Property etraxfs_eth_properties[] = { - DEFINE_PROP_UINT32("phyaddr", struct fs_eth, phyaddr, 1), - DEFINE_PROP_PTR("dma_out", struct fs_eth, vdma_out), - DEFINE_PROP_PTR("dma_in", struct fs_eth, vdma_in), - DEFINE_NIC_PROPERTIES(struct fs_eth, conf), + DEFINE_PROP_UINT32("phyaddr", ETRAXFSEthState, phyaddr, 1), + DEFINE_PROP_PTR("dma_out", ETRAXFSEthState, vdma_out), + DEFINE_PROP_PTR("dma_in", ETRAXFSEthState, vdma_in), + DEFINE_NIC_PROPERTIES(ETRAXFSEthState, conf), DEFINE_PROP_END_OF_LIST(), }; @@ -642,9 +649,9 @@ static void etraxfs_eth_class_init(ObjectClass *klass, void *data) } static const TypeInfo etraxfs_eth_info = { - .name = "etraxfs-eth", + .name = TYPE_ETRAX_FS_ETH, .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(struct fs_eth), + .instance_size = sizeof(ETRAXFSEthState), .class_init = etraxfs_eth_class_init, }; diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c index 403fb868ae..2c838f67dc 100644 --- a/hw/net/lan9118.c +++ b/hw/net/lan9118.c @@ -170,8 +170,12 @@ static const VMStateDescription vmstate_lan9118_packet = { } }; +#define TYPE_LAN9118 "lan9118" +#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118) + typedef struct { - SysBusDevice busdev; + SysBusDevice parent_obj; + NICState *nic; NICConf conf; qemu_irq irq; @@ -401,7 +405,8 @@ static void phy_reset(lan9118_state *s) static void lan9118_reset(DeviceState *d) { - lan9118_state *s = FROM_SYSBUS(lan9118_state, SYS_BUS_DEVICE(d)); + lan9118_state *s = LAN9118(d); + s->irq_cfg &= (IRQ_TYPE | IRQ_POL); s->int_sts = 0; s->int_en = 0; @@ -1053,7 +1058,7 @@ static void lan9118_writel(void *opaque, hwaddr offset, case CSR_HW_CFG: if (val & 1) { /* SRST */ - lan9118_reset(&s->busdev.qdev); + lan9118_reset(DEVICE(s)); } else { s->hw_cfg = (val & 0x003f300) | (s->hw_cfg & 0x4); } @@ -1320,21 +1325,23 @@ static NetClientInfo net_lan9118_info = { .link_status_changed = lan9118_set_link, }; -static int lan9118_init1(SysBusDevice *dev) +static int lan9118_init1(SysBusDevice *sbd) { - lan9118_state *s = FROM_SYSBUS(lan9118_state, dev); + DeviceState *dev = DEVICE(sbd); + lan9118_state *s = LAN9118(dev); QEMUBH *bh; int i; const MemoryRegionOps *mem_ops = s->mode_16bit ? &lan9118_16bit_mem_ops : &lan9118_mem_ops; - memory_region_init_io(&s->mmio, mem_ops, s, "lan9118-mmio", 0x100); - sysbus_init_mmio(dev, &s->mmio); - sysbus_init_irq(dev, &s->irq); + memory_region_init_io(&s->mmio, OBJECT(dev), mem_ops, s, + "lan9118-mmio", 0x100); + sysbus_init_mmio(sbd, &s->mmio); + sysbus_init_irq(sbd, &s->irq); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_lan9118_info, &s->conf, - object_get_typename(OBJECT(dev)), dev->qdev.id, s); + object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); s->eeprom[0] = 0xa5; for (i = 0; i < 6; i++) { @@ -1369,7 +1376,7 @@ static void lan9118_class_init(ObjectClass *klass, void *data) } static const TypeInfo lan9118_info = { - .name = "lan9118", + .name = TYPE_LAN9118, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(lan9118_state), .class_init = lan9118_class_init, @@ -1388,7 +1395,7 @@ void lan9118_init(NICInfo *nd, uint32_t base, qemu_irq irq) SysBusDevice *s; qemu_check_nic_model(nd, "lan9118"); - dev = qdev_create(NULL, "lan9118"); + dev = qdev_create(NULL, TYPE_LAN9118); qdev_set_nic_properties(dev, nd); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); diff --git a/hw/net/lance.c b/hw/net/lance.c index 187497c0ce..e339f029b7 100644 --- a/hw/net/lance.c +++ b/hw/net/lance.c @@ -43,8 +43,13 @@ #include "pcnet.h" #include "trace.h" +#define TYPE_LANCE "lance" +#define SYSBUS_PCNET(obj) \ + OBJECT_CHECK(SysBusPCNetState, (obj), TYPE_LANCE) + typedef struct { - SysBusDevice busdev; + SysBusDevice parent_obj; + PCNetState state; } SysBusPCNetState; @@ -112,27 +117,29 @@ static const VMStateDescription vmstate_lance = { } }; -static int lance_init(SysBusDevice *dev) +static int lance_init(SysBusDevice *sbd) { - SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev); + DeviceState *dev = DEVICE(sbd); + SysBusPCNetState *d = SYSBUS_PCNET(dev); PCNetState *s = &d->state; - memory_region_init_io(&s->mmio, &lance_mem_ops, d, "lance-mmio", 4); + memory_region_init_io(&s->mmio, OBJECT(d), &lance_mem_ops, d, + "lance-mmio", 4); - qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1); + qdev_init_gpio_in(dev, parent_lance_reset, 1); - sysbus_init_mmio(dev, &s->mmio); + sysbus_init_mmio(sbd, &s->mmio); - sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(sbd, &s->irq); s->phys_mem_read = ledma_memory_read; s->phys_mem_write = ledma_memory_write; - return pcnet_common_init(&dev->qdev, s, &net_lance_info); + return pcnet_common_init(dev, s, &net_lance_info); } static void lance_reset(DeviceState *dev) { - SysBusPCNetState *d = DO_UPCAST(SysBusPCNetState, busdev.qdev, dev); + SysBusPCNetState *d = SYSBUS_PCNET(dev); pcnet_h_reset(&d->state); } @@ -149,6 +156,7 @@ static void lance_class_init(ObjectClass *klass, void *data) SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = lance_init; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); dc->fw_name = "ethernet"; dc->reset = lance_reset; dc->vmsd = &vmstate_lance; @@ -156,7 +164,7 @@ static void lance_class_init(ObjectClass *klass, void *data) } static const TypeInfo lance_info = { - .name = "lance", + .name = TYPE_LANCE, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(SysBusPCNetState), .class_init = lance_class_init, diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c index 2ef5a0d73d..4bff3de34f 100644 --- a/hw/net/mcf_fec.c +++ b/hw/net/mcf_fec.c @@ -468,7 +468,7 @@ void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd, s->sysmem = sysmem; s->irq = irq; - memory_region_init_io(&s->iomem, &mcf_fec_ops, s, "fec", 0x400); + memory_region_init_io(&s->iomem, NULL, &mcf_fec_ops, s, "fec", 0x400); memory_region_add_subregion(sysmem, base, &s->iomem); s->conf.macaddr = nd->macaddr; diff --git a/hw/net/milkymist-minimac2.c b/hw/net/milkymist-minimac2.c index 4ef6318418..1e9237984d 100644 --- a/hw/net/milkymist-minimac2.c +++ b/hw/net/milkymist-minimac2.c @@ -90,8 +90,13 @@ struct MilkymistMinimac2MdioState { }; typedef struct MilkymistMinimac2MdioState MilkymistMinimac2MdioState; +#define TYPE_MILKYMIST_MINIMAC2 "milkymist-minimac2" +#define MILKYMIST_MINIMAC2(obj) \ + OBJECT_CHECK(MilkymistMinimac2State, (obj), TYPE_MILKYMIST_MINIMAC2) + struct MilkymistMinimac2State { - SysBusDevice busdev; + SysBusDevice parent_obj; + NICState *nic; NICConf conf; char *phy_model; @@ -355,7 +360,7 @@ minimac2_write(void *opaque, hwaddr addr, uint64_t value, { MilkymistMinimac2State *s = opaque; - trace_milkymist_minimac2_memory_read(addr, value); + trace_milkymist_minimac2_memory_write(addr, value); addr >>= 2; switch (addr) { @@ -429,8 +434,7 @@ static void minimac2_cleanup(NetClientState *nc) static void milkymist_minimac2_reset(DeviceState *d) { - MilkymistMinimac2State *s = - container_of(d, MilkymistMinimac2State, busdev.qdev); + MilkymistMinimac2State *s = MILKYMIST_MINIMAC2(d); int i; for (i = 0; i < R_MAX; i++) { @@ -453,31 +457,32 @@ static NetClientInfo net_milkymist_minimac2_info = { .cleanup = minimac2_cleanup, }; -static int milkymist_minimac2_init(SysBusDevice *dev) +static int milkymist_minimac2_init(SysBusDevice *sbd) { - MilkymistMinimac2State *s = FROM_SYSBUS(typeof(*s), dev); + DeviceState *dev = DEVICE(sbd); + MilkymistMinimac2State *s = MILKYMIST_MINIMAC2(dev); size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE); - sysbus_init_irq(dev, &s->rx_irq); - sysbus_init_irq(dev, &s->tx_irq); + sysbus_init_irq(sbd, &s->rx_irq); + sysbus_init_irq(sbd, &s->tx_irq); - memory_region_init_io(&s->regs_region, &minimac2_ops, s, + memory_region_init_io(&s->regs_region, OBJECT(dev), &minimac2_ops, s, "milkymist-minimac2", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); + sysbus_init_mmio(sbd, &s->regs_region); /* register buffers memory */ - memory_region_init_ram(&s->buffers, "milkymist-minimac2.buffers", + memory_region_init_ram(&s->buffers, OBJECT(dev), "milkymist-minimac2.buffers", buffers_size); vmstate_register_ram_global(&s->buffers); s->rx0_buf = memory_region_get_ram_ptr(&s->buffers); s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE; s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE; - sysbus_init_mmio(dev, &s->buffers); + sysbus_init_mmio(sbd, &s->buffers); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf, - object_get_typename(OBJECT(dev)), dev->qdev.id, s); + object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); return 0; @@ -532,7 +537,7 @@ static void milkymist_minimac2_class_init(ObjectClass *klass, void *data) } static const TypeInfo milkymist_minimac2_info = { - .name = "milkymist-minimac2", + .name = TYPE_MILKYMIST_MINIMAC2, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(MilkymistMinimac2State), .class_init = milkymist_minimac2_class_init, diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c index ac6193a89e..e421b867e7 100644 --- a/hw/net/mipsnet.c +++ b/hw/net/mipsnet.c @@ -19,8 +19,11 @@ #define MAX_ETH_FRAME_SIZE 1514 +#define TYPE_MIPS_NET "mipsnet" +#define MIPS_NET(obj) OBJECT_CHECK(MIPSnetState, (obj), TYPE_MIPS_NET) + typedef struct MIPSnetState { - SysBusDevice busdev; + SysBusDevice parent_obj; uint32_t busy; uint32_t rx_count; @@ -231,16 +234,18 @@ static const MemoryRegionOps mipsnet_ioport_ops = { .impl.max_access_size = 4, }; -static int mipsnet_sysbus_init(SysBusDevice *dev) +static int mipsnet_sysbus_init(SysBusDevice *sbd) { - MIPSnetState *s = DO_UPCAST(MIPSnetState, busdev, dev); + DeviceState *dev = DEVICE(sbd); + MIPSnetState *s = MIPS_NET(dev); - memory_region_init_io(&s->io, &mipsnet_ioport_ops, s, "mipsnet-io", 36); - sysbus_init_mmio(dev, &s->io); - sysbus_init_irq(dev, &s->irq); + memory_region_init_io(&s->io, OBJECT(dev), &mipsnet_ioport_ops, s, + "mipsnet-io", 36); + sysbus_init_mmio(sbd, &s->io); + sysbus_init_irq(sbd, &s->irq); s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf, - object_get_typename(OBJECT(dev)), dev->qdev.id, s); + object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); return 0; @@ -248,7 +253,7 @@ static int mipsnet_sysbus_init(SysBusDevice *dev) static void mipsnet_sysbus_reset(DeviceState *dev) { - MIPSnetState *s = DO_UPCAST(MIPSnetState, busdev.qdev, dev); + MIPSnetState *s = MIPS_NET(dev); mipsnet_reset(s); } @@ -263,6 +268,7 @@ static void mipsnet_class_init(ObjectClass *klass, void *data) SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = mipsnet_sysbus_init; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); dc->desc = "MIPS Simulator network device"; dc->reset = mipsnet_sysbus_reset; dc->vmsd = &vmstate_mipsnet; @@ -270,7 +276,7 @@ static void mipsnet_class_init(ObjectClass *klass, void *data) } static const TypeInfo mipsnet_info = { - .name = "mipsnet", + .name = TYPE_MIPS_NET, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(MIPSnetState), .class_init = mipsnet_class_init, diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c index f8e610cfa2..26b83cef0d 100644 --- a/hw/net/ne2000-isa.c +++ b/hw/net/ne2000-isa.c @@ -66,24 +66,23 @@ static const VMStateDescription vmstate_isa_ne2000 = { } }; -static int isa_ne2000_initfn(ISADevice *dev) +static void isa_ne2000_realizefn(DeviceState *dev, Error **errp) { + ISADevice *isadev = ISA_DEVICE(dev); ISANE2000State *isa = ISA_NE2000(dev); NE2000State *s = &isa->ne2000; - ne2000_setup_io(s, 0x20); - isa_register_ioport(dev, &s->io, isa->iobase); + ne2000_setup_io(s, DEVICE(isadev), 0x20); + isa_register_ioport(isadev, &s->io, isa->iobase); - isa_init_irq(dev, &s->irq, isa->isairq); + isa_init_irq(isadev, &s->irq, isa->isairq); qemu_macaddr_default_if_unset(&s->c.macaddr); ne2000_reset(s); s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c, - object_get_typename(OBJECT(dev)), dev->qdev.id, s); + object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a); - - return 0; } static Property ne2000_isa_properties[] = { @@ -96,9 +95,10 @@ static Property ne2000_isa_properties[] = { static void isa_ne2000_class_initfn(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - ISADeviceClass *ic = ISA_DEVICE_CLASS(klass); - ic->init = isa_ne2000_initfn; + + dc->realize = isa_ne2000_realizefn; dc->props = ne2000_isa_properties; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); } static const TypeInfo ne2000_isa_info = { diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c index 33ee03e68e..31afd28c7c 100644 --- a/hw/net/ne2000.c +++ b/hw/net/ne2000.c @@ -699,9 +699,9 @@ static const MemoryRegionOps ne2000_ops = { /***********************************************************/ /* PCI NE2000 definitions */ -void ne2000_setup_io(NE2000State *s, unsigned size) +void ne2000_setup_io(NE2000State *s, DeviceState *dev, unsigned size) { - memory_region_init_io(&s->io, &ne2000_ops, s, "ne2000", size); + memory_region_init_io(&s->io, OBJECT(dev), &ne2000_ops, s, "ne2000", size); } static void ne2000_cleanup(NetClientState *nc) @@ -729,7 +729,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev) pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */ s = &d->ne2000; - ne2000_setup_io(s, 0x100); + ne2000_setup_io(s, DEVICE(pci_dev), 0x100); pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io); s->irq = d->dev.irq[0]; @@ -772,6 +772,7 @@ static void ne2000_class_init(ObjectClass *klass, void *data) k->class_id = PCI_CLASS_NETWORK_ETHERNET; dc->vmsd = &vmstate_pci_ne2000; dc->props = ne2000_properties; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); } static const TypeInfo ne2000_info = { diff --git a/hw/net/ne2000.h b/hw/net/ne2000.h index b31ae030f9..e500306aac 100644 --- a/hw/net/ne2000.h +++ b/hw/net/ne2000.h @@ -31,7 +31,7 @@ typedef struct NE2000State { uint8_t mem[NE2000_MEM_SIZE]; } NE2000State; -void ne2000_setup_io(NE2000State *s, unsigned size); +void ne2000_setup_io(NE2000State *s, DeviceState *dev, unsigned size); extern const VMStateDescription vmstate_ne2000; void ne2000_reset(NE2000State *s); int ne2000_can_receive(NetClientState *nc); diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c index be64bf2a68..4118d54ac8 100644 --- a/hw/net/opencores_eth.c +++ b/hw/net/opencores_eth.c @@ -267,8 +267,12 @@ typedef struct desc { #define DEFAULT_PHY 1 +#define TYPE_OPEN_ETH "open_eth" +#define OPEN_ETH(obj) OBJECT_CHECK(OpenEthState, (obj), TYPE_OPEN_ETH) + typedef struct OpenEthState { - SysBusDevice dev; + SysBusDevice parent_obj; + NICState *nic; NICConf conf; MemoryRegion reg_io; @@ -677,28 +681,30 @@ static const MemoryRegionOps open_eth_desc_ops = { .write = open_eth_desc_write, }; -static int sysbus_open_eth_init(SysBusDevice *dev) +static int sysbus_open_eth_init(SysBusDevice *sbd) { - OpenEthState *s = DO_UPCAST(OpenEthState, dev, dev); + DeviceState *dev = DEVICE(sbd); + OpenEthState *s = OPEN_ETH(dev); - memory_region_init_io(&s->reg_io, &open_eth_reg_ops, s, + memory_region_init_io(&s->reg_io, OBJECT(dev), &open_eth_reg_ops, s, "open_eth.regs", 0x54); - sysbus_init_mmio(dev, &s->reg_io); + sysbus_init_mmio(sbd, &s->reg_io); - memory_region_init_io(&s->desc_io, &open_eth_desc_ops, s, + memory_region_init_io(&s->desc_io, OBJECT(dev), &open_eth_desc_ops, s, "open_eth.desc", 0x400); - sysbus_init_mmio(dev, &s->desc_io); + sysbus_init_mmio(sbd, &s->desc_io); - sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(sbd, &s->irq); s->nic = qemu_new_nic(&net_open_eth_info, &s->conf, - object_get_typename(OBJECT(s)), s->dev.qdev.id, s); + object_get_typename(OBJECT(s)), dev->id, s); return 0; } static void qdev_open_eth_reset(DeviceState *dev) { - OpenEthState *d = DO_UPCAST(OpenEthState, dev.qdev, dev); + OpenEthState *d = OPEN_ETH(dev); + open_eth_reset(d); } @@ -713,13 +719,14 @@ static void open_eth_class_init(ObjectClass *klass, void *data) SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = sysbus_open_eth_init; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); dc->desc = "Opencores 10/100 Mbit Ethernet"; dc->reset = qdev_open_eth_reset; dc->props = open_eth_properties; } static const TypeInfo open_eth_info = { - .name = "open_eth", + .name = TYPE_OPEN_ETH, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(OpenEthState), .class_init = open_eth_class_init, diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c index 9df2b87543..2c2301c360 100644 --- a/hw/net/pcnet-pci.c +++ b/hw/net/pcnet-pci.c @@ -43,9 +43,16 @@ //#define PCNET_DEBUG_TMD //#define PCNET_DEBUG_MATCH +#define TYPE_PCI_PCNET "pcnet" + +#define PCI_PCNET(obj) \ + OBJECT_CHECK(PCIPCNetState, (obj), TYPE_PCI_PCNET) typedef struct { - PCIDevice pci_dev; + /*< private >*/ + PCIDevice parent_obj; + /*< public >*/ + PCNetState state; MemoryRegion io_bar; } PCIPCNetState; @@ -236,7 +243,7 @@ static const VMStateDescription vmstate_pci_pcnet = { .minimum_version_id = 2, .minimum_version_id_old = 2, .fields = (VMStateField []) { - VMSTATE_PCI_DEVICE(pci_dev, PCIPCNetState), + VMSTATE_PCI_DEVICE(parent_obj, PCIPCNetState), VMSTATE_STRUCT(state, PCIPCNetState, 0, vmstate_pcnet, PCNetState), VMSTATE_END_OF_LIST() } @@ -273,7 +280,7 @@ static void pci_pcnet_cleanup(NetClientState *nc) static void pci_pcnet_uninit(PCIDevice *dev) { - PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev); + PCIPCNetState *d = PCI_PCNET(dev); memory_region_destroy(&d->state.mmio); memory_region_destroy(&d->io_bar); @@ -293,7 +300,7 @@ static NetClientInfo net_pci_pcnet_info = { static int pci_pcnet_init(PCIDevice *pci_dev) { - PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev); + PCIPCNetState *d = PCI_PCNET(pci_dev); PCNetState *s = &d->state; uint8_t *pci_conf; @@ -315,10 +322,10 @@ static int pci_pcnet_init(PCIDevice *pci_dev) pci_conf[PCI_MAX_LAT] = 0xff; /* Handler for memory-mapped I/O */ - memory_region_init_io(&d->state.mmio, &pcnet_mmio_ops, s, "pcnet-mmio", - PCNET_PNPMMIO_SIZE); + memory_region_init_io(&d->state.mmio, OBJECT(d), &pcnet_mmio_ops, s, + "pcnet-mmio", PCNET_PNPMMIO_SIZE); - memory_region_init_io(&d->io_bar, &pcnet_io_ops, s, "pcnet-io", + memory_region_init_io(&d->io_bar, OBJECT(d), &pcnet_io_ops, s, "pcnet-io", PCNET_IOPORT_SIZE); pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar); @@ -329,12 +336,12 @@ static int pci_pcnet_init(PCIDevice *pci_dev) s->phys_mem_write = pci_physical_memory_write; s->dma_opaque = pci_dev; - return pcnet_common_init(&pci_dev->qdev, s, &net_pci_pcnet_info); + return pcnet_common_init(DEVICE(pci_dev), s, &net_pci_pcnet_info); } static void pci_reset(DeviceState *dev) { - PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev.qdev, dev); + PCIPCNetState *d = PCI_PCNET(dev); pcnet_h_reset(&d->state); } @@ -359,10 +366,11 @@ static void pcnet_class_init(ObjectClass *klass, void *data) dc->reset = pci_reset; dc->vmsd = &vmstate_pci_pcnet; dc->props = pcnet_properties; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); } static const TypeInfo pcnet_info = { - .name = "pcnet", + .name = TYPE_PCI_PCNET, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIPCNetState), .class_init = pcnet_class_init, diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c index b606d2be3b..63aa73a241 100644 --- a/hw/net/pcnet.c +++ b/hw/net/pcnet.c @@ -861,6 +861,8 @@ static void pcnet_init(PCNetState *s) s->csr[0] |= 0x0101; s->csr[0] &= ~0x0004; /* clear STOP bit */ + + qemu_flush_queued_packets(qemu_get_queue(s->nic)); } static void pcnet_start(PCNetState *s) @@ -878,6 +880,8 @@ static void pcnet_start(PCNetState *s) s->csr[0] &= ~0x0004; /* clear STOP bit */ s->csr[0] |= 0x0002; pcnet_poll_timer(s); + + qemu_flush_queued_packets(qemu_get_queue(s->nic)); } static void pcnet_stop(PCNetState *s) diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c index 7993f9f5b9..ee3b6903a1 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c @@ -92,6 +92,11 @@ static inline GCC_FMT_ATTR(1, 2) int DPRINTF(const char *fmt, ...) } #endif +#define TYPE_RTL8139 "rtl8139" + +#define RTL8139(obj) \ + OBJECT_CHECK(RTL8139State, (obj), TYPE_RTL8139) + /* Symbolic offsets to registers. */ enum RTL8139_registers { MAC0 = 0, /* Ethernet hardware address. */ @@ -428,7 +433,10 @@ typedef struct RTL8139TallyCounters static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters); typedef struct RTL8139State { - PCIDevice dev; + /*< private >*/ + PCIDevice parent_obj; + /*< public >*/ + uint8_t phys[8]; /* mac address */ uint8_t mult[8]; /* multicast mask array */ @@ -701,13 +709,14 @@ static void prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi) static void rtl8139_update_irq(RTL8139State *s) { + PCIDevice *d = PCI_DEVICE(s); int isr; isr = (s->IntrStatus & s->IntrMask) & 0xffff; DPRINTF("Set IRQ to %d (%04x %04x)\n", isr ? 1 : 0, s->IntrStatus, s->IntrMask); - qemu_set_irq(s->dev.irq[0], (isr != 0)); + qemu_set_irq(d->irq[0], (isr != 0)); } static int rtl8139_RxWrap(RTL8139State *s) @@ -738,6 +747,8 @@ static int rtl8139_cp_transmitter_enabled(RTL8139State *s) static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size) { + PCIDevice *d = PCI_DEVICE(s); + if (s->RxBufAddr + size > s->RxBufferSize) { int wrapped = MOD2(s->RxBufAddr + size, s->RxBufferSize); @@ -749,14 +760,14 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size) if (size > wrapped) { - pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr, + pci_dma_write(d, s->RxBuf + s->RxBufAddr, buf, size-wrapped); } /* reset buffer pointer */ s->RxBufAddr = 0; - pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr, + pci_dma_write(d, s->RxBuf + s->RxBufAddr, buf + (size-wrapped), wrapped); s->RxBufAddr = wrapped; @@ -766,7 +777,7 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size) } /* non-wrapping path or overwrapping enabled */ - pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr, buf, size); + pci_dma_write(d, s->RxBuf + s->RxBufAddr, buf, size); s->RxBufAddr += size; } @@ -809,6 +820,7 @@ static int rtl8139_can_receive(NetClientState *nc) static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t size_, int do_interrupt) { RTL8139State *s = qemu_get_nic_opaque(nc); + PCIDevice *d = PCI_DEVICE(s); /* size is the length of the buffer passed to the driver */ int size = size_; const uint8_t *dot1q_buf = NULL; @@ -973,13 +985,13 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI; - pci_dma_read(&s->dev, cplus_rx_ring_desc, &val, 4); + pci_dma_read(d, cplus_rx_ring_desc, &val, 4); rxdw0 = le32_to_cpu(val); - pci_dma_read(&s->dev, cplus_rx_ring_desc+4, &val, 4); + pci_dma_read(d, cplus_rx_ring_desc+4, &val, 4); rxdw1 = le32_to_cpu(val); - pci_dma_read(&s->dev, cplus_rx_ring_desc+8, &val, 4); + pci_dma_read(d, cplus_rx_ring_desc+8, &val, 4); rxbufLO = le32_to_cpu(val); - pci_dma_read(&s->dev, cplus_rx_ring_desc+12, &val, 4); + pci_dma_read(d, cplus_rx_ring_desc+12, &val, 4); rxbufHI = le32_to_cpu(val); DPRINTF("+++ C+ mode RX descriptor %d %08x %08x %08x %08x\n", @@ -1047,12 +1059,12 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t /* receive/copy to target memory */ if (dot1q_buf) { - pci_dma_write(&s->dev, rx_addr, buf, 2 * ETHER_ADDR_LEN); - pci_dma_write(&s->dev, rx_addr + 2 * ETHER_ADDR_LEN, + pci_dma_write(d, rx_addr, buf, 2 * ETHER_ADDR_LEN); + pci_dma_write(d, rx_addr + 2 * ETHER_ADDR_LEN, buf + 2 * ETHER_ADDR_LEN + VLAN_HLEN, size - 2 * ETHER_ADDR_LEN); } else { - pci_dma_write(&s->dev, rx_addr, buf, size); + pci_dma_write(d, rx_addr, buf, size); } if (s->CpCmd & CPlusRxChkSum) @@ -1062,7 +1074,7 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t /* write checksum */ val = cpu_to_le32(crc32(0, buf, size_)); - pci_dma_write(&s->dev, rx_addr+size, (uint8_t *)&val, 4); + pci_dma_write(d, rx_addr+size, (uint8_t *)&val, 4); /* first segment of received packet flag */ #define CP_RX_STATUS_FS (1<<29) @@ -1108,9 +1120,9 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t /* update ring data */ val = cpu_to_le32(rxdw0); - pci_dma_write(&s->dev, cplus_rx_ring_desc, (uint8_t *)&val, 4); + pci_dma_write(d, cplus_rx_ring_desc, (uint8_t *)&val, 4); val = cpu_to_le32(rxdw1); - pci_dma_write(&s->dev, cplus_rx_ring_desc+4, (uint8_t *)&val, 4); + pci_dma_write(d, cplus_rx_ring_desc+4, (uint8_t *)&val, 4); /* update tally counter */ ++s->tally_counters.RxOk; @@ -1197,7 +1209,7 @@ static void rtl8139_reset_rxring(RTL8139State *s, uint32_t bufferSize) static void rtl8139_reset(DeviceState *d) { - RTL8139State *s = container_of(d, RTL8139State, dev.qdev); + RTL8139State *s = RTL8139(d); int i; /* restore MAC address */ @@ -1293,49 +1305,50 @@ static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters) static void RTL8139TallyCounters_dma_write(RTL8139State *s, dma_addr_t tc_addr) { + PCIDevice *d = PCI_DEVICE(s); RTL8139TallyCounters *tally_counters = &s->tally_counters; uint16_t val16; uint32_t val32; uint64_t val64; val64 = cpu_to_le64(tally_counters->TxOk); - pci_dma_write(&s->dev, tc_addr + 0, (uint8_t *)&val64, 8); + pci_dma_write(d, tc_addr + 0, (uint8_t *)&val64, 8); val64 = cpu_to_le64(tally_counters->RxOk); - pci_dma_write(&s->dev, tc_addr + 8, (uint8_t *)&val64, 8); + pci_dma_write(d, tc_addr + 8, (uint8_t *)&val64, 8); val64 = cpu_to_le64(tally_counters->TxERR); - pci_dma_write(&s->dev, tc_addr + 16, (uint8_t *)&val64, 8); + pci_dma_write(d, tc_addr + 16, (uint8_t *)&val64, 8); val32 = cpu_to_le32(tally_counters->RxERR); - pci_dma_write(&s->dev, tc_addr + 24, (uint8_t *)&val32, 4); + pci_dma_write(d, tc_addr + 24, (uint8_t *)&val32, 4); val16 = cpu_to_le16(tally_counters->MissPkt); - pci_dma_write(&s->dev, tc_addr + 28, (uint8_t *)&val16, 2); + pci_dma_write(d, tc_addr + 28, (uint8_t *)&val16, 2); val16 = cpu_to_le16(tally_counters->FAE); - pci_dma_write(&s->dev, tc_addr + 30, (uint8_t *)&val16, 2); + pci_dma_write(d, tc_addr + 30, (uint8_t *)&val16, 2); val32 = cpu_to_le32(tally_counters->Tx1Col); - pci_dma_write(&s->dev, tc_addr + 32, (uint8_t *)&val32, 4); + pci_dma_write(d, tc_addr + 32, (uint8_t *)&val32, 4); val32 = cpu_to_le32(tally_counters->TxMCol); - pci_dma_write(&s->dev, tc_addr + 36, (uint8_t *)&val32, 4); + pci_dma_write(d, tc_addr + 36, (uint8_t *)&val32, 4); val64 = cpu_to_le64(tally_counters->RxOkPhy); - pci_dma_write(&s->dev, tc_addr + 40, (uint8_t *)&val64, 8); + pci_dma_write(d, tc_addr + 40, (uint8_t *)&val64, 8); val64 = cpu_to_le64(tally_counters->RxOkBrd); - pci_dma_write(&s->dev, tc_addr + 48, (uint8_t *)&val64, 8); + pci_dma_write(d, tc_addr + 48, (uint8_t *)&val64, 8); val32 = cpu_to_le32(tally_counters->RxOkMul); - pci_dma_write(&s->dev, tc_addr + 56, (uint8_t *)&val32, 4); + pci_dma_write(d, tc_addr + 56, (uint8_t *)&val32, 4); val16 = cpu_to_le16(tally_counters->TxAbt); - pci_dma_write(&s->dev, tc_addr + 60, (uint8_t *)&val16, 2); + pci_dma_write(d, tc_addr + 60, (uint8_t *)&val16, 2); val16 = cpu_to_le16(tally_counters->TxUndrn); - pci_dma_write(&s->dev, tc_addr + 62, (uint8_t *)&val16, 2); + pci_dma_write(d, tc_addr + 62, (uint8_t *)&val16, 2); } /* Loads values of tally counters from VM state file */ @@ -1364,6 +1377,8 @@ static const VMStateDescription vmstate_tally_counters = { static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val) { + DeviceState *d = DEVICE(s); + val &= 0xff; DPRINTF("ChipCmd write val=0x%08x\n", val); @@ -1371,7 +1386,7 @@ static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val) if (val & CmdReset) { DPRINTF("ChipCmd reset\n"); - rtl8139_reset(&s->dev.qdev); + rtl8139_reset(d); } if (val & CmdRxEnb) { @@ -1525,6 +1540,8 @@ static uint32_t rtl8139_BasicModeStatus_read(RTL8139State *s) static void rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val) { + DeviceState *d = DEVICE(s); + val &= 0xff; DPRINTF("Cfg9346 write val=0x%02x\n", val); @@ -1544,7 +1561,7 @@ static void rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val) } else if (opmode == 0x40) { /* Reset. */ val = 0; - rtl8139_reset(&s->dev.qdev); + rtl8139_reset(d); } s->Cfg9346 = val; @@ -1821,13 +1838,14 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor) DPRINTF("+++ transmitting from descriptor %d\n", descriptor); + PCIDevice *d = PCI_DEVICE(s); int txsize = s->TxStatus[descriptor] & 0x1fff; uint8_t txbuffer[0x2000]; DPRINTF("+++ transmit reading %d bytes from host memory at 0x%08x\n", txsize, s->TxAddr[descriptor]); - pci_dma_read(&s->dev, s->TxAddr[descriptor], txbuffer, txsize); + pci_dma_read(d, s->TxAddr[descriptor], txbuffer, txsize); /* Mark descriptor as transferred */ s->TxStatus[descriptor] |= TxHostOwns; @@ -1946,6 +1964,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) return 0 ; } + PCIDevice *d = PCI_DEVICE(s); int descriptor = s->currCPlusTxDesc; dma_addr_t cplus_tx_ring_desc = rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]); @@ -1959,13 +1978,13 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) uint32_t val, txdw0,txdw1,txbufLO,txbufHI; - pci_dma_read(&s->dev, cplus_tx_ring_desc, (uint8_t *)&val, 4); + pci_dma_read(d, cplus_tx_ring_desc, (uint8_t *)&val, 4); txdw0 = le32_to_cpu(val); - pci_dma_read(&s->dev, cplus_tx_ring_desc+4, (uint8_t *)&val, 4); + pci_dma_read(d, cplus_tx_ring_desc+4, (uint8_t *)&val, 4); txdw1 = le32_to_cpu(val); - pci_dma_read(&s->dev, cplus_tx_ring_desc+8, (uint8_t *)&val, 4); + pci_dma_read(d, cplus_tx_ring_desc+8, (uint8_t *)&val, 4); txbufLO = le32_to_cpu(val); - pci_dma_read(&s->dev, cplus_tx_ring_desc+12, (uint8_t *)&val, 4); + pci_dma_read(d, cplus_tx_ring_desc+12, (uint8_t *)&val, 4); txbufHI = le32_to_cpu(val); DPRINTF("+++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", descriptor, @@ -2072,7 +2091,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) DMA_ADDR_FMT" to offset %d\n", txsize, tx_addr, s->cplus_txbuffer_offset); - pci_dma_read(&s->dev, tx_addr, + pci_dma_read(d, tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize); s->cplus_txbuffer_offset += txsize; @@ -2100,7 +2119,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) /* update ring data */ val = cpu_to_le32(txdw0); - pci_dma_write(&s->dev, cplus_tx_ring_desc, (uint8_t *)&val, 4); + pci_dma_write(d, cplus_tx_ring_desc, (uint8_t *)&val, 4); /* Now decide if descriptor being processed is holding the last segment of packet */ if (txdw0 & CP_TX_LS) @@ -3273,7 +3292,7 @@ static const VMStateDescription vmstate_rtl8139 = { .post_load = rtl8139_post_load, .pre_save = rtl8139_pre_save, .fields = (VMStateField []) { - VMSTATE_PCI_DEVICE(dev, RTL8139State), + VMSTATE_PCI_DEVICE(parent_obj, RTL8139State), VMSTATE_PARTIAL_BUFFER(phys, RTL8139State, 6), VMSTATE_BUFFER(mult, RTL8139State), VMSTATE_UINT32_ARRAY(TxStatus, RTL8139State, 4), @@ -3439,7 +3458,7 @@ static void rtl8139_cleanup(NetClientState *nc) static void pci_rtl8139_uninit(PCIDevice *dev) { - RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev); + RTL8139State *s = RTL8139(dev); memory_region_destroy(&s->bar_io); memory_region_destroy(&s->bar_mem); @@ -3477,19 +3496,22 @@ static NetClientInfo net_rtl8139_info = { static int pci_rtl8139_init(PCIDevice *dev) { - RTL8139State * s = DO_UPCAST(RTL8139State, dev, dev); + RTL8139State *s = RTL8139(dev); + DeviceState *d = DEVICE(dev); uint8_t *pci_conf; - pci_conf = s->dev.config; + pci_conf = dev->config; pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */ /* TODO: start of capability list, but no capability * list bit in status register, and offset 0xdc seems unused. */ pci_conf[PCI_CAPABILITY_LIST] = 0xdc; - memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100); - memory_region_init_io(&s->bar_mem, &rtl8139_mmio_ops, s, "rtl8139", 0x100); - pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io); - pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem); + memory_region_init_io(&s->bar_io, OBJECT(s), &rtl8139_io_ops, s, + "rtl8139", 0x100); + memory_region_init_io(&s->bar_mem, OBJECT(s), &rtl8139_mmio_ops, s, + "rtl8139", 0x100); + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io); + pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem); qemu_macaddr_default_if_unset(&s->conf.macaddr); @@ -3505,7 +3527,7 @@ static int pci_rtl8139_init(PCIDevice *dev) s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8; s->nic = qemu_new_nic(&net_rtl8139_info, &s->conf, - object_get_typename(OBJECT(dev)), dev->qdev.id, s); + object_get_typename(OBJECT(dev)), d->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); s->cplus_txbuffer = NULL; @@ -3516,7 +3538,7 @@ static int pci_rtl8139_init(PCIDevice *dev) s->timer = qemu_new_timer_ns(vm_clock, rtl8139_timer, s); rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock)); - add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet-phy@0"); + add_boot_device_path(s->conf.bootindex, d, "/ethernet-phy@0"); return 0; } @@ -3541,10 +3563,11 @@ static void rtl8139_class_init(ObjectClass *klass, void *data) dc->reset = rtl8139_reset; dc->vmsd = &vmstate_rtl8139; dc->props = rtl8139_properties; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); } static const TypeInfo rtl8139_info = { - .name = "rtl8139", + .name = TYPE_RTL8139, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(RTL8139State), .class_init = rtl8139_class_init, diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c index c2feae6eb8..f5963e2cbe 100644 --- a/hw/net/smc91c111.c +++ b/hw/net/smc91c111.c @@ -16,8 +16,12 @@ /* Number of 2k memory pages available. */ #define NUM_PACKETS 4 +#define TYPE_SMC91C111 "smc91c111" +#define SMC91C111(obj) OBJECT_CHECK(smc91c111_state, (obj), TYPE_SMC91C111) + typedef struct { - SysBusDevice busdev; + SysBusDevice parent_obj; + NICState *nic; NICConf conf; uint16_t tcr; @@ -254,7 +258,8 @@ static void smc91c111_queue_tx(smc91c111_state *s, int packet) static void smc91c111_reset(DeviceState *dev) { - smc91c111_state *s = FROM_SYSBUS(smc91c111_state, SYS_BUS_DEVICE(dev)); + smc91c111_state *s = SMC91C111(dev); + s->bank = 0; s->tx_fifo_len = 0; s->tx_fifo_done_len = 0; @@ -302,8 +307,9 @@ static void smc91c111_writeb(void *opaque, hwaddr offset, return; case 5: SET_HIGH(rcr, value); - if (s->rcr & RCR_SOFT_RST) - smc91c111_reset(&s->busdev.qdev); + if (s->rcr & RCR_SOFT_RST) { + smc91c111_reset(DEVICE(s)); + } return; case 10: case 11: /* RPCR */ /* Ignored */ @@ -744,16 +750,18 @@ static NetClientInfo net_smc91c111_info = { .cleanup = smc91c111_cleanup, }; -static int smc91c111_init1(SysBusDevice *dev) +static int smc91c111_init1(SysBusDevice *sbd) { - smc91c111_state *s = FROM_SYSBUS(smc91c111_state, dev); - memory_region_init_io(&s->mmio, &smc91c111_mem_ops, s, + DeviceState *dev = DEVICE(sbd); + smc91c111_state *s = SMC91C111(dev); + + memory_region_init_io(&s->mmio, OBJECT(s), &smc91c111_mem_ops, s, "smc91c111-mmio", 16); - sysbus_init_mmio(dev, &s->mmio); - sysbus_init_irq(dev, &s->irq); + sysbus_init_mmio(sbd, &s->mmio); + sysbus_init_irq(sbd, &s->irq); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf, - object_get_typename(OBJECT(dev)), dev->qdev.id, s); + object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); /* ??? Save/restore. */ return 0; @@ -776,7 +784,7 @@ static void smc91c111_class_init(ObjectClass *klass, void *data) } static const TypeInfo smc91c111_info = { - .name = "smc91c111", + .name = TYPE_SMC91C111, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(smc91c111_state), .class_init = smc91c111_class_init, @@ -795,7 +803,7 @@ void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq) SysBusDevice *s; qemu_check_nic_model(nd, "smc91c111"); - dev = qdev_create(NULL, "smc91c111"); + dev = qdev_create(NULL, TYPE_SMC91C111); qdev_set_nic_properties(dev, nd); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c index 03a09f2047..4ff04113db 100644 --- a/hw/net/spapr_llan.c +++ b/hw/net/spapr_llan.c @@ -38,9 +38,9 @@ /*#define DEBUG*/ #ifdef DEBUG -#define dprintf(fmt...) do { fprintf(stderr, fmt); } while (0) +#define DPRINTF(fmt...) do { fprintf(stderr, fmt); } while (0) #else -#define dprintf(fmt...) +#define DPRINTF(fmt...) #endif /* @@ -81,9 +81,9 @@ typedef struct VIOsPAPRVLANDevice { VIOsPAPRDevice sdev; NICConf nicconf; NICState *nic; - int isopen; + bool isopen; target_ulong buf_list; - int add_buf_ptr, use_buf_ptr, rx_bufs; + uint32_t add_buf_ptr, use_buf_ptr, rx_bufs; target_ulong rxq_ptr; } VIOsPAPRVLANDevice; @@ -105,7 +105,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, uint64_t handle; uint8_t control; - dprintf("spapr_vlan_receive() [%s] rx_bufs=%d\n", sdev->qdev.id, + DPRINTF("spapr_vlan_receive() [%s] rx_bufs=%d\n", sdev->qdev.id, dev->rx_bufs); if (!dev->isopen) { @@ -123,7 +123,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, } bd = vio_ldq(sdev, dev->buf_list + buf_ptr); - dprintf("use_buf_ptr=%d bd=0x%016llx\n", + DPRINTF("use_buf_ptr=%d bd=0x%016llx\n", buf_ptr, (unsigned long long)bd); } while ((!(bd & VLAN_BD_VALID) || (VLAN_BD_LEN(bd) < (size + 8))) && (buf_ptr != dev->use_buf_ptr)); @@ -138,14 +138,14 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, dev->use_buf_ptr = buf_ptr; vio_stq(sdev, dev->buf_list + dev->use_buf_ptr, 0); - dprintf("Found buffer: ptr=%d num=%d\n", dev->use_buf_ptr, dev->rx_bufs); + DPRINTF("Found buffer: ptr=%d num=%d\n", dev->use_buf_ptr, dev->rx_bufs); /* Transfer the packet data */ if (spapr_vio_dma_write(sdev, VLAN_BD_ADDR(bd) + 8, buf, size) < 0) { return -1; } - dprintf("spapr_vlan_receive: DMA write completed\n"); + DPRINTF("spapr_vlan_receive: DMA write completed\n"); /* Update the receive queue */ control = VLAN_RXQC_TOGGLE | VLAN_RXQC_VALID; @@ -159,7 +159,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, vio_sth(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 2, 8); vio_stb(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr, control); - dprintf("wrote rxq entry (ptr=0x%llx): 0x%016llx 0x%016llx\n", + DPRINTF("wrote rxq entry (ptr=0x%llx): 0x%016llx 0x%016llx\n", (unsigned long long)dev->rxq_ptr, (unsigned long long)vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr), @@ -374,7 +374,7 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu, VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev); vlan_bd_t bd; - dprintf("H_ADD_LOGICAL_LAN_BUFFER(0x" TARGET_FMT_lx + DPRINTF("H_ADD_LOGICAL_LAN_BUFFER(0x" TARGET_FMT_lx ", 0x" TARGET_FMT_lx ")\n", reg, buf); if (!sdev) { @@ -405,7 +405,7 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu, dev->rx_bufs++; - dprintf("h_add_logical_lan_buffer(): Added buf ptr=%d rx_bufs=%d" + DPRINTF("h_add_logical_lan_buffer(): Added buf ptr=%d rx_bufs=%d" " bd=0x%016llx\n", dev->add_buf_ptr, dev->rx_bufs, (unsigned long long)buf); @@ -425,14 +425,14 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr, int i, nbufs; int ret; - dprintf("H_SEND_LOGICAL_LAN(0x" TARGET_FMT_lx ", <bufs>, 0x" + DPRINTF("H_SEND_LOGICAL_LAN(0x" TARGET_FMT_lx ", <bufs>, 0x" TARGET_FMT_lx ")\n", reg, continue_token); if (!sdev) { return H_PARAMETER; } - dprintf("rxbufs = %d\n", dev->rx_bufs); + DPRINTF("rxbufs = %d\n", dev->rx_bufs); if (!dev->isopen) { return H_DROPPED; @@ -444,7 +444,7 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr, total_len = 0; for (i = 0; i < 6; i++) { - dprintf(" buf desc: 0x" TARGET_FMT_lx "\n", bufs[i]); + DPRINTF(" buf desc: 0x" TARGET_FMT_lx "\n", bufs[i]); if (!(bufs[i] & VLAN_BD_VALID)) { break; } @@ -452,7 +452,7 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr, } nbufs = i; - dprintf("h_send_logical_lan() %d buffers, total length 0x%x\n", + DPRINTF("h_send_logical_lan() %d buffers, total length 0x%x\n", nbufs, total_len); if (total_len == 0) { @@ -500,6 +500,25 @@ static Property spapr_vlan_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static const VMStateDescription vmstate_spapr_llan = { + .name = "spapr_llan", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVLANDevice), + /* LLAN state */ + VMSTATE_BOOL(isopen, VIOsPAPRVLANDevice), + VMSTATE_UINTTL(buf_list, VIOsPAPRVLANDevice), + VMSTATE_UINT32(add_buf_ptr, VIOsPAPRVLANDevice), + VMSTATE_UINT32(use_buf_ptr, VIOsPAPRVLANDevice), + VMSTATE_UINT32(rx_bufs, VIOsPAPRVLANDevice), + VMSTATE_UINTTL(rxq_ptr, VIOsPAPRVLANDevice), + + VMSTATE_END_OF_LIST() + }, +}; + static void spapr_vlan_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -514,6 +533,7 @@ static void spapr_vlan_class_init(ObjectClass *klass, void *data) k->signal_mask = 0x1; dc->props = spapr_vlan_properties; k->rtce_window_size = 0x10000000; + dc->vmsd = &vmstate_spapr_llan; } static const TypeInfo spapr_vlan_info = { diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c index 59b84564a0..9dd77f7571 100644 --- a/hw/net/stellaris_enet.c +++ b/hw/net/stellaris_enet.c @@ -42,8 +42,13 @@ do { fprintf(stderr, "stellaris_enet: error: " fmt , ## __VA_ARGS__);} while (0) #define SE_TCTL_CRC 0x04 #define SE_TCTL_DUPLEX 0x08 +#define TYPE_STELLARIS_ENET "stellaris_enet" +#define STELLARIS_ENET(obj) \ + OBJECT_CHECK(stellaris_enet_state, (obj), TYPE_STELLARIS_ENET) + typedef struct { - SysBusDevice busdev; + SysBusDevice parent_obj; + uint32_t ris; uint32_t im; uint32_t rctl; @@ -386,11 +391,7 @@ static void stellaris_enet_cleanup(NetClientState *nc) { stellaris_enet_state *s = qemu_get_nic_opaque(nc); - unregister_savevm(&s->busdev.qdev, "stellaris_enet", s); - - memory_region_destroy(&s->mmio); - - g_free(s); + s->nic = NULL; } static NetClientInfo net_stellaris_enet_info = { @@ -401,26 +402,36 @@ static NetClientInfo net_stellaris_enet_info = { .cleanup = stellaris_enet_cleanup, }; -static int stellaris_enet_init(SysBusDevice *dev) +static int stellaris_enet_init(SysBusDevice *sbd) { - stellaris_enet_state *s = FROM_SYSBUS(stellaris_enet_state, dev); + DeviceState *dev = DEVICE(sbd); + stellaris_enet_state *s = STELLARIS_ENET(dev); - 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); + memory_region_init_io(&s->mmio, OBJECT(s), &stellaris_enet_ops, s, + "stellaris_enet", 0x1000); + sysbus_init_mmio(sbd, &s->mmio); + sysbus_init_irq(sbd, &s->irq); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf, - object_get_typename(OBJECT(dev)), dev->qdev.id, s); + object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); stellaris_enet_reset(s); - register_savevm(&s->busdev.qdev, "stellaris_enet", -1, 1, + register_savevm(dev, "stellaris_enet", -1, 1, stellaris_enet_save, stellaris_enet_load, s); return 0; } +static void stellaris_enet_unrealize(DeviceState *dev, Error **errp) +{ + stellaris_enet_state *s = STELLARIS_ENET(dev); + + unregister_savevm(DEVICE(s), "stellaris_enet", s); + + memory_region_destroy(&s->mmio); +} + static Property stellaris_enet_properties[] = { DEFINE_NIC_PROPERTIES(stellaris_enet_state, conf), DEFINE_PROP_END_OF_LIST(), @@ -432,11 +443,12 @@ static void stellaris_enet_class_init(ObjectClass *klass, void *data) SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = stellaris_enet_init; + dc->unrealize = stellaris_enet_unrealize; dc->props = stellaris_enet_properties; } static const TypeInfo stellaris_enet_info = { - .name = "stellaris_enet", + .name = TYPE_STELLARIS_ENET, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(stellaris_enet_state), .class_init = stellaris_enet_class_init, diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index bed0822f0a..aa1880cb87 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -21,6 +21,8 @@ #include "hw/virtio/virtio-net.h" #include "net/vhost_net.h" #include "hw/virtio/virtio-bus.h" +#include "qapi/qmp/qjson.h" +#include "monitor/monitor.h" #define VIRTIO_NET_VM_VERSION 11 @@ -192,6 +194,105 @@ static void virtio_net_set_link_status(NetClientState *nc) virtio_net_set_status(vdev, vdev->status); } +static void rxfilter_notify(NetClientState *nc) +{ + QObject *event_data; + VirtIONet *n = qemu_get_nic_opaque(nc); + + if (nc->rxfilter_notify_enabled) { + if (n->netclient_name) { + event_data = qobject_from_jsonf("{ 'name': %s, 'path': %s }", + n->netclient_name, + object_get_canonical_path(OBJECT(n->qdev))); + } else { + event_data = qobject_from_jsonf("{ 'path': %s }", + object_get_canonical_path(OBJECT(n->qdev))); + } + monitor_protocol_event(QEVENT_NIC_RX_FILTER_CHANGED, event_data); + qobject_decref(event_data); + + /* disable event notification to avoid events flooding */ + nc->rxfilter_notify_enabled = 0; + } +} + +static char *mac_strdup_printf(const uint8_t *mac) +{ + return g_strdup_printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", mac[0], + mac[1], mac[2], mac[3], mac[4], mac[5]); +} + +static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc) +{ + VirtIONet *n = qemu_get_nic_opaque(nc); + RxFilterInfo *info; + strList *str_list, *entry; + intList *int_list, *int_entry; + int i, j; + + info = g_malloc0(sizeof(*info)); + info->name = g_strdup(nc->name); + info->promiscuous = n->promisc; + + if (n->nouni) { + info->unicast = RX_STATE_NONE; + } else if (n->alluni) { + info->unicast = RX_STATE_ALL; + } else { + info->unicast = RX_STATE_NORMAL; + } + + if (n->nomulti) { + info->multicast = RX_STATE_NONE; + } else if (n->allmulti) { + info->multicast = RX_STATE_ALL; + } else { + info->multicast = RX_STATE_NORMAL; + } + + info->broadcast_allowed = n->nobcast; + info->multicast_overflow = n->mac_table.multi_overflow; + info->unicast_overflow = n->mac_table.uni_overflow; + + info->main_mac = mac_strdup_printf(n->mac); + + str_list = NULL; + for (i = 0; i < n->mac_table.first_multi; i++) { + entry = g_malloc0(sizeof(*entry)); + entry->value = mac_strdup_printf(n->mac_table.macs + i * ETH_ALEN); + entry->next = str_list; + str_list = entry; + } + info->unicast_table = str_list; + + str_list = NULL; + for (i = n->mac_table.first_multi; i < n->mac_table.in_use; i++) { + entry = g_malloc0(sizeof(*entry)); + entry->value = mac_strdup_printf(n->mac_table.macs + i * ETH_ALEN); + entry->next = str_list; + str_list = entry; + } + info->multicast_table = str_list; + + int_list = NULL; + for (i = 0; i < MAX_VLAN >> 5; i++) { + for (j = 0; n->vlans[i] && j < 0x1f; j++) { + if (n->vlans[i] & (1U << j)) { + int_entry = g_malloc0(sizeof(*int_entry)); + int_entry->value = (i << 5) + j; + int_entry->next = int_list; + int_list = int_entry; + } + } + } + info->vlan_table = int_list; + + /* enable event notification after query */ + nc->rxfilter_notify_enabled = 1; + + return info; +} + static void virtio_net_reset(VirtIODevice *vdev) { VirtIONet *n = VIRTIO_NET(vdev); @@ -359,6 +460,34 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev) return features; } +static void virtio_net_apply_guest_offloads(VirtIONet *n) +{ + tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer, + !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)), + !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)), + !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)), + !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)), + !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO))); +} + +static uint64_t virtio_net_guest_offloads_by_features(uint32_t features) +{ + static const uint64_t guest_offloads_mask = + (1ULL << VIRTIO_NET_F_GUEST_CSUM) | + (1ULL << VIRTIO_NET_F_GUEST_TSO4) | + (1ULL << VIRTIO_NET_F_GUEST_TSO6) | + (1ULL << VIRTIO_NET_F_GUEST_ECN) | + (1ULL << VIRTIO_NET_F_GUEST_UFO); + + return guest_offloads_mask & features; +} + +static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n) +{ + VirtIODevice *vdev = VIRTIO_DEVICE(n); + return virtio_net_guest_offloads_by_features(vdev->guest_features); +} + static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features) { VirtIONet *n = VIRTIO_NET(vdev); @@ -369,12 +498,9 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features) virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF))); if (n->has_vnet_hdr) { - tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer, - (features >> VIRTIO_NET_F_GUEST_CSUM) & 1, - (features >> VIRTIO_NET_F_GUEST_TSO4) & 1, - (features >> VIRTIO_NET_F_GUEST_TSO6) & 1, - (features >> VIRTIO_NET_F_GUEST_ECN) & 1, - (features >> VIRTIO_NET_F_GUEST_UFO) & 1); + n->curr_guest_offloads = + virtio_net_guest_offloads_by_features(features); + virtio_net_apply_guest_offloads(n); } for (i = 0; i < n->max_queues; i++) { @@ -395,6 +521,7 @@ static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd, { uint8_t on; size_t s; + NetClientState *nc = qemu_get_queue(n->nic); s = iov_to_buf(iov, iov_cnt, 0, &on, sizeof(on)); if (s != sizeof(on)) { @@ -417,14 +544,54 @@ static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd, return VIRTIO_NET_ERR; } + rxfilter_notify(nc); + return VIRTIO_NET_OK; } +static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd, + struct iovec *iov, unsigned int iov_cnt) +{ + VirtIODevice *vdev = VIRTIO_DEVICE(n); + uint64_t offloads; + size_t s; + + if (!((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features)) { + return VIRTIO_NET_ERR; + } + + s = iov_to_buf(iov, iov_cnt, 0, &offloads, sizeof(offloads)); + if (s != sizeof(offloads)) { + return VIRTIO_NET_ERR; + } + + if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) { + uint64_t supported_offloads; + + if (!n->has_vnet_hdr) { + return VIRTIO_NET_ERR; + } + + supported_offloads = virtio_net_supported_guest_offloads(n); + if (offloads & ~supported_offloads) { + return VIRTIO_NET_ERR; + } + + n->curr_guest_offloads = offloads; + virtio_net_apply_guest_offloads(n); + + return VIRTIO_NET_OK; + } else { + return VIRTIO_NET_ERR; + } +} + static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, struct iovec *iov, unsigned int iov_cnt) { struct virtio_net_ctrl_mac mac_data; size_t s; + NetClientState *nc = qemu_get_queue(n->nic); if (cmd == VIRTIO_NET_CTRL_MAC_ADDR_SET) { if (iov_size(iov, iov_cnt) != sizeof(n->mac)) { @@ -433,6 +600,8 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, s = iov_to_buf(iov, iov_cnt, 0, &n->mac, sizeof(n->mac)); assert(s == sizeof(n->mac)); qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac); + rxfilter_notify(nc); + return VIRTIO_NET_OK; } @@ -450,19 +619,19 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, sizeof(mac_data.entries)); mac_data.entries = ldl_p(&mac_data.entries); if (s != sizeof(mac_data.entries)) { - return VIRTIO_NET_ERR; + goto error; } iov_discard_front(&iov, &iov_cnt, s); if (mac_data.entries * ETH_ALEN > iov_size(iov, iov_cnt)) { - return VIRTIO_NET_ERR; + goto error; } if (mac_data.entries <= MAC_TABLE_ENTRIES) { s = iov_to_buf(iov, iov_cnt, 0, n->mac_table.macs, mac_data.entries * ETH_ALEN); if (s != mac_data.entries * ETH_ALEN) { - return VIRTIO_NET_ERR; + goto error; } n->mac_table.in_use += mac_data.entries; } else { @@ -477,27 +646,33 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, sizeof(mac_data.entries)); mac_data.entries = ldl_p(&mac_data.entries); if (s != sizeof(mac_data.entries)) { - return VIRTIO_NET_ERR; + goto error; } iov_discard_front(&iov, &iov_cnt, s); if (mac_data.entries * ETH_ALEN != iov_size(iov, iov_cnt)) { - return VIRTIO_NET_ERR; + goto error; } if (n->mac_table.in_use + mac_data.entries <= MAC_TABLE_ENTRIES) { s = iov_to_buf(iov, iov_cnt, 0, n->mac_table.macs, mac_data.entries * ETH_ALEN); if (s != mac_data.entries * ETH_ALEN) { - return VIRTIO_NET_ERR; + goto error; } n->mac_table.in_use += mac_data.entries; } else { n->mac_table.multi_overflow = 1; } + rxfilter_notify(nc); + return VIRTIO_NET_OK; + +error: + rxfilter_notify(nc); + return VIRTIO_NET_ERR; } static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd, @@ -505,6 +680,7 @@ static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd, { uint16_t vid; size_t s; + NetClientState *nc = qemu_get_queue(n->nic); s = iov_to_buf(iov, iov_cnt, 0, &vid, sizeof(vid)); vid = lduw_p(&vid); @@ -522,6 +698,8 @@ static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd, else return VIRTIO_NET_ERR; + rxfilter_notify(nc); + return VIRTIO_NET_OK; } @@ -590,6 +768,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) status = virtio_net_handle_vlan_table(n, ctrl.cmd, iov, iov_cnt); } else if (ctrl.class == VIRTIO_NET_CTRL_MQ) { status = virtio_net_handle_mq(n, ctrl.cmd, iov, iov_cnt); + } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) { + status = virtio_net_handle_offloads(n, ctrl.cmd, iov, iov_cnt); } s = iov_from_buf(elem.in_sg, elem.in_num, 0, &status, sizeof(status)); @@ -1110,6 +1290,10 @@ static void virtio_net_save(QEMUFile *f, void *opaque) qemu_put_be32(f, n->vqs[i].tx_waiting); } } + + if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) { + qemu_put_be64(f, n->curr_guest_offloads); + } } static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) @@ -1167,15 +1351,6 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) error_report("virtio-net: saved image requires vnet_hdr=on"); return -1; } - - if (n->has_vnet_hdr) { - tap_set_offload(qemu_get_queue(n->nic)->peer, - (vdev->guest_features >> VIRTIO_NET_F_GUEST_CSUM) & 1, - (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO4) & 1, - (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO6) & 1, - (vdev->guest_features >> VIRTIO_NET_F_GUEST_ECN) & 1, - (vdev->guest_features >> VIRTIO_NET_F_GUEST_UFO) & 1); - } } if (version_id >= 9) { @@ -1209,6 +1384,16 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) } } + if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) { + n->curr_guest_offloads = qemu_get_be64(f); + } else { + n->curr_guest_offloads = virtio_net_supported_guest_offloads(n); + } + + if (peer_has_vnet_hdr(n)) { + virtio_net_apply_guest_offloads(n); + } + virtio_net_set_queues(n); /* Find the first multicast entry in the saved MAC filter */ @@ -1243,6 +1428,7 @@ static NetClientInfo net_virtio_info = { .receive = virtio_net_receive, .cleanup = virtio_net_cleanup, .link_status_changed = virtio_net_set_link_status, + .query_rx_filter = virtio_net_query_rxfilter, }; static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx) @@ -1304,6 +1490,7 @@ static int virtio_net_device_init(VirtIODevice *vdev) DeviceState *qdev = DEVICE(vdev); VirtIONet *n = VIRTIO_NET(vdev); + NetClientState *nc; virtio_init(VIRTIO_DEVICE(n), "virtio-net", VIRTIO_ID_NET, n->config_size); @@ -1370,6 +1557,9 @@ static int virtio_net_device_init(VirtIODevice *vdev) n->vlans = g_malloc0(MAX_VLAN >> 3); + nc = qemu_get_queue(n->nic); + nc->rxfilter_notify_enabled = 1; + n->qdev = qdev; register_savevm(qdev, "virtio-net", -1, VIRTIO_NET_VM_VERSION, virtio_net_save, virtio_net_load, n); @@ -1448,6 +1638,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data) VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); dc->exit = virtio_net_device_exit; dc->props = virtio_net_properties; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); vdc->init = virtio_net_device_init; vdc->get_config = virtio_net_get_config; vdc->set_config = virtio_net_set_config; diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 4c575e55a7..49c2466434 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -528,7 +528,7 @@ vmxnet3_setup_tx_offloads(VMXNET3State *s) break; default: - assert(false); + g_assert_not_reached(); return false; } @@ -575,7 +575,7 @@ vmxnet3_on_tx_done_update_stats(VMXNET3State *s, int qidx, stats->ucastBytesTxOK += tot_len; break; default: - assert(false); + g_assert_not_reached(); } if (s->offload_mode == VMXNET3_OM_TSO) { @@ -599,7 +599,7 @@ vmxnet3_on_tx_done_update_stats(VMXNET3State *s, int qidx, break; default: - assert(false); + g_assert_not_reached(); } } @@ -634,7 +634,7 @@ vmxnet3_on_rx_done_update_stats(VMXNET3State *s, stats->ucastBytesRxOK += tot_len; break; default: - assert(false); + g_assert_not_reached(); } if (tot_len > s->mtu) { @@ -643,7 +643,7 @@ vmxnet3_on_rx_done_update_stats(VMXNET3State *s, } break; default: - assert(false); + g_assert_not_reached(); } } @@ -1106,7 +1106,7 @@ vmxnet3_io_bar0_read(void *opaque, hwaddr addr, unsigned size) { if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_IMR, VMXNET3_MAX_INTRS, VMXNET3_REG_ALIGN)) { - assert(false); + g_assert_not_reached(); } VMW_CBPRN("BAR0 unknown read [%" PRIx64 "], size %d", addr, size); @@ -1651,7 +1651,7 @@ vmxnet3_io_bar1_write(void *opaque, case VMXNET3_REG_ICR: VMW_CBPRN("Write BAR1 [VMXNET3_REG_ICR] = %" PRIx64 ", size %d", val, size); - assert(false); + g_assert_not_reached(); break; /* Event Cause Register */ @@ -1801,7 +1801,7 @@ vmxnet3_rx_filter_may_indicate(VMXNET3State *s, const void *data, break; default: - assert(false); + g_assert_not_reached(); } return true; @@ -2073,17 +2073,17 @@ static int vmxnet3_pci_init(PCIDevice *pci_dev) VMW_CBPRN("Starting init..."); - memory_region_init_io(&s->bar0, &b0_ops, s, + memory_region_init_io(&s->bar0, OBJECT(s), &b0_ops, s, "vmxnet3-b0", VMXNET3_PT_REG_SIZE); pci_register_bar(pci_dev, VMXNET3_BAR0_IDX, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0); - memory_region_init_io(&s->bar1, &b1_ops, s, + memory_region_init_io(&s->bar1, OBJECT(s), &b1_ops, s, "vmxnet3-b1", VMXNET3_VD_REG_SIZE); pci_register_bar(pci_dev, VMXNET3_BAR1_IDX, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1); - memory_region_init(&s->msix_bar, "vmxnet3-msix-bar", + memory_region_init(&s->msix_bar, OBJECT(s), "vmxnet3-msix-bar", VMXNET3_MSIX_BAR_SIZE); pci_register_bar(pci_dev, VMXNET3_MSIX_BAR_IDX, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix_bar); @@ -2453,6 +2453,7 @@ static void vmxnet3_class_init(ObjectClass *class, void *data) dc->reset = vmxnet3_qdev_reset; dc->vmsd = &vmstate_vmxnet3; dc->props = vmxnet3_properties; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); } static const TypeInfo vmxnet3_info = { diff --git a/hw/net/vmxnet_tx_pkt.c b/hw/net/vmxnet_tx_pkt.c index fc01e4da3c..f7344c4cb3 100644 --- a/hw/net/vmxnet_tx_pkt.c +++ b/hw/net/vmxnet_tx_pkt.c @@ -287,7 +287,7 @@ void vmxnet_tx_pkt_build_vheader(struct VmxnetTxPkt *pkt, bool tso_enable, break; default: - assert(false); + g_assert_not_reached(); } if (csum_enable) { diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c index 1d9074a1d0..9384fa0c5c 100644 --- a/hw/net/xgmac.c +++ b/hw/net/xgmac.c @@ -135,8 +135,12 @@ typedef struct RxTxStats { uint64_t rx_mcast; } RxTxStats; +#define TYPE_XGMAC "xgmac" +#define XGMAC(obj) OBJECT_CHECK(XgmacState, (obj), TYPE_XGMAC) + typedef struct XgmacState { - SysBusDevice busdev; + SysBusDevice parent_obj; + MemoryRegion iomem; qemu_irq sbd_irq; qemu_irq pmt_irq; @@ -173,14 +177,14 @@ static const VMStateDescription vmstate_xgmac = { } }; -static void xgmac_read_desc(struct XgmacState *s, struct desc *d, int rx) +static void xgmac_read_desc(XgmacState *s, struct desc *d, int rx) { uint32_t addr = rx ? s->regs[DMA_CUR_RX_DESC_ADDR] : s->regs[DMA_CUR_TX_DESC_ADDR]; cpu_physical_memory_read(addr, d, sizeof(*d)); } -static void xgmac_write_desc(struct XgmacState *s, struct desc *d, int rx) +static void xgmac_write_desc(XgmacState *s, struct desc *d, int rx) { int reg = rx ? DMA_CUR_RX_DESC_ADDR : DMA_CUR_TX_DESC_ADDR; uint32_t addr = s->regs[reg]; @@ -195,7 +199,7 @@ static void xgmac_write_desc(struct XgmacState *s, struct desc *d, int rx) cpu_physical_memory_write(addr, d, sizeof(*d)); } -static void xgmac_enet_send(struct XgmacState *s) +static void xgmac_enet_send(XgmacState *s) { struct desc bd; int frame_size; @@ -246,7 +250,7 @@ static void xgmac_enet_send(struct XgmacState *s) } } -static void enet_update_irq(struct XgmacState *s) +static void enet_update_irq(XgmacState *s) { int stat = s->regs[DMA_STATUS] & s->regs[DMA_INTR_ENA]; qemu_set_irq(s->sbd_irq, !!stat); @@ -254,7 +258,7 @@ static void enet_update_irq(struct XgmacState *s) static uint64_t enet_read(void *opaque, hwaddr addr, unsigned size) { - struct XgmacState *s = opaque; + XgmacState *s = opaque; uint64_t r = 0; addr >>= 2; @@ -274,7 +278,7 @@ static uint64_t enet_read(void *opaque, hwaddr addr, unsigned size) static void enet_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { - struct XgmacState *s = opaque; + XgmacState *s = opaque; addr >>= 2; switch (addr) { @@ -310,7 +314,7 @@ static const MemoryRegionOps enet_mem_ops = { static int eth_can_rx(NetClientState *nc) { - struct XgmacState *s = qemu_get_nic_opaque(nc); + XgmacState *s = qemu_get_nic_opaque(nc); /* RX enabled? */ return s->regs[DMA_CONTROL] & DMA_CONTROL_SR; @@ -318,7 +322,7 @@ static int eth_can_rx(NetClientState *nc) static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size) { - struct XgmacState *s = qemu_get_nic_opaque(nc); + XgmacState *s = qemu_get_nic_opaque(nc); static const unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; int unicast, broadcast, multicast; @@ -366,7 +370,8 @@ out: static void eth_cleanup(NetClientState *nc) { - struct XgmacState *s = qemu_get_nic_opaque(nc); + XgmacState *s = qemu_get_nic_opaque(nc); + s->nic = NULL; } @@ -378,19 +383,21 @@ static NetClientInfo net_xgmac_enet_info = { .cleanup = eth_cleanup, }; -static int xgmac_enet_init(SysBusDevice *dev) +static int xgmac_enet_init(SysBusDevice *sbd) { - struct XgmacState *s = FROM_SYSBUS(typeof(*s), dev); + DeviceState *dev = DEVICE(sbd); + XgmacState *s = XGMAC(dev); - memory_region_init_io(&s->iomem, &enet_mem_ops, s, "xgmac", 0x1000); - sysbus_init_mmio(dev, &s->iomem); - sysbus_init_irq(dev, &s->sbd_irq); - sysbus_init_irq(dev, &s->pmt_irq); - sysbus_init_irq(dev, &s->mci_irq); + memory_region_init_io(&s->iomem, OBJECT(s), &enet_mem_ops, s, + "xgmac", 0x1000); + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->sbd_irq); + sysbus_init_irq(sbd, &s->pmt_irq); + sysbus_init_irq(sbd, &s->mci_irq); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_xgmac_enet_info, &s->conf, - object_get_typename(OBJECT(dev)), dev->qdev.id, s); + object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); s->regs[XGMAC_ADDR_HIGH(0)] = (s->conf.macaddr.a[5] << 8) | @@ -404,7 +411,7 @@ static int xgmac_enet_init(SysBusDevice *dev) } static Property xgmac_properties[] = { - DEFINE_NIC_PROPERTIES(struct XgmacState, conf), + DEFINE_NIC_PROPERTIES(XgmacState, conf), DEFINE_PROP_END_OF_LIST(), }; @@ -419,9 +426,9 @@ static void xgmac_enet_class_init(ObjectClass *klass, void *data) } static const TypeInfo xgmac_enet_info = { - .name = "xgmac", + .name = TYPE_XGMAC, .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(struct XgmacState), + .instance_size = sizeof(XgmacState), .class_init = xgmac_enet_class_init, }; diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c index 8989e95297..f173429ecc 100644 --- a/hw/net/xilinx_axienet.c +++ b/hw/net/xilinx_axienet.c @@ -575,7 +575,7 @@ static void enet_write(void *opaque, hwaddr addr, break; case R_MC: - value &= ((1 < 7) - 1); + value &= ((1 << 7) - 1); /* Enable the MII. */ if (value & MC_EN) { @@ -1001,7 +1001,7 @@ static void xilinx_enet_init(Object *obj) sysbus_init_irq(sbd, &s->irq); - memory_region_init_io(&s->iomem, &enet_ops, s, "enet", 0x40000); + memory_region_init_io(&s->iomem, OBJECT(s), &enet_ops, s, "enet", 0x40000); sysbus_init_mmio(sbd, &s->iomem); } diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index b2e35237f8..3a2a6c21c9 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -47,9 +47,14 @@ #define CTRL_P 0x2 #define CTRL_S 0x1 +#define TYPE_XILINX_ETHLITE "xlnx.xps-ethernetlite" +#define XILINX_ETHLITE(obj) \ + OBJECT_CHECK(struct xlx_ethlite, (obj), TYPE_XILINX_ETHLITE) + struct xlx_ethlite { - SysBusDevice busdev; + SysBusDevice parent_obj; + MemoryRegion mmio; qemu_irq irq; NICState *nic; @@ -214,20 +219,21 @@ static NetClientInfo net_xilinx_ethlite_info = { .cleanup = eth_cleanup, }; -static int xilinx_ethlite_init(SysBusDevice *dev) +static int xilinx_ethlite_init(SysBusDevice *sbd) { - struct xlx_ethlite *s = FROM_SYSBUS(typeof (*s), dev); + DeviceState *dev = DEVICE(sbd); + struct xlx_ethlite *s = XILINX_ETHLITE(dev); - sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(sbd, &s->irq); s->rxbuf = 0; - memory_region_init_io(&s->mmio, ð_ops, s, "xlnx.xps-ethernetlite", - R_MAX * 4); - sysbus_init_mmio(dev, &s->mmio); + memory_region_init_io(&s->mmio, OBJECT(s), ð_ops, s, + "xlnx.xps-ethernetlite", R_MAX * 4); + sysbus_init_mmio(sbd, &s->mmio); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf, - object_get_typename(OBJECT(dev)), dev->qdev.id, s); + object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); return 0; } @@ -249,7 +255,7 @@ static void xilinx_ethlite_class_init(ObjectClass *klass, void *data) } static const TypeInfo xilinx_ethlite_info = { - .name = "xlnx.xps-ethernetlite", + .name = TYPE_XILINX_ETHLITE, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(struct xlx_ethlite), .class_init = xilinx_ethlite_class_init, |