diff options
-rw-r--r-- | src/mainboard/siemens/mc_apl1/Kconfig | 2 | ||||
-rw-r--r-- | src/mainboard/siemens/mc_apl1/mainboard.c | 83 |
2 files changed, 85 insertions, 0 deletions
diff --git a/src/mainboard/siemens/mc_apl1/Kconfig b/src/mainboard/siemens/mc_apl1/Kconfig index 6201ed3664..ef9d0216ca 100644 --- a/src/mainboard/siemens/mc_apl1/Kconfig +++ b/src/mainboard/siemens/mc_apl1/Kconfig @@ -5,6 +5,8 @@ config BOARD_SPECIFIC_OPTIONS select SOC_INTEL_APOLLOLAKE select BOARD_ROMSIZE_KB_16384 select HAVE_ACPI_TABLES + select DRIVER_INTEL_I210 + select USE_SIEMENS_HWILIB config MAINBOARD_DIR string diff --git a/src/mainboard/siemens/mc_apl1/mainboard.c b/src/mainboard/siemens/mc_apl1/mainboard.c index f7a2ef1c99..1c2dd19c61 100644 --- a/src/mainboard/siemens/mc_apl1/mainboard.c +++ b/src/mainboard/siemens/mc_apl1/mainboard.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright 2016 Google Inc. + * Copyright (C) 2017 Siemens AG * * 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 @@ -14,6 +15,88 @@ */ #include <device/device.h> +#include <console/console.h> +#include <string.h> +#include <hwilib.h> +#include <i210.h> + +#define MAX_PATH_DEPTH 12 +#define MAX_NUM_MAPPINGS 10 + +/** \brief This function can decide if a given MAC address is valid or not. + * Currently, addresses filled with 0xff or 0x00 are not valid. + * @param mac Buffer to the MAC address to check + * @return 0 if address is not valid, otherwise 1 + */ +static uint8_t is_mac_adr_valid(uint8_t mac[6]) +{ + uint8_t buf[6]; + + memset(buf, 0, sizeof(buf)); + if (!memcmp(buf, mac, sizeof(buf))) + return 0; + memset(buf, 0xff, sizeof(buf)); + if (!memcmp(buf, mac, sizeof(buf))) + return 0; + return 1; +} + +/** \brief This function will search for a MAC address which can be assigned + * to a MACPHY. + * @param dev pointer to PCI device + * @param mac buffer where to store the MAC address + * @return cb_err CB_ERR or CB_SUCCESS + */ +enum cb_err mainboard_get_mac_address(struct device *dev, uint8_t mac[6]) +{ + struct bus *parent = dev->bus; + uint8_t buf[16], mapping[16], i = 0, chain_len = 0; + + memset(buf, 0, sizeof(buf)); + memset(mapping, 0, sizeof(mapping)); + + /* The first entry in the tree is the device itself. */ + buf[0] = dev->path.pci.devfn; + chain_len = 1; + for (i = 1; i < MAX_PATH_DEPTH && parent->dev->bus->subordinate; i++) { + buf[i] = parent->dev->path.pci.devfn; + chain_len++; + parent = parent->dev->bus; + } + if (i == MAX_PATH_DEPTH) { + /* The path is deeper than MAX_PATH_DEPTH devices, error. */ + printk(BIOS_ERR, "Too many bridges for %s\n", dev_path(dev)); + return CB_ERR; + } + /* + * Now construct the mapping based on the device chain starting from + * root bridge device to the device itself. + */ + mapping[0] = 1; + mapping[1] = chain_len; + for (i = 0; i < chain_len; i++) + mapping[i + 4] = buf[chain_len - i - 1]; + + /* Open main hwinfo block */ + if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS) + return CB_ERR; + /* Now try to find a valid MAC address in hwinfo for this mapping.*/ + for (i = 0; i < MAX_NUM_MAPPINGS; i++) { + if ((hwilib_get_field(XMac1Mapping + i, buf, 16) == 16) && + !(memcmp(buf, mapping, chain_len + 4))) { + /* There is a matching mapping available, get MAC address. */ + if ((hwilib_get_field(XMac1 + i, mac, 6) == 6) && + (is_mac_adr_valid(mac))) { + return CB_SUCCESS; + } else { + return CB_ERR; + } + } else + continue; + } + /* No MAC address found for */ + return CB_ERR; +} static void mainboard_init(void *chip_info) { |