Blame 0202-e1000-use-MII-status-register-for-link-up-down.patch

cd9d16
From 461473595d1dd1131cb060c460c87ca7b652939e Mon Sep 17 00:00:00 2001
cd9d16
From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
cd9d16
Date: Wed, 17 Aug 2011 11:03:14 +0200
cd9d16
Subject: [PATCH] e1000: use MII status register for link up/down
cd9d16
MIME-Version: 1.0
cd9d16
Content-Type: text/plain; charset=UTF-8
cd9d16
Content-Transfer-Encoding: 8bit
cd9d16
cd9d16
Some guests will use the standard MII status register
cd9d16
to verify link state.  They will not notice link changes
cd9d16
unless this register is updated.
cd9d16
cd9d16
Verified with Linux 3.0 and Windows XP guests.
cd9d16
cd9d16
Without this patch, ethtool will report speed and duplex as
cd9d16
unknown when the link is down, but still report the link as
cd9d16
up.  This is because the Linux e1000 driver checks the
cd9d16
mac_reg[STATUS] register link state before it checks speed
cd9d16
and duplex, but uses the phy_reg[PHY_STATUS] register for
cd9d16
the actual link state check.  Fix by updating both registers
cd9d16
on link state changes.
cd9d16
cd9d16
Linux guest before:
cd9d16
cd9d16
 (qemu) set_link e1000.0 off
cd9d16
cd9d16
 kvm-sid:~# ethtool eth0
cd9d16
 Settings for eth0:
cd9d16
        Supported ports: [ TP ]
cd9d16
        Supported link modes:   10baseT/Half 10baseT/Full
cd9d16
                                100baseT/Half 100baseT/Full
cd9d16
                                1000baseT/Full
cd9d16
        Supports auto-negotiation: Yes
cd9d16
        Advertised link modes:  10baseT/Half 10baseT/Full
cd9d16
                                100baseT/Half 100baseT/Full
cd9d16
                                1000baseT/Full
cd9d16
        Advertised pause frame use: No
cd9d16
        Advertised auto-negotiation: Yes
cd9d16
        Speed: Unknown!
cd9d16
        Duplex: Unknown! (255)
cd9d16
        Port: Twisted Pair
cd9d16
        PHYAD: 0
cd9d16
        Transceiver: internal
cd9d16
        Auto-negotiation: on
cd9d16
        MDI-X: Unknown
cd9d16
        Supports Wake-on: umbg
cd9d16
        Wake-on: d
cd9d16
        Current message level: 0x00000007 (7)
cd9d16
                               drv probe link
cd9d16
        Link detected: yes
cd9d16
cd9d16
 (qemu) set_link e1000.0 on
cd9d16
cd9d16
Linux guest after:
cd9d16
cd9d16
 (qemu) set_link e1000.0 off
cd9d16
 [   63.384221] e1000: eth0 NIC Link is Down
cd9d16
cd9d16
 kvm-sid:~# ethtool eth0
cd9d16
 Settings for eth0:
cd9d16
        Supported ports: [ TP ]
cd9d16
        Supported link modes:   10baseT/Half 10baseT/Full
cd9d16
                                100baseT/Half 100baseT/Full
cd9d16
                                1000baseT/Full
cd9d16
        Supports auto-negotiation: Yes
cd9d16
        Advertised link modes:  10baseT/Half 10baseT/Full
cd9d16
                                100baseT/Half 100baseT/Full
cd9d16
                                1000baseT/Full
cd9d16
        Advertised pause frame use: No
cd9d16
        Advertised auto-negotiation: Yes
cd9d16
        Speed: Unknown!
cd9d16
        Duplex: Unknown! (255)
cd9d16
        Port: Twisted Pair
cd9d16
        PHYAD: 0
cd9d16
        Transceiver: internal
cd9d16
        Auto-negotiation: on
cd9d16
        MDI-X: Unknown
cd9d16
        Supports Wake-on: umbg
cd9d16
        Wake-on: d
cd9d16
        Current message level: 0x00000007 (7)
cd9d16
                               drv probe link
cd9d16
        Link detected: no
cd9d16
cd9d16
 (qemu) set_link e1000.0 on
cd9d16
 [   84.304582] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
