2 * This file is part of the coreboot project.
4 * Copyright 2014 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <boot/coreboot_tables.h>
17 #include <console/console.h>
20 #include <vendorcode/google/chromeos/cros_vpd.h>
23 * Decode string representation of the MAC address (a string of 12 hex
24 * symbols) into binary. 'key_name' is the name of the VPD field, it's used if
25 * it is necessary to report an input data format problem.
27 static void decode_mac(struct mac_address
*mac
,
28 const char *mac_addr_str
,
33 for (i
= 0; i
< sizeof(mac
->mac_addr
); i
++) {
37 for (j
= 0; j
< 2; j
++) {
38 char c
= mac_addr_str
[i
* 2 + j
];
44 c
= tolower(c
) - 'a' + 10;
46 printk(BIOS_ERR
, "%s: non hexadecimal symbol "
47 "%#2.2x in the VPD field %s:%s\n",
48 __func__
, (uint8_t)c
, key_name
,
59 void lb_table_add_macs_from_vpd(struct lb_header
*header
)
62 * Mac addresses in the VPD can be stored in two groups, for ethernet
63 * and WiFi, with keys 'ethernet_macX and wifi_macX.
65 const char *mac_addr_key_bases
[] = {"ethernet_mac0", "wifi_mac0"};
66 char mac_addr_key
[20]; /* large enough for either key */
67 char mac_addr_str
[13]; /* 12 symbols and the trailing zero. */
69 struct lb_macs
*macs
= NULL
;
71 /* Make sure the copy is always zero terminated. */
72 mac_addr_key
[sizeof(mac_addr_key
) - 1] = '\0';
75 for (i
= 0; i
< ARRAY_SIZE(mac_addr_key_bases
); i
++) {
78 strncpy(mac_addr_key
, mac_addr_key_bases
[i
],
79 sizeof(mac_addr_key
) - 1);
80 index_of_index
= strlen(mac_addr_key
) - 1;
84 * If there are no more MAC addresses of this template
85 * in the VPD - move on.
87 if (!cros_vpd_gets(mac_addr_key
, mac_addr_str
,
88 sizeof(mac_addr_str
)))
92 macs
= (struct lb_macs
*)lb_new_record(header
);
93 macs
->tag
= LB_TAG_MAC_ADDRS
;
96 decode_mac(macs
->mac_addrs
+ count
,
101 mac_addr_key
[index_of_index
]++;
102 } while (count
< 10);
105 return; /* No MAC addresses in the VPD. */
108 macs
->size
= sizeof(*macs
) + count
* sizeof(struct mac_address
);