Date: Sun, 7 Jun 2009 19:27:12 +0200 (CEST) From: Juergen Lock <nox@jelal.kn-bremen.de> To: sebosik@demax.sk Cc: freebsd-emulation@freebsd.org Subject: em(4) patch for qemu/kvm/vbox guests (was: Re: flash10 vs f10; em(4) now broken in -current in qemu/vbox) Message-ID: <200906071727.n57HRCZK012510@triton.kn-bremen.de> In-Reply-To: <4A2BC96B.9010209@demax.sk>
next in thread | previous in thread | raw e-mail | index | archive | help
In article <4A2BC96B.9010209@demax.sk> you write:
>Hi
>
>I think its caused by internal control of MAC address validity in
>freebsd-sources ( sys/dev/e1000/if_em.c ) on line 4950.
>You can safely remove references to that function + function itself and than
>happily use if_em undex VBox as before.
Actually that wasn't it, in fact commit 190872 changed the way mac addresses
are read (e1000_read_mac_addr_generic() in sys/dev/e1000/e1000_nvm.c) - if I
add the old way back for the case that the new code gets all zeros em(4)
works again:
Index: sys/dev/e1000/e1000_nvm.c
@@ -820,20 +820,45 @@
u32 rar_high;
u32 rar_low;
u16 i;
+ s32 ret_val = E1000_SUCCESS;
+
+ DEBUGFUNC("e1000_read_mac_addr");
rar_high = E1000_READ_REG(hw, E1000_RAH(0));
rar_low = E1000_READ_REG(hw, E1000_RAL(0));
- for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
- hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
+ /* Fall back to reading from actual EEPROM like this code used to do
+ * in case we got all zeroes. (This fixes qemu/kvm/vbox guests.)
+ */
+ if (!rar_low && !rar_high) {
+ u16 offset, nvm_data;
+
+ for (i = 0; i < ETH_ADDR_LEN; i += 2) {
+ offset = i >> 1;
+ ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
+ if (ret_val) {
+ DEBUGOUT("NVM Read Error\n");
+ goto out;
+ }
+ hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
+ hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
+ }
- for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
- hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
+ /* Flip last bit of mac address if we're on second port */
+ if (hw->bus.func == E1000_FUNC_1)
+ hw->mac.perm_addr[5] ^= 1;
+ } else {
+ for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
+ hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
+ for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
+ hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
+ }
for (i = 0; i < ETH_ADDR_LEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
- return E1000_SUCCESS;
+out:
+ return ret_val;
}
/**
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906071727.n57HRCZK012510>
