diff -Naur qemu/hw/net/e1000.c qemu-a/hw/net/e1000.c
--- qemu/hw/net/e1000.c 2013-10-27 15:36:05.496526538 -0600
+++ qemu-a/hw/net/e1000.c 2013-10-30 18:09:03.101711694 -0600
@@ -203,6 +203,12 @@
DBGOUT(PHY, "Start link auto negotiation\n");
timer_mod(s->autoneg_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
}
+
+ if (val & 0x8000) {
+ val &= 0x7fff;
+ set_ics(s, 0, E1000_ICR_LSC);
+ }
+ s->phy_reg[PHY_CTRL] = val;
}
static void
@@ -390,6 +396,8 @@
d->rxbuf_min_shift = 1;
memset(&d->tx, 0, sizeof d->tx);
+ d->mac_reg[RA+0] = (macaddr[3] << 24) | (macaddr[2] << 16) | (macaddr[1] << 8) | macaddr[0];
+ d->mac_reg[RA+1] = E1000_RAH_AV | (macaddr[5] << 8) | macaddr[4];
if (qemu_get_queue(d->nic)->link_down) {
e1000_link_down(d);
}
@@ -409,6 +417,8 @@
{
/* RST is self clearing */
s->mac_reg[CTRL] = val & ~E1000_CTRL_RST;
+ if (val & E1000_CTRL_RST)
+ set_ics(s, 0, E1000_ICR_LSC);
}
static void
@@ -446,7 +456,15 @@
if (addr < NPHYWRITEOPS && phyreg_writeops[addr]) {
phyreg_writeops[addr](s, index, data);
}
- s->phy_reg[addr] = data;
+ switch (addr) {
+ case PHY_CTRL:
+ s->phy_reg[addr] = data & 0x7eff;
+ if (s->phy_reg[addr] != data)
+ set_ics(s, 0, E1000_ICR_LSC);
+ break;
+ default:
+ s->phy_reg[addr] = data;
+ }
}
}
s->mac_reg[MDIC] = val | E1000_MDIC_READY;
@@ -1163,8 +1181,13 @@
static void
set_ims(E1000State *s, int index, uint32_t val)
{
+ uint32_t old_val = s->mac_reg[IMS];
s->mac_reg[IMS] |= val;
- set_ics(s, 0, 0);
+ if ((val & E1000_ICR_LSC) && old_val == 0) {
+ set_ics(s, 0, E1000_ICR_LSC); /* inject Link Status for uncooperative Darwin driver */
+ } else {
+ set_ics(s, 0, 0);
+ }
}
#define getreg(x) [x] = mac_readreg
@@ -1192,7 +1215,7 @@
static void (*macreg_writeops[])(E1000State *, int, uint32_t) = {
putreg(PBA), putreg(EERD), putreg(SWSM), putreg(WUFC),
putreg(TDBAL), putreg(TDBAH), putreg(TXDCTL), putreg(RDBAH),
- putreg(RDBAL), putreg(LEDCTL), putreg(VET),
+ putreg(RDBAL), putreg(LEDCTL), putreg(VET), putreg(MANC),
[TDLEN] = set_dlen, [RDLEN] = set_dlen, [TCTL] = set_tctl,
[TDT] = set_tctl, [MDIC] = set_mdic, [ICS] = set_ics,
[TDH] = set_16bit, [RDH] = set_16bit, [RDT] = set_rdt,