lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <1519659254.10722.189.camel@linux.intel.com>
Date:   Mon, 26 Feb 2018 17:34:14 +0200
From:   Andy Shevchenko <andriy.shevchenko@...ux.intel.com>
To:     Mika Westerberg <mika.westerberg@...ux.intel.com>,
        linux-kernel@...r.kernel.org
Cc:     Andreas Noever <andreas.noever@...il.com>,
        Michael Jamet <michael.jamet@...el.com>,
        Yehezkel Bernat <yehezkel.bernat@...el.com>,
        Bjorn Helgaas <bhelgaas@...gle.com>,
        Mario.Limonciello@...l.com,
        Radion Mirchevsky <radion.mirchevsky@...el.com>,
        Randy Dunlap <rdunlap@...radead.org>,
        Jeremy McNicoll <jmcnicol@...hat.com>,
        Andrei Emeltchenko <andrei.emeltchenko@...el.com>
Subject: Re: [PATCH v2 18/18] thunderbolt: Add support for Intel Titan Ridge

On Mon, 2018-02-26 at 17:10 +0300, Mika Westerberg wrote:
> From: Radion Mirchevsky <radion.mirchevsky@...el.com>
> 
> Intel Titan Ridge is the next Thunderbolt 3 controller. The ICM
> firmware
> message format in Titan Ridge differs from Falcon Ridge and Alpine
> Ridge
> somewhat because it is using route strings addressing devices. In
> addition to that the DMA port of 4-channel (two port) controller is in
> different port number than the previous controllers. There are some
> other minor differences as well.
> 
> This patch add support for Intel Titan Ridge and the new ICM firmware
> message format.
> 

All right then, looks good!

Reviewed-by: Andy Shevchenko <andriy.shevchenko@...ux.intel.com>

