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>
This commit is contained in:
parent
335384d2b7
commit
2a82f744d4
|
@ -92,12 +92,49 @@ static u8 get_hex_digit(const u8 c)
|
||||||
|
|
||||||
#define MACLEN 17
|
#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;
|
struct region_device rdev;
|
||||||
void *search_address;
|
void *search_address;
|
||||||
size_t search_length;
|
size_t search_length;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
|
||||||
|
if (fmap_locate_area_as_rdev("RO_VPD", &rdev)) {
|
||||||
|
printk(BIOS_ERR, "Error: Couldn't find RO_VPD region.");
|
||||||
|
return CB_ERR;
|
||||||
|
}
|
||||||
|
search_address = rdev_mmap_full(&rdev);
|
||||||
|
if (search_address == NULL) {
|
||||||
|
printk(BIOS_ERR, "LAN: VPD not found.\n");
|
||||||
|
return CB_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
search_length = region_device_sz(&rdev);
|
||||||
|
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", vpd_key);
|
||||||
|
return CB_ERR;
|
||||||
|
}
|
||||||
|
printk(BIOS_DEBUG, "Located '%s' in VPD\n", vpd_key);
|
||||||
|
|
||||||
|
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 */
|
char key[] = "ethernet_mac "; /* Leave a space at tail to stuff an index */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -112,35 +149,29 @@ static enum cb_err fetch_mac_string_vpd(u8 *macstrbuf, const u8 device_index)
|
||||||
/* Translate index number from integer to ascii */
|
/* Translate index number from integer to ascii */
|
||||||
key[DEVICE_INDEX_BYTE] = (device_index - 1) + '0';
|
key[DEVICE_INDEX_BYTE] = (device_index - 1) + '0';
|
||||||
|
|
||||||
if (fmap_locate_area_as_rdev("RO_VPD", &rdev)) {
|
return fetch_mac_vpd_key(macstrbuf, key);
|
||||||
printk(BIOS_ERR, "Error: Couldn't find RO_VPD region.");
|
|
||||||
return CB_ERR;
|
|
||||||
}
|
|
||||||
search_address = rdev_mmap_full(&rdev);
|
|
||||||
if (search_address == NULL) {
|
|
||||||
printk(BIOS_ERR, "LAN: VPD not found.\n");
|
|
||||||
return CB_ERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
search_length = region_device_sz(&rdev);
|
static void fetch_mac_string_vpd(struct drivers_net_config *config, u8 *macstrbuf)
|
||||||
offset = search(key, search_address, strlen(key),
|
{
|
||||||
search_length);
|
if (!config)
|
||||||
|
return;
|
||||||
|
|
||||||
if (offset == search_length) {
|
/* Current implementation is up to 10 NIC cards */
|
||||||
printk(BIOS_ERR,
|
if (config->device_index > MAX_DEVICE_SUPPORT) {
|
||||||
"Error: Could not locate '%s' in VPD\n", key);
|
printk(BIOS_ERR, "r8168: the maximum device_index should be less then %d\n."
|
||||||
return CB_ERR;
|
" Using default 00:e0:4c:00:c0:b0\n", MAX_DEVICE_SUPPORT);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
printk(BIOS_DEBUG, "Located '%s' in VPD\n", key);
|
|
||||||
|
|
||||||
offset += strlen(key) + 1; /* move to next character */
|
/* 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 (offset + MACLEN > search_length) {
|
if (fetch_mac_vpd_dev_idx(macstrbuf, config->device_index) != CB_SUCCESS)
|
||||||
printk(BIOS_ERR, "Search result too small!\n");
|
printk(BIOS_ERR, "r8168: mac address not found in VPD,"
|
||||||
return CB_ERR;
|
" using default 00:e0:4c:00:c0:b0\n");
|
||||||
}
|
|
||||||
memcpy(macstrbuf, search_address + offset, MACLEN);
|
|
||||||
return CB_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum cb_err fetch_mac_string_cbfs(u8 *macstrbuf)
|
static enum cb_err fetch_mac_string_cbfs(u8 *macstrbuf)
|
||||||
|
@ -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 */
|
/* Default MAC Address of 00:E0:4C:00:C0:B0 */
|
||||||
u8 mac[6] = { 0x00, 0xe0, 0x4c, 0x00, 0xc0, 0xb0 };
|
u8 mac[6] = { 0x00, 0xe0, 0x4c, 0x00, 0xc0, 0xb0 };
|
||||||
struct drivers_net_config *config = dev->chip_info;
|
struct drivers_net_config *config = dev->chip_info;
|
||||||
bool mac_found = false;
|
|
||||||
|
|
||||||
/* check the VPD for the mac address */
|
/* check the VPD for the mac address */
|
||||||
if (CONFIG(RT8168_GET_MAC_FROM_VPD)) {
|
if (CONFIG(RT8168_GET_MAC_FROM_VPD)) {
|
||||||
/* Current implementation is up to 10 NIC cards */
|
fetch_mac_string_vpd(config, macstrbuf);
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (fetch_mac_string_cbfs(macstrbuf) != CB_SUCCESS)
|
if (fetch_mac_string_cbfs(macstrbuf) != CB_SUCCESS)
|
||||||
printk(BIOS_ERR, "r8168: Error reading MAC from CBFS,"
|
printk(BIOS_ERR, "r8168: Error reading MAC from CBFS,"
|
||||||
|
|
Loading…
Reference in New Issue