LKML Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support
@ 2020-11-19 15:55 Mika Westerberg
  2020-11-19 15:55 ` [PATCH 01/12] thunderbolt: Move max_boot_acl field to correct place in struct icm Mika Westerberg
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

Hi all,

This series improves the USB4 router NVM upgrade functionality and adds
support for USB4 router operations proxy implemented by recent Intel
Thunderbolt firmware connection manager. The last patch adds support for
Intel Maple Ridge that is the first discrete Thunderbolt/USB4 controller
from Intel.

This also includes a couple of minor cleanups and improvements around
debug logging.

Mika Westerberg (12):
  thunderbolt: Move max_boot_acl field to correct place in struct icm
  thunderbolt: Log which connection manager implementation is used
  thunderbolt: Log adapter numbers in decimal in path activation/deactivation
  thunderbolt: Keep the parent runtime resumed for a while on device disconnect
  thunderbolt: Return -ENOTCONN when ERR_CONN is received
  thunderbolt: Perform USB4 router NVM upgrade in two phases
  thunderbolt: Pass metadata directly to usb4_switch_op()
  thunderbolt: Pass TX and RX data directly to usb4_switch_op()
  thunderbolt: Add connection manager specific hooks for USB4 router operations
  thunderbolt: Move constants for USB4 router operations to tb_regs.h
  thunderbolt: Add USB4 router operation proxy for firmware connection manager
  thunderbolt: Add support for Intel Maple Ridge

 drivers/thunderbolt/ctl.c     |   3 +
 drivers/thunderbolt/icm.c     | 240 ++++++++++++++++++++++++++++--
 drivers/thunderbolt/nhi.h     |   1 +
 drivers/thunderbolt/path.c    |   4 +-
 drivers/thunderbolt/switch.c  |  20 ++-
 drivers/thunderbolt/tb.c      |   2 +
 drivers/thunderbolt/tb.h      |  14 ++
 drivers/thunderbolt/tb_msgs.h |  28 ++++
 drivers/thunderbolt/tb_regs.h |  14 ++
 drivers/thunderbolt/usb4.c    | 269 ++++++++++++++++++++--------------
 10 files changed, 473 insertions(+), 122 deletions(-)

-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 01/12] thunderbolt: Move max_boot_acl field to correct place in struct icm
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 02/12] thunderbolt: Log which connection manager implementation is used Mika Westerberg
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

This makes the kernel-doc to match the ordering and also this is better
place for it, not between upstream_port and vnd_cap that are used
together.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/icm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index b51fc3f62b1f..03e86817afc7 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -79,9 +79,9 @@ struct icm {
 	struct mutex request_lock;
 	struct delayed_work rescan_work;
 	struct pci_dev *upstream_port;
-	size_t max_boot_acl;
 	int vnd_cap;
 	bool safe_mode;
+	size_t max_boot_acl;
 	bool rpm;
 	bool can_upgrade_nvm;
 	bool veto;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 02/12] thunderbolt: Log which connection manager implementation is used
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
  2020-11-19 15:55 ` [PATCH 01/12] thunderbolt: Move max_boot_acl field to correct place in struct icm Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 03/12] thunderbolt: Log adapter numbers in decimal in path activation/deactivation Mika Westerberg
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

This makes it easier to figure out whether the driver is using firmware
or software based connection manager implementation.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/icm.c | 2 ++
 drivers/thunderbolt/tb.c  | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index 03e86817afc7..beee6e6b8b6e 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -2302,5 +2302,7 @@ struct tb *icm_probe(struct tb_nhi *nhi)
 		return NULL;
 	}
 
+	tb_dbg(tb, "using firmware connection manager\n");
+
 	return tb;
 }
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 214fbc92c1b7..51d5b031cada 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -1534,5 +1534,7 @@ struct tb *tb_probe(struct tb_nhi *nhi)
 	INIT_LIST_HEAD(&tcm->dp_resources);
 	INIT_DELAYED_WORK(&tcm->remove_work, tb_remove_work);
 
+	tb_dbg(tb, "using software connection manager\n");
+
 	return tb;
 }
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 03/12] thunderbolt: Log adapter numbers in decimal in path activation/deactivation
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
  2020-11-19 15:55 ` [PATCH 01/12] thunderbolt: Move max_boot_acl field to correct place in struct icm Mika Westerberg
  2020-11-19 15:55 ` [PATCH 02/12] thunderbolt: Log which connection manager implementation is used Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 04/12] thunderbolt: Keep the parent runtime resumed for a while on device disconnect Mika Westerberg
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

This makes it consistent with other debug logs that already are using
decimal number for adapters (ports).

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/path.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c
index 7c2c45d9ba4a..ca7d738d66de 100644
--- a/drivers/thunderbolt/path.c
+++ b/drivers/thunderbolt/path.c
@@ -454,7 +454,7 @@ void tb_path_deactivate(struct tb_path *path)
 		return;
 	}
 	tb_dbg(path->tb,
-	       "deactivating %s path from %llx:%x to %llx:%x\n",
+	       "deactivating %s path from %llx:%u to %llx:%u\n",
 	       path->name, tb_route(path->hops[0].in_port->sw),
 	       path->hops[0].in_port->port,
 	       tb_route(path->hops[path->path_length - 1].out_port->sw),
@@ -482,7 +482,7 @@ int tb_path_activate(struct tb_path *path)
 	}
 
 	tb_dbg(path->tb,
-	       "activating %s path from %llx:%x to %llx:%x\n",
+	       "activating %s path from %llx:%u to %llx:%u\n",
 	       path->name, tb_route(path->hops[0].in_port->sw),
 	       path->hops[0].in_port->port,
 	       tb_route(path->hops[path->path_length - 1].out_port->sw),
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 04/12] thunderbolt: Keep the parent runtime resumed for a while on device disconnect
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
                   ` (2 preceding siblings ...)
  2020-11-19 15:55 ` [PATCH 03/12] thunderbolt: Log adapter numbers in decimal in path activation/deactivation Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 05/12] thunderbolt: Return -ENOTCONN when ERR_CONN is received Mika Westerberg
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

When doing device firmware upgrade the device will disconnect for a
while and then reconnect back. Keep the parent device (and the whole
domain) powered for a while so we don't need to runtime resume
immediately when the device is connected back after the device upgrade
completes.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/icm.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index beee6e6b8b6e..635b949fb1d6 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -870,7 +870,13 @@ icm_fr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
 		return;
 	}
 
+	pm_runtime_get_sync(sw->dev.parent);
+
 	remove_switch(sw);
+
+	pm_runtime_mark_last_busy(sw->dev.parent);
+	pm_runtime_put_autosuspend(sw->dev.parent);
+
 	tb_switch_put(sw);
 }
 
@@ -1280,8 +1286,13 @@ icm_tr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
 		tb_warn(tb, "no switch exists at %llx, ignoring\n", route);
 		return;
 	}
+	pm_runtime_get_sync(sw->dev.parent);
 
 	remove_switch(sw);
+
+	pm_runtime_mark_last_busy(sw->dev.parent);
+	pm_runtime_put_autosuspend(sw->dev.parent);
+
 	tb_switch_put(sw);
 }
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 05/12] thunderbolt: Return -ENOTCONN when ERR_CONN is received
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
                   ` (3 preceding siblings ...)
  2020-11-19 15:55 ` [PATCH 04/12] thunderbolt: Keep the parent runtime resumed for a while on device disconnect Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 06/12] thunderbolt: Perform USB4 router NVM upgrade in two phases Mika Westerberg
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

