// SPDX-License-Identifier: GPL-2.0
/*
 * Internal Thunderbolt Connection Manager. This is a firmware running on
 * the Thunderbolt host controller performing most of the low-level
 * handling.
 *
 * Copyright (C) 2017, Intel Corporation
 * Authors: Michael Jamet <michael.jamet@intel.com>
 *          Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/pm_runtime.h>
#include <linux/platform_data/x86/apple.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/workqueue.h>

#include "ctl.h"
#include "nhi_regs.h"
#include "tb.h"

#define PCIE2CIO_CMD			0x30
#define PCIE2CIO_CMD_TIMEOUT		BIT(31)
#define PCIE2CIO_CMD_START		BIT(30)
#define PCIE2CIO_CMD_WRITE		BIT(21)
#define PCIE2CIO_CMD_CS_MASK		GENMASK(20, 19)
#define PCIE2CIO_CMD_CS_SHIFT		19
#define PCIE2CIO_CMD_PORT_MASK		GENMASK(18, 13)
#define PCIE2CIO_CMD_PORT_SHIFT		13

#define PCIE2CIO_WRDATA			0x34
#define PCIE2CIO_RDDATA			0x38

#define PHY_PORT_CS1			0x37
#define PHY_PORT_CS1_LINK_DISABLE	BIT(14)
#define PHY_PORT_CS1_LINK_STATE_MASK	GENMASK(29, 26)
#define PHY_PORT_CS1_LINK_STATE_SHIFT	26

#define ICM_TIMEOUT			5000	/* ms */
#define ICM_RETRIES			3
#define ICM_APPROVE_TIMEOUT		10000	/* ms */
#define ICM_MAX_LINK			4

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
 * @rescan_work: Work used to rescan the surviving switches after resume
 * @upstream_port: Pointer to the PCIe upstream port this host
 *		   controller is connected. This is only set for systems
 *		   where ICM needs to be started manually
 * @vnd_cap: Vendor defined capability where PCIe2CIO mailbox resides
 *	     (only set when @upstream_port is not %NULL)
 * @safe_mode: ICM is in safe mode
 * @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
 * @get_mode: Read and return the ICM firmware mode (optional)
 * @get_route: Find a route string for given switch
 * @save_devices: Ask ICM to save devices to ACL when suspending (optional)
 * @driver_ready: Send driver ready message to ICM
 * @set_uuid: Set UUID for the root switch (optional)
 * @device_connected: Handle device connected ICM message
 * @device_disconnected: Handle device disconnected ICM message
 * @xdomain_connected: Handle XDomain connected ICM message
 * @xdomain_disconnected: Handle XDomain disconnected ICM message
 * @rtd3_veto: Handle RTD3 veto notification ICM message
 */
struct icm {
	struct mutex request_lock;
	struct delayed_work rescan_work;
	struct pci_dev *upstream_port;
	int vnd_cap;
	bool safe_mode;
	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);
	int (*get_mode)(struct tb *tb);
	int (*get_route)(struct tb *tb, u8 link, u8 depth, u64 *route);
	void (*save_devices)(struct tb *tb);
	int (*driver_ready)(struct tb *tb,
			    enum tb_security_level *security_level,
			    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);
	void (*device_disconnected)(struct tb *tb,
				    const struct icm_pkg_header *hdr);
	void (*xdomain_connected)(struct tb *tb,
				  const struct icm_pkg_header *hdr);
	void (*xdomain_disconnected)(struct tb *tb,
				     const struct icm_pkg_header *hdr);
	void (*rtd3_veto)(struct tb *tb, const struct icm_pkg_header *hdr);
};

struct icm_notification {
	struct work_struct work;
	struct icm_pkg_header *pkg;
	struct tb *tb;
};

struct ep_name_entry {
	u8 len;
	u8 type;
	u8 data[];
};

#define EP_NAME_INTEL_VSS	0x10

/* Intel Vendor specific structure */
struct intel_vss {
	u16 vendor;
	u16 model;
	u8 mc;
	u8 flags;
	u16 pci_devid;
	u32 nvm_version;
};

#define INTEL_VSS_FLAGS_RTD3	BIT(0)

static const struct intel_vss *parse_intel_vss(const void *ep_name, size_t size)
{
	const void *end = ep_name + size;

	while (ep_name < end) {
		const struct ep_name_entry *ep = ep_name;

		if (!ep->len)
			break;
		if (ep_name + ep->len > end)
			break;

		if (ep->type == EP_NAME_INTEL_VSS)
			return (const struct intel_vss *)ep->data;

		ep_name += ep->len;
	}

	return NULL;
}

static bool intel_vss_is_rtd3(const void *ep_name, size_t size)
{
	const struct intel_vss *vss;

	vss = parse_intel_vss(ep_name, size);
	if (vss)
		return !!(vss->flags & INTEL_VSS_FLAGS_RTD3);

	return false;
}

static inline struct tb *icm_to_tb(struct icm *icm)
{
	return ((void *)icm - sizeof(struct tb));
}

static inline u8 phy_port_from_route(u64 route, u8 depth)
{
	u8 link;

	link = depth ? route >> ((depth - 1) * 8) : route;
	return tb_phy_port_from_link(link);
}

static inline u8 dual_link_from_link(u8 link)
{
	return link ? ((link - 1) ^ 0x01) + 1 : 0;
}

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 int pci2cio_wait_completion(struct icm *icm, unsigned long timeout_msec)
{
	unsigned long end = jiffies + msecs_to_jiffies(timeout_msec);
	u32 cmd;

	do {
		pci_read_config_dword(icm->upstream_port,
				      icm->vnd_cap + PCIE2CIO_CMD, &cmd);
		if (!(cmd & PCIE2CIO_CMD_START)) {
			if (cmd & PCIE2CIO_CMD_TIMEOUT)
				break;
			return 0;
		}

		msleep(50);
	} while (time_before(jiffies, end));

	return -ETIMEDOUT;
}

static int pcie2cio_read(struct icm *icm, enum tb_cfg_space cs,
			 unsigned int port, unsigned int index, u32 *data)
{
	struct pci_dev *pdev = icm->upstream_port;
	int ret, vnd_cap = icm->vnd_cap;
	u32 cmd;

	cmd = index;
	cmd |= (port << PCIE2CIO_CMD_PORT_SHIFT) & PCIE2CIO_CMD_PORT_MASK;
	cmd |= (cs << PCIE2CIO_CMD_CS_SHIFT) & PCIE2CIO_CMD_CS_MASK;
	cmd |= PCIE2CIO_CMD_START;
	pci_write_config_dword(pdev, vnd_cap + PCIE2CIO_CMD, cmd);

	ret = pci2cio_wait_completion(icm, 5000);
	if (ret)
		return ret;

	pci_read_config_dword(pdev, vnd_cap + PCIE2CIO_RDDATA, data);
	return 0;
}

static int pcie2cio_write(struct icm *icm, enum tb_cfg_space cs,
			  unsigned int port, unsigned int index, u32 data)
{
	struct pci_dev *pdev = icm->upstream_port;
	int vnd_cap = icm->vnd_cap;
	u32 cmd;

	pci_write_config_dword(pdev, vnd_cap + PCIE2CIO_WRDATA, data);

	cmd = index;
	cmd |= (port << PCIE2CIO_CMD_PORT_SHIFT) & PCIE2CIO_CMD_PORT_MASK;
	cmd |= (cs << PCIE2CIO_CMD_CS_SHIFT) & PCIE2CIO_CMD_CS_MASK;
	cmd |= PCIE2CIO_CMD_WRITE | PCIE2CIO_CMD_START;
	pci_write_config_dword(pdev, vnd_cap + PCIE2CIO_CMD, cmd);

	return pci2cio_wait_completion(icm, 5000);
}