> Signed-off-by: Radion Mirchevsky <radion.mirchevsky@...el.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@...ux.intel.com>
> ---
>  drivers/thunderbolt/dma_port.c |  28 ++-
>  drivers/thunderbolt/icm.c      | 382
> +++++++++++++++++++++++++++++++++++++++++
>  drivers/thunderbolt/nhi.c      |   2 +
>  drivers/thunderbolt/nhi.h      |   5 +
>  drivers/thunderbolt/switch.c   |   3 +
>  drivers/thunderbolt/tb_msgs.h  | 141 +++++++++++++++
>  6 files changed, 546 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/thunderbolt/dma_port.c
> b/drivers/thunderbolt/dma_port.c
> index af6dde347bee..f2701194f810 100644
> --- a/drivers/thunderbolt/dma_port.c
> +++ b/drivers/thunderbolt/dma_port.c
> @@ -170,24 +170,22 @@ static int dma_port_write(struct tb_ctl *ctl,
> const void *buffer, u64 route,
>  
>  static int dma_find_port(struct tb_switch *sw)
>  {
> -	int port, ret;
> -	u32 type;
> +	static const int ports[] = { 3, 5, 7 };
> +	int i;
>  
>  	/*
> -	 * The DMA (NHI) port is either 3 or 5 depending on the
> -	 * controller. Try both starting from 5 which is more common.
> +	 * The DMA (NHI) port is either 3, 5 or 7 depending on the
> +	 * controller. Try all of them.
>  	 */
> -	port = 5;
> -	ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw), port,
> 2, 1,
> -			    DMA_PORT_TIMEOUT);
> -	if (!ret && (type & 0xffffff) == TB_TYPE_NHI)
> -		return port;
> -
> -	port = 3;
> -	ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw), port,
> 2, 1,
> -			    DMA_PORT_TIMEOUT);
> -	if (!ret && (type & 0xffffff) == TB_TYPE_NHI)
> -		return port;
> +	for (i = 0; i < ARRAY_SIZE(ports); i++) {
> +		u32 type;
> +		int ret;
> +
> +		ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw),
> ports[i],
> +				    2, 1, DMA_PORT_TIMEOUT);
> +		if (!ret && (type & 0xffffff) == TB_TYPE_NHI)
> +			return ports[i];
> +	}
>  
>  	return -ENODEV;
>  }
> diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
> index 1f2c17bc7571..10cef4e0f032 100644
> --- a/drivers/thunderbolt/icm.c
> +++ b/drivers/thunderbolt/icm.c
> @@ -118,6 +118,12 @@ static inline u64 get_route(u32 route_hi, u32
> route_lo)
>  	return (u64)route_hi << 32 | route_lo;
>  }
>  
> +static inline u64 get_parent_route(u64 route)
> +{
> +	int depth = tb_route_length(route);
> +	return depth ? route & ~(0xffULL << (depth - 1) *
> TB_ROUTE_SHIFT) : 0;
> +}
> +
>  static bool icm_match(const struct tb_cfg_request *req,
>  		      const struct ctl_pkg *pkg)
>  {
> @@ -749,6 +755,351 @@ icm_fr_xdomain_disconnected(struct tb *tb, const
> struct icm_pkg_header *hdr)
>  	}
>  }
>  
> +static int
> +icm_tr_driver_ready(struct tb *tb, enum tb_security_level
> *security_level,
> +		    size_t *nboot_acl)
> +{
> +	struct icm_tr_pkg_driver_ready_response reply;
> +	struct icm_pkg_driver_ready request = {
> +		.hdr.code = ICM_DRIVER_READY,
> +	};
> +	int ret;
> +
> +	memset(&reply, 0, sizeof(reply));
> +	ret = icm_request(tb, &request, sizeof(request), &reply,
> sizeof(reply),
> +			  1, 20000);
> +	if (ret)
> +		return ret;
> +
> +	if (security_level)
> +		*security_level = reply.info &
> ICM_TR_INFO_SLEVEL_MASK;
> +	if (nboot_acl)
> +		*nboot_acl = (reply.info & ICM_TR_INFO_BOOT_ACL_MASK)
> >>
> +				ICM_TR_INFO_BOOT_ACL_SHIFT;
> +	return 0;
> +}
> +
> +static int icm_tr_approve_switch(struct tb *tb, struct tb_switch *sw)
> +{
> +	struct icm_tr_pkg_approve_device request;
> +	struct icm_tr_pkg_approve_device reply;
> +	int ret;
> +
> +	memset(&request, 0, sizeof(request));
> +	memcpy(&request.ep_uuid, sw->uuid, sizeof(request.ep_uuid));
> +	request.hdr.code = ICM_APPROVE_DEVICE;
> +	request.route_lo = sw->config.route_lo;
> +	request.route_hi = sw->config.route_hi;
> +	request.connection_id = sw->connection_id;
> +
> +	memset(&reply, 0, sizeof(reply));
> +	ret = icm_request(tb, &request, sizeof(request), &reply,
> sizeof(reply),
> +			  1, ICM_APPROVE_TIMEOUT);
> +	if (ret)
> +		return ret;
> +
> +	if (reply.hdr.flags & ICM_FLAGS_ERROR) {
> +		tb_warn(tb, "PCIe tunnel creation failed\n");
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static int icm_tr_add_switch_key(struct tb *tb, struct tb_switch *sw)
> +{
> +	struct icm_tr_pkg_add_device_key_response reply;
> +	struct icm_tr_pkg_add_device_key request;
> +	int ret;
> +
> +	memset(&request, 0, sizeof(request));
> +	memcpy(&request.ep_uuid, sw->uuid, sizeof(request.ep_uuid));
> +	request.hdr.code = ICM_ADD_DEVICE_KEY;
> +	request.route_lo = sw->config.route_lo;
> +	request.route_hi = sw->config.route_hi;
> +	request.connection_id = sw->connection_id;
> +	memcpy(request.key, sw->key, TB_SWITCH_KEY_SIZE);
> +
> +	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) {
> +		tb_warn(tb, "Adding key to switch failed\n");
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static int icm_tr_challenge_switch_key(struct tb *tb, struct
> tb_switch *sw,
> +				       const u8 *challenge, u8
> *response)
> +{
> +	struct icm_tr_pkg_challenge_device_response reply;
> +	struct icm_tr_pkg_challenge_device request;
> +	int ret;
> +
> +	memset(&request, 0, sizeof(request));
> +	memcpy(&request.ep_uuid, sw->uuid, sizeof(request.ep_uuid));
> +	request.hdr.code = ICM_CHALLENGE_DEVICE;
> +	request.route_lo = sw->config.route_lo;
> +	request.route_hi = sw->config.route_hi;
> +	request.connection_id = sw->connection_id;
> +	memcpy(request.challenge, challenge, TB_SWITCH_KEY_SIZE);
> +
> +	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 -EKEYREJECTED;
> +	if (reply.hdr.flags & ICM_FLAGS_NO_KEY)
> +		return -ENOKEY;
> +
> +	memcpy(response, reply.response, TB_SWITCH_KEY_SIZE);
> +
> +	return 0;
> +}
> +
> +static int icm_tr_approve_xdomain_paths(struct tb *tb, struct
> tb_xdomain *xd)
> +{
> +	struct icm_tr_pkg_approve_xdomain_response reply;
> +	struct icm_tr_pkg_approve_xdomain request;
> +	int ret;
> +
> +	memset(&request, 0, sizeof(request));
> +	request.hdr.code = ICM_APPROVE_XDOMAIN;
> +	request.route_hi = upper_32_bits(xd->route);
> +	request.route_lo = lower_32_bits(xd->route);
> +	request.transmit_path = xd->transmit_path;
> +	request.transmit_ring = xd->transmit_ring;
> +	request.receive_path = xd->receive_path;
> +	request.receive_ring = xd->receive_ring;
> +	memcpy(&request.remote_uuid, xd->remote_uuid, sizeof(*xd-
> >remote_uuid));
> +
> +	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;
> +
> +	return 0;
> +}
> +
> +static int icm_tr_xdomain_tear_down(struct tb *tb, struct tb_xdomain
> *xd,
> +				    int stage)
> +{
> +	struct icm_tr_pkg_disconnect_xdomain_response reply;
> +	struct icm_tr_pkg_disconnect_xdomain request;
> +	int ret;
> +
> +	memset(&request, 0, sizeof(request));
> +	request.hdr.code = ICM_DISCONNECT_XDOMAIN;
> +	request.stage = stage;
> +	request.route_hi = upper_32_bits(xd->route);
> +	request.route_lo = lower_32_bits(xd->route);
> +	memcpy(&request.remote_uuid, xd->remote_uuid, sizeof(*xd-
> >remote_uuid));
> +
> +	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;
> +
> +	return 0;
> +}
> +
> +static int icm_tr_disconnect_xdomain_paths(struct tb *tb, struct
> tb_xdomain *xd)
> +{
> +	int ret;
> +
> +	ret = icm_tr_xdomain_tear_down(tb, xd, 1);
> +	if (ret)
> +		return ret;
> +
> +	usleep_range(10, 50);
> +	return icm_tr_xdomain_tear_down(tb, xd, 2);
> +}
> +
> +static void
> +icm_tr_device_connected(struct tb *tb, const struct icm_pkg_header
> *hdr)
> +{
> +	const struct icm_tr_event_device_connected *pkg =
> +		(const struct icm_tr_event_device_connected *)hdr;
> +	enum tb_security_level security_level;
> +	struct tb_switch *sw, *parent_sw;
> +	struct tb_xdomain *xd;
> +	bool authorized, boot;
> +	u64 route;
> +
> +	/*
> +	 * Currently we don't use the QoS information coming with the
> +	 * device connected message so simply just ignore that extra
> +	 * packet for now.
> +	 */
> +	if (pkg->hdr.packet_id)
> +		return;
> +
> +	/*
> +	 * After NVM upgrade adding root switch device fails because
> we
> +	 * initiated reset. During that time ICM might still send
> device
> +	 * connected message which we ignore here.
> +	 */
> +	if (!tb->root_switch)
> +		return;
> +
> +	route = get_route(pkg->route_hi, pkg->route_lo);
> +	authorized = pkg->link_info & ICM_LINK_INFO_APPROVED;
> +	security_level = (pkg->hdr.flags & ICM_FLAGS_SLEVEL_MASK) >>
> +			 ICM_FLAGS_SLEVEL_SHIFT;
> +	boot = pkg->link_info & ICM_LINK_INFO_BOOT;
> +
> +	if (pkg->link_info & ICM_LINK_INFO_REJECTED) {
> +		tb_info(tb, "switch at %llx was rejected by ICM
> firmware\n",
> +			route);
> +		return;
> +	}
> +
> +	sw = tb_switch_find_by_uuid(tb, &pkg->ep_uuid);
> +	if (sw) {
> +		/* Update the switch if it is still in the same place
> */
> +		if (tb_route(sw) == route && !!sw->authorized ==
> authorized) {
> +			parent_sw = tb_to_switch(sw->dev.parent);
> +			update_switch(parent_sw, sw, route, pkg-
> >connection_id,
> +				      0, 0, 0, boot);
> +			tb_switch_put(sw);
> +			return;
> +		}
> +
> +		remove_switch(sw);
> +		tb_switch_put(sw);
> +	}
> +
> +	/* Another switch with the same address */
> +	sw = tb_switch_find_by_route(tb, route);
> +	if (sw) {
> +		remove_switch(sw);
> +		tb_switch_put(sw);
> +	}
> +
> +	/* XDomain connection with the same address */
> +	xd = tb_xdomain_find_by_route(tb, route);
> +	if (xd) {
> +		remove_xdomain(xd);
> +		tb_xdomain_put(xd);
> +	}
> +
> +	parent_sw = tb_switch_find_by_route(tb,
> get_parent_route(route));
> +	if (!parent_sw) {
> +		tb_err(tb, "failed to find parent switch for %llx\n",
> route);
> +		return;
> +	}
> +
> +	add_switch(parent_sw, route, &pkg->ep_uuid, pkg-
> >connection_id,
> +		   0, 0, 0, security_level, authorized, boot);
> +
> +	tb_switch_put(parent_sw);
> +}
> +
> +static void
> +icm_tr_device_disconnected(struct tb *tb, const struct icm_pkg_header
> *hdr)
> +{
> +	const struct icm_tr_event_device_disconnected *pkg =
> +		(const struct icm_tr_event_device_disconnected *)hdr;
> +	struct tb_switch *sw;
> +	u64 route;
> +
> +	route = get_route(pkg->route_hi, pkg->route_lo);
> +
> +	sw = tb_switch_find_by_route(tb, route);
> +	if (!sw) {
> +		tb_warn(tb, "no switch exists at %llx, ignoring\n",
> route);
> +		return;
> +	}
> +
> +	remove_switch(sw);
> +	tb_switch_put(sw);
> +}
> +
> +static void
> +icm_tr_xdomain_connected(struct tb *tb, const struct icm_pkg_header
> *hdr)
> +{
> +	const struct icm_tr_event_xdomain_connected *pkg =
> +		(const struct icm_tr_event_xdomain_connected *)hdr;
> +	struct tb_xdomain *xd;
> +	struct tb_switch *sw;
> +	u64 route;
> +
> +	if (!tb->root_switch)
> +		return;
> +
> +	route = get_route(pkg->local_route_hi, pkg->local_route_lo);
> +
> +	xd = tb_xdomain_find_by_uuid(tb, &pkg->remote_uuid);
> +	if (xd) {
> +		if (xd->route == route) {
> +			update_xdomain(xd, route, 0);
> +			tb_xdomain_put(xd);
> +			return;
> +		}
> +
> +		remove_xdomain(xd);
> +		tb_xdomain_put(xd);
> +	}
> +
> +	/* An existing xdomain with the same address */
> +	xd = tb_xdomain_find_by_route(tb, route);
> +	if (xd) {
> +		remove_xdomain(xd);
> +		tb_xdomain_put(xd);
> +	}
> +
> +	/*
> +	 * If the user disconnected a switch during suspend and
> +	 * connected another host to the same port, remove the switch
> +	 * first.
> +	 */
> +	sw = get_switch_at_route(tb->root_switch, route);
> +	if (sw)
> +		remove_switch(sw);
> +
> +	sw = tb_switch_find_by_route(tb, get_parent_route(route));
> +	if (!sw) {
> +		tb_warn(tb, "no switch exists at %llx, ignoring\n",
> route);
> +		return;
> +	}
> +
> +	add_xdomain(sw, route, &pkg->local_uuid, &pkg->remote_uuid,
> 0, 0);
> +	tb_switch_put(sw);
> +}
> +
> +static void
> +icm_tr_xdomain_disconnected(struct tb *tb, const struct
> icm_pkg_header *hdr)
> +{
> +	const struct icm_tr_event_xdomain_disconnected *pkg =
> +		(const struct icm_tr_event_xdomain_disconnected
> *)hdr;
> +	struct tb_xdomain *xd;
> +	u64 route;
> +
> +	route = get_route(pkg->route_hi, pkg->route_lo);
> +
> +	xd = tb_xdomain_find_by_route(tb, route);
> +	if (xd) {
> +		remove_xdomain(xd);
> +		tb_xdomain_put(xd);
> +	}
> +}
> +
>  static struct pci_dev *get_upstream_port(struct pci_dev *pdev)
>  {
>  	struct pci_dev *parent;
> @@ -1471,6 +1822,24 @@ static const struct tb_cm_ops icm_ar_ops = {
>  	.disconnect_xdomain_paths = icm_fr_disconnect_xdomain_paths,
>  };
>  
> +/* Titan Ridge */
> +static const struct tb_cm_ops icm_tr_ops = {
> +	.driver_ready = icm_driver_ready,
> +	.start = icm_start,
> +	.stop = icm_stop,
> +	.suspend = icm_suspend,
> +	.complete = icm_complete,
> +	.handle_event = icm_handle_event,
> +	.get_boot_acl = icm_ar_get_boot_acl,
> +	.set_boot_acl = icm_ar_set_boot_acl,
> +	.approve_switch = icm_tr_approve_switch,
> +	.add_switch_key = icm_tr_add_switch_key,
> +	.challenge_switch_key = icm_tr_challenge_switch_key,
> +	.disconnect_pcie_paths = icm_disconnect_pcie_paths,
> +	.approve_xdomain_paths = icm_tr_approve_xdomain_paths,
> +	.disconnect_xdomain_paths = icm_tr_disconnect_xdomain_paths,
> +};
> +
>  struct tb *icm_probe(struct tb_nhi *nhi)
>  {
>  	struct icm *icm;
> @@ -1513,6 +1882,19 @@ struct tb *icm_probe(struct tb_nhi *nhi)
>  		icm->xdomain_disconnected =
> icm_fr_xdomain_disconnected;
>  		tb->cm_ops = &icm_ar_ops;
>  		break;
> +
> +	case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_NHI:
> +	case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_NHI:
> +		icm->max_boot_acl = ICM_AR_PREBOOT_ACL_ENTRIES;
> +		icm->is_supported = icm_ar_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.c b/drivers/thunderbolt/nhi.c
> index 9e58d09f6029..f5a33e88e676 100644
> --- a/drivers/thunderbolt/nhi.c
> +++ b/drivers/thunderbolt/nhi.c
> @@ -1111,6 +1111,8 @@ static struct pci_device_id nhi_ids[] = {
>  	{ PCI_VDEVICE(INTEL,
> PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_NHI) },
>  	{ PCI_VDEVICE(INTEL,
> PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_NHI) },
>  	{ PCI_VDEVICE(INTEL,
> PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_USBONLY_NHI) },
> +	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_NHI)
> },
> +	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_NHI)
> },
>  
>  	{ 0,}
>  };
> diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
> index 4476ab4cfd0c..1696a4560948 100644
> --- a/drivers/thunderbolt/nhi.h
> +++ b/drivers/thunderbolt/nhi.h
> @@ -45,5 +45,10 @@ enum nhi_fw_mode nhi_mailbox_mode(struct tb_nhi
> *nhi);
>  #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_USBONLY_NHI	0x15dc
>  #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_USBONLY_NHI	0x15dd
>  #define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_USBONLY_NHI	0x15de
> +#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_BRIDGE	0x15e7
> +#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_NHI		0x15e8
> +#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_BRIDGE	0x15ea
> +#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_NHI		0x15eb
> +#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE	0x15ef
>  
>  #endif
> diff --git a/drivers/thunderbolt/switch.c
> b/drivers/thunderbolt/switch.c
> index e9e30aaab2a3..25758671ddf4 100644
> --- a/drivers/thunderbolt/switch.c
> +++ b/drivers/thunderbolt/switch.c
> @@ -1051,6 +1051,9 @@ static int tb_switch_get_generation(struct
> tb_switch *sw)
>  	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE:
>  	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE:
>  	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE:
> +	case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_BRIDGE:
> +	case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_BRIDGE:
> +	case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE:
>  		return 3;
>  
>  	default:
> diff --git a/drivers/thunderbolt/tb_msgs.h
> b/drivers/thunderbolt/tb_msgs.h
> index e0edb9541e5d..028fe6c4accf 100644
> --- a/drivers/thunderbolt/tb_msgs.h
> +++ b/drivers/thunderbolt/tb_msgs.h
> @@ -102,6 +102,7 @@ enum icm_pkg_code {
>  	ICM_ADD_DEVICE_KEY = 0x6,
>  	ICM_GET_ROUTE = 0xa,
>  	ICM_APPROVE_XDOMAIN = 0x10,
> +	ICM_DISCONNECT_XDOMAIN = 0x11,
>  	ICM_PREBOOT_ACL = 0x18,
>  };
>  
> @@ -321,6 +322,146 @@ struct icm_ar_pkg_preboot_acl_response {
>  	struct icm_ar_boot_acl_entry acl[ICM_AR_PREBOOT_ACL_ENTRIES];
>  };
>  
> +/* Titan Ridge messages */
> +
> +struct icm_tr_pkg_driver_ready_response {
> +	struct icm_pkg_header hdr;
> +	u16 reserved1;
> +	u16 info;
> +	u32 nvm_version;
> +	u16 device_id;
> +	u16 reserved2;
> +};
> +
> +#define ICM_TR_INFO_SLEVEL_MASK		GENMASK(2, 0)
> +#define ICM_TR_INFO_BOOT_ACL_SHIFT	7
> +#define ICM_TR_INFO_BOOT_ACL_MASK	GENMASK(12, 7)
> +
> +struct icm_tr_event_device_connected {
> +	struct icm_pkg_header hdr;
> +	uuid_t ep_uuid;
> +	u32 route_hi;
> +	u32 route_lo;
> +	u8 connection_id;
> +	u8 reserved;
> +	u16 link_info;
> +	u32 ep_name[55];
> +};
> +
> +struct icm_tr_event_device_disconnected {
> +	struct icm_pkg_header hdr;
> +	u32 route_hi;
> +	u32 route_lo;
> +};
> +
> +struct icm_tr_event_xdomain_connected {
> +	struct icm_pkg_header hdr;
> +	u16 reserved;
> +	u16 link_info;
> +	uuid_t remote_uuid;
> +	uuid_t local_uuid;
> +	u32 local_route_hi;
> +	u32 local_route_lo;
> +	u32 remote_route_hi;
> +	u32 remote_route_lo;
> +};
> +
> +struct icm_tr_event_xdomain_disconnected {
> +	struct icm_pkg_header hdr;
> +	u32 route_hi;
> +	u32 route_lo;
> +	uuid_t remote_uuid;
> +};
> +
> +struct icm_tr_pkg_approve_device {
> +	struct icm_pkg_header hdr;
> +	uuid_t ep_uuid;
> +	u32 route_hi;
> +	u32 route_lo;
> +	u8 connection_id;
> +	u8 reserved1[3];
> +};
> +
> +struct icm_tr_pkg_add_device_key {
> +	struct icm_pkg_header hdr;
> +	uuid_t ep_uuid;
> +	u32 route_hi;
> +	u32 route_lo;
> +	u8 connection_id;
> +	u8 reserved[3];
> +	u32 key[8];
> +};
> +
> +struct icm_tr_pkg_challenge_device {
> +	struct icm_pkg_header hdr;
> +	uuid_t ep_uuid;
> +	u32 route_hi;
> +	u32 route_lo;
> +	u8 connection_id;
> +	u8 reserved[3];
> +	u32 challenge[8];
> +};
> +
> +struct icm_tr_pkg_approve_xdomain {
> +	struct icm_pkg_header hdr;
> +	u32 route_hi;
> +	u32 route_lo;
> +	uuid_t remote_uuid;
> +	u16 transmit_path;
> +	u16 transmit_ring;
> +	u16 receive_path;
> +	u16 receive_ring;
> +};
> +
> +struct icm_tr_pkg_disconnect_xdomain {
> +	struct icm_pkg_header hdr;
> +	u8 stage;
> +	u8 reserved[3];
> +	u32 route_hi;
> +	u32 route_lo;
> +	uuid_t remote_uuid;
> +};
> +
> +struct icm_tr_pkg_challenge_device_response {
> +	struct icm_pkg_header hdr;
> +	uuid_t ep_uuid;
> +	u32 route_hi;
> +	u32 route_lo;
> +	u8 connection_id;
> +	u8 reserved[3];
> +	u32 challenge[8];
> +	u32 response[8];
> +};
> +
> +struct icm_tr_pkg_add_device_key_response {
> +	struct icm_pkg_header hdr;
> +	uuid_t ep_uuid;
> +	u32 route_hi;
> +	u32 route_lo;
> +	u8 connection_id;
> +	u8 reserved[3];
> +};
> +
> +struct icm_tr_pkg_approve_xdomain_response {
> +	struct icm_pkg_header hdr;
> +	u32 route_hi;
> +	u32 route_lo;
> +	uuid_t remote_uuid;
> +	u16 transmit_path;
> +	u16 transmit_ring;
> +	u16 receive_path;
> +	u16 receive_ring;
> +};
> +
> +struct icm_tr_pkg_disconnect_xdomain_response {
> +	struct icm_pkg_header hdr;
> +	u8 stage;
> +	u8 reserved[3];
> +	u32 route_hi;
> +	u32 route_lo;
> +	uuid_t remote_uuid;
> +};
> +
>  /* XDomain messages */
>  
>  struct tb_xdomain_header {

-- 
Andy Shevchenko <andriy.shevchenko@...ux.intel.com>
Intel Finland Oy

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