This allows the calling code to distinguish if the error was due to
ERR_CONN (adapter is disconneced or disabled) or something else. Will be
needed in USB4 router NVM update in the following patch.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/ctl.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c
index 1d86e27a0ef3..bac08b820015 100644
--- a/drivers/thunderbolt/ctl.c
+++ b/drivers/thunderbolt/ctl.c
@@ -962,6 +962,9 @@ static int tb_cfg_get_error(struct tb_ctl *ctl, enum tb_cfg_space space,
 
 	if (res->tb_error == TB_CFG_ERROR_LOCK)
 		return -EACCES;
+	else if (res->tb_error == TB_CFG_ERROR_PORT_NOT_CONNECTED)
+		return -ENOTCONN;
+
 	return -EIO;
 }
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 06/12] thunderbolt: Perform USB4 router NVM upgrade in two phases
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
                   ` (4 preceding siblings ...)
  2020-11-19 15:55 ` [PATCH 05/12] thunderbolt: Return -ENOTCONN when ERR_CONN is received Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 07/12] thunderbolt: Pass metadata directly to usb4_switch_op() Mika Westerberg
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

The currect code expects that the router returns back the status of the
NVM authentication immediately. When tested against a real USB4 device
what happens is that the router is reset and only after that the result
is updated in the ROUTER_CS_26 register status field. This also seems to
align better what the spec suggests.

For this reason do the same what we already do with the Thunderbolt 3
devices and perform the NVM upgrade in two phases. First start the
NVM_AUTH router operation and once the router is added back after the
reset read the status in ROUTER_CS_26 and expose it to the userspace
accordingly.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/switch.c  | 20 ++++++++--
 drivers/thunderbolt/tb.h      |  1 +
 drivers/thunderbolt/tb_regs.h |  1 +
 drivers/thunderbolt/usb4.c    | 75 +++++++++++++++++++++++++++--------
 4 files changed, 77 insertions(+), 20 deletions(-)

diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index cdfd8cccfe19..a8572f49d3ad 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -2160,6 +2160,7 @@ static int tb_switch_add_dma_port(struct tb_switch *sw)
 
 		fallthrough;
 	case 3:
+	case 4:
 		ret = tb_switch_set_uuid(sw);
 		if (ret)
 			return ret;
@@ -2175,6 +2176,22 @@ static int tb_switch_add_dma_port(struct tb_switch *sw)
 		break;
 	}
 
+	if (sw->no_nvm_upgrade)
+		return 0;
+
+	if (tb_switch_is_usb4(sw)) {
+		ret = usb4_switch_nvm_authenticate_status(sw, &status);
+		if (ret)
+			return ret;
+
+		if (status) {
+			tb_sw_info(sw, "switch flash authentication failed\n");
+			nvm_set_auth_status(sw, status);
+		}
+
+		return 0;
+	}
+
 	/* Root switch DMA port requires running firmware */
 	if (!tb_route(sw) && !tb_switch_is_icm(sw))
 		return 0;
@@ -2183,9 +2200,6 @@ static int tb_switch_add_dma_port(struct tb_switch *sw)
 	if (!sw->dma_port)
 		return 0;
 
-	if (sw->no_nvm_upgrade)
-		return 0;
-
 	/*
 	 * If there is status already set then authentication failed
 	 * when the dma_port_flash_update_auth() returned. Power cycling
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index a21000649009..3885f2515aae 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -972,6 +972,7 @@ int usb4_switch_nvm_read(struct tb_switch *sw, unsigned int address, void *buf,
 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);
 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 e7d9529822fa..67cb173a2f8e 100644
--- a/drivers/thunderbolt/tb_regs.h
+++ b/drivers/thunderbolt/tb_regs.h
@@ -211,6 +211,7 @@ struct tb_regs_switch_header {
 #define ROUTER_CS_9				0x09
 #define ROUTER_CS_25				0x19
 #define ROUTER_CS_26				0x1a
+#define ROUTER_CS_26_OPCODE_MASK		GENMASK(15, 0)
 #define ROUTER_CS_26_STATUS_MASK		GENMASK(29, 24)
 #define ROUTER_CS_26_STATUS_SHIFT		24
 #define ROUTER_CS_26_ONS			BIT(30)
diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
index 40f13579a3fe..d88e28eee975 100644
--- a/drivers/thunderbolt/usb4.c
+++ b/drivers/thunderbolt/usb4.c
@@ -192,7 +192,9 @@ static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u8 *status)
 	if (val & ROUTER_CS_26_ONS)
 		return -EOPNOTSUPP;
 
-	*status = (val & ROUTER_CS_26_STATUS_MASK) >> ROUTER_CS_26_STATUS_SHIFT;
+	if (status)
+		*status = (val & ROUTER_CS_26_STATUS_MASK) >>
+			ROUTER_CS_26_STATUS_SHIFT;
 	return 0;
 }
 
@@ -634,32 +636,71 @@ int usb4_switch_nvm_write(struct tb_switch *sw, unsigned int address,
  * @sw: USB4 router
  *
  * After the new NVM has been written via usb4_switch_nvm_write(), this
- * function triggers NVM authentication process. If the authentication
- * is successful the router is power cycled and the new NVM starts
+ * function triggers NVM authentication process. The router gets power
+ * cycled and if the authentication is successful the new NVM starts
  * running. In case of failure returns negative errno.
+ *
+ * The caller should call usb4_switch_nvm_authenticate_status() to read
+ * the status of the authentication after power cycle. It should be the
+ * first router operation to avoid the status being lost.
  */
 int usb4_switch_nvm_authenticate(struct tb_switch *sw)
 {
-	u8 status = 0;
 	int ret;
 
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_AUTH, &status);
+	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_AUTH, NULL);
+	switch (ret) {
+	/*
+	 * The router is power cycled once NVM_AUTH is started so it is
+	 * expected to get any of the following errors back.
+	 */
+	case -EACCES:
+	case -ENOTCONN:
+	case -ETIMEDOUT:
+		return 0;
+
+	default:
+		return ret;
+	}
+}
+
+/**
+ * usb4_switch_nvm_authenticate_status() - Read status of last NVM authenticate
+ * @sw: USB4 router
+ * @status: Status code of the operation
+ *
+ * The function checks if there is status available from the last NVM
+ * authenticate router operation. If there is status then %0 is returned
+ * and the status code is placed in @status. Returns negative errno in case
+ * of failure.
+ *
+ * Must be called before any other router operation.
+ */
+int usb4_switch_nvm_authenticate_status(struct tb_switch *sw, u32 *status)
+{
+	u16 opcode;
+	u32 val;
+	int ret;
+
+	ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_26, 1);
 	if (ret)
 		return ret;
 