static bool icm_match(const struct tb_cfg_request *req,
		      const struct ctl_pkg *pkg)
{
	const struct icm_pkg_header *res_hdr = pkg->buffer;
	const struct icm_pkg_header *req_hdr = req->request;

	if (pkg->frame.eof != req->response_type)
		return false;
	if (res_hdr->code != req_hdr->code)
		return false;

	return true;
}

static bool icm_copy(struct tb_cfg_request *req, const struct ctl_pkg *pkg)
{
	const struct icm_pkg_header *hdr = pkg->buffer;

	if (hdr->packet_id < req->npackets) {
		size_t offset = hdr->packet_id * req->response_size;

		memcpy(req->response + offset, pkg->buffer, req->response_size);
	}

	return hdr->packet_id == hdr->total_packets - 1;
}

static int icm_request(struct tb *tb, const void *request, size_t request_size,
		       void *response, size_t response_size, size_t npackets,
		       int retries, unsigned int timeout_msec)
{
	struct icm *icm = tb_priv(tb);

	do {
		struct tb_cfg_request *req;
		struct tb_cfg_result res;

		req = tb_cfg_request_alloc();
		if (!req)
			return -ENOMEM;

		req->match = icm_match;
		req->copy = icm_copy;
		req->request = request;
		req->request_size = request_size;
		req->request_type = TB_CFG_PKG_ICM_CMD;
		req->response = response;
		req->npackets = npackets;
		req->response_size = response_size;
		req->response_type = TB_CFG_PKG_ICM_RESP;

		mutex_lock(&icm->request_lock);
		res = tb_cfg_request_sync(tb->ctl, req, timeout_msec);
		mutex_unlock(&icm->request_lock);

		tb_cfg_request_put(req);

		if (res.err != -ETIMEDOUT)
			return res.err == 1 ? -EIO : res.err;

		usleep_range(20, 50);
	} while (retries--);

	return -ETIMEDOUT;
}

/*
 * If rescan is queued to run (we are resuming), postpone it to give the
 * firmware some more time to send device connected notifications for next
 * devices in the chain.
 */
static void icm_postpone_rescan(struct tb *tb)
{
	struct icm *icm = tb_priv(tb);

	if (delayed_work_pending(&icm->rescan_work))
		mod_delayed_work(tb->wq, &icm->rescan_work,
				 msecs_to_jiffies(500));
}

static void icm_veto_begin(struct tb *tb)
{
	struct icm *icm = tb_priv(tb);

	if (!icm->veto) {
		icm->veto = true;
		/* Keep the domain powered while veto is in effect */
		pm_runtime_get(&tb->dev);
	}
}

static void icm_veto_end(struct tb *tb)
{
	struct icm *icm = tb_priv(tb);

	if (icm->veto) {
		icm->veto = false;
		/* Allow the domain suspend now */
		pm_runtime_mark_last_busy(&tb->dev);
		pm_runtime_put_autosuspend(&tb->dev);
	}
}

static bool icm_firmware_running(const struct tb_nhi *nhi)
{
	u32 val;

	val = ioread32(nhi->iobase + REG_FW_STS);
	return !!(val & REG_FW_STS_ICM_EN);
}

static bool icm_fr_is_supported(struct tb *tb)
{
	return !x86_apple_machine;
}

static inline int icm_fr_get_switch_index(u32 port)
{
	int index;

	if ((port & ICM_PORT_TYPE_MASK) != TB_TYPE_PORT)
		return 0;

	index = port >> ICM_PORT_INDEX_SHIFT;
	return index != 0xff ? index : 0;
}

static int icm_fr_get_route(struct tb *tb, u8 link, u8 depth, u64 *route)
{
	struct icm_fr_pkg_get_topology_response *switches, *sw;
	struct icm_fr_pkg_get_topology request = {
		.hdr = { .code = ICM_GET_TOPOLOGY },
	};
	size_t npackets = ICM_GET_TOPOLOGY_PACKETS;
	int ret, index;
	u8 i;

	switches = kcalloc(npackets, sizeof(*switches), GFP_KERNEL);
	if (!switches)
		return -ENOMEM;

	ret = icm_request(tb, &request, sizeof(request), switches,
			  sizeof(*switches), npackets, ICM_RETRIES, ICM_TIMEOUT);
	if (ret)
		goto err_free;

	sw = &switches[0];
	index = icm_fr_get_switch_index(sw->ports[link]);
	if (!index) {
		ret = -ENODEV;
		goto err_free;
	}

	sw = &switches[index];
	for (i = 1; i < depth; i++) {
		unsigned int j;

		if (!(sw->first_data & ICM_SWITCH_USED)) {
			ret = -ENODEV;
			goto err_free;
		}

		for (j = 0; j < ARRAY_SIZE(sw->ports); j++) {
			index = icm_fr_get_switch_index(sw->ports[j]);
			if (index > sw->switch_index) {
				sw = &switches[index];
				break;
			}
		}
	}

	*route = get_route(sw->route_hi, sw->route_lo);

err_free:
	kfree(switches);
	return ret;
}

static void icm_fr_save_devices(struct tb *tb)
{
	nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0);
}

static int
icm_fr_driver_ready(struct tb *tb, enum tb_security_level *security_level,
		    u8 *proto_version, size_t *nboot_acl, bool *rpm)
{
	struct icm_fr_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, ICM_RETRIES, ICM_TIMEOUT);
	if (ret)
		return ret;

	if (security_level)
		*security_level = reply.security_level & ICM_FR_SLEVEL_MASK;

	return 0;
}

