blob: 1c2dd19c61a9654ef348cac2a0eeacaa80e8d63e [file] [log] [blame]
Mario Scheithauer092db952017-01-31 15:45:13 +01001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2016 Google Inc.
Mario Scheithauer480eab02017-02-16 13:39:16 +01005 * Copyright (C) 2017 Siemens AG
Mario Scheithauer092db952017-01-31 15:45:13 +01006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <device/device.h>
Mario Scheithauer480eab02017-02-16 13:39:16 +010018#include <console/console.h>
19#include <string.h>
20#include <hwilib.h>
21#include <i210.h>
22
23#define MAX_PATH_DEPTH 12
24#define MAX_NUM_MAPPINGS 10
25
26/** \brief This function can decide if a given MAC address is valid or not.
27 * Currently, addresses filled with 0xff or 0x00 are not valid.
28 * @param mac Buffer to the MAC address to check
29 * @return 0 if address is not valid, otherwise 1
30 */
31static uint8_t is_mac_adr_valid(uint8_t mac[6])
32{
33 uint8_t buf[6];
34
35 memset(buf, 0, sizeof(buf));
36 if (!memcmp(buf, mac, sizeof(buf)))
37 return 0;
38 memset(buf, 0xff, sizeof(buf));
39 if (!memcmp(buf, mac, sizeof(buf)))
40 return 0;
41 return 1;
42}
43
44/** \brief This function will search for a MAC address which can be assigned
45 * to a MACPHY.
46 * @param dev pointer to PCI device
47 * @param mac buffer where to store the MAC address
48 * @return cb_err CB_ERR or CB_SUCCESS
49 */
50enum cb_err mainboard_get_mac_address(struct device *dev, uint8_t mac[6])
51{
52 struct bus *parent = dev->bus;
53 uint8_t buf[16], mapping[16], i = 0, chain_len = 0;
54
55 memset(buf, 0, sizeof(buf));
56 memset(mapping, 0, sizeof(mapping));
57
58 /* The first entry in the tree is the device itself. */
59 buf[0] = dev->path.pci.devfn;
60 chain_len = 1;
61 for (i = 1; i < MAX_PATH_DEPTH && parent->dev->bus->subordinate; i++) {
62 buf[i] = parent->dev->path.pci.devfn;
63 chain_len++;
64 parent = parent->dev->bus;
65 }
66 if (i == MAX_PATH_DEPTH) {
67 /* The path is deeper than MAX_PATH_DEPTH devices, error. */
68 printk(BIOS_ERR, "Too many bridges for %s\n", dev_path(dev));
69 return CB_ERR;
70 }
71 /*
72 * Now construct the mapping based on the device chain starting from
73 * root bridge device to the device itself.
74 */
75 mapping[0] = 1;
76 mapping[1] = chain_len;
77 for (i = 0; i < chain_len; i++)
78 mapping[i + 4] = buf[chain_len - i - 1];
79
80 /* Open main hwinfo block */
81 if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
82 return CB_ERR;
83 /* Now try to find a valid MAC address in hwinfo for this mapping.*/
84 for (i = 0; i < MAX_NUM_MAPPINGS; i++) {
85 if ((hwilib_get_field(XMac1Mapping + i, buf, 16) == 16) &&
86 !(memcmp(buf, mapping, chain_len + 4))) {
87 /* There is a matching mapping available, get MAC address. */
88 if ((hwilib_get_field(XMac1 + i, mac, 6) == 6) &&
89 (is_mac_adr_valid(mac))) {
90 return CB_SUCCESS;
91 } else {
92 return CB_ERR;
93 }
94 } else
95 continue;
96 }
97 /* No MAC address found for */
98 return CB_ERR;
99}
Mario Scheithauer092db952017-01-31 15:45:13 +0100100
101static void mainboard_init(void *chip_info)
102{
103 /* Nothing Here Yet */
104}
105
106struct chip_operations mainboard_ops = {
107 .init = mainboard_init,
108};