Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

r8152: Add macpassthru support for ThinkPad Thunderbolt 3 Dock Gen 2

ThinkPad Thunderbolt 3 Dock Gen 2 is another docking station that uses
RTL8153 based USB ethernet.

The device supports macpassthru, but it failed to pass the test of -AD,
-BND and -BD. Simply bypass these tests since the device supports this
feature just fine.

Also the ACPI objects have some differences between Dell's and Lenovo's,
so make those ACPI infos no longer hardcoded.

BugLink: https://bugs.launchpad.net/bugs/1827961
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Acked-by: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Kai-Heng Feng and committed by
David S. Miller
9647722b 86e8f298

+45 -18
+7
drivers/net/usb/cdc_ether.c
··· 766 766 .driver_info = 0, 767 767 }, 768 768 769 + /* ThinkPad Thunderbolt 3 Dock Gen 2 (based on Realtek RTL8153) */ 770 + { 771 + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3082, USB_CLASS_COMM, 772 + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), 773 + .driver_info = 0, 774 + }, 775 + 769 776 /* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ 770 777 { 771 778 USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM,
+38 -18
drivers/net/usb/r8152.c
··· 670 670 SCHEDULE_TASKLET, 671 671 GREEN_ETHERNET, 672 672 DELL_TB_RX_AGG_BUG, 673 + LENOVO_MACPASSTHRU, 673 674 }; 674 675 675 676 /* Define these values to match your device */ ··· 1409 1408 int ret = -EINVAL; 1410 1409 u32 ocp_data; 1411 1410 unsigned char buf[6]; 1411 + char *mac_obj_name; 1412 + acpi_object_type mac_obj_type; 1413 + int mac_strlen; 1412 1414 1413 - /* test for -AD variant of RTL8153 */ 1414 - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); 1415 - if ((ocp_data & AD_MASK) == 0x1000) { 1416 - /* test for MAC address pass-through bit */ 1417 - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); 1418 - if ((ocp_data & PASS_THRU_MASK) != 1) { 1419 - netif_dbg(tp, probe, tp->netdev, 1420 - "No efuse for RTL8153-AD MAC pass through\n"); 1421 - return -ENODEV; 1422 - } 1415 + if (test_bit(LENOVO_MACPASSTHRU, &tp->flags)) { 1416 + mac_obj_name = "\\MACA"; 1417 + mac_obj_type = ACPI_TYPE_STRING; 1418 + mac_strlen = 0x16; 1423 1419 } else { 1424 - /* test for RTL8153-BND and RTL8153-BD */ 1425 - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); 1426 - if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { 1427 - netif_dbg(tp, probe, tp->netdev, 1428 - "Invalid variant for MAC pass through\n"); 1429 - return -ENODEV; 1420 + /* test for -AD variant of RTL8153 */ 1421 + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); 1422 + if ((ocp_data & AD_MASK) == 0x1000) { 1423 + /* test for MAC address pass-through bit */ 1424 + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); 1425 + if ((ocp_data & PASS_THRU_MASK) != 1) { 1426 + netif_dbg(tp, probe, tp->netdev, 1427 + "No efuse for RTL8153-AD MAC pass through\n"); 1428 + return -ENODEV; 1429 + } 1430 + } else { 1431 + /* test for RTL8153-BND and RTL8153-BD */ 1432 + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); 1433 + if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { 1434 + netif_dbg(tp, probe, tp->netdev, 1435 + "Invalid variant for MAC pass through\n"); 1436 + return -ENODEV; 1437 + } 1430 1438 } 1439 + 1440 + mac_obj_name = "\\_SB.AMAC"; 1441 + mac_obj_type = ACPI_TYPE_BUFFER; 1442 + mac_strlen = 0x17; 1431 1443 } 1432 1444 1433 1445 /* returns _AUXMAC_#AABBCCDDEEFF# */ 1434 - status = acpi_evaluate_object(NULL, "\\_SB.AMAC", NULL, &buffer); 1446 + status = acpi_evaluate_object(NULL, mac_obj_name, NULL, &buffer); 1435 1447 obj = (union acpi_object *)buffer.pointer; 1436 1448 if (!ACPI_SUCCESS(status)) 1437 1449 return -ENODEV; 1438 - if (obj->type != ACPI_TYPE_BUFFER || obj->string.length != 0x17) { 1450 + if (obj->type != mac_obj_type || obj->string.length != mac_strlen) { 1439 1451 netif_warn(tp, probe, tp->netdev, 1440 1452 "Invalid buffer for pass-thru MAC addr: (%d, %d)\n", 1441 1453 obj->type, obj->string.length); 1442 1454 goto amacout; 1443 1455 } 1456 + 1444 1457 if (strncmp(obj->string.pointer, "_AUXMAC_#", 9) != 0 || 1445 1458 strncmp(obj->string.pointer + 0x15, "#", 1) != 0) { 1446 1459 netif_warn(tp, probe, tp->netdev, ··· 6644 6629 netdev->hw_features &= ~NETIF_F_RXCSUM; 6645 6630 } 6646 6631 6632 + if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO && 6633 + le16_to_cpu(udev->descriptor.idProduct) == 0x3082) 6634 + set_bit(LENOVO_MACPASSTHRU, &tp->flags); 6635 + 6647 6636 if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 && udev->serial && 6648 6637 (!strcmp(udev->serial, "000001000000") || 6649 6638 !strcmp(udev->serial, "000002000000"))) { ··· 6774 6755 {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, 6775 6756 {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3062)}, 6776 6757 {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3069)}, 6758 + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3082)}, 6777 6759 {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, 6778 6760 {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, 6779 6761 {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)},