static int icm_fr_approve_switch(struct tb *tb, struct tb_switch *sw)
{
	struct icm_fr_pkg_approve_device request;
	struct icm_fr_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.connection_id = sw->connection_id;
	request.connection_key = sw->connection_key;

	memset(&reply, 0, sizeof(reply));
	/* Use larger timeout as establishing tunnels can take some time */
	ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
			  1, ICM_RETRIES, 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_fr_add_switch_key(struct tb *tb, struct tb_switch *sw)
{
	struct icm_fr_pkg_add_device_key request;
	struct icm_fr_pkg_add_device_key_response reply;
	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.connection_id = sw->connection_id;
	request.connection_key = sw->connection_key;
	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_RETRIES, 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_fr_challenge_switch_key(struct tb *tb, struct tb_switch *sw,
				       const u8 *challenge, u8 *response)
{
	struct icm_fr_pkg_challenge_device request;
	struct icm_fr_pkg_challenge_device_response reply;
	int ret;

	memset(&request, 0, sizeof(request));
	memcpy(&request.ep_uuid, sw->uuid, sizeof(request.ep_uuid));
	request.hdr.code = ICM_CHALLENGE_DEVICE;
	request.connection_id = sw->connection_id;
	request.connection_key = sw->connection_key;
	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_RETRIES, 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_fr_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd,
					int transmit_path, int transmit_ring,
					int receive_path, int receive_ring)
{
	struct icm_fr_pkg_approve_xdomain_response reply;
	struct icm_fr_pkg_approve_xdomain request;
	int ret;

	memset(&request, 0, sizeof(request));
	request.hdr.code = ICM_APPROVE_XDOMAIN;
	request.link_info = xd->depth << ICM_LINK_INFO_DEPTH_SHIFT | xd->link;
	memcpy(&request.remote_uuid, xd->remote_uuid, sizeof(*xd->remote_uuid));

	request.transmit_path = transmit_path;
	request.transmit_ring = transmit_ring;
	request.receive_path = receive_path;
	request.receive_ring = receive_ring;

	memset(&reply, 0, sizeof(reply));
	ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
			  1, ICM_RETRIES, ICM_TIMEOUT);
	if (ret)
		return ret;

	if (reply.hdr.flags & ICM_FLAGS_ERROR)
		return -EIO;

	return 0;
}

static int icm_fr_disconnect_xdomain_paths(struct tb *tb, struct tb_xdomain *xd,
					   int transmit_path, int transmit_ring,
					   int receive_path, int receive_ring)
{
	u8 phy_port;
	u8 cmd;

	phy_port = tb_phy_port_from_link(xd->link);
	if (phy_port == 0)
		cmd = NHI_MAILBOX_DISCONNECT_PA;
	else
		cmd = NHI_MAILBOX_DISCONNECT_PB;

	nhi_mailbox_cmd(tb->nhi, cmd, 1);
	usleep_range(10, 50);
	nhi_mailbox_cmd(tb->nhi, cmd, 2);
	return 0;
}

static struct tb_switch *alloc_switch(struct tb_switch *parent_sw, u64 route,
				      const uuid_t *uuid)
{
	struct tb *tb = parent_sw->tb;
	struct tb_switch *sw;

	sw = tb_switch_alloc(tb, &parent_sw->dev, route);
	if (IS_ERR(sw)) {
		tb_warn(tb, "failed to allocate switch at %llx\n", route);
		return sw;
	}

	sw->uuid = kmemdup(uuid, sizeof(*uuid), GFP_KERNEL);
	if (!sw->uuid) {
		tb_switch_put(sw);
		return ERR_PTR(-ENOMEM);
	}

	init_completion(&sw->rpm_complete);
	return sw;
}

static int add_switch(struct tb_switch *parent_sw, struct tb_switch *sw)
{
	u64 route = tb_route(sw);
	int ret;

	/* Link the two switches now */
	tb_port_at(route, parent_sw)->remote = tb_upstream_port(sw);
	tb_upstream_port(sw)->remote = tb_port_at(route, parent_sw);

	ret = tb_switch_add(sw);
	if (ret)
		tb_port_at(tb_route(sw), parent_sw)->remote = NULL;

	return ret;
}

static void update_switch(struct tb_switch *sw, u64 route, u8 connection_id,
			  u8 connection_key, u8 link, u8 depth, bool boot)
{
	struct tb_switch *parent_sw = tb_switch_parent(sw);

	/* Disconnect from parent */
	tb_switch_downstream_port(sw)->remote = NULL;
	/* Re-connect via updated port */
	tb_port_at(route, parent_sw)->remote = tb_upstream_port(sw);

	/* Update with the new addressing information */
	sw->config.route_hi = upper_32_bits(route);
	sw->config.route_lo = lower_32_bits(route);
	sw->connection_id = connection_id;
	sw->connection_key = connection_key;
	sw->link = link;
	sw->depth = depth;
	sw->boot = boot;

	/* This switch still exists */
	sw->is_unplugged = false;

	/* Runtime resume is now complete */
	complete(&sw->rpm_complete);
}

static void remove_switch(struct tb_switch *sw)
{
	tb_switch_downstream_port(sw)->remote = NULL;
	tb_switch_remove(sw);
}

static void add_xdomain(struct tb_switch *sw, u64 route,
			const uuid_t *local_uuid, const uuid_t *remote_uuid,
			u8 link, u8 depth)
{
	struct tb_xdomain *xd;

	pm_runtime_get_sync(&sw->dev);

	xd = tb_xdomain_alloc(sw->tb, &sw->dev, route, local_uuid, remote_uuid);
	if (!xd)
		goto out;

	xd->link = link;
	xd->depth = depth;

	tb_port_at(route, sw)->xdomain = xd;

	tb_xdomain_add(xd);

out:
	pm_runtime_mark_last_busy(&sw->dev);
	pm_runtime_put_autosuspend(&sw->dev);
}

static void update_xdomain(struct tb_xdomain *xd, u64 route, u8 link)
{
	xd->link = link;
	xd->route = route;
	xd->is_unplugged = false;
}

static void remove_xdomain(struct tb_xdomain *xd)
{
	struct tb_switch *sw;

	sw = tb_to_switch(xd->dev.parent);
	tb_port_at(xd->route, sw)->xdomain = NULL;
	tb_xdomain_remove(xd);
}

static void
icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
{
	const struct icm_fr_event_device_connected *pkg =
		(const struct icm_fr_event_device_connected *)hdr;
	enum tb_security_level security_level;
	struct tb_switch *sw, *parent_sw;
	bool boot, dual_lane, speed_gen3;
	struct icm *icm = tb_priv(tb);
	bool authorized = false;
	struct tb_xdomain *xd;
	u8 link, depth;
	u64 route;
	int ret;

	icm_postpone_rescan(tb);

	link = pkg->link_info & ICM_LINK_INFO_LINK_MASK;
	depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>
		ICM_LINK_INFO_DEPTH_SHIFT;
	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;
	dual_lane = pkg->hdr.flags & ICM_FLAGS_DUAL_LANE;
	speed_gen3 = pkg->hdr.flags & ICM_FLAGS_SPEED_GEN3;

	if (pkg->link_info & ICM_LINK_INFO_REJECTED) {
		tb_info(tb, "switch at %u.%u was rejected by ICM firmware because topology limit exceeded\n",
			link, depth);
		return;
	}

	sw = tb_switch_find_by_uuid(tb, &pkg->ep_uuid);
	if (sw) {
		u8 phy_port, sw_phy_port;

		sw_phy_port = tb_phy_port_from_link(sw->link);
		phy_port = tb_phy_port_from_link(link);

		/*
		 * On resume ICM will send us connected events for the
		 * devices that still are present. However, that
		 * information might have changed for example by the
		 * fact that a switch on a dual-link connection might
		 * have been enumerated using the other link now. Make
		 * sure our book keeping matches that.
		 */
		if (sw->depth == depth && sw_phy_port == phy_port &&
		    !!sw->authorized == authorized) {
			/*
			 * It was enumerated through another link so update
			 * route string accordingly.
			 */
			if (sw->link != link) {
				ret = icm->get_route(tb, link, depth, &route);
				if (ret) {
					tb_err(tb, "failed to update route string for switch at %u.%u\n",
					       link, depth);
					tb_switch_put(sw);
					return;
				}
			} else {
				route = tb_route(sw);
			}

			update_switch(sw, route, pkg->connection_id,
				      pkg->connection_key, link, depth, boot);
			tb_switch_put(sw);
			return;
		}

		/*
		 * User connected the same switch to another physical
		 * port or to another part of the topology. Remove the
		 * existing switch now before adding the new one.
		 */
		remove_switch(sw);
		tb_switch_put(sw);
	}

	/*
	 * If the switch was not found by UUID, look for a switch on
	 * same physical port (taking possible link aggregation into
	 * account) and depth. If we found one it is definitely a stale
	 * one so remove it first.
	 */
	sw = tb_switch_find_by_link_depth(tb, link, depth);
	if (!sw) {
		u8 dual_link;

		dual_link = dual_link_from_link(link);
		if (dual_link)
			sw = tb_switch_find_by_link_depth(tb, dual_link, depth);
	}
	if (sw) {
		remove_switch(sw);
		tb_switch_put(sw);
	}

	/* Remove existing XDomain connection if found */
	xd = tb_xdomain_find_by_link_depth(tb, link, depth);
	if (xd) {
		remove_xdomain(xd);
		tb_xdomain_put(xd);
	}

	parent_sw = tb_switch_find_by_link_depth(tb, link, depth - 1);
	if (!parent_sw) {
		tb_err(tb, "failed to find parent switch for %u.%u\n",
		       link, depth);
		return;
	}

	ret = icm->get_route(tb, link, depth, &route);
	if (ret) {
		tb_err(tb, "failed to find route string for switch at %u.%u\n",
		       link, depth);
		tb_switch_put(parent_sw);
		return;
	}

	pm_runtime_get_sync(&parent_sw->dev);

	sw = alloc_switch(parent_sw, route, &pkg->ep_uuid);
	if (!IS_ERR(sw)) {
		sw->connection_id = pkg->connection_id;
		sw->connection_key = pkg->connection_key;
		sw->link = link;
		sw->depth = depth;
		sw->authorized = authorized;
		sw->security_level = security_level;
		sw->boot = boot;
		sw->link_speed = speed_gen3 ? 20 : 10;
		sw->link_width = dual_lane ? TB_LINK_WIDTH_DUAL :
					     TB_LINK_WIDTH_SINGLE;
		sw->rpm = intel_vss_is_rtd3(pkg->ep_name, sizeof(pkg->ep_name));

		if (add_switch(parent_sw, sw))
			tb_switch_put(sw);
	}

	pm_runtime_mark_last_busy(&parent_sw->dev);
	pm_runtime_put_autosuspend(&parent_sw->dev);

	tb_switch_put(parent_sw);
}

static void
icm_fr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
{
	const struct icm_fr_event_device_disconnected *pkg =
		(const struct icm_fr_event_device_disconnected *)hdr;
	struct tb_switch *sw;
	u8 link, depth;

	link = pkg->link_info & ICM_LINK_INFO_LINK_MASK;
	depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>
		ICM_LINK_INFO_DEPTH_SHIFT;

	if (link > ICM_MAX_LINK || depth > TB_SWITCH_MAX_DEPTH) {
		tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth);
		return;
	}

	sw = tb_switch_find_by_link_depth(tb, link, depth);
	if (!sw) {
		tb_warn(tb, "no switch exists at %u.%u, ignoring\n", link,
			depth);
		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);
}

