blob: 5a091ddfaac23d0705797a65d80fbb41698462d2 [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
Simon Glassaa215742019-05-16 14:51:51 -060019 * dock pass-through feature which can result in the dock ethernet port
20 * using the same MAC address that is assigned to the internal NIC. This
21 * is done by calling an ACPI method at \_SB.AMAC() which returns a
22 * formatted string (as a buffer) containing the MAC address for the
23 * dock to use.
Duncan Laurie57d5e472019-03-01 15:40:48 +080024 *
25 * The Linux kernel implementation can be found at
26 * drivers/net/usb/r8152.c:vendor_mac_passthru_addr_read()
27 *
28 * For Chrome OS, the policy which controls where the dock MAC address
Simon Glassaa215742019-05-16 14:51:51 -060029 * comes from is written into RW_VPD property "dock_passthrough":
Duncan Laurie57d5e472019-03-01 15:40:48 +080030 *
31 * "dock_mac" or empty: Use MAC address from RO_VPD value "dock_mac"
32 * "ethernet_mac0": Use MAC address from RO_VPD value "ethernet_mac0"
33 * "builtin": existing dock MAC address (return nothing)
34 */
35
36Scope (\_SB)
37{
38 Method (AMAC, 0, Serialized)
39 {
40 /* Format expected by the Linux kernel r8152 driver */
41 Name (MACA, "_AUXMAC_#XXXXXXXXXXXX#")
42
Simon Glassaa215742019-05-16 14:51:51 -060043 /* Get "dock_passthrough" value from RW_VPD */
44 Local0 = \VPD.VPDF ("RW", "dock_passthrough")
Duncan Laurie57d5e472019-03-01 15:40:48 +080045
Duncan Laurie643daed2019-05-08 15:09:29 -060046 Local1 = Zero
Duncan Laurie57d5e472019-03-01 15:40:48 +080047 Switch (ToString (Local0))
48 {
49 Case ("ethernet_mac0") {
50 Local1 = \VPD.VPDF ("RO", "ethernet_mac0")
51 }
52 Case ("builtin") {
53 Return (Zero)
54 }
55 /* "dock_mac" or policy not found. */
56 Default {
57 Local1 = \VPD.VPDF ("RO", "dock_mac")
58 }
59 }
Duncan Laurie643daed2019-05-08 15:09:29 -060060 If (Local1 == Zero) {
Duncan Laurie57d5e472019-03-01 15:40:48 +080061 Return (Zero)
62 }
63 Printf ("MAC address returned from VPD: %o", Local1)
64
65 /* Verify MAC address format is AA:BB:CC:DD:EE:FF */
66 For (Local3 = 2, Local3 < 17, Local3 += 3) {
67 If (ToString (DerefOf (Local1[Local3])) != ":") {
68 Printf ("Invalid MAC address byte %o", Local3)
69 Return (Zero)
70 }
71 }
72
73 /* Convert MAC address into format specified by MACA */
74 Local2 = ToBuffer (MACA)
75 Local4 = 0 /* First MAC address byte in input buffer */
76 Local5 = 9 /* First MAC address byte in output buffer */
77 For (Local3 = 0, Local3 < 6, Local3++) {
78 Local2[Local5] = DerefOf (Local1[Local4])
79 Local2[Local5 + 1] = DerefOf (Local1[Local4 + 1])
80 Local5 += 2
81 Local4 += 3 /* Skip ":" in address from VPD */
82 }
83
84 Printf ("AMAC = %o", ToString (Local2))
Duncan Laurie8d8cead2019-03-07 22:24:43 +080085 Return (Local2)
Duncan Laurie57d5e472019-03-01 15:40:48 +080086 }
87}