From dca06c9eca4a9c9bc06349412bf60c3f3d321fff Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Amos Kong Date: Mon, 15 Oct 2012 12:05:59 +0200 Subject: [PATCH 25/27] rtl8139: implement 8139cp link status RH-Author: Amos Kong Message-id: <1350302761-15231-2-git-send-email-akong@redhat.com> Patchwork-id: 43163 O-Subject: [RHEL-6.4 qemu-kvm PATCH 1/3] rtl8139: implement 8139cp link status Bugzilla: 852965 RH-Acked-by: Xiao Wang RH-Acked-by: Michael S. Tsirkin RH-Acked-by: Stefan Hajnoczi From: Jason Wang Add a link status chang callback and change the link status bit in BMSR & MSR accordingly. Tested in Linux/Windows guests. The link status bit of MediaStatus is infered from BasicModeStatus, they are inverse. nc.link_down could not be migrated, this patch updates link_down in rtl8139_post_load() to keep it coincident with real link status. Conflicts: hw/rtl8139.c Signed-off-by: Jason Wang Signed-off-by: Amos Kong Signed-off-by: Stefan Hajnoczi (cherry picked from commit 9e12c5aff2cfdd1574bf732c4bbf579d0c2e85c1) --- hw/rtl8139.c | 24 ++++++++++++++++++++++-- 1 files changed, 22 insertions(+), 2 deletions(-) Signed-off-by: Michal Novotny --- hw/rtl8139.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/hw/rtl8139.c b/hw/rtl8139.c index c3d0552..0403686 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -162,7 +162,7 @@ enum IntrStatusBits { PCIErr = 0x8000, PCSTimeout = 0x4000, RxFIFOOver = 0x40, - RxUnderrun = 0x20, + RxUnderrun = 0x20, /* Packet Underrun / Link Change */ RxOverflow = 0x10, TxErr = 0x08, TxOK = 0x04, @@ -2914,7 +2914,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr) break; case MediaStatus: - ret = 0xd0; + /* The LinkDown bit of MediaStatus is inverse with link status */ + ret = 0xd0 | (~s->BasicModeStatus & 0x04); DEBUG_PRINT(("RTL8139: MediaStatus read 0x%x\n", ret)); break; @@ -3179,6 +3180,10 @@ static int rtl8139_post_load(void *opaque, int version_id) s->cplus_enabled = s->CpCmd != 0; } + /* nc.link_down can't be migrated, so infer link_down according + * to link status bit in BasicModeStatus */ + s->nic->nc.link_down = (s->BasicModeStatus & 0x04) == 0; + return 0; } @@ -3409,12 +3414,27 @@ static int pci_rtl8139_uninit(PCIDevice *dev) return 0; } +static void rtl8139_set_link_status(VLANClientState *nc) +{ + RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque; + + if (nc->link_down) { + s->BasicModeStatus &= ~0x04; + } else { + s->BasicModeStatus |= 0x04; + } + + s->IntrStatus |= RxUnderrun; + rtl8139_update_irq(s); +} + static NetClientInfo net_rtl8139_info = { .type = NET_CLIENT_TYPE_NIC, .size = sizeof(NICState), .can_receive = rtl8139_can_receive, .receive = rtl8139_receive, .cleanup = rtl8139_cleanup, + .link_status_changed = rtl8139_set_link_status, }; static int pci_rtl8139_init(PCIDevice *dev) -- 1.7.11.7