aboutsummaryrefslogtreecommitdiff
path: root/hw/net
diff options
context:
space:
mode:
authorChristina Wang <christina.wang@windriver.com>2021-07-23 15:55:10 +0800
committerJason Wang <jasowang@redhat.com>2021-08-02 12:19:18 +0800
commita1d7e475beb5c9e7a8e1213f29b0d20a208a9ade (patch)
tree18d51c5f2b49729fab94421fdd206343196b8c00 /hw/net
parent11744862f27b9ba6488a247d2fd6bb83d9bc3c8d (diff)
downloadqemu-a1d7e475beb5c9e7a8e1213f29b0d20a208a9ade.zip
qemu-a1d7e475beb5c9e7a8e1213f29b0d20a208a9ade.tar.gz
qemu-a1d7e475beb5c9e7a8e1213f29b0d20a208a9ade.tar.bz2
hw/net: e1000: Correct the initial value of VET register
The initial value of VLAN Ether Type (VET) register is 0x8100, as per the manual and real hardware. While Linux e1000 driver always writes VET register to 0x8100, it is not always the case for everyone. Drivers relying on the reset value of VET won't be able to transmit and receive VLAN frames in QEMU. Reported-by: Markus Carlstedt <markus.carlstedt@windriver.com> Signed-off-by: Christina Wang <christina.wang@windriver.com> Signed-off-by: Bin Meng <bin.meng@windriver.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'hw/net')
-rw-r--r--hw/net/e1000.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 4f75b44..a30546c 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -29,6 +29,7 @@
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
+#include "net/eth.h"
#include "net/net.h"
#include "net/checksum.h"
#include "sysemu/sysemu.h"
@@ -130,10 +131,13 @@ struct E1000State_st {
#define E1000_FLAG_MIT_BIT 1
#define E1000_FLAG_MAC_BIT 2
#define E1000_FLAG_TSO_BIT 3
+#define E1000_FLAG_VET_BIT 4
#define E1000_FLAG_AUTONEG (1 << E1000_FLAG_AUTONEG_BIT)
#define E1000_FLAG_MIT (1 << E1000_FLAG_MIT_BIT)
#define E1000_FLAG_MAC (1 << E1000_FLAG_MAC_BIT)
#define E1000_FLAG_TSO (1 << E1000_FLAG_TSO_BIT)
+#define E1000_FLAG_VET (1 << E1000_FLAG_VET_BIT)
+
uint32_t compat_flags;
bool received_tx_tso;
bool use_tso_for_migration;
@@ -361,6 +365,13 @@ e1000_autoneg_timer(void *opaque)
}
}
+static bool e1000_vet_init_need(void *opaque)
+{
+ E1000State *s = opaque;
+
+ return chkflag(VET);
+}
+
static void e1000_reset(void *opaque)
{
E1000State *d = opaque;
@@ -386,6 +397,10 @@ static void e1000_reset(void *opaque)
}
e1000x_reset_mac_addr(d->nic, d->mac_reg, macaddr);
+
+ if (e1000_vet_init_need(d)) {
+ d->mac_reg[VET] = ETH_P_VLAN;
+ }
}
static void
@@ -1737,6 +1752,8 @@ static Property e1000_properties[] = {
compat_flags, E1000_FLAG_MAC_BIT, true),
DEFINE_PROP_BIT("migrate_tso_props", E1000State,
compat_flags, E1000_FLAG_TSO_BIT, true),
+ DEFINE_PROP_BIT("init-vet", E1000State,
+ compat_flags, E1000_FLAG_VET_BIT, true),
DEFINE_PROP_END_OF_LIST(),
};