drivers/net/r8168: Add ASPM control mechanism

Add a new configuration parameter "enable_aspm_l1_2".

Write value 0xe059000f to register offset 0xb0 to allow kernel driver to
enable ASPM L1.2.

Use Kconfig "PCIEXP_ASPM" and "enable_aspm_l1_2" to decide whether to
enable ASPM L1.2.

BUG=b:204309459
TEST=emerge and test if the driver can read the correct value

Change-Id: I944dbf04d3ca19df4de224540bee538bff4d1f12
Signed-off-by: Alan Huang <alan-huang@quanta.corp-partner.google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/61267
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
diff --git a/src/drivers/net/chip.h b/src/drivers/net/chip.h
index a4ba8af..f253cae 100644
--- a/src/drivers/net/chip.h
+++ b/src/drivers/net/chip.h
@@ -31,6 +31,9 @@
 	 * the device number is and the valid range is [1-10].
 	 */
 	uint8_t device_index;
+
+	/* Allow kernel driver to enable ASPM L1.2. */
+	bool enable_aspm_l1_2;
 };
 
 #endif /* __DRIVERS_R8168_CHIP_H__ */
diff --git a/src/drivers/net/r8168.c b/src/drivers/net/r8168.c
index 51d4fcb..3432249 100644
--- a/src/drivers/net/r8168.c
+++ b/src/drivers/net/r8168.c
@@ -36,6 +36,8 @@
 #define CFG_9346		0x50
 #define  CFG_9346_LOCK		0x00
 #define  CFG_9346_UNLOCK	0xc0
+#define CMD_REG_ASPM		0xb0
+#define ASPM_L1_2_MASK		0xe059000f
 
 #define DEVICE_INDEX_BYTE	12
 #define MAX_DEVICE_SUPPORT	10
@@ -244,6 +246,20 @@
 	printk(BIOS_DEBUG, "done\n");
 }
 
+static void enable_aspm_l1_2(u16 io_base)
+{
+	printk(BIOS_INFO, "rtl: Enable ASPM L1.2\n");
+
+	/* Disable register protection */
+	outb(CFG_9346_UNLOCK, io_base + CFG_9346);
+
+	/* Enable ASPM_L1.2 */
+	outl(ASPM_L1_2_MASK, io_base + CMD_REG_ASPM);
+
+	/* Lock config regs */
+	outb(CFG_9346_LOCK, io_base + CFG_9346);
+}
+
 static void r8168_set_customized_led(struct device *dev, u16 io_base)
 {
 	struct drivers_net_config *config = dev->chip_info;
@@ -338,6 +354,10 @@
 	/* Program customized LED mode */
 	if (CONFIG(RT8168_SET_LED_MODE))
 		r8168_set_customized_led(dev, io_base);
+
+	struct drivers_net_config *config = dev->chip_info;
+	if (CONFIG(PCIEXP_ASPM) && config->enable_aspm_l1_2)
+		enable_aspm_l1_2(io_base);
 }
 
 #if CONFIG(HAVE_ACPI_TABLES)