From patchwork Tue Oct 1 17:30:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832705 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.129.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD1D91CC158 for ; Tue, 1 Oct 2024 17:32:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803928; cv=none; b=pLSGE+kUcj33nLjoLjm7q2W7Fho5zDfu7OsIBTSp51v620rNXCcpjZIyIqY47HzgeCp9w89AfkRDsHlw6Kn0UTL0MrNFYOEtlkQlF8xhw3h65+2zsf/ScA2UQa0mjFjN4tNtDyPk1bd2m9ZtKU7hWhY9O68XxcBfw6snIKduOuk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803928; c=relaxed/simple; bh=2rXJmCQImnyyQETslHEWVdgM3hwO32Sca6tGzmM6+ck=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=fqyK0t0134V8IRfeQxO3hu4k67Faq/zc8is9gN1s5NQ7/GRhl1CauahEoDEdOYdMfxbwbqLjMlzOOxaYh3nnGXQr77pByRcNs8vGKYXiIJe8G63ZFDSbLFkK8Od21A8yjBFRbJBJgikHag/2nGFsNyBSCWtgHavO+0twbUwPyd8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=QEOGC50N; arc=none smtp.client-ip=170.10.129.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="QEOGC50N" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803926; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2rXJmCQImnyyQETslHEWVdgM3hwO32Sca6tGzmM6+ck=; b=QEOGC50N6aSuGtSzL0KJHFsJma4N4CIuN+KvdyfKNcNt1+PJeZsEyqEHjsDMC2p9yGNAr7 3ff3Lax8E5WAW1tRv8Sb8h7bMB3FbJwg1tV9xiXqUNwjaxY3eumqDkOuB4cGZ0cTXbuAV1 4bERfseIfIqAZ+2MepnUW0vDWZnZSYA= Received: from g8t13017g.inc.hp.com (hpi-bastion.austin2.mail.core.hp.com [15.72.64.135]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-25-VTQl0jrzNuGHA5hkj1vccQ-1; Tue, 01 Oct 2024 13:32:05 -0400 X-MC-Unique: VTQl0jrzNuGHA5hkj1vccQ-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g8t13017g.inc.hp.com (Postfix) with ESMTPS id 0381260008BE; Tue, 1 Oct 2024 17:32:04 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id E70511E; Tue, 1 Oct 2024 17:32:01 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Gil Fine , Alexandru Gagniuc Subject: [PATCH 6.6 01/14] thunderbolt: Fix debug log when DisplayPort adapter not available for pairing Date: Tue, 1 Oct 2024 17:30:56 +0000 Message-Id: <20241001173109.1513-2-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Gil Fine [ Upstream commit 6b8ac54f31f985d3abb0b4212187838dd8ea4227 ] Fix debug log when looking for a DisplayPort adapter pair of DP IN and DP OUT. In case of no DP adapter available, log the type of the DP adapter that is not available. Signed-off-by: Gil Fine Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tb.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index c5e10c1d4c38..6fc300edad68 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -1311,13 +1311,12 @@ static void tb_tunnel_dp(struct tb *tb) continue; } - tb_port_dbg(port, "DP IN available\n"); + in = port; + tb_port_dbg(in, "DP IN available\n"); out = tb_find_dp_out(tb, port); - if (out) { - in = port; + if (out) break; - } } if (!in) { From patchwork Tue Oct 1 17:30:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832704 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.133.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 41CEB1CC154 for ; Tue, 1 Oct 2024 17:32:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803930; cv=none; b=OXymNP7tOzEGDTQ6Vq018toX8DK7yrbGsZKc5vWGiRFUELZQRZw28BRLBhJkKvSH/0l2zKm01wz67iBcgyyGYj5YJ9BlVkcZE8D8LTvxqSxLyawSCbTdSB8YImgq9Vz0w7p0jjRppA+/mrdPSE2TG5Qrz68aV0o5/KIunS5Nwjk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803930; c=relaxed/simple; bh=95uHAVLhn3dwbvkj1bSKFguBoCiULtcN730jVEMT60M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=Z8p6P6lZsehtSHmxc/8EBALa3EgJF/z0Ve3dN8/EWb0MD3+LCAHAsMePN8ATY30atbnvYKpto6VOJE2vMB1CYRR7iynH7EhiqKahecOZMXXxfAdkuYOSuQ18HymVnj/ZDKxbDUlAga+Ew7TEQcM6uBKMs3UL5/LWOjLCaTtX15k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=jrZI2jzU; arc=none smtp.client-ip=170.10.133.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="jrZI2jzU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803927; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9FDkauejoxz2XTpH28ePbl2EFJ+/zapfPnhifYMCH08=; b=jrZI2jzUa5XKqQamxTArYVngKqkz6Ox0p3xKKo1zY2to8zUeda07S0NuFVOEkis+5U41QH iZs+zygvFNMIf+8CcNerteNQ49HnKQBFBALqisDfmmo3Q3LvnwWvBOO4IwMOwAD6XIn1pU /dsCfWVKygrbFlki7lGx65+IRvMR2WE= Received: from g7t16451g.inc.hp.com (hpi-bastion.austin1.mail.core.hp.com [15.73.128.137]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-400-ohbBEXR0ML-V0qPm_19wDw-1; Tue, 01 Oct 2024 13:32:06 -0400 X-MC-Unique: ohbBEXR0ML-V0qPm_19wDw-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g7t16451g.inc.hp.com (Postfix) with ESMTPS id 30CFD6000E52; Tue, 1 Oct 2024 17:32:05 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id C8BD118; Tue, 1 Oct 2024 17:32:03 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Alexandru Gagniuc Subject: [PATCH 6.6 02/14] thunderbolt: Use tb_tunnel_dbg() where possible to make logging more consistent Date: Tue, 1 Oct 2024 17:30:57 +0000 Message-Id: <20241001173109.1513-3-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Mika Westerberg [ Upstream commit fe8a0293c922ee8bc1ff0cf9048075afb264004a ] This makes it easier to find out the tunnel in question. Also drop a couple of lines that generate duplicate information. Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tunnel.c | 65 +++++++++++++++++------------------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index a6810fb36860..c0a8142f73f4 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -614,8 +614,9 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) in_rate = tb_dp_cap_get_rate(in_dp_cap); in_lanes = tb_dp_cap_get_lanes(in_dp_cap); - tb_port_dbg(in, "maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", - in_rate, in_lanes, tb_dp_bandwidth(in_rate, in_lanes)); + tb_tunnel_dbg(tunnel, + "DP IN maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", + in_rate, in_lanes, tb_dp_bandwidth(in_rate, in_lanes)); /* * If the tunnel bandwidth is limited (max_bw is set) then see @@ -624,8 +625,9 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) out_rate = tb_dp_cap_get_rate(out_dp_cap); out_lanes = tb_dp_cap_get_lanes(out_dp_cap); bw = tb_dp_bandwidth(out_rate, out_lanes); - tb_port_dbg(out, "maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", - out_rate, out_lanes, bw); + tb_tunnel_dbg(tunnel, + "DP OUT maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", + out_rate, out_lanes, bw); if (in->sw->config.depth < out->sw->config.depth) max_bw = tunnel->max_down; @@ -639,13 +641,14 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) out_rate, out_lanes, &new_rate, &new_lanes); if (ret) { - tb_port_info(out, "not enough bandwidth for DP tunnel\n"); + tb_tunnel_info(tunnel, "not enough bandwidth\n"); return ret; } new_bw = tb_dp_bandwidth(new_rate, new_lanes); - tb_port_dbg(out, "bandwidth reduced to %u Mb/s x%u = %u Mb/s\n", - new_rate, new_lanes, new_bw); + tb_tunnel_dbg(tunnel, + "bandwidth reduced to %u Mb/s x%u = %u Mb/s\n", + new_rate, new_lanes, new_bw); /* * Set new rate and number of lanes before writing it to @@ -662,7 +665,7 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) */ if (tb_route(out->sw) && tb_switch_is_titan_ridge(out->sw)) { out_dp_cap |= DP_COMMON_CAP_LTTPR_NS; - tb_port_dbg(out, "disabling LTTPR\n"); + tb_tunnel_dbg(tunnel, "disabling LTTPR\n"); } return tb_port_write(in, &out_dp_cap, TB_CFG_PORT, @@ -712,8 +715,8 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel) lanes = min(in_lanes, out_lanes); tmp = tb_dp_bandwidth(rate, lanes); - tb_port_dbg(in, "non-reduced bandwidth %u Mb/s x%u = %u Mb/s\n", rate, - lanes, tmp); + tb_tunnel_dbg(tunnel, "non-reduced bandwidth %u Mb/s x%u = %u Mb/s\n", + rate, lanes, tmp); ret = usb4_dp_port_set_nrd(in, rate, lanes); if (ret) @@ -728,15 +731,15 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel) rate = min(in_rate, out_rate); tmp = tb_dp_bandwidth(rate, lanes); - tb_port_dbg(in, - "maximum bandwidth through allocation mode %u Mb/s x%u = %u Mb/s\n", - rate, lanes, tmp); + tb_tunnel_dbg(tunnel, + "maximum bandwidth through allocation mode %u Mb/s x%u = %u Mb/s\n", + rate, lanes, tmp); for (granularity = 250; tmp / granularity > 255 && granularity <= 1000; granularity *= 2) ; - tb_port_dbg(in, "granularity %d Mb/s\n", granularity); + tb_tunnel_dbg(tunnel, "granularity %d Mb/s\n", granularity); /* * Returns -EINVAL if granularity above is outside of the @@ -756,7 +759,7 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel) else estimated_bw = tunnel->max_up; - tb_port_dbg(in, "estimated bandwidth %d Mb/s\n", estimated_bw); + tb_tunnel_dbg(tunnel, "estimated bandwidth %d Mb/s\n", estimated_bw); ret = usb4_dp_port_set_estimated_bandwidth(in, estimated_bw); if (ret) @@ -767,7 +770,7 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel) if (ret) return ret; - tb_port_dbg(in, "bandwidth allocation mode enabled\n"); + tb_tunnel_dbg(tunnel, "bandwidth allocation mode enabled\n"); return 0; } @@ -788,7 +791,7 @@ static int tb_dp_init(struct tb_tunnel *tunnel) if (!usb4_dp_port_bandwidth_mode_supported(in)) return 0; - tb_port_dbg(in, "bandwidth allocation mode supported\n"); + tb_tunnel_dbg(tunnel, "bandwidth allocation mode supported\n"); ret = usb4_dp_port_set_cm_id(in, tb->index); if (ret) @@ -805,7 +808,7 @@ static void tb_dp_deinit(struct tb_tunnel *tunnel) return; if (usb4_dp_port_bandwidth_mode_enabled(in)) { usb4_dp_port_set_cm_bandwidth_mode_supported(in, false); - tb_port_dbg(in, "bandwidth allocation mode disabled\n"); + tb_tunnel_dbg(tunnel, "bandwidth allocation mode disabled\n"); } } @@ -921,9 +924,6 @@ static int tb_dp_bandwidth_mode_consumed_bandwidth(struct tb_tunnel *tunnel, if (allocated_bw == max_bw) allocated_bw = ret; - tb_port_dbg(in, "consumed bandwidth through allocation mode %d Mb/s\n", - allocated_bw); - if (in->sw->config.depth < out->sw->config.depth) { *consumed_up = 0; *consumed_down = allocated_bw; @@ -1006,9 +1006,6 @@ static int tb_dp_alloc_bandwidth(struct tb_tunnel *tunnel, int *alloc_up, /* Now we can use BW mode registers to figure out the bandwidth */ /* TODO: need to handle discovery too */ tunnel->bw_mode = true; - - tb_port_dbg(in, "allocated bandwidth through allocation mode %d Mb/s\n", - tmp); return 0; } @@ -1035,8 +1032,7 @@ static int tb_dp_read_dprx(struct tb_tunnel *tunnel, u32 *rate, u32 *lanes, *rate = tb_dp_cap_get_rate(val); *lanes = tb_dp_cap_get_lanes(val); - tb_port_dbg(in, "consumed bandwidth through DPRX %d Mb/s\n", - tb_dp_bandwidth(*rate, *lanes)); + tb_tunnel_dbg(tunnel, "DPRX read done\n"); return 0; } usleep_range(100, 150); @@ -1073,9 +1069,6 @@ static int tb_dp_read_cap(struct tb_tunnel *tunnel, unsigned int cap, u32 *rate, *rate = tb_dp_cap_get_rate(val); *lanes = tb_dp_cap_get_lanes(val); - - tb_port_dbg(in, "bandwidth from %#x capability %d Mb/s\n", cap, - tb_dp_bandwidth(*rate, *lanes)); return 0; } @@ -1253,8 +1246,9 @@ static void tb_dp_dump(struct tb_tunnel *tunnel) rate = tb_dp_cap_get_rate(dp_cap); lanes = tb_dp_cap_get_lanes(dp_cap); - tb_port_dbg(in, "maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", - rate, lanes, tb_dp_bandwidth(rate, lanes)); + tb_tunnel_dbg(tunnel, + "DP IN maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", + rate, lanes, tb_dp_bandwidth(rate, lanes)); out = tunnel->dst_port; @@ -1265,8 +1259,9 @@ static void tb_dp_dump(struct tb_tunnel *tunnel) rate = tb_dp_cap_get_rate(dp_cap); lanes = tb_dp_cap_get_lanes(dp_cap); - tb_port_dbg(out, "maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", - rate, lanes, tb_dp_bandwidth(rate, lanes)); + tb_tunnel_dbg(tunnel, + "DP OUT maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", + rate, lanes, tb_dp_bandwidth(rate, lanes)); if (tb_port_read(in, &dp_cap, TB_CFG_PORT, in->cap_adap + DP_REMOTE_CAP, 1)) @@ -1275,8 +1270,8 @@ static void tb_dp_dump(struct tb_tunnel *tunnel) rate = tb_dp_cap_get_rate(dp_cap); lanes = tb_dp_cap_get_lanes(dp_cap); - tb_port_dbg(in, "reduced bandwidth %u Mb/s x%u = %u Mb/s\n", - rate, lanes, tb_dp_bandwidth(rate, lanes)); + tb_tunnel_dbg(tunnel, "reduced bandwidth %u Mb/s x%u = %u Mb/s\n", + rate, lanes, tb_dp_bandwidth(rate, lanes)); } /** From patchwork Tue Oct 1 17:30:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832204 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.133.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D16E1CC8AD for ; Tue, 1 Oct 2024 17:32:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803932; cv=none; b=tSN6RGArjiE74l533WRPZqApppQc/K2FWKghJcV2sKNWL4+UHTBpbbkz8+LYiKWIZ7WT+ELBmBZk0bMZNPynkZG0JVU3NdResQjZzTatR1DYDsiLAeOTfWP96brkJcPiDIRwT5EGEkdxfwp6oZxAqD5p64RM23k+KXnyvVUTuLg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803932; c=relaxed/simple; bh=FAPTaMdSV48f1tF+9Jpob0UOmt1PtaSVTqw0KNCZCAA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=sE0lM6S4CeIPDR3qv3tWsk6X+0f6I1F2loKuoYKjDos/RYY3eXk3HZjDPGGm3LrTo3PfWvnEKmk8jBkHLixhH6jH/GZhPzDhjU+vEMH/KKp2h1yttZRKWRZU53//AOa0S4g8m0sgLusT9KsfTv2PdMGHs8TKMp5lr3Ts/I1cnKg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=CjlJY1up; arc=none smtp.client-ip=170.10.133.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="CjlJY1up" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803928; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=n5a6zSq0OG6cvfAemvQqxd1Yqrh9eX3QmCO9Ky3kiRs=; b=CjlJY1upt7DsZ49Kdd/KrJZBc1Dsk0swqnSzssa6o5VD0xAzAxX49wCEXeblma4TnWGsUG z0pxEn050f91Z2Hj+4t0f0b502iJhDlKRRfnKWybNsOrRuhKunrnBxigrZeYx+pMPlCNNj leDbUY0/SujYxwlpHHQVWhaQWBj/GF4= Received: from g8t13016g.inc.hp.com (hpi-bastion.austin2.mail.core.hp.com [15.72.64.134]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-342-UF3Wt5jKM9ucahjbHwHoqg-1; Tue, 01 Oct 2024 13:32:07 -0400 X-MC-Unique: UF3Wt5jKM9ucahjbHwHoqg-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g8t13016g.inc.hp.com (Postfix) with ESMTPS id 9C7DF6000FE9; Tue, 1 Oct 2024 17:32:06 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 236061E; Tue, 1 Oct 2024 17:32:04 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Alexandru Gagniuc Subject: [PATCH 6.6 03/14] thunderbolt: Expose tb_tunnel_xxx() log macros to the rest of the driver Date: Tue, 1 Oct 2024 17:30:58 +0000 Message-Id: <20241001173109.1513-4-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Mika Westerberg [ Upstream commit d27bd2c37d4666bce25ec4d9ac8c6b169992f0f0 ] In order to allow more consistent logging of tunnel related information make these logging macros available to the rest of the driver. Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tunnel.c | 26 +++++--------------------- drivers/thunderbolt/tunnel.h | 24 +++++++++++++++++++++++- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index c0a8142f73f4..389b8dfc2447 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -58,27 +58,6 @@ MODULE_PARM_DESC(bw_alloc_mode, static const char * const tb_tunnel_names[] = { "PCI", "DP", "DMA", "USB3" }; -#define __TB_TUNNEL_PRINT(level, tunnel, fmt, arg...) \ - do { \ - struct tb_tunnel *__tunnel = (tunnel); \ - level(__tunnel->tb, "%llx:%u <-> %llx:%u (%s): " fmt, \ - tb_route(__tunnel->src_port->sw), \ - __tunnel->src_port->port, \ - tb_route(__tunnel->dst_port->sw), \ - __tunnel->dst_port->port, \ - tb_tunnel_names[__tunnel->type], \ - ## arg); \ - } while (0) - -#define tb_tunnel_WARN(tunnel, fmt, arg...) \ - __TB_TUNNEL_PRINT(tb_WARN, tunnel, fmt, ##arg) -#define tb_tunnel_warn(tunnel, fmt, arg...) \ - __TB_TUNNEL_PRINT(tb_warn, tunnel, fmt, ##arg) -#define tb_tunnel_info(tunnel, fmt, arg...) \ - __TB_TUNNEL_PRINT(tb_info, tunnel, fmt, ##arg) -#define tb_tunnel_dbg(tunnel, fmt, arg...) \ - __TB_TUNNEL_PRINT(tb_dbg, tunnel, fmt, ##arg) - static inline unsigned int tb_usable_credits(const struct tb_port *port) { return port->total_credits - port->ctl_credits; @@ -2382,3 +2361,8 @@ void tb_tunnel_reclaim_available_bandwidth(struct tb_tunnel *tunnel, tunnel->reclaim_available_bandwidth(tunnel, available_up, available_down); } + +const char *tb_tunnel_type_name(const struct tb_tunnel *tunnel) +{ + return tb_tunnel_names[tunnel->type]; +} diff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h index bf690f7beeee..750ebb570d99 100644 --- a/drivers/thunderbolt/tunnel.h +++ b/drivers/thunderbolt/tunnel.h @@ -137,5 +137,27 @@ static inline bool tb_tunnel_is_usb3(const struct tb_tunnel *tunnel) return tunnel->type == TB_TUNNEL_USB3; } -#endif +const char *tb_tunnel_type_name(const struct tb_tunnel *tunnel); + +#define __TB_TUNNEL_PRINT(level, tunnel, fmt, arg...) \ + do { \ + struct tb_tunnel *__tunnel = (tunnel); \ + level(__tunnel->tb, "%llx:%u <-> %llx:%u (%s): " fmt, \ + tb_route(__tunnel->src_port->sw), \ + __tunnel->src_port->port, \ + tb_route(__tunnel->dst_port->sw), \ + __tunnel->dst_port->port, \ + tb_tunnel_type_name(__tunnel), \ + ## arg); \ + } while (0) +#define tb_tunnel_WARN(tunnel, fmt, arg...) \ + __TB_TUNNEL_PRINT(tb_WARN, tunnel, fmt, ##arg) +#define tb_tunnel_warn(tunnel, fmt, arg...) \ + __TB_TUNNEL_PRINT(tb_warn, tunnel, fmt, ##arg) +#define tb_tunnel_info(tunnel, fmt, arg...) \ + __TB_TUNNEL_PRINT(tb_info, tunnel, fmt, ##arg) +#define tb_tunnel_dbg(tunnel, fmt, arg...) \ + __TB_TUNNEL_PRINT(tb_dbg, tunnel, fmt, ##arg) + +#endif From patchwork Tue Oct 1 17:30:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832703 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.129.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1521B1CC8BB for ; Tue, 1 Oct 2024 17:32:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803932; cv=none; b=PdhkGhaw4p9gl2Ta09kw6SxO3FK+uz9A+j8VD2x0c3MXaQcIaARgpWr+61hMNI2GwYdTJvs228ms4AN3HJw8zKqfrDpcxnEJ14XRVhWnhQparPJqQOlYBYuu/SKbzNLu6UxKkfT+s3NhOXYq54yMLmkqPLTeo+Sict2DlDIlR2o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803932; c=relaxed/simple; bh=mtqObfXgLYJ048H8y2GtYJDqsZj6puboQCx0Bpj5QOQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=TKaAWDnmJOPMp6Sh5MY3D9ZLdBJTOMbeK455s0QYQ8WmvC7Y4klmVzyojsEiJHxLl0iBcKM598ElLj9F0Se0p/mmxBIkFic5klrro8TrA/8lf4mQh5p0chAg/ZtXqbAgE+mFql97EH2NZpavJ+vzZie328DkBga5N7YuM8EnVCI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=mcMKs5zs; arc=none smtp.client-ip=170.10.129.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="mcMKs5zs" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803930; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mtqObfXgLYJ048H8y2GtYJDqsZj6puboQCx0Bpj5QOQ=; b=mcMKs5zskf99NgpqAElZz0BHd4yVUggDM+LOprxoJCshygaj3WeB/Rc6IkyAVJk9d4JsqO dhUbSHZzEQI1oP57UooAsD2QG7fOAIUiRMpw1yIszjjOwaCXB4+gucBLdKxp3b86I9TO7c Np8Sk8206J/FtuAKKg7AQZlmHBS4f+E= Received: from g8t13017g.inc.hp.com (hpi-bastion.austin2.mail.core.hp.com [15.72.64.135]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-515-zKK06PPyPqWyIvY9Rx75Gg-1; Tue, 01 Oct 2024 13:32:09 -0400 X-MC-Unique: zKK06PPyPqWyIvY9Rx75Gg-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g8t13017g.inc.hp.com (Postfix) with ESMTPS id 3E51E60008BE; Tue, 1 Oct 2024 17:32:08 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 76B2718; Tue, 1 Oct 2024 17:32:06 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Gil Fine , Alexandru Gagniuc Subject: [PATCH 6.6 04/14] thunderbolt: Create multiple DisplayPort tunnels if there are more DP IN/OUT pairs Date: Tue, 1 Oct 2024 17:30:59 +0000 Message-Id: <20241001173109.1513-5-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Gil Fine [ Upstream commit 8648c6465c025c488e2855c209c0dea1a1a15184 ] Currently we only create one DisplayPort tunnel even if there would be more DP IN/OUT pairs available. Specifically this happens when a router is unplugged and we check if a new DisplayPort tunnel can be created. To cover this create tunnels as long as we find suitable DP IN/OUT pairs. Signed-off-by: Gil Fine Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tb.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 6fc300edad68..e37fb1081420 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -1282,18 +1282,13 @@ static struct tb_port *tb_find_dp_out(struct tb *tb, struct tb_port *in) return NULL; } -static void tb_tunnel_dp(struct tb *tb) +static bool tb_tunnel_one_dp(struct tb *tb) { int available_up, available_down, ret, link_nr; struct tb_cm *tcm = tb_priv(tb); struct tb_port *port, *in, *out; struct tb_tunnel *tunnel; - if (!tb_acpi_may_tunnel_dp()) { - tb_dbg(tb, "DP tunneling disabled, not creating tunnel\n"); - return; - } - /* * Find pair of inactive DP IN and DP OUT adapters and then * establish a DP tunnel between them. @@ -1321,11 +1316,11 @@ static void tb_tunnel_dp(struct tb *tb) if (!in) { tb_dbg(tb, "no suitable DP IN adapter available, not tunneling\n"); - return; + return false; } if (!out) { tb_dbg(tb, "no suitable DP OUT adapter available, not tunneling\n"); - return; + return false; } /* @@ -1398,7 +1393,7 @@ static void tb_tunnel_dp(struct tb *tb) * TMU mode to HiFi for CL0s to work. */ tb_increase_tmu_accuracy(tunnel); - return; + return true; err_free: tb_tunnel_free(tunnel); @@ -1413,6 +1408,19 @@ static void tb_tunnel_dp(struct tb *tb) pm_runtime_put_autosuspend(&out->sw->dev); pm_runtime_mark_last_busy(&in->sw->dev); pm_runtime_put_autosuspend(&in->sw->dev); + + return false; +} + +static void tb_tunnel_dp(struct tb *tb) +{ + if (!tb_acpi_may_tunnel_dp()) { + tb_dbg(tb, "DP tunneling disabled, not creating tunnel\n"); + return; + } + + while (tb_tunnel_one_dp(tb)) + ; } static void tb_enter_redrive(struct tb_port *port) From patchwork Tue Oct 1 17:31:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832203 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.133.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 485E71CBEAA for ; Tue, 1 Oct 2024 17:32:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803934; cv=none; b=hNUOirw6hYZbghyR7YuPCSeU+XhaCLsY6EIZUJADRh+Px847KfPbpqOTMOSXCePJAAvjykOvzwiRTA5jc8Xy7eCn853wDXZKym7kTk8udNYZG2FAss89dHaTZ/AfBTv82Xz8nP+FR1k7VfEuenMYuYHZs5l8D+olfEYCOcACp2c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803934; c=relaxed/simple; bh=NrO6P5oycsDCrsZvxiJrZTKeIEbsDkKLOs0SvA0S750=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=RPhVW0MIDPgTuGTDm59+G++MWprtkZyoLfatinyuqIVKMcLVOxT66W9hLfRjrWzzod5hUv5EuU8TZVJnGAxVWCW820GV3UxWLjjdPREI2pz96i2dxQYaRQcCNy13Dp+5+Hf7SV3axnjxXKgn65ESQMzxwmlrI8D9rLwDi1yl/m4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=WVtfgS7w; arc=none smtp.client-ip=170.10.133.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="WVtfgS7w" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803931; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NrO6P5oycsDCrsZvxiJrZTKeIEbsDkKLOs0SvA0S750=; b=WVtfgS7wiay484A35VQ2F9A03NQta2yRyOtqeUdfWD5KuTu1WlnG3ek/73d02PXR0K81tp nVJ97wnogeKzfaxkNwTz72zwELv/U4F+m3ywV5ebmW65WcJdaqbFuRUvp/Ht4a19nxPl4V n0XVsbN597iLGK843ebhZa9VmktQypA= Received: from g7t16451g.inc.hp.com (hpifallback.mail.core.hp.com [15.73.128.137]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-338-3dSQa8JsOKODyGQBkEqtWg-1; Tue, 01 Oct 2024 13:32:10 -0400 X-MC-Unique: 3dSQa8JsOKODyGQBkEqtWg-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g7t16451g.inc.hp.com (Postfix) with ESMTPS id 6E3BD6000B74; Tue, 1 Oct 2024 17:32:09 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 0DE881E; Tue, 1 Oct 2024 17:32:07 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Alexandru Gagniuc Subject: [PATCH 6.6 05/14] thunderbolt: Use constants for path weight and priority Date: Tue, 1 Oct 2024 17:31:00 +0000 Message-Id: <20241001173109.1513-6-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Mika Westerberg [ Upstream commit f73edddfa2a64a185c65a33f100778169c92fc25 ] Makes it easier to follow and update. No functional changes. Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tunnel.c | 39 +++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index 389b8dfc2447..9947b9d0d51a 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -21,12 +21,18 @@ #define TB_PCI_PATH_DOWN 0 #define TB_PCI_PATH_UP 1 +#define TB_PCI_PRIORITY 3 +#define TB_PCI_WEIGHT 1 + /* USB3 adapters use always HopID of 8 for both directions */ #define TB_USB3_HOPID 8 #define TB_USB3_PATH_DOWN 0 #define TB_USB3_PATH_UP 1 +#define TB_USB3_PRIORITY 3 +#define TB_USB3_WEIGHT 3 + /* DP adapters use HopID 8 for AUX and 9 for Video */ #define TB_DP_AUX_TX_HOPID 8 #define TB_DP_AUX_RX_HOPID 8 @@ -36,6 +42,12 @@ #define TB_DP_AUX_PATH_OUT 1 #define TB_DP_AUX_PATH_IN 2 +#define TB_DP_VIDEO_PRIORITY 1 +#define TB_DP_VIDEO_WEIGHT 1 + +#define TB_DP_AUX_PRIORITY 2 +#define TB_DP_AUX_WEIGHT 1 + /* Minimum number of credits needed for PCIe path */ #define TB_MIN_PCIE_CREDITS 6U /* @@ -46,6 +58,9 @@ /* Minimum number of credits for DMA path */ #define TB_MIN_DMA_CREDITS 1 +#define TB_DMA_PRIORITY 5 +#define TB_DMA_WEIGHT 1 + static unsigned int dma_credits = TB_DMA_CREDITS; module_param(dma_credits, uint, 0444); MODULE_PARM_DESC(dma_credits, "specify custom credits for DMA tunnels (default: " @@ -213,8 +228,8 @@ static int tb_pci_init_path(struct tb_path *path) path->egress_shared_buffer = TB_PATH_NONE; path->ingress_fc_enable = TB_PATH_ALL; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 3; - path->weight = 1; + path->priority = TB_PCI_PRIORITY; + path->weight = TB_PCI_WEIGHT; path->drop_packages = 0; tb_path_for_each_hop(path, hop) { @@ -1152,8 +1167,8 @@ static void tb_dp_init_aux_path(struct tb_path *path) path->egress_shared_buffer = TB_PATH_NONE; path->ingress_fc_enable = TB_PATH_ALL; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 2; - path->weight = 1; + path->priority = TB_DP_AUX_PRIORITY; + path->weight = TB_DP_AUX_WEIGHT; tb_path_for_each_hop(path, hop) tb_dp_init_aux_credits(hop); @@ -1196,8 +1211,8 @@ static int tb_dp_init_video_path(struct tb_path *path) path->egress_shared_buffer = TB_PATH_NONE; path->ingress_fc_enable = TB_PATH_NONE; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 1; - path->weight = 1; + path->priority = TB_DP_VIDEO_PRIORITY; + path->weight = TB_DP_VIDEO_WEIGHT; tb_path_for_each_hop(path, hop) { int ret; @@ -1471,8 +1486,8 @@ static int tb_dma_init_rx_path(struct tb_path *path, unsigned int credits) path->ingress_fc_enable = TB_PATH_ALL; path->egress_shared_buffer = TB_PATH_NONE; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 5; - path->weight = 1; + path->priority = TB_DMA_PRIORITY; + path->weight = TB_DMA_WEIGHT; path->clear_fc = true; /* @@ -1505,8 +1520,8 @@ static int tb_dma_init_tx_path(struct tb_path *path, unsigned int credits) path->ingress_fc_enable = TB_PATH_ALL; path->egress_shared_buffer = TB_PATH_NONE; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 5; - path->weight = 1; + path->priority = TB_DMA_PRIORITY; + path->weight = TB_DMA_WEIGHT; path->clear_fc = true; tb_path_for_each_hop(path, hop) { @@ -1845,8 +1860,8 @@ static void tb_usb3_init_path(struct tb_path *path) path->egress_shared_buffer = TB_PATH_NONE; path->ingress_fc_enable = TB_PATH_ALL; path->ingress_shared_buffer = TB_PATH_NONE; - path->priority = 3; - path->weight = 3; + path->priority = TB_USB3_PRIORITY; + path->weight = TB_USB3_WEIGHT; path->drop_packages = 0; tb_path_for_each_hop(path, hop) From patchwork Tue Oct 1 17:31:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832702 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.133.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F6211CCB5F for ; Tue, 1 Oct 2024 17:32:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803935; cv=none; b=OBr+UlnAcfpP+07bHvY25G3ASauxQnitTHVIWgA41q4cwWxtzZKQsPqOcMXtiVd2WOzAz5JiaYzwkKmcdBvd4GJnl8wk3l9f8ZCR76CaIP3yLWz3eR+yIY4j+xPPVzQMPJzGbYdk+VsbT74ocOM70/zNQ87wF3DiEM1U2kwWT9k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803935; c=relaxed/simple; bh=sVXoRa3TsqDBKsgTaREp1zzsof1dAq+XUY/Prh3ZPu4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=OfOukTyxLFs7mdniKPHH4s7t1YtNSMpAQ8sDiriUJcoQCIdfLu2hIb14ZlTlMA9lb9CfMlJeX+tILQ/5JssPCUxXnE/sn8cdY0L1aK2KCXMfXuBH4yRgyCKY0+QDZkBXbQTEEr++5mgBMEoHuLkAAl1nI/0i1UdvQVjuZbRz5VU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=VP5UEnGj; arc=none smtp.client-ip=170.10.133.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="VP5UEnGj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803932; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sVXoRa3TsqDBKsgTaREp1zzsof1dAq+XUY/Prh3ZPu4=; b=VP5UEnGj0QS+SARoDlUp4YPdPSbCzs9ZBezkM4oaru4qBWtSJzyEpjKIdjGbIIFfORyGrA XP2/g+o1bpdBiHD4l4L8GiWRFJarRLqw8lYUPK5TK/aZc3W4lGUEEiE4EH76V4mIqVg7By AW7u5FzXexXib7yIbcCSsPpPirlDpOE= Received: from g8t13017g.inc.hp.com (g8t13017g.inc.hp.com [15.72.64.135]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-168-GrdOUHwCOLyxMv2YdaWF1Q-1; Tue, 01 Oct 2024 13:32:11 -0400 X-MC-Unique: GrdOUHwCOLyxMv2YdaWF1Q-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g8t13017g.inc.hp.com (Postfix) with ESMTPS id BAAA160008BE; Tue, 1 Oct 2024 17:32:10 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 4CB5D18; Tue, 1 Oct 2024 17:32:09 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Alexandru Gagniuc Subject: [PATCH 6.6 06/14] thunderbolt: Use weight constants in tb_usb3_consumed_bandwidth() Date: Tue, 1 Oct 2024 17:31:01 +0000 Message-Id: <20241001173109.1513-7-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Mika Westerberg [ Upstream commit 4d24db0c801461adeefd7e0bdc98c79c60ccefb0 ] Instead of magic numbers use the constants we introduced in the previous commit to make the code more readable. No functional changes. Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tunnel.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index 9947b9d0d51a..b81344c6c06a 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -1747,14 +1747,17 @@ static int tb_usb3_activate(struct tb_tunnel *tunnel, bool activate) static int tb_usb3_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, int *consumed_down) { - int pcie_enabled = tb_acpi_may_tunnel_pcie(); + int pcie_weight = tb_acpi_may_tunnel_pcie() ? TB_PCI_WEIGHT : 0; /* * PCIe tunneling, if enabled, affects the USB3 bandwidth so * take that it into account here. */ - *consumed_up = tunnel->allocated_up * (3 + pcie_enabled) / 3; - *consumed_down = tunnel->allocated_down * (3 + pcie_enabled) / 3; + *consumed_up = tunnel->allocated_up * + (TB_USB3_WEIGHT + pcie_weight) / TB_USB3_WEIGHT; + *consumed_down = tunnel->allocated_down * + (TB_USB3_WEIGHT + pcie_weight) / TB_USB3_WEIGHT; + return 0; } From patchwork Tue Oct 1 17:31:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832202 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.133.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F9F61CDA31 for ; Tue, 1 Oct 2024 17:32:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803938; cv=none; b=LCnKyPwJ83O966hG9sh1RhdC2V8cjYyz3XW41PkhJYv/CO2UqphnosAwxhX4pFxF/cvpmQZUa1b0BKbQ9ZmMWDG55IqxaMvWiU4TfNBtSN6JJU4V4n5h4JIvwHnhxzHRTMv5QoN6zsjDdp7okXKkvScRzit3PC6LAejSWuN6CsY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803938; c=relaxed/simple; bh=2ng+RV1VbPbxMmDv0Xm5/UVcAWuKCHRdeXUIR4phYZ4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=FN6Cd+DTgrDi9h5jow+8O/Gi09jQMPgaGEmQYuaCHcTdB+zSBl3BqK0WZXbNE5Y1U44HA6ZoiUuzesLwvx/5TrAsCdHZ18HYTXRnpKjwXYzjh85vouEntzWqQfuXEiaOtWCsBH7nV3q1bg3YIT0SjCWDzuMWMWC39sn/MGnfb2Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=Li+ZYDGm; arc=none smtp.client-ip=170.10.133.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="Li+ZYDGm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iJXCUAuPokK3CibSKfom0IbRsRkVfnieOynAhDn4f3Q=; b=Li+ZYDGmQ2GavKQRkfYeXb0b+robeYMVI4mHJyWJ60qhXIC6lzK6HfPjsXT2rWxn9JRBN8 Sr1hTJUNPdAj79Q3Hx0+yTOGMYdGAFzypNgZ5KnVNamg82ABPN6adg/uzXcWqqOKZQN9lV ncKPY0VxFCBQg0YFBFnMlzrrGr1zRjo= Received: from g8t13017g.inc.hp.com (hpi-bastion.austin2.mail.core.hp.com [15.72.64.135]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-548-JWTzcliXPGihSWoAhSSUmA-1; Tue, 01 Oct 2024 13:32:13 -0400 X-MC-Unique: JWTzcliXPGihSWoAhSSUmA-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g8t13017g.inc.hp.com (Postfix) with ESMTPS id 456866000DFA; Tue, 1 Oct 2024 17:32:12 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 8CBB41E; Tue, 1 Oct 2024 17:32:10 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Gil Fine , Alexandru Gagniuc Subject: [PATCH 6.6 07/14] thunderbolt: Make is_gen4_link() available to the rest of the driver Date: Tue, 1 Oct 2024 17:31:02 +0000 Message-Id: <20241001173109.1513-8-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Gil Fine [ Upstream commit aa673d606078da36ebc379f041c794228ac08cb5 ] Rework the function to return the link generation, update the name to tb_port_get_link_generation(), and make available to the rest of the driver. This is needed in the subsequent patches. Signed-off-by: Gil Fine Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/switch.c | 36 +++++++++++++++++++++++++++++------- drivers/thunderbolt/tb.h | 1 + 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index f9f40c0e9add..c7f16fd0a043 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -921,6 +921,32 @@ int tb_port_get_link_speed(struct tb_port *port) } } +/** + * tb_port_get_link_generation() - Returns link generation + * @port: Lane adapter + * + * Returns link generation as number or negative errno in case of + * failure. Does not distinguish between Thunderbolt 1 and Thunderbolt 2 + * links so for those always returns 2. + */ +int tb_port_get_link_generation(struct tb_port *port) +{ + int ret; + + ret = tb_port_get_link_speed(port); + if (ret < 0) + return ret; + + switch (ret) { + case 40: + return 4; + case 20: + return 3; + default: + return 2; + } +} + /** * tb_port_get_link_width() - Get current link width * @port: Port to check (USB4 or CIO) @@ -966,11 +992,6 @@ static bool tb_port_is_width_supported(struct tb_port *port, return widths & width_mask; } -static bool is_gen4_link(struct tb_port *port) -{ - return tb_port_get_link_speed(port) > 20; -} - /** * tb_port_set_link_width() - Set target link width of the lane adapter * @port: Lane adapter @@ -998,7 +1019,7 @@ int tb_port_set_link_width(struct tb_port *port, enum tb_link_width width) switch (width) { case TB_LINK_WIDTH_SINGLE: /* Gen 4 link cannot be single */ - if (is_gen4_link(port)) + if (tb_port_get_link_generation(port) >= 4) return -EOPNOTSUPP; val |= LANE_ADP_CS_1_TARGET_WIDTH_SINGLE << LANE_ADP_CS_1_TARGET_WIDTH_SHIFT; @@ -1147,7 +1168,8 @@ int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width_mask, int ret; /* Gen 4 link does not support single lane */ - if ((width_mask & TB_LINK_WIDTH_SINGLE) && is_gen4_link(port)) + if ((width_mask & TB_LINK_WIDTH_SINGLE) && + tb_port_get_link_generation(port) >= 4) return -EOPNOTSUPP; do { diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 8a75aabb9ce8..2f5f85666302 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1062,6 +1062,7 @@ static inline bool tb_port_use_credit_allocation(const struct tb_port *port) (p) = tb_next_port_on_path((src), (dst), (p))) int tb_port_get_link_speed(struct tb_port *port); +int tb_port_get_link_generation(struct tb_port *port); int tb_port_get_link_width(struct tb_port *port); int tb_port_set_link_width(struct tb_port *port, enum tb_link_width width); int tb_port_lane_bonding_enable(struct tb_port *port); From patchwork Tue Oct 1 17:31:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832701 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.129.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D46421CDA27 for ; Tue, 1 Oct 2024 17:32:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803939; cv=none; b=smjzeJeln2BmhC3DcJfQexSbTBi0+14S5DAyScx9tOvuVlChfr2Ew1MV/ikdNAFLAZyGRKdSVSQHn3J3kj7HUAB0+r7GwyBryGVafuzBx147nCVdPZ/HQUHWxTYO6XtBkvfYCzSFZhN+HVjmhP6HpbmQ8kW3reKuqIXIf4vOWc0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803939; c=relaxed/simple; bh=wD5UzNOGnwoP9ZSWg2h3fTpS7wT4w7eNnEoqlpkN8m8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=R0EW/9aSDPyPPkgT9DCOGaIaWWEWtCf3mhheeiPvqBjp81/h/pSPQFV8CnududchYysC4WiMWuOfG9altZ1o+idaRH/JK1iQrVMInnMVHaqv71u5MZB4u570wvoZgtpi0DgLBmKHoKB9js9r4lD5zbG2FiPbH8y49ePTPgT8Q4E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=b0yTpGv2; arc=none smtp.client-ip=170.10.129.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="b0yTpGv2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HzqaCbz4br+TId6QRJQ5oLRsFXW/A1tLqhS1ZmhX9J0=; b=b0yTpGv2AdHDqTg3mZ9GFJ7dZ8aho0wFTMbh9zYvPE9D1p/mS6Hu6EDPslkvxdi2+C+T/Y u9rrduZWsJ5eMpuTx9p9dyhPnVdEuFcTZiV23Y2RysnIt1DREJcYaDijGSHs13MymfLlsi cyzfS3qA/OXz48Hsv4jZ2g5MsT/HpQw= Received: from g7t16454g.inc.hp.com (hpifallback.mail.core.hp.com [15.73.128.143]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-665-onVi1qf5N7uGwN-3Q-fnWg-1; Tue, 01 Oct 2024 13:32:15 -0400 X-MC-Unique: onVi1qf5N7uGwN-3Q-fnWg-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g7t16454g.inc.hp.com (Postfix) with ESMTPS id B3E7A6000C06; Tue, 1 Oct 2024 17:32:13 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 146C818; Tue, 1 Oct 2024 17:32:11 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Gil Fine , Alexandru Gagniuc Subject: [PATCH 6.6 08/14] thunderbolt: Change bandwidth reservations to comply USB4 v2 Date: Tue, 1 Oct 2024 17:31:03 +0000 Message-Id: <20241001173109.1513-9-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Gil Fine [ Upstream commit 582e70b0d3a412d15389a3c9c07a44791b311715 ] USB4 v2 Connection Manager guide (section 6.1.2.3) suggests to reserve bandwidth in a sligthly different manner. It suggests to keep minimum of 1500 Mb/s for each path that carry a bulk traffic. Here we change the bandwidth reservations to comply to the above for USB 3.x and PCIe protocols over Gen 4 link, taking weights into account (that's 1500 Mb/s for PCIe and 3000 Mb/s for USB 3.x). For Gen 3 and below we use the existing reservation. Signed-off-by: Gil Fine Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tb.c | 11 ++++++ drivers/thunderbolt/tunnel.c | 66 ++++++++++++++++++++++++++++++++++-- drivers/thunderbolt/tunnel.h | 2 ++ 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index e37fb1081420..183225bdbbf5 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -602,6 +602,7 @@ static int tb_available_bandwidth(struct tb *tb, struct tb_port *src_port, /* Find the minimum available bandwidth over all links */ tb_for_each_port_on_path(src_port, dst_port, port) { int link_speed, link_width, up_bw, down_bw; + int pci_reserved_up, pci_reserved_down; if (!tb_port_is_null(port)) continue; @@ -695,6 +696,16 @@ static int tb_available_bandwidth(struct tb *tb, struct tb_port *src_port, up_bw -= usb3_consumed_up; down_bw -= usb3_consumed_down; + /* + * If there is anything reserved for PCIe bulk traffic + * take it into account here too. + */ + if (tb_tunnel_reserved_pci(port, &pci_reserved_up, + &pci_reserved_down)) { + up_bw -= pci_reserved_up; + down_bw -= pci_reserved_down; + } + if (up_bw < *available_up) *available_up = up_bw; if (down_bw < *available_down) diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index b81344c6c06a..e296ab5d657b 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -31,7 +31,7 @@ #define TB_USB3_PATH_UP 1 #define TB_USB3_PRIORITY 3 -#define TB_USB3_WEIGHT 3 +#define TB_USB3_WEIGHT 2 /* DP adapters use HopID 8 for AUX and 9 for Video */ #define TB_DP_AUX_TX_HOPID 8 @@ -61,6 +61,15 @@ #define TB_DMA_PRIORITY 5 #define TB_DMA_WEIGHT 1 +/* + * Reserve additional bandwidth for USB 3.x and PCIe bulk traffic + * according to USB4 v2 Connection Manager guide. This ends up reserving + * 1500 Mb/s for PCIe and 3000 Mb/s for USB 3.x taking weights into + * account. + */ +#define USB4_V2_PCI_MIN_BANDWIDTH (1500 * TB_PCI_WEIGHT) +#define USB4_V2_USB3_MIN_BANDWIDTH (1500 * TB_USB3_WEIGHT) + static unsigned int dma_credits = TB_DMA_CREDITS; module_param(dma_credits, uint, 0444); MODULE_PARM_DESC(dma_credits, "specify custom credits for DMA tunnels (default: " @@ -150,11 +159,11 @@ static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths, static int tb_pci_set_ext_encapsulation(struct tb_tunnel *tunnel, bool enable) { + struct tb_port *port = tb_upstream_port(tunnel->dst_port->sw); int ret; /* Only supported of both routers are at least USB4 v2 */ - if (usb4_switch_version(tunnel->src_port->sw) < 2 || - usb4_switch_version(tunnel->dst_port->sw) < 2) + if (tb_port_get_link_generation(port) < 4) return 0; ret = usb4_pci_port_set_ext_encapsulation(tunnel->src_port, enable); @@ -370,6 +379,51 @@ struct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up, return NULL; } +/** + * tb_tunnel_reserved_pci() - Amount of bandwidth to reserve for PCIe + * @port: Lane 0 adapter + * @reserved_up: Upstream bandwidth in Mb/s to reserve + * @reserved_down: Downstream bandwidth in Mb/s to reserve + * + * Can be called to any connected lane 0 adapter to find out how much + * bandwidth needs to be left in reserve for possible PCIe bulk traffic. + * Returns true if there is something to be reserved and writes the + * amount to @reserved_down/@reserved_up. Otherwise returns false and + * does not touch the parameters. + */ +bool tb_tunnel_reserved_pci(struct tb_port *port, int *reserved_up, + int *reserved_down) +{ + if (WARN_ON_ONCE(!port->remote)) + return false; + + if (!tb_acpi_may_tunnel_pcie()) + return false; + + if (tb_port_get_link_generation(port) < 4) + return false; + + /* Must have PCIe adapters */ + if (tb_is_upstream_port(port)) { + if (!tb_switch_find_port(port->sw, TB_TYPE_PCIE_UP)) + return false; + if (!tb_switch_find_port(port->remote->sw, TB_TYPE_PCIE_DOWN)) + return false; + } else { + if (!tb_switch_find_port(port->sw, TB_TYPE_PCIE_DOWN)) + return false; + if (!tb_switch_find_port(port->remote->sw, TB_TYPE_PCIE_UP)) + return false; + } + + *reserved_up = USB4_V2_PCI_MIN_BANDWIDTH; + *reserved_down = USB4_V2_PCI_MIN_BANDWIDTH; + + tb_port_dbg(port, "reserving %u/%u Mb/s for PCIe\n", *reserved_up, + *reserved_down); + return true; +} + static bool tb_dp_is_usb4(const struct tb_switch *sw) { /* Titan Ridge DP adapters need the same treatment as USB4 */ @@ -1747,6 +1801,7 @@ static int tb_usb3_activate(struct tb_tunnel *tunnel, bool activate) static int tb_usb3_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, int *consumed_down) { + struct tb_port *port = tb_upstream_port(tunnel->dst_port->sw); int pcie_weight = tb_acpi_may_tunnel_pcie() ? TB_PCI_WEIGHT : 0; /* @@ -1758,6 +1813,11 @@ static int tb_usb3_consumed_bandwidth(struct tb_tunnel *tunnel, *consumed_down = tunnel->allocated_down * (TB_USB3_WEIGHT + pcie_weight) / TB_USB3_WEIGHT; + if (tb_port_get_link_generation(port) >= 4) { + *consumed_up = max(*consumed_up, USB4_V2_USB3_MIN_BANDWIDTH); + *consumed_down = max(*consumed_down, USB4_V2_USB3_MIN_BANDWIDTH); + } + return 0; } diff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h index 750ebb570d99..b4cff5482112 100644 --- a/drivers/thunderbolt/tunnel.h +++ b/drivers/thunderbolt/tunnel.h @@ -80,6 +80,8 @@ struct tb_tunnel *tb_tunnel_discover_pci(struct tb *tb, struct tb_port *down, bool alloc_hopid); struct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up, struct tb_port *down); +bool tb_tunnel_reserved_pci(struct tb_port *port, int *reserved_up, + int *reserved_down); struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, bool alloc_hopid); struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, From patchwork Tue Oct 1 17:31:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832201 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.129.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 047661CDFB4 for ; Tue, 1 Oct 2024 17:32:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803939; cv=none; b=XuK06jbfbKVJiUH1EY4AwxHacZeZiLRu6+667opjx0iqb1Fc/qRSem231bx9741AvDslArhgs4HZ/wSYMTa11mjTTA/c16PcxLLOFak03GSTfIP81KHZMCYuv9p3b8SraorMcwcrYNwXC2P2IqdTnph5+lzsXH4+uFL6NDvkqPo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803939; c=relaxed/simple; bh=vvqaqbYxZyCCLWrD5t0qxu/3Bn5uWXKD6rgCCsrg+Wc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=aP3DDbGikh+qkxNck8GskZosXIZscz5kiwne8Ybv+yUSdzSUFEgF37WG8BzLJCTC3nJj/7idNAqD8ryepaycX7QDTbMpDxXLfDuNzFfuK8P5F4Q1JCI4bYFgkI2/FpZnDANHKXvup1kvpeG7yyyqxtvzBI6tEtUivs4K7ZCYey8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=HdpR7uB0; arc=none smtp.client-ip=170.10.129.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="HdpR7uB0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803937; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ch5qqPD68czI4VQ55H/x4IwmJfUibR6hfTWfzqJbV2Y=; b=HdpR7uB053DAvPf2IzZnHrT756OipZUHivtNMuP2sEvUrb3DsyBPdCdSjlWgMdRx7qpdqF xkNMwar42v7uVJtdVOo+hgyBDrp32s8wzdsYNw8PLCT1ol44BRlFgKR3NvwQ6T/pD/zCa6 a6eZob+nQZdpUodGy9t8fWyQEtgyR18= Received: from g7t16451g.inc.hp.com (hpifallback.mail.core.hp.com [15.73.128.137]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-661-4zLU7p1sMCGRT1V_T3Hzwg-1; Tue, 01 Oct 2024 13:32:16 -0400 X-MC-Unique: 4zLU7p1sMCGRT1V_T3Hzwg-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g7t16451g.inc.hp.com (Postfix) with ESMTPS id 3282160000B2; Tue, 1 Oct 2024 17:32:15 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 92ED220; Tue, 1 Oct 2024 17:32:13 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Gil Fine , Alexandru Gagniuc Subject: [PATCH 6.6 09/14] thunderbolt: Introduce tb_port_path_direction_downstream() Date: Tue, 1 Oct 2024 17:31:04 +0000 Message-Id: <20241001173109.1513-10-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Gil Fine [ Upstream commit 2bfeca73e94567c1a117ca45d2e8a25d63e5bd2c ] Introduce tb_port_path_direction_downstream() to check if path from source adapter to destination adapter is directed towards downstream. Convert existing users to call this helper instead of open-coding. No functional changes. Signed-off-by: Gil Fine Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tb.c | 6 +++--- drivers/thunderbolt/tb.h | 15 +++++++++++++++ drivers/thunderbolt/tunnel.c | 14 +++++++------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 183225bdbbf5..4ea0536ec5cf 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -553,7 +553,7 @@ static struct tb_tunnel *tb_find_first_usb3_tunnel(struct tb *tb, struct tb_switch *sw; /* Pick the router that is deepest in the topology */ - if (dst_port->sw->config.depth > src_port->sw->config.depth) + if (tb_port_path_direction_downstream(src_port, dst_port)) sw = dst_port->sw; else sw = src_port->sw; @@ -1223,7 +1223,7 @@ tb_recalc_estimated_bandwidth_for_group(struct tb_bandwidth_group *group) tb_port_dbg(in, "re-calculated estimated bandwidth %u/%u Mb/s\n", estimated_up, estimated_down); - if (in->sw->config.depth < out->sw->config.depth) + if (tb_port_path_direction_downstream(in, out)) estimated_bw = estimated_down; else estimated_bw = estimated_up; @@ -2002,7 +2002,7 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work) out = tunnel->dst_port; - if (in->sw->config.depth < out->sw->config.depth) { + if (tb_port_path_direction_downstream(in, out)) { requested_up = -1; requested_down = requested_bw; } else { diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 2f5f85666302..6d66dd2a3ab0 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1044,6 +1044,21 @@ void tb_port_release_out_hopid(struct tb_port *port, int hopid); struct tb_port *tb_next_port_on_path(struct tb_port *start, struct tb_port *end, struct tb_port *prev); +/** + * tb_port_path_direction_downstream() - Checks if path directed downstream + * @src: Source adapter + * @dst: Destination adapter + * + * Returns %true only if the specified path from source adapter (@src) + * to destination adapter (@dst) is directed downstream. + */ +static inline bool +tb_port_path_direction_downstream(const struct tb_port *src, + const struct tb_port *dst) +{ + return src->sw->config.depth < dst->sw->config.depth; +} + static inline bool tb_port_use_credit_allocation(const struct tb_port *port) { return tb_port_is_null(port) && port->sw->credit_allocation; diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index e296ab5d657b..8aec678d80d3 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -677,7 +677,7 @@ static int tb_dp_xchg_caps(struct tb_tunnel *tunnel) "DP OUT maximum supported bandwidth %u Mb/s x%u = %u Mb/s\n", out_rate, out_lanes, bw); - if (in->sw->config.depth < out->sw->config.depth) + if (tb_port_path_direction_downstream(in, out)) max_bw = tunnel->max_down; else max_bw = tunnel->max_up; @@ -802,7 +802,7 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel) * max_up/down fields. For discovery we just read what the * estimation was set to. */ - if (in->sw->config.depth < out->sw->config.depth) + if (tb_port_path_direction_downstream(in, out)) estimated_bw = tunnel->max_down; else estimated_bw = tunnel->max_up; @@ -972,7 +972,7 @@ static int tb_dp_bandwidth_mode_consumed_bandwidth(struct tb_tunnel *tunnel, if (allocated_bw == max_bw) allocated_bw = ret; - if (in->sw->config.depth < out->sw->config.depth) { + if (tb_port_path_direction_downstream(in, out)) { *consumed_up = 0; *consumed_down = allocated_bw; } else { @@ -1007,7 +1007,7 @@ static int tb_dp_allocated_bandwidth(struct tb_tunnel *tunnel, int *allocated_up if (allocated_bw == max_bw) allocated_bw = ret; - if (in->sw->config.depth < out->sw->config.depth) { + if (tb_port_path_direction_downstream(in, out)) { *allocated_up = 0; *allocated_down = allocated_bw; } else { @@ -1035,7 +1035,7 @@ static int tb_dp_alloc_bandwidth(struct tb_tunnel *tunnel, int *alloc_up, if (ret < 0) return ret; - if (in->sw->config.depth < out->sw->config.depth) { + if (tb_port_path_direction_downstream(in, out)) { tmp = min(*alloc_down, max_bw); ret = usb4_dp_port_allocate_bandwidth(in, tmp); if (ret) @@ -1133,7 +1133,7 @@ static int tb_dp_maximum_bandwidth(struct tb_tunnel *tunnel, int *max_up, if (ret < 0) return ret; - if (in->sw->config.depth < tunnel->dst_port->sw->config.depth) { + if (tb_port_path_direction_downstream(in, tunnel->dst_port)) { *max_up = 0; *max_down = ret; } else { @@ -1191,7 +1191,7 @@ static int tb_dp_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, return 0; } - if (in->sw->config.depth < tunnel->dst_port->sw->config.depth) { + if (tb_port_path_direction_downstream(in, tunnel->dst_port)) { *consumed_up = 0; *consumed_down = tb_dp_bandwidth(rate, lanes); } else { From patchwork Tue Oct 1 17:31:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832700 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.133.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 682A01CDFDB for ; Tue, 1 Oct 2024 17:32:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803941; cv=none; b=GxmXwoXQ/73bShPLlJrOQiTmQWLUAttgvPLkZSNbYrv6of+2qYsNLLdnqnV+fwPYOB7U9bs+Kui/WhAAuveKAnak73QL9dOWAkCmIu6w9PivzXDv5HhDZ89TqZnPe+2ln/czTGzbjGP7eV7aRQzxreRs9QA47Ln9BDKHoEAXR0I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803941; c=relaxed/simple; bh=s6/akAZsgWqiuMk26sEf6V9ItVqhVmu5+dG+4vYNaXg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=azu9D71MonRafoiThOBg8Dwq+orBKSefYaKAO2FBYoYpk0TtYkJfQI0UdUt4jjuGFd2lgElICph+1/RWuH5JFBGkfVhGpLhzwJwybqA4Yi0gTSUTv9pZwysQW9JX3MgbB6em5+Y8SavxnFOTxhBGtkp9458j6Aj+U4G7boGEiGI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=foh8QRdN; arc=none smtp.client-ip=170.10.133.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="foh8QRdN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803938; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pq/Dm2clE4lZ83DOiVWYmNMrV36eWwjNAXhOWGGYXak=; b=foh8QRdNk422SJ1Ia8qOfeucQi8UpqrEVF0lhhBw3C8/onuNH8Am7cuXZFpuETwxwps1d3 f6nYcW81Oiik/kLrWOMPHy2OV8mWgF0ca+7e1eB6bdAT5ez94LJkHSvMscpycM95RaEzEj GmK01svyTCuyxaw7IMvnXxANiWhu0x4= Received: from g8t13016g.inc.hp.com (hpifallback.mail.core.hp.com [15.72.64.134]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-364-XyXImHsdPT-O_3v_vPRZnw-1; Tue, 01 Oct 2024 13:32:17 -0400 X-MC-Unique: XyXImHsdPT-O_3v_vPRZnw-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g8t13016g.inc.hp.com (Postfix) with ESMTPS id 7362F600021C; Tue, 1 Oct 2024 17:32:16 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 1371A18; Tue, 1 Oct 2024 17:32:14 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Alexandru Gagniuc Subject: [PATCH 6.6 10/14] thunderbolt: Introduce tb_for_each_upstream_port_on_path() Date: Tue, 1 Oct 2024 17:31:05 +0000 Message-Id: <20241001173109.1513-11-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Mika Westerberg [ Upstream commit 956c3abe72fb6a651b8cf77c28462f7e5b6a48b1 ] This is useful when walking over upstream lane adapters over given path. Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tb.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 6d66dd2a3ab0..4cd5f48e3dee 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1076,6 +1076,21 @@ static inline bool tb_port_use_credit_allocation(const struct tb_port *port) for ((p) = tb_next_port_on_path((src), (dst), NULL); (p); \ (p) = tb_next_port_on_path((src), (dst), (p))) +/** + * tb_for_each_upstream_port_on_path() - Iterate over each upstreamm port on path + * @src: Source port + * @dst: Destination port + * @p: Port used as iterator + * + * Walks over each upstream lane adapter on path from @src to @dst. + */ +#define tb_for_each_upstream_port_on_path(src, dst, p) \ + for ((p) = tb_next_port_on_path((src), (dst), NULL); (p); \ + (p) = tb_next_port_on_path((src), (dst), (p))) \ + if (!tb_port_is_null((p)) || !tb_is_upstream_port((p))) {\ + continue; \ + } else + int tb_port_get_link_speed(struct tb_port *port); int tb_port_get_link_generation(struct tb_port *port); int tb_port_get_link_width(struct tb_port *port); From patchwork Tue Oct 1 17:31:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832200 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.133.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80DEE1CEAC1 for ; Tue, 1 Oct 2024 17:32:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803942; cv=none; b=DfSoZRaaZmxzE0dLzYERxWV1AGWrHKm7R/LL7uSGOM8r/t/D8uYHgJCbdyQgjkym4Sv9i76d7gwz3wg/B0KnpNJjL+AcjbwkZOO9uyBc+OJcZsrZi5wLFEhXje/ZhrwjVS++X42Hu4jHhpUh4ouxPrs++CR/oyjuhPaeVs1b5WI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803942; c=relaxed/simple; bh=E1zRdRY7CREGHcB8DQSWRV+OAnZp8YYwBtEFQ7UBRX4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=s7FfZldB4cljjHf4EyOowMfIwwmmXI3FfK2sNNRvpv18KPqM2wE0OwVNIk27LBPv8jJFUTjvc2u7xA0kmZdDLAr2Qc7XfxQHjRM3q84gwRBbw6BjlnKnR4p9xWMc6Bxg0amW9GaFP5X0FR6rwKHymZlvr8CjeNvkvza90ufwNFY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=NsJC86Af; arc=none smtp.client-ip=170.10.133.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="NsJC86Af" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803939; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=E1zRdRY7CREGHcB8DQSWRV+OAnZp8YYwBtEFQ7UBRX4=; b=NsJC86Af5JQkuGsmgNoYXSNbEj2rjUdGdEv/Ev3bVtq+hUIth7/fti6W8HuQfbEyVdh5Gt DReaYY02CDEj7I4WGO5k/Liv6Kw67BjT10RmleyGLa5lOhnSXIshrUboq/p6EB9WWKMZYw kS9Cs0rFlOdBTgyjKY8yJMvrKLSXs8g= Received: from g8t13016g.inc.hp.com (g8t13016g.inc.hp.com [15.72.64.134]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-508-KUgP6ZiFNtm5Mpq2zu-GLA-1; Tue, 01 Oct 2024 13:32:18 -0400 X-MC-Unique: KUgP6ZiFNtm5Mpq2zu-GLA-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g8t13016g.inc.hp.com (Postfix) with ESMTPS id 9BFE76000FE9; Tue, 1 Oct 2024 17:32:17 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 446371E; Tue, 1 Oct 2024 17:32:16 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Alexandru Gagniuc Subject: [PATCH 6.6 11/14] thunderbolt: Introduce tb_switch_depth() Date: Tue, 1 Oct 2024 17:31:06 +0000 Message-Id: <20241001173109.1513-12-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Mika Westerberg [ Upstream commit c4ff14436952c3d0dd05769d76cf48e73a253b48 ] This is useful helper to find out the depth of a connected router. Convert the existing users to call this helper instead of open-coding. No functional changes. Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tb.c | 4 ++-- drivers/thunderbolt/tb.h | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 4ea0536ec5cf..39ec8da576ef 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -255,13 +255,13 @@ static int tb_enable_clx(struct tb_switch *sw) * this in the future to cover the whole topology if it turns * out to be beneficial. */ - while (sw && sw->config.depth > 1) + while (sw && tb_switch_depth(sw) > 1) sw = tb_switch_parent(sw); if (!sw) return 0; - if (sw->config.depth != 1) + if (tb_switch_depth(sw) != 1) return 0; /* diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 4cd5f48e3dee..d2ef9575231c 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -868,6 +868,15 @@ static inline struct tb_port *tb_switch_downstream_port(struct tb_switch *sw) return tb_port_at(tb_route(sw), tb_switch_parent(sw)); } +/** + * tb_switch_depth() - Returns depth of the connected router + * @sw: Router + */ +static inline int tb_switch_depth(const struct tb_switch *sw) +{ + return sw->config.depth; +} + static inline bool tb_switch_is_light_ridge(const struct tb_switch *sw) { return sw->config.vendor_id == PCI_VENDOR_ID_INTEL && From patchwork Tue Oct 1 17:31:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832699 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.129.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD56A1CEE89 for ; Tue, 1 Oct 2024 17:32:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803944; cv=none; b=Rntz4WWRh8LozTCGjiezMqxKJaZnO6bBRsI10rS2r4t7vYOGrr5qKhX9eR0tpyA0a0P7sp6PZgQgkMcjXDvIVj8L5YxwlbNQI0+QvWJ5IIJIcFaTepWZrQtvppdu2GCd9ZZnpmGDKbaOQ03lyTi000frQ56/6MFw+6ZN2KKfPbM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803944; c=relaxed/simple; bh=o2lbj287EJsRj7sQHip58MRo9G/2DFfFjfeXt6sr9+Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=cDr3kqqQ9YGXwIRweCs4tZR4czmP3D0wrkxaqfSN7MnUufLWOBKMB6IXzpxJDziy1prccnThAor1exQ6O4whVBPD4hWXW+XvuRDJ/VshkHxXI2NL6IApJN44591O8ZHq0p1ZC10qXIK2O0pB3o+LsJxcO8zoenhgrd57/IvFEU4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=ZpD5hmcs; arc=none smtp.client-ip=170.10.129.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="ZpD5hmcs" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803941; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=we2/gdzQ7DJTwX/x8DaC/A7w8CojI9uOFEjYiTZJppk=; b=ZpD5hmcspifh7SDTnw3Ab/rhmrTulbyzDGYhJZA81IO6sm9psuSeeu3Px54K7IR29WcP5a GOmNTA0msCP4x4j493nBMQKli/jQBUAnBiggJvPh7o2C9HdGJijYy5smig0XMmVOY/V5cv JcdBqJRS4LHDx0o08Bcz8nIk65jsOmc= Received: from g7t16454g.inc.hp.com (hpifallback.mail.core.hp.com [15.73.128.143]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-681-YhyUp16wMMamEyq0VKFiVg-1; Tue, 01 Oct 2024 13:32:20 -0400 X-MC-Unique: YhyUp16wMMamEyq0VKFiVg-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g7t16454g.inc.hp.com (Postfix) with ESMTPS id 12C476000C06; Tue, 1 Oct 2024 17:32:19 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 70A3118; Tue, 1 Oct 2024 17:32:17 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Gil Fine , Alexandru Gagniuc Subject: [PATCH 6.6 12/14] thunderbolt: Add support for asymmetric link Date: Tue, 1 Oct 2024 17:31:07 +0000 Message-Id: <20241001173109.1513-13-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Gil Fine [ Upstream commit 81af2952e60603d12415e1a6fd200f8073a2ad8b ] USB4 v2 spec defines a Gen 4 link that can operate as an aggregated symmetric (80/80G) or asymmetric (120/40G). When the link is asymmetric, the USB4 port on one side of the link operates with three TX lanes and one RX lane, while the USB4 port on the opposite side of the link operates with three RX lanes and one TX lane. Add support for the asymmetric link and provide functions that can be used to transition the link to asymmetric and back. Signed-off-by: Gil Fine Co-developed-by: Mika Westerberg Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/switch.c | 294 +++++++++++++++++++++++++++++----- drivers/thunderbolt/tb.c | 11 +- drivers/thunderbolt/tb.h | 16 +- drivers/thunderbolt/tb_regs.h | 9 +- drivers/thunderbolt/usb4.c | 106 ++++++++++++ 5 files changed, 381 insertions(+), 55 deletions(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index c7f16fd0a043..6393ce44c253 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -947,6 +947,22 @@ int tb_port_get_link_generation(struct tb_port *port) } } +static const char *width_name(enum tb_link_width width) +{ + switch (width) { + case TB_LINK_WIDTH_SINGLE: + return "symmetric, single lane"; + case TB_LINK_WIDTH_DUAL: + return "symmetric, dual lanes"; + case TB_LINK_WIDTH_ASYM_TX: + return "asymmetric, 3 transmitters, 1 receiver"; + case TB_LINK_WIDTH_ASYM_RX: + return "asymmetric, 3 receivers, 1 transmitter"; + default: + return "unknown"; + } +} + /** * tb_port_get_link_width() - Get current link width * @port: Port to check (USB4 or CIO) @@ -972,8 +988,15 @@ int tb_port_get_link_width(struct tb_port *port) LANE_ADP_CS_1_CURRENT_WIDTH_SHIFT; } -static bool tb_port_is_width_supported(struct tb_port *port, - unsigned int width_mask) +/** + * tb_port_width_supported() - Is the given link width supported + * @port: Port to check + * @width: Widths to check (bitmask) + * + * Can be called to any lane adapter. Checks if given @width is + * supported by the hardware and returns %true if it is. + */ +bool tb_port_width_supported(struct tb_port *port, unsigned int width) { u32 phy, widths; int ret; @@ -981,15 +1004,23 @@ static bool tb_port_is_width_supported(struct tb_port *port, if (!port->cap_phy) return false; + if (width & (TB_LINK_WIDTH_ASYM_TX | TB_LINK_WIDTH_ASYM_RX)) { + if (tb_port_get_link_generation(port) < 4 || + !usb4_port_asym_supported(port)) + return false; + } + ret = tb_port_read(port, &phy, TB_CFG_PORT, port->cap_phy + LANE_ADP_CS_0, 1); if (ret) return false; - widths = (phy & LANE_ADP_CS_0_SUPPORTED_WIDTH_MASK) >> - LANE_ADP_CS_0_SUPPORTED_WIDTH_SHIFT; - - return widths & width_mask; + /* + * The field encoding is the same as &enum tb_link_width (which is + * passed to @width). + */ + widths = FIELD_GET(LANE_ADP_CS_0_SUPPORTED_WIDTH_MASK, phy); + return widths & width; } /** @@ -1024,10 +1055,18 @@ int tb_port_set_link_width(struct tb_port *port, enum tb_link_width width) val |= LANE_ADP_CS_1_TARGET_WIDTH_SINGLE << LANE_ADP_CS_1_TARGET_WIDTH_SHIFT; break; + case TB_LINK_WIDTH_DUAL: + if (tb_port_get_link_generation(port) >= 4) + return usb4_port_asym_set_link_width(port, width); val |= LANE_ADP_CS_1_TARGET_WIDTH_DUAL << LANE_ADP_CS_1_TARGET_WIDTH_SHIFT; break; + + case TB_LINK_WIDTH_ASYM_TX: + case TB_LINK_WIDTH_ASYM_RX: + return usb4_port_asym_set_link_width(port, width); + default: return -EINVAL; } @@ -1152,7 +1191,7 @@ void tb_port_lane_bonding_disable(struct tb_port *port) /** * tb_port_wait_for_link_width() - Wait until link reaches specific width * @port: Port to wait for - * @width_mask: Expected link width mask + * @width: Expected link width (bitmask) * @timeout_msec: Timeout in ms how long to wait * * Should be used after both ends of the link have been bonded (or @@ -1161,14 +1200,14 @@ void tb_port_lane_bonding_disable(struct tb_port *port) * within the given timeout, %0 if it did. Can be passed a mask of * expected widths and succeeds if any of the widths is reached. */ -int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width_mask, +int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width, int timeout_msec) { ktime_t timeout = ktime_add_ms(ktime_get(), timeout_msec); int ret; /* Gen 4 link does not support single lane */ - if ((width_mask & TB_LINK_WIDTH_SINGLE) && + if ((width & TB_LINK_WIDTH_SINGLE) && tb_port_get_link_generation(port) >= 4) return -EOPNOTSUPP; @@ -1182,7 +1221,7 @@ int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width_mask, */ if (ret != -EACCES) return ret; - } else if (ret & width_mask) { + } else if (ret & width) { return 0; } @@ -2821,6 +2860,38 @@ static int tb_switch_update_link_attributes(struct tb_switch *sw) return 0; } +/* Must be called after tb_switch_update_link_attributes() */ +static void tb_switch_link_init(struct tb_switch *sw) +{ + struct tb_port *up, *down; + bool bonded; + + if (!tb_route(sw) || tb_switch_is_icm(sw)) + return; + + tb_sw_dbg(sw, "current link speed %u.0 Gb/s\n", sw->link_speed); + tb_sw_dbg(sw, "current link width %s\n", width_name(sw->link_width)); + + bonded = sw->link_width >= TB_LINK_WIDTH_DUAL; + + /* + * Gen 4 links come up as bonded so update the port structures + * accordingly. + */ + up = tb_upstream_port(sw); + down = tb_switch_downstream_port(sw); + + up->bonded = bonded; + if (up->dual_link_port) + up->dual_link_port->bonded = bonded; + tb_port_update_credits(up); + + down->bonded = bonded; + if (down->dual_link_port) + down->dual_link_port->bonded = bonded; + tb_port_update_credits(down); +} + /** * tb_switch_lane_bonding_enable() - Enable lane bonding * @sw: Switch to enable lane bonding @@ -2829,24 +2900,20 @@ static int tb_switch_update_link_attributes(struct tb_switch *sw) * switch. If conditions are correct and both switches support the feature, * lanes are bonded. It is safe to call this to any switch. */ -int tb_switch_lane_bonding_enable(struct tb_switch *sw) +static int tb_switch_lane_bonding_enable(struct tb_switch *sw) { struct tb_port *up, *down; - u64 route = tb_route(sw); - unsigned int width_mask; + unsigned int width; int ret; - if (!route) - return 0; - if (!tb_switch_lane_bonding_possible(sw)) return 0; up = tb_upstream_port(sw); down = tb_switch_downstream_port(sw); - if (!tb_port_is_width_supported(up, TB_LINK_WIDTH_DUAL) || - !tb_port_is_width_supported(down, TB_LINK_WIDTH_DUAL)) + if (!tb_port_width_supported(up, TB_LINK_WIDTH_DUAL) || + !tb_port_width_supported(down, TB_LINK_WIDTH_DUAL)) return 0; /* @@ -2870,21 +2937,10 @@ int tb_switch_lane_bonding_enable(struct tb_switch *sw) } /* Any of the widths are all bonded */ - width_mask = TB_LINK_WIDTH_DUAL | TB_LINK_WIDTH_ASYM_TX | - TB_LINK_WIDTH_ASYM_RX; + width = TB_LINK_WIDTH_DUAL | TB_LINK_WIDTH_ASYM_TX | + TB_LINK_WIDTH_ASYM_RX; - ret = tb_port_wait_for_link_width(down, width_mask, 100); - if (ret) { - tb_port_warn(down, "timeout enabling lane bonding\n"); - return ret; - } - - tb_port_update_credits(down); - tb_port_update_credits(up); - tb_switch_update_link_attributes(sw); - - tb_sw_dbg(sw, "lane bonding enabled\n"); - return ret; + return tb_port_wait_for_link_width(down, width, 100); } /** @@ -2894,20 +2950,27 @@ int tb_switch_lane_bonding_enable(struct tb_switch *sw) * Disables lane bonding between @sw and parent. This can be called even * if lanes were not bonded originally. */ -void tb_switch_lane_bonding_disable(struct tb_switch *sw) +static int tb_switch_lane_bonding_disable(struct tb_switch *sw) { struct tb_port *up, *down; int ret; - if (!tb_route(sw)) - return; - up = tb_upstream_port(sw); if (!up->bonded) - return; + return 0; - down = tb_switch_downstream_port(sw); + /* + * If the link is Gen 4 there is no way to switch the link to + * two single lane links so avoid that here. Also don't bother + * if the link is not up anymore (sw is unplugged). + */ + ret = tb_port_get_link_generation(up); + if (ret < 0) + return ret; + if (ret >= 4) + return -EOPNOTSUPP; + down = tb_switch_downstream_port(sw); tb_port_lane_bonding_disable(up); tb_port_lane_bonding_disable(down); @@ -2915,15 +2978,160 @@ void tb_switch_lane_bonding_disable(struct tb_switch *sw) * It is fine if we get other errors as the router might have * been unplugged. */ - ret = tb_port_wait_for_link_width(down, TB_LINK_WIDTH_SINGLE, 100); - if (ret == -ETIMEDOUT) - tb_sw_warn(sw, "timeout disabling lane bonding\n"); + return tb_port_wait_for_link_width(down, TB_LINK_WIDTH_SINGLE, 100); +} + +static int tb_switch_asym_enable(struct tb_switch *sw, enum tb_link_width width) +{ + struct tb_port *up, *down, *port; + enum tb_link_width down_width; + int ret; + + up = tb_upstream_port(sw); + down = tb_switch_downstream_port(sw); + + if (width == TB_LINK_WIDTH_ASYM_TX) { + down_width = TB_LINK_WIDTH_ASYM_RX; + port = down; + } else { + down_width = TB_LINK_WIDTH_ASYM_TX; + port = up; + } + + ret = tb_port_set_link_width(up, width); + if (ret) + return ret; + + ret = tb_port_set_link_width(down, down_width); + if (ret) + return ret; + + /* + * Initiate the change in the router that one of its TX lanes is + * changing to RX but do so only if there is an actual change. + */ + if (sw->link_width != width) { + ret = usb4_port_asym_start(port); + if (ret) + return ret; + + ret = tb_port_wait_for_link_width(up, width, 100); + if (ret) + return ret; + } + + sw->link_width = width; + return 0; +} + +static int tb_switch_asym_disable(struct tb_switch *sw) +{ + struct tb_port *up, *down; + int ret; + + up = tb_upstream_port(sw); + down = tb_switch_downstream_port(sw); + + ret = tb_port_set_link_width(up, TB_LINK_WIDTH_DUAL); + if (ret) + return ret; + + ret = tb_port_set_link_width(down, TB_LINK_WIDTH_DUAL); + if (ret) + return ret; + + /* + * Initiate the change in the router that has three TX lanes and + * is changing one of its TX lanes to RX but only if there is a + * change in the link width. + */ + if (sw->link_width > TB_LINK_WIDTH_DUAL) { + if (sw->link_width == TB_LINK_WIDTH_ASYM_TX) + ret = usb4_port_asym_start(up); + else + ret = usb4_port_asym_start(down); + if (ret) + return ret; + + ret = tb_port_wait_for_link_width(up, TB_LINK_WIDTH_DUAL, 100); + if (ret) + return ret; + } + + sw->link_width = TB_LINK_WIDTH_DUAL; + return 0; +} + +/** + * tb_switch_set_link_width() - Configure router link width + * @sw: Router to configure + * @width: The new link width + * + * Set device router link width to @width from router upstream port + * perspective. Supports also asymmetric links if the routers boths side + * of the link supports it. + * + * Does nothing for host router. + * + * Returns %0 in case of success, negative errno otherwise. + */ +int tb_switch_set_link_width(struct tb_switch *sw, enum tb_link_width width) +{ + struct tb_port *up, *down; + int ret = 0; + + if (!tb_route(sw)) + return 0; + + up = tb_upstream_port(sw); + down = tb_switch_downstream_port(sw); + + switch (width) { + case TB_LINK_WIDTH_SINGLE: + ret = tb_switch_lane_bonding_disable(sw); + break; + + case TB_LINK_WIDTH_DUAL: + if (sw->link_width == TB_LINK_WIDTH_ASYM_TX || + sw->link_width == TB_LINK_WIDTH_ASYM_RX) { + ret = tb_switch_asym_disable(sw); + if (ret) + break; + } + ret = tb_switch_lane_bonding_enable(sw); + break; + + case TB_LINK_WIDTH_ASYM_TX: + case TB_LINK_WIDTH_ASYM_RX: + ret = tb_switch_asym_enable(sw, width); + break; + } + + switch (ret) { + case 0: + break; + + case -ETIMEDOUT: + tb_sw_warn(sw, "timeout changing link width\n"); + return ret; + + case -ENOTCONN: + case -EOPNOTSUPP: + case -ENODEV: + return ret; + + default: + tb_sw_dbg(sw, "failed to change link width: %d\n", ret); + return ret; + } tb_port_update_credits(down); tb_port_update_credits(up); + tb_switch_update_link_attributes(sw); - tb_sw_dbg(sw, "lane bonding disabled\n"); + tb_sw_dbg(sw, "link width set to %s\n", width_name(width)); + return ret; } /** @@ -3090,6 +3298,8 @@ int tb_switch_add(struct tb_switch *sw) if (ret) return ret; + tb_switch_link_init(sw); + ret = tb_switch_clx_init(sw); if (ret) return ret; diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 39ec8da576ef..550f1c9a1170 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -985,7 +985,7 @@ static void tb_scan_port(struct tb_port *port) } /* Enable lane bonding if supported */ - tb_switch_lane_bonding_enable(sw); + tb_switch_set_link_width(sw, TB_LINK_WIDTH_DUAL); /* Set the link configured */ tb_switch_configure_link(sw); /* @@ -1103,7 +1103,8 @@ static void tb_free_unplugged_children(struct tb_switch *sw) tb_retimer_remove_all(port); tb_remove_dp_resources(port->remote->sw); tb_switch_unconfigure_link(port->remote->sw); - tb_switch_lane_bonding_disable(port->remote->sw); + tb_switch_set_link_width(port->remote->sw, + TB_LINK_WIDTH_SINGLE); tb_switch_remove(port->remote->sw); port->remote = NULL; if (port->dual_link_port) @@ -1766,7 +1767,8 @@ static void tb_handle_hotplug(struct work_struct *work) tb_remove_dp_resources(port->remote->sw); tb_switch_tmu_disable(port->remote->sw); tb_switch_unconfigure_link(port->remote->sw); - tb_switch_lane_bonding_disable(port->remote->sw); + tb_switch_set_link_width(port->remote->sw, + TB_LINK_WIDTH_SINGLE); tb_switch_remove(port->remote->sw); port->remote = NULL; if (port->dual_link_port) @@ -2258,7 +2260,8 @@ static void tb_restore_children(struct tb_switch *sw) continue; if (port->remote) { - tb_switch_lane_bonding_enable(port->remote->sw); + tb_switch_set_link_width(port->remote->sw, + port->remote->sw->link_width); tb_switch_configure_link(port->remote->sw); tb_restore_children(port->remote->sw); diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index d2ef9575231c..920dac8a63e1 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -164,11 +164,6 @@ struct tb_switch_tmu { * switches) you need to have domain lock held. * * In USB4 terminology this structure represents a router. - * - * Note @link_width is not the same as whether link is bonded or not. - * For Gen 4 links the link is also bonded when it is asymmetric. The - * correct way to find out whether the link is bonded or not is to look - * @bonded field of the upstream port. */ struct tb_switch { struct device dev; @@ -969,8 +964,7 @@ static inline bool tb_switch_is_icm(const struct tb_switch *sw) return !sw->config.enabled; } -int tb_switch_lane_bonding_enable(struct tb_switch *sw); -void tb_switch_lane_bonding_disable(struct tb_switch *sw); +int tb_switch_set_link_width(struct tb_switch *sw, enum tb_link_width width); int tb_switch_configure_link(struct tb_switch *sw); void tb_switch_unconfigure_link(struct tb_switch *sw); @@ -1103,10 +1097,11 @@ static inline bool tb_port_use_credit_allocation(const struct tb_port *port) int tb_port_get_link_speed(struct tb_port *port); int tb_port_get_link_generation(struct tb_port *port); int tb_port_get_link_width(struct tb_port *port); +bool tb_port_width_supported(struct tb_port *port, unsigned int width); int tb_port_set_link_width(struct tb_port *port, enum tb_link_width width); int tb_port_lane_bonding_enable(struct tb_port *port); void tb_port_lane_bonding_disable(struct tb_port *port); -int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width_mask, +int tb_port_wait_for_link_width(struct tb_port *port, unsigned int width, int timeout_msec); int tb_port_update_credits(struct tb_port *port); @@ -1304,6 +1299,11 @@ int usb4_port_router_online(struct tb_port *port); int usb4_port_enumerate_retimers(struct tb_port *port); bool usb4_port_clx_supported(struct tb_port *port); int usb4_port_margining_caps(struct tb_port *port, u32 *caps); + +bool usb4_port_asym_supported(struct tb_port *port); +int usb4_port_asym_set_link_width(struct tb_port *port, enum tb_link_width width); +int usb4_port_asym_start(struct tb_port *port); + int usb4_port_hw_margin(struct tb_port *port, unsigned int lanes, unsigned int ber_level, bool timing, bool right_high, u32 *results); diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h index 736e28beac11..4419e274d2b4 100644 --- a/drivers/thunderbolt/tb_regs.h +++ b/drivers/thunderbolt/tb_regs.h @@ -348,10 +348,14 @@ struct tb_regs_port_header { #define LANE_ADP_CS_1 0x01 #define LANE_ADP_CS_1_TARGET_SPEED_MASK GENMASK(3, 0) #define LANE_ADP_CS_1_TARGET_SPEED_GEN3 0xc -#define LANE_ADP_CS_1_TARGET_WIDTH_MASK GENMASK(9, 4) +#define LANE_ADP_CS_1_TARGET_WIDTH_MASK GENMASK(5, 4) #define LANE_ADP_CS_1_TARGET_WIDTH_SHIFT 4 #define LANE_ADP_CS_1_TARGET_WIDTH_SINGLE 0x1 #define LANE_ADP_CS_1_TARGET_WIDTH_DUAL 0x3 +#define LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK GENMASK(7, 6) +#define LANE_ADP_CS_1_TARGET_WIDTH_ASYM_TX 0x1 +#define LANE_ADP_CS_1_TARGET_WIDTH_ASYM_RX 0x2 +#define LANE_ADP_CS_1_TARGET_WIDTH_ASYM_DUAL 0x0 #define LANE_ADP_CS_1_CL0S_ENABLE BIT(10) #define LANE_ADP_CS_1_CL1_ENABLE BIT(11) #define LANE_ADP_CS_1_CL2_ENABLE BIT(12) @@ -384,6 +388,8 @@ struct tb_regs_port_header { #define PORT_CS_18_WOCS BIT(16) #define PORT_CS_18_WODS BIT(17) #define PORT_CS_18_WOU4S BIT(18) +#define PORT_CS_18_CSA BIT(22) +#define PORT_CS_18_TIP BIT(24) #define PORT_CS_19 0x13 #define PORT_CS_19_DPR BIT(0) #define PORT_CS_19_PC BIT(3) @@ -391,6 +397,7 @@ struct tb_regs_port_header { #define PORT_CS_19_WOC BIT(16) #define PORT_CS_19_WOD BIT(17) #define PORT_CS_19_WOU4 BIT(18) +#define PORT_CS_19_START_ASYM BIT(24) /* Display Port adapter registers */ #define ADP_DP_CS_0 0x00 diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index 3aa32d7f9f6a..e048e81c3027 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -1494,6 +1494,112 @@ bool usb4_port_clx_supported(struct tb_port *port) return !!(val & PORT_CS_18_CPS); } +/** + * usb4_port_asym_supported() - If the port supports asymmetric link + * @port: USB4 port + * + * Checks if the port and the cable supports asymmetric link and returns + * %true in that case. + */ +bool usb4_port_asym_supported(struct tb_port *port) +{ + u32 val; + + if (!port->cap_usb4) + return false; + + if (tb_port_read(port, &val, TB_CFG_PORT, port->cap_usb4 + PORT_CS_18, 1)) + return false; + + return !!(val & PORT_CS_18_CSA); +} + +/** + * usb4_port_asym_set_link_width() - Set link width to asymmetric or symmetric + * @port: USB4 port + * @width: Asymmetric width to configure + * + * Sets USB4 port link width to @width. Can be called for widths where + * usb4_port_asym_width_supported() returned @true. + */ +int usb4_port_asym_set_link_width(struct tb_port *port, enum tb_link_width width) +{ + u32 val; + int ret; + + if (!port->cap_phy) + return -EINVAL; + + ret = tb_port_read(port, &val, TB_CFG_PORT, + port->cap_phy + LANE_ADP_CS_1, 1); + if (ret) + return ret; + + val &= ~LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK; + switch (width) { + case TB_LINK_WIDTH_DUAL: + val |= FIELD_PREP(LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK, + LANE_ADP_CS_1_TARGET_WIDTH_ASYM_DUAL); + break; + case TB_LINK_WIDTH_ASYM_TX: + val |= FIELD_PREP(LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK, + LANE_ADP_CS_1_TARGET_WIDTH_ASYM_TX); + break; + case TB_LINK_WIDTH_ASYM_RX: + val |= FIELD_PREP(LANE_ADP_CS_1_TARGET_WIDTH_ASYM_MASK, + LANE_ADP_CS_1_TARGET_WIDTH_ASYM_RX); + break; + default: + return -EINVAL; + } + + return tb_port_write(port, &val, TB_CFG_PORT, + port->cap_phy + LANE_ADP_CS_1, 1); +} + +/** + * usb4_port_asym_start() - Start symmetry change and wait for completion + * @port: USB4 port + * + * Start symmetry change of the link to asymmetric or symmetric + * (according to what was previously set in tb_port_set_link_width(). + * Wait for completion of the change. + * + * Returns %0 in case of success, %-ETIMEDOUT if case of timeout or + * a negative errno in case of a failure. + */ +int usb4_port_asym_start(struct tb_port *port) +{ + int ret; + u32 val; + + ret = tb_port_read(port, &val, TB_CFG_PORT, + port->cap_usb4 + PORT_CS_19, 1); + if (ret) + return ret; + + val &= ~PORT_CS_19_START_ASYM; + val |= FIELD_PREP(PORT_CS_19_START_ASYM, 1); + + ret = tb_port_write(port, &val, TB_CFG_PORT, + port->cap_usb4 + PORT_CS_19, 1); + if (ret) + return ret; + + /* + * Wait for PORT_CS_19_START_ASYM to be 0. This means the USB4 + * port started the symmetry transition. + */ + ret = usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_19, + PORT_CS_19_START_ASYM, 0, 1000); + if (ret) + return ret; + + /* Then wait for the transtion to be completed */ + return usb4_port_wait_for_bit(port, port->cap_usb4 + PORT_CS_18, + PORT_CS_18_TIP, 0, 5000); +} + /** * usb4_port_margining_caps() - Read USB4 port marginig capabilities * @port: USB4 port From patchwork Tue Oct 1 17:31:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832199 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.129.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A52DC1CF28E for ; Tue, 1 Oct 2024 17:32:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803947; cv=none; b=GWo3Psrci9ovTBh8ItIzRCPRLo2O/jsQmVqnl4mHRN836YkxOwxOi+yYgtu+1U782Q6uqZM6gwWpvq/9A50N2s12juVr1D9JM23zWZGVRyIezyRyCD9b24IM1oA5pQpkm/rUXFdJU10GSc24oVqyT7fVldgc1PrfBQ7ShKVzDoY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803947; c=relaxed/simple; bh=DIINOT42YchIWJ+zd0FHdcvBKnl6XN3kJQP4Iq5jl5A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=Qg5ieYhD7xAZ+PsXj9T5cTc4GyBJBOfKXpVSXz3hmvX2n/hE/Mof+HPKwBPMRb2eQ5t1JdBFLRAQNmjBL4PtWjsileIMUhI6WNRcMqDWEA4l7o/ksCL2LCuIZ6IgTO0JaAEtgKLK/IhKQHKSBK96jRTG3/Sbt7H4sQczQvsDtIk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=c/3cmU0P; arc=none smtp.client-ip=170.10.129.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="c/3cmU0P" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803942; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZjZhgctZtpP6DpugbtO933fRuYTRgFbd3PqLZMvoOHk=; b=c/3cmU0PXfp/3Jclzmq1vumUZeYFslBKb16wskWBSf7nctwC376CSZug4KmQbXUD1MbfhP 49NamqjbKuTJ7lZ2i4uRxA6gQef4iEnc8fiH1vprcv1oGZlYwSu5g6wM7yt7yWhFX3CnpK UEATEAI+qbz37X2sySdd4ftnzCzVhUs= Received: from g7t16454g.inc.hp.com (g7t16454g.inc.hp.com [15.73.128.143]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-121-ksSeZ18TMZaubxo49BurlA-1; Tue, 01 Oct 2024 13:32:21 -0400 X-MC-Unique: ksSeZ18TMZaubxo49BurlA-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g7t16454g.inc.hp.com (Postfix) with ESMTPS id 8F6376000D9B; Tue, 1 Oct 2024 17:32:20 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id E53261E; Tue, 1 Oct 2024 17:32:18 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Gil Fine , Alexandru Gagniuc Subject: [PATCH 6.6 13/14] thunderbolt: Configure asymmetric link if needed and bandwidth allows Date: Tue, 1 Oct 2024 17:31:08 +0000 Message-Id: <20241001173109.1513-14-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Gil Fine [ Upstream commit 3e36528c1127b20492ffaea53930bcc3df46a718 ] USB4 v2 spec defines a Gen 4 link that can operate as an asymmetric 120/40G. When the link is asymmetric, the USB4 port on one side of the link operates with three TX lanes and one RX lane, while the USB4 port on the opposite side of the link operates with three RX lanes and one TX lane. Using asymmetric link we can get much more bandwidth from one direction and that allows us to support the new Ultra High Bit Rate DisplayPort modes (that consume up to 77.37 Gb/s). Add the basic logic for changing Gen 4 links to asymmetric and back following the below rules: 1) The default threshold is 45 Gb/s (tunable by asym_threshold) 2) When DisplayPort tunnel is established, or when there is bandwidth request through bandwidth allocation mode, the links can be transitioned to asymmetric or symmetric (depending on the required bandwidth). 3) Only DisplayPort bandwidth on a link, is taken into account when deciding whether a link is transitioned to asymmetric or symmetric 4) If bandwidth on a link is >= asym_threshold transition the link to asymmetric 5) If bandwidth on a link < asym_threshold transition the link to symmetric (unless the bandwidth request is above currently allocated on a tunnel). 6) If a USB4 v2 device router with symmetric link is connected, transition all the links above it to symmetric if the bandwidth allows. Signed-off-by: Gil Fine Co-developed-by: Mika Westerberg Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tb.c | 681 ++++++++++++++++++++++++++++++++------- 1 file changed, 558 insertions(+), 123 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 550f1c9a1170..c52cbd5194f1 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -16,8 +16,31 @@ #include "tb_regs.h" #include "tunnel.h" -#define TB_TIMEOUT 100 /* ms */ -#define MAX_GROUPS 7 /* max Group_ID is 7 */ +#define TB_TIMEOUT 100 /* ms */ + +/* + * Minimum bandwidth (in Mb/s) that is needed in the single transmitter/receiver + * direction. This is 40G - 10% guard band bandwidth. + */ +#define TB_ASYM_MIN (40000 * 90 / 100) + +/* + * Threshold bandwidth (in Mb/s) that is used to switch the links to + * asymmetric and back. This is selected as 45G which means when the + * request is higher than this, we switch the link to asymmetric, and + * when it is less than this we switch it back. The 45G is selected so + * that we still have 27G (of the total 72G) for bulk PCIe traffic when + * switching back to symmetric. + */ +#define TB_ASYM_THRESHOLD 45000 + +#define MAX_GROUPS 7 /* max Group_ID is 7 */ + +static unsigned int asym_threshold = TB_ASYM_THRESHOLD; +module_param_named(asym_threshold, asym_threshold, uint, 0444); +MODULE_PARM_DESC(asym_threshold, + "threshold (Mb/s) when to Gen 4 switch link symmetry. 0 disables. (default: " + __MODULE_STRING(TB_ASYM_THRESHOLD) ")"); /** * struct tb_cm - Simple Thunderbolt connection manager @@ -285,14 +308,32 @@ static int tb_enable_clx(struct tb_switch *sw) return ret == -EOPNOTSUPP ? 0 : ret; } -/* Disables CL states up to the host router */ -static void tb_disable_clx(struct tb_switch *sw) +/** + * tb_disable_clx() - Disable CL states up to host router + * @sw: Router to start + * + * Disables CL states from @sw up to the host router. Returns true if + * any CL state were disabled. This can be used to figure out whether + * the link was setup by us or the boot firmware so we don't + * accidentally enable them if they were not enabled during discovery. + */ +static bool tb_disable_clx(struct tb_switch *sw) { + bool disabled = false; + do { - if (tb_switch_clx_disable(sw) < 0) + int ret; + + ret = tb_switch_clx_disable(sw); + if (ret > 0) + disabled = true; + else if (ret < 0) tb_sw_warn(sw, "failed to disable CL states\n"); + sw = tb_switch_parent(sw); } while (sw); + + return disabled; } static int tb_increase_switch_tmu_accuracy(struct device *dev, void *data) @@ -572,144 +613,294 @@ static struct tb_tunnel *tb_find_first_usb3_tunnel(struct tb *tb, return tb_find_tunnel(tb, TB_TUNNEL_USB3, usb3_down, NULL); } -static int tb_available_bandwidth(struct tb *tb, struct tb_port *src_port, - struct tb_port *dst_port, int *available_up, int *available_down) -{ - int usb3_consumed_up, usb3_consumed_down, ret; - struct tb_cm *tcm = tb_priv(tb); +/** + * tb_consumed_usb3_pcie_bandwidth() - Consumed USB3/PCIe bandwidth over a single link + * @tb: Domain structure + * @src_port: Source protocol adapter + * @dst_port: Destination protocol adapter + * @port: USB4 port the consumed bandwidth is calculated + * @consumed_up: Consumed upsream bandwidth (Mb/s) + * @consumed_down: Consumed downstream bandwidth (Mb/s) + * + * Calculates consumed USB3 and PCIe bandwidth at @port between path + * from @src_port to @dst_port. Does not take tunnel starting from + * @src_port and ending from @src_port into account. + */ +static int tb_consumed_usb3_pcie_bandwidth(struct tb *tb, + struct tb_port *src_port, + struct tb_port *dst_port, + struct tb_port *port, + int *consumed_up, + int *consumed_down) +{ + int pci_consumed_up, pci_consumed_down; struct tb_tunnel *tunnel; - struct tb_port *port; - tb_dbg(tb, "calculating available bandwidth between %llx:%u <-> %llx:%u\n", - tb_route(src_port->sw), src_port->port, tb_route(dst_port->sw), - dst_port->port); + *consumed_up = *consumed_down = 0; tunnel = tb_find_first_usb3_tunnel(tb, src_port, dst_port); if (tunnel && tunnel->src_port != src_port && tunnel->dst_port != dst_port) { - ret = tb_tunnel_consumed_bandwidth(tunnel, &usb3_consumed_up, - &usb3_consumed_down); + int ret; + + ret = tb_tunnel_consumed_bandwidth(tunnel, consumed_up, + consumed_down); if (ret) return ret; - } else { - usb3_consumed_up = 0; - usb3_consumed_down = 0; } - /* Maximum possible bandwidth asymmetric Gen 4 link is 120 Gb/s */ - *available_up = *available_down = 120000; + /* + * If there is anything reserved for PCIe bulk traffic take it + * into account here too. + */ + if (tb_tunnel_reserved_pci(port, &pci_consumed_up, &pci_consumed_down)) { + *consumed_up += pci_consumed_up; + *consumed_down += pci_consumed_down; + } - /* Find the minimum available bandwidth over all links */ - tb_for_each_port_on_path(src_port, dst_port, port) { - int link_speed, link_width, up_bw, down_bw; - int pci_reserved_up, pci_reserved_down; + return 0; +} - if (!tb_port_is_null(port)) +/** + * tb_consumed_dp_bandwidth() - Consumed DP bandwidth over a single link + * @tb: Domain structure + * @src_port: Source protocol adapter + * @dst_port: Destination protocol adapter + * @port: USB4 port the consumed bandwidth is calculated + * @consumed_up: Consumed upsream bandwidth (Mb/s) + * @consumed_down: Consumed downstream bandwidth (Mb/s) + * + * Calculates consumed DP bandwidth at @port between path from @src_port + * to @dst_port. Does not take tunnel starting from @src_port and ending + * from @src_port into account. + */ +static int tb_consumed_dp_bandwidth(struct tb *tb, + struct tb_port *src_port, + struct tb_port *dst_port, + struct tb_port *port, + int *consumed_up, + int *consumed_down) +{ + struct tb_cm *tcm = tb_priv(tb); + struct tb_tunnel *tunnel; + int ret; + + *consumed_up = *consumed_down = 0; + + /* + * Find all DP tunnels that cross the port and reduce + * their consumed bandwidth from the available. + */ + list_for_each_entry(tunnel, &tcm->tunnel_list, list) { + int dp_consumed_up, dp_consumed_down; + + if (tb_tunnel_is_invalid(tunnel)) continue; - if (tb_is_upstream_port(port)) { - link_speed = port->sw->link_speed; + if (!tb_tunnel_is_dp(tunnel)) + continue; + + if (!tb_tunnel_port_on_path(tunnel, port)) + continue; + + /* + * Ignore the DP tunnel between src_port and dst_port + * because it is the same tunnel and we may be + * re-calculating estimated bandwidth. + */ + if (tunnel->src_port == src_port && + tunnel->dst_port == dst_port) + continue; + + ret = tb_tunnel_consumed_bandwidth(tunnel, &dp_consumed_up, + &dp_consumed_down); + if (ret) + return ret; + + *consumed_up += dp_consumed_up; + *consumed_down += dp_consumed_down; + } + + return 0; +} + +static bool tb_asym_supported(struct tb_port *src_port, struct tb_port *dst_port, + struct tb_port *port) +{ + bool downstream = tb_port_path_direction_downstream(src_port, dst_port); + enum tb_link_width width; + + if (tb_is_upstream_port(port)) + width = downstream ? TB_LINK_WIDTH_ASYM_RX : TB_LINK_WIDTH_ASYM_TX; + else + width = downstream ? TB_LINK_WIDTH_ASYM_TX : TB_LINK_WIDTH_ASYM_RX; + + return tb_port_width_supported(port, width); +} + +/** + * tb_maximum_banwidth() - Maximum bandwidth over a single link + * @tb: Domain structure + * @src_port: Source protocol adapter + * @dst_port: Destination protocol adapter + * @port: USB4 port the total bandwidth is calculated + * @max_up: Maximum upstream bandwidth (Mb/s) + * @max_down: Maximum downstream bandwidth (Mb/s) + * @include_asym: Include bandwidth if the link is switched from + * symmetric to asymmetric + * + * Returns maximum possible bandwidth in @max_up and @max_down over a + * single link at @port. If @include_asym is set then includes the + * additional banwdith if the links are transitioned into asymmetric to + * direction from @src_port to @dst_port. + */ +static int tb_maximum_bandwidth(struct tb *tb, struct tb_port *src_port, + struct tb_port *dst_port, struct tb_port *port, + int *max_up, int *max_down, bool include_asym) +{ + bool downstream = tb_port_path_direction_downstream(src_port, dst_port); + int link_speed, link_width, up_bw, down_bw; + + /* + * Can include asymmetric, only if it is actually supported by + * the lane adapter. + */ + if (!tb_asym_supported(src_port, dst_port, port)) + include_asym = false; + + if (tb_is_upstream_port(port)) { + link_speed = port->sw->link_speed; + /* + * sw->link_width is from upstream perspective so we use + * the opposite for downstream of the host router. + */ + if (port->sw->link_width == TB_LINK_WIDTH_ASYM_TX) { + up_bw = link_speed * 3 * 1000; + down_bw = link_speed * 1 * 1000; + } else if (port->sw->link_width == TB_LINK_WIDTH_ASYM_RX) { + up_bw = link_speed * 1 * 1000; + down_bw = link_speed * 3 * 1000; + } else if (include_asym) { /* - * sw->link_width is from upstream perspective - * so we use the opposite for downstream of the - * host router. + * The link is symmetric at the moment but we + * can switch it to asymmetric as needed. Report + * this bandwidth as available (even though it + * is not yet enabled). */ - if (port->sw->link_width == TB_LINK_WIDTH_ASYM_TX) { - up_bw = link_speed * 3 * 1000; - down_bw = link_speed * 1 * 1000; - } else if (port->sw->link_width == TB_LINK_WIDTH_ASYM_RX) { + if (downstream) { up_bw = link_speed * 1 * 1000; down_bw = link_speed * 3 * 1000; } else { - up_bw = link_speed * port->sw->link_width * 1000; - down_bw = up_bw; + up_bw = link_speed * 3 * 1000; + down_bw = link_speed * 1 * 1000; } } else { - link_speed = tb_port_get_link_speed(port); - if (link_speed < 0) - return link_speed; - - link_width = tb_port_get_link_width(port); - if (link_width < 0) - return link_width; - - if (link_width == TB_LINK_WIDTH_ASYM_TX) { + up_bw = link_speed * port->sw->link_width * 1000; + down_bw = up_bw; + } + } else { + link_speed = tb_port_get_link_speed(port); + if (link_speed < 0) + return link_speed; + + link_width = tb_port_get_link_width(port); + if (link_width < 0) + return link_width; + + if (link_width == TB_LINK_WIDTH_ASYM_TX) { + up_bw = link_speed * 1 * 1000; + down_bw = link_speed * 3 * 1000; + } else if (link_width == TB_LINK_WIDTH_ASYM_RX) { + up_bw = link_speed * 3 * 1000; + down_bw = link_speed * 1 * 1000; + } else if (include_asym) { + /* + * The link is symmetric at the moment but we + * can switch it to asymmetric as needed. Report + * this bandwidth as available (even though it + * is not yet enabled). + */ + if (downstream) { up_bw = link_speed * 1 * 1000; down_bw = link_speed * 3 * 1000; - } else if (link_width == TB_LINK_WIDTH_ASYM_RX) { + } else { up_bw = link_speed * 3 * 1000; down_bw = link_speed * 1 * 1000; - } else { - up_bw = link_speed * link_width * 1000; - down_bw = up_bw; } + } else { + up_bw = link_speed * link_width * 1000; + down_bw = up_bw; } + } - /* Leave 10% guard band */ - up_bw -= up_bw / 10; - down_bw -= down_bw / 10; - - tb_port_dbg(port, "link total bandwidth %d/%d Mb/s\n", up_bw, - down_bw); - - /* - * Find all DP tunnels that cross the port and reduce - * their consumed bandwidth from the available. - */ - list_for_each_entry(tunnel, &tcm->tunnel_list, list) { - int dp_consumed_up, dp_consumed_down; + /* Leave 10% guard band */ + *max_up = up_bw - up_bw / 10; + *max_down = down_bw - down_bw / 10; - if (tb_tunnel_is_invalid(tunnel)) - continue; + tb_port_dbg(port, "link maximum bandwidth %d/%d Mb/s\n", *max_up, *max_down); + return 0; +} - if (!tb_tunnel_is_dp(tunnel)) - continue; +/** + * tb_available_bandwidth() - Available bandwidth for tunneling + * @tb: Domain structure + * @src_port: Source protocol adapter + * @dst_port: Destination protocol adapter + * @available_up: Available bandwidth upstream (Mb/s) + * @available_down: Available bandwidth downstream (Mb/s) + * @include_asym: Include bandwidth if the link is switched from + * symmetric to asymmetric + * + * Calculates maximum available bandwidth for protocol tunneling between + * @src_port and @dst_port at the moment. This is minimum of maximum + * link bandwidth across all links reduced by currently consumed + * bandwidth on that link. + * + * If @include_asym is true then includes also bandwidth that can be + * added when the links are transitioned into asymmetric (but does not + * transition the links). + */ +static int tb_available_bandwidth(struct tb *tb, struct tb_port *src_port, + struct tb_port *dst_port, int *available_up, + int *available_down, bool include_asym) +{ + struct tb_port *port; + int ret; - if (!tb_tunnel_port_on_path(tunnel, port)) - continue; + /* Maximum possible bandwidth asymmetric Gen 4 link is 120 Gb/s */ + *available_up = *available_down = 120000; - /* - * Ignore the DP tunnel between src_port and - * dst_port because it is the same tunnel and we - * may be re-calculating estimated bandwidth. - */ - if (tunnel->src_port == src_port && - tunnel->dst_port == dst_port) - continue; + /* Find the minimum available bandwidth over all links */ + tb_for_each_port_on_path(src_port, dst_port, port) { + int max_up, max_down, consumed_up, consumed_down; - ret = tb_tunnel_consumed_bandwidth(tunnel, - &dp_consumed_up, - &dp_consumed_down); - if (ret) - return ret; + if (!tb_port_is_null(port)) + continue; - up_bw -= dp_consumed_up; - down_bw -= dp_consumed_down; - } + ret = tb_maximum_bandwidth(tb, src_port, dst_port, port, + &max_up, &max_down, include_asym); + if (ret) + return ret; - /* - * If USB3 is tunneled from the host router down to the - * branch leading to port we need to take USB3 consumed - * bandwidth into account regardless whether it actually - * crosses the port. - */ - up_bw -= usb3_consumed_up; - down_bw -= usb3_consumed_down; + ret = tb_consumed_usb3_pcie_bandwidth(tb, src_port, dst_port, + port, &consumed_up, + &consumed_down); + if (ret) + return ret; + max_up -= consumed_up; + max_down -= consumed_down; - /* - * If there is anything reserved for PCIe bulk traffic - * take it into account here too. - */ - if (tb_tunnel_reserved_pci(port, &pci_reserved_up, - &pci_reserved_down)) { - up_bw -= pci_reserved_up; - down_bw -= pci_reserved_down; - } + ret = tb_consumed_dp_bandwidth(tb, src_port, dst_port, port, + &consumed_up, &consumed_down); + if (ret) + return ret; + max_up -= consumed_up; + max_down -= consumed_down; - if (up_bw < *available_up) - *available_up = up_bw; - if (down_bw < *available_down) - *available_down = down_bw; + if (max_up < *available_up) + *available_up = max_up; + if (max_down < *available_down) + *available_down = max_down; } if (*available_up < 0) @@ -747,7 +938,7 @@ static void tb_reclaim_usb3_bandwidth(struct tb *tb, struct tb_port *src_port, * That determines the whole USB3 bandwidth for this branch. */ ret = tb_available_bandwidth(tb, tunnel->src_port, tunnel->dst_port, - &available_up, &available_down); + &available_up, &available_down, false); if (ret) { tb_warn(tb, "failed to calculate available bandwidth\n"); return; @@ -805,8 +996,8 @@ static int tb_tunnel_usb3(struct tb *tb, struct tb_switch *sw) return ret; } - ret = tb_available_bandwidth(tb, down, up, &available_up, - &available_down); + ret = tb_available_bandwidth(tb, down, up, &available_up, &available_down, + false); if (ret) goto err_reclaim; @@ -867,6 +1058,225 @@ static int tb_create_usb3_tunnels(struct tb_switch *sw) return 0; } +/** + * tb_configure_asym() - Transition links to asymmetric if needed + * @tb: Domain structure + * @src_port: Source adapter to start the transition + * @dst_port: Destination adapter + * @requested_up: Additional bandwidth (Mb/s) required upstream + * @requested_down: Additional bandwidth (Mb/s) required downstream + * + * Transition links between @src_port and @dst_port into asymmetric, with + * three lanes in the direction from @src_port towards @dst_port and one lane + * in the opposite direction, if the bandwidth requirements + * (requested + currently consumed) on that link exceed @asym_threshold. + * + * Must be called with available >= requested over all links. + */ +static int tb_configure_asym(struct tb *tb, struct tb_port *src_port, + struct tb_port *dst_port, int requested_up, + int requested_down) +{ + struct tb_switch *sw; + bool clx, downstream; + struct tb_port *up; + int ret = 0; + + if (!asym_threshold) + return 0; + + /* Disable CL states before doing any transitions */ + downstream = tb_port_path_direction_downstream(src_port, dst_port); + /* Pick up router deepest in the hierarchy */ + if (downstream) + sw = dst_port->sw; + else + sw = src_port->sw; + + clx = tb_disable_clx(sw); + + tb_for_each_upstream_port_on_path(src_port, dst_port, up) { + int consumed_up, consumed_down; + enum tb_link_width width; + + ret = tb_consumed_dp_bandwidth(tb, src_port, dst_port, up, + &consumed_up, &consumed_down); + if (ret) + break; + + if (downstream) { + /* + * Downstream so make sure upstream is within the 36G + * (40G - guard band 10%), and the requested is above + * what the threshold is. + */ + if (consumed_up + requested_up >= TB_ASYM_MIN) { + ret = -ENOBUFS; + break; + } + /* Does consumed + requested exceed the threshold */ + if (consumed_down + requested_down < asym_threshold) + continue; + + width = TB_LINK_WIDTH_ASYM_RX; + } else { + /* Upstream, the opposite of above */ + if (consumed_down + requested_down >= TB_ASYM_MIN) { + ret = -ENOBUFS; + break; + } + if (consumed_up + requested_up < asym_threshold) + continue; + + width = TB_LINK_WIDTH_ASYM_TX; + } + + if (up->sw->link_width == width) + continue; + + if (!tb_port_width_supported(up, width)) + continue; + + tb_sw_dbg(up->sw, "configuring asymmetric link\n"); + + /* + * Here requested + consumed > threshold so we need to + * transtion the link into asymmetric now. + */ + ret = tb_switch_set_link_width(up->sw, width); + if (ret) { + tb_sw_warn(up->sw, "failed to set link width\n"); + break; + } + } + + /* Re-enable CL states if they were previosly enabled */ + if (clx) + tb_enable_clx(sw); + + return ret; +} + +/** + * tb_configure_sym() - Transition links to symmetric if possible + * @tb: Domain structure + * @src_port: Source adapter to start the transition + * @dst_port: Destination adapter + * @requested_up: New lower bandwidth request upstream (Mb/s) + * @requested_down: New lower bandwidth request downstream (Mb/s) + * + * Goes over each link from @src_port to @dst_port and tries to + * transition the link to symmetric if the currently consumed bandwidth + * allows. + */ +static int tb_configure_sym(struct tb *tb, struct tb_port *src_port, + struct tb_port *dst_port, int requested_up, + int requested_down) +{ + struct tb_switch *sw; + bool clx, downstream; + struct tb_port *up; + int ret = 0; + + if (!asym_threshold) + return 0; + + /* Disable CL states before doing any transitions */ + downstream = tb_port_path_direction_downstream(src_port, dst_port); + /* Pick up router deepest in the hierarchy */ + if (downstream) + sw = dst_port->sw; + else + sw = src_port->sw; + + clx = tb_disable_clx(sw); + + tb_for_each_upstream_port_on_path(src_port, dst_port, up) { + int consumed_up, consumed_down; + + /* Already symmetric */ + if (up->sw->link_width <= TB_LINK_WIDTH_DUAL) + continue; + /* Unplugged, no need to switch */ + if (up->sw->is_unplugged) + continue; + + ret = tb_consumed_dp_bandwidth(tb, src_port, dst_port, up, + &consumed_up, &consumed_down); + if (ret) + break; + + if (downstream) { + /* + * Downstream so we want the consumed_down < threshold. + * Upstream traffic should be less than 36G (40G + * guard band 10%) as the link was configured asymmetric + * already. + */ + if (consumed_down + requested_down >= asym_threshold) + continue; + } else { + if (consumed_up + requested_up >= asym_threshold) + continue; + } + + if (up->sw->link_width == TB_LINK_WIDTH_DUAL) + continue; + + tb_sw_dbg(up->sw, "configuring symmetric link\n"); + + ret = tb_switch_set_link_width(up->sw, TB_LINK_WIDTH_DUAL); + if (ret) { + tb_sw_warn(up->sw, "failed to set link width\n"); + break; + } + } + + /* Re-enable CL states if they were previosly enabled */ + if (clx) + tb_enable_clx(sw); + + return ret; +} + +static void tb_configure_link(struct tb_port *down, struct tb_port *up, + struct tb_switch *sw) +{ + struct tb *tb = sw->tb; + + /* Link the routers using both links if available */ + down->remote = up; + up->remote = down; + if (down->dual_link_port && up->dual_link_port) { + down->dual_link_port->remote = up->dual_link_port; + up->dual_link_port->remote = down->dual_link_port; + } + + /* + * Enable lane bonding if the link is currently two single lane + * links. + */ + if (sw->link_width < TB_LINK_WIDTH_DUAL) + tb_switch_set_link_width(sw, TB_LINK_WIDTH_DUAL); + + /* + * Device router that comes up as symmetric link is + * connected deeper in the hierarchy, we transition the links + * above into symmetric if bandwidth allows. + */ + if (tb_switch_depth(sw) > 1 && + tb_port_get_link_generation(up) >= 4 && + up->sw->link_width == TB_LINK_WIDTH_DUAL) { + struct tb_port *host_port; + + host_port = tb_port_at(tb_route(sw), tb->root_switch); + tb_configure_sym(tb, host_port, up, 0, 0); + } + + /* Set the link configured */ + tb_switch_configure_link(sw); +} + static void tb_scan_port(struct tb_port *port); /* @@ -975,19 +1385,9 @@ static void tb_scan_port(struct tb_port *port) goto out_rpm_put; } - /* Link the switches using both links if available */ upstream_port = tb_upstream_port(sw); - port->remote = upstream_port; - upstream_port->remote = port; - if (port->dual_link_port && upstream_port->dual_link_port) { - port->dual_link_port->remote = upstream_port->dual_link_port; - upstream_port->dual_link_port->remote = port->dual_link_port; - } + tb_configure_link(port, upstream_port, sw); - /* Enable lane bonding if supported */ - tb_switch_set_link_width(sw, TB_LINK_WIDTH_DUAL); - /* Set the link configured */ - tb_switch_configure_link(sw); /* * CL0s and CL1 are enabled and supported together. * Silently ignore CLx enabling in case CLx is not supported. @@ -1051,6 +1451,11 @@ static void tb_deactivate_and_free_tunnel(struct tb_tunnel *tunnel) * deallocated properly. */ tb_switch_dealloc_dp_resource(src_port->sw, src_port); + /* + * If bandwidth on a link is < asym_threshold + * transition the link to symmetric. + */ + tb_configure_sym(tb, src_port, dst_port, 0, 0); /* Now we can allow the domain to runtime suspend again */ pm_runtime_mark_last_busy(&dst_port->sw->dev); pm_runtime_put_autosuspend(&dst_port->sw->dev); @@ -1208,7 +1613,7 @@ tb_recalc_estimated_bandwidth_for_group(struct tb_bandwidth_group *group) out = tunnel->dst_port; ret = tb_available_bandwidth(tb, in, out, &estimated_up, - &estimated_down); + &estimated_down, true); if (ret) { tb_port_warn(in, "failed to re-calculate estimated bandwidth\n"); @@ -1299,6 +1704,7 @@ static bool tb_tunnel_one_dp(struct tb *tb) int available_up, available_down, ret, link_nr; struct tb_cm *tcm = tb_priv(tb); struct tb_port *port, *in, *out; + int consumed_up, consumed_down; struct tb_tunnel *tunnel; /* @@ -1375,7 +1781,8 @@ static bool tb_tunnel_one_dp(struct tb *tb) goto err_detach_group; } - ret = tb_available_bandwidth(tb, in, out, &available_up, &available_down); + ret = tb_available_bandwidth(tb, in, out, &available_up, &available_down, + true); if (ret) goto err_reclaim_usb; @@ -1397,6 +1804,13 @@ static bool tb_tunnel_one_dp(struct tb *tb) list_add_tail(&tunnel->list, &tcm->tunnel_list); tb_reclaim_usb3_bandwidth(tb, in, out); + /* + * Transition the links to asymmetric if the consumption exceeds + * the threshold. + */ + if (!tb_tunnel_consumed_bandwidth(tunnel, &consumed_up, &consumed_down)) + tb_configure_asym(tb, in, out, consumed_up, consumed_down); + /* Update the domain with the new bandwidth estimation */ tb_recalc_estimated_bandwidth(tb); @@ -1903,6 +2317,11 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, if ((*requested_up >= 0 && requested_up_corrected <= allocated_up) || (*requested_down >= 0 && requested_down_corrected <= allocated_down)) { + /* + * If bandwidth on a link is < asym_threshold transition + * the link to symmetric. + */ + tb_configure_sym(tb, in, out, *requested_up, *requested_down); /* * If requested bandwidth is less or equal than what is * currently allocated to that tunnel we simply change @@ -1928,7 +2347,8 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, * are also in the same group but we use the same function here * that we use with the normal bandwidth allocation). */ - ret = tb_available_bandwidth(tb, in, out, &available_up, &available_down); + ret = tb_available_bandwidth(tb, in, out, &available_up, &available_down, + true); if (ret) goto reclaim; @@ -1937,8 +2357,23 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, if ((*requested_up >= 0 && available_up >= requested_up_corrected) || (*requested_down >= 0 && available_down >= requested_down_corrected)) { + /* + * If bandwidth on a link is >= asym_threshold + * transition the link to asymmetric. + */ + ret = tb_configure_asym(tb, in, out, *requested_up, + *requested_down); + if (ret) { + tb_configure_sym(tb, in, out, 0, 0); + return ret; + } + ret = tb_tunnel_alloc_bandwidth(tunnel, requested_up, requested_down); + if (ret) { + tb_tunnel_warn(tunnel, "failed to allocate bandwidth\n"); + tb_configure_sym(tb, in, out, 0, 0); + } } else { ret = -ENOBUFS; } From patchwork Tue Oct 1 17:31:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Gagniuc X-Patchwork-Id: 832698 Received: from us-smtp-delivery-162.mimecast.com (us-smtp-delivery-162.mimecast.com [170.10.129.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2C5B1CF5C2 for ; Tue, 1 Oct 2024 17:32:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.162 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803949; cv=none; b=FIkT4pF+axiXDV8YtuLuMwVZSVcv6XSRUxbCigKB74XCLeW9RQknrYO+yrPuiHsjyhGRVmZ8dkJFOsQsBdvTxqwepeeV//CBZsaV3tRCegLO3I6/t7pNX+7pa7F+XDXsrmOMCnux/mpWJRk37Oum1aUtZsdHX0X27h7L4PtceQ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727803949; c=relaxed/simple; bh=E4LgHLrWgF1RKt3FIMRF2EcRz70JSi2sS8gv4RwlqDE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=q5Oyd2q8XN8Iit9iId9b5CBhihxFUJNwzVM75B0j7nN3Jv+JODObZtL0Di551kKfcIQdGN1eT5zl/9YpAM0tajDIov3TNNVHKcnDW06jCE33e0RjiDSE3ZG01vxBl7nwBeXOzE9qsZGKleFyfeVa8yculBqnPQSIU2S/cxcrGyg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com; spf=pass smtp.mailfrom=hp.com; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b=hQF0hzBg; arc=none smtp.client-ip=170.10.129.162 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=hp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=hp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=hp.com header.i=@hp.com header.b="hQF0hzBg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hp.com; s=mimecast20180716; t=1727803946; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lD2i1Q6tTo9IRdXlsPnDOoVcWUOqej5qY4Gl2VuLzfE=; b=hQF0hzBg/PGSs85RufzgYKLUFOJuTo1cjgvdrFkxs1kphyQwYmKlEnS4JhP2yXYD2FTzhN NVJBWqdNoeuJW5uMDZhV8Kjc4qaWF06+lN9uquObWht8Zl9dI898D0OOyF1r4gFbqjek8K XuKymVetx5k9GMIOqe4O4mCWrbCJDuA= Received: from g8t13017g.inc.hp.com (hpi-bastion.austin2.mail.core.hp.com [15.72.64.135]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-307-gSUzTbAsM5alVaa2JaNgjQ-1; Tue, 01 Oct 2024 13:32:24 -0400 X-MC-Unique: gSUzTbAsM5alVaa2JaNgjQ-1 Received: from g7t14407g.inc.hpicorp.net (g7t14407g.inc.hpicorp.net [15.63.19.131]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by g8t13017g.inc.hp.com (Postfix) with ESMTPS id 136236000DFA; Tue, 1 Oct 2024 17:32:22 +0000 (UTC) Received: from localhost.localdomain (unknown [15.53.255.151]) by g7t14407g.inc.hpicorp.net (Postfix) with ESMTP id 6E05318; Tue, 1 Oct 2024 17:32:20 +0000 (UTC) From: Alexandru Gagniuc To: gregkh@linuxfoundation.org, stable@vger.kernel.org Cc: qin.wan@hp.com, andreas.noever@gmail.com, michael.jamet@intel.com, mika.westerberg@linux.intel.com, YehezkelShB@gmail.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Gil Fine , Alexandru Gagniuc Subject: [PATCH 6.6 14/14] thunderbolt: Improve DisplayPort tunnel setup process to be more robust Date: Tue, 1 Oct 2024 17:31:09 +0000 Message-Id: <20241001173109.1513-15-alexandru.gagniuc@hp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241001173109.1513-1-alexandru.gagniuc@hp.com> References: <20241001173109.1513-1-alexandru.gagniuc@hp.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: hp.com From: Gil Fine [ Upstream commit b4734507ac55cc7ea1380e20e83f60fcd7031955 ] After DisplayPort tunnel setup, we add verification that the DPRX capabilities read process completed. Otherwise, we bail out, teardown the tunnel, and try setup another DisplayPort tunnel using next available DP IN adapter. We do so till all DP IN adapters tried. This way, we avoid allocating DP IN adapter and (bandwidth for it) for unusable tunnel. Signed-off-by: Gil Fine Signed-off-by: Mika Westerberg Signed-off-by: Qin Wan Signed-off-by: Alexandru Gagniuc --- drivers/thunderbolt/tb.c | 84 ++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index c52cbd5194f1..ea155547e871 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -1699,48 +1699,14 @@ static struct tb_port *tb_find_dp_out(struct tb *tb, struct tb_port *in) return NULL; } -static bool tb_tunnel_one_dp(struct tb *tb) +static bool tb_tunnel_one_dp(struct tb *tb, struct tb_port *in, + struct tb_port *out) { int available_up, available_down, ret, link_nr; struct tb_cm *tcm = tb_priv(tb); - struct tb_port *port, *in, *out; int consumed_up, consumed_down; struct tb_tunnel *tunnel; - /* - * Find pair of inactive DP IN and DP OUT adapters and then - * establish a DP tunnel between them. - */ - tb_dbg(tb, "looking for DP IN <-> DP OUT pairs:\n"); - - in = NULL; - out = NULL; - list_for_each_entry(port, &tcm->dp_resources, list) { - if (!tb_port_is_dpin(port)) - continue; - - if (tb_port_is_enabled(port)) { - tb_port_dbg(port, "DP IN in use\n"); - continue; - } - - in = port; - tb_port_dbg(in, "DP IN available\n"); - - out = tb_find_dp_out(tb, port); - if (out) - break; - } - - if (!in) { - tb_dbg(tb, "no suitable DP IN adapter available, not tunneling\n"); - return false; - } - if (!out) { - tb_dbg(tb, "no suitable DP OUT adapter available, not tunneling\n"); - return false; - } - /* * This is only applicable to links that are not bonded (so * when Thunderbolt 1 hardware is involved somewhere in the @@ -1801,15 +1767,19 @@ static bool tb_tunnel_one_dp(struct tb *tb) goto err_free; } + /* If fail reading tunnel's consumed bandwidth, tear it down */ + ret = tb_tunnel_consumed_bandwidth(tunnel, &consumed_up, &consumed_down); + if (ret) + goto err_deactivate; + list_add_tail(&tunnel->list, &tcm->tunnel_list); - tb_reclaim_usb3_bandwidth(tb, in, out); + tb_reclaim_usb3_bandwidth(tb, in, out); /* * Transition the links to asymmetric if the consumption exceeds * the threshold. */ - if (!tb_tunnel_consumed_bandwidth(tunnel, &consumed_up, &consumed_down)) - tb_configure_asym(tb, in, out, consumed_up, consumed_down); + tb_configure_asym(tb, in, out, consumed_up, consumed_down); /* Update the domain with the new bandwidth estimation */ tb_recalc_estimated_bandwidth(tb); @@ -1821,6 +1791,8 @@ static bool tb_tunnel_one_dp(struct tb *tb) tb_increase_tmu_accuracy(tunnel); return true; +err_deactivate: + tb_tunnel_deactivate(tunnel); err_free: tb_tunnel_free(tunnel); err_reclaim_usb: @@ -1840,13 +1812,43 @@ static bool tb_tunnel_one_dp(struct tb *tb) static void tb_tunnel_dp(struct tb *tb) { + struct tb_cm *tcm = tb_priv(tb); + struct tb_port *port, *in, *out; + if (!tb_acpi_may_tunnel_dp()) { tb_dbg(tb, "DP tunneling disabled, not creating tunnel\n"); return; } - while (tb_tunnel_one_dp(tb)) - ; + /* + * Find pair of inactive DP IN and DP OUT adapters and then + * establish a DP tunnel between them. + */ + tb_dbg(tb, "looking for DP IN <-> DP OUT pairs:\n"); + + in = NULL; + out = NULL; + list_for_each_entry(port, &tcm->dp_resources, list) { + if (!tb_port_is_dpin(port)) + continue; + + if (tb_port_is_enabled(port)) { + tb_port_dbg(port, "DP IN in use\n"); + continue; + } + + in = port; + tb_port_dbg(in, "DP IN available\n"); + + out = tb_find_dp_out(tb, port); + if (out) + tb_tunnel_one_dp(tb, in, out); + else + tb_port_dbg(in, "no suitable DP OUT adapter available, not tunneling\n"); + } + + if (!in) + tb_dbg(tb, "no suitable DP IN adapter available, not tunneling\n"); } static void tb_enter_redrive(struct tb_port *port)