static void
icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
{
	const struct icm_fr_event_xdomain_connected *pkg =
		(const struct icm_fr_event_xdomain_connected *)hdr;
	struct tb_xdomain *xd;
	struct tb_switch *sw;
	u8 link, depth;
	u64 route;

	link = pkg->link_info & ICM_LINK_INFO_LINK_MASK;
	depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>
		ICM_LINK_INFO_DEPTH_SHIFT;

	if (link > ICM_MAX_LINK || depth > TB_SWITCH_MAX_DEPTH) {
		tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth);
		return;
	}

	route = get_route(pkg->local_route_hi, pkg->local_route_lo);

	xd = tb_xdomain_find_by_uuid(tb, &pkg->remote_uuid);
	if (xd) {
		u8 xd_phy_port, phy_port;

		xd_phy_port = phy_port_from_route(xd->route, xd->depth);
		phy_port = phy_port_from_route(route, depth);

		if (xd->depth == depth && xd_phy_port == phy_port) {
			update_xdomain(xd, route, link);
			tb_xdomain_put(xd);
			return;
		}

		/*
		 * If we find an existing XDomain connection remove it
		 * now. We need to go through login handshake and
		 * everything anyway to be able to re-establish the
		 * connection.
		 */
		remove_xdomain(xd);
		tb_xdomain_put(xd);
	}

	/*
	 * Look if there already exists an XDomain in the same place
	 * than the new one and in that case remove it because it is
	 * most likely another host that got disconnected.
	 */
	xd = tb_xdomain_find_by_link_depth(tb, link, depth);
	if (!xd) {
		u8 dual_link;

		dual_link = dual_link_from_link(link);
		if (dual_link)
			xd = tb_xdomain_find_by_link_depth(tb, dual_link,
							   depth);
	}
	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 = tb_switch_find_by_route(tb, route);
	if (sw) {
		remove_switch(sw);
		tb_switch_put(sw);
	}

	sw = tb_switch_find_by_link_depth(tb, link, depth);
	if (!sw) {
		tb_warn(tb, "no switch exists at %u.%u, ignoring\n", link,
			depth);
		return;
	}

	add_xdomain(sw, route, &pkg->local_uuid, &pkg->remote_uuid, link,
		    depth);
	tb_switch_put(sw);
}

static void
icm_fr_xdomain_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
{
	const struct icm_fr_event_xdomain_disconnected *pkg =
		(const struct icm_fr_event_xdomain_disconnected *)hdr;
	struct tb_xdomain *xd;

	/*
	 * If the connection is through one or multiple devices, the
	 * XDomain device is removed along with them so it is fine if we
	 * cannot find it here.
	 */
	xd = tb_xdomain_find_by_uuid(tb, &pkg->remote_uuid);
	if (xd) {
		remove_xdomain(xd);
		tb_xdomain_put(xd);
	}
}

static int icm_tr_cio_reset(struct tb *tb)
{
	return pcie2cio_write(tb_priv(tb), TB_CFG_SWITCH, 0, 0x777, BIT(1));
}

