drivers/net/r8168.c: Add option to program MAC address to ERI registers
On mainboard/asus/p8z77-v_le_plus, programmed MAC address is being reverted with controller resets done at loading and unloading of Linux r8169 kernel module. Ghidra examination of vendor BIOS reveals an additional sequence to program the MAC address into its ERI register block. This patch adds code to replicate that sequence, gated by a Kconfig so it's only included where necessary. BUG=https://ticket.coreboot.org/issues/579 TEST=When applied with mainboard level changes in CB:87437, specified MAC address now recognized and retained by Linux r8169 driver without further work. Change-Id: Iae33e24e564f9fba52acb16138fe89085d9eeb03 Signed-off-by: Keith Hui <buurin@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/87436 Reviewed-by: Matt DeVillier <matt.devillier@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
4b871c6314
commit
2b598a9472
2 changed files with 41 additions and 3 deletions
|
|
@ -16,6 +16,16 @@ config REALTEK_8168_MACADDRESS
|
|||
hexadecimal number for it to be valid. Failing to do so will
|
||||
result in the default macaddress being used.
|
||||
|
||||
config RT8168_PUT_MAC_TO_ERI
|
||||
bool
|
||||
help
|
||||
After programming MAC address into the regular rt8168 ID registers,
|
||||
also program it into ERI. On some mainboards our programmed
|
||||
MAC address will not survive a controller reset without this step.
|
||||
|
||||
Select at mainboard level only if its rt8168 has no EEPROM and
|
||||
programmed MAC address is lost after booting to OS.
|
||||
|
||||
config RT8168_GET_MAC_FROM_VPD
|
||||
bool
|
||||
default n
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#define CFG_9346_UNLOCK 0xc0
|
||||
#define CMD_REG_ASPM 0xb0
|
||||
#define ASPM_L1_2_MASK 0xe059000f
|
||||
#define ERIDR 0x70
|
||||
#define ERIAR 0x74
|
||||
|
||||
#define DEVICE_INDEX_BYTE 12
|
||||
#define MAX_DEVICE_SUPPORT 10
|
||||
|
|
@ -200,6 +202,7 @@ static void get_mac_address(u8 *macaddr, const u8 *strbuf)
|
|||
static void program_mac_address(struct device *dev, u16 io_base)
|
||||
{
|
||||
u8 macstrbuf[MACLEN] = { 0 };
|
||||
u32 maclo, machi;
|
||||
int i = 0;
|
||||
/* Default MAC Address of 00:E0:4C:00:C0:B0 */
|
||||
u8 mac[6] = { 0x00, 0xe0, 0x4c, 0x00, 0xc0, 0xb0 };
|
||||
|
|
@ -234,11 +237,36 @@ static void program_mac_address(struct device *dev, u16 io_base)
|
|||
outb(CFG_9346_UNLOCK, io_base + CFG_9346);
|
||||
|
||||
/* Set MAC address: only 4-byte write accesses allowed */
|
||||
outl(mac[4] | mac[5] << 8, io_base + 4);
|
||||
maclo = mac[0] | mac[1] << 8 | mac[2] << 16 | mac[3] << 24;
|
||||
machi = mac[4] | mac[5] << 8;
|
||||
outl(machi, io_base + 4);
|
||||
inl(io_base + 4);
|
||||
outl(mac[0] | mac[1] << 8 | mac[2] << 16 | mac[3] << 24,
|
||||
io_base);
|
||||
outl(maclo, io_base);
|
||||
inl(io_base);
|
||||
/* Some boards (e.g. asus/p8z77-v_le_plus) need the MAC address set here too */
|
||||
if (CONFIG(RT8168_PUT_MAC_TO_ERI)) {
|
||||
switch (pci_read_config8(dev, PCI_REVISION_ID)) {
|
||||
case 6:
|
||||
outl((maclo & 0xffff) << 16, io_base + ERIDR);
|
||||
inl(io_base + ERIDR);
|
||||
outl(0x8000f0f0, io_base + ERIAR);
|
||||
inl(io_base + ERIAR);
|
||||
outl((machi << 16 | maclo >> 16), io_base + ERIDR);
|
||||
inl(io_base + ERIDR);
|
||||
outl(0x8000f0f4, io_base + ERIAR);
|
||||
break;
|
||||
case 9:
|
||||
outl(maclo, io_base + ERIDR);
|
||||
inl(io_base + ERIDR);
|
||||
outl(0x8000f0e0, io_base + ERIAR);
|
||||
inl(io_base + ERIAR);
|
||||
outl(machi, io_base + ERIDR);
|
||||
inl(io_base + ERIDR);
|
||||
outl(0x800030e4, io_base + ERIAR);
|
||||
break;
|
||||
}
|
||||
udelay(1000);
|
||||
}
|
||||
/* Lock config regs */
|
||||
outb(CFG_9346_LOCK, io_base + CFG_9346);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue