summaryrefslogtreecommitdiff
path: root/hw/net
diff options
context:
space:
mode:
Diffstat (limited to 'hw/net')
-rw-r--r--hw/net/cadence_gem.c29
-rw-r--r--hw/net/dp8393x.c2
-rw-r--r--hw/net/e1000.c78
-rw-r--r--hw/net/eepro100.c15
-rw-r--r--hw/net/etraxfs_eth.c55
-rw-r--r--hw/net/lan9118.c29
-rw-r--r--hw/net/lance.c28
-rw-r--r--hw/net/mcf_fec.c2
-rw-r--r--hw/net/milkymist-minimac2.c33
-rw-r--r--hw/net/mipsnet.c24
-rw-r--r--hw/net/ne2000-isa.c18
-rw-r--r--hw/net/ne2000.c7
-rw-r--r--hw/net/ne2000.h2
-rw-r--r--hw/net/opencores_eth.c29
-rw-r--r--hw/net/pcnet-pci.c28
-rw-r--r--hw/net/pcnet.c4
-rw-r--r--hw/net/rtl8139.c121
-rw-r--r--hw/net/smc91c111.c32
-rw-r--r--hw/net/spapr_llan.c50
-rw-r--r--hw/net/stellaris_enet.c42
-rw-r--r--hw/net/virtio-net.c233
-rw-r--r--hw/net/vmxnet3.c23
-rw-r--r--hw/net/vmxnet_tx_pkt.c2
-rw-r--r--hw/net/xgmac.c49
-rw-r--r--hw/net/xilinx_axienet.c4
-rw-r--r--hw/net/xilinx_ethlite.c24
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, &eth_ops, s, "etraxfs-eth", 0x5c);
- sysbus_init_mmio(dev, &s->mmio);
+ memory_region_init_io(&s->mmio, OBJECT(dev), &eth_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, &eth_ops, s, "xlnx.xps-ethernetlite",
- R_MAX * 4);
- sysbus_init_mmio(dev, &s->mmio);
+ memory_region_init_io(&s->mmio, OBJECT(s), &eth_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,