From patchwork Tue Mar 23 14:56:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 12158229 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B58E0C433E3 for ; Tue, 23 Mar 2021 14:57:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9814B619B8 for ; Tue, 23 Mar 2021 14:57:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232528AbhCWO5N (ORCPT ); Tue, 23 Mar 2021 10:57:13 -0400 Received: from mga01.intel.com ([192.55.52.88]:15373 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232476AbhCWO4x (ORCPT ); Tue, 23 Mar 2021 10:56:53 -0400 IronPort-SDR: Sea0LBThTt1TLRhwo2U5uYPTe4pUGh+aTSwt4x8WjgMvp3tDEHSMFUVlzII760Ou4h6rWRODXh dSMqvySiLIuw== X-IronPort-AV: E=McAfee;i="6000,8403,9931"; a="210571190" X-IronPort-AV: E=Sophos;i="5.81,271,1610438400"; d="scan'208";a="210571190" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Mar 2021 07:56:52 -0700 IronPort-SDR: wf87nNv+7zXymM9tphKAgmfkxh83tbmLis5NJ1RBWJOKhTCRQ49MZwGJxoLKN9mAD1FC+Z/uIM mMc8x0PMKEbg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,271,1610438400"; d="scan'208";a="390910870" Received: from black.fi.intel.com ([10.237.72.28]) by orsmga002.jf.intel.com with ESMTP; 23 Mar 2021 07:56:48 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id C52F353E; Tue, 23 Mar 2021 16:57:01 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Michael Jamet , Yehezkel Bernat , Andreas Noever , Lukas Wunner , Mario Limonciello , Christian Kellner , Benson Leung , Prashant Malani , Diego Rivas , Greg Kroah-Hartman , Mika Westerberg Subject: [PATCH v2 1/3] thunderbolt: Add details to router uevent Date: Tue, 23 Mar 2021 17:56:59 +0300 Message-Id: <20210323145701.86161-2-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210323145701.86161-1-mika.westerberg@linux.intel.com> References: <20210323145701.86161-1-mika.westerberg@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Expose two environment variables for routers as part of the initial uevent: USB4_VERSION=1.0 USB4_TYPE=host|device|hub Userspace can use this information to expose more details about each connected device. Only USB4 devices have USB4_VERSION but all devices have USB4_TYPE. Signed-off-by: Mika Westerberg Reviewed-by: Greg Kroah-Hartman --- drivers/thunderbolt/switch.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 321a5bcfce65..a1b4a695080e 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -1835,6 +1835,39 @@ static void tb_switch_release(struct device *dev) kfree(sw); } +static int tb_switch_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct tb_switch *sw = tb_to_switch(dev); + const char *type; + + if (sw->config.thunderbolt_version == USB4_VERSION_1_0) { + if (add_uevent_var(env, "USB4_VERSION=1.0")) + return -ENOMEM; + } + + if (!tb_route(sw)) { + type = "host"; + } else { + const struct tb_port *port; + bool hub = false; + + /* Device is hub if it has any downstream ports */ + tb_switch_for_each_port(sw, port) { + if (!port->disabled && !tb_is_upstream_port(port) && + tb_port_is_null(port)) { + hub = true; + break; + } + } + + type = hub ? "hub" : "device"; + } + + if (add_uevent_var(env, "USB4_TYPE=%s", type)) + return -ENOMEM; + return 0; +} + /* * Currently only need to provide the callbacks. Everything else is handled * in the connection manager. @@ -1868,6 +1901,7 @@ static const struct dev_pm_ops tb_switch_pm_ops = { struct device_type tb_switch_type = { .name = "thunderbolt_device", .release = tb_switch_release, + .uevent = tb_switch_uevent, .pm = &tb_switch_pm_ops, }; From patchwork Tue Mar 23 14:57:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 12158227 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CEE4C433DB for ; Tue, 23 Mar 2021 14:57:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5027F619B7 for ; Tue, 23 Mar 2021 14:57:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232477AbhCWO5O (ORCPT ); Tue, 23 Mar 2021 10:57:14 -0400 Received: from mga05.intel.com ([192.55.52.43]:26356 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232475AbhCWO4x (ORCPT ); Tue, 23 Mar 2021 10:56:53 -0400 IronPort-SDR: Voq3aBB2GN9jaaJlPAzLs0Kx7KmNaGljBJMAMZQZ1/kEucNxUtpCWjPULhicaYN1WeNrYmpgua xJ0px7UIp+Rw== X-IronPort-AV: E=McAfee;i="6000,8403,9931"; a="275592054" X-IronPort-AV: E=Sophos;i="5.81,271,1610438400"; d="scan'208";a="275592054" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Mar 2021 07:56:52 -0700 IronPort-SDR: ZUGaN4BzgLwwYndyuX8Pz5KdTmFUiXgM/jUmDsEqmgyojXjXsI/H+WfCCaQmeXLciGmMcct5Mu 7ElJywZgwmRw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,271,1610438400"; d="scan'208";a="435584482" Received: from black.fi.intel.com ([10.237.72.28]) by fmsmga004.fm.intel.com with ESMTP; 23 Mar 2021 07:56:48 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id CED7D4CC; Tue, 23 Mar 2021 16:57:01 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Michael Jamet , Yehezkel Bernat , Andreas Noever , Lukas Wunner , Mario Limonciello , Christian Kellner , Benson Leung , Prashant Malani , Diego Rivas , Greg Kroah-Hartman , Mika Westerberg Subject: [PATCH v2 2/3] thunderbolt: Hide authorized attribute if router does not support PCIe tunnels Date: Tue, 23 Mar 2021 17:57:00 +0300 Message-Id: <20210323145701.86161-3-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210323145701.86161-1-mika.westerberg@linux.intel.com> References: <20210323145701.86161-1-mika.westerberg@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org With USB4 devices PCIe tunneling is optional so for device routers without PCIe upstream adapter it does not make much sense to expose the authorized attribute. For this reason hide it if PCIe tunneling is not supported by the device router. Signed-off-by: Mika Westerberg Reviewed-by: Greg Kroah-Hartman --- drivers/thunderbolt/switch.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index a1b4a695080e..fbcc920e327c 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -1746,6 +1746,18 @@ static struct attribute *switch_attrs[] = { NULL, }; +static bool has_port(const struct tb_switch *sw, enum tb_port_type type) +{ + const struct tb_port *port; + + tb_switch_for_each_port(sw, port) { + if (!port->disabled && port->config.type == type) + return true; + } + + return false; +} + static umode_t switch_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { @@ -1754,7 +1766,8 @@ static umode_t switch_attr_is_visible(struct kobject *kobj, if (attr == &dev_attr_authorized.attr) { if (sw->tb->security_level == TB_SECURITY_NOPCIE || - sw->tb->security_level == TB_SECURITY_DPONLY) + sw->tb->security_level == TB_SECURITY_DPONLY || + !has_port(sw, TB_TYPE_PCIE_UP)) return 0; } else if (attr == &dev_attr_device.attr) { if (!sw->device) From patchwork Tue Mar 23 14:57:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 12158225 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B057C433E0 for ; Tue, 23 Mar 2021 14:57:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1AC3F619AE for ; Tue, 23 Mar 2021 14:57:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232494AbhCWO5M (ORCPT ); Tue, 23 Mar 2021 10:57:12 -0400 Received: from mga03.intel.com ([134.134.136.65]:9377 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232372AbhCWO4w (ORCPT ); Tue, 23 Mar 2021 10:56:52 -0400 IronPort-SDR: ygPhG5M+pLNVWTHyOkV5qlkSsX72pd8ilUR+Dyy4eW/DuE/oIgpQBzjc9z68D+Bwy0i6EWbunB y5LV5EsupDvg== X-IronPort-AV: E=McAfee;i="6000,8403,9931"; a="190523050" X-IronPort-AV: E=Sophos;i="5.81,271,1610438400"; d="scan'208";a="190523050" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Mar 2021 07:56:51 -0700 IronPort-SDR: k8ZJzuRHrCquJVJnN/oOn6ynb81161hIfq5FSOUlkY65sY6XlFKLgUWWP0j+U05st59lqJTv04 YVzca2EVgHVQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,271,1610438400"; d="scan'208";a="593009793" Received: from black.fi.intel.com ([10.237.72.28]) by orsmga005.jf.intel.com with ESMTP; 23 Mar 2021 07:56:48 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id DF2A87D7; Tue, 23 Mar 2021 16:57:01 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Michael Jamet , Yehezkel Bernat , Andreas Noever , Lukas Wunner , Mario Limonciello , Christian Kellner , Benson Leung , Prashant Malani , Diego Rivas , Greg Kroah-Hartman , Mika Westerberg Subject: [PATCH v2 3/3] thunderbolt: Expose more details about USB 3.x and DisplayPort tunnels Date: Tue, 23 Mar 2021 17:57:01 +0300 Message-Id: <20210323145701.86161-4-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210323145701.86161-1-mika.westerberg@linux.intel.com> References: <20210323145701.86161-1-mika.westerberg@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org This exposes two new attributes under each device router: usb3 and dp that hold number of tunnels ending to this switch. These attributes are only available if the connection manager supports it (tunneling_details attribute reads 1). Currently only the software connection manager supports this. Based on these userspace can show the user more detailed information what is going on. Signed-off-by: Mika Westerberg --- .../ABI/testing/sysfs-bus-thunderbolt | 26 +++++++++++ drivers/thunderbolt/domain.c | 10 +++++ drivers/thunderbolt/switch.c | 29 ++++++++++++ drivers/thunderbolt/tb.c | 44 ++++++++++++++----- drivers/thunderbolt/tb.h | 4 ++ include/linux/thunderbolt.h | 6 +++ 6 files changed, 108 insertions(+), 11 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt index c41c68f64693..1569be391ca6 100644 --- a/Documentation/ABI/testing/sysfs-bus-thunderbolt +++ b/Documentation/ABI/testing/sysfs-bus-thunderbolt @@ -61,6 +61,14 @@ Description: This attribute holds current Thunderbolt security level the BIOS. ======= ================================================== +What: /sys/bus/thunderbolt/devices/.../domainX/tunneling_details +Date: July 2021 +KernelVersion: 5.13 +Contact: Mika Westerberg +Description: The connection manager implementation may expose + additional details about tunneling. If it supports this + the attribute reads 1. + What: /sys/bus/thunderbolt/devices/.../authorized Date: Sep 2017 KernelVersion: 4.13 @@ -102,6 +110,15 @@ Contact: thunderbolt-software@lists.01.org Description: This attribute contains 1 if Thunderbolt device was already authorized on boot and 0 otherwise. +What: /sys/bus/thunderbolt/devices/.../dp +Date: Jul 2021 +KernelVersion: 5.13 +Contact: Mika Westerberg +Description: Only available if the domain tunneling_details attribute + reads 1. If present means that the device router has + DisplayPort sink. Contents will be number how many + active DisplayPort tunnels end up to this router. + What: /sys/bus/thunderbolt/devices/.../generation Date: Jan 2020 KernelVersion: 5.5 @@ -169,6 +186,15 @@ Contact: Mika Westerberg Description: This attribute reports number of TX lanes the device is using simultaneusly through its upstream port. +What: /sys/bus/thunderbolt/devices/.../usb3 +Date: Jul 2021 +KernelVersion: 5.13 +Contact: Mika Westerberg +Description: Only available if the domain tunneling_details attribute + reads 1. If present means that the device router has + USB 3.x upstream adapter. Reads 1 if there is an active + USB 3.x tunnel to this router. + What: /sys/bus/thunderbolt/devices/.../vendor Date: Sep 2017 KernelVersion: 4.13 diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c index 98f4056f89ff..d86b0864f870 100644 --- a/drivers/thunderbolt/domain.c +++ b/drivers/thunderbolt/domain.c @@ -282,11 +282,21 @@ static ssize_t security_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(security); +static ssize_t tunneling_details_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const struct tb *tb = container_of(dev, struct tb, dev); + + return sprintf(buf, "%d\n", !!(tb->cm_caps & TB_CAP_TUNNEL_DETAILS)); +} +static DEVICE_ATTR_RO(tunneling_details); + static struct attribute *domain_attrs[] = { &dev_attr_boot_acl.attr, &dev_attr_deauthorization.attr, &dev_attr_iommu_dma_protection.attr, &dev_attr_security.attr, + &dev_attr_tunneling_details.attr, NULL, }; diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index fbcc920e327c..b2c0cfec03d5 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -1493,6 +1493,15 @@ device_name_show(struct device *dev, struct device_attribute *attr, char *buf) } static DEVICE_ATTR_RO(device_name); +static ssize_t dp_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tb_switch *sw = tb_to_switch(dev); + + return sysfs_emit(buf, "%u\n", sw->dp); +} +static DEVICE_ATTR_RO(dp); + static ssize_t generation_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1699,6 +1708,15 @@ static ssize_t nvm_version_show(struct device *dev, } static DEVICE_ATTR_RO(nvm_version); +static ssize_t usb3_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tb_switch *sw = tb_to_switch(dev); + + return sysfs_emit(buf, "%u\n", sw->usb3); +} +static DEVICE_ATTR_RO(usb3); + static ssize_t vendor_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1731,6 +1749,7 @@ static struct attribute *switch_attrs[] = { &dev_attr_boot.attr, &dev_attr_device.attr, &dev_attr_device_name.attr, + &dev_attr_dp.attr, &dev_attr_generation.attr, &dev_attr_key.attr, &dev_attr_nvm_authenticate.attr, @@ -1740,6 +1759,7 @@ static struct attribute *switch_attrs[] = { &dev_attr_rx_lanes.attr, &dev_attr_tx_speed.attr, &dev_attr_tx_lanes.attr, + &dev_attr_usb3.attr, &dev_attr_vendor.attr, &dev_attr_vendor_name.attr, &dev_attr_unique_id.attr, @@ -1763,6 +1783,7 @@ static umode_t switch_attr_is_visible(struct kobject *kobj, { struct device *dev = kobj_to_dev(kobj); struct tb_switch *sw = tb_to_switch(dev); + const struct tb *tb = sw->tb; if (attr == &dev_attr_authorized.attr) { if (sw->tb->security_level == TB_SECURITY_NOPCIE || @@ -1775,6 +1796,10 @@ static umode_t switch_attr_is_visible(struct kobject *kobj, } else if (attr == &dev_attr_device_name.attr) { if (!sw->device_name) return 0; + } else if (attr == &dev_attr_dp.attr) { + if (!(tb->cm_caps & TB_CAP_TUNNEL_DETAILS) || + !has_port(sw, TB_TYPE_DP_HDMI_OUT)) + return 0; } else if (attr == &dev_attr_vendor.attr) { if (!sw->vendor) return 0; @@ -1794,6 +1819,10 @@ static umode_t switch_attr_is_visible(struct kobject *kobj, if (tb_route(sw)) return attr->mode; return 0; + } else if (attr == &dev_attr_usb3.attr) { + if (!(tb->cm_caps & TB_CAP_TUNNEL_DETAILS) || + !has_port(sw, TB_TYPE_USB3_UP)) + return 0; } else if (attr == &dev_attr_nvm_authenticate.attr) { if (nvm_upgradeable(sw)) return attr->mode; diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index eb15022e4e3e..5295930917ab 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -104,10 +104,34 @@ static void tb_remove_dp_resources(struct tb_switch *sw) } } +static void tb_add_tunnel(struct tb *tb, struct tb_tunnel *tunnel) +{ + struct tb_switch *sw = tunnel->dst_port->sw; + struct tb_cm *tcm = tb_priv(tb); + + if (tb_tunnel_is_usb3(tunnel)) + sw->usb3++; + else if (tb_tunnel_is_dp(tunnel)) + sw->dp++; + + list_add_tail(&tunnel->list, &tcm->tunnel_list); +} + +static void tb_remove_tunnel(struct tb_tunnel *tunnel) +{ + struct tb_switch *sw = tunnel->dst_port->sw; + + if (tb_tunnel_is_usb3(tunnel) && sw->usb3) + sw->usb3--; + else if (tb_tunnel_is_dp(tunnel) && sw->dp) + sw->dp--; + + list_del(&tunnel->list); +} + static void tb_discover_tunnels(struct tb_switch *sw) { struct tb *tb = sw->tb; - struct tb_cm *tcm = tb_priv(tb); struct tb_port *port; tb_switch_for_each_port(sw, port) { @@ -142,7 +166,7 @@ static void tb_discover_tunnels(struct tb_switch *sw) } } - list_add_tail(&tunnel->list, &tcm->tunnel_list); + tb_add_tunnel(tb, tunnel); } tb_switch_for_each_port(sw, port) { @@ -436,7 +460,6 @@ static int tb_tunnel_usb3(struct tb *tb, struct tb_switch *sw) struct tb_switch *parent = tb_switch_parent(sw); int ret, available_up, available_down; struct tb_port *up, *down, *port; - struct tb_cm *tcm = tb_priv(tb); struct tb_tunnel *tunnel; if (!tb_acpi_may_tunnel_usb3()) { @@ -499,7 +522,7 @@ static int tb_tunnel_usb3(struct tb *tb, struct tb_switch *sw) goto err_free; } - list_add_tail(&tunnel->list, &tcm->tunnel_list); + tb_add_tunnel(tb, tunnel); if (tb_route(parent)) tb_reclaim_usb3_bandwidth(tb, down, up); @@ -682,7 +705,7 @@ static void tb_deactivate_and_free_tunnel(struct tb_tunnel *tunnel) return; tb_tunnel_deactivate(tunnel); - list_del(&tunnel->list); + tb_remove_tunnel(tunnel); tb = tunnel->tb; src_port = tunnel->src_port; @@ -933,7 +956,7 @@ static void tb_tunnel_dp(struct tb *tb) goto err_free; } - list_add_tail(&tunnel->list, &tcm->tunnel_list); + tb_add_tunnel(tb, tunnel); tb_reclaim_usb3_bandwidth(tb, in, out); return; @@ -1034,7 +1057,7 @@ static int tb_disconnect_pci(struct tb *tb, struct tb_switch *sw) return -ENODEV; tb_tunnel_deactivate(tunnel); - list_del(&tunnel->list); + tb_remove_tunnel(tunnel); tb_tunnel_free(tunnel); return 0; } @@ -1042,7 +1065,6 @@ static int tb_disconnect_pci(struct tb *tb, struct tb_switch *sw) static int tb_tunnel_pci(struct tb *tb, struct tb_switch *sw) { struct tb_port *up, *down, *port; - struct tb_cm *tcm = tb_priv(tb); struct tb_switch *parent_sw; struct tb_tunnel *tunnel; @@ -1071,7 +1093,7 @@ static int tb_tunnel_pci(struct tb *tb, struct tb_switch *sw) return -EIO; } - list_add_tail(&tunnel->list, &tcm->tunnel_list); + tb_add_tunnel(tb, tunnel); return 0; } @@ -1079,7 +1101,6 @@ static int tb_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd, int transmit_path, int transmit_ring, int receive_path, int receive_ring) { - struct tb_cm *tcm = tb_priv(tb); struct tb_port *nhi_port, *dst_port; struct tb_tunnel *tunnel; struct tb_switch *sw; @@ -1104,7 +1125,7 @@ static int tb_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd, return -EIO; } - list_add_tail(&tunnel->list, &tcm->tunnel_list); + tb_add_tunnel(tb, tunnel); mutex_unlock(&tb->lock); return 0; } @@ -1582,6 +1603,7 @@ struct tb *tb_probe(struct tb_nhi *nhi) tb->security_level = TB_SECURITY_NOPCIE; tb->cm_ops = &tb_cm_ops; + tb->cm_caps |= TB_CAP_TUNNEL_DETAILS; tcm = tb_priv(tb); INIT_LIST_HEAD(&tcm->tunnel_list); diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 9790e9f13d2b..eb93c41a0881 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -123,6 +123,8 @@ struct tb_switch_tmu { * @safe_mode: The switch is in safe-mode * @boot: Whether the switch was already authorized on boot or not * @rpm: The switch supports runtime PM + * @usb3: Number of USB 3.x tunnels to this switch (0 or 1) + * @dp: Number of DisplayPort tunnels ending to this switch * @authorized: Whether the switch is authorized by user or policy * @security_level: Switch supported security level * @debugfs_dir: Pointer to the debugfs structure @@ -167,6 +169,8 @@ struct tb_switch { bool safe_mode; bool boot; bool rpm; + unsigned int usb3; + unsigned int dp; unsigned int authorized; enum tb_security_level security_level; struct dentry *debugfs_dir; diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h index e7c96c37174f..dc6cfb4237d1 100644 --- a/include/linux/thunderbolt.h +++ b/include/linux/thunderbolt.h @@ -57,6 +57,9 @@ enum tb_security_level { TB_SECURITY_NOPCIE, }; +/* Connection manager exposes details about tunneling */ +#define TB_CAP_TUNNEL_DETAILS BIT(0) + /** * struct tb - main thunderbolt bus structure * @dev: Domain device @@ -67,6 +70,8 @@ enum tb_security_level { * @wq: Ordered workqueue for all domain specific work * @root_switch: Root switch of this domain * @cm_ops: Connection manager specific operations vector + * @cm_caps: Extra capabilities supported by the connection manager + * implementation * @index: Linux assigned domain number * @security_level: Current security level * @nboot_acl: Number of boot ACLs the domain supports @@ -80,6 +85,7 @@ struct tb { struct workqueue_struct *wq; struct tb_switch *root_switch; const struct tb_cm_ops *cm_ops; + unsigned int cm_caps; int index; enum tb_security_level security_level; size_t nboot_acl;