-	switch (status) {
-	case 0x0:
-		tb_sw_dbg(sw, "NVM authentication successful\n");
-		return 0;
-	case 0x1:
-		return -EINVAL;
-	case 0x2:
-		return -EAGAIN;
-	case 0x3:
-		return -EOPNOTSUPP;
-	default:
-		return -EIO;
+	/* Check that the opcode is correct */
+	opcode = val & ROUTER_CS_26_OPCODE_MASK;
+	if (opcode == USB4_SWITCH_OP_NVM_AUTH) {
+		if (val & ROUTER_CS_26_OV)
+			return -EBUSY;
+		if (val & ROUTER_CS_26_ONS)
+			return -EOPNOTSUPP;
+
+		*status = (val & ROUTER_CS_26_STATUS_MASK) >>
+			ROUTER_CS_26_STATUS_SHIFT;
+	} else {
+		*status = 0;
 	}
+
+	return 0;
 }
 
 /**
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 07/12] thunderbolt: Pass metadata directly to usb4_switch_op()
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
                   ` (5 preceding siblings ...)
  2020-11-19 15:55 ` [PATCH 06/12] thunderbolt: Perform USB4 router NVM upgrade in two phases Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 08/12] thunderbolt: Pass TX and RX data " Mika Westerberg
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

We are going to make usb4_switch_op() to match better the corresponding
firmware (ICM) USB4 router operation proxy interface, so that we can use
either based on the connection manager implementation. For this reason
pass metadata directly to usb4_switch_op().

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/usb4.c | 77 ++++++++++++++------------------------
 1 file changed, 28 insertions(+), 49 deletions(-)

diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
index d88e28eee975..5f3237d66987 100644
--- a/drivers/thunderbolt/usb4.c
+++ b/drivers/thunderbolt/usb4.c
@@ -92,16 +92,6 @@ static int usb4_switch_op_write_data(struct tb_switch *sw, const void *data,
 	return tb_sw_write(sw, data, TB_CFG_SWITCH, ROUTER_CS_9, dwords);
 }
 
-static int usb4_switch_op_read_metadata(struct tb_switch *sw, u32 *metadata)
-{
-	return tb_sw_read(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1);
-}
-
-static int usb4_switch_op_write_metadata(struct tb_switch *sw, u32 metadata)
-{
-	return tb_sw_write(sw, &metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1);
-}
-
 static int usb4_do_read_data(u16 address, void *buf, size_t size,
 			     read_block_fn read_block, void *read_block_data)
 {
@@ -171,11 +161,18 @@ static int usb4_do_write_data(unsigned int address, const void *buf, size_t size
 	return 0;
 }
 
-static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u8 *status)
+static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata,
+			  u8 *status)
 {
 	u32 val;
 	int ret;
 
+	if (metadata) {
+		ret = tb_sw_write(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1);
+		if (ret)
+			return ret;
+	}
+
 	val = opcode | ROUTER_CS_26_OV;
 	ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_26, 1);
 	if (ret)
@@ -195,7 +192,9 @@ static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u8 *status)
 	if (status)
 		*status = (val & ROUTER_CS_26_STATUS_MASK) >>
 			ROUTER_CS_26_STATUS_SHIFT;
-	return 0;
+
+	return metadata ?
+		tb_sw_read(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1) : 0;
 }
 
 static void usb4_switch_check_wakes(struct tb_switch *sw)
@@ -350,11 +349,7 @@ static int usb4_switch_drom_read_block(void *data,
 	metadata |= (dwaddress << USB4_DROM_ADDRESS_SHIFT) &
 		USB4_DROM_ADDRESS_MASK;
 
-	ret = usb4_switch_op_write_metadata(sw, metadata);
-	if (ret)
-		return ret;
-
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_DROM_READ, &status);
+	ret = usb4_switch_op(sw, USB4_SWITCH_OP_DROM_READ, &metadata, &status);
 	if (ret)
 		return ret;
 
@@ -510,17 +505,14 @@ int usb4_switch_nvm_sector_size(struct tb_switch *sw)
 	u8 status;
 	int ret;
 
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_SECTOR_SIZE, &status);
+	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_SECTOR_SIZE, &metadata,
+			     &status);
 	if (ret)
 		return ret;
 
 	if (status)
 		return status == 0x2 ? -EOPNOTSUPP : -EIO;
 
-	ret = usb4_switch_op_read_metadata(sw, &metadata);
-	if (ret)
-		return ret;
-
 	return metadata & USB4_NVM_SECTOR_SIZE_MASK;
 }
 
@@ -537,11 +529,7 @@ static int usb4_switch_nvm_read_block(void *data,
 	metadata |= (dwaddress << USB4_NVM_READ_OFFSET_SHIFT) &
 		   USB4_NVM_READ_OFFSET_MASK;
 
-	ret = usb4_switch_op_write_metadata(sw, metadata);
-	if (ret)
-		return ret;
-
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_READ, &status);
+	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_READ, &metadata, &status);
 	if (ret)
 		return ret;
 
@@ -579,11 +567,8 @@ static int usb4_switch_nvm_set_offset(struct tb_switch *sw,
 	metadata = (dwaddress << USB4_NVM_SET_OFFSET_SHIFT) &
 		   USB4_NVM_SET_OFFSET_MASK;
 
-	ret = usb4_switch_op_write_metadata(sw, metadata);
-	if (ret)
-		return ret;
-
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_SET_OFFSET, &status);
+	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_SET_OFFSET, &metadata,
+			     &status);
 	if (ret)
 		return ret;
 
@@ -601,7 +586,7 @@ static int usb4_switch_nvm_write_next_block(void *data, const void *buf,
 	if (ret)
 		return ret;
 
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_WRITE, &status);
+	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_WRITE, NULL, &status);
 	if (ret)
 		return ret;
 
@@ -648,7 +633,7 @@ int usb4_switch_nvm_authenticate(struct tb_switch *sw)
 {
 	int ret;
 
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_AUTH, NULL);
+	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_AUTH, NULL, NULL);
 	switch (ret) {
 	/*
 	 * The router is power cycled once NVM_AUTH is started so it is
@@ -714,14 +699,12 @@ int usb4_switch_nvm_authenticate_status(struct tb_switch *sw, u32 *status)
  */
 bool usb4_switch_query_dp_resource(struct tb_switch *sw, struct tb_port *in)
 {
+	u32 metadata = in->port;
 	u8 status;
 	int ret;
 
-	ret = usb4_switch_op_write_metadata(sw, in->port);
-	if (ret)
-		return false;
-
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_QUERY_DP_RESOURCE, &status);
+	ret = usb4_switch_op(sw, USB4_SWITCH_OP_QUERY_DP_RESOURCE, &metadata,
+			     &status);
 	/*
 	 * If DP resource allocation is not supported assume it is
 	 * always available.
@@ -746,14 +729,12 @@ 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)
 {
+	u32 metadata = in->port;
 	u8 status;
 	int ret;
 
-	ret = usb4_switch_op_write_metadata(sw, in->port);
-	if (ret)
-		return ret;
-
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_ALLOC_DP_RESOURCE, &status);
+	ret = usb4_switch_op(sw, USB4_SWITCH_OP_ALLOC_DP_RESOURCE, &metadata,
+			     &status);
 	if (ret == -EOPNOTSUPP)
 		return 0;
 	else if (ret)
@@ -771,14 +752,12 @@ 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)
 {
+	u32 metadata = in->port;
 	u8 status;
 	int ret;
 
-	ret = usb4_switch_op_write_metadata(sw, in->port);
-	if (ret)
-		return ret;
-
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_DEALLOC_DP_RESOURCE, &status);
+	ret = usb4_switch_op(sw, USB4_SWITCH_OP_DEALLOC_DP_RESOURCE, &metadata,
+			     &status);
 	if (ret == -EOPNOTSUPP)
 		return 0;
 	else if (ret)
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 08/12] thunderbolt: Pass TX and RX data directly to usb4_switch_op()
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
                   ` (6 preceding siblings ...)
  2020-11-19 15:55 ` [PATCH 07/12] thunderbolt: Pass metadata directly to usb4_switch_op() Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 09/12] thunderbolt: Add connection manager specific hooks for USB4 router operations Mika Westerberg
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

We are going to make usb4_switch_op() to match better the corresponding
firmware (ICM) USB4 router operation proxy interface, so that we can use
either based on the connection manager implementation.

For this reason rename usb4_switch_op() to __usb4_switch_op() that
provides the most complete interface. Then make usb4_switch_op() and
usb4_switch_op_data() call it with correct set of parameters and update
the callers accordingly.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/usb4.c | 85 +++++++++++++++++++++-----------------
 1 file changed, 48 insertions(+), 37 deletions(-)

diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
index 5f3237d66987..c1bb5ec6e1db 100644
--- a/drivers/thunderbolt/usb4.c
+++ b/drivers/thunderbolt/usb4.c
@@ -74,24 +74,6 @@ static int usb4_switch_wait_for_bit(struct tb_switch *sw, u32 offset, u32 bit,
 	return -ETIMEDOUT;
 }
 
-static int usb4_switch_op_read_data(struct tb_switch *sw, void *data,
-				    size_t dwords)
-{
-	if (dwords > USB4_DATA_DWORDS)
-		return -EINVAL;
-
-	return tb_sw_read(sw, data, TB_CFG_SWITCH, ROUTER_CS_9, dwords);
-}
-
-static int usb4_switch_op_write_data(struct tb_switch *sw, const void *data,
-				     size_t dwords)
-{
-	if (dwords > USB4_DATA_DWORDS)
-		return -EINVAL;
-
-	return tb_sw_write(sw, data, TB_CFG_SWITCH, ROUTER_CS_9, dwords);
-}
-
 static int usb4_do_read_data(u16 address, void *buf, size_t size,
 			     read_block_fn read_block, void *read_block_data)
 {
@@ -161,17 +143,27 @@ static int usb4_do_write_data(unsigned int address, const void *buf, size_t size
 	return 0;
 }
 
-static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata,
-			  u8 *status)
+static int __usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata,
+			    u8 *status, const void *tx_data, size_t tx_dwords,
+			    void *rx_data, size_t rx_dwords)
 {
 	u32 val;
 	int ret;
 
+	if (tx_dwords > USB4_DATA_DWORDS || rx_dwords > USB4_DATA_DWORDS)
+		return -EINVAL;
+
 	if (metadata) {
 		ret = tb_sw_write(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1);
 		if (ret)
 			return ret;
 	}
+	if (tx_dwords) {
+		ret = tb_sw_write(sw, tx_data, TB_CFG_SWITCH, ROUTER_CS_9,
+				  tx_dwords);
+		if (ret)
+			return ret;
+	}
 
 	val = opcode | ROUTER_CS_26_OV;
 	ret = tb_sw_write(sw, &val, TB_CFG_SWITCH, ROUTER_CS_26, 1);
@@ -193,8 +185,34 @@ static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata,
 		*status = (val & ROUTER_CS_26_STATUS_MASK) >>
 			ROUTER_CS_26_STATUS_SHIFT;
 
-	return metadata ?
-		tb_sw_read(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1) : 0;
+	if (metadata) {
+		ret = tb_sw_read(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1);
+		if (ret)
+			return ret;
+	}
+	if (rx_dwords) {
+		ret = tb_sw_read(sw, rx_data, TB_CFG_SWITCH, ROUTER_CS_9,
+				 rx_dwords);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static inline int usb4_switch_op(struct tb_switch *sw, u16 opcode,
+				 u32 *metadata, u8 *status)
+{
+	return __usb4_switch_op(sw, opcode, metadata, status, NULL, 0, NULL, 0);
+}
+
+static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode,
+				      u32 *metadata, u8 *status,
+				      const void *tx_data, size_t tx_dwords,
+				      void *rx_data, size_t rx_dwords)
+{
+	return __usb4_switch_op(sw, opcode, metadata, status, tx_data,
+				tx_dwords, rx_data, rx_dwords);
 }
 
 static void usb4_switch_check_wakes(struct tb_switch *sw)
@@ -349,14 +367,12 @@ static int usb4_switch_drom_read_block(void *data,
 	metadata |= (dwaddress << USB4_DROM_ADDRESS_SHIFT) &
 		USB4_DROM_ADDRESS_MASK;
 
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_DROM_READ, &metadata, &status);
+	ret = usb4_switch_op_data(sw, USB4_SWITCH_OP_DROM_READ, &metadata,
+				  &status, NULL, 0, buf, dwords);
 	if (ret)
 		return ret;
 
-	if (status)
-		return -EIO;
-
-	return usb4_switch_op_read_data(sw, buf, dwords);
+	return status ? -EIO : 0;
 }
 
 /**
@@ -529,14 +545,12 @@ static int usb4_switch_nvm_read_block(void *data,
 	metadata |= (dwaddress << USB4_NVM_READ_OFFSET_SHIFT) &
 		   USB4_NVM_READ_OFFSET_MASK;
 
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_READ, &metadata, &status);
+	ret = usb4_switch_op_data(sw, USB4_SWITCH_OP_NVM_READ, &metadata,
+				  &status, NULL, 0, buf, dwords);
 	if (ret)
 		return ret;
 
-	if (status)
-		return -EIO;
-
-	return usb4_switch_op_read_data(sw, buf, dwords);
+	return status ? -EIO : 0;
 }
 
 /**
@@ -582,11 +596,8 @@ static int usb4_switch_nvm_write_next_block(void *data, const void *buf,
 	u8 status;
 	int ret;
 
-	ret = usb4_switch_op_write_data(sw, buf, dwords);
-	if (ret)
-		return ret;
-
-	ret = usb4_switch_op(sw, USB4_SWITCH_OP_NVM_WRITE, NULL, &status);
+	ret = usb4_switch_op_data(sw, USB4_SWITCH_OP_NVM_WRITE, NULL, &status,
+				  buf, dwords, NULL, 0);
 	if (ret)
 		return ret;
 
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 09/12] thunderbolt: Add connection manager specific hooks for USB4 router operations
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
                   ` (7 preceding siblings ...)
  2020-11-19 15:55 ` [PATCH 08/12] thunderbolt: Pass TX and RX data " Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 10/12] thunderbolt: Move constants for USB4 router operations to tb_regs.h Mika Westerberg
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

Intel USB4 host routers that run the firmware based connection manager
(ICM) may implement a proxy for USB4 router operations. This is to avoid
the firmware to race with the OS driver, as both may need to run these
operations.

This adds two new connection manager specific callbacks which, if
provided, get called instead of the native USB4 router operation.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/tb.h   | 13 ++++++++++
 drivers/thunderbolt/usb4.c | 50 +++++++++++++++++++++++++++++++++-----
 2 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 3885f2515aae..d19dbc8e9457 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -367,6 +367,14 @@ struct tb_path {
  * @disconnect_pcie_paths: Disconnects PCIe paths before NVM update
  * @approve_xdomain_paths: Approve (establish) XDomain DMA paths
  * @disconnect_xdomain_paths: Disconnect XDomain DMA paths
+ * @usb4_switch_op: Optional proxy for USB4 router operations. If set
+ *		    this will be called whenever USB4 router operation is
+ *		    performed. If this returns %-EOPNOTSUPP then the
+ *		    native USB4 router operation is called.
+ * @usb4_switch_nvm_authenticate_status: Optional callback that the CM
+ *					 implementation can be used to
+ *					 return status of USB4 NVM_AUTH
+ *					 router operation.
  */
 struct tb_cm_ops {
 	int (*driver_ready)(struct tb *tb);
@@ -393,6 +401,11 @@ struct tb_cm_ops {
 	int (*disconnect_pcie_paths)(struct tb *tb);
 	int (*approve_xdomain_paths)(struct tb *tb, struct tb_xdomain *xd);
 	int (*disconnect_xdomain_paths)(struct tb *tb, struct tb_xdomain *xd);
+	int (*usb4_switch_op)(struct tb_switch *sw, u16 opcode, u32 *metadata,
+			      u8 *status, const void *tx_data, size_t tx_data_len,
+			      void *rx_data, size_t rx_data_len);
+	int (*usb4_switch_nvm_authenticate_status)(struct tb_switch *sw,
+						   u32 *status);
 };
 
 static inline void *tb_priv(struct tb *tb)
diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
index c1bb5ec6e1db..cbf1c0536360 100644
--- a/drivers/thunderbolt/usb4.c
+++ b/drivers/thunderbolt/usb4.c
@@ -143,16 +143,14 @@ static int usb4_do_write_data(unsigned int address, const void *buf, size_t size
 	return 0;
 }
 
-static int __usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata,
-			    u8 *status, const void *tx_data, size_t tx_dwords,
-			    void *rx_data, size_t rx_dwords)
+static int usb4_native_switch_op(struct tb_switch *sw, u16 opcode,
+				 u32 *metadata, u8 *status,
+				 const void *tx_data, size_t tx_dwords,
+				 void *rx_data, size_t rx_dwords)
 {
 	u32 val;
 	int ret;
 
-	if (tx_dwords > USB4_DATA_DWORDS || rx_dwords > USB4_DATA_DWORDS)
-		return -EINVAL;
-
 	if (metadata) {
 		ret = tb_sw_write(sw, metadata, TB_CFG_SWITCH, ROUTER_CS_25, 1);
 		if (ret)
@@ -200,6 +198,39 @@ static int __usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata,
 	return 0;
 }
 
+static int __usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata,
+			    u8 *status, const void *tx_data, size_t tx_dwords,
+			    void *rx_data, size_t rx_dwords)
+{
+	const struct tb_cm_ops *cm_ops = sw->tb->cm_ops;
+
+	if (tx_dwords > USB4_DATA_DWORDS || rx_dwords > USB4_DATA_DWORDS)
+		return -EINVAL;
+
+	/*
+	 * If the connection manager implementation provides USB4 router
+	 * operation proxy callback, call it here instead of running the
+	 * operation natively.
+	 */
+	if (cm_ops->usb4_switch_op) {
+		int ret;
+
+		ret = cm_ops->usb4_switch_op(sw, opcode, metadata, status,
+					     tx_data, tx_dwords, rx_data,
+					     rx_dwords);
+		if (ret != -EOPNOTSUPP)
+			return ret;
+
+		/*
+		 * If the proxy was not supported then run the native
+		 * router operation instead.
+		 */
+	}
+
+	return usb4_native_switch_op(sw, opcode, metadata, status, tx_data,
+				     tx_dwords, rx_data, rx_dwords);
+}
+
 static inline int usb4_switch_op(struct tb_switch *sw, u16 opcode,
 				 u32 *metadata, u8 *status)
 {
@@ -674,10 +705,17 @@ int usb4_switch_nvm_authenticate(struct tb_switch *sw)
  */
 int usb4_switch_nvm_authenticate_status(struct tb_switch *sw, u32 *status)
 {
+	const struct tb_cm_ops *cm_ops = sw->tb->cm_ops;
 	u16 opcode;
 	u32 val;
 	int ret;
 
+	if (cm_ops->usb4_switch_nvm_authenticate_status) {
+		ret = cm_ops->usb4_switch_nvm_authenticate_status(sw, status);
+		if (ret != -EOPNOTSUPP)
+			return ret;
+	}
+
 	ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_26, 1);
 	if (ret)
 		return ret;
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 10/12] thunderbolt: Move constants for USB4 router operations to tb_regs.h
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
                   ` (8 preceding siblings ...)
  2020-11-19 15:55 ` [PATCH 09/12] thunderbolt: Add connection manager specific hooks for USB4 router operations Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 11/12] thunderbolt: Add USB4 router operation proxy for firmware connection manager Mika Westerberg
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

