diff options
author | Gaggery Tsai <gaggery.tsai@intel.com> | 2017-12-26 17:13:52 +0800 |
---|---|---|
committer | Furquan Shaikh <furquan@google.com> | 2018-01-22 23:04:34 +0000 |
commit | 1f8470463634b4e09c986150a07b51edfd1999ee (patch) | |
tree | 88e33b6ed61b1ae8e909c86347766b2cf33fa809 | |
parent | ff588063e9f747a6c13a009fb100ed49fca93c7b (diff) | |
download | coreboot-1f8470463634b4e09c986150a07b51edfd1999ee.tar.xz |
drivers/net: Add device index for multiple NIC cards
This patch adds a member device_index to r8168 chip information which
allows driver to identify which NIC card requests MAC address.
In this implementation, only 10 NIC cards are supported, the device
index is in the range of 0 to 10. Regarding to MAC address mapping,
when there is only one NIC on DUT, it is treated as a special case
mapping to "ethernet_mac" in VPD for backward compatibility. When
there are multiple NICs on DUT, they are mapping to "ethernet_macN"
where N is [0-9].
Device tree configuration:
For single NIC: .device_index = "0", maps to "ethernet_mac"
For multiple NICs: .device_index = "[1-10]", maps to
"ethernet_mac[device_index - 1]"
BUG=b:69950854
BRANCH=None
TEST=Added device_index = [0-10] under /drivers/net in device tree &&
Programmed the mac address to VPD in shell
vpd -s ethernet_mac=<mac address> or
vpd -s ethernet-mac[0-9]=<mac address> && reboot the system.
Ensure the MAC address was fetched correctly by ifconfig command.
Change-Id: I108b9bfba39370c8906a2fa4d2b39b106e884e0c
Signed-off-by: Gaggery Tsai <gaggery.tsai@intel.com>
Reviewed-on: https://review.coreboot.org/22984
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
-rw-r--r-- | src/drivers/net/chip.h | 8 | ||||
-rw-r--r-- | src/drivers/net/r8168.c | 39 |
2 files changed, 38 insertions, 9 deletions
diff --git a/src/drivers/net/chip.h b/src/drivers/net/chip.h index 8e8c02b002..81dbefa556 100644 --- a/src/drivers/net/chip.h +++ b/src/drivers/net/chip.h @@ -16,7 +16,13 @@ struct drivers_net_config { uint16_t customized_leds; - unsigned wake; /* Wake pin for ACPI _PRW */ + unsigned wake; /* Wake pin for ACPI _PRW */ + /* + * There maybe many NIC cards in a system. + * This paramter is for driver to identify what + * the device number is and the valid range is [1-10]. + */ + uint8_t device_index; }; #endif /* __DRIVERS_R8168_CHIP_H__ */ diff --git a/src/drivers/net/r8168.c b/src/drivers/net/r8168.c index 4c17017440..288888d4a8 100644 --- a/src/drivers/net/r8168.c +++ b/src/drivers/net/r8168.c @@ -45,6 +45,8 @@ #define CFG_9346_LOCK 0x00 #define CFG_9346_UNLOCK 0xc0 +#define DEVICE_INDEX_BYTE 12 +#define MAX_DEVICE_SUPPORT 10 /** * search: Find first instance of string in a given region * @param p string to find @@ -91,13 +93,25 @@ static u8 get_hex_digit(const u8 c) #define MACLEN 17 -static enum cb_err fetch_mac_string_vpd(u8 *macstrbuf) +static enum cb_err fetch_mac_string_vpd(u8 *macstrbuf, const u8 device_index) { struct region_device rdev; void *search_address; size_t search_length; size_t offset; - char key[] = "ethernet_mac"; + char key[] = "ethernet_mac "; /* Leave a space at tail to stuff an index */ + + /* + * The device_index 0 is treated as an special case matching to + * "ethernet_mac" with single NIC on DUT. When there are mulitple + * NICs on DUT, they are mapping to "ethernet_macN", where + * N is [0-9]. + */ + if (device_index == 0) + key[DEVICE_INDEX_BYTE] = '\0'; + else + /* Translate index number from integer to ascii */ + key[DEVICE_INDEX_BYTE] = (device_index - 1) + '0'; if (fmap_locate_area_as_rdev("RO_VPD", &rdev)) { printk(BIOS_ERR, "Error: Couldn't find RO_VPD region."); @@ -112,6 +126,7 @@ static enum cb_err fetch_mac_string_vpd(u8 *macstrbuf) search_length = region_device_sz(&rdev); offset = search(key, search_address, strlen(key), search_length); + if (offset == search_length) { printk(BIOS_ERR, "Error: Could not locate '%s' in VPD\n", key); @@ -119,14 +134,13 @@ static enum cb_err fetch_mac_string_vpd(u8 *macstrbuf) } printk(BIOS_DEBUG, "Located '%s' in VPD\n", key); - offset += sizeof(key); /* move to next character */ + offset += strlen(key) + 1; /* move to next character */ if (offset + MACLEN > search_length) { printk(BIOS_ERR, "Search result too small!\n"); return CB_ERR; } memcpy(macstrbuf, search_address + offset, MACLEN); - return CB_SUCCESS; } @@ -172,16 +186,25 @@ static void program_mac_address(struct device *dev, u16 io_base) int i = 0; /* Default MAC Address of 00:E0:4C:00:C0:B0 */ u8 mac[6] = { 0x00, 0xe0, 0x4c, 0x00, 0xc0, 0xb0 }; + struct drivers_net_config *config = dev->chip_info; /* check the VPD for the mac address */ if (IS_ENABLED(CONFIG_RT8168_GET_MAC_FROM_VPD)) { - if (fetch_mac_string_vpd(macstrbuf) != CB_SUCCESS) - printk(BIOS_ERR, "r8168: mac address not found in VPD," - " using default 00:e0:4c:00:c0:b0\n"); + /* Current implementation is up to 10 NIC cards */ + if (config && config->device_index <= MAX_DEVICE_SUPPORT) { + if (fetch_mac_string_vpd(macstrbuf, config->device_index) + != CB_SUCCESS) + printk(BIOS_ERR, "r8168: mac address not found in VPD," + " using default 00:e0:4c:00:c0:b0\n"); + } else { + printk(BIOS_ERR, "r8168: the maximum device_index should be" + " less then %d\n. Using default 00:e0:4c:00:c0:b0\n", + MAX_DEVICE_SUPPORT); + } } else { if (fetch_mac_string_cbfs(macstrbuf) != CB_SUCCESS) printk(BIOS_ERR, "r8168: Error reading MAC from CBFS," - " using default 00:e0:4c:00:c0:b0\n"); + " using default 00:e0:4c:00:c0:b0\n"); } get_mac_address(mac, macstrbuf); |