tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / vendorcode / google / chromeos / vpd_mac.c
blob061997453aff429610df041ee39284302e14d474
1 /*
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>
18 #include <string.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,
29 const char *key_name)
31 int i;
33 for (i = 0; i < sizeof(mac->mac_addr); i++) {
34 int j;
35 uint8_t n = 0;
37 for (j = 0; j < 2; j++) {
38 char c = mac_addr_str[i * 2 + j];
40 if (isxdigit(c)) {
41 if (isdigit(c))
42 c -= '0';
43 else
44 c = tolower(c) - 'a' + 10;
45 } else {
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,
49 mac_addr_str);
50 c = 0;
52 n <<= 4;
53 n |= c;
55 mac->mac_addr[i] = n;
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. */
68 int i, count;
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';
74 count = 0;
75 for (i = 0; i < ARRAY_SIZE(mac_addr_key_bases); i++) {
76 int index_of_index;
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;
82 do {
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)))
89 break;
91 if (!macs) {
92 macs = (struct lb_macs *)lb_new_record(header);
93 macs->tag = LB_TAG_MAC_ADDRS;
96 decode_mac(macs->mac_addrs + count,
97 mac_addr_str,
98 mac_addr_key);
100 count++;
101 mac_addr_key[index_of_index]++;
102 } while (count < 10);
104 if (!count)
105 return; /* No MAC addresses in the VPD. */
107 macs->count = count;
108 macs->size = sizeof(*macs) + count * sizeof(struct mac_address);