diff options
Diffstat (limited to 'src/mainboard')
-rw-r--r-- | src/mainboard/siemens/mc_bdx1/Kconfig | 2 | ||||
-rw-r--r-- | src/mainboard/siemens/mc_bdx1/mainboard.c | 77 |
2 files changed, 78 insertions, 1 deletions
diff --git a/src/mainboard/siemens/mc_bdx1/Kconfig b/src/mainboard/siemens/mc_bdx1/Kconfig index e33b14ab30..f947f3d626 100644 --- a/src/mainboard/siemens/mc_bdx1/Kconfig +++ b/src/mainboard/siemens/mc_bdx1/Kconfig @@ -9,6 +9,8 @@ config BOARD_SPECIFIC_OPTIONS select TSC_MONOTONIC_TIMER select HAVE_FSP_BIN if FSP_PACKAGE_DEFAULT select CBFS_AUTOGEN_ATTRIBUTES + select USE_SIEMENS_HWILIB + select DRIVER_INTEL_I210 config MAINBOARD_DIR string diff --git a/src/mainboard/siemens/mc_bdx1/mainboard.c b/src/mainboard/siemens/mc_bdx1/mainboard.c index 58da0361d8..af886a9b5b 100644 --- a/src/mainboard/siemens/mc_bdx1/mainboard.c +++ b/src/mainboard/siemens/mc_bdx1/mainboard.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2011 Google Inc. + * Copyright (C) 2016 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 @@ -17,7 +18,6 @@ #include <types.h> #include <string.h> #include <device/device.h> -#include <device/device.h> #include <device/pci_def.h> #include <device/pci_ops.h> #include <console/console.h> @@ -29,7 +29,11 @@ #include <arch/io.h> #include <arch/interrupt.h> #include <boot/coreboot_tables.h> +#include <hwilib.h> +#include <i210.h> +#define MAX_PATH_DEPTH 12 +#define MAX_NUM_MAPPINGS 10 /* * mainboard_enable is executed as first thing after enumerate_buses(). * This is the earliest point to add customization. @@ -38,6 +42,77 @@ static void mainboard_enable(device_t dev) { } +/** \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; +} struct chip_operations mainboard_ops = { .enable_dev = mainboard_enable, |