Message ID | 20191113035233.1942-3-kai.heng.feng@canonical.com |
---|---|
State | New |
Headers | show |
Series | Support Lenovo Dock MAC passthrough | expand |
On Wed, Nov 13, 2019 at 11:52:33AM +0800, Kai-Heng Feng wrote: > BugLink: https://bugs.launchpad.net/bugs/1827961 > > 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> > (cherry picked from commit 9647722befbedcd6735e00655ffec392c05f0c56 linux-next) As Stefan pointed out already, it's upstream now so we can just drop 'linux-next' from the cherry picked line (SHA1 is the same). Acked-by: Andrea Righi <andrea.righi@canonical.com> > Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> > --- > drivers/net/usb/cdc_ether.c | 7 +++++ > drivers/net/usb/r8152.c | 58 +++++++++++++++++++++++++------------ > 2 files changed, 46 insertions(+), 19 deletions(-) > > diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c > index fe630438f67b..0cdb2ce47645 100644 > --- a/drivers/net/usb/cdc_ether.c > +++ b/drivers/net/usb/cdc_ether.c > @@ -766,6 +766,13 @@ static const struct usb_device_id products[] = { > .driver_info = 0, > }, > > +/* ThinkPad Thunderbolt 3 Dock Gen 2 (based on Realtek RTL8153) */ > +{ > + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3082, USB_CLASS_COMM, > + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), > + .driver_info = 0, > +}, > + > /* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ > { > USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM, > diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c > index d4a95b50bda6..014655ca37f2 100644 > --- a/drivers/net/usb/r8152.c > +++ b/drivers/net/usb/r8152.c > @@ -622,6 +622,7 @@ enum rtl8152_flags { > SCHEDULE_TASKLET, > GREEN_ETHERNET, > DELL_TB_RX_AGG_BUG, > + LENOVO_MACPASSTHRU, > }; > > /* Define these values to match your device */ > @@ -1222,38 +1223,52 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) > int ret = -EINVAL; > u32 ocp_data; > unsigned char buf[6]; > - > - /* test for -AD variant of RTL8153 */ > - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); > - if ((ocp_data & AD_MASK) == 0x1000) { > - /* test for MAC address pass-through bit */ > - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); > - if ((ocp_data & PASS_THRU_MASK) != 1) { > - netif_dbg(tp, probe, tp->netdev, > - "No efuse for RTL8153-AD MAC pass through\n"); > - return -ENODEV; > - } > + char *mac_obj_name; > + acpi_object_type mac_obj_type; > + int mac_strlen; > + > + if (test_bit(LENOVO_MACPASSTHRU, &tp->flags)) { > + mac_obj_name = "\\MACA"; > + mac_obj_type = ACPI_TYPE_STRING; > + mac_strlen = 0x16; > } else { > - /* test for RTL8153-BND and RTL8153-BD */ > - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); > - if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { > - netif_dbg(tp, probe, tp->netdev, > - "Invalid variant for MAC pass through\n"); > - return -ENODEV; > + /* test for -AD variant of RTL8153 */ > + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); > + if ((ocp_data & AD_MASK) == 0x1000) { > + /* test for MAC address pass-through bit */ > + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); > + if ((ocp_data & PASS_THRU_MASK) != 1) { > + netif_dbg(tp, probe, tp->netdev, > + "No efuse for RTL8153-AD MAC pass through\n"); > + return -ENODEV; > + } > + } else { > + /* test for RTL8153-BND and RTL8153-BD */ > + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); > + if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { > + netif_dbg(tp, probe, tp->netdev, > + "Invalid variant for MAC pass through\n"); > + return -ENODEV; > + } > } > + > + mac_obj_name = "\\_SB.AMAC"; > + mac_obj_type = ACPI_TYPE_BUFFER; > + mac_strlen = 0x17; > } > > /* returns _AUXMAC_#AABBCCDDEEFF# */ > - status = acpi_evaluate_object(NULL, "\\_SB.AMAC", NULL, &buffer); > + status = acpi_evaluate_object(NULL, mac_obj_name, NULL, &buffer); > obj = (union acpi_object *)buffer.pointer; > if (!ACPI_SUCCESS(status)) > return -ENODEV; > - if (obj->type != ACPI_TYPE_BUFFER || obj->string.length != 0x17) { > + if (obj->type != mac_obj_type || obj->string.length != mac_strlen) { > netif_warn(tp, probe, tp->netdev, > "Invalid buffer for pass-thru MAC addr: (%d, %d)\n", > obj->type, obj->string.length); > goto amacout; > } > + > if (strncmp(obj->string.pointer, "_AUXMAC_#", 9) != 0 || > strncmp(obj->string.pointer + 0x15, "#", 1) != 0) { > netif_warn(tp, probe, tp->netdev, > @@ -5632,6 +5647,10 @@ static int rtl8152_probe(struct usb_interface *intf, > netdev->hw_features &= ~NETIF_F_RXCSUM; > } > > + if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO && > + le16_to_cpu(udev->descriptor.idProduct) == 0x3082) > + set_bit(LENOVO_MACPASSTHRU, &tp->flags); > + > if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 && udev->serial && > (!strcmp(udev->serial, "000001000000") || !strcmp(udev->serial, "000002000000"))) { > dev_info(&udev->dev, "Dell TB16 Dock, disable RX aggregation"); > @@ -5752,6 +5771,7 @@ static const struct usb_device_id rtl8152_table[] = { > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3062)}, > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3069)}, > + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3082)}, > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, > -- > 2.17.1 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team
On Wed, Nov 13, 2019 at 11:52:33AM +0800, Kai-Heng Feng wrote: > BugLink: https://bugs.launchpad.net/bugs/1827961 > > 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> > (cherry picked from commit 9647722befbedcd6735e00655ffec392c05f0c56 linux-next) > Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> > --- > drivers/net/usb/cdc_ether.c | 7 +++++ > drivers/net/usb/r8152.c | 58 +++++++++++++++++++++++++------------ > 2 files changed, 46 insertions(+), 19 deletions(-) > > diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c > index fe630438f67b..0cdb2ce47645 100644 > --- a/drivers/net/usb/cdc_ether.c > +++ b/drivers/net/usb/cdc_ether.c > @@ -766,6 +766,13 @@ static const struct usb_device_id products[] = { > .driver_info = 0, > }, > > +/* ThinkPad Thunderbolt 3 Dock Gen 2 (based on Realtek RTL8153) */ > +{ > + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3082, USB_CLASS_COMM, > + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), > + .driver_info = 0, > +}, > + > /* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ > { > USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM, > diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c > index d4a95b50bda6..014655ca37f2 100644 > --- a/drivers/net/usb/r8152.c > +++ b/drivers/net/usb/r8152.c > @@ -622,6 +622,7 @@ enum rtl8152_flags { > SCHEDULE_TASKLET, > GREEN_ETHERNET, > DELL_TB_RX_AGG_BUG, > + LENOVO_MACPASSTHRU, > }; > > /* Define these values to match your device */ > @@ -1222,38 +1223,52 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) > int ret = -EINVAL; > u32 ocp_data; > unsigned char buf[6]; > - > - /* test for -AD variant of RTL8153 */ > - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); > - if ((ocp_data & AD_MASK) == 0x1000) { > - /* test for MAC address pass-through bit */ > - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); > - if ((ocp_data & PASS_THRU_MASK) != 1) { > - netif_dbg(tp, probe, tp->netdev, > - "No efuse for RTL8153-AD MAC pass through\n"); > - return -ENODEV; > - } > + char *mac_obj_name; > + acpi_object_type mac_obj_type; > + int mac_strlen; > + > + if (test_bit(LENOVO_MACPASSTHRU, &tp->flags)) { > + mac_obj_name = "\\MACA"; > + mac_obj_type = ACPI_TYPE_STRING; > + mac_strlen = 0x16; > } else { > - /* test for RTL8153-BND and RTL8153-BD */ > - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); > - if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { > - netif_dbg(tp, probe, tp->netdev, > - "Invalid variant for MAC pass through\n"); > - return -ENODEV; > + /* test for -AD variant of RTL8153 */ > + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); > + if ((ocp_data & AD_MASK) == 0x1000) { > + /* test for MAC address pass-through bit */ > + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); > + if ((ocp_data & PASS_THRU_MASK) != 1) { > + netif_dbg(tp, probe, tp->netdev, > + "No efuse for RTL8153-AD MAC pass through\n"); > + return -ENODEV; > + } > + } else { > + /* test for RTL8153-BND and RTL8153-BD */ > + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); > + if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { > + netif_dbg(tp, probe, tp->netdev, > + "Invalid variant for MAC pass through\n"); > + return -ENODEV; > + } > } > + > + mac_obj_name = "\\_SB.AMAC"; > + mac_obj_type = ACPI_TYPE_BUFFER; > + mac_strlen = 0x17; > } > > /* returns _AUXMAC_#AABBCCDDEEFF# */ > - status = acpi_evaluate_object(NULL, "\\_SB.AMAC", NULL, &buffer); > + status = acpi_evaluate_object(NULL, mac_obj_name, NULL, &buffer); > obj = (union acpi_object *)buffer.pointer; > if (!ACPI_SUCCESS(status)) > return -ENODEV; > - if (obj->type != ACPI_TYPE_BUFFER || obj->string.length != 0x17) { > + if (obj->type != mac_obj_type || obj->string.length != mac_strlen) { > netif_warn(tp, probe, tp->netdev, > "Invalid buffer for pass-thru MAC addr: (%d, %d)\n", > obj->type, obj->string.length); > goto amacout; > } > + > if (strncmp(obj->string.pointer, "_AUXMAC_#", 9) != 0 || > strncmp(obj->string.pointer + 0x15, "#", 1) != 0) { > netif_warn(tp, probe, tp->netdev, > @@ -5632,6 +5647,10 @@ static int rtl8152_probe(struct usb_interface *intf, > netdev->hw_features &= ~NETIF_F_RXCSUM; > } > > + if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO && > + le16_to_cpu(udev->descriptor.idProduct) == 0x3082) > + set_bit(LENOVO_MACPASSTHRU, &tp->flags); > + > if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 && udev->serial && > (!strcmp(udev->serial, "000001000000") || !strcmp(udev->serial, "000002000000"))) { > dev_info(&udev->dev, "Dell TB16 Dock, disable RX aggregation"); > @@ -5752,6 +5771,7 @@ static const struct usb_device_id rtl8152_table[] = { > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3062)}, > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3069)}, > + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3082)}, > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, > {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, > -- > 2.17.1 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index fe630438f67b..0cdb2ce47645 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -766,6 +766,13 @@ static const struct usb_device_id products[] = { .driver_info = 0, }, +/* ThinkPad Thunderbolt 3 Dock Gen 2 (based on Realtek RTL8153) */ +{ + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3082, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + /* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ { USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM, diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index d4a95b50bda6..014655ca37f2 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -622,6 +622,7 @@ enum rtl8152_flags { SCHEDULE_TASKLET, GREEN_ETHERNET, DELL_TB_RX_AGG_BUG, + LENOVO_MACPASSTHRU, }; /* Define these values to match your device */ @@ -1222,38 +1223,52 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) int ret = -EINVAL; u32 ocp_data; unsigned char buf[6]; - - /* test for -AD variant of RTL8153 */ - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); - if ((ocp_data & AD_MASK) == 0x1000) { - /* test for MAC address pass-through bit */ - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); - if ((ocp_data & PASS_THRU_MASK) != 1) { - netif_dbg(tp, probe, tp->netdev, - "No efuse for RTL8153-AD MAC pass through\n"); - return -ENODEV; - } + char *mac_obj_name; + acpi_object_type mac_obj_type; + int mac_strlen; + + if (test_bit(LENOVO_MACPASSTHRU, &tp->flags)) { + mac_obj_name = "\\MACA"; + mac_obj_type = ACPI_TYPE_STRING; + mac_strlen = 0x16; } else { - /* test for RTL8153-BND and RTL8153-BD */ - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); - if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { - netif_dbg(tp, probe, tp->netdev, - "Invalid variant for MAC pass through\n"); - return -ENODEV; + /* test for -AD variant of RTL8153 */ + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); + if ((ocp_data & AD_MASK) == 0x1000) { + /* test for MAC address pass-through bit */ + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); + if ((ocp_data & PASS_THRU_MASK) != 1) { + netif_dbg(tp, probe, tp->netdev, + "No efuse for RTL8153-AD MAC pass through\n"); + return -ENODEV; + } + } else { + /* test for RTL8153-BND and RTL8153-BD */ + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); + if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { + netif_dbg(tp, probe, tp->netdev, + "Invalid variant for MAC pass through\n"); + return -ENODEV; + } } + + mac_obj_name = "\\_SB.AMAC"; + mac_obj_type = ACPI_TYPE_BUFFER; + mac_strlen = 0x17; } /* returns _AUXMAC_#AABBCCDDEEFF# */ - status = acpi_evaluate_object(NULL, "\\_SB.AMAC", NULL, &buffer); + status = acpi_evaluate_object(NULL, mac_obj_name, NULL, &buffer); obj = (union acpi_object *)buffer.pointer; if (!ACPI_SUCCESS(status)) return -ENODEV; - if (obj->type != ACPI_TYPE_BUFFER || obj->string.length != 0x17) { + if (obj->type != mac_obj_type || obj->string.length != mac_strlen) { netif_warn(tp, probe, tp->netdev, "Invalid buffer for pass-thru MAC addr: (%d, %d)\n", obj->type, obj->string.length); goto amacout; } + if (strncmp(obj->string.pointer, "_AUXMAC_#", 9) != 0 || strncmp(obj->string.pointer + 0x15, "#", 1) != 0) { netif_warn(tp, probe, tp->netdev, @@ -5632,6 +5647,10 @@ static int rtl8152_probe(struct usb_interface *intf, netdev->hw_features &= ~NETIF_F_RXCSUM; } + if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO && + le16_to_cpu(udev->descriptor.idProduct) == 0x3082) + set_bit(LENOVO_MACPASSTHRU, &tp->flags); + if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 && udev->serial && (!strcmp(udev->serial, "000001000000") || !strcmp(udev->serial, "000002000000"))) { dev_info(&udev->dev, "Dell TB16 Dock, disable RX aggregation"); @@ -5752,6 +5771,7 @@ static const struct usb_device_id rtl8152_table[] = { {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3062)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3069)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3082)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)},