static int
icm_tr_driver_ready(struct tb *tb, enum tb_security_level *security_level,
		    u8 *proto_version, size_t *nboot_acl, bool *rpm)
{
	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, 10, 250);
	if (ret)
		return ret;

	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;
	if (rpm)
		*rpm = !!(reply.hdr.flags & ICM_TR_FLAGS_RTD3);

	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_RETRIES, 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_RETRIES, 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_RETRIES, 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,
					int transmit_path, int transmit_ring,
					int receive_path, int receive_ring)
{
	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 = transmit_path;
	request.transmit_ring = transmit_ring;
	request.receive_path = receive_path;
	request.receive_ring = 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_RETRIES, 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_RETRIES, 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 transmit_path, int transmit_ring,
					   int receive_path, int receive_ring)
{
	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,
			  bool force_rtd3)
{
	const struct icm_tr_event_device_connected *pkg =
		(const struct icm_tr_event_device_connected *)hdr;
	bool authorized, boot, dual_lane, speed_gen3;
	enum tb_security_level security_level;
	struct tb_switch *sw, *parent_sw;
	struct tb_xdomain *xd;
	u64 route;

	icm_postpone_rescan(tb);

	/*
	 * 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;

	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;
	dual_lane = pkg->hdr.flags & ICM_FLAGS_DUAL_LANE;
	speed_gen3 = pkg->hdr.flags & ICM_FLAGS_SPEED_GEN3;

	if (pkg->link_info & ICM_LINK_INFO_REJECTED) {
		tb_info(tb, "switch at %llx was rejected by ICM firmware because topology limit exceeded\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) {
			update_switch(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;
	}

	pm_runtime_get_sync(&parent_sw->dev);

	sw = alloc_switch(parent_sw, route, &pkg->ep_uuid);
	if (!IS_ERR(sw)) {
		sw->connection_id = pkg->connection_id;
		sw->authorized = authorized;
		sw->security_level = security_level;
		sw->boot = boot;
		sw->link_speed = speed_gen3 ? 20 : 10;
		sw->link_width = dual_lane ? TB_LINK_WIDTH_DUAL :
					     TB_LINK_WIDTH_SINGLE;
		sw->rpm = force_rtd3;
		if (!sw->rpm)
			sw->rpm = intel_vss_is_rtd3(pkg->ep_name,
						    sizeof(pkg->ep_name));

		if (add_switch(parent_sw, sw))
			tb_switch_put(sw);
	}

	pm_runtime_mark_last_busy(&parent_sw->dev);
	pm_runtime_put_autosuspend(&parent_sw->dev);

	tb_switch_put(parent_sw);
}

static void
icm_tr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
{
	__icm_tr_device_connected(tb, hdr, false);
}

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;
	}
	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);
}

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 = tb_switch_find_by_route(tb, route);
	if (sw) {
		remove_switch(sw);
		tb_switch_put(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;

	parent = pci_upstream_bridge(pdev);
	while (parent) {
		if (!pci_is_pcie(parent))
			return NULL;
		if (pci_pcie_type(parent) == PCI_EXP_TYPE_UPSTREAM)
			break;
		parent = pci_upstream_bridge(parent);
	}

	if (!parent)
		return NULL;

	switch (parent->device) {
	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE:
	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE:
	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_BRIDGE:
	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE:
	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE:
	case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_BRIDGE:
	case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_BRIDGE:
		return parent;
	}

	return NULL;
}

static bool icm_ar_is_supported(struct tb *tb)
{
	struct pci_dev *upstream_port;
	struct icm *icm = tb_priv(tb);

	/*
	 * Starting from Alpine Ridge we can use ICM on Apple machines
	 * as well. We just need to reset and re-enable it first.
	 * However, only start it if explicitly asked by the user.
	 */
	if (icm_firmware_running(tb->nhi))
		return true;
	if (!start_icm)
		return false;

	/*
	 * Find the upstream PCIe port in case we need to do reset
	 * through its vendor specific registers.
	 */
	upstream_port = get_upstream_port(tb->nhi->pdev);
	if (upstream_port) {
		int cap;

		cap = pci_find_ext_capability(upstream_port,
					      PCI_EXT_CAP_ID_VNDR);
		if (cap > 0) {
			icm->upstream_port = upstream_port;
			icm->vnd_cap = cap;

			return true;
		}
	}

	return false;
}

static int icm_ar_cio_reset(struct tb *tb)
{
	return pcie2cio_write(tb_priv(tb), TB_CFG_SWITCH, 0, 0x50, BIT(9));
}

static int icm_ar_get_mode(struct tb *tb)
{
	struct tb_nhi *nhi = tb->nhi;
	int retries = 60;
	u32 val;

	do {
		val = ioread32(nhi->iobase + REG_FW_STS);
		if (val & REG_FW_STS_NVM_AUTH_DONE)
			break;
		msleep(50);
	} while (--retries);

	if (!retries) {
		dev_err(&nhi->pdev->dev, "ICM firmware not authenticated\n");
		return -ENODEV;
	}

	return nhi_mailbox_mode(nhi);
}

static int
icm_ar_driver_ready(struct tb *tb, enum tb_security_level *security_level,
		    u8 *proto_version, size_t *nboot_acl, bool *rpm)
{
	struct icm_ar_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, ICM_RETRIES, ICM_TIMEOUT);
	if (ret)
		return ret;

	if (security_level)
		*security_level = reply.info & ICM_AR_INFO_SLEVEL_MASK;
	if (nboot_acl && (reply.info & ICM_AR_INFO_BOOT_ACL_SUPPORTED))
		*nboot_acl = (reply.info & ICM_AR_INFO_BOOT_ACL_MASK) >>
				ICM_AR_INFO_BOOT_ACL_SHIFT;
	if (rpm)
		*rpm = !!(reply.hdr.flags & ICM_AR_FLAGS_RTD3);

	return 0;
}

static int icm_ar_get_route(struct tb *tb, u8 link, u8 depth, u64 *route)
{
	struct icm_ar_pkg_get_route_response reply;
	struct icm_ar_pkg_get_route request = {
		.hdr = { .code = ICM_GET_ROUTE },
		.link_info = depth << ICM_LINK_INFO_DEPTH_SHIFT | link,
	};
	int ret;

	memset(&reply, 0, sizeof(reply));
	ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
			  1, ICM_RETRIES, ICM_TIMEOUT);
	if (ret)
		return ret;

	if (reply.hdr.flags & ICM_FLAGS_ERROR)
		return -EIO;

	*route = get_route(reply.route_hi, reply.route_lo);
	return 0;
}

static int icm_ar_get_boot_acl(struct tb *tb, uuid_t *uuids, size_t nuuids)
{
	struct icm_ar_pkg_preboot_acl_response reply;
	struct icm_ar_pkg_preboot_acl request = {
		.hdr = { .code = ICM_PREBOOT_ACL },
	};
	int ret, i;

	memset(&reply, 0, sizeof(reply));
	ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
			  1, ICM_RETRIES, ICM_TIMEOUT);
	if (ret)
		return ret;

	if (reply.hdr.flags & ICM_FLAGS_ERROR)
		return -EIO;

	for (i = 0; i < nuuids; i++) {
		u32 *uuid = (u32 *)&uuids[i];

		uuid[0] = reply.acl[i].uuid_lo;
		uuid[1] = reply.acl[i].uuid_hi;

		if (uuid[0] == 0xffffffff && uuid[1] == 0xffffffff) {
			/* Map empty entries to null UUID */
			uuid[0] = 0;
			uuid[1] = 0;
		} else if (uuid[0] != 0 || uuid[1] != 0) {
			/* Upper two DWs are always one's */
			uuid[2] = 0xffffffff;
			uuid[3] = 0xffffffff;
		}
	}

	return ret;
}

static int icm_ar_set_boot_acl(struct tb *tb, const uuid_t *uuids,
			       size_t nuuids)
{
	struct icm_ar_pkg_preboot_acl_response reply;
	struct icm_ar_pkg_preboot_acl request = {
		.hdr = {
			.code = ICM_PREBOOT_ACL,
			.flags = ICM_FLAGS_WRITE,
		},
	};
	int ret, i;

	for (i = 0; i < nuuids; i++) {
		const u32 *uuid = (const u32 *)&uuids[i];

		if (uuid_is_null(&uuids[i])) {
			/*
			 * Map null UUID to the empty (all one) entries
			 * for ICM.
			 */
			request.acl[i].uuid_lo = 0xffffffff;
			request.acl[i].uuid_hi = 0xffffffff;
		} else {
			/* Two high DWs need to be set to all one */
			if (uuid[2] != 0xffffffff || uuid[3] != 0xffffffff)
				return -EINVAL;

			request.acl[i].uuid_lo = uuid[0];
			request.acl[i].uuid_hi = uuid[1];
		}
	}

	memset(&reply, 0, sizeof(reply));
	ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
			  1, ICM_RETRIES, ICM_TIMEOUT);
	if (ret)
		return ret;

	if (reply.hdr.flags & ICM_FLAGS_ERROR)
		return -EIO;

	return 0;
}

static int
icm_icl_driver_ready(struct tb *tb, enum tb_security_level *security_level,
		     u8 *proto_version, size_t *nboot_acl, bool *rpm)
{
	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, ICM_RETRIES, 20000);
	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;

	return 0;
}

