diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/net/e1000.c | 5 | ||||
-rw-r--r-- | hw/net/lan9118.c | 20 | ||||
-rw-r--r-- | hw/net/pcnet.c | 14 | ||||
-rw-r--r-- | hw/net/vmxnet3.c | 1 |
4 files changed, 29 insertions, 11 deletions
diff --git a/hw/net/e1000.c b/hw/net/e1000.c index c877e06c5d..bec06e90ec 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -447,6 +447,11 @@ static void e1000_reset(void *opaque) e1000_link_down(d); } + /* Throttle interrupts to prevent guest (e.g Win 2012) from + * reinjecting interrupts endlessly. TODO: fix non ITR case. + */ + d->mac_reg[ITR] = 250; + /* Some guests expect pre-initialized RAH/RAL (AddrValid flag + MACaddr) */ d->mac_reg[RA] = 0; d->mac_reg[RA + 1] = E1000_RAH_AV; diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c index 4f0e840f0e..1734b5276d 100644 --- a/hw/net/lan9118.c +++ b/hw/net/lan9118.c @@ -56,6 +56,8 @@ do { fprintf(stderr, "lan9118: error: " fmt , ## __VA_ARGS__);} while (0) #define CSR_E2P_CMD 0xb0 #define CSR_E2P_DATA 0xb4 +#define E2P_CMD_MAC_ADDR_LOADED 0x100 + /* IRQ_CFG */ #define IRQ_INT 0x00001000 #define IRQ_EN 0x00000100 @@ -352,14 +354,14 @@ static void lan9118_reload_eeprom(lan9118_state *s) { int i; if (s->eeprom[0] != 0xa5) { - s->e2p_cmd &= ~0x10; + s->e2p_cmd &= ~E2P_CMD_MAC_ADDR_LOADED; DPRINTF("MACADDR load failed\n"); return; } for (i = 0; i < 6; i++) { s->conf.macaddr.a[i] = s->eeprom[i + 1]; } - s->e2p_cmd |= 0x10; + s->e2p_cmd |= E2P_CMD_MAC_ADDR_LOADED; DPRINTF("MACADDR loaded from eeprom\n"); lan9118_mac_changed(s); } @@ -902,7 +904,8 @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val) */ break; default: - hw_error("lan9118: Unimplemented MAC register write: %d = 0x%x\n", + qemu_log_mask(LOG_GUEST_ERROR, + "lan9118: Unimplemented MAC register write: %d = 0x%x\n", s->mac_cmd & 0xf, val); } } @@ -930,14 +933,16 @@ static uint32_t do_mac_read(lan9118_state *s, int reg) case MAC_FLOW: return s->mac_flow; default: - hw_error("lan9118: Unimplemented MAC register read: %d\n", + qemu_log_mask(LOG_GUEST_ERROR, + "lan9118: Unimplemented MAC register read: %d\n", s->mac_cmd & 0xf); + return 0; } } static void lan9118_eeprom_cmd(lan9118_state *s, int cmd, int addr) { - s->e2p_cmd = (s->e2p_cmd & 0x10) | (cmd << 28) | addr; + s->e2p_cmd = (s->e2p_cmd & E2P_CMD_MAC_ADDR_LOADED) | (cmd << 28) | addr; switch (cmd) { case 0: s->e2p_data = s->eeprom[addr]; @@ -1128,7 +1133,8 @@ static void lan9118_writel(void *opaque, hwaddr offset, break; default: - hw_error("lan9118_write: Bad reg 0x%x = %x\n", (int)offset, (int)val); + qemu_log_mask(LOG_GUEST_ERROR, "lan9118_write: Bad reg 0x%x = %x\n", + (int)offset, (int)val); break; } lan9118_update(s); @@ -1246,7 +1252,7 @@ static uint64_t lan9118_readl(void *opaque, hwaddr offset, case CSR_E2P_DATA: return s->e2p_data; } - hw_error("lan9118_read: Bad reg 0x%x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, "lan9118_read: Bad reg 0x%x\n", (int)offset); return 0; } diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c index 0eb3cc4d5b..1f4a3dbe49 100644 --- a/hw/net/pcnet.c +++ b/hw/net/pcnet.c @@ -1064,6 +1064,12 @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_) int pktcount = 0; if (!s->looptest) { + if (size > 4092) { +#ifdef PCNET_DEBUG_RMD + fprintf(stderr, "pcnet: truncates rx packet.\n"); +#endif + size = 4092; + } memcpy(src, buf, size); /* no need to compute the CRC */ src[size] = 0; @@ -1084,7 +1090,7 @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_) uint32_t fcs = ~0; uint8_t *p = src; - while (p != &src[size-4]) + while (p != &src[size]) CRC(fcs, *p++); crc_err = (*(uint32_t *)p != htonl(fcs)); } @@ -1233,8 +1239,10 @@ static void pcnet_transmit(PCNetState *s) bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); /* if multi-tmd packet outsizes s->buffer then skip it silently. - Note: this is not what real hw does */ - if (s->xmit_pos + bcnt > sizeof(s->buffer)) { + * Note: this is not what real hw does. + * Last four bytes of s->buffer are used to store CRC FCS code. + */ + if (s->xmit_pos + bcnt > sizeof(s->buffer) - 4) { s->xmit_pos = -1; goto txdone; } diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 5e3a233237..37373e5d3d 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -2015,7 +2015,6 @@ static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s) return true; } - VMW_WRPRN("Peer has no virtio extension. Task offloads will be emulated."); return false; } |