1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <boot/coreboot_tables.h>
4 #include <console/console.h>
8 #include <drivers/vpd/vpd.h>
11 * Decode string representation of the MAC address (a string of 12 hex
12 * symbols) into binary. 'key_name' is the name of the VPD field, it's used if
13 * it is necessary to report an input data format problem.
15 static void decode_mac(struct mac_address
*mac
,
16 const char *mac_addr_str
,
21 for (i
= 0; i
< sizeof(mac
->mac_addr
); i
++) {
25 for (j
= 0; j
< 2; j
++) {
26 char c
= mac_addr_str
[i
* 2 + j
];
32 c
= tolower(c
) - 'a' + 10;
34 printk(BIOS_ERR
, "%s: non hexadecimal symbol "
35 "%#2.2x in the VPD field %s:%s\n",
36 __func__
, (uint8_t)c
, key_name
,
47 void lb_table_add_macs_from_vpd(struct lb_header
*header
)
50 * Mac addresses in the VPD can be stored in two groups, for ethernet
51 * and WiFi, with keys 'ethernet_macX and wifi_macX.
53 const char *mac_addr_key_bases
[] = {"ethernet_mac0", "wifi_mac0"};
54 char mac_addr_key
[20]; /* large enough for either key */
55 char mac_addr_str
[13]; /* 12 symbols and the trailing zero. */
57 struct lb_macs
*macs
= NULL
;
59 /* Make sure the copy is always zero terminated. */
60 mac_addr_key
[sizeof(mac_addr_key
) - 1] = '\0';
63 for (i
= 0; i
< ARRAY_SIZE(mac_addr_key_bases
); i
++) {
66 strncpy(mac_addr_key
, mac_addr_key_bases
[i
],
67 sizeof(mac_addr_key
) - 1);
68 index_of_index
= strlen(mac_addr_key
) - 1;
72 * If there are no more MAC addresses of this template
73 * in the VPD - move on.
75 if (!vpd_gets(mac_addr_key
, mac_addr_str
,
76 sizeof(mac_addr_str
), VPD_RO_THEN_RW
))
80 macs
= (struct lb_macs
*)lb_new_record(header
);
81 macs
->tag
= LB_TAG_MAC_ADDRS
;
84 decode_mac(macs
->mac_addrs
+ count
,
89 mac_addr_key
[index_of_index
]++;
93 return; /* No MAC addresses in the VPD. */
96 macs
->size
= sizeof(*macs
) + count
* sizeof(struct mac_address
);