summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/coreboot/2a6f251f4d8d41d13051ec2c897aea800c07275a/grub/ga-g41m-es2l/004-add-driver-to-reset-nic.patch
blob: 7d1d1c5adc45f49589cac00905383621b79b474e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
From 8f90ec9634e7eb0a385902fe2d74af4ebc33c7c2 Mon Sep 17 00:00:00 2001
From: Damien Zammit <damien@zamaudio.com>
Date: Sat, 21 May 2016 02:24:19 +1000
Subject: [PATCH] drivers/net/r8168: Add driver for realtek nic

One thing that is vital to this patch is the MAC address setting
in case the EEPROM/efuse is unconfigured.
Linux now recognises the default MAC address on GA-G41M-ES2L which
does rely on the default bios settings for the MAC address.

Change-Id: I32e070b545b4c6369686a7087b7ff838d00764e3
Signed-off-by: Damien Zammit <damien@zamaudio.com>
---

diff --git a/src/drivers/net/Kconfig b/src/drivers/net/Kconfig
new file mode 100644
index 0000000..b4bafd2
--- /dev/null
+++ b/src/drivers/net/Kconfig
@@ -0,0 +1,5 @@
+config REALTEK_8168_RESET
+	bool "Realtek 8168 reset"
+	help
+	  This forces a realtek 10ec:8168 card to reset to ensure power state
+	  is correct at boot.
diff --git a/src/drivers/net/Makefile.inc b/src/drivers/net/Makefile.inc
index 9b3008d..e435d48 100644
--- a/src/drivers/net/Makefile.inc
+++ b/src/drivers/net/Makefile.inc
@@ -1,2 +1,3 @@
 romstage-$(CONFIG_CONSOLE_NE2K) += ne2k.c
 ramstage-$(CONFIG_CONSOLE_NE2K) += ne2k.c
+ramstage-$(CONFIG_REALTEK_8168_RESET) += r8168.c
diff --git a/src/drivers/net/r8168.c b/src/drivers/net/r8168.c
new file mode 100644
index 0000000..4301693
--- /dev/null
+++ b/src/drivers/net/r8168.c
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Damien Zammit <damien@zamaudio.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This driver forces the 10ec:8168 device to reset so that it goes
+ * into a proper power state, also programs a default MAC address
+ * so that if the EEPROM/efuse is unconfigured it still has a default MAC.
+ */
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_def.h>
+#include <delay.h>
+#include <console/console.h>
+
+#define NIC_TIMEOUT		1000
+
+#define CMD_REG			0x37
+#define  CMD_REG_RESET		0x10
+
+#define CFG_9346		0x50
+#define  CFG_9346_LOCK		0x00
+#define  CFG_9346_UNLOCK	0xc0
+
+static void r8168_init(struct device *dev)
+{
+	u32 i;
+	const u8 mac[6] = { 0x00, 0xe0, 0x4c, 0x00, 0xc0, 0xb0 };
+
+	/* Get the resource of the NIC mmio */
+	struct resource *nic_res = find_resource(dev, PCI_BASE_ADDRESS_0);
+	u16 nic_port = (u16)nic_res->base;
+
+	/* Set bus master */
+	pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER
+					| PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
+
+	/* Reset NIC */
+	printk(BIOS_DEBUG, "r8168: Resetting NIC...");
+	outb(CMD_REG_RESET, nic_port + CMD_REG);
+
+	i = 0;
+	/* Poll for reset, with 1s timeout */
+	while (i < NIC_TIMEOUT && (inb(nic_port + CMD_REG) & CMD_REG_RESET)) {
+		udelay(1000);
+		if (++i >= NIC_TIMEOUT)
+			printk(BIOS_DEBUG, "timeout waiting for nic to reset\n");
+	}
+	if (i < NIC_TIMEOUT)
+		printk(BIOS_DEBUG, "done\n");
+
+	/* Unlock config regs */
+	outb(CFG_9346_UNLOCK, nic_port + CFG_9346);
+
+	/* Set MAC address 00:e0:4c:00:c0:b0
+	 * NB: only 4-byte write accesses allowed
+	 */
+	outl(mac[4] | mac[5] << 8, nic_port + 4);
+	inl(nic_port + 4);
+
+	outl(mac[0] | mac[1] << 8 | mac[2] << 16 | mac[3] << 24, nic_port);
+	inl(nic_port);
+
+	/* Lock config regs */
+	outb(CFG_9346_LOCK, nic_port + CFG_9346);
+}
+
+static struct device_operations r8168_ops  = {
+       .read_resources   = pci_dev_read_resources,
+       .set_resources    = pci_dev_set_resources,
+       .enable_resources = pci_dev_enable_resources,
+       .init             = r8168_init,
+       .scan_bus         = 0,
+};
+
+static const struct pci_driver r8168_driver __pci_driver = {
+        .ops    = &r8168_ops,
+        .vendor = 0x10ec,
+        .device = 0x8168,
+};