diff options
author | Edward O'Callaghan <quasisec@google.com> | 2020-03-25 12:52:50 +1100 |
---|---|---|
committer | Edward O'Callaghan <quasisec@chromium.org> | 2020-03-26 05:30:39 +0000 |
commit | 2a82f744d460afee2218e072a3b8a31a4c6efb11 (patch) | |
tree | 738260e168375128e2f9c742f9b5b25644fc8305 /src/drivers/net | |
parent | 335384d2b75eb0266c6f13b52e20b2d3bba390ea (diff) |
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 <quasisec@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/39811
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/drivers/net')
-rw-r--r-- | src/drivers/net/r8168.c | 84 |
1 files changed, 50 insertions, 34 deletions
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," |