From 2a82f744d460afee2218e072a3b8a31a4c6efb11 Mon Sep 17 00:00:00 2001 From: Edward O'Callaghan Date: Wed, 25 Mar 2020 12:52:50 +1100 Subject: drivers/net/r8168: Split fetch_mac_string_vpd() logic up Orginally fetch_mac_string_vpd() has been special cased around a device_index of 0/1 that causes a number of edge cases and complexity when attempting to refactor to deal with the revised VPD format. The following change prepares the ground work by splitting up the functional into logical workers where we can deal with each edge case in a more bounded way. The background here is that the format for VPD has changed s.t. the first NIC should always have a zero concat to the end. The details of that can be found here: https://chromeos.google.com/partner/dlm/docs/factory/vpd.html#field-ethernet_macn BUG=b:152157720 BRANCH=none TEST=none Change-Id: Idc886d9b0b3037c91f40b742437e4e50711b5f00 Signed-off-by: Edward O'Callaghan Reviewed-on: https://review.coreboot.org/c/coreboot/+/39811 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/drivers/net/r8168.c | 84 +++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 34 deletions(-) (limited to 'src/drivers') diff --git a/src/drivers/net/r8168.c b/src/drivers/net/r8168.c index 07069aa88b..fcdac90481 100644 --- a/src/drivers/net/r8168.c +++ b/src/drivers/net/r8168.c @@ -92,25 +92,13 @@ static u8 get_hex_digit(const u8 c) #define MACLEN 17 -static enum cb_err fetch_mac_string_vpd(u8 *macstrbuf, const u8 device_index) +/* Returns MAC address based on the key that is passed in. */ +static enum cb_err fetch_mac_vpd_key(u8 *macstrbuf, const char *vpd_key) { struct region_device rdev; void *search_address; size_t search_length; size_t offset; - 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."); @@ -123,26 +111,69 @@ static enum cb_err fetch_mac_string_vpd(u8 *macstrbuf, const u8 device_index) } search_length = region_device_sz(&rdev); - offset = search(key, search_address, strlen(key), + offset = search(vpd_key, search_address, strlen(vpd_key), search_length); if (offset == search_length) { printk(BIOS_ERR, - "Error: Could not locate '%s' in VPD\n", key); + "Error: Could not locate '%s' in VPD\n", vpd_key); return CB_ERR; } - printk(BIOS_DEBUG, "Located '%s' in VPD\n", key); + printk(BIOS_DEBUG, "Located '%s' in VPD\n", vpd_key); - offset += strlen(key) + 1; /* move to next character */ + offset += strlen(vpd_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; } +/* Prepares vpd_key by concatenating ethernet_mac with device_index */ +static enum cb_err fetch_mac_vpd_dev_idx(u8 *macstrbuf, u8 device_index) +{ + 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'; + + return fetch_mac_vpd_key(macstrbuf, key); +} + +static void fetch_mac_string_vpd(struct drivers_net_config *config, u8 *macstrbuf) +{ + if (!config) + return; + + /* Current implementation is up to 10 NIC cards */ + if (config->device_index > MAX_DEVICE_SUPPORT) { + 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); + return; + } + + /* check "ethernet_mac" first when the device index is 1 */ + if (config->device_index == 1 && + fetch_mac_vpd_dev_idx(macstrbuf, 0) == CB_SUCCESS) + return; + + if (fetch_mac_vpd_dev_idx(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"); +} + static enum cb_err fetch_mac_string_cbfs(u8 *macstrbuf) { struct cbfsf fh; @@ -186,25 +217,10 @@ static void program_mac_address(struct device *dev, u16 io_base) /* 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; - bool mac_found = false; /* check the VPD for the mac address */ if (CONFIG(RT8168_GET_MAC_FROM_VPD)) { - /* Current implementation is up to 10 NIC cards */ - if (config && config->device_index <= MAX_DEVICE_SUPPORT) { - /* check "ethernet_mac" first when the device index is 1 */ - if (config->device_index == 1 && - fetch_mac_string_vpd(macstrbuf, 0) == CB_SUCCESS) - mac_found = true; - if (!mac_found && 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); - } + fetch_mac_string_vpd(config, macstrbuf); } else { if (fetch_mac_string_cbfs(macstrbuf) != CB_SUCCESS) printk(BIOS_ERR, "r8168: Error reading MAC from CBFS," -- cgit v1.2.3