From nobody Fri Dec 19 08:10:20 2025 Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4DD73009ED for ; Tue, 9 Dec 2025 05:41:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765258911; cv=none; b=GoxA/jeBxOA8mNR6VcKQMKU/MwZRoolB2SkDbItvOZ7en+O5+o3U0JtPhCERUGlD3CjGyKjgbooAryZPB1rvORQxwwXUpJE2UmfnGWEYgx+YWXzUQWVDm6cBXWkj+oMERiPPWAKSEsQM9O/dnjIrvhd5KBalTP8+r9Iw5U843rY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765258911; c=relaxed/simple; bh=41CdFHLabBujmCKkaBvRSIYs6uwj1klEYRM1b7Cgexk=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type; b=LWW86fhqRImueL7lMQvHvxQGEZTOpx1OMz9M4y59hPqZPGVcqfz0NSm/LXtY9MHFRcis17mvim4JskIwZB3w615YXJ76iqkvj65HCJFvgCnF02m0Huc8JjEj7nb8/MQjcbqkXKbMutvRYNKou4CIt38HaWs41QEjCsda13jZBng= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=reject dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=T2D1o1h6; arc=none smtp.client-ip=209.85.214.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=reject dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="T2D1o1h6" Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-298287a26c3so70616395ad.0 for ; Mon, 08 Dec 2025 21:41:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1765258909; x=1765863709; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:sender:from:to:cc:subject:date:message-id:reply-to; bh=PTRFVgVHGAErXbVV5LVlpbXUuhRN9WLfw8Rm44Nxnbc=; b=T2D1o1h6o9LT2kd6650kNZ64da5jHArf1Qx6AlwC2nQ5YZTYlrmFpuEh+AOOjPtg6G 4mdNWGq1KIzOSmRiCkMxX1ievAYwTPNmzZdufkIy75mPMRSpIhY07cfCIsucZkRbcbbt qepdgpt/srIrLDdE3TmVxR84+y+Gp5TVcnNc+bqX2DEcjRpY+H29HdwQgaB8CWm3TPhx nXb4j4PQt+cWbqeYWeCZlGJqOO/HhYPluDPz2EWobHZTEwzRd0HAIlfzos6/nB7t8Qxa UUoDzzM+2K9G5bIwOoJszTAK4EPS5gkDhAAf47cSOGh1i21XlmOIvNbCzN63fXShbDNS FqoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765258909; x=1765863709; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:sender:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=PTRFVgVHGAErXbVV5LVlpbXUuhRN9WLfw8Rm44Nxnbc=; b=Y/b0fkkGryOGxOahL9QYpgevnH55IonQjkDzzWhDGuHDBMdfM3IQL1jYQ2VO+42NS2 Pucxz7YXMNHcxbIKG5iZ5uMogb5w/QCKjXh4rYEGtKHbQkBCRW0prfpAXi3C+6nrHcCb ve99SkCz7UOjIFGPhL3yRShH6yA8K67oQSBhrz1oaEiQg/QzVJr3CJBTV6txgOI5rDOW Y/KuWCV0RPA4g7RlNu9j9Wn7pbbVI3rtrVCqnShRvIf5N26Mn7s0/feqnKBSlRS1Bi/S NXiTtUWxtyOheJW7jrCM0P9zu57diXv3+Db2qZ4l8lbYZrnFW2s4Z7JMZHlobV5qk0DW X6Fg== X-Forwarded-Encrypted: i=1; AJvYcCX7oWRPHhgCDo+AL2AgUJc2nfccv4Ck2q5mnph5Jg6F8cgIHogXLoV+PDFBnKgh5tg47wozU0CsGLejnKA=@vger.kernel.org X-Gm-Message-State: AOJu0YzaUnCtmIOtbFuX42bBwI6T2xhfw6LEXpDIpKTNLed1KmiLDmYk bm5zcWls9SECuO3/bLWEqS7vtK/46cIWcssAbek70iZtzhT2+o/IjoXS X-Gm-Gg: ASbGncsVZ3CYwF4NZ+W3GNRqZIqGkBWoef9LxmCH7woL48gIdM1Uz5A9NWh8td7cJL2 hUhgnthySydMYFZAResNhqvVoBkZNQa/d5IuGbyEjsOZ7niuLS1cpmM1FkXjvC2NKwR3sVoMO5P S3K4x4yUGYqv2kN/wiKzm3lFJOFc64yZi8WrTS3qdXsQbTnT6nwkDV1xId2yEOztM1tLmTMIdK5 WDbZjxJYX1j5fusZS8mzvxAO7RvXOVan4QF9G3EMz0byGT76qCouMuuYSd4oKq180aqq/RCCfV5 jHVSgPFZzGgeITSLUDJlMy6/ewcornbVMnyI/J5JKSnZAMVVEn0+hEKNArLMb9eD6R0wj7T/h71 /Nto7Do66vUotOi6MEWZl+25gV9ysvmwV/nAZIhaIsoiAfFBZpS/TAImH5TBkyJqQflhYjA== X-Google-Smtp-Source: AGHT+IFcqiBHI21RrSttGZiP497t9/mOpRwkZ2oqsE5EQeAnB/xmol5gM3RYbyZHVwOJtrf+Y0s8Fg== X-Received: by 2002:a17:903:11cf:b0:298:90f:5b01 with SMTP id d9443c01a7336-29df5f1bda3mr101903405ad.52.1765258908812; Mon, 08 Dec 2025 21:41:48 -0800 (PST) Received: from localhost ([2001:67c:1562:8007::aac:4468]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-29dae49b196sm144408235ad.17.2025.12.08.21.41.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Dec 2025 21:41:47 -0800 (PST) Sender: AceLan Kao From: "Chia-Lin Kao (AceLan)" To: Andreas Noever , Mika Westerberg , Yehezkel Bernat , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] [RFC] thunderbolt: Add delay for Dell U2725QE link width Date: Tue, 9 Dec 2025 13:41:41 +0800 Message-ID: <20251209054141.1975982-1-acelan.kao@canonical.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable When plugging in a Dell U2725QE Thunderbolt monitor, the kernel produces a call trace during initial enumeration. The device automatically disconnects and reconnects ~3 seconds later, and works correctly on the second attempt. Issue Description: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D The Dell U2725QE (USB4 device 8087:b26) requires additional time during link width negotiation from single lane to dual lane. On first plug, the following sequence occurs: 1. Port state reaches TB_PORT_UP (link established, single lane) 2. Path activation begins immediately 3. tb_path_activate() - > tb_port_write() returns -ENOTCONN (error -107) 4. Call trace is generated at tb_path_activate() 5. Device disconnects/reconnects automatically after ~3 seconds 6. Second attempt succeeds with full dual-lane bandwidth First attempt dmesg (failure): ------------------------------- [ 36.030347] thunderbolt 0000:c7:00.6: 2:16: available bandwidth for new = USB3 tunnel 9000/9000 Mb/s [ 36.030613] thunderbolt 0000:c7:00.6: 2: USB3 tunnel creation failed [ 36.031530] thunderbolt 0000:c7:00.6: PCIe Down path activation failed [ 36.031531] WARNING: drivers/thunderbolt/path.c:589 at 0x0, CPU#12: pool= -/usr/libex/3145 Second attempt dmesg (success): -------------------------------- [ 40.440012] thunderbolt 0000:c7:00.6: 2:16: available bandwidth for new = USB3 tunnel 36000/36000 Mb/s [ 40.440261] thunderbolt 0000:c7:00.6: 2:16: maximum required bandwidth f= or USB3 tunnel 9000 Mb/s [ 40.440269] thunderbolt 0000:c7:00.6: 0:4 <-> 2:16 (USB3): activating [ 40.440271] thunderbolt 0000:c7:00.6: 0:4 <-> 2:16 (USB3): allocating in= itial bandwidth 9000/9000 Mb/s The bandwidth difference (9000 vs 36000 Mb/s) indicates the first attempt occurs while the link is still in single-lane mode. Root Cause Analysis: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D The error originates from the Thunderbolt/USB4 device hardware itself: 1. Port config space read/write returns TB_CFG_ERROR_PORT_NOT_CONNECTED 2. This gets translated to -ENOTCONN in tb_cfg_get_error() 3. The port's control channel is temporarily unavailable during state transition from single lane to dual lane (lane bonding) The comment in drivers/thunderbolt/ctl.c explains this is expected: "Port is not connected. This can happen during surprise removal. Do not warn." Attempted Solutions: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 1. Retry logic on -ENOTCONN in tb_path_activate(): Result: Caused host port (0:0) lockup with hundreds of "downstream port is locked" errors. Rejected by user. 2. Increased tb_port_wait_for_link_width() timeout from 100ms to 3000ms: Result: Did not resolve the issue. The timeout increase alone is insufficient because the port state hasn't reached TB_PORT_UP when lane bonding is attempted. 3. Added msleep(2000) at various points in enumeration flow: Locations tested: - Before tb_switch_configure(): Works =E2=9C=93 - Before tb_switch_add(): Works =E2=9C=93 - Before usb4_port_hotplug_enable(): Works =E2=9C=93 - After tb_switch_add(): Doesn't work =E2=9C=97 - In tb_configure_link(): Doesn't work =E2=9C=97 - In tb_switch_lane_bonding_enable(): Doesn't work =E2=9C=97 - In tb_port_wait_for_link_width(): Doesn't work =E2=9C=97 The pattern shows the delay must occur BEFORE hotplug enable, which happens early in tb_switch_port_hotplug_enable() -> usb4_port_hotplug_en= able(). Current Workaround: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Add a 2-second delay in tb_wait_for_port() when the port state reaches TB_PORT_UP. This is the earliest point where we know: - The link is physically established - The device is responsive - But lane width negotiation may still be in progress This location is chosen because: 1. It's called during port enumeration before any tunnel creation 2. The port has just transitioned to TB_PORT_UP state 3. Allows sufficient time for lane bonding to complete 4. Avoids affecting other code paths Testing Results: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D With this patch: - No call trace on first plug - Device enumerates correctly on first attempt - Full bandwidth (36000 Mb/s) available immediately - No disconnect/reconnect cycle - USB and PCIe tunnels create successfully Without this patch: - Call trace on every first plug - Only 9000 Mb/s bandwidth (single lane) on first attempt - Automatic disconnect/reconnect after ~3 seconds - Second attempt works with 36000 Mb/s Discussion Points for RFC: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D 1. Is a fixed 2-second delay acceptable, or should we poll for a specific hardware state? 2. Should we check PORT_CS_18_TIP (Transition In Progress) bit instead of using a fixed delay? 3. Is there a better location for this delay in the enumeration flow? 4. Should this be device-specific (based on vendor/device ID) or apply to all USB4 devices? 5. The 100ms timeout in tb_switch_lane_bonding_enable() may be too short for other devices as well. Should we increase it universally? Hardware Details: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Device: Dell U2725QE Thunderbolt Monitor USB4 Router: 8087:b26 (Intel USB4 controller) Host: AMD Thunderbolt 4 controller (0000:c7:00.6) Signed-off-by: Chia-Lin Kao (AceLan) --- Full dmesg log available at: https://paste.ubuntu.com/p/CXs2T4XzZ3/ --- drivers/thunderbolt/switch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index b3948aad0b955..e0c65e5fb0dca 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -530,6 +530,8 @@ int tb_wait_for_port(struct tb_port *port, bool wait_if= _unplugged) return 0; =20 case TB_PORT_UP: + msleep(2000); + fallthrough; case TB_PORT_TX_CL0S: case TB_PORT_RX_CL0S: case TB_PORT_CL1: --=20 2.43.0