We currently just update the HMP NIC info when the last bit of macaddr
is written. This assumes that guest driver will write all the macaddr
from bit 0 to bit 5 when it changes the macaddr, this is the current
behavior of linux driver (e1000/rtl8139cp), but we can't do this
assumption.
The macaddr that is used for rx-filter will be updated when every bit
is changed. This patch updates the e1000/rtl8139 nic to update HMP NIC
info when every bit has been changed. It will be same as virtio-net.
Signed-off-by: Vlad Yasevich <address@hidden>
---
hw/net/e1000.c | 17 ++++++++++++++++-
hw/net/rtl8139.c | 14 +++++++++-----
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 8387443..a5967ed 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -149,6 +149,10 @@ typedef struct E1000State_st {
#define E1000_FLAG_AUTONEG (1 << E1000_FLAG_AUTONEG_BIT)
#define E1000_FLAG_MIT (1 << E1000_FLAG_MIT_BIT)
uint32_t compat_flags;
+ uint32_t mac_changed;
+#define E1000_RA0_CHANGED 0
+#define E1000_RA1_CHANGED 1
+#define E1000_RA_ALL_CHANGED (E1000_RA0_CHANGED|E1000_RA1_CHANGED)
} E1000State;
#define TYPE_E1000 "e1000"
@@ -402,6 +406,7 @@ static void e1000_reset(void *opaque)
d->mac_reg[RA + 1] |= (i < 2) ? macaddr[i + 4] << (8 * i) : 0;
}
qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);
+ d->mac_changed = 0;
}
static void
@@ -1106,10 +1111,20 @@ mac_writereg(E1000State *s, int index, uint32_t val)
s->mac_reg[index] = val;
- if (index == RA + 1) {
+ switch (index) {
+ case RA:
+ s->mac_changed |= E1000_RA0_CHANGED;
+ break;
+ case (RA + 1):
+ s->mac_changed |= E1000_RA1_CHANGED;
+ break;
+ }
+
+ if (s->mac_changed == E1000_RA_ALL_CHANGED) {
macaddr[0] = cpu_to_le32(s->mac_reg[RA]);
macaddr[1] = cpu_to_le32(s->mac_reg[RA + 1]);
qemu_format_nic_info_str(qemu_get_queue(s->nic), (uint8_t *)macaddr);
+ s->mac_changed = 0;
}
}
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 5329f44..6dac10c 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -476,6 +476,8 @@ typedef struct RTL8139State {
uint16_t CpCmd;
uint8_t TxThresh;
+ uint8_t mac_changed;
+#define RTL8139_MAC_CHANGED_ALL 0x3F
NICState *nic;
NICConf conf;
@@ -1215,6 +1217,7 @@ static void rtl8139_reset(DeviceState *d)
/* restore MAC address */
memcpy(s->phys, s->conf.macaddr.a, 6);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->phys);
+ s->mac_changed = 0;
/* reset interrupt mask */
s->IntrStatus = 0;
@@ -2741,12 +2744,13 @@ static void rtl8139_io_writeb(void *opaque, uint8_t
addr, uint32_t val)
switch (addr)
{
- case MAC0 ... MAC0+4:
- s->phys[addr - MAC0] = val;
- break;
- case MAC0+5:
+ case MAC0 ... MAC0+5:
s->phys[addr - MAC0] = val;
- qemu_format_nic_info_str(qemu_get_queue(s->nic), s->phys);
+ s->mac_changed |= (1 << (addr - MAC0));
+ if (s->mac_changed == RTL8139_MAC_CHANGED_ALL) {
+ qemu_format_nic_info_str(qemu_get_queue(s->nic), s->phys);
+ s->mac_changed = 0;
+ }
break;
case MAC0+6 ... MAC0+7:
/* reserved */
--
1.8.4.2