static void icm_icl_set_uuid(struct tb *tb)
{
	struct tb_nhi *nhi = tb->nhi;
	u32 uuid[4];

	pci_read_config_dword(nhi->pdev, VS_CAP_10, &uuid[0]);
	pci_read_config_dword(nhi->pdev, VS_CAP_11, &uuid[1]);
	uuid[2] = 0xffffffff;
	uuid[3] = 0xffffffff;

	tb->root_switch->uuid = kmemdup(uuid, sizeof(uuid), GFP_KERNEL);
}

static void
icm_icl_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
{
	__icm_tr_device_connected(tb, hdr, true);
}

static void icm_icl_rtd3_veto(struct tb *tb, const struct icm_pkg_header *hdr)
{
	const struct icm_icl_event_rtd3_veto *pkg =
		(const struct icm_icl_event_rtd3_veto *)hdr;

	tb_dbg(tb, "ICM rtd3 veto=0x%08x\n", pkg->veto_reason);

	if (pkg->veto_reason)
		icm_veto_begin(tb);
	else
		icm_veto_end(tb);
}

static bool icm_tgl_is_supported(struct tb *tb)
{
	unsigned long end = jiffies + msecs_to_jiffies(10);

	do {
		u32 val;

		val = ioread32(tb->nhi->iobase + REG_FW_STS);
		if (val & REG_FW_STS_NVM_AUTH_DONE)
			return true;
		usleep_range(100, 500);
	} while (time_before(jiffies, end));

	return false;
}

static void icm_handle_notification(struct work_struct *work)
{
	struct icm_notification *n = container_of(work, typeof(*n), work);
	struct tb *tb = n->tb;
	struct icm *icm = tb_priv(tb);

	mutex_lock(&tb->lock);

	/*
	 * When the domain is stopped we flush its workqueue but before
	 * that the root switch is removed. In that case we should treat
	 * the queued events as being canceled.
	 */
	if (tb->root_switch) {
		switch (n->pkg->code) {
		case ICM_EVENT_DEVICE_CONNECTED:
			icm->device_connected(tb, n->pkg);
			break;
		case ICM_EVENT_DEVICE_DISCONNECTED:
			icm->device_disconnected(tb, n->pkg);
			break;
		case ICM_EVENT_XDOMAIN_CONNECTED:
			if (tb_is_xdomain_enabled())
				icm->xdomain_connected(tb, n->pkg);
			break;
		case ICM_EVENT_XDOMAIN_DISCONNECTED:
			if (tb_is_xdomain_enabled())
				icm->xdomain_disconnected(tb, n->pkg);
			break;
		case ICM_EVENT_RTD3_VETO:
			icm->rtd3_veto(tb, n->pkg);
			break;
		}
	}

	mutex_unlock(&tb->lock);

	kfree(n->pkg);
	kfree(n);
}

static void icm_handle_event(struct tb *tb, enum tb_cfg_pkg_type type,
			     const void *buf, size_t size)
{
	struct icm_notification *n;

	n = kmalloc(sizeof(*n), GFP_KERNEL);
	if (!n)
		return;

	n->pkg = kmemdup(buf, size, GFP_KERNEL);
	if (!n->pkg) {
		kfree(n);
		return;
	}

	INIT_WORK(&n->work, icm_handle_notification);
	n->tb = tb;

	queue_work(tb->wq, &n->work);
}

static int
__icm_driver_ready(struct tb *tb, enum tb_security_level *security_level,
		   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, proto_version, nboot_acl,
				rpm);
	if (ret) {
		tb_err(tb, "failed to send driver ready to ICM\n");
		return ret;
	}

	/*
	 * Hold on here until the switch config space is accessible so
	 * that we can read root switch config successfully.
	 */
	do {
		struct tb_cfg_result res;
		u32 tmp;

		res = tb_cfg_read_raw(tb->ctl, &tmp, 0, 0, TB_CFG_SWITCH,
				      0, 1, 100);
		if (!res.err)
			return 0;

		msleep(50);
	} while (--retries);

	tb_err(tb, "failed to read root switch config space, giving up\n");
	return -ETIMEDOUT;
}

static int icm_firmware_reset(struct tb *tb, struct tb_nhi *nhi)
{
	struct icm *icm = tb_priv(tb);
	u32 val;

	if (!icm->upstream_port)
		return -ENODEV;

	/* Put ARC to wait for CIO reset event to happen */
	val = ioread32(nhi->iobase + REG_FW_STS);
	val |= REG_FW_STS_CIO_RESET_REQ;
	iowrite32(val, nhi->iobase + REG_FW_STS);

	/* Re-start ARC */
	val = ioread32(nhi->iobase + REG_FW_STS);
	val |= REG_FW_STS_ICM_EN_INVERT;
	val |= REG_FW_STS_ICM_EN_CPU;
	iowrite32(val, nhi->iobase + REG_FW_STS);

	/* Trigger CIO reset now */
	return icm->cio_reset(tb);
}

static int icm_firmware_start(struct tb *tb, struct tb_nhi *nhi)
{
	unsigned int retries = 10;
	int ret;
	u32 val;

	/* Check if the ICM firmware is already running */
	if (icm_firmware_running(nhi))
		return 0;

	dev_dbg(&nhi->pdev->dev, "starting ICM firmware\n");

	ret = icm_firmware_reset(tb, nhi);
	if (ret)
		return ret;

	/* Wait until the ICM firmware tells us it is up and running */
	do {
		/* Check that the ICM firmware is running */
		val = ioread32(nhi->iobase + REG_FW_STS);
		if (val & REG_FW_STS_NVM_AUTH_DONE)
			return 0;

		msleep(300);
	} while (--retries);

	return -ETIMEDOUT;
}

static int icm_reset_phy_port(struct tb *tb, int phy_port)
{
	struct icm *icm = tb_priv(tb);
	u32 state0, state1;
	int port0, port1;
	u32 val0, val1;
	int ret;

	if (!icm->upstream_port)
		return 0;

	if (phy_port) {
		port0 = 3;
		port1 = 4;
	} else {
		port0 = 1;
		port1 = 2;
	}

	/*
	 * Read link status of both null ports belonging to a single
	 * physical port.
	 */
	ret = pcie2cio_read(icm, TB_CFG_PORT, port0, PHY_PORT_CS1, &val0);
	if (ret)
		return ret;
	ret = pcie2cio_read(icm, TB_CFG_PORT, port1, PHY_PORT_CS1, &val1);
	if (ret)
		return ret;

	state0 = val0 & PHY_PORT_CS1_LINK_STATE_MASK;
	state0 >>= PHY_PORT_CS1_LINK_STATE_SHIFT;
	state1 = val1 & PHY_PORT_CS1_LINK_STATE_MASK;
	state1 >>= PHY_PORT_CS1_LINK_STATE_SHIFT;

	/* If they are both up we need to reset them now */
	if (state0 != TB_PORT_UP || state1 != TB_PORT_UP)
		return 0;

	val0 |= PHY_PORT_CS1_LINK_DISABLE;
	ret = pcie2cio_write(icm, TB_CFG_PORT, port0, PHY_PORT_CS1, val0);
	if (ret)
		return ret;

	val1 |= PHY_PORT_CS1_LINK_DISABLE;
	ret = pcie2cio_write(icm, TB_CFG_PORT, port1, PHY_PORT_CS1, val1);
	if (ret)
		return ret;

	/* Wait a bit and then re-enable both ports */
	usleep_range(10, 100);

	ret = pcie2cio_read(icm, TB_CFG_PORT, port0, PHY_PORT_CS1, &val0);
	if (ret)
		return ret;
	ret = pcie2cio_read(icm, TB_CFG_PORT, port1, PHY_PORT_CS1, &val1);
	if (ret)
		return ret;

	val0 &= ~PHY_PORT_CS1_LINK_DISABLE;
	ret = pcie2cio_write(icm, TB_CFG_PORT, port0, PHY_PORT_CS1, val0);
	if (ret)
		return ret;

	val1 &= ~PHY_PORT_CS1_LINK_DISABLE;
	return pcie2cio_write(icm, TB_CFG_PORT, port1, PHY_PORT_CS1, val1);
}