cd9d16
cd9d16
Signed-off-by: Bjørn Mork <bjorn@mork.no>
cd9d16
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
cd9d16
(cherry picked from commit d4044c2a6b9ba4a00dd653f515a4b0ebfcb7e125)
cd9d16
cd9d16
Signed-off-by: Andreas Färber <afaerber@suse.de>
cd9d16
---
cd9d16
 hw/e1000.c    |  7 +++++--
cd9d16
 hw/e1000_hw.h | 17 +++++++++++++++++
cd9d16
 2 files changed, 22 insertions(+), 2 deletions(-)
cd9d16
cd9d16
diff --git a/hw/e1000.c b/hw/e1000.c
cd9d16
index 96d84f9..e4d9ab5 100644
cd9d16
--- a/hw/e1000.c
cd9d16
+++ b/hw/e1000.c
cd9d16
@@ -624,10 +624,13 @@ e1000_set_link_status(VLANClientState *nc)
cd9d16
     E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
cd9d16
     uint32_t old_status = s->mac_reg[STATUS];
cd9d16
 
cd9d16
-    if (nc->link_down)
cd9d16
+    if (nc->link_down) {
cd9d16
         s->mac_reg[STATUS] &= ~E1000_STATUS_LU;
cd9d16
-    else
cd9d16
+        s->phy_reg[PHY_STATUS] &= ~MII_SR_LINK_STATUS;
cd9d16
+    } else {
cd9d16
         s->mac_reg[STATUS] |= E1000_STATUS_LU;
cd9d16
+        s->phy_reg[PHY_STATUS] |= MII_SR_LINK_STATUS;
cd9d16
+    }
cd9d16
 
cd9d16
     if (s->mac_reg[STATUS] != old_status)
cd9d16
         set_ics(s, 0, E1000_ICR_LSC);
cd9d16
diff --git a/hw/e1000_hw.h b/hw/e1000_hw.h
cd9d16
index 9bd8a4b..2e341ac 100644
cd9d16
--- a/hw/e1000_hw.h
cd9d16
+++ b/hw/e1000_hw.h
cd9d16
@@ -349,6 +349,23 @@
cd9d16
 #define M88E1000_PHY_VCO_REG_BIT8  0x100 /* Bits 8 & 11 are adjusted for */
cd9d16
 #define M88E1000_PHY_VCO_REG_BIT11 0x800    /* improved BER performance */
cd9d16
 
cd9d16
+/* PHY Status Register */
cd9d16
+#define MII_SR_EXTENDED_CAPS     0x0001	/* Extended register capabilities */
cd9d16
+#define MII_SR_JABBER_DETECT     0x0002	/* Jabber Detected */
cd9d16
+#define MII_SR_LINK_STATUS       0x0004	/* Link Status 1 = link */
cd9d16
+#define MII_SR_AUTONEG_CAPS      0x0008	/* Auto Neg Capable */
cd9d16
+#define MII_SR_REMOTE_FAULT      0x0010	/* Remote Fault Detect */
cd9d16
+#define MII_SR_AUTONEG_COMPLETE  0x0020	/* Auto Neg Complete */
cd9d16
+#define MII_SR_PREAMBLE_SUPPRESS 0x0040	/* Preamble may be suppressed */
cd9d16
+#define MII_SR_EXTENDED_STATUS   0x0100	/* Ext. status info in Reg 0x0F */
cd9d16
+#define MII_SR_100T2_HD_CAPS     0x0200	/* 100T2 Half Duplex Capable */
cd9d16
+#define MII_SR_100T2_FD_CAPS     0x0400	/* 100T2 Full Duplex Capable */
cd9d16
+#define MII_SR_10T_HD_CAPS       0x0800	/* 10T   Half Duplex Capable */
cd9d16
+#define MII_SR_10T_FD_CAPS       0x1000	/* 10T   Full Duplex Capable */
cd9d16
+#define MII_SR_100X_HD_CAPS      0x2000	/* 100X  Half Duplex Capable */
cd9d16
+#define MII_SR_100X_FD_CAPS      0x4000	/* 100X  Full Duplex Capable */
cd9d16
+#define MII_SR_100T4_CAPS        0x8000	/* 100T4 Capable */
cd9d16
+
cd9d16
 /* Interrupt Cause Read */
cd9d16
 #define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
cd9d16
 #define E1000_ICR_TXQE          0x00000002 /* Transmit Queue empty */
cd9d16
-- 
cd9d16
1.7.11.2
cd9d16