We are going to use these in subsequent patch so make them available
outside of usb4.c.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/tb_regs.h | 13 +++++++++++++
 drivers/thunderbolt/usb4.c    | 12 ------------
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h
index 67cb173a2f8e..ae427a953489 100644
--- a/drivers/thunderbolt/tb_regs.h
+++ b/drivers/thunderbolt/tb_regs.h
@@ -217,6 +217,19 @@ struct tb_regs_switch_header {
 #define ROUTER_CS_26_ONS			BIT(30)
 #define ROUTER_CS_26_OV				BIT(31)
 
+/* USB4 router operations opcodes */
+enum usb4_switch_op {
+	USB4_SWITCH_OP_QUERY_DP_RESOURCE = 0x10,
+	USB4_SWITCH_OP_ALLOC_DP_RESOURCE = 0x11,
+	USB4_SWITCH_OP_DEALLOC_DP_RESOURCE = 0x12,
+	USB4_SWITCH_OP_NVM_WRITE = 0x20,
+	USB4_SWITCH_OP_NVM_AUTH = 0x21,
+	USB4_SWITCH_OP_NVM_READ = 0x22,
+	USB4_SWITCH_OP_NVM_SET_OFFSET = 0x23,
+	USB4_SWITCH_OP_DROM_READ = 0x24,
+	USB4_SWITCH_OP_NVM_SECTOR_SIZE = 0x25,
+};
+
 /* Router TMU configuration */
 #define TMU_RTR_CS_0				0x00
 #define TMU_RTR_CS_0_TD				BIT(27)
diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
index cbf1c0536360..6a0aa83a1ac8 100644
--- a/drivers/thunderbolt/usb4.c
+++ b/drivers/thunderbolt/usb4.c
@@ -16,18 +16,6 @@
 #define USB4_DATA_DWORDS		16
 #define USB4_DATA_RETRIES		3
 
-enum usb4_switch_op {
-	USB4_SWITCH_OP_QUERY_DP_RESOURCE = 0x10,
-	USB4_SWITCH_OP_ALLOC_DP_RESOURCE = 0x11,
-	USB4_SWITCH_OP_DEALLOC_DP_RESOURCE = 0x12,
-	USB4_SWITCH_OP_NVM_WRITE = 0x20,
-	USB4_SWITCH_OP_NVM_AUTH = 0x21,
-	USB4_SWITCH_OP_NVM_READ = 0x22,
-	USB4_SWITCH_OP_NVM_SET_OFFSET = 0x23,
-	USB4_SWITCH_OP_DROM_READ = 0x24,
-	USB4_SWITCH_OP_NVM_SECTOR_SIZE = 0x25,
-};
-
 enum usb4_sb_target {
 	USB4_SB_TARGET_ROUTER,
 	USB4_SB_TARGET_PARTNER,
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 11/12] thunderbolt: Add USB4 router operation proxy for firmware connection manager
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
                   ` (9 preceding siblings ...)
  2020-11-19 15:55 ` [PATCH 10/12] thunderbolt: Move constants for USB4 router operations to tb_regs.h Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-19 15:55 ` [PATCH 12/12] thunderbolt: Add support for Intel Maple Ridge Mika Westerberg
  2020-11-30 11:44 ` [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

Intel Maple Ridge and Tiger Lake connection manager firmware implements
a USB4 router operation proxy that should be used instead of direct
register access to avoid races with the firmware. This is supported in
all firmwares where the protocol version field returned in the driver
ready response is 3 (or higher).

This adds the USB4 router proxy operations support to the driver so that
we first check the protocol version and if it is 3 (or higher) the USB4
router operation is run through the firmware provided proxy. Otherwise
the native version is used.

Most USB4 router proxy operations are pretty straightforward except
NVM_AUTH where the firmware only responds once the router is restarted
but before it sends device connected notification. To support this we
split the operation so that the reply is received asynchronously and
stored to struct icm. This last reply is then returned in
icm_usb4_switch_nvm_authenticate_status() if available.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/icm.c     | 214 ++++++++++++++++++++++++++++++++--
 drivers/thunderbolt/tb_msgs.h |  28 +++++
 2 files changed, 232 insertions(+), 10 deletions(-)

diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index 635b949fb1d6..35935c106e3d 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -48,6 +48,18 @@ static bool start_icm;
 module_param(start_icm, bool, 0444);
 MODULE_PARM_DESC(start_icm, "start ICM firmware if it is not running (default: false)");
 
+/**
+ * struct usb4_switch_nvm_auth - Holds USB4 NVM_AUTH status
+ * @reply: Reply from ICM firmware is placed here
+ * @request: Request that is sent to ICM firmware
+ * @icm: Pointer to ICM private data
+ */
+struct usb4_switch_nvm_auth {
+	struct icm_usb4_switch_op_response reply;
+	struct icm_usb4_switch_op request;
+	struct icm *icm;
+};
+
 /**
  * struct icm - Internal connection manager private data
  * @request_lock: Makes sure only one message is send to ICM at time
@@ -61,6 +73,8 @@ MODULE_PARM_DESC(start_icm, "start ICM firmware if it is not running (default: f
  * @max_boot_acl: Maximum number of preboot ACL entries (%0 if not supported)
  * @rpm: Does the controller support runtime PM (RTD3)
  * @can_upgrade_nvm: Can the NVM firmware be upgrade on this controller
+ * @proto_version: Firmware protocol version
+ * @last_nvm_auth: Last USB4 router NVM_AUTH result (or %NULL if not set)
  * @veto: Is RTD3 veto in effect
  * @is_supported: Checks if we can support ICM on this controller
  * @cio_reset: Trigger CIO reset
@@ -84,6 +98,8 @@ struct icm {
 	size_t max_boot_acl;
 	bool rpm;
 	bool can_upgrade_nvm;
+	u8 proto_version;
+	struct usb4_switch_nvm_auth *last_nvm_auth;
 	bool veto;
 	bool (*is_supported)(struct tb *tb);
 	int (*cio_reset)(struct tb *tb);
@@ -92,7 +108,7 @@ struct icm {
 	void (*save_devices)(struct tb *tb);
 	int (*driver_ready)(struct tb *tb,
 			    enum tb_security_level *security_level,
-			    size_t *nboot_acl, bool *rpm);
+			    u8 *proto_version, size_t *nboot_acl, bool *rpm);
 	void (*set_uuid)(struct tb *tb);
 	void (*device_connected)(struct tb *tb,
 				 const struct icm_pkg_header *hdr);
@@ -437,7 +453,7 @@ static void icm_fr_save_devices(struct tb *tb)
 
 static int
 icm_fr_driver_ready(struct tb *tb, enum tb_security_level *security_level,
-		    size_t *nboot_acl, bool *rpm)
+		    u8 *proto_version, size_t *nboot_acl, bool *rpm)
 {
 	struct icm_fr_pkg_driver_ready_response reply;
 	struct icm_pkg_driver_ready request = {
@@ -992,7 +1008,7 @@ static int icm_tr_cio_reset(struct tb *tb)
 
 static int
 icm_tr_driver_ready(struct tb *tb, enum tb_security_level *security_level,
-		    size_t *nboot_acl, bool *rpm)
+		    u8 *proto_version, size_t *nboot_acl, bool *rpm)
 {
 	struct icm_tr_pkg_driver_ready_response reply;
 	struct icm_pkg_driver_ready request = {
@@ -1008,6 +1024,9 @@ icm_tr_driver_ready(struct tb *tb, enum tb_security_level *security_level,
 
 	if (security_level)
 		*security_level = reply.info & ICM_TR_INFO_SLEVEL_MASK;
+	if (proto_version)
+		*proto_version = (reply.info & ICM_TR_INFO_PROTO_VERSION_MASK) >>
+				ICM_TR_INFO_PROTO_VERSION_SHIFT;
 	if (nboot_acl)
 		*nboot_acl = (reply.info & ICM_TR_INFO_BOOT_ACL_MASK) >>
 				ICM_TR_INFO_BOOT_ACL_SHIFT;
@@ -1461,7 +1480,7 @@ static int icm_ar_get_mode(struct tb *tb)
 
 static int
 icm_ar_driver_ready(struct tb *tb, enum tb_security_level *security_level,
-		    size_t *nboot_acl, bool *rpm)
+		    u8 *proto_version, size_t *nboot_acl, bool *rpm)
 {
 	struct icm_ar_pkg_driver_ready_response reply;
 	struct icm_pkg_driver_ready request = {
@@ -1591,7 +1610,7 @@ static int icm_ar_set_boot_acl(struct tb *tb, const uuid_t *uuids,
 
 static int
 icm_icl_driver_ready(struct tb *tb, enum tb_security_level *security_level,
-		    size_t *nboot_acl, bool *rpm)
+		     u8 *proto_version, size_t *nboot_acl, bool *rpm)
 {
 	struct icm_tr_pkg_driver_ready_response reply;
 	struct icm_pkg_driver_ready request = {
@@ -1605,6 +1624,10 @@ icm_icl_driver_ready(struct tb *tb, enum tb_security_level *security_level,
 	if (ret)
 		return ret;
 
+	if (proto_version)
+		*proto_version = (reply.info & ICM_TR_INFO_PROTO_VERSION_MASK) >>
+				ICM_TR_INFO_PROTO_VERSION_SHIFT;
+
 	/* Ice Lake always supports RTD3 */
 	if (rpm)
 		*rpm = true;
@@ -1713,13 +1736,14 @@ static void icm_handle_event(struct tb *tb, enum tb_cfg_pkg_type type,
 
 static int
 __icm_driver_ready(struct tb *tb, enum tb_security_level *security_level,
-		   size_t *nboot_acl, bool *rpm)
+		   u8 *proto_version, size_t *nboot_acl, bool *rpm)
 {
 	struct icm *icm = tb_priv(tb);
 	unsigned int retries = 50;
 	int ret;
 
-	ret = icm->driver_ready(tb, security_level, nboot_acl, rpm);
+	ret = icm->driver_ready(tb, security_level, proto_version, nboot_acl,
+				rpm);
 	if (ret) {
 		tb_err(tb, "failed to send driver ready to ICM\n");
 		return ret;
@@ -1929,8 +1953,8 @@ static int icm_driver_ready(struct tb *tb)
 		return 0;
 	}
 
-	ret = __icm_driver_ready(tb, &tb->security_level, &tb->nboot_acl,
-				 &icm->rpm);
+	ret = __icm_driver_ready(tb, &tb->security_level, &icm->proto_version,
+				 &tb->nboot_acl, &icm->rpm);
 	if (ret)
 		return ret;
 
@@ -1941,6 +1965,9 @@ static int icm_driver_ready(struct tb *tb)
 	if (tb->nboot_acl > icm->max_boot_acl)
 		tb->nboot_acl = 0;
 
+	if (icm->proto_version >= 3)
+		tb_dbg(tb, "USB4 proxy operations supported\n");
+
 	return 0;
 }
 
@@ -2052,7 +2079,7 @@ static void icm_complete(struct tb *tb)
 	 * Now all existing children should be resumed, start events
 	 * from ICM to get updated status.
 	 */
-	__icm_driver_ready(tb, NULL, NULL, NULL);
+	__icm_driver_ready(tb, NULL, NULL, NULL, NULL);
 
 	/*
 	 * We do not get notifications of devices that have been
@@ -2131,6 +2158,8 @@ static void icm_stop(struct tb *tb)
 	tb_switch_remove(tb->root_switch);
 	tb->root_switch = NULL;
 	nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_DRV_UNLOADS, 0);
+	kfree(icm->last_nvm_auth);
+	icm->last_nvm_auth = NULL;
 }
 
 static int icm_disconnect_pcie_paths(struct tb *tb)
@@ -2138,6 +2167,165 @@ static int icm_disconnect_pcie_paths(struct tb *tb)
 	return nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_DISCONNECT_PCIE_PATHS, 0);
 }
 
+static void icm_usb4_switch_nvm_auth_complete(void *data)
+{
+	struct usb4_switch_nvm_auth *auth = data;
+	struct icm *icm = auth->icm;
+	struct tb *tb = icm_to_tb(icm);
+
+	tb_dbg(tb, "NVM_AUTH response for %llx flags %#x status %#x\n",
+	       get_route(auth->reply.route_hi, auth->reply.route_lo),
+	       auth->reply.hdr.flags, auth->reply.status);
+
+	mutex_lock(&tb->lock);
+	if (WARN_ON(icm->last_nvm_auth))
+		kfree(icm->last_nvm_auth);
+	icm->last_nvm_auth = auth;
+	mutex_unlock(&tb->lock);
+}
+
+static int icm_usb4_switch_nvm_authenticate(struct tb *tb, u64 route)
+{
+	struct usb4_switch_nvm_auth *auth;
+	struct icm *icm = tb_priv(tb);
+	struct tb_cfg_request *req;
+	int ret;
+
+	auth = kzalloc(sizeof(*auth), GFP_KERNEL);
+	if (!auth)
+		return -ENOMEM;
+
+	auth->icm = icm;
+	auth->request.hdr.code = ICM_USB4_SWITCH_OP;
+	auth->request.route_hi = upper_32_bits(route);
+	auth->request.route_lo = lower_32_bits(route);
+	auth->request.opcode = USB4_SWITCH_OP_NVM_AUTH;
+
+	req = tb_cfg_request_alloc();
+	if (!req) {
+		ret = -ENOMEM;
+		goto err_free_auth;
+	}
+
+	req->match = icm_match;
+	req->copy = icm_copy;
+	req->request = &auth->request;
+	req->request_size = sizeof(auth->request);
+	req->request_type = TB_CFG_PKG_ICM_CMD;
+	req->response = &auth->reply;
+	req->npackets = 1;
+	req->response_size = sizeof(auth->reply);
+	req->response_type = TB_CFG_PKG_ICM_RESP;
+
+	tb_dbg(tb, "NVM_AUTH request for %llx\n", route);
+
+	mutex_lock(&icm->request_lock);
+	ret = tb_cfg_request(tb->ctl, req, icm_usb4_switch_nvm_auth_complete,
+			     auth);
+	mutex_unlock(&icm->request_lock);
+
+	tb_cfg_request_put(req);
+	if (ret)
+		goto err_free_auth;
+	return 0;
+
+err_free_auth:
+	kfree(auth);
+	return ret;
+}
+
+static int icm_usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata,
+			      u8 *status, const void *tx_data, size_t tx_data_len,
+			      void *rx_data, size_t rx_data_len)
+{
+	struct icm_usb4_switch_op_response reply;
+	struct icm_usb4_switch_op request;
+	struct tb *tb = sw->tb;
+	struct icm *icm = tb_priv(tb);
+	u64 route = tb_route(sw);
+	int ret;
+
+	/*
+	 * USB4 router operation proxy is supported in firmware if the
+	 * protocol version is 3 or higher.
+	 */
+	if (icm->proto_version < 3)
+		return -EOPNOTSUPP;
+
+	/*
+	 * NVM_AUTH is a special USB4 proxy operation that does not
+	 * return immediately so handle it separately.
+	 */
+	if (opcode == USB4_SWITCH_OP_NVM_AUTH)
+		return icm_usb4_switch_nvm_authenticate(tb, route);
+
+	memset(&request, 0, sizeof(request));
+	request.hdr.code = ICM_USB4_SWITCH_OP;
+	request.route_hi = upper_32_bits(route);
+	request.route_lo = lower_32_bits(route);
+	request.opcode = opcode;
+	if (metadata)
+		request.metadata = *metadata;
+
+	if (tx_data_len) {
+		request.data_len_valid |= ICM_USB4_SWITCH_DATA_VALID;
+		if (tx_data_len < ARRAY_SIZE(request.data))
+			request.data_len_valid =
+				tx_data_len & ICM_USB4_SWITCH_DATA_LEN_MASK;
+		memcpy(request.data, tx_data, tx_data_len * sizeof(u32));
+	}
+
+	memset(&reply, 0, sizeof(reply));
+	ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
+			  1, ICM_TIMEOUT);
+	if (ret)
+		return ret;
+
+	if (reply.hdr.flags & ICM_FLAGS_ERROR)
+		return -EIO;
+
+	if (status)
+		*status = reply.status;
+
+	if (metadata)
+		*metadata = reply.metadata;
+
+	if (rx_data_len)
+		memcpy(rx_data, reply.data, rx_data_len * sizeof(u32));
+
+	return 0;
+}
+
+static int icm_usb4_switch_nvm_authenticate_status(struct tb_switch *sw,
+						   u32 *status)
+{
+	struct usb4_switch_nvm_auth *auth;
+	struct tb *tb = sw->tb;
+	struct icm *icm = tb_priv(tb);
+	int ret = 0;
+
+	if (icm->proto_version < 3)
+		return -EOPNOTSUPP;
+
+	auth = icm->last_nvm_auth;
+	icm->last_nvm_auth = NULL;
+
+	if (auth && auth->reply.route_hi == sw->config.route_hi &&
+	    auth->reply.route_lo == sw->config.route_lo) {
+		tb_dbg(tb, "NVM_AUTH found for %llx flags 0x%#x status %#x\n",
+		       tb_route(sw), auth->reply.hdr.flags, auth->reply.status);
+		if (auth->reply.hdr.flags & ICM_FLAGS_ERROR)
+			ret = -EIO;
+		else
+			*status = auth->reply.status;
+	} else {
+		*status = 0;
+	}
+
+	kfree(auth);
+	return ret;
+}
+
 /* Falcon Ridge */
 static const struct tb_cm_ops icm_fr_ops = {
 	.driver_ready = icm_driver_ready,
@@ -2196,6 +2384,9 @@ static const struct tb_cm_ops icm_tr_ops = {
 	.disconnect_pcie_paths = icm_disconnect_pcie_paths,
 	.approve_xdomain_paths = icm_tr_approve_xdomain_paths,
 	.disconnect_xdomain_paths = icm_tr_disconnect_xdomain_paths,
+	.usb4_switch_op = icm_usb4_switch_op,
+	.usb4_switch_nvm_authenticate_status =
+		icm_usb4_switch_nvm_authenticate_status,
 };
 
 /* Ice Lake */
@@ -2209,6 +2400,9 @@ static const struct tb_cm_ops icm_icl_ops = {
 	.handle_event = icm_handle_event,
 	.approve_xdomain_paths = icm_tr_approve_xdomain_paths,
 	.disconnect_xdomain_paths = icm_tr_disconnect_xdomain_paths,
+	.usb4_switch_op = icm_usb4_switch_op,
+	.usb4_switch_nvm_authenticate_status =
+		icm_usb4_switch_nvm_authenticate_status,
 };
 
 struct tb *icm_probe(struct tb_nhi *nhi)
diff --git a/drivers/thunderbolt/tb_msgs.h b/drivers/thunderbolt/tb_msgs.h
index 0e01dbc63e72..bcabfcb2fd03 100644
--- a/drivers/thunderbolt/tb_msgs.h
+++ b/drivers/thunderbolt/tb_msgs.h
@@ -106,6 +106,7 @@ enum icm_pkg_code {
 	ICM_APPROVE_XDOMAIN = 0x10,
 	ICM_DISCONNECT_XDOMAIN = 0x11,
 	ICM_PREBOOT_ACL = 0x18,
+	ICM_USB4_SWITCH_OP = 0x20,
 };
 
 enum icm_event_code {
@@ -343,6 +344,8 @@ struct icm_tr_pkg_driver_ready_response {
 #define ICM_TR_FLAGS_RTD3		BIT(6)
 
 #define ICM_TR_INFO_SLEVEL_MASK		GENMASK(2, 0)
+#define ICM_TR_INFO_PROTO_VERSION_MASK	GENMASK(6, 4)
+#define ICM_TR_INFO_PROTO_VERSION_SHIFT	4
 #define ICM_TR_INFO_BOOT_ACL_SHIFT	7
 #define ICM_TR_INFO_BOOT_ACL_MASK	GENMASK(12, 7)
 
@@ -478,6 +481,31 @@ struct icm_icl_event_rtd3_veto {
 	u32 veto_reason;
 };
 
+/* USB4 ICM messages */
+
+struct icm_usb4_switch_op {
+	struct icm_pkg_header hdr;
+	u32 route_hi;
+	u32 route_lo;
+	u32 metadata;
+	u16 opcode;
+	u16 data_len_valid;
+	u32 data[16];
+};
+
+#define ICM_USB4_SWITCH_DATA_LEN_MASK	GENMASK(3, 0)
+#define ICM_USB4_SWITCH_DATA_VALID	BIT(4)
+
+struct icm_usb4_switch_op_response {
+	struct icm_pkg_header hdr;
+	u32 route_hi;
+	u32 route_lo;
+	u32 metadata;
+	u16 opcode;
+	u16 status;
+	u32 data[16];
+};
+
 /* XDomain messages */
 
 struct tb_xdomain_header {
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 12/12] thunderbolt: Add support for Intel Maple Ridge
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
                   ` (10 preceding siblings ...)
  2020-11-19 15:55 ` [PATCH 11/12] thunderbolt: Add USB4 router operation proxy for firmware connection manager Mika Westerberg
@ 2020-11-19 15:55 ` Mika Westerberg
  2020-11-30 11:44 ` [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-19 15:55 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman, Mika Westerberg

Maple Ridge is first discrete USB4 host controller from Intel. It comes
with firmware based connection manager and the flows are similar as used
in Intel Titan Ridge.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/thunderbolt/icm.c | 11 +++++++++++
 drivers/thunderbolt/nhi.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index 35935c106e3d..adc7b61937a1 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -2499,6 +2499,17 @@ struct tb *icm_probe(struct tb_nhi *nhi)
 		icm->rtd3_veto = icm_icl_rtd3_veto;
 		tb->cm_ops = &icm_icl_ops;
 		break;
+
+	case PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_4C_NHI:
+		icm->is_supported = icm_tgl_is_supported;
+		icm->get_mode = icm_ar_get_mode;
+		icm->driver_ready = icm_tr_driver_ready;
+		icm->device_connected = icm_tr_device_connected;
+		icm->device_disconnected = icm_tr_device_disconnected;
+		icm->xdomain_connected = icm_tr_xdomain_connected;
+		icm->xdomain_disconnected = icm_tr_xdomain_disconnected;
+		tb->cm_ops = &icm_tr_ops;
+		break;
 	}
 
 	if (!icm->is_supported || !icm->is_supported(tb)) {
diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
index 80162e4b013f..ffe0531c0fd0 100644
--- a/drivers/thunderbolt/nhi.h
+++ b/drivers/thunderbolt/nhi.h
@@ -55,6 +55,7 @@ extern const struct tb_nhi_ops icl_nhi_ops;
  * need for the PCI quirk anymore as we will use ICM also on Apple
  * hardware.
  */
+#define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_4C_NHI		0x1137
 #define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_NHI            0x157d
 #define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_BRIDGE         0x157e
 #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_NHI		0x15bf
-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support
  2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
                   ` (11 preceding siblings ...)
  2020-11-19 15:55 ` [PATCH 12/12] thunderbolt: Add support for Intel Maple Ridge Mika Westerberg
@ 2020-11-30 11:44 ` Mika Westerberg
  12 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2020-11-30 11:44 UTC (permalink / raw)
  To: linux-kernel
  Cc: Yehezkel Bernat, Michael Jamet, Andreas Noever, Lukas Wunner,
	Greg Kroah-Hartman

On Thu, Nov 19, 2020 at 06:55:11PM +0300, Mika Westerberg wrote:
> Hi all,
> 
> This series improves the USB4 router NVM upgrade functionality and adds
> support for USB4 router operations proxy implemented by recent Intel
> Thunderbolt firmware connection manager. The last patch adds support for
> Intel Maple Ridge that is the first discrete Thunderbolt/USB4 controller
> from Intel.
> 
> This also includes a couple of minor cleanups and improvements around
> debug logging.
> 
> Mika Westerberg (12):
>   thunderbolt: Move max_boot_acl field to correct place in struct icm
>   thunderbolt: Log which connection manager implementation is used
>   thunderbolt: Log adapter numbers in decimal in path activation/deactivation
>   thunderbolt: Keep the parent runtime resumed for a while on device disconnect
>   thunderbolt: Return -ENOTCONN when ERR_CONN is received
>   thunderbolt: Perform USB4 router NVM upgrade in two phases
>   thunderbolt: Pass metadata directly to usb4_switch_op()
>   thunderbolt: Pass TX and RX data directly to usb4_switch_op()
>   thunderbolt: Add connection manager specific hooks for USB4 router operations
>   thunderbolt: Move constants for USB4 router operations to tb_regs.h
>   thunderbolt: Add USB4 router operation proxy for firmware connection manager
>   thunderbolt: Add support for Intel Maple Ridge

All applied to thunderbolt.git/next.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, back to index

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-19 15:55 [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg
2020-11-19 15:55 ` [PATCH 01/12] thunderbolt: Move max_boot_acl field to correct place in struct icm Mika Westerberg
2020-11-19 15:55 ` [PATCH 02/12] thunderbolt: Log which connection manager implementation is used Mika Westerberg
2020-11-19 15:55 ` [PATCH 03/12] thunderbolt: Log adapter numbers in decimal in path activation/deactivation Mika Westerberg
2020-11-19 15:55 ` [PATCH 04/12] thunderbolt: Keep the parent runtime resumed for a while on device disconnect Mika Westerberg
2020-11-19 15:55 ` [PATCH 05/12] thunderbolt: Return -ENOTCONN when ERR_CONN is received Mika Westerberg
2020-11-19 15:55 ` [PATCH 06/12] thunderbolt: Perform USB4 router NVM upgrade in two phases Mika Westerberg
2020-11-19 15:55 ` [PATCH 07/12] thunderbolt: Pass metadata directly to usb4_switch_op() Mika Westerberg
2020-11-19 15:55 ` [PATCH 08/12] thunderbolt: Pass TX and RX data " Mika Westerberg
2020-11-19 15:55 ` [PATCH 09/12] thunderbolt: Add connection manager specific hooks for USB4 router operations Mika Westerberg
2020-11-19 15:55 ` [PATCH 10/12] thunderbolt: Move constants for USB4 router operations to tb_regs.h Mika Westerberg
2020-11-19 15:55 ` [PATCH 11/12] thunderbolt: Add USB4 router operation proxy for firmware connection manager Mika Westerberg
2020-11-19 15:55 ` [PATCH 12/12] thunderbolt: Add support for Intel Maple Ridge Mika Westerberg
2020-11-30 11:44 ` [PATCH 00/12] thunderbolt: USB4 NVM upgrade improvements & Maple Ridge support Mika Westerberg

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git
	git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git