static int icm_firmware_init(struct tb *tb)
{
	struct icm *icm = tb_priv(tb);
	struct tb_nhi *nhi = tb->nhi;
	int ret;

	ret = icm_firmware_start(tb, nhi);
	if (ret) {
		dev_err(&nhi->pdev->dev, "could not start ICM firmware\n");
		return ret;
	}

	if (icm->get_mode) {
		ret = icm->get_mode(tb);

		switch (ret) {
		case NHI_FW_SAFE_MODE:
			icm->safe_mode = true;
			break;

		case NHI_FW_CM_MODE:
			/* Ask ICM to accept all Thunderbolt devices */
			nhi_mailbox_cmd(nhi, NHI_MAILBOX_ALLOW_ALL_DEVS, 0);
			break;

		default:
			if (ret < 0)
				return ret;

			tb_err(tb, "ICM firmware is in wrong mode: %u\n", ret);
			return -ENODEV;
		}
	}

	/*
	 * Reset both physical ports if there is anything connected to
	 * them already.
	 */
	ret = icm_reset_phy_port(tb, 0);
	if (ret)
		dev_warn(&nhi->pdev->dev, "failed to reset links on port0\n");
	ret = icm_reset_phy_port(tb, 1);
	if (ret)
		dev_warn(&nhi->pdev->dev, "failed to reset links on port1\n");

	return 0;
}

static int icm_driver_ready(struct tb *tb)
{
	struct icm *icm = tb_priv(tb);
	int ret;

	ret = icm_firmware_init(tb);
	if (ret)
		return ret;

	if (icm->safe_mode) {
		tb_info(tb, "Thunderbolt host controller is in safe mode.\n");
		tb_info(tb, "You need to update NVM firmware of the controller before it can be used.\n");
		tb_info(tb, "For latest updates check https://thunderbolttechnology.net/updates.\n");
		return 0;
	}

	ret = __icm_driver_ready(tb, &tb->security_level, &icm->proto_version,
				 &tb->nboot_acl, &icm->rpm);
	if (ret)
		return ret;

	/*
	 * Make sure the number of supported preboot ACL matches what we
	 * expect or disable the whole feature.
	 */
	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;
}

static int icm_suspend(struct tb *tb)
{
	struct icm *icm = tb_priv(tb);

	if (icm->save_devices)
		icm->save_devices(tb);

	nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_DRV_UNLOADS, 0);
	return 0;
}

/*
 * Mark all switches (except root switch) below this one unplugged. ICM
 * firmware will send us an updated list of switches after we have send
 * it driver ready command. If a switch is not in that list it will be
 * removed when we perform rescan.
 */
static void icm_unplug_children(struct tb_switch *sw)
{
	struct tb_port *port;

	if (tb_route(sw))
		sw->is_unplugged = true;

	tb_switch_for_each_port(sw, port) {
		if (port->xdomain)
			port->xdomain->is_unplugged = true;
		else if (tb_port_has_remote(port))
			icm_unplug_children(port->remote->sw);
	}
}

static int complete_rpm(struct device *dev, void *data)
{
	struct tb_switch *sw = tb_to_switch(dev);

	if (sw)
		complete(&sw->rpm_complete);
	return 0;
}

static void remove_unplugged_switch(struct tb_switch *sw)
{
	struct device *parent = get_device(sw->dev.parent);

	pm_runtime_get_sync(parent);

	/*
	 * Signal this and switches below for rpm_complete because
	 * tb_switch_remove() calls pm_runtime_get_sync() that then waits
	 * for it.
	 */
	complete_rpm(&sw->dev, NULL);
	bus_for_each_dev(&tb_bus_type, &sw->dev, NULL, complete_rpm);
	tb_switch_remove(sw);

	pm_runtime_mark_last_busy(parent);
	pm_runtime_put_autosuspend(parent);

	put_device(parent);
}

static void icm_free_unplugged_children(struct tb_switch *sw)
{
	struct tb_port *port;

	tb_switch_for_each_port(sw, port) {
		if (port->xdomain && port->xdomain->is_unplugged) {
			tb_xdomain_remove(port->xdomain);
			port->xdomain = NULL;
		} else if (tb_port_has_remote(port)) {
			if (port->remote->sw->is_unplugged) {
				remove_unplugged_switch(port->remote->sw);
				port->remote = NULL;
			} else {
				icm_free_unplugged_children(port->remote->sw);
			}
		}
	}
}

static void icm_rescan_work(struct work_struct *work)
{
	struct icm *icm = container_of(work, struct icm, rescan_work.work);
	struct tb *tb = icm_to_tb(icm);

	mutex_lock(&tb->lock);
	if (tb->root_switch)
		icm_free_unplugged_children(tb->root_switch);
	mutex_unlock(&tb->lock);
}

static void icm_complete(struct tb *tb)
{
	struct icm *icm = tb_priv(tb);

	if (tb->nhi->going_away)
		return;

	/*
	 * If RTD3 was vetoed before we entered system suspend allow it
	 * again now before driver ready is sent. Firmware sends a new RTD3
	 * veto if it is still the case after we have sent it driver ready
	 * command.
	 */
	icm_veto_end(tb);
	icm_unplug_children(tb->root_switch);

	/*
	 * Now all existing children should be resumed, start events
	 * from ICM to get updated status.
	 */
	__icm_driver_ready(tb, NULL, NULL, NULL, NULL);

	/*
	 * We do not get notifications of devices that have been
	 * unplugged during suspend so schedule rescan to clean them up
	 * if any.
	 */
	queue_delayed_work(tb->wq, &icm->rescan_work, msecs_to_jiffies(500));
}

static int icm_runtime_suspend(struct tb *tb)
{
	nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_DRV_UNLOADS, 0);
	return 0;
}

static int icm_runtime_suspend_switch(struct tb_switch *sw)
{
	if (tb_route(sw))
		reinit_completion(&sw->rpm_complete);
	return 0;
}

static int icm_runtime_resume_switch(struct tb_switch *sw)
{
	if (tb_route(sw)) {
		if (!wait_for_completion_timeout(&sw->rpm_complete,
						 msecs_to_jiffies(500))) {
			dev_dbg(&sw->dev, "runtime resuming timed out\n");
		}
	}
	return 0;
}

static int icm_runtime_resume(struct tb *tb)
{
	/*
	 * We can reuse the same resume functionality than with system
	 * suspend.
	 */
	icm_complete(tb);
	return 0;
}

static int icm_start(struct tb *tb, bool not_used)
{
	struct icm *icm = tb_priv(tb);
	int ret;

	if (icm->safe_mode)
		tb->root_switch = tb_switch_alloc_safe_mode(tb, &tb->dev, 0);
	else
		tb->root_switch = tb_switch_alloc(tb, &tb->dev, 0);
	if (IS_ERR(tb->root_switch))
		return PTR_ERR(tb->root_switch);

	tb->root_switch->no_nvm_upgrade = !icm->can_upgrade_nvm;
	tb->root_switch->rpm = icm->rpm;

	if (icm->set_uuid)
		icm->set_uuid(tb);

	ret = tb_switch_add(tb->root_switch);
	if (ret) {
		tb_switch_put(tb->root_switch);
		tb->root_switch = NULL;
	}

	return ret;
}

