diff mbox

[v1,3/3] e1000: signal guest on successful link auto-negotiation

Message ID 1402939751-8371-4-git-send-email-somlo@cmu.edu
State New
Headers show

Commit Message

Gabriel L. Somlo June 16, 2014, 5:29 p.m. UTC
Generate a link status change interrupt once link auto-netotiation
is successfully completed. This does not affect Linux and Windows
(XP and 7 tested) in any way, but is needed by the stock OS X driver
(AppleIntel8254XEthernet.kext), which would otherwise fail to notice
the link status change event.

Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
---

While Windows and Linux e1000 drivers (and, apparently, the open-source
AppleIntelE1000.kext from SourceForge) don't need an LSC interrupt to
detect when the link comes on (maybe because they're polling for it, I'd
have to look through the source to be 100% sure), Apple's stock, "out of
the box" e1000 driver (AppleIntel8254XEthernet.kext) will not become
aware of the link status change unless we send it an interrupt.

I believe it's not an unreasonable thing to do, and it's definitely not
something that happens in the BIOS, as I previously (mistakenly) thought...

As I mentioned in the commit blurb above, Linux and Windows don't mind the
additional LSC interrupt (not that they should, but just making sure... :).

Finally, it may be better to simply move e1000_autoneg_timer() to somewhere
*after* set_ics() in the source file, to avoid the forward-reference, but
I figured I'd keep the visual noise to a minimum for now...

Thanks,
  Gabriel

 hw/net/e1000.c | 3 +++
 1 file changed, 3 insertions(+)
diff mbox

Patch

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 04e4044..0c9b472 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -204,6 +204,8 @@  set_phy_ctrl(E1000State *s, int index, uint16_t val)
     }
 }
 
+static void set_ics(E1000State *s, int index, uint32_t val);
+
 static void
 e1000_autoneg_timer(void *opaque)
 {
@@ -213,6 +215,7 @@  e1000_autoneg_timer(void *opaque)
         s->phy_reg[PHY_LP_ABILITY] |= MII_LPAR_LPACK;
         s->phy_reg[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
         DBGOUT(PHY, "Auto negotiation is completed\n");
+        set_ics(s, 0, E1000_ICS_LSC); /* signal link status change to guest */
     }
 }