diff --git a/src/drivers/net/Kconfig b/src/drivers/net/Kconfig index 67a138938e..bd6f09a61d 100644 --- a/src/drivers/net/Kconfig +++ b/src/drivers/net/Kconfig @@ -18,3 +18,14 @@ config RT8168_GET_MAC_FROM_VPD bool default n select REALTEK_8168_RESET + +config RT8168_SET_LED_MODE + bool + default n + select REALTEK_8168_RESET + help + This is to set a customized LED mode to distinguish 10/100/1000 + link and speed status with limited LEDs avaiable on a board. + Please refer to RTL811x datasheet section 7.2 Customizable LED + Configuration for details. With this flag enabled, the + customized_leds variable will be read from devicetree setting. diff --git a/src/drivers/net/chip.h b/src/drivers/net/chip.h new file mode 100644 index 0000000000..7a37cdedb9 --- /dev/null +++ b/src/drivers/net/chip.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * 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. + */ + +#ifndef __DRIVERS_R8168_CHIP_H__ +#define __DRIVERS_R8168_CHIP_H__ + +struct drivers_net_config { + uint16_t customized_leds; +}; + +#endif /* __DRIVERS_R8168_CHIP_H__ */ diff --git a/src/drivers/net/r8168.c b/src/drivers/net/r8168.c index 3727ccdd0f..350dc37322 100644 --- a/src/drivers/net/r8168.c +++ b/src/drivers/net/r8168.c @@ -31,11 +31,13 @@ #include #include #include +#include "chip.h" #define NIC_TIMEOUT 1000 #define CMD_REG 0x37 #define CMD_REG_RESET 0x10 +#define CMD_LED0_LED1 0x18 #define CFG_9346 0x50 #define CFG_9346_LOCK 0x00 @@ -211,22 +213,59 @@ static void program_mac_address(struct device *dev, u16 io_base) printk(BIOS_DEBUG, "done\n"); } +static void r8168_set_customized_led(struct device *dev, u16 io_base) +{ + struct drivers_net_config *config = dev->chip_info; + + if (!config) + return; + + /* Read the customized LED setting from devicetree */ + printk(BIOS_DEBUG, "r8168: Customized LED 0x%x\n", config->customized_leds); + + /* + * Refer to RTL8111H datasheet 7.2 Customizable LED Configuration + * Starting from offset 0x18 + * Bit[15:12] LED Feature Control(FC) + * Bit[11:08] LED Select for PINLED2 + * Bit[07:04] LED Select for PINLED1 + * Bit[03:00] LED Select for PINLED0 + * + * Speed Link10M Link100M Link1000M ACT/Full + * LED0 Bit0 Bit1 Bit2 Bit3 + * LED1 Bit4 Bit5 Bit6 Bit7 + * LED2 Bit8 Bit9 Bit10 Bit11 + * FC Bit12 Bit13 Bit14 Bit15 + */ + + /* Set customized LED registers */ + outw(config->customized_leds, io_base + CMD_LED0_LED1); + printk(BIOS_DEBUG, "r8168: read back LED setting as 0x%x\n", + inw(io_base + CMD_LED0_LED1)); +} + static void r8168_init(struct device *dev) { /* Get the resource of the NIC mmio */ struct resource *nic_res = find_resource(dev, PCI_BASE_ADDRESS_0); u16 io_base = (u16)nic_res->base; + /* Check if the base is invalid */ + if (!io_base) { + printk(BIOS_ERR, "r8168: Error cant find IO resource\n"); + return; + } /* Enable but do not set bus master */ pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_IO); /* Program MAC address based on CBFS "macaddress" containing * a string AA:BB:CC:DD:EE:FF */ - if (io_base) - program_mac_address(dev, io_base); - else - printk(BIOS_ERR, "r8168: Error cant find MMIO resource\n"); + program_mac_address(dev, io_base); + + /* Program customized LED mode */ + if (IS_ENABLED(CONFIG_RT8168_SET_LED_MODE)) + r8168_set_customized_led(dev, io_base); } static struct device_operations r8168_ops = {