blob: 838506abcb953f85213805f53d524db0f6810a4b [file] [log] [blame]
Duncan Laurie57d5e472019-03-01 15:40:48 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2019 Google LLC
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * 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/*
18 * The Realtek r8152 driver in the Linux kernel supports a MAC address
19 * passthru feature which can result in the dock ethernet port using the
20 * same MAC address that is assigned to the internal NIC. This is done
21 * by calling an ACPI method at \_SB.AMAC() which returns a formatted
22 * string containing the MAC address for the dock to use.
23 *
24 * The Linux kernel implementation can be found at
25 * drivers/net/usb/r8152.c:vendor_mac_passthru_addr_read()
26 *
27 * For Chrome OS, the policy which controls where the dock MAC address
28 * comes from is written into RW_VPD property "dock_passthru":
29 *
30 * "dock_mac" or empty: Use MAC address from RO_VPD value "dock_mac"
31 * "ethernet_mac0": Use MAC address from RO_VPD value "ethernet_mac0"
32 * "builtin": existing dock MAC address (return nothing)
33 */
34
35Scope (\_SB)
36{
37 Method (AMAC, 0, Serialized)
38 {
39 /* Format expected by the Linux kernel r8152 driver */
40 Name (MACA, "_AUXMAC_#XXXXXXXXXXXX#")
41
42 /* Get "dock_passthru" value from RW_VPD */
43 Local0 = \VPD.VPDF ("RW", "dock_passthru")
44
45 Switch (ToString (Local0))
46 {
47 Case ("ethernet_mac0") {
48 Local1 = \VPD.VPDF ("RO", "ethernet_mac0")
49 }
50 Case ("builtin") {
51 Return (Zero)
52 }
53 /* "dock_mac" or policy not found. */
54 Default {
55 Local1 = \VPD.VPDF ("RO", "dock_mac")
56 }
57 }
58 If (!Local1) {
59 Return (Zero)
60 }
61 Printf ("MAC address returned from VPD: %o", Local1)
62
63 /* Verify MAC address format is AA:BB:CC:DD:EE:FF */
64 For (Local3 = 2, Local3 < 17, Local3 += 3) {
65 If (ToString (DerefOf (Local1[Local3])) != ":") {
66 Printf ("Invalid MAC address byte %o", Local3)
67 Return (Zero)
68 }
69 }
70
71 /* Convert MAC address into format specified by MACA */
72 Local2 = ToBuffer (MACA)
73 Local4 = 0 /* First MAC address byte in input buffer */
74 Local5 = 9 /* First MAC address byte in output buffer */
75 For (Local3 = 0, Local3 < 6, Local3++) {
76 Local2[Local5] = DerefOf (Local1[Local4])
77 Local2[Local5 + 1] = DerefOf (Local1[Local4 + 1])
78 Local5 += 2
79 Local4 += 3 /* Skip ":" in address from VPD */
80 }
81
82 Printf ("AMAC = %o", ToString (Local2))
83 Return (ToString (Local2))
84 }
85}