From patchwork Wed Aug 25 05:23:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai-Heng Feng X-Patchwork-Id: 1520520 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=EacLmrYv; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GvZDN3Npgz9sX2; Wed, 25 Aug 2021 15:24:51 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mIlP6-00077H-I8; Wed, 25 Aug 2021 05:24:48 +0000 Received: from smtp-relay-canonical-0.internal ([10.131.114.83] helo=smtp-relay-canonical-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mIlOw-00075w-Mt for kernel-team@lists.ubuntu.com; Wed, 25 Aug 2021 05:24:38 +0000 Received: from localhost.localdomain (1.general.khfeng.us.vpn [10.172.68.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-0.canonical.com (Postfix) with ESMTPSA id 66F883F361 for ; Wed, 25 Aug 2021 05:24:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1629869078; bh=YNmrpbFNP/+9GXr59K6rNZlfRgLJJwExvq6THney14c=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EacLmrYvrBZwG2NSzedhR17aICOskKt7CazKT//1KEqqd5fNuLX4P+NrCNLqV4smi dnGhhuDFVn15Afhay1/mAtHomj6f6EIypSCIm++aIH66NlxO02QcTowkIVLAf/Vs5u BBTTvc4OnLswfPKmp/5VjtTom+qwsvOnryVsKXsg2NmR7OEIoFCcEruF1rjUYMV6cG xiVz7HsYH6GHRbLEgtc4qjRbTqTjzH8yFA2AD+EfZXToqrCYZIt5YrVCchEOHrFBe1 BzM7jIpu0DxQAQsmoHfRxjPDLitt+PGarXHXhYUWMK4cBYprBvnzYJSWkLj2KL4oaT abuTgCLxeTAaA== From: Kai-Heng Feng To: kernel-team@lists.ubuntu.com Subject: [SRU] [I/OEM-5.13] [PATCH 1/7] thunderbolt: Split NVM read/write generic functions out from usb4.c Date: Wed, 25 Aug 2021 13:23:29 +0800 Message-Id: <20210825052335.53234-2-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210825052335.53234-1-kai.heng.feng@canonical.com> References: <20210825052335.53234-1-kai.heng.feng@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Mika Westerberg BugLink: https://bugs.launchpad.net/bugs/1941036 We do this for Thunderbolt 2/3 devices through DMA port, USB4 devices and retimers pretty much the same way. Only the actual block read/write is different. For this reason split out the NVM read/write functions from usb4.c to nvm.c and make USB4 device code call these when needed. Signed-off-by: Mika Westerberg (cherry picked from commit 9b383037770fcd6b03dd3793c89055b8490957e0) Signed-off-by: Kai-Heng Feng --- drivers/thunderbolt/nvm.c | 95 ++++++++++++++++++++++++++++++++ drivers/thunderbolt/tb.h | 11 ++++ drivers/thunderbolt/usb4.c | 110 ++++++------------------------------- 3 files changed, 124 insertions(+), 92 deletions(-) diff --git a/drivers/thunderbolt/nvm.c b/drivers/thunderbolt/nvm.c index 29de6d95c6e7f..3a5336913ccac 100644 --- a/drivers/thunderbolt/nvm.c +++ b/drivers/thunderbolt/nvm.c @@ -164,6 +164,101 @@ void tb_nvm_free(struct tb_nvm *nvm) kfree(nvm); } +/** + * tb_nvm_read_data() - Read data from NVM + * @address: Start address on the flash + * @buf: Buffer where the read data is copied + * @size: Size of the buffer in bytes + * @retries: Number of retries if block read fails + * @read_block: Function that reads block from the flash + * @read_block_data: Data passsed to @read_block + * + * This is a generic function that reads data from NVM or NVM like + * device. + * + * Returns %0 on success and negative errno otherwise. + */ +int tb_nvm_read_data(unsigned int address, void *buf, size_t size, + unsigned int retries, read_block_fn read_block, + void *read_block_data) +{ + do { + unsigned int dwaddress, dwords, offset; + u8 data[NVM_DATA_DWORDS * 4]; + size_t nbytes; + int ret; + + offset = address & 3; + nbytes = min_t(size_t, size + offset, NVM_DATA_DWORDS * 4); + + dwaddress = address / 4; + dwords = ALIGN(nbytes, 4) / 4; + + ret = read_block(read_block_data, dwaddress, data, dwords); + if (ret) { + if (ret != -ENODEV && retries--) + continue; + return ret; + } + + nbytes -= offset; + memcpy(buf, data + offset, nbytes); + + size -= nbytes; + address += nbytes; + buf += nbytes; + } while (size > 0); + + return 0; +} + +/** + * tb_nvm_write_data() - Write data to NVM + * @address: Start address on the flash + * @buf: Buffer where the data is copied from + * @size: Size of the buffer in bytes + * @retries: Number of retries if the block write fails + * @write_block: Function that writes block to the flash + * @write_block_data: Data passwd to @write_block + * + * This is generic function that writes data to NVM or NVM like device. + * + * Returns %0 on success and negative errno otherwise. + */ +int tb_nvm_write_data(unsigned int address, const void *buf, size_t size, + unsigned int retries, write_block_fn write_block, + void *write_block_data) +{ + do { + unsigned int offset, dwaddress; + u8 data[NVM_DATA_DWORDS * 4]; + size_t nbytes; + int ret; + + offset = address & 3; + nbytes = min_t(u32, size + offset, NVM_DATA_DWORDS * 4); + + memcpy(data + offset, buf, nbytes); + + dwaddress = address / 4; + ret = write_block(write_block_data, dwaddress, data, nbytes / 4); + if (ret) { + if (ret == -ETIMEDOUT) { + if (retries--) + continue; + ret = -EIO; + } + return ret; + } + + size -= nbytes; + address += nbytes; + buf += nbytes; + } while (size > 0); + + return 0; +} + void tb_nvm_exit(void) { ida_destroy(&nvm_ida); diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 9790e9f13d2be..d9d1adc4cfd33 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -20,6 +20,7 @@ #define NVM_MIN_SIZE SZ_32K #define NVM_MAX_SIZE SZ_512K +#define NVM_DATA_DWORDS 16 /* Intel specific NVM offsets */ #define NVM_DEVID 0x05 @@ -674,6 +675,16 @@ int tb_nvm_add_non_active(struct tb_nvm *nvm, size_t size, void tb_nvm_free(struct tb_nvm *nvm); void tb_nvm_exit(void); +typedef int (*read_block_fn)(void *, unsigned int, void *, size_t); +typedef int (*write_block_fn)(void *, unsigned int, const void *, size_t); + +int tb_nvm_read_data(unsigned int address, void *buf, size_t size, + unsigned int retries, read_block_fn read_block, + void *read_block_data); +int tb_nvm_write_data(unsigned int address, const void *buf, size_t size, + unsigned int retries, write_block_fn write_next_block, + void *write_block_data); + struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent, u64 route); struct tb_switch *tb_switch_alloc_safe_mode(struct tb *tb, diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index 671d72af8ba13..c0a14bfa36d41 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -13,7 +13,6 @@ #include "sb_regs.h" #include "tb.h" -#define USB4_DATA_DWORDS 16 #define USB4_DATA_RETRIES 3 enum usb4_sb_target { @@ -37,9 +36,6 @@ enum usb4_sb_target { #define USB4_NVM_SECTOR_SIZE_MASK GENMASK(23, 0) -typedef int (*read_block_fn)(void *, unsigned int, void *, size_t); -typedef int (*write_block_fn)(void *, const void *, size_t); - static int usb4_switch_wait_for_bit(struct tb_switch *sw, u32 offset, u32 bit, u32 value, int timeout_msec) { @@ -62,76 +58,6 @@ static int usb4_switch_wait_for_bit(struct tb_switch *sw, u32 offset, u32 bit, return -ETIMEDOUT; } -static int usb4_do_read_data(u16 address, void *buf, size_t size, - read_block_fn read_block, void *read_block_data) -{ - unsigned int retries = USB4_DATA_RETRIES; - unsigned int offset; - - do { - unsigned int dwaddress, dwords; - u8 data[USB4_DATA_DWORDS * 4]; - size_t nbytes; - int ret; - - offset = address & 3; - nbytes = min_t(size_t, size + offset, USB4_DATA_DWORDS * 4); - - dwaddress = address / 4; - dwords = ALIGN(nbytes, 4) / 4; - - ret = read_block(read_block_data, dwaddress, data, dwords); - if (ret) { - if (ret != -ENODEV && retries--) - continue; - return ret; - } - - nbytes -= offset; - memcpy(buf, data + offset, nbytes); - - size -= nbytes; - address += nbytes; - buf += nbytes; - } while (size > 0); - - return 0; -} - -static int usb4_do_write_data(unsigned int address, const void *buf, size_t size, - write_block_fn write_next_block, void *write_block_data) -{ - unsigned int retries = USB4_DATA_RETRIES; - unsigned int offset; - - offset = address & 3; - address = address & ~3; - - do { - u32 nbytes = min_t(u32, size, USB4_DATA_DWORDS * 4); - u8 data[USB4_DATA_DWORDS * 4]; - int ret; - - memcpy(data + offset, buf, nbytes); - - ret = write_next_block(write_block_data, data, nbytes / 4); - if (ret) { - if (ret == -ETIMEDOUT) { - if (retries--) - continue; - ret = -EIO; - } - return ret; - } - - size -= nbytes; - address += nbytes; - buf += nbytes; - } while (size > 0); - - return 0; -} - static int usb4_native_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata, u8 *status, const void *tx_data, size_t tx_dwords, @@ -193,7 +119,7 @@ static int __usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata, { const struct tb_cm_ops *cm_ops = sw->tb->cm_ops; - if (tx_dwords > USB4_DATA_DWORDS || rx_dwords > USB4_DATA_DWORDS) + if (tx_dwords > NVM_DATA_DWORDS || rx_dwords > NVM_DATA_DWORDS) return -EINVAL; /* @@ -414,8 +340,8 @@ static int usb4_switch_drom_read_block(void *data, int usb4_switch_drom_read(struct tb_switch *sw, unsigned int address, void *buf, size_t size) { - return usb4_do_read_data(address, buf, size, - usb4_switch_drom_read_block, sw); + return tb_nvm_read_data(address, buf, size, USB4_DATA_RETRIES, + usb4_switch_drom_read_block, sw); } /** @@ -595,8 +521,8 @@ static int usb4_switch_nvm_read_block(void *data, int usb4_switch_nvm_read(struct tb_switch *sw, unsigned int address, void *buf, size_t size) { - return usb4_do_read_data(address, buf, size, - usb4_switch_nvm_read_block, sw); + return tb_nvm_read_data(address, buf, size, USB4_DATA_RETRIES, + usb4_switch_nvm_read_block, sw); } static int usb4_switch_nvm_set_offset(struct tb_switch *sw, @@ -618,8 +544,8 @@ static int usb4_switch_nvm_set_offset(struct tb_switch *sw, return status ? -EIO : 0; } -static int usb4_switch_nvm_write_next_block(void *data, const void *buf, - size_t dwords) +static int usb4_switch_nvm_write_next_block(void *data, unsigned int dwaddress, + const void *buf, size_t dwords) { struct tb_switch *sw = data; u8 status; @@ -652,8 +578,8 @@ int usb4_switch_nvm_write(struct tb_switch *sw, unsigned int address, if (ret) return ret; - return usb4_do_write_data(address, buf, size, - usb4_switch_nvm_write_next_block, sw); + return tb_nvm_write_data(address, buf, size, USB4_DATA_RETRIES, + usb4_switch_nvm_write_next_block, sw); } /** @@ -1029,7 +955,7 @@ static int usb4_port_wait_for_bit(struct tb_port *port, u32 offset, u32 bit, static int usb4_port_read_data(struct tb_port *port, void *data, size_t dwords) { - if (dwords > USB4_DATA_DWORDS) + if (dwords > NVM_DATA_DWORDS) return -EINVAL; return tb_port_read(port, data, TB_CFG_PORT, port->cap_usb4 + PORT_CS_2, @@ -1039,7 +965,7 @@ static int usb4_port_read_data(struct tb_port *port, void *data, size_t dwords) static int usb4_port_write_data(struct tb_port *port, const void *data, size_t dwords) { - if (dwords > USB4_DATA_DWORDS) + if (dwords > NVM_DATA_DWORDS) return -EINVAL; return tb_port_write(port, data, TB_CFG_PORT, port->cap_usb4 + PORT_CS_2, @@ -1316,8 +1242,8 @@ struct retimer_info { u8 index; }; -static int usb4_port_retimer_nvm_write_next_block(void *data, const void *buf, - size_t dwords) +static int usb4_port_retimer_nvm_write_next_block(void *data, + unsigned int dwaddress, const void *buf, size_t dwords) { const struct retimer_info *info = data; @@ -1357,8 +1283,8 @@ int usb4_port_retimer_nvm_write(struct tb_port *port, u8 index, unsigned int add if (ret) return ret; - return usb4_do_write_data(address, buf, size, - usb4_port_retimer_nvm_write_next_block, &info); + return tb_nvm_write_data(address, buf, size, USB4_DATA_RETRIES, + usb4_port_retimer_nvm_write_next_block, &info); } /** @@ -1442,7 +1368,7 @@ static int usb4_port_retimer_nvm_read_block(void *data, unsigned int dwaddress, int ret; metadata = dwaddress << USB4_NVM_READ_OFFSET_SHIFT; - if (dwords < USB4_DATA_DWORDS) + if (dwords < NVM_DATA_DWORDS) metadata |= dwords << USB4_NVM_READ_LENGTH_SHIFT; ret = usb4_port_retimer_write(port, index, USB4_SB_METADATA, &metadata, @@ -1475,8 +1401,8 @@ int usb4_port_retimer_nvm_read(struct tb_port *port, u8 index, { struct retimer_info info = { .port = port, .index = index }; - return usb4_do_read_data(address, buf, size, - usb4_port_retimer_nvm_read_block, &info); + return tb_nvm_read_data(address, buf, size, USB4_DATA_RETRIES, + usb4_port_retimer_nvm_read_block, &info); } /** From patchwork Wed Aug 25 05:23:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai-Heng Feng X-Patchwork-Id: 1520523 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=tMhL3Xxi; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GvZDY30ndz9sW8; Wed, 25 Aug 2021 15:25:01 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mIlPF-0007Al-Ua; Wed, 25 Aug 2021 05:24:57 +0000 Received: from smtp-relay-canonical-0.internal ([10.131.114.83] helo=smtp-relay-canonical-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mIlOy-000763-At for kernel-team@lists.ubuntu.com; Wed, 25 Aug 2021 05:24:40 +0000 Received: from localhost.localdomain (1.general.khfeng.us.vpn [10.172.68.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-0.canonical.com (Postfix) with ESMTPSA id 3658C40C9E for ; Wed, 25 Aug 2021 05:24:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1629869080; bh=0aFPrz/aw4n8JROhghE+82OeLMR6s0Vcw930wUDHu2Y=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tMhL3XxiTAnlDFViUadIleo3GgPTfwXS6Q9R100pVIpUgxasnT57kAZGj24ZpoA3B /Scw4qARYWuR4dSg4kTYMN0WlAzMgvdK8q3axU3ZptO6RoqvUowVMK/KKa6Ipjt/Jp tfZLmfa9GuG/D3d3tvcf4AzFUaBJgSLXJyUIszOzgQtYFXep+Z+88uBVtfNKyumDjs f3Kn21wy0FYrNCkd6gSkjSuC+ULJA9oSn7l4yiAR40XNXgl3+wXrTQZSZPc43ZtmNV Xhd3d/5DkLkYSTHla38kclZTac1me5QgMQ9OwS2ZzUMl0ZfHUJPLdrJ7MZ/Hdot/yc fa14Z+TBAc2HQ== From: Kai-Heng Feng To: kernel-team@lists.ubuntu.com Subject: [SRU] [I/OEM-5.13] [PATCH 2/7] thunderbolt: Make tb_port_type() take const parameter Date: Wed, 25 Aug 2021 13:23:30 +0800 Message-Id: <20210825052335.53234-3-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210825052335.53234-1-kai.heng.feng@canonical.com> References: <20210825052335.53234-1-kai.heng.feng@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Mika Westerberg BugLink: https://bugs.launchpad.net/bugs/1941036 The function does not modify the object in any way so make the parameter const to reflect this. No functional changes intended. Signed-off-by: Mika Westerberg (cherry picked from commit 1c561e4e659d59f1f2825dec42f09338eac1c774) Signed-off-by: Kai-Heng Feng --- drivers/thunderbolt/switch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index a82032c081e83..95dcb2ae14163 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -459,7 +459,7 @@ static void tb_switch_nvm_remove(struct tb_switch *sw) /* port utility functions */ -static const char *tb_port_type(struct tb_regs_port_header *port) +static const char *tb_port_type(const struct tb_regs_port_header *port) { switch (port->type >> 16) { case 0: From patchwork Wed Aug 25 05:23:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai-Heng Feng X-Patchwork-Id: 1520526 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=vpLWWw4c; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GvZDw60lnz9sWc; Wed, 25 Aug 2021 15:25:20 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mIlPZ-0007Lt-Jz; Wed, 25 Aug 2021 05:25:17 +0000 Received: from smtp-relay-canonical-0.internal ([10.131.114.83] helo=smtp-relay-canonical-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mIlP0-00076S-9M for kernel-team@lists.ubuntu.com; Wed, 25 Aug 2021 05:24:42 +0000 Received: from localhost.localdomain (1.general.khfeng.us.vpn [10.172.68.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-0.canonical.com (Postfix) with ESMTPSA id D224F3F361 for ; Wed, 25 Aug 2021 05:24:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1629869081; bh=XMfGZtCFJpoMMXzXb967GXmIZlALGUYpeqgvBXyspFQ=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=vpLWWw4cH1oDkrp7noHmPgiF0ExwuiPU0vn+0JKDgaK4Dmz78tUvIEs66BQQpsuHG G/xSDtuFqQwczpbPub2F699tYPmh2zrDaCW47JzeAeirbD8EmKK64jWveotbd0CeNv ggEmcyyJnGe/AMIvSekUsj+ekjwlS7UzOWK7XNr0ZqJSGYkax5jC5NZhb3npG/YHIL yyFlMgskC+VndTU24NtI6LPae4jg9TsYYhuhwxu4ZJzihySF19CiXgYC9juKZTl6Vs GAW3bdfSGRlXGb6KL2rtos7zrQIplEuY422K6VF9mpgZWomS7XT0AM6gzriB7+Ypl/ 9hTShjKg43vYg== From: Kai-Heng Feng To: kernel-team@lists.ubuntu.com Subject: [SRU] [I/OEM-5.13] [PATCH 3/7] thunderbolt: Read router preferred credit allocation information Date: Wed, 25 Aug 2021 13:23:31 +0800 Message-Id: <20210825052335.53234-4-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210825052335.53234-1-kai.heng.feng@canonical.com> References: <20210825052335.53234-1-kai.heng.feng@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Mika Westerberg BugLink: https://bugs.launchpad.net/bugs/1941036 USB4 routers must expose their preferred credit (buffer) allocation information through router operation. This information tells the connection manager how the router prefers its buffers to be allocated to get the expected bandwidth for the supported protocols. Read this information and store it as part of struct tb_switch for each USB4 router. Signed-off-by: Mika Westerberg (cherry picked from commit 56ad3aef5cdac0695944985f7f70209aec0efd4d) Signed-off-by: Kai-Heng Feng --- drivers/thunderbolt/switch.c | 51 +++++++++-- drivers/thunderbolt/tb.h | 22 +++++ drivers/thunderbolt/tb_regs.h | 1 + drivers/thunderbolt/usb4.c | 155 ++++++++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+), 8 deletions(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 95dcb2ae14163..448931066cfbb 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -488,17 +488,21 @@ static const char *tb_port_type(const struct tb_regs_port_header *port) } } -static void tb_dump_port(struct tb *tb, struct tb_regs_port_header *port) +static void tb_dump_port(struct tb *tb, const struct tb_port *port) { + const struct tb_regs_port_header *regs = &port->config; + tb_dbg(tb, " Port %d: %x:%x (Revision: %d, TB Version: %d, Type: %s (%#x))\n", - port->port_number, port->vendor_id, port->device_id, - port->revision, port->thunderbolt_version, tb_port_type(port), - port->type); + regs->port_number, regs->vendor_id, regs->device_id, + regs->revision, regs->thunderbolt_version, tb_port_type(regs), + regs->type); tb_dbg(tb, " Max hop id (in/out): %d/%d\n", - port->max_in_hop_id, port->max_out_hop_id); - tb_dbg(tb, " Max counters: %d\n", port->max_counters); - tb_dbg(tb, " NFC Credits: %#x\n", port->nfc_credits); + regs->max_in_hop_id, regs->max_out_hop_id); + tb_dbg(tb, " Max counters: %d\n", regs->max_counters); + tb_dbg(tb, " NFC Credits: %#x\n", regs->nfc_credits); + tb_dbg(tb, " Credits (total/control): %u/%u\n", port->total_credits, + port->ctl_credits); } /** @@ -738,13 +742,32 @@ static int tb_init_port(struct tb_port *port) cap = tb_port_find_cap(port, TB_PORT_CAP_USB4); if (cap > 0) port->cap_usb4 = cap; + + /* + * USB4 ports the buffers allocated for the control path + * can be read from the path config space. Legacy + * devices we use hard-coded value. + */ + if (tb_switch_is_usb4(port->sw)) { + struct tb_regs_hop hop; + + if (!tb_port_read(port, &hop, TB_CFG_HOPS, 0, 2)) + port->ctl_credits = hop.initial_credits; + } + if (!port->ctl_credits) + port->ctl_credits = 2; + } else if (port->port != 0) { cap = tb_port_find_cap(port, TB_PORT_CAP_ADAP); if (cap > 0) port->cap_adap = cap; } - tb_dump_port(port->sw->tb, &port->config); + port->total_credits = + (port->config.nfc_credits & ADP_CS_4_TOTAL_BUFFERS_MASK) >> + ADP_CS_4_TOTAL_BUFFERS_SHIFT; + + tb_dump_port(port->sw->tb, port); INIT_LIST_HEAD(&port->list); return 0; @@ -2516,6 +2539,16 @@ void tb_switch_unconfigure_link(struct tb_switch *sw) tb_lc_unconfigure_port(down); } +static void tb_switch_credits_init(struct tb_switch *sw) +{ + if (tb_switch_is_icm(sw)) + return; + if (!tb_switch_is_usb4(sw)) + return; + if (usb4_switch_credits_init(sw)) + tb_sw_info(sw, "failed to determine preferred buffer allocation, using defaults\n"); +} + /** * tb_switch_add() - Add a switch to the domain * @sw: Switch to add @@ -2546,6 +2579,8 @@ int tb_switch_add(struct tb_switch *sw) } if (!sw->safe_mode) { + tb_switch_credits_init(sw); + /* read drom */ ret = tb_drom_read(sw); if (ret) { diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index d9d1adc4cfd33..bb66a855c871e 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -136,6 +136,12 @@ struct tb_switch_tmu { * @rpm_complete: Completion used to wait for runtime resume to * complete (ICM only) * @quirks: Quirks used for this Thunderbolt switch + * @credit_allocation: Are the below buffer allocation parameters valid + * @max_usb3_credits: Router preferred number of buffers for USB 3.x + * @min_dp_aux_credits: Router preferred minimum number of buffers for DP AUX + * @min_dp_main_credits: Router preferred minimum number of buffers for DP MAIN + * @max_pcie_credits: Router preferred number of buffers for PCIe + * @max_dma_credits: Router preferred number of buffers for DMA/P2P * * When the switch is being added or removed to the domain (other * switches) you need to have domain lock held. @@ -178,6 +184,12 @@ struct tb_switch { u8 depth; struct completion rpm_complete; unsigned long quirks; + bool credit_allocation; + unsigned int max_usb3_credits; + unsigned int min_dp_aux_credits; + unsigned int min_dp_main_credits; + unsigned int max_pcie_credits; + unsigned int max_dma_credits; }; /** @@ -199,6 +211,8 @@ struct tb_switch { * @in_hopids: Currently allocated input HopIDs * @out_hopids: Currently allocated output HopIDs * @list: Used to link ports to DP resources list + * @total_credits: Total number of buffers available for this port + * @ctl_credits: Buffers reserved for control path * * In USB4 terminology this structure represents an adapter (protocol or * lane adapter). @@ -220,6 +234,8 @@ struct tb_port { struct ida in_hopids; struct ida out_hopids; struct list_head list; + unsigned int total_credits; + unsigned int ctl_credits; }; /** @@ -864,6 +880,11 @@ 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); +static inline bool tb_port_use_credit_allocation(const struct tb_port *port) +{ + return tb_port_is_null(port) && port->sw->credit_allocation; +} + /** * tb_for_each_port_on_path() - Iterate over each port on path * @src: Source port @@ -990,6 +1011,7 @@ int usb4_switch_nvm_write(struct tb_switch *sw, unsigned int address, const void *buf, size_t size); int usb4_switch_nvm_authenticate(struct tb_switch *sw); int usb4_switch_nvm_authenticate_status(struct tb_switch *sw, u32 *status); +int usb4_switch_credits_init(struct tb_switch *sw); bool usb4_switch_query_dp_resource(struct tb_switch *sw, struct tb_port *in); int usb4_switch_alloc_dp_resource(struct tb_switch *sw, struct tb_port *in); int usb4_switch_dealloc_dp_resource(struct tb_switch *sw, struct tb_port *in); diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h index 626751e062920..c585210613212 100644 --- a/drivers/thunderbolt/tb_regs.h +++ b/drivers/thunderbolt/tb_regs.h @@ -228,6 +228,7 @@ enum usb4_switch_op { USB4_SWITCH_OP_NVM_SET_OFFSET = 0x23, USB4_SWITCH_OP_DROM_READ = 0x24, USB4_SWITCH_OP_NVM_SECTOR_SIZE = 0x25, + USB4_SWITCH_OP_BUFFER_ALLOC = 0x33, }; /* Router TMU configuration */ diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index c0a14bfa36d41..8ecb285f3a7ea 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -36,6 +36,20 @@ enum usb4_sb_target { #define USB4_NVM_SECTOR_SIZE_MASK GENMASK(23, 0) +#define USB4_BA_LENGTH_MASK GENMASK(7, 0) +#define USB4_BA_INDEX_MASK GENMASK(15, 0) + +enum usb4_ba_index { + USB4_BA_MAX_USB3 = 0x1, + USB4_BA_MIN_DP_AUX = 0x2, + USB4_BA_MIN_DP_MAIN = 0x3, + USB4_BA_MAX_PCIE = 0x4, + USB4_BA_MAX_HI = 0x5, +}; + +#define USB4_BA_VALUE_MASK GENMASK(31, 16) +#define USB4_BA_VALUE_SHIFT 16 + static int usb4_switch_wait_for_bit(struct tb_switch *sw, u32 offset, u32 bit, u32 value, int timeout_msec) { @@ -661,6 +675,147 @@ int usb4_switch_nvm_authenticate_status(struct tb_switch *sw, u32 *status) return 0; } +/** + * usb4_switch_credits_init() - Read buffer allocation parameters + * @sw: USB4 router + * + * Reads @sw buffer allocation parameters and initializes @sw buffer + * allocation fields accordingly. Specifically @sw->credits_allocation + * is set to %true if these parameters can be used in tunneling. + * + * Returns %0 on success and negative errno otherwise. + */ +int usb4_switch_credits_init(struct tb_switch *sw) +{ + int max_usb3, min_dp_aux, min_dp_main, max_pcie, max_dma; + int ret, length, i, nports; + const struct tb_port *port; + u32 data[NVM_DATA_DWORDS]; + u32 metadata = 0; + u8 status = 0; + + memset(data, 0, sizeof(data)); + ret = usb4_switch_op_data(sw, USB4_SWITCH_OP_BUFFER_ALLOC, &metadata, + &status, NULL, 0, data, ARRAY_SIZE(data)); + if (ret) + return ret; + if (status) + return -EIO; + + length = metadata & USB4_BA_LENGTH_MASK; + if (WARN_ON(length > ARRAY_SIZE(data))) + return -EMSGSIZE; + + max_usb3 = -1; + min_dp_aux = -1; + min_dp_main = -1; + max_pcie = -1; + max_dma = -1; + + tb_sw_dbg(sw, "credit allocation parameters:\n"); + + for (i = 0; i < length; i++) { + u16 index, value; + + index = data[i] & USB4_BA_INDEX_MASK; + value = (data[i] & USB4_BA_VALUE_MASK) >> USB4_BA_VALUE_SHIFT; + + switch (index) { + case USB4_BA_MAX_USB3: + tb_sw_dbg(sw, " USB3: %u\n", value); + max_usb3 = value; + break; + case USB4_BA_MIN_DP_AUX: + tb_sw_dbg(sw, " DP AUX: %u\n", value); + min_dp_aux = value; + break; + case USB4_BA_MIN_DP_MAIN: + tb_sw_dbg(sw, " DP main: %u\n", value); + min_dp_main = value; + break; + case USB4_BA_MAX_PCIE: + tb_sw_dbg(sw, " PCIe: %u\n", value); + max_pcie = value; + break; + case USB4_BA_MAX_HI: + tb_sw_dbg(sw, " DMA: %u\n", value); + max_dma = value; + break; + default: + tb_sw_dbg(sw, " unknown credit allocation index %#x, skipping\n", + index); + break; + } + } + + /* + * Validate the buffer allocation preferences. If we find + * issues, log a warning and fall back using the hard-coded + * values. + */ + + /* Host router must report baMaxHI */ + if (!tb_route(sw) && max_dma < 0) { + tb_sw_warn(sw, "host router is missing baMaxHI\n"); + goto err_invalid; + } + + nports = 0; + tb_switch_for_each_port(sw, port) { + if (tb_port_is_null(port)) + nports++; + } + + /* Must have DP buffer allocation (multiple USB4 ports) */ + if (nports > 2 && (min_dp_aux < 0 || min_dp_main < 0)) { + tb_sw_warn(sw, "multiple USB4 ports require baMinDPaux/baMinDPmain\n"); + goto err_invalid; + } + + tb_switch_for_each_port(sw, port) { + if (tb_port_is_dpout(port) && min_dp_main < 0) { + tb_sw_warn(sw, "missing baMinDPmain"); + goto err_invalid; + } + if ((tb_port_is_dpin(port) || tb_port_is_dpout(port)) && + min_dp_aux < 0) { + tb_sw_warn(sw, "missing baMinDPaux"); + goto err_invalid; + } + if ((tb_port_is_usb3_down(port) || tb_port_is_usb3_up(port)) && + max_usb3 < 0) { + tb_sw_warn(sw, "missing baMaxUSB3"); + goto err_invalid; + } + if ((tb_port_is_pcie_down(port) || tb_port_is_pcie_up(port)) && + max_pcie < 0) { + tb_sw_warn(sw, "missing baMaxPCIe"); + goto err_invalid; + } + } + + /* + * Buffer allocation passed the validation so we can use it in + * path creation. + */ + sw->credit_allocation = true; + if (max_usb3 > 0) + sw->max_usb3_credits = max_usb3; + if (min_dp_aux > 0) + sw->min_dp_aux_credits = min_dp_aux; + if (min_dp_main > 0) + sw->min_dp_main_credits = min_dp_main; + if (max_pcie > 0) + sw->max_pcie_credits = max_pcie; + if (max_dma > 0) + sw->max_dma_credits = max_dma; + + return 0; + +err_invalid: + return -EINVAL; +} + /** * usb4_switch_query_dp_resource() - Query availability of DP IN resource * @sw: USB4 router From patchwork Wed Aug 25 05:23:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai-Heng Feng X-Patchwork-Id: 1520527 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=fG9Erw2s; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GvZF12mrQz9sX2; Wed, 25 Aug 2021 15:25:25 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mIlPd-0007Nn-Qk; Wed, 25 Aug 2021 05:25:21 +0000 Received: from smtp-relay-canonical-0.internal ([10.131.114.83] helo=smtp-relay-canonical-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mIlP1-00076h-VD for kernel-team@lists.ubuntu.com; Wed, 25 Aug 2021 05:24:43 +0000 Received: from localhost.localdomain (1.general.khfeng.us.vpn [10.172.68.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-0.canonical.com (Postfix) with ESMTPSA id CB2B23F361 for ; Wed, 25 Aug 2021 05:24:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1629869083; bh=jjaJxW4PQjtwz4qv7waqdnfmjhYMzRYxesZ2wAS1P2Q=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fG9Erw2sLWNCrZDrITT78ARkXIQ8xrFsGHq2xF3UAB26XIx2E+ldwpa5UhsWmPs6c Hvs99PFEYem8BuLKzN/Ig5HISWTlmic0IaYz6seawQv8Fzm0dxGN9EU894FfyLgUri Z5cd2TOzufUpdez7WtFX/f4B5/2REp05rdIlB7GixawJbIX/PkOSUc5fLu75N/YCx4 PYwoikJ6vEDwwAEW7SnQ9XXAjnmOOoJPU+R65z3p5xl73KPSgjMht/GfK8Bgbl4CAv OMgWVgU/j6S1+64pIl0uH7bdaPg14IK5fz+RaZ7qTvp0vm/ojaJ2Hb5moYGMcqaCyl RGBw61zbldSAg== From: Kai-Heng Feng To: kernel-team@lists.ubuntu.com Subject: [SRU] [I/Unstable/OEM-5.13] [PATCH 4/7] thunderbolt: Add vendor specific NHI quirk for auto-clearing interrupt status Date: Wed, 25 Aug 2021 13:23:32 +0800 Message-Id: <20210825052335.53234-5-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210825052335.53234-1-kai.heng.feng@canonical.com> References: <20210825052335.53234-1-kai.heng.feng@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Sanjay R Mehta BugLink: https://bugs.launchpad.net/bugs/1941036 Introduce nhi_check_quirks() routine to handle any vendor specific quirks to manage a hardware specific implementation. On Intel hardware the USB4 controller supports clearing the interrupt status register automatically right after it is being issued. For this reason add a new quirk that does that on all Intel hardware. Signed-off-by: Basavaraj Natikar Signed-off-by: Sanjay R Mehta Signed-off-by: Mika Westerberg (cherry picked from commit e390909ac763589558ffb91856f121820f933e4b linux-next) Signed-off-by: Kai-Heng Feng --- drivers/thunderbolt/nhi.c | 33 +++++++++++++++++++++++++-------- include/linux/thunderbolt.h | 2 ++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index bfb780601e292..c044a64420752 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -36,6 +36,8 @@ #define NHI_MAILBOX_TIMEOUT 500 /* ms */ +#define QUIRK_AUTO_CLEAR_INT BIT(0) + static int ring_interrupt_index(struct tb_ring *ring) { int bit = ring->hop; @@ -67,14 +69,17 @@ static void ring_interrupt_active(struct tb_ring *ring, bool active) else index = ring->hop + ring->nhi->hop_count; - /* - * Ask the hardware to clear interrupt status bits automatically - * since we already know which interrupt was triggered. - */ - misc = ioread32(ring->nhi->iobase + REG_DMA_MISC); - if (!(misc & REG_DMA_MISC_INT_AUTO_CLEAR)) { - misc |= REG_DMA_MISC_INT_AUTO_CLEAR; - iowrite32(misc, ring->nhi->iobase + REG_DMA_MISC); + if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) { + /* + * Ask the hardware to clear interrupt status + * bits automatically since we already know + * which interrupt was triggered. + */ + misc = ioread32(ring->nhi->iobase + REG_DMA_MISC); + if (!(misc & REG_DMA_MISC_INT_AUTO_CLEAR)) { + misc |= REG_DMA_MISC_INT_AUTO_CLEAR; + iowrite32(misc, ring->nhi->iobase + REG_DMA_MISC); + } } ivr_base = ring->nhi->iobase + REG_INT_VEC_ALLOC_BASE; @@ -1075,6 +1080,16 @@ static void nhi_shutdown(struct tb_nhi *nhi) nhi->ops->shutdown(nhi); } +static void nhi_check_quirks(struct tb_nhi *nhi) +{ + /* + * Intel hardware supports auto clear of the interrupt status + * reqister right after interrupt is being issued. + */ + if (nhi->pdev->vendor == PCI_VENDOR_ID_INTEL) + nhi->quirks |= QUIRK_AUTO_CLEAR_INT; +} + static int nhi_init_msi(struct tb_nhi *nhi) { struct pci_dev *pdev = nhi->pdev; @@ -1254,6 +1269,8 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (!nhi->tx_rings || !nhi->rx_rings) return -ENOMEM; + nhi_check_quirks(nhi); + res = nhi_init_msi(nhi); if (res) { dev_err(&pdev->dev, "cannot enable MSI, aborting\n"); diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h index e7c96c37174f1..124e13cb1469c 100644 --- a/include/linux/thunderbolt.h +++ b/include/linux/thunderbolt.h @@ -468,6 +468,7 @@ static inline struct tb_xdomain *tb_service_parent(struct tb_service *svc) * @interrupt_work: Work scheduled to handle ring interrupt when no * MSI-X is used. * @hop_count: Number of rings (end point hops) supported by NHI. + * @quirks: NHI specific quirks if any */ struct tb_nhi { spinlock_t lock; @@ -480,6 +481,7 @@ struct tb_nhi { bool going_away; struct work_struct interrupt_work; u32 hop_count; + unsigned long quirks; }; /** From patchwork Wed Aug 25 05:23:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai-Heng Feng X-Patchwork-Id: 1520525 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=IaCBM1Cy; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GvZDk1B4Fz9sXN; Wed, 25 Aug 2021 15:25:10 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mIlPO-0007GA-2K; Wed, 25 Aug 2021 05:25:06 +0000 Received: from smtp-relay-canonical-0.internal ([10.131.114.83] helo=smtp-relay-canonical-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mIlP3-00076r-LZ for kernel-team@lists.ubuntu.com; Wed, 25 Aug 2021 05:24:45 +0000 Received: from localhost.localdomain (1.general.khfeng.us.vpn [10.172.68.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-0.canonical.com (Postfix) with ESMTPSA id 7CCDC3F361 for ; Wed, 25 Aug 2021 05:24:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1629869085; bh=HerCpIDNim66jLaeDgSzNEV7Iz/ElL/jo/zkmswuOns=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IaCBM1CyTkPqJlU7MaleC4SRpJwquQxy6AXQ9FqZjfKyFu/g+RAi38AgeqO34vlP0 GOg3WHiWlJiiJKN1syweZPKFcmoy5K6xvZUfj5FQhC1+PrcXOf3XfqImaA3Ag65sF7 6DFb+bUVUxNRu5f/DIG8a1D4mj1zZVxuOcZem9ZzGSDLz67i7/qljXsOWkDRp8bzBY 9tV2CbnbhQWbsEk6hDOwJexMEF19nr1YSYZn2K70eKvxYWoZfEXRTEYVlcmnDyNhT8 WR3jMaZY3v47tTi5Tjd4N74oYF0pIOrFilKm/BICcVLghdSNYqfo00wwml6gVYPkwr Aw7bAero/8gmQ== From: Kai-Heng Feng To: kernel-team@lists.ubuntu.com Subject: [SRU] [I/Unstable/OEM-5.13] [PATCH 5/7] thunderbolt: Handle ring interrupt by reading interrupt status register Date: Wed, 25 Aug 2021 13:23:33 +0800 Message-Id: <20210825052335.53234-6-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210825052335.53234-1-kai.heng.feng@canonical.com> References: <20210825052335.53234-1-kai.heng.feng@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Sanjay R Mehta BugLink: https://bugs.launchpad.net/bugs/1941036 As per USB4 specification by default "Disable ISR Auto-Clear" bit is set to zero and the Tx/Rx ring interrupt status needs to be cleared. Hence handle it by reading the interrupt status register (ISR) in the MSI-X handler. Signed-off-by: Basavaraj Natikar Signed-off-by: Sanjay R Mehta Signed-off-by: Mika Westerberg (cherry picked from commit 7a1808f82a37d638ee6862175e8e5c5433fdd642 linux-next) Signed-off-by: Kai-Heng Feng --- drivers/thunderbolt/nhi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index c044a64420752..98aac1cd328ce 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -383,11 +383,24 @@ void tb_ring_poll_complete(struct tb_ring *ring) } EXPORT_SYMBOL_GPL(tb_ring_poll_complete); +static void ring_clear_msix(const struct tb_ring *ring) +{ + if (ring->nhi->quirks & QUIRK_AUTO_CLEAR_INT) + return; + + if (ring->is_tx) + ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE); + else + ioread32(ring->nhi->iobase + REG_RING_NOTIFY_BASE + + 4 * (ring->nhi->hop_count / 32)); +} + static irqreturn_t ring_msix(int irq, void *data) { struct tb_ring *ring = data; spin_lock(&ring->nhi->lock); + ring_clear_msix(ring); spin_lock(&ring->lock); __ring_interrupt(ring); spin_unlock(&ring->lock); From patchwork Wed Aug 25 05:23:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai-Heng Feng X-Patchwork-Id: 1520522 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=lINqeITk; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GvZDS2pQQz9sxS; Wed, 25 Aug 2021 15:24:56 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mIlPA-00078L-Op; Wed, 25 Aug 2021 05:24:52 +0000 Received: from smtp-relay-canonical-0.internal ([10.131.114.83] helo=smtp-relay-canonical-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mIlP5-000777-6Y for kernel-team@lists.ubuntu.com; Wed, 25 Aug 2021 05:24:47 +0000 Received: from localhost.localdomain (1.general.khfeng.us.vpn [10.172.68.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-0.canonical.com (Postfix) with ESMTPSA id 2D7703F361 for ; Wed, 25 Aug 2021 05:24:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1629869086; bh=5/SKK78X+OeiF2CAS3Acq/U1L0wRaWVRLZcKRcWoiT4=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=lINqeITkiTjtQ9HxMUoSQBWHNMXizF6QzX1LsEbuAi71xq1aHZzewTIX3s8PhBhQY pUggbetBu/cb3SzIRk5oVffePqqZ0GNFg3V9TfBjzs1NcqS9eLfxgs6VP3SM6kgLnt hSmHMZ+Pm5FrEngpwb91XuOnZEdBS9/TXuSi5KhVQA+x3aAgPBytYSNvgBpPyr212d t2Rudt1b1I5vyFEl7LI9nzVGwa9vTPFKAyF3LJth/9pf4w5VDgQTSii6+w/r4h0pVN MHPICsDg5wYahAuikM0+eXYBU7v7Fu6tuOs7N+etozYWs3WwZMb378PWvhNWYPDFQc +yOdQE8bQYMyA== From: Kai-Heng Feng To: kernel-team@lists.ubuntu.com Subject: [SRU] [I/Unstable/OEM-5.13] [PATCH 6/7] thunderbolt: Do not read control adapter config space Date: Wed, 25 Aug 2021 13:23:34 +0800 Message-Id: <20210825052335.53234-7-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210825052335.53234-1-kai.heng.feng@canonical.com> References: <20210825052335.53234-1-kai.heng.feng@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Sanjay R Mehta BugLink: https://bugs.launchpad.net/bugs/1941036 Adapter 0 is the control adapter and as per USB4 spec in section 2.2.6.2 control Adapters do not have an adapter configuration space. For this reason skip reading adapter config space in tb_port_init() when the port number is 0. This actually simplifies the rest of the function as we don't need to check for the port->port == 0 anymore. While there drop the extra empty line at the end of the function. Signed-off-by: Basavaraj Natikar Signed-off-by: Sanjay R Mehta Signed-off-by: Mika Westerberg (cherry picked from commit fb7a89ad2f048489605611801d480c7bb9d03f94 linux-next) Signed-off-by: Kai-Heng Feng --- drivers/thunderbolt/switch.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 448931066cfbb..344402d1cf9c4 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -719,6 +719,12 @@ static int tb_init_port(struct tb_port *port) int res; int cap; + INIT_LIST_HEAD(&port->list); + + /* Control adapter does not have configuration space */ + if (!port->port) + return 0; + res = tb_port_read(port, &port->config, TB_CFG_PORT, 0, 8); if (res) { if (res == -ENODEV) { @@ -731,7 +737,7 @@ static int tb_init_port(struct tb_port *port) } /* Port 0 is the switch itself and has no PHY. */ - if (port->config.type == TB_TYPE_PORT && port->port != 0) { + if (port->config.type == TB_TYPE_PORT) { cap = tb_port_find_cap(port, TB_PORT_CAP_PHY); if (cap > 0) @@ -757,7 +763,7 @@ static int tb_init_port(struct tb_port *port) if (!port->ctl_credits) port->ctl_credits = 2; - } else if (port->port != 0) { + } else { cap = tb_port_find_cap(port, TB_PORT_CAP_ADAP); if (cap > 0) port->cap_adap = cap; @@ -768,10 +774,7 @@ static int tb_init_port(struct tb_port *port) ADP_CS_4_TOTAL_BUFFERS_SHIFT; tb_dump_port(port->sw->tb, port); - - INIT_LIST_HEAD(&port->list); return 0; - } static int tb_port_alloc_hopid(struct tb_port *port, bool in, int min_hopid, From patchwork Wed Aug 25 05:23:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai-Heng Feng X-Patchwork-Id: 1520524 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=RP7akOZn; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GvZDd2cWrz9sW8; Wed, 25 Aug 2021 15:25:05 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mIlPJ-0007CX-6O; Wed, 25 Aug 2021 05:25:01 +0000 Received: from smtp-relay-canonical-0.internal ([10.131.114.83] helo=smtp-relay-canonical-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mIlP6-00077Q-NT for kernel-team@lists.ubuntu.com; Wed, 25 Aug 2021 05:24:48 +0000 Received: from localhost.localdomain (1.general.khfeng.us.vpn [10.172.68.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-0.canonical.com (Postfix) with ESMTPSA id 9EAC93F361 for ; Wed, 25 Aug 2021 05:24:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1629869088; bh=hNxh/CCcoIIuRdFs5Rjfzyf1IvzSSwSYw2QrT4HYWWY=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RP7akOZniHbaYZ5z47rTA5jafWCXcFKkspYpQ9un/mzgG5nFIQmh9xFKDEmLyWCxc uIlm4C0dpEDuYfkbfyFfZY6/Hyo1phuhUX7JUcLvgsdXBtvp9Z6aHkOS9kUan1vTV7 D2gK4Ekukh8eWDVM1xbDlvj8Qtjf346P/cogO7Nm6URSL6pk8pLU27HBHrz8CG3oUJ ESxP0CK6DguQqdjh8QwvkisM6x2cBtoBXplB5RD/gPvMODtQ+lpUD7e/r76AQ519rq DXgvyq4a1jWAug7WCnCEk0A0HRl70QOCe80/5eanREZRSP3vgT/wY8jl6Ext3V10dv XRcjyaV2cUXuQ== From: Kai-Heng Feng To: kernel-team@lists.ubuntu.com Subject: [SRU] [I/Unstable/OEM-5.13] [PATCH 7/7] thunderbolt: Fix port linking by checking all adapters Date: Wed, 25 Aug 2021 13:23:35 +0800 Message-Id: <20210825052335.53234-8-kai.heng.feng@canonical.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210825052335.53234-1-kai.heng.feng@canonical.com> References: <20210825052335.53234-1-kai.heng.feng@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Sanjay R Mehta BugLink: https://bugs.launchpad.net/bugs/1941036 In tb_switch_default_link_ports(), while linking of ports, only odd-numbered ports (1,3,5..) are considered and even-numbered ports are not considered. AMD host router has lane adapters at 2 and 3 and link ports at adapter 2 is not considered due to which lane bonding gets disabled. Hence added a fix such that all ports are considered during linking of ports. Signed-off-by: Basavaraj Natikar Signed-off-by: Sanjay R Mehta Signed-off-by: Mika Westerberg (cherry picked from commit 42716425ad7e1b6529ec61c260c11176841f4b5f linux-next) Signed-off-by: Kai-Heng Feng --- drivers/thunderbolt/switch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 344402d1cf9c4..7c265a75f5ccd 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -2334,7 +2334,7 @@ static void tb_switch_default_link_ports(struct tb_switch *sw) { int i; - for (i = 1; i <= sw->config.max_port_number; i += 2) { + for (i = 1; i <= sw->config.max_port_number; i++) { struct tb_port *port = &sw->ports[i]; struct tb_port *subordinate;