From fcd23a67875d6f7f8256b90960ec05312cab2f5b Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 12 Jun 2019 18:14:05 +0100 Subject: [PATCH 1/6] sun4m: set default display type to TCX Commit 6807874d55 "sun4m: obey -vga none" changed the sun4m machines so that they could be started without a framebuffer installed, but as no default display type was configured the machines would start in headless mode without an explict -vga option. Set the default display type for all sun4m machines to TCX so that they will start with a framebuffer if one is not specifically requested. Signed-off-by: Mark Cave-Ayland --- hw/sparc/sun4m.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 7e4f61fc3e..99f53e87f7 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -1406,6 +1406,7 @@ static void ss5_class_init(ObjectClass *oc, void *data) mc->is_default = 1; mc->default_boot_order = "c"; mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Fujitsu-MB86904"); + mc->default_display = "tcx"; } static const TypeInfo ss5_type = { @@ -1424,6 +1425,7 @@ static void ss10_class_init(ObjectClass *oc, void *data) mc->max_cpus = 4; mc->default_boot_order = "c"; mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-SuperSparc-II"); + mc->default_display = "tcx"; } static const TypeInfo ss10_type = { @@ -1442,6 +1444,7 @@ static void ss600mp_class_init(ObjectClass *oc, void *data) mc->max_cpus = 4; mc->default_boot_order = "c"; mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-SuperSparc-II"); + mc->default_display = "tcx"; } static const TypeInfo ss600mp_type = { @@ -1460,6 +1463,7 @@ static void ss20_class_init(ObjectClass *oc, void *data) mc->max_cpus = 4; mc->default_boot_order = "c"; mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-SuperSparc-II"); + mc->default_display = "tcx"; } static const TypeInfo ss20_type = { @@ -1477,6 +1481,7 @@ static void voyager_class_init(ObjectClass *oc, void *data) mc->block_default_type = IF_SCSI; mc->default_boot_order = "c"; mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Fujitsu-MB86904"); + mc->default_display = "tcx"; } static const TypeInfo voyager_type = { @@ -1494,6 +1499,7 @@ static void ss_lx_class_init(ObjectClass *oc, void *data) mc->block_default_type = IF_SCSI; mc->default_boot_order = "c"; mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-MicroSparc-I"); + mc->default_display = "tcx"; } static const TypeInfo ss_lx_type = { @@ -1511,6 +1517,7 @@ static void ss4_class_init(ObjectClass *oc, void *data) mc->block_default_type = IF_SCSI; mc->default_boot_order = "c"; mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Fujitsu-MB86904"); + mc->default_display = "tcx"; } static const TypeInfo ss4_type = { @@ -1528,6 +1535,7 @@ static void scls_class_init(ObjectClass *oc, void *data) mc->block_default_type = IF_SCSI; mc->default_boot_order = "c"; mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-MicroSparc-I"); + mc->default_display = "tcx"; } static const TypeInfo scls_type = { @@ -1545,6 +1553,7 @@ static void sbook_class_init(ObjectClass *oc, void *data) mc->block_default_type = IF_SCSI; mc->default_boot_order = "c"; mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-MicroSparc-I"); + mc->default_display = "tcx"; } static const TypeInfo sbook_type = { From 6bdc3707d993f9e90a5f592ecf261c4f647dbb46 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sun, 30 Jun 2019 18:21:50 +0100 Subject: [PATCH 2/6] sunhme: add trace event for logging PCI IRQ Signed-off-by: Mark Cave-Ayland --- hw/net/sunhme.c | 2 ++ hw/net/trace-events | 1 + 2 files changed, 3 insertions(+) diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c index 1ebaee3c82..6d660a8238 100644 --- a/hw/net/sunhme.c +++ b/hw/net/sunhme.c @@ -209,6 +209,8 @@ static void sunhme_update_irq(SunHMEState *s) } level = (seb ? 1 : 0); + trace_sunhme_update_irq(mifmask, mif, sebmask, seb, level); + pci_set_irq(d, level); } diff --git a/hw/net/trace-events b/hw/net/trace-events index 3cd9e122df..d16273c579 100644 --- a/hw/net/trace-events +++ b/hw/net/trace-events @@ -359,6 +359,7 @@ sunhme_rx_filter_reject(void) "rejecting incoming frame" sunhme_rx_filter_accept(void) "accepting incoming frame" sunhme_rx_desc(uint32_t addr, int offset, uint32_t status, int len, int cr, int nr) "addr 0x%"PRIx32"(+0x%x) status 0x%"PRIx32 " len %d (ring %d/%d)" sunhme_rx_xsum_calc(uint16_t xsum) "calculated incoming xsum as 0x%x" +sunhme_update_irq(uint32_t mifmask, uint32_t mif, uint32_t sebmask, uint32_t seb, int level) "mifmask: 0x%x mif: 0x%x sebmask: 0x%x seb: 0x%x level: %d" # virtio-net.c virtio_net_announce_notify(void) "" From 076489c043a22fe9be8f3458fbc9012b1fc0606f Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sun, 30 Jun 2019 18:21:50 +0100 Subject: [PATCH 3/6] sunhme: fix incorrect constant in sunhme_can_receive() Due to a copy/paste error the wrong register was being checked in order to determine if the NIC is able to receive data. Signed-off-by: Mark Cave-Ayland --- hw/net/sunhme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c index 6d660a8238..e3a488ee1d 100644 --- a/hw/net/sunhme.c +++ b/hw/net/sunhme.c @@ -649,7 +649,7 @@ static int sunhme_can_receive(NetClientState *nc) { SunHMEState *s = qemu_get_nic_opaque(nc); - return s->macregs[HME_MAC_RXCFG_ENABLE >> 2] & HME_MAC_RXCFG_ENABLE; + return s->macregs[HME_MACI_RXCFG >> 2] & HME_MAC_RXCFG_ENABLE; } static void sunhme_link_status_changed(NetClientState *nc) From 1058e1a377680e17bc8b56d5e9cab9559d47a3c1 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sun, 30 Jun 2019 18:21:50 +0100 Subject: [PATCH 4/6] sunhme: flush any queued packets when HME_MAC_RXCFG_ENABLE bit is raised Some client drivers use this bit to pause and resume the driver so make sure that queued packets are flushed when the MAC is disabled and then reactivated. Signed-off-by: Mark Cave-Ayland --- hw/net/sunhme.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c index e3a488ee1d..14e7effb88 100644 --- a/hw/net/sunhme.c +++ b/hw/net/sunhme.c @@ -373,10 +373,20 @@ static void sunhme_mac_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { SunHMEState *s = SUNHME(opaque); + uint64_t oldval = s->macregs[addr >> 2]; trace_sunhme_mac_write(addr, val); s->macregs[addr >> 2] = val; + + switch (addr) { + case HME_MACI_RXCFG: + if (!(oldval & HME_MAC_RXCFG_ENABLE) && + (val & HME_MAC_RXCFG_ENABLE)) { + qemu_flush_queued_packets(qemu_get_queue(s->nic)); + } + break; + } } static uint64_t sunhme_mac_read(void *opaque, hwaddr addr, From 29df47a5cc4133a31259c24ffdf26bf25080558a Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sun, 30 Jun 2019 18:21:50 +0100 Subject: [PATCH 5/6] sunhme: fix return values from sunhme_receive() during receive packet processing The current return values in sunhme_receive() when processing incoming packets are inverted from what they should be. Make sure that we return 0 to indicate the packet was discarded (and polling is to be disabled) and -1 to indicate that the packet was discarded but polling for incoming data is to be continued. Signed-off-by: Mark Cave-Ayland --- hw/net/sunhme.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c index 14e7effb88..cd076d642b 100644 --- a/hw/net/sunhme.c +++ b/hw/net/sunhme.c @@ -728,7 +728,7 @@ static ssize_t sunhme_receive(NetClientState *nc, const uint8_t *buf, /* Do nothing if MAC RX disabled */ if (!(s->macregs[HME_MACI_RXCFG >> 2] & HME_MAC_RXCFG_ENABLE)) { - return -1; + return 0; } trace_sunhme_rx_filter_destmac(buf[0], buf[1], buf[2], @@ -757,14 +757,14 @@ static ssize_t sunhme_receive(NetClientState *nc, const uint8_t *buf, /* Didn't match hash filter */ trace_sunhme_rx_filter_hash_nomatch(); trace_sunhme_rx_filter_reject(); - return 0; + return -1; } else { trace_sunhme_rx_filter_hash_match(); } } else { /* Not for us */ trace_sunhme_rx_filter_reject(); - return 0; + return -1; } } else { trace_sunhme_rx_filter_promisc_match(); From 09340f497e96a62d076b2f223e7b16a7358cfecb Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sun, 30 Jun 2019 18:21:50 +0100 Subject: [PATCH 6/6] sunhme: ensure that RX descriptor ring overflow is indicated to client driver On very busy networks connected via a tap interface, it is possible to overflow the RX descriptor ring in the time between the client driver enabling the RX MAC and finishing writing the final configuration to the NIC registers. Ensure that we detect this condition and update the status register accordingly to indicate an overflow has occurred (and the incoming packet dropped) in order to prevent the client driver becoming confused. Signed-off-by: Mark Cave-Ayland --- hw/net/sunhme.c | 9 +++++++++ hw/net/trace-events | 1 + 2 files changed, 10 insertions(+) diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c index cd076d642b..8b8603e696 100644 --- a/hw/net/sunhme.c +++ b/hw/net/sunhme.c @@ -44,6 +44,7 @@ #define HME_SEBI_STAT 0x100 #define HME_SEBI_STAT_LINUXBUG 0x108 #define HME_SEB_STAT_RXTOHOST 0x10000 +#define HME_SEB_STAT_NORXD 0x20000 #define HME_SEB_STAT_MIFIRQ 0x800000 #define HME_SEB_STAT_HOSTTOTX 0x1000000 #define HME_SEB_STAT_TXALL 0x2000000 @@ -787,6 +788,14 @@ static ssize_t sunhme_receive(NetClientState *nc, const uint8_t *buf, pci_dma_read(d, rb + cr * HME_DESC_SIZE, &status, 4); pci_dma_read(d, rb + cr * HME_DESC_SIZE + 4, &buffer, 4); + /* If we don't own the current descriptor then indicate overflow error */ + if (!(status & HME_XD_OWN)) { + s->sebregs[HME_SEBI_STAT >> 2] |= HME_SEB_STAT_NORXD; + sunhme_update_irq(s); + trace_sunhme_rx_norxd(); + return -1; + } + rxoffset = (s->erxregs[HME_ERXI_CFG >> 2] & HME_ERX_CFG_BYTEOFFSET) >> HME_ERX_CFG_BYTEOFFSET_SHIFT; diff --git a/hw/net/trace-events b/hw/net/trace-events index d16273c579..58665655cc 100644 --- a/hw/net/trace-events +++ b/hw/net/trace-events @@ -359,6 +359,7 @@ sunhme_rx_filter_reject(void) "rejecting incoming frame" sunhme_rx_filter_accept(void) "accepting incoming frame" sunhme_rx_desc(uint32_t addr, int offset, uint32_t status, int len, int cr, int nr) "addr 0x%"PRIx32"(+0x%x) status 0x%"PRIx32 " len %d (ring %d/%d)" sunhme_rx_xsum_calc(uint16_t xsum) "calculated incoming xsum as 0x%x" +sunhme_rx_norxd(void) "no free rx descriptors available" sunhme_update_irq(uint32_t mifmask, uint32_t mif, uint32_t sebmask, uint32_t seb, int level) "mifmask: 0x%x mif: 0x%x sebmask: 0x%x seb: 0x%x level: %d" # virtio-net.c