static void icm_stop(struct tb *tb)
{
	struct icm *icm = tb_priv(tb);

	cancel_delayed_work(&icm->rescan_work);
	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)
{
	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_RETRIES, 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 %#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,
	.start = icm_start,
	.stop = icm_stop,
	.suspend = icm_suspend,
	.complete = icm_complete,
	.handle_event = icm_handle_event,
	.approve_switch = icm_fr_approve_switch,
	.add_switch_key = icm_fr_add_switch_key,
	.challenge_switch_key = icm_fr_challenge_switch_key,
	.disconnect_pcie_paths = icm_disconnect_pcie_paths,
	.approve_xdomain_paths = icm_fr_approve_xdomain_paths,
	.disconnect_xdomain_paths = icm_fr_disconnect_xdomain_paths,
};

/* Alpine Ridge */
static const struct tb_cm_ops icm_ar_ops = {
	.driver_ready = icm_driver_ready,
	.start = icm_start,
	.stop = icm_stop,
	.suspend = icm_suspend,
	.complete = icm_complete,
	.runtime_suspend = icm_runtime_suspend,
	.runtime_resume = icm_runtime_resume,
	.runtime_suspend_switch = icm_runtime_suspend_switch,
	.runtime_resume_switch = icm_runtime_resume_switch,
	.handle_event = icm_handle_event,
	.get_boot_acl = icm_ar_get_boot_acl,
	.set_boot_acl = icm_ar_set_boot_acl,
	.approve_switch = icm_fr_approve_switch,
	.add_switch_key = icm_fr_add_switch_key,
	.challenge_switch_key = icm_fr_challenge_switch_key,
	.disconnect_pcie_paths = icm_disconnect_pcie_paths,
	.approve_xdomain_paths = icm_fr_approve_xdomain_paths,
	.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,
	.runtime_suspend = icm_runtime_suspend,
	.runtime_resume = icm_runtime_resume,
	.runtime_suspend_switch = icm_runtime_suspend_switch,
	.runtime_resume_switch = icm_runtime_resume_switch,
	.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,
	.usb4_switch_op = icm_usb4_switch_op,
	.usb4_switch_nvm_authenticate_status =
		icm_usb4_switch_nvm_authenticate_status,
};

/* Ice Lake */
static const struct tb_cm_ops icm_icl_ops = {
	.driver_ready = icm_driver_ready,
	.start = icm_start,
	.stop = icm_stop,
	.complete = icm_complete,
	.runtime_suspend = icm_runtime_suspend,
	.runtime_resume = icm_runtime_resume,
	.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)
{
	struct icm *icm;
	struct tb *tb;

	tb = tb_domain_alloc(nhi, ICM_TIMEOUT, sizeof(struct icm));
	if (!tb)
		return NULL;

	icm = tb_priv(tb);
	INIT_DELAYED_WORK(&icm->rescan_work, icm_rescan_work);
	mutex_init(&icm->request_lock);

	switch (nhi->pdev->device) {
	case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI:
	case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI:
		icm->can_upgrade_nvm = true;
		icm->is_supported = icm_fr_is_supported;
		icm->get_route = icm_fr_get_route;
		icm->save_devices = icm_fr_save_devices;
		icm->driver_ready = icm_fr_driver_ready;
		icm->device_connected = icm_fr_device_connected;
		icm->device_disconnected = icm_fr_device_disconnected;
		icm->xdomain_connected = icm_fr_xdomain_connected;
		icm->xdomain_disconnected = icm_fr_xdomain_disconnected;
		tb->cm_ops = &icm_fr_ops;
		break;

	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_NHI:
	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_NHI:
	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_NHI:
	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_NHI:
	case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_NHI:
		icm->max_boot_acl = ICM_AR_PREBOOT_ACL_ENTRIES;
		/*
		 * NVM upgrade has not been tested on Apple systems and
		 * they don't provide images publicly either. To be on
		 * the safe side prevent root switch NVM upgrade on Macs
		 * for now.
		 */
		icm->can_upgrade_nvm = !x86_apple_machine;
		icm->is_supported = icm_ar_is_supported;
		icm->cio_reset = icm_ar_cio_reset;
		icm->get_mode = icm_ar_get_mode;
		icm->get_route = icm_ar_get_route;
		icm->save_devices = icm_fr_save_devices;
		icm->driver_ready = icm_ar_driver_ready;
		icm->device_connected = icm_fr_device_connected;
		icm->device_disconnected = icm_fr_device_disconnected;
		icm->xdomain_connected = icm_fr_xdomain_connected;
		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->can_upgrade_nvm = !x86_apple_machine;
		icm->is_supported = icm_ar_is_supported;
		icm->cio_reset = icm_tr_cio_reset;
		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;

	case PCI_DEVICE_ID_INTEL_ICL_NHI0:
	case PCI_DEVICE_ID_INTEL_ICL_NHI1:
		icm->is_supported = icm_fr_is_supported;
		icm->driver_ready = icm_icl_driver_ready;
		icm->set_uuid = icm_icl_set_uuid;
		icm->device_connected = icm_icl_device_connected;
		icm->device_disconnected = icm_tr_device_disconnected;
		icm->xdomain_connected = icm_tr_xdomain_connected;
		icm->xdomain_disconnected = icm_tr_xdomain_disconnected;
		icm->rtd3_veto = icm_icl_rtd3_veto;
		tb->cm_ops = &icm_icl_ops;
		break;

	case PCI_DEVICE_ID_INTEL_TGL_NHI0:
	case PCI_DEVICE_ID_INTEL_TGL_NHI1:
	case PCI_DEVICE_ID_INTEL_TGL_H_NHI0:
	case PCI_DEVICE_ID_INTEL_TGL_H_NHI1:
	case PCI_DEVICE_ID_INTEL_ADL_NHI0:
	case PCI_DEVICE_ID_INTEL_ADL_NHI1:
	case PCI_DEVICE_ID_INTEL_RPL_NHI0:
	case PCI_DEVICE_ID_INTEL_RPL_NHI1:
	case PCI_DEVICE_ID_INTEL_MTL_M_NHI0:
	case PCI_DEVICE_ID_INTEL_MTL_P_NHI0:
	case PCI_DEVICE_ID_INTEL_MTL_P_NHI1:
		icm->is_supported = icm_tgl_is_supported;
		icm->driver_ready = icm_icl_driver_ready;
		icm->set_uuid = icm_icl_set_uuid;
		icm->device_connected = icm_icl_device_connected;
		icm->device_disconnected = icm_tr_device_disconnected;
		icm->xdomain_connected = icm_tr_xdomain_connected;
		icm->xdomain_disconnected = icm_tr_xdomain_disconnected;
		icm->rtd3_veto = icm_icl_rtd3_veto;
		tb->cm_ops = &icm_icl_ops;
		break;

	case PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_2C_NHI:
	case PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_4C_NHI:
		icm->can_upgrade_nvm = true;
		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)) {
		dev_dbg(&nhi->pdev->dev, "ICM not supported on this controller\n");
		tb_domain_put(tb);
		return NULL;
	}

	tb_dbg(tb, "using firmware connection manager\n");

	return tb;
}
